下面列出了怎么用org.objectweb.asm.tree.LookupSwitchInsnNode的API类实例代码及写法,或者点击链接到github查看源代码。
@Override
public LookupSwitchInsnNode deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
JsonObject jsonObject = (JsonObject) json;
LabelNode dflt = context.deserialize(jsonObject.get("dflt"), LabelNode.class);
List<Integer> keysList = context.deserialize(jsonObject.get("keys"), List.class);
List<LabelNode> labelsList = context.deserialize(jsonObject.get("labels"), List.class);
int[] keys = new int[keysList.size()];
for(int i=0; i < keys.length; i++){
keys[i] = keysList.get(i);
}
LabelNode[] labels = new LabelNode[labelsList.size()];
for(int i=0; i < labels.length; i++){
labels[i] = labelsList.get(i);
}
return new LookupSwitchInsnNode(dflt, keys, labels);
}
public InsnValue getSwitchValue(AbstractInsnNode insn, InsnValue value) {
if (value.getValue() == null) {
return InsnValue.intValue(-1);
}
int i = (int) value.getValue();
switch (insn.getOpcode()) {
case Opcodes.TABLESWITCH:
TableSwitchInsnNode tsin = (TableSwitchInsnNode) insn;
if (i < tsin.min || i > tsin.max) {
return InsnValue.intValue(-1);
}
return InsnValue.intValue(i);
case Opcodes.LOOKUPSWITCH:
LookupSwitchInsnNode lsin = (LookupSwitchInsnNode) insn;
for (Object o : lsin.keys) {
if (o.equals(i)) {
return InsnValue.intValue(i);
}
}
return InsnValue.intValue(-1);
}
return null;
}
private static Set<AbstractInsnNode> findJumpTargets(final InsnList instructions) {
final Set<AbstractInsnNode> jumpTargets = new HashSet<>();
final ListIterator<AbstractInsnNode> it = instructions.iterator();
while (it.hasNext()) {
final AbstractInsnNode o = it.next();
if (o instanceof JumpInsnNode) {
jumpTargets.add(((JumpInsnNode) o).label);
} else if (o instanceof TableSwitchInsnNode) {
final TableSwitchInsnNode twn = (TableSwitchInsnNode) o;
jumpTargets.add(twn.dflt);
jumpTargets.addAll(twn.labels);
} else if (o instanceof LookupSwitchInsnNode) {
final LookupSwitchInsnNode lsn = (LookupSwitchInsnNode) o;
jumpTargets.add(lsn.dflt);
jumpTargets.addAll(lsn.labels);
}
}
return jumpTargets;
}
/**
* <p>
* This method finds Switch block in a method and processes it
* </p>.
*
* @param scanStartIndex Start index for the scan
* @param scanEndIndex End index for the scan
*/
private void instrumentswitchBlock(int scanStartIndex,
int scanEndIndex) {
for (scanIndexForswitch = scanStartIndex; scanIndexForswitch <= scanEndIndex; scanIndexForswitch++) {
AbstractInsnNode currentInsnNode = insnArr[scanIndexForswitch];
if (currentInsnNode instanceof TableSwitchInsnNode
&& Opcodes.TABLESWITCH == currentInsnNode.getOpcode()) {
processTableSwitchBlock((TableSwitchInsnNode) currentInsnNode);
} else if (currentInsnNode instanceof LookupSwitchInsnNode
&& Opcodes.LOOKUPSWITCH == currentInsnNode.getOpcode()) {
processLookupSwitchBlock((LookupSwitchInsnNode) currentInsnNode);
}
}
}
private static Set<LabelNode> findJumpTargets(final InsnList instructions) {
final Set<LabelNode> jumpTargets = new HashSet<>();
for (AbstractInsnNode o : instructions) {
if (o instanceof JumpInsnNode) {
jumpTargets.add(((JumpInsnNode) o).label);
} else if (o instanceof TableSwitchInsnNode) {
final TableSwitchInsnNode twn = (TableSwitchInsnNode) o;
jumpTargets.add(twn.dflt);
jumpTargets.addAll(twn.labels);
} else if (o instanceof LookupSwitchInsnNode) {
final LookupSwitchInsnNode lsn = (LookupSwitchInsnNode) o;
jumpTargets.add(lsn.dflt);
jumpTargets.addAll(lsn.labels);
}
}
return jumpTargets;
}
@Override
protected void process(MethodContext context, LookupSwitchInsnNode node) {
StringBuilder output = context.output;
output.append(getStart(context)).append("\n ");
for (int i = 0; i < node.labels.size(); ++i) {
output.append(String.format(" %s\n ", getPart(context,
node.keys.get(i),
node.labels.get(i).getLabel())));
}
output.append(String.format(" %s\n ", getDefault(context, node.dflt.getLabel())));
instructionName = "LOOKUPSWITCH_END";
}
@Override
public JsonElement serialize(LookupSwitchInsnNode src, Type typeOfSrc, JsonSerializationContext context) {
JsonObject object = new JsonObject();
object.add("dflt", context.serialize(src.dflt));
object.add("key", context.serialize(src.keys));
object.add("labels", context.serialize(src.labels));
return object;
}
@Override
public boolean accept(AbstractInsnNode t) {
if (!(t instanceof LookupSwitchInsnNode || t instanceof TableSwitchInsnNode))
return false;
if (!opcodeFilter.accept(t))
return false;
for(Filter<Object> filter : filters) {
if (!filter.accept(t))
return false;
}
return true;
}
public static void lookupswitch(final Frame frame) {
LookupSwitchInsnNode lookup = frame.lookupSwitchInsnNode();
LabelNode labelNode = lookup.dflt;
int key = frame.operandStack.popInt();
for (int i = 0; i < lookup.keys.size(); i++) {
int k = lookup.keys.get(i);
if (k == key) {
labelNode = lookup.labels.get(i);
break;
}
}
frame.jump(labelNode);
//Log.opcode(frame.getCurrentOpCode());
}
private static boolean canProtect(InsnList insnList) {
return Stream.of(insnList.toArray()).noneMatch(insn -> insn.getOpcode() == INVOKEDYNAMIC
|| (insn instanceof LdcInsnNode && ((LdcInsnNode) insn).cst instanceof Handle)
|| insn instanceof MultiANewArrayInsnNode
|| insn instanceof LookupSwitchInsnNode
|| insn instanceof TableSwitchInsnNode);
}
public static void lookupswitch(final Frame frame) {
LookupSwitchInsnNode lookup = frame.lookupSwitchInsnNode();
LabelNode labelNode = lookup.dflt;
int key = frame.operandStack.popInt();
for (int i = 0; i < lookup.keys.size(); i++) {
int k = lookup.keys.get(i);
if (k == key) {
labelNode = lookup.labels.get(i);
break;
}
}
frame.jump(labelNode);
//Log.opcode(frame.getCurrentOpCode());
}
private void convertLookupSwitchInsn(LookupSwitchInsnNode insn) {
StackFrame frame = getFrame(insn);
if (units.containsKey(insn)) {
frame.mergeIn(pop());
return;
}
Operand key = popImmediate();
UnitBox dflt = Jimple.v().newStmtBox(null);
List<UnitBox> targets = new ArrayList<UnitBox>(insn.labels.size());
labels.put(insn.dflt, dflt);
for (LabelNode ln : insn.labels) {
UnitBox box = Jimple.v().newStmtBox(null);
targets.add(box);
labels.put(ln, box);
}
List<IntConstant> keys = new ArrayList<IntConstant>(insn.keys.size());
for (Integer i : insn.keys)
keys.add(IntConstant.v(i));
LookupSwitchStmt lss = Jimple.v().newLookupSwitchStmt(key.stackOrValue(),
keys, targets, dflt);
key.addBox(lss.getKeyBox());
frame.in(key);
frame.boxes(lss.getKeyBox());
setUnit(insn, lss);
}
/**
* <p>
* This method Handled the Switch cases of LookupSwitchInsnNode type in a
* method
* </p>.
*
* @param currentTableSwithInsn Type of switch block
*/
@SuppressWarnings("unchecked")
private void handleLookupSwitchCases(
LookupSwitchInsnNode currentTableSwithInsn) {
List<AbstractInsnNode> caseList = currentTableSwithInsn.labels;
LabelNode currentLabel = currentTableSwithInsn.dflt;
List<Integer> casekeys = currentTableSwithInsn.keys;
int totalcaselogs = casekeys.size() * 2;
String[] logMsgs = new String[totalcaselogs];
int[] caseValues = new int[totalcaselogs];
AbstractInsnNode abstractCaseInsnNode[] = new AbstractInsnNode[totalcaselogs];
int index = 0;
for (int i = 0; i < casekeys.size(); i++) {
abstractCaseInsnNode[index] = caseList.get(i);
caseValues[index] = casekeys.get(i);
caseValues[index + 1] = casekeys.get(i);
AbstractInsnNode nextNode = lookNode(caseList,
abstractCaseInsnNode[index], currentLabel);
abstractCaseInsnNode[index + 1] = nextNode;
logMsgs[index] = InstrumentationMessageLoader
.getMessage(MessageConstants.MSG_IN_SWITCHCASE);
logMsgs[index + 1] = InstrumentationMessageLoader
.getMessage(MessageConstants.MSG_OUT_SWITCHCASE);
index += 2;
}
Integer[] lineNumbers = getLineNumbersForSwitchCase(abstractCaseInsnNode);
InsnList[] il = getInsnForswitchCaseBlock(logMsgs, caseValues,
lineNumbers);
addInsnForswitchBlock(il, abstractCaseInsnNode);
}
/**
* <p>
* This method Handled the Switch block of LookupSwitchInsnNode type in a
* method
* </p>.
*
* @param currentTableSwithInsn Type of switch block
*/
private void processLookupSwitchBlock(
LookupSwitchInsnNode currentTableSwithInsn) {
LabelNode currentLabel = currentTableSwithInsn.dflt;
int switchStartIndex = CollectionUtil.getObjectIndexInArray(insnArr,
currentTableSwithInsn);
int switchTargetIndex = CollectionUtil.getObjectIndexInArray(insnArr,
currentLabel);
if (switchTargetIndex > switchStartIndex) {
LOGGER.debug("switch block ended at: " + switchTargetIndex);
switchCount++;
AbstractInsnNode[] ainSwitchBlock = new AbstractInsnNode[] {
currentTableSwithInsn.getPrevious(), currentLabel };
Integer[] lineNumbers = getLineNumbersForSwitchBlock(ainSwitchBlock);
InsnList[] il = getInsnForswitchBlock(switchCount, lineNumbers);
addInsnForswitchBlock(il, ainSwitchBlock);
scanIndexForswitch = switchTargetIndex;
handleLookupSwitchCases(currentTableSwithInsn);
}
}
public CodeBlock lookupswitch(final LabelNode defaultHandler,
final int[] keys,
final LabelNode[] handlers)
{
instructionList.add(new LookupSwitchInsnNode(defaultHandler, keys,
handlers));
return this;
}
public CodeBlock visitLookupSwitchInsn(final LabelNode defaultHandler,
final int[] keys, final LabelNode[] handlers)
{
instructionList.add(new LookupSwitchInsnNode(defaultHandler, keys,
handlers));
return this;
}
public boolean endsWithSwitch() {
return endNode instanceof TableSwitchInsnNode || endNode instanceof LookupSwitchInsnNode;
}
public boolean endsWithSwitch() {
return endNode instanceof TableSwitchInsnNode || endNode instanceof LookupSwitchInsnNode;
}
private void _visitInsn(AbstractInsnNode insn) {
switch (insn.getType()) {
case 0:
visitInsn(insn.getOpcode());
break;
case 1:
IntInsnNode iinsn = (IntInsnNode) insn;
visitIntInsn(iinsn.getOpcode(), iinsn.operand);
break;
case 2:
VarInsnNode vinsn = (VarInsnNode) insn;
visitVarInsn(vinsn.getOpcode(), vinsn.var);
break;
case 3:
TypeInsnNode tinsn = (TypeInsnNode) insn;
visitTypeInsn(tinsn.getOpcode(), tinsn.desc);
break;
case 4:
FieldInsnNode finsn = (FieldInsnNode) insn;
visitFieldInsn(finsn.getOpcode(), finsn.owner, finsn.name, finsn.desc);
break;
case 5:
MethodInsnNode minsn = (MethodInsnNode) insn;
visitMethodInsn(minsn.getOpcode(), minsn.owner, minsn.name, minsn.desc);
break;
case 6:
InvokeDynamicInsnNode idinsn = (InvokeDynamicInsnNode) insn;
visitInvokeDynamicInsn(idinsn.name, idinsn.desc, idinsn.bsm, idinsn.bsmArgs);
break;
case 7:
JumpInsnNode jinsn = (JumpInsnNode) insn;
visitJumpInsn(jinsn.getOpcode(), jinsn.label.getLabel());
break;
case 8:
LabelNode linsn = (LabelNode) insn;
visitLabel(linsn.getLabel());
break;
case 9:
LdcInsnNode ldcinsn = (LdcInsnNode) insn;
visitLdcInsn(ldcinsn.cst);
break;
case 10:
IincInsnNode iiinsn = (IincInsnNode) insn;
visitIincInsn(iiinsn.var, iiinsn.incr);
break;
case 11:
TableSwitchInsnNode tsinsn = (TableSwitchInsnNode) insn;
Label[] tslables = new Label[tsinsn.labels.size()];
for (int i = 0; i < tslables.length; i++) {
tslables[i] = tsinsn.labels.get(i).getLabel();
}
visitTableSwitchInsn(tsinsn.min, tsinsn.max, tsinsn.dflt.getLabel(), tslables);
break;
case 12:
LookupSwitchInsnNode lsinsn = (LookupSwitchInsnNode) insn;
Label[] lslables = new Label[lsinsn.labels.size()];
for (int i = 0; i < lslables.length; i++) {
lslables[i] = lsinsn.labels.get(i).getLabel();
}
int[] lskeys = new int[lsinsn.keys.size()];
for (int i = 0; i < lskeys.length; i++) {
lskeys[i] = lsinsn.keys.get(i);
}
visitLookupSwitchInsn(lsinsn.dflt.getLabel(), lskeys, lslables);
break;
case 13:
MultiANewArrayInsnNode ainsn = (MultiANewArrayInsnNode) insn;
visitMultiANewArrayInsn(ainsn.desc, ainsn.dims);
break;
case 14:
FrameNode fnode = (FrameNode) insn;
switch (fnode.type) {
case -1:
case 0:
visitFrame(fnode.type, fnode.local.size(), fnode.local.toArray(), fnode.stack.size(), fnode.stack.toArray());
break;
case 1:
visitFrame(fnode.type, fnode.local.size(), fnode.local.toArray(), 0, null);
break;
case 2:
visitFrame(fnode.type, fnode.local.size(), null, 0, null);
break;
case 3:
visitFrame(fnode.type, 0, null, 0, null);
break;
case 4:
visitFrame(fnode.type, 0, null, 1, fnode.stack.toArray());
}
break;
case 15:
LineNumberNode lnode = (LineNumberNode) insn;
visitLineNumber(lnode.line, lnode.start.getLabel());
break;
}
}
@SuppressWarnings("deprecation")
private void _visitInsn(AbstractInsnNode insn) {
switch (insn.getType()) {
case 0:
visitInsn(insn.getOpcode());
break;
case 1:
IntInsnNode iinsn = (IntInsnNode) insn;
visitIntInsn(iinsn.getOpcode(), iinsn.operand);
break;
case 2:
VarInsnNode vinsn = (VarInsnNode) insn;
visitVarInsn(vinsn.getOpcode(), vinsn.var);
break;
case 3:
TypeInsnNode tinsn = (TypeInsnNode) insn;
visitTypeInsn(tinsn.getOpcode(), tinsn.desc);
break;
case 4:
FieldInsnNode finsn = (FieldInsnNode) insn;
visitFieldInsn(finsn.getOpcode(), finsn.owner, finsn.name, finsn.desc);
break;
case 5:
MethodInsnNode minsn = (MethodInsnNode) insn;
visitMethodInsn(minsn.getOpcode(), minsn.owner, minsn.name, minsn.desc);
break;
case 6:
InvokeDynamicInsnNode idinsn = (InvokeDynamicInsnNode) insn;
visitInvokeDynamicInsn(idinsn.name, idinsn.desc, idinsn.bsm, idinsn.bsmArgs);
break;
case 7:
JumpInsnNode jinsn = (JumpInsnNode) insn;
visitJumpInsn(jinsn.getOpcode(), jinsn.label.getLabel());
break;
case 8:
LabelNode linsn = (LabelNode) insn;
visitLabel(linsn.getLabel());
break;
case 9:
LdcInsnNode ldcinsn = (LdcInsnNode) insn;
visitLdcInsn(ldcinsn.cst);
break;
case 10:
IincInsnNode iiinsn = (IincInsnNode) insn;
visitIincInsn(iiinsn.var, iiinsn.incr);
break;
case 11:
TableSwitchInsnNode tsinsn = (TableSwitchInsnNode) insn;
Label[] tslables = new Label[tsinsn.labels.size()];
for (int i = 0; i < tslables.length; i++) {
tslables[i] = tsinsn.labels.get(i).getLabel();
}
visitTableSwitchInsn(tsinsn.min, tsinsn.max, tsinsn.dflt.getLabel(), tslables);
break;
case 12:
LookupSwitchInsnNode lsinsn = (LookupSwitchInsnNode) insn;
Label[] lslables = new Label[lsinsn.labels.size()];
for (int i = 0; i < lslables.length; i++) {
lslables[i] = lsinsn.labels.get(i).getLabel();
}
int[] lskeys = new int[lsinsn.keys.size()];
for (int i = 0; i < lskeys.length; i++) {
lskeys[i] = lsinsn.keys.get(i);
}
visitLookupSwitchInsn(lsinsn.dflt.getLabel(), lskeys, lslables);
break;
case 13:
MultiANewArrayInsnNode ainsn = (MultiANewArrayInsnNode) insn;
visitMultiANewArrayInsn(ainsn.desc, ainsn.dims);
break;
case 14:
FrameNode fnode = (FrameNode) insn;
switch (fnode.type) {
case -1:
case 0:
visitFrame(fnode.type, fnode.local.size(), fnode.local.toArray(), fnode.stack.size(), fnode.stack.toArray());
break;
case 1:
visitFrame(fnode.type, fnode.local.size(), fnode.local.toArray(), 0, null);
break;
case 2:
visitFrame(fnode.type, fnode.local.size(), null, 0, null);
break;
case 3:
visitFrame(fnode.type, 0, null, 0, null);
break;
case 4:
visitFrame(fnode.type, 0, null, 1, fnode.stack.toArray());
}
break;
case 15:
LineNumberNode lnode = (LineNumberNode) insn;
visitLineNumber(lnode.line, lnode.start.getLabel());
break;
}
}
@SuppressWarnings("deprecation")
private void _visitInsn(AbstractInsnNode insn) {
switch (insn.getType()) {
case 0:
visitInsn(insn.getOpcode());
break;
case 1:
IntInsnNode iinsn = (IntInsnNode) insn;
visitIntInsn(iinsn.getOpcode(), iinsn.operand);
break;
case 2:
VarInsnNode vinsn = (VarInsnNode) insn;
visitVarInsn(vinsn.getOpcode(), vinsn.var);
break;
case 3:
TypeInsnNode tinsn = (TypeInsnNode) insn;
visitTypeInsn(tinsn.getOpcode(), tinsn.desc);
break;
case 4:
FieldInsnNode finsn = (FieldInsnNode) insn;
visitFieldInsn(finsn.getOpcode(), finsn.owner, finsn.name, finsn.desc);
break;
case 5:
MethodInsnNode minsn = (MethodInsnNode) insn;
visitMethodInsn(minsn.getOpcode(), minsn.owner, minsn.name, minsn.desc);
break;
case 6:
InvokeDynamicInsnNode idinsn = (InvokeDynamicInsnNode) insn;
visitInvokeDynamicInsn(idinsn.name, idinsn.desc, idinsn.bsm, idinsn.bsmArgs);
break;
case 7:
JumpInsnNode jinsn = (JumpInsnNode) insn;
visitJumpInsn(jinsn.getOpcode(), jinsn.label.getLabel());
break;
case 8:
LabelNode linsn = (LabelNode) insn;
visitLabel(linsn.getLabel());
break;
case 9:
LdcInsnNode ldcinsn = (LdcInsnNode) insn;
visitLdcInsn(ldcinsn.cst);
break;
case 10:
IincInsnNode iiinsn = (IincInsnNode) insn;
visitIincInsn(iiinsn.var, iiinsn.incr);
break;
case 11:
TableSwitchInsnNode tsinsn = (TableSwitchInsnNode) insn;
Label[] tslables = new Label[tsinsn.labels.size()];
for (int i = 0; i < tslables.length; i++) {
tslables[i] = tsinsn.labels.get(i).getLabel();
}
visitTableSwitchInsn(tsinsn.min, tsinsn.max, tsinsn.dflt.getLabel(), tslables);
break;
case 12:
LookupSwitchInsnNode lsinsn = (LookupSwitchInsnNode) insn;
Label[] lslables = new Label[lsinsn.labels.size()];
for (int i = 0; i < lslables.length; i++) {
lslables[i] = lsinsn.labels.get(i).getLabel();
}
int[] lskeys = new int[lsinsn.keys.size()];
for (int i = 0; i < lskeys.length; i++) {
lskeys[i] = lsinsn.keys.get(i);
}
visitLookupSwitchInsn(lsinsn.dflt.getLabel(), lskeys, lslables);
break;
case 13:
MultiANewArrayInsnNode ainsn = (MultiANewArrayInsnNode) insn;
visitMultiANewArrayInsn(ainsn.desc, ainsn.dims);
break;
case 14:
FrameNode fnode = (FrameNode) insn;
switch (fnode.type) {
case -1:
case 0:
visitFrame(fnode.type, fnode.local.size(), fnode.local.toArray(), fnode.stack.size(), fnode.stack.toArray());
break;
case 1:
visitFrame(fnode.type, fnode.local.size(), fnode.local.toArray(), 0, null);
break;
case 2:
visitFrame(fnode.type, fnode.local.size(), null, 0, null);
break;
case 3:
visitFrame(fnode.type, 0, null, 0, null);
break;
case 4:
visitFrame(fnode.type, 0, null, 1, fnode.stack.toArray());
}
break;
case 15:
LineNumberNode lnode = (LineNumberNode) insn;
visitLineNumber(lnode.line, lnode.start.getLabel());
break;
}
}
private void makeTypedSwitchGetterSetter(TypeImpl featureRangeType) {
List<FeatureImpl> features = type.getFeaturesSharingRange(featureRangeType);
if (null == features || features.size() == 0) {
return;
}
final int nbrFeats = features.size();
String rangeName = featureRangeType.isArray() ? ((TypeImplArray) featureRangeType).getComponentType().getName() + "Array" : featureRangeType.getShortName();
String javaDesc = featureRangeType.getJavaDescriptor();
// these two are for the method calls to the actual getters/setters
String getterJavaDesc = "()" + javaDesc;
String setterJavaDesc = "(" + javaDesc + ")V";
LabelNode[] labelNodesGet = new LabelNode[nbrFeats];
LabelNode[] labelNodesSet = new LabelNode[nbrFeats];
int[] keys = new int[nbrFeats];
for (int i = 0; i < nbrFeats; i++) {
labelNodesGet[i] = new LabelNode(new Label());
labelNodesSet[i] = new LabelNode(new Label());
keys[i] = features.get(i).getOffsetForGenerics();
}
Arrays.sort(keys);
LabelNode defaultLabelNodeGet = new LabelNode(new Label());
LabelNode defaultLabelNodeSet = new LabelNode(new Label());
for (boolean isGet : GET_SET) {
MethodNode mn = new MethodNode(ASM5, ACC_PUBLIC,
"_" + (isGet ? "get" : "set") + rangeName, // _ avoids name collision with other getters/setters
isGet ? ("(I)" + javaDesc) :
("(I" + javaDesc + ")V"), null, null);
InsnList il = mn.instructions;
il.add(new VarInsnNode(ILOAD, 1)); // load the switch int
il.add(new LookupSwitchInsnNode(isGet ? defaultLabelNodeGet : defaultLabelNodeSet,
keys,
isGet ? labelNodesGet : labelNodesSet));
for (int i = 0; i < nbrFeats; i++) {
final FeatureImpl fi = features.get(i);
il.add((isGet ? labelNodesGet : labelNodesSet)[i]);
il.add(new FrameNode(F_SAME, 0, null, 0, null));
il.add(new VarInsnNode(ALOAD, 0)); // load this
if (isGet) {
il.add(new MethodInsnNode(INVOKEVIRTUAL, typeJavaClassName, fi.getGetterSetterName(GET), getterJavaDesc, false));
il.add(new InsnNode(getReturnInst(fi)));
} else {
// setter - here we might insert code to do index corruption fixup
il.add(new VarInsnNode(getLoadInst(fi), 2)); // load the value or value ref
il.add(new MethodInsnNode(INVOKEVIRTUAL, typeJavaClassName, fi.getGetterSetterName(SET), setterJavaDesc, false));
il.add(new InsnNode(RETURN));
}
}
// default - throw
il.add(isGet? defaultLabelNodeGet : defaultLabelNodeSet);
il.add(new FrameNode(F_SAME, 0, null, 0, null));
il.add(new TypeInsnNode(NEW, CAS_RUN_EX));
il.add(new InsnNode(DUP));
il.add(new LdcInsnNode("INAPPROP_FEAT_X"));
il.add(new MethodInsnNode(INVOKESPECIAL, CAS_RUN_EX, "<init>", "(Ljava/lang/String;)V", false));
il.add(new InsnNode(ATHROW));
boolean is2slotValue = featureRangeType.isLongOrDouble();
mn.maxStack = 3; // for throw
mn.maxLocals = isGet ? 2 : (is2slotValue ? 4 : 3);
cn.methods.add(mn);
}
}