Java Code Examples for org.objectweb.asm.commons.GeneratorAdapter#dup()
The following examples show how to use
org.objectweb.asm.commons.GeneratorAdapter#dup() .
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: ByteCodeUtils.java From Stark with Apache License 2.0 | 7 votes |
/** * Given an array on the stack, it loads it with the values of the given variables stating at * offset. */ static void loadVariableArray( @NonNull GeneratorAdapter mv, @NonNull List<LocalVariable> variables, int offset) { // we need to maintain the stack index when loading parameters from, as for long and double // values, it uses 2 stack elements, all others use only 1 stack element. for (int i = offset; i < variables.size(); i++) { LocalVariable variable = variables.get(i); // duplicate the array of objects reference, it will be used to store the value in. mv.dup(); // index in the array of objects to store the boxed parameter. mv.push(i); // Pushes the appropriate local variable on the stack mv.visitVarInsn(variable.type.getOpcode(Opcodes.ILOAD), variable.var); // potentially box up intrinsic types. mv.box(variable.type); // store it in the array mv.arrayStore(Type.getType(Object.class)); } }
Example 2
Source File: ByteCodeUtils.java From Stark with Apache License 2.0 | 6 votes |
/** * Given an array with values at the top of the stack, the values are unboxed and stored * on the given variables. The array is popped from the stack. */ static void restoreVariables( @NonNull GeneratorAdapter mv, @NonNull List<LocalVariable> variables) { for (int i = 0; i < variables.size(); i++) { LocalVariable variable = variables.get(i); // Duplicates the array on the stack; mv.dup(); // Sets up the index mv.push(i); // Gets the Object value mv.arrayLoad(Type.getType(Object.class)); // Unboxes to the type of the local variable mv.unbox(variable.type); // Restores the local variable mv.visitVarInsn(variable.type.getOpcode(Opcodes.ISTORE), variable.var); } // Pops the array from the stack. mv.pop(); }
Example 3
Source File: AsmDeltaSpikeProxyClassGenerator.java From deltaspike with Apache License 2.0 | 6 votes |
/** * Defines a new Object[] and push all method argmuments into the array. * * @param mg * @param method * @param methodType */ private static void loadArguments(GeneratorAdapter mg, java.lang.reflect.Method method, Type methodType) { // create the Object[] mg.push(methodType.getArgumentTypes().length); mg.newArray(TYPE_OBJECT); // push parameters into array for (int i = 0; i < methodType.getArgumentTypes().length; i++) { // keep copy of array on stack mg.dup(); // push index onto stack mg.push(i); mg.loadArg(i); mg.valueOf(methodType.getArgumentTypes()[i]); mg.arrayStore(TYPE_OBJECT); } }
Example 4
Source File: AsmDeltaSpikeProxyClassGenerator.java From deltaspike with Apache License 2.0 | 6 votes |
/** * Generates: * <pre> * Method method = * method.getDeclaringClass().getMethod("methodName", new Class[] { args... }); * </pre> * @param mg * @param method * @param methodType */ private static void loadCurrentMethod(GeneratorAdapter mg, java.lang.reflect.Method method, Type methodType) { mg.push(Type.getType(method.getDeclaringClass())); mg.push(method.getName()); // create the Class[] mg.push(methodType.getArgumentTypes().length); mg.newArray(TYPE_CLASS); // push parameters into array for (int i = 0; i < methodType.getArgumentTypes().length; i++) { // keep copy of array on stack mg.dup(); // push index onto stack mg.push(i); mg.push(methodType.getArgumentTypes()[i]); mg.arrayStore(TYPE_CLASS); } // invoke getMethod() with the method name and the array of types mg.invokeVirtual(TYPE_CLASS, Method.getMethod("java.lang.reflect.Method getDeclaredMethod(String, Class[])")); }
Example 5
Source File: ByteCodeUtils.java From Aceso with Apache License 2.0 | 6 votes |
/** * Given an array on the stack, it loads it with the values of the given variables stating at * offset. */ static void loadVariableArray( GeneratorAdapter mv, List<LocalVariable> variables, int offset) { // we need to maintain the stack index when loading parameters from, as for long and double // values, it uses 2 stack elements, all others use only 1 stack element. for (int i = offset; i < variables.size(); i++) { LocalVariable variable = variables.get(i); // duplicate the array of objects reference, it will be used to store the value in. mv.dup(); // index in the array of objects to store the boxed parameter. mv.push(i); // Pushes the appropriate local variable on the stack mv.visitVarInsn(variable.type.getOpcode(Opcodes.ILOAD), variable.var); // potentially box up intrinsic types. mv.box(variable.type); // store it in the array mv.arrayStore(Type.getType(Object.class)); } }
Example 6
Source File: RobustAsmUtils.java From Robust with Apache License 2.0 | 6 votes |
private static void createClassArray(GeneratorAdapter mv, List<Type> args) { // create an array of objects capable of containing all the parameters and optionally the "this" createLocals(mv, args); // we need to maintain the stack index when loading parameters from, as for long and double // values, it uses 2 stack elements, all others use only 1 stack element. int stackIndex = 0; for (int arrayIndex = 0; arrayIndex < args.size(); arrayIndex++) { Type arg = args.get(arrayIndex); // duplicate the array of objects reference, it will be used to store the value in. mv.dup(); // index in the array of objects to store the boxed parameter. mv.push(arrayIndex); // Pushes the appropriate local variable on the stack redirectLocal(mv, arg); // mv.visitLdcInsn(Type.getType(arg.getDescriptor())); // potentially box up intrinsic types. // mv.box(arg); mv.arrayStore(Type.getType(Class.class)); // stack index must progress according to the parameter type we just processed. // stackIndex += arg.getSize(); } }
Example 7
Source File: IntSwitch.java From Aceso with Apache License 2.0 | 5 votes |
void writeMissingMessageWithHash(GeneratorAdapter mv, String visitedClassName) { mv.newInstance(INSTANT_RELOAD_EXCEPTION_TYPE); mv.dup(); mv.push("int switch could not find %d in %s"); mv.push(3); mv.newArray(OBJECT_TYPE); mv.dup(); mv.push(0); visitInt(); mv.visitMethodInsn( Opcodes.INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false); mv.arrayStore(OBJECT_TYPE); mv.dup(); mv.push(2); mv.push(visitedClassName); mv.arrayStore(OBJECT_TYPE); mv.visitMethodInsn( Opcodes.INVOKESTATIC, "java/lang/String", "format", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;", false); mv.invokeConstructor(INSTANT_RELOAD_EXCEPTION_TYPE, Method.getMethod("void <init> (String)")); mv.throwException(); }
Example 8
Source File: Redirection.java From AnoleFix with MIT License | 5 votes |
/** * Adds the instructions to do a generic redirection. * <p/> * Note that the generated bytecode does not have a direct translation to code, but as an * example, the following code block gets inserted. * <code> * if ($change != null) { * $change.access$dispatch($name, new object[] { arg0, ... argsN }) * $anyCodeInsertedbyRestore * } * $originalMethodBody * </code> * * @param mv the method visitor to add the instructions to. * @param change the local variable containing the alternate implementation. * @param args the type of the local variable that need to be forwarded. */ void redirect(GeneratorAdapter mv, int change, List<Type> args) { // code to check if a new implementation of the current class is available. Label l0 = new Label(); mv.loadLocal(change); mv.visitJumpInsn(Opcodes.IFNULL, l0); mv.loadLocal(change); mv.push(name); // create an array of objects capable of containing all the parameters and optionally the "this" createLocals(mv, args); // we need to maintain the stack index when loading parameters from, as for long and double // values, it uses 2 stack elements, all others use only 1 stack element. int stackIndex = 0; for (int arrayIndex = 0; arrayIndex < args.size(); arrayIndex++) { Type arg = args.get(arrayIndex); // duplicate the array of objects reference, it will be used to store the value in. mv.dup(); // index in the array of objects to store the boxed parameter. mv.push(arrayIndex); // Pushes the appropriate local variable on the stack redirectLocal(mv, stackIndex, arg); // potentially box up intrinsic types. mv.box(arg); mv.arrayStore(Type.getType(Object.class)); // stack index must progress according to the parameter type we just processed. stackIndex += arg.getSize(); } // now invoke the generic dispatch method. mv.invokeInterface(IncrementalVisitor.CHANGE_TYPE, Method.getMethod("Object access$dispatch(String, Object[])")); // Restore the state after the redirection restore(mv, args); // jump label for classes without any new implementation, just invoke the original // method implementation. mv.visitLabel(l0); }
Example 9
Source File: ConstructorArgsRedirection.java From AnoleFix with MIT License | 5 votes |
@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 10
Source File: StringSwitch.java From AnoleFix with MIT License | 5 votes |
/** * Generates a standard error exception with message similar to: * * String switch could not find 'equals.(Ljava/lang/Object;)Z' with hashcode 0 * in com/example/basic/GrandChild * * @param mv The generator adaptor used to emit the lookup switch code. * @param visitedClassName The abstract string trie structure. */ void writeMissingMessageWithHash(GeneratorAdapter mv, String visitedClassName) { mv.newInstance(INSTANT_RELOAD_EXCEPTION_TYPE); mv.dup(); mv.push("String switch could not find '%s' with hashcode %s in %s"); mv.push(3); mv.newArray(OBJECT_TYPE); mv.dup(); mv.push(0); visitString(); mv.arrayStore(OBJECT_TYPE); mv.dup(); mv.push(1); visitString(); visitHashMethod(mv); mv.visitMethodInsn( Opcodes.INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false); mv.arrayStore(OBJECT_TYPE); mv.dup(); mv.push(2); mv.push(visitedClassName); mv.arrayStore(OBJECT_TYPE); mv.visitMethodInsn( Opcodes.INVOKESTATIC, "java/lang/String", "format", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;", false); mv.invokeConstructor(INSTANT_RELOAD_EXCEPTION_TYPE, Method.getMethod("void <init> (String)")); mv.throwException(); }
Example 11
Source File: ExpressionThrow.java From datakernel with Apache License 2.0 | 5 votes |
@Override public Type load(Context ctx) { GeneratorAdapter g = ctx.getGeneratorAdapter(); g.newInstance(getType(exceptionClass)); g.dup(); if (message == null) { g.invokeConstructor(getType(exceptionClass), new Method("<init>", VOID_TYPE, new Type[]{})); } else { message.load(ctx); g.invokeConstructor(getType(exceptionClass), new Method("<init>", VOID_TYPE, new Type[]{getType(String.class)})); } g.throwException(); return VOID_TYPE; }
Example 12
Source File: StringSwitch.java From Stark with Apache License 2.0 | 5 votes |
/** * Generates a standard error exception with message similar to: * * String switch could not find 'equals.(Ljava/lang/Object;)Z' with hashcode 0 * in com/example/basic/GrandChild * * @param mv The generator adaptor used to emit the lookup switch code. * @param visitedClassName The abstract string trie structure. */ void writeMissingMessageWithHash(GeneratorAdapter mv, String visitedClassName) { mv.newInstance(STARK_RELOAD_EXCEPTION_TYPE); mv.dup(); mv.push("String switch could not find '%s' with hashcode %s in %s"); mv.push(3); mv.newArray(OBJECT_TYPE); mv.dup(); mv.push(0); visitString(); mv.arrayStore(OBJECT_TYPE); mv.dup(); mv.push(1); visitString(); visitHashMethod(mv); mv.visitMethodInsn( Opcodes.INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false); mv.arrayStore(OBJECT_TYPE); mv.dup(); mv.push(2); mv.push(visitedClassName); mv.arrayStore(OBJECT_TYPE); mv.visitMethodInsn( Opcodes.INVOKESTATIC, "java/lang/String", "format", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;", false); mv.invokeConstructor(STARK_RELOAD_EXCEPTION_TYPE, Method.getMethod("void <init> (String)")); mv.throwException(); }
Example 13
Source File: TBConstructorRedirection.java From atlas with Apache License 2.0 | 4 votes |
@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 14
Source File: ConstructorArgsRedirection.java From AnoleFix with MIT License | 4 votes |
@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 15
Source File: ExpressionComparator.java From datakernel with Apache License 2.0 | 4 votes |
@Override public Type load(Context ctx) { GeneratorAdapter g = ctx.getGeneratorAdapter(); Label labelReturn = new Label(); for (ComparablePair pair : pairs) { Type leftPropertyType = pair.left.load(ctx); Type rightPropertyType = pair.right.load(ctx); checkArgument(leftPropertyType.equals(rightPropertyType), "Types of compared values should match"); if (isPrimitiveType(leftPropertyType)) { g.invokeStatic(wrap(leftPropertyType), new Method("compare", INT_TYPE, new Type[]{leftPropertyType, leftPropertyType})); g.dup(); g.ifZCmp(NE, labelReturn); g.pop(); } else if (!pair.nullable) { g.invokeVirtual(leftPropertyType, new Method("compareTo", INT_TYPE, new Type[]{Type.getType(Object.class)})); g.dup(); g.ifZCmp(NE, labelReturn); g.pop(); } else { VarLocal varRight = ctx.newLocal(rightPropertyType); varRight.store(ctx); VarLocal varLeft = ctx.newLocal(leftPropertyType); varLeft.store(ctx); Label continueLabel = new Label(); Label nonNulls = new Label(); Label leftNonNull = new Label(); varLeft.load(ctx); g.ifNonNull(leftNonNull); varRight.load(ctx); g.ifNull(continueLabel); g.push(-1); g.returnValue(); g.mark(leftNonNull); varRight.load(ctx); g.ifNonNull(nonNulls); g.push(1); g.returnValue(); g.mark(nonNulls); varLeft.load(ctx); varRight.load(ctx); g.invokeVirtual(leftPropertyType, new Method("compareTo", INT_TYPE, new Type[]{Type.getType(Object.class)})); g.dup(); g.ifZCmp(NE, labelReturn); g.pop(); g.mark(continueLabel); } } g.push(0); g.mark(labelReturn); return INT_TYPE; }
Example 16
Source File: ExpressionToString.java From datakernel with Apache License 2.0 | 4 votes |
@Override public Type load(Context ctx) { GeneratorAdapter g = ctx.getGeneratorAdapter(); g.newInstance(getType(StringBuilder.class)); g.dup(); g.invokeConstructor(getType(StringBuilder.class), getMethod("void <init> ()")); boolean first = true; for (Object key : arguments.keySet()) { String str = first ? begin : separator; first = false; if (key instanceof String) { str += key; } if (!str.isEmpty()) { g.dup(); g.push(str); g.invokeVirtual(getType(StringBuilder.class), getMethod("StringBuilder append(String)")); g.pop(); } g.dup(); Expression expression = arguments.get(key); Type type = expression.load(ctx); if (isPrimitiveType(type)) { g.invokeStatic(wrap(type), new Method("toString", getType(String.class), new Type[]{type})); } else { Label nullLabel = new Label(); Label afterToString = new Label(); g.dup(); g.ifNull(nullLabel); g.invokeVirtual(type, getMethod("String toString()")); g.goTo(afterToString); g.mark(nullLabel); g.pop(); g.push("null"); g.mark(afterToString); } g.invokeVirtual(getType(StringBuilder.class), getMethod("StringBuilder append(String)")); g.pop(); } if (!end.isEmpty()) { g.dup(); g.push(end); g.invokeVirtual(getType(StringBuilder.class), getMethod("StringBuilder append(String)")); g.pop(); } g.invokeVirtual(getType(StringBuilder.class), getMethod("String toString()")); return getType(String.class); }
Example 17
Source File: AsmDeltaSpikeProxyClassGenerator.java From deltaspike with Apache License 2.0 | 4 votes |
private static void defineMethod(ClassWriter cw, java.lang.reflect.Method method, Type proxyType) { Type methodType = Type.getType(method); ArrayList<Type> exceptionsToCatch = new ArrayList<Type>(); for (Class<?> exception : method.getExceptionTypes()) { if (!RuntimeException.class.isAssignableFrom(exception)) { exceptionsToCatch.add(Type.getType(exception)); } } // push the method definition int modifiers = (Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED) & method.getModifiers(); Method asmMethod = Method.getMethod(method); GeneratorAdapter mg = new GeneratorAdapter(modifiers, asmMethod, null, getTypes(method.getExceptionTypes()), cw); // copy annotations for (Annotation annotation : method.getDeclaredAnnotations()) { mg.visitAnnotation(Type.getDescriptor(annotation.annotationType()), true).visitEnd(); } mg.visitCode(); Label tryBlockStart = mg.mark(); mg.loadThis(); mg.getField(proxyType, FIELDNAME_INVOCATION_HANDLER, TYPE_DELTA_SPIKE_PROXY_INVOCATION_HANDLER); mg.loadThis(); loadCurrentMethod(mg, method, methodType); loadArguments(mg, method, methodType); mg.invokeVirtual(TYPE_DELTA_SPIKE_PROXY_INVOCATION_HANDLER, Method.getMethod("Object invoke(Object, java.lang.reflect.Method, Object[])")); // cast the result mg.unbox(methodType.getReturnType()); // build try catch Label tryBlockEnd = mg.mark(); // push return mg.returnValue(); // catch runtime exceptions and rethrow it Label rethrow = mg.mark(); mg.visitVarInsn(Opcodes.ASTORE, 1); mg.visitVarInsn(Opcodes.ALOAD, 1); mg.throwException(); mg.visitTryCatchBlock(tryBlockStart, tryBlockEnd, rethrow, Type.getInternalName(RuntimeException.class)); // catch checked exceptions and rethrow it boolean throwableCatched = false; if (!exceptionsToCatch.isEmpty()) { rethrow = mg.mark(); mg.visitVarInsn(Opcodes.ASTORE, 1); mg.visitVarInsn(Opcodes.ALOAD, 1); mg.throwException(); // catch declared exceptions and rethrow it... for (Type exceptionType : exceptionsToCatch) { if (exceptionType.getClassName().equals(Throwable.class.getName())) { throwableCatched = true; } mg.visitTryCatchBlock(tryBlockStart, tryBlockEnd, rethrow, exceptionType.getInternalName()); } } // if throwable isn't alreached cachted, catch it and wrap it with an UndeclaredThrowableException and throw it if (!throwableCatched) { Type uteType = Type.getType(UndeclaredThrowableException.class); Label wrapAndRethrow = mg.mark(); mg.visitVarInsn(Opcodes.ASTORE, 1); mg.newInstance(uteType); mg.dup(); mg.visitVarInsn(Opcodes.ALOAD, 1); mg.invokeConstructor(uteType, Method.getMethod("void <init>(java.lang.Throwable)")); mg.throwException(); mg.visitTryCatchBlock(tryBlockStart, tryBlockEnd, wrapAndRethrow, Type.getInternalName(Throwable.class)); } // finish the method mg.endMethod(); mg.visitMaxs(12, 12); mg.visitEnd(); }
Example 18
Source File: ConstructorRedirection.java From Stark with Apache License 2.0 | 4 votes |
@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(); }