Diff
Modified: trunk/JSTests/ChangeLog (273159 => 273160)
--- trunk/JSTests/ChangeLog 2021-02-19 20:47:53 UTC (rev 273159)
+++ trunk/JSTests/ChangeLog 2021-02-19 20:50:48 UTC (rev 273160)
@@ -1,3 +1,65 @@
+2021-02-19 Michael Saboff <msab...@apple.com>
+
+ Minor fixes to RegExp match indices after r273086
+ https://bugs.webkit.org/show_bug.cgi?id=222157
+
+ Reviewed by Yusuke Suzuki.
+
+ Added a new test to verify that all flag RegExp flag combinations work round tripping
+ from flags to flag proerties and back.
+ Added standalone versions of the updated regexp-match-indices from the PR
+ https://github.com/tc39/test262/pull/2934 as JSTest/stress test.
+ Disabled the regexp-match-indices feature test in test262 until the pull request
+ with updated tests land and we update the WebKit version.
+ This is tracked in https://bugs.webkit.org/show_bug.cgi?id=222142.
+
+ * stress/regexp-all-flags.js: Added.
+ (flagsFromVariation):
+ (setPropertiesForVariation):
+ (missingPropertiesForVariation):
+ (test.let.flagsSet.get call):
+ (test):
+ * stress/test262-indices-array-element.js: Added.
+ (assertSameValue):
+ * stress/test262-indices-array-matched.js: Added.
+ (assertSameValue):
+ (assertCompareArray):
+ * stress/test262-indices-array-non-unicode-match.js: Added.
+ (assertSameValue):
+ (assertCompareArray):
+ (assertDeepEqual):
+ (verifyProperty):
+ * stress/test262-indices-array-properties.js: Added.
+ (verifyProperty):
+ * stress/test262-indices-array-unicode-match.js: Added.
+ (assertSameValue):
+ (assertCompareArray):
+ (assertDeepEqual):
+ (verifyProperty):
+ * stress/test262-indices-array-unicode-property-names.js: Added.
+ (assertCompareArray):
+ * stress/test262-indices-array-unmatched.js: Added.
+ (assertSameValue):
+ * stress/test262-indices-array.js: Added.
+ (assert):
+ (assertSameValue):
+ * stress/test262-indices-groups-object-undefined.js: Added.
+ (verifyProperty):
+ * stress/test262-indices-groups-object-unmatched.js: Added.
+ (assertSameValue):
+ (assertCompareArray):
+ * stress/test262-indices-groups-object.js: Added.
+ (assertSameValue):
+ (assertCompareArray):
+ (verifyProperty):
+ * stress/test262-indices-groups-properties.js: Added.
+ (assertCompareArray):
+ (verifyProperty):
+ * stress/test262-indices-property.js: Added.
+ (assertSameValue):
+ (verifyProperty):
+ * test262/config.yaml:
+
2021-02-19 Yusuke Suzuki <ysuz...@apple.com>
[JSC] Do not use toObject for options in new Intl constructors
Added: trunk/JSTests/stress/regexp-all-flags.js (0 => 273160)
--- trunk/JSTests/stress/regexp-all-flags.js (rev 0)
+++ trunk/JSTests/stress/regexp-all-flags.js 2021-02-19 20:50:48 UTC (rev 273160)
@@ -0,0 +1,60 @@
+let allRegExpFlags = "dgimsuy";
+let allRegExpProperties = [ 'hasIndices', 'global', 'ignoreCase', 'multiline', 'dotAll', 'unicode', 'sticky'];
+const numFlags = allRegExpFlags.length;
+const numVariations = 2 ** numFlags;
+
+function flagsFromVariation(variation)
+{
+ let flags = "";
+
+ for (let i = 0; i < numFlags; i++)
+ if (variation & (2 ** i))
+ flags = flags + allRegExpFlags[i];
+
+ return flags;
+}
+
+function setPropertiesForVariation(variation, o)
+{
+ for (let i = 0; i < numFlags; i++)
+ if (variation & (2 ** i))
+ o[allRegExpProperties[i]] = true;
+
+ return o;
+}
+
+function missingPropertiesForVariation(variation, o)
+{
+ let missingProperties = [];
+
+ for (let i = 0; i < numFlags; i++)
+ if (variation & (2 ** i) && !o[allRegExpProperties[i]])
+ missingProperties.push(allRegExpProperties[i]);
+
+ return missingProperties;
+}
+
+var get = Object.getOwnPropertyDescriptor(RegExp.prototype, "flags").get
+
+function test()
+{
+ for (let variation = 0; variation < numVariations; ++variation) {
+ let flags = flagsFromVariation(variation);
+
+ let r = new RegExp("foo", flags);
+
+ let missingProperties = missingPropertiesForVariation(variation, r);
+ if (missingProperties.length)
+ throw "RegExp " + r.toString() + " missing properties: " + missingProperties;
+
+ r = setPropertiesForVariation(variation, {});
+
+ let flagsSet = get.call(r);
+
+ if (flagsSet != flags)
+ throw "RegExp with flags: \"" + flags + "\" should have properties: " + missingPropertiesForVariation(variation, {});
+ }
+}
+
+test();
+
Added: trunk/JSTests/stress/test262-indices-array-element.js (0 => 273160)
--- trunk/JSTests/stress/test262-indices-array-element.js (rev 0)
+++ trunk/JSTests/stress/test262-indices-array-element.js 2021-02-19 20:50:48 UTC (rev 273160)
@@ -0,0 +1,33 @@
+// Copyright 2019 Ron Buckton. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: A matching element of indices is an Array with exactly two number properties.
+esid: sec-getmatchindicesarray
+features: [regexp-match-indices]
+info: |
+ GetMatchIndicesArray ( S, match )
+ 5. Return CreateArrayFromList(ยซ _match_.[[StartIndex]], _match_.[[EndIndex]] ยป).
+---*/
+
+function assertSameValue(a, b)
+{
+ if (a !== b)
+ throw "Values not same";
+}
+
+let input = "abcd";
+let match = /b(c)/d.exec(input);
+let indices = match.indices;
+
+// `indices[0]` is an array
+assertSameValue(Object.getPrototypeOf(indices[0]), Array.prototype);
+assertSameValue(indices[0].length, 2);
+assertSameValue(typeof indices[0][0], "number");
+assertSameValue(typeof indices[0][1], "number");
+
+// `indices[1]` is an array
+assertSameValue(Object.getPrototypeOf(indices[1]), Array.prototype);
+assertSameValue(indices[1].length, 2);
+assertSameValue(typeof indices[1][0], "number");
+assertSameValue(typeof indices[1][1], "number");
Added: trunk/JSTests/stress/test262-indices-array-matched.js (0 => 273160)
--- trunk/JSTests/stress/test262-indices-array-matched.js (rev 0)
+++ trunk/JSTests/stress/test262-indices-array-matched.js 2021-02-19 20:50:48 UTC (rev 273160)
@@ -0,0 +1,60 @@
+// Copyright 2019 Ron Buckton. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: The properties of the "indices" array correspond to the start/end indices of the same values in the match.
+includes: [compareArray.js]
+esid: sec-makeindicesarray
+features: [regexp-match-indices]
+info: |
+ MakeIndicesArray ( S, indices, groupNames, hasIndices )
+ 4. Let _n_ be the number of elements in _indices_.
+ ...
+ 8. Set _A_ to ! ArrayCreate(_n_).
+ ...
+ 13. For each integer _i_ such that _i_ >= 0 and _i_ < _n_, do
+ a. Let _matchIndices_ be _indices_[_i_].
+ b. If _matchIndices_ is not *undefined*, then
+ i. Let _matchIndicesArray_ be ! GetMatchIndicesArray(_S_, _matchIndices_).
+ c. Else,
+ i. Let _matchIndicesArray_ be *undefined*.
+ d. Perform ! CreateDataProperty(_A_, ! ToString(_n_), _matchIndicesArray_).
+ ...
+---*/
+
+function assertSameValue(a, b)
+{
+ if (a !== b)
+ throw "Values not same";
+}
+
+function assertCompareArray(a, b)
+{
+ if (!a instanceof Array)
+ throw "a not array";
+
+ if (!b instanceof Array)
+ throw "b not array";
+
+ if (a.length !== b.length)
+ throw "Arrays differ in length";
+
+ for (let i = 0; i < a.length; ++i)
+ if (a[i] !== b[i])
+ throw "Array element " + i + " differ";
+}
+
+let input = "abcd";
+let match = /b(c)/d.exec(input);
+let indices = match.indices;
+
+// `indices` has the same length as match
+assertSameValue(indices.length, match.length);
+
+// The first element of `indices` contains the start/end indices of the match
+assertCompareArray(indices[0], [1, 3]);
+assertSameValue(input.slice(indices[0][0], indices[0][1]), match[0]);
+
+// The second element of `indices` contains the start/end indices of the first capture
+assertCompareArray(indices[1], [2, 3]);
+assertSameValue(input.slice(indices[1][0], indices[1][1]), match[1]);
Added: trunk/JSTests/stress/test262-indices-array-non-unicode-match.js (0 => 273160)
--- trunk/JSTests/stress/test262-indices-array-non-unicode-match.js (rev 0)
+++ trunk/JSTests/stress/test262-indices-array-non-unicode-match.js 2021-02-19 20:50:48 UTC (rev 273160)
@@ -0,0 +1,129 @@
+// Copyright 2019 Ron Buckton. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Basic matching cases with non-unicode matches.
+includes: [compareArray.js, propertyHelper.js, deepEqual.js]
+esid: sec-regexpbuiltinexec
+features: [regexp-match-indices]
+info: |
+ Runtime Semantics: RegExpBuiltinExec ( R, S )
+ ...
+ 4. Let _lastIndex_ be ? ToLength(? Get(_R_, `"lastIndex")).
+ ...
+ 8. If _flags_ contains `"d"`, let _hasIndices_ be *true*, else let _hasIndices_ be *false*.
+ ...
+ 26. Let _match_ be the Match { [[StartIndex]]: _lastIndex_, [[EndIndex]]: _e_ }.
+ 27. Let _indices_ be a new empty List.
+ 29. Add _match_ as the last element of _indices_.
+ ...
+ 35. For each integer _i_ such that _i_ > 0 and _i_ <= _n_, in ascending order, do
+ ...
+ f. Else,
+ i. Let _captureStart_ be _captureI_'s _startIndex_.
+ ii. Let _captureEnd_ be _captureI_'s _endIndex_.
+ ...
+ iv. Let _capture_ be the Match { [[StartIndex]]: _captureStart_, [[EndIndex]]: _captureEnd_ }.
+ v. Append _capture_ to _indices_.
+ ...
+ 36. If _hasIndices_ is *true*, then
+ a. Let _indicesArray_ be MakeIndicesArray( _S_, _indices_, _groupNames_).
+ b. Perform ! CreateDataProperty(_A_, `"indices"`, _indicesArray_).
+---*/
+
+function assertSameValue(a, b)
+{
+ if (a !== b)
+ throw "Values not same";
+}
+
+function assertCompareArray(a, b)
+{
+ if (!a instanceof Array)
+ throw "a not array";
+
+ if (!b instanceof Array)
+ throw "b not array";
+
+ if (a.length !== b.length)
+ throw "Arrays differ in length";
+
+ for (let i = 0; i < a.length; ++i)
+ if (a[i] !== b[i])
+ throw "Array element " + i + " differ";
+}
+
+function assertDeepEqual(a, b)
+{
+ if (!a instanceof Array)
+ throw "a not array";
+
+ if (!b instanceof Array)
+ throw "b not array";
+
+ if (a.length !== b.length)
+ throw "Arrays differ in length";
+
+ for (let i = 0; i < a.length; ++i) {
+ if (a[i] instanceof Array)
+ assertDeepEqual(a[i], b[i]);
+ else if (a[i] !== b[i])
+ throw "Array element " + i + " differ";
+ }
+}
+
+function verifyProperty(obj, prop, expect)
+{
+ let desc = Object.getOwnPropertyDescriptor(obj, prop);
+
+ for (const [key, value] of Object.entries(expect))
+ if (desc[key] != value)
+ throw "obj." + prop + " " + key + ": is not " + value;
+}
+
+assertDeepEqual([[1, 2], [1, 2]], "bab".match(/(a)/d).indices);
+assertDeepEqual([[0, 3], [1, 2]], "bab".match(/.(a)./d).indices);
+assertDeepEqual([[0, 3], [1, 2], [2, 3]], "bab".match(/.(a)(.)/d).indices);
+assertDeepEqual([[0, 3], [1, 3]], "bab".match(/.(\w\w)/d).indices);
+assertDeepEqual([[0, 3], [0, 3]], "bab".match(/(\w\w\w)/d).indices);
+assertDeepEqual([[0, 3], [0, 2], [2, 3]], "bab".match(/(\w\w)(\w)/d).indices);
+assertDeepEqual([[0, 2], [0, 2], undefined], "bab".match(/(\w\w)(\W)?/d).indices);
+
+let groups = /(?<a>.)(?<b>.)(?<c>.)\k<c>\k<b>\k<a>/d.exec("abccba").indices.groups;
+assertCompareArray([0, 1], groups.a);
+assertCompareArray([1, 2], groups.b);
+assertCompareArray([2, 3], groups.c);
+verifyProperty(groups, "a", {
+ enumerable: true,
+ writable: true,
+ configurable: true
+});
+verifyProperty(groups, "b", {
+ enumerable: true,
+ writable: true,
+ configurable: true
+});
+verifyProperty(groups, "c", {
+ enumerable: true,
+ writable: true,
+ configurable: true
+});
+
+// "๐" is U+1d401 MATHEMATICAL BOLD CAPITAL B
+// - Also representable as the code point "\u{1d401}"
+// - Also representable as the surrogate pair "\uD835\uDC01"
+
+// Verify assumptions:
+assertSameValue("๐".length, 2, 'The length of "๐" is 2');
+assertSameValue("\u{1d401}".length, 2, 'The length of "\\u{1d401}" is 2');
+assertSameValue("\uD835\uDC01".length, 2, 'The length of "\\uD835\\uDC01" is 2');
+assertSameValue("๐".match(/./)[0].length, 1, 'The length of a single code unit match against "๐" is 1 (without /u flag)');
+assertSameValue("\u{1d401}".match(/./)[0].length, 1, 'The length of a single code unit match against "\\u{1d401}" is 1 (without /u flag)');
+assertSameValue("\uD835\uDC01".match(/./)[0].length, 1, 'The length of a single code unit match against "\\ud835\\udc01" is 1 (without /u flag)');
+
+assertCompareArray([0, 1], "๐".match(/./d).indices[0], 'Indices for non-unicode match against "๐" (without /u flag)');
+assertCompareArray([0, 1], "\u{1d401}".match(/./d).indices[0], 'Indices for non-unicode match against "\\u{1d401}" (without /u flag)');
+assertCompareArray([0, 1], "\uD835\uDC01".match(/./d).indices[0], 'Indices for non-unicode match against "\\ud835\\udc01" (without /u flag)');
+assertCompareArray([0, 1], "๐".match(/(?<a>.)/d).indices.groups.a, 'Indices for non-unicode match against "๐" in groups.a (without /u flag)');
+assertCompareArray([0, 1], "\u{1d401}".match(/(?<a>.)/d).indices.groups.a, 'Indices for non-unicode match against "\\u{1d401}" in groups.a (without /u flag)');
+assertCompareArray([0, 1], "\uD835\uDC01".match(/(?<a>.)/d).indices.groups.a, 'Indices for non-unicode match against "\\ud835\\udc01" in groups.a (without /u flag)');
Added: trunk/JSTests/stress/test262-indices-array-properties.js (0 => 273160)
--- trunk/JSTests/stress/test262-indices-array-properties.js (rev 0)
+++ trunk/JSTests/stress/test262-indices-array-properties.js 2021-02-19 20:50:48 UTC (rev 273160)
@@ -0,0 +1,38 @@
+// Copyright 2019 Ron Buckton. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: The properties of the "indices" array are created with CreateDataProperty.
+includes: [propertyHelper.js]
+esid: sec-makeindicesarray
+features: [regexp-match-indices]
+info: |
+ MakeIndicesArray ( S, indices, groupNames, hasGroups )
+ 13. For each integer _i_ such that _i_ >= 0 and _i_ < _n_, do
+ d. Perform ! CreateDataProperty(_A_, ! ToString(_n_), _matchIndicesArray_).
+---*/
+
+let input = "abcd";
+let match = /b(c)/d.exec(input);
+let indices = match.indices;
+
+function verifyProperty(obj, prop, expect)
+{
+ let desc = Object.getOwnPropertyDescriptor(obj, prop);
+
+ for (const [key, value] of Object.entries(expect))
+ if (desc[key] != value)
+ throw "obj." + prop + " " + key + ": is not " + value;
+}
+
+verifyProperty(indices, '0', {
+ enumerable: true,
+ configurable: true,
+ writable: true
+});
+
+verifyProperty(indices, '1', {
+ enumerable: true,
+ configurable: true,
+ writable: true
+});
Added: trunk/JSTests/stress/test262-indices-array-unicode-match.js (0 => 273160)
--- trunk/JSTests/stress/test262-indices-array-unicode-match.js (rev 0)
+++ trunk/JSTests/stress/test262-indices-array-unicode-match.js 2021-02-19 20:50:48 UTC (rev 273160)
@@ -0,0 +1,137 @@
+// Copyright 2019 Ron Buckton. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Basic matching cases with non-unicode matches.
+includes: [compareArray.js, propertyHelper.js, deepEqual.js]
+esid: sec-regexpbuiltinexec
+features: [regexp-match-indices]
+info: |
+ Runtime Semantics: RegExpBuiltinExec ( R, S )
+ ...
+ 4. Let _lastIndex_ be ? ToLength(? Get(_R_, `"lastIndex")).
+ ...
+ 16. If _fullUnicode_ is *true*, set _e_ to ! GetStringIndex(_S_, _Input_, _e_).
+ ...
+ 26. Let _match_ be the Match { [[StartIndex]]: _lastIndex_, [[EndIndex]]: _e_ }.
+ 27. Let _indices_ be a new empty List.
+ ...
+ 29. Add _match_ as the last element of _indices_.
+ ...
+ 35. For each integer _i_ such that _i_ > 0 and _i_ <= _n_, in ascending order, do
+ ...
+ f. Else,
+ i. Let _captureStart_ be _captureI_'s _startIndex_.
+ ii. Let _captureEnd_ be _captureI_'s _endIndex_.
+ iii. If _fullUnicode_ is *true*, then
+ 1. Set _captureStart_ to ! GetStringIndex(_S_, _Input_, _captureStart_).
+ 1. Set _captureEnd_ to ! GetStringIndex(_S_, _Input_, _captureEnd_).
+ iv. Let _capture_ be the Match { [[StartIndex]]: _captureStart_, [[EndIndex]]: _captureEnd_ }.
+ v. Append _capture_ to _indices_.
+ ...
+ 36. If _hasIndices_ is *true*, then
+ a. Let _indicesArray_ be MakeIndicesArray(_S_, _indices_, _groupNames_, _hasGroups_).
+ b. Perform ! CreateDataProperty(_A_, `"indices"`, _indicesArray_).
+
+ GetStringIndex ( S, Input, e )
+ ...
+ 4. Let _eUTF_ be the smallest index into _S_ that corresponds to the character at element _e_ of _Input_. If _e_ is greater than or equal to the number of elements in _Input_, then _eUTF_ is the number of code units in _S_.
+ 5. Return _eUTF_.
+---*/
+
+function assertSameValue(a, b)
+{
+ if (a !== b)
+ throw "Values not same";
+}
+
+function assertCompareArray(a, b)
+{
+ if (!a instanceof Array)
+ throw "a not array";
+
+ if (!b instanceof Array)
+ throw "b not array";
+
+ if (a.length !== b.length)
+ throw "Arrays differ in length";
+
+ for (let i = 0; i < a.length; ++i)
+ if (a[i] !== b[i])
+ throw "Array element " + i + " differ";
+}
+
+function assertDeepEqual(a, b)
+{
+ if (!a instanceof Array)
+ throw "a not array";
+
+ if (!b instanceof Array)
+ throw "b not array";
+
+ if (a.length !== b.length)
+ throw "Arrays differ in length";
+
+ for (let i = 0; i < a.length; ++i) {
+ if (a[i] instanceof Array)
+ assertDeepEqual(a[i], b[i]);
+ else if (a[i] !== b[i])
+ throw "Array element " + i + " differ";
+ }
+}
+
+function verifyProperty(obj, prop, expect)
+{
+ let desc = Object.getOwnPropertyDescriptor(obj, prop);
+
+ for (const [key, value] of Object.entries(expect))
+ if (desc[key] != value)
+ throw "obj." + prop + " " + key + ": is not " + value;
+}
+
+assertDeepEqual([[1, 2], [1, 2]], "bab".match(/(a)/du).indices);
+assertDeepEqual([[0, 3], [1, 2]], "bab".match(/.(a)./du).indices);
+assertDeepEqual([[0, 3], [1, 2], [2, 3]], "bab".match(/.(a)(.)/du).indices);
+assertDeepEqual([[0, 3], [1, 3]], "bab".match(/.(\w\w)/du).indices);
+assertDeepEqual([[0, 3], [0, 3]], "bab".match(/(\w\w\w)/du).indices);
+assertDeepEqual([[0, 3], [0, 2], [2, 3]], "bab".match(/(\w\w)(\w)/du).indices);
+assertDeepEqual([[0, 2], [0, 2], undefined], "bab".match(/(\w\w)(\W)?/du).indices);
+
+let groups = /(?<a>.)(?<b>.)(?<c>.)\k<c>\k<b>\k<a>/du.exec("abccba").indices.groups;
+assertCompareArray([0, 1], groups.a);
+assertCompareArray([1, 2], groups.b);
+assertCompareArray([2, 3], groups.c);
+verifyProperty(groups, "a", {
+ enumerable: true,
+ writable: true,
+ configurable: true
+});
+verifyProperty(groups, "b", {
+ enumerable: true,
+ writable: true,
+ configurable: true
+});
+verifyProperty(groups, "c", {
+ enumerable: true,
+ writable: true,
+ configurable: true
+});
+
+// "๐" is U+1d401 MATHEMATICAL BOLD CAPITAL B
+// - Also representable as the code point "\u{1d401}"
+// - Also representable as the surrogate pair "\uD835\uDC01"
+
+// Verify assumptions:
+assertSameValue("๐".length, 2, 'The length of "๐" is 2');
+assertSameValue("\u{1d401}".length, 2, 'The length of "\\u{1d401}" is 2');
+assertSameValue("\uD835\uDC01".length, 2, 'The length of "\\uD835\\uDC01" is 2');
+assertSameValue(2, "๐".match(/./u)[0].length, 'The length of a single code point match against "๐" is 2 (with /du flag)');
+assertSameValue(2, "\u{1d401}".match(/./u)[0].length, 'The length of a single code point match against "\\u{1d401}" is 2 (with /du flag)');
+assertSameValue(2, "\uD835\uDC01".match(/./u)[0].length, 'The length of a single code point match against "\\ud835\\udc01" is 2 (with /du flag)');
+
+assertCompareArray([0, 2], "๐".match(/./du).indices[0], 'Indices for unicode match against "๐" (with /du flag)');
+assertCompareArray([0, 2], "\u{1d401}".match(/./du).indices[0], 'Indices for unicode match against \\u{1d401} (with /du flag)');
+assertCompareArray([0, 2], "\uD835\uDC01".match(/./du).indices[0], 'Indices for unicode match against \\ud835\\udc01 (with /du flag)');
+assertCompareArray([0, 2], "๐".match(/(?<a>.)/du).indices.groups.a, 'Indices for unicode match against ๐ in groups.a (with /du flag)');
+assertCompareArray([0, 2], "\u{1d401}".match(/(?<a>.)/du).indices.groups.a, 'Indices for unicode match against \\u{1d401} in groups.a (with /du flag)');
+assertCompareArray([0, 2], "\uD835\uDC01".match(/(?<a>.)/du).indices.groups.a, 'Indices for unicode match against \\ud835\\udc01 in groups.a (with /du flag)');
Added: trunk/JSTests/stress/test262-indices-array-unicode-property-names.js (0 => 273160)
--- trunk/JSTests/stress/test262-indices-array-unicode-property-names.js (rev 0)
+++ trunk/JSTests/stress/test262-indices-array-unicode-property-names.js 2021-02-19 20:50:48 UTC (rev 273160)
@@ -0,0 +1,36 @@
+// Copyright 2019 Ron Buckton. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Basic matching cases with non-unicode matches.
+includes: [compareArray.js]
+esid: sec-makeindicesarray
+features: [regexp-match-indices]
+---*/
+
+function assertCompareArray(a, b)
+{
+ if (!a instanceof Array)
+ throw "a not array";
+
+ if (!b instanceof Array)
+ throw "b not array";
+
+ if (a.length !== b.length)
+ throw "Arrays differ in length";
+
+ for (let i = 0; i < a.length; ++i)
+ if (a[i] !== b[i])
+ throw "Array element " + i + " differ";
+}
+
+assertCompareArray([1, 2], /(?<ฯ>a)/du.exec("bab").indices.groups.ฯ);
+assertCompareArray([1, 2], /(?<\u{03C0}>a)/du.exec("bab").indices.groups.ฯ);
+assertCompareArray([1, 2], /(?<ฯ>a)/du.exec("bab").indices.groups.\u03C0);
+assertCompareArray([1, 2], /(?<\u{03C0}>a)/du.exec("bab").indices.groups.\u03C0);
+assertCompareArray([1, 2], /(?<$>a)/du.exec("bab").indices.groups.$);
+assertCompareArray([1, 2], /(?<_>a)/du.exec("bab").indices.groups._);
+assertCompareArray([1, 2], /(?<$๐ค>a)/du.exec("bab").indices.groups.$๐ค);
+assertCompareArray([1, 2], /(?<_\u200C>a)/du.exec("bab").indices.groups._\u200C);
+assertCompareArray([1, 2], /(?<_\u200D>a)/du.exec("bab").indices.groups._\u200D);
+assertCompareArray([1, 2], /(?<เฒ _เฒ >a)/du.exec("bab").indices.groups.เฒ _เฒ );
Added: trunk/JSTests/stress/test262-indices-array-unmatched.js (0 => 273160)
--- trunk/JSTests/stress/test262-indices-array-unmatched.js (rev 0)
+++ trunk/JSTests/stress/test262-indices-array-unmatched.js 2021-02-19 20:50:48 UTC (rev 273160)
@@ -0,0 +1,38 @@
+// Copyright 2019 Ron Buckton. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: An unmatched capture in a match corresponds to an unmatched capture in "indices"
+esid: sec-makeindicesarray
+features: [regexp-match-indices]
+info: |
+ MakeIndicesArray ( S, indices, groupNames )
+ 4. Let _n_ be the number of elements in _indices_.
+ ...
+ 6. Set _A_ to ! ArrayCreate(_n_).
+ ...
+ 11. For each integer _i_ such that _i_ >= 0 and _i_ < _n_, do
+ a. Let _matchIndices_ be _indices_[_i_].
+ b. If _matchIndices_ is not *undefined*, then
+ i. Let _matchIndicesArray_ be ! GetMatchIndicesArray(_S_, _matchIndices_).
+ c. Else,
+ i. Let _matchIndicesArray_ be *undefined*.
+ d. Perform ! CreateDataProperty(_A_, ! ToString(_n_), _matchIndicesArray_).
+ ...
+---*/
+
+function assertSameValue(a, b)
+{
+ if (a !== b)
+ throw "Values not same";
+}
+
+let input = "abd";
+let match = /b(c)?/d.exec(input);
+let indices = match.indices;
+
+// `indices` has the same length as match
+assertSameValue(indices.length, match.length);
+
+// The second element of `indices` should be undefined.
+assertSameValue(indices[1], undefined);
Added: trunk/JSTests/stress/test262-indices-array.js (0 => 273160)
--- trunk/JSTests/stress/test262-indices-array.js (rev 0)
+++ trunk/JSTests/stress/test262-indices-array.js 2021-02-19 20:50:48 UTC (rev 273160)
@@ -0,0 +1,30 @@
+// Copyright 2019 Ron Buckton. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: The "indices" property is an Array.
+esid: sec-makeindicesarray
+features: [regexp-match-indices]
+info: |
+ MakeIndicesArray ( S, indices, groupNames, hasGroups )
+ 6. Set _A_ to ! ArrayCreate(_n_).
+---*/
+
+function assert(a)
+{
+ if (!a)
+ throw "Values not true";
+}
+
+function assertSameValue(a, b)
+{
+ if (a !== b)
+ throw "Values not same";
+}
+
+let match = /a/d.exec("a");
+let indices = match.indices;
+
+// `indices` is an array
+assertSameValue(Object.getPrototypeOf(indices), Array.prototype);
+assert(Array.isArray(indices));
Added: trunk/JSTests/stress/test262-indices-groups-object-undefined.js (0 => 273160)
--- trunk/JSTests/stress/test262-indices-groups-object-undefined.js (rev 0)
+++ trunk/JSTests/stress/test262-indices-groups-object-undefined.js 2021-02-19 20:50:48 UTC (rev 273160)
@@ -0,0 +1,34 @@
+// Copyright 2019 Ron Buckton. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: The groups object of indices is created unconditionally.
+includes: [propertyHelper.js]
+esid: sec-makeindicesarray
+features: [regexp-named-groups, regexp-match-indices]
+info: |
+ MakeIndicesArray ( S, indices, groupNames, hasGroups )
+ 10. If _hasGroups_ is *true*, then
+ a. Let _groups_ be ! ObjectCreate(*null*).
+ 11. Else,
+ a. Let _groups_ be *undefined*.
+ 12. Perform ! CreateDataProperty(_A_, `"groups"`, _groups_).
+---*/
+
+function verifyProperty(obj, prop, expect)
+{
+ let desc = Object.getOwnPropertyDescriptor(obj, prop);
+
+ for (const [key, value] of Object.entries(expect))
+ if (desc[key] != value)
+ throw "obj." + prop + " " + key + ": is not " + value;
+}
+
+const re = /./d;
+const indices = re.exec("a").indices;
+verifyProperty(indices, 'groups', {
+ writable: true,
+ enumerable: true,
+ configurable: true,
+ value: undefined
+});
Added: trunk/JSTests/stress/test262-indices-groups-object-unmatched.js (0 => 273160)
--- trunk/JSTests/stress/test262-indices-groups-object-unmatched.js (rev 0)
+++ trunk/JSTests/stress/test262-indices-groups-object-unmatched.js 2021-02-19 20:50:48 UTC (rev 273160)
@@ -0,0 +1,41 @@
+// Copyright 2019 Ron Buckton. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Test the groups object of indices with matched and unmatched named captures.
+includes: [compareArray.js]
+esid: sec-makeindicesarray
+features: [regexp-named-groups, regexp-match-indices]
+info: |
+ MakeIndicesArray ( S, indices, groupNames, hasGroups )
+ 11. For each integer _i_ such that _i_ >= 0 and _i_ < _n_, do
+ e. If _i_ > 0 and _groupNames_[_i_ - 1] is not *undefined*, then
+ i. Perform ! CreateDataProperty(_groups_, _groupNames_[_i_ - 1], _matchIndicesArray_).
+---*/
+
+function assertSameValue(a, b)
+{
+ if (a !== b)
+ throw "Values not same";
+}
+
+function assertCompareArray(a, b)
+{
+ if (!a instanceof Array)
+ throw "a not array";
+
+ if (!b instanceof Array)
+ throw "b not array";
+
+ if (a.length !== b.length)
+ throw "Arrays differ in length";
+
+ for (let i = 0; i < a.length; ++i)
+ if (a[i] !== b[i])
+ throw "Array element " + i + " differ";
+}
+
+const re = /(?<a>a).|(?<x>x)/d;
+const result = re.exec("ab").indices;
+assertCompareArray([0, 1], result.groups.a);
+assertSameValue(undefined, result.groups.x);
Added: trunk/JSTests/stress/test262-indices-groups-object.js (0 => 273160)
--- trunk/JSTests/stress/test262-indices-groups-object.js (rev 0)
+++ trunk/JSTests/stress/test262-indices-groups-object.js 2021-02-19 20:50:48 UTC (rev 273160)
@@ -0,0 +1,70 @@
+// Copyright 2019 Ron Buckton. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: The groups object of indices is created with CreateDataProperty
+includes: [propertyHelper.js, compareArray.js]
+esid: sec-makeindicesarray
+features: [regexp-named-groups, regexp-match-indices]
+info: |
+ MakeIndicesArray ( S, indices, groupNames, hasIndices )
+ 10. If _hasIndices_ is *true*, then
+ a. Let _groups_ be ! ObjectCreate(*null*).
+ 11. Else,
+ a. Let _groups_ be *undefined*.
+ 12. Perform ! CreateDataProperty(_A_, `"groups"`, _groups_).
+---*/
+
+function assertSameValue(a, b)
+{
+ if (a !== b)
+ throw "Values not same";
+}
+
+function assertCompareArray(a, b)
+{
+ if (!a instanceof Array)
+ throw "a not array";
+
+ if (!b instanceof Array)
+ throw "b not array";
+
+ if (a.length !== b.length)
+ throw "Arrays differ in length";
+
+ for (let i = 0; i < a.length; ++i)
+ if (a[i] !== b[i])
+ throw "Array element " + i + " differ";
+}
+
+function verifyProperty(obj, prop, expect)
+{
+ let desc = Object.getOwnPropertyDescriptor(obj, prop);
+
+ for (const [key, value] of Object.entries(expect))
+ if (desc[key] != value)
+ throw "obj." + prop + " " + key + ": is not " + value;
+}
+
+// `groups` is created with Define, not Set.
+let counter = 0;
+Object.defineProperty(Array.prototype, "groups", {
+ set() { counter++; }
+});
+
+let indices = /(?<x>.)/d.exec("a").indices;
+assertSameValue(counter, 0);
+
+// `groups` is writable, enumerable and configurable
+// (from CreateDataProperty).
+verifyProperty(indices, 'groups', {
+ writable: true,
+ enumerable: true,
+ configurable: true
+});
+
+// The `__proto__` property on the groups object is not special,
+// and does not affect the [[Prototype]] of the resulting groups object.
+let {groups} = /(?<__proto__>.)/d.exec("a").indices;
+assertCompareArray([0, 1], groups.__proto__);
+assertSameValue(null, Object.getPrototypeOf(groups));
Added: trunk/JSTests/stress/test262-indices-groups-properties.js (0 => 273160)
--- trunk/JSTests/stress/test262-indices-groups-properties.js (rev 0)
+++ trunk/JSTests/stress/test262-indices-groups-properties.js 2021-02-19 20:50:48 UTC (rev 273160)
@@ -0,0 +1,59 @@
+// Copyright 2019 Ron Buckton. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Properties of the groups object of indices are created with CreateDataProperty
+includes: [compareArray.js, propertyHelper.js]
+esid: sec-makeindicesarray
+features: [regexp-named-groups, regexp-match-indices]
+info: |
+ MakeIndicesArray ( S, indices, groupNames, hasIndices )
+ 13. For each integer _i_ such that _i_ >= 0 and _i_ < _n_, do
+ e. If _i_ > 0 and _groupNames_[_i_ - 1] is not *undefined*, then
+ i. Perform ! CreateDataProperty(_groups_, _groupNames_[_i_ - 1], _matchIndicesArray_).
+---*/
+
+function assertCompareArray(a, b)
+{
+ if (!a instanceof Array)
+ throw "a not array";
+
+ if (!b instanceof Array)
+ throw "b not array";
+
+ if (a.length !== b.length)
+ throw "Arrays differ in length";
+
+ for (let i = 0; i < a.length; ++i)
+ if (a[i] !== b[i])
+ throw "Array element " + i + " differ";
+}
+
+function verifyProperty(obj, prop, expect)
+{
+ let desc = Object.getOwnPropertyDescriptor(obj, prop);
+
+ for (const [key, value] of Object.entries(expect))
+ if (desc[key] != value)
+ throw "obj." + prop + " " + key + ": is not " + value;
+}
+
+// Properties created on result.groups in textual order.
+let groupNames = Object.getOwnPropertyNames(/(?<fst>.)|(?<snd>.)/du.exec("abcd").indices.groups);
+assertCompareArray(groupNames, ["fst", "snd"]);
+
+// // Properties are created with Define, not Set
+// let counter = 0;
+// Object.defineProperty(Object.prototype, 'x', {set() { counter++; }});
+
+let indices = /(?<x>.)/d.exec('a').indices;
+let groups = indices.groups;
+// assert.sameValue(counter, 0);
+
+// Properties are writable, enumerable and configurable
+// (from CreateDataProperty)
+verifyProperty(groups, 'x', {
+ writable: true,
+ enumerable: true,
+ configurable: true
+});
Added: trunk/JSTests/stress/test262-indices-property.js (0 => 273160)
--- trunk/JSTests/stress/test262-indices-property.js (rev 0)
+++ trunk/JSTests/stress/test262-indices-property.js 2021-02-19 20:50:48 UTC (rev 273160)
@@ -0,0 +1,47 @@
+// Copyright 2019 Ron Buckton. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: The "indices" property is created with DefinePropertyOrThrow
+includes: [propertyHelper.js]
+esid: sec-regexpbuiltinexec
+features: [regexp-match-indices]
+info: |
+ Runtime Semantics: RegExpBuiltinExec ( R, S )
+ 8. If _flags_ contains `"d"`, let _hasIndices_ be *true*, else let _hasIndices_ be *false*.
+ ...
+ 36. If _hasIndices_ is *true*, then
+ a. Let _indicesArray_ be MakeIndicesArray(_S_, _indices_, _groupNames_, _hasGroups_).
+ b. Perform ! CreateDataProperty(_A_, `"indices"`, _indicesArray_).
+---*/
+
+function assertSameValue(a, b)
+{
+ if (a !== b)
+ throw "Values not same";
+}
+
+function verifyProperty(obj, prop, expect)
+{
+ let desc = Object.getOwnPropertyDescriptor(obj, prop);
+
+ for (const [key, value] of Object.entries(expect))
+ if (desc[key] != value)
+ throw "obj." + prop + " " + key + ": is not " + value;
+}
+
+// `indices` is created with Define, not Set.
+let counter = 0;
+Object.defineProperty(Array.prototype, "indices", {
+ set() { counter++; }
+});
+
+let match = /a/d.exec("a");
+assertSameValue(counter, 0);
+
+// `indices` is a non-writable, non-enumerable, and configurable data-property.
+verifyProperty(match, 'indices', {
+ writable: true,
+ enumerable: true,
+ configurable: true
+});
Modified: trunk/JSTests/test262/config.yaml (273159 => 273160)
--- trunk/JSTests/test262/config.yaml 2021-02-19 20:47:53 UTC (rev 273159)
+++ trunk/JSTests/test262/config.yaml 2021-02-19 20:50:48 UTC (rev 273160)
@@ -23,7 +23,10 @@
- cleanupSome
- host-gc-required
- # https://bugs.webkit.org/show_bug.cgi?id=202475
+
+ # FIXME: https://bugs.webkit.org/show_bug.cgi?id=222142
+ - regexp-match-indices
+
- top-level-await
paths:
files:
Modified: trunk/Source/_javascript_Core/ChangeLog (273159 => 273160)
--- trunk/Source/_javascript_Core/ChangeLog 2021-02-19 20:47:53 UTC (rev 273159)
+++ trunk/Source/_javascript_Core/ChangeLog 2021-02-19 20:50:48 UTC (rev 273160)
@@ -1,3 +1,18 @@
+2021-02-19 Michael Saboff <msab...@apple.com>
+
+ Minor fixes to RegExp match indices after r273086
+ https://bugs.webkit.org/show_bug.cgi?id=222157
+
+ Reviewed by Yusuke Suzuki.
+
+ When hasIndices is true, but there aren't any named groups, the spec says that we should
+ create the indices.groups property is the value undefined.
+ Increased the size of FlagsString to 7 plus terminater to account for the new 'd' flags.
+
+ * runtime/RegExpMatchesArray.h:
+ (JSC::createRegExpMatchesArray):
+ * runtime/RegExpPrototype.cpp:
+
2021-02-19 Yusuke Suzuki <ysuz...@apple.com>
[JSC] Do not use toObject for options in new Intl constructors
Modified: trunk/Source/_javascript_Core/runtime/RegExpMatchesArray.h (273159 => 273160)
--- trunk/Source/_javascript_Core/runtime/RegExpMatchesArray.h 2021-02-19 20:47:53 UTC (rev 273159)
+++ trunk/Source/_javascript_Core/runtime/RegExpMatchesArray.h 2021-02-19 20:50:48 UTC (rev 273160)
@@ -106,7 +106,7 @@
Structure* indicesStructure = globalObject->regExpMatchesIndicesArrayStructure();
- indicesArray->putDirect(vm, RegExpMatchesIndicesGroupsPropertyOffset, indicesGroups);
+ indicesArray->putDirect(vm, RegExpMatchesIndicesGroupsPropertyOffset, indicesGroups ? indicesGroups : jsUndefined());
ASSERT(!indicesArray->butterfly()->indexingHeader()->preCapacity(indicesStructure));
auto indicesCapacity = indicesStructure->outOfLineCapacity();
Modified: trunk/Source/_javascript_Core/runtime/RegExpPrototype.cpp (273159 => 273160)
--- trunk/Source/_javascript_Core/runtime/RegExpPrototype.cpp 2021-02-19 20:47:53 UTC (rev 273159)
+++ trunk/Source/_javascript_Core/runtime/RegExpPrototype.cpp 2021-02-19 20:50:48 UTC (rev 273160)
@@ -162,7 +162,7 @@
return JSValue::encode(thisRegExp);
}
-typedef std::array<char, 6 + 1> FlagsString; // 6 different flags and a null character terminator.
+typedef std::array<char, 7 + 1> FlagsString; // 6 different flags and a null character terminator.
static inline FlagsString flagsString(JSGlobalObject* globalObject, JSObject* regexp)
{