Commit 4268141c authored by verwaest's avatar verwaest Committed by Commit bot

Reland "Mark internal AccessorInfo properties as 'special data properties'"

This reverts commit ac5336ba.

BUG=

Review URL: https://codereview.chromium.org/1138483005

Cr-Commit-Position: refs/heads/master@{#28442}
parent 029a2d61
...@@ -32,6 +32,7 @@ Handle<AccessorInfo> Accessors::MakeAccessor( ...@@ -32,6 +32,7 @@ Handle<AccessorInfo> Accessors::MakeAccessor(
info->set_property_attributes(attributes); info->set_property_attributes(attributes);
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_name(*name); info->set_name(*name);
Handle<Object> get = v8::FromCData(isolate, getter); Handle<Object> get = v8::FromCData(isolate, getter);
Handle<Object> set = v8::FromCData(isolate, setter); Handle<Object> set = v8::FromCData(isolate, setter);
...@@ -126,31 +127,6 @@ bool Accessors::IsJSArrayBufferViewFieldAccessor(Handle<Map> map, ...@@ -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 // Accessors::ArgumentsIterator
// //
...@@ -174,8 +150,6 @@ void Accessors::ArgumentsIteratorSetter( ...@@ -174,8 +150,6 @@ void Accessors::ArgumentsIteratorSetter(
Handle<JSObject> object = Utils::OpenHandle(*info.This()); Handle<JSObject> object = Utils::OpenHandle(*info.This());
Handle<Object> value = Utils::OpenHandle(*val); Handle<Object> value = Utils::OpenHandle(*val);
if (SetPropertyOnInstanceIfInherited(isolate, info, name, value)) return;
LookupIterator it(object, Utils::OpenHandle(*name)); LookupIterator it(object, Utils::OpenHandle(*name));
CHECK_EQ(LookupIterator::ACCESSOR, it.state()); CHECK_EQ(LookupIterator::ACCESSOR, it.state());
DCHECK(it.HolderIsReceiverOrHiddenPrototype()); DCHECK(it.HolderIsReceiverOrHiddenPrototype());
...@@ -234,9 +208,6 @@ void Accessors::ArrayLengthSetter( ...@@ -234,9 +208,6 @@ void Accessors::ArrayLengthSetter(
HandleScope scope(isolate); HandleScope scope(isolate);
Handle<JSObject> object = Utils::OpenHandle(*info.This()); Handle<JSObject> object = Utils::OpenHandle(*info.This());
Handle<Object> value = Utils::OpenHandle(*val); Handle<Object> value = Utils::OpenHandle(*val);
if (SetPropertyOnInstanceIfInherited(isolate, info, name, value)) {
return;
}
value = FlattenNumber(isolate, value); value = FlattenNumber(isolate, value);
...@@ -970,9 +941,6 @@ void Accessors::FunctionPrototypeSetter( ...@@ -970,9 +941,6 @@ void Accessors::FunctionPrototypeSetter(
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
HandleScope scope(isolate); HandleScope scope(isolate);
Handle<Object> value = Utils::OpenHandle(*val); Handle<Object> value = Utils::OpenHandle(*val);
if (SetPropertyOnInstanceIfInherited(isolate, info, name, value)) {
return;
}
Handle<JSFunction> object = Handle<JSFunction> object =
Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder())); Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
if (SetFunctionPrototype(isolate, object, value).is_null()) { if (SetFunctionPrototype(isolate, object, value).is_null()) {
...@@ -1061,8 +1029,6 @@ void Accessors::FunctionLengthSetter( ...@@ -1061,8 +1029,6 @@ void Accessors::FunctionLengthSetter(
HandleScope scope(isolate); HandleScope scope(isolate);
Handle<Object> value = Utils::OpenHandle(*val); Handle<Object> value = Utils::OpenHandle(*val);
if (SetPropertyOnInstanceIfInherited(isolate, info, name, value)) return;
Handle<JSFunction> object = Handle<JSFunction> object =
Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder())); Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
if (SetFunctionLength(isolate, object, value).is_null()) { if (SetFunctionLength(isolate, object, value).is_null()) {
...@@ -1120,8 +1086,6 @@ void Accessors::FunctionNameSetter( ...@@ -1120,8 +1086,6 @@ void Accessors::FunctionNameSetter(
HandleScope scope(isolate); HandleScope scope(isolate);
Handle<Object> value = Utils::OpenHandle(*val); Handle<Object> value = Utils::OpenHandle(*val);
if (SetPropertyOnInstanceIfInherited(isolate, info, name, value)) return;
Handle<JSFunction> object = Handle<JSFunction> object =
Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder())); Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
if (SetFunctionName(isolate, object, value).is_null()) { if (SetFunctionName(isolate, object, value).is_null()) {
......
...@@ -1671,6 +1671,12 @@ Handle<Code> StoreIC::CompileHandler(LookupIterator* lookup, ...@@ -1671,6 +1671,12 @@ Handle<Code> StoreIC::CompileHandler(LookupIterator* lookup,
TRACE_GENERIC_IC(isolate(), "StoreIC", "setter == 0"); TRACE_GENERIC_IC(isolate(), "StoreIC", "setter == 0");
break; break;
} }
if (AccessorInfo::cast(*accessors)->is_special_data_property() &&
!lookup->HolderIsReceiverOrHiddenPrototype()) {
TRACE_GENERIC_IC(isolate(), "StoreIC",
"special data property in prototype chain");
break;
}
if (!ExecutableAccessorInfo::IsCompatibleReceiverMap(isolate(), info, if (!ExecutableAccessorInfo::IsCompatibleReceiverMap(isolate(), info,
receiver_map())) { receiver_map())) {
TRACE_GENERIC_IC(isolate(), "StoreIC", "incompatible receiver type"); TRACE_GENERIC_IC(isolate(), "StoreIC", "incompatible receiver type");
......
...@@ -142,7 +142,9 @@ void LookupIterator::PrepareTransitionToDataProperty( ...@@ -142,7 +142,9 @@ void LookupIterator::PrepareTransitionToDataProperty(
Handle<Object> value, PropertyAttributes attributes, Handle<Object> value, PropertyAttributes attributes,
Object::StoreFromKeyed store_mode) { Object::StoreFromKeyed store_mode) {
if (state_ == TRANSITION) return; 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_NE(LookupIterator::INTEGER_INDEXED_EXOTIC, state_);
DCHECK(state_ == NOT_FOUND || !HolderIsReceiverOrHiddenPrototype()); DCHECK(state_ == NOT_FOUND || !HolderIsReceiverOrHiddenPrototype());
// Can only be called when the receiver is a JSObject. JSProxy has to be // Can only be called when the receiver is a JSObject. JSProxy has to be
......
...@@ -7055,6 +7055,16 @@ void AccessorInfo::set_all_can_write(bool value) { ...@@ -7055,6 +7055,16 @@ void AccessorInfo::set_all_can_write(bool value) {
} }
bool AccessorInfo::is_special_data_property() {
return BooleanBit::get(flag(), kSpecialDataProperty);
}
void AccessorInfo::set_is_special_data_property(bool value) {
set_flag(BooleanBit::set(flag(), kSpecialDataProperty, value));
}
PropertyAttributes AccessorInfo::property_attributes() { PropertyAttributes AccessorInfo::property_attributes() {
return AttributesField::decode(static_cast<uint32_t>(flag()->value())); return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
} }
......
...@@ -3215,14 +3215,21 @@ MaybeHandle<Object> Object::SetPropertyInternal(LookupIterator* it, ...@@ -3215,14 +3215,21 @@ MaybeHandle<Object> Object::SetPropertyInternal(LookupIterator* it,
} }
break; break;
case LookupIterator::ACCESSOR: case LookupIterator::ACCESSOR: {
if (it->property_details().IsReadOnly()) { if (it->property_details().IsReadOnly()) {
return WriteToReadOnlyProperty(it, value, language_mode); 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, return SetPropertyWithAccessor(it->GetReceiver(), it->name(), value,
it->GetHolder<JSObject>(), it->GetHolder<JSObject>(), accessors,
it->GetAccessors(), language_mode); language_mode);
}
case LookupIterator::INTEGER_INDEXED_EXOTIC: case LookupIterator::INTEGER_INDEXED_EXOTIC:
done = true; done = true;
break; break;
......
...@@ -10517,6 +10517,9 @@ class AccessorInfo: public Struct { ...@@ -10517,6 +10517,9 @@ class AccessorInfo: public Struct {
inline bool all_can_write(); inline bool all_can_write();
inline void set_all_can_write(bool value); inline void set_all_can_write(bool value);
inline bool is_special_data_property();
inline void set_is_special_data_property(bool value);
inline PropertyAttributes property_attributes(); inline PropertyAttributes property_attributes();
inline void set_property_attributes(PropertyAttributes attributes); inline void set_property_attributes(PropertyAttributes attributes);
...@@ -10549,7 +10552,8 @@ class AccessorInfo: public Struct { ...@@ -10549,7 +10552,8 @@ class AccessorInfo: public Struct {
// Bit positions in flag. // Bit positions in flag.
static const int kAllCanReadBit = 0; static const int kAllCanReadBit = 0;
static const int kAllCanWriteBit = 1; 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); DISALLOW_IMPLICIT_CONSTRUCTORS(AccessorInfo);
}; };
......
...@@ -119,3 +119,9 @@ for (var i = 0; i < 7; i++) { ...@@ -119,3 +119,9 @@ for (var i = 0; i < 7; i++) {
t = a.length = 7; t = a.length = 7;
assertEquals(7, t); assertEquals(7, t);
} }
(function () {
"use strict";
var frozen_object = Object.freeze({__proto__:[]});
assertThrows(function () { frozen_object.length = 10 });
})();
...@@ -219,10 +219,7 @@ function TestArgumentsAsProto() { ...@@ -219,10 +219,7 @@ function TestArgumentsAsProto() {
assertSame([][Symbol.iterator], o[Symbol.iterator]); assertSame([][Symbol.iterator], o[Symbol.iterator]);
assertFalse(o.hasOwnProperty(Symbol.iterator)); assertFalse(o.hasOwnProperty(Symbol.iterator));
assertSame([][Symbol.iterator], o[Symbol.iterator]); assertSame([][Symbol.iterator], o[Symbol.iterator]);
// This should throw, but currently it doesn't, because assertThrows(function () { o[Symbol.iterator] = 10 });
// ExecutableAccessorInfo callbacks don't see the current strict mode.
// See note in accessors.cc:SetPropertyOnInstanceIfInherited.
o[Symbol.iterator] = 10;
assertFalse(o.hasOwnProperty(Symbol.iterator)); assertFalse(o.hasOwnProperty(Symbol.iterator));
assertEquals([][Symbol.iterator], o[Symbol.iterator]); assertEquals([][Symbol.iterator], o[Symbol.iterator]);
assertSame([][Symbol.iterator], arguments[Symbol.iterator]); assertSame([][Symbol.iterator], arguments[Symbol.iterator]);
......
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
this.__proto__ = Array.prototype;
Object.freeze(this);
function __f_0() {
for (var __v_0 = 0; __v_0 < 10; __v_0++) {
this.length = 1;
}
}
__f_0();
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