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

The following examples show how to use org.objectweb.asm.commons.GeneratorAdapter#visitInsn() . 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: RobustAsmUtils.java    From Robust with Apache License 2.0 5 votes vote down vote up
private static void prepareMethodParameters(GeneratorAdapter mv, String className, List<Type> args, Type returnType, boolean isStatic, int methodId) {
    //第一个参数:new Object[]{...};,如果方法没有参数直接传入new Object[0]
    if (args.size() == 0) {
        mv.visitInsn(Opcodes.ICONST_0);
        mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object");
    } else {
        createObjectArray(mv, args, isStatic);
    }

    //第二个参数:this,如果方法是static的话就直接传入null
    if (isStatic) {
        mv.visitInsn(Opcodes.ACONST_NULL);
    } else {
        mv.visitVarInsn(Opcodes.ALOAD, 0);
    }

    //第三个参数:changeQuickRedirect
    mv.visitFieldInsn(Opcodes.GETSTATIC,
            className,
            REDIRECTFIELD_NAME,
            REDIRECTCLASSNAME);

    //第四个参数:false,标志是否为static
    mv.visitInsn(isStatic ? Opcodes.ICONST_1 : Opcodes.ICONST_0);
    //第五个参数:
    mv.push(methodId);
    //第六个参数:参数class数组
    createClassArray(mv, args);
    //第七个参数:返回值类型class
    createReturnClass(mv, returnType);
}
 
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 generateConstructor(ClassVisitor cv) {
    GeneratorAdapter mv = new GeneratorAdapter(ACC_PUBLIC, EMPTY_CONSTRUCTOR, null, null, cv);
    mv.visitCode();
    mv.loadThis();
    mv.invokeConstructor(TEST_THREAD_EXECUTION_TYPE, TEST_THREAD_EXECUTION_CONSTRUCTOR);
    mv.visitInsn(RETURN);
    mv.visitMaxs(1, 1);
    mv.visitEnd();
}
 
Example 3
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 4
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 5
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 6
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 7
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 8
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 9
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;
}