summaryrefslogtreecommitdiff
path: root/deps/v8/test/mjsunit
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/test/mjsunit')
-rw-r--r--deps/v8/test/mjsunit/array-iteration.js95
-rw-r--r--deps/v8/test/mjsunit/array-reduce.js684
-rw-r--r--deps/v8/test/mjsunit/code-coverage-block-noopt.js2
-rw-r--r--deps/v8/test/mjsunit/code-coverage-block-opt.js4
-rw-r--r--deps/v8/test/mjsunit/code-coverage-block.js25
-rw-r--r--deps/v8/test/mjsunit/compiler/array-multiple-receiver-maps.js122
-rw-r--r--deps/v8/test/mjsunit/compiler/deopt-array-builtins.js148
-rw-r--r--deps/v8/test/mjsunit/compiler/deopt-array-push.js97
-rw-r--r--deps/v8/test/mjsunit/compiler/escape-analysis-13.js2
-rw-r--r--deps/v8/test/mjsunit/compiler/escape-analysis-15.js2
-rw-r--r--deps/v8/test/mjsunit/compiler/escape-analysis-phi-type.js2
-rw-r--r--deps/v8/test/mjsunit/compiler/materialize-dictionary-properties.js18
-rw-r--r--deps/v8/test/mjsunit/compiler/materialize-mutable-heap-number.js22
-rw-r--r--deps/v8/test/mjsunit/compiler/new-cons-string.js71
-rw-r--r--deps/v8/test/mjsunit/compiler/regress-786521.js23
-rw-r--r--deps/v8/test/mjsunit/compiler/regress-793863.js12
-rw-r--r--deps/v8/test/mjsunit/compiler/regress-796041.js35
-rw-r--r--deps/v8/test/mjsunit/compiler/regress-797596.js30
-rw-r--r--deps/v8/test/mjsunit/compiler/regress-801097.js19
-rw-r--r--deps/v8/test/mjsunit/compiler/varargs.js49
-rw-r--r--deps/v8/test/mjsunit/constant-folding-2.js4
-rw-r--r--deps/v8/test/mjsunit/d8/.gitignore1
-rw-r--r--deps/v8/test/mjsunit/d8/d8-os.js (renamed from deps/v8/test/mjsunit/d8-os.js)0
-rw-r--r--deps/v8/test/mjsunit/d8/d8-performance-now.js (renamed from deps/v8/test/mjsunit/d8-performance-now.js)0
-rw-r--r--deps/v8/test/mjsunit/d8/d8-worker-sharedarraybuffer.js (renamed from deps/v8/test/mjsunit/d8-worker-sharedarraybuffer.js)0
-rw-r--r--deps/v8/test/mjsunit/d8/d8-worker-spawn-worker.js (renamed from deps/v8/test/mjsunit/d8-worker-spawn-worker.js)0
-rw-r--r--deps/v8/test/mjsunit/d8/d8-worker.js (renamed from deps/v8/test/mjsunit/d8-worker.js)0
-rw-r--r--deps/v8/test/mjsunit/d8/enable-tracing.js8
-rw-r--r--deps/v8/test/mjsunit/deserialize-reference.js2
-rw-r--r--deps/v8/test/mjsunit/dictionary-prototypes.js409
-rw-r--r--deps/v8/test/mjsunit/es6/array-find.js34
-rw-r--r--deps/v8/test/mjsunit/es6/array-findindex.js34
-rw-r--r--deps/v8/test/mjsunit/es6/array-iterator-turbo.js2
-rw-r--r--deps/v8/test/mjsunit/es6/call-with-spread-modify-next.js4
-rw-r--r--deps/v8/test/mjsunit/es6/computed-property-names-object-literals-methods.js2
-rw-r--r--deps/v8/test/mjsunit/es6/destructuring-assignment.js44
-rw-r--r--deps/v8/test/mjsunit/es6/iteration-semantics.js8
-rw-r--r--deps/v8/test/mjsunit/es6/reflect-construct.js2
-rw-r--r--deps/v8/test/mjsunit/es6/spread-call.js18
-rw-r--r--deps/v8/test/mjsunit/es6/super-with-spread-modify-next.js4
-rw-r--r--deps/v8/test/mjsunit/es6/typedarray.js24
-rw-r--r--deps/v8/test/mjsunit/es8/object-entries.js33
-rw-r--r--deps/v8/test/mjsunit/es8/regress/regress-794744.js8
-rw-r--r--deps/v8/test/mjsunit/global-prototypes.js354
-rw-r--r--deps/v8/test/mjsunit/harmony/async-for-of-non-iterable.js1
-rw-r--r--deps/v8/test/mjsunit/harmony/async-from-sync-iterator.js2
-rw-r--r--deps/v8/test/mjsunit/harmony/async-generators-basic.js2
-rw-r--r--deps/v8/test/mjsunit/harmony/async-generators-resume-return.js2
-rw-r--r--deps/v8/test/mjsunit/harmony/async-generators-return.js2
-rw-r--r--deps/v8/test/mjsunit/harmony/async-generators-yield.js2
-rw-r--r--deps/v8/test/mjsunit/harmony/bigint/as-int-n.js18
-rw-r--r--deps/v8/test/mjsunit/harmony/bigint/basics.js10
-rw-r--r--deps/v8/test/mjsunit/harmony/bigint/comparisons.js2
-rw-r--r--deps/v8/test/mjsunit/harmony/bigint/dec.js3
-rw-r--r--deps/v8/test/mjsunit/harmony/bigint/exp.js43
-rw-r--r--deps/v8/test/mjsunit/harmony/bigint/inc.js3
-rw-r--r--deps/v8/test/mjsunit/harmony/bigint/json.js2
-rw-r--r--deps/v8/test/mjsunit/harmony/bigint/neg.js3
-rw-r--r--deps/v8/test/mjsunit/harmony/bigint/not.js3
-rw-r--r--deps/v8/test/mjsunit/harmony/bigint/regressions.js4
-rw-r--r--deps/v8/test/mjsunit/harmony/bigint/tonumber.js2
-rw-r--r--deps/v8/test/mjsunit/harmony/bigint/too-big-literal.js14
-rw-r--r--deps/v8/test/mjsunit/harmony/bigint/turbo.js193
-rw-r--r--deps/v8/test/mjsunit/harmony/for-await-of.js2
-rw-r--r--deps/v8/test/mjsunit/harmony/modules-import-15.js3
-rw-r--r--deps/v8/test/mjsunit/harmony/optional-catch-binding-breaks.js65
-rw-r--r--deps/v8/test/mjsunit/harmony/optional-catch-binding.js39
-rw-r--r--deps/v8/test/mjsunit/harmony/promise-prototype-finally.js10
-rw-r--r--deps/v8/test/mjsunit/harmony/public-instance-class-fields.js82
-rw-r--r--deps/v8/test/mjsunit/harmony/public-static-class-fields.js130
-rw-r--r--deps/v8/test/mjsunit/harmony/regexp-named-captures.js123
-rw-r--r--deps/v8/test/mjsunit/harmony/regress/regress-6322.js2
-rw-r--r--deps/v8/test/mjsunit/harmony/regress/regress-772649.js2
-rw-r--r--deps/v8/test/mjsunit/harmony/sharedarraybuffer.js3
-rw-r--r--deps/v8/test/mjsunit/harmony/symbol-async-iterator.js2
-rw-r--r--deps/v8/test/mjsunit/ic-lookup-on-receiver.js44
-rw-r--r--deps/v8/test/mjsunit/mjsunit.status59
-rw-r--r--deps/v8/test/mjsunit/optimized-array-every.js520
-rw-r--r--deps/v8/test/mjsunit/optimized-array-find.js460
-rw-r--r--deps/v8/test/mjsunit/optimized-array-findindex.js460
-rw-r--r--deps/v8/test/mjsunit/optimized-array-some.js502
-rw-r--r--deps/v8/test/mjsunit/optimized-filter.js53
-rw-r--r--deps/v8/test/mjsunit/optimized-foreach.js50
-rw-r--r--deps/v8/test/mjsunit/optimized-map.js53
-rw-r--r--deps/v8/test/mjsunit/regress/modules-skip-regress-797581-1.js5
-rw-r--r--deps/v8/test/mjsunit/regress/modules-skip-regress-797581-2.js5
-rw-r--r--deps/v8/test/mjsunit/regress/modules-skip-regress-797581-3.js5
-rw-r--r--deps/v8/test/mjsunit/regress/modules-skip-regress-797581-4.js5
-rw-r--r--deps/v8/test/mjsunit/regress/modules-skip-regress-797581-5.js6
-rw-r--r--deps/v8/test/mjsunit/regress/regress-2646.js2
-rw-r--r--deps/v8/test/mjsunit/regress/regress-370827.js2
-rw-r--r--deps/v8/test/mjsunit/regress/regress-599717.js2
-rw-r--r--deps/v8/test/mjsunit/regress/regress-791334.js8
-rw-r--r--deps/v8/test/mjsunit/regress/regress-791958.js15
-rw-r--r--deps/v8/test/mjsunit/regress/regress-793588.js13
-rw-r--r--deps/v8/test/mjsunit/regress/regress-796427.js7
-rw-r--r--deps/v8/test/mjsunit/regress/regress-797481.js10
-rw-r--r--deps/v8/test/mjsunit/regress/regress-797581.js29
-rw-r--r--deps/v8/test/mjsunit/regress/regress-800538.js6
-rw-r--r--deps/v8/test/mjsunit/regress/regress-801171.js20
-rw-r--r--deps/v8/test/mjsunit/regress/regress-801772.js9
-rw-r--r--deps/v8/test/mjsunit/regress/regress-802060.js24
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-789764.js15
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-791245-1.js18
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-791245-2.js18
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-795922.js9
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-798644.js21
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-800077.js6
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-800810.js13
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-807096.js27
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-808192.js32
-rw-r--r--deps/v8/test/mjsunit/regress/regress-crbug-813427.js49
-rw-r--r--deps/v8/test/mjsunit/regress/regress-v8-7245.js6
-rw-r--r--deps/v8/test/mjsunit/regress/wasm/regress-791810.js21
-rw-r--r--deps/v8/test/mjsunit/regress/wasm/regress-793551.js20
-rw-r--r--deps/v8/test/mjsunit/regress/wasm/regress-797846.js14
-rw-r--r--deps/v8/test/mjsunit/regress/wasm/regress-800756.js15
-rw-r--r--deps/v8/test/mjsunit/regress/wasm/regress-801850.js11
-rw-r--r--deps/v8/test/mjsunit/regress/wasm/regress-802244.js22
-rw-r--r--deps/v8/test/mjsunit/regress/wasm/regress-808980.js28
-rw-r--r--deps/v8/test/mjsunit/serialize-after-execute.js15
-rw-r--r--deps/v8/test/mjsunit/serialize-embedded-error.js2
-rw-r--r--deps/v8/test/mjsunit/serialize-ic.js2
-rw-r--r--deps/v8/test/mjsunit/testcfg.py75
-rw-r--r--deps/v8/test/mjsunit/wasm/errors.js18
-rw-r--r--deps/v8/test/mjsunit/wasm/grow-memory-detaching.js65
-rw-r--r--deps/v8/test/mjsunit/wasm/indirect-tables.js101
-rw-r--r--deps/v8/test/mjsunit/wasm/lazy-compilation.js39
-rw-r--r--deps/v8/test/mjsunit/wasm/many-parameters.js9
-rw-r--r--deps/v8/test/mjsunit/wasm/module-memory.js23
-rw-r--r--deps/v8/test/mjsunit/wasm/shared-memory.js39
-rw-r--r--deps/v8/test/mjsunit/wasm/trap-location.js2
-rw-r--r--deps/v8/test/mjsunit/wasm/wasm-module-builder.js25
133 files changed, 6102 insertions, 263 deletions
diff --git a/deps/v8/test/mjsunit/array-iteration.js b/deps/v8/test/mjsunit/array-iteration.js
index 9d03ed13ce..4de58208b4 100644
--- a/deps/v8/test/mjsunit/array-iteration.js
+++ b/deps/v8/test/mjsunit/array-iteration.js
@@ -73,6 +73,31 @@
assertEquals(3, count);
for (var i in a) assertEquals(2, a[i]);
+ // Skip over missing properties.
+ a = {
+ "0": 0,
+ "2": 2,
+ length: 3
+ };
+ var received = [];
+ assertArrayEquals([2],
+ Array.prototype.filter.call(a, function(n) {
+ received.push(n);
+ return n == 2;
+ }));
+ assertArrayEquals([0, 2], received);
+
+ // Modify array prototype
+ a = [0, , 2];
+ received = [];
+ assertArrayEquals([2],
+ Array.prototype.filter.call(a, function(n) {
+ a.__proto__ = null;
+ received.push(n);
+ return n == 2;
+ }));
+ assertArrayEquals([0, 2], received);
+
// Create a new object in each function call when receiver is a
// primitive value. See ECMA-262, Annex C.
a = [];
@@ -131,6 +156,26 @@
a.forEach(function(n) { count++; });
assertEquals(1, count);
+ // Skip over missing properties.
+ a = {
+ "0": 0,
+ "2": 2,
+ length: 3
+ };
+ var received = [];
+ Array.prototype.forEach.call(a, function(n) { received.push(n); });
+ assertArrayEquals([0, 2], received);
+
+ // Modify array prototype
+ a = [0, , 2];
+ received = [];
+ Array.prototype.forEach.call(a, function(n) {
+ a.__proto__ = null;
+ received.push(n);
+ return n == 2;
+ });
+ assertArrayEquals([0, 2], received);
+
// Create a new object in each function call when receiver is a
// primitive value. See ECMA-262, Annex C.
a = [];
@@ -194,6 +239,31 @@
assertTrue(a.every(function(n) { count++; return n == 2; }));
assertEquals(2, count);
+ // Skip over missing properties.
+ a = {
+ "0": 2,
+ "2": 2,
+ length: 3
+ };
+ var received = [];
+ assertTrue(
+ Array.prototype.every.call(a, function(n) {
+ received.push(n);
+ return n == 2;
+ }));
+ assertArrayEquals([2, 2], received);
+
+ // Modify array prototype
+ a = [2, , 2];
+ received = [];
+ assertTrue(
+ Array.prototype.every.call(a, function(n) {
+ a.__proto__ = null;
+ received.push(n);
+ return n == 2;
+ }));
+ assertArrayEquals([2, 2], received);
+
// Create a new object in each function call when receiver is a
// primitive value. See ECMA-262, Annex C.
a = [];
@@ -252,6 +322,31 @@
a = a.map(function(n) { return 2*n; });
for (var i in a) assertEquals(4, a[i]);
+ // Skip over missing properties.
+ a = {
+ "0": 1,
+ "2": 2,
+ length: 3
+ };
+ var received = [];
+ assertArrayEquals([2, , 4],
+ Array.prototype.map.call(a, function(n) {
+ received.push(n);
+ return n * 2;
+ }));
+ assertArrayEquals([1, 2], received);
+
+ // Modify array prototype
+ a = [1, , 2];
+ received = [];
+ assertArrayEquals([2, , 4],
+ Array.prototype.map.call(a, function(n) {
+ a.__proto__ = null;
+ received.push(n);
+ return n * 2;
+ }));
+ assertArrayEquals([1, 2], received);
+
// Create a new object in each function call when receiver is a
// primitive value. See ECMA-262, Annex C.
a = [];
diff --git a/deps/v8/test/mjsunit/array-reduce.js b/deps/v8/test/mjsunit/array-reduce.js
index 4a4494a72c..171a40f092 100644
--- a/deps/v8/test/mjsunit/array-reduce.js
+++ b/deps/v8/test/mjsunit/array-reduce.js
@@ -25,6 +25,8 @@
// (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
+
/**
* @fileoverview Test reduce and reduceRight
*/
@@ -557,3 +559,685 @@ assertEquals(undefined, arr.reduceRight(function(val) { return val }));
}, 'initial')
}, 'do not continue');
})();
+
+(function OptimizedReduce() {
+ let f = (a,current) => a + current;
+ let g = function(a) {
+ return a.reduce(f);
+ }
+ let a = [1,2,3,4,5,6,7,8,9,10];
+ g(a); g(a);
+ let total = g(a);
+ %OptimizeFunctionOnNextCall(g);
+ assertEquals(total, g(a));
+})();
+
+(function OptimizedReduceEmpty() {
+ let f = (a,current) => a + current;
+ let g = function(a) {
+ return a.reduce(f);
+ }
+ let a = [1,2,3,4,5,6,7,8,9,10];
+ g(a); g(a); g(a);
+ %OptimizeFunctionOnNextCall(g);
+ g(a);
+ assertThrows(() => g([]));
+})();
+
+(function OptimizedReduceLazyDeopt() {
+ let deopt = false;
+ let f = (a,current) => { if (deopt) %DeoptimizeNow(); return a + current; };
+ let g = function(a) {
+ return a.reduce(f);
+ }
+ let a = [1,2,3,4,5,6,7,8,9,10];
+ g(a); g(a);
+ let total = g(a);
+ %OptimizeFunctionOnNextCall(g);
+ g(a);
+ deopt = true;
+ assertEquals(total, g(a));
+})();
+
+(function OptimizedReduceLazyDeoptMiddleOfIteration() {
+ let deopt = false;
+ let f = (a,current) => {
+ if (current == 6 && deopt) %DeoptimizeNow();
+ return a + current;
+ };
+ let g = function(a) {
+ return a.reduce(f);
+ }
+ let a = [11,22,33,45,56,6,77,84,93,101];
+ g(a); g(a);
+ let total = g(a);
+ %OptimizeFunctionOnNextCall(g);
+ g(a);
+ deopt = true;
+ assertEquals(total, g(a));
+})();
+
+(function OptimizedReduceEagerDeoptMiddleOfIteration() {
+ let deopt = false;
+ let array = [11,22,33,45,56,6,77,84,93,101];
+ let f = (a,current) => {
+ if (current == 6 && deopt) {array[0] = 1.5; }
+ return a + current;
+ };
+ let g = function() {
+ return array.reduce(f);
+ }
+ g(); g();
+ let total = g();
+ %OptimizeFunctionOnNextCall(g);
+ g();
+ deopt = true;
+ g();
+ deopt = false;
+ array = [11,22,33,45,56,6,77,84,93,101];
+ %OptimizeFunctionOnNextCall(g);
+ g();
+ deopt = true;
+ assertEquals(total, g());
+})();
+
+(function ReduceCatch() {
+ let f = (a,current) => {
+ return a + current;
+ };
+ let g = function() {
+ try {
+ return array.reduce(f);
+ } catch (e) {
+ }
+ }
+ g(); g();
+ let total = g();
+ %OptimizeFunctionOnNextCall(g);
+ g();
+ g();
+ assertEquals(total, g());
+})();
+
+(function ReduceThrow() {
+ let done = false;
+ let f = (a, current) => {
+ if (done) throw "x";
+ return a + current;
+ };
+ let array = [1,2,3];
+ let g = function() {
+ try {
+ return array.reduce(f);
+ } catch (e) {
+ return null;
+ }
+ }
+ g(); g();
+ let total = g();
+ %OptimizeFunctionOnNextCall(g);
+ g();
+ assertEquals(6, g());
+ done = true;
+ assertEquals(null, g());
+ done = false;
+ g(); g();
+ %OptimizeFunctionOnNextCall(g);
+ g();
+ assertEquals(6, g());
+ done = true;
+ assertEquals(null, g());
+})();
+
+(function ReduceThrow() {
+ let done = false;
+ let f = (a, current) => {
+ if (done) throw "x";
+ return a + current;
+ };
+ %NeverOptimizeFunction(f);
+ let array = [1,2,3];
+ let g = function() {
+ try {
+ return array.reduce(f);
+ } catch (e) {
+ return null;
+ }
+ }
+ g(); g();
+ let total = g();
+ %OptimizeFunctionOnNextCall(g);
+ g();
+ assertEquals(6, g());
+ done = true;
+ assertEquals(null, g());
+ done = false;
+ g(); g();
+ %OptimizeFunctionOnNextCall(g);
+ g();
+ assertEquals(6, g());
+ done = true;
+ assertEquals(null, g());
+})();
+
+(function ReduceFinally() {
+ let done = false;
+ let f = (a, current) => {
+ if (done) throw "x";
+ return a + current;
+ };
+ let array = [1,2,3];
+ let g = function() {
+ try {
+ return array.reduce(f);
+ } catch (e) {
+ } finally {
+ if (done) return null;
+ }
+ }
+ g(); g();
+ let total = g();
+ %OptimizeFunctionOnNextCall(g);
+ g();
+ assertEquals(6, g());
+ done = true;
+ assertEquals(null, g());
+ done = false;
+ g(); g();
+ %OptimizeFunctionOnNextCall(g);
+ g();
+ assertEquals(6, g());
+ done = true;
+ assertEquals(null, g());
+})();
+
+(function ReduceFinallyNoInline() {
+ let done = false;
+ let f = (a, current) => {
+ if (done) throw "x";
+ return a + current;
+ };
+ %NeverOptimizeFunction(f);
+ let array = [1,2,3];
+ let g = function() {
+ try {
+ return array.reduce(f);
+ } catch (e) {
+ } finally {
+ if (done) return null;
+ }
+ }
+ g(); g();
+ let total = g();
+ %OptimizeFunctionOnNextCall(g);
+ g();
+ assertEquals(6, g());
+ done = true;
+ assertEquals(null, g());
+ done = false;
+ g(); g();
+ %OptimizeFunctionOnNextCall(g);
+ g();
+ assertEquals(6, g());
+ done = true;
+ assertEquals(null, g());
+})();
+
+(function ReduceNonCallableOpt() {
+ let done = false;
+ let f = (a, current) => {
+ return a + current;
+ };
+ let array = [1,2,3];
+ let g = function() {
+ return array.reduce(f);
+ }
+ g(); g();
+ let total = g();
+ %OptimizeFunctionOnNextCall(g);
+ g(); g();
+ assertEquals(6, g());
+ f = null;
+ assertThrows(() => g());
+})();
+
+(function ReduceCatchInlineDeopt() {
+ let done = false;
+ let f = (a, current) => {
+ if (done) {
+ %DeoptimizeNow();
+ throw "x";
+ }
+ return a + current;
+ };
+ let array = [1,2,3];
+ let g = function() {
+ try {
+ return array.reduce(f);
+ } catch (e) {
+ if (done) return null;
+ }
+ }
+ g(); g();
+ let total = g();
+ %OptimizeFunctionOnNextCall(g);
+ g();
+ assertEquals(6, g());
+ done = true;
+ assertEquals(null, g());
+ done = false;
+ g(); g();
+ %OptimizeFunctionOnNextCall(g);
+ g();
+ assertEquals(6, g());
+ done = true;
+ assertEquals(null, g());
+})();
+
+(function ReduceFinallyInlineDeopt() {
+ let done = false;
+ let f = (a, current) => {
+ if (done) {
+ %DeoptimizeNow();
+ throw "x";
+ }
+ return a + current;
+ };
+ let array = [1,2,3];
+ let g = function() {
+ try {
+ return array.reduce(f);
+ } catch (e) {
+ } finally {
+ if (done) return null;
+ }
+ }
+ g(); g();
+ let total = g();
+ %OptimizeFunctionOnNextCall(g);
+ g();
+ assertEquals(6, g());
+ done = true;
+ assertEquals(null, g());
+ done = false;
+ g(); g();
+ %OptimizeFunctionOnNextCall(g);
+ g();
+ assertEquals(6, g());
+ done = true;
+ assertEquals(null, g());
+})();
+
+(function OptimizedReduceRight() {
+ let count = 0;
+ let f = (a,current,i) => a + current * ++count;
+ let g = function(a) {
+ count = 0;
+ return a.reduceRight(f);
+ }
+ let a = [1,2,3,4,5,6,7,8,9,10];
+ g(a); g(a);
+ let total = g(a);
+ %OptimizeFunctionOnNextCall(g);
+ assertEquals(total, g(a));
+})();
+
+(function OptimizedReduceEmpty() {
+ let count = 0;
+ let f = (a,current,i) => a + current * ++count;
+ let g = function(a) {
+ count = 0;
+ return a.reduceRight(f);
+ }
+ let a = [1,2,3,4,5,6,7,8,9,10];
+ g(a); g(a); g(a);
+ %OptimizeFunctionOnNextCall(g);
+ g(a);
+ assertThrows(() => g([]));
+})();
+
+(function OptimizedReduceLazyDeopt() {
+ let deopt = false;
+ let f = (a,current) => { if (deopt) %DeoptimizeNow(); return a + current; };
+ let g = function(a) {
+ return a.reduceRight(f);
+ }
+ let a = [1,2,3,4,5,6,7,8,9,10];
+ g(a); g(a);
+ let total = g(a);
+ %OptimizeFunctionOnNextCall(g);
+ g(a);
+ deopt = true;
+ assertEquals(total, g(a));
+})();
+
+(function OptimizedReduceLazyDeoptMiddleOfIteration() {
+ let deopt = false;
+ let f = (a,current) => {
+ if (current == 6 && deopt) %DeoptimizeNow();
+ return a + current;
+ };
+ let g = function(a) {
+ return a.reduceRight(f);
+ }
+ let a = [11,22,33,45,56,6,77,84,93,101];
+ g(a); g(a);
+ let total = g(a);
+ %OptimizeFunctionOnNextCall(g);
+ g(a);
+ deopt = true;
+ assertEquals(total, g(a));
+})();
+
+(function OptimizedReduceEagerDeoptMiddleOfIteration() {
+ let deopt = false;
+ let array = [11,22,33,45,56,6,77,84,93,101];
+ let f = (a,current) => {
+ if (current == 6 && deopt) {array[9] = 1.5; }
+ return a + current;
+ };
+ let g = function() {
+ return array.reduceRight(f);
+ }
+ g(); g();
+ let total = g();
+ %OptimizeFunctionOnNextCall(g);
+ g();
+ deopt = true;
+ g();
+ deopt = false;
+ array = [11,22,33,45,56,6,77,84,93,101];
+ %OptimizeFunctionOnNextCall(g);
+ g();
+ deopt = true;
+ assertEquals(total, g());
+})();
+
+(function ReduceCatch() {
+ let f = (a,current) => {
+ return a + current;
+ };
+ let g = function() {
+ try {
+ return array.reduceRight(f);
+ } catch (e) {
+ }
+ }
+ g(); g();
+ let total = g();
+ %OptimizeFunctionOnNextCall(g);
+ g();
+ g();
+ assertEquals(total, g());
+})();
+
+(function ReduceThrow() {
+ let done = false;
+ let f = (a, current) => {
+ if (done) throw "x";
+ return a + current;
+ };
+ let array = [1,2,3];
+ let g = function() {
+ try {
+ return array.reduceRight(f);
+ } catch (e) {
+ return null;
+ }
+ }
+ g(); g();
+ let total = g();
+ %OptimizeFunctionOnNextCall(g);
+ g();
+ assertEquals(6, g());
+ done = true;
+ assertEquals(null, g());
+ done = false;
+ g(); g();
+ %OptimizeFunctionOnNextCall(g);
+ g();
+ assertEquals(6, g());
+ done = true;
+ assertEquals(null, g());
+})();
+
+(function ReduceThrow() {
+ let done = false;
+ let f = (a, current) => {
+ if (done) throw "x";
+ return a + current;
+ };
+ %NeverOptimizeFunction(f);
+ let array = [1,2,3];
+ let g = function() {
+ try {
+ return array.reduceRight(f);
+ } catch (e) {
+ return null;
+ }
+ }
+ g(); g();
+ let total = g();
+ %OptimizeFunctionOnNextCall(g);
+ g();
+ assertEquals(6, g());
+ done = true;
+ assertEquals(null, g());
+ done = false;
+ g(); g();
+ %OptimizeFunctionOnNextCall(g);
+ g();
+ assertEquals(6, g());
+ done = true;
+ assertEquals(null, g());
+})();
+
+(function ReduceFinally() {
+ let done = false;
+ let f = (a, current) => {
+ if (done) throw "x";
+ return a + current;
+ };
+ let array = [1,2,3];
+ let g = function() {
+ try {
+ return array.reduceRight(f);
+ } catch (e) {
+ } finally {
+ if (done) return null;
+ }
+ }
+ g(); g();
+ let total = g();
+ %OptimizeFunctionOnNextCall(g);
+ g();
+ assertEquals(6, g());
+ done = true;
+ assertEquals(null, g());
+ done = false;
+ g(); g();
+ %OptimizeFunctionOnNextCall(g);
+ g();
+ assertEquals(6, g());
+ done = true;
+ assertEquals(null, g());
+})();
+
+(function ReduceFinallyNoInline() {
+ let done = false;
+ let f = (a, current) => {
+ if (done) throw "x";
+ return a + current;
+ };
+ %NeverOptimizeFunction(f);
+ let array = [1,2,3];
+ let g = function() {
+ try {
+ return array.reduceRight(f);
+ } catch (e) {
+ } finally {
+ if (done) return null;
+ }
+ }
+ g(); g();
+ let total = g();
+ %OptimizeFunctionOnNextCall(g);
+ g();
+ assertEquals(6, g());
+ done = true;
+ assertEquals(null, g());
+ done = false;
+ g(); g();
+ %OptimizeFunctionOnNextCall(g);
+ g();
+ assertEquals(6, g());
+ done = true;
+ assertEquals(null, g());
+})();
+
+(function ReduceNonCallableOpt() {
+ let done = false;
+ let f = (a, current) => {
+ return a + current;
+ };
+ let array = [1,2,3];
+ let g = function() {
+ return array.reduceRight(f);
+ }
+ g(); g();
+ let total = g();
+ %OptimizeFunctionOnNextCall(g);
+ g(); g();
+ assertEquals(6, g());
+ f = null;
+ assertThrows(() => g());
+})();
+
+(function ReduceCatchInlineDeopt() {
+ let done = false;
+ let f = (a, current) => {
+ if (done) {
+ %DeoptimizeNow();
+ throw "x";
+ }
+ return a + current;
+ };
+ let array = [1,2,3];
+ let g = function() {
+ try {
+ return array.reduceRight(f);
+ } catch (e) {
+ if (done) return null;
+ }
+ }
+ g(); g();
+ let total = g();
+ %OptimizeFunctionOnNextCall(g);
+ g();
+ assertEquals(6, g());
+ done = true;
+ assertEquals(null, g());
+ done = false;
+ g(); g();
+ %OptimizeFunctionOnNextCall(g);
+ g();
+ assertEquals(6, g());
+ done = true;
+ assertEquals(null, g());
+})();
+
+(function ReduceFinallyInlineDeopt() {
+ let done = false;
+ let f = (a, current) => {
+ if (done) {
+ %DeoptimizeNow();
+ throw "x";
+ }
+ return a + current;
+ };
+ let array = [1,2,3];
+ let g = function() {
+ try {
+ return array.reduceRight(f);
+ } catch (e) {
+ } finally {
+ if (done) return null;
+ }
+ }
+ g(); g();
+ let total = g();
+ %OptimizeFunctionOnNextCall(g);
+ g();
+ assertEquals(6, g());
+ done = true;
+ assertEquals(null, g());
+ done = false;
+ g(); g();
+ %OptimizeFunctionOnNextCall(g);
+ g();
+ assertEquals(6, g());
+ done = true;
+ assertEquals(null, g());
+})();
+
+(function ReduceHoleyArrayWithDefaultAccumulator() {
+ var __v_12258 = new Array(10);
+ function __f_3253(a) {
+ let __f_3252 = function(accumulator, currentValue) {
+ return currentValue;
+ }
+ return a.reduce(__f_3252, 13);
+ }
+ assertEquals(13, __f_3253(__v_12258));
+ assertEquals(13, __f_3253(__v_12258));
+ assertEquals(13, __f_3253(__v_12258));
+ %OptimizeFunctionOnNextCall(__f_3253);
+ assertEquals(13, __f_3253(__v_12258));
+})();
+
+(function ReduceRightHoleyArrayWithDefaultAccumulator() {
+ var __v_12258 = new Array(10);
+ function __f_3253(a) {
+ let __f_3252 = function(accumulator, currentValue) {
+ return currentValue;
+ }
+ return a.reduceRight(__f_3252, 13);
+ }
+ assertEquals(13, __f_3253(__v_12258));
+ assertEquals(13, __f_3253(__v_12258));
+ assertEquals(13, __f_3253(__v_12258));
+ %OptimizeFunctionOnNextCall(__f_3253);
+ assertEquals(13, __f_3253(__v_12258));
+})();
+
+(function ReduceHoleyArrayOneElementWithDefaultAccumulator() {
+ var __v_12258 = new Array(10);
+ __v_12258[1] = 5;
+ function __f_3253(a) {
+ let __f_3252 = function(accumulator, currentValue) {
+ return currentValue + accumulator;
+ }
+ return a.reduce(__f_3252, 13);
+ }
+ assertEquals(18, __f_3253(__v_12258));
+ assertEquals(18, __f_3253(__v_12258));
+ assertEquals(18, __f_3253(__v_12258));
+ %OptimizeFunctionOnNextCall(__f_3253);
+ assertEquals(18, __f_3253(__v_12258));
+})();
+
+(function ReduceRightHoleyArrayOneElementWithDefaultAccumulator() {
+ var __v_12258 = new Array(10);
+ __v_12258[1] = 5;
+ function __f_3253(a) {
+ let __f_3252 = function(accumulator, currentValue) {
+ return currentValue + accumulator;
+ }
+ return a.reduceRight(__f_3252, 13);
+ }
+ assertEquals(18, __f_3253(__v_12258));
+ assertEquals(18, __f_3253(__v_12258));
+ assertEquals(18, __f_3253(__v_12258));
+ %OptimizeFunctionOnNextCall(__f_3253);
+ assertEquals(18, __f_3253(__v_12258));
+})();
diff --git a/deps/v8/test/mjsunit/code-coverage-block-noopt.js b/deps/v8/test/mjsunit/code-coverage-block-noopt.js
index 3eba9d3f57..ef68e0394d 100644
--- a/deps/v8/test/mjsunit/code-coverage-block-noopt.js
+++ b/deps/v8/test/mjsunit/code-coverage-block-noopt.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: --allow-natives-syntax --no-always-opt --harmony-async-iteration
+// Flags: --allow-natives-syntax --no-always-opt
// Flags: --no-opt
// Files: test/mjsunit/code-coverage-utils.js
diff --git a/deps/v8/test/mjsunit/code-coverage-block-opt.js b/deps/v8/test/mjsunit/code-coverage-block-opt.js
index bc4a3f1010..e02775bd45 100644
--- a/deps/v8/test/mjsunit/code-coverage-block-opt.js
+++ b/deps/v8/test/mjsunit/code-coverage-block-opt.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: --allow-natives-syntax --no-always-opt --harmony-async-iteration --opt
+// Flags: --allow-natives-syntax --no-always-opt --opt
// Files: test/mjsunit/code-coverage-utils.js
%DebugToggleBlockCoverage(true);
@@ -39,7 +39,7 @@ TestCoverage("Partial coverage collection",
}(); // 0400
`,
[{"start":52,"end":153,"count":0},
- {"start":127,"end":152,"count":1}]
+ {"start":121,"end":152,"count":1}]
);
%DebugToggleBlockCoverage(false);
diff --git a/deps/v8/test/mjsunit/code-coverage-block.js b/deps/v8/test/mjsunit/code-coverage-block.js
index 3355fd1259..b9d00bce6d 100644
--- a/deps/v8/test/mjsunit/code-coverage-block.js
+++ b/deps/v8/test/mjsunit/code-coverage-block.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: --allow-natives-syntax --no-always-opt --harmony-async-iteration
+// Flags: --allow-natives-syntax --no-always-opt
// Files: test/mjsunit/code-coverage-utils.js
%DebugToggleBlockCoverage(true);
@@ -38,20 +38,23 @@ function f(x) { // 0050
} // 0550
f(42); // 0600
f(43); // 0650
-`,
-[{"start":0,"end":699,"count":1},
+if (true) { // 0700
+ const foo = 'bar'; // 0750
+} else { // 0800
+ const bar = 'foo'; // 0850
+} // 0900
+`,
+[{"start":0,"end":949,"count":1},
+ {"start":801,"end":901,"count":0},
{"start":0,"end":15,"count":11},
{"start":50,"end":551,"count":2},
{"start":115,"end":203,"count":1},
{"start":167,"end":171,"count":0},
- {"start":265,"end":273,"count":1},
- {"start":279,"end":287,"count":1},
- {"start":315,"end":319,"count":1},
- {"start":325,"end":329,"count":1},
+ {"start":265,"end":287,"count":1},
+ {"start":315,"end":329,"count":1},
{"start":363,"end":367,"count":0},
{"start":413,"end":417,"count":0},
- {"start":472,"end":476,"count":0}]
-
+ {"start":466,"end":476,"count":0}]
);
TestCoverage(
@@ -82,7 +85,7 @@ TestCoverage(
`,
[{"start":0,"end":249,"count":1},
{"start":1,"end":201,"count":1},
- {"start":124,"end":129,"count":0}]
+ {"start":118,"end":129,"count":0}]
);
TestCoverage(
@@ -109,7 +112,7 @@ function g() {} // 0000
{"start":330,"end":334,"count":0},
{"start":431,"end":503,"count":12},
{"start":470,"end":474,"count":4},
- {"start":480,"end":484,"count":8}]
+ {"start":474,"end":484,"count":8}]
);
TestCoverage(
diff --git a/deps/v8/test/mjsunit/compiler/array-multiple-receiver-maps.js b/deps/v8/test/mjsunit/compiler/array-multiple-receiver-maps.js
new file mode 100644
index 0000000000..2ef0cc3a01
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/array-multiple-receiver-maps.js
@@ -0,0 +1,122 @@
+// Copyright 2018 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: --allow-natives-syntax --opt --no-always-opt
+
+function runTest(f, message, mkICTraining, deoptArg) {
+ function test(f, message, ictraining, deoptArg) {
+ // Train the call ic to the maps.
+ let t = ictraining;
+
+ // We put the training data into local variables
+ // to ensure their maps are kepts alive. If the
+ // maps die, gc *may* deoptimize {f}, which makes
+ // the test flaky.
+ let t1 = t();
+ let t2 = t();
+ let t3 = t();
+
+ for (let a of t1) {
+ f(a.arr, () => a.el);
+ }
+ for (let a of t2) {
+ f(a.arr, () => a.el);
+ }
+ %OptimizeFunctionOnNextCall(f);
+ message += " trained with" + JSON.stringify(t());
+ if (deoptArg == undefined) {
+ // Make sure the optimized function can handle
+ // all trained maps without deopt.
+ for (let a of t3) {
+ f(a.arr, () => a.el);
+ message += " for args " + JSON.stringify(a);
+ assertOptimized(f, undefined, message + " should have been optimized");
+ }
+ } else {
+ // Trigger deopt, causing no-speculation bit to be set.
+ let a1 = deoptArg;
+ let a2 = deoptArg;
+ message += " for args " + JSON.stringify(a1);
+ f(a1.arr, () => a1.el);
+ assertUnoptimized(f, undefined, message + " should have been unoptimized");
+ %OptimizeFunctionOnNextCall(f);
+ // No speculation should protect against further deopts.
+ f(a2.arr, () => a2.el);
+ assertOptimized(f, undefined, message + " should have been optimized");
+ }
+ }
+
+ // Get function as a string.
+ var testString = test.toString();
+ // Remove the function header..
+ testString = testString.replace(new RegExp("[^\n]*"), "let f = " + f.toString() + ";");
+ // ..and trailing '}'.
+ testString = testString.replace(new RegExp("[^\n]*$"), "");
+ // Substitute parameters.
+ testString = testString.replace(new RegExp("ictraining", 'g'), mkICTraining.toString());
+ testString = testString.replace(new RegExp("deoptArg", 'g'),
+ deoptArg ? JSON.stringify(deoptArg) : "undefined");
+
+ var modTest = new Function("message", testString);
+ //print(modTest);
+ modTest(message);
+}
+
+let checks = {
+ smiReceiver:
+ { mkTrainingArguments : () => [{arr:[1], el:3}],
+ deoptingArguments : [{arr:[0.1], el:1}, {arr:[{}], el:1}]
+ },
+ objectReceiver:
+ { mkTrainingArguments : () => [{arr:[{}], el:0.1}],
+ deoptingArguments : []
+ },
+ multipleSmiReceivers:
+ { mkTrainingArguments : () => { let b = [1]; b.x=3; return [{arr:[1], el:3}, {arr:b, el:3}] },
+ deoptingArguments : [{arr:[0.1], el:1}, {arr:[{}], el:1}]
+ },
+ multipleSmiReceiversPackedUnpacked:
+ { mkTrainingArguments : () => { let b = [1]; b[100] = 3; return [{arr:[1], el:3}, {arr:b, el:3}] },
+ deoptingArguments : [{arr:[0.1], el:1}, {arr:[{}], el:1}]
+ },
+ multipleDoubleReceivers:
+ { mkTrainingArguments : () => { let b = [0.1]; b.x=0.3; return [{arr:[0.1], el:0.3}, {arr:b, el:0.3}] },
+ deoptingArguments : [{arr:[{}], el:true}, {arr:[1], el:true}]
+ },
+ multipleDoubleReceiversPackedUnpacked:
+ { mkTrainingArguments : () => { let b = [0.1]; b[100] = 0.3; return [{arr:[0.1], el:0.3}, {arr:b, el:0.3}] },
+ deoptingArguments : [{arr:[{}], el:true}, {arr:[1], el:true}]
+ },
+ multipleMixedReceivers:
+ { mkTrainingArguments : () => { let b = [0.1]; b.x=0.3; return [{arr:[1], el:0.3}, {arr:[{}], el:true}, {arr:b, el:0.3}] },
+ deoptingArguments : []
+ },
+ multipleMixedReceiversPackedUnpacked:
+ { mkTrainingArguments : () => { let b = [0.1]; b[100] = 0.3; return [{arr:[1], el:0.3}, {arr:[{}], el:true}, {arr:b, el:0.3}] },
+ deoptingArguments : []
+ },
+};
+
+const functions = {
+ push_reliable: (a,g) => { let b = g(); return a.push(2, b); },
+ push_unreliable: (a,g) => { return a.push(2, g()); },
+ pop_reliable: (a,g) => { let b = g(); return a.pop(2, b); },
+ pop_unreliable: (a,g) => { return a.pop(2, g()); },
+ shift_reliable: (a,g) => { let b = g(); return a.shift(2, b); },
+ shift_unreliable: (a,g) => { return a.shift(2, g()); }
+}
+
+Object.keys(checks).forEach(
+ key => {
+ let check = checks[key];
+
+ for (fnc in functions) {
+ runTest(functions[fnc], "test-reliable-" + key, check.mkTrainingArguments);
+ // Test each deopting arg separately.
+ for (let deoptArg of check.deoptingArguments) {
+ runTest(functions[fnc], "testDeopt-reliable-" + key, check.mkTrainingArguments, deoptArg);
+ }
+ }
+ }
+);
diff --git a/deps/v8/test/mjsunit/compiler/deopt-array-builtins.js b/deps/v8/test/mjsunit/compiler/deopt-array-builtins.js
new file mode 100644
index 0000000000..b737b17ed0
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/deopt-array-builtins.js
@@ -0,0 +1,148 @@
+// Copyright 2017 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: --allow-natives-syntax --opt
+
+/* Test MapCheck behavior */
+
+(function testForEachMapCheck() {
+ function f(v,n,o) {
+ Object.freeze(o);
+ }
+ function g() {
+ [1,2,3].forEach(f);
+ }
+ g();
+ g();
+ %OptimizeFunctionOnNextCall(g);
+ g();
+ %OptimizeFunctionOnNextCall(g);
+ g();
+ assertOptimized(g);
+})();
+
+
+(function testFindMapCheck() {
+ function f(v,n,o) {
+ Object.freeze(o);
+ return false;
+ }
+ function g() {
+ [1,2,3].find(f);
+ }
+ g();
+ g();
+ %OptimizeFunctionOnNextCall(g);
+ g();
+ %OptimizeFunctionOnNextCall(g);
+ g();
+ assertOptimized(g);
+})();
+
+(function testMapMapCheck() {
+ function f(v,n,o) {
+ Object.freeze(o);
+ return false;
+ }
+ function g() {
+ [1,2,3].map(f);
+ }
+ g();
+ g();
+ %OptimizeFunctionOnNextCall(g);
+ g();
+ %OptimizeFunctionOnNextCall(g);
+ g();
+ assertOptimized(g);
+})();
+
+(function testFilterMapCheck() {
+ function f(v,n,o) {
+ Object.freeze(o);
+ return true;
+ }
+ function g() {
+ [1,2,3].filter(f);
+ }
+ g();
+ g();
+ %OptimizeFunctionOnNextCall(g);
+ g();
+ %OptimizeFunctionOnNextCall(g);
+ g();
+ assertOptimized(g);
+})();
+
+
+/* Test CheckBounds behavior */
+
+(function testForEachCheckBounds() {
+ function f(v,n,o) {
+ o.length=2;
+ }
+ function g() {
+ [1,2,3].forEach(f);
+ }
+ g();
+ g();
+ %OptimizeFunctionOnNextCall(g);
+ g();
+ %OptimizeFunctionOnNextCall(g);
+ g();
+ assertOptimized(g);
+})();
+
+
+(function testFindCheckBounds() {
+ function f(v,n,o) {
+ o.length=2;
+ return false;
+ }
+ function g() {
+ [1,2,3].find(f);
+ }
+ g();
+ g();
+ %OptimizeFunctionOnNextCall(g);
+ g();
+ %OptimizeFunctionOnNextCall(g);
+ g();
+ assertOptimized(g);
+})();
+
+(function testMapCheckBounds() {
+ function f(v,n,o) {
+ o.length=2;
+ return false;
+ }
+ function g() {
+ [1,2,3].map(f);
+ }
+ g();
+ g();
+ %OptimizeFunctionOnNextCall(g);
+ g();
+ %OptimizeFunctionOnNextCall(g);
+ g();
+ assertOptimized(g);
+})();
+
+(function testFilterCheckBounds() {
+ function f(v,n,o) {
+ o.length = 2;
+ return true;
+ }
+ function g() {
+ [1,2,3].filter(f);
+ }
+ g();
+ g();
+ %OptimizeFunctionOnNextCall(g);
+ g();
+ g();
+ %OptimizeFunctionOnNextCall(g);
+ g();
+ g();
+ assertOptimized(g);
+})();
diff --git a/deps/v8/test/mjsunit/compiler/deopt-array-push.js b/deps/v8/test/mjsunit/compiler/deopt-array-push.js
new file mode 100644
index 0000000000..e34d99a325
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/deopt-array-push.js
@@ -0,0 +1,97 @@
+// Copyright 2017 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: --allow-natives-syntax --opt
+
+(function test() {
+ function foo(a) { a.push(a.length = 2); }
+
+ foo([1]);
+ foo([1]);
+ %OptimizeFunctionOnNextCall(foo);
+ foo([1]);
+ %OptimizeFunctionOnNextCall(foo);
+ foo([1]);
+ assertOptimized(foo);
+})();
+
+(function testElementTypeCheckSmi() {
+ function foo(a) { a.push('a'); }
+
+ foo([1]);
+ foo([1]);
+ %OptimizeFunctionOnNextCall(foo);
+ foo([1]);
+ %OptimizeFunctionOnNextCall(foo);
+ foo([1]);
+ assertOptimized(foo);
+})();
+
+(function testElementTypeCheckDouble() {
+ function foo(a) { a.push('a'); }
+
+ foo([0.3413312]);
+ foo([0.3413312]);
+ %OptimizeFunctionOnNextCall(foo);
+ foo([0.3413312]);
+ %OptimizeFunctionOnNextCall(foo);
+ foo([0.3413312]);
+ assertOptimized(foo);
+})();
+(function test() {
+ function bar(a) { a.x = 2 };
+ %NeverOptimizeFunction(bar);
+ function foo(a) { a.push(bar(a)); }
+
+ foo(["1"]);
+ foo(["1"]);
+ %OptimizeFunctionOnNextCall(foo);
+ foo(["1"]);
+ %OptimizeFunctionOnNextCall(foo);
+ foo(["1"]);
+ assertOptimized(foo);
+})();
+
+(function test() {
+ function foo(a) { a.push(a.length = 2); }
+
+ foo([0.34234]);
+ foo([0.34234]);
+ %OptimizeFunctionOnNextCall(foo);
+ foo([0.34234]);
+ %OptimizeFunctionOnNextCall(foo);
+ foo([0.34234]);
+ assertOptimized(foo);
+})();
+
+(function test() {
+ const N = 128 * 1024;
+
+ function foo(a) { a.push(1); }
+
+ foo(new Array(N));
+ foo(new Array(N));
+ %OptimizeFunctionOnNextCall(foo);
+ foo(new Array(N));
+ %OptimizeFunctionOnNextCall(foo);
+ foo(new Array(N));
+ assertOptimized(foo);
+})();
+
+(function test() {
+ function mkArray() {
+ const N = 128 * 1024;
+ let a = [0.1];
+ a.length = N;
+ return a;
+ }
+ function foo(a) { a.push(0.23441233123); }
+ foo(mkArray());
+ foo(mkArray());
+ %OptimizeFunctionOnNextCall(foo);
+ foo(mkArray());
+ %OptimizeFunctionOnNextCall(foo);
+ foo(mkArray());
+ assertOptimized(foo);
+})();
diff --git a/deps/v8/test/mjsunit/compiler/escape-analysis-13.js b/deps/v8/test/mjsunit/compiler/escape-analysis-13.js
index fca4da618e..5f281aaaa4 100644
--- a/deps/v8/test/mjsunit/compiler/escape-analysis-13.js
+++ b/deps/v8/test/mjsunit/compiler/escape-analysis-13.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: --allow-natives-syntax --turbo-escape --turbo-experimental
+// Flags: --allow-natives-syntax --turbo-escape
function f() {
var x = {};
diff --git a/deps/v8/test/mjsunit/compiler/escape-analysis-15.js b/deps/v8/test/mjsunit/compiler/escape-analysis-15.js
index 4f9a40ad5c..1960d74892 100644
--- a/deps/v8/test/mjsunit/compiler/escape-analysis-15.js
+++ b/deps/v8/test/mjsunit/compiler/escape-analysis-15.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: --allow-natives-syntax --turbo-escape --turbo-experimental --no-turbo-load-elimination
+// Flags: --allow-natives-syntax --turbo-escape --no-turbo-load-elimination
function f(i) {
var o1 = {a: 1, b: 2};
diff --git a/deps/v8/test/mjsunit/compiler/escape-analysis-phi-type.js b/deps/v8/test/mjsunit/compiler/escape-analysis-phi-type.js
index 806b09b3de..9d033b9640 100644
--- a/deps/v8/test/mjsunit/compiler/escape-analysis-phi-type.js
+++ b/deps/v8/test/mjsunit/compiler/escape-analysis-phi-type.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: --allow-natives-syntax --turbo-escape --turbo-experimental --no-turbo-loop-peeling
+// Flags: --allow-natives-syntax --turbo-escape --no-turbo-loop-peeling
function f(x) {
var o = {a : 0};
diff --git a/deps/v8/test/mjsunit/compiler/materialize-dictionary-properties.js b/deps/v8/test/mjsunit/compiler/materialize-dictionary-properties.js
new file mode 100644
index 0000000000..5838a83979
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/materialize-dictionary-properties.js
@@ -0,0 +1,18 @@
+// Copyright 2017 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: --allow-natives-syntax
+
+function f() {
+ // Create a non-escaping object.
+ var o = Object.create(null);
+ %DeoptimizeNow();
+ // Keep it alive.
+ return o ? 1 : 0;
+}
+
+f();
+f();
+%OptimizeFunctionOnNextCall(f);
+assertEquals(1, f());
diff --git a/deps/v8/test/mjsunit/compiler/materialize-mutable-heap-number.js b/deps/v8/test/mjsunit/compiler/materialize-mutable-heap-number.js
new file mode 100644
index 0000000000..b6b99afcf4
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/materialize-mutable-heap-number.js
@@ -0,0 +1,22 @@
+// Copyright 2017 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: --allow-natives-syntax
+
+function C() {}
+%CompleteInobjectSlackTracking(new C());
+
+function f() {
+ // Create a non-escaping object.
+ var o = new C();
+ // Add an out-of-object double property.
+ o.x = 0.5;
+ %DeoptimizeNow();
+ return o.x + 0.25;
+}
+
+f();
+f();
+%OptimizeFunctionOnNextCall(f);
+assertEquals(0.75, f());
diff --git a/deps/v8/test/mjsunit/compiler/new-cons-string.js b/deps/v8/test/mjsunit/compiler/new-cons-string.js
new file mode 100644
index 0000000000..7f6da7262a
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/new-cons-string.js
@@ -0,0 +1,71 @@
+// Copyright 2017 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: --allow-natives-syntax --expose-externalize-string
+
+(function() {
+ function foo(s) {
+ return "abcdefghijklm" + s;
+ }
+
+ assertTrue(isOneByteString(foo("0")));
+ assertTrue(isOneByteString(foo("0")));
+ %OptimizeFunctionOnNextCall(foo);
+ assertTrue(isOneByteString(foo("0")));
+})();
+
+(function() {
+ function foo(s) {
+ return s + "abcdefghijklm";
+ }
+
+ assertTrue(isOneByteString(foo("0")));
+ assertTrue(isOneByteString(foo("0")));
+ %OptimizeFunctionOnNextCall(foo);
+ assertTrue(isOneByteString(foo("0")));
+})();
+
+(function() {
+ function foo(s) {
+ return "abcdefghijklm" + s;
+ }
+
+ assertFalse(isOneByteString(foo("\u1234")));
+ assertFalse(isOneByteString(foo("\u1234")));
+ %OptimizeFunctionOnNextCall(foo);
+ assertFalse(isOneByteString(foo("\u1234")));
+})();
+
+(function() {
+ function foo(s) {
+ return s + "abcdefghijklm";
+ }
+
+ assertFalse(isOneByteString(foo("\u1234")));
+ assertFalse(isOneByteString(foo("\u1234")));
+ %OptimizeFunctionOnNextCall(foo);
+ assertFalse(isOneByteString(foo("\u1234")));
+})();
+
+(function() {
+ function foo(s) {
+ return "abcdefghijkl\u1234" + s;
+ }
+
+ assertFalse(isOneByteString(foo("0")));
+ assertFalse(isOneByteString(foo("0")));
+ %OptimizeFunctionOnNextCall(foo);
+ assertFalse(isOneByteString(foo("0")));
+})();
+
+(function() {
+ function foo(s) {
+ return s + "abcdefghijkl\u1234";
+ }
+
+ assertFalse(isOneByteString(foo("0")));
+ assertFalse(isOneByteString(foo("0")));
+ %OptimizeFunctionOnNextCall(foo);
+ assertFalse(isOneByteString(foo("0")));
+})();
diff --git a/deps/v8/test/mjsunit/compiler/regress-786521.js b/deps/v8/test/mjsunit/compiler/regress-786521.js
new file mode 100644
index 0000000000..2b161270ed
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/regress-786521.js
@@ -0,0 +1,23 @@
+// Copyright 2017 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: --allow-natives-syntax
+
+// Provoke type None as result of a SpeculativeNumberMultiply to
+// ensure that Turbofan can handle this.
+
+function inlined(b, x) {
+ if (b) {
+ x * 2 * 2
+ }
+}
+
+inlined(true, 1);
+inlined(true, 2);
+inlined(false, 1);
+
+function foo(b) { inlined(b, "") }
+foo(false); foo(false);
+%OptimizeFunctionOnNextCall(foo);
+foo(true);
diff --git a/deps/v8/test/mjsunit/compiler/regress-793863.js b/deps/v8/test/mjsunit/compiler/regress-793863.js
new file mode 100644
index 0000000000..883805dff6
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/regress-793863.js
@@ -0,0 +1,12 @@
+// Copyright 2017 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: --allow-natives-syntax
+
+function f(a) {
+ return arguments[0];
+}
+
+%OptimizeFunctionOnNextCall(f);
+assertEquals(undefined, f());
diff --git a/deps/v8/test/mjsunit/compiler/regress-796041.js b/deps/v8/test/mjsunit/compiler/regress-796041.js
new file mode 100644
index 0000000000..e2c2e11c0b
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/regress-796041.js
@@ -0,0 +1,35 @@
+// Copyright 2018 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: --allow-natives-syntax
+
+'use strict';
+
+function f(abort, n, a, b) {
+ if (abort) return;
+ var x = a ? true : "" + a;
+ if (!a) {
+ var dead = n + 1 + 1;
+ if(!b) {
+ x = dead;
+ }
+ if (x) {
+ x = false;
+ }
+ if (b) {
+ x = false;
+ }
+ }
+ return x + 1;
+}
+f(false, 5); f(false, 6); f(false, 7); f(false, 8);
+
+function g(abort, a, b) {
+ return f(abort, "abc", a, b);
+}
+
+g(true); g(true); g(true); g(true);
+
+%OptimizeFunctionOnNextCall(g);
+g(false);
diff --git a/deps/v8/test/mjsunit/compiler/regress-797596.js b/deps/v8/test/mjsunit/compiler/regress-797596.js
new file mode 100644
index 0000000000..4e3594bdb1
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/regress-797596.js
@@ -0,0 +1,30 @@
+// Copyright 2017 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-gc --allow-natives-syntax
+var notCallable;
+function inferReceiverMapsInDeadCode() {
+ var obj = { func() {} };
+ gc();
+ function wrappedCode() { try { code(); } catch (e) {} }
+ function code() {
+ obj.a;
+ try {
+ Object.defineProperty(obj, "func", { get() {} });
+ } catch (neverCaught) {}
+ for (var i = 0; i < 1; i++) {
+ try {
+ notCallable(arguments[i]);
+ } catch (alwaysCaught) {}
+ }
+ }
+ wrappedCode();
+ try {
+ %OptimizeFunctionOnNextCall(wrappedCode);
+ wrappedCode();
+ } catch (e) {}
+}
+inferReceiverMapsInDeadCode();
+inferReceiverMapsInDeadCode();
+inferReceiverMapsInDeadCode();
diff --git a/deps/v8/test/mjsunit/compiler/regress-801097.js b/deps/v8/test/mjsunit/compiler/regress-801097.js
new file mode 100644
index 0000000000..d488ce4deb
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/regress-801097.js
@@ -0,0 +1,19 @@
+// Copyright 2018 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: --allow-natives-syntax
+
+function GetFunction() {
+ var source = "return ((dividend | 0) / ((";
+ for (var i = 0; i < 0x8000; i++) {
+ source += "a,"
+ }
+ source += "a) | 0)) | 0";
+ return Function("dividend", source);
+}
+
+var func = GetFunction();
+assertThrows("func();");
+%OptimizeFunctionOnNextCall(func);
+assertThrows("func()");
diff --git a/deps/v8/test/mjsunit/compiler/varargs.js b/deps/v8/test/mjsunit/compiler/varargs.js
new file mode 100644
index 0000000000..ae636dc0f7
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/varargs.js
@@ -0,0 +1,49 @@
+// Copyright 2017 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.
+
+x = "a";
+
+function test_varargs(...args) {
+ var sum = this.x;
+ for (i in args) {
+ sum += "," + args[i];
+ }
+ return sum;
+}
+
+assertEquals("a", test_varargs());
+assertEquals("a,b", test_varargs("b"));
+assertEquals("a,b,c", test_varargs("b", "c"));
+assertEquals("a,b,c,d", test_varargs("b", "c", "d"));
+assertEquals("a,b,c,d,e", test_varargs("b", "c", "d", "e"));
+
+function forward_varargs(...args) {
+ return test_varargs(...args);
+}
+
+assertEquals("a", forward_varargs());
+assertEquals("a,b", forward_varargs("b"));
+assertEquals("a,b,c", forward_varargs("b", "c"));
+assertEquals("a,b,c,d", forward_varargs("b", "c", "d"));
+assertEquals("a,b,c,d,e", forward_varargs("b", "c", "d", "e"));
+
+function forward_varargs_one_arg(x, ...args) {
+ return test_varargs(x, ...args);
+}
+
+assertEquals("a,undefined", forward_varargs_one_arg());
+assertEquals("a,b", forward_varargs_one_arg("b"));
+assertEquals("a,b,c", forward_varargs_one_arg("b", "c"));
+assertEquals("a,b,c,d", forward_varargs_one_arg("b", "c", "d"));
+assertEquals("a,b,c,d,e", forward_varargs_one_arg("b", "c", "d", "e"));
+
+function forward_varargs_two_args(x, y, ...args) {
+ return test_varargs(x, y, ...args);
+}
+
+assertEquals("a,undefined,undefined", forward_varargs_two_args());
+assertEquals("a,b,undefined", forward_varargs_two_args("b"));
+assertEquals("a,b,c", forward_varargs_two_args("b", "c"));
+assertEquals("a,b,c,d", forward_varargs_two_args("b", "c", "d"));
+assertEquals("a,b,c,d,e", forward_varargs_two_args("b", "c", "d", "e"));
diff --git a/deps/v8/test/mjsunit/constant-folding-2.js b/deps/v8/test/mjsunit/constant-folding-2.js
index da9e5d5469..7586261c92 100644
--- a/deps/v8/test/mjsunit/constant-folding-2.js
+++ b/deps/v8/test/mjsunit/constant-folding-2.js
@@ -33,8 +33,6 @@ function test(f) {
f();
%OptimizeFunctionOnNextCall(f);
f();
- // Assert that there has been no deopt.
- assertOptimized(f);
}
test(function add() {
@@ -234,6 +232,7 @@ test(function stringCharCodeAt() {
assertEquals("NaN", String("abc".charCodeAt(4)));
assertEquals(98, "abc".charCodeAt(1.1));
assertEquals("NaN", String("abc".charCodeAt(4.1)));
+ assertEquals("NaN", String("abc".charCodeAt(1 + 4294967295)));
});
test(function stringCharAt() {
@@ -242,6 +241,7 @@ test(function stringCharAt() {
assertEquals("", "abc".charAt(4));
assertEquals("b", "abc".charAt(1.1));
assertEquals("", "abc".charAt(4.1));
+ assertEquals("", String("abc".charAt(1 + 4294967295)));
});
diff --git a/deps/v8/test/mjsunit/d8/.gitignore b/deps/v8/test/mjsunit/d8/.gitignore
new file mode 100644
index 0000000000..4497115e4c
--- /dev/null
+++ b/deps/v8/test/mjsunit/d8/.gitignore
@@ -0,0 +1 @@
+v8_trace.json
diff --git a/deps/v8/test/mjsunit/d8-os.js b/deps/v8/test/mjsunit/d8/d8-os.js
index c2d8ec59bc..c2d8ec59bc 100644
--- a/deps/v8/test/mjsunit/d8-os.js
+++ b/deps/v8/test/mjsunit/d8/d8-os.js
diff --git a/deps/v8/test/mjsunit/d8-performance-now.js b/deps/v8/test/mjsunit/d8/d8-performance-now.js
index 3e5485e81d..3e5485e81d 100644
--- a/deps/v8/test/mjsunit/d8-performance-now.js
+++ b/deps/v8/test/mjsunit/d8/d8-performance-now.js
diff --git a/deps/v8/test/mjsunit/d8-worker-sharedarraybuffer.js b/deps/v8/test/mjsunit/d8/d8-worker-sharedarraybuffer.js
index 09586c3a11..09586c3a11 100644
--- a/deps/v8/test/mjsunit/d8-worker-sharedarraybuffer.js
+++ b/deps/v8/test/mjsunit/d8/d8-worker-sharedarraybuffer.js
diff --git a/deps/v8/test/mjsunit/d8-worker-spawn-worker.js b/deps/v8/test/mjsunit/d8/d8-worker-spawn-worker.js
index a114d8587e..a114d8587e 100644
--- a/deps/v8/test/mjsunit/d8-worker-spawn-worker.js
+++ b/deps/v8/test/mjsunit/d8/d8-worker-spawn-worker.js
diff --git a/deps/v8/test/mjsunit/d8-worker.js b/deps/v8/test/mjsunit/d8/d8-worker.js
index a73d7b1706..a73d7b1706 100644
--- a/deps/v8/test/mjsunit/d8-worker.js
+++ b/deps/v8/test/mjsunit/d8/d8-worker.js
diff --git a/deps/v8/test/mjsunit/d8/enable-tracing.js b/deps/v8/test/mjsunit/d8/enable-tracing.js
new file mode 100644
index 0000000000..5174b41155
--- /dev/null
+++ b/deps/v8/test/mjsunit/d8/enable-tracing.js
@@ -0,0 +1,8 @@
+// Copyright 2017 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: --enable-tracing --trace-path=test/mjsunit/d8/v8_trace.json
+
+// Just test that running d8 with --enable-tracing does not crash in a normal
+// execution without exceptions or calls to natives.
diff --git a/deps/v8/test/mjsunit/deserialize-reference.js b/deps/v8/test/mjsunit/deserialize-reference.js
index b032013159..ac4979bd26 100644
--- a/deps/v8/test/mjsunit/deserialize-reference.js
+++ b/deps/v8/test/mjsunit/deserialize-reference.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: --cache=code --serialize-toplevel
+// Flags: --cache=code
var a = "123";
assertEquals(a, "123");
diff --git a/deps/v8/test/mjsunit/dictionary-prototypes.js b/deps/v8/test/mjsunit/dictionary-prototypes.js
new file mode 100644
index 0000000000..109f8d42a6
--- /dev/null
+++ b/deps/v8/test/mjsunit/dictionary-prototypes.js
@@ -0,0 +1,409 @@
+// Copyright 2017 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: --allow-natives-syntax
+
+function EnsureDictionaryMode(obj, properties=1500) {
+ for (let i = 0; i < properties; i++) {
+ obj["x" + i] = 0;
+ }
+ assertFalse(%HasFastProperties(obj));
+}
+
+function EnsureAlmostDictionaryMode(obj) {
+ for (let i = 0; i < 1020; i++) {
+ obj["x" + i] = 0;
+ }
+}
+
+function TestAddingPropertyToDictionaryPrototype() {
+ let foo_func_called = 0;
+ let bar_func_called = 0;
+
+ function Foo() {}
+ Foo.prototype.func = function() { ++foo_func_called; }
+
+ function Bar() {}
+ Bar.prototype = Object.create(Foo.prototype);
+ EnsureDictionaryMode(Bar.prototype);
+
+ let o = new Bar();
+
+ for (let i = 0; i < 11; ++i) {
+ // First, the property is looked up from Foo.
+ o.func();
+
+ // Add the property to Bar which is a dictionary-mode prototype between o
+ // and Foo. In the next iteration, it's looked up from Bar.
+ if (i == 9) {
+ // The UNINITIALIZED -> PREMONOMORPHIC transition of StoreIC should
+ // properly invalidate prototype chains.
+ Bar.prototype.func = function() { ++bar_func_called; }
+ }
+ }
+
+ assertEquals(10, foo_func_called);
+ assertEquals(1, bar_func_called);
+}
+
+TestAddingPropertyToDictionaryPrototype();
+
+// Same as TestAddingPropertyToDictionaryPrototype, but using o["foo"] access
+// instead of o.foo.
+function TestAddingPropertyToDictionaryPrototype2() {
+ let foo_func_called = 0;
+ let bar_func_called = 0;
+ let name = "func";
+
+ function Foo() {}
+ Foo.prototype[name] = function() { ++foo_func_called; }
+
+ function Bar() {}
+ Bar.prototype = Object.create(Foo.prototype);
+ EnsureDictionaryMode(Bar.prototype);
+
+ let o = new Bar();
+
+ for (let i = 0; i < 11; ++i) {
+ // First, the property is looked up from Foo.
+ o[name]();
+
+ // Add the property to Bar which is a dictionary-mode prototype between o
+ // and Foo. In the next iteration, it's looked up from Bar.
+ if (i == 9) {
+ // The UNINITIALIZED -> PREMONOMORPHIC transition of KeyedStoreIC should
+ // properly invalidate prototype chains.
+ Bar.prototype[name] = function() { ++bar_func_called; }
+ }
+ }
+
+ assertEquals(10, foo_func_called);
+ assertEquals(1, bar_func_called);
+}
+
+TestAddingPropertyToDictionaryPrototype2();
+
+function TestAddingPropertyToDictionaryPrototype_DefineProperty() {
+ let foo_func_called = 0;
+ let bar_func_called = 0;
+
+ function Foo() {}
+ Foo.prototype.func = function() { ++foo_func_called; }
+
+ function Bar() {}
+ Bar.prototype = Object.create(Foo.prototype);
+ EnsureDictionaryMode(Bar.prototype);
+
+ let o = new Bar();
+
+ for (let i = 0; i < 11; ++i) {
+ // First, the property is looked up from Foo.
+ o.func();
+
+ // Add the property to Bar which is a dictionary-mode prototype between o
+ // and Foo. In the next iteration, it's looked up from Bar.
+ if (i == 9) {
+ // The runtime should properly invalidate prototype chains.
+ Object.defineProperty(Bar.prototype, "func", {value: function() { ++bar_func_called; }});
+ }
+ }
+
+ assertEquals(10, foo_func_called);
+ assertEquals(1, bar_func_called);
+}
+
+TestAddingPropertyToDictionaryPrototype_DefineProperty();
+
+function TestAddingPropertyToDictionaryPrototype_DictionaryAddSlowPath() {
+ let foo_func_called = 0;
+ let bar_func_called = 0;
+
+ function Foo() {}
+ Foo.prototype.func = function() { ++foo_func_called; }
+
+ function Bar() {}
+ Bar.prototype = Object.create(Foo.prototype);
+ // The magic number ensures that the next addition to the dictionary will
+ // trigger the slow path.
+ EnsureDictionaryMode(Bar.prototype, 2731);
+
+ let o = new Bar();
+
+ for (let i = 0; i < 11; ++i) {
+ // First, the property is looked up from Foo.
+ o.func();
+
+ // Add the property to Bar which is a dictionary-mode prototype between o
+ // and Foo. In the next iteration, it's looked up from Bar.
+ if (i == 9) {
+ // -> slow path for dictionary add
+ Bar.prototype.func = function() { ++bar_func_called; }
+ }
+ }
+
+ assertEquals(10, foo_func_called);
+ assertEquals(1, bar_func_called);
+}
+
+TestAddingPropertyToDictionaryPrototype_DictionaryAddSlowPath();
+
+function TestAddingAccessorPropertyToDictionaryPrototype() {
+ let foo_func_called = 0;
+ let bar_func_called = 0;
+
+ function Foo() {}
+ Foo.prototype.func = function() { ++foo_func_called; }
+
+ function Bar() {}
+ Bar.prototype = Object.create(Foo.prototype);
+ EnsureDictionaryMode(Bar.prototype);
+
+ let o = new Bar();
+
+ for (let i = 0; i < 11; ++i) {
+ // First, the property is looked up from Foo.
+ o.func();
+
+ // Add the property to Bar which is a dictionary-mode prototype between o
+ // and Foo. In the next iteration, it's looked up from Bar.
+ if (i == 9) {
+ Object.defineProperty(Bar.prototype, "func",
+ {get: function() { return function() { ++bar_func_called; }}});
+ }
+ }
+
+ assertEquals(10, foo_func_called);
+ assertEquals(1, bar_func_called);
+}
+
+TestAddingAccessorPropertyToDictionaryPrototype();
+
+function TestRemovingPropertyFromDictionaryPrototype() {
+ let foo_func_called = 0;
+ let bar_func_called = 0;
+
+ function Foo() {}
+ Foo.prototype.func = function() { ++foo_func_called; }
+
+ function Bar() {}
+ Bar.prototype = Object.create(Foo.prototype);
+ EnsureDictionaryMode(Bar.prototype);
+ Bar.prototype.func = function() { ++bar_func_called; }
+
+ let o = new Bar();
+
+ for (let i = 0; i < 11; ++i) {
+ // First, the property is looked up from Bar.
+ o.func();
+
+ // Remove the property from Bar which is a dictionary-mode prototype between
+ // o and Foo. In the next iteration, it's looked up from Foo.
+ if (i == 9) {
+ delete Bar.prototype.func;
+ }
+ }
+
+ assertEquals(1, foo_func_called);
+ assertEquals(10, bar_func_called);
+}
+
+TestRemovingPropertyFromDictionaryPrototype();
+
+// Same as TestRemovingPropertyFromDictionaryPrototype, but using o["foo"] access
+// instead of o.foo.
+function TestRemovingPropertyFromDictionaryPrototype2() {
+ let foo_func_called = 0;
+ let bar_func_called = 0;
+ let name = "func";
+
+ function Foo() {}
+ Foo.prototype[name] = function() { ++foo_func_called; }
+
+ function Bar() {}
+ Bar.prototype = Object.create(Foo.prototype);
+ EnsureDictionaryMode(Bar.prototype);
+ Bar.prototype[name] = function() { ++bar_func_called; }
+
+ let o = new Bar();
+
+ for (let i = 0; i < 11; ++i) {
+ // First, the property is looked up from Bar.
+ o[name]();
+
+ // Remove the property from Bar which is a dictionary-mode prototype between
+ // o and Foo. In the next iteration, it's looked up from Foo.
+ if (i == 9) {
+ delete Bar.prototype[name];
+ }
+ }
+
+ assertEquals(1, foo_func_called);
+ assertEquals(10, bar_func_called);
+}
+
+TestRemovingPropertyFromDictionaryPrototype2();
+
+function TestAddingPropertyToDictionaryPrototype_Monomorphic() {
+ function DoMonomorphicStoreToPrototype(p, f, do_delete=true) {
+ p.func = f;
+ if (do_delete) {
+ delete p.func;
+ }
+ }
+
+ let foo_func_called = 0;
+ let bar_func_called = 0;
+
+ function Foo() {}
+ Foo.prototype.func = function() { ++foo_func_called; }
+
+ function Bar() {}
+ Bar.prototype = Object.create(Foo.prototype);
+ EnsureDictionaryMode(Bar.prototype);
+
+ function bar_func() {
+ ++bar_func_called;
+ }
+ DoMonomorphicStoreToPrototype(Bar.prototype, bar_func);
+ DoMonomorphicStoreToPrototype(Bar.prototype, bar_func);
+ DoMonomorphicStoreToPrototype(Bar.prototype, bar_func);
+
+ let o = new Bar();
+
+ for (let i = 0; i < 11; ++i) {
+ // First, the property is looked up from Foo.
+ o.func();
+
+ // Add the property to Bar which is a dictionary-mode prototype between o
+ // and Foo. In the next iteration, it's looked up from Bar.
+ if (i == 9) {
+ DoMonomorphicStoreToPrototype(Bar.prototype, bar_func, false);
+ }
+ }
+
+ assertEquals(10, foo_func_called);
+ assertEquals(1, bar_func_called);
+}
+
+TestAddingPropertyToDictionaryPrototype_Monomorphic();
+
+function TestAddingKeyedPropertyToDictionaryPrototype_Monomorphic() {
+ function DoMonomorphicKeyedStoreToPrototype(p, name, f, do_delete=true) {
+ p[name] = f;
+ if (do_delete) {
+ delete p[name];
+ }
+ }
+
+ let foo_func_called = 0;
+ let bar_func_called = 0;
+ let name = "func";
+
+ function Foo() {}
+ Foo.prototype[name] = function() { ++foo_func_called; }
+
+ function Bar() {}
+ Bar.prototype = Object.create(Foo.prototype);
+ EnsureDictionaryMode(Bar.prototype);
+
+ function bar_func() {
+ ++bar_func_called;
+ }
+ DoMonomorphicKeyedStoreToPrototype(Bar.prototype, name, bar_func);
+ DoMonomorphicKeyedStoreToPrototype(Bar.prototype, name, bar_func);
+ DoMonomorphicKeyedStoreToPrototype(Bar.prototype, name, bar_func);
+
+ let o = new Bar();
+
+ for (let i = 0; i < 11; ++i) {
+ // First, the property is looked up from Foo.
+ o.func();
+
+ // Add the property to Bar which is a dictionary-mode prototype between o
+ // and Foo. In the next iteration, it's looked up from Bar.
+ if (i == 9) {
+ DoMonomorphicKeyedStoreToPrototype(Bar.prototype, name, bar_func, false);
+ }
+ }
+
+ assertEquals(10, foo_func_called);
+ assertEquals(1, bar_func_called);
+}
+
+TestAddingKeyedPropertyToDictionaryPrototype_Monomorphic();
+
+// Like TestAddingPropertyToDictionaryPrototype, except that the prototype isn't
+// in dictionary mode yet, but turns to dictionary mode after the interesting
+// property is added.
+function TestAddingPropertyToAlmostDictionaryPrototype() {
+ let foo_func_called = 0;
+ let bar_func_called = 0;
+
+ function Foo() {}
+ Foo.prototype.func = function() { ++foo_func_called; }
+
+ function Bar() {}
+ Bar.prototype = Object.create(Foo.prototype);
+ EnsureAlmostDictionaryMode(Bar.prototype);
+
+ let o = new Bar();
+ for (let i = 0; i < 2; ++i) {
+ o.x0;
+ }
+ assertTrue(%HasFastProperties(Bar.prototype));
+
+ for (let i = 0; i < 11; ++i) {
+ // First, the property is looked up from Foo.
+ o.func();
+
+ // Add the property to Bar which will now turn permanently into dictionary
+ // mode. In the next iteration, it's looked up from Bar.
+ if (i == 9) {
+ Bar.prototype.func = function() { ++bar_func_called; }
+ assertFalse(%HasFastProperties(Bar.prototype));
+ }
+ }
+
+ assertEquals(10, foo_func_called);
+ assertEquals(1, bar_func_called);
+}
+
+TestAddingPropertyToAlmostDictionaryPrototype();
+
+function TestReconfiguringDataToAccessor() {
+ let setter_called = 0;
+
+ function Bar() {}
+ EnsureDictionaryMode(Bar.prototype);
+ let name = "prop";
+ Object.defineProperty(Bar.prototype, name,
+ {value: 1000, writable: true, configurable: true});
+
+ for (let i = 0; i < 11; ++i) {
+ let obj1 = new Bar();
+ if (i < 10) {
+ assertEquals(1000, obj1.prop);
+ } else {
+ assertEquals(3000, obj1.prop);
+ }
+
+ // Add the property into the object.
+ obj1.prop = 2000;
+ if (i < 10) {
+ assertEquals(2000, obj1.prop);
+ } else {
+ assertEquals(3000, obj1.prop);
+ }
+
+ // Make "prop" an accessor property in the prototype.
+ if (i == 9) {
+ Object.defineProperty(Bar.prototype, name,
+ {get: () => 3000,
+ set: function(val) { ++setter_called; }});
+ }
+ }
+ assertEquals(1, setter_called);
+}
+
+TestReconfiguringDataToAccessor();
diff --git a/deps/v8/test/mjsunit/es6/array-find.js b/deps/v8/test/mjsunit/es6/array-find.js
index 5f6ba4226b..9fed027c8f 100644
--- a/deps/v8/test/mjsunit/es6/array-find.js
+++ b/deps/v8/test/mjsunit/es6/array-find.js
@@ -234,6 +234,40 @@ assertEquals(22, a.find(function(val) { return 22 === val; }), undefined);
//
+// Test predicate is called for missing properties
+//
+(function() {
+ const obj = {
+ "0": 0,
+ "2": 2,
+ length: 3
+ };
+ const received = [];
+ const predicate = (v) => { received.push(v); return false; };
+ const found = Array.prototype.find.call(obj, predicate);
+ assertEquals(undefined, found);
+ assertArrayEquals([0, undefined, 2], received);
+})();
+
+
+//
+// Test predicate modifying array prototype
+//
+(function() {
+ const a = [0, , 2];
+ const received = [];
+ const predicate = (v) => {
+ a.__proto__ = null;
+ received.push(v);
+ return false;
+ };
+ const found = Array.prototype.find.call(a, predicate);
+ assertEquals(undefined, found);
+ assertArrayEquals([0, undefined, 2], received);
+})();
+
+
+//
// Test thisArg
//
(function() {
diff --git a/deps/v8/test/mjsunit/es6/array-findindex.js b/deps/v8/test/mjsunit/es6/array-findindex.js
index 716eb4e0db..d335c15108 100644
--- a/deps/v8/test/mjsunit/es6/array-findindex.js
+++ b/deps/v8/test/mjsunit/es6/array-findindex.js
@@ -234,6 +234,40 @@ assertEquals(3, a.findIndex(function(val) { return 24 === val; }));
//
+// Test predicate is called for missing properties
+//
+(function() {
+ const obj = {
+ "0": 0,
+ "2": 2,
+ length: 3
+ };
+ const received = [];
+ const predicate = (v) => { received.push(v); return false; };
+ const found = Array.prototype.findIndex.call(obj, predicate);
+ assertEquals(-1, found);
+ assertArrayEquals([0, undefined, 2], received);
+})();
+
+
+//
+// Test predicate modifying array prototype
+//
+(function() {
+ const a = [0, , 2];
+ const received = [];
+ const predicate = (v) => {
+ a.__proto__ = null;
+ received.push(v);
+ return false;
+ };
+ const found = Array.prototype.findIndex.call(a, predicate);
+ assertEquals(-1, found);
+ assertArrayEquals([0, undefined, 2], received);
+})();
+
+
+//
// Test thisArg
//
(function() {
diff --git a/deps/v8/test/mjsunit/es6/array-iterator-turbo.js b/deps/v8/test/mjsunit/es6/array-iterator-turbo.js
index 3a159b6337..489a53dbc7 100644
--- a/deps/v8/test/mjsunit/es6/array-iterator-turbo.js
+++ b/deps/v8/test/mjsunit/es6/array-iterator-turbo.js
@@ -3,7 +3,7 @@
// found in the LICENSE file.
// Flags: --turbo-escape --allow-natives-syntax --no-always-opt
-// Flags: --opt --turbo-filter=*
+// Flags: --opt --turbo-filter=* --no-force-slow-path
"use strict";
diff --git a/deps/v8/test/mjsunit/es6/call-with-spread-modify-next.js b/deps/v8/test/mjsunit/es6/call-with-spread-modify-next.js
index d22a1eaec0..3cae94ff9d 100644
--- a/deps/v8/test/mjsunit/es6/call-with-spread-modify-next.js
+++ b/deps/v8/test/mjsunit/es6/call-with-spread-modify-next.js
@@ -37,6 +37,8 @@
var r2 = testMax(1, 2);
- assertEquals(3, called);
+ // .next() is only loaded once during the iteration prologue (see
+ // https://github.com/tc39/ecma262/pull/988/ and v8:6861)
+ assertEquals(1, called);
assertEquals(2, r2);
})();
diff --git a/deps/v8/test/mjsunit/es6/computed-property-names-object-literals-methods.js b/deps/v8/test/mjsunit/es6/computed-property-names-object-literals-methods.js
index 36afbe2ced..24a357258a 100644
--- a/deps/v8/test/mjsunit/es6/computed-property-names-object-literals-methods.js
+++ b/deps/v8/test/mjsunit/es6/computed-property-names-object-literals-methods.js
@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --harmony-async-iteration
-
function ID(x) {
return x;
}
diff --git a/deps/v8/test/mjsunit/es6/destructuring-assignment.js b/deps/v8/test/mjsunit/es6/destructuring-assignment.js
index 579c87718b..dee7a0b16d 100644
--- a/deps/v8/test/mjsunit/es6/destructuring-assignment.js
+++ b/deps/v8/test/mjsunit/es6/destructuring-assignment.js
@@ -513,25 +513,31 @@ assertEquals(oz, [1, 2, 3, 4, 5]);
}
function FakeNewTarget() {}
- assertEquals(undefined, ReturnNewTarget1());
- assertEquals(ReturnNewTarget1, new ReturnNewTarget1());
- assertEquals(FakeNewTarget,
- Reflect.construct(ReturnNewTarget1, [], FakeNewTarget));
-
- assertEquals(undefined, ReturnNewTarget2());
- assertEquals(ReturnNewTarget2, new ReturnNewTarget2());
- assertEquals(FakeNewTarget,
- Reflect.construct(ReturnNewTarget2, [], FakeNewTarget));
-
- assertEquals(undefined, ReturnNewTarget3());
- assertEquals(ReturnNewTarget3, new ReturnNewTarget3());
- assertEquals(FakeNewTarget,
- Reflect.construct(ReturnNewTarget3, [], FakeNewTarget));
-
- assertEquals(undefined, ReturnNewTarget4());
- assertEquals(ReturnNewTarget4, new ReturnNewTarget4());
- assertEquals(FakeNewTarget,
- Reflect.construct(ReturnNewTarget4, [], FakeNewTarget));
+
+ function construct() {
+ assertEquals(undefined, ReturnNewTarget1());
+ assertEquals(ReturnNewTarget1, new ReturnNewTarget1());
+ assertEquals(FakeNewTarget,
+ Reflect.construct(ReturnNewTarget1, [], FakeNewTarget));
+
+ assertEquals(undefined, ReturnNewTarget2());
+ assertEquals(ReturnNewTarget2, new ReturnNewTarget2());
+ assertEquals(FakeNewTarget,
+ Reflect.construct(ReturnNewTarget2, [], FakeNewTarget));
+
+ assertEquals(undefined, ReturnNewTarget3());
+ assertEquals(ReturnNewTarget3, new ReturnNewTarget3());
+ assertEquals(FakeNewTarget,
+ Reflect.construct(ReturnNewTarget3, [], FakeNewTarget));
+
+ assertEquals(undefined, ReturnNewTarget4());
+ assertEquals(ReturnNewTarget4, new ReturnNewTarget4());
+ assertEquals(FakeNewTarget,
+ Reflect.construct(ReturnNewTarget4, [], FakeNewTarget));
+ }
+ construct();
+ FakeNewTarget.prototype = 1;
+ construct();
})();
(function testSuperCall() {
diff --git a/deps/v8/test/mjsunit/es6/iteration-semantics.js b/deps/v8/test/mjsunit/es6/iteration-semantics.js
index 558fb837e7..40037be6f5 100644
--- a/deps/v8/test/mjsunit/es6/iteration-semantics.js
+++ b/deps/v8/test/mjsunit/es6/iteration-semantics.js
@@ -220,13 +220,11 @@ assertThrows('fold(sum, 0, unreachable({}))', TypeError);
assertThrows('fold(sum, 0, unreachable(false))', TypeError);
assertThrows('fold(sum, 0, unreachable(37))', TypeError);
-// "next" is looked up each time.
-assertThrows('fold(sum, 0, remove_next_after(integers_until(10), 5))',
- TypeError);
-// It is not called at any other time.
+// "next" is looked up only once during the iteration prologue (see
+// https://github.com/tc39/ecma262/pull/988)
+assertEquals(45, fold(sum, 0, remove_next_after(integers_until(10), 5)));
assertEquals(45,
fold(sum, 0, remove_next_after(integers_until(10), 10)));
-// It is not looked up too many times.
assertEquals(45,
fold(sum, 0, poison_next_after(integers_until(10), 10)));
diff --git a/deps/v8/test/mjsunit/es6/reflect-construct.js b/deps/v8/test/mjsunit/es6/reflect-construct.js
index 03e8397a9b..34b6f27373 100644
--- a/deps/v8/test/mjsunit/es6/reflect-construct.js
+++ b/deps/v8/test/mjsunit/es6/reflect-construct.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: --allow-unsafe-function-constructor --harmony-async-iteration
+// Flags: --allow-unsafe-function-constructor
(function testReflectConstructArity() {
diff --git a/deps/v8/test/mjsunit/es6/spread-call.js b/deps/v8/test/mjsunit/es6/spread-call.js
index cdedd990c8..7403e0726e 100644
--- a/deps/v8/test/mjsunit/es6/spread-call.js
+++ b/deps/v8/test/mjsunit/es6/spread-call.js
@@ -376,6 +376,11 @@ testSpreadCallsStrict();
a[3] = 4;
var called = 0;
+ // .next method is only accessed during iteration prologue (see
+ // https://github.com/tc39/ecma262/pull/988)
+ let ArrayIteratorPrototype = Array.prototype[Symbol.iterator]().__proto__;
+ let ArrayIteratorPrototypeNextDescriptor =
+ Object.getOwnPropertyDescriptor(ArrayIteratorPrototype, 'next');
Object.defineProperty(Array.prototype, 2, {
get: function() {
var ai = a[Symbol.iterator]();
@@ -384,7 +389,8 @@ testSpreadCallsStrict();
get: function() {
called++;
return original_next;
- }
+ },
+ configurable: true
});
return 3;
},
@@ -392,8 +398,10 @@ testSpreadCallsStrict();
});
assertEquals(10, sum(...a));
- assertEquals(2, called);
+ assertEquals(0, called);
+ Object.defineProperty(ArrayIteratorPrototype, 'next',
+ ArrayIteratorPrototypeNextDescriptor);
Object.defineProperty(Array.prototype, 2, {});
})();
@@ -430,9 +438,9 @@ testSpreadCallsStrict();
countArgs(...a);
- // should be called 4 times; 3 for the values, 1 for the final
- // {value: undefined, done: true} pair
- assertEquals(4, called);
+ // .next method is only accessed during iteration prologue (see
+ // https://github.com/tc39/ecma262/pull/988)
+ assertEquals(1, called);
})();
(function testArrayIteratorPrototypeModified() {
diff --git a/deps/v8/test/mjsunit/es6/super-with-spread-modify-next.js b/deps/v8/test/mjsunit/es6/super-with-spread-modify-next.js
index 299917dbf1..cd7798b8d1 100644
--- a/deps/v8/test/mjsunit/es6/super-with-spread-modify-next.js
+++ b/deps/v8/test/mjsunit/es6/super-with-spread-modify-next.js
@@ -48,7 +48,9 @@
var r2 = testArgumentsPoint(1, 2);
- assertEquals(3, called);
+ // .next() is only loaded once during the iteration prologue (see
+ // https://github.com/tc39/ecma262/pull/988/ and v8:6861)
+ assertEquals(1, called);
assertInstanceof(r2, ArgumentsPoint);
assertInstanceof(r2, Point);
assertEquals(r2.x, 1);
diff --git a/deps/v8/test/mjsunit/es6/typedarray.js b/deps/v8/test/mjsunit/es6/typedarray.js
index 93d92097cd..02bd91c1e5 100644
--- a/deps/v8/test/mjsunit/es6/typedarray.js
+++ b/deps/v8/test/mjsunit/es6/typedarray.js
@@ -341,16 +341,30 @@ function TestTypedArray(constr, elementSize, typicalElement) {
// Modified %ArrayIteratorPrototype%.next() method is honoured (v8:5699)
const ArrayIteratorPrototype = Object.getPrototypeOf([][Symbol.iterator]());
+ const ArrayIteratorPrototypeNextDescriptor =
+ Object.getOwnPropertyDescriptor(ArrayIteratorPrototype, 'next');
const ArrayIteratorPrototypeNext = ArrayIteratorPrototype.next;
ArrayIteratorPrototype.next = function() {
return { done: true };
};
genArr = new constr([1, 2, 3]);
assertEquals(0, genArr.length);
+
ArrayIteratorPrototype.next = ArrayIteratorPrototypeNext;
- // Modified %ArrayIteratorPrototype%.next() during iteration is honoured as
- // well.
+ // Modified %ArrayIteratorPrototype%.next() is only loaded during the iterator
+ // prologue.
+ let nextMethod = ArrayIteratorPrototypeNext;
+ let getNextCount = 0;
+ Object.defineProperty(ArrayIteratorPrototype, 'next', {
+ get() {
+ getNextCount++;
+ return nextMethod;
+ },
+ set(v) { nextMethod = v; },
+ configurable: true
+ });
+
genArr = new constr(Object.defineProperty([1, , 3], 1, {
get() {
ArrayIteratorPrototype.next = function() {
@@ -359,9 +373,13 @@ function TestTypedArray(constr, elementSize, typicalElement) {
return 2;
}
}));
- assertEquals(2, genArr.length);
+ Object.defineProperty(ArrayIteratorPrototype, 'next',
+ ArrayIteratorPrototypeNextDescriptor);
+ assertEquals(1, getNextCount);
+ assertEquals(3, genArr.length);
assertEquals(1, genArr[0]);
assertEquals(2, genArr[1]);
+ assertEquals(3, genArr[2]);
ArrayIteratorPrototype.next = ArrayIteratorPrototypeNext;
}
diff --git a/deps/v8/test/mjsunit/es8/object-entries.js b/deps/v8/test/mjsunit/es8/object-entries.js
index c59d81c823..5c7e74e378 100644
--- a/deps/v8/test/mjsunit/es8/object-entries.js
+++ b/deps/v8/test/mjsunit/es8/object-entries.js
@@ -284,8 +284,8 @@ TestMutateDuringEnumeration();
HOLEY_DOUBLE_ELEMENTS: [ [, , NaN], [ ["2", NaN] ] ],
DICTIONARY_ELEMENTS: [ Object.defineProperties({ 10000: "world" }, {
- 100: { enumerable: true, value: "hello" },
- 99: { enumerable: false, value: "nope" }
+ 100: { enumerable: true, value: "hello", configurable: true},
+ 99: { enumerable: false, value: "nope", configurable: true}
}), [ ["100", "hello"], ["10000", "world" ] ] ],
FAST_SLOPPY_ARGUMENTS_ELEMENTS: [
fastSloppyArguments("a", "b", "c"),
@@ -298,17 +298,42 @@ TestMutateDuringEnumeration();
[ ["0", "s"], ["1", "t"], ["2", "r"]] ],
SLOW_STRING_WRAPPER_ELEMENTS: [
Object.defineProperties(new String("str"), {
- 10000: { enumerable: false, value: "X" },
- 9999: { enumerable: true, value: "Y" }
+ 10000: { enumerable: false, value: "X", configurable: true},
+ 9999: { enumerable: true, value: "Y", configurable: true}
}), [["0", "s"], ["1", "t"], ["2", "r"], ["9999", "Y"]] ],
};
for (let [kind, [object, expected]] of Object.entries(element_kinds)) {
let result1 = Object.entries(object);
+ %HeapObjectVerify(object);
+ %HeapObjectVerify(result1);
assertEquals(expected, result1, `fast Object.entries() with ${kind}`);
let proxy = new Proxy(object, {});
let result2 = Object.entries(proxy);
+ %HeapObjectVerify(result2);
assertEquals(result1, result2, `slow Object.entries() with ${kind}`);
}
+
+ function makeFastElements(array) {
+ // Remove all possible getters.
+ for (let k of Object.getOwnPropertyNames(this)) {
+ if (k == "length") continue;
+ delete this[k];
+ }
+ // Make the array large enough to trigger re-checking for compaction.
+ this[1000] = 1;
+ // Make the elements fast again.
+ Array.prototype.unshift.call(this, 1.1);
+ }
+
+ // Test that changing the elements kind is supported.
+ for (let [kind, [object, expected]] of Object.entries(element_kinds)) {
+ if (kind == "FAST_STRING_WRAPPER_ELEMENTS") break;
+ object.__defineGetter__(1, makeFastElements);
+ let result1 = Object.entries(object).toString();
+ %HeapObjectVerify(object);
+ %HeapObjectVerify(result1);
+ }
+
})();
diff --git a/deps/v8/test/mjsunit/es8/regress/regress-794744.js b/deps/v8/test/mjsunit/es8/regress/regress-794744.js
new file mode 100644
index 0000000000..a4dcb5d42a
--- /dev/null
+++ b/deps/v8/test/mjsunit/es8/regress/regress-794744.js
@@ -0,0 +1,8 @@
+// Copyright 2017 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.
+
+// Object.getOwnPropertyDescriptors loads %FunctionPrototype%.caller, an
+// accessor property which inspects the current callstack. Verify that this
+// callstack iteration doesn't crash when there are no JS frames on the stack.
+Promise.resolve(function () {}).then(Object.getOwnPropertyDescriptors);
diff --git a/deps/v8/test/mjsunit/global-prototypes.js b/deps/v8/test/mjsunit/global-prototypes.js
new file mode 100644
index 0000000000..98232c2814
--- /dev/null
+++ b/deps/v8/test/mjsunit/global-prototypes.js
@@ -0,0 +1,354 @@
+// Copyright 2017 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: --allow-natives-syntax
+
+
+assertEquals(this.__proto__, Object.prototype);
+
+function TestAddingPropertyToGlobalPrototype() {
+ let foo_func_called = 0;
+ let bar_func_called = 0;
+
+ function Foo() {}
+ Foo.prototype.func = function() { ++foo_func_called; }
+
+ delete this.func;
+ this.__proto__ = Foo.prototype;
+
+ function Bar() {}
+ Bar.prototype = this;
+
+ let o = new Bar();
+
+ for (let i = 0; i < 11; ++i) {
+ // First, the property is looked up from Foo.
+ o.func();
+
+ // Add the property to Bar which is a Global-mode prototype between o
+ // and Foo. In the next iteration, it's looked up from Bar.
+ if (i == 9) {
+ Bar.prototype.func = function() { ++bar_func_called; }
+ }
+ }
+
+ assertEquals(10, foo_func_called);
+ assertEquals(1, bar_func_called);
+}
+
+TestAddingPropertyToGlobalPrototype();
+
+
+// Same as TestAddingPropertyToGlobalPrototype, but using o["foo"] access
+// instead of o.foo.
+function TestAddingPropertyToGlobalPrototype2() {
+ let foo_func_called = 0;
+ let bar_func_called = 0;
+ let name = "func";
+
+ function Foo() {}
+ Foo.prototype[name] = function() { ++foo_func_called; }
+
+ delete this[name];
+ this.__proto__ = Foo.prototype;
+
+ function Bar() {}
+ Bar.prototype = this;
+
+ let o = new Bar();
+
+ for (let i = 0; i < 11; ++i) {
+ // First, the property is looked up from Foo.
+ o[name]();
+
+ // Add the property to Bar which is a Global-mode prototype between o
+ // and Foo. In the next iteration, it's looked up from Bar.
+ if (i == 9) {
+ Bar.prototype[name] = function() { ++bar_func_called; }
+ }
+ }
+
+ assertEquals(10, foo_func_called);
+ assertEquals(1, bar_func_called);
+}
+
+TestAddingPropertyToGlobalPrototype2();
+
+
+function TestAddingPropertyToGlobalPrototype_DefineProperty() {
+ let foo_func_called = 0;
+ let bar_func_called = 0;
+
+ function Foo() {}
+ Foo.prototype.func = function() { ++foo_func_called; }
+
+ delete this.func;
+ this.__proto__ = Foo.prototype;
+
+ function Bar() {}
+ Bar.prototype = this;
+
+ let o = new Bar();
+
+ for (let i = 0; i < 11; ++i) {
+ // First, the property is looked up from Foo.
+ o.func();
+
+ // Add the property to Bar which is a Global-mode prototype between o
+ // and Foo. In the next iteration, it's looked up from Bar.
+ if (i == 9) {
+ Object.defineProperty(Bar.prototype, "func",
+ {
+ value: function() { ++bar_func_called; },
+ configurable:true
+ });
+ }
+ }
+
+ assertEquals(10, foo_func_called);
+ assertEquals(1, bar_func_called);
+}
+
+TestAddingPropertyToGlobalPrototype_DefineProperty();
+
+
+function TestAddingAccessorPropertyToGlobalPrototype() {
+ let foo_func_called = 0;
+ let bar_func_called = 0;
+
+ function Foo() {}
+ Foo.prototype.func = function() { ++foo_func_called; }
+
+ delete this.func;
+ this.__proto__ = Foo.prototype;
+
+ function Bar() {}
+ Bar.prototype = this;
+
+ let o = new Bar();
+
+ for (let i = 0; i < 11; ++i) {
+ // First, the property is looked up from Foo.
+ o.func();
+
+ // Add the property to Bar which is a Global-mode prototype between o
+ // and Foo. In the next iteration, it's looked up from Bar.
+ if (i == 9) {
+ Object.defineProperty(Bar.prototype, "func",
+ {
+ get: function() { return function() { ++bar_func_called; }},
+ configurable: true
+ });
+ }
+ }
+
+ assertEquals(10, foo_func_called);
+ assertEquals(1, bar_func_called);
+}
+
+TestAddingAccessorPropertyToGlobalPrototype();
+
+
+function TestRemovingPropertyFromGlobalPrototype() {
+ let foo_func_called = 0;
+ let bar_func_called = 0;
+
+ function Foo() {}
+ Foo.prototype.func = function() { ++foo_func_called; }
+
+ delete this.func;
+ this.__proto__ = Foo.prototype;
+
+ function Bar() {}
+ Bar.prototype = this;
+ Bar.prototype.func = function() { ++bar_func_called; }
+
+ let o = new Bar();
+
+ for (let i = 0; i < 11; ++i) {
+ // First, the property is looked up from Bar.
+ o.func();
+
+ // Remove the property from Bar which is a Global-mode prototype between
+ // o and Foo. In the next iteration, it's looked up from Foo.
+ if (i == 9) {
+ delete Bar.prototype.func;
+ }
+ }
+
+ assertEquals(1, foo_func_called);
+ assertEquals(10, bar_func_called);
+}
+
+TestRemovingPropertyFromGlobalPrototype();
+
+
+// Same as TestRemovingPropertyFromGlobalPrototype, but using o["foo"] access
+// instead of o.foo.
+function TestRemovingPropertyFromGlobalPrototype2() {
+ let foo_func_called = 0;
+ let bar_func_called = 0;
+ let name = "func";
+
+ function Foo() {}
+ Foo.prototype[name] = function() { ++foo_func_called; }
+
+ this.__proto__ = Foo.prototype;
+
+ function Bar() {}
+ Bar.prototype = this;
+ Bar.prototype[name] = function() { ++bar_func_called; }
+
+ let o = new Bar();
+
+ for (let i = 0; i < 11; ++i) {
+ // First, the property is looked up from Bar.
+ o[name]();
+
+ // Remove the property from Bar which is a Global-mode prototype between
+ // o and Foo. In the next iteration, it's looked up from Foo.
+ if (i == 9) {
+ delete Bar.prototype[name];
+ }
+ }
+
+ assertEquals(1, foo_func_called);
+ assertEquals(10, bar_func_called);
+}
+
+TestRemovingPropertyFromGlobalPrototype2();
+
+
+function TestAddingPropertyToGlobalPrototype_MonomorphicDot() {
+ function DoMonomorphicStoreToPrototypeDot(p, f, do_delete=true) {
+ p.func = f;
+ if (do_delete) {
+ delete p.func;
+ }
+ }
+ let foo_func_called = 0;
+ let bar_func_called = 0;
+
+ function Foo() {}
+ Foo.prototype.func = function() { ++foo_func_called; }
+
+ delete this.func;
+ this.__proto__ = Foo.prototype;
+
+ function Bar() {}
+ Bar.prototype = this;
+
+ function bar_func() {
+ ++bar_func_called;
+ }
+ DoMonomorphicStoreToPrototypeDot(Bar.prototype, bar_func);
+ DoMonomorphicStoreToPrototypeDot(Bar.prototype, bar_func);
+ DoMonomorphicStoreToPrototypeDot(Bar.prototype, bar_func);
+
+ let o = new Bar();
+
+ for (let i = 0; i < 11; ++i) {
+ // First, the property is looked up from Foo.
+ o.func();
+
+ // Add the property to Bar which is a Global-mode prototype between o
+ // and Foo. In the next iteration, it's looked up from Bar.
+ if (i == 9) {
+ DoMonomorphicStoreToPrototypeDot(Bar.prototype, bar_func, false);
+ }
+ }
+
+ assertEquals(10, foo_func_called);
+ assertEquals(1, bar_func_called);
+}
+
+TestAddingPropertyToGlobalPrototype_MonomorphicDot();
+
+
+function TestAddingPropertyToGlobalPrototype_MonomorphicBrackets() {
+ function DoMonomorphicStoreToPrototypeBrackets(p, name, f, do_delete=true) {
+ p[name] = f;
+ if (do_delete) {
+ delete p[name];
+ }
+ }
+ let foo_func_called = 0;
+ let bar_func_called = 0;
+ let name = "func";
+
+ function Foo() {}
+ Foo.prototype[name] = function() { ++foo_func_called; }
+
+ delete this[name];
+ this.__proto__ = Foo.prototype;
+
+ function Bar() {}
+ Bar.prototype = this;
+
+ function bar_func() {
+ ++bar_func_called;
+ }
+ DoMonomorphicStoreToPrototypeBrackets(Bar.prototype, name, bar_func);
+ DoMonomorphicStoreToPrototypeBrackets(Bar.prototype, name, bar_func);
+ DoMonomorphicStoreToPrototypeBrackets(Bar.prototype, name, bar_func);
+
+ let o = new Bar();
+
+ for (let i = 0; i < 11; ++i) {
+ // First, the property is looked up from Foo.
+ o.func();
+
+ // Add the property to Bar which is a Global-mode prototype between o
+ // and Foo. In the next iteration, it's looked up from Bar.
+ if (i == 9) {
+ DoMonomorphicStoreToPrototypeBrackets(Bar.prototype, name, bar_func, false);
+ }
+ }
+
+ assertEquals(10, foo_func_called);
+ assertEquals(1, bar_func_called);
+}
+
+TestAddingPropertyToGlobalPrototype_MonomorphicBrackets();
+
+
+function TestReconfiguringDataToAccessor() {
+ let setter_called = 0;
+ let name = "prop";
+
+ delete this[name];
+ this.__proto__ = Object.prototype;
+
+ function Bar() {}
+ Bar.prototype = this;
+
+ Object.defineProperty(Bar.prototype, name, {value: 1000, writable: true, configurable: true});
+
+ for (let i = 0; i < 11; ++i) {
+ let obj1 = new Bar();
+ if (i < 10) {
+ assertEquals(1000, obj1.prop);
+ } else {
+ assertEquals(3000, obj1.prop);
+ }
+
+ // Add the property into the object.
+ obj1.prop = 2000;
+ if (i < 10) {
+ assertEquals(2000, obj1.prop);
+ } else {
+ assertEquals(3000, obj1.prop);
+ }
+
+ // Make "prop" an accessor property in the prototype.
+ if (i == 9) {
+ Object.defineProperty(Bar.prototype, name,
+ {get: () => 3000,
+ set: function(val) { ++setter_called; }});
+ }
+ }
+ assertEquals(1, setter_called);
+}
+
+TestReconfiguringDataToAccessor();
diff --git a/deps/v8/test/mjsunit/harmony/async-for-of-non-iterable.js b/deps/v8/test/mjsunit/harmony/async-for-of-non-iterable.js
index c84c9c6884..3394ed394c 100644
--- a/deps/v8/test/mjsunit/harmony/async-for-of-non-iterable.js
+++ b/deps/v8/test/mjsunit/harmony/async-for-of-non-iterable.js
@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --harmony-async-iteration
var done = false;
async function f() {
diff --git a/deps/v8/test/mjsunit/harmony/async-from-sync-iterator.js b/deps/v8/test/mjsunit/harmony/async-from-sync-iterator.js
index d965bd070c..a7b0d1bda4 100644
--- a/deps/v8/test/mjsunit/harmony/async-from-sync-iterator.js
+++ b/deps/v8/test/mjsunit/harmony/async-from-sync-iterator.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-async-iteration --allow-natives-syntax
+// Flags: --allow-natives-syntax
let testFailed = false;
let testFailure;
diff --git a/deps/v8/test/mjsunit/harmony/async-generators-basic.js b/deps/v8/test/mjsunit/harmony/async-generators-basic.js
index 29441b119b..d7af1836b8 100644
--- a/deps/v8/test/mjsunit/harmony/async-generators-basic.js
+++ b/deps/v8/test/mjsunit/harmony/async-generators-basic.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-async-iteration --allow-natives-syntax
+// Flags: --allow-natives-syntax
function assertThrowsAsync(run, errorType, message) {
var actual;
diff --git a/deps/v8/test/mjsunit/harmony/async-generators-resume-return.js b/deps/v8/test/mjsunit/harmony/async-generators-resume-return.js
index 7a7efe7801..715c81fc21 100644
--- a/deps/v8/test/mjsunit/harmony/async-generators-resume-return.js
+++ b/deps/v8/test/mjsunit/harmony/async-generators-resume-return.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-async-iteration --allow-natives-syntax
+// Flags: --allow-natives-syntax
// .return() from state suspendedStart with undefined
testAsync(test => {
diff --git a/deps/v8/test/mjsunit/harmony/async-generators-return.js b/deps/v8/test/mjsunit/harmony/async-generators-return.js
index b0c7febf8c..27cbd4373b 100644
--- a/deps/v8/test/mjsunit/harmony/async-generators-return.js
+++ b/deps/v8/test/mjsunit/harmony/async-generators-return.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-async-iteration --allow-natives-syntax
+// Flags: --allow-natives-syntax
testAsync(test => {
test.plan(2);
diff --git a/deps/v8/test/mjsunit/harmony/async-generators-yield.js b/deps/v8/test/mjsunit/harmony/async-generators-yield.js
index c999c7006f..feb6339af2 100644
--- a/deps/v8/test/mjsunit/harmony/async-generators-yield.js
+++ b/deps/v8/test/mjsunit/harmony/async-generators-yield.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-async-iteration --allow-natives-syntax
+// Flags: --allow-natives-syntax
// Yield a thenable which is never settled
testAsync(test => {
diff --git a/deps/v8/test/mjsunit/harmony/bigint/as-int-n.js b/deps/v8/test/mjsunit/harmony/bigint/as-int-n.js
index 08c94245fd..faa7dba866 100644
--- a/deps/v8/test/mjsunit/harmony/bigint/as-int-n.js
+++ b/deps/v8/test/mjsunit/harmony/bigint/as-int-n.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-bigint --noopt
+// Flags: --harmony-bigint
// BigInt.asIntN
{
@@ -145,6 +145,8 @@
}{
assertThrows(() => BigInt.asIntN(3, 12), TypeError);
assertEquals(-4n, BigInt.asIntN(3, "12"));
+ assertEquals(0x123456789abcdefn,
+ BigInt.asIntN(64, 0xabcdef0123456789abcdefn));
}
// BigInt.asUintN
@@ -244,10 +246,9 @@
assertEquals(9223372036854775808n - 42n, BigInt.asUintN(63, -42n));
assertEquals(18446744073709551616n - 42n, BigInt.asUintN(64, -42n));
assertEquals(36893488147419103232n - 42n, BigInt.asUintN(65, -42n));
- // TODO(neis): Enable once we have exponentation.
- // assertEquals(2n**127n - 42n, BigInt.asUintN(127, -42n));
- // assertEquals(2n**128n - 42n, BigInt.asUintN(128, -42n));
- // assertEquals(2n**129n - 42n, BigInt.asUintN(129, -42n));
+ assertEquals(2n**127n - 42n, BigInt.asUintN(127, -42n));
+ assertEquals(2n**128n - 42n, BigInt.asUintN(128, -42n));
+ assertEquals(2n**129n - 42n, BigInt.asUintN(129, -42n));
}{
assertEquals(0n, BigInt.asUintN(0, 4294967295n));
assertEquals(1n, BigInt.asUintN(1, 4294967295n));
@@ -274,10 +275,9 @@
BigInt.asUintN(64,-4294967295n));
assertEquals(36893488147419103232n - 4294967295n,
BigInt.asUintN(65, -4294967295n));
- // TODO(neis): Enable once we have exponentation.
- // assertEquals(2n**127n - 42n, BigInt.asUintN(127, -4294967295n));
- // assertEquals(2n**128n - 42n, BigInt.asUintN(128, -4294967295n));
- // assertEquals(2n**129n - 42n, BigInt.asUintN(129, -4294967295n));
+ assertEquals(2n**127n - 4294967295n, BigInt.asUintN(127, -4294967295n));
+ assertEquals(2n**128n - 4294967295n, BigInt.asUintN(128, -4294967295n));
+ assertEquals(2n**129n - 4294967295n, BigInt.asUintN(129, -4294967295n));
}{
assertEquals(42n, BigInt.asUintN(2**32, 42n));
assertEquals(4294967295n, BigInt.asUintN(2**32, 4294967295n));
diff --git a/deps/v8/test/mjsunit/harmony/bigint/basics.js b/deps/v8/test/mjsunit/harmony/bigint/basics.js
index 5ea89009a3..398d670ca8 100644
--- a/deps/v8/test/mjsunit/harmony/bigint/basics.js
+++ b/deps/v8/test/mjsunit/harmony/bigint/basics.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: --allow-natives-syntax --harmony-bigint --no-opt
+// Flags: --allow-natives-syntax --harmony-bigint
'use strict'
@@ -105,14 +105,6 @@ const six = BigInt(6);
assertTrue(typeof 1n === "bigint");
assertFalse(typeof 1n === "BigInt");
assertFalse(typeof 1 === "bigint");
-}{
- // TODO(neis): Enable once --no-opt can be removed.
- //
- // function Typeof(x) { return typeof x }
- // assertEquals(Typeof(zero), "bigint");
- // assertEquals(Typeof(zero), "bigint");
- // %OptimizeFunctionOnNextCall(Typeof);
- // assertEquals(Typeof(zero), "bigint");
}
// ToString
diff --git a/deps/v8/test/mjsunit/harmony/bigint/comparisons.js b/deps/v8/test/mjsunit/harmony/bigint/comparisons.js
index 7be5eb7ee5..513ff37d00 100644
--- a/deps/v8/test/mjsunit/harmony/bigint/comparisons.js
+++ b/deps/v8/test/mjsunit/harmony/bigint/comparisons.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: --allow-natives-syntax --harmony-bigint --no-opt
+// Flags: --allow-natives-syntax --harmony-bigint
'use strict'
diff --git a/deps/v8/test/mjsunit/harmony/bigint/dec.js b/deps/v8/test/mjsunit/harmony/bigint/dec.js
index cdf1d96d60..5e1f40b2dd 100644
--- a/deps/v8/test/mjsunit/harmony/bigint/dec.js
+++ b/deps/v8/test/mjsunit/harmony/bigint/dec.js
@@ -6,9 +6,6 @@
// Flags: --harmony-bigint
-// TODO(adamk/jkummerow/neis): Support BigInts in TF unary ops.
-// Flags: --noopt
-
var data = [{
a: "-609648ccf253976b12f6b6c8e20790c17ef6b89ea9f536267783607cf465b1ca",
r: "-609648ccf253976b12f6b6c8e20790c17ef6b89ea9f536267783607cf465b1cb"
diff --git a/deps/v8/test/mjsunit/harmony/bigint/exp.js b/deps/v8/test/mjsunit/harmony/bigint/exp.js
new file mode 100644
index 0000000000..5a4601134f
--- /dev/null
+++ b/deps/v8/test/mjsunit/harmony/bigint/exp.js
@@ -0,0 +1,43 @@
+// Copyright 2017 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: --allow-natives-syntax --harmony-bigint
+
+assertEquals(1n, 0n ** 0n);
+assertEquals(0n, 0n ** 1n);
+assertEquals(0n, 0n ** 23n);
+
+assertEquals(1n, 1n ** 0n);
+assertEquals(1n, 1n ** 1n);
+assertEquals(1n, 99n ** 0n);
+
+assertEquals(2n, 2n ** 1n);
+assertEquals(4n, 2n ** 2n);
+assertEquals(8n, 2n ** 3n);
+assertEquals(16n, 2n ** 4n);
+assertEquals(151115727451828646838272n, 2n ** 77n);
+
+assertEquals(3n, 3n ** 1n);
+assertEquals(9n, 3n ** 2n);
+assertEquals(27n, 3n ** 3n);
+assertEquals(81n, 3n ** 4n);
+assertEquals(243n, 3n ** 5n);
+assertEquals(30903154382632612361920641803529n, 3n ** 66n);
+
+assertEquals(1n, (-2n) ** 0n);
+assertEquals(-2n, (-2n) ** 1n);
+assertEquals(4n, (-2n) ** 2n);
+assertEquals(-8n, (-2n) ** 3n);
+assertEquals(16n, (-2n) ** 4n);
+assertEquals(-32n, (-2n) ** 5n);
+
+assertEquals(1n, (-3n) ** 0n);
+assertEquals(-3n, (-3n) ** 1n);
+assertEquals(9n, (-3n) ** 2n);
+assertEquals(-27n, (-3n) ** 3n);
+assertEquals(81n, (-3n) ** 4n);
+assertEquals(-243n, (-3n) ** 5n);
+
+assertThrows(() => 3n ** -2n, RangeError); // Negative exponent.
+assertThrows(() => 2n ** (1024n ** 4n), RangeError); // Too big.
diff --git a/deps/v8/test/mjsunit/harmony/bigint/inc.js b/deps/v8/test/mjsunit/harmony/bigint/inc.js
index 2773ed9110..64865a2b32 100644
--- a/deps/v8/test/mjsunit/harmony/bigint/inc.js
+++ b/deps/v8/test/mjsunit/harmony/bigint/inc.js
@@ -6,9 +6,6 @@
// Flags: --harmony-bigint
-// TODO(adamk/jkummerow/neis): Support BigInts in TF unary ops.
-// Flags: --noopt
-
var data = [{
a: "-989c298c6fc3",
r: "-989c298c6fc2"
diff --git a/deps/v8/test/mjsunit/harmony/bigint/json.js b/deps/v8/test/mjsunit/harmony/bigint/json.js
index 10afdfce02..eb0eefc4bb 100644
--- a/deps/v8/test/mjsunit/harmony/bigint/json.js
+++ b/deps/v8/test/mjsunit/harmony/bigint/json.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: --allow-natives-syntax --harmony-bigint --no-opt
+// Flags: --allow-natives-syntax --harmony-bigint
'use strict'
diff --git a/deps/v8/test/mjsunit/harmony/bigint/neg.js b/deps/v8/test/mjsunit/harmony/bigint/neg.js
index 75548f62c3..8cec9cc21b 100644
--- a/deps/v8/test/mjsunit/harmony/bigint/neg.js
+++ b/deps/v8/test/mjsunit/harmony/bigint/neg.js
@@ -6,9 +6,6 @@
// Flags: --harmony-bigint
-// TODO(adamk/jkummerow/neis): Support BigInts in TF unary ops.
-// Flags: --noopt
-
var data = [{
a: "58ad59aa3aa9d04d4c12493966e204ef0500d5f92ecb31",
r: "-58ad59aa3aa9d04d4c12493966e204ef0500d5f92ecb31"
diff --git a/deps/v8/test/mjsunit/harmony/bigint/not.js b/deps/v8/test/mjsunit/harmony/bigint/not.js
index fe23c8f965..7ceaa01e63 100644
--- a/deps/v8/test/mjsunit/harmony/bigint/not.js
+++ b/deps/v8/test/mjsunit/harmony/bigint/not.js
@@ -6,9 +6,6 @@
// Flags: --harmony-bigint
-// TODO(adamk/jkummerow/neis): Support BigInts in TF unary ops.
-// Flags: --noopt
-
var data = [{
a: "3d02c87edc77722299f6559ecca038911f864a4e78c20af80f4a6d9",
r: "-3d02c87edc77722299f6559ecca038911f864a4e78c20af80f4a6da"
diff --git a/deps/v8/test/mjsunit/harmony/bigint/regressions.js b/deps/v8/test/mjsunit/harmony/bigint/regressions.js
index 45c8816fe7..3057fe1230 100644
--- a/deps/v8/test/mjsunit/harmony/bigint/regressions.js
+++ b/deps/v8/test/mjsunit/harmony/bigint/regressions.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-bigint --noopt
+// Flags: --harmony-bigint
var a = 5n;
var b = a / -1n;
@@ -16,3 +16,5 @@ assertEquals(0n, 5n % 1n);
assertEquals(0n, -5n % 1n);
assertEquals(0n, 5n % -1n);
assertEquals(0n, -5n % -1n);
+
+assertTrue(0n === 0n);
diff --git a/deps/v8/test/mjsunit/harmony/bigint/tonumber.js b/deps/v8/test/mjsunit/harmony/bigint/tonumber.js
index 0061d91d67..d2802a79be 100644
--- a/deps/v8/test/mjsunit/harmony/bigint/tonumber.js
+++ b/deps/v8/test/mjsunit/harmony/bigint/tonumber.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-bigint --no-opt
+// Flags: --harmony-bigint
function Check(bigint, number_string) {
var number = Number(number_string);
diff --git a/deps/v8/test/mjsunit/harmony/bigint/too-big-literal.js b/deps/v8/test/mjsunit/harmony/bigint/too-big-literal.js
deleted file mode 100644
index 242700191a..0000000000
--- a/deps/v8/test/mjsunit/harmony/bigint/too-big-literal.js
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2017 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-bigint --no-opt
-
-const MAX_BIGINT_BITS = 1024 * 1024; // Matches BigInt::kMaxLengthBits
-const MAX_BIGINT_CHARS = MAX_BIGINT_BITS / 4;
-
-const TOO_MANY_ONES = Array(MAX_BIGINT_CHARS + 2).join("1") + "n";
-
-const tooBigHex = "0x" + TOO_MANY_ONES;
-
-assertThrows(tooBigHex, SyntaxError);
diff --git a/deps/v8/test/mjsunit/harmony/bigint/turbo.js b/deps/v8/test/mjsunit/harmony/bigint/turbo.js
new file mode 100644
index 0000000000..87130ea101
--- /dev/null
+++ b/deps/v8/test/mjsunit/harmony/bigint/turbo.js
@@ -0,0 +1,193 @@
+// Copyright 2017 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: --allow-natives-syntax --harmony-bigint
+
+'use strict'
+
+
+function test(f, {input, check}) {
+ let result;
+ try {
+ result = { value: f(input), exception: false }
+ } catch(e) {
+ result = { value: e, exception: true }
+ }
+ check(result);
+}
+
+function Test(f, ...cases) {
+ for (let i = 0; i < cases.length; ++i) {
+ test(f, cases[i]);
+ %OptimizeFunctionOnNextCall(f);
+ for (let j = 0; j < cases.length; ++j) {
+ test(f, cases[j]);
+ }
+ %DeoptimizeFunction(f);
+ }
+}
+
+
+function V(input, expected_value) {
+ function check(result) {
+ assertFalse(result.exception, input);
+ assertEquals(expected_value, result.value);
+ }
+ return {input, check};
+}
+
+function E(input, expected_exception) {
+ function check(result) {
+ assertTrue(result.exception, input);
+ assertInstanceof(result.value, expected_exception);
+ }
+ return {input, check};
+}
+
+
+const six = {[Symbol.toPrimitive]() {return 6n}};
+
+
+////////////////////////////////////////////////////////////////////////////////
+// The first argument to {Test} is the function to test. The other arguments are
+// the test cases, basically pairs of input and expected output. {Test} runs the
+// function first unoptimized on one of the inputs, and then optimized on all
+// inputs.
+////////////////////////////////////////////////////////////////////////////////
+
+
+Test(x => Number(x),
+ V(1n, 1), V(1, 1), V("", 0), V(1.4, 1.4), V(null, 0), V(six, 6));
+
+Test(x => String(x),
+ V(1n, "1"), V(1, "1"), V(1.4, "1.4"), V(null, "null"), V(six, "6"));
+
+Test(x => BigInt(x),
+ V(true, 1n), V(false, 0n), V(42n, 42n), E(NaN, RangeError), V(six, 6n));
+
+Test(x => typeof x,
+ V(1n, "bigint"), V(1, "number"), V(six, "object"));
+Test(x => typeof x == "bigint",
+ V(1n, true), V(1, false), V(six, false));
+
+Test(x => !x,
+ V(0n, true), V(42n, false), V(0x10000000000000000n, false), V(1, false),
+ V(undefined, true), V(six, false));
+Test(x => !!x,
+ V(0n, false), V(42n, true), V(0x10000000000000000n, true), V(1, true),
+ V(undefined, false), V(six, true));
+
+Test(x => +x,
+ E(-3n, TypeError), V(-4, -4), V(1.4, 1.4), V(null, 0), V("5", 5),
+ E(six, TypeError));
+
+Test(x => -x,
+ V(-3n, 3n), V(-4, 4), V(1.4, -1.4), V(null, -0), V("5", -5), V(six, -6n));
+
+Test(x => ~x,
+ V(-3n, 2n), V(-4, 3), V(1.5, -2), V(null, -1), V("5", -6), V(six, -7n));
+
+Test(x => ++x,
+ V(-3n, -2n), V(-4, -3), V(1.5, 2.5), V(null, 1), V("5", 6), V(six, 7n));
+
+Test(x => --x,
+ V(-3n, -4n), V(-4, -5), V(1.5, 0.5), V(null, -1), V("5", 4), V(six, 5n));
+
+Test(x => x++,
+ V(-3n, -3n), V(-4, -4), V(1.5, 1.5), V(null, 0), V("5", 5), V(six, 6n));
+
+Test(x => x--,
+ V(-3n, -3n), V(-4, -4), V(1.5, 1.5), V(null, 0), V("5", 5), V(six, 6n));
+
+Test(x => x + 42,
+ E(1n, TypeError), V(2, 44), V(null, 42), V("a", "a42"), E(six, TypeError));
+Test(x => x + 42n,
+ V(1n, 43n), E(2, TypeError), E(null, TypeError), V("a", "a42"), V(six,48n));
+
+Test(x => x - 4,
+ E(1n, TypeError), V(3, -1), V(null, -4), V("a", NaN), E(six, TypeError));
+Test(x => x - 4n,
+ V(1n, -3n), E(3, TypeError), E(null, TypeError), E("a", TypeError),
+ V(six, 2n));
+
+Test(x => x * 42,
+ E(2n, TypeError), V(3, 126), V("a", NaN), V(null, 0), E(six, TypeError));
+Test(x => x * 42n,
+ V(2n, 84n), E(3, TypeError), E("a", TypeError), E(null, TypeError),
+ V(six, 252n));
+
+Test(x => x / 2,
+ E(2n, TypeError), V(6, 3), V("a", NaN), V(null, 0), E(six, TypeError));
+Test(x => x / 2n,
+ V(2n, 1n), E(6, TypeError), E("a", TypeError), E(null, TypeError),
+ V(six, 3n));
+
+Test(x => x % 2,
+ E(2n, TypeError), V(3, 1), V("a", NaN), V(null, 0), E(six, TypeError));
+Test(x => x % 2n,
+ V(2n, 0n), E(3, TypeError), E("a", TypeError), E(null, TypeError),
+ V(six, 0n));
+
+Test(x => x | 5,
+ E(2n, TypeError), V(3, 7), V("a", 5), V(null, 5), E(six, TypeError));
+Test(x => x | 5n,
+ V(2n, 7n), E(3, TypeError), E("a", TypeError), E(null, TypeError),
+ V(six, 7n));
+
+Test(x => x & 5,
+ E(2n, TypeError), V(3, 1), V("a", 0), V(null, 0), E(six, TypeError));
+Test(x => x & 5n,
+ V(2n, 0n), E(3, TypeError), E("a", TypeError), E(null, TypeError),
+ V(six, 4n));
+
+Test(x => x ^ 5,
+ E(2n, TypeError), V(3, 6), V("a", 5), V(null, 5), E(six, TypeError));
+Test(x => x ^ 5n,
+ V(2n, 7n), E(3, TypeError), E("a", TypeError), E(null, TypeError),
+ V(six, 3n));
+
+Test(x => x << 3,
+ E(2n, TypeError), V(3, 24), V("a", 0), V(null, 0), E(six, TypeError));
+Test(x => x << 3n,
+ V(2n, 16n), E(3, TypeError), E("a", TypeError), E(null, TypeError),
+ V(six, 48n));
+
+Test(x => x >> 1,
+ E(2n, TypeError), V(3, 1), V("a", 0), V(null, 0), E(six, TypeError));
+Test(x => x >> 1n,
+ V(2n, 1n), E(3, TypeError), E("a", TypeError), E(null, TypeError),
+ V(six, 3n));
+
+Test(x => x >>> 1,
+ E(2n, TypeError), V(3, 1), V("a", 0), V(null, 0), E(six, TypeError));
+Test(x => x >>> 1n,
+ E(2n, TypeError), E(3, TypeError), E("a", TypeError), E(null, TypeError),
+ E(six, TypeError));
+
+Test(x => x === 42,
+ V(1n, false), V(2, false), V(null, false), V("a", false), V(six, false));
+Test(x => x === 42,
+ V(42n, false), V(42, true), V(null, false), V("42", false), V(six, false));
+Test(x => x === 42n,
+ V(1n, false), V(2, false), V(null, false), V("a", false), V(six, false));
+Test(x => x === 42n,
+ V(42n, true), V(42, false), V(null, false), V("42", false), V(six, false));
+
+Test(x => x == 42,
+ V(1n, false), V(2, false), V(null, false), V("a", false), V(six, false));
+Test(x => x == 42,
+ V(42n, true), V(42, true), V(null, false), V("42", true), V(six, false));
+Test(x => x == 42n,
+ V(1n, false), V(2, false), V(null, false), V("a", false), V(six, false));
+Test(x => x == 42n,
+ V(42n, true), V(42, true), V(null, false), V("42", true), V(six, false));
+
+Test(x => x < 42,
+ V(1n, true), V(2, true), V(null, true), V("41", true), V(six, true));
+Test(x => x < 42,
+ V(42n, false), V(42, false), V(null, true), V("42", false), V(six, true));
+Test(x => x < 42n,
+ V(1n, true), V(2, true), V(null, true), V("41", true), V(six, true));
+Test(x => x < 42n,
+ V(42n, false), V(42, false), V(null, true), V("42", false), V(six, true));
diff --git a/deps/v8/test/mjsunit/harmony/for-await-of.js b/deps/v8/test/mjsunit/harmony/for-await-of.js
index efcfdab2ea..e23758a5e1 100644
--- a/deps/v8/test/mjsunit/harmony/for-await-of.js
+++ b/deps/v8/test/mjsunit/harmony/for-await-of.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-async-iteration --allow-natives-syntax
+// Flags: --allow-natives-syntax
let testFailed = false;
let testFailure;
diff --git a/deps/v8/test/mjsunit/harmony/modules-import-15.js b/deps/v8/test/mjsunit/harmony/modules-import-15.js
index ac33cd50b2..32255ce980 100644
--- a/deps/v8/test/mjsunit/harmony/modules-import-15.js
+++ b/deps/v8/test/mjsunit/harmony/modules-import-15.js
@@ -29,7 +29,8 @@ async function test2() {
} catch(e) {
assertInstanceof(e, SyntaxError);
assertEquals(
- "The requested module does not provide an export named 'default'",
+ "The requested module 'modules-skip-empty.js' does not provide an " +
+ "export named 'default'",
e.message);
ran = true;
}
diff --git a/deps/v8/test/mjsunit/harmony/optional-catch-binding-breaks.js b/deps/v8/test/mjsunit/harmony/optional-catch-binding-breaks.js
new file mode 100644
index 0000000000..82be60cda1
--- /dev/null
+++ b/deps/v8/test/mjsunit/harmony/optional-catch-binding-breaks.js
@@ -0,0 +1,65 @@
+// Copyright 2017 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-optional-catch-binding
+
+let state = 'initial';
+x: try {
+ throw new Error('caught');
+ state = 'unreachable';
+} catch {
+ assertEquals(state, 'initial');
+ state = 'caught';
+ break x;
+ state = 'unreachable';
+}
+assertEquals(state, 'caught');
+
+
+state = 'initial';
+x: try {
+ throw new Error('caught');
+ state = 'unreachable';
+} catch {
+ assertEquals(state, 'initial');
+ state = 'caught';
+ break x;
+ state = 'unreachable';
+} finally {
+ assertEquals(state, 'caught');
+ state = 'finally';
+}
+assertEquals(state, 'finally');
+
+
+state = 'initial';
+x: {
+ y: try {
+ throw new Error('caught');
+ state = 'unreachable';
+ } catch {
+ assertEquals(state, 'initial');
+ state = 'caught';
+ break x;
+ state = 'unreachable';
+ } finally {
+ assertEquals(state, 'caught');
+ state = 'finally';
+ break y;
+ state = 'unreachable';
+ }
+ assertEquals(state, 'finally');
+ state = 'after block';
+}
+assertEquals(state, 'after block');
+
+
+do {
+ try {
+ throw new Error();
+ } catch {
+ break;
+ }
+ assertUnreachable();
+} while(false);
diff --git a/deps/v8/test/mjsunit/harmony/optional-catch-binding.js b/deps/v8/test/mjsunit/harmony/optional-catch-binding.js
new file mode 100644
index 0000000000..093288c4e6
--- /dev/null
+++ b/deps/v8/test/mjsunit/harmony/optional-catch-binding.js
@@ -0,0 +1,39 @@
+// Copyright 2017 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-optional-catch-binding
+
+let state = 'initial';
+try {
+ throw new Error('caught');
+ state = 'unreachable';
+} catch { // Note the lack of a binding
+ assertEquals(state, 'initial');
+ state = 'caught';
+}
+assertEquals(state, 'caught');
+
+
+let sigil1 = {};
+try {
+ throw sigil1;
+} catch (e) {
+ assertEquals(e, sigil1);
+}
+
+
+let sigil2 = {};
+let reached = false;
+try {
+ try {
+ throw sigil1;
+ } catch {
+ reached = true;
+ } finally {
+ throw sigil2;
+ }
+} catch (e) {
+ assertEquals(e, sigil2);
+}
+assertTrue(reached);
diff --git a/deps/v8/test/mjsunit/harmony/promise-prototype-finally.js b/deps/v8/test/mjsunit/harmony/promise-prototype-finally.js
index 3668ab5538..4e91f2e6d1 100644
--- a/deps/v8/test/mjsunit/harmony/promise-prototype-finally.js
+++ b/deps/v8/test/mjsunit/harmony/promise-prototype-finally.js
@@ -605,3 +605,13 @@ testAsync(assert => {
.then(() => assert.equals(1, value));
}, "PromiseResolve-ordering");
+
+(function testIsObject() {
+ var called = false;
+ var p = new Proxy(Promise.resolve(), {});
+ var oldThen = Promise.prototype.then;
+ Promise.prototype.then = () => called = true;
+ Promise.prototype.finally.call(p);
+ assertTrue(called);
+ Promise.prototype.then = oldThen;
+})();
diff --git a/deps/v8/test/mjsunit/harmony/public-instance-class-fields.js b/deps/v8/test/mjsunit/harmony/public-instance-class-fields.js
index acf0f13a99..a82a0ac919 100644
--- a/deps/v8/test/mjsunit/harmony/public-instance-class-fields.js
+++ b/deps/v8/test/mjsunit/harmony/public-instance-class-fields.js
@@ -52,16 +52,8 @@
b = x;
c = 1;
hasOwnProperty() { return 1;}
- static [x] = 2;
- static b = 3;
- static d;
}
- assertEquals(2, C.a);
- assertEquals(3, C.b);
- assertEquals(undefined, C.d);
- assertEquals(undefined, C.c);
-
let c = new C;
assertEquals(undefined, c.a);
assertEquals('a', c.b);
@@ -270,7 +262,7 @@
let c = new C;
assertEquals(1, c.a);
assertEquals(undefined, c.b);
- assertEquals(undefined, c.c1);
+ assertEquals(undefined, c[c1]);
}
{
@@ -281,10 +273,10 @@
}
class C {
- [run(1)] = run(7);
- [run(2)] = run(8);
+ [run(1)] = run(6);
+ [run(2)] = run(7);
[run(3)]() { run(9);}
- static [run(4)] = run(6);
+ [run(4)] = run(8);
[run(5)]() { throw new Error('should not execute');};
}
@@ -303,10 +295,10 @@ function x() {
}
class C {
- [run(1)] = run(7);
- [run(2)] = run(8);
+ [run(1)] = run(6);
+ [run(2)] = run(7);
[run(3)]() { run(9);}
- static [run(4)] = run(6);
+ [run(4)] = run(8);
[run(5)]() { throw new Error('should not execute');};
}
@@ -315,7 +307,7 @@ function x() {
assertEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], log);
}
}
-x();
+x()();
{
class C {}
@@ -637,20 +629,6 @@ x();
}
{
- function t() {
- return class {
- ['x'] = 1;
- static ['x'] = 2;
- }
- }
-
- let klass = t();
- let obj = new klass;
- assertEquals(1, obj.x);
- assertEquals(2, klass.x);
-}
-
-{
new class {
t = 1;
constructor(t = this.t) {
@@ -674,3 +652,47 @@ x();
}
}, ReferenceError);
}
+
+{
+ class X {
+ p = function() { return arguments[0]; }
+ }
+
+ let x = new X;
+ assertEquals(1, x.p(1));
+}
+
+{
+ class X {
+ t = () => {
+ function p() { return arguments[0]; };
+ return p;
+ }
+ }
+
+ let x = new X;
+ let p = x.t();
+ assertEquals(1, p(1));
+}
+
+{
+ class X {
+ t = () => {
+ function p() { return eval("arguments[0]"); };
+ return p;
+ }
+ }
+
+ let x = new X;
+ let p = x.t();
+ assertEquals(1, p(1));
+}
+
+{
+ class X {
+ p = eval("(function() { return arguments[0]; })(1)");
+ }
+
+ let x = new X;
+ assertEquals(1, x.p);
+}
diff --git a/deps/v8/test/mjsunit/harmony/public-static-class-fields.js b/deps/v8/test/mjsunit/harmony/public-static-class-fields.js
index 0477e3dca7..3de3e2d9d2 100644
--- a/deps/v8/test/mjsunit/harmony/public-static-class-fields.js
+++ b/deps/v8/test/mjsunit/harmony/public-static-class-fields.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-public-fields
+// Flags: --harmony-public-fields --harmony-static-fields
"use strict";
@@ -262,7 +262,7 @@
assertEquals(1, C.a);
assertEquals(undefined, C.b);
- assertEquals(undefined, C.c);
+ assertEquals(undefined, C[c]);
}
{
@@ -310,7 +310,51 @@ function x() {
assertEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], log);
}
}
-x();
+x()();
+
+{
+ let log = [];
+ function run(i) {
+ log.push(i);
+ return i;
+ }
+
+ class C {
+ [run(1)] = run(7);
+ [run(2)] = run(8);
+ [run(3)]() { run(9);}
+ static [run(4)] = run(6);
+ [run(5)]() { throw new Error('should not execute');};
+ }
+
+ let c = new C;
+ c[3]();
+ assertEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], log);
+}
+
+function y() {
+ // This tests lazy parsing.
+ return function() {
+ let log = [];
+ function run(i) {
+ log.push(i);
+ return i;
+ }
+
+ class C {
+ [run(1)] = run(7);
+ [run(2)] = run(8);
+ [run(3)]() { run(9);}
+ static [run(4)] = run(6);
+ [run(5)]() { throw new Error('should not execute');};
+ }
+
+ let c = new C;
+ c[3]();
+ assertEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], log);
+ }
+}
+y()();
{
class C {}
@@ -333,3 +377,83 @@ x();
let obj = new klass;
assertEquals(2, klass.x);
}
+
+{
+ let x = 'a';
+ class C {
+ a;
+ b = x;
+ c = 1;
+ hasOwnProperty() { return 1;}
+ static [x] = 2;
+ static b = 3;
+ static d;
+ }
+
+ assertEquals(2, C.a);
+ assertEquals(3, C.b);
+ assertEquals(undefined, C.d);
+ assertEquals(undefined, C.c);
+
+ let c = new C;
+ assertEquals(undefined, c.a);
+ assertEquals('a', c.b);
+ assertEquals(1, c.c);
+ assertEquals(undefined, c.d);
+ assertEquals(1, c.hasOwnProperty());
+}
+
+{
+ function t() {
+ return class {
+ ['x'] = 1;
+ static ['x'] = 2;
+ }
+ }
+
+ let klass = t();
+ let obj = new klass;
+ assertEquals(1, obj.x);
+ assertEquals(2, klass.x);
+}
+
+
+{
+ class X {
+ static p = function() { return arguments[0]; }
+ }
+
+ assertEquals(1, X.p(1));
+}
+
+{
+ class X {
+ static t = () => {
+ function p() { return arguments[0]; };
+ return p;
+ }
+ }
+
+ let p = X.t();
+ assertEquals(1, p(1));
+}
+
+{
+ class X {
+ static t = () => {
+ function p() { return eval("arguments[0]"); };
+ return p;
+ }
+ }
+
+ let p = X.t();
+ assertEquals(1, p(1));
+}
+
+{
+ class X {
+ static p = eval("(function() { return arguments[0]; })(1)");
+ }
+
+ assertEquals(1, X.p);
+}
diff --git a/deps/v8/test/mjsunit/harmony/regexp-named-captures.js b/deps/v8/test/mjsunit/harmony/regexp-named-captures.js
index 1ad29f6b49..72041b99bf 100644
--- a/deps/v8/test/mjsunit/harmony/regexp-named-captures.js
+++ b/deps/v8/test/mjsunit/harmony/regexp-named-captures.js
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --harmony-regexp-named-captures
+// Flags: --harmony-regexp-named-captures --allow-natives-syntax
// Malformed named captures.
assertThrows("/(?<>a)/u", SyntaxError); // Empty name.
@@ -418,3 +418,124 @@ function toSlowMode(re) {
assertEquals("cd", "abcd".replace(re, "$<fth>"));
assertEquals("cd", "abcd".replace(re, "$<$1>"));
}
+
+// Tests for 'groups' semantics on the regexp result object.
+// https://crbug.com/v8/7192
+
+{
+ const re = /./;
+ const result = re.exec("a");
+ assertTrue(%SpeciesProtector());
+ assertEquals(result.__proto__, Array.prototype);
+ assertTrue(result.hasOwnProperty('groups'));
+ assertArrayEquals(["a"], result);
+ assertEquals(0, result.index);
+ assertEquals(undefined, result.groups);
+
+ Array.prototype.groups = { a: "b" };
+ assertTrue(%SpeciesProtector());
+ assertEquals("$<a>", "a".replace(re, "$<a>"));
+ Array.prototype.groups = undefined;
+}
+
+{
+ const re = toSlowMode(/./);
+ const result = re.exec("a");
+ assertTrue(%SpeciesProtector());
+ assertEquals(result.__proto__, Array.prototype);
+ assertTrue(result.hasOwnProperty('groups'));
+ assertArrayEquals(["a"], result);
+ assertEquals(0, result.index);
+ assertEquals(undefined, result.groups);
+
+ Array.prototype.groups = { a: "b" };
+ assertTrue(%SpeciesProtector());
+ assertEquals("$<a>", "a".replace(re, "$<a>"));
+ Array.prototype.groups = undefined;
+}
+
+{
+ const re = /(?<a>a).|(?<x>x)/;
+ const result = re.exec("ab");
+ assertTrue(%SpeciesProtector());
+ assertEquals(result.__proto__, Array.prototype);
+ assertTrue(result.hasOwnProperty('groups'));
+ assertArrayEquals(["ab", "a", undefined], result);
+ assertEquals(0, result.index);
+ assertEquals({a: "a", x: undefined}, result.groups);
+
+ // a is a matched named capture, b is an unmatched named capture, and z
+ // is not a named capture.
+ Array.prototype.groups = { a: "b", x: "y", z: "z" };
+ assertTrue(%SpeciesProtector());
+ assertEquals("a", "ab".replace(re, "$<a>"));
+ assertEquals("", "ab".replace(re, "$<x>"));
+ assertEquals("", "ab".replace(re, "$<z>"));
+ Array.prototype.groups = undefined;
+}
+
+{
+ const re = toSlowMode(/(?<a>a).|(?<x>x)/);
+ const result = re.exec("ab");
+ assertTrue(%SpeciesProtector());
+ assertEquals(result.__proto__, Array.prototype);
+ assertTrue(result.hasOwnProperty('groups'));
+ assertArrayEquals(["ab", "a", undefined], result);
+ assertEquals(0, result.index);
+ assertEquals({a: "a", x: undefined}, result.groups);
+
+ // a is a matched named capture, b is an unmatched named capture, and z
+ // is not a named capture.
+ Array.prototype.groups = { a: "b", x: "y", z: "z" };
+ assertTrue(%SpeciesProtector());
+ assertEquals("a", "ab".replace(re, "$<a>"));
+ assertEquals("", "ab".replace(re, "$<x>"));
+ assertEquals("", "ab".replace(re, "$<z>"));
+ Array.prototype.groups = undefined;
+}
+
+{
+ class FakeRegExp extends RegExp {
+ exec(subject) {
+ const fake_result = [ "ab", "a" ];
+ fake_result.index = 0;
+ // groups is not set, triggering prototype lookup.
+ return fake_result;
+ }
+ };
+
+ const re = new FakeRegExp();
+ const result = re.exec("ab");
+ assertTrue(%SpeciesProtector());
+ assertEquals(result.__proto__, Array.prototype);
+ assertFalse(result.hasOwnProperty('groups'));
+
+ Array.prototype.groups = { a: "b" };
+ Array.prototype.groups.__proto__.b = "c";
+ assertTrue(%SpeciesProtector());
+ assertEquals("b", "ab".replace(re, "$<a>"));
+ assertEquals("c", "ab".replace(re, "$<b>"));
+ Array.prototype.groups = undefined;
+}
+
+{
+ class FakeRegExp extends RegExp {
+ exec(subject) {
+ const fake_result = [ "ab", "a" ];
+ fake_result.index = 0;
+ fake_result.groups = { a: "b" };
+ fake_result.groups.__proto__.b = "c";
+ return fake_result;
+ }
+ };
+
+ const re = new FakeRegExp();
+ const result = re.exec("ab");
+ assertTrue(%SpeciesProtector());
+ assertEquals(result.__proto__, Array.prototype);
+ assertTrue(result.hasOwnProperty('groups'));
+ assertEquals({ a: "b" }, result.groups);
+
+ assertEquals("b", "ab".replace(re, "$<a>"));
+ assertEquals("c", "ab".replace(re, "$<b>"));
+}
diff --git a/deps/v8/test/mjsunit/harmony/regress/regress-6322.js b/deps/v8/test/mjsunit/harmony/regress/regress-6322.js
index 9c312a35a5..927b56ea79 100644
--- a/deps/v8/test/mjsunit/harmony/regress/regress-6322.js
+++ b/deps/v8/test/mjsunit/harmony/regress/regress-6322.js
@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --harmony-async-iteration
-
// Crash with --verify-heap
(async function() { for await (let { a = class b { } } of [{}]) { } })();
(async function() { var a; for await ({ a = class b { } } of [{}]) { } })();
diff --git a/deps/v8/test/mjsunit/harmony/regress/regress-772649.js b/deps/v8/test/mjsunit/harmony/regress/regress-772649.js
index d080410226..2ff27670df 100644
--- a/deps/v8/test/mjsunit/harmony/regress/regress-772649.js
+++ b/deps/v8/test/mjsunit/harmony/regress/regress-772649.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: --allow-natives-syntax --harmony-async-iteration
+// Flags: --allow-natives-syntax
async function* gen([[notIterable]] = [null]) {}
assertThrows(() => gen(), TypeError);
diff --git a/deps/v8/test/mjsunit/harmony/sharedarraybuffer.js b/deps/v8/test/mjsunit/harmony/sharedarraybuffer.js
index 12e8c9508e..a79574d69f 100644
--- a/deps/v8/test/mjsunit/harmony/sharedarraybuffer.js
+++ b/deps/v8/test/mjsunit/harmony/sharedarraybuffer.js
@@ -89,9 +89,6 @@ function TestTypedArray(constr, elementSize, typicalElement) {
assertEquals("[object " + constr.name + "]",
Object.prototype.toString.call(a0));
- // TODO(binji): Should this return false here? It is a view, but it doesn't
- // view a SharedArrayBuffer...
- assertTrue(SharedArrayBuffer.isView(a0));
assertSame(elementSize, a0.BYTES_PER_ELEMENT);
assertSame(30, a0.length);
assertSame(30*elementSize, a0.byteLength);
diff --git a/deps/v8/test/mjsunit/harmony/symbol-async-iterator.js b/deps/v8/test/mjsunit/harmony/symbol-async-iterator.js
index 8a92add635..5b7e6b5f40 100644
--- a/deps/v8/test/mjsunit/harmony/symbol-async-iterator.js
+++ b/deps/v8/test/mjsunit/harmony/symbol-async-iterator.js
@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --harmony-async-iteration
-
assertTrue(Symbol.hasOwnProperty('asyncIterator'));
assertEquals('symbol', typeof Symbol.asyncIterator);
assertInstanceof(Object(Symbol.asyncIterator), Symbol);
diff --git a/deps/v8/test/mjsunit/ic-lookup-on-receiver.js b/deps/v8/test/mjsunit/ic-lookup-on-receiver.js
new file mode 100644
index 0000000000..8be3779f05
--- /dev/null
+++ b/deps/v8/test/mjsunit/ic-lookup-on-receiver.js
@@ -0,0 +1,44 @@
+// Copyright 2017 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: --allow-natives-syntax
+
+(function TestLookupOnReceiver() {
+ let log = [];
+
+ function f(o, v) {
+ o.x = v;
+ return o.x;
+ }
+
+ let p = {};
+ Object.defineProperty(
+ p, "x",
+ {
+ get: function() { return 153; },
+ set: function(v) { log.push("set"); },
+ configurable: true
+ });
+
+ let o = Object.create(p);
+ // Turn o to dictionary mode.
+ for (let i = 0; i < 2048; i++) {
+ o["p"+i] = 0;
+ }
+ assertFalse(%HasFastProperties(o));
+
+ for (let i = 0; i < 5; i++) {
+ log.push(f(o, i));
+ }
+
+ Object.defineProperty(o, "x", { value: 0, configurable: true, writable: true});
+
+ for (let i = 0; i < 5; i++) {
+ log.push(f(o, 42 + i));
+ }
+
+ assertEquals(log,
+ ["set", 153, "set", 153, "set", 153, "set", 153, "set", 153,
+ 42, 43, 44, 45, 46]);
+})();
diff --git a/deps/v8/test/mjsunit/mjsunit.status b/deps/v8/test/mjsunit/mjsunit.status
index aa59fb680a..d91ff6f015 100644
--- a/deps/v8/test/mjsunit/mjsunit.status
+++ b/deps/v8/test/mjsunit/mjsunit.status
@@ -31,6 +31,7 @@
# tested standalone.
'modules-skip*': [SKIP],
'harmony/modules-skip*': [SKIP],
+ 'regress/modules-skip*': [SKIP],
# All tests in the bug directory are expected to fail.
'bugs/*': [FAIL],
@@ -78,13 +79,16 @@
##############################################################################
# No need to waste time for this test.
- 'd8-performance-now': [PASS, NO_VARIANTS],
+ 'd8/d8-performance-now': [PASS, NO_VARIANTS],
'regress/regress-crbug-491062': [PASS, NO_VARIANTS],
# Issue 488: this test sometimes times out.
# TODO(arm): This seems to flush out a bug on arm with simulator.
'array-constructor': [PASS, SLOW, ['arch == arm and simulator == True', SKIP]],
+ # Very slow test
+ 'regress/regress-crbug-808192' : [PASS, NO_VARIANTS, ['arch == arm or arch == arm64 or arch == android_arm or arch == android_arm64 or arch == mipsel or arch == mips64el or arch == mips64 or arch == mips', SKIP]],
+
# Very slow on ARM and MIPS, contains no architecture dependent code.
'unicode-case-overoptimization': [PASS, NO_VARIANTS, ['arch == arm or arch == arm64 or arch == android_arm or arch == android_arm64 or arch == mipsel or arch == mips64el or arch == mips64 or arch == mips', SKIP]],
'regress/regress-3976': [PASS, NO_VARIANTS, ['arch == arm or arch == arm64 or arch == android_arm or arch == android_arm64 or arch == mipsel or arch == mips64el or arch == mips64 or arch == mips', SKIP]],
@@ -109,11 +113,17 @@
# we cannot run several variants of d8-os simultaneously, since all of them
# get the same random seed and would generate the same directory name. Besides
# that, it doesn't make sense to run several variants of d8-os anyways.
- 'd8-os': [PASS, NO_VARIANTS, ['isolates or arch == android_arm or arch == android_arm64 or arch == android_ia32', SKIP]],
+ 'd8/d8-os': [PASS, NO_VARIANTS, ['isolates or arch == android_arm or arch == android_arm64 or arch == android_ia32', SKIP]],
'tools/tickprocessor': [PASS, NO_VARIANTS, ['arch == android_arm or arch == android_arm64 or arch == android_ia32', SKIP]],
'tools/dumpcpp': [PASS, NO_VARIANTS, ['arch == android_arm or arch == android_arm64 or arch == android_ia32', SKIP]],
##############################################################################
+ # This test generates a file in the test directory, so we cannot run several
+ # variants of the test simultaneously. Additionally the test should not be
+ # affected by variants.
+ 'd8/enable-tracing': [PASS, NO_VARIANTS],
+
+ ##############################################################################
# Long running test that reproduces memory leak and should be run manually.
'regress/regress-2073': [SKIP],
@@ -135,9 +145,9 @@
'math-floor-of-div-nosudiv': [PASS, SLOW, ['arch not in [arm, arm64, android_arm, android_arm64]', SKIP]],
# Too slow for slow variants.
- 'asm/embenchen/*': [PASS, SLOW, FAST_VARIANTS],
- 'asm/poppler/*': [PASS, SLOW, FAST_VARIANTS],
- 'asm/sqlite3/*': [PASS, SLOW, FAST_VARIANTS],
+ 'asm/embenchen/*': [PASS, SLOW, NO_VARIANTS],
+ 'asm/poppler/*': [PASS, SLOW, NO_VARIANTS],
+ 'asm/sqlite3/*': [PASS, SLOW, NO_VARIANTS],
# Slow tests.
'copy-on-write-assert': [PASS, SLOW],
@@ -162,6 +172,7 @@
'regexp-modifiers-autogenerated-i18n': [PASS, ['no_i18n == True', FAIL]],
# desugaring regexp property class relies on ICU.
'harmony/regexp-property-*': [PASS, ['no_i18n == True', FAIL]],
+ 'regress/regress-793588': [PASS, ['no_i18n == True', FAIL]],
# noi18n build cannot parse characters in supplementary plane.
'harmony/regexp-named-captures': [PASS, ['no_i18n == True', FAIL]],
@@ -193,13 +204,19 @@
}], # novfp3 == True
##############################################################################
+# TODO(ahaas): Port multiple return values to ARM, MIPS, S390 and PPC
+['arch == arm or arch == arm64 or arch == mips or arch == mips64 or arch == mipsel or arch == mips64el or arch == s390 or arch == s390x or arch == ppc or arch == ppc64', {
+ 'wasm/multi-value': [SKIP],
+}],
+
+##############################################################################
['gc_stress == True', {
# Skip tests not suitable for GC stress.
'allocation-site-info': [SKIP],
'array-constructor-feedback': [SKIP],
'array-feedback': [SKIP],
'array-literal-feedback': [SKIP],
- 'd8-performance-now': [SKIP],
+ 'd8/d8-performance-now': [SKIP],
'elements-kind': [SKIP],
'elements-transition-hoisting': [SKIP],
'fast-prototype': [SKIP],
@@ -250,7 +267,7 @@
'regress/regress-inline-getter-near-stack-limit': [PASS, SLOW],
# BUG(v8:4779): Crashes flakily with stress mode on arm64.
- 'array-splice': [PASS, SLOW, ['arch == arm64', FAST_VARIANTS]],
+ 'array-splice': [PASS, SLOW, ['arch == arm64', NO_VARIANTS]],
# BUG(chromium:751825): Crashes flakily.
'wasm/js-api': [SKIP],
@@ -333,6 +350,9 @@
'unicode-test': [PASS, SLOW],
'wasm/atomics': [PASS, SLOW],
'whitespaces': [PASS, SLOW],
+
+ # BUG(v8:7247).
+ 'regress/regress-779407': [PASS, SLOW, NO_VARIANTS],
}], # 'arch == arm64'
['arch == arm64 and mode == debug and simulator_run', {
@@ -578,9 +598,6 @@
'math-floor-of-div-nosudiv': [PASS, ['mode == debug', SKIP]],
'unicodelctest': [PASS, ['mode == debug', SKIP]],
- # BUG(v8:4495).
- 'es6/collections': [PASS, ['arch == ia32', FAST_VARIANTS]],
-
# Setting the timezone and locale with environment variables unavailable
'icu-date-to-string': [SKIP],
'icu-date-lord-howe': [SKIP],
@@ -624,14 +641,19 @@
'regress/regress-336820': [SKIP],
'regress/regress-748069': [SKIP],
'regress/regress-778668': [SKIP],
+ 'ignition/regress-672027': [PASS, ['tsan', SKIP]],
}], # 'gc_fuzzer == True'
##############################################################################
['predictable == True', {
# Skip tests that are known to be non-deterministic.
- 'd8-worker-sharedarraybuffer': [SKIP],
- 'd8-os': [SKIP],
+ 'd8/d8-worker-sharedarraybuffer': [SKIP],
+ 'd8/d8-os': [SKIP],
+ 'harmony/futex': [SKIP],
+
+ # BUG(v8:7166).
+ 'd8/enable-tracing': [SKIP],
}], # 'predictable == True'
##############################################################################
@@ -735,16 +757,17 @@
}], # arch != x64 and arch != ia32
##############################################################################
-# BUG(v8:7138).
-['arch == arm and not simulator_run and variant == wasm_traps', {
- '*': [SKIP],
-}], # arch == arm and not simulator_run and variant == wasm_traps
-
-##############################################################################
['variant == liftoff', {
# In the liftoff variant, liftoff compilation happens even though the test
# does not explicitly enable it.
'wasm/default-liftoff-setting': [SKIP],
}], # variant == liftoff
+##############################################################################
+['variant == slow_path and gc_stress', {
+ # Slow tests.
+ 'regress/regress-crbug-493779': [SKIP],
+ 'string-replace-gc': [SKIP],
+}], # variant == slow_path
+
]
diff --git a/deps/v8/test/mjsunit/optimized-array-every.js b/deps/v8/test/mjsunit/optimized-array-every.js
new file mode 100644
index 0000000000..0cbab7df67
--- /dev/null
+++ b/deps/v8/test/mjsunit/optimized-array-every.js
@@ -0,0 +1,520 @@
+// Copyright 2017 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: --allow-natives-syntax --turbo-inline-array-builtins --opt
+// Flags: --no-always-opt
+
+// Early exit from every functions properly.
+(() => {
+ const a = [1, 2, 3, 4, 5];
+ let result = 0;
+ function earlyExit() {
+ return a.every(v => {
+ result += v;
+ return v < 2;
+ });
+ }
+ assertFalse(earlyExit());
+ earlyExit();
+ %OptimizeFunctionOnNextCall(earlyExit);
+ assertFalse(earlyExit());
+ assertEquals(9, result);
+})();
+
+// Soft-deopt plus early exit.
+(() => {
+ const a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+ let result = 0;
+ function softyPlusEarlyExit(deopt) {
+ return a.every(v => {
+ result += v;
+ if (v === 4 && deopt) {
+ a.abc = 25;
+ }
+ return v < 8;
+ });
+ }
+ assertFalse(softyPlusEarlyExit(false));
+ softyPlusEarlyExit(false);
+ %OptimizeFunctionOnNextCall(softyPlusEarlyExit);
+ assertFalse(softyPlusEarlyExit(true));
+ assertEquals(36*3, result);
+})();
+
+// Soft-deopt synced with early exit, which forces the lazy deoptimization
+// continuation handler to exit.
+(() => {
+ const a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+ let called_values = [];
+ function softyPlusEarlyExit(deopt) {
+ called_values = [];
+ return a.every(v => {
+ called_values.push(v);
+ if (v === 4 && deopt) {
+ a.abc = 25;
+ return false;
+ }
+ return v < 8;
+ });
+ }
+ assertFalse(softyPlusEarlyExit(false));
+ assertArrayEquals([1, 2, 3, 4, 5, 6, 7, 8], called_values);
+ softyPlusEarlyExit(false);
+ %OptimizeFunctionOnNextCall(softyPlusEarlyExit);
+ assertFalse(softyPlusEarlyExit(true));
+ assertArrayEquals([1, 2, 3, 4], called_values);
+})();
+
+// Unknown field access leads to soft-deopt unrelated to every, should still
+// lead to correct result.
+(() => {
+ const a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25];
+ let result = 0;
+ function eagerDeoptInCalled(deopt) {
+ return a.every((v, i) => {
+ if (i === 13 && deopt) {
+ a.abc = 25;
+ }
+ result += v;
+ return true;
+ });
+ }
+ eagerDeoptInCalled();
+ eagerDeoptInCalled();
+ %OptimizeFunctionOnNextCall(eagerDeoptInCalled);
+ eagerDeoptInCalled();
+ assertTrue(eagerDeoptInCalled(true));
+ eagerDeoptInCalled();
+ assertEquals(1625, result);
+})();
+
+// Length change detected during loop, must cause properly handled eager deopt.
+(() => {
+ let called_values;
+ function eagerDeoptInCalled(deopt) {
+ const a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+ called_values = [];
+ return a.every((v,i) => {
+ called_values.push(v);
+ a.length = (i === 5 && deopt) ? 8 : 10;
+ return true;
+ });
+ }
+ assertTrue(eagerDeoptInCalled());
+ assertArrayEquals([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], called_values);
+ eagerDeoptInCalled();
+ %OptimizeFunctionOnNextCall(eagerDeoptInCalled);
+ assertTrue(eagerDeoptInCalled());
+ assertTrue(eagerDeoptInCalled(true));
+ assertArrayEquals([1, 2, 3, 4, 5, 6, 7, 8], called_values);
+ eagerDeoptInCalled();
+})();
+
+// Lazy deopt from a callback that changes the input array. Deopt in a callback
+// execution that returns true.
+(() => {
+ const a = [1, 2, 3, 4, 5];
+ function lazyChanger(deopt) {
+ return a.every((v, i) => {
+ if (i === 3 && deopt) {
+ a[3] = 100;
+ %DeoptimizeNow();
+ }
+ return true;
+ });
+ }
+ assertTrue(lazyChanger());
+ lazyChanger();
+ %OptimizeFunctionOnNextCall(lazyChanger);
+ assertTrue(lazyChanger(true));
+ assertTrue(lazyChanger());
+})();
+
+// Lazy deopt from a callback that will always return true and no element is
+// found. Verifies the lazy-after-callback continuation builtin.
+(() => {
+ const a = [1, 2, 3, 4, 5];
+ function lazyChanger(deopt) {
+ return a.every((v, i) => {
+ if (i === 3 && deopt) {
+ %DeoptimizeNow();
+ }
+ return true;
+ });
+ }
+ assertTrue(lazyChanger());
+ lazyChanger();
+ %OptimizeFunctionOnNextCall(lazyChanger);
+ assertTrue(lazyChanger(true));
+ assertTrue(lazyChanger());
+})();
+
+// Lazy deopt from a callback that changes the input array. Deopt in a callback
+// execution that returns true.
+(() => {
+ const a = [1, 2, 3, 4, 5];
+ function lazyChanger(deopt) {
+ return a.every((v, i) => {
+ if (i === 2 && deopt) {
+ a[3] = 100;
+ %DeoptimizeNow();
+ }
+ return true;
+ });
+ }
+ assertTrue(lazyChanger());
+ lazyChanger();
+ %OptimizeFunctionOnNextCall(lazyChanger);
+ assertTrue(lazyChanger(true));
+ assertTrue(lazyChanger());
+})();
+
+// Escape analyzed array
+(() => {
+ let result = 0;
+ function eagerDeoptInCalled(deopt) {
+ const a_noescape = [0, 1, 2, 3, 4, 5];
+ a_noescape.every((v, i) => {
+ result += v | 0;
+ if (i === 13 && deopt) {
+ a_noescape.length = 25;
+ }
+ return true;
+ });
+ }
+ eagerDeoptInCalled();
+ eagerDeoptInCalled();
+ %OptimizeFunctionOnNextCall(eagerDeoptInCalled);
+ eagerDeoptInCalled();
+ eagerDeoptInCalled(true);
+ eagerDeoptInCalled();
+ assertEquals(75, result);
+})();
+
+// Lazy deopt from runtime call from inlined callback function.
+(() => {
+ const a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25];
+ let result = 0;
+ function lazyDeopt(deopt) {
+ a.every((v, i) => {
+ result += i;
+ if (i === 13 && deopt) {
+ %DeoptimizeNow();
+ }
+ return true;
+ });
+ }
+ lazyDeopt();
+ lazyDeopt();
+ %OptimizeFunctionOnNextCall(lazyDeopt);
+ lazyDeopt();
+ lazyDeopt(true);
+ lazyDeopt();
+ assertEquals(1500, result);
+})();
+
+// Lazy deopt from runtime call from non-inline callback function.
+(() => {
+ const a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25];
+ let result = 0;
+ function lazyDeopt(deopt) {
+ function callback(v, i) {
+ result += i;
+ if (i === 13 && deopt) {
+ %DeoptimizeNow();
+ }
+ return true;
+ }
+ %NeverOptimizeFunction(callback);
+ a.every(callback);
+ }
+ lazyDeopt();
+ lazyDeopt();
+ %OptimizeFunctionOnNextCall(lazyDeopt);
+ lazyDeopt();
+ lazyDeopt(true);
+ lazyDeopt();
+ assertEquals(1500, result);
+})();
+
+// Call to a.every is done inside a try-catch block and the callback function
+// being called actually throws.
+(() => {
+ const a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25];
+ let caught = false;
+ function lazyDeopt(deopt) {
+ try {
+ a.every((v, i) => {
+ if (i === 1 && deopt) {
+ throw("a");
+ }
+ return true;
+ });
+ } catch (e) {
+ caught = true;
+ }
+ }
+ lazyDeopt();
+ lazyDeopt();
+ %OptimizeFunctionOnNextCall(lazyDeopt);
+ lazyDeopt();
+ assertDoesNotThrow(() => lazyDeopt(true));
+ assertTrue(caught);
+ lazyDeopt();
+})();
+
+// Call to a.every is done inside a try-catch block and the callback function
+// being called actually throws, but the callback is not inlined.
+(() => {
+ let a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+ let caught = false;
+ function lazyDeopt(deopt) {
+ function callback(v, i) {
+ if (i === 1 && deopt) {
+ throw("a");
+ }
+ return true;
+ }
+ %NeverOptimizeFunction(callback);
+ try {
+ a.every(callback);
+ } catch (e) {
+ caught = true;
+ }
+ }
+ lazyDeopt();
+ lazyDeopt();
+ %OptimizeFunctionOnNextCall(lazyDeopt);
+ lazyDeopt();
+ assertDoesNotThrow(() => lazyDeopt(true));
+ assertTrue(caught);
+ lazyDeopt();
+})();
+
+// Call to a.every is done inside a try-catch block and the callback function
+// being called throws into a deoptimized caller function.
+(function TestThrowIntoDeoptimizedOuter() {
+ const a = [1, 2, 3, 4];
+ function lazyDeopt(deopt) {
+ function callback(v, i) {
+ if (i === 1 && deopt) {
+ %DeoptimizeFunction(lazyDeopt);
+ throw "some exception";
+ }
+ return true;
+ }
+ %NeverOptimizeFunction(callback);
+ let result = 0;
+ try {
+ result = a.every(callback);
+ } catch (e) {
+ assertEquals("some exception", e);
+ result = "nope";
+ }
+ return result;
+ }
+ assertEquals(true, lazyDeopt(false));
+ assertEquals(true, lazyDeopt(false));
+ assertEquals("nope", lazyDeopt(true));
+ assertEquals("nope", lazyDeopt(true));
+ %OptimizeFunctionOnNextCall(lazyDeopt);
+ assertEquals(true, lazyDeopt(false));
+ assertEquals("nope", lazyDeopt(true));
+})();
+
+// An error generated inside the callback includes every in it's
+// stack trace.
+(() => {
+ const re = /Array\.every/;
+ function lazyDeopt(deopt) {
+ const b = [1, 2, 3];
+ let result = 0;
+ b.every((v, i) => {
+ result += v;
+ if (i === 1) {
+ const e = new Error();
+ assertTrue(re.exec(e.stack) !== null);
+ }
+ return true;
+ });
+ }
+ lazyDeopt();
+ lazyDeopt();
+ %OptimizeFunctionOnNextCall(lazyDeopt);
+ lazyDeopt();
+})();
+
+// An error generated inside a non-inlined callback function also
+// includes every in it's stack trace.
+(() => {
+ const re = /Array\.every/;
+ function lazyDeopt(deopt) {
+ const b = [1, 2, 3];
+ let did_assert_error = false;
+ let result = 0;
+ function callback(v, i) {
+ result += v;
+ if (i === 1) {
+ const e = new Error();
+ assertTrue(re.exec(e.stack) !== null);
+ did_assert_error = true;
+ }
+ return true;
+ }
+ %NeverOptimizeFunction(callback);
+ b.every(callback);
+ return did_assert_error;
+ }
+ lazyDeopt();
+ lazyDeopt();
+ %OptimizeFunctionOnNextCall(lazyDeopt);
+ assertTrue(lazyDeopt());
+})();
+
+// An error generated inside a recently deoptimized callback function
+// includes every in it's stack trace.
+(() => {
+ const re = /Array\.every/;
+ function lazyDeopt(deopt) {
+ const b = [1, 2, 3];
+ let did_assert_error = false;
+ let result = 0;
+ b.every((v, i) => {
+ result += v;
+ if (i === 1) {
+ %DeoptimizeNow();
+ } else if (i === 2) {
+ const e = new Error();
+ assertTrue(re.exec(e.stack) !== null);
+ did_assert_error = true;
+ }
+ return true;
+ });
+ return did_assert_error;
+ }
+ lazyDeopt();
+ lazyDeopt();
+ %OptimizeFunctionOnNextCall(lazyDeopt);
+ assertTrue(lazyDeopt());
+})();
+
+// Verify that various exception edges are handled appropriately.
+// The thrown Error object should always indicate it was created from
+// an every call stack.
+(() => {
+ const re = /Array\.every/;
+ const a = [1, 2, 3];
+ let result = 0;
+ function lazyDeopt() {
+ a.every((v, i) => {
+ result += i;
+ if (i === 1) {
+ %DeoptimizeFunction(lazyDeopt);
+ throw new Error();
+ }
+ return true;
+ });
+ }
+ assertThrows(() => lazyDeopt());
+ assertThrows(() => lazyDeopt());
+ try {
+ lazyDeopt();
+ } catch (e) {
+ assertTrue(re.exec(e.stack) !== null);
+ }
+ %OptimizeFunctionOnNextCall(lazyDeopt);
+ try {
+ lazyDeopt();
+ } catch (e) {
+ assertTrue(re.exec(e.stack) !== null);
+ }
+})();
+
+// Verify holes are skipped.
+(() => {
+ const a = [1, 2, , 3, 4];
+ function withHoles() {
+ const callback_values = [];
+ a.every(v => {
+ callback_values.push(v);
+ return true;
+ });
+ return callback_values;
+ }
+ withHoles();
+ withHoles();
+ %OptimizeFunctionOnNextCall(withHoles);
+ assertArrayEquals([1, 2, 3, 4], withHoles());
+})();
+
+(() => {
+ const a = [1.5, 2.5, , 3.5, 4.5];
+ function withHoles() {
+ const callback_values = [];
+ a.every(v => {
+ callback_values.push(v);
+ return true;
+ });
+ return callback_values;
+ }
+ withHoles();
+ withHoles();
+ %OptimizeFunctionOnNextCall(withHoles);
+ assertArrayEquals([1.5, 2.5, 3.5, 4.5], withHoles());
+})();
+
+// Ensure that we handle side-effects between load and call.
+(() => {
+ function side_effect(a, b) { if (b) a.foo = 3; return a; }
+ %NeverOptimizeFunction(side_effect);
+
+ function unreliable(a, b) {
+ return a.every(x => true, side_effect(a, b));
+ }
+
+ let a = [1, 2, 3];
+ unreliable(a, false);
+ unreliable(a, false);
+ %OptimizeFunctionOnNextCall(unreliable);
+ unreliable(a, false);
+ // Now actually do change the map.
+ unreliable(a, true);
+})();
+
+// Handle callback is not callable.
+(() => {
+ const a = [1, 2, 3, 4, 5];
+ function notCallable() {
+ return a.every(undefined);
+ }
+
+ assertThrows(notCallable, TypeError);
+ try { notCallable(); } catch(e) { }
+ %OptimizeFunctionOnNextCall(notCallable);
+ assertThrows(notCallable, TypeError);
+})();
+
+// Messing with the Array prototype causes deoptimization.
+(() => {
+ const a = [1, 2, 3];
+ let result = 0;
+ function prototypeChanged() {
+ a.every((v, i) => {
+ result += v;
+ return true;
+ });
+ }
+ prototypeChanged();
+ prototypeChanged();
+ %OptimizeFunctionOnNextCall(prototypeChanged);
+ prototypeChanged();
+ a.constructor = {};
+ prototypeChanged();
+ assertUnoptimized(prototypeChanged);
+ assertEquals(24, result);
+})();
diff --git a/deps/v8/test/mjsunit/optimized-array-find.js b/deps/v8/test/mjsunit/optimized-array-find.js
new file mode 100644
index 0000000000..abcd2cf704
--- /dev/null
+++ b/deps/v8/test/mjsunit/optimized-array-find.js
@@ -0,0 +1,460 @@
+// Copyright 2017 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: --allow-natives-syntax --turbo-inline-array-builtins --opt
+// Flags: --no-always-opt
+
+// Unknown field access leads to soft-deopt unrelated to find, should still
+// lead to correct result.
+(() => {
+ const a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25];
+ let result = 0;
+ function eagerDeoptInCalled(deopt) {
+ return a.find((v, i) => {
+ if (i === 13 && deopt) {
+ a.abc = 25;
+ }
+ result += v;
+ return v === 20;
+ });
+ }
+ eagerDeoptInCalled();
+ eagerDeoptInCalled();
+ %OptimizeFunctionOnNextCall(eagerDeoptInCalled);
+ eagerDeoptInCalled();
+ assertEquals(20, eagerDeoptInCalled(true));
+ eagerDeoptInCalled();
+ assertEquals(1050, result);
+})();
+
+// Length change detected during loop, must cause properly handled eager deopt.
+(() => {
+ let called_values;
+ function eagerDeoptInCalled(deopt) {
+ const a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+ called_values = [];
+ return a.find((v,i) => {
+ called_values.push(v);
+ a.length = (i === 5 && deopt) ? 8 : 10;
+ return v === 9;
+ });
+ }
+ assertEquals(9, eagerDeoptInCalled());
+ assertArrayEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], called_values);
+ eagerDeoptInCalled();
+ %OptimizeFunctionOnNextCall(eagerDeoptInCalled);
+ assertEquals(9, eagerDeoptInCalled());
+ assertEquals(undefined, eagerDeoptInCalled(true));
+ assertArrayEquals([1, 2, 3, 4, 5, 6, 7, 8, undefined, undefined],
+ called_values);
+ eagerDeoptInCalled();
+})();
+
+// Lazy deopt from a callback that changes the input array. Deopt in a callback
+// execution that returns true.
+(() => {
+ const a = [1, 2, 3, 4, 5];
+ function lazyChanger(deopt) {
+ return a.find((v, i) => {
+ if (i === 3 && deopt) {
+ a[3] = 100;
+ %DeoptimizeNow();
+ }
+ return v > 3;
+ });
+ }
+ assertEquals(4, lazyChanger());
+ lazyChanger();
+ %OptimizeFunctionOnNextCall(lazyChanger);
+ assertEquals(4, lazyChanger(true));
+ assertEquals(100, lazyChanger());
+})();
+
+// Lazy deopt from a callback that will always return false and no element is
+// found. Verifies the lazy-after-callback continuation builtin.
+(() => {
+ const a = [1, 2, 3, 4, 5];
+ function lazyChanger(deopt) {
+ return a.find((v, i) => {
+ if (i === 3 && deopt) {
+ %DeoptimizeNow();
+ }
+ return false;
+ });
+ }
+ assertEquals(undefined, lazyChanger());
+ lazyChanger();
+ %OptimizeFunctionOnNextCall(lazyChanger);
+ assertEquals(undefined, lazyChanger(true));
+ assertEquals(undefined, lazyChanger());
+})();
+
+// Lazy deopt from a callback that changes the input array. Deopt in a callback
+// execution that returns false.
+(() => {
+ const a = [1, 2, 3, 4, 5];
+ function lazyChanger(deopt) {
+ return a.find((v, i) => {
+ if (i === 2 && deopt) {
+ a[3] = 100;
+ %DeoptimizeNow();
+ }
+ return v > 3;
+ });
+ }
+ assertEquals(4, lazyChanger());
+ lazyChanger();
+ %OptimizeFunctionOnNextCall(lazyChanger);
+ assertEquals(100, lazyChanger(true));
+ assertEquals(100, lazyChanger());
+})();
+
+// Escape analyzed array
+(() => {
+ let result = 0;
+ function eagerDeoptInCalled(deopt) {
+ const a_noescape = [0, 1, 2, 3, 4, 5];
+ a_noescape.find((v, i) => {
+ result += v | 0;
+ if (i === 13 && deopt) {
+ a_noescape.length = 25;
+ }
+ return false;
+ });
+ }
+ eagerDeoptInCalled();
+ eagerDeoptInCalled();
+ %OptimizeFunctionOnNextCall(eagerDeoptInCalled);
+ eagerDeoptInCalled();
+ eagerDeoptInCalled(true);
+ eagerDeoptInCalled();
+ assertEquals(75, result);
+})();
+
+// Lazy deopt from runtime call from inlined callback function.
+(() => {
+ const a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25];
+ let result = 0;
+ function lazyDeopt(deopt) {
+ a.find((v, i) => {
+ result += i;
+ if (i === 13 && deopt) {
+ %DeoptimizeNow();
+ }
+ return false;
+ });
+ }
+ lazyDeopt();
+ lazyDeopt();
+ %OptimizeFunctionOnNextCall(lazyDeopt);
+ lazyDeopt();
+ lazyDeopt(true);
+ lazyDeopt();
+ assertEquals(1500, result);
+})();
+
+// Lazy deopt from runtime call from non-inline callback function.
+(() => {
+ const a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25];
+ let result = 0;
+ function lazyDeopt(deopt) {
+ function callback(v, i) {
+ result += i;
+ if (i === 13 && deopt) {
+ %DeoptimizeNow();
+ }
+ return false;
+ }
+ %NeverOptimizeFunction(callback);
+ a.find(callback);
+ }
+ lazyDeopt();
+ lazyDeopt();
+ %OptimizeFunctionOnNextCall(lazyDeopt);
+ lazyDeopt();
+ lazyDeopt(true);
+ lazyDeopt();
+ assertEquals(1500, result);
+})();
+
+// Call to a.find is done inside a try-catch block and the callback function
+// being called actually throws.
+(() => {
+ const a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25];
+ let caught = false;
+ function lazyDeopt(deopt) {
+ try {
+ a.find((v, i) => {
+ if (i === 1 && deopt) {
+ throw("a");
+ }
+ return false;
+ });
+ } catch (e) {
+ caught = true;
+ }
+ }
+ lazyDeopt();
+ lazyDeopt();
+ %OptimizeFunctionOnNextCall(lazyDeopt);
+ lazyDeopt();
+ assertDoesNotThrow(() => lazyDeopt(true));
+ assertTrue(caught);
+ lazyDeopt();
+})();
+
+// Call to a.find is done inside a try-catch block and the callback function
+// being called actually throws, but the callback is not inlined.
+(() => {
+ let a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+ let caught = false;
+ function lazyDeopt(deopt) {
+ function callback(v, i) {
+ if (i === 1 && deopt) {
+ throw("a");
+ }
+ return false;
+ }
+ %NeverOptimizeFunction(callback);
+ try {
+ a.find(callback);
+ } catch (e) {
+ caught = true;
+ }
+ }
+ lazyDeopt();
+ lazyDeopt();
+ %OptimizeFunctionOnNextCall(lazyDeopt);
+ lazyDeopt();
+ assertDoesNotThrow(() => lazyDeopt(true));
+ assertTrue(caught);
+ lazyDeopt();
+})();
+
+// Call to a.find is done inside a try-catch block and the callback function
+// being called throws into a deoptimized caller function.
+(function TestThrowIntoDeoptimizedOuter() {
+ const a = [1, 2, 3, 4];
+ function lazyDeopt(deopt) {
+ function callback(v, i) {
+ if (i === 1 && deopt) {
+ %DeoptimizeFunction(lazyDeopt);
+ throw "some exception";
+ }
+ return v === 3;
+ }
+ %NeverOptimizeFunction(callback);
+ let result = 0;
+ try {
+ result = a.find(callback);
+ } catch (e) {
+ assertEquals("some exception", e);
+ result = "nope";
+ }
+ return result;
+ }
+ assertEquals(3, lazyDeopt(false));
+ assertEquals(3, lazyDeopt(false));
+ assertEquals("nope", lazyDeopt(true));
+ assertEquals("nope", lazyDeopt(true));
+ %OptimizeFunctionOnNextCall(lazyDeopt);
+ assertEquals(3, lazyDeopt(false));
+ assertEquals("nope", lazyDeopt(true));
+})();
+
+// An error generated inside the callback includes find in it's
+// stack trace.
+(() => {
+ const re = /Array\.find/;
+ function lazyDeopt(deopt) {
+ const b = [1, 2, 3];
+ let result = 0;
+ b.find((v, i) => {
+ result += v;
+ if (i === 1) {
+ const e = new Error();
+ assertTrue(re.exec(e.stack) !== null);
+ }
+ return false;
+ });
+ }
+ lazyDeopt();
+ lazyDeopt();
+ %OptimizeFunctionOnNextCall(lazyDeopt);
+ lazyDeopt();
+})();
+
+// An error generated inside a non-inlined callback function also
+// includes find in it's stack trace.
+(() => {
+ const re = /Array\.find/;
+ function lazyDeopt(deopt) {
+ const b = [1, 2, 3];
+ let did_assert_error = false;
+ let result = 0;
+ function callback(v, i) {
+ result += v;
+ if (i === 1) {
+ const e = new Error();
+ assertTrue(re.exec(e.stack) !== null);
+ did_assert_error = true;
+ }
+ return false;
+ }
+ %NeverOptimizeFunction(callback);
+ b.find(callback);
+ return did_assert_error;
+ }
+ lazyDeopt();
+ lazyDeopt();
+ %OptimizeFunctionOnNextCall(lazyDeopt);
+ assertTrue(lazyDeopt());
+})();
+
+// An error generated inside a recently deoptimized callback function
+// includes find in it's stack trace.
+(() => {
+ const re = /Array\.find/;
+ function lazyDeopt(deopt) {
+ const b = [1, 2, 3];
+ let did_assert_error = false;
+ let result = 0;
+ b.find((v, i) => {
+ result += v;
+ if (i === 1) {
+ %DeoptimizeNow();
+ } else if (i === 2) {
+ const e = new Error();
+ assertTrue(re.exec(e.stack) !== null);
+ did_assert_error = true;
+ }
+ return false;
+ });
+ return did_assert_error;
+ }
+ lazyDeopt();
+ lazyDeopt();
+ %OptimizeFunctionOnNextCall(lazyDeopt);
+ assertTrue(lazyDeopt());
+})();
+
+// Verify that various exception edges are handled appropriately.
+// The thrown Error object should always indicate it was created from
+// a find call stack.
+(() => {
+ const re = /Array\.find/;
+ const a = [1, 2, 3];
+ let result = 0;
+ function lazyDeopt() {
+ a.find((v, i) => {
+ result += i;
+ if (i === 1) {
+ %DeoptimizeFunction(lazyDeopt);
+ throw new Error();
+ }
+ return false;
+ });
+ }
+ assertThrows(() => lazyDeopt());
+ assertThrows(() => lazyDeopt());
+ try {
+ lazyDeopt();
+ } catch (e) {
+ assertTrue(re.exec(e.stack) !== null);
+ }
+ %OptimizeFunctionOnNextCall(lazyDeopt);
+ try {
+ lazyDeopt();
+ } catch (e) {
+ assertTrue(re.exec(e.stack) !== null);
+ }
+})();
+
+// Messing with the Array prototype causes deoptimization.
+(() => {
+ const a = [1, 2, 3];
+ let result = 0;
+ function prototypeChanged() {
+ a.find((v, i) => {
+ result += v;
+ return false;
+ });
+ }
+ prototypeChanged();
+ prototypeChanged();
+ %OptimizeFunctionOnNextCall(prototypeChanged);
+ prototypeChanged();
+ a.constructor = {};
+ prototypeChanged();
+ assertUnoptimized(prototypeChanged);
+ assertEquals(24, result);
+})();
+
+// Verify holes are replaced with undefined.
+(() => {
+ const a = [1, 2, , 3, 4];
+ function withHoles() {
+ const callback_values = [];
+ a.find(v => {
+ callback_values.push(v);
+ return false;
+ });
+ return callback_values;
+ }
+ withHoles();
+ withHoles();
+ %OptimizeFunctionOnNextCall(withHoles);
+ assertArrayEquals([1, 2, undefined, 3, 4], withHoles());
+})();
+
+(() => {
+ const a = [1.5, 2.5, , 3.5, 4.5];
+ function withHoles() {
+ const callback_values = [];
+ a.find(v => {
+ callback_values.push(v);
+ return false;
+ });
+ return callback_values;
+ }
+ withHoles();
+ withHoles();
+ %OptimizeFunctionOnNextCall(withHoles);
+ assertArrayEquals([1.5, 2.5, undefined, 3.5, 4.5], withHoles());
+})();
+
+// Ensure that we handle side-effects between load and call.
+(() => {
+ function side_effect(a, b) { if (b) a.foo = 3; return a; }
+ %NeverOptimizeFunction(side_effect);
+
+ function unreliable(a, b) {
+ return a.find(x => false, side_effect(a, b));
+ }
+
+ let a = [1, 2, 3];
+ unreliable(a, false);
+ unreliable(a, false);
+ %OptimizeFunctionOnNextCall(unreliable);
+ unreliable(a, false);
+ // Now actually do change the map.
+ unreliable(a, true);
+})();
+
+// Handle callback is not callable.
+(() => {
+ const a = [1, 2, 3, 4, 5];
+ function notCallable() {
+ return a.find(undefined);
+ }
+
+ assertThrows(notCallable, TypeError);
+ try { notCallable(); } catch(e) { }
+ %OptimizeFunctionOnNextCall(notCallable);
+ assertThrows(notCallable, TypeError);
+})();
diff --git a/deps/v8/test/mjsunit/optimized-array-findindex.js b/deps/v8/test/mjsunit/optimized-array-findindex.js
new file mode 100644
index 0000000000..91f4a6cc60
--- /dev/null
+++ b/deps/v8/test/mjsunit/optimized-array-findindex.js
@@ -0,0 +1,460 @@
+// Copyright 2017 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: --allow-natives-syntax --turbo-inline-array-builtins --opt
+// Flags: --no-always-opt
+
+// Unknown field access leads to soft-deopt unrelated to findIndex, should still
+// lead to correct result.
+(() => {
+ const a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25];
+ let result = 0;
+ function eagerDeoptInCalled(deopt) {
+ return a.findIndex((v, i) => {
+ if (i === 13 && deopt) {
+ a.abc = 25;
+ }
+ result += v;
+ return v === 20;
+ });
+ }
+ eagerDeoptInCalled();
+ eagerDeoptInCalled();
+ %OptimizeFunctionOnNextCall(eagerDeoptInCalled);
+ eagerDeoptInCalled();
+ assertEquals(19, eagerDeoptInCalled(true));
+ eagerDeoptInCalled();
+ assertEquals(1050, result);
+})();
+
+// Length change detected during loop, must cause properly handled eager deopt.
+(() => {
+ let called_values;
+ function eagerDeoptInCalled(deopt) {
+ const a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+ called_values = [];
+ return a.findIndex((v,i) => {
+ called_values.push(v);
+ a.length = (i === 5 && deopt) ? 8 : 10;
+ return v === 9;
+ });
+ }
+ assertEquals(8, eagerDeoptInCalled());
+ assertArrayEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], called_values);
+ eagerDeoptInCalled();
+ %OptimizeFunctionOnNextCall(eagerDeoptInCalled);
+ assertEquals(8, eagerDeoptInCalled());
+ assertEquals(-1, eagerDeoptInCalled(true));
+ assertArrayEquals([1, 2, 3, 4, 5, 6, 7, 8, undefined, undefined],
+ called_values);
+ eagerDeoptInCalled();
+})();
+
+// Lazy deopt from a callback that changes the input array. Deopt in a callback
+// execution that returns true.
+(() => {
+ const a = [1, 2, 3, 4, 5];
+ function lazyChanger(deopt) {
+ return a.findIndex((v, i) => {
+ if (i === 3 && deopt) {
+ a[3] = 3;
+ %DeoptimizeNow();
+ }
+ return v > 3;
+ });
+ }
+ assertEquals(3, lazyChanger());
+ lazyChanger();
+ %OptimizeFunctionOnNextCall(lazyChanger);
+ assertEquals(3, lazyChanger(true));
+ assertEquals(4, lazyChanger());
+})();
+
+// Lazy deopt from a callback that will always return false and no element is
+// found. Verifies the lazy-after-callback continuation builtin.
+(() => {
+ const a = [1, 2, 3, 4, 5];
+ function lazyChanger(deopt) {
+ return a.findIndex((v, i) => {
+ if (i === 3 && deopt) {
+ %DeoptimizeNow();
+ }
+ return false;
+ });
+ }
+ assertEquals(-1, lazyChanger());
+ lazyChanger();
+ %OptimizeFunctionOnNextCall(lazyChanger);
+ assertEquals(-1, lazyChanger(true));
+ assertEquals(-1, lazyChanger());
+})();
+
+// Lazy deopt from a callback that changes the input array. Deopt in a callback
+// execution that returns false.
+(() => {
+ const a = [1, 2, 3, 4, 5];
+ function lazyChanger(deopt) {
+ return a.findIndex((v, i) => {
+ if (i === 2 && deopt) {
+ a[3] = 2;
+ %DeoptimizeNow();
+ }
+ return v > 3;
+ });
+ }
+ assertEquals(3, lazyChanger());
+ lazyChanger();
+ %OptimizeFunctionOnNextCall(lazyChanger);
+ assertEquals(4, lazyChanger(true));
+ assertEquals(4, lazyChanger());
+})();
+
+// Escape analyzed array
+(() => {
+ let result = 0;
+ function eagerDeoptInCalled(deopt) {
+ const a_noescape = [0, 1, 2, 3, 4, 5];
+ a_noescape.findIndex((v, i) => {
+ result += v | 0;
+ if (i === 13 && deopt) {
+ a_noescape.length = 25;
+ }
+ return false;
+ });
+ }
+ eagerDeoptInCalled();
+ eagerDeoptInCalled();
+ %OptimizeFunctionOnNextCall(eagerDeoptInCalled);
+ eagerDeoptInCalled();
+ eagerDeoptInCalled(true);
+ eagerDeoptInCalled();
+ assertEquals(75, result);
+})();
+
+// Lazy deopt from runtime call from inlined callback function.
+(() => {
+ const a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25];
+ let result = 0;
+ function lazyDeopt(deopt) {
+ a.findIndex((v, i) => {
+ result += i;
+ if (i === 13 && deopt) {
+ %DeoptimizeNow();
+ }
+ return false;
+ });
+ }
+ lazyDeopt();
+ lazyDeopt();
+ %OptimizeFunctionOnNextCall(lazyDeopt);
+ lazyDeopt();
+ lazyDeopt(true);
+ lazyDeopt();
+ assertEquals(1500, result);
+})();
+
+// Lazy deopt from runtime call from non-inline callback function.
+(() => {
+ const a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25];
+ let result = 0;
+ function lazyDeopt(deopt) {
+ function callback(v, i) {
+ result += i;
+ if (i === 13 && deopt) {
+ %DeoptimizeNow();
+ }
+ return false;
+ }
+ %NeverOptimizeFunction(callback);
+ a.findIndex(callback);
+ }
+ lazyDeopt();
+ lazyDeopt();
+ %OptimizeFunctionOnNextCall(lazyDeopt);
+ lazyDeopt();
+ lazyDeopt(true);
+ lazyDeopt();
+ assertEquals(1500, result);
+})();
+
+// Call to a.findIndex is done inside a try-catch block and the callback function
+// being called actually throws.
+(() => {
+ const a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25];
+ let caught = false;
+ function lazyDeopt(deopt) {
+ try {
+ a.findIndex((v, i) => {
+ if (i === 1 && deopt) {
+ throw("a");
+ }
+ return false;
+ });
+ } catch (e) {
+ caught = true;
+ }
+ }
+ lazyDeopt();
+ lazyDeopt();
+ %OptimizeFunctionOnNextCall(lazyDeopt);
+ lazyDeopt();
+ assertDoesNotThrow(() => lazyDeopt(true));
+ assertTrue(caught);
+ lazyDeopt();
+})();
+
+// Call to a.findIndex is done inside a try-catch block and the callback function
+// being called actually throws, but the callback is not inlined.
+(() => {
+ let a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+ let caught = false;
+ function lazyDeopt(deopt) {
+ function callback(v, i) {
+ if (i === 1 && deopt) {
+ throw("a");
+ }
+ return false;
+ }
+ %NeverOptimizeFunction(callback);
+ try {
+ a.findIndex(callback);
+ } catch (e) {
+ caught = true;
+ }
+ }
+ lazyDeopt();
+ lazyDeopt();
+ %OptimizeFunctionOnNextCall(lazyDeopt);
+ lazyDeopt();
+ assertDoesNotThrow(() => lazyDeopt(true));
+ assertTrue(caught);
+ lazyDeopt();
+})();
+
+// Call to a.findIndex is done inside a try-catch block and the callback function
+// being called throws into a deoptimized caller function.
+(function TestThrowIntoDeoptimizedOuter() {
+ const a = [1, 2, 3, 4];
+ function lazyDeopt(deopt) {
+ function callback(v, i) {
+ if (i === 1 && deopt) {
+ %DeoptimizeFunction(lazyDeopt);
+ throw "some exception";
+ }
+ return v === 3;
+ }
+ %NeverOptimizeFunction(callback);
+ let result = 0;
+ try {
+ result = a.findIndex(callback);
+ } catch (e) {
+ assertEquals("some exception", e);
+ result = "nope";
+ }
+ return result;
+ }
+ assertEquals(2, lazyDeopt(false));
+ assertEquals(2, lazyDeopt(false));
+ assertEquals("nope", lazyDeopt(true));
+ assertEquals("nope", lazyDeopt(true));
+ %OptimizeFunctionOnNextCall(lazyDeopt);
+ assertEquals(2, lazyDeopt(false));
+ assertEquals("nope", lazyDeopt(true));
+})();
+
+// An error generated inside the callback includes findIndex in it's
+// stack trace.
+(() => {
+ const re = /Array\.findIndex/;
+ function lazyDeopt(deopt) {
+ const b = [1, 2, 3];
+ let result = 0;
+ b.findIndex((v, i) => {
+ result += v;
+ if (i === 1) {
+ const e = new Error();
+ assertTrue(re.exec(e.stack) !== null);
+ }
+ return false;
+ });
+ }
+ lazyDeopt();
+ lazyDeopt();
+ %OptimizeFunctionOnNextCall(lazyDeopt);
+ lazyDeopt();
+})();
+
+// An error generated inside a non-inlined callback function also
+// includes findIndex in it's stack trace.
+(() => {
+ const re = /Array\.findIndex/;
+ function lazyDeopt(deopt) {
+ const b = [1, 2, 3];
+ let did_assert_error = false;
+ let result = 0;
+ function callback(v, i) {
+ result += v;
+ if (i === 1) {
+ const e = new Error();
+ assertTrue(re.exec(e.stack) !== null);
+ did_assert_error = true;
+ }
+ return false;
+ }
+ %NeverOptimizeFunction(callback);
+ b.findIndex(callback);
+ return did_assert_error;
+ }
+ lazyDeopt();
+ lazyDeopt();
+ %OptimizeFunctionOnNextCall(lazyDeopt);
+ assertTrue(lazyDeopt());
+})();
+
+// An error generated inside a recently deoptimized callback function
+// includes findIndex in it's stack trace.
+(() => {
+ const re = /Array\.findIndex/;
+ function lazyDeopt(deopt) {
+ const b = [1, 2, 3];
+ let did_assert_error = false;
+ let result = 0;
+ b.findIndex((v, i) => {
+ result += v;
+ if (i === 1) {
+ %DeoptimizeNow();
+ } else if (i === 2) {
+ const e = new Error();
+ assertTrue(re.exec(e.stack) !== null);
+ did_assert_error = true;
+ }
+ return false;
+ });
+ return did_assert_error;
+ }
+ lazyDeopt();
+ lazyDeopt();
+ %OptimizeFunctionOnNextCall(lazyDeopt);
+ assertTrue(lazyDeopt());
+})();
+
+// Verify that various exception edges are handled appropriately.
+// The thrown Error object should always indicate it was created from
+// a findIndex call stack.
+(() => {
+ const re = /Array\.findIndex/;
+ const a = [1, 2, 3];
+ let result = 0;
+ function lazyDeopt() {
+ a.findIndex((v, i) => {
+ result += i;
+ if (i === 1) {
+ %DeoptimizeFunction(lazyDeopt);
+ throw new Error();
+ }
+ return false;
+ });
+ }
+ assertThrows(() => lazyDeopt());
+ assertThrows(() => lazyDeopt());
+ try {
+ lazyDeopt();
+ } catch (e) {
+ assertTrue(re.exec(e.stack) !== null);
+ }
+ %OptimizeFunctionOnNextCall(lazyDeopt);
+ try {
+ lazyDeopt();
+ } catch (e) {
+ assertTrue(re.exec(e.stack) !== null);
+ }
+})();
+
+// Messing with the Array prototype causes deoptimization.
+(() => {
+ const a = [1, 2, 3];
+ let result = 0;
+ function prototypeChanged() {
+ a.findIndex((v, i) => {
+ result += v;
+ return false;
+ });
+ }
+ prototypeChanged();
+ prototypeChanged();
+ %OptimizeFunctionOnNextCall(prototypeChanged);
+ prototypeChanged();
+ a.constructor = {};
+ prototypeChanged();
+ assertUnoptimized(prototypeChanged);
+ assertEquals(24, result);
+})();
+
+// Verify holes are replaced with undefined.
+(() => {
+ const a = [1, 2, , 3, 4];
+ function withHoles() {
+ const callback_values = [];
+ a.findIndex(v => {
+ callback_values.push(v);
+ return false;
+ });
+ return callback_values;
+ }
+ withHoles();
+ withHoles();
+ %OptimizeFunctionOnNextCall(withHoles);
+ assertArrayEquals([1, 2, undefined, 3, 4], withHoles());
+})();
+
+(() => {
+ const a = [1.5, 2.5, , 3.5, 4.5];
+ function withHoles() {
+ const callback_values = [];
+ a.findIndex(v => {
+ callback_values.push(v);
+ return false;
+ });
+ return callback_values;
+ }
+ withHoles();
+ withHoles();
+ %OptimizeFunctionOnNextCall(withHoles);
+ assertArrayEquals([1.5, 2.5, undefined, 3.5, 4.5], withHoles());
+})();
+
+// Ensure that we handle side-effects between load and call.
+(() => {
+ function side_effect(a, b) { if (b) a.foo = 3; return a; }
+ %NeverOptimizeFunction(side_effect);
+
+ function unreliable(a, b) {
+ return a.findIndex(x => false, side_effect(a, b));
+ }
+
+ let a = [1, 2, 3];
+ unreliable(a, false);
+ unreliable(a, false);
+ %OptimizeFunctionOnNextCall(unreliable);
+ unreliable(a, false);
+ // Now actually do change the map.
+ unreliable(a, true);
+})();
+
+// Handle callback is not callable.
+(() => {
+ const a = [1, 2, 3, 4, 5];
+ function notCallable() {
+ return a.findIndex(undefined);
+ }
+
+ assertThrows(notCallable, TypeError);
+ try { notCallable(); } catch(e) { }
+ %OptimizeFunctionOnNextCall(notCallable);
+ assertThrows(notCallable, TypeError);
+})();
diff --git a/deps/v8/test/mjsunit/optimized-array-some.js b/deps/v8/test/mjsunit/optimized-array-some.js
new file mode 100644
index 0000000000..8d0114aa64
--- /dev/null
+++ b/deps/v8/test/mjsunit/optimized-array-some.js
@@ -0,0 +1,502 @@
+// Copyright 2017 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: --allow-natives-syntax --turbo-inline-array-builtins --opt
+// Flags: --no-always-opt
+
+// Early exit from some functions properly.
+(() => {
+ const a = [1, 2, 3, 4, 5];
+ let result = 0;
+ function earlyExit() {
+ return a.some(v => {
+ result += v;
+ return v > 2;
+ });
+ }
+ assertTrue(earlyExit());
+ earlyExit();
+ %OptimizeFunctionOnNextCall(earlyExit);
+ assertTrue(earlyExit());
+ assertEquals(18, result);
+})();
+
+// Soft-deopt plus early exit.
+(() => {
+ const a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+ let result = 0;
+ function softyPlusEarlyExit(deopt) {
+ return a.some(v => {
+ result += v;
+ if (v === 4 && deopt) {
+ a.abc = 25;
+ }
+ return v > 7;
+ });
+ }
+ assertTrue(softyPlusEarlyExit(false));
+ softyPlusEarlyExit(false);
+ %OptimizeFunctionOnNextCall(softyPlusEarlyExit);
+ assertTrue(softyPlusEarlyExit(true));
+ assertEquals(36*3, result);
+})();
+
+// Soft-deopt synced with early exit, which forces the lazy deoptimization
+// continuation handler to exit.
+(() => {
+ const a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+ let called_values = [];
+ function softyPlusEarlyExit(deopt) {
+ called_values = [];
+ return a.some(v => {
+ called_values.push(v);
+ if (v === 4 && deopt) {
+ a.abc = 25;
+ return true;
+ }
+ return v > 7;
+ });
+ }
+ assertTrue(softyPlusEarlyExit(false));
+ assertArrayEquals([1, 2, 3, 4, 5, 6, 7, 8], called_values);
+ softyPlusEarlyExit(false);
+ %OptimizeFunctionOnNextCall(softyPlusEarlyExit);
+ assertTrue(softyPlusEarlyExit(true));
+ assertArrayEquals([1, 2, 3, 4], called_values);
+})();
+
+// Unknown field access leads to soft-deopt unrelated to some, should still
+// lead to correct result.
+(() => {
+ const a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25];
+ let result = 0;
+ function eagerDeoptInCalled(deopt) {
+ return a.some((v, i) => {
+ if (i === 13 && deopt) {
+ a.abc = 25;
+ }
+ result += v;
+ return false;
+ });
+ }
+ eagerDeoptInCalled();
+ eagerDeoptInCalled();
+ %OptimizeFunctionOnNextCall(eagerDeoptInCalled);
+ eagerDeoptInCalled();
+ assertFalse(eagerDeoptInCalled(true));
+ eagerDeoptInCalled();
+ assertEquals(1625, result);
+})();
+
+// Length change detected during loop, must cause properly handled eager deopt.
+(() => {
+ let called_values;
+ function eagerDeoptInCalled(deopt) {
+ const a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+ called_values = [];
+ return a.some((v,i) => {
+ called_values.push(v);
+ a.length = (i === 5 && deopt) ? 8 : 10;
+ return false;
+ });
+ }
+ assertFalse(eagerDeoptInCalled());
+ assertArrayEquals([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], called_values);
+ eagerDeoptInCalled();
+ %OptimizeFunctionOnNextCall(eagerDeoptInCalled);
+ assertFalse(eagerDeoptInCalled());
+ assertFalse(eagerDeoptInCalled(true));
+ assertArrayEquals([1, 2, 3, 4, 5, 6, 7, 8], called_values);
+ eagerDeoptInCalled();
+})();
+
+// Lazy deopt from a callback that changes the input array. Deopt in a callback
+// execution that returns true.
+(() => {
+ const a = [1, 2, 3, 4, 5];
+ function lazyChanger(deopt) {
+ return a.some((v, i) => {
+ if (i === 3 && deopt) {
+ a[3] = 100;
+ %DeoptimizeNow();
+ }
+ return false;
+ });
+ }
+ assertFalse(lazyChanger());
+ lazyChanger();
+ %OptimizeFunctionOnNextCall(lazyChanger);
+ assertFalse(lazyChanger(true));
+ assertFalse(lazyChanger());
+})();
+
+// Lazy deopt from a callback that will always return false and no element is
+// found. Verifies the lazy-after-callback continuation builtin.
+(() => {
+ const a = [1, 2, 3, 4, 5];
+ function lazyChanger(deopt) {
+ return a.some((v, i) => {
+ if (i === 3 && deopt) {
+ %DeoptimizeNow();
+ }
+ return false;
+ });
+ }
+ assertFalse(lazyChanger());
+ lazyChanger();
+ %OptimizeFunctionOnNextCall(lazyChanger);
+ assertFalse(lazyChanger(true));
+ assertFalse(lazyChanger());
+})();
+
+// Lazy deopt from a callback that changes the input array. Deopt in a callback
+// execution that returns false.
+(() => {
+ const a = [1, 2, 3, 4, 5];
+ function lazyChanger(deopt) {
+ return a.every((v, i) => {
+ if (i === 2 && deopt) {
+ a[3] = 100;
+ %DeoptimizeNow();
+ }
+ return false;
+ });
+ }
+ assertFalse(lazyChanger());
+ lazyChanger();
+ %OptimizeFunctionOnNextCall(lazyChanger);
+ assertFalse(lazyChanger(true));
+ assertFalse(lazyChanger());
+})();
+
+// Escape analyzed array
+(() => {
+ let result = 0;
+ function eagerDeoptInCalled(deopt) {
+ const a_noescape = [0, 1, 2, 3, 4, 5];
+ a_noescape.some((v, i) => {
+ result += v | 0;
+ if (i === 13 && deopt) {
+ a_noescape.length = 25;
+ }
+ return false;
+ });
+ }
+ eagerDeoptInCalled();
+ eagerDeoptInCalled();
+ %OptimizeFunctionOnNextCall(eagerDeoptInCalled);
+ eagerDeoptInCalled();
+ eagerDeoptInCalled(true);
+ eagerDeoptInCalled();
+ assertEquals(75, result);
+})();
+
+// Lazy deopt from runtime call from inlined callback function.
+(() => {
+ const a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25];
+ let result = 0;
+ function lazyDeopt(deopt) {
+ a.some((v, i) => {
+ result += i;
+ if (i === 13 && deopt) {
+ %DeoptimizeNow();
+ }
+ return false;
+ });
+ }
+ lazyDeopt();
+ lazyDeopt();
+ %OptimizeFunctionOnNextCall(lazyDeopt);
+ lazyDeopt();
+ lazyDeopt(true);
+ lazyDeopt();
+ assertEquals(1500, result);
+})();
+
+// Lazy deopt from runtime call from non-inline callback function.
+(() => {
+ const a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25];
+ let result = 0;
+ function lazyDeopt(deopt) {
+ function callback(v, i) {
+ result += i;
+ if (i === 13 && deopt) {
+ %DeoptimizeNow();
+ }
+ return false;
+ }
+ %NeverOptimizeFunction(callback);
+ a.some(callback);
+ }
+ lazyDeopt();
+ lazyDeopt();
+ %OptimizeFunctionOnNextCall(lazyDeopt);
+ lazyDeopt();
+ lazyDeopt(true);
+ lazyDeopt();
+ assertEquals(1500, result);
+})();
+
+// Call to a.some is done inside a try-catch block and the callback function
+// being called actually throws.
+(() => {
+ const a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25];
+ let caught = false;
+ function lazyDeopt(deopt) {
+ try {
+ a.some((v, i) => {
+ if (i === 1 && deopt) {
+ throw("a");
+ }
+ return false;
+ });
+ } catch (e) {
+ caught = true;
+ }
+ }
+ lazyDeopt();
+ lazyDeopt();
+ %OptimizeFunctionOnNextCall(lazyDeopt);
+ lazyDeopt();
+ assertDoesNotThrow(() => lazyDeopt(true));
+ assertTrue(caught);
+ lazyDeopt();
+})();
+
+// Call to a.some is done inside a try-catch block and the callback function
+// being called actually throws, but the callback is not inlined.
+(() => {
+ let a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+ let caught = false;
+ function lazyDeopt(deopt) {
+ function callback(v, i) {
+ if (i === 1 && deopt) {
+ throw("a");
+ }
+ return false;
+ }
+ %NeverOptimizeFunction(callback);
+ try {
+ a.some(callback);
+ } catch (e) {
+ caught = true;
+ }
+ }
+ lazyDeopt();
+ lazyDeopt();
+ %OptimizeFunctionOnNextCall(lazyDeopt);
+ lazyDeopt();
+ assertDoesNotThrow(() => lazyDeopt(true));
+ assertTrue(caught);
+ lazyDeopt();
+})();
+
+// Call to a.some is done inside a try-catch block and the callback function
+// being called throws into a deoptimized caller function.
+(function TestThrowIntoDeoptimizedOuter() {
+ const a = [1, 2, 3, 4];
+ function lazyDeopt(deopt) {
+ function callback(v, i) {
+ if (i === 1 && deopt) {
+ %DeoptimizeFunction(lazyDeopt);
+ throw "some exception";
+ }
+ return false;
+ }
+ %NeverOptimizeFunction(callback);
+ let result = 0;
+ try {
+ result = a.some(callback);
+ } catch (e) {
+ assertEquals("some exception", e);
+ result = "nope";
+ }
+ return result;
+ }
+ assertEquals(false, lazyDeopt(false));
+ assertEquals(false, lazyDeopt(false));
+ assertEquals("nope", lazyDeopt(true));
+ assertEquals("nope", lazyDeopt(true));
+ %OptimizeFunctionOnNextCall(lazyDeopt);
+ assertEquals(false, lazyDeopt(false));
+ assertEquals("nope", lazyDeopt(true));
+})();
+
+// An error generated inside the callback includes some in it's
+// stack trace.
+(() => {
+ const re = /Array\.some/;
+ function lazyDeopt(deopt) {
+ const b = [1, 2, 3];
+ let result = 0;
+ b.some((v, i) => {
+ result += v;
+ if (i === 1) {
+ const e = new Error();
+ assertTrue(re.exec(e.stack) !== null);
+ }
+ return false;
+ });
+ }
+ lazyDeopt();
+ lazyDeopt();
+ %OptimizeFunctionOnNextCall(lazyDeopt);
+ lazyDeopt();
+})();
+
+// An error generated inside a non-inlined callback function also
+// includes some in it's stack trace.
+(() => {
+ const re = /Array\.some/;
+ function lazyDeopt(deopt) {
+ const b = [1, 2, 3];
+ let did_assert_error = false;
+ let result = 0;
+ function callback(v, i) {
+ result += v;
+ if (i === 1) {
+ const e = new Error();
+ assertTrue(re.exec(e.stack) !== null);
+ did_assert_error = true;
+ }
+ return false;
+ }
+ %NeverOptimizeFunction(callback);
+ b.some(callback);
+ return did_assert_error;
+ }
+ lazyDeopt();
+ lazyDeopt();
+ %OptimizeFunctionOnNextCall(lazyDeopt);
+ assertTrue(lazyDeopt());
+})();
+
+// An error generated inside a recently deoptimized callback function
+// includes some in it's stack trace.
+(() => {
+ const re = /Array\.some/;
+ function lazyDeopt(deopt) {
+ const b = [1, 2, 3];
+ let did_assert_error = false;
+ let result = 0;
+ b.some((v, i) => {
+ result += v;
+ if (i === 1) {
+ %DeoptimizeNow();
+ } else if (i === 2) {
+ const e = new Error();
+ assertTrue(re.exec(e.stack) !== null);
+ did_assert_error = true;
+ }
+ return false;
+ });
+ return did_assert_error;
+ }
+ lazyDeopt();
+ lazyDeopt();
+ %OptimizeFunctionOnNextCall(lazyDeopt);
+ assertTrue(lazyDeopt());
+})();
+
+// Verify that various exception edges are handled appropriately.
+// The thrown Error object should always indicate it was created from
+// a some call stack.
+(() => {
+ const re = /Array\.some/;
+ const a = [1, 2, 3];
+ let result = 0;
+ function lazyDeopt() {
+ a.some((v, i) => {
+ result += i;
+ if (i === 1) {
+ %DeoptimizeFunction(lazyDeopt);
+ throw new Error();
+ }
+ return false;
+ });
+ }
+ assertThrows(() => lazyDeopt());
+ assertThrows(() => lazyDeopt());
+ try {
+ lazyDeopt();
+ } catch (e) {
+ assertTrue(re.exec(e.stack) !== null);
+ }
+ %OptimizeFunctionOnNextCall(lazyDeopt);
+ try {
+ lazyDeopt();
+ } catch (e) {
+ assertTrue(re.exec(e.stack) !== null);
+ }
+})();
+
+// Messing with the Array prototype causes deoptimization.
+(() => {
+ const a = [1, 2, 3];
+ let result = 0;
+ function prototypeChanged() {
+ a.some((v, i) => {
+ result += v;
+ return false;
+ });
+ }
+ prototypeChanged();
+ prototypeChanged();
+ %OptimizeFunctionOnNextCall(prototypeChanged);
+ prototypeChanged();
+ a.constructor = {};
+ prototypeChanged();
+ assertUnoptimized(prototypeChanged);
+ assertEquals(24, result);
+})();
+
+// Verify holes are skipped.
+(() => {
+ const a = [1, 2, , 3, 4];
+ function withHoles() {
+ const callback_values = [];
+ a.some(v => {
+ callback_values.push(v);
+ return false;
+ });
+ return callback_values;
+ }
+ withHoles();
+ withHoles();
+ %OptimizeFunctionOnNextCall(withHoles);
+ assertArrayEquals([1, 2, 3, 4], withHoles());
+})();
+
+(() => {
+ const a = [1.5, 2.5, , 3.5, 4.5];
+ function withHoles() {
+ const callback_values = [];
+ a.some(v => {
+ callback_values.push(v);
+ return false;
+ });
+ return callback_values;
+ }
+ withHoles();
+ withHoles();
+ %OptimizeFunctionOnNextCall(withHoles);
+ assertArrayEquals([1.5, 2.5, 3.5, 4.5], withHoles());
+})();
+
+// Handle callback is not callable.
+(() => {
+ const a = [1, 2, 3, 4, 5];
+ function notCallable() {
+ return a.some(undefined);
+ }
+
+ assertThrows(notCallable, TypeError);
+ try { notCallable(); } catch(e) { }
+ %OptimizeFunctionOnNextCall(notCallable);
+ assertThrows(notCallable, TypeError);
+})();
diff --git a/deps/v8/test/mjsunit/optimized-filter.js b/deps/v8/test/mjsunit/optimized-filter.js
index b13edc3b36..3c7d827e0f 100644
--- a/deps/v8/test/mjsunit/optimized-filter.js
+++ b/deps/v8/test/mjsunit/optimized-filter.js
@@ -417,6 +417,59 @@
}
})();
+// Verify holes are skipped.
+(() => {
+ const a = [1, 2, , 3, 4];
+ let callback_values = [];
+ function withHoles() {
+ callback_values = [];
+ return a.filter(v => {
+ callback_values.push(v);
+ return true;
+ });
+ }
+ withHoles();
+ withHoles();
+ %OptimizeFunctionOnNextCall(withHoles);
+ assertArrayEquals([1, 2, 3, 4], withHoles());
+ assertArrayEquals([1, 2, 3, 4], callback_values);
+})();
+
+(() => {
+ const a = [1.5, 2.5, , 3.5, 4.5];
+ let callback_values = [];
+ function withHoles() {
+ callback_values = [];
+ return a.filter(v => {
+ callback_values.push(v);
+ return true;
+ });
+ }
+ withHoles();
+ withHoles();
+ %OptimizeFunctionOnNextCall(withHoles);
+ assertArrayEquals([1.5, 2.5, 3.5, 4.5], withHoles());
+ assertArrayEquals([1.5, 2.5, 3.5, 4.5], callback_values);
+})();
+
+// Ensure that we handle side-effects between load and call.
+(() => {
+ function side_effect(a, b) { if (b) a.foo = 3; return a; }
+ %NeverOptimizeFunction(side_effect);
+
+ function unreliable(a, b) {
+ return a.filter(x => x % 2 === 0, side_effect(a, b));
+ }
+
+ let a = [1, 2, 3];
+ unreliable(a, false);
+ unreliable(a, false);
+ %OptimizeFunctionOnNextCall(unreliable);
+ unreliable(a, false);
+ // Now actually do change the map.
+ unreliable(a, true);
+})();
+
// Messing with the Array species constructor causes deoptimization.
(function() {
var result = 0;
diff --git a/deps/v8/test/mjsunit/optimized-foreach.js b/deps/v8/test/mjsunit/optimized-foreach.js
index f3513f3838..1fe54b5e9f 100644
--- a/deps/v8/test/mjsunit/optimized-foreach.js
+++ b/deps/v8/test/mjsunit/optimized-foreach.js
@@ -343,3 +343,53 @@ var c = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25];
assertTrue(re.exec(e.stack) !== null);
}
})();
+
+// Verify holes are skipped.
+(() => {
+ const a = [1, 2, , 3, 4];
+ function withHoles() {
+ const callback_values = [];
+ a.forEach(v => {
+ callback_values.push(v);
+ });
+ return callback_values;
+ }
+ withHoles();
+ withHoles();
+ %OptimizeFunctionOnNextCall(withHoles);
+ assertArrayEquals([1, 2, 3, 4], withHoles());
+})();
+
+(() => {
+ const a = [1.5, 2.5, , 3.5, 4.5];
+ function withHoles() {
+ const callback_values = [];
+ a.forEach(v => {
+ callback_values.push(v);
+ });
+ return callback_values;
+ }
+ withHoles();
+ withHoles();
+ %OptimizeFunctionOnNextCall(withHoles);
+ assertArrayEquals([1.5, 2.5, 3.5, 4.5], withHoles());
+})();
+
+// Ensure that we handle side-effects between load and call.
+(() => {
+ function side_effect(a, b) { if (b) a.foo = 3; return a; }
+ %NeverOptimizeFunction(side_effect);
+
+ function unreliable(a, b) {
+ let sum = 0;
+ return a.forEach(x => sum += x, side_effect(a, b));
+ }
+
+ let a = [1, 2, 3];
+ unreliable(a, false);
+ unreliable(a, false);
+ %OptimizeFunctionOnNextCall(unreliable);
+ unreliable(a, false);
+ // Now actually do change the map.
+ unreliable(a, true);
+})();
diff --git a/deps/v8/test/mjsunit/optimized-map.js b/deps/v8/test/mjsunit/optimized-map.js
index d8613e0300..6a3df4d7d4 100644
--- a/deps/v8/test/mjsunit/optimized-map.js
+++ b/deps/v8/test/mjsunit/optimized-map.js
@@ -468,6 +468,59 @@ var c = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25];
assertEquals("hello1", string_results()[0]);
})();
+// Verify holes are not visited.
+(() => {
+ const a = [1, 2, , 3, 4];
+ let callback_values = [];
+ function withHoles() {
+ callback_values = [];
+ return a.map(v => {
+ callback_values.push(v);
+ return v;
+ });
+ }
+ withHoles();
+ withHoles();
+ %OptimizeFunctionOnNextCall(withHoles);
+ assertArrayEquals([1, 2, , 3, 4], withHoles());
+ assertArrayEquals([1, 2, 3, 4], callback_values);
+})();
+
+(() => {
+ const a = [1.5, 2.5, , 3.5, 4.5];
+ let callback_values = [];
+ function withHoles() {
+ callback_values = [];
+ return a.map(v => {
+ callback_values.push(v);
+ return v;
+ });
+ }
+ withHoles();
+ withHoles();
+ %OptimizeFunctionOnNextCall(withHoles);
+ assertArrayEquals([1.5, 2.5, , 3.5, 4.5], withHoles());
+ assertArrayEquals([1.5, 2.5, 3.5, 4.5], callback_values);
+})();
+
+// Ensure that we handle side-effects between load and call.
+(() => {
+ function side_effect(a, b) { if (b) a.foo = 3; return a; }
+ %NeverOptimizeFunction(side_effect);
+
+ function unreliable(a, b) {
+ return a.map(x => x * 2, side_effect(a, b));
+ }
+
+ let a = [1, 2, 3];
+ unreliable(a, false);
+ unreliable(a, false);
+ %OptimizeFunctionOnNextCall(unreliable);
+ unreliable(a, false);
+ // Now actually do change the map.
+ unreliable(a, true);
+})();
+
// Messing with the Array species constructor causes deoptimization.
(function() {
var result = 0;
diff --git a/deps/v8/test/mjsunit/regress/modules-skip-regress-797581-1.js b/deps/v8/test/mjsunit/regress/modules-skip-regress-797581-1.js
new file mode 100644
index 0000000000..1aa55aa9fb
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/modules-skip-regress-797581-1.js
@@ -0,0 +1,5 @@
+// Copyright 2018 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.
+
+export default ()
diff --git a/deps/v8/test/mjsunit/regress/modules-skip-regress-797581-2.js b/deps/v8/test/mjsunit/regress/modules-skip-regress-797581-2.js
new file mode 100644
index 0000000000..855aa2e9d7
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/modules-skip-regress-797581-2.js
@@ -0,0 +1,5 @@
+// Copyright 2018 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.
+
+export default (...)
diff --git a/deps/v8/test/mjsunit/regress/modules-skip-regress-797581-3.js b/deps/v8/test/mjsunit/regress/modules-skip-regress-797581-3.js
new file mode 100644
index 0000000000..e6d043d2ce
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/modules-skip-regress-797581-3.js
@@ -0,0 +1,5 @@
+// Copyright 2018 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.
+
+export default (a, ...b)
diff --git a/deps/v8/test/mjsunit/regress/modules-skip-regress-797581-4.js b/deps/v8/test/mjsunit/regress/modules-skip-regress-797581-4.js
new file mode 100644
index 0000000000..fc7968d03d
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/modules-skip-regress-797581-4.js
@@ -0,0 +1,5 @@
+// Copyright 2018 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.
+
+export default 1, 2;
diff --git a/deps/v8/test/mjsunit/regress/modules-skip-regress-797581-5.js b/deps/v8/test/mjsunit/regress/modules-skip-regress-797581-5.js
new file mode 100644
index 0000000000..10864c260f
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/modules-skip-regress-797581-5.js
@@ -0,0 +1,6 @@
+// Copyright 2018 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.
+
+let x;
+export default x = 0;
diff --git a/deps/v8/test/mjsunit/regress/regress-2646.js b/deps/v8/test/mjsunit/regress/regress-2646.js
index c51a28060c..ef72556e04 100644
--- a/deps/v8/test/mjsunit/regress/regress-2646.js
+++ b/deps/v8/test/mjsunit/regress/regress-2646.js
@@ -25,8 +25,6 @@
// (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: --heap-stats
-
var expectedItemsCount = 10000,
itemSize = 5,
heap = new ArrayBuffer(expectedItemsCount * itemSize * 8),
diff --git a/deps/v8/test/mjsunit/regress/regress-370827.js b/deps/v8/test/mjsunit/regress/regress-370827.js
index 5536d5196b..e6d5185e70 100644
--- a/deps/v8/test/mjsunit/regress/regress-370827.js
+++ b/deps/v8/test/mjsunit/regress/regress-370827.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: --allow-natives-syntax --expose-gc --heap-stats
+// Flags: --allow-natives-syntax --expose-gc
function g(dummy, x) {
var start = "";
diff --git a/deps/v8/test/mjsunit/regress/regress-599717.js b/deps/v8/test/mjsunit/regress/regress-599717.js
index 94a41ce4d3..51831860e9 100644
--- a/deps/v8/test/mjsunit/regress/regress-599717.js
+++ b/deps/v8/test/mjsunit/regress/regress-599717.js
@@ -15,7 +15,7 @@ function __f_61(stdlib, foreign, buffer) {
}
var ok = false;
try {
- var __v_12 = new ArrayBuffer(1 << 30);
+ var __v_12 = new ArrayBuffer(2147483648);
ok = true;
} catch (e) {
// Can happen on 32 bit systems.
diff --git a/deps/v8/test/mjsunit/regress/regress-791334.js b/deps/v8/test/mjsunit/regress/regress-791334.js
new file mode 100644
index 0000000000..9f2748fdad
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-791334.js
@@ -0,0 +1,8 @@
+// Copyright 2017 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.
+
+// MODULE
+
+let foo = () => { return this };
+assertEquals(undefined, foo());
diff --git a/deps/v8/test/mjsunit/regress/regress-791958.js b/deps/v8/test/mjsunit/regress/regress-791958.js
new file mode 100644
index 0000000000..443ef6e359
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-791958.js
@@ -0,0 +1,15 @@
+// Copyright 2017 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: --allow-natives-syntax
+
+obj = {m: print};
+function foo() {
+ for (var x = -536870912; x != -536870903; ++x) {
+ obj.m(-x >= 1000000 ? x % 1000000 : y);
+ }
+}
+foo();
+%OptimizeFunctionOnNextCall(foo);
+foo();
diff --git a/deps/v8/test/mjsunit/regress/regress-793588.js b/deps/v8/test/mjsunit/regress/regress-793588.js
new file mode 100644
index 0000000000..6ad7a76e2a
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-793588.js
@@ -0,0 +1,13 @@
+// Copyright 2017 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
+
+assertNull(/a\P{Any}a/u.exec("a\u{d83d}a"));
+assertEquals(["a\u{d83d}a"], /a\p{Any}a/u.exec("a\u{d83d}a"));
+assertEquals(["a\u{d83d}a"], /(?:a\P{Any}a|a\p{Any}a)/u.exec("a\u{d83d}a"));
+assertNull(/a[\P{Any}]a/u.exec("a\u{d83d}a"));
+assertEquals(["a\u{d83d}a"], /a[^\P{Any}]a/u.exec("a\u{d83d}a"));
+assertEquals(["a\u{d83d}a"], /a[^\P{Any}x]a/u.exec("a\u{d83d}a"));
+assertNull(/a[^\P{Any}x]a/u.exec("axa"));
diff --git a/deps/v8/test/mjsunit/regress/regress-796427.js b/deps/v8/test/mjsunit/regress/regress-796427.js
new file mode 100644
index 0000000000..c09688d1ec
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-796427.js
@@ -0,0 +1,7 @@
+// Copyright 2017 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: --stack-size=150
+
+assertThrows(() => "" + { toString: Object.prototype.toLocaleString }, RangeError);
diff --git a/deps/v8/test/mjsunit/regress/regress-797481.js b/deps/v8/test/mjsunit/regress/regress-797481.js
new file mode 100644
index 0000000000..7963dbd3b7
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-797481.js
@@ -0,0 +1,10 @@
+// Copyright 2017 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: --stack-size=100
+
+const a = /x/;
+
+a.exec = RegExp.prototype.test;
+assertThrows(() => RegExp.prototype.test.call(a), RangeError);
diff --git a/deps/v8/test/mjsunit/regress/regress-797581.js b/deps/v8/test/mjsunit/regress/regress-797581.js
new file mode 100644
index 0000000000..17ac0ea50d
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-797581.js
@@ -0,0 +1,29 @@
+// Copyright 2018 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: --allow-natives-syntax --harmony-dynamic-import
+
+function TryToLoadModule(filename, expect_error, token) {
+ let caught_error;
+
+ function SetError(e) {
+ caught_error = e;
+ }
+
+ import(filename).catch(SetError);
+ %RunMicrotasks();
+
+ if (expect_error) {
+ assertTrue(caught_error instanceof SyntaxError);
+ assertEquals("Unexpected token " + token, caught_error.message);
+ } else {
+ assertEquals(undefined, caught_error);
+ }
+}
+
+TryToLoadModule("modules-skip-regress-797581-1.js", true, ")");
+TryToLoadModule("modules-skip-regress-797581-2.js", true, ")");
+TryToLoadModule("modules-skip-regress-797581-3.js", true, "...");
+TryToLoadModule("modules-skip-regress-797581-4.js", true, ",");
+TryToLoadModule("modules-skip-regress-797581-5.js", false);
diff --git a/deps/v8/test/mjsunit/regress/regress-800538.js b/deps/v8/test/mjsunit/regress/regress-800538.js
new file mode 100644
index 0000000000..bc420d676c
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-800538.js
@@ -0,0 +1,6 @@
+// Copyright 2018 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.
+
+RegExp.prototype.__defineGetter__("global", () => true);
+assertEquals("/()/g", /()/.toString());
diff --git a/deps/v8/test/mjsunit/regress/regress-801171.js b/deps/v8/test/mjsunit/regress/regress-801171.js
new file mode 100644
index 0000000000..4bd85eeafc
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-801171.js
@@ -0,0 +1,20 @@
+// Copyright 2018 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.
+
+let called_custom_unicode_getter = false;
+const re = /./;
+
+function f() {
+ re.__defineGetter__("unicode", function() {
+ called_custom_unicode_getter = true;
+ });
+ return 2;
+}
+
+assertEquals(["","",], re[Symbol.split]("abc", { valueOf: f }));
+
+// The spec mandates retrieving the regexp instance's flags before
+// ToUint(limit), i.e. the unicode getter must still be unmodified when
+// flags are retrieved.
+assertFalse(called_custom_unicode_getter);
diff --git a/deps/v8/test/mjsunit/regress/regress-801772.js b/deps/v8/test/mjsunit/regress/regress-801772.js
new file mode 100644
index 0000000000..06597e251a
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-801772.js
@@ -0,0 +1,9 @@
+// Copyright 2018 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function foo(f) { f(); }
+
+foo(function arguments() {
+ function skippable() { }
+});
diff --git a/deps/v8/test/mjsunit/regress/regress-802060.js b/deps/v8/test/mjsunit/regress/regress-802060.js
new file mode 100644
index 0000000000..e975615484
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-802060.js
@@ -0,0 +1,24 @@
+// Copyright 2018 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: --allow-natives-syntax
+
+function assertEquals(expected, found) {
+ found.length !== expected.length;
+}
+assertEquals([], [])
+assertEquals("a", "a");
+assertEquals([], []);
+function f() {
+ assertEquals(0, undefined);
+}
+try {
+ f();
+} catch (e) {
+}
+%OptimizeFunctionOnNextCall(f);
+try {
+ f();
+} catch (e) {
+}
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-789764.js b/deps/v8/test/mjsunit/regress/regress-crbug-789764.js
new file mode 100644
index 0000000000..c377e644fc
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-789764.js
@@ -0,0 +1,15 @@
+// Copyright 2017 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.
+
+// Original repro (used to crash):
+_v3 = ({ _v7 = (function outer() {
+ for ([...[]][function inner() {}] in []) {
+ }
+ })} = {}) => {
+};
+_v3();
+
+// Smaller repro (used to crash):
+a = (b = !function outer() { for (function inner() {}.foo in []) {} }) => {};
+a();
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-791245-1.js b/deps/v8/test/mjsunit/regress/regress-crbug-791245-1.js
new file mode 100644
index 0000000000..0d51f8a4a0
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-791245-1.js
@@ -0,0 +1,18 @@
+// Copyright 2017 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: --allow-natives-syntax
+
+const s = new Map;
+
+function foo(s) {
+ const i = s[Symbol.iterator]();
+ i.next();
+ return i;
+}
+
+console.log(foo(s));
+console.log(foo(s));
+%OptimizeFunctionOnNextCall(foo);
+console.log(foo(s));
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-791245-2.js b/deps/v8/test/mjsunit/regress/regress-crbug-791245-2.js
new file mode 100644
index 0000000000..6734ed2baa
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-791245-2.js
@@ -0,0 +1,18 @@
+// Copyright 2017 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: --allow-natives-syntax
+
+const s = new Set;
+
+function foo(s) {
+ const i = s[Symbol.iterator]();
+ i.next();
+ return i;
+}
+
+console.log(foo(s));
+console.log(foo(s));
+%OptimizeFunctionOnNextCall(foo);
+console.log(foo(s));
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-795922.js b/deps/v8/test/mjsunit/regress/regress-crbug-795922.js
new file mode 100644
index 0000000000..da2b36740e
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-795922.js
@@ -0,0 +1,9 @@
+// Copyright 2017 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.
+
+assertThrows(
+ // Should throw a syntax error, but not crash.
+ "({ __proto__: null, __proto__: 1 })",
+ SyntaxError
+);
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-798644.js b/deps/v8/test/mjsunit/regress/regress-crbug-798644.js
new file mode 100644
index 0000000000..c878a6fda8
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-798644.js
@@ -0,0 +1,21 @@
+// Copyright 2018 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: --allow-natives-syntax
+
+let arr = [];
+// Make the array large enough to trigger re-checking for compaction.
+arr[1000] = 0x1234;
+
+arr.__defineGetter__(256, function () {
+ // Remove the getter so we can compact the array.
+ delete arr[256];
+ // Trigger compaction.
+ arr.unshift(1.1);
+});
+
+let results = Object.entries(arr);
+%HeapObjectVerify(results);
+%HeapObjectVerify(arr);
+let str = results.toString();
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-800077.js b/deps/v8/test/mjsunit/regress/regress-crbug-800077.js
new file mode 100644
index 0000000000..13679073fe
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-800077.js
@@ -0,0 +1,6 @@
+// Copyright 2018 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.
+
+var sample = new Float64Array(1);
+Reflect.has(sample, undefined);
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-800810.js b/deps/v8/test/mjsunit/regress/regress-crbug-800810.js
new file mode 100644
index 0000000000..22ac38833e
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-800810.js
@@ -0,0 +1,13 @@
+// Copyright 2018 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.
+
+var array = [];
+Object.defineProperty(array , 506519, {});
+Object.defineProperty(array , 3, {
+ get: function () {
+ Object.defineProperty(array , undefined, {
+ })
+ }
+});
+array.includes(61301);
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-807096.js b/deps/v8/test/mjsunit/regress/regress-crbug-807096.js
new file mode 100644
index 0000000000..845120db6a
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-807096.js
@@ -0,0 +1,27 @@
+// Copyright 2018 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: --allow-natives-syntax --no-lazy
+
+// For regression testing, it's important that these functions are:
+// 1) toplevel
+// 2) arrow functions with single-expression bodies
+// 3) eagerly compiled
+
+let f = ({a = (({b = {a = c} = {
+ a: 0x1234
+}}) => 1)({})}, c) => 1;
+
+assertThrows(() => f({}), ReferenceError);
+
+let g = ({a = (async ({b = {a = c} = {
+ a: 0x1234
+}}) => 1)({})}, c) => a;
+
+testAsync(assert => {
+ assert.plan(1);
+ g({}).catch(e => {
+ assert.equals("ReferenceError", e.name);
+ });
+});
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-808192.js b/deps/v8/test/mjsunit/regress/regress-crbug-808192.js
new file mode 100644
index 0000000000..3336c0043e
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-808192.js
@@ -0,0 +1,32 @@
+// Copyright 2018 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.
+
+// TODO(cbruni): enable always opt once v8:7438
+// Flags: --expose-gc --no-always-opt
+
+const f = eval(`(function f(i) {
+ if (i == 0) {
+ class Derived extends Object {
+ constructor() {
+ super();
+ ${"this.a=1;".repeat(0x3fffe-8)}
+ }
+ }
+ return Derived;
+ }
+
+ class DerivedN extends f(i-1) {
+ constructor() {
+ super();
+ ${"this.a=1;".repeat(0x40000-8)}
+ }
+ }
+
+ return DerivedN;
+})`);
+
+let a = new (f(0x7ff))();
+a.a = 1;
+gc();
+assertEquals(1, a.a);
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-813427.js b/deps/v8/test/mjsunit/regress/regress-crbug-813427.js
new file mode 100644
index 0000000000..95fa015de2
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-813427.js
@@ -0,0 +1,49 @@
+// Copyright 2018 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: --allow-natives-syntax
+
+// Create {count} property assignments.
+function createPropertiesAssignment(count) {
+ let result = "";
+ for (let i = 0; i < count; i++) {
+ result += "this.p"+i+" = undefined;";
+ }
+ return result;
+}
+
+function testSubclassProtoProperties(count) {
+ const MyClass = eval(`(class MyClass {
+ constructor() {
+ ${createPropertiesAssignment(count)}
+ }
+ });`);
+
+ class BaseClass {};
+ class SubClass extends BaseClass {
+ constructor() {
+ super()
+ }
+ };
+
+ const boundMyClass = MyClass.bind();
+ %HeapObjectVerify(boundMyClass);
+
+ SubClass.__proto__ = boundMyClass;
+ var instance = new SubClass();
+
+ %HeapObjectVerify(instance);
+ // Create some more instances to complete in-object slack tracking.
+ let results = [];
+ for (let i = 0; i < 4000; i++) {
+ results.push(new SubClass());
+ }
+ var instance = new SubClass();
+ %HeapObjectVerify(instance);
+}
+
+
+for (let count = 0; count < 10; count++) {
+ testSubclassProtoProperties(count);
+}
diff --git a/deps/v8/test/mjsunit/regress/regress-v8-7245.js b/deps/v8/test/mjsunit/regress/regress-v8-7245.js
new file mode 100644
index 0000000000..c1a9df2bb3
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-v8-7245.js
@@ -0,0 +1,6 @@
+// Copyright 2017 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.
+
+const { revoke } = Proxy.revocable({}, {});
+assertEquals("", revoke.name);
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-791810.js b/deps/v8/test/mjsunit/regress/wasm/regress-791810.js
new file mode 100644
index 0000000000..cd6c4e2728
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-791810.js
@@ -0,0 +1,21 @@
+// Copyright 2017 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.
+
+load('test/mjsunit/wasm/wasm-constants.js');
+load('test/mjsunit/wasm/wasm-module-builder.js');
+
+const builder = new WasmModuleBuilder();
+builder.addFunction('test', kSig_i_i)
+ .addBody([
+ kExprGetLocal, 0x00, // get_local 0
+ kExprBlock, kWasmStmt, // block
+ kExprBr, 0x00, // br depth=0
+ kExprEnd, // end
+ kExprBlock, kWasmStmt, // block
+ kExprBr, 0x00, // br depth=0
+ kExprEnd, // end
+ kExprBr, 0x00, // br depth=0
+ ])
+ .exportFunc();
+builder.instantiate();
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-793551.js b/deps/v8/test/mjsunit/regress/wasm/regress-793551.js
new file mode 100644
index 0000000000..8aa0241923
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-793551.js
@@ -0,0 +1,20 @@
+// Copyright 2017 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.
+
+load('test/mjsunit/wasm/wasm-constants.js');
+load('test/mjsunit/wasm/wasm-module-builder.js');
+
+const builder = new WasmModuleBuilder();
+builder.addFunction('test', kSig_i_i)
+ .addBody([
+ // body:
+ kExprGetLocal, 0, // get_local 0
+ kExprGetLocal, 0, // get_local 0
+ kExprLoop, kWasmStmt, // loop
+ kExprBr, 0, // br depth=0
+ kExprEnd, // end
+ kExprUnreachable, // unreachable
+ ])
+ .exportFunc();
+builder.instantiate();
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-797846.js b/deps/v8/test/mjsunit/regress/wasm/regress-797846.js
new file mode 100644
index 0000000000..6a4fd5c5f7
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-797846.js
@@ -0,0 +1,14 @@
+// Copyright 2017 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.
+
+load('test/mjsunit/wasm/wasm-constants.js');
+load('test/mjsunit/wasm/wasm-module-builder.js');
+
+// We need a module with one valid function.
+const builder = new WasmModuleBuilder();
+builder.addFunction('test', kSig_v_v).addBody([]);
+
+const buffer = builder.toBuffer();
+assertPromiseResult(
+ WebAssembly.compile(buffer), _ => Realm.createAllowCrossRealmAccess());
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-800756.js b/deps/v8/test/mjsunit/regress/wasm/regress-800756.js
new file mode 100644
index 0000000000..2d29997cef
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-800756.js
@@ -0,0 +1,15 @@
+// Copyright 2018 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.
+
+load('test/mjsunit/wasm/wasm-constants.js');
+load('test/mjsunit/wasm/wasm-module-builder.js');
+
+const builder = new WasmModuleBuilder();
+builder.addMemory(16, 32);
+builder.addFunction(undefined, kSig_i_iii).addBody([
+ kExprI32Const, 0, // i32.const 0
+ kExprI32LoadMem8S, 0, 0, // i32.load8_s offset=0 align=0
+ kExprI32Eqz, // i32.eqz
+]);
+builder.instantiate();
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-801850.js b/deps/v8/test/mjsunit/regress/wasm/regress-801850.js
new file mode 100644
index 0000000000..ad6ff4c432
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-801850.js
@@ -0,0 +1,11 @@
+// Copyright 2018 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.
+
+load('test/mjsunit/wasm/wasm-constants.js');
+load('test/mjsunit/wasm/wasm-module-builder.js');
+
+var builder = new WasmModuleBuilder();
+let module = new WebAssembly.Module(builder.toBuffer());
+var worker = new Worker('onmessage = function() {};');
+worker.postMessage(module)
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-802244.js b/deps/v8/test/mjsunit/regress/wasm/regress-802244.js
new file mode 100644
index 0000000000..0b8decb637
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-802244.js
@@ -0,0 +1,22 @@
+// Copyright 2018 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.
+
+load('test/mjsunit/wasm/wasm-constants.js');
+load('test/mjsunit/wasm/wasm-module-builder.js');
+
+const builder = new WasmModuleBuilder();
+builder.addFunction(undefined, kSig_v_iii).addBody([
+ kExprI32Const, 0x41, // i32.const 0x41
+ kExprLoop, 0x7c, // loop f64
+ kExprGetLocal, 0x00, // get_local 0
+ kExprGetLocal, 0x01, // get_local 1
+ kExprBrIf, 0x01, // br_if depth=1
+ kExprGetLocal, 0x00, // get_local 0
+ kExprI32Rol, // i32.rol
+ kExprBrIf, 0x00, // br_if depth=0
+ kExprUnreachable, // unreachable
+ kExprEnd, // end
+ kExprUnreachable, // unreachable
+]);
+builder.instantiate();
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-808980.js b/deps/v8/test/mjsunit/regress/wasm/regress-808980.js
new file mode 100644
index 0000000000..884572b895
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-808980.js
@@ -0,0 +1,28 @@
+// Copyright 2018 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: --allow-natives-syntax --throws
+
+load('test/mjsunit/wasm/wasm-constants.js');
+load('test/mjsunit/wasm/wasm-module-builder.js');
+let kTableSize = 3;
+
+var builder = new WasmModuleBuilder();
+var sig_index1 = builder.addType(kSig_i_v);
+builder.addFunction('main', kSig_i_ii).addBody([
+ kExprGetLocal,
+ 0,
+ kExprCallIndirect,
+ sig_index1,
+ kTableZero
+]).exportAs('main');
+builder.setFunctionTableBounds(kTableSize, kTableSize);
+var m1_bytes = builder.toBuffer();
+var m1 = new WebAssembly.Module(m1_bytes);
+
+var serialized_m1 = %SerializeWasmModule(m1);
+var m1_clone = %DeserializeWasmModule(serialized_m1, m1_bytes);
+var i1 = new WebAssembly.Instance(m1_clone);
+
+i1.exports.main(123123);
diff --git a/deps/v8/test/mjsunit/serialize-after-execute.js b/deps/v8/test/mjsunit/serialize-after-execute.js
new file mode 100644
index 0000000000..a3e6bc82ae
--- /dev/null
+++ b/deps/v8/test/mjsunit/serialize-after-execute.js
@@ -0,0 +1,15 @@
+// Copyright 2017 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: --cache=after-execute
+
+function g() {
+ function h() {
+ function k() { return 0; };
+ return k;
+ }
+ return h();
+}
+
+g();
diff --git a/deps/v8/test/mjsunit/serialize-embedded-error.js b/deps/v8/test/mjsunit/serialize-embedded-error.js
index 473c931b30..320fe475b0 100644
--- a/deps/v8/test/mjsunit/serialize-embedded-error.js
+++ b/deps/v8/test/mjsunit/serialize-embedded-error.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.
-// --serialize-toplevel --cache=code
+// --cache=code
var caught = false;
try {
diff --git a/deps/v8/test/mjsunit/serialize-ic.js b/deps/v8/test/mjsunit/serialize-ic.js
index 8e5cd2fd50..74821a9ec3 100644
--- a/deps/v8/test/mjsunit/serialize-ic.js
+++ b/deps/v8/test/mjsunit/serialize-ic.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: --cache=code --serialize-toplevel
+// Flags: --cache=code
var foo = [];
foo[0] = "bar";
diff --git a/deps/v8/test/mjsunit/testcfg.py b/deps/v8/test/mjsunit/testcfg.py
index ff84bc3be5..bc9d69ff33 100644
--- a/deps/v8/test/mjsunit/testcfg.py
+++ b/deps/v8/test/mjsunit/testcfg.py
@@ -31,7 +31,6 @@ import re
from testrunner.local import testsuite
from testrunner.objects import testcase
-FLAGS_PATTERN = re.compile(r"//\s+Flags:(.*)")
FILES_PATTERN = re.compile(r"//\s+Files:(.*)")
ENV_PATTERN = re.compile(r"//\s+Environment Variables:(.*)")
SELF_SCRIPT_PATTERN = re.compile(r"//\s+Env: TEST_FILE_NAME")
@@ -39,11 +38,7 @@ MODULE_PATTERN = re.compile(r"^// MODULE$", flags=re.MULTILINE)
NO_HARNESS_PATTERN = re.compile(r"^// NO HARNESS$", flags=re.MULTILINE)
-class MjsunitTestSuite(testsuite.TestSuite):
-
- def __init__(self, name, root):
- super(MjsunitTestSuite, self).__init__(name, root)
-
+class TestSuite(testsuite.TestSuite):
def ListTests(self, context):
tests = []
for dirname, dirs, files in os.walk(self.root, followlinks=True):
@@ -56,19 +51,19 @@ class MjsunitTestSuite(testsuite.TestSuite):
fullpath = os.path.join(dirname, filename)
relpath = fullpath[len(self.root) + 1 : -3]
testname = relpath.replace(os.path.sep, "/")
- test = testcase.TestCase(self, testname)
+ test = self._create_test(testname)
tests.append(test)
return tests
- def GetParametersForTestCase(self, testcase, context):
- source = self.GetSourceForTest(testcase)
+ def _test_class(self):
+ return TestCase
- flags = testcase.flags + context.mode_flags
- env = self._get_env(source)
- flags_match = re.findall(FLAGS_PATTERN, source)
- for match in flags_match:
- flags += match.strip().split()
+class TestCase(testcase.TestCase):
+ def __init__(self, *args, **kwargs):
+ super(TestCase, self).__init__(*args, **kwargs)
+
+ source = self.get_source()
files_list = [] # List of file names to append to command arguments.
files_match = FILES_PATTERN.search(source);
@@ -79,28 +74,32 @@ class MjsunitTestSuite(testsuite.TestSuite):
files_match = FILES_PATTERN.search(source, files_match.end())
else:
break
- files = [ os.path.normpath(os.path.join(self.root, '..', '..', f))
+ files = [ os.path.normpath(os.path.join(self.suite.root, '..', '..', f))
for f in files_list ]
- testfilename = os.path.join(self.root, testcase.path + self.suffix())
+ testfilename = os.path.join(self.suite.root,
+ self.path + self._get_suffix())
if SELF_SCRIPT_PATTERN.search(source):
files = (
["-e", "TEST_FILE_NAME=\"%s\"" % testfilename.replace("\\", "\\\\")] +
files)
- if not context.no_harness and not NO_HARNESS_PATTERN.search(source):
- files.append(os.path.join(self.root, "mjsunit.js"))
+ if NO_HARNESS_PATTERN.search(source):
+ mjsunit_files = []
+ else:
+ mjsunit_files = [os.path.join(self.suite.root, "mjsunit.js")]
+ files_suffix = []
if MODULE_PATTERN.search(source):
- files.append("--module")
- files.append(testfilename)
-
- all_files = list(files)
- if context.isolates:
- all_files += ["--isolate"] + files
+ files_suffix.append("--module")
+ files_suffix.append(testfilename)
- return all_files, flags, env
+ self._source_files = files
+ self._source_flags = self._parse_source_flags(source)
+ self._mjsunit_files = mjsunit_files
+ self._files_suffix = files_suffix
+ self._env = self._parse_source_env(source)
- def _get_env(self, source):
+ def _parse_source_env(self, source):
env_match = ENV_PATTERN.search(source)
env = {}
if env_match:
@@ -109,11 +108,25 @@ class MjsunitTestSuite(testsuite.TestSuite):
env[var] = value
return env
- def GetSourceForTest(self, testcase):
- filename = os.path.join(self.root, testcase.path + self.suffix())
- with open(filename) as f:
- return f.read()
+ def _get_source_flags(self):
+ return self._source_flags
+
+ def _get_files_params(self, ctx):
+ files = list(self._source_files)
+ if not ctx.no_harness:
+ files += self._mjsunit_files
+ files += self._files_suffix
+ if ctx.isolates:
+ files += ['--isolate'] + files
+
+ return files
+
+ def _get_cmd_env(self):
+ return self._env
+
+ def _get_source_path(self):
+ return os.path.join(self.suite.root, self.path + self._get_suffix())
def GetSuite(name, root):
- return MjsunitTestSuite(name, root)
+ return TestSuite(name, root)
diff --git a/deps/v8/test/mjsunit/wasm/errors.js b/deps/v8/test/mjsunit/wasm/errors.js
index 89066d671a..a90236459f 100644
--- a/deps/v8/test/mjsunit/wasm/errors.js
+++ b/deps/v8/test/mjsunit/wasm/errors.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: --expose-wasm
+// Flags: --expose-wasm --allow-natives-syntax
'use strict';
@@ -170,3 +170,19 @@ function assertConversionError(bytes, imports, msg) {
kExprI64Const, 0
]).exportFunc().end().toBuffer(), {}, "invalid type");
})();
+
+
+(function InternalDebugTrace() {
+ var builder = new WasmModuleBuilder();
+ var sig = builder.addType(kSig_i_dd);
+ builder.addImport("mod", "func", sig);
+ builder.addFunction("main", sig)
+ .addBody([kExprGetLocal, 0, kExprGetLocal, 1, kExprCallFunction, 0])
+ .exportAs("main")
+ var main = builder.instantiate({
+ mod: {
+ func: ()=>{%DebugTrace();}
+ }
+ }).exports.main;
+ main();
+})();
diff --git a/deps/v8/test/mjsunit/wasm/grow-memory-detaching.js b/deps/v8/test/mjsunit/wasm/grow-memory-detaching.js
new file mode 100644
index 0000000000..da6516afd7
--- /dev/null
+++ b/deps/v8/test/mjsunit/wasm/grow-memory-detaching.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.
+
+// Flags: --expose-wasm
+
+load("test/mjsunit/wasm/wasm-constants.js");
+load("test/mjsunit/wasm/wasm-module-builder.js");
+
+let module = (() => {
+ let builder = new WasmModuleBuilder();
+ builder.addMemory(1, kV8MaxPages, false);
+ builder.addFunction("grow_memory", kSig_i_i)
+ .addBody([kExprGetLocal, 0, kExprGrowMemory, kMemoryZero])
+ .exportFunc();
+ builder.exportMemoryAs("memory");
+ return builder.toModule();
+})();
+
+(function TestDetachingViaAPI() {
+ print("TestDetachingViaAPI...");
+ let memory = new WebAssembly.Memory({initial: 1, maximum: 100});
+ let growMem = (pages) => memory.grow(pages);
+
+ let b1 = memory.buffer;
+ assertEquals(kPageSize, b1.byteLength);
+
+ growMem(0);
+ let b2 = memory.buffer;
+ assertFalse(b1 === b2);
+ assertEquals(0, b1.byteLength);
+ assertEquals(kPageSize, b2.byteLength);
+
+ growMem(1);
+ let b3 = memory.buffer;
+ assertFalse(b1 === b3);
+ assertFalse(b2 === b3);
+ assertEquals(0, b1.byteLength);
+ assertEquals(0, b2.byteLength);
+ assertEquals(2 * kPageSize, b3.byteLength);
+})();
+
+(function TestDetachingViaBytecode() {
+ print("TestDetachingViaBytecode...");
+ let instance = new WebAssembly.Instance(module);
+ let growMem = instance.exports.grow_memory;
+ let memory = instance.exports.memory;
+
+ let b1 = memory.buffer;
+ assertEquals(kPageSize, b1.byteLength);
+
+ growMem(0);
+ let b2 = memory.buffer;
+ assertFalse(b1 === b2);
+ assertEquals(0, b1.byteLength);
+ assertEquals(kPageSize, b2.byteLength);
+
+ growMem(1);
+ let b3 = memory.buffer;
+ assertFalse(b1 === b3);
+ assertFalse(b2 === b3);
+ assertEquals(0, b1.byteLength);
+ assertEquals(0, b2.byteLength);
+ assertEquals(2 * kPageSize, b3.byteLength);
+})();
diff --git a/deps/v8/test/mjsunit/wasm/indirect-tables.js b/deps/v8/test/mjsunit/wasm/indirect-tables.js
index 4c6d9c9f3b..88d1bb719a 100644
--- a/deps/v8/test/mjsunit/wasm/indirect-tables.js
+++ b/deps/v8/test/mjsunit/wasm/indirect-tables.js
@@ -602,6 +602,47 @@ function js_div(a, b) { return (a / b) | 0; }
/signature mismatch/);
})();
+(function IndirectCallIntoOtherInstance() {
+ print("IndirectCallIntoOtherInstance...");
+ var mem_1 = new WebAssembly.Memory({initial: 1});
+ var mem_2 = new WebAssembly.Memory({initial: 1});
+ var view_1 = new Int32Array(mem_1.buffer);
+ var view_2 = new Int32Array(mem_2.buffer);
+ view_1[0] = 1;
+ view_2[0] = 1000;
+
+ let builder = new WasmModuleBuilder();
+ let sig = builder.addType(kSig_i_v);
+ builder.addFunction('main', kSig_i_i)
+ .addBody([kExprGetLocal, 0, kExprCallIndirect, sig, kTableZero])
+ .exportAs('main');
+ builder.addImportedMemory('', 'memory', 1);
+
+ builder.setFunctionTableBounds(1, 1);
+ builder.addExportOfKind('table', kExternalTable);
+
+ let module1 = new WebAssembly.Module(builder.toBuffer());
+ let instance1 = new WebAssembly.Instance(module1, {'':{memory:mem_1}});
+
+ builder = new WasmModuleBuilder();
+ builder.addFunction('main', kSig_i_v).addBody([kExprI32Const, 0, kExprI32LoadMem, 0, 0]);
+ builder.addImportedTable('', 'table');
+ builder.addFunctionTableInit(0, false, [0], true);
+ builder.addImportedMemory('', 'memory', 1);
+
+
+ let module2 = new WebAssembly.Module(builder.toBuffer());
+ let instance2 = new WebAssembly.Instance(module2, {
+ '': {
+ table: instance1.exports.table,
+ memory: mem_2
+ }
+ });
+
+ assertEquals(instance1.exports.main(0), 1000);
+})();
+
+
(function ImportedFreestandingTable() {
print("ImportedFreestandingTable...");
@@ -665,42 +706,40 @@ function js_div(a, b) { return (a / b) | 0; }
test(1, 3);
})();
-(function IndirectCallIntoOtherInstance() {
- print("IndirectCallIntoOtherInstance...");
- var mem_1 = new WebAssembly.Memory({initial: 1});
- var mem_2 = new WebAssembly.Memory({initial: 1});
- var view_1 = new Int32Array(mem_1.buffer);
- var view_2 = new Int32Array(mem_2.buffer);
- view_1[0] = 1;
- view_2[0] = 1000;
-
- let builder = new WasmModuleBuilder();
- let sig = builder.addType(kSig_i_v);
- builder.addFunction('main', kSig_i_i)
- .addBody([kExprGetLocal, 0, kExprCallIndirect, sig, kTableZero])
- .exportAs('main');
- builder.addImportedMemory('', 'memory', 1);
- builder.setFunctionTableBounds(1, 1);
- builder.addExportOfKind('table', kExternalTable);
-
- let module1 = new WebAssembly.Module(builder.toBuffer());
- let instance1 = new WebAssembly.Instance(module1, {'':{memory:mem_1}});
-
- builder = new WasmModuleBuilder();
- builder.addFunction('main', kSig_i_v).addBody([kExprI32Const, 0, kExprI32LoadMem, 0, 0]);
- builder.addImportedTable('', 'table');
- builder.addFunctionTableInit(0, false, [0], true);
- builder.addImportedMemory('', 'memory', 1);
+// Remove this test when v8:7232 is addressed comprehensively.
+(function TablesAreImmutableInWasmCallstacks() {
+ print('TablesAreImmutableInWasmCallstacks...');
+ let table = new WebAssembly.Table({initial:2, element:'anyfunc'});
+ let builder = new WasmModuleBuilder();
+ builder.addImport('', 'mutator', kSig_v_v);
+ builder.addFunction('main', kSig_v_v)
+ .addBody([
+ kExprCallFunction, 0
+ ]).exportAs('main');
- let module2 = new WebAssembly.Module(builder.toBuffer());
- let instance2 = new WebAssembly.Instance(module2, {
+ let module = new WebAssembly.Module(builder.toBuffer());
+ let instance = new WebAssembly.Instance(module, {
'': {
- table: instance1.exports.table,
- memory: mem_2
+ 'mutator': () => {table.set(0, null);}
}
});
- assertEquals(instance1.exports.main(0), 1000);
+ table.set(0, instance.exports.main);
+
+ try {
+ instance.exports.main();
+ assertUnreached();
+ } catch (e) {
+ assertTrue(e instanceof RangeError);
+ }
+ try {
+ instance.exports.main();
+ assertUnreached();
+ } catch (e) {
+ assertTrue(e instanceof RangeError);
+ }
+ table.set(0, null);
+ assertEquals(null, table.get(0));
})();
diff --git a/deps/v8/test/mjsunit/wasm/lazy-compilation.js b/deps/v8/test/mjsunit/wasm/lazy-compilation.js
index 3d840398a8..fc41fbd622 100644
--- a/deps/v8/test/mjsunit/wasm/lazy-compilation.js
+++ b/deps/v8/test/mjsunit/wasm/lazy-compilation.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: --wasm-lazy-compilation
+// Flags: --wasm-lazy-compilation --allow-natives-syntax
load('test/mjsunit/wasm/wasm-constants.js');
load('test/mjsunit/wasm/wasm-module-builder.js');
@@ -46,6 +46,10 @@ load('test/mjsunit/wasm/wasm-module-builder.js');
instance2.exports.call_store(3);
assertEquals(3, mem1[0]);
assertEquals(0, mem2[0]);
+ %FreezeWasmLazyCompilation(instance1);
+ %FreezeWasmLazyCompilation(instance2);
+ instance2.exports.call_store(7);
+ assertEquals(7, mem1[0]);
})();
(function exportImportedFunction() {
@@ -60,4 +64,37 @@ load('test/mjsunit/wasm/wasm-module-builder.js');
const instance2 = builder2.instantiate({A: instance1.exports});
instance2.exports.foo();
+ %FreezeWasmLazyCompilation(instance1);
+ %FreezeWasmLazyCompilation(instance2);
+ instance2.exports.foo();
+})();
+
+(function exportImportedFunctionWithDifferentMemory() {
+ print(arguments.callee.name);
+ const builder1 = new WasmModuleBuilder();
+ builder1.addMemory(1, 1, true);
+ builder1.addFunction('store', kSig_v_i)
+ .addBody([
+ kExprI32Const, 0, // i32.const 1
+ kExprGetLocal, 0, // get_local 0
+ kExprI32StoreMem, 0, 0, // i32.store offset=0 align=0
+ ])
+ .exportFunc();
+ const instance1 = builder1.instantiate();
+ const mem1 = new Int32Array(instance1.exports.memory.buffer);
+
+ const builder2 = new WasmModuleBuilder();
+ builder2.addMemory(1, 1, true);
+ const imp_idx = builder2.addImport('A', 'store', kSig_v_i);
+ builder2.addExport('exp_store', imp_idx);
+ const instance2 = builder2.instantiate({A: instance1.exports});
+ const mem2 = new Int32Array(instance2.exports.memory.buffer);
+
+ instance2.exports.exp_store(3);
+ assertEquals(3, mem1[0]);
+ assertEquals(0, mem2[0]);
+ %FreezeWasmLazyCompilation(instance1);
+ %FreezeWasmLazyCompilation(instance2);
+ instance2.exports.exp_store(7);
+ assertEquals(7, mem1[0]);
})();
diff --git a/deps/v8/test/mjsunit/wasm/many-parameters.js b/deps/v8/test/mjsunit/wasm/many-parameters.js
index 03d7e09ef3..a56619a6ad 100644
--- a/deps/v8/test/mjsunit/wasm/many-parameters.js
+++ b/deps/v8/test/mjsunit/wasm/many-parameters.js
@@ -12,10 +12,13 @@ let type_const = [wasmI32Const, wasmF32Const, wasmF64Const];
function f(values, shift, num_const_params, ...args) {
assertEquals(
values.length + num_const_params, args.length, 'number of arguments');
+ const expected = idx =>
+ idx < values.length ? values[(idx + shift) % values.length] : idx;
+ const msg = 'shifted by ' + shift + ': ' +
+ 'expected [' + args.map((_, i) => expected(i)).join(', ') + '], got [' +
+ args.join(', ') + ']';
args.forEach((arg_val, idx) => {
- const expected =
- idx < values.length ? values[(idx + shift) % values.length] : idx;
- assertEquals(expected, arg_val, 'arg #' + idx + ', shifted by ' + shift);
+ assertEquals(expected(idx), arg_val, 'arg #' + idx + ', ' + msg);
});
}
diff --git a/deps/v8/test/mjsunit/wasm/module-memory.js b/deps/v8/test/mjsunit/wasm/module-memory.js
index f5b5981436..e9d2bb954d 100644
--- a/deps/v8/test/mjsunit/wasm/module-memory.js
+++ b/deps/v8/test/mjsunit/wasm/module-memory.js
@@ -172,3 +172,26 @@ function testOOBThrows() {
}
testOOBThrows();
+
+function testAddressSpaceLimit() {
+ // 1TiB, see wasm-memory.h
+ const kMaxAddressSpace = 1 * 1024 * 1024 * 1024 * 1024;
+ const kAddressSpacePerMemory = 8 * 1024 * 1024 * 1024;
+
+ try {
+ let memories = [];
+ let address_space = 0;
+ while (address_space <= kMaxAddressSpace + 1) {
+ memories.push(new WebAssembly.Memory({initial: 1}));
+ address_space += kAddressSpacePerMemory;
+ }
+ } catch (e) {
+ assertTrue(e instanceof RangeError);
+ return;
+ }
+ failWithMessage("allocated too much memory");
+}
+
+if(%IsWasmTrapHandlerEnabled()) {
+ testAddressSpaceLimit();
+}
diff --git a/deps/v8/test/mjsunit/wasm/shared-memory.js b/deps/v8/test/mjsunit/wasm/shared-memory.js
index fa51a8307f..bbe89a3fe5 100644
--- a/deps/v8/test/mjsunit/wasm/shared-memory.js
+++ b/deps/v8/test/mjsunit/wasm/shared-memory.js
@@ -7,20 +7,23 @@
load("test/mjsunit/wasm/wasm-constants.js");
load("test/mjsunit/wasm/wasm-module-builder.js");
-function assertMemoryIsValid(memory) {
+function assertMemoryIsValid(memory, shared) {
assertSame(WebAssembly.Memory.prototype, memory.__proto__);
assertSame(WebAssembly.Memory, memory.constructor);
assertTrue(memory instanceof Object);
assertTrue(memory instanceof WebAssembly.Memory);
+ if (shared) {
+ assertTrue(memory.buffer instanceof SharedArrayBuffer);
+ // Assert that the buffer is frozen when memory is shared.
+ assertTrue(Object.isFrozen(memory.buffer));
+ }
}
(function TestConstructorWithShared() {
print("TestConstructorWithShared");
let memory = new WebAssembly.Memory({
initial: 0, maximum: 10, shared: true});
- assertMemoryIsValid(memory);
- // Assert that the buffer is frozen when memory is shared.
- assertTrue(Object.isFrozen(memory.buffer));
+ assertMemoryIsValid(memory, true);
})();
(function TestConstructorWithUndefinedShared() {
@@ -36,7 +39,7 @@ function assertMemoryIsValid(memory) {
// For numeric values, shared = true.
let memory = new WebAssembly.Memory({
initial: 0, maximum: 10, shared: 2098665});
- assertMemoryIsValid(memory);
+ assertMemoryIsValid(memory, true);
})();
(function TestConstructorWithEmptyStringShared() {
@@ -101,3 +104,29 @@ function assertMemoryIsValid(memory) {
assertThrows(() => new WebAssembly.Instance(module,
{m: {imported_mem: memory}}), WebAssembly.LinkError);
})();
+
+(function TestInstantiateWithSharedDefined() {
+ print("TestInstantiateWithSharedDefined");
+ let builder = new WasmModuleBuilder();
+ builder.addMemory(2, 10, true, "shared");
+ let module = new WebAssembly.Module(builder.toBuffer());
+ let instance = new WebAssembly.Instance(module);
+ assertMemoryIsValid(instance.exports.memory, true);
+})();
+
+(function TestAtomicOpWithSharedMemoryDefined() {
+ print("TestAtomicOpWithSharedMemoryDefined");
+ let builder = new WasmModuleBuilder();
+ builder.addMemory(2, 10, false, "shared");
+ builder.addFunction("main", kSig_i_ii)
+ .addBody([
+ kExprGetLocal, 0,
+ kExprGetLocal, 1,
+ kAtomicPrefix,
+ kExprI32AtomicAdd, 2, 0])
+ .exportFunc();
+ let module = new WebAssembly.Module(builder.toBuffer());
+ let instance = new WebAssembly.Instance(module);
+ assertEquals(0, instance.exports.main(0, 0x11111111));
+ assertEquals(0x11111111, instance.exports.main(0, 0x11111111));
+})();
diff --git a/deps/v8/test/mjsunit/wasm/trap-location.js b/deps/v8/test/mjsunit/wasm/trap-location.js
index 0c646c92cd..c4a0f4d787 100644
--- a/deps/v8/test/mjsunit/wasm/trap-location.js
+++ b/deps/v8/test/mjsunit/wasm/trap-location.js
@@ -86,7 +86,7 @@ let buffer = builder.toBuffer();
// Test async compilation and instantiation.
assertPromiseResult(WebAssembly.instantiate(buffer), pair => {
- testTrapLocations(pair.instance, 6);
+ testTrapLocations(pair.instance, 5);
});
// Test sync compilation and instantiation.
diff --git a/deps/v8/test/mjsunit/wasm/wasm-module-builder.js b/deps/v8/test/mjsunit/wasm/wasm-module-builder.js
index d21067b36e..c00c2c8226 100644
--- a/deps/v8/test/mjsunit/wasm/wasm-module-builder.js
+++ b/deps/v8/test/mjsunit/wasm/wasm-module-builder.js
@@ -121,9 +121,25 @@ class WasmFunctionBuilder {
return this;
}
+ getNumLocals() {
+ let total_locals = 0;
+ for (let l of this.locals || []) {
+ for (let type of ["i32", "i64", "f32", "f64", "s128"]) {
+ total_locals += l[type + "_count"] || 0;
+ }
+ }
+ return total_locals;
+ }
+
addLocals(locals, names) {
- this.locals = locals;
- this.local_names = names;
+ const old_num_locals = this.getNumLocals();
+ if (!this.locals) this.locals = []
+ this.locals.push(locals);
+ if (names) {
+ if (!this.local_names) this.local_names = [];
+ const missing_names = old_num_locals - this.local_names.length;
+ this.local_names.push(...new Array(missing_names), ...names);
+ }
return this;
}
@@ -409,7 +425,6 @@ class WasmModuleBuilder {
}
section.emit_u32v(wasm.memory.min);
if (has_max) section.emit_u32v(wasm.memory.max);
- if (wasm.memory.shared) section.emit_u8(1);
});
}
@@ -538,9 +553,7 @@ class WasmModuleBuilder {
for (let func of wasm.functions) {
// Function body length will be patched later.
let local_decls = [];
- let l = func.locals;
- if (l !== undefined) {
- let local_decls_count = 0;
+ for (let l of func.locals || []) {
if (l.i32_count > 0) {
local_decls.push({count: l.i32_count, type: kWasmI32});
}