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