OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [tools/] [external/] [asm/] [org/] [objectweb/] [asm/] [xml/] [ASMContentHandler.java] - Blame information for rev 779

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 779 jeremybenn
/***
2
 * ASM XML Adapter
3
 * Copyright (c) 2004, Eugene Kuleshov
4
 * All rights reserved.
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions
8
 * are met:
9
 * 1. Redistributions of source code must retain the above copyright
10
 *    notice, this list of conditions and the following disclaimer.
11
 * 2. Redistributions in binary form must reproduce the above copyright
12
 *    notice, this list of conditions and the following disclaimer in the
13
 *    documentation and/or other materials provided with the distribution.
14
 * 3. Neither the name of the copyright holders nor the names of its
15
 *    contributors may be used to endorse or promote products derived from
16
 *    this software without specific prior written permission.
17
 *
18
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28
 * THE POSSIBILITY OF SUCH DAMAGE.
29
 */
30
package org.objectweb.asm.xml;
31
 
32
import java.io.IOException;
33
import java.io.OutputStream;
34
import java.util.ArrayList;
35
import java.util.HashMap;
36
import java.util.Iterator;
37
import java.util.List;
38
import java.util.Map;
39
 
40
import org.objectweb.asm.AnnotationVisitor;
41
import org.objectweb.asm.ClassVisitor;
42
import org.objectweb.asm.ClassWriter;
43
import org.objectweb.asm.FieldVisitor;
44
import org.objectweb.asm.MethodVisitor;
45
import org.objectweb.asm.Opcodes;
46
import org.objectweb.asm.Label;
47
import org.objectweb.asm.Type;
48
 
49
import org.xml.sax.Attributes;
50
import org.xml.sax.SAXException;
51
import org.xml.sax.helpers.DefaultHandler;
52
 
53
/**
54
 * A {@link org.xml.sax.ContentHandler ContentHandler} that transforms XML
55
 * document into Java class file. This class can be feeded by any kind of SAX
56
 * 2.0 event producers, e.g. XML parser, XSLT or XPath engines, or custom code.
57
 *
58
 * @see org.objectweb.asm.xml.SAXClassAdapter
59
 * @see org.objectweb.asm.xml.Processor
60
 *
61
 * @author Eugene Kuleshov
62
 */
63
public class ASMContentHandler extends DefaultHandler implements Opcodes {
64
    /**
65
     * Stack of the intermediate processing contexts.
66
     */
67
    private List stack = new ArrayList();
68
 
69
    /**
70
     * Complete name of the current element.
71
     */
72
    private String match = "";
73
 
74
    /**
75
     * <tt>true</tt> if the maximum stack size and number of local variables
76
     * must be automatically computed.
77
     */
78
    protected boolean computeMax;
79
 
80
    /**
81
     * Output stream to write result bytecode.
82
     */
83
    protected OutputStream os;
84
 
85
    /**
86
     * Current instance of the {@link ClassWriter ClassWriter} used to write
87
     * class bytecode.
88
     */
89
    protected ClassWriter cw;
90
 
91
    /**
92
     * Map of the active {@link Label Label} instances for current method.
93
     */
94
    protected Map labels;
95
 
96
    private static final String BASE = "class";
97
 
98
    private final RuleSet RULES = new RuleSet();
99
    {
100
        RULES.add(BASE, new ClassRule());
101
        RULES.add(BASE + "/interfaces/interface", new InterfaceRule());
102
        RULES.add(BASE + "/interfaces", new InterfacesRule());
103
        RULES.add(BASE + "/outerclass", new OuterClassRule());
104
        RULES.add(BASE + "/innerclass", new InnerClassRule());
105
        RULES.add(BASE + "/source", new SourceRule());
106
        RULES.add(BASE + "/field", new FieldRule());
107
 
108
        RULES.add(BASE + "/method", new MethodRule());
109
        RULES.add(BASE + "/method/exceptions/exception", new ExceptionRule());
110
        RULES.add(BASE + "/method/exceptions", new ExceptionsRule());
111
 
112
        RULES.add(BASE + "/method/annotationDefault",
113
                new AnnotationDefaultRule());
114
 
115
        RULES.add(BASE + "/method/code/*", new OpcodesRule()); // opcodes
116
 
117
        RULES.add(BASE + "/method/code/TABLESWITCH", new TableSwitchRule());
118
        RULES.add(BASE + "/method/code/TABLESWITCH/label",
119
                new TableSwitchLabelRule());
120
        RULES.add(BASE + "/method/code/LOOKUPSWITCH", new LookupSwitchRule());
121
        RULES.add(BASE + "/method/code/LOOKUPSWITCH/label",
122
                new LookupSwitchLabelRule());
123
 
124
        RULES.add(BASE + "/method/code/Label", new LabelRule());
125
        RULES.add(BASE + "/method/code/TryCatch", new TryCatchRule());
126
        RULES.add(BASE + "/method/code/LineNumber", new LineNumberRule());
127
        RULES.add(BASE + "/method/code/LocalVar", new LocalVarRule());
128
        RULES.add(BASE + "/method/code/Max", new MaxRule());
129
 
130
        RULES.add("*/annotation", new AnnotationRule());
131
        RULES.add("*/parameterAnnotation", new AnnotationParameterRule());
132
        RULES.add("*/annotationValue", new AnnotationValueRule());
133
        RULES.add("*/annotationValueAnnotation",
134
                new AnnotationValueAnnotationRule());
135
        RULES.add("*/annotationValueEnum", new AnnotationValueEnumRule());
136
        RULES.add("*/annotationValueArray", new AnnotationValueArrayRule());
137
    }
138
 
139
    private static interface OpcodeGroup {
140
        public static final int INSN = 0;
141
        public static final int INSN_INT = 1;
142
        public static final int INSN_VAR = 2;
143
        public static final int INSN_TYPE = 3;
144
        public static final int INSN_FIELD = 4;
145
        public static final int INSN_METHOD = 5;
146
        public static final int INSN_JUMP = 6;
147
        public static final int INSN_LDC = 7;
148
        public static final int INSN_IINC = 8;
149
        public static final int INSN_MULTIANEWARRAY = 9;
150
    }
151
 
152
    /**
153
     * Map of the opcode names to opcode and opcode group
154
     */
155
    static final Map OPCODES = new HashMap();
156
    static {
157
        OPCODES.put("NOP", new Opcode(NOP, OpcodeGroup.INSN));
158
        OPCODES.put("ACONST_NULL", new Opcode(ACONST_NULL, OpcodeGroup.INSN));
159
        OPCODES.put("ICONST_M1", new Opcode(ICONST_M1, OpcodeGroup.INSN));
160
        OPCODES.put("ICONST_0", new Opcode(ICONST_0, OpcodeGroup.INSN));
161
        OPCODES.put("ICONST_1", new Opcode(ICONST_1, OpcodeGroup.INSN));
162
        OPCODES.put("ICONST_2", new Opcode(ICONST_2, OpcodeGroup.INSN));
163
        OPCODES.put("ICONST_3", new Opcode(ICONST_3, OpcodeGroup.INSN));
164
        OPCODES.put("ICONST_4", new Opcode(ICONST_4, OpcodeGroup.INSN));
165
        OPCODES.put("ICONST_5", new Opcode(ICONST_5, OpcodeGroup.INSN));
166
        OPCODES.put("LCONST_0", new Opcode(LCONST_0, OpcodeGroup.INSN));
167
        OPCODES.put("LCONST_1", new Opcode(LCONST_1, OpcodeGroup.INSN));
168
        OPCODES.put("FCONST_0", new Opcode(FCONST_0, OpcodeGroup.INSN));
169
        OPCODES.put("FCONST_1", new Opcode(FCONST_1, OpcodeGroup.INSN));
170
        OPCODES.put("FCONST_2", new Opcode(FCONST_2, OpcodeGroup.INSN));
171
        OPCODES.put("DCONST_0", new Opcode(DCONST_0, OpcodeGroup.INSN));
172
        OPCODES.put("DCONST_1", new Opcode(DCONST_1, OpcodeGroup.INSN));
173
        OPCODES.put("BIPUSH", new Opcode(BIPUSH, OpcodeGroup.INSN_INT));
174
        OPCODES.put("SIPUSH", new Opcode(SIPUSH, OpcodeGroup.INSN_INT));
175
        OPCODES.put("LDC", new Opcode(LDC, OpcodeGroup.INSN_LDC));
176
        OPCODES.put("ILOAD", new Opcode(ILOAD, OpcodeGroup.INSN_VAR));
177
        OPCODES.put("LLOAD", new Opcode(LLOAD, OpcodeGroup.INSN_VAR));
178
        OPCODES.put("FLOAD", new Opcode(FLOAD, OpcodeGroup.INSN_VAR));
179
        OPCODES.put("DLOAD", new Opcode(DLOAD, OpcodeGroup.INSN_VAR));
180
        OPCODES.put("ALOAD", new Opcode(ALOAD, OpcodeGroup.INSN_VAR));
181
        OPCODES.put("IALOAD", new Opcode(IALOAD, OpcodeGroup.INSN));
182
        OPCODES.put("LALOAD", new Opcode(LALOAD, OpcodeGroup.INSN));
183
        OPCODES.put("FALOAD", new Opcode(FALOAD, OpcodeGroup.INSN));
184
        OPCODES.put("DALOAD", new Opcode(DALOAD, OpcodeGroup.INSN));
185
        OPCODES.put("AALOAD", new Opcode(AALOAD, OpcodeGroup.INSN));
186
        OPCODES.put("BALOAD", new Opcode(BALOAD, OpcodeGroup.INSN));
187
        OPCODES.put("CALOAD", new Opcode(CALOAD, OpcodeGroup.INSN));
188
        OPCODES.put("SALOAD", new Opcode(SALOAD, OpcodeGroup.INSN));
189
        OPCODES.put("ISTORE", new Opcode(ISTORE, OpcodeGroup.INSN_VAR));
190
        OPCODES.put("LSTORE", new Opcode(LSTORE, OpcodeGroup.INSN_VAR));
191
        OPCODES.put("FSTORE", new Opcode(FSTORE, OpcodeGroup.INSN_VAR));
192
        OPCODES.put("DSTORE", new Opcode(DSTORE, OpcodeGroup.INSN_VAR));
193
        OPCODES.put("ASTORE", new Opcode(ASTORE, OpcodeGroup.INSN_VAR));
194
        OPCODES.put("IASTORE", new Opcode(IASTORE, OpcodeGroup.INSN));
195
        OPCODES.put("LASTORE", new Opcode(LASTORE, OpcodeGroup.INSN));
196
        OPCODES.put("FASTORE", new Opcode(FASTORE, OpcodeGroup.INSN));
197
        OPCODES.put("DASTORE", new Opcode(DASTORE, OpcodeGroup.INSN));
198
        OPCODES.put("AASTORE", new Opcode(AASTORE, OpcodeGroup.INSN));
199
        OPCODES.put("BASTORE", new Opcode(BASTORE, OpcodeGroup.INSN));
200
        OPCODES.put("CASTORE", new Opcode(CASTORE, OpcodeGroup.INSN));
201
        OPCODES.put("SASTORE", new Opcode(SASTORE, OpcodeGroup.INSN));
202
        OPCODES.put("POP", new Opcode(POP, OpcodeGroup.INSN));
203
        OPCODES.put("POP2", new Opcode(POP2, OpcodeGroup.INSN));
204
        OPCODES.put("DUP", new Opcode(DUP, OpcodeGroup.INSN));
205
        OPCODES.put("DUP_X1", new Opcode(DUP_X1, OpcodeGroup.INSN));
206
        OPCODES.put("DUP_X2", new Opcode(DUP_X2, OpcodeGroup.INSN));
207
        OPCODES.put("DUP2", new Opcode(DUP2, OpcodeGroup.INSN));
208
        OPCODES.put("DUP2_X1", new Opcode(DUP2_X1, OpcodeGroup.INSN));
209
        OPCODES.put("DUP2_X2", new Opcode(DUP2_X2, OpcodeGroup.INSN));
210
        OPCODES.put("SWAP", new Opcode(SWAP, OpcodeGroup.INSN));
211
        OPCODES.put("IADD", new Opcode(IADD, OpcodeGroup.INSN));
212
        OPCODES.put("LADD", new Opcode(LADD, OpcodeGroup.INSN));
213
        OPCODES.put("FADD", new Opcode(FADD, OpcodeGroup.INSN));
214
        OPCODES.put("DADD", new Opcode(DADD, OpcodeGroup.INSN));
215
        OPCODES.put("ISUB", new Opcode(ISUB, OpcodeGroup.INSN));
216
        OPCODES.put("LSUB", new Opcode(LSUB, OpcodeGroup.INSN));
217
        OPCODES.put("FSUB", new Opcode(FSUB, OpcodeGroup.INSN));
218
        OPCODES.put("DSUB", new Opcode(DSUB, OpcodeGroup.INSN));
219
        OPCODES.put("IMUL", new Opcode(IMUL, OpcodeGroup.INSN));
220
        OPCODES.put("LMUL", new Opcode(LMUL, OpcodeGroup.INSN));
221
        OPCODES.put("FMUL", new Opcode(FMUL, OpcodeGroup.INSN));
222
        OPCODES.put("DMUL", new Opcode(DMUL, OpcodeGroup.INSN));
223
        OPCODES.put("IDIV", new Opcode(IDIV, OpcodeGroup.INSN));
224
        OPCODES.put("LDIV", new Opcode(LDIV, OpcodeGroup.INSN));
225
        OPCODES.put("FDIV", new Opcode(FDIV, OpcodeGroup.INSN));
226
        OPCODES.put("DDIV", new Opcode(DDIV, OpcodeGroup.INSN));
227
        OPCODES.put("IREM", new Opcode(IREM, OpcodeGroup.INSN));
228
        OPCODES.put("LREM", new Opcode(LREM, OpcodeGroup.INSN));
229
        OPCODES.put("FREM", new Opcode(FREM, OpcodeGroup.INSN));
230
        OPCODES.put("DREM", new Opcode(DREM, OpcodeGroup.INSN));
231
        OPCODES.put("INEG", new Opcode(INEG, OpcodeGroup.INSN));
232
        OPCODES.put("LNEG", new Opcode(LNEG, OpcodeGroup.INSN));
233
        OPCODES.put("FNEG", new Opcode(FNEG, OpcodeGroup.INSN));
234
        OPCODES.put("DNEG", new Opcode(DNEG, OpcodeGroup.INSN));
235
        OPCODES.put("ISHL", new Opcode(ISHL, OpcodeGroup.INSN));
236
        OPCODES.put("LSHL", new Opcode(LSHL, OpcodeGroup.INSN));
237
        OPCODES.put("ISHR", new Opcode(ISHR, OpcodeGroup.INSN));
238
        OPCODES.put("LSHR", new Opcode(LSHR, OpcodeGroup.INSN));
239
        OPCODES.put("IUSHR", new Opcode(IUSHR, OpcodeGroup.INSN));
240
        OPCODES.put("LUSHR", new Opcode(LUSHR, OpcodeGroup.INSN));
241
        OPCODES.put("IAND", new Opcode(IAND, OpcodeGroup.INSN));
242
        OPCODES.put("LAND", new Opcode(LAND, OpcodeGroup.INSN));
243
        OPCODES.put("IOR", new Opcode(IOR, OpcodeGroup.INSN));
244
        OPCODES.put("LOR", new Opcode(LOR, OpcodeGroup.INSN));
245
        OPCODES.put("IXOR", new Opcode(IXOR, OpcodeGroup.INSN));
246
        OPCODES.put("LXOR", new Opcode(LXOR, OpcodeGroup.INSN));
247
        OPCODES.put("IINC", new Opcode(IINC, OpcodeGroup.INSN_IINC));
248
        OPCODES.put("I2L", new Opcode(I2L, OpcodeGroup.INSN));
249
        OPCODES.put("I2F", new Opcode(I2F, OpcodeGroup.INSN));
250
        OPCODES.put("I2D", new Opcode(I2D, OpcodeGroup.INSN));
251
        OPCODES.put("L2I", new Opcode(L2I, OpcodeGroup.INSN));
252
        OPCODES.put("L2F", new Opcode(L2F, OpcodeGroup.INSN));
253
        OPCODES.put("L2D", new Opcode(L2D, OpcodeGroup.INSN));
254
        OPCODES.put("F2I", new Opcode(F2I, OpcodeGroup.INSN));
255
        OPCODES.put("F2L", new Opcode(F2L, OpcodeGroup.INSN));
256
        OPCODES.put("F2D", new Opcode(F2D, OpcodeGroup.INSN));
257
        OPCODES.put("D2I", new Opcode(D2I, OpcodeGroup.INSN));
258
        OPCODES.put("D2L", new Opcode(D2L, OpcodeGroup.INSN));
259
        OPCODES.put("D2F", new Opcode(D2F, OpcodeGroup.INSN));
260
        OPCODES.put("I2B", new Opcode(I2B, OpcodeGroup.INSN));
261
        OPCODES.put("I2C", new Opcode(I2C, OpcodeGroup.INSN));
262
        OPCODES.put("I2S", new Opcode(I2S, OpcodeGroup.INSN));
263
        OPCODES.put("LCMP", new Opcode(LCMP, OpcodeGroup.INSN));
264
        OPCODES.put("FCMPL", new Opcode(FCMPL, OpcodeGroup.INSN));
265
        OPCODES.put("FCMPG", new Opcode(FCMPG, OpcodeGroup.INSN));
266
        OPCODES.put("DCMPL", new Opcode(DCMPL, OpcodeGroup.INSN));
267
        OPCODES.put("DCMPG", new Opcode(DCMPG, OpcodeGroup.INSN));
268
        OPCODES.put("IFEQ", new Opcode(IFEQ, OpcodeGroup.INSN_JUMP));
269
        OPCODES.put("IFNE", new Opcode(IFNE, OpcodeGroup.INSN_JUMP));
270
        OPCODES.put("IFLT", new Opcode(IFLT, OpcodeGroup.INSN_JUMP));
271
        OPCODES.put("IFGE", new Opcode(IFGE, OpcodeGroup.INSN_JUMP));
272
        OPCODES.put("IFGT", new Opcode(IFGT, OpcodeGroup.INSN_JUMP));
273
        OPCODES.put("IFLE", new Opcode(IFLE, OpcodeGroup.INSN_JUMP));
274
        OPCODES.put("IF_ICMPEQ", new Opcode(IF_ICMPEQ, OpcodeGroup.INSN_JUMP));
275
        OPCODES.put("IF_ICMPNE", new Opcode(IF_ICMPNE, OpcodeGroup.INSN_JUMP));
276
        OPCODES.put("IF_ICMPLT", new Opcode(IF_ICMPLT, OpcodeGroup.INSN_JUMP));
277
        OPCODES.put("IF_ICMPGE", new Opcode(IF_ICMPGE, OpcodeGroup.INSN_JUMP));
278
        OPCODES.put("IF_ICMPGT", new Opcode(IF_ICMPGT, OpcodeGroup.INSN_JUMP));
279
        OPCODES.put("IF_ICMPLE", new Opcode(IF_ICMPLE, OpcodeGroup.INSN_JUMP));
280
        OPCODES.put("IF_ACMPEQ", new Opcode(IF_ACMPEQ, OpcodeGroup.INSN_JUMP));
281
        OPCODES.put("IF_ACMPNE", new Opcode(IF_ACMPNE, OpcodeGroup.INSN_JUMP));
282
        OPCODES.put("GOTO", new Opcode(GOTO, OpcodeGroup.INSN_JUMP));
283
        OPCODES.put("JSR", new Opcode(JSR, OpcodeGroup.INSN_JUMP));
284
        OPCODES.put("RET", new Opcode(RET, OpcodeGroup.INSN_VAR));
285
        // OPCODES.put( "TABLESWITCH", new Opcode( TABLESWITCH,
286
        // "visiTableSwitchInsn"));
287
        // OPCODES.put( "LOOKUPSWITCH", new Opcode( LOOKUPSWITCH,
288
        // "visitLookupSwitch"));
289
        OPCODES.put("IRETURN", new Opcode(IRETURN, OpcodeGroup.INSN));
290
        OPCODES.put("LRETURN", new Opcode(LRETURN, OpcodeGroup.INSN));
291
        OPCODES.put("FRETURN", new Opcode(FRETURN, OpcodeGroup.INSN));
292
        OPCODES.put("DRETURN", new Opcode(DRETURN, OpcodeGroup.INSN));
293
        OPCODES.put("ARETURN", new Opcode(ARETURN, OpcodeGroup.INSN));
294
        OPCODES.put("RETURN", new Opcode(RETURN, OpcodeGroup.INSN));
295
        OPCODES.put("GETSTATIC", new Opcode(GETSTATIC, OpcodeGroup.INSN_FIELD));
296
        OPCODES.put("PUTSTATIC", new Opcode(PUTSTATIC, OpcodeGroup.INSN_FIELD));
297
        OPCODES.put("GETFIELD", new Opcode(GETFIELD, OpcodeGroup.INSN_FIELD));
298
        OPCODES.put("PUTFIELD", new Opcode(PUTFIELD, OpcodeGroup.INSN_FIELD));
299
        OPCODES.put("INVOKEVIRTUAL", new Opcode(INVOKEVIRTUAL,
300
                OpcodeGroup.INSN_METHOD));
301
        OPCODES.put("INVOKESPECIAL", new Opcode(INVOKESPECIAL,
302
                OpcodeGroup.INSN_METHOD));
303
        OPCODES.put("INVOKESTATIC", new Opcode(INVOKESTATIC,
304
                OpcodeGroup.INSN_METHOD));
305
        OPCODES.put("INVOKEINTERFACE", new Opcode(INVOKEINTERFACE,
306
                OpcodeGroup.INSN_METHOD));
307
        OPCODES.put("NEW", new Opcode(NEW, OpcodeGroup.INSN_TYPE));
308
        OPCODES.put("NEWARRAY", new Opcode(NEWARRAY, OpcodeGroup.INSN_INT));
309
        OPCODES.put("ANEWARRAY", new Opcode(ANEWARRAY, OpcodeGroup.INSN_TYPE));
310
        OPCODES.put("ARRAYLENGTH", new Opcode(ARRAYLENGTH, OpcodeGroup.INSN));
311
        OPCODES.put("ATHROW", new Opcode(ATHROW, OpcodeGroup.INSN));
312
        OPCODES.put("CHECKCAST", new Opcode(CHECKCAST, OpcodeGroup.INSN_TYPE));
313
        OPCODES.put("INSTANCEOF", new Opcode(INSTANCEOF, OpcodeGroup.INSN_TYPE));
314
        OPCODES.put("MONITORENTER", new Opcode(MONITORENTER, OpcodeGroup.INSN));
315
        OPCODES.put("MONITOREXIT", new Opcode(MONITOREXIT, OpcodeGroup.INSN));
316
        OPCODES.put("MULTIANEWARRAY", new Opcode(MULTIANEWARRAY,
317
                OpcodeGroup.INSN_MULTIANEWARRAY));
318
        OPCODES.put("IFNULL", new Opcode(IFNULL, OpcodeGroup.INSN_JUMP));
319
        OPCODES.put("IFNONNULL", new Opcode(IFNONNULL, OpcodeGroup.INSN_JUMP));
320
    }
321
 
322
    /**
323
     * Constructs a new {@link ASMContentHandler ASMContentHandler} object.
324
     *
325
     * @param os output stream to write generated class.
326
     * @param computeMax <tt>true</tt> if the maximum stack size and the
327
     *        maximum number of local variables must be automatically computed.
328
     *        This value is passed to {@link ClassWriter ClassWriter} instance.
329
     */
330
    public ASMContentHandler(OutputStream os, boolean computeMax) {
331
        this.os = os;
332
        this.computeMax = computeMax;
333
    }
334
 
335
    /**
336
     * Returns the bytecode of the class that was build with underneath class
337
     * writer.
338
     *
339
     * @return the bytecode of the class that was build with underneath class
340
     *         writer or null if there are no classwriter created.
341
     */
342
    public byte[] toByteArray() {
343
        return cw == null ? null : cw.toByteArray();
344
    }
345
 
346
    /**
347
     * Process notification of the start of an XML element being reached.
348
     *
349
     * @param ns - The Namespace URI, or the empty string if the element has no
350
     *        Namespace URI or if Namespace processing is not being performed.
351
     * @param localName - The local name (without prefix), or the empty string
352
     *        if Namespace processing is not being performed.
353
     * @param qName - The qualified name (with prefix), or the empty string if
354
     *        qualified names are not available.
355
     * @param list - The attributes attached to the element. If there are no
356
     *        attributes, it shall be an empty Attributes object.
357
     * @exception SAXException if a parsing error is to be reported
358
     */
359
    public final void startElement(
360
        String ns,
361
        String localName,
362
        String qName,
363
        Attributes list) throws SAXException
364
    {
365
        // the actual element name is either in localName or qName, depending
366
        // on whether the parser is namespace aware
367
        String name = localName;
368
        if (name == null || name.length() < 1) {
369
            name = qName;
370
        }
371
 
372
        // Compute the current matching rule
373
        StringBuffer sb = new StringBuffer(match);
374
        if (match.length() > 0) {
375
            sb.append('/');
376
        }
377
        sb.append(name);
378
        match = sb.toString();
379
 
380
        // Fire "begin" events for all relevant rules
381
        Rule r = (Rule) RULES.match(match);
382
        if (r != null)
383
            r.begin(name, list);
384
    }
385
 
386
    /**
387
     * Process notification of the end of an XML element being reached.
388
     *
389
     * @param ns - The Namespace URI, or the empty string if the element has no
390
     *        Namespace URI or if Namespace processing is not being performed.
391
     * @param localName - The local name (without prefix), or the empty string
392
     *        if Namespace processing is not being performed.
393
     * @param qName - The qualified XML 1.0 name (with prefix), or the empty
394
     *        string if qualified names are not available.
395
     *
396
     * @exception SAXException if a parsing error is to be reported
397
     */
398
    public final void endElement(String ns, String localName, String qName)
399
            throws SAXException
400
    {
401
        // the actual element name is either in localName or qName, depending
402
        // on whether the parser is namespace aware
403
        String name = localName;
404
        if (name == null || name.length() < 1) {
405
            name = qName;
406
        }
407
 
408
        // Fire "end" events for all relevant rules in reverse order
409
        Rule r = (Rule) RULES.match(match);
410
        if (r != null)
411
            r.end(name);
412
 
413
        // Recover the previous match expression
414
        int slash = match.lastIndexOf('/');
415
        if (slash >= 0) {
416
            match = match.substring(0, slash);
417
        } else {
418
            match = "";
419
        }
420
    }
421
 
422
    /**
423
     * Process notification of the end of a document and write generated
424
     * bytecode into output stream.
425
     *
426
     * @exception SAXException if parsing or writing error is to be reported.
427
     */
428
    public final void endDocument() throws SAXException {
429
        try {
430
            os.write(cw.toByteArray());
431
        } catch (IOException ex) {
432
            throw new SAXException(ex.toString(), ex);
433
        }
434
    }
435
 
436
    /**
437
     * Return the top object on the stack without removing it. If there are no
438
     * objects on the stack, return <code>null</code>.
439
     *
440
     * @return the top object on the stack without removing it.
441
     */
442
    final Object peek() {
443
        return stack.size() == 0 ? null : stack.get(stack.size() - 1);
444
    }
445
 
446
    /**
447
     * Return the n'th object down the stack, where 0 is the top element and
448
     * [getCount()-1] is the bottom element. If the specified index is out of
449
     * range, return <code>null</code>.
450
     *
451
     * @param n Index of the desired element, where 0 is the top of the stack, 1
452
     *        is the next element down, and so on.
453
     * @return the n'th object down the stack.
454
     */
455
    final Object peek(int n) {
456
        return stack.size() < (n + 1) ? null : stack.get(n);
457
    }
458
 
459
    /**
460
     * Pop the top object off of the stack, and return it. If there are no
461
     * objects on the stack, return <code>null</code>.
462
     *
463
     * @return the top object off of the stack.
464
     */
465
    final Object pop() {
466
        return stack.size() == 0 ? null : stack.remove(stack.size() - 1);
467
    }
468
 
469
    /**
470
     * Push a new object onto the top of the object stack.
471
     *
472
     * @param object The new object
473
     */
474
    final void push(Object object) {
475
        stack.add(object);
476
    }
477
 
478
    private static final class RuleSet {
479
        private Map rules = new HashMap();
480
 
481
        private List lpatterns = new ArrayList();
482
 
483
        private List rpatterns = new ArrayList();
484
 
485
        public void add(String path, Object rule) {
486
            String pattern = path;
487
            if (path.startsWith("*/")) {
488
                pattern = path.substring(1);
489
                lpatterns.add(pattern);
490
            } else if (path.endsWith("/*")) {
491
                pattern = path.substring(0, path.length() - 1);
492
                rpatterns.add(pattern);
493
            }
494
            rules.put(pattern, rule);
495
        }
496
 
497
        public Object match(String path) {
498
            if (rules.containsKey(path)) {
499
                return rules.get(path);
500
            }
501
 
502
            int n = path.lastIndexOf('/');
503
            for (Iterator it = lpatterns.iterator(); it.hasNext();) {
504
                String pattern = (String) it.next();
505
                if (path.substring(n).endsWith(pattern)) {
506
                    return rules.get(pattern);
507
                }
508
            }
509
 
510
            for (Iterator it = rpatterns.iterator(); it.hasNext();) {
511
                String pattern = (String) it.next();
512
                if (path.startsWith(pattern)) {
513
                    return rules.get(pattern);
514
                }
515
            }
516
 
517
            return null;
518
        }
519
 
520
    }
521
 
522
    /**
523
     * Rule
524
     */
525
    protected abstract class Rule {
526
 
527
        public void begin(String name, Attributes attrs) {
528
        }
529
 
530
        public void end(String name) {
531
        }
532
 
533
        protected final Object getValue(String desc, String val) {
534
            Object value = null;
535
            if (val != null) {
536
                if (desc.equals("Ljava/lang/String;")) {
537
                    value = decode(val);
538
                } else if ("Ljava/lang/Integer;".equals(desc)
539
                        || "I".equals(desc) || "S".equals(desc)
540
                        || "B".equals(desc) || "C".equals(desc)
541
                        || desc.equals("Z"))
542
                {
543
                    value = new Integer(val);
544
 
545
                } else if ("Ljava/lang/Short;".equals(desc)) {
546
                    value = new Short(val);
547
 
548
                } else if ("Ljava/lang/Byte;".equals(desc)) {
549
                    value = new Byte(val);
550
 
551
                } else if ("Ljava/lang/Character;".equals(desc)) {
552
                    value = new Character(decode(val).charAt(0));
553
 
554
                } else if ("Ljava/lang/Boolean;".equals(desc)) {
555
                    value = Boolean.valueOf(val);
556
 
557
                    // } else if ("Ljava/lang/Integer;".equals(desc)
558
                    // || desc.equals("I"))
559
                    // {
560
                    // value = new Integer(val);
561
                    // } else if ("Ljava/lang/Character;".equals(desc)
562
                    // || desc.equals("C"))
563
                    // {
564
                    // value = new Character(decode(val).charAt(0));
565
                    // } else if ("Ljava/lang/Short;".equals(desc) ||
566
                    // desc.equals("S"))
567
                    // {
568
                    // value = Short.valueOf(val);
569
                    // } else if ("Ljava/lang/Byte;".equals(desc) ||
570
                    // desc.equals("B"))
571
                    // {
572
                    // value = Byte.valueOf(val);
573
 
574
                } else if ("Ljava/lang/Long;".equals(desc) || desc.equals("J"))
575
                {
576
                    value = new Long(val);
577
                } else if ("Ljava/lang/Float;".equals(desc) || desc.equals("F"))
578
                {
579
                    value = new Float(val);
580
                } else if ("Ljava/lang/Double;".equals(desc)
581
                        || desc.equals("D"))
582
                {
583
                    value = new Double(val);
584
                } else if (Type.getDescriptor(Type.class).equals(desc)) {
585
                    value = Type.getType(val);
586
 
587
                    // } else if ("[I".equals(desc)) {
588
                    // value = new int[0]; // TODO
589
                    // } else if ("[C".equals(desc)) {
590
                    // value = new char[0]; // TODO
591
                    // } else if ("[Z".equals(desc)) {
592
                    // value = new boolean[0]; // TODO
593
                    // } else if ("[S".equals(desc)) {
594
                    // value = new short[0]; // TODO
595
                    // } else if ("[B".equals(desc)) {
596
                    // value = new byte[0]; // TODO
597
                    // } else if ("[J".equals(desc)) {
598
                    // value = new long[0]; // TODO
599
                    // } else if ("[F".equals(desc)) {
600
                    // value = new float[0]; // TODO
601
                    // } else if ("[D".equals(desc)) {
602
                    // value = new double[0]; // TODO
603
 
604
                } else {
605
                    throw new RuntimeException("Invalid value:" + val
606
                            + " desc:" + desc + " ctx:" + this);
607
                }
608
            }
609
            return value;
610
        }
611
 
612
        private final String decode(String val) {
613
            StringBuffer sb = new StringBuffer(val.length());
614
            try {
615
                int n = 0;
616
                while (n < val.length()) {
617
                    char c = val.charAt(n);
618
                    if (c == '\\') {
619
                        n++;
620
                        c = val.charAt(n);
621
                        if (c == '\\') {
622
                            sb.append('\\');
623
                        } else {
624
                            n++; // skip 'u'
625
                            sb.append((char) Integer.parseInt(val.substring(n,
626
                                    n + 4), 16));
627
                            n += 3;
628
                        }
629
                    } else {
630
                        sb.append(c);
631
                    }
632
                    n++;
633
                }
634
 
635
            } catch (RuntimeException ex) {
636
                System.err.println(val + "\n" + ex.toString());
637
                ex.printStackTrace();
638
                throw ex;
639
            }
640
            return sb.toString();
641
        }
642
 
643
        protected final Label getLabel(Object label) {
644
            Label lbl = (Label) labels.get(label);
645
            if (lbl == null) {
646
                lbl = new Label();
647
                labels.put(label, lbl);
648
            }
649
            return lbl;
650
        }
651
 
652
        // TODO verify move to stack
653
        protected final MethodVisitor getCodeVisitor() {
654
            return (MethodVisitor) peek();
655
        }
656
 
657
        protected final int getAccess(String s) {
658
            int access = 0;
659
            if (s.indexOf("public") != -1)
660
                access |= Opcodes.ACC_PUBLIC;
661
            if (s.indexOf("private") != -1)
662
                access |= Opcodes.ACC_PRIVATE;
663
            if (s.indexOf("protected") != -1)
664
                access |= Opcodes.ACC_PROTECTED;
665
            if (s.indexOf("static") != -1)
666
                access |= Opcodes.ACC_STATIC;
667
            if (s.indexOf("final") != -1)
668
                access |= Opcodes.ACC_FINAL;
669
            if (s.indexOf("super") != -1)
670
                access |= Opcodes.ACC_SUPER;
671
            if (s.indexOf("synchronized") != -1)
672
                access |= Opcodes.ACC_SYNCHRONIZED;
673
            if (s.indexOf("volatile") != -1)
674
                access |= Opcodes.ACC_VOLATILE;
675
            if (s.indexOf("bridge") != -1)
676
                access |= Opcodes.ACC_BRIDGE;
677
            if (s.indexOf("varargs") != -1)
678
                access |= Opcodes.ACC_VARARGS;
679
            if (s.indexOf("transient") != -1)
680
                access |= Opcodes.ACC_TRANSIENT;
681
            if (s.indexOf("native") != -1)
682
                access |= Opcodes.ACC_NATIVE;
683
            if (s.indexOf("interface") != -1)
684
                access |= Opcodes.ACC_INTERFACE;
685
            if (s.indexOf("abstract") != -1)
686
                access |= Opcodes.ACC_ABSTRACT;
687
            if (s.indexOf("strict") != -1)
688
                access |= Opcodes.ACC_STRICT;
689
            if (s.indexOf("synthetic") != -1)
690
                access |= Opcodes.ACC_SYNTHETIC;
691
            if (s.indexOf("annotation") != -1)
692
                access |= Opcodes.ACC_ANNOTATION;
693
            if (s.indexOf("enum") != -1)
694
                access |= Opcodes.ACC_ENUM;
695
            if (s.indexOf("deprecated") != -1)
696
                access |= Opcodes.ACC_DEPRECATED;
697
            return access;
698
        }
699
 
700
    }
701
 
702
    /**
703
     * ClassRule
704
     */
705
    private final class ClassRule extends Rule {
706
 
707
        public final void begin(String name, Attributes attrs) {
708
            int major = Integer.parseInt(attrs.getValue("major"));
709
            int minor = Integer.parseInt(attrs.getValue("minor"));
710
            cw = new ClassWriter(computeMax);
711
            Map vals = new HashMap();
712
            vals.put("version", new Integer(minor << 16 | major));
713
            vals.put("access", attrs.getValue("access"));
714
            vals.put("name", attrs.getValue("name"));
715
            vals.put("parent", attrs.getValue("parent"));
716
            vals.put("source", attrs.getValue("source"));
717
            vals.put("signature", attrs.getValue("signature"));
718
            vals.put("interfaces", new ArrayList());
719
            push(vals);
720
            // values will be extracted in InterfacesRule.end();
721
        }
722
 
723
    }
724
 
725
    private final class SourceRule extends Rule {
726
 
727
        public void begin(String name, Attributes attrs) {
728
            String file = attrs.getValue("file");
729
            String debug = attrs.getValue("debug");
730
            cw.visitSource(file, debug);
731
        }
732
 
733
    }
734
 
735
    /**
736
     * InterfaceRule
737
     */
738
    private final class InterfaceRule extends Rule {
739
 
740
        public final void begin(String name, Attributes attrs) {
741
            ((List) ((Map) peek()).get("interfaces")).add(attrs.getValue("name"));
742
        }
743
 
744
    }
745
 
746
    /**
747
     * InterfacesRule
748
     */
749
    private final class InterfacesRule extends Rule {
750
 
751
        public final void end(String element) {
752
            Map vals = (Map) pop();
753
            int version = ((Integer) vals.get("version")).intValue();
754
            int access = getAccess((String) vals.get("access"));
755
            String name = (String) vals.get("name");
756
            String signature = (String) vals.get("signature");
757
            String parent = (String) vals.get("parent");
758
            List infs = (List) vals.get("interfaces");
759
            String[] interfaces = (String[]) infs.toArray(new String[infs.size()]);
760
            cw.visit(version, access, name, signature, parent, interfaces);
761
            push(cw);
762
        }
763
 
764
    }
765
 
766
    /**
767
     * OuterClassRule
768
     */
769
    private final class OuterClassRule extends Rule {
770
 
771
        public final void begin(String element, Attributes attrs) {
772
            String owner = attrs.getValue("owner");
773
            String name = attrs.getValue("name");
774
            String desc = attrs.getValue("desc");
775
            cw.visitOuterClass(owner, name, desc);
776
        }
777
 
778
    }
779
 
780
    /**
781
     * InnerClassRule
782
     */
783
    private final class InnerClassRule extends Rule {
784
 
785
        public final void begin(String element, Attributes attrs) {
786
            int access = getAccess(attrs.getValue("access"));
787
            String name = attrs.getValue("name");
788
            String outerName = attrs.getValue("outerName");
789
            String innerName = attrs.getValue("innerName");
790
            cw.visitInnerClass(name, outerName, innerName, access);
791
        }
792
 
793
    }
794
 
795
    /**
796
     * FieldRule
797
     */
798
    private final class FieldRule extends Rule {
799
 
800
        public final void begin(String element, Attributes attrs) {
801
            int access = getAccess(attrs.getValue("access"));
802
            String name = attrs.getValue("name");
803
            String signature = attrs.getValue("signature");
804
            String desc = attrs.getValue("desc");
805
            Object value = getValue(desc, attrs.getValue("value"));
806
            push(cw.visitField(access, name, desc, signature, value));
807
        }
808
 
809
        public void end(String name) {
810
            ((FieldVisitor) pop()).visitEnd();
811
        }
812
 
813
    }
814
 
815
    /**
816
     * MethodRule
817
     */
818
    private final class MethodRule extends Rule {
819
 
820
        public final void begin(String name, Attributes attrs) {
821
            labels = new HashMap();
822
            Map vals = new HashMap();
823
            vals.put("access", attrs.getValue("access"));
824
            vals.put("name", attrs.getValue("name"));
825
            vals.put("desc", attrs.getValue("desc"));
826
            vals.put("signature", attrs.getValue("signature"));
827
            vals.put("exceptions", new ArrayList());
828
            push(vals);
829
            // values will be extracted in ExceptionsRule.end();
830
        }
831
 
832
        public final void end(String name) {
833
            ((MethodVisitor) pop()).visitEnd();
834
            labels = null;
835
        }
836
 
837
    }
838
 
839
    /**
840
     * ExceptionRule
841
     */
842
    private final class ExceptionRule extends Rule {
843
 
844
        public final void begin(String name, Attributes attrs) {
845
            ((List) ((Map) peek()).get("exceptions")).add(attrs.getValue("name"));
846
        }
847
 
848
    }
849
 
850
    /**
851
     * ExceptionsRule
852
     */
853
    private final class ExceptionsRule extends Rule {
854
 
855
        public final void end(String element) {
856
            Map vals = (Map) pop();
857
            int access = getAccess((String) vals.get("access"));
858
            String name = (String) vals.get("name");
859
            String desc = (String) vals.get("desc");
860
            String signature = (String) vals.get("signature");
861
            List excs = (List) vals.get("exceptions");
862
            String[] exceptions = (String[]) excs.toArray(new String[excs.size()]);
863
 
864
            push(cw.visitMethod(access, name, desc, signature, exceptions));
865
        }
866
 
867
    }
868
 
869
    /**
870
     * TableSwitchRule
871
     */
872
    private class TableSwitchRule extends Rule {
873
 
874
        public final void begin(String name, Attributes attrs) {
875
            Map vals = new HashMap();
876
            vals.put("min", attrs.getValue("min"));
877
            vals.put("max", attrs.getValue("max"));
878
            vals.put("dflt", attrs.getValue("dflt"));
879
            vals.put("labels", new ArrayList());
880
            push(vals);
881
        }
882
 
883
        public final void end(String name) {
884
            Map vals = (Map) pop();
885
            int min = Integer.parseInt((String) vals.get("min"));
886
            int max = Integer.parseInt((String) vals.get("max"));
887
            Label dflt = getLabel(vals.get("dflt"));
888
            List lbls = (List) vals.get("labels");
889
            Label[] labels = (Label[]) lbls.toArray(new Label[lbls.size()]);
890
            getCodeVisitor().visitTableSwitchInsn(min, max, dflt, labels);
891
        }
892
 
893
    }
894
 
895
    /**
896
     * TableSwitchLabelRule
897
     */
898
    private final class TableSwitchLabelRule extends Rule {
899
 
900
        public final void begin(String name, Attributes attrs) {
901
            ((List) ((Map) peek()).get("labels")).add(getLabel(attrs.getValue("name")));
902
        }
903
 
904
    }
905
 
906
    /**
907
     * LookupSwitchRule
908
     */
909
    private final class LookupSwitchRule extends Rule {
910
 
911
        public final void begin(String name, Attributes attrs) {
912
            Map vals = new HashMap();
913
            vals.put("dflt", attrs.getValue("dflt"));
914
            vals.put("labels", new ArrayList());
915
            vals.put("keys", new ArrayList());
916
            push(vals);
917
        }
918
 
919
        public final void end(String name) {
920
            Map vals = (Map) pop();
921
            Label dflt = getLabel(vals.get("dflt"));
922
            List keyList = (List) vals.get("keys");
923
            List lbls = (List) vals.get("labels");
924
            Label[] labels = (Label[]) lbls.toArray(new Label[lbls.size()]);
925
            int[] keys = new int[keyList.size()];
926
            for (int i = 0; i < keys.length; i++) {
927
                keys[i] = Integer.parseInt((String) keyList.get(i));
928
            }
929
            getCodeVisitor().visitLookupSwitchInsn(dflt, keys, labels);
930
        }
931
 
932
    }
933
 
934
    /**
935
     * LookupSwitchLabelRule
936
     */
937
    private final class LookupSwitchLabelRule extends Rule {
938
 
939
        public final void begin(String name, Attributes attrs) {
940
            Map vals = (Map) peek();
941
            ((List) vals.get("labels")).add(getLabel(attrs.getValue("name")));
942
            ((List) vals.get("keys")).add(attrs.getValue("key"));
943
        }
944
 
945
    }
946
 
947
    /**
948
     * LabelRule
949
     */
950
    private final class LabelRule extends Rule {
951
 
952
        public final void begin(String name, Attributes attrs) {
953
            getCodeVisitor().visitLabel(getLabel(attrs.getValue("name")));
954
        }
955
 
956
    }
957
 
958
    /**
959
     * TryCatchRule
960
     */
961
    private final class TryCatchRule extends Rule {
962
 
963
        public final void begin(String name, Attributes attrs) {
964
            Label start = getLabel(attrs.getValue("start"));
965
            Label end = getLabel(attrs.getValue("end"));
966
            Label handler = getLabel(attrs.getValue("handler"));
967
            String type = attrs.getValue("type");
968
            getCodeVisitor().visitTryCatchBlock(start, end, handler, type);
969
        }
970
 
971
    }
972
 
973
    /**
974
     * LineNumberRule
975
     */
976
    private final class LineNumberRule extends Rule {
977
 
978
        public final void begin(String name, Attributes attrs) {
979
            int line = Integer.parseInt(attrs.getValue("line"));
980
            Label start = getLabel(attrs.getValue("start"));
981
            getCodeVisitor().visitLineNumber(line, start);
982
        }
983
 
984
    }
985
 
986
    /**
987
     * LocalVarRule
988
     */
989
    private final class LocalVarRule extends Rule {
990
 
991
        public final void begin(String element, Attributes attrs) {
992
            String name = attrs.getValue("name");
993
            String desc = attrs.getValue("desc");
994
            String signature = attrs.getValue("signature");
995
            Label start = getLabel(attrs.getValue("start"));
996
            Label end = getLabel(attrs.getValue("end"));
997
            int var = Integer.parseInt(attrs.getValue("var"));
998
            getCodeVisitor().visitLocalVariable(name,
999
                    desc,
1000
                    signature,
1001
                    start,
1002
                    end,
1003
                    var);
1004
        }
1005
 
1006
    }
1007
 
1008
    /**
1009
     * OpcodesRule
1010
     */
1011
    private final class OpcodesRule extends Rule {
1012
 
1013
        // public boolean match( String match, String element) {
1014
        // return match.startsWith( path) && OPCODES.containsKey( element);
1015
        // }
1016
 
1017
        public final void begin(String element, Attributes attrs) {
1018
            Opcode o = ((Opcode) OPCODES.get(element));
1019
            if (o == null)
1020
                return;
1021
 
1022
            switch (o.type) {
1023
                case OpcodeGroup.INSN:
1024
                    getCodeVisitor().visitInsn(o.opcode);
1025
                    break;
1026
 
1027
                case OpcodeGroup.INSN_FIELD:
1028
                    getCodeVisitor().visitFieldInsn(o.opcode,
1029
                            attrs.getValue("owner"),
1030
                            attrs.getValue("name"),
1031
                            attrs.getValue("desc"));
1032
                    break;
1033
 
1034
                case OpcodeGroup.INSN_INT:
1035
                    getCodeVisitor().visitIntInsn(o.opcode,
1036
                            Integer.parseInt(attrs.getValue("value")));
1037
                    break;
1038
 
1039
                case OpcodeGroup.INSN_JUMP:
1040
                    getCodeVisitor().visitJumpInsn(o.opcode,
1041
                            getLabel(attrs.getValue("label")));
1042
                    break;
1043
 
1044
                case OpcodeGroup.INSN_METHOD:
1045
                    getCodeVisitor().visitMethodInsn(o.opcode,
1046
                            attrs.getValue("owner"),
1047
                            attrs.getValue("name"),
1048
                            attrs.getValue("desc"));
1049
                    break;
1050
 
1051
                case OpcodeGroup.INSN_TYPE:
1052
                    getCodeVisitor().visitTypeInsn(o.opcode,
1053
                            attrs.getValue("desc"));
1054
                    break;
1055
 
1056
                case OpcodeGroup.INSN_VAR:
1057
                    getCodeVisitor().visitVarInsn(o.opcode,
1058
                            Integer.parseInt(attrs.getValue("var")));
1059
                    break;
1060
 
1061
                case OpcodeGroup.INSN_IINC:
1062
                    getCodeVisitor().visitIincInsn(Integer.parseInt(attrs.getValue("var")),
1063
                            Integer.parseInt(attrs.getValue("inc")));
1064
                    break;
1065
 
1066
                case OpcodeGroup.INSN_LDC:
1067
                    getCodeVisitor().visitLdcInsn(getValue(attrs.getValue("desc"),
1068
                            attrs.getValue("cst")));
1069
                    break;
1070
 
1071
                case OpcodeGroup.INSN_MULTIANEWARRAY:
1072
                    getCodeVisitor().visitMultiANewArrayInsn(attrs.getValue("desc"),
1073
                            Integer.parseInt(attrs.getValue("dims")));
1074
                    break;
1075
 
1076
                default:
1077
                    throw new RuntimeException("Invalid element: " + element
1078
                            + " at " + match);
1079
 
1080
            }
1081
        }
1082
    }
1083
 
1084
    /**
1085
     * MaxRule
1086
     */
1087
    private final class MaxRule extends Rule {
1088
 
1089
        public final void begin(String element, Attributes attrs) {
1090
            int maxStack = Integer.parseInt(attrs.getValue("maxStack"));
1091
            int maxLocals = Integer.parseInt(attrs.getValue("maxLocals"));
1092
            getCodeVisitor().visitMaxs(maxStack, maxLocals);
1093
        }
1094
 
1095
    }
1096
 
1097
    private final class AnnotationRule extends Rule {
1098
 
1099
        public void begin(String name, Attributes attrs) {
1100
            String desc = attrs.getValue("desc");
1101
            boolean visible = Boolean.valueOf(attrs.getValue("visible"))
1102
                    .booleanValue();
1103
 
1104
            Object v = peek();
1105
            if (v instanceof ClassVisitor) {
1106
                push(((ClassVisitor) v).visitAnnotation(desc, visible));
1107
            } else if (v instanceof FieldVisitor) {
1108
                push(((FieldVisitor) v).visitAnnotation(desc, visible));
1109
            } else if (v instanceof MethodVisitor) {
1110
                push(((MethodVisitor) v).visitAnnotation(desc, visible));
1111
            }
1112
        }
1113
 
1114
        public void end(String name) {
1115
            ((AnnotationVisitor) pop()).visitEnd();
1116
        }
1117
 
1118
    }
1119
 
1120
    private final class AnnotationParameterRule extends Rule {
1121
 
1122
        public void begin(String name, Attributes attrs) {
1123
            int parameter = Integer.parseInt(attrs.getValue("parameter"));
1124
            String desc = attrs.getValue("desc");
1125
            boolean visible = Boolean.valueOf(attrs.getValue("visible"))
1126
                    .booleanValue();
1127
 
1128
            push(((MethodVisitor) peek()).visitParameterAnnotation(parameter,
1129
                    desc,
1130
                    visible));
1131
        }
1132
 
1133
        public void end(String name) {
1134
            ((AnnotationVisitor) pop()).visitEnd();
1135
        }
1136
 
1137
    }
1138
 
1139
    private final class AnnotationValueRule extends Rule {
1140
 
1141
        public void begin(String nm, Attributes attrs) {
1142
            String name = attrs.getValue("name");
1143
            String desc = attrs.getValue("desc");
1144
            String value = attrs.getValue("value");
1145
            ((AnnotationVisitor) peek()).visit(name, getValue(desc, value));
1146
        }
1147
 
1148
    }
1149
 
1150
    private final class AnnotationValueEnumRule extends Rule {
1151
 
1152
        public void begin(String nm, Attributes attrs) {
1153
            String name = attrs.getValue("name");
1154
            String desc = attrs.getValue("desc");
1155
            String value = attrs.getValue("value");
1156
            ((AnnotationVisitor) peek()).visitEnum(name, desc, value);
1157
        }
1158
 
1159
    }
1160
 
1161
    private final class AnnotationValueAnnotationRule extends Rule {
1162
 
1163
        public void begin(String nm, Attributes attrs) {
1164
            String name = attrs.getValue("name");
1165
            String desc = attrs.getValue("desc");
1166
            push(((AnnotationVisitor) peek()).visitAnnotation(name, desc));
1167
        }
1168
 
1169
        public void end(String name) {
1170
            ((AnnotationVisitor) pop()).visitEnd();
1171
        }
1172
 
1173
    }
1174
 
1175
    private final class AnnotationValueArrayRule extends Rule {
1176
 
1177
        public void begin(String nm, Attributes attrs) {
1178
            String name = attrs.getValue("name");
1179
            push(((AnnotationVisitor) peek()).visitArray(name));
1180
        }
1181
 
1182
        public void end(String name) {
1183
            ((AnnotationVisitor) pop()).visitEnd();
1184
        }
1185
 
1186
    }
1187
 
1188
    private final class AnnotationDefaultRule extends Rule {
1189
 
1190
        public void begin(String nm, Attributes attrs) {
1191
            push(((MethodVisitor) peek()).visitAnnotationDefault());
1192
        }
1193
 
1194
        public void end(String name) {
1195
            ((AnnotationVisitor) pop()).visitEnd();
1196
        }
1197
 
1198
    }
1199
 
1200
    /**
1201
     * Opcode
1202
     */
1203
    private final static class Opcode {
1204
        public int opcode;
1205
 
1206
        public int type;
1207
 
1208
        public Opcode(int opcode, int type) {
1209
            this.opcode = opcode;
1210
            this.type = type;
1211
        }
1212
 
1213
    }
1214
 
1215
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.