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