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() {
transition_map()->GetBackPointer(isolate_).IsMap(isolate_);
}
void LookupIterator::UpdateProtector() {
if (IsElement()) return;
// static
void LookupIterator::UpdateProtector(Isolate* isolate, Handle<Object> receiver,
Handle<Name> name) {
// This list must be kept in sync with
// CodeStubAssembler::CheckForAssociatedProtector!
ReadOnlyRoots roots(isolate_);
if (*name_ == roots.is_concat_spreadable_symbol() ||
*name_ == roots.constructor_string() || *name_ == roots.next_string() ||
*name_ == roots.species_symbol() || *name_ == roots.iterator_symbol() ||
*name_ == roots.resolve_string() || *name_ == roots.then_string()) {
InternalUpdateProtector();
ReadOnlyRoots roots(isolate);
if (*name == roots.is_concat_spreadable_symbol() ||
*name == roots.constructor_string() || *name == roots.next_string() ||
*name == roots.species_symbol() || *name == roots.iterator_symbol() ||
*name == roots.resolve_string() || *name == roots.then_string()) {
InternalUpdateProtector(isolate, receiver, name);
}
}
void LookupIterator::UpdateProtector() {
if (IsElement()) return;
UpdateProtector(isolate_, receiver_, name_);
}
InternalIndex LookupIterator::descriptor_number() const {
DCHECK(!IsElement());
DCHECK(has_property_);
......
This diff is collapsed.
......@@ -182,6 +182,8 @@ class V8_EXPORT_PRIVATE LookupIterator final {
Handle<Object> GetDataValue() const;
void WriteDataValue(Handle<Object> value, bool initializing_store);
inline void UpdateProtector();
static inline void UpdateProtector(Isolate* isolate, Handle<Object> receiver,
Handle<Name> name);
// Lookup a 'cached' private property for an accessor.
// If not found returns false and leaves the LookupIterator unmodified.
......@@ -194,7 +196,8 @@ class V8_EXPORT_PRIVATE LookupIterator final {
Handle<Map> transition_map, PropertyDetails details,
bool has_property);
void InternalUpdateProtector();
static void InternalUpdateProtector(Isolate* isolate, Handle<Object> receiver,
Handle<Name> name);
enum class InterceptorState {
kUninitialized,
......
......@@ -17,6 +17,7 @@
#include "src/objects/elements.h"
#include "src/objects/hash-table-inl.h"
#include "src/objects/literal-objects-inl.h"
#include "src/objects/lookup-inl.h"
#include "src/objects/smi.h"
#include "src/objects/struct-inl.h"
#include "src/runtime/runtime.h"
......@@ -282,6 +283,26 @@ bool SubstituteValues(Isolate* isolate, Handle<Dictionary> dictionary,
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(
Isolate* isolate, Handle<Map> map,
Handle<DescriptorArray> descriptors_template,
......@@ -368,6 +389,8 @@ bool AddDescriptorsByTemplate(
}
}
UpdateProtectors(isolate, receiver, descriptors_template);
map->InitializeDescriptors(isolate, *descriptors,
LayoutDescriptor::FastPointerLayout());
if (elements_dictionary->NumberOfElements() > 0) {
......@@ -448,6 +471,8 @@ bool AddDescriptorsByTemplate(
CHECK_EQ(*dict, *properties_dictionary);
}
UpdateProtectors(isolate, receiver, properties_dictionary);
if (elements_dictionary->NumberOfElements() > 0) {
if (!SubstituteValues<NumberDictionary>(isolate, elements_dictionary,
receiver, args)) {
......
......@@ -256,9 +256,6 @@
# Test doesn't work on 32-bit architectures (it would require a
# 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]],
# BUG(v8:9837)
'es6/array-concat-unspreadable-array-subclass': [FAIL],
}], # ALWAYS
['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