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 5435 2006-09-08 18:14:50Z 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/show.h"
183 #include "vm/access.h"
184 #include "vm/resolve.h"
185 #include "vm/exceptions.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 opt_typecheckverbose = false;
199 FILE *typecheck_logfile;
200 #define DOLOG(action) do { if (opt_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 exceptions_throw_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 exceptions_throw_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 instruction *iptr; /* pointer to current instruction */
434 basicblock *bptr; /* pointer to current basic block */
436 methodinfo *m; /* the current method */
437 jitdata *jd; /* jitdata for current method */
438 codegendata *cd; /* codegendata for current method */
439 registerdata *rd; /* registerdata for current method */
441 basicblock *basicblocks;
444 s4 numlocals; /* number of local variables */
445 s4 validlocals; /* number of Java-accessible locals */
446 void *localbuf; /* local variable types for each block start */
447 typevector *localset; /* typevector set for local variables */
448 typedescriptor returntype; /* return type of the current method */
450 stackptr savedstackbuf; /* buffer for saving the stack */
451 stackptr savedstack; /* saved instack of current block */
453 exceptiontable **handlers; /* active exception handlers */
454 stackelement excstack; /* instack for exception handlers */
456 bool repeat; /* if true, blocks are iterated over again */
457 bool initmethod; /* true if this is an "<init>" method */
458 bool jsrencountered; /* true if we there was a JSR */
460 #ifdef TYPECHECK_STATISTICS
461 bool stat_maythrow; /* at least one instruction may throw */
465 /****************************************************************************/
466 /* TYPESTACK MACROS AND FUNCTIONS */
468 /* These macros and functions act on the 'type stack', which is a shorthand */
469 /* for the types of the stackslots of the current stack. The type of a */
470 /* stack slot is usually described by a TYPE_* constant and -- for TYPE_ADR */
471 /* -- by the typeinfo of the slot. The only thing that makes the type stack */
472 /* more complicated are returnAddresses of local subroutines, because a */
473 /* single stack slot may contain a set of more than one possible return */
474 /* address. This is handled by 'return address sets'. A return address set */
475 /* is kept as a linked list dangling off the typeinfo of the stack slot. */
476 /****************************************************************************/
478 #define TYPESTACK_IS_RETURNADDRESS(sptr) \
479 TYPE_IS_RETURNADDRESS((sptr)->type,(sptr)->typeinfo)
481 #define TYPESTACK_RETURNADDRESSSET(sptr) \
482 ((typeinfo_retaddr_set*)TYPEINFO_RETURNADDRESS((sptr)->typeinfo))
484 #define RETURNADDRESSSET_SEEK(set,pos) \
485 do {int i; for (i=pos;i--;) set=set->alt;} while(0)
487 /* typestack_copy **************************************************************
489 Copy the types on the given stack to the destination stack.
491 This function does a straight forward copy except for returnAddress types.
492 For returnAddress slots only the return addresses corresponding to
493 typevectors in the SELECTED set are copied.
496 state............current verifier state
497 y................stack with types to copy
498 selected.........set of selected typevectors
501 *dst.............the destination stack
504 true.............success
505 false............an exception has been thrown
507 *******************************************************************************/
510 typestack_copy(verifier_state *state,stackptr dst,stackptr y,typevector *selected)
513 typeinfo_retaddr_set *sety;
514 typeinfo_retaddr_set *new;
515 typeinfo_retaddr_set **next;
518 for (;dst; dst=dst->prev, y=y->prev) {
519 /* XXX only check the following two in debug mode? */
521 exceptions_throw_verifyerror(state->m,"Stack depth mismatch");
524 if (dst->type != y->type) {
525 exceptions_throw_verifyerror(state->m,"Stack type mismatch");
528 LOG3("copy %p -> %p (type %d)",y,dst,dst->type);
529 if (dst->type == TYPE_ADR) {
530 if (TYPEINFO_IS_PRIMITIVE(y->typeinfo)) {
531 /* We copy the returnAddresses from the selected
534 LOG("copying returnAddress");
535 sety = TYPESTACK_RETURNADDRESSSET(y);
537 for (k=0,sel=selected; sel; sel=sel->alt) {
538 LOG1("selected k=%d",sel->k);
543 *next = DNEW(typeinfo_retaddr_set);
544 (*next)->addr = sety->addr;
545 next = &((*next)->alt);
548 TYPEINFO_INIT_RETURNADDRESS(dst->typeinfo,new);
551 TYPEINFO_CLONE(y->typeinfo,dst->typeinfo);
556 exceptions_throw_verifyerror(state->m,"Stack depth mismatch");
562 /* typestack_put_retaddr *******************************************************
564 Put a returnAddress into a stack slot.
566 The stack slot receives a set of return addresses with as many members as
567 there are typevectors in the local variable set.
570 retaddr..........the returnAddress to set (a basicblock *)
571 loc..............the local variable typevector set
574 *dst.............the destination stack slot
576 *******************************************************************************/
579 typestack_put_retaddr(stackptr dst,void *retaddr,typevector *loc)
581 TYPECHECK_ASSERT(dst->type == TYPE_ADR);
583 TYPEINFO_INIT_RETURNADDRESS(dst->typeinfo,NULL);
584 for (;loc; loc=loc->alt) {
585 typeinfo_retaddr_set *set = DNEW(typeinfo_retaddr_set);
587 set->alt = TYPESTACK_RETURNADDRESSSET(dst);
588 TYPEINFO_INIT_RETURNADDRESS(dst->typeinfo,set);
592 /* typestack_collapse **********************************************************
594 Collapse the given stack by shortening all return address sets to a single
598 *dst.............the destination stack to collapse
600 *******************************************************************************/
603 typestack_collapse(stackptr dst)
605 for (; dst; dst = dst->prev) {
606 if (TYPESTACK_IS_RETURNADDRESS(dst))
607 TYPESTACK_RETURNADDRESSSET(dst)->alt = NULL;
611 /* typestack_merge *************************************************************
613 Merge the types on one stack into the destination stack.
616 state............current state of the verifier
617 dst..............the destination stack
618 y................the second stack
621 *dst.............receives the result of the stack merge
624 typecheck_TRUE...*dst has been modified
625 typecheck_FALSE..*dst has not been modified
626 typecheck_FAIL...an exception has been thrown
628 *******************************************************************************/
630 static typecheck_result
631 typestack_merge(verifier_state *state,stackptr dst,stackptr y)
634 bool changed = false;
636 for (; dst; dst = dst->prev, y=y->prev) {
638 exceptions_throw_verifyerror(state->m,"Stack depth mismatch");
639 return typecheck_FAIL;
641 if (dst->type != y->type) {
642 exceptions_throw_verifyerror(state->m,"Stack type mismatch");
643 return typecheck_FAIL;
645 if (dst->type == TYPE_ADR) {
646 if (TYPEINFO_IS_PRIMITIVE(dst->typeinfo)) {
647 /* dst has returnAddress type */
648 if (!TYPEINFO_IS_PRIMITIVE(y->typeinfo)) {
649 exceptions_throw_verifyerror(state->m,"Merging returnAddress with reference");
650 return typecheck_FAIL;
654 /* dst has reference type */
655 if (TYPEINFO_IS_PRIMITIVE(y->typeinfo)) {
656 exceptions_throw_verifyerror(state->m,"Merging reference with returnAddress");
657 return typecheck_FAIL;
659 r = typeinfo_merge(state->m,&(dst->typeinfo),&(y->typeinfo));
660 if (r == typecheck_FAIL)
667 exceptions_throw_verifyerror(state->m,"Stack depth mismatch");
668 return typecheck_FAIL;
673 /* typestack_add ***************************************************************
675 Add the return addresses in the given stack at a given k-index to the
676 corresponding return address sets in the destination stack.
679 dst..............the destination stack
680 y................the second stack
681 ky...............the k-index which should be selected from the Y stack
684 *dst.............receives the result of adding the addresses
686 *******************************************************************************/
689 typestack_add(stackptr dst,stackptr y,int ky)
691 typeinfo_retaddr_set *setd;
692 typeinfo_retaddr_set *sety;
694 for (; dst; dst = dst->prev, y=y->prev) {
695 if (TYPESTACK_IS_RETURNADDRESS(dst)) {
696 setd = TYPESTACK_RETURNADDRESSSET(dst);
697 sety = TYPESTACK_RETURNADDRESSSET(y);
698 RETURNADDRESSSET_SEEK(sety,ky);
701 setd->alt = DNEW(typeinfo_retaddr_set);
702 setd->alt->addr = sety->addr;
703 setd->alt->alt = NULL;
708 /* typestack_separable_with ****************************************************
710 This function answers the question: If variant 'kb' of typestack 'b' is
711 added to typestack 'a', will the result be separable?
713 A typestack is called 'separable' if it has at least one slot of type
714 returnAddress that contains at least two different return addresses.
715 (ie. a RET using the value in this slot could go to more than one target)
718 a................the first typestack
719 b................the second typestack
720 kb...............the k-index of the variant that should be selected
724 true.............the result would be separable
725 false............the result would not be separable
728 'a' and 'b' are assumed to have passed typestack_canmerge!
730 *******************************************************************************/
733 typestack_separable_with(stackptr a,stackptr b,int kb)
735 typeinfo_retaddr_set *seta;
736 typeinfo_retaddr_set *setb;
738 for (; a; a = a->prev, b = b->prev) {
740 if (TYPESTACK_IS_RETURNADDRESS(a)) {
741 TYPECHECK_ASSERT(TYPESTACK_IS_RETURNADDRESS(b));
742 seta = TYPESTACK_RETURNADDRESSSET(a);
743 setb = TYPESTACK_RETURNADDRESSSET(b);
744 RETURNADDRESSSET_SEEK(setb,kb);
746 for (;seta;seta=seta->alt)
747 if (seta->addr != setb->addr) return true;
750 TYPECHECK_ASSERT(!b);
754 /* typestack_separable_from ****************************************************
756 This function answers the question: Is variant 'ka' of typestack 'a'
757 separable from variant 'kb' of typestack 'b'?
759 Two variants of typestacks are called 'separable' from each other, if there
760 is at least one slot for which the variants contain different return addresses.
761 (ie. a RET using the value in this slot would go to one target in the first
762 variant and to another target in the second variant)
765 a................the first typestack
766 ka...............the k-index of the variant that should be selected
768 b................the second typestack
769 kb...............the k-index of the variant that should be selected
773 true.............the variants are separable
774 false............the variants are not separable
777 'a' and 'b' are assumed to have passed typestack_canmerge!
779 *******************************************************************************/
782 typestack_separable_from(stackptr a,int ka,stackptr b,int kb)
784 typeinfo_retaddr_set *seta;
785 typeinfo_retaddr_set *setb;
787 for (; a; a = a->prev, b = b->prev) {
789 if (TYPESTACK_IS_RETURNADDRESS(a)) {
790 TYPECHECK_ASSERT(TYPESTACK_IS_RETURNADDRESS(b));
791 seta = TYPESTACK_RETURNADDRESSSET(a);
792 setb = TYPESTACK_RETURNADDRESSSET(b);
793 RETURNADDRESSSET_SEEK(seta,ka);
794 RETURNADDRESSSET_SEEK(setb,kb);
796 if (seta->addr != setb->addr) return true;
799 TYPECHECK_ASSERT(!b);
803 /****************************************************************************/
804 /* TYPESTATE FUNCTIONS */
806 /* These functions act on the 'type state', which comprises: */
807 /* - the types of the stack slots of the current stack */
808 /* - the set of type vectors describing the local variables */
809 /****************************************************************************/
811 /* typestate_merge *************************************************************
813 Merge the types of one state into the destination state.
816 state............current state of the verifier
817 deststack........the destination stack
818 destloc..........the destination set of local variable typevectors
819 ystack...........the second stack
820 yloc.............the second set of local variable typevectors
823 *deststack.......receives the result of the stack merge
824 *destloc.........receives the result of the local variable merge
827 typecheck_TRUE...destination state has been modified
828 typecheck_FALSE..destination state has not been modified
829 typecheck_FAIL...an exception has been thrown
831 *******************************************************************************/
833 static typecheck_result
834 typestate_merge(verifier_state *state,
835 stackptr deststack,typevector *destloc,
836 stackptr ystack,typevector *yloc)
838 typevector *dvec,*yvec;
840 bool changed = false;
844 LOGSTR("dstack: "); DOLOG(typestack_print(typecheck_logfile,deststack)); LOGNL;
845 LOGSTR("ystack: "); DOLOG(typestack_print(typecheck_logfile,ystack)); LOGNL;
846 LOGSTR("dloc : "); DOLOG(typevectorset_print(typecheck_logfile,destloc,state->numlocals)); LOGNL;
847 LOGSTR("yloc : "); DOLOG(typevectorset_print(typecheck_logfile,yloc,state->numlocals)); LOGNL;
850 /* The stack is always merged. If there are returnAddresses on
851 * the stack they are ignored in this step. */
853 r = typestack_merge(state,deststack,ystack);
854 if (r == typecheck_FAIL)
858 /* If there have not been any JSRs we just have a single typevector merge */
859 if (!state->jsrencountered) {
860 r = typevector_merge(state->m,destloc,yloc,state->numlocals);
861 if (r == typecheck_FAIL)
866 for (yvec=yloc; yvec; yvec=yvec->alt) {
869 /* Check if the typestates (deststack,destloc) will be
870 * separable when (ystack,yvec) is added. */
872 if (!typestack_separable_with(deststack,ystack,ky)
873 && !typevectorset_separable_with(destloc,yvec,state->numlocals))
875 /* No, the resulting set won't be separable, thus we
876 * may merge all states in (deststack,destloc) and
879 typestack_collapse(deststack);
880 if (typevectorset_collapse(state->m,destloc,state->numlocals) == typecheck_FAIL)
881 return typecheck_FAIL;
882 if (typevector_merge(state->m,destloc,yvec,state->numlocals) == typecheck_FAIL)
883 return typecheck_FAIL;
886 /* Yes, the resulting set will be separable. Thus we check
887 * if we may merge (ystack,yvec) with a single state in
888 * (deststack,destloc). */
890 for (dvec=destloc,kd=0; dvec; dvec=dvec->alt, kd++) {
891 if (!typestack_separable_from(ystack,ky,deststack,kd)
892 && !typevector_separable_from(yvec,dvec,state->numlocals))
894 /* The typestate (ystack,yvec) is not separable from
895 * (deststack,dvec) by any returnAddress. Thus we may
896 * merge the states. */
898 r = typevector_merge(state->m,dvec,yvec,state->numlocals);
899 if (r == typecheck_FAIL)
907 /* The typestate (ystack,yvec) is separable from all typestates
908 * (deststack,destloc). Thus we must add this state to the
911 typestack_add(deststack,ystack,ky);
912 typevectorset_add(destloc,yvec,state->numlocals);
921 LOGSTR("dstack: "); DOLOG(typestack_print(typecheck_logfile,deststack)); LOGNL;
922 LOGSTR("dloc : "); DOLOG(typevectorset_print(typecheck_logfile,destloc,state->numlocals)); LOGNL;
928 /* typestate_reach *************************************************************
930 Reach a destination block and propagate stack and local variable types
933 state............current state of the verifier
934 destblock........destination basic block
935 ystack...........stack to propagate
936 yloc.............set of local variable typevectors to propagate
939 state->repeat....set to true if the verifier must iterate again
940 over the basic blocks
943 true.............success
944 false............an exception has been thrown
946 *******************************************************************************/
949 typestate_reach(verifier_state *state,
950 basicblock *destblock,
951 stackptr ystack,typevector *yloc)
955 bool changed = false;
958 LOG1("reaching block L%03d",destblock->nr);
959 TYPECHECK_COUNT(stat_reached);
961 destidx = destblock - state->basicblocks;
962 destloc = MGET_TYPEVECTOR(state->localbuf,destidx,state->numlocals);
964 /* When branching backwards we have to check for uninitialized objects */
966 if (destblock <= state->bptr) {
971 TYPECHECK_COUNT(stat_backwards);
973 for (sp = ystack; sp; sp=sp->prev)
974 if (sp->type == TYPE_ADR &&
975 TYPEINFO_IS_NEWOBJECT(sp->typeinfo)) {
976 /*printf("current: %d, dest: %d\n", state->bptr->nr, destblock->nr);*/
977 exceptions_throw_verifyerror(state->m,"Branching backwards with uninitialized object on stack");
981 for (i=0; i<state->numlocals; ++i)
982 if (yloc->td[i].type == TYPE_ADR &&
983 TYPEINFO_IS_NEWOBJECT(yloc->td[i].info)) {
984 exceptions_throw_verifyerror(state->m,"Branching backwards with uninitialized object in local variable");
990 if (destblock->flags == BBTYPECHECK_UNDEF) {
991 /* The destblock has never been reached before */
993 TYPECHECK_COUNT(stat_copied);
994 LOG1("block (index %04d) reached first time",destidx);
996 if (!typestack_copy(state,destblock->instack,ystack,yloc))
998 typevectorset_copy_inplace(yloc,destloc,state->numlocals);
1002 /* The destblock has already been reached before */
1004 TYPECHECK_COUNT(stat_merged);
1005 LOG1("block (index %04d) reached before",destidx);
1007 r = typestate_merge(state,destblock->instack,destloc,ystack,yloc);
1008 if (r == typecheck_FAIL)
1011 TYPECHECK_COUNTIF(changed,stat_merging_changed);
1016 destblock->flags = BBTYPECHECK_REACHED;
1017 if (destblock <= state->bptr) {
1019 state->repeat = true;
1025 /* typestate_ret ***************************************************************
1027 Reach the destinations of a RET instruction.
1030 state............current state of the verifier
1031 retindex.........index of local variable containing the returnAddress
1034 state->repeat....set to true if the verifier must iterate again
1035 over the basic blocks
1038 true.............success
1039 false............an exception has been thrown
1041 *******************************************************************************/
1044 typestate_ret(verifier_state *state,int retindex)
1047 typevector *selected;
1048 basicblock *destblock;
1050 for (yvec=state->localset; yvec; ) {
1051 if (!TYPEDESC_IS_RETURNADDRESS(yvec->td[retindex])) {
1052 exceptions_throw_verifyerror(state->m,"Illegal instruction: RET on non-returnAddress");
1056 destblock = (basicblock*) TYPEINFO_RETURNADDRESS(yvec->td[retindex].info);
1058 selected = typevectorset_select(&yvec,retindex,destblock);
1060 if (!typestate_reach(state,destblock,state->bptr->outstack,selected))
1066 /* typestate_save_instack ******************************************************
1068 Save the input stack of the current basic block in the "savedstackbuf"
1069 of the verifier state.
1071 This function must be called before an instruction modifies a stack slot
1072 that happens to be part of the instack of the current block. In such
1073 cases the instack of the block must be saved, and restored at the end
1074 of the analysis of this basic block, so that the instack again reflects
1075 the *input* to this basic block (and does not randomly contain types
1076 that appear within the block).
1079 state............current state of the verifier
1081 *******************************************************************************/
1084 typestate_save_instack(verifier_state *state)
1090 LOG("saving input stack types");
1091 if (!state->savedstackbuf) {
1092 LOG("allocating savedstack buffer");
1093 state->savedstackbuf = DMNEW(stackelement, state->cd->maxstack);
1094 state->savedstackbuf->prev = NULL;
1095 for (i = 1; i < state->cd->maxstack; ++i)
1096 state->savedstackbuf[i].prev = state->savedstackbuf+(i-1);
1098 sp = state->savedstack = state->bptr->instack;
1099 dest = state->bptr->instack = state->savedstackbuf + (state->bptr->indepth-1);
1101 for(; sp; sp=sp->prev, dest=dest->prev) {
1102 dest->type = sp->type;
1103 TYPEINFO_COPY(sp->typeinfo,dest->typeinfo);
1107 /* typestate_restore_instack ***************************************************
1109 Restore the input stack of the current basic block that has been previously
1110 saved by `typestate_save_instack`.
1113 state............current state of the verifier
1115 *******************************************************************************/
1118 typestate_restore_instack(verifier_state *state)
1123 TYPECHECK_COUNT(stat_savedstack);
1124 LOG("restoring saved instack");
1126 sp = state->bptr->instack;
1127 dest = state->savedstack;
1128 for(; sp; sp=sp->prev, dest=dest->prev) {
1129 dest->type = sp->type;
1130 TYPEINFO_COPY(sp->typeinfo,dest->typeinfo);
1133 state->bptr->instack = state->savedstack;
1134 state->savedstack = NULL;
1137 /****************************************************************************/
1139 /****************************************************************************/
1141 #define COPYTYPE(source,dest) \
1142 {if ((source)->type == TYPE_ADR) \
1143 TYPEINFO_COPY((source)->typeinfo,(dest)->typeinfo);}
1145 #define ISBUILTIN(v) (bte->fp == (functionptr) (v))
1147 /* verify_invocation ***********************************************************
1149 Verify an ICMD_INVOKE* instruction.
1152 state............the current state of the verifier
1155 true.............successful verification,
1156 false............an exception has been thrown.
1158 *******************************************************************************/
1161 verify_invocation(verifier_state *state)
1163 unresolved_method *um; /* struct describing the called method */
1164 constant_FMIref *mref; /* reference to the called method */
1165 methodinfo *mi; /* resolved method (if any) */
1166 methoddesc *md; /* descriptor of the called method */
1167 utf *mname; /* method name */
1168 utf *mclassname; /* name of the method's class */
1169 bool specialmethod; /* true if a <...> method is called */
1170 int opcode; /* invocation opcode */
1171 bool callinginit; /* true if <init> is called */
1173 classref_or_classinfo initclass;
1175 stackelement *arg; /* argument pointer */
1176 stackelement *dst; /* result stack of the invocation */
1177 int i; /* counter */
1178 u1 rtype; /* return type of called method */
1179 resolve_result_t result;
1181 if (INSTRUCTION_IS_UNRESOLVED(state->iptr)) {
1182 /* unresolved method */
1183 um = state->iptr->sx.s23.s3.um;
1184 mref = um->methodref;
1187 /* resolved method */
1189 mref = state->iptr->sx.s23.s3.fmiref;
1192 md = mref->parseddesc.md;
1195 if (IS_FMIREF_RESOLVED(mref)) {
1196 mi = mref->p.method;
1197 mclassname = mi->class->name;
1201 mclassname = mref->p.classref->name;
1204 specialmethod = (mname->text[0] == '<');
1205 opcode = state->iptr[0].opc;
1206 dst = state->iptr->dst.var;
1208 /* prevent compiler warnings */
1212 /* check whether we are calling <init> */
1214 callinginit = (opcode == ICMD_INVOKESPECIAL && mname == utf_init);
1215 if (specialmethod && !callinginit)
1216 TYPECHECK_VERIFYERROR_bool("Invalid invocation of special method");
1218 /* allocate parameters if necessary */
1221 if (!descriptor_params_from_paramtypes(md,
1222 (opcode == ICMD_INVOKESTATIC) ? ACC_STATIC : ACC_NONE))
1225 /* check parameter types */
1227 i = md->paramcount; /* number of parameters including 'this'*/
1230 arg = state->iptr->sx.s23.s2.args[i];
1231 td = md->paramtypes + i;
1232 if (arg->type != td->type)
1233 TYPECHECK_VERIFYERROR_bool("Parameter type mismatch in method invocation");
1234 if (arg->type == TYPE_ADR) {
1235 LOGINFO(&(arg->typeinfo));
1236 if (i==0 && callinginit)
1238 /* first argument to <init> method */
1239 if (!TYPEINFO_IS_NEWOBJECT(arg->typeinfo))
1240 TYPECHECK_VERIFYERROR_bool("Calling <init> on initialized object");
1242 /* get the address of the NEW instruction */
1243 LOGINFO(&(arg->typeinfo));
1244 ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(arg->typeinfo);
1246 initclass = ins[-1].sx.val.c;
1248 initclass.cls = state->m->class;
1249 LOGSTR("class: "); LOGNAME(initclass); LOGNL;
1253 /* non-adress argument. if this is the first argument and we are */
1254 /* invoking an instance method, this is an error. */
1255 if (i==0 && opcode != ICMD_INVOKESTATIC) {
1256 TYPECHECK_VERIFYERROR_bool("Parameter type mismatch for 'this' argument");
1262 LOG("checking return type");
1263 rtype = md->returntype.type;
1264 if (rtype != TYPE_VOID) {
1265 if (rtype != dst->type)
1266 TYPECHECK_VERIFYERROR_bool("Return type mismatch in method invocation");
1267 if (!typeinfo_init_from_typedesc(&(md->returntype),NULL,&(dst->typeinfo)))
1272 LOG("replacing uninitialized object");
1273 /* replace uninitialized object type on stack */
1275 /* for all live-in and live-through variables */
1276 for (i=0; i<state->iptr->s1.argcount; ++i) {
1277 arg = state->iptr->sx.s23.s2.args[i];
1278 if (arg->type == TYPE_ADR
1279 && TYPEINFO_IS_NEWOBJECT(arg->typeinfo)
1280 && TYPEINFO_NEWOBJECT_INSTRUCTION(arg->typeinfo) == ins)
1282 LOG("replacing uninitialized type on stack");
1284 /* If this stackslot is in the instack of
1285 * this basic block we must save the type(s)
1286 * we are going to replace.
1288 /* XXX this needs a new check */
1289 if (arg <= state->bptr->instack && !state->savedstack)
1290 typestate_save_instack(state);
1292 if (!typeinfo_init_class(&(arg->typeinfo),initclass))
1297 /* replace uninitialized object type in locals */
1298 if (!typevectorset_init_object(state->localset,ins,initclass,state->numlocals))
1301 /* initializing the 'this' reference? */
1304 TYPECHECK_ASSERT(state->initmethod);
1305 /* { we are initializing the 'this' reference } */
1306 /* must be <init> of current class or direct superclass */
1307 /* the current class is linked, so must be its superclass. thus we can be */
1308 /* sure that resolving will be trivial. */
1313 if (!resolve_classref(state->m,mref->p.classref,resolveLazy,false,true,&cls))
1314 return false; /* exception */
1317 /* if lazy resolving did not succeed, it's not one of the allowed classes */
1318 /* otherwise we check it directly */
1319 if (cls == NULL || (cls != state->m->class && cls != state->m->class->super.cls)) {
1320 TYPECHECK_VERIFYERROR_bool("<init> calling <init> of the wrong class");
1323 /* set our marker variable to type int */
1324 LOG("setting <init> marker");
1325 typevectorset_store(state->localset,state->numlocals-1,TYPE_INT,NULL);
1328 /* { we are initializing an instance created with NEW } */
1329 if ((IS_CLASSREF(initclass) ? initclass.ref->name : initclass.cls->name) != mclassname) {
1330 TYPECHECK_VERIFYERROR_bool("wrong <init> called for uninitialized reference");
1335 /* try to resolve the method lazily */
1337 result = new_resolve_method_lazy(state->iptr,state->m);
1338 if (result == resolveFailed)
1341 if (result != resolveSucceeded) {
1343 um = new_create_unresolved_method(state->m->class,
1344 state->m, state->iptr);
1350 /* record subtype constraints for parameters */
1352 if (!new_constrain_unresolved_method(um,state->m->class,state->m,state->iptr))
1353 return false; /* XXX maybe wrap exception */
1355 /* store the unresolved_method pointer */
1357 state->iptr->sx.s23.s3.um = um;
1358 state->iptr->flags.bits |= INS_FLAG_UNRESOLVED;
1361 assert(IS_FMIREF_RESOLVED(state->iptr->sx.s23.s3.fmiref));
1367 /* verify_generic_builtin ******************************************************
1369 Verify the call of a generic builtin method.
1372 state............the current state of the verifier
1375 true.............successful verification,
1376 false............an exception has been thrown.
1378 *******************************************************************************/
1381 verify_generic_builtin(verifier_state *state)
1383 builtintable_entry *bte;
1389 TYPECHECK_COUNT(stat_ins_builtin_gen);
1391 bte = state->iptr->sx.s23.s3.bte;
1395 /* check the types of the arguments on the stack */
1397 for (i--; i >= 0; i--) {
1398 arg = state->iptr->sx.s23.s2.args[i];
1400 if (arg->type != md->paramtypes[i].type) {
1401 TYPECHECK_VERIFYERROR_bool("parameter type mismatch for builtin method");
1404 #ifdef TYPECHECK_DEBUG
1405 /* generic builtins may only take primitive types and java.lang.Object references */
1406 if (arg->type == TYPE_ADR && md->paramtypes[i].classref->name != utf_java_lang_Object) {
1407 *exceptionptr = new_internalerror("generic builtin method with non-generic reference parameter");
1413 /* check the return type */
1415 rtype = md->returntype.type;
1416 if (rtype != TYPE_VOID) {
1419 dst = state->iptr->dst.var;
1420 if (rtype != dst->type)
1421 TYPECHECK_VERIFYERROR_bool("Return type mismatch in generic builtin invocation");
1422 if (!typeinfo_init_from_typedesc(&(md->returntype),NULL,&(dst->typeinfo)))
1429 /* verify_builtin **************************************************************
1431 Verify the call of a builtin method.
1434 state............the current state of the verifier
1437 true.............successful verification,
1438 false............an exception has been thrown.
1440 *******************************************************************************/
1443 verify_builtin(verifier_state *state)
1445 builtintable_entry *bte;
1446 classref_or_classinfo cls;
1447 stackptr dst; /* output stack of current instruction */
1449 bte = state->iptr->sx.s23.s3.bte;
1450 dst = state->iptr->dst.var;
1452 /* XXX this is an ugly if-chain but twisti did not want a function */
1453 /* pointer in builtintable_entry for this, so here you go.. ;) */
1455 if (ISBUILTIN(BUILTIN_new)) {
1456 if (state->iptr[-1].opc != ICMD_ACONST)
1457 TYPECHECK_VERIFYERROR_bool("illegal instruction: builtin_new without class");
1458 cls = state->iptr[-1].sx.val.c;
1459 TYPEINFO_INIT_NEWOBJECT(dst->typeinfo,state->iptr);
1461 else if (ISBUILTIN(BUILTIN_newarray_boolean)) {
1462 TYPECHECK_INT(state->iptr->sx.s23.s2.args[0]);
1463 TYPEINFO_INIT_PRIMITIVE_ARRAY(dst->typeinfo,ARRAYTYPE_BOOLEAN);
1465 else if (ISBUILTIN(BUILTIN_newarray_char)) {
1466 TYPECHECK_INT(state->iptr->sx.s23.s2.args[0]);
1467 TYPEINFO_INIT_PRIMITIVE_ARRAY(dst->typeinfo,ARRAYTYPE_CHAR);
1469 else if (ISBUILTIN(BUILTIN_newarray_float)) {
1470 TYPECHECK_INT(state->iptr->sx.s23.s2.args[0]);
1471 TYPEINFO_INIT_PRIMITIVE_ARRAY(dst->typeinfo,ARRAYTYPE_FLOAT);
1473 else if (ISBUILTIN(BUILTIN_newarray_double)) {
1474 TYPECHECK_INT(state->iptr->sx.s23.s2.args[0]);
1475 TYPEINFO_INIT_PRIMITIVE_ARRAY(dst->typeinfo,ARRAYTYPE_DOUBLE);
1477 else if (ISBUILTIN(BUILTIN_newarray_byte)) {
1478 TYPECHECK_INT(state->iptr->sx.s23.s2.args[0]);
1479 TYPEINFO_INIT_PRIMITIVE_ARRAY(dst->typeinfo,ARRAYTYPE_BYTE);
1481 else if (ISBUILTIN(BUILTIN_newarray_short)) {
1482 TYPECHECK_INT(state->iptr->sx.s23.s2.args[0]);
1483 TYPEINFO_INIT_PRIMITIVE_ARRAY(dst->typeinfo,ARRAYTYPE_SHORT);
1485 else if (ISBUILTIN(BUILTIN_newarray_int)) {
1486 TYPECHECK_INT(state->iptr->sx.s23.s2.args[0]);
1487 TYPEINFO_INIT_PRIMITIVE_ARRAY(dst->typeinfo,ARRAYTYPE_INT);
1489 else if (ISBUILTIN(BUILTIN_newarray_long)) {
1490 TYPECHECK_INT(state->iptr->sx.s23.s2.args[0]);
1491 TYPEINFO_INIT_PRIMITIVE_ARRAY(dst->typeinfo,ARRAYTYPE_LONG);
1493 else if (ISBUILTIN(BUILTIN_newarray))
1495 TYPECHECK_INT(state->iptr->sx.s23.s2.args[0]);
1496 if (state->iptr[-1].opc != ICMD_ACONST)
1497 TYPECHECK_VERIFYERROR_bool("illegal instruction: builtin_newarray without class");
1498 /* XXX check that it is an array class(ref) */
1499 typeinfo_init_class(&(dst->typeinfo),state->iptr[-1].sx.val.c);
1501 else if (ISBUILTIN(BUILTIN_arrayinstanceof))
1503 TYPECHECK_ADR(state->iptr->sx.s23.s2.args[0]);
1504 if (state->iptr[-1].opc != ICMD_ACONST)
1505 TYPECHECK_VERIFYERROR_bool("illegal instruction: builtin_arrayinstanceof without class");
1506 /* XXX check that it is an array class(ref) */
1509 return verify_generic_builtin(state);
1514 /* verify_multianewarray *******************************************************
1516 Verify a MULTIANEWARRAY instruction.
1519 state............the current state of the verifier
1522 true.............successful verification,
1523 false............an exception has been thrown.
1525 *******************************************************************************/
1528 verify_multianewarray(verifier_state *state)
1531 classinfo *arrayclass;
1532 arraydescriptor *desc;
1535 /* check the array lengths on the stack */
1536 i = state->iptr->s1.argcount;
1538 TYPECHECK_VERIFYERROR_bool("Illegal dimension argument");
1541 arg = state->iptr->sx.s23.s2.args[i];
1542 /* XXX this should be checked in stack.c: */
1544 TYPECHECK_VERIFYERROR_bool("Unable to pop operand off an empty stack");
1548 /* check array descriptor */
1549 if (INSTRUCTION_IS_RESOLVED(state->iptr)) {
1550 /* the array class reference has already been resolved */
1551 arrayclass = state->iptr->sx.s23.s3.c.cls;
1553 TYPECHECK_VERIFYERROR_bool("MULTIANEWARRAY with unlinked class");
1554 if ((desc = arrayclass->vftbl->arraydesc) == NULL)
1555 TYPECHECK_VERIFYERROR_bool("MULTIANEWARRAY with non-array class");
1556 if (desc->dimension < state->iptr->s1.argcount)
1557 TYPECHECK_VERIFYERROR_bool("MULTIANEWARRAY dimension to high");
1559 /* set the array type of the result */
1560 typeinfo_init_classinfo(&(state->iptr->dst.var->typeinfo), arrayclass);
1564 constant_classref *cr;
1566 /* the array class reference is still unresolved */
1567 /* check that the reference indicates an array class of correct dimension */
1568 cr = state->iptr->sx.s23.s3.c.ref;
1573 /* { the dimension of the array class == i } */
1575 TYPECHECK_VERIFYERROR_bool("MULTIANEWARRAY with non-array class");
1576 if (i < state->iptr->s1.argcount)
1577 TYPECHECK_VERIFYERROR_bool("MULTIANEWARRAY dimension to high");
1579 /* set the array type of the result */
1580 if (!typeinfo_init_class(&(state->iptr->dst.var->typeinfo),CLASSREF_OR_CLASSINFO(cr)))
1588 /* verify_basic_block **********************************************************
1590 Perform bytecode verification of a basic block.
1593 state............the current state of the verifier
1596 true.............successful verification,
1597 false............an exception has been thrown.
1599 *******************************************************************************/
1602 verify_basic_block(verifier_state *state)
1604 int opcode; /* current opcode */
1605 int len; /* for counting instructions, etc. */
1606 bool superblockend; /* true if no fallthrough to next block */
1607 instruction *iptr; /* the current instruction */
1609 basicblock *tbptr; /* temporary for target block */
1610 bool maythrow; /* true if this instruction may throw */
1611 unresolved_field *uf; /* for field accesses */
1612 constant_FMIref *fieldref; /* for field accesses */
1616 resolve_result_t result;
1617 branch_target_t *table;
1618 lookup_target_t *lookup;
1620 LOGSTR1("\n---- BLOCK %04d ------------------------------------------------\n",state->bptr->nr);
1623 superblockend = false;
1624 state->bptr->flags = BBFINISHED;
1625 b_index = state->bptr - state->basicblocks;
1627 /* prevent compiler warnings */
1631 /* determine the active exception handlers for this block */
1632 /* XXX could use a faster algorithm with sorted lists or */
1635 for (i = 0; i < state->cd->exceptiontablelength; ++i) {
1636 if ((state->cd->exceptiontable[i].start <= state->bptr) && (state->cd->exceptiontable[i].end > state->bptr)) {
1637 LOG1("active handler L%03d", state->cd->exceptiontable[i].handler->nr);
1638 state->handlers[len++] = state->cd->exceptiontable + i;
1641 state->handlers[len] = NULL;
1643 /* init variable types at the start of this block */
1644 typevectorset_copy_inplace(MGET_TYPEVECTOR(state->localbuf,b_index,state->numlocals),
1645 state->localset,state->numlocals);
1647 if (state->handlers[0])
1648 for (i=0; i<state->numlocals; ++i)
1649 if (state->localset->td[i].type == TYPE_ADR
1650 && TYPEINFO_IS_NEWOBJECT(state->localset->td[i].info)) {
1651 /* XXX we do not check this for the uninitialized 'this' instance in */
1652 /* <init> methods. Otherwise there are problems with try blocks in */
1653 /* <init>. The spec seems to indicate that we should perform the test*/
1654 /* in all cases, but this fails with real code. */
1655 /* Example: org/eclipse/ui/internal/PerspectiveBarNewContributionItem*/
1656 /* of eclipse 3.0.2 */
1657 /* XXX Try to show that the check is not necessary for 'this'! */
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->nr);
1661 TYPECHECK_VERIFYERROR_bool("Uninitialized object in local variable inside try block");
1664 DOLOG(typestate_print(typecheck_logfile,state->bptr->instack,state->localset,state->numlocals));
1667 /* loop over the instructions */
1668 len = state->bptr->icount;
1669 state->iptr = state->bptr->iinstr;
1670 while (--len >= 0) {
1671 TYPECHECK_COUNT(stat_ins);
1675 DOLOG(typestate_print(typecheck_logfile,NULL,state->localset,state->numlocals));
1678 DOLOG(show_icmd(state->iptr,false)); LOGNL; LOGFLUSH;
1681 dst = iptr->dst.var;
1686 /****************************************/
1687 /* STACK MANIPULATIONS */
1689 /* We just need to copy the typeinfo */
1690 /* for slots containing addresses. */
1694 TYPECHECK_COUNT(stat_ins_stack);
1695 COPYTYPE(iptr->s1.var, iptr->dst.var);
1698 /****************************************/
1699 /* PRIMITIVE VARIABLE ACCESS */
1701 case ICMD_ILOAD: if (!typevectorset_checktype(state->localset,state->iptr->s1.localindex,TYPE_INT))
1702 TYPECHECK_VERIFYERROR_bool("Local variable type mismatch");
1704 case ICMD_IINC: if (!typevectorset_checktype(state->localset,state->iptr->s1.localindex,TYPE_INT))
1705 TYPECHECK_VERIFYERROR_bool("Local variable type mismatch");
1707 case ICMD_FLOAD: if (!typevectorset_checktype(state->localset,state->iptr->s1.localindex,TYPE_FLT))
1708 TYPECHECK_VERIFYERROR_bool("Local variable type mismatch");
1710 case ICMD_LLOAD: if (!typevectorset_checktype(state->localset,state->iptr->s1.localindex,TYPE_LNG))
1711 TYPECHECK_VERIFYERROR_bool("Local variable type mismatch");
1713 case ICMD_DLOAD: if (!typevectorset_checktype(state->localset,state->iptr->s1.localindex,TYPE_DBL))
1714 TYPECHECK_VERIFYERROR_bool("Local variable type mismatch");
1717 case ICMD_ISTORE: typevectorset_store(state->localset,state->iptr->dst.localindex,TYPE_INT,NULL); break;
1718 case ICMD_FSTORE: typevectorset_store(state->localset,state->iptr->dst.localindex,TYPE_FLT,NULL); break;
1719 case ICMD_LSTORE: typevectorset_store_twoword(state->localset,state->iptr->dst.localindex,TYPE_LNG); break;
1720 case ICMD_DSTORE: typevectorset_store_twoword(state->localset,state->iptr->dst.localindex,TYPE_DBL); break;
1722 /****************************************/
1723 /* LOADING ADDRESS FROM VARIABLE */
1726 TYPECHECK_COUNT(stat_ins_aload);
1728 /* loading a returnAddress is not allowed */
1729 if (state->jsrencountered) {
1730 if (!typevectorset_checkreference(state->localset,state->iptr->s1.localindex)) {
1731 TYPECHECK_VERIFYERROR_bool("illegal instruction: ALOAD loading non-reference");
1733 if (typevectorset_copymergedtype(state->m,state->localset,state->iptr->s1.localindex,&(dst->typeinfo)) == -1)
1737 if (!TYPEDESC_IS_REFERENCE(state->localset->td[state->iptr->s1.localindex])) {
1738 TYPECHECK_VERIFYERROR_bool("illegal instruction: ALOAD loading non-reference");
1740 TYPEINFO_COPY(state->localset->td[state->iptr->s1.localindex].info,dst->typeinfo);
1744 /****************************************/
1745 /* STORING ADDRESS TO VARIABLE */
1748 if (state->handlers[0] && TYPEINFO_IS_NEWOBJECT(state->iptr->s1.var->typeinfo)) {
1749 TYPECHECK_VERIFYERROR_bool("Storing uninitialized object in local variable inside try block");
1752 if (TYPESTACK_IS_RETURNADDRESS(state->iptr->s1.var)) {
1753 typevectorset_store_retaddr(state->localset,state->iptr->dst.localindex,&(state->iptr->s1.var->typeinfo));
1756 typevectorset_store(state->localset,state->iptr->dst.localindex,TYPE_ADR,
1757 &(state->iptr->s1.var->typeinfo));
1761 /****************************************/
1762 /* LOADING ADDRESS FROM ARRAY */
1765 if (!TYPEINFO_MAYBE_ARRAY_OF_REFS(state->iptr->s1.var->typeinfo))
1766 TYPECHECK_VERIFYERROR_bool("illegal instruction: AALOAD on non-reference array");
1768 if (!typeinfo_init_component(&state->iptr->s1.var->typeinfo,&dst->typeinfo))
1773 /****************************************/
1777 case ICMD_PUTSTATIC:
1778 case ICMD_PUTFIELDCONST:
1779 case ICMD_PUTSTATICCONST:
1780 TYPECHECK_COUNT(stat_ins_field);
1782 if (INSTRUCTION_IS_UNRESOLVED(state->iptr)) {
1783 uf = state->iptr->sx.s23.s3.uf;
1784 fieldref = uf->fieldref;
1788 fieldref = state->iptr->sx.s23.s3.fmiref;
1791 goto fieldaccess_tail;
1794 case ICMD_GETSTATIC:
1795 TYPECHECK_COUNT(stat_ins_field);
1797 if (INSTRUCTION_IS_UNRESOLVED(state->iptr)) {
1798 uf = state->iptr->sx.s23.s3.uf;
1799 fieldref = uf->fieldref;
1803 fieldref = state->iptr->sx.s23.s3.fmiref;
1806 /* the result is pushed on the stack */
1807 if (dst->type == TYPE_ADR) {
1808 if (!typeinfo_init_from_typedesc(fieldref->parseddesc.fd,NULL,&(dst->typeinfo)))
1813 /* try to resolve the field reference lazily */
1814 result = new_resolve_field_lazy(state->iptr, state->m);
1815 if (result == resolveFailed)
1818 if (result != resolveSucceeded) {
1820 uf = new_create_unresolved_field(state->m->class, state->m, state->iptr);
1824 state->iptr->sx.s23.s3.uf = uf;
1825 state->iptr->flags.bits |= INS_FLAG_UNRESOLVED;
1828 /* record the subtype constraints for this field access */
1829 if (!new_constrain_unresolved_field(uf,state->m->class,state->m,state->iptr))
1830 return false; /* XXX maybe wrap exception? */
1832 TYPECHECK_COUNTIF(INSTRUCTION_IS_UNRESOLVED(state->iptr),stat_ins_field_unresolved);
1833 TYPECHECK_COUNTIF(INSTRUCTION_IS_RESOLVED(state->iptr) && !state->iptr->sx.s23.s3.fmiref->p.field->class->initialized,stat_ins_field_uninitialized);
1839 /****************************************/
1840 /* PRIMITIVE ARRAY ACCESS */
1842 case ICMD_ARRAYLENGTH:
1843 if (!TYPEINFO_MAYBE_ARRAY(state->iptr->s1.var->typeinfo)
1844 && state->iptr->s1.var->typeinfo.typeclass.cls != pseudo_class_Arraystub)
1845 TYPECHECK_VERIFYERROR_bool("illegal instruction: ARRAYLENGTH on non-array");
1850 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->iptr->s1.var->typeinfo,ARRAYTYPE_BOOLEAN)
1851 && !TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->iptr->s1.var->typeinfo,ARRAYTYPE_BYTE))
1852 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1856 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->iptr->s1.var->typeinfo,ARRAYTYPE_CHAR))
1857 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1861 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->iptr->s1.var->typeinfo,ARRAYTYPE_DOUBLE))
1862 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1866 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->iptr->s1.var->typeinfo,ARRAYTYPE_FLOAT))
1867 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1871 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->iptr->s1.var->typeinfo,ARRAYTYPE_INT))
1872 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1876 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->iptr->s1.var->typeinfo,ARRAYTYPE_SHORT))
1877 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1881 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->iptr->s1.var->typeinfo,ARRAYTYPE_LONG))
1882 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1887 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->iptr->s1.var->typeinfo,ARRAYTYPE_BOOLEAN)
1888 && !TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->iptr->s1.var->typeinfo,ARRAYTYPE_BYTE))
1889 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1893 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->iptr->s1.var->typeinfo,ARRAYTYPE_CHAR))
1894 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1898 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->iptr->s1.var->typeinfo,ARRAYTYPE_DOUBLE))
1899 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1903 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->iptr->s1.var->typeinfo,ARRAYTYPE_FLOAT))
1904 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1908 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->iptr->s1.var->typeinfo,ARRAYTYPE_INT))
1909 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1913 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->iptr->s1.var->typeinfo,ARRAYTYPE_SHORT))
1914 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1918 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->iptr->s1.var->typeinfo,ARRAYTYPE_LONG))
1919 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1924 /* we just check the basic input types and that the */
1925 /* destination is an array of references. Assignability to */
1926 /* the actual array must be checked at runtime, each time the */
1927 /* instruction is performed. (See builtin_canstore.) */
1928 TYPECHECK_ADR(state->iptr->sx.s23.s3.var);
1929 TYPECHECK_INT(state->iptr->sx.s23.s2.var);
1930 TYPECHECK_ADR(state->iptr->s1.var);
1931 if (!TYPEINFO_MAYBE_ARRAY_OF_REFS(state->iptr->s1.var->typeinfo))
1932 TYPECHECK_VERIFYERROR_bool("illegal instruction: AASTORE to non-reference array");
1936 case ICMD_IASTORECONST:
1937 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->iptr->s1.var->typeinfo, ARRAYTYPE_INT))
1938 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1942 case ICMD_LASTORECONST:
1943 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->iptr->s1.var->typeinfo, ARRAYTYPE_LONG))
1944 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1948 case ICMD_BASTORECONST:
1949 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->iptr->s1.var->typeinfo, ARRAYTYPE_BOOLEAN)
1950 && !TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->iptr->s1.var->typeinfo, ARRAYTYPE_BYTE))
1951 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1955 case ICMD_CASTORECONST:
1956 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->iptr->s1.var->typeinfo, ARRAYTYPE_CHAR))
1957 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1961 case ICMD_SASTORECONST:
1962 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(state->iptr->s1.var->typeinfo, ARRAYTYPE_SHORT))
1963 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1967 /****************************************/
1968 /* ADDRESS CONSTANTS */
1971 if (state->iptr->flags.bits & INS_FLAG_CLASS) {
1972 /* a java.lang.Class reference */
1973 TYPEINFO_INIT_JAVA_LANG_CLASS(dst->typeinfo,state->iptr->sx.val.c);
1976 if (state->iptr->sx.val.anyptr == NULL)
1977 TYPEINFO_INIT_NULLTYPE(dst->typeinfo);
1979 /* string constant (or constant for builtin function) */
1980 typeinfo_init_classinfo(&(dst->typeinfo),class_java_lang_String);
1985 /****************************************/
1986 /* CHECKCAST AND INSTANCEOF */
1988 case ICMD_CHECKCAST:
1989 TYPECHECK_ADR(state->iptr->s1.var);
1990 /* returnAddress is not allowed */
1991 if (!TYPEINFO_IS_REFERENCE(state->iptr->s1.var->typeinfo))
1992 TYPECHECK_VERIFYERROR_bool("Illegal instruction: CHECKCAST on non-reference");
1994 if (!typeinfo_init_class(&(dst->typeinfo),state->iptr->sx.s23.s3.c))
1999 case ICMD_INSTANCEOF:
2000 TYPECHECK_ADR(state->iptr->s1.var);
2001 /* returnAddress is not allowed */
2002 if (!TYPEINFO_IS_REFERENCE(state->iptr->s1.var->typeinfo))
2003 TYPECHECK_VERIFYERROR_bool("Illegal instruction: INSTANCEOF on non-reference");
2006 /****************************************/
2007 /* BRANCH INSTRUCTIONS */
2009 case ICMD_INLINE_GOTO:
2010 COPYTYPE(state->iptr->s1.var,dst);
2013 superblockend = true;
2016 case ICMD_IFNONNULL:
2023 case ICMD_IF_ICMPEQ:
2024 case ICMD_IF_ICMPNE:
2025 case ICMD_IF_ICMPLT:
2026 case ICMD_IF_ICMPGE:
2027 case ICMD_IF_ICMPGT:
2028 case ICMD_IF_ICMPLE:
2029 case ICMD_IF_ACMPEQ:
2030 case ICMD_IF_ACMPNE:
2039 case ICMD_IF_LCMPEQ:
2040 case ICMD_IF_LCMPNE:
2041 case ICMD_IF_LCMPLT:
2042 case ICMD_IF_LCMPGE:
2043 case ICMD_IF_LCMPGT:
2044 case ICMD_IF_LCMPLE:
2046 case ICMD_IF_FCMPEQ:
2047 case ICMD_IF_FCMPNE:
2049 case ICMD_IF_FCMPL_LT:
2050 case ICMD_IF_FCMPL_GE:
2051 case ICMD_IF_FCMPL_GT:
2052 case ICMD_IF_FCMPL_LE:
2054 case ICMD_IF_FCMPG_LT:
2055 case ICMD_IF_FCMPG_GE:
2056 case ICMD_IF_FCMPG_GT:
2057 case ICMD_IF_FCMPG_LE:
2059 case ICMD_IF_DCMPEQ:
2060 case ICMD_IF_DCMPNE:
2062 case ICMD_IF_DCMPL_LT:
2063 case ICMD_IF_DCMPL_GE:
2064 case ICMD_IF_DCMPL_GT:
2065 case ICMD_IF_DCMPL_LE:
2067 case ICMD_IF_DCMPG_LT:
2068 case ICMD_IF_DCMPG_GE:
2069 case ICMD_IF_DCMPG_GT:
2070 case ICMD_IF_DCMPG_LE:
2071 TYPECHECK_COUNT(stat_ins_branch);
2073 /* propagate stack and variables to the target block */
2074 if (!typestate_reach(state,state->iptr->dst.block,
2075 state->bptr->outstack,state->localset))
2079 /****************************************/
2082 case ICMD_TABLESWITCH:
2083 TYPECHECK_COUNT(stat_ins_switch);
2085 table = iptr->dst.table;
2086 i = iptr->sx.s23.s3.tablehigh
2087 - iptr->sx.s23.s2.tablelow + 1 + 1; /* plus default */
2090 tbptr = (table++)->block;
2091 LOG2("target %d is block %04d",i,tbptr->nr);
2092 if (!typestate_reach(state,tbptr,state->bptr->outstack,
2098 superblockend = true;
2101 case ICMD_LOOKUPSWITCH:
2102 TYPECHECK_COUNT(stat_ins_switch);
2104 lookup = iptr->dst.lookup;
2105 i = iptr->sx.s23.s2.lookupcount;
2107 if (!typestate_reach(state,iptr->sx.s23.s3.lookupdefault.block,
2108 state->bptr->outstack,state->localset))
2112 tbptr = (lookup++)->target.block;
2113 LOG2("target %d is block %04d",i,tbptr->nr);
2114 if (!typestate_reach(state,tbptr,state->bptr->outstack,state->localset))
2119 superblockend = true;
2122 /****************************************/
2123 /* ADDRESS RETURNS AND THROW */
2126 TYPECHECK_COUNT(stat_ins_athrow);
2127 r = typeinfo_is_assignable_to_class(&state->iptr->s1.var->typeinfo,
2128 CLASSREF_OR_CLASSINFO(class_java_lang_Throwable));
2129 if (r == typecheck_FALSE)
2130 TYPECHECK_VERIFYERROR_bool("illegal instruction: ATHROW on non-Throwable");
2131 if (r == typecheck_FAIL)
2133 if (r == typecheck_MAYBE) {
2134 /* the check has to be postponed. we need a patcher */
2135 TYPECHECK_COUNT(stat_ins_athrow_unresolved);
2136 iptr->sx.s23.s2.uc = create_unresolved_class(
2138 /* XXX make this more efficient, use class_java_lang_Throwable
2140 class_get_classref(state->m->class,utf_java_lang_Throwable),
2141 &state->iptr->s1.var->typeinfo);
2142 iptr->flags.bits |= INS_FLAG_UNRESOLVED;
2144 superblockend = true;
2149 TYPECHECK_COUNT(stat_ins_areturn);
2150 if (!TYPEINFO_IS_REFERENCE(state->iptr->s1.var->typeinfo))
2151 TYPECHECK_VERIFYERROR_bool("illegal instruction: ARETURN on non-reference");
2153 if (state->returntype.type != TYPE_ADR
2154 || (r = typeinfo_is_assignable(&state->iptr->s1.var->typeinfo,&(state->returntype.info)))
2156 TYPECHECK_VERIFYERROR_bool("Return type mismatch");
2157 if (r == typecheck_FAIL)
2159 if (r == typecheck_MAYBE) {
2160 /* the check has to be postponed, we need a patcher */
2161 TYPECHECK_COUNT(stat_ins_areturn_unresolved);
2162 iptr->sx.s23.s2.uc = create_unresolved_class(
2164 state->m->parseddesc->returntype.classref,
2165 &state->iptr->s1.var->typeinfo);
2166 iptr->flags.bits |= INS_FLAG_UNRESOLVED;
2170 /****************************************/
2171 /* PRIMITIVE RETURNS */
2174 if (state->returntype.type != TYPE_INT) TYPECHECK_VERIFYERROR_bool("Return type mismatch");
2178 if (state->returntype.type != TYPE_LNG) TYPECHECK_VERIFYERROR_bool("Return type mismatch");
2182 if (state->returntype.type != TYPE_FLT) TYPECHECK_VERIFYERROR_bool("Return type mismatch");
2186 if (state->returntype.type != TYPE_DBL) TYPECHECK_VERIFYERROR_bool("Return type mismatch");
2190 if (state->returntype.type != TYPE_VOID) TYPECHECK_VERIFYERROR_bool("Return type mismatch");
2192 TYPECHECK_COUNT(stat_ins_primitive_return);
2194 if (state->initmethod && state->m->class != class_java_lang_Object) {
2195 /* Check if the 'this' instance has been initialized. */
2196 LOG("Checking <init> marker");
2197 if (!typevectorset_checktype(state->localset,state->numlocals-1,TYPE_INT))
2198 TYPECHECK_VERIFYERROR_bool("<init> method does not initialize 'this'");
2201 superblockend = true;
2205 /****************************************/
2206 /* SUBROUTINE INSTRUCTIONS */
2210 state->jsrencountered = true;
2212 tbptr = state->iptr->sx.s23.s3.jsrtarget.block;
2213 if (state->bptr + 1 == (state->basicblocks + state->basicblockcount + 1))
2214 TYPECHECK_VERIFYERROR_bool("Illegal instruction: JSR at end of bytecode");
2215 typestack_put_retaddr(dst,state->bptr+1,state->localset);
2216 if (!typestate_reach(state,tbptr,dst,state->localset))
2219 superblockend = true;
2223 /* check returnAddress variable */
2224 if (!typevectorset_checkretaddr(state->localset,state->iptr->s1.localindex))
2225 TYPECHECK_VERIFYERROR_bool("illegal instruction: RET using non-returnAddress variable");
2227 if (!typestate_ret(state,state->iptr->s1.localindex))
2230 superblockend = true;
2233 /****************************************/
2236 case ICMD_INVOKEVIRTUAL:
2237 case ICMD_INVOKESPECIAL:
2238 case ICMD_INVOKESTATIC:
2239 case ICMD_INVOKEINTERFACE:
2240 TYPECHECK_COUNT(stat_ins_invoke);
2241 if (!verify_invocation(state))
2243 TYPECHECK_COUNTIF(!state->iptr[0].val.a,stat_ins_invoke_unresolved);
2247 /****************************************/
2248 /* MULTIANEWARRAY */
2250 case ICMD_MULTIANEWARRAY:
2251 if (!verify_multianewarray(state))
2256 /****************************************/
2260 TYPECHECK_COUNT(stat_ins_builtin);
2261 if (!verify_builtin(state))
2266 /****************************************/
2267 /* SIMPLE EXCEPTION THROWING TESTS */
2269 case ICMD_CHECKNULL:
2270 /* CHECKNULL just requires that the stack top
2271 * is an address. This is checked in stack.c */
2275 /****************************************/
2276 /* INSTRUCTIONS WHICH SHOULD HAVE BEEN */
2277 /* REPLACED BY OTHER OPCODES */
2279 #ifdef TYPECHECK_DEBUG
2282 case ICMD_ANEWARRAY:
2283 case ICMD_MONITORENTER:
2284 case ICMD_MONITOREXIT:
2285 LOG2("ICMD %d at %d\n", state->iptr->opc, (int)(state->iptr-state->bptr->iinstr));
2286 LOG("Should have been converted to builtin function call.");
2287 TYPECHECK_ASSERT(false);
2291 /****************************************/
2292 /* UNCHECKED OPERATIONS */
2294 /*********************************************
2295 * Instructions below...
2296 * *) don't operate on local variables,
2297 * *) don't operate on references,
2298 * *) don't operate on returnAddresses,
2299 * *) don't affect control flow (except
2300 * by throwing exceptions).
2302 * (These instructions are typechecked in
2304 ********************************************/
2306 /* Instructions which may throw a runtime exception: */
2316 /* Instructions which never throw a runtime exception: */
2317 #if defined(TYPECHECK_DEBUG) || defined(TYPECHECK_STATISTICS)
2351 case ICMD_IADDCONST:
2352 case ICMD_ISUBCONST:
2353 case ICMD_IMULCONST:
2354 case ICMD_IANDCONST:
2356 case ICMD_IXORCONST:
2357 case ICMD_ISHLCONST:
2358 case ICMD_ISHRCONST:
2359 case ICMD_IUSHRCONST:
2361 case ICMD_LADDCONST:
2362 case ICMD_LSUBCONST:
2363 case ICMD_LMULCONST:
2364 case ICMD_LANDCONST:
2366 case ICMD_LXORCONST:
2367 case ICMD_LSHLCONST:
2368 case ICMD_LSHRCONST:
2369 case ICMD_LUSHRCONST:
2386 case ICMD_INT2SHORT:
2389 case ICMD_LCMPCONST:
2408 case ICMD_INLINE_START:
2409 case ICMD_INLINE_END:
2411 /* XXX What shall we do with the following ?*/
2412 case ICMD_AASTORECONST:
2413 TYPECHECK_COUNT(stat_ins_unchecked);
2416 /****************************************/
2419 LOG2("ICMD %d at %d\n", state->iptr->opc, (int)(state->iptr-state->bptr->iinstr));
2420 TYPECHECK_VERIFYERROR_bool("Missing ICMD code during typecheck");
2424 /* reach exception handlers for this instruction */
2426 TYPECHECK_COUNT(stat_ins_maythrow);
2427 TYPECHECK_MARK(state->stat_maythrow);
2428 LOG("reaching exception handlers");
2430 while (state->handlers[i]) {
2431 TYPECHECK_COUNT(stat_handlers_reached);
2432 if (state->handlers[i]->catchtype.any)
2433 state->excstack.typeinfo.typeclass = state->handlers[i]->catchtype;
2435 state->excstack.typeinfo.typeclass.cls = class_java_lang_Throwable;
2436 if (!typestate_reach(state,
2437 state->handlers[i]->handler,
2438 &(state->excstack),state->localset))
2444 LOG("next instruction");
2446 } /* while instructions */
2448 LOG("instructions done");
2449 LOGSTR("RESULT=> ");
2450 DOLOG(typestate_print(typecheck_logfile,state->bptr->outstack,state->localset,state->numlocals));
2453 /* propagate stack and variables to the following block */
2454 if (!superblockend) {
2455 LOG("reaching following block");
2456 tbptr = state->bptr + 1;
2457 while (tbptr->flags == BBDELETED) {
2459 #ifdef TYPECHECK_DEBUG
2460 /* this must be checked in parse.c */
2461 if ((tbptr->nr) >= state->basicblockcount)
2462 TYPECHECK_VERIFYERROR_bool("Control flow falls off the last block");
2465 if (!typestate_reach(state,tbptr,state->bptr->outstack,state->localset))
2469 /* We may have to restore the types of the instack slots. They
2470 * have been saved if an <init> call inside the block has
2471 * modified the instack types. (see INVOKESPECIAL) */
2473 if (state->savedstack)
2474 typestate_restore_instack(state);
2479 /* verify_init_locals **********************************************************
2481 Initialize the local variables in the verifier state.
2484 state............the current state of the verifier
2487 true.............success,
2488 false............an exception has been thrown.
2490 *******************************************************************************/
2493 verify_init_locals(verifier_state *state)
2499 /* initialize the variable types of the first block */
2500 /* to the types of the arguments */
2502 lset = MGET_TYPEVECTOR(state->localbuf,0,state->numlocals);
2506 i = state->validlocals;
2508 /* allocate parameter descriptors if necessary */
2510 if (!state->m->parseddesc->params)
2511 if (!descriptor_params_from_paramtypes(state->m->parseddesc,state->m->flags))
2514 /* if this is an instance method initialize the "this" ref type */
2516 if (!(state->m->flags & ACC_STATIC)) {
2518 TYPECHECK_VERIFYERROR_bool("Not enough local variables for method arguments");
2519 td->type = TYPE_ADR;
2520 if (state->initmethod)
2521 TYPEINFO_INIT_NEWOBJECT(td->info,NULL);
2523 typeinfo_init_classinfo(&(td->info), state->m->class);
2528 LOG("'this' argument set.\n");
2530 /* the rest of the arguments and the return type */
2532 i = typedescriptors_init_from_methoddesc(td, state->m->parseddesc,
2534 true, /* two word types use two slots */
2535 (td - lset->td), /* skip 'this' pointer */
2536 &state->returntype);
2541 /* variables not used for arguments are initialized to TYPE_VOID */
2543 i = state->numlocals - (td - lset->td);
2545 td->type = TYPE_VOID;
2549 LOG("Arguments set.\n");
2553 /* typecheck_init_flags ********************************************************
2555 Initialize the basic block flags for the following CFG traversal.
2558 state............the current state of the verifier
2560 *******************************************************************************/
2563 typecheck_init_flags(verifier_state *state)
2568 /* set all BBFINISHED blocks to BBTYPECHECK_UNDEF. */
2570 i = state->basicblockcount;
2571 block = state->basicblocks;
2575 #ifdef TYPECHECK_DEBUG
2576 /* check for invalid flags */
2577 if (block->flags != BBFINISHED && block->flags != BBDELETED && block->flags != BBUNDEF)
2579 /*show_icmd_method(state->m,state->cd,state->rd);*/
2580 LOGSTR1("block flags: %d\n",block->flags); LOGFLUSH;
2581 TYPECHECK_ASSERT(false);
2585 if (block->flags >= BBFINISHED) {
2586 block->flags = BBTYPECHECK_UNDEF;
2591 /* the first block is always reached */
2593 if (state->basicblockcount && state->basicblocks[0].flags == BBTYPECHECK_UNDEF)
2594 state->basicblocks[0].flags = BBTYPECHECK_REACHED;
2597 /* typecheck_reset_flags *******************************************************
2599 Reset the flags of basic blocks we have not reached.
2602 state............the current state of the verifier
2604 *******************************************************************************/
2607 typecheck_reset_flags(verifier_state *state)
2611 /* check for invalid flags at exit */
2613 #ifdef TYPECHECK_DEBUG
2614 for (i=0; i<state->basicblockcount; ++i) {
2615 if (state->basicblocks[i].flags != BBDELETED
2616 && state->basicblocks[i].flags != BBUNDEF
2617 && state->basicblocks[i].flags != BBFINISHED
2618 && state->basicblocks[i].flags != BBTYPECHECK_UNDEF) /* typecheck may never reach
2619 * some exception handlers,
2622 LOG2("block L%03d has invalid flags after typecheck: %d",
2623 state->basicblocks[i].nr,state->basicblocks[i].flags);
2624 TYPECHECK_ASSERT(false);
2629 /* Reset blocks we never reached */
2631 for (i=0; i<state->basicblockcount; ++i) {
2632 if (state->basicblocks[i].flags == BBTYPECHECK_UNDEF)
2633 state->basicblocks[i].flags = BBFINISHED;
2637 /****************************************************************************/
2639 /* This is the main function of the bytecode verifier. It is called */
2640 /* directly after analyse_stack. */
2643 /* meth.............the method to verify */
2644 /* cdata............codegendata for the method */
2645 /* rdata............registerdata for the method */
2648 /* true.............successful verification */
2649 /* false............an exception has been thrown */
2651 /****************************************************************************/
2653 #define MAXPARAMS 255
2655 bool typecheck(jitdata *jd)
2660 verifier_state state; /* current state of the verifier */
2661 int i; /* temporary counter */
2663 /* collect statistics */
2665 #ifdef TYPECHECK_STATISTICS
2666 int count_iterations = 0;
2667 TYPECHECK_COUNT(stat_typechecked);
2668 TYPECHECK_COUNT_FREQ(stat_locals,cdata->maxlocals,STAT_LOCALS);
2669 TYPECHECK_COUNT_FREQ(stat_blocks,cdata->method->basicblockcount/10,STAT_BLOCKS);
2670 TYPECHECK_COUNTIF(cdata->method->exceptiontablelength != 0,stat_methods_with_handlers);
2671 state.stat_maythrow = false;
2674 /* get required compiler data */
2680 /* some logging on entry */
2682 DOLOG(typecheck_logfile = stdout);
2683 LOGSTR("\n==============================================================================\n");
2684 /*DOLOG( show_icmd_method(cdata->method,cdata,rdata));*/
2685 LOGSTR("\n==============================================================================\n");
2686 LOGMETHOD("Entering typecheck: ",cdata->method);
2688 /* initialize the verifier state */
2690 state.savedstackbuf = NULL;
2691 state.savedstack = NULL;
2692 state.jsrencountered = false;
2697 state.basicblockcount = jd->new_basicblockcount;
2698 state.basicblocks = jd->new_basicblocks;
2700 /* check if this method is an instance initializer method */
2702 state.initmethod = (state.m->name == utf_init);
2704 /* initialize the basic block flags for the following CFG traversal */
2706 typecheck_init_flags(&state);
2708 /* number of local variables */
2710 /* In <init> methods we use an extra local variable to indicate whether */
2711 /* the 'this' reference has been initialized. */
2712 /* TYPE_VOID...means 'this' has not been initialized, */
2713 /* TYPE_INT....means 'this' has been initialized. */
2714 state.numlocals = state.cd->maxlocals;
2715 state.validlocals = state.numlocals;
2716 if (state.initmethod) state.numlocals++;
2718 /* allocate the buffers for local variables */
2720 state.localbuf = DMNEW_TYPEVECTOR(state.basicblockcount+1, state.numlocals);
2721 state.localset = MGET_TYPEVECTOR(state.localbuf,state.basicblockcount,state.numlocals);
2723 LOG("Variable buffer allocated.\n");
2725 /* allocate the buffer of active exception handlers */
2727 state.handlers = DMNEW(exceptiontable*, state.cd->exceptiontablelength + 1);
2729 /* initialized local variables of first block */
2731 if (!verify_init_locals(&state))
2734 /* initialize the input stack of exception handlers */
2736 state.excstack.prev = NULL;
2737 state.excstack.type = TYPE_ADR;
2738 typeinfo_init_classinfo(&(state.excstack.typeinfo),
2739 class_java_lang_Throwable); /* changed later */
2741 LOG("Exception handler stacks set.\n");
2743 /* loop while there are still blocks to be checked */
2745 TYPECHECK_COUNT(count_iterations);
2747 state.repeat = false;
2749 i = state.basicblockcount;
2750 state.bptr = state.basicblocks;
2753 LOGSTR1("---- BLOCK %04d, ",state.bptr->nr);
2754 LOGSTR1("blockflags: %d\n",state.bptr->flags);
2757 /* verify reached block */
2758 if (state.bptr->flags == BBTYPECHECK_REACHED) {
2759 if (!verify_basic_block(&state))
2763 } /* while blocks */
2765 LOGIF(state.repeat,"state.repeat == true");
2766 } while (state.repeat);
2770 #ifdef TYPECHECK_STATISTICS
2771 LOG1("Typechecker did %4d iterations",count_iterations);
2772 TYPECHECK_COUNT_FREQ(stat_iterations,count_iterations,STAT_ITERATIONS);
2773 TYPECHECK_COUNTIF(state.jsrencountered,stat_typechecked_jsr);
2774 TYPECHECK_COUNTIF(state.stat_maythrow,stat_methods_maythrow);
2777 /* reset the flags of blocks we haven't reached */
2779 typecheck_reset_flags(&state);
2781 /* everything's ok */
2783 LOGimp("exiting typecheck");
2786 #endif /* ENABLE_VERIFIER */
2789 * These are local overrides for various environment variables in Emacs.
2790 * Please do not remove this and leave it at the end of the file, where
2791 * Emacs will automagically detect them.
2792 * ---------------------------------------------------------------------
2795 * indent-tabs-mode: t
2799 * vim:noexpandtab:sw=4:ts=4: