* src/vm/jit/parse.c (new_parse): Replaced opt_verify with
[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 5202 2006-08-01 13:10:48Z twisti $
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                 new_block_insert(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                         new_block_insert(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                 new_block_insert(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 static exceptiontable * fillextable(methodinfo *m, 
148                                                                         exceptiontable *extable, 
149                                                                         exceptiontable *raw_extable, 
150                                                                 int exceptiontablelength, 
151                                                                         int *block_count)
152 {
153         int b_count, p, src;
154         
155         if (exceptiontablelength == 0) 
156                 return extable;
157
158         b_count = *block_count;
159
160         for (src = exceptiontablelength-1; src >=0; src--) {
161                 /* the start of the handled region becomes a basic block start */
162                 p = raw_extable[src].startpc;
163                 CHECK_BYTECODE_INDEX(p);
164                 extable->startpc = p;
165                 block_insert(p);
166                 
167                 p = raw_extable[src].endpc; /* see JVM Spec 4.7.3 */
168                 CHECK_BYTECODE_INDEX_EXCLUSIVE(p);
169
170 #if defined(ENABLE_VERIFIER)
171                 if (p <= raw_extable[src].startpc) {
172                         exceptions_throw_verifyerror(m,
173                                 "Invalid exception handler range");
174                         return NULL;
175                 }
176 #endif
177                 extable->endpc = p;
178                 
179                 /* end of handled region becomes a basic block boundary  */
180                 /* (If it is the bytecode end, we'll use the special     */
181                 /* end block that is created anyway.)                    */
182                 if (p < m->jcodelength) 
183                         block_insert(p);
184
185                 /* the start of the handler becomes a basic block start  */
186                 p = raw_extable[src].handlerpc;
187                 CHECK_BYTECODE_INDEX(p);
188                 extable->handlerpc = p;
189                 block_insert(p);
190
191                 extable->catchtype = raw_extable[src].catchtype;
192                 extable->next = NULL;
193                 extable->down = &extable[1];
194                 extable--;
195         }
196
197         *block_count = b_count;
198         
199         /* everything ok */
200         return extable;
201
202 #if defined(ENABLE_VERIFIER)
203 throw_invalid_bytecode_index:
204         exceptions_throw_verifyerror(m,
205                                                                  "Illegal bytecode index in exception table");
206         return NULL;
207 #endif
208 }
209
210 /*** macro for checking the length of the bytecode ***/
211
212 #if defined(ENABLE_VERIFIER)
213 #define CHECK_END_OF_BYTECODE(neededlength) \
214         do { \
215                 if ((neededlength) > m->jcodelength) \
216                         goto throw_unexpected_end_of_bytecode; \
217         } while (0)
218 #else /* !ENABLE_VERIFIER */
219 #define CHECK_END_OF_BYTECODE(neededlength)
220 #endif /* ENABLE_VERIFIER */
221
222 bool new_parse(jitdata *jd)
223 {
224         methodinfo  *m;             /* method being parsed                      */
225         codeinfo    *code;
226         codegendata *cd;
227         int  p;                     /* java instruction counter                 */
228         int  nextp;                 /* start of next java instruction           */
229         int  opcode;                /* java opcode                              */
230         int  i;                     /* temporary for different uses (ctrs)      */
231         int  ipc = 0;               /* intermediate instruction counter         */
232         int  b_count = 0;           /* basic block counter                      */
233         int  s_count = 0;           /* stack element counter                    */
234         bool blockend = false;      /* true if basic block end has been reached */
235         bool iswide = false;        /* true if last instruction was a wide      */
236         new_instruction *iptr;      /* current ptr into instruction array       */
237         u1 *instructionstart;       /* 1 for pcs which are valid instr. starts  */
238         constant_classref  *cr;
239         constant_classref  *compr;
240         classinfo          *c;
241         builtintable_entry *bte;
242         constant_FMIref    *mr;
243         methoddesc         *md;
244         unresolved_method  *um;
245         resolve_result_t    result;
246         u2                  lineindex = 0;
247         u2                  currentline = 0;
248         u2                  linepcchange = 0;
249         u4                  flags;
250         basicblock         *bptr;
251
252         /* get required compiler data */
253
254         m    = jd->m;
255         code = jd->code;
256         cd   = jd->cd;
257
258         /* allocate instruction array and block index table */
259
260         /* 1 additional for end ipc  */
261         jd->new_basicblockindex = DMNEW(s4, m->jcodelength + 1);
262         memset(jd->new_basicblockindex, 0, sizeof(s4) * (m->jcodelength + 1));
263
264         instructionstart = DMNEW(u1, m->jcodelength + 1);
265         memset(instructionstart, 0, sizeof(u1) * (m->jcodelength + 1));
266
267         /* IMPORTANT: We assume that parsing creates at most one instruction per */
268         /*            byte of original bytecode!                                 */
269
270         iptr = jd->new_instructions = DMNEW(new_instruction, m->jcodelength);
271
272         /* compute branch targets of exception table */
273
274         if (!new_fillextable(jd, m,
275                         &(cd->exceptiontable[cd->exceptiontablelength-1]),
276                         m->exceptiontable,
277                         m->exceptiontablelength,
278                         &b_count))
279         {
280                 return false;
281         }
282
283         s_count = 1 + m->exceptiontablelength; /* initialize stack element counter   */
284
285 #if defined(ENABLE_THREADS)
286         if (checksync && (m->flags & ACC_SYNCHRONIZED))
287                 jd->isleafmethod = false;
288 #endif
289
290         /* setup line number info */
291
292         currentline = 0;
293         linepcchange = 0;
294
295         if (m->linenumbercount == 0) {
296                 lineindex = 0;
297         }
298         else {
299                 linepcchange = m->linenumbers[0].start_pc;
300         }
301
302         /*** LOOP OVER ALL BYTECODE INSTRUCTIONS **********************************/
303
304         for (p = 0; p < m->jcodelength; p = nextp) {
305
306                 /* mark this position as a valid instruction start */
307
308                 instructionstart[p] = 1;
309
310                 /* change the current line number, if necessary */
311
312                 /* XXX rewrite this using pointer arithmetic */
313
314                 if (linepcchange == p) {
315                         if (m->linenumbercount > lineindex) {
316 next_linenumber:
317                                 currentline = m->linenumbers[lineindex].line_number;
318                                 lineindex++;
319                                 if (lineindex < m->linenumbercount) {
320                                         linepcchange = m->linenumbers[lineindex].start_pc;
321                                         if (linepcchange == p)
322                                                 goto next_linenumber;
323                                 }
324                         }
325                 }
326
327                 /* fetch next opcode  */
328 fetch_opcode:
329                 opcode = SUCK_BE_U1(m->jcode + p);
330
331                 /* store intermediate instruction count (bit 0 mark block starts) */
332
333                 jd->new_basicblockindex[p] |= (ipc << 1);
334
335                 /* some compilers put a JAVA_NOP after a blockend instruction */
336
337                 if (blockend && (opcode != JAVA_NOP)) {
338                         /* start new block */
339
340                         new_block_insert(p);
341                         blockend = false;
342                 }
343
344                 /* compute next instruction start */
345
346                 nextp = p + jcommandsize[opcode];
347
348                 CHECK_END_OF_BYTECODE(nextp);
349
350                 /* add stack elements produced by this instruction */
351
352                 s_count += stackreq[opcode];
353
354                 /* translate this bytecode instruction */
355
356                 switch (opcode) {
357
358                 case JAVA_NOP:
359                         break;
360
361                 /* pushing constants onto the stack ***********************************/
362
363                 case JAVA_BIPUSH:
364                         NEW_OP_LOADCONST_I(SUCK_BE_S1(m->jcode + p + 1));
365                         break;
366
367                 case JAVA_SIPUSH:
368                         NEW_OP_LOADCONST_I(SUCK_BE_S2(m->jcode + p + 1));
369                         break;
370
371                 case JAVA_LDC1:
372                         i = SUCK_BE_U1(m->jcode + p + 1);
373                         goto pushconstantitem;
374
375                 case JAVA_LDC2:
376                 case JAVA_LDC2W:
377                         i = SUCK_BE_U2(m->jcode + p + 1);
378
379                 pushconstantitem:
380
381 #if defined(ENABLE_VERIFIER)
382                         if (i >= m->class->cpcount) {
383                                 exceptions_throw_verifyerror(m,
384                                         "Attempt to access constant outside range");
385                                 return false;
386                         }
387 #endif
388
389                         switch (m->class->cptags[i]) {
390                         case CONSTANT_Integer:
391                                 NEW_OP_LOADCONST_I(((constant_integer *) (m->class->cpinfos[i]))->value);
392                                 break;
393                         case CONSTANT_Long:
394                                 NEW_OP_LOADCONST_L(((constant_long *) (m->class->cpinfos[i]))->value);
395                                 break;
396                         case CONSTANT_Float:
397                                 NEW_OP_LOADCONST_F(((constant_float *) (m->class->cpinfos[i]))->value);
398                                 break;
399                         case CONSTANT_Double:
400                                 NEW_OP_LOADCONST_D(((constant_double *) (m->class->cpinfos[i]))->value);
401                                 break;
402                         case CONSTANT_String:
403                                 NEW_OP_LOADCONST_STRING(literalstring_new((utf *) (m->class->cpinfos[i])));
404                                 break;
405                         case CONSTANT_Class:
406                                 cr = (constant_classref *) (m->class->cpinfos[i]);
407
408                                 if (!resolve_classref(m, cr, resolveLazy, true,
409                                                                           true, &c))
410                                         return false;
411
412                                 /* if not resolved, c == NULL */
413
414                                 NEW_OP_LOADCONST_CLASSINFO_OR_CLASSREF(c, cr, 0 /* no extra flags */);
415
416                                 break;
417
418 #if defined(ENABLE_VERIFIER)
419                         default:
420                                 exceptions_throw_verifyerror(m,
421                                                 "Invalid constant type to push");
422                                 return false;
423 #endif
424                         }
425                         break;
426
427                 case JAVA_ACONST_NULL:
428                         NEW_OP_LOADCONST_NULL();
429                         break;
430
431                 case JAVA_ICONST_M1:
432                 case JAVA_ICONST_0:
433                 case JAVA_ICONST_1:
434                 case JAVA_ICONST_2:
435                 case JAVA_ICONST_3:
436                 case JAVA_ICONST_4:
437                 case JAVA_ICONST_5:
438                         NEW_OP_LOADCONST_I(opcode - JAVA_ICONST_0);
439                         break;
440
441                 case JAVA_LCONST_0:
442                 case JAVA_LCONST_1:
443                         NEW_OP_LOADCONST_L(opcode - JAVA_LCONST_0);
444                         break;
445
446                 case JAVA_FCONST_0:
447                 case JAVA_FCONST_1:
448                 case JAVA_FCONST_2:
449                         NEW_OP_LOADCONST_F(opcode - JAVA_FCONST_0);
450                         break;
451
452                 case JAVA_DCONST_0:
453                 case JAVA_DCONST_1:
454                         NEW_OP_LOADCONST_D(opcode - JAVA_DCONST_0);
455                         break;
456
457                 /* local variable access instructions *********************************/
458
459                 case JAVA_ILOAD:
460                 case JAVA_FLOAD:
461                 case JAVA_ALOAD:
462                         if (iswide == false) {
463                                 i = SUCK_BE_U1(m->jcode + p + 1);
464                         }
465                         else {
466                                 i = SUCK_BE_U2(m->jcode + p + 1);
467                                 nextp = p + 3;
468                                 iswide = false;
469                         }
470                         NEW_OP_LOAD_ONEWORD(opcode, i);
471                         break;
472
473                 case JAVA_LLOAD:
474                 case JAVA_DLOAD:
475                         if (iswide == false) {
476                                 i = SUCK_BE_U1(m->jcode + p + 1);
477                         }
478                         else {
479                                 i = SUCK_BE_U2(m->jcode + p + 1);
480                                 nextp = p + 3;
481                                 iswide = false;
482                         }
483                         NEW_OP_LOAD_TWOWORD(opcode, i);
484                         break;
485
486                 case JAVA_ILOAD_0:
487                 case JAVA_ILOAD_1:
488                 case JAVA_ILOAD_2:
489                 case JAVA_ILOAD_3:
490                         NEW_OP_LOAD_ONEWORD(ICMD_ILOAD, opcode - JAVA_ILOAD_0);
491                         break;
492
493                 case JAVA_LLOAD_0:
494                 case JAVA_LLOAD_1:
495                 case JAVA_LLOAD_2:
496                 case JAVA_LLOAD_3:
497                         NEW_OP_LOAD_TWOWORD(ICMD_LLOAD, opcode - JAVA_LLOAD_0);
498                         break;
499
500                 case JAVA_FLOAD_0:
501                 case JAVA_FLOAD_1:
502                 case JAVA_FLOAD_2:
503                 case JAVA_FLOAD_3:
504                         NEW_OP_LOAD_ONEWORD(ICMD_FLOAD, opcode - JAVA_FLOAD_0);
505                         break;
506
507                 case JAVA_DLOAD_0:
508                 case JAVA_DLOAD_1:
509                 case JAVA_DLOAD_2:
510                 case JAVA_DLOAD_3:
511                         NEW_OP_LOAD_TWOWORD(ICMD_DLOAD, opcode - JAVA_DLOAD_0);
512                         break;
513
514                 case JAVA_ALOAD_0:
515                 case JAVA_ALOAD_1:
516                 case JAVA_ALOAD_2:
517                 case JAVA_ALOAD_3:
518                         NEW_OP_LOAD_ONEWORD(ICMD_ALOAD, opcode - JAVA_ALOAD_0);
519                         break;
520
521                 case JAVA_ISTORE:
522                 case JAVA_FSTORE:
523                 case JAVA_ASTORE:
524                         if (iswide == false) {
525                                 i = SUCK_BE_U1(m->jcode + p + 1);
526                         }
527                         else {
528                                 i = SUCK_BE_U2(m->jcode + p + 1);
529                                 iswide = false;
530                                 nextp = p + 3;
531                         }
532                         NEW_OP_STORE_ONEWORD(opcode, i);
533                         break;
534
535                 case JAVA_LSTORE:
536                 case JAVA_DSTORE:
537                         if (iswide == false) {
538                                 i = SUCK_BE_U1(m->jcode + p + 1);
539                         }
540                         else {
541                                 i = SUCK_BE_U2(m->jcode + p + 1);
542                                 iswide = false;
543                                 nextp = p + 3;
544                         }
545                         NEW_OP_STORE_TWOWORD(opcode, i);
546                         break;
547
548                 case JAVA_ISTORE_0:
549                 case JAVA_ISTORE_1:
550                 case JAVA_ISTORE_2:
551                 case JAVA_ISTORE_3:
552                         NEW_OP_STORE_ONEWORD(ICMD_ISTORE, opcode - JAVA_ISTORE_0);
553                         break;
554
555                 case JAVA_LSTORE_0:
556                 case JAVA_LSTORE_1:
557                 case JAVA_LSTORE_2:
558                 case JAVA_LSTORE_3:
559                         NEW_OP_STORE_TWOWORD(ICMD_LSTORE, opcode - JAVA_LSTORE_0);
560                         break;
561
562                 case JAVA_FSTORE_0:
563                 case JAVA_FSTORE_1:
564                 case JAVA_FSTORE_2:
565                 case JAVA_FSTORE_3:
566                         NEW_OP_STORE_ONEWORD(ICMD_FSTORE, opcode - JAVA_FSTORE_0);
567                         break;
568
569                 case JAVA_DSTORE_0:
570                 case JAVA_DSTORE_1:
571                 case JAVA_DSTORE_2:
572                 case JAVA_DSTORE_3:
573                         NEW_OP_STORE_TWOWORD(ICMD_DSTORE, opcode - JAVA_DSTORE_0);
574                         break;
575
576                 case JAVA_ASTORE_0:
577                 case JAVA_ASTORE_1:
578                 case JAVA_ASTORE_2:
579                 case JAVA_ASTORE_3:
580                         NEW_OP_STORE_ONEWORD(ICMD_ASTORE, opcode - JAVA_ASTORE_0);
581                         break;
582
583                 case JAVA_IINC:
584                         {
585                                 int v;
586
587                                 if (iswide == false) {
588                                         i = SUCK_BE_U1(m->jcode + p + 1);
589                                         v = SUCK_BE_S1(m->jcode + p + 2);
590
591                                 }
592                                 else {
593                                         i = SUCK_BE_U2(m->jcode + p + 1);
594                                         v = SUCK_BE_S2(m->jcode + p + 3);
595                                         iswide = false;
596                                         nextp = p + 5;
597                                 }
598                                 INDEX_ONEWORD(i);
599                                 NEW_OP_LOCALINDEX_I(opcode, i, v);
600                         }
601                         break;
602
603                 /* wider index for loading, storing and incrementing ******************/
604
605                 case JAVA_WIDE:
606                         iswide = true;
607                         p++;
608                         goto fetch_opcode;
609
610                 /* managing arrays ****************************************************/
611
612                 case JAVA_NEWARRAY:
613                         switch (SUCK_BE_S1(m->jcode + p + 1)) {
614                         case 4:
615                                 bte = builtintable_get_internal(BUILTIN_newarray_boolean);
616                                 break;
617                         case 5:
618                                 bte = builtintable_get_internal(BUILTIN_newarray_char);
619                                 break;
620                         case 6:
621                                 bte = builtintable_get_internal(BUILTIN_newarray_float);
622                                 break;
623                         case 7:
624                                 bte = builtintable_get_internal(BUILTIN_newarray_double);
625                                 break;
626                         case 8:
627                                 bte = builtintable_get_internal(BUILTIN_newarray_byte);
628                                 break;
629                         case 9:
630                                 bte = builtintable_get_internal(BUILTIN_newarray_short);
631                                 break;
632                         case 10:
633                                 bte = builtintable_get_internal(BUILTIN_newarray_int);
634                                 break;
635                         case 11:
636                                 bte = builtintable_get_internal(BUILTIN_newarray_long);
637                                 break;
638 #if defined(ENABLE_VERIFIER)
639                         default:
640                                 exceptions_throw_verifyerror(m, "Invalid array-type to create");
641                                 return false;
642 #endif
643                         }
644                         NEW_OP_BUILTIN_CHECK_EXCEPTION(bte);
645                         break;
646
647                 case JAVA_ANEWARRAY:
648                         i = SUCK_BE_U2(m->jcode + p + 1);
649                         compr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
650                         if (!compr)
651                                 return false;
652
653                         if (!(cr = class_get_classref_multiarray_of(1, compr)))
654                                 return false;
655
656                         if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
657                                 return false;
658
659                         NEW_OP_LOADCONST_CLASSINFO_OR_CLASSREF(c, cr, INS_FLAG_NOCHECK);
660                         bte = builtintable_get_internal(BUILTIN_newarray);
661                         NEW_OP_BUILTIN_CHECK_EXCEPTION(bte);
662                         s_count++;
663                         break;
664
665                 case JAVA_MULTIANEWARRAY:
666                         jd->isleafmethod = false;
667                         i = SUCK_BE_U2(m->jcode + p + 1);
668                         {
669                                 s4 v = SUCK_BE_U1(m->jcode + p + 3);
670
671                                 cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
672                                 if (!cr)
673                                         return false;
674
675                                 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
676                                         return false;
677
678                                 /* if unresolved, c == NULL */
679
680                                 iptr->s1.argcount = v;
681                                 NEW_OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, 0 /* flags */);
682                         }
683                         break;
684
685                 /* control flow instructions ******************************************/
686
687                 case JAVA_IFEQ:
688                 case JAVA_IFLT:
689                 case JAVA_IFLE:
690                 case JAVA_IFNE:
691                 case JAVA_IFGT:
692                 case JAVA_IFGE:
693                 case JAVA_IFNULL:
694                 case JAVA_IFNONNULL:
695                 case JAVA_IF_ICMPEQ:
696                 case JAVA_IF_ICMPNE:
697                 case JAVA_IF_ICMPLT:
698                 case JAVA_IF_ICMPGT:
699                 case JAVA_IF_ICMPLE:
700                 case JAVA_IF_ICMPGE:
701                 case JAVA_IF_ACMPEQ:
702                 case JAVA_IF_ACMPNE:
703                 case JAVA_GOTO:
704                         i = p + SUCK_BE_S2(m->jcode + p + 1);
705                         CHECK_BYTECODE_INDEX(i);
706                         new_block_insert(i);
707                         blockend = true;
708                         NEW_OP_INSINDEX(opcode, i);
709                         break;
710
711                 case JAVA_GOTO_W:
712                         i = p + SUCK_BE_S4(m->jcode + p + 1);
713                         CHECK_BYTECODE_INDEX(i);
714                         new_block_insert(i);
715                         blockend = true;
716                         NEW_OP_INSINDEX(opcode, i);
717                         break;
718
719                 case JAVA_JSR:
720                         i = p + SUCK_BE_S2(m->jcode + p + 1);
721 jsr_tail:
722                         CHECK_BYTECODE_INDEX(i);
723                         new_block_insert(i);
724                         blockend = true;
725                         NEW_OP_PREPARE_ZEROFLAGS(JAVA_JSR);
726                         iptr->sx.s23.s3.jsrtarget.insindex = i;
727                         PINC;
728                         break;
729
730                 case JAVA_JSR_W:
731                         i = p + SUCK_BE_S4(m->jcode + p + 1);
732                         goto jsr_tail;
733
734                 case JAVA_RET:
735                         if (iswide == false) {
736                                 i = SUCK_BE_U1(m->jcode + p + 1);
737                         }
738                         else {
739                                 i = SUCK_BE_U2(m->jcode + p + 1);
740                                 nextp = p + 3;
741                                 iswide = false;
742                         }
743                         blockend = true;
744
745                         NEW_OP_LOAD_ONEWORD(opcode, i);
746                         break;
747
748                 case JAVA_IRETURN:
749                 case JAVA_LRETURN:
750                 case JAVA_FRETURN:
751                 case JAVA_DRETURN:
752                 case JAVA_ARETURN:
753                 case JAVA_RETURN:
754                         blockend = true;
755                         /* XXX ARETURN will need a flag in the typechecker */
756                         NEW_OP(opcode);
757                         break;
758
759                 case JAVA_ATHROW:
760                         blockend = true;
761                         /* XXX ATHROW will need a flag in the typechecker */
762                         NEW_OP(opcode);
763                         break;
764
765
766                 /* table jumps ********************************************************/
767
768                 case JAVA_LOOKUPSWITCH:
769                         {
770                                 s4 num, j;
771                                 lookup_target_t *lookup;
772 #if defined(ENABLE_VERIFIER)
773                                 s4 prevvalue = 0;
774 #endif
775                                 blockend = true;
776                                 nextp = ALIGN((p + 1), 4);
777
778                                 CHECK_END_OF_BYTECODE(nextp + 8);
779
780                                 NEW_OP_PREPARE_ZEROFLAGS(opcode);
781
782                                 /* default target */
783
784                                 j = p + SUCK_BE_S4(m->jcode + nextp);
785                                 iptr->sx.s23.s3.lookupdefault.insindex = j;
786                                 nextp += 4;
787                                 CHECK_BYTECODE_INDEX(j);
788                                 new_block_insert(j);
789
790                                 /* number of pairs */
791
792                                 num = SUCK_BE_U4(m->jcode + nextp);
793                                 iptr->sx.s23.s2.lookupcount = num;
794                                 nextp += 4;
795
796                                 /* allocate the intermediate code table */
797
798                                 lookup = DMNEW(lookup_target_t, num);
799                                 iptr->dst.lookup = lookup;
800
801                                 /* iterate over the lookup table */
802
803                                 CHECK_END_OF_BYTECODE(nextp + 8 * num);
804
805                                 for (i = 0; i < num; i++) {
806                                         /* value */
807
808                                         j = SUCK_BE_S4(m->jcode + nextp);
809                                         lookup->value = j;
810
811                                         nextp += 4;
812
813 #if defined(ENABLE_VERIFIER)
814                                         /* check if the lookup table is sorted correctly */
815
816                                         if (i && (j <= prevvalue)) {
817                                                 exceptions_throw_verifyerror(m, "Unsorted lookup switch");
818                                                 return false;
819                                         }
820                                         prevvalue = j;
821 #endif
822                                         /* target */
823
824                                         j = p + SUCK_BE_S4(m->jcode + nextp);
825                                         lookup->target.insindex = j;
826                                         lookup++;
827                                         nextp += 4;
828                                         CHECK_BYTECODE_INDEX(j);
829                                         new_block_insert(j);
830                                 }
831
832                                 PINC;
833                                 break;
834                         }
835
836
837                 case JAVA_TABLESWITCH:
838                         {
839                                 s4 num, j;
840                                 s4 deftarget;
841                                 branch_target_t *table;
842
843                                 blockend = true;
844                                 nextp = ALIGN((p + 1), 4);
845
846                                 CHECK_END_OF_BYTECODE(nextp + 12);
847
848                                 NEW_OP_PREPARE_ZEROFLAGS(opcode);
849
850                                 /* default target */
851
852                                 deftarget = p + SUCK_BE_S4(m->jcode + nextp);
853                                 nextp += 4;
854                                 CHECK_BYTECODE_INDEX(deftarget);
855                                 new_block_insert(deftarget);
856
857                                 /* lower bound */
858
859                                 j = SUCK_BE_S4(m->jcode + nextp);
860                                 iptr->sx.s23.s2.tablelow = j;
861                                 nextp += 4;
862
863                                 /* upper bound */
864
865                                 num = SUCK_BE_S4(m->jcode + nextp);
866                                 iptr->sx.s23.s3.tablehigh = num;
867                                 nextp += 4;
868
869                                 /* calculate the number of table entries */
870
871                                 num = num - j + 1;
872
873 #if defined(ENABLE_VERIFIER)
874                                 if (num < 1) {
875                                         exceptions_throw_verifyerror(m,
876                                                         "invalid TABLESWITCH: upper bound < lower bound");
877                                         return false;
878                                 }
879 #endif
880                                 /* create the intermediate code table */
881                                 /* the first entry is the default target */
882
883                                 table = MNEW(branch_target_t, 1 + num);
884                                 iptr->dst.table = table;
885                                 (table++)->insindex = deftarget;
886
887                                 /* iterate over the target table */
888
889                                 CHECK_END_OF_BYTECODE(nextp + 4 * num);
890
891                                 for (i = 0; i < num; i++) {
892                                         j = p + SUCK_BE_S4(m->jcode + nextp);
893                                         (table++)->insindex = j;
894                                         nextp += 4;
895                                         CHECK_BYTECODE_INDEX(j);
896                                         new_block_insert(j);
897                                 }
898
899                                 PINC;
900                                 break;
901                         }
902
903
904                 /* load and store of object fields ************************************/
905
906                 case JAVA_AASTORE:
907                         NEW_OP(opcode);
908                         jd->isleafmethod = false;
909                         break;
910
911                 case JAVA_GETSTATIC:
912                 case JAVA_PUTSTATIC:
913                 case JAVA_GETFIELD:
914                 case JAVA_PUTFIELD:
915                         {
916                                 constant_FMIref  *fr;
917                                 unresolved_field *uf;
918
919                                 i = SUCK_BE_U2(m->jcode + p + 1);
920                                 fr = class_getconstant(m->class, i, CONSTANT_Fieldref);
921                                 if (!fr)
922                                         return false;
923
924                                 NEW_OP_PREPARE_ZEROFLAGS(opcode);
925                                 iptr->sx.s23.s3.fmiref = fr;
926
927                                 /* only with -noverify, otherwise the typechecker does this */
928
929 #if defined(ENABLE_VERIFIER)
930                                 if (!JITDATA_HAS_FLAG_VERIFY(jd)) {
931 #endif
932                                         result = new_resolve_field_lazy(iptr, NULL, m);
933                                         if (result == resolveFailed)
934                                                 return false;
935
936                                         if (result != resolveSucceeded) {
937                                                 uf = new_create_unresolved_field(m->class, m, iptr);
938
939                                                 if (uf == NULL)
940                                                         return false;
941
942                                                 /* store the unresolved_field pointer */
943
944                                                 iptr->sx.s23.s3.uf = uf;
945                                                 iptr->flags.bits = INS_FLAG_UNRESOLVED;
946                                         }
947 #if defined(ENABLE_VERIFIER)
948                                 }
949 #endif
950                                 PINC;
951                         }
952                         break;
953
954
955                 /* method invocation **************************************************/
956
957                 case JAVA_INVOKESTATIC:
958                         i = SUCK_BE_U2(m->jcode + p + 1);
959                         mr = class_getconstant(m->class, i, CONSTANT_Methodref);
960                         if (!mr)
961                                 return false;
962
963                         md = mr->parseddesc.md;
964
965                         if (!md->params)
966                                 if (!descriptor_params_from_paramtypes(md, ACC_STATIC))
967                                         return false;
968
969                         goto invoke_method;
970
971                 case JAVA_INVOKEINTERFACE:
972                         i = SUCK_BE_U2(m->jcode + p + 1);
973
974                         mr = class_getconstant(m->class, i,
975                                         CONSTANT_InterfaceMethodref);
976
977                         goto invoke_nonstatic_method;
978
979                 case JAVA_INVOKESPECIAL:
980                 case JAVA_INVOKEVIRTUAL:
981                         i = SUCK_BE_U2(m->jcode + p + 1);
982                         mr = class_getconstant(m->class, i, CONSTANT_Methodref);
983
984 invoke_nonstatic_method:
985                         if (!mr)
986                                 return false;
987
988                         md = mr->parseddesc.md;
989
990                         if (!md->params)
991                                 if (!descriptor_params_from_paramtypes(md, 0))
992                                         return false;
993
994 invoke_method:
995                         jd->isleafmethod = false;
996
997                         NEW_OP_PREPARE_ZEROFLAGS(opcode);
998                         iptr->sx.s23.s3.fmiref = mr;
999
1000                         /* only with -noverify, otherwise the typechecker does this */
1001
1002 #if defined(ENABLE_VERIFIER)
1003                         if (!JITDATA_HAS_FLAG_VERIFY(jd)) {
1004 #endif
1005                                 result = new_resolve_method_lazy(iptr, NULL, m);
1006                                 if (result == resolveFailed)
1007                                         return false;
1008
1009                                 if (result != resolveSucceeded) {
1010                                         um = new_create_unresolved_method(m->class, m, iptr);
1011
1012                                         if (!um)
1013                                                 return false;
1014
1015                                         /* store the unresolved_method pointer */
1016
1017                                         iptr->sx.s23.s3.um = um;
1018                                         iptr->flags.bits = INS_FLAG_UNRESOLVED;
1019                                 }
1020 #if defined(ENABLE_VERIFIER)
1021                         }
1022 #endif
1023                         PINC;
1024                         break;
1025
1026                 /* instructions taking class arguments ********************************/
1027
1028                 case JAVA_NEW:
1029                         i = SUCK_BE_U2(m->jcode + p + 1);
1030                         cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
1031                         if (!cr)
1032                                 return false;
1033
1034                         if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
1035                                 return false;
1036
1037                         NEW_OP_LOADCONST_CLASSINFO_OR_CLASSREF(c, cr, INS_FLAG_NOCHECK);
1038                         bte = builtintable_get_internal(BUILTIN_new);
1039                         NEW_OP_BUILTIN_CHECK_EXCEPTION(bte);
1040                         s_count++;
1041                         break;
1042
1043                 case JAVA_CHECKCAST:
1044                         i = SUCK_BE_U2(m->jcode + p + 1);
1045                         cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
1046                         if (!cr)
1047                                 return false;
1048
1049                         if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
1050                                 return false;
1051
1052                         if (cr->name->text[0] == '[') {
1053                                 /* array type cast-check */
1054                                 flags = INS_FLAG_ARRAY;
1055                                 jd->isleafmethod = false;
1056                         }
1057                         else {
1058                                 /* object type cast-check */
1059                                 flags = 0;
1060                         }
1061                         NEW_OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, flags);
1062                         break;
1063
1064                 case JAVA_INSTANCEOF:
1065                         i = SUCK_BE_U2(m->jcode + p + 1);
1066                         cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
1067                         if (!cr)
1068                                 return false;
1069
1070                         if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
1071                                 return false;
1072
1073                         if (cr->name->text[0] == '[') {
1074                                 /* array type cast-check */
1075                                 NEW_OP_LOADCONST_CLASSINFO_OR_CLASSREF(c, cr, INS_FLAG_NOCHECK);
1076                                 bte = builtintable_get_internal(BUILTIN_arrayinstanceof);
1077                                 NEW_OP_BUILTIN_NO_EXCEPTION(bte);
1078                                 s_count++;
1079                         }
1080                         else {
1081                                 /* object type cast-check */
1082                                 NEW_OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, 0 /* flags*/);
1083                         }
1084                         break;
1085
1086                 /* synchronization instructions ***************************************/
1087
1088                 case JAVA_MONITORENTER:
1089 #if defined(ENABLE_THREADS)
1090                         if (checksync) {
1091                                 /* XXX null check */
1092                                 bte = builtintable_get_internal(LOCK_monitor_enter);
1093                                 NEW_OP_BUILTIN_NO_EXCEPTION(bte);
1094                         }
1095                         else
1096 #endif
1097                         {
1098                                 NEW_OP(ICMD_CHECKNULL_POP);
1099                         }
1100                         break;
1101
1102                 case JAVA_MONITOREXIT:
1103 #if defined(ENABLE_THREADS)
1104                         if (checksync) {
1105                                 /* XXX null check */
1106                                 bte = builtintable_get_internal(LOCK_monitor_exit);
1107                                 NEW_OP_BUILTIN_CHECK_EXCEPTION(bte);
1108                         }
1109                         else
1110 #endif
1111                         {
1112                                 NEW_OP(ICMD_CHECKNULL_POP);
1113                         }
1114                         break;
1115
1116                 /* arithmetic instructions that may become builtin functions **********/
1117
1118                 case JAVA_IDIV:
1119 #if !SUPPORT_DIVISION
1120                         bte = builtintable_get_internal(BUILTIN_idiv);
1121                         NEW_OP_BUILTIN_ARITHMETIC(opcode, bte);
1122 #else
1123                         OP(opcode);
1124 #endif
1125                         break;
1126
1127                 case JAVA_IREM:
1128 #if !SUPPORT_DIVISION
1129                         bte = builtintable_get_internal(BUILTIN_irem);
1130                         NEW_OP_BUILTIN_ARITHMETIC(opcode, bte);
1131 #else
1132                         OP(opcode);
1133 #endif
1134                         break;
1135
1136                 case JAVA_LDIV:
1137 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1138                         bte = builtintable_get_internal(BUILTIN_ldiv);
1139                         NEW_OP_BUILTIN_ARITHMETIC(opcode, bte);
1140 #else
1141                         OP(opcode);
1142 #endif
1143                         break;
1144
1145                 case JAVA_LREM:
1146 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1147                         bte = builtintable_get_internal(BUILTIN_lrem);
1148                         NEW_OP_BUILTIN_ARITHMETIC(opcode, bte);
1149 #else
1150                         OP(opcode);
1151 #endif
1152                         break;
1153
1154                 case JAVA_FREM:
1155 #if defined(__I386__)
1156                         NEW_OP(opcode);
1157 #else
1158                         bte = builtintable_get_internal(BUILTIN_frem);
1159                         NEW_OP_BUILTIN_NO_EXCEPTION(bte);
1160 #endif
1161                         break;
1162
1163                 case JAVA_DREM:
1164 #if defined(__I386__)
1165                         NEW_OP(opcode);
1166 #else
1167                         bte = builtintable_get_internal(BUILTIN_drem);
1168                         NEW_OP_BUILTIN_NO_EXCEPTION(bte);
1169 #endif
1170                         break;
1171
1172                 case JAVA_F2I:
1173 #if defined(__ALPHA__)
1174                         if (!opt_noieee) {
1175                                 bte = builtintable_get_internal(BUILTIN_f2i);
1176                                 NEW_OP_BUILTIN_NO_EXCEPTION(bte);
1177                         }
1178                         else
1179 #endif
1180                         {
1181                                 NEW_OP(opcode);
1182                         }
1183                         break;
1184
1185                 case JAVA_F2L:
1186 #if defined(__ALPHA__)
1187                         if (!opt_noieee) {
1188                                 bte = builtintable_get_internal(BUILTIN_f2l);
1189                                 NEW_OP_BUILTIN_NO_EXCEPTION(bte);
1190                         }
1191                         else
1192 #endif
1193                         {
1194                                 NEW_OP(opcode);
1195                         }
1196                         break;
1197
1198                 case JAVA_D2I:
1199 #if defined(__ALPHA__)
1200                         if (!opt_noieee) {
1201                                 bte = builtintable_get_internal(BUILTIN_d2i);
1202                                 NEW_OP_BUILTIN_NO_EXCEPTION(bte);
1203                         }
1204                         else
1205 #endif
1206                         {
1207                                 NEW_OP(opcode);
1208                         }
1209                         break;
1210
1211                 case JAVA_D2L:
1212 #if defined(__ALPHA__)
1213                         if (!opt_noieee) {
1214                                 bte = builtintable_get_internal(BUILTIN_d2l);
1215                                 NEW_OP_BUILTIN_NO_EXCEPTION(bte);
1216                         }
1217                         else
1218 #endif
1219                         {
1220                                 NEW_OP(opcode);
1221                         }
1222                         break;
1223
1224                 /* invalid opcodes ****************************************************/
1225
1226                         /* check for invalid opcodes if the verifier is enabled */
1227 #if defined(ENABLE_VERIFIER)
1228                 case JAVA_BREAKPOINT:
1229                         exceptions_throw_verifyerror(m, "Quick instructions shouldn't appear, yet.");
1230                         return false;
1231
1232                 case 186: /* unused opcode */
1233                 case 203:
1234                 case 204:
1235                 case 205:
1236                 case 206:
1237                 case 207:
1238                 case 208:
1239                 case 209:
1240                 case 210:
1241                 case 211:
1242                 case 212:
1243                 case 213:
1244                 case 214:
1245                 case 215:
1246                 case 216:
1247                 case 217:
1248                 case 218:
1249                 case 219:
1250                 case 220:
1251                 case 221:
1252                 case 222:
1253                 case 223:
1254                 case 224:
1255                 case 225:
1256                 case 226:
1257                 case 227:
1258                 case 228:
1259                 case 229:
1260                 case 230:
1261                 case 231:
1262                 case 232:
1263                 case 233:
1264                 case 234:
1265                 case 235:
1266                 case 236:
1267                 case 237:
1268                 case 238:
1269                 case 239:
1270                 case 240:
1271                 case 241:
1272                 case 242:
1273                 case 243:
1274                 case 244:
1275                 case 245:
1276                 case 246:
1277                 case 247:
1278                 case 248:
1279                 case 249:
1280                 case 250:
1281                 case 251:
1282                 case 252:
1283                 case 253:
1284                 case 254:
1285                 case 255:
1286                         exceptions_throw_verifyerror(m, "Illegal opcode %d at instr %d\n",
1287                                                                                  opcode, ipc);
1288                         return false;
1289                         break;
1290 #endif /* defined(ENABLE_VERIFIER) */
1291
1292                 /* opcodes that don't require translation *****************************/
1293
1294                 default:
1295                         /* straight-forward translation to ICMD */
1296                         NEW_OP(opcode);
1297                         break;
1298
1299                 } /* end switch */
1300
1301                 /* verifier checks ****************************************************/
1302
1303 #if defined(ENABLE_VERIFIER)
1304                 /* If WIDE was used correctly, iswide should have been reset by now. */
1305                 if (iswide) {
1306                         exceptions_throw_verifyerror(m,
1307                                         "Illegal instruction: WIDE before incompatible opcode");
1308                         return false;
1309                 }
1310 #endif /* defined(ENABLE_VERIFIER) */
1311
1312         } /* end for */
1313
1314         /*** END OF LOOP **********************************************************/
1315
1316         /* assert that we did not write more ICMDs than allocated */
1317
1318         assert(ipc == (iptr - jd->new_instructions));
1319         assert(ipc <= m->jcodelength);
1320
1321         /*** verifier checks ******************************************************/
1322
1323 #if defined(ENABLE_VERIFIER)
1324         if (p != m->jcodelength) {
1325                 exceptions_throw_verifyerror(m,
1326                                 "Command-sequence crosses code-boundary");
1327                 return false;
1328         }
1329
1330         if (!blockend) {
1331                 exceptions_throw_verifyerror(m, "Falling off the end of the code");
1332                 return false;
1333         }
1334 #endif /* defined(ENABLE_VERIFIER) */
1335
1336         /*** setup the methodinfo, allocate stack and basic blocks ****************/
1337
1338         /* adjust block count if target 0 is not first intermediate instruction */
1339
1340         if (!jd->new_basicblockindex[0] || (jd->new_basicblockindex[0] > 1))
1341                 b_count++;
1342
1343         /* copy local to method variables */
1344
1345         jd->new_instructioncount = ipc;
1346         jd->new_basicblockcount = b_count;
1347         jd->new_stackcount = s_count + jd->new_basicblockcount * m->maxstack; /* in-stacks */
1348
1349         /* allocate stack table */
1350
1351         jd->new_stack = DMNEW(stackelement, jd->new_stackcount);
1352
1353         /* build basic block list */
1354
1355         bptr = jd->new_basicblocks = DMNEW(basicblock, b_count + 1);    /* one more for end ipc */
1356
1357         b_count = 0;
1358         jd->new_c_debug_nr = 0;
1359
1360         /* additional block if target 0 is not first intermediate instruction */
1361
1362         if (!jd->new_basicblockindex[0] || (jd->new_basicblockindex[0] > 1)) {
1363                 BASICBLOCK_INIT(bptr, m);
1364
1365                 bptr->iinstr = /* XXX */ (instruction *) jd->new_instructions;
1366                 /* bptr->icount is set when the next block is allocated */
1367
1368                 bptr++;
1369                 b_count++;
1370                 bptr[-1].next = bptr;
1371         }
1372
1373         /* allocate blocks */
1374
1375         for (p = 0; p < m->jcodelength; p++) {
1376                 if (jd->new_basicblockindex[p] & 1) {
1377                         /* Check if this block starts at the beginning of an          */
1378                         /* instruction.                                               */
1379 #if defined(ENABLE_VERIFIER)
1380                         if (!instructionstart[p]) {
1381                                 exceptions_throw_verifyerror(m,
1382                                                 "Branch into middle of instruction");
1383                                 return false;
1384                         }
1385 #endif
1386
1387                         /* allocate the block */
1388
1389                         BASICBLOCK_INIT(bptr, m);
1390
1391                         bptr->iinstr = /* XXX */ (instruction *) (jd->new_instructions + (jd->new_basicblockindex[p] >> 1));
1392                         if (b_count) {
1393                                 bptr[-1].icount = /*XXX*/ (new_instruction *)bptr->iinstr - (new_instruction*) bptr[-1].iinstr;
1394                         }
1395                         /* bptr->icount is set when the next block is allocated */
1396
1397                         jd->new_basicblockindex[p] = b_count;
1398
1399                         bptr++;
1400                         b_count++;
1401                         bptr[-1].next = bptr;
1402                 }
1403         }
1404
1405         /* set instruction count of last real block */
1406
1407         if (b_count) {
1408                 bptr[-1].icount = (jd->new_instructions + jd->new_instructioncount) - /* XXX */ (new_instruction *) bptr[-1].iinstr;
1409         }
1410
1411         /* allocate additional block at end */
1412
1413         BASICBLOCK_INIT(bptr,m);
1414
1415         bptr->instack = bptr->outstack = NULL;
1416         bptr->indepth = bptr->outdepth = 0;
1417         bptr->iinstr = NULL;
1418         bptr->icount = 0;
1419         bptr->next = NULL;
1420
1421         /* set basicblock pointers in exception table */
1422
1423         if (cd->exceptiontablelength > 0) {
1424                 cd->exceptiontable[cd->exceptiontablelength - 1].down = NULL;
1425         }
1426
1427         for (i = 0; i < cd->exceptiontablelength; ++i) {
1428                 p = cd->exceptiontable[i].startpc;
1429                 cd->exceptiontable[i].start = jd->new_basicblocks + jd->new_basicblockindex[p];
1430
1431                 p = cd->exceptiontable[i].endpc;
1432                 cd->exceptiontable[i].end = (p == m->jcodelength) ? (jd->new_basicblocks + jd->new_basicblockcount /*+ 1*/) : (jd->new_basicblocks + jd->new_basicblockindex[p]);
1433
1434                 p = cd->exceptiontable[i].handlerpc;
1435                 cd->exceptiontable[i].handler = jd->new_basicblocks + jd->new_basicblockindex[p];
1436         }
1437
1438         /* XXX activate this if you want to try inlining */
1439 #if 0
1440         for (i = 0; i < m->exceptiontablelength; ++i) {
1441                 p = m->exceptiontable[i].startpc;
1442                 m->exceptiontable[i].start = jd->new_basicblocks + jd->new_basicblockindex[p];
1443
1444                 p = m->exceptiontable[i].endpc;
1445                 m->exceptiontable[i].end = (p == m->jcodelength) ? (jd->new_basicblocks + jd->new_basicblockcount /*+ 1*/) : (jd->new_basicblocks + jd->new_basicblockindex[p]);
1446
1447                 p = m->exceptiontable[i].handlerpc;
1448                 m->exceptiontable[i].handler = jd->new_basicblocks + jd->new_basicblockindex[p];
1449         }
1450 #endif
1451
1452         /* everything's ok */
1453
1454         return true;
1455
1456         /*** goto labels for throwing verifier exceptions *************************/
1457
1458 #if defined(ENABLE_VERIFIER)
1459
1460 throw_unexpected_end_of_bytecode:
1461         exceptions_throw_verifyerror(m, "Unexpected end of bytecode");
1462         return false;
1463
1464 throw_invalid_bytecode_index:
1465         exceptions_throw_verifyerror(m, "Illegal target of branch instruction");
1466         return false;
1467
1468 throw_illegal_local_variable_number:
1469         exceptions_throw_verifyerror(m, "Illegal local variable number");
1470         return false;
1471
1472 #endif /* ENABLE_VERIFIER */
1473 }
1474
1475
1476 bool parse(jitdata *jd)
1477 {
1478         methodinfo  *m;
1479         codeinfo    *code;
1480         codegendata *cd;
1481         int  p;                     /* java instruction counter           */
1482         int  nextp;                 /* start of next java instruction     */
1483         int  opcode;                /* java opcode                        */
1484         int  i;                     /* temporary for different uses (ctrs)*/
1485         int  ipc = 0;               /* intermediate instruction counter   */
1486         int  b_count = 0;           /* basic block counter                */
1487         int  s_count = 0;           /* stack element counter              */
1488         bool blockend = false;      /* true if basic block end has been reached   */
1489         bool iswide = false;        /* true if last instruction was a wide*/
1490         instruction *iptr;          /* current ptr into instruction array */
1491
1492         u1 *instructionstart;       /* 1 for pcs which are valid instr. starts    */
1493
1494         constant_classref  *cr;
1495         constant_classref  *compr;
1496         classinfo          *c;
1497         builtintable_entry *bte;
1498
1499         constant_FMIref   *mr;
1500         methoddesc        *md;
1501         unresolved_method *um;
1502         resolve_result_t   result;
1503
1504         u2 lineindex = 0;
1505         u2 currentline = 0;
1506         u2 linepcchange = 0;
1507
1508         /* get required compiler data */
1509
1510         m    = jd->m;
1511         code = jd->code;
1512         cd   = jd->cd;
1513
1514         /* allocate instruction array and block index table */
1515         
1516         /* 1 additional for end ipc  */
1517         m->basicblockindex = DMNEW(s4, m->jcodelength + 1);
1518         memset(m->basicblockindex, 0, sizeof(s4) * (m->jcodelength + 1));
1519
1520         instructionstart = DMNEW(u1, m->jcodelength + 1);
1521         memset(instructionstart, 0, sizeof(u1) * (m->jcodelength + 1));
1522
1523         /* 1 additional for TRACEBUILTIN and 4 for MONITORENTER/EXIT */
1524         /* additional MONITOREXITS are reached by branches which are 3 bytes */
1525         
1526         iptr = m->instructions = DMNEW(instruction, m->jcodelength + 5);
1527
1528         /* Zero the intermediate instructions array so we don't have any
1529          * invalid pointers in it if we cannot finish analyse_stack(). */
1530
1531         memset(iptr, 0, sizeof(instruction) * (m->jcodelength + 5));
1532         
1533         /* compute branch targets of exception table */
1534
1535         if (!fillextable(m, 
1536                         &(cd->exceptiontable[cd->exceptiontablelength-1]), 
1537                         m->exceptiontable, 
1538                         m->exceptiontablelength, 
1539                         &b_count))
1540         {
1541                 return false;
1542         }
1543
1544         s_count = 1 + m->exceptiontablelength; /* initialize stack element counter   */
1545
1546 #if defined(ENABLE_THREADS)
1547         if (checksync && (m->flags & ACC_SYNCHRONIZED))
1548                 jd->isleafmethod = false;
1549 #endif
1550
1551         /* scan all java instructions */
1552         currentline = 0;
1553         linepcchange = 0;
1554
1555         if (m->linenumbercount == 0) {
1556                 lineindex = 0;
1557         } 
1558         else {
1559                 linepcchange = m->linenumbers[0].start_pc;
1560         }
1561
1562         for (p = 0; p < m->jcodelength; p = nextp) {
1563           
1564                 /* mark this position as a valid instruction start */
1565                 instructionstart[p] = 1;
1566                 if (linepcchange == p) {
1567                         if (m->linenumbercount > lineindex) {
1568 next_linenumber:
1569                                 currentline = m->linenumbers[lineindex].line_number;
1570                                 lineindex++;
1571                                 if (lineindex < m->linenumbercount) {
1572                                         linepcchange = m->linenumbers[lineindex].start_pc;
1573                                         if (linepcchange == p)
1574                                                 goto next_linenumber;
1575                                 }
1576                         }
1577                 }
1578
1579                 /* fetch next opcode  */
1580 fetch_opcode:
1581                 opcode = SUCK_BE_U1(m->jcode + p);
1582
1583                 m->basicblockindex[p] |= (ipc << 1); /*store intermed cnt*/
1584
1585                 /* some compilers put a JAVA_NOP after a blockend instruction */
1586
1587                 if (blockend && (opcode != JAVA_NOP)) {
1588                         /* start new block */
1589
1590                         block_insert(p);
1591                         blockend = false;
1592                 }
1593
1594                 nextp = p + jcommandsize[opcode];   /* compute next instruction start */
1595
1596                 CHECK_END_OF_BYTECODE(nextp);
1597
1598                 s_count += stackreq[opcode];            /* compute stack element count    */
1599                 switch (opcode) {
1600                 case JAVA_NOP:
1601                         break;
1602
1603                         /* pushing constants onto the stack p */
1604
1605                 case JAVA_BIPUSH:
1606                         LOADCONST_I(SUCK_BE_S1(m->jcode + p + 1));
1607                         break;
1608
1609                 case JAVA_SIPUSH:
1610                         LOADCONST_I(SUCK_BE_S2(m->jcode + p + 1));
1611                         break;
1612
1613                 case JAVA_LDC1:
1614                         i = SUCK_BE_U1(m->jcode + p + 1);
1615                         goto pushconstantitem;
1616
1617                 case JAVA_LDC2:
1618                 case JAVA_LDC2W:
1619                         i = SUCK_BE_U2(m->jcode + p + 1);
1620
1621                 pushconstantitem:
1622
1623 #if defined(ENABLE_VERIFIER)
1624                         if (i >= m->class->cpcount) {
1625                                 exceptions_throw_verifyerror(m,
1626                                         "Attempt to access constant outside range");
1627                                 return false;
1628                         }
1629 #endif
1630
1631                         switch (m->class->cptags[i]) {
1632                         case CONSTANT_Integer:
1633                                 LOADCONST_I(((constant_integer *) (m->class->cpinfos[i]))->value);
1634                                 break;
1635                         case CONSTANT_Long:
1636                                 LOADCONST_L(((constant_long *) (m->class->cpinfos[i]))->value);
1637                                 break;
1638                         case CONSTANT_Float:
1639                                 LOADCONST_F(((constant_float *) (m->class->cpinfos[i]))->value);
1640                                 break;
1641                         case CONSTANT_Double:
1642                                 LOADCONST_D(((constant_double *) (m->class->cpinfos[i]))->value);
1643                                 break;
1644                         case CONSTANT_String:
1645                                 LOADCONST_A(literalstring_new((utf *) (m->class->cpinfos[i])));
1646                                 break;
1647                         case CONSTANT_Class:
1648                                 cr = (constant_classref *) (m->class->cpinfos[i]);
1649
1650                                 if (!resolve_classref(m, cr, resolveLazy, true,
1651                                                                           true, &c))
1652                                         return false;
1653
1654                                 /* if not resolved, c == NULL */
1655
1656                                 if (c) {
1657                                         iptr->target = (void*) 0x02; /* XXX target used temporarily as flag */
1658                                         LOADCONST_A(c);
1659                                 }
1660                                 else {
1661                                         iptr->target = (void*) 0x03; /* XXX target used temporarily as flag */
1662                                         LOADCONST_A(cr);
1663                                 }
1664                                 break;
1665
1666 #if defined(ENABLE_VERIFIER)
1667                         default:
1668                                 exceptions_throw_verifyerror(m,
1669                                                 "Invalid constant type to push");
1670                                 return false;
1671 #endif
1672                         }
1673                         break;
1674
1675                 case JAVA_ACONST_NULL:
1676                         LOADCONST_A(NULL);
1677                         break;
1678
1679                 case JAVA_ICONST_M1:
1680                 case JAVA_ICONST_0:
1681                 case JAVA_ICONST_1:
1682                 case JAVA_ICONST_2:
1683                 case JAVA_ICONST_3:
1684                 case JAVA_ICONST_4:
1685                 case JAVA_ICONST_5:
1686                         LOADCONST_I(opcode - JAVA_ICONST_0);
1687                         break;
1688
1689                 case JAVA_LCONST_0:
1690                 case JAVA_LCONST_1:
1691                         LOADCONST_L(opcode - JAVA_LCONST_0);
1692                         break;
1693
1694                 case JAVA_FCONST_0:
1695                 case JAVA_FCONST_1:
1696                 case JAVA_FCONST_2:
1697                         LOADCONST_F(opcode - JAVA_FCONST_0);
1698                         break;
1699
1700                 case JAVA_DCONST_0:
1701                 case JAVA_DCONST_1:
1702                         LOADCONST_D(opcode - JAVA_DCONST_0);
1703                         break;
1704
1705                         /* loading variables onto the stack */
1706
1707                 case JAVA_ILOAD:
1708                 case JAVA_FLOAD:
1709                 case JAVA_ALOAD:
1710                         if (iswide == false) {
1711                                 i = SUCK_BE_U1(m->jcode + p + 1);
1712                         } 
1713                         else {
1714                                 i = SUCK_BE_U2(m->jcode + p + 1);
1715                                 nextp = p + 3;
1716                                 iswide = false;
1717                         }
1718                         OP1LOAD_ONEWORD(opcode, i);
1719                         break;
1720
1721                 case JAVA_LLOAD:
1722                 case JAVA_DLOAD:
1723                         if (iswide == false) {
1724                                 i = SUCK_BE_U1(m->jcode + p + 1);
1725                         } 
1726                         else {
1727                                 i = SUCK_BE_U2(m->jcode + p + 1);
1728                                 nextp = p + 3;
1729                                 iswide = false;
1730                         }
1731                         OP1LOAD_TWOWORD(opcode, i);
1732                         break;
1733
1734                 case JAVA_ILOAD_0:
1735                 case JAVA_ILOAD_1:
1736                 case JAVA_ILOAD_2:
1737                 case JAVA_ILOAD_3:
1738                         OP1LOAD_ONEWORD(ICMD_ILOAD, opcode - JAVA_ILOAD_0);
1739                         break;
1740
1741                 case JAVA_LLOAD_0:
1742                 case JAVA_LLOAD_1:
1743                 case JAVA_LLOAD_2:
1744                 case JAVA_LLOAD_3:
1745                         OP1LOAD_TWOWORD(ICMD_LLOAD, opcode - JAVA_LLOAD_0);
1746                         break;
1747
1748                 case JAVA_FLOAD_0:
1749                 case JAVA_FLOAD_1:
1750                 case JAVA_FLOAD_2:
1751                 case JAVA_FLOAD_3:
1752                         OP1LOAD_ONEWORD(ICMD_FLOAD, opcode - JAVA_FLOAD_0);
1753                         break;
1754
1755                 case JAVA_DLOAD_0:
1756                 case JAVA_DLOAD_1:
1757                 case JAVA_DLOAD_2:
1758                 case JAVA_DLOAD_3:
1759                         OP1LOAD_TWOWORD(ICMD_DLOAD, opcode - JAVA_DLOAD_0);
1760                         break;
1761
1762                 case JAVA_ALOAD_0:
1763                 case JAVA_ALOAD_1:
1764                 case JAVA_ALOAD_2:
1765                 case JAVA_ALOAD_3:
1766                         OP1LOAD_ONEWORD(ICMD_ALOAD, opcode - JAVA_ALOAD_0);
1767                         break;
1768
1769                         /* storing stack values into local variables */
1770
1771                 case JAVA_ISTORE:
1772                 case JAVA_FSTORE:
1773                 case JAVA_ASTORE:
1774                         if (iswide == false) {
1775                                 i = SUCK_BE_U1(m->jcode + p + 1);
1776                         } 
1777                         else {
1778                                 i = SUCK_BE_U2(m->jcode + p + 1);
1779                                 iswide = false;
1780                                 nextp = p + 3;
1781                         }
1782                         OP1STORE_ONEWORD(opcode, i);
1783                         break;
1784
1785                 case JAVA_LSTORE:
1786                 case JAVA_DSTORE:
1787                         if (iswide == false) {
1788                                 i = SUCK_BE_U1(m->jcode + p + 1);
1789                         } 
1790                         else {
1791                                 i = SUCK_BE_U2(m->jcode + p + 1);
1792                                 iswide = false;
1793                                 nextp = p + 3;
1794                         }
1795                         OP1STORE_TWOWORD(opcode, i);
1796                         break;
1797
1798                 case JAVA_ISTORE_0:
1799                 case JAVA_ISTORE_1:
1800                 case JAVA_ISTORE_2:
1801                 case JAVA_ISTORE_3:
1802                         OP1STORE_ONEWORD(ICMD_ISTORE, opcode - JAVA_ISTORE_0);
1803                         break;
1804
1805                 case JAVA_LSTORE_0:
1806                 case JAVA_LSTORE_1:
1807                 case JAVA_LSTORE_2:
1808                 case JAVA_LSTORE_3:
1809                         OP1STORE_TWOWORD(ICMD_LSTORE, opcode - JAVA_LSTORE_0);
1810                         break;
1811
1812                 case JAVA_FSTORE_0:
1813                 case JAVA_FSTORE_1:
1814                 case JAVA_FSTORE_2:
1815                 case JAVA_FSTORE_3:
1816                         OP1STORE_ONEWORD(ICMD_FSTORE, opcode - JAVA_FSTORE_0);
1817                         break;
1818
1819                 case JAVA_DSTORE_0:
1820                 case JAVA_DSTORE_1:
1821                 case JAVA_DSTORE_2:
1822                 case JAVA_DSTORE_3:
1823                         OP1STORE_TWOWORD(ICMD_DSTORE, opcode - JAVA_DSTORE_0);
1824                         break;
1825
1826                 case JAVA_ASTORE_0:
1827                 case JAVA_ASTORE_1:
1828                 case JAVA_ASTORE_2:
1829                 case JAVA_ASTORE_3:
1830                         OP1STORE_ONEWORD(ICMD_ASTORE, opcode - JAVA_ASTORE_0);
1831                         break;
1832
1833                 case JAVA_IINC:
1834                         {
1835                                 int v;
1836                                 
1837                                 if (iswide == false) {
1838                                         i = SUCK_BE_U1(m->jcode + p + 1);
1839                                         v = SUCK_BE_S1(m->jcode + p + 2);
1840
1841                                 } 
1842                                 else {
1843                                         i = SUCK_BE_U2(m->jcode + p + 1);
1844                                         v = SUCK_BE_S2(m->jcode + p + 3);
1845                                         iswide = false;
1846                                         nextp = p + 5;
1847                                 }
1848                                 INDEX_ONEWORD(i);
1849                                 OP2I(opcode, i, v);
1850                         }
1851                         break;
1852
1853                         /* wider index for loading, storing and incrementing */
1854
1855                 case JAVA_WIDE:
1856                         iswide = true;
1857                         p++;
1858                         goto fetch_opcode;
1859
1860                 /* managing arrays ****************************************************/
1861
1862                 case JAVA_NEWARRAY:
1863                         switch (SUCK_BE_S1(m->jcode + p + 1)) {
1864                         case 4:
1865                                 bte = builtintable_get_internal(BUILTIN_newarray_boolean);
1866                                 break;
1867                         case 5:
1868                                 bte = builtintable_get_internal(BUILTIN_newarray_char);
1869                                 break;
1870                         case 6:
1871                                 bte = builtintable_get_internal(BUILTIN_newarray_float);
1872                                 break;
1873                         case 7:
1874                                 bte = builtintable_get_internal(BUILTIN_newarray_double);
1875                                 break;
1876                         case 8:
1877                                 bte = builtintable_get_internal(BUILTIN_newarray_byte);
1878                                 break;
1879                         case 9:
1880                                 bte = builtintable_get_internal(BUILTIN_newarray_short);
1881                                 break;
1882                         case 10:
1883                                 bte = builtintable_get_internal(BUILTIN_newarray_int);
1884                                 break;
1885                         case 11:
1886                                 bte = builtintable_get_internal(BUILTIN_newarray_long);
1887                                 break;
1888 #if defined(ENABLE_VERIFIER)
1889                         default:
1890                                 exceptions_throw_verifyerror(m,
1891                                                 "Invalid array-type to create");
1892                                 return false;
1893 #endif
1894                         }
1895                         BUILTIN(bte, true, NULL, currentline);
1896                         break;
1897
1898                 case JAVA_ANEWARRAY:
1899                         i = SUCK_BE_U2(m->jcode + p + 1);
1900                         compr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
1901                         if (!compr)
1902                                 return false;
1903
1904                         if (!(cr = class_get_classref_multiarray_of(1, compr)))
1905                                 return false;
1906
1907                         if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
1908                                 return false;
1909
1910                         LOADCONST_A_BUILTIN(c, cr);
1911                         bte = builtintable_get_internal(BUILTIN_newarray);
1912                         BUILTIN(bte, true, NULL, currentline);
1913                         s_count++;
1914                         break;
1915
1916                 case JAVA_MULTIANEWARRAY:
1917                         jd->isleafmethod = false;
1918                         i = SUCK_BE_U2(m->jcode + p + 1);
1919                         {
1920                                 s4 v = SUCK_BE_U1(m->jcode + p + 3);
1921
1922                                 cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
1923                                 if (!cr)
1924                                         return false;
1925
1926                                 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
1927                                         return false;
1928
1929                                 /* if unresolved, c == NULL */
1930                                 OP2AT(opcode, v, c, cr, currentline);
1931                         }
1932                         break;
1933
1934                 case JAVA_IFEQ:
1935                 case JAVA_IFLT:
1936                 case JAVA_IFLE:
1937                 case JAVA_IFNE:
1938                 case JAVA_IFGT:
1939                 case JAVA_IFGE:
1940                 case JAVA_IFNULL:
1941                 case JAVA_IFNONNULL:
1942                 case JAVA_IF_ICMPEQ:
1943                 case JAVA_IF_ICMPNE:
1944                 case JAVA_IF_ICMPLT:
1945                 case JAVA_IF_ICMPGT:
1946                 case JAVA_IF_ICMPLE:
1947                 case JAVA_IF_ICMPGE:
1948                 case JAVA_IF_ACMPEQ:
1949                 case JAVA_IF_ACMPNE:
1950                 case JAVA_GOTO:
1951                 case JAVA_JSR:
1952                         i = p + SUCK_BE_S2(m->jcode + p + 1);
1953                         CHECK_BYTECODE_INDEX(i);
1954                         block_insert(i);
1955                         blockend = true;
1956                         OP1(opcode, i);
1957                         break;
1958
1959                 case JAVA_GOTO_W:
1960                 case JAVA_JSR_W:
1961                         i = p + SUCK_BE_S4(m->jcode + p + 1);
1962                         CHECK_BYTECODE_INDEX(i);
1963                         block_insert(i);
1964                         blockend = true;
1965                         OP1(opcode, i);
1966                         break;
1967
1968                 case JAVA_RET:
1969                         if (iswide == false) {
1970                                 i = SUCK_BE_U1(m->jcode + p + 1);
1971                         } 
1972                         else {
1973                                 i = SUCK_BE_U2(m->jcode + p + 1);
1974                                 nextp = p + 3;
1975                                 iswide = false;
1976                         }
1977                         blockend = true;
1978                                 
1979                         OP1LOAD_ONEWORD(opcode, i);
1980                         break;
1981
1982                 case JAVA_IRETURN:
1983                 case JAVA_LRETURN:
1984                 case JAVA_FRETURN:
1985                 case JAVA_DRETURN:
1986                 case JAVA_ARETURN:
1987                 case JAVA_RETURN:
1988                         blockend = true;
1989                         /* zero val.a so no patcher is inserted */
1990                         /* the type checker may set this later  */
1991                         iptr->val.a = NULL;
1992                         OP(opcode);
1993                         break;
1994
1995                 case JAVA_ATHROW:
1996                         blockend = true;
1997                         /* zero val.a so no patcher is inserted */
1998                         /* the type checker may set this later  */
1999                         iptr->val.a = NULL;
2000                         OP(opcode);
2001                         break;
2002                                 
2003
2004                 /* table jumps ********************************************************/
2005
2006                 case JAVA_LOOKUPSWITCH:
2007                         {
2008                                 s4 num, j;
2009                                 s4 *tablep;
2010 #if defined(ENABLE_VERIFIER)
2011                                 s4 prevvalue = 0;
2012 #endif
2013
2014                                 blockend = true;
2015                                 nextp = ALIGN((p + 1), 4);
2016
2017                                 CHECK_END_OF_BYTECODE(nextp + 8);
2018
2019                                 tablep = (s4 *) (m->jcode + nextp);
2020
2021                                 OP2A(opcode, 0, tablep, currentline);
2022
2023                                 /* default target */
2024
2025                                 j =  p + SUCK_BE_S4(m->jcode + nextp);
2026                                 *tablep = j;     /* restore for little endian */
2027                                 tablep++;
2028                                 nextp += 4;
2029                                 CHECK_BYTECODE_INDEX(j);
2030                                 block_insert(j);
2031
2032                                 /* number of pairs */
2033
2034                                 num = SUCK_BE_U4(m->jcode + nextp);
2035                                 *tablep = num;
2036                                 tablep++;
2037                                 nextp += 4;
2038
2039                                 CHECK_END_OF_BYTECODE(nextp + 8 * num);
2040
2041                                 for (i = 0; i < num; i++) {
2042                                         /* value */
2043
2044                                         j = SUCK_BE_S4(m->jcode + nextp);
2045                                         *tablep = j; /* restore for little endian */
2046                                         tablep++;
2047                                         nextp += 4;
2048
2049 #if defined(ENABLE_VERIFIER)
2050                                         /* check if the lookup table is sorted correctly */
2051                                         
2052                                         if (i && (j <= prevvalue)) {
2053                                                 exceptions_throw_verifyerror(m, "Unsorted lookup switch");
2054                                                 return false;
2055                                         }
2056                                         prevvalue = j;
2057 #endif
2058
2059                                         /* target */
2060
2061                                         j = p + SUCK_BE_S4(m->jcode + nextp);
2062                                         *tablep = j; /* restore for little endian */
2063                                         tablep++;
2064                                         nextp += 4;
2065                                         CHECK_BYTECODE_INDEX(j);
2066                                         block_insert(j);
2067                                 }
2068
2069                                 break;
2070                         }
2071
2072
2073                 case JAVA_TABLESWITCH:
2074                         {
2075                                 s4 num, j;
2076                                 s4 *tablep;
2077
2078                                 blockend = true;
2079                                 nextp = ALIGN((p + 1), 4);
2080
2081                                 CHECK_END_OF_BYTECODE(nextp + 12);
2082
2083                                 tablep = (s4 *) (m->jcode + nextp);
2084
2085                                 OP2A(opcode, 0, tablep, currentline);
2086
2087                                 /* default target */
2088
2089                                 j = p + SUCK_BE_S4(m->jcode + nextp);
2090                                 *tablep = j;     /* restore for little endian */
2091                                 tablep++;
2092                                 nextp += 4;
2093                                 CHECK_BYTECODE_INDEX(j);
2094                                 block_insert(j);
2095
2096                                 /* lower bound */
2097
2098                                 j = SUCK_BE_S4(m->jcode + nextp);
2099                                 *tablep = j;     /* restore for little endian */
2100                                 tablep++;
2101                                 nextp += 4;
2102
2103                                 /* upper bound */
2104
2105                                 num = SUCK_BE_S4(m->jcode + nextp);
2106                                 *tablep = num;   /* restore for little endian */
2107                                 tablep++;
2108                                 nextp += 4;
2109
2110                                 num -= j;  /* difference of upper - lower */
2111
2112 #if defined(ENABLE_VERIFIER)
2113                                 if (num < 0) {
2114                                         exceptions_throw_verifyerror(m,
2115                                                         "invalid TABLESWITCH: upper bound < lower bound");
2116                                         return false;
2117                                 }
2118 #endif
2119
2120                                 CHECK_END_OF_BYTECODE(nextp + 4 * (num + 1));
2121
2122                                 for (i = 0; i <= num; i++) {
2123                                         j = p + SUCK_BE_S4(m->jcode + nextp);
2124                                         *tablep = j; /* restore for little endian */
2125                                         tablep++;
2126                                         nextp += 4;
2127                                         CHECK_BYTECODE_INDEX(j);
2128                                         block_insert(j);
2129                                 }
2130
2131                                 break;
2132                         }
2133
2134
2135                 /* load and store of object fields ************************************/
2136
2137                 case JAVA_AASTORE:
2138                         OP(opcode);
2139                         jd->isleafmethod = false;
2140                         break;
2141
2142                 case JAVA_GETSTATIC:
2143                 case JAVA_PUTSTATIC:
2144                 case JAVA_GETFIELD:
2145                 case JAVA_PUTFIELD:
2146                         {
2147                                 constant_FMIref  *fr;
2148                                 unresolved_field *uf;
2149
2150                                 i = SUCK_BE_U2(m->jcode + p + 1);
2151                                 fr = class_getconstant(m->class, i, CONSTANT_Fieldref);
2152                                 if (!fr)
2153                                         return false;
2154
2155                                 OP2A_NOINC(opcode, fr->parseddesc.fd->type, fr, currentline);
2156
2157                                 /* only with -noverify, otherwise the typechecker does this */
2158
2159 #if defined(ENABLE_VERIFIER)
2160                                 if (!JITDATA_HAS_FLAG_VERIFY(jd)) {
2161 #endif
2162                                         result = resolve_field_lazy(iptr, NULL, m);
2163                                         if (result == resolveFailed)
2164                                                 return false;
2165
2166                                         if (result != resolveSucceeded) {
2167                                                 uf = create_unresolved_field(m->class, m, iptr);
2168
2169                                                 if (uf == NULL)
2170                                                         return false;
2171
2172                                                 /* store the unresolved_field pointer */
2173
2174                                                 /* XXX this will be changed */
2175                                                 iptr->val.a = uf;
2176                                                 iptr->target = (void*) 0x01; /* XXX target temporarily used as flag */
2177                                         }
2178                                         else {
2179                                                 iptr->target = NULL;
2180                                         }
2181 #if defined(ENABLE_VERIFIER)
2182                                 }
2183                                 else {
2184                                         iptr->target = NULL;
2185                                 }
2186 #endif
2187                                 PINC;
2188                         }
2189                         break;
2190                                 
2191
2192                 /* method invocation **************************************************/
2193
2194                 case JAVA_INVOKESTATIC:
2195                         i = SUCK_BE_U2(m->jcode + p + 1);
2196                         mr = class_getconstant(m->class, i, CONSTANT_Methodref);
2197                         if (!mr)
2198                                 return false;
2199
2200                         md = mr->parseddesc.md;
2201
2202                         if (!md->params)
2203                                 if (!descriptor_params_from_paramtypes(md, ACC_STATIC))
2204                                         return false;
2205
2206                         goto invoke_method;
2207
2208                 case JAVA_INVOKEINTERFACE:
2209                         i = SUCK_BE_U2(m->jcode + p + 1);
2210                         mr = class_getconstant(m->class, i, CONSTANT_InterfaceMethodref);
2211
2212                         goto invoke_nonstatic_method;
2213
2214                 case JAVA_INVOKESPECIAL:
2215                 case JAVA_INVOKEVIRTUAL:
2216                         i = SUCK_BE_U2(m->jcode + p + 1);
2217                         mr = class_getconstant(m->class, i, CONSTANT_Methodref);
2218
2219 invoke_nonstatic_method:
2220                         if (!mr)
2221                                 return false;
2222
2223                         md = mr->parseddesc.md;
2224
2225                         if (!md->params)
2226                                 if (!descriptor_params_from_paramtypes(md, 0))
2227                                         return false;
2228
2229 invoke_method:
2230                         jd->isleafmethod = false;
2231
2232                         OP2A_NOINC(opcode, 0, mr, currentline);
2233
2234                         /* only with -noverify, otherwise the typechecker does this */
2235
2236 #if defined(ENABLE_VERIFIER)
2237                         if (!JITDATA_HAS_FLAG_VERIFY(jd)) {
2238 #endif
2239                                 result = resolve_method_lazy(iptr, NULL, m);
2240                                 if (result == resolveFailed)
2241                                         return false;
2242
2243                                 if (result != resolveSucceeded) {
2244                                         um = create_unresolved_method(m->class, m, iptr);
2245
2246                                         if (um == NULL)
2247                                                 return false;
2248
2249                                         /* store the unresolved_method pointer */
2250
2251                                         /* XXX this will be changed */
2252                                         iptr->val.a = um;
2253                                         iptr->target = (void*) 0x01; /* XXX target temporarily used as flag */
2254                                 }
2255                                 else {
2256                                         /* the method could be resolved */
2257                                         iptr->target = NULL;
2258                                 }
2259 #if defined(ENABLE_VERIFIER)
2260                         }
2261                         else {
2262                                 iptr->target = NULL;
2263                         }
2264 #endif
2265                         PINC;
2266                         break;
2267
2268                 /* miscellaneous object operations ************************************/
2269
2270                 case JAVA_NEW:
2271                         i = SUCK_BE_U2(m->jcode + p + 1);
2272                         cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
2273                         if (!cr)
2274                                 return false;
2275
2276                         if (!resolve_classref(m, cr, resolveLazy, true, true,
2277                                                                   &c))
2278                                 return false;
2279
2280                         LOADCONST_A_BUILTIN(c, cr);
2281                         bte = builtintable_get_internal(BUILTIN_new);
2282                         BUILTIN(bte, true, NULL, currentline);
2283                         s_count++;
2284                         break;
2285
2286                 case JAVA_CHECKCAST:
2287                         i = SUCK_BE_U2(m->jcode + p + 1);
2288                         cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
2289                         if (!cr)
2290                                 return false;
2291
2292                         if (!resolve_classref(m, cr, resolveLazy, true,
2293                                                                   true, &c))
2294                                 return false;
2295
2296                         if (cr->name->text[0] == '[') {
2297                                 /* array type cast-check */
2298                                 OP2AT(opcode, 0, c, cr, currentline);
2299                                 jd->isleafmethod = false;
2300
2301                         } 
2302                         else {
2303                                 /* object type cast-check */
2304                                 OP2AT(opcode, 1, c, cr, currentline);
2305                         }
2306                         break;
2307
2308                 case JAVA_INSTANCEOF:
2309                         i = SUCK_BE_U2(m->jcode + p + 1);
2310                         cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
2311                         if (!cr)
2312                                 return false;
2313
2314                         if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
2315                                 return false;
2316
2317                         if (cr->name->text[0] == '[') {
2318                                 /* array type cast-check */
2319                                 LOADCONST_A_BUILTIN(c, cr);
2320                                 bte = builtintable_get_internal(BUILTIN_arrayinstanceof);
2321                                 BUILTIN(bte, false, NULL, currentline);
2322                                 s_count++;
2323
2324                         } 
2325                         else {
2326                                 /* object type cast-check */
2327                                 OP2AT(opcode, 1, c, cr, currentline);
2328                         }
2329                         break;
2330
2331                 case JAVA_MONITORENTER:
2332 #if defined(ENABLE_THREADS)
2333                         if (checksync) {
2334                                 OP(ICMD_CHECKNULL);
2335                                 bte = builtintable_get_internal(LOCK_monitor_enter);
2336                                 BUILTIN(bte, false, NULL, currentline);
2337                         } 
2338                         else
2339 #endif
2340                                 {
2341                                         OP(ICMD_CHECKNULL);
2342                                         OP(ICMD_POP);
2343                                 }
2344                         break;
2345
2346                 case JAVA_MONITOREXIT:
2347 #if defined(ENABLE_THREADS)
2348                         if (checksync) {
2349                                 bte = builtintable_get_internal(LOCK_monitor_exit);
2350                                 BUILTIN(bte, false, NULL, currentline);
2351                         } 
2352                         else
2353 #endif
2354                                 {
2355                                         OP(ICMD_POP);
2356                                 }
2357                         break;
2358
2359                 /* any other basic operation ******************************************/
2360
2361                 case JAVA_IDIV:
2362 #if !SUPPORT_DIVISION
2363                         bte = builtintable_get_internal(BUILTIN_idiv);
2364                         OP2A(opcode, bte->md->paramcount, bte, currentline);
2365                         jd->isleafmethod = false;
2366 #else
2367                         OP(opcode);
2368 #endif
2369                         break;
2370
2371                 case JAVA_IREM:
2372 #if !SUPPORT_DIVISION
2373                         bte = builtintable_get_internal(BUILTIN_irem);
2374                         OP2A(opcode, bte->md->paramcount, bte, currentline);
2375                         jd->isleafmethod = false;
2376 #else
2377                         OP(opcode);
2378 #endif
2379                         break;
2380
2381                 case JAVA_LDIV:
2382 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
2383                         bte = builtintable_get_internal(BUILTIN_ldiv);
2384                         OP2A(opcode, bte->md->paramcount, bte, currentline);
2385                         jd->isleafmethod = false;
2386 #else
2387                         OP(opcode);
2388 #endif
2389                         break;
2390
2391                 case JAVA_LREM:
2392 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
2393                         bte = builtintable_get_internal(BUILTIN_lrem);
2394                         OP2A(opcode, bte->md->paramcount, bte, currentline);
2395                         jd->isleafmethod = false;
2396 #else
2397                         OP(opcode);
2398 #endif
2399                         break;
2400
2401                 case JAVA_FREM:
2402 #if defined(__I386__)
2403                         OP(opcode);
2404 #else
2405                         bte = builtintable_get_internal(BUILTIN_frem);
2406                         BUILTIN(bte, false, NULL, currentline);
2407 #endif
2408                         break;
2409
2410                 case JAVA_DREM:
2411 #if defined(__I386__)
2412                         OP(opcode);
2413 #else
2414                         bte = builtintable_get_internal(BUILTIN_drem);
2415                         BUILTIN(bte, false, NULL, currentline);
2416 #endif
2417                         break;
2418
2419                 case JAVA_F2I:
2420 #if defined(__ALPHA__)
2421                         if (!opt_noieee) {
2422                                 bte = builtintable_get_internal(BUILTIN_f2i);
2423                                 BUILTIN(bte, false, NULL, currentline);
2424                         } 
2425                         else
2426 #endif
2427                                 {
2428                                         OP(opcode);
2429                                 }
2430                         break;
2431
2432                 case JAVA_F2L:
2433 #if defined(__ALPHA__)
2434                         if (!opt_noieee) {
2435                                 bte = builtintable_get_internal(BUILTIN_f2l);
2436                                 BUILTIN(bte, false, NULL, currentline);
2437                         } 
2438                         else 
2439 #endif
2440                                 {
2441                                         OP(opcode);
2442                                 }
2443                         break;
2444
2445                 case JAVA_D2I:
2446 #if defined(__ALPHA__)
2447                         if (!opt_noieee) {
2448                                 bte = builtintable_get_internal(BUILTIN_d2i);
2449                                 BUILTIN(bte, false, NULL, currentline);
2450                         } 
2451                         else
2452 #endif
2453                                 {
2454                                         OP(opcode);
2455                                 }
2456                         break;
2457
2458                 case JAVA_D2L:
2459 #if defined(__ALPHA__)
2460                         if (!opt_noieee) {
2461                                 bte = builtintable_get_internal(BUILTIN_d2l);
2462                                 BUILTIN(bte, false, NULL, currentline);
2463                         } 
2464                         else
2465 #endif
2466                                 {
2467                                         OP(opcode);
2468                                 }
2469                         break;
2470
2471                         /* check for invalid opcodes if the verifier is enabled */
2472 #if defined(ENABLE_VERIFIER)
2473                 case JAVA_BREAKPOINT:
2474                         exceptions_throw_verifyerror(m, "Quick instructions shouldn't appear yet.");
2475                         return false;
2476
2477                 case 186: /* unused opcode */
2478                 case 203:
2479                 case 204:
2480                 case 205:
2481                 case 206:
2482                 case 207:
2483                 case 208:
2484                 case 209:
2485                 case 210:
2486                 case 211:
2487                 case 212:
2488                 case 213:
2489                 case 214:
2490                 case 215:
2491                 case 216:
2492                 case 217:
2493                 case 218:
2494                 case 219:
2495                 case 220:
2496                 case 221:
2497                 case 222:
2498                 case 223:
2499                 case 224:
2500                 case 225:
2501                 case 226:
2502                 case 227:
2503                 case 228:
2504                 case 229:
2505                 case 230:
2506                 case 231:
2507                 case 232:
2508                 case 233:
2509                 case 234:
2510                 case 235:
2511                 case 236:
2512                 case 237:
2513                 case 238:
2514                 case 239:
2515                 case 240:
2516                 case 241:
2517                 case 242:
2518                 case 243:
2519                 case 244:
2520                 case 245:
2521                 case 246:
2522                 case 247:
2523                 case 248:
2524                 case 249:
2525                 case 250:
2526                 case 251:
2527                 case 252:
2528                 case 253:
2529                 case 254:
2530                 case 255:
2531                         exceptions_throw_verifyerror(m, "Illegal opcode %d at instr %d\n",
2532                                                                                  opcode, ipc);
2533                         return false;
2534                         break;
2535 #endif /* defined(ENABLE_VERIFIER) */
2536
2537                 default:
2538                         /* straight-forward translation to ICMD */
2539                         OP(opcode);
2540                         break;
2541                                 
2542                 } /* end switch */
2543
2544 #if defined(ENABLE_VERIFIER)
2545                 /* If WIDE was used correctly, iswide should have been reset by now. */
2546                 if (iswide) {
2547                         exceptions_throw_verifyerror(m,
2548                                         "Illegal instruction: WIDE before incompatible opcode");
2549                         return false;
2550                 }
2551 #endif /* defined(ENABLE_VERIFIER) */
2552
2553         } /* end for */
2554
2555 #if defined(ENABLE_VERIFIER)
2556         if (p != m->jcodelength) {
2557                 exceptions_throw_verifyerror(m,
2558                                 "Command-sequence crosses code-boundary");
2559                 return false;
2560         }
2561
2562         if (!blockend) {
2563                 exceptions_throw_verifyerror(m, "Falling off the end of the code");
2564                 return false;
2565         }
2566 #endif /* defined(ENABLE_VERIFIER) */
2567
2568         /* adjust block count if target 0 is not first intermediate instruction */
2569
2570         if (!m->basicblockindex[0] || (m->basicblockindex[0] > 1))
2571                 b_count++;
2572
2573         /* copy local to method variables */
2574
2575         m->instructioncount = ipc;
2576         m->basicblockcount = b_count;
2577         m->stackcount = s_count + m->basicblockcount * m->maxstack;
2578
2579         /* allocate stack table */
2580
2581         m->stack = DMNEW(stackelement, m->stackcount);
2582
2583         {
2584                 basicblock *bptr;
2585
2586                 bptr = m->basicblocks = DMNEW(basicblock, b_count + 1);    /* one more for end ipc */
2587
2588                 b_count = 0;
2589                 m->c_debug_nr = 0;
2590         
2591                 /* additional block if target 0 is not first intermediate instruction */
2592
2593                 if (!m->basicblockindex[0] || (m->basicblockindex[0] > 1)) {
2594                         BASICBLOCK_INIT(bptr,m);
2595
2596                         bptr->iinstr = m->instructions;
2597                         /* bptr->icount is set when the next block is allocated */
2598
2599                         bptr++;
2600                         b_count++;
2601                         bptr[-1].next = bptr;
2602                 }
2603
2604                 /* allocate blocks */
2605
2606                 for (p = 0; p < m->jcodelength; p++) { 
2607                         if (m->basicblockindex[p] & 1) {
2608                                 /* Check if this block starts at the beginning of an          */
2609                                 /* instruction.                                               */
2610 #if defined(ENABLE_VERIFIER)
2611                                 if (!instructionstart[p]) {
2612                                         exceptions_throw_verifyerror(m,
2613                                                 "Branch into middle of instruction");
2614                                         return false;
2615                                 }
2616 #endif
2617
2618                                 /* allocate the block */
2619
2620                                 BASICBLOCK_INIT(bptr,m);
2621
2622                                 bptr->iinstr = m->instructions + (m->basicblockindex[p] >> 1);
2623                                 if (b_count) {
2624                                         bptr[-1].icount = bptr->iinstr - bptr[-1].iinstr;
2625                                 }
2626                                 /* bptr->icount is set when the next block is allocated */
2627
2628                                 m->basicblockindex[p] = b_count;
2629
2630                                 bptr++;
2631                                 b_count++;
2632                                 bptr[-1].next = bptr;
2633                         }
2634                 }
2635
2636                 /* set instruction count of last real block */
2637
2638                 if (b_count) {
2639                         bptr[-1].icount = (m->instructions + m->instructioncount) - bptr[-1].iinstr;
2640                 }
2641
2642                 /* allocate additional block at end */
2643
2644                 BASICBLOCK_INIT(bptr,m);
2645                 
2646                 bptr->instack = bptr->outstack = NULL;
2647                 bptr->indepth = bptr->outdepth = 0;
2648                 bptr->iinstr = NULL;
2649                 bptr->icount = 0;
2650                 bptr->next = NULL;
2651
2652                 /* set basicblock pointers in exception table */
2653
2654                 if (cd->exceptiontablelength > 0) {
2655                         cd->exceptiontable[cd->exceptiontablelength - 1].down = NULL;
2656                 }
2657                 
2658                 for (i = 0; i < cd->exceptiontablelength; ++i) {
2659                         p = cd->exceptiontable[i].startpc;
2660                         cd->exceptiontable[i].start = m->basicblocks + m->basicblockindex[p];
2661
2662                         p = cd->exceptiontable[i].endpc;
2663                         cd->exceptiontable[i].end = (p == m->jcodelength) ? (m->basicblocks + m->basicblockcount /*+ 1*/) : (m->basicblocks + m->basicblockindex[p]);
2664
2665                         p = cd->exceptiontable[i].handlerpc;
2666                         cd->exceptiontable[i].handler = m->basicblocks + m->basicblockindex[p];
2667             }
2668
2669                 /* XXX activate this if you want to try inlining */
2670 #if 0
2671                 for (i = 0; i < m->exceptiontablelength; ++i) {
2672                         p = m->exceptiontable[i].startpc;
2673                         m->exceptiontable[i].start = m->basicblocks + m->basicblockindex[p];
2674
2675                         p = m->exceptiontable[i].endpc;
2676                         m->exceptiontable[i].end = (p == m->jcodelength) ? (m->basicblocks + m->basicblockcount /*+ 1*/) : (m->basicblocks + m->basicblockindex[p]);
2677
2678                         p = m->exceptiontable[i].handlerpc;
2679                         m->exceptiontable[i].handler = m->basicblocks + m->basicblockindex[p];
2680             }
2681 #endif
2682
2683         }
2684
2685         /* everything's ok */
2686
2687         return true;
2688
2689 #if defined(ENABLE_VERIFIER)
2690
2691 throw_unexpected_end_of_bytecode:
2692         exceptions_throw_verifyerror(m, "Unexpected end of bytecode");
2693         return false;
2694
2695 throw_invalid_bytecode_index:
2696         exceptions_throw_verifyerror(m, "Illegal target of branch instruction");
2697         return false;
2698
2699 throw_illegal_local_variable_number:
2700         exceptions_throw_verifyerror(m, "Illegal local variable number");
2701         return false;
2702                 
2703 #endif /* ENABLE_VERIFIER */
2704 }
2705
2706
2707 /*
2708  * These are local overrides for various environment variables in Emacs.
2709  * Please do not remove this and leave it at the end of the file, where
2710  * Emacs will automagically detect them.
2711  * ---------------------------------------------------------------------
2712  * Local variables:
2713  * mode: c
2714  * indent-tabs-mode: t
2715  * c-basic-offset: 4
2716  * tab-width: 4
2717  * End:
2718  * vim:noexpandtab:sw=4:ts=4:
2719  */