Lazy loading changes.
[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 2263 2005-04-11 09:56:52Z 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_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_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                                 if (!resolve_classref(inline_env->method,fr->classref,resolveEager,true,&frclass))
1031                                         return NULL;
1032
1033                                 fi = class_resolvefield(frclass,
1034                                                                                 fr->name,
1035                                                                                 fr->descriptor,
1036                                                                                 inline_env->method->class,
1037                                                                                 true);
1038
1039                                 if (!fi)
1040                                         return NULL;
1041
1042                                 OP2A(opcode, fi->type, fi, currentline);
1043                                 if (!fi->class->initialized) {
1044                                         inline_env->method->isleafmethod = false;
1045                                 }
1046 #endif
1047                         }
1048                         break;
1049
1050 #if !defined(__X86_64__)
1051                 case JAVA_PUTFIELD:
1052                 case JAVA_GETFIELD:
1053                         i = code_get_u2(p + 1,inline_env->method);
1054                         {
1055                                 constant_FMIref *fr;
1056                                 fieldinfo *fi;
1057                                 classinfo *frclass;
1058
1059                                 fr = class_getconstant(inline_env->method->class, i, CONSTANT_Fieldref);
1060                                 if (!resolve_classref(inline_env->method,fr->classref,resolveEager,true,&frclass))
1061                                         return NULL;
1062
1063                                 fi = class_resolvefield(frclass,
1064                                                                                 fr->name,
1065                                                                                 fr->descriptor,
1066                                                                                 inline_env->method->class,
1067                                                                                 true);
1068
1069                                 if (!fi)
1070                                         return NULL;
1071
1072                                 OP2A(opcode, fi->type, fi, currentline);
1073                         }
1074                         break;
1075 #endif
1076
1077
1078                         /* method invocation *****/
1079
1080                 case JAVA_INVOKESTATIC:
1081                         i = code_get_u2(p + 1, inline_env->method);
1082                         {
1083                                 constant_FMIref *mr;
1084                                 methodinfo *mi;
1085                                 unresolved_method *um;
1086                                 classinfo *mrclass;
1087
1088                                 inline_env->method->isleafmethod = false;
1089
1090                                 mr = class_getconstant(inline_env->method->class, i, CONSTANT_Methodref);
1091 #if defined(__X86_64__)
1092                                 OP2A_NOINC(opcode, mr->parseddesc.md->paramcount, mr, currentline);
1093
1094                                 um = create_unresolved_method(inline_env->method->class,
1095                                                                                           inline_env->method,
1096                                                                                           iptr,
1097                                                                                           NULL);
1098
1099                                 if (!um)
1100                                         return NULL;
1101
1102                                 /* store the unresolved_method pointer */
1103
1104                                 iptr->target = um;
1105
1106                                 /* only with -noverify, otherwise the typechecker does this */
1107
1108                                 if (!opt_verify) {
1109                                         if (!resolve_method(um, resolveLazy, &mi))
1110                                                 return NULL;
1111
1112                                         iptr->val.a = mi;
1113                                 }
1114                                 PINC;
1115 #else
1116                                 if (!resolve_classref(inline_env->method,mr->classref,resolveEager,true,&mrclass))
1117                                         return NULL;
1118
1119                                 mi = class_resolveclassmethod(mrclass,
1120                                                                                           mr->name,
1121                                                                                           mr->descriptor,
1122                                                                                           inline_env->method->class,
1123                                                                                           true);
1124
1125                                 if (!mi)
1126                                         return NULL;
1127
1128 if (DEBUG4==true) { 
1129         method_display_w_class(mi); 
1130         printf("\tINVOKE SPEC/VIRT\n");
1131         fflush(stdout);}
1132
1133                                 if (mi->flags & ACC_STATIC) {
1134                                         *exceptionptr =
1135                                                 new_exception(string_java_lang_IncompatibleClassChangeError);
1136                                         return NULL;
1137                                 }
1138
1139                                 method_descriptor2types(mi);
1140                                 OP2A(opcode, mi->paramcount, mi, currentline);
1141 #endif
1142                         }
1143                         break;
1144
1145                 case JAVA_INVOKESPECIAL:
1146                 case JAVA_INVOKEVIRTUAL:
1147                         i = code_get_u2(p + 1, inline_env->method);
1148                         {
1149                                 constant_FMIref *mr;
1150                                 methodinfo *mi;
1151                                 unresolved_method *um;
1152                                 classinfo *mrclass;
1153
1154                                 inline_env->method->isleafmethod = false;
1155
1156                                 mr = class_getconstant(inline_env->method->class, i, CONSTANT_Methodref);
1157 #if defined(__X86_64__)
1158                                 OP2A_NOINC(opcode, mr->parseddesc.md->paramcount + 1, mr, currentline);
1159
1160                                 um = create_unresolved_method(inline_env->method->class,
1161                                                                                           inline_env->method,
1162                                                                                           iptr,
1163                                                                                           NULL);
1164
1165                                 if (!um)
1166                                         return NULL;
1167
1168                                 /* store the unresolved_method* */
1169
1170                                 iptr->target = um;
1171
1172                                 /* only with -noverify, otherwise the typechecker does this */
1173
1174                                 if (!opt_verify) {
1175                                         if (!resolve_method(um, resolveLazy, &mi))
1176                                                 return NULL;
1177
1178                                         iptr->val.a = mi;
1179                                 }
1180                                 PINC;
1181 #else
1182                                 if (!resolve_classref(inline_env->method,mr->classref,resolveEager,true,&mrclass))
1183                                         return NULL;
1184
1185                                 mi = class_resolveclassmethod(mrclass,
1186                                                                                           mr->name,
1187                                                                                           mr->descriptor,
1188                                                                                           inline_env->method->class,
1189                                                                                           true);
1190
1191                                 if (!mi)
1192                                         return NULL;
1193
1194 if (DEBUG4==true) { 
1195         method_display_w_class(mi); 
1196         printf("\tINVOKE SPEC/VIRT\n");
1197         fflush(stdout);}
1198
1199                                 if (mi->flags & ACC_STATIC) {
1200                                         *exceptionptr =
1201                                                 new_exception(string_java_lang_IncompatibleClassChangeError);
1202                                         return NULL;
1203                                 }
1204
1205                                 method_descriptor2types(mi);
1206                                 OP2A(opcode, mi->paramcount, mi, currentline);
1207 #endif
1208                         }
1209                         break;
1210
1211                 case JAVA_INVOKEINTERFACE:
1212                         i = code_get_u2(p + 1,inline_env->method);
1213                         {
1214                                 constant_FMIref *mr;
1215                                 methodinfo *mi;
1216                                 classinfo *mrclass;
1217                                 unresolved_method *um;
1218                                 
1219                                 inline_env->method->isleafmethod = false;
1220
1221                                 mr = class_getconstant(inline_env->method->class, i, CONSTANT_InterfaceMethodref);
1222 #if defined(__X86_64__)
1223                                 OP2A_NOINC(opcode, mr->parseddesc.md->paramcount + 1, mr, currentline);
1224
1225                                 um = create_unresolved_method(inline_env->method->class,
1226                                                                                           inline_env->method,
1227                                                                                           iptr,
1228                                                                                           NULL);
1229
1230                                 if (!um)
1231                                         return NULL;
1232
1233                                 /* store the unresolved_method* */
1234
1235                                 iptr->target = um;
1236
1237                                 /* only with -noverify, otherwise the typechecker does this */
1238
1239                                 if (!opt_verify) {
1240                                         if (!resolve_method(um, resolveLazy, &mi))
1241                                                 return NULL;
1242
1243                                         iptr->val.a = mi;
1244                                 }
1245                                 PINC;
1246 #else
1247                                 if (!resolve_classref(inline_env->method,mr->classref,resolveEager,true,&mrclass))
1248                                         return NULL;
1249
1250                                 mi = class_resolveinterfacemethod(mrclass,
1251                                                                                                   mr->name,
1252                                                                                                   mr->descriptor,
1253                                                                                                   inline_env->method->class,
1254                                                                                                   true);
1255                                 if (!mi)
1256                                         return NULL;
1257
1258                                 if (mi->flags & ACC_STATIC) {
1259                                         *exceptionptr =
1260                                                 new_exception(string_java_lang_IncompatibleClassChangeError);
1261                                         return NULL;
1262                                 }
1263
1264 if (DEBUG4==true) { 
1265         method_display_w_class(mi); 
1266         printf("\tINVOKE INTERFACE\n");
1267         fflush(stdout);}
1268                                 method_descriptor2types(mi);
1269                                 OP2A(opcode, mi->paramcount, mi, currentline);
1270 #endif
1271                         }
1272                         break;
1273
1274                         /* miscellaneous object operations *******/
1275
1276                 case JAVA_NEW:
1277                         {
1278                                 constant_classref *cr;
1279                                 classinfo         *cls;
1280                                 
1281 #if defined(__X86_64__)
1282                                 i = code_get_u2(p + 1, inline_env->method);
1283                                 cr = (constant_classref *) class_getconstant(inline_env->method->class, i, CONSTANT_Class);
1284
1285                                 if (!resolve_classref(inline_env->method, cr, resolveLazy, true, &cls))
1286                                         return NULL;
1287
1288                                 /* <clinit> can throw an exception over native code */
1289
1290                                 if (cls && cls->initialized) {
1291                                         LOADCONST_A_BUILTIN(cls);
1292                                         BUILTIN1(BUILTIN_new, TYPE_ADR, currentline);
1293
1294                                 } else {
1295                                         LOADCONST_A_BUILTIN(cr);
1296                                         BUILTIN1((functionptr) asm_builtin_new, TYPE_ADR, currentline);
1297                                 }
1298
1299                                 s_count++;
1300                                 OP(ICMD_CHECKEXCEPTION);
1301 #else
1302                                 i = code_get_u2(p + 1,inline_env->method);
1303                                 cr = (constant_classref *) class_getconstant(inline_env->method->class, i, CONSTANT_Class);
1304                                 if (!resolve_classref(inline_env->method,cr,resolveEager,true,&cls))
1305                                         return NULL;
1306                                 LOADCONST_A_BUILTIN(cls);
1307                                 s_count++;
1308                                 BUILTIN1(BUILTIN_new, TYPE_ADR, currentline);
1309                                 OP(ICMD_CHECKEXCEPTION);
1310 #endif
1311                         }
1312                         break;
1313
1314                 case JAVA_CHECKCAST:
1315                         i = code_get_u2(p + 1, inline_env->method);
1316                         {
1317                                 constant_classref *cr;
1318                                 classinfo *cls;
1319                                 
1320                                 cr = (constant_classref *) class_getconstant(inline_env->method->class, i, CONSTANT_Class);
1321
1322 #if defined(x__X86_64__)
1323                                 if (!resolve_classref(inline_env->method, cr, resolveLazy, true, &cls))
1324                                         return NULL;
1325
1326                                 if (cr->name->text[0] == '[') {
1327                                         if (!resolve_classref(inline_env->method, cr, resolveEager, true, &cls))
1328                                                 return NULL;
1329
1330                                         /* array type cast-check */
1331                                         LOADCONST_A_BUILTIN(cls->vftbl);
1332                                         BUILTIN2(BUILTIN_checkarraycast, TYPE_ADR, currentline);
1333
1334                                 } else {
1335                                         /* object type cast-check */
1336                                         OP2AT(opcode, 1, cls, cr, currentline);
1337                                 }
1338                                 s_count++;
1339 #else
1340                                 if (!resolve_classref(inline_env->method,
1341                                                         cr,resolveEager,true,&cls))
1342                                         return NULL;
1343
1344                                 if (cls->vftbl->arraydesc) {
1345                                         /* array type cast-check */
1346                                         LOADCONST_A_BUILTIN(cls->vftbl);
1347                                         s_count++;
1348                                         BUILTIN2(BUILTIN_checkarraycast, TYPE_ADR,currentline);
1349
1350                                 } else { /* object type cast-check */
1351                                         /*
1352                                           +                                               LOADCONST_A_BUILTIN(class_getconstant(class, i, CONSTANT_Class));
1353                                           +                                               s_count++;
1354                                           +                                               BUILTIN2(BUILTIN_checkcast, TYPE_ADR,currentline);
1355                                           +                                             */
1356                                         OP2A(opcode, 1, cls, currentline);
1357                                 }
1358 #endif
1359                         }
1360                         break;
1361
1362                 case JAVA_INSTANCEOF:
1363                         i = code_get_u2(p + 1,inline_env->method);
1364                         {
1365                                 constant_classref *cr;
1366                                 classinfo *cls;
1367                                 
1368                                 cr = (constant_classref *) class_getconstant(inline_env->method->class, i, CONSTANT_Class);
1369                                 if (!resolve_classref(inline_env->method,
1370                                                         cr,resolveEager,true,&cls))
1371                                         return NULL;
1372
1373                                 if (cls->vftbl->arraydesc) {
1374                                         /* array type cast-check */
1375                                         LOADCONST_A_BUILTIN(cls->vftbl);
1376                                         s_count++;
1377                                         BUILTIN2(BUILTIN_arrayinstanceof, TYPE_INT, currentline);
1378                                 }
1379                                 else { /* object type cast-check */
1380                                         /*
1381                                           LOADCONST_A_BUILTIN(class_getconstant(class, i, CONSTANT_Class));
1382                                           s_count++;
1383                                           BUILTIN2(BUILTIN_instanceof, TYPE_INT,currentline);
1384                                           +                                             */
1385                                         OP2A(opcode, 1, cls, currentline);
1386                                 }
1387                         }
1388                         break;
1389
1390                 case JAVA_MONITORENTER:
1391 #if defined(USE_THREADS)
1392                         if (checksync) {
1393                                 BUILTIN1(BUILTIN_monitorenter, TYPE_VOID,currentline);
1394                         } else
1395 #endif
1396                                 {
1397                                         OP(ICMD_NULLCHECKPOP);
1398                                 }
1399                         break;
1400
1401                 case JAVA_MONITOREXIT:
1402 #if defined(USE_THREADS)
1403                         if (checksync) {
1404                                 BUILTIN1(BUILTIN_monitorexit, TYPE_VOID,currentline);
1405                                 OP(ICMD_CHECKEXCEPTION);
1406                         } else
1407 #endif
1408                                 {
1409                                         OP(ICMD_POP);
1410                                 }
1411                         break;
1412
1413                         /* any other basic operation **************************************/
1414
1415                 case JAVA_IDIV:
1416                         OP(opcode);
1417                         break;
1418
1419                 case JAVA_IREM:
1420                         OP(opcode);
1421                         break;
1422
1423                 case JAVA_LDIV:
1424                         OP(opcode);
1425                         break;
1426
1427                 case JAVA_LREM:
1428                         OP(opcode);
1429                         break;
1430
1431                 case JAVA_FREM:
1432 #if defined(__I386__)
1433                         OP(opcode);
1434 #else
1435                         BUILTIN2(BUILTIN_frem, TYPE_FLOAT,currentline);
1436 #endif
1437                         break;
1438
1439                 case JAVA_DREM:
1440 #if defined(__I386__)
1441                         OP(opcode);
1442 #else
1443                         BUILTIN2(BUILTIN_drem, TYPE_DOUBLE,currentline);
1444 #endif
1445                         break;
1446
1447                 case JAVA_F2I:
1448 #if defined(__ALPHA__)
1449                         if (!opt_noieee) {
1450                                 BUILTIN1(BUILTIN_f2i, TYPE_INT,currentline);
1451                         } else
1452 #endif
1453                                 {
1454                                         OP(opcode);
1455                                 }
1456                         break;
1457
1458                 case JAVA_F2L:
1459 #if defined(__ALPHA__)
1460                         if (!opt_noieee) {
1461                                 BUILTIN1(BUILTIN_f2l, TYPE_LONG,currentline);
1462                         } else 
1463 #endif
1464                                 {
1465                                         OP(opcode);
1466                                 }
1467                         break;
1468
1469                 case JAVA_D2I:
1470 #if defined(__ALPHA__)
1471                         if (!opt_noieee) {
1472                                 BUILTIN1(BUILTIN_d2i, TYPE_INT,currentline);
1473                         } else
1474 #endif
1475                                 {
1476                                         OP(opcode);
1477                                 }
1478                         break;
1479
1480                 case JAVA_D2L:
1481 #if defined(__ALPHA__)
1482                         if (!opt_noieee) {
1483                                 BUILTIN1(BUILTIN_d2l, TYPE_LONG,currentline);
1484                         } else
1485 #endif
1486                                 {
1487                                         OP(opcode);
1488                                 }
1489                         break;
1490
1491                 case JAVA_BREAKPOINT:
1492                         *exceptionptr =
1493                                 new_verifyerror(m, "Quick instructions shouldn't appear yet.");
1494                         return NULL;
1495
1496                 case 204: /* unused opcode */
1497                 case 205:
1498                 case 206:
1499                 case 207:
1500                 case 208:
1501                 case 209:
1502                 case 210:
1503                 case 211:
1504                 case 212:
1505                 case 213:
1506                 case 214:
1507                 case 215:
1508                 case 216:
1509                 case 217:
1510                 case 218:
1511                 case 219:
1512                 case 220:
1513                 case 221:
1514                 case 222:
1515                 case 223:
1516                 case 224:
1517                 case 225:
1518                 case 226:
1519                 case 227:
1520                 case 228:
1521                 case 229:
1522                 case 230:
1523                 case 231:
1524                 case 232:
1525                 case 233:
1526                 case 234:
1527                 case 235:
1528                 case 236:
1529                 case 237:
1530                 case 238:
1531                 case 239:
1532                 case 240:
1533                 case 241:
1534                 case 242:
1535                 case 243:
1536                 case 244:
1537                 case 245:
1538                 case 246:
1539                 case 247:
1540                 case 248:
1541                 case 249:
1542                 case 250:
1543                 case 251:
1544                 case 252:
1545                 case 253:
1546                 case 254:
1547                 case 255:
1548                         printf("Illegal opcode %d at instr %d\n", opcode, ipc);
1549                         panic("Illegal opcode encountered");
1550                         break;
1551
1552                 default:
1553                         OP(opcode);
1554                         break;
1555                                 
1556                 } /* end switch */
1557
1558                 /* If WIDE was used correctly, iswide should have been reset by now. */
1559                 if (iswide && opcode != JAVA_WIDE)
1560                         panic("Illegal instruction: WIDE before incompatible opcode");
1561                 
1562                 /* INLINING */
1563                   
1564                 /* if (inline_env->isinlinedmethod && p == inline_env->method->jcodelength - 1) { */ /* end of an inlined method */
1565                 if (inline_env->isinlinedmethod && (nextp >= inline_env->method->jcodelength) ) { /* end of an inlined method */
1566                         /*                printf("setting gp from %d to %d\n",gp, inlinfo->stopgp); */
1567                         gp = inlinfo->stopgp; 
1568                         inlining_restore_compiler_variables();
1569                         OP(ICMD_INLINE_END);
1570 /*label_index = inlinfo->label_index;*/
1571
1572 METHINFOt(inline_env->method,"AFTER RESTORE : ",DEBUG);
1573                         list_remove(inlinfo->inlinedmethods, list_first(inlinfo->inlinedmethods));
1574                         if (inlinfo->inlinedmethods == NULL) { /* JJJJ */
1575                                 nextgp = -1;
1576                         } else {
1577                                 tmpinlinf = list_first(inlinfo->inlinedmethods);
1578                                 nextgp = (tmpinlinf != NULL) ? tmpinlinf->startgp : -1;
1579                         }
1580                         /*                printf("nextpgp: %d\n", nextgp); */
1581                         label_index=inlinfo->label_index;
1582                         firstlocal = inlinfo->firstlocal;
1583                 }
1584
1585         } /* end for */
1586
1587
1588         if (p != m->jcodelength) {
1589                 printf("p (%d) != m->jcodelength (%d)\n",p,m->jcodelength);
1590                 panic("Command-sequence crosses code-boundary");
1591         }
1592         if (!blockend) {
1593                 *exceptionptr = new_verifyerror(m, "Falling off the end of the code");
1594                 return NULL;
1595         }
1596
1597         /* adjust block count if target 0 is not first intermediate instruction */
1598
1599         if (!m->basicblockindex[0] || (m->basicblockindex[0] > 1))
1600                 b_count++;
1601
1602         /* copy local to method variables */
1603
1604         m->instructioncount = ipc;
1605         m->basicblockcount = b_count;
1606         m->stackcount = s_count + m->basicblockcount * m->maxstack;
1607
1608         /* allocate stack table */
1609
1610         m->stack = DMNEW(stackelement, m->stackcount);
1611
1612         {
1613                 basicblock *bptr;
1614
1615                 bptr = m->basicblocks = DMNEW(basicblock, b_count + 1);    /* one more for end ipc */
1616
1617                 b_count = 0;
1618                 m->c_debug_nr = 0;
1619         
1620                 /* additional block if target 0 is not first intermediate instruction */
1621
1622                 if (!m->basicblockindex[0] || (m->basicblockindex[0] > 1)) {
1623                         bptr->iinstr = m->instructions;
1624                         bptr->mpc = -1;
1625                         bptr->flags = -1;
1626                         bptr->type = BBTYPE_STD;
1627                         bptr->branchrefs = NULL;
1628                         bptr->pre_count = 0;
1629                         bptr->debug_nr = m->c_debug_nr++;
1630                         bptr++;
1631                         b_count++;
1632                         (bptr - 1)->next = bptr;
1633                 }
1634
1635                 /* allocate blocks */
1636
1637                 for (p = 0; p < inline_env->cumjcodelength; p++) { 
1638                 /* for (p = 0; p < m->jcodelength; p++) { */
1639                         if (m->basicblockindex[p] & 1) {
1640                                 /* check if this block starts at the beginning of an instruction */
1641                                 if (!instructionstart[p]) {
1642                                         printf("Basic Block beginn: %d\n",p);
1643                                         panic("Branch into middle of instruction");
1644                                 }
1645                                 /* allocate the block */
1646                                 bptr->iinstr = m->instructions + (m->basicblockindex[p] >> 1);
1647                                 bptr->debug_nr = m->c_debug_nr++;
1648                                 if (b_count != 0)
1649                                         (bptr - 1)->icount = bptr->iinstr - (bptr - 1)->iinstr;
1650                                 bptr->mpc = -1;
1651                                 bptr->flags = -1;
1652                                 bptr->lflags = 0;
1653                                 bptr->type = BBTYPE_STD;
1654                                 bptr->branchrefs = NULL;
1655                                 m->basicblockindex[p] = b_count;
1656                                 bptr->pre_count = 0;
1657                                 bptr++;
1658                                 b_count++;
1659                                 (bptr - 1)->next = bptr;
1660                         }
1661                 }
1662
1663                 /* allocate additional block at end */
1664
1665                 bptr->instack = bptr->outstack = NULL;
1666                 bptr->indepth = bptr->outdepth = 0;
1667                 bptr->iinstr = NULL;
1668                 (bptr - 1)->icount = (m->instructions + m->instructioncount) - (bptr - 1)->iinstr;
1669                 bptr->icount = 0;
1670                 bptr->mpc = -1;
1671                 bptr->flags = -1;
1672                 bptr->lflags = 0;
1673                 bptr->type = BBTYPE_STD;
1674                 bptr->branchrefs = NULL;
1675                 bptr->pre_count = 0;
1676                 bptr->debug_nr = m->c_debug_nr++;
1677                 (bptr - 1)->next = bptr;
1678                 bptr->next = NULL;
1679
1680                 if (cd->exceptiontablelength > 0) {
1681                         cd->exceptiontable[cd->exceptiontablelength - 1].down = NULL;
1682                 }
1683                 
1684                 for (i = 0; i < cd->exceptiontablelength; ++i) {
1685                         p = cd->exceptiontable[i].startpc;
1686                         cd->exceptiontable[i].start = m->basicblocks + m->basicblockindex[p];
1687
1688                         p = cd->exceptiontable[i].endpc;
1689                         cd->exceptiontable[i].end = (p == inline_env->method->jcodelength) ? (m->basicblocks + m->basicblockcount /*+ 1*/) : (m->basicblocks + m->basicblockindex[p]);
1690
1691                         p = cd->exceptiontable[i].handlerpc;
1692                         cd->exceptiontable[i].handler = m->basicblocks + m->basicblockindex[p];
1693             }
1694         }
1695         
1696         if (useinlining) inlining_cleanup(inline_env);
1697
1698         /* just return methodinfo* to signal everything was ok */
1699
1700         return m;
1701 }
1702
1703
1704 /*
1705  * These are local overrides for various environment variables in Emacs.
1706  * Please do not remove this and leave it at the end of the file, where
1707  * Emacs will automagically detect them.
1708  * ---------------------------------------------------------------------
1709  * Local variables:
1710  * mode: c
1711  * indent-tabs-mode: t
1712  * c-basic-offset: 4
1713  * tab-width: 4
1714  * End:
1715  */
1716