예제 #1
0
 /**
  * Expects an integer on the stack and pushes a 0 if its value is 0 and a 1 otherwise.
  *
  * @see com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateTo
  */
 public void translateTo(ClassGenerator classGen, MethodGenerator methodGen, BooleanType type) {
   final InstructionList il = methodGen.getInstructionList();
   final BranchHandle falsec = il.append(new IFEQ(null));
   il.append(ICONST_1);
   final BranchHandle truec = il.append(new GOTO(null));
   falsec.setTarget(il.append(ICONST_0));
   truec.setTarget(il.append(NOP));
 }
예제 #2
0
 /** Back patch a flow list. All instruction handles must be branch handles. */
 public void backPatch(InstructionHandle target) {
   if (_elements != null) {
     final int n = _elements.size();
     for (int i = 0; i < n; i++) {
       BranchHandle bh = (BranchHandle) _elements.elementAt(i);
       bh.setTarget(target);
     }
     _elements.clear(); // avoid backpatching more than once
   }
 }
예제 #3
0
  public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
    final ConstantPoolGen cpg = classGen.getConstantPool();
    final InstructionList il = methodGen.getInstructionList();

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

    // Collect sort objects associated with this instruction
    final Vector sortObjects = new Vector();
    Enumeration children = elements();
    while (children.hasMoreElements()) {
      final Object child = children.nextElement();
      if (child instanceof Sort) {
        sortObjects.addElement(child);
      }
    }

    if ((_type != null) && (_type instanceof ResultTreeType)) {
      // Store existing DOM on stack - must be restored when loop is done
      il.append(methodGen.loadDOM());

      // <xsl:sort> cannot be applied to a result tree - issue warning
      if (sortObjects.size() > 0) {
        ErrorMsg msg = new ErrorMsg(ErrorMsg.RESULT_TREE_SORT_ERR, this);
        getParser().reportError(WARNING, msg);
      }

      // Put the result tree on the stack (DOM)
      _select.translate(classGen, methodGen);
      // Get an iterator for the whole DOM - excluding the root node
      _type.translateTo(classGen, methodGen, Type.NodeSet);
      // Store the result tree as the default DOM
      il.append(SWAP);
      il.append(methodGen.storeDOM());
    } else {
      // Compile node iterator
      if (sortObjects.size() > 0) {
        Sort.translateSortIterator(classGen, methodGen, _select, sortObjects);
      } else {
        _select.translate(classGen, methodGen);
      }

      if (_type instanceof ReferenceType == false) {
        il.append(methodGen.loadContextNode());
        il.append(methodGen.setStartNode());
      }
    }

    // Overwrite current iterator
    il.append(methodGen.storeIterator());

    // Give local variables (if any) default values before starting loop
    initializeVariables(classGen, methodGen);

    final BranchHandle nextNode = il.append(new GOTO(null));
    final InstructionHandle loop = il.append(NOP);

    translateContents(classGen, methodGen);

    nextNode.setTarget(il.append(methodGen.loadIterator()));
    il.append(methodGen.nextNode());
    il.append(DUP);
    il.append(methodGen.storeCurrentNode());
    il.append(new IFGT(loop));

    // Restore current DOM (if result tree was used instead for this loop)
    if ((_type != null) && (_type instanceof ResultTreeType)) {
      il.append(methodGen.storeDOM());
    }

    // Restore current node and current iterator from the stack
    il.append(methodGen.storeIterator());
    il.append(methodGen.storeCurrentNode());
  }
예제 #4
0
  public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
    final ConstantPoolGen cpg = classGen.getConstantPool();
    final InstructionList il = methodGen.getInstructionList();

    final Type tleft = _left.getType();
    Type tright = _right.getType();

    if (tleft instanceof BooleanType || tleft instanceof NumberType) {
      translateDesynthesized(classGen, methodGen);
      synthesize(classGen, methodGen);
      return;
    }

    if (tleft instanceof StringType) {
      final int equals = cpg.addMethodref(STRING_CLASS, "equals", "(" + OBJECT_SIG + ")Z");
      _left.translate(classGen, methodGen);
      _right.translate(classGen, methodGen);
      il.append(new INVOKEVIRTUAL(equals));

      if (_op == Operators.NE) {
        il.append(ICONST_1);
        il.append(IXOR); // not x <-> x xor 1
      }
      return;
    }

    BranchHandle truec, falsec;

    if (tleft instanceof ResultTreeType) {
      if (tright instanceof BooleanType) {
        _right.translate(classGen, methodGen);
        if (_op == Operators.NE) {
          il.append(ICONST_1);
          il.append(IXOR); // not x <-> x xor 1
        }
        return;
      }

      if (tright instanceof RealType) {
        _left.translate(classGen, methodGen);
        tleft.translateTo(classGen, methodGen, Type.Real);
        _right.translate(classGen, methodGen);

        il.append(DCMPG);
        falsec =
            il.append(
                _op == Operators.EQ
                    ? (BranchInstruction) new IFNE(null)
                    : (BranchInstruction) new IFEQ(null));
        il.append(ICONST_1);
        truec = il.append(new GOTO(null));
        falsec.setTarget(il.append(ICONST_0));
        truec.setTarget(il.append(NOP));
        return;
      }

      // Next, result-tree/string and result-tree/result-tree comparisons

      _left.translate(classGen, methodGen);
      tleft.translateTo(classGen, methodGen, Type.String);
      _right.translate(classGen, methodGen);

      if (tright instanceof ResultTreeType) {
        tright.translateTo(classGen, methodGen, Type.String);
      }

      final int equals = cpg.addMethodref(STRING_CLASS, "equals", "(" + OBJECT_SIG + ")Z");
      il.append(new INVOKEVIRTUAL(equals));

      if (_op == Operators.NE) {
        il.append(ICONST_1);
        il.append(IXOR); // not x <-> x xor 1
      }
      return;
    }

    if (tleft instanceof NodeSetType && tright instanceof BooleanType) {
      _left.translate(classGen, methodGen);
      _left.startIterator(classGen, methodGen);
      Type.NodeSet.translateTo(classGen, methodGen, Type.Boolean);
      _right.translate(classGen, methodGen);

      il.append(IXOR); // x != y <-> x xor y
      if (_op == Operators.EQ) {
        il.append(ICONST_1);
        il.append(IXOR); // not x <-> x xor 1
      }
      return;
    }

    if (tleft instanceof NodeSetType && tright instanceof StringType) {
      _left.translate(classGen, methodGen);
      _left.startIterator(classGen, methodGen); // needed ?
      _right.translate(classGen, methodGen);
      il.append(new PUSH(cpg, _op));
      il.append(methodGen.loadDOM());
      final int cmp =
          cpg.addMethodref(
              BASIS_LIBRARY_CLASS,
              "compare",
              "(" + tleft.toSignature() + tright.toSignature() + "I" + DOM_INTF_SIG + ")Z");
      il.append(new INVOKESTATIC(cmp));
      return;
    }

    // Next, node-set/t for t in {real, string, node-set, result-tree}
    _left.translate(classGen, methodGen);
    _left.startIterator(classGen, methodGen);
    _right.translate(classGen, methodGen);
    _right.startIterator(classGen, methodGen);

    // Cast a result tree to a string to use an existing compare
    if (tright instanceof ResultTreeType) {
      tright.translateTo(classGen, methodGen, Type.String);
      tright = Type.String;
    }

    // Call the appropriate compare() from the BasisLibrary
    il.append(new PUSH(cpg, _op));
    il.append(methodGen.loadDOM());

    final int compare =
        cpg.addMethodref(
            BASIS_LIBRARY_CLASS,
            "compare",
            "(" + tleft.toSignature() + tright.toSignature() + "I" + DOM_INTF_SIG + ")Z");
    il.append(new INVOKESTATIC(compare));
  }