Cleanup GetPropertyWithCallback / SetPropertyWithCallback API
BUG= R=ishell@chromium.org Review URL: https://codereview.chromium.org/305513004 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@21555 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
52cfd35fb2
commit
6b712555dd
245
src/objects.cc
245
src/objects.cc
@ -361,10 +361,24 @@ Handle<FixedArray> JSObject::EnsureWritableFastElements(
|
||||
}
|
||||
|
||||
|
||||
MaybeHandle<Object> JSObject::GetPropertyWithCallback(Handle<JSObject> object,
|
||||
Handle<Object> receiver,
|
||||
Handle<Object> structure,
|
||||
Handle<Name> name) {
|
||||
MaybeHandle<Object> JSProxy::GetPropertyWithHandler(Handle<JSProxy> proxy,
|
||||
Handle<Object> receiver,
|
||||
Handle<Name> name) {
|
||||
Isolate* isolate = proxy->GetIsolate();
|
||||
|
||||
// TODO(rossberg): adjust once there is a story for symbols vs proxies.
|
||||
if (name->IsSymbol()) return isolate->factory()->undefined_value();
|
||||
|
||||
Handle<Object> args[] = { receiver, name };
|
||||
return CallTrap(
|
||||
proxy, "get", isolate->derived_get_trap(), ARRAY_SIZE(args), args);
|
||||
}
|
||||
|
||||
|
||||
MaybeHandle<Object> Object::GetPropertyWithCallback(Handle<Object> receiver,
|
||||
Handle<Name> name,
|
||||
Handle<JSObject> holder,
|
||||
Handle<Object> structure) {
|
||||
Isolate* isolate = name->GetIsolate();
|
||||
ASSERT(!structure->IsForeign());
|
||||
// api style callbacks.
|
||||
@ -395,8 +409,8 @@ MaybeHandle<Object> JSObject::GetPropertyWithCallback(Handle<JSObject> object,
|
||||
if (call_fun == NULL) return isolate->factory()->undefined_value();
|
||||
|
||||
Handle<String> key = Handle<String>::cast(name);
|
||||
LOG(isolate, ApiNamedPropertyAccess("load", *object, *name));
|
||||
PropertyCallbackArguments args(isolate, data->data(), *receiver, *object);
|
||||
LOG(isolate, ApiNamedPropertyAccess("load", *holder, *name));
|
||||
PropertyCallbackArguments args(isolate, data->data(), *receiver, *holder);
|
||||
v8::Handle<v8::Value> result =
|
||||
args.Call(call_fun, v8::Utils::ToLocal(key));
|
||||
RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
|
||||
@ -415,29 +429,79 @@ MaybeHandle<Object> JSObject::GetPropertyWithCallback(Handle<JSObject> object,
|
||||
if (getter->IsSpecFunction()) {
|
||||
// TODO(rossberg): nicer would be to cast to some JSCallable here...
|
||||
return Object::GetPropertyWithDefinedGetter(
|
||||
object, receiver, Handle<JSReceiver>::cast(getter));
|
||||
receiver, Handle<JSReceiver>::cast(getter));
|
||||
}
|
||||
// Getter is not a function.
|
||||
return isolate->factory()->undefined_value();
|
||||
}
|
||||
|
||||
|
||||
MaybeHandle<Object> JSProxy::GetPropertyWithHandler(Handle<JSProxy> proxy,
|
||||
Handle<Object> receiver,
|
||||
Handle<Name> name) {
|
||||
Isolate* isolate = proxy->GetIsolate();
|
||||
MaybeHandle<Object> Object::SetPropertyWithCallback(Handle<Object> receiver,
|
||||
Handle<Name> name,
|
||||
Handle<Object> value,
|
||||
Handle<JSObject> holder,
|
||||
Handle<Object> structure,
|
||||
StrictMode strict_mode) {
|
||||
Isolate* isolate = name->GetIsolate();
|
||||
|
||||
// TODO(rossberg): adjust once there is a story for symbols vs proxies.
|
||||
if (name->IsSymbol()) return isolate->factory()->undefined_value();
|
||||
// We should never get here to initialize a const with the hole
|
||||
// value since a const declaration would conflict with the setter.
|
||||
ASSERT(!value->IsTheHole());
|
||||
ASSERT(!structure->IsForeign());
|
||||
if (structure->IsExecutableAccessorInfo()) {
|
||||
// api style callbacks
|
||||
ExecutableAccessorInfo* data = ExecutableAccessorInfo::cast(*structure);
|
||||
if (!data->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<Object>(error);
|
||||
}
|
||||
// TODO(rossberg): Support symbols in the API.
|
||||
if (name->IsSymbol()) return value;
|
||||
Object* call_obj = data->setter();
|
||||
v8::AccessorSetterCallback call_fun =
|
||||
v8::ToCData<v8::AccessorSetterCallback>(call_obj);
|
||||
if (call_fun == NULL) return value;
|
||||
Handle<String> key = Handle<String>::cast(name);
|
||||
LOG(isolate, ApiNamedPropertyAccess("store", *holder, *name));
|
||||
PropertyCallbackArguments args(isolate, data->data(), *receiver, *holder);
|
||||
args.Call(call_fun,
|
||||
v8::Utils::ToLocal(key),
|
||||
v8::Utils::ToLocal(value));
|
||||
RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
|
||||
return value;
|
||||
}
|
||||
|
||||
Handle<Object> args[] = { receiver, name };
|
||||
return CallTrap(
|
||||
proxy, "get", isolate->derived_get_trap(), ARRAY_SIZE(args), args);
|
||||
if (structure->IsAccessorPair()) {
|
||||
Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate);
|
||||
if (setter->IsSpecFunction()) {
|
||||
// TODO(rossberg): nicer would be to cast to some JSCallable here...
|
||||
return SetPropertyWithDefinedSetter(
|
||||
receiver, Handle<JSReceiver>::cast(setter), value);
|
||||
} else {
|
||||
if (strict_mode == SLOPPY) return value;
|
||||
Handle<Object> args[2] = { name, holder };
|
||||
Handle<Object> error =
|
||||
isolate->factory()->NewTypeError("no_setter_in_callback",
|
||||
HandleVector(args, 2));
|
||||
return isolate->Throw<Object>(error);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(dcarney): Handle correctly.
|
||||
if (structure->IsDeclaredAccessorInfo()) {
|
||||
return value;
|
||||
}
|
||||
|
||||
UNREACHABLE();
|
||||
return MaybeHandle<Object>();
|
||||
}
|
||||
|
||||
|
||||
MaybeHandle<Object> Object::GetPropertyWithDefinedGetter(
|
||||
Handle<Object> object,
|
||||
Handle<Object> receiver,
|
||||
Handle<JSReceiver> getter) {
|
||||
Isolate* isolate = getter->GetIsolate();
|
||||
@ -453,6 +517,29 @@ MaybeHandle<Object> Object::GetPropertyWithDefinedGetter(
|
||||
}
|
||||
|
||||
|
||||
MaybeHandle<Object> Object::SetPropertyWithDefinedSetter(
|
||||
Handle<Object> receiver,
|
||||
Handle<JSReceiver> setter,
|
||||
Handle<Object> value) {
|
||||
Isolate* isolate = setter->GetIsolate();
|
||||
|
||||
Debug* debug = isolate->debug();
|
||||
// Handle stepping into a setter if step into is active.
|
||||
// TODO(rossberg): should this apply to getters that are function proxies?
|
||||
if (debug->StepInActive() && setter->IsJSFunction()) {
|
||||
debug->HandleStepIn(
|
||||
Handle<JSFunction>::cast(setter), Handle<Object>::null(), 0, false);
|
||||
}
|
||||
|
||||
Handle<Object> argv[] = { value };
|
||||
RETURN_ON_EXCEPTION(
|
||||
isolate,
|
||||
Execution::Call(isolate, setter, receiver, ARRAY_SIZE(argv), argv),
|
||||
Object);
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
// Only deal with CALLBACKS and INTERCEPTOR
|
||||
MaybeHandle<Object> JSObject::GetPropertyWithFailedAccessCheck(
|
||||
Handle<JSObject> object,
|
||||
@ -477,7 +564,7 @@ MaybeHandle<Object> JSObject::GetPropertyWithFailedAccessCheck(
|
||||
break;
|
||||
}
|
||||
Handle<JSObject> holder(result->holder(), isolate);
|
||||
return GetPropertyWithCallback(holder, receiver, callback_obj, name);
|
||||
return GetPropertyWithCallback(receiver, name, holder, callback_obj);
|
||||
}
|
||||
case NORMAL:
|
||||
case FIELD:
|
||||
@ -791,11 +878,9 @@ MaybeHandle<Object> Object::GetProperty(Handle<Object> object,
|
||||
case CONSTANT:
|
||||
return handle(result->GetConstant(), isolate);
|
||||
case CALLBACKS:
|
||||
return JSObject::GetPropertyWithCallback(
|
||||
handle(result->holder(), isolate),
|
||||
receiver,
|
||||
handle(result->GetCallbackObject(), isolate),
|
||||
name);
|
||||
return GetPropertyWithCallback(
|
||||
receiver, name, handle(result->holder(), isolate),
|
||||
handle(result->GetCallbackObject(), isolate));
|
||||
case HANDLER:
|
||||
return JSProxy::GetPropertyWithHandler(
|
||||
handle(result->proxy(), isolate), receiver, name);
|
||||
@ -3005,94 +3090,6 @@ MaybeHandle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object,
|
||||
}
|
||||
|
||||
|
||||
MaybeHandle<Object> JSObject::SetPropertyWithCallback(Handle<JSObject> object,
|
||||
Handle<Object> structure,
|
||||
Handle<Name> name,
|
||||
Handle<Object> value,
|
||||
Handle<JSObject> holder,
|
||||
StrictMode strict_mode) {
|
||||
Isolate* isolate = object->GetIsolate();
|
||||
|
||||
// We should never get here to initialize a const with the hole
|
||||
// value since a const declaration would conflict with the setter.
|
||||
ASSERT(!value->IsTheHole());
|
||||
ASSERT(!structure->IsForeign());
|
||||
if (structure->IsExecutableAccessorInfo()) {
|
||||
// api style callbacks
|
||||
ExecutableAccessorInfo* data = ExecutableAccessorInfo::cast(*structure);
|
||||
if (!data->IsCompatibleReceiver(*object)) {
|
||||
Handle<Object> args[2] = { name, object };
|
||||
Handle<Object> error =
|
||||
isolate->factory()->NewTypeError("incompatible_method_receiver",
|
||||
HandleVector(args,
|
||||
ARRAY_SIZE(args)));
|
||||
return isolate->Throw<Object>(error);
|
||||
}
|
||||
// TODO(rossberg): Support symbols in the API.
|
||||
if (name->IsSymbol()) return value;
|
||||
Object* call_obj = data->setter();
|
||||
v8::AccessorSetterCallback call_fun =
|
||||
v8::ToCData<v8::AccessorSetterCallback>(call_obj);
|
||||
if (call_fun == NULL) return value;
|
||||
Handle<String> key = Handle<String>::cast(name);
|
||||
LOG(isolate, ApiNamedPropertyAccess("store", *object, *name));
|
||||
PropertyCallbackArguments args(isolate, data->data(), *object, *holder);
|
||||
args.Call(call_fun,
|
||||
v8::Utils::ToLocal(key),
|
||||
v8::Utils::ToLocal(value));
|
||||
RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
|
||||
return value;
|
||||
}
|
||||
|
||||
if (structure->IsAccessorPair()) {
|
||||
Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate);
|
||||
if (setter->IsSpecFunction()) {
|
||||
// TODO(rossberg): nicer would be to cast to some JSCallable here...
|
||||
return SetPropertyWithDefinedSetter(
|
||||
object, Handle<JSReceiver>::cast(setter), value);
|
||||
} else {
|
||||
if (strict_mode == SLOPPY) return value;
|
||||
Handle<Object> args[2] = { name, holder };
|
||||
Handle<Object> error =
|
||||
isolate->factory()->NewTypeError("no_setter_in_callback",
|
||||
HandleVector(args, 2));
|
||||
return isolate->Throw<Object>(error);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(dcarney): Handle correctly.
|
||||
if (structure->IsDeclaredAccessorInfo()) {
|
||||
return value;
|
||||
}
|
||||
|
||||
UNREACHABLE();
|
||||
return MaybeHandle<Object>();
|
||||
}
|
||||
|
||||
|
||||
MaybeHandle<Object> JSReceiver::SetPropertyWithDefinedSetter(
|
||||
Handle<JSReceiver> object,
|
||||
Handle<JSReceiver> setter,
|
||||
Handle<Object> value) {
|
||||
Isolate* isolate = object->GetIsolate();
|
||||
|
||||
Debug* debug = isolate->debug();
|
||||
// Handle stepping into a setter if step into is active.
|
||||
// TODO(rossberg): should this apply to getters that are function proxies?
|
||||
if (debug->StepInActive() && setter->IsJSFunction()) {
|
||||
debug->HandleStepIn(
|
||||
Handle<JSFunction>::cast(setter), Handle<Object>::null(), 0, false);
|
||||
}
|
||||
|
||||
Handle<Object> argv[] = { value };
|
||||
RETURN_ON_EXCEPTION(
|
||||
isolate,
|
||||
Execution::Call(isolate, setter, object, ARRAY_SIZE(argv), argv),
|
||||
Object);
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
MaybeHandle<Object> JSObject::SetElementWithCallbackSetterInPrototypes(
|
||||
Handle<JSObject> object,
|
||||
uint32_t index,
|
||||
@ -3166,8 +3163,9 @@ MaybeHandle<Object> JSObject::SetPropertyViaPrototypes(
|
||||
*done = true;
|
||||
if (!result.IsReadOnly()) {
|
||||
Handle<Object> callback_object(result.GetCallbackObject(), isolate);
|
||||
return SetPropertyWithCallback(object, callback_object, name, value,
|
||||
handle(result.holder()), strict_mode);
|
||||
return SetPropertyWithCallback(object, name, value,
|
||||
handle(result.holder()),
|
||||
callback_object, strict_mode);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -3625,22 +3623,16 @@ MaybeHandle<Object> JSObject::SetPropertyWithFailedAccessCheck(
|
||||
if (obj->IsAccessorInfo()) {
|
||||
Handle<AccessorInfo> info(AccessorInfo::cast(obj));
|
||||
if (info->all_can_write()) {
|
||||
return SetPropertyWithCallback(object,
|
||||
info,
|
||||
name,
|
||||
value,
|
||||
return SetPropertyWithCallback(object, name, value,
|
||||
handle(result->holder()),
|
||||
strict_mode);
|
||||
info, strict_mode);
|
||||
}
|
||||
} else if (obj->IsAccessorPair()) {
|
||||
Handle<AccessorPair> pair(AccessorPair::cast(obj));
|
||||
if (pair->all_can_read()) {
|
||||
return SetPropertyWithCallback(object,
|
||||
pair,
|
||||
name,
|
||||
value,
|
||||
return SetPropertyWithCallback(object, name, value,
|
||||
handle(result->holder()),
|
||||
strict_mode);
|
||||
pair, strict_mode);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -4300,8 +4292,9 @@ MaybeHandle<Object> JSObject::SetPropertyForResult(
|
||||
break;
|
||||
case CALLBACKS: {
|
||||
Handle<Object> callback_object(lookup->GetCallbackObject(), isolate);
|
||||
return SetPropertyWithCallback(object, callback_object, name, value,
|
||||
handle(lookup->holder()), strict_mode);
|
||||
return SetPropertyWithCallback(object, name, value,
|
||||
handle(lookup->holder()),
|
||||
callback_object, strict_mode);
|
||||
}
|
||||
case INTERCEPTOR:
|
||||
maybe_result = SetPropertyWithInterceptor(
|
||||
@ -12581,7 +12574,7 @@ MaybeHandle<Object> JSObject::GetElementWithCallback(
|
||||
if (getter->IsSpecFunction()) {
|
||||
// TODO(rossberg): nicer would be to cast to some JSCallable here...
|
||||
return GetPropertyWithDefinedGetter(
|
||||
object, receiver, Handle<JSReceiver>::cast(getter));
|
||||
receiver, Handle<JSReceiver>::cast(getter));
|
||||
}
|
||||
// Getter is not a function.
|
||||
return isolate->factory()->undefined_value();
|
||||
|
@ -1477,10 +1477,26 @@ class Object {
|
||||
Handle<Name> key,
|
||||
PropertyAttributes* attributes);
|
||||
|
||||
MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithCallback(
|
||||
Handle<Object> receiver,
|
||||
Handle<Name> name,
|
||||
Handle<JSObject> holder,
|
||||
Handle<Object> structure);
|
||||
MUST_USE_RESULT static MaybeHandle<Object> SetPropertyWithCallback(
|
||||
Handle<Object> receiver,
|
||||
Handle<Name> name,
|
||||
Handle<Object> value,
|
||||
Handle<JSObject> holder,
|
||||
Handle<Object> structure,
|
||||
StrictMode strict_mode);
|
||||
|
||||
MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithDefinedGetter(
|
||||
Handle<Object> object,
|
||||
Handle<Object> receiver,
|
||||
Handle<JSReceiver> getter);
|
||||
MUST_USE_RESULT static MaybeHandle<Object> SetPropertyWithDefinedSetter(
|
||||
Handle<Object> receiver,
|
||||
Handle<JSReceiver> setter,
|
||||
Handle<Object> value);
|
||||
|
||||
MUST_USE_RESULT static inline MaybeHandle<Object> GetElement(
|
||||
Isolate* isolate,
|
||||
@ -1994,12 +2010,6 @@ class JSReceiver: public HeapObject {
|
||||
Handle<JSReceiver> object,
|
||||
KeyCollectionType type);
|
||||
|
||||
protected:
|
||||
MUST_USE_RESULT static MaybeHandle<Object> SetPropertyWithDefinedSetter(
|
||||
Handle<JSReceiver> object,
|
||||
Handle<JSReceiver> setter,
|
||||
Handle<Object> value);
|
||||
|
||||
private:
|
||||
static PropertyAttributes GetPropertyAttributeForResult(
|
||||
Handle<JSReceiver> object,
|
||||
@ -2128,20 +2138,6 @@ class JSObject: public JSReceiver {
|
||||
static Handle<Object> PrepareSlowElementsForSort(Handle<JSObject> object,
|
||||
uint32_t limit);
|
||||
|
||||
MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithCallback(
|
||||
Handle<JSObject> object,
|
||||
Handle<Object> receiver,
|
||||
Handle<Object> structure,
|
||||
Handle<Name> name);
|
||||
|
||||
MUST_USE_RESULT static MaybeHandle<Object> SetPropertyWithCallback(
|
||||
Handle<JSObject> object,
|
||||
Handle<Object> structure,
|
||||
Handle<Name> name,
|
||||
Handle<Object> value,
|
||||
Handle<JSObject> holder,
|
||||
StrictMode strict_mode);
|
||||
|
||||
MUST_USE_RESULT static MaybeHandle<Object> SetPropertyWithInterceptor(
|
||||
Handle<JSObject> object,
|
||||
Handle<Name> name,
|
||||
|
@ -5188,12 +5188,9 @@ RUNTIME_FUNCTION(Runtime_DefineOrRedefineDataProperty) {
|
||||
Handle<Object> result_object;
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
||||
isolate, result_object,
|
||||
JSObject::SetPropertyWithCallback(js_object,
|
||||
callback,
|
||||
name,
|
||||
obj_value,
|
||||
JSObject::SetPropertyWithCallback(js_object, name, obj_value,
|
||||
handle(lookup.holder()),
|
||||
STRICT));
|
||||
callback, STRICT));
|
||||
return *result_object;
|
||||
}
|
||||
}
|
||||
@ -10789,7 +10786,7 @@ static Handle<Object> DebugLookupResultValue(Isolate* isolate,
|
||||
ASSERT(!structure->IsForeign());
|
||||
if (structure->IsAccessorInfo()) {
|
||||
MaybeHandle<Object> obj = JSObject::GetPropertyWithCallback(
|
||||
handle(result->holder(), isolate), receiver, structure, name);
|
||||
receiver, name, handle(result->holder(), isolate), structure);
|
||||
if (!obj.ToHandle(&value)) {
|
||||
value = handle(isolate->pending_exception(), isolate);
|
||||
isolate->clear_pending_exception();
|
||||
|
Loading…
Reference in New Issue
Block a user