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:
neis 2015-10-21 04:17:12 -07:00 committed by Commit bot
parent a910b8f0e2
commit 33f1075933
6 changed files with 20 additions and 39 deletions

View File

@ -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);
}

View File

@ -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(

View File

@ -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);

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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());
}