def setUp(self): self.ul = Var.UpdateLocationBuilder(arch) tpe = Bit64 loc = Loc.RegisterX64('rax') self.var = Var.Var('testVar', loc, tpe) self.b = Builder() self.ul.toStack(self.b, self.var, 3)
def setUp(self): self.ul = Var.UpdateLocationBuilder(arch) tpe = Bit64 loc = Loc.GlobalROAddressX64('pi') self.var = Var.Var('testVar', loc, tpe) self.b = Builder() self.ul.toRegister(self.b, self.var, 'rbx')
def test_toReg_reallocs(self): b = Builder() var = self.a.varRegCreate(b, 'testVar', 'r15', Type.Bit64, 3) self.a.toReg(b, var, 'rsi') self.assertTrue(self.a.autoReg.isAllocated('rsi'))
def test_stackToStack_build(self): b = Builder() var = self.a.varStackCreate('testVar', Type.Bit64, 3) with self.assertRaises(AssertionError): self.a.toStack(b, var)
def test_labelToStack_build(self): b = Builder() var = self.a.varROCreate('ro1', Type.Bit64, 3) self.a.toStack(b, var) self.assertEqual(b._code[0], 'mov qword[rbp - 16], ro1')
def test_toStack_removes(self): b = Builder() var = self.a.varRegCreate(b, 'testVar', 'r15', Type.Bit64, 3) slot = self.a.toStack(b, var) self.assertFalse(self.a.autoReg.isAllocated('r15'))
def test_toRegAny_stack(self): b = Builder() var = self.a.varStackCreate('testVar', Type.Bit64, 3) self.a.toRegAny(b, var) self.assertTrue(self.a.autoReg.isAllocated(var.loc.lid))
def test_toRegAny_label_build(self): b = Builder() var = self.a.varROCreate('ro1', Type.Bit64, 3) self.a.toRegAny(b, var) self.assertEqual(b._code[0], 'mov qword r15, ro1')
def test_varRegCreate(self): b = Builder() var = self.a.varRegCreate(b,'testVar', 'rsi', Type.Bit64, 3) self.assertTrue(self.a.autoReg('rsi'), var)
def test_varLabelCreate(self): b = Builder() var = self.a.varROCreate('ro1', Type.Bit64, 3) self.assertEqual(var.loc.lid, 'ro1')
def test_toReg_build(self): b = Builder() var = self.a.varStackCreate("testVar", Type.Bit64, 3) self.a.toReg(b, var, 'rsi') self.assertEqual(b._code[0], 'mov rsi, qword [rbp - 16]')
def test_toReg_reallocs(self): b = Builder() var = self.a.varStackCreate("testVar", Type.Bit64, 3) self.a.toReg(b, var, 'rsi') self.assertTrue(self.a.autoReg.isAllocated('rsi'))
def test_toReg_build(self): b = Builder() var = self.a.varROCreate('ro1', Type.Bit64, 3) self.a.toReg(b, var, 'rsi') self.assertEqual(b._code[0], 'mov qword rsi, ro1')
def test_toReg_removes(self): b = Builder() var = self.a.varROCreate('ro1', Type.Bit64, 3) self.a.toReg(b, var, 'rsi') self.assertFalse(self.a.autoReg.isAllocated('r15'))
def test_toReg_build(self): b = Builder() var = self.a.varRegCreate(b, 'testVar', 'r15', Type.Bit64, 3) self.a.toReg(b, var, 'rsi') self.assertEqual(b._code[0], 'mov qword rsi, r15')
def test_toRegAny_label(self): b = Builder() var = self.a.varROCreate('ro1', Type.Bit64, 3) self.a.toRegAny(b, var) self.assertTrue(self.a.autoReg.isAllocated(var.loc.lid))
def test_varStackCreate(self): b = Builder() var = self.a.varStackCreate("testVar", Type.Bit64, 3) self.assertTrue(self.a.autoStack.isAllocated(var.loc.lid))
def test_toRegAny_reg(self): b = Builder() var = self.a.varRegCreate(b, 'testVar', 'r15', Type.Bit64, 3) self.a.toRegAny(b, var) self.assertTrue(self.a.autoReg.isAllocated(var.loc.lid))
def test_varRegCreate_double_relocate_toRegister(self): b = Builder() var1 = self.a.varRegCreate(b,'testVar', 'rsi', Type.Bit64, 3) var2 = self.a.varRegCreate(b, 'testVar2', 'rsi', Type.Bit8, 3) self.assertTrue(self.a.autoReg.isAllocated('r15'))
def test_toRegAny_stack_build(self): b = Builder() var = self.a.varStackCreate('testVar', Type.Bit64, 3) self.a.toRegAny(b, var) self.assertEqual(b._code[0], 'mov r15, qword [rbp - 16]')
def test_varRegCreate_double_build(self): b = Builder() var1 = self.a.varRegCreate(b,'testVar', 'rsi', Type.Bit64, 3) var2 = self.a.varRegCreate(b, 'testVar2', 'rsi', Type.Bit8, 3) self.assertEqual(b._code[0], 'mov qword r15, rsi')
def test_toStack_reallocs(self): b = Builder() var = self.a.varRegCreate(b, 'testVar', 'r15', Type.Bit64, 3) self.a.toStack(b, var) self.assertTrue(self.a.autoStack.isAllocated(var.loc.lid))
def test_label_delete(self): b = Builder() var = self.a.varROCreate('ro1', Type.Bit64, 3) with self.assertRaises(BuilderError): self.a.delete(var)
def test_regToStack_build(self): b = Builder() var = self.a.varRegCreate(b, 'testVar', 'r15', Type.Bit64, 3) self.a.toStack(b, var) self.assertEqual(b._code[0], 'mov qword[rbp - 16], r15')
def test_reg_delete(self): b = Builder() var = self.a.varRegCreate(b, 'testVar', 'rsi', Type.Bit64, 3) self.a.delete(var) with self.assertRaises(BuilderError): self.a.autoReg('rsi')
def __init__(self, tokenIt, builderAPI): ''' builderAPI ''' self.b = Builder() self.instructionStack = [] self.instructionsStoreTrigger = False # EnvStd is builtin symbol definitions from BuilderAPI #x self.envStd = builderAPI self.builderAPI = builderAPI builderFuncSymbols = [ SymbolBuiltinFunc(funcName, getattr(builderAPI, funcName), NoType) for funcName in builderAPI.funcNameToArgsType.keys()] self.scopeStd = Scope(builderFuncSymbols) # These need explaining. # This is a link auto-wired into the API so the API can refer # back to this class. # Really the API is a specialism of this class, and should # inherit it. But then it is not an API, and inherits plenty # of methods and attributes that may get awkward. # So the API is composed, and so cleanly encapsulated. # Main issue with that is that the API benefits from access to # this class. It will recieve further errors from construction # classes, and sometimes needs to signal the overall handlers # here to work e.g. make a new environment. # If the API was interited, it could do that, but composed, no. # For a while the solution was to send data back with # structures like Options and Eithers. But this got messy, as # there is a lot of it. And the API knows what it wants to do, # no need for ifs... # So the API is now given a hard link back here to do it's # tinkering. If there is one problen, you can see a link loop # now exists, the API can call into the Compiler affecting the # API... However, the concerns and information are clearly # outlined, this should never occur. #x self.envStd.compiler = self self.builderAPI.compiler = self self.funcNameToArgsType = builderAPI.funcNameToArgsType # EnvClosure holds symbiol definitions local to patches of # code, such as codeblocks for whiles etc. # As such, it can be stacked. #x self.envClosure = [] self.scopeStack = [] # Used for the occasional section vars. #? Policy undecided #x #self.envGlobal = {} self.scopeGlobal = Scope.empty() # Closure data is not part of the env group at all. # Rubble does not have bracketing, and does not enable # bracketing, prefering to mark start and end locations with # sitandalone functions. So we need to keep track of those. # Of course, environments will be enabled within these blocks. self.closureData = [] super().__init__(tokenIt)
def test_stack_delete(self): b = Builder() var = self.a.varStackCreate("testVar", Type.Bit64, 3) self.a.delete(var) with self.assertRaises(BuilderError): self.a.autoStack(var.loc.lid)