Reviewers: rossberg,
Message:
PTAL
Description:
Mark internal AccessorInfo properties as "special data properties" to ensure
correct strict-mode handling.
BUG=
Please review this at https://codereview.chromium.org/1123163005/
Base URL: https://chromium.googlesource.com/v8/v8.git@master
Affected files (+37, -47 lines):
M src/accessors.cc
M src/lookup.cc
M src/objects.h
M src/objects.cc
M src/objects-inl.h
M test/mjsunit/array-length.js
M test/mjsunit/es6/arguments-iterator.js
Index: src/accessors.cc
diff --git a/src/accessors.cc b/src/accessors.cc
index
9b24ee37ecf433b50062e20cb541bbda239ba337..7737a6ddb66f3345c8ff23ec94f3897b0f60ae03
100644
--- a/src/accessors.cc
+++ b/src/accessors.cc
@@ -32,6 +32,7 @@ Handle<AccessorInfo> Accessors::MakeAccessor(
info->set_property_attributes(attributes);
info->set_all_can_read(false);
info->set_all_can_write(false);
+ info->mark_special_data_property();
info->set_name(*name);
Handle<Object> get = v8::FromCData(isolate, getter);
Handle<Object> set = v8::FromCData(isolate, setter);
@@ -126,31 +127,6 @@ bool
Accessors::IsJSArrayBufferViewFieldAccessor(Handle<Map> map,
}
-bool SetPropertyOnInstanceIfInherited(
- Isolate* isolate, const v8::PropertyCallbackInfo<void>& info,
- v8::Local<v8::Name> name, Handle<Object> value) {
- Handle<Object> holder = Utils::OpenHandle(*info.Holder());
- Handle<Object> receiver = Utils::OpenHandle(*info.This());
- if (*holder == *receiver) return false;
- if (receiver->IsJSObject()) {
- Handle<JSObject> object = Handle<JSObject>::cast(receiver);
- // This behaves sloppy since we lost the actual strict-mode.
- // TODO(verwaest): Fix by making ExecutableAccessorInfo behave like
data
- // properties.
- if (object->IsJSGlobalProxy()) {
- PrototypeIterator iter(isolate, object);
- if (iter.IsAtEnd()) return true;
- DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject());
- object = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
- }
- if (!object->map()->is_extensible()) return true;
- JSObject::SetOwnPropertyIgnoreAttributes(object,
Utils::OpenHandle(*name),
- value, NONE).Check();
- }
- return true;
-}
-
-
//
// Accessors::ArgumentsIterator
//
@@ -174,8 +150,6 @@ void Accessors::ArgumentsIteratorSetter(
Handle<JSObject> object = Utils::OpenHandle(*info.This());
Handle<Object> value = Utils::OpenHandle(*val);
- if (SetPropertyOnInstanceIfInherited(isolate, info, name, value)) return;
-
LookupIterator it(object, Utils::OpenHandle(*name));
CHECK_EQ(LookupIterator::ACCESSOR, it.state());
DCHECK(it.HolderIsReceiverOrHiddenPrototype());
@@ -234,9 +208,6 @@ void Accessors::ArrayLengthSetter(
HandleScope scope(isolate);
Handle<JSObject> object = Utils::OpenHandle(*info.This());
Handle<Object> value = Utils::OpenHandle(*val);
- if (SetPropertyOnInstanceIfInherited(isolate, info, name, value)) {
- return;
- }
value = FlattenNumber(isolate, value);
@@ -970,9 +941,6 @@ void Accessors::FunctionPrototypeSetter(
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
HandleScope scope(isolate);
Handle<Object> value = Utils::OpenHandle(*val);
- if (SetPropertyOnInstanceIfInherited(isolate, info, name, value)) {
- return;
- }
Handle<JSFunction> object =
Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
if (SetFunctionPrototype(isolate, object, value).is_null()) {
@@ -1061,8 +1029,6 @@ void Accessors::FunctionLengthSetter(
HandleScope scope(isolate);
Handle<Object> value = Utils::OpenHandle(*val);
- if (SetPropertyOnInstanceIfInherited(isolate, info, name, value)) return;
-
Handle<JSFunction> object =
Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
if (SetFunctionLength(isolate, object, value).is_null()) {
@@ -1120,8 +1086,6 @@ void Accessors::FunctionNameSetter(
HandleScope scope(isolate);
Handle<Object> value = Utils::OpenHandle(*val);
- if (SetPropertyOnInstanceIfInherited(isolate, info, name, value)) return;
-
Handle<JSFunction> object =
Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
if (SetFunctionName(isolate, object, value).is_null()) {
Index: src/lookup.cc
diff --git a/src/lookup.cc b/src/lookup.cc
index
809fd0eb2ef58a3bc292867135784c569b6bebdc..85745ce3e573321ac29feebd0a8b14c9a02b9341
100644
--- a/src/lookup.cc
+++ b/src/lookup.cc
@@ -142,7 +142,9 @@ void LookupIterator::PrepareTransitionToDataProperty(
Handle<Object> value, PropertyAttributes attributes,
Object::StoreFromKeyed store_mode) {
if (state_ == TRANSITION) return;
- DCHECK_NE(LookupIterator::ACCESSOR, state_);
+ DCHECK(state_ != LookupIterator::ACCESSOR ||
+ (GetAccessors()->IsAccessorInfo() &&
+
AccessorInfo::cast(*GetAccessors())->is_special_data_property()));
DCHECK_NE(LookupIterator::INTEGER_INDEXED_EXOTIC, state_);
DCHECK(state_ == NOT_FOUND || !HolderIsReceiverOrHiddenPrototype());
// Can only be called when the receiver is a JSObject. JSProxy has to be
Index: src/objects-inl.h
diff --git a/src/objects-inl.h b/src/objects-inl.h
index
cc264f6aef251d4680e4bb4b1621353a74f18483..e46f291770e9ab48297fa72940f68e72d6285641
100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -7036,6 +7036,16 @@ void AccessorInfo::set_all_can_write(bool value) {
}
+bool AccessorInfo::is_special_data_property() {
+ return BooleanBit::get(flag(), kSpecialDataProperty);
+}
+
+
+void AccessorInfo::mark_special_data_property() {
+ set_flag(BooleanBit::set(flag(), kSpecialDataProperty, true));
+}
+
+
PropertyAttributes AccessorInfo::property_attributes() {
return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
}
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index
9a5353fe630eaba44fecc4d3ce558c1babd343d5..d94aa598069e6eeb027ff958ce970a34b44ae3a4
100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -3194,14 +3194,21 @@ MaybeHandle<Object>
Object::SetPropertyInternal(LookupIterator* it,
}
break;
- case LookupIterator::ACCESSOR:
+ case LookupIterator::ACCESSOR: {
if (it->property_details().IsReadOnly()) {
return WriteToReadOnlyProperty(it, value, language_mode);
}
+ Handle<Object> accessors = it->GetAccessors();
+ if (accessors->IsAccessorInfo() &&
+ !it->HolderIsReceiverOrHiddenPrototype() &&
+ AccessorInfo::cast(*accessors)->is_special_data_property()) {
+ done = true;
+ break;
+ }
return SetPropertyWithAccessor(it->GetReceiver(), it->name(),
value,
- it->GetHolder<JSObject>(),
- it->GetAccessors(), language_mode);
-
+ it->GetHolder<JSObject>(),
accessors,
+ language_mode);
+ }
case LookupIterator::INTEGER_INDEXED_EXOTIC:
done = true;
break;
Index: src/objects.h
diff --git a/src/objects.h b/src/objects.h
index
4823243f2384b510771dd53a76dfa3bdb80c9471..d9e5b45b1f90a7ca77596c234750ee5140a6c185
100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -10506,6 +10506,9 @@ class AccessorInfo: public Struct {
inline bool all_can_write();
inline void set_all_can_write(bool value);
+ inline bool is_special_data_property();
+ inline void mark_special_data_property();
+
inline PropertyAttributes property_attributes();
inline void set_property_attributes(PropertyAttributes attributes);
@@ -10538,7 +10541,8 @@ class AccessorInfo: public Struct {
// Bit positions in flag.
static const int kAllCanReadBit = 0;
static const int kAllCanWriteBit = 1;
- class AttributesField: public BitField<PropertyAttributes, 2, 3> {};
+ static const int kSpecialDataProperty = 2;
+ class AttributesField : public BitField<PropertyAttributes, 3, 3> {};
DISALLOW_IMPLICIT_CONSTRUCTORS(AccessorInfo);
};
Index: test/mjsunit/array-length.js
diff --git a/test/mjsunit/array-length.js b/test/mjsunit/array-length.js
index
16867db733b6c98bb45b9428b86755d6c1e58e5d..04b1750a4a46023b15026000ff41caabac92125a
100644
--- a/test/mjsunit/array-length.js
+++ b/test/mjsunit/array-length.js
@@ -119,3 +119,9 @@ for (var i = 0; i < 7; i++) {
t = a.length = 7;
assertEquals(7, t);
}
+
+(function () {
+ "use strict";
+ var frozen_object = Object.freeze({__proto__:[]});
+ assertThrows(function () { frozen_object.length = 10 });
+})();
Index: test/mjsunit/es6/arguments-iterator.js
diff --git a/test/mjsunit/es6/arguments-iterator.js
b/test/mjsunit/es6/arguments-iterator.js
index
32d4b11ee1f58427dca47bfc6a8496ad3f3e8c8b..cf1e1f97ca32242770c0d915fde276aca85b6920
100644
--- a/test/mjsunit/es6/arguments-iterator.js
+++ b/test/mjsunit/es6/arguments-iterator.js
@@ -219,10 +219,7 @@ function TestArgumentsAsProto() {
assertSame([][Symbol.iterator], o[Symbol.iterator]);
assertFalse(o.hasOwnProperty(Symbol.iterator));
assertSame([][Symbol.iterator], o[Symbol.iterator]);
- // This should throw, but currently it doesn't, because
- // ExecutableAccessorInfo callbacks don't see the current strict mode.
- // See note in accessors.cc:SetPropertyOnInstanceIfInherited.
- o[Symbol.iterator] = 10;
+ assertThrows(function () { o[Symbol.iterator] = 10 });
assertFalse(o.hasOwnProperty(Symbol.iterator));
assertEquals([][Symbol.iterator], o[Symbol.iterator]);
assertSame([][Symbol.iterator], arguments[Symbol.iterator]);
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.