summaryrefslogtreecommitdiff
path: root/test/built-ins/RegExp
diff options
context:
space:
mode:
authorRick Waldron <waldron.rick@gmail.com>2015-09-02 17:20:17 -0400
committerRick Waldron <waldron.rick@gmail.com>2015-09-02 17:20:17 -0400
commita2a92d0765c3898bde9b03234cc7824007630053 (patch)
tree252e80bb78d0dc7090636f105c0d1b26a14844b2 /test/built-ins/RegExp
parent574c87b1677c3f1b8bfee0d9cc4be3831ab31c4c (diff)
parentbb0cbeb6556c1bd78d1617c1de7284569c91e98a (diff)
downloadqtdeclarative-testsuites-a2a92d0765c3898bde9b03234cc7824007630053.tar.gz
Merge pull request #402 from bocoup/symbol-replace
Add tests for well-known Symbol: @@replace
Diffstat (limited to 'test/built-ins/RegExp')
-rw-r--r--test/built-ins/RegExp/prototype/Symbol.replace/arg-1-coerce-err.js24
-rw-r--r--test/built-ins/RegExp/prototype/Symbol.replace/arg-1-coerce.js25
-rw-r--r--test/built-ins/RegExp/prototype/Symbol.replace/arg-2-coerce-err.js26
-rw-r--r--test/built-ins/RegExp/prototype/Symbol.replace/arg-2-coerce.js27
-rw-r--r--test/built-ins/RegExp/prototype/Symbol.replace/coerce-global.js47
-rw-r--r--test/built-ins/RegExp/prototype/Symbol.replace/coerce-unicode.js48
-rw-r--r--test/built-ins/RegExp/prototype/Symbol.replace/exec-err.js33
-rw-r--r--test/built-ins/RegExp/prototype/Symbol.replace/exec-invocation.js44
-rw-r--r--test/built-ins/RegExp/prototype/Symbol.replace/fn-coerce-replacement-err.js34
-rw-r--r--test/built-ins/RegExp/prototype/Symbol.replace/fn-coerce-replacement.js29
-rw-r--r--test/built-ins/RegExp/prototype/Symbol.replace/fn-err.js29
-rw-r--r--test/built-ins/RegExp/prototype/Symbol.replace/fn-invoke-args.js33
-rw-r--r--test/built-ins/RegExp/prototype/Symbol.replace/fn-invoke-this-no-strict.js30
-rw-r--r--test/built-ins/RegExp/prototype/Symbol.replace/fn-invoke-this-strict.js29
-rw-r--r--test/built-ins/RegExp/prototype/Symbol.replace/g-init-lastindex-err.js29
-rw-r--r--test/built-ins/RegExp/prototype/Symbol.replace/g-init-lastindex.js22
-rw-r--r--test/built-ins/RegExp/prototype/Symbol.replace/g-pos-decrement.js41
-rw-r--r--test/built-ins/RegExp/prototype/Symbol.replace/g-pos-increment.js41
-rw-r--r--test/built-ins/RegExp/prototype/Symbol.replace/get-exec-err.js33
-rw-r--r--test/built-ins/RegExp/prototype/Symbol.replace/get-global-err.js23
-rw-r--r--test/built-ins/RegExp/prototype/Symbol.replace/length.js25
-rw-r--r--test/built-ins/RegExp/prototype/Symbol.replace/match-failure.js27
-rw-r--r--test/built-ins/RegExp/prototype/Symbol.replace/name.js23
-rw-r--r--test/built-ins/RegExp/prototype/Symbol.replace/prop-desc.js18
-rw-r--r--test/built-ins/RegExp/prototype/Symbol.replace/replace-with-trailing.js24
-rw-r--r--test/built-ins/RegExp/prototype/Symbol.replace/replace-without-trailing.js16
-rw-r--r--test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-capture-err.js39
-rw-r--r--test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-capture.js38
-rw-r--r--test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-index-err.js35
-rw-r--r--test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-index.js33
-rw-r--r--test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-length-err.js34
-rw-r--r--test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-length.js36
-rw-r--r--test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-matched-err.js34
-rw-r--r--test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-matched.js33
-rw-r--r--test/built-ins/RegExp/prototype/Symbol.replace/result-get-capture-err.js34
-rw-r--r--test/built-ins/RegExp/prototype/Symbol.replace/result-get-index-err.js32
-rw-r--r--test/built-ins/RegExp/prototype/Symbol.replace/result-get-length-err.js31
-rw-r--r--test/built-ins/RegExp/prototype/Symbol.replace/result-get-matched-err.js32
-rw-r--r--test/built-ins/RegExp/prototype/Symbol.replace/subst-after.js32
-rw-r--r--test/built-ins/RegExp/prototype/Symbol.replace/subst-before.js32
-rw-r--r--test/built-ins/RegExp/prototype/Symbol.replace/subst-capture-idx-1.js35
-rw-r--r--test/built-ins/RegExp/prototype/Symbol.replace/subst-capture-idx-2.js38
-rw-r--r--test/built-ins/RegExp/prototype/Symbol.replace/subst-dollar.js43
-rw-r--r--test/built-ins/RegExp/prototype/Symbol.replace/subst-matched.js26
-rw-r--r--test/built-ins/RegExp/prototype/Symbol.replace/this-val-non-obj.js39
45 files changed, 1436 insertions, 0 deletions
diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/arg-1-coerce-err.js b/test/built-ins/RegExp/prototype/Symbol.replace/arg-1-coerce-err.js
new file mode 100644
index 000000000..43eaded35
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.replace/arg-1-coerce-err.js
@@ -0,0 +1,24 @@
+// 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 thrown while type coercing first argument
+es6id: 21.2.5.8
+info: >
+ 21.2.5.8 RegExp.prototype [ @@replace ] ( string, replaceValue )
+
+ [...]
+ 3. Let S be ToString(string).
+ 4. ReturnIfAbrupt(S).
+features: [Symbol.replace]
+---*/
+
+var arg = {
+ toString: function() {
+ throw new Test262Error();
+ }
+};
+
+assert.throws(Test262Error, function() {
+ /./[Symbol.replace](arg);
+});
diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/arg-1-coerce.js b/test/built-ins/RegExp/prototype/Symbol.replace/arg-1-coerce.js
new file mode 100644
index 000000000..def76f2ba
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.replace/arg-1-coerce.js
@@ -0,0 +1,25 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Type coercion of first argument
+es6id: 21.2.5.8
+info: >
+ 21.2.5.8 RegExp.prototype [ @@replace ] ( string, replaceValue )
+
+ [...]
+ 3. Let S be ToString(string).
+ [...]
+features: [Symbol.replace]
+---*/
+
+var arg = {
+ valueOf: function() {
+ $ERROR('This method should not be invoked.');
+ },
+ toString: function() {
+ return 'toString value';
+ }
+};
+
+assert.sameValue(/./[Symbol.replace](arg, 'x'), 'xoString value');
diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/arg-2-coerce-err.js b/test/built-ins/RegExp/prototype/Symbol.replace/arg-2-coerce-err.js
new file mode 100644
index 000000000..29beacad6
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.replace/arg-2-coerce-err.js
@@ -0,0 +1,26 @@
+// 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 thrown while type coercing second argument
+es6id: 21.2.5.8
+info: >
+ 21.2.5.8 RegExp.prototype [ @@replace ] ( string, replaceValue )
+
+ [...]
+ 6. Let functionalReplace be IsCallable(replaceValue).
+ 7. If functionalReplace is false, then
+ a. Let replaceValue be ToString(replaceValue).
+ b. ReturnIfAbrupt(replaceValue).
+features: [Symbol.replace]
+---*/
+
+var arg = {
+ toString: function() {
+ throw new Test262Error();
+ }
+};
+
+assert.throws(Test262Error, function() {
+ /./[Symbol.replace]('', arg);
+});
diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/arg-2-coerce.js b/test/built-ins/RegExp/prototype/Symbol.replace/arg-2-coerce.js
new file mode 100644
index 000000000..74da6902d
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.replace/arg-2-coerce.js
@@ -0,0 +1,27 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Type coercion of second argument
+es6id: 21.2.5.8
+info: >
+ 21.2.5.8 RegExp.prototype [ @@replace ] ( string, replaceValue )
+
+ [...]
+ 6. Let functionalReplace be IsCallable(replaceValue).
+ 7. If functionalReplace is false, then
+ a. Let replaceValue be ToString(replaceValue).
+ [...]
+features: [Symbol.replace]
+---*/
+
+var arg = {
+ valueOf: function() {
+ $ERROR('This method should not be invoked.');
+ },
+ toString: function() {
+ return 'toString value';
+ }
+};
+
+assert.sameValue(/./[Symbol.replace]('string', arg), 'toString valuetring');
diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/coerce-global.js b/test/built-ins/RegExp/prototype/Symbol.replace/coerce-global.js
new file mode 100644
index 000000000..c9467aec9
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.replace/coerce-global.js
@@ -0,0 +1,47 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Boolean coercion of `global` property
+es6id: 21.2.5.8
+info: >
+ 21.2.5.6 RegExp.prototype [ @@replace ] ( string )
+
+ [...]
+ 8. Let global be ToBoolean(Get(rx, "global")).
+ [...]
+features: [Symbol.replace]
+---*/
+
+var r = /a/;
+Object.defineProperty(r, 'global', { writable: true });
+
+r.global = undefined;
+assert.sameValue(r[Symbol.replace]('aa', 'b'), 'ba');
+
+r.global = null;
+assert.sameValue(r[Symbol.replace]('aa', 'b'), 'ba');
+
+r.global = false;
+assert.sameValue(r[Symbol.replace]('aa', 'b'), 'ba');
+
+r.global = NaN;
+assert.sameValue(r[Symbol.replace]('aa', 'b'), 'ba');
+
+r.global = 0;
+assert.sameValue(r[Symbol.replace]('aa', 'b'), 'ba');
+
+r.global = '';
+assert.sameValue(r[Symbol.replace]('aa', 'b'), 'ba');
+
+r.global = true;
+assert.sameValue(r[Symbol.replace]('aa', 'b'), 'bb');
+
+r.global = 86;
+assert.sameValue(r[Symbol.replace]('aa', 'b'), 'bb');
+
+r.global = Symbol.replace;
+assert.sameValue(r[Symbol.replace]('aa', 'b'), 'bb');
+
+r.global = {};
+assert.sameValue(r[Symbol.replace]('aa', 'b'), 'bb');
diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/coerce-unicode.js b/test/built-ins/RegExp/prototype/Symbol.replace/coerce-unicode.js
new file mode 100644
index 000000000..edee4aa8b
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.replace/coerce-unicode.js
@@ -0,0 +1,48 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Boolean coercion of `unicode` property
+es6id: 21.2.5.8
+info: >
+ 21.2.5.6 RegExp.prototype [ @@replace ] ( string )
+
+ [...]
+ 10. If global is true, then
+ a. Let fullUnicode be ToBoolean(Get(rx, "unicode")).
+ [...]
+features: [Symbol.replace]
+---*/
+
+var r = /^|\udf06/g;
+Object.defineProperty(r, 'unicode', { writable: true });
+
+r.unicode = undefined;
+assert.sameValue(r[Symbol.replace]('\ud834\udf06', 'XXX'), 'XXX\ud834XXX');
+
+r.unicode = null;
+assert.sameValue(r[Symbol.replace]('\ud834\udf06', 'XXX'), 'XXX\ud834XXX');
+
+r.unicode = false;
+assert.sameValue(r[Symbol.replace]('\ud834\udf06', 'XXX'), 'XXX\ud834XXX');
+
+r.unicode = NaN;
+assert.sameValue(r[Symbol.replace]('\ud834\udf06', 'XXX'), 'XXX\ud834XXX');
+
+r.unicode = 0;
+assert.sameValue(r[Symbol.replace]('\ud834\udf06', 'XXX'), 'XXX\ud834XXX');
+
+r.unicode = '';
+assert.sameValue(r[Symbol.replace]('\ud834\udf06', 'XXX'), 'XXX\ud834XXX');
+
+r.unicode = true;
+assert.sameValue(r[Symbol.replace]('\ud834\udf06', 'XXX'), 'XXX\ud834\udf06');
+
+r.unicode = 86;
+assert.sameValue(r[Symbol.replace]('\ud834\udf06', 'XXX'), 'XXX\ud834\udf06');
+
+r.unicode = Symbol.replace;
+assert.sameValue(r[Symbol.replace]('\ud834\udf06', 'XXX'), 'XXX\ud834\udf06');
+
+r.unicode = {};
+assert.sameValue(r[Symbol.replace]('\ud834\udf06', 'XXX'), 'XXX\ud834\udf06');
diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/exec-err.js b/test/built-ins/RegExp/prototype/Symbol.replace/exec-err.js
new file mode 100644
index 000000000..bad4d02d2
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.replace/exec-err.js
@@ -0,0 +1,33 @@
+// 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 by `exec` method
+es6id: 21.2.5.8
+info: >
+ 21.2.5.8 RegExp.prototype [ @@replace ] ( string, replaceValue )
+
+ [...]
+ 13. Repeat, while done is false
+ a. Let result be RegExpExec(rx, S).
+ b. ReturnIfAbrupt(result).
+
+ 21.2.5.2.1 Runtime Semantics: RegExpExec ( R, S )
+
+ [...]
+ 3. Let exec be Get(R, "exec").
+ 4. ReturnIfAbrupt(exec).
+ 5. If IsCallable(exec) is true, then
+ a. Let result be Call(exec, R, «S»).
+ b. ReturnIfAbrupt(result).
+features: [Symbol.replace]
+---*/
+
+var r = /./;
+r.exec = function() {
+ throw new Test262Error();
+};
+
+assert.throws(Test262Error, function() {
+ r[Symbol.replace]('', '');
+});
diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/exec-invocation.js b/test/built-ins/RegExp/prototype/Symbol.replace/exec-invocation.js
new file mode 100644
index 000000000..0669de385
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.replace/exec-invocation.js
@@ -0,0 +1,44 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Invocation of `exec` method
+es6id: 21.2.5.8
+info: >
+ [...]
+ 13. Repeat, while done is false
+ a. Let result be RegExpExec(rx, S).
+ [...]
+
+ 21.2.5.2.1 Runtime Semantics: RegExpExec ( R, S )
+
+ [...]
+ 3. Let exec be Get(R, "exec").
+ 4. ReturnIfAbrupt(exec).
+ 5. If IsCallable(exec) is true, then
+ a. Let result be Call(exec, R, «S»).
+features: [Symbol.match]
+---*/
+
+var r = /./;
+var callCount = 0;
+var arg = {
+ toString: function() {
+ return 'string form';
+ }
+};
+var thisValue, args;
+
+r.exec = function() {
+ thisValue = this;
+ args = arguments;
+ callCount += 1;
+ return null;
+};
+
+r[Symbol.replace](arg, '');
+
+assert.sameValue(callCount, 1);
+assert.sameValue(thisValue, r);
+assert.sameValue(args.length, 1);
+assert.sameValue(args[0], 'string form');
diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/fn-coerce-replacement-err.js b/test/built-ins/RegExp/prototype/Symbol.replace/fn-coerce-replacement-err.js
new file mode 100644
index 000000000..d4f70ef93
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.replace/fn-coerce-replacement-err.js
@@ -0,0 +1,34 @@
+// 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 string coercion of the value returned
+ by functional replaceValue
+es6id: 21.2.5.8
+info: >
+ 16. Repeat, for each result in results,
+ [...]
+ m. If functionalReplace is true, then
+ i. Let replacerArgs be «matched».
+ ii. Append in list order the elements of captures to the end of the
+ List replacerArgs.
+ iii. Append position and S as the last two elements of replacerArgs.
+ iv. Let replValue be Call(replaceValue, undefined, replacerArgs).
+ v. Let replacement be ToString(replValue).
+ [...]
+ o. ReturnIfAbrupt(replacement).
+features: [Symbol.replace]
+---*/
+
+var replacer = function() {
+ return {
+ toString: function() {
+ throw new Test262Error();
+ }
+ };
+};
+
+assert.throws(Test262Error, function() {
+ /x/[Symbol.replace]('[x]', replacer);
+});
diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/fn-coerce-replacement.js b/test/built-ins/RegExp/prototype/Symbol.replace/fn-coerce-replacement.js
new file mode 100644
index 000000000..6c087c6c0
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.replace/fn-coerce-replacement.js
@@ -0,0 +1,29 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: String coercion of the value returned by functional replaceValue
+es6id: 21.2.5.8
+info: >
+ 16. Repeat, for each result in results,
+ [...]
+ m. If functionalReplace is true, then
+ i. Let replacerArgs be «matched».
+ ii. Append in list order the elements of captures to the end of the
+ List replacerArgs.
+ iii. Append position and S as the last two elements of replacerArgs.
+ iv. Let replValue be Call(replaceValue, undefined, replacerArgs).
+ v. Let replacement be ToString(replValue).
+ [...]
+features: [Symbol.replace]
+---*/
+
+var replacer = function() {
+ return {
+ toString: function() {
+ return 'toString value';
+ }
+ };
+};
+
+assert.sameValue(/x/[Symbol.replace]('[x]', replacer), '[toString value]');
diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/fn-err.js b/test/built-ins/RegExp/prototype/Symbol.replace/fn-err.js
new file mode 100644
index 000000000..1ca987b4b
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.replace/fn-err.js
@@ -0,0 +1,29 @@
+// 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 by functional replaceValue.
+es6id: 21.2.5.8
+info: >
+ 16. Repeat, for each result in results,
+ [...]
+ m. If functionalReplace is true, then
+ i. Let replacerArgs be «matched».
+ ii. Append in list order the elements of captures to the end of the
+ List replacerArgs.
+ iii. Append position and S as the last two elements of replacerArgs.
+ iv. Let replValue be Call(replaceValue, undefined, replacerArgs).
+ v. Let replacement be ToString(replValue).
+ [...]
+ o. ReturnIfAbrupt(replacement).
+features: [Symbol.replace]
+---*/
+
+var replacer = function() {
+ throw new Test262Error();
+};
+
+assert.throws(Test262Error, function() {
+ /./[Symbol.replace]('a', replacer);
+});
diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/fn-invoke-args.js b/test/built-ins/RegExp/prototype/Symbol.replace/fn-invoke-args.js
new file mode 100644
index 000000000..287b79548
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.replace/fn-invoke-args.js
@@ -0,0 +1,33 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Arguments of functional replaceValue
+es6id: 21.2.5.8
+info: >
+ 16. Repeat, for each result in results,
+ [...]
+ m. If functionalReplace is true, then
+ i. Let replacerArgs be «matched».
+ ii. Append in list order the elements of captures to the end of the
+ List replacerArgs.
+ iii. Append position and S as the last two elements of replacerArgs.
+ iv. Let replValue be Call(replaceValue, undefined, replacerArgs).
+ [...]
+features: [Symbol.replace]
+---*/
+
+var args;
+var replacer = function() {
+ args = arguments;
+};
+
+/b(.).(.)/[Symbol.replace]('abcdef', replacer);
+
+assert.notSameValue(args, undefined);
+assert.sameValue(args.length, 5);
+assert.sameValue(args[0], 'bcde');
+assert.sameValue(args[1], 'c');
+assert.sameValue(args[2], 'e');
+assert.sameValue(args[3], 1);
+assert.sameValue(args[4], 'abcdef');
diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/fn-invoke-this-no-strict.js b/test/built-ins/RegExp/prototype/Symbol.replace/fn-invoke-this-no-strict.js
new file mode 100644
index 000000000..654d7b7ef
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.replace/fn-invoke-this-no-strict.js
@@ -0,0 +1,30 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ `this` value of functional replaceValue (outside of strict mode)
+es6id: 21.2.5.8
+info: >
+ 16. Repeat, for each result in results,
+ [...]
+ m. If functionalReplace is true, then
+ i. Let replacerArgs be «matched».
+ ii. Append in list order the elements of captures to the end of the
+ List replacerArgs.
+ iii. Append position and S as the last two elements of replacerArgs.
+ iv. Let replValue be Call(replaceValue, undefined, replacerArgs).
+ [...]
+flags: [noStrict]
+includes: [fnGlobalObject.js]
+features: [Symbol.replace]
+---*/
+
+var thisVal;
+var replacer = function() {
+ thisVal = this;
+};
+
+/./[Symbol.replace]('x', replacer);
+
+assert.sameValue(thisVal, fnGlobalObject());
diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/fn-invoke-this-strict.js b/test/built-ins/RegExp/prototype/Symbol.replace/fn-invoke-this-strict.js
new file mode 100644
index 000000000..50acd5f86
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.replace/fn-invoke-this-strict.js
@@ -0,0 +1,29 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ `this` value of functional replaceValue (within strict mode)
+es6id: 21.2.5.8
+info: >
+ 16. Repeat, for each result in results,
+ [...]
+ m. If functionalReplace is true, then
+ i. Let replacerArgs be «matched».
+ ii. Append in list order the elements of captures to the end of the
+ List replacerArgs.
+ iii. Append position and S as the last two elements of replacerArgs.
+ iv. Let replValue be Call(replaceValue, undefined, replacerArgs).
+ [...]
+flags: [onlyStrict]
+features: [Symbol.replace]
+---*/
+
+var thisVal = null;
+var replacer = function() {
+ thisVal = this;
+};
+
+/./[Symbol.replace]('x', replacer);
+
+assert.sameValue(thisVal, undefined);
diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/g-init-lastindex-err.js b/test/built-ins/RegExp/prototype/Symbol.replace/g-init-lastindex-err.js
new file mode 100644
index 000000000..e941c3999
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.replace/g-init-lastindex-err.js
@@ -0,0 +1,29 @@
+// 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 while initializing `lastIndex` property for
+ "global" instances
+es6id: 21.2.5.8
+info: >
+ 21.2.5.8 RegExp.prototype [ @@replace ] ( string, replaceValue )
+
+ [...]
+ 10. If global is true, then
+ [...]
+ c. Let setStatus be Set(rx, "lastIndex", 0, true).
+ d. ReturnIfAbrupt(setStatus).
+features: [Symbol.replace]
+---*/
+
+var r = /./g;
+
+// Avoid false positives from unrelated TypeErrors
+r[Symbol.replace]('x', 'x');
+
+Object.defineProperty(r, 'lastIndex', { writable: false });
+
+assert.throws(TypeError, function() {
+ r[Symbol.replace]('x', 'x');
+});
diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/g-init-lastindex.js b/test/built-ins/RegExp/prototype/Symbol.replace/g-init-lastindex.js
new file mode 100644
index 000000000..1f0e4bfcf
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.replace/g-init-lastindex.js
@@ -0,0 +1,22 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Initialization of `lastIndex` property for "global" instances
+es6id: 21.2.5.8
+info: >
+ 21.2.5.8 RegExp.prototype [ @@replace ] ( string, replaceValue )
+
+ [...]
+ 10. If global is true, then
+ [...]
+ c. Let setStatus be Set(rx, "lastIndex", 0, true).
+ [...]
+features: [Symbol.replace]
+---*/
+
+var r = /./g;
+
+r.lastIndex = 1;
+
+assert.sameValue(r[Symbol.replace]('aa', 'x'), 'xx');
diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/g-pos-decrement.js b/test/built-ins/RegExp/prototype/Symbol.replace/g-pos-decrement.js
new file mode 100644
index 000000000..eafb47d8c
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.replace/g-pos-decrement.js
@@ -0,0 +1,41 @@
+// 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 position is decremented during result accumulation
+es6id: 21.2.5.8
+info: >
+ 16. Repeat, for each result in results,
+ [...]
+ p. If position ≥ nextSourcePosition, then
+ i. NOTE position should not normally move backwards. If it does, it
+ is an indication of an ill-behaving RegExp subclass or use of an
+ access triggered side-effect to change the global flag or other
+ characteristics of rx. In such cases, the corresponding
+ substitution is ignored.
+ ii. Let accumulatedResult be the String formed by concatenating the
+ code units of the current value of accumulatedResult with the
+ substring of S consisting of the code units from
+ nextSourcePosition (inclusive) up to position (exclusive) and
+ with the code units of replacement.
+ iii. Let nextSourcePosition be position + matchLength.
+features: [Symbol.replace]
+---*/
+
+var r = /./g;
+var callCount = 0;
+r.exec = function() {
+ callCount += 1;
+
+ if (callCount === 1) {
+ return { index: 3, length: 1, 0: 0 };
+ } else if (callCount === 2) {
+ return { index: 1, length: 1, 0: 0 };
+ }
+
+ return null;
+};
+
+assert.sameValue(r[Symbol.replace]('abcde', 'X'), 'abcXe');
+assert.sameValue(callCount, 3);
diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/g-pos-increment.js b/test/built-ins/RegExp/prototype/Symbol.replace/g-pos-increment.js
new file mode 100644
index 000000000..5370241ec
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.replace/g-pos-increment.js
@@ -0,0 +1,41 @@
+// 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 position is incremented during result accumulation
+es6id: 21.2.5.8
+info: >
+ 16. Repeat, for each result in results,
+ [...]
+ p. If position ≥ nextSourcePosition, then
+ i. NOTE position should not normally move backwards. If it does, it
+ is an indication of an ill-behaving RegExp subclass or use of an
+ access triggered side-effect to change the global flag or other
+ characteristics of rx. In such cases, the corresponding
+ substitution is ignored.
+ ii. Let accumulatedResult be the String formed by concatenating the
+ code units of the current value of accumulatedResult with the
+ substring of S consisting of the code units from
+ nextSourcePosition (inclusive) up to position (exclusive) and
+ with the code units of replacement.
+ iii. Let nextSourcePosition be position + matchLength.
+features: [Symbol.replace]
+---*/
+
+var r = /./g;
+var callCount = 0;
+r.exec = function() {
+ callCount += 1;
+
+ if (callCount === 1) {
+ return { index: 1, length: 1, 0: 0 };
+ } else if (callCount === 2) {
+ return { index: 3, length: 1, 0: 0 };
+ }
+
+ return null;
+};
+
+assert.sameValue(r[Symbol.replace]('abcde', 'X'), 'aXcXe');
+assert.sameValue(callCount, 3);
diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/get-exec-err.js b/test/built-ins/RegExp/prototype/Symbol.replace/get-exec-err.js
new file mode 100644
index 000000000..45f30bd2d
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.replace/get-exec-err.js
@@ -0,0 +1,33 @@
+// 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 there is an error thrown while accessing the `exec` method of
+ "global" instances
+es6id: 21.2.5.8
+info: >
+ [...]
+ 13. Repeat, while done is false
+ a. Let result be RegExpExec(rx, S).
+
+ ES6 21.2.5.2.1 Runtime Semantics: RegExpExec ( R, S )
+
+ [...]
+ 3. Let exec be Get(R, "exec").
+ 4. ReturnIfAbrupt(exec).
+features: [Symbol.match]
+---*/
+
+var r = { global: true };
+Object.defineProperty(r, 'exec', {
+ get: function() {
+ throw new Test262Error();
+ }
+});
+
+assert.throws(Test262Error, function() {
+ RegExp.prototype[Symbol.replace].call(r, '', '');
+});
+
+assert.sameValue(r.lastIndex, 0, 'Error thrown after setting `lastIndex`');
diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/get-global-err.js b/test/built-ins/RegExp/prototype/Symbol.replace/get-global-err.js
new file mode 100644
index 000000000..efb1efc6a
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.replace/get-global-err.js
@@ -0,0 +1,23 @@
+// 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 `global` property
+es6id: 21.2.5.8
+info: >
+ [...]
+ 8. Let global be ToBoolean(Get(rx, "global")).
+ 9. ReturnIfAbrupt(global).
+features: [Symbol.replace]
+---*/
+
+var obj = {
+ get global() {
+ throw new Test262Error();
+ }
+};
+
+assert.throws(Test262Error, function() {
+ RegExp.prototype[Symbol.replace].call(obj);
+});
diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/length.js b/test/built-ins/RegExp/prototype/Symbol.replace/length.js
new file mode 100644
index 000000000..1686a1bd2
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.replace/length.js
@@ -0,0 +1,25 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 21.2.5.8
+description: RegExp.prototype[Symbol.replace] `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.
+
+ [...]
+
+ Unless otherwise specified, the length property of a built-in Function
+ object has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+ [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+assert.sameValue(RegExp.prototype[Symbol.replace].length, 2);
+
+verifyNotEnumerable(RegExp.prototype[Symbol.replace], 'length');
+verifyNotWritable(RegExp.prototype[Symbol.replace], 'length');
+verifyConfigurable(RegExp.prototype[Symbol.replace], 'length');
diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/match-failure.js b/test/built-ins/RegExp/prototype/Symbol.replace/match-failure.js
new file mode 100644
index 000000000..fae47dc0e
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.replace/match-failure.js
@@ -0,0 +1,27 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Return original string when no matches occur
+es6id: 21.2.5.8
+info: >
+ 21.2.5.8 RegExp.prototype [ @@replace ] ( string, replaceValue )
+
+ [...]
+ 12. Let done be false.
+ 13. Repeat, while done is false
+ a. Let result be RegExpExec(rx, S).
+ b. ReturnIfAbrupt(result).
+ c. If result is null, set done to true.
+ [...]
+ 14. Let accumulatedResult be the empty String value.
+ 15. Let nextSourcePosition be 0.
+ [...]
+ 18. Return the String formed by concatenating the code units of
+ accumulatedResult with the substring of S consisting of the code units
+ from nextSourcePosition (inclusive) up through the final code unit of S
+ (inclusive).
+features: [Symbol.replace]
+---*/
+
+assert.sameValue(/x/[Symbol.replace]('abc', 'X'), 'abc');
diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/name.js b/test/built-ins/RegExp/prototype/Symbol.replace/name.js
new file mode 100644
index 000000000..67eba90a1
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.replace/name.js
@@ -0,0 +1,23 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+es6id: 21.2.5.8
+description: RegExp.prototype[Symbol.replace] `name` property
+info: >
+ The value of the name property of this function is "[Symbol.replace]".
+
+ ES6 Section 17:
+
+ [...]
+
+ 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]
+---*/
+
+assert.sameValue(RegExp.prototype[Symbol.replace].name, '[Symbol.replace]');
+
+verifyNotEnumerable(RegExp.prototype[Symbol.replace], 'name');
+verifyNotWritable(RegExp.prototype[Symbol.replace], 'name');
+verifyConfigurable(RegExp.prototype[Symbol.replace], 'name');
diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/prop-desc.js b/test/built-ins/RegExp/prototype/Symbol.replace/prop-desc.js
new file mode 100644
index 000000000..eb4f5f082
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.replace/prop-desc.js
@@ -0,0 +1,18 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+es6id: 21.2.5.8
+description: RegExp.prototype[Symbol.replace] property descriptor
+info: >
+ ES6 Section 17
+
+ Every other data property described in clauses 18 through 26 and in Annex
+ B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false,
+ [[Configurable]]: true } unless otherwise specified.
+includes: [propertyHelper.js]
+---*/
+
+verifyNotEnumerable(RegExp.prototype, Symbol.replace);
+verifyWritable(RegExp.prototype, Symbol.replace);
+verifyConfigurable(RegExp.prototype, Symbol.replace);
diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/replace-with-trailing.js b/test/built-ins/RegExp/prototype/Symbol.replace/replace-with-trailing.js
new file mode 100644
index 000000000..12b44b8c4
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.replace/replace-with-trailing.js
@@ -0,0 +1,24 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Return value when replacement pattern does not match final code point
+es6id: 21.2.5.8
+info: >
+ [...]
+ 18. Return the String formed by concatenating the code units of
+ accumulatedResult with the substring of S consisting of the code units
+ from nextSourcePosition (inclusive) up through the final code unit of S
+ (inclusive).
+features: [Symbol.replace]
+---*/
+
+assert.sameValue(/abc/[Symbol.replace]('abcd', 'X'), 'Xd');
+assert.sameValue(/bc/[Symbol.replace]('abcd', 'X'), 'aXd');
+assert.sameValue(/c/[Symbol.replace]('abcd', 'X'), 'abXd');
+
+assert.sameValue(/ab/[Symbol.replace]('abcd', 'X'), 'Xcd');
+assert.sameValue(/b/[Symbol.replace]('abcd', 'X'), 'aXcd');
+
+assert.sameValue(/a/[Symbol.replace]('abcd', 'X'), 'Xbcd');
diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/replace-without-trailing.js b/test/built-ins/RegExp/prototype/Symbol.replace/replace-without-trailing.js
new file mode 100644
index 000000000..0789ef097
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.replace/replace-without-trailing.js
@@ -0,0 +1,16 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Return value when replacement pattern matches final code point
+es6id: 21.2.5.8
+info: >
+ [...]
+ 17. If nextSourcePosition ≥ lengthS, return accumulatedResult.
+features: [Symbol.replace]
+---*/
+
+assert.sameValue(/abcd/[Symbol.replace]('abcd', 'X'), 'X');
+assert.sameValue(/bcd/[Symbol.replace]('abcd', 'X'), 'aX');
+assert.sameValue(/cd/[Symbol.replace]('abcd', 'X'), 'abX');
+assert.sameValue(/d/[Symbol.replace]('abcd', 'X'), 'abcX');
diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-capture-err.js b/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-capture-err.js
new file mode 100644
index 000000000..849797f30
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-capture-err.js
@@ -0,0 +1,39 @@
+// 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 while type coercing `1` property of result
+es6id: 21.2.5.8
+info: >
+ [...]
+ 13. Repeat, while done is false
+ a. Let result be RegExpExec(rx, S).
+ [...]
+ 16. Repeat, for each result in results,
+ [...]
+ l. Repeat while n ≤ nCaptures
+ i. Let capN be Get(result, ToString(n)).
+ ii. ReturnIfAbrupt(capN).
+ iii. If capN is not undefined, then
+ 1. Let capN be ToString(capN).
+ 2. ReturnIfAbrupt(capN).
+features: [Symbol.replace]
+---*/
+
+var r = /./;
+var uncoercibleValue = {
+ length: 2,
+ 1: {
+ toString: function() {
+ throw new Test262Error();
+ }
+ }
+};
+r.exec = function() {
+ return uncoercibleValue;
+};
+
+assert.throws(Test262Error, function() {
+ r[Symbol.replace]('a', 'b');
+});
diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-capture.js b/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-capture.js
new file mode 100644
index 000000000..044e9916c
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-capture.js
@@ -0,0 +1,38 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Type coercion of `1` property of result
+es6id: 21.2.5.8
+info: >
+ [...]
+ 13. Repeat, while done is false
+ a. Let result be RegExpExec(rx, S).
+ [...]
+ 16. Repeat, for each result in results,
+ [...]
+ l. Repeat while n ≤ nCaptures
+ i. Let capN be Get(result, ToString(n)).
+ ii. ReturnIfAbrupt(capN).
+ iii. If capN is not undefined, then
+ 1. Let capN be ToString(capN).
+ [...]
+features: [Symbol.replace]
+---*/
+
+var r = /./;
+var coercibleValue = {
+ length: 4,
+ 3: {
+ toString: function() {
+ return 'toString value';
+ }
+ }
+};
+r.exec = function() {
+ return coercibleValue;
+};
+
+assert.sameValue(
+ r[Symbol.replace]('', 'foo[$3]bar'), 'foo[toString value]bar'
+);
diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-index-err.js b/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-index-err.js
new file mode 100644
index 000000000..1b230905d
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-index-err.js
@@ -0,0 +1,35 @@
+// 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 while type coercing `index` property of
+ result
+es6id: 21.2.5.8
+info: >
+ [...]
+ 13. Repeat, while done is false
+ a. Let result be RegExpExec(rx, S).
+ [...]
+ 16. Repeat, for each result in results,
+ [...]
+ g. Let position be ToInteger(Get(result, "index")).
+ h. ReturnIfAbrupt(position).
+features: [Symbol.replace]
+---*/
+
+var r = /./;
+var uncoercibleIndex = {
+ index: {
+ valueOf: function() {
+ throw new Test262Error();
+ }
+ }
+};
+r.exec = function() {
+ return uncoercibleIndex;
+};
+
+assert.throws(Test262Error, function() {
+ r[Symbol.replace]('a', 'b');
+});
diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-index.js b/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-index.js
new file mode 100644
index 000000000..21bf3ee90
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-index.js
@@ -0,0 +1,33 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Type coercion of `index` property of result
+es6id: 21.2.5.8
+info: >
+ [...]
+ 13. Repeat, while done is false
+ a. Let result be RegExpExec(rx, S).
+ [...]
+ 16. Repeat, for each result in results,
+ [...]
+ g. Let position be ToInteger(Get(result, "index")).
+ [...]
+features: [Symbol.replace]
+---*/
+
+var r = /./;
+var counter = 0;
+var coercibleIndex = {
+ index: {
+ valueOf: function() {
+ return 2.9;
+ }
+ }
+};
+r.exec = function() {
+ return coercibleIndex;
+};
+
+assert.sameValue(r[Symbol.replace]('abcd', ''), 'ab');
diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-length-err.js b/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-length-err.js
new file mode 100644
index 000000000..55d4a6948
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-length-err.js
@@ -0,0 +1,34 @@
+// 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 while type coercing `length` property of
+ result
+es6id: 21.2.5.8
+info: >
+ [...]
+ 13. Repeat, while done is false
+ a. Let result be RegExpExec(rx, S).
+ [...]
+ 16. Repeat, for each result in results,
+ a. Let nCaptures be ToLength(Get(result, "length")).
+ b. ReturnIfAbrupt(nCaptures).
+features: [Symbol.match]
+---*/
+
+var r = /./;
+var uncoercibleLength = {
+ length: {
+ valueOf: function() {
+ throw new Test262Error();
+ }
+ }
+};
+r.exec = function() {
+ return uncoercibleLength;
+};
+
+assert.throws(Test262Error, function() {
+ r[Symbol.replace]('a', 'b');
+});
diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-length.js b/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-length.js
new file mode 100644
index 000000000..de4a28a37
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-length.js
@@ -0,0 +1,36 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Type coercion of `length` property of result
+es6id: 21.2.5.8
+info: >
+ [...]
+ 13. Repeat, while done is false
+ a. Let result be RegExpExec(rx, S).
+ [...]
+ 16. Repeat, for each result in results,
+ a. Let nCaptures be ToLength(Get(result, "length")).
+ [...]
+features: [Symbol.replace]
+---*/
+
+var r = /./;
+var counter = 0;
+var coercibleIndex = {
+ length: {
+ valueOf: function() {
+ return 3.9;
+ }
+ },
+ 0: '',
+ 1: 'foo',
+ 2: 'bar',
+ 3: 'baz'
+};
+r.exec = function() {
+ return coercibleIndex;
+};
+
+assert.sameValue(r[Symbol.replace]('', '$1$2$3'), 'foobar$3');
diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-matched-err.js b/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-matched-err.js
new file mode 100644
index 000000000..044935b4d
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-matched-err.js
@@ -0,0 +1,34 @@
+// 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 while type coercing `0` property of result
+es6id: 21.2.5.8
+info: >
+ [...]
+ 13. Repeat, while done is false
+ a. Let result be RegExpExec(rx, S).
+ [...]
+ 16. Repeat, for each result in results,
+ [...]
+ d. Let matched be ToString(Get(result, "0")).
+ e. ReturnIfAbrupt(matched).
+features: [Symbol.replace]
+---*/
+
+var r = /./;
+var uncoercibleValue = {
+ 0: {
+ toString: function() {
+ throw new Test262Error();
+ }
+ }
+};
+r.exec = function() {
+ return uncoercibleValue;
+};
+
+assert.throws(Test262Error, function() {
+ r[Symbol.replace]('a', 'b');
+});
diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-matched.js b/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-matched.js
new file mode 100644
index 000000000..ba72d7aa9
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-matched.js
@@ -0,0 +1,33 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: Type coercion of `0` property of result
+es6id: 21.2.5.8
+info: >
+ [...]
+ 13. Repeat, while done is false
+ a. Let result be RegExpExec(rx, S).
+ [...]
+ 16. Repeat, for each result in results,
+ [...]
+ d. Let matched be ToString(Get(result, "0")).
+ [...]
+features: [Symbol.replace]
+---*/
+
+var r = /./;
+var coercibleValue = {
+ 0: {
+ toString: function() {
+ return 'toString value';
+ }
+ }
+};
+r.exec = function() {
+ return coercibleValue;
+};
+
+assert.sameValue(
+ r[Symbol.replace]('', 'foo[$&]bar'), 'foo[toString value]bar'
+);
diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/result-get-capture-err.js b/test/built-ins/RegExp/prototype/Symbol.replace/result-get-capture-err.js
new file mode 100644
index 000000000..1f7f141cb
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.replace/result-get-capture-err.js
@@ -0,0 +1,34 @@
+// 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 while accessing `1` property of result
+es6id: 21.2.5.8
+info: >
+ [...]
+ 13. Repeat, while done is false
+ a. Let result be RegExpExec(rx, S).
+ [...]
+ 16. Repeat, for each result in results,
+ [...]
+ l. Repeat while n ≤ nCaptures
+ i. Let capN be Get(result, ToString(n)).
+ ii. ReturnIfAbrupt(capN).
+features: [Symbol.replace]
+---*/
+
+var r = /./;
+var poisonedValue = {
+ length: 2,
+ get 1() {
+ throw new Test262Error();
+ }
+};
+r.exec = function() {
+ return poisonedValue;
+};
+
+assert.throws(Test262Error, function() {
+ r[Symbol.replace]('a', 'b');
+});
diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/result-get-index-err.js b/test/built-ins/RegExp/prototype/Symbol.replace/result-get-index-err.js
new file mode 100644
index 000000000..7d4e384a2
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.replace/result-get-index-err.js
@@ -0,0 +1,32 @@
+// 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 while accessing `index` property of result
+es6id: 21.2.5.8
+info: >
+ [...]
+ 13. Repeat, while done is false
+ a. Let result be RegExpExec(rx, S).
+ [...]
+ 16. Repeat, for each result in results,
+ [...]
+ g. Let position be ToInteger(Get(result, "index")).
+ h. ReturnIfAbrupt(position).
+features: [Symbol.replace]
+---*/
+
+var r = /./;
+var poisonedIndex = {
+ get index() {
+ throw new Test262Error();
+ }
+};
+r.exec = function() {
+ return poisonedIndex;
+};
+
+assert.throws(Test262Error, function() {
+ r[Symbol.replace]('a', 'b');
+});
diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/result-get-length-err.js b/test/built-ins/RegExp/prototype/Symbol.replace/result-get-length-err.js
new file mode 100644
index 000000000..40f9d11d0
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.replace/result-get-length-err.js
@@ -0,0 +1,31 @@
+// 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 while accessing `length` property of result
+es6id: 21.2.5.8
+info: >
+ [...]
+ 13. Repeat, while done is false
+ a. Let result be RegExpExec(rx, S).
+ [...]
+ 16. Repeat, for each result in results,
+ a. Let nCaptures be ToLength(Get(result, "length")).
+ b. ReturnIfAbrupt(nCaptures).
+features: [Symbol.match]
+---*/
+
+var r = /./;
+var poisonedLength = {
+ get length() {
+ throw new Test262Error();
+ }
+};
+r.exec = function() {
+ return poisonedLength;
+};
+
+assert.throws(Test262Error, function() {
+ r[Symbol.replace]('a', 'b');
+});
diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/result-get-matched-err.js b/test/built-ins/RegExp/prototype/Symbol.replace/result-get-matched-err.js
new file mode 100644
index 000000000..a8cd33399
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.replace/result-get-matched-err.js
@@ -0,0 +1,32 @@
+// 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 while accessing `0` property of result
+es6id: 21.2.5.8
+info: >
+ [...]
+ 13. Repeat, while done is false
+ a. Let result be RegExpExec(rx, S).
+ [...]
+ 16. Repeat, for each result in results,
+ [...]
+ d. Let matched be ToString(Get(result, "0")).
+ e. ReturnIfAbrupt(matched).
+features: [Symbol.replace]
+---*/
+
+var r = /./;
+var poisonedValue = {
+ get 0() {
+ throw new Test262Error();
+ }
+};
+r.exec = function() {
+ return poisonedValue;
+};
+
+assert.throws(Test262Error, function() {
+ r[Symbol.replace]('a', 'b');
+});
diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/subst-after.js b/test/built-ins/RegExp/prototype/Symbol.replace/subst-after.js
new file mode 100644
index 000000000..828f57585
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.replace/subst-after.js
@@ -0,0 +1,32 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Substitution pattern: text after match
+es6id: 21.2.5.8
+info: >
+ 16. Repeat, for each result in results,
+ [...]
+ m. If functionalReplace is true, then
+ [...]
+ n. Else,
+ i. Let replacement be GetSubstitution(matched, S, position,
+ captures, replaceValue).
+ [...]
+
+ 21.1.3.14.1 Runtime Semantics: GetSubstitution
+
+ Code units: 0x0024, 0x0027
+
+ Unicode Characters: $'
+
+ Replacement text:
+ If tailPos ≥ stringLength, the replacement is the empty String. Otherwise
+ the replacement is the substring of str that starts at index tailPos and
+ continues to the end of str.
+features: [Symbol.replace]
+---*/
+
+assert.sameValue(/c/[Symbol.replace]('abc', '[$\']'), 'ab[]');
+assert.sameValue(/b/[Symbol.replace]('abc', '[$\']'), 'a[c]c');
diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/subst-before.js b/test/built-ins/RegExp/prototype/Symbol.replace/subst-before.js
new file mode 100644
index 000000000..8061ec93f
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.replace/subst-before.js
@@ -0,0 +1,32 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Substitution pattern: text before match
+es6id: 21.2.5.8
+info: >
+ 16. Repeat, for each result in results,
+ [...]
+ m. If functionalReplace is true, then
+ [...]
+ n. Else,
+ i. Let replacement be GetSubstitution(matched, S, position,
+ captures, replaceValue).
+ [...]
+
+ 21.1.3.14.1 Runtime Semantics: GetSubstitution
+
+ Code units: 0x0024, 0x0060
+
+ Unicode Characters: $`
+
+ Replacement text:
+ If position is 0, the replacement is the empty String. Otherwise the
+ replacement is the substring of str that starts at index 0 and whose last
+ code unit is at index `position-1`.
+features: [Symbol.replace]
+---*/
+
+assert.sameValue(/a/[Symbol.replace]('abc', '[$`]'), '[]bc');
+assert.sameValue(/b/[Symbol.replace]('abc', '[$`]'), 'a[a]c');
diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/subst-capture-idx-1.js b/test/built-ins/RegExp/prototype/Symbol.replace/subst-capture-idx-1.js
new file mode 100644
index 000000000..6073c7ec8
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.replace/subst-capture-idx-1.js
@@ -0,0 +1,35 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Substitution pattern: one-digit capturing group reference
+es6id: 21.2.5.8
+info: >
+ 16. Repeat, for each result in results,
+ [...]
+ m. If functionalReplace is true, then
+ [...]
+ n. Else,
+ i. Let replacement be GetSubstitution(matched, S, position,
+ captures, replaceValue).
+ [...]
+
+ 21.1.3.14.1 Runtime Semantics: GetSubstitution
+
+ Code units:
+ 0x0024, N
+ Where 0x0031 ≤ N ≤ 0x0039
+
+ Unicode Characters:
+ $n where
+ n is one of 1 2 3 4 5 6 7 8 9 and $n is not followed by a decimal digit
+
+ Replacement text:
+ The nth element of captures, where n is a single digit in the range 1 to 9.
+ If n≤m and the nth element of captures is undefined, use the empty String
+ instead. If n>m, the result is implementation-defined.
+features: [Symbol.replace]
+---*/
+
+assert.sameValue(/b(c)(z)?(.)/[Symbol.replace]('abcde', '[$1$2$3]'), 'a[cd]e');
diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/subst-capture-idx-2.js b/test/built-ins/RegExp/prototype/Symbol.replace/subst-capture-idx-2.js
new file mode 100644
index 000000000..d57eb3aae
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.replace/subst-capture-idx-2.js
@@ -0,0 +1,38 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Substitution pattern: two-digit capturing group reference
+es6id: 21.2.5.8
+info: >
+ 16. Repeat, for each result in results,
+ [...]
+ m. If functionalReplace is true, then
+ [...]
+ n. Else,
+ i. Let replacement be GetSubstitution(matched, S, position,
+ captures, replaceValue).
+ [...]
+
+ 21.1.3.14.1 Runtime Semantics: GetSubstitution
+
+ Code units:
+ 0x0024, N, N
+ Where 0x0030 ≤ N ≤ 0x0039
+
+ Unicode Characters:
+ $nn where
+ n is one of 0 1 2 3 4 5 6 7 8 9
+
+ Replacement text:
+ The nnth element of captures, where nn is a two-digit decimal number in the
+ range 01 to 99. If nn≤m and the nnth element of captures is undefined, use
+ the empty String instead. If nn is 00 or nn>m, the result is
+ implementation-defined.
+features: [Symbol.replace]
+---*/
+
+assert.sameValue(
+ /b(c)(z)?(.)/[Symbol.replace]('abcde', '[$01$02$03]'), 'a[cd]e'
+);
diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/subst-dollar.js b/test/built-ins/RegExp/prototype/Symbol.replace/subst-dollar.js
new file mode 100644
index 000000000..e47762846
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.replace/subst-dollar.js
@@ -0,0 +1,43 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Substitution pattern: dollar sign
+es6id: 21.2.5.8
+info: >
+ 16. Repeat, for each result in results,
+ [...]
+ m. If functionalReplace is true, then
+ [...]
+ n. Else,
+ i. Let replacement be GetSubstitution(matched, S, position,
+ captures, replaceValue).
+ [...]
+
+ 21.1.3.14.1 Runtime Semantics: GetSubstitution
+
+ Code units: 0x0024, 0x0024
+ Unicode Characters: $$
+ Replacement text: $
+
+ [...]
+
+ Code units: 0x0024
+ Unicode Characters: $ in any context that does not match any of the above.
+ Replacement text: $
+features: [Symbol.replace]
+---*/
+
+assert.sameValue(/./[Symbol.replace]('abc', '$$'), '$bc', '"escaped" version');
+assert.sameValue(
+ /./[Symbol.replace]('abc', '$'), '$bc', '"unescaped" version'
+);
+assert.sameValue(
+ /./[Symbol.replace]('abc', '\\$'), '\\$bc', 'backslash-prefixed'
+);
+assert.sameValue(
+ /./[Symbol.replace]('abc', '$$$'),
+ '$$bc',
+ '"escaped" followed by "unuescaped"'
+);
diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/subst-matched.js b/test/built-ins/RegExp/prototype/Symbol.replace/subst-matched.js
new file mode 100644
index 000000000..f253c0d4a
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.replace/subst-matched.js
@@ -0,0 +1,26 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+ Substitution pattern: matched string
+es6id: 21.2.5.8
+info: >
+ 16. Repeat, for each result in results,
+ [...]
+ m. If functionalReplace is true, then
+ [...]
+ n. Else,
+ i. Let replacement be GetSubstitution(matched, S, position,
+ captures, replaceValue).
+ [...]
+
+ 21.1.3.14.1 Runtime Semantics: GetSubstitution
+
+ Code units: 0x0024, 0x0026
+ Unicode Characters: $&
+ Replacement text: matched
+features: [Symbol.replace]
+---*/
+
+assert.sameValue(/.4?./[Symbol.replace]('abc', '[$&]'), '[ab]c');
diff --git a/test/built-ins/RegExp/prototype/Symbol.replace/this-val-non-obj.js b/test/built-ins/RegExp/prototype/Symbol.replace/this-val-non-obj.js
new file mode 100644
index 000000000..25fa93807
--- /dev/null
+++ b/test/built-ins/RegExp/prototype/Symbol.replace/this-val-non-obj.js
@@ -0,0 +1,39 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: The `this` value must be an object
+es6id: 21.2.5.8
+info: >
+ 1. Let rx be the this value.
+ 2. If Type(rx) is not Object, throw a TypeError exception.
+features: [Symbol.replace]
+---*/
+
+assert.throws(TypeError, function() {
+ RegExp.prototype[Symbol.replace].call();
+});
+
+assert.throws(TypeError, function() {
+ RegExp.prototype[Symbol.replace].call(undefined);
+});
+
+assert.throws(TypeError, function() {
+ RegExp.prototype[Symbol.replace].call(null);
+});
+
+assert.throws(TypeError, function() {
+ RegExp.prototype[Symbol.replace].call(true);
+});
+
+assert.throws(TypeError, function() {
+ RegExp.prototype[Symbol.replace].call('string');
+});
+
+assert.throws(TypeError, function() {
+ RegExp.prototype[Symbol.replace].call(Symbol.replace);
+});
+
+assert.throws(TypeError, function() {
+ RegExp.prototype[Symbol.replace].call(86);
+});