* src/vm/jit/parse.c (parseRT.h, parseXTA.h, inline.h, parseRTprint.h):
[cacao.git] / src / vm / jit / parse.c
1 /* src/vm/jit/parse.c - parser for JavaVM to intermediate code translation
2
3    Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, Institut f. Computersprachen - TU Wien
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., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25    Contact: cacao@cacaojvm.org
26
27    Author: Andreas Krall
28
29    Changes: Carolyn Oates
30             Edwin Steiner
31             Joseph Wenninger
32             Christian Thalinger
33
34    $Id: parse.c 4449 2006-02-05 23:02:05Z edwin $
35
36 */
37
38
39 #include <assert.h>
40 #include <string.h>
41
42 #include "config.h"
43
44 #include "vm/types.h"
45
46 #include "mm/memory.h"
47 #include "native/native.h"
48 #include "toolbox/logging.h"
49 #include "vm/builtin.h"
50 #include "vm/exceptions.h"
51 #include "vm/global.h"
52 #include "vm/linker.h"
53 #include "vm/loader.h"
54 #include "vm/resolve.h"
55 #include "vm/options.h"
56 #include "vm/statistics.h"
57 #include "vm/stringlocal.h"
58 #include "vm/jit/asmpart.h"
59 #include "vm/jit/jit.h"
60 #include "vm/jit/parse.h"
61 #include "vm/jit/patcher.h"
62 #include "vm/jit/loop/loop.h"
63
64 /*******************************************************************************
65
66         function 'parse' scans the JavaVM code and generates intermediate code
67
68         During parsing the block index table is used to store at bit pos 0
69         a flag which marks basic block starts and at position 1 to 31 the
70         intermediate instruction index. After parsing the block index table
71         is scanned, for marked positions a block is generated and the block
72         number is stored in the block index table.
73
74 *******************************************************************************/
75
76 static exceptiontable * fillextable(methodinfo *m, 
77                                                                         exceptiontable *extable, 
78                                                                         exceptiontable *raw_extable, 
79                                                                 int exceptiontablelength, 
80                                                                         int *label_index, 
81                                                                         int *block_count)
82 {
83         int b_count, p, src, insertBlock;
84         
85         if (exceptiontablelength == 0) 
86                 return extable;
87
88         b_count = *block_count;
89
90         for (src = exceptiontablelength-1; src >=0; src--) {
91                 p = raw_extable[src].startpc;
92                 if (label_index != NULL) p = label_index[p];
93                 extable->startpc = p;
94                 bound_check(p);
95                 block_insert(p);
96                 
97                 p = raw_extable[src].endpc; /* see JVM Spec 4.7.3 */
98                 if (p <= raw_extable[src].startpc) {
99                         *exceptionptr = new_verifyerror(m,
100                                 "Invalid exception handler range");
101                         return NULL;
102                 }
103
104                 if (p >m->jcodelength) {
105                         *exceptionptr = new_verifyerror(m,
106                                 "Invalid exception handler end is after code end");
107                         return NULL;
108                 }
109
110                 if (p<m->jcodelength) insertBlock=1; else insertBlock=0;
111                 if (label_index != NULL) p = label_index[p];
112                 extable->endpc = p;
113                 bound_check_exclusive(p);
114                 /* if (p < m->jcodelength) block_insert(p); */
115         if (insertBlock) 
116                         block_insert(p);
117
118                 p = raw_extable[src].handlerpc;
119                 if (label_index != NULL) p = label_index[p];
120                 extable->handlerpc = p;
121                 bound_check(p);
122                 block_insert(p);
123
124                 extable->catchtype  = raw_extable[src].catchtype;
125                 extable->next = NULL;
126                 extable->down = &extable[1];
127                 extable--;
128         }
129
130         *block_count = b_count;
131         return extable; /*&extable[i];*/  /* return the next free xtable* */
132 }
133
134
135
136 methodinfo *parse(methodinfo *m, codegendata *cd)
137 {
138         int  p;                     /* java instruction counter           */
139         int  nextp;                 /* start of next java instruction     */
140         int  opcode;                /* java opcode                        */
141         int  i;                     /* temporary for different uses (ctrs)*/
142         int  ipc = 0;               /* intermediate instruction counter   */
143         int  b_count = 0;           /* basic block counter                */
144         int  s_count = 0;           /* stack element counter              */
145         bool blockend = false;      /* true if basic block end has been reached   */
146         bool iswide = false;        /* true if last instruction was a wide*/
147         instruction *iptr;          /* current ptr into instruction array */
148         int gp;                     /* global java instruction counter    */
149
150         int *label_index = NULL;    /* label redirection table            */
151         int firstlocal = 0;         /* first local variable of method     */
152         exceptiontable* nextex;     /* points next free entry in extable  */
153         u1 *instructionstart;       /* 1 for pcs which are valid instr. starts    */
154
155         constant_classref  *cr;
156         constant_classref  *compr;
157         classinfo          *c;
158         builtintable_entry *bte;
159
160         u2 lineindex = 0;
161         u2 currentline = 0;
162         u2 linepcchange = 0;
163
164         u2 skipBasicBlockChange;
165
166         /* allocate instruction array and block index table */
167         
168         /* 1 additional for end ipc  */
169         m->basicblockindex = DMNEW(s4, m->jcodelength + 1);
170         memset(m->basicblockindex, 0, sizeof(s4) * (m->jcodelength + 1));
171
172         instructionstart = DMNEW(u1, m->jcodelength + 1);
173         memset(instructionstart, 0, sizeof(u1) * (m->jcodelength + 1));
174
175         /* 1 additional for TRACEBUILTIN and 4 for MONITORENTER/EXIT */
176         /* additional MONITOREXITS are reached by branches which are 3 bytes */
177         
178         iptr = m->instructions = DMNEW(instruction, m->jcodelength + 5);
179
180         /* Zero the intermediate instructions array so we don't have any
181          * invalid pointers in it if we cannot finish analyse_stack(). */
182
183         memset(iptr, 0, sizeof(instruction) * (m->jcodelength + 5));
184         
185         /* compute branch targets of exception table */
186
187         nextex = fillextable(m, 
188           &(cd->exceptiontable[cd->exceptiontablelength-1]), m->exceptiontable, m->exceptiontablelength, 
189           label_index, &b_count);
190         if (!nextex)
191                 return NULL;
192         s_count = 1 + m->exceptiontablelength; /* initialize stack element counter   */
193
194 #if defined(USE_THREADS)
195         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
196                 m->isleafmethod = false;
197         }                       
198 #endif
199
200         /* scan all java instructions */
201         currentline = 0;
202         linepcchange = 0;
203
204         if (m->linenumbercount == 0) {
205                 lineindex = 0;
206         } else {
207                 linepcchange = m->linenumbers[0].start_pc;
208         }
209
210         skipBasicBlockChange=0;
211         for (p = 0, gp = 0; p < m->jcodelength; gp += (nextp - p), p = nextp) {
212           
213                 /* mark this position as a valid instruction start */
214                 if (!iswide) {
215                         instructionstart[gp] = 1;
216                         if (linepcchange==p) {
217                                 if (m->linenumbercount > lineindex) {
218                                         currentline = m->linenumbers[lineindex].line_number;
219                                         lineindex++;
220                                         if (lineindex < m->linenumbercount)
221                                                 linepcchange = m->linenumbers[lineindex].start_pc;
222                                 }
223                         }
224                 }
225
226                 /* fetch next opcode  */
227
228                 opcode = code_get_u1(p, m);
229
230                 if (!skipBasicBlockChange) {
231                         m->basicblockindex[gp] |= (ipc << 1); /*store intermed cnt*/
232                 } else skipBasicBlockChange=0;
233
234                 /* some compilers put a JAVA_NOP after a blockend instruction */
235
236                 if ((opcode != JAVA_NOP) && (blockend == true)) {
237                         /* start new block */
238
239                         block_insert(gp);
240                         blockend = false;
241                 }
242
243                 nextp = p + jcommandsize[opcode];   /* compute next instruction start */
244
245                 if (nextp > m->jcodelength) {
246                         *exceptionptr = new_verifyerror(m,
247                                         "Unexpected end of bytecode");
248                         return NULL;
249                 }
250
251                 s_count += stackreq[opcode];            /* compute stack element count    */
252                 switch (opcode) {
253                 case JAVA_NOP:
254                         break;
255
256                         /* pushing constants onto the stack p */
257
258                 case JAVA_BIPUSH:
259                         LOADCONST_I(code_get_s1(p+1,m));
260                         break;
261
262                 case JAVA_SIPUSH:
263                         LOADCONST_I(code_get_s2(p+1,m));
264                         break;
265
266                 case JAVA_LDC1:
267                         i = code_get_u1(p + 1, m);
268                         goto pushconstantitem;
269
270                 case JAVA_LDC2:
271                 case JAVA_LDC2W:
272                         i = code_get_u2(p + 1, m);
273
274                 pushconstantitem:
275
276                         if (i >= m->class->cpcount) {
277                                 *exceptionptr = new_verifyerror(m,
278                                         "Attempt to access constant outside range");
279                                 return NULL;
280                         }
281
282                         switch (m->class->cptags[i]) {
283                         case CONSTANT_Integer:
284                                 LOADCONST_I(((constant_integer *) (m->class->cpinfos[i]))->value);
285                                 break;
286                         case CONSTANT_Long:
287                                 LOADCONST_L(((constant_long *) (m->class->cpinfos[i]))->value);
288                                 break;
289                         case CONSTANT_Float:
290                                 LOADCONST_F(((constant_float *) (m->class->cpinfos[i]))->value);
291                                 break;
292                         case CONSTANT_Double:
293                                 LOADCONST_D(((constant_double *) (m->class->cpinfos[i]))->value);
294                                 break;
295                         case CONSTANT_String:
296                                 LOADCONST_A(literalstring_new((utf *) (m->class->cpinfos[i])));
297                                 break;
298                         case CONSTANT_Class:
299                                 cr = (constant_classref *) (m->class->cpinfos[i]);
300
301                                 if (!resolve_classref(m, cr, resolveLazy, true,
302                                                                           true, &c))
303                                         return NULL;
304
305                                 /* if not resolved, c == NULL */
306
307                                 LOADCONST_A_CLASS(c, cr);
308                                 break;
309                         default:
310                                 *exceptionptr = new_verifyerror(m,
311                                                 "Invalid constant type to push");
312                                 return NULL;
313                         }
314                         break;
315
316                 case JAVA_ACONST_NULL:
317                         LOADCONST_A(NULL);
318                         break;
319
320                 case JAVA_ICONST_M1:
321                 case JAVA_ICONST_0:
322                 case JAVA_ICONST_1:
323                 case JAVA_ICONST_2:
324                 case JAVA_ICONST_3:
325                 case JAVA_ICONST_4:
326                 case JAVA_ICONST_5:
327                         LOADCONST_I(opcode - JAVA_ICONST_0);
328                         break;
329
330                 case JAVA_LCONST_0:
331                 case JAVA_LCONST_1:
332                         LOADCONST_L(opcode - JAVA_LCONST_0);
333                         break;
334
335                 case JAVA_FCONST_0:
336                 case JAVA_FCONST_1:
337                 case JAVA_FCONST_2:
338                         LOADCONST_F(opcode - JAVA_FCONST_0);
339                         break;
340
341                 case JAVA_DCONST_0:
342                 case JAVA_DCONST_1:
343                         LOADCONST_D(opcode - JAVA_DCONST_0);
344                         break;
345
346                         /* loading variables onto the stack */
347
348                 case JAVA_ILOAD:
349                 case JAVA_LLOAD:
350                 case JAVA_FLOAD:
351                 case JAVA_DLOAD:
352                 case JAVA_ALOAD:
353                         if (!iswide) {
354                                 i = code_get_u1(p + 1,m);
355                         } else {
356                                 i = code_get_u2(p + 1,m);
357                                 nextp = p + 3;
358                                 iswide = false;
359                         }
360                         OP1LOAD(opcode, i + firstlocal);
361                         break;
362
363                 case JAVA_ILOAD_0:
364                 case JAVA_ILOAD_1:
365                 case JAVA_ILOAD_2:
366                 case JAVA_ILOAD_3:
367                         OP1LOAD(ICMD_ILOAD, opcode - JAVA_ILOAD_0 + firstlocal);
368                         break;
369
370                 case JAVA_LLOAD_0:
371                 case JAVA_LLOAD_1:
372                 case JAVA_LLOAD_2:
373                 case JAVA_LLOAD_3:
374                         OP1LOAD(ICMD_LLOAD, opcode - JAVA_LLOAD_0 + firstlocal);
375                         break;
376
377                 case JAVA_FLOAD_0:
378                 case JAVA_FLOAD_1:
379                 case JAVA_FLOAD_2:
380                 case JAVA_FLOAD_3:
381                         OP1LOAD(ICMD_FLOAD, opcode - JAVA_FLOAD_0 + firstlocal);
382                         break;
383
384                 case JAVA_DLOAD_0:
385                 case JAVA_DLOAD_1:
386                 case JAVA_DLOAD_2:
387                 case JAVA_DLOAD_3:
388                         OP1LOAD(ICMD_DLOAD, opcode - JAVA_DLOAD_0 + firstlocal);
389                         break;
390
391                 case JAVA_ALOAD_0:
392                 case JAVA_ALOAD_1:
393                 case JAVA_ALOAD_2:
394                 case JAVA_ALOAD_3:
395                         OP1LOAD(ICMD_ALOAD, opcode - JAVA_ALOAD_0 + firstlocal);
396                         break;
397
398                         /* storing stack values into local variables */
399
400                 case JAVA_ISTORE:
401                 case JAVA_LSTORE:
402                 case JAVA_FSTORE:
403                 case JAVA_DSTORE:
404                 case JAVA_ASTORE:
405                         if (!iswide) {
406                                 i = code_get_u1(p + 1,m);
407                         } else {
408                                 i = code_get_u2(p + 1,m);
409                                 iswide = false;
410                                 nextp = p + 3;
411                         }
412                         OP1STORE(opcode, i + firstlocal);
413                         break;
414
415                 case JAVA_ISTORE_0:
416                 case JAVA_ISTORE_1:
417                 case JAVA_ISTORE_2:
418                 case JAVA_ISTORE_3:
419                         OP1STORE(ICMD_ISTORE, opcode - JAVA_ISTORE_0 + firstlocal);
420                         break;
421
422                 case JAVA_LSTORE_0:
423                 case JAVA_LSTORE_1:
424                 case JAVA_LSTORE_2:
425                 case JAVA_LSTORE_3:
426                         OP1STORE(ICMD_LSTORE, opcode - JAVA_LSTORE_0 + firstlocal);
427                         break;
428
429                 case JAVA_FSTORE_0:
430                 case JAVA_FSTORE_1:
431                 case JAVA_FSTORE_2:
432                 case JAVA_FSTORE_3:
433                         OP1STORE(ICMD_FSTORE, opcode - JAVA_FSTORE_0 + firstlocal);
434                         break;
435
436                 case JAVA_DSTORE_0:
437                 case JAVA_DSTORE_1:
438                 case JAVA_DSTORE_2:
439                 case JAVA_DSTORE_3:
440                         OP1STORE(ICMD_DSTORE, opcode - JAVA_DSTORE_0 + firstlocal);
441                         break;
442
443                 case JAVA_ASTORE_0:
444                 case JAVA_ASTORE_1:
445                 case JAVA_ASTORE_2:
446                 case JAVA_ASTORE_3:
447                         OP1STORE(ICMD_ASTORE, opcode - JAVA_ASTORE_0 + firstlocal);
448                         break;
449
450                 case JAVA_IINC:
451                         {
452                                 int v;
453                                 
454                                 if (!iswide) {
455                                         i = code_get_u1(p + 1,m);
456                                         v = code_get_s1(p + 2,m);
457
458                                 } else {
459                                         i = code_get_u2(p + 1,m);
460                                         v = code_get_s2(p + 3,m);
461                                         iswide = false;
462                                         nextp = p + 5;
463                                 }
464                                 INDEX_ONEWORD(i + firstlocal);
465                                 OP2I(opcode, i + firstlocal, v);
466                         }
467                         break;
468
469                         /* wider index for loading, storing and incrementing */
470
471                 case JAVA_WIDE:
472                         iswide = true;
473                         nextp = p + 1;
474                         break;
475
476                 /* managing arrays ****************************************************/
477
478                 case JAVA_NEWARRAY:
479                         switch (code_get_s1(p + 1, m)) {
480                         case 4:
481                                 bte = builtintable_get_internal(BUILTIN_newarray_boolean);
482                                 break;
483                         case 5:
484                                 bte = builtintable_get_internal(BUILTIN_newarray_char);
485                                 break;
486                         case 6:
487                                 bte = builtintable_get_internal(BUILTIN_newarray_float);
488                                 break;
489                         case 7:
490                                 bte = builtintable_get_internal(BUILTIN_newarray_double);
491                                 break;
492                         case 8:
493                                 bte = builtintable_get_internal(BUILTIN_newarray_byte);
494                                 break;
495                         case 9:
496                                 bte = builtintable_get_internal(BUILTIN_newarray_short);
497                                 break;
498                         case 10:
499                                 bte = builtintable_get_internal(BUILTIN_newarray_int);
500                                 break;
501                         case 11:
502                                 bte = builtintable_get_internal(BUILTIN_newarray_long);
503                                 break;
504                         default:
505                                 *exceptionptr = new_verifyerror(m,
506                                                 "Invalid array-type to create");
507                                 return NULL;
508                         }
509                         BUILTIN(bte, true, NULL, currentline);
510                         break;
511
512                 case JAVA_ANEWARRAY:
513                         i = code_get_u2(p + 1, m);
514                         compr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
515                         if (!compr)
516                                 return NULL;
517
518                         if (!(cr = class_get_classref_multiarray_of(1, compr)))
519                                 return NULL;
520
521                         if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
522                                 return NULL;
523
524                         LOADCONST_A_BUILTIN(c, cr);
525                         bte = builtintable_get_internal(BUILTIN_newarray);
526                         BUILTIN(bte, true, NULL, currentline);
527                         s_count++;
528                         break;
529
530                 case JAVA_MULTIANEWARRAY:
531                         m->isleafmethod = false;
532                         i = code_get_u2(p + 1, m);
533                         {
534                                 s4 v = code_get_u1(p + 3, m);
535
536                                 cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
537                                 if (!cr)
538                                         return NULL;
539
540                                 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
541                                         return NULL;
542
543                                 /* if unresolved, c == NULL */
544                                 OP2AT(opcode, v, c, cr, currentline);
545                         }
546                         break;
547
548                 case JAVA_IFEQ:
549                 case JAVA_IFLT:
550                 case JAVA_IFLE:
551                 case JAVA_IFNE:
552                 case JAVA_IFGT:
553                 case JAVA_IFGE:
554                 case JAVA_IFNULL:
555                 case JAVA_IFNONNULL:
556                 case JAVA_IF_ICMPEQ:
557                 case JAVA_IF_ICMPNE:
558                 case JAVA_IF_ICMPLT:
559                 case JAVA_IF_ICMPGT:
560                 case JAVA_IF_ICMPLE:
561                 case JAVA_IF_ICMPGE:
562                 case JAVA_IF_ACMPEQ:
563                 case JAVA_IF_ACMPNE:
564                 case JAVA_GOTO:
565                 case JAVA_JSR:
566                         i = p + code_get_s2(p + 1,m);
567                         bound_check(i);
568                         block_insert(i);
569                         blockend = true;
570                         OP1(opcode, i);
571                         break;
572
573                 case JAVA_GOTO_W:
574                 case JAVA_JSR_W:
575                         i = p + code_get_s4(p + 1,m);
576                         bound_check(i);
577                         block_insert(i);
578                         blockend = true;
579                         OP1(opcode, i);
580                         break;
581
582                 case JAVA_RET:
583                         if (!iswide) {
584                                 i = code_get_u1(p + 1,m);
585                         } else {
586                                 i = code_get_u2(p + 1,m);
587                                 nextp = p + 3;
588                                 iswide = false;
589                         }
590                         blockend = true;
591                                 
592                         OP1LOAD(opcode, i + firstlocal);
593                         break;
594
595                 case JAVA_IRETURN:
596                 case JAVA_LRETURN:
597                 case JAVA_FRETURN:
598                 case JAVA_DRETURN:
599                 case JAVA_ARETURN:
600                 case JAVA_RETURN:
601                         blockend = true;
602                         /* zero val.a so no patcher is inserted */
603                         /* the type checker may set this later  */
604                         iptr->val.a = NULL;
605                         OP(opcode);
606                         break;
607
608                 case JAVA_ATHROW:
609                         blockend = true;
610                         /* zero val.a so no patcher is inserted */
611                         /* the type checker may set this later  */
612                         iptr->val.a = NULL;
613                         OP(opcode);
614                         break;
615                                 
616
617                 /* table jumps ********************************************************/
618
619                 case JAVA_LOOKUPSWITCH:
620                         {
621                                 s4 num, j;
622                                 s4 *tablep;
623                                 s4 prevvalue=0;
624
625                                 blockend = true;
626                                 nextp = ALIGN((p + 1), 4);
627
628                                 if (nextp + 8 > m->jcodelength) {
629                                         *exceptionptr = new_verifyerror(m,
630                                                         "Unexpected end of bytecode");
631                                         return NULL;
632                                 }
633
634                                 tablep = (s4 *) (m->jcode + nextp);
635
636                                 OP2A(opcode, 0, tablep, currentline);
637
638                                 /* default target */
639
640                                 j =  p + code_get_s4(nextp, m);
641                                 *tablep = j;     /* restore for little endian */
642                                 tablep++;
643                                 nextp += 4;
644                                 bound_check(j);
645                                 block_insert(j);
646
647                                 /* number of pairs */
648
649                                 num = code_get_u4(nextp, m);
650                                 *tablep = num;
651                                 tablep++;
652                                 nextp += 4;
653
654                                 if (nextp + 8 * num > m->jcodelength) {
655                                         *exceptionptr = new_verifyerror(m,
656                                                 "Unexpected end of bytecode");
657                                         return NULL;
658                                 }
659
660                                 for (i = 0; i < num; i++) {
661                                         /* value */
662
663                                         j = code_get_s4(nextp, m);
664                                         *tablep = j; /* restore for little endian */
665                                         tablep++;
666                                         nextp += 4;
667
668                                         /* check if the lookup table is sorted correctly */
669                                         
670                                         if (i && (j <= prevvalue)) {
671                                                 *exceptionptr = new_verifyerror(m, "Unsorted lookup switch");
672                                                 return NULL;
673                                         }
674                                         prevvalue = j;
675
676                                         /* target */
677
678                                         j = p + code_get_s4(nextp,m);
679                                         *tablep = j; /* restore for little endian */
680                                         tablep++;
681                                         nextp += 4;
682                                         bound_check(j);
683                                         block_insert(j);
684                                 }
685
686                                 break;
687                         }
688
689
690                 case JAVA_TABLESWITCH:
691                         {
692                                 s4 num, j;
693                                 s4 *tablep;
694
695                                 blockend = true;
696                                 nextp = ALIGN((p + 1), 4);
697                                 if (nextp + 12 > m->jcodelength) {
698                                         *exceptionptr = new_verifyerror(m,
699                                                 "Unexpected end of bytecode");
700                                         return NULL;
701                                 }
702
703                                 tablep = (s4 *) (m->jcode + nextp);
704
705                                 OP2A(opcode, 0, tablep, currentline);
706
707                                 /* default target */
708
709                                 j = p + code_get_s4(nextp, m);
710                                 *tablep = j;     /* restore for little endian */
711                                 tablep++;
712                                 nextp += 4;
713                                 bound_check(j);
714                                 block_insert(j);
715
716                                 /* lower bound */
717
718                                 j = code_get_s4(nextp, m);
719                                 *tablep = j;     /* restore for little endian */
720                                 tablep++;
721                                 nextp += 4;
722
723                                 /* upper bound */
724
725                                 num = code_get_s4(nextp, m);
726                                 *tablep = num;   /* restore for little endian */
727                                 tablep++;
728                                 nextp += 4;
729
730                                 num -= j;  /* difference of upper - lower */
731
732                                 if (num < 0) {
733                                         *exceptionptr = new_verifyerror(m,
734                                                         "invalid TABLESWITCH: upper bound < lower bound");
735                                         return NULL;
736                                 }
737
738                                 if (nextp + 4 * (num + 1) > m->jcodelength) {
739                                         *exceptionptr = new_verifyerror(m,
740                                                 "Unexpected end of bytecode");
741                                         return NULL;
742                                 }
743
744                                 for (i = 0; i <= num; i++) {
745                                         j = p + code_get_s4(nextp,m);
746                                         *tablep = j; /* restore for little endian */
747                                         tablep++;
748                                         nextp += 4;
749                                         bound_check(j);
750                                         block_insert(j);
751                                 }
752
753                                 break;
754                         }
755
756
757                 /* load and store of object fields ************************************/
758
759                 case JAVA_AASTORE:
760                         OP(opcode);
761                         m->isleafmethod = false;
762                         break;
763
764                 case JAVA_GETSTATIC:
765                 case JAVA_PUTSTATIC:
766                 case JAVA_GETFIELD:
767                 case JAVA_PUTFIELD:
768                         {
769                                 constant_FMIref  *fr;
770                                 unresolved_field *uf;
771                                 fieldinfo        *fi;
772
773                                 i = code_get_u2(p + 1, m);
774                                 fr = class_getconstant(m->class, i,
775                                                                            CONSTANT_Fieldref);
776                                 if (!fr)
777                                         return NULL;
778
779                                 OP2A_NOINC(opcode, fr->parseddesc.fd->type, fr, currentline);
780
781                                 if (!(uf = create_unresolved_field(m->class,
782                                                                                                    m,
783                                                                                                    iptr)))
784                                         return NULL;
785
786                                 /* store unresolved_field pointer */
787
788                                 iptr->target = uf;
789
790                                 /* only with -noverify, otherwise the typechecker does this */
791
792                                 if (!opt_verify) {
793                                         if (!resolve_field(uf, resolveLazy, &fi))
794                                                 return NULL;
795
796                                         iptr->val.a = fi;
797
798                                 } else {
799                                         iptr->val.a = NULL;
800                                 }
801                                 PINC;
802                         }
803                         break;
804
805
806                 /* method invocation **************************************************/
807
808                 case JAVA_INVOKESTATIC:
809                         i = code_get_u2(p + 1, m);
810                         {
811                                 constant_FMIref   *mr;
812                                 methoddesc        *md;
813                                 unresolved_method *um;
814                                 methodinfo        *mi;
815
816                                 m->isleafmethod = false;
817
818                                 mr = class_getconstant(m->class, i,
819                                                                            CONSTANT_Methodref);
820                                 if (!mr)
821                                         return NULL;
822
823                                 md = mr->parseddesc.md;
824
825                                 if (!md->params)
826                                         if (!descriptor_params_from_paramtypes(md, ACC_STATIC))
827                                                 return NULL;
828
829                                 OP2A_NOINC(opcode, 0, mr, currentline);
830
831                                 um = create_unresolved_method(m->class,
832                                                                                           m, iptr);
833
834                                 if (!um)
835                                         return NULL;
836
837                                 /* store the unresolved_method pointer */
838
839                                 iptr->target = um;
840
841                                 /* only with -noverify, otherwise the typechecker does this */
842
843                                 if (!opt_verify) {
844                                         if (!resolve_method(um, resolveLazy, &mi))
845                                                 return NULL;
846
847                                         iptr->val.a = mi;
848                                 }
849                                 else {
850                                         iptr->val.a = NULL;
851                                 }
852                                 PINC;
853                         }
854                         break;
855
856                 case JAVA_INVOKESPECIAL:
857                 case JAVA_INVOKEVIRTUAL:
858                         {
859                                 constant_FMIref   *mr;
860                                 methoddesc        *md;
861                                 unresolved_method *um;
862                                 methodinfo        *mi;
863
864                                 m->isleafmethod = false;
865
866                                 i = code_get_u2(p + 1, m);
867                                 mr = class_getconstant(m->class, i,
868                                                                            CONSTANT_Methodref);
869                                 if (!mr)
870                                         return NULL;
871
872                                 md = mr->parseddesc.md;
873
874                                 if (!md->params)
875                                         if (!descriptor_params_from_paramtypes(md, 0))
876                                                 return NULL;
877                                 
878                                 OP2A_NOINC(opcode, 0, mr, currentline);
879
880                                 um = create_unresolved_method(m->class,
881                                                                                           m, iptr);
882
883                                 if (!um)
884                                         return NULL;
885
886                                 /* store the unresolved_method* */
887
888                                 iptr->target = um;
889
890                                 /* only with -noverify, otherwise the typechecker does this */
891
892                                 if (!opt_verify) {
893                                         if (!resolve_method(um, resolveLazy, &mi))
894                                                 return NULL;
895
896                                         iptr->val.a = mi;
897                                 }
898                                 else {
899                                         iptr->val.a = NULL;
900                                 }
901                                 PINC;
902                         }
903                         break;
904
905                 case JAVA_INVOKEINTERFACE:
906                         i = code_get_u2(p + 1, m);
907                         {
908                                 constant_FMIref   *mr;
909                                 methoddesc        *md;
910                                 unresolved_method *um;
911                                 methodinfo        *mi;
912                                 
913                                 m->isleafmethod = false;
914
915                                 mr = class_getconstant(m->class, i,
916                                                                            CONSTANT_InterfaceMethodref);
917                                 if (!mr)
918                                         return NULL;
919
920                                 md = mr->parseddesc.md;
921
922                                 if (!md->params)
923                                         if (!descriptor_params_from_paramtypes(md, 0))
924                                                 return NULL;
925
926                                 OP2A_NOINC(opcode, 0, mr, currentline);
927
928                                 um = create_unresolved_method(m->class,
929                                                                                           m, iptr);
930
931                                 if (!um)
932                                         return NULL;
933
934                                 /* store the unresolved_method* */
935
936                                 iptr->target = um;
937
938                                 /* only with -noverify, otherwise the typechecker does this */
939
940                                 if (!opt_verify) {
941                                         if (!resolve_method(um, resolveLazy, &mi))
942                                                 return NULL;
943
944                                         iptr->val.a = mi;
945                                 }
946                                 else {
947                                         iptr->val.a = NULL;
948                                 }
949                                 PINC;
950                         }
951                         break;
952
953                 /* miscellaneous object operations ************************************/
954
955                 case JAVA_NEW:
956                         i = code_get_u2(p + 1, m);
957                         cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
958                         if (!cr)
959                                 return NULL;
960
961                         if (!resolve_classref(m, cr, resolveLazy, true, true,
962                                                                   &c))
963                                 return NULL;
964
965                         LOADCONST_A_BUILTIN(c, cr);
966                         bte = builtintable_get_internal(BUILTIN_new);
967                         BUILTIN(bte, true, NULL, currentline);
968                         s_count++;
969                         break;
970
971                 case JAVA_CHECKCAST:
972                         i = code_get_u2(p + 1, m);
973                         cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
974                         if (!cr)
975                                 return NULL;
976
977                         if (!resolve_classref(m, cr, resolveLazy, true,
978                                                                   true, &c))
979                                 return NULL;
980
981                         if (cr->name->text[0] == '[') {
982                                 /* array type cast-check */
983                                 OP2AT(opcode, 0, c, cr, currentline);
984                                 m->isleafmethod = false;
985
986                         } else {
987                                 /* object type cast-check */
988                                 OP2AT(opcode, 1, c, cr, currentline);
989                         }
990                         break;
991
992                 case JAVA_INSTANCEOF:
993                         i = code_get_u2(p + 1,m);
994                         cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
995                         if (!cr)
996                                 return NULL;
997
998                         if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
999                                 return NULL;
1000
1001                         if (cr->name->text[0] == '[') {
1002                                 /* array type cast-check */
1003                                 LOADCONST_A_BUILTIN(c, cr);
1004                                 bte = builtintable_get_internal(BUILTIN_arrayinstanceof);
1005                                 BUILTIN(bte, false, NULL, currentline);
1006                                 s_count++;
1007
1008                         } else {
1009                                 /* object type cast-check */
1010                                 OP2AT(opcode, 1, c, cr, currentline);
1011                         }
1012                         break;
1013
1014                 case JAVA_MONITORENTER:
1015 #if defined(USE_THREADS)
1016                         if (checksync) {
1017                                 OP(ICMD_CHECKNULL);
1018                                 bte = builtintable_get_internal(BUILTIN_monitorenter);
1019                                 BUILTIN(bte, false, NULL, currentline);
1020                         } else
1021 #endif
1022                                 {
1023                                         OP(ICMD_CHECKNULL);
1024                                         OP(ICMD_POP);
1025                                 }
1026                         break;
1027
1028                 case JAVA_MONITOREXIT:
1029 #if defined(USE_THREADS)
1030                         if (checksync) {
1031                                 bte = builtintable_get_internal(BUILTIN_monitorexit);
1032                                 BUILTIN(bte, false, NULL, currentline);
1033                         } else
1034 #endif
1035                                 {
1036                                         OP(ICMD_POP);
1037                                 }
1038                         break;
1039
1040                 /* any other basic operation ******************************************/
1041
1042                 case JAVA_IDIV:
1043 #if !SUPPORT_DIVISION
1044                         bte = builtintable_get_internal(BUILTIN_idiv);
1045                         OP2A(opcode, bte->md->paramcount, bte, currentline);
1046                         m->isleafmethod = false;
1047 #else
1048                         OP(opcode);
1049 #endif
1050                         break;
1051
1052                 case JAVA_IREM:
1053 #if !SUPPORT_DIVISION
1054                         bte = builtintable_get_internal(BUILTIN_irem);
1055                         OP2A(opcode, bte->md->paramcount, bte, currentline);
1056                         m->isleafmethod = false;
1057 #else
1058                         OP(opcode);
1059 #endif
1060                         break;
1061
1062                 case JAVA_LDIV:
1063 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1064                         bte = builtintable_get_internal(BUILTIN_ldiv);
1065                         OP2A(opcode, bte->md->paramcount, bte, currentline);
1066                         m->isleafmethod = false;
1067 #else
1068                         OP(opcode);
1069 #endif
1070                         break;
1071
1072                 case JAVA_LREM:
1073 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1074                         bte = builtintable_get_internal(BUILTIN_lrem);
1075                         OP2A(opcode, bte->md->paramcount, bte, currentline);
1076                         m->isleafmethod = false;
1077 #else
1078                         OP(opcode);
1079 #endif
1080                         break;
1081
1082                 case JAVA_FREM:
1083 #if defined(__I386__)
1084                         OP(opcode);
1085 #else
1086                         bte = builtintable_get_internal(BUILTIN_frem);
1087                         BUILTIN(bte, false, NULL, currentline);
1088 #endif
1089                         break;
1090
1091                 case JAVA_DREM:
1092 #if defined(__I386__)
1093                         OP(opcode);
1094 #else
1095                         bte = builtintable_get_internal(BUILTIN_drem);
1096                         BUILTIN(bte, false, NULL, currentline);
1097 #endif
1098                         break;
1099
1100                 case JAVA_F2I:
1101 #if defined(__ALPHA__)
1102                         if (!opt_noieee) {
1103                                 bte = builtintable_get_internal(BUILTIN_f2i);
1104                                 BUILTIN(bte, false, NULL, currentline);
1105                         } else
1106 #endif
1107                                 {
1108                                         OP(opcode);
1109                                 }
1110                         break;
1111
1112                 case JAVA_F2L:
1113 #if defined(__ALPHA__)
1114                         if (!opt_noieee) {
1115                                 bte = builtintable_get_internal(BUILTIN_f2l);
1116                                 BUILTIN(bte, false, NULL, currentline);
1117                         } else 
1118 #endif
1119                                 {
1120                                         OP(opcode);
1121                                 }
1122                         break;
1123
1124                 case JAVA_D2I:
1125 #if defined(__ALPHA__)
1126                         if (!opt_noieee) {
1127                                 bte = builtintable_get_internal(BUILTIN_d2i);
1128                                 BUILTIN(bte, false, NULL, currentline);
1129                         } else
1130 #endif
1131                                 {
1132                                         OP(opcode);
1133                                 }
1134                         break;
1135
1136                 case JAVA_D2L:
1137 #if defined(__ALPHA__)
1138                         if (!opt_noieee) {
1139                                 bte = builtintable_get_internal(BUILTIN_d2l);
1140                                 BUILTIN(bte, false, NULL, currentline);
1141                         } else
1142 #endif
1143                                 {
1144                                         OP(opcode);
1145                                 }
1146                         break;
1147
1148                 case JAVA_BREAKPOINT:
1149                         *exceptionptr =
1150                                 new_verifyerror(m, "Quick instructions shouldn't appear yet.");
1151                         return NULL;
1152
1153                 case 186: /* unused opcode */
1154                 case 203:
1155                 case 204:
1156                 case 205:
1157                 case 206:
1158                 case 207:
1159                 case 208:
1160                 case 209:
1161                 case 210:
1162                 case 211:
1163                 case 212:
1164                 case 213:
1165                 case 214:
1166                 case 215:
1167                 case 216:
1168                 case 217:
1169                 case 218:
1170                 case 219:
1171                 case 220:
1172                 case 221:
1173                 case 222:
1174                 case 223:
1175                 case 224:
1176                 case 225:
1177                 case 226:
1178                 case 227:
1179                 case 228:
1180                 case 229:
1181                 case 230:
1182                 case 231:
1183                 case 232:
1184                 case 233:
1185                 case 234:
1186                 case 235:
1187                 case 236:
1188                 case 237:
1189                 case 238:
1190                 case 239:
1191                 case 240:
1192                 case 241:
1193                 case 242:
1194                 case 243:
1195                 case 244:
1196                 case 245:
1197                 case 246:
1198                 case 247:
1199                 case 248:
1200                 case 249:
1201                 case 250:
1202                 case 251:
1203                 case 252:
1204                 case 253:
1205                 case 254:
1206                 case 255:
1207                         *exceptionptr =
1208                                 new_verifyerror(m,"Illegal opcode %d at instr %d\n",
1209                                                                   opcode, ipc);
1210                         return NULL;
1211                         break;
1212
1213                 default:
1214                         OP(opcode);
1215                         break;
1216                                 
1217                 } /* end switch */
1218
1219                 /* If WIDE was used correctly, iswide should have been reset by now. */
1220                 if (iswide && opcode != JAVA_WIDE) {
1221                         *exceptionptr = new_verifyerror(m,
1222                                         "Illegal instruction: WIDE before incompatible opcode");
1223                         return NULL;
1224                 }
1225
1226         } /* end for */
1227
1228         if (p != m->jcodelength) {
1229                 printf("p (%d) != m->jcodelength (%d)\n",p,m->jcodelength);
1230                 *exceptionptr = new_verifyerror(m,
1231                                 "Command-sequence crosses code-boundary");
1232                 return NULL;
1233         }
1234
1235         if (!blockend) {
1236                 *exceptionptr = new_verifyerror(m, "Falling off the end of the code");
1237                 return NULL;
1238         }
1239
1240         /* adjust block count if target 0 is not first intermediate instruction */
1241
1242         if (!m->basicblockindex[0] || (m->basicblockindex[0] > 1))
1243                 b_count++;
1244
1245         /* copy local to method variables */
1246
1247         m->instructioncount = ipc;
1248         m->basicblockcount = b_count;
1249         m->stackcount = s_count + m->basicblockcount * m->maxstack;
1250
1251         /* allocate stack table */
1252
1253         m->stack = DMNEW(stackelement, m->stackcount);
1254
1255         {
1256                 basicblock *bptr;
1257
1258                 bptr = m->basicblocks = DMNEW(basicblock, b_count + 1);    /* one more for end ipc */
1259
1260                 b_count = 0;
1261                 m->c_debug_nr = 0;
1262         
1263                 /* additional block if target 0 is not first intermediate instruction */
1264
1265                 if (!m->basicblockindex[0] || (m->basicblockindex[0] > 1)) {
1266                         bptr->iinstr = m->instructions;
1267                         bptr->mpc = -1;
1268                         bptr->flags = -1;
1269                         bptr->type = BBTYPE_STD;
1270                         bptr->branchrefs = NULL;
1271                         bptr->pre_count = 0;
1272                         bptr->debug_nr = m->c_debug_nr++;
1273                         bptr++;
1274                         b_count++;
1275                         (bptr - 1)->next = bptr;
1276                 }
1277
1278                 /* allocate blocks */
1279
1280                 for (p = 0; p < m->jcodelength; p++) { 
1281                 /* for (p = 0; p < m->jcodelength; p++) { */
1282                         if (m->basicblockindex[p] & 1) {
1283                                 /* Check if this block starts at the beginning of an          */
1284                                 /* instruction.                                               */
1285
1286                                 if (!instructionstart[p]) {
1287                                         *exceptionptr = new_verifyerror(m,
1288                                                 "Branch into middle of instruction");
1289                                         return NULL;
1290                                 }
1291
1292                                 /* allocate the block */
1293                                 bptr->iinstr = m->instructions + (m->basicblockindex[p] >> 1);
1294                                 bptr->debug_nr = m->c_debug_nr++;
1295                                 if (b_count != 0)
1296                                         (bptr - 1)->icount = bptr->iinstr - (bptr - 1)->iinstr;
1297                                 bptr->mpc = -1;
1298                                 bptr->flags = -1;
1299                                 bptr->lflags = 0;
1300                                 bptr->type = BBTYPE_STD;
1301                                 bptr->branchrefs = NULL;
1302                                 m->basicblockindex[p] = b_count;
1303                                 bptr->pre_count = 0;
1304                                 bptr++;
1305                                 b_count++;
1306                                 (bptr - 1)->next = bptr;
1307                         }
1308                 }
1309
1310                 /* allocate additional block at end */
1311
1312                 bptr->instack = bptr->outstack = NULL;
1313                 bptr->indepth = bptr->outdepth = 0;
1314                 bptr->iinstr = NULL;
1315                 (bptr - 1)->icount = (m->instructions + m->instructioncount) - (bptr - 1)->iinstr;
1316                 bptr->icount = 0;
1317                 bptr->mpc = -1;
1318                 bptr->flags = -1;
1319                 bptr->lflags = 0;
1320                 bptr->type = BBTYPE_STD;
1321                 bptr->branchrefs = NULL;
1322                 bptr->pre_count = 0;
1323                 bptr->debug_nr = m->c_debug_nr++;
1324                 (bptr - 1)->next = bptr;
1325                 bptr->next = NULL;
1326
1327                 if (cd->exceptiontablelength > 0) {
1328                         cd->exceptiontable[cd->exceptiontablelength - 1].down = NULL;
1329                 }
1330                 
1331                 for (i = 0; i < cd->exceptiontablelength; ++i) {
1332                         p = cd->exceptiontable[i].startpc;
1333                         cd->exceptiontable[i].start = m->basicblocks + m->basicblockindex[p];
1334
1335                         p = cd->exceptiontable[i].endpc;
1336                         cd->exceptiontable[i].end = (p == m->jcodelength) ? (m->basicblocks + m->basicblockcount /*+ 1*/) : (m->basicblocks + m->basicblockindex[p]);
1337
1338                         p = cd->exceptiontable[i].handlerpc;
1339                         cd->exceptiontable[i].handler = m->basicblocks + m->basicblockindex[p];
1340             }
1341         }
1342
1343         /* just return methodinfo* to signal everything was ok */
1344
1345         return m;
1346 }
1347
1348
1349 /*
1350  * These are local overrides for various environment variables in Emacs.
1351  * Please do not remove this and leave it at the end of the file, where
1352  * Emacs will automagically detect them.
1353  * ---------------------------------------------------------------------
1354  * Local variables:
1355  * mode: c
1356  * indent-tabs-mode: t
1357  * c-basic-offset: 4
1358  * tab-width: 4
1359  * End:
1360  * vim:noexpandtab:sw=4:ts=4:
1361  */