Merge V8 5.3.332.45. DO NOT MERGE
Test: Manual
FPIIM-449
Change-Id: Id3254828b068abdea3cb10442e0172a8c9a98e03
(cherry picked from commit 13e2dadd00298019ed862f2b2fc5068bba730bcf)
diff --git a/test/mjsunit/harmony/array-species-constructor-accessor.js b/test/mjsunit/harmony/array-species-constructor-accessor.js
deleted file mode 100644
index 4c852f0..0000000
--- a/test/mjsunit/harmony/array-species-constructor-accessor.js
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2016 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-species --allow-natives-syntax
-
-// Overwriting the constructor of an instance updates the protector
-
-let x = [];
-
-assertEquals(Array, x.map(()=>{}).constructor);
-assertEquals(Array, x.filter(()=>{}).constructor);
-assertEquals(Array, x.slice().constructor);
-assertEquals(Array, x.splice().constructor);
-assertEquals(Array, x.concat([1]).constructor);
-assertEquals(1, x.concat([1])[0]);
-
-class MyArray extends Array { }
-
-Object.defineProperty(x, 'constructor', {get() { return MyArray; }});
-assertFalse(%SpeciesProtector());
-
-assertEquals(MyArray, x.map(()=>{}).constructor);
-assertEquals(MyArray, x.filter(()=>{}).constructor);
-assertEquals(MyArray, x.slice().constructor);
-assertEquals(MyArray, x.splice().constructor);
-assertEquals(MyArray, x.concat([1]).constructor);
-assertEquals(1, x.concat([1])[0]);
diff --git a/test/mjsunit/harmony/array-species-constructor-delete.js b/test/mjsunit/harmony/array-species-constructor-delete.js
deleted file mode 100644
index f341282..0000000
--- a/test/mjsunit/harmony/array-species-constructor-delete.js
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2016 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-species --allow-natives-syntax
-
-// Overwriting the constructor of an instance updates the protector
-
-let x = [];
-
-assertEquals(Array, x.map(()=>{}).constructor);
-assertEquals(Array, x.filter(()=>{}).constructor);
-assertEquals(Array, x.slice().constructor);
-assertEquals(Array, x.splice().constructor);
-assertEquals(Array, x.concat([1]).constructor);
-assertEquals(1, x.concat([1])[0]);
-
-class MyArray extends Array { }
-
-Object.prototype.constructor = MyArray;
-delete Array.prototype.constructor;
-assertFalse(%SpeciesProtector());
-
-assertEquals(MyArray, x.map(()=>{}).constructor);
-assertEquals(MyArray, x.filter(()=>{}).constructor);
-assertEquals(MyArray, x.slice().constructor);
-assertEquals(MyArray, x.splice().constructor);
-assertEquals(MyArray, x.concat([1]).constructor);
-assertEquals(1, x.concat([1])[0]);
diff --git a/test/mjsunit/harmony/array-species-constructor.js b/test/mjsunit/harmony/array-species-constructor.js
deleted file mode 100644
index d766e09..0000000
--- a/test/mjsunit/harmony/array-species-constructor.js
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2016 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-species --allow-natives-syntax
-
-// Overwriting the constructor of an instance updates the protector
-
-let x = [];
-
-assertEquals(Array, x.map(()=>{}).constructor);
-assertEquals(Array, x.filter(()=>{}).constructor);
-assertEquals(Array, x.slice().constructor);
-assertEquals(Array, x.splice().constructor);
-assertEquals(Array, x.concat([1]).constructor);
-assertEquals(1, x.concat([1])[0]);
-
-class MyArray extends Array { }
-
-x.constructor = MyArray;
-assertFalse(%SpeciesProtector());
-
-assertEquals(MyArray, x.map(()=>{}).constructor);
-assertEquals(MyArray, x.filter(()=>{}).constructor);
-assertEquals(MyArray, x.slice().constructor);
-assertEquals(MyArray, x.splice().constructor);
-assertEquals(MyArray, x.concat([1]).constructor);
-assertEquals(1, x.concat([1])[0]);
diff --git a/test/mjsunit/harmony/array-species-delete.js b/test/mjsunit/harmony/array-species-delete.js
deleted file mode 100644
index ba49414..0000000
--- a/test/mjsunit/harmony/array-species-delete.js
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2016 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-species --allow-natives-syntax
-
-// Overwriting the constructor of an instance updates the protector
-
-let x = [];
-
-assertEquals(Array, x.map(()=>{}).constructor);
-assertEquals(Array, x.filter(()=>{}).constructor);
-assertEquals(Array, x.slice().constructor);
-assertEquals(Array, x.splice().constructor);
-assertEquals(Array, x.concat([1]).constructor);
-assertEquals(1, x.concat([1])[0]);
-
-class MyArray extends Array { }
-
-Object.prototype[Symbol.species] = MyArray;
-delete Array[Symbol.species];
-assertFalse(%SpeciesProtector());
-
-assertEquals(MyArray, x.map(()=>{}).constructor);
-assertEquals(MyArray, x.filter(()=>{}).constructor);
-assertEquals(MyArray, x.slice().constructor);
-assertEquals(MyArray, x.splice().constructor);
-assertEquals(MyArray, x.concat([1]).constructor);
-assertEquals(1, x.concat([1])[0]);
diff --git a/test/mjsunit/harmony/array-species-modified.js b/test/mjsunit/harmony/array-species-modified.js
deleted file mode 100644
index 73c52b9..0000000
--- a/test/mjsunit/harmony/array-species-modified.js
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2016 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-species --allow-natives-syntax
-
-// Overwriting Array[Symbol.species] updates the protector
-
-let x = [];
-
-assertEquals(Array, x.map(()=>{}).constructor);
-assertEquals(Array, x.filter(()=>{}).constructor);
-assertEquals(Array, x.slice().constructor);
-assertEquals(Array, x.splice().constructor);
-assertEquals(Array, x.concat([1]).constructor);
-assertEquals(1, x.concat([1])[0]);
-
-class MyArray extends Array { }
-
-Object.defineProperty(Array, Symbol.species, {value: MyArray});
-assertFalse(%SpeciesProtector());
-
-assertEquals(MyArray, x.map(()=>{}).constructor);
-assertEquals(MyArray, x.filter(()=>{}).constructor);
-assertEquals(MyArray, x.slice().constructor);
-assertEquals(MyArray, x.splice().constructor);
-assertEquals(MyArray, x.concat([1]).constructor);
-assertEquals(1, x.concat([1])[0]);
diff --git a/test/mjsunit/harmony/array-species-parent-constructor.js b/test/mjsunit/harmony/array-species-parent-constructor.js
deleted file mode 100644
index 347732e..0000000
--- a/test/mjsunit/harmony/array-species-parent-constructor.js
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2016 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-species --allow-natives-syntax
-
-// Overwriting Array.prototype.constructor updates the protector
-
-let x = [];
-
-assertEquals(Array, x.map(()=>{}).constructor);
-assertEquals(Array, x.filter(()=>{}).constructor);
-assertEquals(Array, x.slice().constructor);
-assertEquals(Array, x.splice().constructor);
-assertEquals(Array, x.concat([1]).constructor);
-assertEquals(1, x.concat([1])[0]);
-
-class MyArray extends Array { }
-
-Array.prototype.constructor = MyArray;
-assertFalse(%SpeciesProtector());
-
-assertEquals(MyArray, x.map(()=>{}).constructor);
-assertEquals(MyArray, x.filter(()=>{}).constructor);
-assertEquals(MyArray, x.slice().constructor);
-assertEquals(MyArray, x.splice().constructor);
-assertEquals(MyArray, x.concat([1]).constructor);
-assertEquals(1, x.concat([1])[0]);
diff --git a/test/mjsunit/harmony/array-species-proto.js b/test/mjsunit/harmony/array-species-proto.js
deleted file mode 100644
index 70db751..0000000
--- a/test/mjsunit/harmony/array-species-proto.js
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2016 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-species --allow-natives-syntax
-
-// Overwriting an array instance's __proto__ updates the protector
-
-let x = [];
-
-assertEquals(Array, x.map(()=>{}).constructor);
-assertEquals(Array, x.filter(()=>{}).constructor);
-assertEquals(Array, x.slice().constructor);
-assertEquals(Array, x.splice().constructor);
-assertEquals(Array, x.concat([1]).constructor);
-assertEquals(1, x.concat([1])[0]);
-
-class MyArray extends Array { }
-
-x.__proto__ = MyArray.prototype;
-assertTrue(%SpeciesProtector());
-
-assertEquals(MyArray, x.map(()=>{}).constructor);
-assertEquals(MyArray, x.filter(()=>{}).constructor);
-assertEquals(MyArray, x.slice().constructor);
-assertEquals(MyArray, x.splice().constructor);
-assertEquals(MyArray, x.concat([1]).constructor);
-assertEquals(1, x.concat([1])[0]);
diff --git a/test/mjsunit/harmony/array-species.js b/test/mjsunit/harmony/array-species.js
deleted file mode 100644
index 19ed1d8..0000000
--- a/test/mjsunit/harmony/array-species.js
+++ /dev/null
@@ -1,173 +0,0 @@
-// Copyright 2015 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-species
-
-// Test the ES2015 @@species feature
-
-'use strict';
-
-// Subclasses of Array construct themselves under map, etc
-
-class MyArray extends Array { }
-
-assertEquals(MyArray, new MyArray().map(()=>{}).constructor);
-assertEquals(MyArray, new MyArray().filter(()=>{}).constructor);
-assertEquals(MyArray, new MyArray().slice().constructor);
-assertEquals(MyArray, new MyArray().splice().constructor);
-assertEquals(MyArray, new MyArray().concat([1]).constructor);
-assertEquals(1, new MyArray().concat([1])[0]);
-
-// Subclasses can override @@species to return the another class
-
-class MyOtherArray extends Array {
- static get [Symbol.species]() { return MyArray; }
-}
-
-assertEquals(MyArray, new MyOtherArray().map(()=>{}).constructor);
-assertEquals(MyArray, new MyOtherArray().filter(()=>{}).constructor);
-assertEquals(MyArray, new MyOtherArray().slice().constructor);
-assertEquals(MyArray, new MyOtherArray().splice().constructor);
-assertEquals(MyArray, new MyOtherArray().concat().constructor);
-
-// Array methods on non-arrays return arrays
-
-class MyNonArray extends Array {
- static get [Symbol.species]() { return MyObject; }
-}
-
-class MyObject { }
-
-assertEquals(MyObject,
- Array.prototype.map.call(new MyNonArray(), ()=>{}).constructor);
-assertEquals(MyObject,
- Array.prototype.filter.call(new MyNonArray(), ()=>{}).constructor);
-assertEquals(MyObject,
- Array.prototype.slice.call(new MyNonArray()).constructor);
-assertEquals(MyObject,
- Array.prototype.splice.call(new MyNonArray()).constructor);
-assertEquals(MyObject,
- Array.prototype.concat.call(new MyNonArray()).constructor);
-
-assertEquals(undefined,
- Array.prototype.map.call(new MyNonArray(), ()=>{}).length);
-assertEquals(undefined,
- Array.prototype.filter.call(new MyNonArray(), ()=>{}).length);
-assertEquals(undefined,
- Array.prototype.concat.call(new MyNonArray(), ()=>{}).length);
-// slice and splice actually do explicitly define the length for some reason
-assertEquals(0, Array.prototype.slice.call(new MyNonArray()).length);
-assertEquals(0, Array.prototype.splice.call(new MyNonArray()).length);
-
-// Cross-realm Arrays build same-realm arrays
-
-var realm = Realm.create();
-assertEquals(Array,
- Array.prototype.map.call(
- Realm.eval(realm, "[]"), ()=>{}).constructor);
-assertFalse(Array === Realm.eval(realm, "[]").map(()=>{}).constructor);
-assertFalse(Array === Realm.eval(realm, "[].map(()=>{}).constructor"));
-assertEquals(Array,
- Array.prototype.concat.call(
- Realm.eval(realm, "[]")).constructor);
-
-// Defaults when constructor or @@species is missing or non-constructor
-
-class MyDefaultArray extends Array {
- static get [Symbol.species]() { return undefined; }
-}
-assertEquals(Array, new MyDefaultArray().map(()=>{}).constructor);
-
-class MyOtherDefaultArray extends Array { }
-assertEquals(MyOtherDefaultArray,
- new MyOtherDefaultArray().map(()=>{}).constructor);
-MyOtherDefaultArray.prototype.constructor = undefined;
-assertEquals(Array, new MyOtherDefaultArray().map(()=>{}).constructor);
-assertEquals(Array, new MyOtherDefaultArray().concat().constructor);
-
-// Exceptions propagated when getting constructor @@species throws
-
-class SpeciesError extends Error { }
-class ConstructorError extends Error { }
-class MyThrowingArray extends Array {
- static get [Symbol.species]() { throw new SpeciesError; }
-}
-assertThrows(() => new MyThrowingArray().map(()=>{}), SpeciesError);
-Object.defineProperty(MyThrowingArray.prototype, 'constructor', {
- get() { throw new ConstructorError; }
-});
-assertThrows(() => new MyThrowingArray().map(()=>{}), ConstructorError);
-
-// Previously unexpected errors from setting properties in arrays throw
-
-class FrozenArray extends Array {
- constructor(...args) {
- super(...args);
- Object.freeze(this);
- }
-}
-assertThrows(() => new FrozenArray([1]).map(()=>0), TypeError);
-assertThrows(() => new FrozenArray([1]).filter(()=>true), TypeError);
-assertThrows(() => new FrozenArray([1]).slice(0, 1), TypeError);
-assertThrows(() => new FrozenArray([1]).splice(0, 1), TypeError);
-assertThrows(() => new FrozenArray([]).concat([1]), TypeError);
-
-// Verify call counts and constructor parameters
-
-var count;
-var params;
-class MyObservedArray extends Array {
- constructor(...args) {
- super(...args);
- params = args;
- }
- static get [Symbol.species]() {
- count++
- return this;
- }
-}
-
-count = 0;
-params = undefined;
-assertEquals(MyObservedArray,
- new MyObservedArray().map(()=>{}).constructor);
-assertEquals(1, count);
-assertArrayEquals([0], params);
-
-count = 0;
-params = undefined;
-assertEquals(MyObservedArray,
- new MyObservedArray().filter(()=>{}).constructor);
-assertEquals(1, count);
-assertArrayEquals([0], params);
-
-count = 0;
-params = undefined;
-assertEquals(MyObservedArray,
- new MyObservedArray().concat().constructor);
-assertEquals(1, count);
-assertArrayEquals([0], params);
-
-count = 0;
-params = undefined;
-assertEquals(MyObservedArray,
- new MyObservedArray().slice().constructor);
-assertEquals(1, count);
-assertArrayEquals([0], params);
-
-count = 0;
-params = undefined;
-assertEquals(MyObservedArray,
- new MyObservedArray().splice().constructor);
-assertEquals(1, count);
-assertArrayEquals([0], params);
-
-// @@species constructor can be a Proxy, and the realm access doesn't
-// crash
-
-class MyProxyArray extends Array { }
-let ProxyArray = new Proxy(MyProxyArray, {});
-MyProxyArray.constructor = ProxyArray;
-
-assertEquals(MyProxyArray, new ProxyArray().map(()=>{}).constructor);
diff --git a/test/mjsunit/harmony/arraybuffer-species.js b/test/mjsunit/harmony/arraybuffer-species.js
deleted file mode 100644
index 0445a4b..0000000
--- a/test/mjsunit/harmony/arraybuffer-species.js
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2015 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-species
-
-// ArrayBuffer.prototype.slice makes subclass and checks length
-
-class MyArrayBuffer extends ArrayBuffer { }
-assertEquals(MyArrayBuffer, new MyArrayBuffer(0).slice().constructor);
-
-class MyShortArrayBuffer extends ArrayBuffer {
- constructor(length) { super(length - 1); }
-}
-assertThrows(() => new MyShortArrayBuffer(5).slice(0, 4), TypeError);
-
-class SingletonArrayBuffer extends ArrayBuffer {
- constructor(...args) {
- if (SingletonArrayBuffer.cached) return SingletonArrayBuffer.cached;
- super(...args);
- SingletonArrayBuffer.cached = this;
- }
-}
-assertThrows(() => new SingletonArrayBuffer(5).slice(0, 4), TypeError);
-
-class NonArrayBuffer extends ArrayBuffer {
- constructor() {
- return {};
- }
-}
-assertThrows(() => new NonArrayBuffer(5).slice(0, 4), TypeError);
-
-// Species fallback is ArrayBuffer
-class UndefinedArrayBuffer extends ArrayBuffer { }
-UndefinedArrayBuffer.prototype.constructor = undefined;
-assertEquals(ArrayBuffer, new UndefinedArrayBuffer(0).slice().constructor);
diff --git a/test/mjsunit/harmony/async-await-basic.js b/test/mjsunit/harmony/async-await-basic.js
index d0888ea..ba0350f 100644
--- a/test/mjsunit/harmony/async-await-basic.js
+++ b/test/mjsunit/harmony/async-await-basic.js
@@ -343,5 +343,27 @@
assertEquals("async x => x", (async x => x).toString());
assertEquals("async x => { return x }", (async x => { return x }).toString());
class AsyncMethod { async foo() { } }
-assertEquals("async foo() { }", Function.prototype.toString.call(AsyncMethod.prototype.foo));
-assertEquals("async foo() { }", Function.prototype.toString.call({async foo() { }}.foo));
+assertEquals("async foo() { }",
+ Function.prototype.toString.call(AsyncMethod.prototype.foo));
+assertEquals("async foo() { }",
+ Function.prototype.toString.call({async foo() { }}.foo));
+
+// Async functions are not constructible
+assertThrows(() => class extends (async function() {}) {}, TypeError);
+
+// Regress v8:5148
+assertEqualsAsync("1", () => (async({ a = NaN }) => a)({ a: "1" }));
+assertEqualsAsync(
+ "10", () => (async(foo, { a = NaN }) => foo + a)("1", { a: "0" }));
+assertEqualsAsync("2", () => (async({ a = "2" }) => a)({ a: undefined }));
+assertEqualsAsync(
+ "20", () => (async(foo, { a = "0" }) => foo + a)("2", { a: undefined }));
+assertThrows(() => eval("async({ foo = 1 })"), SyntaxError);
+assertThrows(() => eval("async(a, { foo = 1 })"), SyntaxError);
+
+// https://bugs.chromium.org/p/chromium/issues/detail?id=638019
+async function gaga() {
+ let i = 1;
+ while (i-- > 0) { await 42 }
+}
+assertDoesNotThrow(gaga);
diff --git a/test/mjsunit/harmony/async-debug-basic.js b/test/mjsunit/harmony/async-debug-basic.js
new file mode 100644
index 0000000..a490972
--- /dev/null
+++ b/test/mjsunit/harmony/async-debug-basic.js
@@ -0,0 +1,40 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-async-await --allow-natives-syntax --expose-debug-as debug
+
+// Get the Debug object exposed from the debug context global object.
+Debug = debug.Debug
+
+listenerComplete = false;
+breakPointCount = 0;
+
+async function f() {
+ await (async function() { var a = "a"; await 1; debugger; })();
+
+ var b = "b";
+
+ assertTrue(listenerDone);
+ assertFalse(exception);
+ assertEquals(1, breakpointCount);
+}
+
+function listener(event, exec_state, event_data, data) {
+ try {
+ if (event != Debug.DebugEvent.Break) return;
+
+ breakpointCount++;
+ listenerDone = true;
+ assertEquals("a", exec_state.frame(0).evaluate("a"));
+ assertEquals("b", exec_state.frame(1).evaluate("b"));
+ assertEquals("c", exec_state.frame(2).evaluate("c"));
+ } catch (e) {
+ exception = e;
+ };
+};
+
+Debug.setListener(listener);
+
+var c = "c";
+f();
diff --git a/test/mjsunit/harmony/async-debug-step-abort-at-break.js b/test/mjsunit/harmony/async-debug-step-abort-at-break.js
new file mode 100644
index 0000000..be1f805
--- /dev/null
+++ b/test/mjsunit/harmony/async-debug-step-abort-at-break.js
@@ -0,0 +1,55 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug --allow-natives-syntax --harmony-async-await
+
+var Debug = debug.Debug;
+var step_count = 0;
+
+function listener(event, execState, eventData, data) {
+ if (event != Debug.DebugEvent.Break) return;
+ try {
+ var line = execState.frame(0).sourceLineText();
+ print(line);
+ var [match, expected_count, step] = /\/\/ B(\d) (\w+)$/.exec(line);
+ assertEquals(step_count++, parseInt(expected_count));
+ if (step != "Continue") execState.prepareStep(Debug.StepAction[step]);
+ } catch (e) {
+ print(e, e.stack);
+ quit(1);
+ }
+}
+
+Debug.setListener(listener);
+
+var late_resolve;
+
+function g() {
+ return new Promise( // B3 StepOut
+ function(res, rej) {
+ late_resolve = res;
+ }
+ );
+}
+
+async function f() {
+ var a = 1;
+ debugger; // B0 StepNext
+ a += // B1 StepNext
+ await // B4 StepNext
+ g(); // B2 StepIn
+ return a;
+}
+
+f();
+
+// Starting a new step action at an intermediate break point
+// means that we will abort the current async step.
+debugger; // B5 StepNext
+
+late_resolve(3); // B6 Continue
+
+%RunMicrotasks();
+
+assertEquals(7, step_count);
diff --git a/test/mjsunit/harmony/async-debug-step-continue-at-break.js b/test/mjsunit/harmony/async-debug-step-continue-at-break.js
new file mode 100644
index 0000000..5099b2f
--- /dev/null
+++ b/test/mjsunit/harmony/async-debug-step-continue-at-break.js
@@ -0,0 +1,55 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug --allow-natives-syntax --harmony-async-await
+
+var Debug = debug.Debug;
+var step_count = 0;
+
+function listener(event, execState, eventData, data) {
+ if (event != Debug.DebugEvent.Break) return;
+ try {
+ var line = execState.frame(0).sourceLineText();
+ print(line);
+ var [match, expected_count, step] = /\/\/ B(\d) (\w+)$/.exec(line);
+ assertEquals(step_count++, parseInt(expected_count));
+ if (step != "Continue") execState.prepareStep(Debug.StepAction[step]);
+ } catch (e) {
+ print(e, e.stack);
+ quit(1);
+ }
+}
+
+Debug.setListener(listener);
+
+var late_resolve;
+
+function g() {
+ return new Promise( // B3 StepOut
+ function(res, rej) {
+ late_resolve = res;
+ }
+ );
+}
+
+async function f() {
+ var a = 1;
+ debugger; // B0 StepNext
+ a += // B1 StepNext
+ await // B4 StepNext
+ g(); // B2 StepIn
+ return a; // B6 StepNext
+} // B7 Continue
+
+f();
+
+// Continuing at an intermediate break point means that we will
+// carry on with the current async step.
+debugger; // B5 Continue
+
+late_resolve(3);
+
+%RunMicrotasks();
+
+assertEquals(8, step_count);
diff --git a/test/mjsunit/harmony/async-debug-step-in-and-out.js b/test/mjsunit/harmony/async-debug-step-in-and-out.js
new file mode 100644
index 0000000..30fe2d6
--- /dev/null
+++ b/test/mjsunit/harmony/async-debug-step-in-and-out.js
@@ -0,0 +1,51 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug --allow-natives-syntax --harmony-async-await
+
+var Debug = debug.Debug;
+var step_count = 0;
+
+function listener(event, execState, eventData, data) {
+ if (event != Debug.DebugEvent.Break) return;
+ try {
+ var line = execState.frame(0).sourceLineText();
+ print(line);
+ var [match, expected_count, step] = /\/\/ B(\d) (\w+)$/.exec(line);
+ assertEquals(step_count++, parseInt(expected_count));
+ if (step != "Continue") execState.prepareStep(Debug.StepAction[step]);
+ } catch (e) {
+ print(e, e.stack);
+ quit(1);
+ }
+}
+
+Debug.setListener(listener);
+
+var late_resolve;
+
+function g() {
+ return new Promise( // B3 StepOut
+ function(res, rej) {
+ late_resolve = res;
+ }
+ );
+}
+
+async function f() {
+ var a = 1;
+ debugger; // B0 StepNext
+ a += // B1 StepNext
+ await // B4 StepNext
+ g(); // B2 StepIn
+ return a; // B5 StepNext
+} // B6 Continue
+
+f();
+
+late_resolve(3);
+
+%RunMicrotasks();
+
+assertEquals(7, step_count);
diff --git a/test/mjsunit/harmony/async-debug-step-in-out-out.js b/test/mjsunit/harmony/async-debug-step-in-out-out.js
new file mode 100644
index 0000000..c2f34bb
--- /dev/null
+++ b/test/mjsunit/harmony/async-debug-step-in-out-out.js
@@ -0,0 +1,51 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug --allow-natives-syntax --harmony-async-await
+
+var Debug = debug.Debug;
+var step_count = 0;
+
+function listener(event, execState, eventData, data) {
+ if (event != Debug.DebugEvent.Break) return;
+ try {
+ var line = execState.frame(0).sourceLineText();
+ print(line);
+ var [match, expected_count, step] = /\/\/ B(\d) (\w+)$/.exec(line);
+ assertEquals(step_count++, parseInt(expected_count));
+ if (step != "Continue") execState.prepareStep(Debug.StepAction[step]);
+ } catch (e) {
+ print(e, e.stack);
+ quit(1);
+ }
+}
+
+Debug.setListener(listener);
+
+var late_resolve;
+
+function g() {
+ return new Promise( // B3 StepOut
+ function(res, rej) {
+ late_resolve = res;
+ }
+ );
+}
+
+async function f() {
+ var a = 1;
+ debugger; // B0 StepNext
+ a += // B1 StepNext
+ await // B4 StepOut
+ g(); // B2 StepIn
+ return a;
+}
+
+f();
+
+late_resolve(3); // B5 Continue
+
+%RunMicrotasks();
+
+assertEquals(6, step_count);
diff --git a/test/mjsunit/harmony/async-debug-step-in.js b/test/mjsunit/harmony/async-debug-step-in.js
new file mode 100644
index 0000000..0a7de1a
--- /dev/null
+++ b/test/mjsunit/harmony/async-debug-step-in.js
@@ -0,0 +1,51 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug --allow-natives-syntax --harmony-async-await
+
+var Debug = debug.Debug;
+var step_count = 0;
+
+function listener(event, execState, eventData, data) {
+ if (event != Debug.DebugEvent.Break) return;
+ try {
+ var line = execState.frame(0).sourceLineText();
+ print(line);
+ var [match, expected_count, step] = /\/\/ B(\d) (\w+)$/.exec(line);
+ assertEquals(step_count++, parseInt(expected_count));
+ if (step != "Continue") execState.prepareStep(Debug.StepAction[step]);
+ } catch (e) {
+ print(e, e.stack);
+ quit(1);
+ }
+}
+
+Debug.setListener(listener);
+
+var late_resolve;
+
+function g() {
+ return new Promise( // B3 StepIn
+ function(res, rej) {
+ late_resolve = res; // B4 StepIn
+ } // B5 StepIn
+ );
+} // B6 StepIn
+
+async function f() {
+ var a = 1;
+ debugger; // B0 StepNext
+ a += // B1 StepIn
+ await // B7 StepIn
+ g(); // B2 StepIn
+ return a; // B8 StepIn
+} // B9 Continue
+
+f().then(value => assertEquals(4, value));
+
+late_resolve(3);
+
+%RunMicrotasks();
+
+assertEquals(10, step_count);
diff --git a/test/mjsunit/harmony/async-debug-step-nested.js b/test/mjsunit/harmony/async-debug-step-nested.js
new file mode 100644
index 0000000..adf7a51
--- /dev/null
+++ b/test/mjsunit/harmony/async-debug-step-nested.js
@@ -0,0 +1,58 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug --allow-natives-syntax --harmony-async-await
+
+var Debug = debug.Debug;
+var step_count = 0;
+
+function listener(event, execState, eventData, data) {
+ if (event != Debug.DebugEvent.Break) return;
+ try {
+ var line = execState.frame(0).sourceLineText();
+ print(line);
+ var [match, expected_count, step] = /\/\/ B(\d) (\w+)$/.exec(line);
+ assertEquals(step_count++, parseInt(expected_count));
+ if (step != "Continue") execState.prepareStep(Debug.StepAction[step]);
+ } catch (e) {
+ print(e, e.stack);
+ quit(1);
+ }
+}
+
+Debug.setListener(listener);
+
+var late_resolve;
+
+function g() {
+ return new Promise( // B4 StepOut
+ function(res, rej) {
+ late_resolve = res;
+ }
+ );
+}
+
+async function f1() {
+ var a = 1;
+ debugger; // B0 StepNext
+ a += // B1 StepNext
+ await // B6 StepNext
+ f2(); // B2 StepIn
+ return a; // B7 StepNext
+} // B8 Continue
+
+async function f2() {
+ var b =
+ await // B5 StepOut
+ g(); // B3 StepIn
+ return b;
+}
+
+f1();
+
+late_resolve(3);
+
+%RunMicrotasks();
+
+assertEquals(9, step_count);
diff --git a/test/mjsunit/harmony/async-debug-step-next-constant.js b/test/mjsunit/harmony/async-debug-step-next-constant.js
new file mode 100644
index 0000000..cea86d7
--- /dev/null
+++ b/test/mjsunit/harmony/async-debug-step-next-constant.js
@@ -0,0 +1,39 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug --allow-natives-syntax --harmony-async-await
+
+var Debug = debug.Debug;
+var step_count = 0;
+
+function listener(event, execState, eventData, data) {
+ if (event != Debug.DebugEvent.Break) return;
+ try {
+ var line = execState.frame(0).sourceLineText();
+ print(line);
+ var [match, expected_count, step] = /\/\/ B(\d) (\w+)$/.exec(line);
+ assertEquals(step_count++, parseInt(expected_count));
+ if (step != "Continue") execState.prepareStep(Debug.StepAction[step]);
+ } catch (e) {
+ print(e, e.stack);
+ quit(1);
+ }
+}
+
+Debug.setListener(listener);
+
+async function f() {
+ var a = 1;
+ debugger; // B0 StepNext
+ a += // B1 StepNext
+ await // B3 StepNext
+ 5; // B2 StepNext
+ return a; // B4 StepNext
+} // B5 Continue
+
+f();
+
+%RunMicrotasks();
+
+assertEquals(6, step_count);
diff --git a/test/mjsunit/harmony/async-debug-step-next.js b/test/mjsunit/harmony/async-debug-step-next.js
new file mode 100644
index 0000000..952d88d
--- /dev/null
+++ b/test/mjsunit/harmony/async-debug-step-next.js
@@ -0,0 +1,51 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug --allow-natives-syntax --harmony-async-await
+
+var Debug = debug.Debug;
+var step_count = 0;
+
+function listener(event, execState, eventData, data) {
+ if (event != Debug.DebugEvent.Break) return;
+ try {
+ var line = execState.frame(0).sourceLineText();
+ print(line);
+ var [match, expected_count, step] = /\/\/ B(\d) (\w+)$/.exec(line);
+ assertEquals(step_count++, parseInt(expected_count));
+ if (step != "Continue") execState.prepareStep(Debug.StepAction[step]);
+ } catch (e) {
+ print(e, e.stack);
+ quit(1);
+ }
+}
+
+Debug.setListener(listener);
+
+var late_resolve;
+
+function g() {
+ return new Promise(
+ function(res, rej) {
+ late_resolve = res;
+ }
+ );
+}
+
+async function f() {
+ var a = 1;
+ debugger; // B0 StepNext
+ a += // B1 StepNext
+ await // B3 StepNext
+ g(); // B2 StepNext
+ return a; // B4 StepNext
+} // B5 Continue
+
+f();
+
+late_resolve(3);
+
+%RunMicrotasks();
+
+assertEquals(6, step_count);
diff --git a/test/mjsunit/harmony/async-debug-step-out.js b/test/mjsunit/harmony/async-debug-step-out.js
new file mode 100644
index 0000000..41779ac
--- /dev/null
+++ b/test/mjsunit/harmony/async-debug-step-out.js
@@ -0,0 +1,49 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug --allow-natives-syntax --harmony-async-await
+
+var Debug = debug.Debug;
+var step_count = 0;
+
+function listener(event, execState, eventData, data) {
+ if (event != Debug.DebugEvent.Break) return;
+ try {
+ var line = execState.frame(0).sourceLineText();
+ print(line);
+ var [match, expected_count, step] = /\/\/ B(\d) (\w+)$/.exec(line);
+ assertEquals(step_count++, parseInt(expected_count));
+ if (step != "Continue") execState.prepareStep(Debug.StepAction[step]);
+ } catch (e) {
+ print(e, e.stack);
+ quit(1);
+ }
+}
+
+Debug.setListener(listener);
+
+var late_resolve;
+
+function g() {
+ return new Promise(
+ function(res, rej) {
+ late_resolve = res;
+ }
+ );
+}
+
+async function f() {
+ var a = 1;
+ debugger; // B0 StepNext
+ a += await g(); // B1 StepOut
+ return a;
+}
+
+f();
+
+late_resolve(3); // B2 Continue
+
+%RunMicrotasks();
+
+assertEquals(3, step_count);
diff --git a/test/mjsunit/harmony/async-function-debug-evaluate.js b/test/mjsunit/harmony/async-function-debug-evaluate.js
new file mode 100644
index 0000000..edf7bca
--- /dev/null
+++ b/test/mjsunit/harmony/async-function-debug-evaluate.js
@@ -0,0 +1,139 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-async-await --expose-debug-as debug
+
+var Debug = debug.Debug;
+var breakPointCount = 0;
+
+function listener(event, exec_state, event_data, data) {
+ if (event != Debug.DebugEvent.Break) return;
+ ++breakPointCount;
+ try {
+ if (breakPointCount === 1) {
+ assertEquals(
+ "inner", exec_state.frame(0).evaluate("inner").value());
+ assertThrows(() => exec_state.frame(0).evaluate("letInner").value(),
+ ReferenceError);
+ assertThrows(() => exec_state.frame(0).evaluate("constInner").value(),
+ ReferenceError);
+
+ assertEquals("outer", exec_state.frame(0).evaluate("outer").value());
+ assertEquals(
+ "const outer", exec_state.frame(0).evaluate("constOuter").value());
+ assertEquals(
+ "let outer", exec_state.frame(0).evaluate("letOuter").value());
+
+ assertEquals("outer", exec_state.frame(1).evaluate("outer").value());
+ assertEquals(
+ "const outer", exec_state.frame(1).evaluate("constOuter").value());
+ assertEquals(
+ "let outer", exec_state.frame(1).evaluate("letOuter").value());
+
+ assertThrows(() => exec_state.frame(0).evaluate("withVar").value(),
+ ReferenceError);
+
+ } else if (breakPointCount === 2) {
+ assertEquals(
+ "inner", exec_state.frame(0).evaluate("inner").value());
+ assertThrows(() => exec_state.frame(0).evaluate("letInner").value(),
+ ReferenceError);
+ assertThrows(() => exec_state.frame(0).evaluate("constInner").value(),
+ ReferenceError);
+
+ assertEquals(57, exec_state.frame(0).evaluate("x").value());
+ assertEquals(100, exec_state.frame(0).evaluate("y").value());
+
+ // From breakPointCount === 1 and later, it's not possible to access
+ // earlier framestates.
+ assertEquals("outer", exec_state.frame(0).evaluate("outer").value());
+ assertEquals(
+ "const outer", exec_state.frame(0).evaluate("constOuter").value());
+ assertEquals(
+ "let outer", exec_state.frame(0).evaluate("letOuter").value());
+
+ exec_state.frame(0).evaluate("x = `x later(${x})`");
+ exec_state.frame(0).evaluate("y = `y later(${y})`");
+ exec_state.frame(0).evaluate("z = `ZEE`");
+
+ } else if (breakPointCount === 3) {
+ assertEquals(
+ "inner", exec_state.frame(0).evaluate("inner").value());
+ assertEquals(
+ "let inner", exec_state.frame(0).evaluate("letInner").value());
+ assertEquals(
+ "const inner", exec_state.frame(0).evaluate("constInner").value());
+
+ } else if (breakPointCount === 4) {
+ assertEquals(
+ "oop", exec_state.frame(0).evaluate("error.message").value());
+ assertEquals(
+ "Error",
+ exec_state.frame(0).evaluate("error.constructor.name").value());
+ assertEquals("floof", exec_state.frame(0).evaluate("bun").value());
+ assertThrows(() => exec_state.frame(0).evaluate("cow").value(),
+ ReferenceError);
+
+ assertEquals("outer", exec_state.frame(0).evaluate("outer").value());
+ assertEquals(
+ "const outer", exec_state.frame(0).evaluate("constOuter").value());
+ assertEquals(
+ "let outer", exec_state.frame(0).evaluate("letOuter").value());
+ }
+ } catch (e) {
+ print(e.stack);
+ quit(1);
+ }
+}
+
+Debug.setListener(listener);
+
+var outer = "outer";
+const constOuter = "const outer";
+let letOuter = "let outer"
+
+async function thrower() {
+ return Promise.reject(new Error("oop"));
+}
+
+async function testLater() {
+ return { x: 57, y: 100 };
+}
+
+async function test() {
+ var inner = "inner";
+ debugger;
+
+ let withVar = await testLater();
+ with (withVar) {
+ debugger;
+ }
+
+ assertEquals("x later(57)", withVar.x);
+ assertEquals("y later(100)", withVar.y);
+ assertEquals(undefined, withVar.z);
+ assertEquals("ZEE", z);
+
+ let letInner = "let inner";
+ const constInner = "const inner";
+ debugger;
+
+ try {
+ await thrower();
+ } catch (error) {
+ const bun = "floof";
+ debugger;
+ let cow = "moo";
+ }
+}
+
+test().
+then(x => {
+ Debug.setListener(null);
+}).
+catch(error => {
+ print(error.stack);
+ quit(1);
+ Debug.setListener(null);
+});
diff --git a/test/mjsunit/harmony/async-function-debug-scopes.js b/test/mjsunit/harmony/async-function-debug-scopes.js
new file mode 100644
index 0000000..3d72549
--- /dev/null
+++ b/test/mjsunit/harmony/async-function-debug-scopes.js
@@ -0,0 +1,616 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-async-await --expose-debug-as debug
+
+var Debug = debug.Debug;
+
+var AsyncFunction = (async function() {}).constructor;
+
+async function thrower() { throw 'Exception'; }
+
+async function test(name, func, args, handler, continuation) {
+ var handler_called = false;
+ var exception = null;
+
+ function listener(event, exec_state, event_data, data) {
+ try {
+ if (event == Debug.DebugEvent.Break) {
+ handler_called = true;
+ handler(exec_state);
+ }
+ } catch (e) {
+ exception = e;
+ }
+ }
+
+ Debug.setListener(listener);
+
+ var result;
+ if (typeof func === "object")
+ result = await func.method.apply(func, args);
+ else
+ result = await func.apply(null, args);
+
+ if (typeof continuation === "function") {
+ await continuation(result);
+ }
+
+ assertTrue(handler_called, `Expected ${name} handler to be called`);
+ if (exception) {
+ exception.message = `${name} / ${exception.message}`;
+ print(exception.stack);
+ quit(1);
+ }
+
+ Debug.setListener(null);
+}
+
+async function runTests() {
+
+// Simple
+await test(
+ "(AsyncFunctionExpression) Local 1",
+ async function() { debugger; }, [],
+ exec_state => {
+ CheckScopeChain([debug.ScopeType.Local,
+ debug.ScopeType.Closure,
+ debug.ScopeType.Script,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({}, 0, exec_state);
+ });
+
+await test(
+ "(AsyncFunctionExpression) Local 1 --- resume normal",
+ async function() { let z = await 2; debugger; }, [],
+ exec_state => {
+ CheckScopeChain([debug.ScopeType.Local,
+ debug.ScopeType.Closure,
+ debug.ScopeType.Script,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({z: 2}, 0, exec_state);
+ });
+
+await test(
+ "(AsyncFunctionExpression) Local 1 --- resume throw",
+ async function() { let q = await 1;
+ try { let z = await thrower(); }
+ catch (e) { debugger; } }, [],
+ exec_state => {
+ CheckScopeChain([debug.ScopeType.Catch,
+ debug.ScopeType.Local,
+ debug.ScopeType.Closure,
+ debug.ScopeType.Script,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({e: 'Exception'}, 0, exec_state);
+ CheckScopeContent({q: 1}, 1, exec_state);
+
+ });
+
+// Simple With Parameter
+await test(
+ "(AsyncFunctionExpression) Local 2",
+ async function(a) { debugger; }, [1],
+ exec_state => {
+ CheckScopeChain([debug.ScopeType.Local,
+ debug.ScopeType.Closure,
+ debug.ScopeType.Script,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({ a: 1 }, 0, exec_state);
+ });
+
+await test(
+ "(AsyncFunctionExpression) Local 2 --- resume normal",
+ async function(a) { let z = await 2; debugger; }, [1],
+ exec_state => {
+ CheckScopeChain([debug.ScopeType.Local,
+ debug.ScopeType.Closure,
+ debug.ScopeType.Script,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({ a: 1, z: 2 }, 0, exec_state);
+ });
+
+await test(
+ "(AsyncFunctionExpression) Local 2 --- resume throw",
+ async function(a) { let z = await 2;
+ try { await thrower(); } catch (e) { debugger; } }, [1],
+ exec_state => {
+ CheckScopeChain([debug.ScopeType.Catch,
+ debug.ScopeType.Local,
+ debug.ScopeType.Closure,
+ debug.ScopeType.Script,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({ e: 'Exception' }, 0, exec_state);
+ CheckScopeContent({ a: 1, z: 2 }, 1, exec_state);
+ });
+
+// Simple With Parameter and Variable
+await test(
+ "(AsyncFunctionExpression) Local 3",
+ async function(a) { var b = 2; debugger; }, [1],
+ exec_state => {
+ CheckScopeChain([debug.ScopeType.Local,
+ debug.ScopeType.Closure,
+ debug.ScopeType.Script,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({ a: 1, b: 2 }, 0, exec_state);
+ });
+
+await test(
+ "(AsyncFunctionExpression) Local 3 --- resume normal",
+ async function(a) { let y = await 3; var b = 2; let z = await 4;
+ debugger; }, [1],
+ exec_state => {
+ CheckScopeChain([debug.ScopeType.Local,
+ debug.ScopeType.Closure,
+ debug.ScopeType.Script,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({ a: 1, b: 2, y: 3, z: 4 }, 0, exec_state);
+ });
+
+await test(
+ "(AsyncFunctionExpression) Local 3 --- resume throw",
+ async function(a) { let y = await 3;
+ try { var b = 2; let z = await thrower(); }
+ catch (e) { debugger; } }, [1],
+ exec_state => {
+ CheckScopeChain([debug.ScopeType.Catch,
+ debug.ScopeType.Local,
+ debug.ScopeType.Closure,
+ debug.ScopeType.Script,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({ e: 'Exception' }, 0, exec_state);
+ CheckScopeContent({ a: 1, b: 2, y: 3 }, 1, exec_state);
+ });
+
+// Local scope with parameters and local variables.
+await test(
+ "(AsyncFunctionExpression) Local 4",
+ async function(a, b) { var x = 3; var y = 4; debugger; }, [1, 2],
+ exec_state => {
+ CheckScopeChain([debug.ScopeType.Local,
+ debug.ScopeType.Closure,
+ debug.ScopeType.Script,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({a:1,b:2,x:3,y:4}, 0, exec_state);
+ });
+
+await test(
+ "(AsyncFunctionExpression) Local 4 --- resume normal",
+ async function(a, b) { let q = await 5; var x = 3; var y = 4;
+ let r = await 6; debugger; }, [1, 2],
+ exec_state => {
+ CheckScopeChain([debug.ScopeType.Local,
+ debug.ScopeType.Closure,
+ debug.ScopeType.Script,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({a:1,b:2,x:3,y:4, q: 5, r: 6}, 0, exec_state);
+ });
+
+await test(
+ "(AsyncFunctionExpression) Local 4 --- resume throw",
+ async function(a, b) { let q = await 5; var x = 3; var y = 4;
+ try { let r = await thrower(); }
+ catch (e) { debugger; } }, [1, 2],
+ exec_state => {
+ CheckScopeChain([debug.ScopeType.Catch,
+ debug.ScopeType.Local,
+ debug.ScopeType.Closure,
+ debug.ScopeType.Script,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({e: 'Exception'}, 0, exec_state);
+ CheckScopeContent({a:1,b:2,x:3,y:4, q: 5}, 1, exec_state);
+ });
+
+// Empty local scope with use of eval.
+await test(
+ "(AsyncFunctionExpression) Local 5",
+ async function() { eval(""); debugger; }, [],
+ exec_state => {
+ CheckScopeChain([debug.ScopeType.Local,
+ debug.ScopeType.Closure,
+ debug.ScopeType.Script,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({}, 0, exec_state);
+ });
+
+await test(
+ "(AsyncFunctionExpression) Local 5 --- resume normal",
+ async function() { let x = await 1; eval(""); let y = await 2;
+ debugger; }, [],
+ exec_state => {
+ CheckScopeChain([debug.ScopeType.Local,
+ debug.ScopeType.Closure,
+ debug.ScopeType.Script,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({ x: 1, y: 2 }, 0, exec_state);
+ });
+
+await test(
+ "(AsyncFunctionExpression) Local 5 --- resume throw",
+ async function() { let x = await 1; eval("");
+ try { let y = await thrower(); }
+ catch (e) { debugger; } }, [],
+ exec_state => {
+ CheckScopeChain([debug.ScopeType.Catch,
+ debug.ScopeType.Local,
+ debug.ScopeType.Closure,
+ debug.ScopeType.Script,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({ e: 'Exception' }, 0, exec_state);
+ CheckScopeContent({ x: 1 }, 1, exec_state);
+ });
+
+// Local introducing local variable using eval.
+await test(
+ "(AsyncFunctionExpression) Local 6",
+ async function() { eval("var i = 5"); debugger; }, [],
+ exec_state => {
+ CheckScopeChain([debug.ScopeType.Local,
+ debug.ScopeType.Closure,
+ debug.ScopeType.Script,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({i:5}, 0, exec_state);
+ });
+
+await test(
+ "(AsyncFunctionExpression) Local 6 --- resume normal",
+ async function() { let x = await 1; eval("var i = 5"); let y = await 2;
+ debugger; }, [],
+ exec_state => {
+ CheckScopeChain([debug.ScopeType.Local,
+ debug.ScopeType.Closure,
+ debug.ScopeType.Script,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({i:5, x: 1, y: 2}, 0, exec_state);
+ });
+
+await test(
+ "(AsyncFunctionExpression) Local 6 --- resume throw",
+ async function() { let x = await 1; eval("var i = 5");
+ try { let y = await thrower(); }
+ catch (e) { debugger; } }, [],
+ exec_state => {
+ CheckScopeChain([debug.ScopeType.Catch,
+ debug.ScopeType.Local,
+ debug.ScopeType.Closure,
+ debug.ScopeType.Script,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({e: 'Exception' }, 0, exec_state);
+ CheckScopeContent({i:5, x: 1}, 1, exec_state);
+ });
+
+// Local scope with parameters, local variables and local variable introduced
+// using eval.
+await test(
+ "(AsyncFunctionExpression) Local 7",
+ async function(a, b) { var x = 3; var y = 4;
+ eval("var i = 5;"); eval("var j = 6");
+ debugger; }, [1, 2],
+ exec_state => {
+ CheckScopeChain([debug.ScopeType.Local,
+ debug.ScopeType.Closure,
+ debug.ScopeType.Script,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6}, 0, exec_state);
+ });
+
+await test(
+ "(AsyncFunctionExpression) Local 7 --- resume normal",
+ async function(a, b) { let z = await 7; var x = 3; var y = 4;
+ eval("var i = 5;"); eval("var j = 6");
+ let q = await 8;
+ debugger; }, [1, 2],
+ exec_state => {
+ CheckScopeChain([debug.ScopeType.Local,
+ debug.ScopeType.Closure,
+ debug.ScopeType.Script,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6, z:7, q:8}, 0, exec_state);
+ });
+
+await test(
+ "(AsyncFunctionExpression) Local 7 --- resume throw",
+ async function(a, b) { let z = await 7; var x = 3; var y = 4;
+ eval("var i = 5;"); eval("var j = 6");
+ try { let q = await thrower(); }
+ catch (e) { debugger; } }, [1, 2],
+ exec_state => {
+ CheckScopeChain([debug.ScopeType.Catch,
+ debug.ScopeType.Local,
+ debug.ScopeType.Closure,
+ debug.ScopeType.Script,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({e: 'Exception'}, 0, exec_state);
+ //CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6, z:7}, 1, exec_state);
+ });
+
+// Nested empty with blocks.
+await test(
+ "(AsyncFunctionExpression) With",
+ async function() { with ({}) { with ({}) { debugger; } } }, [],
+ exec_state => {
+ CheckScopeChain([debug.ScopeType.With,
+ debug.ScopeType.With,
+ debug.ScopeType.Local,
+ debug.ScopeType.Closure,
+ debug.ScopeType.Script,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({}, 0, exec_state);
+ CheckScopeContent({}, 1, exec_state);
+ });
+
+await test(
+ "(AsyncFunctionExpression) With --- resume normal",
+ async function() { let x = await 1; with ({}) { with ({}) {
+ let y = await 2; debugger; } } }, [],
+ exec_state => {
+ CheckScopeChain([debug.ScopeType.Block,
+ debug.ScopeType.With,
+ debug.ScopeType.With,
+ debug.ScopeType.Local,
+ debug.ScopeType.Closure,
+ debug.ScopeType.Script,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({y:2}, 0, exec_state);
+ CheckScopeContent({}, 1, exec_state);
+ CheckScopeContent({}, 2, exec_state);
+ CheckScopeContent({x:1}, 3, exec_state);
+ });
+
+await test(
+ "(AsyncFunctionExpression) With --- resume throw",
+ async function() { let x = await 1; with ({}) { with ({}) {
+ try { let y = await thrower(); }
+ catch (e) { debugger; } } } }, [],
+ exec_state => {
+ CheckScopeChain([debug.ScopeType.Catch,
+ debug.ScopeType.With,
+ debug.ScopeType.With,
+ debug.ScopeType.Local,
+ debug.ScopeType.Closure,
+ debug.ScopeType.Script,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({ e: 'Exception'}, 0, exec_state);
+ CheckScopeContent({}, 1, exec_state);
+ CheckScopeContent({}, 2, exec_state);
+ CheckScopeContent({x:1}, 3, exec_state);
+ });
+
+// Simple closure formed by returning an inner function referering the outer
+// functions arguments.
+await test(
+ "(AsyncFunctionExpression) Closure 1",
+ async function(a) { return function() { debugger; return a; } }, [1],
+ exec_state => {
+ CheckScopeChain([debug.ScopeType.Local,
+ debug.ScopeType.Closure,
+ debug.ScopeType.Closure,
+ debug.ScopeType.Script,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({a:1}, 1, exec_state);
+ },
+ result => result());
+
+await test(
+ "(AsyncFunctionExpression) Closure 1 --- resume normal",
+ async function(a) { let x = await 2;
+ return function() { debugger; return a; } }, [1],
+ exec_state => {
+ CheckScopeChain([debug.ScopeType.Local,
+ debug.ScopeType.Closure,
+ debug.ScopeType.Closure,
+ debug.ScopeType.Script,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({a:1, x: 2}, 1, exec_state);
+ },
+ result => result());
+
+await test(
+ "(AsyncFunctionExpression) Closure 1 --- resume throw",
+ async function(a) { let x = await 2;
+ return async function() {
+ try { await thrower(); }
+ catch (e) { debugger; } return a; }; }, [1],
+ exec_state => {
+ CheckScopeChain([debug.ScopeType.Catch,
+ debug.ScopeType.Local,
+ debug.ScopeType.Closure,
+ debug.ScopeType.Closure,
+ debug.ScopeType.Script,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({e: 'Exception'}, 0, exec_state);
+ CheckScopeContent({a:1, x: 2}, 2, exec_state);
+ },
+ result => result());
+
+await test(
+ "(AsyncFunctionExpression) Catch block 1",
+ async function() { try { throw 'Exception'; } catch (e) { debugger; } }, [],
+ exec_state => {
+ CheckScopeChain([debug.ScopeType.Catch,
+ debug.ScopeType.Local,
+ debug.ScopeType.Closure,
+ debug.ScopeType.Script,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({e:'Exception'}, 0, exec_state);
+ });
+
+await test(
+ "(AsyncFunctionExpression) Catch block 1 --- resume normal",
+ async function() {
+ let x = await 1;
+ try { throw 'Exception'; } catch (e) { let y = await 2; debugger; } }, [],
+ exec_state => {
+ CheckScopeChain([debug.ScopeType.Block,
+ debug.ScopeType.Catch,
+ debug.ScopeType.Local,
+ debug.ScopeType.Closure,
+ debug.ScopeType.Script,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({y: 2}, 0, exec_state);
+ CheckScopeContent({e:'Exception'}, 1, exec_state);
+ CheckScopeContent({x: 1}, 2, exec_state);
+ });
+
+await test(
+ "(AsyncFunctionExpression) Catch block 1 --- resume throw",
+ async function() {
+ let x = await 1;
+ try { throw 'Exception!'; } catch (e) {
+ try { let y = await thrower(); } catch (e) { debugger; } } }, [],
+ exec_state => {
+ CheckScopeChain([debug.ScopeType.Catch,
+ debug.ScopeType.Catch,
+ debug.ScopeType.Local,
+ debug.ScopeType.Closure,
+ debug.ScopeType.Script,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({e:'Exception'}, 0, exec_state);
+ CheckScopeContent({e:'Exception!'}, 1, exec_state);
+ CheckScopeContent({x: 1}, 2, exec_state);
+ });
+}
+
+runTests().catch(error => {
+ print(error.stack);
+ quit(1);
+})
+
+// Check that two scope are the same.
+function assertScopeMirrorEquals(scope1, scope2) {
+ assertEquals(scope1.scopeType(), scope2.scopeType());
+ assertEquals(scope1.frameIndex(), scope2.frameIndex());
+ assertEquals(scope1.scopeIndex(), scope2.scopeIndex());
+ assertPropertiesEqual(
+ scope1.scopeObject().value(), scope2.scopeObject().value());
+}
+
+function CheckFastAllScopes(scopes, exec_state) {
+ var fast_all_scopes = exec_state.frame().allScopes(true);
+ var length = fast_all_scopes.length;
+ assertTrue(scopes.length >= length);
+ for (var i = 0; i < scopes.length && i < length; i++) {
+ var scope = fast_all_scopes[length - i - 1];
+ assertTrue(scope.isScope());
+ assertEquals(scopes[scopes.length - i - 1], scope.scopeType());
+ }
+}
+
+// Check that the scope chain contains the expected types of scopes.
+function CheckScopeChain(scopes, exec_state) {
+ var all_scopes = exec_state.frame().allScopes();
+ assertEquals(
+ scopes.length, all_scopes.length, "FrameMirror.allScopes length");
+ for (var i = 0; i < scopes.length; i++) {
+ var scope = exec_state.frame().scope(i);
+ assertTrue(scope.isScope());
+ assertEquals(scopes[i], scope.scopeType());
+ assertScopeMirrorEquals(all_scopes[i], scope);
+
+ // Check the global object when hitting the global scope.
+ if (scopes[i] == debug.ScopeType.Global) {
+ // Objects don't have same class (one is "global", other is "Object",
+ // so just check the properties directly.
+ assertPropertiesEqual(this, scope.scopeObject().value());
+ }
+ }
+ CheckFastAllScopes(scopes, exec_state);
+
+ // Get the debug command processor.
+ var dcp = exec_state.debugCommandProcessor("unspecified_running_state");
+
+ // Send a scopes request and check the result.
+ var json;
+ var request_json = '{"seq":0,"type":"request","command":"scopes"}';
+ var response_json = dcp.processDebugJSONRequest(request_json);
+ var response = JSON.parse(response_json);
+ assertEquals(scopes.length, response.body.scopes.length);
+ for (var i = 0; i < scopes.length; i++) {
+ var scopeRef = response.body.scopes[i].object.ref;
+ assertEquals(i, response.body.scopes[i].index);
+ assertEquals(scopes[i], response.body.scopes[i].type);
+ if (scopes[i] == debug.ScopeType.Local ||
+ scopes[i] == debug.ScopeType.Script ||
+ scopes[i] == debug.ScopeType.Closure) {
+ assertTrue(response.body.scopes[i].object.ref < 0);
+ } else {
+ assertTrue(response.body.scopes[i].object.ref >= 0);
+ }
+ var found = false;
+ for (var j = 0; j < response.refs.length && !found; j++) {
+ found = response.refs[j].handle == response.body.scopes[i].object.ref;
+ }
+ assertTrue(found, `Scope object ${scopeRef} not found`);
+ }
+}
+
+// Check that the content of the scope is as expected. For functions just check
+// that there is a function.
+function CheckScopeContent(content, number, exec_state) {
+ var scope = exec_state.frame().scope(number);
+ var count = 0;
+ for (var p in content) {
+ var property_mirror = scope.scopeObject().property(p);
+ assertFalse(property_mirror.isUndefined(),
+ `property ${p} not found in scope`);
+ if (typeof(content[p]) === 'function') {
+ assertTrue(property_mirror.value().isFunction());
+ } else {
+ assertEquals(content[p], property_mirror.value().value(),
+ `property ${p} has unexpected value`);
+ }
+ count++;
+ }
+
+ // 'arguments' and might be exposed in the local and closure scope. Just
+ // ignore this.
+ var scope_size = scope.scopeObject().properties().length;
+ if (!scope.scopeObject().property('arguments').isUndefined()) {
+ scope_size--;
+ }
+ // Skip property with empty name.
+ if (!scope.scopeObject().property('').isUndefined()) {
+ scope_size--;
+ }
+
+ if (count != scope_size) {
+ print('Names found in scope:');
+ var names = scope.scopeObject().propertyNames();
+ for (var i = 0; i < names.length; i++) {
+ print(names[i]);
+ }
+ }
+ assertEquals(count, scope_size);
+
+ // Get the debug command processor.
+ var dcp = exec_state.debugCommandProcessor("unspecified_running_state");
+
+ // Send a scope request for information on a single scope and check the
+ // result.
+ var request_json = `{
+ "seq": 0,
+ "type": "request",
+ "command": "scope",
+ "arguments": {
+ "number": `;
+ request_json += scope.scopeIndex();
+ request_json += '}}';
+ var response_json = dcp.processDebugJSONRequest(request_json);
+ var response = JSON.parse(response_json);
+ assertEquals(scope.scopeType(), response.body.type);
+ assertEquals(number, response.body.index);
+ if (scope.scopeType() == debug.ScopeType.Local ||
+ scope.scopeType() == debug.ScopeType.Script ||
+ scope.scopeType() == debug.ScopeType.Closure) {
+ assertTrue(response.body.object.ref < 0);
+ } else {
+ assertTrue(response.body.object.ref >= 0);
+ }
+ var found = false;
+ for (var i = 0; i < response.refs.length && !found; i++) {
+ found = response.refs[i].handle == response.body.object.ref;
+ }
+ assertTrue(found, "Scope object " + response.body.object.ref + " not found");
+}
diff --git a/test/mjsunit/harmony/async-function-stacktrace.js b/test/mjsunit/harmony/async-function-stacktrace.js
new file mode 100644
index 0000000..50df44d
--- /dev/null
+++ b/test/mjsunit/harmony/async-function-stacktrace.js
@@ -0,0 +1,115 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-async-await
+
+async function test(func, funcs) {
+ try {
+ await func();
+ throw new Error("Expected " + func.toString() + " to throw");
+ } catch (e) {
+ var stack = e.stack.split('\n').
+ slice(1).
+ map(line => line.trim()).
+ map(line => line.match(/at (?:(.*) )?.*$/)[1]).
+ filter(x => typeof x === 'string' && x.length);
+
+ assertEquals(funcs, stack, `Unexpected stack trace ${e.stack}`);
+ }
+}
+
+function thrower() { throw new Error("NOPE"); }
+function reject() { return Promise.reject(new Error("NOPE")); }
+
+async function runTests() {
+ await test(async function a() {
+ throw new Error("FAIL");
+ },
+ ["a", "test", "runTests"]);
+
+ await test(async function a2() {
+ await 1;
+ throw new Error("FAIL");
+ }, ["a2"]);
+
+ await test(async function a3() {
+ await 1;
+ try { await thrower(); } catch (e) { throw new Error("FAIL"); }
+ }, ["a3"]);
+
+ await test(async function a4() {
+ await 1;
+ try { await reject(); } catch (e) { throw new Error("FAIL"); }
+ }, ["a4"]);
+
+ await test({ async b() {
+ throw new Error("FAIL");
+ }}.b,
+ ["b", "test", "runTests"]);
+
+ await test({ async b2() {
+ await 1;
+ throw new Error("FAIL");
+ }}.b2, ["b2"]);
+
+ await test({ async b3() {
+ await 1;
+ try { await thrower(); } catch (e) { throw new Error("FAIL"); }
+ } }.b3, ["b3"]);
+
+ await test({ async b4() {
+ await 1;
+ try { await reject(); } catch (e) { throw new Error("FAIL"); }
+ } }.b4, ["b4"]);
+
+ await test((new class { async c() {
+ throw new Error("FAIL");
+ } }).c,
+ ["c", "test", "runTests"]);
+
+ await test((new class { async c2() {
+ await 1;
+ throw new Error("FAIL");
+ } }).c2, ["c2"]);
+
+ await test((new class { async c3() {
+ await 1;
+ try { await thrower(); } catch (e) { throw new Error("FAIL"); }
+ } }).c3, ["c3"]);
+
+ await test((new class { async c4() {
+ await 1;
+ try { await reject(); } catch (e) { throw new Error("FAIL"); }
+ } }).c4, ["c4"]);
+
+ // TODO(caitp): `async` probably shouldn't be the inferred name for async
+ // arrow functions...
+ await test(async() => { throw new Error("FAIL") },
+ ["async", "test", "runTests"]);
+
+ await test(async() => { await 1; throw new Error("FAIL") }, ["async"]);
+
+ await test(async() => {
+ await 1;
+ try {
+ await thrower();
+ } catch (e) {
+ throw new Error("FAIL");
+ }
+ }, ["e"]); // TODO(caitp): FuncNameInferer is doing some weird stuff...
+
+ await test(async() => {
+ await 1;
+ try {
+ await reject();
+ } catch (e) {
+ throw new Error("FAIL");
+ }
+ }, ["e"]);
+}
+
+runTests().catch(e => {
+ print(e);
+ quit(1);
+});
diff --git a/test/mjsunit/harmony/debug-async-break-on-stack.js b/test/mjsunit/harmony/debug-async-break-on-stack.js
new file mode 100644
index 0000000..d3d9d8b
--- /dev/null
+++ b/test/mjsunit/harmony/debug-async-break-on-stack.js
@@ -0,0 +1,78 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug
+// Flags: --harmony-async-await --allow-natives-syntax
+
+var Debug = debug.Debug;
+
+function assertEqualsAsync(expected, run, msg) {
+ var actual;
+ var hadValue = false;
+ var hadError = false;
+ var promise = run();
+
+ if (typeof promise !== "object" || typeof promise.then !== "function") {
+ throw new MjsUnitAssertionError(
+ "Expected " + run.toString() +
+ " to return a Promise, but it returned " + promise);
+ }
+
+ promise.then(function(value) { hadValue = true; actual = value; },
+ function(error) { hadError = true; actual = error; });
+
+ assertFalse(hadValue || hadError);
+
+ %RunMicrotasks();
+
+ if (hadError) throw actual;
+
+ assertTrue(
+ hadValue, "Expected '" + run.toString() + "' to produce a value");
+
+ assertEquals(expected, actual, msg);
+}
+
+var break_count = 0;
+var exception = null;
+
+function listener(event, exec_state, event_data, data) {
+ if (event != Debug.DebugEvent.Break) return;
+ try {
+ break_count++;
+ var line = exec_state.frame(0).sourceLineText();
+ print(line);
+ assertTrue(line.indexOf(`B${break_count}`) > 0);
+ } catch (e) {
+ exception = e;
+ }
+}
+
+
+async function g() {
+ setbreaks();
+ throw 1; // B1
+}
+
+async function f() {
+ try {
+ await g();
+ } catch (e) {}
+ return 2; // B2
+}
+
+function setbreaks() {
+ Debug.setListener(listener);
+ Debug.setBreakPoint(g, 2);
+ Debug.setBreakPoint(f, 4);
+}
+
+f();
+
+%RunMicrotasks();
+
+assertEqualsAsync(2, async () => break_count);
+assertEqualsAsync(null, async () => exception);
+
+Debug.setListener(null);
diff --git a/test/mjsunit/harmony/debug-async-break.js b/test/mjsunit/harmony/debug-async-break.js
new file mode 100644
index 0000000..3b6b71b
--- /dev/null
+++ b/test/mjsunit/harmony/debug-async-break.js
@@ -0,0 +1,76 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug
+// Flags: --harmony-async-await --allow-natives-syntax
+
+var Debug = debug.Debug;
+
+function assertEqualsAsync(expected, run, msg) {
+ var actual;
+ var hadValue = false;
+ var hadError = false;
+ var promise = run();
+
+ if (typeof promise !== "object" || typeof promise.then !== "function") {
+ throw new MjsUnitAssertionError(
+ "Expected " + run.toString() +
+ " to return a Promise, but it returned " + promise);
+ }
+
+ promise.then(function(value) { hadValue = true; actual = value; },
+ function(error) { hadError = true; actual = error; });
+
+ assertFalse(hadValue || hadError);
+
+ %RunMicrotasks();
+
+ if (hadError) throw actual;
+
+ assertTrue(
+ hadValue, "Expected '" + run.toString() + "' to produce a value");
+
+ assertEquals(expected, actual, msg);
+}
+
+var break_count = 0;
+var exception = null;
+
+function listener(event, exec_state, event_data, data) {
+ if (event != Debug.DebugEvent.Break) return;
+ try {
+ break_count++;
+ var line = exec_state.frame(0).sourceLineText();
+ assertTrue(line.indexOf(`B${break_count}`) > 0);
+ } catch (e) {
+ exception = e;
+ }
+}
+
+Debug.setListener(listener);
+
+async function g() {
+ throw 1;
+}
+
+async function f() {
+ try {
+ await g(); // B1
+ } catch (e) {}
+ assertEquals(2, break_count); // B2
+ return 1; // B3
+}
+
+Debug.setBreakPoint(f, 2);
+Debug.setBreakPoint(f, 4);
+Debug.setBreakPoint(f, 5);
+
+f();
+
+%RunMicrotasks();
+
+assertEqualsAsync(3, async () => break_count);
+assertEqualsAsync(null, async () => exception);
+
+Debug.setListener(null);
diff --git a/test/mjsunit/harmony/debug-async-function-async-task-event.js b/test/mjsunit/harmony/debug-async-function-async-task-event.js
new file mode 100644
index 0000000..249f02f
--- /dev/null
+++ b/test/mjsunit/harmony/debug-async-function-async-task-event.js
@@ -0,0 +1,70 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-async-await --expose-debug-as debug --allow-natives-syntax
+
+Debug = debug.Debug;
+
+var base_id = -1;
+var exception = null;
+var expected = [
+ "enqueue #1",
+ "willHandle #1",
+ "then #1",
+ "enqueue #2",
+ "enqueue #3",
+ "didHandle #1",
+ "willHandle #2",
+ "then #2",
+ "didHandle #2",
+ "willHandle #3",
+ "enqueue #4",
+ "didHandle #3",
+ "willHandle #4",
+ "didHandle #4",
+];
+
+function assertLog(msg) {
+ print(msg);
+ assertTrue(expected.length > 0);
+ assertEquals(expected.shift(), msg);
+ if (!expected.length) {
+ Debug.setListener(null);
+ }
+}
+
+function listener(event, exec_state, event_data, data) {
+ if (event != Debug.DebugEvent.AsyncTaskEvent) return;
+ try {
+ if (base_id < 0)
+ base_id = event_data.id();
+ var id = event_data.id() - base_id + 1;
+ assertTrue("Promise.resolve" == event_data.name() ||
+ "PromiseResolveThenableJob" == event_data.name());
+ assertLog(event_data.type() + " #" + id);
+ } catch (e) {
+ print(e + e.stack)
+ exception = e;
+ }
+}
+
+Debug.setListener(listener);
+
+var resolver;
+var p = new Promise(function(resolve, reject) {
+ resolver = resolve;
+});
+
+async function main() {
+ await p;
+ assertLog("then #1");
+ await undefined;
+ assertLog("then #2");
+}
+main();
+resolver();
+
+%RunMicrotasks();
+
+assertNull(exception);
diff --git a/test/mjsunit/harmony/debug-async-liveedit.js b/test/mjsunit/harmony/debug-async-liveedit.js
new file mode 100644
index 0000000..c651ddb
--- /dev/null
+++ b/test/mjsunit/harmony/debug-async-liveedit.js
@@ -0,0 +1,133 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-async-await
+// Flags: --expose-debug-as debug --allow-natives-syntax --ignition-generators
+
+var Debug = debug.Debug;
+var LiveEdit = Debug.LiveEdit;
+
+unique_id = 0;
+
+var AsyncFunction = (async function(){}).constructor;
+
+function assertPromiseValue(value, promise) {
+ promise.then(resolve => {
+ went = true;
+ if (resolve !== value) {
+ print(`expected ${value} found ${resolve}`);
+ quit(1);
+ }
+ }, reject => {
+ print(`rejected ${reject}`);
+ quit(1);
+ });
+}
+
+function MakeAsyncFunction() {
+ // Prevents eval script caching.
+ unique_id++;
+ return AsyncFunction('callback',
+ "/* " + unique_id + "*/\n" +
+ "await callback();\n" +
+ "return 'Cat';\n");
+}
+
+function MakeFunction() {
+ // Prevents eval script caching.
+ unique_id++;
+ return Function('callback',
+ "/* " + unique_id + "*/\n" +
+ "callback();\n" +
+ "return 'Cat';\n");
+}
+
+// First, try MakeGenerator with no perturbations.
+(function(){
+ var asyncfn = MakeAsyncFunction();
+ function callback() {};
+ var promise = asyncfn(callback);
+ assertPromiseValue('Cat', promise);
+})();
+
+function patch(fun, from, to) {
+ function debug() {
+ var log = new Array();
+ var script = Debug.findScript(fun);
+ var pos = script.source.indexOf(from);
+ print(`pos ${pos}`);
+ try {
+ LiveEdit.TestApi.ApplySingleChunkPatch(script, pos, from.length, to,
+ log);
+ } finally {
+ print("Change log: " + JSON.stringify(log) + "\n");
+ }
+ }
+ %ExecuteInDebugContext(debug);
+}
+
+// Try to edit a MakeAsyncFunction while it's running, then again while it's
+// stopped.
+(function(){
+ var asyncfn = MakeAsyncFunction();
+
+ var patch_attempted = false;
+ function attempt_patch() {
+ assertFalse(patch_attempted);
+ patch_attempted = true;
+ assertThrows(function() { patch(asyncfn, "'Cat'", "'Capybara'") },
+ LiveEdit.Failure);
+ };
+ var promise = asyncfn(attempt_patch);
+ // Patch should not succeed because there is a live async function activation
+ // on the stack.
+ assertPromiseValue("Cat", promise);
+ assertTrue(patch_attempted);
+
+ %RunMicrotasks();
+
+ // At this point one iterator is live, but closed, so the patch will succeed.
+ patch(asyncfn, "'Cat'", "'Capybara'");
+ promise = asyncfn(function(){});
+ // Patch successful.
+ assertPromiseValue("Capybara", promise);
+
+ // Patching will fail however when an async function is suspended.
+ var resolve;
+ promise = asyncfn(function(){return new Promise(function(r){resolve = r})});
+ assertThrows(function() { patch(asyncfn, "'Capybara'", "'Tapir'") },
+ LiveEdit.Failure);
+ resolve();
+ assertPromiseValue("Capybara", promise);
+
+ // Try to patch functions with activations inside and outside async
+ // function activations. We should succeed in the former case, but not in the
+ // latter.
+ var fun_outside = MakeFunction();
+ var fun_inside = MakeFunction();
+ var fun_patch_attempted = false;
+ var fun_patch_restarted = false;
+ function attempt_fun_patches() {
+ if (fun_patch_attempted) {
+ assertFalse(fun_patch_restarted);
+ fun_patch_restarted = true;
+ return;
+ }
+ fun_patch_attempted = true;
+ // Patching outside an async function activation must fail.
+ assertThrows(function() { patch(fun_outside, "'Cat'", "'Cobra'") },
+ LiveEdit.Failure);
+ // Patching inside an async function activation may succeed.
+ patch(fun_inside, "'Cat'", "'Koala'");
+ }
+ promise = asyncfn(function() { return fun_inside(attempt_fun_patches) });
+ assertEquals('Cat',
+ fun_outside(function () {
+ assertPromiseValue('Capybara', promise);
+ assertTrue(fun_patch_restarted);
+ assertTrue(fun_inside.toString().includes("'Koala'"));
+ }));
+})();
+
+%RunMicrotasks();
diff --git a/test/mjsunit/harmony/function-name.js b/test/mjsunit/harmony/function-name.js
deleted file mode 100644
index 66a69e0..0000000
--- a/test/mjsunit/harmony/function-name.js
+++ /dev/null
@@ -1,372 +0,0 @@
-// Copyright 2015 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// Flags: --harmony-function-name
-
-(function testVariableDeclarationsFunction() {
- 'use strict';
- var a = function(){};
- assertEquals('a', a.name);
- let b = () => {};
- assertEquals('b', b.name);
- const c = ((function(){}));
- assertEquals('c', c.name);
-
- var x = function(){}, y = () => {}, z = function withName() {};
- assertEquals('x', x.name);
- assertEquals('y', y.name);
- assertEquals('withName', z.name);
-})();
-
-(function testVariableDeclarationsClass() {
- 'use strict';
- var a = class {};
- assertEquals('a', a.name);
- let b = ((class {}));
- assertEquals('b', b.name);
- // Should not overwrite name property.
- const c = class { static name() { } }
- assertEquals('function', typeof c.name);
-
- var x = class {}, y = class NamedClass {};
- assertEquals('x', x.name);
- assertEquals('NamedClass', y.name);
-})();
-
-(function testObjectProperties() {
- 'use strict';
- var obj = {
- a: function() {},
- b: () => {},
- c() { },
- get d() { },
- set d(val) { },
- x: function withName() { },
- y: class { },
- z: class ClassName { },
- 42: function() {},
- 4.2: function() {},
- __proto__: function() {},
- };
-
- assertEquals('a', obj.a.name);
- assertEquals('b', obj.b.name);
- assertEquals('c', obj.c.name);
- var dDescriptor = Object.getOwnPropertyDescriptor(obj, 'd');
- assertEquals('get d', dDescriptor.get.name);
- assertEquals('set d', dDescriptor.set.name);
- assertEquals('withName', obj.x.name);
- assertEquals('y', obj.y.name);
- assertEquals('ClassName', obj.z.name);
- assertEquals('42', obj[42].name);
- assertEquals('4.2', obj[4.2].name);
- assertEquals('', obj.__proto__.name);
-})();
-
-(function testClassProperties() {
- 'use strict';
- class C {
- a() { }
- static b() { }
- get c() { }
- set c(val) { }
- 42() { }
- static 43() { }
- get 44() { }
- set 44(val) { }
- };
-
- assertEquals('a', C.prototype.a.name);
- assertEquals('b', C.b.name);
- var descriptor = Object.getOwnPropertyDescriptor(C.prototype, 'c');
- assertEquals('get c', descriptor.get.name);
- assertEquals('set c', descriptor.set.name);
- assertEquals('42', C.prototype[42].name);
- assertEquals('43', C[43].name);
- var descriptor = Object.getOwnPropertyDescriptor(C.prototype, '44');
- assertEquals('get 44', descriptor.get.name);
- assertEquals('set 44', descriptor.set.name);
-})();
-
-(function testComputedProperties() {
- 'use strict';
- var a = 'a';
- var b = 'b';
- var sym1 = Symbol('1');
- var sym2 = Symbol('2');
- var sym3 = Symbol('3');
- var symNoDescription = Symbol();
- var obj = {
- [a]: function() {},
- [sym1]: function() {},
- [sym2]: function withName() {},
- [symNoDescription]: function() {},
-
- get [sym3]() {},
- set [b](val) {},
- };
-
- assertEquals('a', obj[a].name);
- assertEquals('[1]', obj[sym1].name);
- assertEquals('withName', obj[sym2].name);
- assertEquals('', obj[symNoDescription].name);
-
- assertEquals('get [3]', Object.getOwnPropertyDescriptor(obj, sym3).get.name);
- assertEquals('set b', Object.getOwnPropertyDescriptor(obj, 'b').set.name);
-
- var objMethods = {
- [a]() {},
- [sym1]() {},
- [symNoDescription]: function() {},
- };
-
- assertEquals('a', objMethods[a].name);
- assertEquals('[1]', objMethods[sym1].name);
- assertEquals('', objMethods[symNoDescription].name);
-
- class C {
- [a]() { }
- [sym1]() { }
- static [sym2]() { }
- [symNoDescription]() { }
-
- get [sym3]() { }
- static set [b](val) { }
- }
-
- assertEquals('a', C.prototype[a].name);
- assertEquals('[1]', C.prototype[sym1].name);
- assertEquals('[2]', C[sym2].name);
- assertEquals('', C.prototype[symNoDescription].name);
-
- assertEquals('get [3]', Object.getOwnPropertyDescriptor(C.prototype, sym3).get.name);
- assertEquals('set b', Object.getOwnPropertyDescriptor(C, 'b').set.name);
-})();
-
-
-(function testAssignment() {
- var basicFn, arrowFn, generatorFn, classLit;
-
- basicFn = function() { return true; };
- assertEquals('basicFn', basicFn.name);
- var basicFn2 = basicFn;
- assertEquals('basicFn', basicFn2.name);
- basicFn = function functionWithName() { };
- assertEquals("functionWithName", basicFn.name);
-
- arrowFn = x => x;
- assertEquals('arrowFn', arrowFn.name);
- var arrowFn2 = arrowFn;
- assertEquals('arrowFn', arrowFn2.name);
-
- generatorFn = function*() { yield true; };
- assertEquals('generatorFn', generatorFn.name);
- var generatorFn2 = generatorFn;
- assertEquals('generatorFn', generatorFn2.name);
- generatorFn = function* generatorWithName() { };
- assertEquals("generatorWithName", generatorFn.name);
-
- classLit = class { constructor() {} };
- assertEquals('classLit', classLit.name);
- var classLit2 = classLit;
- assertEquals('classLit', classLit2.name);
- classLit = class classWithName { constructor() {} };
- assertEquals('classWithName', classLit.name);
- classLit = class { constructor() {} static name() {} };
- assertEquals('function', typeof classLit.name);
- classLit = class { constructor() {} static get name() { return true; } };
- assertTrue(classLit.name);
- classLit = class { constructor() {} static ['name']() {} };
- assertEquals('function', typeof classLit.name);
- classLit = class { constructor() {} static get ['name']() { return true; } };
- assertTrue(classLit.name);
-})();
-
-(function testObjectBindingPattern() {
- var {
- a = function() {},
- b = () => {},
- x = function withName() { },
- y = class { },
- z = class ClassName { },
- q = class { static name() { return 42 } },
- foo: bar = function() {},
- inParens = (() => {}),
- inManyParens = ((((() => {})))),
- } = {};
- assertEquals('a', a.name);
- assertEquals('b', b.name);
- assertEquals('withName', x.name);
- assertEquals('y', y.name);
- assertEquals('ClassName', z.name);
- assertEquals('function', typeof q.name);
- assertEquals('bar', bar.name);
- assertEquals('inParens', inParens.name)
- assertEquals('inManyParens', inManyParens.name)
-})();
-
-(function testArrayBindingPattern() {
- var [
- a = function() {},
- b = () => {},
- x = function withName() { },
- y = class { },
- z = class ClassName { },
- q = class { static name() { return 42 } },
- inParens = (() => {}),
- inManyParens = ((((() => {})))),
- ] = [];
- assertEquals('a', a.name);
- assertEquals('b', b.name);
- assertEquals('withName', x.name);
- assertEquals('y', y.name);
- assertEquals('ClassName', z.name);
- assertEquals('function', typeof q.name);
- assertEquals('inParens', inParens.name)
- assertEquals('inManyParens', inManyParens.name)
-})();
-
-(function testObjectAssignmentPattern() {
- var a, b, x, y, z, q;
- ({
- a = function() {},
- b = () => {},
- x = function withName() { },
- y = class { },
- z = class ClassName { },
- q = class { static name() { return 42 } },
- foo: bar = function() {},
- inParens = (() => {}),
- inManyParens = ((((() => {})))),
- } = {});
- assertEquals('a', a.name);
- assertEquals('b', b.name);
- assertEquals('withName', x.name);
- assertEquals('y', y.name);
- assertEquals('ClassName', z.name);
- assertEquals('function', typeof q.name);
- assertEquals('bar', bar.name);
- assertEquals('inParens', inParens.name)
- assertEquals('inManyParens', inManyParens.name)
-})();
-
-(function testArrayAssignmentPattern() {
- var a, b, x, y, z, q;
- [
- a = function() {},
- b = () => {},
- x = function withName() { },
- y = class { },
- z = class ClassName { },
- q = class { static name() { return 42 } },
- inParens = (() => {}),
- inManyParens = ((((() => {})))),
- ] = [];
- assertEquals('a', a.name);
- assertEquals('b', b.name);
- assertEquals('withName', x.name);
- assertEquals('y', y.name);
- assertEquals('ClassName', z.name);
- assertEquals('function', typeof q.name);
- assertEquals('inParens', inParens.name)
- assertEquals('inManyParens', inManyParens.name)
-})();
-
-(function testParameterDestructuring() {
- (function({ a = function() {},
- b = () => {},
- x = function withName() { },
- y = class { },
- z = class ClassName { },
- q = class { static name() { return 42 } },
- foo: bar = function() {},
- inParens = (() => {}),
- inManyParens = ((((() => {})))) }) {
- assertEquals('a', a.name);
- assertEquals('b', b.name);
- assertEquals('withName', x.name);
- assertEquals('y', y.name);
- assertEquals('ClassName', z.name);
- assertEquals('function', typeof q.name);
- assertEquals('bar', bar.name);
- assertEquals('inParens', inParens.name)
- assertEquals('inManyParens', inManyParens.name)
- })({});
-
- (function([ a = function() {},
- b = () => {},
- x = function withName() { },
- y = class { },
- z = class ClassName { },
- q = class { static name() { return 42 } },
- inParens = (() => {}),
- inManyParens = ((((() => {})))) ]) {
- assertEquals('a', a.name);
- assertEquals('b', b.name);
- assertEquals('withName', x.name);
- assertEquals('y', y.name);
- assertEquals('ClassName', z.name);
- assertEquals('function', typeof q.name);
- assertEquals('inParens', inParens.name)
- assertEquals('inManyParens', inManyParens.name)
- })([]);
-})();
-
-(function testDefaultParameters() {
- (function(a = function() {},
- b = () => {},
- x = function withName() { },
- y = class { },
- z = class ClassName { },
- q = class { static name() { return 42 } },
- inParens = (() => {}),
- inManyParens = ((((() => {}))))) {
- assertEquals('a', a.name);
- assertEquals('b', b.name);
- assertEquals('withName', x.name);
- assertEquals('y', y.name);
- assertEquals('ClassName', z.name);
- assertEquals('function', typeof q.name);
- assertEquals('inParens', inParens.name)
- assertEquals('inManyParens', inManyParens.name)
- })();
-})();
-
-(function testComputedNameNotShared() {
- function makeClass(propName) {
- return class {
- static [propName]() {}
- }
- }
-
- var sym1 = Symbol('1');
- var sym2 = Symbol('2');
- var class1 = makeClass(sym1);
- assertEquals('[1]', class1[sym1].name);
- var class2 = makeClass(sym2);
- assertEquals('[2]', class2[sym2].name);
- assertEquals('[1]', class1[sym1].name);
-})();
-
-
-(function testComputedNamesOnlyAppliedSyntactically() {
- function factory() { return () => {}; }
-
- var obj = { ['foo']: factory() };
- assertEquals('', obj.foo.name);
-})();
-
-
-(function testNameNotReflectedInToString() {
- var f = function() {};
- var g = function*() {};
- var obj = {
- ['h']: function() {},
- i: () => {}
- };
- assertEquals('function () {}', f.toString());
- assertEquals('function* () {}', g.toString());
- assertEquals('function () {}', obj.h.toString());
- assertEquals('() => {}', obj.i.toString());
-})();
diff --git a/test/mjsunit/harmony/generators-turbo.js b/test/mjsunit/harmony/generators-turbo.js
new file mode 100644
index 0000000..23913e4
--- /dev/null
+++ b/test/mjsunit/harmony/generators-turbo.js
@@ -0,0 +1,655 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --ignition --ignition-generators --harmony-do-expressions
+// Flags: --allow-natives-syntax --turbo --turbo-from-bytecode
+
+
+// This file is identical to mjsunit/harmony/generators.js, except for its Flags
+// lines. The purpose is to explicitly mention --turbo-from-bytecode such that
+// Clusterfuzz can thoroughly test the new generators implementation.
+
+
+function MaybeOptimizeOrDeoptimize(f) {
+ let x = Math.random(); // --random-seed makes this deterministic
+ if (x <= 0.33) {
+ %OptimizeFunctionOnNextCall(f);
+ } else if (x <= 0.66) {
+ %DeoptimizeFunction(f);
+ }
+}
+
+function Next(generator, ...args) {
+ MaybeOptimizeOrDeoptimize(%GeneratorGetFunction(generator));
+ return generator.next(...args);
+}
+
+function Return(generator, ...args) {
+ MaybeOptimizeOrDeoptimize(%GeneratorGetFunction(generator));
+ return generator.return(...args);
+}
+
+function Throw(generator, ...args) {
+ MaybeOptimizeOrDeoptimize(%GeneratorGetFunction(generator));
+ return generator.throw(...args);
+}
+
+
+{ // yield in try-catch
+
+ let g = function*() {
+ try {yield 1} catch (error) {assertEquals("caught", error)}
+ };
+
+ assertThrowsEquals(() => Throw(g(), "not caught"), "not caught");
+
+ {
+ let x = g();
+ assertEquals({value: 1, done: false}, Next(x));
+ assertEquals({value: undefined, done: true}, Throw(x, "caught"));
+ }
+
+ {
+ let x = g();
+ assertEquals({value: 1, done: false}, Next(x));
+ assertEquals({value: undefined, done: true}, Next(x));
+ assertThrowsEquals(() => Throw(x, "not caught"), "not caught");
+ }
+}
+
+
+{ // return that doesn't close
+ let g = function*() { try {return 42} finally {yield 43} };
+
+ {
+ let x = g();
+ assertEquals({value: 43, done: false}, Next(x));
+ assertEquals({value: 42, done: true}, Next(x));
+ }
+}
+
+
+{ // return that doesn't close
+ let x;
+ let g = function*() { try {return 42} finally {Throw(x, 666)} };
+
+ {
+ x = g();
+ assertThrows(() => Next(x), TypeError); // still executing
+ }
+}
+
+
+{ // yield in try-finally, finally clause performs return
+
+ let g = function*() { try {yield 42} finally {return 13} };
+
+ { // "return" closes at suspendedStart
+ let x = g();
+ assertEquals({value: 666, done: true}, Return(x, 666));
+ assertEquals({value: undefined, done: true}, Next(x, 42));
+ assertThrowsEquals(() => Throw(x, 43), 43);
+ assertEquals({value: 42, done: true}, Return(x, 42));
+ }
+
+ { // "throw" closes at suspendedStart
+ let x = g();
+ assertThrowsEquals(() => Throw(x, 666), 666);
+ assertEquals({value: undefined, done: true}, Next(x, 42));
+ assertEquals({value: 43, done: true}, Return(x, 43));
+ assertThrowsEquals(() => Throw(x, 44), 44);
+ }
+
+ { // "next" closes at suspendedYield
+ let x = g();
+ assertEquals({value: 42, done: false}, Next(x));
+ assertEquals({value: 13, done: true}, Next(x, 666));
+ assertEquals({value: undefined, done: true}, Next(x, 666));
+ assertThrowsEquals(() => Throw(x, 666), 666);
+ }
+
+ { // "return" closes at suspendedYield
+ let x = g();
+ assertEquals({value: 42, done: false}, Next(x));
+ assertEquals({value: 13, done: true}, Return(x, 666));
+ assertEquals({value: undefined, done: true}, Next(x, 666));
+ assertEquals({value: 666, done: true}, Return(x, 666));
+ }
+
+ { // "throw" closes at suspendedYield
+ let x = g();
+ assertEquals({value: 42, done: false}, Next(x));
+ assertEquals({value: 13, done: true}, Throw(x, 666));
+ assertThrowsEquals(() => Throw(x, 666), 666);
+ assertEquals({value: undefined, done: true}, Next(x, 666));
+ }
+}
+
+
+{ // yield in try-finally, finally clause doesn't perform return
+
+ let g = function*() { try {yield 42} finally {13} };
+
+ { // "return" closes at suspendedStart
+ let x = g();
+ assertEquals({value: 666, done: true}, Return(x, 666));
+ assertEquals({value: undefined, done: true}, Next(x, 42));
+ assertThrowsEquals(() => Throw(x, 43), 43);
+ assertEquals({value: 42, done: true}, Return(x, 42));
+ }
+
+ { // "throw" closes at suspendedStart
+ let x = g();
+ assertThrowsEquals(() => Throw(x, 666), 666);
+ assertEquals({value: undefined, done: true}, Next(x, 42));
+ assertEquals({value: 43, done: true}, Return(x, 43));
+ assertThrowsEquals(() => Throw(x, 44), 44);
+ }
+
+ { // "next" closes at suspendedYield
+ let x = g();
+ assertEquals({value: 42, done: false}, Next(x));
+ assertEquals({value: undefined, done: true}, Next(x, 666));
+ assertEquals({value: undefined, done: true}, Next(x, 666));
+ assertThrowsEquals(() => Throw(x, 666), 666);
+ assertEquals({value: 42, done: true}, Return(x, 42));
+ }
+
+ { // "return" closes at suspendedYield
+ let x = g();
+ assertEquals({value: 42, done: false}, Next(x));
+ assertEquals({value: 666, done: true}, Return(x, 666));
+ assertEquals({value: undefined, done: true}, Next(x, 666));
+ assertThrowsEquals(() => Throw(x, 44), 44);
+ assertEquals({value: 42, done: true}, Return(x, 42));
+ }
+
+ { // "throw" closes at suspendedYield
+ let x = g();
+ assertEquals({value: 42, done: false}, Next(x));
+ assertThrowsEquals(() => Throw(x, 666), 666);
+ assertEquals({value: undefined, done: true}, Next(x, 666));
+ assertThrowsEquals(() => Throw(x, 666), 666);
+ assertEquals({value: 42, done: true}, Return(x, 42));
+ }
+}
+
+
+{ // yield in try-finally, finally clause yields and performs return
+
+ let g = function*() { try {yield 42} finally {yield 43; return 13} };
+
+ {
+ let x = g();
+ assertEquals({value: 42, done: false}, Next(x));
+ assertEquals({value: 43, done: false}, Return(x, 666));
+ assertEquals({value: 13, done: true}, Next(x));
+ assertEquals({value: 666, done: true}, Return(x, 666));
+ }
+
+ {
+ let x = g();
+ assertEquals({value: 666, done: true}, Return(x, 666));
+ assertEquals({value: undefined, done: true}, Next(x));
+ assertEquals({value: 666, done: true}, Return(x, 666));
+ }
+}
+
+
+{ // yield in try-finally, finally clause yields and doesn't perform return
+
+ let g = function*() { try {yield 42} finally {yield 43; 13} };
+
+ {
+ let x = g();
+ assertEquals({value: 42, done: false}, Next(x));
+ assertEquals({value: 43, done: false}, Return(x, 666));
+ assertEquals({value: 666, done: true}, Next(x));
+ assertEquals({value: 5, done: true}, Return(x, 5));
+ }
+
+ {
+ let x = g();
+ assertEquals({value: 666, done: true}, Return(x, 666));
+ assertEquals({value: undefined, done: true}, Next(x));
+ assertEquals({value: 666, done: true}, Return(x, 666));
+ }
+}
+
+
+{ // yield*, finally clause performs return
+
+ let h = function*() { try {yield 42} finally {yield 43; return 13} };
+ let g = function*() { yield 1; yield yield* h(); };
+
+ {
+ let x = g();
+ assertEquals({value: 1, done: false}, Next(x));
+ assertEquals({value: 42, done: false}, Next(x));
+ assertEquals({value: 43, done: false}, Next(x, 666));
+ assertEquals({value: 13, done: false}, Next(x));
+ assertEquals({value: undefined, done: true}, Next(x));
+ }
+
+ {
+ let x = g();
+ assertEquals({value: 1, done: false}, Next(x));
+ assertEquals({value: 42, done: false}, Next(x));
+ assertEquals({value: 43, done: false}, Return(x, 666));
+ assertEquals({value: 13, done: false}, Next(x));
+ assertEquals({value: undefined, done: true}, Next(x));
+ }
+
+ {
+ let x = g();
+ assertEquals({value: 1, done: false}, Next(x));
+ assertEquals({value: 42, done: false}, Next(x));
+ assertEquals({value: 43, done: false}, Throw(x, 666));
+ assertEquals({value: 13, done: false}, Next(x));
+ assertEquals({value: undefined, done: true}, Next(x));
+ }
+}
+
+
+{ // yield*, finally clause does not perform return
+
+ let h = function*() { try {yield 42} finally {yield 43; 13} };
+ let g = function*() { yield 1; yield yield* h(); };
+
+ {
+ let x = g();
+ assertEquals({value: 1, done: false}, Next(x));
+ assertEquals({value: 42, done: false}, Next(x));
+ assertEquals({value: 43, done: false}, Next(x, 666));
+ assertEquals({value: undefined, done: false}, Next(x));
+ assertEquals({value: undefined, done: true}, Next(x));
+ }
+
+ {
+ let x = g();
+ assertEquals({value: 1, done: false}, Next(x));
+ assertEquals({value: 42, done: false}, Next(x));
+ assertEquals({value: 43, done: false}, Return(x, 44));
+ assertEquals({value: 44, done: false}, Next(x));
+ assertEquals({value: undefined, done: true}, Next(x));
+ }
+
+ {
+ let x = g();
+ assertEquals({value: 1, done: false}, Next(x));
+ assertEquals({value: 42, done: false}, Next(x));
+ assertEquals({value: 43, done: false}, Throw(x, 666));
+ assertThrowsEquals(() => Next(x), 666);
+ }
+}
+
+
+{ // yield*, .return argument is final result
+
+ function* inner() {
+ yield 2;
+ }
+
+ function* g() {
+ yield 1;
+ return yield* inner();
+ }
+
+ {
+ let x = g();
+ assertEquals({value: 1, done: false}, Next(x));
+ assertEquals({value: 2, done: false}, Next(x));
+ assertEquals({value: 42, done: true}, Return(x, 42));
+ }
+}
+
+
+// More or less random tests from here on.
+
+
+{
+ function* foo() { }
+ let g = foo();
+ assertEquals({value: undefined, done: true}, Next(g));
+ assertEquals({value: undefined, done: true}, Next(g));
+}
+
+{
+ function* foo() { return new.target }
+ let g = foo();
+ assertEquals({value: undefined, done: true}, Next(g));
+ assertEquals({value: undefined, done: true}, Next(g));
+}
+
+{
+ function* foo() { throw 666; return 42}
+ let g = foo();
+ assertThrowsEquals(() => Next(g), 666);
+ assertEquals({value: undefined, done: true}, Next(g));
+}
+
+{
+ function* foo(a) { return a; }
+ let g = foo(42);
+ assertEquals({value: 42, done: true}, Next(g));
+ assertEquals({value: undefined, done: true}, Next(g));
+}
+
+{
+ function* foo(a) { a.iwashere = true; return a; }
+ let x = {};
+ let g = foo(x);
+ assertEquals({value: {iwashere: true}, done: true}, Next(g));
+ assertEquals({value: undefined, done: true}, Next(g));
+}
+
+{
+ let a = 42;
+ function* foo() { return a; }
+ let g = foo();
+ assertEquals({value: 42, done: true}, Next(g));
+ assertEquals({value: undefined, done: true}, Next(g));
+}
+
+{
+ let a = 40;
+ function* foo(b) { return a + b; }
+ let g = foo(2);
+ assertEquals({value: 42, done: true}, Next(g));
+ assertEquals({value: undefined, done: true}, Next(g));
+}
+
+{
+ let a = 40;
+ function* foo(b) { a--; b++; return a + b; }
+ let g = foo(2);
+ assertEquals({value: 42, done: true}, Next(g));
+ assertEquals({value: undefined, done: true}, Next(g));
+}
+
+{
+ let g;
+ function* foo() { Next(g) }
+ g = foo();
+ assertThrows(() => Next(g), TypeError);
+ assertEquals({value: undefined, done: true}, Next(g));
+}
+
+{
+ function* foo() { yield 2; yield 3; yield 4 }
+ g = foo();
+ assertEquals({value: 2, done: false}, Next(g));
+ assertEquals({value: 3, done: false}, Next(g));
+ assertEquals({value: 4, done: false}, Next(g));
+ assertEquals({value: undefined, done: true}, Next(g));
+ assertEquals({value: undefined, done: true}, Next(g));
+}
+
+
+{
+ function* foo() { yield 2; if (true) { yield 3 }; yield 4 }
+ g = foo();
+ assertEquals({value: 2, done: false}, Next(g));
+ assertEquals({value: 3, done: false}, Next(g));
+ assertEquals({value: 4, done: false}, Next(g));
+ assertEquals({value: undefined, done: true}, Next(g));
+ assertEquals({value: undefined, done: true}, Next(g));
+}
+
+{
+ function* foo() { yield 2; if (true) { yield 3; yield 4 } }
+ g = foo();
+ assertEquals({value: 2, done: false}, Next(g));
+ assertEquals({value: 3, done: false}, Next(g));
+ assertEquals({value: 4, done: false}, Next(g));
+ assertEquals({value: undefined, done: true}, Next(g));
+ assertEquals({value: undefined, done: true}, Next(g));
+}
+
+{
+ function* foo() { yield 2; if (false) { yield 3 }; yield 4 }
+ g = foo();
+ assertEquals({value: 2, done: false}, Next(g));
+ assertEquals({value: 4, done: false}, Next(g));
+ assertEquals({value: undefined, done: true}, Next(g));
+ assertEquals({value: undefined, done: true}, Next(g));
+}
+
+{
+ function* foo() { yield 2; while (true) { yield 3 }; yield 4 }
+ g = foo();
+ assertEquals({value: 2, done: false}, Next(g));
+ assertEquals({value: 3, done: false}, Next(g));
+ assertEquals({value: 3, done: false}, Next(g));
+ assertEquals({value: 3, done: false}, Next(g));
+ assertEquals({value: 3, done: false}, Next(g));
+}
+
+{
+ function* foo() { yield 2; (yield 3) + 42; yield 4 }
+ g = foo();
+ assertEquals({value: 2, done: false}, Next(g));
+ assertEquals({value: 3, done: false}, Next(g));
+ assertEquals({value: 4, done: false}, Next(g));
+}
+
+{
+ function* foo() { yield 2; (do {yield 3}) + 42; yield 4 }
+ g = foo();
+ assertEquals({value: 2, done: false}, Next(g));
+ assertEquals({value: 3, done: false}, Next(g));
+ assertEquals({value: 4, done: false}, Next(g));
+}
+
+{
+ function* foo() { yield 2; return (yield 3) + 42; yield 4 }
+ g = foo();
+ assertEquals({value: 2, done: false}, Next(g));
+ assertEquals({value: 3, done: false}, Next(g));
+ assertEquals({value: 42, done: true}, Next(g, 0));
+ assertEquals({value: undefined, done: true}, Next(g));
+}
+
+{
+ let x = 42;
+ function* foo() {
+ yield x;
+ for (let x in {a: 1, b: 2}) {
+ let i = 2;
+ yield x;
+ yield i;
+ do {
+ yield i;
+ } while (i-- > 0);
+ }
+ yield x;
+ return 5;
+ }
+ g = foo();
+ assertEquals({value: 42, done: false}, Next(g));
+ assertEquals({value: 'a', done: false}, Next(g));
+ assertEquals({value: 2, done: false}, Next(g));
+ assertEquals({value: 2, done: false}, Next(g));
+ assertEquals({value: 1, done: false}, Next(g));
+ assertEquals({value: 0, done: false}, Next(g));
+ assertEquals({value: 'b', done: false}, Next(g));
+ assertEquals({value: 2, done: false}, Next(g));
+ assertEquals({value: 2, done: false}, Next(g));
+ assertEquals({value: 1, done: false}, Next(g));
+ assertEquals({value: 0, done: false}, Next(g));
+ assertEquals({value: 42, done: false}, Next(g));
+ assertEquals({value: 5, done: true}, Next(g));
+}
+
+{
+ let a = 3;
+ function* foo() {
+ let b = 4;
+ yield 1;
+ { let c = 5; yield 2; yield a; yield b; yield c; }
+ }
+ g = foo();
+ assertEquals({value: 1, done: false}, Next(g));
+ assertEquals({value: 2, done: false}, Next(g));
+ assertEquals({value: 3, done: false}, Next(g));
+ assertEquals({value: 4, done: false}, Next(g));
+ assertEquals({value: 5, done: false}, Next(g));
+ assertEquals({value: undefined, done: true}, Next(g));
+}
+
+{
+ function* foo() {
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ yield 42;
+ }
+ g = foo();
+ for (let i = 0; i < 100; ++i) {
+ assertEquals({value: 42, done: false}, i%25 === 0 ? Next(g) : g.next());
+ }
+ assertEquals({value: undefined, done: true}, Next(g));
+}
+
+{
+ function* foo() {
+ for (let i = 0; i < 3; ++i) {
+ let j = 0
+ yield i;
+ do {
+ yield (i + 10);
+ } while (++j < 2);
+ }
+ }
+ g = foo();
+ assertEquals({value: 0, done: false}, Next(g));
+ assertEquals({value: 10, done: false}, Next(g));
+ assertEquals({value: 10, done: false}, Next(g));
+ assertEquals({value: 1, done: false}, Next(g));
+ assertEquals({value: 11, done: false}, Next(g));
+ assertEquals({value: 11, done: false}, Next(g));
+ assertEquals({value: 2, done: false}, Next(g));
+ assertEquals({value: 12, done: false}, Next(g));
+ assertEquals({value: 12, done: false}, Next(g));
+ assertEquals({value: undefined, done: true}, Next(g));
+}
+
+{
+ let foo = function*() {
+ while (true) {
+ if (true || false) yield 42;
+ continue;
+ }
+ }
+ g = foo();
+ assertEquals({value: 42, done: false}, Next(g));
+ assertEquals({value: 42, done: false}, Next(g));
+ assertEquals({value: 42, done: false}, Next(g));
+}
+
+{
+ let foo = function*() {
+ yield* (function*() { yield 42; }());
+ assertUnreachable();
+ }
+ g = foo();
+ assertEquals({value: 42, done: false}, Next(g));
+ assertEquals({value: 23, done: true}, Return(g, 23));
+}
diff --git a/test/mjsunit/harmony/generators.js b/test/mjsunit/harmony/generators.js
index 895a248..eb4e51e 100644
--- a/test/mjsunit/harmony/generators.js
+++ b/test/mjsunit/harmony/generators.js
@@ -648,15 +648,3 @@
assertEquals({value: 42, done: false}, Next(g));
assertEquals({value: 23, done: true}, Return(g, 23));
}
-
-{
- let iterable = {
- [Symbol.iterator]() {
- return { next() { return {} } };
- }
- };
- let foo = function*() { yield* iterable };
- g = foo();
- g.next();
- assertThrows(() => Throw(g), TypeError);
-}
diff --git a/test/mjsunit/harmony/instanceof-es6.js b/test/mjsunit/harmony/instanceof-es6.js
deleted file mode 100644
index 4971c9c..0000000
--- a/test/mjsunit/harmony/instanceof-es6.js
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2016 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-instanceof
-
-// Make sure it's an error if @@hasInstance isn't a function.
-(function() {
- var F = {};
- F[Symbol.hasInstance] = null;
- assertThrows(function() { 0 instanceof F; }, TypeError);
-})();
-
-// Make sure the result is coerced to boolean.
-(function() {
- var F = {};
- F[Symbol.hasInstance] = function() { return undefined; };
- assertEquals(0 instanceof F, false);
- F[Symbol.hasInstance] = function() { return null; };
- assertEquals(0 instanceof F, false);
- F[Symbol.hasInstance] = function() { return true; };
- assertEquals(0 instanceof F, true);
-})();
-
-// Make sure if @@hasInstance throws, we catch it.
-(function() {
- var F = {};
- F[Symbol.hasInstance] = function() { throw new Error("always throws"); }
- try {
- 0 instanceof F;
- } catch (e) {
- assertEquals(e.message, "always throws");
- }
-})();
-
-// @@hasInstance works for bound functions.
-(function() {
- var BC = function() {};
- var bc = new BC();
- var bound = BC.bind();
- assertEquals(bound[Symbol.hasInstance](bc), true);
- assertEquals(bound[Symbol.hasInstance]([]), false);
-})();
-
-// if OrdinaryHasInstance is passed a non-callable receiver, return false.
-assertEquals(Function.prototype[Symbol.hasInstance].call(Array, []), true);
-assertEquals(Function.prototype[Symbol.hasInstance].call({}, {}), false);
-
-// OrdinaryHasInstance passed a non-object argument returns false.
-assertEquals(Function.prototype[Symbol.hasInstance].call(Array, 0), false);
-
-// Cannot assign to @@hasInstance with %FunctionPrototype%.
-(function() {
- "use strict";
- function F() {}
- assertThrows(function() { F[Symbol.hasInstance] = (v) => v }, TypeError);
-})();
-
-// Check correct invocation of @@hasInstance handler on function instance.
-(function() {
- function F() {}
- var counter = 0;
- var proto = Object.getPrototypeOf(F);
- Object.setPrototypeOf(F, null);
- F[Symbol.hasInstance] = function(v) { ++counter; return true };
- Object.setPrototypeOf(F, proto);
- assertTrue(1 instanceof F);
- assertEquals(1, counter);
-})();
diff --git a/test/mjsunit/harmony/iterator-close.js b/test/mjsunit/harmony/iterator-close.js
deleted file mode 100644
index 03cdeac..0000000
--- a/test/mjsunit/harmony/iterator-close.js
+++ /dev/null
@@ -1,1372 +0,0 @@
-// Copyright 2016 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-iterator-close
-
-
-function* g() { yield 42; return 88 };
-
-
-// Return method is "undefined".
-{
- g.prototype.return = null;
-
-
- assertEquals(undefined, (() => {
- for (var x of g()) { break; }
- })());
-
- assertEquals(undefined, (() => {
- for (let x of g()) { break; }
- })());
-
- assertEquals(undefined, (() => {
- for (const x of g()) { break; }
- })());
-
- assertEquals(undefined, (() => {
- for (x of g()) { break; }
- })());
-
-
- assertThrowsEquals(() => {
- for (var x of g()) { throw 42; }
- }, 42);
-
- assertThrowsEquals(() => {
- for (let x of g()) { throw 42; }
- }, 42);
-
- assertThrowsEquals(() => {
- for (const x of g()) { throw 42; }
- }, 42);
-
- assertThrowsEquals(() => {
- for (x of g()) { throw 42; }
- }, 42);
-
-
- assertEquals(42, (() => {
- for (var x of g()) { return 42; }
- })());
-
- assertEquals(42, (() => {
- for (let x of g()) { return 42; }
- })());
-
- assertEquals(42, (() => {
- for (const x of g()) { return 42; }
- })());
-
- assertEquals(42, (() => {
- for (x of g()) { return 42; }
- })());
-
-
- assertEquals(42, eval('for (var x of g()) { x; }'));
-
- assertEquals(42, eval('for (let x of g()) { x; }'));
-
- assertEquals(42, eval('for (const x of g()) { x; }'));
-
- assertEquals(42, eval('for (x of g()) { x; }'));
-
-
- assertEquals(42, (() => {
- var [x] = g(); return x;
- })());
-
- assertEquals(42, (() => {
- let [x] = g(); return x;
- })());
-
- assertEquals(42, (() => {
- const [x] = g(); return x;
- })());
-
- assertEquals(42, (() => {
- [x] = g(); return x;
- })());
-
- assertEquals(42,
- (([x]) => x)(g())
- );
-}
-
-
-// Return method is not callable.
-{
- g.prototype.return = 666;
-
-
- assertThrows(() => {
- for (var x of g()) { break; }
- }, TypeError);
-
- assertThrows(() => {
- for (let x of g()) { break; }
- }, TypeError);
-
- assertThrows(() => {
- for (const x of g()) { break; }
- }, TypeError);
-
- assertThrows(() => {
- for (x of g()) { break; }
- }, TypeError);
-
-
- assertThrows(() => {
- for (var x of g()) { throw 666; }
- }, TypeError);
-
- assertThrows(() => {
- for (let x of g()) { throw 666; }
- }, TypeError);
-
- assertThrows(() => {
- for (const x of g()) { throw 666; }
- }, TypeError);
-
- assertThrows(() => {
- for (x of g()) { throw 666; }
- }, TypeError);
-
-
- assertThrows(() => {
- for (var x of g()) { return 666; }
- }, TypeError);
-
- assertThrows(() => {
- for (let x of g()) { return 666; }
- }, TypeError);
-
- assertThrows(() => {
- for (const x of g()) { return 666; }
- }, TypeError);
-
- assertThrows(() => {
- for (x of g()) { return 666; }
- }, TypeError);
-
-
- assertEquals(42, eval('for (var x of g()) { x; }'));
-
- assertEquals(42, eval('for (let x of g()) { x; }'));
-
- assertEquals(42, eval('for (const x of g()) { x; }'));
-
- assertEquals(42, eval('for (x of g()) { x; }'));
-
-
- assertThrows(() => {
- var [x] = g(); return x;
- }, TypeError);
-
- assertThrows(() => {
- let [x] = g(); return x;
- }, TypeError);
-
- assertThrows(() => {
- const [x] = g(); return x;
- }, TypeError);
-
- assertThrows(() => {
- [x] = g(); return x;
- }, TypeError);
-
- assertThrows(() => {
- (([x]) => x)(g());
- }, TypeError);
-}
-
-
-// Return method does not return an object.
-{
- g.prototype.return = () => 666;
-
-
- assertThrows(() => {
- for (var x of g()) { break; }
- }, TypeError);
-
- assertThrows(() => {
- for (let x of g()) { break; }
- }, TypeError);
-
- assertThrows(() => {
- for (const x of g()) { break; }
- }, TypeError);
-
- assertThrows(() => {
- for (x of g()) { break; }
- }, TypeError);
-
-
- // Throw from the body of a for loop 'wins' vs throw
- // originating from a bad 'return' value.
-
- assertThrowsEquals(() => {
- for (var x of g()) { throw 666; }
- }, 666);
-
- assertThrowsEquals(() => {
- for (let x of g()) { throw 666; }
- }, 666);
-
- assertThrowsEquals(() => {
- for (const x of g()) { throw 666; }
- }, 666);
-
- assertThrowsEquals(() => {
- for (x of g()) { throw 666; }
- }, 666);
-
-
- assertThrows(() => {
- for (var x of g()) { return 666; }
- }, TypeError);
-
- assertThrows(() => {
- for (let x of g()) { return 666; }
- }, TypeError);
-
- assertThrows(() => {
- for (const x of g()) { return 666; }
- }, TypeError);
-
- assertThrows(() => {
- for (x of g()) { return 666; }
- }, TypeError);
-
-
- assertEquals(42, eval('for (var x of g()) { x; }'));
-
- assertEquals(42, eval('for (let x of g()) { x; }'));
-
- assertEquals(42, eval('for (const x of g()) { x; }'));
-
- assertEquals(42, eval('for (x of g()) { x; }'));
-
-
- assertThrows(() => {
- var [x] = g(); return x;
- }, TypeError);
-
- assertThrows(() => {
- let [x] = g(); return x;
- }, TypeError);
-
- assertThrows(() => {
- const [x] = g(); return x;
- }, TypeError);
-
- assertThrows(() => {
- [x] = g(); return x;
- }, TypeError);
-
- assertThrows(() => {
- (([x]) => x)(g());
- }, TypeError);
-}
-
-
-// Return method returns an object.
-{
- let log = [];
- g.prototype.return = (...args) => { log.push(args); return {} };
-
-
- log = [];
- for (var x of g()) { break; }
- assertEquals([[]], log);
-
- log = [];
- for (let x of g()) { break; }
- assertEquals([[]], log);
-
- log = [];
- for (const x of g()) { break; }
- assertEquals([[]], log);
-
- log = [];
- for (x of g()) { break; }
- assertEquals([[]], log);
-
-
- log = [];
- assertThrowsEquals(() => {
- for (var x of g()) { throw 42; }
- }, 42);
- assertEquals([[]], log);
-
- log = [];
- assertThrowsEquals(() => {
- for (let x of g()) { throw 42; }
- }, 42);
- assertEquals([[]], log);
-
- log = [];
- assertThrowsEquals(() => {
- for (const x of g()) { throw 42; }
- }, 42);
- assertEquals([[]], log);
-
- log = [];
- assertThrowsEquals(() => {
- for (x of g()) { throw 42; }
- }, 42);
- assertEquals([[]], log);
-
-
- log = [];
- assertEquals(42, (() => {
- for (var x of g()) { return 42; }
- })());
- assertEquals([[]], log);
-
- log = [];
- assertEquals(42, (() => {
- for (let x of g()) { return 42; }
- })());
- assertEquals([[]], log);
-
- log = [];
- assertEquals(42, (() => {
- for (const x of g()) { return 42; }
- })());
- assertEquals([[]], log);
-
- log = [];
- assertEquals(42, (() => {
- for (x of g()) { return 42; }
- })());
- assertEquals([[]], log);
-
-
- log = [];
- assertEquals(42, eval('for (var x of g()) { x; }'));
- assertEquals([], log);
-
- log = [];
- assertEquals(42, eval('for (let x of g()) { x; }'));
- assertEquals([], log);
-
- log = [];
- assertEquals(42, eval('for (const x of g()) { x; }'));
- assertEquals([], log);
-
- log = [];
- assertEquals(42, eval('for (x of g()) { x; }'));
- assertEquals([], log);
-
-
- // Even if doing the assignment throws, still call return
- log = [];
- x = { set attr(_) { throw 1234; } };
- assertThrowsEquals(() => {
- for (x.attr of g()) { throw 456; }
- }, 1234);
- assertEquals([[]], log);
-
-
- log = [];
- assertEquals(42, (() => {
- var [x] = g(); return x;
- })());
- assertEquals([[]], log);
-
- log = [];
- assertEquals(42, (() => {
- let [x] = g(); return x;
- })());
- assertEquals([[]], log);
-
- log = [];
- assertEquals(42, (() => {
- const [x] = g(); return x;
- })());
- assertEquals([[]], log);
-
- log = [];
- assertEquals(42, (() => {
- [x] = g(); return x;
- })());
- assertEquals([[]], log);
-
- log = []
- assertEquals(42,
- (([x]) => x)(g())
- );
- assertEquals([[]], log);
-
-
- log = [];
- assertEquals(42, (() => {
- var [x,] = g(); return x;
- })());
- assertEquals([[]], log);
-
- log = [];
- assertEquals(42, (() => {
- let [x,] = g(); return x;
- })());
- assertEquals([[]], log);
-
- log = [];
- assertEquals(42, (() => {
- const [x,] = g(); return x;
- })());
- assertEquals([[]], log);
-
- log = [];
- assertEquals(42, (() => {
- [x,] = g(); return x;
- })());
- assertEquals([[]], log);
-
- log = []
- assertEquals(42,
- (([x,]) => x)(g())
- );
- assertEquals([[]], log);
-
-
- log = [];
- assertEquals(42, (() => {
- var [x,,] = g(); return x;
- })());
- assertEquals([], log);
-
- log = [];
- assertEquals(42, (() => {
- let [x,,] = g(); return x;
- })());
- assertEquals([], log);
-
- log = [];
- assertEquals(42, (() => {
- const [x,,] = g(); return x;
- })());
- assertEquals([], log);
-
- log = [];
- assertEquals(42, (() => {
- [x,,] = g(); return x;
- })());
- assertEquals([], log);
-
- log = []
- assertEquals(42,
- (([x,,]) => x)(g())
- );
- assertEquals([], log);
-
-
- log = [];
- assertEquals([42, undefined], (() => {
- var [x, y] = g(); return [x, y];
- })());
- assertEquals([], log);
-
- log = [];
- assertEquals([42, undefined], (() => {
- let [x, y] = g(); return [x, y];
- })());
- assertEquals([], log);
-
- log = [];
- assertEquals([42, undefined], (() => {
- const [x, y] = g(); return [x, y];
- })());
- assertEquals([], log);
-
- log = [];
- assertEquals([42, undefined], (() => {
- [x, y] = g(); return [x, y];
- })());
- assertEquals([], log);
-
- log = []
- assertEquals([42, undefined],
- (([x, y]) => [x, y])(g())
- );
- assertEquals([], log);
-
-
- log = [];
- assertEquals([42], (() => {
- var [...x] = g(); return x;
- })());
- assertEquals([], log);
-
- log = [];
- assertEquals([42], (() => {
- let [...x] = g(); return x;
- })());
- assertEquals([], log);
-
- log = [];
- assertEquals([42], (() => {
- const [...x] = g(); return x;
- })());
- assertEquals([], log);
-
- log = [];
- assertEquals([42], (() => {
- [...x] = g(); return x;
- })());
- assertEquals([], log);
-
- log = []
- assertEquals([42],
- (([...x]) => x)(g())
- );
- assertEquals([], log);
-
-
- log = [];
- assertEquals([42, []], (() => {
- var [x, ...y] = g(); return [x, y];
- })());
- assertEquals([], log);
-
- log = [];
- assertEquals([42, []], (() => {
- let [x, ...y] = g(); return [x, y];
- })());
- assertEquals([], log);
-
- log = [];
- assertEquals([42, []], (() => {
- const [x, ...y] = g(); return [x, y];
- })());
- assertEquals([], log);
-
- log = [];
- assertEquals([42, []], (() => {
- [x, ...y] = g(); return [x, y];
- })());
- assertEquals([], log);
-
- log = []
- assertEquals([42, []],
- (([x, ...y]) => [x, y])(g())
- );
- assertEquals([], log);
-
-
- log = [];
- assertEquals([], (() => {
- var [] = g(); return [];
- })());
- assertEquals([[]], log);
-
- log = [];
- assertEquals([], (() => {
- let [] = g(); return [];
- })());
- assertEquals([[]], log);
-
- log = [];
- assertEquals([], (() => {
- const [] = g(); return [];
- })());
- assertEquals([[]], log);
-
- log = [];
- assertEquals([], (() => {
- [] = g(); return [];
- })());
- assertEquals([[]], log);
-
- log = []
- assertEquals([],
- (([]) => [])(g())
- );
- assertEquals([[]], log);
-
-
- log = [];
- assertEquals([], (() => {
- var [...[]] = g(); return [];
- })());
- assertEquals([], log);
-
- log = [];
- assertEquals([], (() => {
- let [...[]] = g(); return [];
- })());
- assertEquals([], log);
-
- log = [];
- assertEquals([], (() => {
- const [...[]] = g(); return [];
- })());
- assertEquals([], log);
-
- log = [];
- assertEquals([], (() => {
- [...[]] = g(); return [];
- })());
- assertEquals([], log);
-
- log = []
- assertEquals([],
- (([...[]]) => [])(g())
- );
- assertEquals([], log);
-
-
- log = [];
- assertEquals([42], (() => {
- var [...[x]] = g(); return [x];
- })());
- assertEquals([], log);
-
- log = [];
- assertEquals([42], (() => {
- let [...[x]] = g(); return [x];
- })());
- assertEquals([], log);
-
- log = [];
- assertEquals([42], (() => {
- const [...[x]] = g(); return [x];
- })());
- assertEquals([], log);
-
- log = [];
- assertEquals([42], (() => {
- [...[x]] = g(); return [x];
- })());
- assertEquals([], log);
-
- log = []
- assertEquals([42],
- (([...[x]]) => [x])(g())
- );
- assertEquals([], log);
-
-
- log = [];
- assertEquals([42, undefined], (() => {
- var [...[x, y]] = g(); return [x, y];
- })());
- assertEquals([], log);
-
- log = [];
- assertEquals([42, undefined], (() => {
- let [...[x, y]] = g(); return [x, y];
- })());
- assertEquals([], log);
-
- log = [];
- assertEquals([42, undefined], (() => {
- const [...[x, y]] = g(); return [x, y];
- })());
- assertEquals([], log);
-
- log = [];
- assertEquals([42, undefined], (() => {
- [...[x, y]] = g(); return [x, y];
- })());
- assertEquals([], log);
-
- log = []
- assertEquals([42, undefined],
- (([...[x, y]]) => [x, y])(g())
- );
- assertEquals([], log);
-
-
- log = []
- assertThrowsEquals(() => {
- let x = { set foo(_) { throw 666; } };
- [x.foo] = g();
- }, 666);
- assertEquals([[]], log);
-
-
- log = []
- assertThrows(() => {
- var [[]] = g();
- }, TypeError);
- assertEquals([[]], log);
-
- log = []
- assertThrows(() => {
- let [[]] = g();
- }, TypeError);
- assertEquals([[]], log);
-
- log = []
- assertThrows(() => {
- const [[]] = g();
- }, TypeError);
- assertEquals([[]], log);
-
- log = []
- assertThrows(() => {
- [[]] = g();
- }, TypeError);
- assertEquals([[]], log);
-
- log = []
- assertThrows(() => {
- (([[]]) => 0)(g());
- }, TypeError);
- assertEquals([[]], log);
-
-
- log = []
- assertThrows(() => {
- var [...[[]]] = g();
- }, TypeError);
- assertEquals([], log);
-
- log = []
- assertThrows(() => {
- let [...[[]]] = g();
- }, TypeError);
- assertEquals([], log);
-
- log = []
- assertThrows(() => {
- const [...[[]]] = g();
- }, TypeError);
- assertEquals([], log);
-
- log = []
- assertThrows(() => {
- [...[[]]] = g();
- }, TypeError);
- assertEquals([], log);
-
- log = []
- assertThrows(() => {
- (([...[[]]]) => 0)(g());
- }, TypeError);
- assertEquals([], log);
-
-
- {
- let backup = Array.prototype[Symbol.iterator];
- Array.prototype[Symbol.iterator] = () => g();
-
-
- log = [];
- assertDoesNotThrow(() => {
- var [x, ...[y]] = [1, 2, 3]
- });
- assertEquals(log, [[]]);
-
- log = [];
- assertDoesNotThrow(() => {
- let [x, ...[y]] = [1, 2, 3];
- });
- assertEquals(log, [[]]);
-
- log = [];
- assertDoesNotThrow(() => {
- const [x, ...[y]] = [1, 2, 3];
- });
- assertEquals(log, [[]]);
-
- log = [];
- assertDoesNotThrow(() => {
- (([x, ...[y]]) => {})([1, 2, 3]);
- });
- assertEquals(log, [[]]);
-
-
- log = [];
- assertThrows(() => {
- var [x, ...[[]]] = [1, 2, 3];
- }, TypeError);
- assertEquals(log, [[]]);
-
- log = [];
- assertThrows(() => {
- let [x, ...[[]]] = [1, 2, 3];
- }, TypeError);
- assertEquals(log, [[]]);
-
- log = [];
- assertThrows(() => {
- const [x, ...[[]]] = [1, 2, 3];
- }, TypeError);
- assertEquals(log, [[]]);
-
- log = [];
- assertThrows(() => {
- (([x, ...[[]]]) => {})([1, 2, 3]);
- }, TypeError);
- assertEquals(log, [[]]);
-
-
- log = [];
- assertDoesNotThrow(() => {
- var [x, ...[...y]] = [1, 2, 3];
- });
- assertEquals(log, []);
-
- log = [];
- assertDoesNotThrow(() => {
- let [x, ...[...y]] = [1, 2, 3];
- });
- assertEquals(log, []);
-
- log = [];
- assertDoesNotThrow(() => {
- const [x, ...[...y]] = [1, 2, 3];
- });
- assertEquals(log, []);
-
- log = [];
- assertDoesNotThrow(() => {
- (([x, ...[...y]]) => {})([1, 2, 3]);
- });
- assertEquals(log, []);
-
-
- Array.prototype[Symbol.iterator] = backup;
- }
-}
-
-
-// Return method throws.
-{
- let log = [];
- g.prototype.return = (...args) => { log.push(args); throw 23 };
-
-
- log = [];
- assertThrowsEquals(() => {
- for (var x of g()) { break; }
- }, 23);
- assertEquals([[]], log);
-
- log = [];
- assertThrowsEquals(() => {
- for (let x of g()) { break; }
- }, 23);
- assertEquals([[]], log);
-
- log = [];
- assertThrowsEquals(() => {
- for (const x of g()) { break; }
- }, 23);
- assertEquals([[]], log);
-
- log = [];
- assertThrowsEquals(() => {
- for (x of g()) { break; }
- }, 23);
- assertEquals([[]], log);
-
-
- log = [];
- assertThrowsEquals(() => {
- for (var x of g()) { throw 42; }
- }, 42);
- assertEquals([[]], log);
-
- log = [];
- assertThrowsEquals(() => {
- for (let x of g()) { throw 42; }
- }, 42);
- assertEquals([[]], log);
-
- log = [];
- assertThrowsEquals(() => {
- for (const x of g()) { throw 42; }
- }, 42);
- assertEquals([[]], log);
-
- log = [];
- assertThrowsEquals(() => {
- for (x of g()) { throw 42; }
- }, 42);
- assertEquals([[]], log);
-
-
- log = [];
- assertThrowsEquals(() => {
- for (var x of g()) { return 42; }
- }, 23);
- assertEquals([[]], log);
-
- log = [];
- assertThrowsEquals(() => {
- for (let x of g()) { return 42; }
- }, 23);
- assertEquals([[]], log);
-
- log = [];
- assertThrowsEquals(() => {
- for (const x of g()) { return 42; }
- }, 23);
- assertEquals([[]], log);
-
- log = [];
- assertThrowsEquals(() => {
- for (x of g()) { return 42; }
- }, 23);
- assertEquals([[]], log);
-
-
- log = [];
- assertEquals(42, eval('for (var x of g()) { x; }'));
- assertEquals([], log);
-
- log = [];
- assertEquals(42, eval('for (let x of g()) { x; }'));
- assertEquals([], log);
-
- log = [];
- assertEquals(42, eval('for (const x of g()) { x; }'));
- assertEquals([], log);
-
- log = [];
- assertEquals(42, eval('for (x of g()) { x; }'));
- assertEquals([], log);
-
-
- log = [];
- assertThrowsEquals(() => {
- var [x] = g(); return x;
- }, 23);
- assertEquals([[]], log);
-
- log = [];
- assertThrowsEquals(() => {
- let [x] = g(); return x;
- }, 23);
- assertEquals([[]], log);
-
- log = [];
- assertThrowsEquals(() => {
- const [x] = g(); return x;
- }, 23);
- assertEquals([[]], log);
-
- log = [];
- assertThrowsEquals(() => {
- [x] = g(); return x;
- }, 23);
- assertEquals([[]], log);
-
- log = [];
- assertThrowsEquals(() => {
- (([x]) => x)(g())
- }, 23);
- assertEquals([[]], log);
-}
-
-
-// Next method throws.
-{
- g.prototype.next = () => { throw 666; };
- g.prototype.return = () => { assertUnreachable() };
-
-
- assertThrowsEquals(() => {
- for (var x of g()) {}
- }, 666);
-
- assertThrowsEquals(() => {
- for (let x of g()) {}
- }, 666);
-
- assertThrowsEquals(() => {
- for (const x of g()) {}
- }, 666);
-
- assertThrowsEquals(() => {
- for (x of g()) {}
- }, 666);
-
- assertThrowsEquals(() => {
- var [x] = g();
- }, 666);
-
- assertThrowsEquals(() => {
- let [x] = g();
- }, 666);
-
- assertThrowsEquals(() => {
- const [x] = g();
- }, 666);
-
- assertThrowsEquals(() => {
- [x] = g();
- }, 666);
-
- assertThrowsEquals(() => {
- (([x]) => x)(g());
- }, 666);
-
- assertThrowsEquals(() => {
- var [...x] = g();
- }, 666);
-
- assertThrowsEquals(() => {
- let [...x] = g();
- }, 666);
-
- assertThrowsEquals(() => {
- const [...x] = g();
- }, 666);
-
- assertThrowsEquals(() => {
- [...x] = g();
- }, 666);
-
- assertThrowsEquals(() => {
- (([...x]) => x)(g());
- }, 666);
-}
-
-
-// Value throws.
-{
- g.prototype.next = () => ({get value() {throw 666}});
- g.prototype.return = () => { assertUnreachable() };
-
-
- assertThrowsEquals(() => {
- for (var x of g()) {}
- }, 666);
-
- assertThrowsEquals(() => {
- for (let x of g()) {}
- }, 666);
-
- assertThrowsEquals(() => {
- for (const x of g()) {}
- }, 666);
-
- assertThrowsEquals(() => {
- for (x of g()) {}
- }, 666);
-
- assertThrowsEquals(() => {
- var [x] = g();
- }, 666);
-
- assertThrowsEquals(() => {
- let [x] = g();
- }, 666);
-
- assertThrowsEquals(() => {
- const [x] = g();
- }, 666);
-
- assertThrowsEquals(() => {
- [x] = g();
- }, 666);
-
- assertThrowsEquals(() => {
- (([x]) => x)(g());
- }, 666);
-
- assertThrowsEquals(() => {
- var [...x] = g();
- }, 666);
-
- assertThrowsEquals(() => {
- let [...x] = g();
- }, 666);
-
- assertThrowsEquals(() => {
- const [...x] = g();
- }, 666);
-
- assertThrowsEquals(() => {
- [...x] = g();
- }, 666);
-
- assertThrowsEquals(() => {
- (([...x]) => x)(g());
- }, 666);
-}
-
-
-// Done throws.
-{
- g.prototype.next = () => ({get done() {throw 666}});
- g.prototype.return = () => { assertUnreachable() };
-
-
- assertThrowsEquals(() => {
- for (var x of g()) {}
- }, 666);
-
- assertThrowsEquals(() => {
- for (let x of g()) {}
- }, 666);
-
- assertThrowsEquals(() => {
- for (const x of g()) {}
- }, 666);
-
- assertThrowsEquals(() => {
- for (x of g()) {}
- }, 666);
-
- assertThrowsEquals(() => {
- var [x] = g();
- }, 666);
-
- assertThrowsEquals(() => {
- let [x] = g();
- }, 666);
-
- assertThrowsEquals(() => {
- const [x] = g();
- }, 666);
-
- assertThrowsEquals(() => {
- [x] = g();
- }, 666);
-
- assertThrowsEquals(() => {
- (([x]) => x)(g());
- }, 666);
-
- assertThrowsEquals(() => {
- var [...x] = g();
- }, 666);
-
- assertThrowsEquals(() => {
- let [...x] = g();
- }, 666);
-
- assertThrowsEquals(() => {
- const [...x] = g();
- }, 666);
-
- assertThrowsEquals(() => {
- [...x] = g();
- }, 666);
-
- assertThrowsEquals(() => {
- (([...x]) => x)(g());
- }, 666);
-}
-
-
-// Nested loops.
-{
- function* g1() { yield 1; yield 2; throw 3; }
- function* g2() { yield -1; yield -2; throw -3; }
-
- assertDoesNotThrow(() => {
- for (let x of g1()) {
- for (let y of g2()) {
- if (y == -2) break;
- }
- if (x == 2) break;
- }
- }, -3);
-
- assertThrowsEquals(() => {
- for (let x of g1()) {
- for (let y of g2()) {
- }
- }
- }, -3);
-
- assertThrowsEquals(() => {
- for (let x of g1()) {
- for (let y of g2()) {
- if (y == -2) break;
- }
- }
- }, 3);
-
- assertDoesNotThrow(() => {
- l: for (let x of g1()) {
- for (let y of g2()) {
- if (y == -2) break l;
- }
- }
- });
-
- assertThrowsEquals(() => {
- for (let x of g1()) {
- for (let y of g2()) {
- throw 4;
- }
- }
- }, 4);
-
- assertThrowsEquals(() => {
- for (let x of g1()) {
- for (let y of g2()) {
- if (y == -2) throw 4;
- }
- }
- }, 4);
-
- let log = [];
- g1.prototype.return = () => { log.push(1); throw 5 };
- g2.prototype.return = () => { log.push(2); throw -5 };
-
- log = [];
- assertThrowsEquals(() => {
- for (let x of g1()) {
- for (let y of g2()) {
- if (y == -2) break;
- }
- if (x == 2) break;
- }
- }, -5);
- assertEquals([2, 1], log);
-
- log = [];
- assertThrowsEquals(() => {
- for (let x of g1()) {
- for (let y of g2()) {
- }
- }
- }, -3);
- assertEquals([1], log);
-
- log = [];
- assertThrowsEquals(() => {
- for (let x of g1()) {
- for (let y of g2()) {
- if (y == -2) break;
- }
- }
- }, -5);
- assertEquals([2, 1], log);
-
- log = [];
- assertThrowsEquals(() => {
- l: for (let x of g1()) {
- for (let y of g2()) {
- if (y == -2) break l;
- }
- }
- }, -5);
- assertEquals([2, 1], log);
-
- log = [];
- assertThrowsEquals(() => {
- for (let x of g1()) {
- for (let y of g2()) {
- throw 4;
- }
- }
- }, 4);
- assertEquals([2, 1], log);
-
- log = [];
- assertThrowsEquals(() => {
- for (let x of g1()) {
- for (let y of g2()) {
- if (y == -2) throw 4;
- }
- }
- }, 4);
- assertEquals([2, 1], log);
-
- log = [];
- assertThrowsEquals(() => {
- for (let x of g1()) {
- try {
- for (let y of g2()) {
- }
- } catch (_) {}
- }
- }, 3);
- assertEquals([], log);
-
- log = [];
- assertThrowsEquals(() => {
- for (let x of g1()) {
- try {
- for (let y of g2()) {
- }
- } catch (_) {}
- if (x == 2) break;
- }
- }, 5);
- assertEquals([1], log);
-}
-
-
-// yield*, argument's return method is "undefined".
-function TestYieldStarWithoutReturn(get_iterable) {
- assertTrue(get_iterable().return == undefined);
-
- function* g() { yield* get_iterable() }
-
- {
- let gen = g();
- assertEquals({value: 1, done: false}, gen.next());
- assertEquals({value: undefined, done: true}, gen.return());
- }
-
- assertEquals(42, (() => {
- for (let x of g()) break;
- return 42;
- })());
-
- assertEquals(42, (() => {
- for (let x of g()) return 42;
- })());
-
- assertThrowsEquals(() => {
- for (let x of g()) throw 42;
- }, 42);
-}
-{
- let get_iterable1 = () => [1, 2];
- let get_iterable2 = function*() { yield 1; yield 2 };
- get_iterable2.prototype.return = null;
- TestYieldStarWithoutReturn(get_iterable1);
- TestYieldStarWithoutReturn(get_iterable2);
-}
-
-
-// yield*, argument's return method is defined.
-{
- let get_iterable = function*() { yield 1; yield 2 };
- const obj = {};
- get_iterable.prototype.return = (...args) => obj;
-
- function* g() { yield* get_iterable() }
-
- {
- let gen = g();
- assertEquals({value: 1, done: false}, gen.next());
- assertSame(obj, gen.return());
- assertSame(obj, gen.return());
- assertSame(obj, gen.return());
- assertEquals({value: 2, done: false}, gen.next());
- assertSame(obj, gen.return());
- assertSame(obj, gen.return());
- assertSame(obj, gen.return());
- assertEquals({value: undefined, done: true}, gen.next());
- assertEquals({value: undefined, done: true}, gen.return());
- assertEquals({value: undefined, done: true}, gen.return());
- }
-
- assertEquals(42, (() => {
- for (let x of g()) break;
- return 42;
- })());
-
- assertEquals(42, (() => {
- for (let x of g()) return 42;
- })());
-
- assertThrowsEquals(() => {
- for (let x of g()) throw 42;
- }, 42);
-}
diff --git a/test/mjsunit/harmony/mirror-async-function-promise.js b/test/mjsunit/harmony/mirror-async-function-promise.js
new file mode 100644
index 0000000..966b0ce
--- /dev/null
+++ b/test/mjsunit/harmony/mirror-async-function-promise.js
@@ -0,0 +1,93 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug --harmony-async-await --allow-natives-syntax
+// Test the mirror object for promises.
+
+var AsyncFunction = (async function() {}).constructor;
+
+function MirrorRefCache(json_refs) {
+ var tmp = eval('(' + json_refs + ')');
+ this.refs_ = [];
+ for (var i = 0; i < tmp.length; i++) {
+ this.refs_[tmp[i].handle] = tmp[i];
+ }
+}
+
+MirrorRefCache.prototype.lookup = function(handle) {
+ return this.refs_[handle];
+}
+
+function testPromiseMirror(promise, status, value) {
+ // Create mirror and JSON representation.
+ var mirror = debug.MakeMirror(promise);
+ var serializer = debug.MakeMirrorSerializer();
+ var json = JSON.stringify(serializer.serializeValue(mirror));
+ var refs = new MirrorRefCache(
+ JSON.stringify(serializer.serializeReferencedObjects()));
+
+ // Check the mirror hierachy.
+ assertTrue(mirror instanceof debug.Mirror);
+ assertTrue(mirror instanceof debug.ValueMirror);
+ assertTrue(mirror instanceof debug.ObjectMirror);
+ assertTrue(mirror instanceof debug.PromiseMirror);
+
+ // Check the mirror properties.
+ assertEquals(status, mirror.status());
+ assertTrue(mirror.isPromise());
+ assertEquals('promise', mirror.type());
+ assertFalse(mirror.isPrimitive());
+ assertEquals("Object", mirror.className());
+ assertEquals("#<Promise>", mirror.toText());
+ assertSame(promise, mirror.value());
+ assertTrue(mirror.promiseValue() instanceof debug.Mirror);
+ assertEquals(value, mirror.promiseValue().value());
+
+ // Parse JSON representation and check.
+ var fromJSON = eval('(' + json + ')');
+ assertEquals('promise', fromJSON.type);
+ assertEquals('Object', fromJSON.className);
+ assertEquals('function', refs.lookup(fromJSON.constructorFunction.ref).type);
+ assertEquals('Promise', refs.lookup(fromJSON.constructorFunction.ref).name);
+ assertEquals(status, fromJSON.status);
+ assertEquals(value, refs.lookup(fromJSON.promiseValue.ref).value);
+}
+
+// Test a number of different promises.
+var resolved = (async function() {})();
+var rejected = (async function() { throw undefined; })();
+var pending = (async function() { await 1; })();
+
+testPromiseMirror(resolved, "resolved", undefined);
+testPromiseMirror(rejected, "rejected", undefined);
+testPromiseMirror(pending, "pending", undefined);
+
+var resolvedv = (async function() { return "resolve"; })();
+var rejectedv = (async function() { return Promise.reject("reject"); })();
+var thrownv = (async function() { throw "throw"; })();
+
+testPromiseMirror(resolvedv, "resolved", 'resolve');
+testPromiseMirror(rejectedv, "rejected", 'reject');
+testPromiseMirror(thrownv, "rejected", 'throw');
+
+// Test internal properties of different promises.
+var m1 = debug.MakeMirror((async function() { return 1; })());
+var ip = m1.internalProperties();
+assertEquals(2, ip.length);
+assertEquals("[[PromiseStatus]]", ip[0].name());
+assertEquals("[[PromiseValue]]", ip[1].name());
+assertEquals("resolved", ip[0].value().value());
+assertEquals(1, ip[1].value().value());
+
+var m2 = debug.MakeMirror((async function() { throw 2; })());
+ip = m2.internalProperties();
+assertEquals("rejected", ip[0].value().value());
+assertEquals(2, ip[1].value().value());
+
+var m3 = debug.MakeMirror((async function() { await 1; })());
+ip = m3.internalProperties();
+assertEquals("pending", ip[0].value().value());
+assertEquals("undefined", typeof(ip[1].value().value()));
+
+%RunMicrotasks();
diff --git a/test/mjsunit/harmony/mirror-async-function.js b/test/mjsunit/harmony/mirror-async-function.js
new file mode 100644
index 0000000..b4ba831
--- /dev/null
+++ b/test/mjsunit/harmony/mirror-async-function.js
@@ -0,0 +1,76 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug --harmony-async-await --allow-natives-syntax
+// Test the mirror object for functions.
+
+var AsyncFunction = (async function() {}).constructor;
+
+function MirrorRefCache(json_refs) {
+ var tmp = eval('(' + json_refs + ')');
+ this.refs_ = [];
+ for (var i = 0; i < tmp.length; i++) {
+ this.refs_[tmp[i].handle] = tmp[i];
+ }
+}
+
+MirrorRefCache.prototype.lookup = function(handle) {
+ return this.refs_[handle];
+}
+
+function testFunctionMirror(f) {
+ // Create mirror and JSON representation.
+ var mirror = debug.MakeMirror(f);
+ var serializer = debug.MakeMirrorSerializer();
+ var json = JSON.stringify(serializer.serializeValue(mirror));
+ var refs = new MirrorRefCache(
+ JSON.stringify(serializer.serializeReferencedObjects()));
+
+ // Check the mirror hierachy.
+ assertTrue(mirror instanceof debug.Mirror);
+ assertTrue(mirror instanceof debug.ValueMirror);
+ assertTrue(mirror instanceof debug.ObjectMirror);
+ assertTrue(mirror instanceof debug.FunctionMirror);
+
+ // Check the mirror properties.
+ assertTrue(mirror.isFunction());
+ assertEquals('function', mirror.type());
+ assertFalse(mirror.isPrimitive());
+ assertEquals("Function", mirror.className());
+ assertEquals(f.name, mirror.name());
+ assertTrue(mirror.resolved());
+ assertEquals(f.toString(), mirror.source());
+ assertTrue(mirror.constructorFunction() instanceof debug.ObjectMirror);
+ assertTrue(mirror.protoObject() instanceof debug.Mirror);
+ assertTrue(mirror.prototypeObject() instanceof debug.Mirror);
+
+ // Test text representation
+ assertEquals(f.toString(), mirror.toText());
+
+ // Parse JSON representation and check.
+ var fromJSON = eval('(' + json + ')');
+ assertEquals('function', fromJSON.type);
+ assertEquals('Function', fromJSON.className);
+ assertEquals('function', refs.lookup(fromJSON.constructorFunction.ref).type);
+ assertEquals('AsyncFunction',
+ refs.lookup(fromJSON.constructorFunction.ref).name);
+ assertTrue(fromJSON.resolved);
+ assertEquals(f.name, fromJSON.name);
+ assertEquals(f.toString(), fromJSON.source);
+
+ // Check the formatted text (regress 1142074).
+ assertEquals(f.toString(), fromJSON.text);
+}
+
+
+// Test a number of different functions.
+testFunctionMirror(async function(){});
+testFunctionMirror(AsyncFunction());
+testFunctionMirror(new AsyncFunction());
+testFunctionMirror(async() => {});
+testFunctionMirror(async function a(){return 1;});
+testFunctionMirror(({ async foo() {} }).foo);
+testFunctionMirror((async function(){}).bind({}), "Object");
+
+%RunMicrotasks();
diff --git a/test/mjsunit/harmony/promise-species.js b/test/mjsunit/harmony/promise-species.js
deleted file mode 100644
index 12244f2..0000000
--- a/test/mjsunit/harmony/promise-species.js
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2015 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-species --allow-natives-syntax
-
-// Test that Promises use @@species appropriately
-
-// Another constructor with no species will not be instantiated
-var test = new Promise(function(){});
-var bogoCount = 0;
-function bogusConstructor() { bogoCount++; }
-test.constructor = bogusConstructor;
-assertTrue(Promise.resolve(test) instanceof Promise);
-assertFalse(Promise.resolve(test) instanceof bogusConstructor);
-// Tests that chromium:575314 is fixed thoroughly
-Promise.resolve(test).catch(e => %AbortJS("Error " + e)).then(() => {
- if (bogoCount != 0) %AbortJS("bogoCount was " + bogoCount + " should be 0");
-});
-
-// If there is a species, it will be instantiated
-// @@species will be read exactly once, and the constructor is called with a
-// function
-var count = 0;
-var params;
-class MyPromise extends Promise {
- constructor(...args) {
- super(...args);
- params = args;
- }
- static get [Symbol.species]() {
- count++
- return this;
- }
-}
-
-var myPromise = MyPromise.resolve().then();
-assertEquals(1, count);
-assertEquals(1, params.length);
-assertEquals('function', typeof(params[0]));
-assertTrue(myPromise instanceof MyPromise);
-assertTrue(myPromise instanceof Promise);
diff --git a/test/mjsunit/harmony/regexp-change-exec.js b/test/mjsunit/harmony/regexp-change-exec.js
index 4c9757e..ff84506 100644
--- a/test/mjsunit/harmony/regexp-change-exec.js
+++ b/test/mjsunit/harmony/regexp-change-exec.js
@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --harmony-regexp-exec
-
class MyError extends Error { }
RegExp.prototype.exec = () => { throw new MyError() };
assertThrows(() => "foo".match(/bar/), MyError);
diff --git a/test/mjsunit/harmony/regexp-named-captures.js b/test/mjsunit/harmony/regexp-named-captures.js
new file mode 100644
index 0000000..ced8e4b
--- /dev/null
+++ b/test/mjsunit/harmony/regexp-named-captures.js
@@ -0,0 +1,76 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-regexp-named-captures
+
+// Malformed named captures.
+assertThrows("/(?<>a)/u"); // Empty name.
+assertThrows("/(?<aa)/u"); // Unterminated name.
+assertThrows("/(?<42a>a)/u"); // Name starting with digits.
+assertThrows("/(?<:a>a)/u"); // Name starting with invalid char.
+assertThrows("/(?<a:>a)/u"); // Name containing with invalid char.
+assertThrows("/(?<a>a)(?<a>a)/u"); // Duplicate name.
+assertThrows("/(?<a>a)(?<b>b)(?<a>a)/u"); // Duplicate name.
+assertThrows("/\\k<a>/u"); // Invalid reference.
+assertThrows("/(?<a>a)\\k<ab>/u"); // Invalid reference.
+assertThrows("/(?<ab>a)\\k<a>/u"); // Invalid reference.
+assertThrows("/\\k<a>(?<ab>a)/u"); // Invalid reference.
+
+// Fallback behavior in non-unicode mode.
+assertThrows("/(?<>a)/");
+assertThrows("/(?<aa)/");
+assertThrows("/(?<42a>a)/");
+assertThrows("/(?<:a>a)/");
+assertThrows("/(?<a:>a)/");
+assertThrows("/(?<a>a)(?<a>a)/");
+assertThrows("/(?<a>a)(?<b>b)(?<a>a)/");
+assertThrows("/(?<a>a)\\k<ab>/");
+assertThrows("/(?<ab>a)\\k<a>/");
+
+assertEquals(["k<a>"], "xxxk<a>xxx".match(/\k<a>/));
+assertEquals(["k<a"], "xxxk<a>xxx".match(/\k<a/));
+
+// Basic named groups.
+assertEquals(["a", "a"], "bab".match(/(?<a>a)/u));
+assertEquals(["a", "a"], "bab".match(/(?<a42>a)/u));
+assertEquals(["a", "a"], "bab".match(/(?<_>a)/u));
+assertEquals(["a", "a"], "bab".match(/(?<$>a)/u));
+assertEquals(["bab", "a"], "bab".match(/.(?<$>a)./u));
+assertEquals(["bab", "a", "b"], "bab".match(/.(?<a>a)(.)/u));
+assertEquals(["bab", "a", "b"], "bab".match(/.(?<a>a)(?<b>.)/u));
+assertEquals(["bab", "ab"], "bab".match(/.(?<a>\w\w)/u));
+assertEquals(["bab", "bab"], "bab".match(/(?<a>\w\w\w)/u));
+assertEquals(["bab", "ba", "b"], "bab".match(/(?<a>\w\w)(?<b>\w)/u));
+
+assertEquals("bab".match(/(a)/u), "bab".match(/(?<a>a)/u));
+assertEquals("bab".match(/(a)/u), "bab".match(/(?<a42>a)/u));
+assertEquals("bab".match(/(a)/u), "bab".match(/(?<_>a)/u));
+assertEquals("bab".match(/(a)/u), "bab".match(/(?<$>a)/u));
+assertEquals("bab".match(/.(a)./u), "bab".match(/.(?<$>a)./u));
+assertEquals("bab".match(/.(a)(.)/u), "bab".match(/.(?<a>a)(.)/u));
+assertEquals("bab".match(/.(a)(.)/u), "bab".match(/.(?<a>a)(?<b>.)/u));
+assertEquals("bab".match(/.(\w\w)/u), "bab".match(/.(?<a>\w\w)/u));
+assertEquals("bab".match(/(\w\w\w)/u), "bab".match(/(?<a>\w\w\w)/u));
+assertEquals("bab".match(/(\w\w)(\w)/u), "bab".match(/(?<a>\w\w)(?<b>\w)/u));
+
+assertEquals(["bab", "b"], "bab".match(/(?<b>b).\1/u));
+assertEquals(["baba", "b", "a"], "baba".match(/(.)(?<a>a)\1\2/u));
+assertEquals(["baba", "b", "a", "b", "a"],
+ "baba".match(/(.)(?<a>a)(?<b>\1)(\2)/u));
+assertEquals(["<a", "<"], "<a".match(/(?<lt><)a/u));
+assertEquals([">a", ">"], ">a".match(/(?<gt>>)a/u));
+
+// Named references.
+assertEquals(["bab", "b"], "bab".match(/(?<b>.).\k<b>/u));
+assertNull("baa".match(/(?<b>.).\k<b>/u));
+
+// Nested groups.
+assertEquals(["bab", "bab", "ab", "b"], "bab".match(/(?<a>.(?<b>.(?<c>.)))/u));
+
+// Reference inside group.
+assertEquals(["bab", "b"], "bab".match(/(?<a>\k<a>\w)../u));
+
+// Reference before group.
+assertEquals(["bab", "b"], "bab".match(/\k<a>(?<a>b)\w\k<a>/u));
+assertEquals(["bab", "b", "a"], "bab".match(/(?<b>b)\k<a>(?<a>a)\k<b>/u));
diff --git a/test/mjsunit/harmony/regexp-no-change-exec.js b/test/mjsunit/harmony/regexp-no-change-exec.js
deleted file mode 100644
index 30b5050..0000000
--- a/test/mjsunit/harmony/regexp-no-change-exec.js
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright 2016 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --no-harmony-regexp-exec
-
-class MyError extends Error { }
-RegExp.prototype.exec = () => { throw new MyError() };
-assertEquals(null, "foo".match(/bar/));
diff --git a/test/mjsunit/harmony/regexp-property-binary.js b/test/mjsunit/harmony/regexp-property-binary.js
index d0894b7..c0b4426 100644
--- a/test/mjsunit/harmony/regexp-property-binary.js
+++ b/test/mjsunit/harmony/regexp-property-binary.js
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --harmony-regexp-property --harmony-unicode-regexps
+// Flags: --harmony-regexp-property
function t(re, s) { assertTrue(re.test(s)); }
function f(re, s) { assertFalse(re.test(s)); }
diff --git a/test/mjsunit/harmony/regexp-property-blocks.js b/test/mjsunit/harmony/regexp-property-blocks.js
index f41c06e..de3fd1e 100644
--- a/test/mjsunit/harmony/regexp-property-blocks.js
+++ b/test/mjsunit/harmony/regexp-property-blocks.js
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --harmony-regexp-property --harmony-unicode-regexps
+// Flags: --harmony-regexp-property
function t(re, s) { assertTrue(re.test(s)); }
function f(re, s) { assertFalse(re.test(s)); }
diff --git a/test/mjsunit/harmony/regexp-property-char-class.js b/test/mjsunit/harmony/regexp-property-char-class.js
index 6162012..c70e826 100644
--- a/test/mjsunit/harmony/regexp-property-char-class.js
+++ b/test/mjsunit/harmony/regexp-property-char-class.js
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --harmony-unicode-regexps --harmony-regexp-property
+// Flags: --harmony-regexp-property
assertThrows("/[\\p]/u");
assertThrows("/[\\p{garbage}]/u");
diff --git a/test/mjsunit/harmony/regexp-property-disabled.js b/test/mjsunit/harmony/regexp-property-disabled.js
index 7a3158c..f471ef4 100644
--- a/test/mjsunit/harmony/regexp-property-disabled.js
+++ b/test/mjsunit/harmony/regexp-property-disabled.js
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --harmony-unicode-regexps --no-harmony-regexp-property
+// Flags: --no-harmony-regexp-property
function test(source, message) {
try {
diff --git a/test/mjsunit/harmony/regexp-property-enumerated.js b/test/mjsunit/harmony/regexp-property-enumerated.js
index e4a81a4..dba8397 100644
--- a/test/mjsunit/harmony/regexp-property-enumerated.js
+++ b/test/mjsunit/harmony/regexp-property-enumerated.js
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --harmony-regexp-property --harmony-unicode-regexps
+// Flags: --harmony-regexp-property
function t(re, s) { assertTrue(re.test(s)); }
function f(re, s) { assertFalse(re.test(s)); }
diff --git a/test/mjsunit/harmony/regexp-property-exact-match.js b/test/mjsunit/harmony/regexp-property-exact-match.js
index fe233f2..0d1f704 100644
--- a/test/mjsunit/harmony/regexp-property-exact-match.js
+++ b/test/mjsunit/harmony/regexp-property-exact-match.js
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --harmony-regexp-property --harmony-unicode-regexps
+// Flags: --harmony-regexp-property
assertThrows("/\\p{In CJK}/u");
assertThrows("/\\p{InCJKUnifiedIdeographs}/u");
@@ -15,7 +15,7 @@
assertThrows("/\\p{InCyrillicSupplementary}/u");
assertThrows("/\\p{InCyrillic_supplementary}/u");
-assertDoesNotThrow("/\\pC/u");
+assertDoesNotThrow("/\\p{C}/u");
assertDoesNotThrow("/\\p{Other}/u");
assertDoesNotThrow("/\\p{Cc}/u");
assertDoesNotThrow("/\\p{Control}/u");
diff --git a/test/mjsunit/harmony/regexp-property-general-category.js b/test/mjsunit/harmony/regexp-property-general-category.js
index e2015ad..e4fb8b5 100644
--- a/test/mjsunit/harmony/regexp-property-general-category.js
+++ b/test/mjsunit/harmony/regexp-property-general-category.js
@@ -2,16 +2,20 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --harmony-regexp-property --harmony-unicode-regexps
+// Flags: --harmony-regexp-property
assertThrows("/\\p/u");
assertThrows("/\\p{garbage}/u");
assertThrows("/\\p{}/u");
assertThrows("/\\p{/u");
assertThrows("/\\p}/u");
-assertThrows("/\p{Math}/u");
-assertThrows("/\p{Bidi_M}/u");
-assertThrows("/\p{Hex}/u");
+assertThrows("/\\pL/u");
+assertThrows("/\\P/u");
+assertThrows("/\\P{garbage}/u");
+assertThrows("/\\P{}/u");
+assertThrows("/\\P{/u");
+assertThrows("/\\P}/u");
+assertThrows("/\\PL/u");
assertTrue(/\p{Ll}/u.test("a"));
assertFalse(/\P{Ll}/u.test("a"));
@@ -26,10 +30,10 @@
assertTrue(/\p{Ll}/iu.test("\u{118D4}"));
assertTrue(/\p{Ll}/iu.test("A"));
assertTrue(/\p{Ll}/iu.test("\u{118B4}"));
-assertFalse(/\P{Ll}/iu.test("a"));
-assertFalse(/\P{Ll}/iu.test("\u{118D4}"));
-assertFalse(/\P{Ll}/iu.test("A"));
-assertFalse(/\P{Ll}/iu.test("\u{118B4}"));
+assertTrue(/\P{Ll}/iu.test("a"));
+assertTrue(/\P{Ll}/iu.test("\u{118D4}"));
+assertTrue(/\P{Ll}/iu.test("A"));
+assertTrue(/\P{Ll}/iu.test("\u{118B4}"));
assertTrue(/\p{Lu}/u.test("A"));
assertFalse(/\P{Lu}/u.test("A"));
@@ -44,22 +48,16 @@
assertTrue(/\p{Lu}/iu.test("\u{118D4}"));
assertTrue(/\p{Lu}/iu.test("A"));
assertTrue(/\p{Lu}/iu.test("\u{118B4}"));
-assertFalse(/\P{Lu}/iu.test("a"));
-assertFalse(/\P{Lu}/iu.test("\u{118D4}"));
-assertFalse(/\P{Lu}/iu.test("A"));
-assertFalse(/\P{Lu}/iu.test("\u{118B4}"));
+assertTrue(/\P{Lu}/iu.test("a"));
+assertTrue(/\P{Lu}/iu.test("\u{118D4}"));
+assertTrue(/\P{Lu}/iu.test("A"));
+assertTrue(/\P{Lu}/iu.test("\u{118B4}"));
assertTrue(/\p{Sm}/u.test("+"));
assertFalse(/\P{Sm}/u.test("+"));
assertTrue(/\p{Sm}/u.test("\u{1D6C1}"));
assertFalse(/\P{Sm}/u.test("\u{1D6C1}"));
-assertTrue(/\pL/u.test("a"));
-assertFalse(/\PL/u.test("a"));
-assertFalse(/\pL/u.test("1"));
-assertTrue(/\PL/u.test("1"));
-assertTrue(/\pL/u.test("\u1FAB"));
-assertFalse(/\PL/u.test("\u1FAB"));
assertFalse(/\p{L}/u.test("\uA6EE"));
assertTrue(/\P{L}/u.test("\uA6EE"));
diff --git a/test/mjsunit/harmony/regexp-property-lu-ui.js b/test/mjsunit/harmony/regexp-property-lu-ui.js
new file mode 100644
index 0000000..115e064
--- /dev/null
+++ b/test/mjsunit/harmony/regexp-property-lu-ui.js
@@ -0,0 +1,13 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-regexp-property
+
+const regexp = /\P{Lu}/ui;
+const regexpu = /[\0-@\[-\xBF\xD7\xDF-\xFF\u0101\u0103\u0105\u0107\u0109\u010B\u010D\u010F\u0111\u0113\u0115\u0117\u0119\u011B\u011D\u011F\u0121\u0123\u0125\u0127\u0129\u012B\u012D\u012F\u0131\u0133\u0135\u0137\u0138\u013A\u013C\u013E\u0140\u0142\u0144\u0146\u0148\u0149\u014B\u014D\u014F\u0151\u0153\u0155\u0157\u0159\u015B\u015D\u015F\u0161\u0163\u0165\u0167\u0169\u016B\u016D\u016F\u0171\u0173\u0175\u0177\u017A\u017C\u017E-\u0180\u0183\u0185\u0188\u018C\u018D\u0192\u0195\u0199-\u019B\u019E\u01A1\u01A3\u01A5\u01A8\u01AA\u01AB\u01AD\u01B0\u01B4\u01B6\u01B9-\u01BB\u01BD-\u01C3\u01C5\u01C6\u01C8\u01C9\u01CB\u01CC\u01CE\u01D0\u01D2\u01D4\u01D6\u01D8\u01DA\u01DC\u01DD\u01DF\u01E1\u01E3\u01E5\u01E7\u01E9\u01EB\u01ED\u01EF\u01F0\u01F2\u01F3\u01F5\u01F9\u01FB\u01FD\u01FF\u0201\u0203\u0205\u0207\u0209\u020B\u020D\u020F\u0211\u0213\u0215\u0217\u0219\u021B\u021D\u021F\u0221\u0223\u0225\u0227\u0229\u022B\u022D\u022F\u0231\u0233-\u0239\u023C\u023F\u0240\u0242\u0247\u0249\u024B\u024D\u024F-\u036F\u0371\u0373-\u0375\u0377-\u037E\u0380-\u0385\u0387\u038B\u038D\u0390\u03A2\u03AC-\u03CE\u03D0\u03D1\u03D5-\u03D7\u03D9\u03DB\u03DD\u03DF\u03E1\u03E3\u03E5\u03E7\u03E9\u03EB\u03ED\u03EF-\u03F3\u03F5\u03F6\u03F8\u03FB\u03FC\u0430-\u045F\u0461\u0463\u0465\u0467\u0469\u046B\u046D\u046F\u0471\u0473\u0475\u0477\u0479\u047B\u047D\u047F\u0481-\u0489\u048B\u048D\u048F\u0491\u0493\u0495\u0497\u0499\u049B\u049D\u049F\u04A1\u04A3\u04A5\u04A7\u04A9\u04AB\u04AD\u04AF\u04B1\u04B3\u04B5\u04B7\u04B9\u04BB\u04BD\u04BF\u04C2\u04C4\u04C6\u04C8\u04CA\u04CC\u04CE\u04CF\u04D1\u04D3\u04D5\u04D7\u04D9\u04DB\u04DD\u04DF\u04E1\u04E3\u04E5\u04E7\u04E9\u04EB\u04ED\u04EF\u04F1\u04F3\u04F5\u04F7\u04F9\u04FB\u04FD\u04FF\u0501\u0503\u0505\u0507\u0509\u050B\u050D\u050F\u0511\u0513\u0515\u0517\u0519\u051B\u051D\u051F\u0521\u0523\u0525\u0527\u0529\u052B\u052D\u052F\u0530\u0557-\u109F\u10C6\u10C8-\u10CC\u10CE-\u139F\u13F6-\u1DFF\u1E01\u1E03\u1E05\u1E07\u1E09\u1E0B\u1E0D\u1E0F\u1E11\u1E13\u1E15\u1E17\u1E19\u1E1B\u1E1D\u1E1F\u1E21\u1E23\u1E25\u1E27\u1E29\u1E2B\u1E2D\u1E2F\u1E31\u1E33\u1E35\u1E37\u1E39\u1E3B\u1E3D\u1E3F\u1E41\u1E43\u1E45\u1E47\u1E49\u1E4B\u1E4D\u1E4F\u1E51\u1E53\u1E55\u1E57\u1E59\u1E5B\u1E5D\u1E5F\u1E61\u1E63\u1E65\u1E67\u1E69\u1E6B\u1E6D\u1E6F\u1E71\u1E73\u1E75\u1E77\u1E79\u1E7B\u1E7D\u1E7F\u1E81\u1E83\u1E85\u1E87\u1E89\u1E8B\u1E8D\u1E8F\u1E91\u1E93\u1E95-\u1E9D\u1E9F\u1EA1\u1EA3\u1EA5\u1EA7\u1EA9\u1EAB\u1EAD\u1EAF\u1EB1\u1EB3\u1EB5\u1EB7\u1EB9\u1EBB\u1EBD\u1EBF\u1EC1\u1EC3\u1EC5\u1EC7\u1EC9\u1ECB\u1ECD\u1ECF\u1ED1\u1ED3\u1ED5\u1ED7\u1ED9\u1EDB\u1EDD\u1EDF\u1EE1\u1EE3\u1EE5\u1EE7\u1EE9\u1EEB\u1EED\u1EEF\u1EF1\u1EF3\u1EF5\u1EF7\u1EF9\u1EFB\u1EFD\u1EFF-\u1F07\u1F10-\u1F17\u1F1E-\u1F27\u1F30-\u1F37\u1F40-\u1F47\u1F4E-\u1F58\u1F5A\u1F5C\u1F5E\u1F60-\u1F67\u1F70-\u1FB7\u1FBC-\u1FC7\u1FCC-\u1FD7\u1FDC-\u1FE7\u1FED-\u1FF7\u1FFC-\u2101\u2103-\u2106\u2108-\u210A\u210E\u210F\u2113\u2114\u2116-\u2118\u211E-\u2123\u2125\u2127\u2129\u212E\u212F\u2134-\u213D\u2140-\u2144\u2146-\u2182\u2184-\u2BFF\u2C2F-\u2C5F\u2C61\u2C65\u2C66\u2C68\u2C6A\u2C6C\u2C71\u2C73\u2C74\u2C76-\u2C7D\u2C81\u2C83\u2C85\u2C87\u2C89\u2C8B\u2C8D\u2C8F\u2C91\u2C93\u2C95\u2C97\u2C99\u2C9B\u2C9D\u2C9F\u2CA1\u2CA3\u2CA5\u2CA7\u2CA9\u2CAB\u2CAD\u2CAF\u2CB1\u2CB3\u2CB5\u2CB7\u2CB9\u2CBB\u2CBD\u2CBF\u2CC1\u2CC3\u2CC5\u2CC7\u2CC9\u2CCB\u2CCD\u2CCF\u2CD1\u2CD3\u2CD5\u2CD7\u2CD9\u2CDB\u2CDD\u2CDF\u2CE1\u2CE3-\u2CEA\u2CEC\u2CEE-\u2CF1\u2CF3-\uA63F\uA641\uA643\uA645\uA647\uA649\uA64B\uA64D\uA64F\uA651\uA653\uA655\uA657\uA659\uA65B\uA65D\uA65F\uA661\uA663\uA665\uA667\uA669\uA66B\uA66D-\uA67F\uA681\uA683\uA685\uA687\uA689\uA68B\uA68D\uA68F\uA691\uA693\uA695\uA697\uA699\uA69B-\uA721\uA723\uA725\uA727\uA729\uA72B\uA72D\uA72F-\uA731\uA733\uA735\uA737\uA739\uA73B\uA73D\uA73F\uA741\uA743\uA745\uA747\uA749\uA74B\uA74D\uA74F\uA751\uA753\uA755\uA757\uA759\uA75B\uA75D\uA75F\uA761\uA763\uA765\uA767\uA769\uA76B\uA76D\uA76F-\uA778\uA77A\uA77C\uA77F\uA781\uA783\uA785\uA787-\uA78A\uA78C\uA78E\uA78F\uA791\uA793-\uA795\uA797\uA799\uA79B\uA79D\uA79F\uA7A1\uA7A3\uA7A5\uA7A7\uA7A9\uA7AE\uA7AF\uA7B5\uA7B7-\uFF20\uFF3B-\u{103FF}\u{10428}-\u{10C7F}\u{10CB3}-\u{1189F}\u{118C0}-\u{1D3FF}\u{1D41A}-\u{1D433}\u{1D44E}-\u{1D467}\u{1D482}-\u{1D49B}\u{1D49D}\u{1D4A0}\u{1D4A1}\u{1D4A3}\u{1D4A4}\u{1D4A7}\u{1D4A8}\u{1D4AD}\u{1D4B6}-\u{1D4CF}\u{1D4EA}-\u{1D503}\u{1D506}\u{1D50B}\u{1D50C}\u{1D515}\u{1D51D}-\u{1D537}\u{1D53A}\u{1D53F}\u{1D545}\u{1D547}-\u{1D549}\u{1D551}-\u{1D56B}\u{1D586}-\u{1D59F}\u{1D5BA}-\u{1D5D3}\u{1D5EE}-\u{1D607}\u{1D622}-\u{1D63B}\u{1D656}-\u{1D66F}\u{1D68A}-\u{1D6A7}\u{1D6C1}-\u{1D6E1}\u{1D6FB}-\u{1D71B}\u{1D735}-\u{1D755}\u{1D76F}-\u{1D78F}\u{1D7A9}-\u{1D7C9}\u{1D7CB}-\u{10FFFF}]/ui;
+
+for (let codePoint = 0; codePoint <= 0x10FFFF; codePoint++) {
+ const string = String.fromCodePoint(codePoint);
+ assertEquals(regexp.test(string), regexpu.test(string));
+}
diff --git a/test/mjsunit/harmony/regexp-property-scripts.js b/test/mjsunit/harmony/regexp-property-scripts.js
index ec2b11d..565a59a 100644
--- a/test/mjsunit/harmony/regexp-property-scripts.js
+++ b/test/mjsunit/harmony/regexp-property-scripts.js
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --harmony-regexp-property --harmony-unicode-regexps
+// Flags: --harmony-regexp-property
function t(re, s) { assertTrue(re.test(s)); }
function f(re, s) { assertFalse(re.test(s)); }
diff --git a/test/mjsunit/harmony/regexp-property-special.js b/test/mjsunit/harmony/regexp-property-special.js
new file mode 100644
index 0000000..204b77f
--- /dev/null
+++ b/test/mjsunit/harmony/regexp-property-special.js
@@ -0,0 +1,51 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-regexp-property
+
+function t(re, s) { assertTrue(re.test(s)); }
+function f(re, s) { assertFalse(re.test(s)); }
+
+t(/\p{ASCII}+/u, "abc123");
+f(/\p{ASCII}+/u, "ⓐⓑⓒ①②③");
+f(/\p{ASCII}+/u, "🄰🄱🄲①②③");
+f(/\P{ASCII}+/u, "abcd123");
+t(/\P{ASCII}+/u, "ⓐⓑⓒ①②③");
+t(/\P{ASCII}+/u, "🄰🄱🄲①②③");
+
+f(/[^\p{ASCII}]+/u, "abc123");
+f(/[\p{ASCII}]+/u, "ⓐⓑⓒ①②③");
+f(/[\p{ASCII}]+/u, "🄰🄱🄲①②③");
+t(/[^\P{ASCII}]+/u, "abcd123");
+t(/[\P{ASCII}]+/u, "ⓐⓑⓒ①②③");
+f(/[^\P{ASCII}]+/u, "🄰🄱🄲①②③");
+
+t(/\p{Any}+/u, "🄰🄱🄲①②③");
+
+assertEquals(["\ud800"], /\p{Any}/u.exec("\ud800\ud801"));
+assertEquals(["\udc00"], /\p{Any}/u.exec("\udc00\udc01"));
+assertEquals(["\ud800\udc01"], /\p{Any}/u.exec("\ud800\udc01"));
+assertEquals(["\udc01"], /\p{Any}/u.exec("\udc01"));
+
+f(/\P{Any}+/u, "123");
+f(/[\P{Any}]+/u, "123");
+t(/[\P{Any}\d]+/u, "123");
+t(/[^\P{Any}]+/u, "123");
+
+t(/\p{Assigned}+/u, "123");
+t(/\p{Assigned}+/u, "🄰🄱🄲");
+f(/\p{Assigned}+/u, "\ufdd0");
+f(/\p{Assigned}+/u, "\u{fffff}");
+
+f(/\P{Assigned}+/u, "123");
+f(/\P{Assigned}+/u, "🄰🄱🄲");
+t(/\P{Assigned}+/u, "\ufdd0");
+t(/\P{Assigned}+/u, "\u{fffff}");
+f(/\P{Assigned}/u, "");
+
+t(/[^\P{Assigned}]+/u, "123");
+f(/[\P{Assigned}]+/u, "🄰🄱🄲");
+f(/[^\P{Assigned}]+/u, "\ufdd0");
+t(/[\P{Assigned}]+/u, "\u{fffff}");
+f(/[\P{Assigned}]/u, "");
diff --git a/test/mjsunit/harmony/regress/regress-618603.js b/test/mjsunit/harmony/regress/regress-618603.js
new file mode 100644
index 0000000..7b23ef4
--- /dev/null
+++ b/test/mjsunit/harmony/regress/regress-618603.js
@@ -0,0 +1,14 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-async-await --ignition-generators
+
+try {
+} catch(e) {; }
+function __f_7(expected, run) {
+ var __v_10 = run();
+};
+__f_7("[1,2,3]", () => (function() {
+ return (async () => {[...await arguments] })();
+ })());
diff --git a/test/mjsunit/harmony/regress/regress-crbug-621111.js b/test/mjsunit/harmony/regress/regress-crbug-621111.js
new file mode 100644
index 0000000..58a0d5c
--- /dev/null
+++ b/test/mjsunit/harmony/regress/regress-crbug-621111.js
@@ -0,0 +1,6 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(y = 1[1, [...[]]]) => 1; // will core dump, if not fixed
+(y = 1[1, [...[]]]) => {}; // will core dump, if not fixed
diff --git a/test/mjsunit/harmony/regress/regress-crbug-621496.js b/test/mjsunit/harmony/regress/regress-crbug-621496.js
new file mode 100644
index 0000000..4db7a95
--- /dev/null
+++ b/test/mjsunit/harmony/regress/regress-crbug-621496.js
@@ -0,0 +1,7 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function testIllegalSpreadAsSingleArrowParameter() {
+ assertThrows("(...[42]) => 42)", SyntaxError) // will core dump, if not fixed
+})();
diff --git a/test/mjsunit/harmony/simd.js b/test/mjsunit/harmony/simd.js
index 1868050..a3d4615 100644
--- a/test/mjsunit/harmony/simd.js
+++ b/test/mjsunit/harmony/simd.js
@@ -622,7 +622,9 @@
function TestStringify(expected, input) {
assertEquals(expected, JSON.stringify(input));
- assertEquals(expected, JSON.stringify(input, null, 0));
+ assertEquals(expected, JSON.stringify(input, (key, value) => value));
+ assertEquals(JSON.stringify(input, null, "="),
+ JSON.stringify(input, (key, value) => value, "="));
}
TestStringify(undefined, SIMD.Float32x4(1, 2, 3, 4));
diff --git a/test/mjsunit/harmony/sloppy-legacy-duplicate-generators.js b/test/mjsunit/harmony/sloppy-legacy-duplicate-generators.js
new file mode 100644
index 0000000..1fde475
--- /dev/null
+++ b/test/mjsunit/harmony/sloppy-legacy-duplicate-generators.js
@@ -0,0 +1,60 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --no-harmony-restrictive-generators
+
+// In legacy mode, generators get sloppy-mode block-scoped function hoisting
+
+// Hoisting to the global scope
+
+{
+ function* foo() {}
+ assertEquals('function', typeof foo);
+}
+//assertEquals('function', typeof foo);
+
+// Hoisting within a function scope
+(function() {
+ { function* bar() {} }
+ assertEquals('function', typeof bar);
+})();
+
+// Lexical shadowing allowed; hoisting happens
+(function() {
+ function* x() { yield 1; }
+ { function* x() { yield 2 } }
+ assertEquals(2, x().next().value);
+})();
+
+// Duplicates allowed
+(function() {
+ function* y() { yield 1; }
+ function* y() { yield 2 }
+ assertEquals(2, y().next().value);
+})();
+
+// Functions and generators may duplicate each other
+(function() {
+ function* z() { yield 1; }
+ function z() { return 2 }
+ assertEquals(2, z());
+
+ function a() { return 1; }
+ function* a() { yield 2 }
+ assertEquals(2, a().next().value);
+})();
+
+// In strict mode, none of this happens
+
+(function() {
+ 'use strict';
+
+ { function* bar() {} }
+ assertEquals('undefined', typeof bar);
+
+ // Lexical shadowing allowed; hoisting happens
+ function* x() { yield 1; }
+ { function* x() { yield 2 } }
+ assertEquals(1, x().next().value);
+})();
diff --git a/test/mjsunit/harmony/sloppy-no-duplicate-async.js b/test/mjsunit/harmony/sloppy-no-duplicate-async.js
new file mode 100644
index 0000000..97411c0
--- /dev/null
+++ b/test/mjsunit/harmony/sloppy-no-duplicate-async.js
@@ -0,0 +1,30 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-async-await
+
+// Async functions don't get sloppy-mode block-scoped function hoisting
+
+// No hoisting to the global scope
+
+{
+ async function foo() {}
+ assertEquals('function', typeof foo);
+}
+assertEquals('undefined', typeof foo);
+
+// No hoisting within a function scope
+(function() {
+ { async function bar() {} }
+ assertEquals('undefined', typeof bar);
+})();
+
+// Lexical shadowing allowed, no hoisting
+(function() {
+ var y;
+ async function x() { y = 1; }
+ { async function x() { y = 2; } }
+ x();
+ assertEquals(1, y);
+})();
diff --git a/test/mjsunit/harmony/sloppy-no-duplicate-generators.js b/test/mjsunit/harmony/sloppy-no-duplicate-generators.js
new file mode 100644
index 0000000..de2e461
--- /dev/null
+++ b/test/mjsunit/harmony/sloppy-no-duplicate-generators.js
@@ -0,0 +1,28 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-restrictive-generators
+
+// Generators don't get sloppy-mode block-scoped function hoisting
+
+// No hoisting to the global scope
+
+{
+ function* foo() {}
+ assertEquals('function', typeof foo);
+}
+assertEquals('undefined', typeof foo);
+
+// No hoisting within a function scope
+(function() {
+ { function* bar() {} }
+ assertEquals('undefined', typeof bar);
+})();
+
+// Lexical shadowing allowed, no hoisting
+(function() {
+ function* x() { yield 1; }
+ { function* x() { yield 2 } }
+ assertEquals(1, x().next().value);
+})();
diff --git a/test/mjsunit/harmony/species.js b/test/mjsunit/harmony/species.js
deleted file mode 100644
index da1df43..0000000
--- a/test/mjsunit/harmony/species.js
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2015 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-species
-
-// Test the ES2015 @@species feature
-
-'use strict';
-
-let TypedArray = Uint8Array.__proto__;
-
-// The @@species property exists on the right objects and has the right values
-
-let classesWithSpecies = [RegExp, Array, TypedArray, ArrayBuffer, Map, Set, Promise];
-let classesWithoutSpecies = [Object, Function, String, Number, Symbol, WeakMap, WeakSet];
-
-for (let constructor of classesWithSpecies) {
- assertEquals(constructor, constructor[Symbol.species]);
- assertThrows(function() { constructor[Symbol.species] = undefined }, TypeError);
- let descriptor = Object.getOwnPropertyDescriptor(constructor, Symbol.species);
- assertTrue(descriptor.configurable);
- assertFalse(descriptor.enumerable);
- assertEquals(undefined, descriptor.writable);
- assertEquals(undefined, descriptor.set);
- assertEquals('function', typeof descriptor.get);
-}
-
-// @@species is defined with distinct getters
-assertEquals(classesWithSpecies.length,
- new Set(classesWithSpecies.map(constructor =>
- Object.getOwnPropertyDescriptor(
- constructor, Symbol.species).get)
- ).size);
-
-for (let constructor of classesWithoutSpecies)
- assertEquals(undefined, constructor[Symbol.species]);
diff --git a/test/mjsunit/harmony/string-match.js b/test/mjsunit/harmony/string-match.js
deleted file mode 100644
index 25a3ca2..0000000
--- a/test/mjsunit/harmony/string-match.js
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2015 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-regexp-subclass
-
-var pattern = {};
-pattern[Symbol.match] = function(string) {
- return string.length;
-};
-// Check object coercible fails.
-assertThrows(() => String.prototype.match.call(null, pattern),
- TypeError);
-// Override is called.
-assertEquals(5, "abcde".match(pattern));
-// Non-callable override.
-pattern[Symbol.match] = "dumdidum";
-assertThrows(() => "abcde".match(pattern), TypeError);
-
-assertEquals("[Symbol.match]", RegExp.prototype[Symbol.match].name);
diff --git a/test/mjsunit/harmony/string-replace.js b/test/mjsunit/harmony/string-replace.js
deleted file mode 100644
index 208c483..0000000
--- a/test/mjsunit/harmony/string-replace.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2015 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-regexp-subclass
-
-var pattern = {
- [Symbol.replace]: (string, newValue) => string + newValue
-};
-// Check object coercible fails.
-assertThrows(() => String.prototype.replace.call(null, pattern, "x"),
- TypeError);
-// Override is called.
-assertEquals("abcdex", "abcde".replace(pattern, "x"));
-// Non-callable override.
-pattern[Symbol.replace] = "dumdidum";
-assertThrows(() => "abcde".replace(pattern, "x"), TypeError);
-
-assertEquals("[Symbol.replace]", RegExp.prototype[Symbol.replace].name);
diff --git a/test/mjsunit/harmony/string-split.js b/test/mjsunit/harmony/string-split.js
deleted file mode 100644
index 1240d84..0000000
--- a/test/mjsunit/harmony/string-split.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2015 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-regexp-subclass
-
-var pattern = {};
-var limit = { value: 3 };
-pattern[Symbol.split] = function(string, limit) {
- return string.length * limit.value;
-};
-// Check object coercible fails.
-assertThrows(() => String.prototype.split.call(null, pattern, limit),
- TypeError);
-// Override is called.
-assertEquals(15, "abcde".split(pattern, limit));
-// Non-callable override.
-pattern[Symbol.split] = "dumdidum";
-assertThrows(() => "abcde".split(pattern, limit), TypeError);
-
-assertEquals("[Symbol.split]", RegExp.prototype[Symbol.split].name);
diff --git a/test/mjsunit/harmony/typedarray-species.js b/test/mjsunit/harmony/typedarray-species.js
deleted file mode 100644
index 35a9ea1..0000000
--- a/test/mjsunit/harmony/typedarray-species.js
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright 2015 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-species
-
-// Subclasses of %TypedArray% construct themselves under map, etc
-
-var typedArrayConstructors = [
- Uint8Array,
- Int8Array,
- Uint16Array,
- Int16Array,
- Uint32Array,
- Int32Array,
- Uint8ClampedArray,
- Float32Array,
- Float64Array
-];
-
-for (let constructor of typedArrayConstructors) {
- class MyTypedArray extends constructor { }
- assertEquals(MyTypedArray, new MyTypedArray().map(()=>0).constructor);
- assertEquals(MyTypedArray, new MyTypedArray().filter(()=>{}).constructor);
- assertEquals(MyTypedArray, new MyTypedArray().slice().constructor);
-}
-
-// Subclasses can override @@species to return the another class
-
-for (let constructor of typedArrayConstructors) {
- class MyTypedArray extends constructor { }
- class MyOtherTypedArray extends constructor {
- static get [Symbol.species]() { return MyTypedArray; }
- }
- assertEquals(MyTypedArray, new MyOtherTypedArray().map(()=>0).constructor);
- assertEquals(MyTypedArray, new MyOtherTypedArray().filter(()=>{}).constructor);
- assertEquals(MyTypedArray, new MyOtherTypedArray().slice().constructor);
-}
-
-// TypedArray too-short and non-TypedArray error checking
-
-for (let constructor of typedArrayConstructors) {
- class MyShortTypedArray extends constructor {
- constructor(length) { super(length - 1); }
- }
- assertThrows(() => new MyShortTypedArray(5).map(()=>0), TypeError);
- assertThrows(() => new MyShortTypedArray(5).filter(()=>true), TypeError);
- assertThrows(() => new MyShortTypedArray(5).slice(), TypeError);
-
- class MyNonTypedArray extends constructor {
- static get [Symbol.species]() { return Array; }
- }
- assertThrows(() => new MyNonTypedArray().map(()=>0), TypeError);
- assertThrows(() => new MyNonTypedArray().filter(()=>{}), TypeError);
- assertThrows(() => new MyNonTypedArray().slice(), TypeError);
-}
-
-// Defaults when constructor or @@species is missing or non-constructor
-
-for (let constructor of typedArrayConstructors) {
- class MyDefaultTypedArray extends constructor {
- static get [Symbol.species]() { return undefined; }
- }
- assertEquals(constructor, new MyDefaultTypedArray().map(()=>0).constructor);
-
- class MyOtherDefaultTypedArray extends constructor { }
- assertEquals(MyOtherDefaultTypedArray, new MyOtherDefaultTypedArray().map(()=>0).constructor);
- MyOtherDefaultTypedArray.prototype.constructor = undefined;
- assertEquals(constructor, new MyOtherDefaultTypedArray().map(()=>0).constructor);
-}
-
-// Exceptions propagated when getting constructor @@species throws
-
-class SpeciesError extends Error { }
-class ConstructorError extends Error { }
-
-for (let constructor of typedArrayConstructors) {
- class MyThrowingArray extends constructor {
- static get [Symbol.species]() { throw new SpeciesError; }
- }
- assertThrows(() => new MyThrowingArray().map(()=>{}), SpeciesError);
- Object.defineProperty(MyThrowingArray.prototype, 'constructor', {
- get() { throw new ConstructorError; }
- });
- assertThrows(() => new MyThrowingArray().map(()=>{}), ConstructorError);
-}
diff --git a/test/mjsunit/harmony/unicode-character-ranges.js b/test/mjsunit/harmony/unicode-character-ranges.js
deleted file mode 100644
index e4f5247..0000000
--- a/test/mjsunit/harmony/unicode-character-ranges.js
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright 2016 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-unicode-regexps --harmony-regexp-lookbehind
-
-function execl(expectation, regexp, subject) {
- if (regexp instanceof String) regexp = new RegExp(regexp, "u");
- assertEquals(expectation, regexp.exec(subject));
-}
-
-function execs(expectation, regexp_source, subject) {
- execl(expectation, new RegExp(regexp_source, "u"), subject);
-}
-
-// Character ranges.
-execl(["A"], /[A-D]/u, "A");
-execs(["A"], "[A-D]", "A");
-execl(["ABCD"], /[A-D]+/u, "ZABCDEF");
-execs(["ABCD"], "[A-D]+", "ZABCDEF");
-
-execl(["\u{12345}"], /[\u1234-\u{12345}]/u, "\u{12345}");
-execs(["\u{12345}"], "[\u1234-\u{12345}]", "\u{12345}");
-execl(null, /[^\u1234-\u{12345}]/u, "\u{12345}");
-execs(null, "[^\u1234-\u{12345}]", "\u{12345}");
-
-execl(["\u{1234}"], /[\u1234-\u{12345}]/u, "\u{1234}");
-execs(["\u{1234}"], "[\u1234-\u{12345}]", "\u{1234}");
-execl(null, /[^\u1234-\u{12345}]/u, "\u{1234}");
-execs(null, "[^\u1234-\u{12345}]", "\u{1234}");
-
-execl(null, /[\u1234-\u{12345}]/u, "\u{1233}");
-execs(null, "[\u1234-\u{12345}]", "\u{1233}");
-execl(["\u{1233}"], /[^\u1234-\u{12345}]/u, "\u{1233}");
-execs(["\u{1233}"], "[^\u1234-\u{12345}]", "\u{1233}");
-
-execl(["\u{12346}"], /[^\u1234-\u{12345}]/u, "\u{12346}");
-execs(["\u{12346}"], "[^\u1234-\u{12345}]", "\u{12346}");
-execl(null, /[\u1234-\u{12345}]/u, "\u{12346}");
-execs(null, "[\u1234-\u{12345}]", "\u{12346}");
-
-execl(["\u{12342}"], /[\u{12340}-\u{12345}]/u, "\u{12342}");
-execs(["\u{12342}"], "[\u{12340}-\u{12345}]", "\u{12342}");
-execl(["\u{12342}"], /[\ud808\udf40-\ud808\udf45]/u, "\u{12342}");
-execs(["\u{12342}"], "[\ud808\udf40-\ud808\udf45]", "\u{12342}");
-execl(null, /[^\u{12340}-\u{12345}]/u, "\u{12342}");
-execs(null, "[^\u{12340}-\u{12345}]", "\u{12342}");
-execl(null, /[^\ud808\udf40-\ud808\udf45]/u, "\u{12342}");
-execs(null, "[^\ud808\udf40-\ud808\udf45]", "\u{12342}");
-
-execl(["\u{ffff}"], /[\u{ff80}-\u{12345}]/u, "\u{ffff}");
-execs(["\u{ffff}"], "[\u{ff80}-\u{12345}]", "\u{ffff}");
-execl(["\u{ffff}"], /[\u{ff80}-\ud808\udf45]/u, "\u{ffff}");
-execs(["\u{ffff}"], "[\u{ff80}-\ud808\udf45]", "\u{ffff}");
-execl(null, /[^\u{ff80}-\u{12345}]/u, "\u{ffff}");
-execs(null, "[^\u{ff80}-\u{12345}]", "\u{ffff}");
-execl(null, /[^\u{ff80}-\ud808\udf45]/u, "\u{ffff}");
-execs(null, "[^\u{ff80}-\ud808\udf45]", "\u{ffff}");
-
-// Lone surrogate
-execl(["\ud800"], /[^\u{ff80}-\u{12345}]/u, "\uff99\u{d800}A");
-execs(["\udc00"], "[^\u{ff80}-\u{12345}]", "\uff99\u{dc00}A");
-execl(["\udc01"], /[\u0100-\u{10ffff}]/u, "A\udc01");
-execl(["\udc03"], /[\udc01-\udc03]/u, "\ud801\udc02\udc03");
-execl(["\ud801"], /[\ud801-\ud803]/u, "\ud802\udc01\ud801");
-
-// Paired sorrogate.
-execl(null, /[^\u{ff80}-\u{12345}]/u, "\u{d800}\u{dc00}");
-execs(null, "[^\u{ff80}-\u{12345}]", "\u{d800}\u{dc00}");
-execl(["\ud800\udc00"], /[\u{ff80}-\u{12345}]/u, "\u{d800}\u{dc00}");
-execs(["\ud800\udc00"], "[\u{ff80}-\u{12345}]", "\u{d800}\u{dc00}");
-execl(["foo\u{10e6d}bar"], /foo\ud803\ude6dbar/u, "foo\u{10e6d}bar");
-
-// Lone surrogates
-execl(["\ud801\ud801"], /\ud801+/u, "\ud801\udc01\ud801\ud801");
-execl(["\udc01\udc01"], /\udc01+/u, "\ud801\ud801\udc01\udc01\udc01");
-
-execl(["\udc02\udc03A"], /\W\WA/u, "\ud801\udc01A\udc02\udc03A");
-execl(["\ud801\ud802"], /\ud801./u, "\ud801\udc01\ud801\ud802");
-execl(["\udc02\udc03A"], /[\ud800-\udfff][\ud800-\udfff]A/u,
- "\ud801\udc01A\udc02\udc03A");
-
-// Character classes
-execl(null, /\w/u, "\ud801\udc01");
-execl(["\ud801"], /[^\w]/, "\ud801\udc01");
-execl(["\ud801\udc01"], /[^\w]/u, "\ud801\udc01");
-execl(["\ud801"], /\W/, "\ud801\udc01");
-execl(["\ud801\udc01"], /\W/u, "\ud801\udc01");
-
-execl(["\ud800X"], /.X/u, "\ud800XaX");
-execl(["aX"], /.(?<!\ud800)X/u, "\ud800XaX");
-execl(["aX"], /.(?<![\ud800-\ud900])X/u, "\ud800XaX");
-
-execl(null, /[]/u, "\u1234");
-execl(["0abc"], /[^]abc/u, "0abc");
-execl(["\u1234abc"], /[^]abc/u, "\u1234abc");
-execl(["\u{12345}abc"], /[^]abc/u, "\u{12345}abc");
-
-execl(null, /[\u{0}-\u{1F444}]/u, "\ud83d\udfff");
-
-// Backward matches of lone surrogates.
-execl(["B", "\ud803A"], /(?<=([\ud800-\ud900]A))B/u,
- "\ud801\udc00AB\udc00AB\ud802\ud803AB");
-execl(["B", "\udc00A"], /(?<=([\ud800-\u{10300}]A))B/u,
- "\ud801\udc00AB\udc00AB\ud802\ud803AB");
-execl(["B", "\udc11A"], /(?<=([\udc00-\udd00]A))B/u,
- "\ud801\udc00AB\udc11AB\ud802\ud803AB");
-execl(["X", "\ud800C"], /(?<=(\ud800\w))X/u,
- "\ud800\udc00AX\udc11BX\ud800\ud800CX");
-execl(["C", "\ud800\ud800"], /(?<=(\ud800.))\w/u,
- "\ud800\udc00AX\udc11BX\ud800\ud800CX");
-execl(["X", "\udc01C"], /(?<=(\udc01\w))X/u,
- "\ud800\udc01AX\udc11BX\udc01\udc01CX");
-execl(["C", "\udc01\udc01"], /(?<=(\udc01.))./u,
- "\ud800\udc01AX\udc11BX\udc01\udc01CX");
-
-var L = "\ud800";
-var T = "\udc00";
-var X = "X";
-
-// Test string contains only match.
-function testw(expect, src, subject) {
- var re = new RegExp("^" + src + "$", "u");
- assertEquals(expect, re.test(subject));
-}
-
-// Test string starts with match.
-function tests(expect, src, subject) {
- var re = new RegExp("^" + src, "u");
- assertEquals(expect, re.test(subject));
-}
-
-testw(true, X, X);
-testw(true, L, L);
-testw(true, T, T);
-testw(true, L + T, L + T);
-testw(true, T + L, T + L);
-testw(false, T, L + T);
-testw(false, L, L + T);
-testw(true, ".(?<=" + L + ")", L);
-testw(true, ".(?<=" + T + ")", T);
-testw(true, ".(?<=" + L + T + ")", L + T);
-testw(true, ".(?<=" + L + T + ")", L + T);
-tests(true, ".(?<=" + T + ")", T + L);
-tests(false, ".(?<=" + L + ")", L + T);
-tests(false, ".(?<=" + T + ")", L + T);
-tests(true, "..(?<=" + T + ")", T + T + L);
-tests(true, "..(?<=" + T + ")", X + T + L);
-tests(true, "...(?<=" + L + ")", X + T + L);
-tests(false, "...(?<=" + T + ")", X + L + T)
-tests(true, "..(?<=" + L + T + ")", X + L + T)
-tests(true, "..(?<=" + L + T + "(?<=" + L + T + "))", X + L + T);
-tests(false, "..(?<=" + L + "(" + T + "))", X + L + T);
-tests(false, ".*" + L, X + L + T);
-tests(true, ".*" + L, X + L + L + T);
-tests(false, ".*" + L, X + L + T + L + T);
-tests(false, ".*" + T, X + L + T + L + T);
-tests(true, ".*" + T, X + L + T + T + L + T);
diff --git a/test/mjsunit/harmony/unicode-escapes-in-regexps.js b/test/mjsunit/harmony/unicode-escapes-in-regexps.js
deleted file mode 100644
index 7ea6f62..0000000
--- a/test/mjsunit/harmony/unicode-escapes-in-regexps.js
+++ /dev/null
@@ -1,287 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// ES6 extends the \uxxxx escape and also allows \u{xxxxx}.
-
-// Flags: --harmony-unicode-regexps
-
-function testRegexpHelper(r) {
- assertTrue(r.test("foo"));
- assertTrue(r.test("boo"));
- assertFalse(r.test("moo"));
-}
-
-
-(function TestUnicodeEscapes() {
- testRegexpHelper(/(\u0066|\u0062)oo/);
- testRegexpHelper(/(\u0066|\u0062)oo/u);
- testRegexpHelper(/(\u{0066}|\u{0062})oo/u);
- testRegexpHelper(/(\u{66}|\u{000062})oo/u);
-
- // Note that we need \\ inside a string, otherwise it's interpreted as a
- // unicode escape inside a string.
- testRegexpHelper(new RegExp("(\\u0066|\\u0062)oo"));
- testRegexpHelper(new RegExp("(\\u0066|\\u0062)oo", "u"));
- testRegexpHelper(new RegExp("(\\u{0066}|\\u{0062})oo", "u"));
- testRegexpHelper(new RegExp("(\\u{66}|\\u{000062})oo", "u"));
-
- // Though, unicode escapes via strings should work too.
- testRegexpHelper(new RegExp("(\u0066|\u0062)oo"));
- testRegexpHelper(new RegExp("(\u0066|\u0062)oo", "u"));
- testRegexpHelper(new RegExp("(\u{0066}|\u{0062})oo", "u"));
- testRegexpHelper(new RegExp("(\u{66}|\u{000062})oo", "u"));
-})();
-
-
-(function TestUnicodeEscapesInCharacterClasses() {
- testRegexpHelper(/[\u0062-\u0066]oo/);
- testRegexpHelper(/[\u0062-\u0066]oo/u);
- testRegexpHelper(/[\u{0062}-\u{0066}]oo/u);
- testRegexpHelper(/[\u{62}-\u{00000066}]oo/u);
-
- // Note that we need \\ inside a string, otherwise it's interpreted as a
- // unicode escape inside a string.
- testRegexpHelper(new RegExp("[\\u0062-\\u0066]oo"));
- testRegexpHelper(new RegExp("[\\u0062-\\u0066]oo", "u"));
- testRegexpHelper(new RegExp("[\\u{0062}-\\u{0066}]oo", "u"));
- testRegexpHelper(new RegExp("[\\u{62}-\\u{00000066}]oo", "u"));
-
- // Though, unicode escapes via strings should work too.
- testRegexpHelper(new RegExp("[\u0062-\u0066]oo"));
- testRegexpHelper(new RegExp("[\u0062-\u0066]oo", "u"));
- testRegexpHelper(new RegExp("[\u{0062}-\u{0066}]oo", "u"));
- testRegexpHelper(new RegExp("[\u{62}-\u{00000066}]oo", "u"));
-})();
-
-
-(function TestBraceEscapesWithoutUnicodeFlag() {
- // \u followed by illegal escape will be parsed as u. {x} will be the
- // character count.
- function helper1(r) {
- assertFalse(r.test("fbar"));
- assertFalse(r.test("fubar"));
- assertTrue(r.test("fuubar"));
- assertFalse(r.test("fuuubar"));
- }
- helper1(/f\u{2}bar/);
- helper1(new RegExp("f\\u{2}bar"));
-
- function helper2(r) {
- assertFalse(r.test("fbar"));
- assertTrue(r.test("fubar"));
- assertTrue(r.test("fuubar"));
- assertFalse(r.test("fuuubar"));
- }
-
- helper2(/f\u{1,2}bar/);
- helper2(new RegExp("f\\u{1,2}bar"));
-
- function helper3(r) {
- assertTrue(r.test("u"));
- assertTrue(r.test("{"));
- assertTrue(r.test("2"));
- assertTrue(r.test("}"));
- assertFalse(r.test("q"));
- assertFalse(r.test("("));
- assertFalse(r.test(")"));
- }
- helper3(/[\u{2}]/);
- helper3(new RegExp("[\\u{2}]"));
-})();
-
-
-(function TestInvalidEscapes() {
- // Without the u flag, invalid unicode escapes and other invalid escapes are
- // treated as identity escapes.
- function helper1(r) {
- assertTrue(r.test("firstuxz89second"));
- }
- helper1(/first\u\x\z\8\9second/);
- helper1(new RegExp("first\\u\\x\\z\\8\\9second"));
-
- function helper2(r) {
- assertTrue(r.test("u"));
- assertTrue(r.test("x"));
- assertTrue(r.test("z"));
- assertTrue(r.test("8"));
- assertTrue(r.test("9"));
- assertFalse(r.test("q"));
- assertFalse(r.test("7"));
- }
- helper2(/[\u\x\z\8\9]/);
- helper2(new RegExp("[\\u\\x\\z\\8\\9]"));
-
- // However, with the u flag, these are treated as invalid escapes.
- assertThrows("/\\u/u", SyntaxError);
- assertThrows("/\\u12/u", SyntaxError);
- assertThrows("/\\ufoo/u", SyntaxError);
- assertThrows("/\\x/u", SyntaxError);
- assertThrows("/\\xfoo/u", SyntaxError);
- assertThrows("/\\z/u", SyntaxError);
- assertThrows("/\\8/u", SyntaxError);
- assertThrows("/\\9/u", SyntaxError);
-
- assertThrows("new RegExp('\\\\u', 'u')", SyntaxError);
- assertThrows("new RegExp('\\\\u12', 'u')", SyntaxError);
- assertThrows("new RegExp('\\\\ufoo', 'u')", SyntaxError);
- assertThrows("new RegExp('\\\\x', 'u')", SyntaxError);
- assertThrows("new RegExp('\\\\xfoo', 'u')", SyntaxError);
- assertThrows("new RegExp('\\\\z', 'u')", SyntaxError);
- assertThrows("new RegExp('\\\\8', 'u')", SyntaxError);
- assertThrows("new RegExp('\\\\9', 'u')", SyntaxError);
-})();
-
-
-(function TestTooBigHexEscape() {
- // The hex number inside \u{} has a maximum value.
- /\u{10ffff}/u
- new RegExp("\\u{10ffff}", "u")
- assertThrows("/\\u{110000}/u", SyntaxError);
- assertThrows("new RegExp('\\\\u{110000}', 'u')", SyntaxError);
-
- // Without the u flag, they're of course fine ({x} is the count).
- /\u{110000}/
- new RegExp("\\u{110000}")
-})();
-
-
-(function TestSyntaxEscapes() {
- // Syntax escapes work the same with or without the u flag.
- function helper(r) {
- assertTrue(r.test("foo[bar"));
- assertFalse(r.test("foo]bar"));
- }
- helper(/foo\[bar/);
- helper(new RegExp("foo\\[bar"));
- helper(/foo\[bar/u);
- helper(new RegExp("foo\\[bar", "u"));
-})();
-
-
-(function TestUnicodeSurrogates() {
- // U+10E6D corresponds to the surrogate pair [U+D803, U+DE6D].
- function helper(r) {
- assertTrue(r.test("foo\u{10e6d}bar"));
- }
- helper(/foo\ud803\ude6dbar/u);
- helper(new RegExp("foo\\ud803\\ude6dbar", "u"));
-})();
-
-
-(function AllFlags() {
- // Test that we can pass all possible regexp flags and they work properly.
- function helper1(r) {
- assertTrue(r.global);
- assertTrue(r.ignoreCase);
- assertTrue(r.multiline);
- assertTrue(r.sticky);
- assertTrue(r.unicode);
- }
-
- helper1(/foo/gimyu);
- helper1(new RegExp("foo", "gimyu"));
-
- function helper2(r) {
- assertFalse(r.global);
- assertFalse(r.ignoreCase);
- assertFalse(r.multiline);
- assertFalse(r.sticky);
- assertFalse(r.unicode);
- }
-
- helper2(/foo/);
- helper2(new RegExp("foo"));
-})();
-
-
-(function DuplicatedFlags() {
- // Test that duplicating the u flag is not allowed.
- assertThrows("/foo/ugu");
- assertThrows("new RegExp('foo', 'ugu')");
-})();
-
-
-(function ToString() {
- // Test that the u flag is included in the string representation of regexps.
- function helper(r) {
- assertEquals(r.toString(), "/foo/u");
- }
- helper(/foo/u);
- helper(new RegExp("foo", "u"));
-})();
-
-// Non-BMP patterns.
-// Single character atom.
-assertTrue(new RegExp("\u{12345}", "u").test("\u{12345}"));
-assertTrue(/\u{12345}/u.test("\u{12345}"));
-assertTrue(new RegExp("\u{12345}", "u").test("\ud808\udf45"));
-assertTrue(/\u{12345}/u.test("\ud808\udf45"));
-assertFalse(new RegExp("\u{12345}", "u").test("\udf45"));
-assertFalse(/\u{12345}/u.test("\udf45"));
-
-// Multi-character atom.
-assertTrue(new RegExp("\u{12345}\u{23456}", "u").test("a\u{12345}\u{23456}b"));
-assertTrue(/\u{12345}\u{23456}/u.test("b\u{12345}\u{23456}c"));
-assertFalse(new RegExp("\u{12345}\u{23456}", "u").test("a\udf45\u{23456}b"));
-assertFalse(/\u{12345}\u{23456}/u.test("b\udf45\u{23456}c"));
-
-// Disjunction.
-assertTrue(new RegExp("\u{12345}(?:\u{23456})", "u").test(
- "a\u{12345}\u{23456}b"));
-assertTrue(/\u{12345}(?:\u{23456})/u.test("b\u{12345}\u{23456}c"));
-assertFalse(new RegExp("\u{12345}(?:\u{23456})", "u").test(
- "a\udf45\u{23456}b"));
-assertFalse(/\u{12345}(?:\u{23456})/u.test("b\udf45\u{23456}c"));
-
-// Alternative.
-assertTrue(new RegExp("\u{12345}|\u{23456}", "u").test("a\u{12345}b"));
-assertTrue(/\u{12345}|\u{23456}/u.test("b\u{23456}c"));
-assertFalse(new RegExp("\u{12345}|\u{23456}", "u").test("a\udf45\ud84db"));
-assertFalse(/\u{12345}|\u{23456}/u.test("b\udf45\ud808c"));
-
-// Capture.
-assertTrue(new RegExp("(\u{12345}|\u{23456}).\\1", "u").test(
- "\u{12345}b\u{12345}"));
-assertTrue(/(\u{12345}|\u{23456}).\1/u.test("\u{12345}b\u{12345}"));
-assertFalse(new RegExp("(\u{12345}|\u{23456}).\\1", "u").test(
- "\u{12345}b\u{23456}"));
-assertFalse(/(\u{12345}|\u{23456}).\1/u.test("\u{12345}b\u{23456}"));
-
-// Quantifier.
-assertTrue(new RegExp("\u{12345}{3}", "u").test("\u{12345}\u{12345}\u{12345}"));
-assertTrue(/\u{12345}{3}/u.test("\u{12345}\u{12345}\u{12345}"));
-assertTrue(new RegExp("\u{12345}{3}").test("\u{12345}\udf45\udf45"));
-assertFalse(/\ud808\udf45{3}/u.test("\u{12345}\udf45\udf45"));
-assertTrue(/\ud808\udf45{3}/u.test("\u{12345}\u{12345}\u{12345}"));
-assertFalse(new RegExp("\u{12345}{3}", "u").test("\u{12345}\udf45\udf45"));
-assertFalse(/\u{12345}{3}/u.test("\u{12345}\udf45\udf45"));
-
-// Literal surrogates.
-assertEquals(["\u{10000}\u{10000}"],
- new RegExp("\ud800\udc00+", "u").exec("\u{10000}\u{10000}"));
-assertEquals(["\u{10000}\u{10000}"],
- new RegExp("\\ud800\\udc00+", "u").exec("\u{10000}\u{10000}"));
-
-assertEquals(["\u{10003}\u{50001}"],
- new RegExp("[\\ud800\\udc03-\\ud900\\udc01\]+", "u").exec(
- "\u{10003}\u{50001}"));
-assertEquals(["\u{10003}\u{50001}"],
- new RegExp("[\ud800\udc03-\u{50001}\]+", "u").exec(
- "\u{10003}\u{50001}"));
-
-// Unicode escape sequences to represent a non-BMP character cannot have
-// mixed notation, and must follow the rules for RegExpUnicodeEscapeSequence.
-assertThrows(() => new RegExp("[\\ud800\udc03-\ud900\\udc01\]+", "u"));
-assertThrows(() => new RegExp("[\\ud800\udc03-\ud900\\udc01\]+", "u"));
-assertNull(new RegExp("\\ud800\udc00+", "u").exec("\u{10000}\u{10000}"));
-assertNull(new RegExp("\ud800\\udc00+", "u").exec("\u{10000}\u{10000}"));
-
-assertNull(new RegExp("[\\ud800\udc00]", "u").exec("\u{10000}"));
-assertNull(new RegExp("[\\{ud800}\udc00]", "u").exec("\u{10000}"));
-assertNull(new RegExp("[\ud800\\udc00]", "u").exec("\u{10000}"));
-assertNull(new RegExp("[\ud800\\{udc00}]", "u").exec("\u{10000}"));
-
-assertNull(/\u{d800}\u{dc00}+/u.exec("\ud800\udc00\udc00"));
-assertNull(/\ud800\u{dc00}+/u.exec("\ud800\udc00\udc00"));
-assertNull(/\u{d800}\udc00+/u.exec("\ud800\udc00\udc00"));
diff --git a/test/mjsunit/harmony/unicode-regexp-backrefs.js b/test/mjsunit/harmony/unicode-regexp-backrefs.js
deleted file mode 100644
index e02301b..0000000
--- a/test/mjsunit/harmony/unicode-regexp-backrefs.js
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2016 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-unicode-regexps --harmony-regexp-lookbehind
-
-// Back reference does not end in the middle of a surrogate pair.
-function replace(string) {
- return string.replace(/L/g, "\ud800")
- .replace(/l/g, "\ud801")
- .replace(/T/g, "\udc00")
- .replace(/\./g, "[^]");
-}
-
-function test(expectation, regexp_source, subject) {
- if (expectation !== null) expectation = expectation.map(replace);
- subject = replace(subject);
- regexp_source = replace(regexp_source);
- assertEquals(expectation, new RegExp(regexp_source, "u").exec(subject));
-}
-
-// Back reference does not end in the middle of a surrogate pair.
-test(null, "(L)\\1", "LLT");
-test(["LLTLl", "L", "l"], "(L).*\\1(.)", "LLTLl");
-test(null, "(aL).*\\1", "aLaLT");
-test(["aLaLTaLl", "aL", "l"], "(aL).*\\1(.)", "aLaLTaLl");
-
-var s = "TabcLxLTabcLxTabcLTyTabcLz";
-test([s, "TabcL", "z"], "([^x]+).*\\1(.)", s);
-
-// Back reference does not start in the middle of a surrogate pair.
-test(["TLTabTc", "T", "c"], "(T).*\\1(.)", "TLTabTc");
-
-// Lookbehinds.
-test(null, "(?<=\\1(T)x)", "LTTx");
-test(["", "b", "T"], "(?<=(.)\\2.*(T)x)", "bTaLTTx");
-test(null, "(?<=\\1.*(L)x)", "LTLx");
-test(["", "b", "L"], "(?<=(.)\\2.*(L)x)", "bLaLTLx");
-
-
-test(null, "([^x]+)x*\\1", "LxLT");
-test(null, "([^x]+)x*\\1", "TxLT");
-test(null, "([^x]+)x*\\1", "LTxL");
-test(null, "([^x]+)x*\\1", "LTxT");
-test(null, "([^x]+)x*\\1", "xLxLT");
-test(null, "([^x]+)x*\\1", "xTxLT");
-test(null, "([^x]+)x*\\1", "xLTxL");
-test(null, "([^x]+)x*\\1", "xLTxT");
-test(null, "([^x]+)x*\\1", "xxxLxxLTxx");
-test(null, "([^x]+)x*\\1", "xxxTxxLTxx");
-test(null, "([^x]+)x*\\1", "xxxLTxxLxx");
-test(null, "([^x]+)x*\\1", "xxxLTxxTxx");
-test(["LTTxxLTT", "LTT"], "([^x]+)x*\\1", "xxxLTTxxLTTxx");
diff --git a/test/mjsunit/harmony/unicode-regexp-ignore-case-noi18n.js b/test/mjsunit/harmony/unicode-regexp-ignore-case-noi18n.js
deleted file mode 100644
index a4cb9dc..0000000
--- a/test/mjsunit/harmony/unicode-regexp-ignore-case-noi18n.js
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2016 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-unicode-regexps
-
-// Non-unicode use toUpperCase mappings.
-assertFalse(/[\u00e5]/i.test("\u212b"));
-assertFalse(/[\u212b]/i.test("\u00e5\u1234"));
-assertFalse(/[\u212b]/i.test("\u00e5"));
-
-assertTrue("\u212b".toLowerCase() == "\u00e5");
-assertTrue("\u00c5".toLowerCase() == "\u00e5");
-assertTrue("\u00e5".toUpperCase() == "\u00c5");
-
-// Unicode uses case folding mappings.
-assertFalse(/\u00e5/ui.test("\u212b"));
-assertTrue(/\u00e5/ui.test("\u00c5"));
-assertTrue(/\u00e5/ui.test("\u00e5"));
-assertFalse(/\u00e5/ui.test("\u212b"));
-assertTrue(/\u00c5/ui.test("\u00e5"));
-assertFalse(/\u00c5/ui.test("\u212b"));
-assertTrue(/\u00c5/ui.test("\u00c5"));
-assertFalse(/\u212b/ui.test("\u00c5"));
-assertFalse(/\u212b/ui.test("\u00e5"));
-assertTrue(/\u212b/ui.test("\u212b"));
-
-// Non-BMP.
-assertFalse(/\u{10400}/i.test("\u{10428}"));
-assertFalse(/\u{10400}/ui.test("\u{10428}"));
-assertFalse(/\ud801\udc00/ui.test("\u{10428}"));
-assertFalse(/[\u{10428}]/ui.test("\u{10400}"));
-assertFalse(/[\ud801\udc28]/ui.test("\u{10400}"));
-assertEquals(["\uff21\u{10400}"],
- /[\uff40-\u{10428}]+/ui.exec("\uff21\u{10400}abc"));
-assertEquals(["abc"], /[^\uff40-\u{10428}]+/ui.exec("\uff21\u{10400}abc\uff23"));
-assertEquals(["\uff53\u24bb"],
- /[\u24d5-\uff33]+/ui.exec("\uff54\uff53\u24bb\u24ba"));
-
-// Full mappings are ignored.
-assertFalse(/\u00df/ui.test("SS"));
-assertFalse(/\u1f8d/ui.test("\u1f05\u03b9"));
-
-// Simple mappings.
-assertFalse(/\u1f8d/ui.test("\u1f85"));
-
-// Common mappings.
-assertTrue(/\u1f6b/ui.test("\u1f63"));
-
-// Back references.
-assertNull(/(.)\1\1/ui.exec("\u00e5\u212b\u00c5"));
-assertNull(/(.)\1/ui.exec("\u{118aa}\u{118ca}"));
-
-
-// Non-Latin1 maps to Latin1.
-assertNull(/^\u017F/ui.exec("s"));
-assertNull(/^\u017F/ui.exec("s\u1234"));
-assertNull(/^a[\u017F]/ui.exec("as"));
-assertNull(/^a[\u017F]/ui.exec("as\u1234"));
diff --git a/test/mjsunit/harmony/unicode-regexp-ignore-case.js b/test/mjsunit/harmony/unicode-regexp-ignore-case.js
deleted file mode 100644
index 291b866..0000000
--- a/test/mjsunit/harmony/unicode-regexp-ignore-case.js
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2016 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-unicode-regexps
-
-// Non-unicode use toUpperCase mappings.
-assertFalse(/[\u00e5]/i.test("\u212b"));
-assertFalse(/[\u212b]/i.test("\u00e5\u1234"));
-assertFalse(/[\u212b]/i.test("\u00e5"));
-
-assertTrue("\u212b".toLowerCase() == "\u00e5");
-assertTrue("\u00c5".toLowerCase() == "\u00e5");
-assertTrue("\u00e5".toUpperCase() == "\u00c5");
-
-// Unicode uses case folding mappings.
-assertTrue(/\u00e5/ui.test("\u212b"));
-assertTrue(/\u00e5/ui.test("\u00c5"));
-assertTrue(/\u00e5/ui.test("\u00e5"));
-assertTrue(/\u00e5/ui.test("\u212b"));
-assertTrue(/\u00c5/ui.test("\u00e5"));
-assertTrue(/\u00c5/ui.test("\u212b"));
-assertTrue(/\u00c5/ui.test("\u00c5"));
-assertTrue(/\u212b/ui.test("\u00c5"));
-assertTrue(/\u212b/ui.test("\u00e5"));
-assertTrue(/\u212b/ui.test("\u212b"));
-
-// Non-BMP.
-assertFalse(/\u{10400}/i.test("\u{10428}"));
-assertTrue(/\u{10400}/ui.test("\u{10428}"));
-assertTrue(/\ud801\udc00/ui.test("\u{10428}"));
-assertTrue(/[\u{10428}]/ui.test("\u{10400}"));
-assertTrue(/[\ud801\udc28]/ui.test("\u{10400}"));
-assertEquals(["\uff21\u{10400}"],
- /[\uff40-\u{10428}]+/ui.exec("\uff21\u{10400}abc"));
-assertEquals(["abc"], /[^\uff40-\u{10428}]+/ui.exec("\uff21\u{10400}abc\uff23"));
-assertEquals(["\uff53\u24bb"],
- /[\u24d5-\uff33]+/ui.exec("\uff54\uff53\u24bb\u24ba"));
-
-// Full mappings are ignored.
-assertFalse(/\u00df/ui.test("SS"));
-assertFalse(/\u1f8d/ui.test("\u1f05\u03b9"));
-
-// Simple mappings work.
-assertTrue(/\u1f8d/ui.test("\u1f85"));
-
-// Common mappings work.
-assertTrue(/\u1f6b/ui.test("\u1f63"));
-
-// Back references.
-assertEquals(["\u00e5\u212b\u00c5", "\u00e5"],
- /(.)\1\1/ui.exec("\u00e5\u212b\u00c5"));
-assertEquals(["\u{118aa}\u{118ca}", "\u{118aa}"],
- /(.)\1/ui.exec("\u{118aa}\u{118ca}"));
-
-// Misc.
-assertTrue(/\u00e5\u00e5\u00e5/ui.test("\u212b\u00e5\u00c5"));
-assertTrue(/AB\u{10400}/ui.test("ab\u{10428}"));
-
-// Non-Latin1 maps to Latin1.
-assertEquals(["s"], /^\u017F/ui.exec("s"));
-assertEquals(["s"], /^\u017F/ui.exec("s\u1234"));
-assertEquals(["as"], /^a[\u017F]/ui.exec("as"));
-assertEquals(["as"], /^a[\u017F]/ui.exec("as\u1234"));
diff --git a/test/mjsunit/harmony/unicode-regexp-last-index.js b/test/mjsunit/harmony/unicode-regexp-last-index.js
deleted file mode 100644
index 4a075d4..0000000
--- a/test/mjsunit/harmony/unicode-regexp-last-index.js
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright 2016 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-unicode-regexps --harmony-regexp-lookbehind
-
-var r = /./ug;
-assertEquals(["\ud800\udc00"], r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(2, r.lastIndex);
-r.lastIndex = 1;
-assertEquals(["\ud800\udc00"], r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(2, r.lastIndex);
-assertEquals(["\ud801\udc01"], r.exec("\ud800\udc00\ud801\udc01"));
-r.lastIndex = 3;
-assertEquals(["\ud801\udc01"], r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(4, r.lastIndex);
-r.lastIndex = 4;
-assertNull(r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(0, r.lastIndex);
-r.lastIndex = 5;
-assertNull(r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(0, r.lastIndex);
-
-r.lastIndex = 3;
-assertEquals(["\ud802"], r.exec("\ud800\udc00\ud801\ud802"));
-r.lastIndex = 4;
-assertNull(r.exec("\ud800\udc00\ud801\ud802"));
-
-r = /./g;
-assertEquals(["\ud800"], r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(1, r.lastIndex);
-assertEquals(["\udc00"], r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(2, r.lastIndex);
-assertEquals(["\ud801"], r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(3, r.lastIndex);
-assertEquals(["\udc01"], r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(4, r.lastIndex);
-assertNull(r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(0, r.lastIndex);
-r.lastIndex = 1;
-assertEquals(["\udc00"], r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(2, r.lastIndex);
-
-// ------------------------
-
-r = /^./ug;
-assertEquals(["\ud800\udc00"], r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(2, r.lastIndex);
-r.lastIndex = 1;
-assertEquals(["\ud800\udc00"], r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(2, r.lastIndex);
-assertNull(r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(0, r.lastIndex);
-r.lastIndex = 3;
-assertNull(r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(0, r.lastIndex);
-r.lastIndex = 4;
-assertNull(r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(0, r.lastIndex);
-r.lastIndex = 5;
-assertNull(r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(0, r.lastIndex);
-
-r = /^./g;
-assertEquals(["\ud800"], r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(1, r.lastIndex);
-assertNull(r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(0, r.lastIndex);
-r.lastIndex = 3;
-assertNull(r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(0, r.lastIndex);
-
-//------------------------
-
-r = /(?:(^.)|.)/ug;
-assertEquals(["\ud800\udc00", "\ud800\udc00"],
- r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(2, r.lastIndex);
-r.lastIndex = 1;
-assertEquals(["\ud800\udc00", "\ud800\udc00"],
- r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(2, r.lastIndex);
-assertEquals(["\ud801\udc01", undefined], r.exec("\ud800\udc00\ud801\udc01"));
-r.lastIndex = 3;
-assertEquals(["\ud801\udc01", undefined], r.exec("\ud800\udc00\ud801\udc01"));
-r.lastIndex = 4;
-assertNull(r.exec("\ud800\udc00\ud801\udc01"));
-r.lastIndex = 5;
-assertNull(r.exec("\ud800\udc00\ud801\udc01"));
-
-r.lastIndex = 3;
-assertEquals(["\ud802", undefined], r.exec("\ud800\udc00\ud801\ud802"));
-r.lastIndex = 4;
-assertNull(r.exec("\ud800\udc00\ud801\ud802"));
-
-r = /(?:(^.)|.)/g;
-assertEquals(["\ud800", "\ud800"],
- r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(1, r.lastIndex);
-assertEquals(["\udc00", undefined], r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(2, r.lastIndex);
-r.lastIndex = 3;
-assertEquals(["\udc01", undefined], r.exec("\ud800\udc00\ud801\udc01"));
-assertEquals(4, r.lastIndex);
diff --git a/test/mjsunit/harmony/unicode-regexp-restricted-syntax.js b/test/mjsunit/harmony/unicode-regexp-restricted-syntax.js
deleted file mode 100644
index d129cc3..0000000
--- a/test/mjsunit/harmony/unicode-regexp-restricted-syntax.js
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2016 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-unicode-regexps
-
-// test262/data/test/language/literals/regexp/u-dec-esc
-assertThrows("/\\1/u", SyntaxError);
-// test262/language/literals/regexp/u-invalid-char-range-a
-assertThrows("/[\\w-a]/u", SyntaxError);
-// test262/language/literals/regexp/u-invalid-char-range-b
-assertThrows("/[a-\\w]/u", SyntaxError);
-// test262/language/literals/regexp/u-invalid-char-esc
-assertThrows("/\\c/u", SyntaxError);
-assertThrows("/\\c0/u", SyntaxError);
-// test262/built-ins/RegExp/unicode_restricted_quantifiable_assertion
-assertThrows("/(?=.)*/u", SyntaxError);
-// test262/built-ins/RegExp/unicode_restricted_octal_escape
-assertThrows("/[\\1]/u", SyntaxError);
-assertThrows("/\\00/u", SyntaxError);
-assertThrows("/\\09/u", SyntaxError);
-// test262/built-ins/RegExp/unicode_restricted_identity_escape_alpha
-assertThrows("/[\\c]/u", SyntaxError);
-// test262/built-ins/RegExp/unicode_restricted_identity_escape_c
-assertThrows("/[\\c0]/u", SyntaxError);
-// test262/built-ins/RegExp/unicode_restricted_incomple_quantifier
-assertThrows("/a{/u", SyntaxError);
-assertThrows("/a{1,/u", SyntaxError);
-assertThrows("/{/u", SyntaxError);
-assertThrows("/}/u", SyntaxError);
-// test262/data/test/built-ins/RegExp/unicode_restricted_brackets
-assertThrows("/]/u", SyntaxError);
-// test262/built-ins/RegExp/unicode_identity_escape
-/\//u;
-
-// escaped \0 is allowed inside a character class.
-assertEquals(["\0"], /[\0]/u.exec("\0"));
-// unless it is followed by another digit.
-assertThrows("/[\\00]/u", SyntaxError);
-assertThrows("/[\\01]/u", SyntaxError);
-assertThrows("/[\\09]/u", SyntaxError);
-assertEquals(["\u{0}1\u{0}a\u{0}"], /[1\0a]+/u.exec("b\u{0}1\u{0}a\u{0}2"));
-// escaped \- is allowed inside a character class.
-assertEquals(["-"], /[a\-z]/u.exec("12-34"));
diff --git a/test/mjsunit/harmony/unicode-regexp-unanchored-advance.js b/test/mjsunit/harmony/unicode-regexp-unanchored-advance.js
deleted file mode 100644
index 97960e1..0000000
--- a/test/mjsunit/harmony/unicode-regexp-unanchored-advance.js
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2013 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-unicode-regexps
-
-var s = "a".repeat(1E7) + "\u1234";
-assertEquals(["\u1234", "\u1234"], /(\u1234)/u.exec(s));
diff --git a/test/mjsunit/harmony/unicode-regexp-zero-length.js b/test/mjsunit/harmony/unicode-regexp-zero-length.js
deleted file mode 100644
index bbc17dc..0000000
--- a/test/mjsunit/harmony/unicode-regexp-zero-length.js
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2016 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-unicode-regexps
-
-var L = "\ud800";
-var T = "\udc00";
-var x = "x";
-
-var r = /()/g; // Global, but not unicode.
-// Zero-length matches do not advance lastIndex.
-assertEquals(["", ""], r.exec(L + T + L + T));
-assertEquals(0, r.lastIndex);
-r.lastIndex = 1;
-assertEquals(["", ""], r.exec(L + T + L + T));
-assertEquals(1, r.lastIndex);
-
-var u = /()/ug; // Global and unicode.
-// Zero-length matches do not advance lastIndex.
-assertEquals(["", ""], u.exec(L + T + L + T));
-assertEquals(0, u.lastIndex);
-u.lastIndex = 1;
-assertEquals(["", ""], u.exec(L + T + L + T));
-assertEquals(0, u.lastIndex);
-
-// However, with repeating matches, lastIndex does not matter.
-// We do advance from match to match.
-r.lastIndex = 2;
-assertEquals(x + L + x + T + x + L + x + T + x,
- (L + T + L + T).replace(r, "x"));
-
-// With unicode flag, we advance code point by code point.
-u.lastIndex = 3;
-assertEquals(x + L + T + x + L + T + x,
- (L + T + L + T).replace(u, "x"));
-
-// Test that exhausting the global match cache is fine.
-assertEquals((x + L + T).repeat(1000) + x,
- (L + T).repeat(1000).replace(u, "x"));
-
-// Same thing for RegExp.prototype.match.
-r.lastIndex = 1;
-assertEquals(["","","","",""], (L + T + L + T).match(r));
-r.lastIndex = 2;
-assertEquals(["","","","",""], (L + T + L + T).match(r));
-
-u.lastIndex = 1;
-assertEquals(["","",""], (L + T + L + T).match(u));
-u.lastIndex = 2;
-assertEquals(["","",""], (L + T + L + T).match(u));
-
-var expected = [];
-for (var i = 0; i <= 1000; i++) expected.push("");
-assertEquals(expected, (L + T).repeat(1000).match(u));
-
-// Also test RegExp.prototype.@@split.
-assertEquals(["\u{12345}"], "\u{12345}".split(/(?:)/u));