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