Commit 7d6ada27 authored by Shu-yu Guo's avatar Shu-yu Guo Committed by Commit Bot

[protectors] Update protectors in DefineClass

DefineClass uses the ClassBoilerplate to directly construct the
property descriptor array or dictionary for defining the class
constructor and prototype, skipping use of the LookupIterator and the
encapsulated protector update logic. This patch adds manual calls
to UpdateProtector(), which is in particular relevant for the
isConcatSpreadable protector.

Bug: v8:9837
Change-Id: I7b9d8105d41f5f0f826ca2ce35d6bf3d1aeee6e7
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1863644
Commit-Queue: Shu-yu Guo <syg@chromium.org>
Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#64368}
parent 2c678a71
...@@ -123,19 +123,25 @@ bool LookupIterator::IsCacheableTransition() { ...@@ -123,19 +123,25 @@ bool LookupIterator::IsCacheableTransition() {
transition_map()->GetBackPointer(isolate_).IsMap(isolate_); transition_map()->GetBackPointer(isolate_).IsMap(isolate_);
} }
void LookupIterator::UpdateProtector() { // static
if (IsElement()) return; void LookupIterator::UpdateProtector(Isolate* isolate, Handle<Object> receiver,
Handle<Name> name) {
// This list must be kept in sync with // This list must be kept in sync with
// CodeStubAssembler::CheckForAssociatedProtector! // CodeStubAssembler::CheckForAssociatedProtector!
ReadOnlyRoots roots(isolate_); ReadOnlyRoots roots(isolate);
if (*name_ == roots.is_concat_spreadable_symbol() || if (*name == roots.is_concat_spreadable_symbol() ||
*name_ == roots.constructor_string() || *name_ == roots.next_string() || *name == roots.constructor_string() || *name == roots.next_string() ||
*name_ == roots.species_symbol() || *name_ == roots.iterator_symbol() || *name == roots.species_symbol() || *name == roots.iterator_symbol() ||
*name_ == roots.resolve_string() || *name_ == roots.then_string()) { *name == roots.resolve_string() || *name == roots.then_string()) {
InternalUpdateProtector(); InternalUpdateProtector(isolate, receiver, name);
} }
} }
void LookupIterator::UpdateProtector() {
if (IsElement()) return;
UpdateProtector(isolate_, receiver_, name_);
}
InternalIndex LookupIterator::descriptor_number() const { InternalIndex LookupIterator::descriptor_number() const {
DCHECK(!IsElement()); DCHECK(!IsElement());
DCHECK(has_property_); DCHECK(has_property_);
......
...@@ -231,195 +231,198 @@ bool IsTypedArrayFunctionInAnyContext(Isolate* isolate, HeapObject object) { ...@@ -231,195 +231,198 @@ bool IsTypedArrayFunctionInAnyContext(Isolate* isolate, HeapObject object) {
} // namespace } // namespace
void LookupIterator::InternalUpdateProtector() { // static
if (isolate_->bootstrapper()->IsActive()) return; void LookupIterator::InternalUpdateProtector(Isolate* isolate,
if (!receiver_->IsHeapObject()) return; Handle<Object> receiver_generic,
Handle<HeapObject> receiver = Handle<HeapObject>::cast(receiver_); Handle<Name> name) {
if (isolate->bootstrapper()->IsActive()) return;
if (!receiver_generic->IsHeapObject()) return;
Handle<HeapObject> receiver = Handle<HeapObject>::cast(receiver_generic);
// Getting the native_context from the isolate as a fallback. If possible, we // Getting the native_context from the isolate as a fallback. If possible, we
// use the receiver's creation context instead. // use the receiver's creation context instead.
Handle<NativeContext> native_context = isolate_->native_context(); Handle<NativeContext> native_context = isolate->native_context();
ReadOnlyRoots roots(isolate_); ReadOnlyRoots roots(isolate);
if (*name_ == roots.constructor_string()) { if (*name == roots.constructor_string()) {
// Fetching the context in here since the operation is rather expensive. // Fetching the context in here since the operation is rather expensive.
if (receiver->IsJSReceiver()) { if (receiver->IsJSReceiver()) {
native_context = Handle<JSReceiver>::cast(receiver)->GetCreationContext(); native_context = Handle<JSReceiver>::cast(receiver)->GetCreationContext();
} }
if (!Protectors::IsArraySpeciesLookupChainIntact(isolate_) && if (!Protectors::IsArraySpeciesLookupChainIntact(isolate) &&
!Protectors::IsPromiseSpeciesLookupChainIntact(isolate_) && !Protectors::IsPromiseSpeciesLookupChainIntact(isolate) &&
!Protectors::IsRegExpSpeciesLookupChainProtectorIntact( !Protectors::IsRegExpSpeciesLookupChainProtectorIntact(
native_context) && native_context) &&
!Protectors::IsTypedArraySpeciesLookupChainIntact(isolate_)) { !Protectors::IsTypedArraySpeciesLookupChainIntact(isolate)) {
return; return;
} }
// Setting the constructor property could change an instance's @@species // Setting the constructor property could change an instance's @@species
if (receiver->IsJSArray(isolate_)) { if (receiver->IsJSArray(isolate)) {
if (!Protectors::IsArraySpeciesLookupChainIntact(isolate_)) return; if (!Protectors::IsArraySpeciesLookupChainIntact(isolate)) return;
isolate_->CountUsage( isolate->CountUsage(
v8::Isolate::UseCounterFeature::kArrayInstanceConstructorModified); v8::Isolate::UseCounterFeature::kArrayInstanceConstructorModified);
Protectors::InvalidateArraySpeciesLookupChain(isolate_); Protectors::InvalidateArraySpeciesLookupChain(isolate);
return; return;
} else if (receiver->IsJSPromise(isolate_)) { } else if (receiver->IsJSPromise(isolate)) {
if (!Protectors::IsPromiseSpeciesLookupChainIntact(isolate_)) return; if (!Protectors::IsPromiseSpeciesLookupChainIntact(isolate)) return;
Protectors::InvalidatePromiseSpeciesLookupChain(isolate_); Protectors::InvalidatePromiseSpeciesLookupChain(isolate);
return; return;
} else if (receiver->IsJSRegExp(isolate_)) { } else if (receiver->IsJSRegExp(isolate)) {
if (!Protectors::IsRegExpSpeciesLookupChainProtectorIntact( if (!Protectors::IsRegExpSpeciesLookupChainProtectorIntact(
native_context)) { native_context)) {
return; return;
} }
Protectors::InvalidateRegExpSpeciesLookupChainProtector(isolate_, Protectors::InvalidateRegExpSpeciesLookupChainProtector(isolate,
native_context); native_context);
return; return;
} else if (receiver->IsJSTypedArray(isolate_)) { } else if (receiver->IsJSTypedArray(isolate)) {
if (!Protectors::IsTypedArraySpeciesLookupChainIntact(isolate_)) return; if (!Protectors::IsTypedArraySpeciesLookupChainIntact(isolate)) return;
Protectors::InvalidateTypedArraySpeciesLookupChain(isolate_); Protectors::InvalidateTypedArraySpeciesLookupChain(isolate);
return; return;
} }
if (receiver->map(isolate_).is_prototype_map()) { if (receiver->map(isolate).is_prototype_map()) {
DisallowHeapAllocation no_gc; DisallowHeapAllocation no_gc;
// Setting the constructor of any prototype with the @@species protector // Setting the constructor of any prototype with the @@species protector
// (of any realm) also needs to invalidate the protector. // (of any realm) also needs to invalidate the protector.
// For typed arrays, we check a prototype of this receiver since // For typed arrays, we check a prototype of this receiver since
// TypedArrays have different prototypes for each type, and their parent // TypedArrays have different prototypes for each type, and their parent
// prototype is pointing the same TYPED_ARRAY_PROTOTYPE. // prototype is pointing the same TYPED_ARRAY_PROTOTYPE.
if (isolate_->IsInAnyContext(*receiver, if (isolate->IsInAnyContext(*receiver,
Context::INITIAL_ARRAY_PROTOTYPE_INDEX)) { Context::INITIAL_ARRAY_PROTOTYPE_INDEX)) {
if (!Protectors::IsArraySpeciesLookupChainIntact(isolate_)) return; if (!Protectors::IsArraySpeciesLookupChainIntact(isolate)) return;
isolate_->CountUsage( isolate->CountUsage(
v8::Isolate::UseCounterFeature::kArrayPrototypeConstructorModified); v8::Isolate::UseCounterFeature::kArrayPrototypeConstructorModified);
Protectors::InvalidateArraySpeciesLookupChain(isolate_); Protectors::InvalidateArraySpeciesLookupChain(isolate);
} else if (isolate_->IsInAnyContext(*receiver, } else if (isolate->IsInAnyContext(*receiver,
Context::PROMISE_PROTOTYPE_INDEX)) { Context::PROMISE_PROTOTYPE_INDEX)) {
if (!Protectors::IsPromiseSpeciesLookupChainIntact(isolate_)) return; if (!Protectors::IsPromiseSpeciesLookupChainIntact(isolate)) return;
Protectors::InvalidatePromiseSpeciesLookupChain(isolate_); Protectors::InvalidatePromiseSpeciesLookupChain(isolate);
} else if (isolate_->IsInAnyContext(*receiver, } else if (isolate->IsInAnyContext(*receiver,
Context::REGEXP_PROTOTYPE_INDEX)) { Context::REGEXP_PROTOTYPE_INDEX)) {
if (!Protectors::IsRegExpSpeciesLookupChainProtectorIntact( if (!Protectors::IsRegExpSpeciesLookupChainProtectorIntact(
native_context)) { native_context)) {
return; return;
} }
Protectors::InvalidateRegExpSpeciesLookupChainProtector(isolate_, Protectors::InvalidateRegExpSpeciesLookupChainProtector(isolate,
native_context); native_context);
} else if (isolate_->IsInAnyContext( } else if (isolate->IsInAnyContext(
receiver->map(isolate_).prototype(isolate_), receiver->map(isolate).prototype(isolate),
Context::TYPED_ARRAY_PROTOTYPE_INDEX)) { Context::TYPED_ARRAY_PROTOTYPE_INDEX)) {
if (!Protectors::IsTypedArraySpeciesLookupChainIntact(isolate_)) return; if (!Protectors::IsTypedArraySpeciesLookupChainIntact(isolate)) return;
Protectors::InvalidateTypedArraySpeciesLookupChain(isolate_); Protectors::InvalidateTypedArraySpeciesLookupChain(isolate);
} }
} }
} else if (*name_ == roots.next_string()) { } else if (*name == roots.next_string()) {
if (receiver->IsJSArrayIterator() || if (receiver->IsJSArrayIterator() ||
isolate_->IsInAnyContext( isolate->IsInAnyContext(
*receiver, Context::INITIAL_ARRAY_ITERATOR_PROTOTYPE_INDEX)) { *receiver, Context::INITIAL_ARRAY_ITERATOR_PROTOTYPE_INDEX)) {
// Setting the next property of %ArrayIteratorPrototype% also needs to // Setting the next property of %ArrayIteratorPrototype% also needs to
// invalidate the array iterator protector. // invalidate the array iterator protector.
if (!Protectors::IsArrayIteratorLookupChainIntact(isolate_)) return; if (!Protectors::IsArrayIteratorLookupChainIntact(isolate)) return;
Protectors::InvalidateArrayIteratorLookupChain(isolate_); Protectors::InvalidateArrayIteratorLookupChain(isolate);
} else if (receiver->IsJSMapIterator() || } else if (receiver->IsJSMapIterator() ||
isolate_->IsInAnyContext( isolate->IsInAnyContext(
*receiver, Context::INITIAL_MAP_ITERATOR_PROTOTYPE_INDEX)) { *receiver, Context::INITIAL_MAP_ITERATOR_PROTOTYPE_INDEX)) {
if (!Protectors::IsMapIteratorLookupChainIntact(isolate_)) return; if (!Protectors::IsMapIteratorLookupChainIntact(isolate)) return;
Protectors::InvalidateMapIteratorLookupChain(isolate_); Protectors::InvalidateMapIteratorLookupChain(isolate);
} else if (receiver->IsJSSetIterator() || } else if (receiver->IsJSSetIterator() ||
isolate_->IsInAnyContext( isolate->IsInAnyContext(
*receiver, Context::INITIAL_SET_ITERATOR_PROTOTYPE_INDEX)) { *receiver, Context::INITIAL_SET_ITERATOR_PROTOTYPE_INDEX)) {
if (!Protectors::IsSetIteratorLookupChainIntact(isolate_)) return; if (!Protectors::IsSetIteratorLookupChainIntact(isolate)) return;
Protectors::InvalidateSetIteratorLookupChain(isolate_); Protectors::InvalidateSetIteratorLookupChain(isolate);
} else if (receiver->IsJSStringIterator() || } else if (receiver->IsJSStringIterator() ||
isolate_->IsInAnyContext( isolate->IsInAnyContext(
*receiver, *receiver,
Context::INITIAL_STRING_ITERATOR_PROTOTYPE_INDEX)) { Context::INITIAL_STRING_ITERATOR_PROTOTYPE_INDEX)) {
// Setting the next property of %StringIteratorPrototype% invalidates the // Setting the next property of %StringIteratorPrototype% invalidates the
// string iterator protector. // string iterator protector.
if (!Protectors::IsStringIteratorLookupChainIntact(isolate_)) return; if (!Protectors::IsStringIteratorLookupChainIntact(isolate)) return;
Protectors::InvalidateStringIteratorLookupChain(isolate_); Protectors::InvalidateStringIteratorLookupChain(isolate);
} }
} else if (*name_ == roots.species_symbol()) { } else if (*name == roots.species_symbol()) {
// Fetching the context in here since the operation is rather expensive. // Fetching the context in here since the operation is rather expensive.
if (receiver->IsJSReceiver()) { if (receiver->IsJSReceiver()) {
native_context = Handle<JSReceiver>::cast(receiver)->GetCreationContext(); native_context = Handle<JSReceiver>::cast(receiver)->GetCreationContext();
} }
if (!Protectors::IsArraySpeciesLookupChainIntact(isolate_) && if (!Protectors::IsArraySpeciesLookupChainIntact(isolate) &&
!Protectors::IsPromiseSpeciesLookupChainIntact(isolate_) && !Protectors::IsPromiseSpeciesLookupChainIntact(isolate) &&
!Protectors::IsRegExpSpeciesLookupChainProtectorIntact( !Protectors::IsRegExpSpeciesLookupChainProtectorIntact(
native_context) && native_context) &&
!Protectors::IsTypedArraySpeciesLookupChainIntact(isolate_)) { !Protectors::IsTypedArraySpeciesLookupChainIntact(isolate)) {
return; return;
} }
// Setting the Symbol.species property of any Array, Promise or TypedArray // Setting the Symbol.species property of any Array, Promise or TypedArray
// constructor invalidates the @@species protector // constructor invalidates the @@species protector
if (isolate_->IsInAnyContext(*receiver, Context::ARRAY_FUNCTION_INDEX)) { if (isolate->IsInAnyContext(*receiver, Context::ARRAY_FUNCTION_INDEX)) {
if (!Protectors::IsArraySpeciesLookupChainIntact(isolate_)) return; if (!Protectors::IsArraySpeciesLookupChainIntact(isolate)) return;
isolate_->CountUsage( isolate->CountUsage(
v8::Isolate::UseCounterFeature::kArraySpeciesModified); v8::Isolate::UseCounterFeature::kArraySpeciesModified);
Protectors::InvalidateArraySpeciesLookupChain(isolate_); Protectors::InvalidateArraySpeciesLookupChain(isolate);
} else if (isolate_->IsInAnyContext(*receiver, } else if (isolate->IsInAnyContext(*receiver,
Context::PROMISE_FUNCTION_INDEX)) { Context::PROMISE_FUNCTION_INDEX)) {
if (!Protectors::IsPromiseSpeciesLookupChainIntact(isolate_)) return; if (!Protectors::IsPromiseSpeciesLookupChainIntact(isolate)) return;
Protectors::InvalidatePromiseSpeciesLookupChain(isolate_); Protectors::InvalidatePromiseSpeciesLookupChain(isolate);
} else if (isolate_->IsInAnyContext(*receiver, } else if (isolate->IsInAnyContext(*receiver,
Context::REGEXP_FUNCTION_INDEX)) { Context::REGEXP_FUNCTION_INDEX)) {
if (!Protectors::IsRegExpSpeciesLookupChainProtectorIntact( if (!Protectors::IsRegExpSpeciesLookupChainProtectorIntact(
native_context)) { native_context)) {
return; return;
} }
Protectors::InvalidateRegExpSpeciesLookupChainProtector(isolate_, Protectors::InvalidateRegExpSpeciesLookupChainProtector(isolate,
native_context); native_context);
} else if (IsTypedArrayFunctionInAnyContext(isolate_, *receiver)) { } else if (IsTypedArrayFunctionInAnyContext(isolate, *receiver)) {
if (!Protectors::IsTypedArraySpeciesLookupChainIntact(isolate_)) return; if (!Protectors::IsTypedArraySpeciesLookupChainIntact(isolate)) return;
Protectors::InvalidateTypedArraySpeciesLookupChain(isolate_); Protectors::InvalidateTypedArraySpeciesLookupChain(isolate);
} }
} else if (*name_ == roots.is_concat_spreadable_symbol()) { } else if (*name == roots.is_concat_spreadable_symbol()) {
if (!Protectors::IsIsConcatSpreadableLookupChainIntact(isolate_)) return; if (!Protectors::IsIsConcatSpreadableLookupChainIntact(isolate)) return;
Protectors::InvalidateIsConcatSpreadableLookupChain(isolate_); Protectors::InvalidateIsConcatSpreadableLookupChain(isolate);
} else if (*name_ == roots.iterator_symbol()) { } else if (*name == roots.iterator_symbol()) {
if (receiver->IsJSArray(isolate_)) { if (receiver->IsJSArray(isolate)) {
if (!Protectors::IsArrayIteratorLookupChainIntact(isolate_)) return; if (!Protectors::IsArrayIteratorLookupChainIntact(isolate)) return;
Protectors::InvalidateArrayIteratorLookupChain(isolate_); Protectors::InvalidateArrayIteratorLookupChain(isolate);
} else if (receiver->IsJSSet(isolate_) || receiver->IsJSSetIterator() || } else if (receiver->IsJSSet(isolate) || receiver->IsJSSetIterator() ||
isolate_->IsInAnyContext( isolate->IsInAnyContext(
*receiver, Context::INITIAL_SET_ITERATOR_PROTOTYPE_INDEX) || *receiver, Context::INITIAL_SET_ITERATOR_PROTOTYPE_INDEX) ||
isolate_->IsInAnyContext(*receiver, isolate->IsInAnyContext(*receiver,
Context::INITIAL_SET_PROTOTYPE_INDEX)) { Context::INITIAL_SET_PROTOTYPE_INDEX)) {
if (Protectors::IsSetIteratorLookupChainIntact(isolate_)) { if (Protectors::IsSetIteratorLookupChainIntact(isolate)) {
Protectors::InvalidateSetIteratorLookupChain(isolate_); Protectors::InvalidateSetIteratorLookupChain(isolate);
} }
} else if (receiver->IsJSMapIterator() || } else if (receiver->IsJSMapIterator() ||
isolate_->IsInAnyContext( isolate->IsInAnyContext(
*receiver, Context::INITIAL_MAP_ITERATOR_PROTOTYPE_INDEX)) { *receiver, Context::INITIAL_MAP_ITERATOR_PROTOTYPE_INDEX)) {
if (Protectors::IsMapIteratorLookupChainIntact(isolate_)) { if (Protectors::IsMapIteratorLookupChainIntact(isolate)) {
Protectors::InvalidateMapIteratorLookupChain(isolate_); Protectors::InvalidateMapIteratorLookupChain(isolate);
} }
} else if (isolate_->IsInAnyContext( } else if (isolate->IsInAnyContext(
*receiver, Context::INITIAL_ITERATOR_PROTOTYPE_INDEX)) { *receiver, Context::INITIAL_ITERATOR_PROTOTYPE_INDEX)) {
if (Protectors::IsMapIteratorLookupChainIntact(isolate_)) { if (Protectors::IsMapIteratorLookupChainIntact(isolate)) {
Protectors::InvalidateMapIteratorLookupChain(isolate_); Protectors::InvalidateMapIteratorLookupChain(isolate);
} }
if (Protectors::IsSetIteratorLookupChainIntact(isolate_)) { if (Protectors::IsSetIteratorLookupChainIntact(isolate)) {
Protectors::InvalidateSetIteratorLookupChain(isolate_); Protectors::InvalidateSetIteratorLookupChain(isolate);
} }
} else if (isolate_->IsInAnyContext( } else if (isolate->IsInAnyContext(
*receiver, Context::INITIAL_STRING_PROTOTYPE_INDEX)) { *receiver, Context::INITIAL_STRING_PROTOTYPE_INDEX)) {
// Setting the Symbol.iterator property of String.prototype invalidates // Setting the Symbol.iterator property of String.prototype invalidates
// the string iterator protector. Symbol.iterator can also be set on a // the string iterator protector. Symbol.iterator can also be set on a
// String wrapper, but not on a primitive string. We only support // String wrapper, but not on a primitive string. We only support
// protector for primitive strings. // protector for primitive strings.
if (!Protectors::IsStringIteratorLookupChainIntact(isolate_)) return; if (!Protectors::IsStringIteratorLookupChainIntact(isolate)) return;
Protectors::InvalidateStringIteratorLookupChain(isolate_); Protectors::InvalidateStringIteratorLookupChain(isolate);
} }
} else if (*name_ == roots.resolve_string()) { } else if (*name == roots.resolve_string()) {
if (!Protectors::IsPromiseResolveLookupChainIntact(isolate_)) return; if (!Protectors::IsPromiseResolveLookupChainIntact(isolate)) return;
// Setting the "resolve" property on any %Promise% intrinsic object // Setting the "resolve" property on any %Promise% intrinsic object
// invalidates the Promise.resolve protector. // invalidates the Promise.resolve protector.
if (isolate_->IsInAnyContext(*receiver, Context::PROMISE_FUNCTION_INDEX)) { if (isolate->IsInAnyContext(*receiver, Context::PROMISE_FUNCTION_INDEX)) {
Protectors::InvalidatePromiseResolveLookupChain(isolate_); Protectors::InvalidatePromiseResolveLookupChain(isolate);
} }
} else if (*name_ == roots.then_string()) { } else if (*name == roots.then_string()) {
if (!Protectors::IsPromiseThenLookupChainIntact(isolate_)) return; if (!Protectors::IsPromiseThenLookupChainIntact(isolate)) return;
// Setting the "then" property on any JSPromise instance or on the // Setting the "then" property on any JSPromise instance or on the
// initial %PromisePrototype% invalidates the Promise#then protector. // initial %PromisePrototype% invalidates the Promise#then protector.
// Also setting the "then" property on the initial %ObjectPrototype% // Also setting the "then" property on the initial %ObjectPrototype%
...@@ -427,11 +430,11 @@ void LookupIterator::InternalUpdateProtector() { ...@@ -427,11 +430,11 @@ void LookupIterator::InternalUpdateProtector() {
// to guard the fast-path in AsyncGeneratorResolve, where we can skip // to guard the fast-path in AsyncGeneratorResolve, where we can skip
// the ResolvePromise step and go directly to FulfillPromise if we // the ResolvePromise step and go directly to FulfillPromise if we
// know that the Object.prototype doesn't contain a "then" method. // know that the Object.prototype doesn't contain a "then" method.
if (receiver->IsJSPromise(isolate_) || if (receiver->IsJSPromise(isolate) ||
isolate_->IsInAnyContext(*receiver, isolate->IsInAnyContext(*receiver,
Context::INITIAL_OBJECT_PROTOTYPE_INDEX) || Context::INITIAL_OBJECT_PROTOTYPE_INDEX) ||
isolate_->IsInAnyContext(*receiver, Context::PROMISE_PROTOTYPE_INDEX)) { isolate->IsInAnyContext(*receiver, Context::PROMISE_PROTOTYPE_INDEX)) {
Protectors::InvalidatePromiseThenLookupChain(isolate_); Protectors::InvalidatePromiseThenLookupChain(isolate);
} }
} }
} }
......
...@@ -182,6 +182,8 @@ class V8_EXPORT_PRIVATE LookupIterator final { ...@@ -182,6 +182,8 @@ class V8_EXPORT_PRIVATE LookupIterator final {
Handle<Object> GetDataValue() const; Handle<Object> GetDataValue() const;
void WriteDataValue(Handle<Object> value, bool initializing_store); void WriteDataValue(Handle<Object> value, bool initializing_store);
inline void UpdateProtector(); inline void UpdateProtector();
static inline void UpdateProtector(Isolate* isolate, Handle<Object> receiver,
Handle<Name> name);
// Lookup a 'cached' private property for an accessor. // Lookup a 'cached' private property for an accessor.
// If not found returns false and leaves the LookupIterator unmodified. // If not found returns false and leaves the LookupIterator unmodified.
...@@ -194,7 +196,8 @@ class V8_EXPORT_PRIVATE LookupIterator final { ...@@ -194,7 +196,8 @@ class V8_EXPORT_PRIVATE LookupIterator final {
Handle<Map> transition_map, PropertyDetails details, Handle<Map> transition_map, PropertyDetails details,
bool has_property); bool has_property);
void InternalUpdateProtector(); static void InternalUpdateProtector(Isolate* isolate, Handle<Object> receiver,
Handle<Name> name);
enum class InterceptorState { enum class InterceptorState {
kUninitialized, kUninitialized,
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "src/objects/elements.h" #include "src/objects/elements.h"
#include "src/objects/hash-table-inl.h" #include "src/objects/hash-table-inl.h"
#include "src/objects/literal-objects-inl.h" #include "src/objects/literal-objects-inl.h"
#include "src/objects/lookup-inl.h"
#include "src/objects/smi.h" #include "src/objects/smi.h"
#include "src/objects/struct-inl.h" #include "src/objects/struct-inl.h"
#include "src/runtime/runtime.h" #include "src/runtime/runtime.h"
...@@ -282,6 +283,26 @@ bool SubstituteValues(Isolate* isolate, Handle<Dictionary> dictionary, ...@@ -282,6 +283,26 @@ bool SubstituteValues(Isolate* isolate, Handle<Dictionary> dictionary,
return true; return true;
} }
void UpdateProtectors(Isolate* isolate, Handle<JSObject> receiver,
Handle<NameDictionary> properties_dictionary) {
ReadOnlyRoots roots(isolate);
for (InternalIndex i : properties_dictionary->IterateEntries()) {
Object maybe_key = properties_dictionary->KeyAt(i);
if (!NameDictionary::IsKey(roots, maybe_key)) continue;
Handle<Name> name(Name::cast(maybe_key), isolate);
LookupIterator::UpdateProtector(isolate, receiver, name);
}
}
void UpdateProtectors(Isolate* isolate, Handle<JSObject> receiver,
Handle<DescriptorArray> properties_template) {
int nof_descriptors = properties_template->number_of_descriptors();
for (InternalIndex i : InternalIndex::Range(nof_descriptors)) {
Handle<Name> name(properties_template->GetKey(i), isolate);
LookupIterator::UpdateProtector(isolate, receiver, name);
}
}
bool AddDescriptorsByTemplate( bool AddDescriptorsByTemplate(
Isolate* isolate, Handle<Map> map, Isolate* isolate, Handle<Map> map,
Handle<DescriptorArray> descriptors_template, Handle<DescriptorArray> descriptors_template,
...@@ -368,6 +389,8 @@ bool AddDescriptorsByTemplate( ...@@ -368,6 +389,8 @@ bool AddDescriptorsByTemplate(
} }
} }
UpdateProtectors(isolate, receiver, descriptors_template);
map->InitializeDescriptors(isolate, *descriptors, map->InitializeDescriptors(isolate, *descriptors,
LayoutDescriptor::FastPointerLayout()); LayoutDescriptor::FastPointerLayout());
if (elements_dictionary->NumberOfElements() > 0) { if (elements_dictionary->NumberOfElements() > 0) {
...@@ -448,6 +471,8 @@ bool AddDescriptorsByTemplate( ...@@ -448,6 +471,8 @@ bool AddDescriptorsByTemplate(
CHECK_EQ(*dict, *properties_dictionary); CHECK_EQ(*dict, *properties_dictionary);
} }
UpdateProtectors(isolate, receiver, properties_dictionary);
if (elements_dictionary->NumberOfElements() > 0) { if (elements_dictionary->NumberOfElements() > 0) {
if (!SubstituteValues<NumberDictionary>(isolate, elements_dictionary, if (!SubstituteValues<NumberDictionary>(isolate, elements_dictionary,
receiver, args)) { receiver, args)) {
......
...@@ -256,9 +256,6 @@ ...@@ -256,9 +256,6 @@
# Test doesn't work on 32-bit architectures (it would require a # Test doesn't work on 32-bit architectures (it would require a
# regexp pattern with too many captures). # regexp pattern with too many captures).
'regress/regress-976627': [FAIL, ['arch == x64 or arch == arm64 or arch == mips64el or arch == ppc64 or arch == s390x', PASS]], 'regress/regress-976627': [FAIL, ['arch == x64 or arch == arm64 or arch == mips64el or arch == ppc64 or arch == s390x', PASS]],
# BUG(v8:9837)
'es6/array-concat-unspreadable-array-subclass': [FAIL],
}], # ALWAYS }], # ALWAYS
['novfp3 == True', { ['novfp3 == True', {
......
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