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