/** * TODO * * @param mg */ public StackTypes(MethodGen mg) { InstructionList il = mg.getInstructionList(); int size = 0; if (il != null) size = il.getEnd().getPosition(); os_arr = new OperandStack[size + 1]; if (track_locals) loc_arr = new LocalVariables[size + 1]; }
/** * Runs through instructions from given index which is important when executing branch of * conditions. Also the stack and item pool are cloned and put back afterwards. * * @param startInstruction * @return true - method is dangerous; false - method is safe * @throws DangerousPatternException */ private boolean runInstructions(int startInstruction) throws DangerousPatternException { ArrayList<Item> clonedStack = (ArrayList<Item>) this.stack.clone(); HashMap<Integer, Item> clonedPool = new HashMap<>(this.itemsPool); try { InstructionList handlers = this.instructionsPool; InstructionHandle instruction = handlers.findHandle(startInstruction); while (instruction != null) { switch (this.watchOpcode(instruction)) { case 0: return false; case 1: break; } instruction = instruction.getNext(); } } finally { this.stack = clonedStack; this.itemsPool = clonedPool; } return false; }
/** * Create a constructor for the new class. Updates the reference to the collator in the super * calls only when the stylesheet specifies a new language in xsl:sort. */ private static MethodGenerator compileInit( Vector sortObjects, NodeSortRecordGenerator sortRecord, ConstantPoolGen cpg, String className) { final InstructionList il = new InstructionList(); final MethodGenerator init = new MethodGenerator( ACC_PUBLIC, org.apache.bcel.generic.Type.VOID, null, null, "<init>", className, il, cpg); // Call the constructor in the NodeSortRecord superclass il.append(ALOAD_0); il.append(new INVOKESPECIAL(cpg.addMethodref(NODE_SORT_RECORD, "<init>", "()V"))); il.append(RETURN); return init; }
byte[] nullAdaptClass(final InputStream is, final String name) throws Exception { JavaClass jc = new ClassParser(is, name + ".class").parse(); ClassGen cg = new ClassGen(jc); String cName = cg.getClassName(); ConstantPoolGen cp = cg.getConstantPool(); Method[] ms = cg.getMethods(); for (int j = 0; j < ms.length; ++j) { MethodGen mg = new MethodGen(ms[j], cg.getClassName(), cp); boolean lv = ms[j].getLocalVariableTable() == null; boolean ln = ms[j].getLineNumberTable() == null; if (lv) { mg.removeLocalVariables(); } if (ln) { mg.removeLineNumbers(); } mg.stripAttributes(skipDebug); InstructionList il = mg.getInstructionList(); if (il != null) { InstructionHandle ih = il.getStart(); while (ih != null) { ih = ih.getNext(); } if (compute) { mg.setMaxStack(); mg.setMaxLocals(); } } cg.replaceMethod(ms[j], mg.getMethod()); } return cg.getJavaClass().getBytes(); }
/** Checks the specific method for consistency. */ public static void checkMgen(MethodGen mgen) { if (skip_checks) return; try { mgen.toString(); mgen.getLineNumberTable(mgen.getConstantPool()); InstructionList ilist = mgen.getInstructionList(); if (ilist == null || ilist.getStart() == null) return; CodeExceptionGen[] exceptionHandlers = mgen.getExceptionHandlers(); for (CodeExceptionGen gen : exceptionHandlers) { assert ilist.contains(gen.getStartPC()) : "exception handler " + gen + " has been forgotten in " + mgen.getClassName() + "." + mgen.getName(); } MethodGen nmg = new MethodGen(mgen.getMethod(), mgen.getClassName(), mgen.getConstantPool()); nmg.getLineNumberTable(mgen.getConstantPool()); } catch (Throwable t) { System.out.printf("failure in method %s.%s\n", mgen.getClassName(), mgen.getName()); t.printStackTrace(); throw new Error(t); } }
/** * Builds an array of line numbers for the specified instruction list. Each opcode is assigned the * next source line number starting at 1000. */ public static void add_line_numbers(MethodGen mg, InstructionList il) { il.setPositions(true); for (InstructionHandle ih : il.getInstructionHandles()) { mg.addLineNumber(ih, 1000 + ih.getPosition()); } }
/** Instrument the specified method to replace mapped calls. */ public void instrument_method(Method m, MethodGen mg) { // Loop through each instruction, making substitutions InstructionList il = mg.getInstructionList(); for (InstructionHandle ih = il.getStart(); ih != null; ) { if (debug_instrument_inst.enabled()) { debug_instrument_inst.log("instrumenting instruction %s%n", ih); // ih.getInstruction().toString(pool.getConstantPool())); } InstructionList new_il = null; // Remember the next instruction to process InstructionHandle next_ih = ih.getNext(); // Get the translation for this instruction (if any) new_il = xform_inst(mg, ih.getInstruction()); if (debug_instrument_inst.enabled()) debug_instrument_inst.log(" new inst: %s%n", new_il); // If this instruction was modified, replace it with the new // instruction list. If this instruction was the target of any // jumps or line numbers , replace them with the first // instruction in the new list replace_instructions(il, ih, new_il); ih = next_ih; } }
/** Loads the code of the method. */ protected Instruction[] loadCode(Method m) { Code c = m.getCode(); if (c == null) { return null; } InstructionList il = new InstructionList(c.getCode()); InstructionHandle[] hs = il.getInstructionHandles(); int length = hs.length; Instruction[] is = new Instruction[length]; for (int i = 0; i < length; i++) { is[i] = insnFactory.createAndInitialize(this, hs[i], i, m.getConstantPool()); if (c.getLineNumberTable() != null) { // annoying bug when BCEL don't seem to find linenumber - pos match // also sometimes linenumber tables are not available is[i].setContext( ci.getName(), name, c.getLineNumberTable().getSourceLine(is[i].getPosition()), is[i].getPosition()); } } return is; }
Method generate(String currentClass, ConstantPoolGen cpg) { InstructionList il = new InstructionList(); int instanceOffset = 0; short flags = Constants.ACC_PUBLIC; if (invokeKind != INVOKESTATIC) { instanceOffset = 1; il.append(InstructionFactory.createThis()); } else { flags |= Constants.ACC_STATIC; } int pos = 0; for (int i = 0; i < args.length; i++) { il.append(InstructionFactory.createLoad(args[i], pos + instanceOffset)); pos += args[i].getSize(); } il.append( new InstructionFactory(cpg) .createInvoke(targetClass, methodName, returnType, args, invokeKind)); il.append(InstructionFactory.createReturn(returnType)); MethodGen newMethod = new MethodGen( flags, returnType, args, /*argNames*/ null, accessorName, currentClass, il, cpg); newMethod.setMaxLocals(); newMethod.setMaxStack(); return newMethod.getMethod(); }
CFG createCFG(String className) throws ClassNotFoundException { CFG cfg = new CFG(); JavaClass jc = Repository.lookupClass(className); ClassGen cg = new ClassGen(jc); ConstantPoolGen cpg = cg.getConstantPool(); for (Method m : cg.getMethods()) { MethodGen mg = new MethodGen(m, cg.getClassName(), cpg); InstructionList il = mg.getInstructionList(); InstructionHandle[] handles = il.getInstructionHandles(); int prev = 0; for (InstructionHandle ih : handles) { int position = ih.getPosition(); cfg.addNode(position, m, jc); Instruction inst = ih.getInstruction(); boolean br = inst.getName().contains("if") || inst.getName().contains("goto"); boolean ret = inst.getName().contains("return"); boolean stat = inst.getName().contains("invokestatic"); int len = inst.getLength(); if (stat) { int index = inst.toString(true).indexOf(" "); String name = inst.toString(true).substring(index + 1); int tar = Integer.valueOf(name); INVOKESTATIC inv = new INVOKESTATIC(tar); name = inv.getMethodName(cpg); Method m2 = null; Method[] tm = cg.getMethods(); for (int i = 0; i < tm.length; i++) { if (tm[i].getName().equals(name)) { m2 = tm[i]; } } cfg.addEdge(position, m, jc, 0, m2, jc); cfg.addEdge(-1, m2, jc, position + len, m, jc); } if (!ret && !stat) { cfg.addEdge(position, position + len, m, jc); } if (br) { cfg.addEdge(position, position + len, m, jc); IF_ICMPGE comp = new IF_ICMPGE(ih); String name = comp.getTarget().toString(false); int index = name.indexOf(">"); name = name.substring(index + 2); int tar = Integer.valueOf(name); cfg.addEdge(position, tar, m, jc); } if (ret) { cfg.addEdge(position, -1, m, jc); } prev = position; } System.out.println(cfg.toString()); } return cfg; }
/** Translate code to call the BasisLibrary.unallowed_extensionF(String) method. */ private void translateUnallowedExtension(ConstantPoolGen cpg, InstructionList il) { int index = cpg.addMethodref( BASIS_LIBRARY_CLASS, "unallowed_extension_functionF", "(Ljava/lang/String;)V"); il.append(new PUSH(cpg, _fname.toString())); il.append(new INVOKESTATIC(index)); }
public void translate(ClassGenerator classGen, MethodGenerator methodGen) { final ConstantPoolGen cpg = classGen.getConstantPool(); final InstructionList il = methodGen.getInstructionList(); // Don't generate code for unreferenced variables if (_refs.isEmpty()) { _ignore = true; } // Make sure that a variable instance is only compiled once if (_ignore) return; _ignore = true; final String name = getEscapedName(); if (isLocal()) { // Compile variable value computation translateValue(classGen, methodGen); // Add a new local variable and store value boolean createLocal = _local == null; if (createLocal) { mapRegister(methodGen); } InstructionHandle storeInst = il.append(_type.STORE(_local.getIndex())); // If the local is just being created, mark the store as the start // of its live range. Note that it might have been created by // initializeVariables already, which would have set the start of // the live range already. if (createLocal) { _local.setStart(storeInst); } } else { String signature = _type.toSignature(); // Global variables are store in class fields if (classGen.containsField(name) == null) { classGen.addField( new Field( ACC_PUBLIC, cpg.addUtf8(name), cpg.addUtf8(signature), null, cpg.getConstantPool())); // Push a reference to "this" for putfield il.append(classGen.loadTranslet()); // Compile variable value computation translateValue(classGen, methodGen); // Store the variable in the allocated field il.append(new PUTFIELD(cpg.addFieldref(classGen.getClassName(), name, signature))); } } }
private Method generateSuperAccessor( ConstantPoolGen cpg, String className, SuperMethodDescriptor superMethod, InstructionFactory factory) { int endPos = superMethod.signature.indexOf(')'); String segment = superMethod.signature.substring(1, endPos); String[] typeNames = (segment.length() > 0) ? segment.split(",") : new String[0]; Type[] argTypes = new Type[typeNames.length]; for (int i = 0; i < argTypes.length; i++) argTypes[i] = Type.getType(typeNames[i]); int index = superMethod.signature.lastIndexOf(')') + 1; Type returnType = Type.getType(superMethod.signature.substring(index)); Type baseType = new ObjectType(className); Type[] wrapperTypes = new Type[argTypes.length + 1]; System.arraycopy(argTypes, 0, wrapperTypes, 1, argTypes.length); wrapperTypes[0] = baseType; String[] argNames = new String[wrapperTypes.length]; for (int i = 0; i < argNames.length; i++) { argNames[i] = "arg" + i; } InstructionList il = new InstructionList(); MethodGen mg = new MethodGen( (Constants.ACC_PUBLIC | Constants.ACC_STATIC), returnType, wrapperTypes, argNames, OT_PREFIX + superMethod.methodName + "$super", className, il, cpg); il.append(InstructionFactory.createLoad(baseType, 0)); // first argument is base instance for (int i = 0; i < argTypes.length; i++) il.append(InstructionFactory.createLoad(argTypes[i], i + 1)); // if super method is also callin bound directly invoke the orig-version // (to avoid that BaseMethodTransformation.checkReplaceWickedSuper() has to rewrite this code // again): String methodName = (CallinBindingManager.isBoundBaseMethod( superMethod.superClass, superMethod.methodName, superMethod.signature)) ? genOrigMethName(superMethod.methodName) : superMethod.methodName; il.append( factory.createInvoke( superMethod.superClass, methodName, returnType, argTypes, INVOKESPECIAL)); il.append(InstructionFactory.createReturn(returnType)); mg.setMaxStack(); mg.setMaxLocals(); return mg.getMethod(); }
/** Compile the function call and treat as an expression Update true/false-lists. */ public void translateDesynthesized(ClassGenerator classGen, MethodGenerator methodGen) { Type type = Type.Boolean; if (_chosenMethodType != null) type = _chosenMethodType.resultType(); final InstructionList il = methodGen.getInstructionList(); translate(classGen, methodGen); if ((type instanceof BooleanType) || (type instanceof IntType)) { _falseList.add(il.append(new IFEQ(null))); } }
public void translate(ClassGenerator classGen, MethodGenerator methodGen) { final InstructionList il = methodGen.getInstructionList(); if (methodGen instanceof CompareGenerator) { il.append(((CompareGenerator) methodGen).loadLastNode()); } else if (methodGen instanceof TestGenerator) { il.append(new ILOAD(LAST_INDEX)); } else { final ConstantPoolGen cpg = classGen.getConstantPool(); final int getLast = cpg.addInterfaceMethodref(NODE_ITERATOR, "getLast", "()I"); il.append(methodGen.loadIterator()); il.append(new INVOKEINTERFACE(getLast, 1)); } }
public void translate(ClassGenerator classGen, MethodGenerator methodGen) { final ConstantPoolGen cpg = classGen.getConstantPool(); final InstructionList il = methodGen.getInstructionList(); // Push the this pointer on the stack... il.append(methodGen.loadDOM()); // ...then the entity name... _entity.translate(classGen, methodGen); // ...to get the URI from the DOM object. il.append( new INVOKEINTERFACE( cpg.addInterfaceMethodref( DOM_INTF, GET_UNPARSED_ENTITY_URI, GET_UNPARSED_ENTITY_URI_SIG), 2)); }
/** * Translate a predicate expression. If non of the optimizations apply then this translation * pushes two references on the stack: a reference to a newly created filter object and a * reference to the predicate's closure. See class <code>Step</code> for further details. */ public void translate(ClassGenerator classGen, MethodGenerator methodGen) { final ConstantPoolGen cpg = classGen.getConstantPool(); final InstructionList il = methodGen.getInstructionList(); if (_nthPositionFilter || _nthDescendant) { _exp.translate(classGen, methodGen); } else if (isNodeValueTest() && (getParent() instanceof Step)) { _value.translate(classGen, methodGen); il.append(new CHECKCAST(cpg.addClass(STRING_CLASS))); il.append(new PUSH(cpg, ((EqualityExpr) _exp).getOp())); } else { translateFilter(classGen, methodGen); } }
/** Compiles a method that overloads NodeSortRecord.extractValueFromDOM() */ private static MethodGenerator compileExtract( Vector sortObjects, NodeSortRecordGenerator sortRecord, ConstantPoolGen cpg, String className) { final InstructionList il = new InstructionList(); // String NodeSortRecord.extractValueFromDOM(dom,node,level); final CompareGenerator extractMethod = new CompareGenerator( ACC_PUBLIC | ACC_FINAL, org.apache.bcel.generic.Type.STRING, new org.apache.bcel.generic.Type[] { Util.getJCRefType(DOM_INTF_SIG), org.apache.bcel.generic.Type.INT, org.apache.bcel.generic.Type.INT, Util.getJCRefType(TRANSLET_SIG), org.apache.bcel.generic.Type.INT }, new String[] {"dom", "current", "level", "translet", "last"}, "extractValueFromDOM", className, il, cpg); // Values needed for the switch statement final int levels = sortObjects.size(); final int match[] = new int[levels]; final InstructionHandle target[] = new InstructionHandle[levels]; InstructionHandle tblswitch = null; // Compile switch statement only if the key has multiple levels if (levels > 1) { // Put the parameter to the swtich statement on the stack il.append(new ILOAD(extractMethod.getLocalIndex("level"))); // Append the switch statement here later on tblswitch = il.append(new NOP()); } // Append all the cases for the switch statment for (int level = 0; level < levels; level++) { match[level] = level; final Sort sort = (Sort) sortObjects.elementAt(level); target[level] = il.append(NOP); sort.translateSelect(sortRecord, extractMethod); il.append(ARETURN); } // Compile def. target for switch statement if key has multiple levels if (levels > 1) { // Append the default target - it will _NEVER_ be reached InstructionHandle defaultTarget = il.append(new PUSH(cpg, EMPTYSTRING)); il.insert(tblswitch, new TABLESWITCH(match, target, defaultTarget)); il.append(ARETURN); } return extractMethod; }
private void createMethod(Element method) throws IllegalXMLVMException { il = new InstructionList(); instructionHandlerManager = new InstructionHandlerManager(il); String methodName = method.getAttributeValue("name"); Element signature = method.getChild("signature", nsXMLVM); Type retType = collectReturnType(signature); Type[] argTypes = collectArgumentTypes(signature); short accessFlags = getAccessFlags(method); if (methodName.equals( ".cctor")) // Same concept, different names in .net/JVM. Note we are doing init of statics // for a class { System.out.println("Changed name to clinit"); methodName = "<clinit>"; accessFlags = 0x8; // static } MethodGen m = new MethodGen( accessFlags, retType, argTypes, null, methodName, fullQualifiedClassName, il, _cp); Element code = method.getChild("code", nsXMLVM); createCode(code); instructionHandlerManager.checkConsistency(); m.setMaxLocals(); m.setMaxStack(); _cg.addMethod(m.getMethod()); il.dispose(); }
private void createMethod_0() { InstructionList il = new InstructionList(); MethodGen method = new MethodGen( ACC_PUBLIC, Type.VOID, Type.NO_ARGS, new String[] {}, "<init>", objectType, il, _cp); InstructionHandle ih_0 = il.append(_factory.createLoad(Type.OBJECT, 0)); il.append( _factory.createInvoke( "java.lang.Object", "<init>", Type.VOID, Type.NO_ARGS, Constants.INVOKESPECIAL)); InstructionHandle ih_4 = il.append(_factory.createReturn(Type.VOID)); method.setMaxStack(); method.setMaxLocals(); _cg.addMethod(method.getMethod()); il.dispose(); }
/** * Generates a setter method for the field described by 'fd' in the class 'class_name'. * * @param cpg the ConstantPoolGen of the class * @param class_name the name of the class * @param fd the FieldDescriptor describing the affected field * @param factory an InstructionFactory for this class * @return the generated getter method */ private Method generateSetter( ConstantPoolGen cpg, String class_name, FieldDescriptor fd, InstructionFactory factory) { String fieldName = fd.getFieldName(); Type fieldType = Type.getType(fd.getFieldSignature()); Type baseType = new ObjectType(class_name); Type[] argumentTypes; String[] argumentNames; if (fd.isStaticField()) { argumentTypes = new Type[] {fieldType}; argumentNames = new String[] {"new_value"}; } else { argumentTypes = new Type[] {baseType, fieldType}; argumentNames = new String[] {"base_obj", "new_value"}; } InstructionList il = new InstructionList(); MethodGen mg = new MethodGen( (Constants.ACC_PUBLIC | Constants.ACC_STATIC), Type.VOID, argumentTypes, argumentNames, OT_PREFIX + "set$" + fieldName, class_name, il, cpg); int argumentPosition; // position for the argument holding the new field value. if (!fd.isStaticField()) { il.append( InstructionFactory.createLoad( baseType, 0)); // first argument is at slot 0 in static methods argumentPosition = 1; } else { argumentPosition = 0; } il.append(InstructionFactory.createLoad(fieldType, argumentPosition)); short fieldKind = fd.isStaticField() ? Constants.PUTSTATIC : Constants.PUTFIELD; il.append(factory.createFieldAccess(class_name, fieldName, fieldType, fieldKind)); il.append(InstructionFactory.createReturn(Type.VOID)); mg.removeNOPs(); mg.setMaxStack(); mg.setMaxLocals(); return mg.getMethod(); }
/** * Generates the Java bytecode corresponding to this list of bytecodes. This just calls {@code * bytecode.NonBranchingBytecode.generateJavaBytecode(JavaClassGenerator)} on each non-branching * bytecode in the list and appends the results. * * @param classGen the Java class generator to be used for this generation * @return the Java bytecode corresponding to this list of bytecodes */ public InstructionList generateJavaBytecode(JavaClassGenerator classGen) { InstructionList result; if (head instanceof NonBranchingBytecode) // generiamo il Java bytecode dal primo bytecode, se non è una condizione di un ramo result = ((NonBranchingBytecode) head).generateJavaBytecode(classGen); else result = new InstructionList(); // e per quelli successivi, se esistono if (tail != null) result.append(tail.generateJavaBytecode(classGen)); // se non sono state aggiunte istruzioni, ne aggiungiamo una fittizia cosi da ritornare sempre // una lista non vuota if (result.isEmpty()) result.append(new org.apache.bcel.generic.NOP()); return result; }
/* * (non-Javadoc) * * @see * edu.umd.cs.findbugs.classfile.IAnalysisEngine#analyze(edu.umd.cs.findbugs * .classfile.IAnalysisCache, java.lang.Object) */ public LoadedFieldSet analyze(IAnalysisCache analysisCache, MethodDescriptor descriptor) throws CheckedAnalysisException { MethodGen methodGen = getMethodGen(analysisCache, descriptor); if (methodGen == null) return null; InstructionList il = methodGen.getInstructionList(); LoadedFieldSet loadedFieldSet = new LoadedFieldSet(methodGen); ConstantPoolGen cpg = getConstantPoolGen(analysisCache, descriptor.getClassDescriptor()); for (InstructionHandle handle = il.getStart(); handle != null; handle = handle.getNext()) { Instruction ins = handle.getInstruction(); short opcode = ins.getOpcode(); try { if (opcode == Constants.INVOKESTATIC) { INVOKESTATIC inv = (INVOKESTATIC) ins; if (Hierarchy.isInnerClassAccess(inv, cpg)) { InnerClassAccess access = Hierarchy.getInnerClassAccess(inv, cpg); /* * if (access == null) { * System.out.println("Missing inner class access in " + * SignatureConverter.convertMethodSignature(methodGen) * + " at " + inv); } */ if (access != null) { if (access.isLoad()) loadedFieldSet.addLoad(handle, access.getField()); else loadedFieldSet.addStore(handle, access.getField()); } } } else if (fieldInstructionOpcodeSet.get(opcode)) { boolean isLoad = (opcode == Constants.GETFIELD || opcode == Constants.GETSTATIC); XField field = Hierarchy.findXField((FieldInstruction) ins, cpg); if (field != null) { if (isLoad) loadedFieldSet.addLoad(handle, field); else loadedFieldSet.addStore(handle, field); } } } catch (ClassNotFoundException e) { AnalysisContext.currentAnalysisContext().getLookupFailureCallback().reportMissingClass(e); } } return loadedFieldSet; }
/** * Transforms the init method to create the newly added join point member field. * * @param cp the ConstantPoolGen * @param cg the ClassGen * @param init the constructor for the class * @param method the current method * @param factory the objectfactory * @param methodSequence the methods sequence number * @return the modified constructor */ private MethodGen createJoinPointField( final ConstantPoolGen cp, final ClassGen cg, final Method init, final Method method, final InstructionFactory factory, final int methodSequence) { final MethodGen mg = new MethodGen(init, cg.getClassName(), cp); final InstructionList il = mg.getInstructionList(); final InstructionHandle[] ihs = il.getInstructionHandles(); // grab the handle to the the return instruction of the constructor InstructionHandle ih = ihs[0]; for (int i = 0; i < ihs.length; i++) { Instruction instruction = ihs[i].getInstruction(); if (instruction instanceof ReturnInstruction) { ih = ihs[i]; // set the instruction handle to the return instruction break; } } final String joinPoint = getJoinPointName(method, methodSequence); final InstructionHandle ihPost; ihPost = il.insert(ih, factory.createLoad(Type.OBJECT, 0)); il.insert(ih, factory.createNew(TransformationUtil.THREAD_LOCAL_CLASS)); il.insert(ih, InstructionConstants.DUP); il.insert( ih, factory.createInvoke( TransformationUtil.THREAD_LOCAL_CLASS, "<init>", Type.VOID, new Type[] {}, Constants.INVOKESPECIAL)); il.insert( ih, factory.createFieldAccess( cg.getClassName(), joinPoint, new ObjectType(TransformationUtil.THREAD_LOCAL_CLASS), Constants.PUTFIELD)); il.redirectBranches(ih, ihPost); mg.setMaxStack(); mg.setMaxLocals(); return mg; }
// TODO: write Javadoc public static String instruction_descr(InstructionList il, ConstantPoolGen pool) { String out = ""; // not generic because BCEL is not generic for (Iterator i = il.iterator(); i.hasNext(); ) { InstructionHandle handle = (InstructionHandle) i.next(); out += handle.getInstruction().toString(pool.getConstantPool()) + "\n"; } return (out); }
/** * Translate a predicate expression. This translation pushes two references on the stack: a * reference to a newly created filter object and a reference to the predicate's closure. */ public void translateFilter(ClassGenerator classGen, MethodGenerator methodGen) { final ConstantPoolGen cpg = classGen.getConstantPool(); final InstructionList il = methodGen.getInstructionList(); // Compile auxiliary class for filter compileFilter(classGen, methodGen); // Create new instance of filter il.append(new NEW(cpg.addClass(_className))); il.append(DUP); il.append(new INVOKESPECIAL(cpg.addMethodref(_className, "<init>", "()V"))); // Initialize closure variables final int length = (_closureVars == null) ? 0 : _closureVars.size(); for (int i = 0; i < length; i++) { VariableRefBase varRef = (VariableRefBase) _closureVars.get(i); VariableBase var = varRef.getVariable(); Type varType = var.getType(); il.append(DUP); // Find nearest closure implemented as an inner class Closure variableClosure = _parentClosure; while (variableClosure != null) { if (variableClosure.inInnerClass()) break; variableClosure = variableClosure.getParentClosure(); } // Use getfield if in an inner class if (variableClosure != null) { il.append(ALOAD_0); il.append( new GETFIELD( cpg.addFieldref( variableClosure.getInnerClassName(), var.getEscapedName(), varType.toSignature()))); } else { // Use a load of instruction if in translet class il.append(var.loadInstruction()); } // Store variable in new closure il.append( new PUTFIELD(cpg.addFieldref(_className, var.getEscapedName(), varType.toSignature()))); } }
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())); }
/** Adds code in nl to start of method mg * */ public static void add_to_start(MethodGen mg, InstructionList nl) { // Add the code before the first instruction InstructionList il = mg.getInstructionList(); InstructionHandle old_start = il.getStart(); InstructionHandle new_start = il.insert(nl); // Move any LineNumbers and local variable that currently point to // the first instruction to include the new instructions. Other // targeters (branches, exceptions) should not include the new // code if (old_start.hasTargeters()) { for (InstructionTargeter it : old_start.getTargeters()) { if ((it instanceof LineNumberGen) || (it instanceof LocalVariableGen)) it.updateTarget(old_start, new_start); } } mg.setMaxStack(); mg.setMaxLocals(); }
/* 43: */ /* 44: */ public void translate(ClassGenerator classGen, MethodGenerator methodGen) /* 45: */ { /* 46:77 */ ConstantPoolGen cpg = classGen.getConstantPool(); /* 47:78 */ InstructionList il = methodGen.getInstructionList(); /* 48: */ /* 49:80 */ int tst = cpg.addMethodref( "org.apache.xalan.xsltc.runtime.BasisLibrary", "testLanguage", "(Ljava/lang/String;Lorg/apache/xalan/xsltc/DOM;I)Z"); /* 50: */ /* 51: */ /* 52:83 */ this._lang.translate(classGen, methodGen); /* 53:84 */ il.append(methodGen.loadDOM()); /* 54:85 */ if ((classGen instanceof FilterGenerator)) { /* 55:86 */ il.append(new ILOAD(1)); /* 56: */ } else { /* 57:88 */ il.append(methodGen.loadContextNode()); /* 58: */ } /* 59:89 */ il.append(new INVOKESTATIC(tst)); /* 60: */ }
/** * Translate the code required for getting the node for which the QName, local-name or namespace * URI should be extracted. */ public void translate(ClassGenerator classGen, MethodGenerator methodGen) { final ConstantPoolGen cpg = classGen.getConstantPool(); final InstructionList il = methodGen.getInstructionList(); il.append(methodGen.loadDOM()); // Function was called with no parameters if (argumentCount() == 0) { il.append(methodGen.loadContextNode()); } // Function was called with node parameter else if (_paramType == Type.Node) { _param.translate(classGen, methodGen); } else if (_paramType == Type.Reference) { _param.translate(classGen, methodGen); il.append( new INVOKESTATIC( cpg.addMethodref( BASIS_LIBRARY_CLASS, "referenceToNodeSet", "(" + OBJECT_SIG + ")" + NODE_ITERATOR_SIG))); il.append(methodGen.nextNode()); } // Function was called with node-set parameter else { _param.translate(classGen, methodGen); _param.startIterator(classGen, methodGen); il.append(methodGen.nextNode()); } }