1 /* src/vm/jit/verify/typecheck.c - typechecking (part of bytecode verification)
3 Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
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., 51 Franklin Street, Fifth Floor, Boston, MA
25 Contact: cacao@cacaojvm.org
27 Authors: Edwin Steiner
29 Changes: Christian Thalinger
31 $Id: typecheck.c 4760 2006-04-12 20:06:23Z 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.
169 #include "vm/types.h"
170 #include "vm/global.h"
172 #ifdef ENABLE_VERIFIER
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/jit/jit.h"
182 #include "vm/jit/stack.h"
183 #include "vm/access.h"
184 #include "vm/resolve.h"
187 /****************************************************************************/
189 /****************************************************************************/
191 #ifdef TYPECHECK_DEBUG
192 #define TYPECHECK_ASSERT(cond) assert(cond)
194 #define TYPECHECK_ASSERT(cond)
197 #ifdef TYPECHECK_VERBOSE_OPT
198 bool typecheckverbose = false;
199 FILE *typecheck_logfile;
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(typecheck_logfile,(info));log_finish();} while(0))
215 #define LOGINFO(info)
216 #define typevectorset_print(x,y,z)
218 #define LOGFLUSH DOLOG(fflush(typecheck_logfile))
219 #define LOGNL DOLOG(log_finish())
220 #define LOGSTR(str) DOLOG(log_print(str))
221 #define LOGSTR1(str,a) DOLOG(log_print(str,a))
222 #define LOGSTR2(str,a,b) DOLOG(log_print(str,a,b))
223 #define LOGSTR3(str,a,b,c) DOLOG(log_print(str,a,b,c))
224 #define LOGNAME(c) DOLOG(log_message_utf("class: ",(IS_CLASSREF(c) ? c.ref->name : c.cls->name)))
225 #define LOGMETHOD(str,m) DOLOG(log_message_method(str,m))
229 #define LOG2(str,a,b)
230 #define LOG3(str,a,b,c)
231 #define LOGIF(cond,str)
232 #define LOGINFO(info)
236 #define LOGSTR1(str,a)
237 #define LOGSTR2(str,a,b)
238 #define LOGSTR3(str,a,b,c)
240 #define LOGMETHOD(str,m)
243 #ifdef TYPECHECK_VERBOSE_IMPORTANT
244 #define LOGimp(str) DOLOG(log_text(str))
245 #define LOGimpSTR(str) DOLOG(log_print(str))
248 #define LOGimpSTR(str)
251 #if defined(TYPECHECK_VERBOSE) || defined(TYPECHECK_VERBOSE_IMPORTANT)
257 typestack_print(FILE *file,stackptr stack)
259 #ifdef TYPEINFO_DEBUG
261 /*fprintf(file,"<%p>",stack);*/
262 typeinfo_print_stacktype(file,stack->type,&(stack->typeinfo));
264 if (stack) fprintf(file," ");
271 typestate_print(FILE *file,stackptr instack,typevector *localset,int size)
273 fprintf(file,"Stack: ");
274 typestack_print(file,instack);
275 fprintf(file," Locals:");
276 typevectorset_print(file,localset,size);
281 /****************************************************************************/
283 /****************************************************************************/
285 #ifdef TYPECHECK_DEBUG
286 /*#define TYPECHECK_STATISTICS*/
289 #ifdef TYPECHECK_STATISTICS
290 #define STAT_ITERATIONS 10
291 #define STAT_BLOCKS 10
292 #define STAT_LOCALS 16
294 static int stat_typechecked = 0;
295 static int stat_typechecked_jsr = 0;
296 static int stat_methods_with_handlers = 0;
297 static int stat_methods_maythrow = 0;
298 static int stat_iterations[STAT_ITERATIONS+1] = { 0 };
299 static int stat_reached = 0;
300 static int stat_copied = 0;
301 static int stat_merged = 0;
302 static int stat_merging_changed = 0;
303 static int stat_backwards = 0;
304 static int stat_blocks[STAT_BLOCKS+1] = { 0 };
305 static int stat_locals[STAT_LOCALS+1] = { 0 };
306 static int stat_ins = 0;
307 static int stat_ins_maythrow = 0;
308 static int stat_ins_stack = 0;
309 static int stat_ins_field = 0;
310 static int stat_ins_field_unresolved = 0;
311 static int stat_ins_field_uninitialized = 0;
312 static int stat_ins_invoke = 0;
313 static int stat_ins_invoke_unresolved = 0;
314 static int stat_ins_primload = 0;
315 static int stat_ins_aload = 0;
316 static int stat_ins_builtin = 0;
317 static int stat_ins_builtin_gen = 0;
318 static int stat_ins_branch = 0;
319 static int stat_ins_switch = 0;
320 static int stat_ins_primitive_return = 0;
321 static int stat_ins_areturn = 0;
322 static int stat_ins_areturn_unresolved = 0;
323 static int stat_ins_athrow = 0;
324 static int stat_ins_athrow_unresolved = 0;
325 static int stat_ins_unchecked = 0;
326 static int stat_handlers_reached = 0;
327 static int stat_savedstack = 0;
329 #define TYPECHECK_MARK(var) ((var) = true)
330 #define TYPECHECK_COUNT(cnt) (cnt)++
331 #define TYPECHECK_COUNTIF(cond,cnt) do{if(cond) (cnt)++;} while(0)
332 #define TYPECHECK_COUNT_FREQ(array,val,limit) \
334 if ((val) < (limit)) (array)[val]++; \
335 else (array)[limit]++; \
338 static void print_freq(FILE *file,int *array,int limit)
341 for (i=0; i<limit; ++i)
342 fprintf(file," %3d: %8d\n",i,array[i]);
343 fprintf(file," >=%3d: %8d\n",limit,array[limit]);
346 void typecheck_print_statistics(FILE *file) {
347 fprintf(file,"typechecked methods: %8d\n",stat_typechecked);
348 fprintf(file," with JSR : %8d\n",stat_typechecked_jsr);
349 fprintf(file," with handler(s): %8d\n",stat_methods_with_handlers);
350 fprintf(file," with throw(s) : %8d\n",stat_methods_maythrow);
351 fprintf(file,"reached blocks : %8d\n",stat_reached);
352 fprintf(file,"copied states : %8d\n",stat_copied);
353 fprintf(file,"merged states : %8d\n",stat_merged);
354 fprintf(file,"merging changed : %8d\n",stat_merging_changed);
355 fprintf(file,"backwards branches : %8d\n",stat_backwards);
356 fprintf(file,"handlers reached : %8d\n",stat_handlers_reached);
357 fprintf(file,"saved stack (times): %8d\n",stat_savedstack);
358 fprintf(file,"instructions : %8d\n",stat_ins);
359 fprintf(file," stack : %8d\n",stat_ins_stack);
360 fprintf(file," field access : %8d\n",stat_ins_field);
361 fprintf(file," (unresolved) : %8d\n",stat_ins_field_unresolved);
362 fprintf(file," (uninit.) : %8d\n",stat_ins_field_uninitialized);
363 fprintf(file," invocations : %8d\n",stat_ins_invoke);
364 fprintf(file," (unresolved) : %8d\n",stat_ins_invoke_unresolved);
365 fprintf(file," load primitive : (currently not counted) %8d\n",stat_ins_primload);
366 fprintf(file," load address : %8d\n",stat_ins_aload);
367 fprintf(file," builtins : %8d\n",stat_ins_builtin);
368 fprintf(file," generic : %8d\n",stat_ins_builtin_gen);
369 fprintf(file," branches : %8d\n",stat_ins_branch);
370 fprintf(file," switches : %8d\n",stat_ins_switch);
371 fprintf(file," prim. return : %8d\n",stat_ins_primitive_return);
372 fprintf(file," areturn : %8d\n",stat_ins_areturn);
373 fprintf(file," (unresolved) : %8d\n",stat_ins_areturn_unresolved);
374 fprintf(file," athrow : %8d\n",stat_ins_athrow);
375 fprintf(file," (unresolved) : %8d\n",stat_ins_athrow_unresolved);
376 fprintf(file," unchecked : %8d\n",stat_ins_unchecked);
377 fprintf(file," maythrow : %8d\n",stat_ins_maythrow);
378 fprintf(file,"iterations used:\n");
379 print_freq(file,stat_iterations,STAT_ITERATIONS);
380 fprintf(file,"basic blocks per method / 10:\n");
381 print_freq(file,stat_blocks,STAT_BLOCKS);
382 fprintf(file,"locals:\n");
383 print_freq(file,stat_locals,STAT_LOCALS);
388 #define TYPECHECK_COUNT(cnt)
389 #define TYPECHECK_MARK(var)
390 #define TYPECHECK_COUNTIF(cond,cnt)
391 #define TYPECHECK_COUNT_FREQ(array,val,limit)
394 /****************************************************************************/
395 /* MACROS FOR THROWING EXCEPTIONS */
396 /****************************************************************************/
398 #define TYPECHECK_VERIFYERROR_ret(m,msg,retval) \
400 *exceptionptr = new_verifyerror((m), (msg)); \
404 #define TYPECHECK_VERIFYERROR_main(msg) TYPECHECK_VERIFYERROR_ret(state.m,(msg),NULL)
405 #define TYPECHECK_VERIFYERROR_bool(msg) TYPECHECK_VERIFYERROR_ret(state->m,(msg),false)
407 /****************************************************************************/
408 /* MACROS FOR STACK SLOT TYPE CHECKING */
409 /****************************************************************************/
411 #define TYPECHECK_CHECK_TYPE(sp,tp,msg) \
413 if ((sp)->type != (tp)) { \
414 *exceptionptr = new_verifyerror(state->m, (msg)); \
419 #define TYPECHECK_INT(sp) TYPECHECK_CHECK_TYPE(sp,TYPE_INT,"Expected to find integer on stack")
420 #define TYPECHECK_LNG(sp) TYPECHECK_CHECK_TYPE(sp,TYPE_LNG,"Expected to find long on stack")
421 #define TYPECHECK_FLT(sp) TYPECHECK_CHECK_TYPE(sp,TYPE_FLT,"Expected to find float on stack")
422 #define TYPECHECK_DBL(sp) TYPECHECK_CHECK_TYPE(sp,TYPE_DBL,"Expected to find double on stack")
423 #define TYPECHECK_ADR(sp) TYPECHECK_CHECK_TYPE(sp,TYPE_ADR,"Expected to find object on stack")
425 /****************************************************************************/
426 /* VERIFIER STATE STRUCT */
427 /****************************************************************************/
429 /* verifier_state - This structure keeps the current state of the */
430 /* bytecode verifier for passing it between verifier functions. */
432 typedef struct verifier_state {
433 stackptr curstack; /* input stack top for current instruction */
434 instruction *iptr; /* pointer to current instruction */
435 basicblock *bptr; /* pointer to current basic block */
437 methodinfo *m; /* the current method */
438 codegendata *cd; /* codegendata for current method */
439 registerdata *rd; /* registerdata for current method */
441 s4 numlocals; /* number of local variables */
442 s4 validlocals; /* number of Java-accessible locals */
443 void *localbuf; /* local variable types for each block start */
444 typevector *localset; /* typevector set for local variables */
445 typedescriptor returntype; /* return type of the current method */
447 stackptr savedstackbuf; /* buffer for saving the stack */
448 stackptr savedstack; /* saved instack of current block */
450 exceptiontable **handlers; /* active exception handlers */
451 stackelement excstack; /* instack for exception handlers */
453 bool repeat; /* if true, blocks are iterated over again */
454 bool initmethod; /* true if this is an "<init>" method */
455 bool jsrencountered; /* true if we there was a JSR */
457 #ifdef TYPECHECK_STATISTICS
458 bool stat_maythrow; /* at least one instruction may throw */
462 /****************************************************************************/
463 /* TYPESTACK MACROS AND FUNCTIONS */
465 /* These macros and functions act on the 'type stack', which is a shorthand */
466 /* for the types of the stackslots of the current stack. The type of a */
467 /* stack slot is usually described by a TYPE_* constant and -- for TYPE_ADR */
468 /* -- by the typeinfo of the slot. The only thing that makes the type stack */
469 /* more complicated are returnAddresses of local subroutines, because a */
470 /* single stack slot may contain a set of more than one possible return */
471 /* address. This is handled by 'return address sets'. A return address set */
472 /* is kept as a linked list dangling off the typeinfo of the stack slot. */
473 /****************************************************************************/
475 #define TYPESTACK_IS_RETURNADDRESS(sptr) \
476 TYPE_IS_RETURNADDRESS((sptr)->type,(sptr)->typeinfo)
478 #define TYPESTACK_RETURNADDRESSSET(sptr) \
479 ((typeinfo_retaddr_set*)TYPEINFO_RETURNADDRESS((sptr)->typeinfo))
481 #define RETURNADDRESSSET_SEEK(set,pos) \
482 do {int i; for (i=pos;i--;) set=set->alt;} while(0)
484 /* typestack_copy **************************************************************
486 Copy the types on the given stack to the destination stack.
488 This function does a straight forward copy except for returnAddress types.
489 For returnAddress slots only the return addresses corresponding to
490 typevectors in the SELECTED set are copied.
493 state............current verifier state
494 y................stack with types to copy
495 selected.........set of selected typevectors
498 *dst.............the destination stack
501 true.............success
502 false............an exception has been thrown
504 *******************************************************************************/
507 typestack_copy(verifier_state *state,stackptr dst,stackptr y,typevector *selected)
510 typeinfo_retaddr_set *sety;
511 typeinfo_retaddr_set *new;
512 typeinfo_retaddr_set **next;
515 for (;dst; dst=dst->prev, y=y->prev) {
516 /* XXX only check the following two in debug mode? */
518 *exceptionptr = new_verifyerror(state->m,"Stack depth mismatch");
521 if (dst->type != y->type) {
522 *exceptionptr = new_verifyerror(state->m,"Stack type mismatch");
525 LOG3("copy %p -> %p (type %d)",y,dst,dst->type);
526 if (dst->type == TYPE_ADDRESS) {
527 if (TYPEINFO_IS_PRIMITIVE(y->typeinfo)) {
528 /* We copy the returnAddresses from the selected
531 LOG("copying returnAddress");
532 sety = TYPESTACK_RETURNADDRESSSET(y);
534 for (k=0,sel=selected; sel; sel=sel->alt) {
535 LOG1("selected k=%d",sel->k);
540 *next = DNEW(typeinfo_retaddr_set);
541 (*next)->addr = sety->addr;
542 next = &((*next)->alt);
545 TYPEINFO_INIT_RETURNADDRESS(dst->typeinfo,new);
548 TYPEINFO_CLONE(y->typeinfo,dst->typeinfo);
553 *exceptionptr = new_verifyerror(state->m,"Stack depth mismatch");
559 /* typestack_put_retaddr *******************************************************
561 Put a returnAddress into a stack slot.
563 The stack slot receives a set of return addresses with as many members as
564 there are typevectors in the local variable set.
567 retaddr..........the returnAddress to set (a basicblock *)
568 loc..............the local variable typevector set
571 *dst.............the destination stack slot
573 *******************************************************************************/
576 typestack_put_retaddr(stackptr dst,void *retaddr,typevector *loc)
578 TYPECHECK_ASSERT(dst->type == TYPE_ADDRESS);
580 TYPEINFO_INIT_RETURNADDRESS(dst->typeinfo,NULL);
581 for (;loc; loc=loc->alt) {
582 typeinfo_retaddr_set *set = DNEW(typeinfo_retaddr_set);
584 set->alt = TYPESTACK_RETURNADDRESSSET(dst);
585 TYPEINFO_INIT_RETURNADDRESS(dst->typeinfo,set);
589 /* typestack_collapse **********************************************************
591 Collapse the given stack by shortening all return address sets to a single
595 *dst.............the destination stack to collapse
597 *******************************************************************************/
600 typestack_collapse(stackptr dst)
602 for (; dst; dst = dst->prev) {
603 if (TYPESTACK_IS_RETURNADDRESS(dst))
604 TYPESTACK_RETURNADDRESSSET(dst)->alt = NULL;
608 /* typestack_merge *************************************************************
610 Merge the types on one stack into the destination stack.
613 state............current state of the verifier
614 dst..............the destination stack
615 y................the second stack
618 *dst.............receives the result of the stack merge
621 typecheck_TRUE...*dst has been modified
622 typecheck_FALSE..*dst has not been modified
623 typecheck_FAIL...an exception has been thrown
625 *******************************************************************************/
627 static typecheck_result
628 typestack_merge(verifier_state *state,stackptr dst,stackptr y)
631 bool changed = false;
633 for (; dst; dst = dst->prev, y=y->prev) {
635 *exceptionptr = new_verifyerror(state->m,"Stack depth mismatch");
636 return typecheck_FAIL;
638 if (dst->type != y->type) {
639 *exceptionptr = new_verifyerror(state->m,"Stack type mismatch");
640 return typecheck_FAIL;
642 if (dst->type == TYPE_ADDRESS) {
643 if (TYPEINFO_IS_PRIMITIVE(dst->typeinfo)) {
644 /* dst has returnAddress type */
645 if (!TYPEINFO_IS_PRIMITIVE(y->typeinfo)) {
646 *exceptionptr = new_verifyerror(state->m,"Merging returnAddress with reference");
647 return typecheck_FAIL;
651 /* dst has reference type */
652 if (TYPEINFO_IS_PRIMITIVE(y->typeinfo)) {
653 *exceptionptr = new_verifyerror(state->m,"Merging reference with returnAddress");
654 return typecheck_FAIL;
656 r = typeinfo_merge(state->m,&(dst->typeinfo),&(y->typeinfo));
657 if (r == typecheck_FAIL)
664 *exceptionptr = new_verifyerror(state->m,"Stack depth mismatch");
665 return typecheck_FAIL;
670 /* typestack_add ***************************************************************
672 Add the return addresses in the given stack at a given k-index to the
673 corresponding return address sets in the destination stack.
676 dst..............the destination stack
677 y................the second stack
678 ky...............the k-index which should be selected from the Y stack
681 *dst.............receives the result of adding the addresses
683 *******************************************************************************/
686 typestack_add(stackptr dst,stackptr y,int ky)
688 typeinfo_retaddr_set *setd;
689 typeinfo_retaddr_set *sety;
691 for (; dst; dst = dst->prev, y=y->prev) {
692 if (TYPESTACK_IS_RETURNADDRESS(dst)) {
693 setd = TYPESTACK_RETURNADDRESSSET(dst);
694 sety = TYPESTACK_RETURNADDRESSSET(y);
695 RETURNADDRESSSET_SEEK(sety,ky);
698 setd->alt = DNEW(typeinfo_retaddr_set);
699 setd->alt->addr = sety->addr;
700 setd->alt->alt = NULL;
705 /* typestack_separable_with ****************************************************
707 This function answers the question: If variant 'kb' of typestack 'b' is
708 added to typestack 'a', will the result be separable?
710 A typestack is called 'separable' if it has at least one slot of type
711 returnAddress that contains at least two different return addresses.
712 (ie. a RET using the value in this slot could go to more than one target)
715 a................the first typestack
716 b................the second typestack
717 kb...............the k-index of the variant that should be selected
721 true.............the result would be separable
722 false............the result would not be separable
725 'a' and 'b' are assumed to have passed typestack_canmerge!
727 *******************************************************************************/
730 typestack_separable_with(stackptr a,stackptr b,int kb)
732 typeinfo_retaddr_set *seta;
733 typeinfo_retaddr_set *setb;
735 for (; a; a = a->prev, b = b->prev) {
737 if (TYPESTACK_IS_RETURNADDRESS(a)) {
738 TYPECHECK_ASSERT(TYPESTACK_IS_RETURNADDRESS(b));
739 seta = TYPESTACK_RETURNADDRESSSET(a);
740 setb = TYPESTACK_RETURNADDRESSSET(b);
741 RETURNADDRESSSET_SEEK(setb,kb);
743 for (;seta;seta=seta->alt)
744 if (seta->addr != setb->addr) return true;
747 TYPECHECK_ASSERT(!b);
751 /* typestack_separable_from ****************************************************
753 This function answers the question: Is variant 'ka' of typestack 'a'
754 separable from variant 'kb' of typestack 'b'?
756 Two variants of typestacks are called 'separable' from each other, if there
757 is at least one slot for which the variants contain different return addresses.
758 (ie. a RET using the value in this slot would go to one target in the first
759 variant and to another target in the second variant)
762 a................the first typestack
763 ka...............the k-index of the variant that should be selected
765 b................the second typestack
766 kb...............the k-index of the variant that should be selected
770 true.............the variants are separable
771 false............the variants are not separable
774 'a' and 'b' are assumed to have passed typestack_canmerge!
776 *******************************************************************************/
779 typestack_separable_from(stackptr a,int ka,stackptr b,int kb)
781 typeinfo_retaddr_set *seta;
782 typeinfo_retaddr_set *setb;
784 for (; a; a = a->prev, b = b->prev) {
786 if (TYPESTACK_IS_RETURNADDRESS(a)) {
787 TYPECHECK_ASSERT(TYPESTACK_IS_RETURNADDRESS(b));
788 seta = TYPESTACK_RETURNADDRESSSET(a);
789 setb = TYPESTACK_RETURNADDRESSSET(b);
790 RETURNADDRESSSET_SEEK(seta,ka);
791 RETURNADDRESSSET_SEEK(setb,kb);
793 if (seta->addr != setb->addr) return true;
796 TYPECHECK_ASSERT(!b);
800 /****************************************************************************/
801 /* TYPESTATE FUNCTIONS */
803 /* These functions act on the 'type state', which comprises: */
804 /* - the types of the stack slots of the current stack */
805 /* - the set of type vectors describing the local variables */
806 /****************************************************************************/
808 /* typestate_merge *************************************************************
810 Merge the types of one state into the destination state.
813 state............current state of the verifier
814 deststack........the destination stack
815 destloc..........the destination set of local variable typevectors
816 ystack...........the second stack
817 yloc.............the second set of local variable typevectors
820 *deststack.......receives the result of the stack merge
821 *destloc.........receives the result of the local variable merge
824 typecheck_TRUE...destination state has been modified
825 typecheck_FALSE..destination state has not been modified
826 typecheck_FAIL...an exception has been thrown
828 *******************************************************************************/
830 static typecheck_result
831 typestate_merge(verifier_state *state,
832 stackptr deststack,typevector *destloc,
833 stackptr ystack,typevector *yloc)
835 typevector *dvec,*yvec;
837 bool changed = false;
841 LOGSTR("dstack: "); DOLOG(typestack_print(typecheck_logfile,deststack)); LOGNL;
842 LOGSTR("ystack: "); DOLOG(typestack_print(typecheck_logfile,ystack)); LOGNL;
843 LOGSTR("dloc : "); DOLOG(typevectorset_print(typecheck_logfile,destloc,state->numlocals)); LOGNL;
844 LOGSTR("yloc : "); DOLOG(typevectorset_print(typecheck_logfile,yloc,state->numlocals)); LOGNL;
847 /* The stack is always merged. If there are returnAddresses on
848 * the stack they are ignored in this step. */
850 r = typestack_merge(state,deststack,ystack);
851 if (r == typecheck_FAIL)
855 /* If there have not been any JSRs we just have a single typevector merge */
856 if (!state->jsrencountered) {
857 r = typevector_merge(state->m,destloc,yloc,state->numlocals);
858 if (r == typecheck_FAIL)
863 for (yvec=yloc; yvec; yvec=yvec->alt) {
866 /* Check if the typestates (deststack,destloc) will be
867 * separable when (ystack,yvec) is added. */
869 if (!typestack_separable_with(deststack,ystack,ky)
870 && !typevectorset_separable_with(destloc,yvec,state->numlocals))
872 /* No, the resulting set won't be separable, thus we
873 * may merge all states in (deststack,destloc) and
876 typestack_collapse(deststack);
877 if (typevectorset_collapse(state->m,destloc,state->numlocals) == typecheck_FAIL)
878 return typecheck_FAIL;
879 if (typevector_merge(state->m,destloc,yvec,state->numlocals) == typecheck_FAIL)
880 return typecheck_FAIL;
883 /* Yes, the resulting set will be separable. Thus we check
884 * if we may merge (ystack,yvec) with a single state in
885 * (deststack,destloc). */
887 for (dvec=destloc,kd=0; dvec; dvec=dvec->alt, kd++) {
888 if (!typestack_separable_from(ystack,ky,deststack,kd)
889 && !typevector_separable_from(yvec,dvec,state->numlocals))
891 /* The typestate (ystack,yvec) is not separable from
892 * (deststack,dvec) by any returnAddress. Thus we may
893 * merge the states. */
895 r = typevector_merge(state->m,dvec,yvec,state->numlocals);
896 if (r == typecheck_FAIL)
904 /* The typestate (ystack,yvec) is separable from all typestates
905 * (deststack,destloc). Thus we must add this state to the
908 typestack_add(deststack,ystack,ky);
909 typevectorset_add(destloc,yvec,state->numlocals);
918 LOGSTR("dstack: "); DOLOG(typestack_print(typecheck_logfile,deststack)); LOGNL;
919 LOGSTR("dloc : "); DOLOG(typevectorset_print(typecheck_logfile,destloc,state->numlocals)); LOGNL;
925 /* typestate_reach *************************************************************
927 Reach a destination block and propagate stack and local variable types
930 state............current state of the verifier
931 destblock........destination basic block
932 ystack...........stack to propagate
933 yloc.............set of local variable typevectors to propagate
936 state->repeat....set to true if the verifier must iterate again
937 over the basic blocks
940 true.............success
941 false............an exception has been thrown
943 *******************************************************************************/
946 typestate_reach(verifier_state *state,
947 basicblock *destblock,
948 stackptr ystack,typevector *yloc)
952 bool changed = false;
955 LOG1("reaching block L%03d",destblock->debug_nr);
956 TYPECHECK_COUNT(stat_reached);
958 destidx = destblock - state->cd->method->basicblocks;
959 destloc = MGET_TYPEVECTOR(state->localbuf,destidx,state->numlocals);
961 /* When branching backwards we have to check for uninitialized objects */
963 if (destblock <= state->bptr) {
967 /* XXX FIXME FOR INLINING */
970 TYPECHECK_COUNT(stat_backwards);
972 for (sp = ystack; sp; sp=sp->prev)
973 if (sp->type == TYPE_ADR &&
974 TYPEINFO_IS_NEWOBJECT(sp->typeinfo)) {
975 /*printf("current: %d, dest: %d\n", state->bptr->debug_nr, destblock->debug_nr);*/
976 *exceptionptr = new_verifyerror(state->m,"Branching backwards with uninitialized object on stack");
980 for (i=0; i<state->numlocals; ++i)
981 if (yloc->td[i].type == TYPE_ADR &&
982 TYPEINFO_IS_NEWOBJECT(yloc->td[i].info)) {
983 *exceptionptr = new_verifyerror(state->m,"Branching backwards with uninitialized object in local variable");
989 if (destblock->flags == BBTYPECHECK_UNDEF) {
990 /* The destblock has never been reached before */
992 TYPECHECK_COUNT(stat_copied);
993 LOG1("block (index %04d) reached first time",destidx);
995 if (!typestack_copy(state,destblock->instack,ystack,yloc))
997 typevectorset_copy_inplace(yloc,destloc,state->numlocals);
1001 /* The destblock has already been reached before */
1003 TYPECHECK_COUNT(stat_merged);
1004 LOG1("block (index %04d) reached before",destidx);
1006 r = typestate_merge(state,destblock->instack,destloc,ystack,yloc);
1007 if (r == typecheck_FAIL)
1010 TYPECHECK_COUNTIF(changed,stat_merging_changed);
1015 destblock->flags = BBTYPECHECK_REACHED;
1016 if (destblock <= state->bptr) {
1018 state->repeat = true;
1024 /* typestate_ret ***************************************************************
1026 Reach the destinations of a RET instruction.
1029 state............current state of the verifier
1030 retindex.........index of local variable containing the returnAddress
1033 state->repeat....set to true if the verifier must iterate again
1034 over the basic blocks
1037 true.............success
1038 false............an exception has been thrown
1040 *******************************************************************************/
1043 typestate_ret(verifier_state *state,int retindex)
1046 typevector *selected;
1047 basicblock *destblock;
1049 for (yvec=state->localset; yvec; ) {
1050 if (!TYPEDESC_IS_RETURNADDRESS(yvec->td[retindex])) {
1051 *exceptionptr = new_verifyerror(state->m,"Illegal instruction: RET on non-returnAddress");
1055 destblock = (basicblock*) TYPEINFO_RETURNADDRESS(yvec->td[retindex].info);
1057 selected = typevectorset_select(&yvec,retindex,destblock);
1059 if (!typestate_reach(state,destblock,state->curstack,selected))
1065 /* typestate_save_instack ******************************************************
1067 Save the input stack of the current basic block in the "savedstackbuf"
1068 of the verifier state.
1070 This function must be called before an instruction modifies a stack slot
1071 that happens to be part of the instack of the current block. In such
1072 cases the instack of the block must be saved, and restored at the end
1073 of the analysis of this basic block, so that the instack again reflects
1074 the *input* to this basic block (and does not randomly contain types
1075 that appear within the block).
1078 state............current state of the verifier
1080 *******************************************************************************/
1083 typestate_save_instack(verifier_state *state)
1089 LOG("saving input stack types");
1090 if (!state->savedstackbuf) {
1091 LOG("allocating savedstack buffer");
1092 state->savedstackbuf = DMNEW(stackelement, state->cd->maxstack);
1093 state->savedstackbuf->prev = NULL;
1094 for (i = 1; i < state->cd->maxstack; ++i)
1095 state->savedstackbuf[i].prev = state->savedstackbuf+(i-1);
1097 sp = state->savedstack = state->bptr->instack;
1098 dest = state->bptr->instack = state->savedstackbuf + (state->bptr->indepth-1);
1100 for(; sp; sp=sp->prev, dest=dest->prev) {
1101 dest->type = sp->type;
1102 TYPEINFO_COPY(sp->typeinfo,dest->typeinfo);
1106 /* typestate_restore_instack ***************************************************
1108 Restore the input stack of the current basic block that has been previously
1109 saved by `typestate_save_instack`.
1112 state............current state of the verifier
1114 *******************************************************************************/
1117 typestate_restore_instack(verifier_state *state)
1122 TYPECHECK_COUNT(stat_savedstack);
1123 LOG("restoring saved instack");
1125 sp = state->bptr->instack;
1126 dest = state->savedstack;
1127 for(; sp; sp=sp->prev, dest=dest->prev) {
1128 dest->type = sp->type;
1129 TYPEINFO_COPY(sp->typeinfo,dest->typeinfo);
1132 state->bptr->instack = state->savedstack;
1133 state->savedstack = NULL;
1136 /****************************************************************************/
1138 /****************************************************************************/
1140 #define COPYTYPE(source,dest) \
1141 {if ((source)->type == TYPE_ADR) \
1142 TYPEINFO_COPY((source)->typeinfo,(dest)->typeinfo);}
1144 #define ISBUILTIN(v) (bte->fp == (functionptr) (v))
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 methodinfo *mi; /* resolved method (if any) */
1165 methoddesc *md; /* descriptor of the called method */
1166 utf *mname; /* method name */
1167 utf *mclassname; /* name of the method's class */
1168 bool specialmethod; /* true if a <...> method is called */
1169 int opcode; /* invocation opcode */
1170 bool callinginit; /* true if <init> is called */
1172 classref_or_classinfo initclass;
1174 stackelement *stack; /* temporary stack pointer */
1175 stackelement *dst; /* result stack of the invocation */
1176 int i; /* counter */
1177 u1 rtype; /* return type of called method */
1178 resolve_result_t result;
1180 if (state->iptr[0].target) { /* XXX used temporarily as flag */
1181 /* unresolved method */
1182 um = (unresolved_method *) state->iptr[0].val.a;
1183 mref = um->methodref;
1187 mref = (constant_FMIref *) state->iptr[0].val.a;
1190 md = mref->parseddesc.md;
1193 if (IS_FMIREF_RESOLVED(mref)) {
1194 mi = mref->p.method;
1195 mclassname = mi->class->name;
1199 mclassname = mref->p.classref->name;
1202 specialmethod = (mname->text[0] == '<');
1203 opcode = state->iptr[0].opc;
1204 dst = state->iptr->dst;
1206 /* prevent compiler warnings */
1210 /* check whether we are calling <init> */
1212 callinginit = (opcode == ICMD_INVOKESPECIAL && mname == utf_init);
1213 if (specialmethod && !callinginit)
1214 TYPECHECK_VERIFYERROR_bool("Invalid invocation of special method");
1216 /* allocate parameters if necessary */
1219 if (!descriptor_params_from_paramtypes(md,
1220 (opcode == ICMD_INVOKESTATIC) ? ACC_STATIC : ACC_NONE))
1223 /* check parameter types */
1225 stack = state->curstack;
1226 i = md->paramcount; /* number of parameters including 'this'*/
1229 td = md->paramtypes + i;
1230 if (stack->type != td->type)
1231 TYPECHECK_VERIFYERROR_bool("Parameter type mismatch in method invocation");
1232 if (stack->type == TYPE_ADR) {
1233 LOGINFO(&(stack->typeinfo));
1234 if (i==0 && callinginit)
1236 /* first argument to <init> method */
1237 if (!TYPEINFO_IS_NEWOBJECT(stack->typeinfo))
1238 TYPECHECK_VERIFYERROR_bool("Calling <init> on initialized object");
1240 /* get the address of the NEW instruction */
1241 LOGINFO(&(stack->typeinfo));
1242 ins = (instruction*)TYPEINFO_NEWOBJECT_INSTRUCTION(stack->typeinfo);
1244 initclass = CLASSREF_OR_CLASSINFO(ins[-1].target);
1246 initclass.cls = state->m->class;
1247 LOGSTR("class: "); LOGNAME(initclass); LOGNL;
1251 /* non-adress argument. if this is the first argument and we are */
1252 /* invoking an instance method, this is an error. */
1253 if (i==0 && opcode != ICMD_INVOKESTATIC) {
1254 TYPECHECK_VERIFYERROR_bool("Parameter type mismatch for 'this' argument");
1260 stack = stack->prev;
1263 LOG("checking return type");
1264 rtype = md->returntype.type;
1265 if (rtype != TYPE_VOID) {
1266 if (rtype != dst->type)
1267 TYPECHECK_VERIFYERROR_bool("Return type mismatch in method invocation");
1268 if (!typeinfo_init_from_typedesc(&(md->returntype),NULL,&(dst->typeinfo)))
1273 LOG("replacing uninitialized object");
1274 /* replace uninitialized object type on stack */
1277 if (stack->type == TYPE_ADR
1278 && TYPEINFO_IS_NEWOBJECT(stack->typeinfo)
1279 && TYPEINFO_NEWOBJECT_INSTRUCTION(stack->typeinfo) == ins)
1281 LOG("replacing uninitialized type on stack");
1283 /* If this stackslot is in the instack of
1284 * this basic block we must save the type(s)
1285 * we are going to replace.
1287 if (stack <= state->bptr->instack && !state->savedstack)
1288 typestate_save_instack(state);
1290 if (!typeinfo_init_class(&(stack->typeinfo),initclass))
1293 stack = stack->prev;
1295 /* replace uninitialized object type in locals */
1296 if (!typevectorset_init_object(state->localset,ins,initclass,state->numlocals))
1299 /* initializing the 'this' reference? */
1302 TYPECHECK_ASSERT(state->initmethod);
1303 /* { we are initializing the 'this' reference } */
1304 /* must be <init> of current class or direct superclass */
1305 /* the current class is linked, so must be its superclass. thus we can be */
1306 /* sure that resolving will be trivial. */
1311 if (!resolve_classref(state->m,mref->p.classref,resolveLazy,false,true,&cls))
1312 return false; /* exception */
1315 /* if lazy resolving did not succeed, it's not one of the allowed classes */
1316 /* otherwise we check it directly */
1317 if (cls == NULL || (cls != state->m->class && cls != state->m->class->super.cls)) {
1318 TYPECHECK_VERIFYERROR_bool("<init> calling <init> of the wrong class");
1321 /* set our marker variable to type int */
1322 LOG("setting <init> marker");
1323 typevectorset_store(state->localset,state->numlocals-1,TYPE_INT,NULL);
1326 /* { we are initializing an instance created with NEW } */
1327 if ((IS_CLASSREF(initclass) ? initclass.ref->name : initclass.cls->name) != mclassname) {
1328 TYPECHECK_VERIFYERROR_bool("wrong <init> called for uninitialized reference");
1333 /* try to resolve the method lazily */
1335 result = resolve_method_lazy(state->iptr,state->curstack,state->m);
1336 if (result == resolveFailed)
1339 if (result != resolveSucceeded) {
1341 um = create_unresolved_method(state->m->class,
1342 state->m, state->iptr);
1348 /* record subtype constraints for parameters */
1350 if (!constrain_unresolved_method(um,state->m->class,state->m,state->iptr,state->curstack))
1351 return false; /* XXX maybe wrap exception */
1353 /* store the unresolved_method pointer */
1355 /* XXX this will be changed */
1356 state->iptr->val.a = um;
1357 state->iptr->target = (void*)1; /* XXX used temporarily as flag */
1363 /* verify_generic_builtin ******************************************************
1365 Verify the call of a generic builtin method.
1368 state............the current state of the verifier
1371 true.............successful verification,
1372 false............an exception has been thrown.
1374 *******************************************************************************/
1377 verify_generic_builtin(verifier_state *state)
1379 builtintable_entry *bte;
1385 TYPECHECK_COUNT(stat_ins_builtin_gen);
1387 bte = (builtintable_entry *) state->iptr[0].val.a;
1391 /* check the types of the arguments on the stack */
1393 sp = state->curstack;
1394 for (i--; i >= 0; i--) {
1395 if (sp->type != md->paramtypes[i].type) {
1396 TYPECHECK_VERIFYERROR_bool("parameter type mismatch for builtin method");
1399 #ifdef TYPECHECK_DEBUG
1400 /* generic builtins may only take primitive types and java.lang.Object references */
1401 if (sp->type == TYPE_ADR && md->paramtypes[i].classref->name != utf_java_lang_Object) {
1402 *exceptionptr = new_internalerror("generic builtin method with non-generic reference parameter");
1410 /* check the return type */
1412 rtype = md->returntype.type;
1413 if (rtype != TYPE_VOID) {
1416 dst = state->iptr->dst;
1417 if (rtype != dst->type)
1418 TYPECHECK_VERIFYERROR_bool("Return type mismatch in generic builtin invocation");
1419 if (!typeinfo_init_from_typedesc(&(md->returntype),NULL,&(dst->typeinfo)))
1426 /* verify_builtin **************************************************************
1428 Verify the call of a builtin method.
1431 state............the current state of the verifier
1434 true.............successful verification,
1435 false............an exception has been thrown.
1437 *******************************************************************************/
1440 verify_builtin(verifier_state *state)
1442 builtintable_entry *bte;
1443 classref_or_classinfo cls;
1444 stackptr dst; /* output stack of current instruction */
1446 bte = (builtintable_entry *) state->iptr[0].val.a;
1447 dst = state->iptr->dst;
1449 /* XXX this is an ugly if-chain but twisti did not want a function */
1450 /* pointer in builtintable_entry for this, so here you go.. ;) */
1452 if (ISBUILTIN(BUILTIN_new)) {
1453 if (state->iptr[-1].opc != ICMD_ACONST)
1454 TYPECHECK_VERIFYERROR_bool("illegal instruction: builtin_new without class");
1455 cls.any = state->iptr[-1].target;
1456 TYPEINFO_INIT_NEWOBJECT(dst->typeinfo,state->iptr);
1458 else if (ISBUILTIN(BUILTIN_newarray_boolean)) {
1459 TYPECHECK_INT(state->curstack);
1460 TYPEINFO_INIT_PRIMITIVE_ARRAY(dst->typeinfo,ARRAYTYPE_BOOLEAN);
1462 else if (ISBUILTIN(BUILTIN_newarray_char)) {
1463 TYPECHECK_INT(state->curstack);
1464 TYPEINFO_INIT_PRIMITIVE_ARRAY(dst->typeinfo,ARRAYTYPE_CHAR);
1466 else if (ISBUILTIN(BUILTIN_newarray_float)) {
1467 TYPECHECK_INT(state->curstack);
1468 TYPEINFO_INIT_PRIMITIVE_ARRAY(dst->typeinfo,ARRAYTYPE_FLOAT);
1470 else if (ISBUILTIN(BUILTIN_newarray_double)) {
1471 TYPECHECK_INT(state->curstack);
1472 TYPEINFO_INIT_PRIMITIVE_ARRAY(dst->typeinfo,ARRAYTYPE_DOUBLE);
1474 else if (ISBUILTIN(BUILTIN_newarray_byte)) {
1475 TYPECHECK_INT(state->curstack);
1476 TYPEINFO_INIT_PRIMITIVE_ARRAY(dst->typeinfo,ARRAYTYPE_BYTE);
1478 else if (ISBUILTIN(BUILTIN_newarray_short)) {
1479 TYPECHECK_INT(state->curstack);
1480 TYPEINFO_INIT_PRIMITIVE_ARRAY(dst->typeinfo,ARRAYTYPE_SHORT);
1482 else if (ISBUILTIN(BUILTIN_newarray_int)) {
1483 TYPECHECK_INT(state->curstack);
1484 TYPEINFO_INIT_PRIMITIVE_ARRAY(dst->typeinfo,ARRAYTYPE_INT);
1486 else if (ISBUILTIN(BUILTIN_newarray_long)) {
1487 TYPECHECK_INT(state->curstack);
1488 TYPEINFO_INIT_PRIMITIVE_ARRAY(dst->typeinfo,ARRAYTYPE_LONG);
1490 else if (ISBUILTIN(BUILTIN_newarray))
1492 TYPECHECK_INT(state->curstack->prev);
1493 if (state->iptr[-1].opc != ICMD_ACONST || !state->iptr[-1].target)
1494 TYPECHECK_VERIFYERROR_bool("illegal instruction: builtin_newarray without class");
1495 /* XXX check that it is an array class(ref) */
1496 typeinfo_init_class(&(dst->typeinfo),CLASSREF_OR_CLASSINFO(state->iptr[-1].target));
1498 else if (ISBUILTIN(BUILTIN_arrayinstanceof))
1500 TYPECHECK_ADR(state->curstack->prev);
1501 if (state->iptr[-1].opc != ICMD_ACONST)
1502 TYPECHECK_VERIFYERROR_bool("illegal instruction: builtin_arrayinstanceof without class");
1503 /* XXX check that it is an array class(ref) */
1506 return verify_generic_builtin(state);
1511 /* verify_multianewarray *******************************************************
1513 Verify a MULTIANEWARRAY instruction.
1516 state............the current state of the verifier
1519 true.............successful verification,
1520 false............an exception has been thrown.
1522 *******************************************************************************/
1525 verify_multianewarray(verifier_state *state)
1528 classinfo *arrayclass;
1529 arraydescriptor *desc;
1532 /* check the array lengths on the stack */
1533 i = state->iptr[0].op1;
1535 TYPECHECK_VERIFYERROR_bool("Illegal dimension argument");
1537 sp = state->curstack;
1540 TYPECHECK_VERIFYERROR_bool("Unable to pop operand off an empty stack");
1545 /* check array descriptor */
1546 if (state->iptr[0].val.a != NULL) {
1547 /* the array class reference has already been resolved */
1548 arrayclass = (classinfo *) state->iptr[0].val.a;
1550 TYPECHECK_VERIFYERROR_bool("MULTIANEWARRAY with unlinked class");
1551 if ((desc = arrayclass->vftbl->arraydesc) == NULL)
1552 TYPECHECK_VERIFYERROR_bool("MULTIANEWARRAY with non-array class");
1553 if (desc->dimension < state->iptr[0].op1)
1554 TYPECHECK_VERIFYERROR_bool("MULTIANEWARRAY dimension to high");
1556 /* set the array type of the result */
1557 typeinfo_init_classinfo(&(state->iptr->dst->typeinfo), arrayclass);
1561 constant_classref *cr;
1563 /* the array class reference is still unresolved */
1564 /* check that the reference indicates an array class of correct dimension */
1565 cr = (constant_classref *) state->iptr[0].target;
1570 /* { the dimension of the array class == i } */
1572 TYPECHECK_VERIFYERROR_bool("MULTIANEWARRAY with non-array class");
1573 if (i < state->iptr[0].op1)
1574 TYPECHECK_VERIFYERROR_bool("MULTIANEWARRAY dimension to high");
1576 /* set the array type of the result */
1577 if (!typeinfo_init_class(&(state->iptr->dst->typeinfo),CLASSREF_OR_CLASSINFO(state->iptr[0].target)))
1585 /* verify_basic_block **********************************************************
1587 Perform bytecode verification of a basic block.
1590 state............the current state of the verifier
1593 true.............successful verification,
1594 false............an exception has been thrown.
1596 *******************************************************************************/
1599 verify_basic_block(verifier_state *state)
1601 int opcode; /* current opcode */
1602 int len; /* for counting instructions, etc. */
1603 bool superblockend; /* true if no fallthrough to next block */
1604 basicblock *tbptr; /* temporary for target block */
1605 stackptr dst; /* output stack of current instruction */
1606 basicblock **tptr; /* pointer into target list of switch instr. */
1607 classinfo *cls; /* temporary */
1608 bool maythrow; /* true if this instruction may throw */
1609 unresolved_field *uf; /* for field accesses */
1610 constant_FMIref *fieldref; /* for field accesses */
1614 resolve_result_t result;
1616 LOGSTR1("\n---- BLOCK %04d ------------------------------------------------\n",state->bptr->debug_nr);
1619 superblockend = false;
1620 state->bptr->flags = BBFINISHED;
1621 b_index = state->bptr - state->m->basicblocks;
1623 /* init stack at the start of this block */
1624 state->curstack = state->bptr->instack;
1626 /* prevent compiler warnings */
1630 /* determine the active exception handlers for this block */
1631 /* XXX could use a faster algorithm with sorted lists or */
1634 for (i = 0; i < state->cd->exceptiontablelength; ++i) {
1635 if ((state->cd->exceptiontable[i].start <= state->bptr) && (state->cd->exceptiontable[i].end > state->bptr)) {
1636 LOG1("active handler L%03d", state->cd->exceptiontable[i].handler->debug_nr);
1637 state->handlers[len++] = state->cd->exceptiontable + i;
1640 state->handlers[len] = NULL;
1642 /* init variable types at the start of this block */
1643 typevectorset_copy_inplace(MGET_TYPEVECTOR(state->localbuf,b_index,state->numlocals),
1644 state->localset,state->numlocals);
1646 /* XXX FIXME FOR INLINING */
1648 if (state->handlers[0])
1649 for (i=0; i<state->numlocals; ++i)
1650 if (state->localset->td[i].type == TYPE_ADR
1651 && TYPEINFO_IS_NEWOBJECT(state->localset->td[i].info)) {
1652 /* XXX we do not check this for the uninitialized 'this' instance in */
1653 /* <init> methods. Otherwise there are problems with try blocks in */
1654 /* <init>. The spec seems to indicate that we should perform the test*/
1655 /* in all cases, but this fails with real code. */
1656 /* Example: org/eclipse/ui/internal/PerspectiveBarNewContributionItem*/
1657 /* of eclipse 3.0.2 */
1658 if (TYPEINFO_NEWOBJECT_INSTRUCTION(state->localset->td[i].info) != NULL) {
1659 /*show_icmd_method(state->m, state->cd, state->rd);*/
1660 printf("Uninitialized variable: %d, block: %d\n", i, state->bptr->debug_nr);
1661 TYPECHECK_VERIFYERROR_bool("Uninitialized object in local variable inside try block");
1665 DOLOG(typestate_print(typecheck_logfile,state->curstack,state->localset,state->numlocals));
1668 /* loop over the instructions */
1669 len = state->bptr->icount;
1670 state->iptr = state->bptr->iinstr;
1671 while (--len >= 0) {
1672 TYPECHECK_COUNT(stat_ins);
1674 DOLOG(typestate_print(typecheck_logfile,state->curstack,state->localset,state->numlocals));
1677 DOLOG(show_icmd(state->iptr,false)); LOGNL; LOGFLUSH;
1679 opcode = state->iptr->opc;
1680 dst = state->iptr->dst;
1685 /****************************************/
1686 /* STACK MANIPULATIONS */
1688 /* We just need to copy the typeinfo */
1689 /* for slots containing addresses. */
1691 /* CAUTION: We assume that the destination stack
1692 * slots were continuously allocated in
1693 * memory! (The current implementation in
1698 TYPECHECK_COUNT(stat_ins_stack);
1699 COPYTYPE(state->curstack,dst);
1703 TYPECHECK_COUNT(stat_ins_stack);
1704 COPYTYPE(state->curstack,dst);
1705 COPYTYPE(state->curstack,dst-2);
1706 COPYTYPE(state->curstack->prev,dst-1);
1710 TYPECHECK_COUNT(stat_ins_stack);
1711 COPYTYPE(state->curstack,dst);
1712 COPYTYPE(state->curstack,dst-3);
1713 COPYTYPE(state->curstack->prev,dst-1);
1714 COPYTYPE(state->curstack->prev->prev,dst-2);
1718 TYPECHECK_COUNT(stat_ins_stack);
1719 COPYTYPE(state->curstack,dst);
1720 COPYTYPE(state->curstack->prev,dst-1);
1724 TYPECHECK_COUNT(stat_ins_stack);
1725 COPYTYPE(state->curstack,dst);
1726 COPYTYPE(state->curstack->prev,dst-1);
1727 COPYTYPE(state->curstack,dst-3);
1728 COPYTYPE(state->curstack->prev,dst-4);
1729 COPYTYPE(state->curstack->prev->prev,dst-2);
1733 TYPECHECK_COUNT(stat_ins_stack);
1734 COPYTYPE(state->curstack,dst);
1735 COPYTYPE(state->curstack->prev,dst-1);
1736 COPYTYPE(state->curstack,dst-4);
1737 COPYTYPE(state->curstack->prev,dst-5);
1738 COPYTYPE(state->curstack->prev->prev,dst-2);
1739 COPYTYPE(state->curstack->prev->prev->prev,dst-3);
1743 TYPECHECK_COUNT(stat_ins_stack);
1744 COPYTYPE(state->curstack,dst-1);
1745 COPYTYPE(state->curstack->prev,dst);
1748 /****************************************/
1749 /* PRIMITIVE VARIABLE ACCESS */
1751 case ICMD_ILOAD: if (!typevectorset_checktype(state->localset,state->iptr->op1,TYPE_INT))
1752 TYPECHECK_VERIFYERROR_bool("Local variable type mismatch");
1754 case ICMD_IINC: if (!typevectorset_checktype(state->localset,state->iptr->op1,TYPE_INT))
1755 TYPECHECK_VERIFYERROR_bool("Local variable type mismatch");
1757 case ICMD_FLOAD: if (!typevectorset_checktype(state->localset,state->iptr->op1,TYPE_FLOAT))
1758 TYPECHECK_VERIFYERROR_bool("Local variable type mismatch");
1760 case ICMD_LLOAD: if (!typevectorset_checktype(state->localset,state->iptr->op1,TYPE_LONG))
1761 TYPECHECK_VERIFYERROR_bool("Local variable type mismatch");
1763 case ICMD_DLOAD: if (!typevectorset_checktype(state->localset,state->iptr->op1,TYPE_DOUBLE))
1764 TYPECHECK_VERIFYERROR_bool("Local variable type mismatch");
1767 case ICMD_ISTORE: typevectorset_store(state->localset,state->iptr->op1,TYPE_INT,NULL); break;
1768 case ICMD_FSTORE: typevectorset_store(state->localset,state->iptr->op1,TYPE_FLOAT,NULL); break;
1769 case ICMD_LSTORE: typevectorset_store_twoword(state->localset,state->iptr->op1,TYPE_LONG); break;
1770 case ICMD_DSTORE: typevectorset_store_twoword(state->localset,state->iptr->op1,TYPE_DOUBLE); break;
1772 /****************************************/
1773 /* LOADING ADDRESS FROM VARIABLE */
1776 TYPECHECK_COUNT(stat_ins_aload);
1778 /* loading a returnAddress is not allowed */
1779 if (state->jsrencountered) {
1780 if (!typevectorset_checkreference(state->localset,state->iptr->op1)) {
1781 TYPECHECK_VERIFYERROR_bool("illegal instruction: ALOAD loading non-reference");
1783 if (typevectorset_copymergedtype(state->m,state->localset,state->iptr->op1,&(dst->typeinfo)) == -1)
1787 if (!TYPEDESC_IS_REFERENCE(state->localset->td[state->iptr->op1])) {
1788 TYPECHECK_VERIFYERROR_bool("illegal instruction: ALOAD loading non-reference");
1790 TYPEINFO_COPY(state->localset->td[state->iptr->op1].info,dst->typeinfo);
1794 /****************************************/
1795 /* STORING ADDRESS TO VARIABLE */
1798 if (state->handlers[0] && TYPEINFO_IS_NEWOBJECT(state->curstack->typeinfo)) {
1799 TYPECHECK_VERIFYERROR_bool("Storing uninitialized object in local variable inside try block");
1802 if (TYPESTACK_IS_RETURNADDRESS(state->curstack)) {
1803 typevectorset_store_retaddr(state->localset,state->iptr->op1,&(state->curstack->typeinfo));
1806 typevectorset_store(state->localset,state->iptr->op1,TYPE_ADDRESS,
1807 &(state->curstack->typeinfo));
1811 /****************************************/
1812 /* LOADING ADDRESS FROM ARRAY */
1815 if (!TYPEINFO_MAYBE_ARRAY_OF_REFS(state->curstack->prev->typeinfo))
1816 TYPECHECK_VERIFYERROR_bool("illegal instruction: AALOAD on non-reference array");
1818 if (!typeinfo_init_component(&state->curstack->prev->typeinfo,&dst->typeinfo))
1823 /****************************************/
1826 case ICMD_PUTFIELDCONST:
1827 case ICMD_PUTSTATICCONST:
1828 TYPECHECK_COUNT(stat_ins_field);
1830 if (INSTRUCTION_IS_UNRESOLVED(state->iptr + 1)) {
1831 uf = INSTRUCTION_UNRESOLVED_FIELD(state->iptr + 1);
1832 fieldref = uf->fieldref;
1836 fieldref = INSTRUCTION_RESOLVED_FMIREF(state->iptr + 1);
1839 goto fieldaccess_tail;
1842 case ICMD_PUTSTATIC:
1843 TYPECHECK_COUNT(stat_ins_field);
1845 if (INSTRUCTION_IS_UNRESOLVED(state->iptr)) {
1846 uf = INSTRUCTION_UNRESOLVED_FIELD(state->iptr);
1847 fieldref = uf->fieldref;
1851 fieldref = INSTRUCTION_RESOLVED_FMIREF(state->iptr);
1854 goto fieldaccess_tail;
1857 case ICMD_GETSTATIC:
1858 TYPECHECK_COUNT(stat_ins_field);
1860 if (INSTRUCTION_IS_UNRESOLVED(state->iptr)) {
1861 uf = INSTRUCTION_UNRESOLVED_FIELD(state->iptr);
1862 fieldref = uf->fieldref;
1866 fieldref = INSTRUCTION_RESOLVED_FMIREF(state->iptr);
1869 /* the result is pushed on the stack */
1870 if (dst->type == TYPE_ADR) {
1871 if (!typeinfo_init_from_typedesc(fieldref->parseddesc.fd,NULL,&(dst->typeinfo)))
1876 /* try to resolve the field reference lazily */
1877 result = resolve_field_lazy(state->iptr, state->curstack, state->m);
1878 if (result == resolveFailed)
1881 if (result != resolveSucceeded) {
1883 uf = create_unresolved_field(state->m->class, state->m, state->iptr);
1887 if (opcode == ICMD_PUTSTATICCONST || opcode == ICMD_PUTFIELDCONST) {
1888 state->iptr[1].val.a = uf;
1889 state->iptr[1].target = (void*)1; /* XXX target used temporarily as flag */
1892 state->iptr[0].val.a = uf;
1893 state->iptr[0].target = (void*)1; /* XXX target used temporarily as flag */
1897 /* record the subtype constraints for this field access */
1898 if (!constrain_unresolved_field(uf,state->m->class,state->m,state->iptr,state->curstack))
1899 return false; /* XXX maybe wrap exception? */
1901 TYPECHECK_COUNTIF(INSTRUCTION_IS_UNRESOLVED(state->iptr),stat_ins_field_unresolved);
1902 TYPECHECK_COUNTIF(INSTRUCTION_IS_RESOLVED(state->iptr) && !INSTRUCTION_RESOLVED_FIELDINFO(state->iptr)->class->initialized,stat_ins_field_uninitialized);
1908 /****************************************/
1909 /* PRIMITIVE ARRAY ACCESS */
1911 case ICMD_ARRAYLENGTH:
1912 if (!TYPEINFO_MAYBE_ARRAY(state->curstack->typeinfo)
1913 && state->curstack->typeinfo.typeclass.cls != pseudo_class_Arraystub)
1914 TYPECHECK_VERIFYERROR_bool("illegal instruction: ARRAYLENGTH on non-array");
1919 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->curstack->prev->typeinfo,ARRAYTYPE_BOOLEAN)
1920 && !TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->curstack->prev->typeinfo,ARRAYTYPE_BYTE))
1921 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1925 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->curstack->prev->typeinfo,ARRAYTYPE_CHAR))
1926 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1930 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->curstack->prev->typeinfo,ARRAYTYPE_DOUBLE))
1931 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1935 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->curstack->prev->typeinfo,ARRAYTYPE_FLOAT))
1936 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1940 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->curstack->prev->typeinfo,ARRAYTYPE_INT))
1941 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1945 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->curstack->prev->typeinfo,ARRAYTYPE_SHORT))
1946 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1950 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->curstack->prev->typeinfo,ARRAYTYPE_LONG))
1951 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1956 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->curstack->prev->prev->typeinfo,ARRAYTYPE_BOOLEAN)
1957 && !TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->curstack->prev->prev->typeinfo,ARRAYTYPE_BYTE))
1958 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1962 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->curstack->prev->prev->typeinfo,ARRAYTYPE_CHAR))
1963 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1967 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->curstack->prev->prev->typeinfo,ARRAYTYPE_DOUBLE))
1968 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1972 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->curstack->prev->prev->typeinfo,ARRAYTYPE_FLOAT))
1973 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1977 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->curstack->prev->prev->typeinfo,ARRAYTYPE_INT))
1978 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1982 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->curstack->prev->prev->typeinfo,ARRAYTYPE_SHORT))
1983 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1987 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->curstack->prev->prev->typeinfo,ARRAYTYPE_LONG))
1988 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1993 /* we just check the basic input types and that the */
1994 /* destination is an array of references. Assignability to */
1995 /* the actual array must be checked at runtime, each time the */
1996 /* instruction is performed. (See builtin_canstore.) */
1997 TYPECHECK_ADR(state->curstack);
1998 TYPECHECK_INT(state->curstack->prev);
1999 TYPECHECK_ADR(state->curstack->prev->prev);
2000 if (!TYPEINFO_MAYBE_ARRAY_OF_REFS(state->curstack->prev->prev->typeinfo))
2001 TYPECHECK_VERIFYERROR_bool("illegal instruction: AASTORE to non-reference array");
2005 case ICMD_IASTORECONST:
2006 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->curstack->prev->typeinfo, ARRAYTYPE_INT))
2007 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
2011 case ICMD_LASTORECONST:
2012 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->curstack->prev->typeinfo, ARRAYTYPE_LONG))
2013 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
2017 case ICMD_BASTORECONST:
2018 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->curstack->prev->typeinfo, ARRAYTYPE_BOOLEAN)
2019 && !TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->curstack->prev->typeinfo, ARRAYTYPE_BYTE))
2020 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
2024 case ICMD_CASTORECONST:
2025 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->curstack->prev->typeinfo, ARRAYTYPE_CHAR))
2026 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
2030 case ICMD_SASTORECONST:
2031 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->curstack->prev->typeinfo, ARRAYTYPE_SHORT))
2032 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
2036 /****************************************/
2037 /* ADDRESS CONSTANTS */
2040 if (state->iptr->target) {
2041 /* a java.lang.Class reference */
2042 TYPEINFO_INIT_JAVA_LANG_CLASS(dst->typeinfo,(constant_classref *)state->iptr->target);
2045 if (state->iptr->val.a == NULL)
2046 TYPEINFO_INIT_NULLTYPE(dst->typeinfo);
2048 /* string constant (or constant for builtin function) */
2049 typeinfo_init_classinfo(&(dst->typeinfo),class_java_lang_String);
2054 /****************************************/
2055 /* CHECKCAST AND INSTANCEOF */
2057 case ICMD_CHECKCAST:
2058 TYPECHECK_ADR(state->curstack);
2059 /* returnAddress is not allowed */
2060 if (!TYPEINFO_IS_REFERENCE(state->curstack->typeinfo))
2061 TYPECHECK_VERIFYERROR_bool("Illegal instruction: CHECKCAST on non-reference");
2063 cls = (classinfo *) state->iptr[0].val.a;
2065 typeinfo_init_classinfo(&(dst->typeinfo),cls);
2067 if (!typeinfo_init_class(&(dst->typeinfo),CLASSREF_OR_CLASSINFO(state->iptr[0].target)))
2072 case ICMD_INSTANCEOF:
2073 TYPECHECK_ADR(state->curstack);
2074 /* returnAddress is not allowed */
2075 if (!TYPEINFO_IS_REFERENCE(state->curstack->typeinfo))
2076 TYPECHECK_VERIFYERROR_bool("Illegal instruction: INSTANCEOF on non-reference");
2079 /****************************************/
2080 /* BRANCH INSTRUCTIONS */
2082 case ICMD_INLINE_GOTO:
2083 COPYTYPE(state->curstack,dst);
2086 superblockend = true;
2089 case ICMD_IFNONNULL:
2096 case ICMD_IF_ICMPEQ:
2097 case ICMD_IF_ICMPNE:
2098 case ICMD_IF_ICMPLT:
2099 case ICMD_IF_ICMPGE:
2100 case ICMD_IF_ICMPGT:
2101 case ICMD_IF_ICMPLE:
2102 case ICMD_IF_ACMPEQ:
2103 case ICMD_IF_ACMPNE:
2110 case ICMD_IF_LCMPEQ:
2111 case ICMD_IF_LCMPNE:
2112 case ICMD_IF_LCMPLT:
2113 case ICMD_IF_LCMPGE:
2114 case ICMD_IF_LCMPGT:
2115 case ICMD_IF_LCMPLE:
2116 TYPECHECK_COUNT(stat_ins_branch);
2117 tbptr = (basicblock *) state->iptr->target;
2119 /* propagate stack and variables to the target block */
2120 if (!typestate_reach(state,tbptr,dst,state->localset))
2124 /****************************************/
2127 case ICMD_TABLESWITCH:
2128 TYPECHECK_COUNT(stat_ins_switch);
2130 s4 *s4ptr = state->iptr->val.a;
2131 s4ptr++; /* skip default */
2132 i = *s4ptr++; /* low */
2133 i = *s4ptr++ - i + 2; /* +1 for default target */
2135 goto switch_instruction_tail;
2137 case ICMD_LOOKUPSWITCH:
2138 TYPECHECK_COUNT(stat_ins_switch);
2140 s4 *s4ptr = state->iptr->val.a;
2141 s4ptr++; /* skip default */
2142 i = *s4ptr++ + 1; /* count +1 for default */
2144 switch_instruction_tail:
2145 tptr = (basicblock **)state->iptr->target;
2149 LOG2("target %d is block %04d",(tptr-(basicblock **)state->iptr->target)-1,tbptr->debug_nr);
2150 if (!typestate_reach(state,tbptr,dst,state->localset))
2154 superblockend = true;
2157 /****************************************/
2158 /* ADDRESS RETURNS AND THROW */
2161 TYPECHECK_COUNT(stat_ins_athrow);
2162 r = typeinfo_is_assignable_to_class(&state->curstack->typeinfo,
2163 CLASSREF_OR_CLASSINFO(class_java_lang_Throwable));
2164 if (r == typecheck_FALSE)
2165 TYPECHECK_VERIFYERROR_bool("illegal instruction: ATHROW on non-Throwable");
2166 if (r == typecheck_FAIL)
2168 if (r == typecheck_MAYBE) {
2169 /* the check has to be postponed. we need a patcher */
2170 TYPECHECK_COUNT(stat_ins_athrow_unresolved);
2171 state->iptr->val.a = create_unresolved_class(
2173 /* XXX make this more efficient, use class_java_lang_Throwable
2175 class_get_classref(state->m->class,utf_java_lang_Throwable),
2176 &state->curstack->typeinfo);
2178 superblockend = true;
2183 TYPECHECK_COUNT(stat_ins_areturn);
2184 if (!TYPEINFO_IS_REFERENCE(state->curstack->typeinfo))
2185 TYPECHECK_VERIFYERROR_bool("illegal instruction: ARETURN on non-reference");
2187 if (state->returntype.type != TYPE_ADDRESS
2188 || (r = typeinfo_is_assignable(&state->curstack->typeinfo,&(state->returntype.info)))
2190 TYPECHECK_VERIFYERROR_bool("Return type mismatch");
2191 if (r == typecheck_FAIL)
2193 if (r == typecheck_MAYBE) {
2194 /* the check has to be postponed, we need a patcher */
2195 TYPECHECK_COUNT(stat_ins_areturn_unresolved);
2196 state->iptr->val.a = create_unresolved_class(
2198 state->m->parseddesc->returntype.classref,
2199 &state->curstack->typeinfo);
2203 /****************************************/
2204 /* PRIMITIVE RETURNS */
2207 if (state->returntype.type != TYPE_INT) TYPECHECK_VERIFYERROR_bool("Return type mismatch");
2211 if (state->returntype.type != TYPE_LONG) TYPECHECK_VERIFYERROR_bool("Return type mismatch");
2215 if (state->returntype.type != TYPE_FLOAT) TYPECHECK_VERIFYERROR_bool("Return type mismatch");
2219 if (state->returntype.type != TYPE_DOUBLE) TYPECHECK_VERIFYERROR_bool("Return type mismatch");
2223 if (state->returntype.type != TYPE_VOID) TYPECHECK_VERIFYERROR_bool("Return type mismatch");
2225 TYPECHECK_COUNT(stat_ins_primitive_return);
2227 if (state->initmethod && state->m->class != class_java_lang_Object) {
2228 /* Check if the 'this' instance has been initialized. */
2229 LOG("Checking <init> marker");
2230 if (!typevectorset_checktype(state->localset,state->numlocals-1,TYPE_INT))
2231 TYPECHECK_VERIFYERROR_bool("<init> method does not initialize 'this'");
2234 superblockend = true;
2238 /****************************************/
2239 /* SUBROUTINE INSTRUCTIONS */
2243 state->jsrencountered = true;
2245 /* This is a dirty hack. It is needed
2246 * because of the special handling of
2247 * ICMD_JSR in stack.c
2249 dst = (stackptr) state->iptr->val.a;
2251 tbptr = (basicblock *) state->iptr->target;
2252 if (state->bptr + 1 == (state->m->basicblocks + state->m->basicblockcount + 1))
2253 TYPECHECK_VERIFYERROR_bool("Illegal instruction: JSR at end of bytecode");
2254 typestack_put_retaddr(dst,state->bptr+1,state->localset);
2255 if (!typestate_reach(state,tbptr,dst,state->localset))
2258 superblockend = true;
2262 /* check returnAddress variable */
2263 if (!typevectorset_checkretaddr(state->localset,state->iptr->op1))
2264 TYPECHECK_VERIFYERROR_bool("illegal instruction: RET using non-returnAddress variable");
2266 if (!typestate_ret(state,state->iptr->op1))
2269 superblockend = true;
2272 /****************************************/
2275 case ICMD_INVOKEVIRTUAL:
2276 case ICMD_INVOKESPECIAL:
2277 case ICMD_INVOKESTATIC:
2278 case ICMD_INVOKEINTERFACE:
2279 TYPECHECK_COUNT(stat_ins_invoke);
2280 if (!verify_invocation(state))
2282 TYPECHECK_COUNTIF(!state->iptr[0].val.a,stat_ins_invoke_unresolved);
2286 /****************************************/
2287 /* MULTIANEWARRAY */
2289 case ICMD_MULTIANEWARRAY:
2290 if (!verify_multianewarray(state))
2295 /****************************************/
2299 TYPECHECK_COUNT(stat_ins_builtin);
2300 if (!verify_builtin(state))
2305 /****************************************/
2306 /* SIMPLE EXCEPTION THROWING TESTS */
2308 case ICMD_CHECKNULL:
2309 /* CHECKNULL just requires that the stack top
2310 * is an address. This is checked in stack.c */
2314 /****************************************/
2315 /* INSTRUCTIONS WHICH SHOULD HAVE BEEN */
2316 /* REPLACED BY OTHER OPCODES */
2318 #ifdef TYPECHECK_DEBUG
2321 case ICMD_ANEWARRAY:
2322 case ICMD_MONITORENTER:
2323 case ICMD_MONITOREXIT:
2324 LOG2("ICMD %d at %d\n", state->iptr->opc, (int)(state->iptr-state->bptr->iinstr));
2325 LOG("Should have been converted to builtin function call.");
2326 TYPECHECK_ASSERT(false);
2330 /****************************************/
2331 /* UNCHECKED OPERATIONS */
2333 /*********************************************
2334 * Instructions below...
2335 * *) don't operate on local variables,
2336 * *) don't operate on references,
2337 * *) don't operate on returnAddresses,
2338 * *) don't affect control flow (except
2339 * by throwing exceptions).
2341 * (These instructions are typechecked in
2343 ********************************************/
2345 /* Instructions which may throw a runtime exception: */
2355 /* Instructions which never throw a runtime exception: */
2356 #if defined(TYPECHECK_DEBUG) || defined(TYPECHECK_STATISTICS)
2366 case ICMD_IFEQ_ICONST:
2367 case ICMD_IFNE_ICONST:
2368 case ICMD_IFLT_ICONST:
2369 case ICMD_IFGE_ICONST:
2370 case ICMD_IFGT_ICONST:
2371 case ICMD_IFLE_ICONST:
2372 case ICMD_ELSE_ICONST:
2398 case ICMD_IADDCONST:
2399 case ICMD_ISUBCONST:
2400 case ICMD_IMULCONST:
2401 case ICMD_IANDCONST:
2403 case ICMD_IXORCONST:
2404 case ICMD_ISHLCONST:
2405 case ICMD_ISHRCONST:
2406 case ICMD_IUSHRCONST:
2408 case ICMD_LADDCONST:
2409 case ICMD_LSUBCONST:
2410 case ICMD_LMULCONST:
2411 case ICMD_LANDCONST:
2413 case ICMD_LXORCONST:
2414 case ICMD_LSHLCONST:
2415 case ICMD_LSHRCONST:
2416 case ICMD_LUSHRCONST:
2433 case ICMD_INT2SHORT:
2436 case ICMD_LCMPCONST:
2455 case ICMD_INLINE_START:
2456 case ICMD_INLINE_END:
2458 /*XXX What shall we do with the following ?*/
2459 case ICMD_AASTORECONST:
2460 TYPECHECK_COUNT(stat_ins_unchecked);
2463 /****************************************/
2466 LOG2("ICMD %d at %d\n", state->iptr->opc, (int)(state->iptr-state->bptr->iinstr));
2467 TYPECHECK_VERIFYERROR_bool("Missing ICMD code during typecheck");
2471 /* the output of this instruction becomes the current stack */
2472 state->curstack = dst;
2474 /* reach exception handlers for this instruction */
2476 TYPECHECK_COUNT(stat_ins_maythrow);
2477 TYPECHECK_MARK(state->stat_maythrow);
2478 LOG("reaching exception handlers");
2480 while (state->handlers[i]) {
2481 TYPECHECK_COUNT(stat_handlers_reached);
2482 if (state->handlers[i]->catchtype.any)
2483 state->excstack.typeinfo.typeclass = state->handlers[i]->catchtype;
2485 state->excstack.typeinfo.typeclass.cls = class_java_lang_Throwable;
2486 if (!typestate_reach(state,
2487 state->handlers[i]->handler,
2488 &(state->excstack),state->localset))
2494 LOG("next instruction");
2496 } /* while instructions */
2498 LOG("instructions done");
2499 LOGSTR("RESULT=> ");
2500 DOLOG(typestate_print(typecheck_logfile,state->curstack,state->localset,state->numlocals));
2503 /* propagate stack and variables to the following block */
2504 if (!superblockend) {
2505 LOG("reaching following block");
2506 tbptr = state->bptr + 1;
2507 while (tbptr->flags == BBDELETED) {
2509 #ifdef TYPECHECK_DEBUG
2510 /* this must be checked in parse.c */
2511 if ((tbptr->debug_nr) >= state->m->basicblockcount)
2512 TYPECHECK_VERIFYERROR_bool("Control flow falls off the last block");
2515 if (!typestate_reach(state,tbptr,dst,state->localset))
2519 /* We may have to restore the types of the instack slots. They
2520 * have been saved if an <init> call inside the block has
2521 * modified the instack types. (see INVOKESPECIAL) */
2523 if (state->savedstack)
2524 typestate_restore_instack(state);
2529 /* verify_init_locals **********************************************************
2531 Initialize the local variables in the verifier state.
2534 state............the current state of the verifier
2537 true.............success,
2538 false............an exception has been thrown.
2540 *******************************************************************************/
2543 verify_init_locals(verifier_state *state)
2549 /* initialize the variable types of the first block */
2550 /* to the types of the arguments */
2552 lset = MGET_TYPEVECTOR(state->localbuf,0,state->numlocals);
2556 i = state->validlocals;
2558 /* allocate parameter descriptors if necessary */
2560 if (!state->m->parseddesc->params)
2561 if (!descriptor_params_from_paramtypes(state->m->parseddesc,state->m->flags))
2564 /* if this is an instance method initialize the "this" ref type */
2566 if (!(state->m->flags & ACC_STATIC)) {
2568 TYPECHECK_VERIFYERROR_bool("Not enough local variables for method arguments");
2569 td->type = TYPE_ADDRESS;
2570 if (state->initmethod)
2571 TYPEINFO_INIT_NEWOBJECT(td->info,NULL);
2573 typeinfo_init_classinfo(&(td->info), state->m->class);
2578 LOG("'this' argument set.\n");
2580 /* the rest of the arguments and the return type */
2582 i = typedescriptors_init_from_methoddesc(td, state->m->parseddesc,
2584 true, /* two word types use two slots */
2585 (td - lset->td), /* skip 'this' pointer */
2586 &state->returntype);
2591 /* variables not used for arguments are initialized to TYPE_VOID */
2593 i = state->numlocals - (td - lset->td);
2595 td->type = TYPE_VOID;
2599 LOG("Arguments set.\n");
2603 /* typecheck_init_flags ********************************************************
2605 Initialize the basic block flags for the following CFG traversal.
2608 state............the current state of the verifier
2610 *******************************************************************************/
2613 typecheck_init_flags(verifier_state *state)
2618 /* set all BBFINISHED blocks to BBTYPECHECK_UNDEF. */
2620 i = state->m->basicblockcount;
2621 block = state->m->basicblocks;
2625 #ifdef TYPECHECK_DEBUG
2626 /* check for invalid flags */
2627 if (block->flags != BBFINISHED && block->flags != BBDELETED && block->flags != BBUNDEF)
2629 /*show_icmd_method(state->cd->method,state->cd,state->rd);*/
2630 LOGSTR1("block flags: %d\n",block->flags); LOGFLUSH;
2631 TYPECHECK_ASSERT(false);
2635 if (block->flags >= BBFINISHED) {
2636 block->flags = BBTYPECHECK_UNDEF;
2641 /* the first block is always reached */
2643 if (state->m->basicblockcount && state->m->basicblocks[0].flags == BBTYPECHECK_UNDEF)
2644 state->m->basicblocks[0].flags = BBTYPECHECK_REACHED;
2647 /* typecheck_reset_flags *******************************************************
2649 Reset the flags of basic blocks we have not reached.
2652 state............the current state of the verifier
2654 *******************************************************************************/
2657 typecheck_reset_flags(verifier_state *state)
2661 /* check for invalid flags at exit */
2663 #ifdef TYPECHECK_DEBUG
2664 for (i=0; i<state->m->basicblockcount; ++i) {
2665 if (state->m->basicblocks[i].flags != BBDELETED
2666 && state->m->basicblocks[i].flags != BBUNDEF
2667 && state->m->basicblocks[i].flags != BBFINISHED
2668 && state->m->basicblocks[i].flags != BBTYPECHECK_UNDEF) /* typecheck may never reach
2669 * some exception handlers,
2672 LOG2("block L%03d has invalid flags after typecheck: %d",
2673 state->m->basicblocks[i].debug_nr,state->m->basicblocks[i].flags);
2674 TYPECHECK_ASSERT(false);
2679 /* Reset blocks we never reached */
2681 for (i=0; i<state->m->basicblockcount; ++i) {
2682 if (state->m->basicblocks[i].flags == BBTYPECHECK_UNDEF)
2683 state->m->basicblocks[i].flags = BBFINISHED;
2687 /****************************************************************************/
2689 /* This is the main function of the bytecode verifier. It is called */
2690 /* directly after analyse_stack. */
2693 /* meth.............the method to verify */
2694 /* cdata............codegendata for the method */
2695 /* rdata............registerdata for the method */
2698 /* true.............successful verification */
2699 /* false............an exception has been thrown */
2702 /* Bytecode verification has not been tested with inlining and */
2703 /* probably does not work correctly with inlining. */
2704 /****************************************************************************/
2706 #define MAXPARAMS 255
2708 bool typecheck(jitdata *jd)
2713 verifier_state state; /* current state of the verifier */
2714 int i; /* temporary counter */
2716 /* collect statistics */
2718 #ifdef TYPECHECK_STATISTICS
2719 int count_iterations = 0;
2720 TYPECHECK_COUNT(stat_typechecked);
2721 TYPECHECK_COUNT_FREQ(stat_locals,cdata->maxlocals,STAT_LOCALS);
2722 TYPECHECK_COUNT_FREQ(stat_blocks,cdata->method->basicblockcount/10,STAT_BLOCKS);
2723 TYPECHECK_COUNTIF(cdata->method->exceptiontablelength != 0,stat_methods_with_handlers);
2724 state.stat_maythrow = false;
2727 /* get required compiler data */
2733 /* some logging on entry */
2735 DOLOG(typecheck_logfile = stdout);
2736 LOGSTR("\n==============================================================================\n");
2737 /*DOLOG( show_icmd_method(cdata->method,cdata,rdata));*/
2738 LOGSTR("\n==============================================================================\n");
2739 LOGMETHOD("Entering typecheck: ",cdata->method);
2741 /* initialize the verifier state */
2743 state.savedstackbuf = NULL;
2744 state.savedstack = NULL;
2745 state.jsrencountered = false;
2750 /* check if this method is an instance initializer method */
2752 state.initmethod = (state.m->name == utf_init);
2754 /* initialize the basic block flags for the following CFG traversal */
2756 typecheck_init_flags(&state);
2758 /* number of local variables */
2760 /* In <init> methods we use an extra local variable to indicate whether */
2761 /* the 'this' reference has been initialized. */
2762 /* TYPE_VOID...means 'this' has not been initialized, */
2763 /* TYPE_INT....means 'this' has been initialized. */
2764 state.numlocals = state.cd->maxlocals;
2765 state.validlocals = state.numlocals;
2766 if (state.initmethod) state.numlocals++;
2768 /* allocate the buffers for local variables */
2770 state.localbuf = DMNEW_TYPEVECTOR(state.m->basicblockcount+1, state.numlocals);
2771 state.localset = MGET_TYPEVECTOR(state.localbuf,state.m->basicblockcount,state.numlocals);
2773 LOG("Variable buffer allocated.\n");
2775 /* allocate the buffer of active exception handlers */
2777 state.handlers = DMNEW(exceptiontable*, state.cd->exceptiontablelength + 1);
2779 /* initialized local variables of first block */
2781 if (!verify_init_locals(&state))
2784 /* initialize the input stack of exception handlers */
2786 state.excstack.prev = NULL;
2787 state.excstack.type = TYPE_ADR;
2788 typeinfo_init_classinfo(&(state.excstack.typeinfo),
2789 class_java_lang_Throwable); /* changed later */
2791 LOG("Exception handler stacks set.\n");
2793 /* loop while there are still blocks to be checked */
2795 TYPECHECK_COUNT(count_iterations);
2797 state.repeat = false;
2799 i = state.m->basicblockcount;
2800 state.bptr = state.m->basicblocks;
2803 LOGSTR1("---- BLOCK %04d, ",state.bptr->debug_nr);
2804 LOGSTR1("blockflags: %d\n",state.bptr->flags);
2807 /* verify reached block */
2808 if (state.bptr->flags == BBTYPECHECK_REACHED) {
2809 if (!verify_basic_block(&state))
2813 } /* while blocks */
2815 LOGIF(state.repeat,"state.repeat == true");
2816 } while (state.repeat);
2820 #ifdef TYPECHECK_STATISTICS
2821 LOG1("Typechecker did %4d iterations",count_iterations);
2822 TYPECHECK_COUNT_FREQ(stat_iterations,count_iterations,STAT_ITERATIONS);
2823 TYPECHECK_COUNTIF(state.jsrencountered,stat_typechecked_jsr);
2824 TYPECHECK_COUNTIF(state.stat_maythrow,stat_methods_maythrow);
2827 /* reset the flags of blocks we haven't reached */
2829 typecheck_reset_flags(&state);
2831 /* everything's ok */
2833 LOGimp("exiting typecheck");
2837 #endif /* ENABLE_VERIFIER */
2840 * These are local overrides for various environment variables in Emacs.
2841 * Please do not remove this and leave it at the end of the file, where
2842 * Emacs will automagically detect them.
2843 * ---------------------------------------------------------------------
2846 * indent-tabs-mode: t
2850 * vim:noexpandtab:sw=4:ts=4: