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