/* src/vm/jit/verify/typecheck.c - typechecking (part of bytecode verification)
- Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
- R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
- C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
- Institut f. Computersprachen - TU Wien
+ Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+ C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
+ E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
+ J. Wenninger, Institut f. Computersprachen - TU Wien
This file is part of CACAO.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA.
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
- Contact: cacao@complang.tuwien.ac.at
+ Contact: cacao@cacaojvm.org
Authors: Edwin Steiner
Changes: Christian Thalinger
- $Id: typecheck.c 3644 2005-11-09 19:32:03Z edwin $
+ $Id: typecheck.c 4357 2006-01-22 23:33:38Z twisti $
*/
#include <assert.h>
#include <string.h>
+#include "config.h"
#include "vm/types.h"
+#include "vm/global.h"
-#include "vm/global.h" /* must be here because of CACAO_TYPECHECK */
-
-#ifdef CACAO_TYPECHECK
+#ifdef ENABLE_VERIFIER
#include "mm/memory.h"
#include "toolbox/logging.h"
#include "vm/jit/patcher.h"
#include "vm/loader.h"
#include "vm/options.h"
-#include "vm/tables.h"
#include "vm/jit/jit.h"
#include "vm/jit/stack.h"
#include "vm/access.h"
fprintf(file," (uninit.) : %8d\n",stat_ins_field_uninitialized);
fprintf(file," invocations : %8d\n",stat_ins_invoke);
fprintf(file," (unresolved) : %8d\n",stat_ins_invoke_unresolved);
- fprintf(file," load primitive : %8d\n",stat_ins_primload);
+ fprintf(file," load primitive : (currently not counted) %8d\n",stat_ins_primload);
fprintf(file," load address : %8d\n",stat_ins_aload);
fprintf(file," builtins : %8d\n",stat_ins_builtin);
fprintf(file," generic : %8d\n",stat_ins_builtin_gen);
int k;
for (;dst; dst=dst->prev, y=y->prev) {
+ /* XXX only check the following two in debug mode? */
if (!y) {
*exceptionptr = new_verifyerror(state->m,"Stack depth mismatch");
return false;
}
}
-/* XXX document */
-/* 'a' and 'b' are assumed to have passed typestack_canmerge! */
+/* typestack_separable_with ****************************************************
+
+ This function answers the question: If variant 'kb' of typestack 'b' is
+ added to typestack 'a', will the result be separable?
+
+ A typestack is called 'separable' if it has at least one slot of type
+ returnAddress that contains at least two different return addresses.
+ (ie. a RET using the value in this slot could go to more than one target)
+
+ IN:
+ a................the first typestack
+ b................the second typestack
+ kb...............the k-index of the variant that should be selected
+ from typestack 'b'
+
+ OUT:
+ true.............the result would be separable
+ false............the result would not be separable
+
+ PRE-CONDITION:
+ 'a' and 'b' are assumed to have passed typestack_canmerge!
+
+*******************************************************************************/
+
static bool
typestack_separable_with(stackptr a,stackptr b,int kb)
{
return false;
}
-/* XXX document */
-/* 'a' and 'b' are assumed to have passed typestack_canmerge! */
+/* typestack_separable_from ****************************************************
+
+ This function answers the question: Is variant 'ka' of typestack 'a'
+ separable from variant 'kb' of typestack 'b'?
+
+ Two variants of typestacks are called 'separable' from each other, if there
+ is at least one slot for which the variants contain different return addresses.
+ (ie. a RET using the value in this slot would go to one target in the first
+ variant and to another target in the second variant)
+
+ IN:
+ a................the first typestack
+ ka...............the k-index of the variant that should be selected
+ from typestack 'a'
+ b................the second typestack
+ kb...............the k-index of the variant that should be selected
+ from typestack 'b'
+
+ OUT:
+ true.............the variants are separable
+ false............the variants are not separable
+
+ PRE-CONDITION:
+ 'a' and 'b' are assumed to have passed typestack_canmerge!
+
+*******************************************************************************/
+
static bool
typestack_separable_from(stackptr a,int ka,stackptr b,int kb)
{
}
/* check array descriptor */
- if (state->iptr[0].target == NULL) {
+ if (state->iptr[0].val.a != NULL) {
/* the array class reference has already been resolved */
arrayclass = (classinfo *) state->iptr[0].val.a;
if (!arrayclass)
/* the array class reference is still unresolved */
/* check that the reference indicates an array class of correct dimension */
- cr = (constant_classref *) state->iptr[0].val.a;
+ cr = (constant_classref *) state->iptr[0].target;
i = 0;
p = cr->name->text;
while (p[i] == '[')
TYPECHECK_VERIFYERROR_bool("MULTIANEWARRAY dimension to high");
/* set the array type of the result */
- if (!typeinfo_init_class(&(state->iptr->dst->typeinfo),CLASSREF_OR_CLASSINFO(state->iptr[0].val.a)))
+ if (!typeinfo_init_class(&(state->iptr->dst->typeinfo),CLASSREF_OR_CLASSINFO(state->iptr[0].target)))
return false;
}
/* of eclipse 3.0.2 */
if (TYPEINFO_NEWOBJECT_INSTRUCTION(state->localset->td[i].info) != NULL) {
/*show_icmd_method(state->m, state->cd, state->rd);*/
- printf("Uninitialized variale: %d, block: %d\n", i, state->bptr->debug_nr);
+ printf("Uninitialized variable: %d, block: %d\n", i, state->bptr->debug_nr);
TYPECHECK_VERIFYERROR_bool("Uninitialized object in local variable inside try block");
}
}
if (!resolve_field(uf,resolveLazy,fieldinfop))
return false;
- /* we need a patcher, so this is not a leafmethod */
-#if defined(__MIPS__)
- if (!*fieldinfop || !(*fieldinfop)->class->initialized)
- state->cd->method->isleafmethod = false;
-#endif
TYPECHECK_COUNTIF(!*fieldinfop,stat_ins_field_unresolved);
TYPECHECK_COUNTIF(*fieldinfop && !(*fieldinfop)->class->initialized,stat_ins_field_uninitialized);
* Instructions below...
* *) don't operate on local variables,
* *) don't operate on references,
- * *) don't operate on returnAddresses.
+ * *) don't operate on returnAddresses,
+ * *) don't affect control flow (except
+ * by throwing exceptions).
*
* (These instructions are typechecked in
* analyse_stack.)
case ICMD_LSHL:
case ICMD_LSHR:
case ICMD_LUSHR:
-#if 0
- case ICMD_IREM0X10001:
- case ICMD_LREM0X10001:
-#endif
case ICMD_IMULPOW2:
case ICMD_LMULPOW2:
case ICMD_IDIVPOW2:
return state.m;
}
-#endif /* CACAO_TYPECHECK */
+#endif /* ENABLE_VERIFIER */
/*
* These are local overrides for various environment variables in Emacs.