InvokeOp(MethodLocation location, MethodLocation child, VirtualMethod method, int[] parameterRegisters, VirtualMachine vm) { super(location, child); this.method = method; this.parameterRegisters = parameterRegisters; analyzedParameterTypes = new String[method.getParameterTypeNames().size()]; this.vm = vm; classManager = vm.getClassManager(); sideEffectLevel = SideEffect.Level.STRONG; }
public ExecutionContext spawnRootContext(String className, String methodDescriptor) { VirtualMethod method = getClassManager().getVirtualClass(className).getMethod(methodDescriptor); if (method == null) { throw new RuntimeException("Method signature not found: " + className + "->" + methodDescriptor); } return spawnRootContext(method); }
private HeapItem getVirtualField(Field field, VirtualMachine vm, ExecutionContext context) { String className = ClassNameUtils.toInternal(field.getDeclaringClass()); VirtualClass fieldClass = vm.getClassManager().getVirtualClass(className); VirtualField virtualField = fieldClass.getField(field.getName()); StaticFieldAccessor accessor = vm.getStaticFieldAccessor(); return accessor.getField(context, virtualField); }
@Override public Op create(MethodLocation location, TIntObjectMap<MethodLocation> addressToLocation, VirtualMachine vm) { MethodLocation child = Utils.getNextLocation(location, addressToLocation); Instruction21c instr = (Instruction21c) location.getInstruction(); int targetRegister = instr.getRegisterA(); TypeReference reference = (TypeReference) instr.getReference(); VirtualType referenceType = vm.getClassManager().getVirtualType(reference); return new CheckCastOp(location, child, targetRegister, referenceType, vm.getClassManager(), vm.getExceptionFactory()); }
@Override public Op create(MethodLocation location, TIntObjectMap<MethodLocation> addressToLocation, VirtualMachine vm) { MethodLocation child = Utils.getNextLocation(location, addressToLocation); Instruction21c instr = (Instruction21c) location.getInstruction(); int destRegister = instr.getRegisterA(); TypeReference typeRef = (TypeReference) instr.getReference(); String className = typeRef.getType(); VirtualClass virtualClass = vm.getClassManager().getVirtualClass(className); return new NewInstanceOp(location, child, destRegister, virtualClass, vm); }
@Before public void setUp() { vm = VMTester.spawnVM(true); thisReference = vm.getClassManager().getVirtualClass(CLASS_NAME); }
private static ExecutionContext buildContext(VirtualMachine vm) { VirtualClass dummyClass = vm.getClassManager().getVirtualClass(DUMMY_CLASS_NAME); VirtualMethod inertStatic = dummyClass.getMethod("dummyMethod()V"); return vm.spawnRootContext(inertStatic); }
@Override public Op create(MethodLocation location, TIntObjectMap<MethodLocation> addressToLocation, VirtualMachine vm) { MethodLocation child = Utils.getNextLocation(location, addressToLocation); Instruction22c instr = (Instruction22c) location.getInstruction(); int destRegister = instr.getRegisterA(); int arg1Register = instr.getRegisterB(); TypeReference typeReference = (TypeReference) instr.getReference(); VirtualType referenceType = vm.getClassManager().getVirtualType(typeReference); return new InstanceOfOp(location, child, destRegister, arg1Register, referenceType, vm); }
@Before public void setUp() { vm = VMTester.spawnVM(); virtualClass = vm.getClassManager().getVirtualClass(CLASS_NAME); initial = new VMState(); }
@Override public Op create(MethodLocation location, TIntObjectMap<MethodLocation> addressToLocation, VirtualMachine vm) { MethodLocation child = Utils.getNextLocation(location, addressToLocation); Instruction21c instr = (Instruction21c) location.getInstruction(); int destRegister = instr.getRegisterA(); FieldReference fieldReference = (FieldReference) instr.getReference(); VirtualClass fieldClass = vm.getClassManager().getVirtualClass(fieldReference.getDefiningClass()); VirtualField actualField = fieldClass.getField(fieldReference.getName()); return new SGetOp(location, child, destRegister, fieldReference, actualField, vm); }
@Override public Op create(MethodLocation location, TIntObjectMap<MethodLocation> addressToLocation, VirtualMachine vm) { MethodLocation child = Utils.getNextLocation(location, addressToLocation); Instruction21c instr = (Instruction21c) location.getInstruction(); int destRegister = instr.getRegisterA(); FieldReference fieldReference = (FieldReference) instr.getReference(); VirtualClass fieldClass = vm.getClassManager().getVirtualClass(fieldReference.getDefiningClass()); VirtualField actualField = fieldClass.getField(fieldReference.getName()); return new SPutOp(location, child, destRegister, fieldReference, actualField, vm); }
private static void testRegisterCount(ExecutionGraphManipulator manipulator, String methodDescriptor, int expectedRegisterCount) { ClassManager classManager = manipulator.getVM().getClassManager(); VirtualMethod method = classManager.getMethod(CLASS_NAME, methodDescriptor); int actualRegisterCount = method.getImplementation().getRegisterCount(); assertEquals(expectedRegisterCount, actualRegisterCount); }
@Before public void setupVM() { /* * On TravisCI, these tests fail with StackOverflowError and missing classes unless classes are reloaded. Local test classes are actually * completely missing for no obvious reason. */ vm = VMTester.spawnVM(true); ClassManager classManager = vm.getClassManager(); childClass = classManager.getVirtualClass("Lchild_class;"); parentClass = classManager.getVirtualClass("Lparent_class;"); grandparentClass = classManager.getVirtualClass("Lgrandparent_class;"); }
@Test public void canCreateLocalInstance() throws ClassNotFoundException { initial.setRegisters(0, 1, "I"); ExecutionGraph graph = VMTester.execute(vm, CLASS_NAME, "newLocalInstance()V", initial); VirtualType instanceType = vm.getClassManager().getVirtualType(CLASS_NAME); expected.setRegisters(0, new UninitializedInstance(instanceType), CLASS_NAME); VMTester.testState(graph, expected); }
@Test public void hasExpectedToString() { VirtualMachine vm = VMTester.spawnVM(); VirtualClass virtualClass = vm.getClassManager().getVirtualClass(CLASS_NAME); VirtualMethod method = virtualClass.getMethod("invokeReturnVoid()V"); ExecutionGraph graph = vm.spawnInstructionGraph(method); Op op = graph.getOp(0); assertEquals("invoke-static {}, " + CLASS_NAME + "->returnVoid()V", op.toString()); } }
@Test public void stringInitWithUnknownValueIsNotReplaced() { VirtualType instanceType = vm.getClassManager().getVirtualType("Ljava/lang/String;"); ExecutionGraphManipulator manipulator = getOptimizedGraph(vm, METHOD_NAME, 0, new UninitializedInstance(instanceType), "Ljava/lang/String;", 1, new UnknownValue(), "[B"); Instruction35c instruction = (Instruction35c) manipulator.getInstruction(ADDRESS); String methodDescriptor = ReferenceUtil.getMethodDescriptor((MethodReference) instruction.getReference()); assertEquals("Ljava/lang/String;-><init>([B)V", methodDescriptor); }
private static ExecutionContext buildInitializedContext(VirtualMachine vm, String methodSignature, VMState state) { VirtualMethod method = vm.getClassManager().getMethod(methodSignature); ExecutionContext context = vm.spawnRootContext(method); int registerCount = context.getMethodState().getRegisterCount(); setupMethodState(context, state.getRegisters(), registerCount); setupClassStates(context, vm, state.getFields()); return context; }
@Test public void enumClassInitializationCreatesCorrectClass() { VirtualMachine vm = VMTester.spawnVM(); VirtualType type = vm.getClassManager().getVirtualType("Lextends_enum;"); initial.setRegisters(0, new UninitializedInstance(type), "Lextends_enum;", 1, "NONE", "Ljava/lang/String;", 2, 0, "I", 3, 0, "I"); ExecutionGraph graph = VMTester.execute("Lextends_enum;", "<init>(Ljava/lang/String;II)V", initial); HeapItem consensus = graph.getTerminatingRegisterConsensus(0); assertEquals("Lextends_enum;", consensus.getType()); } }
@Test public void objectClassInitializationCreatesCorrectClass() { VirtualMachine vm = VMTester.spawnVM(); VirtualType type = vm.getClassManager().getVirtualType("Lhash_code;"); initial.setRegisters(0, new UninitializedInstance(type), "Lhash_code;"); ExecutionGraph graph = VMTester.execute("Lhash_code;", "<init>()V"); HeapItem consensus = graph.getTerminatingRegisterConsensus(0); assertEquals("Lhash_code;", consensus.getType()); }
private void testForExpectedInstruction(Object register1, String expectedConstant) { VirtualType instanceType = vm.getClassManager().getVirtualType("Ljava/lang/String;"); ExecutionGraphManipulator manipulator = getOptimizedGraph(METHOD_NAME, 0, new UninitializedInstance(instanceType), "Ljava/lang/String;", 1, register1, "[B"); BuilderInstruction21c instruction = (BuilderInstruction21c) manipulator.getInstruction (ADDRESS); assertEquals(Opcode.CONST_STRING, instruction.getOpcode()); assertEquals(0, instruction.getRegisterA()); String actualConstant = ((StringReference) instruction.getReference()).getString(); assertEquals(expectedConstant, actualConstant); } }