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 TestGenerator(g, expected_values_for_next, | 38 function TestGenerator(g, expected_values_for_next, |
35 send_val, expected_values_for_send) { | 39 send_val, expected_values_for_send) { |
36 function testNext(thunk) { | 40 function testNext(thunk) { |
37 var iter = thunk(); | 41 var iter = thunk(); |
38 for (var i = 0; i < expected_values_for_next.length; i++) { | 42 for (var i = 0; i < expected_values_for_next.length; i++) { |
39 assertEquals({ value: expected_values_for_next[i], | 43 assertIteratorResult(expected_values_for_next[i], |
40 done: i == expected_values_for_next.length - 1 }, | 44 i == expected_values_for_next.length - 1, |
41 iter.next()); | 45 iter.next()); |
42 } | 46 } |
43 assertThrows(function() { iter.next(); }, Error); | 47 assertThrows(function() { iter.next(); }, Error); |
44 } | 48 } |
45 function testSend(thunk) { | 49 function testSend(thunk) { |
46 var iter = thunk(); | 50 var iter = thunk(); |
47 for (var i = 0; i < expected_values_for_send.length; i++) { | 51 for (var i = 0; i < expected_values_for_send.length; i++) { |
48 assertEquals({ value: expected_values_for_send[i], | 52 assertIteratorResult(expected_values_for_send[i], |
49 done: i == expected_values_for_send.length - 1 }, | 53 i == expected_values_for_send.length - 1, |
50 iter.send(send_val)); | 54 iter.send(send_val)); |
51 } | 55 } |
52 assertThrows(function() { iter.send(send_val); }, Error); | 56 assertThrows(function() { iter.send(send_val); }, Error); |
53 } | 57 } |
54 function testThrow(thunk) { | 58 function testThrow(thunk) { |
55 for (var i = 0; i < expected_values_for_next.length; i++) { | 59 for (var i = 0; i < expected_values_for_next.length; i++) { |
56 var iter = thunk(); | 60 var iter = thunk(); |
57 for (var j = 0; j < i; j++) { | 61 for (var j = 0; j < i; j++) { |
58 assertEquals({ value: expected_values_for_next[j], | 62 assertIteratorResult(expected_values_for_next[j], |
59 done: j == expected_values_for_next.length - 1 }, | 63 j == expected_values_for_next.length - 1, |
60 iter.next()); | 64 iter.next()); |
61 } | 65 } |
62 function Sentinel() {} | 66 function Sentinel() {} |
63 assertThrows(function () { iter.throw(new Sentinel); }, Sentinel); | 67 assertThrows(function () { iter.throw(new Sentinel); }, Sentinel); |
64 assertThrows(function () { iter.next(); }, Error); | 68 assertThrows(function () { iter.next(); }, Error); |
65 } | 69 } |
66 } | 70 } |
67 | 71 |
68 testNext(g); | 72 testNext(g); |
69 testSend(g); | 73 testSend(g); |
70 testThrow(g); | 74 testThrow(g); |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
269 [2, "1foo3", 5, "4foo6", undefined]); | 273 [2, "1foo3", 5, "4foo6", undefined]); |
270 | 274 |
271 TestGenerator( | 275 TestGenerator( |
272 function* g23() { | 276 function* g23() { |
273 return (yield (1 + (yield 2) + 3)) + (yield (4 + (yield 5) + 6)); | 277 return (yield (1 + (yield 2) + 3)) + (yield (4 + (yield 5) + 6)); |
274 }, | 278 }, |
275 [2, NaN, 5, NaN, NaN], | 279 [2, NaN, 5, NaN, NaN], |
276 "foo", | 280 "foo", |
277 [2, "1foo3", 5, "4foo6", "foofoo"]); | 281 [2, "1foo3", 5, "4foo6", "foofoo"]); |
278 | 282 |
| 283 // Rewind a try context with and without operands on the stack. |
| 284 TestGenerator( |
| 285 function* g24() { |
| 286 try { |
| 287 return (yield (1 + (yield 2) + 3)) + (yield (4 + (yield 5) + 6)); |
| 288 } catch (e) { |
| 289 throw e; |
| 290 } |
| 291 }, |
| 292 [2, NaN, 5, NaN, NaN], |
| 293 "foo", |
| 294 [2, "1foo3", 5, "4foo6", "foofoo"]); |
| 295 |
| 296 // Yielding in a catch context, with and without operands on the stack. |
| 297 TestGenerator( |
| 298 function* g25() { |
| 299 try { |
| 300 throw (yield (1 + (yield 2) + 3)) |
| 301 } catch (e) { |
| 302 if (typeof e == 'object') throw e; |
| 303 return e + (yield (4 + (yield 5) + 6)); |
| 304 } |
| 305 }, |
| 306 [2, NaN, 5, NaN, NaN], |
| 307 "foo", |
| 308 [2, "1foo3", 5, "4foo6", "foofoo"]); |
| 309 |
| 310 function TestTryCatch() { |
| 311 function* g() { yield 1; try { yield 2; } catch (e) { yield e; } yield 3; } |
| 312 function Sentinel() {} |
| 313 var iter; |
| 314 |
| 315 iter = g(); |
| 316 assertIteratorResult(1, false, iter.next()); |
| 317 assertIteratorResult(2, false, iter.next()); |
| 318 assertIteratorResult(3, false, iter.next()); |
| 319 assertIteratorResult(undefined, true, iter.next()); |
| 320 assertThrows(function() { iter.next(); }, Error); |
| 321 |
| 322 iter = g(); |
| 323 assertThrows(function() { iter.throw(new Sentinel); }, Sentinel); |
| 324 assertThrows(function() { iter.next(); }, Error); |
| 325 |
| 326 iter = g(); |
| 327 assertIteratorResult(1, false, iter.next()); |
| 328 assertThrows(function() { iter.throw(new Sentinel); }, Sentinel); |
| 329 assertThrows(function() { iter.next(); }, Error); |
| 330 |
| 331 iter = g(); |
| 332 assertIteratorResult(1, false, iter.next()); |
| 333 assertIteratorResult(2, false, iter.next()); |
| 334 var exn = new Sentinel; |
| 335 assertIteratorResult(exn, false, iter.throw(exn)); |
| 336 assertIteratorResult(3, false, iter.next()); |
| 337 assertIteratorResult(undefined, true, iter.next()); |
| 338 assertThrows(function() { iter.next(); }, Error); |
| 339 |
| 340 iter = g(); |
| 341 assertIteratorResult(1, false, iter.next()); |
| 342 assertIteratorResult(2, false, iter.next()); |
| 343 var exn = new Sentinel; |
| 344 assertIteratorResult(exn, false, iter.throw(exn)); |
| 345 assertIteratorResult(3, false, iter.next()); |
| 346 assertThrows(function() { iter.throw(new Sentinel); }, Sentinel); |
| 347 assertThrows(function() { iter.next(); }, Error); |
| 348 |
| 349 iter = g(); |
| 350 assertIteratorResult(1, false, iter.next()); |
| 351 assertIteratorResult(2, false, iter.next()); |
| 352 var exn = new Sentinel; |
| 353 assertIteratorResult(exn, false, iter.throw(exn)); |
| 354 assertThrows(function() { iter.throw(new Sentinel); }, Sentinel); |
| 355 assertThrows(function() { iter.next(); }, Error); |
| 356 |
| 357 iter = g(); |
| 358 assertIteratorResult(1, false, iter.next()); |
| 359 assertIteratorResult(2, false, iter.next()); |
| 360 assertIteratorResult(3, false, iter.next()); |
| 361 assertIteratorResult(undefined, true, iter.next()); |
| 362 assertThrows(function() { iter.next(); }, Error); |
| 363 } |
| 364 TestTryCatch(); |
| 365 |
| 366 function TestTryFinally() { |
| 367 function* g() { yield 1; try { yield 2; } finally { yield 3; } yield 4; } |
| 368 function Sentinel() {} |
| 369 function Sentinel2() {} |
| 370 var iter; |
| 371 |
| 372 iter = g(); |
| 373 assertIteratorResult(1, false, iter.next()); |
| 374 assertIteratorResult(2, false, iter.next()); |
| 375 assertIteratorResult(3, false, iter.next()); |
| 376 assertIteratorResult(4, false, iter.next()); |
| 377 assertIteratorResult(undefined, true, iter.next()); |
| 378 assertThrows(function() { iter.next(); }, Error); |
| 379 |
| 380 iter = g(); |
| 381 assertThrows(function() { iter.throw(new Sentinel); }, Sentinel); |
| 382 assertThrows(function() { iter.next(); }, Error); |
| 383 |
| 384 iter = g(); |
| 385 assertIteratorResult(1, false, iter.next()); |
| 386 assertThrows(function() { iter.throw(new Sentinel); }, Sentinel); |
| 387 assertThrows(function() { iter.next(); }, Error); |
| 388 |
| 389 iter = g(); |
| 390 assertIteratorResult(1, false, iter.next()); |
| 391 assertIteratorResult(2, false, iter.next()); |
| 392 assertIteratorResult(3, false, iter.throw(new Sentinel)); |
| 393 assertThrows(function() { iter.next(); }, Sentinel); |
| 394 assertThrows(function() { iter.next(); }, Error); |
| 395 |
| 396 iter = g(); |
| 397 assertIteratorResult(1, false, iter.next()); |
| 398 assertIteratorResult(2, false, iter.next()); |
| 399 assertIteratorResult(3, false, iter.throw(new Sentinel)); |
| 400 assertThrows(function() { iter.throw(new Sentinel2); }, Sentinel2); |
| 401 assertThrows(function() { iter.next(); }, Error); |
| 402 |
| 403 iter = g(); |
| 404 assertIteratorResult(1, false, iter.next()); |
| 405 assertIteratorResult(2, false, iter.next()); |
| 406 assertIteratorResult(3, false, iter.next()); |
| 407 assertThrows(function() { iter.throw(new Sentinel); }, Sentinel); |
| 408 assertThrows(function() { iter.next(); }, Error); |
| 409 |
| 410 iter = g(); |
| 411 assertIteratorResult(1, false, iter.next()); |
| 412 assertIteratorResult(2, false, iter.next()); |
| 413 assertIteratorResult(3, false, iter.next()); |
| 414 assertIteratorResult(4, false, iter.next()); |
| 415 assertThrows(function() { iter.throw(new Sentinel); }, Sentinel); |
| 416 assertThrows(function() { iter.next(); }, Error); |
| 417 |
| 418 iter = g(); |
| 419 assertIteratorResult(1, false, iter.next()); |
| 420 assertIteratorResult(2, false, iter.next()); |
| 421 assertIteratorResult(3, false, iter.next()); |
| 422 assertIteratorResult(4, false, iter.next()); |
| 423 assertIteratorResult(undefined, true, iter.next()); |
| 424 assertThrows(function() { iter.next(); }, Error); |
| 425 } |
| 426 TestTryFinally(); |
| 427 |
| 428 function TestNestedTry() { |
| 429 function* g() { |
| 430 try { |
| 431 yield 1; |
| 432 try { yield 2; } catch (e) { yield e; } |
| 433 yield 3; |
| 434 } finally { |
| 435 yield 4; |
| 436 } |
| 437 yield 5; |
| 438 } |
| 439 function Sentinel() {} |
| 440 function Sentinel2() {} |
| 441 var iter; |
| 442 |
| 443 iter = g(); |
| 444 assertIteratorResult(1, false, iter.next()); |
| 445 assertIteratorResult(2, false, iter.next()); |
| 446 assertIteratorResult(3, false, iter.next()); |
| 447 assertIteratorResult(4, false, iter.next()); |
| 448 assertIteratorResult(5, false, iter.next()); |
| 449 assertIteratorResult(undefined, true, iter.next()); |
| 450 assertThrows(function() { iter.next(); }, Error); |
| 451 |
| 452 iter = g(); |
| 453 assertThrows(function() { iter.throw(new Sentinel); }, Sentinel); |
| 454 assertThrows(function() { iter.next(); }, Error); |
| 455 |
| 456 iter = g(); |
| 457 assertIteratorResult(1, false, iter.next()); |
| 458 assertIteratorResult(4, false, iter.throw(new Sentinel)); |
| 459 assertThrows(function() { iter.next(); }, Sentinel); |
| 460 assertThrows(function() { iter.next(); }, Error); |
| 461 |
| 462 iter = g(); |
| 463 assertIteratorResult(1, false, iter.next()); |
| 464 assertIteratorResult(4, false, iter.throw(new Sentinel)); |
| 465 assertThrows(function() { iter.throw(new Sentinel2); }, Sentinel2); |
| 466 assertThrows(function() { iter.next(); }, Error); |
| 467 |
| 468 iter = g(); |
| 469 assertIteratorResult(1, false, iter.next()); |
| 470 assertIteratorResult(2, false, iter.next()); |
| 471 var exn = new Sentinel; |
| 472 assertIteratorResult(exn, false, iter.throw(exn)); |
| 473 assertIteratorResult(3, false, iter.next()); |
| 474 assertIteratorResult(4, false, iter.next()); |
| 475 assertIteratorResult(5, false, iter.next()); |
| 476 assertIteratorResult(undefined, true, iter.next()); |
| 477 assertThrows(function() { iter.next(); }, Error); |
| 478 |
| 479 iter = g(); |
| 480 assertIteratorResult(1, false, iter.next()); |
| 481 assertIteratorResult(2, false, iter.next()); |
| 482 var exn = new Sentinel; |
| 483 assertIteratorResult(exn, false, iter.throw(exn)); |
| 484 assertIteratorResult(4, false, iter.throw(new Sentinel2)); |
| 485 assertThrows(function() { iter.next(); }, Sentinel2); |
| 486 assertThrows(function() { iter.next(); }, Error); |
| 487 |
| 488 iter = g(); |
| 489 assertIteratorResult(1, false, iter.next()); |
| 490 assertIteratorResult(2, false, iter.next()); |
| 491 var exn = new Sentinel; |
| 492 assertIteratorResult(exn, false, iter.throw(exn)); |
| 493 assertIteratorResult(3, false, iter.next()); |
| 494 assertIteratorResult(4, false, iter.throw(new Sentinel2)); |
| 495 assertThrows(function() { iter.next(); }, Sentinel2); |
| 496 assertThrows(function() { iter.next(); }, Error); |
| 497 |
| 498 // That's probably enough. |
| 499 } |
| 500 TestNestedTry(); |
| 501 |
279 function TestRecursion() { | 502 function TestRecursion() { |
280 function TestNextRecursion() { | 503 function TestNextRecursion() { |
281 function* g() { yield iter.next(); } | 504 function* g() { yield iter.next(); } |
282 var iter = g(); | 505 var iter = g(); |
283 return iter.next(); | 506 return iter.next(); |
284 } | 507 } |
285 function TestSendRecursion() { | 508 function TestSendRecursion() { |
286 function* g() { yield iter.send(42); } | 509 function* g() { yield iter.send(42); } |
287 var iter = g(); | 510 var iter = g(); |
288 return iter.next(); | 511 return iter.next(); |
289 } | 512 } |
290 function TestThrowRecursion() { | 513 function TestThrowRecursion() { |
291 function* g() { yield iter.throw(1); } | 514 function* g() { yield iter.throw(1); } |
292 var iter = g(); | 515 var iter = g(); |
293 return iter.next(); | 516 return iter.next(); |
294 } | 517 } |
295 assertThrows(TestNextRecursion, Error); | 518 assertThrows(TestNextRecursion, Error); |
296 assertThrows(TestSendRecursion, Error); | 519 assertThrows(TestSendRecursion, Error); |
297 assertThrows(TestThrowRecursion, Error); | 520 assertThrows(TestThrowRecursion, Error); |
298 } | 521 } |
299 TestRecursion(); | 522 TestRecursion(); |
OLD | NEW |