1 /* jit/parse.c - parser for JavaVM to intermediate code translation
3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4 R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
5 M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
6 P. Tomsich, J. Wenninger
8 This file is part of CACAO.
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.
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.
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., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
29 Changes: Carolyn Oates
32 $Id: parse.c 1038 2004-04-26 16:41:30Z twisti $
44 #include "loop/loop.h"
50 #include "toolbox/memory.h"
51 #include "toolbox/loging.h"
54 /* data about the currently parsed method */
56 classinfo *rt_class; /* class the compiled method belongs to */
57 methodinfo *rt_method; /* pointer to method info of compiled method */
58 utf *rt_descriptor; /* type descriptor of compiled method */
59 int rt_jcodelength; /* length of JavaVM-codes */
60 u1 *rt_jcode; /* pointer to start of JavaVM-code */
66 /*#define debug_writebranch printf("op: %s i: %d label_index[i]: %d\n",icmd_names[opcode], i, label_index[i]);*/
67 #define debug_writebranch
70 /* function descriptor2typesL ***************************************************
72 decodes a already checked method descriptor. The parameter count, the
73 return type and the argument types are stored in the passed methodinfo.
74 gets and saves classptr for object ref.s
76 *******************************************************************************/
78 classSetNode *descriptor2typesL(methodinfo *m)
85 classinfo** classtypes;
90 printf("In descriptor2typesL >>>\t"); fflush(stdout);
91 utf_display(m->class->name); printf(".");
92 method_display(m);fflush(stdout);
96 desc = MNEW (char, 256);
97 types = DMNEW (u1, m->descriptor->blength);
98 classtypes = MNEW (classinfo*, m->descriptor->blength+1);
99 m->returnclass = NULL;
101 if (!(m->flags & ACC_STATIC)) {
103 if (debugInfo >= 1) {
104 printf("param #0 (this?) method class =");utf_display(m->class->name);printf("\n");
106 classtypes[pcount] = m->class;
107 p = addClassCone(p, m->class);
111 utf_ptr = m->descriptor->text + 1;
112 strcpy (desc,utf_ptr);
114 while ((c = *desc++) != ')') {
121 case 'Z': *tptr++ = TYPE_INT;
123 case 'J': *tptr++ = TYPE_LNG;
125 case 'F': *tptr++ = TYPE_FLT;
127 case 'D': *tptr++ = TYPE_DBL;
129 case 'L': *tptr++ = TYPE_ADR;
130 /* get class string */
131 class = strtok(desc,";");
132 desc = strtok(NULL,"\0");
133 /* get/save classinfo ptr */
134 classtypes[pcount-1] = class_get(utf_new_char(class));
135 p = addClassCone(p, class_get(utf_new_char(class)));
136 if (debugInfo >= 1) {
137 printf("LParam#%i 's class type is: %s\n",pcount-1,class);fflush(stdout);
138 printf("Lclasstypes[%i]=",pcount-1);fflush(stdout);
139 utf_display(classtypes[pcount-1]->name);
142 case '[': *tptr++ = TYPE_ADR;
145 /* get class string */
147 class = strtok(desc,";");
148 desc = strtok(NULL,"\0");
149 /* get/save classinfo ptr */
150 classtypes[pcount-1] = class_get(utf_new_char(class));
151 p= addClassCone(p, class_get(utf_new_char(class)));
152 if (debugInfo >= 1) {
153 printf("[Param#%i 's class type is: %s\n",pcount-1,class);
154 printf("[classtypes[%i]=",pcount-1);fflush(stdout);
155 utf_display(classtypes[pcount-1]->name);
160 classtypes[pcount-1] = NULL;
163 panic("Ill formed methodtype-descriptor");
167 /* compute return type */
173 case 'Z': m->returntype = TYPE_INT;
175 case 'J': m->returntype = TYPE_LNG;
177 case 'F': m->returntype = TYPE_FLT;
179 case 'D': m->returntype = TYPE_DBL;
182 m->returntype = TYPE_ADR;
190 m->returntype = TYPE_ADR;
192 /* get class string */
193 class = strtok(desc,";");
194 m->returnclass = class_get(utf_new_char(class));
195 if (m->returnclass == NULL) {
196 printf("class=%s :\t",class);
197 panic ("return class not found");
200 case 'V': m->returntype = TYPE_VOID;
203 default: panic("Ill formed methodtype-descriptor-ReturnType");
206 m->paramcount = pcount;
207 m->paramtypes = types;
208 m->paramclass = classtypes;
212 for (i=0; i< m->paramcount; i++) {
213 if ((m->paramtypes[i] == TYPE_ADR) && (m->paramclass[i] != NULL)) {
214 printf("Param #%i is:\t",i);
215 utf_display(m->paramclass[i]->name);
220 if ((m->returntype == TYPE_ADR) && (m->returnclass != NULL)) {
221 printf("\tReturn Type is:\t"); fflush(stdout);
222 utf_display(m->returnclass->name);
226 printf("params2types: START results in a set \n");
227 printf("param2types: A Set size=%i=\n",sizeOfSet(p));
236 /* function descriptor2types ***************************************************
238 decodes a already checked method descriptor. The parameter count, the
239 return type and the argument types are stored in the passed methodinfo.
241 *******************************************************************************/
243 void descriptor2types(methodinfo *m)
249 types = DMNEW(u1, m->descriptor->blength);
252 if (!(m->flags & ACC_STATIC)) {
257 utf_ptr = m->descriptor->text + 1;
259 while ((c = *utf_ptr++) != ')') {
266 case 'Z': *tptr++ = TYPE_INT;
268 case 'J': *tptr++ = TYPE_LNG;
270 case 'F': *tptr++ = TYPE_FLT;
272 case 'D': *tptr++ = TYPE_DBL;
274 case 'L': *tptr++ = TYPE_ADR;
275 while (*utf_ptr++ != ';');
277 case '[': *tptr++ = TYPE_ADR;
281 while (*utf_ptr++ != ';') /* skip */;
283 default: panic ("Ill formed methodtype-descriptor");
287 /* compute return type */
289 switch (*utf_ptr++) {
294 case 'Z': m->returntype = TYPE_INT;
296 case 'J': m->returntype = TYPE_LNG;
298 case 'F': m->returntype = TYPE_FLT;
300 case 'D': m->returntype = TYPE_DBL;
303 case 'L': m->returntype = TYPE_ADR;
305 case 'V': m->returntype = TYPE_VOID;
308 default: panic ("Ill formed methodtype-descriptor");
311 m->paramcount = pcount;
312 m->paramtypes = types;
317 /*******************************************************************************
319 function 'parse' scans the JavaVM code and generates intermediate code
321 During parsing the block index table is used to store at bit pos 0
322 a flag which marks basic block starts and at position 1 to 31 the
323 intermediate instruction index. After parsing the block index table
324 is scanned, for marked positions a block is generated and the block
325 number is stored in the block index table.
327 *******************************************************************************/
329 static xtable* fillextable(xtable* extable, exceptiontable *raw_extable, int exceptiontablelength, int *label_index, int *block_count)
333 if (exceptiontablelength == 0)
336 b_count = *block_count;
338 for (i = 0; i < exceptiontablelength; i++) {
339 p = raw_extable[i].startpc;
340 if (label_index != NULL) p = label_index[p];
341 extable[i].startpc = p;
345 p = raw_extable[i].endpc;
346 if (p <= raw_extable[i].startpc)
347 panic("Invalid exception handler range");
348 if (label_index != NULL) p = label_index[p];
349 extable[i].endpc = p;
351 if (p < cumjcodelength)
354 p = raw_extable[i].handlerpc;
355 if (label_index != NULL) p = label_index[p];
356 extable[i].handlerpc = p;
360 extable[i].catchtype = raw_extable[i].catchtype;
363 if (extable[i].catchtype) {
364 utf_display_classname(extable[i].catchtype->name);
366 /* is this catch class loaded */
367 if (!extable[i].catchtype->loaded)
368 class_load(extable[i].catchtype);
370 /* is this catch class linked */
371 if (!extable[i].catchtype->linked)
372 class_link(extable[i].catchtype);
376 extable[i].next = NULL;
377 extable[i].down = &extable[i + 1];
380 *block_count = b_count;
381 return &extable[i]; /* return the next free xtable* */
388 int p; /* java instruction counter */
389 int nextp; /* start of next java instruction */
390 int opcode; /* java opcode */
391 int i; /* temporary for different uses (counters) */
392 int ipc = 0; /* intermediate instruction counter */
393 int b_count = 0; /* basic block counter */
394 int s_count = 0; /* stack element counter */
395 bool blockend = false; /* true if basic block end has been reached */
396 bool iswide = false; /* true if last instruction was a wide */
397 instruction *iptr; /* current pointer into instruction array */
398 int gp; /* global java instruction counter */
399 /* inlining info for current method */
400 inlining_methodinfo *inlinfo = inlining_rootinfo;
401 inlining_methodinfo *tmpinlinf;
402 int nextgp = -1; /* start of next method to be inlined */
403 int *label_index = NULL; /* label redirection table */
404 int firstlocal = 0; /* first local variable of method */
405 xtable* nextex; /* points next free entry in extable */
406 u1 *instructionstart; /* 1 for pcs which are valid instr. starts */
414 if (compileverbose) {
415 char logtext[MAXLOGTEXT];
416 sprintf(logtext, "Parsing: ");
417 utf_sprint_classname(logtext+strlen(logtext), method->class->name);
418 strcpy(logtext+strlen(logtext), ".");
419 utf_sprint(logtext+strlen(logtext), method->name);
420 utf_sprint_classname(logtext+strlen(logtext), method->descriptor);
426 label_index = inlinfo->label_index;
427 maxstack = cummaxstack;
428 exceptiontablelength = cumextablelength;
431 useinltmp = useinlining; /* FIXME remove this after debugging */
432 /*useinlining = false;*/ /* and merge the if-statements */
435 cumjcodelength = jcodelength;
438 tmpinlinf = (inlining_methodinfo*) list_first(inlinfo->inlinedmethods);
439 if (tmpinlinf != NULL) nextgp = tmpinlinf->startgp;
442 if ((opt_rt || opt_xta || opt_vta) && (pOpcodes == 2 || pOpcodes == 3)) {
443 printf("PARSE method name =");
444 utf_display(method->class->name);
446 method_display(method);
451 if (opt_rt || opt_xta) {
452 RT_jit_parse(method);
456 printf("VTA requested, but not yet implemented\n");
460 /* allocate instruction array and block index table */
462 /* 1 additional for end ipc and 3 for loop unrolling */
464 block_index = DMNEW(int, cumjcodelength + 4);
465 instructionstart = DMNEW(u1, cumjcodelength + 4);
466 memset(instructionstart,0,sizeof(u1) * (cumjcodelength + 4));
468 /* 1 additional for TRACEBUILTIN and 4 for MONITORENTER/EXIT */
469 /* additional MONITOREXITS are reached by branches which are 3 bytes */
471 iptr = instr = DMNEW(instruction, cumjcodelength + 5);
473 /* Zero the intermediate instructions array so we don't have any
474 * invalid pointers in it if we cannot finish analyse_stack(). */
475 memset(iptr,0,sizeof(instruction) * (cumjcodelength + 5));
477 /* initialize block_index table (unrolled four times) */
482 for (i = 0, ip = block_index; i <= cumjcodelength; i += 4, ip += 4) {
490 /* compute branch targets of exception table */
492 extable = DMNEW(xtable, exceptiontablelength + 1);
494 for (i = 0; i < method->exceptiontablelength; i++) {
496 p = extable[i].startpc = raw_extable[i].startpc;
497 if (useinlining) p = label_index[p];
501 p = extable[i].endpc = raw_extable[i].endpc;
502 if (useinlining) p = label_index[p];
504 if (p < cumjcodelength)
507 p = extable[i].handlerpc = raw_extable[i].handlerpc;
511 extable[i].catchtype = raw_extable[i].catchtype;
513 extable[i].next = NULL;
514 extable[i].down = &extable[i+1];
518 nextex = fillextable(extable, raw_extable, method->exceptiontablelength, label_index, &b_count);
520 s_count = 1 + exceptiontablelength; /* initialize stack element counter */
523 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
524 isleafmethod = false;
528 /* scan all java instructions */
531 if (jlinenumbercount==0) {
534 linepcchange=jlinenumbers[0].start_pc;
537 for (p = 0, gp = 0; p < jcodelength; gp += (nextp - p), p = nextp) {
539 /* DEBUG */ /*printf("p:%d gp:%d ",p,gp);*/
541 /* mark this position as a valid instruction start */
543 instructionstart[gp] = 1;
544 /*log_text("new start of instruction");*/
545 if (linepcchange==p) {
546 if (jlinenumbercount>lineindex) {
547 currentline=jlinenumbers[lineindex].line_number;
549 if (lineindex<jlinenumbercount)
550 linepcchange=jlinenumbers[lineindex].start_pc;
551 /*printf("Line number changed to: %ld\n",currentline);*/
557 if ((useinlining) && (gp == nextgp)) {
559 bool *readonly = NULL;
562 opcode = code_get_u1(p);
563 nextp = p += jcommandsize[opcode];
564 if (nextp > jcodelength)
565 panic("Unexpected end of bytecode");
566 tmpinlinf = list_first(inlinfo->inlinedmethods);
567 firstlocal = tmpinlinf->firstlocal;
568 label_index = tmpinlinf->label_index;
569 readonly = tmpinlinf->readonly;
571 for (i = 0, tptr = tmpinlinf->method->paramtypes + tmpinlinf->method->paramcount - 1; i < tmpinlinf->method->paramcount; i++, tptr--) {
574 if ((i == 0) && inlineparamopt) {
575 OP1(ICMD_CLEAR_ARGREN, firstlocal);
578 if (!inlineparamopt || !readonly[i]) {
582 op = ICMD_READONLY_ARG;
586 OP1(op, firstlocal + tmpinlinf->method->paramcount - 1 - i);
588 /* block_index[gp] |= (ipc << 1);*/ /*FIXME: necessary ? */
591 inlining_save_compiler_variables();
592 inlining_set_compiler_variables(tmpinlinf);
593 if (compileverbose) {
594 char logtext[MAXLOGTEXT];
595 sprintf(logtext, "Parsing (inlined): ");
596 utf_sprint(logtext+strlen(logtext), method->class->name);
597 strcpy(logtext+strlen(logtext), ".");
598 utf_sprint(logtext+strlen(logtext), method->name);
599 utf_sprint(logtext+strlen(logtext), method->descriptor);
604 if (inlinfo->inlinedmethods == NULL) {
607 tmpinlinf = list_first(inlinfo->inlinedmethods);
608 nextgp = (tmpinlinf != NULL) ? tmpinlinf->startgp : -1;
610 if (method->exceptiontablelength > 0)
611 nextex = fillextable(nextex, method->exceptiontable, method->exceptiontablelength, label_index, &b_count);
615 opcode = code_get_u1(p); /* fetch op code */
618 if (opt_rt && (pOpcodes == 2 || pOpcodes == 3)) {
619 printf("Parse<%i> p=%i<%i< opcode=<%i> %s\n",
620 pOpcodes, p, rt_jcodelength, opcode, icmd_names[opcode]);
623 block_index[gp] |= (ipc << 1); /* store intermediate count */
626 block_insert(gp); /* start new block */
630 nextp = p + jcommandsize[opcode]; /* compute next instruction start */
631 if (nextp > jcodelength)
632 panic("Unexpected end of bytecode");
633 s_count += stackreq[opcode]; /* compute stack element count */
639 /* pushing constants onto the stack p */
642 LOADCONST_I(code_get_s1(p+1));
646 LOADCONST_I(code_get_s2(p+1));
650 i = code_get_u1(p+1);
651 goto pushconstantitem;
654 i = code_get_u2(p + 1);
658 if (i >= class->cpcount)
659 panic ("Attempt to access constant outside range");
661 switch (class->cptags[i]) {
662 case CONSTANT_Integer:
663 LOADCONST_I(((constant_integer*)
664 (class->cpinfos[i]))->value);
667 LOADCONST_L(((constant_long*)
668 (class->cpinfos[i]))->value);
671 LOADCONST_F(((constant_float*)
672 (class->cpinfos[i]))->value);
674 case CONSTANT_Double:
675 LOADCONST_D(((constant_double*)
676 (class->cpinfos[i]))->value);
678 case CONSTANT_String:
679 LOADCONST_A(literalstring_new((utf*)
680 (class->cpinfos[i])));
682 default: panic("Invalid constant type to push");
686 case JAVA_ACONST_NULL:
697 LOADCONST_I(opcode - JAVA_ICONST_0);
702 LOADCONST_L(opcode - JAVA_LCONST_0);
708 LOADCONST_F(opcode - JAVA_FCONST_0);
713 LOADCONST_D(opcode - JAVA_DCONST_0);
716 /* loading variables onto the stack */
724 i = code_get_u1(p + 1);
726 i = code_get_u2(p + 1);
730 OP1LOAD(opcode, i + firstlocal);
737 OP1LOAD(ICMD_ILOAD, opcode - JAVA_ILOAD_0 + firstlocal);
744 OP1LOAD(ICMD_LLOAD, opcode - JAVA_LLOAD_0 + firstlocal);
751 OP1LOAD(ICMD_FLOAD, opcode - JAVA_FLOAD_0 + firstlocal);
758 OP1LOAD(ICMD_DLOAD, opcode - JAVA_DLOAD_0 + firstlocal);
765 OP1LOAD(ICMD_ALOAD, opcode - JAVA_ALOAD_0 + firstlocal);
768 /* storing stack values into local variables */
776 i = code_get_u1(p + 1);
778 i = code_get_u2(p + 1);
782 OP1STORE(opcode, i + firstlocal);
789 OP1STORE(ICMD_ISTORE, opcode - JAVA_ISTORE_0 + firstlocal);
796 OP1STORE(ICMD_LSTORE, opcode - JAVA_LSTORE_0 + firstlocal);
803 OP1STORE(ICMD_FSTORE, opcode - JAVA_FSTORE_0 + firstlocal);
810 OP1STORE(ICMD_DSTORE, opcode - JAVA_DSTORE_0 + firstlocal);
817 OP1STORE(ICMD_ASTORE, opcode - JAVA_ASTORE_0 + firstlocal);
825 i = code_get_u1(p + 1);
826 v = code_get_s1(p + 2);
829 i = code_get_u2(p + 1);
830 v = code_get_s2(p + 3);
834 INDEX_ONEWORD(i + firstlocal);
835 OP2I(opcode, i + firstlocal, v);
839 /* wider index for loading, storing and incrementing */
846 /* managing arrays ************************************************/
849 OP2I(ICMD_CHECKASIZE, 0, 0);
850 switch (code_get_s1(p + 1)) {
852 BUILTIN1(BUILTIN_newarray_boolean, TYPE_ADR,currentline);
855 BUILTIN1(BUILTIN_newarray_char, TYPE_ADR,currentline);
858 BUILTIN1(BUILTIN_newarray_float, TYPE_ADR,currentline);
861 BUILTIN1(BUILTIN_newarray_double, TYPE_ADR,currentline);
864 BUILTIN1(BUILTIN_newarray_byte, TYPE_ADR,currentline);
867 BUILTIN1(BUILTIN_newarray_short, TYPE_ADR,currentline);
870 BUILTIN1(BUILTIN_newarray_int, TYPE_ADR,currentline);
873 BUILTIN1(BUILTIN_newarray_long, TYPE_ADR,currentline);
875 default: panic("Invalid array-type to create");
877 OP2I(ICMD_CHECKOOM, 0, 0);
881 OP2I(ICMD_CHECKASIZE, 0, 0);
882 i = code_get_u2(p + 1);
884 classinfo *component =
885 (classinfo *) class_getconstant(class, i, CONSTANT_Class);
887 class_load(component);
888 class_link(component);
890 LOADCONST_A_BUILTIN(class_array_of(component)->vftbl);
891 /* LOADCONST_A_BUILTIN(component); */
893 BUILTIN2(BUILTIN_newarray, TYPE_ADR,currentline);
895 OP2I(ICMD_CHECKOOM, 0, 0);
898 case JAVA_MULTIANEWARRAY:
899 isleafmethod = false;
900 i = code_get_u2(p + 1);
902 s4 v = code_get_u1(p + 3);
905 /* vftbl *arrayvftbl = */
906 /* ((classinfo *) class_getconstant(class, i, CONSTANT_Class))->vftbl; */
907 /* OP2A(opcode, v, arrayvftbl,currentline); */
910 classinfo *component =
911 (classinfo *) class_getconstant(class, i, CONSTANT_Class);
913 class_load(component);
914 class_link(component);
916 vftbl *arrayvftbl = component->vftbl;
917 OP2A(opcode, v, arrayvftbl,currentline);
919 /* classinfo *arrayclass = */
920 /* (classinfo *) class_getconstant(class, i, CONSTANT_Class); */
921 /* OP2A(opcode, v, arrayclass, currentline); */
943 i = p + code_get_s2(p + 1);
955 i = p + code_get_s4(p + 1);
968 i = code_get_u1(p + 1);
970 i = code_get_u2(p + 1);
977 if (isinlinedmethod) {
978 OP1(ICMD_GOTO, inlinfo->stopgp);
982 OP1LOAD(opcode, i + firstlocal);
991 if (isinlinedmethod) {
992 /* if (p==jcodelength-1) {*/ /* return is at end of inlined method */
997 OP1(ICMD_GOTO, inlinfo->stopgp);
1011 /* table jumps ********************************/
1013 case JAVA_LOOKUPSWITCH:
1020 nextp = ALIGN((p + 1), 4);
1021 if (nextp + 8 > jcodelength)
1022 panic("Unexpected end of bytecode");
1024 tablep = (s4*)(jcode + nextp);
1027 num = code_get_u4(nextp + 4);
1028 tablep = DMNEW(s4, num * 2 + 2);
1031 OP2A(opcode, 0, tablep,currentline);
1033 /* default target */
1035 j = p + code_get_s4(nextp);
1038 *tablep = j; /* restore for little endian */
1044 /* number of pairs */
1046 num = code_get_u4(nextp);
1051 if (nextp + 8*(num) > jcodelength)
1052 panic("Unexpected end of bytecode");
1054 for (i = 0; i < num; i++) {
1057 j = code_get_s4(nextp);
1058 *tablep = j; /* restore for little endian */
1062 /* check if the lookup table is sorted correctly */
1064 if (i && (j <= prevvalue))
1065 panic("invalid LOOKUPSWITCH: table not sorted");
1070 j = p + code_get_s4(nextp);
1073 *tablep = j; /* restore for little endian */
1084 case JAVA_TABLESWITCH:
1090 nextp = ALIGN((p + 1), 4);
1091 if (nextp + 12 > jcodelength)
1092 panic("Unexpected end of bytecode");
1094 tablep = (s4*)(jcode + nextp);
1097 num = code_get_u4(nextp + 8) - code_get_u4(nextp + 4);
1098 tablep = DMNEW(s4, num + 1 + 3);
1101 OP2A(opcode, 0, tablep,currentline);
1103 /* default target */
1105 j = p + code_get_s4(nextp);
1108 *tablep = j; /* restore for little endian */
1116 j = code_get_s4(nextp);
1117 *tablep = j; /* restore for little endian */
1123 num = code_get_s4(nextp);
1124 *tablep = num; /* restore for little endian */
1128 num -= j; /* difference of upper - lower */
1130 panic("invalid TABLESWITCH: upper bound < lower bound");
1132 if (nextp + 4*(num+1) > jcodelength)
1133 panic("Unexpected end of bytecode");
1135 for (i = 0; i <= num; i++) {
1136 j = p + code_get_s4(nextp);
1139 *tablep = j; /* restore for little endian */
1150 /* load and store of object fields *******************/
1153 BUILTIN3(BUILTIN_aastore, TYPE_VOID,currentline);
1156 case JAVA_PUTSTATIC:
1157 case JAVA_GETSTATIC:
1158 i = code_get_u2(p + 1);
1160 constant_FMIref *fr;
1163 fr = class_getconstant(class, i, CONSTANT_Fieldref);
1165 class_load(fr->class);
1166 class_link(fr->class);
1168 fi = class_resolvefield(fr->class, fr->name, fr->descriptor, class, true);
1170 panic("Exception thrown while parsing bytecode"); /* XXX should be passed on */
1171 OP2A(opcode, fi->type, fi,currentline);
1172 if (!fi->class->initialized) {
1173 isleafmethod = false;
1180 i = code_get_u2(p + 1);
1182 constant_FMIref *fr;
1185 fr = class_getconstant (class, i, CONSTANT_Fieldref);
1187 class_load(fr->class);
1188 class_link(fr->class);
1190 fi = class_resolvefield(fr->class, fr->name, fr->descriptor, class, true);
1192 panic("Exception thrown while parsing bytecode"); /* XXX should be passed on */
1193 OP2A(opcode, fi->type, fi,currentline);
1198 /* method invocation *****/
1200 case JAVA_INVOKESTATIC:
1201 i = code_get_u2(p + 1);
1203 constant_FMIref *mr;
1206 mr = class_getconstant(class, i, CONSTANT_Methodref);
1208 class_load(mr->class);
1209 class_link(mr->class);
1211 mi = class_resolveclassmethod(mr->class, mr->name, mr->descriptor, class, true);
1213 panic("Exception thrown while parsing bytecode"); /* XXX should be passed on */
1214 /*RTAprint*/ if (((pOpcodes == 2) || (pOpcodes == 3)) && opt_rt)
1215 /*RTAprint*/ {printf(" method name =");
1216 /*RTAprint*/ utf_display(mi->class->name); printf(".");
1217 /*RTAprint*/ utf_display(mi->name);printf("\tINVOKE STATIC\n");
1218 /*RTAprint*/ fflush(stdout);}
1219 if (!(mi->flags & ACC_STATIC))
1220 panic ("Static/Nonstatic mismatch calling static method");
1221 descriptor2types(mi);
1224 OP2A(opcode, mi->paramcount, mi,currentline);
1228 case JAVA_INVOKESPECIAL:
1229 case JAVA_INVOKEVIRTUAL:
1230 i = code_get_u2(p + 1);
1232 constant_FMIref *mr;
1235 mr = class_getconstant(class, i, CONSTANT_Methodref);
1237 class_load(mr->class);
1238 class_link(mr->class);
1240 mi = class_resolveclassmethod(mr->class, mr->name, mr->descriptor, class, true);
1242 panic("Exception thrown while parsing bytecode");
1244 /*RTAprint*/ if (((pOpcodes == 2) || (pOpcodes == 3)) && opt_rt)
1245 /*RTAprint*/ {printf(" method name =");
1247 /*RTAprint*/ utf_display(mi->class->name); printf(".");
1248 /*RTAprint*/ utf_display(mi->name);printf("\tINVOKE SPECIAL/VIRTUAL\n");
1249 /*RTAprint*/ fflush(stdout);}
1251 if (mi->flags & ACC_STATIC)
1252 panic ("Static/Nonstatic mismatch calling static method");
1253 descriptor2types(mi);
1255 OP2A(opcode, mi->paramcount, mi,currentline);
1259 case JAVA_INVOKEINTERFACE:
1260 i = code_get_u2(p + 1);
1262 constant_FMIref *mr;
1265 mr = class_getconstant(class, i, CONSTANT_InterfaceMethodref);
1267 class_load(mr->class);
1268 class_link(mr->class);
1270 mi = class_resolveinterfacemethod(mr->class, mr->name, mr->descriptor, class, true);
1272 panic("Exception thrown while parsing bytecode"); /* XXX should be passed on */
1273 if (mi->flags & ACC_STATIC)
1274 panic ("Static/Nonstatic mismatch calling static method");
1275 descriptor2types(mi);
1277 OP2A(opcode, mi->paramcount, mi,currentline);
1281 /* miscellaneous object operations *******/
1284 i = code_get_u2 (p+1);
1286 LOADCONST_A_BUILTIN(class_getconstant(class, i, CONSTANT_Class));
1288 BUILTIN1(BUILTIN_new, TYPE_ADR,currentline);
1289 OP2I(ICMD_CHECKOOM, 0, 0);
1292 case JAVA_CHECKCAST:
1293 i = code_get_u2(p+1);
1296 (classinfo *) class_getconstant(class, i, CONSTANT_Class);
1298 /* is the class loaded */
1302 /* is the class linked */
1306 if (cls->vftbl->arraydesc) {
1307 /* array type cast-check */
1308 LOADCONST_A_BUILTIN(cls->vftbl);
1310 BUILTIN2(BUILTIN_checkarraycast, TYPE_ADR,currentline);
1312 else { /* object type cast-check */
1314 + LOADCONST_A_BUILTIN(class_getconstant(class, i, CONSTANT_Class));
1316 + BUILTIN2(BUILTIN_checkcast, TYPE_ADR,currentline);
1318 OP2A(opcode, 1, cls,currentline);
1324 case JAVA_INSTANCEOF:
1325 i = code_get_u2(p+1);
1329 (classinfo *) class_getconstant(class, i, CONSTANT_Class);
1331 /* is the class loaded */
1335 /* is the class linked */
1339 if (cls->vftbl->arraydesc) {
1340 /* array type cast-check */
1341 LOADCONST_A_BUILTIN(cls->vftbl);
1343 BUILTIN2(BUILTIN_arrayinstanceof, TYPE_INT,currentline);
1345 else { /* object type cast-check */
1347 LOADCONST_A_BUILTIN(class_getconstant(class, i, CONSTANT_Class));
1349 BUILTIN2(BUILTIN_instanceof, TYPE_INT,currentline);
1351 OP2A(opcode, 1, cls,currentline);
1356 case JAVA_MONITORENTER:
1359 BUILTIN1(BUILTIN_monitorenter, TYPE_VOID,currentline);
1363 OP(ICMD_NULLCHECKPOP);
1367 case JAVA_MONITOREXIT:
1370 BUILTIN1(BUILTIN_monitorexit, TYPE_VOID,currentline);
1379 /* any other basic operation **************************************/
1398 #if defined(__I386__)
1401 BUILTIN2(BUILTIN_frem, TYPE_FLOAT,currentline);
1406 #if defined(__I386__)
1409 BUILTIN2(BUILTIN_drem, TYPE_DOUBLE,currentline);
1414 #if defined(__ALPHA__)
1416 BUILTIN1(BUILTIN_f2i, TYPE_INT,currentline);
1425 #if defined(__ALPHA__)
1427 BUILTIN1(BUILTIN_f2l, TYPE_LONG,currentline);
1436 #if defined(__ALPHA__)
1438 BUILTIN1(BUILTIN_d2i, TYPE_INT,currentline);
1447 #if defined(__ALPHA__)
1449 BUILTIN1(BUILTIN_d2l, TYPE_LONG,currentline);
1457 case JAVA_BREAKPOINT:
1458 panic("Illegal opcode Breakpoint encountered");
1461 case 186: /* unused opcode */
1515 printf("Illegal opcode %d at instr %d\n", opcode, ipc);
1516 panic("Illegal opcode encountered");
1525 /* If WIDE was used correctly, iswide should have been reset by now. */
1526 if (iswide && opcode != JAVA_WIDE)
1527 panic("Illegal instruction: WIDE before incompatible opcode");
1531 if (isinlinedmethod && p == jcodelength - 1) { /* end of an inlined method */
1532 /* printf("setting gp from %d to %d\n",gp, inlinfo->stopgp); */
1533 gp = inlinfo->stopgp;
1534 inlining_restore_compiler_variables();
1535 list_remove(inlinfo->inlinedmethods, list_first(inlinfo->inlinedmethods));
1536 if (inlinfo->inlinedmethods == NULL) {
1539 tmpinlinf = list_first(inlinfo->inlinedmethods);
1540 nextgp = (tmpinlinf != NULL) ? tmpinlinf->startgp : -1;
1542 /* printf("nextpgp: %d\n", nextgp); */
1543 label_index=inlinfo->label_index;
1544 firstlocal = inlinfo->firstlocal;
1548 if (p != jcodelength)
1549 panic("Command-sequence crosses code-boundary");
1552 panic("Code does not end with branch/return/athrow - stmt");
1554 /* adjust block count if target 0 is not first intermediate instruction */
1556 if (!block_index[0] || (block_index[0] > 1))
1559 /* copy local to global variables */
1562 block_count = b_count;
1563 stack_count = s_count + block_count * maxstack;
1565 /* allocate stack table */
1567 stack = DMNEW(stackelement, stack_count);
1572 bptr = block = DMNEW(basicblock, b_count + 1); /* one more for end ipc */
1577 /* additional block if target 0 is not first intermediate instruction */
1579 if (!block_index[0] || (block_index[0] > 1)) {
1580 bptr->iinstr = instr;
1583 bptr->type = BBTYPE_STD;
1584 bptr->branchrefs = NULL;
1585 bptr->pre_count = 0;
1586 bptr->debug_nr = c_debug_nr++;
1589 (bptr - 1)->next = bptr;
1592 /* allocate blocks */
1594 for (p = 0; p < cumjcodelength; p++) {
1595 if (block_index[p] & 1) {
1596 /* check if this block starts at the beginning of an instruction */
1597 if (!instructionstart[p])
1598 panic("Branch into middle of instruction");
1599 /* allocate the block */
1600 bptr->iinstr = instr + (block_index[p] >> 1);
1601 bptr->debug_nr = c_debug_nr++;
1603 (bptr - 1)->icount = bptr->iinstr - (bptr - 1)->iinstr;
1607 bptr->type = BBTYPE_STD;
1608 bptr->branchrefs = NULL;
1609 block_index[p] = b_count;
1610 bptr->pre_count = 0;
1613 (bptr - 1)->next = bptr;
1617 /* allocate additional block at end */
1619 bptr->instack = bptr->outstack = NULL;
1620 bptr->indepth = bptr->outdepth = 0;
1621 bptr->iinstr = NULL;
1622 (bptr - 1)->icount = (instr + instr_count) - (bptr - 1)->iinstr;
1627 bptr->type = BBTYPE_STD;
1628 bptr->branchrefs = NULL;
1629 bptr->pre_count = 0;
1630 bptr->debug_nr = c_debug_nr++;
1631 (bptr - 1)->next = bptr;
1636 if (exceptiontablelength > 0)
1637 extable[exceptiontablelength - 1].down = NULL;
1641 for (i = 0; i < exceptiontablelength; ++i) {
1642 p = extable[i].startpc;
1643 extable[i].start = block + block_index[p];
1645 p = extable[i].endpc;
1646 extable[i].end = (p == cumjcodelength) ? last_block : (block + block_index[p]);
1648 p = extable[i].handlerpc;
1649 extable[i].handler = block + block_index[p];
1653 if (useinlining) inlining_cleanup();
1654 useinlining = useinltmp;
1656 if (compileverbose) {
1657 char logtext[MAXLOGTEXT];
1658 sprintf(logtext, "Parsing done: ");
1659 utf_sprint_classname(logtext + strlen(logtext), method->class->name);
1660 strcpy(logtext + strlen(logtext), ".");
1661 utf_sprint(logtext + strlen(logtext), method->name);
1662 utf_sprint_classname(logtext + strlen(logtext), method->descriptor);
1669 * These are local overrides for various environment variables in Emacs.
1670 * Please do not remove this and leave it at the end of the file, where
1671 * Emacs will automagically detect them.
1672 * ---------------------------------------------------------------------
1675 * indent-tabs-mode: t