Merge V8 5.2.361.47 DO NOT MERGE
https://chromium.googlesource.com/v8/v8/+/5.2.361.47
FPIIM-449
Change-Id: Ibec421b85a9b88cb3a432ada642e469fe7e78346
(cherry picked from commit bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8)
diff --git a/test/mjsunit/harmony/array-concat-array-proto-getter.js b/test/mjsunit/harmony/array-concat-array-proto-getter.js
new file mode 100644
index 0000000..9368e7f
--- /dev/null
+++ b/test/mjsunit/harmony/array-concat-array-proto-getter.js
@@ -0,0 +1,53 @@
+// 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.
+
+// Check that @@isConcatSpreadable is checked when set on Object.prototype
+
+"use strict"
+
+var array = [1, 2, 3];
+var object = {length: 1, '0': 'a'};
+
+function testConcatDefaults() {
+ assertEquals(array, [].concat(array));
+ assertEquals(array, array.concat([]));
+ assertEquals([1, 2, 3, 1, 2, 3], array.concat(array));
+ assertEquals([object], [].concat(object));
+ assertEquals([1, 2, 3, object], array.concat(object));
+ assertEquals([object], Array.prototype.concat.call(object,[]));
+ assertEquals([object, 1, 2, 3], Array.prototype.concat.call(object, array));
+ assertEquals([object, object], Array.prototype.concat.call(object, object));
+}
+
+testConcatDefaults();
+
+var concatSpreadable = false;
+Object.defineProperty(Array.prototype, Symbol.isConcatSpreadable, {
+ get() { return concatSpreadable },
+ configurable: true
+});
+
+assertEquals([[], array], [].concat(array));
+assertEquals([array, []], array.concat([]));
+assertEquals([array, array], array.concat(array));
+assertEquals([[], object], [].concat(object));
+assertEquals([array, object], array.concat(object));
+assertEquals([object, []], Array.prototype.concat.call(object,[]));
+assertEquals([object, array], Array.prototype.concat.call(object, array));
+assertEquals([object, object], Array.prototype.concat.call(object, object));
+
+concatSpreadable = true;
+
+assertEquals(array, [].concat(array));
+assertEquals(array, array.concat([]));
+assertEquals([1, 2, 3, 1, 2, 3], array.concat(array));
+assertEquals([object], [].concat(object));
+assertEquals([1, 2, 3, object], array.concat(object));
+assertEquals([object], Array.prototype.concat.call(object,[]));
+assertEquals([object, 1, 2, 3], Array.prototype.concat.call(object, array));
+assertEquals([object, object], Array.prototype.concat.call(object, object));
+
+
+delete Array.prototype[Symbol.isConcatSpreadable];
+testConcatDefaults();
diff --git a/test/mjsunit/harmony/array-concat-array-proto.js b/test/mjsunit/harmony/array-concat-array-proto.js
new file mode 100644
index 0000000..520178f
--- /dev/null
+++ b/test/mjsunit/harmony/array-concat-array-proto.js
@@ -0,0 +1,48 @@
+// 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.
+
+// Check that @@isConcatSpreadable is checked when set on Object.prototype
+
+"use strict"
+
+var array = [1, 2, 3];
+var object = {length: 1, '0': 'a'};
+
+function testConcatDefaults() {
+ assertEquals(array, [].concat(array));
+ assertEquals(array, array.concat([]));
+ assertEquals([1, 2, 3, 1, 2, 3], array.concat(array));
+ assertEquals([object], [].concat(object));
+ assertEquals([1, 2, 3, object], array.concat(object));
+ assertEquals([object], Array.prototype.concat.call(object,[]));
+ assertEquals([object, 1, 2, 3], Array.prototype.concat.call(object, array));
+ assertEquals([object, object], Array.prototype.concat.call(object, object));
+}
+
+testConcatDefaults();
+
+Array.prototype[Symbol.isConcatSpreadable] = false;
+
+assertEquals([[], array], [].concat(array));
+assertEquals([array, []], array.concat([]));
+assertEquals([array, array], array.concat(array));
+assertEquals([[], object], [].concat(object));
+assertEquals([array, object], array.concat(object));
+assertEquals([object, []], Array.prototype.concat.call(object,[]));
+assertEquals([object, array], Array.prototype.concat.call(object, array));
+assertEquals([object, object], Array.prototype.concat.call(object, object));
+
+Array.prototype[Symbol.isConcatSpreadable] = true;
+
+assertEquals(array, [].concat(array));
+assertEquals(array, array.concat([]));
+assertEquals([1, 2, 3, 1, 2, 3], array.concat(array));
+assertEquals([object], [].concat(object));
+assertEquals([1, 2, 3, object], array.concat(object));
+assertEquals([object], Array.prototype.concat.call(object,[]));
+assertEquals([object, 1, 2, 3], Array.prototype.concat.call(object, array));
+assertEquals([object, object], Array.prototype.concat.call(object, object));
+
+delete Array.prototype[Symbol.isConcatSpreadable];
+testConcatDefaults();
diff --git a/test/mjsunit/harmony/array-concat-object-proto-dict-getter.js b/test/mjsunit/harmony/array-concat-object-proto-dict-getter.js
new file mode 100644
index 0000000..6e61588
--- /dev/null
+++ b/test/mjsunit/harmony/array-concat-object-proto-dict-getter.js
@@ -0,0 +1,57 @@
+// 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.
+
+// Check that @@isConcatSpreadable is checked when set on Object.prototype
+// with a dictionary backing store.
+
+// Force Object.prototype into dictionary backing store by adding many
+// properties.
+for (var i = 0; i < 10*1000; i++) {
+ Object.prototype['generatedProperty'+i] = true;
+}
+
+var array = [1, 2, 3];
+var object = {length: 1, '0': 'a'};
+
+function testConcatDefaults() {
+ assertEquals(array, [].concat(array));
+ assertEquals(array, array.concat([]));
+ assertEquals([1, 2, 3, 1, 2, 3], array.concat(array));
+ assertEquals([object], [].concat(object));
+ assertEquals([1, 2, 3, object], array.concat(object));
+ assertEquals([object], Array.prototype.concat.call(object,[]));
+ assertEquals([object, 1, 2, 3], Array.prototype.concat.call(object, array));
+ assertEquals([object, object], Array.prototype.concat.call(object, object));
+}
+
+testConcatDefaults();
+
+var concatSpreadable = false;
+Object.defineProperty(Object.prototype, Symbol.isConcatSpreadable, {
+ get() { return concatSpreadable },
+ configurable: true
+});
+
+assertEquals([[], array], [].concat(array));
+assertEquals([array, []], array.concat([]));
+assertEquals([array, array], array.concat(array));
+assertEquals([[], object], [].concat(object));
+assertEquals([array, object], array.concat(object));
+assertEquals([object, []], Array.prototype.concat.call(object,[]));
+assertEquals([object, array], Array.prototype.concat.call(object, array));
+assertEquals([object, object], Array.prototype.concat.call(object, object));
+
+concatSpreadable = true;
+
+assertEquals(array, [].concat(array));
+assertEquals(array, array.concat([]));
+assertEquals([1, 2, 3, 1, 2, 3], array.concat(array));
+assertEquals(['a'], [].concat(object));
+assertEquals([1, 2, 3, 'a'], array.concat(object));
+assertEquals(['a'], Array.prototype.concat.call(object,[]));
+assertEquals(['a', 1, 2, 3], Array.prototype.concat.call(object, array));
+assertEquals(['a', 'a'], Array.prototype.concat.call(object, object));
+
+delete Object.prototype[Symbol.isConcatSpreadable];
+testConcatDefaults();
diff --git a/test/mjsunit/harmony/array-concat-object-proto-dict.js b/test/mjsunit/harmony/array-concat-object-proto-dict.js
new file mode 100644
index 0000000..c817006
--- /dev/null
+++ b/test/mjsunit/harmony/array-concat-object-proto-dict.js
@@ -0,0 +1,53 @@
+// 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.
+
+// Check that @@isConcatSpreadable is checked when set on Object.prototype
+// with a dictionary backing store.
+
+// Force Object.prototype into dictionary backing store by adding many
+// properties.
+for (var i = 0; i < 10*1000; i++) {
+ Object.prototype['generatedProperty'+i] = true;
+}
+
+var array = [1, 2, 3];
+var object = {length: 1, '0': 'a'};
+
+function testConcatDefaults() {
+ assertEquals(array, [].concat(array));
+ assertEquals(array, array.concat([]));
+ assertEquals([1, 2, 3, 1, 2, 3], array.concat(array));
+ assertEquals([object], [].concat(object));
+ assertEquals([1, 2, 3, object], array.concat(object));
+ assertEquals([object], Array.prototype.concat.call(object,[]));
+ assertEquals([object, 1, 2, 3], Array.prototype.concat.call(object, array));
+ assertEquals([object, object], Array.prototype.concat.call(object, object));
+}
+
+testConcatDefaults();
+
+Object.prototype[Symbol.isConcatSpreadable] = false;
+
+assertEquals([[], array], [].concat(array));
+assertEquals([array, []], array.concat([]));
+assertEquals([array, array], array.concat(array));
+assertEquals([[], object], [].concat(object));
+assertEquals([array, object], array.concat(object));
+assertEquals([object, []], Array.prototype.concat.call(object,[]));
+assertEquals([object, array], Array.prototype.concat.call(object, array));
+assertEquals([object, object], Array.prototype.concat.call(object, object));
+
+Object.prototype[Symbol.isConcatSpreadable] = true;
+
+assertEquals(array, [].concat(array));
+assertEquals(array, array.concat([]));
+assertEquals([1, 2, 3, 1, 2, 3], array.concat(array));
+assertEquals(['a'], [].concat(object));
+assertEquals([1, 2, 3, 'a'], array.concat(object));
+assertEquals(['a'], Array.prototype.concat.call(object,[]));
+assertEquals(['a', 1, 2, 3], Array.prototype.concat.call(object, array));
+assertEquals(['a', 'a'], Array.prototype.concat.call(object, object));
+
+delete Object.prototype[Symbol.isConcatSpreadable];
+testConcatDefaults();
diff --git a/test/mjsunit/harmony/array-concat-object-proto-generic-dict.js b/test/mjsunit/harmony/array-concat-object-proto-generic-dict.js
new file mode 100644
index 0000000..7b61422
--- /dev/null
+++ b/test/mjsunit/harmony/array-concat-object-proto-generic-dict.js
@@ -0,0 +1,65 @@
+// 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.
+
+// Check that @@isConcatSpreadable is checked when set on Object.prototype
+// with a dictionary backing store.
+
+// Force Object.prototype into dictionary backing store by adding many
+// properties.
+for (var i = 0; i < 10*1000; i++) {
+ Object.prototype['generatedProperty'+i] = true;
+}
+
+var array = [1, 2, 3];
+var object = {length: 1, '0': 'a'};
+
+function SetProperty(receiver, key, value) {
+ receiver[key] = value;
+}
+
+// Force the Keyed Store IC in SetProperty to be generic.
+var receiver = {};
+for (var i = 0; i < 100; i++) {
+ SetProperty(receiver, 'prop'+i, 'value');
+}
+
+function testConcatDefaults() {
+ assertEquals(array, [].concat(array));
+ assertEquals(array, array.concat([]));
+ assertEquals([1, 2, 3, 1, 2, 3], array.concat(array));
+ assertEquals([object], [].concat(object));
+ assertEquals([1, 2, 3, object], array.concat(object));
+ assertEquals([object], Array.prototype.concat.call(object,[]));
+ assertEquals([object, 1, 2, 3], Array.prototype.concat.call(object, array));
+ assertEquals([object, object], Array.prototype.concat.call(object, object));
+}
+
+testConcatDefaults();
+
+// Use a generic IC to set @@isConcatSpreadable
+SetProperty(Object.prototype, Symbol.isConcatSpreadable, false);
+
+assertEquals([[], array], [].concat(array));
+assertEquals([array, []], array.concat([]));
+assertEquals([array, array], array.concat(array));
+assertEquals([[], object], [].concat(object));
+assertEquals([array, object], array.concat(object));
+assertEquals([object, []], Array.prototype.concat.call(object,[]));
+assertEquals([object, array], Array.prototype.concat.call(object, array));
+assertEquals([object, object], Array.prototype.concat.call(object, object));
+
+// Use a generic IC to set @@isConcatSpreadable
+SetProperty(Object.prototype, Symbol.isConcatSpreadable, true);
+
+assertEquals(array, [].concat(array));
+assertEquals(array, array.concat([]));
+assertEquals([1, 2, 3, 1, 2, 3], array.concat(array));
+assertEquals(['a'], [].concat(object));
+assertEquals([1, 2, 3, 'a'], array.concat(object));
+assertEquals(['a'], Array.prototype.concat.call(object,[]));
+assertEquals(['a', 1, 2, 3], Array.prototype.concat.call(object, array));
+assertEquals(['a', 'a'], Array.prototype.concat.call(object, object));
+
+delete Object.prototype[Symbol.isConcatSpreadable];
+testConcatDefaults();
diff --git a/test/mjsunit/harmony/array-concat-object-proto.js b/test/mjsunit/harmony/array-concat-object-proto.js
new file mode 100644
index 0000000..307326c
--- /dev/null
+++ b/test/mjsunit/harmony/array-concat-object-proto.js
@@ -0,0 +1,48 @@
+// 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.
+
+// Check that @@isConcatSpreadable is checked when set on Object.prototype
+
+"use strict"
+
+var array = [1, 2, 3];
+var object = {length: 1, '0': 'a'};
+
+function testConcatDefaults() {
+ assertEquals(array, [].concat(array));
+ assertEquals(array, array.concat([]));
+ assertEquals([1, 2, 3, 1, 2, 3], array.concat(array));
+ assertEquals([object], [].concat(object));
+ assertEquals([1, 2, 3, object], array.concat(object));
+ assertEquals([object], Array.prototype.concat.call(object,[]));
+ assertEquals([object, 1, 2, 3], Array.prototype.concat.call(object, array));
+ assertEquals([object, object], Array.prototype.concat.call(object, object));
+}
+
+testConcatDefaults();
+
+Object.prototype[Symbol.isConcatSpreadable] = false;
+
+assertEquals([[], array], [].concat(array));
+assertEquals([array, []], array.concat([]));
+assertEquals([array, array], array.concat(array));
+assertEquals([[], object], [].concat(object));
+assertEquals([array, object], array.concat(object));
+assertEquals([object, []], Array.prototype.concat.call(object,[]));
+assertEquals([object, array], Array.prototype.concat.call(object, array));
+assertEquals([object, object], Array.prototype.concat.call(object, object));
+
+Object.prototype[Symbol.isConcatSpreadable] = true;
+
+assertEquals(array, [].concat(array));
+assertEquals(array, array.concat([]));
+assertEquals([1, 2, 3, 1, 2, 3], array.concat(array));
+assertEquals(['a'], [].concat(object));
+assertEquals([1, 2, 3, 'a'], array.concat(object));
+assertEquals(['a'], Array.prototype.concat.call(object,[]));
+assertEquals(['a', 1, 2, 3], Array.prototype.concat.call(object, array));
+assertEquals(['a', 'a'], Array.prototype.concat.call(object, object));
+
+delete Object.prototype[Symbol.isConcatSpreadable];
+testConcatDefaults();
diff --git a/test/mjsunit/harmony/async-arrow-lexical-arguments.js b/test/mjsunit/harmony/async-arrow-lexical-arguments.js
new file mode 100644
index 0000000..44d38a4
--- /dev/null
+++ b/test/mjsunit/harmony/async-arrow-lexical-arguments.js
@@ -0,0 +1,42 @@
+// 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
+
+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 " + PrettyPrint(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);
+};
+
+assertEqualsAsync("[1,2,3]", () => (function() {
+ return (async () => JSON.stringify([...arguments]))();
+})(1, 2, 3));
+
+assertEqualsAsync("[4,5,6]",
+ () => (function() {
+ return (async () => {
+ return JSON.stringify([...await arguments]) })();
+ })(4, 5, 6));
diff --git a/test/mjsunit/harmony/async-arrow-lexical-new.target.js b/test/mjsunit/harmony/async-arrow-lexical-new.target.js
new file mode 100644
index 0000000..72b29e6
--- /dev/null
+++ b/test/mjsunit/harmony/async-arrow-lexical-new.target.js
@@ -0,0 +1,43 @@
+// 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
+
+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 " + PrettyPrint(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);
+};
+
+class BaseClass {
+ constructor() {
+ return async () => new.target;
+ }
+}
+
+class ChildClass extends BaseClass {}
+
+assertEqualsAsync(BaseClass, () => new BaseClass()());
+assertEqualsAsync(ChildClass, () => new ChildClass()());
diff --git a/test/mjsunit/harmony/async-arrow-lexical-super.js b/test/mjsunit/harmony/async-arrow-lexical-super.js
new file mode 100644
index 0000000..78f5d55
--- /dev/null
+++ b/test/mjsunit/harmony/async-arrow-lexical-super.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: --harmony-async-await --allow-natives-syntax
+
+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 " + PrettyPrint(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);
+};
+
+class BaseClass {
+ constructor(x) {
+ this.name_ = x;
+ }
+ get name() { return this.name_; }
+};
+
+class DeferredSuperCall extends BaseClass {
+ constructor(x) {
+ return async() => super(x);
+ }
+};
+
+assertEqualsAsync(
+ "LexicalSuperCall",
+ () => new DeferredSuperCall("LexicalSuperCall")().then(x => x.name));
+
+
+class DeferredSuperProperty extends BaseClass {
+ deferredName() { return async() => super.name; }
+};
+
+assertEqualsAsync(
+ "LexicalSuperProperty",
+ () => new DeferredSuperProperty("LexicalSuperProperty").deferredName()());
diff --git a/test/mjsunit/harmony/async-arrow-lexical-this.js b/test/mjsunit/harmony/async-arrow-lexical-this.js
new file mode 100644
index 0000000..182db47
--- /dev/null
+++ b/test/mjsunit/harmony/async-arrow-lexical-this.js
@@ -0,0 +1,48 @@
+// 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
+
+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 " + PrettyPrint(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 O = {
+ [Symbol.toStringTag]: "LexicalThis",
+ run(n) {
+ return async passFail => `${n}. ${passFail}: ${this}`;
+ },
+};
+
+assertEqualsAsync("1. PASS: [object LexicalThis]", () => O.run(1)("PASS"));
+
+var O2 = {
+ [Symbol.toStringTag]: "LexicalThis",
+ run: O.run(2)
+};
+
+assertEqualsAsync("2. PASS: [object LexicalThis]", () => O2.run("PASS"));
diff --git a/test/mjsunit/harmony/async-await-basic.js b/test/mjsunit/harmony/async-await-basic.js
new file mode 100644
index 0000000..d0888ea
--- /dev/null
+++ b/test/mjsunit/harmony/async-await-basic.js
@@ -0,0 +1,347 @@
+// 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
+
+// Do not install `AsyncFunction` constructor on global object
+
+function assertThrowsAsync(run, errorType, message) {
+ 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 " + PrettyPrint(promise));
+ }
+
+ promise.then(function(value) { hadValue = true; actual = value; },
+ function(error) { hadError = true; actual = error; });
+
+ assertFalse(hadValue || hadError);
+
+ %RunMicrotasks();
+
+ if (!hadError) {
+ throw new MjsUnitAssertionError(
+ "Expected " + run + "() to throw " + errorType.name +
+ ", but did not throw.");
+ }
+ if (!(actual instanceof errorType))
+ throw new MjsUnitAssertionError(
+ "Expected " + run + "() to throw " + errorType.name +
+ ", but threw '" + actual + "'");
+ if (message !== void 0 && actual.message !== message)
+ throw new MjsUnitAssertionError(
+ "Expected " + run + "() to throw '" + message + "', but threw '" +
+ actual.message + "'");
+};
+
+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 " + PrettyPrint(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);
+};
+
+assertEquals(undefined, this.AsyncFunction);
+let AsyncFunction = (async function() {}).constructor;
+
+// Let functionPrototype be the intrinsic object %AsyncFunctionPrototype%.
+async function asyncFunctionForProto() {}
+assertEquals(AsyncFunction.prototype,
+ Object.getPrototypeOf(asyncFunctionForProto));
+assertEquals(AsyncFunction.prototype,
+ Object.getPrototypeOf(async function() {}));
+assertEquals(AsyncFunction.prototype, Object.getPrototypeOf(async () => {}));
+assertEquals(AsyncFunction.prototype,
+ Object.getPrototypeOf({ async method() {} }.method));
+assertEquals(AsyncFunction.prototype, Object.getPrototypeOf(AsyncFunction()));
+assertEquals(AsyncFunction.prototype,
+ Object.getPrototypeOf(new AsyncFunction()));
+
+// AsyncFunctionCreate does not produce an object with a Prototype
+assertEquals(undefined, asyncFunctionForProto.prototype);
+assertEquals(false, asyncFunctionForProto.hasOwnProperty("prototype"));
+assertEquals(undefined, (async function() {}).prototype);
+assertEquals(false, (async function() {}).hasOwnProperty("prototype"));
+assertEquals(undefined, (async() => {}).prototype);
+assertEquals(false, (async() => {}).hasOwnProperty("prototype"));
+assertEquals(undefined, ({ async method() {} }).method.prototype);
+assertEquals(false, ({ async method() {} }).method.hasOwnProperty("prototype"));
+assertEquals(undefined, AsyncFunction().prototype);
+assertEquals(false, AsyncFunction().hasOwnProperty("prototype"));
+assertEquals(undefined, (new AsyncFunction()).prototype);
+assertEquals(false, (new AsyncFunction()).hasOwnProperty("prototype"));
+
+assertEquals(1, async function(a) { await 1; }.length);
+assertEquals(2, async function(a, b) { await 1; }.length);
+assertEquals(1, async function(a, b = 2) { await 1; }.length);
+assertEquals(2, async function(a, b, ...c) { await 1; }.length);
+
+assertEquals(1, (async(a) => await 1).length);
+assertEquals(2, (async(a, b) => await 1).length);
+assertEquals(1, (async(a, b = 2) => await 1).length);
+assertEquals(2, (async(a, b, ...c) => await 1).length);
+
+assertEquals(1, ({ async f(a) { await 1; } }).f.length);
+assertEquals(2, ({ async f(a, b) { await 1; } }).f.length);
+assertEquals(1, ({ async f(a, b = 2) { await 1; } }).f.length);
+assertEquals(2, ({ async f(a, b, ...c) { await 1; } }).f.length);
+
+assertEquals(1, AsyncFunction("a", "await 1").length);
+assertEquals(2, AsyncFunction("a", "b", "await 1").length);
+assertEquals(1, AsyncFunction("a", "b = 2", "await 1").length);
+assertEquals(2, AsyncFunction("a", "b", "...c", "await 1").length);
+
+assertEquals(1, (new AsyncFunction("a", "await 1")).length);
+assertEquals(2, (new AsyncFunction("a", "b", "await 1")).length);
+assertEquals(1, (new AsyncFunction("a", "b = 2", "await 1")).length);
+assertEquals(2, (new AsyncFunction("a", "b", "...c", "await 1")).length);
+
+// AsyncFunction.prototype[ @@toStringTag ]
+var descriptor =
+ Object.getOwnPropertyDescriptor(AsyncFunction.prototype,
+ Symbol.toStringTag);
+assertEquals("AsyncFunction", descriptor.value);
+assertEquals(false, descriptor.enumerable);
+assertEquals(false, descriptor.writable);
+assertEquals(true, descriptor.configurable);
+
+assertEquals(1, AsyncFunction.length);
+
+// Let F be ! FunctionAllocate(functionPrototype, Strict, "non-constructor")
+async function asyncNonConstructorDecl() {}
+assertThrows(
+ () => new asyncNonConstructorDecl(), TypeError);
+assertThrows(
+ () => new (async function() {}), TypeError);
+assertThrows(
+ () => new ({ async nonConstructor() {} }).nonConstructor(), TypeError);
+assertThrows(
+ () => new (() => "not a constructor!"), TypeError);
+assertThrows(
+ () => new (AsyncFunction()), TypeError);
+assertThrows(
+ () => new (new AsyncFunction()), TypeError);
+
+// Normal completion
+async function asyncDecl() { return "test"; }
+assertEqualsAsync("test", asyncDecl);
+assertEqualsAsync("test2", async function() { return "test2"; });
+assertEqualsAsync("test3", async () => "test3");
+assertEqualsAsync("test4", () => ({ async f() { return "test4"; } }).f());
+assertEqualsAsync("test5", () => AsyncFunction("no", "return 'test' + no;")(5));
+assertEqualsAsync("test6",
+ () => (new AsyncFunction("no", "return 'test' + no;"))(6));
+
+class MyError extends Error {};
+
+// Throw completion
+async function asyncDeclThrower(e) { throw new MyError(e); }
+assertThrowsAsync(() => asyncDeclThrower("boom!"), MyError, "boom!");
+assertThrowsAsync(
+ () => (async function(e) { throw new MyError(e); })("boom!!!"),
+ MyError, "boom!!!");
+assertThrowsAsync(
+ () => (async e => { throw new MyError(e) })("boom!!"), MyError, "boom!!");
+assertThrowsAsync(
+ () => ({ async thrower(e) { throw new MyError(e); } }).thrower("boom!1!"),
+ MyError, "boom!1!");
+assertThrowsAsync(
+ () => AsyncFunction("msg", "throw new MyError(msg)")("boom!2!!"),
+ MyError, "boom!2!!");
+assertThrowsAsync(
+ () => (new AsyncFunction("msg", "throw new MyError(msg)"))("boom!2!!!"),
+ MyError, "boom!2!!!");
+
+function resolveLater(value) { return Promise.resolve(value); }
+function rejectLater(error) { return Promise.reject(error); }
+
+// Resume after Normal completion
+var log = [];
+async function resumeAfterNormal(value) {
+ log.push("start:" + value);
+ value = await resolveLater(value + 1);
+ log.push("resume:" + value);
+ value = await resolveLater(value + 1);
+ log.push("resume:" + value);
+ return value + 1;
+}
+
+assertEqualsAsync(4, () => resumeAfterNormal(1));
+assertEquals("start:1 resume:2 resume:3", log.join(" "));
+
+var O = {
+ async resumeAfterNormal(value) {
+ log.push("start:" + value);
+ value = await resolveLater(value + 1);
+ log.push("resume:" + value);
+ value = await resolveLater(value + 1);
+ log.push("resume:" + value);
+ return value + 1;
+ }
+};
+log = [];
+assertEqualsAsync(5, () => O.resumeAfterNormal(2));
+assertEquals("start:2 resume:3 resume:4", log.join(" "));
+
+var resumeAfterNormalArrow = async (value) => {
+ log.push("start:" + value);
+ value = await resolveLater(value + 1);
+ log.push("resume:" + value);
+ value = await resolveLater(value + 1);
+ log.push("resume:" + value);
+ return value + 1;
+};
+log = [];
+assertEqualsAsync(6, () => resumeAfterNormalArrow(3));
+assertEquals("start:3 resume:4 resume:5", log.join(" "));
+
+var resumeAfterNormalEval = AsyncFunction("value", `
+ log.push("start:" + value);
+ value = await resolveLater(value + 1);
+ log.push("resume:" + value);
+ value = await resolveLater(value + 1);
+ log.push("resume:" + value);
+ return value + 1;`);
+log = [];
+assertEqualsAsync(7, () => resumeAfterNormalEval(4));
+assertEquals("start:4 resume:5 resume:6", log.join(" "));
+
+var resumeAfterNormalNewEval = new AsyncFunction("value", `
+ log.push("start:" + value);
+ value = await resolveLater(value + 1);
+ log.push("resume:" + value);
+ value = await resolveLater(value + 1);
+ log.push("resume:" + value);
+ return value + 1;`);
+log = [];
+assertEqualsAsync(8, () => resumeAfterNormalNewEval(5));
+assertEquals("start:5 resume:6 resume:7", log.join(" "));
+
+// Resume after Throw completion
+async function resumeAfterThrow(value) {
+ log.push("start:" + value);
+ try {
+ value = await rejectLater("throw1");
+ } catch (e) {
+ log.push("resume:" + e);
+ }
+ try {
+ value = await rejectLater("throw2");
+ } catch (e) {
+ log.push("resume:" + e);
+ }
+ return value + 1;
+}
+
+log = [];
+assertEqualsAsync(2, () => resumeAfterThrow(1));
+assertEquals("start:1 resume:throw1 resume:throw2", log.join(" "));
+
+var O = {
+ async resumeAfterThrow(value) {
+ log.push("start:" + value);
+ try {
+ value = await rejectLater("throw1");
+ } catch (e) {
+ log.push("resume:" + e);
+ }
+ try {
+ value = await rejectLater("throw2");
+ } catch (e) {
+ log.push("resume:" + e);
+ }
+ return value + 1;
+ }
+}
+log = [];
+assertEqualsAsync(3, () => O.resumeAfterThrow(2));
+assertEquals("start:2 resume:throw1 resume:throw2", log.join(" "));
+
+var resumeAfterThrowArrow = async (value) => {
+ log.push("start:" + value);
+ try {
+ value = await rejectLater("throw1");
+ } catch (e) {
+ log.push("resume:" + e);
+ }
+ try {
+ value = await rejectLater("throw2");
+ } catch (e) {
+ log.push("resume:" + e);
+ }
+ return value + 1;
+};
+
+log = [];
+
+assertEqualsAsync(4, () => resumeAfterThrowArrow(3));
+assertEquals("start:3 resume:throw1 resume:throw2", log.join(" "));
+
+var resumeAfterThrowEval = AsyncFunction("value", `
+ log.push("start:" + value);
+ try {
+ value = await rejectLater("throw1");
+ } catch (e) {
+ log.push("resume:" + e);
+ }
+ try {
+ value = await rejectLater("throw2");
+ } catch (e) {
+ log.push("resume:" + e);
+ }
+ return value + 1;`);
+log = [];
+assertEqualsAsync(5, () => resumeAfterThrowEval(4));
+assertEquals("start:4 resume:throw1 resume:throw2", log.join(" "));
+
+var resumeAfterThrowNewEval = new AsyncFunction("value", `
+ log.push("start:" + value);
+ try {
+ value = await rejectLater("throw1");
+ } catch (e) {
+ log.push("resume:" + e);
+ }
+ try {
+ value = await rejectLater("throw2");
+ } catch (e) {
+ log.push("resume:" + e);
+ }
+ return value + 1;`);
+log = [];
+assertEqualsAsync(6, () => resumeAfterThrowNewEval(5));
+assertEquals("start:5 resume:throw1 resume:throw2", log.join(" "));
+
+async function foo() {}
+assertEquals("async function foo() {}", foo.toString());
+assertEquals("async function () {}", async function() {}.toString());
+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));
diff --git a/test/mjsunit/harmony/atomics.js b/test/mjsunit/harmony/atomics.js
index bf27eb4..e608df3 100644
--- a/test/mjsunit/harmony/atomics.js
+++ b/test/mjsunit/harmony/atomics.js
@@ -16,26 +16,19 @@
return value;
}
-function toRangeClamped(value) {
- if (value < this.min) return this.min;
- if (value > this.max) return this.max;
- return value;
-}
-
function makeConstructorObject(constr, min, max, toRange) {
var o = {constr: constr, min: min, max: max};
- o.toRange = toRange.bind(o);
+ o.toRange = toRangeWrapped.bind(o);
return o;
}
var IntegerTypedArrayConstructors = [
- makeConstructorObject(Int8Array, -128, 127, toRangeWrapped),
- makeConstructorObject(Int16Array, -32768, 32767, toRangeWrapped),
- makeConstructorObject(Int32Array, -0x80000000, 0x7fffffff, toRangeWrapped),
- makeConstructorObject(Uint8Array, 0, 255, toRangeWrapped),
- makeConstructorObject(Uint8ClampedArray, 0, 255, toRangeClamped),
- makeConstructorObject(Uint16Array, 0, 65535, toRangeWrapped),
- makeConstructorObject(Uint32Array, 0, 0xffffffff, toRangeWrapped),
+ makeConstructorObject(Int8Array, -128, 127),
+ makeConstructorObject(Int16Array, -32768, 32767),
+ makeConstructorObject(Int32Array, -0x80000000, 0x7fffffff),
+ makeConstructorObject(Uint8Array, 0, 255),
+ makeConstructorObject(Uint16Array, 0, 65535),
+ makeConstructorObject(Uint32Array, 0, 0xffffffff),
];
(function TestBadArray() {
@@ -44,9 +37,13 @@
var sab = new SharedArrayBuffer(128);
var sf32a = new Float32Array(sab);
var sf64a = new Float64Array(sab);
+ var u8ca = new Uint8ClampedArray(sab);
// Atomic ops required integer shared typed arrays
- [undefined, 1, 'hi', 3.4, ab, u32a, sab, sf32a, sf64a].forEach(function(o) {
+ var badArrayTypes = [
+ undefined, 1, 'hi', 3.4, ab, u32a, sab, sf32a, sf64a, u8ca
+ ];
+ badArrayTypes.forEach(function(o) {
assertThrows(function() { Atomics.compareExchange(o, 0, 0, 0); },
TypeError);
assertThrows(function() { Atomics.load(o, 0); }, TypeError);
@@ -129,15 +126,16 @@
var testOp = function(op, ia, index, expectedIndex, name) {
for (var i = 0; i < ia.length; ++i)
- ia[i] = 22;
+ ia[i] = i * 2;
ia[expectedIndex] = 0;
- assertEquals(0, op(ia, index, 0, 0), name);
+ var result = op(ia, index, 0, 0);
+ assertEquals(0, result, name);
assertEquals(0, ia[expectedIndex], name);
for (var i = 0; i < ia.length; ++i) {
if (i == expectedIndex) continue;
- assertEquals(22, ia[i], name);
+ assertEquals(i * 2, ia[i], name);
}
};
@@ -222,6 +220,24 @@
}
})
});
+
+ // Test Smi range
+ (function () {
+ var sab = new SharedArrayBuffer(4);
+ var i32 = new Int32Array(sab);
+ var u32 = new Uint32Array(sab);
+
+ function testLoad(signedValue, unsignedValue) {
+ u32[0] = unsignedValue;
+ assertEquals(unsignedValue, Atomics.load(u32, 0));
+ assertEquals(signedValue, Atomics.load(i32, 0));
+ }
+
+ testLoad(0x3fffffff, 0x3fffffff); // 2**30-1 (always smi)
+ testLoad(0x40000000, 0x40000000); // 2**30 (smi if signed and 32-bits)
+ testLoad(0x80000000, -0x80000000); // 2**31 (smi if signed and 32-bits)
+ testLoad(0xffffffff, -1); // 2**31 (smi if signed)
+ });
})();
(function TestStore() {
@@ -405,7 +421,7 @@
assertEquals(50, Atomics.compareExchange(sta, 0, v, v), name);
// Store
- assertEquals(+v, Atomics.store(sta, 0, v), name);
+ assertEquals(v|0, Atomics.store(sta, 0, v), name);
assertEquals(v|0, sta[0], name);
// Add
diff --git a/test/mjsunit/harmony/block-conflicts-sloppy.js b/test/mjsunit/harmony/block-conflicts-sloppy.js
deleted file mode 100644
index 8908ce4..0000000
--- a/test/mjsunit/harmony/block-conflicts-sloppy.js
+++ /dev/null
@@ -1,179 +0,0 @@
-// Copyright 2011 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.
-
-// Test for conflicting variable bindings.
-
-// Flags: --harmony-sloppy --harmony-sloppy-let --harmony-sloppy-function
-
-function CheckException(e) {
- var string = e.toString();
- assertTrue(string.indexOf("has already been declared") >= 0 ||
- string.indexOf("redeclaration") >= 0);
- return 'Conflict';
-}
-
-
-function TestGlobal(s,e) {
- try {
- return eval(s + e);
- } catch (x) {
- return CheckException(x);
- }
-}
-
-
-function TestFunction(s,e) {
- try {
- return eval("(function(){" + s + " return " + e + "})")();
- } catch (x) {
- return CheckException(x);
- }
-}
-
-
-function TestBlock(s,e) {
- try {
- return eval("(function(){ {" + s + "} return " + e + "})")();
- } catch (x) {
- return CheckException(x);
- }
-}
-
-function TestAll(expected,s,opt_e) {
- var e = "";
- var msg = s;
- if (opt_e) { e = opt_e; msg += opt_e; }
- // TODO(littledan): Add tests using Realm.eval to ensure that global eval
- // works as expected.
- assertEquals(expected === 'LocalConflict' ? 'NoConflict' : expected,
- TestGlobal(s,e), "global:'" + msg + "'");
- assertEquals(expected === 'LocalConflict' ? 'NoConflict' : expected,
- TestFunction(s,e), "function:'" + msg + "'");
- assertEquals(expected === 'LocalConflict' ? 'Conflict' : expected,
- TestBlock(s,e), "block:'" + msg + "'");
-}
-
-
-function TestConflict(s) {
- TestAll('Conflict', s);
- TestAll('Conflict', 'eval("' + s + '");');
-}
-
-function TestNoConflict(s) {
- TestAll('NoConflict', s, "'NoConflict'");
- TestAll('NoConflict', 'eval("' + s + '");', "'NoConflict'");
-}
-
-function TestLocalConflict(s) {
- TestAll('LocalConflict', s, "'NoConflict'");
- TestAll('NoConflict', 'eval("' + s + '");', "'NoConflict'");
-}
-
-var letbinds = [ "let x;",
- "let x = 0;",
- "let x = undefined;",
- "let x = function() {};",
- "let x, y;",
- "let y, x;",
- "const x = 0;",
- "const x = undefined;",
- "const x = function() {};",
- "const x = 2, y = 3;",
- "const y = 4, x = 5;",
- "class x { }",
- ];
-function forCompatible(bind) {
- return !bind.startsWith('class');
-}
-var varbinds = [ "var x;",
- "var x = 0;",
- "var x = undefined;",
- "var x = function() {};",
- "var x, y;",
- "var y, x;",
- ];
-var funbind = "function x() {}";
-
-for (var l = 0; l < letbinds.length; ++l) {
- // Test conflicting let/var bindings.
- for (var v = 0; v < varbinds.length; ++v) {
- // Same level.
- TestConflict(letbinds[l] + varbinds[v]);
- TestConflict(varbinds[v] + letbinds[l]);
- // Different level.
- TestConflict(letbinds[l] + '{' + varbinds[v] + '}');
- TestConflict('{' + varbinds[v] +'}' + letbinds[l]);
- TestNoConflict(varbinds[v] + '{' + letbinds[l] + '}');
- TestNoConflict('{' + letbinds[l] + '}' + varbinds[v]);
- // For loop.
- if (forCompatible(letbinds[l])) {
- TestConflict('for (' + letbinds[l] + '0;) {' + varbinds[v] + '}');
- }
- TestNoConflict('for (' + varbinds[v] + '0;) {' + letbinds[l] + '}');
- }
-
- // Test conflicting let/let bindings.
- for (var k = 0; k < letbinds.length; ++k) {
- // Same level.
- TestConflict(letbinds[l] + letbinds[k]);
- TestConflict(letbinds[k] + letbinds[l]);
- // Different level.
- TestNoConflict(letbinds[l] + '{ ' + letbinds[k] + '}');
- TestNoConflict('{' + letbinds[k] +'} ' + letbinds[l]);
- // For loop.
- if (forCompatible(letbinds[l])) {
- TestNoConflict('for (' + letbinds[l] + '0;) {' + letbinds[k] + '}');
- }
- if (forCompatible(letbinds[k])) {
- TestNoConflict('for (' + letbinds[k] + '0;) {' + letbinds[l] + '}');
- }
- }
-
- // Test conflicting function/let bindings.
- // Same level.
- TestConflict(letbinds[l] + funbind);
- TestConflict(funbind + letbinds[l]);
- // Different level.
- TestNoConflict(letbinds[l] + '{' + funbind + '}');
- TestNoConflict('{' + funbind + '}' + letbinds[l]);
- TestNoConflict(funbind + '{' + letbinds[l] + '}');
- TestNoConflict('{' + letbinds[l] + '}' + funbind);
- // For loop.
- if (forCompatible(letbinds[l])) {
- TestNoConflict('for (' + letbinds[l] + '0;) {' + funbind + '}');
- }
-
- // Test conflicting parameter/let bindings.
- TestConflict('(function(x) {' + letbinds[l] + '})();');
-}
-
-// Test conflicting function/var bindings.
-for (var v = 0; v < varbinds.length; ++v) {
- // Same level.
- TestLocalConflict(varbinds[v] + funbind);
- TestLocalConflict(funbind + varbinds[v]);
- // Different level.
- TestLocalConflict(funbind + '{' + varbinds[v] + '}');
- TestLocalConflict('{' + varbinds[v] +'}' + funbind);
- TestNoConflict(varbinds[v] + '{' + funbind + '}');
- TestNoConflict('{' + funbind + '}' + varbinds[v]);
- // For loop.
- TestNoConflict('for (' + varbinds[v] + '0;) {' + funbind + '}');
-}
-
-// Test conflicting catch/var bindings.
-for (var v = 0; v < varbinds.length; ++v) {
- TestNoConflict('try {} catch(x) {' + varbinds[v] + '}');
-}
-
-// Test conflicting parameter/var bindings.
-for (var v = 0; v < varbinds.length; ++v) {
- TestNoConflict('(function (x) {' + varbinds[v] + '})();');
-}
-
-// Test conflicting catch/function bindings.
-TestNoConflict('try {} catch(x) {' + funbind + '}');
-
-// Test conflicting parameter/function bindings.
-TestNoConflict('(function (x) {' + funbind + '})();');
diff --git a/test/mjsunit/harmony/block-const-assign-sloppy.js b/test/mjsunit/harmony/block-const-assign-sloppy.js
deleted file mode 100644
index 5dde82c..0000000
--- a/test/mjsunit/harmony/block-const-assign-sloppy.js
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Flags: --harmony-sloppy --harmony-sloppy-let
-
-// Test that we throw early syntax errors in harmony mode
-// when using an immutable binding in an assigment or with
-// prefix/postfix decrement/increment operators.
-
-const decls = [
- // Const declaration.
- function(use) { return "const c = 1; " + use + ";" }, TypeError,
- function(use) { return "const x = 0, c = 1; " + use + ";" }, TypeError,
- function(use) { return "const c = 1, x = (" + use + ");" }, TypeError,
- function(use) { return use + "; const c = 1;" }, ReferenceError,
- function(use) { return use + "; const x = 0, c = 1;" }, ReferenceError,
- function(use) { return "const x = (" + use + "), c = 1;" }, ReferenceError,
- function(use) { return "const c = (" + use + ");" }, ReferenceError,
-
- // Function expression.
- function(use) { return "(function c() { " + use + "; })();"; }, TypeError,
- // TODO(rossberg): Once we have default parameters, test using 'c' there.
-
- // Class expression.
- function(use) {
- return "new class c { constructor() { " + use + " } };";
- }, TypeError,
- function(use) {
- return "(new class c { m() { " + use + " } }).m();";
- }, TypeError,
- function(use) {
- return "(new class c { get a() { " + use + " } }).a;";
- }, TypeError,
- function(use) {
- return "(new class c { set a(x) { " + use + " } }).a = 0;";
- }, TypeError,
- function(use) {
- return "(class c { static m() { " + use + " } }).s();";
- }, TypeError,
- function(use) {
- return "(class c extends (" + use + ") {});";
- }, ReferenceError,
- function(use) {
- return "(class c { [" + use + "]() {} });";
- }, ReferenceError,
- function(use) {
- return "(class c { get [" + use + "]() {} });";
- }, ReferenceError,
- function(use) {
- return "(class c { set [" + use + "](x) {} });";
- }, ReferenceError,
- function(use) {
- return "(class c { static [" + use + "]() {} });";
- }, ReferenceError,
-
- // For loop.
- function(use) {
- return "for (const c = 0; " + use + ";) {}"
- }, TypeError,
- function(use) {
- return "for (const x = 0, c = 0; " + use + ";) {}"
- }, TypeError,
- function(use) {
- return "for (const c = 0; ; " + use + ") {}"
- }, TypeError,
- function(use) {
- return "for (const x = 0, c = 0; ; " + use + ") {}"
- }, TypeError,
- function(use) {
- return "for (const c = 0; ;) { " + use + "; }"
- }, TypeError,
- function(use) {
- return "for (const x = 0, c = 0; ;) { " + use + "; }"
- }, TypeError,
- function(use) {
- return "for (const c in {a: 1}) { " + use + "; }"
- }, TypeError,
- function(use) {
- return "for (const c of [1]) { " + use + "; }"
- }, TypeError,
- function(use) {
- return "for (const x = (" + use + "), c = 0; ;) {}"
- }, ReferenceError,
- function(use) {
- return "for (const c = (" + use + "); ;) {}"
- }, ReferenceError,
-]
-
-let uses = [
- 'c = 1',
- 'c += 1',
- '++c',
- 'c--',
-];
-
-let declcontexts = [
- function(decl) { return decl; },
- function(decl) { return "eval(\'" + decl + "\')"; },
- function(decl) { return "{ " + decl + " }"; },
- function(decl) { return "(function() { " + decl + " })()"; },
-];
-
-let usecontexts = [
- function(use) { return use; },
- function(use) { return "eval(\"" + use + "\")"; },
- function(use) { return "(function() { " + use + " })()"; },
- function(use) { return "(function() { eval(\"" + use + "\"); })()"; },
- function(use) { return "eval(\"(function() { " + use + "; })\")()"; },
-];
-
-function Test(program, error) {
- program = "'use strict'; " + program;
- try {
- print(program, " // throw " + error.name);
- eval(program);
- } catch (e) {
- assertInstanceof(e, error);
- if (e === TypeError) {
- assertTrue(e.toString().indexOf("Assignment to constant variable") >= 0);
- }
- return;
- }
- assertUnreachable();
-}
-
-for (var d = 0; d < decls.length; d += 2) {
- for (var u = 0; u < uses.length; ++u) {
- for (var o = 0; o < declcontexts.length; ++o) {
- for (var i = 0; i < usecontexts.length; ++i) {
- Test(declcontexts[o](decls[d](usecontexts[i](uses[u]))), decls[d + 1]);
- }
- }
- }
-}
diff --git a/test/mjsunit/harmony/block-eval-var-over-let.js b/test/mjsunit/harmony/block-eval-var-over-let.js
deleted file mode 100644
index 98091b4..0000000
--- a/test/mjsunit/harmony/block-eval-var-over-let.js
+++ /dev/null
@@ -1,143 +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-sloppy --harmony-sloppy-let --harmony-sloppy-function
-
-// Var-let conflict in a function throws, even if the var is in an eval
-
-// Throws at the top level of a function
-assertThrows(function() {
- let x = 1;
- eval('var x');
-}, TypeError);
-
-// If the eval is in its own block scope, throws
-assertThrows(function() {
- let y = 1;
- { eval('var y'); }
-}, TypeError);
-
-// If the let is in its own block scope, with the eval, throws
-assertThrows(function() {
- {
- let x = 1;
- eval('var x');
- }
-}, TypeError);
-
-// Legal if the let is no longer visible
-assertDoesNotThrow(function() {
- {
- let x = 1;
- }
- eval('var x');
-});
-
-// All the same works for const:
-// Throws at the top level of a function
-assertThrows(function() {
- const x = 1;
- eval('var x');
-}, TypeError);
-
-// If the eval is in its own block scope, throws
-assertThrows(function() {
- const y = 1;
- { eval('var y'); }
-}, TypeError);
-
-// If the const is in its own block scope, with the eval, throws
-assertThrows(function() {
- {
- const x = 1;
- eval('var x');
- }
-}, TypeError);
-
-// Legal if the const is no longer visible
-assertDoesNotThrow(function() {
- {
- const x = 1;
- }
- eval('var x');
-});
-
-// In global scope
-let caught = false;
-try {
- let z = 1;
- eval('var z');
-} catch (e) {
- caught = true;
-}
-assertTrue(caught);
-
-// Let declarations beyond a function boundary don't conflict
-caught = false;
-try {
- let a = 1;
- (function() {
- eval('var a');
- })();
-} catch (e) {
- caught = true;
-}
-assertFalse(caught);
-
-// var across with doesn't conflict
-caught = false;
-try {
- (function() {
- with ({x: 1}) {
- eval("var x");
- }
- })();
-} catch (e) {
- caught = true;
-}
-assertFalse(caught);
-
-// var can still conflict with let across a with
-caught = false;
-try {
- (function() {
- let x;
- with ({x: 1}) {
- eval("var x");
- }
- })();
-} catch (e) {
- caught = true;
-}
-assertTrue(caught);
-
-// Functions declared in eval also conflict
-caught = false
-try {
- (function() {
- {
- let x = 1;
- eval('function x() {}');
- }
- })();
-} catch (e) {
- caught = true;
-}
-assertTrue(caught);
-
-// TODO(littledan): Hoisting x out of the block should be
-// prevented in this case BUG(v8:4479)
-caught = false
-try {
- (function() {
- {
- let x = 1;
- eval('{ function x() {} }');
- }
- })();
-} catch (e) {
- caught = true;
-}
-// TODO(littledan): switch to assertTrue when bug is fixed
-assertTrue(caught);
diff --git a/test/mjsunit/harmony/block-for-sloppy.js b/test/mjsunit/harmony/block-for-sloppy.js
deleted file mode 100644
index 261c46a..0000000
--- a/test/mjsunit/harmony/block-for-sloppy.js
+++ /dev/null
@@ -1,201 +0,0 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Flags: --harmony-sloppy --harmony-sloppy-let
-
-function props(x) {
- var array = [];
- for (let p in x) array.push(p);
- return array.sort();
-}
-
-assertEquals(0, props({}).length);
-assertEquals(1, props({x:1}).length);
-assertEquals(2, props({x:1, y:2}).length);
-
-assertArrayEquals(["x"], props({x:1}));
-assertArrayEquals(["x", "y"], props({x:1, y:2}));
-assertArrayEquals(["x", "y", "zoom"], props({x:1, y:2, zoom:3}));
-
-assertEquals(0, props([]).length);
-assertEquals(1, props([1]).length);
-assertEquals(2, props([1,2]).length);
-
-assertArrayEquals(["0"], props([1]));
-assertArrayEquals(["0", "1"], props([1,2]));
-assertArrayEquals(["0", "1", "2"], props([1,2,3]));
-
-var o = {};
-var a = [];
-let i = "outer_i";
-let s = "outer_s";
-for (let i = 0x0020; i < 0x01ff; i+=2) {
- let s = 'char:' + String.fromCharCode(i);
- a.push(s);
- o[s] = i;
-}
-assertArrayEquals(a, props(o));
-assertEquals(i, "outer_i");
-assertEquals(s, "outer_s");
-
-var a = [];
-assertEquals(0, props(a).length);
-a[Math.pow(2,30)-1] = 0;
-assertEquals(1, props(a).length);
-a[Math.pow(2,31)-1] = 0;
-assertEquals(2, props(a).length);
-a[1] = 0;
-assertEquals(3, props(a).length);
-
-var result = '';
-for (let p in {a : [0], b : 1}) { result += p; }
-assertEquals('ab', result);
-
-var result = '';
-for (let p in {a : {v:1}, b : 1}) { result += p; }
-assertEquals('ab', result);
-
-var result = '';
-for (let p in { get a() {}, b : 1}) { result += p; }
-assertEquals('ab', result);
-
-var result = '';
-for (let p in { get a() {}, set a(x) {}, b : 1}) { result += p; }
-assertEquals('ab', result);
-
-
-// Check that there is exactly one variable without initializer
-// in a for-in statement with let variables.
-assertThrows("function foo() { 'use strict'; for (let in {}) { } }", SyntaxError);
-assertThrows("function foo() { 'use strict'; for (let x = 3 in {}) { } }", SyntaxError);
-assertThrows("function foo() { 'use strict'; for (let x, y in {}) { } }", SyntaxError);
-assertThrows("function foo() { 'use strict'; for (let x = 3, y in {}) { } }", SyntaxError);
-assertThrows("function foo() { 'use strict'; for (let x, y = 4 in {}) { } }", SyntaxError);
-assertThrows("function foo() { 'use strict'; for (let x = 3, y = 4 in {}) { } }", SyntaxError);
-
-
-// In a normal for statement the iteration variable is
-// freshly allocated for each iteration.
-function closures1() {
- let a = [];
- for (let i = 0; i < 5; ++i) {
- a.push(function () { return i; });
- }
- for (let j = 0; j < 5; ++j) {
- assertEquals(j, a[j]());
- }
-}
-closures1();
-
-
-function closures2() {
- let a = [], b = [];
- for (let i = 0, j = 10; i < 5; ++i, ++j) {
- a.push(function () { return i; });
- b.push(function () { return j; });
- }
- for (let k = 0; k < 5; ++k) {
- assertEquals(k, a[k]());
- assertEquals(k + 10, b[k]());
- }
-}
-closures2();
-
-
-function closure_in_for_init() {
- let a = [];
- for (let i = 0, f = function() { return i }; i < 5; ++i) {
- a.push(f);
- }
- for (let k = 0; k < 5; ++k) {
- assertEquals(0, a[k]());
- }
-}
-closure_in_for_init();
-
-
-function closure_in_for_cond() {
- let a = [];
- for (let i = 0; a.push(function () { return i; }), i < 5; ++i) { }
- for (let k = 0; k < 5; ++k) {
- assertEquals(k, a[k]());
- }
-}
-closure_in_for_cond();
-
-
-function closure_in_for_next() {
- let a = [];
- for (let i = 0; i < 5; a.push(function () { return i; }), ++i) { }
- for (let k = 0; k < 5; ++k) {
- assertEquals(k + 1, a[k]());
- }
-}
-closure_in_for_next();
-
-
-// In a for-in statement the iteration variable is fresh
-// for each iteration.
-function closures3(x) {
- let a = [];
- for (let p in x) {
- a.push(function () { return p; });
- }
- let k = 0;
- for (let q in x) {
- assertEquals(q, a[k]());
- ++k;
- }
-}
-closures3({a : [0], b : 1, c : {v : 1}, get d() {}, set e(x) {}});
-
-// Check normal for statement completion values.
-assertEquals(1, eval("for (let i = 0; i < 10; i++) { 1; }"));
-assertEquals(9, eval("for (let i = 0; i < 10; i++) { i; }"));
-assertEquals(undefined, eval("for (let i = 0; false;) { }"));
-assertEquals(undefined, eval("for (const i = 0; false;) { }"));
-assertEquals(undefined, eval("for (let i = 0; i < 10; i++) { }"));
-assertEquals(undefined, eval("for (let i = 0; false;) { i; }"));
-assertEquals(undefined, eval("for (const i = 0; false;) { i; }"));
-assertEquals(undefined, eval("for (let i = 0; true;) { break; }"));
-assertEquals(undefined, eval("for (const i = 0; true;) { break; }"));
-assertEquals(undefined, eval("for (let i = 0; i < 10; i++) { continue; }"));
-assertEquals(undefined, eval("for (let i = 0; true;) { break; i; }"));
-assertEquals(undefined, eval("for (const i = 0; true;) { break; i; }"));
-assertEquals(undefined, eval("for (let i = 0; i < 10; i++) { continue; i; }"));
-assertEquals(0, eval("for (let i = 0; true;) { i; break; }"));
-assertEquals(0, eval("for (const i = 0; true;) { i; break; }"));
-assertEquals(9, eval("for (let i = 0; i < 10; i++) { i; continue; }"));
-assertEquals(
- undefined, eval("for (let i = 0; true; i++) { i; if (i >= 3) break; }"));
-assertEquals(
- undefined, eval("for (let i = 0; true; i++) { if (i >= 3) break; i; }"));
-assertEquals(
- undefined, eval("for (let i = 0; i < 10; i++) { if (i >= 3) continue; i; }"));
-assertEquals(undefined, eval("foo: for (let i = 0; true;) { break foo; }"));
-assertEquals(undefined, eval("foo: for (const i = 0; true;) { break foo; }"));
-assertEquals(3, eval("foo: for (let i = 3; true;) { i; break foo; }"));
diff --git a/test/mjsunit/harmony/block-leave-sloppy.js b/test/mjsunit/harmony/block-leave-sloppy.js
deleted file mode 100644
index 0023fa0..0000000
--- a/test/mjsunit/harmony/block-leave-sloppy.js
+++ /dev/null
@@ -1,224 +0,0 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Flags: --harmony-sloppy --harmony-sloppy-let
-
-// We want to test the context chain shape. In each of the tests cases
-// below, the outer with is to force a runtime lookup of the identifier 'x'
-// to actually verify that the inner context has been discarded. A static
-// lookup of 'x' might accidentally succeed.
-
-{
- let x = 2;
- L: {
- let x = 3;
- assertEquals(3, x);
- break L;
- assertTrue(false);
- }
- assertEquals(2, x);
-}
-
-do {
- let x = 4;
- assertEquals(4,x);
- {
- let x = 5;
- assertEquals(5, x);
- continue;
- assertTrue(false);
- }
-} while (false);
-
-var caught = false;
-try {
- {
- let xx = 18;
- throw 25;
- assertTrue(false);
- }
-} catch (e) {
- caught = true;
- assertEquals(25, e);
- (function () {
- try {
- // NOTE: This checks that the block scope containing xx has been
- // removed from the context chain.
- eval('xx');
- assertTrue(false); // should not reach here
- } catch (e2) {
- assertTrue(e2 instanceof ReferenceError);
- }
- })();
-}
-assertTrue(caught);
-
-
-(function(x) {
- label: {
- let x = 'inner';
- break label;
- }
- assertEquals('outer', eval('x'));
-})('outer');
-
-
-(function(x) {
- label: {
- let x = 'middle';
- {
- let x = 'inner';
- break label;
- }
- }
- assertEquals('outer', eval('x'));
-})('outer');
-
-
-(function(x) {
- for (var i = 0; i < 10; ++i) {
- let x = 'inner' + i;
- continue;
- }
- assertEquals('outer', eval('x'));
-})('outer');
-
-
-(function(x) {
- label: for (var i = 0; i < 10; ++i) {
- let x = 'middle' + i;
- for (var j = 0; j < 10; ++j) {
- let x = 'inner' + j;
- continue label;
- }
- }
- assertEquals('outer', eval('x'));
-})('outer');
-
-
-(function(x) {
- try {
- let x = 'inner';
- throw 0;
- } catch (e) {
- assertEquals('outer', eval('x'));
- }
-})('outer');
-
-
-(function(x) {
- try {
- let x = 'middle';
- {
- let x = 'inner';
- throw 0;
- }
- } catch (e) {
- assertEquals('outer', eval('x'));
- }
-})('outer');
-
-
-try {
- (function(x) {
- try {
- let x = 'inner';
- throw 0;
- } finally {
- assertEquals('outer', eval('x'));
- }
- })('outer');
-} catch (e) {
- if (e instanceof MjsUnitAssertionError) throw e;
-}
-
-
-try {
- (function(x) {
- try {
- let x = 'middle';
- {
- let x = 'inner';
- throw 0;
- }
- } finally {
- assertEquals('outer', eval('x'));
- }
- })('outer');
-} catch (e) {
- if (e instanceof MjsUnitAssertionError) throw e;
-}
-
-
-// Verify that the context is correctly set in the stack frame after exiting
-// from eval.
-function f() {}
-
-(function(x) {
- label: {
- let x = 'inner';
- break label;
- }
- f(); // The context could be restored from the stack after the call.
- assertEquals('outer', eval('x'));
-})('outer');
-
-
-(function(x) {
- for (var i = 0; i < 10; ++i) {
- let x = 'inner';
- continue;
- }
- f();
- assertEquals('outer', eval('x'));
-})('outer');
-
-
-(function(x) {
- try {
- let x = 'inner';
- throw 0;
- } catch (e) {
- f();
- assertEquals('outer', eval('x'));
- }
-})('outer');
-
-
-try {
- (function(x) {
- try {
- let x = 'inner';
- throw 0;
- } finally {
- f();
- assertEquals('outer', eval('x'));
- }
- })('outer');
-} catch (e) {
- if (e instanceof MjsUnitAssertionError) throw e;
-}
diff --git a/test/mjsunit/harmony/block-let-crankshaft-sloppy.js b/test/mjsunit/harmony/block-let-crankshaft-sloppy.js
deleted file mode 100644
index 4f29c05..0000000
--- a/test/mjsunit/harmony/block-let-crankshaft-sloppy.js
+++ /dev/null
@@ -1,483 +0,0 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Flags: --allow-natives-syntax
-// Flags: --harmony-sloppy --harmony-sloppy-let
-
-// Check that the following functions are optimizable.
-var functions = [ f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14,
- f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26,
- f27, f28, f29, f30, f31, f32, f33];
-
-for (var i = 0; i < functions.length; ++i) {
- var func = functions[i];
- print("Testing:");
- print(func);
- for (var j = 0; j < 10; ++j) {
- func(12);
- }
- %OptimizeFunctionOnNextCall(func);
- func(12);
- assertOptimized(func);
-}
-
-function f1() { }
-
-function f2(x) { }
-
-function f3() {
- let x;
-}
-
-function f4() {
- function foo() {
- }
-}
-
-function f5() {
- let x = 1;
-}
-
-function f6() {
- const x = 1;
-}
-
-function f7(x) {
- return x;
-}
-
-function f8() {
- let x;
- return x;
-}
-
-function f9() {
- function x() {
- }
- return x;
-}
-
-function f10(x) {
- x = 1;
-}
-
-function f11() {
- let x;
- x = 1;
-}
-
-function f12() {
- function x() {};
- x = 1;
-}
-
-function f13(x) {
- (function() { x; });
-}
-
-function f14() {
- let x;
- (function() { x; });
-}
-
-function f15() {
- function x() {
- }
- (function() { x; });
-}
-
-function f16() {
- let x = 1;
- (function() { x; });
-}
-
-function f17() {
- const x = 1;
- (function() { x; });
-}
-
-function f18(x) {
- return x;
- (function() { x; });
-}
-
-function f19() {
- let x;
- return x;
- (function() { x; });
-}
-
-function f20() {
- function x() {
- }
- return x;
- (function() { x; });
-}
-
-function f21(x) {
- x = 1;
- (function() { x; });
-}
-
-function f22() {
- let x;
- x = 1;
- (function() { x; });
-}
-
-function f23() {
- function x() { }
- x = 1;
- (function() { x; });
-}
-
-function f24() {
- let x = 1;
- {
- let x = 2;
- {
- let x = 3;
- assertEquals(3, x);
- }
- assertEquals(2, x);
- }
- assertEquals(1, x);
-}
-
-function f25() {
- {
- let x = 2;
- L: {
- let x = 3;
- assertEquals(3, x);
- break L;
- assertTrue(false);
- }
- assertEquals(2, x);
- }
- assertTrue(true);
-}
-
-function f26() {
- {
- let x = 1;
- L: {
- let x = 2;
- {
- let x = 3;
- assertEquals(3, x);
- break L;
- assertTrue(false);
- }
- assertTrue(false);
- }
- assertEquals(1, x);
- }
-}
-
-
-function f27() {
- do {
- let x = 4;
- assertEquals(4,x);
- {
- let x = 5;
- assertEquals(5, x);
- continue;
- assertTrue(false);
- }
- } while (false);
-}
-
-function f28() {
- label: for (var i = 0; i < 10; ++i) {
- let x = 'middle' + i;
- for (var j = 0; j < 10; ++j) {
- let x = 'inner' + j;
- continue label;
- }
- }
-}
-
-function f29() {
- // Verify that the context is correctly set in the stack frame after exiting
- // from with.
-
- let x = 'outer';
- label: {
- let x = 'inner';
- break label;
- }
- f(); // The context could be restored from the stack after the call.
- assertEquals('outer', x);
-
- function f() {
- assertEquals('outer', x);
- };
-}
-
-function f30() {
- let x = 'outer';
- for (var i = 0; i < 10; ++i) {
- let x = 'inner';
- continue;
- }
- f();
- assertEquals('outer', x);
-
- function f() {
- assertEquals('outer', x);
- };
-}
-
-function f31() {
- {
- let x = 'outer';
- label: for (var i = 0; assertEquals('outer', x), i < 10; ++i) {
- let x = 'middle' + i;
- {
- let x = 'inner' + j;
- continue label;
- }
- }
- assertEquals('outer', x);
- }
-}
-
-var c = true;
-
-function f32() {
- {
- let x = 'outer';
- L: {
- {
- let x = 'inner';
- if (c) {
- break L;
- }
- }
- foo();
- }
- }
-
- function foo() {
- return 'bar';
- }
-}
-
-function f33() {
- {
- let x = 'outer';
- L: {
- {
- let x = 'inner';
- if (c) {
- break L;
- }
- foo();
- }
- }
- }
-
- function foo() {
- return 'bar';
- }
-}
-
-function TestThrow() {
- function f() {
- let x = 'outer';
- {
- let x = 'inner';
- throw x;
- }
- }
- for (var i = 0; i < 5; i++) {
- try {
- f();
- } catch (e) {
- assertEquals('inner', e);
- }
- }
- %OptimizeFunctionOnNextCall(f);
- try {
- f();
- } catch (e) {
- assertEquals('inner', e);
- }
- assertOptimized(f);
-}
-
-TestThrow();
-
-// Test that temporal dead zone semantics for function and block scoped
-// let bindings are handled by the optimizing compiler.
-
-function TestFunctionLocal(s) {
- 'use strict';
- var func = eval("(function baz(){" + s + "; })");
- print("Testing:");
- print(func);
- for (var i = 0; i < 5; ++i) {
- try {
- func();
- assertUnreachable();
- } catch (e) {
- assertInstanceof(e, ReferenceError);
- }
- }
- %OptimizeFunctionOnNextCall(func);
- try {
- func();
- assertUnreachable();
- } catch (e) {
- assertInstanceof(e, ReferenceError);
- }
-}
-
-function TestFunctionContext(s) {
- 'use strict';
- var func = eval("(function baz(){ " + s + "; (function() { x; }); })");
- print("Testing:");
- print(func);
- for (var i = 0; i < 5; ++i) {
- print(i);
- try {
- func();
- assertUnreachable();
- } catch (e) {
- assertInstanceof(e, ReferenceError);
- }
- }
- print("optimize");
- %OptimizeFunctionOnNextCall(func);
- try {
- print("call");
- func();
- assertUnreachable();
- } catch (e) {
- print("catch");
- assertInstanceof(e, ReferenceError);
- }
-}
-
-function TestBlockLocal(s) {
- 'use strict';
- var func = eval("(function baz(){ { " + s + "; } })");
- print("Testing:");
- print(func);
- for (var i = 0; i < 5; ++i) {
- try {
- func();
- assertUnreachable();
- } catch (e) {
- assertInstanceof(e, ReferenceError);
- }
- }
- %OptimizeFunctionOnNextCall(func);
- try {
- func();
- assertUnreachable();
- } catch (e) {
- assertInstanceof(e, ReferenceError);
- }
-}
-
-function TestBlockContext(s) {
- 'use strict';
- var func = eval("(function baz(){ { " + s + "; (function() { x; }); } })");
- print("Testing:");
- print(func);
- for (var i = 0; i < 5; ++i) {
- print(i);
- try {
- func();
- assertUnreachable();
- } catch (e) {
- assertInstanceof(e, ReferenceError);
- }
- }
- print("optimize");
- %OptimizeFunctionOnNextCall(func);
- try {
- print("call");
- func();
- assertUnreachable();
- } catch (e) {
- print("catch");
- assertInstanceof(e, ReferenceError);
- }
-}
-
-function TestAll(s) {
- TestFunctionLocal(s);
- TestFunctionContext(s);
- TestBlockLocal(s);
- TestBlockContext(s);
-}
-
-// Use before initialization in declaration statement.
-TestAll('let x = x + 1');
-TestAll('let x = x += 1');
-TestAll('let x = x++');
-TestAll('let x = ++x');
-TestAll('const x = x + 1');
-
-// Use before initialization in prior statement.
-TestAll('x + 1; let x;');
-TestAll('x = 1; let x;');
-TestAll('x += 1; let x;');
-TestAll('++x; let x;');
-TestAll('x++; let x;');
-TestAll('let y = x; const x = 1;');
-
-
-function f(x) {
- let y = x + 42;
- return y;
-}
-
-function g(x) {
- {
- let y = x + 42;
- return y;
- }
-}
-
-for (var i=0; i<10; i++) {
- f(i);
- g(i);
-}
-
-%OptimizeFunctionOnNextCall(f);
-%OptimizeFunctionOnNextCall(g);
-
-f(12);
-g(12);
-
-assertTrue(%GetOptimizationStatus(f) != 2);
-assertTrue(%GetOptimizationStatus(g) != 2);
diff --git a/test/mjsunit/harmony/block-let-declaration-sloppy.js b/test/mjsunit/harmony/block-let-declaration-sloppy.js
deleted file mode 100644
index af95553..0000000
--- a/test/mjsunit/harmony/block-let-declaration-sloppy.js
+++ /dev/null
@@ -1,174 +0,0 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Test let declarations in various settings.
-
-// Flags: --harmony-sloppy --harmony-sloppy-let
-
-// Global
-let x;
-let y = 2;
-const z = 4;
-class c { static foo() { return 1; } }
-
-// Block local
-{
- let y;
- let x = 3;
- const z = 5;
- class c { static foo() { return 2; } }
-}
-
-assertEquals(undefined, x);
-assertEquals(2,y);
-assertEquals(4,z);
-assertEquals(1, c.foo());
-
-if (true) {
- let y;
- assertEquals(undefined, y);
-}
-
-// Invalid declarations are early errors in harmony mode and thus should trigger
-// an exception in eval code during parsing, before even compiling or executing
-// the code. Thus the generated function is not called here.
-function TestLocalThrows(str, expect) {
- assertThrows("(function(arg){ 'use strict'; " + str + "})", expect);
-}
-
-function TestLocalDoesNotThrow(str) {
- assertDoesNotThrow("(function(arg){ 'use strict'; " + str + "})()");
-}
-
-// Test let declarations in statement positions.
-TestLocalThrows("if (true) let x;", SyntaxError);
-TestLocalThrows("if (true) {} else let x;", SyntaxError);
-TestLocalThrows("do let x; while (false)", SyntaxError);
-TestLocalThrows("while (false) let x;", SyntaxError);
-TestLocalThrows("label: let x;", SyntaxError);
-TestLocalThrows("for (;false;) let x;", SyntaxError);
-TestLocalDoesNotThrow("switch (true) { case true: let x; }");
-TestLocalDoesNotThrow("switch (true) { default: let x; }");
-
-// Test const declarations with initialisers in statement positions.
-TestLocalThrows("if (true) const x = 1;", SyntaxError);
-TestLocalThrows("if (true) {} else const x = 1;", SyntaxError);
-TestLocalThrows("do const x = 1; while (false)", SyntaxError);
-TestLocalThrows("while (false) const x = 1;", SyntaxError);
-TestLocalThrows("label: const x = 1;", SyntaxError);
-TestLocalThrows("for (;false;) const x = 1;", SyntaxError);
-TestLocalDoesNotThrow("switch (true) { case true: const x = 1; }");
-TestLocalDoesNotThrow("switch (true) { default: const x = 1; }");
-
-// Test const declarations without initialisers.
-TestLocalThrows("const x;", SyntaxError);
-TestLocalThrows("const x = 1, y;", SyntaxError);
-TestLocalThrows("const x, y = 1;", SyntaxError);
-
-// Test const declarations without initialisers in statement positions.
-TestLocalThrows("if (true) const x;", SyntaxError);
-TestLocalThrows("if (true) {} else const x;", SyntaxError);
-TestLocalThrows("do const x; while (false)", SyntaxError);
-TestLocalThrows("while (false) const x;", SyntaxError);
-TestLocalThrows("label: const x;", SyntaxError);
-TestLocalThrows("for (;false;) const x;", SyntaxError);
-TestLocalThrows("switch (true) { case true: const x; }", SyntaxError);
-TestLocalThrows("switch (true) { default: const x; }", SyntaxError);
-
-// Test var declarations in statement positions.
-TestLocalDoesNotThrow("if (true) var x;");
-TestLocalDoesNotThrow("if (true) {} else var x;");
-TestLocalDoesNotThrow("do var x; while (false)");
-TestLocalDoesNotThrow("while (false) var x;");
-TestLocalDoesNotThrow("label: var x;");
-TestLocalDoesNotThrow("for (;false;) var x;");
-TestLocalDoesNotThrow("switch (true) { case true: var x; }");
-TestLocalDoesNotThrow("switch (true) { default: var x; }");
-
-// Test class declarations with initialisers in statement positions.
-TestLocalThrows("if (true) class x { };", SyntaxError);
-TestLocalThrows("if (true) {} else class x { };", SyntaxError);
-TestLocalThrows("do class x { }; while (false)", SyntaxError);
-TestLocalThrows("while (false) class x { };", SyntaxError);
-TestLocalThrows("label: class x { };", SyntaxError);
-TestLocalThrows("for (;false;) class x { };", SyntaxError);
-TestLocalDoesNotThrow("switch (true) { case true: class x { }; }");
-TestLocalDoesNotThrow("switch (true) { default: class x { }; }");
-
-// Test that redeclarations of functions are only allowed in outermost scope.
-TestLocalThrows("{ let f; var f; }");
-TestLocalThrows("{ var f; let f; }");
-TestLocalThrows("{ function f() {} let f; }");
-TestLocalThrows("{ let f; function f() {} }");
-TestLocalThrows("{ function f() {} var f; }");
-TestLocalThrows("{ var f; function f() {} }");
-TestLocalThrows("{ function f() {} class f {} }");
-TestLocalThrows("{ class f {}; function f() {} }");
-TestLocalThrows("{ function f() {} function f() {} }");
-TestLocalThrows("function f() {} let f;");
-TestLocalThrows("let f; function f() {}");
-TestLocalThrows("function f() {} class f {}");
-TestLocalThrows("class f {}; function f() {}");
-TestLocalDoesNotThrow("function arg() {}");
-TestLocalDoesNotThrow("function f() {} var f;");
-TestLocalDoesNotThrow("var f; function f() {}");
-TestLocalDoesNotThrow("function f() {} function f() {}");
-
-function g(f) {
- function f() { return 1 }
- return f()
-}
-assertEquals(1, g(function() { return 2 }))
-
-
-// Test function declarations in source element and
-// sloppy statement positions.
-function f() {
- // Sloppy source element positions.
- function g0() {
- "use strict";
- // Strict source element positions.
- function h() { }
- {
- function h1() { }
- }
- }
- {
- function g1() { }
- }
-}
-f();
-
-// Test function declarations in statement position in strict mode.
-TestLocalThrows("function f() { if (true) function g() {} }", SyntaxError);
-TestLocalThrows("function f() { if (true) {} else function g() {} }", SyntaxError);
-TestLocalThrows("function f() { do function g() {} while (false) }", SyntaxError);
-TestLocalThrows("function f() { while (false) function g() {} }", SyntaxError);
-TestLocalThrows("function f() { label: function g() {} }", SyntaxError);
-TestLocalThrows("function f() { for (;false;) function g() {} }", SyntaxError);
-TestLocalDoesNotThrow("function f() { switch (true) { case true: function g() {} } }");
-TestLocalDoesNotThrow("function f() { switch (true) { default: function g() {} } }");
diff --git a/test/mjsunit/harmony/block-let-semantics-sloppy.js b/test/mjsunit/harmony/block-let-semantics-sloppy.js
deleted file mode 100644
index a55ff8f..0000000
--- a/test/mjsunit/harmony/block-let-semantics-sloppy.js
+++ /dev/null
@@ -1,193 +0,0 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Flags: --harmony-sloppy --harmony-sloppy-let --harmony-sloppy-function
-
-// Test temporal dead zone semantics of let bound variables in
-// function and block scopes.
-
-function TestFunctionLocal(s) {
- try {
- eval("(function(){" + s + "; })")();
- } catch (e) {
- assertInstanceof(e, ReferenceError);
- return;
- }
- assertUnreachable();
-}
-
-function TestBlockLocal(s,e) {
- try {
- eval("(function(){ {" + s + ";} })")();
- } catch (e) {
- assertInstanceof(e, ReferenceError);
- return;
- }
- assertUnreachable();
-}
-
-
-function TestAll(s) {
- TestBlockLocal(s);
- TestFunctionLocal(s);
-}
-
-// Use before initialization in declaration statement.
-TestAll('let x = x + 1');
-TestAll('let x = x += 1');
-TestAll('let x = x++');
-TestAll('let x = ++x');
-TestAll('const x = x + 1');
-
-// Use before initialization in prior statement.
-TestAll('x + 1; let x;');
-TestAll('x = 1; let x;');
-TestAll('x += 1; let x;');
-TestAll('++x; let x;');
-TestAll('x++; let x;');
-TestAll('let y = x; const x = 1;');
-TestAll('let y = x; class x {}');
-
-TestAll('f(); let x; function f() { return x + 1; }');
-TestAll('f(); let x; function f() { x = 1; }');
-TestAll('f(); let x; function f() { x += 1; }');
-TestAll('f(); let x; function f() { ++x; }');
-TestAll('f(); let x; function f() { x++; }');
-TestAll('f(); const x = 1; function f() { return x; }');
-TestAll('f(); class x { }; function f() { return x; }');
-
-TestAll('f()(); let x; function f() { return function() { return x + 1; } }');
-TestAll('f()(); let x; function f() { return function() { x = 1; } }');
-TestAll('f()(); let x; function f() { return function() { x += 1; } }');
-TestAll('f()(); let x; function f() { return function() { ++x; } }');
-TestAll('f()(); let x; function f() { return function() { x++; } }');
-TestAll('f()(); const x = 1; function f() { return function() { return x; } }');
-TestAll('f()(); class x { }; function f() { return function() { return x; } }');
-
-for (var kw of ['let x = 2', 'const x = 2', 'class x { }']) {
- // Use before initialization with a dynamic lookup.
- TestAll(`eval("x"); ${kw};`);
- TestAll(`eval("x + 1;"); ${kw};`);
- TestAll(`eval("x = 1;"); ${kw};`);
- TestAll(`eval("x += 1;"); ${kw};`);
- TestAll(`eval("++x;"); ${kw};`);
- TestAll(`eval("x++;"); ${kw};`);
-
- // Use before initialization with check for eval-shadowed bindings.
- TestAll(`function f() { eval("var y = 2;"); x + 1; }; f(); ${kw};`);
- TestAll(`function f() { eval("var y = 2;"); x = 1; }; f(); ${kw};`);
- TestAll(`function f() { eval("var y = 2;"); x += 1; }; f(); ${kw};`);
- TestAll(`function f() { eval("var y = 2;"); ++x; }; f(); ${kw};`);
- TestAll(`function f() { eval("var y = 2;"); x++; }; f(); ${kw};`);
-}
-
-// Test that variables introduced by function declarations are created and
-// initialized upon entering a function / block scope.
-function f() {
- {
- assertEquals(2, g1());
- assertEquals(2, eval("g1()"));
-
- // block scoped function declaration
- function g1() {
- return 2;
- }
- }
-
- assertEquals(3, g2());
- assertEquals(3, eval("g2()"));
- // function scoped function declaration
- function g2() {
- return 3;
- }
-}
-f();
-
-// Test that a function declaration introduces a block scoped variable
-// and no function hoisting if there is a conflict.
-TestFunctionLocal('{ function k() { return 0; } }; k(); let k;');
-
-// Test that a function declaration sees the scope it resides in.
-function f2() {
- let m, n, o, p;
- {
- m = g;
- function g() {
- return a;
- }
- let a = 1;
- }
- assertEquals(1, m());
-
- try {
- throw 2;
- } catch(b) {
- n = h;
- function h() {
- return b + c;
- }
- let c = 3;
- }
- assertEquals(5, n());
-
- {
- o = i;
- function i() {
- return d;
- }
- let d = 4;
- }
- assertEquals(4, o());
-
- try {
- throw 5;
- } catch(e) {
- p = j;
- function j() {
- return e + f;
- }
- let f = 6;
- }
- assertEquals(11, p());
-}
-f2();
-
-// Test that resolution of let bound variables works with scopes that call eval.
-function outer() {
- function middle() {
- function inner() {
- return x;
- }
- eval("1 + 1");
- return x + inner();
- }
-
- let x = 1;
- return middle();
-}
-
-assertEquals(2, outer());
diff --git a/test/mjsunit/harmony/block-scoping-sloppy.js b/test/mjsunit/harmony/block-scoping-sloppy.js
deleted file mode 100644
index 1785901..0000000
--- a/test/mjsunit/harmony/block-scoping-sloppy.js
+++ /dev/null
@@ -1,309 +0,0 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Flags: --allow-natives-syntax --harmony-sloppy --harmony-sloppy-let --harmony-sloppy-function
-// Test functionality of block scopes.
-
-// Hoisting of var declarations.
-function f1() {
- {
- var x = 1;
- var y;
- }
- assertEquals(1, x)
- assertEquals(undefined, y)
-}
-for (var j = 0; j < 5; ++j) f1();
-%OptimizeFunctionOnNextCall(f1);
-f1();
-assertTrue(%GetOptimizationStatus(f1) != 2);
-
-// Dynamic lookup in and through block contexts.
-function f2(one) {
- var x = one + 1;
- let y = one + 2;
- const u = one + 4;
- class a { static foo() { return one + 6; } }
- {
- let z = one + 3;
- const v = one + 5;
- class b { static foo() { return one + 7; } }
- assertEquals(1, eval('one'));
- assertEquals(2, eval('x'));
- assertEquals(3, eval('y'));
- assertEquals(4, eval('z'));
- assertEquals(5, eval('u'));
- assertEquals(6, eval('v'));
- assertEquals(7, eval('a.foo()'));
- assertEquals(8, eval('b.foo()'));
- }
-}
-
-f2(1);
-
-// Lookup in and through block contexts.
-function f3(one) {
- var x = one + 1;
- let y = one + 2;
- const u = one + 4;
- class a { static foo() { return one + 6; } }
- {
- let z = one + 3;
- const v = one + 5;
- class b { static foo() { return one + 7; } }
- assertEquals(1, one);
- assertEquals(2, x);
- assertEquals(3, y);
- assertEquals(4, z);
- assertEquals(5, u);
- assertEquals(6, v);
- assertEquals(7, a.foo());
- assertEquals(8, b.foo());
- }
-}
-for (var j = 0; j < 5; ++j) f3(1);
-%OptimizeFunctionOnNextCall(f3);
-f3(1);
-
-
-
-// Dynamic lookup from closure.
-function f4(one) {
- var x = one + 1;
- let y = one + 2;
- const u = one + 4;
- class a { static foo() { return one + 6; } }
- {
- let z = one + 3;
- const v = one + 5;
- class b { static foo() { return one + 7; } }
- function f() {
- assertEquals(1, eval('one'));
- assertEquals(2, eval('x'));
- assertEquals(3, eval('y'));
- assertEquals(4, eval('z'));
- assertEquals(5, eval('u'));
- assertEquals(6, eval('v'));
- assertEquals(7, eval('a.foo()'));
- assertEquals(8, eval('b.foo()'));
- }
- f();
- }
-}
-f4(1);
-
-
-// Lookup from closure.
-function f5(one) {
- var x = one + 1;
- let y = one + 2;
- const u = one + 4;
- class a { static foo() { return one + 6; } }
- {
- let z = one + 3;
- const v = one + 5;
- class b { static foo() { return one + 7; } }
- function f() {
- assertEquals(1, one);
- assertEquals(2, x);
- assertEquals(3, y);
- assertEquals(4, z);
- assertEquals(5, u);
- assertEquals(6, v);
- assertEquals(7, a.foo());
- assertEquals(8, b.foo());
- }
- f();
- }
-}
-f5(1);
-
-
-// Return from block.
-function f6() {
- let x = 1;
- const u = 3;
- {
- let y = 2;
- const v = 4;
- return x + y;
- }
-}
-assertEquals(3, f6(6));
-
-
-// Variable shadowing and lookup.
-function f7(a) {
- let b = 1;
- var c = 1;
- var d = 1;
- const e = 1;
- class f { static foo() { return 1; } }
- { // let variables shadowing argument, let, const, class and var variables
- let a = 2;
- let b = 2;
- let c = 2;
- let e = 2;
- let f = 2;
- assertEquals(2,a);
- assertEquals(2,b);
- assertEquals(2,c);
- assertEquals(2,e);
- assertEquals(2,f);
- }
- { // const variables shadowing argument, let, const and var variables
- const a = 2;
- const b = 2;
- const c = 2;
- const e = 2;
- const f = 2;
- assertEquals(2,a);
- assertEquals(2,b);
- assertEquals(2,c);
- assertEquals(2,e);
- assertEquals(2,f);
- }
- { // class variables shadowing argument, let, const and var variables
- class a { static foo() { return 2; } }
- class b { static foo() { return 2; } }
- class c { static foo() { return 2; } }
- class d { static foo() { return 2; } }
- class e { static foo() { return 2; } }
- class f { static foo() { return 2; } }
- assertEquals(2,a.foo());
- assertEquals(2,b.foo());
- assertEquals(2,c.foo());
- assertEquals(2,e.foo());
- assertEquals(2,f.foo());
- }
- try {
- throw 'stuff1';
- } catch (a) {
- assertEquals('stuff1',a);
- // catch variable shadowing argument
- a = 2;
- assertEquals(2,a);
- {
- // let variable shadowing catch variable
- let a = 3;
- assertEquals(3,a);
- try {
- throw 'stuff2';
- } catch (a) {
- assertEquals('stuff2',a);
- // catch variable shadowing let variable
- a = 4;
- assertEquals(4,a);
- }
- assertEquals(3,a);
- }
- assertEquals(2,a);
- }
- try {
- throw 'stuff3';
- } catch (c) {
- // catch variable shadowing var variable
- assertEquals('stuff3',c);
- {
- // const variable shadowing catch variable
- const c = 3;
- assertEquals(3,c);
- }
- assertEquals('stuff3',c);
- try {
- throw 'stuff4';
- } catch(c) {
- assertEquals('stuff4',c);
- // catch variable shadowing catch variable
- c = 3;
- assertEquals(3,c);
- }
- (function(c) {
- // argument shadowing catch variable
- c = 3;
- assertEquals(3,c);
- })();
- assertEquals('stuff3', c);
- (function() {
- // var variable shadowing catch variable
- var c = 3;
- })();
- assertEquals('stuff3', c);
- c = 2;
- }
- assertEquals(1,c);
- (function(a,b,c,e,f) {
- // arguments shadowing argument, let, const, class and var variable
- a = 2;
- b = 2;
- c = 2;
- e = 2;
- f = 2;
- assertEquals(2,a);
- assertEquals(2,b);
- assertEquals(2,c);
- assertEquals(2,e);
- assertEquals(2,f);
- // var variable shadowing var variable
- var d = 2;
- })(1,1);
- assertEquals(1,a);
- assertEquals(1,b);
- assertEquals(1,c);
- assertEquals(1,d);
- assertEquals(1,e);
- assertEquals(1,f.foo());
-}
-f7(1);
-
-
-// Ensure let and const variables are block local
-// and var variables function local.
-function f8() {
- var let_accessors = [];
- var var_accessors = [];
- var const_accessors = [];
- var class_accessors = [];
- for (var i = 0; i < 10; i++) {
- let x = i;
- var y = i;
- const z = i;
- class a { static foo() { return x; } }
- let_accessors[i] = function() { return x; }
- var_accessors[i] = function() { return y; }
- const_accessors[i] = function() { return z; }
- class_accessors[i] = function() { return a; }
- }
- for (var j = 0; j < 10; j++) {
- y = j + 10;
- assertEquals(j, let_accessors[j]());
- assertEquals(y, var_accessors[j]());
- assertEquals(j, const_accessors[j]());
- assertEquals(j, class_accessors[j]().foo());
- }
-}
-f8();
diff --git a/test/mjsunit/harmony/block-scoping-top-level-sloppy.js b/test/mjsunit/harmony/block-scoping-top-level-sloppy.js
deleted file mode 100644
index 6f6a8fe..0000000
--- a/test/mjsunit/harmony/block-scoping-top-level-sloppy.js
+++ /dev/null
@@ -1,34 +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: --min-preparse-length=0
-// Flags: --harmony-sloppy --harmony-sloppy-let
-
-let xxx = 1;
-let f = undefined;
-{
- let inner_x = xxx;
- f = function() { return inner_x; };
-}
-
-assertSame(1, f());
-
-xxx = 42;
-{
- f = function() { return inner_x1; };
- let inner_x1 = xxx;
-}
-
-assertSame(42, f());
-
-xxx = 31;
-{
- let inner_x1 = xxx;
- try {
- throw new Error();
- } catch (e) {
- f = function() { return inner_x1; };
- }
-}
-assertSame(31, f());
diff --git a/test/mjsunit/harmony/block-sloppy-function.js b/test/mjsunit/harmony/block-sloppy-function.js
deleted file mode 100644
index 2bea147..0000000
--- a/test/mjsunit/harmony/block-sloppy-function.js
+++ /dev/null
@@ -1,301 +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-sloppy --harmony-sloppy-let
-// Flags: --harmony-sloppy-function
-
-// Test Annex B 3.3 semantics for functions declared in blocks in sloppy mode.
-// http://www.ecma-international.org/ecma-262/6.0/#sec-block-level-function-declarations-web-legacy-compatibility-semantics
-
-(function overridingLocalFunction() {
- var x = [];
- assertEquals('function', typeof f);
- function f() {
- x.push(1);
- }
- f();
- {
- f();
- function f() {
- x.push(2);
- }
- f();
- }
- f();
- {
- f();
- function f() {
- x.push(3);
- }
- f();
- }
- f();
- assertArrayEquals([1, 2, 2, 2, 3, 3, 3], x);
-})();
-
-(function newFunctionBinding() {
- var x = [];
- assertEquals('undefined', typeof f);
- {
- f();
- function f() {
- x.push(2);
- }
- f();
- }
- f();
- {
- f();
- function f() {
- x.push(3);
- }
- f();
- }
- f();
- assertArrayEquals([2, 2, 2, 3, 3, 3], x);
-})();
-
-(function shadowingLetDoesntBind() {
- let f = 1;
- assertEquals(1, f);
- {
- let y = 3;
- function f() {
- y = 2;
- }
- f();
- assertEquals(2, y);
- }
- assertEquals(1, f);
-})();
-
-(function shadowingClassDoesntBind() {
- class f { }
- assertEquals('class f { }', f.toString());
- {
- let y = 3;
- function f() {
- y = 2;
- }
- f();
- assertEquals(2, y);
- }
- assertEquals('class f { }', f.toString());
-})();
-
-(function shadowingConstDoesntBind() {
- const f = 1;
- assertEquals(1, f);
- {
- let y = 3;
- function f() {
- y = 2;
- }
- f();
- assertEquals(2, y);
- }
- assertEquals(1, f);
-})();
-
-(function shadowingVarBinds() {
- var f = 1;
- assertEquals(1, f);
- {
- let y = 3;
- function f() {
- y = 2;
- }
- f();
- assertEquals(2, y);
- }
- assertEquals('function', typeof f);
-})();
-
-(function conditional() {
- if (true) {
- function f() { return 1; }
- } else {
- function f() { return 2; }
- }
- assertEquals(1, f());
-
- if (false) {
- function g() { return 1; }
- } else {
- function g() { return 2; }
- }
- assertEquals(2, g());
-})();
-
-(function skipExecution() {
- {
- function f() { return 1; }
- }
- assertEquals(1, f());
- {
- function f() { return 2; }
- }
- assertEquals(2, f());
- L: {
- assertEquals(3, f());
- break L;
- function f() { return 3; }
- }
- assertEquals(2, f());
-})();
-
-// Test that shadowing arguments is fine
-(function shadowArguments(x) {
- assertArrayEquals([1], arguments);
- {
- assertEquals('function', typeof arguments);
- function arguments() {}
- assertEquals('function', typeof arguments);
- }
- assertEquals('function', typeof arguments);
-})(1);
-
-// Shadow function parameter
-(function shadowParameter(x) {
- assertEquals(1, x);
- {
- function x() {}
- }
- assertEquals('function', typeof x);
-})(1);
-
-// Shadow function parameter
-(function shadowDefaultParameter(x = 0) {
- assertEquals(1, x);
- {
- function x() {}
- }
- // TODO(littledan): Once destructured parameters are no longer
- // let-bound, enable this assertion. This is the core of the test.
- // assertEquals('function', typeof x);
-})(1);
-
-(function shadowRestParameter(...x) {
- assertArrayEquals([1], x);
- {
- function x() {}
- }
- // TODO(littledan): Once destructured parameters are no longer
- // let-bound, enable this assertion. This is the core of the test.
- // assertEquals('function', typeof x);
-})(1);
-
-assertThrows(function notInDefaultScope(x = y) {
- {
- function y() {}
- }
- assertEquals('function', typeof y);
- assertEquals(x, undefined);
-}, ReferenceError);
-
-// Test that hoisting from blocks does happen in global scope
-function globalHoisted() { return 0; }
-{
- function globalHoisted() { return 1; }
-}
-assertEquals(1, globalHoisted());
-
-// Also happens when not previously defined
-assertEquals(undefined, globalUndefinedHoisted);
-{
- function globalUndefinedHoisted() { return 1; }
-}
-assertEquals(1, globalUndefinedHoisted());
-var globalUndefinedHoistedDescriptor =
- Object.getOwnPropertyDescriptor(this, "globalUndefinedHoisted");
-assertFalse(globalUndefinedHoistedDescriptor.configurable);
-assertTrue(globalUndefinedHoistedDescriptor.writable);
-assertTrue(globalUndefinedHoistedDescriptor.enumerable);
-assertEquals(1, globalUndefinedHoistedDescriptor.value());
-
-// When a function property is hoisted, it should be
-// made enumerable.
-// BUG(v8:4451)
-Object.defineProperty(this, "globalNonEnumerable", {
- value: false,
- configurable: true,
- writable: true,
- enumerable: false
-});
-eval("{function globalNonEnumerable() { return 1; }}");
-var globalNonEnumerableDescriptor
- = Object.getOwnPropertyDescriptor(this, "globalNonEnumerable");
-// BUG(v8:4451): Should be made non-configurable
-assertTrue(globalNonEnumerableDescriptor.configurable);
-assertTrue(globalNonEnumerableDescriptor.writable);
-// BUG(v8:4451): Should be made enumerable
-assertFalse(globalNonEnumerableDescriptor.enumerable);
-assertEquals(1, globalNonEnumerableDescriptor.value());
-
-// When a function property is hoisted, it should be overwritten and
-// made writable and overwritten, even if the property was non-writable.
-Object.defineProperty(this, "globalNonWritable", {
- value: false,
- configurable: true,
- writable: false,
- enumerable: true
-});
-eval("{function globalNonWritable() { return 1; }}");
-var globalNonWritableDescriptor
- = Object.getOwnPropertyDescriptor(this, "globalNonWritable");
-// BUG(v8:4451): Should be made non-configurable
-assertTrue(globalNonWritableDescriptor.configurable);
-// BUG(v8:4451): Should be made writable
-assertFalse(globalNonWritableDescriptor.writable);
-assertFalse(globalNonEnumerableDescriptor.enumerable);
-// BUG(v8:4451): Should be overwritten
-assertEquals(false, globalNonWritableDescriptor.value);
-
-// Test that hoisting from blocks does happen in an eval
-eval(`
- function evalHoisted() { return 0; }
- {
- function evalHoisted() { return 1; }
- }
- assertEquals(1, evalHoisted());
-`);
-
-// Test that hoisting from blocks happens from eval in a function
-!function() {
- eval(`
- function evalInFunctionHoisted() { return 0; }
- {
- function evalInFunctionHoisted() { return 1; }
- }
- assertEquals(1, evalInFunctionHoisted());
- `);
-}();
-
-let dontHoistGlobal;
-{ function dontHoistGlobal() {} }
-assertEquals(undefined, dontHoistGlobal);
-
-let dontHoistEval;
-// BUG(v8:) This shouldn't hoist and shouldn't throw
-var throws = false;
-try {
- eval("{ function dontHoistEval() {} }");
-} catch (e) {
- throws = true;
-}
-assertTrue(throws);
-
-// When the global object is frozen, silently don't hoist
-// Currently this actually throws BUG(v8:4452)
-Object.freeze(this);
-throws = false;
-try {
- eval('{ function hoistWhenFrozen() {} }');
-} catch (e) {
- throws = true;
-}
-assertFalse(this.hasOwnProperty("hoistWhenFrozen"));
-assertThrows(() => hoistWhenFrozen, ReferenceError);
-// Should be assertFalse BUG(v8:4452)
-assertTrue(throws);
diff --git a/test/mjsunit/harmony/do-expressions.js b/test/mjsunit/harmony/do-expressions.js
index b3be4ec..38b68b6 100644
--- a/test/mjsunit/harmony/do-expressions.js
+++ b/test/mjsunit/harmony/do-expressions.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-do-expressions --harmony-sloppy-let --allow-natives-syntax
+// Flags: --harmony-do-expressions --allow-natives-syntax
function returnValue(v) { return v; }
function MyError() {}
diff --git a/test/mjsunit/harmony/for-in.js b/test/mjsunit/harmony/for-in.js
new file mode 100644
index 0000000..58e343b
--- /dev/null
+++ b/test/mjsunit/harmony/for-in.js
@@ -0,0 +1,9 @@
+// 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-for-in
+
+assertThrows("for (var x = 0 in {});", SyntaxError);
+assertThrows("for (const x = 0 in {});", SyntaxError);
+assertThrows("for (let x = 0 in {});", SyntaxError);
diff --git a/test/mjsunit/harmony/function-sent.js b/test/mjsunit/harmony/function-sent.js
index b3cd644..cd0ca95 100644
--- a/test/mjsunit/harmony/function-sent.js
+++ b/test/mjsunit/harmony/function-sent.js
@@ -49,7 +49,7 @@
try {
yield function.sent;
} finally {
- return 666;
+ return 23;
}
}
@@ -77,7 +77,7 @@
let x = g();
assertEquals({value: 1, done: false}, x.next(1));
assertEquals({value: undefined, done: false}, x.next(2));
- assertEquals({value: 42, done: true}, x.return(42));
+ assertEquals({value: 23, done: true}, x.return(42));
}
}
diff --git a/test/mjsunit/harmony/generators.js b/test/mjsunit/harmony/generators.js
index df6cec8..895a248 100644
--- a/test/mjsunit/harmony/generators.js
+++ b/test/mjsunit/harmony/generators.js
@@ -2,6 +2,34 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// Flags: --ignition-generators --harmony-do-expressions
+// Flags: --allow-natives-syntax
+
+
+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
@@ -9,19 +37,19 @@
try {yield 1} catch (error) {assertEquals("caught", error)}
};
- assertThrowsEquals(() => g().throw("not caught"), "not caught");
+ assertThrowsEquals(() => Throw(g(), "not caught"), "not caught");
{
let x = g();
- assertEquals({value: 1, done: false}, x.next());
- assertEquals({value: undefined, done: true}, x.throw("caught"));
+ assertEquals({value: 1, done: false}, Next(x));
+ assertEquals({value: undefined, done: true}, Throw(x, "caught"));
}
{
let x = g();
- assertEquals({value: 1, done: false}, x.next());
- assertEquals({value: undefined, done: true}, x.next());
- assertThrowsEquals(() => x.throw("not caught"), "not caught");
+ assertEquals({value: 1, done: false}, Next(x));
+ assertEquals({value: undefined, done: true}, Next(x));
+ assertThrowsEquals(() => Throw(x, "not caught"), "not caught");
}
}
@@ -31,19 +59,19 @@
{
let x = g();
- assertEquals({value: 43, done: false}, x.next());
- assertEquals({value: 42, done: true}, x.next());
+ 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 {x.throw(666)} };
+ let g = function*() { try {return 42} finally {Throw(x, 666)} };
{
x = g();
- assertThrows(() => x.next(), TypeError); // still executing
+ assertThrows(() => Next(x), TypeError); // still executing
}
}
@@ -54,42 +82,42 @@
{ // "return" closes at suspendedStart
let x = g();
- assertEquals({value: 666, done: true}, x.return(666));
- assertEquals({value: undefined, done: true}, x.next(42));
- assertThrowsEquals(() => x.throw(43), 43);
- assertEquals({value: 42, done: true}, x.return(42));
+ 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(() => x.throw(666), 666);
- assertEquals({value: undefined, done: true}, x.next(42));
- assertEquals({value: 43, done: true}, x.return(43));
- assertThrowsEquals(() => x.throw(44), 44);
+ 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}, x.next());
- assertEquals({value: 13, done: true}, x.next(666));
- assertEquals({value: undefined, done: true}, x.next(666));
- assertThrowsEquals(() => x.throw(666), 666);
+ 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}, x.next());
- assertEquals({value: 13, done: true}, x.return(666));
- assertEquals({value: undefined, done: true}, x.next(666));
- assertEquals({value: 666, done: true}, x.return(666));
+ 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}, x.next());
- assertEquals({value: 13, done: true}, x.throw(666));
- assertThrowsEquals(() => x.throw(666), 666);
- assertEquals({value: undefined, done: true}, x.next(666));
+ 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));
}
}
@@ -100,45 +128,45 @@
{ // "return" closes at suspendedStart
let x = g();
- assertEquals({value: 666, done: true}, x.return(666));
- assertEquals({value: undefined, done: true}, x.next(42));
- assertThrowsEquals(() => x.throw(43), 43);
- assertEquals({value: 42, done: true}, x.return(42));
+ 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(() => x.throw(666), 666);
- assertEquals({value: undefined, done: true}, x.next(42));
- assertEquals({value: 43, done: true}, x.return(43));
- assertThrowsEquals(() => x.throw(44), 44);
+ 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}, x.next());
- assertEquals({value: undefined, done: true}, x.next(666));
- assertEquals({value: undefined, done: true}, x.next(666));
- assertThrowsEquals(() => x.throw(666), 666);
- assertEquals({value: 42, done: true}, x.return(42));
+ 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}, x.next());
- assertEquals({value: 666, done: true}, x.return(666));
- assertEquals({value: undefined, done: true}, x.next(666));
- assertThrowsEquals(() => x.throw(44), 44);
- assertEquals({value: 42, done: true}, x.return(42));
+ 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}, x.next());
- assertThrowsEquals(() => x.throw(666), 666);
- assertEquals({value: undefined, done: true}, x.next(666));
- assertThrowsEquals(() => x.throw(666), 666);
- assertEquals({value: 42, done: true}, x.return(42));
+ 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));
}
}
@@ -149,17 +177,17 @@
{
let x = g();
- assertEquals({value: 42, done: false}, x.next());
- assertEquals({value: 43, done: false}, x.return(666));
- assertEquals({value: 13, done: true}, x.next());
- assertEquals({value: 666, done: true}, x.return(666));
+ 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}, x.return(666));
- assertEquals({value: undefined, done: true}, x.next());
- assertEquals({value: 666, done: true}, x.return(666));
+ assertEquals({value: 666, done: true}, Return(x, 666));
+ assertEquals({value: undefined, done: true}, Next(x));
+ assertEquals({value: 666, done: true}, Return(x, 666));
}
}
@@ -170,17 +198,17 @@
{
let x = g();
- assertEquals({value: 42, done: false}, x.next());
- assertEquals({value: 43, done: false}, x.return(666));
- assertEquals({value: 666, done: true}, x.next());
- assertEquals({value: 5, done: true}, x.return(5));
+ 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}, x.return(666));
- assertEquals({value: undefined, done: true}, x.next());
- assertEquals({value: 666, done: true}, x.return(666));
+ assertEquals({value: 666, done: true}, Return(x, 666));
+ assertEquals({value: undefined, done: true}, Next(x));
+ assertEquals({value: 666, done: true}, Return(x, 666));
}
}
@@ -192,29 +220,29 @@
{
let x = g();
- assertEquals({value: 1, done: false}, x.next());
- assertEquals({value: 42, done: false}, x.next());
- assertEquals({value: 43, done: false}, x.next(666));
- assertEquals({value: 13, done: false}, x.next());
- assertEquals({value: undefined, done: true}, x.next());
+ 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}, x.next());
- assertEquals({value: 42, done: false}, x.next());
- assertEquals({value: 43, done: false}, x.return(666));
- assertEquals({value: 13, done: false}, x.next());
- assertEquals({value: undefined, done: true}, x.next());
+ 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}, x.next());
- assertEquals({value: 42, done: false}, x.next());
- assertEquals({value: 43, done: false}, x.throw(666));
- assertEquals({value: 13, done: false}, x.next());
- assertEquals({value: undefined, done: true}, x.next());
+ 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));
}
}
@@ -226,28 +254,28 @@
{
let x = g();
- assertEquals({value: 1, done: false}, x.next());
- assertEquals({value: 42, done: false}, x.next());
- assertEquals({value: 43, done: false}, x.next(666));
- assertEquals({value: undefined, done: false}, x.next());
- assertEquals({value: undefined, done: true}, x.next());
+ 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}, x.next());
- assertEquals({value: 42, done: false}, x.next());
- assertEquals({value: 43, done: false}, x.return(44));
- assertEquals({value: 44, done: false}, x.next());
- assertEquals({value: undefined, done: true}, x.next());
+ 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}, x.next());
- assertEquals({value: 42, done: false}, x.next());
- assertEquals({value: 43, done: false}, x.throw(666));
- assertThrowsEquals(() => x.next(), 666);
+ 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);
}
}
@@ -265,8 +293,370 @@
{
let x = g();
- assertEquals({value: 1, done: false}, x.next());
- assertEquals({value: 2, done: false}, x.next());
- assertEquals({value: 42, done: true}, x.return(42));
+ 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));
+}
+
+{
+ 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/harmony-string-pad-end.js b/test/mjsunit/harmony/harmony-string-pad-end.js
index 3292e94..03e5aea 100644
--- a/test/mjsunit/harmony/harmony-string-pad-end.js
+++ b/test/mjsunit/harmony/harmony-string-pad-end.js
@@ -67,8 +67,19 @@
(function TestFillerToString() {
assertEquals(". ", ".".padEnd(10));
assertEquals(". ", ".".padEnd(10, undefined));
- assertEquals(". ", ".".padEnd(10, { toString() { return ""; } }));
assertEquals(".nullnulln", ".".padEnd(10, null));
+ assertEquals(".XXXXXXXXX", ".".padEnd(10, { toString() { return "X"; } }));
+ assertEquals(
+ ".111111111",
+ ".".padEnd(10, { toString: undefined, valueOf() { return 1; } }));
+})();
+
+
+(function TestFillerEmptyString() {
+ assertEquals(".", ".".padEnd(10, ""));
+ assertEquals(".", ".".padEnd(10, { toString() { return ""; } }));
+ assertEquals(
+ ".", ".".padEnd(10, { toString: undefined, valueOf() { return ""; } }));
})();
diff --git a/test/mjsunit/harmony/harmony-string-pad-start.js b/test/mjsunit/harmony/harmony-string-pad-start.js
index 2b2d004..33bf8f3 100644
--- a/test/mjsunit/harmony/harmony-string-pad-start.js
+++ b/test/mjsunit/harmony/harmony-string-pad-start.js
@@ -67,8 +67,19 @@
(function TestFillerToString() {
assertEquals(" .", ".".padStart(10));
assertEquals(" .", ".".padStart(10, undefined));
- assertEquals(" .", ".".padStart(10, { toString() { return ""; } }));
assertEquals("nullnulln.", ".".padStart(10, null));
+ assertEquals("XXXXXXXXX.", ".".padStart(10, { toString() { return "X"; } }));
+ assertEquals(
+ "111111111.",
+ ".".padStart(10, { toString: undefined, valueOf() { return 1; } }));
+})();
+
+
+(function TestFillerEmptyString() {
+ assertEquals(".", ".".padStart(10, ""));
+ assertEquals(".", ".".padStart(10, { toString() { return ""; } }));
+ assertEquals(
+ ".", ".".padStart(10, { toString: undefined, valueOf() { return ""; } }));
})();
diff --git a/test/mjsunit/harmony/instanceof-es6.js b/test/mjsunit/harmony/instanceof-es6.js
index 60e7ee2..4971c9c 100644
--- a/test/mjsunit/harmony/instanceof-es6.js
+++ b/test/mjsunit/harmony/instanceof-es6.js
@@ -48,3 +48,22 @@
// 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
index 09e0153..03cdeac 100644
--- a/test/mjsunit/harmony/iterator-close.js
+++ b/test/mjsunit/harmony/iterator-close.js
@@ -1007,6 +1007,26 @@
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);
}
@@ -1051,6 +1071,26 @@
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);
}
@@ -1095,6 +1135,26 @@
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);
}
@@ -1238,3 +1298,75 @@
}, 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/regexp-property-binary.js b/test/mjsunit/harmony/regexp-property-binary.js
new file mode 100644
index 0000000..d0894b7
--- /dev/null
+++ b/test/mjsunit/harmony/regexp-property-binary.js
@@ -0,0 +1,25 @@
+// 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 --harmony-unicode-regexps
+
+function t(re, s) { assertTrue(re.test(s)); }
+function f(re, s) { assertFalse(re.test(s)); }
+
+t(/\p{Bidi_Control}+/u, "\u200E");
+f(/\p{Bidi_C}+/u, "On a dark desert highway, cool wind in my hair");
+t(/\p{AHex}+/u, "DEADBEEF");
+t(/\p{Alphabetic}+/u, "abcdefg");
+t(/\P{Alphabetic}+/u, "1234");
+t(/\p{White_Space}+/u, "\u00A0");
+t(/\p{Uppercase}+/u, "V");
+f(/\p{Lower}+/u, "U");
+t(/\p{Ideo}+/u, "字");
+f(/\p{Ideo}+/u, "x");
+
+assertThrows("/\\p{Hiragana}/u");
+assertThrows("/\\p{Bidi_Class}/u");
+assertThrows("/\\p{Bidi_C=False}/u");
+assertThrows("/\\P{Bidi_Control=Y}/u");
+assertThrows("/\\p{AHex=Yes}/u");
diff --git a/test/mjsunit/harmony/regexp-property-blocks.js b/test/mjsunit/harmony/regexp-property-blocks.js
index d186e98..f41c06e 100644
--- a/test/mjsunit/harmony/regexp-property-blocks.js
+++ b/test/mjsunit/harmony/regexp-property-blocks.js
@@ -7,28 +7,28 @@
function t(re, s) { assertTrue(re.test(s)); }
function f(re, s) { assertFalse(re.test(s)); }
-t(/\p{InASCII}+/u, ".");
-t(/\p{InASCII}+/u, "supercalifragilisticexpialidocious");
-t(/\p{InBasic_Latin}+/u, ".");
-t(/\p{InBasic_Latin}+/u, "supercalifragilisticexpialidocious");
+t(/\p{Block=ASCII}+/u, ".");
+t(/\p{Block=ASCII}+/u, "supercalifragilisticexpialidocious");
+t(/\p{Block=Basic_Latin}+/u, ".");
+t(/\p{Block=Basic_Latin}+/u, "supercalifragilisticexpialidocious");
-t(/\p{InCJK}+/u, "话说天下大势,分久必合,合久必分");
-t(/\p{InCJK_Unified_Ideographs}+/u, "吾庄后有一桃园,花开正盛");
-f(/\p{InCJK}+/u, "おはようございます");
-f(/\p{InCJK_Unified_Ideographs}+/u,
+t(/\p{blk=CJK}+/u, "话说天下大势,分久必合,合久必分");
+t(/\p{blk=CJK_Unified_Ideographs}+/u, "吾庄后有一桃园,花开正盛");
+f(/\p{blk=CJK}+/u, "おはようございます");
+f(/\p{blk=CJK_Unified_Ideographs}+/u,
"Something is rotten in the state of Denmark");
-t(/\p{InLatin_1}+/u, "Wie froh bin ich, daß ich weg bin!");
-f(/\p{InLatin_1_Supplement}+/u, "奔腾千里荡尘埃,渡水登山紫雾开");
-f(/\p{InLatin_1_Sup}+/u, "いただきます");
+t(/\p{blk=Latin_1}+/u, "Wie froh bin ich, daß ich weg bin!");
+f(/\p{blk=Latin_1_Supplement}+/u, "奔腾千里荡尘埃,渡水登山紫雾开");
+f(/\p{blk=Latin_1_Sup}+/u, "いただきます");
-t(/\p{InHiragana}/u, "いただきます");
-t(/\p{Hiragana}/u, "\u{1b001}"); // This refers to the script "Hiragana".
-f(/\p{InHiragana}/u, "\u{1b001}"); // This refers to the block "Hiragana".
+t(/\p{blk=Hiragana}/u, "いただきます");
+t(/\p{sc=Hiragana}/u, "\u{1b001}"); // This refers to the script "Hiragana".
+f(/\p{blk=Hiragana}/u, "\u{1b001}"); // This refers to the block "Hiragana".
-t(/\p{InGreek_And_Coptic}/u,
+t(/\p{blk=Greek_And_Coptic}/u,
"ἄνδρα μοι ἔννεπε, μοῦσα, πολύτροπον, ὃς μάλα πολλὰ");
-t(/\p{InGreek}/u, "μῆνιν ἄειδε θεὰ Πηληϊάδεω Ἀχιλῆος");
+t(/\p{blk=Greek}/u, "μῆνιν ἄειδε θεὰ Πηληϊάδεω Ἀχιλῆος");
assertThrows("/\\p{In}/u");
assertThrows("/\\pI/u");
diff --git a/test/mjsunit/harmony/regexp-property-char-class.js b/test/mjsunit/harmony/regexp-property-char-class.js
index 76774cb..6162012 100644
--- a/test/mjsunit/harmony/regexp-property-char-class.js
+++ b/test/mjsunit/harmony/regexp-property-char-class.js
@@ -9,9 +9,6 @@
assertThrows("/[\\p{}]/u");
assertThrows("/[\\p{]/u");
assertThrows("/[\\p}]/u");
-assertThrows("/[\\p{Math}]/u");
-assertThrows("/[\\p{Bidi_M}]/u");
-assertThrows("/[\\p{Hex}]/u");
assertTrue(/^[\p{Lu}\p{Ll}]+$/u.test("ABCabc"));
assertTrue(/^[\p{Lu}-\p{Ll}]+$/u.test("ABC-abc"));
@@ -19,6 +16,9 @@
assertTrue(/^[\P{Lu}\p{Ll}]+$/u.test("abc"));
assertTrue(/^[\P{Lu}]+$/u.test("abc123"));
assertFalse(/^[\P{Lu}]+$/u.test("XYZ"));
+assertTrue(/[\p{Math}]/u.test("+"));
+assertTrue(/[\P{Bidi_M}]/u.test(" "));
+assertTrue(/[\p{Hex}]/u.test("A"));
assertTrue(/^[^\P{Lu}]+$/u.test("XYZ"));
assertFalse(/^[^\p{Lu}\p{Ll}]+$/u.test("abc"));
diff --git a/test/mjsunit/harmony/regexp-property-enumerated.js b/test/mjsunit/harmony/regexp-property-enumerated.js
new file mode 100644
index 0000000..e4a81a4
--- /dev/null
+++ b/test/mjsunit/harmony/regexp-property-enumerated.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-regexp-property --harmony-unicode-regexps
+
+function t(re, s) { assertTrue(re.test(s)); }
+function f(re, s) { assertFalse(re.test(s)); }
+
+t(/\p{Bidi_Class=L}+/u, "Is this the real life?");
+t(/\p{bc=Left_To_Right}+/u, "Is this just fantasy?");
+t(/\p{bc=AL}+/u, "السلام عليكم");
+t(/\p{bc=Arabic_Letter}+/u, "متشرف بمعرفتك");
+
+t(/\p{Line_Break=Glue}/u, "\u00A0");
+t(/\p{lb=AL}/u, "~");
+
+assertThrows("/\\p{Block=}/u");
+assertThrows("/\\p{=}/u");
+assertThrows("/\\p{=L}/u");
+assertThrows("/\\p{=Hiragana}/u");
+assertThrows("/\\p{Block=CJK=}/u");
+
+assertThrows("/\\p{Age=V8_0}/u");
+assertThrows("/\\p{General_Category=Letter}/u");
+assertThrows("/\\p{gc=L}/u");
+assertThrows("/\\p{General_Category_Mask=Letter}/u");
+assertThrows("/\\p{gcm=L}/u");
diff --git a/test/mjsunit/harmony/regexp-property-exact-match.js b/test/mjsunit/harmony/regexp-property-exact-match.js
index 4dfcc5f..fe233f2 100644
--- a/test/mjsunit/harmony/regexp-property-exact-match.js
+++ b/test/mjsunit/harmony/regexp-property-exact-match.js
@@ -6,12 +6,12 @@
assertThrows("/\\p{In CJK}/u");
assertThrows("/\\p{InCJKUnifiedIdeographs}/u");
-assertDoesNotThrow("/\\p{InCJK}/u");
-assertDoesNotThrow("/\\p{InCJK_Unified_Ideographs}/u");
+assertThrows("/\\p{InCJK}/u");
+assertThrows("/\\p{InCJK_Unified_Ideographs}/u");
-assertDoesNotThrow("/\\p{InCyrillic_Sup}/u");
-assertDoesNotThrow("/\\p{InCyrillic_Supplement}/u");
-assertDoesNotThrow("/\\p{InCyrillic_Supplementary}/u");
+assertThrows("/\\p{InCyrillic_Sup}/u");
+assertThrows("/\\p{InCyrillic_Supplement}/u");
+assertThrows("/\\p{InCyrillic_Supplementary}/u");
assertThrows("/\\p{InCyrillicSupplementary}/u");
assertThrows("/\\p{InCyrillic_supplementary}/u");
@@ -25,9 +25,18 @@
assertDoesNotThrow("/\\p{Combining_Mark}/u");
assertThrows("/\\p{Combining Mark}/u");
-assertDoesNotThrow("/\\p{Copt}/u");
-assertDoesNotThrow("/\\p{Coptic}/u");
-assertDoesNotThrow("/\\p{Qaac}/u");
-assertDoesNotThrow("/\\p{Egyp}/u");
-assertDoesNotThrow("/\\p{Egyptian_Hieroglyphs}/u");
+assertDoesNotThrow("/\\p{Script=Copt}/u");
+assertThrows("/\\p{Coptic}/u");
+assertThrows("/\\p{Qaac}/u");
+assertThrows("/\\p{Egyp}/u");
+assertDoesNotThrow("/\\p{Script=Egyptian_Hieroglyphs}/u");
assertThrows("/\\p{EgyptianHieroglyphs}/u");
+
+assertThrows("/\\p{BidiClass=LeftToRight}/u");
+assertThrows("/\\p{BidiC=LeftToRight}/u");
+assertThrows("/\\p{bidi_c=Left_To_Right}/u");
+
+assertDoesNotThrow("/\\p{Block=CJK}/u");
+assertThrows("/\\p{Block = CJK}/u");
+assertThrows("/\\p{Block=cjk}/u");
+assertThrows("/\\p{BLK=CJK}/u");
diff --git a/test/mjsunit/harmony/regexp-property-scripts.js b/test/mjsunit/harmony/regexp-property-scripts.js
index 19b50ee..ec2b11d 100644
--- a/test/mjsunit/harmony/regexp-property-scripts.js
+++ b/test/mjsunit/harmony/regexp-property-scripts.js
@@ -7,33 +7,33 @@
function t(re, s) { assertTrue(re.test(s)); }
function f(re, s) { assertFalse(re.test(s)); }
-t(/\p{Common}+/u, ".");
-f(/\p{Common}+/u, "supercalifragilisticexpialidocious");
+t(/\p{Script=Common}+/u, ".");
+f(/\p{Script=Common}+/u, "supercalifragilisticexpialidocious");
-t(/\p{Han}+/u, "话说天下大势,分久必合,合久必分");
-t(/\p{Hani}+/u, "吾庄后有一桃园,花开正盛");
-f(/\p{Han}+/u, "おはようございます");
-f(/\p{Hani}+/u, "Something is rotten in the state of Denmark");
+t(/\p{Script=Han}+/u, "话说天下大势,分久必合,合久必分");
+t(/\p{Script=Hani}+/u, "吾庄后有一桃园,花开正盛");
+f(/\p{Script=Han}+/u, "おはようございます");
+f(/\p{Script=Hani}+/u, "Something is rotten in the state of Denmark");
-t(/\p{Latin}+/u, "Wie froh bin ich, daß ich weg bin!");
-t(/\p{Latn}+/u,
+t(/\p{Script=Latin}+/u, "Wie froh bin ich, daß ich weg bin!");
+t(/\p{Script=Latn}+/u,
"It was a bright day in April, and the clocks were striking thirteen");
-f(/\p{Latin}+/u, "奔腾千里荡尘埃,渡水登山紫雾开");
-f(/\p{Latn}+/u, "いただきます");
+f(/\p{Script=Latin}+/u, "奔腾千里荡尘埃,渡水登山紫雾开");
+f(/\p{Script=Latn}+/u, "いただきます");
-t(/\p{Hiragana}/u, "いただきます");
-t(/\p{Hira}/u, "ありがとうございました");
-f(/\p{Hiragana}/u,
+t(/\p{sc=Hiragana}/u, "いただきます");
+t(/\p{sc=Hira}/u, "ありがとうございました");
+f(/\p{sc=Hiragana}/u,
"Als Gregor Samsa eines Morgens aus unruhigen Träumen erwachte");
-f(/\p{Hira}/u, "Call me Ishmael");
+f(/\p{sc=Hira}/u, "Call me Ishmael");
-t(/\p{Phoenician}/u, "\u{10900}\u{1091a}");
-t(/\p{Phnx}/u, "\u{1091f}\u{10916}");
-f(/\p{Phoenician}/u, "Arthur est un perroquet");
-f(/\p{Phnx}/u, "设心狠毒非良士,操卓原来一路人");
+t(/\p{sc=Phoenician}/u, "\u{10900}\u{1091a}");
+t(/\p{sc=Phnx}/u, "\u{1091f}\u{10916}");
+f(/\p{sc=Phoenician}/u, "Arthur est un perroquet");
+f(/\p{sc=Phnx}/u, "设心狠毒非良士,操卓原来一路人");
-t(/\p{Grek}/u, "ἄνδρα μοι ἔννεπε, μοῦσα, πολύτροπον, ὃς μάλα πολλὰ");
-t(/\p{Greek}/u, "μῆνιν ἄειδε θεὰ Πηληϊάδεω Ἀχιλῆος");
-f(/\p{Greek}/u, "高贤未服英雄志,屈节偏生杰士疑");
-f(/\p{Greek}/u,
+t(/\p{sc=Grek}/u, "ἄνδρα μοι ἔννεπε, μοῦσα, πολύτροπον, ὃς μάλα πολλὰ");
+t(/\p{sc=Greek}/u, "μῆνιν ἄειδε θεὰ Πηληϊάδεω Ἀχιλῆος");
+f(/\p{sc=Greek}/u, "高贤未服英雄志,屈节偏生杰士疑");
+f(/\p{sc=Greek}/u,
"Mr. Jones, of the Manor Farm, had locked the hen-houses for the night");
diff --git a/test/mjsunit/harmony/regress/regress-4482.js b/test/mjsunit/harmony/regress/regress-4482.js
deleted file mode 100644
index 2472b46..0000000
--- a/test/mjsunit/harmony/regress/regress-4482.js
+++ /dev/null
@@ -1,9 +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-sloppy
-
-assertEquals("function", (function f() { f = 42; return typeof f })());
-assertEquals("function",
- (function* g() { g = 42; yield typeof g })().next().value);
diff --git a/test/mjsunit/harmony/regress/regress-4904.js b/test/mjsunit/harmony/regress/regress-4904.js
new file mode 100644
index 0000000..a57d246
--- /dev/null
+++ b/test/mjsunit/harmony/regress/regress-4904.js
@@ -0,0 +1,24 @@
+// 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-do-expressions
+
+(function testCatchScopeInDoExpression() {
+ var f = (s = 17, y = do { try { throw 25; } catch(e) { s += e; }; }) => s;
+ var result = f();
+ assertEquals(result, 42);
+})();
+
+(function testCatchScopeInDoExpression() {
+ var f = (s = 17, y = do { let t; try { throw 25; } catch(e) { s += e; }; }) => s;
+ var result = f();
+ assertEquals(result, 42);
+})();
+
+(function testCatchScopeInDoExpression() {
+ let t1;
+ var f = (s = 17, y = do { let t2; try { throw 25; } catch(e) { s += e; }; }) => s;
+ var result = f();
+ assertEquals(result, 42);
+})();
diff --git a/test/mjsunit/harmony/regress/regress-observe-empty-double-array.js b/test/mjsunit/harmony/regress/regress-observe-empty-double-array.js
deleted file mode 100644
index 1460889..0000000
--- a/test/mjsunit/harmony/regress/regress-observe-empty-double-array.js
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Flags: --harmony-object-observe
-// Flags: --allow-natives-syntax
-//
-// Test passes if it does not crash.
-
-arr = [1.1];
-Object.observe(arr, function(){});
-arr.length = 0;
-// TODO(observe): we currently disallow fast elements for observed object.
-// assertTrue(%HasFastDoubleElements(arr));
-// Should not crash
-arr.push(1.1);