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