List of usage examples for org.objectweb.asm.commons InstructionAdapter dup
public void dup()
From source file:com.gargoylesoftware.js.nashorn.internal.runtime.linker.JavaAdapterBytecodeGenerator.java
License:Open Source License
private void generateClassInit() { final InstructionAdapter mv = new InstructionAdapter( cw.visitMethod(ACC_STATIC, CLASS_INIT, Type.getMethodDescriptor(Type.VOID_TYPE), null, null)); mv.invokestatic(SERVICES_CLASS_TYPE_NAME, "getClassOverrides", GET_CLASS_INITIALIZER_DESCRIPTOR, false); final Label initGlobal; if (samName != null) { // If the class is a SAM, allow having a ScriptFunction passed as class overrides final Label notAFunction = new Label(); mv.dup(); mv.instanceOf(SCRIPT_FUNCTION_TYPE); mv.ifeq(notAFunction);/*from w ww . ja v a2 s . c om*/ mv.checkcast(SCRIPT_FUNCTION_TYPE); // Assign MethodHandle fields through invoking getHandle() for a ScriptFunction, only assigning the SAM // method(s). for (final MethodInfo mi : methodInfos) { if (mi.getName().equals(samName)) { mv.dup(); loadMethodTypeAndGetHandle(mv, mi, GET_HANDLE_FUNCTION_DESCRIPTOR); } else { mv.visitInsn(ACONST_NULL); } mv.putstatic(generatedClassName, mi.methodHandleFieldName, METHOD_HANDLE_TYPE_DESCRIPTOR); } initGlobal = new Label(); mv.goTo(initGlobal); mv.visitLabel(notAFunction); } else { initGlobal = null; } // Assign MethodHandle fields through invoking getHandle() for a ScriptObject for (final MethodInfo mi : methodInfos) { mv.dup(); mv.aconst(mi.getName()); loadMethodTypeAndGetHandle(mv, mi, GET_HANDLE_OBJECT_DESCRIPTOR); mv.putstatic(generatedClassName, mi.methodHandleFieldName, METHOD_HANDLE_TYPE_DESCRIPTOR); } if (initGlobal != null) { mv.visitLabel(initGlobal); } // Assign "global = Context.getGlobal()" invokeGetGlobalWithNullCheck(mv); mv.putstatic(generatedClassName, GLOBAL_FIELD_NAME, GLOBAL_TYPE_DESCRIPTOR); generateConverterInit(mv, false); endInitMethod(mv); }
From source file:com.gargoylesoftware.js.nashorn.internal.runtime.linker.JavaAdapterBytecodeGenerator.java
License:Open Source License
private static void invokeGetGlobalWithNullCheck(final InstructionAdapter mv) { invokeGetGlobal(mv);//from w w w. ja v a2s .c o m mv.dup(); mv.invokevirtual(OBJECT_TYPE_NAME, "getClass", GET_CLASS_METHOD_DESCRIPTOR, false); // check against null Context mv.pop(); }
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. *//*ww w. ja v a 2 s .c o m*/ 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());//from w w w . ja v a 2s . com builder.newarray(Type.getType(String.class)); for (int i = 0; i < stringList.size(); i++) { builder.dup(); 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());/*from ww w. j a va 2 s. c o m*/ insts.newarray(Type.INT_TYPE); int curIndex = 0; for (Integer value : values) { insts.dup(); 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:edu.ubc.mirrors.holograms.HologramMethodGenerator.java
License:Open Source License
public static void initializeStaticFields(Type owner, InstructionAdapter mv) { // Initialize the static field that holds the ClassMirror for this holographic Class mv.aconst(owner);/* ww w . j av a 2s .co m*/ new MethodHandle() { protected void methodCall() throws Throwable { ObjectHologram.getClassMirrorForHolographicClass(null); } }.invoke(mv); mv.dup(); mv.putstatic(owner.getInternalName(), "classMirror", classMirrorType.getDescriptor()); }
From source file:org.jetbrains.jet.codegen.intrinsics.Sure.java
License:Apache License
@Override public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver) { JetCallExpression call = (JetCallExpression) element; ResolvedCall<? extends CallableDescriptor> resolvedCall = codegen.getBindingContext() .get(BindingContext.RESOLVED_CALL, call.getCalleeExpression()); assert resolvedCall != null; if (resolvedCall.getReceiverArgument().getType().isNullable()) { receiver.put(receiver.type, v);/*from w w w . j a va 2 s.c o m*/ v.dup(); Label ok = new Label(); v.ifnonnull(ok); v.invokestatic("jet/runtime/Intrinsics", "throwNpe", "()V"); v.mark(ok); StackValue.onStack(receiver.type).put(expectedType, v); } else { codegen.generateFromResolvedCall(resolvedCall.getReceiverArgument(), expectedType); } return StackValue.onStack(expectedType); }