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

subtype testing table

parent 00c5cd50
No related branches found
No related tags found
2 merge requests!22Subtype test,!20Master
......@@ -62,26 +62,36 @@ def reachabilityChecking(ASTs):
# (also simultaneosly creating fieldOffset because fieldOffset table is required to generate size)
def codeGenPrep(ASTs):
interM = []
types = []
for t in ASTs:
classInterNode = t[1].typeDcl
if classInterNode and classInterNode.__class__.__name__ == "ClassNode":
types.append(classInterNode)
if classInterNode.__class__.__name__ == "ClassNode":
classInterNode.populateSizeAndFieldOffset()
else: # interfaceNode, get their methods to prep for SIT
interM += classInterNode.methods
if interM: # prep SIT
for i in range(len(interM)):
interM[i].methodOffset = i * 4
interM[i].isInterM = True
for t in ASTs:
classInterNode = t[1].typeDcl
if classInterNode and classInterNode.__class__.__name__ == "ClassNode":
classInterNode.SITsize = len(interM)
# prep SIT
for i in range(len(interM)):
interM[i].methodOffset = i * 4
interM[i].isInterM = True
# prep subtype testing table
for i in range(len(types)):
types[i].subTypeOffset = i * 4 # assign each type a position in the subtype testing table
# store SIT and subtype table size
for t in ASTs:
classInterNode = t[1].typeDcl
if classInterNode.__class__.__name__ == "ClassNode":
classInterNode.SITsize = len(interM)
classInterNode.subTypeSize = len(types)
def codeGen(ASTs, output="output"):
ASTs = ASTs[:10] # TOREMOVE: don't compile stdlib for now
codeGenPrep(ASTs)
ASTs = ASTs[:1] # TOREMOVE: don't compile stdlib for now
for t in ASTs:
t[1].codeGen()
# Outputting the generated code into className.s
......
......@@ -17,6 +17,8 @@ class ClassInterNode(ASTNode):
self.children = []
self.canonName = ''
self.SITsize = 0
self.subTypeSize = 0
self.subTypeOffset = 0
# sets
self.inherits = []
......@@ -310,7 +312,6 @@ class ClassNode(ClassInterNode):
if hasattr(self, "code"):
return
self.code = "" # For read-only section
self.data = "" # For writeable data section
# print("This is the super class: {}".format(self.superClass))
......@@ -324,10 +325,12 @@ class ClassNode(ClassInterNode):
self.data += self.label
# SIT
self.data += pLabel("SIT_spot_"+ self.name, "inter") # type 'inter' for interface methods
self.data += pLabel("SIT_spot_"+ self.name, "inter") # type 'inter' for internal usage
self.data += p("dd", "42")
# TODO: subtype testing tables
# subtype testing table
self.data += pLabel("subT_spot_"+ self.name, "inter") # type 'inter' for internal usage
self.data += p("dd", "42")
####### 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
......@@ -381,6 +384,12 @@ class ClassNode(ClassInterNode):
self.data += pLabel("SIT_" + str(i), "inter")
self.data += p("dd", "42")
# Layout subtype testing column
self.data += pLabel("subT_" + self.name, "inter")
for i in range(self.subTypeSize):
self.data += pLabel("subT_" + str(i), "inter")
self.data += p("dd", "0") # 0 for False, 1 for True
self.data += ";END OF CLASS MEMORY LAYOUT FOR CLASS " + self.name + "\n"
......@@ -423,19 +432,21 @@ class ClassNode(ClassInterNode):
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"
# fill in subtype testing column
self.code += "\n; Filling in subtype testing\n"
self.code += p("mov", "eax", "I_subT_spot_" + self.name)
self.code += p("mov", "[eax]", "dword I_subT_" + self.name)
for t in getSupers(self): # getSupers includes self
dlabel = "I_subT_" + str(t.subTypeOffset // 4)
self.code += p("mov", "eax", dlabel, "self is a subType of " + t.canonName)
self.code += p("mov", "[eax]", "dword 1")
self.code += "; End of fill in subtype testing.\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)
# print(self.code)
###########################################################
# Generating a function that allocates and initializes all static fields
......@@ -552,3 +563,12 @@ def safeReplace(cur, new, className):
# quick fix for final method getClass from java.lang.Object
if 'final' in cur.mods and cur.name != 'getClass':
raise Exception("ERROR: In class {0}, {1} '{2}' in class '{3}' replaces final {1} in class/interface {4}".format(className, methodOrField, new.name, new.typeName, cur.typeName))
# helper: get list of all super class/interface of a ClassInterNode
def getSupers(classType):
result = {classType}
for s in classType.super:
result.add(s)
result.union(getSupers(s))
return result
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