Package org.apache.bcel.generic

Examples of org.apache.bcel.generic.InstructionList


  final String[] argNames = new String[3];
  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");

        // Insert an extra NOP just to keep "current" from appearing as if it
        // has a value before the start of the loop.
        mainIL.append(NOP);

        // Create a local variable to hold the current node
  final LocalVariableGen current;
  current = methodGen.addLocalVariable2("current",
                org.apache.bcel.generic.Type.INT,
                null);
  _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 IFLT(null));
  final BranchHandle loop = ilLoop.append(new GOTO_W(null));
  ifeq.setTarget(ilLoop.append(RETURN));   // applyTemplates() ends here!
  final InstructionHandle ihLoop = ilLoop.getStart();

        current.setStart(mainIL.append(new GOTO_W(ihLoop)));

        // Live range of "current" ends at end of loop
        current.setEnd(loop);

  // 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[DTM.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 + DTM.NTYPES] = isAttributeName(name);
      isNamespace[i + DTM.NTYPES] = isNamespaceName(name);
  }

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

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

  // Handle template with explicit "@*" pattern
  final TestSeq attrTest = _testSeq[DTM.ATTRIBUTE_NODE];
  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[DTM.TEXT_NODE];
      double textPrio = (0 - Double.MAX_VALUE);
      int    textPos  = Integer.MIN_VALUE;

      if (textTest != null) {
    textPrio = textTest.getPriority();
    textPos  = textTest.getPosition();
      }
      if (Double.isNaN(textPrio) || textPrio < nodePrio ||
          (textPrio == nodePrio && textPos < nodePos))
      {
    ihText = _childNodeTestSeq.compile(classGen, methodGen, ihLoop);
    _testSeq[DTM.TEXT_NODE] = _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 = DTM.NTYPES; i < targets.length; i++) {
      final TestSeq testSeq = _testSeq[i];
View Full Code Here


     */
    protected void compileResultTree(ClassGenerator classGen,
             MethodGenerator methodGen)
    {
  final ConstantPoolGen cpg = classGen.getConstantPool();
  final InstructionList il = methodGen.getInstructionList();
  final Stylesheet stylesheet = classGen.getStylesheet();

  boolean isSimple = isSimpleRTF(this);
  boolean isAdaptive = false;
  if (!isSimple) {
      isAdaptive = isAdaptiveRTF(this);
  }
 
  int rtfType = isSimple ? DOM.SIMPLE_RTF
                         : (isAdaptive ? DOM.ADAPTIVE_RTF : DOM.TREE_RTF);
 
  // Save the current handler base on the stack
  il.append(methodGen.loadHandler());

  final String DOM_CLASS = classGen.getDOMClass();

  // Create new instance of DOM class (with RTF_INITIAL_SIZE nodes)
  //int index = cpg.addMethodref(DOM_IMPL, "<init>", "(I)V");
  //il.append(new NEW(cpg.addClass(DOM_IMPL)));
 
  il.append(methodGen.loadDOM());
  int index = cpg.addInterfaceMethodref(DOM_INTF,
         "getResultTreeFrag",
         "(IIZ)" + DOM_INTF_SIG);
  il.append(new PUSH(cpg, RTF_INITIAL_SIZE));
  il.append(new PUSH(cpg, rtfType));
  il.append(new PUSH(cpg, stylesheet.callsNodeset()));
  il.append(new INVOKEINTERFACE(index,4));
 
  il.append(DUP);

  // Overwrite old handler with DOM handler
  index = cpg.addInterfaceMethodref(DOM_INTF,
         "getOutputDomBuilder",
         "()" + TRANSLET_OUTPUT_SIG);

  il.append(new INVOKEINTERFACE(index,1));
  il.append(DUP);
  il.append(methodGen.storeHandler());

  // Call startDocument on the new handler
  il.append(methodGen.startDocument());

  // Instantiate result tree fragment
  translateContents(classGen, methodGen);

  // Call endDocument on the new handler
  il.append(methodGen.loadHandler());
  il.append(methodGen.endDocument());

  // Check if we need to wrap the DOMImpl object in a DOMAdapter object.
  // DOMAdapter is not needed if the RTF is a simple RTF and the nodeset()
  // function is not used.
  if (stylesheet.callsNodeset()
      && !DOM_CLASS.equals(DOM_IMPL_CLASS)) {
      // new org.apache.xalan.xsltc.dom.DOMAdapter(DOMImpl,String[]);
      index = cpg.addMethodref(DOM_ADAPTER_CLASS,
             "<init>",
             "("+DOM_INTF_SIG+
             "["+STRING_SIG+
             "["+STRING_SIG+
             "[I"+
             "["+STRING_SIG+")V");
      il.append(new NEW(cpg.addClass(DOM_ADAPTER_CLASS)));
      il.append(new DUP_X1());
      il.append(SWAP);

      /*
       * Give the DOM adapter an empty type mapping if the nodeset
       * extension function is never called.
       */
      if (!stylesheet.callsNodeset()) {
    il.append(new ICONST(0));
    il.append(new ANEWARRAY(cpg.addClass(STRING)));
    il.append(DUP);
    il.append(DUP);
    il.append(new ICONST(0));
    il.append(new NEWARRAY(BasicType.INT));
    il.append(SWAP);
    il.append(new INVOKESPECIAL(index));
      }
      else {
    // Push name arrays on the stack
    il.append(ALOAD_0);
    il.append(new GETFIELD(cpg.addFieldref(TRANSLET_CLASS,
             NAMES_INDEX,
             NAMES_INDEX_SIG)));
    il.append(ALOAD_0);
    il.append(new GETFIELD(cpg.addFieldref(TRANSLET_CLASS,
             URIS_INDEX,
             URIS_INDEX_SIG)));
    il.append(ALOAD_0);
    il.append(new GETFIELD(cpg.addFieldref(TRANSLET_CLASS,
             TYPES_INDEX,
             TYPES_INDEX_SIG)));
    il.append(ALOAD_0);
    il.append(new GETFIELD(cpg.addFieldref(TRANSLET_CLASS,
             NAMESPACE_INDEX,
             NAMESPACE_INDEX_SIG)));

    // Initialized DOM adapter
    il.append(new INVOKESPECIAL(index));

    // Add DOM adapter to MultiDOM class by calling addDOMAdapter()
    il.append(DUP);
    il.append(methodGen.loadDOM());
    il.append(new CHECKCAST(cpg.addClass(classGen.getDOMClass())));
    il.append(SWAP);
    index = cpg.addMethodref(MULTI_DOM_CLASS,
           "addDOMAdapter",
           "(" + DOM_ADAPTER_SIG + ")I");
    il.append(new INVOKEVIRTUAL(index));
    il.append(POP);    // ignore mask returned by addDOMAdapter
      }
  }

  // Restore old handler base from stack
  il.append(SWAP);
  il.append(methodGen.storeHandler());
    }
View Full Code Here

  return typeCheckContents(stable);
    }

    public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
  final ConstantPoolGen cpg = classGen.getConstantPool();
  final InstructionList il = methodGen.getInstructionList();

  if (_disabled) return;
  // bug fix #4433133, add a call to named template from applyTemplates
  String className = classGen.getClassName();

  if (_compiled && isNamed()){
      String methodName = Util.escape(_name.toString());
      il.append(classGen.loadTranslet());
      il.append(methodGen.loadDOM());
      il.append(methodGen.loadIterator());
      il.append(methodGen.loadHandler());
      il.append(methodGen.loadCurrentNode());
      il.append(new INVOKEVIRTUAL(cpg.addMethodref(className,
               methodName,
               "("
               + DOM_INTF_SIG
               + NODE_ITERATOR_SIG
               + TRANSLET_OUTPUT_SIG
               + "I)V")));
      return;
  }

  if (_compiled) return;
  _compiled = true;
   
  // %OPT% Special handling for simple named templates.
  if (_isSimpleNamedTemplate && methodGen instanceof NamedMethodGenerator) {
      int numParams = _parameters.size();
      NamedMethodGenerator namedMethodGen = (NamedMethodGenerator)methodGen;
           
            // Update load/store instructions to access Params from the stack
      for (int i = 0; i < numParams; i++) {
        Param param = (Param)_parameters.elementAt(i);
        param.setLoadInstruction(namedMethodGen.loadParameter(i));
        param.setStoreInstruction(namedMethodGen.storeParameter(i));
      }
  }
       
        translateContents(classGen, methodGen);
  il.setPositions(true);
    }
View Full Code Here

    }

    public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
  final Stylesheet stylesheet = classGen.getStylesheet();
  final ConstantPoolGen cpg = classGen.getConstantPool();
  final InstructionList il = methodGen.getInstructionList();

        // If there are Params in the stylesheet or WithParams in this call?
  if (stylesheet.hasLocalParams() || hasContents()) {
      _calleeTemplate = getCalleeTemplate();
     
      // Build the parameter list if the called template is simple named
      if (_calleeTemplate != null) {
        buildParameterList();
      }
      // This is only needed when the called template is not
      // a simple named template.
      else {
          // Push parameter frame
          final int push = cpg.addMethodref(TRANSLET_CLASS,
                    PUSH_PARAM_FRAME,
                    PUSH_PARAM_FRAME_SIG);
          il.append(classGen.loadTranslet());
          il.append(new INVOKEVIRTUAL(push));
          translateContents(classGen, methodGen);
      }
  }

        // Generate a valid Java method name
  final String className = stylesheet.getClassName();
        String methodName = Util.escape(_name.toString());

        // Load standard arguments
  il.append(classGen.loadTranslet());
  il.append(methodGen.loadDOM());
  il.append(methodGen.loadIterator());
  il.append(methodGen.loadHandler());
  il.append(methodGen.loadCurrentNode());
       
        // Initialize prefix of method signature
  StringBuffer methodSig = new StringBuffer("(" + DOM_INTF_SIG
            + NODE_ITERATOR_SIG + TRANSLET_OUTPUT_SIG + NODE_SIG);
 
        // If calling a simply named template, push actual arguments
  if (_calleeTemplate != null) {
      Vector calleeParams = _calleeTemplate.getParameters();
      int numParams = _parameters.length;
     
      for (int i = 0; i < numParams; i++) {
          SyntaxTreeNode node = (SyntaxTreeNode)_parameters[i];
                methodSig.append(OBJECT_SIG);   // append Object to signature
               
                // Push 'null' if Param to indicate no actual parameter specified
                if (node instanceof Param) {
                    il.append(ACONST_NULL);
                }
                else // translate WithParam
                    node.translate(classGen, methodGen);
                }
            }
        }

        // Complete signature and generate invokevirtual call
  methodSig.append(")V");
  il.append(new INVOKEVIRTUAL(cpg.addMethodref(className,
                 methodName,
                 methodSig.toString())));
 
  // Do not need to call Translet.popParamFrame() if we are
  // calling a simple named template.
  if (_calleeTemplate == null && (stylesheet.hasLocalParams() || hasContents())) {
      // Pop parameter frame
      final int pop = cpg.addMethodref(TRANSLET_CLASS,
               POP_PARAM_FRAME,
               POP_PARAM_FRAME_SIG);
      il.append(classGen.loadTranslet());
      il.append(new INVOKEVIRTUAL(pop));
  }
    }
View Full Code Here

     * In this case, there is no need to inspect the element name at runtime to
     * determine if a prefix exists, needs to be generated, etc.
     */
    public void translateLiteral(ClassGenerator classGen, MethodGenerator methodGen) {
  final ConstantPoolGen cpg = classGen.getConstantPool();
  final InstructionList il = methodGen.getInstructionList();

  if (!_ignore) {
      il.append(methodGen.loadHandler());
      _name.translate(classGen, methodGen);
      il.append(DUP2);
      il.append(methodGen.startElement());

      if (_namespace != null) {
    il.append(methodGen.loadHandler());
    il.append(new PUSH(cpg, _prefix));
    _namespace.translate(classGen,methodGen);
    il.append(methodGen.namespace());
      }
  }

  translateContents(classGen, methodGen);

  if (!_ignore) {
      il.append(methodGen.endElement());
  }
    }
View Full Code Here

     * on the handler (vii) evaluates the contents (viii) calls endElement().
     */
    public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
  LocalVariableGen local = null;
  final ConstantPoolGen cpg = classGen.getConstantPool();
  final InstructionList il = methodGen.getInstructionList();

  // Optimize translation if element name is a literal
  if (_isLiteralName) {
      translateLiteral(classGen, methodGen);
      return;
  }

  if (!_ignore) {
      
            // if the qname is an AVT, then the qname has to be checked at runtime if it is a valid qname
            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 checkQName if the name is an AVT
            final int check = cpg.addMethodref(BASIS_LIBRARY_CLASS, "checkQName",
                            "("
                            +STRING_SIG
                            +")V");                
            il.append(new INVOKESTATIC(check));
           
            // Push handler for call to endElement()
            il.append(methodGen.loadHandler());        
           
            // load name value again
            nameValue.setEnd(il.append(new ALOAD(nameValue.getIndex())));
                   
      if (_namespace != null) {
    _namespace.translate(classGen, methodGen);
      }
      else {
                // If name is an AVT and namespace is not specified, need to
                // look up any prefix in the stylesheet by calling
                //   BasisLibrary.lookupStylesheetQNameNamespace(
                //                name, stylesheetNode, ancestorsArray,
                //                prefixURIsIndexArray, prefixURIPairsArray,
                //                !ignoreDefaultNamespace)
                String transletClassName = getXSLTC().getClassName();
                il.append(DUP);
                il.append(new PUSH(cpg, getNodeIDForStylesheetNSLookup()));
                il.append(new GETSTATIC(cpg.addFieldref(
                                             transletClassName,
                                             STATIC_NS_ANCESTORS_ARRAY_FIELD,
                                             NS_ANCESTORS_INDEX_SIG)));
                il.append(new GETSTATIC(cpg.addFieldref(
                                             transletClassName,
                                             STATIC_PREFIX_URIS_IDX_ARRAY_FIELD,
                                             PREFIX_URIS_IDX_SIG)));
                il.append(new GETSTATIC(cpg.addFieldref(
                                             transletClassName,
                                             STATIC_PREFIX_URIS_ARRAY_FIELD,
                                             PREFIX_URIS_ARRAY_SIG)));
                // Default namespace is significant
                il.append(ICONST_0);
                il.append(
                    new INVOKESTATIC(
                        cpg.addMethodref(BASIS_LIBRARY_CLASS,
                                           LOOKUP_STYLESHEET_QNAME_NS_REF,
                                           LOOKUP_STYLESHEET_QNAME_NS_SIG)));
      }

            // Push additional arguments
      il.append(methodGen.loadHandler());
      il.append(methodGen.loadDOM());
      il.append(methodGen.loadCurrentNode());
       
            // Invoke BasisLibrary.startXslElemCheckQName()
            il.append(new INVOKESTATIC(
            cpg.addMethodref(BASIS_LIBRARY_CLASS, "startXslElement",
                    "(" + STRING_SIG
                    + STRING_SIG
                    + TRANSLET_OUTPUT_SIG
                    + DOM_INTF_SIG + "I)" + STRING_SIG)));               


  }

  translateContents(classGen, methodGen);

  if (!_ignore) {
      il.append(methodGen.endElement());
  }
    }
View Full Code Here

  return Type.NodeSet;
    }

    public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
  final ConstantPoolGen cpg = classGen.getConstantPool();
  final InstructionList il = methodGen.getInstructionList();

  // context node is on the stack
  int gname = cpg.addInterfaceMethodref(DOM_INTF,
                "getNodeName",
                "(I)Ljava/lang/String;");
  int cmp = cpg.addMethodref(STRING_CLASS,
           "equals", "(Ljava/lang/Object;)Z");

  // Push current node on the stack
  il.append(methodGen.loadCurrentNode());
  il.append(SWAP);

  // Overwrite current node with matching node
  il.append(methodGen.storeCurrentNode());

  // If pattern not reduced then check kernel
  if (!_typeChecked) {
      il.append(methodGen.loadCurrentNode());
      final int getType = cpg.addInterfaceMethodref(DOM_INTF,
                "getType", "(I)I");
      il.append(methodGen.loadDOM());
      il.append(methodGen.loadCurrentNode());
      il.append(new INVOKEINTERFACE(getType, 2));
      il.append(new PUSH(cpg, DOM.PROCESSING_INSTRUCTION));
      _falseList.add(il.append(new IF_ICMPEQ(null)));
  }

  // Load the requested processing instruction name
  il.append(new PUSH(cpg, _name));
  // Load the current processing instruction's name
  il.append(methodGen.loadDOM());
  il.append(methodGen.loadCurrentNode());
  il.append(new INVOKEINTERFACE(gname, 2));
  // Compare the two strings
  il.append(new INVOKEVIRTUAL(cmp));
  _falseList.add(il.append(new IFEQ(null)));
   
  // Compile the expressions within the predicates
  if (hasPredicates()) {
      final int n = _predicates.size();
      for (int i = 0; i < n; i++) {
    Predicate pred = (Predicate)_predicates.elementAt(i);
    Expression exp = pred.getExpr();
    exp.translateDesynthesized(classGen, methodGen);
    _trueList.append(exp._trueList);
    _falseList.append(exp._falseList);
      }
  }

  // Backpatch true list and restore current iterator/node
  InstructionHandle restore;
  restore = il.append(methodGen.storeCurrentNode());
  backPatchTrueList(restore);
  BranchHandle skipFalse = il.append(new GOTO(null));

  // Backpatch false list and restore current iterator/node
  restore = il.append(methodGen.storeCurrentNode());
  backPatchFalseList(restore);
  _falseList.add(il.append(new GOTO(null)));

  // True list falls through
  skipFalse.setTarget(il.append(NOP));
    }
View Full Code Here

      compileResultTree(classGen, methodGen);
  }
  // If neither are present then store empty string in parameter slot
  else {
      final ConstantPoolGen cpg = classGen.getConstantPool();
      final InstructionList il = methodGen.getInstructionList();
      il.append(new PUSH(cpg, Constants.EMPTYSTRING));
  }
    }
View Full Code Here

     * addParameter() method in AbstractTranslet. The method call will add
     * (or update) the parameter frame with the new parameter value.
     */
    public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
  final ConstantPoolGen cpg = classGen.getConstantPool();
  final InstructionList il = methodGen.getInstructionList();

  // Make name acceptable for use as field name in class
  String name = Util.escape(_name.getLocalPart());

  // Load reference to the translet (method is in AbstractTranslet)
  il.append(classGen.loadTranslet());

  // Load the name of the parameter
  il.append(new PUSH(cpg, name)); // TODO: namespace ?
  // Generete the value of the parameter (use value in 'select' by def.)
  translateValue(classGen, methodGen);
  // Mark this parameter value is not being the default value
  il.append(new PUSH(cpg, false));
  // Pass the parameter to the template
  il.append(new INVOKEVIRTUAL(cpg.addMethodref(TRANSLET_CLASS,
                 ADD_PARAMETER,
                 ADD_PARAMETER_SIG)));
  il.append(POP); // cleanup stack
    }
View Full Code Here

     * Compile expression and update true/false-lists
     */
    public void translateDesynthesized(ClassGenerator classGen,
               MethodGenerator methodGen) {

  final InstructionList il = methodGen.getInstructionList();
  final SyntaxTreeNode parent = getParent();

  // Compile AND-expression
  if (_op == AND) {

      // Translate left hand side - must be true
      _left.translateDesynthesized(classGen, methodGen);

      // Need this for chaining any OR-expression children
      InstructionHandle middle = il.append(NOP);

      // Translate left right side - must be true
      _right.translateDesynthesized(classGen, methodGen);

      // Need this for chaining any OR-expression children
      InstructionHandle after = il.append(NOP);

      // Append child expression false-lists to our false-list
      _falseList.append(_right._falseList.append(_left._falseList));

      // Special case for OR-expression as a left child of AND.
      // The true-list of OR must point to second clause of AND.
      if ((_left instanceof LogicalExpr) &&
    (((LogicalExpr)_left).getOp() == OR)) {
    _left.backPatchTrueList(middle);
      }
      else if (_left instanceof NotCall) {
    _left.backPatchTrueList(middle);
      }
      else {
    _trueList.append(_left._trueList);
      }

      // Special case for OR-expression as a right child of AND
      // The true-list of OR must point to true-list of AND.
      if ((_right instanceof LogicalExpr) &&
    (((LogicalExpr)_right).getOp() == OR)) {
    _right.backPatchTrueList(after);
      }
      else if (_right instanceof NotCall) {
    _right.backPatchTrueList(after);
      }
      else {
    _trueList.append(_right._trueList);
      }
  }
  // Compile OR-expression
  else {
      // Translate left-hand side expression and produce true/false list
      _left.translateDesynthesized(classGen, methodGen);

      // This GOTO is used to skip over the code for the last test
      // in the case where the the first test succeeds
      InstructionHandle ih = il.append(new GOTO(null));

      // Translate right-hand side expression and produce true/false list
      _right.translateDesynthesized(classGen, methodGen);

      _left._trueList.backPatch(ih);
View Full Code Here

TOP

Related Classes of org.apache.bcel.generic.InstructionList

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.