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