Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(34)

Unified Diff: test/mjsunit/harmony/do-expressions.js

Issue 1399893002: [es7] implement |do| expressions proposal (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Disable CrankShaft Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« src/ast.h ('K') | « src/typing-asm.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: test/mjsunit/harmony/do-expressions.js
diff --git a/test/mjsunit/harmony/do-expressions.js b/test/mjsunit/harmony/do-expressions.js
new file mode 100644
index 0000000000000000000000000000000000000000..a2c014cbc6f523e7bbba07a2bc5323fa548cd8a7
--- /dev/null
+++ b/test/mjsunit/harmony/do-expressions.js
@@ -0,0 +1,273 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-do-expressions --harmony-sloppy-let --allow-natives-syntax
+// Flags: --harmony-default-parameters --harmony-destructuring
+
+function returnValue(v) { return v; }
+function MyError() {}
+var global = this;
+
+function TestBasic() {
+ // Looping and lexical declarations
+ assertEquals(512, returnValue(do {
+ let n = 2;
+ for (let i = 0; i < 4; i++) n <<= 2;
+ }));
+
+ // Strings do the right thing
+ assertEquals("spooky halloween", returnValue(do {
+ "happy halloween".replace('happy', 'spooky');
+ }));
+
+ // Do expressions with no completion produce an undefined value
+ assertEquals(undefined, returnValue(do {}));
+ assertEquals(undefined, returnValue(do { var x = 99; }));
+ assertEquals(undefined, returnValue(do { function f() {}; }));
+ assertEquals(undefined, returnValue(do { let z = 33; }));
+
+ // Propagation of exception
+ assertThrows(function() {
+ (do {
+ throw new MyError();
+ "potatoes";
+ });
+ }, MyError);
+
+ assertThrows(function() {
+ return do {
+ throw new MyError();
+ "potatoes";
+ };
+ }, MyError);
+
+ // Return value within do-block overrides `return |do-expression|`
+ assertEquals("inner-return", (function() {
+ return "outer-return" + do {
+ return "inner-return";
+ "";
+ };
+ })());
+
+ var count = 0, n = 1;
+ // Breaking out |do-expression|
+ assertEquals(3, (function() {
+ for (var i = 0; i < 10; ++i) (count += 2 * do { if (i === 3) break; ++n });
+ return i;
+ })());
+ // (2 * 2) + (2 * 3) + (2 * 4)
+ assertEquals(18, count);
+
+ // Continue in |do-expression|
+ count = 0, n = 1;
+ assertEquals([1, 3, 5, 7, 9], (function() {
+ var values = [];
+ for (var i = 0; i < 10; ++i) {
+ count += 2 * (do {
+ if ((i & 1) === 0) continue;
+ values.push(i);
+ ++n;
+ }) + 1;
+ }
+ // (2*2) + 1 + (2*3) + 1 + (2*4) + 1 + (2*5) + 1 + (2*6) + 1
+ return values;
+ })());
+ assertEquals(count, 45);
+
+ assertThrows("(do { break; });", SyntaxError);
+ assertThrows("(do { continue; });", SyntaxError);
+
+ // Real-world use case for desugaring
+ var array = [1, 2, 3, 4, 5], iterable = [6, 7, 8,9];
+ assertEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], do {
+ for (var element of iterable) array.push(element);
+ array;
+ });
+
+ // Nested do-expressions
+ assertEquals(125, do { (do { (do { 5 * 5 * 5 }) }) });
+
+ // Directives are not honoured
+ (do {
+ "use strict";
+ foo = 80;
+ assertEquals(foo, 80);
+ });
+
+ // Non-empty operand stack testing
+ var O = {
+ method1() {
+ let x = 256;
+ return x + do {
+ for (var i = 0; i < 4; ++i) x += i;
+ } + 17;
+ },
+ method2() {
+ let x = 256;
+ this.reset();
+ return x + do {
+ for (var i = 0; i < this.length(); ++i) x += this.index() * 2;
+ };
+ },
+ _index: 0,
+ index() {
+ return ++this._index;
+ },
+ _length: 4,
+ length() { return this._length; },
+ reset() { this._index = 0; }
+ };
+ assertEquals(535, O["method" + do { 1 } + ""]());
+ assertEquals(532, O["method" + do { ({ valueOf() { return "2"; } }); }]());
+ assertEquals(532, O[
+ do { let s = ""; for (let c of "method") s += c; } + "2"]());
+}
+TestBasic();
+
+
+function TestDeoptimization1() {
+ function f(v) {
+ return 88 + do {
+ v.a * v.b + v.c;
+ };
+ }
+
+ var o1 = {};
+ o1.a = 10;
+ o1.b = 5;
+ o1.c = 50;
+
+ var o2 = {};
+ o2.c = 100;
+ o2.a = 10;
+ o2.b = 10;
+
+ assertEquals(188, f(o1));
+ assertEquals(188, f(o1));
+ %OptimizeFunctionOnNextCall(f);
+ assertEquals(188, f(o1));
+ assertOptimized(f);
+ assertEquals(288, f(o2));
+ assertUnoptimized(f);
+ assertEquals(288, f(o2));
+}
+TestDeoptimization1();
+
+
+function TestInParameterInitializers() {
+ var first_name = "George";
+ var last_name = "Jetson";
+ function fn1(name = do { first_name + " " + last_name }) {
+ return name;
+ }
+ assertEquals("George Jetson", fn1());
+
+ var _items = [1, 2, 3, NaN, 4, 5];
+ function fn2(items = do {
+ let items = [];
+ for (var el of _items) {
+ if (el !== el) break;
+ items.push(el), items;
+ }
+ }) {
+ return items;
+ }
+ assertEquals([1, 2, 3], fn2());
+
+ function thrower() { throw new MyError(); }
+ function fn3(exception = do { try { thrower(); } catch (e) { e } }) {
+ return exception;
+ }
+ assertDoesNotThrow(fn3);
+ assertInstanceof(fn3(), MyError);
+
+ function fn4(exception = do { throw new MyError() }) {}
+ function catcher(fn) {
+ try {
+ fn();
+ assertUnreachable("fn() initializer should throw");
+ } catch (e) {
+ assertInstanceof(e, MyError);
+ }
+ }
+ catcher(fn4);
+}
+TestInParameterInitializers();
+
+
+function TestWithEval() {
+ (function sloppy1() {
+ assertEquals(do { eval("var x = 5"), x }, 5);
+ assertEquals(x, 5);
+ })();
+
+ assertThrows(function strict1() {
+ "use strict";
+ (do { eval("var x = 5"), x }, 5);
+ }, ReferenceError);
+
+ assertThrows(function strict2() {
+ (do { eval("'use strict'; var x = 5"), x }, 5);
+ }, ReferenceError);
+}
+TestWithEval();
+
+
+function TestHoisting() {
+ (do { var a = 1; });
+ assertEquals(a, 1);
+ assertEquals(global.a, undefined);
+
+ (do {
+ for (let it of [1, 2, 3, 4, 5]) {
+ var b = it;
+ }
+ });
+ assertEquals(b, 5);
+ assertEquals(global.b, undefined);
+
+ {
+ let x = 1
+
+ // TODO(caitp): ensure VariableStatements in |do-expressions| in parameter
+ // initializers, are evaluated in the same VariableEnvironment as they would
+ // be for eval().
+ // function f1(a = do { var x = 2 }, b = x) { return b }
+ // assertEquals(1, f1())
+
+ // function f2(a = x, b = do { var x = 2 }) { return a }
+ // assertEquals(1, f2())
+
+ function f3({a = do { var x = 2 }, b = x}) { return b }
+ assertEquals(2, f3({}))
+
+ function f4({a = x, b = do { var x = 2 }}) { return b }
+ assertEquals(undefined, f4({}))
+
+ function f5(a = do { var y = 0 }) {}
+ assertThrows(() => y, ReferenceError)
+ }
+
+ // TODO(caitp): Always block-scope function declarations in |do| expressions
+ //(do {
+ // assertEquals(true, inner_func());
+ // function inner_func() { return true; }
+ //});
+ //assertThrows(function() { return innerFunc(); }, ReferenceError);
+}
+TestHoisting();
+
+
+function TestOSR() {
+ var numbers = do {
+ let nums = [];
+ for (let i = 0; i < 1000; ++i) {
+ let value = (Math.random() * 100) | 0;
+ nums.push(value === 0 ? 1 : value), nums;
+ }
+ };
+ assertEquals(numbers.length, 1000);
+}
+
+for (var i = 0; i < 64; ++i) TestOSR();
« src/ast.h ('K') | « src/typing-asm.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698