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())
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 test_newobj_no_parameters_initializes_int_field_to_zero(self): from VM import VM vm = VM() m = MethodDefinition() m.name = 'ctor' m.namespace = 'testnamespace.testclass' vm.methods.append(m) c = ClassDefinition() c.name = 'testclass' c.namespace = 'testnamespace' c.methods.append(m) v = Variable() v.name = 'xyz' v.type = Types.Int32 c.fieldDefinitions.append(v) t = Types.register_custom_type(c) n = newobj('instance void testnamespace.testclass::.ctor()') n.execute(vm) Types.unregister_custom_type(t) o = vm.stack.pop() self.assertEqual(o.type, t) self.assertEqual(len(o.fields), 1) self.assertEqual(o.fields[0].value, 0) self.assertEqual(len(o.fieldNames), 1) self.assertEqual(o.fieldNames[0], 'xyz')
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 test_resolve_mscorlib_type_returns_custom_type(self): from ClassDefinition import ClassDefinition c = ClassDefinition() c.namespace = 'System' c.name = 'FooBar' c.assembly = 'mscorlib' t = register_custom_type(c) result = resolve_type('[mscorlib]System.FooBar::.ctor()') self.assertEqual(t, result) unregister_custom_type(t)
def test_parse_class_local_with_alias(self): from ParserContext import ParserContext s = 'init ([0] class NS.C f)' p = ParserContext(s) mp = MethodParser() c = ClassDefinition() c.name = 'C' c.namespace = 'NS' Types.register_custom_type(c) locals = mp.parse_locals(p) self.assertEqual(len(locals), 1) self.assertTrue(isinstance(locals[0], ReferenceType)) self.assertEqual(locals[0].name, 'f') self.assertEqual(locals[0].alias, '0') self.assertEqual(locals[0].type.name, 'C') self.assertEqual(locals[0].type.namespace, 'NS')
def test_parse_class_local_with_alias(self): from ParserContext import ParserContext s = 'init ([0] class NS.C f)' p = ParserContext(s) mp = MethodParser() c = ClassDefinition() c.name = 'C' c.namespace = 'NS' Types.register_custom_type(c) locals = mp.parse_locals(p) self.assertEqual(len(locals), 1) self.assertTrue(isinstance(locals[0], ReferenceType)) self.assertEqual(locals[0].name, 'f') self.assertEqual(locals[0].alias, '0') self.assertEqual(locals[0].type.name, 'C') self.assertEqual(locals[0].type.namespace, 'NS')
def parse(self, parserContext): c = ClassDefinition() while True: token = parserContext.get_next_token() if token in ClassFlags: c.flags.append(token) elif token == 'extends': c.base = parserContext.get_next_token() elif token == '.method': m = MethodParser().parse(parserContext) m.namespace = c.namespace + '.' + c.name c.methods.append(m) parserContext.methods.append(m) # fixme - should i add to both? elif token == '.field': v = Variable() visibility = parserContext.get_next_token() type = parserContext.get_next_token( ) # fixme - type, visibility if type == 'class': type = parserContext.get_next_token() if Types.BuiltInTypes.has_key(type): v.type = Types.BuiltInTypes[type] else: v.type = Types.resolve_type(type) name = parserContext.get_next_token() v.name = name c.fieldDefinitions.append(v) elif token == '}': break elif token != '{': fullyQualifiedName = token.split('.') c.name = fullyQualifiedName[-1] c.namespace = '.'.join(fullyQualifiedName[:-1]) Types.register_custom_type(c) return c
def test_newobj_no_parameters_adds_this_pointer_to_parameters(self): from VM import VM vm = VM() m = MethodDefinition() m.name = 'ctor' m.namespace = 'testnamespace.testclass' vm.methods.append(m) c = ClassDefinition() c.name = 'testclass' c.namespace = 'testnamespace' c.methods.append(m) t = Types.register_custom_type(c) n = newobj('instance void testnamespace.testclass::.ctor()') n.execute(vm) self.assertEqual(len(vm.current_method().parameters), 1) Types.unregister_custom_type(t)
def parse(self, parserContext): c = ClassDefinition() while True: token = parserContext.get_next_token() if token in ClassFlags: c.flags.append(token) elif token == 'extends': c.base = parserContext.get_next_token() elif token == '.method': m = MethodParser().parse(parserContext) m.namespace = c.namespace + '.' + c.name c.methods.append(m) parserContext.methods.append(m) # fixme - should i add to both? elif token == '.field': v = Variable() visibility = parserContext.get_next_token() type = parserContext.get_next_token() # fixme - type, visibility if type == 'class': type = parserContext.get_next_token() if Types.BuiltInTypes.has_key(type): v.type = Types.BuiltInTypes[type] else: v.type = Types.resolve_type(type) name = parserContext.get_next_token() v.name = name c.fieldDefinitions.append(v) elif token == '}': break elif token != '{': fullyQualifiedName = token.split('.') c.name = fullyQualifiedName[-1] c.namespace = '.'.join(fullyQualifiedName[:-1]) Types.register_custom_type(c) return c
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_newobj_no_parameters_calls_constructor(self): from VM import VM vm = VM() m = MethodDefinition() m.name = 'ctor' m.namespace = 'testnamespace.testclass' vm.methods.append(m) c = ClassDefinition() c.name = 'testclass' c.namespace = 'testnamespace' c.methods.append(m) t = Types.register_custom_type(c) n = newobj('instance void testnamespace.testclass::ctor()') n.execute(vm) Types.unregister_custom_type(t) o = vm.stack.pop() self.assertEqual(o.type, t) self.assertEquals(vm.current_method().methodDefinition, m)
Int16 = BuiltInTypes['int16'] UInt16 = BuiltInTypes['uint16'] Int32 = BuiltInTypes['int32'] UInt32 = BuiltInTypes['uint32'] Int64 = BuiltInTypes['int64'] UInt64 = BuiltInTypes['uint64'] Float32 = BuiltInTypes['float32'] Float64 = BuiltInTypes['float64'] Void = BuiltInTypes['void'] Bool = BuiltInTypes['bool'] # CLR type, not VES type Array = Type('array', 4) # TODO - do these in a nicer place c = ClassDefinition() c.namespace = 'System' c.name = 'Exception' c.assembly = 'mscorlib' register_custom_type(c, True) c = ClassDefinition() c.namespace = 'System' c.name = 'String' c.assembly = 'mscorlib' stringType = register_custom_type(c, True) add_type_alias(stringType, 'string') add_type_alias(BuiltInTypes['int32'], 'int') add_type_alias(BuiltInTypes['int32'], 'System.Int32') class TypeTests(unittest.TestCase):