Example usage for org.objectweb.asm MethodVisitor visitJumpInsn

List of usage examples for org.objectweb.asm MethodVisitor visitJumpInsn

Introduction

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

Prototype

public void visitJumpInsn(final int opcode, final Label label) 

Source Link

Document

Visits a jump instruction.

Usage

From source file:org.eclipse.golo.compiler.JavaBytecodeStructGenerator.java

License:Open Source License

private void makeGetMethod(ClassWriter classWriter, Struct struct) {
    String owner = struct.getPackageAndClass().toJVMType();
    MethodVisitor visitor = classWriter.visitMethod(ACC_PUBLIC, "get", "(Ljava/lang/String;)Ljava/lang/Object;",
            null, null);/*w  w w . jav a 2s.  c  o  m*/
    visitor.visitCode();
    insertPrivateElementCheck(struct, visitor);
    Label nextCase = new Label();
    for (Member member : struct.getMembers()) {
        visitor.visitLdcInsn(member.getName());
        visitor.visitVarInsn(ALOAD, 1);
        visitor.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false);
        visitor.visitJumpInsn(IFEQ, nextCase);
        visitor.visitVarInsn(ALOAD, 0);
        visitor.visitMethodInsn(INVOKEVIRTUAL, owner, member.getName(), "()Ljava/lang/Object;", false);
        visitor.visitInsn(ARETURN);
        visitor.visitLabel(nextCase);
        nextCase = new Label();
    }
    insertUnknowElementCode(struct, visitor);
    visitor.visitMaxs(0, 0);
    visitor.visitEnd();
}

From source file:org.eclipse.golo.compiler.JavaBytecodeStructGenerator.java

License:Open Source License

private void insertPrivateElementCheck(Struct struct, MethodVisitor visitor) {
    Label afterPrivateCheck = new Label();
    visitor.visitVarInsn(ALOAD, 1);// www  . j  a  v a  2  s  .  co m
    visitor.visitLdcInsn("_");
    visitor.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "startsWith", "(Ljava/lang/String;)Z", false);
    visitor.visitJumpInsn(IFEQ, afterPrivateCheck);
    throwLocalized(visitor, "java/lang/IllegalArgumentException", "struct_private_member",
            struct.getPackageAndClass().toString());
    visitor.visitLabel(afterPrivateCheck);
}

From source file:org.eclipse.golo.compiler.JavaBytecodeStructGenerator.java

License:Open Source License

private void makeEquals(ClassWriter classWriter, Struct struct) {
    String owner = struct.getPackageAndClass().toJVMType();
    MethodVisitor visitor = classWriter.visitMethod(ACC_PUBLIC, "equals", "(Ljava/lang/Object;)Z", null, null);
    Label notFrozenLabel = new Label();
    Label falseLabel = new Label();
    Label sameTypeLabel = new Label();
    visitor.visitCode();//from  w ww .  ja v a  2  s.c  o m
    visitor.visitVarInsn(ALOAD, 0);
    visitor.visitFieldInsn(GETFIELD, owner, $_frozen, "Z");
    visitor.visitJumpInsn(IFNE, notFrozenLabel);
    // super.equals()
    visitor.visitVarInsn(ALOAD, 0);
    visitor.visitVarInsn(ALOAD, 1);
    visitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", false);
    visitor.visitInsn(IRETURN);
    // The receiver is frozen
    visitor.visitLabel(notFrozenLabel);
    visitor.visitVarInsn(ALOAD, 1);
    visitor.visitTypeInsn(INSTANCEOF, owner);
    visitor.visitJumpInsn(IFNE, sameTypeLabel);
    visitor.visitJumpInsn(GOTO, falseLabel);
    // The argument is of the same type, too
    visitor.visitLabel(sameTypeLabel);
    visitor.visitVarInsn(ALOAD, 1);
    visitor.visitTypeInsn(CHECKCAST, owner);
    visitor.visitFieldInsn(GETFIELD, owner, $_frozen, "Z");
    visitor.visitJumpInsn(IFEQ, falseLabel);
    // The argument is not frozen
    for (Member member : struct.getMembers()) {
        visitor.visitVarInsn(ALOAD, 0);
        visitor.visitFieldInsn(GETFIELD, owner, member.getName(), "Ljava/lang/Object;");
        visitor.visitVarInsn(ALOAD, 1);
        visitor.visitTypeInsn(CHECKCAST, owner);
        visitor.visitFieldInsn(GETFIELD, owner, member.getName(), "Ljava/lang/Object;");
        visitor.visitMethodInsn(INVOKESTATIC, "java/util/Objects", "equals",
                "(Ljava/lang/Object;Ljava/lang/Object;)Z", false);
        visitor.visitJumpInsn(IFEQ, falseLabel);
    }
    visitor.visitInsn(ICONST_1);
    visitor.visitInsn(IRETURN);
    // False
    visitor.visitLabel(falseLabel);
    visitor.visitInsn(ICONST_0);
    visitor.visitInsn(IRETURN);
    visitor.visitMaxs(0, 0);
    visitor.visitEnd();
}

From source file:org.eclipse.golo.compiler.JavaBytecodeStructGenerator.java

License:Open Source License

private void makeHashCode(ClassWriter classWriter, Struct struct) {
    String owner = struct.getPackageAndClass().toJVMType();
    MethodVisitor visitor = classWriter.visitMethod(ACC_PUBLIC, "hashCode", "()I", null, null);
    Label notFrozenLabel = new Label();
    visitor.visitCode();/*  w  w w . ja v a  2  s .c om*/
    visitor.visitVarInsn(ALOAD, 0);
    visitor.visitFieldInsn(GETFIELD, owner, $_frozen, "Z");
    visitor.visitJumpInsn(IFNE, notFrozenLabel);
    // super.hashCode()
    visitor.visitVarInsn(ALOAD, 0);
    visitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "hashCode", "()I", false);
    visitor.visitInsn(IRETURN);
    // The receiver is frozen
    visitor.visitLabel(notFrozenLabel);
    loadInteger(visitor, struct.getMembers().size());
    visitor.visitTypeInsn(ANEWARRAY, "java/lang/Object");
    int i = 0;
    for (Member member : struct.getMembers()) {
        visitor.visitInsn(DUP);
        loadInteger(visitor, i);
        visitor.visitVarInsn(ALOAD, 0);
        visitor.visitFieldInsn(GETFIELD, owner, member.getName(), "Ljava/lang/Object;");
        visitor.visitInsn(AASTORE);
        i++;
    }
    visitor.visitMethodInsn(INVOKESTATIC, "java/util/Objects", "hash", "([Ljava/lang/Object;)I", false);
    visitor.visitInsn(IRETURN);
    visitor.visitMaxs(0, 0);
    visitor.visitEnd();
}

From source file:org.eclipse.golo.compiler.JavaBytecodeStructGenerator.java

License:Open Source License

private void makeSetter(ClassWriter classWriter, String owner, String name, Struct struct) {
    int accessFlag = name.startsWith("_") ? ACC_PRIVATE : ACC_PUBLIC;
    MethodVisitor visitor = classWriter.visitMethod(accessFlag, name,
            "(Ljava/lang/Object;)L" + struct.getPackageAndClass().toJVMType() + ";", null, null);
    visitor.visitCode();//from   w  w  w  .  j a va 2s .  c  om
    visitor.visitVarInsn(ALOAD, 0);
    visitor.visitFieldInsn(GETFIELD, owner, $_frozen, "Z");
    Label setLabel = new Label();
    visitor.visitJumpInsn(IFEQ, setLabel);
    throwLocalized(visitor, "java/lang/IllegalStateException", "frozen_struct",
            struct.getPackageAndClass().toString());
    visitor.visitLabel(setLabel);
    visitor.visitVarInsn(ALOAD, 0);
    visitor.visitVarInsn(ALOAD, 1);
    visitor.visitFieldInsn(PUTFIELD, owner, name, "Ljava/lang/Object;");
    visitor.visitVarInsn(ALOAD, 0);
    visitor.visitInsn(ARETURN);
    visitor.visitMaxs(0, 0);
    visitor.visitEnd();
}

From source file:org.eclipse.golo.compiler.JavaBytecodeUnionGenerator.java

License:Open Source License

private void makeMatchlikeTestMethod(ClassWriter classWriter, UnionValue value, boolean result) {
    String methName = "is" + value.getName();
    MethodVisitor mv = classWriter.visitMethod(ACC_PUBLIC, methName, "()Z", null, null);
    mv.visitCode();//  www.  j  av  a2s. co m
    mv.visitInsn(result ? ICONST_1 : ICONST_0);
    mv.visitInsn(IRETURN);
    mv.visitMaxs(0, 0);
    mv.visitEnd();

    if (value.hasMembers()) {
        mv = classWriter.visitMethod(ACC_PUBLIC, methName, argsSignature(value.getMembers().size()) + "Z", null,
                null);
        for (Member member : value.getMembers()) {
            mv.visitParameter(member.getName(), ACC_FINAL);
        }
        mv.visitCode();
        if (!result) {
            mv.visitInsn(ICONST_0);
        } else {
            int i = 1;
            Label allEquals = new Label();
            Label notEqual = new Label();
            String target = value.getPackageAndClass().toJVMType();
            for (Member member : value.getMembers()) {
                mv.visitVarInsn(ALOAD, i);
                mv.visitVarInsn(ALOAD, 0);
                mv.visitFieldInsn(GETFIELD, target, member.getName(), "Ljava/lang/Object;");
                mv.visitMethodInsn(INVOKESTATIC, "java/util/Objects", "equals",
                        "(Ljava/lang/Object;Ljava/lang/Object;)Z", false);
                mv.visitJumpInsn(IFEQ, notEqual);
                i++;
            }
            mv.visitInsn(ICONST_1);
            mv.visitJumpInsn(GOTO, allEquals);
            mv.visitLabel(notEqual);
            mv.visitInsn(ICONST_0);
            mv.visitLabel(allEquals);
        }
        mv.visitInsn(IRETURN);
        mv.visitMaxs(0, 0);
        mv.visitEnd();
    }
}

From source file:org.eclipse.golo.compiler.JavaBytecodeUnionGenerator.java

License:Open Source License

private void makeEquals(ClassWriter cw, UnionValue value) {
    String target = value.getPackageAndClass().toJVMType();
    MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "equals", "(Ljava/lang/Object;)Z", null, null);
    Label notSameInstance = new Label();
    Label notNull = new Label();
    Label sameType = new Label();
    Label allAttrsEquals = new Label();
    Label attrNotEqual = new Label();
    mv.visitCode();//from   w  ww. j a v a2s .  c  o m

    // if (other == this) { return true; }
    mv.visitVarInsn(ALOAD, 1);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitJumpInsn(IF_ACMPNE, notSameInstance);
    mv.visitInsn(ICONST_1);
    mv.visitInsn(IRETURN);
    mv.visitLabel(notSameInstance);

    // if (other == null) { return false; }
    mv.visitVarInsn(ALOAD, 1);
    mv.visitJumpInsn(IFNONNULL, notNull);
    mv.visitInsn(ICONST_0);
    mv.visitInsn(IRETURN);
    mv.visitLabel(notNull);

    // if (!(other instanceof <value>)) { return false; }
    mv.visitVarInsn(ALOAD, 1);
    mv.visitTypeInsn(INSTANCEOF, target);
    mv.visitJumpInsn(IFNE, sameType);
    mv.visitInsn(ICONST_0);
    mv.visitInsn(IRETURN);
    mv.visitLabel(sameType);

    // cast other to <value>
    mv.visitVarInsn(ALOAD, 1);
    mv.visitTypeInsn(CHECKCAST, target);
    mv.visitVarInsn(ASTORE, 2);

    // java.util.Objects.equals(<member>, other.<member>)
    for (Member member : value.getMembers()) {
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(GETFIELD, target, member.getName(), "Ljava/lang/Object;");
        mv.visitVarInsn(ALOAD, 2);
        mv.visitFieldInsn(GETFIELD, target, member.getName(), "Ljava/lang/Object;");
        mv.visitMethodInsn(INVOKESTATIC, "java/util/Objects", "equals",
                "(Ljava/lang/Object;Ljava/lang/Object;)Z", false);
        mv.visitJumpInsn(IFEQ, attrNotEqual);
    }
    mv.visitInsn(ICONST_1);
    mv.visitJumpInsn(GOTO, allAttrsEquals);
    mv.visitLabel(attrNotEqual);
    mv.visitInsn(ICONST_0);
    mv.visitLabel(allAttrsEquals);
    mv.visitInsn(IRETURN);
    mv.visitMaxs(0, 0);
    mv.visitEnd();
}

From source file:org.eclipse.m2m.atl.emftvm.jit.CodeBlockJIT.java

License:Open Source License

/**
 * Generates an execute method for the {@link JITCodeBlock}.
 * @param execute the execute method visitor
 * @param cb the {@link CodeBlock} to JIT-compile
 * @param className the name of the generated class
 *//*from   w  w  w.  ja  v a2s.  c  om*/
protected void generateExecute(final MethodVisitor execute, final CodeBlock cb, final String className) {
    execute.visitCode();
    // Generate labels
    final LabelSwitch ls = new LabelSwitch();
    for (Instruction instr : cb.getCode()) {
        ls.doSwitch(instr);
    }
    // Default labels
    final Label start = new Label();
    final Label end = new Label();
    final Label tryStart = new Label();
    final Label vmExceptionHandler = new Label();
    final Label exceptionHandler = new Label();
    final Label catchEnd = new Label();
    // Create exception table
    execute.visitTryCatchBlock(tryStart, vmExceptionHandler, vmExceptionHandler,
            Type.getInternalName(VMException.class));
    execute.visitTryCatchBlock(tryStart, vmExceptionHandler, exceptionHandler,
            Type.getInternalName(Exception.class));
    // Generate bytecode
    execute.visitLabel(start);
    execute.visitVarInsn(ALOAD, 1); // frame
    execute.visitMethodInsn(INVOKEVIRTUAL, Type.getInternalName(StackFrame.class), "getEnv",
            Type.getMethodDescriptor(Type.getType(ExecEnv.class), new Type[0]));
    execute.visitVarInsn(ASTORE, 2);
    execute.visitVarInsn(ALOAD, 2); // env
    execute.visitMethodInsn(INVOKEINTERFACE, Type.getInternalName(ExecEnv.class), "getMonitor",
            Type.getMethodDescriptor(Type.getType(VMMonitor.class), new Type[0]));
    execute.visitVarInsn(ASTORE, 3); // monitor
    execute.visitLabel(tryStart);
    final ByteCodeSwitch bs = new ByteCodeSwitch(this, execute, ls);
    final EList<Instruction> code = cb.getCode();
    final boolean hasMonitor = getEnv().getMonitor() != null;
    for (Instruction instr : code) {
        if (hasMonitor) {
            // do checkMonitor() before each instruction
            generateCheckMonitor(execute, code.indexOf(instr) + 1); // pc
        }
        // generate instruction-specific code
        bs.doSwitch(instr);
    }
    execute.visitJumpInsn(GOTO, catchEnd);
    // catch (VMException e)
    execute.visitLabel(vmExceptionHandler);
    execute.visitVarInsn(ASTORE, 4); // e
    execute.visitVarInsn(ALOAD, 4); // e
    execute.visitInsn(ATHROW); // throw e
    // catch (Exception e)
    execute.visitLabel(exceptionHandler);
    execute.visitVarInsn(ASTORE, 4); // e
    execute.visitTypeInsn(NEW, Type.getInternalName(VMException.class)); // new VMException(): [vme, ...]
    execute.visitInsn(DUP); // [vme, vme, e, ...]
    execute.visitVarInsn(ALOAD, 1); // frame: [frame, vme, vme, ...]
    execute.visitVarInsn(ALOAD, 4); // e: [e, frame, vme, vme, ...]
    execute.visitMethodInsn(INVOKESPECIAL, // new VMException(frame, e): [vme, ...]
            Type.getInternalName(VMException.class), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE,
                    new Type[] { Type.getType(StackFrame.class), Type.getType(Throwable.class) }));
    execute.visitInsn(ATHROW); // throw vme
    // Regular method return
    execute.visitLabel(catchEnd);
    if (cb.getStackLevel() == 0) {
        execute.visitInsn(ACONST_NULL); // push null
    }
    execute.visitInsn(ARETURN); // return result
    execute.visitLabel(end);
    // Create local variable table
    execute.visitLocalVariable("this", "L" + className + ";", null, start, end, 0);
    execute.visitLocalVariable("frame", Type.getDescriptor(StackFrame.class), null, start, end, 1);
    execute.visitLocalVariable("env", Type.getDescriptor(ExecEnv.class), null, start, end, 2);
    execute.visitLocalVariable("monitor", Type.getDescriptor(VMMonitor.class), null, start, end, 3);
    execute.visitLocalVariable("e", Type.getDescriptor(VMException.class), null, vmExceptionHandler,
            exceptionHandler, 4);
    execute.visitLocalVariable("e", Type.getDescriptor(Exception.class), null, exceptionHandler, catchEnd, 4);
    // Finalise
    execute.visitMaxs(0, 0); // recalculate 
    execute.visitEnd();
}

From source file:org.eclipse.m2m.atl.emftvm.jit.CodeBlockJIT.java

License:Open Source License

/**
 * Generates bytecode for checking the VM monitor
 * @param mv the method visitor to generate code for
 * @param pc the current program counter
 *///from  w  ww .j  av  a 2 s  .  c  o  m
protected static void generateCheckMonitor(final MethodVisitor mv, final int pc) {
    // Labels
    final Label notTerminated = new Label();
    // Generate bytecode
    mv.visitVarInsn(ALOAD, 3); // monitor: [..., monitor]
    mv.visitMethodInsn(INVOKEINTERFACE, // monitor.isTerminated(): [..., boolean]
            Type.getInternalName(VMMonitor.class), "isTerminated",
            Type.getMethodDescriptor(Type.BOOLEAN_TYPE, new Type[0]));
    mv.visitJumpInsn(IFEQ, notTerminated); // jump if isTerminated == false: [...]
    mv.visitTypeInsn(NEW, Type.getInternalName(VMException.class)); // new VMException: [..., vme]
    mv.visitInsn(DUP); // [..., vme, vme]
    mv.visitVarInsn(ALOAD, 1); // frame: [..., vme, vme, frame]
    mv.visitLdcInsn("Execution terminated."); // [..., vme, vme, frame, msg]
    mv.visitMethodInsn(INVOKESPECIAL, // vme.<init>(frame, msg): [..., vme]
            Type.getInternalName(VMException.class), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE,
                    new Type[] { Type.getType(StackFrame.class), Type.getType(String.class) }));
    mv.visitInsn(ATHROW); // throw vme: [...]
    mv.visitLabel(notTerminated);
    mv.visitVarInsn(ALOAD, 1); // frame: [..., frame]
    generatePushInt(mv, pc); // [..., frame, pc]
    mv.visitMethodInsn(INVOKEVIRTUAL, // frame.setPc(pc): [...] 
            Type.getInternalName(StackFrame.class), "setPc",
            Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { Type.INT_TYPE }));
    mv.visitVarInsn(ALOAD, 3); // monitor: [..., monitor]
    mv.visitVarInsn(ALOAD, 1); // frame: [..., monitor, frame]
    mv.visitMethodInsn(INVOKEINTERFACE, // monitor.step(frame): [...]
            Type.getInternalName(VMMonitor.class), "step",
            Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { Type.getType(StackFrame.class) }));
}

From source file:org.eclipse.objectteams.otredyn.bytecode.asm.AddGlobalTeamActivationAdapter.java

License:Open Source License

@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
    synchronized (AddGlobalTeamActivationAdapter.class) {
        if (!done && isMainMethod(name, desc, access)) {
            done = true;//  ww w  . ja  v a  2 s. c o  m
            final MethodVisitor methodVisitor = cv.visitMethod(access, name, desc, null, null);
            return new AdviceAdapter(this.api, methodVisitor, access, name, desc) {
                @Override
                protected void onMethodEnter() {
                    List<String> teams = getTeamsFromConfigFile();
                    for (String aTeam : teams) {
                        Label start, end, typeHandler, ctorHandler, after;

                        String aTeamSlash = aTeam.replace('.', '/');

                        // new SomeTeam():
                        methodVisitor.visitLabel(start = new Label());
                        methodVisitor.visitTypeInsn(Opcodes.NEW, aTeamSlash);
                        //       .activate(Team.ALL_THREADS):
                        methodVisitor.visitInsn(Opcodes.DUP);
                        methodVisitor.visitMethodInsn(Opcodes.INVOKESPECIAL, aTeamSlash, "<init>", "()V",
                                false);
                        methodVisitor.visitFieldInsn(Opcodes.GETSTATIC, ClassNames.TEAM_SLASH, "ALL_THREADS",
                                "Ljava/lang/Thread;");
                        methodVisitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, aTeamSlash, "activate",
                                "(Ljava/lang/Thread;)V", false);

                        methodVisitor.visitLabel(end = new Label());
                        methodVisitor.visitJumpInsn(Opcodes.GOTO, after = new Label());

                        // catch (ClassNotFoundException, NoClassDefFoundError):
                        //   System.err.println(...)
                        methodVisitor.visitLabel(typeHandler = new Label());
                        methodVisitor.visitInsn(Opcodes.POP); // discard the exception
                        methodVisitor.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "err",
                                "Ljava/io/PrintStream;");
                        methodVisitor.visitLdcInsn("Config error: Team class '" + aTeam + "' in config file '"
                                + TEAM_CONFIG_FILE + "' can not be found!");
                        methodVisitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println",
                                "(Ljava/lang/String;)V", false);
                        methodVisitor.visitJumpInsn(Opcodes.GOTO, after);
                        methodVisitor.visitTryCatchBlock(start, end, typeHandler,
                                "java/lang/ClassNotFoundException");
                        // dup to avoid stackmap errors (ASM bug at 1.8)
                        methodVisitor.visitLabel(typeHandler = new Label());
                        methodVisitor.visitInsn(Opcodes.POP); // discard the exception
                        methodVisitor.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "err",
                                "Ljava/io/PrintStream;");
                        methodVisitor.visitLdcInsn("Config error: Team class '" + aTeam + "' in config file '"
                                + TEAM_CONFIG_FILE + "' can not be found!");
                        methodVisitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println",
                                "(Ljava/lang/String;)V", false);
                        methodVisitor.visitJumpInsn(Opcodes.GOTO, after);
                        //
                        methodVisitor.visitTryCatchBlock(start, end, typeHandler,
                                "java/lang/NoClassDefFoundError");

                        // catch (NoSuchMethodError):
                        //   System.err.println(...)
                        methodVisitor.visitLabel(ctorHandler = new Label());
                        methodVisitor.visitInsn(Opcodes.POP); // discard the exception
                        methodVisitor.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "err",
                                "Ljava/io/PrintStream;");
                        methodVisitor.visitLdcInsn(
                                "Activation failed: Team class '" + aTeam + "' has no default constuctor!");
                        methodVisitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println",
                                "(Ljava/lang/String;)V", false);
                        methodVisitor.visitTryCatchBlock(start, end, ctorHandler,
                                "java/lang/NoSuchMethodError");

                        methodVisitor.visitLabel(after);
                    }
                }

                @Override
                public void visitMaxs(int maxStack, int maxLocals) {
                    super.visitMaxs(Math.max(maxStack, 3), maxLocals);
                }
            };
        }
        return null;
    }
}