Commit 127d6781 authored by jochen's avatar jochen Committed by Commit bot

Convert primitive receivers for API property callbacks

They're always in sloppy mode, so always do the conversion

BUG=chromium:609134
R=bmeurer@chromium.org,verwaest@chromium.org
LOG=n

Review-Url: https://codereview.chromium.org/1960663002
Cr-Commit-Position: refs/heads/master@{#36084}
parent c2c2d8e6
...@@ -32,6 +32,7 @@ Handle<AccessorInfo> Accessors::MakeAccessor( ...@@ -32,6 +32,7 @@ Handle<AccessorInfo> Accessors::MakeAccessor(
info->set_all_can_read(false); info->set_all_can_read(false);
info->set_all_can_write(false); info->set_all_can_write(false);
info->set_is_special_data_property(true); info->set_is_special_data_property(true);
info->set_is_sloppy(false);
name = factory->InternalizeName(name); name = factory->InternalizeName(name);
info->set_name(*name); info->set_name(*name);
Handle<Object> get = v8::FromCData(isolate, getter); Handle<Object> get = v8::FromCData(isolate, getter);
......
...@@ -1496,6 +1496,9 @@ class LoadApiGetterStub : public TurboFanCodeStub { ...@@ -1496,6 +1496,9 @@ class LoadApiGetterStub : public TurboFanCodeStub {
public: public:
LoadApiGetterStub(Isolate* isolate, bool receiver_is_holder, int index) LoadApiGetterStub(Isolate* isolate, bool receiver_is_holder, int index)
: TurboFanCodeStub(isolate) { : TurboFanCodeStub(isolate) {
// If that's not true, we need to ensure that the receiver is actually a
// JSReceiver. http://crbug.com/609134
DCHECK(receiver_is_holder);
minor_key_ = IndexBits::encode(index) | minor_key_ = IndexBits::encode(index) |
ReceiverIsHolderBits::encode(receiver_is_holder); ReceiverIsHolderBits::encode(receiver_is_holder);
} }
......
...@@ -866,6 +866,7 @@ Handle<AccessorInfo> Factory::NewAccessorInfo() { ...@@ -866,6 +866,7 @@ Handle<AccessorInfo> Factory::NewAccessorInfo() {
Handle<AccessorInfo> info = Handle<AccessorInfo> info =
Handle<AccessorInfo>::cast(NewStruct(ACCESSOR_INFO_TYPE)); Handle<AccessorInfo>::cast(NewStruct(ACCESSOR_INFO_TYPE));
info->set_flag(0); // Must clear the flag, it was initialized as undefined. info->set_flag(0); // Must clear the flag, it was initialized as undefined.
info->set_is_sloppy(true);
return info; return info;
} }
......
...@@ -7218,6 +7218,11 @@ void AccessorInfo::set_is_special_data_property(bool value) { ...@@ -7218,6 +7218,11 @@ void AccessorInfo::set_is_special_data_property(bool value) {
set_flag(BooleanBit::set(flag(), kSpecialDataProperty, value)); set_flag(BooleanBit::set(flag(), kSpecialDataProperty, value));
} }
bool AccessorInfo::is_sloppy() { return BooleanBit::get(flag(), kIsSloppy); }
void AccessorInfo::set_is_sloppy(bool value) {
set_flag(BooleanBit::set(flag(), kIsSloppy, value));
}
PropertyAttributes AccessorInfo::property_attributes() { PropertyAttributes AccessorInfo::property_attributes() {
return AttributesField::decode(static_cast<uint32_t>(flag())); return AttributesField::decode(static_cast<uint32_t>(flag()));
......
...@@ -1070,6 +1070,12 @@ MaybeHandle<Object> Object::GetPropertyWithAccessor(LookupIterator* it) { ...@@ -1070,6 +1070,12 @@ MaybeHandle<Object> Object::GetPropertyWithAccessor(LookupIterator* it) {
v8::ToCData<v8::AccessorNameGetterCallback>(info->getter()); v8::ToCData<v8::AccessorNameGetterCallback>(info->getter());
if (call_fun == nullptr) return isolate->factory()->undefined_value(); if (call_fun == nullptr) return isolate->factory()->undefined_value();
if (info->is_sloppy() && !receiver->IsJSReceiver()) {
ASSIGN_RETURN_ON_EXCEPTION(isolate, receiver,
Object::ConvertReceiver(isolate, receiver),
Object);
}
PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder, PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder,
Object::DONT_THROW); Object::DONT_THROW);
Handle<Object> result = args.Call(call_fun, name); Handle<Object> result = args.Call(call_fun, name);
...@@ -1154,6 +1160,12 @@ Maybe<bool> Object::SetPropertyWithAccessor(LookupIterator* it, ...@@ -1154,6 +1160,12 @@ Maybe<bool> Object::SetPropertyWithAccessor(LookupIterator* it,
// have a setter. // have a setter.
if (call_fun == nullptr) return Just(true); if (call_fun == nullptr) return Just(true);
if (info->is_sloppy() && !receiver->IsJSReceiver()) {
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
isolate, receiver, Object::ConvertReceiver(isolate, receiver),
Nothing<bool>());
}
PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder, PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder,
should_throw); should_throw);
args.Call(call_fun, name, value); args.Call(call_fun, name, value);
......
...@@ -10202,6 +10202,9 @@ class AccessorInfo: public Struct { ...@@ -10202,6 +10202,9 @@ class AccessorInfo: public Struct {
inline bool is_special_data_property(); inline bool is_special_data_property();
inline void set_is_special_data_property(bool value); inline void set_is_special_data_property(bool value);
inline bool is_sloppy();
inline void set_is_sloppy(bool value);
inline PropertyAttributes property_attributes(); inline PropertyAttributes property_attributes();
inline void set_property_attributes(PropertyAttributes attributes); inline void set_property_attributes(PropertyAttributes attributes);
...@@ -10239,7 +10242,8 @@ class AccessorInfo: public Struct { ...@@ -10239,7 +10242,8 @@ class AccessorInfo: public Struct {
static const int kAllCanReadBit = 0; static const int kAllCanReadBit = 0;
static const int kAllCanWriteBit = 1; static const int kAllCanWriteBit = 1;
static const int kSpecialDataProperty = 2; static const int kSpecialDataProperty = 2;
class AttributesField : public BitField<PropertyAttributes, 3, 3> {}; static const int kIsSloppy = 3;
class AttributesField : public BitField<PropertyAttributes, 4, 3> {};
DISALLOW_IMPLICIT_CONSTRUCTORS(AccessorInfo); DISALLOW_IMPLICIT_CONSTRUCTORS(AccessorInfo);
}; };
......
...@@ -774,3 +774,28 @@ TEST(PrototypeGetterAccessCheck) { ...@@ -774,3 +774,28 @@ TEST(PrototypeGetterAccessCheck) {
CHECK(try_catch.HasCaught()); CHECK(try_catch.HasCaught());
} }
} }
static void check_receiver(Local<String> name,
const v8::PropertyCallbackInfo<v8::Value>& info) {
CHECK(info.This()->IsObject());
}
TEST(Regress609134) {
v8::internal::FLAG_allow_natives_syntax = true;
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope scope(isolate);
auto fun_templ = v8::FunctionTemplate::New(isolate);
fun_templ->InstanceTemplate()->SetNativeDataProperty(v8_str("foo"),
check_receiver);
CHECK(env->Global()
->Set(env.local(), v8_str("Fun"),
fun_templ->GetFunction(env.local()).ToLocalChecked())
.FromJust());
CompileRun(
"var f = new Fun();"
"Number.prototype.__proto__ = f;"
"[42][0].foo");
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment