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