Package org.apache.xalan.xsltc.compiler.util

Examples of org.apache.xalan.xsltc.compiler.util.MethodGenerator


  argNames[0] = DOCUMENT_PNAME;
  argNames[1] = ITERATOR_PNAME;
  argNames[2] = TRANSLET_OUTPUT_PNAME;

  final InstructionList mainIL = new InstructionList();
  final MethodGenerator methodGen =
      new MethodGenerator(ACC_PUBLIC | ACC_FINAL,
        org.apache.bcel.generic.Type.VOID,
        argTypes, argNames, functionName(),
        getClassName(), mainIL,
        classGen.getConstantPool());
  methodGen.addException("org.apache.xalan.xsltc.TransletException");

  // Create a local variable to hold the current node
  final LocalVariableGen current;
  current = methodGen.addLocalVariable2("current",
                org.apache.bcel.generic.Type.INT,
                mainIL.getEnd());
  _currentIndex = current.getIndex();

  // Create the "body" instruction list that will eventually hold the
  // code for the entire method (other ILs will be appended).
  final InstructionList body = new InstructionList();
  body.append(NOP);

  // Create an instruction list that contains the default next-node
  // iteration
  final InstructionList ilLoop = new InstructionList();
  ilLoop.append(methodGen.loadIterator());
  ilLoop.append(methodGen.nextNode());
  ilLoop.append(DUP);
  ilLoop.append(new ISTORE(_currentIndex));

  // The body of this code can get very large - large than can be handled
  // by a single IFNE(body.getStart()) instruction - need workaround:
        final BranchHandle ifeq = ilLoop.append(new IFEQ(null));
  final BranchHandle loop = ilLoop.append(new GOTO_W(null));
  ifeq.setTarget(ilLoop.append(RETURN));   // applyTemplates() ends here!
  final InstructionHandle ihLoop = ilLoop.getStart();

  // Compile default handling of elements (traverse children)
  InstructionList ilRecurse =
      compileDefaultRecursion(classGen, methodGen, ihLoop);
  InstructionHandle ihRecurse = ilRecurse.getStart();

  // Compile default handling of text/attribute nodes (output text)
  InstructionList ilText =
      compileDefaultText(classGen, methodGen, ihLoop);
  InstructionHandle ihText = ilText.getStart();

  // Distinguish attribute/element/namespace tests for further processing
  final int[] types = new int[DOM.NTYPES + names.size()];
  for (int i = 0; i < types.length; i++) {
      types[i] = i;
  }

  // Initialize isAttribute[] and isNamespace[] arrays
  final boolean[] isAttribute = new boolean[types.length];
  final boolean[] isNamespace = new boolean[types.length];
  for (int i = 0; i < names.size(); i++) {
      final String name = (String)names.elementAt(i);
      isAttribute[i + DOM.NTYPES] = isAttributeName(name);
      isNamespace[i + DOM.NTYPES] = isNamespaceName(name);
  }

  // Compile all templates - regardless of pattern type
  compileTemplates(classGen, methodGen, ihLoop);

  // Handle template with explicit "*" pattern
  final TestSeq elemTest = _testSeq[DOM.ELEMENT];
  InstructionHandle ihElem = ihRecurse;
  if (elemTest != null)
      ihElem = elemTest.compile(classGen, methodGen, ihRecurse);

  // Handle template with explicit "@*" pattern
  final TestSeq attrTest = _testSeq[DOM.ATTRIBUTE];
  InstructionHandle ihAttr = ihText;
  if (attrTest != null)
      ihAttr = attrTest.compile(classGen, methodGen, ihAttr);

  // Do tests for id() and key() patterns first
  InstructionList ilKey = null;
  if (_idxTestSeq != null) {
      loop.setTarget(_idxTestSeq.compile(classGen, methodGen, body.getStart()));
      ilKey = _idxTestSeq.getInstructionList();
  }
  else {
      loop.setTarget(body.getStart());
  }

  // If there is a match on node() we need to replace ihElem
  // and ihText if the priority of node() is higher
  if (_childNodeTestSeq != null) {
      // Compare priorities of node() and "*"
      double nodePrio = _childNodeTestSeq.getPriority();
      int    nodePos  = _childNodeTestSeq.getPosition();
      double elemPrio = (0 - Double.MAX_VALUE);
      int    elemPos  = Integer.MIN_VALUE;

      if (elemTest != null) {
    elemPrio = elemTest.getPriority();
    elemPos  = elemTest.getPosition();
      }
      if (elemPrio == Double.NaN || elemPrio < nodePrio ||
    (elemPrio == nodePrio && elemPos < nodePos))
      {
    ihElem = _childNodeTestSeq.compile(classGen, methodGen, ihLoop);
      }

      // Compare priorities of node() and text()
      final TestSeq textTest = _testSeq[DOM.TEXT];
      double textPrio = (0 - Double.MAX_VALUE);
      int    textPos  = Integer.MIN_VALUE;

      if (textTest != null) {
    textPrio = textTest.getPriority();
    textPos  = textTest.getPosition();
      }
      if (textPrio == Double.NaN || textPrio < nodePrio ||
          (textPrio == nodePrio && textPos < nodePos))
      {
    ihText = _childNodeTestSeq.compile(classGen, methodGen, ihLoop);
    _testSeq[DOM.TEXT] = _childNodeTestSeq;
      }
  }

  // Handle templates with "ns:*" pattern
  InstructionHandle elemNamespaceHandle = ihElem;
  InstructionList nsElem = compileNamespaces(classGen, methodGen,
               isNamespace, isAttribute,
               false, ihElem);
  if (nsElem != null) elemNamespaceHandle = nsElem.getStart();

  // Handle templates with "ns:@*" pattern
  InstructionHandle attrNamespaceHandle = ihAttr;
  InstructionList nsAttr = compileNamespaces(classGen, methodGen,
               isNamespace, isAttribute,
               true, ihAttr);
  if (nsAttr != null) attrNamespaceHandle = nsAttr.getStart();

  // Handle templates with "ns:elem" or "ns:@attr" pattern
  final InstructionHandle[] targets = new InstructionHandle[types.length];
  for (int i = DOM.NTYPES; i < targets.length; i++) {
      final TestSeq testSeq = _testSeq[i];
      // Jump straight to namespace tests ?
      if (isNamespace[i]) {
    if (isAttribute[i])
        targets[i] = attrNamespaceHandle;
    else
        targets[i] = elemNamespaceHandle;
      }
      // Test first, then jump to namespace tests
      else if (testSeq != null) {
    if (isAttribute[i])
        targets[i] = testSeq.compile(classGen, methodGen,
             attrNamespaceHandle);
    else
        targets[i] = testSeq.compile(classGen, methodGen,
             elemNamespaceHandle);
      }
      else {
    targets[i] = ihLoop;
      }
  }


  // Handle pattern with match on root node - default: traverse children
  targets[DOM.ROOT] = _rootPattern != null
      ? getTemplateInstructionHandle(_rootPattern.getTemplate())
      : ihRecurse;
 
  // Handle any pattern with match on text nodes - default: output text
  targets[DOM.TEXT] = _testSeq[DOM.TEXT] != null
      ? _testSeq[DOM.TEXT].compile(classGen, methodGen, ihText)
      : ihText;

  // This DOM-type is not in use - default: process next node
  targets[DOM.NAMESPACE] = ihLoop;

  // Match unknown element in DOM - default: check for namespace match
  targets[DOM.ELEMENT] = elemNamespaceHandle;

  // Match unknown attribute in DOM - default: check for namespace match
  targets[DOM.ATTRIBUTE] = attrNamespaceHandle;

  // Match on processing instruction - default: process next node
  InstructionHandle ihPI = ihLoop;
  if (_childNodeTestSeq != null) ihPI = ihElem;
  if (_testSeq[DOM.PROCESSING_INSTRUCTION] != null)
      targets[DOM.PROCESSING_INSTRUCTION] =
    _testSeq[DOM.PROCESSING_INSTRUCTION].
    compile(classGen, methodGen, ihPI);
  else
      targets[DOM.PROCESSING_INSTRUCTION] = ihPI;
 
  // Match on comments - default: process next node
  InstructionHandle ihComment = ihLoop;
  if (_childNodeTestSeq != null) ihComment = ihElem;
  targets[DOM.COMMENT] = _testSeq[DOM.COMMENT] != null
      ? _testSeq[DOM.COMMENT].compile(classGen, methodGen, ihComment)
      : ihComment;

  // Now compile test sequences for various match patterns:
  for (int i = DOM.NTYPES; i < targets.length; i++) {
      final TestSeq testSeq = _testSeq[i];
      // Jump straight to namespace tests ?
      if ((testSeq == null) || (isNamespace[i])) {
    if (isAttribute[i])
        targets[i] = attrNamespaceHandle;
    else
        targets[i] = elemNamespaceHandle;
      }
      // Match on node type
      else {
    if (isAttribute[i])
        targets[i] = testSeq.compile(classGen, methodGen,
             attrNamespaceHandle);
    else
        targets[i] = testSeq.compile(classGen, methodGen,
             elemNamespaceHandle);
      }
  }

  if (ilKey != null) body.insert(ilKey);

  // Append first code in applyTemplates() - get type of current node
  final int getType = cpg.addInterfaceMethodref(DOM_INTF,
                  "getType", "(I)I");
  body.append(methodGen.loadDOM());
  body.append(new ILOAD(_currentIndex));
  body.append(new INVOKEINTERFACE(getType, 2));

  // Append switch() statement - main dispatch loop in applyTemplates()
  InstructionHandle disp = body.append(new SWITCH(types, targets, ihLoop));

  // Append all the "case:" statements
  appendTestSequences(body);
  // Append the actual template code
  appendTemplateCode(body);

  // Append NS:* node tests (if any)
  if (nsElem != null) body.append(nsElem);
  // Append NS:@* node tests (if any)
  if (nsAttr != null) body.append(nsAttr);

  // Append default action for element and root nodes
  body.append(ilRecurse);
  // Append default action for text and attribute nodes
  body.append(ilText);

  // putting together constituent instruction lists
  mainIL.append(new GOTO_W(ihLoop));
  mainIL.append(body);
  // fall through to ilLoop
  mainIL.append(ilLoop);

  peepHoleOptimization(methodGen);
  methodGen.stripAttributes(true);
 
  methodGen.setMaxLocals();
  methodGen.setMaxStack();
  methodGen.removeNOPs();
  classGen.addMethod(methodGen.getMethod());

  // Compile method(s) for <xsl:apply-imports/> for this mode
  if (_importLevels != null) {
      Enumeration levels = _importLevels.keys();
      while (levels.hasMoreElements()) {
View Full Code Here


  argNames[0] = DOCUMENT_PNAME;
  argNames[1] = ITERATOR_PNAME;
  argNames[2] = TRANSLET_OUTPUT_PNAME;

  final InstructionList mainIL = new InstructionList();
  final MethodGenerator methodGen =
      new MethodGenerator(ACC_PUBLIC | ACC_FINAL,
        org.apache.bcel.generic.Type.VOID,
        argTypes, argNames, functionName()+'_'+max,
        getClassName(), mainIL,
        classGen.getConstantPool());
  methodGen.addException("org.apache.xalan.xsltc.TransletException");

  // Create the local variable to hold the current node
  final LocalVariableGen current;
  current = methodGen.addLocalVariable2("current",
                org.apache.bcel.generic.Type.INT,
                mainIL.getEnd());
  _currentIndex = current.getIndex();

  // Create the "body" instruction list that will eventually hold the
  // code for the entire method (other ILs will be appended).
  final InstructionList body = new InstructionList();
  body.append(NOP);

  // Create an instruction list that contains the default next-node
  // iteration
  final InstructionList ilLoop = new InstructionList();
  ilLoop.append(methodGen.loadIterator());
  ilLoop.append(methodGen.nextNode());
  ilLoop.append(DUP);
  ilLoop.append(new ISTORE(_currentIndex));

  // The body of this code can get very large - large than can be handled
  // by a single IFNE(body.getStart()) instruction - need workaround:
        final BranchHandle ifeq = ilLoop.append(new IFEQ(null));
  final BranchHandle loop = ilLoop.append(new GOTO_W(null));
  ifeq.setTarget(ilLoop.append(RETURN)); // applyTemplates() ends here!
  final InstructionHandle ihLoop = ilLoop.getStart();

  // Compile default handling of elements (traverse children)
  InstructionList ilRecurse =
      compileDefaultRecursion(classGen, methodGen, ihLoop);
  InstructionHandle ihRecurse = ilRecurse.getStart();

  // Compile default handling of text/attribute nodes (output text)
  InstructionList ilText =
      compileDefaultText(classGen, methodGen, ihLoop);
  InstructionHandle ihText = ilText.getStart();

  // Distinguish attribute/element/namespace tests for further processing
  final int[] types = new int[DOM.NTYPES + names.size()];
  for (int i = 0; i < types.length; i++) {
      types[i] = i;
  }

  final boolean[] isAttribute = new boolean[types.length];
  final boolean[] isNamespace = new boolean[types.length];
  for (int i = 0; i < names.size(); i++) {
      final String name = (String)names.elementAt(i);
      isAttribute[i+DOM.NTYPES] = isAttributeName(name);
      isNamespace[i+DOM.NTYPES] = isNamespaceName(name);
  }

  // Compile all templates - regardless of pattern type
  compileTemplateCalls(classGen, methodGen, ihLoop, min, max);

  // Handle template with explicit "*" pattern
  final TestSeq elemTest = _testSeq[DOM.ELEMENT];
  InstructionHandle ihElem = ihRecurse;
  if (elemTest != null) {
      ihElem = elemTest.compile(classGen, methodGen, ihLoop);
  }

  // Handle template with explicit "@*" pattern
  final TestSeq attrTest = _testSeq[DOM.ATTRIBUTE];
  InstructionHandle ihAttr = ihLoop;
  if (attrTest != null) {
      ihAttr = attrTest.compile(classGen, methodGen, ihAttr);
  }

  // Do tests for id() and key() patterns first
  InstructionList ilKey = null;
  if (_idxTestSeq != null) {
      loop.setTarget(_idxTestSeq.compile(classGen, methodGen, body.getStart()));
      ilKey = _idxTestSeq.getInstructionList();
  }
  else {
      loop.setTarget(body.getStart());
  }

  // If there is a match on node() we need to replace ihElem
  // and ihText if the priority of node() is higher
  if (_childNodeTestSeq != null) {
      // Compare priorities of node() and "*"
      double nodePrio = _childNodeTestSeq.getPriority();
      int    nodePos  = _childNodeTestSeq.getPosition();
      double elemPrio = (0 - Double.MAX_VALUE);
      int    elemPos  = Integer.MIN_VALUE;

      if (elemTest != null) {
    elemPrio = elemTest.getPriority();
    elemPos  = elemTest.getPosition();
      }

      if (elemPrio == Double.NaN || elemPrio < nodePrio ||
    (elemPrio == nodePrio && elemPos < nodePos))
      {
    ihElem = _childNodeTestSeq.compile(classGen, methodGen, ihLoop);
      }

      // Compare priorities of node() and text()
      final TestSeq textTest = _testSeq[DOM.TEXT];
      double textPrio = (0 - Double.MAX_VALUE);
      int    textPos  = Integer.MIN_VALUE;

      if (textTest != null) {
    textPrio = textTest.getPriority();
    textPos  = textTest.getPosition();
      }

      if (textPrio == Double.NaN || textPrio < nodePrio ||
          (textPrio == nodePrio && textPos < nodePos))
      {
    ihText = _childNodeTestSeq.compile(classGen, methodGen, ihLoop);
    _testSeq[DOM.TEXT] = _childNodeTestSeq;
      }
  }

  // Handle templates with "ns:*" pattern
  InstructionHandle elemNamespaceHandle = ihElem;
  InstructionList nsElem = compileNamespaces(classGen, methodGen,
               isNamespace, isAttribute,
               false, ihElem);
  if (nsElem != null) elemNamespaceHandle = nsElem.getStart();

  // Handle templates with "ns:@*" pattern
  InstructionList nsAttr = compileNamespaces(classGen, methodGen,
               isNamespace, isAttribute,
               true, ihAttr);
  InstructionHandle attrNamespaceHandle = ihAttr;
  if (nsAttr != null) attrNamespaceHandle = nsAttr.getStart();

  // Handle templates with "ns:elem" or "ns:@attr" pattern
  final InstructionHandle[] targets = new InstructionHandle[types.length];
  for (int i = DOM.NTYPES; i < targets.length; i++) {
      final TestSeq testSeq = _testSeq[i];
      // Jump straight to namespace tests ?
      if (isNamespace[i]) {
    if (isAttribute[i])
        targets[i] = attrNamespaceHandle;
    else
        targets[i] = elemNamespaceHandle;
      }
      // Test first, then jump to namespace tests
      else if (testSeq != null) {
    if (isAttribute[i])
        targets[i] = testSeq.compile(classGen, methodGen,
             attrNamespaceHandle);
    else
        targets[i] = testSeq.compile(classGen, methodGen,
             elemNamespaceHandle);
      }
      else {
    targets[i] = ihLoop;
      }
  }

  // Handle pattern with match on root node - default: traverse children
  targets[DOM.ROOT] = _rootPattern != null
      ? getTemplateInstructionHandle(_rootPattern.getTemplate())
      : ihRecurse;
 
  // Handle any pattern with match on text nodes - default: loop
  targets[DOM.TEXT] = _testSeq[DOM.TEXT] != null
      ? _testSeq[DOM.TEXT].compile(classGen, methodGen, ihText)
      : ihText;

  // This DOM-type is not in use - default: process next node
  targets[DOM.NAMESPACE] = ihLoop;

  // Match unknown element in DOM - default: check for namespace match
  targets[DOM.ELEMENT] = elemNamespaceHandle;

  // Match unknown attribute in DOM - default: check for namespace match
  targets[DOM.ATTRIBUTE] = attrNamespaceHandle;

  // Match on processing instruction - default: loop
  InstructionHandle ihPI = ihLoop;
  if (_childNodeTestSeq != null) ihPI = ihElem;
  if (_testSeq[DOM.PROCESSING_INSTRUCTION] != null) {
      targets[DOM.PROCESSING_INSTRUCTION] =
    _testSeq[DOM.PROCESSING_INSTRUCTION].
    compile(classGen, methodGen, ihPI);
  }
  else {
      targets[DOM.PROCESSING_INSTRUCTION] = ihPI;
  }
 
  // Match on comments - default: process next node
  InstructionHandle ihComment = ihLoop;
  if (_childNodeTestSeq != null) ihComment = ihElem;
  targets[DOM.COMMENT] = _testSeq[DOM.COMMENT] != null
      ? _testSeq[DOM.COMMENT].compile(classGen, methodGen, ihComment)
      : ihComment;

  // Now compile test sequences for various match patterns:
  for (int i = DOM.NTYPES; i < targets.length; i++) {
      final TestSeq testSeq = _testSeq[i];
      // Jump straight to namespace tests ?
      if ((testSeq == null) || (isNamespace[i])) {
    if (isAttribute[i])
        targets[i] = attrNamespaceHandle;
    else
        targets[i] = elemNamespaceHandle;
      }
      // Match on node type
      else {
    if (isAttribute[i])
        targets[i] = testSeq.compile(classGen, methodGen,
             attrNamespaceHandle);
    else
        targets[i] = testSeq.compile(classGen, methodGen,
             elemNamespaceHandle);
      }
  }

  if (ilKey != null) body.insert(ilKey);

  // Append first code in applyTemplates() - get type of current node
  final int getType = cpg.addInterfaceMethodref(DOM_INTF,
                  "getType", "(I)I");
  body.append(methodGen.loadDOM());
  body.append(new ILOAD(_currentIndex));
  body.append(new INVOKEINTERFACE(getType, 2));

  // Append switch() statement - main dispatch loop in applyTemplates()
  InstructionHandle disp = body.append(new SWITCH(types,targets,ihLoop));

  // Append all the "case:" statements
  appendTestSequences(body);
  // Append the actual template code
  appendTemplateCode(body);

  // Append NS:* node tests (if any)
  if (nsElem != null) body.append(nsElem);
  // Append NS:@* node tests (if any)
  if (nsAttr != null) body.append(nsAttr);

  // Append default action for element and root nodes
  body.append(ilRecurse);
  // Append default action for text and attribute nodes
  body.append(ilText);

  // putting together constituent instruction lists
  mainIL.append(new GOTO_W(ihLoop));
  mainIL.append(body);
  // fall through to ilLoop
  mainIL.append(ilLoop);

  peepHoleOptimization(methodGen);
  methodGen.stripAttributes(true);
 
  methodGen.setMaxLocals();
  methodGen.setMaxStack();
  methodGen.removeNOPs();
  classGen.addMethod(methodGen.getMethod());

  // Restore original (complete) set of templates for this transformation
  _templates = oldTemplates;
    }
View Full Code Here

  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;
    }
View Full Code Here

            null, cpg.getConstantPool()));
    dups.add(varRef);
      }
  }

  MethodGenerator init = compileInit(sortObjects, sortRecord,
             cpg, className);
  MethodGenerator extract = compileExtract(sortObjects, sortRecord,
                   cpg, className);
  sortRecord.addMethod(init);
  sortRecord.addMethod(extract);

  xsltc.dumpClass(sortRecord.getJavaClass());
View Full Code Here

             NodeSortRecordGenerator sortRecord,
             ConstantPoolGen cpg,
             String className)
    {
  final InstructionList il = new InstructionList();
  final MethodGenerator init =
      new MethodGenerator(ACC_PUBLIC,
        org.apache.bcel.generic.Type.VOID,
        null, null, "<init>", className,
        il, cpg);

  // Call the constructor in the NodeSortRecord superclass
View Full Code Here

      DOCUMENT_PNAME, ITERATOR_PNAME, TRANSLET_OUTPUT_PNAME
  };

  final InstructionList il = new InstructionList();

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

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

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

  final int setFilter = cpg.addInterfaceMethodref(DOM_INTF,
             "setFilter",
             "(Lorg/apache/xalan/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);
View Full Code Here

      DOCUMENT_PNAME, ITERATOR_PNAME, TRANSLET_OUTPUT_PNAME, "current"
  };

  final InstructionList il = new InstructionList();

  final MethodGenerator buildKeys =
      new MethodGenerator(ACC_PUBLIC,
        org.apache.bcel.generic.Type.VOID,
        argTypes, argNames,
        "buildKeys", _className, il,
        classGen.getConstantPool());

  buildKeys.addException("org.apache.xalan.xsltc.TransletException");
 
  final Enumeration elements = elements();
  while (elements.hasMoreElements()) {
      // xsl:key
      final Object element = elements.nextElement();
View Full Code Here

  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,
        org.apache.bcel.generic.Type.VOID,
        argTypes, argNames,
        "transform",
        _className,
        il,
        classGen.getConstantPool());
  transf.addException("org.apache.xalan.xsltc.TransletException");

  // Define and initialize current with the root node
  final LocalVariableGen current =
      transf.addLocalVariable("current",
            org.apache.bcel.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);
View Full Code Here

     */
    private void compileStaticInitializer(ClassGenerator classGen) {
  final ConstantPoolGen cpg = classGen.getConstantPool();
  final InstructionList il = new InstructionList();

  final MethodGenerator staticConst =
      new MethodGenerator(ACC_PUBLIC|ACC_STATIC,
        org.apache.bcel.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);
            staticConst.markChunkEnd();
  }

  // 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();
  }

        // Put the tree of stylesheet namespace declarations into the translet
        final Vector namespaceAncestors = getXSLTC().getNSAncestorPointers();
        if (namespaceAncestors != null && namespaceAncestors.size() != 0) {
            addStaticField(classGen, NS_ANCESTORS_INDEX_SIG,
                           STATIC_NS_ANCESTORS_ARRAY_FIELD);
            staticConst.markChunkStart();
            il.append(new PUSH(cpg, namespaceAncestors.size()));
            il.append(new NEWARRAY(BasicType.INT));
            int namespaceAncestorsArrayRef =
                    cpg.addFieldref(_className, STATIC_NS_ANCESTORS_ARRAY_FIELD,
                                    NS_ANCESTORS_INDEX_SIG);
            il.append(new PUTSTATIC(namespaceAncestorsArrayRef));
            staticConst.markChunkEnd();
            for (int i = 0; i < namespaceAncestors.size(); i++) {
                int ancestor = ((Integer) namespaceAncestors.get(i)).intValue();
                staticConst.markChunkStart();
                il.append(new GETSTATIC(namespaceAncestorsArrayRef));
                il.append(new PUSH(cpg, i));
                il.append(new PUSH(cpg, ancestor));
                il.append(IASTORE);
                staticConst.markChunkEnd();
            }
        }
        // Put the array of indices into the namespace prefix/URI pairs array
        // into the translet
        final Vector prefixURIPairsIdx = getXSLTC().getPrefixURIPairsIdx();
        if (prefixURIPairsIdx != null && prefixURIPairsIdx.size() != 0) {
            addStaticField(classGen, PREFIX_URIS_IDX_SIG,
                           STATIC_PREFIX_URIS_IDX_ARRAY_FIELD);
            staticConst.markChunkStart();
            il.append(new PUSH(cpg, prefixURIPairsIdx.size()));
            il.append(new NEWARRAY(BasicType.INT));
            int prefixURIPairsIdxArrayRef =
                        cpg.addFieldref(_className,
                                        STATIC_PREFIX_URIS_IDX_ARRAY_FIELD,
                                        PREFIX_URIS_IDX_SIG);
            il.append(new PUTSTATIC(prefixURIPairsIdxArrayRef));
            staticConst.markChunkEnd();
            for (int i = 0; i < prefixURIPairsIdx.size(); i++) {
                int idx = ((Integer) prefixURIPairsIdx.get(i)).intValue();
                staticConst.markChunkStart();
                il.append(new GETSTATIC(prefixURIPairsIdxArrayRef));
                il.append(new PUSH(cpg, i));
                il.append(new PUSH(cpg, idx));
                il.append(IASTORE);
                staticConst.markChunkEnd();
            }
        }

        // Put the array of pairs of namespace prefixes and URIs into the
        // translet
        final Vector prefixURIPairs = getXSLTC().getPrefixURIPairs();
        if (prefixURIPairs != null && prefixURIPairs.size() != 0) {
            addStaticField(classGen, PREFIX_URIS_ARRAY_SIG,
                    STATIC_PREFIX_URIS_ARRAY_FIELD);

            staticConst.markChunkStart();
            il.append(new PUSH(cpg, prefixURIPairs.size()));
            il.append(new ANEWARRAY(cpg.addClass(STRING)));
            int prefixURIPairsRef =
                        cpg.addFieldref(_className,
                                        STATIC_PREFIX_URIS_ARRAY_FIELD,
                                        PREFIX_URIS_ARRAY_SIG);
            il.append(new PUTSTATIC(prefixURIPairsRef));
            staticConst.markChunkEnd();
            for (int i = 0; i < prefixURIPairs.size(); i++) {
                String prefixOrURI = (String) prefixURIPairs.get(i);
                staticConst.markChunkStart();
                il.append(new GETSTATIC(prefixURIPairsRef));
                il.append(new PUSH(cpg, i));
                il.append(new PUSH(cpg, prefixOrURI));
                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);
View Full Code Here

    private void compileConstructor(ClassGenerator classGen, Output output) {

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

  final MethodGenerator constructor =
      new MethodGenerator(ACC_PUBLIC,
        org.apache.bcel.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)));
        constructor.markChunkEnd();
 
        constructor.markChunkStart();
  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);
View Full Code Here

TOP

Related Classes of org.apache.xalan.xsltc.compiler.util.MethodGenerator

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.