From 5f17ca73630846ecac4fa0ca1be0addbce2ad1b2 Mon Sep 17 00:00:00 2001 From: pycsham <shampuiyanchloe@gmail.com> Date: Mon, 6 Apr 2020 02:16:50 -0400 Subject: [PATCH] fixed class memory layout (method labels). And fixed test.py for MacOS (DS_store issue) --- Test.py | 6 +++++- TypeNodes.py | 23 +++++++++++++++++++++-- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/Test.py b/Test.py index 795dd2b..5f4c3d0 100644 --- a/Test.py +++ b/Test.py @@ -48,7 +48,10 @@ def a2Multiple(): testOutput = "output/" + c.split("/")[-1] if exists(testOutput): - rmtree(testOutput) + try: + rmtree(testOutput) + except: + rmtree("output/.DS_Store") makedirs(testOutput) copyfile('stdlib/5.0/runtime.s', testOutput + "/runtime.s") @@ -150,6 +153,7 @@ def run(testFiles, testOutput): codeGen(ASTs, testOutput) except Exception as e: return "code generation: " + e.args[0] + # codeGen(ASTs, testOutput) return "" diff --git a/TypeNodes.py b/TypeNodes.py index b50ee78..12a15e6 100644 --- a/TypeNodes.py +++ b/TypeNodes.py @@ -163,7 +163,7 @@ class ClassNode(ClassInterNode): self.superClass = '' # these fields initially stores a string that represent the super #### Code generation relevant fields #### self.label = "" # label in assembly - self.methodOffset = {} # a dictionary that maps method signatures (method.name, method.paramTypes) to offsets in the CLASS memory layout + self.methodOffset = {} # a dictionary that maps method signatures (method.name, method.paramTypes) to (offset, constructorFlag) in the CLASS memory layout self.fieldOffset = {} # a dictionary that maps field names to offsets in OBJECT memory layout self.staticFieldLabels = [] # a list of static field labels @@ -320,19 +320,38 @@ class ClassNode(ClassInterNode): self.code += p(instruction="dd", arg1=64) # just declaring a memory segment with a random number # 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 for method in self.methods: + methodDict[(method.name, method.paramTypes)] = method if not (method.name, method.paramTypes) in self.methodOffset: lastMethodOffset += 4 self.methodOffset[(method.name, method.paramTypes)] = lastMethodOffset self.code += pLabel(name=self.name + "_" + method.name + "_" + method.paramTypes, type="vtable") self.code += p(instruction="dd", arg1=64) # just declaring a memory segment with a random number + + # 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 # print(self.methodOffset) self.code += ";END OF CLASS MEMORY LAYOUT FOR CLASS " + self.name + "\n" + + # 4. Fill in the memory segment declared in step 1 and 2 with the addresses of the method implementations for key,value in self.methodOffset.items(): vLabel = "V_" + self.name + "_" + key[0] + "_" + key[1]+"" # method at class's vtable - mLabel = "M_" + self.name + "_" + key[0] + "_" + key[1] # method implementation + + className = "" # The name of the class that contains the most recent implementation + if key in methodDict: + className = methodDict[key].typeName + else: # a constructor + className = key[0] + + mLabel = "M_" + className + "_" + key[0] + "_" + key[1] # method implementation self.code += p(instruction="mov", arg1="eax", arg2=vLabel, comment="Filling in class memory segment for method " + mLabel) self.code += p(instruction="mov", arg1="[eax]", arg2="dword " + mLabel) -- GitLab