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 5499 2006-09-14 20:36:33Z 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 *) Checks for uninitialized object instances are hard because after the
105 invocation of <init> on an uninitialized object *all* slots/variables
106 referring to this object (and exactly those slots/variables) must be
107 marked as initialized.
109 Solution: The JVM spec describes a solution, which has been
110 implemented in this typechecker.
115 [1] Actually only the types of slots/variables at the start of each
116 basic block are remembered. Within a basic block the algorithm only keeps
117 the types of the slots/variables for the "current" instruction which is
120 [2] Actually the algorithm iterates through the basic block list until
121 there are no more changes. Theoretically it would be wise to sort the
122 basic blocks topologically beforehand, but the number of average/max
123 iterations observed is so low, that this was not deemed necessary.
125 [3] This is similar to a method proposed by: Alessandro Coglio et al., A
126 Formal Specification of Java Class Loading, Technical Report, Kestrel
127 Institute April 2000, revised July 2000
128 http://www.kestrel.edu/home/people/coglio/loading.pdf
129 An important difference is that Coglio's subtype constraints are checked
130 after loading, while our constraints are checked when the field/method
131 is accessed for the first time, so we can guarantee lexically correct
140 #include "vm/types.h"
141 #include "vm/global.h"
143 #ifdef ENABLE_VERIFIER
145 #include "mm/memory.h"
146 #include "toolbox/logging.h"
147 #include "native/native.h"
148 #include "vm/builtin.h"
149 #include "vm/jit/patcher.h"
150 #include "vm/loader.h"
151 #include "vm/options.h"
152 #include "vm/jit/jit.h"
153 #include "vm/jit/show.h"
154 #include "vm/access.h"
155 #include "vm/resolve.h"
156 #include "vm/exceptions.h"
158 /****************************************************************************/
160 /****************************************************************************/
162 #ifdef TYPECHECK_DEBUG
163 #define TYPECHECK_ASSERT(cond) assert(cond)
165 #define TYPECHECK_ASSERT(cond)
168 #ifdef TYPECHECK_VERBOSE_OPT
169 bool opt_typecheckverbose = false;
170 #define DOLOG(action) do { if (opt_typecheckverbose) {action;} } while(0)
172 #define DOLOG(action)
175 #ifdef TYPECHECK_VERBOSE
176 #define TYPECHECK_VERBOSE_IMPORTANT
177 #define LOGNL DOLOG(puts(""))
178 #define LOG(str) DOLOG(puts(str);)
179 #define LOG1(str,a) DOLOG(printf(str,a); LOGNL)
180 #define LOG2(str,a,b) DOLOG(printf(str,a,b); LOGNL)
181 #define LOG3(str,a,b,c) DOLOG(printf(str,a,b,c); LOGNL)
182 #define LOGIF(cond,str) DOLOG(do {if (cond) { puts(str); }} while(0))
183 #ifdef TYPEINFO_DEBUG
184 #define LOGINFO(info) DOLOG(do {typeinfo_print_short(stdout,(info)); LOGNL;} while(0))
186 #define LOGINFO(info)
187 #define typevector_print(x,y,z)
189 #define LOGFLUSH DOLOG(fflush(stdout))
190 #define LOGSTR(str) DOLOG(printf("%s", str))
191 #define LOGSTR1(str,a) DOLOG(printf(str,a))
192 #define LOGSTR2(str,a,b) DOLOG(printf(str,a,b))
193 #define LOGSTR3(str,a,b,c) DOLOG(printf(str,a,b,c))
194 #define LOGNAME(c) DOLOG(class_classref_or_classinfo_print(c))
195 #define LOGMETHOD(str,m) DOLOG(printf("%s", str); method_println(m);)
199 #define LOG2(str,a,b)
200 #define LOG3(str,a,b,c)
201 #define LOGIF(cond,str)
202 #define LOGINFO(info)
206 #define LOGSTR1(str,a)
207 #define LOGSTR2(str,a,b)
208 #define LOGSTR3(str,a,b,c)
210 #define LOGMETHOD(str,m)
213 #ifdef TYPECHECK_VERBOSE_IMPORTANT
214 #define LOGimp(str) DOLOG(puts(str);LOGNL)
215 #define LOGimpSTR(str) DOLOG(puts(str))
218 #define LOGimpSTR(str)
221 #if defined(TYPECHECK_VERBOSE) || defined(TYPECHECK_VERBOSE_IMPORTANT)
225 static void typecheck_print_var(FILE *file, jitdata *jd, s4 index)
229 assert(index >= 0 && index < jd->varcount);
230 var = jd->var + index;
231 typeinfo_print_type(file, var->type, &(var->typeinfo));
234 static void typecheck_print_vararray(FILE *file, jitdata *jd, s4 *vars, int len)
238 for (i=0; i<len; ++i) {
241 typecheck_print_var(file, jd, *vars++);
248 /****************************************************************************/
250 /****************************************************************************/
252 #ifdef TYPECHECK_DEBUG
253 /*#define TYPECHECK_STATISTICS*/
256 #ifdef TYPECHECK_STATISTICS
257 #define STAT_ITERATIONS 10
258 #define STAT_BLOCKS 10
259 #define STAT_LOCALS 16
261 static int stat_typechecked = 0;
262 static int stat_methods_with_handlers = 0;
263 static int stat_methods_maythrow = 0;
264 static int stat_iterations[STAT_ITERATIONS+1] = { 0 };
265 static int stat_reached = 0;
266 static int stat_copied = 0;
267 static int stat_merged = 0;
268 static int stat_merging_changed = 0;
269 static int stat_backwards = 0;
270 static int stat_blocks[STAT_BLOCKS+1] = { 0 };
271 static int stat_locals[STAT_LOCALS+1] = { 0 };
272 static int stat_ins = 0;
273 static int stat_ins_maythrow = 0;
274 static int stat_ins_stack = 0;
275 static int stat_ins_field = 0;
276 static int stat_ins_field_unresolved = 0;
277 static int stat_ins_field_uninitialized = 0;
278 static int stat_ins_invoke = 0;
279 static int stat_ins_invoke_unresolved = 0;
280 static int stat_ins_primload = 0;
281 static int stat_ins_aload = 0;
282 static int stat_ins_builtin = 0;
283 static int stat_ins_builtin_gen = 0;
284 static int stat_ins_branch = 0;
285 static int stat_ins_switch = 0;
286 static int stat_ins_primitive_return = 0;
287 static int stat_ins_areturn = 0;
288 static int stat_ins_areturn_unresolved = 0;
289 static int stat_ins_athrow = 0;
290 static int stat_ins_athrow_unresolved = 0;
291 static int stat_ins_unchecked = 0;
292 static int stat_handlers_reached = 0;
293 static int stat_savedstack = 0;
295 #define TYPECHECK_MARK(var) ((var) = true)
296 #define TYPECHECK_COUNT(cnt) (cnt)++
297 #define TYPECHECK_COUNTIF(cond,cnt) do{if(cond) (cnt)++;} while(0)
298 #define TYPECHECK_COUNT_FREQ(array,val,limit) \
300 if ((val) < (limit)) (array)[val]++; \
301 else (array)[limit]++; \
304 static void print_freq(FILE *file,int *array,int limit)
307 for (i=0; i<limit; ++i)
308 fprintf(file," %3d: %8d\n",i,array[i]);
309 fprintf(file," >=%3d: %8d\n",limit,array[limit]);
312 void typecheck_print_statistics(FILE *file) {
313 fprintf(file,"typechecked methods: %8d\n",stat_typechecked);
314 fprintf(file," with handler(s): %8d\n",stat_methods_with_handlers);
315 fprintf(file," with throw(s) : %8d\n",stat_methods_maythrow);
316 fprintf(file,"reached blocks : %8d\n",stat_reached);
317 fprintf(file,"copied states : %8d\n",stat_copied);
318 fprintf(file,"merged states : %8d\n",stat_merged);
319 fprintf(file,"merging changed : %8d\n",stat_merging_changed);
320 fprintf(file,"backwards branches : %8d\n",stat_backwards);
321 fprintf(file,"handlers reached : %8d\n",stat_handlers_reached);
322 fprintf(file,"saved stack (times): %8d\n",stat_savedstack);
323 fprintf(file,"instructions : %8d\n",stat_ins);
324 fprintf(file," stack : %8d\n",stat_ins_stack);
325 fprintf(file," field access : %8d\n",stat_ins_field);
326 fprintf(file," (unresolved) : %8d\n",stat_ins_field_unresolved);
327 fprintf(file," (uninit.) : %8d\n",stat_ins_field_uninitialized);
328 fprintf(file," invocations : %8d\n",stat_ins_invoke);
329 fprintf(file," (unresolved) : %8d\n",stat_ins_invoke_unresolved);
330 fprintf(file," load primitive : (currently not counted) %8d\n",stat_ins_primload);
331 fprintf(file," load address : %8d\n",stat_ins_aload);
332 fprintf(file," builtins : %8d\n",stat_ins_builtin);
333 fprintf(file," generic : %8d\n",stat_ins_builtin_gen);
334 fprintf(file," branches : %8d\n",stat_ins_branch);
335 fprintf(file," switches : %8d\n",stat_ins_switch);
336 fprintf(file," prim. return : %8d\n",stat_ins_primitive_return);
337 fprintf(file," areturn : %8d\n",stat_ins_areturn);
338 fprintf(file," (unresolved) : %8d\n",stat_ins_areturn_unresolved);
339 fprintf(file," athrow : %8d\n",stat_ins_athrow);
340 fprintf(file," (unresolved) : %8d\n",stat_ins_athrow_unresolved);
341 fprintf(file," unchecked : %8d\n",stat_ins_unchecked);
342 fprintf(file," maythrow : %8d\n",stat_ins_maythrow);
343 fprintf(file,"iterations used:\n");
344 print_freq(file,stat_iterations,STAT_ITERATIONS);
345 fprintf(file,"basic blocks per method / 10:\n");
346 print_freq(file,stat_blocks,STAT_BLOCKS);
347 fprintf(file,"locals:\n");
348 print_freq(file,stat_locals,STAT_LOCALS);
353 #define TYPECHECK_COUNT(cnt)
354 #define TYPECHECK_MARK(var)
355 #define TYPECHECK_COUNTIF(cond,cnt)
356 #define TYPECHECK_COUNT_FREQ(array,val,limit)
360 /****************************************************************************/
361 /* MACROS FOR THROWING EXCEPTIONS */
362 /****************************************************************************/
364 #define TYPECHECK_VERIFYERROR_ret(m,msg,retval) \
366 exceptions_throw_verifyerror((m), (msg)); \
370 #define TYPECHECK_VERIFYERROR_main(msg) TYPECHECK_VERIFYERROR_ret(state.m,(msg),NULL)
371 #define TYPECHECK_VERIFYERROR_bool(msg) TYPECHECK_VERIFYERROR_ret(state->m,(msg),false)
374 /****************************************************************************/
375 /* MACROS FOR VARIABLE TYPE CHECKING */
376 /****************************************************************************/
378 #define TYPECHECK_CHECK_TYPE(i,tp,msg) \
380 if (VAR(i)->type != (tp)) { \
381 exceptions_throw_verifyerror(state->m, (msg)); \
386 #define TYPECHECK_INT(i) \
387 TYPECHECK_CHECK_TYPE(i,TYPE_INT,"Expected to find integer value")
388 #define TYPECHECK_LNG(i) \
389 TYPECHECK_CHECK_TYPE(i,TYPE_LNG,"Expected to find long value")
390 #define TYPECHECK_FLT(i) \
391 TYPECHECK_CHECK_TYPE(i,TYPE_FLT,"Expected to find float value")
392 #define TYPECHECK_DBL(i) \
393 TYPECHECK_CHECK_TYPE(i,TYPE_DBL,"Expected to find double value")
394 #define TYPECHECK_ADR(i) \
395 TYPECHECK_CHECK_TYPE(i,TYPE_ADR,"Expected to find object value")
397 #define TYPECHECK_INT_OP(o) TYPECHECK_INT((o).varindex)
398 #define TYPECHECK_LNG_OP(o) TYPECHECK_LNG((o).varindex)
399 #define TYPECHECK_FLT_OP(o) TYPECHECK_FLT((o).varindex)
400 #define TYPECHECK_DBL_OP(o) TYPECHECK_DBL((o).varindex)
401 #define TYPECHECK_ADR_OP(o) TYPECHECK_ADR((o).varindex)
404 /****************************************************************************/
405 /* VERIFIER STATE STRUCT */
406 /****************************************************************************/
408 /* verifier_state - This structure keeps the current state of the */
409 /* bytecode verifier for passing it between verifier functions. */
411 typedef struct verifier_state {
412 instruction *iptr; /* pointer to current instruction */
413 basicblock *bptr; /* pointer to current basic block */
415 methodinfo *m; /* the current method */
416 jitdata *jd; /* jitdata for current method */
417 codegendata *cd; /* codegendata for current method */
418 registerdata *rd; /* registerdata for current method */
420 basicblock *basicblocks;
423 s4 numlocals; /* number of local variables */
424 s4 validlocals; /* number of Java-accessible locals */
425 typedescriptor returntype; /* return type of the current method */
429 s4 *savedinvars; /* saved invar pointer */
433 exceptiontable **handlers; /* active exception handlers */
435 bool repeat; /* if true, blocks are iterated over again */
436 bool initmethod; /* true if this is an "<init>" method */
438 #ifdef TYPECHECK_STATISTICS
439 bool stat_maythrow; /* at least one instruction may throw */
444 /****************************************************************************/
445 /* TYPESTACK MACROS AND FUNCTIONS */
447 /* These macros and functions act on the 'type stack', which is a shorthand */
448 /* for the types of the stackslots of the current stack. The type of a */
449 /* stack slot is usually described by a TYPE_* constant and -- for TYPE_ADR */
450 /* -- by the typeinfo of the slot. The only thing that makes the type stack */
451 /* more complicated are returnAddresses of local subroutines, because a */
452 /* single stack slot may contain a set of more than one possible return */
453 /* address. This is handled by 'return address sets'. A return address set */
454 /* is kept as a linked list dangling off the typeinfo of the stack slot. */
455 /****************************************************************************/
457 /* typecheck_copy_types ********************************************************
459 Copy the types of the source variables to the destination variables.
462 state............current verifier state
463 srcvars..........array of variable indices to copy
464 dstvars..........array of the destination variables
465 n................number of variables to copy
468 true.............success
469 false............an exception has been thrown
471 *******************************************************************************/
474 typecheck_copy_types(verifier_state *state, s4 *srcvars, s4 *dstvars, s4 n)
479 jitdata *jd = state->jd;
481 for (i=0; i < n; ++i, ++srcvars, ++dstvars) {
486 if (dv->type == TYPE_ADR) {
487 TYPEINFO_CLONE(sv->typeinfo,dv->typeinfo);
494 /* typecheck_merge_types *******************************************************
496 Merge the types of the source variables into the destination variables.
499 state............current state of the verifier
500 srcvars..........source variable indices
501 dstvars..........destination variable indices
502 n................number of variables
505 typecheck_TRUE...the destination variables have been modified
506 typecheck_FALSE..the destination variables are unchanged
507 typecheck_FAIL...an exception has been thrown
509 *******************************************************************************/
511 static typecheck_result
512 typecheck_merge_types(verifier_state *state,s4 *srcvars, s4 *dstvars, s4 n)
517 jitdata *jd = state->jd;
519 bool changed = false;
521 for (i=0; i < n; ++i, ++srcvars, ++dstvars) {
525 if (dv->type != sv->type) {
526 exceptions_throw_verifyerror(state->m,"Stack type mismatch");
527 return typecheck_FAIL;
529 if (dv->type == TYPE_ADR) {
530 if (TYPEINFO_IS_PRIMITIVE(dv->typeinfo)) {
531 /* dv has returnAddress type */
532 if (!TYPEINFO_IS_PRIMITIVE(sv->typeinfo)) {
533 exceptions_throw_verifyerror(state->m,"Merging returnAddress with reference");
534 return typecheck_FAIL;
538 /* dv has reference type */
539 if (TYPEINFO_IS_PRIMITIVE(sv->typeinfo)) {
540 exceptions_throw_verifyerror(state->m,"Merging reference with returnAddress");
541 return typecheck_FAIL;
543 r = typeinfo_merge(state->m,&(dv->typeinfo),&(sv->typeinfo));
544 if (r == typecheck_FAIL)
554 /****************************************************************************/
555 /* TYPESTATE FUNCTIONS */
557 /* These functions act on the 'type state', which comprises: */
558 /* - the types of the stack slots of the current stack */
559 /* - the set of type vectors describing the local variables */
560 /****************************************************************************/
562 /* typestate_merge *************************************************************
564 Merge the types of one state into the destination state.
567 state............current state of the verifier
568 dstvars..........indices of the destinations invars
569 dstlocals........the destinations inlocals
570 srcvars..........indices of the source's outvars
571 srclocals........the source locals
572 n................number of invars (== number of outvars)
575 typecheck_TRUE...destination state has been modified
576 typecheck_FALSE..destination state has not been modified
577 typecheck_FAIL...an exception has been thrown
579 *******************************************************************************/
581 static typecheck_result
582 typestate_merge(verifier_state *state,
583 s4 *srcvars, varinfo *srclocals,
584 s4 *dstvars, varinfo *dstlocals,
587 bool changed = false;
592 LOGSTR("dstack: "); DOLOG(typestack_print(stdout,deststack)); LOGNL;
593 LOGSTR("ystack: "); DOLOG(typestack_print(stdout,ystack)); LOGNL;
594 LOGSTR("dloc : "); DOLOG(typevector_print(stdout,destloc,state->numlocals)); LOGNL;
595 LOGSTR("yloc : "); DOLOG(typevector_print(stdout,yloc,state->numlocals)); LOGNL;
599 /* The stack is always merged. If there are returnAddresses on
600 * the stack they are ignored in this step. */
602 r = typecheck_merge_types(state, srcvars, dstvars, n);
603 if (r == typecheck_FAIL)
607 /* merge the locals */
609 r = typevector_merge(state->m, dstlocals, srclocals, state->numlocals);
610 if (r == typecheck_FAIL)
616 /* typestate_reach *************************************************************
618 Reach a destination block and propagate stack and local variable types
621 state............current state of the verifier
622 destblock........destination basic block
623 srcvars..........variable indices of the outvars to propagate
624 srclocals........local variables to propagate
625 n................number of srcvars
628 state->repeat....set to true if the verifier must iterate again
629 over the basic blocks
632 true.............success
633 false............an exception has been thrown
635 *******************************************************************************/
638 typestate_reach(verifier_state *state,
639 basicblock *destblock,
640 s4 *srcvars, varinfo *srclocals, s4 n)
645 jitdata *jd = state->jd;
646 bool changed = false;
649 LOG1("reaching block L%03d",destblock->nr);
650 TYPECHECK_COUNT(stat_reached);
652 destloc = destblock->inlocals;
654 /* When branching backwards we have to check for uninitialized objects */
656 if (destblock <= state->bptr) {
657 TYPECHECK_COUNT(stat_backwards);
659 for (i=0; i<n; ++i) {
660 sv = VAR(srcvars[i]);
661 if (sv->type == TYPE_ADR &&
662 TYPEINFO_IS_NEWOBJECT(sv->typeinfo)) {
663 exceptions_throw_verifyerror(state->m,
664 "Branching backwards with uninitialized object on stack");
669 for (i=0; i<state->numlocals; ++i) {
671 if (sv->type == TYPE_ADR &&
672 TYPEINFO_IS_NEWOBJECT(sv->typeinfo)) {
673 exceptions_throw_verifyerror(state->m,
674 "Branching backwards with uninitialized object in local variable");
680 if (destblock->flags == BBTYPECHECK_UNDEF) {
681 /* The destblock has never been reached before */
683 TYPECHECK_COUNT(stat_copied);
684 LOG1("block L%03d reached first time",destblock->nr);
686 if (!typecheck_copy_types(state, srcvars, destblock->invars, n))
688 typevector_copy_inplace(srclocals, destloc, state->numlocals);
692 /* The destblock has already been reached before */
694 TYPECHECK_COUNT(stat_merged);
695 LOG1("block L%03d reached before", destblock->nr);
697 r = typestate_merge(state, srcvars, srclocals,
698 destblock->invars, destblock->inlocals, n);
699 if (r == typecheck_FAIL)
702 TYPECHECK_COUNTIF(changed,stat_merging_changed);
707 destblock->flags = BBTYPECHECK_REACHED;
708 if (destblock <= state->bptr) {
710 state->repeat = true;
717 /* typestate_save_invars *******************************************************
719 Save the invars of the current basic block in the space reserved by
722 This function must be called before an instruction modifies a variable
723 that is an invar of the current block. In such cases the invars of the
724 block must be saved, and restored at the end of the analysis of this
725 basic block, so that the invars again reflect the *input* to this basic
726 block (and do not randomly contain types that appear within the block).
729 state............current state of the verifier
731 *******************************************************************************/
734 typestate_save_invars(verifier_state *state)
739 LOG("saving invars");
741 if (!state->savedindices) {
742 LOG("allocating savedindices buffer");
743 pindex = DMNEW(s4, state->m->maxstack);
744 state->savedindices = pindex;
745 index = state->numlocals + VERIFIER_EXTRA_VARS;
746 for (i=0; i<state->m->maxstack; ++i)
752 typecheck_copy_types(state, state->bptr->invars, state->savedindices,
753 state->bptr->indepth);
755 /* set the invars of the block to the saved variables */
756 /* and remember the original invars */
758 state->savedinvars = state->bptr->invars;
759 state->bptr->invars = state->savedindices;
763 /* typestate_restore_invars ***************************************************
765 Restore the invars of the current basic block that have been previously
766 saved by `typestate_save_invars`.
769 state............current state of the verifier
771 *******************************************************************************/
774 typestate_restore_invars(verifier_state *state)
776 TYPECHECK_COUNT(stat_savedstack);
777 LOG("restoring saved invars");
779 /* restore the invars pointer */
781 state->bptr->invars = state->savedinvars;
783 /* copy the types back */
785 typecheck_copy_types(state, state->savedindices, state->bptr->invars,
786 state->bptr->indepth);
788 /* mark that there are no saved invars currently */
790 state->savedinvars = NULL;
794 /****************************************************************************/
796 /****************************************************************************/
798 #define COPYTYPE(source,dest) \
799 {if (VAROP(source)->type == TYPE_ADR) \
800 TYPEINFO_COPY(VAROP(source)->typeinfo,VAROP(dest)->typeinfo);}
802 #define ISBUILTIN(v) (bte->fp == (functionptr) (v))
805 /* verify_invocation ***********************************************************
807 Verify an ICMD_INVOKE* instruction.
810 state............the current state of the verifier
813 true.............successful verification,
814 false............an exception has been thrown.
816 *******************************************************************************/
819 verify_invocation(verifier_state *state)
821 unresolved_method *um; /* struct describing the called method */
822 constant_FMIref *mref; /* reference to the called method */
823 methodinfo *mi; /* resolved method (if any) */
824 methoddesc *md; /* descriptor of the called method */
825 utf *mname; /* method name */
826 utf *mclassname; /* name of the method's class */
827 bool specialmethod; /* true if a <...> method is called */
828 int opcode; /* invocation opcode */
829 bool callinginit; /* true if <init> is called */
831 classref_or_classinfo initclass;
833 s4 argindex; /* argument variable index */
834 varinfo *av; /* argument variable */
835 varinfo *dv; /* result variable of the invocation */
837 u1 rtype; /* return type of called method */
838 resolve_result_t result;
843 /* get the FMIref and the unresolved_method struct (if any) */
844 /* from the instruction */
846 if (INSTRUCTION_IS_UNRESOLVED(state->iptr)) {
847 /* unresolved method */
848 um = state->iptr->sx.s23.s3.um;
849 mref = um->methodref;
852 /* resolved method */
854 mref = state->iptr->sx.s23.s3.fmiref;
857 /* get method descriptor and name */
859 md = mref->parseddesc.md;
862 /* get method info (if resolved) and classname */
864 if (IS_FMIREF_RESOLVED(mref)) {
866 mclassname = mi->class->name;
870 mclassname = mref->p.classref->name;
873 specialmethod = (mname->text[0] == '<');
874 opcode = state->iptr[0].opc;
875 dv = VAROP(state->iptr->dst);
877 /* prevent compiler warnings */
881 /* check whether we are calling <init> */
883 callinginit = (opcode == ICMD_INVOKESPECIAL && mname == utf_init);
884 if (specialmethod && !callinginit)
885 TYPECHECK_VERIFYERROR_bool("Invalid invocation of special method");
887 /* allocate parameters if necessary */
890 if (!descriptor_params_from_paramtypes(md,
891 (opcode == ICMD_INVOKESTATIC) ? ACC_STATIC : ACC_NONE))
894 /* check parameter types */
896 i = md->paramcount; /* number of parameters including 'this'*/
899 argindex = state->iptr->sx.s23.s2.args[i];
901 td = md->paramtypes + i;
903 if (av->type != td->type)
904 TYPECHECK_VERIFYERROR_bool("Parameter type mismatch in method invocation");
906 if (av->type == TYPE_ADR) {
907 LOGINFO(&(av->typeinfo));
908 if (i==0 && callinginit)
910 /* first argument to <init> method */
911 if (!TYPEINFO_IS_NEWOBJECT(av->typeinfo))
912 TYPECHECK_VERIFYERROR_bool("Calling <init> on initialized object");
914 /* get the address of the NEW instruction */
915 LOGINFO(&(av->typeinfo));
916 ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(av->typeinfo);
918 initclass = ins[-1].sx.val.c;
920 initclass.cls = state->m->class;
921 LOGSTR("class: "); LOGNAME(initclass); LOGNL;
925 /* non-adress argument. if this is the first argument and we are */
926 /* invoking an instance method, this is an error. */
927 if (i==0 && opcode != ICMD_INVOKESTATIC) {
928 TYPECHECK_VERIFYERROR_bool("Parameter type mismatch for 'this' argument");
935 LOG("replacing uninitialized object");
936 /* replace uninitialized object type on stack */
938 /* for all live-in and live-through variables */
939 for (i=0; i<state->iptr->s1.argcount; ++i) {
940 argindex = state->iptr->sx.s23.s2.args[i];
942 if (av->type == TYPE_ADR
943 && TYPEINFO_IS_NEWOBJECT(av->typeinfo)
944 && TYPEINFO_NEWOBJECT_INSTRUCTION(av->typeinfo) == ins)
946 LOG("replacing uninitialized type");
948 /* If this stackslot is in the instack of
949 * this basic block we must save the type(s)
950 * we are going to replace.
952 /* XXX this needs a new check */
953 if (state->bptr->invars
954 && argindex >= state->bptr->invars[0]
955 && argindex < state->bptr->varstart
956 && !state->savedinvars)
958 typestate_save_invars(state);
961 if (!typeinfo_init_class(&(av->typeinfo),initclass))
966 /* replace uninitialized object type in locals */
967 if (!typevector_init_object(state->jd->var, ins, initclass,
971 /* initializing the 'this' reference? */
974 TYPECHECK_ASSERT(state->initmethod);
975 /* { we are initializing the 'this' reference } */
976 /* must be <init> of current class or direct superclass */
977 /* the current class is linked, so must be its superclass. thus we can be */
978 /* sure that resolving will be trivial. */
983 if (!resolve_classref(state->m,mref->p.classref,resolveLazy,false,true,&cls))
984 return false; /* exception */
987 /* if lazy resolving did not succeed, it's not one of the allowed classes */
988 /* otherwise we check it directly */
989 if (cls == NULL || (cls != state->m->class && cls != state->m->class->super.cls)) {
990 TYPECHECK_VERIFYERROR_bool("<init> calling <init> of the wrong class");
993 /* set our marker variable to type int */
994 LOG("setting <init> marker");
995 typevector_store(jd->var, state->numlocals-1, TYPE_INT, NULL);
998 /* { we are initializing an instance created with NEW } */
999 if ((IS_CLASSREF(initclass) ? initclass.ref->name : initclass.cls->name) != mclassname) {
1000 TYPECHECK_VERIFYERROR_bool("wrong <init> called for uninitialized reference");
1005 /* try to resolve the method lazily */
1007 result = new_resolve_method_lazy(jd, state->iptr, state->m);
1008 if (result == resolveFailed)
1011 if (result != resolveSucceeded) {
1013 um = new_create_unresolved_method(state->m->class,
1014 state->m, state->iptr);
1020 /* record subtype constraints for parameters */
1022 if (!new_constrain_unresolved_method(jd, um, state->m->class,
1023 state->m, state->iptr))
1024 return false; /* XXX maybe wrap exception */
1026 /* store the unresolved_method pointer */
1028 state->iptr->sx.s23.s3.um = um;
1029 state->iptr->flags.bits |= INS_FLAG_UNRESOLVED;
1032 assert(IS_FMIREF_RESOLVED(state->iptr->sx.s23.s3.fmiref));
1035 rtype = md->returntype.type;
1036 if (rtype != TYPE_VOID) {
1038 if (!typeinfo_init_from_typedesc(&(md->returntype),NULL,&(dv->typeinfo)))
1046 /* verify_generic_builtin ******************************************************
1048 Verify the call of a generic builtin method.
1051 state............the current state of the verifier
1054 true.............successful verification,
1055 false............an exception has been thrown.
1057 *******************************************************************************/
1060 verify_generic_builtin(verifier_state *state)
1062 builtintable_entry *bte;
1067 jitdata *jd = state->jd;
1069 TYPECHECK_COUNT(stat_ins_builtin_gen);
1071 bte = state->iptr->sx.s23.s3.bte;
1075 /* check the types of the arguments on the stack */
1077 for (i--; i >= 0; i--) {
1078 av = VAR(state->iptr->sx.s23.s2.args[i]);
1080 if (av->type != md->paramtypes[i].type) {
1081 TYPECHECK_VERIFYERROR_bool("parameter type mismatch for builtin method");
1084 #ifdef TYPECHECK_DEBUG
1085 /* generic builtins may only take primitive types and java.lang.Object references */
1086 if (av->type == TYPE_ADR && md->paramtypes[i].classref->name != utf_java_lang_Object) {
1087 *exceptionptr = new_internalerror("generic builtin method with non-generic reference parameter");
1093 /* set the return type */
1095 rtype = md->returntype.type;
1096 if (rtype != TYPE_VOID) {
1099 dv = VAROP(state->iptr->dst);
1101 if (!typeinfo_init_from_typedesc(&(md->returntype),NULL,&(dv->typeinfo)))
1109 /* verify_builtin **************************************************************
1111 Verify the call of a builtin method.
1114 state............the current state of the verifier
1117 true.............successful verification,
1118 false............an exception has been thrown.
1120 *******************************************************************************/
1123 verify_builtin(verifier_state *state)
1125 builtintable_entry *bte;
1126 classref_or_classinfo cls;
1127 varinfo *dv; /* output variable of current instruction */
1128 jitdata *jd = state->jd;
1130 bte = state->iptr->sx.s23.s3.bte;
1131 dv = VAROP(state->iptr->dst);
1133 /* XXX this is an ugly if-chain but twisti did not want a function */
1134 /* pointer in builtintable_entry for this, so here you go.. ;) */
1136 if (ISBUILTIN(BUILTIN_new)) {
1137 if (state->iptr[-1].opc != ICMD_ACONST)
1138 TYPECHECK_VERIFYERROR_bool("illegal instruction: builtin_new without class");
1139 cls = state->iptr[-1].sx.val.c;
1140 dv->type = TYPE_ADR;
1141 TYPEINFO_INIT_NEWOBJECT(dv->typeinfo,state->iptr);
1143 else if (ISBUILTIN(BUILTIN_newarray_boolean)) {
1144 TYPECHECK_INT(state->iptr->sx.s23.s2.args[0]);
1145 dv->type = TYPE_ADR;
1146 TYPEINFO_INIT_PRIMITIVE_ARRAY(dv->typeinfo,ARRAYTYPE_BOOLEAN);
1148 else if (ISBUILTIN(BUILTIN_newarray_char)) {
1149 TYPECHECK_INT(state->iptr->sx.s23.s2.args[0]);
1150 dv->type = TYPE_ADR;
1151 TYPEINFO_INIT_PRIMITIVE_ARRAY(dv->typeinfo,ARRAYTYPE_CHAR);
1153 else if (ISBUILTIN(BUILTIN_newarray_float)) {
1154 TYPECHECK_INT(state->iptr->sx.s23.s2.args[0]);
1155 dv->type = TYPE_ADR;
1156 TYPEINFO_INIT_PRIMITIVE_ARRAY(dv->typeinfo,ARRAYTYPE_FLOAT);
1158 else if (ISBUILTIN(BUILTIN_newarray_double)) {
1159 TYPECHECK_INT(state->iptr->sx.s23.s2.args[0]);
1160 dv->type = TYPE_ADR;
1161 TYPEINFO_INIT_PRIMITIVE_ARRAY(dv->typeinfo,ARRAYTYPE_DOUBLE);
1163 else if (ISBUILTIN(BUILTIN_newarray_byte)) {
1164 TYPECHECK_INT(state->iptr->sx.s23.s2.args[0]);
1165 dv->type = TYPE_ADR;
1166 TYPEINFO_INIT_PRIMITIVE_ARRAY(dv->typeinfo,ARRAYTYPE_BYTE);
1168 else if (ISBUILTIN(BUILTIN_newarray_short)) {
1169 TYPECHECK_INT(state->iptr->sx.s23.s2.args[0]);
1170 dv->type = TYPE_ADR;
1171 TYPEINFO_INIT_PRIMITIVE_ARRAY(dv->typeinfo,ARRAYTYPE_SHORT);
1173 else if (ISBUILTIN(BUILTIN_newarray_int)) {
1174 TYPECHECK_INT(state->iptr->sx.s23.s2.args[0]);
1175 dv->type = TYPE_ADR;
1176 TYPEINFO_INIT_PRIMITIVE_ARRAY(dv->typeinfo,ARRAYTYPE_INT);
1178 else if (ISBUILTIN(BUILTIN_newarray_long)) {
1179 TYPECHECK_INT(state->iptr->sx.s23.s2.args[0]);
1180 dv->type = TYPE_ADR;
1181 TYPEINFO_INIT_PRIMITIVE_ARRAY(dv->typeinfo,ARRAYTYPE_LONG);
1183 else if (ISBUILTIN(BUILTIN_newarray))
1185 TYPECHECK_INT(state->iptr->sx.s23.s2.args[0]);
1186 if (state->iptr[-1].opc != ICMD_ACONST)
1187 TYPECHECK_VERIFYERROR_bool("illegal instruction: builtin_newarray without class");
1188 /* XXX check that it is an array class(ref) */
1189 dv->type = TYPE_ADR;
1190 typeinfo_init_class(&(dv->typeinfo),state->iptr[-1].sx.val.c);
1192 else if (ISBUILTIN(BUILTIN_arrayinstanceof))
1194 TYPECHECK_ADR(state->iptr->sx.s23.s2.args[0]);
1195 if (state->iptr[-1].opc != ICMD_ACONST)
1196 TYPECHECK_VERIFYERROR_bool("illegal instruction: builtin_arrayinstanceof without class");
1197 dv->type = TYPE_INT;
1198 /* XXX check that it is an array class(ref) */
1201 return verify_generic_builtin(state);
1207 /* verify_multianewarray *******************************************************
1209 Verify a MULTIANEWARRAY instruction.
1212 state............the current state of the verifier
1215 true.............successful verification,
1216 false............an exception has been thrown.
1218 *******************************************************************************/
1221 verify_multianewarray(verifier_state *state)
1223 classinfo *arrayclass;
1224 arraydescriptor *desc;
1226 jitdata *jd = state->jd;
1228 /* check the array lengths on the stack */
1229 i = state->iptr->s1.argcount;
1231 TYPECHECK_VERIFYERROR_bool("Illegal dimension argument");
1234 TYPECHECK_INT(state->iptr->sx.s23.s2.args[i]);
1237 /* check array descriptor */
1238 if (INSTRUCTION_IS_RESOLVED(state->iptr)) {
1239 /* the array class reference has already been resolved */
1240 arrayclass = state->iptr->sx.s23.s3.c.cls;
1242 TYPECHECK_VERIFYERROR_bool("MULTIANEWARRAY with unlinked class");
1243 if ((desc = arrayclass->vftbl->arraydesc) == NULL)
1244 TYPECHECK_VERIFYERROR_bool("MULTIANEWARRAY with non-array class");
1245 if (desc->dimension < state->iptr->s1.argcount)
1246 TYPECHECK_VERIFYERROR_bool("MULTIANEWARRAY dimension to high");
1248 /* set the array type of the result */
1249 typeinfo_init_classinfo(&(VAROP(state->iptr->dst)->typeinfo), arrayclass);
1253 constant_classref *cr;
1255 /* the array class reference is still unresolved */
1256 /* check that the reference indicates an array class of correct dimension */
1257 cr = state->iptr->sx.s23.s3.c.ref;
1262 /* { the dimension of the array class == i } */
1264 TYPECHECK_VERIFYERROR_bool("MULTIANEWARRAY with non-array class");
1265 if (i < state->iptr->s1.argcount)
1266 TYPECHECK_VERIFYERROR_bool("MULTIANEWARRAY dimension to high");
1268 /* set the array type of the result */
1269 if (!typeinfo_init_class(&(VAROP(state->iptr->dst)->typeinfo),CLASSREF_OR_CLASSINFO(cr)))
1273 /* set return type */
1275 VAROP(state->iptr->dst)->type = TYPE_ADR;
1282 static void typecheck_invalidate_locals(verifier_state *state, s4 index, bool twoword)
1287 jitdata *jd = state->jd;
1288 s4 *localmap = jd->local_map;
1289 varinfo *vars = jd->var;
1291 i = state->reverselocalmap[index];
1294 localmap += 5 * (i-1);
1295 for (t=0; t<5; ++t) {
1296 mapped = *localmap++;
1297 if (mapped >= 0 && IS_2_WORD_TYPE(vars[mapped].type)) {
1298 LOG1("invalidate local %d", mapped);
1299 vars[mapped].type = TYPE_VOID;
1307 for (t=0; t<5; ++t) {
1308 mapped = *localmap++;
1310 LOG1("invalidate local %d", mapped);
1311 vars[mapped].type = TYPE_VOID;
1316 for (t=0; t<5; ++t) {
1317 mapped = *localmap++;
1319 LOG1("invalidate local %d", mapped);
1320 vars[mapped].type = TYPE_VOID;
1327 /* verify_basic_block **********************************************************
1329 Perform bytecode verification of a basic block.
1332 state............the current state of the verifier
1335 true.............successful verification,
1336 false............an exception has been thrown.
1338 *******************************************************************************/
1341 verify_basic_block(verifier_state *state)
1343 int opcode; /* current opcode */
1344 int len; /* for counting instructions, etc. */
1345 bool superblockend; /* true if no fallthrough to next block */
1346 instruction *iptr; /* the current instruction */
1347 basicblock *tbptr; /* temporary for target block */
1348 bool maythrow; /* true if this instruction may throw */
1349 unresolved_field *uf; /* for field accesses */
1350 constant_FMIref *fieldref; /* for field accesses */
1353 resolve_result_t result;
1354 branch_target_t *table;
1355 lookup_target_t *lookup;
1356 jitdata *jd = state->jd;
1360 LOGSTR1("\n---- BLOCK %04d ------------------------------------------------\n",state->bptr->nr);
1362 DOLOG(new_show_basicblock(jd, state->bptr, SHOW_STACK));
1364 superblockend = false;
1365 state->bptr->flags = BBFINISHED;
1367 /* prevent compiler warnings */
1371 /* determine the active exception handlers for this block */
1372 /* XXX could use a faster algorithm with sorted lists or */
1375 for (ex = state->cd->exceptiontable; ex ; ex = ex->down) {
1376 if ((ex->start <= state->bptr) && (ex->end > state->bptr)) {
1377 LOG1("active handler L%03d", ex->handler->nr);
1378 state->handlers[len++] = ex;
1381 state->handlers[len] = NULL;
1383 /* init variable types at the start of this block */
1384 typevector_copy_inplace(state->bptr->inlocals, jd->var, state->numlocals);
1386 if (state->handlers[0])
1387 for (i=0; i<state->numlocals; ++i)
1388 if (VAR(i)->type == TYPE_ADR
1389 && TYPEINFO_IS_NEWOBJECT(VAR(i)->typeinfo)) {
1390 /* XXX we do not check this for the uninitialized 'this' instance in */
1391 /* <init> methods. Otherwise there are problems with try blocks in */
1392 /* <init>. The spec seems to indicate that we should perform the test*/
1393 /* in all cases, but this fails with real code. */
1394 /* Example: org/eclipse/ui/internal/PerspectiveBarNewContributionItem*/
1395 /* of eclipse 3.0.2 */
1396 /* XXX Try to show that the check is not necessary for 'this'! */
1397 if (TYPEINFO_NEWOBJECT_INSTRUCTION(VAR(i)->typeinfo) != NULL) {
1398 /*show_icmd_method(state->m, state->cd, state->rd);*/
1399 printf("Uninitialized variable: %d, block: %d\n", i, state->bptr->nr);
1400 TYPECHECK_VERIFYERROR_bool("Uninitialized object in local variable inside try block");
1404 DOLOG(typecheck_print_vararray(stdout, jd, state->bptr->invars,
1405 state->bptr->indepth));
1406 DOLOG(typevector_print(stdout, jd->var, state->numlocals));
1409 /* loop over the instructions */
1410 len = state->bptr->icount;
1411 state->iptr = state->bptr->iinstr;
1412 while (--len >= 0) {
1413 TYPECHECK_COUNT(stat_ins);
1417 DOLOG(typevector_print(stdout, jd->var, state->numlocals));
1419 DOLOG(new_show_icmd(jd, state->iptr, false, SHOW_STACK)); LOGNL; LOGFLUSH;
1422 dv = VAROP(iptr->dst);
1427 /****************************************/
1428 /* STACK MANIPULATIONS */
1430 /* We just need to copy the typeinfo */
1431 /* for slots containing addresses. */
1435 TYPECHECK_COUNT(stat_ins_stack);
1436 COPYTYPE(iptr->s1, iptr->dst);
1437 dv->type = VAROP(iptr->s1)->type;
1440 /****************************************/
1441 /* PRIMITIVE VARIABLE ACCESS */
1443 case ICMD_ILOAD: if (!typevector_checktype(jd->var,state->iptr->s1.varindex,TYPE_INT))
1444 TYPECHECK_VERIFYERROR_bool("Local variable type mismatch");
1445 dv->type = TYPE_INT;
1447 case ICMD_IINC: if (!typevector_checktype(jd->var,state->iptr->s1.varindex,TYPE_INT))
1448 TYPECHECK_VERIFYERROR_bool("Local variable type mismatch");
1449 dv->type = TYPE_INT;
1451 case ICMD_FLOAD: if (!typevector_checktype(jd->var,state->iptr->s1.varindex,TYPE_FLT))
1452 TYPECHECK_VERIFYERROR_bool("Local variable type mismatch");
1453 dv->type = TYPE_FLT;
1455 case ICMD_LLOAD: if (!typevector_checktype(jd->var,state->iptr->s1.varindex,TYPE_LNG))
1456 TYPECHECK_VERIFYERROR_bool("Local variable type mismatch");
1457 dv->type = TYPE_LNG;
1459 case ICMD_DLOAD: if (!typevector_checktype(jd->var,state->iptr->s1.varindex,TYPE_DBL))
1460 TYPECHECK_VERIFYERROR_bool("Local variable type mismatch");
1461 dv->type = TYPE_DBL;
1465 typecheck_invalidate_locals(state, state->iptr->dst.varindex, false);
1466 typevector_store(jd->var,state->iptr->dst.varindex,TYPE_INT,NULL);
1469 typecheck_invalidate_locals(state, state->iptr->dst.varindex, false);
1470 typevector_store(jd->var,state->iptr->dst.varindex,TYPE_FLT,NULL);
1473 typecheck_invalidate_locals(state, state->iptr->dst.varindex, true);
1474 typevector_store(jd->var,state->iptr->dst.varindex,TYPE_LNG,NULL);
1477 typecheck_invalidate_locals(state, state->iptr->dst.varindex, true);
1478 typevector_store(jd->var,state->iptr->dst.varindex,TYPE_DBL,NULL);
1481 /****************************************/
1482 /* LOADING ADDRESS FROM VARIABLE */
1485 TYPECHECK_COUNT(stat_ins_aload);
1487 /* loading a returnAddress is not allowed */
1488 if (!TYPEDESC_IS_REFERENCE(jd->var[state->iptr->s1.varindex])) {
1489 TYPECHECK_VERIFYERROR_bool("illegal instruction: ALOAD loading non-reference");
1491 TYPEINFO_COPY(jd->var[state->iptr->s1.varindex].typeinfo,dv->typeinfo);
1492 dv->type = TYPE_ADR;
1495 /****************************************/
1496 /* STORING ADDRESS TO VARIABLE */
1499 if (state->handlers[0] && TYPEINFO_IS_NEWOBJECT(VAROP(state->iptr->s1)->typeinfo)) {
1500 TYPECHECK_VERIFYERROR_bool("Storing uninitialized object in local variable inside try block");
1503 typecheck_invalidate_locals(state, state->iptr->dst.varindex, false);
1505 if (TYPEINFO_IS_PRIMITIVE(VAROP(state->iptr->s1)->typeinfo)) {
1506 typevector_store_retaddr(jd->var,state->iptr->dst.varindex,&(VAROP(state->iptr->s1)->typeinfo));
1509 typevector_store(jd->var,state->iptr->dst.varindex,TYPE_ADR,
1510 &(VAROP(state->iptr->s1)->typeinfo));
1514 /****************************************/
1515 /* LOADING ADDRESS FROM ARRAY */
1518 if (!TYPEINFO_MAYBE_ARRAY_OF_REFS(VAROP(state->iptr->s1)->typeinfo))
1519 TYPECHECK_VERIFYERROR_bool("illegal instruction: AALOAD on non-reference array");
1521 if (!typeinfo_init_component(&VAROP(state->iptr->s1)->typeinfo,&dv->typeinfo))
1523 dv->type = TYPE_ADR;
1527 /****************************************/
1531 case ICMD_PUTSTATIC:
1532 case ICMD_PUTFIELDCONST:
1533 case ICMD_PUTSTATICCONST:
1534 TYPECHECK_COUNT(stat_ins_field);
1536 if (INSTRUCTION_IS_UNRESOLVED(state->iptr)) {
1537 uf = state->iptr->sx.s23.s3.uf;
1538 fieldref = uf->fieldref;
1542 fieldref = state->iptr->sx.s23.s3.fmiref;
1545 goto fieldaccess_tail;
1548 case ICMD_GETSTATIC:
1549 TYPECHECK_COUNT(stat_ins_field);
1551 if (INSTRUCTION_IS_UNRESOLVED(state->iptr)) {
1552 uf = state->iptr->sx.s23.s3.uf;
1553 fieldref = uf->fieldref;
1557 fieldref = state->iptr->sx.s23.s3.fmiref;
1560 /* the result is pushed on the stack */
1561 dv->type = fieldref->parseddesc.fd->type;
1562 if (dv->type == TYPE_ADR) {
1563 if (!typeinfo_init_from_typedesc(fieldref->parseddesc.fd,NULL,&(dv->typeinfo)))
1568 /* try to resolve the field reference lazily */
1569 result = new_resolve_field_lazy(jd, state->iptr, state->m);
1570 if (result == resolveFailed)
1573 if (result != resolveSucceeded) {
1575 uf = new_create_unresolved_field(state->m->class, state->m, state->iptr);
1579 state->iptr->sx.s23.s3.uf = uf;
1580 state->iptr->flags.bits |= INS_FLAG_UNRESOLVED;
1583 /* record the subtype constraints for this field access */
1584 if (!new_constrain_unresolved_field(jd, uf,state->m->class,state->m,state->iptr))
1585 return false; /* XXX maybe wrap exception? */
1587 TYPECHECK_COUNTIF(INSTRUCTION_IS_UNRESOLVED(state->iptr),stat_ins_field_unresolved);
1588 TYPECHECK_COUNTIF(INSTRUCTION_IS_RESOLVED(state->iptr) && !state->iptr->sx.s23.s3.fmiref->p.field->class->initialized,stat_ins_field_uninitialized);
1594 /****************************************/
1595 /* PRIMITIVE ARRAY ACCESS */
1597 case ICMD_ARRAYLENGTH:
1598 if (!TYPEINFO_MAYBE_ARRAY(VAROP(state->iptr->s1)->typeinfo)
1599 && VAROP(state->iptr->s1)->typeinfo.typeclass.cls != pseudo_class_Arraystub)
1600 TYPECHECK_VERIFYERROR_bool("illegal instruction: ARRAYLENGTH on non-array");
1601 dv->type = TYPE_INT;
1606 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_BOOLEAN)
1607 && !TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_BYTE))
1608 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1609 dv->type = TYPE_INT;
1613 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_CHAR))
1614 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1615 dv->type = TYPE_INT;
1619 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_DOUBLE))
1620 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1621 dv->type = TYPE_DBL;
1625 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_FLOAT))
1626 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1627 dv->type = TYPE_FLT;
1631 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_INT))
1632 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1633 dv->type = TYPE_INT;
1637 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_SHORT))
1638 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1639 dv->type = TYPE_INT;
1643 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_LONG))
1644 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1645 dv->type = TYPE_LNG;
1650 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_BOOLEAN)
1651 && !TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_BYTE))
1652 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1656 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_CHAR))
1657 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1661 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_DOUBLE))
1662 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1666 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_FLOAT))
1667 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1671 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_INT))
1672 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1676 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_SHORT))
1677 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1681 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_LONG))
1682 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1687 /* we just check the basic input types and that the */
1688 /* destination is an array of references. Assignability to */
1689 /* the actual array must be checked at runtime, each time the */
1690 /* instruction is performed. (See builtin_canstore.) */
1691 TYPECHECK_ADR_OP(state->iptr->sx.s23.s3);
1692 TYPECHECK_INT_OP(state->iptr->sx.s23.s2);
1693 TYPECHECK_ADR_OP(state->iptr->s1);
1694 if (!TYPEINFO_MAYBE_ARRAY_OF_REFS(VAROP(state->iptr->s1)->typeinfo))
1695 TYPECHECK_VERIFYERROR_bool("illegal instruction: AASTORE to non-reference array");
1699 case ICMD_IASTORECONST:
1700 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo, ARRAYTYPE_INT))
1701 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1705 case ICMD_LASTORECONST:
1706 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo, ARRAYTYPE_LONG))
1707 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1711 case ICMD_BASTORECONST:
1712 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo, ARRAYTYPE_BOOLEAN)
1713 && !TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo, ARRAYTYPE_BYTE))
1714 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1718 case ICMD_CASTORECONST:
1719 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo, ARRAYTYPE_CHAR))
1720 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1724 case ICMD_SASTORECONST:
1725 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo, ARRAYTYPE_SHORT))
1726 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1730 /****************************************/
1731 /* ADDRESS CONSTANTS */
1734 if (state->iptr->flags.bits & INS_FLAG_CLASS) {
1735 /* a java.lang.Class reference */
1736 TYPEINFO_INIT_JAVA_LANG_CLASS(dv->typeinfo,state->iptr->sx.val.c);
1739 if (state->iptr->sx.val.anyptr == NULL)
1740 TYPEINFO_INIT_NULLTYPE(dv->typeinfo);
1742 /* string constant (or constant for builtin function) */
1743 typeinfo_init_classinfo(&(dv->typeinfo),class_java_lang_String);
1746 dv->type = TYPE_ADR;
1749 /****************************************/
1750 /* CHECKCAST AND INSTANCEOF */
1752 case ICMD_CHECKCAST:
1753 TYPECHECK_ADR_OP(state->iptr->s1);
1754 /* returnAddress is not allowed */
1755 if (!TYPEINFO_IS_REFERENCE(VAROP(state->iptr->s1)->typeinfo))
1756 TYPECHECK_VERIFYERROR_bool("Illegal instruction: CHECKCAST on non-reference");
1758 if (!typeinfo_init_class(&(dv->typeinfo),state->iptr->sx.s23.s3.c))
1760 dv->type = TYPE_ADR;
1764 case ICMD_INSTANCEOF:
1765 TYPECHECK_ADR_OP(state->iptr->s1);
1766 /* returnAddress is not allowed */
1767 if (!TYPEINFO_IS_REFERENCE(VAROP(state->iptr->s1)->typeinfo))
1768 TYPECHECK_VERIFYERROR_bool("Illegal instruction: INSTANCEOF on non-reference");
1769 dv->type = TYPE_INT;
1772 /****************************************/
1773 /* BRANCH INSTRUCTIONS */
1775 case ICMD_INLINE_GOTO:
1776 COPYTYPE(state->iptr->s1,state->iptr->dst);
1779 superblockend = true;
1782 case ICMD_IFNONNULL:
1789 case ICMD_IF_ICMPEQ:
1790 case ICMD_IF_ICMPNE:
1791 case ICMD_IF_ICMPLT:
1792 case ICMD_IF_ICMPGE:
1793 case ICMD_IF_ICMPGT:
1794 case ICMD_IF_ICMPLE:
1795 case ICMD_IF_ACMPEQ:
1796 case ICMD_IF_ACMPNE:
1805 case ICMD_IF_LCMPEQ:
1806 case ICMD_IF_LCMPNE:
1807 case ICMD_IF_LCMPLT:
1808 case ICMD_IF_LCMPGE:
1809 case ICMD_IF_LCMPGT:
1810 case ICMD_IF_LCMPLE:
1812 case ICMD_IF_FCMPEQ:
1813 case ICMD_IF_FCMPNE:
1815 case ICMD_IF_FCMPL_LT:
1816 case ICMD_IF_FCMPL_GE:
1817 case ICMD_IF_FCMPL_GT:
1818 case ICMD_IF_FCMPL_LE:
1820 case ICMD_IF_FCMPG_LT:
1821 case ICMD_IF_FCMPG_GE:
1822 case ICMD_IF_FCMPG_GT:
1823 case ICMD_IF_FCMPG_LE:
1825 case ICMD_IF_DCMPEQ:
1826 case ICMD_IF_DCMPNE:
1828 case ICMD_IF_DCMPL_LT:
1829 case ICMD_IF_DCMPL_GE:
1830 case ICMD_IF_DCMPL_GT:
1831 case ICMD_IF_DCMPL_LE:
1833 case ICMD_IF_DCMPG_LT:
1834 case ICMD_IF_DCMPG_GE:
1835 case ICMD_IF_DCMPG_GT:
1836 case ICMD_IF_DCMPG_LE:
1837 TYPECHECK_COUNT(stat_ins_branch);
1839 /* propagate stack and variables to the target block */
1840 if (!typestate_reach(state, state->iptr->dst.block,
1841 state->bptr->outvars, jd->var,
1842 state->bptr->outdepth))
1846 /****************************************/
1849 case ICMD_TABLESWITCH:
1850 TYPECHECK_COUNT(stat_ins_switch);
1852 table = iptr->dst.table;
1853 i = iptr->sx.s23.s3.tablehigh
1854 - iptr->sx.s23.s2.tablelow + 1 + 1; /* plus default */
1857 tbptr = (table++)->block;
1858 LOG2("target %d is block %04d",i,tbptr->nr);
1859 if (!typestate_reach(state, tbptr, state->bptr->outvars,
1860 jd->var, state->bptr->outdepth))
1865 superblockend = true;
1868 case ICMD_LOOKUPSWITCH:
1869 TYPECHECK_COUNT(stat_ins_switch);
1871 lookup = iptr->dst.lookup;
1872 i = iptr->sx.s23.s2.lookupcount;
1874 if (!typestate_reach(state,iptr->sx.s23.s3.lookupdefault.block,
1875 state->bptr->outvars, jd->var,
1876 state->bptr->outdepth))
1880 tbptr = (lookup++)->target.block;
1881 LOG2("target %d is block %04d",i,tbptr->nr);
1882 if (!typestate_reach(state, tbptr, state->bptr->outvars,
1883 jd->var, state->bptr->outdepth))
1888 superblockend = true;
1892 /****************************************/
1893 /* ADDRESS RETURNS AND THROW */
1896 TYPECHECK_COUNT(stat_ins_athrow);
1897 r = typeinfo_is_assignable_to_class(&VAROP(state->iptr->s1)->typeinfo,
1898 CLASSREF_OR_CLASSINFO(class_java_lang_Throwable));
1899 if (r == typecheck_FALSE)
1900 TYPECHECK_VERIFYERROR_bool("illegal instruction: ATHROW on non-Throwable");
1901 if (r == typecheck_FAIL)
1903 if (r == typecheck_MAYBE) {
1904 /* the check has to be postponed. we need a patcher */
1905 TYPECHECK_COUNT(stat_ins_athrow_unresolved);
1906 iptr->sx.s23.s2.uc = create_unresolved_class(
1908 /* XXX make this more efficient, use class_java_lang_Throwable
1910 class_get_classref(state->m->class,utf_java_lang_Throwable),
1911 &VAROP(state->iptr->s1)->typeinfo);
1912 iptr->flags.bits |= INS_FLAG_UNRESOLVED;
1914 superblockend = true;
1919 TYPECHECK_COUNT(stat_ins_areturn);
1920 if (!TYPEINFO_IS_REFERENCE(VAROP(state->iptr->s1)->typeinfo))
1921 TYPECHECK_VERIFYERROR_bool("illegal instruction: ARETURN on non-reference");
1923 if (state->returntype.type != TYPE_ADR
1924 || (r = typeinfo_is_assignable(&VAROP(state->iptr->s1)->typeinfo,&(state->returntype.typeinfo)))
1926 TYPECHECK_VERIFYERROR_bool("Return type mismatch");
1927 if (r == typecheck_FAIL)
1929 if (r == typecheck_MAYBE) {
1930 /* the check has to be postponed, we need a patcher */
1931 TYPECHECK_COUNT(stat_ins_areturn_unresolved);
1932 iptr->sx.s23.s2.uc = create_unresolved_class(
1934 state->m->parseddesc->returntype.classref,
1935 &VAROP(state->iptr->s1)->typeinfo);
1936 iptr->flags.bits |= INS_FLAG_UNRESOLVED;
1940 /****************************************/
1941 /* PRIMITIVE RETURNS */
1944 if (state->returntype.type != TYPE_INT) TYPECHECK_VERIFYERROR_bool("Return type mismatch");
1948 if (state->returntype.type != TYPE_LNG) TYPECHECK_VERIFYERROR_bool("Return type mismatch");
1952 if (state->returntype.type != TYPE_FLT) TYPECHECK_VERIFYERROR_bool("Return type mismatch");
1956 if (state->returntype.type != TYPE_DBL) TYPECHECK_VERIFYERROR_bool("Return type mismatch");
1960 if (state->returntype.type != TYPE_VOID) TYPECHECK_VERIFYERROR_bool("Return type mismatch");
1962 TYPECHECK_COUNT(stat_ins_primitive_return);
1964 if (state->initmethod && state->m->class != class_java_lang_Object) {
1965 /* Check if the 'this' instance has been initialized. */
1966 LOG("Checking <init> marker");
1967 if (!typevector_checktype(jd->var,state->numlocals-1,TYPE_INT))
1968 TYPECHECK_VERIFYERROR_bool("<init> method does not initialize 'this'");
1971 superblockend = true;
1975 /****************************************/
1976 /* SUBROUTINE INSTRUCTIONS */
1981 tbptr = state->iptr->sx.s23.s3.jsrtarget.block;
1982 TYPEINFO_INIT_RETURNADDRESS(dv->typeinfo, state->bptr->next);
1983 if (!typestate_reach(state, tbptr, state->bptr->outvars, jd->var,
1984 state->bptr->outdepth))
1987 superblockend = true;
1991 /* check returnAddress variable */
1992 if (!typevector_checkretaddr(jd->var,state->iptr->s1.varindex))
1993 TYPECHECK_VERIFYERROR_bool("illegal instruction: RET using non-returnAddress variable");
1995 if (!typestate_reach(state, iptr->dst.block, state->bptr->outvars, jd->var,
1996 state->bptr->outdepth))
1999 superblockend = true;
2002 /****************************************/
2005 case ICMD_INVOKEVIRTUAL:
2006 case ICMD_INVOKESPECIAL:
2007 case ICMD_INVOKESTATIC:
2008 case ICMD_INVOKEINTERFACE:
2009 TYPECHECK_COUNT(stat_ins_invoke);
2010 if (!verify_invocation(state))
2012 TYPECHECK_COUNTIF(INSTRUCTION_IS_UNRESOLVED(iptr), stat_ins_invoke_unresolved);
2016 /****************************************/
2017 /* MULTIANEWARRAY */
2019 case ICMD_MULTIANEWARRAY:
2020 if (!verify_multianewarray(state))
2025 /****************************************/
2029 TYPECHECK_COUNT(stat_ins_builtin);
2030 if (!verify_builtin(state))
2035 /****************************************/
2036 /* SIMPLE EXCEPTION THROWING TESTS */
2038 case ICMD_CHECKNULL:
2039 /* CHECKNULL just requires that the stack top
2040 * is an address. This is checked in stack.c */
2044 /****************************************/
2045 /* INSTRUCTIONS WHICH SHOULD HAVE BEEN */
2046 /* REPLACED BY OTHER OPCODES */
2048 #ifdef TYPECHECK_DEBUG
2051 case ICMD_ANEWARRAY:
2052 case ICMD_MONITORENTER:
2053 case ICMD_MONITOREXIT:
2054 LOG2("ICMD %d at %d\n", state->iptr->opc, (int)(state->iptr-state->bptr->iinstr));
2055 LOG("Should have been converted to builtin function call.");
2056 TYPECHECK_ASSERT(false);
2060 /****************************************/
2061 /* UNCHECKED OPERATIONS */
2063 /*********************************************
2064 * Instructions below...
2065 * *) don't operate on local variables,
2066 * *) don't operate on references,
2067 * *) don't operate on returnAddresses,
2068 * *) don't affect control flow (except
2069 * by throwing exceptions).
2071 * (These instructions are typechecked in
2073 ********************************************/
2075 /* Instructions which may throw a runtime exception: */
2079 dv->type = TYPE_INT;
2085 dv->type = TYPE_LNG;
2089 /* Instructions which never throw a runtime exception: */
2108 case ICMD_IADDCONST:
2109 case ICMD_ISUBCONST:
2110 case ICMD_IMULCONST:
2111 case ICMD_IANDCONST:
2113 case ICMD_IXORCONST:
2114 case ICMD_ISHLCONST:
2115 case ICMD_ISHRCONST:
2116 case ICMD_IUSHRCONST:
2120 case ICMD_INT2SHORT:
2125 case ICMD_LCMPCONST:
2130 dv->type = TYPE_INT;
2146 case ICMD_LADDCONST:
2147 case ICMD_LSUBCONST:
2148 case ICMD_LMULCONST:
2149 case ICMD_LANDCONST:
2151 case ICMD_LXORCONST:
2152 case ICMD_LSHLCONST:
2153 case ICMD_LSHRCONST:
2154 case ICMD_LUSHRCONST:
2159 dv->type = TYPE_LNG;
2172 dv->type = TYPE_FLT;
2185 dv->type = TYPE_DBL;
2188 case ICMD_INLINE_START:
2189 case ICMD_INLINE_END:
2192 /* XXX What shall we do with the following ?*/
2193 case ICMD_AASTORECONST:
2194 TYPECHECK_COUNT(stat_ins_unchecked);
2197 /****************************************/
2200 LOG2("ICMD %d at %d\n", state->iptr->opc, (int)(state->iptr-state->bptr->iinstr));
2201 TYPECHECK_VERIFYERROR_bool("Missing ICMD code during typecheck");
2204 /* reach exception handlers for this instruction */
2207 TYPECHECK_COUNT(stat_ins_maythrow);
2208 TYPECHECK_MARK(state->stat_maythrow);
2209 LOG("reaching exception handlers");
2211 while (state->handlers[i]) {
2212 TYPECHECK_COUNT(stat_handlers_reached);
2213 if (state->handlers[i]->catchtype.any)
2214 VAR(state->exinvars)->typeinfo.typeclass = state->handlers[i]->catchtype;
2216 VAR(state->exinvars)->typeinfo.typeclass.cls = class_java_lang_Throwable;
2217 if (!typestate_reach(state,
2218 state->handlers[i]->handler,
2219 &(state->exinvars), jd->var, 1))
2225 LOG("\t\tnext instruction");
2227 } /* while instructions */
2229 LOG("instructions done");
2230 LOGSTR("RESULT=> ");
2231 DOLOG(typecheck_print_vararray(stdout, jd, state->bptr->outvars,
2232 state->bptr->outdepth));
2233 DOLOG(typevector_print(stdout, jd->var, state->numlocals));
2236 /* propagate stack and variables to the following block */
2237 if (!superblockend) {
2238 LOG("reaching following block");
2239 tbptr = state->bptr->next;
2240 while (tbptr->flags == BBDELETED) {
2241 tbptr = tbptr->next;
2242 #ifdef TYPECHECK_DEBUG
2243 /* this must be checked in parse.c */
2244 if ((tbptr->nr) >= state->basicblockcount)
2245 TYPECHECK_VERIFYERROR_bool("Control flow falls off the last block");
2248 if (!typestate_reach(state,tbptr,state->bptr->outvars, jd->var,
2249 state->bptr->outdepth))
2253 /* We may have to restore the types of the instack slots. They
2254 * have been saved if an <init> call inside the block has
2255 * modified the instack types. (see INVOKESPECIAL) */
2257 if (state->savedinvars)
2258 typestate_restore_invars(state);
2264 /* verify_init_locals **********************************************************
2266 Initialize the local variables in the verifier state.
2269 state............the current state of the verifier
2272 true.............success,
2273 false............an exception has been thrown.
2275 *******************************************************************************/
2278 verify_init_locals(verifier_state *state)
2284 jitdata *jd = state->jd;
2287 locals = state->basicblocks[0].inlocals;
2289 /* allocate parameter descriptors if necessary */
2291 if (!state->m->parseddesc->params)
2292 if (!descriptor_params_from_paramtypes(state->m->parseddesc,state->m->flags))
2295 /* pre-initialize variables as TYPE_VOID */
2297 i = state->numlocals;
2300 v->type = TYPE_VOID;
2304 /* if this is an instance method initialize the "this" ref type */
2306 if (!(state->m->flags & ACC_STATIC)) {
2307 index = jd->local_map[5*0 + TYPE_ADR];
2308 if (index != UNUSED) {
2309 if (state->validlocals < 1)
2310 TYPECHECK_VERIFYERROR_bool("Not enough local variables for method arguments");
2313 if (state->initmethod)
2314 TYPEINFO_INIT_NEWOBJECT(v->typeinfo, NULL);
2316 typeinfo_init_classinfo(&(v->typeinfo), state->m->class);
2322 LOG("'this' argument set.\n");
2324 /* the rest of the arguments and the return type */
2326 if (!typeinfo_init_varinfos_from_methoddesc(locals, state->m->parseddesc,
2328 skip, /* skip 'this' pointer */
2330 &state->returntype))
2333 LOG("Arguments set.\n");
2338 /* typecheck_init_flags ********************************************************
2340 Initialize the basic block flags for the following CFG traversal.
2343 state............the current state of the verifier
2345 *******************************************************************************/
2348 typecheck_init_flags(verifier_state *state)
2353 /* set all BBFINISHED blocks to BBTYPECHECK_UNDEF. */
2355 i = state->basicblockcount;
2356 for (block = state->basicblocks; block; block = block->next) {
2358 #ifdef TYPECHECK_DEBUG
2359 /* check for invalid flags */
2360 if (block->flags != BBFINISHED && block->flags != BBDELETED && block->flags != BBUNDEF)
2362 /*show_icmd_method(state->m,state->cd,state->rd);*/
2363 LOGSTR1("block flags: %d\n",block->flags); LOGFLUSH;
2364 TYPECHECK_ASSERT(false);
2368 if (block->flags >= BBFINISHED) {
2369 block->flags = BBTYPECHECK_UNDEF;
2373 /* the first block is always reached */
2375 if (state->basicblockcount && state->basicblocks[0].flags == BBTYPECHECK_UNDEF)
2376 state->basicblocks[0].flags = BBTYPECHECK_REACHED;
2380 /* typecheck_reset_flags *******************************************************
2382 Reset the flags of basic blocks we have not reached.
2385 state............the current state of the verifier
2387 *******************************************************************************/
2390 typecheck_reset_flags(verifier_state *state)
2394 /* check for invalid flags at exit */
2396 #ifdef TYPECHECK_DEBUG
2397 for (block = state->basicblocks; block; block = block->next) {
2398 if (block->flags != BBDELETED
2399 && block->flags != BBUNDEF
2400 && block->flags != BBFINISHED
2401 && block->flags != BBTYPECHECK_UNDEF) /* typecheck may never reach
2402 * some exception handlers,
2405 LOG2("block L%03d has invalid flags after typecheck: %d",
2406 block->nr,block->flags);
2407 TYPECHECK_ASSERT(false);
2412 /* Reset blocks we never reached */
2414 for (block = state->basicblocks; block; block = block->next) {
2415 if (block->flags == BBTYPECHECK_UNDEF)
2416 block->flags = BBFINISHED;
2421 /****************************************************************************/
2423 /* This is the main function of the bytecode verifier. It is called */
2424 /* directly after analyse_stack. */
2427 /* meth.............the method to verify */
2428 /* cdata............codegendata for the method */
2429 /* rdata............registerdata for the method */
2432 /* true.............successful verification */
2433 /* false............an exception has been thrown */
2435 /****************************************************************************/
2437 #define MAXPARAMS 255
2439 bool typecheck(jitdata *jd)
2444 varinfo *savedlocals;
2445 verifier_state state; /* current state of the verifier */
2449 /* collect statistics */
2451 #ifdef TYPECHECK_STATISTICS
2452 int count_iterations = 0;
2453 TYPECHECK_COUNT(stat_typechecked);
2454 TYPECHECK_COUNT_FREQ(stat_locals,cdata->maxlocals,STAT_LOCALS);
2455 TYPECHECK_COUNT_FREQ(stat_blocks,cdata->method->basicblockcount/10,STAT_BLOCKS);
2456 TYPECHECK_COUNTIF(cdata->method->exceptiontablelength != 0,stat_methods_with_handlers);
2457 state.stat_maythrow = false;
2460 /* get required compiler data */
2466 /* some logging on entry */
2469 LOGSTR("\n==============================================================================\n");
2470 DOLOG( new_show_method(jd, SHOW_STACK) );
2471 LOGSTR("\n==============================================================================\n");
2472 LOGMETHOD("Entering typecheck: ",cd->method);
2474 /* initialize the verifier state */
2480 state.basicblockcount = jd->new_basicblockcount;
2481 state.basicblocks = jd->new_basicblocks;
2482 state.savedindices = NULL;
2483 state.savedinvars = NULL;
2485 /* check if this method is an instance initializer method */
2487 state.initmethod = (state.m->name == utf_init);
2489 /* initialize the basic block flags for the following CFG traversal */
2491 typecheck_init_flags(&state);
2493 /* number of local variables */
2495 /* In <init> methods we use an extra local variable to indicate whether */
2496 /* the 'this' reference has been initialized. */
2497 /* TYPE_VOID...means 'this' has not been initialized, */
2498 /* TYPE_INT....means 'this' has been initialized. */
2500 state.numlocals = state.jd->localcount;
2501 state.validlocals = state.numlocals;
2502 if (state.initmethod)
2503 state.numlocals++; /* VERIFIER_EXTRA_LOCALS */
2505 state.reverselocalmap = DMNEW(s4, state.validlocals);
2506 for (i=0; i<jd->m->maxlocals; ++i)
2507 for (t=0; t<5; ++t) {
2508 s4 mapped = jd->local_map[5*i + t];
2510 state.reverselocalmap[mapped] = i;
2513 /* allocate the buffer of active exception handlers */
2515 state.handlers = DMNEW(exceptiontable*, state.cd->exceptiontablelength + 1);
2517 /* save local variables */
2519 savedlocals = DMNEW(varinfo, state.numlocals);
2520 MCOPY(savedlocals, jd->var, varinfo, state.numlocals);
2522 /* initialized local variables of first block */
2524 if (!verify_init_locals(&state))
2527 /* initialize invars of exception handlers */
2529 state.exinvars = state.numlocals;
2530 VAR(state.exinvars)->type = TYPE_ADR;
2531 typeinfo_init_classinfo(&(VAR(state.exinvars)->typeinfo),
2532 class_java_lang_Throwable); /* changed later */
2534 LOG("Exception handler stacks set.\n");
2536 /* loop while there are still blocks to be checked */
2538 TYPECHECK_COUNT(count_iterations);
2540 state.repeat = false;
2542 state.bptr = state.basicblocks;
2544 for (; state.bptr; state.bptr = state.bptr->next) {
2545 LOGSTR1("---- BLOCK %04d, ",state.bptr->nr);
2546 LOGSTR1("blockflags: %d\n",state.bptr->flags);
2549 /* verify reached block */
2550 if (state.bptr->flags == BBTYPECHECK_REACHED) {
2551 if (!verify_basic_block(&state))
2556 LOGIF(state.repeat,"state.repeat == true");
2557 } while (state.repeat);
2561 #ifdef TYPECHECK_STATISTICS
2562 LOG1("Typechecker did %4d iterations",count_iterations);
2563 TYPECHECK_COUNT_FREQ(stat_iterations,count_iterations,STAT_ITERATIONS);
2564 TYPECHECK_COUNTIF(state.jsrencountered,stat_typechecked_jsr);
2565 TYPECHECK_COUNTIF(state.stat_maythrow,stat_methods_maythrow);
2568 /* reset the flags of blocks we haven't reached */
2570 typecheck_reset_flags(&state);
2572 /* restore locals */
2574 MCOPY(jd->var, savedlocals, varinfo, state.numlocals);
2576 /* everything's ok */
2578 LOGimp("exiting typecheck");
2581 #endif /* ENABLE_VERIFIER */
2584 * These are local overrides for various environment variables in Emacs.
2585 * Please do not remove this and leave it at the end of the file, where
2586 * Emacs will automagically detect them.
2587 * ---------------------------------------------------------------------
2590 * indent-tabs-mode: t
2594 * vim:noexpandtab:sw=4:ts=4: