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