From 0bbd98b0064e4344b9b6f3ce63b55a6e8397ceff Mon Sep 17 00:00:00 2001 From: Xun Yang <x299yang@uwaterloo.ca> Date: Mon, 13 Apr 2020 00:47:44 -0400 Subject: [PATCH] array subtype table --- AstBuilding.py | 41 +++++++++++++++++++++++++++++++++++++---- TypeNodes.py | 8 ++++++++ 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/AstBuilding.py b/AstBuilding.py index 2d3409c..3508248 100644 --- a/AstBuilding.py +++ b/AstBuilding.py @@ -1,6 +1,7 @@ from CompNode import CompNode from pprint import pprint from Environment import GlobalEnv +from TypeNodes import getSupers from CodeGenUtils import p, genProcedure, used_labels, local_labels, pLabel, genericHelperFunctions, globalImport # tree: (filename, parseTree) @@ -62,23 +63,47 @@ def reachabilityChecking(ASTs): # Returns a dictionary (type e.g. "boolean") -> str (the assembly code generated) def arrayClassMemory(types): # All method labels from java.lang.Object - # TODO: add subtype testing table methods = ["M_Object_Object_", "M_Object_equals_Object", "M_Object_toString_", "M_Object_hashCode_", "M_Object_clone_", "M_Object_getClass_"] - typeDict = {} primTypes = ['boolean', 'byte', 'char', 'int', 'short'] # All possible types - for t in types: + typeDict = {} + # assignable = dict({"java.lang.Object" : 0, + # "java.lang.Cloneable" : 4, + # "java.io.Serializable" : 8 + # }) + + for tt in types: # Class memory layout # Label: "A_type" # Label for SIT pointer: "I_SIT_spot_typeName_array" # Label for method pointers: "V_typeName_methodName_param_array" + if tt.__class__.__name__ == "ClassNode": + t = tt.name + else: + t = tt + code = "section .data\n" code += "; Start of class memory layout\n" code += pLabel(name=t, type="array") + \ pLabel("SIT_spot_"+ t + "_array", "inter") + \ p(instruction="dd", arg1=64) + + # point to subtype table + code += pLabel("subT_spot_" + t, "inter") + code += p("dd", "42") + for m in methods: code += pLabel(name=t+"_"+m+"_array", type="vtable") + \ p(instruction="dd", arg1=64) + + # layout subtype table + code += pLabel("subT_" + t, "inter") + code += p("dd", "0") # row 0 = false for all other objects + for i in range(3): + code += p("dd", "1") # True for 3 objects + + for i in range (len(types) - 5): # non primtype arrays + code += pLabel("subT_" + str(i), "inter") + code += p("dd", "0") code += "; End of class memory layout\n" # Creating a function to initialize class memory layout @@ -94,6 +119,14 @@ def arrayClassMemory(types): code += p(instruction="extern", arg1=m) + \ p(instruction="mov", arg1="eax", arg2="dword V_"+t+"_"+m+"_array") + \ p(instruction="mov", arg1="[eax]", arg2="dword "+m, comment="points to method implementation") + + # fill in SubT for non-primType arrays + if tt.__class__.__name__ == "ClassNode": + for s in getSupers(tt): + dlabel = "I_subT_" + str(s.subTypeOffset // 4) # 9 = 4 objects + 5 primtype arrays + code += p("mov", "eax", dlabel, "self is a subType of array " + s.canonName) + code += p("mov", "[eax]", "dword 1") + code += p(instruction="ret", arg1="") code += "; End of function to initialize class memory layout\n" if t in primTypes: @@ -118,7 +151,7 @@ def codeGenPrep(ASTs): classInterNode = t[1].typeDcl if classInterNode.__class__.__name__ == "ClassNode": - types.append(classInterNode.name) + types.append(classInterNode) classNodes.append(classInterNode) else: # interfaceNode, get their methods to prep for SIT interM += classInterNode.methods diff --git a/TypeNodes.py b/TypeNodes.py index 99fab64..e3bca58 100644 --- a/TypeNodes.py +++ b/TypeNodes.py @@ -19,6 +19,7 @@ class ClassInterNode(ASTNode): self.SITsize = 0 self.subTypeSize = 0 self.subTypeOffset = 0 + self.arrayTypeOffset = 0 # only array assignable classes will have this field set # sets self.inherits = [] @@ -307,6 +308,13 @@ class ClassNode(ClassInterNode): # Calculating the size of objects of this class self.size += (len(self.fieldOffset))*4 + assignable = dict({"java.lang.Object" : 4, + "java.lang.Cloneable" : 8, + "java.io.Serializable" : 12 + }) # fix offsets for array assignable classes, 0 row is reserve for all the non assignable ones + if self.canonName in assignable.keys(): + self.arrayTypeOffset = assignable[self.canonName] + # Populating method offset and creating class memory layout def populateMethodOffset(self): if hasattr(self, "data"): -- GitLab