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

Side by Side Diff: test/mjsunit/harmony/iteration-semantics.js

Issue 15288011: Baseline for-of implementation (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: s/syntax/semantics/ Created 7 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « src/x64/full-codegen-x64.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 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 // Flags: --harmony
29
30 // Test for-of semantics.
31
32 "use strict";
33
34
35 // First, some helpers.
36
37 function* values() {
38 for (var i = 0; i < arguments.length; i++) {
39 yield arguments[i];
40 }
41 }
42
43 function integers_until(max) {
44 function next() {
45 var ret = { value: this.n, done: this.n == max };
46 this.n++;
47 return ret;
48 }
49 return { next: next, n: 0 }
50 }
51
52 function results(results) {
53 var i = 0;
54 function next() {
55 return results[i++];
56 }
57 return { next: next }
58 }
59
60 function* integers_from(n) {
61 while (1) yield n++;
62 }
63
64 // A destructive append.
65 function append(x, tail) {
66 tail[tail.length] = x;
67 return tail;
68 }
69
70 function sum(x, tail) {
71 return x + tail;
72 }
73
74 function fold(cons, seed, iter) {
75 for (var x of iter) {
76 seed = cons(x, seed);
77 }
78 return seed;
79 }
80
81 function* take(iter, n) {
82 if (n == 0) return;
83 for (let x of iter) {
84 yield x;
85 if (--n == 0) break;
86 }
87 }
88
89 function nth(iter, n) {
90 for (let x of iter) {
91 if (n-- == 0) return x;
92 }
93 throw "unreachable";
94 }
95
96 function* skip_every(iter, n) {
97 var i = 0;
98 for (let x of iter) {
99 if (++i % n == 0) continue;
100 yield x;
101 }
102 }
103
104 function* iter_map(iter, f) {
105 for (var x of iter) {
106 yield f(x);
107 }
108 }
109 function nested_fold(cons, seed, iter) {
110 var visited = []
111 for (let x of iter) {
112 for (let y of x) {
113 seed = cons(y, seed);
114 }
115 }
116 return seed;
117 }
118
119 function* unreachable(iter) {
120 for (let x of iter) {
121 throw "not reached";
122 }
123 }
124
125 function one_time_getter(o, prop, val) {
126 function set_never() { throw "unreachable"; }
127 var gotten = false;
128 function get_once() {
129 if (gotten) throw "got twice";
130 gotten = true;
131 return val;
132 }
133 Object.defineProperty(o, prop, {get: get_once, set: set_never})
134 return o;
135 }
136
137 function never_getter(o, prop) {
138 function never() { throw "unreachable"; }
139 Object.defineProperty(o, prop, {get: never, set: never})
140 return o;
141 }
142
143 function remove_next_after(iter, n) {
144 function next() {
145 if (n-- == 0) delete this.next;
146 return iter.next();
147 }
148 return { next: next }
149 }
150
151 function poison_next_after(iter, n) {
152 function next() {
153 return iter.next();
154 }
155 function next_getter() {
156 if (n-- < 0)
157 throw "poisoned";
158 return next;
159 }
160 var o = {};
161 Object.defineProperty(o, 'next', { get: next_getter });
162 return o;
163 }
164
165 // Now, the tests.
166
167 // Non-generator iterators.
168 assertEquals(45, fold(sum, 0, integers_until(10)));
169 // Generator iterators.
170 assertEquals([1, 2, 3], fold(append, [], values(1, 2, 3)));
171 // Break.
172 assertEquals(45, fold(sum, 0, take(integers_from(0), 10)));
173 // Continue.
174 assertEquals(90, fold(sum, 0, take(skip_every(integers_from(0), 2), 10)));
175 // Return.
176 assertEquals(10, nth(integers_from(0), 10));
177 // Nested for-of.
178 assertEquals([0, 0, 1, 0, 1, 2, 0, 1, 2, 3],
179 nested_fold(append,
180 [],
181 iter_map(integers_until(5), integers_until)));
182 // Result objects with sparse fields.
183 assertEquals([undefined, 1, 2, 3],
184 fold(append, [],
185 results([{ done: false },
186 { value: 1, done: false },
187 // A missing "done" is the same as undefined, which
188 // is false.
189 { value: 2 },
190 // Not done.
191 { value: 3, done: 0 },
192 // Done.
193 { value: 4, done: 42 }])));
194 // Results that are not objects.
195 assertEquals([undefined, undefined, undefined],
196 fold(append, [],
197 results([10, "foo", /qux/, { value: 37, done: true }])));
198 // Getters (shudder).
199 assertEquals([1, 2],
200 fold(append, [],
201 results([one_time_getter({ value: 1 }, 'done', false),
202 one_time_getter({ done: false }, 'value', 2),
203 { value: 37, done: true },
204 never_getter(never_getter({}, 'done'), 'value')])));
205
206 // Null and undefined do not cause an error.
207 assertEquals(0, fold(sum, 0, unreachable(null)));
208 assertEquals(0, fold(sum, 0, unreachable(undefined)));
209
210 // Other non-iterators do cause an error.
211 assertThrows('fold(sum, 0, unreachable({}))', TypeError);
212 assertThrows('fold(sum, 0, unreachable("foo"))', TypeError);
213 assertThrows('fold(sum, 0, unreachable(37))', TypeError);
214
215 // "next" is looked up each time.
216 assertThrows('fold(sum, 0, remove_next_after(integers_until(10), 5))',
217 TypeError);
218 // It is not called at any other time.
219 assertEquals(45,
220 fold(sum, 0, remove_next_after(integers_until(10), 10)));
221 // It is not looked up too many times.
222 assertEquals(45,
223 fold(sum, 0, poison_next_after(integers_until(10), 10)));
224
225 function labelled_continue(iter) {
226 var n = 0;
227 outer:
228 while (true) {
229 n++;
230 for (var x of iter) continue outer;
231 break;
232 }
233 return n;
234 }
235 assertEquals(11, labelled_continue(integers_until(10)));
236
237 function labelled_break(iter) {
238 var n = 0;
239 outer:
240 while (true) {
241 n++;
242 for (var x of iter) break outer;
243 }
244 return n;
245 }
246 assertEquals(1, labelled_break(integers_until(10)));
247
248 // Test continue/break in catch.
249 function catch_control(iter, k) {
250 var n = 0;
251 for (var x of iter) {
252 try {
253 return k(x);
254 } catch (e) {
255 if (e == "continue") continue;
256 else if (e == "break") break;
257 else throw e;
258 }
259 } while (false);
260 return false;
261 }
262 assertEquals(false,
263 catch_control(integers_until(10),
264 function() { throw "break" }));
265 assertEquals(false,
266 catch_control(integers_until(10),
267 function() { throw "continue" }));
268 assertEquals(5,
269 catch_control(integers_until(10),
270 function(x) {
271 if (x == 5) return x;
272 throw "continue";
273 }));
274
275 // Test continue/break in try.
276 function try_control(iter, k) {
277 var n = 0;
278 for (var x of iter) {
279 try {
280 var e = k(x);
281 if (e == "continue") continue;
282 else if (e == "break") break;
283 return e;
284 } catch (e) {
285 throw e;
286 }
287 } while (false);
288 return false;
289 }
290 assertEquals(false,
291 try_control(integers_until(10),
292 function() { return "break" }));
293 assertEquals(false,
294 try_control(integers_until(10),
295 function() { return "continue" }));
296 assertEquals(5,
297 try_control(integers_until(10),
298 function(x) { return (x == 5) ? x : "continue" }));
299
300 // Proxy results, with getters.
301 function transparent_proxy(x) {
302 return Proxy.create({
303 get: function(receiver, name) { return x[name]; }
304 });
305 }
306 assertEquals([1, 2],
307 fold(append, [],
308 results([one_time_getter({ value: 1 }, 'done', false),
309 one_time_getter({ done: false }, 'value', 2),
310 { value: 37, done: true },
311 never_getter(never_getter({}, 'done'), 'value')]
312 .map(transparent_proxy))));
313
314 // Proxy iterators.
315 function poison_proxy_after(x, n) {
316 return Proxy.create({
317 get: function(receiver, name) {
318 if (name == 'next' && n-- < 0) throw "unreachable";
319 return x[name];
320 },
321 // Needed for integers_until(10)'s this.n++.
322 set: function(receiver, name, val) {
323 return x[name] = val;
324 }
325 });
326 }
327 assertEquals(45, fold(sum, 0, poison_proxy_after(integers_until(10), 10)));
OLDNEW
« no previous file with comments | « src/x64/full-codegen-x64.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698