Java Code Examples for com.sun.org.apache.bcel.internal.generic.LocalVariableGen#setEnd()

The following examples show how to use com.sun.org.apache.bcel.internal.generic.LocalVariableGen#setEnd() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: RealType.java    From openjdk-jdk8u-backup with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Translates a real into a non-synthesized boolean. It does not push a
 * 0 or a 1 but instead returns branchhandle list to be appended to the
 * false list. A NaN must be converted to "false".
 *
 * @see     com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateToDesynthesized
 */
public FlowList translateToDesynthesized(ClassGenerator classGen,
                                         MethodGenerator methodGen,
                                         BooleanType type) {
    LocalVariableGen local;
    final FlowList flowlist = new FlowList();
    final ConstantPoolGen cpg = classGen.getConstantPool();
    final InstructionList il = methodGen.getInstructionList();

    // Store real into a local variable
    il.append(DUP2);
    local = methodGen.addLocalVariable("real_to_boolean_tmp",
                                       com.sun.org.apache.bcel.internal.generic.Type.DOUBLE,
                                       null, null);
    local.setStart(il.append(new DSTORE(local.getIndex())));

    // Compare it to 0.0
    il.append(DCONST_0);
    il.append(DCMPG);
    flowlist.add(il.append(new IFEQ(null)));

    //!!! call isNaN
    // Compare it to itself to see if NaN
    il.append(new DLOAD(local.getIndex()));
    local.setEnd(il.append(new DLOAD(local.getIndex())));
    il.append(DCMPG);
    flowlist.add(il.append(new IFNE(null)));        // NaN != NaN
    return flowlist;
}
 
Example 2
Source File: RealType.java    From JDKSourceCode1.8 with MIT License 5 votes vote down vote up
/**
 * Translates a real into a non-synthesized boolean. It does not push a
 * 0 or a 1 but instead returns branchhandle list to be appended to the
 * false list. A NaN must be converted to "false".
 *
 * @see     com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateToDesynthesized
 */
public FlowList translateToDesynthesized(ClassGenerator classGen,
                                         MethodGenerator methodGen,
                                         BooleanType type) {
    LocalVariableGen local;
    final FlowList flowlist = new FlowList();
    final ConstantPoolGen cpg = classGen.getConstantPool();
    final InstructionList il = methodGen.getInstructionList();

    // Store real into a local variable
    il.append(DUP2);
    local = methodGen.addLocalVariable("real_to_boolean_tmp",
                                       com.sun.org.apache.bcel.internal.generic.Type.DOUBLE,
                                       null, null);
    local.setStart(il.append(new DSTORE(local.getIndex())));

    // Compare it to 0.0
    il.append(DCONST_0);
    il.append(DCMPG);
    flowlist.add(il.append(new IFEQ(null)));

    //!!! call isNaN
    // Compare it to itself to see if NaN
    il.append(new DLOAD(local.getIndex()));
    local.setEnd(il.append(new DLOAD(local.getIndex())));
    il.append(DCMPG);
    flowlist.add(il.append(new IFNE(null)));        // NaN != NaN
    return flowlist;
}
 
Example 3
Source File: AncestorPattern.java    From openjdk-jdk8u with GNU General Public License v2.0 4 votes vote down vote up
public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
    InstructionHandle parent;
    final ConstantPoolGen cpg = classGen.getConstantPool();
    final InstructionList il = methodGen.getInstructionList();

    /*
     * The scope of this local var must be the entire method since
     * a another pattern may decide to jump back into the loop
     */
    final LocalVariableGen local =
        methodGen.addLocalVariable2("app", Util.getJCRefType(NODE_SIG),
                                    il.getEnd());

    final com.sun.org.apache.bcel.internal.generic.Instruction loadLocal =
        new ILOAD(local.getIndex());
    final com.sun.org.apache.bcel.internal.generic.Instruction storeLocal =
        new ISTORE(local.getIndex());

    if (_right instanceof StepPattern) {
        il.append(DUP);
        il.append(storeLocal);
        _right.translate(classGen, methodGen);
        il.append(methodGen.loadDOM());
        il.append(loadLocal);
    }
    else {
        _right.translate(classGen, methodGen);

        if (_right instanceof AncestorPattern) {
            il.append(methodGen.loadDOM());
            il.append(SWAP);
        }
    }

    if (_left != null) {
        final int getParent = cpg.addInterfaceMethodref(DOM_INTF,
                                                        GET_PARENT,
                                                        GET_PARENT_SIG);
        parent = il.append(new INVOKEINTERFACE(getParent, 2));

        il.append(DUP);
        il.append(storeLocal);
        _falseList.add(il.append(new IFLT(null)));
        il.append(loadLocal);

        _left.translate(classGen, methodGen);

        final SyntaxTreeNode p = getParent();
        if (p == null || p instanceof Instruction ||
            p instanceof TopLevelElement)
        {
            // do nothing
        }
        else {
            il.append(loadLocal);
        }

        final BranchHandle exit = il.append(new GOTO(null));
        _loop = il.append(methodGen.loadDOM());
        il.append(loadLocal);
        local.setEnd(_loop);
        il.append(new GOTO(parent));
        exit.setTarget(il.append(NOP));
        _left.backPatchFalseList(_loop);

        _trueList.append(_left._trueList);
    }
    else {
        il.append(POP2);
    }

    /*
     * If _right is an ancestor pattern, backpatch this pattern's false
     * list to the loop that searches for more ancestors.
     */
    if (_right instanceof AncestorPattern) {
        final AncestorPattern ancestor = (AncestorPattern) _right;
        _falseList.backPatch(ancestor.getLoopHandle());    // clears list
    }

    _trueList.append(_right._trueList);
    _falseList.append(_right._falseList);
}
 
Example 4
Source File: FilterParentPath.java    From JDKSourceCode1.8 with MIT License 4 votes vote down vote up
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));
    }
}
 
Example 5
Source File: Sort.java    From jdk8u60 with GNU General Public License v2.0 4 votes vote down vote up
/**
 * 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));
}
 
Example 6
Source File: AbsoluteLocationPath.java    From openjdk-8 with GNU General Public License v2.0 4 votes vote down vote up
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));
    }
}
 
Example 7
Source File: AncestorPattern.java    From TencentKona-8 with GNU General Public License v2.0 4 votes vote down vote up
public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
    InstructionHandle parent;
    final ConstantPoolGen cpg = classGen.getConstantPool();
    final InstructionList il = methodGen.getInstructionList();

    /*
     * The scope of this local var must be the entire method since
     * a another pattern may decide to jump back into the loop
     */
    final LocalVariableGen local =
        methodGen.addLocalVariable2("app", Util.getJCRefType(NODE_SIG),
                                    il.getEnd());

    final com.sun.org.apache.bcel.internal.generic.Instruction loadLocal =
        new ILOAD(local.getIndex());
    final com.sun.org.apache.bcel.internal.generic.Instruction storeLocal =
        new ISTORE(local.getIndex());

    if (_right instanceof StepPattern) {
        il.append(DUP);
        il.append(storeLocal);
        _right.translate(classGen, methodGen);
        il.append(methodGen.loadDOM());
        il.append(loadLocal);
    }
    else {
        _right.translate(classGen, methodGen);

        if (_right instanceof AncestorPattern) {
            il.append(methodGen.loadDOM());
            il.append(SWAP);
        }
    }

    if (_left != null) {
        final int getParent = cpg.addInterfaceMethodref(DOM_INTF,
                                                        GET_PARENT,
                                                        GET_PARENT_SIG);
        parent = il.append(new INVOKEINTERFACE(getParent, 2));

        il.append(DUP);
        il.append(storeLocal);
        _falseList.add(il.append(new IFLT(null)));
        il.append(loadLocal);

        _left.translate(classGen, methodGen);

        final SyntaxTreeNode p = getParent();
        if (p == null || p instanceof Instruction ||
            p instanceof TopLevelElement)
        {
            // do nothing
        }
        else {
            il.append(loadLocal);
        }

        final BranchHandle exit = il.append(new GOTO(null));
        _loop = il.append(methodGen.loadDOM());
        il.append(loadLocal);
        local.setEnd(_loop);
        il.append(new GOTO(parent));
        exit.setTarget(il.append(NOP));
        _left.backPatchFalseList(_loop);

        _trueList.append(_left._trueList);
    }
    else {
        il.append(POP2);
    }

    /*
     * If _right is an ancestor pattern, backpatch this pattern's false
     * list to the loop that searches for more ancestors.
     */
    if (_right instanceof AncestorPattern) {
        final AncestorPattern ancestor = (AncestorPattern) _right;
        _falseList.backPatch(ancestor.getLoopHandle());    // clears list
    }

    _trueList.append(_right._trueList);
    _falseList.append(_right._falseList);
}
 
Example 8
Source File: XslElement.java    From openjdk-jdk8u-backup with GNU General Public License v2.0 4 votes vote down vote up
/**
 * 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) {
    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());
    }
}
 
Example 9
Source File: FilteredAbsoluteLocationPath.java    From JDKSourceCode1.8 with MIT License 4 votes vote down vote up
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));
    }
}
 
Example 10
Source File: XslElement.java    From openjdk-8 with GNU General Public License v2.0 4 votes vote down vote up
/**
 * 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());
    }
}
 
Example 11
Source File: StepPattern.java    From openjdk-8-source with GNU General Public License v2.0 4 votes vote down vote up
private void translateSimpleContext(ClassGenerator classGen,
                                    MethodGenerator methodGen) {
    int index;
    final ConstantPoolGen cpg = classGen.getConstantPool();
    final InstructionList il = methodGen.getInstructionList();

    // Store matching node into a local variable
    LocalVariableGen match;
    match = methodGen.addLocalVariable("step_pattern_tmp1",
                                       Util.getJCRefType(NODE_SIG),
                                       null, null);
    match.setStart(il.append(new ISTORE(match.getIndex())));

    // If pattern not reduced then check kernel
    if (!_isEpsilon) {
        il.append(new ILOAD(match.getIndex()));
        translateKernel(classGen, methodGen);
    }

    // Push current iterator and current node on the stack
    il.append(methodGen.loadCurrentNode());
    il.append(methodGen.loadIterator());

    // Create a new matching iterator using the matching node
    index = cpg.addMethodref(MATCHING_ITERATOR, "<init>",
                             "(I" + 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.

    _step.translate(classGen, methodGen);
    LocalVariableGen stepIteratorTemp =
            methodGen.addLocalVariable("step_pattern_tmp2",
                                       Util.getJCRefType(NODE_ITERATOR_SIG),
                                       null, null);
    stepIteratorTemp.setStart(
            il.append(new ASTORE(stepIteratorTemp.getIndex())));

    il.append(new NEW(cpg.addClass(MATCHING_ITERATOR)));
    il.append(DUP);
    il.append(new ILOAD(match.getIndex()));
    stepIteratorTemp.setEnd(
            il.append(new ALOAD(stepIteratorTemp.getIndex())));
    il.append(new INVOKESPECIAL(index));

    // Get the parent of the matching node
    il.append(methodGen.loadDOM());
    il.append(new ILOAD(match.getIndex()));
    index = cpg.addInterfaceMethodref(DOM_INTF, GET_PARENT, GET_PARENT_SIG);
    il.append(new INVOKEINTERFACE(index, 2));

    // Start the iterator with the parent
    il.append(methodGen.setStartNode());

    // Overwrite current iterator and current node
    il.append(methodGen.storeIterator());
    match.setEnd(il.append(new ILOAD(match.getIndex())));
    il.append(methodGen.storeCurrentNode());

    // Translate the expression of the predicate
    Predicate pred = (Predicate) _predicates.elementAt(0);
    Expression exp = pred.getExpr();
    exp.translateDesynthesized(classGen, methodGen);

    // Backpatch true list and restore current iterator/node
    InstructionHandle restore = il.append(methodGen.storeIterator());
    il.append(methodGen.storeCurrentNode());
    exp.backPatchTrueList(restore);
    BranchHandle skipFalse = il.append(new GOTO(null));

    // Backpatch false list and restore current iterator/node
    restore = il.append(methodGen.storeIterator());
    il.append(methodGen.storeCurrentNode());
    exp.backPatchFalseList(restore);
    _falseList.add(il.append(new GOTO(null)));

    // True list falls through
    skipFalse.setTarget(il.append(NOP));
}
 
Example 12
Source File: ProcessingInstruction.java    From TencentKona-8 with GNU General Public License v2.0 4 votes vote down vote up
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());
}
 
Example 13
Source File: ProcessingInstruction.java    From jdk1.8-source-analysis with Apache License 2.0 4 votes vote down vote up
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());
}
 
Example 14
Source File: Sort.java    From openjdk-jdk8u-backup with GNU General Public License v2.0 4 votes vote down vote up
/**
 * 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<Sort> 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));
}
 
Example 15
Source File: Copy.java    From openjdk-jdk8u with GNU General Public License v2.0 4 votes vote down vote up
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);
}
 
Example 16
Source File: AbsoluteLocationPath.java    From openjdk-jdk8u-backup with GNU General Public License v2.0 4 votes vote down vote up
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));
    }
}
 
Example 17
Source File: Sort.java    From JDKSourceCode1.8 with MIT License 4 votes vote down vote up
/**
 * 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<Sort> 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));
}
 
Example 18
Source File: FilterParentPath.java    From Bytecoder with Apache License 2.0 4 votes vote down vote up
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));
    }
}
 
Example 19
Source File: AncestorPattern.java    From jdk1.8-source-analysis with Apache License 2.0 4 votes vote down vote up
public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
    InstructionHandle parent;
    final ConstantPoolGen cpg = classGen.getConstantPool();
    final InstructionList il = methodGen.getInstructionList();

    /*
     * The scope of this local var must be the entire method since
     * a another pattern may decide to jump back into the loop
     */
    final LocalVariableGen local =
        methodGen.addLocalVariable2("app", Util.getJCRefType(NODE_SIG),
                                    il.getEnd());

    final com.sun.org.apache.bcel.internal.generic.Instruction loadLocal =
        new ILOAD(local.getIndex());
    final com.sun.org.apache.bcel.internal.generic.Instruction storeLocal =
        new ISTORE(local.getIndex());

    if (_right instanceof StepPattern) {
        il.append(DUP);
        il.append(storeLocal);
        _right.translate(classGen, methodGen);
        il.append(methodGen.loadDOM());
        il.append(loadLocal);
    }
    else {
        _right.translate(classGen, methodGen);

        if (_right instanceof AncestorPattern) {
            il.append(methodGen.loadDOM());
            il.append(SWAP);
        }
    }

    if (_left != null) {
        final int getParent = cpg.addInterfaceMethodref(DOM_INTF,
                                                        GET_PARENT,
                                                        GET_PARENT_SIG);
        parent = il.append(new INVOKEINTERFACE(getParent, 2));

        il.append(DUP);
        il.append(storeLocal);
        _falseList.add(il.append(new IFLT(null)));
        il.append(loadLocal);

        _left.translate(classGen, methodGen);

        final SyntaxTreeNode p = getParent();
        if (p == null || p instanceof Instruction ||
            p instanceof TopLevelElement)
        {
            // do nothing
        }
        else {
            il.append(loadLocal);
        }

        final BranchHandle exit = il.append(new GOTO(null));
        _loop = il.append(methodGen.loadDOM());
        il.append(loadLocal);
        local.setEnd(_loop);
        il.append(new GOTO(parent));
        exit.setTarget(il.append(NOP));
        _left.backPatchFalseList(_loop);

        _trueList.append(_left._trueList);
    }
    else {
        il.append(POP2);
    }

    /*
     * If _right is an ancestor pattern, backpatch this pattern's false
     * list to the loop that searches for more ancestors.
     */
    if (_right instanceof AncestorPattern) {
        final AncestorPattern ancestor = (AncestorPattern) _right;
        _falseList.backPatch(ancestor.getLoopHandle());    // clears list
    }

    _trueList.append(_right._trueList);
    _falseList.append(_right._falseList);
}
 
Example 20
Source File: AbsolutePathPattern.java    From jdk1.8-source-analysis with Apache License 2.0 4 votes vote down vote up
public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
    final ConstantPoolGen cpg = classGen.getConstantPool();
    final InstructionList il = methodGen.getInstructionList();

    if (_left != null) {
        if (_left instanceof StepPattern) {
            final LocalVariableGen local =
                // absolute path pattern temporary
                methodGen.addLocalVariable2("apptmp",
                                            Util.getJCRefType(NODE_SIG),
                                            null);
            il.append(DUP);
            local.setStart(il.append(new ISTORE(local.getIndex())));
            _left.translate(classGen, methodGen);
            il.append(methodGen.loadDOM());
            local.setEnd(il.append(new ILOAD(local.getIndex())));
            methodGen.removeLocalVariable(local);
        }
        else {
            _left.translate(classGen, methodGen);
        }
    }

    final int getParent = cpg.addInterfaceMethodref(DOM_INTF,
                                                    GET_PARENT,
                                                    GET_PARENT_SIG);
    final int getType = cpg.addInterfaceMethodref(DOM_INTF,
                                                  "getExpandedTypeID",
                                                  "(I)I");

    InstructionHandle begin = il.append(methodGen.loadDOM());
    il.append(SWAP);
    il.append(new INVOKEINTERFACE(getParent, 2));
    if (_left instanceof AncestorPattern) {
        il.append(methodGen.loadDOM());
        il.append(SWAP);
    }
    il.append(new INVOKEINTERFACE(getType, 2));
    il.append(new PUSH(cpg, DTM.DOCUMENT_NODE));

    final BranchHandle skip = il.append(new IF_ICMPEQ(null));
    _falseList.add(il.append(new GOTO_W(null)));
    skip.setTarget(il.append(NOP));

    if (_left != null) {
        _left.backPatchTrueList(begin);

        /*
         * If _left is an ancestor pattern, backpatch this pattern's false
         * list to the loop that searches for more ancestors.
         */
        if (_left instanceof AncestorPattern) {
            final AncestorPattern ancestor = (AncestorPattern) _left;
            _falseList.backPatch(ancestor.getLoopHandle());         // clears list
        }
        _falseList.append(_left._falseList);
    }
}