public HeapItem peekExceptionRegister() { return peekRegister(ExceptionRegister); }
public HeapItem peekResultRegister() { return peekRegister(ResultRegister); }
public HeapItem peekThrowRegister() { return peekRegister(ThrowRegister); }
public HeapItem peekReturnRegister() { return peekRegister(ReturnRegister); }
public HeapItem peekParameter(int parameterRegister) { HeapItem item; if (mutableParameters.contains(parameterRegister)) { item = peekRegister(parameterRegister, MUTABLE_PARAMETER_HEAP); } else { item = peekRegister(parameterRegister); } return item; }
public MethodLocation getPseudoInstructionReturnInstruction() { return (MethodLocation) peekRegister(ReturnAddressRegister).getValue(); }
/** * This gives you every possible value for a given {@code address} and {@code register}. * * @return returns items at {@code address} in {@code register} for every execution path */ public Set<HeapItem> getRegisterItems(int address, int register) { List<ExecutionNode> nodePile = getNodePile(address); Set<HeapItem> items = new HashSet<>(nodePile.size()); for (ExecutionNode node : nodePile) { MethodState mState = node.getContext().getMethodState(); HeapItem item = mState.peekRegister(register); items.add(item); } return items; }
ctx.append("(p").append(register - getParameterStart()).append(')'); HeapItem item = peekRegister(register); ctx.append(": ").append(item).append('\n'); ctx.append("result: ").append(peekRegister(ResultRegister)).append('\n'); ctx.append("return: ").append(peekRegister(ReturnRegister)).append('\n');
public @Nullable HeapItem peekRegister(int register) { if (register == MethodState.ResultRegister) { if (!hasRegister(register, METHOD_HEAP)) { if (getParent() != null && !getParent().hasRegister(register, METHOD_HEAP)) { // ResultRegister can only be read by the instruction immediately after it's set. // It's not in this instruction or its parent, so it effectively doesn't exist. // log.warn("Attempting to read result register but it's not in current or parent context! // Returning null."); return null; } } } return peekRegister(register, METHOD_HEAP); }
@Override public void execute(ExecutionNode node, MethodState mState) { MethodState parent = mState.getParent(); int targetRegister = parent.getRegistersAssigned()[0]; // Peek rather than read. This pseudo-instruction shouldn't count as an actual usage for the optimizer. HeapItem arrayItem = mState.peekRegister(targetRegister); if (!arrayItem.isUnknown()) { Object array = arrayItem.getValue(); Class<?> expectedClass = array.getClass().getComponentType(); for (int i = 0; i < arrayElements.size(); i++) { Number number = arrayElements.get(i); Object value = getProperValue(number, expectedClass); Array.set(array, i, value); } // Poke rather than assign for the optimizer. mState.pokeRegister(targetRegister, arrayItem); } MethodLocation returnLocation = mState.getParent().getPseudoInstructionReturnInstruction(); node.setChildLocations(returnLocation); }
HeapItem item = context.getMethodState().peekRegister(registerA); preCastType = item.getType();
private void executeArrayClone(MethodState callerMethodState, ExecutionNode node) { int instanceRegister = parameterRegisters[0]; HeapItem arrayItem = callerMethodState.peekRegister(instanceRegister); if (arrayItem.isUnknown()) { callerMethodState.assignResultRegister(new UnknownValue(), arrayItem.getType()); } else if (arrayItem.isNull()) { // This operation would have thrown a null pointer exception, and nothing else. Throwable exception = new NullPointerException(); addException(exception); node.clearChildren(); } else { Method m = null; try { m = Object.class.getDeclaredMethod("clone"); m.setAccessible(true); Object clone = m.invoke(arrayItem.getValue()); callerMethodState.assignResultRegister(clone, arrayItem.getType()); } catch (Exception e) { // TODO: should handle exceptions here and bubble them up e.printStackTrace(); } } }
mState.assignParameter(0, instanceItem); } else { HeapItem targetItem = mState.peekRegister(0); if (log.isDebugEnabled()) { log.debug("Reflecting virtual {}, target={} args={}", method, targetItem, Arrays.toString(args));
private void executeLocalObjectInit(MethodState callerMethodState) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { int instanceRegister = parameterRegisters[0]; HeapItem instanceItem = callerMethodState.peekRegister(instanceRegister); UninitializedInstance uninitializedInstance = (UninitializedInstance) instanceItem.getValue(); VirtualType instanceType = uninitializedInstance.getType(); // Create a Java class of the true type Class<?> klazz = vm.getClassLoader().loadClass(instanceType.getBinaryName()); Object newInstance = ObjectInstantiator.newInstance(klazz); HeapItem newInstanceItem = new HeapItem(newInstance, instanceType.getName()); callerMethodState.assignRegisterAndUpdateIdentities(instanceRegister, newInstanceItem); }
if (method.getName().equals("clone") && parameterRegisters.length == 1) { int targetRegister = parameterRegisters[0]; HeapItem item = context.getMethodState().peekRegister(targetRegister); String signature = method.getSignature(); if (signature.charAt(0) == '[' || (!item.isNull() && item.getValueType().charAt(0) == '[')) { if (getName().startsWith("invoke-virtual") && !method.isFinal()) { int targetRegister = parameterRegisters[0]; HeapItem item = context.getMethodState().peekRegister(targetRegister); targetMethod = resolveTargetMethod(item.getValue());
@Test public void methodStateForVirtualMethodCreatedCorrectly() throws VirtualMachineException { String methodDescriptor = "someString()Ljava/lang/String;"; VirtualMethod method = vm.getClassManager().getMethod(CLASS_NAME, methodDescriptor); ExecutionContext spawnedContext = new ExecutionContext(vm, method); ClassState templateClassState = TemplateStateFactory.forClass(spawnedContext, method.getDefiningClass()); spawnedContext.setClassState(templateClassState); MethodState templateMethodState = TemplateStateFactory.forMethod(spawnedContext); spawnedContext.setMethodState(templateMethodState); assertEquals(2, templateMethodState.getRegisterCount()); assertEquals(1, templateMethodState.getParameterCount()); int instanceRegister = templateMethodState.getParameterStart(); assertEquals(1, instanceRegister); HeapItem instanceItem = templateMethodState.peekRegister(instanceRegister); assertEquals(CLASS_NAME, instanceItem.getType()); assertEquals(UnknownValue.class, instanceItem.getValue().getClass()); }
HeapItem originalInstanceItem = callerMethodState.peekRegister(parameterRegisters[0]); HeapItem newInstanceItem = calleeContext.getMethodState().peekParameter(0); if (originalInstanceItem.getValue() != newInstanceItem.getValue()) {
@Test public void methodStateForObjectInitializationMethodCreatedCorrectly() throws VirtualMachineException { String methodDescriptor = "<init>()V"; VirtualMethod method = vm.getClassManager().getMethod(CLASS_NAME, methodDescriptor); ExecutionContext spawnedContext = new ExecutionContext(vm, method); ClassState templateClassState = TemplateStateFactory.forClass(spawnedContext, method.getDefiningClass()); spawnedContext.setClassState(templateClassState); MethodState templateMethodState = TemplateStateFactory.forMethod(spawnedContext); spawnedContext.setMethodState(templateMethodState); assertEquals(1, templateMethodState.getRegisterCount()); assertEquals(1, templateMethodState.getParameterCount()); int instanceRegister = templateMethodState.getParameterStart(); assertEquals(0, instanceRegister); HeapItem instanceItem = templateMethodState.peekRegister(instanceRegister); assertEquals(CLASS_NAME, instanceItem.getType()); assertEquals(UninitializedInstance.class, instanceItem.getValue().getClass()); }