InstructionHandle rewriteStore(MethodGen m, InstructionList il, InstructionHandle i, int maxLocals, String localClassName) { LocalVariableInstruction curr = (LocalVariableInstruction) (i .getInstruction()); Type type = mtab.getLocalType(m, curr, i.getPosition()); if (type == null) { return i; } String name = mtab.getLocalName(m, curr, i.getPosition()); String fieldName = MethodTable.generatedLocalName(type, name); i.setInstruction(new ALOAD(maxLocals)); i = i.getNext(); if (type.equals(Type.LONG) || type.equals(Type.DOUBLE)) { il.insert(i, new DUP_X2()); il.insert(i, new POP()); } else { il.insert(i, new SWAP()); } i = il.insert(i, ins_f.createFieldAccess(localClassName, fieldName, type, Constants.PUTFIELD)); return i; }
void removeUnusedLocals(Method mOrig, MethodGen m) { InstructionList il = m.getInstructionList(); InstructionHandle[] ins = il.getInstructionHandles(); for (int i = 0; i < ins.length; i++) { Instruction in = ins[i].getInstruction(); if (in instanceof LocalVariableInstruction) { LocalVariableInstruction curr = (LocalVariableInstruction) in; if (mtab.getLocal(m, curr, ins[i].getPosition()) != null && curr.getIndex() < m.getMaxLocals() - 5 && !mtab.isLocalUsedInInlet(mOrig, curr.getIndex())) { if (curr instanceof IINC) { ins[i].setInstruction(new NOP()); } else if (curr instanceof LSTORE || curr instanceof DSTORE) { ins[i].setInstruction(new POP2()); } else if (curr instanceof StoreInstruction) { ins[i].setInstruction(new POP()); } else if (curr instanceof ALOAD) { ins[i].setInstruction(new ACONST_NULL()); } else if (curr instanceof FLOAD) { ins[i].setInstruction(new FCONST((float) 0.0)); } else if (curr instanceof ILOAD) { ins[i].setInstruction(new ICONST(0)); } else if (curr instanceof DLOAD) { ins[i].setInstruction(new DCONST(0.0)); } else if (curr instanceof LLOAD) { ins[i].setInstruction(new LCONST(0L)); } else { System.out.println("unhandled ins in " + "removeUnusedLocals: " + curr); System.exit(1); } } } } }
void insertReturnPop(Method m, InstructionList il) { Type returnType = m.getReturnType(); if (returnType.equals(Type.DOUBLE) || returnType.equals(Type.LONG)) { il.append(new POP2()); } else if (returnType.equals(Type.VOID)) { // do nothing } else { il.append(new POP()); } }
InstructionList getAndRemoveStoreIns(InstructionList il, InstructionHandle i) { int netto_stack_inc = 0; InstructionHandle storeStart = i; do { if (i == null) { // Could not find store sequence. return null; } int inc = i.getInstruction().produceStack(cpg) - i.getInstruction().consumeStack(cpg); netto_stack_inc += inc; i = i.getNext(); } while (netto_stack_inc >= 0); if (i == null) { // may happen if the result is used like, for instance: // return f().clone(); // No store sequence, so this is wrong as well. return null; } Instruction store = i.getPrev().getInstruction(); if (store instanceof ReturnInstruction) { return null; } if (store instanceof POP || store instanceof POP2) { return null; } InstructionList result = new InstructionList(); InstructionHandle ip = storeStart; do { result.append(ip.getInstruction()); ip = ip.getNext(); } while (ip != i); deleteIns(il, storeStart, ip.getPrev(), ip); return result; }
@SuppressWarnings("unused") // Called using reflection private Instruction createInstructionPop(Element inst) throws IllegalXMLVMException { return new POP(); }
/** * <<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() )); }