Example usage for org.objectweb.asm.tree InsnList add

List of usage examples for org.objectweb.asm.tree InsnList add

Introduction

In this page you can find the example usage for org.objectweb.asm.tree InsnList add.

Prototype

public void add(final InsnList insnList) 

Source Link

Document

Adds the given instructions to the end of this list.

Usage

From source file:net.sandius.rembulan.compiler.gen.asm.InvokeMethod.java

License:Apache License

public MethodNode methodNode() {
    MethodNode node = new MethodNode(ACC_PUBLIC, "invoke", context.invokeMethodType().getDescriptor(), null,
            runMethod.throwsExceptions());

    InsnList il = node.instructions;
    List<LocalVariableNode> locals = node.localVariables;

    LabelNode begin = new LabelNode();
    LabelNode end = new LabelNode();

    int invokeKind = context.kind();

    il.add(begin);

    // a (slotIdx -> paramIdx) map
    int[] slotParamMap = new int[context.slots.numSlots()];
    Arrays.fill(slotParamMap, -1);

    for (int paramIdx = 0; paramIdx < context.fn.params().size(); paramIdx++) {
        int slotIdx = context.slots.slotOf(context.fn.params().get(paramIdx));
        assert (slotParamMap[slotIdx] == -1);
        slotParamMap[slotIdx] = paramIdx;
    }//from  w w  w. j a v a  2  s .  co  m

    if (invokeKind > 0) {
        il.add(new VarInsnNode(ALOAD, 0)); // this
        il.add(new VarInsnNode(ALOAD, 1)); // context
        il.add(ASMUtils.loadInt(0)); // resumption point

        // we have (invokeKind - 1) standalone parameters, mapping them onto numSlots

        for (int paramIdx : slotParamMap) {
            if (paramIdx < 0) {
                // slot unused
                il.add(new InsnNode(ACONST_NULL));
            } else {
                // used by the parameter #paramIdx
                Var param = context.fn.params().get(paramIdx);
                boolean reified = context.types.isReified(param);

                if (reified) {
                    il.add(new TypeInsnNode(NEW, Type.getInternalName(Variable.class)));
                    il.add(new InsnNode(DUP));
                }

                il.add(new VarInsnNode(ALOAD, 2 + paramIdx));

                if (reified) {
                    il.add(VariableMethods.constructor());
                }
            }
        }
    } else {
        // variable number of parameters, encoded in an array at position 2

        int lv_varargsSize = 3;
        int lv_varargs = 4;

        int numParams = context.numOfParameters();

        if (context.isVararg()) {

            LabelNode l_v_begin = new LabelNode();
            LabelNode l_v_nonempty = new LabelNode();
            LabelNode l_v_empty = new LabelNode();
            LabelNode l_v_done = new LabelNode();

            il.add(new VarInsnNode(ALOAD, 2));
            il.add(new InsnNode(ARRAYLENGTH));

            if (numParams > 0) {
                il.add(ASMUtils.loadInt(context.numOfParameters()));
                il.add(new InsnNode(ISUB));
            }
            il.add(new VarInsnNode(ISTORE, lv_varargsSize));

            il.add(l_v_begin);

            il.add(new VarInsnNode(ILOAD, lv_varargsSize));
            il.add(new JumpInsnNode(IFLE, l_v_empty));

            // nonempty varargs

            // varargs = new Object[varargsSize];
            il.add(new VarInsnNode(ILOAD, lv_varargsSize));
            il.add(new TypeInsnNode(ANEWARRAY, Type.getInternalName(Object.class)));
            il.add(new VarInsnNode(ASTORE, lv_varargs));

            il.add(l_v_nonempty);

            // call System.arraycopy(src, srcPos, dest, destPos, len)
            il.add(new VarInsnNode(ALOAD, 2)); // src
            il.add(ASMUtils.loadInt(numParams)); // srcPos
            il.add(new VarInsnNode(ALOAD, lv_varargs)); // dest
            il.add(ASMUtils.loadInt(0)); // destPos
            il.add(new VarInsnNode(ILOAD, lv_varargsSize)); // len
            il.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(System.class), "arraycopy",
                    Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(Object.class), Type.INT_TYPE,
                            Type.getType(Object.class), Type.INT_TYPE, Type.INT_TYPE),
                    false));

            il.add(new JumpInsnNode(GOTO, l_v_done));

            // empty varargs
            il.add(l_v_empty);
            il.add(new FrameNode(F_APPEND, 1, new Object[] { Opcodes.INTEGER }, 0, null));

            // varargs = new Object[0];
            il.add(ASMUtils.loadInt(0));
            il.add(new TypeInsnNode(ANEWARRAY, Type.getInternalName(Object.class)));
            il.add(new VarInsnNode(ASTORE, lv_varargs));

            il.add(l_v_done);
            il.add(new FrameNode(F_APPEND, 1,
                    new Object[] { ASMUtils.arrayTypeFor(Object.class).getInternalName() }, 0, null));

            locals.add(new LocalVariableNode("sz", Type.INT_TYPE.getDescriptor(), null, l_v_begin, end,
                    lv_varargsSize));
            locals.add(new LocalVariableNode("varargs", ASMUtils.arrayTypeFor(Object.class).getDescriptor(),
                    null, l_v_nonempty, l_v_empty, lv_varargs));
            locals.add(new LocalVariableNode("varargs", ASMUtils.arrayTypeFor(Object.class).getDescriptor(),
                    null, l_v_done, end, lv_varargs));
        }

        // load #numOfParameters, mapping them onto #numOfRegisters

        int lv_param_offset = context.isVararg() ? lv_varargs + 1 : lv_varargsSize;

        if (numParams > 0) {
            // initialise parameter slot variables to null

            for (int i = 0; i < numParams; i++) {
                LabelNode l = new LabelNode();
                int lv = lv_param_offset + i;
                il.add(new InsnNode(ACONST_NULL));
                il.add(new VarInsnNode(ASTORE, lv));
                il.add(l);
                il.add(new FrameNode(F_APPEND, 1, new Object[] { Type.getInternalName(Object.class) }, 0,
                        null));
                locals.add(
                        new LocalVariableNode("arg_" + i, Type.getDescriptor(Object.class), null, l, end, lv));
            }

            // insert switch for filling parameter slots

            LabelNode[] l_s_table = new LabelNode[numParams + 1];
            for (int i = 0; i < numParams + 1; i++) {
                l_s_table[i] = new LabelNode();
            }

            il.add(new VarInsnNode(ALOAD, 2));
            il.add(new InsnNode(ARRAYLENGTH));
            il.add(new TableSwitchInsnNode(0, numParams, l_s_table[numParams], l_s_table));

            for (int i = numParams; i >= 0; i--) {
                // length of args is at least i; may assign into param (i - 1)
                int paramIdx = i - 1;

                il.add(l_s_table[i]);
                il.add(new FrameNode(F_SAME, 0, null, 0, null));

                if (paramIdx >= 0) {
                    // assign into param #paramIdx
                    il.add(new VarInsnNode(ALOAD, 2));
                    il.add(ASMUtils.loadInt(paramIdx));
                    il.add(new InsnNode(AALOAD));
                    il.add(new VarInsnNode(ASTORE, lv_param_offset + paramIdx));
                }
            }
        }

        // now assemble the run() method invocation, filling in nulls for non-parameter slots

        il.add(new VarInsnNode(ALOAD, 0)); // this
        il.add(new VarInsnNode(ALOAD, 1)); // context
        il.add(ASMUtils.loadInt(0)); // resumption point
        if (context.isVararg()) {
            il.add(new VarInsnNode(ALOAD, lv_varargs));
        }
        for (int paramIdx : slotParamMap) {
            if (paramIdx < 0) {
                // slot not used by a parameter
                il.add(new InsnNode(ACONST_NULL));
            } else {
                // slot is parameter #paramIdx
                Var param = context.fn.params().get(paramIdx);
                boolean reified = context.types.isReified(param);

                if (reified) {
                    il.add(new TypeInsnNode(NEW, Type.getInternalName(Variable.class)));
                    il.add(new InsnNode(DUP));
                }

                il.add(new VarInsnNode(ALOAD, lv_param_offset + paramIdx));

                if (reified) {
                    il.add(VariableMethods.constructor());
                }
            }
        }
    }

    il.add(runMethod.methodInvokeInsn());

    il.add(new InsnNode(RETURN));
    il.add(end);

    locals.add(new LocalVariableNode("this", context.thisClassType().getDescriptor(), null, begin, end, 0));
    locals.add(
            new LocalVariableNode("context", Type.getDescriptor(ExecutionContext.class), null, begin, end, 1));
    if (invokeKind > 0) {
        for (int i = 0; i < invokeKind; i++) {
            locals.add(new LocalVariableNode("arg_" + i, Type.getDescriptor(Object.class), null, begin, end,
                    2 + i));
        }
        // TODO: maxLocals, maxStack
    } else {
        locals.add(new LocalVariableNode("args", ASMUtils.arrayTypeFor(Object.class).getDescriptor(), null,
                begin, end, 2));
        // TODO: maxLocals, maxStack
    }

    return node;
}

From source file:net.sandius.rembulan.compiler.gen.asm.ResumeMethod.java

License:Apache License

public MethodNode methodNode() {
    MethodNode node = new MethodNode(ACC_PUBLIC, "resume",
            Type.getMethodType(Type.VOID_TYPE, Type.getType(ExecutionContext.class), Type.getType(Object.class))
                    .getDescriptor(),//from  w  w  w  .  j  a  v a  2 s .  c  om
            null, runMethod.throwsExceptions());

    if (runMethod.isResumable()) {
        InsnList il = node.instructions;
        List<LocalVariableNode> locals = node.localVariables;

        LabelNode begin = new LabelNode();
        LabelNode vars = new LabelNode();
        LabelNode end = new LabelNode();

        il.add(begin);

        il.add(new VarInsnNode(ALOAD, 2));
        il.add(new TypeInsnNode(CHECKCAST, Type.getInternalName(DefaultSavedState.class)));

        il.add(vars);

        il.add(new VarInsnNode(ASTORE, 3));

        il.add(new VarInsnNode(ALOAD, 0)); // this
        il.add(new VarInsnNode(ALOAD, 1)); // context

        il.add(new VarInsnNode(ALOAD, 3)); // saved state
        il.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(DefaultSavedState.class),
                "resumptionPoint", Type.getMethodDescriptor(Type.INT_TYPE), false)); // resumption point

        // registers
        if (context.isVararg() || runMethod.numOfRegisters() > 0) {
            il.add(new VarInsnNode(ALOAD, 3));
            il.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(DefaultSavedState.class), "registers",
                    Type.getMethodDescriptor(ASMUtils.arrayTypeFor(Object.class)), false));

            // varargs stored as the 0th element
            int numRegs = runMethod.numOfRegisters() + (context.isVararg() ? 1 : 0);

            for (int i = 0; i < numRegs; i++) {

                // Note: it might be more elegant to use a local variable
                // to store the array instead of having to perform SWAPs

                if (i + 1 < numRegs) {
                    il.add(new InsnNode(DUP));
                }
                il.add(ASMUtils.loadInt(i));
                il.add(new InsnNode(AALOAD));
                if (i == 0 && context.isVararg()) {
                    il.add(new TypeInsnNode(CHECKCAST, ASMUtils.arrayTypeFor(Object.class).getInternalName()));
                }

                if (i + 1 < numRegs) {
                    il.add(new InsnNode(SWAP));
                }
            }
        }

        // call run(...)
        il.add(runMethod.methodInvokeInsn());

        il.add(new InsnNode(RETURN));
        il.add(end);

        locals.add(new LocalVariableNode("this", context.thisClassType().getDescriptor(), null, begin, end, 0));
        locals.add(new LocalVariableNode("context", Type.getDescriptor(ExecutionContext.class), null, begin,
                end, 1));
        locals.add(new LocalVariableNode("suspendedState", context.savedStateClassType().getDescriptor(), null,
                begin, end, 2));
        locals.add(
                new LocalVariableNode("ss", Type.getDescriptor(DefaultSavedState.class), null, vars, end, 3));

        // TODO: maxStack, maxLocals
        node.maxStack = 3 + (runMethod.numOfRegisters() > 0 ? 3 : 0);
        node.maxLocals = 5;
    } else {
        InsnList il = node.instructions;
        List<LocalVariableNode> locals = node.localVariables;

        LabelNode begin = new LabelNode();
        LabelNode end = new LabelNode();

        il.add(begin);
        il.add(new TypeInsnNode(NEW, Type.getInternalName(NonsuspendableFunctionException.class)));
        il.add(new InsnNode(DUP));
        il.add(ASMUtils.ctor(NonsuspendableFunctionException.class));
        il.add(new InsnNode(ATHROW));
        il.add(end);

        locals.add(new LocalVariableNode("this", context.thisClassType().getDescriptor(), null, begin, end, 0));
        locals.add(new LocalVariableNode("context", Type.getDescriptor(ExecutionContext.class), null, begin,
                end, 1));
        locals.add(new LocalVariableNode("suspendedState", context.savedStateClassType().getDescriptor(), null,
                begin, end, 2));

        node.maxStack = 2;
        node.maxLocals = 3;
    }

    return node;
}

From source file:net.sandius.rembulan.compiler.gen.asm.RunMethod.java

License:Apache License

public MethodNode snapshotMethodNode() {
    MethodNode node = new MethodNode(ACC_PRIVATE, snapshotMethodName(), snapshotMethodType().getDescriptor(),
            null, null);//ww  w.  ja  va 2 s.c  o m

    InsnList il = node.instructions;
    LabelNode begin = new LabelNode();
    LabelNode end = new LabelNode();

    il.add(begin);

    il.add(new TypeInsnNode(NEW, Type.getInternalName(DefaultSavedState.class)));
    il.add(new InsnNode(DUP));

    // resumption point
    il.add(new VarInsnNode(ILOAD, 1));

    // registers
    int numRegs = numOfRegisters() + (context.isVararg() ? 1 : 0);
    int regOffset = context.isVararg() ? 3 : 2;

    il.add(ASMUtils.loadInt(numRegs));
    il.add(new TypeInsnNode(ANEWARRAY, Type.getInternalName(Object.class)));
    {
        for (int i = 0; i < numRegs; i++) {
            il.add(new InsnNode(DUP));
            il.add(ASMUtils.loadInt(i));
            il.add(new VarInsnNode(ALOAD, 2 + i));
            il.add(new InsnNode(AASTORE));
        }
    }

    il.add(ASMUtils.ctor(Type.getType(DefaultSavedState.class), Type.INT_TYPE,
            ASMUtils.arrayTypeFor(Object.class)));

    il.add(new InsnNode(ARETURN));

    il.add(end);

    List<LocalVariableNode> locals = node.localVariables;

    locals.add(new LocalVariableNode("this", context.thisClassType().getDescriptor(), null, begin, end, 0));
    locals.add(new LocalVariableNode("rp", Type.INT_TYPE.getDescriptor(), null, begin, end, 1));
    if (context.isVararg()) {
        locals.add(new LocalVariableNode("varargs", ASMUtils.arrayTypeFor(Object.class).getDescriptor(), null,
                begin, end, 2));
    }
    for (int i = 0; i < numOfRegisters(); i++) {
        locals.add(new LocalVariableNode("r_" + i, Type.getDescriptor(Object.class), null, begin, end,
                regOffset + i));
    }

    node.maxLocals = 2 + numOfRegisters();
    node.maxStack = 4 + 3; // 4 to get register array at top, +3 to add element to it

    return node;
}

From source file:net.sandius.rembulan.compiler.gen.asm.RunMethod.java

License:Apache License

private InsnList errorState(LabelNode label) {
    InsnList il = new InsnList();
    il.add(label);
    il.add(ASMUtils.frameSame());/*from   ww  w  .  j  a  v a 2s. co m*/
    il.add(new TypeInsnNode(NEW, Type.getInternalName(IllegalStateException.class)));
    il.add(new InsnNode(DUP));
    il.add(ASMUtils.ctor(IllegalStateException.class));
    il.add(new InsnNode(ATHROW));
    return il;
}

From source file:net.sandius.rembulan.compiler.gen.asm.RunMethod.java

License:Apache License

private InsnList dispatchTable(List<LabelNode> extLabels, List<LabelNode> resumptionLabels,
        LabelNode errorStateLabel) {//from   www  .j  a v a  2s.co m
    InsnList il = new InsnList();

    assert (!extLabels.isEmpty());

    ArrayList<LabelNode> labels = new ArrayList<>();
    labels.addAll(extLabels);
    labels.addAll(resumptionLabels);
    LabelNode[] labelArray = labels.toArray(new LabelNode[labels.size()]);

    int min = 1 - extLabels.size();
    int max = resumptionLabels.size();

    il.add(new VarInsnNode(ILOAD, LV_RESUME));
    il.add(new TableSwitchInsnNode(min, max, errorStateLabel, labelArray));
    return il;
}

From source file:net.sandius.rembulan.compiler.gen.asm.RunMethod.java

License:Apache License

InsnList createSnapshot() {
    InsnList il = new InsnList();

    il.add(new VarInsnNode(ALOAD, 0)); // this
    il.add(new VarInsnNode(ALOAD, 0));
    il.add(new VarInsnNode(ILOAD, LV_RESUME));
    if (context.isVararg()) {
        il.add(new VarInsnNode(ALOAD, LV_VARARGS));
    }//  w w w.  j a v  a 2  s .  c  o m
    for (int i = 0; i < numOfRegisters(); i++) {
        il.add(new VarInsnNode(ALOAD, slotOffset() + i));
    }
    il.add(snapshotMethodInvokeInsn());

    return il;
}

From source file:net.sandius.rembulan.compiler.gen.asm.RunMethod.java

License:Apache License

protected InsnList resumptionHandler(LabelNode label) {
    InsnList il = new InsnList();

    il.add(label);
    il.add(ASMUtils.frameSame1(UnresolvedControlThrowable.class));

    il.add(createSnapshot());/* ww  w  .  jav  a2s .c  om*/

    // register snapshot with the control exception
    il.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(UnresolvedControlThrowable.class), "resolve",
            Type.getMethodType(Type.getType(ResolvedControlThrowable.class), Type.getType(Resumable.class),
                    Type.getType(Object.class)).getDescriptor(),
            false));

    // rethrow
    il.add(new InsnNode(ATHROW));

    return il;
}

From source file:net.sandius.rembulan.compiler.gen.asm.RunMethod.java

License:Apache License

private MethodNode emitRunMethod(String methodName, Type returnType, BytecodeEmitVisitor visitor,
        List<BasicBlock> blocks, boolean sub) {
    MethodNode node = new MethodNode(ACC_PRIVATE, methodName, methodType(returnType).getDescriptor(), null,
            throwsExceptions());/*  w  w  w  . ja  v a2 s .c  o m*/

    InsnList insns = node.instructions;

    LabelNode l_begin = new LabelNode();
    LabelNode l_end = new LabelNode();

    visitor.visitBlocks(blocks);

    InsnList prefix = new InsnList();
    InsnList suffix = new InsnList();

    final LabelNode l_head;
    final List<LabelNode> els = new ArrayList<>();
    if (sub) {
        assert (!blocks.isEmpty());
        for (int i = blocks.size() - 1; i >= 0; i--) {
            BasicBlock blk = blocks.get(i);
            LabelNode l = visitor.labels.get(blk.label());
            assert (l != null);
            els.add(l);
        }
        l_head = visitor.labels.get(blocks.get(0).label());
    } else {
        l_head = new LabelNode();
        els.add(l_head);
    }

    assert (l_head != null);

    if (visitor.isResumable()) {
        LabelNode l_error_state = new LabelNode();
        LabelNode l_handler_begin = new LabelNode();

        List<LabelNode> rls = visitor.resumptionLabels();

        assert (!rls.isEmpty() || !els.isEmpty());

        prefix.add(dispatchTable(els, rls, l_error_state));

        final LabelNode l_entry = l_head;

        if (!sub) {
            prefix.add(l_entry);
            prefix.add(ASMUtils.frameSame());
        }

        suffix.add(errorState(l_error_state));
        suffix.add(resumptionHandler(l_handler_begin));

        node.tryCatchBlocks.add(new TryCatchBlockNode(l_entry, l_error_state, l_handler_begin,
                Type.getInternalName(UnresolvedControlThrowable.class)));
    }

    insns.add(l_begin);
    insns.add(prefix);
    insns.add(visitor.instructions());
    insns.add(suffix);
    insns.add(l_end);

    addLocals(node, l_begin, l_end, visitor);

    return node;
}

From source file:net.sandius.rembulan.compiler.gen.asm.RunMethod.java

License:Apache License

private MethodNode emitSegmentedRunMethod(int numOfSegments) {
    MethodNode node = new MethodNode(ACC_PRIVATE, methodName(), methodType().getDescriptor(), null,
            throwsExceptions());/* w  w  w . ja  v  a 2  s  . co  m*/

    InsnList il = node.instructions;

    int lvOffset = slotOffset() + numOfRegisters();

    int lv_rpp = lvOffset + 0;
    int lv_methodIdx = lvOffset + 1;
    int lv_jmpIdx = lvOffset + 2;
    int lv_stateIdx = lvOffset + 3;
    int lv_savedState = lvOffset + 4;

    LabelNode l_top = new LabelNode();
    LabelNode l_ret = new LabelNode();
    LabelNode l_end = new LabelNode();

    LabelNode l_rpp = new LabelNode();
    LabelNode l_methodIdx = new LabelNode();
    LabelNode l_jmpIdx = new LabelNode();
    LabelNode l_stateIdx = new LabelNode();
    LabelNode l_savedState = new LabelNode();

    il.add(l_top);
    il.add(new FrameNode(F_SAME, 0, null, 0, null));

    // rpp = rp & ((1 << ST_SHIFT_SEGMENT) - 1)
    il.add(new VarInsnNode(ILOAD, LV_RESUME));
    il.add(ASMUtils.loadInt((1 << ST_SHIFT_SEGMENT) - 1));
    il.add(new InsnNode(IAND));
    il.add(new VarInsnNode(ISTORE, lv_rpp));
    il.add(l_rpp);
    il.add(new FrameNode(F_APPEND, 1, new Object[] { Opcodes.INTEGER }, 0, null));

    // methodIdx = rp >>> ST_SHIFT_SEGMENT
    il.add(new VarInsnNode(ILOAD, LV_RESUME));
    il.add(ASMUtils.loadInt(ST_SHIFT_SEGMENT));
    il.add(new InsnNode(IUSHR));
    il.add(new VarInsnNode(ISTORE, lv_methodIdx));
    il.add(l_methodIdx);
    il.add(new FrameNode(F_APPEND, 1, new Object[] { Opcodes.INTEGER }, 0, null));

    // jmpIdx = rpp >>> ST_SHIFT_LABELIDX
    il.add(new VarInsnNode(ILOAD, lv_rpp));
    il.add(ASMUtils.loadInt(ST_SHIFT_LABELIDX));
    il.add(new InsnNode(IUSHR));
    il.add(new VarInsnNode(ISTORE, lv_jmpIdx));
    il.add(l_jmpIdx);
    il.add(new FrameNode(F_APPEND, 1, new Object[] { Opcodes.INTEGER }, 0, null));

    // stateIdx = (rp & ((1 << ST_SHIFT_LABELIDX) - 1)) - jmpIdx
    il.add(new VarInsnNode(ILOAD, LV_RESUME));
    il.add(ASMUtils.loadInt((1 << ST_SHIFT_LABELIDX) - 1));
    il.add(new InsnNode(IAND));
    il.add(new VarInsnNode(ILOAD, lv_jmpIdx));
    il.add(new InsnNode(ISUB));
    il.add(new VarInsnNode(ISTORE, lv_stateIdx));
    il.add(l_stateIdx);
    il.add(new FrameNode(F_APPEND, 1, new Object[] { Opcodes.INTEGER }, 0, null));

    // savedState = null
    il.add(new InsnNode(ACONST_NULL));
    il.add(new VarInsnNode(ASTORE, lv_savedState));
    il.add(l_savedState);
    il.add(new FrameNode(F_APPEND, 1, new Object[] { context.savedStateClassType().getInternalName() }, 0,
            null));

    // switch on methodIdx

    LabelNode l_after = new LabelNode();

    LabelNode l_error = new LabelNode();
    LabelNode[] l_invokes = new LabelNode[numOfSegments];
    for (int i = 0; i < numOfSegments; i++) {
        l_invokes[i] = new LabelNode();
    }

    il.add(new VarInsnNode(ILOAD, lv_methodIdx));
    il.add(new TableSwitchInsnNode(0, numOfSegments - 1, l_error, l_invokes));

    for (int i = 0; i < numOfSegments; i++) {
        il.add(l_invokes[i]);
        il.add(new FrameNode(F_SAME, 0, null, 0, null));
        // push arguments to stack
        il.add(new VarInsnNode(ALOAD, 0));
        il.add(new VarInsnNode(ALOAD, LV_CONTEXT));
        il.add(new VarInsnNode(ILOAD, lv_stateIdx)); // pass stateIdx to the sub-method
        if (context.isVararg()) {
            il.add(new VarInsnNode(ALOAD, LV_VARARGS));
        }
        for (int j = 0; j < numOfRegisters(); j++) {
            il.add(new VarInsnNode(ALOAD, slotOffset() + j));
        }

        il.add(new MethodInsnNode(INVOKESPECIAL, context.thisClassType().getInternalName(), subRunMethodName(i),
                subMethodType().getDescriptor(), false));

        il.add(new VarInsnNode(ASTORE, lv_savedState));
        il.add(new JumpInsnNode(GOTO, l_after));
    }

    // error state
    il.add(errorState(l_error));

    il.add(l_after);
    il.add(new FrameNode(F_SAME, 0, null, 0, null));

    il.add(new VarInsnNode(ALOAD, lv_savedState));
    il.add(new JumpInsnNode(IFNULL, l_ret)); // savedState == null ?

    // continuing: savedState != null

    // FIXME: taken from ResumeMethod -- beware of code duplication!

    il.add(new VarInsnNode(ALOAD, lv_savedState)); // saved state
    il.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(DefaultSavedState.class), "resumptionPoint",
            Type.getMethodDescriptor(Type.INT_TYPE), false)); // resumption point
    il.add(new VarInsnNode(ISTORE, LV_RESUME));

    // registers
    if (context.isVararg() || numOfRegisters() > 0) {
        il.add(new VarInsnNode(ALOAD, lv_savedState));
        il.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(DefaultSavedState.class), "registers",
                Type.getMethodDescriptor(ASMUtils.arrayTypeFor(Object.class)), false));

        int numRegs = numOfRegisters() + (context.isVararg() ? 1 : 0);

        for (int i = 0; i < numRegs; i++) {
            if (i + 1 < numRegs) {
                il.add(new InsnNode(DUP));
            }
            il.add(ASMUtils.loadInt(i));
            il.add(new InsnNode(AALOAD));
            if (i == 0 && context.isVararg()) {
                il.add(new TypeInsnNode(CHECKCAST, ASMUtils.arrayTypeFor(Object.class).getInternalName()));
            }
            il.add(new VarInsnNode(ASTORE, LV_VARARGS + i));
        }
    }

    // loop back to the beginning
    il.add(new JumpInsnNode(GOTO, l_top));

    // got a null, that's the end
    il.add(l_ret);
    il.add(new FrameNode(F_SAME, 0, null, 0, null));
    il.add(new InsnNode(RETURN));

    il.add(l_end);

    // add local variables
    node.localVariables.addAll(baseLocals(l_top, l_end));
    node.localVariables
            .add(new LocalVariableNode("rpp", Type.INT_TYPE.getDescriptor(), null, l_rpp, l_ret, lv_rpp));
    node.localVariables.add(new LocalVariableNode("methodIdx", Type.INT_TYPE.getDescriptor(), null, l_methodIdx,
            l_ret, lv_methodIdx));
    node.localVariables.add(
            new LocalVariableNode("jmpIdx", Type.INT_TYPE.getDescriptor(), null, l_jmpIdx, l_ret, lv_jmpIdx));
    node.localVariables.add(new LocalVariableNode("stateIdx", Type.INT_TYPE.getDescriptor(), null, l_stateIdx,
            l_ret, lv_stateIdx));
    node.localVariables.add(new LocalVariableNode("savedState", context.savedStateClassType().getDescriptor(),
            null, l_savedState, l_ret, lv_savedState));

    return node;
}

From source file:net.sandius.rembulan.compiler.gen.asm.StaticConstructorMethod.java

License:Apache License

public MethodNode methodNode() {

    MethodNode node = new MethodNode(ACC_STATIC, "<clinit>", "()V", null, null);

    InsnList il = node.instructions;

    LabelNode begin = new LabelNode();
    LabelNode end = new LabelNode();

    il.add(begin);

    if (!context.hasUpvalues()) {
        il.add(new TypeInsnNode(NEW, context.thisClassType().getInternalName()));
        il.add(new InsnNode(DUP));

        il.add(new MethodInsnNode(INVOKESPECIAL, context.thisClassType().getInternalName(), "<init>",
                ctorMethod.methodType().getDescriptor(), false));

        il.add(new FieldInsnNode(PUTSTATIC, context.thisClassType().getInternalName(),
                context.instanceFieldName(), context.thisClassType().getDescriptor()));
    }/* w  w  w  . j  a  va  2s  .  c o m*/

    if (!runMethod.constFields().isEmpty()) {
        for (RunMethod.ConstFieldInstance cfi : runMethod.constFields()) {
            il.add(cfi.instantiateInsns());
        }
    }

    il.add(new InsnNode(RETURN));
    il.add(end);

    return node;
}