From 4a8fb3c062d6326690ba149faa6016994d21c100 Mon Sep 17 00:00:00 2001
From: Xun Yang <x299yang@uwaterloo.ca>
Date: Mon, 13 Apr 2020 15:25:36 -0400
Subject: [PATCH] fix array cast check

---
 ExprPrimaryNodes.py | 56 ++++++++++++++++++++++++++++++---------------
 1 file changed, 37 insertions(+), 19 deletions(-)

diff --git a/ExprPrimaryNodes.py b/ExprPrimaryNodes.py
index 1ac5ba8..ab85e8e 100644
--- a/ExprPrimaryNodes.py
+++ b/ExprPrimaryNodes.py
@@ -414,17 +414,24 @@ class CastNode(ASTNode):
         self.code += self.right.code
 
         # subtype test:
-        if (not self.left.myType.isPrimitive) and self.right.myType.isArray ==  self.left.myType.isArray:
-            # only test if not primitive,  both are array or both non array
-            # cast would've exception if array is casting to non-array and not Object
-            offset = self.left.myType.typePointer.subTypeOffset
-            self.code += p("mov", "ebx", "[eax]", "start subtype test") # access class tag of left object
-            self.code += p("mov", "ebx", "[ebx + 4]") # access subtype testing column
-            self.code += p("mov", "ebx", "[ebx + " + str(offset) + "]") # ebx has isSubtype
 
-            # exception if not subtype, else do nothing (object is already in eax)
-            self.code += p("cmp", "[G__Zero]", "ebx")
-            self.code += p("je", "H__Throw_Exception")
+        # only test if not primitive
+        if self.right.myType.isArray ==  self.left.myType.isArray:
+            if (not self.left.myType.isPrimitive):
+                # cast would've exception if array is casting to non-array and not Object
+                offset = self.left.myType.typePointer.subTypeOffset
+                self.code += p("mov", "ebx", "[eax]", "start subtype test") # access class tag of left object
+                self.code += p("mov", "ebx", "[ebx + 4]") # access subtype testing column
+                self.code += p("mov", "ebx", "[ebx + " + str(offset) + "]") # ebx has isSubtype
+
+                # exception if not subtype, else do nothing (object is already in eax)
+                self.code += p("cmp", "[G__Zero]", "ebx")
+                self.code += p("je", "H__Throw_Exception")
+        else: # one is array, one is Object/Serializable/Cloneable
+            # make sure cast only one way
+            if self.left.myType.isArray:
+                self.code += p("jmp", "H__Throw_Exception")
+
         self.code += "; end of casting\n"
 
 ###################################################################################
@@ -667,16 +674,27 @@ class ExprNode(ASTNode):
             self.code += self.left.code
 
             # only test if non-primitive, both arrays or both non arrays
-            if (not self.right.myType.isPrimitive) and self.right.myType.isArray == self.left.myType.isArray:
-                offset = self.right.myType.typePointer.subTypeOffset
-                self.code += p("mov", "eax", "[eax]") # access class tag of left object
-                self.code += p("mov", "eax", "[eax + 4]") # access subtype testing column
-                self.code += p("mov", "eax", "[eax + " + str(offset) + "]") # subType column stores 0 or 1 already
-            else: # primitive type can be staticly evaluated
-                if self.right.myType.assignable(self.left.myType):
-                    self.code += p("mov", "eax", "1")
-                else:
+            if self.right.myType.isArray == self.left.myType.isArray:
+                if not self.right.myType.isPrimitive:
+                    offset = self.right.myType.typePointer.subTypeOffset
+                    self.code += p("mov", "eax", "[eax]") # access class tag of left object
+                    self.code += p("mov", "eax", "[eax + 4]") # access subtype testing column
+                    self.code += p("mov", "eax", "[eax + " + str(offset) + "]") # subType column stores 0 or 1 already
+
+                else: # primitive type can be staticly evaluated
+                    if self.right.myType.assignable(self.left.myType):
+                        self.code += p("mov", "eax", "1")
+                    else:
+                        self.code += p("mov", "eax", "0")
+
+            else: # non array is never an instance of array, array could be non array
+                if self.right.myType.isArray:
                     self.code += p("mov", "eax", "0")
+                else:
+                    if self.right.myType.assignable(self.left.myType):
+                        self.code += p("mov", "eax", "1")
+                    else:
+                        self.code += p("mov", "eax", "0")
 
             self.code += ("; end of instanceof\n")
             return
-- 
GitLab