public int getParameterStart() { return getRegisterCount() - parameterSize; }
private int getRegisterCount(int address) { return getNodePile(address).get(0).getContext().getMethodState().getRegisterCount(); }
public String toString(boolean onlyPeekCachedRegisters) { StringBuilder sb = new StringBuilder(); int localsCount = getRegisterCount() - getParameterCount(); sb.append("params: ").append(parameterCount).append(", "); sb.append("locals: ").append(localsCount).append('\n'); StringBuilder ctx = new StringBuilder(); for (int register = 0; register < getRegisterCount(); register++) { if (onlyPeekCachedRegisters && !hasRegister(register)) { continue;
private boolean allArgumentsKnown(MethodState mState) { for (int parameterRegister = mState.getParameterStart(); parameterRegister < mState.getRegisterCount(); ) { HeapItem item = mState.peekParameter(parameterRegister); if (item.isUnknown()) { return false; } String type = item.getType(); parameterRegister += Utils.getRegisterSize(type); } return true; }
private InvocationArguments getArguments(MethodState mState) throws ClassNotFoundException { int paramOffset = 0; if (!method.isStatic()) { // First parameter in method state for non-static methods is the virtual instance for that method // It's not needed to reflect the actual JVM method paramOffset = 1; } List<String> parameterTypeNames = method.getParameterTypeNames(); int size = parameterTypeNames.size() - paramOffset; Object[] args = new Object[size]; Class<?>[] parameterTypes = new Class<?>[size]; int registerCount = mState.getRegisterCount(); for (int i = paramOffset; i < registerCount; ) { HeapItem argItem = mState.peekParameter(i); args[i - paramOffset] = argItem.getValue(); String parameterTypeName = parameterTypeNames.get(i); Class<?> parameterType; if (argItem.isPrimitive()) { parameterType = ClassNameUtils.getPrimitiveClass(parameterTypeName); } else { // Shouldn't need a VM class loader since these are all safe to reflect on the JVM // Also, some classes are arrays and loadClass only works for non-array, non-primitive types parameterType = Class.forName(ClassNameUtils.internalToBinary(parameterTypeName)); } parameterTypes[i - paramOffset] = parameterType; // Long tried every diet but is still fat and takes 2 registers. Could be thyroid. i += Utils.getRegisterSize(parameterTypeName); } return new InvocationArguments(args, parameterTypes); }
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 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()); }
@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()); }