public void translateDesynthesized(ClassGenerator classGen, MethodGenerator methodGen) {
    final Type tleft = _left.getType();
    final InstructionList il = methodGen.getInstructionList();

    if (tleft instanceof BooleanType) {
      _left.translate(classGen, methodGen);
      _right.translate(classGen, methodGen);
      _falseList.add(
          il.append(
              _op == Operators.EQ
                  ? (BranchInstruction) new IF_ICMPNE(null)
                  : (BranchInstruction) new IF_ICMPEQ(null)));
    } else if (tleft instanceof NumberType) {
      _left.translate(classGen, methodGen);
      _right.translate(classGen, methodGen);

      if (tleft instanceof RealType) {
        il.append(DCMPG);
        _falseList.add(
            il.append(
                _op == Operators.EQ
                    ? (BranchInstruction) new IFNE(null)
                    : (BranchInstruction) new IFEQ(null)));
      } else {
        _falseList.add(
            il.append(
                _op == Operators.EQ
                    ? (BranchInstruction) new IF_ICMPNE(null)
                    : (BranchInstruction) new IF_ICMPEQ(null)));
      }
    } else {
      translate(classGen, methodGen);
      desynthesize(classGen, methodGen);
    }
  }
Beispiel #2
0
  /**
   * 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());
    }
  }
  public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
    if (elementCount() == 1) {
      final Expression exp = (Expression) elementAt(0);
      exp.translate(classGen, methodGen);
    } else {
      final ConstantPoolGen cpg = classGen.getConstantPool();
      final InstructionList il = methodGen.getInstructionList();
      final int initBuffer = cpg.addMethodref(STRING_BUFFER_CLASS, "<init>", "()V");
      final Instruction append =
          new INVOKEVIRTUAL(
              cpg.addMethodref(
                  STRING_BUFFER_CLASS, "append", "(" + STRING_SIG + ")" + STRING_BUFFER_SIG));

      final int toString = cpg.addMethodref(STRING_BUFFER_CLASS, "toString", "()" + STRING_SIG);
      il.append(new NEW(cpg.addClass(STRING_BUFFER_CLASS)));
      il.append(DUP);
      il.append(new INVOKESPECIAL(initBuffer));
      // StringBuffer is on the stack
      final Iterator<SyntaxTreeNode> elements = elements();
      while (elements.hasNext()) {
        final Expression exp = (Expression) elements.next();
        exp.translate(classGen, methodGen);
        il.append(append);
      }
      il.append(new INVOKEVIRTUAL(toString));
    }
  }
Beispiel #4
0
  public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
    final InstructionList il = methodGen.getInstructionList();

    _left.translate(classGen, methodGen);
    _right.translate(classGen, methodGen);

    switch (_op) {
      case PLUS:
        il.append(_type.ADD());
        break;
      case MINUS:
        il.append(_type.SUB());
        break;
      case TIMES:
        il.append(_type.MUL());
        break;
      case DIV:
        il.append(_type.DIV());
        break;
      case MOD:
        il.append(_type.REM());
        break;
      default:
        ErrorMsg msg = new ErrorMsg(ErrorMsg.ILLEGAL_BINARY_OP_ERR, this);
        getParser().reportError(Constants.ERROR, msg);
    }
  }
Beispiel #5
0
  /**
   * 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);
    }
  }
  public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
    final ConstantPoolGen cpg = classGen.getConstantPool();
    final InstructionList il = methodGen.getInstructionList();

    _right.translate(classGen, methodGen);
    il.append(new CHECKCAST(cpg.addClass(_className)));
  }
 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));
 }
  /**
   * 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));
  }
Beispiel #9
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());
  }
 /**
  * This method compiles code for the select expression for this xsl:sort element. The method is
  * called from the static code-generating methods in this class.
  */
 public void translateSelect(ClassGenerator classGen, MethodGenerator methodGen) {
   _select.translate(classGen, methodGen);
 }
Beispiel #11
0
  /**
   * Create a new "Filter" class implementing <code>CurrentNodeListFilter</code>. Allocate registers
   * for local variables and local parameters passed in the closure to test(). Notice that local
   * variables need to be "unboxed".
   */
  private void compileFilter(ClassGenerator classGen, MethodGenerator methodGen) {
    TestGenerator testGen;
    LocalVariableGen local;
    FilterGenerator filterGen;

    _className = getXSLTC().getHelperClassName();
    filterGen =
        new FilterGenerator(
            _className,
            "java.lang.Object",
            toString(),
            ACC_PUBLIC | ACC_SUPER,
            new String[] {CURRENT_NODE_LIST_FILTER},
            classGen.getStylesheet());

    final ConstantPoolGen cpg = filterGen.getConstantPool();
    final int length = (_closureVars == null) ? 0 : _closureVars.size();

    // Add a new instance variable for each var in closure
    for (int i = 0; i < length; i++) {
      VariableBase var = ((VariableRefBase) _closureVars.get(i)).getVariable();

      filterGen.addField(
          new Field(
              ACC_PUBLIC,
              cpg.addUtf8(var.getEscapedName()),
              cpg.addUtf8(var.getType().toSignature()),
              null,
              cpg.getConstantPool()));
    }

    final InstructionList il = new InstructionList();
    testGen =
        new TestGenerator(
            ACC_PUBLIC | ACC_FINAL,
            org.apache.bcel.generic.Type.BOOLEAN,
            new org.apache.bcel.generic.Type[] {
              org.apache.bcel.generic.Type.INT,
              org.apache.bcel.generic.Type.INT,
              org.apache.bcel.generic.Type.INT,
              org.apache.bcel.generic.Type.INT,
              Util.getJCRefType(TRANSLET_SIG),
              Util.getJCRefType(NODE_ITERATOR_SIG)
            },
            new String[] {"node", "position", "last", "current", "translet", "iterator"},
            "test",
            _className,
            il,
            cpg);

    // Store the dom in a local variable
    local = testGen.addLocalVariable("document", Util.getJCRefType(DOM_INTF_SIG), null, null);
    final String className = classGen.getClassName();
    il.append(filterGen.loadTranslet());
    il.append(new CHECKCAST(cpg.addClass(className)));
    il.append(new GETFIELD(cpg.addFieldref(className, DOM_FIELD, DOM_INTF_SIG)));
    local.setStart(il.append(new ASTORE(local.getIndex())));

    // Store the dom index in the test generator
    testGen.setDomIndex(local.getIndex());

    _exp.translate(filterGen, testGen);
    il.append(IRETURN);

    filterGen.addEmptyConstructor(ACC_PUBLIC);
    filterGen.addMethod(testGen);

    getXSLTC().dumpClass(filterGen.getJavaClass());
  }
Beispiel #12
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));
  }
  /**
   * Translate a function call. The compiled code will leave the function's return value on the
   * JVM's stack.
   */
  public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
    final int n = argumentCount();
    final ConstantPoolGen cpg = classGen.getConstantPool();
    final InstructionList il = methodGen.getInstructionList();
    final boolean isSecureProcessing = classGen.getParser().getXSLTC().isSecureProcessing();
    int index;

    // Translate calls to methods in the BasisLibrary
    if (isStandard() || isExtension()) {
      for (int i = 0; i < n; i++) {
        final Expression exp = argument(i);
        exp.translate(classGen, methodGen);
        exp.startIterator(classGen, methodGen);
      }

      // append "F" to the function's name
      final String name = _fname.toString().replace('-', '_') + "F";
      String args = Constants.EMPTYSTRING;

      // Special precautions for some method calls
      if (name.equals("sumF")) {
        args = DOM_INTF_SIG;
        il.append(methodGen.loadDOM());
      } else if (name.equals("normalize_spaceF")) {
        if (_chosenMethodType.toSignature(args).equals("()Ljava/lang/String;")) {
          args = "I" + DOM_INTF_SIG;
          il.append(methodGen.loadContextNode());
          il.append(methodGen.loadDOM());
        }
      }

      // Invoke the method in the basis library
      index = cpg.addMethodref(BASIS_LIBRARY_CLASS, name, _chosenMethodType.toSignature(args));
      il.append(new INVOKESTATIC(index));
    }
    // Add call to BasisLibrary.unresolved_externalF() to generate
    // run-time error message for unsupported external functions
    else if (unresolvedExternal) {
      index =
          cpg.addMethodref(BASIS_LIBRARY_CLASS, "unresolved_externalF", "(Ljava/lang/String;)V");
      il.append(new PUSH(cpg, _fname.toString()));
      il.append(new INVOKESTATIC(index));
    } else if (_isExtConstructor) {
      if (isSecureProcessing) translateUnallowedExtension(cpg, il);

      final String clazz = _chosenConstructor.getDeclaringClass().getName();
      Class[] paramTypes = _chosenConstructor.getParameterTypes();
      LocalVariableGen[] paramTemp = new LocalVariableGen[n];

      // 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.

      for (int i = 0; i < n; i++) {
        final Expression exp = argument(i);
        Type expType = exp.getType();
        exp.translate(classGen, methodGen);
        // Convert the argument to its Java type
        exp.startIterator(classGen, methodGen);
        expType.translateTo(classGen, methodGen, paramTypes[i]);
        paramTemp[i] =
            methodGen.addLocalVariable(
                "function_call_tmp" + i, expType.toJCType(), il.getEnd(), null);
        il.append(expType.STORE(paramTemp[i].getIndex()));
      }

      il.append(new NEW(cpg.addClass(_className)));
      il.append(InstructionConstants.DUP);

      for (int i = 0; i < n; i++) {
        final Expression arg = argument(i);
        il.append(arg.getType().LOAD(paramTemp[i].getIndex()));
      }

      final StringBuffer buffer = new StringBuffer();
      buffer.append('(');
      for (int i = 0; i < paramTypes.length; i++) {
        buffer.append(getSignature(paramTypes[i]));
      }
      buffer.append(')');
      buffer.append("V");

      index = cpg.addMethodref(clazz, "<init>", buffer.toString());
      il.append(new INVOKESPECIAL(index));

      // Convert the return type back to our internal type
      (Type.Object).translateFrom(classGen, methodGen, _chosenConstructor.getDeclaringClass());

    }
    // Invoke function calls that are handled in separate classes
    else {
      if (isSecureProcessing) translateUnallowedExtension(cpg, il);

      final String clazz = _chosenMethod.getDeclaringClass().getName();
      Class[] paramTypes = _chosenMethod.getParameterTypes();

      // Push "this" if it is an instance method
      if (_thisArgument != null) {
        _thisArgument.translate(classGen, methodGen);
      }

      for (int i = 0; i < n; i++) {
        final Expression exp = argument(i);
        exp.translate(classGen, methodGen);
        // Convert the argument to its Java type
        exp.startIterator(classGen, methodGen);
        exp.getType().translateTo(classGen, methodGen, paramTypes[i]);
      }

      final StringBuffer buffer = new StringBuffer();
      buffer.append('(');
      for (int i = 0; i < paramTypes.length; i++) {
        buffer.append(getSignature(paramTypes[i]));
      }
      buffer.append(')');
      buffer.append(getSignature(_chosenMethod.getReturnType()));

      if (_thisArgument != null && _clazz.isInterface()) {
        index = cpg.addInterfaceMethodref(clazz, _fname.getLocalPart(), buffer.toString());
        il.append(new INVOKEINTERFACE(index, n + 1));
      } else {
        index = cpg.addMethodref(clazz, _fname.getLocalPart(), buffer.toString());
        il.append(
            _thisArgument != null
                ? (InvokeInstruction) new INVOKEVIRTUAL(index)
                : (InvokeInstruction) new INVOKESTATIC(index));
      }

      // Convert the return type back to our internal type
      _type.translateFrom(classGen, methodGen, _chosenMethod.getReturnType());
    }
  }