Fix stub-invoked setter callback handling.
When invoking a setter callback for a property using JSObject::SetPropertyWithCallback(),the callback arguments includes a correct pair of receiver and holder objects. Such a pair of _possibly different_ arguments (receiver, holder) must also be supplied when invoking the same setter callback from JITed code, when the setter is invoked through the StoreCallbackProperty stub. An example where this matters are the accessor properties kept on the global scope of Worker (i.e., properties kept on the global object itself, and not on its prototype.) Conflating the receiver with the holder leads to general confusion when attempting to fetch out the wrapper object. LOG=N R=dcarney@chromium.org, dcarney BUG=239669 Review URL: https://codereview.chromium.org/139263008 Patch from Sigbjorn Finne <sigbjornf@opera.com>. git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18658 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
0575396a4c
commit
7cee52948f
@ -2518,13 +2518,14 @@ Handle<Code> StoreStubCompiler::CompileStoreCallback(
|
||||
Handle<JSObject> holder,
|
||||
Handle<Name> name,
|
||||
Handle<ExecutableAccessorInfo> callback) {
|
||||
HandlerFrontend(IC::CurrentTypeOf(object, isolate()),
|
||||
receiver(), holder, name);
|
||||
Register holder_reg = HandlerFrontend(
|
||||
IC::CurrentTypeOf(object, isolate()), receiver(), holder, name);
|
||||
|
||||
// Stub never generated for non-global objects that require access checks.
|
||||
ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
|
||||
|
||||
__ push(receiver()); // receiver
|
||||
__ push(holder_reg);
|
||||
__ mov(ip, Operand(callback)); // callback info
|
||||
__ push(ip);
|
||||
__ mov(ip, Operand(name));
|
||||
@ -2533,7 +2534,7 @@ Handle<Code> StoreStubCompiler::CompileStoreCallback(
|
||||
// Do tail-call to the runtime system.
|
||||
ExternalReference store_callback_property =
|
||||
ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate());
|
||||
__ TailCallExternalReference(store_callback_property, 4, 1);
|
||||
__ TailCallExternalReference(store_callback_property, 5, 1);
|
||||
|
||||
// Return the generated code.
|
||||
return GetCode(kind(), Code::FAST, name);
|
||||
|
@ -2638,11 +2638,12 @@ Handle<Code> StoreStubCompiler::CompileStoreCallback(
|
||||
Handle<JSObject> holder,
|
||||
Handle<Name> name,
|
||||
Handle<ExecutableAccessorInfo> callback) {
|
||||
HandlerFrontend(IC::CurrentTypeOf(object, isolate()),
|
||||
receiver(), holder, name);
|
||||
Register holder_reg = HandlerFrontend(
|
||||
IC::CurrentTypeOf(object, isolate()), receiver(), holder, name);
|
||||
|
||||
__ pop(scratch1()); // remove the return address
|
||||
__ push(receiver());
|
||||
__ push(holder_reg);
|
||||
__ Push(callback);
|
||||
__ Push(name);
|
||||
__ push(value());
|
||||
@ -2651,7 +2652,7 @@ Handle<Code> StoreStubCompiler::CompileStoreCallback(
|
||||
// Do tail-call to the runtime system.
|
||||
ExternalReference store_callback_property =
|
||||
ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate());
|
||||
__ TailCallExternalReference(store_callback_property, 4, 1);
|
||||
__ TailCallExternalReference(store_callback_property, 5, 1);
|
||||
|
||||
// Return the generated code.
|
||||
return GetCode(kind(), Code::FAST, name);
|
||||
|
@ -2514,14 +2514,15 @@ Handle<Code> StoreStubCompiler::CompileStoreCallback(
|
||||
Handle<JSObject> holder,
|
||||
Handle<Name> name,
|
||||
Handle<ExecutableAccessorInfo> callback) {
|
||||
HandlerFrontend(IC::CurrentTypeOf(object, isolate()),
|
||||
receiver(), holder, name);
|
||||
Register holder_reg = HandlerFrontend(
|
||||
IC::CurrentTypeOf(object, isolate()), receiver(), holder, name);
|
||||
|
||||
// Stub never generated for non-global objects that require access
|
||||
// checks.
|
||||
ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
|
||||
|
||||
__ push(receiver()); // Receiver.
|
||||
__ push(holder_reg);
|
||||
__ li(at, Operand(callback)); // Callback info.
|
||||
__ push(at);
|
||||
__ li(at, Operand(name));
|
||||
@ -2530,7 +2531,7 @@ Handle<Code> StoreStubCompiler::CompileStoreCallback(
|
||||
// Do tail-call to the runtime system.
|
||||
ExternalReference store_callback_property =
|
||||
ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate());
|
||||
__ TailCallExternalReference(store_callback_property, 4, 1);
|
||||
__ TailCallExternalReference(store_callback_property, 5, 1);
|
||||
|
||||
// Return the generated code.
|
||||
return GetCode(kind(), Code::FAST, name);
|
||||
|
@ -810,24 +810,25 @@ void StubCache::CollectMatchingMaps(SmallMapList* types,
|
||||
|
||||
|
||||
RUNTIME_FUNCTION(MaybeObject*, StoreCallbackProperty) {
|
||||
JSObject* recv = JSObject::cast(args[0]);
|
||||
ExecutableAccessorInfo* callback = ExecutableAccessorInfo::cast(args[1]);
|
||||
JSObject* receiver = JSObject::cast(args[0]);
|
||||
JSObject* holder = JSObject::cast(args[1]);
|
||||
ExecutableAccessorInfo* callback = ExecutableAccessorInfo::cast(args[2]);
|
||||
Address setter_address = v8::ToCData<Address>(callback->setter());
|
||||
v8::AccessorSetterCallback fun =
|
||||
FUNCTION_CAST<v8::AccessorSetterCallback>(setter_address);
|
||||
ASSERT(fun != NULL);
|
||||
ASSERT(callback->IsCompatibleReceiver(recv));
|
||||
Handle<Name> name = args.at<Name>(2);
|
||||
Handle<Object> value = args.at<Object>(3);
|
||||
ASSERT(callback->IsCompatibleReceiver(receiver));
|
||||
Handle<Name> name = args.at<Name>(3);
|
||||
Handle<Object> value = args.at<Object>(4);
|
||||
HandleScope scope(isolate);
|
||||
|
||||
// TODO(rossberg): Support symbols in the API.
|
||||
if (name->IsSymbol()) return *value;
|
||||
Handle<String> str = Handle<String>::cast(name);
|
||||
|
||||
LOG(isolate, ApiNamedPropertyAccess("store", recv, *name));
|
||||
LOG(isolate, ApiNamedPropertyAccess("store", receiver, *name));
|
||||
PropertyCallbackArguments
|
||||
custom_args(isolate, callback->data(), recv, recv);
|
||||
custom_args(isolate, callback->data(), receiver, holder);
|
||||
custom_args.Call(fun, v8::Utils::ToLocal(str), v8::Utils::ToLocal(value));
|
||||
RETURN_IF_SCHEDULED_EXCEPTION(isolate);
|
||||
return *value;
|
||||
|
@ -2542,11 +2542,12 @@ Handle<Code> StoreStubCompiler::CompileStoreCallback(
|
||||
Handle<JSObject> holder,
|
||||
Handle<Name> name,
|
||||
Handle<ExecutableAccessorInfo> callback) {
|
||||
HandlerFrontend(IC::CurrentTypeOf(object, isolate()),
|
||||
receiver(), holder, name);
|
||||
Register holder_reg = HandlerFrontend(
|
||||
IC::CurrentTypeOf(object, isolate()), receiver(), holder, name);
|
||||
|
||||
__ PopReturnAddressTo(scratch1());
|
||||
__ push(receiver());
|
||||
__ push(holder_reg);
|
||||
__ Push(callback); // callback info
|
||||
__ Push(name);
|
||||
__ push(value());
|
||||
@ -2555,7 +2556,7 @@ Handle<Code> StoreStubCompiler::CompileStoreCallback(
|
||||
// Do tail-call to the runtime system.
|
||||
ExternalReference store_callback_property =
|
||||
ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate());
|
||||
__ TailCallExternalReference(store_callback_property, 4, 1);
|
||||
__ TailCallExternalReference(store_callback_property, 5, 1);
|
||||
|
||||
// Return the generated code.
|
||||
return GetCode(kind(), Code::FAST, name);
|
||||
|
@ -21735,3 +21735,27 @@ TEST(EscapeableHandleScope) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void SetterWhichExpectsThisAndHolderToDiffer(
|
||||
Local<String>, Local<Value>, const v8::PropertyCallbackInfo<void>& info) {
|
||||
CHECK(info.Holder() != info.This());
|
||||
}
|
||||
|
||||
|
||||
TEST(Regress239669) {
|
||||
LocalContext context;
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
v8::HandleScope scope(isolate);
|
||||
Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
|
||||
templ->SetAccessor(v8_str("x"), 0, SetterWhichExpectsThisAndHolderToDiffer);
|
||||
context->Global()->Set(v8_str("P"), templ->NewInstance());
|
||||
CompileRun(
|
||||
"function C1() {"
|
||||
" this.x = 23;"
|
||||
"};"
|
||||
"C1.prototype = P;"
|
||||
"for (var i = 0; i < 4; i++ ) {"
|
||||
" new C1();"
|
||||
"}");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user