* Updated header: Added 2006. Changed address of FSF. Changed email
[cacao.git] / src / vm / jit / parse.c
1 /* src/vm/jit/parse.c - parser for JavaVM to intermediate code translation
2
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
7
8    This file is part of CACAO.
9
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.
14
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.
19
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
23    02110-1301, USA.
24
25    Contact: cacao@cacaojvm.org
26
27    Author: Andreas Krall
28
29    Changes: Carolyn Oates
30             Edwin Steiner
31             Joseph Wenninger
32             Christian Thalinger
33
34    $Id: parse.c 4357 2006-01-22 23:33:38Z twisti $
35
36 */
37
38
39 #include <assert.h>
40 #include <string.h>
41
42 #include "config.h"
43
44 #include "vm/types.h"
45
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/inline/parseRT.h"
63 #include "vm/jit/inline/parseXTA.h"
64 #include "vm/jit/inline/inline.h"
65 #include "vm/jit/loop/loop.h"
66 #include "vm/jit/inline/parseRTprint.h"
67
68 /*******************************************************************************
69
70         function 'parse' scans the JavaVM code and generates intermediate code
71
72         During parsing the block index table is used to store at bit pos 0
73         a flag which marks basic block starts and at position 1 to 31 the
74         intermediate instruction index. After parsing the block index table
75         is scanned, for marked positions a block is generated and the block
76         number is stored in the block index table.
77
78 *******************************************************************************/
79
80 static exceptiontable * fillextable(methodinfo *m, 
81                                                                         exceptiontable *extable, 
82                                                                         exceptiontable *raw_extable, 
83                                                                 int exceptiontablelength, 
84                                                                         int *label_index, 
85                                                                         int *block_count, 
86                                                                         t_inlining_globals *inline_env)
87 {
88         int b_count, p, src, insertBlock;
89         
90         if (exceptiontablelength == 0) 
91                 return extable;
92
93         b_count = *block_count;
94
95         for (src = exceptiontablelength-1; src >=0; src--) {
96                 p = raw_extable[src].startpc;
97                 if (label_index != NULL) p = label_index[p];
98                 extable->startpc = p;
99                 bound_check(p);
100                 block_insert(p);
101                 
102                 p = raw_extable[src].endpc; /* see JVM Spec 4.7.3 */
103                 if (p <= raw_extable[src].startpc) {
104                         *exceptionptr = new_verifyerror(inline_env->method,
105                                 "Invalid exception handler range");
106                         return NULL;
107                 }
108
109                 if (p >inline_env->method->jcodelength) {
110                         *exceptionptr = new_verifyerror(inline_env->method,
111                                 "Invalid exception handler end is after code end");
112                         return NULL;
113                 }
114
115                 if (p<inline_env->method->jcodelength) insertBlock=1; else insertBlock=0;
116                 if (label_index != NULL) p = label_index[p];
117                 extable->endpc = p;
118                 bound_check1(p);
119                 /* if (p < inline_env->method->jcodelength) block_insert(p); */
120         if (insertBlock) 
121                         block_insert(p);
122
123                 p = raw_extable[src].handlerpc;
124                 if (label_index != NULL) p = label_index[p];
125                 extable->handlerpc = p;
126                 bound_check(p);
127                 block_insert(p);
128
129                 extable->catchtype  = raw_extable[src].catchtype;
130                 extable->next = NULL;
131                 extable->down = &extable[1];
132                 extable--;
133         }
134
135         *block_count = b_count;
136         return extable; /*&extable[i];*/  /* return the next free xtable* */
137 }
138
139
140
141 methodinfo *parse(methodinfo *m, codegendata *cd, t_inlining_globals *inline_env)
142 {
143         int  p;                     /* java instruction counter           */
144         int  nextp;                 /* start of next java instruction     */
145         int  opcode;                /* java opcode                        */
146         int  i;                     /* temporary for different uses (ctrs)*/
147         int  ipc = 0;               /* intermediate instruction counter   */
148         int  b_count = 0;           /* basic block counter                */
149         int  s_count = 0;           /* stack element counter              */
150         bool blockend = false;      /* true if basic block end has been reached   */
151         bool iswide = false;        /* true if last instruction was a wide*/
152         instruction *iptr;          /* current ptr into instruction array */
153         int gp;                     /* global java instruction counter    */
154                                     /* inlining info for current method   */
155
156         inlining_methodinfo *inlinfo = inline_env->inlining_rootinfo;
157         inlining_methodinfo *tmpinlinf;
158         int nextgp = -1;            /* start of next method to be inlined */
159         int *label_index = NULL;    /* label redirection table            */
160         int firstlocal = 0;         /* first local variable of method     */
161         exceptiontable* nextex;     /* points next free entry in extable  */
162         u1 *instructionstart;       /* 1 for pcs which are valid instr. starts    */
163
164         constant_classref  *cr;
165         constant_classref  *compr;
166         classinfo          *c;
167         builtintable_entry *bte;
168
169         u2 lineindex = 0;
170         u2 currentline = 0;
171         u2 linepcchange = 0;
172
173         u2 skipBasicBlockChange;
174
175         /* allocate instruction array and block index table */
176         
177         /* 1 additional for end ipc * # cum inline methods*/
178         
179         m->basicblockindex = DMNEW(s4, inline_env->cumjcodelength + inline_env->cummethods);
180         memset(m->basicblockindex, 0, sizeof(s4) * (inline_env->cumjcodelength + inline_env->cummethods));
181
182         instructionstart = DMNEW(u1, inline_env->cumjcodelength + inline_env->cummethods);
183         memset(instructionstart, 0, sizeof(u1) * (inline_env->cumjcodelength + inline_env->cummethods));
184
185         /* 1 additional for TRACEBUILTIN and 4 for MONITORENTER/EXIT */
186         /* additional MONITOREXITS are reached by branches which are 3 bytes */
187         
188         iptr = m->instructions = DMNEW(instruction, inline_env->cumjcodelength + 5);
189
190         /* Zero the intermediate instructions array so we don't have any
191          * invalid pointers in it if we cannot finish analyse_stack(). */
192
193         memset(iptr, 0, sizeof(instruction) * (inline_env->cumjcodelength + 5));
194         
195         /* compute branch targets of exception table */
196
197         nextex = fillextable(m, 
198           &(cd->exceptiontable[cd->exceptiontablelength-1]), m->exceptiontable, m->exceptiontablelength, 
199           label_index, &b_count, inline_env);
200         if (!nextex)
201                 return NULL;
202         s_count = 1 + m->exceptiontablelength; /* initialize stack element counter   */
203
204 #if defined(USE_THREADS)
205         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
206                 m->isleafmethod = false;
207                 inline_env->method->isleafmethod = false;
208         }                       
209 #endif
210
211         /* scan all java instructions */
212         currentline = 0;
213         linepcchange = 0;
214
215         if (m->linenumbercount == 0) {
216                 lineindex = 0;
217         } else {
218                 linepcchange = m->linenumbers[0].start_pc;
219         }
220
221         skipBasicBlockChange=0;
222         for (p = 0, gp = 0; p < inline_env->method->jcodelength; gp += (nextp - p), p = nextp) {
223           
224                 /* mark this position as a valid instruction start */
225                 if (!iswide) {
226                         instructionstart[gp] = 1;
227                         if (linepcchange==p) {
228                                 if (inline_env->method->linenumbercount > lineindex) {
229                                         currentline = inline_env->method->linenumbers[lineindex].line_number;
230                                         lineindex++;
231                                         if (lineindex < inline_env->method->linenumbercount)
232                                                 linepcchange = inline_env->method->linenumbers[lineindex].start_pc;
233                                 }
234                         }
235                 }
236
237                 /* fetch next opcode  */
238
239                 opcode = code_get_u1(p, inline_env->method);
240
241                 if (!skipBasicBlockChange) {
242                         m->basicblockindex[gp] |= (ipc << 1); /*store intermed cnt*/
243                 } else skipBasicBlockChange=0;
244
245                 /* some compilers put a JAVA_NOP after a blockend instruction */
246
247                 if ((opcode != JAVA_NOP) && (blockend == true)) {
248                         /* start new block */
249
250                         block_insert(gp);
251                         blockend = false;
252                 }
253
254                 nextp = p + jcommandsize[opcode];   /* compute next instruction start */
255
256                 if (nextp > inline_env->method->jcodelength) {
257                         *exceptionptr = new_verifyerror(inline_env->method,
258                                         "Unexpected end of bytecode");
259                         return NULL;
260                 }
261
262                 s_count += stackreq[opcode];            /* compute stack element count    */
263                 switch (opcode) {
264                 case JAVA_NOP:
265                         break;
266
267                         /* pushing constants onto the stack p */
268
269                 case JAVA_BIPUSH:
270                         LOADCONST_I(code_get_s1(p+1,inline_env->method));
271                         break;
272
273                 case JAVA_SIPUSH:
274                         LOADCONST_I(code_get_s2(p+1,inline_env->method));
275                         break;
276
277                 case JAVA_LDC1:
278                         i = code_get_u1(p + 1, inline_env->method);
279                         goto pushconstantitem;
280
281                 case JAVA_LDC2:
282                 case JAVA_LDC2W:
283                         i = code_get_u2(p + 1, inline_env->method);
284
285                 pushconstantitem:
286
287                         if (i >= inline_env->method->class->cpcount) {
288                                 *exceptionptr = new_verifyerror(inline_env->method,
289                                         "Attempt to access constant outside range");
290                                 return NULL;
291                         }
292
293                         switch (inline_env->method->class->cptags[i]) {
294                         case CONSTANT_Integer:
295                                 LOADCONST_I(((constant_integer *) (inline_env->method->class->cpinfos[i]))->value);
296                                 break;
297                         case CONSTANT_Long:
298                                 LOADCONST_L(((constant_long *) (inline_env->method->class->cpinfos[i]))->value);
299                                 break;
300                         case CONSTANT_Float:
301                                 LOADCONST_F(((constant_float *) (inline_env->method->class->cpinfos[i]))->value);
302                                 break;
303                         case CONSTANT_Double:
304                                 LOADCONST_D(((constant_double *) (inline_env->method->class->cpinfos[i]))->value);
305                                 break;
306                         case CONSTANT_String:
307                                 LOADCONST_A(literalstring_new((utf *) (inline_env->method->class->cpinfos[i])));
308                                 break;
309                         case CONSTANT_Class:
310                                 cr = (constant_classref *) (inline_env->method->class->cpinfos[i]);
311
312                                 if (!resolve_classref(inline_env->method, cr, resolveLazy, true,
313                                                                           true, &c))
314                                         return NULL;
315
316                                 /* if not resolved, c == NULL */
317
318                                 LOADCONST_A_CLASS(c, cr);
319                                 break;
320                         default:
321                                 *exceptionptr = new_verifyerror(inline_env->method,
322                                                 "Invalid constant type to push");
323                                 return NULL;
324                         }
325                         break;
326
327                 case JAVA_ACONST_NULL:
328                         LOADCONST_A(NULL);
329                         break;
330
331                 case JAVA_ICONST_M1:
332                 case JAVA_ICONST_0:
333                 case JAVA_ICONST_1:
334                 case JAVA_ICONST_2:
335                 case JAVA_ICONST_3:
336                 case JAVA_ICONST_4:
337                 case JAVA_ICONST_5:
338                         LOADCONST_I(opcode - JAVA_ICONST_0);
339                         break;
340
341                 case JAVA_LCONST_0:
342                 case JAVA_LCONST_1:
343                         LOADCONST_L(opcode - JAVA_LCONST_0);
344                         break;
345
346                 case JAVA_FCONST_0:
347                 case JAVA_FCONST_1:
348                 case JAVA_FCONST_2:
349                         LOADCONST_F(opcode - JAVA_FCONST_0);
350                         break;
351
352                 case JAVA_DCONST_0:
353                 case JAVA_DCONST_1:
354                         LOADCONST_D(opcode - JAVA_DCONST_0);
355                         break;
356
357                         /* loading variables onto the stack */
358
359                 case JAVA_ILOAD:
360                 case JAVA_LLOAD:
361                 case JAVA_FLOAD:
362                 case JAVA_DLOAD:
363                 case JAVA_ALOAD:
364                         if (!iswide) {
365                                 i = code_get_u1(p + 1,inline_env->method);
366                         } else {
367                                 i = code_get_u2(p + 1,inline_env->method);
368                                 nextp = p + 3;
369                                 iswide = false;
370                         }
371                         OP1LOAD(opcode, i + firstlocal);
372                         break;
373
374                 case JAVA_ILOAD_0:
375                 case JAVA_ILOAD_1:
376                 case JAVA_ILOAD_2:
377                 case JAVA_ILOAD_3:
378                         OP1LOAD(ICMD_ILOAD, opcode - JAVA_ILOAD_0 + firstlocal);
379                         break;
380
381                 case JAVA_LLOAD_0:
382                 case JAVA_LLOAD_1:
383                 case JAVA_LLOAD_2:
384                 case JAVA_LLOAD_3:
385                         OP1LOAD(ICMD_LLOAD, opcode - JAVA_LLOAD_0 + firstlocal);
386                         break;
387
388                 case JAVA_FLOAD_0:
389                 case JAVA_FLOAD_1:
390                 case JAVA_FLOAD_2:
391                 case JAVA_FLOAD_3:
392                         OP1LOAD(ICMD_FLOAD, opcode - JAVA_FLOAD_0 + firstlocal);
393                         break;
394
395                 case JAVA_DLOAD_0:
396                 case JAVA_DLOAD_1:
397                 case JAVA_DLOAD_2:
398                 case JAVA_DLOAD_3:
399                         OP1LOAD(ICMD_DLOAD, opcode - JAVA_DLOAD_0 + firstlocal);
400                         break;
401
402                 case JAVA_ALOAD_0:
403                 case JAVA_ALOAD_1:
404                 case JAVA_ALOAD_2:
405                 case JAVA_ALOAD_3:
406                         OP1LOAD(ICMD_ALOAD, opcode - JAVA_ALOAD_0 + firstlocal);
407                         break;
408
409                         /* storing stack values into local variables */
410
411                 case JAVA_ISTORE:
412                 case JAVA_LSTORE:
413                 case JAVA_FSTORE:
414                 case JAVA_DSTORE:
415                 case JAVA_ASTORE:
416                         if (!iswide) {
417                                 i = code_get_u1(p + 1,inline_env->method);
418                         } else {
419                                 i = code_get_u2(p + 1,inline_env->method);
420                                 iswide = false;
421                                 nextp = p + 3;
422                         }
423                         OP1STORE(opcode, i + firstlocal);
424                         break;
425
426                 case JAVA_ISTORE_0:
427                 case JAVA_ISTORE_1:
428                 case JAVA_ISTORE_2:
429                 case JAVA_ISTORE_3:
430                         OP1STORE(ICMD_ISTORE, opcode - JAVA_ISTORE_0 + firstlocal);
431                         break;
432
433                 case JAVA_LSTORE_0:
434                 case JAVA_LSTORE_1:
435                 case JAVA_LSTORE_2:
436                 case JAVA_LSTORE_3:
437                         OP1STORE(ICMD_LSTORE, opcode - JAVA_LSTORE_0 + firstlocal);
438                         break;
439
440                 case JAVA_FSTORE_0:
441                 case JAVA_FSTORE_1:
442                 case JAVA_FSTORE_2:
443                 case JAVA_FSTORE_3:
444                         OP1STORE(ICMD_FSTORE, opcode - JAVA_FSTORE_0 + firstlocal);
445                         break;
446
447                 case JAVA_DSTORE_0:
448                 case JAVA_DSTORE_1:
449                 case JAVA_DSTORE_2:
450                 case JAVA_DSTORE_3:
451                         OP1STORE(ICMD_DSTORE, opcode - JAVA_DSTORE_0 + firstlocal);
452                         break;
453
454                 case JAVA_ASTORE_0:
455                 case JAVA_ASTORE_1:
456                 case JAVA_ASTORE_2:
457                 case JAVA_ASTORE_3:
458                         OP1STORE(ICMD_ASTORE, opcode - JAVA_ASTORE_0 + firstlocal);
459                         break;
460
461                 case JAVA_IINC:
462                         {
463                                 int v;
464                                 
465                                 if (!iswide) {
466                                         i = code_get_u1(p + 1,inline_env->method);
467                                         v = code_get_s1(p + 2,inline_env->method);
468
469                                 } else {
470                                         i = code_get_u2(p + 1,inline_env->method);
471                                         v = code_get_s2(p + 3,inline_env->method);
472                                         iswide = false;
473                                         nextp = p + 5;
474                                 }
475                                 INDEX_ONEWORD(i + firstlocal);
476                                 OP2I(opcode, i + firstlocal, v);
477                         }
478                         break;
479
480                         /* wider index for loading, storing and incrementing */
481
482                 case JAVA_WIDE:
483                         iswide = true;
484                         nextp = p + 1;
485                         break;
486
487                 /* managing arrays ****************************************************/
488
489                 case JAVA_NEWARRAY:
490                         switch (code_get_s1(p + 1, inline_env->method)) {
491                         case 4:
492                                 bte = builtintable_get_internal(BUILTIN_newarray_boolean);
493                                 break;
494                         case 5:
495                                 bte = builtintable_get_internal(BUILTIN_newarray_char);
496                                 break;
497                         case 6:
498                                 bte = builtintable_get_internal(BUILTIN_newarray_float);
499                                 break;
500                         case 7:
501                                 bte = builtintable_get_internal(BUILTIN_newarray_double);
502                                 break;
503                         case 8:
504                                 bte = builtintable_get_internal(BUILTIN_newarray_byte);
505                                 break;
506                         case 9:
507                                 bte = builtintable_get_internal(BUILTIN_newarray_short);
508                                 break;
509                         case 10:
510                                 bte = builtintable_get_internal(BUILTIN_newarray_int);
511                                 break;
512                         case 11:
513                                 bte = builtintable_get_internal(BUILTIN_newarray_long);
514                                 break;
515                         default:
516                                 *exceptionptr = new_verifyerror(inline_env->method,
517                                                 "Invalid array-type to create");
518                                 return NULL;
519                         }
520                         BUILTIN(bte, true, NULL, currentline);
521                         break;
522
523                 case JAVA_ANEWARRAY:
524                         i = code_get_u2(p + 1, inline_env->method);
525                         compr = (constant_classref *) class_getconstant(inline_env->method->class, i, CONSTANT_Class);
526                         if (!compr)
527                                 return NULL;
528
529                         if (!(cr = class_get_classref_multiarray_of(1, compr)))
530                                 return NULL;
531
532                         if (!resolve_classref(inline_env->method, cr, resolveLazy, true, true, &c))
533                                 return NULL;
534
535                         LOADCONST_A_BUILTIN(c, cr);
536                         bte = builtintable_get_internal(BUILTIN_newarray);
537                         BUILTIN(bte, true, NULL, currentline);
538                         s_count++;
539                         break;
540
541                 case JAVA_MULTIANEWARRAY:
542                         inline_env->method->isleafmethod = false;
543                         i = code_get_u2(p + 1, inline_env->method);
544                         {
545                                 s4 v = code_get_u1(p + 3, inline_env->method);
546
547                                 cr = (constant_classref *) class_getconstant(inline_env->method->class, i, CONSTANT_Class);
548                                 if (!cr)
549                                         return NULL;
550
551                                 if (!resolve_classref(inline_env->method, cr, resolveLazy, true, true, &c))
552                                         return NULL;
553
554                                 /* if unresolved, c == NULL */
555                                 OP2AT(opcode, v, c, cr, currentline);
556                         }
557                         break;
558
559                 case JAVA_IFEQ:
560                 case JAVA_IFLT:
561                 case JAVA_IFLE:
562                 case JAVA_IFNE:
563                 case JAVA_IFGT:
564                 case JAVA_IFGE:
565                 case JAVA_IFNULL:
566                 case JAVA_IFNONNULL:
567                 case JAVA_IF_ICMPEQ:
568                 case JAVA_IF_ICMPNE:
569                 case JAVA_IF_ICMPLT:
570                 case JAVA_IF_ICMPGT:
571                 case JAVA_IF_ICMPLE:
572                 case JAVA_IF_ICMPGE:
573                 case JAVA_IF_ACMPEQ:
574                 case JAVA_IF_ACMPNE:
575                 case JAVA_GOTO:
576                 case JAVA_JSR:
577                         i = p + code_get_s2(p + 1,inline_env->method);
578                         if (useinlining) { 
579                                 i = label_index[i];
580                         }
581                         bound_check(i);
582                         block_insert(i);
583                         blockend = true;
584                         OP1(opcode, i);
585                         break;
586
587                 case JAVA_GOTO_W:
588                 case JAVA_JSR_W:
589                         i = p + code_get_s4(p + 1,inline_env->method);
590                         if (useinlining) { 
591                                 i = label_index[i];
592                         }
593                         bound_check(i);
594                         block_insert(i);
595                         blockend = true;
596                         OP1(opcode, i);
597                         break;
598
599                 case JAVA_RET:
600                         if (!iswide) {
601                                 i = code_get_u1(p + 1,inline_env->method);
602                         } else {
603                                 i = code_get_u2(p + 1,inline_env->method);
604                                 nextp = p + 3;
605                                 iswide = false;
606                         }
607                         blockend = true;
608                                 
609                         /*
610                           if (inline_env->isinlinedmethod) {
611                           OP1(ICMD_GOTO, inlinfo->stopgp);
612                           break;
613                           }*/
614
615                         OP1LOAD(opcode, i + firstlocal);
616                         break;
617
618                 case JAVA_IRETURN:
619                 case JAVA_LRETURN:
620                 case JAVA_FRETURN:
621                 case JAVA_DRETURN:
622                 case JAVA_ARETURN:
623                 case JAVA_RETURN:
624                         if (inline_env->isinlinedmethod) {
625                                 /*                                      if (p==m->jcodelength-1) {*/ /* return is at end of inlined method */
626                                 /*                                              OP(ICMD_NOP); */
627                                 /*                                              break; */
628                                 /*                                      } */
629                                 if (nextp>inline_env->method->jcodelength-1) {
630                                         /* OP1(ICMD_GOTO, inlinfo->stopgp);
631                                            OP(ICMD_NOP);
632                                            OP(ICMD_NOP);
633                                         */
634                                         blockend=true;
635                                         break;
636                                 } /* JJJJJJJ */
637                                 blockend = true;
638                                 OP1(ICMD_GOTO, inlinfo->stopgp);
639                                 break;
640                         }
641
642                         blockend = true;
643                         /* zero val.a so no patcher is inserted */
644                         /* the type checker may set this later  */
645                         iptr->val.a = NULL;
646                         OP(opcode);
647                         break;
648
649                 case JAVA_ATHROW:
650                         blockend = true;
651                         /* zero val.a so no patcher is inserted */
652                         /* the type checker may set this later  */
653                         iptr->val.a = NULL;
654                         OP(opcode);
655                         break;
656                                 
657
658                 /* table jumps ********************************************************/
659
660                 case JAVA_LOOKUPSWITCH:
661                         {
662                                 s4 num, j;
663                                 s4 *tablep;
664                                 s4 prevvalue=0;
665
666                                 blockend = true;
667                                 nextp = ALIGN((p + 1), 4);
668
669                                 if (nextp + 8 > inline_env->method->jcodelength) {
670                                         *exceptionptr = new_verifyerror(inline_env->method,
671                                                         "Unexpected end of bytecode");
672                                         return NULL;
673                                 }
674
675                                 if (!useinlining) {
676                                         tablep = (s4 *) (inline_env->method->jcode + nextp);
677
678                                 } else {
679                                         num = code_get_u4(nextp + 4, inline_env->method);
680                                         tablep = DMNEW(s4, num * 2 + 2);
681                                 }
682
683                                 OP2A(opcode, 0, tablep, currentline);
684
685                                 /* default target */
686
687                                 j =  p + code_get_s4(nextp, inline_env->method);
688                                 if (useinlining) 
689                                         j = label_index[j];
690                                 *tablep = j;     /* restore for little endian */
691                                 tablep++;
692                                 nextp += 4;
693                                 bound_check(j);
694                                 block_insert(j);
695
696                                 /* number of pairs */
697
698                                 num = code_get_u4(nextp, inline_env->method);
699                                 *tablep = num;
700                                 tablep++;
701                                 nextp += 4;
702
703                                 if (nextp + 8 * num > inline_env->method->jcodelength) {
704                                         *exceptionptr = new_verifyerror(inline_env->method,
705                                                 "Unexpected end of bytecode");
706                                         return NULL;
707                                 }
708
709                                 for (i = 0; i < num; i++) {
710                                         /* value */
711
712                                         j = code_get_s4(nextp, inline_env->method);
713                                         *tablep = j; /* restore for little endian */
714                                         tablep++;
715                                         nextp += 4;
716
717                                         /* check if the lookup table is sorted correctly */
718                                         
719                                         if (i && (j <= prevvalue)) {
720                                                 *exceptionptr = new_verifyerror(m, "Unsorted lookup switch");
721                                                 return NULL;
722                                         }
723                                         prevvalue = j;
724
725                                         /* target */
726
727                                         j = p + code_get_s4(nextp,inline_env->method);
728                                         if (useinlining)
729                                                 j = label_index[j];
730                                         *tablep = j; /* restore for little endian */
731                                         tablep++;
732                                         nextp += 4;
733                                         bound_check(j);
734                                         block_insert(j);
735                                 }
736
737                                 break;
738                         }
739
740
741                 case JAVA_TABLESWITCH:
742                         {
743                                 s4 num, j;
744                                 s4 *tablep;
745
746                                 blockend = true;
747                                 nextp = ALIGN((p + 1), 4);
748                                 if (nextp + 12 > inline_env->method->jcodelength) {
749                                         *exceptionptr = new_verifyerror(inline_env->method,
750                                                 "Unexpected end of bytecode");
751                                         return NULL;
752                                 }
753
754                                 if (!useinlining) {
755                                         tablep = (s4 *) (inline_env->method->jcode + nextp);
756
757                                 } else {
758                                         num = code_get_u4(nextp + 8,inline_env->method) - code_get_u4(nextp + 4,inline_env->method);
759                                         tablep = DMNEW(s4, num + 1 + 3);
760                                 }
761
762                                 OP2A(opcode, 0, tablep, currentline);
763
764                                 /* default target */
765
766                                 j = p + code_get_s4(nextp, inline_env->method);
767                                 if (useinlining)
768                                         j = label_index[j];
769                                 *tablep = j;     /* restore for little endian */
770                                 tablep++;
771                                 nextp += 4;
772                                 bound_check(j);
773                                 block_insert(j);
774
775                                 /* lower bound */
776
777                                 j = code_get_s4(nextp, inline_env->method);
778                                 *tablep = j;     /* restore for little endian */
779                                 tablep++;
780                                 nextp += 4;
781
782                                 /* upper bound */
783
784                                 num = code_get_s4(nextp, inline_env->method);
785                                 *tablep = num;   /* restore for little endian */
786                                 tablep++;
787                                 nextp += 4;
788
789                                 num -= j;  /* difference of upper - lower */
790
791                                 if (num < 0) {
792                                         *exceptionptr = new_verifyerror(inline_env->method,
793                                                         "invalid TABLESWITCH: upper bound < lower bound");
794                                         return NULL;
795                                 }
796
797                                 if (nextp + 4 * (num + 1) > inline_env->method->jcodelength) {
798                                         *exceptionptr = new_verifyerror(inline_env->method,
799                                                 "Unexpected end of bytecode");
800                                         return NULL;
801                                 }
802
803                                 for (i = 0; i <= num; i++) {
804                                         j = p + code_get_s4(nextp,inline_env->method);
805                                         if (useinlining) {
806                                                 j = label_index[j];
807                                         }
808                                         *tablep = j; /* restore for little endian */
809                                         tablep++;
810                                         nextp += 4;
811                                         bound_check(j);
812                                         block_insert(j);
813                                 }
814
815                                 break;
816                         }
817
818
819                 /* load and store of object fields ************************************/
820
821                 case JAVA_AASTORE:
822                         OP(opcode);
823                         inline_env->method->isleafmethod = false;
824                         break;
825
826                 case JAVA_GETSTATIC:
827                 case JAVA_PUTSTATIC:
828                 case JAVA_GETFIELD:
829                 case JAVA_PUTFIELD:
830                         {
831                                 constant_FMIref  *fr;
832                                 unresolved_field *uf;
833                                 fieldinfo        *fi;
834
835                                 i = code_get_u2(p + 1, inline_env->method);
836                                 fr = class_getconstant(inline_env->method->class, i,
837                                                                            CONSTANT_Fieldref);
838                                 if (!fr)
839                                         return NULL;
840
841                                 OP2A_NOINC(opcode, fr->parseddesc.fd->type, fr, currentline);
842
843                                 if (!(uf = create_unresolved_field(inline_env->method->class,
844                                                                                                    inline_env->method,
845                                                                                                    iptr)))
846                                         return NULL;
847
848                                 /* store unresolved_field pointer */
849
850                                 iptr->target = uf;
851
852                                 /* only with -noverify, otherwise the typechecker does this */
853
854                                 if (!opt_verify) {
855                                         if (!resolve_field(uf, resolveLazy, &fi))
856                                                 return NULL;
857
858                                         iptr->val.a = fi;
859
860                                 } else {
861                                         iptr->val.a = NULL;
862                                 }
863                                 PINC;
864                         }
865                         break;
866
867
868                 /* method invocation **************************************************/
869
870                 case JAVA_INVOKESTATIC:
871                         i = code_get_u2(p + 1, inline_env->method);
872                         {
873                                 constant_FMIref   *mr;
874                                 methoddesc        *md;
875                                 unresolved_method *um;
876                                 methodinfo        *mi;
877
878                                 inline_env->method->isleafmethod = false;
879
880                                 mr = class_getconstant(inline_env->method->class, i,
881                                                                            CONSTANT_Methodref);
882                                 if (!mr)
883                                         return NULL;
884
885                                 md = mr->parseddesc.md;
886
887                                 if (!md->params)
888                                         if (!descriptor_params_from_paramtypes(md, ACC_STATIC))
889                                                 return NULL;
890
891                                 OP2A_NOINC(opcode, 0, mr, currentline);
892
893                                 um = create_unresolved_method(inline_env->method->class,
894                                                                                           inline_env->method, iptr);
895
896                                 if (!um)
897                                         return NULL;
898
899                                 /* store the unresolved_method pointer */
900
901                                 iptr->target = um;
902
903                                 /* only with -noverify, otherwise the typechecker does this */
904
905                                 if (!opt_verify) {
906                                         if (!resolve_method(um, resolveLazy, &mi))
907                                                 return NULL;
908
909                                         iptr->val.a = mi;
910                                 }
911                                 else {
912                                         iptr->val.a = NULL;
913                                 }
914                                 PINC;
915                         }
916                         break;
917
918                 case JAVA_INVOKESPECIAL:
919                 case JAVA_INVOKEVIRTUAL:
920                         {
921                                 constant_FMIref   *mr;
922                                 methoddesc        *md;
923                                 unresolved_method *um;
924                                 methodinfo        *mi;
925
926                                 inline_env->method->isleafmethod = false;
927
928                                 i = code_get_u2(p + 1, inline_env->method);
929                                 mr = class_getconstant(inline_env->method->class, i,
930                                                                            CONSTANT_Methodref);
931                                 if (!mr)
932                                         return NULL;
933
934                                 md = mr->parseddesc.md;
935
936                                 if (!md->params)
937                                         if (!descriptor_params_from_paramtypes(md, 0))
938                                                 return NULL;
939                                 
940                                 OP2A_NOINC(opcode, 0, mr, currentline);
941
942                                 um = create_unresolved_method(inline_env->method->class,
943                                                                                           inline_env->method, iptr);
944
945                                 if (!um)
946                                         return NULL;
947
948                                 /* store the unresolved_method* */
949
950                                 iptr->target = um;
951
952                                 /* only with -noverify, otherwise the typechecker does this */
953
954                                 if (!opt_verify) {
955                                         if (!resolve_method(um, resolveLazy, &mi))
956                                                 return NULL;
957
958                                         iptr->val.a = mi;
959                                 }
960                                 else {
961                                         iptr->val.a = NULL;
962                                 }
963                                 PINC;
964                         }
965                         break;
966
967                 case JAVA_INVOKEINTERFACE:
968                         i = code_get_u2(p + 1, inline_env->method);
969                         {
970                                 constant_FMIref   *mr;
971                                 methoddesc        *md;
972                                 unresolved_method *um;
973                                 methodinfo        *mi;
974                                 
975                                 inline_env->method->isleafmethod = false;
976
977                                 mr = class_getconstant(inline_env->method->class, i,
978                                                                            CONSTANT_InterfaceMethodref);
979                                 if (!mr)
980                                         return NULL;
981
982                                 md = mr->parseddesc.md;
983
984                                 if (!md->params)
985                                         if (!descriptor_params_from_paramtypes(md, 0))
986                                                 return NULL;
987
988                                 OP2A_NOINC(opcode, 0, mr, currentline);
989
990                                 um = create_unresolved_method(inline_env->method->class,
991                                                                                           inline_env->method, iptr);
992
993                                 if (!um)
994                                         return NULL;
995
996                                 /* store the unresolved_method* */
997
998                                 iptr->target = um;
999
1000                                 /* only with -noverify, otherwise the typechecker does this */
1001
1002                                 if (!opt_verify) {
1003                                         if (!resolve_method(um, resolveLazy, &mi))
1004                                                 return NULL;
1005
1006                                         iptr->val.a = mi;
1007                                 }
1008                                 else {
1009                                         iptr->val.a = NULL;
1010                                 }
1011                                 PINC;
1012                         }
1013                         break;
1014
1015                 /* miscellaneous object operations ************************************/
1016
1017                 case JAVA_NEW:
1018                         i = code_get_u2(p + 1, inline_env->method);
1019                         cr = (constant_classref *) class_getconstant(inline_env->method->class, i, CONSTANT_Class);
1020                         if (!cr)
1021                                 return NULL;
1022
1023                         if (!resolve_classref(inline_env->method, cr, resolveLazy, true, true,
1024                                                                   &c))
1025                                 return NULL;
1026
1027                         LOADCONST_A_BUILTIN(c, cr);
1028                         bte = builtintable_get_internal(BUILTIN_new);
1029                         BUILTIN(bte, true, NULL, currentline);
1030                         s_count++;
1031                         break;
1032
1033                 case JAVA_CHECKCAST:
1034                         i = code_get_u2(p + 1, inline_env->method);
1035                         cr = (constant_classref *) class_getconstant(inline_env->method->class, i, CONSTANT_Class);
1036                         if (!cr)
1037                                 return NULL;
1038
1039                         if (!resolve_classref(inline_env->method, cr, resolveLazy, true,
1040                                                                   true, &c))
1041                                 return NULL;
1042
1043                         if (cr->name->text[0] == '[') {
1044                                 /* array type cast-check */
1045                                 OP2AT(opcode, 0, c, cr, currentline);
1046                                 inline_env->method->isleafmethod = false;
1047
1048                         } else {
1049                                 /* object type cast-check */
1050                                 OP2AT(opcode, 1, c, cr, currentline);
1051                         }
1052                         break;
1053
1054                 case JAVA_INSTANCEOF:
1055                         i = code_get_u2(p + 1,inline_env->method);
1056                         cr = (constant_classref *) class_getconstant(inline_env->method->class, i, CONSTANT_Class);
1057                         if (!cr)
1058                                 return NULL;
1059
1060                         if (!resolve_classref(inline_env->method, cr, resolveLazy, true, true, &c))
1061                                 return NULL;
1062
1063                         if (cr->name->text[0] == '[') {
1064                                 /* array type cast-check */
1065                                 LOADCONST_A_BUILTIN(c, cr);
1066                                 bte = builtintable_get_internal(BUILTIN_arrayinstanceof);
1067                                 BUILTIN(bte, false, NULL, currentline);
1068                                 s_count++;
1069
1070                         } else {
1071                                 /* object type cast-check */
1072                                 OP2AT(opcode, 1, c, cr, currentline);
1073                         }
1074                         break;
1075
1076                 case JAVA_MONITORENTER:
1077 #if defined(USE_THREADS)
1078                         if (checksync) {
1079                                 OP(ICMD_CHECKNULL);
1080                                 bte = builtintable_get_internal(BUILTIN_monitorenter);
1081                                 BUILTIN(bte, false, NULL, currentline);
1082                         } else
1083 #endif
1084                                 {
1085                                         OP(ICMD_CHECKNULL);
1086                                         OP(ICMD_POP);
1087                                 }
1088                         break;
1089
1090                 case JAVA_MONITOREXIT:
1091 #if defined(USE_THREADS)
1092                         if (checksync) {
1093                                 bte = builtintable_get_internal(BUILTIN_monitorexit);
1094                                 BUILTIN(bte, false, NULL, currentline);
1095                         } else
1096 #endif
1097                                 {
1098                                         OP(ICMD_POP);
1099                                 }
1100                         break;
1101
1102                 /* any other basic operation ******************************************/
1103
1104                 case JAVA_IDIV:
1105 #if !SUPPORT_DIVISION
1106                         bte = builtintable_get_internal(BUILTIN_idiv);
1107                         OP2A(opcode, bte->md->paramcount, bte, currentline);
1108                         inline_env->method->isleafmethod = false;
1109 #else
1110                         OP(opcode);
1111 #endif
1112                         break;
1113
1114                 case JAVA_IREM:
1115 #if !SUPPORT_DIVISION
1116                         bte = builtintable_get_internal(BUILTIN_irem);
1117                         OP2A(opcode, bte->md->paramcount, bte, currentline);
1118                         inline_env->method->isleafmethod = false;
1119 #else
1120                         OP(opcode);
1121 #endif
1122                         break;
1123
1124                 case JAVA_LDIV:
1125 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1126                         bte = builtintable_get_internal(BUILTIN_ldiv);
1127                         OP2A(opcode, bte->md->paramcount, bte, currentline);
1128                         inline_env->method->isleafmethod = false;
1129 #else
1130                         OP(opcode);
1131 #endif
1132                         break;
1133
1134                 case JAVA_LREM:
1135 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1136                         bte = builtintable_get_internal(BUILTIN_lrem);
1137                         OP2A(opcode, bte->md->paramcount, bte, currentline);
1138                         inline_env->method->isleafmethod = false;
1139 #else
1140                         OP(opcode);
1141 #endif
1142                         break;
1143
1144                 case JAVA_FREM:
1145 #if defined(__I386__)
1146                         OP(opcode);
1147 #else
1148                         bte = builtintable_get_internal(BUILTIN_frem);
1149                         BUILTIN(bte, false, NULL, currentline);
1150 #endif
1151                         break;
1152
1153                 case JAVA_DREM:
1154 #if defined(__I386__)
1155                         OP(opcode);
1156 #else
1157                         bte = builtintable_get_internal(BUILTIN_drem);
1158                         BUILTIN(bte, false, NULL, currentline);
1159 #endif
1160                         break;
1161
1162                 case JAVA_F2I:
1163 #if defined(__ALPHA__)
1164                         if (!opt_noieee) {
1165                                 bte = builtintable_get_internal(BUILTIN_f2i);
1166                                 BUILTIN(bte, false, NULL, currentline);
1167                         } else
1168 #endif
1169                                 {
1170                                         OP(opcode);
1171                                 }
1172                         break;
1173
1174                 case JAVA_F2L:
1175 #if defined(__ALPHA__)
1176                         if (!opt_noieee) {
1177                                 bte = builtintable_get_internal(BUILTIN_f2l);
1178                                 BUILTIN(bte, false, NULL, currentline);
1179                         } else 
1180 #endif
1181                                 {
1182                                         OP(opcode);
1183                                 }
1184                         break;
1185
1186                 case JAVA_D2I:
1187 #if defined(__ALPHA__)
1188                         if (!opt_noieee) {
1189                                 bte = builtintable_get_internal(BUILTIN_d2i);
1190                                 BUILTIN(bte, false, NULL, currentline);
1191                         } else
1192 #endif
1193                                 {
1194                                         OP(opcode);
1195                                 }
1196                         break;
1197
1198                 case JAVA_D2L:
1199 #if defined(__ALPHA__)
1200                         if (!opt_noieee) {
1201                                 bte = builtintable_get_internal(BUILTIN_d2l);
1202                                 BUILTIN(bte, false, NULL, currentline);
1203                         } else
1204 #endif
1205                                 {
1206                                         OP(opcode);
1207                                 }
1208                         break;
1209
1210                 case JAVA_BREAKPOINT:
1211                         *exceptionptr =
1212                                 new_verifyerror(m, "Quick instructions shouldn't appear yet.");
1213                         return NULL;
1214
1215                 case 186: /* unused opcode */
1216                 case 203:
1217                 case 204:
1218                 case 205:
1219                 case 206:
1220                 case 207:
1221                 case 208:
1222                 case 209:
1223                 case 210:
1224                 case 211:
1225                 case 212:
1226                 case 213:
1227                 case 214:
1228                 case 215:
1229                 case 216:
1230                 case 217:
1231                 case 218:
1232                 case 219:
1233                 case 220:
1234                 case 221:
1235                 case 222:
1236                 case 223:
1237                 case 224:
1238                 case 225:
1239                 case 226:
1240                 case 227:
1241                 case 228:
1242                 case 229:
1243                 case 230:
1244                 case 231:
1245                 case 232:
1246                 case 233:
1247                 case 234:
1248                 case 235:
1249                 case 236:
1250                 case 237:
1251                 case 238:
1252                 case 239:
1253                 case 240:
1254                 case 241:
1255                 case 242:
1256                 case 243:
1257                 case 244:
1258                 case 245:
1259                 case 246:
1260                 case 247:
1261                 case 248:
1262                 case 249:
1263                 case 250:
1264                 case 251:
1265                 case 252:
1266                 case 253:
1267                 case 254:
1268                 case 255:
1269                         *exceptionptr =
1270                                 new_verifyerror(inline_env->method,"Illegal opcode %d at instr %d\n",
1271                                                                   opcode, ipc);
1272                         return NULL;
1273                         break;
1274
1275                 default:
1276                         OP(opcode);
1277                         break;
1278                                 
1279                 } /* end switch */
1280
1281                 /* If WIDE was used correctly, iswide should have been reset by now. */
1282                 if (iswide && opcode != JAVA_WIDE) {
1283                         *exceptionptr = new_verifyerror(inline_env->method,
1284                                         "Illegal instruction: WIDE before incompatible opcode");
1285                         return NULL;
1286                 }
1287
1288 #if defined(USE_INLINING)
1289                 /* if (inline_env->isinlinedmethod && p == inline_env->method->jcodelength - 1) { */ /* end of an inlined method */
1290                 if (inline_env->isinlinedmethod && (nextp >= inline_env->method->jcodelength) ) { /* end of an inlined method */
1291                         gp = inlinfo->stopgp; 
1292                         inlining_restore_compiler_variables();
1293                         OP(ICMD_INLINE_END);
1294                         /*label_index = inlinfo->label_index;*/
1295
1296                         list_remove(inlinfo->inlinedmethods, list_first(inlinfo->inlinedmethods));
1297                         if (inlinfo->inlinedmethods == NULL) { /* JJJJ */
1298                                 nextgp = -1;
1299                         } else {
1300                                 tmpinlinf = list_first(inlinfo->inlinedmethods);
1301                                 nextgp = (tmpinlinf != NULL) ? tmpinlinf->startgp : -1;
1302                         }
1303                         label_index=inlinfo->label_index;
1304                         firstlocal = inlinfo->firstlocal;
1305                 }
1306 #endif /* defined(USE_INLINING) */
1307
1308         } /* end for */
1309
1310
1311         if (p != m->jcodelength) {
1312                 printf("p (%d) != m->jcodelength (%d)\n",p,m->jcodelength);
1313                 *exceptionptr = new_verifyerror(inline_env->method,
1314                                 "Command-sequence crosses code-boundary");
1315                 return NULL;
1316         }
1317
1318         if (!blockend) {
1319                 *exceptionptr = new_verifyerror(m, "Falling off the end of the code");
1320                 return NULL;
1321         }
1322
1323         /* adjust block count if target 0 is not first intermediate instruction */
1324
1325         if (!m->basicblockindex[0] || (m->basicblockindex[0] > 1))
1326                 b_count++;
1327
1328         /* copy local to method variables */
1329
1330         m->instructioncount = ipc;
1331         m->basicblockcount = b_count;
1332         m->stackcount = s_count + m->basicblockcount * m->maxstack;
1333
1334         /* allocate stack table */
1335
1336         m->stack = DMNEW(stackelement, m->stackcount);
1337
1338         {
1339                 basicblock *bptr;
1340
1341                 bptr = m->basicblocks = DMNEW(basicblock, b_count + 1);    /* one more for end ipc */
1342
1343                 b_count = 0;
1344                 m->c_debug_nr = 0;
1345         
1346                 /* additional block if target 0 is not first intermediate instruction */
1347
1348                 if (!m->basicblockindex[0] || (m->basicblockindex[0] > 1)) {
1349                         bptr->iinstr = m->instructions;
1350                         bptr->mpc = -1;
1351                         bptr->flags = -1;
1352                         bptr->type = BBTYPE_STD;
1353                         bptr->branchrefs = NULL;
1354                         bptr->pre_count = 0;
1355                         bptr->debug_nr = m->c_debug_nr++;
1356                         bptr++;
1357                         b_count++;
1358                         (bptr - 1)->next = bptr;
1359                 }
1360
1361                 /* allocate blocks */
1362
1363                 for (p = 0; p < inline_env->cumjcodelength; p++) { 
1364                 /* for (p = 0; p < m->jcodelength; p++) { */
1365                         if (m->basicblockindex[p] & 1) {
1366                                 /* Check if this block starts at the beginning of an          */
1367                                 /* instruction.                                               */
1368
1369                                 if (!instructionstart[p]) {
1370                                         *exceptionptr = new_verifyerror(inline_env->method,
1371                                                 "Branch into middle of instruction");
1372                                         return NULL;
1373                                 }
1374
1375                                 /* allocate the block */
1376                                 bptr->iinstr = m->instructions + (m->basicblockindex[p] >> 1);
1377                                 bptr->debug_nr = m->c_debug_nr++;
1378                                 if (b_count != 0)
1379                                         (bptr - 1)->icount = bptr->iinstr - (bptr - 1)->iinstr;
1380                                 bptr->mpc = -1;
1381                                 bptr->flags = -1;
1382                                 bptr->lflags = 0;
1383                                 bptr->type = BBTYPE_STD;
1384                                 bptr->branchrefs = NULL;
1385                                 m->basicblockindex[p] = b_count;
1386                                 bptr->pre_count = 0;
1387                                 bptr++;
1388                                 b_count++;
1389                                 (bptr - 1)->next = bptr;
1390                         }
1391                 }
1392
1393                 /* allocate additional block at end */
1394
1395                 bptr->instack = bptr->outstack = NULL;
1396                 bptr->indepth = bptr->outdepth = 0;
1397                 bptr->iinstr = NULL;
1398                 (bptr - 1)->icount = (m->instructions + m->instructioncount) - (bptr - 1)->iinstr;
1399                 bptr->icount = 0;
1400                 bptr->mpc = -1;
1401                 bptr->flags = -1;
1402                 bptr->lflags = 0;
1403                 bptr->type = BBTYPE_STD;
1404                 bptr->branchrefs = NULL;
1405                 bptr->pre_count = 0;
1406                 bptr->debug_nr = m->c_debug_nr++;
1407                 (bptr - 1)->next = bptr;
1408                 bptr->next = NULL;
1409
1410                 if (cd->exceptiontablelength > 0) {
1411                         cd->exceptiontable[cd->exceptiontablelength - 1].down = NULL;
1412                 }
1413                 
1414                 for (i = 0; i < cd->exceptiontablelength; ++i) {
1415                         p = cd->exceptiontable[i].startpc;
1416                         cd->exceptiontable[i].start = m->basicblocks + m->basicblockindex[p];
1417
1418                         p = cd->exceptiontable[i].endpc;
1419                         cd->exceptiontable[i].end = (p == inline_env->method->jcodelength) ? (m->basicblocks + m->basicblockcount /*+ 1*/) : (m->basicblocks + m->basicblockindex[p]);
1420
1421                         p = cd->exceptiontable[i].handlerpc;
1422                         cd->exceptiontable[i].handler = m->basicblocks + m->basicblockindex[p];
1423             }
1424         }
1425
1426         /* just return methodinfo* to signal everything was ok */
1427
1428         return m;
1429 }
1430
1431
1432 /*
1433  * These are local overrides for various environment variables in Emacs.
1434  * Please do not remove this and leave it at the end of the file, where
1435  * Emacs will automagically detect them.
1436  * ---------------------------------------------------------------------
1437  * Local variables:
1438  * mode: c
1439  * indent-tabs-mode: t
1440  * c-basic-offset: 4
1441  * tab-width: 4
1442  * End:
1443  * vim:noexpandtab:sw=4:ts=4:
1444  */