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 5514 2006-09-15 14:18:19Z 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 if (destblock->flags == BBTYPECHECK_UNDEF) {
655 /* The destblock has never been reached before */
657 TYPECHECK_COUNT(stat_copied);
658 LOG1("block L%03d reached first time",destblock->nr);
660 if (!typecheck_copy_types(state, srcvars, destblock->invars, n))
662 typevector_copy_inplace(srclocals, destloc, state->numlocals);
666 /* The destblock has already been reached before */
668 TYPECHECK_COUNT(stat_merged);
669 LOG1("block L%03d reached before", destblock->nr);
671 r = typestate_merge(state, srcvars, srclocals,
672 destblock->invars, destblock->inlocals, n);
673 if (r == typecheck_FAIL)
676 TYPECHECK_COUNTIF(changed,stat_merging_changed);
681 destblock->flags = BBTYPECHECK_REACHED;
682 if (destblock <= state->bptr) {
684 state->repeat = true;
691 /* typestate_save_invars *******************************************************
693 Save the invars of the current basic block in the space reserved by
696 This function must be called before an instruction modifies a variable
697 that is an invar of the current block. In such cases the invars of the
698 block must be saved, and restored at the end of the analysis of this
699 basic block, so that the invars again reflect the *input* to this basic
700 block (and do not randomly contain types that appear within the block).
703 state............current state of the verifier
705 *******************************************************************************/
708 typestate_save_invars(verifier_state *state)
713 LOG("saving invars");
715 if (!state->savedindices) {
716 LOG("allocating savedindices buffer");
717 pindex = DMNEW(s4, state->m->maxstack);
718 state->savedindices = pindex;
719 index = state->numlocals + VERIFIER_EXTRA_VARS;
720 for (i=0; i<state->m->maxstack; ++i)
726 typecheck_copy_types(state, state->bptr->invars, state->savedindices,
727 state->bptr->indepth);
729 /* set the invars of the block to the saved variables */
730 /* and remember the original invars */
732 state->savedinvars = state->bptr->invars;
733 state->bptr->invars = state->savedindices;
737 /* typestate_restore_invars ***************************************************
739 Restore the invars of the current basic block that have been previously
740 saved by `typestate_save_invars`.
743 state............current state of the verifier
745 *******************************************************************************/
748 typestate_restore_invars(verifier_state *state)
750 TYPECHECK_COUNT(stat_savedstack);
751 LOG("restoring saved invars");
753 /* restore the invars pointer */
755 state->bptr->invars = state->savedinvars;
757 /* copy the types back */
759 typecheck_copy_types(state, state->savedindices, state->bptr->invars,
760 state->bptr->indepth);
762 /* mark that there are no saved invars currently */
764 state->savedinvars = NULL;
768 /****************************************************************************/
770 /****************************************************************************/
772 #define COPYTYPE(source,dest) \
773 {if (VAROP(source)->type == TYPE_ADR) \
774 TYPEINFO_COPY(VAROP(source)->typeinfo,VAROP(dest)->typeinfo);}
776 #define ISBUILTIN(v) (bte->fp == (functionptr) (v))
779 /* verify_invocation ***********************************************************
781 Verify an ICMD_INVOKE* instruction.
784 state............the current state of the verifier
787 true.............successful verification,
788 false............an exception has been thrown.
790 *******************************************************************************/
793 verify_invocation(verifier_state *state)
795 unresolved_method *um; /* struct describing the called method */
796 constant_FMIref *mref; /* reference to the called method */
797 methodinfo *mi; /* resolved method (if any) */
798 methoddesc *md; /* descriptor of the called method */
799 utf *mname; /* method name */
800 utf *mclassname; /* name of the method's class */
801 bool specialmethod; /* true if a <...> method is called */
802 int opcode; /* invocation opcode */
803 bool callinginit; /* true if <init> is called */
805 classref_or_classinfo initclass;
807 s4 argindex; /* argument variable index */
808 varinfo *av; /* argument variable */
809 varinfo *dv; /* result variable of the invocation */
811 u1 rtype; /* return type of called method */
812 resolve_result_t result;
817 /* get the FMIref and the unresolved_method struct (if any) */
818 /* from the instruction */
820 if (INSTRUCTION_IS_UNRESOLVED(state->iptr)) {
821 /* unresolved method */
822 um = state->iptr->sx.s23.s3.um;
823 mref = um->methodref;
826 /* resolved method */
828 mref = state->iptr->sx.s23.s3.fmiref;
831 /* get method descriptor and name */
833 md = mref->parseddesc.md;
836 /* get method info (if resolved) and classname */
838 if (IS_FMIREF_RESOLVED(mref)) {
840 mclassname = mi->class->name;
844 mclassname = mref->p.classref->name;
847 specialmethod = (mname->text[0] == '<');
848 opcode = state->iptr[0].opc;
849 dv = VAROP(state->iptr->dst);
851 /* prevent compiler warnings */
855 /* check whether we are calling <init> */
857 callinginit = (opcode == ICMD_INVOKESPECIAL && mname == utf_init);
858 if (specialmethod && !callinginit)
859 TYPECHECK_VERIFYERROR_bool("Invalid invocation of special method");
861 /* allocate parameters if necessary */
864 if (!descriptor_params_from_paramtypes(md,
865 (opcode == ICMD_INVOKESTATIC) ? ACC_STATIC : ACC_NONE))
868 /* check parameter types */
870 i = md->paramcount; /* number of parameters including 'this'*/
873 argindex = state->iptr->sx.s23.s2.args[i];
875 td = md->paramtypes + i;
877 if (av->type != td->type)
878 TYPECHECK_VERIFYERROR_bool("Parameter type mismatch in method invocation");
880 if (av->type == TYPE_ADR) {
881 LOGINFO(&(av->typeinfo));
882 if (i==0 && callinginit)
884 /* first argument to <init> method */
885 if (!TYPEINFO_IS_NEWOBJECT(av->typeinfo))
886 TYPECHECK_VERIFYERROR_bool("Calling <init> on initialized object");
888 /* get the address of the NEW instruction */
889 LOGINFO(&(av->typeinfo));
890 ins = (instruction *) TYPEINFO_NEWOBJECT_INSTRUCTION(av->typeinfo);
892 initclass = ins[-1].sx.val.c;
894 initclass.cls = state->m->class;
895 LOGSTR("class: "); LOGNAME(initclass); LOGNL;
899 /* non-adress argument. if this is the first argument and we are */
900 /* invoking an instance method, this is an error. */
901 if (i==0 && opcode != ICMD_INVOKESTATIC) {
902 TYPECHECK_VERIFYERROR_bool("Parameter type mismatch for 'this' argument");
909 LOG("replacing uninitialized object");
910 /* replace uninitialized object type on stack */
912 /* for all live-in and live-through variables */
913 for (i=0; i<state->iptr->s1.argcount; ++i) {
914 argindex = state->iptr->sx.s23.s2.args[i];
916 if (av->type == TYPE_ADR
917 && TYPEINFO_IS_NEWOBJECT(av->typeinfo)
918 && TYPEINFO_NEWOBJECT_INSTRUCTION(av->typeinfo) == ins)
920 LOG("replacing uninitialized type");
922 /* If this stackslot is in the instack of
923 * this basic block we must save the type(s)
924 * we are going to replace.
926 /* XXX this needs a new check */
927 if (state->bptr->invars
928 && argindex >= state->bptr->invars[0]
929 && argindex < state->bptr->varstart
930 && !state->savedinvars)
932 typestate_save_invars(state);
935 if (!typeinfo_init_class(&(av->typeinfo),initclass))
940 /* replace uninitialized object type in locals */
941 if (!typevector_init_object(state->jd->var, ins, initclass,
945 /* initializing the 'this' reference? */
948 TYPECHECK_ASSERT(state->initmethod);
949 /* { we are initializing the 'this' reference } */
950 /* must be <init> of current class or direct superclass */
951 /* the current class is linked, so must be its superclass. thus we can be */
952 /* sure that resolving will be trivial. */
957 if (!resolve_classref(state->m,mref->p.classref,resolveLazy,false,true,&cls))
958 return false; /* exception */
961 /* if lazy resolving did not succeed, it's not one of the allowed classes */
962 /* otherwise we check it directly */
963 if (cls == NULL || (cls != state->m->class && cls != state->m->class->super.cls)) {
964 TYPECHECK_VERIFYERROR_bool("<init> calling <init> of the wrong class");
967 /* set our marker variable to type int */
968 LOG("setting <init> marker");
969 typevector_store(jd->var, state->numlocals-1, TYPE_INT, NULL);
972 /* { we are initializing an instance created with NEW } */
973 if ((IS_CLASSREF(initclass) ? initclass.ref->name : initclass.cls->name) != mclassname) {
974 TYPECHECK_VERIFYERROR_bool("wrong <init> called for uninitialized reference");
979 /* try to resolve the method lazily */
981 result = new_resolve_method_lazy(jd, state->iptr, state->m);
982 if (result == resolveFailed)
985 if (result != resolveSucceeded) {
987 um = new_create_unresolved_method(state->m->class,
988 state->m, state->iptr);
994 /* record subtype constraints for parameters */
996 if (!new_constrain_unresolved_method(jd, um, state->m->class,
997 state->m, state->iptr))
998 return false; /* XXX maybe wrap exception */
1000 /* store the unresolved_method pointer */
1002 state->iptr->sx.s23.s3.um = um;
1003 state->iptr->flags.bits |= INS_FLAG_UNRESOLVED;
1006 assert(IS_FMIREF_RESOLVED(state->iptr->sx.s23.s3.fmiref));
1009 rtype = md->returntype.type;
1010 if (rtype != TYPE_VOID) {
1012 if (!typeinfo_init_from_typedesc(&(md->returntype),NULL,&(dv->typeinfo)))
1020 /* verify_generic_builtin ******************************************************
1022 Verify the call of a generic builtin method.
1025 state............the current state of the verifier
1028 true.............successful verification,
1029 false............an exception has been thrown.
1031 *******************************************************************************/
1034 verify_generic_builtin(verifier_state *state)
1036 builtintable_entry *bte;
1041 jitdata *jd = state->jd;
1043 TYPECHECK_COUNT(stat_ins_builtin_gen);
1045 bte = state->iptr->sx.s23.s3.bte;
1049 /* check the types of the arguments on the stack */
1051 for (i--; i >= 0; i--) {
1052 av = VAR(state->iptr->sx.s23.s2.args[i]);
1054 if (av->type != md->paramtypes[i].type) {
1055 TYPECHECK_VERIFYERROR_bool("parameter type mismatch for builtin method");
1058 #ifdef TYPECHECK_DEBUG
1059 /* generic builtins may only take primitive types and java.lang.Object references */
1060 if (av->type == TYPE_ADR && md->paramtypes[i].classref->name != utf_java_lang_Object) {
1061 *exceptionptr = new_internalerror("generic builtin method with non-generic reference parameter");
1067 /* set the return type */
1069 rtype = md->returntype.type;
1070 if (rtype != TYPE_VOID) {
1073 dv = VAROP(state->iptr->dst);
1075 if (!typeinfo_init_from_typedesc(&(md->returntype),NULL,&(dv->typeinfo)))
1083 /* verify_builtin **************************************************************
1085 Verify the call of a builtin method.
1088 state............the current state of the verifier
1091 true.............successful verification,
1092 false............an exception has been thrown.
1094 *******************************************************************************/
1097 verify_builtin(verifier_state *state)
1099 builtintable_entry *bte;
1100 classref_or_classinfo cls;
1101 varinfo *dv; /* output variable of current instruction */
1102 jitdata *jd = state->jd;
1104 bte = state->iptr->sx.s23.s3.bte;
1105 dv = VAROP(state->iptr->dst);
1107 /* XXX this is an ugly if-chain but twisti did not want a function */
1108 /* pointer in builtintable_entry for this, so here you go.. ;) */
1110 if (ISBUILTIN(BUILTIN_new)) {
1111 if (state->iptr[-1].opc != ICMD_ACONST)
1112 TYPECHECK_VERIFYERROR_bool("illegal instruction: builtin_new without class");
1113 cls = state->iptr[-1].sx.val.c;
1114 dv->type = TYPE_ADR;
1115 TYPEINFO_INIT_NEWOBJECT(dv->typeinfo,state->iptr);
1117 else if (ISBUILTIN(BUILTIN_newarray_boolean)) {
1118 TYPECHECK_INT(state->iptr->sx.s23.s2.args[0]);
1119 dv->type = TYPE_ADR;
1120 TYPEINFO_INIT_PRIMITIVE_ARRAY(dv->typeinfo,ARRAYTYPE_BOOLEAN);
1122 else if (ISBUILTIN(BUILTIN_newarray_char)) {
1123 TYPECHECK_INT(state->iptr->sx.s23.s2.args[0]);
1124 dv->type = TYPE_ADR;
1125 TYPEINFO_INIT_PRIMITIVE_ARRAY(dv->typeinfo,ARRAYTYPE_CHAR);
1127 else if (ISBUILTIN(BUILTIN_newarray_float)) {
1128 TYPECHECK_INT(state->iptr->sx.s23.s2.args[0]);
1129 dv->type = TYPE_ADR;
1130 TYPEINFO_INIT_PRIMITIVE_ARRAY(dv->typeinfo,ARRAYTYPE_FLOAT);
1132 else if (ISBUILTIN(BUILTIN_newarray_double)) {
1133 TYPECHECK_INT(state->iptr->sx.s23.s2.args[0]);
1134 dv->type = TYPE_ADR;
1135 TYPEINFO_INIT_PRIMITIVE_ARRAY(dv->typeinfo,ARRAYTYPE_DOUBLE);
1137 else if (ISBUILTIN(BUILTIN_newarray_byte)) {
1138 TYPECHECK_INT(state->iptr->sx.s23.s2.args[0]);
1139 dv->type = TYPE_ADR;
1140 TYPEINFO_INIT_PRIMITIVE_ARRAY(dv->typeinfo,ARRAYTYPE_BYTE);
1142 else if (ISBUILTIN(BUILTIN_newarray_short)) {
1143 TYPECHECK_INT(state->iptr->sx.s23.s2.args[0]);
1144 dv->type = TYPE_ADR;
1145 TYPEINFO_INIT_PRIMITIVE_ARRAY(dv->typeinfo,ARRAYTYPE_SHORT);
1147 else if (ISBUILTIN(BUILTIN_newarray_int)) {
1148 TYPECHECK_INT(state->iptr->sx.s23.s2.args[0]);
1149 dv->type = TYPE_ADR;
1150 TYPEINFO_INIT_PRIMITIVE_ARRAY(dv->typeinfo,ARRAYTYPE_INT);
1152 else if (ISBUILTIN(BUILTIN_newarray_long)) {
1153 TYPECHECK_INT(state->iptr->sx.s23.s2.args[0]);
1154 dv->type = TYPE_ADR;
1155 TYPEINFO_INIT_PRIMITIVE_ARRAY(dv->typeinfo,ARRAYTYPE_LONG);
1157 else if (ISBUILTIN(BUILTIN_newarray))
1159 TYPECHECK_INT(state->iptr->sx.s23.s2.args[0]);
1160 if (state->iptr[-1].opc != ICMD_ACONST)
1161 TYPECHECK_VERIFYERROR_bool("illegal instruction: builtin_newarray without class");
1162 /* XXX check that it is an array class(ref) */
1163 dv->type = TYPE_ADR;
1164 typeinfo_init_class(&(dv->typeinfo),state->iptr[-1].sx.val.c);
1166 else if (ISBUILTIN(BUILTIN_arrayinstanceof))
1168 TYPECHECK_ADR(state->iptr->sx.s23.s2.args[0]);
1169 if (state->iptr[-1].opc != ICMD_ACONST)
1170 TYPECHECK_VERIFYERROR_bool("illegal instruction: builtin_arrayinstanceof without class");
1171 dv->type = TYPE_INT;
1172 /* XXX check that it is an array class(ref) */
1175 return verify_generic_builtin(state);
1181 /* verify_multianewarray *******************************************************
1183 Verify a MULTIANEWARRAY instruction.
1186 state............the current state of the verifier
1189 true.............successful verification,
1190 false............an exception has been thrown.
1192 *******************************************************************************/
1195 verify_multianewarray(verifier_state *state)
1197 classinfo *arrayclass;
1198 arraydescriptor *desc;
1200 jitdata *jd = state->jd;
1202 /* check the array lengths on the stack */
1203 i = state->iptr->s1.argcount;
1205 TYPECHECK_VERIFYERROR_bool("Illegal dimension argument");
1208 TYPECHECK_INT(state->iptr->sx.s23.s2.args[i]);
1211 /* check array descriptor */
1212 if (INSTRUCTION_IS_RESOLVED(state->iptr)) {
1213 /* the array class reference has already been resolved */
1214 arrayclass = state->iptr->sx.s23.s3.c.cls;
1216 TYPECHECK_VERIFYERROR_bool("MULTIANEWARRAY with unlinked class");
1217 if ((desc = arrayclass->vftbl->arraydesc) == NULL)
1218 TYPECHECK_VERIFYERROR_bool("MULTIANEWARRAY with non-array class");
1219 if (desc->dimension < state->iptr->s1.argcount)
1220 TYPECHECK_VERIFYERROR_bool("MULTIANEWARRAY dimension to high");
1222 /* set the array type of the result */
1223 typeinfo_init_classinfo(&(VAROP(state->iptr->dst)->typeinfo), arrayclass);
1227 constant_classref *cr;
1229 /* the array class reference is still unresolved */
1230 /* check that the reference indicates an array class of correct dimension */
1231 cr = state->iptr->sx.s23.s3.c.ref;
1236 /* { the dimension of the array class == i } */
1238 TYPECHECK_VERIFYERROR_bool("MULTIANEWARRAY with non-array class");
1239 if (i < state->iptr->s1.argcount)
1240 TYPECHECK_VERIFYERROR_bool("MULTIANEWARRAY dimension to high");
1242 /* set the array type of the result */
1243 if (!typeinfo_init_class(&(VAROP(state->iptr->dst)->typeinfo),CLASSREF_OR_CLASSINFO(cr)))
1247 /* set return type */
1249 VAROP(state->iptr->dst)->type = TYPE_ADR;
1256 static void typecheck_invalidate_locals(verifier_state *state, s4 index, bool twoword)
1261 jitdata *jd = state->jd;
1262 s4 *localmap = jd->local_map;
1263 varinfo *vars = jd->var;
1265 i = state->reverselocalmap[index];
1268 localmap += 5 * (i-1);
1269 for (t=0; t<5; ++t) {
1270 mapped = *localmap++;
1271 if (mapped >= 0 && IS_2_WORD_TYPE(vars[mapped].type)) {
1272 LOG1("invalidate local %d", mapped);
1273 vars[mapped].type = TYPE_VOID;
1281 for (t=0; t<5; ++t) {
1282 mapped = *localmap++;
1284 LOG1("invalidate local %d", mapped);
1285 vars[mapped].type = TYPE_VOID;
1290 for (t=0; t<5; ++t) {
1291 mapped = *localmap++;
1293 LOG1("invalidate local %d", mapped);
1294 vars[mapped].type = TYPE_VOID;
1301 /* verify_basic_block **********************************************************
1303 Perform bytecode verification of a basic block.
1306 state............the current state of the verifier
1309 true.............successful verification,
1310 false............an exception has been thrown.
1312 *******************************************************************************/
1315 verify_basic_block(verifier_state *state)
1317 int opcode; /* current opcode */
1318 int len; /* for counting instructions, etc. */
1319 bool superblockend; /* true if no fallthrough to next block */
1320 instruction *iptr; /* the current instruction */
1321 basicblock *tbptr; /* temporary for target block */
1322 bool maythrow; /* true if this instruction may throw */
1323 unresolved_field *uf; /* for field accesses */
1324 constant_FMIref *fieldref; /* for field accesses */
1327 resolve_result_t result;
1328 branch_target_t *table;
1329 lookup_target_t *lookup;
1330 jitdata *jd = state->jd;
1334 LOGSTR1("\n---- BLOCK %04d ------------------------------------------------\n",state->bptr->nr);
1336 DOLOG(new_show_basicblock(jd, state->bptr, SHOW_STACK));
1338 superblockend = false;
1339 state->bptr->flags = BBFINISHED;
1341 /* prevent compiler warnings */
1345 /* determine the active exception handlers for this block */
1346 /* XXX could use a faster algorithm with sorted lists or */
1349 for (ex = state->cd->exceptiontable; ex ; ex = ex->down) {
1350 if ((ex->start->nr <= state->bptr->nr) && (ex->end->nr > state->bptr->nr)) {
1351 LOG1("active handler L%03d", ex->handler->nr);
1352 state->handlers[len++] = ex;
1355 state->handlers[len] = NULL;
1357 /* init variable types at the start of this block */
1358 typevector_copy_inplace(state->bptr->inlocals, jd->var, state->numlocals);
1360 DOLOG(typecheck_print_vararray(stdout, jd, state->bptr->invars,
1361 state->bptr->indepth));
1362 DOLOG(typevector_print(stdout, jd->var, state->numlocals));
1365 /* loop over the instructions */
1366 len = state->bptr->icount;
1367 state->iptr = state->bptr->iinstr;
1368 while (--len >= 0) {
1369 TYPECHECK_COUNT(stat_ins);
1373 DOLOG(typevector_print(stdout, jd->var, state->numlocals));
1375 DOLOG(new_show_icmd(jd, state->iptr, false, SHOW_STACK)); LOGNL; LOGFLUSH;
1378 dv = VAROP(iptr->dst);
1383 /****************************************/
1384 /* STACK MANIPULATIONS */
1386 /* We just need to copy the typeinfo */
1387 /* for slots containing addresses. */
1391 TYPECHECK_COUNT(stat_ins_stack);
1392 COPYTYPE(iptr->s1, iptr->dst);
1393 dv->type = VAROP(iptr->s1)->type;
1396 /****************************************/
1397 /* PRIMITIVE VARIABLE ACCESS */
1399 case ICMD_ILOAD: if (!typevector_checktype(jd->var,state->iptr->s1.varindex,TYPE_INT))
1400 TYPECHECK_VERIFYERROR_bool("Local variable type mismatch");
1401 dv->type = TYPE_INT;
1403 case ICMD_IINC: if (!typevector_checktype(jd->var,state->iptr->s1.varindex,TYPE_INT))
1404 TYPECHECK_VERIFYERROR_bool("Local variable type mismatch");
1405 dv->type = TYPE_INT;
1407 case ICMD_FLOAD: if (!typevector_checktype(jd->var,state->iptr->s1.varindex,TYPE_FLT))
1408 TYPECHECK_VERIFYERROR_bool("Local variable type mismatch");
1409 dv->type = TYPE_FLT;
1411 case ICMD_LLOAD: if (!typevector_checktype(jd->var,state->iptr->s1.varindex,TYPE_LNG))
1412 TYPECHECK_VERIFYERROR_bool("Local variable type mismatch");
1413 dv->type = TYPE_LNG;
1415 case ICMD_DLOAD: if (!typevector_checktype(jd->var,state->iptr->s1.varindex,TYPE_DBL))
1416 TYPECHECK_VERIFYERROR_bool("Local variable type mismatch");
1417 dv->type = TYPE_DBL;
1421 typecheck_invalidate_locals(state, state->iptr->dst.varindex, false);
1422 typevector_store(jd->var,state->iptr->dst.varindex,TYPE_INT,NULL);
1425 typecheck_invalidate_locals(state, state->iptr->dst.varindex, false);
1426 typevector_store(jd->var,state->iptr->dst.varindex,TYPE_FLT,NULL);
1429 typecheck_invalidate_locals(state, state->iptr->dst.varindex, true);
1430 typevector_store(jd->var,state->iptr->dst.varindex,TYPE_LNG,NULL);
1433 typecheck_invalidate_locals(state, state->iptr->dst.varindex, true);
1434 typevector_store(jd->var,state->iptr->dst.varindex,TYPE_DBL,NULL);
1437 /****************************************/
1438 /* LOADING ADDRESS FROM VARIABLE */
1441 TYPECHECK_COUNT(stat_ins_aload);
1443 /* loading a returnAddress is not allowed */
1444 if (!TYPEDESC_IS_REFERENCE(jd->var[state->iptr->s1.varindex])) {
1445 TYPECHECK_VERIFYERROR_bool("illegal instruction: ALOAD loading non-reference");
1447 TYPEINFO_COPY(jd->var[state->iptr->s1.varindex].typeinfo,dv->typeinfo);
1448 dv->type = TYPE_ADR;
1451 /****************************************/
1452 /* STORING ADDRESS TO VARIABLE */
1455 typecheck_invalidate_locals(state, state->iptr->dst.varindex, false);
1457 if (TYPEINFO_IS_PRIMITIVE(VAROP(state->iptr->s1)->typeinfo)) {
1458 typevector_store_retaddr(jd->var,state->iptr->dst.varindex,&(VAROP(state->iptr->s1)->typeinfo));
1461 typevector_store(jd->var,state->iptr->dst.varindex,TYPE_ADR,
1462 &(VAROP(state->iptr->s1)->typeinfo));
1466 /****************************************/
1467 /* LOADING ADDRESS FROM ARRAY */
1470 if (!TYPEINFO_MAYBE_ARRAY_OF_REFS(VAROP(state->iptr->s1)->typeinfo))
1471 TYPECHECK_VERIFYERROR_bool("illegal instruction: AALOAD on non-reference array");
1473 if (!typeinfo_init_component(&VAROP(state->iptr->s1)->typeinfo,&dv->typeinfo))
1475 dv->type = TYPE_ADR;
1479 /****************************************/
1483 case ICMD_PUTSTATIC:
1484 case ICMD_PUTFIELDCONST:
1485 case ICMD_PUTSTATICCONST:
1487 case ICMD_GETSTATIC:
1488 TYPECHECK_COUNT(stat_ins_field);
1490 if (INSTRUCTION_IS_UNRESOLVED(state->iptr)) {
1491 uf = state->iptr->sx.s23.s3.uf;
1492 fieldref = uf->fieldref;
1496 fieldref = state->iptr->sx.s23.s3.fmiref;
1499 /* try to resolve the field reference lazily */
1500 result = new_resolve_field_lazy(jd, state->iptr, state->m);
1501 if (result == resolveFailed)
1504 if (result != resolveSucceeded) {
1506 uf = new_create_unresolved_field(state->m->class, state->m, state->iptr);
1510 state->iptr->sx.s23.s3.uf = uf;
1511 state->iptr->flags.bits |= INS_FLAG_UNRESOLVED;
1514 /* record the subtype constraints for this field access */
1515 if (!new_constrain_unresolved_field(jd, uf,state->m->class,state->m,state->iptr))
1516 return false; /* XXX maybe wrap exception? */
1518 TYPECHECK_COUNTIF(INSTRUCTION_IS_UNRESOLVED(state->iptr),stat_ins_field_unresolved);
1519 TYPECHECK_COUNTIF(INSTRUCTION_IS_RESOLVED(state->iptr) && !state->iptr->sx.s23.s3.fmiref->p.field->class->initialized,stat_ins_field_uninitialized);
1522 if (iptr->opc == ICMD_GETFIELD || iptr->opc == ICMD_GETSTATIC) {
1523 /* write the result type */
1524 dv->type = fieldref->parseddesc.fd->type;
1525 if (dv->type == TYPE_ADR) {
1526 if (!typeinfo_init_from_typedesc(fieldref->parseddesc.fd,NULL,&(dv->typeinfo)))
1534 /****************************************/
1535 /* PRIMITIVE ARRAY ACCESS */
1537 case ICMD_ARRAYLENGTH:
1538 if (!TYPEINFO_MAYBE_ARRAY(VAROP(state->iptr->s1)->typeinfo)
1539 && VAROP(state->iptr->s1)->typeinfo.typeclass.cls != pseudo_class_Arraystub)
1540 TYPECHECK_VERIFYERROR_bool("illegal instruction: ARRAYLENGTH on non-array");
1541 dv->type = TYPE_INT;
1546 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_BOOLEAN)
1547 && !TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_BYTE))
1548 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1549 dv->type = TYPE_INT;
1553 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_CHAR))
1554 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1555 dv->type = TYPE_INT;
1559 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_DOUBLE))
1560 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1561 dv->type = TYPE_DBL;
1565 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_FLOAT))
1566 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1567 dv->type = TYPE_FLT;
1571 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_INT))
1572 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1573 dv->type = TYPE_INT;
1577 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_SHORT))
1578 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1579 dv->type = TYPE_INT;
1583 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_LONG))
1584 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1585 dv->type = TYPE_LNG;
1590 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_BOOLEAN)
1591 && !TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_BYTE))
1592 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1596 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_CHAR))
1597 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1601 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_DOUBLE))
1602 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1606 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_FLOAT))
1607 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1611 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_INT))
1612 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1616 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_SHORT))
1617 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1621 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_LONG))
1622 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1627 /* we just check the basic input types and that the */
1628 /* destination is an array of references. Assignability to */
1629 /* the actual array must be checked at runtime, each time the */
1630 /* instruction is performed. (See builtin_canstore.) */
1631 TYPECHECK_ADR_OP(state->iptr->sx.s23.s3);
1632 TYPECHECK_INT_OP(state->iptr->sx.s23.s2);
1633 TYPECHECK_ADR_OP(state->iptr->s1);
1634 if (!TYPEINFO_MAYBE_ARRAY_OF_REFS(VAROP(state->iptr->s1)->typeinfo))
1635 TYPECHECK_VERIFYERROR_bool("illegal instruction: AASTORE to non-reference array");
1639 case ICMD_IASTORECONST:
1640 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo, ARRAYTYPE_INT))
1641 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1645 case ICMD_LASTORECONST:
1646 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo, ARRAYTYPE_LONG))
1647 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1651 case ICMD_BASTORECONST:
1652 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo, ARRAYTYPE_BOOLEAN)
1653 && !TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo, ARRAYTYPE_BYTE))
1654 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1658 case ICMD_CASTORECONST:
1659 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo, ARRAYTYPE_CHAR))
1660 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1664 case ICMD_SASTORECONST:
1665 if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo, ARRAYTYPE_SHORT))
1666 TYPECHECK_VERIFYERROR_bool("Array type mismatch");
1670 /****************************************/
1671 /* ADDRESS CONSTANTS */
1674 if (state->iptr->flags.bits & INS_FLAG_CLASS) {
1675 /* a java.lang.Class reference */
1676 TYPEINFO_INIT_JAVA_LANG_CLASS(dv->typeinfo,state->iptr->sx.val.c);
1679 if (state->iptr->sx.val.anyptr == NULL)
1680 TYPEINFO_INIT_NULLTYPE(dv->typeinfo);
1682 /* string constant (or constant for builtin function) */
1683 typeinfo_init_classinfo(&(dv->typeinfo),class_java_lang_String);
1686 dv->type = TYPE_ADR;
1689 /****************************************/
1690 /* CHECKCAST AND INSTANCEOF */
1692 case ICMD_CHECKCAST:
1693 TYPECHECK_ADR_OP(state->iptr->s1);
1694 /* returnAddress is not allowed */
1695 if (!TYPEINFO_IS_REFERENCE(VAROP(state->iptr->s1)->typeinfo))
1696 TYPECHECK_VERIFYERROR_bool("Illegal instruction: CHECKCAST on non-reference");
1698 if (!typeinfo_init_class(&(dv->typeinfo),state->iptr->sx.s23.s3.c))
1700 dv->type = TYPE_ADR;
1704 case ICMD_INSTANCEOF:
1705 TYPECHECK_ADR_OP(state->iptr->s1);
1706 /* returnAddress is not allowed */
1707 if (!TYPEINFO_IS_REFERENCE(VAROP(state->iptr->s1)->typeinfo))
1708 TYPECHECK_VERIFYERROR_bool("Illegal instruction: INSTANCEOF on non-reference");
1709 dv->type = TYPE_INT;
1712 /****************************************/
1713 /* BRANCH INSTRUCTIONS */
1715 case ICMD_INLINE_GOTO:
1716 COPYTYPE(state->iptr->s1,state->iptr->dst);
1719 superblockend = true;
1722 case ICMD_IFNONNULL:
1729 case ICMD_IF_ICMPEQ:
1730 case ICMD_IF_ICMPNE:
1731 case ICMD_IF_ICMPLT:
1732 case ICMD_IF_ICMPGE:
1733 case ICMD_IF_ICMPGT:
1734 case ICMD_IF_ICMPLE:
1735 case ICMD_IF_ACMPEQ:
1736 case ICMD_IF_ACMPNE:
1745 case ICMD_IF_LCMPEQ:
1746 case ICMD_IF_LCMPNE:
1747 case ICMD_IF_LCMPLT:
1748 case ICMD_IF_LCMPGE:
1749 case ICMD_IF_LCMPGT:
1750 case ICMD_IF_LCMPLE:
1752 case ICMD_IF_FCMPEQ:
1753 case ICMD_IF_FCMPNE:
1755 case ICMD_IF_FCMPL_LT:
1756 case ICMD_IF_FCMPL_GE:
1757 case ICMD_IF_FCMPL_GT:
1758 case ICMD_IF_FCMPL_LE:
1760 case ICMD_IF_FCMPG_LT:
1761 case ICMD_IF_FCMPG_GE:
1762 case ICMD_IF_FCMPG_GT:
1763 case ICMD_IF_FCMPG_LE:
1765 case ICMD_IF_DCMPEQ:
1766 case ICMD_IF_DCMPNE:
1768 case ICMD_IF_DCMPL_LT:
1769 case ICMD_IF_DCMPL_GE:
1770 case ICMD_IF_DCMPL_GT:
1771 case ICMD_IF_DCMPL_LE:
1773 case ICMD_IF_DCMPG_LT:
1774 case ICMD_IF_DCMPG_GE:
1775 case ICMD_IF_DCMPG_GT:
1776 case ICMD_IF_DCMPG_LE:
1777 TYPECHECK_COUNT(stat_ins_branch);
1779 /* propagate stack and variables to the target block */
1780 if (!typestate_reach(state, state->iptr->dst.block,
1781 state->bptr->outvars, jd->var,
1782 state->bptr->outdepth))
1786 /****************************************/
1789 case ICMD_TABLESWITCH:
1790 TYPECHECK_COUNT(stat_ins_switch);
1792 table = iptr->dst.table;
1793 i = iptr->sx.s23.s3.tablehigh
1794 - iptr->sx.s23.s2.tablelow + 1 + 1; /* plus default */
1797 tbptr = (table++)->block;
1798 LOG2("target %d is block %04d",i,tbptr->nr);
1799 if (!typestate_reach(state, tbptr, state->bptr->outvars,
1800 jd->var, state->bptr->outdepth))
1805 superblockend = true;
1808 case ICMD_LOOKUPSWITCH:
1809 TYPECHECK_COUNT(stat_ins_switch);
1811 lookup = iptr->dst.lookup;
1812 i = iptr->sx.s23.s2.lookupcount;
1814 if (!typestate_reach(state,iptr->sx.s23.s3.lookupdefault.block,
1815 state->bptr->outvars, jd->var,
1816 state->bptr->outdepth))
1820 tbptr = (lookup++)->target.block;
1821 LOG2("target %d is block %04d",i,tbptr->nr);
1822 if (!typestate_reach(state, tbptr, state->bptr->outvars,
1823 jd->var, state->bptr->outdepth))
1828 superblockend = true;
1832 /****************************************/
1833 /* ADDRESS RETURNS AND THROW */
1836 TYPECHECK_COUNT(stat_ins_athrow);
1837 r = typeinfo_is_assignable_to_class(&VAROP(state->iptr->s1)->typeinfo,
1838 CLASSREF_OR_CLASSINFO(class_java_lang_Throwable));
1839 if (r == typecheck_FALSE)
1840 TYPECHECK_VERIFYERROR_bool("illegal instruction: ATHROW on non-Throwable");
1841 if (r == typecheck_FAIL)
1843 if (r == typecheck_MAYBE) {
1844 /* the check has to be postponed. we need a patcher */
1845 TYPECHECK_COUNT(stat_ins_athrow_unresolved);
1846 iptr->sx.s23.s2.uc = create_unresolved_class(
1848 /* XXX make this more efficient, use class_java_lang_Throwable
1850 class_get_classref(state->m->class,utf_java_lang_Throwable),
1851 &VAROP(state->iptr->s1)->typeinfo);
1852 iptr->flags.bits |= INS_FLAG_UNRESOLVED;
1854 superblockend = true;
1859 TYPECHECK_COUNT(stat_ins_areturn);
1860 if (!TYPEINFO_IS_REFERENCE(VAROP(state->iptr->s1)->typeinfo))
1861 TYPECHECK_VERIFYERROR_bool("illegal instruction: ARETURN on non-reference");
1863 if (state->returntype.type != TYPE_ADR
1864 || (r = typeinfo_is_assignable(&VAROP(state->iptr->s1)->typeinfo,&(state->returntype.typeinfo)))
1866 TYPECHECK_VERIFYERROR_bool("Return type mismatch");
1867 if (r == typecheck_FAIL)
1869 if (r == typecheck_MAYBE) {
1870 /* the check has to be postponed, we need a patcher */
1871 TYPECHECK_COUNT(stat_ins_areturn_unresolved);
1872 iptr->sx.s23.s2.uc = create_unresolved_class(
1874 state->m->parseddesc->returntype.classref,
1875 &VAROP(state->iptr->s1)->typeinfo);
1876 iptr->flags.bits |= INS_FLAG_UNRESOLVED;
1880 /****************************************/
1881 /* PRIMITIVE RETURNS */
1884 if (state->returntype.type != TYPE_INT) TYPECHECK_VERIFYERROR_bool("Return type mismatch");
1888 if (state->returntype.type != TYPE_LNG) TYPECHECK_VERIFYERROR_bool("Return type mismatch");
1892 if (state->returntype.type != TYPE_FLT) TYPECHECK_VERIFYERROR_bool("Return type mismatch");
1896 if (state->returntype.type != TYPE_DBL) TYPECHECK_VERIFYERROR_bool("Return type mismatch");
1900 if (state->returntype.type != TYPE_VOID) TYPECHECK_VERIFYERROR_bool("Return type mismatch");
1902 TYPECHECK_COUNT(stat_ins_primitive_return);
1904 if (state->initmethod && state->m->class != class_java_lang_Object) {
1905 /* Check if the 'this' instance has been initialized. */
1906 LOG("Checking <init> marker");
1907 if (!typevector_checktype(jd->var,state->numlocals-1,TYPE_INT))
1908 TYPECHECK_VERIFYERROR_bool("<init> method does not initialize 'this'");
1911 superblockend = true;
1915 /****************************************/
1916 /* SUBROUTINE INSTRUCTIONS */
1921 tbptr = state->iptr->sx.s23.s3.jsrtarget.block;
1922 TYPEINFO_INIT_RETURNADDRESS(dv->typeinfo, state->bptr->next);
1923 if (!typestate_reach(state, tbptr, state->bptr->outvars, jd->var,
1924 state->bptr->outdepth))
1927 superblockend = true;
1931 /* check returnAddress variable */
1932 if (!typevector_checkretaddr(jd->var,state->iptr->s1.varindex))
1933 TYPECHECK_VERIFYERROR_bool("illegal instruction: RET using non-returnAddress variable");
1935 if (!typestate_reach(state, iptr->dst.block, state->bptr->outvars, jd->var,
1936 state->bptr->outdepth))
1939 superblockend = true;
1942 /****************************************/
1945 case ICMD_INVOKEVIRTUAL:
1946 case ICMD_INVOKESPECIAL:
1947 case ICMD_INVOKESTATIC:
1948 case ICMD_INVOKEINTERFACE:
1949 TYPECHECK_COUNT(stat_ins_invoke);
1950 if (!verify_invocation(state))
1952 TYPECHECK_COUNTIF(INSTRUCTION_IS_UNRESOLVED(iptr), stat_ins_invoke_unresolved);
1956 /****************************************/
1957 /* MULTIANEWARRAY */
1959 case ICMD_MULTIANEWARRAY:
1960 if (!verify_multianewarray(state))
1965 /****************************************/
1969 TYPECHECK_COUNT(stat_ins_builtin);
1970 if (!verify_builtin(state))
1975 /****************************************/
1976 /* SIMPLE EXCEPTION THROWING TESTS */
1978 case ICMD_CHECKNULL:
1979 /* CHECKNULL just requires that the stack top
1980 * is an address. This is checked in stack.c */
1984 /****************************************/
1985 /* INSTRUCTIONS WHICH SHOULD HAVE BEEN */
1986 /* REPLACED BY OTHER OPCODES */
1988 #ifdef TYPECHECK_DEBUG
1991 case ICMD_ANEWARRAY:
1992 case ICMD_MONITORENTER:
1993 case ICMD_MONITOREXIT:
1994 LOG2("ICMD %d at %d\n", state->iptr->opc, (int)(state->iptr-state->bptr->iinstr));
1995 LOG("Should have been converted to builtin function call.");
1996 TYPECHECK_ASSERT(false);
2000 /****************************************/
2001 /* UNCHECKED OPERATIONS */
2003 /*********************************************
2004 * Instructions below...
2005 * *) don't operate on local variables,
2006 * *) don't operate on references,
2007 * *) don't operate on returnAddresses,
2008 * *) don't affect control flow (except
2009 * by throwing exceptions).
2011 * (These instructions are typechecked in
2013 ********************************************/
2015 /* Instructions which may throw a runtime exception: */
2019 dv->type = TYPE_INT;
2025 dv->type = TYPE_LNG;
2029 /* Instructions which never throw a runtime exception: */
2048 case ICMD_IADDCONST:
2049 case ICMD_ISUBCONST:
2050 case ICMD_IMULCONST:
2051 case ICMD_IANDCONST:
2053 case ICMD_IXORCONST:
2054 case ICMD_ISHLCONST:
2055 case ICMD_ISHRCONST:
2056 case ICMD_IUSHRCONST:
2060 case ICMD_INT2SHORT:
2065 case ICMD_LCMPCONST:
2070 dv->type = TYPE_INT;
2086 case ICMD_LADDCONST:
2087 case ICMD_LSUBCONST:
2088 case ICMD_LMULCONST:
2089 case ICMD_LANDCONST:
2091 case ICMD_LXORCONST:
2092 case ICMD_LSHLCONST:
2093 case ICMD_LSHRCONST:
2094 case ICMD_LUSHRCONST:
2099 dv->type = TYPE_LNG;
2112 dv->type = TYPE_FLT;
2125 dv->type = TYPE_DBL;
2128 case ICMD_INLINE_START:
2129 case ICMD_INLINE_END:
2132 /* XXX What shall we do with the following ?*/
2133 case ICMD_AASTORECONST:
2134 TYPECHECK_COUNT(stat_ins_unchecked);
2137 /****************************************/
2140 LOG2("ICMD %d at %d\n", state->iptr->opc, (int)(state->iptr-state->bptr->iinstr));
2141 TYPECHECK_VERIFYERROR_bool("Missing ICMD code during typecheck");
2144 /* reach exception handlers for this instruction */
2147 TYPECHECK_COUNT(stat_ins_maythrow);
2148 TYPECHECK_MARK(state->stat_maythrow);
2149 LOG("reaching exception handlers");
2151 while (state->handlers[i]) {
2152 TYPECHECK_COUNT(stat_handlers_reached);
2153 if (state->handlers[i]->catchtype.any)
2154 VAR(state->exinvars)->typeinfo.typeclass = state->handlers[i]->catchtype;
2156 VAR(state->exinvars)->typeinfo.typeclass.cls = class_java_lang_Throwable;
2157 if (!typestate_reach(state,
2158 state->handlers[i]->handler,
2159 &(state->exinvars), jd->var, 1))
2165 LOG("\t\tnext instruction");
2167 } /* while instructions */
2169 LOG("instructions done");
2170 LOGSTR("RESULT=> ");
2171 DOLOG(typecheck_print_vararray(stdout, jd, state->bptr->outvars,
2172 state->bptr->outdepth));
2173 DOLOG(typevector_print(stdout, jd->var, state->numlocals));
2176 /* propagate stack and variables to the following block */
2177 if (!superblockend) {
2178 LOG("reaching following block");
2179 tbptr = state->bptr->next;
2180 while (tbptr->flags == BBDELETED) {
2181 tbptr = tbptr->next;
2182 #ifdef TYPECHECK_DEBUG
2183 /* this must be checked in parse.c */
2184 if ((tbptr->nr) >= state->basicblockcount)
2185 TYPECHECK_VERIFYERROR_bool("Control flow falls off the last block");
2188 if (!typestate_reach(state,tbptr,state->bptr->outvars, jd->var,
2189 state->bptr->outdepth))
2193 /* We may have to restore the types of the instack slots. They
2194 * have been saved if an <init> call inside the block has
2195 * modified the instack types. (see INVOKESPECIAL) */
2197 if (state->savedinvars)
2198 typestate_restore_invars(state);
2204 /* verify_init_locals **********************************************************
2206 Initialize the local variables in the verifier state.
2209 state............the current state of the verifier
2212 true.............success,
2213 false............an exception has been thrown.
2215 *******************************************************************************/
2218 verify_init_locals(verifier_state *state)
2224 jitdata *jd = state->jd;
2227 locals = state->basicblocks[0].inlocals;
2229 /* allocate parameter descriptors if necessary */
2231 if (!state->m->parseddesc->params)
2232 if (!descriptor_params_from_paramtypes(state->m->parseddesc,state->m->flags))
2235 /* pre-initialize variables as TYPE_VOID */
2237 i = state->numlocals;
2240 v->type = TYPE_VOID;
2244 /* if this is an instance method initialize the "this" ref type */
2246 if (!(state->m->flags & ACC_STATIC)) {
2247 index = jd->local_map[5*0 + TYPE_ADR];
2248 if (index != UNUSED) {
2249 if (state->validlocals < 1)
2250 TYPECHECK_VERIFYERROR_bool("Not enough local variables for method arguments");
2253 if (state->initmethod)
2254 TYPEINFO_INIT_NEWOBJECT(v->typeinfo, NULL);
2256 typeinfo_init_classinfo(&(v->typeinfo), state->m->class);
2262 LOG("'this' argument set.\n");
2264 /* the rest of the arguments and the return type */
2266 if (!typeinfo_init_varinfos_from_methoddesc(locals, state->m->parseddesc,
2268 skip, /* skip 'this' pointer */
2270 &state->returntype))
2273 LOG("Arguments set.\n");
2278 /* typecheck_init_flags ********************************************************
2280 Initialize the basic block flags for the following CFG traversal.
2283 state............the current state of the verifier
2285 *******************************************************************************/
2288 typecheck_init_flags(verifier_state *state)
2293 /* set all BBFINISHED blocks to BBTYPECHECK_UNDEF. */
2295 i = state->basicblockcount;
2296 for (block = state->basicblocks; block; block = block->next) {
2298 #ifdef TYPECHECK_DEBUG
2299 /* check for invalid flags */
2300 if (block->flags != BBFINISHED && block->flags != BBDELETED && block->flags != BBUNDEF)
2302 /*show_icmd_method(state->m,state->cd,state->rd);*/
2303 LOGSTR1("block flags: %d\n",block->flags); LOGFLUSH;
2304 TYPECHECK_ASSERT(false);
2308 if (block->flags >= BBFINISHED) {
2309 block->flags = BBTYPECHECK_UNDEF;
2313 /* the first block is always reached */
2315 if (state->basicblockcount && state->basicblocks[0].flags == BBTYPECHECK_UNDEF)
2316 state->basicblocks[0].flags = BBTYPECHECK_REACHED;
2320 /* typecheck_reset_flags *******************************************************
2322 Reset the flags of basic blocks we have not reached.
2325 state............the current state of the verifier
2327 *******************************************************************************/
2330 typecheck_reset_flags(verifier_state *state)
2334 /* check for invalid flags at exit */
2336 #ifdef TYPECHECK_DEBUG
2337 for (block = state->basicblocks; block; block = block->next) {
2338 if (block->flags != BBDELETED
2339 && block->flags != BBUNDEF
2340 && block->flags != BBFINISHED
2341 && block->flags != BBTYPECHECK_UNDEF) /* typecheck may never reach
2342 * some exception handlers,
2345 LOG2("block L%03d has invalid flags after typecheck: %d",
2346 block->nr,block->flags);
2347 TYPECHECK_ASSERT(false);
2352 /* Delete blocks we never reached */
2354 for (block = state->basicblocks; block; block = block->next) {
2355 if (block->flags == BBTYPECHECK_UNDEF)
2356 block->flags = BBDELETED;
2361 /****************************************************************************/
2363 /* This is the main function of the bytecode verifier. It is called */
2364 /* directly after analyse_stack. */
2367 /* meth.............the method to verify */
2368 /* cdata............codegendata for the method */
2369 /* rdata............registerdata for the method */
2372 /* true.............successful verification */
2373 /* false............an exception has been thrown */
2375 /****************************************************************************/
2377 #define MAXPARAMS 255
2379 bool typecheck(jitdata *jd)
2384 varinfo *savedlocals;
2385 verifier_state state; /* current state of the verifier */
2389 /* collect statistics */
2391 #ifdef TYPECHECK_STATISTICS
2392 int count_iterations = 0;
2393 TYPECHECK_COUNT(stat_typechecked);
2394 TYPECHECK_COUNT_FREQ(stat_locals,cdata->maxlocals,STAT_LOCALS);
2395 TYPECHECK_COUNT_FREQ(stat_blocks,cdata->method->basicblockcount/10,STAT_BLOCKS);
2396 TYPECHECK_COUNTIF(cdata->method->exceptiontablelength != 0,stat_methods_with_handlers);
2397 state.stat_maythrow = false;
2400 /* get required compiler data */
2406 /* some logging on entry */
2409 LOGSTR("\n==============================================================================\n");
2410 DOLOG( new_show_method(jd, SHOW_STACK) );
2411 LOGSTR("\n==============================================================================\n");
2412 LOGMETHOD("Entering typecheck: ",cd->method);
2414 /* initialize the verifier state */
2420 state.basicblockcount = jd->new_basicblockcount;
2421 state.basicblocks = jd->new_basicblocks;
2422 state.savedindices = NULL;
2423 state.savedinvars = NULL;
2425 /* check if this method is an instance initializer method */
2427 state.initmethod = (state.m->name == utf_init);
2429 /* initialize the basic block flags for the following CFG traversal */
2431 typecheck_init_flags(&state);
2433 /* number of local variables */
2435 /* In <init> methods we use an extra local variable to indicate whether */
2436 /* the 'this' reference has been initialized. */
2437 /* TYPE_VOID...means 'this' has not been initialized, */
2438 /* TYPE_INT....means 'this' has been initialized. */
2440 state.numlocals = state.jd->localcount;
2441 state.validlocals = state.numlocals;
2442 if (state.initmethod)
2443 state.numlocals++; /* VERIFIER_EXTRA_LOCALS */
2445 state.reverselocalmap = DMNEW(s4, state.validlocals);
2446 for (i=0; i<jd->m->maxlocals; ++i)
2447 for (t=0; t<5; ++t) {
2448 s4 mapped = jd->local_map[5*i + t];
2450 state.reverselocalmap[mapped] = i;
2453 /* allocate the buffer of active exception handlers */
2455 state.handlers = DMNEW(exceptiontable*, state.cd->exceptiontablelength + 1);
2457 /* save local variables */
2459 savedlocals = DMNEW(varinfo, state.numlocals);
2460 MCOPY(savedlocals, jd->var, varinfo, state.numlocals);
2462 /* initialized local variables of first block */
2464 if (!verify_init_locals(&state))
2467 /* initialize invars of exception handlers */
2469 state.exinvars = state.numlocals;
2470 VAR(state.exinvars)->type = TYPE_ADR;
2471 typeinfo_init_classinfo(&(VAR(state.exinvars)->typeinfo),
2472 class_java_lang_Throwable); /* changed later */
2474 LOG("Exception handler stacks set.\n");
2476 /* loop while there are still blocks to be checked */
2478 TYPECHECK_COUNT(count_iterations);
2480 state.repeat = false;
2482 state.bptr = state.basicblocks;
2484 for (; state.bptr; state.bptr = state.bptr->next) {
2485 LOGSTR1("---- BLOCK %04d, ",state.bptr->nr);
2486 LOGSTR1("blockflags: %d\n",state.bptr->flags);
2489 /* verify reached block */
2490 if (state.bptr->flags == BBTYPECHECK_REACHED) {
2491 if (!verify_basic_block(&state))
2496 LOGIF(state.repeat,"state.repeat == true");
2497 } while (state.repeat);
2501 #ifdef TYPECHECK_STATISTICS
2502 LOG1("Typechecker did %4d iterations",count_iterations);
2503 TYPECHECK_COUNT_FREQ(stat_iterations,count_iterations,STAT_ITERATIONS);
2504 TYPECHECK_COUNTIF(state.jsrencountered,stat_typechecked_jsr);
2505 TYPECHECK_COUNTIF(state.stat_maythrow,stat_methods_maythrow);
2508 /* reset the flags of blocks we haven't reached */
2510 typecheck_reset_flags(&state);
2512 /* restore locals */
2514 MCOPY(jd->var, savedlocals, varinfo, state.numlocals);
2516 /* everything's ok */
2518 LOGimp("exiting typecheck");
2521 #endif /* ENABLE_VERIFIER */
2524 * These are local overrides for various environment variables in Emacs.
2525 * Please do not remove this and leave it at the end of the file, where
2526 * Emacs will automagically detect them.
2527 * ---------------------------------------------------------------------
2530 * indent-tabs-mode: t
2534 * vim:noexpandtab:sw=4:ts=4: