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