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