diff --git a/AstBuilding.py b/AstBuilding.py index de97379b3853c8d40f67d238dca893a8f16805fb..dbf919b220c100236f64e714c2d6dfc4035cb5b9 100644 --- a/AstBuilding.py +++ b/AstBuilding.py @@ -120,6 +120,7 @@ def codeGenPrep(ASTs): if classInterNode.__class__.__name__ == "ClassNode": classInterNode.populateSizeAndFieldOffset() + classInterNode.populateMethodOffset() types.append(classInterNode.name) else: # interfaceNode, get their methods to prep for SIT interM += classInterNode.methods @@ -140,12 +141,6 @@ def codeGenPrep(ASTs): def codeGen(ASTs, output="output"): - ASTs = ASTs[:1] # TOREMOVE: don't compile stdlib for now - # rASTs = [] - # for index,t in enumerate(ASTs): - # if index == 0 or t[0] == "stdlib/5.0/java/lang/Object.java": - # rASTs.append(t) - # ASTs = rASTs arrayClassMemory = codeGenPrep(ASTs) for t in ASTs: t[1].codeGen() diff --git a/CodeGenUtils.py b/CodeGenUtils.py index 11f7e2a741a8d7b808911d405a1b3c56d2e2a06a..2602d677848c95e45ad71421eff47de512618fee 100644 --- a/CodeGenUtils.py +++ b/CodeGenUtils.py @@ -161,7 +161,8 @@ def globalImport(genGlobalFunction=False): if not genGlobalFunction: code += p(instruction="extern", arg1="G__Zero") + \ p(instruction="extern", arg1="H__Throw_Exception") + \ - p(instruction="extern", arg1="H__Null_Check") + p(instruction="extern", arg1="H__Null_Check") + \ + p(instruction="extern", arg1="H__Bounds_Check") code += "; End of importing helper functions and constants\n" return code diff --git a/TypeNodes.py b/TypeNodes.py index aeec0904e12b107225193878a793f3d274c4ee59..71c91b7b13ed435a4c4a8a936410f05a9c31687e 100644 --- a/TypeNodes.py +++ b/TypeNodes.py @@ -306,20 +306,18 @@ class ClassNode(ClassInterNode): # Calculating the size of objects of this class self.size += (len(self.fieldOffset))*4 - - - def codeGen(self): - if hasattr(self, "code"): + + # Populating method offset and creating class memory layout + def populateMethodOffset(self): + if hasattr(self, "data"): return self.code = "" # For read-only section self.data = "" # For writeable data section - # print("This is the super class: {}".format(self.superClass)) - if self.canonName == "java.lang.Object": self.data += p("global", "I_SIT_" + self.name) - # Generate class label + # 1. Generate class label self.label = pLabel(name=self.name, type="class") self.data += ";START OF CLASS MEMORY LAYOUT FOR CLASS: " + self.canonName + "\n" self.data += self.label @@ -341,8 +339,8 @@ class ClassNode(ClassInterNode): # loops that loops through self.constructors and self.methods, in the case where there is no superClass if self.superClass: - if not hasattr(self.superClass, "code"): - self.superClass.codeGen() + if not hasattr(self.superClass, "data"): + self.superClass.populateMethodOffset() # Iterating through method offset table sorted by offset for key,value in sorted(self.superClass.methodOffset.items(), key=lambda item: item[1]): self.methodOffset[key] = value @@ -361,22 +359,24 @@ class ClassNode(ClassInterNode): # 3. Assigning offsets to methods that aren't in the super class, DECLARING memory segment for the methods # Also simultaneosly creating a dictionary of methods for easier lookup - methodDict = {} # a map of methods of the form (method.name, method.paramTypes) -> method node + self.methodDict = {} # a map of methods of the form (method.name, method.paramTypes) -> method node for method in self.methods: - methodDict[(method.name, method.paramTypes)] = method + self.methodDict[(method.name, method.paramTypes)] = method if not (method.name, method.paramTypes) in self.methodOffset: lastMethodOffset += 4 method.methodOffset = lastMethodOffset self.methodOffset[(method.name, method.paramTypes)] = lastMethodOffset self.data += pLabel(name=self.name + "_" + method.name + "_" + method.paramTypes, type="vtable") self.data += p(instruction="dd", arg1=64) # just declaring a memory segment with a random number + else: + method.methodOffset = self.methodOffset[(method.name, method.paramTypes)] # Adding inherited method to the methodDict for i in self.inherits: if isinstance(i, MethodNode): key = (i.name, i.paramTypes) - if not key in methodDict: - methodDict[(i.name, i.paramTypes)] = i + if not key in self.methodDict: + self.methodDict[(i.name, i.paramTypes)] = i # Layout SIT self.data += pLabel("SIT_" + self.name, "inter") @@ -391,7 +391,16 @@ class ClassNode(ClassInterNode): self.data += p("dd", "0") # 0 for False, 1 for True self.data += ";END OF CLASS MEMORY LAYOUT FOR CLASS " + self.name + "\n" + + def codeGen(self): + if hasattr(self, "code"): + return + + + self.code = "" # For read-only section + + # print("This is the super class: {}".format(self.superClass)) # 4. Fill in the memory segment declared in step 1 and 2 with the addresses of the method implementations self.code += "; Function for filling in class memory layout for class " + self.name + "\n" @@ -400,8 +409,8 @@ class ClassNode(ClassInterNode): vLabel = "V_" + self.name + "_" + key[0] + "_" + key[1]+"" # method at class's vtable className = "" # The name of the class that contains the most recent implementation - if key in methodDict: - className = methodDict[key].typeName + if key in self.methodDict: + className = self.methodDict[key].typeName else: # a constructor className = key[0]