def test_execute_int_parameter(self): from VM import VM vm = VM() c = ClassDefinition() c.namespace = 'a' c.name = 'b' v = Variable() v.name = 'xyz' v.type = Types.Int32 r = ReferenceType() t = Types.register_custom_type(c) r.type = t r.add_field(v) vm.stack.push(r) vm.stack.push(Variable(9876)) x = stfld('int32 a.b::xyz') x.execute(vm) self.assertEqual(vm.stack.count(), 0) self.assertEqual(r.fields[0].value, 9876)
def execute(self, vm): t = Types.resolve_type(self.typeName) r = ReferenceType() r.type = t for f in t.classRef.fieldDefinitions: o = Variable() o.type = f.type o.name = f.name o.value = 0 # fixme - reference types? r.fields.append(o) r.fieldNames.append(f.name) vm.stack.push(r) namespace = t.namespace + '.' + t.name name = 'ctor' methodDefinition = vm.find_method_by_signature( namespace, name, None, None) # fixme - should name have a . in it? if methodDefinition is None: raise Exception("Couldn't find " + name + " method for " + namespace) m = methodDefinition.get_method() #parameter = Variable() #parameter.value = r m.parameters = [ r ] # fixme - create a new method object so we don't overwrite the parameters? #fixme - should we even use parameters? or just the stack? vm.execute_method(m)
def test_execute_reference_type_stores_reference_type_in_local_but_doesnt_change_name(self): from VM import VM vm = VM() x = stloc('0') m = MethodDefinition() localr = ReferenceType() localr.name = 'foobar' m.locals.append(localr) vm.set_current_method(m) r2 = ReferenceType() vm.stack.push(r2) x.execute(vm) self.assertEqual(vm.stack.count(), 0) self.assertEqual(m.locals[0], r2) self.assertEqual(m.locals[0].name, 'foobar')
def test_callvirt_one_parameter_instance_puts_this_pointer_and_parameter_on_stack( self): from VM import VM from MethodDefinition import MethodDefinition vm = VM() paramObject = Variable() paramObject.type = Types.Int32 m = MethodDefinition() m.name = 'TestMethod' m.namespace = 'A.B' m.returnType = Types.Int32 m.parameters = [paramObject] m.names = 'A.B' m.attributes.append(MethodDefinition.AttributeTypes['instance']) vm.methods.append(m) r = ReferenceType() vm.stack.push(r) v = Variable(8888) vm.stack.push(v) self.assertEqual(vm.currentMethod, None) c = callvirt('instance int32 A.B::TestMethod ( int32 )') c.execute(vm) self.assertEqual(vm.currentMethod.methodDefinition, m) self.assertEqual(vm.stack.get_number_of_frames(), 2) self.assertEqual(len(vm.current_method().parameters), 2) self.assertEqual(vm.current_method().parameters[1], v) self.assertEqual(vm.current_method().parameters[0], r)
def test_execute_reference_type_stores_reference_type_in_local_but_doesnt_change_name( self): from VM import VM vm = VM() x = stloc('0') m = MethodDefinition() localr = ReferenceType() localr.name = 'foobar' m.locals.append(localr) vm.set_current_method(m) r2 = ReferenceType() vm.stack.push(r2) x.execute(vm) self.assertEqual(vm.stack.count(), 0) self.assertEqual(m.locals[0], r2) self.assertEqual(m.locals[0].name, 'foobar')
def test_execute_multiple_fields(self): from VM import VM vm = VM() c = ClassDefinition() c.namespace = 'a' c.name = 'b' v = Variable() v.name = 'abc' v.type = Types.Int32 v2 = Variable() v2.name = 'def' v2.type = Types.Int32 c.fieldDefinitions.append(v2) r = ReferenceType() t = Types.register_custom_type(c) r.type = t r.add_field(v) r.add_field(v2) vm.stack.push(r) x = ldfld('int32 ConsoleApplication1.foo::def') x.execute(vm) self.assertEqual(vm.stack.count(), 1) self.assertEqual(r.fields[1], vm.stack.pop())
def parse_locals(self, context): from ParserContext import ParseException locals = [] token = context.get_next_token() if token != 'init': raise ParseException( 'Expected init, found ' + token) # fixme - only required for verifiable methods token = context.get_next_token() if token != '(': raise ParseException('Expected (, found' + token) token = context.get_next_token() lastToken = '' while not token.endswith(')'): v = Variable() if token.startswith('['): v.alias = token[1:-1] lastToken = token token = context.get_next_token() if token == 'class': v2 = ReferenceType() v2.alias = v.alias v2.type = Types.resolve_type(context.get_next_token()) v = v2 elif token.endswith('[]'): # array v.type = Types.Array v.arrayType = Types.resolve_type(token[:-2]) else: v.type = Types.BuiltInTypes[token] # fixme - non-builtin types locals.append(v) lastToken = token token = context.get_next_token() #if token.endswith(')'): # v.name = token[:-1] # token = ')' #else: v.name = token lastToken = token token = context.get_next_token() return locals
def parse_locals(self, context): from ParserContext import ParseException locals = [] token = context.get_next_token() if token != 'init': raise ParseException('Expected init, found ' + token) # fixme - only required for verifiable methods token = context.get_next_token() if token != '(': raise ParseException('Expected (, found' + token) token = context.get_next_token() lastToken = '' while not token.endswith(')'): v = Variable() if token.startswith('['): v.alias = token[1:-1] lastToken = token token = context.get_next_token() if token == 'class': v2 = ReferenceType() v2.alias = v.alias v2.type = Types.resolve_type(context.get_next_token()) v = v2 elif token.endswith('[]'): # array v.type = Types.Array v.arrayType = Types.resolve_type(token[:-2]) else: v.type = Types.BuiltInTypes[token] # fixme - non-builtin types locals.append(v) lastToken = token token = context.get_next_token() #if token.endswith(')'): # v.name = token[:-1] # token = ')' #else: v.name = token lastToken= token token = context.get_next_token() return locals
def test_execute_single_field(self): from VM import VM vm = VM() c = ClassDefinition() c.namespace = 'ConsoleApplication1' c.name = 'foo' v = Variable() v.name = 'z' v.type = Types.Int32 r = ReferenceType() t = Types.register_custom_type(c) r.type = t r.add_field(v) vm.stack.push(r) x = ldfld('int32 ConsoleApplication1.foo::z') x.execute(vm) self.assertEqual(vm.stack.count(), 1) self.assertEqual(r.fields[0], vm.stack.pop())
def test_execute_reference_type_parameter(self): from VM import VM vm = VM() foo = ClassDefinition() foo.namespace = 'ConsoleApplication1' foo.name = 'foo' fooType = Types.register_custom_type(foo) fooObject = ReferenceType() fooObject.name = 'f' fooObject.type = fooType fooObject.value = Variable(3333) bar = ClassDefinition() bar.namespace = 'ConsoleApplication1' bar.name = 'bar' barType = Types.register_custom_type(bar) barObject = ReferenceType() barObject.type = barType field = ReferenceType() field.name = 'f' field.type = fooType barObject.add_field(field) vm.stack.push(barObject) x = ldfld('class ConsoleApplication1.foo ConsoleApplication1.bar::f') x.execute(vm) self.assertEqual(vm.stack.count(), 1) self.assertEqual(barObject.fields[0], vm.stack.pop())