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