1 16 19 20 package org.apache.xalan.xsltc.compiler.util; 21 22 import org.apache.bcel.generic.ALOAD; 23 import org.apache.bcel.generic.ASTORE; 24 import org.apache.bcel.generic.ConstantPoolGen; 25 import org.apache.bcel.generic.ICONST; 26 import org.apache.bcel.generic.ILOAD; 27 import org.apache.bcel.generic.INVOKEINTERFACE; 28 import org.apache.bcel.generic.ISTORE; 29 import org.apache.bcel.generic.Instruction; 30 import org.apache.bcel.generic.InstructionHandle; 31 import org.apache.bcel.generic.InstructionList; 32 import org.apache.bcel.generic.LocalVariableGen; 33 import org.apache.bcel.generic.MethodGen; 34 import org.apache.bcel.generic.Type; 35 36 40 public class MethodGenerator extends MethodGen 41 implements org.apache.xalan.xsltc.compiler.Constants { 42 protected static final int INVALID_INDEX = -1; 43 44 private static final String START_ELEMENT_SIG 45 = "(" + STRING_SIG + ")V"; 46 private static final String END_ELEMENT_SIG 47 = START_ELEMENT_SIG; 48 49 private InstructionList _mapTypeSub; 50 51 private static final int DOM_INDEX = 1; 52 private static final int ITERATOR_INDEX = 2; 53 private static final int HANDLER_INDEX = 3; 54 55 private Instruction _iloadCurrent; 56 private Instruction _istoreCurrent; 57 private final Instruction _astoreHandler; 58 private final Instruction _aloadHandler; 59 private final Instruction _astoreIterator; 60 private final Instruction _aloadIterator; 61 private final Instruction _aloadDom; 62 private final Instruction _astoreDom; 63 64 private final Instruction _startElement; 65 private final Instruction _endElement; 66 private final Instruction _startDocument; 67 private final Instruction _endDocument; 68 private final Instruction _attribute; 69 private final Instruction _uniqueAttribute; 70 private final Instruction _namespace; 71 72 private final Instruction _setStartNode; 73 private final Instruction _reset; 74 private final Instruction _nextNode; 75 76 private SlotAllocator _slotAllocator; 77 private boolean _allocatorInit = false; 78 79 public MethodGenerator(int access_flags, Type return_type, 80 Type[] arg_types, String [] arg_names, 81 String method_name, String class_name, 82 InstructionList il, ConstantPoolGen cpg) { 83 super(access_flags, return_type, arg_types, arg_names, method_name, 84 class_name, il, cpg); 85 86 _astoreHandler = new ASTORE(HANDLER_INDEX); 87 _aloadHandler = new ALOAD(HANDLER_INDEX); 88 _astoreIterator = new ASTORE(ITERATOR_INDEX); 89 _aloadIterator = new ALOAD(ITERATOR_INDEX); 90 _aloadDom = new ALOAD(DOM_INDEX); 91 _astoreDom = new ASTORE(DOM_INDEX); 92 93 final int startElement = 94 cpg.addInterfaceMethodref(TRANSLET_OUTPUT_INTERFACE, 95 "startElement", 96 START_ELEMENT_SIG); 97 _startElement = new INVOKEINTERFACE(startElement, 2); 98 99 final int endElement = 100 cpg.addInterfaceMethodref(TRANSLET_OUTPUT_INTERFACE, 101 "endElement", 102 END_ELEMENT_SIG); 103 _endElement = new INVOKEINTERFACE(endElement, 2); 104 105 final int attribute = 106 cpg.addInterfaceMethodref(TRANSLET_OUTPUT_INTERFACE, 107 "addAttribute", 108 "(" 109 + STRING_SIG 110 + STRING_SIG 111 + ")V"); 112 _attribute = new INVOKEINTERFACE(attribute, 3); 113 114 final int uniqueAttribute = 115 cpg.addInterfaceMethodref(TRANSLET_OUTPUT_INTERFACE, 116 "addUniqueAttribute", 117 "(" 118 + STRING_SIG 119 + STRING_SIG 120 + "I)V"); 121 _uniqueAttribute = new INVOKEINTERFACE(uniqueAttribute, 4); 122 123 final int namespace = 124 cpg.addInterfaceMethodref(TRANSLET_OUTPUT_INTERFACE, 125 "namespaceAfterStartElement", 126 "(" 127 + STRING_SIG 128 + STRING_SIG 129 + ")V"); 130 _namespace = new INVOKEINTERFACE(namespace, 3); 131 132 int index = cpg.addInterfaceMethodref(TRANSLET_OUTPUT_INTERFACE, 133 "startDocument", 134 "()V"); 135 _startDocument = new INVOKEINTERFACE(index, 1); 136 137 index = cpg.addInterfaceMethodref(TRANSLET_OUTPUT_INTERFACE, 138 "endDocument", 139 "()V"); 140 _endDocument = new INVOKEINTERFACE(index, 1); 141 142 143 index = cpg.addInterfaceMethodref(NODE_ITERATOR, 144 SET_START_NODE, 145 SET_START_NODE_SIG); 146 _setStartNode = new INVOKEINTERFACE(index, 2); 147 148 index = cpg.addInterfaceMethodref(NODE_ITERATOR, 149 "reset", "()"+NODE_ITERATOR_SIG); 150 _reset = new INVOKEINTERFACE(index, 1); 151 152 index = cpg.addInterfaceMethodref(NODE_ITERATOR, NEXT, NEXT_SIG); 153 _nextNode = new INVOKEINTERFACE(index, 1); 154 155 _slotAllocator = new SlotAllocator(); 156 _slotAllocator.initialize(getLocalVariables()); 157 _allocatorInit = true; 158 } 159 160 166 public LocalVariableGen addLocalVariable(String name, Type type, 167 InstructionHandle start, 168 InstructionHandle end) 169 { 170 return (_allocatorInit) ? addLocalVariable2(name, type, start) 171 : super.addLocalVariable(name, type, start, end); 172 } 173 174 public LocalVariableGen addLocalVariable2(String name, Type type, 175 InstructionHandle start) 176 { 177 return super.addLocalVariable(name, type, 178 _slotAllocator.allocateSlot(type), 179 start, null); 180 } 181 182 public void removeLocalVariable(LocalVariableGen lvg) { 183 _slotAllocator.releaseSlot(lvg); 184 super.removeLocalVariable(lvg); 185 } 186 187 public Instruction loadDOM() { 188 return _aloadDom; 189 } 190 191 public Instruction storeDOM() { 192 return _astoreDom; 193 } 194 195 public Instruction storeHandler() { 196 return _astoreHandler; 197 } 198 199 public Instruction loadHandler() { 200 return _aloadHandler; 201 } 202 203 public Instruction storeIterator() { 204 return _astoreIterator; 205 } 206 207 public Instruction loadIterator() { 208 return _aloadIterator; 209 } 210 211 public final Instruction setStartNode() { 212 return _setStartNode; 213 } 214 215 public final Instruction reset() { 216 return _reset; 217 } 218 219 public final Instruction nextNode() { 220 return _nextNode; 221 } 222 223 public final Instruction startElement() { 224 return _startElement; 225 } 226 227 public final Instruction endElement() { 228 return _endElement; 229 } 230 231 public final Instruction startDocument() { 232 return _startDocument; 233 } 234 235 public final Instruction endDocument() { 236 return _endDocument; 237 } 238 239 public final Instruction attribute() { 240 return _attribute; 241 } 242 243 public final Instruction uniqueAttribute() { 244 return _uniqueAttribute; 245 } 246 247 public final Instruction namespace() { 248 return _namespace; 249 } 250 251 public Instruction loadCurrentNode() { 252 if (_iloadCurrent == null) { 253 int idx = getLocalIndex("current"); 254 if (idx > 0) 255 _iloadCurrent = new ILOAD(idx); 256 else 257 _iloadCurrent = new ICONST(0); 258 } 259 return _iloadCurrent; 260 } 261 262 public Instruction storeCurrentNode() { 263 return _istoreCurrent != null 264 ? _istoreCurrent 265 : (_istoreCurrent = new ISTORE(getLocalIndex("current"))); 266 } 267 268 269 public Instruction loadContextNode() { 270 return loadCurrentNode(); 271 } 272 273 public Instruction storeContextNode() { 274 return storeCurrentNode(); 275 } 276 277 public int getLocalIndex(String name) { 278 return getLocalVariable(name).getIndex(); 279 } 280 281 public LocalVariableGen getLocalVariable(String name) { 282 final LocalVariableGen[] vars = getLocalVariables(); 283 for (int i = 0; i < vars.length; i++) 284 if (vars[i].getName().equals(name)) 285 return vars[i]; 286 return null; 287 } 288 289 public void setMaxLocals() { 290 291 int maxLocals = super.getMaxLocals(); 293 int prevLocals = maxLocals; 294 295 final LocalVariableGen[] localVars = super.getLocalVariables(); 297 if (localVars != null) { 298 if (localVars.length > maxLocals) 299 maxLocals = localVars.length; 300 } 301 302 if (maxLocals < 5) maxLocals = 5; 304 305 super.setMaxLocals(maxLocals); 306 } 307 308 } 309 | Popular Tags |