summaryrefslogtreecommitdiffstats
path: root/js/src/tests/ecma_6/RegExp
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /js/src/tests/ecma_6/RegExp
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip
Add m-esr52 at 52.6.0
Diffstat (limited to 'js/src/tests/ecma_6/RegExp')
-rw-r--r--js/src/tests/ecma_6/RegExp/RegExpExec-exec.js18
-rw-r--r--js/src/tests/ecma_6/RegExp/RegExpExec-return.js31
-rw-r--r--js/src/tests/ecma_6/RegExp/browser.js0
-rw-r--r--js/src/tests/ecma_6/RegExp/class-null.js15
-rw-r--r--js/src/tests/ecma_6/RegExp/compile-lastIndex.js88
-rw-r--r--js/src/tests/ecma_6/RegExp/constructor-IsRegExp.js86
-rw-r--r--js/src/tests/ecma_6/RegExp/constructor-constructor.js78
-rw-r--r--js/src/tests/ecma_6/RegExp/constructor-ordering-2.js21
-rw-r--r--js/src/tests/ecma_6/RegExp/constructor-ordering.js16
-rw-r--r--js/src/tests/ecma_6/RegExp/constructor-regexp-unicode.js9
-rw-r--r--js/src/tests/ecma_6/RegExp/constructor-regexp.js61
-rw-r--r--js/src/tests/ecma_6/RegExp/descriptor.js25
-rw-r--r--js/src/tests/ecma_6/RegExp/escape.js70
-rw-r--r--js/src/tests/ecma_6/RegExp/exec-lastIndex-negative.js27
-rw-r--r--js/src/tests/ecma_6/RegExp/flag-accessors.js49
-rw-r--r--js/src/tests/ecma_6/RegExp/flags-param-handling.js18
-rw-r--r--js/src/tests/ecma_6/RegExp/flags.js26
-rw-r--r--js/src/tests/ecma_6/RegExp/getter-name.js16
-rw-r--r--js/src/tests/ecma_6/RegExp/ignoreCase-multiple.js71
-rw-r--r--js/src/tests/ecma_6/RegExp/lastIndex-nonwritable.js27
-rw-r--r--js/src/tests/ecma_6/RegExp/match-this.js12
-rw-r--r--js/src/tests/ecma_6/RegExp/match-trace.js147
-rw-r--r--js/src/tests/ecma_6/RegExp/match.js36
-rw-r--r--js/src/tests/ecma_6/RegExp/replace-compile.js21
-rw-r--r--js/src/tests/ecma_6/RegExp/replace-global-unicode.js18
-rw-r--r--js/src/tests/ecma_6/RegExp/replace-sticky-lastIndex.js23
-rw-r--r--js/src/tests/ecma_6/RegExp/replace-sticky.js21
-rw-r--r--js/src/tests/ecma_6/RegExp/replace-this.js12
-rw-r--r--js/src/tests/ecma_6/RegExp/replace-trace.js309
-rw-r--r--js/src/tests/ecma_6/RegExp/replace-twoBytes.js44
-rw-r--r--js/src/tests/ecma_6/RegExp/replace.js34
-rw-r--r--js/src/tests/ecma_6/RegExp/search-this.js12
-rw-r--r--js/src/tests/ecma_6/RegExp/search-trace.js76
-rw-r--r--js/src/tests/ecma_6/RegExp/search.js26
-rw-r--r--js/src/tests/ecma_6/RegExp/shell.js0
-rw-r--r--js/src/tests/ecma_6/RegExp/source.js29
-rw-r--r--js/src/tests/ecma_6/RegExp/split-deleted-flags.js11
-rw-r--r--js/src/tests/ecma_6/RegExp/split-flags-on-obj.js21
-rw-r--r--js/src/tests/ecma_6/RegExp/split-invalid-lastIndex.js31
-rw-r--r--js/src/tests/ecma_6/RegExp/split-limit.js14
-rw-r--r--js/src/tests/ecma_6/RegExp/split-obj.js12
-rw-r--r--js/src/tests/ecma_6/RegExp/split-prop-access.js19
-rw-r--r--js/src/tests/ecma_6/RegExp/split-this.js12
-rw-r--r--js/src/tests/ecma_6/RegExp/split-trace.js229
-rw-r--r--js/src/tests/ecma_6/RegExp/split.js30
-rw-r--r--js/src/tests/ecma_6/RegExp/sticky.js126
-rw-r--r--js/src/tests/ecma_6/RegExp/test-trailing.js31
-rw-r--r--js/src/tests/ecma_6/RegExp/toString.js42
-rw-r--r--js/src/tests/ecma_6/RegExp/unicode-back-reference.js39
-rw-r--r--js/src/tests/ecma_6/RegExp/unicode-braced.js166
-rw-r--r--js/src/tests/ecma_6/RegExp/unicode-character-class-escape.js75
-rw-r--r--js/src/tests/ecma_6/RegExp/unicode-class-braced.js236
-rw-r--r--js/src/tests/ecma_6/RegExp/unicode-class-empty.js25
-rw-r--r--js/src/tests/ecma_6/RegExp/unicode-class-ignoreCase.js28
-rw-r--r--js/src/tests/ecma_6/RegExp/unicode-class-lead-trail.js142
-rw-r--r--js/src/tests/ecma_6/RegExp/unicode-class-negated.js64
-rw-r--r--js/src/tests/ecma_6/RegExp/unicode-class-range.js28
-rw-r--r--js/src/tests/ecma_6/RegExp/unicode-class-raw.js65
-rw-r--r--js/src/tests/ecma_6/RegExp/unicode-disallow-extended.js117
-rw-r--r--js/src/tests/ecma_6/RegExp/unicode-everything.js59
-rw-r--r--js/src/tests/ecma_6/RegExp/unicode-ignoreCase-ascii.js45
-rw-r--r--js/src/tests/ecma_6/RegExp/unicode-ignoreCase-escape.js71
-rw-r--r--js/src/tests/ecma_6/RegExp/unicode-ignoreCase-negated.js19
-rw-r--r--js/src/tests/ecma_6/RegExp/unicode-ignoreCase.js2643
-rw-r--r--js/src/tests/ecma_6/RegExp/unicode-index.js17
-rw-r--r--js/src/tests/ecma_6/RegExp/unicode-lead-trail.js218
-rw-r--r--js/src/tests/ecma_6/RegExp/unicode-raw.js139
67 files changed, 6346 insertions, 0 deletions
diff --git a/js/src/tests/ecma_6/RegExp/RegExpExec-exec.js b/js/src/tests/ecma_6/RegExp/RegExpExec-exec.js
new file mode 100644
index 000000000..e92792fcf
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/RegExpExec-exec.js
@@ -0,0 +1,18 @@
+var BUGNUMBER = 887016;
+var summary = "RegExpExec should throw if exec property of non-RegExp is not callable";
+
+print(BUGNUMBER + ": " + summary);
+
+for (var exec of [null, 0, false, undefined, ""]) {
+ // RegExp with non-callable exec
+ var re = /a/;
+ re.exec = exec;
+ RegExp.prototype[Symbol.match].call(re, "foo");
+
+ // non-RegExp with non-callable exec
+ assertThrowsInstanceOf(() => RegExp.prototype[Symbol.match].call({ exec }, "foo"),
+ TypeError);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/RegExpExec-return.js b/js/src/tests/ecma_6/RegExp/RegExpExec-return.js
new file mode 100644
index 000000000..1148aac07
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/RegExpExec-return.js
@@ -0,0 +1,31 @@
+var BUGNUMBER = 887016;
+var summary = "RegExpExec should throw if returned value is not an object nor null.";
+
+print(BUGNUMBER + ": " + summary);
+
+for (var ret of [null, {}, [], /a/]) {
+ assertEq(RegExp.prototype[Symbol.match].call({
+ get global() {
+ return false;
+ },
+ exec(S) {
+ return ret;
+ }
+ }, "foo"), ret);
+}
+
+for (ret of [undefined, 1, true, false, Symbol.iterator]) {
+ assertThrowsInstanceOf(() => {
+ RegExp.prototype[Symbol.match].call({
+ get global() {
+ return false;
+ },
+ exec(S) {
+ return ret;
+ }
+ }, "foo");
+ }, TypeError);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/browser.js b/js/src/tests/ecma_6/RegExp/browser.js
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/browser.js
diff --git a/js/src/tests/ecma_6/RegExp/class-null.js b/js/src/tests/ecma_6/RegExp/class-null.js
new file mode 100644
index 000000000..c95e5a4d7
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/class-null.js
@@ -0,0 +1,15 @@
+var BUGNUMBER = 1279467;
+var summary = "Null in character class in RegExp with unicode flag.";
+
+print(BUGNUMBER + ": " + summary);
+
+var m = /([\0]+)/u.exec("\u0000");
+assertEq(m.length, 2);
+assertEq(m[0], '\u0000');
+assertEq(m[1], '\u0000');
+
+var m = /([\0]+)/u.exec("0");
+assertEq(m, null);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/compile-lastIndex.js b/js/src/tests/ecma_6/RegExp/compile-lastIndex.js
new file mode 100644
index 000000000..80c820f43
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/compile-lastIndex.js
@@ -0,0 +1,88 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var BUGNUMBER = 1253099;
+var summary =
+ "RegExp.prototype.compile must perform all its steps *except* setting " +
+ ".lastIndex, then throw, when provided a RegExp whose .lastIndex has been " +
+ "made non-writable";
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+var regex = /foo/i;
+
+// Aside from making .lastIndex non-writable, this has two incidental effects
+// ubiquitously tested through the remainder of this test:
+//
+// * RegExp.prototype.compile will do everything it ordinarily does, BUT it
+// will throw a TypeError when attempting to zero .lastIndex immediately
+// before succeeding overall.
+// * RegExp.prototype.test for a non-global and non-sticky regular expression,
+// in case of a match, will return true (as normal). BUT if no match is
+// found, it will throw a TypeError when attempting to modify .lastIndex.
+//
+// Ain't it great?
+Object.defineProperty(regex, "lastIndex", { value: 42, writable: false });
+
+assertEq(regex.global, false);
+assertEq(regex.ignoreCase, true);
+assertEq(regex.multiline, false);
+assertEq(regex.unicode, false);
+assertEq(regex.sticky, false);
+assertEq(Object.getOwnPropertyDescriptor(regex, "lastIndex").writable, false);
+assertEq(regex.lastIndex, 42);
+
+assertEq(regex.test("foo"), true);
+assertEq(regex.test("FOO"), true);
+assertThrowsInstanceOf(() => regex.test("bar"), TypeError);
+assertThrowsInstanceOf(() => regex.test("BAR"), TypeError);
+
+assertThrowsInstanceOf(() => regex.compile("bar"), TypeError);
+
+assertEq(regex.global, false);
+assertEq(regex.ignoreCase, false);
+assertEq(regex.multiline, false);
+assertEq(regex.unicode, false);
+assertEq(regex.sticky, false);
+assertEq(Object.getOwnPropertyDescriptor(regex, "lastIndex").writable, false);
+assertEq(regex.lastIndex, 42);
+assertThrowsInstanceOf(() => regex.test("foo"), TypeError);
+assertThrowsInstanceOf(() => regex.test("FOO"), TypeError);
+assertEq(regex.test("bar"), true);
+assertThrowsInstanceOf(() => regex.test("BAR"), TypeError);
+
+assertThrowsInstanceOf(() => regex.compile("^baz", "m"), TypeError);
+
+assertEq(regex.global, false);
+assertEq(regex.ignoreCase, false);
+assertEq(regex.multiline, true);
+assertEq(regex.unicode, false);
+assertEq(regex.sticky, false);
+assertEq(Object.getOwnPropertyDescriptor(regex, "lastIndex").writable, false);
+assertEq(regex.lastIndex, 42);
+assertThrowsInstanceOf(() => regex.test("foo"), TypeError);
+assertThrowsInstanceOf(() => regex.test("FOO"), TypeError);
+assertThrowsInstanceOf(() => regex.test("bar"), TypeError);
+assertThrowsInstanceOf(() => regex.test("BAR"), TypeError);
+assertEq(regex.test("baz"), true);
+assertThrowsInstanceOf(() => regex.test("BAZ"), TypeError);
+assertThrowsInstanceOf(() => regex.test("012345678901234567890123456789012345678901baz"),
+ TypeError);
+assertEq(regex.test("012345678901234567890123456789012345678901\nbaz"), true);
+assertThrowsInstanceOf(() => regex.test("012345678901234567890123456789012345678901BAZ"),
+ TypeError);
+assertThrowsInstanceOf(() => regex.test("012345678901234567890123456789012345678901\nBAZ"),
+ TypeError);
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("Tests complete");
diff --git a/js/src/tests/ecma_6/RegExp/constructor-IsRegExp.js b/js/src/tests/ecma_6/RegExp/constructor-IsRegExp.js
new file mode 100644
index 000000000..8c735e4b9
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/constructor-IsRegExp.js
@@ -0,0 +1,86 @@
+var BUGNUMBER = 1147817;
+var summary = "RegExp constructor with pattern with @@match.";
+
+print(BUGNUMBER + ": " + summary);
+
+var matchValue;
+var constructorValue;
+
+var matchGet;
+var constructorGet;
+var sourceGet;
+var flagsGet;
+function reset() {
+ matchGet = false;
+ constructorGet = false;
+ sourceGet = false;
+ flagsGet = false;
+}
+var obj = {
+ get [Symbol.match]() {
+ matchGet = true;
+ return matchValue;
+ },
+ get constructor() {
+ constructorGet = true;
+ return constructorValue;
+ },
+ get source() {
+ sourceGet = true;
+ return "foo";
+ },
+ get flags() {
+ flagsGet = true;
+ return "i";
+ },
+ toString() {
+ return "bar";
+ }
+};
+
+matchValue = true;
+constructorValue = function() {};
+
+reset();
+assertEq(RegExp(obj).toString(), "/foo/i");
+assertEq(matchGet, true);
+assertEq(constructorGet, true);
+assertEq(sourceGet, true);
+assertEq(flagsGet, true);
+
+reset();
+assertEq(RegExp(obj, "g").toString(), "/foo/g");
+assertEq(matchGet, true);
+assertEq(constructorGet, false);
+assertEq(sourceGet, true);
+assertEq(flagsGet, false);
+
+matchValue = false;
+constructorValue = function() {};
+
+reset();
+assertEq(RegExp(obj).toString(), "/bar/");
+assertEq(matchGet, true);
+assertEq(constructorGet, false);
+assertEq(sourceGet, false);
+assertEq(flagsGet, false);
+
+reset();
+assertEq(RegExp(obj, "g").toString(), "/bar/g");
+assertEq(matchGet, true);
+assertEq(constructorGet, false);
+assertEq(sourceGet, false);
+assertEq(flagsGet, false);
+
+matchValue = true;
+constructorValue = RegExp;
+
+reset();
+assertEq(RegExp(obj), obj);
+assertEq(matchGet, true);
+assertEq(constructorGet, true);
+assertEq(sourceGet, false);
+assertEq(flagsGet, false);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/constructor-constructor.js b/js/src/tests/ecma_6/RegExp/constructor-constructor.js
new file mode 100644
index 000000000..528f4978c
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/constructor-constructor.js
@@ -0,0 +1,78 @@
+var BUGNUMBER = 1147817;
+var summary = "RegExp constructor should check pattern.constructor.";
+
+print(BUGNUMBER + ": " + summary);
+
+var g = newGlobal();
+
+var re = /foo/;
+assertEq(RegExp(re), re);
+re.constructor = 10;
+assertEq(RegExp(re) === re, false);
+assertEq(RegExp(re).toString(), re.toString());
+
+// If pattern comes from different global, RegExp shouldn't return it.
+re = g.eval(`var re = /foo/; re;`);
+assertEq(RegExp(re) === re, false);
+assertEq(RegExp(re).toString(), re.toString());
+g.eval(`re.constructor = 10;`);
+assertEq(RegExp(re) === re, false);
+assertEq(RegExp(re).toString(), re.toString());
+
+
+re = new Proxy(/a/, {
+ get(that, name) {
+ return that[name];
+ }
+});
+assertEq(RegExp(re), re);
+re = new Proxy(/a/, {
+ get(that, name) {
+ if (name == "constructor") {
+ return function() {};
+ }
+ return that[name];
+ }
+});
+assertEq(RegExp(re) === re, false);
+re = new Proxy(/a/, {
+ get(that, name) {
+ if (name == Symbol.match) {
+ return undefined;
+ }
+ return that[name];
+ }
+});
+assertEq(RegExp(re) === re, false);
+
+re = new Proxy(g.eval(`/a/`), {
+ get(that, name) {
+ return that[name];
+ }
+});
+assertEq(RegExp(re) === re, false);
+
+re = g.eval(`new Proxy(/a/, {
+ get(that, name) {
+ return that[name];
+ }
+});`);
+assertEq(RegExp(re) === re, false);
+
+
+var obj = { [Symbol.match]: true, source: "foo", flags: "gi" };
+assertEq(RegExp(obj) === obj, false);
+assertEq(RegExp(obj).toString(), "/foo/gi");
+obj.constructor = RegExp;
+assertEq(RegExp(obj), obj);
+
+obj = g.eval(`var obj = { [Symbol.match]: true, source: "foo", flags: "gi" }; obj;`);
+assertEq(RegExp(obj) === obj, false);
+assertEq(RegExp(obj).toString(), "/foo/gi");
+g.eval(`obj.constructor = RegExp`);
+assertEq(RegExp(obj) === obj, false);
+obj.constructor = RegExp;
+assertEq(RegExp(obj), obj);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/constructor-ordering-2.js b/js/src/tests/ecma_6/RegExp/constructor-ordering-2.js
new file mode 100644
index 000000000..21a6bbeca
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/constructor-ordering-2.js
@@ -0,0 +1,21 @@
+// Make sure that we don't ToString the second argument until /after/ doing
+// the appropriate subclassing lookups
+
+var didLookup = false;
+
+var re = /a/;
+var flags = { toString() { assertEq(didLookup, true); return "g"; } };
+var newRe = Reflect.construct(RegExp, [re, flags],
+ Object.defineProperty(function(){}.bind(null), "prototype", {
+ get() {
+ didLookup = true;
+ return RegExp.prototype;
+ }
+}));
+
+assertEq(Object.getPrototypeOf(newRe), RegExp.prototype);
+assertEq(didLookup, true);
+
+
+if (typeof reportCompare === 'function')
+ reportCompare(0,0,"OK");
diff --git a/js/src/tests/ecma_6/RegExp/constructor-ordering.js b/js/src/tests/ecma_6/RegExp/constructor-ordering.js
new file mode 100644
index 000000000..3e3a9b695
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/constructor-ordering.js
@@ -0,0 +1,16 @@
+// Make sure that we don't misorder subclassing accesses with respect to
+// accessing regex arg internal slots
+//
+// Test credit André Bargull.
+
+var re = /a/;
+var newRe = Reflect.construct(RegExp, [re], Object.defineProperty(function(){}.bind(null), "prototype", {
+ get() {
+ re.compile("b");
+ return RegExp.prototype;
+ }
+}));
+assertEq(newRe.source, "a");
+
+if (typeof reportCompare === 'function')
+ reportCompare(0,0,"OK");
diff --git a/js/src/tests/ecma_6/RegExp/constructor-regexp-unicode.js b/js/src/tests/ecma_6/RegExp/constructor-regexp-unicode.js
new file mode 100644
index 000000000..b348c34a0
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/constructor-regexp-unicode.js
@@ -0,0 +1,9 @@
+var BUGNUMBER = 1274393;
+var summary = "RegExp constructor should check the pattern syntax again when adding unicode flag.";
+
+print(BUGNUMBER + ": " + summary);
+
+assertThrowsInstanceOf(() => RegExp(/\-/, "u"), SyntaxError);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/constructor-regexp.js b/js/src/tests/ecma_6/RegExp/constructor-regexp.js
new file mode 100644
index 000000000..419b02713
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/constructor-regexp.js
@@ -0,0 +1,61 @@
+var BUGNUMBER = 1130860;
+var summary = "RegExp constructor shouldn't invoke source/flags getters on argument RegExp instance.";
+
+print(BUGNUMBER + ": " + summary);
+
+// same-compartment
+var a = /foo/;
+var flagsCalled = false;
+var sourceCalled = false;
+Object.defineProperty(a, "source", { get: () => {
+ sourceCalled = true;
+ return "bar";
+}});
+Object.defineProperty(a, "flags", { get: () => {
+ flagsCalled = true;
+ return "i";
+}});
+
+assertEq(a.source, "bar");
+assertEq(a.flags, "i");
+assertEq(sourceCalled, true);
+assertEq(flagsCalled, true);
+
+sourceCalled = false;
+flagsCalled = false;
+assertEq(new RegExp(a).source, "foo");
+assertEq(sourceCalled, false);
+assertEq(flagsCalled, false);
+
+// cross-compartment
+var g = newGlobal();
+var b = g.eval(`
+var b = /foo2/;
+var flagsCalled = false;
+var sourceCalled = false;
+Object.defineProperty(b, "source", { get: () => {
+ sourceCalled = true;
+ return "bar2";
+}});
+Object.defineProperty(b, "flags", { get: () => {
+ flagsCalled = true;
+ return "i";
+}});
+b;
+`);
+
+assertEq(b.source, "bar2");
+assertEq(b.flags, "i");
+assertEq(g.eval("sourceCalled;"), true);
+assertEq(g.eval("flagsCalled;"), true);
+
+g.eval(`
+sourceCalled = false;
+flagsCalled = false;
+`);
+assertEq(new RegExp(b).source, "foo2");
+assertEq(g.eval("sourceCalled;"), false);
+assertEq(g.eval("flagsCalled;"), false);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/descriptor.js b/js/src/tests/ecma_6/RegExp/descriptor.js
new file mode 100644
index 000000000..cc545b3a6
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/descriptor.js
@@ -0,0 +1,25 @@
+var BUGNUMBER = 1120169;
+var summary = "Implement RegExp.prototype.{global, ignoreCase, multiline, sticky, unicode} - property descriptor";
+
+print(BUGNUMBER + ": " + summary);
+
+var getters = [
+ "flags",
+ "global",
+ "ignoreCase",
+ "multiline",
+ "source",
+ "sticky",
+ "unicode",
+];
+
+for (var name of getters) {
+ var desc = Object.getOwnPropertyDescriptor(RegExp.prototype, name);
+ assertEq(desc.configurable, true);
+ assertEq(desc.enumerable, false);
+ assertEq("writable" in desc, false);
+ assertEq("get" in desc, true);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/escape.js b/js/src/tests/ecma_6/RegExp/escape.js
new file mode 100644
index 000000000..bb59b797d
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/escape.js
@@ -0,0 +1,70 @@
+var BUGNUMBER = 1130860;
+var summary = 'Slash and LineTerminator should be escaped correctly.';
+
+print(BUGNUMBER + ": " + summary);
+
+function test(re, source) {
+ assertEq(re.source, source);
+ assertEq(eval("/" + re.source + "/").source, source);
+ assertEq(re.toString(), "/" + source + "/");
+}
+
+test(/\\n/, "\\\\n");
+test(/\\\n/, "\\\\\\n");
+test(/\\\\n/, "\\\\\\\\n");
+test(RegExp("\\n"), "\\n");
+test(RegExp("\\\n"), "\\n");
+test(RegExp("\\\\n"), "\\\\n");
+
+test(/\\r/, "\\\\r");
+test(/\\\r/, "\\\\\\r");
+test(/\\\\r/, "\\\\\\\\r");
+test(RegExp("\\r"), "\\r");
+test(RegExp("\\\r"), "\\r");
+test(RegExp("\\\\r"), "\\\\r");
+
+test(/\\u2028/, "\\\\u2028");
+test(/\\\u2028/, "\\\\\\u2028");
+test(/\\\\u2028/, "\\\\\\\\u2028");
+test(RegExp("\\u2028"), "\\u2028");
+test(RegExp("\\\u2028"), "\\u2028");
+test(RegExp("\\\\u2028"), "\\\\u2028");
+
+test(/\\u2029/, "\\\\u2029");
+test(/\\\u2029/, "\\\\\\u2029");
+test(/\\\\u2029/, "\\\\\\\\u2029");
+test(RegExp("\\u2029"), "\\u2029");
+test(RegExp("\\\u2029"), "\\u2029");
+test(RegExp("\\\\u2029"), "\\\\u2029");
+
+test(/\//, "\\/");
+test(/\\\//, "\\\\\\/");
+test(RegExp("/"), "\\/");
+test(RegExp("\/"), "\\/");
+test(RegExp("\\/"), "\\/");
+test(RegExp("\\\/"), "\\/");
+test(RegExp("\\\\/"), "\\\\\\/");
+
+test(/[/]/, "[/]");
+test(/[\/]/, "[\\/]");
+test(/[\\/]/, "[\\\\/]");
+test(/[\\\/]/, "[\\\\\\/]");
+test(RegExp("[/]"), "[/]");
+test(RegExp("[\/]"), "[/]");
+test(RegExp("[\\/]"), "[\\/]");
+test(RegExp("[\\\/]"), "[\\/]");
+test(RegExp("[\\\\/]"), "[\\\\/]");
+
+test(RegExp("\[/\]"), "[/]");
+test(RegExp("\[\\/\]"), "[\\/]");
+
+test(/\[\/\]/, "\\[\\/\\]");
+test(/\[\\\/\]/, "\\[\\\\\\/\\]");
+test(RegExp("\\[/\\]"), "\\[\\/\\]");
+test(RegExp("\\[\/\\]"), "\\[\\/\\]");
+test(RegExp("\\[\\/\\]"), "\\[\\/\\]");
+test(RegExp("\\[\\\/\\]"), "\\[\\/\\]");
+test(RegExp("\\[\\\\/\\]"), "\\[\\\\\\/\\]");
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/exec-lastIndex-negative.js b/js/src/tests/ecma_6/RegExp/exec-lastIndex-negative.js
new file mode 100644
index 000000000..18eb2ab9d
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/exec-lastIndex-negative.js
@@ -0,0 +1,27 @@
+var BUGNUMBER = 1207922;
+var summary = "negative lastIndex should be treated as 0.";
+
+print(BUGNUMBER + ": " + summary);
+
+var pattern = /abc/gi;
+var string = 'AbcaBcabC';
+
+var indices = [
+ -1,
+ -Math.pow(2,32),
+ -(Math.pow(2,32) + 1),
+ -Math.pow(2,32) * 2,
+ -Math.pow(2,40),
+ -Number.MAX_VALUE,
+];
+for (var index of indices) {
+ pattern.lastIndex = index;
+ var result = pattern.exec(string);
+ assertEq(result.index, 0);
+ assertEq(result.length, 1);
+ assertEq(result[0], "Abc");
+ assertEq(pattern.lastIndex, 3);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/flag-accessors.js b/js/src/tests/ecma_6/RegExp/flag-accessors.js
new file mode 100644
index 000000000..848b916c5
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/flag-accessors.js
@@ -0,0 +1,49 @@
+var BUGNUMBER = 1120169;
+var summary = "Implement RegExp.prototype.{global, ignoreCase, multiline, sticky, unicode}";
+
+print(BUGNUMBER + ": " + summary);
+
+var props = [
+ "global",
+ "ignoreCase",
+ "multiline",
+ "sticky",
+ "unicode",
+];
+
+testThrows(RegExp.prototype);
+test(/foo/iymg, [true, true, true, true, false]);
+test(RegExp(""), [false, false, false, false, false]);
+test(RegExp("", "mygi"), [true, true, true, true, false]);
+test(RegExp("", "mygiu"), [true, true, true, true, true]);
+
+testThrowsGeneric();
+testThrowsGeneric(1);
+testThrowsGeneric("");
+testThrowsGeneric({});
+testThrowsGeneric(new Proxy({}, {get(){ return true; }}));
+
+function test(obj, expects) {
+ for (var i = 0; i < props.length; i++) {
+ assertEq(obj[props[i]], expects[i]);
+ }
+}
+
+function testThrows(obj) {
+ for (var prop of props) {
+ assertThrowsInstanceOf(obj[prop], TypeError);
+ }
+}
+
+function testThrowsGeneric(obj) {
+ for (var prop of props) {
+ assertThrowsInstanceOf(() => genericGet(obj, prop), TypeError);
+ }
+}
+
+function genericGet(obj, prop) {
+ return Object.getOwnPropertyDescriptor(RegExp.prototype, prop).get.call(obj);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/flags-param-handling.js b/js/src/tests/ecma_6/RegExp/flags-param-handling.js
new file mode 100644
index 000000000..e47799601
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/flags-param-handling.js
@@ -0,0 +1,18 @@
+assertEq(RegExp(/foo/my).flags, "my");
+assertEq(RegExp(/foo/, "gi").flags, "gi");
+assertEq(RegExp(/foo/my, "gi").flags, "gi");
+assertEq(RegExp(/foo/my, "").flags, "");
+assertEq(RegExp(/foo/my, undefined).flags, "my");
+assertThrowsInstanceOf(() => RegExp(/foo/my, null), SyntaxError);
+assertThrowsInstanceOf(() => RegExp(/foo/my, "foo"), SyntaxError);
+
+assertEq(/a/.compile("b", "gi").flags, "gi");
+assertEq(/a/.compile(/b/my).flags, "my");
+assertEq(/a/.compile(/b/my, undefined).flags, "my");
+assertThrowsInstanceOf(() => /a/.compile(/b/my, "gi"), TypeError);
+assertThrowsInstanceOf(() => /a/.compile(/b/my, ""), TypeError);
+assertThrowsInstanceOf(() => /a/.compile(/b/my, null), TypeError);
+assertThrowsInstanceOf(() => /a/.compile(/b/my, "foo"), TypeError);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/flags.js b/js/src/tests/ecma_6/RegExp/flags.js
new file mode 100644
index 000000000..292fa4f3f
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/flags.js
@@ -0,0 +1,26 @@
+var BUGNUMBER = 1108467;
+var summary = "Implement RegExp.prototype.flags";
+
+print(BUGNUMBER + ": " + summary);
+
+assertEq(RegExp.prototype.flags, "");
+assertEq(/foo/iymg.flags, "gimy");
+assertEq(RegExp("").flags, "");
+assertEq(RegExp("", "mygi").flags, "gimy");
+assertEq(RegExp("", "mygui").flags, "gimuy");
+assertEq(genericFlags({}), "");
+assertEq(genericFlags({ignoreCase: true}), "i");
+assertEq(genericFlags({sticky:1, unicode:1, global: 0}), "uy");
+assertEq(genericFlags({__proto__: {multiline: true}}), "m");
+assertEq(genericFlags(new Proxy({}, {get(){return true}})), "gimuy");
+
+assertThrowsInstanceOf(() => genericFlags(), TypeError);
+assertThrowsInstanceOf(() => genericFlags(1), TypeError);
+assertThrowsInstanceOf(() => genericFlags(""), TypeError);
+
+function genericFlags(obj) {
+ return Object.getOwnPropertyDescriptor(RegExp.prototype,"flags").get.call(obj);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/getter-name.js b/js/src/tests/ecma_6/RegExp/getter-name.js
new file mode 100644
index 000000000..d0a413dbc
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/getter-name.js
@@ -0,0 +1,16 @@
+var BUGNUMBER = 1180290;
+var summary = 'RegExp getters should have get prefix';
+
+print(BUGNUMBER + ": " + summary);
+
+assertEq(Object.getOwnPropertyDescriptor(RegExp, Symbol.species).get.name, "get [Symbol.species]");
+assertEq(Object.getOwnPropertyDescriptor(RegExp.prototype, "flags").get.name, "get flags");
+assertEq(Object.getOwnPropertyDescriptor(RegExp.prototype, "global").get.name, "get global");
+assertEq(Object.getOwnPropertyDescriptor(RegExp.prototype, "ignoreCase").get.name, "get ignoreCase");
+assertEq(Object.getOwnPropertyDescriptor(RegExp.prototype, "multiline").get.name, "get multiline");
+assertEq(Object.getOwnPropertyDescriptor(RegExp.prototype, "source").get.name, "get source");
+assertEq(Object.getOwnPropertyDescriptor(RegExp.prototype, "sticky").get.name, "get sticky");
+assertEq(Object.getOwnPropertyDescriptor(RegExp.prototype, "unicode").get.name, "get unicode");
+
+if (typeof reportCompare === 'function')
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/ignoreCase-multiple.js b/js/src/tests/ecma_6/RegExp/ignoreCase-multiple.js
new file mode 100644
index 000000000..e52cf499b
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/ignoreCase-multiple.js
@@ -0,0 +1,71 @@
+var BUGNUMBER = 1280046;
+var summary = "ignoreCase match should perform Canonicalize both on input and pattern.";
+
+print(BUGNUMBER + ": " + summary);
+
+// Each element [code1, upper, code2] satisfies the following condition:
+// ToUpperCase(code1) == upper
+// ToUpperCase(code2) == upper
+var pairs =
+ [
+ // U+00B5: MICRO SIGN
+ // U+039C: GREEK CAPITAL LETTER MU
+ // U+03BC: GREEK SMALL LETTER MU
+ ["\u00B5", "\u039C", "\u03BC"],
+ // U+0345: COMBINING GREEK YPOGEGRAMMENI
+ // U+0399: GREEK CAPITAL LETTER IOTA
+ // U+03B9: GREEK SMALL LETTER IOTA
+ ["\u0345", "\u0399", "\u03B9"],
+ // U+03C2: GREEK SMALL LETTER FINAL SIGMA
+ // U+03A3: GREEK CAPITAL LETTER SIGMA
+ // U+03C3: GREEK SMALL LETTER SIGMA
+ ["\u03C2", "\u03A3", "\u03C3"],
+ // U+03D0: GREEK BETA SYMBOL
+ // U+0392: GREEK CAPITAL LETTER BETA
+ // U+03B2: GREEK SMALL LETTER BETA
+ ["\u03D0", "\u0392", "\u03B2"],
+ // U+03D1: GREEK THETA SYMBOL
+ // U+0398: GREEK CAPITAL LETTER THETA
+ // U+03B8: GREEK SMALL LETTER THETA
+ ["\u03D1", "\u0398", "\u03B8"],
+ // U+03D5: GREEK PHI SYMBOL
+ // U+03A6: GREEK CAPITAL LETTER PHI
+ // U+03C6: GREEK SMALL LETTER PHI
+ ["\u03D5", "\u03A6", "\u03C6"],
+ // U+03D6: GREEK PI SYMBOL
+ // U+03A0: GREEK CAPITAL LETTER PI
+ // U+03C0: GREEK SMALL LETTER PI
+ ["\u03D6", "\u03A0", "\u03C0"],
+ // U+03F0: GREEK KAPPA SYMBOL
+ // U+039A: GREEK CAPITAL LETTER KAPPA
+ // U+03BA: GREEK SMALL LETTER KAPPA
+ ["\u03F0", "\u039A", "\u03BA"],
+ // U+03F1: GREEK RHO SYMBOL
+ // U+03A1: GREEK CAPITAL LETTER RHO
+ // U+03C1: GREEK SMALL LETTER RHO
+ ["\u03F1", "\u03A1", "\u03C1"],
+ // U+03F5: GREEK LUNATE EPSILON SYMBOL
+ // U+0395: GREEK CAPITAL LETTER EPSILON
+ // U+03B5: GREEK SMALL LETTER EPSILON
+ ["\u03F5", "\u0395", "\u03B5"],
+ // U+1E9B: LATIN SMALL LETTER LONG S WITH DOT ABOVE
+ // U+1E60: LATIN CAPITAL LETTER S WITH DOT ABOVE
+ // U+1E61: LATIN SMALL LETTER S WITH DOT ABOVE
+ ["\u1E9B", "\u1E60", "\u1E61"],
+ // U+1FBE: GREEK PROSGEGRAMMENI
+ // U+0399: GREEK CAPITAL LETTER IOTA
+ // U+03B9: GREEK SMALL LETTER IOTA
+ ["\u1FBE", "\u0399", "\u03B9"],
+ ];
+
+for (var [code1, upper, code2] of pairs) {
+ assertEq(new RegExp(code1, "i").test(code2), true);
+ assertEq(new RegExp(code1, "i").test(upper), true);
+ assertEq(new RegExp(upper, "i").test(code1), true);
+ assertEq(new RegExp(upper, "i").test(code2), true);
+ assertEq(new RegExp(code2, "i").test(code1), true);
+ assertEq(new RegExp(code2, "i").test(upper), true);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/lastIndex-nonwritable.js b/js/src/tests/ecma_6/RegExp/lastIndex-nonwritable.js
new file mode 100644
index 000000000..3c867f953
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/lastIndex-nonwritable.js
@@ -0,0 +1,27 @@
+var BUGNUMBER = 1168416;
+var summary = "Regexp.prototype.test/exec shouldn't change lastIndex if not writable.";
+
+print(BUGNUMBER + ": " + summary);
+
+var regex = /0/g;
+Object.freeze(regex);
+var str = "abc000";
+
+var desc = Object.getOwnPropertyDescriptor(regex, "lastIndex");
+assertEq(desc.writable, false);
+assertEq(desc.value, 0);
+
+assertThrowsInstanceOf(() => regex.test(str), TypeError);
+
+desc = Object.getOwnPropertyDescriptor(regex, "lastIndex");
+assertEq(desc.writable, false);
+assertEq(desc.value, 0);
+
+assertThrowsInstanceOf(() => regex.exec(str), TypeError);
+
+desc = Object.getOwnPropertyDescriptor(regex, "lastIndex");
+assertEq(desc.writable, false);
+assertEq(desc.value, 0);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/match-this.js b/js/src/tests/ecma_6/RegExp/match-this.js
new file mode 100644
index 000000000..ee05462f2
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/match-this.js
@@ -0,0 +1,12 @@
+var BUGNUMBER = 887016;
+var summary = "RegExp.prototype[@@match] should check this value.";
+
+print(BUGNUMBER + ": " + summary);
+
+for (var v of [null, 1, true, undefined, "", Symbol.iterator]) {
+ assertThrowsInstanceOf(() => RegExp.prototype[Symbol.match].call(v),
+ TypeError);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/match-trace.js b/js/src/tests/ecma_6/RegExp/match-trace.js
new file mode 100644
index 000000000..3216db641
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/match-trace.js
@@ -0,0 +1,147 @@
+var BUGNUMBER = 887016;
+var summary = "Trace RegExp.prototype[@@match] behavior.";
+
+print(BUGNUMBER + ": " + summary);
+
+var n;
+var log;
+var target;
+var global;
+var unicode;
+var logProxy;
+
+var execResult;
+var lastIndexResult;
+var lastIndexExpected;
+
+function P(A) {
+ return new Proxy(A, {
+ get(that, name) {
+ if (logProxy)
+ log += "get:result[" + name + "],";
+ return that[name];
+ }
+ });
+}
+
+var myRegExp = {
+ get global() {
+ log += "get:global,";
+ return global;
+ },
+ get lastIndex() {
+ log += "get:lastIndex,";
+ return lastIndexResult[n];
+ },
+ set lastIndex(v) {
+ log += "set:lastIndex,";
+ assertEq(v, lastIndexExpected[n]);
+ },
+ get unicode() {
+ log += "get:unicode,";
+ return unicode;
+ },
+ get exec() {
+ log += "get:exec,";
+ return function(S) {
+ log += "call:exec,";
+ assertEq(S, target);
+ return execResult[n++];
+ };
+ },
+};
+
+function reset() {
+ n = 0;
+ log = "";
+ target = "abcAbcABC";
+ global = true;
+ unicode = false;
+ logProxy = true;
+}
+
+// Trace global with non-empty match.
+reset();
+execResult = [ P(["abc"]), P(["ABC"]), null ];
+lastIndexResult = [ , , , ];
+lastIndexExpected = [ 0, , , ];
+var ret = RegExp.prototype[Symbol.match].call(myRegExp, target);
+assertEq(JSON.stringify(ret), `["abc","ABC"]`);
+assertEq(log,
+ "get:global," +
+ "get:unicode," +
+ "set:lastIndex," +
+ "get:exec,call:exec,get:result[0]," +
+ "get:exec,call:exec,get:result[0]," +
+ "get:exec,call:exec,");
+
+// Trace global with empty match.
+reset();
+execResult = [ P([""]), P([""]), null ];
+lastIndexResult = [ , 4, 20, ];
+lastIndexExpected = [ 0, 5, 21, ];
+ret = RegExp.prototype[Symbol.match].call(myRegExp, target);
+assertEq(JSON.stringify(ret), `["",""]`);
+assertEq(log,
+ "get:global," +
+ "get:unicode," +
+ "set:lastIndex," +
+ "get:exec,call:exec,get:result[0],get:lastIndex,set:lastIndex," +
+ "get:exec,call:exec,get:result[0],get:lastIndex,set:lastIndex," +
+ "get:exec,call:exec,");
+
+// Trace global and unicode with empty match.
+// 1. not surrogate pair
+// 2. lead surrogate pair
+// 3. trail surrogate pair
+// 4. lead surrogate pair without trail surrogate pair
+// 5. index overflow
+reset();
+unicode = true;
+// 0123 4 5678
+target = "___\uD83D\uDC38___\uD83D";
+execResult = [ P([""]), P([""]), P([""]), P([""]), P([""]), null ];
+lastIndexResult = [ , 2, 3, 4, 8, 9, ];
+lastIndexExpected = [ 0, 3, 5, 5, 9, 10, ];
+ret = RegExp.prototype[Symbol.match].call(myRegExp, target);
+assertEq(JSON.stringify(ret), `["","","","",""]`);
+assertEq(log,
+ "get:global," +
+ "get:unicode," +
+ "set:lastIndex," +
+ "get:exec,call:exec,get:result[0],get:lastIndex,set:lastIndex," +
+ "get:exec,call:exec,get:result[0],get:lastIndex,set:lastIndex," +
+ "get:exec,call:exec,get:result[0],get:lastIndex,set:lastIndex," +
+ "get:exec,call:exec,get:result[0],get:lastIndex,set:lastIndex," +
+ "get:exec,call:exec,get:result[0],get:lastIndex,set:lastIndex," +
+ "get:exec,call:exec,");
+
+// Trace global with no match.
+reset();
+execResult = [ null ];
+lastIndexResult = [ , ];
+lastIndexExpected = [ 0, ];
+ret = RegExp.prototype[Symbol.match].call(myRegExp, target);
+assertEq(ret, null);
+assertEq(log,
+ "get:global," +
+ "get:unicode," +
+ "set:lastIndex," +
+ "get:exec,call:exec,");
+
+// Trace non-global.
+reset();
+global = false;
+execResult = [ P(["abc"]) ];
+lastIndexResult = [];
+lastIndexExpected = [];
+ret = RegExp.prototype[Symbol.match].call(myRegExp, target);
+// ret is the Proxy on non-global case, disable logging.
+logProxy = false;
+assertEq(JSON.stringify(ret), `["abc"]`);
+assertEq(log,
+ "get:global," +
+ "get:exec,call:exec,");
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/match.js b/js/src/tests/ecma_6/RegExp/match.js
new file mode 100644
index 000000000..06308b2d6
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/match.js
@@ -0,0 +1,36 @@
+var BUGNUMBER = 887016;
+var summary = "Implement RegExp.prototype[@@match].";
+
+print(BUGNUMBER + ": " + summary);
+
+assertEq(RegExp.prototype[Symbol.match].name, "[Symbol.match]");
+assertEq(RegExp.prototype[Symbol.match].length, 1);
+var desc = Object.getOwnPropertyDescriptor(RegExp.prototype, Symbol.match);
+assertEq(desc.configurable, true);
+assertEq(desc.enumerable, false);
+assertEq(desc.writable, true);
+
+var re = /a/;
+var v = re[Symbol.match]("abcAbcABC");
+assertEq(Array.isArray(v), true);
+assertEq(v.length, 1);
+assertEq(v[0], "a");
+
+re = /d/;
+v = re[Symbol.match]("abcAbcABC");
+assertEq(v, null);
+
+re = /a/ig;
+v = re[Symbol.match]("abcAbcABC");
+assertEq(Array.isArray(v), true);
+assertEq(v.length, 3);
+assertEq(v[0], "a");
+assertEq(v[1], "A");
+assertEq(v[2], "A");
+
+re = /d/g;
+v = re[Symbol.match]("abcAbcABC");
+assertEq(v, null);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/replace-compile.js b/js/src/tests/ecma_6/RegExp/replace-compile.js
new file mode 100644
index 000000000..45359037a
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/replace-compile.js
@@ -0,0 +1,21 @@
+var BUGNUMBER = 1287524;
+var summary = 'RegExp.prototype[@@replace] should call replacer function after collecting all matches.';
+
+print(BUGNUMBER + ": " + summary);
+
+var rx = RegExp("a", "g");
+var r = rx[Symbol.replace]("abba", function() {
+ rx.compile("b", "g");
+ return "?";
+});
+assertEq(r, "?bb?");
+
+rx = RegExp("a", "g");
+r = "abba".replace(rx, function() {
+ rx.compile("b", "g");
+ return "?";
+});
+assertEq(r, "?bb?");
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/replace-global-unicode.js b/js/src/tests/ecma_6/RegExp/replace-global-unicode.js
new file mode 100644
index 000000000..80b3ea199
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/replace-global-unicode.js
@@ -0,0 +1,18 @@
+var BUGNUMBER = 1287524;
+var summary = 'RegExp.prototype[@@replace] should not use optimized path if RegExp.prototype.unicode is modified.';
+
+print(BUGNUMBER + ": " + summary);
+
+Object.defineProperty(RegExp.prototype, "unicode", {
+ get() {
+ RegExp.prototype.exec = () => null;
+ }
+});
+
+var rx = RegExp("a", "g");
+var s = "abba";
+var r = rx[Symbol.replace](s, "c");
+assertEq(r, "abba");
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/replace-sticky-lastIndex.js b/js/src/tests/ecma_6/RegExp/replace-sticky-lastIndex.js
new file mode 100644
index 000000000..2500b2c42
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/replace-sticky-lastIndex.js
@@ -0,0 +1,23 @@
+var BUGNUMBER = 887016;
+var summary = "String.prototype.replace should do nothing if lastIndex is invalid for sticky RegExp";
+
+print(BUGNUMBER + ": " + summary);
+
+var re = /a/y;
+re.lastIndex = -1;
+assertEq("a".replace(re, "b"), "b");
+re.lastIndex = 0;
+assertEq("a".replace(re, "b"), "b");
+re.lastIndex = 1;
+assertEq("a".replace(re, "b"), "a");
+re.lastIndex = 2;
+assertEq("a".replace(re, "b"), "a");
+re.lastIndex = "foo";
+assertEq("a".replace(re, "b"), "b");
+re.lastIndex = "1";
+assertEq("a".replace(re, "b"), "a");
+re.lastIndex = {};
+assertEq("a".replace(re, "b"), "b");
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/replace-sticky.js b/js/src/tests/ecma_6/RegExp/replace-sticky.js
new file mode 100644
index 000000000..32a6e2aee
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/replace-sticky.js
@@ -0,0 +1,21 @@
+var BUGNUMBER = 887016;
+var summary = "String.prototype.replace should use and update lastIndex if sticky flag is set";
+
+print(BUGNUMBER + ": " + summary);
+
+var input = "abcdeabcdeabcdefghij";
+var re = new RegExp("abcde", "y");
+re.test(input);
+assertEq(re.lastIndex, 5);
+var ret = input.replace(re, "ABCDE");
+assertEq(ret, "abcdeABCDEabcdefghij");
+assertEq(re.lastIndex, 10);
+ret = input.replace(re, "ABCDE");
+assertEq(ret, "abcdeabcdeABCDEfghij");
+assertEq(re.lastIndex, 15);
+ret = input.replace(re, "ABCDE");
+assertEq(ret, "abcdeabcdeabcdefghij");
+assertEq(re.lastIndex, 0);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/replace-this.js b/js/src/tests/ecma_6/RegExp/replace-this.js
new file mode 100644
index 000000000..499304f9c
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/replace-this.js
@@ -0,0 +1,12 @@
+var BUGNUMBER = 887016;
+var summary = "RegExp.prototype[@@replace] should check |this| value.";
+
+print(BUGNUMBER + ": " + summary);
+
+for (var v of [null, 1, true, undefined, "", Symbol.iterator]) {
+ assertThrowsInstanceOf(() => RegExp.prototype[Symbol.replace].call(v),
+ TypeError);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/replace-trace.js b/js/src/tests/ecma_6/RegExp/replace-trace.js
new file mode 100644
index 000000000..73e623563
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/replace-trace.js
@@ -0,0 +1,309 @@
+var BUGNUMBER = 887016;
+var summary = "Trace RegExp.prototype[@@replace] behavior.";
+
+print(BUGNUMBER + ": " + summary);
+
+var n;
+var log;
+var target;
+var global;
+var unicode;
+
+var execResult;
+var lastIndexResult;
+var lastIndexExpected;
+
+var arraySetterObserved = false;
+function startObserve() {
+ for (var i = 0; i < 10; i++) {
+ Object.defineProperty(Array.prototype, i, {
+ set: function(v) {
+ arraySetterObserved = true;
+ },
+ configurable: true,
+ });
+ }
+}
+function stopObserve() {
+ for (var i = 0; i < 10; i++)
+ delete Array.prototype[i]
+}
+
+startObserve();
+
+function P(A, index, matched2) {
+ var i = 0;
+ A.index = index;
+ return new Proxy(A, {
+ get(that, name) {
+ log += "get:result[" + name + "],";
+
+ // Return a different value for 2nd access to result[0].
+ if (matched2 !== undefined && name == 0) {
+ if (i == 1) {
+ return matched2;
+ }
+ i++;
+ }
+
+ return that[name];
+ }
+ });
+}
+
+var myRegExp = {
+ get global() {
+ log += "get:global,";
+ return global;
+ },
+ get lastIndex() {
+ log += "get:lastIndex,";
+ return lastIndexResult[n];
+ },
+ set lastIndex(v) {
+ log += "set:lastIndex,";
+ assertEq(v, lastIndexExpected[n]);
+ },
+ get unicode() {
+ log += "get:unicode,";
+ return unicode;
+ },
+ get exec() {
+ log += "get:exec,";
+ return function(S) {
+ log += "call:exec,";
+ assertEq(S, target);
+ return execResult[n++];
+ };
+ },
+};
+
+function reset() {
+ n = 0;
+ log = "";
+ target = "abcAbcABC";
+ global = true;
+ unicode = false;
+ arraySetterObserved = false;
+}
+
+// Trace global with non-empty match.
+reset();
+execResult = [ P(["bc"], 1), null ];
+lastIndexResult = [ , , ];
+lastIndexExpected = [ 0, , ];
+var ret = RegExp.prototype[Symbol.replace].call(myRegExp, target, "_XYZ_");
+assertEq(arraySetterObserved, false);
+assertEq(ret, "a_XYZ_AbcABC");
+assertEq(log,
+ "get:global," +
+ "get:unicode," +
+ "set:lastIndex," +
+ "get:exec,call:exec," +
+ "get:result[0]," +
+ "get:exec,call:exec," +
+ "get:result[length],get:result[0],get:result[index],");
+
+// Trace global with empty match.
+reset();
+execResult = [ P([""], 1), null ];
+lastIndexResult = [ , 5, ];
+lastIndexExpected = [ 0, 6, ];
+ret = RegExp.prototype[Symbol.replace].call(myRegExp, target, "_XYZ_");
+assertEq(arraySetterObserved, false);
+assertEq(ret, "a_XYZ_bcAbcABC");
+assertEq(log,
+ "get:global," +
+ "get:unicode," +
+ "set:lastIndex," +
+ "get:exec,call:exec," +
+ "get:result[0]," +
+ "get:lastIndex,set:lastIndex," +
+ "get:exec,call:exec," +
+ "get:result[length],get:result[0],get:result[index],");
+
+// Trace global and unicode with empty match.
+// 1. not surrogate pair
+// 2. lead surrogate pair
+// 3. trail surrogate pair
+// 4. lead surrogate pair without trail surrogate pair
+// 5. index overflow
+reset();
+unicode = true;
+// 0123 4 5678
+target = "---\uD83D\uDC38---\uD83D";
+execResult = [ P([""], 1), P([""], 2), P([""], 3), P([""], 4), P([""], 5), null ];
+lastIndexResult = [ , 2, 3, 4, 8, 9, ];
+lastIndexExpected = [ 0, 3, 5, 5, 9, 10, ];
+ret = RegExp.prototype[Symbol.replace].call(myRegExp, target, "_XYZ_");
+assertEq(arraySetterObserved, false);
+assertEq(ret, "-_XYZ_-_XYZ_-_XYZ_\uD83D_XYZ_\uDC38_XYZ_---\uD83D");
+assertEq(log,
+ "get:global," +
+ "get:unicode," +
+ "set:lastIndex," +
+ "get:exec,call:exec," +
+ "get:result[0]," +
+ "get:lastIndex,set:lastIndex," +
+ "get:exec,call:exec," +
+ "get:result[0]," +
+ "get:lastIndex,set:lastIndex," +
+ "get:exec,call:exec," +
+ "get:result[0]," +
+ "get:lastIndex,set:lastIndex," +
+ "get:exec,call:exec," +
+ "get:result[0]," +
+ "get:lastIndex,set:lastIndex," +
+ "get:exec,call:exec," +
+ "get:result[0]," +
+ "get:lastIndex,set:lastIndex," +
+ "get:exec,call:exec," +
+ "get:result[length],get:result[0],get:result[index]," +
+ "get:result[length],get:result[0],get:result[index]," +
+ "get:result[length],get:result[0],get:result[index]," +
+ "get:result[length],get:result[0],get:result[index]," +
+ "get:result[length],get:result[0],get:result[index],");
+
+// Trace global with captures and substitutions.
+reset();
+execResult = [ P(["bc", "b", "c"], 1), null ];
+lastIndexResult = [ , , ];
+lastIndexExpected = [ 0, , ];
+ret = RegExp.prototype[Symbol.replace].call(myRegExp, target, "[$&,$`,$',$1,$2,$3,$]");
+assertEq(arraySetterObserved, false);
+assertEq(ret, "a[bc,a,AbcABC,b,c,$3,$]AbcABC");
+assertEq(log,
+ "get:global," +
+ "get:unicode," +
+ "set:lastIndex," +
+ "get:exec,call:exec," +
+ "get:result[0]," +
+ "get:exec,call:exec," +
+ "get:result[length],get:result[0],get:result[index]," +
+ "get:result[1],get:result[2],");
+
+// Trace global with empty match and captures and substitutions,
+// with different matched.
+reset();
+execResult = [ P(["", "b", "c"], 1, "BC"), null ];
+lastIndexResult = [ , 5, ];
+lastIndexExpected = [ 0, 6, ];
+ret = RegExp.prototype[Symbol.replace].call(myRegExp, target, "[$&,$`,$',$1,$2,$3,$]");
+assertEq(arraySetterObserved, false);
+assertEq(ret, "a[BC,a,AbcABC,b,c,$3,$]AbcABC");
+assertEq(log,
+ "get:global," +
+ "get:unicode," +
+ "set:lastIndex," +
+ "get:exec,call:exec," +
+ "get:result[0]," +
+ "get:lastIndex,set:lastIndex," +
+ "get:exec,call:exec," +
+ "get:result[length],get:result[0],get:result[index]," +
+ "get:result[1],get:result[2],");
+
+// Trace global with empty match and captures and function,
+// with different matched.
+reset();
+execResult = [ P(["", "b", "c"], 1, "BC"), null ];
+lastIndexResult = [ , 5, ];
+lastIndexExpected = [ 0, 6, ];
+function replaceFunc(...args) {
+ log += "call:replaceFunc,";
+ assertEq(args.length, 5);
+ assertEq(args[0], "BC");
+ assertEq(args[1], "b");
+ assertEq(args[2], "c");
+ assertEq(args[3], 1);
+ assertEq(args[4], target);
+ return "_ret_";
+}
+// This also tests RegExpStatics save/restore with no match.
+ret = RegExp.prototype[Symbol.replace].call(myRegExp, target, replaceFunc);
+assertEq(arraySetterObserved, false);
+assertEq(ret, "a_ret_AbcABC");
+assertEq(log,
+ "get:global," +
+ "get:unicode," +
+ "set:lastIndex," +
+ "get:exec,call:exec," +
+ "get:result[0]," +
+ "get:lastIndex,set:lastIndex," +
+ "get:exec,call:exec," +
+ "get:result[length],get:result[0],get:result[index]," +
+ "get:result[1],get:result[2]," +
+ "call:replaceFunc,");
+
+// Trace global with non-empty match, move backwards.
+// 2nd match shouldn't be replaced.
+reset();
+execResult = [ P(["X"], 5), P(["YZ"], 1), null ];
+lastIndexResult = [ , , , ];
+lastIndexExpected = [ 0, , , ];
+ret = RegExp.prototype[Symbol.replace].call(myRegExp, target, "_XYZ_");
+assertEq(arraySetterObserved, false);
+assertEq(ret, "abcAb_XYZ_ABC");
+assertEq(log,
+ "get:global," +
+ "get:unicode," +
+ "set:lastIndex," +
+ "get:exec,call:exec," +
+ "get:result[0]," +
+ "get:exec,call:exec," +
+ "get:result[0]," +
+ "get:exec,call:exec," +
+ "get:result[length],get:result[0],get:result[index]," +
+ "get:result[length],get:result[0],get:result[index],");
+
+// Trace global with non-empty match, position + matchLength overflows.
+reset();
+execResult = [ P(["fooooooo"], 7), null ];
+lastIndexResult = [ , , ];
+lastIndexExpected = [ 0, , ];
+ret = RegExp.prototype[Symbol.replace].call(myRegExp, target, "_XYZ_");
+assertEq(arraySetterObserved, false);
+assertEq(ret, "abcAbcA_XYZ_");
+assertEq(log,
+ "get:global," +
+ "get:unicode," +
+ "set:lastIndex," +
+ "get:exec,call:exec," +
+ "get:result[0]," +
+ "get:exec,call:exec," +
+ "get:result[length],get:result[0],get:result[index],");
+
+// Trace global with non-empty match, position overflows.
+reset();
+execResult = [ P(["fooooooo"], 12), null ];
+lastIndexResult = [ , , ];
+lastIndexExpected = [ 0, , ];
+ret = RegExp.prototype[Symbol.replace].call(myRegExp, target, "_XYZ_");
+assertEq(arraySetterObserved, false);
+assertEq(ret, "abcAbcABC_XYZ_");
+assertEq(log,
+ "get:global," +
+ "get:unicode," +
+ "set:lastIndex," +
+ "get:exec,call:exec," +
+ "get:result[0]," +
+ "get:exec,call:exec," +
+ "get:result[length],get:result[0],get:result[index],");
+
+// Trace non-global.
+reset();
+global = false;
+execResult = [ P(["bc"], 1) ];
+lastIndexResult = [ , , ];
+lastIndexExpected = [ 0, , ];
+ret = RegExp.prototype[Symbol.replace].call(myRegExp, target, "_XYZ_");
+assertEq(arraySetterObserved, false);
+assertEq(ret, "a_XYZ_AbcABC");
+assertEq(log,
+ "get:global," +
+ "get:exec,call:exec," +
+ "get:result[length],get:result[0],get:result[index],");
+
+stopObserve();
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/replace-twoBytes.js b/js/src/tests/ecma_6/RegExp/replace-twoBytes.js
new file mode 100644
index 000000000..660677c9f
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/replace-twoBytes.js
@@ -0,0 +1,44 @@
+var BUGNUMBER = 1269719;
+var summary = "RegExp.prototype[@@replace] should check latin1/twoBytes for all strings used in relate operation.";
+
+print(BUGNUMBER + ": " + summary);
+
+var ans = [
+ "[AB$2$3$]",
+ "[AB$2$3$]\u3048",
+ "[AB$2$3$]",
+ "[AB$2$3$]\u3048",
+ "[A\u3044$2$3$]",
+ "[A\u3044$2$3$]\u3048",
+ "[A\u3044$2$3$]",
+ "[A\u3044$2$3$]\u3048",
+ "[\u3042B$2$3$]",
+ "[\u3042B$2$3$]\u3048",
+ "[\u3042B$2$3$]",
+ "[\u3042B$2$3$]\u3048",
+ "[\u3042\u3044$2$3$]",
+ "[\u3042\u3044$2$3$]\u3048",
+ "[\u3042\u3044$2$3$]",
+ "[\u3042\u3044$2$3$]\u3048",
+];
+var i = 0;
+for (var matched of ["A", "\u3042"]) {
+ for (var group1 of ["B", "\u3044"]) {
+ for (var string of ["C", "\u3046"]) {
+ for (var replacement of ["[$&$`$'$1$2$3$]", "[$&$`$'$1$2$3$]\u3048"]) {
+ var myRegExp = {
+ get exec() {
+ return function() {
+ return [matched, group1];
+ };
+ }
+ };
+ assertEq(RegExp.prototype[Symbol.replace].call(myRegExp, string, replacement), ans[i]);
+ i++;
+ }
+ }
+ }
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/replace.js b/js/src/tests/ecma_6/RegExp/replace.js
new file mode 100644
index 000000000..43522ab55
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/replace.js
@@ -0,0 +1,34 @@
+var BUGNUMBER = 887016;
+var summary = "Implement RegExp.prototype[@@replace].";
+
+print(BUGNUMBER + ": " + summary);
+
+assertEq(RegExp.prototype[Symbol.replace].name, "[Symbol.replace]");
+assertEq(RegExp.prototype[Symbol.replace].length, 2);
+var desc = Object.getOwnPropertyDescriptor(RegExp.prototype, Symbol.replace);
+assertEq(desc.configurable, true);
+assertEq(desc.enumerable, false);
+assertEq(desc.writable, true);
+
+var re = /a/;
+var v = re[Symbol.replace]("abcAbcABC", "X");
+assertEq(v, "XbcAbcABC");
+
+re = /d/;
+v = re[Symbol.replace]("abcAbcABC", "X");
+assertEq(v, "abcAbcABC");
+
+re = /a/ig;
+v = re[Symbol.replace]("abcAbcABC", "X");
+assertEq(v, "XbcXbcXBC");
+
+re = /(a)(b)(cd)/;
+v = re[Symbol.replace]("012abcd345", "_$$_$&_$`_$'_$0_$1_$2_$3_$4_$+_$");
+assertEq(v, "012_$_abcd_012_345_$0_a_b_cd_$4_cd_$345");
+
+re = /(a)(b)(cd)/;
+v = re[Symbol.replace]("012abcd345", "_\u3042_$$_$&_$`_$'_$0_$1_$2_$3_$4_$+_$");
+assertEq(v, "012_\u3042_$_abcd_012_345_$0_a_b_cd_$4_cd_$345");
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/search-this.js b/js/src/tests/ecma_6/RegExp/search-this.js
new file mode 100644
index 000000000..731f5480f
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/search-this.js
@@ -0,0 +1,12 @@
+var BUGNUMBER = 887016;
+var summary = "RegExp.prototype[@@search] should check this value.";
+
+print(BUGNUMBER + ": " + summary);
+
+for (var v of [null, 1, true, undefined, "", Symbol.iterator]) {
+ assertThrowsInstanceOf(() => RegExp.prototype[Symbol.search].call(v),
+ TypeError);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/search-trace.js b/js/src/tests/ecma_6/RegExp/search-trace.js
new file mode 100644
index 000000000..ef14514c6
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/search-trace.js
@@ -0,0 +1,76 @@
+var BUGNUMBER = 887016;
+var summary = "Trace RegExp.prototype[@@search] behavior.";
+
+print(BUGNUMBER + ": " + summary);
+
+var n;
+var log;
+var target;
+
+var execResult;
+var lastIndexResult;
+var lastIndexExpected;
+
+function P(index) {
+ return new Proxy({ index }, {
+ get(that, name) {
+ log += "get:result[" + name + "],";
+ return that[name];
+ }
+ });
+}
+
+var myRegExp = {
+ get lastIndex() {
+ log += "get:lastIndex,";
+ return lastIndexResult[n];
+ },
+ set lastIndex(v) {
+ log += "set:lastIndex,";
+ assertEq(v, lastIndexExpected[n]);
+ },
+ get exec() {
+ log += "get:exec,";
+ return function(S) {
+ log += "call:exec,";
+ assertEq(S, target);
+ return execResult[n++];
+ };
+ },
+};
+
+function reset() {
+ n = 0;
+ log = "";
+ target = "abcAbcABC";
+}
+
+// Trace hit.
+reset();
+execResult = [ P(16) ];
+lastIndexResult = [ 10, , ];
+lastIndexExpected = [ 0, 10 ];
+var ret = RegExp.prototype[Symbol.search].call(myRegExp, target);
+assertEq(ret, 16);
+assertEq(log,
+ "get:lastIndex," +
+ "set:lastIndex," +
+ "get:exec,call:exec," +
+ "set:lastIndex," +
+ "get:result[index],");
+
+// Trace not hit.
+reset();
+execResult = [ null ];
+lastIndexResult = [ 10, , ];
+lastIndexExpected = [ 0, 10 ];
+ret = RegExp.prototype[Symbol.search].call(myRegExp, target);
+assertEq(ret, -1);
+assertEq(log,
+ "get:lastIndex," +
+ "set:lastIndex," +
+ "get:exec,call:exec," +
+ "set:lastIndex,");
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/search.js b/js/src/tests/ecma_6/RegExp/search.js
new file mode 100644
index 000000000..0875ee47e
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/search.js
@@ -0,0 +1,26 @@
+var BUGNUMBER = 887016;
+var summary = "Implement RegExp.prototype[@@search].";
+
+print(BUGNUMBER + ": " + summary);
+
+assertEq(RegExp.prototype[Symbol.search].name, "[Symbol.search]");
+assertEq(RegExp.prototype[Symbol.search].length, 1);
+var desc = Object.getOwnPropertyDescriptor(RegExp.prototype, Symbol.search);
+assertEq(desc.configurable, true);
+assertEq(desc.enumerable, false);
+assertEq(desc.writable, true);
+
+var re = /B/;
+var v = re[Symbol.search]("abcAbcABC");
+assertEq(v, 7);
+
+re = /B/i;
+v = re[Symbol.search]("abcAbcABCD");
+assertEq(v, 1);
+
+re = /d/;
+v = re[Symbol.search]("abcAbcABCD");
+assertEq(v, -1);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/shell.js b/js/src/tests/ecma_6/RegExp/shell.js
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/shell.js
diff --git a/js/src/tests/ecma_6/RegExp/source.js b/js/src/tests/ecma_6/RegExp/source.js
new file mode 100644
index 000000000..354a9d19d
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/source.js
@@ -0,0 +1,29 @@
+var BUGNUMBER = 1120169;
+var summary = "Implement RegExp.prototype.source";
+
+print(BUGNUMBER + ": " + summary);
+
+assertEq(RegExp.prototype.source, "(?:)");
+assertEq(/foo/.source, "foo");
+assertEq(/foo/iymg.source, "foo");
+assertEq(/\//.source, "\\/");
+assertEq(/\n\r/.source, "\\n\\r");
+assertEq(/\u2028\u2029/.source, "\\u2028\\u2029");
+assertEq(RegExp("").source, "(?:)");
+assertEq(RegExp("", "mygi").source, "(?:)");
+assertEq(RegExp("/").source, "\\/");
+assertEq(RegExp("\n\r").source, "\\n\\r");
+assertEq(RegExp("\u2028\u2029").source, "\\u2028\\u2029");
+
+assertThrowsInstanceOf(() => genericSource(), TypeError);
+assertThrowsInstanceOf(() => genericSource(1), TypeError);
+assertThrowsInstanceOf(() => genericSource(""), TypeError);
+assertThrowsInstanceOf(() => genericSource({}), TypeError);
+assertThrowsInstanceOf(() => genericSource(new Proxy(/foo/, {get(){ return true; }})), TypeError);
+
+function genericSource(obj) {
+ return Object.getOwnPropertyDescriptor(RegExp.prototype, "source").get.call(obj);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/split-deleted-flags.js b/js/src/tests/ecma_6/RegExp/split-deleted-flags.js
new file mode 100644
index 000000000..d2ccc852d
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/split-deleted-flags.js
@@ -0,0 +1,11 @@
+var BUGNUMBER = 1322319;
+var summary = "RegExp.prototype.split should throw if RegRxp.prototype.flags is deleted."
+
+print(BUGNUMBER + ": " + summary);
+
+delete RegExp.prototype.flags;
+
+assertThrowsInstanceOf(() => "aaaaa".split(/a/), SyntaxError);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/split-flags-on-obj.js b/js/src/tests/ecma_6/RegExp/split-flags-on-obj.js
new file mode 100644
index 000000000..8c68efed5
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/split-flags-on-obj.js
@@ -0,0 +1,21 @@
+var BUGNUMBER = 0;
+var summary = "RegExp.prototype.split should reflect the change to Object.prototype.flags.";
+
+print(BUGNUMBER + ": " + summary);
+
+Object.defineProperty(Object.prototype, "flags", Object.getOwnPropertyDescriptor(RegExp.prototype, "flags"));
+delete RegExp.prototype.flags;
+
+let re = /a/i;
+let a = re[Symbol.split]("1a2A3a4A5");
+assertDeepEq(a, ["1", "2", "3", "4", "5"]);
+
+delete Object.prototype.flags;
+
+Object.prototype.flags = "";
+
+a = re[Symbol.split]("1a2A3a4A5");
+assertDeepEq(a, ["1", "2A3", "4A5"]);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/split-invalid-lastIndex.js b/js/src/tests/ecma_6/RegExp/split-invalid-lastIndex.js
new file mode 100644
index 000000000..3def559ad
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/split-invalid-lastIndex.js
@@ -0,0 +1,31 @@
+var BUGNUMBER = 1263851;
+var summary = "RegExp.prototype[@@split] should handle if lastIndex is out of bound.";
+
+print(BUGNUMBER + ": " + summary);
+
+var myRegExp = {
+ get constructor() {
+ return {
+ get [Symbol.species]() {
+ return function() {
+ return {
+ get lastIndex() {
+ return 9;
+ },
+ set lastIndex(v) {},
+ exec() {
+ return [];
+ }
+ };
+ };
+ }
+ };
+ }
+};
+var result = RegExp.prototype[Symbol.split].call(myRegExp, "abcde");;
+assertEq(result.length, 2);
+assertEq(result[0], "");
+assertEq(result[1], "");
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/split-limit.js b/js/src/tests/ecma_6/RegExp/split-limit.js
new file mode 100644
index 000000000..5fa194b90
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/split-limit.js
@@ -0,0 +1,14 @@
+var BUGNUMBER = 1287525;
+var summary = "RegExp.prototype[@@split] shouldn't use optimized path if limit is not number.";
+
+print(BUGNUMBER + ": " + summary);
+
+var rx = /a/;
+var r = rx[Symbol.split]("abba", {valueOf() {
+ RegExp.prototype.exec = () => null;
+ return 100;
+}});
+assertEq(r.length, 1);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/split-obj.js b/js/src/tests/ecma_6/RegExp/split-obj.js
new file mode 100644
index 000000000..75c09f38d
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/split-obj.js
@@ -0,0 +1,12 @@
+var BUGNUMBER = 887016;
+var summary = "RegExp.prototype[@@split] should check if this value is RegExp.";
+
+print(BUGNUMBER + ": " + summary);
+
+var obj = { flags: "", toString: () => "-" };
+assertDeepEq(RegExp.prototype[Symbol.split].call(obj, "a-b-c"),
+ ["a", "b", "c"]);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
diff --git a/js/src/tests/ecma_6/RegExp/split-prop-access.js b/js/src/tests/ecma_6/RegExp/split-prop-access.js
new file mode 100644
index 000000000..73c5bebb3
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/split-prop-access.js
@@ -0,0 +1,19 @@
+var BUGNUMBER = 1287525;
+var summary = 'String.prototype.split should call ToUint32(limit) before ToString(separator).';
+
+print(BUGNUMBER + ": " + summary);
+
+var accessed = false;
+
+var rx = /a/;
+Object.defineProperty(rx, Symbol.match, {
+ get() {
+ accessed = true;
+ }
+});
+rx[Symbol.split]("abba");
+
+assertEq(accessed, true);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/split-this.js b/js/src/tests/ecma_6/RegExp/split-this.js
new file mode 100644
index 000000000..ece29fe8a
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/split-this.js
@@ -0,0 +1,12 @@
+var BUGNUMBER = 887016;
+var summary = "RegExp.prototype[@@split] should check this value.";
+
+print(BUGNUMBER + ": " + summary);
+
+for (var v of [null, 1, true, undefined, "", Symbol.iterator]) {
+ assertThrowsInstanceOf(() => RegExp.prototype[Symbol.split].call(v),
+ TypeError);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/split-trace.js b/js/src/tests/ecma_6/RegExp/split-trace.js
new file mode 100644
index 000000000..ce6e410d9
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/split-trace.js
@@ -0,0 +1,229 @@
+var BUGNUMBER = 887016;
+var summary = "Trace RegExp.prototype[@@split] behavior.";
+
+print(BUGNUMBER + ": " + summary);
+
+var n;
+var log;
+var target;
+var flags;
+var expectedFlags;
+
+var execResult;
+var lastIndexResult;
+var lastIndexExpected;
+
+var arraySetterObserved = false;
+function startObserve() {
+ for (var i = 0; i < 10; i++) {
+ Object.defineProperty(Array.prototype, i, {
+ set: function(v) {
+ arraySetterObserved = true;
+ },
+ configurable: true,
+ });
+ }
+}
+function stopObserve() {
+ for (var i = 0; i < 10; i++)
+ delete Array.prototype[i]
+}
+
+startObserve();
+
+function P(A) {
+ return new Proxy(A, {
+ get(that, name) {
+ log += "get:result[" + name + "],";
+ return that[name];
+ }
+ });
+}
+
+var myRegExp = {
+ get constructor() {
+ log += "get:constructor,";
+ return {
+ get [Symbol.species]() {
+ log += "get:species,";
+ return function(pattern, flags) {
+ assertEq(pattern, myRegExp);
+ assertEq(flags, expectedFlags);
+ log += "call:constructor,";
+ return {
+ get lastIndex() {
+ log += "get:lastIndex,";
+ return lastIndexResult[n];
+ },
+ set lastIndex(v) {
+ log += "set:lastIndex,";
+ assertEq(v, lastIndexExpected[n]);
+ },
+ get flags() {
+ log += "get:flags,";
+ return flags;
+ },
+ get exec() {
+ log += "get:exec,";
+ return function(S) {
+ log += "call:exec,";
+ assertEq(S, target);
+ return execResult[n++];
+ };
+ },
+ };
+ };
+ }
+ };
+ },
+ get flags() {
+ log += "get:flags,";
+ return flags;
+ },
+};
+
+function reset() {
+ n = 0;
+ log = "";
+ target = "abcde";
+ flags = "";
+ expectedFlags = "y";
+ arraySetterObserved = false;
+}
+
+// Trace match and no match.
+reset();
+execResult = [ null, P(["b"]), null, P(["d"]), null ];
+lastIndexResult = [ , , 2, , 4, , ];
+lastIndexExpected = [ 0, 1, 2, 3, 4, ];
+var ret = RegExp.prototype[Symbol.split].call(myRegExp, target);
+assertEq(arraySetterObserved, false);
+assertEq(JSON.stringify(ret), `["a","c","e"]`);
+assertEq(log,
+ "get:constructor," +
+ "get:species," +
+ "get:flags," +
+ "call:constructor," +
+ "set:lastIndex,get:exec,call:exec," +
+ "set:lastIndex,get:exec,call:exec,get:lastIndex," +
+ "get:result[length]," +
+ "set:lastIndex,get:exec,call:exec," +
+ "set:lastIndex,get:exec,call:exec,get:lastIndex," +
+ "get:result[length]," +
+ "set:lastIndex,get:exec,call:exec,");
+
+// Trace non-empty flags, empty target, no match.
+reset();
+flags = "iy";
+expectedFlags = "iy";
+target = "";
+execResult = [ null ];
+lastIndexResult = [];
+lastIndexExpected = [];
+ret = RegExp.prototype[Symbol.split].call(myRegExp, target);
+assertEq(arraySetterObserved, false);
+assertEq(JSON.stringify(ret), `[""]`);
+assertEq(log,
+ "get:constructor," +
+ "get:species," +
+ "get:flags," +
+ "call:constructor," +
+ "get:exec,call:exec,");
+
+// Trace empty target, match.
+reset();
+target = "";
+execResult = [ P([""]) ];
+lastIndexResult = [];
+lastIndexExpected = [];
+ret = RegExp.prototype[Symbol.split].call(myRegExp, target);
+assertEq(arraySetterObserved, false);
+assertEq(JSON.stringify(ret), `[]`);
+assertEq(log,
+ "get:constructor," +
+ "get:species," +
+ "get:flags," +
+ "call:constructor," +
+ "get:exec,call:exec,");
+
+// Trace captures.
+reset();
+target = "abc";
+execResult = [ null, P(["b", "X", "YZ"]), null ];
+lastIndexResult = [ , , 2, , ];
+lastIndexExpected = [ 0, 1, 2, ];
+ret = RegExp.prototype[Symbol.split].call(myRegExp, target);
+assertEq(arraySetterObserved, false);
+assertEq(JSON.stringify(ret), `["a","X","YZ","c"]`);
+assertEq(log,
+ "get:constructor," +
+ "get:species," +
+ "get:flags," +
+ "call:constructor," +
+ "set:lastIndex,get:exec,call:exec," +
+ "set:lastIndex,get:exec,call:exec,get:lastIndex," +
+ "get:result[length]," +
+ "get:result[1],get:result[2]," +
+ "set:lastIndex,get:exec,call:exec,");
+
+// Trace unicode.
+// 1. not surrogate pair
+// 2. lead surrogate pair
+// 3. trail surrogate pair
+// 4. lead surrogate pair without trail surrogate pair
+// 5. index overflow
+reset();
+flags = "u";
+expectedFlags = "uy";
+target = "-\uD83D\uDC38\uDC38\uD83D";
+execResult = [ null, null, null, null ];
+lastIndexResult = [ , , , , , ];
+lastIndexExpected = [ 0, 1, 3, 4, ];
+ret = RegExp.prototype[Symbol.split].call(myRegExp, target);
+assertEq(arraySetterObserved, false);
+assertEq(JSON.stringify(ret), `["-\uD83D\uDC38\uDC38\uD83D"]`);
+assertEq(log,
+ "get:constructor," +
+ "get:species," +
+ "get:flags," +
+ "call:constructor," +
+ "set:lastIndex,get:exec,call:exec," +
+ "set:lastIndex,get:exec,call:exec," +
+ "set:lastIndex,get:exec,call:exec," +
+ "set:lastIndex,get:exec,call:exec,");
+
+// Trace unicode, match, same position and different position.
+reset();
+flags = "u";
+expectedFlags = "uy";
+target = "-\uD83D\uDC38\uDC38\uD83D";
+var E = P(["", "X"]);
+execResult = [ E, E, E, E, E, E, E ];
+lastIndexResult = [ , 0, 1, 1, 3, 3, 4, 4 ];
+lastIndexExpected = [ 0, 1, 1, 3, 3, 4, 4, ];
+ret = RegExp.prototype[Symbol.split].call(myRegExp, target);
+assertEq(arraySetterObserved, false);
+assertEq(JSON.stringify(ret), `["-","X","\uD83D\uDC38","X","\uDC38","X","\uD83D"]`);
+assertEq(log,
+ "get:constructor," +
+ "get:species," +
+ "get:flags," +
+ "call:constructor," +
+ "set:lastIndex,get:exec,call:exec,get:lastIndex," +
+ "set:lastIndex,get:exec,call:exec,get:lastIndex," +
+ "get:result[length]," +
+ "get:result[1]," +
+ "set:lastIndex,get:exec,call:exec,get:lastIndex," +
+ "set:lastIndex,get:exec,call:exec,get:lastIndex," +
+ "get:result[length]," +
+ "get:result[1]," +
+ "set:lastIndex,get:exec,call:exec,get:lastIndex," +
+ "set:lastIndex,get:exec,call:exec,get:lastIndex," +
+ "get:result[length]," +
+ "get:result[1]," +
+ "set:lastIndex,get:exec,call:exec,get:lastIndex,");
+
+stopObserve();
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/split.js b/js/src/tests/ecma_6/RegExp/split.js
new file mode 100644
index 000000000..d7e28d791
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/split.js
@@ -0,0 +1,30 @@
+var BUGNUMBER = 887016;
+var summary = "Implement RegExp.prototype[@@split].";
+
+print(BUGNUMBER + ": " + summary);
+
+assertEq(RegExp.prototype[Symbol.split].name, "[Symbol.split]");
+assertEq(RegExp.prototype[Symbol.split].length, 2);
+var desc = Object.getOwnPropertyDescriptor(RegExp.prototype, Symbol.split);
+assertEq(desc.configurable, true);
+assertEq(desc.enumerable, false);
+assertEq(desc.writable, true);
+
+var re = /b/;
+var v = re[Symbol.split]("abcAbcABC");
+assertEq(JSON.stringify(v), `["a","cA","cABC"]`);
+
+re = /d/;
+v = re[Symbol.split]("abcAbcABC");
+assertEq(JSON.stringify(v), `["abcAbcABC"]`);
+
+re = /b/ig;
+v = re[Symbol.split]("abcAbcABC");
+assertEq(JSON.stringify(v), `["a","cA","cA","C"]`);
+
+re = /b/ig;
+v = re[Symbol.split]("abcAbcABC", 2);
+assertEq(JSON.stringify(v), `["a","cA"]`);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/sticky.js b/js/src/tests/ecma_6/RegExp/sticky.js
new file mode 100644
index 000000000..13a6debe9
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/sticky.js
@@ -0,0 +1,126 @@
+var BUGNUMBER = 773687;
+var summary = 'sticky flag should not break assertion behavior.';
+
+print(BUGNUMBER + ": " + summary);
+
+function test(re, text, expectations) {
+ // Sanity check for test data itself.
+ assertEq(expectations.length, text.length + 1);
+
+ for (var i = 0; i < expectations.length; i++) {
+ var result = expectations[i];
+
+ re.lastIndex = i;
+ var match = re.exec(text);
+ if (result === null) {
+ assertEq(re.lastIndex, 0);
+ assertEq(match, null);
+ } else {
+ assertEq(re.lastIndex, result.lastIndex);
+ assertEq(match !== null, true);
+ assertEq(match.length, result.matches.length);
+ for (var j = 0; j < result.matches.length; j++)
+ assertEq(match[j], result.matches[j]);
+ assertEq(match.index, result.index);
+ }
+ }
+}
+
+// simple text
+test(/bc/y, "abcabd", [
+ null,
+ { lastIndex: 3, matches: ["bc"], index: 1 },
+ null,
+ null,
+ null,
+ null,
+ null,
+]);
+
+// complex pattern
+test(/bc|c|d/y, "abcabd", [
+ null,
+ { lastIndex: 3, matches: ["bc"], index: 1 },
+ { lastIndex: 3, matches: ["c"], index: 2 },
+ null,
+ null,
+ { lastIndex: 6, matches: ["d"], index: 5 },
+ null,
+]);
+
+test(/.*(bc|c|d)/y, "abcabd", [
+ { lastIndex: 6, matches: ["abcabd", "d"], index: 0 },
+ { lastIndex: 6, matches: ["bcabd", "d"], index: 1 },
+ { lastIndex: 6, matches: ["cabd", "d"], index: 2 },
+ { lastIndex: 6, matches: ["abd", "d"], index: 3 },
+ { lastIndex: 6, matches: ["bd", "d"], index: 4 },
+ { lastIndex: 6, matches: ["d", "d"], index: 5 },
+ null,
+]);
+
+test(/.*?(bc|c|d)/y, "abcabd", [
+ { lastIndex: 3, matches: ["abc", "bc"], index: 0 },
+ { lastIndex: 3, matches: ["bc", "bc"], index: 1 },
+ { lastIndex: 3, matches: ["c", "c"], index: 2 },
+ { lastIndex: 6, matches: ["abd", "d"], index: 3 },
+ { lastIndex: 6, matches: ["bd", "d"], index: 4 },
+ { lastIndex: 6, matches: ["d", "d"], index: 5 },
+ null,
+]);
+
+test(/(bc|.*c|d)/y, "abcabd", [
+ { lastIndex: 3, matches: ["abc", "abc"], index: 0 },
+ { lastIndex: 3, matches: ["bc", "bc"], index: 1 },
+ { lastIndex: 3, matches: ["c", "c"], index: 2 },
+ null,
+ null,
+ { lastIndex: 6, matches: ["d", "d"], index: 5 },
+ null,
+]);
+
+// ^ assertions
+test(/^/y, "abcabc", [
+ { lastIndex: 0, matches: [""], index: 0 },
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+]);
+
+test(/^a/my, "abc\nabc", [
+ { lastIndex: 1, matches: ["a"], index: 0 },
+ null,
+ null,
+ null,
+ { lastIndex: 5, matches: ["a"], index: 4 },
+ null,
+ null,
+ null,
+]);
+
+// \b assertions
+test(/\b/y, "abc bc", [
+ { lastIndex: 0, matches: [""], index: 0 },
+ null,
+ null,
+ { lastIndex: 3, matches: [""], index: 3 },
+ { lastIndex: 4, matches: [""], index: 4 },
+ null,
+ { lastIndex: 6, matches: [""], index: 6 },
+]);
+
+// \B assertions
+test(/\B/y, "abc bc", [
+ null,
+ { lastIndex: 1, matches: [""], index: 1 },
+ { lastIndex: 2, matches: [""], index: 2 },
+ null,
+ null,
+ { lastIndex: 5, matches: [""], index: 5 },
+ null,
+]);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/test-trailing.js b/js/src/tests/ecma_6/RegExp/test-trailing.js
new file mode 100644
index 000000000..7cb910ee6
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/test-trailing.js
@@ -0,0 +1,31 @@
+var BUGNUMBER = 1304737;
+var summary = "Trailing .* should not be ignored on matchOnly match.";
+
+print(BUGNUMBER + ": " + summary);
+
+function test(r, lastIndexIsZero) {
+ r.lastIndex = 0;
+ r.test("foo");
+ assertEq(r.lastIndex, lastIndexIsZero ? 0 : 3);
+
+ r.lastIndex = 0;
+ r.test("foo\nbar");
+ assertEq(r.lastIndex, lastIndexIsZero ? 0 : 3);
+
+ var input = "foo" + ".bar".repeat(20000);
+ r.lastIndex = 0;
+ r.test(input);
+ assertEq(r.lastIndex, lastIndexIsZero ? 0 : input.length);
+
+ r.lastIndex = 0;
+ r.test(input + "\nbaz");
+ assertEq(r.lastIndex, lastIndexIsZero ? 0 : input.length);
+}
+
+test(/f.*/, true);
+test(/f.*/g, false);
+test(/f.*/y, false);
+test(/f.*/gy, false);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/toString.js b/js/src/tests/ecma_6/RegExp/toString.js
new file mode 100644
index 000000000..5ffbeed33
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/toString.js
@@ -0,0 +1,42 @@
+var BUGNUMBER = 1079919;
+var summary = "Make RegExp.prototype.toString to be a generic function.";
+
+print(BUGNUMBER + ": " + summary);
+
+assertEq(RegExp.prototype.toString(), "/(?:)/");
+assertEq(/foo/.toString(), "/foo/");
+assertEq(/foo/i.toString(), "/foo/i");
+assertEq(/foo/gimy.toString(), "/foo/gimy");
+assertEq(/foo/igym.toString(), "/foo/gimy");
+assertEq(/\n\r/.toString(), "/\\n\\r/");
+assertEq(/\u2028\u2029/.toString(), "/\\u2028\\u2029/");
+assertEq(/\//.toString(), "/\\//");
+assertEq(RegExp().toString(), "/(?:)/");
+assertEq(RegExp("", "gimy").toString(), "/(?:)/gimy");
+assertEq(RegExp("\n\r").toString(), "/\\n\\r/");
+assertEq(RegExp("\u2028\u2029").toString(), "/\\u2028\\u2029/");
+assertEq(RegExp("/").toString(), "/\\//");
+
+assertThrowsInstanceOf(() => RegExp.prototype.toString.call(), TypeError);
+assertThrowsInstanceOf(() => RegExp.prototype.toString.call(1), TypeError);
+assertThrowsInstanceOf(() => RegExp.prototype.toString.call(""), TypeError);
+assertEq(RegExp.prototype.toString.call({}), "/undefined/undefined");
+assertEq(RegExp.prototype.toString.call({ source:"foo", flags:"bar" }), "/foo/bar");
+
+var a = [];
+var p = new Proxy({}, {
+ get(that, name) {
+ a.push(name);
+ return {
+ toString() {
+ a.push(name + "-tostring");
+ return name;
+ }
+ };
+ }
+});
+assertEq(RegExp.prototype.toString.call(p), "/source/flags");
+assertEq(a.join(","), "source,source-tostring,flags,flags-tostring");
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/unicode-back-reference.js b/js/src/tests/ecma_6/RegExp/unicode-back-reference.js
new file mode 100644
index 000000000..2a65432a1
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/unicode-back-reference.js
@@ -0,0 +1,39 @@
+var BUGNUMBER = 1135377;
+var summary = "Implement RegExp unicode flag -- back reference should not match lead surrogate that has corresponding trail surrogate.";
+
+print(BUGNUMBER + ": " + summary);
+
+// The last character of back reference is not a surrogate.
+assertEqArray(/foo(.+)bar\1/u.exec("fooAbarA\uDC00"),
+ ["fooAbarA", "A"]);
+assertEqArray(/foo(.+)bar\1/u.exec("fooAbarA\uD834"),
+ ["fooAbarA", "A"]);
+assertEqArray(/foo(.+)bar\1/u.exec("fooAbarAA"),
+ ["fooAbarA", "A"]);
+assertEqArray(/foo(.+)bar\1/u.exec("fooAbarA"),
+ ["fooAbarA", "A"]);
+
+// The last character of back reference is a lead surrogate.
+assertEq(/foo(.+)bar\1/u.exec("foo\uD834bar\uD834\uDC00"), null);
+assertEqArray(/foo(.+)bar\1/u.exec("foo\uD834bar\uD834\uD834"),
+ ["foo\uD834bar\uD834", "\uD834"]);
+assertEqArray(/foo(.+)bar\1/u.exec("foo\uD834bar\uD834A"),
+ ["foo\uD834bar\uD834", "\uD834"]);
+assertEqArray(/foo(.+)bar\1/u.exec("foo\uD834bar\uD834"),
+ ["foo\uD834bar\uD834", "\uD834"]);
+
+// The last character of back reference is a trail surrogate.
+assertEqArray(/foo(.+)bar\1/u.exec("foo\uDC00bar\uDC00\uDC00"),
+ ["foo\uDC00bar\uDC00", "\uDC00"]);
+assertEqArray(/foo(.+)bar\1/u.exec("foo\uDC00bar\uDC00\uD834"),
+ ["foo\uDC00bar\uDC00", "\uDC00"]);
+assertEqArray(/foo(.+)bar\1/u.exec("foo\uDC00bar\uDC00A"),
+ ["foo\uDC00bar\uDC00", "\uDC00"]);
+assertEqArray(/foo(.+)bar\1/u.exec("foo\uDC00bar\uDC00"),
+ ["foo\uDC00bar\uDC00", "\uDC00"]);
+
+// Pattern should not match to surrogate pair partially.
+assertEq(/^(.+)\1$/u.exec("\uDC00foobar\uD834\uDC00foobar\uD834"), null);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/unicode-braced.js b/js/src/tests/ecma_6/RegExp/unicode-braced.js
new file mode 100644
index 000000000..97df7acab
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/unicode-braced.js
@@ -0,0 +1,166 @@
+var BUGNUMBER = 1135377;
+var summary = "Implement RegExp unicode flag -- braced pattern in RegExpUnicodeEscapeSequence.";
+
+print(BUGNUMBER + ": " + summary);
+
+// ==== standalone ====
+
+assertEqArray(/\u{41}/u.exec("ABC"),
+ ["A"]);
+assertEqArray(/\u{41}/.exec("ABC" + "u".repeat(41)),
+ ["u".repeat(41)]);
+
+assertEqArray(/\u{4A}/u.exec("JKL"),
+ ["J"]);
+assertEqArray(/\u{4A}/.exec("JKLu{4A}"),
+ ["u{4A}"]);
+
+assertEqArray(/\u{1F438}/u.exec("\u{1F438}"),
+ ["\u{1F438}"]);
+assertEqArray(/\u{1F438}/.exec("u{1F438}"),
+ ["u{1F438}"]);
+
+assertEqArray(/\u{0}/u.exec("\u{0}"),
+ ["\u{0}"]);
+assertEqArray(/\u{10FFFF}/u.exec("\u{10FFFF}"),
+ ["\u{10FFFF}"]);
+assertEqArray(/\u{10ffff}/u.exec("\u{10FFFF}"),
+ ["\u{10FFFF}"]);
+
+// leading 0
+assertEqArray(/\u{0000000000000000000000}/u.exec("\u{0}"),
+ ["\u{0}"]);
+assertEqArray(/\u{000000000000000010FFFF}/u.exec("\u{10FFFF}"),
+ ["\u{10FFFF}"]);
+
+// RegExp constructor
+assertEqArray(new RegExp("\\u{0}", "u").exec("\u{0}"),
+ ["\u{0}"]);
+assertEqArray(new RegExp("\\u{41}", "u").exec("ABC"),
+ ["A"]);
+assertEqArray(new RegExp("\\u{1F438}", "u").exec("\u{1F438}"),
+ ["\u{1F438}"]);
+assertEqArray(new RegExp("\\u{10FFFF}", "u").exec("\u{10FFFF}"),
+ ["\u{10FFFF}"]);
+
+assertEqArray(new RegExp("\\u{0000000000000000}", "u").exec("\u{0}"),
+ ["\u{0}"]);
+
+assertEqArray(eval(`/\\u{${"0".repeat(Math.pow(2, 24)) + "1234"}}/u`).exec("\u{1234}"),
+ ["\u{1234}"]);
+assertEqArray(new RegExp(`\\u{${"0".repeat(Math.pow(2, 24)) + "1234"}}`, "u").exec("\u{1234}"),
+ ["\u{1234}"]);
+
+// ==== ? ====
+
+assertEqArray(/\u{1F438}?/u.exec("\u{1F438}"),
+ ["\u{1F438}"]);
+assertEqArray(/\u{1F438}?/u.exec(""),
+ [""]);
+
+// lead-only target
+assertEqArray(/\u{1F438}?/u.exec("\uD83D"),
+ [""]);
+
+// RegExp constructor
+assertEqArray(new RegExp("\\u{1F438}?", "u").exec("\u{1F438}"),
+ ["\u{1F438}"]);
+assertEqArray(new RegExp("\\u{1F438}?", "u").exec(""),
+ [""]);
+assertEqArray(new RegExp("\\u{1F438}?", "u").exec("\uD83D"),
+ [""]);
+
+// ==== + ====
+
+assertEqArray(/\u{1F438}+/u.exec("\u{1F438}"),
+ ["\u{1F438}"]);
+assertEqArray(/\u{1F438}+/u.exec("\u{1F438}\u{1F438}"),
+ ["\u{1F438}\u{1F438}"]);
+assertEq(/\u{1F438}+/u.exec(""),
+ null);
+
+// lead-only target
+assertEq(/\u{1F438}+/u.exec("\uD83D"),
+ null);
+assertEqArray(/\u{1F438}+/u.exec("\uD83D\uDC38\uDC38"),
+ ["\uD83D\uDC38"]);
+
+// ==== * ====
+
+assertEqArray(/\u{1F438}*/u.exec("\u{1F438}"),
+ ["\u{1F438}"]);
+assertEqArray(/\u{1F438}*/u.exec("\u{1F438}\u{1F438}"),
+ ["\u{1F438}\u{1F438}"]);
+assertEqArray(/\u{1F438}*/u.exec(""),
+ [""]);
+
+// lead-only target
+assertEqArray(/\u{1F438}*/u.exec("\uD83D"),
+ [""]);
+assertEqArray(/\u{1F438}*/u.exec("\uD83D\uDC38\uDC38"),
+ ["\uD83D\uDC38"]);
+
+// ==== lead-only ====
+
+// match only non-surrogate pair
+assertEqArray(/\u{D83D}/u.exec("\uD83D\uDBFF"),
+ ["\uD83D"]);
+assertEq(/\u{D83D}/u.exec("\uD83D\uDC00"),
+ null);
+assertEq(/\u{D83D}/u.exec("\uD83D\uDFFF"),
+ null);
+assertEqArray(/\u{D83D}/u.exec("\uD83D\uE000"),
+ ["\uD83D"]);
+
+// match before non-tail char
+assertEqArray(/\u{D83D}/u.exec("\uD83D"),
+ ["\uD83D"]);
+assertEqArray(/\u{D83D}/u.exec("\uD83DA"),
+ ["\uD83D"]);
+
+// ==== trail-only ====
+
+// match only non-surrogate pair
+assertEqArray(/\u{DC38}/u.exec("\uD7FF\uDC38"),
+ ["\uDC38"]);
+assertEq(/\u{DC38}/u.exec("\uD800\uDC38"),
+ null);
+assertEq(/\u{DC38}/u.exec("\uDBFF\uDC38"),
+ null);
+assertEqArray(/\u{DC38}/u.exec("\uDC00\uDC38"),
+ ["\uDC38"]);
+
+// match after non-lead char
+assertEqArray(/\u{DC38}/u.exec("\uDC38"),
+ ["\uDC38"]);
+assertEqArray(/\u{DC38}/u.exec("A\uDC38"),
+ ["\uDC38"]);
+
+// ==== wrong patterns ====
+
+assertThrowsInstanceOf(() => eval(`/\\u{-1}/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/\\u{0.0}/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/\\u{G}/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/\\u{}/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/\\u{{/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/\\u{/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/\\u{110000}/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/\\u{00110000}/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/\\u{100000000000000000000000000000}/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/\\u{FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF}/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/\\u{ FFFF}/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/\\u{FFFF }/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/\\u{FF FF}/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/\\u{F F F F}/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/\\u{100000001}/u`), SyntaxError);
+
+// surrogate pair with braced
+assertEq(/\u{D83D}\u{DC38}+/u.exec("\uD83D\uDC38\uDC38"),
+ null);
+assertEq(/\uD83D\u{DC38}+/u.exec("\uD83D\uDC38\uDC38"),
+ null);
+assertEq(/\u{D83D}\uDC38+/u.exec("\uD83D\uDC38\uDC38"),
+ null);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/unicode-character-class-escape.js b/js/src/tests/ecma_6/RegExp/unicode-character-class-escape.js
new file mode 100644
index 000000000..175207d5a
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/unicode-character-class-escape.js
@@ -0,0 +1,75 @@
+var BUGNUMBER = 1135377;
+var summary = "Implement RegExp unicode flag -- CharacterClassEscape.";
+
+print(BUGNUMBER + ": " + summary);
+
+// BMP
+
+assertEqArray(/\d+/u.exec("abcxyzABCXYZ0123456789_\t\r\n\v\x0c\xa0\uFEFF*"),
+ ["0123456789"]);
+assertEqArray(/\D+/u.exec("abcxyzABCXYZ0123456789_\t\r\n\v\x0c\xa0\uFEFF*"),
+ ["abcxyzABCXYZ"]);
+
+assertEqArray(/\s+/u.exec("abcxyzABCXYZ0123456789_\t\r\n\v\x0c\xa0\uFEFF*"),
+ ["\t\r\n\v\x0c\xa0\uFEFF"]);
+assertEqArray(/\S+/u.exec("abcxyzABCXYZ0123456789_\t\r\n\v\x0c\xa0\uFEFF*"),
+ ["abcxyzABCXYZ0123456789_"]);
+
+assertEqArray(/\w+/u.exec("abcxyzABCXYZ0123456789_\t\r\n\v\x0c\xa0\uFEFF*"),
+ ["abcxyzABCXYZ0123456789_"]);
+assertEqArray(/\W+/u.exec("abcxyzABCXYZ0123456789_\t\r\n\v\x0c\xa0\uFEFF*"),
+ ["\t\r\n\v\x0c\xa0\uFEFF*"]);
+
+assertEqArray(/\n+/u.exec("abcxyzABCXYZ0123456789_\t\r\n\v\x0c\xa0\uFEFF*"),
+ ["\n"]);
+
+assertEqArray(/[\d]+/u.exec("abcxyzABCXYZ0123456789_\t\r\n\v\x0c\xa0\uFEFF*"),
+ ["0123456789"]);
+assertEqArray(/[\D]+/u.exec("abcxyzABCXYZ0123456789_\t\r\n\v\x0c\xa0\uFEFF*"),
+ ["abcxyzABCXYZ"]);
+
+assertEqArray(/[\s]+/u.exec("abcxyzABCXYZ0123456789_\t\r\n\v\x0c\xa0\uFEFF*"),
+ ["\t\r\n\v\x0c\xa0\uFEFF"]);
+assertEqArray(/[\S]+/u.exec("abcxyzABCXYZ0123456789_\t\r\n\v\x0c\xa0\uFEFF*"),
+ ["abcxyzABCXYZ0123456789_"]);
+
+assertEqArray(/[\w]+/u.exec("abcxyzABCXYZ0123456789_\t\r\n\v\x0c\xa0\uFEFF*"),
+ ["abcxyzABCXYZ0123456789_"]);
+assertEqArray(/[\W]+/u.exec("abcxyzABCXYZ0123456789_\t\r\n\v\x0c\xa0\uFEFF*"),
+ ["\t\r\n\v\x0c\xa0\uFEFF*"]);
+
+assertEqArray(/[\n]+/u.exec("abcxyzABCXYZ0123456789_\t\r\n\v\x0c\xa0\uFEFF*"),
+ ["\n"]);
+
+// non-BMP
+
+function testNonBMP(re) {
+ assertEqArray(re.exec("\uD83D\uDBFF"),
+ ["\uD83D"]);
+ assertEqArray(re.exec("\uD83D\uDC00"),
+ ["\uD83D\uDC00"]);
+ assertEqArray(re.exec("\uD83D\uDFFF"),
+ ["\uD83D\uDFFF"]);
+ assertEqArray(re.exec("\uD83D\uE000"),
+ ["\uD83D"]);
+
+ assertEqArray(re.exec("\uD7FF\uDC38"),
+ ["\uD7FF"]);
+ assertEqArray(re.exec("\uD800\uDC38"),
+ ["\uD800\uDC38"]);
+ assertEqArray(re.exec("\uDBFF\uDC38"),
+ ["\uDBFF\uDC38"]);
+ assertEqArray(re.exec("\uDC00\uDC38"),
+ ["\uDC00"]);
+}
+
+testNonBMP(/\D/u);
+testNonBMP(/\S/u);
+testNonBMP(/\W/u);
+
+testNonBMP(/[\D]/u);
+testNonBMP(/[\S]/u);
+testNonBMP(/[\W]/u);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/unicode-class-braced.js b/js/src/tests/ecma_6/RegExp/unicode-class-braced.js
new file mode 100644
index 000000000..4b5954012
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/unicode-class-braced.js
@@ -0,0 +1,236 @@
+var BUGNUMBER = 1135377;
+var summary = "Implement RegExp unicode flag -- braced pattern in RegExpUnicodeEscapeSequence in CharacterClass.";
+
+print(BUGNUMBER + ": " + summary);
+
+// ==== standalone ====
+
+assertEqArray(/[\u{41}]/u.exec("ABC"),
+ ["A"]);
+
+assertEqArray(/[\u{1F438}]/u.exec("\u{1F438}"),
+ ["\u{1F438}"]);
+assertEq(/[\u{1F438}]/u.exec("\uD83D"),
+ null);
+assertEq(/[\u{1F438}]/u.exec("\uDC38"),
+ null);
+
+assertEqArray(/[\u{0}]/u.exec("\u{0}"),
+ ["\u{0}"]);
+assertEqArray(/[\u{10FFFF}]/u.exec("\u{10FFFF}"),
+ ["\u{10FFFF}"]);
+assertEqArray(/[\u{10ffff}]/u.exec("\u{10FFFF}"),
+ ["\u{10FFFF}"]);
+
+// leading 0
+assertEqArray(/[\u{0000000000000000000000}]/u.exec("\u{0}"),
+ ["\u{0}"]);
+assertEqArray(/[\u{000000000000000010FFFF}]/u.exec("\u{10FFFF}"),
+ ["\u{10FFFF}"]);
+
+// RegExp constructor
+assertEqArray(new RegExp("[\\u{0}]", "u").exec("\u{0}"),
+ ["\u{0}"]);
+assertEqArray(new RegExp("[\\u{41}]", "u").exec("ABC"),
+ ["A"]);
+assertEqArray(new RegExp("[\\u{1F438}]", "u").exec("\u{1F438}"),
+ ["\u{1F438}"]);
+assertEqArray(new RegExp("[\\u{10FFFF}]", "u").exec("\u{10FFFF}"),
+ ["\u{10FFFF}"]);
+
+assertEqArray(new RegExp("[\\u{0000000000000000}]", "u").exec("\u{0}"),
+ ["\u{0}"]);
+
+assertEqArray(eval(`/[\\u{${"0".repeat(Math.pow(2, 24)) + "1234"}}]/u`).exec("\u{1234}"),
+ ["\u{1234}"]);
+assertEqArray(new RegExp(`[\\u{${"0".repeat(Math.pow(2, 24)) + "1234"}}]`, "u").exec("\u{1234}"),
+ ["\u{1234}"]);
+
+// ==== BMP + non-BMP ====
+
+assertEqArray(/[A\u{1F438}]/u.exec("A\u{1F438}"),
+ ["A"]);
+assertEqArray(/[A\u{1F438}]/u.exec("\u{1F438}A"),
+ ["\u{1F438}"]);
+
+// lead-only target
+assertEqArray(/[A\u{1F438}]/u.exec("\uD83DA"),
+ ["A"]);
+assertEq(/[A\u{1F438}]/u.exec("\uD83D"),
+ null);
+
+// +
+assertEqArray(/[A\u{1F438}]+/u.exec("\u{1F438}A\u{1F438}A"),
+ ["\u{1F438}A\u{1F438}A"]);
+
+// trail surrogate + lead surrogate
+assertEqArray(/[A\u{1F438}]+/u.exec("\uD83D\uDC38A\uDC38\uD83DA"),
+ ["\uD83D\uDC38A"]);
+
+// ==== non-BMP + non-BMP ====
+
+assertEqArray(/[\u{1F418}\u{1F438}]/u.exec("\u{1F418}\u{1F438}"),
+ ["\u{1F418}"]);
+
+assertEqArray(/[\u{1F418}\u{1F438}]+/u.exec("\u{1F418}\u{1F438}"),
+ ["\u{1F418}\u{1F438}"]);
+assertEqArray(/[\u{1F418}\u{1F438}]+/u.exec("\u{1F418}\uDC38\uD83D"),
+ ["\u{1F418}"]);
+assertEqArray(/[\u{1F418}\u{1F438}]+/u.exec("\uDC18\uD83D\u{1F438}"),
+ ["\u{1F438}"]);
+assertEqArray(/[\u{1F418}\u{1F438}]+/u.exec("\uDC18\u{1F438}\uD83D"),
+ ["\u{1F438}"]);
+
+// trail surrogate + lead surrogate
+assertEq(/[\u{1F418}\u{1F438}]+/u.exec("\uDC18\uDC38\uD83D\uD83D"),
+ null);
+
+// ==== non-BMP + non-BMP range (from_lead == to_lead) ====
+
+assertEqArray(/[\u{1F418}-\u{1F438}]/u.exec("\u{1F418}"),
+ ["\u{1F418}"]);
+assertEqArray(/[\u{1F418}-\u{1F438}]/u.exec("\u{1F438}"),
+ ["\u{1F438}"]);
+assertEqArray(/[\u{1F418}-\u{1F438}]/u.exec("\u{1F427}"),
+ ["\u{1F427}"]);
+
+assertEq(/[\u{1F418}-\u{1F438}]/u.exec("\u{1F417}"),
+ null);
+assertEq(/[\u{1F418}-\u{1F438}]/u.exec("\u{1F439}"),
+ null);
+
+// ==== non-BMP + non-BMP range (from_lead + 1 == to_lead) ====
+
+assertEqArray(/[\u{1F17C}-\u{1F438}]/u.exec("\uD83C\uDD7C"),
+ ["\uD83C\uDD7C"]);
+assertEqArray(/[\u{1F17C}-\u{1F438}]/u.exec("\u{1F438}"),
+ ["\u{1F438}"]);
+assertEqArray(/[\u{1F17C}-\u{1F438}]/u.exec("\uD83C\uDF99"),
+ ["\uD83C\uDF99"]);
+assertEqArray(/[\u{1F17C}-\u{1F438}]/u.exec("\uD83D\uDC00"),
+ ["\uD83D\uDC00"]);
+
+assertEq(/[\u{1F17C}-\u{1F438}]/u.exec("\uD83C\uDD7B"),
+ null);
+assertEq(/[\u{1F17C}-\u{1F438}]/u.exec("\uD83C\uE000"),
+ null);
+assertEq(/[\u{1F17C}-\u{1F438}]/u.exec("\uD83D\uDB99"),
+ null);
+assertEq(/[\u{1F17C}-\u{1F438}]/u.exec("\uD83D\uDC39"),
+ null);
+
+// ==== non-BMP + non-BMP range (from_lead + 2 == to_lead) ====
+
+assertEqArray(/[\u{1F17C}-\u{1F829}]/u.exec("\uD83C\uDD7C"),
+ ["\uD83C\uDD7C"]);
+assertEqArray(/[\u{1F17C}-\u{1F829}]/u.exec("\uD83E\uDC29"),
+ ["\uD83E\uDC29"]);
+
+assertEqArray(/[\u{1F17C}-\u{1F829}]/u.exec("\uD83C\uDF99"),
+ ["\uD83C\uDF99"]);
+assertEqArray(/[\u{1F17C}-\u{1F829}]/u.exec("\uD83D\uDC00"),
+ ["\uD83D\uDC00"]);
+assertEqArray(/[\u{1F17C}-\u{1F829}]/u.exec("\uD83D\uDF99"),
+ ["\uD83D\uDF99"]);
+assertEqArray(/[\u{1F17C}-\u{1F829}]/u.exec("\uD83E\uDC00"),
+ ["\uD83E\uDC00"]);
+
+assertEq(/[\u{1F17C}-\u{1F829}]/u.exec("\uD83C\uDD7B"),
+ null);
+assertEq(/[\u{1F17C}-\u{1F829}]/u.exec("\uD83C\uE000"),
+ null);
+assertEq(/[\u{1F17C}-\u{1F829}]/u.exec("\uD83D\uDB99"),
+ null);
+assertEq(/[\u{1F17C}-\u{1F829}]/u.exec("\uD83D\uE000"),
+ null);
+assertEq(/[\u{1F17C}-\u{1F829}]/u.exec("\uD83E\uDB99"),
+ null);
+assertEq(/[\u{1F17C}-\u{1F829}]/u.exec("\uD83E\uDC30"),
+ null);
+
+// ==== non-BMP + non-BMP range (other) ====
+
+assertEqArray(/[\u{1D164}-\u{1F438}]/u.exec("\uD834\uDD64"),
+ ["\uD834\uDD64"]);
+assertEqArray(/[\u{1D164}-\u{1F438}]/u.exec("\u{1F438}"),
+ ["\u{1F438}"]);
+assertEqArray(/[\u{1D164}-\u{1F438}]/u.exec("\uD836\uDF99"),
+ ["\uD836\uDF99"]);
+assertEqArray(/[\u{1D164}-\u{1F438}]/u.exec("\uD838\uDC00"),
+ ["\uD838\uDC00"]);
+
+assertEq(/[\u{1D164}-\u{1F438}]/u.exec("\uD834\uDD63"),
+ null);
+assertEq(/[\u{1D164}-\u{1F438}]/u.exec("\uD83D\uDC39"),
+ null);
+
+assertEq(/[\u{1D164}-\u{1F438}]/u.exec("\uD834\uE000"),
+ null);
+assertEq(/[\u{1D164}-\u{1F438}]/u.exec("\uD835\uDB99"),
+ null);
+assertEq(/[\u{1D164}-\u{1F438}]/u.exec("\uD83C\uE000"),
+ null);
+assertEq(/[\u{1D164}-\u{1F438}]/u.exec("\uD83D\uDB99"),
+ null);
+
+// ==== BMP + non-BMP range ====
+
+assertEqArray(/[\u{42}-\u{1F438}]/u.exec("B"),
+ ["B"]);
+assertEqArray(/[\u{42}-\u{1F438}]/u.exec("C"),
+ ["C"]);
+assertEqArray(/[\u{42}-\u{1F438}]/u.exec("\uFFFF"),
+ ["\uFFFF"]);
+assertEqArray(/[\u{42}-\u{1F438}]/u.exec("\uD800\uDC00"),
+ ["\uD800\uDC00"]);
+
+assertEqArray(/[\u{42}-\u{1F438}]/u.exec("\uD800"),
+ ["\uD800"]);
+assertEqArray(/[\u{42}-\u{1F438}]/u.exec("\uDBFF"),
+ ["\uDBFF"]);
+assertEqArray(/[\u{42}-\u{1F438}]/u.exec("\uDC00"),
+ ["\uDC00"]);
+assertEqArray(/[\u{42}-\u{1F438}]/u.exec("\uDFFF"),
+ ["\uDFFF"]);
+
+assertEqArray(/[\u{42}-\u{1F438}]/u.exec("\uD83D"),
+ ["\uD83D"]);
+assertEqArray(/[\u{42}-\u{1F438}]/u.exec("\uDC38"),
+ ["\uDC38"]);
+
+assertEqArray(/[\u{42}-\u{1F438}]/u.exec("\uD83D\uDBFF"),
+ ["\uD83D"]);
+assertEqArray(/[\u{42}-\u{1F438}]/u.exec("\uD83D\uDC00"),
+ ["\uD83D\uDC00"]);
+assertEqArray(/[\u{42}-\u{1F438}]/u.exec("\uD83D\uDC38"),
+ ["\uD83D\uDC38"]);
+assertEq(/[\u{42}-\u{1F438}]/u.exec("\uD83D\uDC39"),
+ null);
+assertEq(/[\u{42}-\u{1F438}]/u.exec("\uD83D\uDFFF"),
+ null);
+assertEqArray(/[\u{42}-\u{1F438}]/u.exec("\uD83D\uE000"),
+ ["\uD83D"]);
+
+assertEq(/[\u{42}-\u{1F438}]/u.exec("A"),
+ null);
+
+// ==== wrong patterns ====
+
+assertThrowsInstanceOf(() => eval(`/[\\u{-1}]/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/[\\u{0.0}]/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/[\\u{G}]/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/[\\u{}]/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/[\\u{{]/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/[\\u{]/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/[\\u{110000}]/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/[\\u{00110000}]/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/[\\u{100000000000000000000000000000}]/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/[\\u{FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF}]/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/[\\u{ FFFF}]/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/[\\u{FFFF }]/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/[\\u{FF FF}]/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/[\\u{F F F F}]/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/[\\u{100000001}]/u`), SyntaxError);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/unicode-class-empty.js b/js/src/tests/ecma_6/RegExp/unicode-class-empty.js
new file mode 100644
index 000000000..4d187551f
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/unicode-class-empty.js
@@ -0,0 +1,25 @@
+var BUGNUMBER = 1135377;
+var summary = "Implement RegExp unicode flag -- empty class should not match anything.";
+
+print(BUGNUMBER + ": " + summary);
+
+assertEq(/[]/u.exec("A"),
+ null);
+assertEq(/[]/u.exec("\uD83D"),
+ null);
+assertEq(/[]/u.exec("\uDC38"),
+ null);
+assertEq(/[]/u.exec("\uD83D\uDC38"),
+ null);
+
+assertEqArray(/[^]/u.exec("A"),
+ ["A"]);
+assertEqArray(/[^]/u.exec("\uD83D"),
+ ["\uD83D"]);
+assertEqArray(/[^]/u.exec("\uDC38"),
+ ["\uDC38"]);
+assertEqArray(/[^]/u.exec("\uD83D\uDC38"),
+ ["\uD83D\uDC38"]);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/unicode-class-ignoreCase.js b/js/src/tests/ecma_6/RegExp/unicode-class-ignoreCase.js
new file mode 100644
index 000000000..afa7705c7
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/unicode-class-ignoreCase.js
@@ -0,0 +1,28 @@
+var BUGNUMBER = 1135377;
+var summary = "Implement RegExp unicode flag -- ignoreCase flag for CharacterClass.";
+
+print(BUGNUMBER + ": " + summary);
+
+assertEqArray(/[ABC]+/iu.exec("DCBAabcd"),
+ ["CBAabc"]);
+
+assertEqArray(/[A\u{10401}]+/iu.exec("A\u{10401}a\u{10429}"),
+ ["A\u{10401}a\u{10429}"]);
+
+assertEqArray(/[\u{10401}-\u{10404}\u{10408}-\u{1040B}]+/iu.exec("\u{10400}\u{10401}\u{10402}\u{10403}\u{10404}\u{10408}\u{10409}\u{1040A}\u{1040B}\u{1040C}"),
+ ["\u{10401}\u{10402}\u{10403}\u{10404}\u{10408}\u{10409}\u{1040A}\u{1040B}"]);
+assertEqArray(/[\u{10401}-\u{10404}\u{10408}-\u{1040B}]+/iu.exec("\u{10428}\u{10429}\u{1042A}\u{1042B}\u{1042C}\u{10430}\u{10431}\u{10432}\u{10433}\u{10434}"),
+ ["\u{10429}\u{1042A}\u{1042B}\u{1042C}\u{10430}\u{10431}\u{10432}\u{10433}"]);
+
+assertEqArray(/[\u{10429}-\u{1042C}\u{10430}-\u{10433}]+/iu.exec("\u{10400}\u{10401}\u{10402}\u{10403}\u{10404}\u{10408}\u{10409}\u{1040A}\u{1040B}\u{1040C}"),
+ ["\u{10401}\u{10402}\u{10403}\u{10404}\u{10408}\u{10409}\u{1040A}\u{1040B}"]);
+assertEqArray(/[\u{10429}-\u{1042C}\u{10430}-\u{10433}]+/iu.exec("\u{10428}\u{10429}\u{1042A}\u{1042B}\u{1042C}\u{10430}\u{10431}\u{10432}\u{10433}\u{10434}"),
+ ["\u{10429}\u{1042A}\u{1042B}\u{1042C}\u{10430}\u{10431}\u{10432}\u{10433}"]);
+
+assertEqArray(/[\u{10401}-\u{10404}\u{10430}-\u{10433}]+/iu.exec("\u{10400}\u{10401}\u{10402}\u{10403}\u{10404}\u{10408}\u{10409}\u{1040A}\u{1040B}\u{1040C}"),
+ ["\u{10401}\u{10402}\u{10403}\u{10404}\u{10408}\u{10409}\u{1040A}\u{1040B}"]);
+assertEqArray(/[\u{10401}-\u{10404}\u{10430}-\u{10433}]+/iu.exec("\u{10428}\u{10429}\u{1042A}\u{1042B}\u{1042C}\u{10430}\u{10431}\u{10432}\u{10433}\u{10434}"),
+ ["\u{10429}\u{1042A}\u{1042B}\u{1042C}\u{10430}\u{10431}\u{10432}\u{10433}"]);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/unicode-class-lead-trail.js b/js/src/tests/ecma_6/RegExp/unicode-class-lead-trail.js
new file mode 100644
index 000000000..c83bf937d
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/unicode-class-lead-trail.js
@@ -0,0 +1,142 @@
+var BUGNUMBER = 1135377;
+var summary = "Implement RegExp unicode flag -- lead and trail pattern in RegExpUnicodeEscapeSequence in CharacterClass.";
+
+print(BUGNUMBER + ": " + summary);
+
+// ==== standalone ====
+
+assertEqArray(/[\uD83D\uDC38]/u.exec("\uD83D\uDC38"),
+ ["\uD83D\uDC38"]);
+assertEq(/[\uD83D\uDC38]/u.exec("\uD83D"),
+ null);
+assertEq(/[\uD83D\uDC38]/u.exec("\uDC38"),
+ null);
+
+// no unicode flag
+assertEqArray(/[\uD83D\uDC38]/.exec("\uD83D\uDC38"),
+ ["\uD83D"]);
+assertEqArray(/[\uD83D\uDC38]/.exec("\uD83D"),
+ ["\uD83D"]);
+assertEqArray(/[\uD83D\uDC38]/.exec("\uDC38"),
+ ["\uDC38"]);
+
+// RegExp constructor
+assertEqArray(new RegExp("[\uD83D\uDC38]", "u").exec("\uD83D\uDC38"),
+ ["\uD83D\uDC38"]);
+assertEq(new RegExp("[\uD83D\uDC38]", "u").exec("\uD83D"),
+ null);
+assertEq(new RegExp("[\uD83D\uDC38]", "u").exec("\uDC38"),
+ null);
+
+// RegExp constructor, no unicode flag
+assertEqArray(new RegExp("[\uD83D\uDC38]", "").exec("\uD83D\uDC38"),
+ ["\uD83D"]);
+assertEqArray(new RegExp("[\uD83D\uDC38]", "").exec("\uD83D"),
+ ["\uD83D"]);
+assertEqArray(new RegExp("[\uD83D\uDC38]", "").exec("\uDC38"),
+ ["\uDC38"]);
+
+// ==== lead-only ====
+
+// match only non-surrogate pair
+assertEqArray(/[\uD83D]/u.exec("\uD83D\uDBFF"),
+ ["\uD83D"]);
+assertEq(/[\uD83D]/u.exec("\uD83D\uDC00"),
+ null);
+assertEq(/[\uD83D]/u.exec("\uD83D\uDFFF"),
+ null);
+assertEqArray(/[\uD83D]/u.exec("\uD83D\uE000"),
+ ["\uD83D"]);
+
+// match before non-tail char
+assertEqArray(/[\uD83D]/u.exec("\uD83D"),
+ ["\uD83D"]);
+assertEqArray(/[\uD83D]/u.exec("\uD83DA"),
+ ["\uD83D"]);
+
+// no unicode flag
+assertEqArray(/[\uD83D]/.exec("\uD83D\uDBFF"),
+ ["\uD83D"]);
+assertEqArray(/[\uD83D]/.exec("\uD83D\uDC00"),
+ ["\uD83D"]);
+assertEqArray(/[\uD83D]/.exec("\uD83D\uDFFF"),
+ ["\uD83D"]);
+assertEqArray(/[\uD83D]/.exec("\uD83D\uE000"),
+ ["\uD83D"]);
+assertEqArray(/[\uD83D]/.exec("\uD83D"),
+ ["\uD83D"]);
+assertEqArray(/[\uD83D]/.exec("\uD83DA"),
+ ["\uD83D"]);
+
+// ==== trail-only ====
+
+// match only non-surrogate pair
+assertEqArray(/[\uDC38]/u.exec("\uD7FF\uDC38"),
+ ["\uDC38"]);
+assertEq(/[\uDC38]/u.exec("\uD800\uDC38"),
+ null);
+assertEq(/[\uDC38]/u.exec("\uDBFF\uDC38"),
+ null);
+assertEqArray(/[\uDC38]/u.exec("\uDC00\uDC38"),
+ ["\uDC38"]);
+
+// match after non-lead char
+assertEqArray(/[\uDC38]/u.exec("\uDC38"),
+ ["\uDC38"]);
+assertEqArray(/[\uDC38]/u.exec("A\uDC38"),
+ ["\uDC38"]);
+
+// no unicode flag
+assertEqArray(/[\uDC38]/.exec("\uD7FF\uDC38"),
+ ["\uDC38"]);
+assertEqArray(/[\uDC38]/.exec("\uD800\uDC38"),
+ ["\uDC38"]);
+assertEqArray(/[\uDC38]/.exec("\uDBFF\uDC38"),
+ ["\uDC38"]);
+assertEqArray(/[\uDC38]/.exec("\uDC00\uDC38"),
+ ["\uDC38"]);
+assertEqArray(/[\uDC38]/.exec("\uDC38"),
+ ["\uDC38"]);
+assertEqArray(/[\uDC38]/.exec("A\uDC38"),
+ ["\uDC38"]);
+
+// ==== invalid trail ====
+
+assertEqArray(/[\uD83D\u3042]*/u.exec("\uD83D"),
+ ["\uD83D"]);
+assertEqArray(/[\uD83D\u3042]*/u.exec("\uD83D\u3042"),
+ ["\uD83D\u3042"]);
+assertEqArray(/[\uD83D\u3042]*/u.exec("\uD83D\u3042\u3042\uD83D"),
+ ["\uD83D\u3042\u3042\uD83D"]);
+
+assertEqArray(/[\uD83D\u{3042}]*/u.exec("\uD83D"),
+ ["\uD83D"]);
+assertEqArray(/[\uD83D\u{3042}]*/u.exec("\uD83D\u3042"),
+ ["\uD83D\u3042"]);
+assertEqArray(/[\uD83D\u{3042}]*/u.exec("\uD83D\u3042\u3042\uD83D"),
+ ["\uD83D\u3042\u3042\uD83D"]);
+
+assertEqArray(/[\uD83DA]*/u.exec("\uD83D"),
+ ["\uD83D"]);
+assertEqArray(/[\uD83DA]*/u.exec("\uD83DA"),
+ ["\uD83DA"]);
+assertEqArray(/[\uD83DA]*/u.exec("\uD83DAA\uD83D"),
+ ["\uD83DAA\uD83D"]);
+
+// ==== wrong patterns ====
+
+assertThrowsInstanceOf(() => eval(`/[\\u]/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/[\\u0]/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/[\\u00]/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/[\\u000]/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/[\\u000G]/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/[\\u0.00]/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/[\\uD83D\\u]/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/[\\uD83D\\u0]/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/[\\uD83D\\u00]/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/[\\uD83D\\u000]/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/[\\uD83D\\u000G]/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/[\\uD83D\\u0.00]/u`), SyntaxError);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/unicode-class-negated.js b/js/src/tests/ecma_6/RegExp/unicode-class-negated.js
new file mode 100644
index 000000000..0b573f6dc
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/unicode-class-negated.js
@@ -0,0 +1,64 @@
+var BUGNUMBER = 1135377;
+var summary = "Implement RegExp unicode flag -- negated CharacterClass.";
+
+print(BUGNUMBER + ": " + summary);
+
+// ==== BMP ====
+
+assertEqArray(/[^A]/u.exec("ABC"),
+ ["B"]);
+assertEqArray(/[^A]/u.exec("A\u{1F438}C"),
+ ["\u{1F438}"]);
+assertEqArray(/[^A]/u.exec("A\uD83DC"),
+ ["\uD83D"]);
+assertEqArray(/[^A]/u.exec("A\uDC38C"),
+ ["\uDC38"]);
+
+assertEqArray(/[^\uE000]/u.exec("\uE000\uE001"),
+ ["\uE001"]);
+assertEqArray(/[^\uE000]/u.exec("\uE000\u{1F438}"),
+ ["\u{1F438}"]);
+assertEqArray(/[^\uE000]/u.exec("\uE000\uD83D"),
+ ["\uD83D"]);
+assertEqArray(/[^\uE000]/u.exec("\uE000\uDC38"),
+ ["\uDC38"]);
+
+// ==== non-BMP ====
+
+assertEqArray(/[^\u{1F438}]/u.exec("\u{1F438}A"),
+ ["A"]);
+assertEqArray(/[^\u{1F438}]/u.exec("\u{1F438}\u{1F439}"),
+ ["\u{1F439}"]);
+assertEqArray(/[^\u{1F438}]/u.exec("\u{1F438}\uD83D"),
+ ["\uD83D"]);
+assertEqArray(/[^\u{1F438}]/u.exec("\u{1F438}\uDC38"),
+ ["\uDC38"]);
+
+// ==== lead-only ====
+
+assertEqArray(/[^\uD83D]/u.exec("\u{1F438}A"),
+ ["\u{1F438}"]);
+assertEqArray(/[^\uD83D]/u.exec("\uD83D\uDBFF"),
+ ["\uDBFF"]);
+assertEqArray(/[^\uD83D]/u.exec("\uD83D\uDC00"),
+ ["\uD83D\uDC00"]);
+assertEqArray(/[^\uD83D]/u.exec("\uD83D\uDFFF"),
+ ["\uD83D\uDFFF"]);
+assertEqArray(/[^\uD83D]/u.exec("\uD83D\uE000"),
+ ["\uE000"]);
+
+// ==== trail-only ====
+
+assertEqArray(/[^\uDC38]/u.exec("\u{1F438}A"),
+ ["\u{1F438}"]);
+assertEqArray(/[^\uDC38]/u.exec("\uD7FF\uDC38"),
+ ["\uD7FF"]);
+assertEqArray(/[^\uDC38]/u.exec("\uD800\uDC38"),
+ ["\uD800\uDC38"]);
+assertEqArray(/[^\uDC38]/u.exec("\uDBFF\uDC38"),
+ ["\uDBFF\uDC38"]);
+assertEqArray(/[^\uDC38]/u.exec("\uDC00\uDC38"),
+ ["\uDC00"]);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/unicode-class-range.js b/js/src/tests/ecma_6/RegExp/unicode-class-range.js
new file mode 100644
index 000000000..5bb757560
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/unicode-class-range.js
@@ -0,0 +1,28 @@
+var BUGNUMBER = 1135377;
+var summary = "Implement RegExp unicode flag -- disallow range with CharacterClassEscape.";
+
+print(BUGNUMBER + ": " + summary);
+
+assertThrowsInstanceOf(() => eval(`/[\\w-\\uFFFF]/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/[\\W-\\uFFFF]/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/[\\d-\\uFFFF]/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/[\\D-\\uFFFF]/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/[\\s-\\uFFFF]/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/[\\S-\\uFFFF]/u`), SyntaxError);
+
+assertThrowsInstanceOf(() => eval(`/[\\uFFFF-\\w]/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/[\\uFFFF-\\W]/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/[\\uFFFF-\\d]/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/[\\uFFFF-\\D]/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/[\\uFFFF-\\s]/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/[\\uFFFF-\\S]/u`), SyntaxError);
+
+assertThrowsInstanceOf(() => eval(`/[\\w-\\w]/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/[\\W-\\W]/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/[\\d-\\d]/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/[\\D-\\D]/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/[\\s-\\s]/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/[\\S-\\S]/u`), SyntaxError);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/unicode-class-raw.js b/js/src/tests/ecma_6/RegExp/unicode-class-raw.js
new file mode 100644
index 000000000..742fec2b4
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/unicode-class-raw.js
@@ -0,0 +1,65 @@
+var BUGNUMBER = 1135377;
+var summary = "Implement RegExp unicode flag -- raw unicode.";
+
+print(BUGNUMBER + ": " + summary);
+
+// ==== standalone ====
+
+assertEqArray(eval(`/[\uD83D\uDC38]/u`).exec("\u{1F438}"),
+ ["\u{1F438}"]);
+
+// no unicode flag
+assertEqArray(eval(`/[\uD83D\uDC38]/`).exec("\u{1F438}"),
+ ["\uD83D"]);
+
+// escaped (lead)
+assertEq(eval(`/[\\uD83D\uDC38]/u`).exec("\u{1F438}"),
+ null);
+assertEq(eval(`/[\\u{D83D}\uDC38]/u`).exec("\u{1F438}"),
+ null);
+
+// escaped (trail)
+assertEq(eval(`/[\uD83D\\uDC38]/u`).exec("\u{1F438}"),
+ null);
+assertEq(eval(`/[\uD83D\\u{DC38}]/u`).exec("\u{1F438}"),
+ null);
+
+// escaped (lead), no unicode flag
+assertEqArray(eval(`/[\\uD83D\uDC38]/`).exec("\u{1F438}"),
+ ["\uD83D"]);
+
+// escaped (trail), no unicode flag
+assertEqArray(eval(`/[\uD83D\\uDC38]/`).exec("\u{1F438}"),
+ ["\uD83D"]);
+
+// ==== RegExp constructor ====
+
+assertEqArray(new RegExp("[\uD83D\uDC38]", "u").exec("\u{1F438}"),
+ ["\u{1F438}"]);
+
+// no unicode flag
+assertEqArray(new RegExp("[\uD83D\uDC38]", "").exec("\u{1F438}"),
+ ["\uD83D"]);
+
+// escaped(lead)
+assertEq(new RegExp("[\\uD83D\uDC38]", "u").exec("\u{1F438}"),
+ null);
+assertEq(new RegExp("[\\u{D83D}\uDC38]", "u").exec("\u{1F438}"),
+ null);
+
+// escaped(trail)
+assertEq(new RegExp("[\uD83D\\uDC38]", "u").exec("\u{1F438}"),
+ null);
+assertEq(new RegExp("[\uD83D\\u{DC38}]", "u").exec("\u{1F438}"),
+ null);
+
+// escaped(lead), no unicode flag
+assertEqArray(new RegExp("[\\uD83D\uDC38]", "").exec("\u{1F438}"),
+ ["\uD83D"]);
+
+// escaped(trail), no unicode flag
+assertEqArray(new RegExp("[\uD83D\\uDC38]", "").exec("\u{1F438}"),
+ ["\uD83D"]);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/unicode-disallow-extended.js b/js/src/tests/ecma_6/RegExp/unicode-disallow-extended.js
new file mode 100644
index 000000000..d1f775fac
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/unicode-disallow-extended.js
@@ -0,0 +1,117 @@
+var BUGNUMBER = 1135377;
+var summary = "Implement RegExp unicode flag -- disallow extended patterns.";
+
+print(BUGNUMBER + ": " + summary);
+
+// IdentityEscape
+
+assertEqArray(/\^\$\\\.\*\+\?\(\)\[\]\{\}\|/u.exec("^$\\.*+?()[]{}|"),
+ ["^$\\.*+?()[]{}|"]);
+assertThrowsInstanceOf(() => eval(`/\\A/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/\\-/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/\\U{10}/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/\\U0000/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/\\uD83D\\U0000/u`), SyntaxError);
+
+assertEqArray(/[\^\$\\\.\*\+\?\(\)\[\]\{\}\|]+/u.exec("^$\\.*+?()[]{}|"),
+ ["^$\\.*+?()[]{}|"]);
+assertThrowsInstanceOf(() => eval(`/[\\A]/u`), SyntaxError);
+assertEqArray(/[A\-Z]+/u.exec("a-zABC"),
+ ["-"]);
+assertThrowsInstanceOf(() => eval(`/[\\U{10}]/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/[\\U0000]/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/[\\uD83D\\U0000]/u`), SyntaxError);
+
+// PatternCharacter
+assertThrowsInstanceOf(() => eval(`/{}/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/{/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/}/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/]/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/{0}/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/{1,}/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/{1,2}/u`), SyntaxError);
+
+// QuantifiableAssertion
+assertEqArray(/.B(?=A)/u.exec("cBaCBA"),
+ ["CB"]);
+assertEqArray(/.B(?!A)/u.exec("CBAcBa"),
+ ["cB"]);
+assertEqArray(/.B(?:A)/u.exec("cBaCBA"),
+ ["CBA"]);
+assertEqArray(/.B(A)/u.exec("cBaCBA"),
+ ["CBA", "A"]);
+
+assertThrowsInstanceOf(() => eval(`/.B(?=A)+/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/.B(?!A)+/u`), SyntaxError);
+assertEqArray(/.B(?:A)+/u.exec("cBaCBA"),
+ ["CBA"]);
+assertEqArray(/.B(A)+/u.exec("cBaCBA"),
+ ["CBA", "A"]);
+
+// ControlLetter
+assertEqArray(/\cA/u.exec("\u0001"),
+ ["\u0001"]);
+assertEqArray(/\cZ/u.exec("\u001a"),
+ ["\u001a"]);
+assertEqArray(/\ca/u.exec("\u0001"),
+ ["\u0001"]);
+assertEqArray(/\cz/u.exec("\u001a"),
+ ["\u001a"]);
+
+assertEqArray(/[\cA]/u.exec("\u0001"),
+ ["\u0001"]);
+assertEqArray(/[\cZ]/u.exec("\u001a"),
+ ["\u001a"]);
+assertEqArray(/[\ca]/u.exec("\u0001"),
+ ["\u0001"]);
+assertEqArray(/[\cz]/u.exec("\u001a"),
+ ["\u001a"]);
+
+assertThrowsInstanceOf(() => eval(`/\\c/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/\\c1/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/\\c_/u`), SyntaxError);
+
+assertThrowsInstanceOf(() => eval(`/[\\c]/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/[\\c1]/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/[\\c_]/u`), SyntaxError);
+
+// HexEscapeSequence
+assertThrowsInstanceOf(() => eval(`/\\x/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/\\x0/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/\\x1/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/\\x1G/u`), SyntaxError);
+
+// LegacyOctalEscapeSequence
+assertThrowsInstanceOf(() => eval(`/\\52/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/\\052/u`), SyntaxError);
+
+// DecimalEscape
+assertEqArray(/\0/u.exec("\0"),
+ ["\0"]);
+assertEqArray(/[\0]/u.exec("\0"),
+ ["\0"]);
+assertEqArray(/\0A/u.exec("\0A"),
+ ["\0A"]);
+assertEqArray(/\0G/u.exec("\0G"),
+ ["\0G"]);
+assertEqArray(/(A.)\1/u.exec("ABACABAB"),
+ ["ABAB", "AB"]);
+assertEqArray(/(A.)(B.)(C.)(D.)(E.)(F.)(G.)(H.)(I.)(J.)(K.)\10/u.exec("A1B2C3D4E5F6G7H8I9JaKbJa"),
+ ["A1B2C3D4E5F6G7H8I9JaKbJa", "A1", "B2", "C3", "D4", "E5", "F6", "G7", "H8", "I9", "Ja", "Kb"]);
+
+assertThrowsInstanceOf(() => eval(`/\\00/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/\\01/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/\\09/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/\\1/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/\\2/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/\\3/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/\\4/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/\\5/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/\\6/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/\\7/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/\\8/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/\\9/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/\\10/u`), SyntaxError);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/unicode-everything.js b/js/src/tests/ecma_6/RegExp/unicode-everything.js
new file mode 100644
index 000000000..a18ac2867
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/unicode-everything.js
@@ -0,0 +1,59 @@
+var BUGNUMBER = 1135377;
+var summary = "Implement RegExp unicode flag -- everything Atom.";
+
+print(BUGNUMBER + ": " + summary);
+
+// ==== standalone ====
+
+assertEqArray(/./u.exec("ABC"),
+ ["A"]);
+assertEqArray(/./u.exec("\u{1F438}BC"),
+ ["\u{1F438}"]);
+
+assertEqArray(/./u.exec("\uD83D\uDBFF"),
+ ["\uD83D"]);
+assertEqArray(/./u.exec("\uD83D\uDC00"),
+ ["\uD83D\uDC00"]);
+assertEqArray(/./u.exec("\uD83D\uDFFF"),
+ ["\uD83D\uDFFF"]);
+assertEqArray(/./u.exec("\uD83D\uE000"),
+ ["\uD83D"]);
+assertEqArray(/./u.exec("\uD83D"),
+ ["\uD83D"]);
+assertEqArray(/./u.exec("\uD83DA"),
+ ["\uD83D"]);
+
+assertEqArray(/./u.exec("\uD7FF\uDC38"),
+ ["\uD7FF"]);
+assertEqArray(/./u.exec("\uD800\uDC38"),
+ ["\uD800\uDC38"]);
+assertEqArray(/./u.exec("\uDBFF\uDC38"),
+ ["\uDBFF\uDC38"]);
+assertEqArray(/./u.exec("\uDC00\uDC38"),
+ ["\uDC00"]);
+assertEqArray(/./u.exec("\uDC38"),
+ ["\uDC38"]);
+assertEqArray(/./u.exec("A\uDC38"),
+ ["A"]);
+
+assertEqArray(/.A/u.exec("\uD7FF\uDC38A"),
+ ["\uDC38A"]);
+assertEqArray(/.A/u.exec("\uD800\uDC38A"),
+ ["\uD800\uDC38A"]);
+assertEqArray(/.A/u.exec("\uDBFF\uDC38A"),
+ ["\uDBFF\uDC38A"]);
+assertEqArray(/.A/u.exec("\uDC00\uDC38A"),
+ ["\uDC38A"]);
+
+// ==== leading multiple ====
+
+assertEqArray(/.*A/u.exec("\u{1F438}\u{1F438}\u{1F438}A"),
+ ["\u{1F438}\u{1F438}\u{1F438}A"]);
+
+// ==== trailing multiple ====
+
+assertEqArray(/A.*/u.exec("A\u{1F438}\u{1F438}\u{1F438}"),
+ ["A\u{1F438}\u{1F438}\u{1F438}"]);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/unicode-ignoreCase-ascii.js b/js/src/tests/ecma_6/RegExp/unicode-ignoreCase-ascii.js
new file mode 100644
index 000000000..6d453290e
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/unicode-ignoreCase-ascii.js
@@ -0,0 +1,45 @@
+var BUGNUMBER = 1135377;
+var summary = "Implement RegExp unicode flag -- ignoreCase flag with non-ascii to ascii map.";
+
+print(BUGNUMBER + ": " + summary);
+
+// LATIN CAPITAL LETTER Y WITH DIAERESIS
+assertEqArray(/\u0178/iu.exec("\u00FF"),
+ ["\u00FF"]);
+assertEqArray(/\u00FF/iu.exec("\u0178"),
+ ["\u0178"]);
+
+// LATIN SMALL LETTER LONG S
+assertEqArray(/\u017F/iu.exec("S"),
+ ["S"]);
+assertEqArray(/\u017F/iu.exec("s"),
+ ["s"]);
+assertEqArray(/S/iu.exec("\u017F"),
+ ["\u017F"]);
+assertEqArray(/s/iu.exec("\u017F"),
+ ["\u017F"]);
+
+// LATIN CAPITAL LETTER SHARP S
+assertEqArray(/\u1E9E/iu.exec("\u00DF"),
+ ["\u00DF"]);
+assertEqArray(/\u00DF/iu.exec("\u1E9E"),
+ ["\u1E9E"]);
+
+// KELVIN SIGN
+assertEqArray(/\u212A/iu.exec("K"),
+ ["K"]);
+assertEqArray(/\u212A/iu.exec("k"),
+ ["k"]);
+assertEqArray(/K/iu.exec("\u212A"),
+ ["\u212A"]);
+assertEqArray(/k/iu.exec("\u212A"),
+ ["\u212A"]);
+
+// ANGSTROM SIGN
+assertEqArray(/\u212B/iu.exec("\u00E5"),
+ ["\u00E5"]);
+assertEqArray(/\u00E5/iu.exec("\u212B"),
+ ["\u212B"]);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/unicode-ignoreCase-escape.js b/js/src/tests/ecma_6/RegExp/unicode-ignoreCase-escape.js
new file mode 100644
index 000000000..d731fb6bb
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/unicode-ignoreCase-escape.js
@@ -0,0 +1,71 @@
+var BUGNUMBER = 1135377;
+var summary = "Implement RegExp unicode flag -- ignoreCase flag with character class escape.";
+
+// \W doesn't match S or K from the change in
+// https://github.com/tc39/ecma262/pull/525
+// (bug 1281739)
+
+print(BUGNUMBER + ": " + summary);
+
+// LATIN SMALL LETTER LONG S
+
+assertEqArray(/\w/iu.exec("S"),
+ ["S"]);
+assertEqArray(/\w/iu.exec("s"),
+ ["s"]);
+assertEqArray(/\w/iu.exec("\u017F"),
+ ["\u017F"]);
+
+assertEqArray(/[^\W]/iu.exec("S"),
+ ["S"]);
+assertEqArray(/[^\W]/iu.exec("s"),
+ ["s"]);
+assertEqArray(/[^\W]/iu.exec("\u017F"),
+ ["\u017F"]);
+
+assertEq(/\W/iu.exec("S"),
+ null);
+assertEq(/\W/iu.exec("s"),
+ null);
+assertEq(/\W/iu.exec("\u017F"),
+ null);
+
+assertEq(/[^\w]/iu.exec("S"),
+ null);
+assertEq(/[^\w]/iu.exec("s"),
+ null);
+assertEq(/[^\w]/iu.exec("\u017F"),
+ null);
+
+// KELVIN SIGN
+
+assertEqArray(/\w/iu.exec("k"),
+ ["k"]);
+assertEqArray(/\w/iu.exec("k"),
+ ["k"]);
+assertEqArray(/\w/iu.exec("\u212A"),
+ ["\u212A"]);
+
+assertEqArray(/[^\W]/iu.exec("k"),
+ ["k"]);
+assertEqArray(/[^\W]/iu.exec("k"),
+ ["k"]);
+assertEqArray(/[^\W]/iu.exec("\u212A"),
+ ["\u212A"]);
+
+assertEq(/\W/iu.exec("k"),
+ null);
+assertEq(/\W/iu.exec("k"),
+ null);
+assertEq(/\W/iu.exec("\u212A"),
+ null);
+
+assertEq(/[^\w]/iu.exec("k"),
+ null);
+assertEq(/[^\w]/iu.exec("k"),
+ null);
+assertEq(/[^\w]/iu.exec("\u212A"),
+ null);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/unicode-ignoreCase-negated.js b/js/src/tests/ecma_6/RegExp/unicode-ignoreCase-negated.js
new file mode 100644
index 000000000..30909a515
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/unicode-ignoreCase-negated.js
@@ -0,0 +1,19 @@
+var BUGNUMBER = 1135377;
+var summary = "Implement RegExp unicode flag -- ignoreCase flag with negated character class.";
+
+print(BUGNUMBER + ": " + summary);
+
+assertEq(/[^A]/iu.exec("A"),
+ null);
+assertEq(/[^a]/iu.exec("A"),
+ null);
+assertEq(/[^A]/iu.exec("a"),
+ null);
+assertEq(/[^a]/iu.exec("a"),
+ null);
+
+assertEqArray(/[^A]/iu.exec("b"),
+ ["b"]);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/unicode-ignoreCase.js b/js/src/tests/ecma_6/RegExp/unicode-ignoreCase.js
new file mode 100644
index 000000000..28b2e77dc
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/unicode-ignoreCase.js
@@ -0,0 +1,2643 @@
+/* Generated by make_unicode.py DO NOT MODIFY */
+/* Unicode version: 9.0.0 */
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var BUGNUMBER = 1135377;
+var summary = "Implement RegExp unicode flag -- ignoreCase flag.";
+
+print(BUGNUMBER + ": " + summary);
+
+function test(code, ...equivs) {
+ var codeRe = new RegExp(String.fromCodePoint(code) + "+", "iu");
+ var ans = String.fromCodePoint(code) + equivs.map(c => String.fromCodePoint(c)).join("");
+ assertEqArray(codeRe.exec("<" + ans + ">"), [ans]);
+ codeRe = new RegExp("[" + String.fromCodePoint(code) + "]+", "iu");
+ assertEqArray(codeRe.exec("<" + ans + ">"), [ans]);
+}
+test(0x41,0x61);
+test(0x42,0x62);
+test(0x43,0x63);
+test(0x44,0x64);
+test(0x45,0x65);
+test(0x46,0x66);
+test(0x47,0x67);
+test(0x48,0x68);
+test(0x49,0x69);
+test(0x4a,0x6a);
+test(0x4b,0x6b,0x212a);
+test(0x4c,0x6c);
+test(0x4d,0x6d);
+test(0x4e,0x6e);
+test(0x4f,0x6f);
+test(0x50,0x70);
+test(0x51,0x71);
+test(0x52,0x72);
+test(0x53,0x73,0x17f);
+test(0x54,0x74);
+test(0x55,0x75);
+test(0x56,0x76);
+test(0x57,0x77);
+test(0x58,0x78);
+test(0x59,0x79);
+test(0x5a,0x7a);
+test(0x61,0x41);
+test(0x62,0x42);
+test(0x63,0x43);
+test(0x64,0x44);
+test(0x65,0x45);
+test(0x66,0x46);
+test(0x67,0x47);
+test(0x68,0x48);
+test(0x69,0x49);
+test(0x6a,0x4a);
+test(0x6b,0x4b,0x212a);
+test(0x6c,0x4c);
+test(0x6d,0x4d);
+test(0x6e,0x4e);
+test(0x6f,0x4f);
+test(0x70,0x50);
+test(0x71,0x51);
+test(0x72,0x52);
+test(0x73,0x53,0x17f);
+test(0x74,0x54);
+test(0x75,0x55);
+test(0x76,0x56);
+test(0x77,0x57);
+test(0x78,0x58);
+test(0x79,0x59);
+test(0x7a,0x5a);
+test(0xb5,0x3bc,0x39c);
+test(0xc0,0xe0);
+test(0xc1,0xe1);
+test(0xc2,0xe2);
+test(0xc3,0xe3);
+test(0xc4,0xe4);
+test(0xc5,0xe5,0x212b);
+test(0xc6,0xe6);
+test(0xc7,0xe7);
+test(0xc8,0xe8);
+test(0xc9,0xe9);
+test(0xca,0xea);
+test(0xcb,0xeb);
+test(0xcc,0xec);
+test(0xcd,0xed);
+test(0xce,0xee);
+test(0xcf,0xef);
+test(0xd0,0xf0);
+test(0xd1,0xf1);
+test(0xd2,0xf2);
+test(0xd3,0xf3);
+test(0xd4,0xf4);
+test(0xd5,0xf5);
+test(0xd6,0xf6);
+test(0xd8,0xf8);
+test(0xd9,0xf9);
+test(0xda,0xfa);
+test(0xdb,0xfb);
+test(0xdc,0xfc);
+test(0xdd,0xfd);
+test(0xde,0xfe);
+test(0xdf,0x1e9e);
+test(0xe0,0xc0);
+test(0xe1,0xc1);
+test(0xe2,0xc2);
+test(0xe3,0xc3);
+test(0xe4,0xc4);
+test(0xe5,0xc5,0x212b);
+test(0xe6,0xc6);
+test(0xe7,0xc7);
+test(0xe8,0xc8);
+test(0xe9,0xc9);
+test(0xea,0xca);
+test(0xeb,0xcb);
+test(0xec,0xcc);
+test(0xed,0xcd);
+test(0xee,0xce);
+test(0xef,0xcf);
+test(0xf0,0xd0);
+test(0xf1,0xd1);
+test(0xf2,0xd2);
+test(0xf3,0xd3);
+test(0xf4,0xd4);
+test(0xf5,0xd5);
+test(0xf6,0xd6);
+test(0xf8,0xd8);
+test(0xf9,0xd9);
+test(0xfa,0xda);
+test(0xfb,0xdb);
+test(0xfc,0xdc);
+test(0xfd,0xdd);
+test(0xfe,0xde);
+test(0xff,0x178);
+test(0x100,0x101);
+test(0x101,0x100);
+test(0x102,0x103);
+test(0x103,0x102);
+test(0x104,0x105);
+test(0x105,0x104);
+test(0x106,0x107);
+test(0x107,0x106);
+test(0x108,0x109);
+test(0x109,0x108);
+test(0x10a,0x10b);
+test(0x10b,0x10a);
+test(0x10c,0x10d);
+test(0x10d,0x10c);
+test(0x10e,0x10f);
+test(0x10f,0x10e);
+test(0x110,0x111);
+test(0x111,0x110);
+test(0x112,0x113);
+test(0x113,0x112);
+test(0x114,0x115);
+test(0x115,0x114);
+test(0x116,0x117);
+test(0x117,0x116);
+test(0x118,0x119);
+test(0x119,0x118);
+test(0x11a,0x11b);
+test(0x11b,0x11a);
+test(0x11c,0x11d);
+test(0x11d,0x11c);
+test(0x11e,0x11f);
+test(0x11f,0x11e);
+test(0x120,0x121);
+test(0x121,0x120);
+test(0x122,0x123);
+test(0x123,0x122);
+test(0x124,0x125);
+test(0x125,0x124);
+test(0x126,0x127);
+test(0x127,0x126);
+test(0x128,0x129);
+test(0x129,0x128);
+test(0x12a,0x12b);
+test(0x12b,0x12a);
+test(0x12c,0x12d);
+test(0x12d,0x12c);
+test(0x12e,0x12f);
+test(0x12f,0x12e);
+test(0x132,0x133);
+test(0x133,0x132);
+test(0x134,0x135);
+test(0x135,0x134);
+test(0x136,0x137);
+test(0x137,0x136);
+test(0x139,0x13a);
+test(0x13a,0x139);
+test(0x13b,0x13c);
+test(0x13c,0x13b);
+test(0x13d,0x13e);
+test(0x13e,0x13d);
+test(0x13f,0x140);
+test(0x140,0x13f);
+test(0x141,0x142);
+test(0x142,0x141);
+test(0x143,0x144);
+test(0x144,0x143);
+test(0x145,0x146);
+test(0x146,0x145);
+test(0x147,0x148);
+test(0x148,0x147);
+test(0x14a,0x14b);
+test(0x14b,0x14a);
+test(0x14c,0x14d);
+test(0x14d,0x14c);
+test(0x14e,0x14f);
+test(0x14f,0x14e);
+test(0x150,0x151);
+test(0x151,0x150);
+test(0x152,0x153);
+test(0x153,0x152);
+test(0x154,0x155);
+test(0x155,0x154);
+test(0x156,0x157);
+test(0x157,0x156);
+test(0x158,0x159);
+test(0x159,0x158);
+test(0x15a,0x15b);
+test(0x15b,0x15a);
+test(0x15c,0x15d);
+test(0x15d,0x15c);
+test(0x15e,0x15f);
+test(0x15f,0x15e);
+test(0x160,0x161);
+test(0x161,0x160);
+test(0x162,0x163);
+test(0x163,0x162);
+test(0x164,0x165);
+test(0x165,0x164);
+test(0x166,0x167);
+test(0x167,0x166);
+test(0x168,0x169);
+test(0x169,0x168);
+test(0x16a,0x16b);
+test(0x16b,0x16a);
+test(0x16c,0x16d);
+test(0x16d,0x16c);
+test(0x16e,0x16f);
+test(0x16f,0x16e);
+test(0x170,0x171);
+test(0x171,0x170);
+test(0x172,0x173);
+test(0x173,0x172);
+test(0x174,0x175);
+test(0x175,0x174);
+test(0x176,0x177);
+test(0x177,0x176);
+test(0x178,0xff);
+test(0x179,0x17a);
+test(0x17a,0x179);
+test(0x17b,0x17c);
+test(0x17c,0x17b);
+test(0x17d,0x17e);
+test(0x17e,0x17d);
+test(0x17f,0x73,0x53);
+test(0x180,0x243);
+test(0x181,0x253);
+test(0x182,0x183);
+test(0x183,0x182);
+test(0x184,0x185);
+test(0x185,0x184);
+test(0x186,0x254);
+test(0x187,0x188);
+test(0x188,0x187);
+test(0x189,0x256);
+test(0x18a,0x257);
+test(0x18b,0x18c);
+test(0x18c,0x18b);
+test(0x18e,0x1dd);
+test(0x18f,0x259);
+test(0x190,0x25b);
+test(0x191,0x192);
+test(0x192,0x191);
+test(0x193,0x260);
+test(0x194,0x263);
+test(0x195,0x1f6);
+test(0x196,0x269);
+test(0x197,0x268);
+test(0x198,0x199);
+test(0x199,0x198);
+test(0x19a,0x23d);
+test(0x19c,0x26f);
+test(0x19d,0x272);
+test(0x19e,0x220);
+test(0x19f,0x275);
+test(0x1a0,0x1a1);
+test(0x1a1,0x1a0);
+test(0x1a2,0x1a3);
+test(0x1a3,0x1a2);
+test(0x1a4,0x1a5);
+test(0x1a5,0x1a4);
+test(0x1a6,0x280);
+test(0x1a7,0x1a8);
+test(0x1a8,0x1a7);
+test(0x1a9,0x283);
+test(0x1ac,0x1ad);
+test(0x1ad,0x1ac);
+test(0x1ae,0x288);
+test(0x1af,0x1b0);
+test(0x1b0,0x1af);
+test(0x1b1,0x28a);
+test(0x1b2,0x28b);
+test(0x1b3,0x1b4);
+test(0x1b4,0x1b3);
+test(0x1b5,0x1b6);
+test(0x1b6,0x1b5);
+test(0x1b7,0x292);
+test(0x1b8,0x1b9);
+test(0x1b9,0x1b8);
+test(0x1bc,0x1bd);
+test(0x1bd,0x1bc);
+test(0x1bf,0x1f7);
+test(0x1c4,0x1c6,0x1c5);
+test(0x1c5,0x1c6,0x1c4);
+test(0x1c6,0x1c4,0x1c5);
+test(0x1c7,0x1c9,0x1c8);
+test(0x1c8,0x1c9,0x1c7);
+test(0x1c9,0x1c7,0x1c8);
+test(0x1ca,0x1cc,0x1cb);
+test(0x1cb,0x1cc,0x1ca);
+test(0x1cc,0x1ca,0x1cb);
+test(0x1cd,0x1ce);
+test(0x1ce,0x1cd);
+test(0x1cf,0x1d0);
+test(0x1d0,0x1cf);
+test(0x1d1,0x1d2);
+test(0x1d2,0x1d1);
+test(0x1d3,0x1d4);
+test(0x1d4,0x1d3);
+test(0x1d5,0x1d6);
+test(0x1d6,0x1d5);
+test(0x1d7,0x1d8);
+test(0x1d8,0x1d7);
+test(0x1d9,0x1da);
+test(0x1da,0x1d9);
+test(0x1db,0x1dc);
+test(0x1dc,0x1db);
+test(0x1dd,0x18e);
+test(0x1de,0x1df);
+test(0x1df,0x1de);
+test(0x1e0,0x1e1);
+test(0x1e1,0x1e0);
+test(0x1e2,0x1e3);
+test(0x1e3,0x1e2);
+test(0x1e4,0x1e5);
+test(0x1e5,0x1e4);
+test(0x1e6,0x1e7);
+test(0x1e7,0x1e6);
+test(0x1e8,0x1e9);
+test(0x1e9,0x1e8);
+test(0x1ea,0x1eb);
+test(0x1eb,0x1ea);
+test(0x1ec,0x1ed);
+test(0x1ed,0x1ec);
+test(0x1ee,0x1ef);
+test(0x1ef,0x1ee);
+test(0x1f1,0x1f3,0x1f2);
+test(0x1f2,0x1f3,0x1f1);
+test(0x1f3,0x1f1,0x1f2);
+test(0x1f4,0x1f5);
+test(0x1f5,0x1f4);
+test(0x1f6,0x195);
+test(0x1f7,0x1bf);
+test(0x1f8,0x1f9);
+test(0x1f9,0x1f8);
+test(0x1fa,0x1fb);
+test(0x1fb,0x1fa);
+test(0x1fc,0x1fd);
+test(0x1fd,0x1fc);
+test(0x1fe,0x1ff);
+test(0x1ff,0x1fe);
+test(0x200,0x201);
+test(0x201,0x200);
+test(0x202,0x203);
+test(0x203,0x202);
+test(0x204,0x205);
+test(0x205,0x204);
+test(0x206,0x207);
+test(0x207,0x206);
+test(0x208,0x209);
+test(0x209,0x208);
+test(0x20a,0x20b);
+test(0x20b,0x20a);
+test(0x20c,0x20d);
+test(0x20d,0x20c);
+test(0x20e,0x20f);
+test(0x20f,0x20e);
+test(0x210,0x211);
+test(0x211,0x210);
+test(0x212,0x213);
+test(0x213,0x212);
+test(0x214,0x215);
+test(0x215,0x214);
+test(0x216,0x217);
+test(0x217,0x216);
+test(0x218,0x219);
+test(0x219,0x218);
+test(0x21a,0x21b);
+test(0x21b,0x21a);
+test(0x21c,0x21d);
+test(0x21d,0x21c);
+test(0x21e,0x21f);
+test(0x21f,0x21e);
+test(0x220,0x19e);
+test(0x222,0x223);
+test(0x223,0x222);
+test(0x224,0x225);
+test(0x225,0x224);
+test(0x226,0x227);
+test(0x227,0x226);
+test(0x228,0x229);
+test(0x229,0x228);
+test(0x22a,0x22b);
+test(0x22b,0x22a);
+test(0x22c,0x22d);
+test(0x22d,0x22c);
+test(0x22e,0x22f);
+test(0x22f,0x22e);
+test(0x230,0x231);
+test(0x231,0x230);
+test(0x232,0x233);
+test(0x233,0x232);
+test(0x23a,0x2c65);
+test(0x23b,0x23c);
+test(0x23c,0x23b);
+test(0x23d,0x19a);
+test(0x23e,0x2c66);
+test(0x23f,0x2c7e);
+test(0x240,0x2c7f);
+test(0x241,0x242);
+test(0x242,0x241);
+test(0x243,0x180);
+test(0x244,0x289);
+test(0x245,0x28c);
+test(0x246,0x247);
+test(0x247,0x246);
+test(0x248,0x249);
+test(0x249,0x248);
+test(0x24a,0x24b);
+test(0x24b,0x24a);
+test(0x24c,0x24d);
+test(0x24d,0x24c);
+test(0x24e,0x24f);
+test(0x24f,0x24e);
+test(0x250,0x2c6f);
+test(0x251,0x2c6d);
+test(0x252,0x2c70);
+test(0x253,0x181);
+test(0x254,0x186);
+test(0x256,0x189);
+test(0x257,0x18a);
+test(0x259,0x18f);
+test(0x25b,0x190);
+test(0x25c,0xa7ab);
+test(0x260,0x193);
+test(0x261,0xa7ac);
+test(0x263,0x194);
+test(0x265,0xa78d);
+test(0x266,0xa7aa);
+test(0x268,0x197);
+test(0x269,0x196);
+test(0x26a,0xa7ae);
+test(0x26b,0x2c62);
+test(0x26c,0xa7ad);
+test(0x26f,0x19c);
+test(0x271,0x2c6e);
+test(0x272,0x19d);
+test(0x275,0x19f);
+test(0x27d,0x2c64);
+test(0x280,0x1a6);
+test(0x283,0x1a9);
+test(0x287,0xa7b1);
+test(0x288,0x1ae);
+test(0x289,0x244);
+test(0x28a,0x1b1);
+test(0x28b,0x1b2);
+test(0x28c,0x245);
+test(0x292,0x1b7);
+test(0x29d,0xa7b2);
+test(0x29e,0xa7b0);
+test(0x345,0x3b9,0x399,0x1fbe);
+test(0x370,0x371);
+test(0x371,0x370);
+test(0x372,0x373);
+test(0x373,0x372);
+test(0x376,0x377);
+test(0x377,0x376);
+test(0x37b,0x3fd);
+test(0x37c,0x3fe);
+test(0x37d,0x3ff);
+test(0x37f,0x3f3);
+test(0x386,0x3ac);
+test(0x388,0x3ad);
+test(0x389,0x3ae);
+test(0x38a,0x3af);
+test(0x38c,0x3cc);
+test(0x38e,0x3cd);
+test(0x38f,0x3ce);
+test(0x391,0x3b1);
+test(0x392,0x3b2,0x3d0);
+test(0x393,0x3b3);
+test(0x394,0x3b4);
+test(0x395,0x3b5,0x3f5);
+test(0x396,0x3b6);
+test(0x397,0x3b7);
+test(0x398,0x3b8,0x3d1,0x3f4);
+test(0x399,0x3b9,0x345,0x1fbe);
+test(0x39a,0x3ba,0x3f0);
+test(0x39b,0x3bb);
+test(0x39c,0x3bc,0xb5);
+test(0x39d,0x3bd);
+test(0x39e,0x3be);
+test(0x39f,0x3bf);
+test(0x3a0,0x3c0,0x3d6);
+test(0x3a1,0x3c1,0x3f1);
+test(0x3a3,0x3c3,0x3c2);
+test(0x3a4,0x3c4);
+test(0x3a5,0x3c5);
+test(0x3a6,0x3c6,0x3d5);
+test(0x3a7,0x3c7);
+test(0x3a8,0x3c8);
+test(0x3a9,0x3c9,0x2126);
+test(0x3aa,0x3ca);
+test(0x3ab,0x3cb);
+test(0x3ac,0x386);
+test(0x3ad,0x388);
+test(0x3ae,0x389);
+test(0x3af,0x38a);
+test(0x3b1,0x391);
+test(0x3b2,0x392,0x3d0);
+test(0x3b3,0x393);
+test(0x3b4,0x394);
+test(0x3b5,0x395,0x3f5);
+test(0x3b6,0x396);
+test(0x3b7,0x397);
+test(0x3b8,0x398,0x3d1,0x3f4);
+test(0x3b9,0x345,0x399,0x1fbe);
+test(0x3ba,0x39a,0x3f0);
+test(0x3bb,0x39b);
+test(0x3bc,0xb5,0x39c);
+test(0x3bd,0x39d);
+test(0x3be,0x39e);
+test(0x3bf,0x39f);
+test(0x3c0,0x3a0,0x3d6);
+test(0x3c1,0x3a1,0x3f1);
+test(0x3c2,0x3c3,0x3a3);
+test(0x3c3,0x3a3,0x3c2);
+test(0x3c4,0x3a4);
+test(0x3c5,0x3a5);
+test(0x3c6,0x3a6,0x3d5);
+test(0x3c7,0x3a7);
+test(0x3c8,0x3a8);
+test(0x3c9,0x3a9,0x2126);
+test(0x3ca,0x3aa);
+test(0x3cb,0x3ab);
+test(0x3cc,0x38c);
+test(0x3cd,0x38e);
+test(0x3ce,0x38f);
+test(0x3cf,0x3d7);
+test(0x3d0,0x3b2,0x392);
+test(0x3d1,0x3b8,0x398,0x3f4);
+test(0x3d5,0x3c6,0x3a6);
+test(0x3d6,0x3c0,0x3a0);
+test(0x3d7,0x3cf);
+test(0x3d8,0x3d9);
+test(0x3d9,0x3d8);
+test(0x3da,0x3db);
+test(0x3db,0x3da);
+test(0x3dc,0x3dd);
+test(0x3dd,0x3dc);
+test(0x3de,0x3df);
+test(0x3df,0x3de);
+test(0x3e0,0x3e1);
+test(0x3e1,0x3e0);
+test(0x3e2,0x3e3);
+test(0x3e3,0x3e2);
+test(0x3e4,0x3e5);
+test(0x3e5,0x3e4);
+test(0x3e6,0x3e7);
+test(0x3e7,0x3e6);
+test(0x3e8,0x3e9);
+test(0x3e9,0x3e8);
+test(0x3ea,0x3eb);
+test(0x3eb,0x3ea);
+test(0x3ec,0x3ed);
+test(0x3ed,0x3ec);
+test(0x3ee,0x3ef);
+test(0x3ef,0x3ee);
+test(0x3f0,0x3ba,0x39a);
+test(0x3f1,0x3c1,0x3a1);
+test(0x3f2,0x3f9);
+test(0x3f3,0x37f);
+test(0x3f4,0x3b8,0x398,0x3d1);
+test(0x3f5,0x3b5,0x395);
+test(0x3f7,0x3f8);
+test(0x3f8,0x3f7);
+test(0x3f9,0x3f2);
+test(0x3fa,0x3fb);
+test(0x3fb,0x3fa);
+test(0x3fd,0x37b);
+test(0x3fe,0x37c);
+test(0x3ff,0x37d);
+test(0x400,0x450);
+test(0x401,0x451);
+test(0x402,0x452);
+test(0x403,0x453);
+test(0x404,0x454);
+test(0x405,0x455);
+test(0x406,0x456);
+test(0x407,0x457);
+test(0x408,0x458);
+test(0x409,0x459);
+test(0x40a,0x45a);
+test(0x40b,0x45b);
+test(0x40c,0x45c);
+test(0x40d,0x45d);
+test(0x40e,0x45e);
+test(0x40f,0x45f);
+test(0x410,0x430);
+test(0x411,0x431);
+test(0x412,0x432,0x1c80);
+test(0x413,0x433);
+test(0x414,0x434,0x1c81);
+test(0x415,0x435);
+test(0x416,0x436);
+test(0x417,0x437);
+test(0x418,0x438);
+test(0x419,0x439);
+test(0x41a,0x43a);
+test(0x41b,0x43b);
+test(0x41c,0x43c);
+test(0x41d,0x43d);
+test(0x41e,0x43e,0x1c82);
+test(0x41f,0x43f);
+test(0x420,0x440);
+test(0x421,0x441,0x1c83);
+test(0x422,0x442,0x1c84,0x1c85);
+test(0x423,0x443);
+test(0x424,0x444);
+test(0x425,0x445);
+test(0x426,0x446);
+test(0x427,0x447);
+test(0x428,0x448);
+test(0x429,0x449);
+test(0x42a,0x44a,0x1c86);
+test(0x42b,0x44b);
+test(0x42c,0x44c);
+test(0x42d,0x44d);
+test(0x42e,0x44e);
+test(0x42f,0x44f);
+test(0x430,0x410);
+test(0x431,0x411);
+test(0x432,0x412,0x1c80);
+test(0x433,0x413);
+test(0x434,0x414,0x1c81);
+test(0x435,0x415);
+test(0x436,0x416);
+test(0x437,0x417);
+test(0x438,0x418);
+test(0x439,0x419);
+test(0x43a,0x41a);
+test(0x43b,0x41b);
+test(0x43c,0x41c);
+test(0x43d,0x41d);
+test(0x43e,0x41e,0x1c82);
+test(0x43f,0x41f);
+test(0x440,0x420);
+test(0x441,0x421,0x1c83);
+test(0x442,0x422,0x1c84,0x1c85);
+test(0x443,0x423);
+test(0x444,0x424);
+test(0x445,0x425);
+test(0x446,0x426);
+test(0x447,0x427);
+test(0x448,0x428);
+test(0x449,0x429);
+test(0x44a,0x42a,0x1c86);
+test(0x44b,0x42b);
+test(0x44c,0x42c);
+test(0x44d,0x42d);
+test(0x44e,0x42e);
+test(0x44f,0x42f);
+test(0x450,0x400);
+test(0x451,0x401);
+test(0x452,0x402);
+test(0x453,0x403);
+test(0x454,0x404);
+test(0x455,0x405);
+test(0x456,0x406);
+test(0x457,0x407);
+test(0x458,0x408);
+test(0x459,0x409);
+test(0x45a,0x40a);
+test(0x45b,0x40b);
+test(0x45c,0x40c);
+test(0x45d,0x40d);
+test(0x45e,0x40e);
+test(0x45f,0x40f);
+test(0x460,0x461);
+test(0x461,0x460);
+test(0x462,0x463,0x1c87);
+test(0x463,0x462,0x1c87);
+test(0x464,0x465);
+test(0x465,0x464);
+test(0x466,0x467);
+test(0x467,0x466);
+test(0x468,0x469);
+test(0x469,0x468);
+test(0x46a,0x46b);
+test(0x46b,0x46a);
+test(0x46c,0x46d);
+test(0x46d,0x46c);
+test(0x46e,0x46f);
+test(0x46f,0x46e);
+test(0x470,0x471);
+test(0x471,0x470);
+test(0x472,0x473);
+test(0x473,0x472);
+test(0x474,0x475);
+test(0x475,0x474);
+test(0x476,0x477);
+test(0x477,0x476);
+test(0x478,0x479);
+test(0x479,0x478);
+test(0x47a,0x47b);
+test(0x47b,0x47a);
+test(0x47c,0x47d);
+test(0x47d,0x47c);
+test(0x47e,0x47f);
+test(0x47f,0x47e);
+test(0x480,0x481);
+test(0x481,0x480);
+test(0x48a,0x48b);
+test(0x48b,0x48a);
+test(0x48c,0x48d);
+test(0x48d,0x48c);
+test(0x48e,0x48f);
+test(0x48f,0x48e);
+test(0x490,0x491);
+test(0x491,0x490);
+test(0x492,0x493);
+test(0x493,0x492);
+test(0x494,0x495);
+test(0x495,0x494);
+test(0x496,0x497);
+test(0x497,0x496);
+test(0x498,0x499);
+test(0x499,0x498);
+test(0x49a,0x49b);
+test(0x49b,0x49a);
+test(0x49c,0x49d);
+test(0x49d,0x49c);
+test(0x49e,0x49f);
+test(0x49f,0x49e);
+test(0x4a0,0x4a1);
+test(0x4a1,0x4a0);
+test(0x4a2,0x4a3);
+test(0x4a3,0x4a2);
+test(0x4a4,0x4a5);
+test(0x4a5,0x4a4);
+test(0x4a6,0x4a7);
+test(0x4a7,0x4a6);
+test(0x4a8,0x4a9);
+test(0x4a9,0x4a8);
+test(0x4aa,0x4ab);
+test(0x4ab,0x4aa);
+test(0x4ac,0x4ad);
+test(0x4ad,0x4ac);
+test(0x4ae,0x4af);
+test(0x4af,0x4ae);
+test(0x4b0,0x4b1);
+test(0x4b1,0x4b0);
+test(0x4b2,0x4b3);
+test(0x4b3,0x4b2);
+test(0x4b4,0x4b5);
+test(0x4b5,0x4b4);
+test(0x4b6,0x4b7);
+test(0x4b7,0x4b6);
+test(0x4b8,0x4b9);
+test(0x4b9,0x4b8);
+test(0x4ba,0x4bb);
+test(0x4bb,0x4ba);
+test(0x4bc,0x4bd);
+test(0x4bd,0x4bc);
+test(0x4be,0x4bf);
+test(0x4bf,0x4be);
+test(0x4c0,0x4cf);
+test(0x4c1,0x4c2);
+test(0x4c2,0x4c1);
+test(0x4c3,0x4c4);
+test(0x4c4,0x4c3);
+test(0x4c5,0x4c6);
+test(0x4c6,0x4c5);
+test(0x4c7,0x4c8);
+test(0x4c8,0x4c7);
+test(0x4c9,0x4ca);
+test(0x4ca,0x4c9);
+test(0x4cb,0x4cc);
+test(0x4cc,0x4cb);
+test(0x4cd,0x4ce);
+test(0x4ce,0x4cd);
+test(0x4cf,0x4c0);
+test(0x4d0,0x4d1);
+test(0x4d1,0x4d0);
+test(0x4d2,0x4d3);
+test(0x4d3,0x4d2);
+test(0x4d4,0x4d5);
+test(0x4d5,0x4d4);
+test(0x4d6,0x4d7);
+test(0x4d7,0x4d6);
+test(0x4d8,0x4d9);
+test(0x4d9,0x4d8);
+test(0x4da,0x4db);
+test(0x4db,0x4da);
+test(0x4dc,0x4dd);
+test(0x4dd,0x4dc);
+test(0x4de,0x4df);
+test(0x4df,0x4de);
+test(0x4e0,0x4e1);
+test(0x4e1,0x4e0);
+test(0x4e2,0x4e3);
+test(0x4e3,0x4e2);
+test(0x4e4,0x4e5);
+test(0x4e5,0x4e4);
+test(0x4e6,0x4e7);
+test(0x4e7,0x4e6);
+test(0x4e8,0x4e9);
+test(0x4e9,0x4e8);
+test(0x4ea,0x4eb);
+test(0x4eb,0x4ea);
+test(0x4ec,0x4ed);
+test(0x4ed,0x4ec);
+test(0x4ee,0x4ef);
+test(0x4ef,0x4ee);
+test(0x4f0,0x4f1);
+test(0x4f1,0x4f0);
+test(0x4f2,0x4f3);
+test(0x4f3,0x4f2);
+test(0x4f4,0x4f5);
+test(0x4f5,0x4f4);
+test(0x4f6,0x4f7);
+test(0x4f7,0x4f6);
+test(0x4f8,0x4f9);
+test(0x4f9,0x4f8);
+test(0x4fa,0x4fb);
+test(0x4fb,0x4fa);
+test(0x4fc,0x4fd);
+test(0x4fd,0x4fc);
+test(0x4fe,0x4ff);
+test(0x4ff,0x4fe);
+test(0x500,0x501);
+test(0x501,0x500);
+test(0x502,0x503);
+test(0x503,0x502);
+test(0x504,0x505);
+test(0x505,0x504);
+test(0x506,0x507);
+test(0x507,0x506);
+test(0x508,0x509);
+test(0x509,0x508);
+test(0x50a,0x50b);
+test(0x50b,0x50a);
+test(0x50c,0x50d);
+test(0x50d,0x50c);
+test(0x50e,0x50f);
+test(0x50f,0x50e);
+test(0x510,0x511);
+test(0x511,0x510);
+test(0x512,0x513);
+test(0x513,0x512);
+test(0x514,0x515);
+test(0x515,0x514);
+test(0x516,0x517);
+test(0x517,0x516);
+test(0x518,0x519);
+test(0x519,0x518);
+test(0x51a,0x51b);
+test(0x51b,0x51a);
+test(0x51c,0x51d);
+test(0x51d,0x51c);
+test(0x51e,0x51f);
+test(0x51f,0x51e);
+test(0x520,0x521);
+test(0x521,0x520);
+test(0x522,0x523);
+test(0x523,0x522);
+test(0x524,0x525);
+test(0x525,0x524);
+test(0x526,0x527);
+test(0x527,0x526);
+test(0x528,0x529);
+test(0x529,0x528);
+test(0x52a,0x52b);
+test(0x52b,0x52a);
+test(0x52c,0x52d);
+test(0x52d,0x52c);
+test(0x52e,0x52f);
+test(0x52f,0x52e);
+test(0x531,0x561);
+test(0x532,0x562);
+test(0x533,0x563);
+test(0x534,0x564);
+test(0x535,0x565);
+test(0x536,0x566);
+test(0x537,0x567);
+test(0x538,0x568);
+test(0x539,0x569);
+test(0x53a,0x56a);
+test(0x53b,0x56b);
+test(0x53c,0x56c);
+test(0x53d,0x56d);
+test(0x53e,0x56e);
+test(0x53f,0x56f);
+test(0x540,0x570);
+test(0x541,0x571);
+test(0x542,0x572);
+test(0x543,0x573);
+test(0x544,0x574);
+test(0x545,0x575);
+test(0x546,0x576);
+test(0x547,0x577);
+test(0x548,0x578);
+test(0x549,0x579);
+test(0x54a,0x57a);
+test(0x54b,0x57b);
+test(0x54c,0x57c);
+test(0x54d,0x57d);
+test(0x54e,0x57e);
+test(0x54f,0x57f);
+test(0x550,0x580);
+test(0x551,0x581);
+test(0x552,0x582);
+test(0x553,0x583);
+test(0x554,0x584);
+test(0x555,0x585);
+test(0x556,0x586);
+test(0x561,0x531);
+test(0x562,0x532);
+test(0x563,0x533);
+test(0x564,0x534);
+test(0x565,0x535);
+test(0x566,0x536);
+test(0x567,0x537);
+test(0x568,0x538);
+test(0x569,0x539);
+test(0x56a,0x53a);
+test(0x56b,0x53b);
+test(0x56c,0x53c);
+test(0x56d,0x53d);
+test(0x56e,0x53e);
+test(0x56f,0x53f);
+test(0x570,0x540);
+test(0x571,0x541);
+test(0x572,0x542);
+test(0x573,0x543);
+test(0x574,0x544);
+test(0x575,0x545);
+test(0x576,0x546);
+test(0x577,0x547);
+test(0x578,0x548);
+test(0x579,0x549);
+test(0x57a,0x54a);
+test(0x57b,0x54b);
+test(0x57c,0x54c);
+test(0x57d,0x54d);
+test(0x57e,0x54e);
+test(0x57f,0x54f);
+test(0x580,0x550);
+test(0x581,0x551);
+test(0x582,0x552);
+test(0x583,0x553);
+test(0x584,0x554);
+test(0x585,0x555);
+test(0x586,0x556);
+test(0x10a0,0x2d00);
+test(0x10a1,0x2d01);
+test(0x10a2,0x2d02);
+test(0x10a3,0x2d03);
+test(0x10a4,0x2d04);
+test(0x10a5,0x2d05);
+test(0x10a6,0x2d06);
+test(0x10a7,0x2d07);
+test(0x10a8,0x2d08);
+test(0x10a9,0x2d09);
+test(0x10aa,0x2d0a);
+test(0x10ab,0x2d0b);
+test(0x10ac,0x2d0c);
+test(0x10ad,0x2d0d);
+test(0x10ae,0x2d0e);
+test(0x10af,0x2d0f);
+test(0x10b0,0x2d10);
+test(0x10b1,0x2d11);
+test(0x10b2,0x2d12);
+test(0x10b3,0x2d13);
+test(0x10b4,0x2d14);
+test(0x10b5,0x2d15);
+test(0x10b6,0x2d16);
+test(0x10b7,0x2d17);
+test(0x10b8,0x2d18);
+test(0x10b9,0x2d19);
+test(0x10ba,0x2d1a);
+test(0x10bb,0x2d1b);
+test(0x10bc,0x2d1c);
+test(0x10bd,0x2d1d);
+test(0x10be,0x2d1e);
+test(0x10bf,0x2d1f);
+test(0x10c0,0x2d20);
+test(0x10c1,0x2d21);
+test(0x10c2,0x2d22);
+test(0x10c3,0x2d23);
+test(0x10c4,0x2d24);
+test(0x10c5,0x2d25);
+test(0x10c7,0x2d27);
+test(0x10cd,0x2d2d);
+test(0x13a0,0xab70);
+test(0x13a1,0xab71);
+test(0x13a2,0xab72);
+test(0x13a3,0xab73);
+test(0x13a4,0xab74);
+test(0x13a5,0xab75);
+test(0x13a6,0xab76);
+test(0x13a7,0xab77);
+test(0x13a8,0xab78);
+test(0x13a9,0xab79);
+test(0x13aa,0xab7a);
+test(0x13ab,0xab7b);
+test(0x13ac,0xab7c);
+test(0x13ad,0xab7d);
+test(0x13ae,0xab7e);
+test(0x13af,0xab7f);
+test(0x13b0,0xab80);
+test(0x13b1,0xab81);
+test(0x13b2,0xab82);
+test(0x13b3,0xab83);
+test(0x13b4,0xab84);
+test(0x13b5,0xab85);
+test(0x13b6,0xab86);
+test(0x13b7,0xab87);
+test(0x13b8,0xab88);
+test(0x13b9,0xab89);
+test(0x13ba,0xab8a);
+test(0x13bb,0xab8b);
+test(0x13bc,0xab8c);
+test(0x13bd,0xab8d);
+test(0x13be,0xab8e);
+test(0x13bf,0xab8f);
+test(0x13c0,0xab90);
+test(0x13c1,0xab91);
+test(0x13c2,0xab92);
+test(0x13c3,0xab93);
+test(0x13c4,0xab94);
+test(0x13c5,0xab95);
+test(0x13c6,0xab96);
+test(0x13c7,0xab97);
+test(0x13c8,0xab98);
+test(0x13c9,0xab99);
+test(0x13ca,0xab9a);
+test(0x13cb,0xab9b);
+test(0x13cc,0xab9c);
+test(0x13cd,0xab9d);
+test(0x13ce,0xab9e);
+test(0x13cf,0xab9f);
+test(0x13d0,0xaba0);
+test(0x13d1,0xaba1);
+test(0x13d2,0xaba2);
+test(0x13d3,0xaba3);
+test(0x13d4,0xaba4);
+test(0x13d5,0xaba5);
+test(0x13d6,0xaba6);
+test(0x13d7,0xaba7);
+test(0x13d8,0xaba8);
+test(0x13d9,0xaba9);
+test(0x13da,0xabaa);
+test(0x13db,0xabab);
+test(0x13dc,0xabac);
+test(0x13dd,0xabad);
+test(0x13de,0xabae);
+test(0x13df,0xabaf);
+test(0x13e0,0xabb0);
+test(0x13e1,0xabb1);
+test(0x13e2,0xabb2);
+test(0x13e3,0xabb3);
+test(0x13e4,0xabb4);
+test(0x13e5,0xabb5);
+test(0x13e6,0xabb6);
+test(0x13e7,0xabb7);
+test(0x13e8,0xabb8);
+test(0x13e9,0xabb9);
+test(0x13ea,0xabba);
+test(0x13eb,0xabbb);
+test(0x13ec,0xabbc);
+test(0x13ed,0xabbd);
+test(0x13ee,0xabbe);
+test(0x13ef,0xabbf);
+test(0x13f0,0x13f8);
+test(0x13f1,0x13f9);
+test(0x13f2,0x13fa);
+test(0x13f3,0x13fb);
+test(0x13f4,0x13fc);
+test(0x13f5,0x13fd);
+test(0x13f8,0x13f0);
+test(0x13f9,0x13f1);
+test(0x13fa,0x13f2);
+test(0x13fb,0x13f3);
+test(0x13fc,0x13f4);
+test(0x13fd,0x13f5);
+test(0x1c80,0x432,0x412);
+test(0x1c81,0x434,0x414);
+test(0x1c82,0x43e,0x41e);
+test(0x1c83,0x441,0x421);
+test(0x1c84,0x442,0x422,0x1c85);
+test(0x1c85,0x442,0x422,0x1c84);
+test(0x1c86,0x44a,0x42a);
+test(0x1c87,0x463,0x462);
+test(0x1c88,0xa64b,0xa64a);
+test(0x1d79,0xa77d);
+test(0x1d7d,0x2c63);
+test(0x1e00,0x1e01);
+test(0x1e01,0x1e00);
+test(0x1e02,0x1e03);
+test(0x1e03,0x1e02);
+test(0x1e04,0x1e05);
+test(0x1e05,0x1e04);
+test(0x1e06,0x1e07);
+test(0x1e07,0x1e06);
+test(0x1e08,0x1e09);
+test(0x1e09,0x1e08);
+test(0x1e0a,0x1e0b);
+test(0x1e0b,0x1e0a);
+test(0x1e0c,0x1e0d);
+test(0x1e0d,0x1e0c);
+test(0x1e0e,0x1e0f);
+test(0x1e0f,0x1e0e);
+test(0x1e10,0x1e11);
+test(0x1e11,0x1e10);
+test(0x1e12,0x1e13);
+test(0x1e13,0x1e12);
+test(0x1e14,0x1e15);
+test(0x1e15,0x1e14);
+test(0x1e16,0x1e17);
+test(0x1e17,0x1e16);
+test(0x1e18,0x1e19);
+test(0x1e19,0x1e18);
+test(0x1e1a,0x1e1b);
+test(0x1e1b,0x1e1a);
+test(0x1e1c,0x1e1d);
+test(0x1e1d,0x1e1c);
+test(0x1e1e,0x1e1f);
+test(0x1e1f,0x1e1e);
+test(0x1e20,0x1e21);
+test(0x1e21,0x1e20);
+test(0x1e22,0x1e23);
+test(0x1e23,0x1e22);
+test(0x1e24,0x1e25);
+test(0x1e25,0x1e24);
+test(0x1e26,0x1e27);
+test(0x1e27,0x1e26);
+test(0x1e28,0x1e29);
+test(0x1e29,0x1e28);
+test(0x1e2a,0x1e2b);
+test(0x1e2b,0x1e2a);
+test(0x1e2c,0x1e2d);
+test(0x1e2d,0x1e2c);
+test(0x1e2e,0x1e2f);
+test(0x1e2f,0x1e2e);
+test(0x1e30,0x1e31);
+test(0x1e31,0x1e30);
+test(0x1e32,0x1e33);
+test(0x1e33,0x1e32);
+test(0x1e34,0x1e35);
+test(0x1e35,0x1e34);
+test(0x1e36,0x1e37);
+test(0x1e37,0x1e36);
+test(0x1e38,0x1e39);
+test(0x1e39,0x1e38);
+test(0x1e3a,0x1e3b);
+test(0x1e3b,0x1e3a);
+test(0x1e3c,0x1e3d);
+test(0x1e3d,0x1e3c);
+test(0x1e3e,0x1e3f);
+test(0x1e3f,0x1e3e);
+test(0x1e40,0x1e41);
+test(0x1e41,0x1e40);
+test(0x1e42,0x1e43);
+test(0x1e43,0x1e42);
+test(0x1e44,0x1e45);
+test(0x1e45,0x1e44);
+test(0x1e46,0x1e47);
+test(0x1e47,0x1e46);
+test(0x1e48,0x1e49);
+test(0x1e49,0x1e48);
+test(0x1e4a,0x1e4b);
+test(0x1e4b,0x1e4a);
+test(0x1e4c,0x1e4d);
+test(0x1e4d,0x1e4c);
+test(0x1e4e,0x1e4f);
+test(0x1e4f,0x1e4e);
+test(0x1e50,0x1e51);
+test(0x1e51,0x1e50);
+test(0x1e52,0x1e53);
+test(0x1e53,0x1e52);
+test(0x1e54,0x1e55);
+test(0x1e55,0x1e54);
+test(0x1e56,0x1e57);
+test(0x1e57,0x1e56);
+test(0x1e58,0x1e59);
+test(0x1e59,0x1e58);
+test(0x1e5a,0x1e5b);
+test(0x1e5b,0x1e5a);
+test(0x1e5c,0x1e5d);
+test(0x1e5d,0x1e5c);
+test(0x1e5e,0x1e5f);
+test(0x1e5f,0x1e5e);
+test(0x1e60,0x1e61,0x1e9b);
+test(0x1e61,0x1e60,0x1e9b);
+test(0x1e62,0x1e63);
+test(0x1e63,0x1e62);
+test(0x1e64,0x1e65);
+test(0x1e65,0x1e64);
+test(0x1e66,0x1e67);
+test(0x1e67,0x1e66);
+test(0x1e68,0x1e69);
+test(0x1e69,0x1e68);
+test(0x1e6a,0x1e6b);
+test(0x1e6b,0x1e6a);
+test(0x1e6c,0x1e6d);
+test(0x1e6d,0x1e6c);
+test(0x1e6e,0x1e6f);
+test(0x1e6f,0x1e6e);
+test(0x1e70,0x1e71);
+test(0x1e71,0x1e70);
+test(0x1e72,0x1e73);
+test(0x1e73,0x1e72);
+test(0x1e74,0x1e75);
+test(0x1e75,0x1e74);
+test(0x1e76,0x1e77);
+test(0x1e77,0x1e76);
+test(0x1e78,0x1e79);
+test(0x1e79,0x1e78);
+test(0x1e7a,0x1e7b);
+test(0x1e7b,0x1e7a);
+test(0x1e7c,0x1e7d);
+test(0x1e7d,0x1e7c);
+test(0x1e7e,0x1e7f);
+test(0x1e7f,0x1e7e);
+test(0x1e80,0x1e81);
+test(0x1e81,0x1e80);
+test(0x1e82,0x1e83);
+test(0x1e83,0x1e82);
+test(0x1e84,0x1e85);
+test(0x1e85,0x1e84);
+test(0x1e86,0x1e87);
+test(0x1e87,0x1e86);
+test(0x1e88,0x1e89);
+test(0x1e89,0x1e88);
+test(0x1e8a,0x1e8b);
+test(0x1e8b,0x1e8a);
+test(0x1e8c,0x1e8d);
+test(0x1e8d,0x1e8c);
+test(0x1e8e,0x1e8f);
+test(0x1e8f,0x1e8e);
+test(0x1e90,0x1e91);
+test(0x1e91,0x1e90);
+test(0x1e92,0x1e93);
+test(0x1e93,0x1e92);
+test(0x1e94,0x1e95);
+test(0x1e95,0x1e94);
+test(0x1e9b,0x1e61,0x1e60);
+test(0x1e9e,0xdf);
+test(0x1ea0,0x1ea1);
+test(0x1ea1,0x1ea0);
+test(0x1ea2,0x1ea3);
+test(0x1ea3,0x1ea2);
+test(0x1ea4,0x1ea5);
+test(0x1ea5,0x1ea4);
+test(0x1ea6,0x1ea7);
+test(0x1ea7,0x1ea6);
+test(0x1ea8,0x1ea9);
+test(0x1ea9,0x1ea8);
+test(0x1eaa,0x1eab);
+test(0x1eab,0x1eaa);
+test(0x1eac,0x1ead);
+test(0x1ead,0x1eac);
+test(0x1eae,0x1eaf);
+test(0x1eaf,0x1eae);
+test(0x1eb0,0x1eb1);
+test(0x1eb1,0x1eb0);
+test(0x1eb2,0x1eb3);
+test(0x1eb3,0x1eb2);
+test(0x1eb4,0x1eb5);
+test(0x1eb5,0x1eb4);
+test(0x1eb6,0x1eb7);
+test(0x1eb7,0x1eb6);
+test(0x1eb8,0x1eb9);
+test(0x1eb9,0x1eb8);
+test(0x1eba,0x1ebb);
+test(0x1ebb,0x1eba);
+test(0x1ebc,0x1ebd);
+test(0x1ebd,0x1ebc);
+test(0x1ebe,0x1ebf);
+test(0x1ebf,0x1ebe);
+test(0x1ec0,0x1ec1);
+test(0x1ec1,0x1ec0);
+test(0x1ec2,0x1ec3);
+test(0x1ec3,0x1ec2);
+test(0x1ec4,0x1ec5);
+test(0x1ec5,0x1ec4);
+test(0x1ec6,0x1ec7);
+test(0x1ec7,0x1ec6);
+test(0x1ec8,0x1ec9);
+test(0x1ec9,0x1ec8);
+test(0x1eca,0x1ecb);
+test(0x1ecb,0x1eca);
+test(0x1ecc,0x1ecd);
+test(0x1ecd,0x1ecc);
+test(0x1ece,0x1ecf);
+test(0x1ecf,0x1ece);
+test(0x1ed0,0x1ed1);
+test(0x1ed1,0x1ed0);
+test(0x1ed2,0x1ed3);
+test(0x1ed3,0x1ed2);
+test(0x1ed4,0x1ed5);
+test(0x1ed5,0x1ed4);
+test(0x1ed6,0x1ed7);
+test(0x1ed7,0x1ed6);
+test(0x1ed8,0x1ed9);
+test(0x1ed9,0x1ed8);
+test(0x1eda,0x1edb);
+test(0x1edb,0x1eda);
+test(0x1edc,0x1edd);
+test(0x1edd,0x1edc);
+test(0x1ede,0x1edf);
+test(0x1edf,0x1ede);
+test(0x1ee0,0x1ee1);
+test(0x1ee1,0x1ee0);
+test(0x1ee2,0x1ee3);
+test(0x1ee3,0x1ee2);
+test(0x1ee4,0x1ee5);
+test(0x1ee5,0x1ee4);
+test(0x1ee6,0x1ee7);
+test(0x1ee7,0x1ee6);
+test(0x1ee8,0x1ee9);
+test(0x1ee9,0x1ee8);
+test(0x1eea,0x1eeb);
+test(0x1eeb,0x1eea);
+test(0x1eec,0x1eed);
+test(0x1eed,0x1eec);
+test(0x1eee,0x1eef);
+test(0x1eef,0x1eee);
+test(0x1ef0,0x1ef1);
+test(0x1ef1,0x1ef0);
+test(0x1ef2,0x1ef3);
+test(0x1ef3,0x1ef2);
+test(0x1ef4,0x1ef5);
+test(0x1ef5,0x1ef4);
+test(0x1ef6,0x1ef7);
+test(0x1ef7,0x1ef6);
+test(0x1ef8,0x1ef9);
+test(0x1ef9,0x1ef8);
+test(0x1efa,0x1efb);
+test(0x1efb,0x1efa);
+test(0x1efc,0x1efd);
+test(0x1efd,0x1efc);
+test(0x1efe,0x1eff);
+test(0x1eff,0x1efe);
+test(0x1f00,0x1f08);
+test(0x1f01,0x1f09);
+test(0x1f02,0x1f0a);
+test(0x1f03,0x1f0b);
+test(0x1f04,0x1f0c);
+test(0x1f05,0x1f0d);
+test(0x1f06,0x1f0e);
+test(0x1f07,0x1f0f);
+test(0x1f08,0x1f00);
+test(0x1f09,0x1f01);
+test(0x1f0a,0x1f02);
+test(0x1f0b,0x1f03);
+test(0x1f0c,0x1f04);
+test(0x1f0d,0x1f05);
+test(0x1f0e,0x1f06);
+test(0x1f0f,0x1f07);
+test(0x1f10,0x1f18);
+test(0x1f11,0x1f19);
+test(0x1f12,0x1f1a);
+test(0x1f13,0x1f1b);
+test(0x1f14,0x1f1c);
+test(0x1f15,0x1f1d);
+test(0x1f18,0x1f10);
+test(0x1f19,0x1f11);
+test(0x1f1a,0x1f12);
+test(0x1f1b,0x1f13);
+test(0x1f1c,0x1f14);
+test(0x1f1d,0x1f15);
+test(0x1f20,0x1f28);
+test(0x1f21,0x1f29);
+test(0x1f22,0x1f2a);
+test(0x1f23,0x1f2b);
+test(0x1f24,0x1f2c);
+test(0x1f25,0x1f2d);
+test(0x1f26,0x1f2e);
+test(0x1f27,0x1f2f);
+test(0x1f28,0x1f20);
+test(0x1f29,0x1f21);
+test(0x1f2a,0x1f22);
+test(0x1f2b,0x1f23);
+test(0x1f2c,0x1f24);
+test(0x1f2d,0x1f25);
+test(0x1f2e,0x1f26);
+test(0x1f2f,0x1f27);
+test(0x1f30,0x1f38);
+test(0x1f31,0x1f39);
+test(0x1f32,0x1f3a);
+test(0x1f33,0x1f3b);
+test(0x1f34,0x1f3c);
+test(0x1f35,0x1f3d);
+test(0x1f36,0x1f3e);
+test(0x1f37,0x1f3f);
+test(0x1f38,0x1f30);
+test(0x1f39,0x1f31);
+test(0x1f3a,0x1f32);
+test(0x1f3b,0x1f33);
+test(0x1f3c,0x1f34);
+test(0x1f3d,0x1f35);
+test(0x1f3e,0x1f36);
+test(0x1f3f,0x1f37);
+test(0x1f40,0x1f48);
+test(0x1f41,0x1f49);
+test(0x1f42,0x1f4a);
+test(0x1f43,0x1f4b);
+test(0x1f44,0x1f4c);
+test(0x1f45,0x1f4d);
+test(0x1f48,0x1f40);
+test(0x1f49,0x1f41);
+test(0x1f4a,0x1f42);
+test(0x1f4b,0x1f43);
+test(0x1f4c,0x1f44);
+test(0x1f4d,0x1f45);
+test(0x1f51,0x1f59);
+test(0x1f53,0x1f5b);
+test(0x1f55,0x1f5d);
+test(0x1f57,0x1f5f);
+test(0x1f59,0x1f51);
+test(0x1f5b,0x1f53);
+test(0x1f5d,0x1f55);
+test(0x1f5f,0x1f57);
+test(0x1f60,0x1f68);
+test(0x1f61,0x1f69);
+test(0x1f62,0x1f6a);
+test(0x1f63,0x1f6b);
+test(0x1f64,0x1f6c);
+test(0x1f65,0x1f6d);
+test(0x1f66,0x1f6e);
+test(0x1f67,0x1f6f);
+test(0x1f68,0x1f60);
+test(0x1f69,0x1f61);
+test(0x1f6a,0x1f62);
+test(0x1f6b,0x1f63);
+test(0x1f6c,0x1f64);
+test(0x1f6d,0x1f65);
+test(0x1f6e,0x1f66);
+test(0x1f6f,0x1f67);
+test(0x1f70,0x1fba);
+test(0x1f71,0x1fbb);
+test(0x1f72,0x1fc8);
+test(0x1f73,0x1fc9);
+test(0x1f74,0x1fca);
+test(0x1f75,0x1fcb);
+test(0x1f76,0x1fda);
+test(0x1f77,0x1fdb);
+test(0x1f78,0x1ff8);
+test(0x1f79,0x1ff9);
+test(0x1f7a,0x1fea);
+test(0x1f7b,0x1feb);
+test(0x1f7c,0x1ffa);
+test(0x1f7d,0x1ffb);
+test(0x1f80,0x1f88);
+test(0x1f81,0x1f89);
+test(0x1f82,0x1f8a);
+test(0x1f83,0x1f8b);
+test(0x1f84,0x1f8c);
+test(0x1f85,0x1f8d);
+test(0x1f86,0x1f8e);
+test(0x1f87,0x1f8f);
+test(0x1f88,0x1f80);
+test(0x1f89,0x1f81);
+test(0x1f8a,0x1f82);
+test(0x1f8b,0x1f83);
+test(0x1f8c,0x1f84);
+test(0x1f8d,0x1f85);
+test(0x1f8e,0x1f86);
+test(0x1f8f,0x1f87);
+test(0x1f90,0x1f98);
+test(0x1f91,0x1f99);
+test(0x1f92,0x1f9a);
+test(0x1f93,0x1f9b);
+test(0x1f94,0x1f9c);
+test(0x1f95,0x1f9d);
+test(0x1f96,0x1f9e);
+test(0x1f97,0x1f9f);
+test(0x1f98,0x1f90);
+test(0x1f99,0x1f91);
+test(0x1f9a,0x1f92);
+test(0x1f9b,0x1f93);
+test(0x1f9c,0x1f94);
+test(0x1f9d,0x1f95);
+test(0x1f9e,0x1f96);
+test(0x1f9f,0x1f97);
+test(0x1fa0,0x1fa8);
+test(0x1fa1,0x1fa9);
+test(0x1fa2,0x1faa);
+test(0x1fa3,0x1fab);
+test(0x1fa4,0x1fac);
+test(0x1fa5,0x1fad);
+test(0x1fa6,0x1fae);
+test(0x1fa7,0x1faf);
+test(0x1fa8,0x1fa0);
+test(0x1fa9,0x1fa1);
+test(0x1faa,0x1fa2);
+test(0x1fab,0x1fa3);
+test(0x1fac,0x1fa4);
+test(0x1fad,0x1fa5);
+test(0x1fae,0x1fa6);
+test(0x1faf,0x1fa7);
+test(0x1fb0,0x1fb8);
+test(0x1fb1,0x1fb9);
+test(0x1fb3,0x1fbc);
+test(0x1fb8,0x1fb0);
+test(0x1fb9,0x1fb1);
+test(0x1fba,0x1f70);
+test(0x1fbb,0x1f71);
+test(0x1fbc,0x1fb3);
+test(0x1fbe,0x3b9,0x345,0x399);
+test(0x1fc3,0x1fcc);
+test(0x1fc8,0x1f72);
+test(0x1fc9,0x1f73);
+test(0x1fca,0x1f74);
+test(0x1fcb,0x1f75);
+test(0x1fcc,0x1fc3);
+test(0x1fd0,0x1fd8);
+test(0x1fd1,0x1fd9);
+test(0x1fd8,0x1fd0);
+test(0x1fd9,0x1fd1);
+test(0x1fda,0x1f76);
+test(0x1fdb,0x1f77);
+test(0x1fe0,0x1fe8);
+test(0x1fe1,0x1fe9);
+test(0x1fe5,0x1fec);
+test(0x1fe8,0x1fe0);
+test(0x1fe9,0x1fe1);
+test(0x1fea,0x1f7a);
+test(0x1feb,0x1f7b);
+test(0x1fec,0x1fe5);
+test(0x1ff3,0x1ffc);
+test(0x1ff8,0x1f78);
+test(0x1ff9,0x1f79);
+test(0x1ffa,0x1f7c);
+test(0x1ffb,0x1f7d);
+test(0x1ffc,0x1ff3);
+test(0x2126,0x3c9,0x3a9);
+test(0x212a,0x6b,0x4b);
+test(0x212b,0xe5,0xc5);
+test(0x2132,0x214e);
+test(0x214e,0x2132);
+test(0x2160,0x2170);
+test(0x2161,0x2171);
+test(0x2162,0x2172);
+test(0x2163,0x2173);
+test(0x2164,0x2174);
+test(0x2165,0x2175);
+test(0x2166,0x2176);
+test(0x2167,0x2177);
+test(0x2168,0x2178);
+test(0x2169,0x2179);
+test(0x216a,0x217a);
+test(0x216b,0x217b);
+test(0x216c,0x217c);
+test(0x216d,0x217d);
+test(0x216e,0x217e);
+test(0x216f,0x217f);
+test(0x2170,0x2160);
+test(0x2171,0x2161);
+test(0x2172,0x2162);
+test(0x2173,0x2163);
+test(0x2174,0x2164);
+test(0x2175,0x2165);
+test(0x2176,0x2166);
+test(0x2177,0x2167);
+test(0x2178,0x2168);
+test(0x2179,0x2169);
+test(0x217a,0x216a);
+test(0x217b,0x216b);
+test(0x217c,0x216c);
+test(0x217d,0x216d);
+test(0x217e,0x216e);
+test(0x217f,0x216f);
+test(0x2183,0x2184);
+test(0x2184,0x2183);
+test(0x24b6,0x24d0);
+test(0x24b7,0x24d1);
+test(0x24b8,0x24d2);
+test(0x24b9,0x24d3);
+test(0x24ba,0x24d4);
+test(0x24bb,0x24d5);
+test(0x24bc,0x24d6);
+test(0x24bd,0x24d7);
+test(0x24be,0x24d8);
+test(0x24bf,0x24d9);
+test(0x24c0,0x24da);
+test(0x24c1,0x24db);
+test(0x24c2,0x24dc);
+test(0x24c3,0x24dd);
+test(0x24c4,0x24de);
+test(0x24c5,0x24df);
+test(0x24c6,0x24e0);
+test(0x24c7,0x24e1);
+test(0x24c8,0x24e2);
+test(0x24c9,0x24e3);
+test(0x24ca,0x24e4);
+test(0x24cb,0x24e5);
+test(0x24cc,0x24e6);
+test(0x24cd,0x24e7);
+test(0x24ce,0x24e8);
+test(0x24cf,0x24e9);
+test(0x24d0,0x24b6);
+test(0x24d1,0x24b7);
+test(0x24d2,0x24b8);
+test(0x24d3,0x24b9);
+test(0x24d4,0x24ba);
+test(0x24d5,0x24bb);
+test(0x24d6,0x24bc);
+test(0x24d7,0x24bd);
+test(0x24d8,0x24be);
+test(0x24d9,0x24bf);
+test(0x24da,0x24c0);
+test(0x24db,0x24c1);
+test(0x24dc,0x24c2);
+test(0x24dd,0x24c3);
+test(0x24de,0x24c4);
+test(0x24df,0x24c5);
+test(0x24e0,0x24c6);
+test(0x24e1,0x24c7);
+test(0x24e2,0x24c8);
+test(0x24e3,0x24c9);
+test(0x24e4,0x24ca);
+test(0x24e5,0x24cb);
+test(0x24e6,0x24cc);
+test(0x24e7,0x24cd);
+test(0x24e8,0x24ce);
+test(0x24e9,0x24cf);
+test(0x2c00,0x2c30);
+test(0x2c01,0x2c31);
+test(0x2c02,0x2c32);
+test(0x2c03,0x2c33);
+test(0x2c04,0x2c34);
+test(0x2c05,0x2c35);
+test(0x2c06,0x2c36);
+test(0x2c07,0x2c37);
+test(0x2c08,0x2c38);
+test(0x2c09,0x2c39);
+test(0x2c0a,0x2c3a);
+test(0x2c0b,0x2c3b);
+test(0x2c0c,0x2c3c);
+test(0x2c0d,0x2c3d);
+test(0x2c0e,0x2c3e);
+test(0x2c0f,0x2c3f);
+test(0x2c10,0x2c40);
+test(0x2c11,0x2c41);
+test(0x2c12,0x2c42);
+test(0x2c13,0x2c43);
+test(0x2c14,0x2c44);
+test(0x2c15,0x2c45);
+test(0x2c16,0x2c46);
+test(0x2c17,0x2c47);
+test(0x2c18,0x2c48);
+test(0x2c19,0x2c49);
+test(0x2c1a,0x2c4a);
+test(0x2c1b,0x2c4b);
+test(0x2c1c,0x2c4c);
+test(0x2c1d,0x2c4d);
+test(0x2c1e,0x2c4e);
+test(0x2c1f,0x2c4f);
+test(0x2c20,0x2c50);
+test(0x2c21,0x2c51);
+test(0x2c22,0x2c52);
+test(0x2c23,0x2c53);
+test(0x2c24,0x2c54);
+test(0x2c25,0x2c55);
+test(0x2c26,0x2c56);
+test(0x2c27,0x2c57);
+test(0x2c28,0x2c58);
+test(0x2c29,0x2c59);
+test(0x2c2a,0x2c5a);
+test(0x2c2b,0x2c5b);
+test(0x2c2c,0x2c5c);
+test(0x2c2d,0x2c5d);
+test(0x2c2e,0x2c5e);
+test(0x2c30,0x2c00);
+test(0x2c31,0x2c01);
+test(0x2c32,0x2c02);
+test(0x2c33,0x2c03);
+test(0x2c34,0x2c04);
+test(0x2c35,0x2c05);
+test(0x2c36,0x2c06);
+test(0x2c37,0x2c07);
+test(0x2c38,0x2c08);
+test(0x2c39,0x2c09);
+test(0x2c3a,0x2c0a);
+test(0x2c3b,0x2c0b);
+test(0x2c3c,0x2c0c);
+test(0x2c3d,0x2c0d);
+test(0x2c3e,0x2c0e);
+test(0x2c3f,0x2c0f);
+test(0x2c40,0x2c10);
+test(0x2c41,0x2c11);
+test(0x2c42,0x2c12);
+test(0x2c43,0x2c13);
+test(0x2c44,0x2c14);
+test(0x2c45,0x2c15);
+test(0x2c46,0x2c16);
+test(0x2c47,0x2c17);
+test(0x2c48,0x2c18);
+test(0x2c49,0x2c19);
+test(0x2c4a,0x2c1a);
+test(0x2c4b,0x2c1b);
+test(0x2c4c,0x2c1c);
+test(0x2c4d,0x2c1d);
+test(0x2c4e,0x2c1e);
+test(0x2c4f,0x2c1f);
+test(0x2c50,0x2c20);
+test(0x2c51,0x2c21);
+test(0x2c52,0x2c22);
+test(0x2c53,0x2c23);
+test(0x2c54,0x2c24);
+test(0x2c55,0x2c25);
+test(0x2c56,0x2c26);
+test(0x2c57,0x2c27);
+test(0x2c58,0x2c28);
+test(0x2c59,0x2c29);
+test(0x2c5a,0x2c2a);
+test(0x2c5b,0x2c2b);
+test(0x2c5c,0x2c2c);
+test(0x2c5d,0x2c2d);
+test(0x2c5e,0x2c2e);
+test(0x2c60,0x2c61);
+test(0x2c61,0x2c60);
+test(0x2c62,0x26b);
+test(0x2c63,0x1d7d);
+test(0x2c64,0x27d);
+test(0x2c65,0x23a);
+test(0x2c66,0x23e);
+test(0x2c67,0x2c68);
+test(0x2c68,0x2c67);
+test(0x2c69,0x2c6a);
+test(0x2c6a,0x2c69);
+test(0x2c6b,0x2c6c);
+test(0x2c6c,0x2c6b);
+test(0x2c6d,0x251);
+test(0x2c6e,0x271);
+test(0x2c6f,0x250);
+test(0x2c70,0x252);
+test(0x2c72,0x2c73);
+test(0x2c73,0x2c72);
+test(0x2c75,0x2c76);
+test(0x2c76,0x2c75);
+test(0x2c7e,0x23f);
+test(0x2c7f,0x240);
+test(0x2c80,0x2c81);
+test(0x2c81,0x2c80);
+test(0x2c82,0x2c83);
+test(0x2c83,0x2c82);
+test(0x2c84,0x2c85);
+test(0x2c85,0x2c84);
+test(0x2c86,0x2c87);
+test(0x2c87,0x2c86);
+test(0x2c88,0x2c89);
+test(0x2c89,0x2c88);
+test(0x2c8a,0x2c8b);
+test(0x2c8b,0x2c8a);
+test(0x2c8c,0x2c8d);
+test(0x2c8d,0x2c8c);
+test(0x2c8e,0x2c8f);
+test(0x2c8f,0x2c8e);
+test(0x2c90,0x2c91);
+test(0x2c91,0x2c90);
+test(0x2c92,0x2c93);
+test(0x2c93,0x2c92);
+test(0x2c94,0x2c95);
+test(0x2c95,0x2c94);
+test(0x2c96,0x2c97);
+test(0x2c97,0x2c96);
+test(0x2c98,0x2c99);
+test(0x2c99,0x2c98);
+test(0x2c9a,0x2c9b);
+test(0x2c9b,0x2c9a);
+test(0x2c9c,0x2c9d);
+test(0x2c9d,0x2c9c);
+test(0x2c9e,0x2c9f);
+test(0x2c9f,0x2c9e);
+test(0x2ca0,0x2ca1);
+test(0x2ca1,0x2ca0);
+test(0x2ca2,0x2ca3);
+test(0x2ca3,0x2ca2);
+test(0x2ca4,0x2ca5);
+test(0x2ca5,0x2ca4);
+test(0x2ca6,0x2ca7);
+test(0x2ca7,0x2ca6);
+test(0x2ca8,0x2ca9);
+test(0x2ca9,0x2ca8);
+test(0x2caa,0x2cab);
+test(0x2cab,0x2caa);
+test(0x2cac,0x2cad);
+test(0x2cad,0x2cac);
+test(0x2cae,0x2caf);
+test(0x2caf,0x2cae);
+test(0x2cb0,0x2cb1);
+test(0x2cb1,0x2cb0);
+test(0x2cb2,0x2cb3);
+test(0x2cb3,0x2cb2);
+test(0x2cb4,0x2cb5);
+test(0x2cb5,0x2cb4);
+test(0x2cb6,0x2cb7);
+test(0x2cb7,0x2cb6);
+test(0x2cb8,0x2cb9);
+test(0x2cb9,0x2cb8);
+test(0x2cba,0x2cbb);
+test(0x2cbb,0x2cba);
+test(0x2cbc,0x2cbd);
+test(0x2cbd,0x2cbc);
+test(0x2cbe,0x2cbf);
+test(0x2cbf,0x2cbe);
+test(0x2cc0,0x2cc1);
+test(0x2cc1,0x2cc0);
+test(0x2cc2,0x2cc3);
+test(0x2cc3,0x2cc2);
+test(0x2cc4,0x2cc5);
+test(0x2cc5,0x2cc4);
+test(0x2cc6,0x2cc7);
+test(0x2cc7,0x2cc6);
+test(0x2cc8,0x2cc9);
+test(0x2cc9,0x2cc8);
+test(0x2cca,0x2ccb);
+test(0x2ccb,0x2cca);
+test(0x2ccc,0x2ccd);
+test(0x2ccd,0x2ccc);
+test(0x2cce,0x2ccf);
+test(0x2ccf,0x2cce);
+test(0x2cd0,0x2cd1);
+test(0x2cd1,0x2cd0);
+test(0x2cd2,0x2cd3);
+test(0x2cd3,0x2cd2);
+test(0x2cd4,0x2cd5);
+test(0x2cd5,0x2cd4);
+test(0x2cd6,0x2cd7);
+test(0x2cd7,0x2cd6);
+test(0x2cd8,0x2cd9);
+test(0x2cd9,0x2cd8);
+test(0x2cda,0x2cdb);
+test(0x2cdb,0x2cda);
+test(0x2cdc,0x2cdd);
+test(0x2cdd,0x2cdc);
+test(0x2cde,0x2cdf);
+test(0x2cdf,0x2cde);
+test(0x2ce0,0x2ce1);
+test(0x2ce1,0x2ce0);
+test(0x2ce2,0x2ce3);
+test(0x2ce3,0x2ce2);
+test(0x2ceb,0x2cec);
+test(0x2cec,0x2ceb);
+test(0x2ced,0x2cee);
+test(0x2cee,0x2ced);
+test(0x2cf2,0x2cf3);
+test(0x2cf3,0x2cf2);
+test(0x2d00,0x10a0);
+test(0x2d01,0x10a1);
+test(0x2d02,0x10a2);
+test(0x2d03,0x10a3);
+test(0x2d04,0x10a4);
+test(0x2d05,0x10a5);
+test(0x2d06,0x10a6);
+test(0x2d07,0x10a7);
+test(0x2d08,0x10a8);
+test(0x2d09,0x10a9);
+test(0x2d0a,0x10aa);
+test(0x2d0b,0x10ab);
+test(0x2d0c,0x10ac);
+test(0x2d0d,0x10ad);
+test(0x2d0e,0x10ae);
+test(0x2d0f,0x10af);
+test(0x2d10,0x10b0);
+test(0x2d11,0x10b1);
+test(0x2d12,0x10b2);
+test(0x2d13,0x10b3);
+test(0x2d14,0x10b4);
+test(0x2d15,0x10b5);
+test(0x2d16,0x10b6);
+test(0x2d17,0x10b7);
+test(0x2d18,0x10b8);
+test(0x2d19,0x10b9);
+test(0x2d1a,0x10ba);
+test(0x2d1b,0x10bb);
+test(0x2d1c,0x10bc);
+test(0x2d1d,0x10bd);
+test(0x2d1e,0x10be);
+test(0x2d1f,0x10bf);
+test(0x2d20,0x10c0);
+test(0x2d21,0x10c1);
+test(0x2d22,0x10c2);
+test(0x2d23,0x10c3);
+test(0x2d24,0x10c4);
+test(0x2d25,0x10c5);
+test(0x2d27,0x10c7);
+test(0x2d2d,0x10cd);
+test(0xa640,0xa641);
+test(0xa641,0xa640);
+test(0xa642,0xa643);
+test(0xa643,0xa642);
+test(0xa644,0xa645);
+test(0xa645,0xa644);
+test(0xa646,0xa647);
+test(0xa647,0xa646);
+test(0xa648,0xa649);
+test(0xa649,0xa648);
+test(0xa64a,0xa64b,0x1c88);
+test(0xa64b,0x1c88,0xa64a);
+test(0xa64c,0xa64d);
+test(0xa64d,0xa64c);
+test(0xa64e,0xa64f);
+test(0xa64f,0xa64e);
+test(0xa650,0xa651);
+test(0xa651,0xa650);
+test(0xa652,0xa653);
+test(0xa653,0xa652);
+test(0xa654,0xa655);
+test(0xa655,0xa654);
+test(0xa656,0xa657);
+test(0xa657,0xa656);
+test(0xa658,0xa659);
+test(0xa659,0xa658);
+test(0xa65a,0xa65b);
+test(0xa65b,0xa65a);
+test(0xa65c,0xa65d);
+test(0xa65d,0xa65c);
+test(0xa65e,0xa65f);
+test(0xa65f,0xa65e);
+test(0xa660,0xa661);
+test(0xa661,0xa660);
+test(0xa662,0xa663);
+test(0xa663,0xa662);
+test(0xa664,0xa665);
+test(0xa665,0xa664);
+test(0xa666,0xa667);
+test(0xa667,0xa666);
+test(0xa668,0xa669);
+test(0xa669,0xa668);
+test(0xa66a,0xa66b);
+test(0xa66b,0xa66a);
+test(0xa66c,0xa66d);
+test(0xa66d,0xa66c);
+test(0xa680,0xa681);
+test(0xa681,0xa680);
+test(0xa682,0xa683);
+test(0xa683,0xa682);
+test(0xa684,0xa685);
+test(0xa685,0xa684);
+test(0xa686,0xa687);
+test(0xa687,0xa686);
+test(0xa688,0xa689);
+test(0xa689,0xa688);
+test(0xa68a,0xa68b);
+test(0xa68b,0xa68a);
+test(0xa68c,0xa68d);
+test(0xa68d,0xa68c);
+test(0xa68e,0xa68f);
+test(0xa68f,0xa68e);
+test(0xa690,0xa691);
+test(0xa691,0xa690);
+test(0xa692,0xa693);
+test(0xa693,0xa692);
+test(0xa694,0xa695);
+test(0xa695,0xa694);
+test(0xa696,0xa697);
+test(0xa697,0xa696);
+test(0xa698,0xa699);
+test(0xa699,0xa698);
+test(0xa69a,0xa69b);
+test(0xa69b,0xa69a);
+test(0xa722,0xa723);
+test(0xa723,0xa722);
+test(0xa724,0xa725);
+test(0xa725,0xa724);
+test(0xa726,0xa727);
+test(0xa727,0xa726);
+test(0xa728,0xa729);
+test(0xa729,0xa728);
+test(0xa72a,0xa72b);
+test(0xa72b,0xa72a);
+test(0xa72c,0xa72d);
+test(0xa72d,0xa72c);
+test(0xa72e,0xa72f);
+test(0xa72f,0xa72e);
+test(0xa732,0xa733);
+test(0xa733,0xa732);
+test(0xa734,0xa735);
+test(0xa735,0xa734);
+test(0xa736,0xa737);
+test(0xa737,0xa736);
+test(0xa738,0xa739);
+test(0xa739,0xa738);
+test(0xa73a,0xa73b);
+test(0xa73b,0xa73a);
+test(0xa73c,0xa73d);
+test(0xa73d,0xa73c);
+test(0xa73e,0xa73f);
+test(0xa73f,0xa73e);
+test(0xa740,0xa741);
+test(0xa741,0xa740);
+test(0xa742,0xa743);
+test(0xa743,0xa742);
+test(0xa744,0xa745);
+test(0xa745,0xa744);
+test(0xa746,0xa747);
+test(0xa747,0xa746);
+test(0xa748,0xa749);
+test(0xa749,0xa748);
+test(0xa74a,0xa74b);
+test(0xa74b,0xa74a);
+test(0xa74c,0xa74d);
+test(0xa74d,0xa74c);
+test(0xa74e,0xa74f);
+test(0xa74f,0xa74e);
+test(0xa750,0xa751);
+test(0xa751,0xa750);
+test(0xa752,0xa753);
+test(0xa753,0xa752);
+test(0xa754,0xa755);
+test(0xa755,0xa754);
+test(0xa756,0xa757);
+test(0xa757,0xa756);
+test(0xa758,0xa759);
+test(0xa759,0xa758);
+test(0xa75a,0xa75b);
+test(0xa75b,0xa75a);
+test(0xa75c,0xa75d);
+test(0xa75d,0xa75c);
+test(0xa75e,0xa75f);
+test(0xa75f,0xa75e);
+test(0xa760,0xa761);
+test(0xa761,0xa760);
+test(0xa762,0xa763);
+test(0xa763,0xa762);
+test(0xa764,0xa765);
+test(0xa765,0xa764);
+test(0xa766,0xa767);
+test(0xa767,0xa766);
+test(0xa768,0xa769);
+test(0xa769,0xa768);
+test(0xa76a,0xa76b);
+test(0xa76b,0xa76a);
+test(0xa76c,0xa76d);
+test(0xa76d,0xa76c);
+test(0xa76e,0xa76f);
+test(0xa76f,0xa76e);
+test(0xa779,0xa77a);
+test(0xa77a,0xa779);
+test(0xa77b,0xa77c);
+test(0xa77c,0xa77b);
+test(0xa77d,0x1d79);
+test(0xa77e,0xa77f);
+test(0xa77f,0xa77e);
+test(0xa780,0xa781);
+test(0xa781,0xa780);
+test(0xa782,0xa783);
+test(0xa783,0xa782);
+test(0xa784,0xa785);
+test(0xa785,0xa784);
+test(0xa786,0xa787);
+test(0xa787,0xa786);
+test(0xa78b,0xa78c);
+test(0xa78c,0xa78b);
+test(0xa78d,0x265);
+test(0xa790,0xa791);
+test(0xa791,0xa790);
+test(0xa792,0xa793);
+test(0xa793,0xa792);
+test(0xa796,0xa797);
+test(0xa797,0xa796);
+test(0xa798,0xa799);
+test(0xa799,0xa798);
+test(0xa79a,0xa79b);
+test(0xa79b,0xa79a);
+test(0xa79c,0xa79d);
+test(0xa79d,0xa79c);
+test(0xa79e,0xa79f);
+test(0xa79f,0xa79e);
+test(0xa7a0,0xa7a1);
+test(0xa7a1,0xa7a0);
+test(0xa7a2,0xa7a3);
+test(0xa7a3,0xa7a2);
+test(0xa7a4,0xa7a5);
+test(0xa7a5,0xa7a4);
+test(0xa7a6,0xa7a7);
+test(0xa7a7,0xa7a6);
+test(0xa7a8,0xa7a9);
+test(0xa7a9,0xa7a8);
+test(0xa7aa,0x266);
+test(0xa7ab,0x25c);
+test(0xa7ac,0x261);
+test(0xa7ad,0x26c);
+test(0xa7ae,0x26a);
+test(0xa7b0,0x29e);
+test(0xa7b1,0x287);
+test(0xa7b2,0x29d);
+test(0xa7b3,0xab53);
+test(0xa7b4,0xa7b5);
+test(0xa7b5,0xa7b4);
+test(0xa7b6,0xa7b7);
+test(0xa7b7,0xa7b6);
+test(0xab53,0xa7b3);
+test(0xab70,0x13a0);
+test(0xab71,0x13a1);
+test(0xab72,0x13a2);
+test(0xab73,0x13a3);
+test(0xab74,0x13a4);
+test(0xab75,0x13a5);
+test(0xab76,0x13a6);
+test(0xab77,0x13a7);
+test(0xab78,0x13a8);
+test(0xab79,0x13a9);
+test(0xab7a,0x13aa);
+test(0xab7b,0x13ab);
+test(0xab7c,0x13ac);
+test(0xab7d,0x13ad);
+test(0xab7e,0x13ae);
+test(0xab7f,0x13af);
+test(0xab80,0x13b0);
+test(0xab81,0x13b1);
+test(0xab82,0x13b2);
+test(0xab83,0x13b3);
+test(0xab84,0x13b4);
+test(0xab85,0x13b5);
+test(0xab86,0x13b6);
+test(0xab87,0x13b7);
+test(0xab88,0x13b8);
+test(0xab89,0x13b9);
+test(0xab8a,0x13ba);
+test(0xab8b,0x13bb);
+test(0xab8c,0x13bc);
+test(0xab8d,0x13bd);
+test(0xab8e,0x13be);
+test(0xab8f,0x13bf);
+test(0xab90,0x13c0);
+test(0xab91,0x13c1);
+test(0xab92,0x13c2);
+test(0xab93,0x13c3);
+test(0xab94,0x13c4);
+test(0xab95,0x13c5);
+test(0xab96,0x13c6);
+test(0xab97,0x13c7);
+test(0xab98,0x13c8);
+test(0xab99,0x13c9);
+test(0xab9a,0x13ca);
+test(0xab9b,0x13cb);
+test(0xab9c,0x13cc);
+test(0xab9d,0x13cd);
+test(0xab9e,0x13ce);
+test(0xab9f,0x13cf);
+test(0xaba0,0x13d0);
+test(0xaba1,0x13d1);
+test(0xaba2,0x13d2);
+test(0xaba3,0x13d3);
+test(0xaba4,0x13d4);
+test(0xaba5,0x13d5);
+test(0xaba6,0x13d6);
+test(0xaba7,0x13d7);
+test(0xaba8,0x13d8);
+test(0xaba9,0x13d9);
+test(0xabaa,0x13da);
+test(0xabab,0x13db);
+test(0xabac,0x13dc);
+test(0xabad,0x13dd);
+test(0xabae,0x13de);
+test(0xabaf,0x13df);
+test(0xabb0,0x13e0);
+test(0xabb1,0x13e1);
+test(0xabb2,0x13e2);
+test(0xabb3,0x13e3);
+test(0xabb4,0x13e4);
+test(0xabb5,0x13e5);
+test(0xabb6,0x13e6);
+test(0xabb7,0x13e7);
+test(0xabb8,0x13e8);
+test(0xabb9,0x13e9);
+test(0xabba,0x13ea);
+test(0xabbb,0x13eb);
+test(0xabbc,0x13ec);
+test(0xabbd,0x13ed);
+test(0xabbe,0x13ee);
+test(0xabbf,0x13ef);
+test(0xff21,0xff41);
+test(0xff22,0xff42);
+test(0xff23,0xff43);
+test(0xff24,0xff44);
+test(0xff25,0xff45);
+test(0xff26,0xff46);
+test(0xff27,0xff47);
+test(0xff28,0xff48);
+test(0xff29,0xff49);
+test(0xff2a,0xff4a);
+test(0xff2b,0xff4b);
+test(0xff2c,0xff4c);
+test(0xff2d,0xff4d);
+test(0xff2e,0xff4e);
+test(0xff2f,0xff4f);
+test(0xff30,0xff50);
+test(0xff31,0xff51);
+test(0xff32,0xff52);
+test(0xff33,0xff53);
+test(0xff34,0xff54);
+test(0xff35,0xff55);
+test(0xff36,0xff56);
+test(0xff37,0xff57);
+test(0xff38,0xff58);
+test(0xff39,0xff59);
+test(0xff3a,0xff5a);
+test(0xff41,0xff21);
+test(0xff42,0xff22);
+test(0xff43,0xff23);
+test(0xff44,0xff24);
+test(0xff45,0xff25);
+test(0xff46,0xff26);
+test(0xff47,0xff27);
+test(0xff48,0xff28);
+test(0xff49,0xff29);
+test(0xff4a,0xff2a);
+test(0xff4b,0xff2b);
+test(0xff4c,0xff2c);
+test(0xff4d,0xff2d);
+test(0xff4e,0xff2e);
+test(0xff4f,0xff2f);
+test(0xff50,0xff30);
+test(0xff51,0xff31);
+test(0xff52,0xff32);
+test(0xff53,0xff33);
+test(0xff54,0xff34);
+test(0xff55,0xff35);
+test(0xff56,0xff36);
+test(0xff57,0xff37);
+test(0xff58,0xff38);
+test(0xff59,0xff39);
+test(0xff5a,0xff3a);
+test(0x10400,0x10428);
+test(0x10401,0x10429);
+test(0x10402,0x1042a);
+test(0x10403,0x1042b);
+test(0x10404,0x1042c);
+test(0x10405,0x1042d);
+test(0x10406,0x1042e);
+test(0x10407,0x1042f);
+test(0x10408,0x10430);
+test(0x10409,0x10431);
+test(0x1040a,0x10432);
+test(0x1040b,0x10433);
+test(0x1040c,0x10434);
+test(0x1040d,0x10435);
+test(0x1040e,0x10436);
+test(0x1040f,0x10437);
+test(0x10410,0x10438);
+test(0x10411,0x10439);
+test(0x10412,0x1043a);
+test(0x10413,0x1043b);
+test(0x10414,0x1043c);
+test(0x10415,0x1043d);
+test(0x10416,0x1043e);
+test(0x10417,0x1043f);
+test(0x10418,0x10440);
+test(0x10419,0x10441);
+test(0x1041a,0x10442);
+test(0x1041b,0x10443);
+test(0x1041c,0x10444);
+test(0x1041d,0x10445);
+test(0x1041e,0x10446);
+test(0x1041f,0x10447);
+test(0x10420,0x10448);
+test(0x10421,0x10449);
+test(0x10422,0x1044a);
+test(0x10423,0x1044b);
+test(0x10424,0x1044c);
+test(0x10425,0x1044d);
+test(0x10426,0x1044e);
+test(0x10427,0x1044f);
+test(0x10428,0x10400);
+test(0x10429,0x10401);
+test(0x1042a,0x10402);
+test(0x1042b,0x10403);
+test(0x1042c,0x10404);
+test(0x1042d,0x10405);
+test(0x1042e,0x10406);
+test(0x1042f,0x10407);
+test(0x10430,0x10408);
+test(0x10431,0x10409);
+test(0x10432,0x1040a);
+test(0x10433,0x1040b);
+test(0x10434,0x1040c);
+test(0x10435,0x1040d);
+test(0x10436,0x1040e);
+test(0x10437,0x1040f);
+test(0x10438,0x10410);
+test(0x10439,0x10411);
+test(0x1043a,0x10412);
+test(0x1043b,0x10413);
+test(0x1043c,0x10414);
+test(0x1043d,0x10415);
+test(0x1043e,0x10416);
+test(0x1043f,0x10417);
+test(0x10440,0x10418);
+test(0x10441,0x10419);
+test(0x10442,0x1041a);
+test(0x10443,0x1041b);
+test(0x10444,0x1041c);
+test(0x10445,0x1041d);
+test(0x10446,0x1041e);
+test(0x10447,0x1041f);
+test(0x10448,0x10420);
+test(0x10449,0x10421);
+test(0x1044a,0x10422);
+test(0x1044b,0x10423);
+test(0x1044c,0x10424);
+test(0x1044d,0x10425);
+test(0x1044e,0x10426);
+test(0x1044f,0x10427);
+test(0x104b0,0x104d8);
+test(0x104b1,0x104d9);
+test(0x104b2,0x104da);
+test(0x104b3,0x104db);
+test(0x104b4,0x104dc);
+test(0x104b5,0x104dd);
+test(0x104b6,0x104de);
+test(0x104b7,0x104df);
+test(0x104b8,0x104e0);
+test(0x104b9,0x104e1);
+test(0x104ba,0x104e2);
+test(0x104bb,0x104e3);
+test(0x104bc,0x104e4);
+test(0x104bd,0x104e5);
+test(0x104be,0x104e6);
+test(0x104bf,0x104e7);
+test(0x104c0,0x104e8);
+test(0x104c1,0x104e9);
+test(0x104c2,0x104ea);
+test(0x104c3,0x104eb);
+test(0x104c4,0x104ec);
+test(0x104c5,0x104ed);
+test(0x104c6,0x104ee);
+test(0x104c7,0x104ef);
+test(0x104c8,0x104f0);
+test(0x104c9,0x104f1);
+test(0x104ca,0x104f2);
+test(0x104cb,0x104f3);
+test(0x104cc,0x104f4);
+test(0x104cd,0x104f5);
+test(0x104ce,0x104f6);
+test(0x104cf,0x104f7);
+test(0x104d0,0x104f8);
+test(0x104d1,0x104f9);
+test(0x104d2,0x104fa);
+test(0x104d3,0x104fb);
+test(0x104d8,0x104b0);
+test(0x104d9,0x104b1);
+test(0x104da,0x104b2);
+test(0x104db,0x104b3);
+test(0x104dc,0x104b4);
+test(0x104dd,0x104b5);
+test(0x104de,0x104b6);
+test(0x104df,0x104b7);
+test(0x104e0,0x104b8);
+test(0x104e1,0x104b9);
+test(0x104e2,0x104ba);
+test(0x104e3,0x104bb);
+test(0x104e4,0x104bc);
+test(0x104e5,0x104bd);
+test(0x104e6,0x104be);
+test(0x104e7,0x104bf);
+test(0x104e8,0x104c0);
+test(0x104e9,0x104c1);
+test(0x104ea,0x104c2);
+test(0x104eb,0x104c3);
+test(0x104ec,0x104c4);
+test(0x104ed,0x104c5);
+test(0x104ee,0x104c6);
+test(0x104ef,0x104c7);
+test(0x104f0,0x104c8);
+test(0x104f1,0x104c9);
+test(0x104f2,0x104ca);
+test(0x104f3,0x104cb);
+test(0x104f4,0x104cc);
+test(0x104f5,0x104cd);
+test(0x104f6,0x104ce);
+test(0x104f7,0x104cf);
+test(0x104f8,0x104d0);
+test(0x104f9,0x104d1);
+test(0x104fa,0x104d2);
+test(0x104fb,0x104d3);
+test(0x10c80,0x10cc0);
+test(0x10c81,0x10cc1);
+test(0x10c82,0x10cc2);
+test(0x10c83,0x10cc3);
+test(0x10c84,0x10cc4);
+test(0x10c85,0x10cc5);
+test(0x10c86,0x10cc6);
+test(0x10c87,0x10cc7);
+test(0x10c88,0x10cc8);
+test(0x10c89,0x10cc9);
+test(0x10c8a,0x10cca);
+test(0x10c8b,0x10ccb);
+test(0x10c8c,0x10ccc);
+test(0x10c8d,0x10ccd);
+test(0x10c8e,0x10cce);
+test(0x10c8f,0x10ccf);
+test(0x10c90,0x10cd0);
+test(0x10c91,0x10cd1);
+test(0x10c92,0x10cd2);
+test(0x10c93,0x10cd3);
+test(0x10c94,0x10cd4);
+test(0x10c95,0x10cd5);
+test(0x10c96,0x10cd6);
+test(0x10c97,0x10cd7);
+test(0x10c98,0x10cd8);
+test(0x10c99,0x10cd9);
+test(0x10c9a,0x10cda);
+test(0x10c9b,0x10cdb);
+test(0x10c9c,0x10cdc);
+test(0x10c9d,0x10cdd);
+test(0x10c9e,0x10cde);
+test(0x10c9f,0x10cdf);
+test(0x10ca0,0x10ce0);
+test(0x10ca1,0x10ce1);
+test(0x10ca2,0x10ce2);
+test(0x10ca3,0x10ce3);
+test(0x10ca4,0x10ce4);
+test(0x10ca5,0x10ce5);
+test(0x10ca6,0x10ce6);
+test(0x10ca7,0x10ce7);
+test(0x10ca8,0x10ce8);
+test(0x10ca9,0x10ce9);
+test(0x10caa,0x10cea);
+test(0x10cab,0x10ceb);
+test(0x10cac,0x10cec);
+test(0x10cad,0x10ced);
+test(0x10cae,0x10cee);
+test(0x10caf,0x10cef);
+test(0x10cb0,0x10cf0);
+test(0x10cb1,0x10cf1);
+test(0x10cb2,0x10cf2);
+test(0x10cc0,0x10c80);
+test(0x10cc1,0x10c81);
+test(0x10cc2,0x10c82);
+test(0x10cc3,0x10c83);
+test(0x10cc4,0x10c84);
+test(0x10cc5,0x10c85);
+test(0x10cc6,0x10c86);
+test(0x10cc7,0x10c87);
+test(0x10cc8,0x10c88);
+test(0x10cc9,0x10c89);
+test(0x10cca,0x10c8a);
+test(0x10ccb,0x10c8b);
+test(0x10ccc,0x10c8c);
+test(0x10ccd,0x10c8d);
+test(0x10cce,0x10c8e);
+test(0x10ccf,0x10c8f);
+test(0x10cd0,0x10c90);
+test(0x10cd1,0x10c91);
+test(0x10cd2,0x10c92);
+test(0x10cd3,0x10c93);
+test(0x10cd4,0x10c94);
+test(0x10cd5,0x10c95);
+test(0x10cd6,0x10c96);
+test(0x10cd7,0x10c97);
+test(0x10cd8,0x10c98);
+test(0x10cd9,0x10c99);
+test(0x10cda,0x10c9a);
+test(0x10cdb,0x10c9b);
+test(0x10cdc,0x10c9c);
+test(0x10cdd,0x10c9d);
+test(0x10cde,0x10c9e);
+test(0x10cdf,0x10c9f);
+test(0x10ce0,0x10ca0);
+test(0x10ce1,0x10ca1);
+test(0x10ce2,0x10ca2);
+test(0x10ce3,0x10ca3);
+test(0x10ce4,0x10ca4);
+test(0x10ce5,0x10ca5);
+test(0x10ce6,0x10ca6);
+test(0x10ce7,0x10ca7);
+test(0x10ce8,0x10ca8);
+test(0x10ce9,0x10ca9);
+test(0x10cea,0x10caa);
+test(0x10ceb,0x10cab);
+test(0x10cec,0x10cac);
+test(0x10ced,0x10cad);
+test(0x10cee,0x10cae);
+test(0x10cef,0x10caf);
+test(0x10cf0,0x10cb0);
+test(0x10cf1,0x10cb1);
+test(0x10cf2,0x10cb2);
+test(0x118a0,0x118c0);
+test(0x118a1,0x118c1);
+test(0x118a2,0x118c2);
+test(0x118a3,0x118c3);
+test(0x118a4,0x118c4);
+test(0x118a5,0x118c5);
+test(0x118a6,0x118c6);
+test(0x118a7,0x118c7);
+test(0x118a8,0x118c8);
+test(0x118a9,0x118c9);
+test(0x118aa,0x118ca);
+test(0x118ab,0x118cb);
+test(0x118ac,0x118cc);
+test(0x118ad,0x118cd);
+test(0x118ae,0x118ce);
+test(0x118af,0x118cf);
+test(0x118b0,0x118d0);
+test(0x118b1,0x118d1);
+test(0x118b2,0x118d2);
+test(0x118b3,0x118d3);
+test(0x118b4,0x118d4);
+test(0x118b5,0x118d5);
+test(0x118b6,0x118d6);
+test(0x118b7,0x118d7);
+test(0x118b8,0x118d8);
+test(0x118b9,0x118d9);
+test(0x118ba,0x118da);
+test(0x118bb,0x118db);
+test(0x118bc,0x118dc);
+test(0x118bd,0x118dd);
+test(0x118be,0x118de);
+test(0x118bf,0x118df);
+test(0x118c0,0x118a0);
+test(0x118c1,0x118a1);
+test(0x118c2,0x118a2);
+test(0x118c3,0x118a3);
+test(0x118c4,0x118a4);
+test(0x118c5,0x118a5);
+test(0x118c6,0x118a6);
+test(0x118c7,0x118a7);
+test(0x118c8,0x118a8);
+test(0x118c9,0x118a9);
+test(0x118ca,0x118aa);
+test(0x118cb,0x118ab);
+test(0x118cc,0x118ac);
+test(0x118cd,0x118ad);
+test(0x118ce,0x118ae);
+test(0x118cf,0x118af);
+test(0x118d0,0x118b0);
+test(0x118d1,0x118b1);
+test(0x118d2,0x118b2);
+test(0x118d3,0x118b3);
+test(0x118d4,0x118b4);
+test(0x118d5,0x118b5);
+test(0x118d6,0x118b6);
+test(0x118d7,0x118b7);
+test(0x118d8,0x118b8);
+test(0x118d9,0x118b9);
+test(0x118da,0x118ba);
+test(0x118db,0x118bb);
+test(0x118dc,0x118bc);
+test(0x118dd,0x118bd);
+test(0x118de,0x118be);
+test(0x118df,0x118bf);
+test(0x1e900,0x1e922);
+test(0x1e901,0x1e923);
+test(0x1e902,0x1e924);
+test(0x1e903,0x1e925);
+test(0x1e904,0x1e926);
+test(0x1e905,0x1e927);
+test(0x1e906,0x1e928);
+test(0x1e907,0x1e929);
+test(0x1e908,0x1e92a);
+test(0x1e909,0x1e92b);
+test(0x1e90a,0x1e92c);
+test(0x1e90b,0x1e92d);
+test(0x1e90c,0x1e92e);
+test(0x1e90d,0x1e92f);
+test(0x1e90e,0x1e930);
+test(0x1e90f,0x1e931);
+test(0x1e910,0x1e932);
+test(0x1e911,0x1e933);
+test(0x1e912,0x1e934);
+test(0x1e913,0x1e935);
+test(0x1e914,0x1e936);
+test(0x1e915,0x1e937);
+test(0x1e916,0x1e938);
+test(0x1e917,0x1e939);
+test(0x1e918,0x1e93a);
+test(0x1e919,0x1e93b);
+test(0x1e91a,0x1e93c);
+test(0x1e91b,0x1e93d);
+test(0x1e91c,0x1e93e);
+test(0x1e91d,0x1e93f);
+test(0x1e91e,0x1e940);
+test(0x1e91f,0x1e941);
+test(0x1e920,0x1e942);
+test(0x1e921,0x1e943);
+test(0x1e922,0x1e900);
+test(0x1e923,0x1e901);
+test(0x1e924,0x1e902);
+test(0x1e925,0x1e903);
+test(0x1e926,0x1e904);
+test(0x1e927,0x1e905);
+test(0x1e928,0x1e906);
+test(0x1e929,0x1e907);
+test(0x1e92a,0x1e908);
+test(0x1e92b,0x1e909);
+test(0x1e92c,0x1e90a);
+test(0x1e92d,0x1e90b);
+test(0x1e92e,0x1e90c);
+test(0x1e92f,0x1e90d);
+test(0x1e930,0x1e90e);
+test(0x1e931,0x1e90f);
+test(0x1e932,0x1e910);
+test(0x1e933,0x1e911);
+test(0x1e934,0x1e912);
+test(0x1e935,0x1e913);
+test(0x1e936,0x1e914);
+test(0x1e937,0x1e915);
+test(0x1e938,0x1e916);
+test(0x1e939,0x1e917);
+test(0x1e93a,0x1e918);
+test(0x1e93b,0x1e919);
+test(0x1e93c,0x1e91a);
+test(0x1e93d,0x1e91b);
+test(0x1e93e,0x1e91c);
+test(0x1e93f,0x1e91d);
+test(0x1e940,0x1e91e);
+test(0x1e941,0x1e91f);
+test(0x1e942,0x1e920);
+test(0x1e943,0x1e921);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/unicode-index.js b/js/src/tests/ecma_6/RegExp/unicode-index.js
new file mode 100644
index 000000000..a4b2eb203
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/unicode-index.js
@@ -0,0 +1,17 @@
+var BUGNUMBER = 1135377;
+var summary = "Implement RegExp unicode flag -- Pattern match should start from lead surrogate when lastIndex points corresponding trail surrogate.";
+
+print(BUGNUMBER + ": " + summary);
+
+var r = /\uD83D\uDC38/ug;
+r.lastIndex = 1;
+var str = "\uD83D\uDC38";
+var result = r.exec(str);
+assertEq(result.length, 1);
+assertEq(result[0], "\uD83D\uDC38");
+
+// This does not match to ES6 spec, but the spec will be changed.
+assertEq(result.index, 0);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/unicode-lead-trail.js b/js/src/tests/ecma_6/RegExp/unicode-lead-trail.js
new file mode 100644
index 000000000..7ecdb9ace
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/unicode-lead-trail.js
@@ -0,0 +1,218 @@
+var BUGNUMBER = 1135377;
+var summary = "Implement RegExp unicode flag -- lead and trail patterns in RegExpUnicodeEscapeSequence.";
+
+print(BUGNUMBER + ": " + summary);
+
+// ==== standalone ====
+
+assertEqArray(/\uD83D\uDC38/u.exec("\u{1F438}"),
+ ["\u{1F438}"]);
+
+// no unicode flag
+assertEqArray(/\uD83D\uDC38/.exec("\u{1F438}"),
+ ["\u{1F438}"]);
+
+// RegExp constructor
+assertEqArray(new RegExp("\\uD83D\\uDC38", "u").exec("\u{1F438}"),
+ ["\u{1F438}"]);
+
+// RegExp constructor, no unicode flag
+assertEqArray(new RegExp("\\uD83D\\uDC38", "").exec("\u{1F438}"),
+ ["\u{1F438}"]);
+
+// ==== ? ====
+
+assertEqArray(/\uD83D\uDC38?/u.exec("\u{1F438}"),
+ ["\u{1F438}"]);
+assertEqArray(/\uD83D\uDC38?/u.exec(""),
+ [""]);
+
+// lead-only target
+assertEqArray(/\uD83D\uDC38?/u.exec("\uD83D"),
+ [""]);
+
+// no unicode flag
+assertEqArray(/\uD83D\uDC38?/.exec("\u{1F438}"),
+ ["\u{1F438}"]);
+assertEq(/\uD83D\uDC38?/.exec(""),
+ null);
+
+assertEqArray(/\uD83D\uDC38?/.exec("\uD83D"),
+ ["\uD83D"]);
+
+// RegExp constructor
+assertEqArray(new RegExp("\\uD83D\\uDC38?", "u").exec("\u{1F438}"),
+ ["\u{1F438}"]);
+assertEqArray(new RegExp("\\uD83D\\uDC38?", "u").exec(""),
+ [""]);
+
+assertEqArray(new RegExp("\\uD83D\\uDC38?", "u").exec("\uD83D"),
+ [""]);
+
+// RegExp constructor, no unicode flag
+assertEqArray(new RegExp("\\uD83D\\uDC38?", "").exec("\u{1F438}"),
+ ["\u{1F438}"]);
+assertEq(new RegExp("\\uD83D\\uDC38?", "").exec(""),
+ null);
+
+assertEqArray(new RegExp("\\uD83D\\uDC38?", "").exec("\uD83D"),
+ ["\uD83D"]);
+
+// ==== + ====
+
+assertEqArray(/\uD83D\uDC38+/u.exec("\u{1F438}"),
+ ["\u{1F438}"]);
+assertEqArray(/\uD83D\uDC38+/u.exec("\u{1F438}\u{1F438}"),
+ ["\u{1F438}\u{1F438}"]);
+assertEq(/\uD83D\uDC38+/u.exec(""),
+ null);
+
+// lead-only target
+assertEq(/\uD83D\uDC38+/u.exec("\uD83D"),
+ null);
+assertEqArray(/\uD83D\uDC38+/u.exec("\uD83D\uDC38\uDC38"),
+ ["\uD83D\uDC38"]);
+
+// no unicode flag
+assertEqArray(/\uD83D\uDC38+/.exec("\u{1F438}"),
+ ["\u{1F438}"]);
+assertEqArray(/\uD83D\uDC38+/.exec("\u{1F438}\u{1F438}"),
+ ["\u{1F438}"]);
+assertEq(/\uD83D\uDC38+/.exec("\uD83D"),
+ null);
+assertEqArray(/\uD83D\uDC38+/.exec("\uD83D\uDC38\uDC38"),
+ ["\uD83D\uDC38\uDC38"]);
+assertEq(/\uD83D\uDC38+/.exec(""),
+ null);
+
+// ==== * ====
+
+assertEqArray(/\uD83D\uDC38*/u.exec("\u{1F438}"),
+ ["\u{1F438}"]);
+assertEqArray(/\uD83D\uDC38*/u.exec("\u{1F438}\u{1F438}"),
+ ["\u{1F438}\u{1F438}"]);
+assertEqArray(/\uD83D\uDC38*/u.exec(""),
+ [""]);
+
+// lead-only target
+assertEqArray(/\uD83D\uDC38*/u.exec("\uD83D"),
+ [""]);
+assertEqArray(/\uD83D\uDC38*/u.exec("\uD83D\uDC38\uDC38"),
+ ["\uD83D\uDC38"]);
+
+// no unicode flag
+assertEqArray(/\uD83D\uDC38*/.exec("\u{1F438}"),
+ ["\u{1F438}"]);
+assertEqArray(/\uD83D\uDC38*/.exec("\u{1F438}\u{1F438}"),
+ ["\u{1F438}"]);
+assertEqArray(/\uD83D\uDC38*/.exec("\uD83D"),
+ ["\uD83D"]);
+assertEqArray(/\uD83D\uDC38*/.exec("\uD83D\uDC38\uDC38"),
+ ["\uD83D\uDC38\uDC38"]);
+assertEq(/\uD83D\uDC38*/.exec(""),
+ null);
+
+// ==== lead-only ====
+
+// match only non-surrogate pair
+assertEqArray(/\uD83D/u.exec("\uD83D\uDBFF"),
+ ["\uD83D"]);
+assertEq(/\uD83D/u.exec("\uD83D\uDC00"),
+ null);
+assertEq(/\uD83D/u.exec("\uD83D\uDFFF"),
+ null);
+assertEqArray(/\uD83D/u.exec("\uD83D\uE000"),
+ ["\uD83D"]);
+
+// match before non-tail char
+assertEqArray(/\uD83D/u.exec("\uD83D"),
+ ["\uD83D"]);
+assertEqArray(/\uD83D/u.exec("\uD83DA"),
+ ["\uD83D"]);
+
+// no unicode flag
+assertEqArray(/\uD83D/.exec("\uD83D\uDBFF"),
+ ["\uD83D"]);
+assertEqArray(/\uD83D/.exec("\uD83D\uDC00"),
+ ["\uD83D"]);
+assertEqArray(/\uD83D/.exec("\uD83D\uDFFF"),
+ ["\uD83D"]);
+assertEqArray(/\uD83D/.exec("\uD83D\uE000"),
+ ["\uD83D"]);
+assertEqArray(/\uD83D/.exec("\uD83D"),
+ ["\uD83D"]);
+assertEqArray(/\uD83D/.exec("\uD83DA"),
+ ["\uD83D"]);
+
+// ==== trail-only ====
+
+// match only non-surrogate pair
+assertEqArray(/\uDC38/u.exec("\uD7FF\uDC38"),
+ ["\uDC38"]);
+assertEq(/\uDC38/u.exec("\uD800\uDC38"),
+ null);
+assertEq(/\uDC38/u.exec("\uDBFF\uDC38"),
+ null);
+assertEqArray(/\uDC38/u.exec("\uDC00\uDC38"),
+ ["\uDC38"]);
+
+// match after non-lead char
+assertEqArray(/\uDC38/u.exec("\uDC38"),
+ ["\uDC38"]);
+assertEqArray(/\uDC38/u.exec("A\uDC38"),
+ ["\uDC38"]);
+
+// no unicode flag
+assertEqArray(/\uDC38/.exec("\uD7FF\uDC38"),
+ ["\uDC38"]);
+assertEqArray(/\uDC38/.exec("\uD800\uDC38"),
+ ["\uDC38"]);
+assertEqArray(/\uDC38/.exec("\uDBFF\uDC38"),
+ ["\uDC38"]);
+assertEqArray(/\uDC38/.exec("\uDC00\uDC38"),
+ ["\uDC38"]);
+assertEqArray(/\uDC38/.exec("\uDC38"),
+ ["\uDC38"]);
+assertEqArray(/\uDC38/.exec("A\uDC38"),
+ ["\uDC38"]);
+
+// ==== invalid trail ====
+
+assertEqArray(/\uD83D\u3042*/u.exec("\uD83D"),
+ ["\uD83D"]);
+assertEqArray(/\uD83D\u3042*/u.exec("\uD83D\u3042"),
+ ["\uD83D\u3042"]);
+assertEqArray(/\uD83D\u3042*/u.exec("\uD83D\u3042\u3042"),
+ ["\uD83D\u3042\u3042"]);
+
+assertEqArray(/\uD83D\u{3042}*/u.exec("\uD83D"),
+ ["\uD83D"]);
+assertEqArray(/\uD83D\u{3042}*/u.exec("\uD83D\u3042"),
+ ["\uD83D\u3042"]);
+assertEqArray(/\uD83D\u{3042}*/u.exec("\uD83D\u3042\u3042"),
+ ["\uD83D\u3042\u3042"]);
+
+assertEqArray(/\uD83DA*/u.exec("\uD83D"),
+ ["\uD83D"]);
+assertEqArray(/\uD83DA*/u.exec("\uD83DA"),
+ ["\uD83DA"]);
+assertEqArray(/\uD83DA*/u.exec("\uD83DAA"),
+ ["\uD83DAA"]);
+
+// ==== wrong patterns ====
+
+assertThrowsInstanceOf(() => eval(`/\\u/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/\\u0/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/\\u00/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/\\u000/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/\\u000G/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/\\u0.00/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/\\uD83D\\u/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/\\uD83D\\u0/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/\\uD83D\\u00/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/\\uD83D\\u000/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/\\uD83D\\u000G/u`), SyntaxError);
+assertThrowsInstanceOf(() => eval(`/\\uD83D\\u0.00/u`), SyntaxError);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/unicode-raw.js b/js/src/tests/ecma_6/RegExp/unicode-raw.js
new file mode 100644
index 000000000..37b572cd8
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/unicode-raw.js
@@ -0,0 +1,139 @@
+var BUGNUMBER = 1135377;
+var summary = "Implement RegExp unicode flag -- raw unicode.";
+
+print(BUGNUMBER + ": " + summary);
+
+// ==== standalone ====
+
+assertEqArray(eval(`/\uD83D\uDC38/u`).exec("\u{1F438}"),
+ ["\u{1F438}"]);
+
+// no unicode flag
+assertEqArray(eval(`/\uD83D\uDC38/`).exec("\u{1F438}"),
+ ["\u{1F438}"]);
+
+// escaped (lead)
+assertEq(eval(`/\\uD83D\uDC38/u`).exec("\u{1F438}"),
+ null);
+assertEq(eval(`/\\u{D83D}\uDC38/u`).exec("\u{1F438}"),
+ null);
+
+// escaped (trail)
+assertEq(eval(`/\uD83D\\uDC38/u`).exec("\u{1F438}"),
+ null);
+assertEq(eval(`/\uD83D\\u{DC38}/u`).exec("\u{1F438}"),
+ null);
+
+// escaped (lead), no unicode flag
+assertEqArray(eval(`/\\uD83D\uDC38/`).exec("\u{1F438}"),
+ ["\u{1F438}"]);
+
+// escaped (trail), no unicode flag
+assertEqArray(eval(`/\uD83D\\uDC38/`).exec("\u{1F438}"),
+ ["\u{1F438}"]);
+
+// ==== RegExp constructor ====
+
+assertEqArray(new RegExp("\uD83D\uDC38", "u").exec("\u{1F438}"),
+ ["\u{1F438}"]);
+
+// no unicode flag
+assertEqArray(new RegExp("\uD83D\uDC38", "").exec("\u{1F438}"),
+ ["\u{1F438}"]);
+
+// escaped(lead)
+assertEq(new RegExp("\\uD83D\uDC38", "u").exec("\u{1F438}"),
+ null);
+assertEq(new RegExp("\\u{D83D}\uDC38", "u").exec("\u{1F438}"),
+ null);
+
+// escaped(trail)
+assertEq(new RegExp("\uD83D\\uDC38", "u").exec("\u{1F438}"),
+ null);
+assertEq(new RegExp("\uD83D\\u{DC38}", "u").exec("\u{1F438}"),
+ null);
+
+// escaped(lead), no unicode flag
+assertEqArray(new RegExp("\\uD83D\uDC38", "").exec("\u{1F438}"),
+ ["\u{1F438}"]);
+
+// escaped(trail), no unicode flag
+assertEqArray(new RegExp("\uD83D\\uDC38", "").exec("\u{1F438}"),
+ ["\u{1F438}"]);
+
+// ==== ? ====
+
+assertEqArray(eval(`/\uD83D\uDC38?/u`).exec("\u{1F438}"),
+ ["\u{1F438}"]);
+assertEqArray(eval(`/\uD83D\uDC38?/u`).exec(""),
+ [""]);
+
+assertEqArray(eval(`/\uD83D\uDC38?/u`).exec("\uD83D"),
+ [""]);
+
+// no unicode flag
+assertEqArray(eval(`/\uD83D\uDC38?/`).exec("\u{1F438}"),
+ ["\u{1F438}"]);
+assertEq(eval(`/\uD83D\uDC38?/`).exec(""),
+ null);
+
+assertEqArray(eval(`/\uD83D\uDC38?/`).exec("\uD83D"),
+ ["\uD83D"]);
+
+// escaped (lead)
+assertEq(eval(`/\\uD83D\uDC38?/u`).exec("\u{1F438}"),
+ null);
+assertEq(eval(`/\\uD83D\uDC38?/u`).exec(""),
+ null);
+
+assertEqArray(eval(`/\\uD83D\uDC38?/u`).exec("\uD83D"),
+ ["\uD83D"]);
+
+// escaped (trail)
+assertEq(eval(`/\uD83D\\uDC38?/u`).exec("\u{1F438}"),
+ null);
+assertEq(eval(`/\uD83D\\uDC38?/u`).exec(""),
+ null);
+
+assertEqArray(eval(`/\uD83D\\uDC38?/u`).exec("\uD83D"),
+ ["\uD83D"]);
+
+// escaped (lead), no unicode flag
+assertEqArray(eval(`/\\uD83D\uDC38?/`).exec("\u{1F438}"),
+ ["\u{1F438}"]);
+assertEq(eval(`/\\uD83D\uDC38?/`).exec(""),
+ null);
+
+assertEqArray(eval(`/\\uD83D\uDC38?/`).exec("\uD83D"),
+ ["\uD83D"]);
+
+// escaped (trail), no unicode flag
+assertEqArray(eval(`/\uD83D\\uDC38?/`).exec("\u{1F438}"),
+ ["\u{1F438}"]);
+assertEq(eval(`/\uD83D\\uDC38?/`).exec(""),
+ null);
+
+assertEqArray(eval(`/\uD83D\\uDC38?/`).exec("\uD83D"),
+ ["\uD83D"]);
+
+// ==== RegExp constructor, ? ====
+
+assertEqArray(new RegExp("\uD83D\uDC38?", "u").exec("\u{1F438}"),
+ ["\u{1F438}"]);
+assertEqArray(new RegExp("\uD83D\uDC38?", "u").exec(""),
+ [""]);
+
+assertEqArray(new RegExp("\uD83D\uDC38?", "u").exec("\uD83D"),
+ [""]);
+
+// no unicode flag
+assertEqArray(new RegExp("\uD83D\uDC38?", "").exec("\u{1F438}"),
+ ["\u{1F438}"]);
+assertEq(new RegExp("\uD83D\uDC38?", "").exec(""),
+ null);
+
+assertEqArray(new RegExp("\uD83D\uDC38?", "").exec("\uD83D"),
+ ["\uD83D"]);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);