Example usage for org.objectweb.asm.commons Method getDescriptor

List of usage examples for org.objectweb.asm.commons Method getDescriptor

Introduction

In this page you can find the example usage for org.objectweb.asm.commons Method getDescriptor.

Prototype

public String getDescriptor() 

Source Link

Document

Returns the descriptor of the method described by this object.

Usage

From source file:io.datakernel.codegen.AsmBuilder.java

License:Apache License

/**
 * Returns a new class which is created in a dynamic way
 *
 * @param key key//from   www  . jav  a  2s. c o m
 * @return completed class
 */
private Class<T> defineNewClass(AsmClassKey<T> key, String newClassName) {
    DefiningClassWriter cw = new DefiningClassWriter(classLoader);

    String className;
    if (newClassName == null) {
        className = DEFAULT_CLASS_NAME + COUNTER.incrementAndGet();
    } else {
        className = newClassName;
    }

    Type classType = getType('L' + className.replace('.', '/') + ';');

    // contains all classes (abstract and interfaces)
    final Set<Class<?>> parentClasses = scope.getParentClasses();
    final String[] internalNames = new String[parentClasses.size()];
    int pos = 0;
    for (Class<?> clazz : parentClasses)
        internalNames[pos++] = getInternalName(clazz);

    if (scope.getMainType().isInterface()) {
        cw.visit(V1_6, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, classType.getInternalName(), null,
                "java/lang/Object", internalNames);
    } else {
        cw.visit(V1_6, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, classType.getInternalName(), null, internalNames[0],
                Arrays.copyOfRange(internalNames, 1, internalNames.length));
    }

    {
        Method m = getMethod("void <init> ()");
        GeneratorAdapter g = new GeneratorAdapter(ACC_PUBLIC, m, null, null, cw);
        g.loadThis();

        if (scope.getMainType().isInterface()) {
            g.invokeConstructor(getType(Object.class), m);
        } else {
            g.invokeConstructor(getType(scope.getMainType()), m);
        }

        g.returnValue();
        g.endMethod();
    }

    for (String field : fields.keySet()) {
        Class<?> fieldClass = fields.get(field);
        cw.visitField(ACC_PUBLIC, field, getType(fieldClass).getDescriptor(), null, null);
    }

    for (String field : staticFields.keySet()) {
        Class<?> fieldClass = staticFields.get(field);
        cw.visitField(ACC_PUBLIC + ACC_STATIC, field, getType(fieldClass).getDescriptor(), null, null);
    }

    for (Method m : expressionStaticMap.keySet()) {
        try {
            GeneratorAdapter g = new GeneratorAdapter(ACC_PUBLIC + ACC_STATIC + ACC_FINAL, m, null, null, cw);

            Context ctx = new Context(classLoader, g, classType, scope.getParentClasses(),
                    Collections.EMPTY_MAP, scope.getStaticFields(), m.getArgumentTypes(), m, scope.getMethods(),
                    scope.getStaticMethods());

            Expression expression = expressionStaticMap.get(m);
            loadAndCast(ctx, expression, m.getReturnType());
            g.returnValue();

            g.endMethod();
        } catch (Exception e) {
            throw new RuntimeException("Unable to implement " + m.getName() + m.getDescriptor(), e);
        }
    }

    for (Method m : expressionMap.keySet()) {
        try {
            GeneratorAdapter g = new GeneratorAdapter(ACC_PUBLIC + ACC_FINAL, m, null, null, cw);
            Context ctx = new Context(classLoader, g, classType, scope.getParentClasses(), scope.getFields(),
                    scope.getStaticFields(), m.getArgumentTypes(), m, scope.getMethods(),
                    scope.getStaticMethods());

            Expression expression = expressionMap.get(m);
            loadAndCast(ctx, expression, m.getReturnType());
            g.returnValue();

            g.endMethod();
        } catch (Exception e) {
            throw new RuntimeException("Unable to implement " + m.getName() + m.getDescriptor(), e);
        }
    }
    if (bytecodeSaveDir != null) {
        try (FileOutputStream fos = new FileOutputStream(
                bytecodeSaveDir.resolve(className + ".class").toFile())) {
            fos.write(cw.toByteArray());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    cw.visitEnd();

    Class<?> definedClass = classLoader.defineClass(className, key, cw.toByteArray());
    logger.trace("Defined new {} for key {}", definedClass, key);
    return (Class<T>) definedClass;
}

From source file:net.wpm.codegen.ClassBuilder.java

License:Apache License

/**
 * Returns a new class which is created in a dynamic way
 *
 * @param key key//from   w w w . ja v a2s.c  o  m
 * @return completed class
 */
private Class<T> defineNewClass(AsmClassKey<T> key, String newClassName) {
    DefiningClassWriter cw = new DefiningClassWriter(classLoader);

    String className;
    if (newClassName == null) {
        className = DEFAULT_CLASS_NAME + COUNTER.incrementAndGet();
    } else {
        className = newClassName;
    }

    Type classType = getType('L' + className.replace('.', '/') + ';');

    // contains all classes (abstract and interfaces)
    final Set<Class<?>> parentClasses = scope.getParentClasses();
    final String[] internalNames = new String[parentClasses.size()];
    int pos = 0;
    for (Class<?> clazz : parentClasses)
        internalNames[pos++] = getInternalName(clazz);

    if (scope.getMainType().isInterface()) {
        cw.visit(V1_6, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, classType.getInternalName(), null,
                "java/lang/Object", internalNames);
    } else {
        cw.visit(V1_6, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, classType.getInternalName(), null, internalNames[0],
                Arrays.copyOfRange(internalNames, 1, internalNames.length));
    }

    {
        Method m = getMethod("void <init> ()");
        GeneratorAdapter g = new GeneratorAdapter(ACC_PUBLIC, m, null, null, cw);

        if (constructor != null) {
            Context ctx = new Context(classLoader, g, classType, scope.getParentClasses(), scope.getFields(),
                    scope.getStaticFields(), m.getArgumentTypes(), m, scope.getMethods(),
                    scope.getStaticMethods());
            loadAndCast(ctx, constructor, m.getReturnType());
        }
        g.loadThis();

        if (scope.getMainType().isInterface()) {
            g.invokeConstructor(getType(Object.class), m);
        } else {
            g.invokeConstructor(getType(scope.getMainType()), m);
        }

        g.returnValue();
        g.endMethod();
    }

    for (String field : fields.keySet()) {
        Class<?> fieldClass = fields.get(field);
        cw.visitField(ACC_PUBLIC, field, getType(fieldClass).getDescriptor(), null, null);
    }

    for (String field : staticFields.keySet()) {
        Class<?> fieldClass = staticFields.get(field);
        cw.visitField(ACC_PUBLIC + ACC_STATIC, field, getType(fieldClass).getDescriptor(), null, null);
    }

    for (String field : staticConstants.keySet()) {
        Class<?> fieldClass = staticConstants.get(field);
        cw.visitField(ACC_PUBLIC + ACC_STATIC + ACC_FINAL, field, getType(fieldClass).getDescriptor(), null,
                null);
    }

    for (Method m : staticMethods.keySet()) {
        try {
            GeneratorAdapter g = new GeneratorAdapter(ACC_PUBLIC + ACC_STATIC + ACC_FINAL, m, null, null, cw);

            Context ctx = new Context(classLoader, g, classType, scope.getParentClasses(),
                    Collections.EMPTY_MAP, scope.getStaticFields(), m.getArgumentTypes(), m, scope.getMethods(),
                    scope.getStaticMethods());

            Expression expression = staticMethods.get(m);
            loadAndCast(ctx, expression, m.getReturnType());
            g.returnValue();

            g.endMethod();
        } catch (Exception e) {
            throw new RuntimeException("Unable to implement " + m.getName() + m.getDescriptor(), e);
        }
    }

    for (Method m : methods.keySet()) {
        try {
            GeneratorAdapter g = new GeneratorAdapter(ACC_PUBLIC + ACC_FINAL, m, null, null, cw);
            Context ctx = new Context(classLoader, g, classType, scope.getParentClasses(), scope.getFields(),
                    scope.getStaticFields(), m.getArgumentTypes(), m, scope.getMethods(),
                    scope.getStaticMethods());

            Expression expression = methods.get(m);
            loadAndCast(ctx, expression, m.getReturnType());
            g.returnValue();

            g.endMethod();
        } catch (Exception e) {
            throw new RuntimeException("Unable to implement " + m.getName() + m.getDescriptor(), e);
        }
    }
    if (bytecodeSaveDir != null) {
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(bytecodeSaveDir.resolve(className + ".class").toFile());
            fos.write(cw.toByteArray());
            fos.close();
        } catch (IOException e) {
            try {
                if (fos != null)
                    fos.close();
            } catch (IOException ioe) {
                throw new RuntimeException(ioe);
            }
            throw new RuntimeException(e);
        }
    }

    cw.visitEnd();

    Class<?> definedClass = classLoader.defineClass(className, key, cw.toByteArray());
    logger.trace("Defined new {} for key {}", definedClass, key);
    return (Class<T>) definedClass;
}

From source file:nl.hardijzer.fw.checkabstract.ClassInfo.java

License:Open Source License

public static void main(String[] args) throws IOException {
    if (args.length == 0) {
        System.out.println("java -jar srgtool.jar checkabstract --parse file.jar --check file.jar");
        return;/*from  w w w  .ja va  2 s  .  c o m*/
    }

    List<String> listInput = new LinkedList<String>();
    Set<String> setOutput = new TreeSet<String>();
    for (int i = 0; i < args.length; i++)
        if (args[i].equals("--parse")) {
            listInput.add(args[++i]);
        } else if (args[i].equals("--check")) {
            String a = args[++i];
            listInput.add(a);
            setOutput.add(a);
        }
    System.out.println("Generating class map");
    Map<String, ClassInfo> mapClassInfo = new TreeMap<String, ClassInfo>();
    for (String strInput : listInput) {
        System.out.println("Reading in " + strInput);
        ZipFile zipInput = new ZipFile(strInput);
        Enumeration<? extends ZipEntry> entries = zipInput.entries();
        while (entries.hasMoreElements()) {
            ZipEntry entry = entries.nextElement();
            if (!entry.isDirectory() && entry.getName().endsWith(".class")) {
                ClassReader reader = new ClassReader(zipInput.getInputStream(entry));
                ClassInfoGatherer gatherer = new ClassInfoGatherer();
                reader.accept(gatherer, 0);
                gatherer.info.strZipFilename = strInput;
                mapClassInfo.put(gatherer.info.strName, gatherer.info);
            }
        }
        zipInput.close();
    }
    System.out.println("Classes found: " + mapClassInfo.size());
    Set<String> setDone = new TreeSet<String>();
    LinkedList<String> qToDo = new LinkedList<String>();
    qToDo.addAll(mapClassInfo.keySet());
    while (qToDo.size() > 0) {
        String strCurrent = qToDo.peek();
        if (setDone.contains(strCurrent)) {
            qToDo.remove();
            continue;
        }
        ClassInfo info = mapClassInfo.get(strCurrent);
        if (info == null) {
            if (!strCurrent.startsWith("java/") && !strCurrent.startsWith("javax/"))
                System.err.println("Class not found: " + strCurrent);
            qToDo.remove();
            setDone.add(strCurrent);
            //Add a simple one for later
            info = new ClassInfo();
            info.strName = strCurrent;
            mapClassInfo.put(info.strName, info);
            continue;
        }
        int nSizeBefore = qToDo.size();
        for (String i : info.setImplements) {
            if (!setDone.contains(i))
                qToDo.addFirst(i);
        }
        //Added? do the other classes first, we'll get back here later
        if (nSizeBefore != qToDo.size())
            continue;
        //Remove us from the list, and mark as done
        qToDo.remove();
        setDone.add(strCurrent);
        //Copy methods
        for (String i : info.setImplements) {
            ClassInfo parentinfo = mapClassInfo.get(i);
            for (Method m : parentinfo.setAbstractMethods) {
                info.setAbstractMethods.add(m);
                info.mapMethodOwner.put(m, parentinfo.mapMethodOwner.get(m));
            }
            for (Method m : parentinfo.setMethods) {
                info.setMethods.add(m);
                info.mapMethodOwner.put(m, parentinfo.mapMethodOwner.get(m));
            }
        }
        if (setOutput.contains(info.strZipFilename)) {
            //Check abstract not implemented methods
            if (!info.bIsAbstract) {
                //System.out.println(strCurrent+" checking");
                for (Method m : info.setAbstractMethods) {
                    if (!info.setMethods.contains(m)) {
                        System.out.println("Error in " + info.strName.replace('/', '.') + " ("
                                + info.strZipFilename + ")");
                        System.out.println("\tNo implementation found for abstract method");
                        System.out.println("\tOwner: " + info.mapMethodOwner.get(m).replace('/', '.'));
                        System.out.println("\tMethod: " + methodToString(m));
                        System.out.println("\tDescriptor: " + m.getDescriptor());
                    }
                }
            }
        }
    }
}

From source file:org.apache.aries.spifly.weaver.TCCLSetterVisitor.java

License:Apache License

@Override
public void visitEnd() {
    if (!woven) {
        // if this class wasn't woven, then don't add the synthesized method either.
        super.visitEnd();
        return;//from www .  j  a  v a 2s . com
    }

    // Add generated static method
    Set<String> methodNames = new HashSet<String>();

    for (WeavingData wd : weavingData) {
        /* Equivalent to:
         * private static void $$FCCL$$<className>$<methodName>(Class<?> cls) {
         *   Util.fixContextClassLoader("java.util.ServiceLoader", "load", cls, WovenClass.class.getClassLoader());
         * }
         */
        String methodName = getGeneratedMethodName(wd);
        if (methodNames.contains(methodName))
            continue;

        methodNames.add(methodName);
        Method method = new Method(methodName, Type.VOID_TYPE, new Type[] { CLASS_TYPE });

        GeneratorAdapter mv = new GeneratorAdapter(
                cv.visitMethod(ACC_PRIVATE + ACC_STATIC, methodName, method.getDescriptor(), null, null),
                ACC_PRIVATE + ACC_STATIC, methodName, method.getDescriptor());

        //Load the strings, method parameter and target
        mv.visitLdcInsn(wd.getClassName());
        mv.visitLdcInsn(wd.getMethodName());
        mv.loadArg(0);
        mv.visitLdcInsn(targetClass);

        //Change the class on the stack into a classloader
        mv.invokeVirtual(CLASS_TYPE, new Method("getClassLoader", CLASSLOADER_TYPE, new Type[0]));

        //Call our util method
        mv.invokeStatic(UTIL_CLASS, new Method("fixContextClassloader", Type.VOID_TYPE,
                new Type[] { String_TYPE, String_TYPE, CLASS_TYPE, CLASSLOADER_TYPE }));

        mv.returnValue();
        mv.endMethod();
    }

    super.visitEnd();
}

From source file:org.apache.commons.weaver.privilizer.ActionGenerator.java

License:Apache License

/**
 * Create a new {@link ActionGenerator}.
 * @param access modifier//from   w  w  w .j a va 2s  .c  om
 * @param methd {@link Method} to implement
 * @param exceptions thrown
 * @param owner of the action class
 */
ActionGenerator(final int access, final Method methd, final String[] exceptions,
        final PrivilizingVisitor owner) {
    owner.privilizer().super(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
    this.methd = methd;
    this.exc = ArrayUtils.isNotEmpty(exceptions);
    this.exceptions = exc ? new Type[] { Type.getType(Exception.class) } : null;
    this.owner = owner;
    this.simpleName = generateName(methd);
    this.action = Type.getObjectType(owner.className + '$' + simpleName);

    int privilegedAccessIndex = -1;
    String implName = null;
    for (final Map.Entry<Method, String> entry : owner.privilegedMethods.entrySet()) {
        privilegedAccessIndex++;
        if (entry.getKey().equals(methd)) {
            implName = entry.getValue();
            break;
        }
    }
    Validate.validState(implName != null);

    this.index = privilegedAccessIndex;

    this.impl = new Method(implName, methd.getDescriptor());
    this.implIsStatic = Modifier.isStatic(access);
    final Type[] args = implIsStatic ? methd.getArgumentTypes()
            : ArrayUtils.insert(0, methd.getArgumentTypes(), owner.target);
    this.helper = new Method(privilizer().generateName("access$" + index), methd.getReturnType(), args);
    this.result = Privilizer.wrap(methd.getReturnType());
    this.fields = fields(args);
    this.actionInterface = Type.getType(exc ? PrivilegedExceptionAction.class : PrivilegedAction.class);
}

From source file:org.elasticsearch.painless.MethodWriter.java

License:Apache License

public MethodWriter(int access, Method method, ClassVisitor cw, BitSet statements, CompilerSettings settings) {
    super(Opcodes.ASM5, cw.visitMethod(access, method.getName(), method.getDescriptor(), null, null), access,
            method.getName(), method.getDescriptor());

    this.statements = statements;
    this.settings = settings;
}

From source file:org.evosuite.stubs.StubClassVisitor.java

License:Open Source License

/**
 * Stubbed methods forward the query to the central Stubs class
 * and return whatever that class tells it to return
 * /*  w w w. j  a v  a 2s  . c o  m*/
 * @param mg
 * @param m
 */
private void createMethod(GeneratorAdapter mg, Method m) {
    String methodName = "getReturnValue" + getTypeName(m.getReturnType());
    String desc = "(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)"
            + getReturnTypeDesc(m.getReturnType());
    mg.push(className);
    mg.push(m.getName() + m.getDescriptor());
    mg.loadArgArray();
    Type owner = Type.getType(PackageInfo.getNameWithSlash(Stubs.class));
    Method method = new Method(methodName, desc);
    mg.invokeStatic(owner, method);
    insertReturnCast(mg, m);
    mg.returnValue();
    mg.endMethod();
}

From source file:org.glowroot.agent.weaving.WeavingClassVisitor.java

License:Apache License

@RequiresNonNull("type")
private void addShim(ShimType shimType) {
    for (java.lang.reflect.Method reflectMethod : shimType.shimMethods()) {
        Method method = Method.getMethod(reflectMethod);
        Shim shim = reflectMethod.getAnnotation(Shim.class);
        checkNotNull(shim);/*from ww w.  j av  a 2  s.c  om*/
        Method targetMethod = Method.getMethod(shim.value());
        MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, method.getName(), method.getDescriptor(), null, null);
        mv.visitCode();
        int i = 0;
        mv.visitVarInsn(ALOAD, i++);
        for (Type argumentType : method.getArgumentTypes()) {
            mv.visitVarInsn(argumentType.getOpcode(ILOAD), i++);
        }
        mv.visitMethodInsn(INVOKEVIRTUAL, type.getInternalName(), targetMethod.getName(),
                targetMethod.getDescriptor(), false);
        mv.visitInsn(method.getReturnType().getOpcode(IRETURN));
        mv.visitMaxs(0, 0);
        mv.visitEnd();
    }
}

From source file:org.glowroot.agent.weaving.WeavingMethodVisitor.java

License:Apache License

private void defineAndEvaluateEnabledLocalVar(Advice advice) {
    Integer enabledLocal = null;//  ww w . j  a  v  a 2  s  .co  m
    Method isEnabledAdvice = advice.isEnabledAdvice();
    if (isEnabledAdvice != null) {
        loadMethodParameters(advice.isEnabledParameters(), 0, -1, advice.adviceType(), IsEnabled.class, false);
        visitMethodInsn(INVOKESTATIC, advice.adviceType().getInternalName(), isEnabledAdvice.getName(),
                isEnabledAdvice.getDescriptor(), false);
        enabledLocal = newLocal(Type.BOOLEAN_TYPE);
        enabledLocals.put(advice, enabledLocal);
        storeLocal(enabledLocal);
    }
    String nestingGroup = advice.pointcut().nestingGroup();
    if (!nestingGroup.isEmpty() || advice.hasBindThreadContext() || advice.hasBindOptionalThreadContext()) {
        if (threadContextHolderLocal == null) {
            // need to define thread context local var outside of any branches,
            // but also don't want to load ThreadContext if enabledLocal exists and is false
            threadContextHolderLocal = newLocal(fastThreadLocalHolderType);
            visitInsn(ACONST_NULL);
            storeLocal(threadContextHolderLocal);
            threadContextLocal = newLocal(threadContextPlusType);
            visitInsn(ACONST_NULL);
            storeLocal(threadContextLocal);
        }
    }
    Integer prevNestingGroupIdLocal = null;
    if (!nestingGroup.isEmpty()) {
        // need to define thread context local var outside of any branches
        // but also don't want to load ThreadContext if enabledLocal exists and is false
        prevNestingGroupIdLocal = newLocal(Type.INT_TYPE);
        prevNestingGroupIdLocals.put(advice, prevNestingGroupIdLocal);
        visitIntInsn(BIPUSH, -1);
        storeLocal(prevNestingGroupIdLocal);
    }
    // futher calculations whether this @Pointcut is enabled..
    if (!nestingGroup.isEmpty() || (advice.hasBindThreadContext() && !advice.hasBindOptionalThreadContext())) {
        Label disabledLabel = new Label();
        if (enabledLocal != null) {
            loadLocal(enabledLocal);
            visitJumpInsn(IFEQ, disabledLabel);
        } else {
            enabledLocal = newLocal(Type.BOOLEAN_TYPE);
            enabledLocals.put(advice, enabledLocal);
            // temporary initial value to help with Java 7 stack frames
            visitInsn(ICONST_0);
            storeLocal(enabledLocal);
        }
        loadThreadContextHolder();
        dup();
        checkNotNull(threadContextHolderLocal);
        storeLocal(threadContextHolderLocal);
        visitMethodInsn(INVOKEVIRTUAL, fastThreadLocalHolderType.getInternalName(), "get",
                "()" + objectType.getDescriptor(), false);
        dup();
        checkNotNull(threadContextLocal);
        storeLocal(threadContextLocal);
        if (advice.hasBindThreadContext() && !advice.hasBindOptionalThreadContext()) {
            visitJumpInsn(IFNULL, disabledLabel);
            if (!nestingGroup.isEmpty()) {
                checkNotNull(prevNestingGroupIdLocal);
                checkNestingGroupId(prevNestingGroupIdLocal, nestingGroup, disabledLabel);
            }
        } else {
            // this conditional covers !nestingGroup.isEmpty()
            Label enabledLabel = new Label();
            // if thread context == null, then not in nesting group
            visitJumpInsn(IFNULL, enabledLabel);
            checkNotNull(prevNestingGroupIdLocal);
            checkNestingGroupId(prevNestingGroupIdLocal, nestingGroup, disabledLabel);
            visitLabel(enabledLabel);
        }
        visitInsn(ICONST_1);
        Label endLabel = new Label();
        goTo(endLabel);
        visitLabel(disabledLabel);
        visitInsn(ICONST_0);
        visitLabel(endLabel);
        storeLocal(enabledLocal);
    }
}

From source file:org.glowroot.agent.weaving.WeavingMethodVisitor.java

License:Apache License

private void invokeOnBefore(Advice advice, @Nullable Integer travelerLocal) {
    Method onBeforeAdvice = advice.onBeforeAdvice();
    if (onBeforeAdvice == null) {
        return;/*from  w  w w  .j  av  a2s.  co m*/
    }
    Integer enabledLocal = enabledLocals.get(advice);
    Label onBeforeBlockEnd = null;
    if (enabledLocal != null) {
        onBeforeBlockEnd = new Label();
        loadLocal(enabledLocal);
        visitJumpInsn(IFEQ, onBeforeBlockEnd);
    }
    loadMethodParameters(advice.onBeforeParameters(), 0, -1, advice.adviceType(), OnBefore.class, false);
    visitMethodInsn(INVOKESTATIC, advice.adviceType().getInternalName(), onBeforeAdvice.getName(),
            onBeforeAdvice.getDescriptor(), false);
    if (travelerLocal != null) {
        storeLocal(travelerLocal);
    }
    String nestingGroup = advice.pointcut().nestingGroup();
    if (advice.hasBindOptionalThreadContext() && !nestingGroup.isEmpty()) {
        // need to check if transaction was just started in @OnBefore and update its
        // currentNestingGroupId

        Integer prevNestingGroupIdLocal = prevNestingGroupIdLocals.get(advice);
        checkNotNull(prevNestingGroupIdLocal);
        loadLocal(prevNestingGroupIdLocal);
        visitIntInsn(BIPUSH, -1);
        Label label = new Label();
        visitJumpInsn(IF_ICMPNE, label);
        // the only reason prevNestingGroupId is -1 here is because no thread context at the
        // start of the method
        checkNotNull(threadContextLocal);
        loadLocal(threadContextLocal);
        visitMethodInsn(INVOKEINTERFACE, threadContextPlusType.getInternalName(), "getCurrentNestingGroupId",
                "()I", true);
        storeLocal(prevNestingGroupIdLocal);
        loadLocal(threadContextLocal);
        int nestingGroupId = getNestingGroupId(nestingGroup);
        visitIntInsn(BIPUSH, nestingGroupId);
        visitMethodInsn(INVOKEINTERFACE, threadContextPlusType.getInternalName(), "setCurrentNestingGroupId",
                "(I)V", true);
        visitLabel(label);
    }
    if (onBeforeBlockEnd != null) {
        visitLabel(onBeforeBlockEnd);
    }
}