8a7a7c40c83a40c8d45705f446b0ffa039660d6f
[cacao.git] / ncomp / nparse.c
1 /****************************** ncomp/nparse.c *********************************
2
3         Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
4
5         See file COPYRIGHT for information on usage and disclaimer of warranties
6
7         Parser for JavaVM to intermediate code translation
8         
9         Author: Andreas  Krall      EMAIL: cacao@complang.tuwien.ac.at
10
11         Last Change: 1998/05/07
12
13 *******************************************************************************/
14
15 #include "math.h"
16
17 /*********************** function allocate_literals ****************************
18
19         Scans the JavaVM code of a method and allocates string literals. Needed
20         to generate the same addresses as the old JIT compiler.
21         
22 *******************************************************************************/
23
24 static void allocate_literals()
25 {
26         int     p, nextp;
27         int     opcode, i;
28         s4      num;
29         unicode *s;
30
31         for (p = 0; p < jcodelength; p = nextp) {
32
33                 opcode = jcode[p];
34                 nextp = p + jcommandsize[opcode];
35
36                 switch (opcode) {
37                         case JAVA_WIDE:
38                                 if (code_get_u1(p + 1) == JAVA_IINC)
39                                         nextp = p + 6;
40                                 else
41                                         nextp = p + 4;
42                                 break;
43                                                         
44                         case JAVA_LOOKUPSWITCH:
45                                 nextp = ALIGN((p + 1), 4);
46                                 num = code_get_u4(nextp + 4);
47                                 nextp = nextp + 8 + 8 * num;
48                                 break;
49
50                         case JAVA_TABLESWITCH:
51                                 nextp = ALIGN ((p + 1),4);
52                                 num = code_get_s4(nextp + 4);
53                                 num = code_get_s4(nextp + 8) - num;
54                                 nextp = nextp + 16 + 4 * num;
55                                 break;
56
57                         case JAVA_LDC1:
58                                 i = code_get_u1(p+1);
59                                 goto pushconstantitem;
60                         case JAVA_LDC2:
61                         case JAVA_LDC2W:
62                                 i = code_get_u2(p + 1);
63                         pushconstantitem:
64                                 if (class_constanttype(class, i) == CONSTANT_String) {
65                                         s = class_getconstant(class, i, CONSTANT_String);
66                                         (void) literalstring_new(s);
67                                         }
68                                 break;
69                         } /* end switch */
70                 } /* end while */
71 }
72
73
74
75 /*******************************************************************************
76
77         function 'parse' scans the JavaVM code and generates intermediate code
78
79         During parsing the block index table is used to store at bit pos 0
80         a flag which marks basic block starts and at position 1 to 31 the
81         intermediate instruction index. After parsing the block index table
82         is scanned, for marked positions a block is generated and the block
83         number is stored in the block index table.
84
85 *******************************************************************************/
86
87 /* intermediate code generating macros */
88
89 #define PINC           iptr++;ipc++
90 #define LOADCONST_I(v) iptr->opc=ICMD_ICONST;iptr->op1=0;iptr->val.i=(v);PINC
91 #define LOADCONST_L(v) iptr->opc=ICMD_LCONST;iptr->op1=0;iptr->val.l=(v);PINC
92 #define LOADCONST_F(v) iptr->opc=ICMD_FCONST;iptr->op1=0;iptr->val.f=(v);PINC
93 #define LOADCONST_D(v) iptr->opc=ICMD_DCONST;iptr->op1=0;iptr->val.d=(v);PINC
94 #define LOADCONST_A(v) iptr->opc=ICMD_ACONST;iptr->op1=0;iptr->val.a=(v);PINC
95 #define OP(o)          iptr->opc=(o);iptr->op1=0;iptr->val.l=0;PINC
96 #define OP1(o,o1)      iptr->opc=(o);iptr->op1=(o1);iptr->val.l=(0);PINC
97 #define OP2I(o,o1,v)   iptr->opc=(o);iptr->op1=(o1);iptr->val.i=(v);PINC
98 #define OP2A(o,o1,v)   iptr->opc=(o);iptr->op1=(o1);iptr->val.a=(v);PINC
99 #define BUILTIN1(v,t)  isleafmethod=false;iptr->opc=ICMD_BUILTIN1;iptr->op1=t;\
100                        iptr->val.a=(v);PINC
101 #define BUILTIN2(v,t)  isleafmethod=false;iptr->opc=ICMD_BUILTIN2;iptr->op1=t;\
102                        iptr->val.a=(v);PINC
103 #define BUILTIN3(v,t)  isleafmethod=false;iptr->opc=ICMD_BUILTIN3;iptr->op1=t;\
104                        iptr->val.a=(v);PINC
105
106
107 /* block generating and checking macros */
108
109 #define block_insert(i)    {if(!(block_index[i]&1))\
110                                {b_count++;block_index[i] |= 1;}}
111 #define bound_check(i)     {if((i< 0) || (i>=jcodelength)) \
112                                panic("branch target out of code-boundary");}
113 #define bound_check1(i)    {if((i< 0) || (i>jcodelength)) \
114                                panic("branch target out of code-boundary");}
115
116
117 static void parse()
118 {
119         int  p;                     /* java instruction counter                   */
120         int  nextp;                 /* start of next java instruction             */
121         int  opcode;                /* java opcode                                */
122         int  i;                     /* temporary for different uses (counters)    */
123         int  ipc = 0;               /* intermediate instruction counter           */
124         int  b_count = 0;           /* basic block counter                        */
125         int  s_count = 0;           /* stack element counter                      */
126         bool blockend = false;      /* true if basic block end has reached        */
127         bool iswide = false;        /* true if last instruction was a wide        */
128         instruction *iptr;          /* current pointer into instruction array     */
129
130
131         /* allocate instruction array and block index table */
132         
133         /* 1 additional for end ipc and 3 for loop unrolling */
134         
135         block_index = DMNEW(int, jcodelength + 3);
136
137         /* 1 additional for TRACEBUILTIN and 4 for MONITORENTER/EXIT */
138         /* additional MONITOREXITS are reached by branches which are 3 bytes */
139         
140         iptr = instr = DMNEW(instruction, jcodelength + 5);
141         
142         /* initialize block_index table (unrolled four times) */
143
144         {
145         int *ip;
146         
147         for (i = 0, ip = block_index; i <= jcodelength; i += 4, ip += 4) {
148                 ip[0] = 0;
149                 ip[1] = 0;
150                 ip[2] = 0;
151                 ip[3] = 0;
152                 }
153         }
154
155         /* compute branch targets of exception table */
156
157         for (i = 0; i < exceptiontablelength; i++) {
158                 p = extable[i].startpc;
159                 bound_check(p);
160                 block_insert(p);
161                 p = extable[i].endpc;
162                 bound_check1(p);
163                 if (p < jcodelength)
164                         block_insert(p);
165                 p = extable[i].handlerpc;
166                 bound_check(p);
167                 block_insert(p);
168                 }
169
170         s_count = 1 + exceptiontablelength; /* initialize stack element counter   */
171
172         if (runverbose) {
173 /*              isleafmethod=false; */
174                 }
175
176 #ifdef USE_THREADS
177         if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
178                 isleafmethod=false;
179                 }                       
180 #endif
181
182         /* scan all java instructions */
183
184         for (p = 0; p < jcodelength; p = nextp) {
185
186                 opcode = code_get_u1 (p);           /* fetch op code                  */
187
188                 block_index[p] |= (ipc << 1);       /* store intermediate count       */
189
190                 if (blockend) {
191                         block_insert(p);                /* start new block                */
192                         blockend = false;
193                         }
194
195                 nextp = p + jcommandsize[opcode];   /* compute next instruction start */
196                 s_count += stackreq[opcode];            /* compute stack element count    */
197
198                 switch (opcode) {
199
200                         case JAVA_NOP:
201                                 break;
202
203                         /* pushing constants onto the stack p */
204
205                         case JAVA_BIPUSH:
206                                 LOADCONST_I(code_get_s1(p+1));
207                                 break;
208
209                         case JAVA_SIPUSH:
210                                 LOADCONST_I(code_get_s2(p+1));
211                                 break;
212
213                         case JAVA_LDC1:
214                                 i = code_get_u1(p+1);
215                                 goto pushconstantitem;
216                         case JAVA_LDC2:
217                         case JAVA_LDC2W:
218                                 i = code_get_u2(p + 1);
219
220                         pushconstantitem:
221
222                                 if (i >= class->cpcount) 
223                                         panic ("Attempt to access constant outside range");
224
225                                 switch (class->cptags[i]) {
226                                         case CONSTANT_Integer:
227                                                 LOADCONST_I(((constant_integer*)
228                                                              (class->cpinfos[i]))->value);
229                                                 break;
230                                         case CONSTANT_Long:
231                                                 LOADCONST_L(((constant_long*)
232                                                              (class->cpinfos[i]))->value);
233                                                 break;
234                                         case CONSTANT_Float:
235                                                 LOADCONST_F(((constant_float*)
236                                                              (class->cpinfos[i]))->value);
237                                                 break;
238                                         case CONSTANT_Double:
239                                                 LOADCONST_D(((constant_double*)
240                                                              (class->cpinfos[i]))->value);
241                                                 break;
242                                         case CONSTANT_String:
243                                                 LOADCONST_A(literalstring_new((unicode*)
244                                                                               (class->cpinfos[i])));
245                                                 break;
246                                         default: panic("Invalid constant type to push");
247                                         }
248                                 break;
249
250                         case JAVA_ACONST_NULL:
251                                 LOADCONST_A(NULL);
252                                 break;
253
254                         case JAVA_ICONST_M1:
255                         case JAVA_ICONST_0:
256                         case JAVA_ICONST_1:
257                         case JAVA_ICONST_2:
258                         case JAVA_ICONST_3:
259                         case JAVA_ICONST_4:
260                         case JAVA_ICONST_5:
261                                 LOADCONST_I(opcode - JAVA_ICONST_0);
262                                 break;
263
264                         case JAVA_LCONST_0:
265                         case JAVA_LCONST_1:
266                                 LOADCONST_L(opcode - JAVA_LCONST_0);
267                                 break;
268
269                         case JAVA_FCONST_0:
270                         case JAVA_FCONST_1:
271                         case JAVA_FCONST_2:
272                                 LOADCONST_F(opcode - JAVA_FCONST_0);
273                                 break;
274
275                         case JAVA_DCONST_0:
276                         case JAVA_DCONST_1:
277                                 LOADCONST_D(opcode - JAVA_DCONST_0);
278                                 break;
279
280                         /* loading variables onto the stack */
281
282                         case JAVA_ILOAD:
283                         case JAVA_LLOAD:
284                         case JAVA_FLOAD:
285                         case JAVA_DLOAD:
286                         case JAVA_ALOAD:
287                                 if (!iswide)
288                                         i = code_get_u1(p+1);
289                                 else {
290                                         i = code_get_u2(p+1);
291                                         nextp = p+3;
292                                         iswide = false;
293                                         }
294                                 OP1(opcode, i);
295                                 break;
296
297                         case JAVA_ILOAD_0:
298                         case JAVA_ILOAD_1:
299                         case JAVA_ILOAD_2:
300                         case JAVA_ILOAD_3:
301                                 OP1(ICMD_ILOAD, opcode - JAVA_ILOAD_0);
302                                 break;
303
304                         case JAVA_LLOAD_0:
305                         case JAVA_LLOAD_1:
306                         case JAVA_LLOAD_2:
307                         case JAVA_LLOAD_3:
308                                 OP1(ICMD_LLOAD, opcode - JAVA_LLOAD_0);
309                                 break;
310
311                         case JAVA_FLOAD_0:
312                         case JAVA_FLOAD_1:
313                         case JAVA_FLOAD_2:
314                         case JAVA_FLOAD_3:
315                                 OP1(ICMD_FLOAD, opcode - JAVA_FLOAD_0);
316                                 break;
317
318                         case JAVA_DLOAD_0:
319                         case JAVA_DLOAD_1:
320                         case JAVA_DLOAD_2:
321                         case JAVA_DLOAD_3:
322                                 OP1(ICMD_DLOAD, opcode - JAVA_DLOAD_0);
323                                 break;
324
325                         case JAVA_ALOAD_0:
326                         case JAVA_ALOAD_1:
327                         case JAVA_ALOAD_2:
328                         case JAVA_ALOAD_3:
329                                 OP1(ICMD_ALOAD, opcode - JAVA_ALOAD_0);
330                                 break;
331
332                         /* storing stack values into local variables */
333
334                         case JAVA_ISTORE:
335                         case JAVA_LSTORE:
336                         case JAVA_FSTORE:
337                         case JAVA_DSTORE:
338                         case JAVA_ASTORE:
339                                 if (!iswide)
340                                         i = code_get_u1(p+1);
341                                 else {
342                                         i = code_get_u2(p+1);
343                                         iswide=false;
344                                         nextp = p+3;
345                                         }
346                                 OP1(opcode, i);
347                                 break;
348
349                         case JAVA_ISTORE_0:
350                         case JAVA_ISTORE_1:
351                         case JAVA_ISTORE_2:
352                         case JAVA_ISTORE_3:
353                                 OP1(ICMD_ISTORE, opcode - JAVA_ISTORE_0);
354                                 break;
355
356                         case JAVA_LSTORE_0:
357                         case JAVA_LSTORE_1:
358                         case JAVA_LSTORE_2:
359                         case JAVA_LSTORE_3:
360                                 OP1(ICMD_LSTORE, opcode - JAVA_LSTORE_0);
361                                 break;
362
363                         case JAVA_FSTORE_0:
364                         case JAVA_FSTORE_1:
365                         case JAVA_FSTORE_2:
366                         case JAVA_FSTORE_3:
367                                 OP1(ICMD_FSTORE, opcode - JAVA_FSTORE_0);
368                                 break;
369
370                         case JAVA_DSTORE_0:
371                         case JAVA_DSTORE_1:
372                         case JAVA_DSTORE_2:
373                         case JAVA_DSTORE_3:
374                                 OP1(ICMD_DSTORE, opcode - JAVA_DSTORE_0);
375                                 break;
376
377                         case JAVA_ASTORE_0:
378                         case JAVA_ASTORE_1:
379                         case JAVA_ASTORE_2:
380                         case JAVA_ASTORE_3:
381                                 OP1(ICMD_ASTORE, opcode - JAVA_ASTORE_0);
382                                 break;
383
384                         case JAVA_IINC:
385                                 {
386                                 int v;
387                                 
388                                 if (!iswide) {
389                                         i = code_get_u1(p + 1);
390                                         v = code_get_s1(p + 2);
391                                         }
392                                 else {
393                                         i = code_get_u2(p + 1);
394                                         v = code_get_s2(p + 3);
395                                         iswide = false;
396                                         nextp = p+5;
397                                         }
398                                 OP2I(opcode, i, v);
399                                 }
400                                 break;
401
402                         /* wider index for loading, storing and incrementing */
403
404                         case JAVA_WIDE:
405                                 iswide = true;
406                                 nextp = p + 1;
407                                 break;
408
409                         /*********************** managing arrays **************************/
410
411                         case JAVA_NEWARRAY:
412                                 OP2I(ICMD_CHECKASIZE, 0, 0);
413                                 switch (code_get_s1(p+1)) {
414                                         case 4:
415                                                 BUILTIN1((functionptr)builtin_newarray_boolean, TYPE_ADR);
416                                                 break;
417                                         case 5:
418                                                 BUILTIN1((functionptr)builtin_newarray_char, TYPE_ADR);
419                                                 break;
420                                         case 6:
421                                                 BUILTIN1((functionptr)builtin_newarray_float, TYPE_ADR);
422                                                 break;
423                                         case 7:
424                                                 BUILTIN1((functionptr)builtin_newarray_double, TYPE_ADR);
425                                                 break;
426                                         case 8:
427                                                 BUILTIN1((functionptr)builtin_newarray_byte, TYPE_ADR);
428                                                 break;
429                                         case 9:
430                                                 BUILTIN1((functionptr)builtin_newarray_short, TYPE_ADR);
431                                                 break;
432                                         case 10:
433                                                 BUILTIN1((functionptr)builtin_newarray_int, TYPE_ADR);
434                                                 break;
435                                         case 11:
436                                                 BUILTIN1((functionptr)builtin_newarray_long, TYPE_ADR);
437                                                 break;
438                                         default: panic("Invalid array-type to create");
439                                         }
440                                 break;
441
442                         case JAVA_ANEWARRAY:
443                                 OP2I(ICMD_CHECKASIZE, 0, 0);
444                                 i = code_get_u2(p+1);
445                                 /* array or class type ? */
446                                 if (class_constanttype (class, i) == CONSTANT_Arraydescriptor) {
447                                         LOADCONST_A(class_getconstant(class, i,
448                                                                       CONSTANT_Arraydescriptor));
449                                         BUILTIN2((functionptr)builtin_newarray_array, TYPE_ADR);
450                                         }
451                                 else {
452                                         LOADCONST_A(class_getconstant(class, i, CONSTANT_Class));
453                                         BUILTIN2((functionptr)builtin_anewarray, TYPE_ADR);
454                                         }
455                                 break;
456
457                         case JAVA_MULTIANEWARRAY:
458                                 isleafmethod=false;
459                                 i = code_get_u2(p+1);
460                                 {
461                                 int v = code_get_u1(p+3);
462                                 constant_arraydescriptor *desc =
463                                     class_getconstant (class, i, CONSTANT_Arraydescriptor);
464                                 OP2A(opcode, v, desc);
465                                 }
466                                 break;
467
468                         case JAVA_IFEQ:
469                         case JAVA_IFLT:
470                         case JAVA_IFLE:
471                         case JAVA_IFNE:
472                         case JAVA_IFGT:
473                         case JAVA_IFGE:
474                         case JAVA_IFNULL:
475                         case JAVA_IFNONNULL:
476                         case JAVA_IF_ICMPEQ:
477                         case JAVA_IF_ICMPNE:
478                         case JAVA_IF_ICMPLT:
479                         case JAVA_IF_ICMPGT:
480                         case JAVA_IF_ICMPLE:
481                         case JAVA_IF_ICMPGE:
482                         case JAVA_IF_ACMPEQ:
483                         case JAVA_IF_ACMPNE:
484                         case JAVA_GOTO:
485                         case JAVA_JSR:
486                                 i = p + code_get_s2(p+1);
487                                 bound_check(i);
488                                 block_insert(i);
489                                 blockend = true;
490                                 OP1(opcode, i);
491                                 break;
492                         case JAVA_GOTO_W:
493                         case JAVA_JSR_W:
494                                 i = p + code_get_s4(p+1);
495                                 bound_check(i);
496                                 block_insert(i);
497                                 blockend = true;
498                                 OP1(opcode, i);
499                                 break;
500
501                         case JAVA_RET:
502                                 if (!iswide)
503                                         i = code_get_u1(p+1);
504                                 else {
505                                         i = code_get_u2(p+1);
506                                         nextp = p+3;
507                                         iswide = false;
508                                         }
509                                 blockend = true;
510                                 OP1(opcode, i);
511                                 break;
512
513                         case JAVA_IRETURN:
514                         case JAVA_LRETURN:
515                         case JAVA_FRETURN:
516                         case JAVA_DRETURN:
517                         case JAVA_ARETURN:
518                         case JAVA_RETURN:
519                                 blockend = true;
520                                 OP(opcode);
521                                 break;
522
523                         case JAVA_ATHROW:
524                                 blockend = true;
525                                 OP(opcode);
526                                 break;
527                                 
528
529                         /**************** table jumps *****************/
530
531                         case JAVA_LOOKUPSWITCH:
532                                 {
533                                 s4 num, j;
534
535                                 blockend = true;
536                                 nextp = ALIGN((p + 1), 4);
537                                 OP2A(opcode, 0, jcode + nextp);
538
539                                 /* default target */
540
541                                 j =  p + code_get_s4(nextp);
542                                 *((s4*)(jcode + nextp)) = j;     /* restore for little endian */
543                                 nextp += 4;
544                                 bound_check(j);
545                                 block_insert(j);
546
547                                 /* number of pairs */
548
549                                 num = code_get_u4(nextp);
550                                 *((s4*)(jcode + nextp)) = num;
551                                 nextp += 4;
552
553                                 for (i = 0; i < num; i++) {
554
555                                         /* value */
556
557                                         j = code_get_s4(nextp);
558                                         *((s4*)(jcode + nextp)) = j; /* restore for little endian */
559                                         nextp += 4;
560
561                                         /* target */
562
563                                         j = p + code_get_s4(nextp);
564                                         *((s4*)(jcode + nextp)) = j; /* restore for little endian */
565                                         nextp += 4;
566                                         bound_check(j);
567                                         block_insert(j);
568                                         }
569
570                                 break;
571                                 }
572
573
574                         case JAVA_TABLESWITCH:
575                                 {
576                                 s4 num, j;
577
578                                 blockend = true;
579                                 nextp = ALIGN((p + 1), 4);
580                                 OP2A(opcode, 0, jcode + nextp);
581
582                                 /* default target */
583
584                                 j = p + code_get_s4(nextp);
585                                 *((s4*)(jcode + nextp)) = j;     /* restore for little endian */
586                                 nextp += 4;
587                                 bound_check(j);
588                                 block_insert(j);
589
590                                 /* lower bound */
591
592                                 j = code_get_s4(nextp);
593                                 *((s4*)(jcode + nextp)) = j;     /* restore for little endian */
594                                 nextp += 4;
595
596                                 /* upper bound */
597
598                                 num = code_get_s4(nextp);
599                                 *((s4*)(jcode + nextp)) = num;   /* restore for little endian */
600                                 nextp += 4;
601
602                                 num -= j;
603
604                                 for (i = 0; i <= num; i++) {
605                                         j = p + code_get_s4(nextp);
606                                         *((s4*)(jcode + nextp)) = j; /* restore for little endian */
607                                         nextp += 4;
608                                         bound_check(j);
609                                         block_insert(j);
610                                         }
611
612                                 break;
613                                 }
614
615
616                         /************ load and store of object fields ********/
617
618                         case JAVA_AASTORE:
619                                 BUILTIN3((functionptr) new_builtin_aastore, TYPE_VOID);
620                                 break;
621
622                         case JAVA_PUTSTATIC:
623                         case JAVA_GETSTATIC:
624                                 i = code_get_u2(p + 1);
625                                 {
626                                 constant_FMIref *fr;
627                                 fieldinfo *fi;
628                                 fr = class_getconstant (class, i, CONSTANT_Fieldref);
629                                 fi = class_findfield (fr->class, fr->name, fr->descriptor);
630                                 compiler_addinitclass (fr->class);
631                                 OP2A(opcode, fi->type, fi);
632                                 }
633                                 break;
634                         case JAVA_PUTFIELD:
635                         case JAVA_GETFIELD:
636                                 i = code_get_u2(p + 1);
637                                 {
638                                 constant_FMIref *fr;
639                                 fieldinfo *fi;
640                                 fr = class_getconstant (class, i, CONSTANT_Fieldref);
641                                 fi = class_findfield (fr->class, fr->name, fr->descriptor);
642                                 OP2A(opcode, fi->type, fi);
643                                 }
644                                 break;
645
646
647                         /*** method invocation ***/
648
649                         case JAVA_INVOKESTATIC:
650                                 i = code_get_u2(p + 1);
651                                 {
652                                 constant_FMIref *mr;
653                                 methodinfo *mi;
654                                 
655                                 mr = class_getconstant (class, i, CONSTANT_Methodref);
656                                 mi = class_findmethod (mr->class, mr->name, mr->descriptor);
657                                 if (! (mi->flags & ACC_STATIC))
658                                         panic ("Static/Nonstatic mismatch calling static method");
659                                 descriptor2types(mi);
660                                 isleafmethod=false;
661                                 OP2A(opcode, mi->paramcount, mi);
662                                 }
663                                 break;
664                         case JAVA_INVOKESPECIAL:
665                         case JAVA_INVOKEVIRTUAL:
666                                 i = code_get_u2(p + 1);
667                                 {
668                                 constant_FMIref *mr;
669                                 methodinfo *mi;
670                                 
671                                 mr = class_getconstant (class, i, CONSTANT_Methodref);
672                                 mi = class_findmethod (mr->class, mr->name, mr->descriptor);
673                                 if (mi->flags & ACC_STATIC)
674                                         panic ("Static/Nonstatic mismatch calling static method");
675                                 descriptor2types(mi);
676                                 isleafmethod=false;
677                                 OP2A(opcode, mi->paramcount, mi);
678                                 }
679                                 break;
680                         case JAVA_INVOKEINTERFACE:
681                                 i = code_get_u2(p + 1);
682                                 {
683                                 constant_FMIref *mr;
684                                 methodinfo *mi;
685                                 
686                                 mr = class_getconstant (class, i, CONSTANT_InterfaceMethodref);
687                                 mi = class_findmethod (mr->class, mr->name, mr->descriptor);
688                                 if (mi->flags & ACC_STATIC)
689                                         panic ("Static/Nonstatic mismatch calling static method");
690                                 descriptor2types(mi);
691                                 isleafmethod=false;
692                                 OP2A(opcode, mi->paramcount, mi);
693                                 }
694                                 break;
695
696                         /***** miscellaneous object operations ****/
697
698                         case JAVA_NEW:
699                                 i = code_get_u2 (p+1);
700                                 LOADCONST_A(class_getconstant(class, i, CONSTANT_Class));
701                                 BUILTIN1((functionptr) builtin_new, TYPE_ADR);
702                                 break;
703
704                         case JAVA_CHECKCAST:
705                                 i = code_get_u2(p+1);
706
707                                 /* array type cast-check */
708                                 if (class_constanttype (class, i) == CONSTANT_Arraydescriptor) {
709                                         LOADCONST_A(class_getconstant(class, i, CONSTANT_Arraydescriptor));
710                                         BUILTIN2((functionptr) new_builtin_checkarraycast, TYPE_ADR);
711                                         }
712                                 else { /* object type cast-check */
713                                         OP2A(opcode, 1, (class_getconstant(class, i, CONSTANT_Class)));
714                                         }
715                                 break;
716
717                         case JAVA_INSTANCEOF:
718                                 i = code_get_u2(p+1);
719
720                                 /* array type cast-check */
721                                 if (class_constanttype (class, i) == CONSTANT_Arraydescriptor) {
722                                         LOADCONST_A(class_getconstant(class, i, CONSTANT_Arraydescriptor));
723                                         BUILTIN2((functionptr) builtin_arrayinstanceof, TYPE_INT);
724                                         }
725                                 else { /* object type cast-check */
726                                         OP2A(opcode, 1, (class_getconstant(class, i, CONSTANT_Class)));
727                                         }
728                                 break;
729
730                         case JAVA_MONITORENTER:
731 #ifdef USE_THREADS
732                                 if (checksync) {
733 #ifdef SOFTNULLPTRCHECK
734                                         if (checknull) {
735                                                 BUILTIN1((functionptr) new_builtin_monitorenter, TYPE_VOID);
736                                                 }
737                                         else {
738 /*                                              BUILTIN1((functionptr) builtin_monitorenter, TYPE_VOID); */
739                                                 BUILTIN1((functionptr) new_builtin_monitorenter, TYPE_VOID);
740                                                 }
741 #else
742                                         BUILTIN1((functionptr) builtin_monitorenter, TYPE_VOID);
743 #endif
744                                         }
745                                 else
746 #endif
747                                         {
748                                         OP(ICMD_NULLCHECKPOP);
749                                         }
750                                 break;
751
752                         case JAVA_MONITOREXIT:
753 #ifdef USE_THREADS
754                                 if (checksync) {
755                                         BUILTIN1((functionptr) builtin_monitorexit, TYPE_VOID);
756                                         }
757                                 else
758 #endif
759                                         {
760                                         OP(ICMD_POP);
761                                         }
762                                 break;
763
764                         /************** any other basic operation **********/
765
766                         case JAVA_IDIV:
767                                 OP(opcode);
768                                 break;
769
770                         case JAVA_IREM:
771                                 OP(opcode);
772                                 break;
773
774                         case JAVA_LDIV:
775                                 OP(opcode);
776                                 break;
777
778                         case JAVA_LREM:
779                                 OP(opcode);
780                                 break;
781
782                         case JAVA_FREM:
783                                 BUILTIN2((functionptr) builtin_frem, TYPE_FLOAT);
784                                 break;
785
786                         case JAVA_DREM:
787                                 BUILTIN2((functionptr) builtin_drem, TYPE_DOUBLE);
788                                 break;
789
790                         case JAVA_F2I:
791                                 if (checkfloats) {
792                                         BUILTIN1((functionptr) builtin_f2i, TYPE_INT);
793                                         }
794                                 else {
795                                         OP(opcode);
796                                         }
797                                 break;
798
799                         case JAVA_F2L:
800                                 if (checkfloats) {
801                                         BUILTIN1((functionptr) builtin_f2l, TYPE_LONG);
802                                         }
803                                 else {
804                                         OP(opcode);
805                                         }
806                                 break;
807
808                         case JAVA_D2I:
809                                 if (checkfloats) {
810                                         BUILTIN1((functionptr) builtin_d2i, TYPE_INT);
811                                         }
812                                 else {
813                                         OP(opcode);
814                                         }
815                                 break;
816
817                         case JAVA_D2L:
818                                 if (checkfloats) {
819                                         BUILTIN1((functionptr) builtin_d2l, TYPE_LONG);
820                                         }
821                                 else {
822                                         OP(opcode);
823                                         }
824                                 break;
825
826                         case JAVA_BREAKPOINT:
827                                 panic("Illegal opcode Breakpoint encountered");
828                                 break;
829
830                         case 203:
831                         case 204:
832                         case 205:
833                         case 206:
834                         case 207:
835                         case 208:
836                         case 209:
837                         case 210:
838                         case 211:
839                         case 212:
840                         case 213:
841                         case 214:
842                         case 215:
843                         case 216:
844                         case 217:
845                         case 218:
846                         case 219:
847                         case 220:
848                         case 221:
849                         case 222:
850                         case 223:
851                         case 224:
852                         case 225:
853                         case 226:
854                         case 227:
855                         case 228:
856                         case 229:
857                         case 230:
858                         case 231:
859                         case 232:
860                         case 233:
861                         case 234:
862                         case 235:
863                         case 236:
864                         case 237:
865                         case 238:
866                         case 239:
867                         case 240:
868                         case 241:
869                         case 242:
870                         case 243:
871                         case 244:
872                         case 245:
873                         case 246:
874                         case 247:
875                         case 248:
876                         case 249:
877                         case 250:
878                         case 251:
879                         case 252:
880                         case 253:
881                         case 254:
882                         case 255:
883                                 printf("Illegal opcode %d at instr %d", opcode, ipc);
884                                 panic("encountered");
885                                 break;
886
887                         default:
888                                 OP(opcode);
889                                 break;
890
891                         } /* end switch */
892
893                 } /* end for */
894
895         if (p != jcodelength)
896                 panic("Command-sequence crosses code-boundary");
897
898         if (!blockend)
899                 panic("Code does not end with branch/return/athrow - stmt");    
900
901         /* adjust block count if target 0 is not first intermediate instruction   */
902
903         if (!block_index[0] || (block_index[0] > 1))
904                 b_count++;
905
906         /* copy local to global variables   */
907
908         instr_count = ipc;
909         block_count = b_count;
910         stack_count = s_count + block_count * maxstack;
911
912         /* allocate stack table */
913
914         stack = DMNEW(stackelement, stack_count);
915
916         {
917         basicblock  *bptr;
918
919         bptr = block = DMNEW(basicblock, b_count + 1);    /* one more for end ipc */
920
921         b_count = 0;
922         
923         /* additional block if target 0 is not first intermediate instruction     */
924
925         if (!block_index[0] || (block_index[0] > 1)) {
926                 bptr->ipc = 0;
927                 bptr->mpc = -1;
928                 bptr->flags = -1;
929                 bptr->type = BBTYPE_STD;
930                 bptr->branchrefs = NULL;
931                 bptr->pre_count = 0;
932                 bptr++;
933                 b_count++;
934                 }
935
936         /* allocate blocks */
937
938         for (p = 0; p < jcodelength; p++)
939                 if (block_index[p] & 1) {
940                         bptr->ipc = block_index[p] >> 1;
941                         bptr->mpc = -1;
942                         bptr->flags = -1;
943                         bptr->type = BBTYPE_STD;
944                         bptr->branchrefs = NULL;
945                         block_index[p] = b_count;
946                         bptr->pre_count = 0;
947                         bptr++;
948                         b_count++;
949                         }
950
951         /* allocate additional block at end */
952
953         bptr->ipc = instr_count;
954         bptr->mpc = -1;
955         bptr->flags = -1;
956         bptr->type = BBTYPE_STD;
957         bptr->branchrefs = NULL;
958         bptr->pre_count = 0;
959         }
960 }