Skip to content

Instantly share code, notes, and snippets.

@peterwmwong
Created February 24, 2018 04:15
Show Gist options
  • Save peterwmwong/3928b67c9e1aee8071c89d93d4f74d66 to your computer and use it in GitHub Desktop.
Save peterwmwong/3928b67c9e1aee8071c89d93d4f74d66 to your computer and use it in GitHub Desktop.
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
new file mode 100644
index 000000000..544721e31
--- /dev/null
+++ b/.vscode/tasks.json
@@ -0,0 +1,15 @@
+{
+ "version": "2.0.0",
+ "tasks": [
+ {
+ "label": "build",
+ "type": "shell",
+ "command":
+ "clear; cd /p/google/v8 && /p/google/v8/out.gn/x64.optdebug/d8 test/test262/data/harness/sta.js test/test262/data/harness/assert.js test/test262/harness-adapt.js test/test262/data/harness/propertyHelper.js ${file} && echo PASSED",
+ "group": {
+ "kind": "build",
+ "isDefault": true
+ }
+ }
+ ]
+}
diff --git a/pww-todo.md b/pww-todo.md
new file mode 100644
index 000000000..0a13614ab
--- /dev/null
+++ b/pww-todo.md
@@ -0,0 +1,7 @@
+Verify:
+- Author is "Peter Wong"
+- Copyright is "2018"
+- esid is "pending"
+
+Replace after everything is working:
+- var -> const/let
diff --git a/string-prototype-matchall-spec-signoff.md b/string-prototype-matchall-spec-signoff.md
new file mode 100644
index 000000000..232da2eee
--- /dev/null
+++ b/string-prototype-matchall-spec-signoff.md
@@ -0,0 +1,185 @@
+# String.prototype.matchAll ( *regexp* )</h1>
+
+Performs a regular expression match of the String representing the **this** value against *regexp* and returns an iterator. Each iteration result’s value is an Array object containing the results of the match, or **null** if the String did not match.
+
+When the `matchAll` method is called, the following steps are taken:
+ 1. Let *O* be ? [RequireObjectCoercible][require-object-coercible](**this** value).
+ - SPEC: String/prototype/matchAll/this-is-null-throws.js
+ - SPEC: String/prototype/matchAll/this-is-undefined-throws.js
+ 1. If ? [IsRegExp][isregexp](*regexp*) is **true**, then
+ - SPEC: String/prototype/matchAll/return-abrupt-from-regexp-isregexp.js
+ 1. Let *R* be *regexp*.
+ 1. Else,
+ 1. Let *R* be [RegExpCreate][regexp-create](*regexp*, **undefined**).
+ - SPEC: String/prototype/matchAll/tostring-throws.js
+ 1. Let *matcher* be ? [GetMethod][getmethod](*R*, @@matchAll).
+ - SPEC: String/prototype/matchAll/invoke-regexp-matchAll-throws.js
+ - SPEC: String/prototype/matchAll/invoke-internal-regexp-matchAll-throws.js
+ 1. If *matcher* is not **undefined**, then
+ 1. Return ? [Call](call)(*matcher*, *R*, &laquo; *O* &raquo;).
+ - SPEC: String/prototype/matchAll/invoke-internal-regexp-matchAll.js
+ - SPEC: String/prototype/matchAll/invoke-regexp-matchAll.js
+ 1. Return ? [MatchAllIterator](#matchalliterator)(*R*, *O*).
+ - SPEC: String/prototype/matchAll/invoke-internal-regexp-has-no-matchAll
+ - SPEC: String/prototype/matchAll/invoke-regexp-has-no-matchAll
+
+Note 1: The `matchAll` function is intentionally generic, it does not require that its *this* value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.
+Note 2: Similarly to `String.prototype.split`, `String.prototype.matchAll` is designed to typically act without mutating its inputs.
+
+# RegExp.prototype[ @@matchAll ] ( *string* )
+
+When the `@@matchAll` method is called with argument *string*, the following steps are taken:
+ 1. Let *R* be the **this** value.
+ 1. Return ? [MatchAllIterator](#matchalliterator)(*R*, *string*).
+
+The value of the name property of this function is "[Symbol.matchAll]".
+
+# MatchAllIterator ( *R*, *O* )
+
+The abstract operation *MatchAllIterator* performs the following steps:
+ 1. If ? [IsRegExp][isregexp](*R*) is not **true**, throw a **TypeError** exception.
+ 1. Let *S* be ? [ToString][to-string](*O*).
+ 1. Let *C* be ? [SpeciesConstructor][species-constructor](*R*, %RegExp%).
+ 1. Let *flags* be ? [ToString][tostring](? [Get][get](*R*, **"flags"**)).
+ 1. Let *matcher* be ? [Construct][construct](*C*, « *R*, *flags* »).
+ 1. Let *global* be ? [ToBoolean][to-boolean](? [Get][get](*matcher*, **"global"**)).
+ 1. Let *fullUnicode* be ? [ToBoolean][to-boolean](? [Get][get](*matcher*, **"unicode"**)).
+ 1. Let *lastIndex* be ? [ToLength][tolength](? [Get][get](*R*, **"lastIndex"**)).
+ 1. Perform ? [Set][set](*matcher*, **"lastIndex"**, *lastIndex*, **true**).
+ 1. Return ! [CreateRegExpStringIterator](#createregexpstringiterator-abstract-operation)(*matcher*, *S*, *global*, *fullUnicode*).
+
+## CreateRegExpStringIterator( *R*, *S*, *global*, *fullUnicode* )
+
+The abstract operation *CreateRegExpStringIterator* is used to create such iterator objects. It performs the following steps:
+ 1. Assert: [Type][type](*S*) is String.
+ 1. Assert: [Type][type](*global*) is Boolean.
+ 1. Assert: [Type][type](*unicode*) is Boolean.
+ 1. Let *iterator* be ObjectCreate(<emu-xref href="#%RegExpStringIteratorPrototype%">%RegExpStringIteratorPrototype%</emu-xref>, « [[IteratedString]], [[IteratingRegExp]], [[Done]] »).
+ 1. Set *iterator*.[[IteratingRegExp]] to *R*.
+ 1. Set *iterator*.[[IteratedString]] to *S*.
+ 1. Set *iterator*.[[Global]] to *global*.
+ 1. Set *iterator*.[[Unicode]] to *fullUnicode*.
+ 1. Set *iterator*.[[Done]] to **true**.
+ 1. Return *iterator*.
+
+### The %RegExpStringIteratorPrototype% Object
+
+All RegExp String Iterator Objects inherit properties from the [%RegExpStringIteratorPrototype%](#the-regexpstringiteratorprototype-object) intrinsic object. The %RegExpStringIteratorPrototype% object is an ordinary object and its [[Prototype]] [internal slot][internal-slot] is the [%IteratorPrototype%][iterator-prototype] intrinsic object</a>. In addition, %RegExpStringIteratorPrototype% has the following properties:
+
+#### %RegExpStringIteratorPrototype%.next ( )
+ 1. Let O be the **this** value.
+ 1. If [Type][type](O) is not Object, throw a **TypeError** exception.
+ 1. If O does not have all of the internal slots of a RegExp String Iterator Object Instance (see [here](#PropertiesOfRegExpStringIteratorInstances)), throw a **TypeError** exception.
+ 1. If *O*.[[Done]] is **true**, then
+ 1. Return ! [CreateIterResultObject][create-iter-result-object](**null**, **true**).
+ 1. Let *R* be *O*.[[IteratingRegExp]].
+ 1. Let *S* be *O*.[[IteratedString]].
+ 1. Let *global* be *O*.[[Global]].
+ 1. Let *fullUnicode* be *O*.[[Unicode]].
+ 1. Let *match* be ? [RegExpExec][regexp-exec](*R*, *S*).
+ 1. If *match* is **null**, then
+ 1. Set *O*.[[Done]] to **true**.
+ 1. Return ! [CreateIterResultObject][create-iter-result-object](**null**, **true**).
+ 1. Else,
+ 1. If *global* is **true**,
+ 1. Let *matchStr* be ? [ToString][to-string](? [Get][get](*match*, **"0"**)).
+ 1. If *matchStr* is the empty string,
+ 1. Let *thisIndex* be ? [ToLength][tolength](? [Get][get](*R*, **"lastIndex"**).
+ 1. Let *nextIndex* be ! AdvanceStringIndex(*S*, *thisIndex*, *fullUnicode*).
+ 1. Perform ? [Set][set](*R*, **"lastIndex"**, *nextIndex*, **true**).
+ 1. Return ! [CreateIterResultObject][create-iter-result-object](*match*, **false**).
+ 1. Else,
+ 1. Set *O*.[[Done]] to **true**.
+ 1. Return ! [CreateIterResultObject][create-iter-result-object](_match_, **false**).
+
+#### %RegExpStringIteratorPrototype%[ @@toStringTag ]
+
+The initial value of the _@@toStringTag_ property is the String value **"RegExp String Iterator"**.</p>
+This property has the attributes { [[Writable]]: **false**, [[Enumerable]]: **false**, [[Configurable]]: **true** }.</p>
+
+#### Properties of RegExp String Iterator Instances</h1>
+
+RegExp String Iterator instances are ordinary objects that inherit properties from the [%RegExpStringIteratorPrototype%](#%RegExpStringIteratorPrototype%) intrinsic object. RegExp String Iterator instances are initially created with the internal slots listed in <a href="#table-1">Table 1</a>.</p>
+
+<figure>
+ <figcaption><span id="table-1">Table 1</span> — Internal Slots of RegExp String Iterator Instances</figcaption>
+ <table class="real-table">
+ <tbody>
+ <tr>
+ <th>Internal Slot</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>[[IteratingRegExp]]</td>
+ <td>The regular expression used for iteration. [IsRegExp][isregexp]([[IteratingRegExp]]) is always initially true.</td>
+ </tr>
+ <tr>
+ <td>[[IteratedString]]</td>
+ <td>The String value being iterated upon.</td>
+ </tr>
+ <tr>
+ <td>[[Global]]</td>
+ <td>A Boolean value to indicate whether the [[IteratingRegExp]] is global or not.</td>
+ </tr>
+ <tr>
+ <td>[[Unicode]]</td>
+ <td>A Boolean value to indicate whether the [[IteratingRegExp]] is in Unicode mode or not.</td>
+ </tr>
+ <tr>
+ <td>[[Done]]</td>
+ <td>A Boolean value to indicate whether the iteration is complete or not.</td>
+ </tr>
+ </tbody>
+ </table>
+</figure>
+
+# Symbol.matchAll
+
+The initial value of *Symbol.matchAll* is the well-known symbol @@matchAll
+
+This property has the attributes { [[Writable]]: **false**, [[Enumerable]]: **false**, [[Configurable]]: **false** }.
+
+# Well-Known Symbols
+
+<figure>
+ <figcaption>Table 1: Well-known Symbols</figcaption>
+ <table>
+ <thead>
+ <tr>
+ <th>Specification Name</th>
+ <th>[[Description]]</th>
+ <th>Value and Purpose</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td colspan="3">insert after @@match</td>
+ </tr>
+ <tr>
+ <td>@@matchAll</td>
+ <td><code>"Symbol.matchAll"</code></td>
+ <td>A regular expression method that returns an iterator, that yields matches of the regular expression against a string. Called by the <code>String.prototype.matchAll</code> method.</td>
+ </tr>
+ <tr>
+ <td colspan="3">insert before @@replace</td>
+ </tr>
+ </tbody>
+ </table>
+</figure>
+
+[to-string]: https://tc39.github.io/ecma262/#sec-tostring
+[regexp-create]: https://tc39.github.io/ecma262/#sec-regexpcreate
+[regexp-exec]: https://tc39.github.io/ecma262/#sec-regexpexec
+[require-object-coercible]: https://tc39.github.io/ecma262/#sec-requireobjectcoercible
+[internal-slot]: https://tc39.github.io/ecma262/#sec-object-internal-methods-and-internal-slots
+[type]: https://tc39.github.io/ecma262/#sec-ecmascript-data-types-and-values
+[iterator-prototype]: https://tc39.github.io/ecma262/#sec-%iteratorprototype%-object
+[create-iter-result-object]: https://tc39.github.io/ecma262/#sec-createiterresultobject
+[isregexp]: https://tc39.github.io/ecma262/#sec-isregexp
+[object-create]: https://tc39.github.io/ecma262/#sec-objectcreate
+[call]: https://tc39.github.io/ecma262/#sec-call
+[species-constructor]: https://tc39.github.io/ecma262/#sec-speciesconstructor
+[construct]: https://tc39.github.io/ecma262/#sec-construct
+[tolength]: https://tc39.github.io/ecma262/#sec-tolength
+[set]: https://tc39.github.io/ecma262/#sec-set-o-p-v-throw
+[to-boolean]: https://tc39.github.io/ecma262/#sec-toboolean
diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/length.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/length.js
new file mode 100644
index 000000000..ae974ec48
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/length.js
@@ -0,0 +1,26 @@
+// Copyright (C) 2018 Peter Wong. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: Length of RegExp.prototype[ @@matchAll ]
+info: >
+ Section 17:
+ Every built-in Function object, including constructors, has a length
+ property whose value is an integer. Unless otherwise specified, this value
+ is equal to the largest number of named arguments shown in the subclause
+ headings for the function description, including optional parameters.
+
+ [...]
+
+ Unless otherwise specified, the length property of a built-in Function
+ object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+ [[Configurable]]: true }.
+features: [Symbol.matchAll]
+includes: [propertyHelper.js]
+---*/
+
+assert.sameValue(RegExp.prototype[Symbol.matchAll].length, 1);
+
+verifyNotEnumerable(RegExp.prototype[Symbol.matchAll], 'length');
+verifyNotWritable(RegExp.prototype[Symbol.matchAll], 'length');
+verifyConfigurable(RegExp.prototype[Symbol.matchAll], 'length');
diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/name.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/name.js
new file mode 100644
index 000000000..1ffd279fd
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/name.js
@@ -0,0 +1,27 @@
+// Copyright (C) 2018 Peter Wong. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: Name of RegExp.prototype[ @@matchAll ]
+info: >
+ Section 17: ECMAScript Standard Built-in Objects
+
+ Every built-in Function object, including constructors, that is not
+ identified as an anonymous function has a name property whose value is a
+ String. Unless otherwise specified, this value is the name that is given to
+ the function in this specification.
+
+ [...]
+
+ Unless otherwise specified, the name property of a built-in Function
+ object, if it exists, has the attributes { [[Writable]]: false,
+ [[Enumerable]]: false, [[Configurable]]: true }.
+features: [Symbol.matchAll]
+includes: [propertyHelper.js]
+---*/
+
+assert.sameValue(RegExp.prototype[Symbol.matchAll].name, '[Symbol.matchAll]');
+
+verifyNotEnumerable(RegExp.prototype[Symbol.matchAll], 'name');
+verifyNotWritable(RegExp.prototype[Symbol.matchAll], 'name');
+verifyConfigurable(RegExp.prototype[Symbol.matchAll], 'name');
diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/observable-operations.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/observable-operations.js
new file mode 100644
index 000000000..eec1cb4a5
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/observable-operations.js
@@ -0,0 +1,66 @@
+// Copyright (C) 2018 Peter Wong. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: >
+ RegExp.prototype.[@@matchAll] should perform observable operations in the
+ correct order
+info: >
+ pending RegExp.prototype [ @@matchAll ] ( string )
+ [...]
+ 2. Return ? [MatchAllIterator](#matchalliterator)(R, string).
+
+ pending MatchAllIterator ( R, O )
+ 1. If ? IsRegExp(R) is not true, throw a TypeError exception.
+ [...]
+ 4. Let flags be ? [ToString][tostring](? [Get][get](R, "flags")).
+ 5. Let matcher be ? Construct(C, « R, flags »).
+includes: [compareArray.js]
+features: [Symbol.matchAll]
+---*/
+
+const log = [];
+
+function observeGetter(obj, prop, propName = prop) {
+ const proto = Object.getPrototypeOf(obj);
+ const originalGetter = Object.getOwnPropertyDescriptor(proto, prop).get;
+ Object.defineProperty(obj, prop, {
+ get() {
+ log.push(`get ${propName}`);
+ return originalGetter.call(obj);
+ }
+ });
+}
+
+function observeValue(obj, prop, propName = prop) {
+ const value = obj[prop];
+ Object.defineProperty(obj, prop, {
+ get() {
+ log.push(`value ${propName}`);
+ return value;
+ }
+ });
+}
+
+const receiver = /./;
+const string = 'hello';
+
+observeValue(receiver, Symbol.match, 'Symbol.match');
+observeGetter(receiver, 'flags');
+observeGetter(receiver, 'global');
+observeGetter(receiver, 'unicode');
+
+receiver[Symbol.matchAll](string);
+
+assert.compareArray(log, [
+ // 1. If ? IsRegExp(R) is not true, throw a TypeError exception.
+ 'value Symbol.match',
+
+ // 4. Let flags be ? [ToString][tostring](? [Get][get](R, "flags")).
+ 'get flags',
+ 'get global',
+ 'get unicode',
+
+ // 5. Let matcher be ? [Construct][construct](C, R, flags).
+ 'value Symbol.match'
+]);
diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/prop-desc.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/prop-desc.js
new file mode 100644
index 000000000..bb0b41bdb
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/prop-desc.js
@@ -0,0 +1,19 @@
+// Copyright (C) 2018 Peter Wong. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: Property descriptor of RegExp.prototype[ @@matchAll ]
+info: >
+ ES6 Section 17
+
+ Every other data property described in clauses 18 through 26 and in Annex
+ B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false,
+ [[Configurable]]: true } unless otherwise specified.
+features: [Symbol.matchAll]
+includes: [propertyHelper.js]
+---*/
+
+assert.sameValue(typeof RegExp.prototype[Symbol.matchAll], 'function');
+verifyNotEnumerable(RegExp.prototype, Symbol.matchAll);
+verifyWritable(RegExp.prototype, Symbol.matchAll);
+verifyConfigurable(RegExp.prototype, Symbol.matchAll);
diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/regexp-flags-throws.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/regexp-flags-throws.js
new file mode 100644
index 000000000..617de2e07
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/regexp-flags-throws.js
@@ -0,0 +1,25 @@
+// Copyright (C) 2018 Peter Wong. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: >
+ Re-throw errors from RegExp's flags getter
+info: >
+ pending RegExp.prototype [ @@matchAll ] ( string )
+ [...]
+ 2. Return ? [MatchAllIterator](#matchalliterator)(R, string).
+
+ pending MatchAllIterator ( R, O )
+ [...]
+ 4. Let flags be ? [ToString][tostring](? [Get][get](R, "flags"))
+features: [Symbol.matchAll]
+---*/
+
+const regexp = /./;
+Object.defineProperty(regexp, 'flags', {
+ get() { throw new Test262Error(); }
+});
+
+assert.throws(Test262Error, () => {
+ RegExp.prototype[Symbol.matchAll].call(regexp, 'a');
+});
diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/returns-iterator-modified-regexp-lastindex.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/returns-iterator-modified-regexp-lastindex.js
new file mode 100644
index 000000000..967d8edc0
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/returns-iterator-modified-regexp-lastindex.js
@@ -0,0 +1,64 @@
+// Copyright (C) 2018 Peter Wong. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: >
+ The receiver's lastIndex is cached, changes afterwards do not affect
+ iterated results.
+info: >
+ pending RegExp.prototype [ @@matchAll ] ( string )
+ [...]
+ 2. Return ? [MatchAllIterator](#matchalliterator)(R, string).
+
+ pending MatchAllIterator ( R, O )
+ [...]
+ 8. Let lastIndex be ? [ToLength][tolength](? [Get][get](R, "lastIndex")).
+ 9. Perform ? [Set][set](matcher, "lastIndex", lastIndex, true).
+ 10. Return ! CreateRegExpStringIterator(matcher, S, global, fullUnicode).
+includes: [compareArray.js]
+features: [Symbol.matchAll]
+---*/
+
+function TestIteration(changeLastIndex) {
+ const receiver = /\w/g;
+ const string = 'a*b*c';
+
+ receiver.exec(string);
+
+ const iter = receiver[Symbol.matchAll](string);
+
+
+ if (changeLastIndex) {
+ receiver.exec(string);
+ assert.sameValue(receiver.lastIndex, 3);
+ }
+ else {
+ assert.sameValue(receiver.lastIndex, 1);
+ }
+
+
+ let result = iter.next();
+ assert.compareArray(result.value, ['b']);
+ assert(!result.done);
+
+
+ if (changeLastIndex) {
+ receiver.exec(string);
+ assert.sameValue(receiver.lastIndex, 5);
+ }
+ else {
+ assert.sameValue(receiver.lastIndex, 1);
+ }
+
+
+ result = iter.next();
+ assert.compareArray(result.value, ['c']);
+ assert(!result.done);
+
+ result = iter.next();
+ assert.sameValue(result.value, null);
+ assert(result.done);
+}
+
+TestIteration(false);
+TestIteration(true);
diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/returns-iterator.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/returns-iterator.js
new file mode 100644
index 000000000..c8b983e36
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/returns-iterator.js
@@ -0,0 +1,35 @@
+// Copyright (C) 2018 Peter Wong. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: >
+ RegExp.prototype.[@@matchAll] should perform observable operations in the
+ correct order
+info: >
+ pending RegExp.prototype [ @@matchAll ] ( string )
+ [...]
+ 2. Return ? [MatchAllIterator](#matchalliterator)(R, string).
+
+ pending MatchAllIterator ( R, O )
+ [...]
+ 10. Return ! CreateRegExpStringIterator(matcher, S, global, fullUnicode).
+includes: [compareArray.js]
+features: [Symbol.matchAll]
+---*/
+
+const receiver = /\w/g;
+const string = 'a*b';
+const iter = receiver[Symbol.matchAll](string);
+
+let result;
+result = iter.next();
+assert.compareArray(result.value, ['a']);
+assert(!result.done);
+
+result = iter.next();
+assert.compareArray(result.value, ['b']);
+assert(!result.done);
+
+result = iter.next();
+assert.sameValue(result.value, null);
+assert(result.done);
diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-throws.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-throws.js
new file mode 100644
index 000000000..22664fc13
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-throws.js
@@ -0,0 +1,30 @@
+// Copyright (C) 2018 Peter Wong. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: >
+ Re-throw errors from RegExp species constructor.
+info: >
+ pending RegExp.prototype [ @@matchAll ] ( string )
+ [...]
+ 2. Return ? [MatchAllIterator](#matchalliterator)(R, string).
+
+ pending MatchAllIterator ( R, O )
+ [...]
+ 5. Let matcher be ? [Construct][construct](C, R, flags).
+features: [Symbol.matchAll]
+---*/
+
+let should_throw = false;
+class FooRegExp extends RegExp {
+ constructor(...args) {
+ if (should_throw) throw new Test262Error();
+ super(...args);
+ }
+}
+const regexp = new FooRegExp('.', 'gu');
+
+should_throw = true;
+assert.throws(Test262Error, () => {
+ RegExp.prototype[Symbol.matchAll].call(regexp, 'a');
+});
diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor.js
new file mode 100644
index 000000000..ad781f8c5
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor.js
@@ -0,0 +1,38 @@
+// Copyright (C) 2018 Peter Wong. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: >
+ Verifies species constructor is called when creating internal RegExp
+features: [Symbol.matchAll]
+info: >
+ pending RegExp.prototype [ @@matchAll ] ( string )
+ [...]
+ 2. Return ? [MatchAllIterator](#matchalliterator)(R, string).
+
+ pending MatchAllIterator ( R, O )
+ [...]
+ 5. Let matcher be ? [Construct][construct](C, R, flags).
+---*/
+
+let track_calls = false;
+let call_count = 0;
+let call_args;
+class FooRegExp extends RegExp {
+ constructor(...args) {
+ if (track_calls) {
+ call_count++;
+ call_args = args;
+ }
+ return super(...args);
+ }
+}
+const regexp = new FooRegExp('.', 'gu');
+
+track_calls = true;
+RegExp.prototype[Symbol.matchAll].call(regexp, 'a');
+
+assert.sameValue(call_count, 1);
+assert.sameValue(call_args.length, 2);
+assert.sameValue(call_args[0], regexp);
+assert.sameValue(call_args[1], 'gu');
diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/species-regexp-global-throws.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-regexp-global-throws.js
new file mode 100644
index 000000000..d5398a0bc
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-regexp-global-throws.js
@@ -0,0 +1,27 @@
+// Copyright (C) 2018 Peter Wong. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: >
+ Re-throw errors from the species constructed RegExp's
+ global getter
+info: >
+ pending RegExp.prototype [ @@matchAll ] ( string )
+ [...]
+ 2. Return ? [MatchAllIterator](#matchalliterator)(R, string).
+
+ pending MatchAllIterator ( R, O )
+ [...]
+ 6. Let global be ? [ToBoolean][to-boolean](? [Get][get](matcher, "global")).
+features: [Symbol.matchAll]
+---*/
+
+let globalRegexp;
+class GlobalThrowsRegExp extends RegExp {
+ get global() { if (globalRegexp !== this) throw new Test262Error(); }
+}
+globalRegexp = new GlobalThrowsRegExp();
+
+assert.throws(Test262Error, () => {
+ RegExp.prototype[Symbol.matchAll].call(globalRegexp, 'a');
+});
diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/species-regexp-unicode-throws.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-regexp-unicode-throws.js
new file mode 100644
index 000000000..41c561cab
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-regexp-unicode-throws.js
@@ -0,0 +1,27 @@
+// Copyright (C) 2018 Peter Wong. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: >
+ Re-throw errors from the species constructed RegExp's
+ unicode getter
+info: >
+ pending RegExp.prototype [ @@matchAll ] ( string )
+ [...]
+ 2. Return ? [MatchAllIterator](#matchalliterator)(R, string).
+
+ pending MatchAllIterator ( R, O )
+ [...]
+ 7. Let fullUnicode be ? [ToBoolean][to-boolean](? [Get][get](matcher, "unicode")).
+features: [Symbol.matchAll]
+---*/
+
+let unicodeRegexp;
+class UnicodeThrowsRegExp extends RegExp {
+ get unicode() { if (unicodeRegexp !== this) throw new Test262Error(); }
+}
+unicodeRegexp = new UnicodeThrowsRegExp();
+
+assert.throws(Test262Error, () => {
+ RegExp.prototype[Symbol.matchAll].call(unicodeRegexp, 'a');
+});
diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/string-tostring-throws.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/string-tostring-throws.js
new file mode 100644
index 000000000..01e72d11b
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/string-tostring-throws.js
@@ -0,0 +1,24 @@
+// Copyright (C) 2015 Peter Wong. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: >
+ Re-throw errors when coercing `string` value to a string
+info: >
+ pending RegExp.prototype [ @@matchAll ] ( string )
+ [...]
+ 2. Return ? [MatchAllIterator](#matchalliterator)(R, string).
+
+ pending MatchAllIterator ( R, O )
+ [...]
+ 2. Let S be ? [ToString][to-string](O).
+features: [Symbol.iterator]
+---*/
+
+const obj = {
+ toString() { throw new Test262Error(); }
+};
+
+assert.throws(Test262Error, function() {
+ RegExp.prototype[Symbol.matchAll].call(/./, obj);
+});
diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/this-is-not-regexp-throws.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/this-is-not-regexp-throws.js
new file mode 100644
index 000000000..6afffd4e7
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/this-is-not-regexp-throws.js
@@ -0,0 +1,13 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: Error thrown when `this` is not a RegExp
+info: >
+ 1. If ? [IsRegExp][isregexp](R) is not true, throw a TypeError exception.
+features: [Symbol.matchAll]
+---*/
+
+assert.throws(TypeError, () => {
+ RegExp.prototype[Symbol.matchAll].call({}, "a");
+});
diff --git a/test/built-ins/RegExpStringIteratorPrototype/Symbol.toStringTag.js b/test/built-ins/RegExpStringIteratorPrototype/Symbol.toStringTag.js
new file mode 100644
index 000000000..fea812fb3
--- /dev/null
+++ b/test/built-ins/RegExpStringIteratorPrototype/Symbol.toStringTag.js
@@ -0,0 +1,23 @@
+// Copyright (C) 2014 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: pending
+description: >
+ `Symbol.toStringTag` property descriptor
+info: >
+ The initial value of the @@toStringTag property is the string value "String
+ Iterator".
+
+ This property has the attributes { [[Writable]]: false, [[Enumerable]]:
+ false, [[Configurable]]: true }.
+features: [Symbol.toStringTag]
+includes: [propertyHelper.js]
+---*/
+
+var RegExpStringIteratorProto = Object.getPrototypeOf('a'.matchAll(/./));
+
+// assert.sameValue(RegExpStringIteratorProto[Symbol.toStringTag], 'RegExp String Iterator');
+
+// verifyNotEnumerable(RegExpStringIteratorProto, Symbol.toStringTag);
+// verifyNotWritable(RegExpStringIteratorProto, Symbol.toStringTag);
+// verifyConfigurable(RegExpStringIteratorProto, Symbol.toStringTag);
diff --git a/test/built-ins/RegExpStringIteratorPrototype/ancestry.js b/test/built-ins/RegExpStringIteratorPrototype/ancestry.js
new file mode 100644
index 000000000..e471dca8a
--- /dev/null
+++ b/test/built-ins/RegExpStringIteratorPrototype/ancestry.js
@@ -0,0 +1,20 @@
+// Copyright (C) 2014 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: >
+ The [[Prototype]] internal slot ofthe %RegExpStringIteratorPrototype% is the
+ %IteratorPrototype% intrinsic object (25.1.2).
+features: [Symbol.iterator]
+---*/
+
+const RegExpStringIteratorProto = Object.getPrototypeOf(''.matchAll(/./));
+const RegExpStringIteratorProto2 = Object.getPrototypeOf(/./[Symbol.matchAll](''));
+
+assert.sameValue(RegExpStringIteratorProto, RegExpStringIteratorProto2);
+
+var ArrayIteratorProto = Object.getPrototypeOf(
+ Object.getPrototypeOf([][Symbol.iterator]())
+);
+
+assert.sameValue(Object.getPrototypeOf(RegExpStringIteratorProto), ArrayIteratorProto);
diff --git a/test/built-ins/RegExpStringIteratorPrototype/next/length.js b/test/built-ins/RegExpStringIteratorPrototype/next/length.js
new file mode 100644
index 000000000..cde067f53
--- /dev/null
+++ b/test/built-ins/RegExpStringIteratorPrototype/next/length.js
@@ -0,0 +1,32 @@
+// Copyright (C) 2018 Peter Wong. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: pending
+description: >
+ %RegExpStringIteratorPrototype%.next.length is 0.
+info: >
+ %RegExpStringIteratorPrototype%.next ( )
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, has a length
+ property whose value is an integer. Unless otherwise specified, this
+ value is equal to the largest number of named arguments shown in the
+ subclause headings for the function description, including optional
+ parameters. However, rest parameters shown using the form “...name”
+ are not included in the default argument count.
+
+ Unless otherwise specified, the length property of a built-in Function
+ object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+ [[Configurable]]: true }.
+includes: [propertyHelper.js]
+features: []
+---*/
+
+var RegExpStringIteratorProto = Object.getPrototypeOf(''.matchAll(/./));
+
+assert.sameValue(RegExpStringIteratorProto.next.length, 0);
+
+verifyNotEnumerable(RegExpStringIteratorProto.next, "length");
+verifyNotWritable(RegExpStringIteratorProto.next, "length");
+verifyConfigurable(RegExpStringIteratorProto.next, "length");
diff --git a/test/built-ins/RegExpStringIteratorPrototype/next/name.js b/test/built-ins/RegExpStringIteratorPrototype/next/name.js
new file mode 100644
index 000000000..1d03b7ccc
--- /dev/null
+++ b/test/built-ins/RegExpStringIteratorPrototype/next/name.js
@@ -0,0 +1,29 @@
+// Copyright (C) 2018 Peter Wong. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: pending
+description: >
+ %RegExpStringIteratorPrototype%.next.name is "next".
+info: >
+ %RegExpStringIteratorPrototype%.next ( )
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, that is not
+ identified as an anonymous function has a name property whose value
+ is a String.
+
+ Unless otherwise specified, the name property of a built-in Function
+ object, if it exists, has the attributes { [[Writable]]: false,
+ [[Enumerable]]: false, [[Configurable]]: true }.
+includes: [propertyHelper.js]
+features: []
+---*/
+
+var RegExpStringIteratorProto = Object.getPrototypeOf('a'.matchAll(/./));
+
+assert.sameValue(RegExpStringIteratorProto.next.name, "next");
+
+verifyNotEnumerable(RegExpStringIteratorProto.next, "name");
+verifyNotWritable(RegExpStringIteratorProto.next, "name");
+verifyConfigurable(RegExpStringIteratorProto.next, "name");
diff --git a/test/built-ins/RegExpStringIteratorPrototype/next/next-iteration-surrogate-pairs.js b/test/built-ins/RegExpStringIteratorPrototype/next/next-iteration-surrogate-pairs.js
new file mode 100644
index 000000000..c57621e13
--- /dev/null
+++ b/test/built-ins/RegExpStringIteratorPrototype/next/next-iteration-surrogate-pairs.js
@@ -0,0 +1,84 @@
+// Copyright (C) 2014 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 21.1.5.2.1
+description: >
+ Iteration should respect UTF-16-encoded Unicode code points specified via
+ surrogate pairs.
+features: [Symbol.iterator]
+---*/
+
+var lo = '\uD834';
+var hi = '\uDF06';
+var pair = lo + hi;
+var string = 'a' + pair + 'b' + lo + pair + hi + lo;
+var iterator = string[Symbol.iterator]();
+var result;
+
+result = iterator.next();
+assert.sameValue(result.value, 'a', 'First normal code point `value`');
+assert.sameValue(result.done, false, 'First normal code point `done` flag');
+
+result = iterator.next();
+assert.sameValue(
+ result.value, pair, 'Surrogate pair `value` (between normal code points)'
+);
+assert.sameValue(
+ result.done, false, 'Surrogate pair `done` flag (between normal code points)'
+);
+
+result = iterator.next();
+assert.sameValue(result.value, 'b', 'Second normal code point `value`');
+assert.sameValue(result.done, false, 'Second normal code point `done` flag');
+
+result = iterator.next();
+assert.sameValue(
+ result.value,
+ lo,
+ 'Lone lower code point `value` (following normal code point)'
+);
+assert.sameValue(
+ result.done,
+ false,
+ 'Lone lower code point `done` flag (following normal code point)'
+);
+
+result = iterator.next();
+assert.sameValue(
+ result.value,
+ pair,
+ 'Surrogate pair `value` (between lone lower- and upper- code points)'
+);
+assert.sameValue(
+ result.done,
+ false,
+ 'Surrogate pair `done` flag (between lone lower- and upper- code points)'
+);
+
+result = iterator.next();
+assert.sameValue(result.value, hi, 'Lone upper code point `value`');
+assert.sameValue(result.done, false, 'Lone upper code point `done` flag');
+
+result = iterator.next();
+assert.sameValue(
+ result.value,
+ lo,
+ 'Lone lower code point `value` (following lone upper code point)'
+);
+assert.sameValue(
+ result.done,
+ false,
+ 'Lone lower code point `done` flag (following lone upper code point)'
+);
+
+result = iterator.next();
+assert.sameValue(result.value, undefined, 'Exhausted result `value`');
+assert.sameValue(result.done, true, 'Exhausted result `done` flag');
+
+result = iterator.next();
+assert.sameValue(
+ result.value, undefined, 'Exhausted result `value` (repeated request)'
+);
+assert.sameValue(
+ result.done, true, 'Exhausted result `done` flag (repeated request'
+);
diff --git a/test/built-ins/RegExpStringIteratorPrototype/next/next-iteration.js b/test/built-ins/RegExpStringIteratorPrototype/next/next-iteration.js
new file mode 100644
index 000000000..f43cd3f71
--- /dev/null
+++ b/test/built-ins/RegExpStringIteratorPrototype/next/next-iteration.js
@@ -0,0 +1,36 @@
+// Copyright (C) 2014 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 21.1.5.2.1
+description: >
+ Iteration should visit each UTF-8 code point exactly once.
+features: [Symbol.iterator]
+---*/
+
+var string = "abc";
+var iterator = string[Symbol.iterator]();
+var result;
+
+result = iterator.next();
+assert.sameValue(result.value, 'a', 'First result `value`');
+assert.sameValue(result.done, false, 'First result `done` flag');
+
+result = iterator.next();
+assert.sameValue(result.value, 'b', 'Second result `value`');
+assert.sameValue(result.done, false, 'Second result `done` flag');
+
+result = iterator.next();
+assert.sameValue(result.value, 'c', 'Third result `value`');
+assert.sameValue(result.done, false, 'Third result `done` flag');
+
+result = iterator.next();
+assert.sameValue(result.value, undefined, 'Exhausted result `value`');
+assert.sameValue(result.done, true, 'Exhausted result `done` flag');
+
+result = iterator.next();
+assert.sameValue(
+ result.value, undefined, 'Exhausted result `value` (repeated request)'
+);
+assert.sameValue(
+ result.done, true, 'Exhausted result `done` flag (repeated request)'
+);
diff --git a/test/built-ins/RegExpStringIteratorPrototype/next/next-missing-internal-slots.js b/test/built-ins/RegExpStringIteratorPrototype/next/next-missing-internal-slots.js
new file mode 100644
index 000000000..823dea16d
--- /dev/null
+++ b/test/built-ins/RegExpStringIteratorPrototype/next/next-missing-internal-slots.js
@@ -0,0 +1,16 @@
+// Copyright (C) 2014 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: >
+ If the `this` value does not have all of the internal slots of an String
+ Iterator Instance (pending), throw a `TypeError` exception.
+features: []
+---*/
+
+var iterator = 'a'.matchAll(/./);
+var object = Object.create(iterator);
+
+assert.throws(TypeError, function() {
+ object.next();
+});
diff --git a/test/built-ins/String/prototype/matchAll/invoke-internal-regexp-has-no-matchAll.js b/test/built-ins/String/prototype/matchAll/invoke-internal-regexp-has-no-matchAll.js
new file mode 100644
index 000000000..a15d23f31
--- /dev/null
+++ b/test/built-ins/String/prototype/matchAll/invoke-internal-regexp-has-no-matchAll.js
@@ -0,0 +1,38 @@
+// Copyright (C) 2018 Peter Wong. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: pending
+description: Internally created RegExp has no @@matchAll
+info: >
+ [...]
+ 2. If ? IsRegExp(regexp) is true, then
+ 3. Else,
+ a. Let R be ? RegExpCreate(regexp, "g").
+ 4. Let matcher be ? [GetMethod][getmethod](R, @@matchAll).
+ [...]
+ 6. Return ? MatchAllIterator(R, O).
+features: [Symbol.matchAll]
+---*/
+
+const originalMatch = RegExp.prototype[Symbol.matchAll];
+delete RegExp.prototype[Symbol.matchAll];
+try {
+ const string = 'a*b';
+ const iter = string.matchAll('\\w');
+
+ let result;
+ result = iter.next();
+ assert.compareArray(result.value, ['a']);
+ assert(!result.done);
+
+ result = iter.next();
+ assert.compareArray(result.value, ['b']);
+ assert(!result.done);
+
+ result = iter.next();
+ assert.sameValue(result.value, null);
+ assert(result.done);
+} finally {
+ RegExp.prototype[Symbol.matchAll] = originalMatch;
+}
diff --git a/test/built-ins/String/prototype/matchAll/invoke-internal-regexp-matchAll-throws.js b/test/built-ins/String/prototype/matchAll/invoke-internal-regexp-matchAll-throws.js
new file mode 100644
index 000000000..c40abad74
--- /dev/null
+++ b/test/built-ins/String/prototype/matchAll/invoke-internal-regexp-matchAll-throws.js
@@ -0,0 +1,20 @@
+// Copyright (C) 2018 Peter Wong. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: pending
+description: >
+ Invocation of @@matchAll on internally created RegExp throws
+info: >
+ [...]
+ 4. Let matcher be ? [GetMethod][getmethod](R, @@matchAll).
+features: [Symbol.matchAll]
+---*/
+
+RegExp.prototype[Symbol.matchAll] = function() {
+ throw new Test262Error();
+};
+
+assert.throws(Test262Error, function() {
+ 'target'.matchAll('.');
+});
diff --git a/test/built-ins/String/prototype/matchAll/invoke-internal-regexp-matchAll.js b/test/built-ins/String/prototype/matchAll/invoke-internal-regexp-matchAll.js
new file mode 100644
index 000000000..4ed977d16
--- /dev/null
+++ b/test/built-ins/String/prototype/matchAll/invoke-internal-regexp-matchAll.js
@@ -0,0 +1,37 @@
+// Copyright (C) 2018 Peter Wong. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: pending
+description: Invocation of @@matchAll on internally created RegExp
+info: >
+ [...]
+ 4. Let matcher be ? [GetMethod][getmethod](R, @@matchAll).
+ 5. If matcher is not undefined, then
+ a. Return ? Call(matcher, R, « O »).
+features: [Symbol.matchAll]
+---*/
+
+const originalMatch = RegExp.prototype[Symbol.matchAll];
+const returnVal = {};
+const thisVal, args;
+
+RegExp.prototype[Symbol.matchAll] = function() {
+ thisVal = this;
+ args = arguments;
+ return returnVal;
+};
+
+try {
+ const regexString = '.';
+ const result = 'target'.matchAll(regexString);
+
+ assert(thisVal instanceof RegExp);
+ assert.sameValue(thisVal.source, regexString);
+ assert.sameValue(thisVal.flags, 'g');
+ assert.sameValue(args.length, 1);
+ assert.sameValue(args[0], 'target');
+ assert.sameValue(result, returnVal);
+} finally {
+ RegExp.prototype[Symbol.matchAll] = originalMatch;
+}
diff --git a/test/built-ins/String/prototype/matchAll/invoke-regexp-has-no-matchAll.js b/test/built-ins/String/prototype/matchAll/invoke-regexp-has-no-matchAll.js
new file mode 100644
index 000000000..7dfc77f6d
--- /dev/null
+++ b/test/built-ins/String/prototype/matchAll/invoke-regexp-has-no-matchAll.js
@@ -0,0 +1,35 @@
+// Copyright (C) 2018 Peter Wong. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: pending
+description: Internally created RegExp has no @@matchAll
+info: >
+ [...]
+ 2. If ? IsRegExp(regexp) is true, then
+ 3. Else,
+ a. Let R be ? RegExpCreate(regexp, "g").
+ 4. Let matcher be ? [GetMethod][getmethod](R, @@matchAll).
+ [...]
+ 6. Return ? MatchAllIterator(R, O).
+features: [Symbol.matchAll]
+---*/
+
+const regexp = /\w/g;
+delete regexp[Symbol.matchAll];
+const string = 'a*b';
+const iter = string.matchAll(regexp);
+
+let result;
+result = iter.next();
+assert.compareArray(result.value, ['a']);
+assert(!result.done);
+
+result = iter.next();
+assert.compareArray(result.value, ['b']);
+assert(!result.done);
+
+result = iter.next();
+assert.sameValue(result.value, null);
+assert(result.done);
+
diff --git a/test/built-ins/String/prototype/matchAll/invoke-regexp-matchAll-throws.js b/test/built-ins/String/prototype/matchAll/invoke-regexp-matchAll-throws.js
new file mode 100644
index 000000000..f1093fdee
--- /dev/null
+++ b/test/built-ins/String/prototype/matchAll/invoke-regexp-matchAll-throws.js
@@ -0,0 +1,21 @@
+// Copyright (C) 2018 Peter Wong. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: pending
+description: >
+ Invocation of @@matchAll on regexp throws
+info: >
+ [...]
+ 4. Let matcher be ? [GetMethod][getmethod](R, @@matchAll).
+features: [Symbol.matchAll]
+---*/
+
+var regexp = /./;
+regexp[Symbol.matchAll] = function() {
+ throw new Test262Error();
+};
+
+assert.throws(Test262Error, function() {
+ 'target'.matchAll(regexp);
+});
diff --git a/test/built-ins/String/prototype/matchAll/invoke-regexp-matchAll.js b/test/built-ins/String/prototype/matchAll/invoke-regexp-matchAll.js
new file mode 100644
index 000000000..758de19f8
--- /dev/null
+++ b/test/built-ins/String/prototype/matchAll/invoke-regexp-matchAll.js
@@ -0,0 +1,30 @@
+// Copyright (C) 2018 Peter Wong. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: pending
+description: Invocation of @@matchAll on regexp
+info: >
+ [...]
+ 4. Let matcher be ? [GetMethod][getmethod](R, @@matchAll).
+ 5. If matcher is not undefined, then
+ a. Return ? Call(matcher, R, « O »).
+features: [Symbol.matchAll]
+---*/
+
+var regexp = /./;
+var returnVal = {};
+var thisVal, args;
+regexp[Symbol.matchAll] = function() {
+ thisVal = this;
+ args = arguments;
+ return returnVal;
+};
+
+var result = 'target'.matchAll(regexp);
+
+assert(thisVal instanceof RegExp);
+assert.sameValue(thisVal, regexp);
+assert.sameValue(args.length, 1);
+assert.sameValue(args[0], 'target');
+assert.sameValue(result, returnVal);
diff --git a/test/built-ins/String/prototype/matchAll/return-abrupt-from-regexp-isregexp.js b/test/built-ins/String/prototype/matchAll/return-abrupt-from-regexp-isregexp.js
new file mode 100644
index 000000000..cff50bada
--- /dev/null
+++ b/test/built-ins/String/prototype/matchAll/return-abrupt-from-regexp-isregexp.js
@@ -0,0 +1,28 @@
+// Copyright (C) 2018 Peter Wong. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: >
+ Returns abrupt from IsRegExp(O).
+info: >
+ [...]
+ 2. If ? IsRegExp(regexp) is true, then
+
+ 7.2.8 IsRegExp ( argument )
+ [...]
+ 2. Let matcher be ? Get(argument, @@match).
+features: [Symbol.match, String.prototype.matchAll]
+---*/
+
+const obj = {
+ get [Symbol.match]() { throw new Test262Error(); }
+};
+
+assert.throws(Test262Error, () => 'test'.matchAll(obj));
+
+const regexp = /./;
+Object.defineProperty(regexp, Symbol.match, {
+ get: () => { throw new Test262Error(); }
+});
+
+assert.throws(Test262Error, () => 'test'.matchAll(regexp));
diff --git a/test/built-ins/String/prototype/matchAll/this-is-null-throws.js b/test/built-ins/String/prototype/matchAll/this-is-null-throws.js
new file mode 100644
index 000000000..84799293e
--- /dev/null
+++ b/test/built-ins/String/prototype/matchAll/this-is-null-throws.js
@@ -0,0 +1,16 @@
+// Copyright (C) 2018 Peter Wong. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: >
+ Throws TypeError when `this` is null
+info: >
+ pending String.prototype.matchAll ( regexp )
+
+ 1. Let O be RequireObjectCoercible(this value).
+features: [String.prototype.matchAll]
+---*/
+
+assert.throws(TypeError, function() {
+ String.prototype.matchAll.call(null, /./);
+});
diff --git a/test/built-ins/String/prototype/matchAll/this-is-undefined-throws.js b/test/built-ins/String/prototype/matchAll/this-is-undefined-throws.js
new file mode 100644
index 000000000..796ab7b78
--- /dev/null
+++ b/test/built-ins/String/prototype/matchAll/this-is-undefined-throws.js
@@ -0,0 +1,16 @@
+// Copyright (C) 2018 Peter Wong. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: >
+ Throws TypeError when `this` is undefined
+info: >
+ pending String.prototype.matchAll ( regexp )
+
+ 1. Let O be RequireObjectCoercible(this value).
+features: [String.prototype.matchAll]
+---*/
+
+assert.throws(TypeError, function() {
+ String.prototype.matchAll.call(undefined, /./);
+});
diff --git a/test/built-ins/String/prototype/matchAll/tostring-throws.js b/test/built-ins/String/prototype/matchAll/tostring-throws.js
new file mode 100644
index 000000000..025f68d05
--- /dev/null
+++ b/test/built-ins/String/prototype/matchAll/tostring-throws.js
@@ -0,0 +1,24 @@
+// Copyright (C) 2018 Peter Wong. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: pending
+description: >
+ When regexp is string, create a Regular Expression with global flag set.
+info: >
+ [...]
+ 2. If ? IsRegExp(regexp) is true, then
+ [...]
+ 3. Else,
+ a. Let R be ? RegExpCreate(regexp, "g").
+features: [Symbol.matchAll]
+---*/
+
+const obj = {
+ toString() { throw new Test262Error(); }
+};
+
+assert.throws(Test262Error, function() {
+ 'target'.matchAll(obj);
+});
+
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment