Commit 1fcbe01a authored by Joshua Litt's avatar Joshua Litt Committed by Commit Bot

Revert "[regexp] Implement the match indices proposal"

This reverts commit 9460101c.

Reason for revert: Causes confusion on Blink side, as it introduces
an object with >=2 internal fields that is not a wrapper (see bug).

Bug: chromium:996681
Change-Id: I275b5a064a4ee8c73c05f97be322924a3bc5370e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1769148Reviewed-by: 's avatarAdam Klein <adamk@chromium.org>
Commit-Queue: Joshua Litt <joshualitt@chromium.org>
Cr-Commit-Position: refs/heads/master@{#63386}
parent 7fd19228
......@@ -913,7 +913,6 @@ action("postmortem-metadata") {
"src/objects/js-promise-inl.h",
"src/objects/js-promise.h",
"src/objects/js-regexp-inl.h",
"src/objects/js-regexp.cc",
"src/objects/js-regexp.h",
"src/objects/js-regexp-string-iterator-inl.h",
"src/objects/js-regexp-string-iterator.h",
......@@ -2554,7 +2553,6 @@ v8_source_set("v8_base_without_compiler") {
"src/objects/js-regexp-inl.h",
"src/objects/js-regexp-string-iterator-inl.h",
"src/objects/js-regexp-string-iterator.h",
"src/objects/js-regexp.cc",
"src/objects/js-regexp.h",
"src/objects/js-relative-time-format-inl.h",
"src/objects/js-relative-time-format.cc",
......
......@@ -16,7 +16,6 @@
#include "src/objects/contexts.h"
#include "src/objects/field-index-inl.h"
#include "src/objects/js-array-inl.h"
#include "src/objects/js-regexp-inl.h"
#include "src/objects/module-inl.h"
#include "src/objects/property-details.h"
#include "src/objects/prototype.h"
......@@ -841,25 +840,5 @@ Handle<AccessorInfo> Accessors::MakeErrorStackInfo(Isolate* isolate) {
&ErrorStackGetter, &ErrorStackSetter);
}
//
// Accessors::RegExpResultIndices
//
void Accessors::RegExpResultIndicesGetter(
v8::Local<v8::Name> key, const v8::PropertyCallbackInfo<v8::Value>& info) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
HandleScope scope(isolate);
Handle<JSRegExpResult> regexp_result(
Handle<JSRegExpResult>::cast(Utils::OpenHandle(*info.Holder())));
Handle<Object> indices(
JSRegExpResult::GetAndCacheIndices(isolate, regexp_result));
info.GetReturnValue().Set(Utils::ToLocal(indices));
}
Handle<AccessorInfo> Accessors::MakeRegExpResultIndicesInfo(Isolate* isolate) {
return MakeAccessor(isolate, isolate->factory()->indices_string(),
&RegExpResultIndicesGetter, nullptr);
}
} // namespace internal
} // namespace v8
......@@ -43,8 +43,6 @@ class JavaScriptFrame;
kHasSideEffectToReceiver) \
V(_, function_prototype, FunctionPrototype, kHasNoSideEffect, \
kHasSideEffectToReceiver) \
V(_, regexp_result_indices, RegExpResultIndices, kHasSideEffectToReceiver, \
kHasSideEffectToReceiver) \
V(_, string_length, StringLength, kHasNoSideEffect, kHasSideEffectToReceiver)
#define ACCESSOR_SETTER_LIST(V) \
......
......@@ -1284,22 +1284,11 @@ RegExpBuiltinsAssembler::FastStoreLastIndex(FastJSRegExp, Smi): void;
@hasSameInstanceTypeAsParent
extern class JSRegExpResult extends JSArray {
// The below fields are for internal use only.
cached_indices_or_match_info: JSRegExpResultIndices | RegExpMatchInfo;
names: FixedArray | Undefined;
// The below fields are externally exposed.
index: Object;
input: Object;
groups: Object;
}
@hasSameInstanceTypeAsParent
extern class JSRegExpResultIndices extends JSArray {
// The groups field is externally exposed.
groups: Object;
}
extern class JSRegExpStringIterator extends JSObject {
iterating_reg_exp: Object;
iterated_string: String;
......
......@@ -35,8 +35,7 @@ TNode<IntPtrT> RegExpBuiltinsAssembler::IntPtrZero() {
TNode<JSRegExpResult> RegExpBuiltinsAssembler::AllocateRegExpResult(
TNode<Context> context, TNode<Smi> length, TNode<Smi> index,
TNode<String> input, TNode<RegExpMatchInfo> match_info,
TNode<FixedArray>* elements_out) {
TNode<String> input, TNode<FixedArray>* elements_out) {
CSA_ASSERT(this, SmiLessThanOrEqual(
length, SmiConstant(JSArray::kMaxFastArrayLength)));
CSA_ASSERT(this, SmiGreaterThan(length, SmiConstant(0)));
......@@ -63,22 +62,11 @@ TNode<JSRegExpResult> RegExpBuiltinsAssembler::AllocateRegExpResult(
TNode<JSRegExpResult> result = CAST(array);
// Load undefined value once here to avoid multiple LoadRoots.
TNode<Oddball> undefined_value =
UncheckedCast<Oddball>(LoadRoot(RootIndex::kUndefinedValue));
StoreObjectFieldNoWriteBarrier(result, JSRegExpResult::kIndexOffset, index);
// TODO(jgruber,tebbi): Could skip barrier but the MemoryOptimizer complains.
StoreObjectField(result, JSRegExpResult::kInputOffset, input);
StoreObjectFieldNoWriteBarrier(result, JSRegExpResult::kGroupsOffset,
undefined_value);
StoreObjectFieldNoWriteBarrier(result, JSRegExpResult::kNamesOffset,
undefined_value);
// Stash match_info in order to build JSRegExpResultIndices lazily when the
// 'indices' property is accessed.
StoreObjectField(result, JSRegExpResult::kCachedIndicesOrMatchInfoOffset,
match_info);
UndefinedConstant());
// Finish elements initialization.
......@@ -180,7 +168,7 @@ TNode<JSRegExpResult> RegExpBuiltinsAssembler::ConstructNewResultFromMatchInfo(
TNode<FixedArray> result_elements;
TNode<JSRegExpResult> result = AllocateRegExpResult(
context, num_results, start, string, match_info, &result_elements);
context, num_results, start, string, &result_elements);
UnsafeStoreFixedArrayElement(result_elements, 0, first);
......@@ -256,9 +244,6 @@ TNode<JSRegExpResult> RegExpBuiltinsAssembler::ConstructNewResultFromMatchInfo(
TNode<IntPtrT> names_length = LoadAndUntagFixedArrayBaseLength(names);
CSA_ASSERT(this, IntPtrGreaterThan(names_length, IntPtrZero()));
// Stash names in case we need them to build the indices array later.
StoreObjectField(result, JSRegExpResult::kNamesOffset, names);
// Allocate a new object to store the named capture properties.
// TODO(jgruber): Could be optimized by adding the object map to the heap
// root list.
......
......@@ -35,8 +35,7 @@ class RegExpBuiltinsAssembler : public CodeStubAssembler {
// and input string.
TNode<JSRegExpResult> AllocateRegExpResult(
TNode<Context> context, TNode<Smi> length, TNode<Smi> index,
TNode<String> input, TNode<RegExpMatchInfo> match_info,
TNode<FixedArray>* elements_out = nullptr);
TNode<String> input, TNode<FixedArray>* elements_out = nullptr);
TNode<Object> FastLoadLastIndexBeforeSmiCheck(TNode<JSRegExp> regexp);
TNode<Smi> FastLoadLastIndex(TNode<JSRegExp> regexp) {
......
......@@ -208,7 +208,6 @@ DEFINE_IMPLICATION(harmony_import_meta, harmony_dynamic_import)
V(harmony_regexp_sequence, "RegExp Unicode sequence properties") \
V(harmony_weak_refs, "harmony weak references") \
V(harmony_optional_chaining, "harmony optional chaining syntax") \
V(harmony_regexp_match_indices, "harmony regexp match indices") \
V(harmony_nullish, "harmony nullish operator")
#ifdef V8_INTL_SUPPORT
......
......@@ -284,10 +284,6 @@ class Genesis {
void TransferNamedProperties(Handle<JSObject> from, Handle<JSObject> to);
void TransferIndexedProperties(Handle<JSObject> from, Handle<JSObject> to);
Handle<Map> CreateInitialMapForArraySubclass(int size,
int inobject_properties,
int additional_properties = 0);
static bool CompileExtension(Isolate* isolate, v8::Extension* extension);
Isolate* isolate_;
......@@ -4423,17 +4419,6 @@ void Genesis::InitializeGlobal_harmony_promise_all_settled() {
}
}
void Genesis::InitializeGlobal_harmony_regexp_match_indices() {
if (!FLAG_harmony_regexp_match_indices) return;
// Add indices accessor to JSRegExpResult's initial map.
Handle<Map> initial_map(native_context()->regexp_result_map(), isolate());
Descriptor d = Descriptor::AccessorConstant(
factory()->indices_string(), factory()->regexp_result_indices_accessor(),
NONE);
initial_map->AppendDescriptor(isolate(), &d);
}
#ifdef V8_INTL_SUPPORT
void Genesis::InitializeGlobal_harmony_intl_date_format_range() {
......@@ -4915,12 +4900,42 @@ bool Genesis::InstallNatives() {
// predefines the properties index, input, and groups).
{
// JSRegExpResult initial map.
// Add additional slack to the initial map in case regexp_match_indices
// are enabled to account for the additional descriptor.
int additional_slack = 1;
Handle<Map> initial_map = CreateInitialMapForArraySubclass(
JSRegExpResult::kSize, JSRegExpResult::kInObjectPropertyCount,
additional_slack);
// Find global.Array.prototype to inherit from.
Handle<JSFunction> array_constructor(native_context()->array_function(),
isolate());
Handle<JSObject> array_prototype(
JSObject::cast(array_constructor->instance_prototype()), isolate());
// Add initial map.
Handle<Map> initial_map = factory()->NewMap(
JS_ARRAY_TYPE, JSRegExpResult::kSize, TERMINAL_FAST_ELEMENTS_KIND,
JSRegExpResult::kInObjectPropertyCount);
initial_map->SetConstructor(*array_constructor);
// Set prototype on map.
initial_map->set_has_non_instance_prototype(false);
Map::SetPrototype(isolate(), initial_map, array_prototype);
// Update map with length accessor from Array and add "index", "input" and
// "groups".
Map::EnsureDescriptorSlack(isolate(), initial_map,
JSRegExpResult::kInObjectPropertyCount + 1);
// length descriptor.
{
JSFunction array_function = native_context()->array_function();
Handle<DescriptorArray> array_descriptors(
array_function.initial_map().instance_descriptors(), isolate());
Handle<String> length = factory()->length_string();
int old = array_descriptors->SearchWithCache(
isolate(), *length, array_function.initial_map());
DCHECK_NE(old, DescriptorArray::kNotFound);
Descriptor d = Descriptor::AccessorConstant(
length, handle(array_descriptors->GetStrongValue(old), isolate()),
array_descriptors->GetDetails(old).attributes());
initial_map->AppendDescriptor(isolate(), &d);
}
// index descriptor.
{
......@@ -4949,27 +4964,6 @@ bool Genesis::InstallNatives() {
native_context()->set_regexp_result_map(*initial_map);
}
// Create a constructor for JSRegExpResultIndices (a variant of Array that
// predefines the groups property).
{
// JSRegExpResultIndices initial map.
Handle<Map> initial_map = CreateInitialMapForArraySubclass(
JSRegExpResultIndices::kSize,
JSRegExpResultIndices::kInObjectPropertyCount);
// groups descriptor.
{
Descriptor d = Descriptor::DataField(
isolate(), factory()->groups_string(),
JSRegExpResultIndices::kGroupsIndex, NONE, Representation::Tagged());
initial_map->AppendDescriptor(isolate(), &d);
DCHECK_EQ(initial_map->LastAdded(),
JSRegExpResultIndices::kGroupsDescriptorIndex);
}
native_context()->set_regexp_result_indices_map(*initial_map);
}
// Add @@iterator method to the arguments object maps.
{
PropertyAttributes attribs = DONT_ENUM;
......@@ -5371,47 +5365,6 @@ void Genesis::TransferObject(Handle<JSObject> from, Handle<JSObject> to) {
JSObject::ForceSetPrototype(to, proto);
}
Handle<Map> Genesis::CreateInitialMapForArraySubclass(int size,
int inobject_properties,
int additional_slack) {
// Find global.Array.prototype to inherit from.
Handle<JSFunction> array_constructor(native_context()->array_function(),
isolate());
Handle<JSObject> array_prototype(native_context()->initial_array_prototype(),
isolate());
// Add initial map.
Handle<Map> initial_map = factory()->NewMap(
JS_ARRAY_TYPE, size, TERMINAL_FAST_ELEMENTS_KIND, inobject_properties);
initial_map->SetConstructor(*array_constructor);
// Set prototype on map.
initial_map->set_has_non_instance_prototype(false);
Map::SetPrototype(isolate(), initial_map, array_prototype);
// Update map with length accessor from Array.
static constexpr int kTheLengthAccessor = 1;
Map::EnsureDescriptorSlack(
isolate(), initial_map,
inobject_properties + kTheLengthAccessor + additional_slack);
// length descriptor.
{
JSFunction array_function = native_context()->array_function();
Handle<DescriptorArray> array_descriptors(
array_function.initial_map().instance_descriptors(), isolate());
Handle<String> length = factory()->length_string();
int old = array_descriptors->SearchWithCache(isolate(), *length,
array_function.initial_map());
DCHECK_NE(old, DescriptorArray::kNotFound);
Descriptor d = Descriptor::AccessorConstant(
length, handle(array_descriptors->GetStrongValue(old), isolate()),
array_descriptors->GetDetails(old).attributes());
initial_map->AppendDescriptor(isolate(), &d);
}
return initial_map;
}
Genesis::Genesis(
Isolate* isolate, MaybeHandle<JSGlobalProxy> maybe_global_proxy,
v8::Local<v8::ObjectTemplate> global_proxy_template,
......
......@@ -202,7 +202,6 @@
V(_, illegal_access_string, "illegal access") \
V(_, illegal_argument_string, "illegal argument") \
V(_, index_string, "index") \
V(_, indices_string, "indices") \
V(_, Infinity_string, "Infinity") \
V(_, infinity_string, "infinity") \
V(_, input_string, "input") \
......
......@@ -233,7 +233,6 @@ enum ContextLookupFlags {
V(REGEXP_PROTOTYPE_MAP_INDEX, Map, regexp_prototype_map) \
V(REGEXP_REPLACE_FUNCTION_INDEX, JSFunction, regexp_replace_function) \
V(REGEXP_RESULT_MAP_INDEX, Map, regexp_result_map) \
V(REGEXP_RESULT_INDICES_MAP_INDEX, Map, regexp_result_indices_map) \
V(REGEXP_SEARCH_FUNCTION_INDEX, JSFunction, regexp_search_function) \
V(REGEXP_SPECIES_PROTECTOR_INDEX, PropertyCell, regexp_species_protector) \
V(REGEXP_SPLIT_FUNCTION_INDEX, JSFunction, regexp_split_function) \
......
......@@ -451,7 +451,6 @@ V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
V(JSProxy, JS_PROXY_TYPE) \
V(JSRegExp, JS_REGEXP_TYPE) \
V(JSRegExpResult, JS_ARRAY_TYPE) \
V(JSRegExpResultIndices, JS_ARRAY_TYPE) \
V(JSRegExpStringIterator, JS_REGEXP_STRING_ITERATOR_TYPE) \
V(JSSet, JS_SET_TYPE) \
V(JSStringIterator, JS_STRING_ITERATOR_TYPE) \
......
......@@ -7,7 +7,6 @@
#include "src/objects/js-regexp.h"
#include "src/objects/js-array-inl.h"
#include "src/objects/objects-inl.h" // Needed for write barriers
#include "src/objects/smi.h"
#include "src/objects/string.h"
......@@ -19,22 +18,14 @@ namespace v8 {
namespace internal {
OBJECT_CONSTRUCTORS_IMPL(JSRegExp, JSObject)
OBJECT_CONSTRUCTORS_IMPL(JSRegExpResult, JSArray)
OBJECT_CONSTRUCTORS_IMPL(JSRegExpResultIndices, JSArray)
CAST_ACCESSOR(JSRegExp)
CAST_ACCESSOR(JSRegExpResult)
CAST_ACCESSOR(JSRegExpResultIndices)
ACCESSORS(JSRegExp, data, Object, kDataOffset)
ACCESSORS(JSRegExp, flags, Object, kFlagsOffset)
ACCESSORS(JSRegExp, source, Object, kSourceOffset)
ACCESSORS(JSRegExp, last_index, Object, kLastIndexOffset)
ACCESSORS(JSRegExpResult, cached_indices_or_match_info, Object,
kCachedIndicesOrMatchInfoOffset)
ACCESSORS(JSRegExpResult, names, Object, kNamesOffset)
JSRegExp::Type JSRegExp::TypeTag() const {
Object data = this->data();
if (data.IsUndefined()) return JSRegExp::NOT_COMPILED;
......
// Copyright 2019 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.
#include "src/objects/js-regexp.h"
#include "src/objects/js-array-inl.h"
#include "src/objects/js-regexp-inl.h"
namespace v8 {
namespace internal {
Handle<JSArray> JSRegExpResult::GetAndCacheIndices(
Isolate* isolate, Handle<JSRegExpResult> regexp_result) {
// Check for cached indices.
Handle<Object> indices_or_match_info(
regexp_result->cached_indices_or_match_info(), isolate);
if (indices_or_match_info->IsRegExpMatchInfo()) {
// Build and cache indices for next lookup.
// TODO(joshualitt): Instead of caching the indices, we could call
// ReconfigureToDataProperty on 'indices' setting its value to this
// newly created array. However, care would have to be taken to ensure
// a new map is not created each time.
Handle<RegExpMatchInfo> match_info(
RegExpMatchInfo::cast(regexp_result->cached_indices_or_match_info()),
isolate);
Handle<Object> maybe_names(regexp_result->names(), isolate);
indices_or_match_info =
JSRegExpResultIndices::BuildIndices(isolate, match_info, maybe_names);
// Cache the result and clear the names array.
regexp_result->set_cached_indices_or_match_info(*indices_or_match_info);
regexp_result->set_names(ReadOnlyRoots(isolate).undefined_value());
}
return Handle<JSArray>::cast(indices_or_match_info);
}
Handle<JSRegExpResultIndices> JSRegExpResultIndices::BuildIndices(
Isolate* isolate, Handle<RegExpMatchInfo> match_info,
Handle<Object> maybe_names) {
Handle<JSRegExpResultIndices> indices(Handle<JSRegExpResultIndices>::cast(
isolate->factory()->NewJSObjectFromMap(
isolate->regexp_result_indices_map())));
// Initialize indices length to avoid having a partially initialized object
// should GC be triggered by creating a NewFixedArray.
indices->set_length(Smi::kZero);
// Build indices array from RegExpMatchInfo.
int num_indices = match_info->NumberOfCaptureRegisters();
int num_results = num_indices >> 1;
Handle<FixedArray> indices_array =
isolate->factory()->NewFixedArray(num_results);
JSArray::SetContent(indices, indices_array);
for (int i = 0; i < num_results; i++) {
int base_offset = i * 2;
int start_offset = match_info->Capture(base_offset);
int end_offset = match_info->Capture(base_offset + 1);
// Any unmatched captures are set to undefined, otherwise we set them to a
// subarray of the indices.
if (start_offset == -1) {
indices_array->set(i, ReadOnlyRoots(isolate).undefined_value());
} else {
Handle<FixedArray> indices_sub_array(
isolate->factory()->NewFixedArray(2));
indices_sub_array->set(0, Smi::FromInt(start_offset));
indices_sub_array->set(1, Smi::FromInt(end_offset));
Handle<JSArray> indices_sub_jsarray =
isolate->factory()->NewJSArrayWithElements(indices_sub_array,
PACKED_SMI_ELEMENTS, 2);
indices_array->set(i, *indices_sub_jsarray);
}
}
// If there are no capture groups, set the groups property to undefined.
FieldIndex groups_index =
FieldIndex::ForDescriptor(indices->map(), kGroupsDescriptorIndex);
if (maybe_names->IsUndefined(isolate)) {
indices->RawFastPropertyAtPut(groups_index,
ReadOnlyRoots(isolate).undefined_value());
return indices;
}
// Create a groups property which returns a dictionary of named captures to
// their corresponding capture indices.
Handle<FixedArray> names(Handle<FixedArray>::cast(maybe_names));
int num_names = names->length() >> 1;
Handle<NameDictionary> group_names = NameDictionary::New(isolate, num_names);
for (int i = 0; i < num_names; i++) {
int base_offset = i * 2;
int name_offset = base_offset;
int index_offset = base_offset + 1;
Handle<String> name(String::cast(names->get(name_offset)), isolate);
Handle<Smi> smi_index(Smi::cast(names->get(index_offset)), isolate);
Handle<Object> capture_indices(indices_array->get(smi_index->value()),
isolate);
if (!capture_indices->IsUndefined(isolate)) {
capture_indices = Handle<JSArray>::cast(capture_indices);
}
group_names = NameDictionary::Add(
isolate, group_names, name, capture_indices, PropertyDetails::Empty());
}
// Convert group_names to a JSObject and store at the groups property of the
// result indices.
Handle<FixedArrayBase> elements = isolate->factory()->empty_fixed_array();
Handle<HeapObject> null =
Handle<HeapObject>::cast(isolate->factory()->null_value());
Handle<JSObject> js_group_names =
isolate->factory()->NewSlowJSObjectWithPropertiesAndElements(
null, group_names, elements);
indices->RawFastPropertyAtPut(groups_index, *js_group_names);
return indices;
}
} // namespace internal
} // namespace v8
......@@ -199,59 +199,18 @@ DEFINE_OPERATORS_FOR_FLAGS(JSRegExp::Flags)
// After creation the result must be treated as a JSArray in all regards.
class JSRegExpResult : public JSArray {
public:
DECL_CAST(JSRegExpResult)
// TODO(joshualitt): We would like to add printers and verifiers to
// JSRegExpResult, and maybe JSRegExpResultIndices, but both have the same
// instance type as JSArray.
// cached_indices_or_match_info and names, are used to construct the
// JSRegExpResultIndices returned from the indices property lazily.
DECL_ACCESSORS(cached_indices_or_match_info, Object)
DECL_ACCESSORS(names, Object)
// Layout description.
DEFINE_FIELD_OFFSET_CONSTANTS(JSArray::kSize,
TORQUE_GENERATED_JSREG_EXP_RESULT_FIELDS)
static Handle<JSArray> GetAndCacheIndices(
Isolate* isolate, Handle<JSRegExpResult> regexp_result);
// Indices of in-object properties.
static const int kIndexIndex = 0;
static const int kInputIndex = 1;
static const int kGroupsIndex = 2;
static const int kInObjectPropertyCount = 3;
OBJECT_CONSTRUCTORS(JSRegExpResult, JSArray);
};
// JSRegExpResultIndices is just a JSArray with a specific initial map.
// This initial map adds in-object properties for "group"
// properties, as assigned by RegExp.prototype.exec, which allows
// faster creation of RegExp exec results.
// This class just holds constants used when creating the result.
// After creation the result must be treated as a JSArray in all regards.
class JSRegExpResultIndices : public JSArray {
public:
DECL_CAST(JSRegExpResultIndices)
// Layout description.
DEFINE_FIELD_OFFSET_CONSTANTS(
JSArray::kSize, TORQUE_GENERATED_JSREG_EXP_RESULT_INDICES_FIELDS)
static Handle<JSRegExpResultIndices> BuildIndices(
Isolate* isolate, Handle<RegExpMatchInfo> match_info,
Handle<Object> maybe_names);
// Indices of in-object properties.
static const int kGroupsIndex = 0;
static const int kInObjectPropertyCount = 1;
// Descriptor index of groups.
static const int kGroupsDescriptorIndex = 1;
OBJECT_CONSTRUCTORS(JSRegExpResultIndices, JSArray);
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(JSRegExpResult);
};
} // namespace internal
......
......@@ -158,7 +158,6 @@ class ZoneForwardList;
V(JSReceiver) \
V(JSRegExp) \
V(JSRegExpResult) \
V(JSRegExpResultIndices) \
V(JSRegExpStringIterator) \
V(JSSet) \
V(JSSetIterator) \
......
// Copyright 2019 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.
//
// Flags: --harmony-regexp-match-indices
// Sanity test.
{
const re = /a+(?<Z>z)?/;
const m = re.exec("xaaaz");
assertEquals(m.indices, [[1, 5], [4, 5]]);
assertEquals(m.indices.groups, {'Z': [4, 5]})
}
// Capture groups that are not matched return `undefined`.
{
const re = /a+(?<Z>z)?/;
const m = re.exec("xaaay");
assertEquals(m.indices, [[1, 4], undefined]);
assertEquals(m.indices.groups, {'Z': undefined});
}
// Two capture groups.
{
const re = /a+(?<A>zz)?(?<B>ii)?/;
const m = re.exec("xaaazzii");
assertEquals(m.indices, [[1, 8], [4, 6], [6, 8]]);
assertEquals(m.indices.groups, {'A': [4, 6], 'B': [6, 8]});
}
// No capture groups.
{
const re = /a+/;
const m = re.exec("xaaazzii");
assertEquals(m.indices [[1, 4]]);
assertEquals(m.indices.groups, undefined);
}
// No match.
{
const re = /a+/;
const m = re.exec("xzzii");
assertEquals(null, m);
}
// Unnamed capture groups.
{
const re = /a+(z)?/;
const m = re.exec("xaaaz")
assertEquals(m.indices, [[1, 5], [4, 5]]);
assertEquals(m.indices.groups, undefined)
}
// Named and unnamed capture groups.
{
const re = /a+(z)?(?<Y>y)?/;
const m = re.exec("xaaazyy")
assertEquals(m.indices, [[1, 6], [4, 5], [5, 6]]);
assertEquals(m.indices.groups, {'Y': [5, 6]})
}
// Verify property overwrite.
{
const re = /a+(?<Z>z)?/;
const m = re.exec("xaaaz");
m.indices = null;
assertEquals(null, m.indices);
}
// Mess with array prototype, we should still do the right thing.
{
Object.defineProperty(Array.prototype, "groups", {
get: () => {
assertUnreachable();
return null;
},
set: (x) => {
assertUnreachable();
}
});
Object.defineProperty(Array.prototype, "0", {
get: () => {
assertUnreachable();
return null;
},
set: (x) => {
assertUnreachable();
}
});
const re = /a+(?<Z>z)?/;
const m = re.exec("xaaaz");
assertEquals(m.indices.groups, {'Z': [4, 5]})
}
......@@ -291,54 +291,54 @@ KNOWN_MAPS = {
("read_only_space", 0x023a1): (87, "EnumCacheMap"),
("read_only_space", 0x02441): (82, "ArrayBoilerplateDescriptionMap"),
("read_only_space", 0x02631): (90, "InterceptorInfoMap"),
("read_only_space", 0x04ec9): (77, "AccessCheckInfoMap"),
("read_only_space", 0x04f19): (78, "AccessorInfoMap"),
("read_only_space", 0x04f69): (79, "AccessorPairMap"),
("read_only_space", 0x04fb9): (80, "AliasedArgumentsEntryMap"),
("read_only_space", 0x05009): (81, "AllocationMementoMap"),
("read_only_space", 0x05059): (83, "AsmWasmDataMap"),
("read_only_space", 0x050a9): (84, "AsyncGeneratorRequestMap"),
("read_only_space", 0x050f9): (85, "ClassPositionsMap"),
("read_only_space", 0x05149): (86, "DebugInfoMap"),
("read_only_space", 0x05199): (88, "FunctionTemplateInfoMap"),
("read_only_space", 0x051e9): (89, "FunctionTemplateRareDataMap"),
("read_only_space", 0x05239): (91, "InterpreterDataMap"),
("read_only_space", 0x05289): (92, "ObjectTemplateInfoMap"),
("read_only_space", 0x052d9): (93, "PromiseCapabilityMap"),
("read_only_space", 0x05329): (94, "PromiseReactionMap"),
("read_only_space", 0x05379): (95, "PrototypeInfoMap"),
("read_only_space", 0x053c9): (96, "ScriptMap"),
("read_only_space", 0x05419): (97, "SourcePositionTableWithFrameCacheMap"),
("read_only_space", 0x05469): (98, "SourceTextModuleInfoEntryMap"),
("read_only_space", 0x054b9): (99, "StackFrameInfoMap"),
("read_only_space", 0x05509): (100, "StackTraceFrameMap"),
("read_only_space", 0x05559): (101, "TemplateObjectDescriptionMap"),
("read_only_space", 0x055a9): (102, "Tuple2Map"),
("read_only_space", 0x055f9): (103, "Tuple3Map"),
("read_only_space", 0x05649): (104, "WasmCapiFunctionDataMap"),
("read_only_space", 0x05699): (105, "WasmDebugInfoMap"),
("read_only_space", 0x056e9): (106, "WasmExceptionTagMap"),
("read_only_space", 0x05739): (107, "WasmExportedFunctionDataMap"),
("read_only_space", 0x05789): (108, "WasmIndirectFunctionTableMap"),
("read_only_space", 0x057d9): (109, "WasmJSFunctionDataMap"),
("read_only_space", 0x05829): (110, "CallableTaskMap"),
("read_only_space", 0x05879): (111, "CallbackTaskMap"),
("read_only_space", 0x058c9): (112, "PromiseFulfillReactionJobTaskMap"),
("read_only_space", 0x05919): (113, "PromiseRejectReactionJobTaskMap"),
("read_only_space", 0x05969): (114, "PromiseResolveThenableJobTaskMap"),
("read_only_space", 0x059b9): (115, "InternalClassMap"),
("read_only_space", 0x05a09): (116, "SmiPairMap"),
("read_only_space", 0x05a59): (117, "SmiBoxMap"),
("read_only_space", 0x05aa9): (118, "SortStateMap"),
("read_only_space", 0x05af9): (121, "AllocationSiteWithWeakNextMap"),
("read_only_space", 0x05b49): (121, "AllocationSiteWithoutWeakNextMap"),
("read_only_space", 0x05b99): (156, "LoadHandler1Map"),
("read_only_space", 0x05be9): (156, "LoadHandler2Map"),
("read_only_space", 0x05c39): (156, "LoadHandler3Map"),
("read_only_space", 0x05c89): (164, "StoreHandler0Map"),
("read_only_space", 0x05cd9): (164, "StoreHandler1Map"),
("read_only_space", 0x05d29): (164, "StoreHandler2Map"),
("read_only_space", 0x05d79): (164, "StoreHandler3Map"),
("read_only_space", 0x04eb1): (77, "AccessCheckInfoMap"),
("read_only_space", 0x04f01): (78, "AccessorInfoMap"),
("read_only_space", 0x04f51): (79, "AccessorPairMap"),
("read_only_space", 0x04fa1): (80, "AliasedArgumentsEntryMap"),
("read_only_space", 0x04ff1): (81, "AllocationMementoMap"),
("read_only_space", 0x05041): (83, "AsmWasmDataMap"),
("read_only_space", 0x05091): (84, "AsyncGeneratorRequestMap"),
("read_only_space", 0x050e1): (85, "ClassPositionsMap"),
("read_only_space", 0x05131): (86, "DebugInfoMap"),
("read_only_space", 0x05181): (88, "FunctionTemplateInfoMap"),
("read_only_space", 0x051d1): (89, "FunctionTemplateRareDataMap"),
("read_only_space", 0x05221): (91, "InterpreterDataMap"),
("read_only_space", 0x05271): (92, "ObjectTemplateInfoMap"),
("read_only_space", 0x052c1): (93, "PromiseCapabilityMap"),
("read_only_space", 0x05311): (94, "PromiseReactionMap"),
("read_only_space", 0x05361): (95, "PrototypeInfoMap"),
("read_only_space", 0x053b1): (96, "ScriptMap"),
("read_only_space", 0x05401): (97, "SourcePositionTableWithFrameCacheMap"),
("read_only_space", 0x05451): (98, "SourceTextModuleInfoEntryMap"),
("read_only_space", 0x054a1): (99, "StackFrameInfoMap"),
("read_only_space", 0x054f1): (100, "StackTraceFrameMap"),
("read_only_space", 0x05541): (101, "TemplateObjectDescriptionMap"),
("read_only_space", 0x05591): (102, "Tuple2Map"),
("read_only_space", 0x055e1): (103, "Tuple3Map"),
("read_only_space", 0x05631): (104, "WasmCapiFunctionDataMap"),
("read_only_space", 0x05681): (105, "WasmDebugInfoMap"),
("read_only_space", 0x056d1): (106, "WasmExceptionTagMap"),
("read_only_space", 0x05721): (107, "WasmExportedFunctionDataMap"),
("read_only_space", 0x05771): (108, "WasmIndirectFunctionTableMap"),
("read_only_space", 0x057c1): (109, "WasmJSFunctionDataMap"),
("read_only_space", 0x05811): (110, "CallableTaskMap"),
("read_only_space", 0x05861): (111, "CallbackTaskMap"),
("read_only_space", 0x058b1): (112, "PromiseFulfillReactionJobTaskMap"),
("read_only_space", 0x05901): (113, "PromiseRejectReactionJobTaskMap"),
("read_only_space", 0x05951): (114, "PromiseResolveThenableJobTaskMap"),
("read_only_space", 0x059a1): (115, "InternalClassMap"),
("read_only_space", 0x059f1): (116, "SmiPairMap"),
("read_only_space", 0x05a41): (117, "SmiBoxMap"),
("read_only_space", 0x05a91): (118, "SortStateMap"),
("read_only_space", 0x05ae1): (121, "AllocationSiteWithWeakNextMap"),
("read_only_space", 0x05b31): (121, "AllocationSiteWithoutWeakNextMap"),
("read_only_space", 0x05b81): (156, "LoadHandler1Map"),
("read_only_space", 0x05bd1): (156, "LoadHandler2Map"),
("read_only_space", 0x05c21): (156, "LoadHandler3Map"),
("read_only_space", 0x05c71): (164, "StoreHandler0Map"),
("read_only_space", 0x05cc1): (164, "StoreHandler1Map"),
("read_only_space", 0x05d11): (164, "StoreHandler2Map"),
("read_only_space", 0x05d61): (164, "StoreHandler3Map"),
("map_space", 0x00119): (1057, "ExternalMap"),
("map_space", 0x00169): (1073, "JSMessageObjectMap"),
}
......@@ -398,30 +398,29 @@ KNOWN_OBJECTS = {
("old_space", 0x00429): "FunctionNameAccessor",
("old_space", 0x00499): "FunctionLengthAccessor",
("old_space", 0x00509): "FunctionPrototypeAccessor",
("old_space", 0x00579): "RegExpResultIndicesAccessor",
("old_space", 0x005e9): "StringLengthAccessor",
("old_space", 0x00659): "InvalidPrototypeValidityCell",
("old_space", 0x00669): "EmptyScript",
("old_space", 0x006e9): "ManyClosuresCell",
("old_space", 0x00701): "ArrayConstructorProtector",
("old_space", 0x00711): "NoElementsProtector",
("old_space", 0x00739): "IsConcatSpreadableProtector",
("old_space", 0x00749): "ArraySpeciesProtector",
("old_space", 0x00771): "TypedArraySpeciesProtector",
("old_space", 0x00799): "PromiseSpeciesProtector",
("old_space", 0x007c1): "StringLengthProtector",
("old_space", 0x007d1): "ArrayIteratorProtector",
("old_space", 0x007f9): "ArrayBufferDetachingProtector",
("old_space", 0x00821): "PromiseHookProtector",
("old_space", 0x00849): "PromiseResolveProtector",
("old_space", 0x00859): "MapIteratorProtector",
("old_space", 0x00881): "PromiseThenProtector",
("old_space", 0x008a9): "SetIteratorProtector",
("old_space", 0x008d1): "StringIteratorProtector",
("old_space", 0x008f9): "SingleCharacterStringCache",
("old_space", 0x01109): "StringSplitCache",
("old_space", 0x01919): "RegExpMultipleCache",
("old_space", 0x02129): "BuiltinsConstantsTable",
("old_space", 0x00579): "StringLengthAccessor",
("old_space", 0x005e9): "InvalidPrototypeValidityCell",
("old_space", 0x005f9): "EmptyScript",
("old_space", 0x00679): "ManyClosuresCell",
("old_space", 0x00691): "ArrayConstructorProtector",
("old_space", 0x006a1): "NoElementsProtector",
("old_space", 0x006c9): "IsConcatSpreadableProtector",
("old_space", 0x006d9): "ArraySpeciesProtector",
("old_space", 0x00701): "TypedArraySpeciesProtector",
("old_space", 0x00729): "PromiseSpeciesProtector",
("old_space", 0x00751): "StringLengthProtector",
("old_space", 0x00761): "ArrayIteratorProtector",
("old_space", 0x00789): "ArrayBufferDetachingProtector",
("old_space", 0x007b1): "PromiseHookProtector",
("old_space", 0x007d9): "PromiseResolveProtector",
("old_space", 0x007e9): "MapIteratorProtector",
("old_space", 0x00811): "PromiseThenProtector",
("old_space", 0x00839): "SetIteratorProtector",
("old_space", 0x00861): "StringIteratorProtector",
("old_space", 0x00889): "SingleCharacterStringCache",
("old_space", 0x01099): "StringSplitCache",
("old_space", 0x018a9): "RegExpMultipleCache",
("old_space", 0x020b9): "BuiltinsConstantsTable",
}
# List of known V8 Frame Markers.
......
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