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