protected BasicBlock makeBlock(int pos) { return new TypedBlock(pos); }
private void fixTypes(byte[] code, TypedBlock[] blocks) throws NotFoundException, BadBytecode { ArrayList preOrder = new ArrayList(); int len = blocks.length; int index = 0; for (int i = 0; i < len; i++) { TypedBlock block = blocks[i]; if (block.alreadySet()) { // if block is not dead code int n = block.localsTypes.length; for (int j = 0; j < n; j++) index = block.localsTypes[j].dfs(preOrder, index, classPool); n = block.stackTop; for (int j = 0; j < n; j++) index = block.stackTypes[j].dfs(preOrder, index, classPool); } } }
int i = 1; try { while ((i = descToTag(methodDesc, i, ++n, locals)) > 0) if (locals[n].is2WordType()) locals[++n] = TypeTag.TOP;
public StackMap toStackMap2(ConstPool cp, TypedBlock[] blocks) { StackMap.Writer writer = new StackMap.Writer(); int n = blocks.length; // should be > 0 boolean[] effective = new boolean[n]; TypedBlock prev = blocks[0]; // Is the first instruction a branch target? effective[0] = prev.incoming > 0; int num = effective[0] ? 1 : 0; for (int i = 1; i < n; i++) { TypedBlock bb = blocks[i]; if (effective[i] = isTarget(bb, blocks[i - 1])) { bb.resetNumLocals(); prev = bb; num++; } } if (num == 0) return null; writer.write16bit(num); for (int i = 0; i < n; i++) if (effective[i]) writeStackFrame(writer, cp, blocks[i].position, blocks[i]); return writer.toStackMap(cp); }
/** * Computes the stack map table of the given method and returns it. * It returns null if the given method does not have to have a * stack map table or it includes JSR. */ public static StackMapTable make(ClassPool classes, MethodInfo minfo) throws BadBytecode { CodeAttribute ca = minfo.getCodeAttribute(); if (ca == null) return null; TypedBlock[] blocks; try { blocks = TypedBlock.makeBlocks(minfo, ca, true); } catch (BasicBlock.JsrBytecode e) { return null; } if (blocks == null) return null; MapMaker mm = new MapMaker(classes, minfo, ca); try { mm.make(blocks, ca.getCode()); } catch (BadBytecode bb) { throw new BadBytecode(minfo, bb); } return mm.toStackMap(blocks); }
public MapMaker(ClassPool classes, MethodInfo minfo, CodeAttribute ca) { super(classes, minfo.getConstPool(), ca.getMaxStack(), ca.getMaxLocals(), TypedBlock.getRetType(minfo.getDescriptor())); }
private void recordStackMap0(TypedBlock target, int st, TypeData[] tStackTypes) throws BadBytecode { int n = localsTypes.length; TypeData[] tLocalsTypes = TypeData.make(n); int k = recordTypeData(n, localsTypes, tLocalsTypes); target.setStackMap(st, tStackTypes, k, tLocalsTypes); }
protected void toString2(StringBuffer sbuf) { super.toString2(sbuf); sbuf.append(",\n stack={"); printTypes(sbuf, stackTop, stackTypes); sbuf.append("}, locals={"); printTypes(sbuf, numLocals, localsTypes); sbuf.append('}'); }
/** * Divides the method body into basic blocks. * The type information of the first block is initialized. * * @param optimize if it is true and the method does not include * branches, this method returns null. */ public static TypedBlock[] makeBlocks(MethodInfo minfo, CodeAttribute ca, boolean optimize) throws BadBytecode { TypedBlock[] blocks = (TypedBlock[])new Maker().make(minfo); if (optimize && blocks.length < 2) if (blocks.length == 0 || blocks[0].incoming == 0) return null; ConstPool pool = minfo.getConstPool(); boolean isStatic = (minfo.getAccessFlags() & AccessFlag.STATIC) != 0; blocks[0].initFirstBlock(ca.getMaxStack(), ca.getMaxLocals(), pool.getClassName(), minfo.getDescriptor(), isStatic, minfo.isConstructor()); return blocks; }
TypeData t = toPrimitiveTag(c); if (t == null) throw new BadBytecode("bad method descriptor: " + desc);
public StackMap toStackMap2(ConstPool cp, TypedBlock[] blocks) { StackMap.Writer writer = new StackMap.Writer(); int n = blocks.length; // should be > 0 boolean[] effective = new boolean[n]; TypedBlock prev = blocks[0]; // Is the first instruction a branch target? effective[0] = prev.incoming > 0; int num = effective[0] ? 1 : 0; for (int i = 1; i < n; i++) { TypedBlock bb = blocks[i]; if (effective[i] = isTarget(bb, blocks[i - 1])) { bb.resetNumLocals(); prev = bb; num++; } } if (num == 0) return null; writer.write16bit(num); for (int i = 0; i < n; i++) if (effective[i]) writeStackFrame(writer, cp, blocks[i].position, blocks[i]); return writer.toStackMap(cp); }
/** * Computes the stack map table for J2ME. * It returns null if the given method does not have to have a * stack map table or it includes JSR. */ public static StackMap make2(ClassPool classes, MethodInfo minfo) throws BadBytecode { CodeAttribute ca = minfo.getCodeAttribute(); if (ca == null) return null; TypedBlock[] blocks; try { blocks = TypedBlock.makeBlocks(minfo, ca, true); } catch (BasicBlock.JsrBytecode e) { return null; } if (blocks == null) return null; MapMaker mm = new MapMaker(classes, minfo, ca); try { mm.make(blocks, ca.getCode()); } catch (BadBytecode bb) { throw new BadBytecode(minfo, bb); } return mm.toStackMap2(minfo.getConstPool(), blocks); }
public MapMaker(ClassPool classes, MethodInfo minfo, CodeAttribute ca) { super(classes, minfo.getConstPool(), ca.getMaxStack(), ca.getMaxLocals(), TypedBlock.getRetType(minfo.getDescriptor())); }
private void recordStackMap0(TypedBlock target, int st, TypeData[] tStackTypes) throws BadBytecode { int n = localsTypes.length; TypeData[] tLocalsTypes = TypeData.make(n); int k = recordTypeData(n, localsTypes, tLocalsTypes); target.setStackMap(st, tStackTypes, k, tLocalsTypes); }
@Override protected void toString2(StringBuffer sbuf) { super.toString2(sbuf); sbuf.append(",\n stack={"); printTypes(sbuf, stackTop, stackTypes); sbuf.append("}, locals={"); printTypes(sbuf, numLocals, localsTypes); sbuf.append('}'); }
/** * Divides the method body into basic blocks. * The type information of the first block is initialized. * * @param optimize if it is true and the method does not include * branches, this method returns null. */ public static TypedBlock[] makeBlocks(MethodInfo minfo, CodeAttribute ca, boolean optimize) throws BadBytecode { TypedBlock[] blocks = (TypedBlock[])new Maker().make(minfo); if (optimize && blocks.length < 2) if (blocks.length == 0 || blocks[0].incoming == 0) return null; ConstPool pool = minfo.getConstPool(); boolean isStatic = (minfo.getAccessFlags() & AccessFlag.STATIC) != 0; blocks[0].initFirstBlock(ca.getMaxStack(), ca.getMaxLocals(), pool.getClassName(), minfo.getDescriptor(), isStatic, minfo.isConstructor()); return blocks; }
TypeData t = toPrimitiveTag(c); if (t == null) throw new BadBytecode("bad method descriptor: " + desc);
private void findDeadCatchers(byte[] code, TypedBlock[] blocks) throws BadBytecode { int len = blocks.length; for (int i = 0; i < len; i++) { TypedBlock block = blocks[i]; if (!block.alreadySet()) { fixDeadcode(code, block); BasicBlock.Catch handler = block.toCatch; if (handler != null) { TypedBlock tb = (TypedBlock)handler.body; if (!tb.alreadySet()) { // tb is a handler that catches only the exceptions // thrown from dead code. recordStackMap(tb, handler.typeIndex); fixDeadcode(code, tb); tb.incoming = 1; } } } } }
public StackMapTable toStackMap(TypedBlock[] blocks) { StackMapTable.Writer writer = new StackMapTable.Writer(32); int n = blocks.length; TypedBlock prev = blocks[0]; int offsetDelta = prev.length; if (prev.incoming > 0) { // the first instruction is a branch target. writer.sameFrame(0); offsetDelta--; } for (int i = 1; i < n; i++) { TypedBlock bb = blocks[i]; if (isTarget(bb, blocks[i - 1])) { bb.resetNumLocals(); int diffL = stackMapDiff(prev.numLocals, prev.localsTypes, bb.numLocals, bb.localsTypes); toStackMapBody(writer, bb, diffL, offsetDelta, prev); offsetDelta = bb.length - 1; prev = bb; } else if (bb.incoming == 0) { // dead code. writer.sameFrame(offsetDelta); offsetDelta = bb.length - 1; prev = bb; } else offsetDelta += bb.length; } return writer.toStackMapTable(cpool); }
/** * Computes the stack map table of the given method and returns it. * It returns null if the given method does not have to have a * stack map table or it includes JSR. */ public static StackMapTable make(ClassPool classes, MethodInfo minfo) throws BadBytecode { CodeAttribute ca = minfo.getCodeAttribute(); if (ca == null) return null; TypedBlock[] blocks; try { blocks = TypedBlock.makeBlocks(minfo, ca, true); } catch (BasicBlock.JsrBytecode e) { return null; } if (blocks == null) return null; MapMaker mm = new MapMaker(classes, minfo, ca); try { mm.make(blocks, ca.getCode()); } catch (BadBytecode bb) { throw new BadBytecode(minfo, bb); } return mm.toStackMap(blocks); }