* src/vm/jit/parse.c (parse): Fix in ICMD_TABLESWITCH: Put table into
[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 5859 2006-10-29 23:33:30Z 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
49 #if defined(ENABLE_THREADS)
50 # include "threads/native/lock.h"
51 #endif
52
53 #include "toolbox/logging.h"
54 #include "vm/builtin.h"
55 #include "vm/exceptions.h"
56 #include "vm/global.h"
57 #include "vm/linker.h"
58 #include "vm/loader.h"
59 #include "vm/resolve.h"
60 #include "vm/options.h"
61 #include "vm/statistics.h"
62 #include "vm/stringlocal.h"
63 #include "vm/suck.h"
64 #include "vm/jit/asmpart.h"
65 #include "vm/jit/jit.h"
66 #include "vm/jit/parse.h"
67 #include "vm/jit/patcher.h"
68 #include "vm/jit/loop/loop.h"
69
70 #define INSTRUCTIONS_INCREMENT  5  /* number of additional instructions to    */
71                                    /* allocate if space runs out              */
72
73
74 /* parserdata_t ***************************************************************/
75
76 typedef struct parsedata_t parsedata_t;
77
78 struct parsedata_t {
79         instruction *instructions;          /* instruction array                  */
80         s4           instructionslength;    /* length of the instruction array    */
81         u1          *instructionstart;
82 };
83
84
85 /* parse_setup *****************************************************************
86
87    Fills the passed parsedata_t structure.
88
89 *******************************************************************************/
90
91 static void parse_setup(jitdata *jd, parsedata_t *pd)
92 {
93         methodinfo *m;
94
95         /* get required compiler data */
96
97         m = jd->m;
98
99         /* Allocate instruction array and block index table (1 additional
100            for end ipc). */
101
102         jd->basicblockindex = DMNEW(s4, m->jcodelength + 1);
103         pd->instructionstart = DMNEW(u1, m->jcodelength + 1);
104
105         MZERO(jd->basicblockindex, s4, m->jcodelength + 1);
106         MZERO(pd->instructionstart, u1, m->jcodelength + 1);
107
108         /* Set the length of the instruction array.  We simply add 5 more
109            instruction, as this seems to be a reasonable value. */
110
111         pd->instructionslength = m->jcodelength + 1;
112
113         /* allocate the instruction array */
114
115         pd->instructions = DMNEW(instruction, pd->instructionslength);
116
117         /* Zero the intermediate instructions array so we don't have any
118            invalid pointers in it if we cannot finish stack_analyse(). */
119
120         MZERO(pd->instructions, instruction, pd->instructionslength);
121 }
122
123
124 /* parse_realloc_instructions **************************************************
125
126    Reallocate the instructions array so there is room for at least N 
127    additional instructions.
128
129    RETURN VALUE:
130        the new value for iptr
131
132 *******************************************************************************/
133
134 static instruction *parse_realloc_instructions(parsedata_t *pd, s4 ipc, s4 n)
135 {
136         /* increase the size of the instruction array */
137
138         pd->instructionslength += (n + INSTRUCTIONS_INCREMENT);
139
140         /* reallocate the array */
141
142         pd->instructions = DMREALLOC(pd->instructions, instruction, ipc,
143                                                                  pd->instructionslength);
144
145         /* return the iptr */
146
147         return pd->instructions + ipc;
148 }
149
150
151 /* parse_mark_exception_boundaries *********************************************
152
153    Mark exception handlers and the boundaries of the handled regions as
154    basic block boundaries.
155
156    IN:
157        jd...............current jitdata
158
159    RETURN VALUE:
160        >= 0.............the number of new basic blocks marked
161            -1...............an exception has been thrown
162
163 *******************************************************************************/
164
165 static int parse_mark_exception_boundaries(jitdata *jd)
166 {
167         s4                   b_count;
168         s4                   pc;
169         s4                   i;
170         s4                   len;
171         raw_exception_entry *rex;
172         methodinfo          *m;
173
174         m = jd->m;
175         
176         len = m->rawexceptiontablelength;
177
178         if (len == 0)
179                 return 0;
180
181         b_count = 0;
182         rex = m->rawexceptiontable;
183
184         for (i = 0; i < len; ++i, ++rex) {
185
186                 /* the start of the handled region becomes a basic block start */
187
188                 pc = rex->startpc;
189                 CHECK_BYTECODE_INDEX(pc);
190                 MARK_BASICBLOCK(pc);
191                 
192                 pc = rex->endpc; /* see JVM Spec 4.7.3 */
193                 CHECK_BYTECODE_INDEX_EXCLUSIVE(pc);
194
195                 /* check that the range is valid */
196
197 #if defined(ENABLE_VERIFIER)
198                 if (pc <= rex->startpc) {
199                         exceptions_throw_verifyerror(m,
200                                 "Invalid exception handler range");
201                         return -1;
202                 }
203 #endif
204                 
205                 /* end of handled region becomes a basic block boundary  */
206                 /* (If it is the bytecode end, we'll use the special     */
207                 /* end block that is created anyway.)                    */
208
209                 if (pc < m->jcodelength)
210                         MARK_BASICBLOCK(pc);
211
212                 /* the start of the handler becomes a basic block start  */
213
214                 pc = rex->handlerpc;
215                 CHECK_BYTECODE_INDEX(pc);
216                 MARK_BASICBLOCK(pc);
217         }
218
219         /* everything ok */
220
221         return b_count;
222
223 #if defined(ENABLE_VERIFIER)
224 throw_invalid_bytecode_index:
225         exceptions_throw_verifyerror(m,
226                                                                  "Illegal bytecode index in exception table");
227         return -1;
228 #endif
229 }
230
231
232 /* parse_resolve_exception_table ***********************************************
233
234    Enter the exception handlers and their ranges, resolved to basicblock *s,
235    in the jitdata.
236
237    IN:
238        jd...............current jitdata
239
240    RETURN VALUE:
241            true.............everything ok
242            false............an exception has been thrown
243
244 *******************************************************************************/
245
246 static bool parse_resolve_exception_table(jitdata *jd)
247 {
248         methodinfo          *m;
249         raw_exception_entry *rex;
250         exception_entry     *ex;
251         s4                   i;
252         s4                   len;
253         classinfo           *exclass;
254
255         m = jd->m;
256
257         len = m->rawexceptiontablelength;
258
259         /* common case: no handler entries */
260
261         if (len == 0)
262                 return true;
263
264         /* allocate the exception table */
265
266         jd->exceptiontablelength = len;
267         jd->exceptiontable = DMNEW(exception_entry, len + 1); /* XXX why +1? */
268
269         /* copy and resolve the entries */
270
271         ex = jd->exceptiontable;
272         rex = m->rawexceptiontable;
273
274         for (i = 0; i < len; ++i, ++rex, ++ex) {
275                 /* resolve instruction indices to basic blocks */
276
277                 ex->start   = BLOCK_OF(rex->startpc);
278                 ex->end     = BLOCK_OF(rex->endpc);
279                 ex->handler = BLOCK_OF(rex->handlerpc);
280
281                 /* lazily resolve the catchtype */
282
283                 if (rex->catchtype.any != NULL) {
284                         if (!resolve_classref_or_classinfo(m,
285                                                                                            rex->catchtype,
286                                                                                            resolveLazy, true, false,
287                                                                                            &exclass))
288                                 return false;
289
290                         /* if resolved, enter the result of resolution in the table */
291
292                         if (exclass != NULL)
293                                 rex->catchtype.cls = exclass;
294                 }
295
296                 ex->catchtype = rex->catchtype;
297                 ex->next = NULL;   /* set by loop analysis */
298                 ex->down = ex + 1; /* link to next exception entry */
299         }
300
301         /* terminate the ->down linked list */
302
303         assert(ex != jd->exceptiontable);
304         ex[-1].down = NULL;
305
306         return true;
307 }
308
309
310 /*******************************************************************************
311
312         function 'parse' scans the JavaVM code and generates intermediate code
313
314         During parsing the block index table is used to store at bit pos 0
315         a flag which marks basic block starts and at position 1 to 31 the
316         intermediate instruction index. After parsing the block index table
317         is scanned, for marked positions a block is generated and the block
318         number is stored in the block index table.
319
320 *******************************************************************************/
321
322 /*** macro for checking the length of the bytecode ***/
323
324 #if defined(ENABLE_VERIFIER)
325 #define CHECK_END_OF_BYTECODE(neededlength) \
326         do { \
327                 if ((neededlength) > m->jcodelength) \
328                         goto throw_unexpected_end_of_bytecode; \
329         } while (0)
330 #else /* !ENABLE_VERIFIER */
331 #define CHECK_END_OF_BYTECODE(neededlength)
332 #endif /* ENABLE_VERIFIER */
333
334 bool parse(jitdata *jd)
335 {
336         methodinfo  *m;                     /* method being parsed                */
337         codeinfo    *code;
338         parsedata_t  pd;
339         instruction *iptr;                  /* current ptr into instruction array */
340         s4           ipc;                   /* intermediate instruction counter   */
341         s4           p;                     /* java instruction counter           */
342         s4           nextp;                 /* start of next java instruction     */
343         s4           opcode;                /* java opcode                        */
344         s4           i;
345         s4           j;
346         int  b_count;               /* basic block counter                      */
347         int  s_count = 0;           /* stack element counter                    */
348         bool blockend = false;      /* true if basic block end has been reached */
349         bool iswide = false;        /* true if last instruction was a wide      */
350         constant_classref  *cr;
351         constant_classref  *compr;
352         classinfo          *c;
353         builtintable_entry *bte;
354         constant_FMIref    *mr;
355         methoddesc         *md;
356         unresolved_method  *um;
357         resolve_result_t    result;
358         u2                  lineindex = 0;
359         u2                  currentline = 0;
360         u2                  linepcchange = 0;
361         u4                  flags;
362         basicblock         *bptr;
363
364         int                *local_map; /* local pointer to renaming structore     */
365                                        /* is assigned to rd->local_map at the end */
366         /* get required compiler data */
367
368         m    = jd->m;
369         code = jd->code;
370
371         /* allocate buffers for local variable renaming */
372         local_map = DMNEW(int, m->maxlocals * 5);
373         for (i = 0; i < m->maxlocals; i++) {
374                 local_map[i * 5 + 0] = 0;
375                 local_map[i * 5 + 1] = 0;
376                 local_map[i * 5 + 2] = 0;
377                 local_map[i * 5 + 3] = 0;
378                 local_map[i * 5 + 4] = 0;
379         }
380
381         /* initialize the parse data structures */
382   
383         parse_setup(jd, &pd);
384   
385         /* initialize local variables */
386   
387         iptr = pd.instructions;
388         ipc  = 0;
389   
390         /* mark basic block boundaries for exception table */
391
392         b_count = parse_mark_exception_boundaries(jd);
393         if (b_count < 0)
394                 return false;
395
396         /* initialize stack element counter */
397
398         s_count = 1 + m->rawexceptiontablelength;
399
400 #if defined(ENABLE_THREADS)
401         if (checksync && (m->flags & ACC_SYNCHRONIZED))
402                 jd->isleafmethod = false;
403 #endif
404
405         /* setup line number info */
406
407         currentline = 0;
408         linepcchange = 0;
409
410         if (m->linenumbercount == 0) {
411                 lineindex = 0;
412         }
413         else {
414                 linepcchange = m->linenumbers[0].start_pc;
415         }
416
417         /*** LOOP OVER ALL BYTECODE INSTRUCTIONS **********************************/
418
419         for (p = 0; p < m->jcodelength; p = nextp) {
420
421                 /* mark this position as a valid instruction start */
422
423                 pd.instructionstart[p] = 1;
424
425                 /* change the current line number, if necessary */
426
427                 /* XXX rewrite this using pointer arithmetic */
428
429                 if (linepcchange == p) {
430                         if (m->linenumbercount > lineindex) {
431 next_linenumber:
432                                 currentline = m->linenumbers[lineindex].line_number;
433                                 lineindex++;
434                                 if (lineindex < m->linenumbercount) {
435                                         linepcchange = m->linenumbers[lineindex].start_pc;
436                                         if (linepcchange == p)
437                                                 goto next_linenumber;
438                                 }
439                         }
440                 }
441
442 fetch_opcode:
443                 /* fetch next opcode  */        
444
445                 opcode = SUCK_BE_U1(m->jcode + p);
446
447                 /* some compilers put a JAVA_NOP after a blockend instruction */
448
449                 if (blockend && (opcode != JAVA_NOP)) {
450                         /* start new block */
451
452                         MARK_BASICBLOCK(p);
453                         blockend = false;
454                 }
455
456                 /* We need a NOP as last instruction in each basic block
457                    for basic block reordering (may be replaced with a GOTO
458                    later). */
459
460                 if (jd->basicblockindex[p] & 1) {
461                         INSTRUCTIONS_CHECK(1);
462                         OP(ICMD_NOP);
463                 }
464
465                 /* store intermediate instruction count (bit 0 mark block starts) */
466
467                 jd->basicblockindex[p] |= (ipc << 1);
468
469                 /* compute next instruction start */
470
471                 nextp = p + jcommandsize[opcode];
472
473                 CHECK_END_OF_BYTECODE(nextp);
474
475                 /* add stack elements produced by this instruction */
476
477                 s_count += stackreq[opcode];
478
479                 /* We check here for the space of 1 instruction in the
480                    instruction array.  If an opcode is converted to more than
481                    1 instruction, this is checked in the corresponding
482                    case. */
483
484                 INSTRUCTIONS_CHECK(1);
485
486                 /* translate this bytecode instruction */
487                 switch (opcode) {
488
489                 case JAVA_NOP:
490                         break;
491
492                 /* pushing constants onto the stack ***********************************/
493
494                 case JAVA_BIPUSH:
495                         OP_LOADCONST_I(SUCK_BE_S1(m->jcode + p + 1));
496                         break;
497
498                 case JAVA_SIPUSH:
499                         OP_LOADCONST_I(SUCK_BE_S2(m->jcode + p + 1));
500                         break;
501
502                 case JAVA_LDC1:
503                         i = SUCK_BE_U1(m->jcode + p + 1);
504                         goto pushconstantitem;
505
506                 case JAVA_LDC2:
507                 case JAVA_LDC2W:
508                         i = SUCK_BE_U2(m->jcode + p + 1);
509
510                 pushconstantitem:
511
512 #if defined(ENABLE_VERIFIER)
513                         if (i >= m->class->cpcount) {
514                                 exceptions_throw_verifyerror(m,
515                                         "Attempt to access constant outside range");
516                                 return false;
517                         }
518 #endif
519
520                         switch (m->class->cptags[i]) {
521                         case CONSTANT_Integer:
522                                 OP_LOADCONST_I(((constant_integer *) (m->class->cpinfos[i]))->value);
523                                 break;
524                         case CONSTANT_Long:
525                                 OP_LOADCONST_L(((constant_long *) (m->class->cpinfos[i]))->value);
526                                 break;
527                         case CONSTANT_Float:
528                                 OP_LOADCONST_F(((constant_float *) (m->class->cpinfos[i]))->value);
529                                 break;
530                         case CONSTANT_Double:
531                                 OP_LOADCONST_D(((constant_double *) (m->class->cpinfos[i]))->value);
532                                 break;
533                         case CONSTANT_String:
534                                 OP_LOADCONST_STRING(literalstring_new((utf *) (m->class->cpinfos[i])));
535                                 break;
536                         case CONSTANT_Class:
537                                 cr = (constant_classref *) (m->class->cpinfos[i]);
538
539                                 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
540                                         return false;
541
542                                 /* if not resolved, c == NULL */
543
544                                 OP_LOADCONST_CLASSINFO_OR_CLASSREF_CHECK(c, cr);
545
546                                 break;
547
548 #if defined(ENABLE_VERIFIER)
549                         default:
550                                 exceptions_throw_verifyerror(m,
551                                                 "Invalid constant type to push");
552                                 return false;
553 #endif
554                         }
555                         break;
556
557                 case JAVA_ACONST_NULL:
558                         OP_LOADCONST_NULL();
559                         break;
560
561                 case JAVA_ICONST_M1:
562                 case JAVA_ICONST_0:
563                 case JAVA_ICONST_1:
564                 case JAVA_ICONST_2:
565                 case JAVA_ICONST_3:
566                 case JAVA_ICONST_4:
567                 case JAVA_ICONST_5:
568                         OP_LOADCONST_I(opcode - JAVA_ICONST_0);
569                         break;
570
571                 case JAVA_LCONST_0:
572                 case JAVA_LCONST_1:
573                         OP_LOADCONST_L(opcode - JAVA_LCONST_0);
574                         break;
575
576                 case JAVA_FCONST_0:
577                 case JAVA_FCONST_1:
578                 case JAVA_FCONST_2:
579                         OP_LOADCONST_F(opcode - JAVA_FCONST_0);
580                         break;
581
582                 case JAVA_DCONST_0:
583                 case JAVA_DCONST_1:
584                         OP_LOADCONST_D(opcode - JAVA_DCONST_0);
585                         break;
586
587                 /* stack operations ***************************************************/
588
589                 /* We need space for additional ICMDs so we can translate these       */
590                 /* instructions to sequences of ICMD_COPY and ICMD_MOVE instructions. */
591
592                 case JAVA_DUP_X1:
593                         INSTRUCTIONS_CHECK(4);
594                         OP(opcode);
595                         OP(ICMD_NOP);
596                         OP(ICMD_NOP);
597                         OP(ICMD_NOP);
598                         break;
599
600                 case JAVA_DUP_X2:
601                         INSTRUCTIONS_CHECK(6);
602                         OP(opcode);
603                         OP(ICMD_NOP);
604                         OP(ICMD_NOP);
605                         OP(ICMD_NOP);
606                         OP(ICMD_NOP);
607                         OP(ICMD_NOP);
608                         break;
609
610                 case JAVA_DUP2:
611                         INSTRUCTIONS_CHECK(2);
612                         OP(opcode);
613                         OP(ICMD_NOP);
614                         break;
615
616                 case JAVA_DUP2_X1:
617                         INSTRUCTIONS_CHECK(7);
618                         OP(opcode);
619                         OP(ICMD_NOP);
620                         OP(ICMD_NOP);
621                         OP(ICMD_NOP);
622                         OP(ICMD_NOP);
623                         OP(ICMD_NOP);
624                         OP(ICMD_NOP);
625                         break;
626
627                 case JAVA_DUP2_X2:
628                         INSTRUCTIONS_CHECK(9);
629                         OP(opcode);
630                         OP(ICMD_NOP);
631                         OP(ICMD_NOP);
632                         OP(ICMD_NOP);
633                         OP(ICMD_NOP);
634                         OP(ICMD_NOP);
635                         OP(ICMD_NOP);
636                         OP(ICMD_NOP);
637                         OP(ICMD_NOP);
638                         break;
639
640                 case JAVA_SWAP:
641                         INSTRUCTIONS_CHECK(3);
642                         OP(opcode);
643                         OP(ICMD_NOP);
644                         OP(ICMD_NOP);
645                         break;
646
647                 /* local variable access instructions *********************************/
648
649                 case JAVA_ILOAD:
650                 case JAVA_FLOAD:
651                 case JAVA_ALOAD:
652                         if (iswide == false) {
653                                 i = SUCK_BE_U1(m->jcode + p + 1);
654                         }
655                         else {
656                                 i = SUCK_BE_U2(m->jcode + p + 1);
657                                 nextp = p + 3;
658                                 iswide = false;
659                         }
660                         OP_LOAD_ONEWORD(opcode, i, opcode - JAVA_ILOAD);
661                         break;
662
663                 case JAVA_LLOAD:
664                 case JAVA_DLOAD:
665                         if (iswide == false) {
666                                 i = SUCK_BE_U1(m->jcode + p + 1);
667                         }
668                         else {
669                                 i = SUCK_BE_U2(m->jcode + p + 1);
670                                 nextp = p + 3;
671                                 iswide = false;
672                         }
673                         OP_LOAD_TWOWORD(opcode, i, opcode - JAVA_ILOAD);
674                         break;
675
676                 case JAVA_ILOAD_0:
677                 case JAVA_ILOAD_1:
678                 case JAVA_ILOAD_2:
679                 case JAVA_ILOAD_3:
680                         OP_LOAD_ONEWORD(ICMD_ILOAD, opcode - JAVA_ILOAD_0, TYPE_INT);
681                         break;
682
683                 case JAVA_LLOAD_0:
684                 case JAVA_LLOAD_1:
685                 case JAVA_LLOAD_2:
686                 case JAVA_LLOAD_3:
687                         OP_LOAD_TWOWORD(ICMD_LLOAD, opcode - JAVA_LLOAD_0, TYPE_LNG);
688                         break;
689
690                 case JAVA_FLOAD_0:
691                 case JAVA_FLOAD_1:
692                 case JAVA_FLOAD_2:
693                 case JAVA_FLOAD_3:
694                         OP_LOAD_ONEWORD(ICMD_FLOAD, opcode - JAVA_FLOAD_0, TYPE_FLT);
695                         break;
696
697                 case JAVA_DLOAD_0:
698                 case JAVA_DLOAD_1:
699                 case JAVA_DLOAD_2:
700                 case JAVA_DLOAD_3:
701                         OP_LOAD_TWOWORD(ICMD_DLOAD, opcode - JAVA_DLOAD_0, TYPE_DBL);
702                         break;
703
704                 case JAVA_ALOAD_0:
705                 case JAVA_ALOAD_1:
706                 case JAVA_ALOAD_2:
707                 case JAVA_ALOAD_3:
708                         OP_LOAD_ONEWORD(ICMD_ALOAD, opcode - JAVA_ALOAD_0, TYPE_ADR);
709                         break;
710
711                 case JAVA_ISTORE:
712                 case JAVA_FSTORE:
713                 case JAVA_ASTORE:
714                         if (iswide == false) {
715                                 i = SUCK_BE_U1(m->jcode + p + 1);
716                         }
717                         else {
718                                 i = SUCK_BE_U2(m->jcode + p + 1);
719                                 iswide = false;
720                                 nextp = p + 3;
721                         }
722                         OP_STORE_ONEWORD(opcode, i, opcode - JAVA_ISTORE);
723                         break;
724
725                 case JAVA_LSTORE:
726                 case JAVA_DSTORE:
727                         if (iswide == false) {
728                                 i = SUCK_BE_U1(m->jcode + p + 1);
729                         }
730                         else {
731                                 i = SUCK_BE_U2(m->jcode + p + 1);
732                                 iswide = false;
733                                 nextp = p + 3;
734                         }
735                         OP_STORE_TWOWORD(opcode, i, opcode - JAVA_ISTORE);
736                         break;
737
738                 case JAVA_ISTORE_0:
739                 case JAVA_ISTORE_1:
740                 case JAVA_ISTORE_2:
741                 case JAVA_ISTORE_3:
742                         OP_STORE_ONEWORD(ICMD_ISTORE, opcode - JAVA_ISTORE_0, TYPE_INT);
743                         break;
744
745                 case JAVA_LSTORE_0:
746                 case JAVA_LSTORE_1:
747                 case JAVA_LSTORE_2:
748                 case JAVA_LSTORE_3:
749                         OP_STORE_TWOWORD(ICMD_LSTORE, opcode - JAVA_LSTORE_0, TYPE_LNG);
750                         break;
751
752                 case JAVA_FSTORE_0:
753                 case JAVA_FSTORE_1:
754                 case JAVA_FSTORE_2:
755                 case JAVA_FSTORE_3:
756                         OP_STORE_ONEWORD(ICMD_FSTORE, opcode - JAVA_FSTORE_0, TYPE_FLT);
757                         break;
758
759                 case JAVA_DSTORE_0:
760                 case JAVA_DSTORE_1:
761                 case JAVA_DSTORE_2:
762                 case JAVA_DSTORE_3:
763                         OP_STORE_TWOWORD(ICMD_DSTORE, opcode - JAVA_DSTORE_0, TYPE_DBL);
764                         break;
765
766                 case JAVA_ASTORE_0:
767                 case JAVA_ASTORE_1:
768                 case JAVA_ASTORE_2:
769                 case JAVA_ASTORE_3:
770                         OP_STORE_ONEWORD(ICMD_ASTORE, opcode - JAVA_ASTORE_0, TYPE_ADR);
771                         break;
772
773                 case JAVA_IINC:
774                         {
775                                 int v;
776
777                                 if (iswide == false) {
778                                         i = SUCK_BE_U1(m->jcode + p + 1);
779                                         v = SUCK_BE_S1(m->jcode + p + 2);
780
781                                 }
782                                 else {
783                                         i = SUCK_BE_U2(m->jcode + p + 1);
784                                         v = SUCK_BE_S2(m->jcode + p + 3);
785                                         iswide = false;
786                                         nextp = p + 5;
787                                 }
788                                 INDEX_ONEWORD(i);
789                                 LOCALTYPE_USED(i, TYPE_INT);
790                                 OP_LOCALINDEX_I(opcode, i, v);
791                         }
792                         break;
793
794                 /* wider index for loading, storing and incrementing ******************/
795
796                 case JAVA_WIDE:
797                         iswide = true;
798                         p++;
799                         goto fetch_opcode;
800
801                 /* managing arrays ****************************************************/
802
803                 case JAVA_NEWARRAY:
804                         switch (SUCK_BE_S1(m->jcode + p + 1)) {
805                         case 4:
806                                 bte = builtintable_get_internal(BUILTIN_newarray_boolean);
807                                 break;
808                         case 5:
809                                 bte = builtintable_get_internal(BUILTIN_newarray_char);
810                                 break;
811                         case 6:
812                                 bte = builtintable_get_internal(BUILTIN_newarray_float);
813                                 break;
814                         case 7:
815                                 bte = builtintable_get_internal(BUILTIN_newarray_double);
816                                 break;
817                         case 8:
818                                 bte = builtintable_get_internal(BUILTIN_newarray_byte);
819                                 break;
820                         case 9:
821                                 bte = builtintable_get_internal(BUILTIN_newarray_short);
822                                 break;
823                         case 10:
824                                 bte = builtintable_get_internal(BUILTIN_newarray_int);
825                                 break;
826                         case 11:
827                                 bte = builtintable_get_internal(BUILTIN_newarray_long);
828                                 break;
829 #if defined(ENABLE_VERIFIER)
830                         default:
831                                 exceptions_throw_verifyerror(m, "Invalid array-type to create");
832                                 return false;
833 #endif
834                         }
835                         OP_BUILTIN_CHECK_EXCEPTION(bte);
836                         break;
837
838                 case JAVA_ANEWARRAY:
839                         i = SUCK_BE_U2(m->jcode + p + 1);
840                         compr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
841                         if (!compr)
842                                 return false;
843
844                         if (!(cr = class_get_classref_multiarray_of(1, compr)))
845                                 return false;
846
847                         if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
848                                 return false;
849
850                         INSTRUCTIONS_CHECK(2);
851                         OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr);
852                         bte = builtintable_get_internal(BUILTIN_newarray);
853                         OP_BUILTIN_CHECK_EXCEPTION(bte);
854                         s_count++;
855                         break;
856
857                 case JAVA_MULTIANEWARRAY:
858                         jd->isleafmethod = false;
859                         i = SUCK_BE_U2(m->jcode + p + 1);
860                         j = SUCK_BE_U1(m->jcode + p + 3);
861   
862                         cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
863                         if (cr == NULL)
864                                 return false;
865   
866                         if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
867                                 return false;
868   
869                         /* if unresolved, c == NULL */
870   
871                         iptr->s1.argcount = j;
872                         OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, 0 /* flags */);
873                         break;
874
875                 /* control flow instructions ******************************************/
876
877                 case JAVA_IFEQ:
878                 case JAVA_IFLT:
879                 case JAVA_IFLE:
880                 case JAVA_IFNE:
881                 case JAVA_IFGT:
882                 case JAVA_IFGE:
883                 case JAVA_IFNULL:
884                 case JAVA_IFNONNULL:
885                 case JAVA_IF_ICMPEQ:
886                 case JAVA_IF_ICMPNE:
887                 case JAVA_IF_ICMPLT:
888                 case JAVA_IF_ICMPGT:
889                 case JAVA_IF_ICMPLE:
890                 case JAVA_IF_ICMPGE:
891                 case JAVA_IF_ACMPEQ:
892                 case JAVA_IF_ACMPNE:
893                 case JAVA_GOTO:
894                         i = p + SUCK_BE_S2(m->jcode + p + 1);
895                         CHECK_BYTECODE_INDEX(i);
896                         MARK_BASICBLOCK(i);
897                         blockend = true;
898                         OP_INSINDEX(opcode, i);
899                         break;
900
901                 case JAVA_GOTO_W:
902                         i = p + SUCK_BE_S4(m->jcode + p + 1);
903                         CHECK_BYTECODE_INDEX(i);
904                         MARK_BASICBLOCK(i);
905                         blockend = true;
906                         OP_INSINDEX(opcode, i);
907                         break;
908
909                 case JAVA_JSR:
910                         i = p + SUCK_BE_S2(m->jcode + p + 1);
911 jsr_tail:
912                         CHECK_BYTECODE_INDEX(i);
913                         MARK_BASICBLOCK(i);
914                         blockend = true;
915                         OP_PREPARE_ZEROFLAGS(JAVA_JSR);
916                         iptr->sx.s23.s3.jsrtarget.insindex = i;
917                         PINC;
918                         break;
919
920                 case JAVA_JSR_W:
921                         i = p + SUCK_BE_S4(m->jcode + p + 1);
922                         goto jsr_tail;
923
924                 case JAVA_RET:
925                         if (iswide == false) {
926                                 i = SUCK_BE_U1(m->jcode + p + 1);
927                         }
928                         else {
929                                 i = SUCK_BE_U2(m->jcode + p + 1);
930                                 nextp = p + 3;
931                                 iswide = false;
932                         }
933                         blockend = true;
934
935                         OP_LOAD_ONEWORD(opcode, i, TYPE_ADR);
936                         break;
937
938                 case JAVA_IRETURN:
939                 case JAVA_LRETURN:
940                 case JAVA_FRETURN:
941                 case JAVA_DRETURN:
942                 case JAVA_ARETURN:
943                 case JAVA_RETURN:
944                         blockend = true;
945                         /* XXX ARETURN will need a flag in the typechecker */
946                         OP(opcode);
947                         break;
948
949                 case JAVA_ATHROW:
950                         blockend = true;
951                         /* XXX ATHROW will need a flag in the typechecker */
952                         OP(opcode);
953                         break;
954
955
956                 /* table jumps ********************************************************/
957
958                 case JAVA_LOOKUPSWITCH:
959                         {
960                                 s4 num, j;
961                                 lookup_target_t *lookup;
962 #if defined(ENABLE_VERIFIER)
963                                 s4 prevvalue = 0;
964 #endif
965                                 blockend = true;
966                                 nextp = ALIGN((p + 1), 4);
967
968                                 CHECK_END_OF_BYTECODE(nextp + 8);
969
970                                 OP_PREPARE_ZEROFLAGS(opcode);
971
972                                 /* default target */
973
974                                 j = p + SUCK_BE_S4(m->jcode + nextp);
975                                 iptr->sx.s23.s3.lookupdefault.insindex = j;
976                                 nextp += 4;
977                                 CHECK_BYTECODE_INDEX(j);
978                                 MARK_BASICBLOCK(j);
979
980                                 /* number of pairs */
981
982                                 num = SUCK_BE_U4(m->jcode + nextp);
983                                 iptr->sx.s23.s2.lookupcount = num;
984                                 nextp += 4;
985
986                                 /* allocate the intermediate code table */
987
988                                 lookup = DMNEW(lookup_target_t, num);
989                                 iptr->dst.lookup = lookup;
990
991                                 /* iterate over the lookup table */
992
993                                 CHECK_END_OF_BYTECODE(nextp + 8 * num);
994
995                                 for (i = 0; i < num; i++) {
996                                         /* value */
997
998                                         j = SUCK_BE_S4(m->jcode + nextp);
999                                         lookup->value = j;
1000
1001                                         nextp += 4;
1002
1003 #if defined(ENABLE_VERIFIER)
1004                                         /* check if the lookup table is sorted correctly */
1005
1006                                         if (i && (j <= prevvalue)) {
1007                                                 exceptions_throw_verifyerror(m, "Unsorted lookup switch");
1008                                                 return false;
1009                                         }
1010                                         prevvalue = j;
1011 #endif
1012                                         /* target */
1013
1014                                         j = p + SUCK_BE_S4(m->jcode + nextp);
1015                                         lookup->target.insindex = j;
1016                                         lookup++;
1017                                         nextp += 4;
1018                                         CHECK_BYTECODE_INDEX(j);
1019                                         MARK_BASICBLOCK(j);
1020                                 }
1021
1022                                 PINC;
1023                                 break;
1024                         }
1025
1026
1027                 case JAVA_TABLESWITCH:
1028                         {
1029                                 s4 num, j;
1030                                 s4 deftarget;
1031                                 branch_target_t *table;
1032
1033                                 blockend = true;
1034                                 nextp = ALIGN((p + 1), 4);
1035
1036                                 CHECK_END_OF_BYTECODE(nextp + 12);
1037
1038                                 OP_PREPARE_ZEROFLAGS(opcode);
1039
1040                                 /* default target */
1041
1042                                 deftarget = p + SUCK_BE_S4(m->jcode + nextp);
1043                                 nextp += 4;
1044                                 CHECK_BYTECODE_INDEX(deftarget);
1045                                 MARK_BASICBLOCK(deftarget);
1046
1047                                 /* lower bound */
1048
1049                                 j = SUCK_BE_S4(m->jcode + nextp);
1050                                 iptr->sx.s23.s2.tablelow = j;
1051                                 nextp += 4;
1052
1053                                 /* upper bound */
1054
1055                                 num = SUCK_BE_S4(m->jcode + nextp);
1056                                 iptr->sx.s23.s3.tablehigh = num;
1057                                 nextp += 4;
1058
1059                                 /* calculate the number of table entries */
1060
1061                                 num = num - j + 1;
1062
1063 #if defined(ENABLE_VERIFIER)
1064                                 if (num < 1) {
1065                                         exceptions_throw_verifyerror(m,
1066                                                         "invalid TABLESWITCH: upper bound < lower bound");
1067                                         return false;
1068                                 }
1069 #endif
1070                                 /* create the intermediate code table */
1071                                 /* the first entry is the default target */
1072
1073                                 table = DMNEW(branch_target_t, 1 + num);
1074                                 iptr->dst.table = table;
1075                                 (table++)->insindex = deftarget;
1076
1077                                 /* iterate over the target table */
1078
1079                                 CHECK_END_OF_BYTECODE(nextp + 4 * num);
1080
1081                                 for (i = 0; i < num; i++) {
1082                                         j = p + SUCK_BE_S4(m->jcode + nextp);
1083                                         (table++)->insindex = j;
1084                                         nextp += 4;
1085                                         CHECK_BYTECODE_INDEX(j);
1086                                         MARK_BASICBLOCK(j);
1087                                 }
1088
1089                                 PINC;
1090                                 break;
1091                         }
1092
1093
1094                 /* load and store of object fields ************************************/
1095
1096                 case JAVA_AASTORE:
1097                         OP(opcode);
1098                         jd->isleafmethod = false;
1099                         break;
1100
1101                 case JAVA_GETSTATIC:
1102                 case JAVA_PUTSTATIC:
1103                 case JAVA_GETFIELD:
1104                 case JAVA_PUTFIELD:
1105                         {
1106                                 constant_FMIref  *fr;
1107                                 unresolved_field *uf;
1108
1109                                 i = SUCK_BE_U2(m->jcode + p + 1);
1110                                 fr = class_getconstant(m->class, i, CONSTANT_Fieldref);
1111                                 if (!fr)
1112                                         return false;
1113
1114                                 OP_PREPARE_ZEROFLAGS(opcode);
1115                                 iptr->sx.s23.s3.fmiref = fr;
1116
1117                                 /* only with -noverify, otherwise the typechecker does this */
1118
1119 #if defined(ENABLE_VERIFIER)
1120                                 if (!JITDATA_HAS_FLAG_VERIFY(jd)) {
1121 #endif
1122                                         result = resolve_field_lazy(m, fr);
1123                                         if (result == resolveFailed)
1124                                                 return false;
1125
1126                                         if (result != resolveSucceeded) {
1127                                                 uf = resolve_create_unresolved_field(m->class, m, iptr);
1128
1129                                                 if (uf == NULL)
1130                                                         return false;
1131
1132                                                 /* store the unresolved_field pointer */
1133
1134                                                 iptr->sx.s23.s3.uf = uf;
1135                                                 iptr->flags.bits = INS_FLAG_UNRESOLVED;
1136                                         }
1137 #if defined(ENABLE_VERIFIER)
1138                                 }
1139 #endif
1140                                 PINC;
1141                         }
1142                         break;
1143
1144
1145                 /* method invocation **************************************************/
1146
1147                 case JAVA_INVOKESTATIC:
1148                         i = SUCK_BE_U2(m->jcode + p + 1);
1149                         mr = class_getconstant(m->class, i, CONSTANT_Methodref);
1150
1151                         if (mr == NULL)
1152                                 return false;
1153
1154                         md = mr->parseddesc.md;
1155
1156                         if (md->params == NULL)
1157                                 if (!descriptor_params_from_paramtypes(md, ACC_STATIC))
1158                                         return false;
1159
1160                         goto invoke_method;
1161
1162                 case JAVA_INVOKEINTERFACE:
1163                         i = SUCK_BE_U2(m->jcode + p + 1);
1164
1165                         mr = class_getconstant(m->class, i, CONSTANT_InterfaceMethodref);
1166
1167                         goto invoke_nonstatic_method;
1168
1169                 case JAVA_INVOKESPECIAL:
1170                 case JAVA_INVOKEVIRTUAL:
1171                         i = SUCK_BE_U2(m->jcode + p + 1);
1172                         mr = class_getconstant(m->class, i, CONSTANT_Methodref);
1173
1174 invoke_nonstatic_method:
1175                         if (mr == NULL)
1176                                 return false;
1177
1178                         md = mr->parseddesc.md;
1179
1180                         if (md->params == NULL)
1181                                 if (!descriptor_params_from_paramtypes(md, 0))
1182                                         return false;
1183
1184 invoke_method:
1185                         jd->isleafmethod = false;
1186
1187                         OP_PREPARE_ZEROFLAGS(opcode);
1188                         iptr->sx.s23.s3.fmiref = mr;
1189
1190                         /* only with -noverify, otherwise the typechecker does this */
1191
1192 #if defined(ENABLE_VERIFIER)
1193                         if (!JITDATA_HAS_FLAG_VERIFY(jd)) {
1194 #endif
1195                                 result = resolve_method_lazy(m, mr, 
1196                                                 (opcode == JAVA_INVOKESPECIAL));
1197                                 if (result == resolveFailed)
1198                                         return false;
1199
1200                                 if (result == resolveSucceeded) {
1201                                         methodinfo *mi = iptr->sx.s23.s3.fmiref->p.method;
1202
1203                                         /* if this call is monomorphic, turn it into an INVOKESPECIAL */
1204
1205                                         assert(IS_FMIREF_RESOLVED(iptr->sx.s23.s3.fmiref));
1206
1207                                         if ((iptr->opc == ICMD_INVOKEVIRTUAL)
1208                                                 && (mi->flags & (ACC_FINAL | ACC_PRIVATE)))
1209                                         {
1210                                                 iptr->opc = ICMD_INVOKESPECIAL;
1211                                         }
1212                                 }
1213                                 else {
1214                                         um = resolve_create_unresolved_method(m->class, m, mr,
1215                                                         (opcode == JAVA_INVOKESTATIC),
1216                                                         (opcode == JAVA_INVOKESPECIAL));
1217
1218                                         if (!um)
1219                                                 return false;
1220
1221                                         /* store the unresolved_method pointer */
1222
1223                                         iptr->sx.s23.s3.um = um;
1224                                         iptr->flags.bits = INS_FLAG_UNRESOLVED;
1225                                 }
1226 #if defined(ENABLE_VERIFIER)
1227                         }
1228 #endif
1229                         PINC;
1230                         break;
1231
1232                 /* instructions taking class arguments ********************************/
1233
1234                 case JAVA_NEW:
1235                         i = SUCK_BE_U2(m->jcode + p + 1);
1236                         cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
1237                         if (!cr)
1238                                 return false;
1239
1240                         if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
1241                                 return false;
1242
1243                         INSTRUCTIONS_CHECK(2);
1244                         OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr);
1245                         bte = builtintable_get_internal(BUILTIN_new);
1246                         OP_BUILTIN_CHECK_EXCEPTION(bte);
1247                         s_count++;
1248                         break;
1249
1250                 case JAVA_CHECKCAST:
1251                         i = SUCK_BE_U2(m->jcode + p + 1);
1252                         cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
1253                         if (cr == NULL)
1254                                 return false;
1255
1256                         if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
1257                                 return false;
1258
1259                         if (cr->name->text[0] == '[') {
1260                                 /* array type cast-check */
1261                                 flags = INS_FLAG_ARRAY;
1262                                 jd->isleafmethod = false;
1263                         }
1264                         else {
1265                                 /* object type cast-check */
1266                                 flags = 0;
1267                         }
1268                         OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, flags);
1269                         break;
1270
1271                 case JAVA_INSTANCEOF:
1272                         i = SUCK_BE_U2(m->jcode + p + 1);
1273                         cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
1274                         if (cr == NULL)
1275                                 return false;
1276
1277                         if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
1278                                 return false;
1279
1280                         if (cr->name->text[0] == '[') {
1281                                 /* array type cast-check */
1282                                 INSTRUCTIONS_CHECK(2);
1283                                 OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr);
1284                                 bte = builtintable_get_internal(BUILTIN_arrayinstanceof);
1285                                 OP_BUILTIN_NO_EXCEPTION(bte);
1286                                 s_count++;
1287                         }
1288                         else {
1289                                 /* object type cast-check */
1290                                 OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, 0 /* flags*/);
1291                         }
1292                         break;
1293
1294                 /* synchronization instructions ***************************************/
1295
1296                 case JAVA_MONITORENTER:
1297 #if defined(ENABLE_THREADS)
1298                         if (checksync) {
1299                                 bte = builtintable_get_internal(LOCK_monitor_enter);
1300                                 OP_BUILTIN_CHECK_EXCEPTION(bte);
1301                         }
1302                         else
1303 #endif
1304                         {
1305                                 OP(ICMD_CHECKNULL_POP);
1306                         }
1307                         break;
1308
1309                 case JAVA_MONITOREXIT:
1310 #if defined(ENABLE_THREADS)
1311                         if (checksync) {
1312                                 bte = builtintable_get_internal(LOCK_monitor_exit);
1313                                 OP_BUILTIN_CHECK_EXCEPTION(bte);
1314                         }
1315                         else
1316 #endif
1317                         {
1318                                 OP(ICMD_CHECKNULL_POP);
1319                         }
1320                         break;
1321
1322                 /* arithmetic instructions that may become builtin functions **********/
1323
1324                 case JAVA_IDIV:
1325 #if !SUPPORT_DIVISION
1326                         bte = builtintable_get_internal(BUILTIN_idiv);
1327                         OP_BUILTIN_ARITHMETIC(opcode, bte);
1328 #else
1329                         OP(opcode);
1330 #endif
1331                         break;
1332
1333                 case JAVA_IREM:
1334 #if !SUPPORT_DIVISION
1335                         bte = builtintable_get_internal(BUILTIN_irem);
1336                         OP_BUILTIN_ARITHMETIC(opcode, bte);
1337 #else
1338                         OP(opcode);
1339 #endif
1340                         break;
1341
1342                 case JAVA_LDIV:
1343 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1344                         bte = builtintable_get_internal(BUILTIN_ldiv);
1345                         OP_BUILTIN_ARITHMETIC(opcode, bte);
1346 #else
1347                         OP(opcode);
1348 #endif
1349                         break;
1350
1351                 case JAVA_LREM:
1352 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1353                         bte = builtintable_get_internal(BUILTIN_lrem);
1354                         OP_BUILTIN_ARITHMETIC(opcode, bte);
1355 #else
1356                         OP(opcode);
1357 #endif
1358                         break;
1359
1360                 case JAVA_FREM:
1361 #if defined(__I386__)
1362                         OP(opcode);
1363 #else
1364                         bte = builtintable_get_internal(BUILTIN_frem);
1365                         OP_BUILTIN_NO_EXCEPTION(bte);
1366 #endif
1367                         break;
1368
1369                 case JAVA_DREM:
1370 #if defined(__I386__)
1371                         OP(opcode);
1372 #else
1373                         bte = builtintable_get_internal(BUILTIN_drem);
1374                         OP_BUILTIN_NO_EXCEPTION(bte);
1375 #endif
1376                         break;
1377
1378                 case JAVA_F2I:
1379 #if defined(__ALPHA__)
1380                         if (!opt_noieee) {
1381                                 bte = builtintable_get_internal(BUILTIN_f2i);
1382                                 OP_BUILTIN_NO_EXCEPTION(bte);
1383                         }
1384                         else
1385 #endif
1386                         {
1387                                 OP(opcode);
1388                         }
1389                         break;
1390
1391                 case JAVA_F2L:
1392 #if defined(__ALPHA__)
1393                         if (!opt_noieee) {
1394                                 bte = builtintable_get_internal(BUILTIN_f2l);
1395                                 OP_BUILTIN_NO_EXCEPTION(bte);
1396                         }
1397                         else
1398 #endif
1399                         {
1400                                 OP(opcode);
1401                         }
1402                         break;
1403
1404                 case JAVA_D2I:
1405 #if defined(__ALPHA__)
1406                         if (!opt_noieee) {
1407                                 bte = builtintable_get_internal(BUILTIN_d2i);
1408                                 OP_BUILTIN_NO_EXCEPTION(bte);
1409                         }
1410                         else
1411 #endif
1412                         {
1413                                 OP(opcode);
1414                         }
1415                         break;
1416
1417                 case JAVA_D2L:
1418 #if defined(__ALPHA__)
1419                         if (!opt_noieee) {
1420                                 bte = builtintable_get_internal(BUILTIN_d2l);
1421                                 OP_BUILTIN_NO_EXCEPTION(bte);
1422                         }
1423                         else
1424 #endif
1425                         {
1426                                 OP(opcode);
1427                         }
1428                         break;
1429
1430                 /* invalid opcodes ****************************************************/
1431
1432                         /* check for invalid opcodes if the verifier is enabled */
1433 #if defined(ENABLE_VERIFIER)
1434                 case JAVA_BREAKPOINT:
1435                         exceptions_throw_verifyerror(m, "Quick instructions shouldn't appear, yet.");
1436                         return false;
1437
1438                 case 186: /* unused opcode */
1439                 case 203:
1440                 case 204:
1441                 case 205:
1442                 case 206:
1443                 case 207:
1444                 case 208:
1445                 case 209:
1446                 case 210:
1447                 case 211:
1448                 case 212:
1449                 case 213:
1450                 case 214:
1451                 case 215:
1452                 case 216:
1453                 case 217:
1454                 case 218:
1455                 case 219:
1456                 case 220:
1457                 case 221:
1458                 case 222:
1459                 case 223:
1460                 case 224:
1461                 case 225:
1462                 case 226:
1463                 case 227:
1464                 case 228:
1465                 case 229:
1466                 case 230:
1467                 case 231:
1468                 case 232:
1469                 case 233:
1470                 case 234:
1471                 case 235:
1472                 case 236:
1473                 case 237:
1474                 case 238:
1475                 case 239:
1476                 case 240:
1477                 case 241:
1478                 case 242:
1479                 case 243:
1480                 case 244:
1481                 case 245:
1482                 case 246:
1483                 case 247:
1484                 case 248:
1485                 case 249:
1486                 case 250:
1487                 case 251:
1488                 case 252:
1489                 case 253:
1490                 case 254:
1491                 case 255:
1492                         exceptions_throw_verifyerror(m, "Illegal opcode %d at instr %d\n",
1493                                                                                  opcode, ipc);
1494                         return false;
1495                         break;
1496 #endif /* defined(ENABLE_VERIFIER) */
1497
1498                 /* opcodes that don't require translation *****************************/
1499
1500                 default:
1501                         /* straight-forward translation to ICMD */
1502                         OP(opcode);
1503                         break;
1504
1505                 } /* end switch */
1506
1507                 /* verifier checks ****************************************************/
1508
1509 #if defined(ENABLE_VERIFIER)
1510                 /* If WIDE was used correctly, iswide should have been reset by now. */
1511                 if (iswide) {
1512                         exceptions_throw_verifyerror(m,
1513                                         "Illegal instruction: WIDE before incompatible opcode");
1514                         return false;
1515                 }
1516 #endif /* defined(ENABLE_VERIFIER) */
1517
1518         } /* end for */
1519
1520         if (JITDATA_HAS_FLAG_REORDER(jd)) {
1521                 /* add a NOP to the last basic block */
1522
1523                 INSTRUCTIONS_CHECK(1);
1524                 OP(ICMD_NOP);
1525         }
1526
1527         /*** END OF LOOP **********************************************************/
1528
1529         /* assert that we did not write more ICMDs than allocated */
1530
1531         assert(ipc <= pd.instructionslength);
1532         assert(ipc == (iptr - pd.instructions));
1533
1534         /*** verifier checks ******************************************************/
1535
1536 #if defined(ENABLE_VERIFIER)
1537         if (p != m->jcodelength) {
1538                 exceptions_throw_verifyerror(m,
1539                                 "Command-sequence crosses code-boundary");
1540                 return false;
1541         }
1542
1543         if (!blockend) {
1544                 exceptions_throw_verifyerror(m, "Falling off the end of the code");
1545                 return false;
1546         }
1547 #endif /* defined(ENABLE_VERIFIER) */
1548
1549         /*** setup the methodinfo, allocate stack and basic blocks ****************/
1550
1551         /* adjust block count if target 0 is not first intermediate instruction */
1552
1553         if (!jd->basicblockindex[0] || (jd->basicblockindex[0] > 1))
1554                 b_count++;
1555
1556         /* copy local to method variables */
1557
1558         jd->instructions = pd.instructions;
1559         jd->instructioncount = ipc;
1560         jd->basicblockcount = b_count;
1561         jd->stackcount = s_count + jd->basicblockcount * m->maxstack; /* in-stacks */
1562
1563         /* allocate stack table */
1564
1565         jd->stack = DMNEW(stackelement, jd->stackcount);
1566
1567         /* build basic block list */
1568
1569         bptr = jd->basicblocks = DMNEW(basicblock, b_count + 1);    /* one more for end ipc */
1570
1571         /* zero out all basic block structures */
1572
1573         MZERO(bptr, basicblock, b_count + 1);
1574
1575         b_count = 0;
1576
1577         /* additional block if target 0 is not first intermediate instruction */
1578
1579         if (!jd->basicblockindex[0] || (jd->basicblockindex[0] > 1)) {
1580                 BASICBLOCK_INIT(bptr, m);
1581
1582                 bptr->iinstr = jd->instructions;
1583                 /* bptr->icount is set when the next block is allocated */
1584
1585                 bptr->nr = b_count++;
1586                 bptr++;
1587                 bptr[-1].next = bptr;
1588         }
1589
1590         /* allocate blocks */
1591
1592         for (p = 0; p < m->jcodelength; p++) {
1593                 if (jd->basicblockindex[p] & 1) {
1594 #if defined(ENABLE_VERIFIER)
1595                         /* Check if this block starts at the beginning of an
1596                            instruction. */
1597
1598                         if (!pd.instructionstart[p]) {
1599                                 exceptions_throw_verifyerror(m,
1600                                                 "Branch into middle of instruction");
1601                                 return false;
1602                         }
1603 #endif
1604
1605                         /* allocate the block */
1606
1607                         BASICBLOCK_INIT(bptr, m);
1608
1609                         bptr->iinstr = jd->instructions + (jd->basicblockindex[p] >> 1);
1610                         if (b_count) {
1611                                 bptr[-1].icount = bptr->iinstr - bptr[-1].iinstr;
1612                         }
1613                         /* bptr->icount is set when the next block is allocated */
1614
1615                         jd->basicblockindex[p] = b_count;
1616
1617                         bptr->nr = b_count++;
1618                         bptr++;
1619                         bptr[-1].next = bptr;
1620                 }
1621         }
1622
1623         /* set instruction count of last real block */
1624
1625         if (b_count) {
1626                 bptr[-1].icount = (jd->instructions + jd->instructioncount) - bptr[-1].iinstr;
1627         }
1628
1629         /* allocate additional block at end */
1630
1631         BASICBLOCK_INIT(bptr,m);
1632         bptr->nr = b_count;
1633         jd->basicblockindex[m->jcodelength] = b_count;
1634
1635         /* set basicblock pointers in exception table */
1636
1637         if (!parse_resolve_exception_table(jd))
1638                 return false;
1639
1640         /* store the local map */
1641
1642         jd->local_map = local_map;
1643
1644         /* calculate local variable renaming */
1645
1646         {
1647                 s4 nlocals = 0;
1648                 s4 i;
1649
1650                 s4 *mapptr;
1651
1652                 mapptr = local_map;
1653
1654                 /* iterate over local_map[0..m->maxlocals*5] and set all existing  */
1655                 /* index,type pairs (local_map[index*5+type]==1) to an unique value */
1656                 /* -> == new local var index */
1657                 for(i = 0; i < (m->maxlocals * 5); i++, mapptr++) {
1658                         if (*mapptr)
1659                                 *mapptr = nlocals++;
1660                         else
1661                                 *mapptr = UNUSED;
1662                 }
1663
1664                 jd->localcount = nlocals;
1665
1666                 /* calculate the (maximum) number of variables needed */
1667
1668                 jd->varcount = 
1669                           nlocals                                      /* local variables */
1670                         + jd->basicblockcount * m->maxstack                 /* invars */
1671                         + s_count;         /* variables created within blocks (non-invar) */
1672
1673                 /* reserve the first indices for local variables */
1674
1675                 jd->vartop = nlocals;
1676
1677                 /* reserve extra variables needed by stack analyse */
1678
1679                 jd->varcount += STACK_EXTRA_VARS;
1680                 jd->vartop   += STACK_EXTRA_VARS;
1681
1682                 /* The verifier needs space for saving invars in some cases and */
1683                 /* extra variables.                                             */
1684
1685 #if defined(ENABLE_VERIFIER)
1686                 jd->varcount += VERIFIER_EXTRA_LOCALS + VERIFIER_EXTRA_VARS + m->maxstack;
1687                 jd->vartop   += VERIFIER_EXTRA_LOCALS + VERIFIER_EXTRA_VARS + m->maxstack;
1688 #endif
1689                 /* allocate and initialize the variable array */
1690
1691                 jd->var = DMNEW(varinfo, jd->varcount);
1692                 MZERO(jd->var, varinfo, jd->varcount);
1693
1694                 /* set types of all locals in jd->var */
1695
1696                 for(mapptr = local_map, i = 0; i < (m->maxlocals * 5); i++, mapptr++)
1697                         if (*mapptr != UNUSED)
1698                                 VAR(*mapptr)->type = i%5;
1699         }
1700
1701         /* everything's ok */
1702
1703         return true;
1704
1705         /*** goto labels for throwing verifier exceptions *************************/
1706
1707 #if defined(ENABLE_VERIFIER)
1708
1709 throw_unexpected_end_of_bytecode:
1710         exceptions_throw_verifyerror(m, "Unexpected end of bytecode");
1711         return false;
1712
1713 throw_invalid_bytecode_index:
1714         exceptions_throw_verifyerror(m, "Illegal target of branch instruction");
1715         return false;
1716
1717 throw_illegal_local_variable_number:
1718         exceptions_throw_verifyerror(m, "Illegal local variable number");
1719         return false;
1720
1721 #endif /* ENABLE_VERIFIER */
1722 }
1723
1724
1725 /*
1726  * These are local overrides for various environment variables in Emacs.
1727  * Please do not remove this and leave it at the end of the file, where
1728  * Emacs will automagically detect them.
1729  * ---------------------------------------------------------------------
1730  * Local variables:
1731  * mode: c
1732  * indent-tabs-mode: t
1733  * c-basic-offset: 4
1734  * tab-width: 4
1735  * End:
1736  * vim:noexpandtab:sw=4:ts=4:
1737  */