List of usage examples for org.objectweb.asm.tree InsnList add
public void add(final InsnList insnList)
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; }