From b7c81e99522fbc5256f20e826eae18f2a33ea76a Mon Sep 17 00:00:00 2001 From: Jack Palevich Date: Thu, 4 Jun 2009 19:56:13 -0700 Subject: [PATCH] Switch to ANSI C style C function declarations. main(argc, argv) --> int main(int argc, char** argv) Although we accept int, void, and char types, and pointers to same, we actually still treat everything as an int. --- libacc/acc.cpp | 162 ++++++++--- libacc/tests/data/otcc-ansi.c | 449 +++++++++++++++++++++++++++++ libacc/tests/data/returnval-ansi.c | 7 + libacc/tests/main.cpp | 4 +- libacc/tests/testarm | 4 +- libacc/tests/testlocal | 8 +- 6 files changed, 594 insertions(+), 40 deletions(-) create mode 100644 libacc/tests/data/otcc-ansi.c create mode 100644 libacc/tests/data/returnval-ansi.c diff --git a/libacc/acc.cpp b/libacc/acc.cpp index 096500dd8..de36ce552 100644 --- a/libacc/acc.cpp +++ b/libacc/acc.cpp @@ -41,7 +41,6 @@ #define LOG_API(...) do {} while(0) // #define LOG_API(...) fprintf (stderr, __VA_ARGS__) - // #define ENABLE_ARM_DISASSEMBLY namespace acc { @@ -389,7 +388,7 @@ class Compiler : public ErrorSink { /* returns address to patch with local variable size */ virtual int functionEntry(int argCount) { - LOG_API(stderr, "functionEntry(%d);\n", argCount); + LOG_API("functionEntry(%d);\n", argCount); // sp -> arg4 arg5 ... // Push our register-based arguments back on the stack if (argCount > 0) { @@ -1187,15 +1186,17 @@ class Compiler : public ErrorSink { // Indentifiers start at 0x100 and increase by # (chars + 1) * 8 static const int TOK_IDENT = 0x100; static const int TOK_INT = 0x100; - static const int TOK_IF = 0x120; - static const int TOK_ELSE = 0x138; - static const int TOK_WHILE = 0x160; - static const int TOK_BREAK = 0x190; - static const int TOK_RETURN = 0x1c0; - static const int TOK_FOR = 0x1f8; - static const int TOK_PRAGMA = 0x218; - static const int TOK_DEFINE = TOK_PRAGMA + (7*8); - static const int TOK_MAIN = TOK_DEFINE + (7*8); + static const int TOK_CHAR = TOK_INT + 4*8; + static const int TOK_VOID = TOK_CHAR + 5*8; + static const int TOK_IF = TOK_VOID + 5*8; + static const int TOK_ELSE = TOK_IF + 3*8; + static const int TOK_WHILE = TOK_ELSE + 5*8; + static const int TOK_BREAK = TOK_WHILE + 6*8; + static const int TOK_RETURN = TOK_BREAK + 6*8; + static const int TOK_FOR = TOK_RETURN + 7*8; + static const int TOK_PRAGMA = TOK_FOR + 4*8; + static const int TOK_DEFINE = TOK_PRAGMA + 7*8; + static const int TOK_MAIN = TOK_DEFINE + 7*8; static const int TOK_DUMMY = 1; static const int TOK_NUM = 2; @@ -1256,7 +1257,9 @@ class Compiler : public ErrorSink { } } else ch = file->getChar(); - /* printf("ch=%c 0x%x\n", ch, ch); */ +#if 0 + printf("ch='%c' 0x%x\n", ch, ch); +#endif } int isid() { @@ -1685,7 +1688,7 @@ class Compiler : public ErrorSink { } else if (tok == '{') { next(); /* declarations */ - decl(1); + localDeclarations(); while (tok != '}') block(l); next(); @@ -1704,36 +1707,125 @@ class Compiler : public ErrorSink { } } - /* 'l' is true if local declarations */ - void decl(bool l) { - intptr_t a; + typedef int Type; + static const Type TY_UNKNOWN = 0; + static const Type TY_INT = 1; + static const Type TY_CHAR = 2; + static const Type TY_VOID = 3; + static const int TY_BASE_TYPE_MASK = 0xf; + static const int TY_INDIRECTION_MASK = 0xf0; + static const int TY_INDIRECTION_SHIFT = 4; + static const int MAX_INDIRECTION_COUNT = 15; + + Type getBaseType(Type t) { + return t & TY_BASE_TYPE_MASK; + } + + int getIndirectionCount(Type t) { + return (TY_INDIRECTION_MASK & t) >> TY_INDIRECTION_SHIFT; + } + + void setIndirectionCount(Type& t, int count) { + t = ((TY_INDIRECTION_MASK & (count << TY_INDIRECTION_SHIFT)) + | (t & ~TY_INDIRECTION_MASK)); + } + + bool acceptType(Type& t) { + t = TY_UNKNOWN; + if (tok == TOK_INT) { + t = TY_INT; + } else if (tok == TOK_CHAR) { + t = TY_CHAR; + } else if (tok == TOK_VOID) { + t = TY_VOID; + } else { + return false; + } + next(); + return true; + } + + Type acceptPointerDeclaration(Type& base) { + Type t = base; + int indirectionCount = 0; + while (tok == '*' && indirectionCount <= MAX_INDIRECTION_COUNT) { + next(); + indirectionCount++; + } + if (indirectionCount > MAX_INDIRECTION_COUNT) { + error("Too many levels of pointer. Max %d", MAX_INDIRECTION_COUNT); + } + setIndirectionCount(t, indirectionCount); + return t; + } + + void expectType(Type& t) { + if (!acceptType(t)) { + error("Expected a type."); + } + } + + void checkSymbol() { + if (tok <= TOK_DEFINE) { + error("Expected a symbol"); + } + } + + void localDeclarations() { + intptr_t a; + Type base; + + while (acceptType(base)) { + while (tok != ';') { + Type t = acceptPointerDeclaration(t); + checkSymbol(); + loc = loc + 4; + *(int *) tok = -loc; - while ((tok == TOK_INT) | ((tok != EOF) & (!l))) { - if (tok == TOK_INT) { next(); - while (tok != ';') { - if (l) { - loc = loc + 4; - *(int *) tok = -loc; - } else { - *(int* *) tok = (int*) allocGlobalSpace(4); + if (tok == ',') + next(); + } + skip(';'); + } + } + + void globalDeclarations() { + while (tok != EOF) { + Type base; + expectType(base); + Type t = acceptPointerDeclaration(t); + checkSymbol(); + int name = tok; + next(); + if (tok == ',' || tok == ';') { + // it's a variable declaration + for(;;) { + *(int* *) name = (int*) allocGlobalSpace(4); + if (tok != ',') { + break; } next(); - if (tok == ',') - next(); + t = acceptPointerDeclaration(t); + checkSymbol(); + name = tok; + next(); } skip(';'); } else { - /* patch forward references (XXX: do not work for function + /* patch forward references (XXX: does not work for function pointers) */ - pGen->gsym(*(int *) (tok + 4)); + pGen->gsym(*(int *) (name + 4)); /* put function address */ - *(int *) tok = codeBuf.getPC(); - next(); + *(int *) name = codeBuf.getPC(); skip('('); - a = 8; + intptr_t a = 8; int argCount = 0; while (tok != ')') { + Type aType; + expectType(aType); + aType = acceptPointerDeclaration(aType); + checkSymbol(); /* read param name and compute offset */ *(int *) tok = a; a = a + 4; @@ -1742,7 +1834,7 @@ class Compiler : public ErrorSink { next(); argCount++; } - next(); /* skip ')' */ + skip(')'); /* skip ')' */ rsym = loc = 0; a = pGen->functionEntry(argCount); block(0); @@ -1868,7 +1960,9 @@ public: file = new TextInputStream(text, textLength); sym_stk = (char*) calloc(1, ALLOC_SIZE); static const char* predefinedSymbols = - " int if else while break return for pragma define main "; + " int char void" + " if else while break return for" + " pragma define main "; dstk = strcpy(sym_stk, predefinedSymbols) + strlen(predefinedSymbols); pGlobalBase = (char*) calloc(1, ALLOC_SIZE); @@ -1876,7 +1970,7 @@ public: pVarsBase = (char*) calloc(1, ALLOC_SIZE); inp(); next(); - decl(0); + globalDeclarations(); pGen->finishCompile(); } return result; diff --git a/libacc/tests/data/otcc-ansi.c b/libacc/tests/data/otcc-ansi.c new file mode 100644 index 000000000..069514bf0 --- /dev/null +++ b/libacc/tests/data/otcc-ansi.c @@ -0,0 +1,449 @@ +// #include +int d, z, C, h, P, K, ac, q, G, v, Q, R, D, L, W, M; + +void E(int e) { + *(char*) D++ = e; +} + +void o() { + if (L) { + h = *(char*) L++; + if (h == 2) { + L = 0; + h = W; + } + } else + h = fgetc(Q); +} + +int X() { + return isalnum(h) | h == 95; +} + +void Y() { + if (h == 92) { + o(); + if (h == 110) + h = 10; + } +} + +void ad() { + int e, j, m; + while (isspace(h) | h == 35) { + if (h == 35) { + o(); + ad(); + if (d == 536) { + ad(); + E(32); + *(int*) d = 1; + *(int*) (d + 4) = D; + } + while (h != 10) { + E(h); + o(); + } + E(h); + E(2); + } + o(); + } + C = 0; + d = h; + if (X()) { + E(32); + M = D; + while (X()) { + E(h); + o(); + } + if (isdigit(d)) { + z = strtol(M, 0, 0); + d = 2; + } else { + *(char*) D = 32; + d = strstr(R, M - 1) - R; + *(char*) D = 0; + d = d * 8 + 256; + if (d > 536) { + d = P + d; + if (*(int*) d == 1) { + L = *(int*) (d + 4); + W = h; + o(); + ad(); + } + } + } + } else { + o(); + if (d == 39) { + d = 2; + Y(); + z = h; + o(); + o(); + } else if (d == 47 & h == 42) { + o(); + while (h) { + while (h != 42) + o(); + o(); + if (h == 47) + h = 0; + } + o(); + ad(); + } else { + e + = "++#m--%am*@R<^1c/@%[_[H3c%@%[_[H3c+@.B#d-@%:_^BKd<>`/03e<=0f>=/f<@.f>@1f==&g!='g&&k||#l&@.BCh^@.BSi|@.B+j~@/%Yd!@&d*@b"; + while (j = *(char*) e++) { + m = *(char*) e++; + z = 0; + while ((C = *(char*) e++ - 98) < 0) + z = z * 64 + C + 64; + if (j == d & (m == h | m == 64)) { + if (m == h) { + o(); + d = 1; + } + break; + } + } + } + } +} + +void ae(int g) { + while( g&&g!=-1) { + *(char*) q++=g; + g=g>>8; + } +} + +void A(int e) { + int g; + while( e) { + g=*(int*) e; + *(int*) e=q-e-4; + e=g; + } +} + +int s(int g, int e) { + ae(g); + *(int*) q = e; + e = q; + q = q + 4; + return e; +} + +void H(int e) { + s(184,e); +} + +int B(int e) { + return s(233,e); +} + +int S(int j, int e) { + ae(1032325); + return s(132 + j, e); +} + +void Z(int e) { + ae( 49465); + H(0); + ae( 15); + ae( e+144); + ae( 192); +} + +void N(int j, int e) { + ae(j + 131); + s((e < 512) << 7 | 5, e); +} + +void T (int j) { + int g,e,m,aa; + g=1; + if( d == 34) { + H(v); + while( h!=34) { + Y (); + *(char*) v++=h; + o (); + } + *(char*) v=0; + v=v +4&-4; + o (); + ad(); + } + else { + aa=C; + m= z; + e=d; + ad(); + if( e == 2) { + H(m); + } + else if( aa == 2) { + T(0); + s(185,0); + if( e == 33)Z(m); + else ae( m); + } + else if( e == 40) { + w (); + ad(); + } + else if( e == 42) { + ad(); + e=d; + ad(); + ad(); + if( d == 42) { + ad(); + ad(); + ad(); + ad(); + e=0; + } + ad(); + T(0); + if( d == 61) { + ad(); + ae( 80); + w (); + ae( 89); + ae( 392+(e == 256)); + } + else if( e) { + if( e == 256)ae( 139); + else ae( 48655); + q++; + } + } + else if( e == 38) { + N(10,*(int*) d); + ad(); + } + else { + g=*(int*) e; + if(!g)g=dlsym(0,M); + if( d == 61&j) { + ad(); + w (); + N(6,g); + } + else if( d!= 40) { + N(8,g); + if( C == 11) { + N(0,g); + ae( z); + ad(); + } + } + } + } + if( d == 40) { + if( g == 1)ae( 80); + m= s(60545,0); + ad(); + j=0; + while( d!= 41) { + w (); + s(2393225,j); + if( d == 44)ad(); + j=j +4; + } + *(int*) m= j; + ad(); + if(!g) { + e=e +4; + *(int*) e=s(232,*(int*) e); + } + else if( g == 1) { + s(2397439,j); + j=j +4; + } + else { + s(232,g-q-5); + } + if( j)s(50305,j); + } +} + +void O (int j) { + int e,g,m; + if( j--== 1)T(1); + else { + O (j); + m= 0; + while( j == C) { + g=d; + e=z; + ad(); + if( j>8) { + m= S(e,m); + O (j); + } + else { + ae( 80); + O (j); + ae( 89); + if( j == 4|j == 5) { + Z(e); + } + else { + ae( e); + if( g == 37)ae( 146); + } + } + } + if( m&&j>8) { + m= S(e,m); + H(e^1); + B(5); + A(m); + H(e); + } + } +} + +void w() { + O(11); +} + +int U() { + w(); + return S(0, 0); +} + +void I (int j) { + int m,g,e; + if( d == 288) { + ad(); + ad(); + m= U (); + ad(); + I (j); + if( d == 312) { + ad(); + g=B(0); + A(m); + I (j); + A(g); + } + else { + A(m); + } + } + else if( d == 352|d == 504) { + e=d; + ad(); + ad(); + if( e == 352) { + g=q; + m= U (); + } + else { + if( d!= 59)w (); + ad(); + g=q; + m= 0; + if( d!= 59)m= U (); + ad(); + if( d!= 41) { + e=B(0); + w (); + B(g-q-5); + A(e); + g=e +4; + } + } + ad(); + I(&m); + B(g-q-5); + A(m); + } + else if( d == 123) { + ad(); + ab(1); + while( d!= 125)I (j); + ad(); + } + else { + if( d == 448) { + ad(); + if( d!= 59)w (); + K=B(K); + } + else if( d == 400) { + ad(); + *(int*) j=B(*(int*) j); + } + else if( d!= 59)w (); + ad(); + } +} + +void ab (int j) { + int m; + while( d == 256|d!=-1&!j) { + if( d == 256) { + ad(); + while( d!= 59) { + if( j) { + G=G +4; + *(int*) d=-G; + } + else { + *(int*) d=v; + v=v +4; + } + ad(); + if( d == 44)ad(); + } + ad(); + } + else { + A(*(int*)(d +4)); + *(int*) d=q; + ad(); + ad(); + m= 8; + while( d!= 41) { + *(int*) d=m; + m= m +4; + ad(); + if( d == 44)ad(); + } + ad(); + K=G=0; + ae( 15042901); + m= s(60545,0); + I(0); + A(K); + ae( 50121); + *(int*) m= G; + } + } +} + +int main(int g, int e) { + Q = stdin; + if (g-- > 1) { + e = e + 4; + Q = fopen(*(int*) e, "r"); + } + D = strcpy(R = calloc(1, 99999), " int if else while break return for define main ") + 48; + v = calloc(1, 99999); + q = ac = calloc(1, 99999); + P = calloc(1, 99999); + o(); + ad(); + ab(0); + return (*(int(*)()) *(int*) (P + 592))(g, e); +} diff --git a/libacc/tests/data/returnval-ansi.c b/libacc/tests/data/returnval-ansi.c new file mode 100644 index 000000000..42802c5cc --- /dev/null +++ b/libacc/tests/data/returnval-ansi.c @@ -0,0 +1,7 @@ +int main(int argc, char** argv) { + return f(); +} + +int f() { + return 10; +} diff --git a/libacc/tests/main.cpp b/libacc/tests/main.cpp index 6b39f5732..acee09d3c 100644 --- a/libacc/tests/main.cpp +++ b/libacc/tests/main.cpp @@ -68,12 +68,14 @@ int main(int argc, char** argv) { fseek(in, 0, SEEK_END); size_t fileSize = (size_t) ftell(in); rewind(in); - ACCchar* text = new ACCchar[fileSize]; + ACCchar* text = new ACCchar[fileSize + 1]; size_t bytesRead = fread(text, 1, fileSize, in); if (bytesRead != fileSize) { fprintf(stderr, "Could not read all of file %s\n", inFile); } + text[fileSize] = '\0'; + ACCscript* script = accCreateScript(); const ACCchar* scriptSource[] = {text}; diff --git a/libacc/tests/testarm b/libacc/tests/testarm index db7ebe550..24fbc422b 100755 --- a/libacc/tests/testarm +++ b/libacc/tests/testarm @@ -1,9 +1,9 @@ #!/bin/sh adb remount adb shell rm /system/bin/acc -adb push data/returnval.c /system/bin/returnval.c +adb push data/returnval-ansi.c /system/bin/returnval-ansi.c cd .. mm -j8 cd tests adb sync -adb shell /system/bin/acc -S /system/bin/returnval.c +adb shell /system/bin/acc -S /system/bin/returnval-ansi.c diff --git a/libacc/tests/testlocal b/libacc/tests/testlocal index 547aed57a..ccabf7d50 100755 --- a/libacc/tests/testlocal +++ b/libacc/tests/testlocal @@ -4,12 +4,14 @@ cd .. g++ -I../include acc.cpp disassem.cpp tests/main.cpp -g -ldl -o tests/test-acc cd tests if [ -x "test-acc" ]; then - ./test-acc -S data/returnval.c + ./test-acc -S data/returnval-ansi.c if [ "$(uname)" = "Linux" ]; then if [ "$(uname -m)" = "i686" ]; then - echo "Linux i686. Testing otcc-noinclude.c" - ./test-acc data/otcc-noinclude.c data/otcc.c data/returnval.c + echo "Linux i686. Testing otcc-ansi.c" + ./test-acc data/otcc-ansi.c data/returnval.c + echo "Linux i686. Testing otcc-ansi.c data/otcc.c" + ./test-acc data/otcc-ansi.c data/otcc.c data/returnval.c fi fi fi