Handlify GetPropertyWithCallback.
R=mstarzinger@chromium.org BUG= Review URL: https://codereview.chromium.org/27335002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17234 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
0bd3e179e5
commit
1eeebd2b6b
104
src/objects.cc
104
src/objects.cc
@ -343,9 +343,10 @@ static MaybeObject* GetDeclaredAccessorProperty(Object* receiver,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MaybeObject* JSObject::GetPropertyWithCallback(Object* receiver,
|
Handle<Object> JSObject::GetPropertyWithCallback(Handle<JSObject> object,
|
||||||
Object* structure,
|
Handle<Object> receiver,
|
||||||
Name* name) {
|
Handle<Object> structure,
|
||||||
|
Handle<Name> name) {
|
||||||
Isolate* isolate = name->GetIsolate();
|
Isolate* isolate = name->GetIsolate();
|
||||||
// To accommodate both the old and the new api we switch on the
|
// To accommodate both the old and the new api we switch on the
|
||||||
// data structure used to store the callbacks. Eventually foreign
|
// data structure used to store the callbacks. Eventually foreign
|
||||||
@ -353,66 +354,71 @@ MaybeObject* JSObject::GetPropertyWithCallback(Object* receiver,
|
|||||||
if (structure->IsForeign()) {
|
if (structure->IsForeign()) {
|
||||||
AccessorDescriptor* callback =
|
AccessorDescriptor* callback =
|
||||||
reinterpret_cast<AccessorDescriptor*>(
|
reinterpret_cast<AccessorDescriptor*>(
|
||||||
Foreign::cast(structure)->foreign_address());
|
Handle<Foreign>::cast(structure)->foreign_address());
|
||||||
MaybeObject* value = (callback->getter)(isolate, receiver, callback->data);
|
CALL_HEAP_FUNCTION(isolate,
|
||||||
RETURN_IF_SCHEDULED_EXCEPTION(isolate);
|
(callback->getter)(isolate, *receiver, callback->data),
|
||||||
return value;
|
Object);
|
||||||
}
|
}
|
||||||
|
|
||||||
// api style callbacks.
|
// api style callbacks.
|
||||||
if (structure->IsAccessorInfo()) {
|
if (structure->IsAccessorInfo()) {
|
||||||
if (!AccessorInfo::cast(structure)->IsCompatibleReceiver(receiver)) {
|
Handle<AccessorInfo> accessor_info = Handle<AccessorInfo>::cast(structure);
|
||||||
Handle<Object> name_handle(name, isolate);
|
if (!accessor_info->IsCompatibleReceiver(*receiver)) {
|
||||||
Handle<Object> receiver_handle(receiver, isolate);
|
Handle<Object> args[2] = { name, receiver };
|
||||||
Handle<Object> args[2] = { name_handle, receiver_handle };
|
|
||||||
Handle<Object> error =
|
Handle<Object> error =
|
||||||
isolate->factory()->NewTypeError("incompatible_method_receiver",
|
isolate->factory()->NewTypeError("incompatible_method_receiver",
|
||||||
HandleVector(args,
|
HandleVector(args,
|
||||||
ARRAY_SIZE(args)));
|
ARRAY_SIZE(args)));
|
||||||
return isolate->Throw(*error);
|
isolate->Throw(*error);
|
||||||
|
return Handle<Object>::null();
|
||||||
}
|
}
|
||||||
// TODO(rossberg): Handling symbols in the API requires changing the API,
|
// TODO(rossberg): Handling symbols in the API requires changing the API,
|
||||||
// so we do not support it for now.
|
// so we do not support it for now.
|
||||||
if (name->IsSymbol()) return isolate->heap()->undefined_value();
|
if (name->IsSymbol()) return isolate->factory()->undefined_value();
|
||||||
if (structure->IsDeclaredAccessorInfo()) {
|
if (structure->IsDeclaredAccessorInfo()) {
|
||||||
return GetDeclaredAccessorProperty(receiver,
|
CALL_HEAP_FUNCTION(
|
||||||
DeclaredAccessorInfo::cast(structure),
|
isolate,
|
||||||
isolate);
|
GetDeclaredAccessorProperty(*receiver,
|
||||||
|
DeclaredAccessorInfo::cast(*structure),
|
||||||
|
isolate),
|
||||||
|
Object);
|
||||||
}
|
}
|
||||||
ExecutableAccessorInfo* data = ExecutableAccessorInfo::cast(structure);
|
|
||||||
Object* fun_obj = data->getter();
|
Handle<ExecutableAccessorInfo> data =
|
||||||
|
Handle<ExecutableAccessorInfo>::cast(structure);
|
||||||
v8::AccessorGetterCallback call_fun =
|
v8::AccessorGetterCallback call_fun =
|
||||||
v8::ToCData<v8::AccessorGetterCallback>(fun_obj);
|
v8::ToCData<v8::AccessorGetterCallback>(data->getter());
|
||||||
if (call_fun == NULL) return isolate->heap()->undefined_value();
|
if (call_fun == NULL) return isolate->factory()->undefined_value();
|
||||||
|
|
||||||
HandleScope scope(isolate);
|
HandleScope scope(isolate);
|
||||||
JSObject* self = JSObject::cast(receiver);
|
Handle<JSObject> self = Handle<JSObject>::cast(receiver);
|
||||||
Handle<String> key(String::cast(name));
|
Handle<String> key = Handle<String>::cast(name);
|
||||||
LOG(isolate, ApiNamedPropertyAccess("load", self, name));
|
LOG(isolate, ApiNamedPropertyAccess("load", *self, *name));
|
||||||
PropertyCallbackArguments args(isolate, data->data(), self, this);
|
PropertyCallbackArguments args(isolate, data->data(), *self, *object);
|
||||||
v8::Handle<v8::Value> result =
|
v8::Handle<v8::Value> result =
|
||||||
args.Call(call_fun, v8::Utils::ToLocal(key));
|
args.Call(call_fun, v8::Utils::ToLocal(key));
|
||||||
RETURN_IF_SCHEDULED_EXCEPTION(isolate);
|
RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
|
||||||
if (result.IsEmpty()) {
|
if (result.IsEmpty()) {
|
||||||
return isolate->heap()->undefined_value();
|
return isolate->factory()->undefined_value();
|
||||||
}
|
}
|
||||||
Object* return_value = *v8::Utils::OpenHandle(*result);
|
Handle<Object> return_value = v8::Utils::OpenHandle(*result);
|
||||||
return_value->VerifyApiCallResultType();
|
return_value->VerifyApiCallResultType();
|
||||||
return return_value;
|
return scope.CloseAndEscape(return_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// __defineGetter__ callback
|
// __defineGetter__ callback
|
||||||
if (structure->IsAccessorPair()) {
|
Handle<Object> getter(Handle<AccessorPair>::cast(structure)->getter(),
|
||||||
Object* getter = AccessorPair::cast(structure)->getter();
|
isolate);
|
||||||
if (getter->IsSpecFunction()) {
|
if (getter->IsSpecFunction()) {
|
||||||
// TODO(rossberg): nicer would be to cast to some JSCallable here...
|
// TODO(rossberg): nicer would be to cast to some JSCallable here...
|
||||||
return GetPropertyWithDefinedGetter(receiver, JSReceiver::cast(getter));
|
CALL_HEAP_FUNCTION(
|
||||||
|
isolate,
|
||||||
|
object->GetPropertyWithDefinedGetter(*receiver,
|
||||||
|
JSReceiver::cast(*getter)),
|
||||||
|
Object);
|
||||||
}
|
}
|
||||||
// Getter is not a function.
|
// Getter is not a function.
|
||||||
return isolate->heap()->undefined_value();
|
return isolate->factory()->undefined_value();
|
||||||
}
|
|
||||||
|
|
||||||
UNREACHABLE();
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -507,19 +513,6 @@ MaybeObject* Object::GetPropertyWithDefinedGetter(Object* receiver,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO(yangguo): this should eventually replace the non-handlified version.
|
|
||||||
Handle<Object> JSObject::GetPropertyWithCallback(Handle<JSObject> object,
|
|
||||||
Handle<Object> receiver,
|
|
||||||
Handle<Object> structure,
|
|
||||||
Handle<Name> name) {
|
|
||||||
CALL_HEAP_FUNCTION(object->GetIsolate(),
|
|
||||||
object->GetPropertyWithCallback(*receiver,
|
|
||||||
*structure,
|
|
||||||
*name),
|
|
||||||
Object);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Only deal with CALLBACKS and INTERCEPTOR
|
// Only deal with CALLBACKS and INTERCEPTOR
|
||||||
Handle<Object> JSObject::GetPropertyWithFailedAccessCheck(
|
Handle<Object> JSObject::GetPropertyWithFailedAccessCheck(
|
||||||
Handle<JSObject> object,
|
Handle<JSObject> object,
|
||||||
@ -903,9 +896,16 @@ MaybeObject* Object::GetProperty(Object* receiver,
|
|||||||
}
|
}
|
||||||
case CONSTANT:
|
case CONSTANT:
|
||||||
return result->GetConstant();
|
return result->GetConstant();
|
||||||
case CALLBACKS:
|
case CALLBACKS: {
|
||||||
return result->holder()->GetPropertyWithCallback(
|
HandleScope scope(isolate);
|
||||||
receiver, result->GetCallbackObject(), name);
|
Handle<Object> value = JSObject::GetPropertyWithCallback(
|
||||||
|
handle(result->holder(), isolate),
|
||||||
|
handle(receiver, isolate),
|
||||||
|
handle(result->GetCallbackObject(), isolate),
|
||||||
|
handle(name, isolate));
|
||||||
|
RETURN_IF_EMPTY_HANDLE(isolate, value);
|
||||||
|
return *value;
|
||||||
|
}
|
||||||
case HANDLER:
|
case HANDLER:
|
||||||
return result->proxy()->GetPropertyWithHandler(receiver, name);
|
return result->proxy()->GetPropertyWithHandler(receiver, name);
|
||||||
case INTERCEPTOR: {
|
case INTERCEPTOR: {
|
||||||
|
@ -2127,10 +2127,6 @@ class JSObject: public JSReceiver {
|
|||||||
Handle<Object> structure,
|
Handle<Object> structure,
|
||||||
Handle<Name> name);
|
Handle<Name> name);
|
||||||
|
|
||||||
MUST_USE_RESULT MaybeObject* GetPropertyWithCallback(Object* receiver,
|
|
||||||
Object* structure,
|
|
||||||
Name* name);
|
|
||||||
|
|
||||||
static Handle<Object> SetPropertyWithCallback(
|
static Handle<Object> SetPropertyWithCallback(
|
||||||
Handle<JSObject> object,
|
Handle<JSObject> object,
|
||||||
Handle<Object> structure,
|
Handle<Object> structure,
|
||||||
|
@ -10720,19 +10720,20 @@ static MaybeObject* DebugLookupResultValue(Heap* heap,
|
|||||||
case CALLBACKS: {
|
case CALLBACKS: {
|
||||||
Object* structure = result->GetCallbackObject();
|
Object* structure = result->GetCallbackObject();
|
||||||
if (structure->IsForeign() || structure->IsAccessorInfo()) {
|
if (structure->IsForeign() || structure->IsAccessorInfo()) {
|
||||||
MaybeObject* maybe_value = result->holder()->GetPropertyWithCallback(
|
Isolate* isolate = heap->isolate();
|
||||||
receiver, structure, name);
|
HandleScope scope(isolate);
|
||||||
if (!maybe_value->ToObject(&value)) {
|
Handle<Object> value = JSObject::GetPropertyWithCallback(
|
||||||
if (maybe_value->IsRetryAfterGC()) return maybe_value;
|
handle(result->holder(), isolate),
|
||||||
ASSERT(maybe_value->IsException());
|
handle(receiver, isolate),
|
||||||
maybe_value = heap->isolate()->pending_exception();
|
handle(structure, isolate),
|
||||||
|
handle(name, isolate));
|
||||||
|
if (value.is_null()) {
|
||||||
|
MaybeObject* exception = heap->isolate()->pending_exception();
|
||||||
heap->isolate()->clear_pending_exception();
|
heap->isolate()->clear_pending_exception();
|
||||||
if (caught_exception != NULL) {
|
if (caught_exception != NULL) *caught_exception = true;
|
||||||
*caught_exception = true;
|
return exception;
|
||||||
}
|
}
|
||||||
return maybe_value;
|
return *value;
|
||||||
}
|
|
||||||
return value;
|
|
||||||
} else {
|
} else {
|
||||||
return heap->undefined_value();
|
return heap->undefined_value();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user