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