List of usage examples for org.objectweb.asm.commons InstructionAdapter iconst
public void iconst(final int intValue)
From source file:com.gargoylesoftware.js.nashorn.internal.runtime.linker.JavaAdapterBytecodeGenerator.java
License:Open Source License
/** * Generates a method in the adapter class that adapts a method from the original class. The generated methods will * inspect the method handle field assigned to them. If it is null (the JS object doesn't provide an implementation * for the method) then it will either invoke its version in the supertype, or if it is abstract, throw an * {@link UnsupportedOperationException}. Otherwise, if the method handle field's value is not null, the handle is * invoked using invokeExact (signature polymorphic invocation as per JLS 15.12.3). Before the invocation, the * current Nashorn {@link Context} is checked, and if it is different than the global used to create the adapter * instance, the creating global is set to be the current global. In this case, the previously current global is * restored after the invocation. If invokeExact results in a Throwable that is not one of the method's declared * exceptions, and is not an unchecked throwable, then it is wrapped into a {@link RuntimeException} and the runtime * exception is thrown. The method handle retrieved from the field is guaranteed to exactly match the signature of * the method; this is guaranteed by the way constructors of the adapter class obtain them using * {@link #getHandle(Object, String, MethodType, boolean)}. * @param mi the method info describing the method to be generated. *//*w w w . java 2 s.c om*/ private void generateMethod(final MethodInfo mi) { final Method method = mi.method; final Class<?>[] exceptions = method.getExceptionTypes(); final String[] exceptionNames = getExceptionNames(exceptions); final MethodType type = mi.type; final String methodDesc = type.toMethodDescriptorString(); final String name = mi.getName(); final Type asmType = Type.getMethodType(methodDesc); final Type[] asmArgTypes = asmType.getArgumentTypes(); final InstructionAdapter mv = new InstructionAdapter( cw.visitMethod(getAccessModifiers(method), name, methodDesc, null, exceptionNames)); mv.visitCode(); final Label handleDefined = new Label(); final Class<?> returnType = type.returnType(); final Type asmReturnType = Type.getType(returnType); // See if we have overriding method handle defined if (classOverride) { mv.getstatic(generatedClassName, mi.methodHandleFieldName, METHOD_HANDLE_TYPE_DESCRIPTOR); } else { mv.visitVarInsn(ALOAD, 0); mv.getfield(generatedClassName, mi.methodHandleFieldName, METHOD_HANDLE_TYPE_DESCRIPTOR); } // stack: [handle] mv.visitInsn(DUP); mv.visitJumpInsn(IFNONNULL, handleDefined); // No handle is available, fall back to default behavior if (Modifier.isAbstract(method.getModifiers())) { // If the super method is abstract, throw an exception mv.anew(UNSUPPORTED_OPERATION_TYPE); mv.dup(); mv.invokespecial(UNSUPPORTED_OPERATION_TYPE_NAME, INIT, VOID_NOARG_METHOD_DESCRIPTOR, false); mv.athrow(); } else { mv.visitInsn(POP); // If the super method is not abstract, delegate to it. emitSuperCall(mv, method.getDeclaringClass(), name, methodDesc); } mv.visitLabel(handleDefined); // Load the creatingGlobal object if (classOverride) { // If class handle is defined, load the static defining global mv.getstatic(generatedClassName, GLOBAL_FIELD_NAME, GLOBAL_TYPE_DESCRIPTOR); } else { mv.visitVarInsn(ALOAD, 0); mv.getfield(generatedClassName, GLOBAL_FIELD_NAME, GLOBAL_TYPE_DESCRIPTOR); } // stack: [creatingGlobal, handle] final Label setupGlobal = new Label(); mv.visitLabel(setupGlobal); // Determine the first index for a local variable int nextLocalVar = 1; // "this" is at 0 for (final Type t : asmArgTypes) { nextLocalVar += t.getSize(); } // Set our local variable indices final int currentGlobalVar = nextLocalVar++; final int globalsDifferVar = nextLocalVar++; mv.dup(); // stack: [creatingGlobal, creatingGlobal, handle] // Emit code for switching to the creating global // Global currentGlobal = Context.getGlobal(); invokeGetGlobal(mv); mv.dup(); mv.visitVarInsn(ASTORE, currentGlobalVar); // stack: [currentGlobal, creatingGlobal, creatingGlobal, handle] // if(definingGlobal == currentGlobal) { final Label globalsDiffer = new Label(); mv.ifacmpne(globalsDiffer); // stack: [creatingGlobal, handle] // globalsDiffer = false mv.pop(); // stack: [handle] mv.iconst(0); // false // stack: [false, handle] final Label invokeHandle = new Label(); mv.goTo(invokeHandle); mv.visitLabel(globalsDiffer); // } else { // Context.setGlobal(definingGlobal); // stack: [creatingGlobal, handle] invokeSetGlobal(mv); // stack: [handle] // globalsDiffer = true mv.iconst(1); // stack: [true, handle] mv.visitLabel(invokeHandle); mv.visitVarInsn(ISTORE, globalsDifferVar); // stack: [handle] // Load all parameters back on stack for dynamic invocation. NOTE: since we're using a generic // Object(Object, Object, ...) type signature for the method, we must box all arguments here. int varOffset = 1; for (final Type t : asmArgTypes) { mv.load(varOffset, t); boxStackTop(mv, t); varOffset += t.getSize(); } // Invoke the target method handle final Label tryBlockStart = new Label(); mv.visitLabel(tryBlockStart); emitInvokeExact(mv, type.generic()); convertReturnValue(mv, returnType, asmReturnType); final Label tryBlockEnd = new Label(); mv.visitLabel(tryBlockEnd); emitFinally(mv, currentGlobalVar, globalsDifferVar); mv.areturn(asmReturnType); // If Throwable is not declared, we need an adapter from Throwable to RuntimeException final boolean throwableDeclared = isThrowableDeclared(exceptions); final Label throwableHandler; if (!throwableDeclared) { // Add "throw new RuntimeException(Throwable)" handler for Throwable throwableHandler = new Label(); mv.visitLabel(throwableHandler); mv.anew(RUNTIME_EXCEPTION_TYPE); mv.dupX1(); mv.swap(); mv.invokespecial(RUNTIME_EXCEPTION_TYPE_NAME, INIT, Type.getMethodDescriptor(Type.VOID_TYPE, THROWABLE_TYPE), false); // Fall through to rethrow handler } else { throwableHandler = null; } final Label rethrowHandler = new Label(); mv.visitLabel(rethrowHandler); // Rethrow handler for RuntimeException, Error, and all declared exception types emitFinally(mv, currentGlobalVar, globalsDifferVar); mv.athrow(); final Label methodEnd = new Label(); mv.visitLabel(methodEnd); mv.visitLocalVariable("currentGlobal", GLOBAL_TYPE_DESCRIPTOR, null, setupGlobal, methodEnd, currentGlobalVar); mv.visitLocalVariable("globalsDiffer", Type.BOOLEAN_TYPE.getDescriptor(), null, setupGlobal, methodEnd, globalsDifferVar); if (throwableDeclared) { mv.visitTryCatchBlock(tryBlockStart, tryBlockEnd, rethrowHandler, THROWABLE_TYPE_NAME); assert throwableHandler == null; } else { mv.visitTryCatchBlock(tryBlockStart, tryBlockEnd, rethrowHandler, RUNTIME_EXCEPTION_TYPE_NAME); mv.visitTryCatchBlock(tryBlockStart, tryBlockEnd, rethrowHandler, ERROR_TYPE_NAME); for (final String excName : exceptionNames) { mv.visitTryCatchBlock(tryBlockStart, tryBlockEnd, rethrowHandler, excName); } mv.visitTryCatchBlock(tryBlockStart, tryBlockEnd, throwableHandler, THROWABLE_TYPE_NAME); } endMethod(mv); }
From source file:com.github.jasmo.obfuscate.ScrambleStrings.java
License:Open Source License
private void createStaticConstructor(ClassNode owner) throws UnsupportedEncodingException { MethodNode original = BytecodeHelper.getMethod(owner, "<clinit>", "()V"); MethodVisitor mv = owner.visitMethod(Opcodes.ACC_STATIC, "<clinit>", "()V", null, null); // generate instructions InstructionAdapter builder = new InstructionAdapter(mv); builder.iconst(stringList.size()); builder.newarray(Type.getType(String.class)); for (int i = 0; i < stringList.size(); i++) { builder.dup();// w w w .jav a 2 s.co m builder.iconst(i); builder.aconst(Base64.getEncoder().encodeToString(stringList.get(i).getBytes("UTF-8"))); builder.astore(InstructionAdapter.OBJECT_TYPE); } builder.putstatic(unscrambleClass.name, FIELD_NAME, "[Ljava/lang/String;"); // merge with original if it exists if (original != null) { // original should already end with RETURN owner.methods.remove(original); original.instructions.accept(builder); } else { builder.areturn(Type.VOID_TYPE); } }
From source file:com.google.devtools.build.android.resources.IntArrayFieldInitializer.java
License:Open Source License
@Override public int writeCLInit(InstructionAdapter insts, String className) { insts.iconst(values.size()); insts.newarray(Type.INT_TYPE); int curIndex = 0; for (Integer value : values) { insts.dup();// www.j a v a2 s. c o m insts.iconst(curIndex); insts.iconst(value); insts.astore(Type.INT_TYPE); ++curIndex; } insts.putstatic(className, fieldName, DESC); // Needs up to 4 stack slots for: the array ref for the putstatic, the dup of the array ref // for the store, the index, and the value to store. return 4; }
From source file:com.google.devtools.build.android.resources.IntFieldInitializer.java
License:Open Source License
@Override public int writeCLInit(InstructionAdapter insts, String className) { insts.iconst(value); insts.putstatic(className, fieldName, DESC); // Just needs one stack slot for the iconst. return 1;// www .ja v a2 s. com }