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