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