Пример #1
0
 /** Translates an object of this type to its unboxed representation. */
 public void translateUnBox(ClassGenerator classGen, MethodGenerator methodGen) {
   final ConstantPoolGen cpg = classGen.getConstantPool();
   final InstructionList il = methodGen.getInstructionList();
   il.append(new CHECKCAST(cpg.addClass(INTEGER_CLASS)));
   final int index = cpg.addMethodref(INTEGER_CLASS, INT_VALUE, INT_VALUE_SIG);
   il.append(new INVOKEVIRTUAL(index));
 }
  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));
    }
  }
Пример #3
0
  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) /*    */ {
   /* 88 */ ConstantPoolGen cpg = classGen.getConstantPool();
   /* 89 */ InstructionList il = methodGen.getInstructionList();
   /* 90 */ SymbolTable symbolTable = getParser().getSymbolTable();
   /*    */
   /* 93 */ for (int i = 0; i < this._sets.size(); i++)
   /*    */ {
     /* 95 */ QName name = (QName) this._sets.elementAt(i);
     /*    */
     /* 97 */ AttributeSet attrs = symbolTable.lookupAttributeSet(name);
     /*    */
     /* 99 */ if (attrs != null) {
       /* 100 */ String methodName = attrs.getMethodName();
       /* 101 */ il.append(classGen.loadTranslet());
       /* 102 */ il.append(methodGen.loadDOM());
       /* 103 */ il.append(methodGen.loadIterator());
       /* 104 */ il.append(methodGen.loadHandler());
       /* 105 */ il.append(methodGen.loadCurrentNode());
       /* 106 */ int method =
           cpg.addMethodref(
               classGen.getClassName(),
               methodName,
               "(Lcom/sun/org/apache/xalan/internal/xsltc/DOM;Lcom/sun/org/apache/xml/internal/dtm/DTMAxisIterator;Lcom/sun/org/apache/xml/internal/serializer/SerializationHandler;I)V");
       /*    */
       /* 108 */ il.append(new INVOKESPECIAL(method));
       /*    */ }
     /*    */ else
     /*    */ {
       /* 112 */ Parser parser = getParser();
       /* 113 */ String atrs = name.toString();
       /* 114 */ reportError(this, parser, "ATTRIBSET_UNDEF_ERR", atrs);
       /*    */ }
     /*    */ }
   /*    */ }
  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());
  }
Пример #6
0
 /**
  * Expects an integer on the stack and pushes a boxed integer. Boxed integers are represented by
  * an instance of <code>java.lang.Integer</code>.
  *
  * @see com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateTo
  */
 public void translateTo(ClassGenerator classGen, MethodGenerator methodGen, ReferenceType type) {
   final ConstantPoolGen cpg = classGen.getConstantPool();
   final InstructionList il = methodGen.getInstructionList();
   il.append(new NEW(cpg.addClass(INTEGER_CLASS)));
   il.append(DUP_X1);
   il.append(SWAP);
   il.append(new INVOKESPECIAL(cpg.addMethodref(INTEGER_CLASS, "<init>", "(I)V")));
 }
Пример #7
0
  public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
    final ConstantPoolGen cpg = classGen.getConstantPool();
    final InstructionList il = methodGen.getInstructionList();

    // Get two copies of the argument on the stack
    argument().translate(classGen, methodGen);
    il.append(new INVOKESTATIC(cpg.addMethodref(BASIS_LIBRARY_CLASS, "roundF", "(D)D")));
  }
Пример #8
0
  /**
   * Get LocalVariable object.
   *
   * <p>This relies on that the instruction list has already been dumped to byte code or or that the
   * `setPositions' methods has been called for the instruction list.
   *
   * <p>Note that for local variables whose scope end at the last instruction of the method's code,
   * the JVM specification is ambiguous: both a start_pc+length ending at the last instruction and
   * start_pc+length ending at first index beyond the end of the code are valid.
   *
   * @param il instruction list (byte code) which this variable belongs to
   * @param cp constant pool
   */
  public LocalVariable getLocalVariable(ConstantPoolGen cp) {
    int start_pc = start.getPosition();
    int length = end.getPosition() - start_pc;

    if (length > 0) length += end.getInstruction().getLength();

    int name_index = cp.addUtf8(name);
    int signature_index = cp.addUtf8(type.getSignature());

    return new LocalVariable(
        start_pc, length, name_index, signature_index, index, cp.getConstantPool());
  }
Пример #9
0
 /**
  * Get CodeException object.<br>
  * This relies on that the instruction list has already been dumped to byte code or or that the
  * `setPositions' methods has been called for the instruction list.
  *
  * @param cp constant pool
  */
 public CodeException getCodeException(ConstantPoolGen cp) {
   return new CodeException(
       start_pc.getPosition(),
       end_pc.getPosition() + end_pc.getInstruction().getLength(),
       handler_pc.getPosition(),
       (catch_type == null) ? 0 : cp.addClass(catch_type));
 }
Пример #10
0
 public void setClassNameIndex(int class_name_index) {
   this.class_name_index = class_name_index;
   class_name =
       cp.getConstantPool()
           .getConstantString(class_name_index, Constants.CONSTANT_Class)
           .replace('/', '.');
 }
Пример #11
0
 public void setSuperclassNameIndex(int superclass_name_index) {
   this.superclass_name_index = superclass_name_index;
   super_class_name =
       cp.getConstantPool()
           .getConstantString(superclass_name_index, Constants.CONSTANT_Class)
           .replace('/', '.');
 }
Пример #12
0
  public int[] getInterfaces() {
    int size = interface_vec.size();
    int[] interfaces = new int[size];

    for (int i = 0; i < size; i++) interfaces[i] = cp.addClass((String) interface_vec.get(i));

    return interfaces;
  }
Пример #13
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));
  }
Пример #14
0
  /**
   * Convenience method.
   *
   * <p>Add an empty constructor to this class that does nothing but calling super().
   *
   * @param access rights for constructor
   */
  public void addEmptyConstructor(int access_flags) {
    InstructionList il = new InstructionList();
    il.append(InstructionConstants.THIS); // Push `this'
    il.append(new INVOKESPECIAL(cp.addMethodref(super_class_name, "<init>", "()V")));
    il.append(InstructionConstants.RETURN);

    MethodGen mg =
        new MethodGen(access_flags, Type.VOID, Type.NO_ARGS, null, "<init>", class_name, il, cp);
    mg.setMaxStack(1);
    addMethod(mg.getMethod());
  }
Пример #15
0
  /**
   * Convenience constructor to set up some important values initially.
   *
   * @param class_name fully qualified class name
   * @param super_class_name fully qualified superclass name
   * @param file_name source file name
   * @param access_flags access qualifiers
   * @param interfaces implemented interfaces
   * @param cp constant pool to use
   */
  public ClassGen(
      String class_name,
      String super_class_name,
      String file_name,
      int access_flags,
      String[] interfaces,
      ConstantPoolGen cp) {
    this.class_name = class_name;
    this.super_class_name = super_class_name;
    this.file_name = file_name;
    this.access_flags = access_flags;
    this.cp = cp;

    // Put everything needed by default into the constant pool and the vectors
    if (file_name != null)
      addAttribute(
          new SourceFile(cp.addUtf8("SourceFile"), 2, cp.addUtf8(file_name), cp.getConstantPool()));

    class_name_index = cp.addClass(class_name);
    superclass_name_index = cp.addClass(super_class_name);

    if (interfaces != null) for (int i = 0; i < interfaces.length; i++) addInterface(interfaces[i]);
  }
Пример #16
0
 public void setSuperclassName(String name) {
   super_class_name = name.replace('/', '.');
   superclass_name_index = cp.addClass(name);
 }
Пример #17
0
 public void setClassName(String name) {
   class_name = name.replace('/', '.');
   class_name_index = cp.addClass(name);
 }
Пример #18
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));
  }
Пример #19
0
  /**
   * Compile transform() into the output class. This method is used to initialize global variables
   * and global parameters. The current node is set to be the document's root node.
   */
  private void compileTransform(ClassGenerator classGen) {
    final ConstantPoolGen cpg = classGen.getConstantPool();

    /*
     * Define the the method transform with the following signature:
     * void transform(DOM, NodeIterator, HandlerBase)
     */
    final com.sun.org.apache.bcel.internal.generic.Type[] argTypes =
        new com.sun.org.apache.bcel.internal.generic.Type[3];
    argTypes[0] = Util.getJCRefType(DOM_INTF_SIG);
    argTypes[1] = Util.getJCRefType(NODE_ITERATOR_SIG);
    argTypes[2] = Util.getJCRefType(TRANSLET_OUTPUT_SIG);

    final String[] argNames = new String[3];
    argNames[0] = DOCUMENT_PNAME;
    argNames[1] = ITERATOR_PNAME;
    argNames[2] = TRANSLET_OUTPUT_PNAME;

    final InstructionList il = new InstructionList();
    final MethodGenerator transf =
        new MethodGenerator(
            ACC_PUBLIC,
            com.sun.org.apache.bcel.internal.generic.Type.VOID,
            argTypes,
            argNames,
            "transform",
            _className,
            il,
            classGen.getConstantPool());
    transf.addException("com.sun.org.apache.xalan.internal.xsltc.TransletException");

    // Define and initialize current with the root node
    final LocalVariableGen current =
        transf.addLocalVariable(
            "current", com.sun.org.apache.bcel.internal.generic.Type.INT, null, null);
    final String applyTemplatesSig = classGen.getApplyTemplatesSig();
    final int applyTemplates =
        cpg.addMethodref(getClassName(), "applyTemplates", applyTemplatesSig);
    final int domField = cpg.addFieldref(getClassName(), DOM_FIELD, DOM_INTF_SIG);

    // push translet for PUTFIELD
    il.append(classGen.loadTranslet());
    // prepare appropriate DOM implementation

    if (isMultiDocument()) {
      il.append(new NEW(cpg.addClass(MULTI_DOM_CLASS)));
      il.append(DUP);
    }

    il.append(classGen.loadTranslet());
    il.append(transf.loadDOM());
    il.append(
        new INVOKEVIRTUAL(
            cpg.addMethodref(
                TRANSLET_CLASS, "makeDOMAdapter", "(" + DOM_INTF_SIG + ")" + DOM_ADAPTER_SIG)));
    // DOMAdapter is on the stack

    if (isMultiDocument()) {
      final int init = cpg.addMethodref(MULTI_DOM_CLASS, "<init>", "(" + DOM_INTF_SIG + ")V");
      il.append(new INVOKESPECIAL(init));
      // MultiDOM is on the stack
    }

    // store to _dom variable
    il.append(new PUTFIELD(domField));

    // continue with globals initialization
    final int gitr = cpg.addInterfaceMethodref(DOM_INTF, "getIterator", "()" + NODE_ITERATOR_SIG);
    il.append(transf.loadDOM());
    il.append(new INVOKEINTERFACE(gitr, 1));
    il.append(transf.nextNode());
    current.setStart(il.append(new ISTORE(current.getIndex())));

    // Transfer the output settings to the output post-processor
    il.append(classGen.loadTranslet());
    il.append(transf.loadHandler());
    final int index =
        cpg.addMethodref(TRANSLET_CLASS, "transferOutputSettings", "(" + OUTPUT_HANDLER_SIG + ")V");
    il.append(new INVOKEVIRTUAL(index));

    /*
     * Compile buildKeys() method. Note that this method is not
     * invoked here as keys for the input document are now created
     * in topLevel(). However, this method is still needed by the
     * LoadDocument class.
     */
    final String keySig = compileBuildKeys(classGen);
    final int keyIdx = cpg.addMethodref(getClassName(), "buildKeys", keySig);

    // Look for top-level elements that need handling
    final Enumeration toplevel = elements();
    if (_globals.size() > 0 || toplevel.hasMoreElements()) {
      // Compile method for handling top-level elements
      final String topLevelSig = compileTopLevel(classGen);
      // Get a reference to that method
      final int topLevelIdx = cpg.addMethodref(getClassName(), "topLevel", topLevelSig);
      // Push all parameters on the stack and call topLevel()
      il.append(classGen.loadTranslet()); // The 'this' pointer
      il.append(classGen.loadTranslet());
      il.append(new GETFIELD(domField)); // The DOM reference
      il.append(transf.loadIterator());
      il.append(transf.loadHandler()); // The output handler
      il.append(new INVOKEVIRTUAL(topLevelIdx));
    }

    // start document
    il.append(transf.loadHandler());
    il.append(transf.startDocument());

    // push first arg for applyTemplates
    il.append(classGen.loadTranslet());
    // push translet for GETFIELD to get DOM arg
    il.append(classGen.loadTranslet());
    il.append(new GETFIELD(domField));
    // push remaining 2 args
    il.append(transf.loadIterator());
    il.append(transf.loadHandler());
    il.append(new INVOKEVIRTUAL(applyTemplates));
    // endDocument
    il.append(transf.loadHandler());
    il.append(transf.endDocument());

    il.append(RETURN);

    // Compute max locals + stack and add method to class
    classGen.addMethod(transf);
  }
Пример #20
0
  /** Compile the translet's constructor */
  private void compileConstructor(ClassGenerator classGen, Output output) {

    final ConstantPoolGen cpg = classGen.getConstantPool();
    final InstructionList il = new InstructionList();

    final MethodGenerator constructor =
        new MethodGenerator(
            ACC_PUBLIC,
            com.sun.org.apache.bcel.internal.generic.Type.VOID,
            null,
            null,
            "<init>",
            _className,
            il,
            cpg);

    // Call the constructor in the AbstractTranslet superclass
    il.append(classGen.loadTranslet());
    il.append(new INVOKESPECIAL(cpg.addMethodref(TRANSLET_CLASS, "<init>", "()V")));

    constructor.markChunkStart();
    il.append(classGen.loadTranslet());
    il.append(
        new GETSTATIC(cpg.addFieldref(_className, STATIC_NAMES_ARRAY_FIELD, NAMES_INDEX_SIG)));
    il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, NAMES_INDEX, NAMES_INDEX_SIG)));

    il.append(classGen.loadTranslet());
    il.append(new GETSTATIC(cpg.addFieldref(_className, STATIC_URIS_ARRAY_FIELD, URIS_INDEX_SIG)));
    il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, URIS_INDEX, URIS_INDEX_SIG)));
    constructor.markChunkEnd();

    constructor.markChunkStart();
    il.append(classGen.loadTranslet());
    il.append(
        new GETSTATIC(cpg.addFieldref(_className, STATIC_TYPES_ARRAY_FIELD, TYPES_INDEX_SIG)));
    il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, TYPES_INDEX, TYPES_INDEX_SIG)));
    constructor.markChunkEnd();

    constructor.markChunkStart();
    il.append(classGen.loadTranslet());
    il.append(
        new GETSTATIC(
            cpg.addFieldref(_className, STATIC_NAMESPACE_ARRAY_FIELD, NAMESPACE_INDEX_SIG)));
    il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, NAMESPACE_INDEX, NAMESPACE_INDEX_SIG)));
    constructor.markChunkEnd();

    constructor.markChunkStart();
    il.append(classGen.loadTranslet());
    il.append(new PUSH(cpg, AbstractTranslet.CURRENT_TRANSLET_VERSION));
    il.append(
        new PUTFIELD(
            cpg.addFieldref(TRANSLET_CLASS, TRANSLET_VERSION_INDEX, TRANSLET_VERSION_INDEX_SIG)));
    constructor.markChunkEnd();

    if (_hasIdCall) {
      constructor.markChunkStart();
      il.append(classGen.loadTranslet());
      il.append(new PUSH(cpg, Boolean.TRUE));
      il.append(
          new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, HASIDCALL_INDEX, HASIDCALL_INDEX_SIG)));
      constructor.markChunkEnd();
    }

    // Compile in code to set the output configuration from <xsl:output>
    if (output != null) {
      // Set all the output settings files in the translet
      constructor.markChunkStart();
      output.translate(classGen, constructor);
      constructor.markChunkEnd();
    }

    // Compile default decimal formatting symbols.
    // This is an implicit, nameless xsl:decimal-format top-level element.
    if (_numberFormattingUsed) {
      constructor.markChunkStart();
      DecimalFormatting.translateDefaultDFS(classGen, constructor);
      constructor.markChunkEnd();
    }

    il.append(RETURN);

    classGen.addMethod(constructor);
  }
Пример #21
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));
  }
Пример #22
0
 /**
  * Expects an integer on the stack and pushes its string value by calling <code>
  * Integer.toString(int i)</code>.
  *
  * @see com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateTo
  */
 public void translateTo(ClassGenerator classGen, MethodGenerator methodGen, StringType type) {
   final ConstantPoolGen cpg = classGen.getConstantPool();
   final InstructionList il = methodGen.getInstructionList();
   il.append(new INVOKESTATIC(cpg.addMethodref(INTEGER_CLASS, "toString", "(I)" + STRING_SIG)));
 }
Пример #23
0
  /**
   * Compile the namesArray, urisArray and typesArray into the static initializer. They are
   * read-only from the translet. All translet instances can share a single copy of this informtion.
   */
  private void compileStaticInitializer(ClassGenerator classGen) {
    final ConstantPoolGen cpg = classGen.getConstantPool();
    final InstructionList il = new InstructionList();

    final MethodGenerator staticConst =
        new MethodGenerator(
            ACC_PUBLIC | ACC_STATIC,
            com.sun.org.apache.bcel.internal.generic.Type.VOID,
            null,
            null,
            "<clinit>",
            _className,
            il,
            cpg);

    addStaticField(classGen, "[" + STRING_SIG, STATIC_NAMES_ARRAY_FIELD);
    addStaticField(classGen, "[" + STRING_SIG, STATIC_URIS_ARRAY_FIELD);
    addStaticField(classGen, "[I", STATIC_TYPES_ARRAY_FIELD);
    addStaticField(classGen, "[" + STRING_SIG, STATIC_NAMESPACE_ARRAY_FIELD);
    // Create fields of type char[] that will contain literal text from
    // the stylesheet.
    final int charDataFieldCount = getXSLTC().getCharacterDataCount();
    for (int i = 0; i < charDataFieldCount; i++) {
      addStaticField(classGen, STATIC_CHAR_DATA_FIELD_SIG, STATIC_CHAR_DATA_FIELD + i);
    }

    // Put the names array into the translet - used for dom/translet mapping
    final Vector namesIndex = getXSLTC().getNamesIndex();
    int size = namesIndex.size();
    String[] namesArray = new String[size];
    String[] urisArray = new String[size];
    int[] typesArray = new int[size];

    int index;
    for (int i = 0; i < size; i++) {
      String encodedName = (String) namesIndex.elementAt(i);
      if ((index = encodedName.lastIndexOf(':')) > -1) {
        urisArray[i] = encodedName.substring(0, index);
      }

      index = index + 1;
      if (encodedName.charAt(index) == '@') {
        typesArray[i] = DTM.ATTRIBUTE_NODE;
        index++;
      } else if (encodedName.charAt(index) == '?') {
        typesArray[i] = DTM.NAMESPACE_NODE;
        index++;
      } else {
        typesArray[i] = DTM.ELEMENT_NODE;
      }

      if (index == 0) {
        namesArray[i] = encodedName;
      } else {
        namesArray[i] = encodedName.substring(index);
      }
    }

    staticConst.markChunkStart();
    il.append(new PUSH(cpg, size));
    il.append(new ANEWARRAY(cpg.addClass(STRING)));
    int namesArrayRef = cpg.addFieldref(_className, STATIC_NAMES_ARRAY_FIELD, NAMES_INDEX_SIG);
    il.append(new PUTSTATIC(namesArrayRef));
    staticConst.markChunkEnd();

    for (int i = 0; i < size; i++) {
      final String name = namesArray[i];
      staticConst.markChunkStart();
      il.append(new GETSTATIC(namesArrayRef));
      il.append(new PUSH(cpg, i));
      il.append(new PUSH(cpg, name));
      il.append(AASTORE);
      staticConst.markChunkEnd();
    }

    staticConst.markChunkStart();
    il.append(new PUSH(cpg, size));
    il.append(new ANEWARRAY(cpg.addClass(STRING)));
    int urisArrayRef = cpg.addFieldref(_className, STATIC_URIS_ARRAY_FIELD, URIS_INDEX_SIG);
    il.append(new PUTSTATIC(urisArrayRef));
    staticConst.markChunkEnd();

    for (int i = 0; i < size; i++) {
      final String uri = urisArray[i];
      staticConst.markChunkStart();
      il.append(new GETSTATIC(urisArrayRef));
      il.append(new PUSH(cpg, i));
      il.append(new PUSH(cpg, uri));
      il.append(AASTORE);
      staticConst.markChunkEnd();
    }

    staticConst.markChunkStart();
    il.append(new PUSH(cpg, size));
    il.append(new NEWARRAY(BasicType.INT));
    int typesArrayRef = cpg.addFieldref(_className, STATIC_TYPES_ARRAY_FIELD, TYPES_INDEX_SIG);
    il.append(new PUTSTATIC(typesArrayRef));
    staticConst.markChunkEnd();

    for (int i = 0; i < size; i++) {
      final int nodeType = typesArray[i];
      staticConst.markChunkStart();
      il.append(new GETSTATIC(typesArrayRef));
      il.append(new PUSH(cpg, i));
      il.append(new PUSH(cpg, nodeType));
      il.append(IASTORE);
    }

    // Put the namespace names array into the translet
    final Vector namespaces = getXSLTC().getNamespaceIndex();
    staticConst.markChunkStart();
    il.append(new PUSH(cpg, namespaces.size()));
    il.append(new ANEWARRAY(cpg.addClass(STRING)));
    int namespaceArrayRef =
        cpg.addFieldref(_className, STATIC_NAMESPACE_ARRAY_FIELD, NAMESPACE_INDEX_SIG);
    il.append(new PUTSTATIC(namespaceArrayRef));
    staticConst.markChunkEnd();

    for (int i = 0; i < namespaces.size(); i++) {
      final String ns = (String) namespaces.elementAt(i);
      staticConst.markChunkStart();
      il.append(new GETSTATIC(namespaceArrayRef));
      il.append(new PUSH(cpg, i));
      il.append(new PUSH(cpg, ns));
      il.append(AASTORE);
      staticConst.markChunkEnd();
    }

    // Grab all the literal text in the stylesheet and put it in a char[]
    final int charDataCount = getXSLTC().getCharacterDataCount();
    final int toCharArray = cpg.addMethodref(STRING, "toCharArray", "()[C");
    for (int i = 0; i < charDataCount; i++) {
      staticConst.markChunkStart();
      il.append(new PUSH(cpg, getXSLTC().getCharacterData(i)));
      il.append(new INVOKEVIRTUAL(toCharArray));
      il.append(
          new PUTSTATIC(
              cpg.addFieldref(_className, STATIC_CHAR_DATA_FIELD + i, STATIC_CHAR_DATA_FIELD_SIG)));
      staticConst.markChunkEnd();
    }

    il.append(RETURN);

    classGen.addMethod(staticConst);
  }
  @Override
  public void run() {
    ClassGen nodeCG = hookHandler.getClassByNick("Node");
    ClassGen npcCG = hookHandler.getClassByNick("NPC");
    for (ClassGen cG : classes) {
      ConstantPoolGen cpg = cG.getConstantPool();
      if (!cG.getSuperclassName().equals(nodeCG.getClassName())) {
        continue;
      }

      int nonStaticFieldCount = 0;
      int npcFieldCount = 0;
      for (Field field : cG.getFields()) {
        if (field.isStatic()) {
          continue;
        }
        nonStaticFieldCount++;
        if (field.getType().toString().equals(npcCG.getClassName())) {
          npcFieldCount++;
        }
      }
      if (nonStaticFieldCount != 1 || npcFieldCount != 1) {
        continue;
      }

      hookHandler.addClassNick("NPCNode", cG);
      for (Field field : cG.getFields()) {
        if (field.isStatic()) {
          continue;
        }
        if (field.getType().toString().equals(npcCG.getClassName())) {
          hookHandler.addFieldHook("NPCNode", cG, field, "NPC", TypeBuilder.createHookType("NPC"));
        }
      }
    }
    ClassGen npcNodeCG = hookHandler.getClassByNick("NPCNode");
    for (ClassGen cG : classes) {
      for (Field field : cG.getFields()) {
        if (!field.isStatic()) {
          continue;
        }
        if (field.getType().getSignature().equals("[L" + npcNodeCG.getClassName() + ";")) {
          hookHandler.addClientHook(
              cG, field, "NPCNodes", TypeBuilder.createHookArrayType("NPCNode", 1));
        }
      }
    }
    ClassGen nodeCacheCG = hookHandler.getClassByNick("NodeCache");
    FieldHook fieldHook = hookHandler.getFieldHook("NPCNode", "NPC");
    for (ClassGen cG : classes) {
      ConstantPoolGen cpg = cG.getConstantPool();
      if (cpg.lookupClass(nodeCacheCG.getClassName()) == -1) {
        continue;
      }
      if (cpg.lookupFieldref(
              fieldHook.getClassName(),
              fieldHook.getFieldName(),
              fieldHook.getFieldType().getSignature())
          == -1) {
        continue;
      }
      for (Method method : cG.getMethods()) {
        if (!method.isStatic()) {
          continue;
        }
        if (!method.getReturnType().equals(Type.VOID)) {
          continue;
        }
        Type[] args = method.getArgumentTypes();
        if (args.length < 13 || args.length > 14) {
          continue;
        }
        if (TypeCounter.getObjectCount(args) != 0) {
          continue;
        }
        InstructionList iList = new InstructionList(method.getCode().getCode());
        InstructionFinder instructionFinder = new InstructionFinder(iList);
        for (Iterator<InstructionHandle[]> iterator = instructionFinder.search("getstatic");
            iterator.hasNext(); ) {
          InstructionHandle[] ih = iterator.next();
          FieldInstruction fieldInstruction = (FieldInstruction) ih[0].getInstruction();
          if (fieldInstruction.getFieldType(cpg).toString().equals(nodeCacheCG.getClassName())) {
            hookHandler.addClientHook(
                fieldInstruction, cpg, "NPCNodeCache", TypeBuilder.createHookType("NodeCache"));
          }
        }
      }
    }
  }
Пример #25
0
  /**
   * Compile a topLevel() method into the output class. This method is called from transform() to
   * handle all non-template top-level elements. Returns the signature of the topLevel() method.
   *
   * <p>Global variables/params and keys are first sorted to resolve dependencies between them. The
   * XSLT 1.0 spec does not allow a key to depend on a variable. However, for compatibility with
   * Xalan interpretive, that type of dependency is allowed. Note also that the buildKeys() method
   * is still generated as it is used by the LoadDocument class, but it no longer called from
   * transform().
   */
  private String compileTopLevel(ClassGenerator classGen) {

    final ConstantPoolGen cpg = classGen.getConstantPool();

    final com.sun.org.apache.bcel.internal.generic.Type[] argTypes = {
      Util.getJCRefType(DOM_INTF_SIG),
      Util.getJCRefType(NODE_ITERATOR_SIG),
      Util.getJCRefType(TRANSLET_OUTPUT_SIG)
    };

    final String[] argNames = {DOCUMENT_PNAME, ITERATOR_PNAME, TRANSLET_OUTPUT_PNAME};

    final InstructionList il = new InstructionList();

    final MethodGenerator toplevel =
        new MethodGenerator(
            ACC_PUBLIC,
            com.sun.org.apache.bcel.internal.generic.Type.VOID,
            argTypes,
            argNames,
            "topLevel",
            _className,
            il,
            classGen.getConstantPool());

    toplevel.addException("com.sun.org.apache.xalan.internal.xsltc.TransletException");

    // Define and initialize 'current' variable with the root node
    final LocalVariableGen current =
        toplevel.addLocalVariable(
            "current", com.sun.org.apache.bcel.internal.generic.Type.INT, null, null);

    final int setFilter =
        cpg.addInterfaceMethodref(
            DOM_INTF, "setFilter", "(Lcom/sun/org/apache/xalan/internal/xsltc/StripFilter;)V");

    final int gitr = cpg.addInterfaceMethodref(DOM_INTF, "getIterator", "()" + NODE_ITERATOR_SIG);
    il.append(toplevel.loadDOM());
    il.append(new INVOKEINTERFACE(gitr, 1));
    il.append(toplevel.nextNode());
    current.setStart(il.append(new ISTORE(current.getIndex())));

    // Create a new list containing variables/params + keys
    Vector varDepElements = new Vector(_globals);
    Enumeration elements = elements();
    while (elements.hasMoreElements()) {
      final Object element = elements.nextElement();
      if (element instanceof Key) {
        varDepElements.add(element);
      }
    }

    // Determine a partial order for the variables/params and keys
    varDepElements = resolveDependencies(varDepElements);

    // Translate vars/params and keys in the right order
    final int count = varDepElements.size();
    for (int i = 0; i < count; i++) {
      final TopLevelElement tle = (TopLevelElement) varDepElements.elementAt(i);
      tle.translate(classGen, toplevel);
      if (tle instanceof Key) {
        final Key key = (Key) tle;
        _keys.put(key.getName(), key);
      }
    }

    // Compile code for other top-level elements
    Vector whitespaceRules = new Vector();
    elements = elements();
    while (elements.hasMoreElements()) {
      final Object element = elements.nextElement();
      // xsl:decimal-format
      if (element instanceof DecimalFormatting) {
        ((DecimalFormatting) element).translate(classGen, toplevel);
      }
      // xsl:strip/preserve-space
      else if (element instanceof Whitespace) {
        whitespaceRules.addAll(((Whitespace) element).getRules());
      }
    }

    // Translate all whitespace strip/preserve rules
    if (whitespaceRules.size() > 0) {
      Whitespace.translateRules(whitespaceRules, classGen);
    }

    if (classGen.containsMethod(STRIP_SPACE, STRIP_SPACE_PARAMS) != null) {
      il.append(toplevel.loadDOM());
      il.append(classGen.loadTranslet());
      il.append(new INVOKEINTERFACE(setFilter, 2));
    }

    il.append(RETURN);

    // Compute max locals + stack and add method to class
    classGen.addMethod(toplevel);

    return ("(" + DOM_INTF_SIG + NODE_ITERATOR_SIG + TRANSLET_OUTPUT_SIG + ")V");
  }
Пример #26
0
  /** Import constant from another ConstantPool and return new index. */
  public int addConstant(Constant c, ConstantPoolGen cp) {
    Constant[] constants = cp.getConstantPool().getConstantPool();

    switch (c.getTag()) {
      case Constants.CONSTANT_String:
        {
          ConstantString s = (ConstantString) c;
          ConstantUtf8 u8 = (ConstantUtf8) constants[s.getStringIndex()];

          return addString(u8.getBytes());
        }

      case Constants.CONSTANT_Class:
        {
          ConstantClass s = (ConstantClass) c;
          ConstantUtf8 u8 = (ConstantUtf8) constants[s.getNameIndex()];

          return addClass(u8.getBytes());
        }

      case Constants.CONSTANT_NameAndType:
        {
          ConstantNameAndType n = (ConstantNameAndType) c;
          ConstantUtf8 u8 = (ConstantUtf8) constants[n.getNameIndex()];
          ConstantUtf8 u8_2 = (ConstantUtf8) constants[n.getSignatureIndex()];

          return addNameAndType(u8.getBytes(), u8_2.getBytes());
        }

      case Constants.CONSTANT_Utf8:
        return addUtf8(((ConstantUtf8) c).getBytes());

      case Constants.CONSTANT_Double:
        return addDouble(((ConstantDouble) c).getBytes());

      case Constants.CONSTANT_Float:
        return addFloat(((ConstantFloat) c).getBytes());

      case Constants.CONSTANT_Long:
        return addLong(((ConstantLong) c).getBytes());

      case Constants.CONSTANT_Integer:
        return addInteger(((ConstantInteger) c).getBytes());

      case Constants.CONSTANT_InterfaceMethodref:
      case Constants.CONSTANT_Methodref:
      case Constants.CONSTANT_Fieldref:
        {
          ConstantCP m = (ConstantCP) c;
          ConstantClass clazz = (ConstantClass) constants[m.getClassIndex()];
          ConstantNameAndType n = (ConstantNameAndType) constants[m.getNameAndTypeIndex()];
          ConstantUtf8 u8 = (ConstantUtf8) constants[clazz.getNameIndex()];
          String class_name = u8.getBytes().replace('/', '.');

          u8 = (ConstantUtf8) constants[n.getNameIndex()];
          String name = u8.getBytes();

          u8 = (ConstantUtf8) constants[n.getSignatureIndex()];
          String signature = u8.getBytes();

          switch (c.getTag()) {
            case Constants.CONSTANT_InterfaceMethodref:
              return addInterfaceMethodref(class_name, name, signature);

            case Constants.CONSTANT_Methodref:
              return addMethodref(class_name, name, signature);

            case Constants.CONSTANT_Fieldref:
              return addFieldref(class_name, name, signature);

            default: // Never reached
              throw new RuntimeException("Unknown constant type " + c);
          }
        }

      default: // Never reached
        throw new RuntimeException("Unknown constant type " + c);
    }
  }