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

Side by Side 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: Add more test cases + some TODOs 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 unified diff | Download patch
« no previous file with comments | « src/typing-asm.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Flags: --harmony-do-expressions --harmony-sloppy-let --allow-natives-syntax
6 // Flags: --harmony-default-parameters
7
8 function returnValue(v) { return v; }
9 function MyError() {}
10 var global = this;
11
12 function TestBasic() {
13 // Looping and lexical declarations
14 assertEquals(512, returnValue(do {
15 let n = 2;
16 for (let i = 0; i < 4; i++) n <<= 2;
17 }));
18
19 // Strings do the right thing
20 assertEquals("spooky halloween", returnValue(do {
21 "happy halloween".replace('happy', 'spooky');
22 }));
23
24 // Do expressions with no completion produce an undefined value
25 assertEquals(undefined, returnValue(do {}));
26 assertEquals(undefined, returnValue(do { var x = 99; }));
27 assertEquals(undefined, returnValue(do { function f() {}; }));
28 assertEquals(undefined, returnValue(do { let z = 33; }));
29
30 // Propagation of exception
31 assertThrows(function() {
32 (do {
33 throw new MyError();
34 "potatoes";
35 });
36 }, MyError);
37
38 assertThrows(function() {
39 return do {
40 throw new MyError();
41 "potatoes";
42 };
43 }, MyError);
44
45 // Return value within do-block overrides `return |do-expression|`
46 assertEquals("inner-return", (function() {
47 return "outer-return" + do {
48 return "inner-return";
49 "";
50 };
51 })());
52
53 // Breaking out |do-expression|
54 assertEquals(3, (function() {
55 for (var i = 0; i < 10; ++i) (do { if (i === 3) break; });
rossberg 2015/10/16 12:09:40 I'm mildly surprised that this one actually works
caitp (gmail) 2015/10/16 13:12:18 From local testing, it seems to be working fine --
56 return i;
57 })());
58
59 // Continue in |do-expression|
60 assertEquals([1, 3, 5, 7, 9], (function() {
61 var values = [];
62 for (var i = 0; i < 10; ++i) {
63 (do {
64 if ((i & 1) === 0) continue;
rossberg 2015/10/16 12:09:40 Same here.
65 values.push(i);
66 });
67 }
68 return values;
69 })());
70
71 assertThrows("(do { break; });", SyntaxError);
72 assertThrows("(do { continue; });", SyntaxError);
73
74 // Real-world use case for desugaring
75 var array = [1, 2, 3, 4, 5], iterable = [6, 7, 8,9];
76 assertEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], do {
77 for (var element of iterable) array.push(element);
78 array;
79 });
80
81 // Nested do-expressions
82 assertEquals(125, do { (do { (do { 5 * 5 * 5 }) }) });
83
84 // Directives are not honoured
85 (do {
86 "use strict";
87 foo = 80;
88 assertEquals(foo, 80);
89 });
90
91 // Non-empty operand stack testing
92 var O = {
93 method1() {
94 let x = 256;
95 return x + do {
96 for (var i = 0; i < 4; ++i) x += i;
97 } + 17;
98 },
99 method2() {
100 let x = 256;
101 this.reset();
102 return x + do {
103 for (var i = 0; i < this.length(); ++i) x += this.index() * 2;
104 };
105 },
106 _index: 0,
107 index() {
108 return ++this._index;
109 },
110 _length: 4,
111 length() { return this._length; },
112 reset() { this._index = 0; }
113 };
114 assertEquals(535, O["method" + do { 1 } + ""]());
115 assertEquals(532, O["method" + do { ({ valueOf() { return "2"; } }); }]());
116 assertEquals(532, O[
117 do { let s = ""; for (let c of "method") s += c; } + "2"]());
118 }
119 TestBasic();
120
121
122 function TestDeoptimization1() {
123 function f(v) {
124 return 88 + do {
125 v.a * v.b + v.c;
126 };
127 }
128
129 var o1 = {};
130 o1.a = 10;
131 o1.b = 5;
132 o1.c = 50;
133
134 var o2 = {};
135 o2.c = 100;
136 o2.a = 10;
137 o2.b = 10;
138
139 assertEquals(188, f(o1));
140 assertEquals(188, f(o1));
141 %OptimizeFunctionOnNextCall(f);
142 assertEquals(188, f(o1));
143 assertOptimized(f);
144 assertEquals(288, f(o2));
145 assertUnoptimized(f);
146 assertEquals(288, f(o2));
147 }
148 TestDeoptimization1();
149
150
151 function TestInParameterInitializers() {
152 var first_name = "George";
153 var last_name = "Jetson";
154 function fn1(name = do { first_name + " " + last_name }) {
155 return name;
156 }
157 assertEquals("George Jetson", fn1());
158
159 var _items = [1, 2, 3, NaN, 4, 5];
160 function fn2(items = do {
161 let items = [];
162 for (var el of _items) {
163 if (el !== el) break;
164 items.push(el), items;
165 }
166 }) {
167 return items;
168 }
169 assertEquals([1, 2, 3], fn2());
170
171 function thrower() { throw new MyError(); }
172 function fn3(exception = do { try { thrower(); } catch (e) { e } }) {
173 return exception;
174 }
175 assertDoesNotThrow(fn3);
176 assertInstanceof(fn3(), MyError);
177
178 function fn4(exception = do { throw new MyError() }) {}
179 function catcher(fn) {
180 try {
181 fn();
182 assertUnreachable("fn() initializer should throw");
183 } catch (e) {
184 assertInstanceof(e, MyError);
185 }
186 }
187 catcher(fn4);
188 }
189 TestInParameterInitializers();
190
191
192 function TestWithEval() {
193 (function sloppy1() {
194 assertEquals(do { eval("var x = 5"), x }, 5);
195 assertEquals(x, 5);
196 })();
197
198 assertThrows(function strict1() {
199 "use strict";
200 (do { eval("var x = 5"), x }, 5);
201 }, ReferenceError);
202
203 assertThrows(function strict2() {
204 (do { eval("'use strict'; var x = 5"), x }, 5);
205 }, ReferenceError);
206 }
207 TestWithEval();
208
209
210 function TestHoisting() {
rossberg 2015/10/16 12:09:40 Can you add a test with do-var inside a parameter
caitp (gmail) 2015/10/16 12:21:00 I don't expect it to work the way I'd think it wou
rossberg 2015/10/16 12:37:02 Sure, TODO is fine, just was curious in how far it
caitp (gmail) 2015/10/16 13:12:18 Yeah, you're right. Then this doesn't need a TODO
caitp (gmail) 2015/10/16 13:23:03 Is this actually right? Each parameter with an ini
rossberg 2015/10/16 13:28:28 Note the curly braces: this is a single parameter
211 (do { var a = 1; });
212 assertEquals(a, 1);
213 assertEquals(global.a, undefined);
214
215 (do {
216 for (let it of [1, 2, 3, 4, 5]) {
217 var b = it;
218 }
219 });
220 assertEquals(b, 5);
221 assertEquals(global.b, undefined);
222
223 // TODO(caitp): Always block-scope function declarations in |do| expressions
224 //(do {
225 // assertEquals(true, inner_func());
226 // function inner_func() { return true; }
227 //});
228 //assertThrows(function() { return innerFunc(); }, ReferenceError);
229 }
230 TestHoisting();
231
232
233 function TestOSR() {
234 var numbers = do {
235 let nums = [];
236 for (let i = 0; i < 1000; ++i) {
237 let value = (Math.random() * 100) | 0;
238 nums.push(value === 0 ? 1 : value), nums;
239 }
240 };
241 assertEquals(numbers.length, 1000);
242 }
243
244 for (var i = 0; i < 64; ++i) TestOSR();
OLDNEW
« no previous file with comments | « src/typing-asm.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698