verify.cc (pop_init_ref): New method.

* verify.cc (pop_init_ref): New method.
	(verify_instructions_0) [op_iaload, op_laload, op_faload,
	op_daload, op_aaload, op_baload, op_caload, op_saload, op_iastore,
	op_lastore, op_fastore, op_dastore, op_aastore, op_bastore,
	op_castore, op_sastore, op_areturn, op_arraylength, op_checkcast,
	op_instanceof, op_monitorenter, op_monitorexit]: Use it.
	(verify_instructions_0) [op_invokevirtual, op_invokespecial,
	op_invokestatic, op_invokeinterface]:  Use pop_init_ref.  Don't
	let `this' argument be uninitialized.  Don't let `null' be passed
	as `this' to construtor.

From-SVN: r59558
This commit is contained in:
Tom Tromey 2002-11-27 05:59:39 +00:00 committed by Tom Tromey
parent 920e86b8da
commit 02077425b7
2 changed files with 61 additions and 26 deletions

View file

@ -1,3 +1,16 @@
2002-11-26 Tom Tromey <tromey@redhat.com>
* verify.cc (pop_init_ref): New method.
(verify_instructions_0) [op_iaload, op_laload, op_faload,
op_daload, op_aaload, op_baload, op_caload, op_saload, op_iastore,
op_lastore, op_fastore, op_dastore, op_aastore, op_bastore,
op_castore, op_sastore, op_areturn, op_arraylength, op_checkcast,
op_instanceof, op_monitorenter, op_monitorexit]: Use it.
(verify_instructions_0) [op_invokevirtual, op_invokespecial,
op_invokestatic, op_invokeinterface]: Use pop_init_ref. Don't
let `this' argument be uninitialized. Don't let `null' be passed
as `this' to construtor.
2002-11-26 Mark Wielaard <mark@klomp.org> 2002-11-26 Mark Wielaard <mark@klomp.org>
* javax/transaction/HeuristicCommitException.java: Classpath merge. * javax/transaction/HeuristicCommitException.java: Classpath merge.

View file

@ -458,7 +458,8 @@ private:
if (key < reference_type || k.key < reference_type) if (key < reference_type || k.key < reference_type)
return key == k.key; return key == k.key;
// The `null' type is convertible to any reference type. // The `null' type is convertible to any initialized reference
// type.
if (key == null_type || k.key == null_type) if (key == null_type || k.key == null_type)
return true; return true;
@ -1137,6 +1138,19 @@ private:
return t; return t;
} }
// Pop a reference which is guaranteed to be initialized. MATCH
// doesn't have to be a reference type; in this case this acts like
// pop_type.
type pop_init_ref (type match)
{
type t = pop_raw ();
if (t.isreference () && ! t.isinitialized ())
verify_fail ("initialized reference required");
else if (! match.compatible (t, this))
verify_fail ("incompatible type on stack");
return t;
}
// Pop a reference type or a return address. // Pop a reference type or a return address.
type pop_ref_or_return () type pop_ref_or_return ()
{ {
@ -2300,42 +2314,42 @@ private:
break; break;
case op_iaload: case op_iaload:
pop_type (int_type); pop_type (int_type);
push_type (require_array_type (pop_type (reference_type), push_type (require_array_type (pop_init_ref (reference_type),
int_type)); int_type));
break; break;
case op_laload: case op_laload:
pop_type (int_type); pop_type (int_type);
push_type (require_array_type (pop_type (reference_type), push_type (require_array_type (pop_init_ref (reference_type),
long_type)); long_type));
break; break;
case op_faload: case op_faload:
pop_type (int_type); pop_type (int_type);
push_type (require_array_type (pop_type (reference_type), push_type (require_array_type (pop_init_ref (reference_type),
float_type)); float_type));
break; break;
case op_daload: case op_daload:
pop_type (int_type); pop_type (int_type);
push_type (require_array_type (pop_type (reference_type), push_type (require_array_type (pop_init_ref (reference_type),
double_type)); double_type));
break; break;
case op_aaload: case op_aaload:
pop_type (int_type); pop_type (int_type);
push_type (require_array_type (pop_type (reference_type), push_type (require_array_type (pop_init_ref (reference_type),
reference_type)); reference_type));
break; break;
case op_baload: case op_baload:
pop_type (int_type); pop_type (int_type);
require_array_type (pop_type (reference_type), byte_type); require_array_type (pop_init_ref (reference_type), byte_type);
push_type (int_type); push_type (int_type);
break; break;
case op_caload: case op_caload:
pop_type (int_type); pop_type (int_type);
require_array_type (pop_type (reference_type), char_type); require_array_type (pop_init_ref (reference_type), char_type);
push_type (int_type); push_type (int_type);
break; break;
case op_saload: case op_saload:
pop_type (int_type); pop_type (int_type);
require_array_type (pop_type (reference_type), short_type); require_array_type (pop_init_ref (reference_type), short_type);
push_type (int_type); push_type (int_type);
break; break;
case op_istore: case op_istore:
@ -2386,42 +2400,42 @@ private:
case op_iastore: case op_iastore:
pop_type (int_type); pop_type (int_type);
pop_type (int_type); pop_type (int_type);
require_array_type (pop_type (reference_type), int_type); require_array_type (pop_init_ref (reference_type), int_type);
break; break;
case op_lastore: case op_lastore:
pop_type (long_type); pop_type (long_type);
pop_type (int_type); pop_type (int_type);
require_array_type (pop_type (reference_type), long_type); require_array_type (pop_init_ref (reference_type), long_type);
break; break;
case op_fastore: case op_fastore:
pop_type (float_type); pop_type (float_type);
pop_type (int_type); pop_type (int_type);
require_array_type (pop_type (reference_type), float_type); require_array_type (pop_init_ref (reference_type), float_type);
break; break;
case op_dastore: case op_dastore:
pop_type (double_type); pop_type (double_type);
pop_type (int_type); pop_type (int_type);
require_array_type (pop_type (reference_type), double_type); require_array_type (pop_init_ref (reference_type), double_type);
break; break;
case op_aastore: case op_aastore:
pop_type (reference_type); pop_type (reference_type);
pop_type (int_type); pop_type (int_type);
require_array_type (pop_type (reference_type), reference_type); require_array_type (pop_init_ref (reference_type), reference_type);
break; break;
case op_bastore: case op_bastore:
pop_type (int_type); pop_type (int_type);
pop_type (int_type); pop_type (int_type);
require_array_type (pop_type (reference_type), byte_type); require_array_type (pop_init_ref (reference_type), byte_type);
break; break;
case op_castore: case op_castore:
pop_type (int_type); pop_type (int_type);
pop_type (int_type); pop_type (int_type);
require_array_type (pop_type (reference_type), char_type); require_array_type (pop_init_ref (reference_type), char_type);
break; break;
case op_sastore: case op_sastore:
pop_type (int_type); pop_type (int_type);
pop_type (int_type); pop_type (int_type);
require_array_type (pop_type (reference_type), short_type); require_array_type (pop_init_ref (reference_type), short_type);
break; break;
case op_pop: case op_pop:
pop32 (); pop32 ();
@ -2759,7 +2773,7 @@ private:
invalidate_pc (); invalidate_pc ();
break; break;
case op_areturn: case op_areturn:
check_return_type (pop_type (reference_type)); check_return_type (pop_init_ref (reference_type));
invalidate_pc (); invalidate_pc ();
break; break;
case op_return: case op_return:
@ -2841,7 +2855,7 @@ private:
// This is only used for verifying the byte for // This is only used for verifying the byte for
// invokeinterface. // invokeinterface.
nargs -= arg_types[i].depth (); nargs -= arg_types[i].depth ();
pop_type (arg_types[i]); pop_init_ref (arg_types[i]);
} }
if (opcode == op_invokeinterface if (opcode == op_invokeinterface
@ -2858,7 +2872,15 @@ private:
} }
type raw = pop_raw (); type raw = pop_raw ();
bool ok = false; bool ok = false;
if (t.compatible (raw, this)) if (! is_init && ! raw.isinitialized ())
{
// This is a failure.
}
else if (is_init && raw.isnull ())
{
// Another failure.
}
else if (t.compatible (raw, this))
{ {
ok = true; ok = true;
} }
@ -2914,7 +2936,7 @@ private:
break; break;
case op_arraylength: case op_arraylength:
{ {
type t = pop_type (reference_type); type t = pop_init_ref (reference_type);
if (! t.isarray () && ! t.isnull ()) if (! t.isarray () && ! t.isnull ())
verify_fail ("array type expected"); verify_fail ("array type expected");
push_type (int_type); push_type (int_type);
@ -2925,19 +2947,19 @@ private:
invalidate_pc (); invalidate_pc ();
break; break;
case op_checkcast: case op_checkcast:
pop_type (reference_type); pop_init_ref (reference_type);
push_type (check_class_constant (get_ushort ())); push_type (check_class_constant (get_ushort ()));
break; break;
case op_instanceof: case op_instanceof:
pop_type (reference_type); pop_init_ref (reference_type);
check_class_constant (get_ushort ()); check_class_constant (get_ushort ());
push_type (int_type); push_type (int_type);
break; break;
case op_monitorenter: case op_monitorenter:
pop_type (reference_type); pop_init_ref (reference_type);
break; break;
case op_monitorexit: case op_monitorexit:
pop_type (reference_type); pop_init_ref (reference_type);
break; break;
case op_wide: case op_wide:
{ {
@ -2971,7 +2993,7 @@ private:
set_variable (get_ushort (), pop_type (double_type)); set_variable (get_ushort (), pop_type (double_type));
break; break;
case op_astore: case op_astore:
set_variable (get_ushort (), pop_type (reference_type)); set_variable (get_ushort (), pop_init_ref (reference_type));
break; break;
case op_ret: case op_ret:
handle_ret_insn (get_short ()); handle_ret_insn (get_short ());