Пример #1
0
 @Override
 public Constant createConstant(ConstantPoolGen cpg) {
   MethodRef method = getValue();
   int i = cpg.addClass(method.getClassName());
   int n = cpg.addNameAndType(method.getName(), method.getDescriptor().toString());
   return new ConstantMethodref(i, n);
 }
Пример #2
0
  /**
   * Creates the default, nameless, DecimalFormat object in AbstractTranslet's format_symbols
   * hashtable. This should be called for every stylesheet, and the entry may be overridden by later
   * nameless xsl:decimal-format instructions.
   */
  public static void translateDefaultDFS(ClassGenerator classGen, MethodGenerator methodGen) {

    ConstantPoolGen cpg = classGen.getConstantPool();
    InstructionList il = methodGen.getInstructionList();
    final int init = cpg.addMethodref(DFS_CLASS, "<init>", "(" + LOCALE_SIG + ")V");

    // Push the format name, which is empty, on the stack
    // for call to addDecimalFormat()
    il.append(classGen.loadTranslet());
    il.append(new PUSH(cpg, EMPTYSTRING));

    // Manufacture a DecimalFormatSymbols on the stack for
    // call to addDecimalFormat().  Use the US Locale as the
    // default, as most of its settings are equivalent to
    // the default settings required of xsl:decimal-format -
    // except for the NaN and infinity attributes.
    il.append(new NEW(cpg.addClass(DFS_CLASS)));
    il.append(DUP);
    il.append(new GETSTATIC(cpg.addFieldref(LOCALE_CLASS, "US", LOCALE_SIG)));
    il.append(new INVOKESPECIAL(init));

    int nan = cpg.addMethodref(DFS_CLASS, "setNaN", "(Ljava/lang/String;)V");
    il.append(DUP);
    il.append(new PUSH(cpg, "NaN"));
    il.append(new INVOKEVIRTUAL(nan));

    int inf = cpg.addMethodref(DFS_CLASS, "setInfinity", "(Ljava/lang/String;)V");
    il.append(DUP);
    il.append(new PUSH(cpg, "Infinity"));
    il.append(new INVOKEVIRTUAL(inf));

    final int put =
        cpg.addMethodref(TRANSLET_CLASS, "addDecimalFormat", "(" + STRING_SIG + DFS_SIG + ")V");
    il.append(new INVOKEVIRTUAL(put));
  }
  /**
   * 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));
  }
Пример #4
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);
    }
  }
Пример #5
0
  /**
   * Translate a predicate expression. This translation pushes two references on the stack: a
   * reference to a newly created filter object and a reference to the predicate's closure.
   */
  public void translateFilter(ClassGenerator classGen, MethodGenerator methodGen) {
    final ConstantPoolGen cpg = classGen.getConstantPool();
    final InstructionList il = methodGen.getInstructionList();

    // Compile auxiliary class for filter
    compileFilter(classGen, methodGen);

    // Create new instance of filter
    il.append(new NEW(cpg.addClass(_className)));
    il.append(DUP);
    il.append(new INVOKESPECIAL(cpg.addMethodref(_className, "<init>", "()V")));

    // Initialize closure variables
    final int length = (_closureVars == null) ? 0 : _closureVars.size();

    for (int i = 0; i < length; i++) {
      VariableRefBase varRef = (VariableRefBase) _closureVars.get(i);
      VariableBase var = varRef.getVariable();
      Type varType = var.getType();

      il.append(DUP);

      // Find nearest closure implemented as an inner class
      Closure variableClosure = _parentClosure;
      while (variableClosure != null) {
        if (variableClosure.inInnerClass()) break;
        variableClosure = variableClosure.getParentClosure();
      }

      // Use getfield if in an inner class
      if (variableClosure != null) {
        il.append(ALOAD_0);
        il.append(
            new GETFIELD(
                cpg.addFieldref(
                    variableClosure.getInnerClassName(),
                    var.getEscapedName(),
                    varType.toSignature())));
      } else {
        // Use a load of instruction if in translet class
        il.append(var.loadInstruction());
      }

      // Store variable in new closure
      il.append(
          new PUTFIELD(cpg.addFieldref(_className, var.getEscapedName(), varType.toSignature())));
    }
  }
Пример #6
0
  /**
   * This method is called when the constructor is compiled in Stylesheet.compileConstructor() and
   * not as the syntax tree is traversed.
   */
  public void translate(ClassGenerator classGen, MethodGenerator methodGen) {

    ConstantPoolGen cpg = classGen.getConstantPool();
    InstructionList il = methodGen.getInstructionList();

    // DecimalFormatSymbols.<init>(Locale);
    // xsl:decimal-format - except for the NaN and infinity attributes.
    final int init = cpg.addMethodref(DFS_CLASS, "<init>", "(" + LOCALE_SIG + ")V");

    // Push the format name on the stack for call to addDecimalFormat()
    il.append(classGen.loadTranslet());
    il.append(new PUSH(cpg, _name.toString()));

    // Manufacture a DecimalFormatSymbols on the stack
    // for call to addDecimalFormat()
    // Use the US Locale as the default, as most of its settings
    // are equivalent to the default settings required of
    il.append(new NEW(cpg.addClass(DFS_CLASS)));
    il.append(DUP);
    il.append(new GETSTATIC(cpg.addFieldref(LOCALE_CLASS, "US", LOCALE_SIG)));
    il.append(new INVOKESPECIAL(init));

    String tmp = getAttribute("NaN");
    if ((tmp == null) || (tmp.equals(EMPTYSTRING))) {
      int nan = cpg.addMethodref(DFS_CLASS, "setNaN", "(Ljava/lang/String;)V");
      il.append(DUP);
      il.append(new PUSH(cpg, "NaN"));
      il.append(new INVOKEVIRTUAL(nan));
    }

    tmp = getAttribute("infinity");
    if ((tmp == null) || (tmp.equals(EMPTYSTRING))) {
      int inf = cpg.addMethodref(DFS_CLASS, "setInfinity", "(Ljava/lang/String;)V");
      il.append(DUP);
      il.append(new PUSH(cpg, "Infinity"));
      il.append(new INVOKEVIRTUAL(inf));
    }

    final int nAttributes = _attributes.getLength();
    for (int i = 0; i < nAttributes; i++) {
      final String name = _attributes.getQName(i);
      final String value = _attributes.getValue(i);

      boolean valid = true;
      int method = 0;

      if (name.equals("decimal-separator")) {
        // DecimalFormatSymbols.setDecimalSeparator();
        method = cpg.addMethodref(DFS_CLASS, "setDecimalSeparator", "(C)V");
      } else if (name.equals("grouping-separator")) {
        method = cpg.addMethodref(DFS_CLASS, "setGroupingSeparator", "(C)V");
      } else if (name.equals("minus-sign")) {
        method = cpg.addMethodref(DFS_CLASS, "setMinusSign", "(C)V");
      } else if (name.equals("percent")) {
        method = cpg.addMethodref(DFS_CLASS, "setPercent", "(C)V");
      } else if (name.equals("per-mille")) {
        method = cpg.addMethodref(DFS_CLASS, "setPerMill", "(C)V");
      } else if (name.equals("zero-digit")) {
        method = cpg.addMethodref(DFS_CLASS, "setZeroDigit", "(C)V");
      } else if (name.equals("digit")) {
        method = cpg.addMethodref(DFS_CLASS, "setDigit", "(C)V");
      } else if (name.equals("pattern-separator")) {
        method = cpg.addMethodref(DFS_CLASS, "setPatternSeparator", "(C)V");
      } else if (name.equals("NaN")) {
        method = cpg.addMethodref(DFS_CLASS, "setNaN", "(Ljava/lang/String;)V");
        il.append(DUP);
        il.append(new PUSH(cpg, value));
        il.append(new INVOKEVIRTUAL(method));
        valid = false;
      } else if (name.equals("infinity")) {
        method = cpg.addMethodref(DFS_CLASS, "setInfinity", "(Ljava/lang/String;)V");
        il.append(DUP);
        il.append(new PUSH(cpg, value));
        il.append(new INVOKEVIRTUAL(method));
        valid = false;
      } else {
        valid = false;
      }

      if (valid) {
        il.append(DUP);
        il.append(new PUSH(cpg, value.charAt(0)));
        il.append(new INVOKEVIRTUAL(method));
      }
    }

    final int put =
        cpg.addMethodref(TRANSLET_CLASS, "addDecimalFormat", "(" + STRING_SIG + DFS_SIG + ")V");
    il.append(new INVOKEVIRTUAL(put));
  }
  public static String compileSortRecordFactory(
      Vector sortObjects,
      ClassGenerator classGen,
      MethodGenerator methodGen,
      String sortRecordClass) {
    final XSLTC xsltc = ((Sort) sortObjects.firstElement()).getXSLTC();
    final String className = xsltc.getHelperClassName();

    final NodeSortRecordFactGenerator sortRecordFactory =
        new NodeSortRecordFactGenerator(
            className,
            NODE_SORT_FACTORY,
            className + ".java",
            ACC_PUBLIC | ACC_SUPER | ACC_FINAL,
            new String[] {},
            classGen.getStylesheet());

    ConstantPoolGen cpg = sortRecordFactory.getConstantPool();

    // Add a new instance variable for each var in closure
    final int nsorts = sortObjects.size();
    final ArrayList dups = new ArrayList();

    for (int j = 0; j < nsorts; j++) {
      final Sort sort = (Sort) sortObjects.get(j);
      final int length = (sort._closureVars == null) ? 0 : sort._closureVars.size();

      for (int i = 0; i < length; i++) {
        final VariableRefBase varRef = (VariableRefBase) sort._closureVars.get(i);

        // Discard duplicate variable references
        if (dups.contains(varRef)) continue;

        final VariableBase var = varRef.getVariable();
        sortRecordFactory.addField(
            new Field(
                ACC_PUBLIC,
                cpg.addUtf8(var.getEscapedName()),
                cpg.addUtf8(var.getType().toSignature()),
                null,
                cpg.getConstantPool()));
        dups.add(varRef);
      }
    }

    // Define a constructor for this class
    final org.apache.bcel.generic.Type[] argTypes = new org.apache.bcel.generic.Type[7];
    argTypes[0] = Util.getJCRefType(DOM_INTF_SIG);
    argTypes[1] = Util.getJCRefType(STRING_SIG);
    argTypes[2] = Util.getJCRefType(TRANSLET_INTF_SIG);
    argTypes[3] = Util.getJCRefType("[" + STRING_SIG);
    argTypes[4] = Util.getJCRefType("[" + STRING_SIG);
    argTypes[5] = Util.getJCRefType("[" + STRING_SIG);
    argTypes[6] = Util.getJCRefType("[" + STRING_SIG);

    final String[] argNames = new String[7];
    argNames[0] = DOCUMENT_PNAME;
    argNames[1] = "className";
    argNames[2] = TRANSLET_PNAME;
    argNames[3] = "order";
    argNames[4] = "type";
    argNames[5] = "lang";
    argNames[6] = "case_order";

    InstructionList il = new InstructionList();
    final MethodGenerator constructor =
        new MethodGenerator(
            ACC_PUBLIC,
            org.apache.bcel.generic.Type.VOID,
            argTypes,
            argNames,
            "<init>",
            className,
            il,
            cpg);

    // Push all parameters onto the stack and called super.<init>()
    il.append(ALOAD_0);
    il.append(ALOAD_1);
    il.append(ALOAD_2);
    il.append(new ALOAD(3));
    il.append(new ALOAD(4));
    il.append(new ALOAD(5));
    il.append(new ALOAD(6));
    il.append(new ALOAD(7));
    il.append(
        new INVOKESPECIAL(
            cpg.addMethodref(
                NODE_SORT_FACTORY,
                "<init>",
                "("
                    + DOM_INTF_SIG
                    + STRING_SIG
                    + TRANSLET_INTF_SIG
                    + "["
                    + STRING_SIG
                    + "["
                    + STRING_SIG
                    + "["
                    + STRING_SIG
                    + "["
                    + STRING_SIG
                    + ")V")));
    il.append(RETURN);

    // Override the definition of makeNodeSortRecord()
    il = new InstructionList();
    final MethodGenerator makeNodeSortRecord =
        new MethodGenerator(
            ACC_PUBLIC,
            Util.getJCRefType(NODE_SORT_RECORD_SIG),
            new org.apache.bcel.generic.Type[] {
              org.apache.bcel.generic.Type.INT, org.apache.bcel.generic.Type.INT
            },
            new String[] {"node", "last"},
            "makeNodeSortRecord",
            className,
            il,
            cpg);

    il.append(ALOAD_0);
    il.append(ILOAD_1);
    il.append(ILOAD_2);
    il.append(
        new INVOKESPECIAL(
            cpg.addMethodref(
                NODE_SORT_FACTORY, "makeNodeSortRecord", "(II)" + NODE_SORT_RECORD_SIG)));
    il.append(DUP);
    il.append(new CHECKCAST(cpg.addClass(sortRecordClass)));

    // Initialize closure in record class
    final int ndups = dups.size();
    for (int i = 0; i < ndups; i++) {
      final VariableRefBase varRef = (VariableRefBase) dups.get(i);
      final VariableBase var = varRef.getVariable();
      final Type varType = var.getType();

      il.append(DUP);

      // Get field from factory class
      il.append(ALOAD_0);
      il.append(
          new GETFIELD(cpg.addFieldref(className, var.getEscapedName(), varType.toSignature())));

      // Put field in record class
      il.append(
          new PUTFIELD(
              cpg.addFieldref(sortRecordClass, var.getEscapedName(), varType.toSignature())));
    }
    il.append(POP);
    il.append(ARETURN);

    constructor.setMaxLocals();
    constructor.setMaxStack();
    sortRecordFactory.addMethod(constructor);
    makeNodeSortRecord.setMaxLocals();
    makeNodeSortRecord.setMaxStack();
    sortRecordFactory.addMethod(makeNodeSortRecord);
    xsltc.dumpClass(sortRecordFactory.getJavaClass());

    return className;
  }
  /**
   * Compiles code that instantiates a NodeSortRecordFactory object which will produce
   * NodeSortRecord objects of a specific type.
   */
  public static void compileSortRecordFactory(
      Vector sortObjects, ClassGenerator classGen, MethodGenerator methodGen) {
    String sortRecordClass = compileSortRecord(sortObjects, classGen, methodGen);

    boolean needsSortRecordFactory = false;
    final int nsorts = sortObjects.size();
    for (int i = 0; i < nsorts; i++) {
      final Sort sort = (Sort) sortObjects.elementAt(i);
      needsSortRecordFactory |= sort._needsSortRecordFactory;
    }

    String sortRecordFactoryClass = NODE_SORT_FACTORY;
    if (needsSortRecordFactory) {
      sortRecordFactoryClass =
          compileSortRecordFactory(sortObjects, classGen, methodGen, sortRecordClass);
    }

    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.

    // Compile code that initializes the static _sortOrder
    LocalVariableGen sortOrderTemp =
        methodGen.addLocalVariable(
            "sort_order_tmp", Util.getJCRefType("[" + STRING_SIG), null, null);
    il.append(new PUSH(cpg, nsorts));
    il.append(new ANEWARRAY(cpg.addClass(STRING)));
    for (int level = 0; level < nsorts; level++) {
      final Sort sort = (Sort) sortObjects.elementAt(level);
      il.append(DUP);
      il.append(new PUSH(cpg, level));
      sort.translateSortOrder(classGen, methodGen);
      il.append(AASTORE);
    }
    sortOrderTemp.setStart(il.append(new ASTORE(sortOrderTemp.getIndex())));

    LocalVariableGen sortTypeTemp =
        methodGen.addLocalVariable(
            "sort_type_tmp", Util.getJCRefType("[" + STRING_SIG), null, null);
    il.append(new PUSH(cpg, nsorts));
    il.append(new ANEWARRAY(cpg.addClass(STRING)));
    for (int level = 0; level < nsorts; level++) {
      final Sort sort = (Sort) sortObjects.elementAt(level);
      il.append(DUP);
      il.append(new PUSH(cpg, level));
      sort.translateSortType(classGen, methodGen);
      il.append(AASTORE);
    }
    sortTypeTemp.setStart(il.append(new ASTORE(sortTypeTemp.getIndex())));

    LocalVariableGen sortLangTemp =
        methodGen.addLocalVariable(
            "sort_lang_tmp", Util.getJCRefType("[" + STRING_SIG), null, null);
    il.append(new PUSH(cpg, nsorts));
    il.append(new ANEWARRAY(cpg.addClass(STRING)));
    for (int level = 0; level < nsorts; level++) {
      final Sort sort = (Sort) sortObjects.elementAt(level);
      il.append(DUP);
      il.append(new PUSH(cpg, level));
      sort.translateLang(classGen, methodGen);
      il.append(AASTORE);
    }
    sortLangTemp.setStart(il.append(new ASTORE(sortLangTemp.getIndex())));

    LocalVariableGen sortCaseOrderTemp =
        methodGen.addLocalVariable(
            "sort_case_order_tmp", Util.getJCRefType("[" + STRING_SIG), null, null);
    il.append(new PUSH(cpg, nsorts));
    il.append(new ANEWARRAY(cpg.addClass(STRING)));
    for (int level = 0; level < nsorts; level++) {
      final Sort sort = (Sort) sortObjects.elementAt(level);
      il.append(DUP);
      il.append(new PUSH(cpg, level));
      sort.translateCaseOrder(classGen, methodGen);
      il.append(AASTORE);
    }
    sortCaseOrderTemp.setStart(il.append(new ASTORE(sortCaseOrderTemp.getIndex())));

    il.append(new NEW(cpg.addClass(sortRecordFactoryClass)));
    il.append(DUP);
    il.append(methodGen.loadDOM());
    il.append(new PUSH(cpg, sortRecordClass));
    il.append(classGen.loadTranslet());

    sortOrderTemp.setEnd(il.append(new ALOAD(sortOrderTemp.getIndex())));
    sortTypeTemp.setEnd(il.append(new ALOAD(sortTypeTemp.getIndex())));
    sortLangTemp.setEnd(il.append(new ALOAD(sortLangTemp.getIndex())));
    sortCaseOrderTemp.setEnd(il.append(new ALOAD(sortCaseOrderTemp.getIndex())));

    il.append(
        new INVOKESPECIAL(
            cpg.addMethodref(
                sortRecordFactoryClass,
                "<init>",
                "("
                    + DOM_INTF_SIG
                    + STRING_SIG
                    + TRANSLET_INTF_SIG
                    + "["
                    + STRING_SIG
                    + "["
                    + STRING_SIG
                    + "["
                    + STRING_SIG
                    + "["
                    + STRING_SIG
                    + ")V")));

    // Initialize closure variables in sortRecordFactory
    final ArrayList dups = new ArrayList();

    for (int j = 0; j < nsorts; j++) {
      final Sort sort = (Sort) sortObjects.get(j);
      final int length = (sort._closureVars == null) ? 0 : sort._closureVars.size();

      for (int i = 0; i < length; i++) {
        VariableRefBase varRef = (VariableRefBase) sort._closureVars.get(i);

        // Discard duplicate variable references
        if (dups.contains(varRef)) continue;

        final VariableBase var = varRef.getVariable();

        // Store variable in new closure
        il.append(DUP);
        il.append(var.loadInstruction());
        il.append(
            new PUTFIELD(
                cpg.addFieldref(
                    sortRecordFactoryClass, var.getEscapedName(), var.getType().toSignature())));
        dups.add(varRef);
      }
    }
  }
Пример #9
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());
  }
Пример #10
0
 public Instruction createInstructionAnewarray(Element inst) {
   String classType = inst.getAttributeValue("elementType");
   return new ANEWARRAY(_cp.addClass(classType));
 }
Пример #11
0
 public Instruction createInstructionCheckcast(Element inst) throws IllegalXMLVMException {
   String classType = inst.getAttributeValue("type");
   return new CHECKCAST(_cp.addClass(classType));
 }
  /**
   * 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());
    }
  }