Move some code from Runtime_GetPrototype into a new Object::GetPrototype.
Also clean up the access check, which was doing too much. This is in preparation of implementing Reflect.getPrototypeOf. BUG= Review URL: https://codereview.chromium.org/1402973002 Cr-Commit-Position: refs/heads/master@{#31434}
This commit is contained in:
parent
a910b8f0e2
commit
33f1075933
@ -1199,15 +1199,22 @@ MaybeHandle<Object> Object::SetElement(Isolate* isolate, Handle<Object> object,
|
||||
}
|
||||
|
||||
|
||||
Handle<Object> Object::GetPrototypeSkipHiddenPrototypes(
|
||||
Isolate* isolate, Handle<Object> receiver) {
|
||||
PrototypeIterator iter(isolate, receiver);
|
||||
while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)) {
|
||||
Handle<Object> Object::GetPrototype(Isolate* isolate, Handle<Object> obj) {
|
||||
// We don't expect access checks to be needed on JSProxy objects.
|
||||
DCHECK(!obj->IsAccessCheckNeeded() || obj->IsJSObject());
|
||||
Handle<Context> context(isolate->context());
|
||||
if (obj->IsAccessCheckNeeded() &&
|
||||
!isolate->MayAccess(context, Handle<JSObject>::cast(obj))) {
|
||||
return isolate->factory()->null_value();
|
||||
}
|
||||
|
||||
PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER);
|
||||
do {
|
||||
iter.AdvanceIgnoringProxies();
|
||||
if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) {
|
||||
return PrototypeIterator::GetCurrent(iter);
|
||||
}
|
||||
iter.Advance();
|
||||
}
|
||||
} while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN));
|
||||
return PrototypeIterator::GetCurrent(iter);
|
||||
}
|
||||
|
||||
|
@ -13886,7 +13886,7 @@ MaybeHandle<Object> JSObject::SetPrototype(Handle<JSObject> object,
|
||||
const bool observed = from_javascript && object->map()->is_observed();
|
||||
Handle<Object> old_value;
|
||||
if (observed) {
|
||||
old_value = Object::GetPrototypeSkipHiddenPrototypes(isolate, object);
|
||||
old_value = Object::GetPrototype(isolate, object);
|
||||
}
|
||||
|
||||
Handle<Object> result;
|
||||
@ -13895,8 +13895,7 @@ MaybeHandle<Object> JSObject::SetPrototype(Handle<JSObject> object,
|
||||
Object);
|
||||
|
||||
if (observed) {
|
||||
Handle<Object> new_value =
|
||||
Object::GetPrototypeSkipHiddenPrototypes(isolate, object);
|
||||
Handle<Object> new_value = Object::GetPrototype(isolate, object);
|
||||
if (!new_value->SameValue(*old_value)) {
|
||||
RETURN_ON_EXCEPTION(isolate,
|
||||
JSObject::EnqueueChangeRecord(
|
||||
|
@ -1290,8 +1290,9 @@ class Object {
|
||||
Isolate* isolate, Handle<Object> object, uint32_t index,
|
||||
Handle<Object> value, LanguageMode language_mode);
|
||||
|
||||
static inline Handle<Object> GetPrototypeSkipHiddenPrototypes(
|
||||
Isolate* isolate, Handle<Object> receiver);
|
||||
// Get the first non-hidden prototype.
|
||||
static inline Handle<Object> GetPrototype(Isolate* isolate,
|
||||
Handle<Object> receiver);
|
||||
|
||||
bool HasInPrototypeChain(Isolate* isolate, Object* object);
|
||||
|
||||
|
@ -1449,7 +1449,7 @@ RUNTIME_FUNCTION(Runtime_DebugGetPrototype) {
|
||||
HandleScope shs(isolate);
|
||||
DCHECK(args.length() == 1);
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
|
||||
return *Object::GetPrototypeSkipHiddenPrototypes(isolate, obj);
|
||||
return *Object::GetPrototype(isolate, obj);
|
||||
}
|
||||
|
||||
|
||||
|
@ -157,22 +157,7 @@ RUNTIME_FUNCTION(Runtime_GetPrototype) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK(args.length() == 1);
|
||||
CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
|
||||
// We don't expect access checks to be needed on JSProxy objects.
|
||||
DCHECK(!obj->IsAccessCheckNeeded() || obj->IsJSObject());
|
||||
PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER);
|
||||
Handle<Context> context(isolate->context());
|
||||
do {
|
||||
if (PrototypeIterator::GetCurrent(iter)->IsAccessCheckNeeded() &&
|
||||
!isolate->MayAccess(context,
|
||||
PrototypeIterator::GetCurrent<JSObject>(iter))) {
|
||||
return isolate->heap()->null_value();
|
||||
}
|
||||
iter.AdvanceIgnoringProxies();
|
||||
if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) {
|
||||
return *PrototypeIterator::GetCurrent(iter);
|
||||
}
|
||||
} while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN));
|
||||
return *PrototypeIterator::GetCurrent(iter);
|
||||
return *Object::GetPrototype(isolate, obj);
|
||||
}
|
||||
|
||||
|
||||
|
@ -17989,13 +17989,6 @@ THREADED_TEST(Regress93759) {
|
||||
Object::New(isolate);
|
||||
object_with_hidden->SetPrototype(hidden_prototype);
|
||||
|
||||
// Hidden prototype with security check on the hidden prototype.
|
||||
Local<Object> protected_hidden_prototype =
|
||||
protected_hidden_proto_template->GetFunction()->NewInstance();
|
||||
Local<Object> object_with_protected_hidden =
|
||||
Object::New(isolate);
|
||||
object_with_protected_hidden->SetPrototype(protected_hidden_prototype);
|
||||
|
||||
context->Exit();
|
||||
|
||||
// Template for object for second context. Values to test are put on it as
|
||||
@ -18006,7 +17999,6 @@ THREADED_TEST(Regress93759) {
|
||||
global_template->Set(v8_str("global"), global_object);
|
||||
global_template->Set(v8_str("proxy"), proxy_object);
|
||||
global_template->Set(v8_str("hidden"), object_with_hidden);
|
||||
global_template->Set(v8_str("phidden"), object_with_protected_hidden);
|
||||
|
||||
LocalContext context2(NULL, global_template);
|
||||
|
||||
@ -18025,9 +18017,6 @@ THREADED_TEST(Regress93759) {
|
||||
Local<Value> result5 = CompileRun("Object.getPrototypeOf(hidden)");
|
||||
CHECK(result5->Equals(
|
||||
object_with_hidden->GetPrototype()->ToObject(isolate)->GetPrototype()));
|
||||
|
||||
Local<Value> result6 = CompileRun("Object.getPrototypeOf(phidden)");
|
||||
CHECK(result6->IsNull());
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user