public void storeLocal(int pc, int slot) { boolean isupval = pi.isUpvalueAssign(pc, slot); int index = findSlotIndex( slot, isupval ); if (isupval) { boolean isupcreate = pi.isUpvalueCreate(pc, slot); if ( isupcreate ) { append(factory.createInvoke(classname, "newupe", TYPE_LOCALUPVALUE, ARG_TYPES_NONE, Constants.INVOKESTATIC)); append(InstructionConstants.DUP); append(new ASTORE(index)); } else { append(new ALOAD(index)); } append(InstructionConstants.SWAP); append(new PUSH(cp, 0)); append(InstructionConstants.SWAP); append(InstructionConstants.AASTORE); } else { append(new ASTORE(index)); } }
/** * Adds a new JSR or JSR_W that has this subroutine as its target. */ public void addEnteringJsrInstruction(InstructionHandle jsrInst){ if ( (jsrInst == null) || (! (jsrInst.getInstruction() instanceof JsrInstruction))){ throw new AssertionViolatedException("Expecting JsrInstruction InstructionHandle."); } if (localVariable == UNSET){ throw new AssertionViolatedException("Set the localVariable first!"); } else{ // Something is wrong when an ASTORE is targeted that does not operate on the same local variable than the rest of the // JsrInstruction-targets and the RET. // (We don't know out leader here so we cannot check if we're really targeted!) if (localVariable != ((ASTORE) (((JsrInstruction) jsrInst.getInstruction()).getTarget().getInstruction())).getIndex()){ throw new AssertionViolatedException("Setting a wrong JsrInstruction."); } } theJSRs.add(jsrInst); }
public void initializeSlots() { int slot = 0; createUpvalues(-1, 0, p.maxstacksize); if ( superclassType == SUPERTYPE_VARARGS ) { for ( slot=0; slot<p.numparams; slot++ ) { if ( pi.isInitialValueUsed(slot) ) { append(new ALOAD(1)); append(new PUSH(cp, slot+1)); append(factory.createInvoke(STR_VARARGS, "arg", TYPE_LUAVALUE, ARG_TYPES_INT, Constants.INVOKEVIRTUAL)); storeLocal(-1, slot); } } append(new ALOAD(1)); append(new PUSH(cp, 1 + p.numparams)); append(factory.createInvoke(STR_VARARGS, "subargs", TYPE_VARARGS, ARG_TYPES_INT, Constants.INVOKEVIRTUAL)); append(new ASTORE(1)); } else { // fixed arg function between 0 and 3 arguments for ( slot=0; slot<p.numparams; slot++ ) { this.plainSlotVars.put( Integer.valueOf(slot), Integer.valueOf(1+slot) ); if ( pi.isUpvalueCreate(-1, slot) ) { append(new ALOAD(1+slot)); storeLocal(-1, slot); } } } // nil parameters // TODO: remove this for lua 5.2, not needed for ( ; slot<p.maxstacksize; slot++ ) { if ( pi.isInitialValueUsed(slot) ) { loadNil(); storeLocal(-1, slot); } } }
public void createUpvalues(int pc, int firstslot, int numslots) { for ( int i=0; i<numslots; i++ ) { int slot = firstslot + i; boolean isupcreate = pi.isUpvalueCreate(pc, slot); if ( isupcreate ) { int index = findSlotIndex( slot, true ); append(factory.createInvoke(classname, "newupn", TYPE_LOCALUPVALUE, ARG_TYPES_NONE, Constants.INVOKESTATIC)); append(new ASTORE(index)); } } }
public void convertToUpvalue(int pc, int slot) { boolean isupassign = pi.isUpvalueAssign(pc, slot); if ( isupassign ) { int index = findSlotIndex( slot, false ); append(new ALOAD(index)); append(factory.createInvoke(classname, "newupl", TYPE_LOCALUPVALUE, ARG_TYPES_LUAVALUE, Constants.INVOKESTATIC)); int upindex = findSlotIndex( slot, true ); append(new ASTORE(upindex)); } }
/** Checks if the constraints of operands of the said instruction(s) are satisfied. */ public void visitASTORE(ASTORE o){ int idx = o.getIndex(); if (idx < 0){ constraintViolated(o, "Index '"+idx+"' must be non-negative."); } else{ int maxminus1 = max_locals()-1; if (idx > maxminus1){ constraintViolated(o, "Index '"+idx+"' must not be greater than max_locals-1 '"+maxminus1+"'."); } } }
@Override public void generate(GenScope scope) { InstructionList il = scope.getInstructionList(); InstructionFactory ifact = scope.getInstructionFactory(); LocalVariableGen lvg = scope.newLocalVariable(this, Type.OBJECT); // Null initialization of the result il.append(InstructionConstants.ACONST_NULL); il.append(new ASTORE(lvg.getIndex())); generateWithNoVar(scope); il.append(new ASTORE(lvg.getIndex())); }
/** * A new IdcMetaclass object is created to wrap de * real metaclass providing additional functionality. * * <pre> * NEW IdcMetaclass * DUP * LDC <<model_name>> * LDC <<class_name>> * INVOKESPECIAL IdcMetaclass.<init> * ASTORE !!#variable!! * </pre> */ @Override public void generate(GenScope scope) { InstructionList il = scope.getInstructionList(); InstructionFactory ifact = scope.getInstructionFactory(); ConstantPoolGen cpg = scope.getConstantPool(); LocalVariableGen lvg = null; if ( getKind() == ReadMetaKind.METACLASS) { lvg = scope.newLocalVariable(this, DefaultTypes.IdcMetaclass); lvg.setStart(il.append(ifact.createNew(DefaultTypes.IdcMetaclass))); il.append(new DUP()); // il.append(new LDC(cpg.addString(getModel().getName()))); scope.generateGetTransformation(); scope.generateGetModel(getModel().getName()); // CommonGen.generateGetModel(getModel().getName(), il, ifact, scope); il.append(new LDC(cpg.addString(getClassName()))); il.append(ifact.createInvoke(DefaultTypes.IdcMetaclass.getClassName(), "<init>", Type.VOID, new Type[] { DefaultTypes.IdcTransformation, DefaultTypes.IModel, Type.STRING }, Constants.INVOKESPECIAL)); } else if ( getKind() == ReadMetaKind.THIS_TRANSFORMATION_OBJECT || getKind() == ReadMetaKind.THIS_TRANSFORMATION_METHOD_HANDLER ) { lvg = scope.newLocalVariable(this, DefaultTypes.IdcTransformation); lvg.setStart(il.append(InstructionConstants.NOP)); scope.generateGetTransformation(); } else if ( getKind() == ReadMetaKind.MODEL ){ lvg = scope.newLocalVariable(this, DefaultTypes.IModel); lvg.setStart(il.append(InstructionConstants.NOP)); scope.generateGetModel(getModel().getName()); } else { throw new IllegalArgumentException(); } il.append(new ASTORE(lvg.getIndex())); }
@Override public void generate(GenScope scope) { InstructionList il = scope.getInstructionList(); LocalVariableGen lvg = scope.newLocalVariable(this, Type.OBJECT); // create element ModelStrategy strategy = Processor.getModelStrategy(this, scope.getTransformationContext()); strategy.genCreate(this, scope); // store result il.append(new ASTORE( lvg.getIndex() )); }
@Override public void generate(GenScope scope) { InstructionList il = scope.getInstructionList(); InstructionFactory ifact = scope.getInstructionFactory(); NewScopeResult closureClassScope = createClosureClass(scope); ClassGen closureClass = closureClassScope.cg; ClosureScope closureScope = (ClosureScope) closureClassScope.scope; scope.getTransformationContext().addExtraClass(closureClass.getJavaClass()); LocalVariableGen lvg = scope.newLocalVariable(this, Type.OBJECT); // Create the closure instance il.append(ifact.createNew(closureClass.getClassName())); il.append(new DUP()); scope.generateGetTransformation(); scope.generateGetModelManager(); il.append(ifact.createInvoke(closureClass.getClassName(), "<init>", Type.VOID, new Type[] { DefaultTypes.IdcTransformation, DefaultTypes.ModelManager }, Constants.INVOKESPECIAL)); //Type.VOID, new Type[] { DefaultTypes.ModelManager }, Constants.INVOKESPECIAL)); // This is a bit hard-wired because the OuterVariableSet // is computed as a result of creating the closureClass... OuterVariableSet outers = closureScope.getOuterVariables(); Set<Variable> o = outers.get(); for (Variable variable : o) { il.append(new DUP()); scope.loadVariable(variable, il); il.append(scope.getInstructionFactory().createPutField(closureClass.getClassName(), variable.getName(), Type.OBJECT)); } il.append(new ASTORE(lvg.getIndex())); }
private void generateInvokeEntryPoint(GenScope scope, InstructionList il, InstructionFactory ifact, String transformationName, String entryPointName, LocalVariableGen lvg) { // Configure the transformation il.append(InstructionFactory.DUP); il.append(ifact.createInvoke(DefaultTypes.IdcTransformation.getClassName(), "configure_", Type.VOID, new Type[] { }, Constants.INVOKEVIRTUAL)); // TODO: Configure the models properly, not as I'm doing directly in instantiateTransformation directly // Put the params into the stack and invoke, but first check the type of the transformation object ObjectType transformationType = new ObjectType(transformationName); il.append(ifact.createCheckCast(transformationType)); // [Transformation, param1, ..., paramN] EList<Variable> params = this.getEntryPointParameters(); Type[] types = new Type[params.size()]; int i = 0; for (Variable variable : params) { scope.loadVariable(variable, il); types[i++] = Type.OBJECT; } il.append(ifact.createInvoke(transformationType.getClassName(), entryPointName, Type.OBJECT, types, Constants.INVOKEVIRTUAL)); il.append(new ASTORE( lvg.getIndex() )); }
private void generateInvokeTransformation(GenScope scope, InstructionList il, InstructionFactory ifact, String transformationName, LocalVariableGen lvg) { // Configure the invoked transformation: view filter if ( this.getInputViewFilter() != null ) { il.append(InstructionFactory.DUP); scope.loadVariable(this.getInputViewFilter(), il); il.append(ifact.createInvoke(DefaultTypes.IdcTransformation.getClassName(), "configure_invocation_", Type.VOID, new Type[] { DefaultTypes.RunnableClosure }, Constants.INVOKEVIRTUAL)); } // Set the parent transformation il.append(InstructionFactory.DUP); scope.generateGetTransformation(); il.append(InstructionFactory.SWAP); il.append(ifact.createInvoke(DefaultTypes.IdcTransformation.getClassName(), "setParentTransformation", Type.VOID, new Type[] { DefaultTypes.IdcTransformation }, Constants.INVOKEVIRTUAL)); // Configure the transformation il.append(InstructionFactory.DUP); il.append(ifact.createInvoke(DefaultTypes.IdcTransformation.getClassName(), "configure_", Type.VOID, new Type[] { }, Constants.INVOKEVIRTUAL)); // Start the transformation il.append(InstructionFactory.DUP); il.append(ifact.createInvoke(DefaultTypes.IdcTransformation.getClassName(), "start_", Type.VOID, new Type[] { }, Constants.INVOKEVIRTUAL)); il.append(InstructionFactory.ACONST_NULL); il.append(new ASTORE( lvg.getIndex() )); }
@Override public void generate(GenScope scope) { InstructionList il = scope.getInstructionList(); // if (CompilerFlags.use_assign) { LocalVariableGen lvg = scope.newLocalVariable(this, Type.OBJECT); scope.loadVariable(rightVariable, il); il.append(new ASTORE(lvg.getIndex())); // } }
void rewriteAbort(MethodGen m, InstructionList il, InstructionHandle i, int maxLocals) { // in a clone, we have to abort two lists: the outstanding spawns of // the parent, and the outstanding spawns of the clone. Instruction fa = getCashmere(ins_f); Instruction ab = ins_f.createInvoke("ibis.cashmere.impl.Cashmere", "abort", Type.VOID, new Type[] { irType, irType }, Constants.INVOKEVIRTUAL); if (mtab.isClone(m)) { int parentPos = 3; if (!m.isStatic()) { // we have an additional 'this' param parentPos++; } i.getPrev().getPrev().setInstruction(fa); // push outstanding spawns i.getPrev().setInstruction(new ALOAD(maxLocals - 3)); // push parent invocationrecord i.setInstruction(new ALOAD(parentPos)); i = i.getNext(); } else if (mtab.containsInlet(m)) { i.getPrev().getPrev().setInstruction(fa); // push outstanding spawns i.getPrev().setInstruction(new ALOAD(maxLocals - 3)); i.setInstruction(new ACONST_NULL()); i = i.getNext(); } else { i.getPrev().setInstruction(fa); // push outstanding spawns i.setInstruction(new ALOAD(maxLocals - 3)); i = i.getNext(); il.insert(i, new ACONST_NULL()); } // and call Cashmere.abort il.insert(i, ab); // all jobs were killed, set outstandingSpawns to null il.insert(i, new ACONST_NULL()); // push null il.insert(i, new ASTORE(maxLocals - 3)); // write }
void initSpawnTargets(InstructionList il) { for (int i = 0; i < idTable.size(); i++) { InstructionList storeIns = getStoreIns(i); if (storeIns == null) { continue; } if (isArrayStore(storeIns.getStart())) { continue; } Instruction store = storeIns.getStart().getInstruction(); if (store instanceof LSTORE) { il.insert(new LCONST(0)); il.append(il.getStart(), store); } else if (store instanceof ISTORE) { il.insert(new ICONST(0)); il.append(il.getStart(), store); } else if (store instanceof FSTORE) { il.insert(new FCONST((float) 0.0)); il.append(il.getStart(), store); } else if (store instanceof DSTORE) { il.insert(new DCONST(0.0)); il.append(il.getStart(), store); } else if (store instanceof ASTORE) { il.insert(new ACONST_NULL()); il.append(il.getStart(), store); } else if (store instanceof PUTFIELD) { // no need to init. } else if (store instanceof PUTSTATIC) { // no need to init. } else if (store instanceof ALOAD) { // no need to init. } else { System.err.println("WARNING: Unhandled store instruction in " + "initSpawnTargets, opcode = " + store.getOpcode() + " ins = " + store); // System.exit(1); } } }
@SuppressWarnings("unused") // Called using reflection private Instruction createInstructionAstore(Element inst) { int idx = Integer.parseInt(inst.getAttributeValue("index")); return new ASTORE(idx); }
public void storeVarresult() { append(new ASTORE(getVarresultIndex())); }
/** * These are the checks for the satisfaction of constraints which are described in the * Java Virtual Machine Specification, Second Edition as Static Constraints on * the operands of instructions of Java Virtual Machine Code (chapter 4.8.1). * BCEL parses the code array to create an InstructionList and therefore has to check * some of these constraints. Additional checks are also implemented here. * * @throws StaticCodeConstraintException if the verification fails. */ private void pass3StaticInstructionOperandsChecks(){ try { // When building up the InstructionList, BCEL has already done all those checks // mentioned in The Java Virtual Machine Specification, Second Edition, as // "static constraints on the operands of instructions in the code array". // TODO: see the do_verify() comments. Maybe we should really work on the // byte array first to give more comprehensive messages. // TODO: Review Exception API, possibly build in some "offending instruction" thing // when we're ready to insulate the offending instruction by doing the // above thing. // TODO: Implement as much as possible here. BCEL does _not_ check everything. ConstantPoolGen cpg = new ConstantPoolGen(Repository.lookupClass(myOwner.getClassName()).getConstantPool()); InstOperandConstraintVisitor v = new InstOperandConstraintVisitor(cpg); // Checks for the things BCEL does _not_ handle itself. InstructionHandle ih = instructionList.getStart(); while (ih != null){ Instruction i = ih.getInstruction(); // An "own" constraint, due to JustIce's new definition of what "subroutine" means. if (i instanceof JsrInstruction){ InstructionHandle target = ((JsrInstruction) i).getTarget(); if (target == instructionList.getStart()){ throw new StaticCodeInstructionOperandConstraintException("Due to JustIce's clear definition of subroutines, no JSR or JSR_W may have a top-level instruction (such as the very first instruction, which is targeted by instruction '"+ih+"' as its target."); } if (!(target.getInstruction() instanceof ASTORE)){ throw new StaticCodeInstructionOperandConstraintException("Due to JustIce's clear definition of subroutines, no JSR or JSR_W may target anything else than an ASTORE instruction. Instruction '"+ih+"' targets '"+target+"'."); } } // vmspec2, page 134-137 ih.accept(v); ih = ih.getNext(); } } catch (ClassNotFoundException e) { // FIXME: maybe not the best way to handle this throw new AssertionViolatedException("Missing class: " + e.toString()); } }
/** * <<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() )); }
@Override public void generate(GenScope scope) { InstructionList il = scope.getInstructionList(); InstructionFactory ifact = scope.getInstructionFactory(); ConstantPoolGen cpg = scope.getConstantPool(); LocalVariableGen lvg = scope.newLocalVariable(this, Type.OBJECT); switch (kind.getValue()) { case LiteralKind.BOOLEAN_VALUE: if (getBooleanValue()) { il.append(InstructionConstants.ICONST_1); } else { il.append(InstructionConstants.ICONST_0); } il.append(ifact.createInvoke(Boolean.class.getName(), "valueOf", new ObjectType(Boolean.class.getName()), new Type[] { Type.BOOLEAN }, Constants.INVOKESTATIC)); break; case LiteralKind.STRING_VALUE: lvg.setStart(il.append(new LDC(cpg.addString(getStringValue())))); break; case LiteralKind.NULL_VALUE: lvg.setStart(il.append(InstructionConstants.ACONST_NULL)); break; case LiteralKind.INTEGER_VALUE: //lvg.setStart(il.append(new LDC(cpg.addInteger(intValue)))); //il.append(new LDC(cpg.addInteger(intValue))); il.append(ifact.createConstant(intValue)); il.append(ifact.createInvoke(Integer.class.getName(), "valueOf", new ObjectType(Integer.class.getName()), new Type[] { Type.INT }, Constants.INVOKESTATIC)); break; case LiteralKind.DOUBLE_VALUE: //lvg.setStart(il.append(new LDC(cpg.addDouble(doubleValue)))); lvg.setStart(il.append(ifact.createConstant(doubleValue))); il.append(ifact.createInvoke(Double.class.getName(), "valueOf", new ObjectType(Double.class.getName()), new Type[] { Type.DOUBLE }, Constants.INVOKESTATIC)); break; default: throw new IdcException("Not supported literal"); // break; } il.append(new ASTORE(lvg.getIndex())); }
private void generateInvokeTransformation(GenScope scope, InstructionList il, InstructionFactory ifact, String transformationName, LocalVariableGen lvg) { il.append(InstructionFactory.DUP); il.append(InstructionFactory.DUP); il.append(InstructionFactory.DUP); // Configure the invoked transformation: view filter scope.loadVariable(this.getInputViewFilter(), il); il.append(ifact.createInvoke(DefaultTypes.IdcTransformation.getClassName(), "configure_invocation_", Type.VOID, new Type[] { DefaultTypes.RunnableClosure }, Constants.INVOKEVIRTUAL)); // Configure the transformation il.append(InstructionFactory.DUP); il.append(ifact.createInvoke(DefaultTypes.IdcTransformation.getClassName(), "configure_", Type.VOID, new Type[] { }, Constants.INVOKEVIRTUAL)); // Set parameters for(NamedInvocationParameter p : this.getParameters()) { il.append(InstructionFactory.DUP); il.append(ifact.createConstant(p.getFormalName())); scope.loadVariable(p.getResult(), il); il.append(ifact.createInvoke(DefaultTypes.IdcTransformation.getClassName(), "setParameterValue", Type.VOID, new Type[] { Type.STRING, Type.OBJECT }, Constants.INVOKEVIRTUAL)); } // Start the transformation il.append(ifact.createInvoke(DefaultTypes.IdcTransformation.getClassName(), "start_", Type.VOID, new Type[] { }, Constants.INVOKEVIRTUAL)); // Get a target element from a trace if ( this.getOutputResolutionSourceElement() != null ) { scope.loadVariable(this.getOutputResolutionSourceElement(), il); il.append(ifact.createConstant(this.getQueueName())); il.append(ifact.createConstant(this.getSrcTraceAttributeName())); il.append(ifact.createConstant(this.getTgtTraceAttributeName())); il.append(ifact.createInvoke(DefaultTypes.IdcTransformation.getClassName(), "retrieve_from_invocation_", Type.OBJECT, new Type[] { Type.OBJECT, Type.STRING, Type.STRING, Type.STRING }, Constants.INVOKEVIRTUAL)); } else { il.append(InstructionFactory.ACONST_NULL); } il.append(new ASTORE( lvg.getIndex() )); }