1 /* src/vm/jit/verify/typecheck.c - typechecking (part of bytecode verification)
3 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6 Institut f. Computersprachen - TU Wien
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
27 Authors: Edwin Steiner
29 Changes: Christian Thalinger
31 $Id: typecheck.c 3629 2005-11-08 01:40:34Z edwin $
37 What's the purpose of the `typechecker`?
38 ----------------------------------------
40 The typechecker analyses (the intermediate repr. of) the bytecode of
41 each method and ensures that for each instruction the values on the
42 stack and in local variables are of the correct type whenever the
43 instruction is executed.
45 type checking is a mandatory part of bytecode verification.
48 How does the typechecker work?
49 ------------------------------
51 The JVM stack and the local variables are not statically typed, so the
52 typechecker has to *infer* the static types of stack slots and local
53 variables at each point of the method. The JVM spec imposes a lot of
54 restrictions on the bytecode in order to guarantee that this is always
57 Basically the typechecker solves the data flow equations of the method.
58 This is done in the usual way for a forward data flow analysis: Starting
59 from the entry point of the method the typechecker follows the CFG and
60 records the type of each stack slot and local variable at each point[1].
61 When two or more control flow paths merge at a point, the union of the
62 types for each slot/variable is taken. The algorithm continues to follow
63 all possible paths[2] until the recorded types do not change anymore (ie.
64 the equations have been solved).
66 If the solution has been reached and the resulting types are valid for
67 all instructions, then type checking terminates with success, otherwise
68 an exception is thrown.
71 Why is this code so damn complicated?
72 -------------------------------------
74 Short answer: The devil's in the details.
76 While the basic operation of the typechecker is no big deal, there are
77 many properties of Java bytecode which make type checking hard. Some of
78 them are not even addressed in the JVM spec. Some problems and their
81 *) Finding a good representation of the union of two reference types is
82 difficult because of multiple inheritance of interfaces.
84 Solution: The typeinfo system can represent such "merged" types by a
85 list of proper subclasses of a class. Example:
87 typeclass=java.lang.Object merged={ InterfaceA, InterfaceB }
89 represents the result of merging two interface types "InterfaceA"
92 *) When the code of a method is verified, there may still be unresolved
93 references to classes/methods/fields in the code, which we may not force
94 to be resolved eagerly. (A similar problem arises because of the special
95 checks for protected members.)
97 Solution: The typeinfo system knows how to deal with unresolved
98 class references. Whenever a check has to be performed for an
99 unresolved type, the type is annotated with constraints representing
100 the check. Later, when the type is resolved, the constraints are
101 checked. (See the constrain_unresolved_... and the resolve_...
104 *) The boundaries of jsr subroutines are not well-defined. For a given
105 instruction it may be impossible to tell whether it is part of a
106 subroutine, or to which subroutine it belongs.
108 Solution: The typechecker implements a method developed by
109 Alessandro Coglio[4] which treats each returnAddress as a distinct
110 type that is not merged with other returnAddresses. This way, when a
111 RET instruction is reached, we know exactly which types to propagate
112 to which return target among the possible targets of the RET. The
113 downside of this method is, that for each slot/variable we must
114 store not just one type, but one type *for each possible use of the
115 returnAddresses* that currently are in a slot/variable.[5]
117 *) Checks for uninitialized object instances are hard because after the
118 invocation of <init> on an uninitialized object *all* slots/variables
119 referring to this object (and exactly those slots/variables) must be
120 marked as initialized.
122 Solution: The JVM spec describes a solution, which has been
123 implemented in this typechecker.
128 [1] Actually only the types of slots/variables at the start of each
129 basic block are remembered. Within a basic block the algorithm only keeps
130 the types of the slots/variables for the "current" instruction which is
133 [2] Actually the algorithm iterates through the basic block list until
134 there are no more changes. Theoretically it would be wise to sort the
135 basic blocks topologically beforehand, but the number of average/max
136 iterations observed is so low, that this was not deemed necessary.
138 [3] This is similar to a method proposed by: Alessandro Coglio et al., A
139 Formal Specification of Java Class Loading, Technical Report, Kestrel
140 Institute April 2000, revised July 2000
141 http://www.kestrel.edu/home/people/coglio/loading.pdf
142 An important difference is that Coglio's subtype constraints are checked
143 after loading, while our constraints are checked when the field/method
144 is accessed for the first time, so we can guarantee lexically correct
147 [4] Alessandro Coglio, Simple Verification Technique for Complex Java
148 Bytecode Subroutines, 4th ECOOP Workshop on Formal Techniques for
149 Java-like Programs, June 2002
150 http://www.kestrel.edu/home/people/coglio/ftjp02.pdf
152 [5] This is a major source of code complexity. The main data structures
153 dealing with this are the "typevector set" and the typestack. The
154 "typevector set" is a set of alternative typevectors, such that each
155 typevector specifies the types of the local variables for a single
156 combination of returnAddresses used. Thus we support full polymorphism
157 of subroutines over the types of local variables. The typestack,
158 however, does not support polymorphism, both for historical and JVM-spec
159 reasons. A slot of the typestack may, however, contain multiple
160 alternative returnAddresses, which is realized by a linked list hanging
161 of the typeinfo of the stack slot.
168 #include "vm/types.h"
170 #include "vm/global.h" /* must be here because of CACAO_TYPECHECK */
172 #ifdef CACAO_TYPECHECK
174 #include "mm/memory.h"
175 #include "toolbox/logging.h"
176 #include "native/native.h"
177 #include "vm/builtin.h"
178 #include "vm/jit/patcher.h"
179 #include "vm/loader.h"
180 #include "vm/options.h"
181 #include "vm/tables.h"
182 #include "vm/jit/jit.h"
183 #include "vm/jit/stack.h"
184 #include "vm/access.h"
185 #include "vm/resolve.h"
188 /****************************************************************************/
190 /****************************************************************************/
192 #ifdef TYPECHECK_DEBUG
193 #define TYPECHECK_ASSERT(cond) assert(cond)
195 #define TYPECHECK_ASSERT(cond)
198 #ifdef TYPECHECK_VERBOSE_OPT
199 bool typecheckverbose = false;
200 #define DOLOG(action) do { if (typecheckverbose) {action;} } while(0)
202 #define DOLOG(action)
205 #ifdef TYPECHECK_VERBOSE
206 #define TYPECHECK_VERBOSE_IMPORTANT
207 #define LOG(str) DOLOG(log_text(str))
208 #define LOG1(str,a) DOLOG(dolog(str,a))
209 #define LOG2(str,a,b) DOLOG(dolog(str,a,b))
210 #define LOG3(str,a,b,c) DOLOG(dolog(str,a,b,c))
211 #define LOGIF(cond,str) DOLOG(do {if (cond) log_text(str);} while(0))
212 #ifdef TYPEINFO_DEBUG
213 #define LOGINFO(info) DOLOG(do {typeinfo_print_short(get_logfile(),(info));log_plain("\n");} while(0))
215 #define LOGINFO(info)
216 #define typevectorset_print(x,y,z)
218 #define LOGFLUSH DOLOG(fflush(get_logfile()))
219 #define LOGNL DOLOG(log_plain("\n"))
220 #define LOGSTR(str) DOLOG(log_plain(str))
221 #define LOGSTR1(str,a) DOLOG(dolog_plain(str,a))
222 #define LOGSTR2(str,a,b) DOLOG(dolog_plain(str,a,b))
223 #define LOGSTR3(str,a,b,c) DOLOG(dolog_plain(str,a,b,c))
224 #define LOGSTRu(utf) DOLOG(log_plain_utf(utf))
225 #define LOGNAME(c) DOLOG(do {log_plain_utf(IS_CLASSREF(c) ? c.ref->name : c.cls->name);} while(0))
226 #define WORDCHECKFAULT \
228 dolog("localset->td index: %ld\ninstruction belongs to:%s.%s, outermethod:%s.%s\n", \
229 state->iptr->op1,state->iptr->method->class->name->text, \
230 state->iptr->method->name->text,state->m->class->name->text,state->m->name->text); \
231 show_icmd(state->iptr++, false); \
232 show_icmd(state->iptr, false); \
237 #define LOG2(str,a,b)
238 #define LOG3(str,a,b,c)
239 #define LOGIF(cond,str)
240 #define LOGINFO(info)
244 #define LOGSTR1(str,a)
245 #define LOGSTR2(str,a,b)
246 #define LOGSTR3(str,a,b,c)
249 #define WORDCHECKFAULT
252 #ifdef TYPECHECK_VERBOSE_IMPORTANT
253 #define LOGimp(str) DOLOG(log_text(str))
254 #define LOGimpSTR(str) DOLOG(log_plain(str))
255 #define LOGimpSTRu(utf) DOLOG(log_plain_utf(utf))
258 #define LOGimpSTR(str)
259 #define LOGimpSTRu(utf)
262 #if defined(TYPECHECK_VERBOSE) || defined(TYPECHECK_VERBOSE_IMPORTANT)
268 typestack_print(FILE *file,stackptr stack)
270 #ifdef TYPEINFO_DEBUG
272 /*fprintf(file,"<%p>",stack);*/
273 typeinfo_print_stacktype(file,stack->type,&(stack->typeinfo));
275 if (stack) fprintf(file," ");
282 typestate_print(FILE *file,stackptr instack,typevector *localset,int size)
284 fprintf(file,"Stack: ");
285 typestack_print(file,instack);
286 fprintf(file," Locals:");
287 typevectorset_print(file,localset,size);
292 /****************************************************************************/
294 /****************************************************************************/
296 #ifdef TYPECHECK_DEBUG
297 /*#define TYPECHECK_STATISTICS*/
300 #ifdef TYPECHECK_STATISTICS
301 #define STAT_ITERATIONS 10
302 #define STAT_BLOCKS 10
303 #define STAT_LOCALS 16
305 static int stat_typechecked = 0;
306 static int stat_typechecked_jsr = 0;
307 static int stat_methods_with_handlers = 0;
308 static int stat_methods_maythrow = 0;
309 static int stat_iterations[STAT_ITERATIONS+1] = { 0 };
310 static int stat_reached = 0;
311 static int stat_copied = 0;
312 static int stat_merged = 0;
313 static int stat_merging_changed = 0;
314 static int stat_backwards = 0;
315 static int stat_blocks[STAT_BLOCKS+1] = { 0 };
316 static int stat_locals[STAT_LOCALS+1] = { 0 };
317 static int stat_ins = 0;
318 static int stat_ins_maythrow = 0;
319 static int stat_ins_stack = 0;
320 static int stat_ins_field = 0;
321 static int stat_ins_field_unresolved = 0;
322 static int stat_ins_field_uninitialized = 0;
323 static int stat_ins_invoke = 0;
324 static int stat_ins_invoke_unresolved = 0;
325 static int stat_ins_primload = 0;
326 static int stat_ins_aload = 0;
327 static int stat_ins_builtin = 0;
328 static int stat_ins_builtin_gen = 0;
329 static int stat_ins_branch = 0;
330 static int stat_ins_switch = 0;
331 static int stat_ins_primitive_return = 0;
332 static int stat_ins_areturn = 0;
333 static int stat_ins_areturn_unresolved = 0;
334 static int stat_ins_athrow = 0;
335 static int stat_ins_athrow_unresolved = 0;
336 static int stat_ins_unchecked = 0;
337 static int stat_handlers_reached = 0;
338 static int stat_savedstack = 0;
340 #define TYPECHECK_MARK(var) ((var) = true)
341 #define TYPECHECK_COUNT(cnt) (cnt)++
342 #define TYPECHECK_COUNTIF(cond,cnt) do{if(cond) (cnt)++;} while(0)
343 #define TYPECHECK_COUNT_FREQ(array,val,limit) \
345 if ((val) < (limit)) (array)[val]++; \
346 else (array)[limit]++; \
349 static void print_freq(FILE *file,int *array,int limit)
352 for (i=0; i<limit; ++i)
353 fprintf(file," %3d: %8d\n",i,array[i]);
354 fprintf(file," >=%3d: %8d\n",limit,array[limit]);
357 void typecheck_print_statistics(FILE *file) {
358 fprintf(file,"typechecked methods: %8d\n",stat_typechecked);
359 fprintf(file," with JSR : %8d\n",stat_typechecked_jsr);
360 fprintf(file," with handler(s): %8d\n",stat_methods_with_handlers);
361 fprintf(file," with throw(s) : %8d\n",stat_methods_maythrow);
362 fprintf(file,"reached blocks : %8d\n",stat_reached);
363 fprintf(file,"copied states : %8d\n",stat_copied);
364 fprintf(file,"merged states : %8d\n",stat_merged);
365 fprintf(file,"merging changed : %8d\n",stat_merging_changed);
366 fprintf(file,"backwards branches : %8d\n",stat_backwards);
367 fprintf(file,"handlers reached : %8d\n",stat_handlers_reached);
368 fprintf(file,"saved stack (times): %8d\n",stat_savedstack);
369 fprintf(file,"instructions : %8d\n",stat_ins);
370 fprintf(file," stack : %8d\n",stat_ins_stack);
371 fprintf(file," field access : %8d\n",stat_ins_field);
372 fprintf(file," (unresolved) : %8d\n",stat_ins_field_unresolved);
373 fprintf(file," (uninit.) : %8d\n",stat_ins_field_uninitialized);
374 fprintf(file," invocations : %8d\n",stat_ins_invoke);
375 fprintf(file," (unresolved) : %8d\n",stat_ins_invoke_unresolved);
376 fprintf(file," load primitive : %8d\n",stat_ins_primload);
377 fprintf(file," load address : %8d\n",stat_ins_aload);
378 fprintf(file," builtins : %8d\n",stat_ins_builtin);
379 fprintf(file," generic : %8d\n",stat_ins_builtin_gen);
380 fprintf(file," branches : %8d\n",stat_ins_branch);
381 fprintf(file," switches : %8d\n",stat_ins_switch);
382 fprintf(file," prim. return : %8d\n",stat_ins_primitive_return);
383 fprintf(file," areturn : %8d\n",stat_ins_areturn);
384 fprintf(file," (unresolved) : %8d\n",stat_ins_areturn_unresolved);
385 fprintf(file," athrow : %8d\n",stat_ins_athrow);
386 fprintf(file," (unresolved) : %8d\n",stat_ins_athrow_unresolved);
387 fprintf(file," unchecked : %8d\n",stat_ins_unchecked);
388 fprintf(file," maythrow : %8d\n",stat_ins_maythrow);
389 fprintf(file,"iterations used:\n");
390 print_freq(file,stat_iterations,STAT_ITERATIONS);
391 fprintf(file,"basic blocks per method / 10:\n");
392 print_freq(file,stat_blocks,STAT_BLOCKS);
393 fprintf(file,"locals:\n");
394 print_freq(file,stat_locals,STAT_LOCALS);
399 #define TYPECHECK_COUNT(cnt)
400 #define TYPECHECK_MARK(var)
401 #define TYPECHECK_COUNTIF(cond,cnt)
402 #define TYPECHECK_COUNT_FREQ(array,val,limit)
405 /****************************************************************************/
406 /* MACROS FOR THROWING EXCEPTIONS */
407 /****************************************************************************/
409 #define TYPECHECK_VERIFYERROR_ret(m,msg,retval) \
411 *exceptionptr = new_verifyerror((m), (msg)); \
415 #define TYPECHECK_VERIFYERROR_main(msg) TYPECHECK_VERIFYERROR_ret(state.m,(msg),NULL)
416 #define TYPECHECK_VERIFYERROR_bool(msg) TYPECHECK_VERIFYERROR_ret(state->m,(msg),false)
418 /****************************************************************************/
419 /* MACROS FOR STACK SLOT TYPE CHECKING */
420 /****************************************************************************/
422 #define TYPECHECK_CHECK_TYPE(sp,tp,msg) \
424 if ((sp)->type != (tp)) { \
425 *exceptionptr = new_verifyerror(state->m, (msg)); \
430 #define TYPECHECK_INT(sp) TYPECHECK_CHECK_TYPE(sp,TYPE_INT,"Expected to find integer on stack")
431 #define TYPECHECK_LNG(sp) TYPECHECK_CHECK_TYPE(sp,TYPE_LNG,"Expected to find long on stack")
432 #define TYPECHECK_FLT(sp) TYPECHECK_CHECK_TYPE(sp,TYPE_FLT,"Expected to find float on stack")
433 #define TYPECHECK_DBL(sp) TYPECHECK_CHECK_TYPE(sp,TYPE_DBL,"Expected to find double on stack")
434 #define TYPECHECK_ADR(sp) TYPECHECK_CHECK_TYPE(sp,TYPE_ADR,"Expected to find object on stack")
436 /****************************************************************************/
437 /* VERIFIER STATE STRUCT */
438 /****************************************************************************/
440 /* verifier_state - This structure keeps the current state of the */
441 /* bytecode verifier for passing it between verifier functions. */
443 typedef struct verifier_state {
444 stackptr curstack; /* input stack top for current instruction */
445 instruction *iptr; /* pointer to current instruction */
446 basicblock *bptr; /* pointer to current basic block */
448 methodinfo *m; /* the current method */
449 codegendata *cd; /* codegendata for current method */
450 registerdata *rd; /* registerdata for current method */
452 s4 numlocals; /* number of local variables */
453 s4 validlocals; /* number of Java-accessible locals */
454 void *localbuf; /* local variable types for each block start */
455 typevector *localset; /* typevector set for local variables */
456 typedescriptor returntype; /* return type of the current method */
458 stackptr savedstackbuf; /* buffer for saving the stack */
459 stackptr savedstack; /* saved instack of current block */
461 exceptiontable **handlers; /* active exception handlers */
462 stackelement excstack; /* instack for exception handlers */
464 bool repeat; /* if true, blocks are iterated over again */
465 bool initmethod; /* true if this is an "<init>" method */
466 bool jsrencountered; /* true if we there was a JSR */
468 #ifdef TYPECHECK_STATISTICS
469 bool stat_maythrow; /* at least one instruction may throw */
473 /****************************************************************************/
474 /* TYPESTACK MACROS AND FUNCTIONS */
476 /* These macros and functions act on the 'type stack', which is a shorthand */
477 /* for the types of the stackslots of the current stack. The type of a */
478 /* stack slot is usually described by a TYPE_* constant and -- for TYPE_ADR */
479 /* -- by the typeinfo of the slot. The only thing that makes the type stack */
480 /* more complicated are returnAddresses of local subroutines, because a */
481 /* single stack slot may contain a set of more than one possible return */
482 /* address. This is handled by 'return address sets'. A return address set */
483 /* is kept as a linked list dangling off the typeinfo of the stack slot. */
484 /****************************************************************************/
486 #define TYPESTACK_IS_RETURNADDRESS(sptr) \
487 TYPE_IS_RETURNADDRESS((sptr)->type,(sptr)->typeinfo)
489 #define TYPESTACK_RETURNADDRESSSET(sptr) \
490 ((typeinfo_retaddr_set*)TYPEINFO_RETURNADDRESS((sptr)->typeinfo))
492 #define RETURNADDRESSSET_SEEK(set,pos) \
493 do {int i; for (i=pos;i--;) set=set->alt;} while(0)
495 /* typestack_copy **************************************************************
497 Copy the types on the given stack to the destination stack.
499 This function does a straight forward copy except for returnAddress types.
500 For returnAddress slots only the return addresses corresponding to
501 typevectors in the SELECTED set are copied.
504 state............current verifier state
505 y................stack with types to copy
506 selected.........set of selected typevectors
509 *dst.............the destination stack
512 true.............success
513 false............an exception has been thrown
515 *******************************************************************************/
518 typestack_copy(verifier_state *state,stackptr dst,stackptr y,typevector *selected)
521 typeinfo_retaddr_set *sety;
522 typeinfo_retaddr_set *new;
523 typeinfo_retaddr_set **next;
526 for (;dst; dst=dst->prev, y=y->prev) {
528 *exceptionptr = new_verifyerror(state->m,"Stack depth mismatch");
531 if (dst->type != y->type) {
532 *exceptionptr = new_verifyerror(state->m,"Stack type mismatch");
535 LOG3("copy %p -> %p (type %d)",y,dst,dst->type);
536 if (dst->type == TYPE_ADDRESS) {
537 if (TYPEINFO_IS_PRIMITIVE(y->typeinfo)) {
538 /* We copy the returnAddresses from the selected
541 LOG("copying returnAddress");
542 sety = TYPESTACK_RETURNADDRESSSET(y);
544 for (k=0,sel=selected; sel; sel=sel->alt) {
545 LOG1("selected k=%d",sel->k);
550 *next = DNEW(typeinfo_retaddr_set);
551 (*next)->addr = sety->addr;
552 next = &((*next)->alt);
555 TYPEINFO_INIT_RETURNADDRESS(dst->typeinfo,new);
558 TYPEINFO_CLONE(y->typeinfo,dst->typeinfo);
563 *exceptionptr = new_verifyerror(state->m,"Stack depth mismatch");
569 /* typestack_put_retaddr *******************************************************
571 Put a returnAddress into a stack slot.
573 The stack slot receives a set of return addresses with as many members as
574 there are typevectors in the local variable set.
577 retaddr..........the returnAddress to set (a basicblock *)
578 loc..............the local variable typevector set
581 *dst.............the destination stack slot
583 *******************************************************************************/
586 typestack_put_retaddr(stackptr dst,void *retaddr,typevector *loc)
588 TYPECHECK_ASSERT(dst->type == TYPE_ADDRESS);
590 TYPEINFO_INIT_RETURNADDRESS(dst->typeinfo,NULL);
591 for (;loc; loc=loc->alt) {
592 typeinfo_retaddr_set *set = DNEW(typeinfo_retaddr_set);
594 set->alt = TYPESTACK_RETURNADDRESSSET(dst);
595 TYPEINFO_INIT_RETURNADDRESS(dst->typeinfo,set);
599 /* typestack_collapse **********************************************************
601 Collapse the given stack by shortening all return address sets to a single
605 *dst.............the destination stack to collapse
607 *******************************************************************************/
610 typestack_collapse(stackptr dst)
612 for (; dst; dst = dst->prev) {
613 if (TYPESTACK_IS_RETURNADDRESS(dst))
614 TYPESTACK_RETURNADDRESSSET(dst)->alt = NULL;
618 /* typestack_merge *************************************************************
620 Merge the types on one stack into the destination stack.
623 state............current state of the verifier
624 dst..............the destination stack
625 y................the second stack
628 *dst.............receives the result of the stack merge
631 typecheck_TRUE...*dst has been modified
632 typecheck_FALSE..*dst has not been modified
633 typecheck_FAIL...an exception has been thrown
635 *******************************************************************************/
637 static typecheck_result
638 typestack_merge(verifier_state *state,stackptr dst,stackptr y)
641 bool changed = false;
643 for (; dst; dst = dst->prev, y=y->prev) {
645 *exceptionptr = new_verifyerror(state->m,"Stack depth mismatch");
646 return typecheck_FAIL;
648 if (dst->type != y->type) {
649 *exceptionptr = new_verifyerror(state->m,"Stack type mismatch");
650 return typecheck_FAIL;
652 if (dst->type == TYPE_ADDRESS) {
653 if (TYPEINFO_IS_PRIMITIVE(dst->typeinfo)) {
654 /* dst has returnAddress type */
655 if (!TYPEINFO_IS_PRIMITIVE(y->typeinfo)) {
656 *exceptionptr = new_verifyerror(state->m,"Merging returnAddress with reference");
657 return typecheck_FAIL;
661 /* dst has reference type */
662 if (TYPEINFO_IS_PRIMITIVE(y->typeinfo)) {
663 *exceptionptr = new_verifyerror(state->m,"Merging reference with returnAddress");
664 return typecheck_FAIL;
666 r = typeinfo_merge(state->m,&(dst->typeinfo),&(y->typeinfo));
667 if (r == typecheck_FAIL)
674 *exceptionptr = new_verifyerror(state->m,"Stack depth mismatch");
675 return typecheck_FAIL;
680 /* typestack_add ***************************************************************
682 Add the return addresses in the given stack at a given k-index to the
683 corresponding return address sets in the destination stack.
686 dst..............the destination stack
687 y................the second stack
688 ky...............the k-index which should be selected from the Y stack
691 *dst.............receives the result of adding the addresses
693 *******************************************************************************/
696 typestack_add(stackptr dst,stackptr y,int ky)
698 typeinfo_retaddr_set *setd;
699 typeinfo_retaddr_set *sety;
701 for (; dst; dst = dst->prev, y=y->prev) {
702 if (TYPESTACK_IS_RETURNADDRESS(dst)) {
703 setd = TYPESTACK_RETURNADDRESSSET(dst);
704 sety = TYPESTACK_RETURNADDRESSSET(y);
705 RETURNADDRESSSET_SEEK(sety,ky);
708 setd->alt = DNEW(typeinfo_retaddr_set);
709 setd->alt->addr = sety->addr;
710 setd->alt->alt = NULL;
716 /* 'a' and 'b' are assumed to have passed typestack_canmerge! */
718 typestack_separable_with(stackptr a,stackptr b,int kb)
720 typeinfo_retaddr_set *seta;
721 typeinfo_retaddr_set *setb;
723 for (; a; a = a->prev, b = b->prev) {
725 if (TYPESTACK_IS_RETURNADDRESS(a)) {
726 TYPECHECK_ASSERT(TYPESTACK_IS_RETURNADDRESS(b));
727 seta = TYPESTACK_RETURNADDRESSSET(a);
728 setb = TYPESTACK_RETURNADDRESSSET(b);
729 RETURNADDRESSSET_SEEK(setb,kb);
731 for (;seta;seta=seta->alt)
732 if (seta->addr != setb->addr) return true;
735 TYPECHECK_ASSERT(!b);
740 /* 'a' and 'b' are assumed to have passed typestack_canmerge! */
742 typestack_separable_from(stackptr a,int ka,stackptr b,int kb)
744 typeinfo_retaddr_set *seta;
745 typeinfo_retaddr_set *setb;
747 for (; a; a = a->prev, b = b->prev) {
749 if (TYPESTACK_IS_RETURNADDRESS(a)) {
750 TYPECHECK_ASSERT(TYPESTACK_IS_RETURNADDRESS(b));
751 seta = TYPESTACK_RETURNADDRESSSET(a);
752 setb = TYPESTACK_RETURNADDRESSSET(b);
753 RETURNADDRESSSET_SEEK(seta,ka);
754 RETURNADDRESSSET_SEEK(setb,kb);
756 if (seta->addr != setb->addr) return true;
759 TYPECHECK_ASSERT(!b);
763 /****************************************************************************/
764 /* TYPESTATE FUNCTIONS */
766 /* These functions act on the 'type state', which comprises: */
767 /* - the types of the stack slots of the current stack */
768 /* - the set of type vectors describing the local variables */
769 /****************************************************************************/
771 /* typestate_merge *************************************************************
773 Merge the types of one state into the destination state.
776 state............current state of the verifier
777 deststack........the destination stack
778 destloc..........the destination set of local variable typevectors
779 ystack...........the second stack
780 yloc.............the second set of local variable typevectors
783 *deststack.......receives the result of the stack merge
784 *destloc.........receives the result of the local variable merge
787 typecheck_TRUE...destination state has been modified
788 typecheck_FALSE..destination state has not been modified
789 typecheck_FAIL...an exception has been thrown
791 *******************************************************************************/
793 static typecheck_result
794 typestate_merge(verifier_state *state,
795 stackptr deststack,typevector *destloc,
796 stackptr ystack,typevector *yloc)
798 typevector *dvec,*yvec;
800 bool changed = false;
804 LOGSTR("dstack: "); DOLOG(typestack_print(get_logfile(),deststack)); LOGNL;
805 LOGSTR("ystack: "); DOLOG(typestack_print(get_logfile(),ystack)); LOGNL;
806 LOGSTR("dloc : "); DOLOG(typevectorset_print(get_logfile(),destloc,state->numlocals)); LOGNL;
807 LOGSTR("yloc : "); DOLOG(typevectorset_print(get_logfile(),yloc,state->numlocals)); LOGNL;
810 /* The stack is always merged. If there are returnAddresses on
811 * the stack they are ignored in this step. */
813 r = typestack_merge(state,deststack,ystack);
814 if (r == typecheck_FAIL)
818 /* If there have not been any JSRs we just have a single typevector merge */
819 if (!state->jsrencountered) {
820 r = typevector_merge(state->m,destloc,yloc,state->numlocals);
821 if (r == typecheck_FAIL)
826 for (yvec=yloc; yvec; yvec=yvec->alt) {
829 /* Check if the typestates (deststack,destloc) will be
830 * separable when (ystack,yvec) is added. */
832 if (!typestack_separable_with(deststack,ystack,ky)
833 && !typevectorset_separable_with(destloc,yvec,state->numlocals))
835 /* No, the resulting set won't be separable, thus we
836 * may merge all states in (deststack,destloc) and
839 typestack_collapse(deststack);
840 if (typevectorset_collapse(state->m,destloc,state->numlocals) == typecheck_FAIL)
841 return typecheck_FAIL;
842 if (typevector_merge(state->m,destloc,yvec,state->numlocals) == typecheck_FAIL)
843 return typecheck_FAIL;
846 /* Yes, the resulting set will be separable. Thus we check
847 * if we may merge (ystack,yvec) with a single state in
848 * (deststack,destloc). */
850 for (dvec=destloc,kd=0; dvec; dvec=dvec->alt, kd++) {
851 if (!typestack_separable_from(ystack,ky,deststack,kd)
852 && !typevector_separable_from(yvec,dvec,state->numlocals))
854 /* The typestate (ystack,yvec) is not separable from
855 * (deststack,dvec) by any returnAddress. Thus we may
856 * merge the states. */
858 r = typevector_merge(state->m,dvec,yvec,state->numlocals);
859 if (r == typecheck_FAIL)
867 /* The typestate (ystack,yvec) is separable from all typestates
868 * (deststack,destloc). Thus we must add this state to the
871 typestack_add(deststack,ystack,ky);
872 typevectorset_add(destloc,yvec,state->numlocals);
881 LOGSTR("dstack: "); DOLOG(typestack_print(get_logfile(),deststack)); LOGNL;
882 LOGSTR("dloc : "); DOLOG(typevectorset_print(get_logfile(),destloc,state->numlocals)); LOGNL;
888 /* typestate_reach *************************************************************
890 Reach a destination block and propagate stack and local variable types
893 state............current state of the verifier
894 destblock........destination basic block
895 ystack...........stack to propagate
896 yloc.............set of local variable typevectors to propagate
899 state->repeat....set to true if the verifier must iterate again
900 over the basic blocks
903 true.............success
904 false............an exception has been thrown
906 *******************************************************************************/
909 typestate_reach(verifier_state *state,
910 basicblock *destblock,
911 stackptr ystack,typevector *yloc)
915 bool changed = false;
918 LOG1("reaching block L%03d",destblock->debug_nr);
919 TYPECHECK_COUNT(stat_reached);
921 destidx = destblock - state->cd->method->basicblocks;
922 destloc = MGET_TYPEVECTOR(state->localbuf,destidx,state->numlocals);
924 /* When branching backwards we have to check for uninitialized objects */
926 if (destblock <= state->bptr) {
930 /* XXX FIXME FOR INLINING */
933 TYPECHECK_COUNT(stat_backwards);
935 for (sp = ystack; sp; sp=sp->prev)
936 if (sp->type == TYPE_ADR &&
937 TYPEINFO_IS_NEWOBJECT(sp->typeinfo)) {
938 /*printf("current: %d, dest: %d\n", state->bptr->debug_nr, destblock->debug_nr);*/
939 *exceptionptr = new_verifyerror(state->m,"Branching backwards with uninitialized object on stack");
943 for (i=0; i<state->numlocals; ++i)
944 if (yloc->td[i].type == TYPE_ADR &&
945 TYPEINFO_IS_NEWOBJECT(yloc->td[i].info)) {
946 *exceptionptr = new_verifyerror(state->m,"Branching backwards with uninitialized object in local variable");
952 if (destblock->flags == BBTYPECHECK_UNDEF) {
953 /* The destblock has never been reached before */
955 TYPECHECK_COUNT(stat_copied);
956 LOG1("block (index %04d) reached first time",destidx);
958 if (!typestack_copy(state,destblock->instack,ystack,yloc))
960 COPY_TYPEVECTORSET(yloc,destloc,state->numlocals);
964 /* The destblock has already been reached before */
966 TYPECHECK_COUNT(stat_merged);
967 LOG1("block (index %04d) reached before",destidx);
969 r = typestate_merge(state,destblock->instack,destloc,ystack,yloc);
970 if (r == typecheck_FAIL)
973 TYPECHECK_COUNTIF(changed,stat_merging_changed);
978 destblock->flags = BBTYPECHECK_REACHED;
979 if (destblock <= state->bptr) {
981 state->repeat = true;
987 /* typestate_ret ***************************************************************
989 Reach the destinations of a RET instruction.
992 state............current state of the verifier
993 retindex.........index of local variable containing the returnAddress
996 state->repeat....set to true if the verifier must iterate again
997 over the basic blocks
1000 true.............success
1001 false............an exception has been thrown
1003 *******************************************************************************/
1006 typestate_ret(verifier_state *state,int retindex)
1009 typevector *selected;
1010 basicblock *destblock;
1012 for (yvec=state->localset; yvec; ) {
1013 if (!TYPEDESC_IS_RETURNADDRESS(yvec->td[retindex])) {
1014 *exceptionptr = new_verifyerror(state->m,"Illegal instruction: RET on non-returnAddress");
1018 destblock = (basicblock*) TYPEINFO_RETURNADDRESS(yvec->td[retindex].info);
1020 selected = typevectorset_select(&yvec,retindex,destblock);
1022 if (!typestate_reach(state,destblock,state->curstack,selected))
1028 /* typestate_save_instack ******************************************************
1030 Save the input stack of the current basic block in the "savedstackbuf"
1031 of the verifier state.
1033 This function must be called before an instruction modifies a stack slot
1034 that happens to be part of the instack of the current block. In such
1035 cases the instack of the block must be saved, and restored at the end
1036 of the analysis of this basic block, so that the instack again reflects
1037 the *input* to this basic block (and does not randomly contain types
1038 that appear within the block).
1041 state............current state of the verifier
1043 *******************************************************************************/
1046 typestate_save_instack(verifier_state *state)
1052 LOG("saving input stack types");
1053 if (!state->savedstackbuf) {
1054 LOG("allocating savedstack buffer");
1055 state->savedstackbuf = DMNEW(stackelement, state->cd->maxstack);
1056 state->savedstackbuf->prev = NULL;
1057 for (i = 1; i < state->cd->maxstack; ++i)
1058 state->savedstackbuf[i].prev = state->savedstackbuf+(i-1);
1060 sp = state->savedstack = state->bptr->instack;
1061 dest = state->bptr->instack = state->savedstackbuf + (state->bptr->indepth-1);
1063 for(; sp; sp=sp->prev, dest=dest->prev) {
1064 dest->type = sp->type;
1065 TYPEINFO_COPY(sp->typeinfo,dest->typeinfo);
1069 /* typestate_restore_instack ***************************************************
1071 Restore the input stack of the current basic block that has been previously
1072 saved by `typestate_save_instack`.
1075 state............current state of the verifier
1077 *******************************************************************************/
1080 typestate_restore_instack(verifier_state *state)
1085 TYPECHECK_COUNT(stat_savedstack);
1086 LOG("restoring saved instack");
1088 sp = state->bptr->instack;
1089 dest = state->savedstack;
1090 for(; sp; sp=sp->prev, dest=dest->prev) {
1091 dest->type = sp->type;
1092 TYPEINFO_COPY(sp->typeinfo,dest->typeinfo);
1095 state->bptr->instack = state->savedstack;
1096 state->savedstack = NULL;
1099 /****************************************************************************/
1101 /****************************************************************************/
1103 #define COPYTYPE(source,dest) \
1104 {if ((source)->type == TYPE_ADR) \
1105 TYPEINFO_COPY((source)->typeinfo,(dest)->typeinfo);}
1107 #define ISBUILTIN(v) (bte->fp == (functionptr) (v))
1109 /* verify_local_variable_type **************************************************
1111 Verify the type of a local variable in the current state.
1114 state............the current state of the verifier
1115 index............the index of the local variable to check (0-based)
1116 tp...............the TYPE_* constant of the type to check
1119 true.............successful verification,
1120 false............an exception has been thrown.
1122 *******************************************************************************/
1125 verify_local_variable_type(verifier_state *state, int index, int tp)
1128 TYPECHECK_COUNT(stat_ins_primload);
1130 if (state->jsrencountered) {
1131 if (!typevectorset_checktype(state->localset,index,tp)) {
1133 TYPECHECK_VERIFYERROR_bool("Variable type mismatch");
1137 /* XXX check if this "optimized" branch really matters */
1138 if (state->localset->td[index].type != tp) {
1140 TYPECHECK_VERIFYERROR_bool("Variable type mismatch");
1146 /* verify_invocation ***********************************************************
1148 Verify an ICMD_INVOKE* instruction.
1151 state............the current state of the verifier
1154 true.............successful verification,
1155 false............an exception has been thrown.
1157 *******************************************************************************/
1160 verify_invocation(verifier_state *state)
1162 unresolved_method *um; /* struct describing the called method */
1163 constant_FMIref *mref; /* reference to the called method */
1164 methoddesc *md; /* descriptor of the called method */
1165 bool specialmethod; /* true if a <...> method is called */
1166 int opcode; /* invocation opcode */
1167 bool callinginit; /* true if <init> is called */
1169 classref_or_classinfo initclass;
1171 stackelement *stack; /* temporary stack pointer */
1172 stackelement *dst; /* result stack of the invocation */
1173 int i; /* counter */
1174 u1 rtype; /* return type of called method */
1176 um = (unresolved_method *) state->iptr[0].target;
1177 mref = um->methodref;
1178 md = mref->parseddesc.md;
1179 specialmethod = (mref->name->text[0] == '<');
1180 opcode = state->iptr[0].opc;
1181 dst = state->iptr->dst;
1183 /* prevent compiler warnings */
1187 /* check whether we are calling <init> */
1189 callinginit = (opcode == ICMD_INVOKESPECIAL && mref->name == utf_init);
1190 if (specialmethod && !callinginit)
1191 TYPECHECK_VERIFYERROR_bool("Invalid invocation of special method");
1193 /* allocate parameters if necessary */
1196 if (!descriptor_params_from_paramtypes(md,
1197 (opcode == ICMD_INVOKESTATIC) ? ACC_STATIC : ACC_NONE))
1200 /* check parameter types */
1202 stack = state->curstack;
1203 i = md->paramcount; /* number of parameters including 'this'*/
1206 td = md->paramtypes + i;
1207 if (stack->type != td->type)
1208 TYPECHECK_VERIFYERROR_bool("Parameter type mismatch in method invocation");
1209 if (stack->type == TYPE_ADR) {
1210 LOGINFO(&(stack->typeinfo));
1211 if (i==0 && callinginit)
1213 /* first argument to <init> method */
1214 if (!TYPEINFO_IS_NEWOBJECT(stack->typeinfo))
1215 TYPECHECK_VERIFYERROR_bool("Calling <init> on initialized object");
1217 /* get the address of the NEW instruction */
1218 LOGINFO(&(stack->typeinfo));
1219 ins = (instruction*)TYPEINFO_NEWOBJECT_INSTRUCTION(stack->typeinfo);
1221 initclass = CLASSREF_OR_CLASSINFO(ins[-1].target);
1223 initclass.cls = state->m->class;
1224 LOGSTR("class: "); LOGNAME(initclass); LOGNL;
1228 /* non-adress argument. if this is the first argument and we are */
1229 /* invoking an instance method, this is an error. */
1230 if (i==0 && opcode != ICMD_INVOKESTATIC) {
1231 TYPECHECK_VERIFYERROR_bool("Parameter type mismatch for 'this' argument");
1237 stack = stack->prev;
1240 LOG("checking return type");
1241 rtype = md->returntype.type;
1242 if (rtype != TYPE_VOID) {
1243 if (rtype != dst->type)
1244 TYPECHECK_VERIFYERROR_bool("Return type mismatch in method invocation");
1245 if (!typeinfo_init_from_typedesc(&(md->returntype),NULL,&(dst->typeinfo)))
1250 LOG("replacing uninitialized object");
1251 /* replace uninitialized object type on stack */
1254 if (stack->type == TYPE_ADR
1255 && TYPEINFO_IS_NEWOBJECT(stack->typeinfo)
1256 && TYPEINFO_NEWOBJECT_INSTRUCTION(stack->typeinfo) == ins)
1258 LOG("replacing uninitialized type on stack");
1260 /* If this stackslot is in the instack of
1261 * this basic block we must save the type(s)
1262 * we are going to replace.
1264 if (stack <= state->bptr->instack && !state->savedstack)
1265 typestate_save_instack(state);
1267 if (!typeinfo_init_class(&(stack->typeinfo),initclass))
1270 stack = stack->prev;
1272 /* replace uninitialized object type in locals */
1273 if (!typevectorset_init_object(state->localset,ins,initclass,state->numlocals))
1276 /* initializing the 'this' reference? */
1279 TYPECHECK_ASSERT(state->initmethod);
1280 /* { we are initializing the 'this' reference } */
1281 /* must be <init> of current class or direct superclass */
1282 /* the current class is linked, so must be its superclass. thus we can be */
1283 /* sure that resolving will be trivial. */
1284 if (!resolve_classref(state->m,mref->classref,resolveLazy,false,true,&cls))
1285 return false; /* exception */
1287 /* if lazy resolving did not succeed, it's not one of the allowed classes */
1288 /* otherwise we check it directly */
1289 if (cls == NULL || (cls != state->m->class && cls != state->m->class->super.cls)) {
1290 TYPECHECK_VERIFYERROR_bool("<init> calling <init> of the wrong class");
1293 /* set our marker variable to type int */
1294 LOG("setting <init> marker");
1295 typevectorset_store(state->localset,state->numlocals-1,TYPE_INT,NULL);
1298 /* { we are initializing an instance created with NEW } */
1299 if ((IS_CLASSREF(initclass) ? initclass.ref->name : initclass.cls->name) != mref->classref->name) {
1300 TYPECHECK_VERIFYERROR_bool("wrong <init> called for uninitialized reference");
1305 /* record subtype constraints for parameters */
1307 if (!constrain_unresolved_method(um,state->m->class,state->m,state->iptr,state->curstack))
1308 return false; /* XXX maybe wrap exception */
1310 /* try to resolve the method lazily */
1312 if (!resolve_method(um,resolveLazy,(methodinfo **) &(state->iptr[0].val.a)))
1318 /* verify_generic_builtin ******************************************************
1320 Verify the call of a generic builtin method.
1323 state............the current state of the verifier
1326 true.............successful verification,
1327 false............an exception has been thrown.
1329 *******************************************************************************/
1332 verify_generic_builtin(verifier_state *state)
1334 builtintable_entry *bte;
1340 TYPECHECK_COUNT(stat_ins_builtin_gen);
1342 bte = (builtintable_entry *) state->iptr[0].val.a;
1346 /* check the types of the arguments on the stack */
1348 sp = state->curstack;
1349 for (i--; i >= 0; i--) {
1350 if (sp->type != md->paramtypes[i].type) {
1351 TYPECHECK_VERIFYERROR_bool("parameter type mismatch for builtin method");
1354 #ifdef TYPECHECK_DEBUG
1355 /* generic builtins may only take primitive types and java.lang.Object references */
1356 if (sp->type == TYPE_ADR && md->paramtypes[i].classref->name != utf_java_lang_Object) {
1357 *exceptionptr = new_internalerror("generic builtin method with non-generic reference parameter");
1365 /* check the return type */
1367 rtype = md->returntype.type;
1368 if (rtype != TYPE_VOID) {
1371 dst = state->iptr->dst;
1372 if (rtype != dst->type)
1373 TYPECHECK_VERIFYERROR_bool("Return type mismatch in generic builtin invocation");
1374 if (!typeinfo_init_from_typedesc(&(md->returntype),NULL,&(dst->typeinfo)))
1381 /* verify_builtin **************************************************************
1383 Verify the call of a builtin method.
1386 state............the current state of the verifier
1389 true.............successful verification,
1390 false............an exception has been thrown.
1392 *******************************************************************************/
1395 verify_builtin(verifier_state *state)
1397 builtintable_entry *bte;
1398 classref_or_classinfo cls;
1399 stackptr dst; /* output stack of current instruction */
1401 bte = (builtintable_entry *) state->iptr[0].val.a;
1402 dst = state->iptr->dst;
1404 /* XXX this is an ugly if-chain but twisti did not want a function */
1405 /* pointer in builtintable_entry for this, so here you go.. ;) */
1407 if (ISBUILTIN(BUILTIN_new)) {
1408 if (state->iptr[-1].opc != ICMD_ACONST)
1409 TYPECHECK_VERIFYERROR_bool("illegal instruction: builtin_new without class");
1410 cls.any = state->iptr[-1].target;
1411 TYPEINFO_INIT_NEWOBJECT(dst->typeinfo,state->iptr);
1413 else if (ISBUILTIN(BUILTIN_newarray_boolean)) {
1414 TYPECHECK_INT(state->curstack);
1415 TYPEINFO_INIT_PRIMITIVE_ARRAY(dst->typeinfo,ARRAYTYPE_BOOLEAN);
1417 else if (ISBUILTIN(BUILTIN_newarray_char)) {
1418 TYPECHECK_INT(state->curstack);
1419 TYPEINFO_INIT_PRIMITIVE_ARRAY(dst->typeinfo,ARRAYTYPE_CHAR);
1421 else if (ISBUILTIN(BUILTIN_newarray_float)) {
1422 TYPECHECK_INT(state->curstack);
1423 TYPEINFO_INIT_PRIMITIVE_ARRAY(dst->typeinfo,ARRAYTYPE_FLOAT);
1425 else if (ISBUILTIN(BUILTIN_newarray_double)) {
1426 TYPECHECK_INT(state->curstack);
1427 TYPEINFO_INIT_PRIMITIVE_ARRAY(dst->typeinfo,ARRAYTYPE_DOUBLE);
1429 else if (ISBUILTIN(BUILTIN_newarray_byte)) {
1430 TYPECHECK_INT(state->curstack);
1431 TYPEINFO_INIT_PRIMITIVE_ARRAY(dst->typeinfo,ARRAYTYPE_BYTE);
1433 else if (ISBUILTIN(BUILTIN_newarray_short)) {
1434 TYPECHECK_INT(state->curstack);
1435 TYPEINFO_INIT_PRIMITIVE_ARRAY(dst->typeinfo,ARRAYTYPE_SHORT);
1437 else if (ISBUILTIN(BUILTIN_newarray_int)) {
1438 TYPECHECK_INT(state->curstack);
1439 TYPEINFO_INIT_PRIMITIVE_ARRAY(dst->typeinfo,ARRAYTYPE_INT);
1441 else if (ISBUILTIN(BUILTIN_newarray_long)) {
1442 TYPECHECK_INT(state->curstack);
1443 TYPEINFO_INIT_PRIMITIVE_ARRAY(dst->typeinfo,ARRAYTYPE_LONG);
1445 else if (ISBUILTIN(BUILTIN_newarray))
1447 TYPECHECK_INT(state->curstack->prev);
1448 if (state->iptr[-1].opc != ICMD_ACONST || !state->iptr[-1].target)
1449 TYPECHECK_VERIFYERROR_bool("illegal instruction: builtin_newarray without class");
1450 /* XXX check that it is an array class(ref) */
1451 typeinfo_init_class(&(dst->typeinfo),CLASSREF_OR_CLASSINFO(state->iptr[-1].target));
1453 else if (ISBUILTIN(BUILTIN_arrayinstanceof))
1455 TYPECHECK_ADR(state->curstack->prev);
1456 if (state->iptr[-1].opc != ICMD_ACONST)
1457 TYPECHECK_VERIFYERROR_bool("illegal instruction: builtin_arrayinstanceof without class");
1458 /* XXX check that it is an array class(ref) */
1461 return verify_generic_builtin(state);
1466 /* verify_multianewarray *******************************************************
1468 Verify a MULTIANEWARRAY instruction.
1471 state............the current state of the verifier
1474 true.............successful verification,
1475 false............an exception has been thrown.
1477 *******************************************************************************/
1480 verify_multianewarray(verifier_state *state)
1483 classinfo *arrayclass;
1484 arraydescriptor *desc;
1487 /* check the array lengths on the stack */
1488 i = state->iptr[0].op1;
1490 TYPECHECK_VERIFYERROR_bool("Illegal dimension argument");
1492 sp = state->curstack;
1495 TYPECHECK_VERIFYERROR_bool("Unable to pop operand off an empty stack");
1500 /* check array descriptor */
1501 if (state->iptr[0].target == NULL) {
1502 /* the array class reference has already been resolved */
1503 arrayclass = (classinfo *) state->iptr[0].val.a;
1505 TYPECHECK_VERIFYERROR_bool("MULTIANEWARRAY with unlinked class");
1506 if ((desc = arrayclass->vftbl->arraydesc) == NULL)
1507 TYPECHECK_VERIFYERROR_bool("MULTIANEWARRAY with non-array class");
1508 if (desc->dimension < state->iptr[0].op1)
1509 TYPECHECK_VERIFYERROR_bool("MULTIANEWARRAY dimension to high");
1511 /* set the array type of the result */
1512 TYPEINFO_INIT_CLASSINFO(state->iptr->dst->typeinfo, arrayclass);
1516 constant_classref *cr;
1518 /* the array class reference is still unresolved */
1519 /* check that the reference indicates an array class of correct dimension */
1520 cr = (constant_classref *) state->iptr[0].val.a;
1525 /* { the dimension of the array class == i } */
1527 TYPECHECK_VERIFYERROR_bool("MULTIANEWARRAY with non-array class");
1528 if (i < state->iptr[0].op1)
1529 TYPECHECK_VERIFYERROR_bool("MULTIANEWARRAY dimension to high");
1531 /* set the array type of the result */
1532 if (!typeinfo_init_class(&(state->iptr->dst->typeinfo),CLASSREF_OR_CLASSINFO(state->iptr[0].val.a)))
1540 /* verify_basic_block **********************************************************
1542 Perform bytecode verification of a basic block.
1545 state............the current state of the verifier
1548 true.............successful verification,
1549 false............an exception has been thrown.
1551 *******************************************************************************/
1554 verify_basic_block(verifier_state *state)
1556 int opcode; /* current opcode */
1557 int len; /* for counting instructions, etc. */
1558 bool superblockend; /* true if no fallthrough to next block */
1559 basicblock *tbptr; /* temporary for target block */
1560 stackptr dst; /* output stack of current instruction */
1561 basicblock **tptr; /* pointer into target list of switch instr. */
1562 classinfo *cls; /* temporary */
1563 bool maythrow; /* true if this instruction may throw */
1565 unresolved_field *uf; /* for field accesses */
1566 fieldinfo **fieldinfop; /* for field accesses */
1571 LOGSTR1("\n---- BLOCK %04d ------------------------------------------------\n",state->bptr->debug_nr);
1574 superblockend = false;
1575 state->bptr->flags = BBFINISHED;
1576 b_index = state->bptr - state->m->basicblocks;
1578 /* init stack at the start of this block */
1579 state->curstack = state->bptr->instack;
1581 /* prevent compiler warnings */
1585 /* determine the active exception handlers for this block */
1586 /* XXX could use a faster algorithm with sorted lists or */
1589 for (i = 0; i < state->cd->exceptiontablelength; ++i) {
1590 if ((state->cd->exceptiontable[i].start <= state->bptr) && (state->cd->exceptiontable[i].end > state->bptr)) {
1591 LOG1("active handler L%03d", state->cd->exceptiontable[i].handler->debug_nr);
1592 state->handlers[len++] = state->cd->exceptiontable + i;
1595 state->handlers[len] = NULL;
1597 /* init variable types at the start of this block */
1598 COPY_TYPEVECTORSET(MGET_TYPEVECTOR(state->localbuf,b_index,state->numlocals),
1599 state->localset,state->numlocals);
1601 /* XXX FIXME FOR INLINING */
1603 if (state->handlers[0])
1604 for (i=0; i<state->numlocals; ++i)
1605 if (state->localset->td[i].type == TYPE_ADR
1606 && TYPEINFO_IS_NEWOBJECT(state->localset->td[i].info)) {
1607 /* XXX we do not check this for the uninitialized 'this' instance in */
1608 /* <init> methods. Otherwise there are problems with try blocks in */
1609 /* <init>. The spec seems to indicate that we should perform the test*/
1610 /* in all cases, but this fails with real code. */
1611 /* Example: org/eclipse/ui/internal/PerspectiveBarNewContributionItem*/
1612 /* of eclipse 3.0.2 */
1613 if (TYPEINFO_NEWOBJECT_INSTRUCTION(state->localset->td[i].info) != NULL) {
1614 /*show_icmd_method(state->m, state->cd, state->rd);*/
1615 printf("Uninitialized variale: %d, block: %d\n", i, state->bptr->debug_nr);
1616 TYPECHECK_VERIFYERROR_bool("Uninitialized object in local variable inside try block");
1620 DOLOG(typestate_print(get_logfile(),state->curstack,state->localset,state->numlocals));
1623 /* loop over the instructions */
1624 len = state->bptr->icount;
1625 state->iptr = state->bptr->iinstr;
1626 while (--len >= 0) {
1627 TYPECHECK_COUNT(stat_ins);
1629 DOLOG(typestate_print(get_logfile(),state->curstack,state->localset,state->numlocals));
1632 DOLOG(show_icmd(state->iptr,false)); LOGNL; LOGFLUSH;
1634 opcode = state->iptr->opc;
1635 myclass = state->iptr->method->class;
1636 dst = state->iptr->dst;
1641 /****************************************/
1642 /* STACK MANIPULATIONS */
1644 /* We just need to copy the typeinfo */
1645 /* for slots containing addresses. */
1647 /* CAUTION: We assume that the destination stack
1648 * slots were continuously allocated in
1649 * memory! (The current implementation in
1654 TYPECHECK_COUNT(stat_ins_stack);
1655 COPYTYPE(state->curstack,dst);
1659 TYPECHECK_COUNT(stat_ins_stack);
1660 COPYTYPE(state->curstack,dst);
1661 COPYTYPE(state->curstack,dst-2);
1662 COPYTYPE(state->curstack->prev,dst-1);
1666 TYPECHECK_COUNT(stat_ins_stack);
1667 COPYTYPE(state->curstack,dst);
1668 COPYTYPE(state->curstack,dst-3);
1669 COPYTYPE(state->curstack->prev,dst-1);
1670 COPYTYPE(state->curstack->prev->prev,dst-2);
1674 TYPECHECK_COUNT(stat_ins_stack);
1675 COPYTYPE(state->curstack,dst);
1676 COPYTYPE(state->curstack->prev,dst-1);
1680 TYPECHECK_COUNT(stat_ins_stack);
1681 COPYTYPE(state->curstack,dst);
1682 COPYTYPE(state->curstack->prev,dst-1);
1683 COPYTYPE(state->curstack,dst-3);
1684 COPYTYPE(state->curstack->prev,dst-4);
1685 COPYTYPE(state->curstack->prev->prev,dst-2);
1689 TYPECHECK_COUNT(stat_ins_stack);
1690 COPYTYPE(state->curstack,dst);
1691 COPYTYPE(state->curstack->prev,dst-1);
1692 COPYTYPE(state->curstack,dst-4);
1693 COPYTYPE(state->curstack->prev,dst-5);
1694 COPYTYPE(state->curstack->prev->prev,dst-2);
1695 COPYTYPE(state->curstack->prev->prev->prev,dst-3);
1699 TYPECHECK_COUNT(stat_ins_stack);
1700 COPYTYPE(state->curstack,dst-1);
1701 COPYTYPE(state->curstack->prev,dst);
1704 /****************************************/
1705 /* PRIMITIVE VARIABLE ACCESS */
1707 case ICMD_ILOAD: if (!verify_local_variable_type(state,state->iptr->op1,TYPE_INT)) return false; break;
1708 case ICMD_FLOAD: if (!verify_local_variable_type(state,state->iptr->op1,TYPE_FLOAT)) return false; break;
1709 case ICMD_IINC: if (!verify_local_variable_type(state,state->iptr->op1,TYPE_INT)) return false; break;
1710 case ICMD_LLOAD: if (!verify_local_variable_type(state,state->iptr->op1,TYPE_LONG)) return false; break;
1711 case ICMD_DLOAD: if (!verify_local_variable_type(state,state->iptr->op1,TYPE_DOUBLE)) return false; break;
1713 case ICMD_FSTORE: typevectorset_store(state->localset,state->iptr->op1,TYPE_FLOAT,NULL); break;
1714 case ICMD_ISTORE: typevectorset_store(state->localset,state->iptr->op1,TYPE_INT,NULL); break;
1715 case ICMD_LSTORE: typevectorset_store_twoword(state->localset,state->iptr->op1,TYPE_LONG); break;
1716 case ICMD_DSTORE: typevectorset_store_twoword(state->localset,state->iptr->op1,TYPE_DOUBLE); break;
1718 /****************************************/
1719 /* LOADING ADDRESS FROM VARIABLE */
1722 TYPECHECK_COUNT(stat_ins_aload);
1724 /* loading a returnAddress is not allowed */
1725 if (state->jsrencountered) {
1726 if (!typevectorset_checkreference(state->localset,state->iptr->op1)) {
1727 TYPECHECK_VERIFYERROR_bool("illegal instruction: ALOAD loading non-reference");
1729 if (typevectorset_copymergedtype(state->m,state->localset,state->iptr->op1,&(dst->typeinfo)) == -1)
1733 if (!TYPEDESC_IS_REFERENCE(state->localset->td[state->iptr->op1])) {
1734 TYPECHECK_VERIFYERROR_bool("illegal instruction: ALOAD loading non-reference");
1736 TYPEINFO_COPY(state->localset->td[state->iptr->op1].info,dst->typeinfo);
1740 /****************************************/
1741 /* STORING ADDRESS TO VARIABLE */
1744 if (state->handlers[0] && TYPEINFO_IS_NEWOBJECT(state->curstack->typeinfo)) {
1745 TYPECHECK_VERIFYERROR_bool("Storing uninitialized object in local variable inside try block");
1748 if (TYPESTACK_IS_RETURNADDRESS(state->curstack)) {
1749 typevectorset_store_retaddr(state->localset,state->iptr->op1,&(state->curstack->typeinfo));
1752 typevectorset_store(state->localset,state->iptr->op1,TYPE_ADDRESS,
1753 &(state->curstack->typeinfo));
1757 /****************************************/
1758 /* LOADING ADDRESS FROM ARRAY */
1761 if (!TYPEINFO_MAYBE_ARRAY_OF_REFS(state->curstack->prev->typeinfo))
1762 TYPECHECK_VERIFYERROR_bool("illegal instruction: AALOAD on non-reference array");
1764 if (!typeinfo_init_component(&state->curstack->prev->typeinfo,&dst->typeinfo))
1769 /****************************************/
1772 case ICMD_PUTFIELDCONST:
1773 case ICMD_PUTSTATICCONST:
1774 TYPECHECK_COUNT(stat_ins_field);
1776 uf = INSTRUCTION_PUTCONST_FIELDREF(state->iptr);
1777 fieldinfop = INSTRUCTION_PUTCONST_FIELDINFO_PTR(state->iptr);
1779 goto fieldaccess_tail;
1782 case ICMD_PUTSTATIC:
1783 TYPECHECK_COUNT(stat_ins_field);
1785 uf = (unresolved_field *) state->iptr[0].target;
1786 fieldinfop = (fieldinfo **) &(state->iptr[0].val.a);
1788 goto fieldaccess_tail;
1791 case ICMD_GETSTATIC:
1792 TYPECHECK_COUNT(stat_ins_field);
1794 uf = (unresolved_field *) state->iptr[0].target;
1795 fieldinfop = (fieldinfo **) &(state->iptr[0].val.a);
1797 /* the result is pushed on the stack */
1798 if (dst->type == TYPE_ADR) {
1799 if (!typeinfo_init_from_typedesc(uf->fieldref->parseddesc.fd,NULL,&(dst->typeinfo)))
1804 /* record the subtype constraints for this field access */
1805 if (!constrain_unresolved_field(uf,state->m->class,state->m,state->iptr,state->curstack))
1806 return false; /* XXX maybe wrap exception? */
1808 /* try to resolve the field reference */
1809 if (!resolve_field(uf,resolveLazy,fieldinfop))
1812 /* we need a patcher, so this is not a leafmethod */
1813 #if defined(__MIPS__)
1814 if (!*fieldinfop || !(*fieldinfop)->class->initialized)
1815 state->cd->method->isleafmethod = false;
1817 TYPECHECK_COUNTIF(!*fieldinfop,stat_ins_field_unresolved);
1818 TYPECHECK_COUNTIF(*fieldinfop && !(*fieldinfop)->class->initialized,stat_ins_field_uninitialized);
1823 /****************************************/
1824 /* PRIMITIVE ARRAY ACCESS */
1826 case ICMD_ARRAYLENGTH:
1827 if (!TYPEINFO_MAYBE_ARRAY(state->curstack->typeinfo)
1828 && state->curstack->typeinfo.typeclass.cls != pseudo_class_Arraystub)
1829 TYPECHECK_VERIFYERROR_bool("illegal instruction: ARRAYLENGTH on non-array");
1834 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->curstack->prev->typeinfo,ARRAYTYPE_BOOLEAN)
1835 && !TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->curstack->prev->typeinfo,ARRAYTYPE_BYTE))
1836 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1840 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->curstack->prev->typeinfo,ARRAYTYPE_CHAR))
1841 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1845 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->curstack->prev->typeinfo,ARRAYTYPE_DOUBLE))
1846 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1850 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->curstack->prev->typeinfo,ARRAYTYPE_FLOAT))
1851 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1855 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->curstack->prev->typeinfo,ARRAYTYPE_INT))
1856 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1860 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->curstack->prev->typeinfo,ARRAYTYPE_SHORT))
1861 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1865 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->curstack->prev->typeinfo,ARRAYTYPE_LONG))
1866 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1871 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->curstack->prev->prev->typeinfo,ARRAYTYPE_BOOLEAN)
1872 && !TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->curstack->prev->prev->typeinfo,ARRAYTYPE_BYTE))
1873 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1877 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->curstack->prev->prev->typeinfo,ARRAYTYPE_CHAR))
1878 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1882 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->curstack->prev->prev->typeinfo,ARRAYTYPE_DOUBLE))
1883 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1887 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->curstack->prev->prev->typeinfo,ARRAYTYPE_FLOAT))
1888 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1892 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->curstack->prev->prev->typeinfo,ARRAYTYPE_INT))
1893 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1897 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->curstack->prev->prev->typeinfo,ARRAYTYPE_SHORT))
1898 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1902 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->curstack->prev->prev->typeinfo,ARRAYTYPE_LONG))
1903 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1908 /* we just check the basic input types and that the */
1909 /* destination is an array of references. Assignability to */
1910 /* the actual array must be checked at runtime, each time the */
1911 /* instruction is performed. (See builtin_canstore.) */
1912 TYPECHECK_ADR(state->curstack);
1913 TYPECHECK_INT(state->curstack->prev);
1914 TYPECHECK_ADR(state->curstack->prev->prev);
1915 if (!TYPEINFO_MAYBE_ARRAY_OF_REFS(state->curstack->prev->prev->typeinfo))
1916 TYPECHECK_VERIFYERROR_bool("illegal instruction: AASTORE to non-reference array");
1920 case ICMD_IASTORECONST:
1921 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->curstack->prev->typeinfo, ARRAYTYPE_INT))
1922 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1926 case ICMD_LASTORECONST:
1927 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->curstack->prev->typeinfo, ARRAYTYPE_LONG))
1928 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1932 case ICMD_BASTORECONST:
1933 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->curstack->prev->typeinfo, ARRAYTYPE_BOOLEAN)
1934 && !TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->curstack->prev->typeinfo, ARRAYTYPE_BYTE))
1935 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1939 case ICMD_CASTORECONST:
1940 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->curstack->prev->typeinfo, ARRAYTYPE_CHAR))
1941 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1945 case ICMD_SASTORECONST:
1946 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->curstack->prev->typeinfo, ARRAYTYPE_SHORT))
1947 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1951 /****************************************/
1952 /* ADDRESS CONSTANTS */
1955 if (state->iptr->target) {
1956 /* a java.lang.Class reference */
1957 TYPEINFO_INIT_JAVA_LANG_CLASS(dst->typeinfo,(constant_classref *)state->iptr->target);
1960 if (state->iptr->val.a == NULL)
1961 TYPEINFO_INIT_NULLTYPE(dst->typeinfo);
1963 /* string constant (or constant for builtin function) */
1964 TYPEINFO_INIT_CLASSINFO(dst->typeinfo,class_java_lang_String);
1969 /****************************************/
1970 /* CHECKCAST AND INSTANCEOF */
1972 case ICMD_CHECKCAST:
1973 TYPECHECK_ADR(state->curstack);
1974 /* returnAddress is not allowed */
1975 if (!TYPEINFO_IS_REFERENCE(state->curstack->typeinfo))
1976 TYPECHECK_VERIFYERROR_bool("Illegal instruction: CHECKCAST on non-reference");
1978 cls = (classinfo *) state->iptr[0].val.a;
1980 TYPEINFO_INIT_CLASSINFO(dst->typeinfo,cls);
1982 if (!typeinfo_init_class(&(dst->typeinfo),CLASSREF_OR_CLASSINFO(state->iptr[0].target)))
1987 case ICMD_INSTANCEOF:
1988 TYPECHECK_ADR(state->curstack);
1989 /* returnAddress is not allowed */
1990 if (!TYPEINFO_IS_REFERENCE(state->curstack->typeinfo))
1991 TYPECHECK_VERIFYERROR_bool("Illegal instruction: INSTANCEOF on non-reference");
1994 /****************************************/
1995 /* BRANCH INSTRUCTIONS */
1998 superblockend = true;
2001 case ICMD_IFNONNULL:
2008 case ICMD_IF_ICMPEQ:
2009 case ICMD_IF_ICMPNE:
2010 case ICMD_IF_ICMPLT:
2011 case ICMD_IF_ICMPGE:
2012 case ICMD_IF_ICMPGT:
2013 case ICMD_IF_ICMPLE:
2014 case ICMD_IF_ACMPEQ:
2015 case ICMD_IF_ACMPNE:
2022 case ICMD_IF_LCMPEQ:
2023 case ICMD_IF_LCMPNE:
2024 case ICMD_IF_LCMPLT:
2025 case ICMD_IF_LCMPGE:
2026 case ICMD_IF_LCMPGT:
2027 case ICMD_IF_LCMPLE:
2028 TYPECHECK_COUNT(stat_ins_branch);
2029 tbptr = (basicblock *) state->iptr->target;
2031 /* propagate stack and variables to the target block */
2032 if (!typestate_reach(state,tbptr,dst,state->localset))
2036 /****************************************/
2039 case ICMD_TABLESWITCH:
2040 TYPECHECK_COUNT(stat_ins_switch);
2042 s4 *s4ptr = state->iptr->val.a;
2043 s4ptr++; /* skip default */
2044 i = *s4ptr++; /* low */
2045 i = *s4ptr++ - i + 2; /* +1 for default target */
2047 goto switch_instruction_tail;
2049 case ICMD_LOOKUPSWITCH:
2050 TYPECHECK_COUNT(stat_ins_switch);
2052 s4 *s4ptr = state->iptr->val.a;
2053 s4ptr++; /* skip default */
2054 i = *s4ptr++ + 1; /* count +1 for default */
2056 switch_instruction_tail:
2057 tptr = (basicblock **)state->iptr->target;
2061 LOG2("target %d is block %04d",(tptr-(basicblock **)state->iptr->target)-1,tbptr->debug_nr);
2062 if (!typestate_reach(state,tbptr,dst,state->localset))
2066 superblockend = true;
2069 /****************************************/
2070 /* ADDRESS RETURNS AND THROW */
2073 TYPECHECK_COUNT(stat_ins_athrow);
2074 r = typeinfo_is_assignable_to_class(&state->curstack->typeinfo,
2075 CLASSREF_OR_CLASSINFO(class_java_lang_Throwable));
2076 if (r == typecheck_FALSE)
2077 TYPECHECK_VERIFYERROR_bool("illegal instruction: ATHROW on non-Throwable");
2078 if (r == typecheck_FAIL)
2080 if (r == typecheck_MAYBE) {
2081 /* the check has to be postponed. we need a patcher */
2082 TYPECHECK_COUNT(stat_ins_athrow_unresolved);
2083 state->iptr->val.a = create_unresolved_class(
2085 /* XXX make this more efficient, use class_java_lang_Throwable
2087 class_get_classref(state->m->class,utf_java_lang_Throwable),
2088 &state->curstack->typeinfo);
2090 superblockend = true;
2095 TYPECHECK_COUNT(stat_ins_areturn);
2096 if (!TYPEINFO_IS_REFERENCE(state->curstack->typeinfo))
2097 TYPECHECK_VERIFYERROR_bool("illegal instruction: ARETURN on non-reference");
2099 if (state->returntype.type != TYPE_ADDRESS
2100 || (r = typeinfo_is_assignable(&state->curstack->typeinfo,&(state->returntype.info)))
2102 TYPECHECK_VERIFYERROR_bool("Return type mismatch");
2103 if (r == typecheck_FAIL)
2105 if (r == typecheck_MAYBE) {
2106 /* the check has to be postponed, we need a patcher */
2107 TYPECHECK_COUNT(stat_ins_areturn_unresolved);
2108 state->iptr->val.a = create_unresolved_class(
2110 state->m->parseddesc->returntype.classref,
2111 &state->curstack->typeinfo);
2115 /****************************************/
2116 /* PRIMITIVE RETURNS */
2119 if (state->returntype.type != TYPE_INT) TYPECHECK_VERIFYERROR_bool("Return type mismatch");
2123 if (state->returntype.type != TYPE_LONG) TYPECHECK_VERIFYERROR_bool("Return type mismatch");
2127 if (state->returntype.type != TYPE_FLOAT) TYPECHECK_VERIFYERROR_bool("Return type mismatch");
2131 if (state->returntype.type != TYPE_DOUBLE) TYPECHECK_VERIFYERROR_bool("Return type mismatch");
2135 if (state->returntype.type != TYPE_VOID) TYPECHECK_VERIFYERROR_bool("Return type mismatch");
2137 TYPECHECK_COUNT(stat_ins_primitive_return);
2139 if (state->initmethod && state->m->class != class_java_lang_Object) {
2140 /* Check if the 'this' instance has been initialized. */
2141 LOG("Checking <init> marker");
2142 if (!typevectorset_checktype(state->localset,state->numlocals-1,TYPE_INT))
2143 TYPECHECK_VERIFYERROR_bool("<init> method does not initialize 'this'");
2146 superblockend = true;
2150 /****************************************/
2151 /* SUBROUTINE INSTRUCTIONS */
2155 state->jsrencountered = true;
2157 /* This is a dirty hack. It is needed
2158 * because of the special handling of
2159 * ICMD_JSR in stack.c
2161 dst = (stackptr) state->iptr->val.a;
2163 tbptr = (basicblock *) state->iptr->target;
2164 if (state->bptr + 1 == (state->m->basicblocks + state->m->basicblockcount + 1))
2165 TYPECHECK_VERIFYERROR_bool("Illegal instruction: JSR at end of bytecode");
2166 typestack_put_retaddr(dst,state->bptr+1,state->localset);
2167 if (!typestate_reach(state,tbptr,dst,state->localset))
2170 superblockend = true;
2174 /* check returnAddress variable */
2175 if (!typevectorset_checkretaddr(state->localset,state->iptr->op1))
2176 TYPECHECK_VERIFYERROR_bool("illegal instruction: RET using non-returnAddress variable");
2178 if (!typestate_ret(state,state->iptr->op1))
2181 superblockend = true;
2184 /****************************************/
2187 case ICMD_INVOKEVIRTUAL:
2188 case ICMD_INVOKESPECIAL:
2189 case ICMD_INVOKESTATIC:
2190 case ICMD_INVOKEINTERFACE:
2191 TYPECHECK_COUNT(stat_ins_invoke);
2192 if (!verify_invocation(state))
2194 TYPECHECK_COUNTIF(!state->iptr[0].val.a,stat_ins_invoke_unresolved);
2198 /****************************************/
2199 /* MULTIANEWARRAY */
2201 case ICMD_MULTIANEWARRAY:
2202 if (!verify_multianewarray(state))
2207 /****************************************/
2211 TYPECHECK_COUNT(stat_ins_builtin);
2212 if (!verify_builtin(state))
2217 /****************************************/
2218 /* SIMPLE EXCEPTION THROWING TESTS */
2220 case ICMD_CHECKNULL:
2221 /* CHECKNULL just requires that the stack top
2222 * is an address. This is checked in stack.c */
2226 /****************************************/
2227 /* INSTRUCTIONS WHICH SHOULD HAVE BEEN */
2228 /* REPLACED BY OTHER OPCODES */
2230 #ifdef TYPECHECK_DEBUG
2233 case ICMD_ANEWARRAY:
2234 case ICMD_MONITORENTER:
2235 case ICMD_MONITOREXIT:
2236 LOG2("ICMD %d at %d\n", state->iptr->opc, (int)(state->iptr-state->bptr->iinstr));
2237 LOG("Should have been converted to builtin function call.");
2238 TYPECHECK_ASSERT(false);
2241 case ICMD_READONLY_ARG:
2242 case ICMD_CLEAR_ARGREN:
2243 LOG2("ICMD %d at %d\n", state->iptr->opc, (int)(state->iptr-state->bptr->iinstr));
2244 LOG("Should have been replaced in stack.c.");
2245 TYPECHECK_ASSERT(false);
2249 /****************************************/
2250 /* UNCHECKED OPERATIONS */
2252 /*********************************************
2253 * Instructions below...
2254 * *) don't operate on local variables,
2255 * *) don't operate on references,
2256 * *) don't operate on returnAddresses.
2258 * (These instructions are typechecked in
2260 ********************************************/
2262 /* Instructions which may throw a runtime exception: */
2272 /* Instructions which never throw a runtime exception: */
2273 #if defined(TYPECHECK_DEBUG) || defined(TYPECHECK_STATISTICS)
2283 case ICMD_IFEQ_ICONST:
2284 case ICMD_IFNE_ICONST:
2285 case ICMD_IFLT_ICONST:
2286 case ICMD_IFGE_ICONST:
2287 case ICMD_IFGT_ICONST:
2288 case ICMD_IFLE_ICONST:
2289 case ICMD_ELSE_ICONST:
2312 case ICMD_IREM0X10001:
2313 case ICMD_LREM0X10001:
2319 case ICMD_IADDCONST:
2320 case ICMD_ISUBCONST:
2321 case ICMD_IMULCONST:
2322 case ICMD_IANDCONST:
2324 case ICMD_IXORCONST:
2325 case ICMD_ISHLCONST:
2326 case ICMD_ISHRCONST:
2327 case ICMD_IUSHRCONST:
2329 case ICMD_LADDCONST:
2330 case ICMD_LSUBCONST:
2331 case ICMD_LMULCONST:
2332 case ICMD_LANDCONST:
2334 case ICMD_LXORCONST:
2335 case ICMD_LSHLCONST:
2336 case ICMD_LSHRCONST:
2337 case ICMD_LUSHRCONST:
2354 case ICMD_INT2SHORT:
2357 case ICMD_LCMPCONST:
2377 /*XXX What shall we do with the following ?*/
2378 case ICMD_AASTORECONST:
2379 TYPECHECK_COUNT(stat_ins_unchecked);
2382 /****************************************/
2385 LOG2("ICMD %d at %d\n", state->iptr->opc, (int)(state->iptr-state->bptr->iinstr));
2386 TYPECHECK_VERIFYERROR_bool("Missing ICMD code during typecheck");
2390 /* the output of this instruction becomes the current stack */
2391 state->curstack = dst;
2393 /* reach exception handlers for this instruction */
2395 TYPECHECK_COUNT(stat_ins_maythrow);
2396 TYPECHECK_MARK(state->stat_maythrow);
2397 LOG("reaching exception handlers");
2399 while (state->handlers[i]) {
2400 TYPECHECK_COUNT(stat_handlers_reached);
2401 if (state->handlers[i]->catchtype.any)
2402 state->excstack.typeinfo.typeclass = state->handlers[i]->catchtype;
2404 state->excstack.typeinfo.typeclass.cls = class_java_lang_Throwable;
2405 if (!typestate_reach(state,
2406 state->handlers[i]->handler,
2407 &(state->excstack),state->localset))
2413 LOG("next instruction");
2415 } /* while instructions */
2417 LOG("instructions done");
2418 LOGSTR("RESULT=> ");
2419 DOLOG(typestate_print(get_logfile(),state->curstack,state->localset,state->numlocals));
2422 /* propagate stack and variables to the following block */
2423 if (!superblockend) {
2424 LOG("reaching following block");
2425 tbptr = state->bptr + 1;
2426 while (tbptr->flags == BBDELETED) {
2428 #ifdef TYPECHECK_DEBUG
2429 /* this must be checked in parse.c */
2430 if ((tbptr->debug_nr) >= state->m->basicblockcount)
2431 TYPECHECK_VERIFYERROR_bool("Control flow falls off the last block");
2434 if (!typestate_reach(state,tbptr,dst,state->localset))
2438 /* We may have to restore the types of the instack slots. They
2439 * have been saved if an <init> call inside the block has
2440 * modified the instack types. (see INVOKESPECIAL) */
2442 if (state->savedstack)
2443 typestate_restore_instack(state);
2448 /* verify_init_locals **********************************************************
2450 Initialize the local variables in the verifier state.
2453 state............the current state of the verifier
2456 true.............success,
2457 false............an exception has been thrown.
2459 *******************************************************************************/
2462 verify_init_locals(verifier_state *state)
2468 /* initialize the variable types of the first block */
2469 /* to the types of the arguments */
2471 lset = MGET_TYPEVECTOR(state->localbuf,0,state->numlocals);
2475 i = state->validlocals;
2477 /* allocate parameter descriptors if necessary */
2479 if (!state->m->parseddesc->params)
2480 if (!descriptor_params_from_paramtypes(state->m->parseddesc,state->m->flags))
2483 /* if this is an instance method initialize the "this" ref type */
2485 if (!(state->m->flags & ACC_STATIC)) {
2487 TYPECHECK_VERIFYERROR_bool("Not enough local variables for method arguments");
2488 td->type = TYPE_ADDRESS;
2489 if (state->initmethod)
2490 TYPEINFO_INIT_NEWOBJECT(td->info,NULL);
2492 TYPEINFO_INIT_CLASSINFO(td->info, state->m->class);
2497 LOG("'this' argument set.\n");
2499 /* the rest of the arguments and the return type */
2501 i = typedescriptors_init_from_methoddesc(td, state->m->parseddesc,
2503 true, /* two word types use two slots */
2504 (td - lset->td), /* skip 'this' pointer */
2505 &state->returntype);
2510 /* variables not used for arguments are initialized to TYPE_VOID */
2512 i = state->numlocals - (td - lset->td);
2514 td->type = TYPE_VOID;
2518 LOG("Arguments set.\n");
2522 /* typecheck_init_flags ********************************************************
2524 Initialize the basic block flags for the following CFG traversal.
2527 state............the current state of the verifier
2529 *******************************************************************************/
2532 typecheck_init_flags(verifier_state *state)
2537 /* set all BBFINISHED blocks to BBTYPECHECK_UNDEF. */
2539 i = state->m->basicblockcount;
2540 block = state->m->basicblocks;
2544 #ifdef TYPECHECK_DEBUG
2545 /* check for invalid flags */
2546 if (block->flags != BBFINISHED && block->flags != BBDELETED && block->flags != BBUNDEF)
2548 /*show_icmd_method(state->cd->method,state->cd,state->rd);*/
2549 LOGSTR1("block flags: %d\n",block->flags); LOGFLUSH;
2550 TYPECHECK_ASSERT(false);
2554 if (block->flags >= BBFINISHED) {
2555 block->flags = BBTYPECHECK_UNDEF;
2560 /* the first block is always reached */
2562 if (state->m->basicblockcount && state->m->basicblocks[0].flags == BBTYPECHECK_UNDEF)
2563 state->m->basicblocks[0].flags = BBTYPECHECK_REACHED;
2566 /* typecheck_reset_flags *******************************************************
2568 Reset the flags of basic blocks we have not reached.
2571 state............the current state of the verifier
2573 *******************************************************************************/
2576 typecheck_reset_flags(verifier_state *state)
2580 /* check for invalid flags at exit */
2582 #ifdef TYPECHECK_DEBUG
2583 for (i=0; i<state->m->basicblockcount; ++i) {
2584 if (state->m->basicblocks[i].flags != BBDELETED
2585 && state->m->basicblocks[i].flags != BBUNDEF
2586 && state->m->basicblocks[i].flags != BBFINISHED
2587 && state->m->basicblocks[i].flags != BBTYPECHECK_UNDEF) /* typecheck may never reach
2588 * some exception handlers,
2591 LOG2("block L%03d has invalid flags after typecheck: %d",
2592 state->m->basicblocks[i].debug_nr,state->m->basicblocks[i].flags);
2593 TYPECHECK_ASSERT(false);
2598 /* Reset blocks we never reached */
2600 for (i=0; i<state->m->basicblockcount; ++i) {
2601 if (state->m->basicblocks[i].flags == BBTYPECHECK_UNDEF)
2602 state->m->basicblocks[i].flags = BBFINISHED;
2606 /****************************************************************************/
2608 /* This is the main function of the bytecode verifier. It is called */
2609 /* directly after analyse_stack. */
2612 /* meth.............the method to verify */
2613 /* cdata............codegendata for the method */
2614 /* rdata............registerdata for the method */
2617 /* m................successful verification */
2618 /* NULL.............an exception has been thrown */
2621 /* Bytecode verification has not been tested with inlining and */
2622 /* probably does not work correctly with inlining. */
2623 /****************************************************************************/
2625 #define MAXPARAMS 255
2627 methodinfo *typecheck(methodinfo *meth, codegendata *cdata, registerdata *rdata)
2629 verifier_state state; /* current state of the verifier */
2630 int i; /* temporary counter */
2632 /* collect statistics */
2634 #ifdef TYPECHECK_STATISTICS
2635 int count_iterations = 0;
2636 TYPECHECK_COUNT(stat_typechecked);
2637 TYPECHECK_COUNT_FREQ(stat_locals,cdata->maxlocals,STAT_LOCALS);
2638 TYPECHECK_COUNT_FREQ(stat_blocks,cdata->method->basicblockcount/10,STAT_BLOCKS);
2639 TYPECHECK_COUNTIF(cdata->method->exceptiontablelength != 0,stat_methods_with_handlers);
2640 state.stat_maythrow = false;
2643 /* some logging on entry */
2645 LOGSTR("\n==============================================================================\n");
2646 /*DOLOG( show_icmd_method(cdata->method,cdata,rdata));*/
2647 LOGSTR("\n==============================================================================\n");
2648 LOGimpSTR("Entering typecheck: ");
2649 LOGimpSTRu(cdata->method->name);
2651 LOGimpSTRu(cdata->method->descriptor);
2652 LOGimpSTR(" (class ");
2653 LOGimpSTRu(cdata->method->class->name);
2657 /* initialize the verifier state */
2659 state.savedstackbuf = NULL;
2660 state.savedstack = NULL;
2661 state.jsrencountered = false;
2666 /* check if this method is an instance initializer method */
2668 state.initmethod = (state.m->name == utf_init);
2670 /* initialize the basic block flags for the following CFG traversal */
2672 typecheck_init_flags(&state);
2674 /* number of local variables */
2676 /* In <init> methods we use an extra local variable to indicate whether */
2677 /* the 'this' reference has been initialized. */
2678 /* TYPE_VOID...means 'this' has not been initialized, */
2679 /* TYPE_INT....means 'this' has been initialized. */
2680 state.numlocals = state.cd->maxlocals;
2681 state.validlocals = state.numlocals;
2682 if (state.initmethod) state.numlocals++;
2684 /* allocate the buffers for local variables */
2686 state.localbuf = DMNEW_TYPEVECTOR(state.m->basicblockcount+1, state.numlocals);
2687 state.localset = MGET_TYPEVECTOR(state.localbuf,state.m->basicblockcount,state.numlocals);
2689 LOG("Variable buffer allocated.\n");
2691 /* allocate the buffer of active exception handlers */
2693 state.handlers = DMNEW(exceptiontable*, state.cd->exceptiontablelength + 1);
2695 /* initialized local variables of first block */
2697 if (!verify_init_locals(&state))
2700 /* initialize the input stack of exception handlers */
2702 state.excstack.prev = NULL;
2703 state.excstack.type = TYPE_ADR;
2704 TYPEINFO_INIT_CLASSINFO(state.excstack.typeinfo,
2705 class_java_lang_Throwable); /* changed later */
2707 LOG("Exception handler stacks set.\n");
2709 /* loop while there are still blocks to be checked */
2711 TYPECHECK_COUNT(count_iterations);
2713 state.repeat = false;
2715 i = state.m->basicblockcount;
2716 state.bptr = state.m->basicblocks;
2719 LOGSTR1("---- BLOCK %04d, ",state.bptr->debug_nr);
2720 LOGSTR1("blockflags: %d\n",state.bptr->flags);
2723 /* verify reached block */
2724 if (state.bptr->flags == BBTYPECHECK_REACHED) {
2725 if (!verify_basic_block(&state))
2729 } /* while blocks */
2731 LOGIF(state.repeat,"state.repeat == true");
2732 } while (state.repeat);
2736 #ifdef TYPECHECK_STATISTICS
2737 LOG1("Typechecker did %4d iterations",count_iterations);
2738 TYPECHECK_COUNT_FREQ(stat_iterations,count_iterations,STAT_ITERATIONS);
2739 TYPECHECK_COUNTIF(state.jsrencountered,stat_typechecked_jsr);
2740 TYPECHECK_COUNTIF(state.stat_maythrow,stat_methods_maythrow);
2743 /* reset the flags of blocks we haven't reached */
2745 typecheck_reset_flags(&state);
2747 /* just return methodinfo* to indicate everything was ok */
2748 LOGimp("exiting typecheck");
2752 #endif /* CACAO_TYPECHECK */
2755 * These are local overrides for various environment variables in Emacs.
2756 * Please do not remove this and leave it at the end of the file, where
2757 * Emacs will automagically detect them.
2758 * ---------------------------------------------------------------------
2761 * indent-tabs-mode: t
2765 * vim:noexpandtab:sw=4:ts=4: