Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 13ac7f6c authored by Android (Google) Code Review's avatar Android (Google) Code Review
Browse files

Merge change 7048

* changes:
  Implement general casts and pointer dereferencing.
parents c80b0a97 45431bc2
Loading
Loading
Loading
Loading
+27 −32
Original line number Diff line number Diff line
@@ -1019,6 +1019,7 @@ class Compiler : public ErrorSink {
            LOG_API("storeR0(%d);\n", ea);
            TypeTag tag = pType->tag;
            switch (tag) {
                case TY_POINTER:
                case TY_INT:
                case TY_FLOAT:
                    if (ea > -LOCAL && ea < LOCAL) {
@@ -2027,6 +2028,7 @@ class Compiler : public ErrorSink {
            TypeTag tag = pType->tag;
            switch (tag) {
                case TY_INT:
                case TY_POINTER:
                    gmov(6, ea); /* mov %eax, EA */
                    break;
                case TY_FLOAT:
@@ -3663,41 +3665,34 @@ class Compiler : public ErrorSink {
                    pGen->genUnaryOp(a);
                }
            } else if (t == '(') {
                // It's either a cast or an expression
                Type* pCast = acceptCastTypeDeclaration(mLocalArena);
                if (pCast) {
                    skip(')');
                    unary(false);
                    pGen->convertR0(pCast);
                } else {
                    expr();
                    skip(')');
                }
            } else if (t == '*') {
                /* This is a pointer dereference, but we currently only
                 * support a pointer dereference if it's immediately
                 * in front of a cast. So parse the cast right here.
                /* This is a pointer dereference.
                 */
                skip('(');
                Type* pCast = expectCastTypeDeclaration(mLocalArena);
                // We currently only handle 3 types of cast:
                // (int*), (char*) , (int (*)())
                if(typeEqual(pCast, mkpIntPtr)) {
                    t = TOK_INT;
                } else if (typeEqual(pCast, mkpCharPtr)) {
                    t = TOK_CHAR;
                } else if (typeEqual(pCast, mkpFloatPtr)) {
                    t = TOK_FLOAT;
                } else if (typeEqual(pCast, mkpDoublePtr)) {
                    t = TOK_DOUBLE;
                } else if (typeEqual(pCast, mkpPtrIntFn)){
                    t = 0;
                unary(false);
                Type* pR0Type = pGen->getR0Type();
                if (pR0Type->tag != TY_POINTER) {
                    error("Expected a pointer type.");
                } else {
                    String buffer;
                    decodeType(buffer, pCast);
                    error("Unsupported cast type %s", buffer.getUnwrapped());
                    decodeType(buffer, mkpPtrIntFn);
                    if (pR0Type->pHead->tag == TY_FUNC) {
                        t = 0;
                    }
                skip(')');
                unary(false);
                    if (accept('=')) {
                        pGen->pushR0();
                        expr();
                    pGen->storeR0ToTOS(pCast);
                        pGen->storeR0ToTOS(pR0Type);
                    } else if (t) {
                    pGen->loadR0FromR0(pCast);
                        pGen->loadR0FromR0(pR0Type);
                    }
                }
                // Else we fall through to the function call below, with
                // t == 0 to trigger an indirect function call. Hack!
+85 −0
Original line number Diff line number Diff line
void test1() {
    int a = 3;
    int* pb = &a;
    int c = *pb;
    printf("Reading from a pointer: %d %d\n", a, c);
    *pb = 4;
    printf("Writing to a pointer: %d\n", a);
    printf("Testing casts: %d %g %g %d\n", 3, (float) 3, 4.5, (int) 4.5);
}

void test2() {
    int x = 4;
    int px = &x;
    // int z = * px; // An error, expected a pointer type
    int y = * (int*) px;
    printf("Testing reading (int*): %d\n", y);
}

void test3() {
    int px = (int) malloc(120);
    * (int*) px = 8;
    * (int*) (px + 4) = 9;
    printf("Testing writing (int*): %d %d\n", * (int*) px, * (int*) (px + 4));
    free((void*) px);
}

void test4() {
    int x = 0x12345678;
    int px = &x;
    int a = * (char*) px;
    int b = * (char*) (px + 1);
    int c = * (char*) (px + 2);
    int d = * (char*) (px + 3);
    printf("Testing reading (char*): 0x%02x 0x%02x 0x%02x 0x%02x\n", a, b, c, d);
}

void test5() {
    int x = 0xFFFFFFFF;
    int px = &x;
    * (char*) px = 0x21;
    * (char*) (px + 1) = 0x43;
    * (char*) (px + 2) = 0x65;
    * (char*) (px + 3) = 0x87;
    printf("Testing writing (char*): 0x%08x\n", x);
}

int f(int b) {
    printf("f(%d)\n", b);
    return 7 * b;
}

void test6() {
    int fp = &f;
    int x = (*(int(*)()) fp)(10);
    printf("Function pointer result: %d\n", x);
}

void test7() {
    int px = (int) malloc(120);
    * (float*) px = 8.8f;
    * (float*) (px + 4) = 9.9f;
    printf("Testing read/write (float*): %g %g\n", * (float*) px, * (float*) (px + 4));
    free((void*) px);
}

void test8() {
    int px = (int) malloc(120);
    * (double*) px = 8.8;
    * (double*) (px + 8) = 9.9;
    printf("Testing read/write (double*): %g %g\n", * (double*) px, * (double*) (px + 8));
    free((void*) px);
}


int main() {
    test1();
    test2();
    test3();
    test4();
    test5();
    test6();
    test7();
    test8();
    return 0;
}
+84 −68
Original line number Diff line number Diff line
@@ -77,7 +77,14 @@ def firstDifference(a, b):
            return i
    return commonLen

def compareSet(a1,a2,b1,b2):
# a1 and a2 are the expected stdout and stderr.
# b1 and b2 are the actual stdout and stderr.
# Compare the two, sets. Allow any individual line
# to appear in either stdout or stderr. This is because
# the way we obtain output on the ARM combines both
# streams into one sequence.

def compareOuput(a1,a2,b1,b2):
    while True:
        totalLen = len(a1) + len(a2) + len(b1) + len(b2)
        a1, b1 = matchCommon(a1, b1)
@@ -96,6 +103,8 @@ def compareSet(a1,a2,b1,b2):
            return False

def matchCommon(a, b):
    """Remove common items from the beginning of a and b,
       return just the tails that are different."""
    while len(a) > 0 and len(b) > 0 and a[0] == b[0]:
        a = a[1:]
        b = b[1:]
@@ -105,25 +114,20 @@ def rewritePaths(args):
    return [rewritePath(x) for x in args]

def rewritePath(p):
    """Take a path that's correct on the x86 and convert to a path
       that's correct on ARM."""
    if p.startswith("data/"):
        p = "/system/bin/accdata/" + p
    return p

class TestACC(unittest.TestCase):

    def compileCheckOld(self, args, stdErrResult, stdOutResult=""):
        out, err = compile(args)
        compare(out, stdOutResult)
        compare(err, stdErrResult)
        self.assertEqual(out, stdOutResult)
        self.assertEqual(err, stdErrResult)

    def checkResult(self, out, err, stdErrResult, stdOutResult=""):
        a1 = out.splitlines()
        a2 = err.splitlines()
        b2 = stdErrResult.splitlines()
        b1 = stdOutResult.splitlines()
        self.assertEqual(True, compareSet(a1,a2,b1,b2))
        self.assertEqual(True, compareOuput(a1,a2,b1,b2))
        
    def compileCheck(self, args, stdErrResult, stdOutResult="",
                     targets=['arm', 'x86']):
@@ -174,65 +178,77 @@ class TestACC(unittest.TestCase):
        
    def testRunFlops(self):
        self.compileCheck(["-R", "data/flops.c"],
            "Executing compiled code:\nresult: 0\n",
            "-1.1 = -1.1\n" +
            "!1.2 = 0\n" +
            "!0 = 1\n" +
            "double op double:\n" +
            "1 + 2 = 3\n" +
            "1 - 2 = -1\n" +
            "1 * 2 = 2\n" +
            "1 / 2 = 0.5\n" +
            "float op float:\n" +
            "1 + 2 = 3\n" +
            "1 - 2 = -1\n" +
            "1 * 2 = 2\n" +
            "1 / 2 = 0.5\n" +
            "double op float:\n" +
            "1 + 2 = 3\n" +
            "1 - 2 = -1\n" +
            "1 * 2 = 2\n" +
            "1 / 2 = 0.5\n" +
            "double op int:\n" +
            "1 + 2 = 3\n" +
            "1 - 2 = -1\n" +
            "1 * 2 = 2\n" +
            "1 / 2 = 0.5\n" +
            "int op double:\n" +
            "1 + 2 = 3\n" +
            "1 - 2 = -1\n" +
            "1 * 2 = 2\n" +
            "1 / 2 = 0.5\n" +
            "double op double:\n" +
            "1 op 2: < 1   <= 1   == 0   >= 0   > 0   != 1\n" +
            "1 op 1: < 0   <= 1   == 1   >= 1   > 0   != 0\n" +
            "2 op 1: < 0   <= 0   == 0   >= 1   > 1   != 1\n" +
            "double op float:\n" +
            "1 op 2: < 1   <= 1   == 0   >= 0   > 0   != 1\n" +
            "1 op 1: < 0   <= 1   == 1   >= 1   > 0   != 0\n" +
            "2 op 1: < 0   <= 0   == 0   >= 1   > 1   != 1\n" +
            "float op float:\n" +
            "1 op 2: < 1   <= 1   == 0   >= 0   > 0   != 1\n" +
            "1 op 1: < 0   <= 1   == 1   >= 1   > 0   != 0\n" +
            "2 op 1: < 0   <= 0   == 0   >= 1   > 1   != 1\n" +
            "int op double:\n" +
            "1 op 2: < 1   <= 1   == 0   >= 0   > 0   != 1\n" +
            "1 op 1: < 0   <= 1   == 1   >= 1   > 0   != 0\n" +
            "2 op 1: < 0   <= 0   == 0   >= 1   > 1   != 1\n" +
            "double op int:\n" +
            "1 op 2: < 1   <= 1   == 0   >= 0   > 0   != 1\n" +
            "1 op 1: < 0   <= 1   == 1   >= 1   > 0   != 0\n" +
            "2 op 1: < 0   <= 0   == 0   >= 1   > 1   != 1\n" +
            "branching: 1 0 1\n" +
            "testpassi: 1 2 3 4 5 6 7 8\n" +
            "testpassf: 1 2 3 4 5 6 7 8\n" +
            "testpassd: 1 2 3 4 5 6 7 8\n" +
            "testpassidf: 1 2 3\n"
            )
        
    def oldtestArmRunReturnVal(self):
        self.compileCheckArm(["-R", "/system/bin/accdata/data/returnval-ansi.c"],
            "Executing compiled code:\nresult: 42\n")
            """Executing compiled code:
result: 0""",
"""-1.1 = -1.1
!1.2 = 0
!0 = 1
double op double:
1 + 2 = 3
1 - 2 = -1
1 * 2 = 2
1 / 2 = 0.5
float op float:
1 + 2 = 3
1 - 2 = -1
1 * 2 = 2
1 / 2 = 0.5
double op float:
1 + 2 = 3
1 - 2 = -1
1 * 2 = 2
1 / 2 = 0.5
double op int:
1 + 2 = 3
1 - 2 = -1
1 * 2 = 2
1 / 2 = 0.5
int op double:
1 + 2 = 3
1 - 2 = -1
1 * 2 = 2
1 / 2 = 0.5
double op double:
1 op 2: < 1   <= 1   == 0   >= 0   > 0   != 1
1 op 1: < 0   <= 1   == 1   >= 1   > 0   != 0
2 op 1: < 0   <= 0   == 0   >= 1   > 1   != 1
double op float:
1 op 2: < 1   <= 1   == 0   >= 0   > 0   != 1
1 op 1: < 0   <= 1   == 1   >= 1   > 0   != 0
2 op 1: < 0   <= 0   == 0   >= 1   > 1   != 1
float op float:
1 op 2: < 1   <= 1   == 0   >= 0   > 0   != 1
1 op 1: < 0   <= 1   == 1   >= 1   > 0   != 0
2 op 1: < 0   <= 0   == 0   >= 1   > 1   != 1
int op double:
1 op 2: < 1   <= 1   == 0   >= 0   > 0   != 1
1 op 1: < 0   <= 1   == 1   >= 1   > 0   != 0
2 op 1: < 0   <= 0   == 0   >= 1   > 1   != 1
double op int:
1 op 2: < 1   <= 1   == 0   >= 0   > 0   != 1
1 op 1: < 0   <= 1   == 1   >= 1   > 0   != 0
2 op 1: < 0   <= 0   == 0   >= 1   > 1   != 1
branching: 1 0 1
testpassi: 1 2 3 4 5 6 7 8
testpassf: 1 2 3 4 5 6 7 8
testpassd: 1 2 3 4 5 6 7 8
testpassidf: 1 2 3
""")
    def testCasts(self):
        self.compileCheck(["-R", "data/casts.c"],
            """Executing compiled code:
result: 0""", """Reading from a pointer: 3 3
Writing to a pointer: 4
Testing casts: 3 3 4.5 4
Testing reading (int*): 4
Testing writing (int*): 8 9
Testing reading (char*): 0x78 0x56 0x34 0x12
Testing writing (char*): 0x87654321
f(10)
Function pointer result: 70
Testing read/write (float*): 8.8 9.9
Testing read/write (double*): 8.8 9.9
""")

if __name__ == '__main__':
    if not outputCanRun():