1 /* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5 /* 6 * Copyright 2001-2005 The Apache Software Foundation. 7 * 8 * Licensed under the Apache License, Version 2.0 (the "License"); 9 * you may not use this file except in compliance with the License. 10 * You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 */ 20 /* 21 * $Id: FilteredAbsoluteLocationPath.java,v 1.2.4.1 2005/09/12 10:26:50 pvedula Exp $ 22 */ 23 24 package com.sun.org.apache.xalan.internal.xsltc.compiler; 25 26 import com.sun.org.apache.bcel.internal.generic.ALOAD; 27 import com.sun.org.apache.bcel.internal.generic.ASTORE; 28 import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen; 29 import com.sun.org.apache.bcel.internal.generic.INVOKEINTERFACE; 30 import com.sun.org.apache.bcel.internal.generic.INVOKESPECIAL; 31 import com.sun.org.apache.bcel.internal.generic.InstructionList; 32 import com.sun.org.apache.bcel.internal.generic.LocalVariableGen; 33 import com.sun.org.apache.bcel.internal.generic.NEW; 34 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator; 35 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator; 36 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.NodeType; 37 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type; 38 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError; 39 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util; 40 41 /** 42 * @author G. Todd Miller 43 */ 44 final class FilteredAbsoluteLocationPath extends Expression { 45 private Expression _path; // may be null 46 47 public FilteredAbsoluteLocationPath() { 48 _path = null; 49 } 50 51 public FilteredAbsoluteLocationPath(Expression path) { 52 _path = path; 53 if (path != null) { 54 _path.setParent(this); 55 } 56 } 57 58 public void setParser(Parser parser) { 59 super.setParser(parser); 60 if (_path != null) { 61 _path.setParser(parser); 62 } 63 } 64 65 public Expression getPath() { 66 return(_path); 67 } 68 69 public String toString() { 70 return "FilteredAbsoluteLocationPath(" + 71 (_path != null ? _path.toString() : "null") + ')'; 72 } 73 74 public Type typeCheck(SymbolTable stable) throws TypeCheckError { 75 if (_path != null) { 76 final Type ptype = _path.typeCheck(stable); 77 if (ptype instanceof NodeType) { // promote to node-set 78 _path = new CastExpr(_path, Type.NodeSet); 79 } 80 } 81 return _type = Type.NodeSet; 82 } 83 84 public void translate(ClassGenerator classGen, MethodGenerator methodGen) { 85 final ConstantPoolGen cpg = classGen.getConstantPool(); 86 final InstructionList il = methodGen.getInstructionList(); 87 if (_path != null) { 88 final int initDFI = cpg.addMethodref(DUP_FILTERED_ITERATOR, 89 "<init>", 90 "(" 91 + NODE_ITERATOR_SIG 92 + ")V"); 93 94 // Backwards branches are prohibited if an uninitialized object is 95 // on the stack by section 4.9.4 of the JVM Specification, 2nd Ed. 96 // We don't know whether this code might contain backwards branches, 97 // so we mustn't create the new object until after we've created 98 // the suspect arguments to its constructor. Instead we calculate 99 // the values of the arguments to the constructor first, store them 100 // in temporary variables, create the object and reload the 101 // arguments from the temporaries to avoid the problem. 102 103 // Compile relative path iterator(s) 104 LocalVariableGen pathTemp = 105 methodGen.addLocalVariable("filtered_absolute_location_path_tmp", 106 Util.getJCRefType(NODE_ITERATOR_SIG), 107 null, null); 108 _path.translate(classGen, methodGen); 109 pathTemp.setStart(il.append(new ASTORE(pathTemp.getIndex()))); 110 111 // Create new Dup Filter Iterator 112 il.append(new NEW(cpg.addClass(DUP_FILTERED_ITERATOR))); 113 il.append(DUP); 114 pathTemp.setEnd(il.append(new ALOAD(pathTemp.getIndex()))); 115 116 // Initialize Dup Filter Iterator with iterator from the stack 117 il.append(new INVOKESPECIAL(initDFI)); 118 } 119 else { 120 final int git = cpg.addInterfaceMethodref(DOM_INTF, 121 "getIterator", 122 "()"+NODE_ITERATOR_SIG); 123 il.append(methodGen.loadDOM()); 124 il.append(new INVOKEINTERFACE(git, 1)); 125 } 126 } 127 }