1 16 19 20 package com.sun.org.apache.xalan.internal.xsltc.compiler; 21 22 import com.sun.org.apache.bcel.internal.generic.BranchHandle; 23 import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen; 24 import com.sun.org.apache.bcel.internal.generic.GOTO; 25 import com.sun.org.apache.bcel.internal.generic.IFLT; 26 import com.sun.org.apache.bcel.internal.generic.ILOAD; 27 import com.sun.org.apache.bcel.internal.generic.INVOKEINTERFACE; 28 import com.sun.org.apache.bcel.internal.generic.ISTORE; 29 import com.sun.org.apache.bcel.internal.generic.InstructionHandle; 30 import com.sun.org.apache.bcel.internal.generic.InstructionList; 31 import com.sun.org.apache.bcel.internal.generic.LocalVariableGen; 32 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator; 33 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator; 34 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type; 35 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError; 36 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util; 37 38 43 final class AncestorPattern extends RelativePathPattern { 44 45 private final Pattern _left; private final RelativePathPattern _right; 47 private InstructionHandle _loop; 48 49 public AncestorPattern(RelativePathPattern right) { 50 this(null, right); 51 } 52 53 public AncestorPattern(Pattern left, RelativePathPattern right) { 54 _left = left; 55 (_right = right).setParent(this); 56 if (left != null) { 57 left.setParent(this); 58 } 59 } 60 61 public InstructionHandle getLoopHandle() { 62 return _loop; 63 } 64 65 public void setParser(Parser parser) { 66 super.setParser(parser); 67 if (_left != null) { 68 _left.setParser(parser); 69 } 70 _right.setParser(parser); 71 } 72 73 public boolean isWildcard() { 74 return false; 76 } 77 78 public StepPattern getKernelPattern() { 79 return _right.getKernelPattern(); 80 } 81 82 public void reduceKernelPattern() { 83 _right.reduceKernelPattern(); 84 } 85 86 public Type typeCheck(SymbolTable stable) throws TypeCheckError { 87 if (_left != null) { 88 _left.typeCheck(stable); 89 } 90 return _right.typeCheck(stable); 91 } 92 93 public void translate(ClassGenerator classGen, MethodGenerator methodGen) { 94 InstructionHandle parent; 95 final ConstantPoolGen cpg = classGen.getConstantPool(); 96 final InstructionList il = methodGen.getInstructionList(); 97 98 102 final LocalVariableGen local = 103 methodGen.addLocalVariable2("app", Util.getJCRefType(NODE_SIG), 104 il.getEnd()); 105 106 final com.sun.org.apache.bcel.internal.generic.Instruction loadLocal = 107 new ILOAD(local.getIndex()); 108 final com.sun.org.apache.bcel.internal.generic.Instruction storeLocal = 109 new ISTORE(local.getIndex()); 110 111 if (_right instanceof StepPattern) { 112 il.append(DUP); 113 il.append(storeLocal); 114 _right.translate(classGen, methodGen); 115 il.append(methodGen.loadDOM()); 116 il.append(loadLocal); 117 } 118 else { 119 _right.translate(classGen, methodGen); 120 121 if (_right instanceof AncestorPattern) { 122 il.append(methodGen.loadDOM()); 123 il.append(SWAP); 124 } 125 } 126 127 if (_left != null) { 128 final int getParent = cpg.addInterfaceMethodref(DOM_INTF, 129 GET_PARENT, 130 GET_PARENT_SIG); 131 parent = il.append(new INVOKEINTERFACE(getParent, 2)); 132 133 il.append(DUP); 134 il.append(storeLocal); 135 _falseList.add(il.append(new IFLT(null))); 136 il.append(loadLocal); 137 138 _left.translate(classGen, methodGen); 139 140 final SyntaxTreeNode p = getParent(); 141 if (p == null || p instanceof Instruction || 142 p instanceof TopLevelElement) 143 { 144 } 146 else { 147 il.append(loadLocal); 148 } 149 150 final BranchHandle exit = il.append(new GOTO(null)); 151 _loop = il.append(methodGen.loadDOM()); 152 il.append(loadLocal); 153 local.setEnd(_loop); 154 il.append(new GOTO(parent)); 155 exit.setTarget(il.append(NOP)); 156 _left.backPatchFalseList(_loop); 157 158 _trueList.append(_left._trueList); 159 } 160 else { 161 il.append(POP2); 162 } 163 164 168 if (_right instanceof AncestorPattern) { 169 final AncestorPattern ancestor = (AncestorPattern) _right; 170 _falseList.backPatch(ancestor.getLoopHandle()); } 172 173 _trueList.append(_right._trueList); 174 _falseList.append(_right._falseList); 175 } 176 177 public String toString() { 178 return "AncestorPattern(" + _left + ", " + _right + ')'; 179 } 180 } 181 | Popular Tags |