You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by ml...@apache.org on 2007/08/06 05:01:53 UTC
svn commit: r563013 - in
/harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363: Pass2.cpp
context.h tpool.cpp tpool.h
Author: mloenko
Date: Sun Aug 5 20:01:52 2007
New Revision: 563013
URL: http://svn.apache.org/viewvc?view=rev&rev=563013
Log:
fixed HARMONY-4537 and HARMONY-4538 (access to super class members)
Modified:
harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/Pass2.cpp
harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/context.h
harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/tpool.cpp
harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/tpool.h
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/Pass2.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/Pass2.cpp?view=diff&rev=563013&r1=563012&r2=563013
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/Pass2.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/Pass2.cpp Sun Aug 5 20:01:52 2007
@@ -1520,7 +1520,10 @@
if( !tpool.cpool_get_field(cp_idx, &ref, &value) ) return error(VF_ErrorUnknown, "incorrect constantpool entry");
//pop INs
- POP_ref(ref);
+ vf_Result result;
+ if( (result = popFieldRef(ref, cp_idx)) != VF_OK ) {
+ return result;
+ }
//push OUTs
PUSH_z(value);
@@ -1556,7 +1559,10 @@
}
if( workmap_stackview(0).getAnyPossibleValue() != SM_THISUNINIT ) {
- POP_ref(expected_ref);
+ vf_Result result;
+ if( (result = popFieldRef(expected_ref, cp_idx)) != VF_OK ) {
+ return result;
+ }
} else if( expected_ref == tpool.sm_get_const_this() ) {
workmap_pop();
} else {
@@ -1703,18 +1709,22 @@
} else {
if( expected_ref != wm_init.getConst() ) return error(VF_ErrorUnknown, "incorrect uninitialized type");
}
+ } else if( opcode == OP_INVOKESPECIAL ) {
+ //pop object ref (it must extend be either 'this' or a sub class of 'this')
+ POP_ref( tpool.sm_get_const_this() );
+
+ //check that 'expected_ref' is a super class of 'this'
+ if( !tpool.mustbe_assignable(tpool.sm_get_const_this(), expected_ref) ) {
+ return error(VF_ErrorUnknown, "incorrect use of invokespecial");
+ }
+ } else if( opcode == OP_INVOKEVIRTUAL ) {
+ vf_Result result;
+ if( (result = popVirtualRef(expected_ref, cp_idx)) != VF_OK ) {
+ return result;
+ }
} else if( opcode != OP_INVOKESTATIC ) {
//pop object ref
POP_ref( expected_ref );
-
- if( opcode == OP_INVOKESPECIAL ) {
- //TODO: is verifier the right place for this check?
-
- //check that 'expected_ref' is a super class of 'this'
- if( !tpool.mustbe_assignable(tpool.sm_get_const_this(), expected_ref) ) {
- return error(VF_ErrorUnknown, "incorrect use of invokespecial");
- }
- }
}
//push OUTs
@@ -2559,4 +2569,60 @@
return VF_OK;
}
+ vf_Result vf_Context_t::popFieldRef(SmConstant expected_ref, unsigned short cp_idx) {
+ int check = tpool.checkFieldAccess( expected_ref, cp_idx);
+ if ( check == vf_TypePool::_BOGUS ) return error(VF_ErrorResolve, "can't resolve constantpool class");
+
+ if( check != vf_TypePool::_FALSE ) {
+ assert(check == vf_TypePool::_TRUE);
+
+ //pop object ref (it must extend be either 'this' or a sub class of 'this')
+ POP_ref( tpool.sm_get_const_this() );
+
+ //check that 'expected_ref' is a super class of 'this'
+ if( !tpool.mustbe_assignable(tpool.sm_get_const_this(), expected_ref) ) {
+ return error(VF_ErrorUnknown, "incorrect use of invokespecial");
+ }
+ } else {
+ POP_ref( expected_ref );
+ }
+ return VF_OK;
+ }
+
+
+ vf_Result vf_Context_t::popVirtualRef(SmConstant expected_ref, unsigned short cp_idx) {
+ int check = tpool.checkVirtualAccess( expected_ref, cp_idx);
+ if ( check == vf_TypePool::_BOGUS ) return error(VF_ErrorResolve, "can't resolve constantpool class");
+
+ if( check != vf_TypePool::_FALSE ) {
+ if( !workmap_can_pop(1) ) return error(VF_ErrorDataFlow, "unable to pop from empty operand stack");
+ WorkmapElement value = workmap_pop();
+
+ if( check == vf_TypePool::_CLONE ) {
+ //if the first value is an array ==> expect array here
+ SmConstant c = value.getAnyPossibleValue();
+ if( c.isReference() && tpool.sm_get_refname(c)[0] == '[' ) {
+ if( !workmap_expect(value, SM_ANYARRAY) ) return error(VF_ErrorIncompatibleArgument, "incompartible argument");
+ if( !workmap_expect(value, expected_ref) ) return error(VF_ErrorIncompatibleArgument, "incompartible argument");
+ } else {
+ check = vf_TypePool::_TRUE;
+ }
+ }
+
+ if ( check != vf_TypePool::_CLONE ) {
+ assert(check == vf_TypePool::_TRUE);
+
+ //pop object ref (it must extend be either 'this' or a sub class of 'this')
+ if( !workmap_expect(value, tpool.sm_get_const_this()) ) return error(VF_ErrorIncompatibleArgument, "incompartible argument");
+
+ //check that 'expected_ref' is a super class of 'this'
+ if( !tpool.mustbe_assignable(tpool.sm_get_const_this(), expected_ref) ) {
+ return error(VF_ErrorUnknown, "incorrect use of invokespecial");
+ }
+ }
+ } else {
+ POP_ref( expected_ref );
+ }
+ return VF_OK;
+ }
} // namespace CPVerifier
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/context.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/context.h?view=diff&rev=563013&r1=563012&r2=563013
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/context.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/context.h Sun Aug 5 20:01:52 2007
@@ -295,6 +295,14 @@
/////////////////////////////////////////////////////////////////////////////////////////////////////
+ //check conditions for accessing protected non-static fields in different package
+ vf_Result popFieldRef(SmConstant expected_ref, unsigned short cp_idx);
+
+ //check conditions for accessing protected virtual methods in different package
+ vf_Result popVirtualRef(SmConstant expected_ref, unsigned short cp_idx);
+
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+
//add one more possible value (type) that can come to the given point (local or stack)
vf_Result add_incoming_value(SmConstant new_value, StackmapElement *destination);
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/tpool.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/tpool.cpp?view=diff&rev=563013&r1=563012&r2=563013
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/tpool.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/tpool.cpp Sun Aug 5 20:01:52 2007
@@ -261,6 +261,76 @@
}
}
+ //check if expected_ref is a super class of 'this', its package differs
+ int vf_TypePool::checkSuperAndPackage(SmConstant expected_ref) {
+ //check that expected ref is a super of 'this'
+ vf_ValidType *expected_type = &validTypes[expected_ref.getReferenceIdx()];
+
+ if (!class_is_extending_class(k_class, (char*)expected_type->name)) {
+ return _FALSE;
+ }
+
+ class_handler &referred = expected_type->cls;
+
+ if( !referred || referred == CLASS_NOT_LOADED ) {
+ //we need to ersolve class here
+ referred = vf_resolve_class(k_class, expected_type->name, true);
+
+ //referred class can't be resolved ==> return anything
+ if( !referred ) return _BOGUS;
+ }
+
+ //check that they are in different packages and method is protected
+ if( class_is_same_package(k_class, referred) ) {
+ return _FALSE;
+ }
+
+ return _TRUE;
+ }
+
+ //check if expected_ref is a super class of 'this', its package differs, and it's protected
+ int vf_TypePool::checkVirtualAccess(SmConstant expected_ref, unsigned short method_idx) {
+ //check if expected_ref is a super class of 'this', its package differs
+ int sp;
+ if( (sp = checkSuperAndPackage(expected_ref)) != _TRUE ) {
+ return sp;
+ }
+
+ //check further
+ //check that they are in different packages and method is protected
+ method_handler method = class_resolve_method(k_class, method_idx);
+
+ if (!method || method_is_static(method)) {
+ //it's not a VerifyError
+ return _FALSE;
+ }
+
+ // for arrays function clone is public
+ return !method_is_protected(method) ? _FALSE : !memcmp(method_get_name(method), "clone", 6) ? _CLONE : _TRUE;
+ }
+
+ //check if expected_ref is a super class of 'this', its package differs, and it's protected
+ int vf_TypePool::checkFieldAccess(SmConstant expected_ref, unsigned short field_idx) {
+ //check if expected_ref is a super class of 'this', its package differs
+ int sp;
+ if( (sp = checkSuperAndPackage(expected_ref)) != _TRUE ) {
+ return sp;
+ }
+
+ //check further
+ //check that they are in different packages and method is protected
+ field_handler field = class_resolve_nonstatic_field(k_class, field_idx);
+
+ if (!field) {
+ //it's not a VerifyError
+ return _FALSE;
+ }
+
+ // for arrays function clone is public
+ return field_is_protected(field) ? _TRUE : _FALSE;
+ }
+
+
void vf_TypePool::NewConstraint(const char *available,
const char *required)
{
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/tpool.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/tpool.h?view=diff&rev=563013&r1=563012&r2=563013
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/tpool.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/tpool.h Sun Aug 5 20:01:52 2007
@@ -234,6 +234,11 @@
return SM_BOGUS;
}
+ //check if expected_ref is a super class of 'this', its package differs, and it's protected
+ enum FieldAndMethodCheck {_FALSE, _CLONE, _BOGUS, _TRUE};
+ int checkFieldAccess(SmConstant expected_ref, unsigned short method_idx);
+ int checkVirtualAccess(SmConstant expected_ref, unsigned short method_idx);
+ int checkSuperAndPackage(SmConstant expected_ref);
private:
//ref to the main class of the verifier
vf_Context_t *context;