- /****************************************/
- /* STACK MANIPULATIONS */
-
- /* We just need to copy the typeinfo */
- /* for slots containing addresses. */
-
- case ICMD_MOVE:
- case ICMD_COPY:
- TYPECHECK_COUNT(stat_ins_stack);
- COPYTYPE(iptr->s1, iptr->dst);
- dv->type = VAROP(iptr->s1)->type;
- break;
-
- /****************************************/
- /* PRIMITIVE VARIABLE ACCESS */
-
- case ICMD_ILOAD: if (!typevector_checktype(jd->var,state->iptr->s1.varindex,TYPE_INT))
- TYPECHECK_VERIFYERROR_bool("Local variable type mismatch");
- dv->type = TYPE_INT;
- break;
- case ICMD_IINC: if (!typevector_checktype(jd->var,state->iptr->s1.varindex,TYPE_INT))
- TYPECHECK_VERIFYERROR_bool("Local variable type mismatch");
- dv->type = TYPE_INT;
- break;
- case ICMD_FLOAD: if (!typevector_checktype(jd->var,state->iptr->s1.varindex,TYPE_FLT))
- TYPECHECK_VERIFYERROR_bool("Local variable type mismatch");
- dv->type = TYPE_FLT;
- break;
- case ICMD_LLOAD: if (!typevector_checktype(jd->var,state->iptr->s1.varindex,TYPE_LNG))
- TYPECHECK_VERIFYERROR_bool("Local variable type mismatch");
- dv->type = TYPE_LNG;
- break;
- case ICMD_DLOAD: if (!typevector_checktype(jd->var,state->iptr->s1.varindex,TYPE_DBL))
- TYPECHECK_VERIFYERROR_bool("Local variable type mismatch");
- dv->type = TYPE_DBL;
- break;
-
- case ICMD_ISTORE:
- typecheck_invalidate_locals(state, state->iptr->dst.varindex, false);
- typevector_store(jd->var,state->iptr->dst.varindex,TYPE_INT,NULL);
- break;
- case ICMD_FSTORE:
- typecheck_invalidate_locals(state, state->iptr->dst.varindex, false);
- typevector_store(jd->var,state->iptr->dst.varindex,TYPE_FLT,NULL);
- break;
- case ICMD_LSTORE:
- typecheck_invalidate_locals(state, state->iptr->dst.varindex, true);
- typevector_store(jd->var,state->iptr->dst.varindex,TYPE_LNG,NULL);
- break;
- case ICMD_DSTORE:
- typecheck_invalidate_locals(state, state->iptr->dst.varindex, true);
- typevector_store(jd->var,state->iptr->dst.varindex,TYPE_DBL,NULL);
- break;
-
- /****************************************/
- /* LOADING ADDRESS FROM VARIABLE */
-
- case ICMD_ALOAD:
- TYPECHECK_COUNT(stat_ins_aload);
-
- /* loading a returnAddress is not allowed */
- if (!TYPEDESC_IS_REFERENCE(*VAROP(state->iptr->s1))) {
- TYPECHECK_VERIFYERROR_bool("illegal instruction: ALOAD loading non-reference");
- }
- TYPEINFO_COPY(VAROP(state->iptr->s1)->typeinfo,dv->typeinfo);
- dv->type = TYPE_ADR;
- break;
-
- /****************************************/
- /* STORING ADDRESS TO VARIABLE */
-
- case ICMD_ASTORE:
- typecheck_invalidate_locals(state, state->iptr->dst.varindex, false);
-
- if (TYPEINFO_IS_PRIMITIVE(VAROP(state->iptr->s1)->typeinfo)) {
- typevector_store_retaddr(jd->var,state->iptr->dst.varindex,&(VAROP(state->iptr->s1)->typeinfo));
- }
- else {
- typevector_store(jd->var,state->iptr->dst.varindex,TYPE_ADR,
- &(VAROP(state->iptr->s1)->typeinfo));
- }
- break;
-
- /****************************************/
- /* LOADING ADDRESS FROM ARRAY */
-
- case ICMD_AALOAD:
- if (!TYPEINFO_MAYBE_ARRAY_OF_REFS(VAROP(state->iptr->s1)->typeinfo))
- TYPECHECK_VERIFYERROR_bool("illegal instruction: AALOAD on non-reference array");
-
- if (!typeinfo_init_component(&VAROP(state->iptr->s1)->typeinfo,&dv->typeinfo))
- return false;
- dv->type = TYPE_ADR;
- maythrow = true;
- break;
-
- /****************************************/
- /* FIELD ACCESS */
-
- case ICMD_PUTFIELD:
- case ICMD_PUTSTATIC:
- case ICMD_PUTFIELDCONST:
- case ICMD_PUTSTATICCONST:
- case ICMD_GETFIELD:
- case ICMD_GETSTATIC:
- {
- varinfo *valueslot = NULL;
- typeinfo *instanceti = NULL;
- typeinfo *valueti = NULL;
- bool isstatic = false;
- bool isput = false;
- typeinfo constti;
-
- TYPECHECK_COUNT(stat_ins_field);
-
- if (INSTRUCTION_IS_UNRESOLVED(state->iptr)) {
- uf = state->iptr->sx.s23.s3.uf;
- fieldref = uf->fieldref;
- }
- else {
- uf = NULL;
- fieldref = state->iptr->sx.s23.s3.fmiref;
- }
-
- /* get opcode dependent values */
-
- switch (state->iptr->opc) {
- case ICMD_PUTFIELD:
- isput = true;
- valueslot = VAROP(state->iptr->sx.s23.s2);
- instanceti = &(VAROP(state->iptr->s1)->typeinfo);
- break;
-
- case ICMD_PUTFIELDCONST:
- isput = true;
- instanceti = &(VAROP(state->iptr->s1)->typeinfo);
-putfield_const_tail:
- if (IS_ADR_TYPE(fieldref->parseddesc.fd->type)) {
- /* XXX check for java.lang.Class constant values? */
- if (state->iptr->sx.val.anyptr) {
- assert(class_java_lang_String);
- assert(class_java_lang_String->state & CLASS_LOADED);
- assert(class_java_lang_String->state & CLASS_LINKED);
- typeinfo_init_classinfo(&constti, class_java_lang_String);
- }
- else {
- TYPEINFO_INIT_NULLTYPE(constti);
- }
- valueti = &constti;
- }
- break;
-
- case ICMD_PUTSTATIC:
- isput = true;
- isstatic = true;
- valueslot = VAROP(state->iptr->s1);
- break;
-
- case ICMD_PUTSTATICCONST:
- isput = true;
- isstatic = true;
- goto putfield_const_tail;
-
- case ICMD_GETFIELD:
- instanceti = &(VAROP(state->iptr->s1)->typeinfo);
- break;
-
- case ICMD_GETSTATIC:
- isstatic = true;
- break;
-
- default:
- assert(false);
- }
-
- if (valueslot && IS_ADR_TYPE(valueslot->type)) {
- valueti = &(valueslot->typeinfo);
- }
-
- /* try to resolve the field reference lazily */
-
- result = resolve_field_lazy(state->m, fieldref);
-
- if (result == resolveSucceeded) {
- fieldinfo *fi;
-
- /* perform verification checks now */
-
- fi = fieldref->p.field;
-
- result = resolve_field_verifier_checks(
- state->m, fieldref, fi->class, fi,
- instanceti, valueti, isstatic, isput);
- }
-
- if (result == resolveFailed)
- return false;
-
- /* if not resolved, yet, create an unresolved field */
-
- if (result != resolveSucceeded) {
- if (!uf) {
- uf = resolve_create_unresolved_field(state->m->class,
- state->m, state->iptr);
- if (!uf)
- return false;
-
- state->iptr->sx.s23.s3.uf = uf;
- state->iptr->flags.bits |= INS_FLAG_UNRESOLVED;
- }
-
- /* record the subtype constraints for this field access */
-
- if (!resolve_constrain_unresolved_field(
- uf, state->m->class, state->m,
- instanceti, valueti))
- return false; /* XXX maybe wrap exception? */
-
- TYPECHECK_COUNTIF(INSTRUCTION_IS_UNRESOLVED(state->iptr),stat_ins_field_unresolved);
- TYPECHECK_COUNTIF(INSTRUCTION_IS_RESOLVED(state->iptr) &&
- !state->iptr->sx.s23.s3.fmiref->p.field->class->initialized,
- stat_ins_field_uninitialized);
- }
-
- /* write the result type */
-
- if (iptr->opc == ICMD_GETFIELD || iptr->opc == ICMD_GETSTATIC) {
- dv->type = fieldref->parseddesc.fd->type;
- if (dv->type == TYPE_ADR) {
- if (!typeinfo_init_from_typedesc(fieldref->parseddesc.fd,
- NULL, &(dv->typeinfo)))
- return false;
- }
- }
-
- maythrow = true;
- }
- break;
-
- /****************************************/
- /* PRIMITIVE ARRAY ACCESS */
-
- case ICMD_ARRAYLENGTH:
- if (!TYPEINFO_MAYBE_ARRAY(VAROP(state->iptr->s1)->typeinfo)
- && VAROP(state->iptr->s1)->typeinfo.typeclass.cls != pseudo_class_Arraystub)
- TYPECHECK_VERIFYERROR_bool("illegal instruction: ARRAYLENGTH on non-array");
- dv->type = TYPE_INT;
- maythrow = true;
- break;
-
- case ICMD_BALOAD:
- if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_BOOLEAN)
- && !TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_BYTE))
- TYPECHECK_VERIFYERROR_bool("Array type mismatch");
- dv->type = TYPE_INT;
- maythrow = true;
- break;
- case ICMD_CALOAD:
- if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_CHAR))
- TYPECHECK_VERIFYERROR_bool("Array type mismatch");
- dv->type = TYPE_INT;
- maythrow = true;
- break;
- case ICMD_DALOAD:
- if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_DOUBLE))
- TYPECHECK_VERIFYERROR_bool("Array type mismatch");
- dv->type = TYPE_DBL;
- maythrow = true;
- break;
- case ICMD_FALOAD:
- if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_FLOAT))
- TYPECHECK_VERIFYERROR_bool("Array type mismatch");
- dv->type = TYPE_FLT;
- maythrow = true;
- break;
- case ICMD_IALOAD:
- if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_INT))
- TYPECHECK_VERIFYERROR_bool("Array type mismatch");
- dv->type = TYPE_INT;
- maythrow = true;
- break;
- case ICMD_SALOAD:
- if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_SHORT))
- TYPECHECK_VERIFYERROR_bool("Array type mismatch");
- dv->type = TYPE_INT;
- maythrow = true;
- break;
- case ICMD_LALOAD:
- if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_LONG))
- TYPECHECK_VERIFYERROR_bool("Array type mismatch");
- dv->type = TYPE_LNG;
- maythrow = true;
- break;
-
- case ICMD_BASTORE:
- if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_BOOLEAN)
- && !TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_BYTE))
- TYPECHECK_VERIFYERROR_bool("Array type mismatch");
- maythrow = true;
- break;
- case ICMD_CASTORE:
- if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_CHAR))
- TYPECHECK_VERIFYERROR_bool("Array type mismatch");
- maythrow = true;
- break;
- case ICMD_DASTORE:
- if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_DOUBLE))
- TYPECHECK_VERIFYERROR_bool("Array type mismatch");
- maythrow = true;
- break;
- case ICMD_FASTORE:
- if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_FLOAT))
- TYPECHECK_VERIFYERROR_bool("Array type mismatch");
- maythrow = true;
- break;
- case ICMD_IASTORE:
- if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_INT))
- TYPECHECK_VERIFYERROR_bool("Array type mismatch");
- maythrow = true;
- break;
- case ICMD_SASTORE:
- if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_SHORT))
- TYPECHECK_VERIFYERROR_bool("Array type mismatch");
- maythrow = true;
- break;
- case ICMD_LASTORE:
- if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo,ARRAYTYPE_LONG))
- TYPECHECK_VERIFYERROR_bool("Array type mismatch");
- maythrow = true;
- break;
-
- case ICMD_AASTORE:
- /* we just check the basic input types and that the */
- /* destination is an array of references. Assignability to */
- /* the actual array must be checked at runtime, each time the */
- /* instruction is performed. (See builtin_canstore.) */
- TYPECHECK_ADR_OP(state->iptr->sx.s23.s3);
- TYPECHECK_INT_OP(state->iptr->sx.s23.s2);
- TYPECHECK_ADR_OP(state->iptr->s1);
- if (!TYPEINFO_MAYBE_ARRAY_OF_REFS(VAROP(state->iptr->s1)->typeinfo))
- TYPECHECK_VERIFYERROR_bool("illegal instruction: AASTORE to non-reference array");
- maythrow = true;
- break;
-
- case ICMD_IASTORECONST:
- if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo, ARRAYTYPE_INT))
- TYPECHECK_VERIFYERROR_bool("Array type mismatch");
- maythrow = true;
- break;
-
- case ICMD_LASTORECONST:
- if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo, ARRAYTYPE_LONG))
- TYPECHECK_VERIFYERROR_bool("Array type mismatch");
- maythrow = true;
- break;
-
- case ICMD_BASTORECONST:
- if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo, ARRAYTYPE_BOOLEAN)
- && !TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo, ARRAYTYPE_BYTE))
- TYPECHECK_VERIFYERROR_bool("Array type mismatch");
- maythrow = true;
- break;
-
- case ICMD_CASTORECONST:
- if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo, ARRAYTYPE_CHAR))
- TYPECHECK_VERIFYERROR_bool("Array type mismatch");
- maythrow = true;
- break;
-
- case ICMD_SASTORECONST:
- if (!TYPEINFO_MAYBE_PRIMITIVE_ARRAY(VAROP(state->iptr->s1)->typeinfo, ARRAYTYPE_SHORT))
- TYPECHECK_VERIFYERROR_bool("Array type mismatch");
- maythrow = true;
- break;
-
- /****************************************/
- /* ADDRESS CONSTANTS */
-
- case ICMD_ACONST:
- if (state->iptr->flags.bits & INS_FLAG_CLASS) {
- /* a java.lang.Class reference */
- TYPEINFO_INIT_JAVA_LANG_CLASS(dv->typeinfo,state->iptr->sx.val.c);
- }
- else {
- if (state->iptr->sx.val.anyptr == NULL)
- TYPEINFO_INIT_NULLTYPE(dv->typeinfo);
- else {
- /* string constant (or constant for builtin function) */
- typeinfo_init_classinfo(&(dv->typeinfo),class_java_lang_String);
- }
- }
- dv->type = TYPE_ADR;
- break;
-
- /****************************************/
- /* CHECKCAST AND INSTANCEOF */
-
- case ICMD_CHECKCAST:
- TYPECHECK_ADR_OP(state->iptr->s1);
- /* returnAddress is not allowed */
- if (!TYPEINFO_IS_REFERENCE(VAROP(state->iptr->s1)->typeinfo))
- TYPECHECK_VERIFYERROR_bool("Illegal instruction: CHECKCAST on non-reference");
-
- if (!typeinfo_init_class(&(dv->typeinfo),state->iptr->sx.s23.s3.c))
- return false;
- dv->type = TYPE_ADR;
- maythrow = true;
- break;
-
- case ICMD_INSTANCEOF:
- TYPECHECK_ADR_OP(state->iptr->s1);
- /* returnAddress is not allowed */
- if (!TYPEINFO_IS_REFERENCE(VAROP(state->iptr->s1)->typeinfo))
- TYPECHECK_VERIFYERROR_bool("Illegal instruction: INSTANCEOF on non-reference");
- dv->type = TYPE_INT;
- break;
-
- /****************************************/
- /* BRANCH INSTRUCTIONS */
-
- case ICMD_INLINE_GOTO:
- COPYTYPE(state->iptr->s1,state->iptr->dst);
- /* FALLTHROUGH! */
- case ICMD_GOTO:
- superblockend = true;
- /* FALLTHROUGH! */
- case ICMD_IFNULL:
- case ICMD_IFNONNULL:
- case ICMD_IFEQ:
- case ICMD_IFNE:
- case ICMD_IFLT:
- case ICMD_IFGE:
- case ICMD_IFGT:
- case ICMD_IFLE:
- case ICMD_IF_ICMPEQ:
- case ICMD_IF_ICMPNE:
- case ICMD_IF_ICMPLT:
- case ICMD_IF_ICMPGE:
- case ICMD_IF_ICMPGT:
- case ICMD_IF_ICMPLE:
- case ICMD_IF_ACMPEQ:
- case ICMD_IF_ACMPNE:
-
- case ICMD_IF_LEQ:
- case ICMD_IF_LNE:
- case ICMD_IF_LLT:
- case ICMD_IF_LGE:
- case ICMD_IF_LGT:
- case ICMD_IF_LLE:
-
- case ICMD_IF_LCMPEQ:
- case ICMD_IF_LCMPNE:
- case ICMD_IF_LCMPLT:
- case ICMD_IF_LCMPGE:
- case ICMD_IF_LCMPGT:
- case ICMD_IF_LCMPLE:
-
- case ICMD_IF_FCMPEQ:
- case ICMD_IF_FCMPNE:
-
- case ICMD_IF_FCMPL_LT:
- case ICMD_IF_FCMPL_GE:
- case ICMD_IF_FCMPL_GT:
- case ICMD_IF_FCMPL_LE:
-
- case ICMD_IF_FCMPG_LT:
- case ICMD_IF_FCMPG_GE:
- case ICMD_IF_FCMPG_GT:
- case ICMD_IF_FCMPG_LE:
-
- case ICMD_IF_DCMPEQ:
- case ICMD_IF_DCMPNE:
-
- case ICMD_IF_DCMPL_LT:
- case ICMD_IF_DCMPL_GE:
- case ICMD_IF_DCMPL_GT:
- case ICMD_IF_DCMPL_LE:
-
- case ICMD_IF_DCMPG_LT:
- case ICMD_IF_DCMPG_GE:
- case ICMD_IF_DCMPG_GT:
- case ICMD_IF_DCMPG_LE:
- TYPECHECK_COUNT(stat_ins_branch);
-
- /* propagate stack and variables to the target block */
- if (!typestate_reach(state, state->iptr->dst.block,
- state->bptr->outvars, jd->var,
- state->bptr->outdepth))
- return false;
- break;
-
- /****************************************/
- /* SWITCHES */
-
- case ICMD_TABLESWITCH:
- TYPECHECK_COUNT(stat_ins_switch);
-
- table = iptr->dst.table;
- i = iptr->sx.s23.s3.tablehigh
- - iptr->sx.s23.s2.tablelow + 1 + 1; /* plus default */
-
- while (--i >= 0) {
- tbptr = (table++)->block;
- LOG2("target %d is block %04d",i,tbptr->nr);
- if (!typestate_reach(state, tbptr, state->bptr->outvars,
- jd->var, state->bptr->outdepth))
- return false;
- }
-
- LOG("switch done");
- superblockend = true;
- break;
-
- case ICMD_LOOKUPSWITCH:
- TYPECHECK_COUNT(stat_ins_switch);
-
- lookup = iptr->dst.lookup;
- i = iptr->sx.s23.s2.lookupcount;
-
- if (!typestate_reach(state,iptr->sx.s23.s3.lookupdefault.block,
- state->bptr->outvars, jd->var,
- state->bptr->outdepth))
- return false;
-
- while (--i >= 0) {
- tbptr = (lookup++)->target.block;
- LOG2("target %d is block %04d",i,tbptr->nr);
- if (!typestate_reach(state, tbptr, state->bptr->outvars,
- jd->var, state->bptr->outdepth))
- return false;
- }
-
- LOG("switch done");
- superblockend = true;
- break;
-
-
- /****************************************/
- /* ADDRESS RETURNS AND THROW */
-
- case ICMD_ATHROW:
- TYPECHECK_COUNT(stat_ins_athrow);
- r = typeinfo_is_assignable_to_class(&VAROP(state->iptr->s1)->typeinfo,
- CLASSREF_OR_CLASSINFO(class_java_lang_Throwable));
- if (r == typecheck_FALSE)
- TYPECHECK_VERIFYERROR_bool("illegal instruction: ATHROW on non-Throwable");
- if (r == typecheck_FAIL)
- return false;
- if (r == typecheck_MAYBE) {
- /* the check has to be postponed. we need a patcher */
- TYPECHECK_COUNT(stat_ins_athrow_unresolved);
- iptr->sx.s23.s2.uc = create_unresolved_class(
- state->m,
- /* XXX make this more efficient, use class_java_lang_Throwable
- * directly */
- class_get_classref(state->m->class,utf_java_lang_Throwable),
- &VAROP(state->iptr->s1)->typeinfo);
- iptr->flags.bits |= INS_FLAG_UNRESOLVED;
- }
- superblockend = true;
- maythrow = true;
- break;
-
- case ICMD_ARETURN:
- TYPECHECK_COUNT(stat_ins_areturn);
- if (!TYPEINFO_IS_REFERENCE(VAROP(state->iptr->s1)->typeinfo))
- TYPECHECK_VERIFYERROR_bool("illegal instruction: ARETURN on non-reference");
-
- if (state->returntype.type != TYPE_ADR
- || (r = typeinfo_is_assignable(&VAROP(state->iptr->s1)->typeinfo,&(state->returntype.typeinfo)))
- == typecheck_FALSE)
- TYPECHECK_VERIFYERROR_bool("Return type mismatch");
- if (r == typecheck_FAIL)
- return false;
- if (r == typecheck_MAYBE) {
- /* the check has to be postponed, we need a patcher */
- TYPECHECK_COUNT(stat_ins_areturn_unresolved);
- iptr->sx.s23.s2.uc = create_unresolved_class(
- state->m,
- state->m->parseddesc->returntype.classref,
- &VAROP(state->iptr->s1)->typeinfo);
- iptr->flags.bits |= INS_FLAG_UNRESOLVED;
- }
- goto return_tail;
-
- /****************************************/
- /* PRIMITIVE RETURNS */
-
- case ICMD_IRETURN:
- if (state->returntype.type != TYPE_INT) TYPECHECK_VERIFYERROR_bool("Return type mismatch");
- goto return_tail;
-
- case ICMD_LRETURN:
- if (state->returntype.type != TYPE_LNG) TYPECHECK_VERIFYERROR_bool("Return type mismatch");
- goto return_tail;
-
- case ICMD_FRETURN:
- if (state->returntype.type != TYPE_FLT) TYPECHECK_VERIFYERROR_bool("Return type mismatch");
- goto return_tail;
-
- case ICMD_DRETURN:
- if (state->returntype.type != TYPE_DBL) TYPECHECK_VERIFYERROR_bool("Return type mismatch");
- goto return_tail;
-
- case ICMD_RETURN:
- if (state->returntype.type != TYPE_VOID) TYPECHECK_VERIFYERROR_bool("Return type mismatch");
-return_tail:
- TYPECHECK_COUNT(stat_ins_primitive_return);
-
- if (state->initmethod && state->m->class != class_java_lang_Object) {
- /* Check if the 'this' instance has been initialized. */
- LOG("Checking <init> marker");
- if (!typevector_checktype(jd->var,state->numlocals-1,TYPE_INT))
- TYPECHECK_VERIFYERROR_bool("<init> method does not initialize 'this'");
- }
-
- superblockend = true;
- maythrow = true;
- break;
-
- /****************************************/
- /* SUBROUTINE INSTRUCTIONS */
-
- case ICMD_JSR:
- LOG("jsr");
-
- tbptr = state->iptr->sx.s23.s3.jsrtarget.block;
- TYPEINFO_INIT_RETURNADDRESS(dv->typeinfo, state->bptr->next);
- if (!typestate_reach(state, tbptr, state->bptr->outvars, jd->var,
- state->bptr->outdepth))
- return false;
-
- superblockend = true;
- break;
-
- case ICMD_RET:
- /* check returnAddress variable */
- if (!typevector_checkretaddr(jd->var,state->iptr->s1.varindex))
- TYPECHECK_VERIFYERROR_bool("illegal instruction: RET using non-returnAddress variable");
-
- if (!typestate_reach(state, iptr->dst.block, state->bptr->outvars, jd->var,
- state->bptr->outdepth))
- return false;
-
- superblockend = true;
- break;
-
- /****************************************/
- /* INVOKATIONS */
-
- case ICMD_INVOKEVIRTUAL:
- case ICMD_INVOKESPECIAL:
- case ICMD_INVOKESTATIC:
- case ICMD_INVOKEINTERFACE:
- TYPECHECK_COUNT(stat_ins_invoke);
- if (!verify_invocation(state))
- return false;
- TYPECHECK_COUNTIF(INSTRUCTION_IS_UNRESOLVED(iptr), stat_ins_invoke_unresolved);
- maythrow = true;
- break;
-
- /****************************************/
- /* MULTIANEWARRAY */
-
- case ICMD_MULTIANEWARRAY:
- if (!verify_multianewarray(state))
- return false;
- maythrow = true;
- break;
-
- /****************************************/
- /* BUILTINS */
-
- case ICMD_BUILTIN:
- TYPECHECK_COUNT(stat_ins_builtin);
- if (!verify_builtin(state))
- return false;
- maythrow = true;
- break;