KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > xalan > xsltc > compiler > util > MethodGenerator


1 /*
2  * Copyright 2001-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 /*
17  * $Id: MethodGenerator.java,v 1.15 2004/02/16 22:26:44 minchau Exp $
18  */

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 /**
37  * @author Jacek Ambroziak
38  * @author Santiago Pericas-Geertsen
39  */

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 JavaDoc START_ELEMENT_SIG
45     = "(" + STRING_SIG + ")V";
46     private static final String JavaDoc 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 JavaDoc[] arg_names,
81                String JavaDoc method_name, String JavaDoc 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     /**
161      * Allocates a local variable. If the slot allocator has already been
162      * initialized, then call addLocalVariable2() so that the new variable
163      * is known to the allocator. Failing to do this may cause the allocator
164      * to return a slot that is already in use.
165      */

166     public LocalVariableGen addLocalVariable(String JavaDoc 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 JavaDoc 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     /** by default context node is the same as current node. MK437 */
269     public Instruction loadContextNode() {
270     return loadCurrentNode();
271     }
272
273     public Instruction storeContextNode() {
274     return storeCurrentNode();
275     }
276
277     public int getLocalIndex(String JavaDoc name) {
278     return getLocalVariable(name).getIndex();
279     }
280
281     public LocalVariableGen getLocalVariable(String JavaDoc 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     // Get the current number of local variable slots
292
int maxLocals = super.getMaxLocals();
293     int prevLocals = maxLocals;
294
295     // Get numer of actual variables
296
final LocalVariableGen[] localVars = super.getLocalVariables();
297     if (localVars != null) {
298         if (localVars.length > maxLocals)
299         maxLocals = localVars.length;
300     }
301
302     // We want at least 5 local variable slots (for parameters)
303
if (maxLocals < 5) maxLocals = 5;
304
305     super.setMaxLocals(maxLocals);
306     }
307
308 }
309
Popular Tags