def execute(self, vm): stack = vm.stack if stack.get_frame_count() < 2: raise StackStateException('Not enough values on the stack') v2 = stack.pop() v1 = stack.pop() if v1.value == v2.value: stack.push(Variable(1)) else: stack.push(Variable(0)) # fixme - floats? register('ceq', ceq) class ceqTest(unittest.TestCase): def test_execute_not_enough_stack_values(self): from VM import VM vm = VM() vm.stack.push(Variable(1)) x = ceq() self.assertRaises(StackStateException, x.execute, vm) def test_execute_v1_less_than_v2_ints(self): from VM import VM vm = VM() vm.stack.push(Variable(5))
def __init__(self, arguments = None): self.name = 'mul' self.opcode = 0x5A def execute(self, vm): stack = vm.stack if stack.get_frame_count() < 2: raise StackStateException('Not enough values on the stack') rhs = stack.pop() lhs = stack.pop() stack.push(Variable(lhs.value * rhs.value)) # fixme - set type of return variable # fixme - overflow register('mul', mul) class addTest(unittest.TestCase): def test_execute_not_enough_stack_values(self): from VM import VM vm = VM() vm.stack.push(1) x = mul() self.assertRaises(StackStateException, x.execute, vm) def test_execute_int_variables(self): from VM import VM vm = VM() vm.stack.push(Variable(5))
if stack.get_frame_count() < 2: raise StackStateException('Not enough values on the stack') value = vm.stack.pop() object = vm.stack.pop() for fieldIndex in range(len(object.fieldNames)): fieldName = object.fieldNames[fieldIndex] if fieldName == self.fieldName: object.fields[fieldIndex] = value return raise Exception("Field named " + self.fieldName + " not found") #variable = m.locals[self.index] #variable.value = stack.pop() register('stfld', stfld) class stfldTest(unittest.TestCase): 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()
elif self.suffix == 'i4.7': stack.push(Variable(7)) elif self.suffix == 'i4.8': stack.push(Variable(8)) elif self.suffix == 'i4.m1' or self.suffix == 'i4.M1': stack.push(Variable(-1)) elif self.suffix == 'i4.s': stack.push(Variable(int(self.value))) def string_to_number(self, str): if str.startswith('0x'): return int(str, 16) else: return int(str) register('ldc', ldc) class ldcTest(unittest.TestCase): def test_execute_i4_hex(self): from VM import VM vm = VM() x = ldc('i4 0x4d2') x.execute(vm) self.assertEqual(vm.stack.count(), 1) self.assertEqual(vm.stack.pop().value, 0x4d2) def test_execute_i4(self): from VM import VM vm = VM()
self.opcode = 0x2D else: self.opcode = 0x3A self.suffix = '' self.target = args def execute(self, vm): # fixme check if there aren't enough stack values variable = vm.stack.pop() if variable.value != 0: index = vm.find_instruction_pointer_by_label(self.target) vm.current_stack_frame().instructionPointer = index # fixme - check for null objects register('brtrue', brtrue) class brtrueTest(unittest.TestCase): def test_execute_true(self): from VM import VM from MethodDefinition import MethodDefinition vm = VM() m = MethodDefinition() x = ldc('i4.1') m.instructions.append(x) m.instructions.append(x) m.instructions.append(x) dest = ldc('i4.3') dest.label = 'asdf'
from Instruction import Instruction import unittest from Instructions.Instruction import register class throw(Instruction): def __init__(self, arguments): self.name = 'throw' self.target = '' def execute(self, vm): pass register('throw', throw) class throwTest(unittest.TestCase): def test_throw_no_arguments_throws_exception(self): from VM import VM vm = VM() x = throw('asdf') # fixme optional parameters x.execute(vm) index = vm.get_instruction_pointer() self.assertEqual(3, index) def test_throw_object(self): from VM import VM
def execute(self, vm): stack = vm.stack m = vm.current_method() if self.targetName is None: variable = m.locals[self.index] else: for x in m.locals: if x.name == self.targetName: variable = x stack.push(variable) register("ldloc", ldloc) class ldlocTest(unittest.TestCase): def test_execute_0(self): from VM import VM vm = VM() x = ldloc("0") m = MethodDefinition() m.locals.append(Variable(987)) vm.set_current_method(m) x.execute(vm) self.assertEqual(vm.stack.count(), 1) self.assertEqual(vm.stack.pop().value, 987)
def execute(self, vm): stack = vm.stack m = vm.current_method() if stack.get_frame_count() < 1: raise StackStateException('Not enough values on the stack') object = vm.stack.pop() for fieldIndex in range(len(object.fieldNames)): fieldName = object.fieldNames[fieldIndex] if fieldName == self.fieldName: vm.stack.push(object.fields[fieldIndex]) return raise Exception("Field " + self.fieldName + " not found!") register('ldfld', ldfld) class ldfldTest(unittest.TestCase): 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
if arguments.startswith('s '): self.suffix = '.s' self.opcode = 0xdd self.target = arguments[2:] else: self.opcode = 0xde self.suffix = '' self.target = arguments def execute(self, vm): stack = vm.stack index = vm.find_instruction_pointer_by_label(self.target) vm.current_stack_frame().instructionPointer = index register('leave', leave) class leaveTest(unittest.TestCase): def test_leave(self): from VM import VM from MethodDefinition import MethodDefinition vm = VM() m = MethodDefinition() x = ldc('i4.1') m.instructions.append(x) m.instructions.append(x) m.instructions.append(x) dest = ldc('i4.3') dest.label = 'asdf'
class newarr(Instruction): def __init__(self, arguments): self.name = 'newarr' self.opcode = 0x28 # fixme self.arguments = arguments self.type = Types.resolve_type(arguments) def execute(self, vm): length = vm.stack.pop().value a = Array(length) a.arrayType = self.type vm.stack.push(a) register('newarr', newarr) class newarrTest(unittest.TestCase): def test_newarr_int32_one_element(self): from VM import VM vm = VM() vm.stack.push(Variable(1)) n = newarr('[mscorlib]System.Int32') n.execute(vm) o = vm.stack.pop() self.assertEqual(o.type, Types.Array) self.assertIsInstance(o, Array)
self.method_type, self.method_parameters) m = targetMethod.get_method() #fixme throw exception for x in range(len(self.method_parameters)): m.parameters.insert(0, vm.stack.pop()) # push this pointer on to stack if self.instance: obj = vm.stack.pop() m.parameters.insert(0, obj) vm.execute_method(m) register('callvirt', callvirt) class callvirtTest(unittest.TestCase): def test_callvirt_no_parameters_int(self): from VM import VM from MethodDefinition import MethodDefinition vm = VM() m = MethodDefinition() m.name = 'TestMethod()' m.namespace = 'A.B' m.returnType = Types.Int32 m.parameters = [] m.names = 'A.B' vm.methods.append(m)
def execute(self, vm): stack = vm.stack if stack.get_frame_count() < 2: raise StackStateException('Not enough values on the stack') v2 = stack.pop() v1 = stack.pop() if v1.value < v2.value: stack.push(Variable(1)) else: stack.push(Variable(0)) # fixme - floats? register('clt', clt) class cltTest(unittest.TestCase): def test_execute_not_enough_stack_values(self): from VM import VM vm = VM() vm.stack.push(Variable(1)) x = clt() self.assertRaises(StackStateException, x.execute, vm) def test_execute_v1_less_than_v2_ints(self): from VM import VM vm = VM() vm.stack.push(Variable(5))
from Instruction import Instruction import unittest from Instructions.Instruction import register class ldstr(Instruction): def __init__(self, arguments): self.name = 'ldstr' self.opcode = 72 self.value = arguments def execute(self, vm): stack = vm.stack stack.push(self.value) register('ldstr', ldstr) class ldstrTest(unittest.TestCase): def testExecute(self): from VM import VM vm = VM() x = ldstr('Hello world') x.execute(vm) self.assertEqual(vm.stack.count(), 1) self.assertEqual(vm.stack.pop(), 'Hello world')
stack.push(Variable(7)) elif self.suffix == 'i4.8': stack.push(Variable(8)) elif self.suffix == 'i4.m1' or self.suffix == 'i4.M1': stack.push(Variable(-1)) elif self.suffix == 'i4.s': stack.push(Variable(int(self.value))) def string_to_number(self, str): if str.startswith('0x'): return int(str, 16) else: return int(str) register('ldc', ldc) class ldcTest(unittest.TestCase): def test_execute_i4_hex(self): from VM import VM vm = VM() x = ldc('i4 0x4d2') x.execute(vm) self.assertEqual(vm.stack.count(), 1) self.assertEqual(vm.stack.pop().value, 0x4d2) def test_execute_i4(self): from VM import VM vm = VM()
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) register('newobj', newobj) class newobjTest(unittest.TestCase): 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'
if arguments.startswith('s '): self.suffix = '.s' self.opcode = 0x2b self.target = arguments[2:] else: self.opcode = 0x38 self.suffix = '' self.target = arguments def execute(self, vm): stack = vm.stack index = vm.find_instruction_pointer_by_label(self.target) vm.current_stack_frame().instructionPointer = index register('br', br) class brTest(unittest.TestCase): def test_br(self): from VM import VM from MethodDefinition import MethodDefinition vm = VM() m = MethodDefinition() x = ldc('i4.1') m.instructions.append(x) m.instructions.append(x) m.instructions.append(x) dest = ldc('i4.3') dest.label = 'asdf'
self.name = 'ldlen' def execute(self, vm): stack = vm.stack m = vm.current_method() if stack.get_frame_count() < 1: raise StackStateException('Not enough values on the stack') array = vm.stack.pop() result = Variable(array.length) result.type = Types.UInt32 vm.stack.push(result) # fixme - should be native unsigned int register('ldlen', ldlen) class ldlenTest(unittest.TestCase): def test_execute_not_enough_stack_values(self): from VM import VM vm = VM() x = ldlen('') self.assertRaises(StackStateException, x.execute, vm) def test_execute_valid_array(self): from VM import VM vm = VM()
from Instruction import Instruction import unittest from Instructions.Instruction import register class throw(Instruction): def __init__(self, arguments): self.name = "throw" self.target = "" def execute(self, vm): pass register("throw", throw) class throwTest(unittest.TestCase): def test_throw_no_arguments_throws_exception(self): from VM import VM vm = VM() x = throw("asdf") # fixme optional parameters x.execute(vm) index = vm.get_instruction_pointer() self.assertEqual(3, index) def test_throw_object(self): from VM import VM
self.targetName = self.suffix[2:] def execute(self, vm): stack = vm.stack m = vm.current_method() if self.targetName is None: variable = m.locals[self.index] else: for x in m.locals: if x.name == self.targetName: variable = x stack.push(variable) register('ldloc', ldloc) class ldlocTest(unittest.TestCase): def test_execute_0(self): from VM import VM vm = VM() x = ldloc('0') m = MethodDefinition() m.locals.append(Variable(987)) vm.set_current_method(m) x.execute(vm) self.assertEqual(vm.stack.count(), 1) self.assertEqual(vm.stack.pop().value, 987)
) m = targetMethod.get_method() # fixme throw exception for x in range(len(self.method_parameters)): m.parameters.insert(0, vm.stack.pop()) # push this pointer on to stack if self.instance: obj = vm.stack.pop() m.parameters.insert(0, obj) vm.execute_method(m) register("callvirt", callvirt) class callvirtTest(unittest.TestCase): def test_callvirt_no_parameters_int(self): from VM import VM from MethodDefinition import MethodDefinition vm = VM() m = MethodDefinition() m.name = "TestMethod()" m.namespace = "A.B" m.returnType = Types.Int32 m.parameters = [] m.names = "A.B"
else: self.opcode = 0x3A self.suffix = '' self.target = args def execute(self, vm): # fixme check if there aren't enough stack values variable = vm.stack.pop() if variable.value != 0: index = vm.find_instruction_pointer_by_label(self.target) vm.current_stack_frame().instructionPointer = index # fixme - check for null objects register('brtrue', brtrue) class brtrueTest(unittest.TestCase): def test_execute_true(self): from VM import VM from MethodDefinition import MethodDefinition vm = VM() m = MethodDefinition() x = ldc('i4.1') m.instructions.append(x) m.instructions.append(x) m.instructions.append(x) dest = ldc('i4.3') dest.label = 'asdf'
class sub(Instruction): def __init__(self, arguments=None): self.name = 'sub' self.opcode = 0x59 def execute(self, vm): stack = vm.stack if stack.get_frame_count() < 2: raise StackStateException('Not enough values on the stack') rhs = stack.pop() lhs = stack.pop() stack.push(Variable(lhs.value - rhs.value)) register('sub', sub) class subTest(unittest.TestCase): def testExecute_notEnoughStackValues(self): from VM import VM vm = VM() vm.stack.push(Variable(1)) x = sub() self.assertRaises(StackStateException, x.execute, vm) def testExecute_ints(self): from VM import VM vm = VM() vm.stack.push(Variable(999))
# fixme - set opcode self.name = 'ldlen' def execute(self, vm): stack = vm.stack m = vm.current_method() if stack.get_frame_count() < 1: raise StackStateException('Not enough values on the stack') array = vm.stack.pop() result = Variable(array.length) result.type = Types.UInt32 vm.stack.push(result) # fixme - should be native unsigned int register('ldlen', ldlen) class ldlenTest(unittest.TestCase): def test_execute_not_enough_stack_values(self): from VM import VM vm = VM() x = ldlen('') self.assertRaises(StackStateException, x.execute, vm) def test_execute_valid_array(self): from VM import VM vm = VM()
self.opcode = stelem.opcodePrefixTable[suffix] def execute(self, vm): stack = vm.stack m = vm.current_method() if stack.get_frame_count() < 3: raise StackStateException('Not enough values on the stack') value = vm.stack.pop() index = vm.stack.pop() array = vm.stack.pop() array.values[index.value] = value register('stelem', stelem) class stelemTest(unittest.TestCase): def test_execute_not_enough_stack_values(self): from VM import VM vm = VM() x = stelem('') self.assertRaises(StackStateException, x.execute, vm) def test_execute_set_array_element_i4(self): from VM import VM vm = VM() a = Array(100)
class add(Instruction): def __init__(self, arguments): self.name = 'add' self.opcode = 0x58 def execute(self, vm): stack = vm.stack if stack.get_frame_count() < 2: raise StackStateException('Not enough values on the stack') rhs = stack.pop().value lhs = stack.pop().value stack.push(Variable(lhs + rhs)) register('add', add) class addTest(unittest.TestCase): def test_execute_notEnoughStackValues(self): from VM import VM vm = VM() vm.stack.push(Variable(1)) x = add('') self.assertRaises(StackStateException, x.execute, vm) def test_execute_ints(self): from VM import VM vm = VM() vm.stack.push(Variable(5))
from Instruction import Instruction import unittest import Types from MethodDefinition import MethodDefinition from Instructions.Instruction import register class nop(Instruction): def __init__(self, arguments = None): self.name = 'nop' self.opcode = 0x28 def execute(self, vm): pass register('nop', nop) class nopTes(unittest.TestCase): def test_nop(self): from VM import VM vm = VM() m = MethodDefinition() m.name = 'TestMethod' m.returnType = Types.Void m.parameters = [] vm.methods.append(m) self.assertEqual(vm.currentMethod, None)
if(ldelem.opcodePrefixTable.has_key(suffix)): self.opcode = ldelem.opcodePrefixTable[suffix] def execute(self, vm): stack = vm.stack m = vm.current_method() if stack.get_frame_count() < 2: raise StackStateException('Not enough values on the stack') index = vm.stack.pop() array = vm.stack.pop() vm.stack.push(array.values[index.value]) register('ldelem', ldelem) class ldelemTest(unittest.TestCase): def test_execute_not_enough_stack_values(self): from VM import VM vm = VM() x = ldelem('') self.assertRaises(StackStateException, x.execute, vm) def test_execute_get_array_element_i4(self): from VM import VM vm = VM() a = Array(100)
self.value = None def execute(self, vm): t = vm.current_method() if t.returnType != None and t.returnType != Types.Void: value = vm.stack.pop() vm.stack.endFrame() vm.stack.push(value) else: vm.stack.endFrame() # fixme - return value? register('ret', Ret) class RetTest(unittest.TestCase): def test_execute_void_no_parameters(self): from VM import VM vm = VM() m = Method() m.name = 'TestMethod' m.returnType = Types.Void m.parameters = [] vm.methods.append(m) self.assertEqual(vm.current_method(), None) vm.execute_method(m)
m.locals[self.index].value = value.value else: for x in range(len(m.locals)): if m.locals[x].name == self.targetName: if isinstance(value, ReferenceType): value.name = variable.name # fixme - set other properties? m.locals[x] = value else: m.locals[x].value = value.value #temp = stack.pop() #variable.value = stack.pop().value register('stloc', stloc) class stlocTest(unittest.TestCase): 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)
else: for x in range(len(m.locals)): if m.locals[x].name == self.targetName: if isinstance(value, ReferenceType): value.name = variable.name # fixme - set other properties? m.locals[x] = value else: m.locals[x].value = value.value #temp = stack.pop() #variable.value = stack.pop().value register('stloc', stloc) class stlocTest(unittest.TestCase): 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)
else: self.opcode = 0x3B self.suffix = '' self.target = args def execute(self, vm): # fixme check if there aren't enough stack values value2 = vm.stack.pop() value1 = vm.stack.pop() if value1.value == value2.value: index = vm.find_instruction_pointer_by_label(self.target) vm.current_stack_frame().instructionPointer = index # fixme - check for null objects register('beq', beq) class beqTest(unittest.TestCase): def test_execute_true(self): from VM import VM from MethodDefinition import MethodDefinition vm = VM() m = MethodDefinition() m.maxStack = 3 x = ldc('i4.1') m.instructions.append(x) m.instructions.append(x) m.instructions.append(x) dest = ldc('i4.3')
raise Exception('Unimplemented conversion ' + self.suffix) stack.push(result) def convert_to_i4(self, input): type = Types.Int32 value = None if input.type == Types.UInt32: value = input.value # fixme - truncate/overflow/etc else: raise Exception('Unimplemented i4 conversion ' + input.type) result = Variable(value) result.type = type return result register('conv', conv) class convTest(unittest.TestCase): def test_execute_notEnoughStackValues(self): from VM import VM vm = VM() x = conv('i1') self.assertRaises(StackStateException, x.execute, vm) def test_execute_i4_no_overflow(self): from VM import VM vm = VM() v = Variable(999)
self.index = 3 elif self.suffix.startswith('s '): self.index = int(self.suffix[2:]) self.opcode = ldarg.opcodePrefixTable['s'] else: self.index = int(self.suffix) self.opcode = 0xFE09 def execute(self, vm): stack = vm.stack m = vm.current_method() variable = m.parameters[self.index] stack.push(variable) register('ldarg', ldarg) class LdargTest(unittest.TestCase): def test_execute_0(self): from VM import VM vm = VM() x = ldarg('0') m = MethodDefinition() m.parameters.append(Variable(987)) vm.set_current_method(m) x.execute(vm) self.assertEqual(vm.stack.count(), 1) self.assertEqual(vm.stack.pop().value, 987)
class pop(Instruction): def __init__(self, arguments): self.name = 'pop' self.opcode = 0x26 def execute(self, vm): stack = vm.stack if stack.get_frame_count() < 1: raise StackStateException('Not enough values on the stack') stack.pop() register('pop', pop) class popTest(unittest.TestCase): def test_execute_notEnoughStackValues(self): from VM import VM vm = VM() x = pop('') self.assertRaises(StackStateException, x.execute, vm) def test_execute(self): from VM import VM vm = VM() vm.stack.push(Variable(5))
class add(Instruction): def __init__(self, arguments): self.name = 'add' self.opcode = 0x58 def execute(self, vm): stack = vm.stack if stack.get_frame_count() < 2: raise StackStateException('Not enough values on the stack') rhs = stack.pop().value lhs = stack.pop().value stack.push(Variable(lhs + rhs)) register('add', add) class addTest(unittest.TestCase): def test_execute_notEnoughStackValues(self): from VM import VM vm = VM() vm.stack.push(Variable(1)) x = add('') self.assertRaises(StackStateException, x.execute, vm) def test_execute_ints(self): from VM import VM vm = VM()
class pop(Instruction): def __init__(self, arguments): self.name = 'pop' self.opcode = 0x26 def execute(self, vm): stack = vm.stack if stack.get_frame_count() < 1: raise StackStateException('Not enough values on the stack') stack.pop() register('pop', pop) class popTest(unittest.TestCase): def test_execute_notEnoughStackValues(self): from VM import VM vm = VM() x = pop('') self.assertRaises(StackStateException, x.execute, vm) def test_execute(self): from VM import VM vm = VM() vm.stack.push(Variable(5)) x = pop('')
def execute(self, vm): targetMethod = vm.find_method_by_signature(self.method_namespace, self.method_name, self.method_type, self.method_parameters) m = targetMethod.get_method() #fixme throw exception for x in range(len(self.method_parameters)): m.parameters.insert(0, vm.stack.pop()) # push this pointer on to stack if self.instance: obj = vm.stack.pop() m.parameters.insert(0, obj) vm.execute_method(m) register('call', call) class callTest(unittest.TestCase): def test_call_no_parameters_int(self): from VM import VM from MethodDefinition import MethodDefinition vm = VM() m = MethodDefinition() m.name = 'TestMethod()' m.namespace = 'A.B' m.returnType = Types.Int32 m.parameters = [] m.names = 'A.B' vm.methods.append(m)