/** * Helper method to generate an instance of a subclass of * {@link StoreInstruction} based on the specified {@link Type} that will * store a value in the specified local variable * @param index the JVM stack frame index of the variable that is to be * stored * @param type the {@link Type} of the variable * @return the generated {@link StoredInstruction} */ private static Instruction storeLocal(int index, Type type) { if (type == Type.BOOLEAN) { return new ISTORE(index); } else if (type == Type.INT) { return new ISTORE(index); } else if (type == Type.SHORT) { return new ISTORE(index); } else if (type == Type.LONG) { return new LSTORE(index); } else if (type == Type.BYTE) { return new ISTORE(index); } else if (type == Type.CHAR) { return new ISTORE(index); } else if (type == Type.FLOAT) { return new FSTORE(index); } else if (type == Type.DOUBLE) { return new DSTORE(index); } else { return new ASTORE(index); } }
public CompareGenerator(int access_flags, Type return_type, Type[] arg_types, String[] arg_names, String method_name, String class_name, InstructionList il, ConstantPoolGen cp) { super(access_flags, return_type, arg_types, arg_names, method_name, class_name, il, cp); _iloadCurrent = new ILOAD(CURRENT_INDEX); _istoreCurrent = new ISTORE(CURRENT_INDEX); _aloadDom = new ALOAD(DOM_INDEX); _iloadLast = new ILOAD(LAST_INDEX); LocalVariableGen iterator = addLocalVariable("iterator", Util.getJCRefType(Constants.NODE_ITERATOR_SIG), null, null); ITERATOR_INDEX = iterator.getIndex(); _aloadIterator = new ALOAD(ITERATOR_INDEX); _astoreIterator = new ASTORE(ITERATOR_INDEX); il.append(new ACONST_NULL()); il.append(storeIterator()); }
public RtMethodGenerator(int access_flags, Type return_type, Type[] arg_types, String[] arg_names, String method_name, String class_name, InstructionList il, ConstantPoolGen cp) { super(access_flags, return_type, arg_types, arg_names, method_name, class_name, il, cp); _astoreHandler = new ASTORE(HANDLER_INDEX); _aloadHandler = new ALOAD(HANDLER_INDEX); }
public TestGenerator(int access_flags, Type return_type, Type[] arg_types, String[] arg_names, String method_name, String class_name, InstructionList il, ConstantPoolGen cp) { super(access_flags, return_type, arg_types, arg_names, method_name, class_name, il, cp); _iloadCurrent = new ILOAD(CURRENT_NODE_INDEX); _istoreCurrent = new ISTORE(CURRENT_NODE_INDEX); _iloadContext = new ILOAD(CONTEXT_NODE_INDEX); _istoreContext = new ILOAD(CONTEXT_NODE_INDEX); _astoreIterator = new ASTORE(ITERATOR_INDEX); _aloadIterator = new ALOAD(ITERATOR_INDEX); }
public void translate(ClassGenerator classGen, MethodGenerator methodGen) { final ConstantPoolGen cpg = classGen.getConstantPool(); final InstructionList il = methodGen.getInstructionList(); final LocalVariableGen name = methodGen.addLocalVariable2("name", Util.getJCRefType(STRING_SIG), null); final LocalVariableGen length = methodGen.addLocalVariable2("length", Util.getJCRefType("I"), null); // Get the name of the node to copy and save for later il.append(methodGen.loadDOM()); il.append(methodGen.loadCurrentNode()); il.append(methodGen.loadHandler()); final int cpy = cpg.addInterfaceMethodref(DOM_INTF, "shallowCopy", "(" + NODE_SIG + TRANSLET_OUTPUT_SIG + ")" + STRING_SIG); il.append(new INVOKEINTERFACE(cpy, 3)); il.append(DUP); name.setStart(il.append(new ASTORE(name.getIndex()))); final BranchHandle ifBlock1 = il.append(new IFNULL(null)); // Get the length of the node name and save for later il.append(new ALOAD(name.getIndex())); final int lengthMethod = cpg.addMethodref(STRING_CLASS,"length","()I"); il.append(new INVOKEVIRTUAL(lengthMethod)); il.append(DUP); length.setStart(il.append(new ISTORE(length.getIndex()))); // Ignore attribute sets if current node is ROOT. DOM.shallowCopy() // returns "" for ROOT, so skip attribute sets if length == 0 final BranchHandle ifBlock4 = il.append(new IFEQ(null)); // Copy in attribute sets if specified if (_useSets != null) { // If the parent of this element will result in an element being // output then we know that it is safe to copy out the attributes final SyntaxTreeNode parent = getParent(); if ((parent instanceof LiteralElement) || (parent instanceof LiteralElement)) { _useSets.translate(classGen, methodGen); } // If not we have to check to see if the copy will result in an // element being output. else { // check if element; if not skip to translate body il.append(new ILOAD(length.getIndex())); final BranchHandle ifBlock2 = il.append(new IFEQ(null)); // length != 0 -> element -> do attribute sets _useSets.translate(classGen, methodGen); // not an element; root ifBlock2.setTarget(il.append(NOP)); } } // Instantiate body of xsl:copy ifBlock4.setTarget(il.append(NOP)); translateContents(classGen, methodGen); // Call the output handler's endElement() if we copied an element // (The DOM.shallowCopy() method calls startElement().) length.setEnd(il.append(new ILOAD(length.getIndex()))); final BranchHandle ifBlock3 = il.append(new IFEQ(null)); il.append(methodGen.loadHandler()); name.setEnd(il.append(new ALOAD(name.getIndex()))); il.append(methodGen.endElement()); final InstructionHandle end = il.append(NOP); ifBlock1.setTarget(end); ifBlock3.setTarget(end); methodGen.removeLocalVariable(name); methodGen.removeLocalVariable(length); }
/** * Compiles code that instantiates a SortingIterator object. * This object's constructor needs referencdes to the current iterator * and a node sort record producing objects as its parameters. */ public static void translateSortIterator(ClassGenerator classGen, MethodGenerator methodGen, Expression nodeSet, Vector sortObjects) { final ConstantPoolGen cpg = classGen.getConstantPool(); final InstructionList il = methodGen.getInstructionList(); // SortingIterator.SortingIterator(NodeIterator,NodeSortRecordFactory); final int init = cpg.addMethodref(SORT_ITERATOR, "<init>", "(" + NODE_ITERATOR_SIG + NODE_SORT_FACTORY_SIG + ")V"); // Backwards branches are prohibited if an uninitialized object is // on the stack by section 4.9.4 of the JVM Specification, 2nd Ed. // We don't know whether this code might contain backwards branches // so we mustn't create the new object until after we've created // the suspect arguments to its constructor. Instead we calculate // the values of the arguments to the constructor first, store them // in temporary variables, create the object and reload the // arguments from the temporaries to avoid the problem. LocalVariableGen nodesTemp = methodGen.addLocalVariable("sort_tmp1", Util.getJCRefType(NODE_ITERATOR_SIG), null, null); LocalVariableGen sortRecordFactoryTemp = methodGen.addLocalVariable("sort_tmp2", Util.getJCRefType(NODE_SORT_FACTORY_SIG), null, null); // Get the current node iterator if (nodeSet == null) { // apply-templates default final int children = cpg.addInterfaceMethodref(DOM_INTF, "getAxisIterator", "(I)"+ NODE_ITERATOR_SIG); il.append(methodGen.loadDOM()); il.append(new PUSH(cpg, Axis.CHILD)); il.append(new INVOKEINTERFACE(children, 2)); } else { nodeSet.translate(classGen, methodGen); } nodesTemp.setStart(il.append(new ASTORE(nodesTemp.getIndex()))); // Compile the code for the NodeSortRecord producing class and pass // that as the last argument to the SortingIterator constructor. compileSortRecordFactory(sortObjects, classGen, methodGen); sortRecordFactoryTemp.setStart( il.append(new ASTORE(sortRecordFactoryTemp.getIndex()))); il.append(new NEW(cpg.addClass(SORT_ITERATOR))); il.append(DUP); nodesTemp.setEnd(il.append(new ALOAD(nodesTemp.getIndex()))); sortRecordFactoryTemp.setEnd( il.append(new ALOAD(sortRecordFactoryTemp.getIndex()))); il.append(new INVOKESPECIAL(init)); }
public void translate(ClassGenerator classGen, MethodGenerator methodGen) { final ConstantPoolGen cpg = classGen.getConstantPool(); final InstructionList il = methodGen.getInstructionList(); if (_path != null) { final int initDFI = cpg.addMethodref(DUP_FILTERED_ITERATOR, "<init>", "(" + NODE_ITERATOR_SIG + ")V"); // Backwards branches are prohibited if an uninitialized object is // on the stack by section 4.9.4 of the JVM Specification, 2nd Ed. // We don't know whether this code might contain backwards branches, // so we mustn't create the new object until after we've created // the suspect arguments to its constructor. Instead we calculate // the values of the arguments to the constructor first, store them // in temporary variables, create the object and reload the // arguments from the temporaries to avoid the problem. // Compile relative path iterator(s) LocalVariableGen pathTemp = methodGen.addLocalVariable("filtered_absolute_location_path_tmp", Util.getJCRefType(NODE_ITERATOR_SIG), null, null); _path.translate(classGen, methodGen); pathTemp.setStart(il.append(new ASTORE(pathTemp.getIndex()))); // Create new Dup Filter Iterator il.append(new NEW(cpg.addClass(DUP_FILTERED_ITERATOR))); il.append(DUP); pathTemp.setEnd(il.append(new ALOAD(pathTemp.getIndex()))); // Initialize Dup Filter Iterator with iterator from the stack il.append(new INVOKESPECIAL(initDFI)); } else { final int git = cpg.addInterfaceMethodref(DOM_INTF, "getIterator", "()"+NODE_ITERATOR_SIG); il.append(methodGen.loadDOM()); il.append(new INVOKEINTERFACE(git, 1)); } }
/** * This method compiles code that is common to matchesFrom() and * matchesCount() in the auxillary class. */ private void compileLocals(NodeCounterGenerator nodeCounterGen, MatchGenerator matchGen, InstructionList il) { int field; LocalVariableGen local; ConstantPoolGen cpg = nodeCounterGen.getConstantPool(); // Get NodeCounter._iterator and store locally local = matchGen.addLocalVariable("iterator", Util.getJCRefType(NODE_ITERATOR_SIG), null, null); field = cpg.addFieldref(NODE_COUNTER, "_iterator", ITERATOR_FIELD_SIG); il.append(ALOAD_0); // 'this' pointer on stack il.append(new GETFIELD(field)); local.setStart(il.append(new ASTORE(local.getIndex()))); matchGen.setIteratorIndex(local.getIndex()); // Get NodeCounter._translet and store locally local = matchGen.addLocalVariable("translet", Util.getJCRefType(TRANSLET_SIG), null, null); field = cpg.addFieldref(NODE_COUNTER, "_translet", "Lcom/sun/org/apache/xalan/internal/xsltc/Translet;"); il.append(ALOAD_0); // 'this' pointer on stack il.append(new GETFIELD(field)); il.append(new CHECKCAST(cpg.addClass(TRANSLET_CLASS))); local.setStart(il.append(new ASTORE(local.getIndex()))); nodeCounterGen.setTransletIndex(local.getIndex()); // Get NodeCounter._document and store locally local = matchGen.addLocalVariable("document", Util.getJCRefType(DOM_INTF_SIG), null, null); field = cpg.addFieldref(_className, "_document", DOM_INTF_SIG); il.append(ALOAD_0); // 'this' pointer on stack il.append(new GETFIELD(field)); // Make sure we have the correct DOM type on the stack!!! local.setStart(il.append(new ASTORE(local.getIndex()))); matchGen.setDomIndex(local.getIndex()); }
public void translate(ClassGenerator classGen, MethodGenerator methodGen) { final ConstantPoolGen cpg = classGen.getConstantPool(); final InstructionList il = methodGen.getInstructionList(); if (_path != null) { final int initAI = cpg.addMethodref(ABSOLUTE_ITERATOR, "<init>", "(" + NODE_ITERATOR_SIG + ")V"); // Compile relative path iterator(s) // // Backwards branches are prohibited if an uninitialized object is // on the stack by section 4.9.4 of the JVM Specification, 2nd Ed. // We don't know whether this code might contain backwards branches, // so we mustn't create the new object until after we've created // this argument to its constructor. Instead we calculate the // value of the argument to the constructor first, store it in // a temporary variable, create the object and reload the argument // from the temporary to avoid the problem. _path.translate(classGen, methodGen); LocalVariableGen relPathIterator = methodGen.addLocalVariable("abs_location_path_tmp", Util.getJCRefType(NODE_ITERATOR_SIG), null, null); relPathIterator.setStart( il.append(new ASTORE(relPathIterator.getIndex()))); // Create new AbsoluteIterator il.append(new NEW(cpg.addClass(ABSOLUTE_ITERATOR))); il.append(DUP); relPathIterator.setEnd( il.append(new ALOAD(relPathIterator.getIndex()))); // Initialize AbsoluteIterator with iterator from the stack il.append(new INVOKESPECIAL(initAI)); } else { final int gitr = cpg.addInterfaceMethodref(DOM_INTF, "getIterator", "()"+NODE_ITERATOR_SIG); il.append(methodGen.loadDOM()); il.append(new INVOKEINTERFACE(gitr, 1)); } }
public void translateStep(ClassGenerator classGen, MethodGenerator methodGen) { final ConstantPoolGen cpg = classGen.getConstantPool(); final InstructionList il = methodGen.getInstructionList(); // Backwards branches are prohibited if an uninitialized object is // on the stack by section 4.9.4 of the JVM Specification, 2nd Ed. // We don't know whether this code might contain backwards branches // so we mustn't create the new object until after we've created // the suspect arguments to its constructor. Instead we calculate // the values of the arguments to the constructor first, store them // in temporary variables, create the object and reload the // arguments from the temporaries to avoid the problem. LocalVariableGen pathTemp = methodGen.addLocalVariable("parent_location_path_tmp1", Util.getJCRefType(NODE_ITERATOR_SIG), null, null); pathTemp.setStart(il.append(new ASTORE(pathTemp.getIndex()))); _step.translate(classGen, methodGen); LocalVariableGen stepTemp = methodGen.addLocalVariable("parent_location_path_tmp2", Util.getJCRefType(NODE_ITERATOR_SIG), null, null); stepTemp.setStart(il.append(new ASTORE(stepTemp.getIndex()))); // Create new StepIterator final int initSI = cpg.addMethodref(STEP_ITERATOR_CLASS, "<init>", "(" +NODE_ITERATOR_SIG +NODE_ITERATOR_SIG +")V"); il.append(new NEW(cpg.addClass(STEP_ITERATOR_CLASS))); il.append(DUP); pathTemp.setEnd(il.append(new ALOAD(pathTemp.getIndex()))); stepTemp.setEnd(il.append(new ALOAD(stepTemp.getIndex()))); // Initialize StepIterator with iterators from the stack il.append(new INVOKESPECIAL(initSI)); // This is a special case for the //* path with or without predicates Expression stp = _step; if (stp instanceof ParentLocationPath) stp = ((ParentLocationPath)stp).getStep(); if ((_path instanceof Step) && (stp instanceof Step)) { final int path = ((Step)_path).getAxis(); final int step = ((Step)stp).getAxis(); if ((path == Axis.DESCENDANTORSELF && step == Axis.CHILD) || (path == Axis.PRECEDING && step == Axis.PARENT)) { final int incl = cpg.addMethodref(NODE_ITERATOR_BASE, "includeSelf", "()" + NODE_ITERATOR_SIG); il.append(new INVOKEVIRTUAL(incl)); } } /* * If this pattern contains a sequence of descendant iterators we * run the risk of returning the same node several times. We put * a new iterator on top of the existing one to assure node order * and prevent returning a single node multiple times. */ if (_orderNodes) { final int order = cpg.addInterfaceMethodref(DOM_INTF, ORDER_ITERATOR, ORDER_ITERATOR_SIG); il.append(methodGen.loadDOM()); il.append(SWAP); il.append(methodGen.loadContextNode()); il.append(new INVOKEINTERFACE(order, 3)); } }
public void translate(ClassGenerator classGen, MethodGenerator methodGen) { final ConstantPoolGen cpg = classGen.getConstantPool(); final InstructionList il = methodGen.getInstructionList(); if (!_isLiteral) { // if the ncname is an AVT, then the ncname has to be checked at runtime if it is a valid ncname LocalVariableGen nameValue = methodGen.addLocalVariable2("nameValue", Util.getJCRefType(STRING_SIG), null); // store the name into a variable first so _name.translate only needs to be called once _name.translate(classGen, methodGen); nameValue.setStart(il.append(new ASTORE(nameValue.getIndex()))); il.append(new ALOAD(nameValue.getIndex())); // call checkNCName if the name is an AVT final int check = cpg.addMethodref(BASIS_LIBRARY_CLASS, "checkNCName", "(" +STRING_SIG +")V"); il.append(new INVOKESTATIC(check)); // Save the current handler base on the stack il.append(methodGen.loadHandler()); il.append(DUP); // first arg to "attributes" call // load name value again nameValue.setEnd(il.append(new ALOAD(nameValue.getIndex()))); } else { // Save the current handler base on the stack il.append(methodGen.loadHandler()); il.append(DUP); // first arg to "attributes" call // Push attribute name _name.translate(classGen, methodGen);// 2nd arg } il.append(classGen.loadTranslet()); il.append(new GETFIELD(cpg.addFieldref(TRANSLET_CLASS, "stringValueHandler", STRING_VALUE_HANDLER_SIG))); il.append(DUP); il.append(methodGen.storeHandler()); // translate contents with substituted handler translateContents(classGen, methodGen); // get String out of the handler il.append(new INVOKEVIRTUAL(cpg.addMethodref(STRING_VALUE_HANDLER, "getValueOfPI", "()" + STRING_SIG))); // call "processingInstruction" final int processingInstruction = cpg.addInterfaceMethodref(TRANSLET_OUTPUT_INTERFACE, "processingInstruction", "(" + STRING_SIG + STRING_SIG + ")V"); il.append(new INVOKEINTERFACE(processingInstruction, 3)); // Restore old handler base from stack il.append(methodGen.storeHandler()); }
/** * At runtime the compilation of xsl:element results in code that: (i) * evaluates the avt for the name, (ii) checks for a prefix in the name * (iii) generates a new prefix and create a new qname when necessary * (iv) calls startElement() on the handler (v) looks up a uri in the XML * when the prefix is not known at compile time (vi) calls namespace() * on the handler (vii) evaluates the contents (viii) calls endElement(). */ public void translate(ClassGenerator classGen, MethodGenerator methodGen) { LocalVariableGen local = null; final ConstantPoolGen cpg = classGen.getConstantPool(); final InstructionList il = methodGen.getInstructionList(); // Optimize translation if element name is a literal if (_isLiteralName) { translateLiteral(classGen, methodGen); return; } if (!_ignore) { // if the qname is an AVT, then the qname has to be checked at runtime if it is a valid qname LocalVariableGen nameValue = methodGen.addLocalVariable2("nameValue", Util.getJCRefType(STRING_SIG), null); // store the name into a variable first so _name.translate only needs to be called once _name.translate(classGen, methodGen); nameValue.setStart(il.append(new ASTORE(nameValue.getIndex()))); il.append(new ALOAD(nameValue.getIndex())); // call checkQName if the name is an AVT final int check = cpg.addMethodref(BASIS_LIBRARY_CLASS, "checkQName", "(" +STRING_SIG +")V"); il.append(new INVOKESTATIC(check)); // Push handler for call to endElement() il.append(methodGen.loadHandler()); // load name value again nameValue.setEnd(il.append(new ALOAD(nameValue.getIndex()))); if (_namespace != null) { _namespace.translate(classGen, methodGen); } else { il.append(ACONST_NULL); } // Push additional arguments il.append(methodGen.loadHandler()); il.append(methodGen.loadDOM()); il.append(methodGen.loadCurrentNode()); // Invoke BasisLibrary.startXslElemCheckQName() il.append(new INVOKESTATIC( cpg.addMethodref(BASIS_LIBRARY_CLASS, "startXslElement", "(" + STRING_SIG + STRING_SIG + TRANSLET_OUTPUT_SIG + DOM_INTF_SIG + "I)" + STRING_SIG))); } translateContents(classGen, methodGen); if (!_ignore) { il.append(methodGen.endElement()); } }
public void translate(ClassGenerator classGen, MethodGenerator methodGen) { final ConstantPoolGen cpg = classGen.getConstantPool(); final InstructionList il = methodGen.getInstructionList(); // Create new StepIterator final int initSI = cpg.addMethodref(STEP_ITERATOR_CLASS, "<init>", "(" +NODE_ITERATOR_SIG +NODE_ITERATOR_SIG +")V"); // Backwards branches are prohibited if an uninitialized object is // on the stack by section 4.9.4 of the JVM Specification, 2nd Ed. // We don't know whether this code might contain backwards branches, // so we mustn't create the new object until after we've created // the suspect arguments to its constructor. Instead we calculate // the values of the arguments to the constructor first, store them // in temporary variables, create the object and reload the // arguments from the temporaries to avoid the problem. // Recursively compile 2 iterators _filterExpr.translate(classGen, methodGen); LocalVariableGen filterTemp = methodGen.addLocalVariable("filter_parent_path_tmp1", Util.getJCRefType(NODE_ITERATOR_SIG), null, null); filterTemp.setStart(il.append(new ASTORE(filterTemp.getIndex()))); _path.translate(classGen, methodGen); LocalVariableGen pathTemp = methodGen.addLocalVariable("filter_parent_path_tmp2", Util.getJCRefType(NODE_ITERATOR_SIG), null, null); pathTemp.setStart(il.append(new ASTORE(pathTemp.getIndex()))); il.append(new NEW(cpg.addClass(STEP_ITERATOR_CLASS))); il.append(DUP); filterTemp.setEnd(il.append(new ALOAD(filterTemp.getIndex()))); pathTemp.setEnd(il.append(new ALOAD(pathTemp.getIndex()))); // Initialize StepIterator with iterators from the stack il.append(new INVOKESPECIAL(initSI)); // This is a special case for the //* path with or without predicates if (_hasDescendantAxis) { final int incl = cpg.addMethodref(NODE_ITERATOR_BASE, "includeSelf", "()" + NODE_ITERATOR_SIG); il.append(new INVOKEVIRTUAL(incl)); } SyntaxTreeNode parent = getParent(); boolean parentAlreadyOrdered = (parent instanceof RelativeLocationPath) || (parent instanceof FilterParentPath) || (parent instanceof KeyCall) || (parent instanceof CurrentCall) || (parent instanceof DocumentCall); if (!parentAlreadyOrdered) { final int order = cpg.addInterfaceMethodref(DOM_INTF, ORDER_ITERATOR, ORDER_ITERATOR_SIG); il.append(methodGen.loadDOM()); il.append(SWAP); il.append(methodGen.loadContextNode()); il.append(new INVOKEINTERFACE(order, 3)); } }
public Instruction STORE(int slot) { return new ASTORE(slot); }
public Instruction storeParameter(int index) { return new ASTORE(index + PARAM_START_INDEX); }