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