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 4449 2006-02-05 23:02:05Z edwin $
46 #include "mm/memory.h"
47 #include "native/native.h"
48 #include "toolbox/logging.h"
49 #include "vm/builtin.h"
50 #include "vm/exceptions.h"
51 #include "vm/global.h"
52 #include "vm/linker.h"
53 #include "vm/loader.h"
54 #include "vm/resolve.h"
55 #include "vm/options.h"
56 #include "vm/statistics.h"
57 #include "vm/stringlocal.h"
58 #include "vm/jit/asmpart.h"
59 #include "vm/jit/jit.h"
60 #include "vm/jit/parse.h"
61 #include "vm/jit/patcher.h"
62 #include "vm/jit/loop/loop.h"
64 /*******************************************************************************
66 function 'parse' scans the JavaVM code and generates intermediate code
68 During parsing the block index table is used to store at bit pos 0
69 a flag which marks basic block starts and at position 1 to 31 the
70 intermediate instruction index. After parsing the block index table
71 is scanned, for marked positions a block is generated and the block
72 number is stored in the block index table.
74 *******************************************************************************/
76 static exceptiontable * fillextable(methodinfo *m,
77 exceptiontable *extable,
78 exceptiontable *raw_extable,
79 int exceptiontablelength,
83 int b_count, p, src, insertBlock;
85 if (exceptiontablelength == 0)
88 b_count = *block_count;
90 for (src = exceptiontablelength-1; src >=0; src--) {
91 p = raw_extable[src].startpc;
92 if (label_index != NULL) p = label_index[p];
97 p = raw_extable[src].endpc; /* see JVM Spec 4.7.3 */
98 if (p <= raw_extable[src].startpc) {
99 *exceptionptr = new_verifyerror(m,
100 "Invalid exception handler range");
104 if (p >m->jcodelength) {
105 *exceptionptr = new_verifyerror(m,
106 "Invalid exception handler end is after code end");
110 if (p<m->jcodelength) insertBlock=1; else insertBlock=0;
111 if (label_index != NULL) p = label_index[p];
113 bound_check_exclusive(p);
114 /* if (p < m->jcodelength) block_insert(p); */
118 p = raw_extable[src].handlerpc;
119 if (label_index != NULL) p = label_index[p];
120 extable->handlerpc = p;
124 extable->catchtype = raw_extable[src].catchtype;
125 extable->next = NULL;
126 extable->down = &extable[1];
130 *block_count = b_count;
131 return extable; /*&extable[i];*/ /* return the next free xtable* */
136 methodinfo *parse(methodinfo *m, codegendata *cd)
138 int p; /* java instruction counter */
139 int nextp; /* start of next java instruction */
140 int opcode; /* java opcode */
141 int i; /* temporary for different uses (ctrs)*/
142 int ipc = 0; /* intermediate instruction counter */
143 int b_count = 0; /* basic block counter */
144 int s_count = 0; /* stack element counter */
145 bool blockend = false; /* true if basic block end has been reached */
146 bool iswide = false; /* true if last instruction was a wide*/
147 instruction *iptr; /* current ptr into instruction array */
148 int gp; /* global java instruction counter */
150 int *label_index = NULL; /* label redirection table */
151 int firstlocal = 0; /* first local variable of method */
152 exceptiontable* nextex; /* points next free entry in extable */
153 u1 *instructionstart; /* 1 for pcs which are valid instr. starts */
155 constant_classref *cr;
156 constant_classref *compr;
158 builtintable_entry *bte;
164 u2 skipBasicBlockChange;
166 /* allocate instruction array and block index table */
168 /* 1 additional for end ipc */
169 m->basicblockindex = DMNEW(s4, m->jcodelength + 1);
170 memset(m->basicblockindex, 0, sizeof(s4) * (m->jcodelength + 1));
172 instructionstart = DMNEW(u1, m->jcodelength + 1);
173 memset(instructionstart, 0, sizeof(u1) * (m->jcodelength + 1));
175 /* 1 additional for TRACEBUILTIN and 4 for MONITORENTER/EXIT */
176 /* additional MONITOREXITS are reached by branches which are 3 bytes */
178 iptr = m->instructions = DMNEW(instruction, m->jcodelength + 5);
180 /* Zero the intermediate instructions array so we don't have any
181 * invalid pointers in it if we cannot finish analyse_stack(). */
183 memset(iptr, 0, sizeof(instruction) * (m->jcodelength + 5));
185 /* compute branch targets of exception table */
187 nextex = fillextable(m,
188 &(cd->exceptiontable[cd->exceptiontablelength-1]), m->exceptiontable, m->exceptiontablelength,
189 label_index, &b_count);
192 s_count = 1 + m->exceptiontablelength; /* initialize stack element counter */
194 #if defined(USE_THREADS)
195 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
196 m->isleafmethod = false;
200 /* scan all java instructions */
204 if (m->linenumbercount == 0) {
207 linepcchange = m->linenumbers[0].start_pc;
210 skipBasicBlockChange=0;
211 for (p = 0, gp = 0; p < m->jcodelength; gp += (nextp - p), p = nextp) {
213 /* mark this position as a valid instruction start */
215 instructionstart[gp] = 1;
216 if (linepcchange==p) {
217 if (m->linenumbercount > lineindex) {
218 currentline = m->linenumbers[lineindex].line_number;
220 if (lineindex < m->linenumbercount)
221 linepcchange = m->linenumbers[lineindex].start_pc;
226 /* fetch next opcode */
228 opcode = code_get_u1(p, m);
230 if (!skipBasicBlockChange) {
231 m->basicblockindex[gp] |= (ipc << 1); /*store intermed cnt*/
232 } else skipBasicBlockChange=0;
234 /* some compilers put a JAVA_NOP after a blockend instruction */
236 if ((opcode != JAVA_NOP) && (blockend == true)) {
237 /* start new block */
243 nextp = p + jcommandsize[opcode]; /* compute next instruction start */
245 if (nextp > m->jcodelength) {
246 *exceptionptr = new_verifyerror(m,
247 "Unexpected end of bytecode");
251 s_count += stackreq[opcode]; /* compute stack element count */
256 /* pushing constants onto the stack p */
259 LOADCONST_I(code_get_s1(p+1,m));
263 LOADCONST_I(code_get_s2(p+1,m));
267 i = code_get_u1(p + 1, m);
268 goto pushconstantitem;
272 i = code_get_u2(p + 1, m);
276 if (i >= m->class->cpcount) {
277 *exceptionptr = new_verifyerror(m,
278 "Attempt to access constant outside range");
282 switch (m->class->cptags[i]) {
283 case CONSTANT_Integer:
284 LOADCONST_I(((constant_integer *) (m->class->cpinfos[i]))->value);
287 LOADCONST_L(((constant_long *) (m->class->cpinfos[i]))->value);
290 LOADCONST_F(((constant_float *) (m->class->cpinfos[i]))->value);
292 case CONSTANT_Double:
293 LOADCONST_D(((constant_double *) (m->class->cpinfos[i]))->value);
295 case CONSTANT_String:
296 LOADCONST_A(literalstring_new((utf *) (m->class->cpinfos[i])));
299 cr = (constant_classref *) (m->class->cpinfos[i]);
301 if (!resolve_classref(m, cr, resolveLazy, true,
305 /* if not resolved, c == NULL */
307 LOADCONST_A_CLASS(c, cr);
310 *exceptionptr = new_verifyerror(m,
311 "Invalid constant type to push");
316 case JAVA_ACONST_NULL:
327 LOADCONST_I(opcode - JAVA_ICONST_0);
332 LOADCONST_L(opcode - JAVA_LCONST_0);
338 LOADCONST_F(opcode - JAVA_FCONST_0);
343 LOADCONST_D(opcode - JAVA_DCONST_0);
346 /* loading variables onto the stack */
354 i = code_get_u1(p + 1,m);
356 i = code_get_u2(p + 1,m);
360 OP1LOAD(opcode, i + firstlocal);
367 OP1LOAD(ICMD_ILOAD, opcode - JAVA_ILOAD_0 + firstlocal);
374 OP1LOAD(ICMD_LLOAD, opcode - JAVA_LLOAD_0 + firstlocal);
381 OP1LOAD(ICMD_FLOAD, opcode - JAVA_FLOAD_0 + firstlocal);
388 OP1LOAD(ICMD_DLOAD, opcode - JAVA_DLOAD_0 + firstlocal);
395 OP1LOAD(ICMD_ALOAD, opcode - JAVA_ALOAD_0 + firstlocal);
398 /* storing stack values into local variables */
406 i = code_get_u1(p + 1,m);
408 i = code_get_u2(p + 1,m);
412 OP1STORE(opcode, i + firstlocal);
419 OP1STORE(ICMD_ISTORE, opcode - JAVA_ISTORE_0 + firstlocal);
426 OP1STORE(ICMD_LSTORE, opcode - JAVA_LSTORE_0 + firstlocal);
433 OP1STORE(ICMD_FSTORE, opcode - JAVA_FSTORE_0 + firstlocal);
440 OP1STORE(ICMD_DSTORE, opcode - JAVA_DSTORE_0 + firstlocal);
447 OP1STORE(ICMD_ASTORE, opcode - JAVA_ASTORE_0 + firstlocal);
455 i = code_get_u1(p + 1,m);
456 v = code_get_s1(p + 2,m);
459 i = code_get_u2(p + 1,m);
460 v = code_get_s2(p + 3,m);
464 INDEX_ONEWORD(i + firstlocal);
465 OP2I(opcode, i + firstlocal, v);
469 /* wider index for loading, storing and incrementing */
476 /* managing arrays ****************************************************/
479 switch (code_get_s1(p + 1, m)) {
481 bte = builtintable_get_internal(BUILTIN_newarray_boolean);
484 bte = builtintable_get_internal(BUILTIN_newarray_char);
487 bte = builtintable_get_internal(BUILTIN_newarray_float);
490 bte = builtintable_get_internal(BUILTIN_newarray_double);
493 bte = builtintable_get_internal(BUILTIN_newarray_byte);
496 bte = builtintable_get_internal(BUILTIN_newarray_short);
499 bte = builtintable_get_internal(BUILTIN_newarray_int);
502 bte = builtintable_get_internal(BUILTIN_newarray_long);
505 *exceptionptr = new_verifyerror(m,
506 "Invalid array-type to create");
509 BUILTIN(bte, true, NULL, currentline);
513 i = code_get_u2(p + 1, m);
514 compr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
518 if (!(cr = class_get_classref_multiarray_of(1, compr)))
521 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
524 LOADCONST_A_BUILTIN(c, cr);
525 bte = builtintable_get_internal(BUILTIN_newarray);
526 BUILTIN(bte, true, NULL, currentline);
530 case JAVA_MULTIANEWARRAY:
531 m->isleafmethod = false;
532 i = code_get_u2(p + 1, m);
534 s4 v = code_get_u1(p + 3, m);
536 cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
540 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
543 /* if unresolved, c == NULL */
544 OP2AT(opcode, v, c, cr, currentline);
566 i = p + code_get_s2(p + 1,m);
575 i = p + code_get_s4(p + 1,m);
584 i = code_get_u1(p + 1,m);
586 i = code_get_u2(p + 1,m);
592 OP1LOAD(opcode, i + firstlocal);
602 /* zero val.a so no patcher is inserted */
603 /* the type checker may set this later */
610 /* zero val.a so no patcher is inserted */
611 /* the type checker may set this later */
617 /* table jumps ********************************************************/
619 case JAVA_LOOKUPSWITCH:
626 nextp = ALIGN((p + 1), 4);
628 if (nextp + 8 > m->jcodelength) {
629 *exceptionptr = new_verifyerror(m,
630 "Unexpected end of bytecode");
634 tablep = (s4 *) (m->jcode + nextp);
636 OP2A(opcode, 0, tablep, currentline);
640 j = p + code_get_s4(nextp, m);
641 *tablep = j; /* restore for little endian */
647 /* number of pairs */
649 num = code_get_u4(nextp, m);
654 if (nextp + 8 * num > m->jcodelength) {
655 *exceptionptr = new_verifyerror(m,
656 "Unexpected end of bytecode");
660 for (i = 0; i < num; i++) {
663 j = code_get_s4(nextp, m);
664 *tablep = j; /* restore for little endian */
668 /* check if the lookup table is sorted correctly */
670 if (i && (j <= prevvalue)) {
671 *exceptionptr = new_verifyerror(m, "Unsorted lookup switch");
678 j = p + code_get_s4(nextp,m);
679 *tablep = j; /* restore for little endian */
690 case JAVA_TABLESWITCH:
696 nextp = ALIGN((p + 1), 4);
697 if (nextp + 12 > m->jcodelength) {
698 *exceptionptr = new_verifyerror(m,
699 "Unexpected end of bytecode");
703 tablep = (s4 *) (m->jcode + nextp);
705 OP2A(opcode, 0, tablep, currentline);
709 j = p + code_get_s4(nextp, m);
710 *tablep = j; /* restore for little endian */
718 j = code_get_s4(nextp, m);
719 *tablep = j; /* restore for little endian */
725 num = code_get_s4(nextp, m);
726 *tablep = num; /* restore for little endian */
730 num -= j; /* difference of upper - lower */
733 *exceptionptr = new_verifyerror(m,
734 "invalid TABLESWITCH: upper bound < lower bound");
738 if (nextp + 4 * (num + 1) > m->jcodelength) {
739 *exceptionptr = new_verifyerror(m,
740 "Unexpected end of bytecode");
744 for (i = 0; i <= num; i++) {
745 j = p + code_get_s4(nextp,m);
746 *tablep = j; /* restore for little endian */
757 /* load and store of object fields ************************************/
761 m->isleafmethod = false;
770 unresolved_field *uf;
773 i = code_get_u2(p + 1, m);
774 fr = class_getconstant(m->class, i,
779 OP2A_NOINC(opcode, fr->parseddesc.fd->type, fr, currentline);
781 if (!(uf = create_unresolved_field(m->class,
786 /* store unresolved_field pointer */
790 /* only with -noverify, otherwise the typechecker does this */
793 if (!resolve_field(uf, resolveLazy, &fi))
806 /* method invocation **************************************************/
808 case JAVA_INVOKESTATIC:
809 i = code_get_u2(p + 1, m);
813 unresolved_method *um;
816 m->isleafmethod = false;
818 mr = class_getconstant(m->class, i,
823 md = mr->parseddesc.md;
826 if (!descriptor_params_from_paramtypes(md, ACC_STATIC))
829 OP2A_NOINC(opcode, 0, mr, currentline);
831 um = create_unresolved_method(m->class,
837 /* store the unresolved_method pointer */
841 /* only with -noverify, otherwise the typechecker does this */
844 if (!resolve_method(um, resolveLazy, &mi))
856 case JAVA_INVOKESPECIAL:
857 case JAVA_INVOKEVIRTUAL:
861 unresolved_method *um;
864 m->isleafmethod = false;
866 i = code_get_u2(p + 1, m);
867 mr = class_getconstant(m->class, i,
872 md = mr->parseddesc.md;
875 if (!descriptor_params_from_paramtypes(md, 0))
878 OP2A_NOINC(opcode, 0, mr, currentline);
880 um = create_unresolved_method(m->class,
886 /* store the unresolved_method* */
890 /* only with -noverify, otherwise the typechecker does this */
893 if (!resolve_method(um, resolveLazy, &mi))
905 case JAVA_INVOKEINTERFACE:
906 i = code_get_u2(p + 1, m);
910 unresolved_method *um;
913 m->isleafmethod = false;
915 mr = class_getconstant(m->class, i,
916 CONSTANT_InterfaceMethodref);
920 md = mr->parseddesc.md;
923 if (!descriptor_params_from_paramtypes(md, 0))
926 OP2A_NOINC(opcode, 0, mr, currentline);
928 um = create_unresolved_method(m->class,
934 /* store the unresolved_method* */
938 /* only with -noverify, otherwise the typechecker does this */
941 if (!resolve_method(um, resolveLazy, &mi))
953 /* miscellaneous object operations ************************************/
956 i = code_get_u2(p + 1, m);
957 cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
961 if (!resolve_classref(m, cr, resolveLazy, true, true,
965 LOADCONST_A_BUILTIN(c, cr);
966 bte = builtintable_get_internal(BUILTIN_new);
967 BUILTIN(bte, true, NULL, currentline);
972 i = code_get_u2(p + 1, m);
973 cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
977 if (!resolve_classref(m, cr, resolveLazy, true,
981 if (cr->name->text[0] == '[') {
982 /* array type cast-check */
983 OP2AT(opcode, 0, c, cr, currentline);
984 m->isleafmethod = false;
987 /* object type cast-check */
988 OP2AT(opcode, 1, c, cr, currentline);
992 case JAVA_INSTANCEOF:
993 i = code_get_u2(p + 1,m);
994 cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
998 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
1001 if (cr->name->text[0] == '[') {
1002 /* array type cast-check */
1003 LOADCONST_A_BUILTIN(c, cr);
1004 bte = builtintable_get_internal(BUILTIN_arrayinstanceof);
1005 BUILTIN(bte, false, NULL, currentline);
1009 /* object type cast-check */
1010 OP2AT(opcode, 1, c, cr, currentline);
1014 case JAVA_MONITORENTER:
1015 #if defined(USE_THREADS)
1018 bte = builtintable_get_internal(BUILTIN_monitorenter);
1019 BUILTIN(bte, false, NULL, currentline);
1028 case JAVA_MONITOREXIT:
1029 #if defined(USE_THREADS)
1031 bte = builtintable_get_internal(BUILTIN_monitorexit);
1032 BUILTIN(bte, false, NULL, currentline);
1040 /* any other basic operation ******************************************/
1043 #if !SUPPORT_DIVISION
1044 bte = builtintable_get_internal(BUILTIN_idiv);
1045 OP2A(opcode, bte->md->paramcount, bte, currentline);
1046 m->isleafmethod = false;
1053 #if !SUPPORT_DIVISION
1054 bte = builtintable_get_internal(BUILTIN_irem);
1055 OP2A(opcode, bte->md->paramcount, bte, currentline);
1056 m->isleafmethod = false;
1063 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1064 bte = builtintable_get_internal(BUILTIN_ldiv);
1065 OP2A(opcode, bte->md->paramcount, bte, currentline);
1066 m->isleafmethod = false;
1073 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1074 bte = builtintable_get_internal(BUILTIN_lrem);
1075 OP2A(opcode, bte->md->paramcount, bte, currentline);
1076 m->isleafmethod = false;
1083 #if defined(__I386__)
1086 bte = builtintable_get_internal(BUILTIN_frem);
1087 BUILTIN(bte, false, NULL, currentline);
1092 #if defined(__I386__)
1095 bte = builtintable_get_internal(BUILTIN_drem);
1096 BUILTIN(bte, false, NULL, currentline);
1101 #if defined(__ALPHA__)
1103 bte = builtintable_get_internal(BUILTIN_f2i);
1104 BUILTIN(bte, false, NULL, currentline);
1113 #if defined(__ALPHA__)
1115 bte = builtintable_get_internal(BUILTIN_f2l);
1116 BUILTIN(bte, false, NULL, currentline);
1125 #if defined(__ALPHA__)
1127 bte = builtintable_get_internal(BUILTIN_d2i);
1128 BUILTIN(bte, false, NULL, currentline);
1137 #if defined(__ALPHA__)
1139 bte = builtintable_get_internal(BUILTIN_d2l);
1140 BUILTIN(bte, false, NULL, currentline);
1148 case JAVA_BREAKPOINT:
1150 new_verifyerror(m, "Quick instructions shouldn't appear yet.");
1153 case 186: /* unused opcode */
1208 new_verifyerror(m,"Illegal opcode %d at instr %d\n",
1219 /* If WIDE was used correctly, iswide should have been reset by now. */
1220 if (iswide && opcode != JAVA_WIDE) {
1221 *exceptionptr = new_verifyerror(m,
1222 "Illegal instruction: WIDE before incompatible opcode");
1228 if (p != m->jcodelength) {
1229 printf("p (%d) != m->jcodelength (%d)\n",p,m->jcodelength);
1230 *exceptionptr = new_verifyerror(m,
1231 "Command-sequence crosses code-boundary");
1236 *exceptionptr = new_verifyerror(m, "Falling off the end of the code");
1240 /* adjust block count if target 0 is not first intermediate instruction */
1242 if (!m->basicblockindex[0] || (m->basicblockindex[0] > 1))
1245 /* copy local to method variables */
1247 m->instructioncount = ipc;
1248 m->basicblockcount = b_count;
1249 m->stackcount = s_count + m->basicblockcount * m->maxstack;
1251 /* allocate stack table */
1253 m->stack = DMNEW(stackelement, m->stackcount);
1258 bptr = m->basicblocks = DMNEW(basicblock, b_count + 1); /* one more for end ipc */
1263 /* additional block if target 0 is not first intermediate instruction */
1265 if (!m->basicblockindex[0] || (m->basicblockindex[0] > 1)) {
1266 bptr->iinstr = m->instructions;
1269 bptr->type = BBTYPE_STD;
1270 bptr->branchrefs = NULL;
1271 bptr->pre_count = 0;
1272 bptr->debug_nr = m->c_debug_nr++;
1275 (bptr - 1)->next = bptr;
1278 /* allocate blocks */
1280 for (p = 0; p < m->jcodelength; p++) {
1281 /* for (p = 0; p < m->jcodelength; p++) { */
1282 if (m->basicblockindex[p] & 1) {
1283 /* Check if this block starts at the beginning of an */
1286 if (!instructionstart[p]) {
1287 *exceptionptr = new_verifyerror(m,
1288 "Branch into middle of instruction");
1292 /* allocate the block */
1293 bptr->iinstr = m->instructions + (m->basicblockindex[p] >> 1);
1294 bptr->debug_nr = m->c_debug_nr++;
1296 (bptr - 1)->icount = bptr->iinstr - (bptr - 1)->iinstr;
1300 bptr->type = BBTYPE_STD;
1301 bptr->branchrefs = NULL;
1302 m->basicblockindex[p] = b_count;
1303 bptr->pre_count = 0;
1306 (bptr - 1)->next = bptr;
1310 /* allocate additional block at end */
1312 bptr->instack = bptr->outstack = NULL;
1313 bptr->indepth = bptr->outdepth = 0;
1314 bptr->iinstr = NULL;
1315 (bptr - 1)->icount = (m->instructions + m->instructioncount) - (bptr - 1)->iinstr;
1320 bptr->type = BBTYPE_STD;
1321 bptr->branchrefs = NULL;
1322 bptr->pre_count = 0;
1323 bptr->debug_nr = m->c_debug_nr++;
1324 (bptr - 1)->next = bptr;
1327 if (cd->exceptiontablelength > 0) {
1328 cd->exceptiontable[cd->exceptiontablelength - 1].down = NULL;
1331 for (i = 0; i < cd->exceptiontablelength; ++i) {
1332 p = cd->exceptiontable[i].startpc;
1333 cd->exceptiontable[i].start = m->basicblocks + m->basicblockindex[p];
1335 p = cd->exceptiontable[i].endpc;
1336 cd->exceptiontable[i].end = (p == m->jcodelength) ? (m->basicblocks + m->basicblockcount /*+ 1*/) : (m->basicblocks + m->basicblockindex[p]);
1338 p = cd->exceptiontable[i].handlerpc;
1339 cd->exceptiontable[i].handler = m->basicblocks + m->basicblockindex[p];
1343 /* just return methodinfo* to signal everything was ok */
1350 * These are local overrides for various environment variables in Emacs.
1351 * Please do not remove this and leave it at the end of the file, where
1352 * Emacs will automagically detect them.
1353 * ---------------------------------------------------------------------
1356 * indent-tabs-mode: t
1360 * vim:noexpandtab:sw=4:ts=4: