summaryrefslogtreecommitdiffstats
path: root/libacc
diff options
context:
space:
mode:
authorJack Palevich <jackpal@google.com>2009-06-04 19:56:13 -0700
committerJack Palevich <jackpal@google.com>2009-06-04 19:56:13 -0700
commitb7c81e99522fbc5256f20e826eae18f2a33ea76a (patch)
tree939f5bbd87f1c4c87a834bab92fb2eef12851b16 /libacc
parenteedf9d20832f1af3a4bd362819be6eace54240b5 (diff)
downloadsystem_core-b7c81e99522fbc5256f20e826eae18f2a33ea76a.zip
system_core-b7c81e99522fbc5256f20e826eae18f2a33ea76a.tar.gz
system_core-b7c81e99522fbc5256f20e826eae18f2a33ea76a.tar.bz2
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.
Diffstat (limited to 'libacc')
-rw-r--r--libacc/acc.cpp160
-rw-r--r--libacc/tests/data/otcc-ansi.c449
-rw-r--r--libacc/tests/data/returnval-ansi.c7
-rw-r--r--libacc/tests/main.cpp4
-rwxr-xr-xlibacc/tests/testarm4
-rwxr-xr-xlibacc/tests/testlocal8
6 files changed, 593 insertions, 39 deletions
diff --git a/libacc/acc.cpp b/libacc/acc.cpp
index 096500d..de36ce5 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) {
+ 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 0000000..069514b
--- /dev/null
+++ b/libacc/tests/data/otcc-ansi.c
@@ -0,0 +1,449 @@
+// #include <stdio.h>
+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<<Z/03e>>`/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 0000000..42802c5
--- /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 6b39f57..acee09d 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 db7ebe5..24fbc42 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 547aed5..ccabf7d 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