• R/O
  • HTTP
  • SSH
  • HTTPS

提交

标签
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

system/corennnnn


Commit MetaInfo

修订版e27bf3eb290c75704549b4a5eedda56079bac86e (tree)
时间2009-05-11 06:09:03
作者Jack Palevich <jackpal@goog...>
CommiterJack Palevich

Log Message

Replace acc.c with the contents of otccn.c, update tests.

We are no longer checking if the constant data is the same, just the
generated code.

更改概述

差异

--- a/libacc/acc.c
+++ b/libacc/acc.c
@@ -1,525 +1,625 @@
11 /*
2- **
3- ** Copyright 2009, The Android Open Source Project
4- **
5- ** Licensed under the Apache License, Version 2.0 (the "License");
6- ** you may not use this file except in compliance with the License.
7- ** You may obtain a copy of the License at
8- **
9- ** http://www.apache.org/licenses/LICENSE-2.0
10- **
11- ** Unless required by applicable law or agreed to in writing, software
12- ** distributed under the License is distributed on an "AS IS" BASIS,
13- ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14- ** See the License for the specific language governing permissions and
15- ** limitations under the License.
16- */
17-
18-/* Based upon the freeware version of the Obfuscated Tiny C Compiler
19- * by Francis Bellard. <francis@bellard.org>.
20- */
2+ Obfuscated Tiny C Compiler
213
4+ Copyright (C) 2001-2003 Fabrice Bellard
5+
6+ This software is provided 'as-is', without any express or implied
7+ warranty. In no event will the authors be held liable for any damages
8+ arising from the use of this software.
9+
10+ Permission is granted to anyone to use this software for any purpose,
11+ including commercial applications, and to alter it and redistribute it
12+ freely, subject to the following restrictions:
13+
14+ 1. The origin of this software must not be misrepresented; you must not
15+ claim that you wrote the original software. If you use this software
16+ in a product, an acknowledgment in the product and its documentation
17+ *is* required.
18+ 2. Altered source versions must be plainly marked as such, and must not be
19+ misrepresented as being the original software.
20+ 3. This notice may not be removed or altered from any source distribution.
21+*/
22+
23+#include <stdarg.h>
2224 #include <stdio.h>
23-#include <stdlib.h>
24-#include <string.h>
25-
26-#define TOKEN_OPERATOR 1
27-#define TOKEN_NUMBER 2
28-
29-#define TOKEN_SYMBOL_BASE 256
30-#define TOKEN_INT 256
31-#define TOKEN_IF 288
32-#define TOKEN_ELSE 312
33-#define TOKEN_WHILE 352
34-#define TOKEN_BREAK 400
35-#define TOKEN_RETURN 448
36-#define TOKEN_FOR 504
37-#define TOKEN_DEFINE 536
38-
39-static int currentToken;
40-static int currentTokenData;
41-static int gCurrentTokenOperatorLevel;
42-static int currentChar;
43-static int gEndOfFunctionTarget;
44-static int gProgramCounter;
45-static int gFunctionStackSize;
46-static int savedChar;
47-static char* pInProgressMacro;
48-static char* P;
49-static char* ac;
50-static char* gStringTable;
51-static char* pSymbolTable;
52-static char* M;
53-static char* R;
54-static FILE* pInput;
55-
56-static void parseDeclarations (int isLocal);
57-static void parseExpression();
58-
59-static void addToSymbolTable(char e) {
60- *pSymbolTable++ = e;
25+
26+/* vars: value of variables
27+ loc : local variable index
28+ glo : global variable index
29+ ind : output code ptr
30+ rsym: return symbol
31+ prog: output code
32+ dstk: define stack
33+ dptr, dch: macro state
34+*/
35+int tok, tokc, tokl, ch, vars, rsym, prog, ind, loc, glo, file, sym_stk, dstk, dptr, dch, last_id;
36+
37+#define ALLOC_SIZE 99999
38+
39+/* depends on the init string */
40+#define TOK_STR_SIZE 48
41+#define TOK_IDENT 0x100
42+#define TOK_INT 0x100
43+#define TOK_IF 0x120
44+#define TOK_ELSE 0x138
45+#define TOK_WHILE 0x160
46+#define TOK_BREAK 0x190
47+#define TOK_RETURN 0x1c0
48+#define TOK_FOR 0x1f8
49+#define TOK_DEFINE 0x218
50+#define TOK_MAIN 0x250
51+
52+#define TOK_DUMMY 1
53+#define TOK_NUM 2
54+
55+#define LOCAL 0x200
56+
57+#define SYM_FORWARD 0
58+#define SYM_DEFINE 1
59+
60+/* tokens in string heap */
61+#define TAG_TOK ' '
62+#define TAG_MACRO 2
63+
64+pdef(t)
65+{
66+ *(char *)dstk++ = t;
6167 }
6268
63-static void nextChar() {
64- if (pInProgressMacro) {
65- currentChar = *(char*) pInProgressMacro++;
66- if (currentChar == 2) {
67- pInProgressMacro = NULL;
68- currentChar = savedChar;
69+inp()
70+{
71+ if (dptr) {
72+ ch = *(char *)dptr++;
73+ if (ch == TAG_MACRO) {
74+ dptr = 0;
75+ ch = dch;
6976 }
7077 } else
71- currentChar = fgetc(pInput);
78+ ch = fgetc(file);
79+ /* printf("ch=%c 0x%x\n", ch, ch); */
7280 }
7381
74-static int isSymbolChar() {
75- return isalnum(currentChar) || currentChar == '_';
82+isid()
83+{
84+ return isalnum(ch) | ch == '_';
7685 }
7786
78-static void unescapeCurrentChar() {
79- if (currentChar == '\\') {
80- nextChar();
81- if (currentChar == 'n')
82- currentChar = '\n';
87+/* read a character constant */
88+getq()
89+{
90+ if (ch == '\\') {
91+ inp();
92+ if (ch == 'n')
93+ ch = '\n';
8394 }
8495 }
8596
86-static void nextToken() {
87- int j, m;
88- while (isspace(currentChar) || currentChar == '#') {
89- if (currentChar == '#') {
90- nextChar();
91- nextToken();
92- if (currentToken == TOKEN_DEFINE) {
93- nextToken();
94- addToSymbolTable(' ');
95- *(int*) currentToken = 1;
96- *(int*) (currentToken + 4) = (int) pSymbolTable;
97+next()
98+{
99+ int t, l, a;
100+
101+ while (isspace(ch) | ch == '#') {
102+ if (ch == '#') {
103+ inp();
104+ next();
105+ if (tok == TOK_DEFINE) {
106+ next();
107+ pdef(TAG_TOK); /* fill last ident tag */
108+ *(int *)tok = SYM_DEFINE;
109+ *(int *)(tok + 4) = dstk; /* define stack */
97110 }
98- while (currentChar != '\n') {
99- addToSymbolTable(currentChar);
100- nextChar();
111+ /* well we always save the values ! */
112+ while (ch != '\n') {
113+ pdef(ch);
114+ inp();
101115 }
102- addToSymbolTable(currentChar);
103- addToSymbolTable(2);
116+ pdef(ch);
117+ pdef(TAG_MACRO);
104118 }
105- nextChar();
119+ inp();
106120 }
107- gCurrentTokenOperatorLevel = 0;
108- currentToken = currentChar;
109- if (isSymbolChar()) {
110- addToSymbolTable(' ');
111- M = pSymbolTable;
112- while (isSymbolChar()) {
113- addToSymbolTable(currentChar);
114- nextChar();
121+ tokl = 0;
122+ tok = ch;
123+ /* encode identifiers & numbers */
124+ if (isid()) {
125+ pdef(TAG_TOK);
126+ last_id = dstk;
127+ while (isid()) {
128+ pdef(ch);
129+ inp();
115130 }
116- if (isdigit(currentToken)) {
117- currentTokenData = strtol(M, 0, 0);
118- currentToken = TOKEN_NUMBER;
131+ if (isdigit(tok)) {
132+ tokc = strtol(last_id, 0, 0);
133+ tok = TOK_NUM;
119134 } else {
120- *(char*) pSymbolTable = ' ';
121- currentToken = strstr(R, M - 1) - R;
122- *(char*) pSymbolTable = 0;
123- currentToken = currentToken * 8 + TOKEN_SYMBOL_BASE;
124- if (currentToken > TOKEN_DEFINE) {
125- currentToken = ((int) P) + currentToken;
126- if (*(int*) currentToken == 1) {
127- pInProgressMacro = (char*) (*(int*) (currentToken + 4));
128- savedChar = currentChar;
129- nextChar();
130- nextToken();
135+ *(char *)dstk = TAG_TOK; /* no need to mark end of string (we
136+ suppose data is initied to zero */
137+ tok = strstr(sym_stk, last_id - 1) - sym_stk;
138+ *(char *)dstk = 0; /* mark real end of ident for dlsym() */
139+ tok = tok * 8 + TOK_IDENT;
140+ if (tok > TOK_DEFINE) {
141+ tok = vars + tok;
142+ /* printf("tok=%s %x\n", last_id, tok); */
143+ /* define handling */
144+ if (*(int *)tok == SYM_DEFINE) {
145+ dptr = *(int *)(tok + 4);
146+ dch = ch;
147+ inp();
148+ next();
131149 }
132150 }
133151 }
134152 } else {
135- nextChar();
136- if (currentToken == '\'') {
137- currentToken = TOKEN_NUMBER;
138- unescapeCurrentChar();
139- currentTokenData = currentChar;
140- nextChar();
141- nextChar();
142- } else if (currentToken == '/' & currentChar == '*') {
143- nextChar();
144- while (currentChar) {
145- while (currentChar != '*')
146- nextChar();
147- nextChar();
148- if (currentChar == '/')
149- currentChar = 0;
153+ inp();
154+ if (tok == '\'') {
155+ tok = TOK_NUM;
156+ getq();
157+ tokc = ch;
158+ inp();
159+ inp();
160+ } else if (tok == '/' & ch == '*') {
161+ inp();
162+ while (ch) {
163+ while (ch != '*')
164+ inp();
165+ inp();
166+ if (ch == '/')
167+ ch = 0;
150168 }
151- nextChar();
152- nextToken();
153- } else {
154- char* e = "++#m--%am*@R<^1c/@%[_[H3c%@%[_[H3c+@.B#d-@%:_^BKd<<Z/03e>>`/03e<=0f>=/f<@.f>@1f==&g!='g&&k||#l&@.BCh^@.BSi|@.B+j~@/%Yd!@&d*@b";
155- while (j = *(char*) e++) {
156- m = *(char*) e++;
157- currentTokenData = 0;
158- while ((gCurrentTokenOperatorLevel = *(char*) e++ - 98) < 0)
159- currentTokenData = currentTokenData * 64 + gCurrentTokenOperatorLevel + 64;
160- if (j == currentToken && (m == currentChar || m == 64)) {
161- if (m == currentChar) {
162- nextChar();
163- currentToken = TOKEN_OPERATOR;
169+ inp();
170+ next();
171+ } else
172+ {
173+ t = "++#m--%am*@R<^1c/@%[_[H3c%@%[_[H3c+@.B#d-@%:_^BKd<<Z/03e>>`/03e<=0f>=/f<@.f>@1f==&g!=\'g&&k||#l&@.BCh^@.BSi|@.B+j~@/%Yd!@&d*@b";
174+ while (l = *(char *)t++) {
175+ a = *(char *)t++;
176+ tokc = 0;
177+ while ((tokl = *(char *)t++ - 'b') < 0)
178+ tokc = tokc * 64 + tokl + 64;
179+ if (l == tok & (a == ch | a == '@')) {
180+#if 0
181+ printf("%c%c -> tokl=%d tokc=0x%x\n",
182+ l, a, tokl, tokc);
183+#endif
184+ if (a == ch) {
185+ inp();
186+ tok = TOK_DUMMY; /* dummy token for double tokens */
164187 }
165188 break;
166189 }
167190 }
168191 }
169192 }
193+#if 0
194+ {
195+ int p;
196+
197+ printf("tok=0x%x ", tok);
198+ if (tok >= TOK_IDENT) {
199+ printf("'");
200+ if (tok > TOK_DEFINE)
201+ p = sym_stk + 1 + (tok - vars - TOK_IDENT) / 8;
202+ else
203+ p = sym_stk + 1 + (tok - TOK_IDENT) / 8;
204+ while (*(char *)p != TAG_TOK && *(char *)p)
205+ printf("%c", *(char *)p++);
206+ printf("'\n");
207+ } else if (tok == TOK_NUM) {
208+ printf("%d\n", tokc);
209+ } else {
210+ printf("'%c'\n", tok);
211+ }
212+ }
213+#endif
170214 }
171215
172-/*
173- * Emit 1 to 4 bytes of code. Little-endian, doesn't emit high bytes that
174- * are 0x00 or 0xff
175- */
176-static void emitCode(int g) {
177- while( g && g != -1) {
178- *(char*) gProgramCounter++=g;
179- g=g>>8;
216+void error(char *fmt,...)
217+{
218+ va_list ap;
219+
220+ va_start(ap, fmt);
221+ fprintf(stderr, "%d: ", ftell((FILE *)file));
222+ vfprintf(stderr, fmt, ap);
223+ fprintf(stderr, "\n");
224+ exit(1);
225+ va_end(ap);
226+}
227+
228+void skip(c)
229+{
230+ if (tok != c) {
231+ error("'%c' expected", c);
180232 }
233+ next();
181234 }
182235
183-static void fixupAddress(e) {
184- int g;
185- while( e) {
186- g=*(int*) e;
187- *(int*) e=gProgramCounter-e-4;
188- e=g;
236+o(n)
237+{
238+ /* cannot use unsigned, so we must do a hack */
239+ while (n && n != -1) {
240+ *(char *)ind++ = n;
241+ n = n >> 8;
189242 }
190243 }
191244
192-static int emitCodeWithImmediate( g, e) {
193- emitCode(g);
194- *(int*) gProgramCounter = e;
195- e = gProgramCounter;
196- gProgramCounter = gProgramCounter + 4;
197- return e;
245+/* output a symbol and patch all calls to it */
246+gsym(t)
247+{
248+ int n;
249+ while (t) {
250+ n = *(int *)t; /* next value */
251+ *(int *)t = ind - t - 4;
252+ t = n;
253+ }
198254 }
199255
200-static int emitLoadAccumulatorImmediate(e) {
201- emitCodeWithImmediate(0xb8,e); /* Move immediate a, e */
256+/* psym is used to put an instruction with a data field which is a
257+ reference to a symbol. It is in fact the same as oad ! */
258+#define psym oad
259+
260+/* instruction + address */
261+oad(n, t)
262+{
263+ o(n);
264+ *(int *)ind = t;
265+ t = ind;
266+ ind = ind + 4;
267+ return t;
202268 }
203269
204-static int emitBranch(e) {
205- return emitCodeWithImmediate(0xe9,e); /* Jump relative */
270+/* load immediate value */
271+li(t)
272+{
273+ oad(0xb8, t); /* mov $xx, %eax */
206274 }
207275
208-static int emitTest( j, e) {
209- emitCode(0x0FC085); /* 85 C0 FC TEST */
210- return emitCodeWithImmediate(0x84 + j, e); /* TEST */
276+gjmp(t)
277+{
278+ return psym(0xe9, t);
211279 }
212280
213-static void emitSetCC(int condition) {
214- emitCode( 0xC139); /* 39 C1 CMP */
215- emitLoadAccumulatorImmediate(0);
216- emitCode( 0x0F); /* Two byte opcode prefix */
217- emitCode( condition+0x90); /* Set byte on condition (controlled by e) */
218- emitCode( 0xC0); /* I think this is part of the SETcc instruction */
281+/* l = 0: je, l == 1: jne */
282+gtst(l, t)
283+{
284+ o(0x0fc085); /* test %eax, %eax, je/jne xxx */
285+ return psym(0x84 + l, t);
219286 }
220287
221-static void emitNumericOp( int op, int e) {
222- emitCode(op + 0x83);
223- emitCodeWithImmediate((e < 512) << 7 | 5, e);
288+gcmp(t)
289+{
290+ o(0xc139); /* cmp %eax,%ecx */
291+ li(0);
292+ o(0x0f); /* setxx %al */
293+ o(t + 0x90);
294+ o(0xc0);
224295 }
225296
226-static void parseTerminal (int level) {
227- int g,e,m,aa;
228- g=1;
229- if( currentToken == '"') {
230- emitLoadAccumulatorImmediate(gStringTable);
231- while( currentChar != '"') {
232- unescapeCurrentChar ();
233- *(char*) gStringTable++=currentChar;
234- nextChar ();
235- }
236- *(char*) gStringTable=0;
237- gStringTable= (char*) (((int)gStringTable) +4&-4);
238- nextChar();
239- nextToken();
240- }
241- else {
242- aa=gCurrentTokenOperatorLevel;
243- m= currentTokenData;
244- e=currentToken;
245- nextToken();
246- if( e == TOKEN_NUMBER) {
247- emitLoadAccumulatorImmediate(m);
248- }
249- else if( aa == 2) {
250- parseTerminal(0);
251- emitCodeWithImmediate(0xB9,0); /* MOV r1, immediate */
252- if( e == '!')emitSetCC(m);
253- else emitCode( m);
254- }
255- else if( e == '(') {
256- parseExpression ();
257- nextToken();
297+gmov(l, t)
298+{
299+ o(l + 0x83);
300+ oad((t < LOCAL) << 7 | 5, t);
301+}
302+
303+/* l is one if '=' parsing wanted (quick hack) */
304+unary(l)
305+{
306+ int n, t, a, c;
307+
308+ n = 1; /* type of expression 0 = forward, 1 = value, other =
309+ lvalue */
310+ if (tok == '\"') {
311+ li(glo);
312+ while (ch != '\"') {
313+ getq();
314+ *(char *)glo++ = ch;
315+ inp();
258316 }
259- else if( e == '*') {
260- nextToken();
261- e=currentToken;
262- nextToken();
263- nextToken();
264- if( currentToken == '*') {
265- nextToken();
266- nextToken();
267- nextToken();
268- nextToken();
269- e=0;
270- }
271- nextToken();
272- parseTerminal(0);
273- if( currentToken == '=') {
274- nextToken();
275- emitCode( 0x50); /* PUSH r0 */
276- parseExpression ();
277- emitCode( 0x59); /* POP r1 */
278- emitCode( 0x188 + (e == TOKEN_INT)); /* 88 01 MOV */
317+ *(char *)glo = 0;
318+ glo = glo + 4 & -4; /* align heap */
319+ inp();
320+ next();
321+ } else {
322+ c = tokl;
323+ a = tokc;
324+ t = tok;
325+ next();
326+ if (t == TOK_NUM) {
327+ li(a);
328+ } else if (c == 2) {
329+ /* -, +, !, ~ */
330+ unary(0);
331+ oad(0xb9, 0); /* movl $0, %ecx */
332+ if (t == '!')
333+ gcmp(a);
334+ else
335+ o(a);
336+ } else if (t == '(') {
337+ expr();
338+ skip(')');
339+ } else if (t == '*') {
340+ /* parse cast */
341+ skip('(');
342+ t = tok; /* get type */
343+ next(); /* skip int/char/void */
344+ next(); /* skip '*' or '(' */
345+ if (tok == '*') {
346+ /* function type */
347+ skip('*');
348+ skip(')');
349+ skip('(');
350+ skip(')');
351+ t = 0;
279352 }
280- else if( e) {
281- if( e == TOKEN_INT)emitCode( 0x8B); /* MOV */
282- else emitCode( 0xBE0F); /* 0F BE MOVSX move with sign extension */
283- gProgramCounter++;
353+ skip(')');
354+ unary(0);
355+ if (tok == '=') {
356+ next();
357+ o(0x50); /* push %eax */
358+ expr();
359+ o(0x59); /* pop %ecx */
360+ o(0x0188 + (t == TOK_INT)); /* movl %eax/%al, (%ecx) */
361+ } else if (t) {
362+ if (t == TOK_INT)
363+ o(0x8b); /* mov (%eax), %eax */
364+ else
365+ o(0xbe0f); /* movsbl (%eax), %eax */
366+ ind++; /* add zero in code */
284367 }
285- }
286- else if( e == '&') {
287- emitNumericOp(10,*(int*) currentToken); /* 8D LEA */
288- nextToken();
289- }
290- else {
291- g=*(int*) e;
292- if(!g)g=dlsym(0,M);
293- if( currentToken == '=' & level) {
294- nextToken();
295- parseExpression ();
296- emitNumericOp(6,g); /* 89 MOV */
297- }
298- else if( currentToken!= '(') {
299- emitNumericOp(8,g); /* 8B MOV sreg */
300- if( gCurrentTokenOperatorLevel == 11) {
301- emitNumericOp(0,g); /* 83 ADD */
302- emitCode( currentTokenData);
303- nextToken();
368+ } else if (t == '&') {
369+ gmov(10, *(int *)tok); /* leal EA, %eax */
370+ next();
371+ } else {
372+ n = *(int *)t;
373+ /* forward reference: try dlsym */
374+ if (!n)
375+ n = dlsym(0, last_id);
376+ if (tok == '=' & l) {
377+ /* assignment */
378+ next();
379+ expr();
380+ gmov(6, n); /* mov %eax, EA */
381+ } else if (tok != '(') {
382+ /* variable */
383+ gmov(8, n); /* mov EA, %eax */
384+ if (tokl == 11) {
385+ gmov(0, n);
386+ o(tokc);
387+ next();
304388 }
305389 }
306390 }
307391 }
308- if( currentToken == '(') {
309- if( g == 1)emitCode( 0x50); /* push */
310- m= emitCodeWithImmediate(0xEC81,0); /* 81 EC Cmp ?? */
311- nextToken();
312- level=0;
313- while( currentToken!= ')') {
314- parseExpression ();
315- emitCodeWithImmediate(0x248489,level); /* 89 84 24 MOV sp + level*/
316- if( currentToken == ',')nextToken();
317- level=level +4;
318- }
319- *(int*) m= level;
320- nextToken();
321- if(!g) {
322- e=e +4;
323- *(int*) e=emitCodeWithImmediate(0xE8,*(int*) e); /* Call */
324- }
325- else if( g == 1) {
326- emitCodeWithImmediate(0x2494FF,level); /* FF 94 24 */
327- level=level +4;
392+
393+ /* function call */
394+ if (tok == '(') {
395+ if (n == 1)
396+ o(0x50); /* push %eax */
397+
398+ /* push args and invert order */
399+ a = oad(0xec81, 0); /* sub $xxx, %esp */
400+ next();
401+ l = 0;
402+ while(tok != ')') {
403+ expr();
404+ oad(0x248489, l); /* movl %eax, xxx(%esp) */
405+ if (tok == ',')
406+ next();
407+ l = l + 4;
328408 }
329- else {
330- emitCodeWithImmediate(0xE8,g-gProgramCounter-5); /* CALL */
409+ *(int *)a = l;
410+ next();
411+ if (!n) {
412+ /* forward reference */
413+ t = t + 4;
414+ *(int *)t = psym(0xe8, *(int *)t);
415+ } else if (n == 1) {
416+ oad(0x2494ff, l); /* call *xxx(%esp) */
417+ l = l + 4;
418+ } else {
419+ oad(0xe8, n - ind - 5); /* call xxx */
331420 }
332- if( level)emitCodeWithImmediate(0xC481,level); /* 81 C4 adjust stack pointer */
421+ if (l)
422+ oad(0xc481, l); /* add $xxx, %esp */
333423 }
334424 }
335425
336-static void parseBinaryOp (int level) {
337- int e,g,m;
338- if( level--== 1)parseTerminal(1);
426+sum(l)
427+{
428+ int t, n, a;
429+
430+ if (l-- == 1)
431+ unary(1);
339432 else {
340- parseBinaryOp (level);
341- m= 0;
342- while( level == gCurrentTokenOperatorLevel) {
343- g=currentToken;
344- e=currentTokenData;
345- nextToken();
346- if( level>8) {
347- m= emitTest(e,m);
348- parseBinaryOp (level);
349- }
350- else {
351- emitCode( 0x50);
352- parseBinaryOp (level);
353- emitCode( 0x59);
354- if( level == 4 | level == 5) {
355- emitSetCC(e);
356- }
357- else {
358- emitCode( e);
359- if( g == '%')emitCode( 0x92); /* XCHG */
433+ sum(l);
434+ a = 0;
435+ while (l == tokl) {
436+ n = tok;
437+ t = tokc;
438+ next();
439+
440+ if (l > 8) {
441+ a = gtst(t, a); /* && and || output code generation */
442+ sum(l);
443+ } else {
444+ o(0x50); /* push %eax */
445+ sum(l);
446+ o(0x59); /* pop %ecx */
447+
448+ if (l == 4 | l == 5) {
449+ gcmp(t);
450+ } else {
451+ o(t);
452+ if (n == '%')
453+ o(0x92); /* xchg %edx, %eax */
360454 }
361455 }
362456 }
363- if( m&&level>8) {
364- m= emitTest(e,m);
365- emitLoadAccumulatorImmediate(e^1);
366- emitBranch(5); /* Jump relative +5 */
367- fixupAddress(m);
368- emitLoadAccumulatorImmediate(e);
457+ /* && and || output code generation */
458+ if (a && l > 8) {
459+ a = gtst(t, a);
460+ li(t ^ 1);
461+ gjmp(5); /* jmp $ + 5 */
462+ gsym(a);
463+ li(t);
369464 }
370465 }
371466 }
372467
373-static void parseExpression() {
374- parseBinaryOp(11);
468+expr()
469+{
470+ sum(11);
375471 }
376472
377-static int parseExpressionEmitTest() {
378- parseExpression();
379- return emitTest(0, 0);
473+
474+test_expr()
475+{
476+ expr();
477+ return gtst(0, 0);
380478 }
381479
382-static void parseStatement (int* pBreakTarget) {
383- int m,g,e;
384- if( currentToken == TOKEN_IF) {
385- nextToken();
386- nextToken();
387- m= parseExpressionEmitTest ();
388- nextToken();
389- parseStatement (pBreakTarget);
390- if( currentToken == TOKEN_ELSE) {
391- nextToken();
392- g=emitBranch(0);
393- fixupAddress(m);
394- parseStatement (pBreakTarget);
395- fixupAddress(g);
396- }
397- else {
398- fixupAddress(m);
399- }
400- }
401- else if ( currentToken == TOKEN_WHILE || currentToken == TOKEN_FOR) {
402- e = currentToken;
403- nextToken();
404- nextToken();
405- if( e == TOKEN_WHILE) {
406- g=gProgramCounter;
407- m= parseExpressionEmitTest ();
480+block(l)
481+{
482+ int a, n, t;
483+
484+ if (tok == TOK_IF) {
485+ next();
486+ skip('(');
487+ a = test_expr();
488+ skip(')');
489+ block(l);
490+ if (tok == TOK_ELSE) {
491+ next();
492+ n = gjmp(0); /* jmp */
493+ gsym(a);
494+ block(l);
495+ gsym(n); /* patch else jmp */
496+ } else {
497+ gsym(a); /* patch if test */
408498 }
409- else {
410- if( currentToken != ';')parseExpression ();
411- nextToken();
412- g=gProgramCounter;
413- m= 0;
414- if( currentToken != ';')m= parseExpressionEmitTest ();
415- nextToken();
416- if( currentToken!= ')') {
417- e=emitBranch(0);
418- parseExpression ();
419- emitBranch(g-gProgramCounter-5);
420- fixupAddress(e);
421- g=e +4;
499+ } else if (tok == TOK_WHILE | tok == TOK_FOR) {
500+ t = tok;
501+ next();
502+ skip('(');
503+ if (t == TOK_WHILE) {
504+ n = ind;
505+ a = test_expr();
506+ } else {
507+ if (tok != ';')
508+ expr();
509+ skip(';');
510+ n = ind;
511+ a = 0;
512+ if (tok != ';')
513+ a = test_expr();
514+ skip(';');
515+ if (tok != ')') {
516+ t = gjmp(0);
517+ expr();
518+ gjmp(n - ind - 5);
519+ gsym(t);
520+ n = t + 4;
422521 }
423522 }
424- nextToken();
425- parseStatement(&m);
426- emitBranch(g-gProgramCounter-5);
427- fixupAddress(m);
428- }
429- else if( currentToken == '{') {
430- nextToken();
431- parseDeclarations(1);
432- while( currentToken != '}') parseStatement(pBreakTarget);
433- nextToken();
434- }
435- else {
436- if( currentToken == TOKEN_RETURN) {
437- nextToken();
438- if( currentToken != ';') parseExpression();
439- gEndOfFunctionTarget=emitBranch(gEndOfFunctionTarget);
440- }
441- else if( currentToken == TOKEN_BREAK) {
442- nextToken();
443- *pBreakTarget = emitBranch(*pBreakTarget);
444- }
445- else if( currentToken != ';') parseExpression();
446- nextToken();
523+ skip(')');
524+ block(&a);
525+ gjmp(n - ind - 5); /* jmp */
526+ gsym(a);
527+ } else if (tok == '{') {
528+ next();
529+ /* declarations */
530+ decl(1);
531+ while(tok != '}')
532+ block(l);
533+ next();
534+ } else {
535+ if (tok == TOK_RETURN) {
536+ next();
537+ if (tok != ';')
538+ expr();
539+ rsym = gjmp(rsym); /* jmp */
540+ } else if (tok == TOK_BREAK) {
541+ next();
542+ *(int *)l = gjmp(*(int *)l);
543+ } else if (tok != ';')
544+ expr();
545+ skip(';');
447546 }
448547 }
449548
450-static void parseDeclarations (int isLocal) {
451- int m;
452- while( currentToken == TOKEN_INT | currentToken != -1 & !isLocal ) {
453- if( currentToken == TOKEN_INT) {
454- nextToken();
455- while( currentToken != ';') {
456- if( isLocal ) {
457- gFunctionStackSize=gFunctionStackSize +4;
458- *(int*) currentToken=-gFunctionStackSize;
459- }
460- else {
461- *(char**) currentToken = gStringTable;
462- gStringTable=gStringTable +4;
549+/* 'l' is true if local declarations */
550+decl(l)
551+{
552+ int a;
553+
554+ while (tok == TOK_INT | tok != -1 & !l) {
555+ if (tok == TOK_INT) {
556+ next();
557+ while (tok != ';') {
558+ if (l) {
559+ loc = loc + 4;
560+ *(int *)tok = -loc;
561+ } else {
562+ *(int *)tok = glo;
563+ glo = glo + 4;
463564 }
464- nextToken();
465- if( currentToken == ',')nextToken();
565+ next();
566+ if (tok == ',')
567+ next();
466568 }
467- nextToken();
468- }
469- else {
470- fixupAddress(*(int*)(currentToken + 4));
471- *(int*) currentToken=gProgramCounter;
472- nextToken();
473- nextToken();
474- m= 8;
475- while( currentToken != ')') {
476- *(int*) currentToken=m;
477- m= m +4;
478- nextToken();
479- if( currentToken == ',')nextToken();
569+ skip(';');
570+ } else {
571+ /* patch forward references (XXX: do not work for function
572+ pointers) */
573+ gsym(*(int *)(tok + 4));
574+ /* put function address */
575+ *(int *)tok = ind;
576+ next();
577+ skip('(');
578+ a = 8;
579+ while (tok != ')') {
580+ /* read param name and compute offset */
581+ *(int *)tok = a;
582+ a = a + 4;
583+ next();
584+ if (tok == ',')
585+ next();
480586 }
481- nextToken();
482- gEndOfFunctionTarget=gFunctionStackSize=0;
483- emitCode( 0xE58955); /* 55 89 E5 PUSH */
484- m= emitCodeWithImmediate(0xEC81,0); /* 81 EC */
485- parseStatement(0);
486- fixupAddress(gEndOfFunctionTarget);
487- emitCode( 0xC3C9); /* C9 C3 LEAVE */
488- *(int*) m= gFunctionStackSize;
587+ next(); /* skip ')' */
588+ rsym = loc = 0;
589+ o(0xe58955); /* push %ebp, mov %esp, %ebp */
590+ a = oad(0xec81, 0); /* sub $xxx, %esp */
591+ block(0);
592+ gsym(rsym);
593+ o(0xc3c9); /* leave, ret */
594+ *(int *)a = loc; /* save local variables */
489595 }
490596 }
491597 }
492598
493-int main( int argc, char** argv) {
494- pInput = stdin;
495- if (argc-- > 1) {
496- char* file = argv[1];
497- argv += 1;
498- pInput = fopen(file, "r");
499- if (pInput == NULL) {
500- fprintf(stderr, "Could not open file \"%s\"\n", file);
501- return -1;
502- }
599+main(n, t)
600+{
601+ file = stdin;
602+ if (n-- > 1) {
603+ t = t + 4;
604+ file = fopen(*(int *)t, "r");
605+ }
606+ dstk = strcpy(sym_stk = calloc(1, ALLOC_SIZE),
607+ " int if else while break return for define main ") + TOK_STR_SIZE;
608+ glo = calloc(1, ALLOC_SIZE);
609+ ind = prog = calloc(1, ALLOC_SIZE);
610+ vars = calloc(1, ALLOC_SIZE);
611+ inp();
612+ next();
613+ decl(0);
614+#ifdef TEST
615+ {
616+ FILE *f;
617+ f = fopen(*(char **)(t + 4), "w");
618+ fwrite((void *)prog, 1, ind - prog, f);
619+ fclose(f);
620+ return 0;
503621 }
504- pSymbolTable = strcpy(R = calloc(1, 99999),
505- " int if else while break return for define main ") + 48;
506- gStringTable = calloc(1, 99999);
507- ac = calloc(1, 99999);
508- gProgramCounter = (int) ac;
509- P = calloc(1, 99999);
510- nextChar();
511- nextToken();
512- parseDeclarations(0);
513-#if 1
514- fwrite(R, 1, 99999, stdout);
515- fwrite(ac, 1, 99999, stdout);
516- fwrite(P, 1, 99999, stdout);
517- return 0;
518622 #else
519- /* Look up the address of "main" in the symbol table and call it.
520- * We put main in at a known offset, so we know the address.
521- */
522- return (*(int(*)()) *(int*) (P + 592))(argc, argv);
623+ return (*(int (*)())*(int *)(vars + TOK_MAIN)) (n, t);
523624 #endif
524625 }
525-
--- a/libacc/otccn.c
+++ /dev/null
@@ -1,632 +0,0 @@
1-/*
2- Obfuscated Tiny C Compiler
3-
4- Copyright (C) 2001-2003 Fabrice Bellard
5-
6- This software is provided 'as-is', without any express or implied
7- warranty. In no event will the authors be held liable for any damages
8- arising from the use of this software.
9-
10- Permission is granted to anyone to use this software for any purpose,
11- including commercial applications, and to alter it and redistribute it
12- freely, subject to the following restrictions:
13-
14- 1. The origin of this software must not be misrepresented; you must not
15- claim that you wrote the original software. If you use this software
16- in a product, an acknowledgment in the product and its documentation
17- *is* required.
18- 2. Altered source versions must be plainly marked as such, and must not be
19- misrepresented as being the original software.
20- 3. This notice may not be removed or altered from any source distribution.
21-*/
22-#ifndef TINY
23-#include <stdarg.h>
24-#endif
25-#include <stdio.h>
26-
27-/* vars: value of variables
28- loc : local variable index
29- glo : global variable index
30- ind : output code ptr
31- rsym: return symbol
32- prog: output code
33- dstk: define stack
34- dptr, dch: macro state
35-*/
36-int tok, tokc, tokl, ch, vars, rsym, prog, ind, loc, glo, file, sym_stk, dstk, dptr, dch, last_id;
37-
38-#define ALLOC_SIZE 99999
39-
40-/* depends on the init string */
41-#define TOK_STR_SIZE 48
42-#define TOK_IDENT 0x100
43-#define TOK_INT 0x100
44-#define TOK_IF 0x120
45-#define TOK_ELSE 0x138
46-#define TOK_WHILE 0x160
47-#define TOK_BREAK 0x190
48-#define TOK_RETURN 0x1c0
49-#define TOK_FOR 0x1f8
50-#define TOK_DEFINE 0x218
51-#define TOK_MAIN 0x250
52-
53-#define TOK_DUMMY 1
54-#define TOK_NUM 2
55-
56-#define LOCAL 0x200
57-
58-#define SYM_FORWARD 0
59-#define SYM_DEFINE 1
60-
61-/* tokens in string heap */
62-#define TAG_TOK ' '
63-#define TAG_MACRO 2
64-
65-pdef(t)
66-{
67- *(char *)dstk++ = t;
68-}
69-
70-inp()
71-{
72- if (dptr) {
73- ch = *(char *)dptr++;
74- if (ch == TAG_MACRO) {
75- dptr = 0;
76- ch = dch;
77- }
78- } else
79- ch = fgetc(file);
80- /* printf("ch=%c 0x%x\n", ch, ch); */
81-}
82-
83-isid()
84-{
85- return isalnum(ch) | ch == '_';
86-}
87-
88-/* read a character constant */
89-getq()
90-{
91- if (ch == '\\') {
92- inp();
93- if (ch == 'n')
94- ch = '\n';
95- }
96-}
97-
98-next()
99-{
100- int t, l, a;
101-
102- while (isspace(ch) | ch == '#') {
103- if (ch == '#') {
104- inp();
105- next();
106- if (tok == TOK_DEFINE) {
107- next();
108- pdef(TAG_TOK); /* fill last ident tag */
109- *(int *)tok = SYM_DEFINE;
110- *(int *)(tok + 4) = dstk; /* define stack */
111- }
112- /* well we always save the values ! */
113- while (ch != '\n') {
114- pdef(ch);
115- inp();
116- }
117- pdef(ch);
118- pdef(TAG_MACRO);
119- }
120- inp();
121- }
122- tokl = 0;
123- tok = ch;
124- /* encode identifiers & numbers */
125- if (isid()) {
126- pdef(TAG_TOK);
127- last_id = dstk;
128- while (isid()) {
129- pdef(ch);
130- inp();
131- }
132- if (isdigit(tok)) {
133- tokc = strtol(last_id, 0, 0);
134- tok = TOK_NUM;
135- } else {
136- *(char *)dstk = TAG_TOK; /* no need to mark end of string (we
137- suppose data is initied to zero */
138- tok = strstr(sym_stk, last_id - 1) - sym_stk;
139- *(char *)dstk = 0; /* mark real end of ident for dlsym() */
140- tok = tok * 8 + TOK_IDENT;
141- if (tok > TOK_DEFINE) {
142- tok = vars + tok;
143- /* printf("tok=%s %x\n", last_id, tok); */
144- /* define handling */
145- if (*(int *)tok == SYM_DEFINE) {
146- dptr = *(int *)(tok + 4);
147- dch = ch;
148- inp();
149- next();
150- }
151- }
152- }
153- } else {
154- inp();
155- if (tok == '\'') {
156- tok = TOK_NUM;
157- getq();
158- tokc = ch;
159- inp();
160- inp();
161- } else if (tok == '/' & ch == '*') {
162- inp();
163- while (ch) {
164- while (ch != '*')
165- inp();
166- inp();
167- if (ch == '/')
168- ch = 0;
169- }
170- inp();
171- next();
172- } else
173- {
174- t = "++#m--%am*@R<^1c/@%[_[H3c%@%[_[H3c+@.B#d-@%:_^BKd<<Z/03e>>`/03e<=0f>=/f<@.f>@1f==&g!=\'g&&k||#l&@.BCh^@.BSi|@.B+j~@/%Yd!@&d*@b";
175- while (l = *(char *)t++) {
176- a = *(char *)t++;
177- tokc = 0;
178- while ((tokl = *(char *)t++ - 'b') < 0)
179- tokc = tokc * 64 + tokl + 64;
180- if (l == tok & (a == ch | a == '@')) {
181-#if 0
182- printf("%c%c -> tokl=%d tokc=0x%x\n",
183- l, a, tokl, tokc);
184-#endif
185- if (a == ch) {
186- inp();
187- tok = TOK_DUMMY; /* dummy token for double tokens */
188- }
189- break;
190- }
191- }
192- }
193- }
194-#if 0
195- {
196- int p;
197-
198- printf("tok=0x%x ", tok);
199- if (tok >= TOK_IDENT) {
200- printf("'");
201- if (tok > TOK_DEFINE)
202- p = sym_stk + 1 + (tok - vars - TOK_IDENT) / 8;
203- else
204- p = sym_stk + 1 + (tok - TOK_IDENT) / 8;
205- while (*(char *)p != TAG_TOK && *(char *)p)
206- printf("%c", *(char *)p++);
207- printf("'\n");
208- } else if (tok == TOK_NUM) {
209- printf("%d\n", tokc);
210- } else {
211- printf("'%c'\n", tok);
212- }
213- }
214-#endif
215-}
216-
217-#ifdef TINY
218-#define skip(c) next()
219-#else
220-
221-void error(char *fmt,...)
222-{
223- va_list ap;
224-
225- va_start(ap, fmt);
226- fprintf(stderr, "%d: ", ftell((FILE *)file));
227- vfprintf(stderr, fmt, ap);
228- fprintf(stderr, "\n");
229- exit(1);
230- va_end(ap);
231-}
232-
233-void skip(c)
234-{
235- if (tok != c) {
236- error("'%c' expected", c);
237- }
238- next();
239-}
240-
241-#endif
242-
243-o(n)
244-{
245- /* cannot use unsigned, so we must do a hack */
246- while (n && n != -1) {
247- *(char *)ind++ = n;
248- n = n >> 8;
249- }
250-}
251-
252-/* output a symbol and patch all calls to it */
253-gsym(t)
254-{
255- int n;
256- while (t) {
257- n = *(int *)t; /* next value */
258- *(int *)t = ind - t - 4;
259- t = n;
260- }
261-}
262-
263-/* psym is used to put an instruction with a data field which is a
264- reference to a symbol. It is in fact the same as oad ! */
265-#define psym oad
266-
267-/* instruction + address */
268-oad(n, t)
269-{
270- o(n);
271- *(int *)ind = t;
272- t = ind;
273- ind = ind + 4;
274- return t;
275-}
276-
277-/* load immediate value */
278-li(t)
279-{
280- oad(0xb8, t); /* mov $xx, %eax */
281-}
282-
283-gjmp(t)
284-{
285- return psym(0xe9, t);
286-}
287-
288-/* l = 0: je, l == 1: jne */
289-gtst(l, t)
290-{
291- o(0x0fc085); /* test %eax, %eax, je/jne xxx */
292- return psym(0x84 + l, t);
293-}
294-
295-gcmp(t)
296-{
297- o(0xc139); /* cmp %eax,%ecx */
298- li(0);
299- o(0x0f); /* setxx %al */
300- o(t + 0x90);
301- o(0xc0);
302-}
303-
304-gmov(l, t)
305-{
306- o(l + 0x83);
307- oad((t < LOCAL) << 7 | 5, t);
308-}
309-
310-/* l is one if '=' parsing wanted (quick hack) */
311-unary(l)
312-{
313- int n, t, a, c;
314-
315- n = 1; /* type of expression 0 = forward, 1 = value, other =
316- lvalue */
317- if (tok == '\"') {
318- li(glo);
319- while (ch != '\"') {
320- getq();
321- *(char *)glo++ = ch;
322- inp();
323- }
324- *(char *)glo = 0;
325- glo = glo + 4 & -4; /* align heap */
326- inp();
327- next();
328- } else {
329- c = tokl;
330- a = tokc;
331- t = tok;
332- next();
333- if (t == TOK_NUM) {
334- li(a);
335- } else if (c == 2) {
336- /* -, +, !, ~ */
337- unary(0);
338- oad(0xb9, 0); /* movl $0, %ecx */
339- if (t == '!')
340- gcmp(a);
341- else
342- o(a);
343- } else if (t == '(') {
344- expr();
345- skip(')');
346- } else if (t == '*') {
347- /* parse cast */
348- skip('(');
349- t = tok; /* get type */
350- next(); /* skip int/char/void */
351- next(); /* skip '*' or '(' */
352- if (tok == '*') {
353- /* function type */
354- skip('*');
355- skip(')');
356- skip('(');
357- skip(')');
358- t = 0;
359- }
360- skip(')');
361- unary(0);
362- if (tok == '=') {
363- next();
364- o(0x50); /* push %eax */
365- expr();
366- o(0x59); /* pop %ecx */
367- o(0x0188 + (t == TOK_INT)); /* movl %eax/%al, (%ecx) */
368- } else if (t) {
369- if (t == TOK_INT)
370- o(0x8b); /* mov (%eax), %eax */
371- else
372- o(0xbe0f); /* movsbl (%eax), %eax */
373- ind++; /* add zero in code */
374- }
375- } else if (t == '&') {
376- gmov(10, *(int *)tok); /* leal EA, %eax */
377- next();
378- } else {
379- n = *(int *)t;
380- /* forward reference: try dlsym */
381- if (!n)
382- n = dlsym(0, last_id);
383- if (tok == '=' & l) {
384- /* assignment */
385- next();
386- expr();
387- gmov(6, n); /* mov %eax, EA */
388- } else if (tok != '(') {
389- /* variable */
390- gmov(8, n); /* mov EA, %eax */
391- if (tokl == 11) {
392- gmov(0, n);
393- o(tokc);
394- next();
395- }
396- }
397- }
398- }
399-
400- /* function call */
401- if (tok == '(') {
402- if (n == 1)
403- o(0x50); /* push %eax */
404-
405- /* push args and invert order */
406- a = oad(0xec81, 0); /* sub $xxx, %esp */
407- next();
408- l = 0;
409- while(tok != ')') {
410- expr();
411- oad(0x248489, l); /* movl %eax, xxx(%esp) */
412- if (tok == ',')
413- next();
414- l = l + 4;
415- }
416- *(int *)a = l;
417- next();
418- if (!n) {
419- /* forward reference */
420- t = t + 4;
421- *(int *)t = psym(0xe8, *(int *)t);
422- } else if (n == 1) {
423- oad(0x2494ff, l); /* call *xxx(%esp) */
424- l = l + 4;
425- } else {
426- oad(0xe8, n - ind - 5); /* call xxx */
427- }
428- if (l)
429- oad(0xc481, l); /* add $xxx, %esp */
430- }
431-}
432-
433-sum(l)
434-{
435- int t, n, a;
436-
437- if (l-- == 1)
438- unary(1);
439- else {
440- sum(l);
441- a = 0;
442- while (l == tokl) {
443- n = tok;
444- t = tokc;
445- next();
446-
447- if (l > 8) {
448- a = gtst(t, a); /* && and || output code generation */
449- sum(l);
450- } else {
451- o(0x50); /* push %eax */
452- sum(l);
453- o(0x59); /* pop %ecx */
454-
455- if (l == 4 | l == 5) {
456- gcmp(t);
457- } else {
458- o(t);
459- if (n == '%')
460- o(0x92); /* xchg %edx, %eax */
461- }
462- }
463- }
464- /* && and || output code generation */
465- if (a && l > 8) {
466- a = gtst(t, a);
467- li(t ^ 1);
468- gjmp(5); /* jmp $ + 5 */
469- gsym(a);
470- li(t);
471- }
472- }
473-}
474-
475-expr()
476-{
477- sum(11);
478-}
479-
480-
481-test_expr()
482-{
483- expr();
484- return gtst(0, 0);
485-}
486-
487-block(l)
488-{
489- int a, n, t;
490-
491- if (tok == TOK_IF) {
492- next();
493- skip('(');
494- a = test_expr();
495- skip(')');
496- block(l);
497- if (tok == TOK_ELSE) {
498- next();
499- n = gjmp(0); /* jmp */
500- gsym(a);
501- block(l);
502- gsym(n); /* patch else jmp */
503- } else {
504- gsym(a); /* patch if test */
505- }
506- } else if (tok == TOK_WHILE | tok == TOK_FOR) {
507- t = tok;
508- next();
509- skip('(');
510- if (t == TOK_WHILE) {
511- n = ind;
512- a = test_expr();
513- } else {
514- if (tok != ';')
515- expr();
516- skip(';');
517- n = ind;
518- a = 0;
519- if (tok != ';')
520- a = test_expr();
521- skip(';');
522- if (tok != ')') {
523- t = gjmp(0);
524- expr();
525- gjmp(n - ind - 5);
526- gsym(t);
527- n = t + 4;
528- }
529- }
530- skip(')');
531- block(&a);
532- gjmp(n - ind - 5); /* jmp */
533- gsym(a);
534- } else if (tok == '{') {
535- next();
536- /* declarations */
537- decl(1);
538- while(tok != '}')
539- block(l);
540- next();
541- } else {
542- if (tok == TOK_RETURN) {
543- next();
544- if (tok != ';')
545- expr();
546- rsym = gjmp(rsym); /* jmp */
547- } else if (tok == TOK_BREAK) {
548- next();
549- *(int *)l = gjmp(*(int *)l);
550- } else if (tok != ';')
551- expr();
552- skip(';');
553- }
554-}
555-
556-/* 'l' is true if local declarations */
557-decl(l)
558-{
559- int a;
560-
561- while (tok == TOK_INT | tok != -1 & !l) {
562- if (tok == TOK_INT) {
563- next();
564- while (tok != ';') {
565- if (l) {
566- loc = loc + 4;
567- *(int *)tok = -loc;
568- } else {
569- *(int *)tok = glo;
570- glo = glo + 4;
571- }
572- next();
573- if (tok == ',')
574- next();
575- }
576- skip(';');
577- } else {
578- /* patch forward references (XXX: do not work for function
579- pointers) */
580- gsym(*(int *)(tok + 4));
581- /* put function address */
582- *(int *)tok = ind;
583- next();
584- skip('(');
585- a = 8;
586- while (tok != ')') {
587- /* read param name and compute offset */
588- *(int *)tok = a;
589- a = a + 4;
590- next();
591- if (tok == ',')
592- next();
593- }
594- next(); /* skip ')' */
595- rsym = loc = 0;
596- o(0xe58955); /* push %ebp, mov %esp, %ebp */
597- a = oad(0xec81, 0); /* sub $xxx, %esp */
598- block(0);
599- gsym(rsym);
600- o(0xc3c9); /* leave, ret */
601- *(int *)a = loc; /* save local variables */
602- }
603- }
604-}
605-
606-main(n, t)
607-{
608- file = stdin;
609- if (n-- > 1) {
610- t = t + 4;
611- file = fopen(*(int *)t, "r");
612- }
613- dstk = strcpy(sym_stk = calloc(1, ALLOC_SIZE),
614- " int if else while break return for define main ") + TOK_STR_SIZE;
615- glo = calloc(1, ALLOC_SIZE);
616- ind = prog = calloc(1, ALLOC_SIZE);
617- vars = calloc(1, ALLOC_SIZE);
618- inp();
619- next();
620- decl(0);
621-#ifdef TEST
622- {
623- FILE *f;
624- f = fopen(*(char **)(t + 4), "w");
625- fwrite((void *)prog, 1, ind - prog, f);
626- fclose(f);
627- return 0;
628- }
629-#else
630- return (*(int (*)())*(int *)(vars + TOK_MAIN)) (n, t);
631-#endif
632-}
--- a/libacc/test
+++ b/libacc/test
@@ -1,2 +1,2 @@
11 #!/bin/sh
2-gcc acc.c -ldl -o tests/acc && tests/acc tests/otcc.c >tests/otcc.out && diff tests/otcc.out tests/otcc.out-orig
2+gcc acc.c -DTEST -ldl -o tests/acc && tests/acc tests/otcc.c tests/otcc.out && diff tests/otcc.out tests/otcc.out-orig
Binary files a/libacc/tests/hello.out-orig and b/libacc/tests/hello.out-orig differ
Binary files a/libacc/tests/otcc.out-orig and b/libacc/tests/otcc.out-orig differ