Example usage for org.objectweb.asm Label Label

List of usage examples for org.objectweb.asm Label Label

Introduction

In this page you can find the example usage for org.objectweb.asm Label Label.

Prototype

public Label() 

Source Link

Document

Constructs a new label.

Usage

From source file:com.facebook.presto.bytecode.instruction.LabelNode.java

License:Apache License

public LabelNode(String name) {
    this.label = new Label();
    this.name = name + "@" + label.hashCode();
}

From source file:com.facebook.swift.codec.internal.compiler.byteCode.MethodDefinition.java

License:Apache License

private LabelNode getLabel(String name) {
    Label label = labels.get(name);
    if (label == null) {
        label = new Label();
        labels.put(name, label);/*from   w w  w .j av a2  s. com*/
    }
    return new LabelNode(label);
}

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();/*from  ww  w .j av a 2 s .c  o m*/
        mv.instanceOf(SCRIPT_FUNCTION_TYPE);
        mv.ifeq(notAFunction);
        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

/**
 * 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.
 *///from   w w w.ja  va 2s .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.gargoylesoftware.js.nashorn.internal.runtime.linker.JavaAdapterBytecodeGenerator.java

License:Open Source License

/**
 * Emit code to restore the previous Nashorn Context when needed.
 * @param mv the instruction adapter/*from   ww  w.  j a v a2  s  .c om*/
 * @param currentGlobalVar index of the local variable holding the reference to the current global at method
 * entry.
 * @param globalsDifferVar index of the boolean local variable that is true if the global needs to be restored.
 */
private static void emitFinally(final InstructionAdapter mv, final int currentGlobalVar,
        final int globalsDifferVar) {
    // Emit code to restore the previous Nashorn global if needed
    mv.visitVarInsn(ILOAD, globalsDifferVar);
    final Label skip = new Label();
    mv.ifeq(skip);
    mv.visitVarInsn(ALOAD, currentGlobalVar);
    invokeSetGlobal(mv);
    mv.visitLabel(skip);
}

From source file:com.github.anba.es6draft.compiler.assembler.InstructionAssembler.java

License:Open Source License

public void lineInfo(int line) {
    if (lastLineNumber == line) {
        // omit duplicate line info entries
        return;/*from  ww w  .  j  a  v a 2  s .c o m*/
    }
    lastLineNumber = line;
    Label label = new Label();
    methodVisitor.visitLabel(label);
    methodVisitor.visitLineNumber(line, label);
}

From source file:com.github.anba.es6draft.compiler.assembler.Jump.java

License:Open Source License

public Jump() {
    this.label = new Label();
}

From source file:com.github.anba.es6draft.compiler.assembler.TryCatchLabel.java

License:Open Source License

public TryCatchLabel() {
    this.label = new Label();
}

From source file:com.github.javalbert.bytecode.utils.AsmUtils.java

License:Apache License

/**
 * /*from w ww. ja  v a  2s.co m*/
 * @param defaultCaseLabel
 * @param cases should be a sorted int array
 * @return an array of {@link Label}s when calling {@link MethodVisitor#visitTableSwitchInsn(int, int, Label, Label...)}
 */
public static Label[] getTableSwitchLabels(Label defaultCaseLabel, int[] cases) {
    List<Label> labels = new ArrayList<>();

    int currentCase = 0;
    int caseValue = cases[0];

    int hi = cases[cases.length - 1];
    int lo = cases[0];

    for (int i = lo; i <= hi; i++) {
        int currentCaseValue = cases[currentCase];

        if (caseValue < currentCaseValue) {
            labels.add(defaultCaseLabel);
            caseValue++;
        } else {
            labels.add(new Label());
            caseValue = currentCaseValue + 1;
            currentCase++;
        }
    }
    return labels.stream().toArray(s -> new Label[s]);
}

From source file:com.github.javalbert.bytecode.utils.AsmUtils.java

License:Apache License

public static void visitDefaultConstructor(ClassWriter cw, String classTypeDescriptor) {
    MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
    mv.visitCode();//w w  w  .ja  va  2  s.c o  m
    Label l0 = new Label();
    mv.visitLabel(l0);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
    mv.visitInsn(RETURN);
    Label l1 = new Label();
    mv.visitLabel(l1);
    mv.visitLocalVariable("this", classTypeDescriptor, null, l0, l1, 0);
    mv.visitMaxs(1, 1);
    mv.visitEnd();
}