Mercurial > hg > truffle
comparison graal/com.oracle.max.cri/src/com/sun/cri/bytecode/Bytecodes.java @ 3733:e233f5660da4
Added Java files from Maxine project.
author | Thomas Wuerthinger <thomas.wuerthinger@oracle.com> |
---|---|
date | Sat, 17 Dec 2011 19:59:18 +0100 |
parents | |
children | bc8527f3071c |
comparison
equal
deleted
inserted
replaced
3732:3e2e8b8abdaf | 3733:e233f5660da4 |
---|---|
1 /* | |
2 * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. | |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
20 * or visit www.oracle.com if you need additional information or have any | |
21 * questions. | |
22 */ | |
23 package com.sun.cri.bytecode; | |
24 | |
25 import static com.sun.cri.bytecode.Bytecodes.Flags.*; | |
26 | |
27 import java.io.*; | |
28 import java.lang.reflect.*; | |
29 import java.util.regex.*; | |
30 | |
31 /** | |
32 * The definitions of the bytecodes that are valid input to the compiler and | |
33 * related utility methods. This comprises two groups: the standard Java | |
34 * bytecodes defined by <a href= | |
35 * "http://java.sun.com/docs/books/jvms/second_edition/html/VMSpecTOC.doc.html"> | |
36 * Java Virtual Machine Specification</a>, and a set of <i>extended</i> | |
37 * bytecodes that support low-level programming, for example, memory barriers. | |
38 * | |
39 * The extended bytecodes are one or three bytes in size. The one-byte bytecodes | |
40 * follow the values in the standard set, with no gap. The three-byte extended | |
41 * bytecodes share a common first byte and carry additional instruction-specific | |
42 * information in the second and third bytes. | |
43 */ | |
44 public class Bytecodes { | |
45 public static final int NOP = 0; // 0x00 | |
46 public static final int ACONST_NULL = 1; // 0x01 | |
47 public static final int ICONST_M1 = 2; // 0x02 | |
48 public static final int ICONST_0 = 3; // 0x03 | |
49 public static final int ICONST_1 = 4; // 0x04 | |
50 public static final int ICONST_2 = 5; // 0x05 | |
51 public static final int ICONST_3 = 6; // 0x06 | |
52 public static final int ICONST_4 = 7; // 0x07 | |
53 public static final int ICONST_5 = 8; // 0x08 | |
54 public static final int LCONST_0 = 9; // 0x09 | |
55 public static final int LCONST_1 = 10; // 0x0A | |
56 public static final int FCONST_0 = 11; // 0x0B | |
57 public static final int FCONST_1 = 12; // 0x0C | |
58 public static final int FCONST_2 = 13; // 0x0D | |
59 public static final int DCONST_0 = 14; // 0x0E | |
60 public static final int DCONST_1 = 15; // 0x0F | |
61 public static final int BIPUSH = 16; // 0x10 | |
62 public static final int SIPUSH = 17; // 0x11 | |
63 public static final int LDC = 18; // 0x12 | |
64 public static final int LDC_W = 19; // 0x13 | |
65 public static final int LDC2_W = 20; // 0x14 | |
66 public static final int ILOAD = 21; // 0x15 | |
67 public static final int LLOAD = 22; // 0x16 | |
68 public static final int FLOAD = 23; // 0x17 | |
69 public static final int DLOAD = 24; // 0x18 | |
70 public static final int ALOAD = 25; // 0x19 | |
71 public static final int ILOAD_0 = 26; // 0x1A | |
72 public static final int ILOAD_1 = 27; // 0x1B | |
73 public static final int ILOAD_2 = 28; // 0x1C | |
74 public static final int ILOAD_3 = 29; // 0x1D | |
75 public static final int LLOAD_0 = 30; // 0x1E | |
76 public static final int LLOAD_1 = 31; // 0x1F | |
77 public static final int LLOAD_2 = 32; // 0x20 | |
78 public static final int LLOAD_3 = 33; // 0x21 | |
79 public static final int FLOAD_0 = 34; // 0x22 | |
80 public static final int FLOAD_1 = 35; // 0x23 | |
81 public static final int FLOAD_2 = 36; // 0x24 | |
82 public static final int FLOAD_3 = 37; // 0x25 | |
83 public static final int DLOAD_0 = 38; // 0x26 | |
84 public static final int DLOAD_1 = 39; // 0x27 | |
85 public static final int DLOAD_2 = 40; // 0x28 | |
86 public static final int DLOAD_3 = 41; // 0x29 | |
87 public static final int ALOAD_0 = 42; // 0x2A | |
88 public static final int ALOAD_1 = 43; // 0x2B | |
89 public static final int ALOAD_2 = 44; // 0x2C | |
90 public static final int ALOAD_3 = 45; // 0x2D | |
91 public static final int IALOAD = 46; // 0x2E | |
92 public static final int LALOAD = 47; // 0x2F | |
93 public static final int FALOAD = 48; // 0x30 | |
94 public static final int DALOAD = 49; // 0x31 | |
95 public static final int AALOAD = 50; // 0x32 | |
96 public static final int BALOAD = 51; // 0x33 | |
97 public static final int CALOAD = 52; // 0x34 | |
98 public static final int SALOAD = 53; // 0x35 | |
99 public static final int ISTORE = 54; // 0x36 | |
100 public static final int LSTORE = 55; // 0x37 | |
101 public static final int FSTORE = 56; // 0x38 | |
102 public static final int DSTORE = 57; // 0x39 | |
103 public static final int ASTORE = 58; // 0x3A | |
104 public static final int ISTORE_0 = 59; // 0x3B | |
105 public static final int ISTORE_1 = 60; // 0x3C | |
106 public static final int ISTORE_2 = 61; // 0x3D | |
107 public static final int ISTORE_3 = 62; // 0x3E | |
108 public static final int LSTORE_0 = 63; // 0x3F | |
109 public static final int LSTORE_1 = 64; // 0x40 | |
110 public static final int LSTORE_2 = 65; // 0x41 | |
111 public static final int LSTORE_3 = 66; // 0x42 | |
112 public static final int FSTORE_0 = 67; // 0x43 | |
113 public static final int FSTORE_1 = 68; // 0x44 | |
114 public static final int FSTORE_2 = 69; // 0x45 | |
115 public static final int FSTORE_3 = 70; // 0x46 | |
116 public static final int DSTORE_0 = 71; // 0x47 | |
117 public static final int DSTORE_1 = 72; // 0x48 | |
118 public static final int DSTORE_2 = 73; // 0x49 | |
119 public static final int DSTORE_3 = 74; // 0x4A | |
120 public static final int ASTORE_0 = 75; // 0x4B | |
121 public static final int ASTORE_1 = 76; // 0x4C | |
122 public static final int ASTORE_2 = 77; // 0x4D | |
123 public static final int ASTORE_3 = 78; // 0x4E | |
124 public static final int IASTORE = 79; // 0x4F | |
125 public static final int LASTORE = 80; // 0x50 | |
126 public static final int FASTORE = 81; // 0x51 | |
127 public static final int DASTORE = 82; // 0x52 | |
128 public static final int AASTORE = 83; // 0x53 | |
129 public static final int BASTORE = 84; // 0x54 | |
130 public static final int CASTORE = 85; // 0x55 | |
131 public static final int SASTORE = 86; // 0x56 | |
132 public static final int POP = 87; // 0x57 | |
133 public static final int POP2 = 88; // 0x58 | |
134 public static final int DUP = 89; // 0x59 | |
135 public static final int DUP_X1 = 90; // 0x5A | |
136 public static final int DUP_X2 = 91; // 0x5B | |
137 public static final int DUP2 = 92; // 0x5C | |
138 public static final int DUP2_X1 = 93; // 0x5D | |
139 public static final int DUP2_X2 = 94; // 0x5E | |
140 public static final int SWAP = 95; // 0x5F | |
141 public static final int IADD = 96; // 0x60 | |
142 public static final int LADD = 97; // 0x61 | |
143 public static final int FADD = 98; // 0x62 | |
144 public static final int DADD = 99; // 0x63 | |
145 public static final int ISUB = 100; // 0x64 | |
146 public static final int LSUB = 101; // 0x65 | |
147 public static final int FSUB = 102; // 0x66 | |
148 public static final int DSUB = 103; // 0x67 | |
149 public static final int IMUL = 104; // 0x68 | |
150 public static final int LMUL = 105; // 0x69 | |
151 public static final int FMUL = 106; // 0x6A | |
152 public static final int DMUL = 107; // 0x6B | |
153 public static final int IDIV = 108; // 0x6C | |
154 public static final int LDIV = 109; // 0x6D | |
155 public static final int FDIV = 110; // 0x6E | |
156 public static final int DDIV = 111; // 0x6F | |
157 public static final int IREM = 112; // 0x70 | |
158 public static final int LREM = 113; // 0x71 | |
159 public static final int FREM = 114; // 0x72 | |
160 public static final int DREM = 115; // 0x73 | |
161 public static final int INEG = 116; // 0x74 | |
162 public static final int LNEG = 117; // 0x75 | |
163 public static final int FNEG = 118; // 0x76 | |
164 public static final int DNEG = 119; // 0x77 | |
165 public static final int ISHL = 120; // 0x78 | |
166 public static final int LSHL = 121; // 0x79 | |
167 public static final int ISHR = 122; // 0x7A | |
168 public static final int LSHR = 123; // 0x7B | |
169 public static final int IUSHR = 124; // 0x7C | |
170 public static final int LUSHR = 125; // 0x7D | |
171 public static final int IAND = 126; // 0x7E | |
172 public static final int LAND = 127; // 0x7F | |
173 public static final int IOR = 128; // 0x80 | |
174 public static final int LOR = 129; // 0x81 | |
175 public static final int IXOR = 130; // 0x82 | |
176 public static final int LXOR = 131; // 0x83 | |
177 public static final int IINC = 132; // 0x84 | |
178 public static final int I2L = 133; // 0x85 | |
179 public static final int I2F = 134; // 0x86 | |
180 public static final int I2D = 135; // 0x87 | |
181 public static final int L2I = 136; // 0x88 | |
182 public static final int L2F = 137; // 0x89 | |
183 public static final int L2D = 138; // 0x8A | |
184 public static final int F2I = 139; // 0x8B | |
185 public static final int F2L = 140; // 0x8C | |
186 public static final int F2D = 141; // 0x8D | |
187 public static final int D2I = 142; // 0x8E | |
188 public static final int D2L = 143; // 0x8F | |
189 public static final int D2F = 144; // 0x90 | |
190 public static final int I2B = 145; // 0x91 | |
191 public static final int I2C = 146; // 0x92 | |
192 public static final int I2S = 147; // 0x93 | |
193 public static final int LCMP = 148; // 0x94 | |
194 public static final int FCMPL = 149; // 0x95 | |
195 public static final int FCMPG = 150; // 0x96 | |
196 public static final int DCMPL = 151; // 0x97 | |
197 public static final int DCMPG = 152; // 0x98 | |
198 public static final int IFEQ = 153; // 0x99 | |
199 public static final int IFNE = 154; // 0x9A | |
200 public static final int IFLT = 155; // 0x9B | |
201 public static final int IFGE = 156; // 0x9C | |
202 public static final int IFGT = 157; // 0x9D | |
203 public static final int IFLE = 158; // 0x9E | |
204 public static final int IF_ICMPEQ = 159; // 0x9F | |
205 public static final int IF_ICMPNE = 160; // 0xA0 | |
206 public static final int IF_ICMPLT = 161; // 0xA1 | |
207 public static final int IF_ICMPGE = 162; // 0xA2 | |
208 public static final int IF_ICMPGT = 163; // 0xA3 | |
209 public static final int IF_ICMPLE = 164; // 0xA4 | |
210 public static final int IF_ACMPEQ = 165; // 0xA5 | |
211 public static final int IF_ACMPNE = 166; // 0xA6 | |
212 public static final int GOTO = 167; // 0xA7 | |
213 public static final int JSR = 168; // 0xA8 | |
214 public static final int RET = 169; // 0xA9 | |
215 public static final int TABLESWITCH = 170; // 0xAA | |
216 public static final int LOOKUPSWITCH = 171; // 0xAB | |
217 public static final int IRETURN = 172; // 0xAC | |
218 public static final int LRETURN = 173; // 0xAD | |
219 public static final int FRETURN = 174; // 0xAE | |
220 public static final int DRETURN = 175; // 0xAF | |
221 public static final int ARETURN = 176; // 0xB0 | |
222 public static final int RETURN = 177; // 0xB1 | |
223 public static final int GETSTATIC = 178; // 0xB2 | |
224 public static final int PUTSTATIC = 179; // 0xB3 | |
225 public static final int GETFIELD = 180; // 0xB4 | |
226 public static final int PUTFIELD = 181; // 0xB5 | |
227 public static final int INVOKEVIRTUAL = 182; // 0xB6 | |
228 public static final int INVOKESPECIAL = 183; // 0xB7 | |
229 public static final int INVOKESTATIC = 184; // 0xB8 | |
230 public static final int INVOKEINTERFACE = 185; // 0xB9 | |
231 public static final int XXXUNUSEDXXX = 186; // 0xBA | |
232 public static final int NEW = 187; // 0xBB | |
233 public static final int NEWARRAY = 188; // 0xBC | |
234 public static final int ANEWARRAY = 189; // 0xBD | |
235 public static final int ARRAYLENGTH = 190; // 0xBE | |
236 public static final int ATHROW = 191; // 0xBF | |
237 public static final int CHECKCAST = 192; // 0xC0 | |
238 public static final int INSTANCEOF = 193; // 0xC1 | |
239 public static final int MONITORENTER = 194; // 0xC2 | |
240 public static final int MONITOREXIT = 195; // 0xC3 | |
241 public static final int WIDE = 196; // 0xC4 | |
242 public static final int MULTIANEWARRAY = 197; // 0xC5 | |
243 public static final int IFNULL = 198; // 0xC6 | |
244 public static final int IFNONNULL = 199; // 0xC7 | |
245 public static final int GOTO_W = 200; // 0xC8 | |
246 public static final int JSR_W = 201; // 0xC9 | |
247 public static final int BREAKPOINT = 202; // 0xCA | |
248 | |
249 // Start extended bytecodes | |
250 | |
251 /** | |
252 * Native function call. | |
253 * | |
254 * The 'function_address' value on the top of the stack is the result of | |
255 * linking a native function. | |
256 * | |
257 * <pre> | |
258 * Format: { u1 opcode; // JNICALL | |
259 * u2 sig; // Constant pool index of a CONSTANT_Utf8_info representing the signature of the call | |
260 * } | |
261 * | |
262 * Operand Stack: | |
263 * ..., [arg1, [arg2 ... ]] function_address => [return value, ]..., | |
264 * </pre> | |
265 * | |
266 * @see #JNIOP_LINK | |
267 * @see #JNIOP_J2N | |
268 * @see #JNIOP_N2J | |
269 */ | |
270 public static final int JNICALL = 203; | |
271 | |
272 // End extended bytecodes | |
273 | |
274 public static final int ILLEGAL = 255; | |
275 public static final int END = 256; | |
276 | |
277 /** | |
278 * The last opcode defined by the JVM specification. To iterate over all JVM bytecodes: | |
279 * <pre> | |
280 * for (int opcode = 0; opcode <= Bytecodes.LAST_JVM_OPCODE; ++opcode) { | |
281 * // | |
282 * } | |
283 * </pre> | |
284 */ | |
285 public static final int LAST_JVM_OPCODE = JSR_W; | |
286 | |
287 /** | |
288 * A collection of flags describing various bytecode attributes. | |
289 */ | |
290 static class Flags { | |
291 | |
292 /** | |
293 * Denotes an instruction that ends a basic block and does not let control flow fall through to its lexical successor. | |
294 */ | |
295 static final int STOP = 0x00000001; | |
296 | |
297 /** | |
298 * Denotes an instruction that ends a basic block and may let control flow fall through to its lexical successor. | |
299 * In practice this means it is a conditional branch. | |
300 */ | |
301 static final int FALL_THROUGH = 0x00000002; | |
302 | |
303 /** | |
304 * Denotes an instruction that has a 2 or 4 byte operand that is an offset to another instruction in the same method. | |
305 * This does not include the {@link Bytecodes#TABLESWITCH} or {@link Bytecodes#LOOKUPSWITCH} instructions. | |
306 */ | |
307 static final int BRANCH = 0x00000004; | |
308 | |
309 /** | |
310 * Denotes an instruction that reads the value of a static or instance field. | |
311 */ | |
312 static final int FIELD_READ = 0x00000008; | |
313 | |
314 /** | |
315 * Denotes an instruction that writes the value of a static or instance field. | |
316 */ | |
317 static final int FIELD_WRITE = 0x00000010; | |
318 | |
319 /** | |
320 * Denotes an instruction that is not defined in the JVM specification. | |
321 */ | |
322 static final int EXTENSION = 0x00000020; | |
323 | |
324 /** | |
325 * Denotes an instruction that can cause a trap. | |
326 */ | |
327 static final int TRAP = 0x00000080; | |
328 /** | |
329 * Denotes an instruction that is commutative. | |
330 */ | |
331 static final int COMMUTATIVE = 0x00000100; | |
332 /** | |
333 * Denotes an instruction that is associative. | |
334 */ | |
335 static final int ASSOCIATIVE = 0x00000200; | |
336 /** | |
337 * Denotes an instruction that loads an operand. | |
338 */ | |
339 static final int LOAD = 0x00000400; | |
340 /** | |
341 * Denotes an instruction that stores an operand. | |
342 */ | |
343 static final int STORE = 0x00000800; | |
344 /** | |
345 * Denotes the 4 INVOKE* instructions. | |
346 */ | |
347 static final int INVOKE = 0x00001000; | |
348 } | |
349 | |
350 // Performs a sanity check that none of the flags overlap. | |
351 static { | |
352 int allFlags = 0; | |
353 try { | |
354 for (Field field : Flags.class.getDeclaredFields()) { | |
355 int flagsFilter = Modifier.FINAL | Modifier.STATIC; | |
356 if ((field.getModifiers() & flagsFilter) == flagsFilter) { | |
357 assert field.getType() == int.class : "Only " + field; | |
358 final int flag = field.getInt(null); | |
359 assert flag != 0; | |
360 assert (flag & allFlags) == 0 : field.getName() + " has a value conflicting with another flag"; | |
361 allFlags |= flag; | |
362 } | |
363 } | |
364 } catch (Exception e) { | |
365 throw new InternalError(e.toString()); | |
366 } | |
367 } | |
368 | |
369 /** | |
370 * A array that maps from a bytecode value to a {@link String} for the corresponding instruction mnemonic. | |
371 * This will include the root instruction for the three-byte extended instructions. | |
372 */ | |
373 private static final String[] names = new String[256]; | |
374 | |
375 /** | |
376 * A array that maps from a bytecode value to the set of {@link Flags} for the corresponding instruction. | |
377 */ | |
378 private static final int[] flags = new int[256]; | |
379 | |
380 /** | |
381 * A array that maps from a bytecode value to the length in bytes for the corresponding instruction. | |
382 */ | |
383 private static final int[] length = new int[256]; | |
384 | |
385 // Checkstyle: stop | |
386 static { | |
387 def(NOP , "nop" , "b" ); | |
388 def(ACONST_NULL , "aconst_null" , "b" ); | |
389 def(ICONST_M1 , "iconst_m1" , "b" ); | |
390 def(ICONST_0 , "iconst_0" , "b" ); | |
391 def(ICONST_1 , "iconst_1" , "b" ); | |
392 def(ICONST_2 , "iconst_2" , "b" ); | |
393 def(ICONST_3 , "iconst_3" , "b" ); | |
394 def(ICONST_4 , "iconst_4" , "b" ); | |
395 def(ICONST_5 , "iconst_5" , "b" ); | |
396 def(LCONST_0 , "lconst_0" , "b" ); | |
397 def(LCONST_1 , "lconst_1" , "b" ); | |
398 def(FCONST_0 , "fconst_0" , "b" ); | |
399 def(FCONST_1 , "fconst_1" , "b" ); | |
400 def(FCONST_2 , "fconst_2" , "b" ); | |
401 def(DCONST_0 , "dconst_0" , "b" ); | |
402 def(DCONST_1 , "dconst_1" , "b" ); | |
403 def(BIPUSH , "bipush" , "bc" ); | |
404 def(SIPUSH , "sipush" , "bcc" ); | |
405 def(LDC , "ldc" , "bi" , TRAP); | |
406 def(LDC_W , "ldc_w" , "bii" , TRAP); | |
407 def(LDC2_W , "ldc2_w" , "bii" , TRAP); | |
408 def(ILOAD , "iload" , "bi" , LOAD); | |
409 def(LLOAD , "lload" , "bi" , LOAD); | |
410 def(FLOAD , "fload" , "bi" , LOAD); | |
411 def(DLOAD , "dload" , "bi" , LOAD); | |
412 def(ALOAD , "aload" , "bi" , LOAD); | |
413 def(ILOAD_0 , "iload_0" , "b" , LOAD); | |
414 def(ILOAD_1 , "iload_1" , "b" , LOAD); | |
415 def(ILOAD_2 , "iload_2" , "b" , LOAD); | |
416 def(ILOAD_3 , "iload_3" , "b" , LOAD); | |
417 def(LLOAD_0 , "lload_0" , "b" , LOAD); | |
418 def(LLOAD_1 , "lload_1" , "b" , LOAD); | |
419 def(LLOAD_2 , "lload_2" , "b" , LOAD); | |
420 def(LLOAD_3 , "lload_3" , "b" , LOAD); | |
421 def(FLOAD_0 , "fload_0" , "b" , LOAD); | |
422 def(FLOAD_1 , "fload_1" , "b" , LOAD); | |
423 def(FLOAD_2 , "fload_2" , "b" , LOAD); | |
424 def(FLOAD_3 , "fload_3" , "b" , LOAD); | |
425 def(DLOAD_0 , "dload_0" , "b" , LOAD); | |
426 def(DLOAD_1 , "dload_1" , "b" , LOAD); | |
427 def(DLOAD_2 , "dload_2" , "b" , LOAD); | |
428 def(DLOAD_3 , "dload_3" , "b" , LOAD); | |
429 def(ALOAD_0 , "aload_0" , "b" , LOAD); | |
430 def(ALOAD_1 , "aload_1" , "b" , LOAD); | |
431 def(ALOAD_2 , "aload_2" , "b" , LOAD); | |
432 def(ALOAD_3 , "aload_3" , "b" , LOAD); | |
433 def(IALOAD , "iaload" , "b" , TRAP); | |
434 def(LALOAD , "laload" , "b" , TRAP); | |
435 def(FALOAD , "faload" , "b" , TRAP); | |
436 def(DALOAD , "daload" , "b" , TRAP); | |
437 def(AALOAD , "aaload" , "b" , TRAP); | |
438 def(BALOAD , "baload" , "b" , TRAP); | |
439 def(CALOAD , "caload" , "b" , TRAP); | |
440 def(SALOAD , "saload" , "b" , TRAP); | |
441 def(ISTORE , "istore" , "bi" , STORE); | |
442 def(LSTORE , "lstore" , "bi" , STORE); | |
443 def(FSTORE , "fstore" , "bi" , STORE); | |
444 def(DSTORE , "dstore" , "bi" , STORE); | |
445 def(ASTORE , "astore" , "bi" , STORE); | |
446 def(ISTORE_0 , "istore_0" , "b" , STORE); | |
447 def(ISTORE_1 , "istore_1" , "b" , STORE); | |
448 def(ISTORE_2 , "istore_2" , "b" , STORE); | |
449 def(ISTORE_3 , "istore_3" , "b" , STORE); | |
450 def(LSTORE_0 , "lstore_0" , "b" , STORE); | |
451 def(LSTORE_1 , "lstore_1" , "b" , STORE); | |
452 def(LSTORE_2 , "lstore_2" , "b" , STORE); | |
453 def(LSTORE_3 , "lstore_3" , "b" , STORE); | |
454 def(FSTORE_0 , "fstore_0" , "b" , STORE); | |
455 def(FSTORE_1 , "fstore_1" , "b" , STORE); | |
456 def(FSTORE_2 , "fstore_2" , "b" , STORE); | |
457 def(FSTORE_3 , "fstore_3" , "b" , STORE); | |
458 def(DSTORE_0 , "dstore_0" , "b" , STORE); | |
459 def(DSTORE_1 , "dstore_1" , "b" , STORE); | |
460 def(DSTORE_2 , "dstore_2" , "b" , STORE); | |
461 def(DSTORE_3 , "dstore_3" , "b" , STORE); | |
462 def(ASTORE_0 , "astore_0" , "b" , STORE); | |
463 def(ASTORE_1 , "astore_1" , "b" , STORE); | |
464 def(ASTORE_2 , "astore_2" , "b" , STORE); | |
465 def(ASTORE_3 , "astore_3" , "b" , STORE); | |
466 def(IASTORE , "iastore" , "b" , TRAP); | |
467 def(LASTORE , "lastore" , "b" , TRAP); | |
468 def(FASTORE , "fastore" , "b" , TRAP); | |
469 def(DASTORE , "dastore" , "b" , TRAP); | |
470 def(AASTORE , "aastore" , "b" , TRAP); | |
471 def(BASTORE , "bastore" , "b" , TRAP); | |
472 def(CASTORE , "castore" , "b" , TRAP); | |
473 def(SASTORE , "sastore" , "b" , TRAP); | |
474 def(POP , "pop" , "b" ); | |
475 def(POP2 , "pop2" , "b" ); | |
476 def(DUP , "dup" , "b" ); | |
477 def(DUP_X1 , "dup_x1" , "b" ); | |
478 def(DUP_X2 , "dup_x2" , "b" ); | |
479 def(DUP2 , "dup2" , "b" ); | |
480 def(DUP2_X1 , "dup2_x1" , "b" ); | |
481 def(DUP2_X2 , "dup2_x2" , "b" ); | |
482 def(SWAP , "swap" , "b" ); | |
483 def(IADD , "iadd" , "b" , COMMUTATIVE | ASSOCIATIVE); | |
484 def(LADD , "ladd" , "b" , COMMUTATIVE | ASSOCIATIVE); | |
485 def(FADD , "fadd" , "b" , COMMUTATIVE | ASSOCIATIVE); | |
486 def(DADD , "dadd" , "b" , COMMUTATIVE | ASSOCIATIVE); | |
487 def(ISUB , "isub" , "b" ); | |
488 def(LSUB , "lsub" , "b" ); | |
489 def(FSUB , "fsub" , "b" ); | |
490 def(DSUB , "dsub" , "b" ); | |
491 def(IMUL , "imul" , "b" , COMMUTATIVE | ASSOCIATIVE); | |
492 def(LMUL , "lmul" , "b" , COMMUTATIVE | ASSOCIATIVE); | |
493 def(FMUL , "fmul" , "b" , COMMUTATIVE | ASSOCIATIVE); | |
494 def(DMUL , "dmul" , "b" , COMMUTATIVE | ASSOCIATIVE); | |
495 def(IDIV , "idiv" , "b" , TRAP); | |
496 def(LDIV , "ldiv" , "b" , TRAP); | |
497 def(FDIV , "fdiv" , "b" ); | |
498 def(DDIV , "ddiv" , "b" ); | |
499 def(IREM , "irem" , "b" , TRAP); | |
500 def(LREM , "lrem" , "b" , TRAP); | |
501 def(FREM , "frem" , "b" ); | |
502 def(DREM , "drem" , "b" ); | |
503 def(INEG , "ineg" , "b" ); | |
504 def(LNEG , "lneg" , "b" ); | |
505 def(FNEG , "fneg" , "b" ); | |
506 def(DNEG , "dneg" , "b" ); | |
507 def(ISHL , "ishl" , "b" ); | |
508 def(LSHL , "lshl" , "b" ); | |
509 def(ISHR , "ishr" , "b" ); | |
510 def(LSHR , "lshr" , "b" ); | |
511 def(IUSHR , "iushr" , "b" ); | |
512 def(LUSHR , "lushr" , "b" ); | |
513 def(IAND , "iand" , "b" , COMMUTATIVE | ASSOCIATIVE); | |
514 def(LAND , "land" , "b" , COMMUTATIVE | ASSOCIATIVE); | |
515 def(IOR , "ior" , "b" , COMMUTATIVE | ASSOCIATIVE); | |
516 def(LOR , "lor" , "b" , COMMUTATIVE | ASSOCIATIVE); | |
517 def(IXOR , "ixor" , "b" , COMMUTATIVE | ASSOCIATIVE); | |
518 def(LXOR , "lxor" , "b" , COMMUTATIVE | ASSOCIATIVE); | |
519 def(IINC , "iinc" , "bic" , LOAD | STORE); | |
520 def(I2L , "i2l" , "b" ); | |
521 def(I2F , "i2f" , "b" ); | |
522 def(I2D , "i2d" , "b" ); | |
523 def(L2I , "l2i" , "b" ); | |
524 def(L2F , "l2f" , "b" ); | |
525 def(L2D , "l2d" , "b" ); | |
526 def(F2I , "f2i" , "b" ); | |
527 def(F2L , "f2l" , "b" ); | |
528 def(F2D , "f2d" , "b" ); | |
529 def(D2I , "d2i" , "b" ); | |
530 def(D2L , "d2l" , "b" ); | |
531 def(D2F , "d2f" , "b" ); | |
532 def(I2B , "i2b" , "b" ); | |
533 def(I2C , "i2c" , "b" ); | |
534 def(I2S , "i2s" , "b" ); | |
535 def(LCMP , "lcmp" , "b" ); | |
536 def(FCMPL , "fcmpl" , "b" ); | |
537 def(FCMPG , "fcmpg" , "b" ); | |
538 def(DCMPL , "dcmpl" , "b" ); | |
539 def(DCMPG , "dcmpg" , "b" ); | |
540 def(IFEQ , "ifeq" , "boo" , FALL_THROUGH | BRANCH); | |
541 def(IFNE , "ifne" , "boo" , FALL_THROUGH | BRANCH); | |
542 def(IFLT , "iflt" , "boo" , FALL_THROUGH | BRANCH); | |
543 def(IFGE , "ifge" , "boo" , FALL_THROUGH | BRANCH); | |
544 def(IFGT , "ifgt" , "boo" , FALL_THROUGH | BRANCH); | |
545 def(IFLE , "ifle" , "boo" , FALL_THROUGH | BRANCH); | |
546 def(IF_ICMPEQ , "if_icmpeq" , "boo" , COMMUTATIVE | FALL_THROUGH | BRANCH); | |
547 def(IF_ICMPNE , "if_icmpne" , "boo" , COMMUTATIVE | FALL_THROUGH | BRANCH); | |
548 def(IF_ICMPLT , "if_icmplt" , "boo" , FALL_THROUGH | BRANCH); | |
549 def(IF_ICMPGE , "if_icmpge" , "boo" , FALL_THROUGH | BRANCH); | |
550 def(IF_ICMPGT , "if_icmpgt" , "boo" , FALL_THROUGH | BRANCH); | |
551 def(IF_ICMPLE , "if_icmple" , "boo" , FALL_THROUGH | BRANCH); | |
552 def(IF_ACMPEQ , "if_acmpeq" , "boo" , COMMUTATIVE | FALL_THROUGH | BRANCH); | |
553 def(IF_ACMPNE , "if_acmpne" , "boo" , COMMUTATIVE | FALL_THROUGH | BRANCH); | |
554 def(GOTO , "goto" , "boo" , STOP | BRANCH); | |
555 def(JSR , "jsr" , "boo" , STOP | BRANCH); | |
556 def(RET , "ret" , "bi" , STOP); | |
557 def(TABLESWITCH , "tableswitch" , "" , STOP); | |
558 def(LOOKUPSWITCH , "lookupswitch" , "" , STOP); | |
559 def(IRETURN , "ireturn" , "b" , TRAP | STOP); | |
560 def(LRETURN , "lreturn" , "b" , TRAP | STOP); | |
561 def(FRETURN , "freturn" , "b" , TRAP | STOP); | |
562 def(DRETURN , "dreturn" , "b" , TRAP | STOP); | |
563 def(ARETURN , "areturn" , "b" , TRAP | STOP); | |
564 def(RETURN , "return" , "b" , TRAP | STOP); | |
565 def(GETSTATIC , "getstatic" , "bjj" , TRAP | FIELD_READ); | |
566 def(PUTSTATIC , "putstatic" , "bjj" , TRAP | FIELD_WRITE); | |
567 def(GETFIELD , "getfield" , "bjj" , TRAP | FIELD_READ); | |
568 def(PUTFIELD , "putfield" , "bjj" , TRAP | FIELD_WRITE); | |
569 def(INVOKEVIRTUAL , "invokevirtual" , "bjj" , TRAP | INVOKE); | |
570 def(INVOKESPECIAL , "invokespecial" , "bjj" , TRAP | INVOKE); | |
571 def(INVOKESTATIC , "invokestatic" , "bjj" , TRAP | INVOKE); | |
572 def(INVOKEINTERFACE , "invokeinterface" , "bjja_", TRAP | INVOKE); | |
573 def(XXXUNUSEDXXX , "xxxunusedxxx" , "" ); | |
574 def(NEW , "new" , "bii" , TRAP); | |
575 def(NEWARRAY , "newarray" , "bc" , TRAP); | |
576 def(ANEWARRAY , "anewarray" , "bii" , TRAP); | |
577 def(ARRAYLENGTH , "arraylength" , "b" , TRAP); | |
578 def(ATHROW , "athrow" , "b" , TRAP | STOP); | |
579 def(CHECKCAST , "checkcast" , "bii" , TRAP); | |
580 def(INSTANCEOF , "instanceof" , "bii" , TRAP); | |
581 def(MONITORENTER , "monitorenter" , "b" , TRAP); | |
582 def(MONITOREXIT , "monitorexit" , "b" , TRAP); | |
583 def(WIDE , "wide" , "" ); | |
584 def(MULTIANEWARRAY , "multianewarray" , "biic" , TRAP); | |
585 def(IFNULL , "ifnull" , "boo" , FALL_THROUGH | BRANCH); | |
586 def(IFNONNULL , "ifnonnull" , "boo" , FALL_THROUGH | BRANCH); | |
587 def(GOTO_W , "goto_w" , "boooo", STOP | BRANCH); | |
588 def(JSR_W , "jsr_w" , "boooo", STOP | BRANCH); | |
589 def(BREAKPOINT , "breakpoint" , "b" , TRAP); | |
590 | |
591 def(JNICALL , "jnicall" , "bii" , EXTENSION | TRAP); | |
592 } | |
593 // Checkstyle: resume | |
594 | |
595 /** | |
596 * Determines if an opcode is commutative. | |
597 * @param opcode the opcode to check | |
598 * @return {@code true} iff commutative | |
599 */ | |
600 public static boolean isCommutative(int opcode) { | |
601 return (flags[opcode & 0xff] & COMMUTATIVE) != 0; | |
602 } | |
603 | |
604 /** | |
605 * Gets the length of an instruction denoted by a given opcode. | |
606 * | |
607 * @param opcode an instruction opcode | |
608 * @return the length of the instruction denoted by {@code opcode}. If {@code opcode} is an illegal instruction or denotes a | |
609 * variable length instruction (e.g. {@link #TABLESWITCH}), then 0 is returned. | |
610 */ | |
611 public static int lengthOf(int opcode) { | |
612 return length[opcode & 0xff]; | |
613 } | |
614 | |
615 /** | |
616 * Gets the length of an instruction at a given position in a given bytecode array. | |
617 * This methods handles variable length and {@linkplain #WIDE widened} instructions. | |
618 * | |
619 * @param code an array of bytecode | |
620 * @param bci the position in {@code code} of an instruction's opcode | |
621 * @return the length of the instruction at position {@code bci} in {@code code} | |
622 */ | |
623 public static int lengthOf(byte[] code, int bci) { | |
624 int opcode = Bytes.beU1(code, bci); | |
625 int length = Bytecodes.length[opcode & 0xff]; | |
626 if (length == 0) { | |
627 switch (opcode) { | |
628 case TABLESWITCH: { | |
629 return new BytecodeTableSwitch(code, bci).size(); | |
630 } | |
631 case LOOKUPSWITCH: { | |
632 return new BytecodeLookupSwitch(code, bci).size(); | |
633 } | |
634 case WIDE: { | |
635 int opc = Bytes.beU1(code, bci + 1); | |
636 if (opc == RET) { | |
637 return 4; | |
638 } else if (opc == IINC) { | |
639 return 6; | |
640 } else { | |
641 return 4; // a load or store bytecode | |
642 } | |
643 } | |
644 default: | |
645 throw new Error("unknown variable-length bytecode: " + opcode); | |
646 } | |
647 } | |
648 return length; | |
649 } | |
650 | |
651 /** | |
652 * Gets the lower-case mnemonic for a given opcode. | |
653 * | |
654 * @param opcode an opcode | |
655 * @return the mnemonic for {@code opcode} or {@code "<illegal opcode: " + opcode + ">"} if {@code opcode} is not a legal opcode | |
656 */ | |
657 public static String nameOf(int opcode) throws IllegalArgumentException { | |
658 String name = names[opcode & 0xff]; | |
659 if (name == null) { | |
660 return "<illegal opcode: " + opcode + ">"; | |
661 } | |
662 return name; | |
663 } | |
664 | |
665 /** | |
666 * Allocation-free version of {@linkplain #nameOf(int)}. | |
667 * @param opcode an opcode. | |
668 * @return the mnemonic for {@code opcode} or {@code "<illegal opcode>"} if {@code opcode} is not a legal opcode. | |
669 */ | |
670 public static String baseNameOf(int opcode) { | |
671 String name = names[opcode & 0xff]; | |
672 if (name == null) { | |
673 return "<illegal opcode>"; | |
674 } | |
675 return name; | |
676 } | |
677 | |
678 /** | |
679 * Gets the opcode corresponding to a given mnemonic. | |
680 * | |
681 * @param name an opcode mnemonic | |
682 * @return the opcode corresponding to {@code mnemonic} | |
683 * @throws IllegalArgumentException if {@code name} does not denote a valid opcode | |
684 */ | |
685 public static int valueOf(String name) { | |
686 for (int opcode = 0; opcode < names.length; ++opcode) { | |
687 if (name.equalsIgnoreCase(names[opcode])) { | |
688 return opcode; | |
689 } | |
690 } | |
691 throw new IllegalArgumentException("No opcode for " + name); | |
692 } | |
693 | |
694 /** | |
695 * Determines if a given opcode denotes an instruction that can cause an implicit exception. | |
696 * | |
697 * @param opcode an opcode to test | |
698 * @return {@code true} iff {@code opcode} can cause an implicit exception, {@code false} otherwise | |
699 */ | |
700 public static boolean canTrap(int opcode) { | |
701 return (flags[opcode & 0xff] & TRAP) != 0; | |
702 } | |
703 | |
704 /** | |
705 * Determines if a given opcode denotes an instruction that loads a local variable to the operand stack. | |
706 * | |
707 * @param opcode an opcode to test | |
708 * @return {@code true} iff {@code opcode} loads a local variable to the operand stack, {@code false} otherwise | |
709 */ | |
710 public static boolean isLoad(int opcode) { | |
711 return (flags[opcode & 0xff] & LOAD) != 0; | |
712 } | |
713 | |
714 /** | |
715 * Determines if a given opcode denotes an instruction that ends a basic block and does not let control flow fall | |
716 * through to its lexical successor. | |
717 * | |
718 * @param opcode an opcode to test | |
719 * @return {@code true} iff {@code opcode} properly ends a basic block | |
720 */ | |
721 public static boolean isStop(int opcode) { | |
722 return (flags[opcode & 0xff] & STOP) != 0; | |
723 } | |
724 | |
725 /** | |
726 * Determines if a given opcode denotes an instruction that stores a value to a local variable | |
727 * after popping it from the operand stack. | |
728 * | |
729 * @param opcode an opcode to test | |
730 * @return {@code true} iff {@code opcode} stores a value to a local variable, {@code false} otherwise | |
731 */ | |
732 public static boolean isInvoke(int opcode) { | |
733 return (flags[opcode & 0xff] & INVOKE) != 0; | |
734 } | |
735 | |
736 /** | |
737 * Determines if a given opcode denotes an instruction that stores a value to a local variable | |
738 * after popping it from the operand stack. | |
739 * | |
740 * @param opcode an opcode to test | |
741 * @return {@code true} iff {@code opcode} stores a value to a local variable, {@code false} otherwise | |
742 */ | |
743 public static boolean isStore(int opcode) { | |
744 return (flags[opcode & 0xff] & STORE) != 0; | |
745 } | |
746 | |
747 /** | |
748 * Determines if a given opcode is an instruction that delimits a basic block. | |
749 * | |
750 * @param opcode an opcode to test | |
751 * @return {@code true} iff {@code opcode} delimits a basic block | |
752 */ | |
753 public static boolean isBlockEnd(int opcode) { | |
754 return (flags[opcode & 0xff] & (STOP | FALL_THROUGH)) != 0; | |
755 } | |
756 | |
757 /** | |
758 * Determines if a given opcode is an instruction that has a 2 or 4 byte operand that is an offset to another | |
759 * instruction in the same method. This does not include the {@linkplain #TABLESWITCH switch} instructions. | |
760 * | |
761 * @param opcode an opcode to test | |
762 * @return {@code true} iff {@code opcode} is a branch instruction with a single operand | |
763 */ | |
764 public static boolean isBranch(int opcode) { | |
765 return (flags[opcode & 0xff] & BRANCH) != 0; | |
766 } | |
767 | |
768 /** | |
769 * Determines if a given opcode denotes a conditional branch. | |
770 * @param opcode | |
771 * @return {@code true} iff {@code opcode} is a conditional branch | |
772 */ | |
773 public static boolean isConditionalBranch(int opcode) { | |
774 return (flags[opcode & 0xff] & FALL_THROUGH) != 0; | |
775 } | |
776 | |
777 /** | |
778 * Determines if a given opcode denotes a standard bytecode. A standard bytecode is | |
779 * defined in the JVM specification. | |
780 * | |
781 * @param opcode an opcode to test | |
782 * @return {@code true} iff {@code opcode} is a standard bytecode | |
783 */ | |
784 public static boolean isStandard(int opcode) { | |
785 return (flags[opcode & 0xff] & EXTENSION) == 0; | |
786 } | |
787 | |
788 /** | |
789 * Determines if a given opcode denotes an extended bytecode. | |
790 * | |
791 * @param opcode an opcode to test | |
792 * @return {@code true} if {@code opcode} is an extended bytecode | |
793 */ | |
794 public static boolean isExtended(int opcode) { | |
795 return (flags[opcode & 0xff] & EXTENSION) != 0; | |
796 } | |
797 | |
798 /** | |
799 * Determines if a given opcode is a three-byte extended bytecode. | |
800 * | |
801 * @param opcode an opcode to test | |
802 * @return {@code true} if {@code (opcode & ~0xff) != 0} | |
803 */ | |
804 public static boolean isThreeByteExtended(int opcode) { | |
805 return (opcode & ~0xff) != 0; | |
806 } | |
807 | |
808 /** | |
809 * Gets the arithmetic operator name for a given opcode. If {@code opcode} does not denote an | |
810 * arithmetic instruction, then the {@linkplain #nameOf(int) name} of the opcode is returned | |
811 * instead. | |
812 * | |
813 * @param op an opcode | |
814 * @return the arithmetic operator name | |
815 */ | |
816 public static String operator(int op) { | |
817 // Checkstyle: stop | |
818 switch (op) { | |
819 // arithmetic ops | |
820 case IADD : // fall through | |
821 case LADD : // fall through | |
822 case FADD : // fall through | |
823 case DADD : return "+"; | |
824 case ISUB : // fall through | |
825 case LSUB : // fall through | |
826 case FSUB : // fall through | |
827 case DSUB : return "-"; | |
828 case IMUL : // fall through | |
829 case LMUL : // fall through | |
830 case FMUL : // fall through | |
831 case DMUL : return "*"; | |
832 case IDIV : // fall through | |
833 case LDIV : // fall through | |
834 case FDIV : // fall through | |
835 case DDIV : return "/"; | |
836 case IREM : // fall through | |
837 case LREM : // fall through | |
838 case FREM : // fall through | |
839 case DREM : return "%"; | |
840 // shift ops | |
841 case ISHL : // fall through | |
842 case LSHL : return "<<"; | |
843 case ISHR : // fall through | |
844 case LSHR : return ">>"; | |
845 case IUSHR: // fall through | |
846 case LUSHR: return ">>>"; | |
847 // logic ops | |
848 case IAND : // fall through | |
849 case LAND : return "&"; | |
850 case IOR : // fall through | |
851 case LOR : return "|"; | |
852 case IXOR : // fall through | |
853 case LXOR : return "^"; | |
854 } | |
855 // Checkstyle: resume | |
856 return nameOf(op); | |
857 } | |
858 | |
859 /** | |
860 * Defines a bytecode by entering it into the arrays that record its name, length and flags. | |
861 * | |
862 * @param name instruction name (should be lower case) | |
863 * @param format encodes the length of the instruction | |
864 * @param flags the set of {@link Flags} associated with the instruction | |
865 */ | |
866 private static void def(int opcode, String name, String format) { | |
867 def(opcode, name, format, 0); | |
868 } | |
869 | |
870 /** | |
871 * Defines a bytecode by entering it into the arrays that record its name, length and flags. | |
872 * | |
873 * @param name instruction name (lower case) | |
874 * @param format encodes the length of the instruction | |
875 * @param flags the set of {@link Flags} associated with the instruction | |
876 */ | |
877 private static void def(int opcode, String name, String format, int flags) { | |
878 assert names[opcode] == null : "opcode " + opcode + " is already bound to name " + names[opcode]; | |
879 names[opcode] = name; | |
880 int instructionLength = format.length(); | |
881 length[opcode] = instructionLength; | |
882 Bytecodes.flags[opcode] = flags; | |
883 | |
884 assert !isConditionalBranch(opcode) || isBranch(opcode) : "a conditional branch must also be a branch"; | |
885 } | |
886 | |
887 /** | |
888 * Utility for ensuring that the extended opcodes are contiguous and follow on directly | |
889 * from the standard JVM opcodes. If these conditions do not hold for the input source | |
890 * file, then it is modified 'in situ' to fix the problem. | |
891 * | |
892 * @param args {@code args[0]} is the path to this source file | |
893 */ | |
894 public static void main(String[] args) throws Exception { | |
895 Method findWorkspaceDirectory = Class.forName("com.sun.max.ide.JavaProject").getDeclaredMethod("findWorkspaceDirectory"); | |
896 File base = new File((File) findWorkspaceDirectory.invoke(null), "com.oracle.max.cri/src"); | |
897 File file = new File(base, Bytecodes.class.getName().replace('.', File.separatorChar) + ".java").getAbsoluteFile(); | |
898 | |
899 Pattern opcodeDecl = Pattern.compile("(\\s*public static final int )(\\w+)(\\s*=\\s*)(\\d+)(;.*)"); | |
900 | |
901 BufferedReader br = new BufferedReader(new FileReader(file)); | |
902 CharArrayWriter buffer = new CharArrayWriter((int) file.length()); | |
903 PrintWriter out = new PrintWriter(buffer); | |
904 String line; | |
905 int lastExtendedOpcode = BREAKPOINT; | |
906 boolean modified = false; | |
907 int section = 0; | |
908 while ((line = br.readLine()) != null) { | |
909 if (section == 0) { | |
910 if (line.equals(" // Start extended bytecodes")) { | |
911 section = 1; | |
912 } | |
913 } else if (section == 1) { | |
914 if (line.equals(" // End extended bytecodes")) { | |
915 section = 2; | |
916 } else { | |
917 Matcher matcher = opcodeDecl.matcher(line); | |
918 if (matcher.matches()) { | |
919 String name = matcher.group(2); | |
920 String value = matcher.group(4); | |
921 int opcode = Integer.parseInt(value); | |
922 if (names[opcode] == null || !names[opcode].equalsIgnoreCase(name)) { | |
923 throw new RuntimeException("Missing definition of name and flags for " + opcode + ":" + name + " -- " + names[opcode]); | |
924 } | |
925 if (opcode != lastExtendedOpcode + 1) { | |
926 System.err.println("Fixed declaration of opcode " + name + " to be " + (lastExtendedOpcode + 1) + " (was " + value + ")"); | |
927 opcode = lastExtendedOpcode + 1; | |
928 line = line.substring(0, matcher.start(4)) + opcode + line.substring(matcher.end(4)); | |
929 modified = true; | |
930 } | |
931 | |
932 if (opcode >= 256) { | |
933 throw new RuntimeException("Exceeded maximum opcode value with " + name); | |
934 } | |
935 | |
936 lastExtendedOpcode = opcode; | |
937 } | |
938 } | |
939 } | |
940 | |
941 out.println(line); | |
942 } | |
943 if (section == 0) { | |
944 throw new RuntimeException("Did not find line starting extended bytecode declarations:\n\n // Start extended bytecodes"); | |
945 } else if (section == 1) { | |
946 throw new RuntimeException("Did not find line ending extended bytecode declarations:\n\n // End extended bytecodes"); | |
947 } | |
948 | |
949 if (modified) { | |
950 out.flush(); | |
951 FileWriter fileWriter = new FileWriter(file); | |
952 fileWriter.write(buffer.toCharArray()); | |
953 fileWriter.close(); | |
954 | |
955 System.out.println("Modified: " + file); | |
956 } | |
957 | |
958 | |
959 // Uncomment to print out visitor method declarations: | |
960 // for (int opcode = 0; opcode < flags.length; ++opcode) { | |
961 // if (isExtension(opcode)) { | |
962 // String visitorParams = length(opcode) == 1 ? "" : "int index"; | |
963 // System.out.println("@Override"); | |
964 // System.out.println("protected void " + name(opcode) + "(" + visitorParams + ") {"); | |
965 // System.out.println("}"); | |
966 // System.out.println(); | |
967 // } | |
968 // } | |
969 | |
970 // Uncomment to print out visitor method declarations: | |
971 // for (int opcode = 0; opcode < flags.length; ++opcode) { | |
972 // if (isExtension(opcode)) { | |
973 // System.out.println("case " + name(opcode).toUpperCase() + ": {"); | |
974 // String arg = ""; | |
975 // int length = length(opcode); | |
976 // if (length == 2) { | |
977 // arg = "readUnsigned1()"; | |
978 // } else if (length == 3) { | |
979 // arg = "readUnsigned2()"; | |
980 // } | |
981 // System.out.println(" bytecodeVisitor." + name(opcode) + "(" + arg + ");"); | |
982 // System.out.println(" break;"); | |
983 // System.out.println("}"); | |
984 // } | |
985 // } | |
986 | |
987 } | |
988 } |