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