Java Code Examples for org.objectweb.asm.commons.GeneratorAdapter#newLocal()

The following examples show how to use org.objectweb.asm.commons.GeneratorAdapter#newLocal() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: ConstructorArgsRedirection.java    From AnoleFix with MIT License 5 votes vote down vote up
@Override
protected void createLocals(GeneratorAdapter mv, List<Type> args) {
    super.createLocals(mv, args);

    // Override the locals creation to keep a reference to it. We keep a reference to this
    // array because we use it to receive the values of the local variables after the
    // redirection is done.
    locals = mv.newLocal(Type.getType("[Ljava/lang/Object;"));
    mv.dup();
    mv.storeLocal(locals);
}
 
Example 2
Source File: TestThreadExecutionGenerator.java    From lin-check with GNU Lesser General Public License v3.0 5 votes vote down vote up
private static void storeExceptionResultFromThrowable(GeneratorAdapter mv, int resLocal, int iLocal) {
    int eLocal = mv.newLocal(THROWABLE_TYPE);
    mv.storeLocal(eLocal);
    mv.loadLocal(resLocal);
    mv.loadLocal(iLocal);
    mv.loadLocal(eLocal);
    mv.invokeVirtual(OBJECT_TYPE, OBJECT_GET_CLASS);
    mv.invokeStatic(RESULT_TYPE, RESULT_CREATE_EXCEPTION_RESULT);
    mv.arrayStore(RESULT_TYPE);
}
 
Example 3
Source File: TestThreadExecutionGenerator.java    From lin-check with GNU Lesser General Public License v3.0 5 votes vote down vote up
private static int createResultArray(GeneratorAdapter mv, int size) {
    int resLocal = mv.newLocal(RESULT_ARRAY_TYPE);
    mv.push(size);
    mv.newArray(RESULT_TYPE);
    mv.storeLocal(resLocal);
    return resLocal;
}
 
Example 4
Source File: ExpressionArithmeticOp.java    From datakernel with Apache License 2.0 5 votes vote down vote up
@Override
public Type load(Context ctx) {
	GeneratorAdapter g = ctx.getGeneratorAdapter();
	Type leftType = left.load(ctx);
	if (isWrapperType(leftType)) {
		leftType = unwrap(leftType);
		g.unbox(leftType);
	}
	Type rightType = right.load(ctx);
	if (isWrapperType(rightType)) {
		rightType = unwrap(rightType);
		g.unbox(rightType);
	}
	if (op != SHL && op != SHR && op != USHR) {
		Type resultType = getType(unifyArithmeticTypes(ctx.toJavaType(leftType), ctx.toJavaType(rightType)));
		if (leftType != resultType) {
			int rightLocal = g.newLocal(rightType);
			g.storeLocal(rightLocal);
			g.cast(leftType, resultType);
			g.loadLocal(rightLocal);
		}
		if (rightType != resultType) {
			g.cast(rightType, resultType);
		}
		g.visitInsn(resultType.getOpcode(op.opCode));
		return resultType;
	} else {
		if (rightType != Type.getType(int.class)) {
			g.cast(rightType, Type.getType(int.class));
		}
		g.visitInsn(leftType.getOpcode(op.opCode));
		return leftType;
	}
}
 
Example 5
Source File: ConstructorRedirection.java    From Stark with Apache License 2.0 4 votes vote down vote up
@Override
protected void doRedirect(GeneratorAdapter mv, int change) {
    mv.loadLocal(change);
    mv.push("init$args." + constructor.args.desc);

    Type arrayType = Type.getType("[Ljava/lang/Object;");
    // init$args args (including this) + locals
    mv.push(types.size() + 1);
    mv.newArray(Type.getType(Object.class));

    int array = mv.newLocal(arrayType);
    mv.dup();
    mv.storeLocal(array);

    // "this" is not ready yet, use null instead.
    mv.dup();
    mv.push(0);
    mv.visitInsn(Opcodes.ACONST_NULL);
    mv.arrayStore(Type.getType(Object.class));

    // Set the arguments in positions 1..(n-1);
    ByteCodeUtils.loadVariableArray(mv, ByteCodeUtils.toLocalVariables(types), 1); // Skip the this value

    // Add the locals array at the last position.
    mv.dup();
    // The index of the last position of the array.
    mv.push(types.size());
    // Create the array with all the local variables declared up to this point.
    ByteCodeUtils.newVariableArray(mv, constructor.variables.subList(0, constructor.localsAtLoadThis));
    mv.arrayStore(Type.getType(Object.class));

    mv.invokeInterface(MonitorVisitor.CHANGE_TYPE, Method.getMethod("Object access$dispatch(String, Object[])"));
    mv.visitTypeInsn(Opcodes.CHECKCAST, "[Ljava/lang/Object;");
    //// At this point, init$args has been called and the result Object is on the stack.
    //// The value of that Object is Object[] with exactly n + 2 elements.
    //// The first element is the resulting local variables
    //// The second element is a string with the qualified name of the constructor to call.
    //// The remaining elements are the constructor arguments.

    // Keep a reference to the new locals array
    mv.dup();
    mv.push(0);
    mv.arrayLoad(Type.getType("[Ljava/lang/Object;"));
    mv.visitTypeInsn(Opcodes.CHECKCAST, "[Ljava/lang/Object;");
    mv.storeLocal(array);

    // Call super constructor
    // Put this behind the returned array
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.swap();
    // Push a null for the marker parameter.
    mv.visitInsn(Opcodes.ACONST_NULL);
    // Invoke the constructor
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, constructor.owner, "<init>", DISPATCHING_THIS_SIGNATURE, false);

    // Dispatch to init$body
    mv.loadLocal(change);
    mv.push("init$body." + constructor.body.desc);
    mv.loadLocal(array);

    // Now "this" can be set
    mv.dup();
    mv.push(0);
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.arrayStore(Type.getType(Object.class));

    mv.invokeInterface(MonitorVisitor.CHANGE_TYPE, Method.getMethod("Object access$dispatch(String, Object[])"));
    mv.pop();
}
 
Example 6
Source File: TBConstructorRedirection.java    From atlas with Apache License 2.0 4 votes vote down vote up
@Override
protected void doRedirect(GeneratorAdapter mv, int change) {
    mv.loadLocal(change);
    mv.push("init$args." + constructor.args.desc);

    Type arrayType = Type.getType("[Ljava/lang/Object;");
    // init$args args (including this) + locals
    mv.push(types.size() + 1);
    mv.newArray(Type.getType(Object.class));

    int array = mv.newLocal(arrayType);
    mv.dup();
    mv.storeLocal(array);

    // "this" is not ready yet, use null instead.
    mv.dup();
    mv.push(0);
    mv.visitInsn(Opcodes.ACONST_NULL);
    mv.arrayStore(Type.getType(Object.class));

    // Set the arguments in positions 1..(n-1);
    ByteCodeUtils.loadVariableArray(mv, ByteCodeUtils.toLocalVariables(types), 1); // Skip the this value

    // Add the locals array at the last position.
    mv.dup();
    // The index of the last position of the array.
    mv.push(types.size());
    // Create the array with all the local variables declared up to this point.
    ByteCodeUtils.newVariableArray(mv, constructor.variables.subList(0, constructor.localsAtLoadThis));
    mv.arrayStore(Type.getType(Object.class));

    mv.invokeInterface(TBIncrementalVisitor.ALI_CHANGE_TYPE, Method.getMethod("Object ipc$dispatch(String, Object[])"));
    mv.visitTypeInsn(Opcodes.CHECKCAST, "[Ljava/lang/Object;");
    //// At this point, init$args has been called and the result Object is on the stack.
    //// The value of that Object is Object[] with exactly n + 2 elements.
    //// The first element is the resulting local variables
    //// The second element is a string with the qualified name of the constructor to call.
    //// The remaining elements are the constructor arguments.

    // Keep a reference to the new locals array
    mv.dup();
    mv.push(0);
    mv.arrayLoad(Type.getType("[Ljava/lang/Object;"));
    mv.visitTypeInsn(Opcodes.CHECKCAST, "[Ljava/lang/Object;");
    mv.storeLocal(array);

    // Call super constructor
    // Put this behind the returned array
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.swap();
    // Push a null for the marker parameter.
    mv.visitInsn(Opcodes.ACONST_NULL);
    // Invoke the constructor
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, constructor.owner, "<init>", DISPATCHING_THIS_SIGNATURE, false);

    // Dispatch to init$body
    mv.loadLocal(change);
    mv.push("init$body." + constructor.body.desc);
    mv.loadLocal(array);

    // Now "this" can be set
    mv.dup();
    mv.push(0);
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.arrayStore(Type.getType(Object.class));

    mv.invokeInterface(TBIncrementalVisitor.ALI_CHANGE_TYPE, Method.getMethod("Object ipc$dispatch(String, Object[])"));
    mv.pop();
}
 
Example 7
Source File: RobustAsmUtils.java    From Robust with Apache License 2.0 4 votes vote down vote up
/**
 * 插入代码
 *
 * @param mv
 * @param className
 * @param args
 * @param returnType
 * @param isStatic
 */
public static void createInsertCode(GeneratorAdapter mv, String className, List<Type> args, Type returnType, boolean isStatic, int methodId) {
    prepareMethodParameters(mv, className, args, returnType, isStatic, methodId);
    //开始调用
    mv.visitMethodInsn(Opcodes.INVOKESTATIC,
            PROXYCLASSNAME,
            "proxy",
            "([Ljava/lang/Object;Ljava/lang/Object;" + REDIRECTCLASSNAME + "ZI[Ljava/lang/Class;Ljava/lang/Class;)Lcom/meituan/robust/PatchProxyResult;",
            false);

    int local = mv.newLocal(Type.getType("Lcom/meituan/robust/PatchProxyResult;"));
    mv.storeLocal(local);
    mv.loadLocal(local);

    mv.visitFieldInsn(Opcodes.GETFIELD, "com/meituan/robust/PatchProxyResult", "isSupported", "Z");

    // if isSupported
    Label l1 = new Label();
    mv.visitJumpInsn(Opcodes.IFEQ, l1);

    //判断是否有返回值,代码不同
    if ("V".equals(returnType.getDescriptor())) {
        mv.visitInsn(Opcodes.RETURN);
    } else {
        mv.loadLocal(local);
        mv.visitFieldInsn(Opcodes.GETFIELD, "com/meituan/robust/PatchProxyResult", "result", "Ljava/lang/Object;");
        //强制转化类型
        if (!castPrimateToObj(mv, returnType.getDescriptor())) {
            //这里需要注意,如果是数组类型的直接使用即可,如果非数组类型,就得去除前缀了,还有最终是没有结束符;
            //比如:Ljava/lang/String; ==》 java/lang/String
            String newTypeStr = null;
            int len = returnType.getDescriptor().length();
            if (returnType.getDescriptor().startsWith("[")) {
                newTypeStr = returnType.getDescriptor().substring(0, len);
            } else {
                newTypeStr = returnType.getDescriptor().substring(1, len - 1);
            }
            mv.visitTypeInsn(Opcodes.CHECKCAST, newTypeStr);
        }

        //这里还需要做返回类型不同返回指令也不同
        mv.visitInsn(getReturnTypeCode(returnType.getDescriptor()));
    }

    mv.visitLabel(l1);
}
 
Example 8
Source File: ConstructorArgsRedirection.java    From AnoleFix with MIT License 4 votes vote down vote up
@Override
protected void restore(GeneratorAdapter mv, List<Type> args) {
    // At this point, init$args has been called and the result Object is on the stack.
    // The value of that Object is Object[] with exactly n + 1 elements.
    // The first element is a string with the qualified name of the constructor to call.
    // The remaining elements are the constructtor arguments.

    // Create a new local that holds the result of init$args call.
    mv.visitTypeInsn(Opcodes.CHECKCAST, "[Ljava/lang/Object;");
    int constructorArgs = mv.newLocal(Type.getType("[Ljava/lang/Object;"));
    mv.storeLocal(constructorArgs);

    // Reinstate local values
    mv.loadLocal(locals);
    int stackIndex = 0;
    for (int arrayIndex = 0; arrayIndex < args.size(); arrayIndex++) {
        Type arg = args.get(arrayIndex);
        // Do not restore "this"
        if (arrayIndex > 0) {
            // duplicates the array
            mv.dup();
            // index in the array of objects to restore the boxed parameter.
            mv.push(arrayIndex);
            // get it from the array
            mv.arrayLoad(Type.getType(Object.class));
            // unbox the argument
            ByteCodeUtils.unbox(mv, arg);
            // restore the argument
            mv.visitVarInsn(arg.getOpcode(Opcodes.ISTORE), stackIndex);
        }
        // stack index must progress according to the parameter type we just processed.
        stackIndex += arg.getSize();
    }
    // pops the array
    mv.pop();

    // Push a null for the marker parameter.
    mv.loadLocal(constructorArgs);
    mv.visitInsn(Opcodes.ACONST_NULL);

    // Invoke the constructor
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, thisClassName, "<init>", DISPATCHING_THIS_SIGNATURE, false);

    mv.goTo(end.getLabel());
}
 
Example 9
Source File: IncrementalSupportVisitor.java    From AnoleFix with MIT License 4 votes vote down vote up
/***
 * Inserts a trampoline to this class so that the updated methods can make calls to
 * constructors.
 * <p>
 * <p/>
 * Pseudo code for this trampoline:
 * <code>
 * ClassName(Object[] args, Marker unused) {
 * String name = (String) args[0];
 * if (name.equals(
 * "java/lang/ClassName.(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;")) {
 * this((String)arg[1], arg[2]);
 * return
 * }
 * if (name.equals("SuperClassName.(Ljava/lang/String;I)V")) {
 * super((String)arg[1], (int)arg[2]);
 * return;
 * }
 * ...
 * StringBuilder $local1 = new StringBuilder();
 * $local1.append("Method not found ");
 * $local1.append(name);
 * $local1.append(" in " $classType $super implementation");
 * throw new $package/InstantReloadException($local1.toString());
 * }
 * </code>
 */
private void createDispatchingThis() {
    // Gather all methods from itself and its superclasses to generate a giant constructor
    // implementation.
    // This will work fine as long as we don't support adding constructors to classes.
    final Map<String, MethodNode> uniqueMethods = new HashMap<String, MethodNode>();

    addAllNewConstructors(uniqueMethods, classNode, true /*keepPrivateConstructors*/);
    for (ClassNode parentNode : parentNodes) {
        addAllNewConstructors(uniqueMethods, parentNode, false /*keepPrivateConstructors*/);
    }

    int access = Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC;

    Method m = new Method(AsmUtils.CONSTRUCTOR,
            ConstructorArgsRedirection.DISPATCHING_THIS_SIGNATURE);
    MethodVisitor visitor = super.visitMethod(0, m.getName(), m.getDescriptor(), null, null);
    final GeneratorAdapter mv = new GeneratorAdapter(access, m, visitor);

    mv.visitCode();
    // Mark this code as redirection code
    Label label = new Label();
    mv.visitLineNumber(0, label);

    // Get and store the constructor canonical name.
    mv.visitVarInsn(Opcodes.ALOAD, 1);
    mv.push(0);
    mv.visitInsn(Opcodes.AALOAD);
    mv.unbox(Type.getType("Ljava/lang/String;"));
    final int constructorCanonicalName = mv.newLocal(Type.getType("Ljava/lang/String;"));
    mv.storeLocal(constructorCanonicalName);

    new StringSwitch() {

        @Override
        void visitString() {
            mv.loadLocal(constructorCanonicalName);
        }

        @Override
        void visitCase(String canonicalName) {
            MethodNode methodNode = uniqueMethods.get(canonicalName);
            String owner = canonicalName.split("\\.")[0];

            // Parse method arguments and
            mv.visitVarInsn(Opcodes.ALOAD, 0);
            Type[] args = Type.getArgumentTypes(methodNode.desc);
            int argc = 0;
            for (Type t : args) {
                mv.visitVarInsn(Opcodes.ALOAD, 1);
                mv.push(argc + 1);
                mv.visitInsn(Opcodes.AALOAD);
                ByteCodeUtils.unbox(mv, t);
                argc++;
            }

            mv.visitMethodInsn(Opcodes.INVOKESPECIAL, owner, AsmUtils.CONSTRUCTOR,
                    methodNode.desc, false);

            mv.visitInsn(Opcodes.RETURN);
        }

        @Override
        void visitDefault() {
            writeMissingMessageWithHash(mv, visitedClassName);
        }
    }.visit(mv, uniqueMethods.keySet());

    mv.visitMaxs(1, 3);
    mv.visitEnd();
}
 
Example 10
Source File: TestThreadExecutionGenerator.java    From lin-check with GNU Lesser General Public License v3.0 4 votes vote down vote up
private static void generateRun(ClassVisitor cv, Type testType, int iThread, List<Actor> actors, List<Object> objArgs, boolean waitsEnabled) {
    int access = ACC_PUBLIC;
    Method m = new Method("call", RESULT_ARRAY_TYPE, NO_ARGS);
    GeneratorAdapter mv = new GeneratorAdapter(access, m,
        // Try-catch blocks sorting is required
        new TryCatchBlockSorter(cv.visitMethod(access, m.getName(), m.getDescriptor(), null, null),
            access, m.getName(), m.getDescriptor(), null, null)
    );
    mv.visitCode();
    // Create Result[] array and store it to a local variable
    int resLocal = createResultArray(mv, actors.size());
    // Call runner's onStart(iThread) method
    mv.loadThis();
    mv.getField(TEST_THREAD_EXECUTION_TYPE, "runner", RUNNER_TYPE);
    mv.push(iThread);
    mv.invokeVirtual(RUNNER_TYPE, RUNNER_ON_START_METHOD);
    // Number of current operation (starts with 0)
    int iLocal = mv.newLocal(Type.INT_TYPE);
    mv.push(0);
    mv.storeLocal(iLocal);
    // Invoke actors
    for (int i = 0; i < actors.size(); i++) {
        Actor actor = actors.get(i);
        // Add busy-wait before operation execution (for non-first operations only)
        if (waitsEnabled && i > 0) {
            mv.loadThis();
            mv.getField(TEST_THREAD_EXECUTION_TYPE, "waits", INT_ARRAY_TYPE);
            mv.push(i - 1);
            mv.arrayLoad(Type.INT_TYPE);
            mv.invokeStatic(UTILS_TYPE, UTILS_CONSUME_CPU);
        }
        // Start of try-catch block for exceptions which this actor should handle
        Label start, end = null, handler = null, handlerEnd = null;
        if (actor.handlesExceptions()) {
            start = mv.newLabel();
            end = mv.newLabel();
            handler = mv.newLabel();
            handlerEnd = mv.newLabel();
            for (Class<? extends Throwable> ec : actor.handledExceptions)
                mv.visitTryCatchBlock(start, end, handler, Type.getType(ec).getInternalName());
            mv.visitLabel(start);
        }
        // Load result array and index to store the current result
        mv.loadLocal(resLocal);
        mv.push(i);
        // Load test instance
        mv.loadThis();
        mv.getField(TEST_THREAD_EXECUTION_TYPE, "testInstance", OBJECT_TYPE);
        mv.checkCast(testType);
        // Load arguments for operation
        for (int j = 0; j < actor.arguments.length; j++) {
            pushArgumentOnStack(mv, objArgs, actor.arguments[j], actor.method.getParameterTypes()[j]);
        }
        // Invoke operation
        Method actorMethod = Method.getMethod(actor.method);
        mv.invokeVirtual(testType, actorMethod);
        // Create result
        mv.box(actorMethod.getReturnType()); // box if needed
        if (actor.method.getReturnType() == void.class) {
            mv.pop();
            mv.invokeStatic(RESULT_TYPE, RESULT_CREATE_VOID_RESULT);
        } else {
            mv.invokeStatic(RESULT_TYPE, RESULT_CREATE_VALUE_RESULT);
        }
        // Store result to array
        mv.arrayStore(RESULT_TYPE);
        // End of try-catch block
        if (actor.handlesExceptions()) {
            mv.visitLabel(end);
            mv.goTo(handlerEnd);
            mv.visitLabel(handler);
            storeExceptionResultFromThrowable(mv, resLocal, iLocal);
            mv.visitLabel(handlerEnd);
        }
        // Increment number of current operation
        mv.iinc(iLocal, 1);
    }
    // Call runner's onFinish(iThread) method
    mv.loadThis();
    mv.getField(TEST_THREAD_EXECUTION_TYPE, "runner", RUNNER_TYPE);
    mv.push(iThread);
    mv.invokeVirtual(RUNNER_TYPE, RUNNER_ON_FINISH_METHOD);
    // Return results
    mv.loadThis();
    mv.loadLocal(resLocal);
    mv.returnValue();
    mv.visitMaxs(1, 1);
    mv.visitEnd();
}
 
Example 11
Source File: ExpressionHash.java    From datakernel with Apache License 2.0 4 votes vote down vote up
@Override
public Type load(Context ctx) {
	GeneratorAdapter g = ctx.getGeneratorAdapter();

	int resultVar = g.newLocal(INT_TYPE);

	boolean firstIteration = true;

	for (Expression argument : arguments) {
		if (firstIteration) {
			g.push(0);
			firstIteration = false;
		} else {
			g.push(31);
			g.loadLocal(resultVar);
			g.math(IMUL, INT_TYPE);
		}

		Type fieldType = argument.load(ctx);

		if (isPrimitiveType(fieldType)) {
			if (fieldType.getSort() == Type.LONG) {
				g.dup2();
				g.push(32);
				g.visitInsn(LUSHR);
				g.visitInsn(LXOR);
				g.visitInsn(L2I);
			}
			if (fieldType.getSort() == Type.FLOAT) {
				g.invokeStatic(getType(Float.class), getMethod("int floatToRawIntBits (float)"));
			}
			if (fieldType.getSort() == Type.DOUBLE) {
				g.invokeStatic(getType(Double.class), getMethod("long doubleToRawLongBits (double)"));
				g.dup2();
				g.push(32);
				g.visitInsn(LUSHR);
				g.visitInsn(LXOR);
				g.visitInsn(L2I);
			}
			g.visitInsn(IADD);
		} else {
			int tmpVar = g.newLocal(fieldType);
			g.storeLocal(tmpVar);
			g.loadLocal(tmpVar);
			Label ifNullLabel = g.newLabel();
			g.ifNull(ifNullLabel);
			g.loadLocal(tmpVar);
			g.invokeVirtual(fieldType, getMethod("int hashCode()"));
			g.visitInsn(IADD);
			g.mark(ifNullLabel);
		}

		g.storeLocal(resultVar);
	}

	if (firstIteration) {
		g.push(0);
	} else {
		g.loadLocal(resultVar);
	}

	return INT_TYPE;
}