53 #if defined(ENABLE_VERIFIER)
57 #if defined(TYPECHECK_VERBOSE)
59 typedescriptor *
stack,
60 typedescriptor *stackfloor,
65 #define CHECK_STACK_DEPTH(d) \
66 if (((u1*)stack - (u1*)stackfloor) \
67 < (((d)-1) * (int)sizeof(verifier_slot_t))) \
68 goto throw_stack_underflow;
71 #define CHECK_STACK_SPACE(d) \
72 if (((u1*)STATE->stackceiling - (u1*)stack) \
73 < (((d)+1) * (int)sizeof(verifier_slot_t))) \
74 if (STATE->iptr->opc != ICMD_ACONST \
75 || INSTRUCTION_MUST_CHECK(STATE->iptr)) \
76 goto throw_stack_overflow;
78 #define CHECK_STACK_TYPE(s, t) \
79 if ((s).type != (t)) \
80 goto throw_stack_type_error;
83 #define CHECK_LOCAL_TYPE(index, t) \
85 if (state.locals[(index)].type != (t)) \
86 goto throw_local_type_error; \
88 STATE->topjsr->usedlocals[(index)] = 1; \
89 if (STATE->topjsr && IS_2_WORD_TYPE(t)) \
90 STATE->topjsr->usedlocals[(index) + 1] = 1; \
94 #define STORE_LOCAL(t, index) \
96 state.locals[(index)].type = (t); \
97 if ((index) && IS_2_WORD_TYPE(state.locals[(index)-1].type)) \
98 state.locals[(index-1)].type = TYPE_VOID; \
100 STATE->topjsr->usedlocals[(index)] = 1; \
104 #define STORE_LOCAL_2_WORD(t, index) \
106 STORE_LOCAL(t, index); \
107 state.locals[(index)+1].type = TYPE_VOID; \
109 STATE->topjsr->usedlocals[(index)] = 1; \
112 #define VERIFY_ERROR_ret(msg,ret) \
114 OLD_LOG1("VerifyError: %s", msg); \
115 exceptions_throw_verifyerror(STATE->m, msg); \
119 #define VERIFY_ERROR(msg) VERIFY_ERROR_ret(msg,false)
121 #define IS_CAT1(slot) \
122 ((slot).type != TYPE_VOID && !IS_2_WORD_TYPE((slot).type))
124 #define IS_CAT2(slot) \
125 ((slot).type != TYPE_VOID && IS_2_WORD_TYPE((slot).type))
127 #define CHECK_CAT1(slot) \
129 if (!IS_CAT1(slot)) \
130 goto throw_stack_category_error; \
133 #define CHECK_CAT2(slot) \
135 if (!IS_CAT2(slot)) \
136 goto throw_stack_category_error; \
139 #define COPY_SLOT(s, d) \
140 do { (d) = (s); } while (0)
142 #define REACH_BLOCK(target) \
144 if (!typecheck_stackbased_reach(STATE, (target), stack, \
145 (stack - stackfloor) + 1)) \
149 #define REACH(target) \
151 REACH_BLOCK((target).block); \
166 bool changed =
false;
218 bool changed =
false;
220 destidx = destblock->
nr;
222 if (stackdepth != state->
indepth[destidx]) {
227 stackfloor = stack - (stackdepth - 1);
232 for (i=0; i<stackdepth; ++
i, ++
sp, ++dp) {
233 if (sp->type != dp->
type) {
240 if (sp->typeinfo.is_primitive()) {
253 if (sp->typeinfo.is_primitive()) {
279 bool changed =
false;
289 DOLOG( typecheck_stackbased_show_state(state, stack, stack - (stackdepth - 1),
false); );
291 state->
indepth[destblock->
nr] = stackdepth;
294 stack - (stackdepth - 1),
310 DOLOG( typecheck_stackbased_show_state(state, stack, stack - (stackdepth - 1),
false); );
324 if (destblock->
nr <= state->
bptr->
nr) {
359 #define TYPECHECK_STACKBASED
360 #define EXCEPTION do { return NULL; } while (0)
363 #define VERIFY_ERROR(msg) VERIFY_ERROR_ret(msg,NULL)
367 #undef TYPECHECK_STACKBASED
369 #define VERIFY_ERROR(msg) VERIFY_ERROR_ret(msg,false)
373 throw_stack_overflow:
395 if ((stack - stackfloor) + 1 < paramslots) {
397 "Trying to pop operand of an empty stack");
401 dv = stack - (paramslots - 1);
403 #define TYPECHECK_STACKBASED
407 #undef TYPECHECK_STACKBASED
423 paramslots = state->
iptr->
sx.
s23.s3.bte->md->paramslots;
425 if ((stack - stackfloor) + 1 < paramslots) {
427 "Trying to pop operand of an empty stack");
431 dv = stack - (paramslots - 1);
433 #define TYPECHECK_STACKBASED
435 #define TYPECHECK_INT(s) CHECK_STACK_TYPE(*(s), TYPE_INT)
436 #define TYPECHECK_ADR(s) CHECK_STACK_TYPE(*(s), TYPE_ADR)
437 #define TYPECHECK_LNG(s) CHECK_STACK_TYPE(*(s), TYPE_LNG)
438 #define TYPECHECK_FLT(s) CHECK_STACK_TYPE(*(s), TYPE_FLT)
439 #define TYPECHECK_DBL(s) CHECK_STACK_TYPE(*(s), TYPE_DBL)
442 #undef TYPECHECK_STACKBASED
446 throw_stack_type_error:
471 if ((stack - stackfloor) + 1 <
i) {
473 "Trying to pop operand of an empty stack");
480 for (sp = dst; sp <=
stack; ++
sp) {
491 arrayclass = state->
iptr->
sx.
s23.s3.c.cls;
516 if (i < state->iptr->s1.argcount)
555 tbptr = state->
iptr->
sx.
s23.s3.jsrtarget.block;
560 OLD_LOG1(
"another JSR to analysed subroutine L%03d", tbptr->
nr);
572 stack = stackfloor + (jsr->
retdepth - 1);
583 (stack - stackfloor) + 1))
588 OLD_LOG1(
"first JSR to block L%03d", tbptr->
nr);
603 OLD_LOG1(
"re-analysing JSR to block L%03d", tbptr->
nr);
648 OLD_LOG1(
"RET from subroutine L%03d", tbptr->
nr);
669 jsr->
retdepth = (stack - stackfloor) + 1;
680 OLD_LOG1(
"invalidating returnAddress in local %d", i);
687 for (jsrcaller = jsr->
callers; jsrcaller != NULL; jsrcaller = jsrcaller->
next) {
689 OLD_LOG1(
"touching caller L%03d from RET", tbptr->
nr);
727 # define STATE (&state)
747 stack = stackfloor - 1;
770 OLD_LOG(
"Exception handler stacks set.\n");
787 VERIFY_ERROR(
"Not enough local variables for method arguments");
798 OLD_LOG(
"'this' argument set.\n");
839 for (ex =
STATE->jd->exceptiontable; ex ; ex = ex->
down) {
842 STATE->handlers[len++] = ex;
845 STATE->handlers[len] = NULL;
861 stack = stackfloor + (len - 1);
868 superblockend =
false;
870 for (; len--; state.
iptr++) {
875 DOLOG( typecheck_stackbased_show_state(&state, stack, stackfloor,
true); );
878 #define TYPECHECK_STACKBASED 1
879 #define STATE (&state)
880 #define IPTR state.iptr
881 #define BPTR state.bptr
882 #define METHOD state.m
883 #define LOCAL_SLOT(index) (state.locals + (index))
886 OLD_LOG("EXCEPTION THROWN!\n"); \
890 #include <typecheck-stackbased-gen.inc>
891 #undef TYPECHECK_STACKBASED
899 OLD_LOG(
"\treaching exception handlers");
901 while (
STATE->handlers[i]) {
903 if (
STATE->handlers[i]->catchtype.any)
909 STATE->handlers[i]->handler,
919 if (!superblockend) {
921 stack, stack - stackfloor + 1))
957 OLD_LOG(
"typecheck_stackbased successful");
961 throw_stack_underflow:
966 throw_stack_overflow:
971 throw_stack_type_error:
976 throw_local_type_error:
981 throw_stack_category_error:
982 OLD_LOG(
"STACK CATEGORY ERROR!");
988 #if defined(TYPECHECK_VERBOSE)
989 static void typecheck_stackbased_show_state(
verifier_state *state,
997 OLD_LOGSTR1(
"stackdepth %d stack [", (stack - stackfloor) + 1);
998 for (sp=stackfloor; sp <=
stack; sp++) {
void exceptions_throw_verifyerror(methodinfo *m, const char *message,...)
static bool typecheck_stackbased_multianewarray(verifier_state *state, typedescriptor_t *stack, typedescriptor_t *stackfloor)
#define TYPECHECK_COUNT(cnt)
void init_class(classinfo *c)
Initialize object type.
exception_entry ** handlers
void init_newobject(instruction *instr)
#define TYPECHECK_MARK(var)
typedescriptor_t * startstack
typecheck_jsr_t ** jsrinfos
int typedescriptors_init_from_methoddesc(typedescriptor_t *td, methoddesc *desc, int buflen, bool twoword, int startindex, typedescriptor_t *returntype)
static bool typecheck_stackbased_ret(verifier_state *state, typedescriptor_t *stack, typedescriptor_t *stackfloor)
bool typecheck_stackbased(jitdata *jd)
void typecheck_init_state(verifier_state *state, basicblock::State minstate)
typedescriptor_t * retlocals
typedescriptor_t * locals
#define OLD_LOGSTR1(str, a)
static typecheck_result typecheck_stackbased_merge(verifier_state *state, basicblock *destblock, typedescriptor_t *stack, s4 stackdepth)
static bool typecheck_stackbased_reach(verifier_state *state, basicblock *destblock, typedescriptor_t *stack, s4 stackdepth)
JNIEnv jthread jobject jclass jlong size
#define MZERO(ptr, type, num)
typecheck_result merge(methodinfo *m, const typeinfo_t *t)
functions for merging types
void show_basicblock(jitdata *jd, basicblock *bptr, int stage)
#define VERIFY_ERROR(msg)
void init_returnaddress(void *adr)
alloc::list< PassInfo::IDTy >::type & stack
static typecheck_result typecheck_stackbased_merge_locals(methodinfo *m, typedescriptor_t *dst, typedescriptor_t *y, int size)
void typecheck_reset_state(verifier_state *state)
typecheck_jsr_caller_t * next
#define TYPECHECK_VERIFYERROR_bool(msg)
static bool typecheck_stackbased_verify_invocation(verifier_state *state, typedescriptor_t *stack, typedescriptor_t *stackfloor)
void * returnaddress() const
typedescriptor_t verifier_slot_t
bool is_primitive() const
typedescriptor_t * startlocals
union instruction::@12 sx
void params_from_paramtypes(s4 mflags)
typedescriptor_t * retstack
arraydescriptor * arraydesc
#define INSTRUCTION_GET_METHODDESC(iptr, md)
classref_or_classinfo typeclass
static bool typecheck_stackbased_verify_builtin(verifier_state *state, typedescriptor_t *stack, typedescriptor_t *stackfloor)
byte_iterator begin() const
void show_icmd(jitdata *jd, instruction *iptr, bool deadcode, int stage)
static typedescriptor_t * typecheck_stackbased_verify_fieldaccess(verifier_state *state, typedescriptor_t *instance, typedescriptor_t *value, typedescriptor_t *stack)
#define TYPECHECK_COUNTIF(cond, cnt)
static void * allocate(size_t size)
typedescriptor_t returntype
bool is_returnaddress() const
void typedescriptor_print(FILE *file, const typedescriptor_t *td)
struct instruction::@12::@13 s23
static typedescriptor_t * typecheck_stackbased_jsr(verifier_state *state, typedescriptor_t *stack, typedescriptor_t *stackfloor)
void jit_check_basicblock_numbers(jitdata *jd)
typedescriptor_t * stackceiling
#define INSTRUCTION_IS_RESOLVED(iptr)
#define MCOPY(dest, src, type, num)
void exceptions_throw_verifyerror_for_stack(methodinfo *m, int type)
classinfo * class_java_lang_Throwable
typecheck_jsr_caller_t * callers
static void typecheck_stackbased_add_jsr_caller(typecheck_jsr_t *jsr, basicblock *bptr)