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,
|
||||
Object* structure,
|
||||
Name* name) {
|
||||
Handle<Object> JSObject::GetPropertyWithCallback(Handle<JSObject> object,
|
||||
Handle<Object> receiver,
|
||||
Handle<Object> structure,
|
||||
Handle<Name> name) {
|
||||
Isolate* isolate = name->GetIsolate();
|
||||
// To accommodate both the old and the new api we switch on the
|
||||
// data structure used to store the callbacks. Eventually foreign
|
||||
@ -353,66 +354,71 @@ MaybeObject* JSObject::GetPropertyWithCallback(Object* receiver,
|
||||
if (structure->IsForeign()) {
|
||||
AccessorDescriptor* callback =
|
||||
reinterpret_cast<AccessorDescriptor*>(
|
||||
Foreign::cast(structure)->foreign_address());
|
||||
MaybeObject* value = (callback->getter)(isolate, receiver, callback->data);
|
||||
RETURN_IF_SCHEDULED_EXCEPTION(isolate);
|
||||
return value;
|
||||
Handle<Foreign>::cast(structure)->foreign_address());
|
||||
CALL_HEAP_FUNCTION(isolate,
|
||||
(callback->getter)(isolate, *receiver, callback->data),
|
||||
Object);
|
||||
}
|
||||
|
||||
// api style callbacks.
|
||||
if (structure->IsAccessorInfo()) {
|
||||
if (!AccessorInfo::cast(structure)->IsCompatibleReceiver(receiver)) {
|
||||
Handle<Object> name_handle(name, isolate);
|
||||
Handle<Object> receiver_handle(receiver, isolate);
|
||||
Handle<Object> args[2] = { name_handle, receiver_handle };
|
||||
Handle<AccessorInfo> accessor_info = Handle<AccessorInfo>::cast(structure);
|
||||
if (!accessor_info->IsCompatibleReceiver(*receiver)) {
|
||||
Handle<Object> args[2] = { name, receiver };
|
||||
Handle<Object> error =
|
||||
isolate->factory()->NewTypeError("incompatible_method_receiver",
|
||||
HandleVector(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,
|
||||
// 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()) {
|
||||
return GetDeclaredAccessorProperty(receiver,
|
||||
DeclaredAccessorInfo::cast(structure),
|
||||
isolate);
|
||||
CALL_HEAP_FUNCTION(
|
||||
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::ToCData<v8::AccessorGetterCallback>(fun_obj);
|
||||
if (call_fun == NULL) return isolate->heap()->undefined_value();
|
||||
v8::ToCData<v8::AccessorGetterCallback>(data->getter());
|
||||
if (call_fun == NULL) return isolate->factory()->undefined_value();
|
||||
|
||||
HandleScope scope(isolate);
|
||||
JSObject* self = JSObject::cast(receiver);
|
||||
Handle<String> key(String::cast(name));
|
||||
LOG(isolate, ApiNamedPropertyAccess("load", self, name));
|
||||
PropertyCallbackArguments args(isolate, data->data(), self, this);
|
||||
Handle<JSObject> self = Handle<JSObject>::cast(receiver);
|
||||
Handle<String> key = Handle<String>::cast(name);
|
||||
LOG(isolate, ApiNamedPropertyAccess("load", *self, *name));
|
||||
PropertyCallbackArguments args(isolate, data->data(), *self, *object);
|
||||
v8::Handle<v8::Value> result =
|
||||
args.Call(call_fun, v8::Utils::ToLocal(key));
|
||||
RETURN_IF_SCHEDULED_EXCEPTION(isolate);
|
||||
RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
|
||||
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 return_value;
|
||||
return scope.CloseAndEscape(return_value);
|
||||
}
|
||||
|
||||
// __defineGetter__ callback
|
||||
if (structure->IsAccessorPair()) {
|
||||
Object* getter = AccessorPair::cast(structure)->getter();
|
||||
Handle<Object> getter(Handle<AccessorPair>::cast(structure)->getter(),
|
||||
isolate);
|
||||
if (getter->IsSpecFunction()) {
|
||||
// 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.
|
||||
return isolate->heap()->undefined_value();
|
||||
}
|
||||
|
||||
UNREACHABLE();
|
||||
return NULL;
|
||||
return isolate->factory()->undefined_value();
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
Handle<Object> JSObject::GetPropertyWithFailedAccessCheck(
|
||||
Handle<JSObject> object,
|
||||
@ -903,9 +896,16 @@ MaybeObject* Object::GetProperty(Object* receiver,
|
||||
}
|
||||
case CONSTANT:
|
||||
return result->GetConstant();
|
||||
case CALLBACKS:
|
||||
return result->holder()->GetPropertyWithCallback(
|
||||
receiver, result->GetCallbackObject(), name);
|
||||
case CALLBACKS: {
|
||||
HandleScope scope(isolate);
|
||||
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:
|
||||
return result->proxy()->GetPropertyWithHandler(receiver, name);
|
||||
case INTERCEPTOR: {
|
||||
|
@ -2127,10 +2127,6 @@ class JSObject: public JSReceiver {
|
||||
Handle<Object> structure,
|
||||
Handle<Name> name);
|
||||
|
||||
MUST_USE_RESULT MaybeObject* GetPropertyWithCallback(Object* receiver,
|
||||
Object* structure,
|
||||
Name* name);
|
||||
|
||||
static Handle<Object> SetPropertyWithCallback(
|
||||
Handle<JSObject> object,
|
||||
Handle<Object> structure,
|
||||
|
@ -10720,19 +10720,20 @@ static MaybeObject* DebugLookupResultValue(Heap* heap,
|
||||
case CALLBACKS: {
|
||||
Object* structure = result->GetCallbackObject();
|
||||
if (structure->IsForeign() || structure->IsAccessorInfo()) {
|
||||
MaybeObject* maybe_value = result->holder()->GetPropertyWithCallback(
|
||||
receiver, structure, name);
|
||||
if (!maybe_value->ToObject(&value)) {
|
||||
if (maybe_value->IsRetryAfterGC()) return maybe_value;
|
||||
ASSERT(maybe_value->IsException());
|
||||
maybe_value = heap->isolate()->pending_exception();
|
||||
Isolate* isolate = heap->isolate();
|
||||
HandleScope scope(isolate);
|
||||
Handle<Object> value = JSObject::GetPropertyWithCallback(
|
||||
handle(result->holder(), isolate),
|
||||
handle(receiver, isolate),
|
||||
handle(structure, isolate),
|
||||
handle(name, isolate));
|
||||
if (value.is_null()) {
|
||||
MaybeObject* exception = heap->isolate()->pending_exception();
|
||||
heap->isolate()->clear_pending_exception();
|
||||
if (caught_exception != NULL) {
|
||||
*caught_exception = true;
|
||||
if (caught_exception != NULL) *caught_exception = true;
|
||||
return exception;
|
||||
}
|
||||
return maybe_value;
|
||||
}
|
||||
return value;
|
||||
return *value;
|
||||
} else {
|
||||
return heap->undefined_value();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user