public void registerInstructionHandle(InstructionHandle ih) { if (currentIds.size() == 0) return; for (Integer currentID : currentIds) { mapID2InstructionHandle.put(currentID, ih); List<BranchInstruction> l = mapID2BranchInstructions.get(currentID); if (l != null) { // We encountered some branch instructions earlier before we // registered this instruction handle for (BranchInstruction bi : l) { bi.setTarget(ih); } mapID2BranchInstructions.remove(currentID); } } currentIds.clear(); }
public void start() { if (!_mg.isAbstract() && !_mg.isNative()) { for (InstructionHandle ih = _mg.getInstructionList().getStart(); ih != null; ih = ih .getNext()) { Instruction i = ih.getInstruction(); if (i instanceof BranchInstruction) { branch_map.put(i, ih); // memorize container } if (ih.hasTargeters()) { if (i instanceof BranchInstruction) { _out.println(" InstructionHandle ih_" + ih.getPosition() + ";"); } else { _out.print(" InstructionHandle ih_" + ih.getPosition() + " = "); } } else { _out.print(" "); } if (!visitInstruction(i)) { i.accept(this); } } updateBranchTargets(); updateExceptionHandlers(); } }
private void updateBranchTargets() { for (Iterator i = branches.iterator(); i.hasNext();) { BranchInstruction bi = (BranchInstruction) i.next(); BranchHandle bh = (BranchHandle) branch_map.get(bi); int pos = bh.getPosition(); String name = bi.getName() + "_" + pos; int t_pos = bh.getTarget().getPosition(); _out.println(" " + name + ".setTarget(ih_" + t_pos + ");"); if (bi instanceof Select) { InstructionHandle[] ihs = ((Select) bi).getTargets(); for (int j = 0; j < ihs.length; j++) { t_pos = ihs[j].getPosition(); _out.println(" " + name + ".setTarget(" + j + ", ih_" + t_pos + ");"); } } } }
/** * Inject common exception catch blocks */ public void injectCommonExceptionCatchBlock(InstructionList il, MethodGen method, int variableIndex) { il.append(new INSTANCEOF(constantsPool.addClass(new ObjectType("java.lang.RuntimeException")))); BranchInstruction b1 = InstructionFactory.createBranchInstruction(Constants.IFEQ, null); il.append(b1); il.append(InstructionFactory.createLoad(Type.OBJECT, variableIndex)); il.append(factory.createCheckCast(new ObjectType("java.lang.RuntimeException"))); il.append(InstructionConstants.ATHROW); InstructionHandle ih1 = il.append(InstructionFactory.createLoad(Type.OBJECT, variableIndex)); il.append(new INSTANCEOF(constantsPool.addClass(new ObjectType("java.lang.Error")))); BranchInstruction b2 = InstructionFactory.createBranchInstruction(Constants.IFEQ, null); il.append(b2); il.append(InstructionFactory.createLoad(Type.OBJECT, variableIndex)); il.append(factory.createCheckCast(new ObjectType("java.lang.Error"))); il.append(InstructionConstants.ATHROW); InstructionHandle ih2 = il.append(InstructionFactory.createLoad(Type.OBJECT, variableIndex)); il.append(factory.createInvoke("java.lang.Throwable", "printStackTrace", Type.VOID, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); il.append(factory.createNew("org.codehaus.jremoting.client.InvocationException")); il.append(InstructionConstants.DUP); il.append(factory.createNew("java.lang.StringBuffer")); il.append(InstructionConstants.DUP); il.append(new PUSH(constantsPool, "Should never get here: ")); il.append(factory.createInvoke("java.lang.StringBuffer", "<init>", Type.VOID, new Type[]{Type.STRING}, Constants.INVOKESPECIAL)); il.append(InstructionFactory.createLoad(Type.OBJECT, variableIndex)); il.append(factory.createInvoke("java.lang.Throwable", "getMessage", Type.STRING, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); il.append(factory.createInvoke("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[]{Type.STRING}, Constants.INVOKEVIRTUAL)); il.append(factory.createInvoke("java.lang.StringBuffer", "toString", Type.STRING, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); il.append(factory.createInvoke("org.codehaus.jremoting.client.InvocationException", "<init>", Type.VOID, new Type[]{Type.STRING}, Constants.INVOKESPECIAL)); il.append(InstructionConstants.ATHROW); b1.setTarget(ih1); b2.setTarget(ih2); }
public void registerBranchInstruction(BranchInstruction g, int id) { InstructionHandle ih = mapID2InstructionHandle.get(id); if (ih != null) { // Instruction handle was registered before g.setTarget(ih); return; } // We haven't seen the instruction handle yet. Remember this branch // instruction List<BranchInstruction> l = mapID2BranchInstructions.get(id); if (l == null) l = new ArrayList<BranchInstruction>(); l.add(g); mapID2BranchInstructions.put(id, l); }
@SuppressWarnings("unused") // Called using reflection private Instruction createInstructionGoto(Element inst) { int id = Integer.parseInt(inst.getAttributeValue("label")); BranchInstruction bi = new GOTO(null); instructionHandlerManager.registerBranchInstruction(bi, id); return bi; }
@SuppressWarnings("unused") // Called using reflection private Instruction createInstructionIf_acmpne(Element inst) { int id = Integer.parseInt(inst.getAttributeValue("label")); BranchInstruction bi = new IF_ACMPNE(null); instructionHandlerManager.registerBranchInstruction(bi, id); return bi; }
@SuppressWarnings("unused") // Called using reflection private Instruction createInstructionIf_icmplt(Element inst) { int id = Integer.parseInt(inst.getAttributeValue("label")); BranchInstruction bi = new IF_ICMPLT(null); instructionHandlerManager.registerBranchInstruction(bi, id); return bi; }
@SuppressWarnings("unused") // Called using reflection private Instruction createInstructionIf_icmpgt(Element inst) { int id = Integer.parseInt(inst.getAttributeValue("label")); BranchInstruction bi = new IF_ICMPGT(null); instructionHandlerManager.registerBranchInstruction(bi, id); return bi; }
@SuppressWarnings("unused") // Called using reflection private Instruction createInstructionIf_icmpge(Element inst) { int id = Integer.parseInt(inst.getAttributeValue("label")); BranchInstruction bi = new IF_ICMPGE(null); instructionHandlerManager.registerBranchInstruction(bi, id); return bi; }
@SuppressWarnings("unused") // Called using reflection private Instruction createInstructionIf_icmple(Element inst) { int id = Integer.parseInt(inst.getAttributeValue("label")); BranchInstruction bi = new IF_ICMPLE(null); instructionHandlerManager.registerBranchInstruction(bi, id); return bi; }
@SuppressWarnings("unused") // Called using reflection private Instruction createInstructionIf_icmpne(Element inst) { int id = Integer.parseInt(inst.getAttributeValue("label")); BranchInstruction bi = new IF_ICMPNE(null); instructionHandlerManager.registerBranchInstruction(bi, id); return bi; }
@SuppressWarnings("unused") // Called using reflection private Instruction createInstructionIfeq(Element inst) { int id = Integer.parseInt(inst.getAttributeValue("label")); BranchInstruction bi = new IFEQ(null); instructionHandlerManager.registerBranchInstruction(bi, id); return bi; }
@SuppressWarnings("unused") // Called using reflection private Instruction createInstructionIfne(Element inst) { int id = Integer.parseInt(inst.getAttributeValue("label")); BranchInstruction bi = new IFNE(null); instructionHandlerManager.registerBranchInstruction(bi, id); return bi; }
private byte[] getCodeBytes(Method m, int start, int end) { byte[] code = m.getCode().getCode(); byte[] bytes = new byte[end - start]; System.arraycopy(code, start, bytes, 0, end - start); try { ByteSequence sequence = new ByteSequence(code); while ((sequence.available() > 0) && (sequence.getIndex() < start)) { Instruction.readInstruction(sequence); } int pos; while (sequence.available() > 0 && ((pos = sequence.getIndex()) < end)) { Instruction ins = Instruction.readInstruction(sequence); if ((ins instanceof BranchInstruction) && !(ins instanceof TABLESWITCH) && !(ins instanceof LOOKUPSWITCH)) { BranchInstruction bi = (BranchInstruction) ins; int offset = bi.getIndex(); int target = offset + pos; if (target >= end) { // or target < start ?? byte hiByte = (byte) ((target >> 8) & 0x000000FF); byte loByte = (byte) (target & 0x000000FF); bytes[pos + bi.getLength() - 2 - start] = hiByte; bytes[pos + bi.getLength() - 1 - start] = loByte; } } } } catch (IOException ioe) { } return bytes; }
/** * Determine whether or not the given instruction is a control flow merge. * * @param handle * the instruction * @return true if the instruction is a control merge, false otherwise */ private static boolean isMerge(InstructionHandle handle) { if (handle.hasTargeters()) { // Check all targeters of this handle to see if any // of them are branches. If so, the instruction is a merge. InstructionTargeter[] targeterList = handle.getTargeters(); for (InstructionTargeter targeter : targeterList) { if (targeter instanceof BranchInstruction) return true; } } return false; }
/** * Create interface method's args. * * @param numberOfArguments the number of arguments. * @param il an instruction list * @param variableIndex a varible index. * @param paramTypes parameter types * @param generatedClassName the generated class name. */ private void createInterfaceMethodArgs(int numberOfArguments, InstructionList il, int variableIndex, Class[] paramTypes, String generatedClassName) { Type previousType = null; int loadIndex = 0; for (int i = 0; i < numberOfArguments; i++) { // assigning the obj ref's il.append(InstructionFactory.createLoad(Type.OBJECT, variableIndex - 1)); il.append(new PUSH(constantsPool, i)); String className = paramTypes[i].getName(); //adjust for any previous wider datatype (double/long) if (previousType != null && (previousType == Type.DOUBLE || previousType == Type.LONG)) { ++loadIndex; } if (paramTypes[i].isPrimitive()) { il.append(factory.createNew(getJavaWrapperClass(className))); il.append(InstructionConstants.DUP); il.append(InstructionFactory.createLoad(getBCELPrimitiveType(className), ++loadIndex)); il.append(factory.createInvoke(getJavaWrapperClass(className), "<init>", Type.VOID, new Type[]{getBCELPrimitiveType(className)}, Constants.INVOKESPECIAL)); il.append(InstructionConstants.AASTORE); } else { //create the static fields for enabling .class calls String encodedFieldName; if (paramTypes[i].isArray()) { int index = className.lastIndexOf('['); if (className.charAt(index + 1) == 'L') { encodedFieldName = "array$" + className.substring(1 + index, className.length() - 1).replace('.', '$'); } else { encodedFieldName = "array$" + className.substring(1 + index, className.length()); } } else { encodedFieldName = "class$" + className.replace('.', '$'); } addField(encodedFieldName); // ******** TODO assign the obj reference il.append(InstructionFactory.createLoad(Type.OBJECT, variableIndex - 1)); il.append(new PUSH(constantsPool, i)); il.append(InstructionFactory.createLoad(Type.OBJECT, ++loadIndex)); il.append(InstructionConstants.AASTORE); // *********TODO assign the class ref's il.append(InstructionFactory.createLoad(Type.OBJECT, variableIndex)); il.append(new PUSH(constantsPool, i)); il.append(factory.createFieldAccess(generatedClassName, encodedFieldName, new ObjectType("java.lang.Class"), Constants.GETSTATIC)); BranchInstruction ifnull = InstructionFactory.createBranchInstruction(Constants.IFNULL, null); il.append(ifnull); il.append(factory.createFieldAccess(generatedClassName, encodedFieldName, new ObjectType("java.lang.Class"), Constants.GETSTATIC)); BranchInstruction goHeadToStoreRef = InstructionFactory.createBranchInstruction(Constants.GOTO, null); il.append(goHeadToStoreRef); InstructionHandle ifnullStartHere = il.append(new PUSH(constantsPool, className)); ifnull.setTarget(ifnullStartHere); il.append(factory.createInvoke(generatedClassName, "class$", new ObjectType("java.lang.Class"), new Type[]{Type.STRING}, Constants.INVOKESTATIC)); il.append(InstructionConstants.DUP); il.append(factory.createFieldAccess(generatedClassName, encodedFieldName, new ObjectType("java.lang.Class"), Constants.PUTSTATIC)); InstructionHandle storeClassRef = il.append(InstructionConstants.AASTORE); goHeadToStoreRef.setTarget(storeClassRef); } previousType = getBCELPrimitiveType(className); } }
public InstructionHandlerManager() { mapID2InstructionHandle = new HashMap<Integer, InstructionHandle>(); mapID2BranchInstructions = new HashMap<Integer, List<BranchInstruction>>(); currentIds = new ArrayList<Integer>(); }
public JavaBuilder(ProtoInfo pi, String classname, String filename) { this.pi = pi; this.p = pi.prototype; this.classname = classname; // what class to inherit from superclassType = p.numparams; if ( p.is_vararg != 0 || superclassType >= SUPERTYPE_VARARGS ) superclassType = SUPERTYPE_VARARGS; for ( int i=0, n=p.code.length; i<n; i++ ) { int inst = p.code[i]; int o = Lua.GET_OPCODE(inst); if ( (o == Lua.OP_TAILCALL) || ((o == Lua.OP_RETURN) && (Lua.GETARG_B(inst) < 1 || Lua.GETARG_B(inst) > 2)) ) { superclassType = SUPERTYPE_VARARGS; break; } } // create class generator cg = new ClassGen(classname, SUPER_NAME_N[superclassType], filename, Constants.ACC_PUBLIC | Constants.ACC_SUPER, null); cp = cg.getConstantPool(); // cg creates constant pool // main instruction lists factory = new InstructionFactory(cg); init = new InstructionList(); main = new InstructionList(); // create the fields for ( int i=0; i<p.upvalues.length; i++ ) { boolean isrw = pi.isReadWriteUpvalue( pi.upvals[i] ); Type uptype = isrw? (Type) TYPE_LOCALUPVALUE: (Type) TYPE_LUAVALUE; FieldGen fg = new FieldGen(0, uptype, upvalueName(i), cp); cg.addField(fg.getField()); } // create the method mg = new MethodGen( Constants.ACC_PUBLIC | Constants.ACC_FINAL, // access flags RETURN_TYPE_N[superclassType], // return type ARG_TYPES_N[superclassType], // argument types ARG_NAMES_N[superclassType], // arg names METH_NAME_N[superclassType], STR_LUAVALUE, // method, defining class main, cp); // initialize the values in the slots initializeSlots(); // initialize branching int nc = p.code.length; targets = new int[nc]; branches = new BranchInstruction[nc]; branchDestHandles = new InstructionHandle[nc]; lastInstrHandles = new InstructionHandle[nc]; }
private void append( BranchInstruction i ) { conditionalSetBeginningOfLua( main.append(i) ); }
/** * A utility method that calculates the successors of a given InstructionHandle * <B>in the same subroutine</B>. That means, a RET does not have any successors * as defined here. A JsrInstruction has its physical successor as its successor * (opposed to its target) as defined here. */ private static InstructionHandle[] getSuccessors(InstructionHandle instruction){ final InstructionHandle[] empty = new InstructionHandle[0]; final InstructionHandle[] single = new InstructionHandle[1]; final InstructionHandle[] pair = new InstructionHandle[2]; Instruction inst = instruction.getInstruction(); if (inst instanceof RET){ return empty; } // Terminates method normally. if (inst instanceof ReturnInstruction){ return empty; } // Terminates method abnormally, because JustIce mandates // subroutines not to be protected by exception handlers. if (inst instanceof ATHROW){ return empty; } // See method comment. if (inst instanceof JsrInstruction){ single[0] = instruction.getNext(); return single; } if (inst instanceof GotoInstruction){ single[0] = ((GotoInstruction) inst).getTarget(); return single; } if (inst instanceof BranchInstruction){ if (inst instanceof Select){ // BCEL's getTargets() returns only the non-default targets, // thanks to Eli Tilevich for reporting. InstructionHandle[] matchTargets = ((Select) inst).getTargets(); InstructionHandle[] ret = new InstructionHandle[matchTargets.length+1]; ret[0] = ((Select) inst).getTarget(); System.arraycopy(matchTargets, 0, ret, 1, matchTargets.length); return ret; } else{ pair[0] = instruction.getNext(); pair[1] = ((BranchInstruction) inst).getTarget(); return pair; } } // default case: Fall through. single[0] = instruction.getNext(); return single; }
public void visitBranchInstruction( BranchInstruction bi ) { BranchHandle bh = (BranchHandle) branch_map.get(bi); int pos = bh.getPosition(); String name = bi.getName() + "_" + pos; if (bi instanceof Select) { Select s = (Select) bi; branches.add(bi); StringBuffer args = new StringBuffer("new int[] { "); int[] matchs = s.getMatchs(); for (int i = 0; i < matchs.length; i++) { args.append(matchs[i]); if (i < matchs.length - 1) { args.append(", "); } } args.append(" }"); _out.print("Select " + name + " = new " + bi.getName().toUpperCase(Locale.ENGLISH) + "(" + args + ", new InstructionHandle[] { "); for (int i = 0; i < matchs.length; i++) { _out.print("null"); if (i < matchs.length - 1) { _out.print(", "); } } _out.println(" }, null);"); } else { int t_pos = bh.getTarget().getPosition(); String target; if (pos > t_pos) { target = "ih_" + t_pos; } else { branches.add(bi); target = "null"; } _out.println(" BranchInstruction " + name + " = _factory.createBranchInstruction(" + "Constants." + bi.getName().toUpperCase(Locale.ENGLISH) + ", " + target + ");"); } if (bh.hasTargeters()) { _out.println(" ih_" + pos + " = il.append(" + name + ");"); } else { _out.println(" il.append(" + name + ");"); } }
@Override public void genSet(Set s, GenScope scope) { String javaClassName = description.getJavaClass(className); SimpleSet setter = (SimpleSet) description.getSetter(className, s.getFeatureName()); assert(setter != null); // constructor setter should be rewritten in a pre-processing step // ObjectType paramType = new ObjectType(setter.getSetter().getParameterTypes().get(0)); Type returnType = Type.VOID; if ( setter.getSetter().getReturnType() != null ) { returnType = computeParamType(setter.getSetter().getReturnType()); // new ObjectType(setter.getSetter().getReturnType()); } InstructionList il = scope.getInstructionList(); InstructionFactory ifact = scope.getInstructionFactory(); Variable realReceptor = scope.getRealVariable(s.getReceptor()); Variable realValue = scope.getRealVariable(s.getValue()); BranchInstruction branchToEnd = InstructionFactory .createBranchInstruction(Constants.GOTO, null); BranchInstruction branchToMonovalued = InstructionFactory .createBranchInstruction(Constants.IFEQ, null); // push value scope.loadVariable(realValue, il); il.append(InstructionConstants.DUP); // check if it is multivalued result il.append(ifact.createInstanceOf(DefaultTypes.Iterable)); // If it is not an iterable goto -> monovalued set il.append(branchToMonovalued); // It is an iterable -> multivalued set // the collection is in queue, get the iterator il.append(ifact.createCheckCast(DefaultTypes.Iterable)); il.append(ifact.createInvoke("java.lang.Iterable", "iterator", new ObjectType("java.util.Iterator"), Type.NO_ARGS, Constants.INVOKEINTERFACE)); // got to check next BranchHandle gotoHasNext = il.append(InstructionFactory.createBranchInstruction(Constants.GOTO, null)); // next object InstructionHandle nextElement = il.append(InstructionConstants.DUP); il.append(ifact.createInvoke("java.util.Iterator", "next", Type.OBJECT, Type.NO_ARGS, Constants.INVOKEINTERFACE)); genMonovaluedSet(scope, javaClassName, setter.getSetter(), il, ifact, realReceptor, returnType); // check if hasNext, but before dup the iterator gotoHasNext.setTarget( il.append(InstructionConstants.DUP) ); il.append(ifact.createInvoke("java.util.Iterator", "hasNext", Type.BOOLEAN, Type.NO_ARGS, Constants.INVOKEINTERFACE)); il.append(InstructionFactory.createBranchInstruction(Constants.IFNE, nextElement)); // Pop the iterator, that it is no longer needed il.append(InstructionConstants.POP); // end of iteration // Skip monovalued set il.append(branchToEnd); // target of monovalued branchToMonovalued.setTarget(il.append(InstructionConstants.NOP)); genMonovaluedSet(scope, javaClassName, setter.getSetter(), il, ifact, realReceptor, returnType); branchToEnd.setTarget(il.append(InstructionConstants.NOP)); }
/** * <<GET_IMODEL(THIS)>> * ALOAD !!#receptor_variable!! * LDC <<featureName>> * INVOKEINTERFACE getFeature */ @Override public void generate(GenScope scope) { InstructionList il = scope.getInstructionList(); InstructionFactory ifact = scope.getInstructionFactory(); ConstantPoolGen cpg = scope.getConstantPool(); Variable realReceptor = scope.getRealVariable(this.receptor); LocalVariableGen lvg = scope.newLocalVariable(this, Type.OBJECT); // generate model access scope.generateGetModel(realReceptor); il.append(new DUP()); // for later calls of get/method calls (problem if I put the generateGetModel directly, not using the dup optimize, why?) // push receptor // push featureName scope.loadVariable(realReceptor, il); lvg.setStart(il.append(new LDC(cpg.addString(featureName)))); if ( kind == GetKind.PLAIN_GET ) { appendGetFeature(il, ifact); il.append(InstructionFactory.SWAP); il.append(InstructionFactory.POP); // I should swap, and then pop... // il.append(new POP()); } else { BranchInstruction branchToCall = InstructionFactory .createBranchInstruction(Constants.IFEQ, null); BranchInstruction branchToEnd = InstructionFactory .createBranchInstruction(Constants.GOTO, null); // hasFeature(f) // ifeq (jump if value == 0) appendHasFeature(il, ifact); lvg.setStart(il.append(branchToCall)); // push receptor // push featureName // get & jump to the end /* scope.loadVariable(realReceptor, il); lvg.setStart(il.append(new LDC(cpg.addString(featureName)))); */ if ( isStreamingMode(scope) ) { appendContinuableGetFeature(scope, realReceptor, il, ifact, cpg); } else { scope.loadVariable(realReceptor, il); il.append(new LDC(cpg.addString(featureName))); appendGetFeature(il, ifact); // branchToEnd.setTarget(appendGetFeature(il, ifact)); } il.append(branchToEnd); // push receptor // push featureName // methodCall branchToCall.setTarget( il.append(InstructionConstants.NOP) ); // label for this part //scope.loadVariable(realReceptor, il); // lvg.setStart(il.append(new LDC(cpg.addString(featureName)))); lvg.setStart(il.append(InstructionConstants.POP)); // remove IModel appendMethodCall(scope, il, ifact); // NOP-end branchToEnd.setTarget( il.append(InstructionConstants.NOP) ); } // store result il.append(new ASTORE( lvg.getIndex() )); }
public void visitCode(Code code) { MethodGen mg = new MethodGen(_method, clazzname, cp); InstructionList il = mg.getInstructionList(); InstructionHandle[] ihs = il.getInstructionHandles(); LocalVariableGen[] lvs = mg.getLocalVariables(); CodeExceptionGen[] ehs = mg.getExceptionHandlers(); for (int i = 0; i < lvs.length; i++) { LocalVariableGen l = lvs[i]; out.println(" // local variable " + l.getIndex() + " is \"" + l.getName() + "\" " + l.getType() + " from " + l.getStart().getPosition() + " to " + l.getEnd().getPosition()); } out.print("\n"); for (int i = 0; i < ihs.length; i++) { InstructionHandle ih = ihs[i]; Instruction inst = ih.getInstruction(); out.print(" " + ih.getPosition()); if (inst instanceof BranchInstruction) { if (inst instanceof Select) { // Special cases LOOKUPSWITCH and // TABLESWITCH Select s = (Select) inst; int[] matchs = s.getMatchs(); InstructionHandle[] targets = s.getTargets(); if (s instanceof TABLESWITCH) { out.println(" tableswitch " + matchs[0] + " " + matchs[matchs.length - 1]); for (int j = 0; j < targets.length; j++) out.println(" " + targets[j].getPosition()); } else { // LOOKUPSWITCH out.println(" lookupswitch "); for (int j = 0; j < targets.length; j++) out.println(" " + matchs[j] + " : " + targets[j].getPosition()); } out.println(" default: " + s.getTarget()); // Applies // for // both } else { BranchInstruction bi = (BranchInstruction) inst; ih = bi.getTarget(); //str = get(ih); out.println(" " + Constants.OPCODE_NAMES[bi.getOpcode()] + " " + ih); } } else out.println(" " + inst.toString(cp.getConstantPool())); } out.print("\n"); for (int i = 0; i < ehs.length; i++) { CodeExceptionGen c = ehs[i]; ObjectType caught = c.getCatchType(); String class_name = (caught == null) ? // catch any exception, used // when compiling finally "all" : caught.getClassName().replace('.', '/'); out.println(" catch " + class_name + " from " + c.getStartPC().getPosition() + " to " + c.getEndPC().getPosition() + " using " + c.getHandlerPC().getPosition()); } }
/** * A utility method that calculates the successors of a given InstructionHandle * <B>in the same subroutine</B>. That means, a RET does not have any successors * as defined here. A JsrInstruction has its physical successor as its successor * (opposed to its target) as defined here. */ private static InstructionHandle[] getSuccessors(InstructionHandle instruction){ Instruction inst = instruction.getInstruction(); if (inst instanceof RET){ return empty; } // Terminates method normally. if (inst instanceof ReturnInstruction){ return empty; } // Terminates method abnormally, because JustIce mandates // subroutines not to be protected by exception handlers. if (inst instanceof ATHROW){ return empty; } final InstructionHandle[] single = new InstructionHandle[1]; // See method comment. if (inst instanceof JsrInstruction){ single[0] = instruction.getNext(); return single; } if (inst instanceof GotoInstruction){ single[0] = ((GotoInstruction) inst).getTarget(); return single; } if (inst instanceof BranchInstruction){ if (inst instanceof Select){ // BCEL's getTargets() returns only the non-default targets, // thanks to Eli Tilevich for reporting. InstructionHandle[] matchTargets = ((Select) inst).getTargets(); InstructionHandle[] ret = new InstructionHandle[matchTargets.length+1]; ret[0] = ((Select) inst).getTarget(); System.arraycopy(matchTargets, 0, ret, 1, matchTargets.length); return ret; } else{ final InstructionHandle[] pair = new InstructionHandle[2]; pair[0] = instruction.getNext(); pair[1] = ((BranchInstruction) inst).getTarget(); return pair; } } // default case: Fall through. single[0] = instruction.getNext(); return single; }
/** * A utility method that calculates the successors of a given InstructionHandle * That means, a RET does have successors as defined here. * A JsrInstruction has its target as its successor * (opposed to its physical successor) as defined here. */ // TODO: implement caching! private InstructionHandle[] _getSuccessors(){ final InstructionHandle[] empty = new InstructionHandle[0]; final InstructionHandle[] single = new InstructionHandle[1]; final InstructionHandle[] pair = new InstructionHandle[2]; Instruction inst = getInstruction().getInstruction(); if (inst instanceof RET){ Subroutine s = subroutines.subroutineOf(getInstruction()); if (s==null){ //return empty; // RET in dead code. "empty" would be the correct answer, but we know something about the surrounding project... throw new AssertionViolatedException("Asking for successors of a RET in dead code?!"); } //TODO: remove throw new AssertionViolatedException("DID YOU REALLY WANT TO ASK FOR RET'S SUCCS?"); /* InstructionHandle[] jsrs = s.getEnteringJsrInstructions(); InstructionHandle[] ret = new InstructionHandle[jsrs.length]; for (int i=0; i<jsrs.length; i++){ ret[i] = jsrs[i].getNext(); } return ret; */ } // Terminates method normally. if (inst instanceof ReturnInstruction){ return empty; } // Terminates method abnormally, because JustIce mandates // subroutines not to be protected by exception handlers. if (inst instanceof ATHROW){ return empty; } // See method comment. if (inst instanceof JsrInstruction){ single[0] = ((JsrInstruction) inst).getTarget(); return single; } if (inst instanceof GotoInstruction){ single[0] = ((GotoInstruction) inst).getTarget(); return single; } if (inst instanceof BranchInstruction){ if (inst instanceof Select){ // BCEL's getTargets() returns only the non-default targets, // thanks to Eli Tilevich for reporting. InstructionHandle[] matchTargets = ((Select) inst).getTargets(); InstructionHandle[] ret = new InstructionHandle[matchTargets.length+1]; ret[0] = ((Select) inst).getTarget(); System.arraycopy(matchTargets, 0, ret, 1, matchTargets.length); return ret; } else{ pair[0] = getInstruction().getNext(); pair[1] = ((BranchInstruction) inst).getTarget(); return pair; } } // default case: Fall through. single[0] = getInstruction().getNext(); return single; }