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):
####################################################
# 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)
def codeGenPrep(ASTs):
interM = []
for t in ASTs:
classInterNode = t[1].typeDcl
if classInterNode and classInterNode.__class__.__name__ == "ClassNode":
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"):
ASTs = ASTs[:1] # TOREMOVE: don't compile stdlib for now
codeGenPrep(ASTs)
codeGenPrep(ASTs)
for t in ASTs:
t[1].codeGen()
# Outputting the generated code into className.s
......
......@@ -16,6 +16,7 @@ class ClassInterNode(ASTNode):
self.env = None
self.children = []
self.canonName = ''
self.SITsize = 0
# sets
self.inherits = []
......@@ -305,7 +306,7 @@ class ClassNode(ClassInterNode):
return
self.code = "" # For read-only section
self.code = "" # For read-only section
self.data = "" # For writeable data section
# print("This is the super class: {}".format(self.superClass))
......@@ -314,12 +315,15 @@ class ClassNode(ClassInterNode):
self.data += ";START OF CLASS MEMORY LAYOUT FOR CLASS: " + self.canonName + "\n"
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 #########
# 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
# 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
......@@ -355,15 +359,20 @@ class ClassNode(ClassInterNode):
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
# Adding inherited method to the methodDict
# 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)
# 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"
......@@ -385,9 +394,37 @@ class ClassNode(ClassInterNode):
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="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 += "; End of function for filling in class memory layout\n"
# print(self.name)
# print(self.fieldOffset)
......@@ -395,22 +432,22 @@ class ClassNode(ClassInterNode):
###########################################################
# Generating a function that allocates and initializes all static fields
# Note: 1. saving and restoring ebx, a callee-save register
# Generating a function that allocates and initializes all static fields
# 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
# 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 += 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:
if not hasattr(field, "code"):
field.codeGen()
self.code += field.code
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 += "; 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
self.code += "; Function that calls staticFieldMemoryInit and classMemoryInit \n"
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