def test_ins_fdiv(): ins = instructions.keywords['fdiv'] frm = make_frame() frm.stack.append(value_containers.ValueFloat(55.0)) frm.stack.append(value_containers.ValueFloat(10.0)) VM.exec_frame(frm, ins()) assert frm.stack[0] == value_containers.ValueFloat(5.5) frm.stack.append(value_containers.ValueInt(9)) frm.stack.append(value_containers.ValueInt(9)) pytest.raises(TypeError, VM.exec_frame, frm, ins())
def test_fastore(): vt = value_containers.ValueFloat ins = instructions.keywords['fastore'] frm = make_frame() arr = value_containers.ValueFloatArrayRef() arr.allocate(10) arr[2] = value_containers.ValueFloat(4.0) frm.stack.append(arr) frm.stack.append(value_containers.ValueInt(0)) frm.stack.append(value_containers.ValueFloat(5.0)) VM.exec_frame(frm, ins()) assert arr[0] == vt(5.0) assert arr[1].is_none assert arr[1].__class__ == vt
def test_ins_if_fcmpeq(): ins = instructions.keywords['if_fcmpeq'] frm = make_frame() frm.stack.append(value_containers.ValueFloat(9.9)) frm.stack.append(value_containers.ValueFloat(9.9)) assert len(frm.stack) == 2 VM.exec_frame(frm, ins(value_containers.ValueInt(2))) assert frm.pc == 2 assert len(frm.stack) == 0 frm = make_frame() frm.stack.append(value_containers.ValueFloat(9.9)) frm.stack.append(value_containers.ValueFloat(9.91)) VM.exec_frame(frm, ins(value_containers.ValueInt(2))) assert frm.pc == VM_PC_START + 1
def test_ins_fpush(): frm = make_frame() value = value_containers.ValueFloat(9.9) assert len(frm.stack) == 0 VM.exec_frame(frm, instructions.keywords['fpush'](value)) assert frm.pc == VM_PC_START + 1 assert frm.stack[0] == value
def test_ins_fload(): frm = make_frame() value = value_containers.ValueFloat(9.9) frm.variables[0] = value assert len(frm.stack) == 0 VM.exec_frame(frm, instructions.keywords['fload'](value_containers.ValueInt(0))) assert frm.pc == VM_PC_START + 1 assert frm.stack[0] == value
def test_ins_freturn(): ins = instructions.keywords['freturn'] frm = make_frame() value = value_containers.ValueFloat(9.9) frm.stack.append(value) VM.exec_frame(frm, ins()) assert frm.pc == VM_PC_START + 1 assert frm.finished is True assert frm.return_value == value
def test_ins_fstore(): ins = instructions.keywords['fstore'] frm = make_frame() value = value_containers.ValueFloat(9.9) frm.stack.append(value) VM.exec_frame(frm, ins(value_containers.ValueInt(0))) assert frm.variables[0] == value assert frm.pc == VM_PC_START + 1 assert len(frm.stack) == 0
def test_args(): for name, ins in instructions.keywords.items(): if issubclass(ins, instructions.InsArgument): pytest.raises(InstructionException, ins) if issubclass(ins, instructions.InsArgInteger): assert ins(value_containers.ValueInt(1)) is not None elif issubclass(ins, instructions.InsArgFloat): assert ins(value_containers.ValueFloat(1.0)) is not None else: assert ins() is not None
def test_ins_areturn(): ins = instructions.keywords['areturn'] frm = make_frame() value = value_containers.ValueFloatArrayRef() value.allocate(10) value[2] = value_containers.ValueFloat(4.0) frm.stack.append(value) VM.exec_frame(frm, ins()) assert frm.pc == VM_PC_START + 1 assert frm.finished is True assert frm.return_value == value
def test_ins_array_length(): ins = instructions.keywords['arraylength'] frm = make_frame() value = value_containers.ValueFloatArrayRef() value.allocate(10) value[2] = value_containers.ValueFloat(4.0) frm.stack.append(value) VM.exec_frame(frm, ins()) assert frm.pc == VM_PC_START + 1 v = frm.stack.pop() assert v == value_containers.ValueInt(10) pytest.raises(IndexError, ins().execute, frm)
def test_ins_swap(): frm = make_frame() frm.stack.append(value_containers.ValueInt(99)) frm.stack.append(value_containers.ValueFloat(5.5)) assert len(frm.stack) == 2 assert isinstance(frm.stack[0], value_containers.ValueInt) assert isinstance(frm.stack[1], value_containers.ValueFloat) assert frm.stack[0].value == 99 assert frm.stack[1].value == 5.5 VM.exec_frame(frm, instructions.keywords['swap']()) assert frm.pc == VM_PC_START + 1 assert len(frm.stack) == 2 assert isinstance(frm.stack[1], value_containers.ValueInt) assert isinstance(frm.stack[0], value_containers.ValueFloat) assert frm.stack[1].value == 99 assert frm.stack[0].value == 5.5
def test_faload(): vt = value_containers.ValueFloat ins = instructions.keywords['faload'] frm = make_frame() arr = value_containers.ValueFloatArrayRef() arr.allocate(10) arr[2] = value_containers.ValueFloat(4.0) frm.stack.append(arr) frm.stack.append(value_containers.ValueInt(2)) VM.exec_frame(frm, ins()) assert frm.stack.pop() == vt(4.0) frm.stack.append(arr) frm.stack.append(value_containers.ValueInt(1)) VM.exec_frame(frm, ins()) sv = frm.stack.pop() assert sv.is_none assert sv.__class__ == vt
def test_flow_instructions(): # make sure no instruction fall through for name, i in instructions.keywords.items(): m = Method() anz = controlflow.ControlFlowAnalyzer() if issubclass(i, instructions.InsGoto): m.code.append(i(value_containers.ValueInt(3))) m.code.append(instructions.InsNop()) m.code.append(instructions.InsNop()) m.code.append(instructions.InsNop()) anz.analyze(m) assert anz.basic_blocks == [ BasicBlock(instruction_indexes=[0], sucessors=[None]), BasicBlock(instruction_indexes=[1, 2], sucessors=[None]), BasicBlock(instruction_indexes=[3], predecessors=[None, None]) ] elif issubclass(i, instructions.InsBranch): m.code.append(instructions.InsNop()) m.code.append(i(value_containers.ValueInt(0))) anz.analyze(m) assert anz.basic_blocks == [ BasicBlock(instruction_indexes=[0, 1], sucessors=[None], predecessors=[None]) ] elif not issubclass(i, instructions.InsReturn): if issubclass(i, instructions.InsNoArgument): m.code.append(i()) elif issubclass(i, instructions.InsArgInteger): m.code.append(i(value_containers.ValueInt(1))) elif issubclass(i, instructions.InsArgFloat): m.code.append(i(value_containers.ValueFloat(5.0))) else: assert False anz.analyze(m) assert anz.basic_blocks == [BasicBlock(instruction_indexes=[0])] elif issubclass(i, instructions.InsReturn): m.code.append(i()) anz.analyze(m) assert anz.basic_blocks == [BasicBlock(instruction_indexes=[0])] else: assert False
def test_ins_f2i(): ins = instructions.keywords['f2i'] frm = make_frame() frm.stack.append(value_containers.ValueFloat(9.9)) VM.exec_frame(frm, ins()) assert frm.stack[0] == value_containers.ValueInt(9)
def test_execute(): for _, inst in instructions.keywords.items(): for inter in [BasicInterpreter, BasicVerifier]: frame = Frame() frame.add_local(UNINITIALIZED_VALUE) if issubclass(inst, instructions.InsArgInteger): ins = inst(value_containers.ValueInt(0)) elif issubclass(inst, instructions.InsArgFloat): ins = inst(value_containers.ValueFloat(0.0)) else: ins = inst() # prepare frame state if inst.opcode == opcodes.ILOAD: frame.locals[0] = INT_VALUE elif inst.opcode == opcodes.FLOAD: frame.locals[0] = FLOAT_VALUE elif inst.opcode == opcodes.ISTORE: frame.add_local_type(INT_VALUE) frame.push(INT_VALUE) elif inst.opcode == opcodes.FSTORE: frame.add_local_type(FLOAT_VALUE) frame.push(FLOAT_VALUE) elif inst.opcode == opcodes.IRETURN: frame.push(INT_VALUE) frame.return_value = INT_VALUE elif inst.opcode == opcodes.FRETURN: frame.push(FLOAT_VALUE) frame.return_value = FLOAT_VALUE elif inst.opcode == opcodes.POP: frame.push(UNINITIALIZED_VALUE) elif inst.opcode == opcodes.DUP: frame.push(UNINITIALIZED_VALUE) elif inst.opcode == opcodes.SWAP: frame.push(INT_VALUE) frame.push(FLOAT_VALUE) elif opcodes.IF_ICMPEQ <= inst.opcode <= opcodes.IF_ICMPLT: frame.push(INT_VALUE) frame.push(INT_VALUE) elif opcodes.IF_FCMPEQ <= inst.opcode <= opcodes.IF_FCMPLT: frame.push(FLOAT_VALUE) frame.push(FLOAT_VALUE) elif inst.opcode == opcodes.IFNONNULL or inst.opcode == opcodes.IFNULL: frame.push(ARRAY_REF) elif opcodes.IADD <= inst.opcode <= opcodes.IDIV: frame.push(INT_VALUE) frame.push(INT_VALUE) elif opcodes.FADD <= inst.opcode <= opcodes.FDIV: frame.push(FLOAT_VALUE) frame.push(FLOAT_VALUE) elif inst.opcode == opcodes.F2I: frame.push(FLOAT_VALUE) elif inst.opcode == opcodes.I2F: frame.push(INT_VALUE) elif inst.opcode == opcodes.ALOAD: frame.locals[0] = ARRAY_REF elif inst.opcode == opcodes.ASTORE: frame.add_local_type(ARRAY_REF) frame.push(INT_ARRAY_REF) elif inst.opcode == opcodes.IASTORE: frame.push(INT_ARRAY_REF) frame.push(INT_VALUE) frame.push(INT_VALUE) elif inst.opcode == opcodes.IALOAD: frame.push(INT_ARRAY_REF) frame.push(INT_VALUE) elif inst.opcode == opcodes.FASTORE: frame.push(FLOAT_ARRAY_REF) frame.push(INT_VALUE) frame.push(FLOAT_VALUE) elif inst.opcode == opcodes.FALOAD: frame.push(FLOAT_ARRAY_REF) frame.push(INT_VALUE) elif inst.opcode == opcodes.ARETURN: frame.push(ARRAY_REF) frame.return_value = ARRAY_REF elif inst.opcode == opcodes.NEWARRAY: frame.push(INT_VALUE) elif inst.opcode == opcodes.ARRAYLENGTH: frame.push(ARRAY_REF) elif inst.opcode == opcodes.NOP: pass elif inst.opcode == opcodes.GOTO: pass elif inst.opcode == opcodes.IPUSH: pass elif inst.opcode == opcodes.FPUSH: pass else: assert False # execute instruction in frame using and interpreter frame.execute(ins, inter()) # check frame state after execution if inst.opcode == opcodes.ILOAD: assert frame.pop() == INT_VALUE elif inst.opcode == opcodes.FLOAD: assert frame.pop() == FLOAT_VALUE elif inst.opcode == opcodes.ISTORE: assert frame.stack_size == 0 assert frame.locals[0] == INT_VALUE elif inst.opcode == opcodes.FSTORE: assert frame.stack_size == 0 assert frame.locals[0] == FLOAT_VALUE elif inst.opcode == opcodes.IRETURN: assert frame.stack_size == 0 assert frame.return_value == INT_VALUE elif inst.opcode == opcodes.FRETURN: assert frame.stack_size == 0 assert frame.return_value == FLOAT_VALUE elif inst.opcode == opcodes.POP: assert frame.stack_size == 0 elif inst.opcode == opcodes.DUP: assert frame.pop() == UNINITIALIZED_VALUE assert frame.pop() == UNINITIALIZED_VALUE elif inst.opcode == opcodes.SWAP: assert frame.pop() == INT_VALUE assert frame.pop() == FLOAT_VALUE elif opcodes.IF_ICMPEQ <= inst.opcode <= opcodes.IF_ICMPLT or opcodes.IF_FCMPEQ <= inst.opcode <= opcodes.IF_FCMPLT: assert frame.stack_size == 0 elif inst.opcode == opcodes.IFNONNULL or inst.opcode == opcodes.IFNULL: assert frame.stack_size == 0 elif opcodes.IADD <= inst.opcode <= opcodes.IDIV: assert frame.pop() == INT_VALUE elif opcodes.FADD <= inst.opcode <= opcodes.FDIV: assert frame.pop() == FLOAT_VALUE elif inst.opcode == opcodes.F2I: assert frame.pop() == INT_VALUE elif inst.opcode == opcodes.I2F: assert frame.pop() == FLOAT_VALUE elif inst.opcode == opcodes.ALOAD: assert frame.pop() == ARRAY_REF elif inst.opcode == opcodes.ASTORE: assert frame.locals[0] == INT_ARRAY_REF elif inst.opcode == opcodes.IASTORE: assert frame.stack_size == 0 elif inst.opcode == opcodes.IALOAD: assert frame.pop() == INT_VALUE elif inst.opcode == opcodes.FASTORE: assert frame.stack_size == 0 elif inst.opcode == opcodes.FALOAD: assert frame.pop() == FLOAT_VALUE elif inst.opcode == opcodes.ARETURN: assert frame.stack_size == 0 elif inst.opcode == opcodes.NEWARRAY: assert frame.pop() == INT_ARRAY_REF elif inst.opcode == opcodes.ARRAYLENGTH: assert frame.pop() == INT_VALUE elif inst.opcode == opcodes.NOP: pass elif inst.opcode == opcodes.GOTO: pass elif inst.opcode == opcodes.IPUSH: assert frame.pop() == INT_VALUE elif inst.opcode == opcodes.FPUSH: assert frame.pop() == FLOAT_VALUE else: assert False # stack has to be empty assert frame.stack_size == 0