def test_return_results(): value = Integer.create_instance(5) for instruction in RETURN_RESULT_INSTRUCTIONS: assert_instruction(instruction=instruction, op_stack=[value], expected=[ReturnResult(value)])
def test_go_to(): offset = 4 source = 10 # noinspection PyProtectedMember instruction = literal_instruction('goto', offset) instruction = named_tuple_replace(instruction, pos=source) target = offset + source assert_instruction(instruction=instruction, expected=[GoTo(target)])
def test_if_null(): offset = 10 source = 3 value = ArrayReferenceType(Integer).create_instance(NULL_OBJECT) instruction = literal_instruction('ifnull', offset) instruction = named_tuple_replace(instruction, pos=source) assert_instruction(instruction=instruction, op_stack=[value], expected=[Pop(), GoTo(source + offset)])
def test_int_load_from_null_array(): array = NULL_VALUE index = Integer.create_instance(0) assert_instruction( instruction='iaload', op_stack=[index, array], expected=[ throw_null_pointer() ] )
def test_int_store_into_null_array(): value = SOME_INT index = Integer.create_instance(1) array = NULL_VALUE assert_instruction( instruction='iastore', op_stack=[value, index, array], expected=[ throw_null_pointer() ] )
def test_table_switch(): source = 1 switch = TableSwitch(10, [2, 3, 4]) instruction = switch.create_instruction(source) irrelevant_value = switch.high * 2 for i, off in enumerate(switch.offsets): assert_instruction(instruction=instruction, op_stack=[Integer.create_instance(i + switch.low)], expected=[Pop(), GoTo(source + off)]) assert_instruction(instruction=instruction, op_stack=[Integer.create_instance(irrelevant_value)], expected=[Pop(), GoTo(source + switch.default)])
def test_lookup_switch(): source = 1 switch = LookupSwitch(10, [(0, 3), (1, 6), (2, 9)]) irrelevant_value = max(switch.pairs.values()) + 1 instruction = switch.create_instruction(source) for value, offset in switch.pairs.items(): assert_instruction(instruction=instruction, op_stack=[Integer.create_instance(value)], expected=[Pop(), GoTo(source + offset)]) assert_instruction(instruction=instruction, op_stack=[Integer.create_instance(irrelevant_value)], expected=[Pop(), GoTo(source + switch.default)])
def test_invoke_v(): method_name = 'method_name' class_name = 'class_name' consts = ConstantPool() descriptor = '(II)V' key = MethodKey(method_name, descriptor) no_op = Instruction.create('nop') method = BytecodeMethod( name='method_name', descriptor='(II)V', max_locals=5, max_stack=5, instructions=[no_op, no_op], args=[Integer, Integer], ) jvm_class = JvmClass( class_name, RootObjectType.refers_to, consts, methods={ key: method } ) method_ref = consts.create_method_ref(class_name, method_name, descriptor) instruction = constant_instruction('invokevirtual', method_ref) loader = FixedClassLoader({ class_name: jvm_class }) instance = loader.default_instance(class_name) arg_value = SOME_INT arguments = [instance, arg_value, arg_value] reversed_arguments = list(reversed(arguments)) assert_instruction( constants=consts, loader=loader, instruction=instruction, op_stack=reversed_arguments, expected=[ Pop(3), Invoke(class_name, key, arguments) ] )
def _test_branch_comp(name, source, offset, values, type_, op): result = op(*values) if result: actual_offset = offset else: actual_offset = 1 target = source + actual_offset instruction = literal_instruction(name, offset) instruction = named_tuple_replace(instruction, pos=source) try: assert_instruction(instruction=instruction, op_stack=[type_.create_instance(v) for v in values], expected=[Pop(len(values)), GoTo(target)]) except AssertionError as e: raise AssertionError( f'Branch comparison test for {name} failed') from e
def test_return_void(): assert_instruction(instruction='return', expected=[ReturnVoid()])