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