1 /* src/vm/jit/parse.c - parser for JavaVM to intermediate code translation
3 Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 Contact: cacao@cacaojvm.org
29 Changes: Carolyn Oates
34 $Id: parse.c 4687 2006-03-23 12:48:43Z edwin $
42 #include "vm/global.h"
47 #include "mm/memory.h"
48 #include "native/native.h"
49 #include "toolbox/logging.h"
50 #include "vm/builtin.h"
51 #include "vm/exceptions.h"
52 #include "vm/global.h"
53 #include "vm/linker.h"
54 #include "vm/loader.h"
55 #include "vm/resolve.h"
56 #include "vm/options.h"
57 #include "vm/statistics.h"
58 #include "vm/stringlocal.h"
59 #include "vm/jit/asmpart.h"
60 #include "vm/jit/jit.h"
61 #include "vm/jit/parse.h"
62 #include "vm/jit/patcher.h"
63 #include "vm/jit/loop/loop.h"
65 /*******************************************************************************
67 function 'parse' scans the JavaVM code and generates intermediate code
69 During parsing the block index table is used to store at bit pos 0
70 a flag which marks basic block starts and at position 1 to 31 the
71 intermediate instruction index. After parsing the block index table
72 is scanned, for marked positions a block is generated and the block
73 number is stored in the block index table.
75 *******************************************************************************/
77 static exceptiontable * fillextable(methodinfo *m,
78 exceptiontable *extable,
79 exceptiontable *raw_extable,
80 int exceptiontablelength,
85 if (exceptiontablelength == 0)
88 b_count = *block_count;
90 for (src = exceptiontablelength-1; src >=0; src--) {
91 /* the start of the handled region becomes a basic block start */
92 p = raw_extable[src].startpc;
93 CHECK_BYTECODE_INDEX(p);
97 p = raw_extable[src].endpc; /* see JVM Spec 4.7.3 */
98 CHECK_BYTECODE_INDEX_EXCLUSIVE(p);
100 #if defined(ENABLE_VERIFIER)
101 if (p <= raw_extable[src].startpc) {
102 *exceptionptr = new_verifyerror(m,
103 "Invalid exception handler range");
109 /* end of handled region becomes a basic block boundary */
110 /* (If it is the bytecode end, we'll use the special */
111 /* end block that is created anyway.) */
112 if (p < m->jcodelength)
115 /* the start of the handler becomes a basic block start */
116 p = raw_extable[src].handlerpc;
117 CHECK_BYTECODE_INDEX(p);
118 extable->handlerpc = p;
121 extable->catchtype = raw_extable[src].catchtype;
122 extable->next = NULL;
123 extable->down = &extable[1];
127 *block_count = b_count;
132 #if defined(ENABLE_VERIFIER)
133 throw_invalid_bytecode_index:
135 new_verifyerror(m, "Illegal bytecode index in exception table");
140 /*** macro for checking the length of the bytecode ***/
142 #if defined(ENABLE_VERIFIER)
143 #define CHECK_END_OF_BYTECODE(neededlength) \
145 if ((neededlength) > m->jcodelength) \
146 goto throw_unexpected_end_of_bytecode; \
148 #else /* !ENABLE_VERIFIER */
149 #define CHECK_END_OF_BYTECODE(neededlength)
150 #endif /* ENABLE_VERIFIER */
152 methodinfo *parse(methodinfo *m, codegendata *cd)
154 int p; /* java instruction counter */
155 int nextp; /* start of next java instruction */
156 int opcode; /* java opcode */
157 int i; /* temporary for different uses (ctrs)*/
158 int ipc = 0; /* intermediate instruction counter */
159 int b_count = 0; /* basic block counter */
160 int s_count = 0; /* stack element counter */
161 bool blockend = false; /* true if basic block end has been reached */
162 bool iswide = false; /* true if last instruction was a wide*/
163 instruction *iptr; /* current ptr into instruction array */
164 int gp; /* global java instruction counter */
166 int firstlocal = 0; /* first local variable of method */
167 u1 *instructionstart; /* 1 for pcs which are valid instr. starts */
169 constant_classref *cr;
170 constant_classref *compr;
172 builtintable_entry *bte;
178 u2 skipBasicBlockChange;
180 /* allocate instruction array and block index table */
182 /* 1 additional for end ipc */
183 m->basicblockindex = DMNEW(s4, m->jcodelength + 1);
184 memset(m->basicblockindex, 0, sizeof(s4) * (m->jcodelength + 1));
186 instructionstart = DMNEW(u1, m->jcodelength + 1);
187 memset(instructionstart, 0, sizeof(u1) * (m->jcodelength + 1));
189 /* 1 additional for TRACEBUILTIN and 4 for MONITORENTER/EXIT */
190 /* additional MONITOREXITS are reached by branches which are 3 bytes */
192 iptr = m->instructions = DMNEW(instruction, m->jcodelength + 5);
194 /* Zero the intermediate instructions array so we don't have any
195 * invalid pointers in it if we cannot finish analyse_stack(). */
197 memset(iptr, 0, sizeof(instruction) * (m->jcodelength + 5));
199 /* compute branch targets of exception table */
202 &(cd->exceptiontable[cd->exceptiontablelength-1]),
204 m->exceptiontablelength,
210 s_count = 1 + m->exceptiontablelength; /* initialize stack element counter */
212 #if defined(USE_THREADS)
213 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
214 m->isleafmethod = false;
218 /* scan all java instructions */
222 if (m->linenumbercount == 0) {
226 linepcchange = m->linenumbers[0].start_pc;
229 skipBasicBlockChange=0;
230 for (p = 0, gp = 0; p < m->jcodelength; gp += (nextp - p), p = nextp) {
232 /* mark this position as a valid instruction start */
234 instructionstart[gp] = 1;
235 if (linepcchange==p) {
236 if (m->linenumbercount > lineindex) {
237 currentline = m->linenumbers[lineindex].line_number;
239 if (lineindex < m->linenumbercount)
240 linepcchange = m->linenumbers[lineindex].start_pc;
245 /* fetch next opcode */
247 opcode = code_get_u1(p, m);
249 if (!skipBasicBlockChange) {
250 m->basicblockindex[gp] |= (ipc << 1); /*store intermed cnt*/
253 skipBasicBlockChange = 0;
255 /* some compilers put a JAVA_NOP after a blockend instruction */
257 if ((opcode != JAVA_NOP) && (blockend == true)) {
258 /* start new block */
264 nextp = p + jcommandsize[opcode]; /* compute next instruction start */
266 CHECK_END_OF_BYTECODE(nextp);
268 s_count += stackreq[opcode]; /* compute stack element count */
273 /* pushing constants onto the stack p */
276 LOADCONST_I(code_get_s1(p+1,m));
280 LOADCONST_I(code_get_s2(p+1,m));
284 i = code_get_u1(p + 1, m);
285 goto pushconstantitem;
289 i = code_get_u2(p + 1, m);
293 if (i >= m->class->cpcount) {
294 *exceptionptr = new_verifyerror(m,
295 "Attempt to access constant outside range");
299 switch (m->class->cptags[i]) {
300 case CONSTANT_Integer:
301 LOADCONST_I(((constant_integer *) (m->class->cpinfos[i]))->value);
304 LOADCONST_L(((constant_long *) (m->class->cpinfos[i]))->value);
307 LOADCONST_F(((constant_float *) (m->class->cpinfos[i]))->value);
309 case CONSTANT_Double:
310 LOADCONST_D(((constant_double *) (m->class->cpinfos[i]))->value);
312 case CONSTANT_String:
313 LOADCONST_A(literalstring_new((utf *) (m->class->cpinfos[i])));
316 cr = (constant_classref *) (m->class->cpinfos[i]);
318 if (!resolve_classref(m, cr, resolveLazy, true,
322 /* if not resolved, c == NULL */
324 LOADCONST_A_CLASS(c, cr);
327 *exceptionptr = new_verifyerror(m,
328 "Invalid constant type to push");
333 case JAVA_ACONST_NULL:
344 LOADCONST_I(opcode - JAVA_ICONST_0);
349 LOADCONST_L(opcode - JAVA_LCONST_0);
355 LOADCONST_F(opcode - JAVA_FCONST_0);
360 LOADCONST_D(opcode - JAVA_DCONST_0);
363 /* loading variables onto the stack */
371 i = code_get_u1(p + 1,m);
374 i = code_get_u2(p + 1,m);
378 OP1LOAD(opcode, i + firstlocal);
385 OP1LOAD(ICMD_ILOAD, opcode - JAVA_ILOAD_0 + firstlocal);
392 OP1LOAD(ICMD_LLOAD, opcode - JAVA_LLOAD_0 + firstlocal);
399 OP1LOAD(ICMD_FLOAD, opcode - JAVA_FLOAD_0 + firstlocal);
406 OP1LOAD(ICMD_DLOAD, opcode - JAVA_DLOAD_0 + firstlocal);
413 OP1LOAD(ICMD_ALOAD, opcode - JAVA_ALOAD_0 + firstlocal);
416 /* storing stack values into local variables */
424 i = code_get_u1(p + 1,m);
427 i = code_get_u2(p + 1,m);
431 OP1STORE(opcode, i + firstlocal);
438 OP1STORE(ICMD_ISTORE, opcode - JAVA_ISTORE_0 + firstlocal);
445 OP1STORE(ICMD_LSTORE, opcode - JAVA_LSTORE_0 + firstlocal);
452 OP1STORE(ICMD_FSTORE, opcode - JAVA_FSTORE_0 + firstlocal);
459 OP1STORE(ICMD_DSTORE, opcode - JAVA_DSTORE_0 + firstlocal);
466 OP1STORE(ICMD_ASTORE, opcode - JAVA_ASTORE_0 + firstlocal);
474 i = code_get_u1(p + 1,m);
475 v = code_get_s1(p + 2,m);
479 i = code_get_u2(p + 1,m);
480 v = code_get_s2(p + 3,m);
484 INDEX_ONEWORD(i + firstlocal);
485 OP2I(opcode, i + firstlocal, v);
489 /* wider index for loading, storing and incrementing */
496 /* managing arrays ****************************************************/
499 switch (code_get_s1(p + 1, m)) {
501 bte = builtintable_get_internal(BUILTIN_newarray_boolean);
504 bte = builtintable_get_internal(BUILTIN_newarray_char);
507 bte = builtintable_get_internal(BUILTIN_newarray_float);
510 bte = builtintable_get_internal(BUILTIN_newarray_double);
513 bte = builtintable_get_internal(BUILTIN_newarray_byte);
516 bte = builtintable_get_internal(BUILTIN_newarray_short);
519 bte = builtintable_get_internal(BUILTIN_newarray_int);
522 bte = builtintable_get_internal(BUILTIN_newarray_long);
525 *exceptionptr = new_verifyerror(m,
526 "Invalid array-type to create");
529 BUILTIN(bte, true, NULL, currentline);
533 i = code_get_u2(p + 1, m);
534 compr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
538 if (!(cr = class_get_classref_multiarray_of(1, compr)))
541 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
544 LOADCONST_A_BUILTIN(c, cr);
545 bte = builtintable_get_internal(BUILTIN_newarray);
546 BUILTIN(bte, true, NULL, currentline);
550 case JAVA_MULTIANEWARRAY:
551 m->isleafmethod = false;
552 i = code_get_u2(p + 1, m);
554 s4 v = code_get_u1(p + 3, m);
556 cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
560 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
563 /* if unresolved, c == NULL */
564 OP2AT(opcode, v, c, cr, currentline);
586 i = p + code_get_s2(p + 1,m);
587 CHECK_BYTECODE_INDEX(i);
595 i = p + code_get_s4(p + 1,m);
596 CHECK_BYTECODE_INDEX(i);
604 i = code_get_u1(p + 1,m);
607 i = code_get_u2(p + 1,m);
613 OP1LOAD(opcode, i + firstlocal);
623 /* zero val.a so no patcher is inserted */
624 /* the type checker may set this later */
631 /* zero val.a so no patcher is inserted */
632 /* the type checker may set this later */
638 /* table jumps ********************************************************/
640 case JAVA_LOOKUPSWITCH:
644 #if defined(ENABLE_VERIFIER)
649 nextp = ALIGN((p + 1), 4);
651 CHECK_END_OF_BYTECODE(nextp + 8);
653 tablep = (s4 *) (m->jcode + nextp);
655 OP2A(opcode, 0, tablep, currentline);
659 j = p + code_get_s4(nextp, m);
660 *tablep = j; /* restore for little endian */
663 CHECK_BYTECODE_INDEX(j);
666 /* number of pairs */
668 num = code_get_u4(nextp, m);
673 CHECK_END_OF_BYTECODE(nextp + 8 * num);
675 for (i = 0; i < num; i++) {
678 j = code_get_s4(nextp, m);
679 *tablep = j; /* restore for little endian */
683 #if defined(ENABLE_VERIFIER)
684 /* check if the lookup table is sorted correctly */
686 if (i && (j <= prevvalue)) {
687 *exceptionptr = new_verifyerror(m, "Unsorted lookup switch");
695 j = p + code_get_s4(nextp,m);
696 *tablep = j; /* restore for little endian */
699 CHECK_BYTECODE_INDEX(j);
707 case JAVA_TABLESWITCH:
713 nextp = ALIGN((p + 1), 4);
715 CHECK_END_OF_BYTECODE(nextp + 12);
717 tablep = (s4 *) (m->jcode + nextp);
719 OP2A(opcode, 0, tablep, currentline);
723 j = p + code_get_s4(nextp, m);
724 *tablep = j; /* restore for little endian */
727 CHECK_BYTECODE_INDEX(j);
732 j = code_get_s4(nextp, m);
733 *tablep = j; /* restore for little endian */
739 num = code_get_s4(nextp, m);
740 *tablep = num; /* restore for little endian */
744 num -= j; /* difference of upper - lower */
746 #if defined(ENABLE_VERIFIER)
748 *exceptionptr = new_verifyerror(m,
749 "invalid TABLESWITCH: upper bound < lower bound");
754 CHECK_END_OF_BYTECODE(nextp + 4 * (num + 1));
756 for (i = 0; i <= num; i++) {
757 j = p + code_get_s4(nextp,m);
758 *tablep = j; /* restore for little endian */
761 CHECK_BYTECODE_INDEX(j);
769 /* load and store of object fields ************************************/
773 m->isleafmethod = false;
782 unresolved_field *uf;
785 i = code_get_u2(p + 1, m);
786 fr = class_getconstant(m->class, i,
791 OP2A_NOINC(opcode, fr->parseddesc.fd->type, fr, currentline);
793 if (!(uf = create_unresolved_field(m->class,
798 /* store unresolved_field pointer */
802 /* only with -noverify, otherwise the typechecker does this */
805 if (!resolve_field(uf, resolveLazy, &fi))
819 /* method invocation **************************************************/
821 case JAVA_INVOKESTATIC:
822 i = code_get_u2(p + 1, m);
826 unresolved_method *um;
829 m->isleafmethod = false;
831 mr = class_getconstant(m->class, i,
836 md = mr->parseddesc.md;
839 if (!descriptor_params_from_paramtypes(md, ACC_STATIC))
842 OP2A_NOINC(opcode, 0, mr, currentline);
844 um = create_unresolved_method(m->class,
850 /* store the unresolved_method pointer */
854 /* only with -noverify, otherwise the typechecker does this */
857 if (!resolve_method(um, resolveLazy, &mi))
869 case JAVA_INVOKESPECIAL:
870 case JAVA_INVOKEVIRTUAL:
874 unresolved_method *um;
877 m->isleafmethod = false;
879 i = code_get_u2(p + 1, m);
880 mr = class_getconstant(m->class, i,
885 md = mr->parseddesc.md;
888 if (!descriptor_params_from_paramtypes(md, 0))
891 OP2A_NOINC(opcode, 0, mr, currentline);
893 um = create_unresolved_method(m->class,
899 /* store the unresolved_method* */
903 /* only with -noverify, otherwise the typechecker does this */
906 if (!resolve_method(um, resolveLazy, &mi))
918 case JAVA_INVOKEINTERFACE:
919 i = code_get_u2(p + 1, m);
923 unresolved_method *um;
926 m->isleafmethod = false;
928 mr = class_getconstant(m->class, i,
929 CONSTANT_InterfaceMethodref);
933 md = mr->parseddesc.md;
936 if (!descriptor_params_from_paramtypes(md, 0))
939 OP2A_NOINC(opcode, 0, mr, currentline);
941 um = create_unresolved_method(m->class,
947 /* store the unresolved_method* */
951 /* only with -noverify, otherwise the typechecker does this */
954 if (!resolve_method(um, resolveLazy, &mi))
966 /* miscellaneous object operations ************************************/
969 i = code_get_u2(p + 1, m);
970 cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
974 if (!resolve_classref(m, cr, resolveLazy, true, true,
978 LOADCONST_A_BUILTIN(c, cr);
979 bte = builtintable_get_internal(BUILTIN_new);
980 BUILTIN(bte, true, NULL, currentline);
985 i = code_get_u2(p + 1, m);
986 cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
990 if (!resolve_classref(m, cr, resolveLazy, true,
994 if (cr->name->text[0] == '[') {
995 /* array type cast-check */
996 OP2AT(opcode, 0, c, cr, currentline);
997 m->isleafmethod = false;
1001 /* object type cast-check */
1002 OP2AT(opcode, 1, c, cr, currentline);
1006 case JAVA_INSTANCEOF:
1007 i = code_get_u2(p + 1,m);
1008 cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
1012 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
1015 if (cr->name->text[0] == '[') {
1016 /* array type cast-check */
1017 LOADCONST_A_BUILTIN(c, cr);
1018 bte = builtintable_get_internal(BUILTIN_arrayinstanceof);
1019 BUILTIN(bte, false, NULL, currentline);
1024 /* object type cast-check */
1025 OP2AT(opcode, 1, c, cr, currentline);
1029 case JAVA_MONITORENTER:
1030 #if defined(USE_THREADS)
1033 bte = builtintable_get_internal(BUILTIN_monitorenter);
1034 BUILTIN(bte, false, NULL, currentline);
1044 case JAVA_MONITOREXIT:
1045 #if defined(USE_THREADS)
1047 bte = builtintable_get_internal(BUILTIN_monitorexit);
1048 BUILTIN(bte, false, NULL, currentline);
1057 /* any other basic operation ******************************************/
1060 #if !SUPPORT_DIVISION
1061 bte = builtintable_get_internal(BUILTIN_idiv);
1062 OP2A(opcode, bte->md->paramcount, bte, currentline);
1063 m->isleafmethod = false;
1070 #if !SUPPORT_DIVISION
1071 bte = builtintable_get_internal(BUILTIN_irem);
1072 OP2A(opcode, bte->md->paramcount, bte, currentline);
1073 m->isleafmethod = false;
1080 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1081 bte = builtintable_get_internal(BUILTIN_ldiv);
1082 OP2A(opcode, bte->md->paramcount, bte, currentline);
1083 m->isleafmethod = false;
1090 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1091 bte = builtintable_get_internal(BUILTIN_lrem);
1092 OP2A(opcode, bte->md->paramcount, bte, currentline);
1093 m->isleafmethod = false;
1100 #if defined(__I386__)
1103 bte = builtintable_get_internal(BUILTIN_frem);
1104 BUILTIN(bte, false, NULL, currentline);
1109 #if defined(__I386__)
1112 bte = builtintable_get_internal(BUILTIN_drem);
1113 BUILTIN(bte, false, NULL, currentline);
1118 #if defined(__ALPHA__)
1120 bte = builtintable_get_internal(BUILTIN_f2i);
1121 BUILTIN(bte, false, NULL, currentline);
1131 #if defined(__ALPHA__)
1133 bte = builtintable_get_internal(BUILTIN_f2l);
1134 BUILTIN(bte, false, NULL, currentline);
1144 #if defined(__ALPHA__)
1146 bte = builtintable_get_internal(BUILTIN_d2i);
1147 BUILTIN(bte, false, NULL, currentline);
1157 #if defined(__ALPHA__)
1159 bte = builtintable_get_internal(BUILTIN_d2l);
1160 BUILTIN(bte, false, NULL, currentline);
1169 case JAVA_BREAKPOINT:
1171 new_verifyerror(m, "Quick instructions shouldn't appear yet.");
1174 case 186: /* unused opcode */
1229 new_verifyerror(m,"Illegal opcode %d at instr %d\n",
1240 /* If WIDE was used correctly, iswide should have been reset by now. */
1241 if (iswide && opcode != JAVA_WIDE) {
1242 *exceptionptr = new_verifyerror(m,
1243 "Illegal instruction: WIDE before incompatible opcode");
1249 if (p != m->jcodelength) {
1250 printf("p (%d) != m->jcodelength (%d)\n",p,m->jcodelength);
1251 *exceptionptr = new_verifyerror(m,
1252 "Command-sequence crosses code-boundary");
1257 *exceptionptr = new_verifyerror(m, "Falling off the end of the code");
1261 /* adjust block count if target 0 is not first intermediate instruction */
1263 if (!m->basicblockindex[0] || (m->basicblockindex[0] > 1))
1266 /* copy local to method variables */
1268 m->instructioncount = ipc;
1269 m->basicblockcount = b_count;
1270 m->stackcount = s_count + m->basicblockcount * m->maxstack;
1272 /* allocate stack table */
1274 m->stack = DMNEW(stackelement, m->stackcount);
1279 bptr = m->basicblocks = DMNEW(basicblock, b_count + 1); /* one more for end ipc */
1284 /* additional block if target 0 is not first intermediate instruction */
1286 if (!m->basicblockindex[0] || (m->basicblockindex[0] > 1)) {
1287 BASICBLOCK_INIT(bptr,m);
1289 bptr->iinstr = m->instructions;
1290 /* bptr->icount is set when the next block is allocated */
1294 bptr[-1].next = bptr;
1297 /* allocate blocks */
1299 for (p = 0; p < m->jcodelength; p++) {
1300 if (m->basicblockindex[p] & 1) {
1301 /* Check if this block starts at the beginning of an */
1304 if (!instructionstart[p]) {
1305 *exceptionptr = new_verifyerror(m,
1306 "Branch into middle of instruction");
1310 /* allocate the block */
1312 BASICBLOCK_INIT(bptr,m);
1314 bptr->iinstr = m->instructions + (m->basicblockindex[p] >> 1);
1316 bptr[-1].icount = bptr->iinstr - bptr[-1].iinstr;
1318 /* bptr->icount is set when the next block is allocated */
1320 m->basicblockindex[p] = b_count;
1324 bptr[-1].next = bptr;
1328 /* set instruction count of last real block */
1331 bptr[-1].icount = (m->instructions + m->instructioncount) - bptr[-1].iinstr;
1334 /* allocate additional block at end */
1336 BASICBLOCK_INIT(bptr,m);
1338 bptr->instack = bptr->outstack = NULL;
1339 bptr->indepth = bptr->outdepth = 0;
1340 bptr->iinstr = NULL;
1344 /* set basicblock pointers in exception table */
1346 if (cd->exceptiontablelength > 0) {
1347 cd->exceptiontable[cd->exceptiontablelength - 1].down = NULL;
1350 for (i = 0; i < cd->exceptiontablelength; ++i) {
1351 p = cd->exceptiontable[i].startpc;
1352 cd->exceptiontable[i].start = m->basicblocks + m->basicblockindex[p];
1354 p = cd->exceptiontable[i].endpc;
1355 cd->exceptiontable[i].end = (p == m->jcodelength) ? (m->basicblocks + m->basicblockcount /*+ 1*/) : (m->basicblocks + m->basicblockindex[p]);
1357 p = cd->exceptiontable[i].handlerpc;
1358 cd->exceptiontable[i].handler = m->basicblocks + m->basicblockindex[p];
1361 /* XXX activate this if you want to try inlining */
1363 for (i = 0; i < m->exceptiontablelength; ++i) {
1364 p = m->exceptiontable[i].startpc;
1365 m->exceptiontable[i].start = m->basicblocks + m->basicblockindex[p];
1367 p = m->exceptiontable[i].endpc;
1368 m->exceptiontable[i].end = (p == m->jcodelength) ? (m->basicblocks + m->basicblockcount /*+ 1*/) : (m->basicblocks + m->basicblockindex[p]);
1370 p = m->exceptiontable[i].handlerpc;
1371 m->exceptiontable[i].handler = m->basicblocks + m->basicblockindex[p];
1377 /* just return methodinfo* to signal everything was ok */
1381 #if defined(ENABLE_VERIFIER)
1382 throw_unexpected_end_of_bytecode:
1383 *exceptionptr = new_verifyerror(m, "Unexpected end of bytecode");
1386 throw_invalid_bytecode_index:
1388 new_verifyerror(m, "Illegal target of branch instruction");
1390 #endif /* ENABLE_VERIFIER */
1395 * These are local overrides for various environment variables in Emacs.
1396 * Please do not remove this and leave it at the end of the file, where
1397 * Emacs will automagically detect them.
1398 * ---------------------------------------------------------------------
1401 * indent-tabs-mode: t
1405 * vim:noexpandtab:sw=4:ts=4: