From f1e45d9e5e11b2ad073a50dabcfbae35e898caf5 Mon Sep 17 00:00:00 2001
From: peterwmwong <peter.wm.wong@gmail.com>
Date: Sat, 17 Mar 2018 22:48:31 -0500
Subject: [PATCH] Fleshed out tests for Symbol.matchAll, String.p.matchAll,
 RegExp.p[@@matchAll], and %RegExpStringIteratorPrototype%

Tests were updated and assuming https://github.com/tc39/proposal-string-matchall/pull/33 will be merged.
---
 features.txt                                  |  5 ++
 harness/compareIterator.js                    | 34 ++++++++++++
 harness/regExpUtils.js                        | 15 +++++
 .../get-species-constructor-err.js            | 22 --------
 .../internal-regexp-lastindex-not-zero.js     | 33 +++++++++++
 .../isregexp-internal-regexp-is-false.js      | 29 ++++++++++
 .../isregexp-internal-regexp-throws.js        | 29 ++++++++++
 .../Symbol.matchAll/isregexp-this-throws.js   | 26 +++++++++
 .../prototype/Symbol.matchAll/length.js       | 17 ++++--
 .../RegExp/prototype/Symbol.matchAll/name.js  | 11 +++-
 .../prototype/Symbol.matchAll/prop-desc.js    |  7 ++-
 .../regexpcreate-this-throws.js               | 29 ++++++++++
 ...cies-constructor-get-constructor-throws.js | 32 +++++++++++
 .../species-constructor-get-species-throws.js | 31 +++++++++++
 ...pecies-constructor-is-not-object-throws.js | 41 ++++++++++++++
 .../species-constructor-is-undefined.js       | 31 +++++++++++
 ...-constructor-species-is-not-constructor.js | 45 +++++++++++++++
 ...onstructor-species-is-null-or-undefined.js | 41 ++++++++++++++
 .../species-constructor-species-throws.js     | 29 ++++++++++
 .../Symbol.matchAll/species-constructor.js    | 42 ++++++++++++++
 .../species-regexp-get-global-throws.js       | 34 ++++++++++++
 .../species-regexp-get-unicode-throws.js      | 34 ++++++++++++
 ...oerce-arg.js => string-tostring-throws.js} | 20 +++----
 .../Symbol.matchAll/string-tostring.js        | 29 ++++++++++
 .../Symbol.matchAll/this-get-flags-throws.js  | 28 ++++++++++
 .../Symbol.matchAll/this-get-flags.js         | 29 ++++++++++
 .../Symbol.matchAll/this-lastindex-cached.js  | 36 ++++++++++++
 .../Symbol.matchAll/this-not-object-throws.js | 31 +++++++++++
 .../this-tolength-lastindex-throws.js         | 28 ++++++++++
 .../this-tostring-flags-throws.js             | 33 +++++++++++
 .../Symbol.matchAll/this-tostring-flags.js    | 33 +++++++++++
 .../Symbol.matchAll/this-val-non-obj.js       | 36 ------------
 .../Symbol.matchAll/this-val-non-regexp.js    | 22 --------
 .../Symbol.toStringTag.js                     | 23 ++++++++
 .../RegExpStringIteratorPrototype/ancestry.js | 16 ++++++
 .../next/custom-regexpexec-call-throws.js     | 28 ++++++++++
 .../next/custom-regexpexec-get-throws.js      | 28 ++++++++++
 .../custom-regexpexec-match-get-0-throws.js   | 30 ++++++++++
 ...-regexpexec-match-get-0-tostring-throws.js | 31 +++++++++++
 .../custom-regexpexec-match-get-0-tostring.js | 48 ++++++++++++++++
 .../next/custom-regexpexec-not-callable.js    | 40 ++++++++++++++
 .../next/custom-regexpexec.js                 | 55 +++++++++++++++++++
 .../next/length.js                            | 33 +++++++++++
 .../next/name.js                              | 31 +++++++++++
 .../next/next-iteration-global.js             | 40 ++++++++++++++
 .../next/next-iteration.js                    | 37 +++++++++++++
 .../next/next-missing-internal-slots.js       | 21 +++++++
 .../next/prop-desc.js                         | 25 +++++++++
 .../next/regexp-tolength-lastindex-throws.js  | 33 +++++++++++
 .../next/this-is-not-object-throws.js         | 34 ++++++++++++
 .../matchAll/cstm-matcher-get-err.js          | 26 ---------
 .../matchAll/invoke-builtin-matchall.js       | 43 ---------------
 .../String/prototype/matchAll/length.js       | 20 ++++---
 .../String/prototype/matchAll/name.js         | 31 ++++++-----
 .../String/prototype/matchAll/prop-desc.js    | 10 +++-
 .../matchAll/regexp-get-matchAll-throws.js    | 25 +++++++++
 .../prototype/matchAll/regexp-is-null.js      | 27 +++++++++
 .../prototype/matchAll/regexp-is-undefined.js | 28 ++++++++++
 ...ation.js => regexp-matchAll-invocation.js} | 15 ++---
 .../matchAll/regexp-matchAll-throws.js        | 21 +++++++
 .../regexp-prototype-get-matchAll-throws.js   | 22 ++++++++
 .../regexp-prototype-has-no-matchAll.js       | 24 ++++++++
 .../regexp-prototype-matchAll-invocation.js   | 36 ++++++++++++
 .../regexp-prototype-matchAll-throws.js       | 22 ++++++++
 .../matchAll/this-val-non-obj-coercible.js    |  6 +-
 test/built-ins/Symbol/matchAll/cross-realm.js | 14 +++++
 test/built-ins/Symbol/matchAll/prop-desc.js   | 17 ++++++
 67 files changed, 1677 insertions(+), 205 deletions(-)
 create mode 100644 harness/compareIterator.js
 delete mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/get-species-constructor-err.js
 create mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/internal-regexp-lastindex-not-zero.js
 create mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/isregexp-internal-regexp-is-false.js
 create mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/isregexp-internal-regexp-throws.js
 create mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/isregexp-this-throws.js
 create mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/regexpcreate-this-throws.js
 create mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-get-constructor-throws.js
 create mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-get-species-throws.js
 create mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-is-not-object-throws.js
 create mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-is-undefined.js
 create mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-species-is-not-constructor.js
 create mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-species-is-null-or-undefined.js
 create mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-species-throws.js
 create mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor.js
 create mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/species-regexp-get-global-throws.js
 create mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/species-regexp-get-unicode-throws.js
 rename test/built-ins/RegExp/prototype/Symbol.matchAll/{coerce-arg.js => string-tostring-throws.js} (59%)
 create mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/string-tostring.js
 create mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/this-get-flags-throws.js
 create mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/this-get-flags.js
 create mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/this-lastindex-cached.js
 create mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/this-not-object-throws.js
 create mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/this-tolength-lastindex-throws.js
 create mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/this-tostring-flags-throws.js
 create mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/this-tostring-flags.js
 delete mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/this-val-non-obj.js
 delete mode 100644 test/built-ins/RegExp/prototype/Symbol.matchAll/this-val-non-regexp.js
 create mode 100644 test/built-ins/RegExpStringIteratorPrototype/Symbol.toStringTag.js
 create mode 100644 test/built-ins/RegExpStringIteratorPrototype/ancestry.js
 create mode 100644 test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-call-throws.js
 create mode 100644 test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-get-throws.js
 create mode 100644 test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-match-get-0-throws.js
 create mode 100644 test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-match-get-0-tostring-throws.js
 create mode 100644 test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-match-get-0-tostring.js
 create mode 100644 test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-not-callable.js
 create mode 100644 test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec.js
 create mode 100644 test/built-ins/RegExpStringIteratorPrototype/next/length.js
 create mode 100644 test/built-ins/RegExpStringIteratorPrototype/next/name.js
 create mode 100644 test/built-ins/RegExpStringIteratorPrototype/next/next-iteration-global.js
 create mode 100644 test/built-ins/RegExpStringIteratorPrototype/next/next-iteration.js
 create mode 100644 test/built-ins/RegExpStringIteratorPrototype/next/next-missing-internal-slots.js
 create mode 100644 test/built-ins/RegExpStringIteratorPrototype/next/prop-desc.js
 create mode 100644 test/built-ins/RegExpStringIteratorPrototype/next/regexp-tolength-lastindex-throws.js
 create mode 100644 test/built-ins/RegExpStringIteratorPrototype/next/this-is-not-object-throws.js
 delete mode 100644 test/built-ins/String/prototype/matchAll/cstm-matcher-get-err.js
 delete mode 100644 test/built-ins/String/prototype/matchAll/invoke-builtin-matchall.js
 create mode 100644 test/built-ins/String/prototype/matchAll/regexp-get-matchAll-throws.js
 create mode 100644 test/built-ins/String/prototype/matchAll/regexp-is-null.js
 create mode 100644 test/built-ins/String/prototype/matchAll/regexp-is-undefined.js
 rename test/built-ins/String/prototype/matchAll/{cstm-matcher-invocation.js => regexp-matchAll-invocation.js} (67%)
 create mode 100644 test/built-ins/String/prototype/matchAll/regexp-matchAll-throws.js
 create mode 100644 test/built-ins/String/prototype/matchAll/regexp-prototype-get-matchAll-throws.js
 create mode 100644 test/built-ins/String/prototype/matchAll/regexp-prototype-has-no-matchAll.js
 create mode 100644 test/built-ins/String/prototype/matchAll/regexp-prototype-matchAll-invocation.js
 create mode 100644 test/built-ins/String/prototype/matchAll/regexp-prototype-matchAll-throws.js
 create mode 100644 test/built-ins/Symbol/matchAll/cross-realm.js
 create mode 100644 test/built-ins/Symbol/matchAll/prop-desc.js

diff --git a/features.txt b/features.txt
index 6290998b28..874e78f58f 100644
--- a/features.txt
+++ b/features.txt
@@ -72,6 +72,11 @@ String.prototype.trimStart
 # https://github.com/tc39/proposal-numeric-separator
 numeric-separator-literal
 
+# String.prototype.matchAll
+# https://github.com/tc39/proposal-string-matchall
+String.prototype.matchAll
+Symbol.matchAll
+
 # Standard language features
 #
 # Language features that have been included in a published version of the
diff --git a/harness/compareIterator.js b/harness/compareIterator.js
new file mode 100644
index 0000000000..69b9246e1b
--- /dev/null
+++ b/harness/compareIterator.js
@@ -0,0 +1,34 @@
+// Copyright (C) 2018 Peter Wong.  All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: Compare the values of an iterator with an array of expected values
+---*/
+
+// Example:
+//
+//    function* numbers() {
+//      yield 1;
+//      yield 2;
+//      yield 3;
+//    }
+//
+//    compareIterator(numbers(), [
+//      v => assert.sameValue(v, 1),
+//      v => assert.sameValue(v, 2),
+//      v => assert.sameValue(v, 3),
+//    ]);
+//
+assert.compareIterator = function(iter, validators, message) {
+  message = message || '';
+
+  var i, result;
+  for (i = 0; i < validators.length; i++) {
+    result = iter.next();
+    assert(!result.done, 'Expected ' + i + ' values(s). Instead iterator only produced ' + (i - 1) + ' value(s). ' + message);
+    validators[i](result.value);
+  }
+
+  result = iter.next();
+  assert(result.done, 'Expected only ' + i + ' values(s). Instead iterator produced more. ' + message);
+  assert.sameValue(result.value, undefined, 'Expected value of `undefined` when iterator completes. ' + message);
+}
diff --git a/harness/regExpUtils.js b/harness/regExpUtils.js
index bdb956427a..4dd7ddf13b 100644
--- a/harness/regExpUtils.js
+++ b/harness/regExpUtils.js
@@ -37,3 +37,18 @@ function testPropertyEscapes(regex, string, expression) {
     }
   }
 }
+
+// Returns a function that will validate RegExp match result
+//
+// Example:
+//
+//    var validate = matchValidator(['b'], 1, 'abc');
+//    validate(/b/.exec('abc'));
+//
+function matchValidator(expectedEntries, expectedIndex, expectedInput) {
+  return function(match) {
+    assert.compareArray(match, expectedEntries, 'Match entries');
+    assert.sameValue(match.index, expectedIndex, 'Match index');
+    assert.sameValue(match.input, expectedInput, 'Match input');
+  }
+}
diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/get-species-constructor-err.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/get-species-constructor-err.js
deleted file mode 100644
index 64028836ee..0000000000
--- a/test/built-ins/RegExp/prototype/Symbol.matchAll/get-species-constructor-err.js
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright (C) 2015 the V8 project authors. All rights reserved.
-// This code is governed by the BSD license found in the LICENSE file.
-
-/*---
-description: >
-    Behavior when error is thrown during retrieval of `Symbol.species` property
-info: |
-    3. Let C be ? SpeciesConstructor(R, %RegExp%).
-features: [Symbol.match, Symbol.matchAll, Symbol.species]
----*/
-
-var obj = {};
-Object.defineProperty(obj, Symbol.species, {
-  get: function () {
-    throw new Test262Error();
-  }
-});
-obj[Symbol.match] = true;
-
-assert.throws(Test262Error, function() {
-  RegExp.prototype[Symbol.matchAll].call(obj);
-});
diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/internal-regexp-lastindex-not-zero.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/internal-regexp-lastindex-not-zero.js
new file mode 100644
index 0000000000..944ef30989
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/internal-regexp-lastindex-not-zero.js
@@ -0,0 +1,33 @@
+// 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 internally created RegExp's lastIndex is not 0
+info: |
+  RegExp.prototype [ @@matchAll ] ( string )
+    [...]
+    3. Return ? MatchAllIterator(R, string).
+
+  MatchAllIterator ( R, O )
+    [...]
+    2. If ? IsRegExp(R) is true, then
+      [...]
+    3. Else,
+      a. Let matcher be RegExpCreate(R, "g").
+      b. If ? IsRegExp(matcher) is not true, throw a TypeError exception.
+      [...]
+      3. If Get(matcher, "lastIndex") is not 0, throw a TypeError exception.
+features: [Symbol.match, Symbol.matchAll]
+---*/
+
+Object.defineProperty(RegExp.prototype, Symbol.match, {
+  get() {
+    this.lastIndex = 1;
+    return true;
+  }
+});
+
+assert.throws(TypeError, function() {
+  RegExp.prototype[Symbol.matchAll].call({}, '');
+});
diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/isregexp-internal-regexp-is-false.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/isregexp-internal-regexp-is-false.js
new file mode 100644
index 0000000000..214e9b7efd
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/isregexp-internal-regexp-is-false.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: Throws TypeError when internally created RegExp's @@match is false
+info: |
+  RegExp.prototype [ @@matchAll ] ( string )
+    [...]
+    3. Return ? MatchAllIterator(R, string).
+
+  MatchAllIterator ( R, O )
+    [...]
+    2. If ? IsRegExp(R) is true, then
+      [...]
+    3. Else,
+      a. Let matcher be RegExpCreate(R, "g").
+      b. If ? IsRegExp(matcher) is not true, throw a TypeError exception.
+features: [Symbol.match, Symbol.matchAll]
+---*/
+
+Object.defineProperty(RegExp.prototype, Symbol.match, {
+  get() {
+    return false;
+  }
+});
+
+assert.throws(TypeError, function() {
+  RegExp.prototype[Symbol.matchAll].call({}, '');
+});
diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/isregexp-internal-regexp-throws.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/isregexp-internal-regexp-throws.js
new file mode 100644
index 0000000000..70b62da39f
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/isregexp-internal-regexp-throws.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: Re-throws errors thrown while accessing @@match property
+info: |
+  RegExp.prototype [ @@matchAll ] ( string )
+    [...]
+    3. Return ? MatchAllIterator(R, string).
+
+  MatchAllIterator ( R, O )
+    [...]
+    2. If ? IsRegExp(R) is true, then
+      [...]
+    3. Else,
+      a. Let matcher be RegExpCreate(R, "g").
+      b. If ? IsRegExp(matcher) is not true, throw a TypeError exception.
+features: [Symbol.match, Symbol.matchAll]
+---*/
+
+Object.defineProperty(RegExp.prototype, Symbol.match, {
+  get() {
+    throw new Test262Error();
+  }
+});
+
+assert.throws(Test262Error, function() {
+  RegExp.prototype[Symbol.matchAll].call({}, '');
+});
diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/isregexp-this-throws.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/isregexp-this-throws.js
new file mode 100644
index 0000000000..ce31f3392f
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/isregexp-this-throws.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: Re-throws errors thrown while accessing RegExp's @@match property
+info: |
+  RegExp.prototype [ @@matchAll ] ( string )
+    [...]
+    3. Return ? MatchAllIterator(R, string).
+
+  MatchAllIterator ( R, O )
+    [...]
+    2. If ? IsRegExp(R) is true, then
+      [...]
+features: [Symbol.match, Symbol.matchAll]
+---*/
+
+var obj = {
+  get [Symbol.match]() {
+    throw new Test262Error();
+  }
+};
+
+assert.throws(Test262Error, function() {
+  RegExp.prototype[Symbol.matchAll].call(obj, '');
+});
diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/length.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/length.js
index 241d3d40ce..7aee38c0cb 100644
--- a/test/built-ins/RegExp/prototype/Symbol.matchAll/length.js
+++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/length.js
@@ -1,17 +1,22 @@
 // Copyright (C) 2018 Jordan Harband. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 /*---
+esid: pending
 description: RegExp.prototype[Symbol.matchAll] `length` property
 info: |
-    ES6 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.
+  17 ECMAScript Standard Built-in Objects:
 
     [...]
 
-    Unless otherwise specified, the length property of a built-in Function
+    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. Optional parameters
+    (which are indicated with brackets: [ ]) or rest parameters (which
+    are 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]
diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/name.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/name.js
index a755118e00..b603021642 100644
--- a/test/built-ins/RegExp/prototype/Symbol.matchAll/name.js
+++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/name.js
@@ -1,15 +1,20 @@
 // Copyright (C) 2018 Jordan Harband. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 /*---
+esid: pending
 description: RegExp.prototype[Symbol.matchAll] `name` property
 info: |
-    The value of the name property of this function is "[Symbol.matchAll]".
+  17 ECMAScript Standard Built-in Objects:
 
-    ES6 Section 17:
+    [...]
+
+    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
+    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]
diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/prop-desc.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/prop-desc.js
index df4f7955db..63d27c57b7 100644
--- a/test/built-ins/RegExp/prototype/Symbol.matchAll/prop-desc.js
+++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/prop-desc.js
@@ -1,10 +1,12 @@
 // Copyright (C) 2018 Jordan Harband. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
-
 /*---
+esid: pending
 description: RegExp.prototype[Symbol.matchAll] property descriptor
 info: |
-    ES6 Section 17
+  17 ECMAScript Standard Built-in Objects:
+
+    [...]
 
     Every other data property described in clauses 18 through 26 and in Annex
     B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false,
@@ -14,6 +16,7 @@ features: [Symbol.matchAll]
 ---*/
 
 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/regexpcreate-this-throws.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/regexpcreate-this-throws.js
new file mode 100644
index 0000000000..d34b563c28
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/regexpcreate-this-throws.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: Re-throws errors while creating an internal RegExp
+info: |
+  RegExp.prototype [ @@matchAll ] ( string )
+    [...]
+    3. Return ? MatchAllIterator(R, string).
+
+  MatchAllIterator ( R, O )
+    [...]
+    2. If ? IsRegExp(R) is true, then
+      [...]
+    3. Else,
+      a. Let R be RegExpCreate(R, "g").
+features: [Symbol.matchAll]
+---*/
+
+var 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/species-constructor-get-constructor-throws.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-get-constructor-throws.js
new file mode 100644
index 0000000000..2c255853ee
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-get-constructor-throws.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: |
+  Re-throws errors thrown while accessing RegExp's constructor property
+info: |
+  RegExp.prototype [ @@matchAll ] ( string )
+    [...]
+    3. Return ? MatchAllIterator(R, string).
+
+  MatchAllIterator ( R, O )
+    [...]
+    2. If ? IsRegExp(R) is true, then
+      a. Let C be ? SpeciesConstructor(R, RegExp).
+
+  SpeciesConstructor ( O, defaultConstructor )
+    [...]
+    2. Let C be ? Get(O, "constructor").
+features: [Symbol.matchAll]
+---*/
+
+var regexp = /./;
+Object.defineProperty(regexp, 'constructor', {
+  get(){
+    throw new Test262Error();
+  }
+});
+
+assert.throws(Test262Error, function() {
+  regexp[Symbol.matchAll]('');
+});
diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-get-species-throws.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-get-species-throws.js
new file mode 100644
index 0000000000..3e429a88dc
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-get-species-throws.js
@@ -0,0 +1,31 @@
+// 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-throws errors thrown while accessing of @@species property
+info: |
+  RegExp.prototype [ @@matchAll ] ( string )
+    [...]
+    3. Return ? MatchAllIterator(R, string).
+
+  MatchAllIterator ( R, O )
+    [...]
+    2. If ? IsRegExp(R) is true, then
+      a. Let C be ? SpeciesConstructor(R, RegExp).
+
+  SpeciesConstructor ( O, defaultConstructor )
+    [...]
+    2. Let C be ? Get(O, "constructor").
+features: [Symbol.matchAll, Symbol.species]
+---*/
+
+var regexp = /./;
+regexp.constructor = {
+  get [Symbol.species]() {
+    throw new Test262Error();
+  }
+};
+
+assert.throws(Test262Error, function() {
+  regexp[Symbol.matchAll]('');
+});
diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-is-not-object-throws.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-is-not-object-throws.js
new file mode 100644
index 0000000000..d26752a941
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-is-not-object-throws.js
@@ -0,0 +1,41 @@
+// 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 if `constructor` property is not an object
+info: |
+  RegExp.prototype [ @@matchAll ] ( string )
+    [...]
+    3. Return ? MatchAllIterator(R, string).
+
+  MatchAllIterator ( R, O )
+    [...]
+    2. If ? IsRegExp(R) is true, then
+      a. Let C be ? SpeciesConstructor(R, RegExp).
+
+  SpeciesConstructor ( O, defaultConstructor )
+    [...]
+    2. Let C be ? Get(O, "constructor").
+    3. If C is undefined, return defaultConstructor.
+    4. If Type(C) is not Object, throw a TypeError exception.
+features: [Symbol.matchAll]
+---*/
+
+var regexp = /./;
+
+function callMatchAll() { regexp[Symbol.matchAll](''); }
+
+regexp.constructor = null;
+assert.throws(TypeError, callMatchAll, "`constructor` value is null");
+
+regexp.constructor = true;
+assert.throws(TypeError, callMatchAll, "`constructor` value is Boolean");
+
+regexp.constructor = "";
+assert.throws(TypeError, callMatchAll, "`constructor` value is String");
+
+regexp.constructor = Symbol();
+assert.throws(TypeError, callMatchAll, "`constructor` value is Symbol");
+
+regexp.constructor = 1;
+assert.throws(TypeError, callMatchAll, "`constructor` value is Number");
diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-is-undefined.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-is-undefined.js
new file mode 100644
index 0000000000..792bb1e7f8
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-is-undefined.js
@@ -0,0 +1,31 @@
+// 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 if `constructor` property is not an object
+info: |
+  RegExp.prototype [ @@matchAll ] ( string )
+    [...]
+    3. Return ? MatchAllIterator(R, string).
+
+  MatchAllIterator ( R, O )
+    [...]
+    2. If ? IsRegExp(R) is true, then
+      a. Let C be ? SpeciesConstructor(R, RegExp).
+
+  SpeciesConstructor ( O, defaultConstructor )
+    [...]
+    2. Let C be ? Get(O, "constructor").
+    3. If C is undefined, return defaultConstructor.
+features: [Symbol.matchAll]
+includes: [compareArray.js, compareIterator.js, regExpUtils.js]
+---*/
+
+var regexp = /\w/g;
+regexp.constructor = undefined;
+var str = 'a*b';
+
+assert.compareIterator(regexp[Symbol.matchAll](str), [
+  matchValidator(['a'], 0, str),
+  matchValidator(['b'], 2, str)
+]);
diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-species-is-not-constructor.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-species-is-not-constructor.js
new file mode 100644
index 0000000000..b47402d7d6
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-species-is-not-constructor.js
@@ -0,0 +1,45 @@
+// Copyright (C) 2018 Peter Wong. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: TypeError is thrown when species constructor is not a constructor
+info: |
+  RegExp.prototype [ @@matchAll ] ( string )
+    [...]
+    2. Return ? [MatchAllIterator](#matchalliterator)(R, string).
+
+  MatchAllIterator ( R, O )
+    [...]
+    3. Let C be ? [SpeciesConstructor][species-constructor](R, RegExp).
+
+  SpeciesConstructor ( O, defaultConstructor )
+    [...]
+    2. Let C be ? Get(O, "constructor").
+    3. If C is undefined, return defaultConstructor.
+    4. If Type(C) is not Object, throw a TypeError exception.
+    5. Let S be ? Get(C, @@species).
+    6. If S is either undefined or null, return defaultConstructor.
+    7. If IsConstructor(S) is true, return S.
+    8. Throw a TypeError exception.
+features: [Symbol.matchAll, Symbol.species]
+---*/
+
+var regexp = /./;
+var speciesConstructor = {};
+regexp.constructor = speciesConstructor;
+
+var callMatchAll = function() {
+  regexp[Symbol.matchAll]('');
+}
+
+speciesConstructor[Symbol.species] = true;
+assert.throws(TypeError, callMatchAll, "`constructor[Symbol.species]` value is Boolean");
+
+speciesConstructor[Symbol.species] = 1;
+assert.throws(TypeError, callMatchAll, "`constructor[Symbol.species]` value is Number");
+
+speciesConstructor[Symbol.species] = Symbol();
+assert.throws(TypeError, callMatchAll, "`constructor[Symbol.species]` value is Symbol");
+
+speciesConstructor[Symbol.species] = true;
+assert.throws(TypeError, callMatchAll, "`constructor[Symbol.species]` value is Boolean");
diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-species-is-null-or-undefined.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-species-is-null-or-undefined.js
new file mode 100644
index 0000000000..564d8bb58b
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-species-is-null-or-undefined.js
@@ -0,0 +1,41 @@
+// Copyright (C) 2018 Peter Wong. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: |
+  Default constructor is used when species constructor is null or undefined
+info: |
+  RegExp.prototype [ @@matchAll ] ( string )
+    [...]
+    2. Return ? [MatchAllIterator](#matchalliterator)(R, string).
+
+  MatchAllIterator ( R, O )
+    [...]
+    3. Let C be ? [SpeciesConstructor][species-constructor](R, RegExp).
+
+  SpeciesConstructor ( O, defaultConstructor )
+    [...]
+    2. Let C be ? Get(O, "constructor").
+    3. If C is undefined, return defaultConstructor.
+    4. If Type(C) is not Object, throw a TypeError exception.
+    5. Let S be ? Get(C, @@species).
+    6. If S is either undefined or null, return defaultConstructor.
+features: [Symbol.matchAll, Symbol.species]
+includes: [compareArray.js, compareIterator.js, regExpUtils.js]
+---*/
+
+function TestWithConstructor(ctor) {
+  var regexp = /\w/g;
+  regexp.constructor = {
+    [Symbol.species]: ctor
+  };
+  var str = 'a*b';
+
+  assert.compareIterator(regexp[Symbol.matchAll](str), [
+    matchValidator(['a'], 0, str),
+    matchValidator(['b'], 2, str)
+  ]);
+}
+
+TestWithConstructor(undefined);
+TestWithConstructor(null);
diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-species-throws.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-species-throws.js
new file mode 100644
index 0000000000..70a6683f48
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor-species-throws.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: Re-throws errors when calling constructor's @@species
+info: |
+  RegExp.prototype [ @@matchAll ] ( string )
+    [...]
+    3. Return ? MatchAllIterator(R, string).
+
+  MatchAllIterator ( R, O )
+    [...]
+    2. If ? IsRegExp(R) is true, then
+      a. Let C be ? SpeciesConstructor(R, RegExp).
+      b. Let flags be ? ToString(? Get(R, "flags"))
+      c. Let matcher be ? Construct(C, R, flags).
+features: [Symbol.matchAll, Symbol.species]
+---*/
+
+var regexp = /./;
+regexp.constructor = {
+  [Symbol.species]: function() {
+    throw new Test262Error();
+  }
+};
+
+assert.throws(Test262Error, function() {
+  regexp[Symbol.matchAll]('');
+});
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 0000000000..cb9e9bf03c
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-constructor.js
@@ -0,0 +1,42 @@
+// Copyright (C) 2018 Peter Wong. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: Custom species constructor is called when creating internal RegExp
+info: |
+  RegExp.prototype [ @@matchAll ] ( string )
+    [...]
+    3. Return ? MatchAllIterator(R, string).
+
+  MatchAllIterator ( R, O )
+    [...]
+    2. If ? IsRegExp(R) is true, then
+      a. Let C be ? SpeciesConstructor(R, RegExp).
+      b. Let flags be ? ToString(? Get(R, "flags"))
+      c. Let matcher be ? Construct(C, R, flags).
+features: [Symbol.matchAll, Symbol.species]
+includes: [compareArray.js, compareIterator.js, regExpUtils.js]
+---*/
+
+var callCount = 0;
+var callArgs;
+var regexp = /\d/u;
+regexp.constructor = {
+  [Symbol.species]: function(){
+    callCount++;
+    callArgs = arguments;
+    return /\w/g;
+  }
+};
+var str = 'a*b';
+var iter = regexp[Symbol.matchAll](str);
+
+assert.sameValue(callCount, 1);
+assert.sameValue(callArgs.length, 2);
+assert.sameValue(callArgs[0], regexp);
+assert.sameValue(callArgs[1], 'u');
+
+assert.compareIterator(iter, [
+  matchValidator(['a'], 0, str),
+  matchValidator(['b'], 2, str)
+]);
diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/species-regexp-get-global-throws.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-regexp-get-global-throws.js
new file mode 100644
index 0000000000..46304cc84a
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-regexp-get-global-throws.js
@@ -0,0 +1,34 @@
+// 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-throws errors thrown while accessing species constructed RegExp's
+  global property
+info: |
+  RegExp.prototype [ @@matchAll ] ( string )
+    [...]
+    3. Return ? MatchAllIterator(R, string).
+
+  MatchAllIterator ( R, O )
+    [...]
+    2. If ? IsRegExp(R) is true, then
+      [...]
+      d. Let global be ? ToBoolean(? Get(matcher, "global")).
+features: [Symbol.matchAll, Symbol.species]
+---*/
+
+var regexp = /./;
+regexp.constructor = {
+  [Symbol.species]: function() {
+    return Object.defineProperty(/./, 'global', {
+      get() {
+        throw new Test262Error();
+      }
+    });
+  }
+};
+
+assert.throws(Test262Error, function() {
+  regexp[Symbol.matchAll]('');
+});
diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/species-regexp-get-unicode-throws.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-regexp-get-unicode-throws.js
new file mode 100644
index 0000000000..931b028995
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/species-regexp-get-unicode-throws.js
@@ -0,0 +1,34 @@
+// 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-throws errors thrown while accessing species constructed RegExp's
+  unicode property
+info: |
+  RegExp.prototype [ @@matchAll ] ( string )
+    [...]
+    3. Return ? MatchAllIterator(R, string).
+
+  MatchAllIterator ( R, O )
+    [...]
+    2. If ? IsRegExp(R) is true, then
+      [...]
+      e. Let fullUnicode be ? ToBoolean(? Get(matcher, "unicode")).
+features: [Symbol.matchAll, Symbol.species]
+---*/
+
+var regexp = /./;
+regexp.constructor = {
+  [Symbol.species]: function() {
+    return Object.defineProperty(/./, 'unicode', {
+      get() {
+        throw new Test262Error();
+      }
+    });
+  }
+};
+
+assert.throws(Test262Error, function() {
+  regexp[Symbol.matchAll]('');
+});
diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/coerce-arg.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/string-tostring-throws.js
similarity index 59%
rename from test/built-ins/RegExp/prototype/Symbol.matchAll/coerce-arg.js
rename to test/built-ins/RegExp/prototype/Symbol.matchAll/string-tostring-throws.js
index b2557aae99..672ba5792c 100644
--- a/test/built-ins/RegExp/prototype/Symbol.matchAll/coerce-arg.js
+++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/string-tostring-throws.js
@@ -1,27 +1,27 @@
 // Copyright (C) 2018 Jordan Harband. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
-
 /*---
+esid: pending
 description: String coercion of string parameter
 info: |
-    RegExp.prototype [ @@matchAll ] ( string )
-
+  RegExp.prototype [ @@matchAll ] ( string )
     [...]
-    2. Let S be ? ToString(O).
-    [...]
-features: [Symbol.match, Symbol.matchAll]
+    3. Return ? MatchAllIterator(R, string).
+
+  MatchAllIterator ( R, O )
+    1. Let S be ? ToString(O).
+features: [Symbol.matchAll]
 ---*/
 
 var obj = {
-  valueOf: function() {
+  valueOf() {
     $ERROR('This method should not be invoked.');
   },
-  toString: function() {
+  toString() {
     throw new Test262Error('toString invoked');
   }
 };
-obj[Symbol.match] = true;
 
-assert.throws(Test262Error, function () {
+assert.throws(Test262Error, function() {
   /toString value/[Symbol.matchAll](obj);
 });
diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/string-tostring.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/string-tostring.js
new file mode 100644
index 0000000000..bafeb125b6
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/string-tostring.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: String coercion of `string` argument
+info: |
+  RegExp.prototype [ @@matchAll ] ( string )
+    [...]
+    3. Return ? MatchAllIterator(R, string).
+
+  MatchAllIterator ( R, O )
+    1. Let S be ? ToString(O).
+features: [Symbol.matchAll]
+includes: [compareArray.js, compareIterator.js, regExpUtils.js]
+---*/
+
+var str = 'a*b';
+var obj = {
+  toString() {
+    return str;
+  }
+};
+var regexp = /\w/g;
+
+assert.compareIterator(regexp[Symbol.matchAll](obj), [
+  matchValidator(['a'], 0, str),
+  matchValidator(['b'], 2, str)
+]);
+
diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/this-get-flags-throws.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/this-get-flags-throws.js
new file mode 100644
index 0000000000..0f21590b74
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/this-get-flags-throws.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: Re-throws errors thrown while accessing RegExp's flags property
+info: |
+  RegExp.prototype [ @@matchAll ] ( string )
+    [...]
+    3. Return ? MatchAllIterator(R, string).
+
+  MatchAllIterator ( R, O )
+    [...]
+    2. If ? IsRegExp(R) is true, then
+      [...]
+      b. Let flags be ? ToString(? Get(R, "flags"))
+features: [Symbol.matchAll]
+---*/
+
+var regexp = /./;
+Object.defineProperty(regexp, 'flags', {
+  get() {
+    throw new Test262Error();
+  }
+});
+
+assert.throws(Test262Error, function() {
+  regexp[Symbol.matchAll]('');
+});
diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/this-get-flags.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/this-get-flags.js
new file mode 100644
index 0000000000..eca4ffa4d4
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/this-get-flags.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: Regexp's flags
+info: |
+  RegExp.prototype [ @@matchAll ] ( string )
+    [...]
+    3. Return ? MatchAllIterator(R, string).
+
+  MatchAllIterator ( R, O )
+    [...]
+    2. If ? IsRegExp(R) is true, then
+      [...]
+      b. Let flags be ? ToString(? Get(R, "flags"))
+features: [Symbol.matchAll]
+includes: [compareArray.js, compareIterator.js, regExpUtils.js]
+---*/
+
+var regexp = /\w/;
+Object.defineProperty(regexp, 'flags', {
+  value: 'g'
+});
+var str = 'a*b';
+
+assert.compareIterator(regexp[Symbol.matchAll](str), [
+  matchValidator(['a'], 0, str),
+  matchValidator(['b'], 2, str)
+]);
diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/this-lastindex-cached.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/this-lastindex-cached.js
new file mode 100644
index 0000000000..ebefdb4e38
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/this-lastindex-cached.js
@@ -0,0 +1,36 @@
+// Copyright (C) 2018 Peter Wong. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: Verify regexp's lastIndex is cached
+info: |
+  RegExp.prototype [ @@matchAll ] ( string )
+    [...]
+    3. Return ? MatchAllIterator(R, string).
+
+  MatchAllIterator ( R, O )
+    [...]
+    2. If ? IsRegExp(R) is true, then
+      [...]
+      f. Let lastIndex be ? ToLength(? Get(R, "lastIndex")).
+      g. Perform ? Set(matcher, "lastIndex", lastIndex, true).
+features: [Symbol.matchAll]
+includes: [compareArray.js, compareIterator.js, regExpUtils.js]
+---*/
+
+var regexp = /./g;
+regexp.lastIndex = {
+  valueOf() {
+    return 2;
+  }
+};
+var str = 'abcd';
+var iter = regexp[Symbol.matchAll](str);
+
+// Verify lastIndex is cached at the time of calling @@matchAll
+regexp.lastIndex = 0;
+
+assert.compareIterator(iter, [
+  matchValidator(['c'], 2, str),
+  matchValidator(['d'], 3, str)
+]);
diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/this-not-object-throws.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/this-not-object-throws.js
new file mode 100644
index 0000000000..b8f350d05f
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/this-not-object-throws.js
@@ -0,0 +1,31 @@
+// Copyright (C) 2018 Jordan Harband. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: Throws TypeError when `this` is not an Object
+info: |
+  RegExp.prototype [ @@matchAll ] ( string )
+    1. Let R be the this value.
+    2. If Type(R) is not Object, throw a TypeError exception.
+features: [Symbol.matchAll]
+---*/
+
+var thisValue;
+var callMatchAll = function() {
+  RegExp.prototype[Symbol.matchAll].call(thisValue, '');
+};
+
+thisValue = null;
+assert.throws(TypeError, callMatchAll, 'this value is null');
+
+thisValue = true;
+assert.throws(TypeError, callMatchAll, 'this value is Boolean');
+
+thisValue = '';
+assert.throws(TypeError, callMatchAll, 'this value is String');
+
+thisValue = Symbol();
+assert.throws(TypeError, callMatchAll, 'this value is Symbol');
+
+thisValue = 1;
+assert.throws(TypeError, callMatchAll, 'this value is Number');
diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/this-tolength-lastindex-throws.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/this-tolength-lastindex-throws.js
new file mode 100644
index 0000000000..fcaefdaf41
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/this-tolength-lastindex-throws.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: Re-throws errors while coercing RegExp's lastIndex
+info: |
+  RegExp.prototype [ @@matchAll ] ( string )
+    [...]
+    3. Return ? MatchAllIterator(R, string).
+
+  MatchAllIterator ( R, O )
+    [...]
+    2. If ? IsRegExp(R) is true, then
+      [...]
+      f. Let lastIndex be ? ToLength(? Get(R, "lastIndex")).
+features: [Symbol.matchAll]
+---*/
+
+var regexp = /./;
+regexp.lastIndex = {
+  valueOf() {
+    throw new Test262Error();
+  }
+};
+
+assert.throws(Test262Error, function() {
+  regexp[Symbol.matchAll]('');
+});
diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/this-tostring-flags-throws.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/this-tostring-flags-throws.js
new file mode 100644
index 0000000000..206cc65d10
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/this-tostring-flags-throws.js
@@ -0,0 +1,33 @@
+// 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-throws errors while coercing RegExp's flags to a string
+info: |
+  RegExp.prototype [ @@matchAll ] ( string )
+    [...]
+    3. Return ? MatchAllIterator(R, string).
+
+  MatchAllIterator ( R, O )
+    [...]
+    2. If ? IsRegExp(R) is true, then
+      [...]
+      b. Let flags be ? ToString(? Get(R, "flags"))
+features: [Symbol.matchAll]
+---*/
+
+var regexp = /\w/;
+Object.defineProperty(regexp, 'flags', {
+  value: {
+    valueOf() {
+      ERROR('valueOf Should not be called');
+    },
+    toString() {
+      throw new Test262Error();
+    }
+  }
+});
+
+assert.throws(Test262Error, function() {
+  regexp[Symbol.matchAll]('');
+});
diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/this-tostring-flags.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/this-tostring-flags.js
new file mode 100644
index 0000000000..5c7f9cb815
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.matchAll/this-tostring-flags.js
@@ -0,0 +1,33 @@
+// Copyright (C) 2018 Peter Wong. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: Corercing regexp's flags
+info: |
+  RegExp.prototype [ @@matchAll ] ( string )
+    [...]
+    3. Return ? MatchAllIterator(R, string).
+
+  MatchAllIterator ( R, O )
+    [...]
+    2. If ? IsRegExp(R) is true, then
+      [...]
+      b. Let flags be ? ToString(? Get(R, "flags"))
+features: [Symbol.matchAll]
+includes: [compareArray.js, compareIterator.js, regExpUtils.js]
+---*/
+
+var regexp = /\w/;
+Object.defineProperty(regexp, 'flags', {
+  value: {
+    toString() {
+      return 'g';
+    }
+  }
+});
+var str = 'a*b';
+
+assert.compareIterator(regexp[Symbol.matchAll](str), [
+  matchValidator(['a'], 0, str),
+  matchValidator(['b'], 2, str)
+]);
diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/this-val-non-obj.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/this-val-non-obj.js
deleted file mode 100644
index b4469f2ac7..0000000000
--- a/test/built-ins/RegExp/prototype/Symbol.matchAll/this-val-non-obj.js
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (C) 2018 Jordan Harband. All rights reserved.
-// This code is governed by the BSD license found in the LICENSE file.
-
-/*---
-description: The `this` value must be an object
-info: |
-    1. Let R be the this value.
-    2. Return ? MatchAllIterator(R, string).
-    [...]
-    1. If ? IsRegExp(R) is not true, throw a TypeError exception.
-features: [Symbol.matchAll]
----*/
-
-assert.throws(TypeError, function() {
-  RegExp.prototype[Symbol.matchAll].call(undefined);
-});
-
-assert.throws(TypeError, function() {
-  RegExp.prototype[Symbol.matchAll].call(null);
-});
-
-assert.throws(TypeError, function() {
-  RegExp.prototype[Symbol.matchAll].call(true);
-});
-
-assert.throws(TypeError, function() {
-  RegExp.prototype[Symbol.matchAll].call('string');
-});
-
-assert.throws(TypeError, function() {
-  RegExp.prototype[Symbol.matchAll].call(Symbol.matchAll);
-});
-
-assert.throws(TypeError, function() {
-  RegExp.prototype[Symbol.matchAll].call(86);
-});
diff --git a/test/built-ins/RegExp/prototype/Symbol.matchAll/this-val-non-regexp.js b/test/built-ins/RegExp/prototype/Symbol.matchAll/this-val-non-regexp.js
deleted file mode 100644
index 76a57831cb..0000000000
--- a/test/built-ins/RegExp/prototype/Symbol.matchAll/this-val-non-regexp.js
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright (C) 2018 Jordan Harband. All rights reserved.
-// This code is governed by the BSD license found in the LICENSE file.
-
-/*---
-description: The `this` value must be a regular expression (has Symbol.match)
-info: |
-    1. Let R be the this value.
-    2. Return ? MatchAllIterator(R, string).
-    [...]
-    1. If ? IsRegExp(R) is not true, throw a TypeError exception.
-features: [Symbol.match, Symbol.matchAll]
----*/
-
-var regexObj = {};
-regexObj[Symbol.match] = true;
-var obj = {};
-
-RegExp.prototype[Symbol.matchAll].call(regexObj);
-
-assert.throws(TypeError, function() {
-  RegExp.prototype[Symbol.matchAll].call(obj);
-});
diff --git a/test/built-ins/RegExpStringIteratorPrototype/Symbol.toStringTag.js b/test/built-ins/RegExpStringIteratorPrototype/Symbol.toStringTag.js
new file mode 100644
index 0000000000..a412432545
--- /dev/null
+++ b/test/built-ins/RegExpStringIteratorPrototype/Symbol.toStringTag.js
@@ -0,0 +1,23 @@
+// Copyright (C) 2018 Peter Wong. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: 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.matchAll, Symbol.toStringTag]
+includes: [propertyHelper.js]
+---*/
+
+var RegExpStringIteratorProto = Object.getPrototypeOf(/./[Symbol.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 0000000000..f7a6e7b6cb
--- /dev/null
+++ b/test/built-ins/RegExpStringIteratorPrototype/ancestry.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: |
+    The [[Prototype]] internal slot ofthe %RegExpStringIteratorPrototype% is the
+    %IteratorPrototype% intrinsic object (25.1.2).
+features: [Symbol.iterator, Symbol.matchAll]
+---*/
+
+var RegExpStringIteratorProto = Object.getPrototypeOf(/./[Symbol.matchAll]('a'));
+var ArrayIteratorProto = Object.getPrototypeOf(
+  Object.getPrototypeOf([][Symbol.iterator]())
+);
+
+assert.sameValue(Object.getPrototypeOf(RegExpStringIteratorProto), ArrayIteratorProto);
diff --git a/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-call-throws.js b/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-call-throws.js
new file mode 100644
index 0000000000..74df2c83d1
--- /dev/null
+++ b/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-call-throws.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: Re-throws errors when calling exec
+info: |
+  %RegExpStringIteratorPrototype%.next ( )
+    [...]
+    9. Let match be ? RegExpExec(R, S).
+
+  Runtime Semantics: RegExpExec ( R, S )
+    1. Assert: Type(R) is Object.
+    2. Assert: Type(S) is String.
+    3. Let exec be ? Get(R, "exec").
+    4. If IsCallable(exec) is true, then
+      a. Let result be ? Call(exec, R, « S »).
+features: [Symbol.matchAll]
+---*/
+
+var iter = /./[Symbol.matchAll]('');
+
+RegExp.prototype.exec = function() {
+  throw new Test262Error();
+};
+
+assert.throws(Test262Error, function() {
+  iter.next();
+});
diff --git a/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-get-throws.js b/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-get-throws.js
new file mode 100644
index 0000000000..808b142a21
--- /dev/null
+++ b/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-get-throws.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: Re-throws errors thrown while accessing RegExp's exec property
+info: |
+  %RegExpStringIteratorPrototype%.next ( )
+    [...]
+    9. Let match be ? RegExpExec(R, S).
+
+  Runtime Semantics: RegExpExec ( R, S )
+    1. Assert: Type(R) is Object.
+    2. Assert: Type(S) is String.
+    3. Let exec be ? Get(R, "exec").
+features: [Symbol.matchAll]
+---*/
+
+var iter = /./[Symbol.matchAll]('');
+
+Object.defineProperty(RegExp.prototype, 'exec', {
+  get() {
+    throw new Test262Error();
+  }
+});
+
+assert.throws(Test262Error, function() {
+  iter.next();
+});
diff --git a/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-match-get-0-throws.js b/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-match-get-0-throws.js
new file mode 100644
index 0000000000..7dc986da92
--- /dev/null
+++ b/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-match-get-0-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-throws errors thrown while accessing the first match
+info: |
+  %RegExpStringIteratorPrototype%.next ( )
+    [...]
+    9. Let match be ? RegExpExec(R, S).
+    10. If match is null, then
+      [...]
+    11. Else,
+      a. If global is true,
+        i. Let matchStr be ? ToString(? Get(match, "0")).
+features: [Symbol.matchAll]
+---*/
+
+var iter = /./g[Symbol.matchAll]('');
+
+RegExp.prototype.exec = function() {
+  return {
+    get '0'() {
+      throw new Test262Error();
+    }
+  };
+};
+
+assert.throws(Test262Error, function() {
+  iter.next();
+});
diff --git a/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-match-get-0-tostring-throws.js b/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-match-get-0-tostring-throws.js
new file mode 100644
index 0000000000..e84b3c4fc0
--- /dev/null
+++ b/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-match-get-0-tostring-throws.js
@@ -0,0 +1,31 @@
+// 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-throws errors thrown from coercing first match to a string
+info: |
+  %RegExpStringIteratorPrototype%.next ( )
+    [...]
+    9. Let match be ? RegExpExec(R, S).
+    10. If match is null, then
+      [...]
+    11. Else,
+      a. If global is true,
+        i. Let matchStr be ? ToString(? Get(match, "0")).
+features: [Symbol.matchAll]
+---*/
+
+var iter = /./g[Symbol.matchAll]('');
+
+RegExp.prototype.exec = function() {
+  return [{
+    toString: function() {
+      throw new Test262Error();
+    }
+  }];
+};
+
+assert.throws(Test262Error, function() {
+  iter.next();
+});
+
diff --git a/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-match-get-0-tostring.js b/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-match-get-0-tostring.js
new file mode 100644
index 0000000000..33ac742ca2
--- /dev/null
+++ b/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-match-get-0-tostring.js
@@ -0,0 +1,48 @@
+// Copyright (C) 2018 Peter Wong. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: Behavior when first match is coerced to a empty string
+info: |
+  %RegExpStringIteratorPrototype%.next ( )
+    [...]
+    9. Let match be ? RegExpExec(R, S).
+    10. If match is null, then
+      [...]
+    11. Else,
+      a. If global is true,
+        i. Let matchStr be ? ToString(? Get(match, "0")).
+        ii. If matchStr is the empty string,
+          1. Let thisIndex be ? ToLength(? Get(R, "lastIndex").
+          2. Let nextIndex be ! AdvanceStringIndex(S, thisIndex, fullUnicode).
+          3. Perform ? Set(R, "lastIndex", nextIndex, true).
+        iii. Return ! CreateIterResultObject(match, false).
+features: [Symbol.matchAll]
+---*/
+
+var iter = /./g[Symbol.matchAll]('');
+
+var execResult = {
+  get '0'() {
+    return {
+      toString() { return ''; }
+    };
+  }
+};
+
+var internalRegExp;
+RegExp.prototype.exec = function () {
+  internalRegExp = this;
+  return execResult;
+};
+
+var result = iter.next();
+assert.sameValue(internalRegExp.lastIndex, 1);
+assert.sameValue(result.value, execResult);
+assert(!result.done);
+
+
+result = iter.next();
+assert.sameValue(internalRegExp.lastIndex, 2);
+assert.sameValue(result.value, execResult);
+assert(!result.done);
diff --git a/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-not-callable.js b/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-not-callable.js
new file mode 100644
index 0000000000..d659cd28d4
--- /dev/null
+++ b/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec-not-callable.js
@@ -0,0 +1,40 @@
+// Copyright (C) 2018 Peter Wong. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: Behavior with a custom RegExp exec
+info: |
+  %RegExpStringIteratorPrototype%.next ( )
+    [...]
+    9. Let match be ? RegExpExec(R, S).
+
+  Runtime Semantics: RegExpExec ( R, S )
+    1. Assert: Type(R) is Object.
+    2. Assert: Type(S) is String.
+    3. Let exec be ? Get(R, "exec").
+    4. If IsCallable(exec) is true, then
+      [...]
+    5. If R does not have a [[RegExpMatcher]] internal slot, throw a
+       TypeError exception.
+    6. Return ? RegExpBuiltinExec(R, S).
+features: [Symbol.matchAll]
+includes: [compareArray.js, compareIterator.js, regExpUtils.js]
+---*/
+
+function TestWithRegExpExec(exec) {
+  RegExp.prototype.exec = exec;
+
+  var regexp = /\w/g;
+  var str = 'a*b';
+
+  assert.compareIterator(regexp[Symbol.matchAll](str), [
+    matchValidator(['a'], 0, str),
+    matchValidator(['b'], 2, str)
+  ]);
+}
+
+TestWithRegExpExec(undefined);
+TestWithRegExpExec(null);
+TestWithRegExpExec(5);
+TestWithRegExpExec(true);
+TestWithRegExpExec(Symbol());
diff --git a/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec.js b/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec.js
new file mode 100644
index 0000000000..850a7a18c0
--- /dev/null
+++ b/test/built-ins/RegExpStringIteratorPrototype/next/custom-regexpexec.js
@@ -0,0 +1,55 @@
+// Copyright (C) 2018 Peter Wong. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: Behavior with a custom RegExp exec
+info: |
+  %RegExpStringIteratorPrototype%.next ( )
+    [...]
+    9. Let match be ? RegExpExec(R, S).
+
+  Runtime Semantics: RegExpExec ( R, S )
+    1. Assert: Type(R) is Object.
+    2. Assert: Type(S) is String.
+    3. Let exec be ? Get(R, "exec").
+    4. If IsCallable(exec) is true, then
+      a. Let result be ? Call(exec, R, « S »).
+      b. If Type(result) is neither Object or Null, throw a TypeError exception.
+      c. Return result.
+features: [Symbol.matchAll]
+---*/
+
+var regexp = /./g;
+var str = 'abc';
+var iter = regexp[Symbol.matchAll](str);
+
+var callArgs, callCount;
+function callNextWithExecReturnValue(returnValue) {
+  callArgs = undefined;
+  callCount = 0;
+
+  RegExp.prototype.exec = function() {
+    callArgs = arguments;
+    callCount++;
+    return returnValue;
+  }
+
+  return iter.next();
+}
+
+var firstExecReturnValue = ['ab'];
+var result = callNextWithExecReturnValue(firstExecReturnValue);
+assert.sameValue(result.value, firstExecReturnValue);
+assert(!result.done);
+
+assert.sameValue(callArgs.length, 1);
+assert.sameValue(callArgs[0], str);
+assert.sameValue(callCount, 1);
+
+result = callNextWithExecReturnValue(null);
+assert.sameValue(result.value, undefined);
+assert(result.done);
+
+assert.sameValue(callArgs.length, 1);
+assert.sameValue(callArgs[0], str);
+assert.sameValue(callCount, 1);
diff --git a/test/built-ins/RegExpStringIteratorPrototype/next/length.js b/test/built-ins/RegExpStringIteratorPrototype/next/length.js
new file mode 100644
index 0000000000..b9ae0f0099
--- /dev/null
+++ b/test/built-ins/RegExpStringIteratorPrototype/next/length.js
@@ -0,0 +1,33 @@
+// 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` property
+info: |
+  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. Optional parameters
+    (which are indicated with brackets: [ ]) or rest parameters (which
+    are 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: [Symbol.matchAll]
+---*/
+
+var RegExpStringIteratorProto = Object.getPrototypeOf(/./[Symbol.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 0000000000..d9f275fbfe
--- /dev/null
+++ b/test/built-ins/RegExpStringIteratorPrototype/next/name.js
@@ -0,0 +1,31 @@
+// 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` property
+info: |
+  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: [Symbol.matchAll]
+---*/
+
+var RegExpStringIteratorProto = Object.getPrototypeOf(/./[Symbol.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-global.js b/test/built-ins/RegExpStringIteratorPrototype/next/next-iteration-global.js
new file mode 100644
index 0000000000..d1b6726e58
--- /dev/null
+++ b/test/built-ins/RegExpStringIteratorPrototype/next/next-iteration-global.js
@@ -0,0 +1,40 @@
+// Copyright (C) 2018 Peter Wong. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: Iterates over each match
+info: |
+  %RegExpStringIteratorPrototype%.next ( )
+    [...]
+    4. If O.[[Done]] is true, then
+      a. Return ! reateIterResultObject(undefined, true).
+    [...]
+    9. Let match be ? RegExpExec(R, S).
+    10. If match is null, then
+      a. Set O.[[Done]] to true.
+      b. Return ! CreateIterResultObject(undefined, true).
+    11. Else,
+      a. If global is true,
+        i. Let matchStr be ? ToString(? Get(match, "0")).
+        ii. If matchStr is the empty string,
+          1. Let thisIndex be ? ToLength(? Get(R, "lastIndex").
+          2. Let nextIndex be ! AdvanceStringIndex(S, thisIndex, fullUnicode).
+          3. Perform ? Set(R, "lastIndex", nextIndex, true).
+        iii. Return ! CreateIterResultObject(match, false).
+features: [Symbol.matchAll]
+includes: [compareArray.js, compareIterator.js, regExpUtils.js]
+---*/
+
+var regexp = /\w/g;
+var str = 'a*b';
+var iter = regexp[Symbol.matchAll](str);
+
+assert.compareIterator(iter, [
+  matchValidator(['a'], 0, str),
+  matchValidator(['b'], 2, str)
+]);
+
+// Verifies %RegExpStringIteratorPrototype%.next() step 4
+var result = iter.next();
+assert.sameValue(result.value, undefined);
+assert(result.done);
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 0000000000..a6de2ad8a9
--- /dev/null
+++ b/test/built-ins/RegExpStringIteratorPrototype/next/next-iteration.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: Iterates over the first match
+info: |
+  %RegExpStringIteratorPrototype%.next ( )
+    [...]
+    4. If O.[[Done]] is true, then
+      a. Return ! reateIterResultObject(undefined, true).
+    [...]
+    9. Let match be ? RegExpExec(R, S).
+    10. If match is null, then
+      a. Set O.[[Done]] to true.
+      b. Return ! CreateIterResultObject(undefined, true).
+    11. Else,
+      a. If global is true,
+        [...]
+      b. Else,
+        i. Set O.[[Done]] to true.
+        ii. Return ! CreateIterResultObject(match, false).
+features: [Symbol.matchAll]
+includes: [compareArray.js, compareIterator.js, regExpUtils.js]
+---*/
+
+var regexp = /\w/;
+var str = '*a*b';
+var iter = regexp[Symbol.matchAll](str);
+
+assert.compareIterator(iter, [
+  matchValidator(['a'], 1, str)
+]);
+
+// Verifies %RegExpStringIteratorPrototype%.next() step 4
+var result = iter.next();
+assert.sameValue(result.value, undefined);
+assert(result.done);
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 0000000000..826b2ae3c5
--- /dev/null
+++ b/test/built-ins/RegExpStringIteratorPrototype/next/next-missing-internal-slots.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: Throws TypeError when `this` does not have all internal slots
+info: |
+  %RegExpStringIteratorPrototype%.next ( )
+    1. Let O be the this value.
+    2. If Type(O) is not Object, throw a TypeError exception.
+    3. If O does not have all of the internal slots of a RegExp String Iterator
+       Object Instance (see PropertiesOfRegExpStringIteratorInstances), throw a
+       TypeError.
+features: [Symbol.matchAll]
+---*/
+
+var iterator = /./[Symbol.matchAll]('');
+var object = Object.create(iterator);
+
+assert.throws(TypeError, function() {
+  object.next();
+});
diff --git a/test/built-ins/RegExpStringIteratorPrototype/next/prop-desc.js b/test/built-ins/RegExpStringIteratorPrototype/next/prop-desc.js
new file mode 100644
index 0000000000..a679e0ae4c
--- /dev/null
+++ b/test/built-ins/RegExpStringIteratorPrototype/next/prop-desc.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: |
+  %RegExpStringIteratorPrototype%.next property descriptor
+info: |
+  17 ECMAScript Standard Built-in Objects:
+
+    [...]
+
+    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.
+includes: [propertyHelper.js]
+features: [Symbol.matchAll]
+---*/
+
+var RegExpStringIteratorProto = Object.getPrototypeOf(/./[Symbol.matchAll](''));
+
+assert.sameValue(typeof RegExpStringIteratorProto.next, 'function');
+
+verifyNotEnumerable(RegExpStringIteratorProto, 'next');
+verifyWritable(RegExpStringIteratorProto, 'next');
+verifyConfigurable(RegExpStringIteratorProto, 'next');
diff --git a/test/built-ins/RegExpStringIteratorPrototype/next/regexp-tolength-lastindex-throws.js b/test/built-ins/RegExpStringIteratorPrototype/next/regexp-tolength-lastindex-throws.js
new file mode 100644
index 0000000000..603393df67
--- /dev/null
+++ b/test/built-ins/RegExpStringIteratorPrototype/next/regexp-tolength-lastindex-throws.js
@@ -0,0 +1,33 @@
+// 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-throws errors thrown coercing RegExp's lastIndex to a length
+info: |
+  %RegExpStringIteratorPrototype%.next ( )
+    [...]
+    9. Let match be ? RegExpExec(R, S).
+    10. If match is null, then
+      [...]
+    11. Else,
+      a. If global is true,
+        i. Let matchStr be ? ToString(? Get(match, "0")).
+        ii. If matchStr is the empty string,
+          1. Let thisIndex be ? ToLength(? Get(R, "lastIndex").
+features: [Symbol.matchAll]
+---*/
+
+var iter = /./g[Symbol.matchAll]('');
+
+RegExp.prototype.exec = function() {
+  this.lastIndex = {
+    valueOf() {
+      throw new Test262Error();
+    }
+  };
+  return [''];
+};
+
+assert.throws(Test262Error, function() {
+  iter.next();
+});
diff --git a/test/built-ins/RegExpStringIteratorPrototype/next/this-is-not-object-throws.js b/test/built-ins/RegExpStringIteratorPrototype/next/this-is-not-object-throws.js
new file mode 100644
index 0000000000..4470ff19e8
--- /dev/null
+++ b/test/built-ins/RegExpStringIteratorPrototype/next/this-is-not-object-throws.js
@@ -0,0 +1,34 @@
+// 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 not an Object
+info: |
+  %RegExpStringIteratorPrototype%.next ( )
+    1. Let O be the this value.
+    2. If Type(O) is not Object, throw a TypeError exception.
+features: [Symbol.matchAll]
+---*/
+
+var RegExpStringIteratorProto = Object.getPrototypeOf(/./[Symbol.matchAll](''));
+
+var thisValue;
+var callNext = function() {
+  RegExpStringIteratorProto.next.call(thisValue);
+};
+
+thisValue = null;
+assert.throws(TypeError, callNext, 'this value is null');
+
+thisValue = true;
+assert.throws(TypeError, callNext, 'this value is Boolean');
+
+thisValue = '';
+assert.throws(TypeError, callNext, 'this value is String');
+
+thisValue = Symbol();
+assert.throws(TypeError, callNext, 'this value is Symbol');
+
+thisValue = 1;
+assert.throws(TypeError, callNext, 'this value is Number');
+
diff --git a/test/built-ins/String/prototype/matchAll/cstm-matcher-get-err.js b/test/built-ins/String/prototype/matchAll/cstm-matcher-get-err.js
deleted file mode 100644
index e18431c89d..0000000000
--- a/test/built-ins/String/prototype/matchAll/cstm-matcher-get-err.js
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright (C) 2018 Jordan Harband. All rights reserved.
-// This code is governed by the BSD license found in the LICENSE file.
-
-/*---
-description: Behavior when error is thrown accessing @@matchAll property
-info: |
-    [...]
-    4. Let matcher be ? GetMethod(R, @@matchAll).
-    5. If matcher is not undefined, then
-      a. Return ? Call(matcher, R, « O »).
-features: [Symbol.match, Symbol.matchAll]
----*/
-
-var obj = {};
-Object.defineProperty(obj, Symbol.match, {
-  value: true // to make IsRegExp pass
-});
-Object.defineProperty(obj, Symbol.matchAll, {
-  get: function() {
-    throw new Test262Error();
-  }
-});
-
-assert.throws(Test262Error, function() {
-  ''.matchAll(obj);
-});
diff --git a/test/built-ins/String/prototype/matchAll/invoke-builtin-matchall.js b/test/built-ins/String/prototype/matchAll/invoke-builtin-matchall.js
deleted file mode 100644
index feeb36bc6e..0000000000
--- a/test/built-ins/String/prototype/matchAll/invoke-builtin-matchall.js
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright (C) 2018 Jordan Harband. All rights reserved.
-// This code is governed by the BSD license found in the LICENSE file.
-
-/*---
-description: Invocation of @@matchAll property of internally-created RegExps
-info: |
-    [...]
-    3. Else,
-      a. Let R be ? RegExpCreate(regexp, "g").
-    4. Let matcher be ? GetMethod(R, @@matchAll).
-    5. If matcher is not undefined, then
-      a. Return ? Call(matcher, R, « O »).
-    6. Return ? MatchAllIterator(R, O).
-features: [Symbol.match, Symbol.matchAll]
----*/
-
-var originalMatchAll = RegExp.prototype[Symbol.matchAll];
-var returnVal = {};
-var result, thisVal, args;
-
-RegExp.prototype[Symbol.matchAll] = function() {
-  thisVal = this;
-  args = arguments;
-  return returnVal;
-};
-
-var str = 'target';
-var stringToMatch = 'string source';
-
-try {
-  result = str.matchAll(stringToMatch);
-
-  assert(thisVal instanceof RegExp);
-  assert.sameValue(!!thisVal[Symbol.match], true);
-  assert.sameValue(thisVal.source, stringToMatch);
-  assert.sameValue(thisVal.flags, 'g');
-  assert.sameValue(thisVal.lastIndex, 0);
-  assert.sameValue(args.length, 1);
-  assert.sameValue(args[0], str);
-  assert.sameValue(result, returnVal);
-} finally {
-  RegExp.prototype[Symbol.matchAll] = originalMatchAll;
-}
diff --git a/test/built-ins/String/prototype/matchAll/length.js b/test/built-ins/String/prototype/matchAll/length.js
index fd5f0104c4..101d8bbf2e 100644
--- a/test/built-ins/String/prototype/matchAll/length.js
+++ b/test/built-ins/String/prototype/matchAll/length.js
@@ -1,20 +1,26 @@
 // Copyright (C) 2018 Jordan Harband. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 /*---
-description: Length of String.prototype.matchAll
+esid: pending
+description: String.prototype.matchAll `length` property
 info: |
-    ES6 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.
+  17 ECMAScript Standard Built-in Objects:
 
     [...]
 
-    Unless otherwise specified, the length property of a built-in Function
+    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. Optional parameters
+    (which are indicated with brackets: [ ]) or rest parameters (which
+    are 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: [String.prototype.matchAll]
 ---*/
 
 assert.sameValue(String.prototype.matchAll.length, 1);
diff --git a/test/built-ins/String/prototype/matchAll/name.js b/test/built-ins/String/prototype/matchAll/name.js
index 84bb3cf647..cef87994c1 100644
--- a/test/built-ins/String/prototype/matchAll/name.js
+++ b/test/built-ins/String/prototype/matchAll/name.js
@@ -1,27 +1,28 @@
 // Copyright (C) 2018 Jordan Harband. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 /*---
-description: Descriptor for `name` property
+esid: pending
+description: String.prototype.matchAll `name` property
 info: |
-  The value of the name property of this function is "matchAll".
+  17 ECMAScript Standard Built-in Objects:
 
-  ES6 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.
+    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 }.
+    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: [String.prototype.matchAll]
 ---*/
 
-assert.sameValue(String.prototype[Symbol.iterator].name, 'matchAll');
+assert.sameValue(String.prototype.matchAll.name, 'matchAll');
 
-verifyNotEnumerable(String.prototype[Symbol.iterator], 'name');
-verifyNotWritable(String.prototype[Symbol.iterator], 'name');
-verifyConfigurable(String.prototype[Symbol.iterator], 'name');
+verifyNotEnumerable(String.prototype.matchAll, 'name');
+verifyNotWritable(String.prototype.matchAll, 'name');
+verifyConfigurable(String.prototype.matchAll, 'name');
diff --git a/test/built-ins/String/prototype/matchAll/prop-desc.js b/test/built-ins/String/prototype/matchAll/prop-desc.js
index 02b9eaa714..eb1c59a60d 100644
--- a/test/built-ins/String/prototype/matchAll/prop-desc.js
+++ b/test/built-ins/String/prototype/matchAll/prop-desc.js
@@ -1,18 +1,22 @@
 // Copyright (C) 2018 Jordan Harband. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 /*---
-description: Property descriptor
+esid: pending
+description: String.prototype.matchAll property descriptor
 info: |
-    ES6 Section 17
+  17 ECMAScript Standard Built-in Objects:
+
+    [...]
 
     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.iterator]
 includes: [propertyHelper.js]
+features: [String.prototype.matchAll]
 ---*/
 
 assert.sameValue(typeof String.prototype.matchAll, 'function');
+
 verifyNotEnumerable(String.prototype, 'matchAll');
 verifyWritable(String.prototype, 'matchAll');
 verifyConfigurable(String.prototype, 'matchAll');
diff --git a/test/built-ins/String/prototype/matchAll/regexp-get-matchAll-throws.js b/test/built-ins/String/prototype/matchAll/regexp-get-matchAll-throws.js
new file mode 100644
index 0000000000..8c73480b05
--- /dev/null
+++ b/test/built-ins/String/prototype/matchAll/regexp-get-matchAll-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-throws errors when calling @@matchAll
+info: |
+  String.prototype.matchAll ( regexp )
+    [...]
+    2. If regexp is neither undefined nor null, then
+      a. Let matcher be ? GetMethod(regexp, @@matchAll).
+      b. If matcher is not undefined, then
+        i. Return ? Call(matcher, regexp, « O »).
+features: [Symbol.matchAll, String.prototype.matchAll]
+---*/
+
+var regexp = /./;
+Object.defineProperty(regexp, Symbol.matchAll, {
+  get() {
+    throw new Test262Error();
+  }
+});
+
+assert.throws(Test262Error, function() {
+  ''.matchAll(regexp);
+});
diff --git a/test/built-ins/String/prototype/matchAll/regexp-is-null.js b/test/built-ins/String/prototype/matchAll/regexp-is-null.js
new file mode 100644
index 0000000000..9ae102e6b1
--- /dev/null
+++ b/test/built-ins/String/prototype/matchAll/regexp-is-null.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: Behavior when regexp is null
+info: |
+  String.prototype.matchAll ( regexp )
+    1. Let O be ? RequireObjectCoercible(this value).
+    2. If regexp is neither undefined nor null, then
+      [...]
+    3. Return ? MatchAllIterator(regexp, O).
+
+  MatchAllIterator( regexp, O )
+    [...]
+    2. If ? IsRegExp(regexp) is true, then
+      [...]
+    3. Else,
+      a. Let R be RegExpCreate(regexp, "g").
+features: [String.prototype.matchAll]
+includes: [compareArray.js, compareIterator.js, regExpUtils.js]
+---*/
+
+var str = '-null-';
+
+assert.compareIterator(str.matchAll(null), [
+  matchValidator(['null'], 1, str)
+]);
diff --git a/test/built-ins/String/prototype/matchAll/regexp-is-undefined.js b/test/built-ins/String/prototype/matchAll/regexp-is-undefined.js
new file mode 100644
index 0000000000..bf9ac09e00
--- /dev/null
+++ b/test/built-ins/String/prototype/matchAll/regexp-is-undefined.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: Behavior when regexp is null
+info: |
+  String.prototype.matchAll ( regexp )
+    1. Let O be ? RequireObjectCoercible(this value).
+    2. If regexp is neither undefined nor null, then
+      [...]
+    3. Return ? MatchAllIterator(regexp, O).
+
+  MatchAllIterator( regexp, O )
+    [...]
+    2. If ? IsRegExp(regexp) is true, then
+      [...]
+    3. Else,
+      a. Let R be RegExpCreate(regexp, "g").
+features: [String.prototype.matchAll]
+includes: [compareArray.js, compareIterator.js, regExpUtils.js]
+---*/
+
+var str = 'a';
+
+assert.compareIterator(str.matchAll(undefined), [
+  matchValidator([''], 0, str),
+  matchValidator([''], 1, str)
+]);
diff --git a/test/built-ins/String/prototype/matchAll/cstm-matcher-invocation.js b/test/built-ins/String/prototype/matchAll/regexp-matchAll-invocation.js
similarity index 67%
rename from test/built-ins/String/prototype/matchAll/cstm-matcher-invocation.js
rename to test/built-ins/String/prototype/matchAll/regexp-matchAll-invocation.js
index 72c09fd541..7afe2c7965 100644
--- a/test/built-ins/String/prototype/matchAll/cstm-matcher-invocation.js
+++ b/test/built-ins/String/prototype/matchAll/regexp-matchAll-invocation.js
@@ -1,14 +1,16 @@
 // Copyright (C) 2018 Jordan Harband. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
-
 /*---
+esid: pending
 description: Invocation of @@matchAll property of user-supplied RegExp objects
 info: |
+  String.prototype.matchAll ( regexp )
     [...]
-    4. Let matcher be ? GetMethod(R, @@matchAll).
-    5. If matcher is not undefined, then
-      a. Return ? Call(matcher, R, « O »).
-features: [Symbol.match, Symbol.matchAll]
+    2. If regexp is neither undefined nor null, then
+      a. Let matcher be ? GetMethod(regexp, @@matchAll).
+      b. If matcher is not undefined, then
+        i. Return ? Call(matcher, regexp, « O »).
+features: [Symbol.matchAll, String.prototype.matchAll]
 ---*/
 
 var obj = {};
@@ -16,9 +18,8 @@ var returnVal = {};
 var callCount = 0;
 var thisVal, args;
 
-obj[Symbol.match] = true; // https://tc39.github.io/ecma262/#sec-isregexp steps 1-3
 obj[Symbol.matchAll] = function () {
-  callCount += 1;
+  callCount++;
   thisVal = this;
   args = arguments;
   return returnVal;
diff --git a/test/built-ins/String/prototype/matchAll/regexp-matchAll-throws.js b/test/built-ins/String/prototype/matchAll/regexp-matchAll-throws.js
new file mode 100644
index 0000000000..c94ddd095f
--- /dev/null
+++ b/test/built-ins/String/prototype/matchAll/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: Re-throws errors when calling @@matchAll
+info: |
+  String.prototype.matchAll ( regexp )
+    [...]
+    2. If regexp is neither undefined nor null, then
+      a. Let matcher be ? GetMethod(regexp, @@matchAll).
+features: [Symbol.matchAll, String.prototype.matchAll]
+---*/
+
+var regexp = /./;
+regexp[Symbol.matchAll] = function() {
+  throw new Test262Error();
+};
+
+assert.throws(Test262Error, function() {
+  ''.matchAll(regexp);
+});
diff --git a/test/built-ins/String/prototype/matchAll/regexp-prototype-get-matchAll-throws.js b/test/built-ins/String/prototype/matchAll/regexp-prototype-get-matchAll-throws.js
new file mode 100644
index 0000000000..ccafad46a5
--- /dev/null
+++ b/test/built-ins/String/prototype/matchAll/regexp-prototype-get-matchAll-throws.js
@@ -0,0 +1,22 @@
+// 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-throws errors thrown while accessing RegExp's @@matchAll property
+info: |
+  String.prototype.matchAll ( regexp )
+    [...]
+    2. If regexp is neither undefined nor null, then
+      a. Let matcher be ? GetMethod(regexp, @@matchAll).
+features: [Symbol.matchAll]
+---*/
+
+Object.defineProperty(RegExp.prototype, Symbol.matchAll, {
+  get() {
+    throw new Test262Error();
+  }
+});
+
+assert.throws(Test262Error, function() {
+  ''.matchAll(/./);
+});
diff --git a/test/built-ins/String/prototype/matchAll/regexp-prototype-has-no-matchAll.js b/test/built-ins/String/prototype/matchAll/regexp-prototype-has-no-matchAll.js
new file mode 100644
index 0000000000..0aeb021a9e
--- /dev/null
+++ b/test/built-ins/String/prototype/matchAll/regexp-prototype-has-no-matchAll.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: Behavior when @@matchAll is removed from RegExp's prototype
+info: |
+  String.prototype.matchAll ( regexp )
+    1. Let O be ? RequireObjectCoercible(this value).
+    2. If regexp is neither undefined nor null, then
+      a. Let matcher be ? GetMethod(regexp, @@matchAll).
+      b. If matcher is not undefined, then
+        [...]
+    3. Return ? MatchAllIterator(regexp, O).
+features: [Symbol.matchAll, String.prototype.matchAll]
+includes: [compareArray.js, compareIterator.js, regExpUtils.js]
+---*/
+
+delete RegExp.prototype[Symbol.matchAll];
+var str = 'a*b';
+
+assert.compareIterator(str.matchAll(/\w/g), [
+  matchValidator(['a'], 0, str),
+  matchValidator(['b'], 2, str)
+]);
diff --git a/test/built-ins/String/prototype/matchAll/regexp-prototype-matchAll-invocation.js b/test/built-ins/String/prototype/matchAll/regexp-prototype-matchAll-invocation.js
new file mode 100644
index 0000000000..2aec69141c
--- /dev/null
+++ b/test/built-ins/String/prototype/matchAll/regexp-prototype-matchAll-invocation.js
@@ -0,0 +1,36 @@
+// Copyright (C) 2018 Jordan Harband. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: Behavior when invoking of @@matchAll
+info: |
+  String.prototype.matchAll ( regexp )
+    [...]
+    2. If regexp is neither undefined nor null, then
+      a. Let matcher be ? GetMethod(regexp, @@matchAll).
+      b. If matcher is not undefined, then
+        i. Return ? Call(matcher, regexp, « O »).
+features: [Symbol.matchAll]
+---*/
+
+var obj = {};
+var returnVal = {};
+var callCount = 0;
+var thisVal, args;
+
+RegExp.prototype[Symbol.matchAll] = function() {
+  callCount++;
+  thisVal = this;
+  args = arguments;
+  return returnVal;
+};
+
+var regexp = /./;
+var str = '';
+
+assert.sameValue(str.matchAll(regexp), returnVal);
+assert.sameValue(callCount, 1, 'Invokes the method exactly once');
+assert.sameValue(thisVal, regexp);
+assert.notSameValue(args, undefined);
+assert.sameValue(args.length, 1);
+assert.sameValue(args[0], str);
diff --git a/test/built-ins/String/prototype/matchAll/regexp-prototype-matchAll-throws.js b/test/built-ins/String/prototype/matchAll/regexp-prototype-matchAll-throws.js
new file mode 100644
index 0000000000..c2be2331a3
--- /dev/null
+++ b/test/built-ins/String/prototype/matchAll/regexp-prototype-matchAll-throws.js
@@ -0,0 +1,22 @@
+// 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-throws errors when calling @@matchAll
+info: |
+  String.prototype.matchAll ( regexp )
+    [...]
+    2. If regexp is neither undefined nor null, then
+      a. Let matcher be ? GetMethod(regexp, @@matchAll).
+      b. If matcher is not undefined, then
+        i. Return ? Call(matcher, regexp, « O »).
+features: [Symbol.matchAll]
+---*/
+
+RegExp.prototype[Symbol.matchAll] = function() {
+  throw new Test262Error();
+};
+
+assert.throws(Test262Error, function() {
+  ''.matchAll(/./);
+});
diff --git a/test/built-ins/String/prototype/matchAll/this-val-non-obj-coercible.js b/test/built-ins/String/prototype/matchAll/this-val-non-obj-coercible.js
index 2189df4b65..9cfd7705de 100644
--- a/test/built-ins/String/prototype/matchAll/this-val-non-obj-coercible.js
+++ b/test/built-ins/String/prototype/matchAll/this-val-non-obj-coercible.js
@@ -1,12 +1,12 @@
 // Copyright (C) 2018 Jordan Harband. All rights reserved.
 // This code is governed by the BSD license found in the LICENSE file.
 /*---
+esid: pending
 description: The `this` value cannot be coerced into an object
 info: |
+  String.prototype.matchAll ( regexp )
     1. Let O be RequireObjectCoercible(this value).
-    2. Let S be ToString(O).
-    3. ReturnIfAbrupt(S).
-features: [Symbol.iterator]
+features: [String.prototype.matchAll]
 ---*/
 
 var matchAll = String.prototype.matchAll;
diff --git a/test/built-ins/Symbol/matchAll/cross-realm.js b/test/built-ins/Symbol/matchAll/cross-realm.js
new file mode 100644
index 0000000000..e6d2f9cebf
--- /dev/null
+++ b/test/built-ins/Symbol/matchAll/cross-realm.js
@@ -0,0 +1,14 @@
+// Copyright (C) 2018 Peter Wong. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: Value shared by all realms
+info: |
+  Unless otherwise specified, well-known symbols values are shared by all
+  realms.
+features: [cross-realm, Symbol.matchAll]
+---*/
+
+var OSymbol = $262.createRealm().global.Symbol;
+
+assert.sameValue(Symbol.matchAll, OSymbol.matchAll);
diff --git a/test/built-ins/Symbol/matchAll/prop-desc.js b/test/built-ins/Symbol/matchAll/prop-desc.js
new file mode 100644
index 0000000000..705adfc519
--- /dev/null
+++ b/test/built-ins/Symbol/matchAll/prop-desc.js
@@ -0,0 +1,17 @@
+// Copyright (C) 2018 Peter Wong. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: pending
+description: |
+    `Symbol.matchAll` property descriptor
+info: |
+    This property has the attributes { [[Writable]]: false, [[Enumerable]]:
+    false, [[Configurable]]: false }.
+includes: [propertyHelper.js]
+features: [Symbol.match]
+---*/
+
+assert.sameValue(typeof Symbol.matchAll, 'symbol');
+verifyNotEnumerable(Symbol, 'matchAll');
+verifyNotWritable(Symbol, 'matchAll');
+verifyNotConfigurable(Symbol, 'matchAll');
-- 
GitLab