OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 13 matching lines...) Expand all Loading... |
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 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. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | 27 |
28 // Flags: --harmony-generators --expose-gc | 28 // Flags: --harmony-generators --expose-gc |
29 | 29 |
30 // Test generator iteration. | 30 // Test generator iteration. |
31 | 31 |
32 var GeneratorFunction = (function*(){yield 1;}).__proto__.constructor; | 32 var GeneratorFunction = (function*(){yield 1;}).__proto__.constructor; |
33 | 33 |
| 34 function assertIteratorResult(value, done, result) { |
| 35 assertEquals({ value: value, done: done}, result); |
| 36 } |
| 37 |
34 function TestGeneratorResultPrototype() { | 38 function TestGeneratorResultPrototype() { |
35 function* g() { yield 1; } | 39 function* g() { yield 1; } |
36 var iter = g(); | 40 var iter = g(); |
37 var result = iter.next(); | 41 var result = iter.next(); |
38 | 42 |
39 assertSame(Object.prototype, Object.getPrototypeOf(result)); | 43 assertSame(Object.prototype, Object.getPrototypeOf(result)); |
40 property_names = Object.getOwnPropertyNames(result); | 44 property_names = Object.getOwnPropertyNames(result); |
41 property_names.sort(); | 45 property_names.sort(); |
42 assertEquals(["done", "value"], property_names); | 46 assertEquals(["done", "value"], property_names); |
43 assertEquals({ value: 1, done: false }, result); | 47 assertIteratorResult(1, false, result); |
44 } | 48 } |
45 TestGeneratorResultPrototype() | 49 TestGeneratorResultPrototype() |
46 | 50 |
47 function TestGenerator(g, expected_values_for_next, | 51 function TestGenerator(g, expected_values_for_next, |
48 send_val, expected_values_for_send) { | 52 send_val, expected_values_for_send) { |
49 function testNext(thunk) { | 53 function testNext(thunk) { |
50 var iter = thunk(); | 54 var iter = thunk(); |
51 for (var i = 0; i < expected_values_for_next.length; i++) { | 55 for (var i = 0; i < expected_values_for_next.length; i++) { |
52 assertEquals({ value: expected_values_for_next[i], | 56 assertIteratorResult(expected_values_for_next[i], |
53 done: i == expected_values_for_next.length - 1 }, | 57 i == expected_values_for_next.length - 1, |
54 iter.next()); | 58 iter.next()); |
55 } | 59 } |
56 assertThrows(function() { iter.next(); }, Error); | 60 assertThrows(function() { iter.next(); }, Error); |
57 } | 61 } |
58 function testSend(thunk) { | 62 function testSend(thunk) { |
59 var iter = thunk(); | 63 var iter = thunk(); |
60 for (var i = 0; i < expected_values_for_send.length; i++) { | 64 for (var i = 0; i < expected_values_for_send.length; i++) { |
61 assertEquals({ value: expected_values_for_send[i], | 65 assertIteratorResult(expected_values_for_send[i], |
62 done: i == expected_values_for_send.length - 1 }, | 66 i == expected_values_for_send.length - 1, |
63 iter.send(send_val)); | 67 iter.send(send_val)); |
64 } | 68 } |
65 assertThrows(function() { iter.send(send_val); }, Error); | 69 assertThrows(function() { iter.send(send_val); }, Error); |
66 } | 70 } |
67 function testThrow(thunk) { | 71 function testThrow(thunk) { |
68 for (var i = 0; i < expected_values_for_next.length; i++) { | 72 for (var i = 0; i < expected_values_for_next.length; i++) { |
69 var iter = thunk(); | 73 var iter = thunk(); |
70 for (var j = 0; j < i; j++) { | 74 for (var j = 0; j < i; j++) { |
71 assertEquals({ value: expected_values_for_next[j], | 75 assertIteratorResult(expected_values_for_next[j], |
72 done: j == expected_values_for_next.length - 1 }, | 76 j == expected_values_for_next.length - 1, |
73 iter.next()); | 77 iter.next()); |
74 } | 78 } |
75 function Sentinel() {} | 79 function Sentinel() {} |
76 assertThrows(function () { iter.throw(new Sentinel); }, Sentinel); | 80 assertThrows(function () { iter.throw(new Sentinel); }, Sentinel); |
77 assertThrows(function () { iter.next(); }, Error); | 81 assertThrows(function () { iter.next(); }, Error); |
78 } | 82 } |
79 } | 83 } |
80 | 84 |
81 testNext(g); | 85 testNext(g); |
82 testSend(g); | 86 testSend(g); |
83 testThrow(g); | 87 testThrow(g); |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
282 [2, "1foo3", 5, "4foo6", undefined]); | 286 [2, "1foo3", 5, "4foo6", undefined]); |
283 | 287 |
284 TestGenerator( | 288 TestGenerator( |
285 function* g23() { | 289 function* g23() { |
286 return (yield (1 + (yield 2) + 3)) + (yield (4 + (yield 5) + 6)); | 290 return (yield (1 + (yield 2) + 3)) + (yield (4 + (yield 5) + 6)); |
287 }, | 291 }, |
288 [2, NaN, 5, NaN, NaN], | 292 [2, NaN, 5, NaN, NaN], |
289 "foo", | 293 "foo", |
290 [2, "1foo3", 5, "4foo6", "foofoo"]); | 294 [2, "1foo3", 5, "4foo6", "foofoo"]); |
291 | 295 |
| 296 // Rewind a try context with and without operands on the stack. |
| 297 TestGenerator( |
| 298 function* g24() { |
| 299 try { |
| 300 return (yield (1 + (yield 2) + 3)) + (yield (4 + (yield 5) + 6)); |
| 301 } catch (e) { |
| 302 throw e; |
| 303 } |
| 304 }, |
| 305 [2, NaN, 5, NaN, NaN], |
| 306 "foo", |
| 307 [2, "1foo3", 5, "4foo6", "foofoo"]); |
| 308 |
| 309 // Yielding in a catch context, with and without operands on the stack. |
| 310 TestGenerator( |
| 311 function* g25() { |
| 312 try { |
| 313 throw (yield (1 + (yield 2) + 3)) |
| 314 } catch (e) { |
| 315 if (typeof e == 'object') throw e; |
| 316 return e + (yield (4 + (yield 5) + 6)); |
| 317 } |
| 318 }, |
| 319 [2, NaN, 5, NaN, NaN], |
| 320 "foo", |
| 321 [2, "1foo3", 5, "4foo6", "foofoo"]); |
| 322 |
| 323 function TestTryCatch() { |
| 324 function* g() { yield 1; try { yield 2; } catch (e) { yield e; } yield 3; } |
| 325 function Sentinel() {} |
| 326 var iter; |
| 327 |
| 328 iter = g(); |
| 329 assertIteratorResult(1, false, iter.next()); |
| 330 assertIteratorResult(2, false, iter.next()); |
| 331 assertIteratorResult(3, false, iter.next()); |
| 332 assertIteratorResult(undefined, true, iter.next()); |
| 333 assertThrows(function() { iter.next(); }, Error); |
| 334 |
| 335 iter = g(); |
| 336 assertThrows(function() { iter.throw(new Sentinel); }, Sentinel); |
| 337 assertThrows(function() { iter.next(); }, Error); |
| 338 |
| 339 iter = g(); |
| 340 assertIteratorResult(1, false, iter.next()); |
| 341 assertThrows(function() { iter.throw(new Sentinel); }, Sentinel); |
| 342 assertThrows(function() { iter.next(); }, Error); |
| 343 |
| 344 iter = g(); |
| 345 assertIteratorResult(1, false, iter.next()); |
| 346 assertIteratorResult(2, false, iter.next()); |
| 347 var exn = new Sentinel; |
| 348 assertIteratorResult(exn, false, iter.throw(exn)); |
| 349 assertIteratorResult(3, false, iter.next()); |
| 350 assertIteratorResult(undefined, true, iter.next()); |
| 351 assertThrows(function() { iter.next(); }, Error); |
| 352 |
| 353 iter = g(); |
| 354 assertIteratorResult(1, false, iter.next()); |
| 355 assertIteratorResult(2, false, iter.next()); |
| 356 var exn = new Sentinel; |
| 357 assertIteratorResult(exn, false, iter.throw(exn)); |
| 358 assertIteratorResult(3, false, iter.next()); |
| 359 assertThrows(function() { iter.throw(new Sentinel); }, Sentinel); |
| 360 assertThrows(function() { iter.next(); }, Error); |
| 361 |
| 362 iter = g(); |
| 363 assertIteratorResult(1, false, iter.next()); |
| 364 assertIteratorResult(2, false, iter.next()); |
| 365 var exn = new Sentinel; |
| 366 assertIteratorResult(exn, false, iter.throw(exn)); |
| 367 assertThrows(function() { iter.throw(new Sentinel); }, Sentinel); |
| 368 assertThrows(function() { iter.next(); }, Error); |
| 369 |
| 370 iter = g(); |
| 371 assertIteratorResult(1, false, iter.next()); |
| 372 assertIteratorResult(2, false, iter.next()); |
| 373 assertIteratorResult(3, false, iter.next()); |
| 374 assertIteratorResult(undefined, true, iter.next()); |
| 375 assertThrows(function() { iter.next(); }, Error); |
| 376 } |
| 377 TestTryCatch(); |
| 378 |
| 379 function TestTryFinally() { |
| 380 function* g() { yield 1; try { yield 2; } finally { yield 3; } yield 4; } |
| 381 function Sentinel() {} |
| 382 function Sentinel2() {} |
| 383 var iter; |
| 384 |
| 385 iter = g(); |
| 386 assertIteratorResult(1, false, iter.next()); |
| 387 assertIteratorResult(2, false, iter.next()); |
| 388 assertIteratorResult(3, false, iter.next()); |
| 389 assertIteratorResult(4, false, iter.next()); |
| 390 assertIteratorResult(undefined, true, iter.next()); |
| 391 assertThrows(function() { iter.next(); }, Error); |
| 392 |
| 393 iter = g(); |
| 394 assertThrows(function() { iter.throw(new Sentinel); }, Sentinel); |
| 395 assertThrows(function() { iter.next(); }, Error); |
| 396 |
| 397 iter = g(); |
| 398 assertIteratorResult(1, false, iter.next()); |
| 399 assertThrows(function() { iter.throw(new Sentinel); }, Sentinel); |
| 400 assertThrows(function() { iter.next(); }, Error); |
| 401 |
| 402 iter = g(); |
| 403 assertIteratorResult(1, false, iter.next()); |
| 404 assertIteratorResult(2, false, iter.next()); |
| 405 assertIteratorResult(3, false, iter.throw(new Sentinel)); |
| 406 assertThrows(function() { iter.next(); }, Sentinel); |
| 407 assertThrows(function() { iter.next(); }, Error); |
| 408 |
| 409 iter = g(); |
| 410 assertIteratorResult(1, false, iter.next()); |
| 411 assertIteratorResult(2, false, iter.next()); |
| 412 assertIteratorResult(3, false, iter.throw(new Sentinel)); |
| 413 assertThrows(function() { iter.throw(new Sentinel2); }, Sentinel2); |
| 414 assertThrows(function() { iter.next(); }, Error); |
| 415 |
| 416 iter = g(); |
| 417 assertIteratorResult(1, false, iter.next()); |
| 418 assertIteratorResult(2, false, iter.next()); |
| 419 assertIteratorResult(3, false, iter.next()); |
| 420 assertThrows(function() { iter.throw(new Sentinel); }, Sentinel); |
| 421 assertThrows(function() { iter.next(); }, Error); |
| 422 |
| 423 iter = g(); |
| 424 assertIteratorResult(1, false, iter.next()); |
| 425 assertIteratorResult(2, false, iter.next()); |
| 426 assertIteratorResult(3, false, iter.next()); |
| 427 assertIteratorResult(4, false, iter.next()); |
| 428 assertThrows(function() { iter.throw(new Sentinel); }, Sentinel); |
| 429 assertThrows(function() { iter.next(); }, Error); |
| 430 |
| 431 iter = g(); |
| 432 assertIteratorResult(1, false, iter.next()); |
| 433 assertIteratorResult(2, false, iter.next()); |
| 434 assertIteratorResult(3, false, iter.next()); |
| 435 assertIteratorResult(4, false, iter.next()); |
| 436 assertIteratorResult(undefined, true, iter.next()); |
| 437 assertThrows(function() { iter.next(); }, Error); |
| 438 } |
| 439 TestTryFinally(); |
| 440 |
| 441 function TestNestedTry() { |
| 442 function* g() { |
| 443 try { |
| 444 yield 1; |
| 445 try { yield 2; } catch (e) { yield e; } |
| 446 yield 3; |
| 447 } finally { |
| 448 yield 4; |
| 449 } |
| 450 yield 5; |
| 451 } |
| 452 function Sentinel() {} |
| 453 function Sentinel2() {} |
| 454 var iter; |
| 455 |
| 456 iter = g(); |
| 457 assertIteratorResult(1, false, iter.next()); |
| 458 assertIteratorResult(2, false, iter.next()); |
| 459 assertIteratorResult(3, false, iter.next()); |
| 460 assertIteratorResult(4, false, iter.next()); |
| 461 assertIteratorResult(5, false, iter.next()); |
| 462 assertIteratorResult(undefined, true, iter.next()); |
| 463 assertThrows(function() { iter.next(); }, Error); |
| 464 |
| 465 iter = g(); |
| 466 assertThrows(function() { iter.throw(new Sentinel); }, Sentinel); |
| 467 assertThrows(function() { iter.next(); }, Error); |
| 468 |
| 469 iter = g(); |
| 470 assertIteratorResult(1, false, iter.next()); |
| 471 assertIteratorResult(4, false, iter.throw(new Sentinel)); |
| 472 assertThrows(function() { iter.next(); }, Sentinel); |
| 473 assertThrows(function() { iter.next(); }, Error); |
| 474 |
| 475 iter = g(); |
| 476 assertIteratorResult(1, false, iter.next()); |
| 477 assertIteratorResult(4, false, iter.throw(new Sentinel)); |
| 478 assertThrows(function() { iter.throw(new Sentinel2); }, Sentinel2); |
| 479 assertThrows(function() { iter.next(); }, Error); |
| 480 |
| 481 iter = g(); |
| 482 assertIteratorResult(1, false, iter.next()); |
| 483 assertIteratorResult(2, false, iter.next()); |
| 484 var exn = new Sentinel; |
| 485 assertIteratorResult(exn, false, iter.throw(exn)); |
| 486 assertIteratorResult(3, false, iter.next()); |
| 487 assertIteratorResult(4, false, iter.next()); |
| 488 assertIteratorResult(5, false, iter.next()); |
| 489 assertIteratorResult(undefined, true, iter.next()); |
| 490 assertThrows(function() { iter.next(); }, Error); |
| 491 |
| 492 iter = g(); |
| 493 assertIteratorResult(1, false, iter.next()); |
| 494 assertIteratorResult(2, false, iter.next()); |
| 495 var exn = new Sentinel; |
| 496 assertIteratorResult(exn, false, iter.throw(exn)); |
| 497 assertIteratorResult(4, false, iter.throw(new Sentinel2)); |
| 498 assertThrows(function() { iter.next(); }, Sentinel2); |
| 499 assertThrows(function() { iter.next(); }, Error); |
| 500 |
| 501 iter = g(); |
| 502 assertIteratorResult(1, false, iter.next()); |
| 503 assertIteratorResult(2, false, iter.next()); |
| 504 var exn = new Sentinel; |
| 505 assertIteratorResult(exn, false, iter.throw(exn)); |
| 506 assertIteratorResult(3, false, iter.next()); |
| 507 assertIteratorResult(4, false, iter.throw(new Sentinel2)); |
| 508 assertThrows(function() { iter.next(); }, Sentinel2); |
| 509 assertThrows(function() { iter.next(); }, Error); |
| 510 |
| 511 // That's probably enough. |
| 512 } |
| 513 TestNestedTry(); |
| 514 |
292 function TestRecursion() { | 515 function TestRecursion() { |
293 function TestNextRecursion() { | 516 function TestNextRecursion() { |
294 function* g() { yield iter.next(); } | 517 function* g() { yield iter.next(); } |
295 var iter = g(); | 518 var iter = g(); |
296 return iter.next(); | 519 return iter.next(); |
297 } | 520 } |
298 function TestSendRecursion() { | 521 function TestSendRecursion() { |
299 function* g() { yield iter.send(42); } | 522 function* g() { yield iter.send(42); } |
300 var iter = g(); | 523 var iter = g(); |
301 return iter.next(); | 524 return iter.next(); |
302 } | 525 } |
303 function TestThrowRecursion() { | 526 function TestThrowRecursion() { |
304 function* g() { yield iter.throw(1); } | 527 function* g() { yield iter.throw(1); } |
305 var iter = g(); | 528 var iter = g(); |
306 return iter.next(); | 529 return iter.next(); |
307 } | 530 } |
308 assertThrows(TestNextRecursion, Error); | 531 assertThrows(TestNextRecursion, Error); |
309 assertThrows(TestSendRecursion, Error); | 532 assertThrows(TestSendRecursion, Error); |
310 assertThrows(TestThrowRecursion, Error); | 533 assertThrows(TestThrowRecursion, Error); |
311 } | 534 } |
312 TestRecursion(); | 535 TestRecursion(); |
OLD | NEW |