Handlify JSObject::LookupAccessor method.
R=yangguo@chromium.org Review URL: https://codereview.chromium.org/25508002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17048 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
b3c440f8da
commit
d67ffdaa52
@ -6167,7 +6167,7 @@ void JSObject::DefineAccessor(Handle<JSObject> object,
|
|||||||
|
|
||||||
// Make sure that the top context does not change when doing callbacks or
|
// Make sure that the top context does not change when doing callbacks or
|
||||||
// interceptor calls.
|
// interceptor calls.
|
||||||
AssertNoContextChangeWithHandleScope ncc;
|
AssertNoContextChange ncc;
|
||||||
|
|
||||||
// Try to flatten before operating on the string.
|
// Try to flatten before operating on the string.
|
||||||
if (name->IsString()) String::cast(*name)->TryFlatten();
|
if (name->IsString()) String::cast(*name)->TryFlatten();
|
||||||
@ -6412,58 +6412,62 @@ Handle<Object> JSObject::SetAccessor(Handle<JSObject> object,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MaybeObject* JSObject::LookupAccessor(Name* name, AccessorComponent component) {
|
Handle<Object> JSObject::GetAccessor(Handle<JSObject> object,
|
||||||
Heap* heap = GetHeap();
|
Handle<Name> name,
|
||||||
|
AccessorComponent component) {
|
||||||
|
Isolate* isolate = object->GetIsolate();
|
||||||
|
|
||||||
// Make sure that the top context does not change when doing callbacks or
|
// Make sure that the top context does not change when doing callbacks or
|
||||||
// interceptor calls.
|
// interceptor calls.
|
||||||
AssertNoContextChangeWithHandleScope ncc;
|
AssertNoContextChange ncc;
|
||||||
|
|
||||||
// Check access rights if needed.
|
// Check access rights if needed.
|
||||||
if (IsAccessCheckNeeded() &&
|
if (object->IsAccessCheckNeeded() &&
|
||||||
!heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_HAS)) {
|
!isolate->MayNamedAccess(*object, *name, v8::ACCESS_HAS)) {
|
||||||
heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS);
|
isolate->ReportFailedAccessCheck(*object, v8::ACCESS_HAS);
|
||||||
RETURN_IF_SCHEDULED_EXCEPTION(heap->isolate());
|
RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
|
||||||
return heap->undefined_value();
|
return isolate->factory()->undefined_value();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make the lookup and include prototypes.
|
// Make the lookup and include prototypes.
|
||||||
uint32_t index = 0;
|
uint32_t index = 0;
|
||||||
if (name->AsArrayIndex(&index)) {
|
if (name->AsArrayIndex(&index)) {
|
||||||
for (Object* obj = this;
|
for (Handle<Object> obj = object;
|
||||||
obj != heap->null_value();
|
*obj != isolate->heap()->null_value();
|
||||||
obj = JSReceiver::cast(obj)->GetPrototype()) {
|
obj = handle(JSReceiver::cast(*obj)->GetPrototype(), isolate)) {
|
||||||
if (obj->IsJSObject() && JSObject::cast(obj)->HasDictionaryElements()) {
|
if (obj->IsJSObject() && JSObject::cast(*obj)->HasDictionaryElements()) {
|
||||||
JSObject* js_object = JSObject::cast(obj);
|
JSObject* js_object = JSObject::cast(*obj);
|
||||||
SeededNumberDictionary* dictionary = js_object->element_dictionary();
|
SeededNumberDictionary* dictionary = js_object->element_dictionary();
|
||||||
int entry = dictionary->FindEntry(index);
|
int entry = dictionary->FindEntry(index);
|
||||||
if (entry != SeededNumberDictionary::kNotFound) {
|
if (entry != SeededNumberDictionary::kNotFound) {
|
||||||
Object* element = dictionary->ValueAt(entry);
|
Object* element = dictionary->ValueAt(entry);
|
||||||
if (dictionary->DetailsAt(entry).type() == CALLBACKS &&
|
if (dictionary->DetailsAt(entry).type() == CALLBACKS &&
|
||||||
element->IsAccessorPair()) {
|
element->IsAccessorPair()) {
|
||||||
return AccessorPair::cast(element)->GetComponent(component);
|
return handle(AccessorPair::cast(element)->GetComponent(component),
|
||||||
|
isolate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (Object* obj = this;
|
for (Handle<Object> obj = object;
|
||||||
obj != heap->null_value();
|
*obj != isolate->heap()->null_value();
|
||||||
obj = JSReceiver::cast(obj)->GetPrototype()) {
|
obj = handle(JSReceiver::cast(*obj)->GetPrototype(), isolate)) {
|
||||||
LookupResult result(heap->isolate());
|
LookupResult result(isolate);
|
||||||
JSReceiver::cast(obj)->LocalLookup(name, &result);
|
JSReceiver::cast(*obj)->LocalLookup(*name, &result);
|
||||||
if (result.IsFound()) {
|
if (result.IsFound()) {
|
||||||
if (result.IsReadOnly()) return heap->undefined_value();
|
if (result.IsReadOnly()) return isolate->factory()->undefined_value();
|
||||||
if (result.IsPropertyCallbacks()) {
|
if (result.IsPropertyCallbacks()) {
|
||||||
Object* obj = result.GetCallbackObject();
|
Object* obj = result.GetCallbackObject();
|
||||||
if (obj->IsAccessorPair()) {
|
if (obj->IsAccessorPair()) {
|
||||||
return AccessorPair::cast(obj)->GetComponent(component);
|
return handle(AccessorPair::cast(obj)->GetComponent(component),
|
||||||
|
isolate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return heap->undefined_value();
|
return isolate->factory()->undefined_value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2218,6 +2218,15 @@ class JSObject: public JSReceiver {
|
|||||||
uint32_t index,
|
uint32_t index,
|
||||||
bool continue_search);
|
bool continue_search);
|
||||||
|
|
||||||
|
// Retrieves an AccessorPair property from the given object. Might return
|
||||||
|
// undefined if the property doesn't exist or is of a different kind.
|
||||||
|
static Handle<Object> GetAccessor(Handle<JSObject> object,
|
||||||
|
Handle<Name> name,
|
||||||
|
AccessorComponent component);
|
||||||
|
|
||||||
|
// Defines an AccessorPair property on the given object.
|
||||||
|
// TODO(mstarzinger): Rename to SetAccessor() and return empty handle on
|
||||||
|
// exception instead of letting callers check for scheduled exception.
|
||||||
static void DefineAccessor(Handle<JSObject> object,
|
static void DefineAccessor(Handle<JSObject> object,
|
||||||
Handle<Name> name,
|
Handle<Name> name,
|
||||||
Handle<Object> getter,
|
Handle<Object> getter,
|
||||||
@ -2225,8 +2234,7 @@ class JSObject: public JSReceiver {
|
|||||||
PropertyAttributes attributes,
|
PropertyAttributes attributes,
|
||||||
v8::AccessControl access_control = v8::DEFAULT);
|
v8::AccessControl access_control = v8::DEFAULT);
|
||||||
|
|
||||||
MaybeObject* LookupAccessor(Name* name, AccessorComponent component);
|
// Defines an AccessorInfo property on the given object.
|
||||||
|
|
||||||
static Handle<Object> SetAccessor(Handle<JSObject> object,
|
static Handle<Object> SetAccessor(Handle<JSObject> object,
|
||||||
Handle<AccessorInfo> info);
|
Handle<AccessorInfo> info);
|
||||||
|
|
||||||
|
@ -10582,14 +10582,17 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetArrayKeys) {
|
|||||||
|
|
||||||
|
|
||||||
RUNTIME_FUNCTION(MaybeObject*, Runtime_LookupAccessor) {
|
RUNTIME_FUNCTION(MaybeObject*, Runtime_LookupAccessor) {
|
||||||
SealHandleScope shs(isolate);
|
HandleScope scope(isolate);
|
||||||
ASSERT(args.length() == 3);
|
ASSERT(args.length() == 3);
|
||||||
CONVERT_ARG_CHECKED(JSReceiver, receiver, 0);
|
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
|
||||||
CONVERT_ARG_CHECKED(Name, name, 1);
|
CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
|
||||||
CONVERT_SMI_ARG_CHECKED(flag, 2);
|
CONVERT_SMI_ARG_CHECKED(flag, 2);
|
||||||
AccessorComponent component = flag == 0 ? ACCESSOR_GETTER : ACCESSOR_SETTER;
|
AccessorComponent component = flag == 0 ? ACCESSOR_GETTER : ACCESSOR_SETTER;
|
||||||
if (!receiver->IsJSObject()) return isolate->heap()->undefined_value();
|
if (!receiver->IsJSObject()) return isolate->heap()->undefined_value();
|
||||||
return JSObject::cast(receiver)->LookupAccessor(name, component);
|
Handle<Object> result =
|
||||||
|
JSObject::GetAccessor(Handle<JSObject>::cast(receiver), name, component);
|
||||||
|
RETURN_IF_EMPTY_HANDLE(isolate, result);
|
||||||
|
return *result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user