Skip to content
Snippets Groups Projects
Commit 593233be authored by Xun Yang's avatar Xun Yang
Browse files

initial SIT

parent 85c36eaa
No related branches found
No related tags found
2 merge requests!19Namenode,!16Sit
...@@ -58,17 +58,29 @@ def reachabilityChecking(ASTs): ...@@ -58,17 +58,29 @@ def reachabilityChecking(ASTs):
#################################################### ####################################################
# Preparation before code Gen: # Preparation before code Gen:
# 1. Calculating the size of the object from each class # 1. Calculating the size of the object from each class
# (also simultaneosly creating fieldOffset because fieldOffset table is required to generate size) # (also simultaneosly creating fieldOffset because fieldOffset table is required to generate size)
def codeGenPrep(ASTs): def codeGenPrep(ASTs):
interM = []
for t in ASTs: for t in ASTs:
classInterNode = t[1].typeDcl classInterNode = t[1].typeDcl
if classInterNode and classInterNode.__class__.__name__ == "ClassNode": if classInterNode and classInterNode.__class__.__name__ == "ClassNode":
classInterNode.populateSizeAndFieldOffset() classInterNode.populateSizeAndFieldOffset()
else: # interfaceNode, get their methods to prep for SIT
interM += classInterNode.method
if interM: # prep SIT
for i in range(len(interM)):
interM[i].SIToffset = i
for t in ASTs:
classInterNode = t[1].typeDcl
if classInterNode and classInterNode.__class__.__name__ == "ClassNode":
classInterNode.SITsize = len(interM)
def codeGen(ASTs, output="output"): def codeGen(ASTs, output="output"):
ASTs = ASTs[:1] # TOREMOVE: don't compile stdlib for now ASTs = ASTs[:1] # TOREMOVE: don't compile stdlib for now
codeGenPrep(ASTs) codeGenPrep(ASTs)
for t in ASTs: for t in ASTs:
t[1].codeGen() t[1].codeGen()
# Outputting the generated code into className.s # Outputting the generated code into className.s
......
...@@ -16,6 +16,7 @@ class ClassInterNode(ASTNode): ...@@ -16,6 +16,7 @@ class ClassInterNode(ASTNode):
self.env = None self.env = None
self.children = [] self.children = []
self.canonName = '' self.canonName = ''
self.SITsize = 0
# sets # sets
self.inherits = [] self.inherits = []
...@@ -305,7 +306,7 @@ class ClassNode(ClassInterNode): ...@@ -305,7 +306,7 @@ class ClassNode(ClassInterNode):
return return
self.code = "" # For read-only section self.code = "" # For read-only section
self.data = "" # For writeable data section self.data = "" # For writeable data section
# print("This is the super class: {}".format(self.superClass)) # print("This is the super class: {}".format(self.superClass))
...@@ -314,12 +315,15 @@ class ClassNode(ClassInterNode): ...@@ -314,12 +315,15 @@ class ClassNode(ClassInterNode):
self.data += ";START OF CLASS MEMORY LAYOUT FOR CLASS: " + self.canonName + "\n" self.data += ";START OF CLASS MEMORY LAYOUT FOR CLASS: " + self.canonName + "\n"
self.data += self.label self.data += self.label
# SIT
self.data += pLabel("SIT_spot_"+ self.name, "local")
self.data += p("dd", "42")
# TODO: SIT and subtype testing tables # TODO: subtype testing tables
####### ADDING METHODS TO CLASS MEMORY LAYOUT AND FIELDS TO FIELD OFFSET TABLE ######### ####### ADDING METHODS TO CLASS MEMORY LAYOUT AND FIELDS TO FIELD OFFSET TABLE #########
# Copying over the offsets of methods from superclass and DECLARING memory segment for the methods # Copying over the offsets of methods from superclass and DECLARING memory segment for the methods
lastMethodOffset = -4 # stores the largest method offset in the superCalss lastMethodOffset = 0 # stores the largest method offset in the superCalss
# TODO: set this to 4 after the implemntation of both the SIT and subtype testing table # TODO: set this to 4 after the implemntation of both the SIT and subtype testing table
# Note: This is 4 less than the offset of where the next method would be located # Note: This is 4 less than the offset of where the next method would be located
# This is to accomodate for the addition of 4 to lastMethodOffset in EVERY (including the first) iteration in the # This is to accomodate for the addition of 4 to lastMethodOffset in EVERY (including the first) iteration in the
...@@ -355,15 +359,20 @@ class ClassNode(ClassInterNode): ...@@ -355,15 +359,20 @@ class ClassNode(ClassInterNode):
self.methodOffset[(method.name, method.paramTypes)] = lastMethodOffset self.methodOffset[(method.name, method.paramTypes)] = lastMethodOffset
self.data += pLabel(name=self.name + "_" + method.name + "_" + method.paramTypes, type="vtable") 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 self.data += p(instruction="dd", arg1=64) # just declaring a memory segment with a random number
# Adding inherited method to the methodDict # Adding inherited method to the methodDict
for i in self.inherits: for i in self.inherits:
if isinstance(i, MethodNode): if isinstance(i, MethodNode):
key = (i.name, i.paramTypes) key = (i.name, i.paramTypes)
if not key in methodDict: if not key in methodDict:
methodDict[(i.name, i.paramTypes)] = i methodDict[(i.name, i.paramTypes)] = i
# print(self.methodOffset) # Layout SIT
self.code += pLabel("SIT_" + self.name, "local")
for i in range(self.SITsize):
self.code += pLabel("SIT_" + i, "local")
self.data += p("dd", "42")
self.data += ";END OF CLASS MEMORY LAYOUT FOR CLASS " + self.name + "\n" self.data += ";END OF CLASS MEMORY LAYOUT FOR CLASS " + self.name + "\n"
...@@ -385,9 +394,37 @@ class ClassNode(ClassInterNode): ...@@ -385,9 +394,37 @@ class ClassNode(ClassInterNode):
self.code += p(instruction="extern", arg1=mLabel, comment="importing method implementation label") self.code += p(instruction="extern", arg1=mLabel, comment="importing method implementation label")
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=vLabel, comment="Filling in class memory segment for method " + mLabel)
self.code += p(instruction="mov", arg1="[eax]", arg2="dword " + mLabel) self.code += p(instruction="mov", arg1="[eax]", arg2="dword " + mLabel)
self.code += "; End of function for filling in methods in class memory layout\n"
# fill in SIT
self.code += "\n; Filling in SIT\n"
self.code += p("mov", "eax", "_SIT_spot" + self.name)
self.code += p("mov", "[eax]", "dword _SIT_" + self.name)
interM = []
for s in self.super:
if s.__class__.__name__ == "InterNode":
interM += s.methods
for m in interM:
imple = methodDict[(m.name, m.paramTypes)]
className = imple.typeName
dlabel = "_SIT_" + m.SIToffset
imLabel = "M_" + className + "_" + m.name + "_" + m.paramTypes
if className != self.typeName:
self.code += p("extern", imLabel)
self.code += p("mov", "eax", dlabel)
self.code += p("mov", "[eax]", "dword " + imLabel)
self.code += "; End of fill in SIT.\n"
self.code += p(instruction="ret", arg1="") self.code += p(instruction="ret", arg1="")
self.code += "; End of function for filling in class memory layout\n" self.code += "; End of function for filling in class memory layout\n"
# print(self.name) # print(self.name)
# print(self.fieldOffset) # print(self.fieldOffset)
...@@ -395,22 +432,22 @@ class ClassNode(ClassInterNode): ...@@ -395,22 +432,22 @@ class ClassNode(ClassInterNode):
########################################################### ###########################################################
# Generating a function that allocates and initializes all static fields # Generating a function that allocates and initializes all static fields
# Note: 1. saving and restoring ebx, a callee-save register # Note: 1. saving and restoring ebx, a callee-save register
# 2. static fields are intialized in the order of declaration within the class and has to be intialized # 2. static fields are intialized in the order of declaration within the class and has to be intialized
# before the test() method is being called # before the test() method is being called
self.code += "; Function for filling allocating space and initializing static fields for class " + self.name + "\n" self.code += "; Function for filling allocating space and initializing static fields for class " + self.name + "\n"
self.code += pLabel(name=self.name + "_" + "staticFieldMemoryInit", type="helper") self.code += pLabel(name=self.name + "_" + "staticFieldMemoryInit", type="helper")
self.code += p(instruction="push", arg1="ebx", comment="saving ebx") self.code += p(instruction="push", arg1="ebx", comment="saving ebx")
for field in self.fields: for field in self.fields:
if not hasattr(field, "code"): if not hasattr(field, "code"):
field.codeGen() field.codeGen()
self.code += field.code self.code += field.code
self.data += field.data self.data += field.data
self.code += p(instruction="pop", arg1="ebx", comment="restoring ebx") self.code += p(instruction="pop", arg1="ebx", comment="restoring ebx")
self.code += p(instruction="ret", arg1="") self.code += p(instruction="ret", arg1="")
self.code += "; End of function for filling allocating space and initializing static fields for class " + self.name + "\n" self.code += "; End of function for filling allocating space and initializing static fields for class " + self.name + "\n"
# Generating a function that calls both the class memory init and static field init functions # Generating a function that calls both the class memory init and static field init functions
self.code += "; Function that calls staticFieldMemoryInit and classMemoryInit \n" self.code += "; Function that calls staticFieldMemoryInit and classMemoryInit \n"
self.code += pLabel(name=self.name + "_" + "classAndStaticFieldInit", type="helper") self.code += pLabel(name=self.name + "_" + "classAndStaticFieldInit", type="helper")
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment