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