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 5777 2006-10-13 18:25:21Z 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.
112 Note that some checks mentioned in the JVM spec are unnecessary[4] and
113 not performed by either the reference implementation, or this implementation.
118 [1] Actually only the types of slots/variables at the start of each
119 basic block are remembered. Within a basic block the algorithm only keeps
120 the types of the slots/variables for the "current" instruction which is
123 [2] Actually the algorithm iterates through the basic block list until
124 there are no more changes. Theoretically it would be wise to sort the
125 basic blocks topologically beforehand, but the number of average/max
126 iterations observed is so low, that this was not deemed necessary.
128 [3] This is similar to a method proposed by: Alessandro Coglio et al., A
129 Formal Specification of Java Class Loading, Technical Report, Kestrel
130 Institute April 2000, revised July 2000
131 http://www.kestrel.edu/home/people/coglio/loading.pdf
132 An important difference is that Coglio's subtype constraints are checked
133 after loading, while our constraints are checked when the field/method
134 is accessed for the first time, so we can guarantee lexically correct
137 [4] Alessandro Coglio
138 Improving the official specification of Java bytecode verification
139 Proceedings of the 3rd ECOOP Workshop on Formal Techniques for Java Programs
141 citeseer.ist.psu.edu/article/coglio03improving.html
145 #include "vm/types.h"
146 #include "vm/global.h"
151 #ifdef ENABLE_VERIFIER
153 #include "mm/memory.h"
154 #include "toolbox/logging.h"
155 #include "native/native.h"
156 #include "vm/builtin.h"
157 #include "vm/jit/patcher.h"
158 #include "vm/loader.h"
159 #include "vm/options.h"
160 #include "vm/jit/jit.h"
161 #include "vm/jit/show.h"
162 #include "vm/access.h"
163 #include "vm/resolve.h"
164 #include "vm/exceptions.h"
166 #include <typecheck-common.h>
169 /****************************************************************************/
170 /* MACROS FOR VARIABLE TYPE CHECKING */
171 /****************************************************************************/
173 #define TYPECHECK_CHECK_TYPE(i,tp,msg) \
175 if (VAR(i)->type != (tp)) { \
176 exceptions_throw_verifyerror(state->m, (msg)); \
181 #define TYPECHECK_INT(i) \
182 TYPECHECK_CHECK_TYPE(i,TYPE_INT,"Expected to find integer value")
183 #define TYPECHECK_LNG(i) \
184 TYPECHECK_CHECK_TYPE(i,TYPE_LNG,"Expected to find long value")
185 #define TYPECHECK_FLT(i) \
186 TYPECHECK_CHECK_TYPE(i,TYPE_FLT,"Expected to find float value")
187 #define TYPECHECK_DBL(i) \
188 TYPECHECK_CHECK_TYPE(i,TYPE_DBL,"Expected to find double value")
189 #define TYPECHECK_ADR(i) \
190 TYPECHECK_CHECK_TYPE(i,TYPE_ADR,"Expected to find object value")
192 #define TYPECHECK_INT_OP(o) TYPECHECK_INT((o).varindex)
193 #define TYPECHECK_LNG_OP(o) TYPECHECK_LNG((o).varindex)
194 #define TYPECHECK_FLT_OP(o) TYPECHECK_FLT((o).varindex)
195 #define TYPECHECK_DBL_OP(o) TYPECHECK_DBL((o).varindex)
196 #define TYPECHECK_ADR_OP(o) TYPECHECK_ADR((o).varindex)
199 /****************************************************************************/
200 /* TYPESTACK MACROS AND FUNCTIONS */
202 /* These macros and functions act on the 'type stack', which is a shorthand */
203 /* for the types of the stackslots of the current stack. The type of a */
204 /* stack slot is usually described by a TYPE_* constant and -- for TYPE_ADR */
205 /* -- by the typeinfo of the slot. The only thing that makes the type stack */
206 /* more complicated are returnAddresses of local subroutines, because a */
207 /* single stack slot may contain a set of more than one possible return */
208 /* address. This is handled by 'return address sets'. A return address set */
209 /* is kept as a linked list dangling off the typeinfo of the stack slot. */
210 /****************************************************************************/
212 /* typecheck_copy_types ********************************************************
214 Copy the types of the source variables to the destination variables.
217 state............current verifier state
218 srcvars..........array of variable indices to copy
219 dstvars..........array of the destination variables
220 n................number of variables to copy
223 true.............success
224 false............an exception has been thrown
226 *******************************************************************************/
229 typecheck_copy_types(verifier_state *state, s4 *srcvars, s4 *dstvars, s4 n)
234 jitdata *jd = state->jd;
236 for (i=0; i < n; ++i, ++srcvars, ++dstvars) {
241 if (dv->type == TYPE_ADR) {
242 TYPEINFO_CLONE(sv->typeinfo,dv->typeinfo);
249 /* typecheck_merge_types *******************************************************
251 Merge the types of the source variables into the destination variables.
254 state............current state of the verifier
255 srcvars..........source variable indices
256 dstvars..........destination variable indices
257 n................number of variables
260 typecheck_TRUE...the destination variables have been modified
261 typecheck_FALSE..the destination variables are unchanged
262 typecheck_FAIL...an exception has been thrown
264 *******************************************************************************/
266 static typecheck_result
267 typecheck_merge_types(verifier_state *state,s4 *srcvars, s4 *dstvars, s4 n)
272 jitdata *jd = state->jd;
274 bool changed = false;
276 for (i=0; i < n; ++i, ++srcvars, ++dstvars) {
280 if (dv->type != sv->type) {
281 exceptions_throw_verifyerror(state->m,"Stack type mismatch");
282 return typecheck_FAIL;
284 if (dv->type == TYPE_ADR) {
285 if (TYPEINFO_IS_PRIMITIVE(dv->typeinfo)) {
286 /* dv has returnAddress type */
287 if (!TYPEINFO_IS_PRIMITIVE(sv->typeinfo)) {
288 exceptions_throw_verifyerror(state->m,"Merging returnAddress with reference");
289 return typecheck_FAIL;
293 /* dv has reference type */
294 if (TYPEINFO_IS_PRIMITIVE(sv->typeinfo)) {
295 exceptions_throw_verifyerror(state->m,"Merging reference with returnAddress");
296 return typecheck_FAIL;
298 r = typeinfo_merge(state->m,&(dv->typeinfo),&(sv->typeinfo));
299 if (r == typecheck_FAIL)
309 /* typestate_merge *************************************************************
311 Merge the types of one state into the destination state.
314 state............current state of the verifier
315 dstvars..........indices of the destinations invars
316 dstlocals........the destinations inlocals
317 srcvars..........indices of the source's outvars
318 srclocals........the source locals
319 n................number of invars (== number of outvars)
322 typecheck_TRUE...destination state has been modified
323 typecheck_FALSE..destination state has not been modified
324 typecheck_FAIL...an exception has been thrown
326 *******************************************************************************/
328 static typecheck_result
329 typestate_merge(verifier_state *state,
330 s4 *srcvars, varinfo *srclocals,
331 s4 *dstvars, varinfo *dstlocals,
334 bool changed = false;
337 /* The stack is always merged. If there are returnAddresses on
338 * the stack they are ignored in this step. */
340 r = typecheck_merge_types(state, srcvars, dstvars, n);
341 if (r == typecheck_FAIL)
345 /* merge the locals */
347 r = typevector_merge(state->m, dstlocals, srclocals, state->numlocals);
348 if (r == typecheck_FAIL)
354 /* typestate_reach *************************************************************
356 Reach a destination block and propagate stack and local variable types
359 state............current state of the verifier
360 destblock........destination basic block
361 srcvars..........variable indices of the outvars to propagate
362 srclocals........local variables to propagate
363 n................number of srcvars
366 state->repeat....set to true if the verifier must iterate again
367 over the basic blocks
370 true.............success
371 false............an exception has been thrown
373 *******************************************************************************/
376 typestate_reach(verifier_state *state,
377 basicblock *destblock,
378 s4 *srcvars, varinfo *srclocals, s4 n)
381 bool changed = false;
384 LOG1("reaching block L%03d",destblock->nr);
385 TYPECHECK_COUNT(stat_reached);
387 destloc = destblock->inlocals;
389 if (destblock->flags == BBTYPECHECK_UNDEF) {
390 /* The destblock has never been reached before */
392 TYPECHECK_COUNT(stat_copied);
393 LOG1("block L%03d reached first time",destblock->nr);
395 if (!typecheck_copy_types(state, srcvars, destblock->invars, n))
397 typevector_copy_inplace(srclocals, destloc, state->numlocals);
401 /* The destblock has already been reached before */
403 TYPECHECK_COUNT(stat_merged);
404 LOG1("block L%03d reached before", destblock->nr);
406 r = typestate_merge(state, srcvars, srclocals,
407 destblock->invars, destblock->inlocals, n);
408 if (r == typecheck_FAIL)
411 TYPECHECK_COUNTIF(changed,stat_merging_changed);
416 destblock->flags = BBTYPECHECK_REACHED;
417 if (destblock <= state->bptr) {
419 state->repeat = true;
426 /* typestate_save_invars *******************************************************
428 Save the invars of the current basic block in the space reserved by
431 This function must be called before an instruction modifies a variable
432 that is an invar of the current block. In such cases the invars of the
433 block must be saved, and restored at the end of the analysis of this
434 basic block, so that the invars again reflect the *input* to this basic
435 block (and do not randomly contain types that appear within the block).
438 state............current state of the verifier
440 *******************************************************************************/
443 typestate_save_invars(verifier_state *state)
448 LOG("saving invars");
450 if (!state->savedindices) {
451 LOG("allocating savedindices buffer");
452 pindex = DMNEW(s4, state->m->maxstack);
453 state->savedindices = pindex;
454 index = state->numlocals + VERIFIER_EXTRA_VARS;
455 for (i=0; i<state->m->maxstack; ++i)
461 typecheck_copy_types(state, state->bptr->invars, state->savedindices,
462 state->bptr->indepth);
464 /* set the invars of the block to the saved variables */
465 /* and remember the original invars */
467 state->savedinvars = state->bptr->invars;
468 state->bptr->invars = state->savedindices;
472 /* typestate_restore_invars ***************************************************
474 Restore the invars of the current basic block that have been previously
475 saved by `typestate_save_invars`.
478 state............current state of the verifier
480 *******************************************************************************/
483 typestate_restore_invars(verifier_state *state)
485 TYPECHECK_COUNT(stat_savedstack);
486 LOG("restoring saved invars");
488 /* restore the invars pointer */
490 state->bptr->invars = state->savedinvars;
492 /* copy the types back */
494 typecheck_copy_types(state, state->savedindices, state->bptr->invars,
495 state->bptr->indepth);
497 /* mark that there are no saved invars currently */
499 state->savedinvars = NULL;
503 /****************************************************************************/
505 /****************************************************************************/
507 #define COPYTYPE(source,dest) \
508 {if (VAROP(source)->type == TYPE_ADR) \
509 TYPEINFO_COPY(VAROP(source)->typeinfo,VAROP(dest)->typeinfo);}
512 /* verify_fieldaccess **********************************************************
514 Verify an ICMD_{GET,PUT}{STATIC,FIELD}(CONST)?
517 state............the current state of the verifier
520 true.............successful verification,
521 false............an exception has been thrown.
523 *******************************************************************************/
526 verify_fieldaccess(verifier_state *state,
534 #define TYPECHECK_VARIABLESBASED
535 #define EXCEPTION do { return false; } while (0)
536 #define VERIFY_ERROR(msg) TYPECHECK_VERIFYERROR_bool(msg)
537 #include <typecheck-fields.inc>
540 #undef TYPECHECK_VARIABLESBASED
546 /* verify_invocation ***********************************************************
548 Verify an ICMD_INVOKE* instruction.
551 state............the current state of the verifier
554 true.............successful verification,
555 false............an exception has been thrown.
557 *******************************************************************************/
560 verify_invocation(verifier_state *state)
563 varinfo *dv; /* output variable of current instruction */
566 dv = VAROP(state->iptr->dst);
568 #define TYPECHECK_VARIABLESBASED
569 #define OP1 VAR(state->iptr->sx.s23.s2.args[0])
570 #include <typecheck-invoke.inc>
572 #undef TYPECHECK_VARIABLESBASED
578 /* verify_builtin **************************************************************
580 Verify the call of a builtin method.
583 state............the current state of the verifier
586 true.............successful verification,
587 false............an exception has been thrown.
589 *******************************************************************************/
592 verify_builtin(verifier_state *state)
595 varinfo *dv; /* output variable of current instruction */
598 dv = VAROP(state->iptr->dst);
600 #define TYPECHECK_VARIABLESBASED
601 #define OP1 state->iptr->sx.s23.s2.args[0]
602 #include <typecheck-builtins.inc>
604 #undef TYPECHECK_VARIABLESBASED
609 /* verify_multianewarray *******************************************************
611 Verify a MULTIANEWARRAY instruction.
614 state............the current state of the verifier
617 true.............successful verification,
618 false............an exception has been thrown.
620 *******************************************************************************/
623 verify_multianewarray(verifier_state *state)
625 classinfo *arrayclass;
626 arraydescriptor *desc;
628 jitdata *jd = state->jd;
630 /* check the array lengths on the stack */
631 i = state->iptr->s1.argcount;
633 TYPECHECK_VERIFYERROR_bool("Illegal dimension argument");
636 TYPECHECK_INT(state->iptr->sx.s23.s2.args[i]);
639 /* check array descriptor */
640 if (INSTRUCTION_IS_RESOLVED(state->iptr)) {
641 /* the array class reference has already been resolved */
642 arrayclass = state->iptr->sx.s23.s3.c.cls;
644 TYPECHECK_VERIFYERROR_bool("MULTIANEWARRAY with unlinked class");
645 if ((desc = arrayclass->vftbl->arraydesc) == NULL)
646 TYPECHECK_VERIFYERROR_bool("MULTIANEWARRAY with non-array class");
647 if (desc->dimension < state->iptr->s1.argcount)
648 TYPECHECK_VERIFYERROR_bool("MULTIANEWARRAY dimension to high");
650 /* set the array type of the result */
651 typeinfo_init_classinfo(&(VAROP(state->iptr->dst)->typeinfo), arrayclass);
655 constant_classref *cr;
657 /* the array class reference is still unresolved */
658 /* check that the reference indicates an array class of correct dimension */
659 cr = state->iptr->sx.s23.s3.c.ref;
664 /* { the dimension of the array class == i } */
666 TYPECHECK_VERIFYERROR_bool("MULTIANEWARRAY with non-array class");
667 if (i < state->iptr->s1.argcount)
668 TYPECHECK_VERIFYERROR_bool("MULTIANEWARRAY dimension to high");
670 /* set the array type of the result */
671 if (!typeinfo_init_class(&(VAROP(state->iptr->dst)->typeinfo),CLASSREF_OR_CLASSINFO(cr)))
675 /* set return type */
677 VAROP(state->iptr->dst)->type = TYPE_ADR;
684 /* typecheck_invalidate_locals *************************************************
686 Invalidate locals that are overwritten by writing to the given local.
689 state............the current state of the verifier
690 index............the index of the local that is written
691 twoword..........true, if a two-word type is written
693 *******************************************************************************/
695 static void typecheck_invalidate_locals(verifier_state *state, s4 index, bool twoword)
700 jitdata *jd = state->jd;
701 s4 *localmap = jd->local_map;
702 varinfo *vars = jd->var;
704 i = state->reverselocalmap[index];
706 /* invalidate locals of two-word type at index i-1 */
709 localmap += 5 * (i-1);
710 for (t=0; t<5; ++t) {
711 mapped = *localmap++;
712 if (mapped >= 0 && IS_2_WORD_TYPE(vars[mapped].type)) {
713 LOG1("invalidate local %d", mapped);
714 vars[mapped].type = TYPE_VOID;
722 /* invalidate locals at index i */
724 for (t=0; t<5; ++t) {
725 mapped = *localmap++;
727 LOG1("invalidate local %d", mapped);
728 vars[mapped].type = TYPE_VOID;
732 /* if a two-word type is written, invalidate locals at index i+1 */
735 for (t=0; t<5; ++t) {
736 mapped = *localmap++;
738 LOG1("invalidate local %d", mapped);
739 vars[mapped].type = TYPE_VOID;
746 /* macros used by the generated code ******************************************/
748 #define EXCEPTION do { return false; } while (0)
749 #define VERIFY_ERROR(msg) TYPECHECK_VERIFYERROR_bool(msg)
751 #define CHECK_LOCAL_TYPE(index, t) \
753 if (!typevector_checktype(jd->var, (index), (t))) \
754 VERIFY_ERROR("Local variable type mismatch"); \
757 #define STORE_LOCAL(t, index) \
759 typecheck_invalidate_locals(state, (index), false); \
760 typevector_store(jd->var, (index), (t), NULL); \
763 #define STORE_LOCAL_2_WORD(t, index) \
765 typecheck_invalidate_locals(state, (index), true); \
766 typevector_store(jd->var, (index), (t), NULL); \
769 #define REACH_BLOCK(target) \
771 if (!typestate_reach(state, (target), \
772 state->bptr->outvars, jd->var, \
773 state->bptr->outdepth)) \
777 #define REACH(target) REACH_BLOCK((target).block)
780 /* verify_basic_block **********************************************************
782 Perform bytecode verification of a basic block.
785 state............the current state of the verifier
788 true.............successful verification,
789 false............an exception has been thrown.
791 *******************************************************************************/
794 verify_basic_block(verifier_state *state)
796 int opcode; /* current opcode */
797 int len; /* for counting instructions, etc. */
798 bool superblockend; /* true if no fallthrough to next block */
799 instruction *iptr; /* the current instruction */
800 basicblock *tbptr; /* temporary for target block */
801 bool maythrow; /* true if this instruction may throw */
804 branch_target_t *table;
805 lookup_target_t *lookup;
806 jitdata *jd = state->jd;
808 varinfo constvalue; /* for PUT*CONST */
809 constant_FMIref *fieldref;
811 LOGSTR1("\n---- BLOCK %04d ------------------------------------------------\n",state->bptr->nr);
813 DOLOG(show_basicblock(jd, state->bptr, SHOW_STACK));
815 superblockend = false;
816 state->bptr->flags = BBFINISHED;
818 /* prevent compiler warnings */
821 /* determine the active exception handlers for this block */
822 /* XXX could use a faster algorithm with sorted lists or */
825 for (ex = state->cd->exceptiontable; ex ; ex = ex->down) {
826 if ((ex->start->nr <= state->bptr->nr) && (ex->end->nr > state->bptr->nr)) {
827 LOG1("active handler L%03d", ex->handler->nr);
828 state->handlers[len++] = ex;
831 state->handlers[len] = NULL;
833 /* init variable types at the start of this block */
834 typevector_copy_inplace(state->bptr->inlocals, jd->var, state->numlocals);
836 DOLOG(typecheck_print_vararray(stdout, jd, state->bptr->invars,
837 state->bptr->indepth));
838 DOLOG(typevector_print(stdout, jd->var, state->numlocals));
841 /* loop over the instructions */
842 len = state->bptr->icount;
843 state->iptr = state->bptr->iinstr;
845 TYPECHECK_COUNT(stat_ins);
849 DOLOG(typevector_print(stdout, jd->var, state->numlocals));
851 DOLOG(show_icmd(jd, state->iptr, false, SHOW_STACK)); LOGNL; LOGFLUSH;
858 /* include generated code for ICMDs verification */
860 #define TYPECHECK_VARIABLESBASED
862 #define METHOD (state->m)
864 #define BPTR (state->bptr)
865 #include <typecheck-variablesbased-gen.inc>
870 #undef TYPECHECK_VARIABLESBASED
873 LOG1("ICMD %d\n", opcode);
874 TYPECHECK_VERIFYERROR_bool("Missing ICMD code during typecheck");
877 /* reach exception handlers for this instruction */
880 TYPECHECK_COUNT(stat_ins_maythrow);
881 TYPECHECK_MARK(state->stat_maythrow);
882 LOG("reaching exception handlers");
884 while (state->handlers[i]) {
885 TYPECHECK_COUNT(stat_handlers_reached);
886 if (state->handlers[i]->catchtype.any)
887 VAR(state->exinvars)->typeinfo.typeclass = state->handlers[i]->catchtype;
889 VAR(state->exinvars)->typeinfo.typeclass.cls = class_java_lang_Throwable;
890 if (!typestate_reach(state,
891 state->handlers[i]->handler,
892 &(state->exinvars), jd->var, 1))
898 LOG("\t\tnext instruction");
900 } /* while instructions */
902 LOG("instructions done");
904 DOLOG(typecheck_print_vararray(stdout, jd, state->bptr->outvars,
905 state->bptr->outdepth));
906 DOLOG(typevector_print(stdout, jd->var, state->numlocals));
909 /* propagate stack and variables to the following block */
910 if (!superblockend) {
911 LOG("reaching following block");
912 tbptr = state->bptr->next;
913 while (tbptr->flags == BBDELETED) {
915 #ifdef TYPECHECK_DEBUG
916 /* this must be checked in parse.c */
917 if ((tbptr->nr) >= state->basicblockcount)
918 TYPECHECK_VERIFYERROR_bool("Control flow falls off the last block");
921 if (!typestate_reach(state,tbptr,state->bptr->outvars, jd->var,
922 state->bptr->outdepth))
926 /* We may have to restore the types of the instack slots. They
927 * have been saved if an <init> call inside the block has
928 * modified the instack types. (see INVOKESPECIAL) */
930 if (state->savedinvars)
931 typestate_restore_invars(state);
937 /* verify_init_locals **********************************************************
939 Initialize the local variables in the verifier state.
942 state............the current state of the verifier
945 true.............success,
946 false............an exception has been thrown.
948 *******************************************************************************/
951 verify_init_locals(verifier_state *state)
957 jitdata *jd = state->jd;
960 locals = state->basicblocks[0].inlocals;
962 /* allocate parameter descriptors if necessary */
964 if (!state->m->parseddesc->params)
965 if (!descriptor_params_from_paramtypes(state->m->parseddesc,state->m->flags))
968 /* pre-initialize variables as TYPE_VOID */
970 i = state->numlocals;
977 /* if this is an instance method initialize the "this" ref type */
979 if (!(state->m->flags & ACC_STATIC)) {
980 index = jd->local_map[5*0 + TYPE_ADR];
981 if (index != UNUSED) {
982 if (state->validlocals < 1)
983 TYPECHECK_VERIFYERROR_bool("Not enough local variables for method arguments");
986 if (state->initmethod)
987 TYPEINFO_INIT_NEWOBJECT(v->typeinfo, NULL);
989 typeinfo_init_classinfo(&(v->typeinfo), state->m->class);
995 LOG("'this' argument set.\n");
997 /* the rest of the arguments and the return type */
999 if (!typeinfo_init_varinfos_from_methoddesc(locals, state->m->parseddesc,
1001 skip, /* skip 'this' pointer */
1003 &state->returntype))
1006 LOG("Arguments set.\n");
1011 /****************************************************************************/
1013 /* This is the main function of the bytecode verifier. It is called */
1014 /* directly after analyse_stack. */
1017 /* meth.............the method to verify */
1018 /* cdata............codegendata for the method */
1019 /* rdata............registerdata for the method */
1022 /* true.............successful verification */
1023 /* false............an exception has been thrown */
1025 /****************************************************************************/
1027 #define MAXPARAMS 255
1029 bool typecheck(jitdata *jd)
1033 varinfo *savedlocals;
1034 verifier_state state; /* current state of the verifier */
1038 /* collect statistics */
1040 #ifdef TYPECHECK_STATISTICS
1041 int count_iterations = 0;
1042 TYPECHECK_COUNT(stat_typechecked);
1043 TYPECHECK_COUNT_FREQ(stat_locals,cdata->maxlocals,STAT_LOCALS);
1044 TYPECHECK_COUNT_FREQ(stat_blocks,cdata->method->basicblockcount/10,STAT_BLOCKS);
1045 TYPECHECK_COUNTIF(cdata->method->exceptiontablelength != 0,stat_methods_with_handlers);
1046 state.stat_maythrow = false;
1049 /* get required compiler data */
1054 /* some logging on entry */
1057 LOGSTR("\n==============================================================================\n");
1058 DOLOG( show_method(jd, SHOW_STACK) );
1059 LOGSTR("\n==============================================================================\n");
1060 LOGMETHOD("Entering typecheck: ",cd->method);
1062 /* initialize the verifier state */
1067 state.basicblockcount = jd->basicblockcount;
1068 state.basicblocks = jd->basicblocks;
1069 state.savedindices = NULL;
1070 state.savedinvars = NULL;
1072 /* check if this method is an instance initializer method */
1074 state.initmethod = (state.m->name == utf_init);
1076 /* initialize the basic block flags for the following CFG traversal */
1078 typecheck_init_flags(&state, BBFINISHED);
1080 /* number of local variables */
1082 /* In <init> methods we use an extra local variable to indicate whether */
1083 /* the 'this' reference has been initialized. */
1084 /* TYPE_VOID...means 'this' has not been initialized, */
1085 /* TYPE_INT....means 'this' has been initialized. */
1087 state.numlocals = state.jd->localcount;
1088 state.validlocals = state.numlocals;
1089 if (state.initmethod)
1090 state.numlocals++; /* VERIFIER_EXTRA_LOCALS */
1092 state.reverselocalmap = DMNEW(s4, state.validlocals);
1093 for (i=0; i<jd->m->maxlocals; ++i)
1094 for (t=0; t<5; ++t) {
1095 s4 mapped = jd->local_map[5*i + t];
1097 state.reverselocalmap[mapped] = i;
1101 LOG("reverselocalmap:");
1102 for (i=0; i<state.validlocals; ++i) {
1103 LOG2(" %i => javaindex %i", i, state.reverselocalmap[i]);
1106 /* allocate the buffer of active exception handlers */
1108 state.handlers = DMNEW(exceptiontable*, state.cd->exceptiontablelength + 1);
1110 /* save local variables */
1112 savedlocals = DMNEW(varinfo, state.numlocals);
1113 MCOPY(savedlocals, jd->var, varinfo, state.numlocals);
1115 /* initialized local variables of first block */
1117 if (!verify_init_locals(&state))
1120 /* initialize invars of exception handlers */
1122 state.exinvars = state.numlocals;
1123 VAR(state.exinvars)->type = TYPE_ADR;
1124 typeinfo_init_classinfo(&(VAR(state.exinvars)->typeinfo),
1125 class_java_lang_Throwable); /* changed later */
1127 LOG("Exception handler stacks set.\n");
1129 /* loop while there are still blocks to be checked */
1131 TYPECHECK_COUNT(count_iterations);
1133 state.repeat = false;
1135 state.bptr = state.basicblocks;
1137 for (; state.bptr; state.bptr = state.bptr->next) {
1138 LOGSTR1("---- BLOCK %04d, ",state.bptr->nr);
1139 LOGSTR1("blockflags: %d\n",state.bptr->flags);
1142 /* verify reached block */
1143 if (state.bptr->flags == BBTYPECHECK_REACHED) {
1144 if (!verify_basic_block(&state))
1149 LOGIF(state.repeat,"state.repeat == true");
1150 } while (state.repeat);
1154 #ifdef TYPECHECK_STATISTICS
1155 LOG1("Typechecker did %4d iterations",count_iterations);
1156 TYPECHECK_COUNT_FREQ(stat_iterations,count_iterations,STAT_ITERATIONS);
1157 TYPECHECK_COUNTIF(state.jsrencountered,stat_typechecked_jsr);
1158 TYPECHECK_COUNTIF(state.stat_maythrow,stat_methods_maythrow);
1161 /* reset the flags of blocks we haven't reached */
1163 typecheck_reset_flags(&state);
1165 /* restore locals */
1167 MCOPY(jd->var, savedlocals, varinfo, state.numlocals);
1169 /* everything's ok */
1171 LOGimp("exiting typecheck");
1174 #endif /* ENABLE_VERIFIER */
1177 * These are local overrides for various environment variables in Emacs.
1178 * Please do not remove this and leave it at the end of the file, where
1179 * Emacs will automagically detect them.
1180 * ---------------------------------------------------------------------
1183 * indent-tabs-mode: t
1187 * vim:noexpandtab:sw=4:ts=4: