OLD | NEW |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 | 5 |
6 #include "vm/ast_printer.h" | 6 #include "vm/ast_printer.h" |
7 #include "vm/class_finalizer.h" | 7 #include "vm/class_finalizer.h" |
8 #include "vm/debugger.h" | 8 #include "vm/debugger.h" |
9 #include "vm/longjump.h" | 9 #include "vm/longjump.h" |
10 #include "vm/object.h" | 10 #include "vm/object.h" |
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
365 " return value1 + aa();\n" | 365 " return value1 + aa();\n" |
366 " }\n" | 366 " }\n" |
367 " return b();\n" | 367 " return b();\n" |
368 "}\n"; | 368 "}\n"; |
369 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); | 369 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); |
370 EXPECT_VALID(lib); | 370 EXPECT_VALID(lib); |
371 | 371 |
372 EXPECT_STREQ( | 372 EXPECT_STREQ( |
373 // bb captures only value2 from aa. No others. | 373 // bb captures only value2 from aa. No others. |
374 "a.b.aa.bb\n" | 374 "a.b.aa.bb\n" |
375 " 0 ContextVar level=0 begin=33 end=43 name=value2\n" | 375 " 0 ContextVar level=0 begin=34 end=44 name=value2\n" |
376 " 1 CurrentCtx scope=0 begin=0 end=0" | 376 " 1 CurrentCtx scope=0 begin=0 end=0" |
377 " name=:current_context_var\n" | 377 " name=:current_context_var\n" |
378 | 378 |
379 // Closure call saves current context. | 379 // Closure call saves current context. |
380 "_Closure.call\n" | 380 "_Closure.call\n" |
381 " 0 StackVar scope=1 begin=0 end=4 name=this\n" | 381 " 0 StackVar scope=1 begin=0 end=4 name=this\n" |
382 " 1 CurrentCtx scope=0 begin=0 end=0" | 382 " 1 CurrentCtx scope=0 begin=0 end=0" |
383 " name=:current_context_var\n" | 383 " name=:current_context_var\n" |
384 | 384 |
385 // aa shares value2. Notice that we save the entry ctx instead | 385 // aa shares value2. Notice that we save the entry ctx instead |
386 // of chaining from b. This keeps us from holding onto closures | 386 // of chaining from b. This keeps us from holding onto closures |
387 // that we would never access. | 387 // that we would never access. |
388 "a.b.aa\n" | 388 "a.b.aa\n" |
389 " 0 CurrentCtx scope=0 begin=0 end=0" | 389 " 0 CurrentCtx scope=0 begin=0 end=0" |
390 " name=:current_context_var\n" | 390 " name=:current_context_var\n" |
391 " 1 ContextLevel level=1 scope=2 begin=22 end=52\n" | 391 " 1 ContextLevel level=1 scope=2 begin=22 end=53\n" |
392 " 2 ContextVar level=1 begin=28 end=52 name=value2\n" | 392 " 2 ContextVar level=1 begin=29 end=53 name=value2\n" |
393 " 3 StackVar scope=2 begin=30 end=52 name=bb\n" | 393 " 3 StackVar scope=2 begin=31 end=53 name=bb\n" |
394 | 394 |
395 // Closure call saves current context. | 395 // Closure call saves current context. |
396 "_Closure.call\n" | 396 "_Closure.call\n" |
397 " 0 StackVar scope=1 begin=0 end=4 name=this\n" | 397 " 0 StackVar scope=1 begin=0 end=4 name=this\n" |
398 " 1 CurrentCtx scope=0 begin=0 end=0" | 398 " 1 CurrentCtx scope=0 begin=0 end=0" |
399 " name=:current_context_var\n" | 399 " name=:current_context_var\n" |
400 | 400 |
401 // b captures value1 from a. | 401 // b captures value1 from a. |
402 "a.b\n" | 402 "a.b\n" |
403 " 0 ContextVar level=0 begin=14 end=62 name=value1\n" | 403 " 0 ContextVar level=0 begin=14 end=63 name=value1\n" |
404 " 1 CurrentCtx scope=0 begin=0 end=0" | 404 " 1 CurrentCtx scope=0 begin=0 end=0" |
405 " name=:current_context_var\n" | 405 " name=:current_context_var\n" |
406 " 2 StackVar scope=2 begin=18 end=62 name=aa\n" | 406 " 2 StackVar scope=2 begin=18 end=63 name=aa\n" |
407 | 407 |
408 // Closure call saves current context. | 408 // Closure call saves current context. |
409 "_Closure.call\n" | 409 "_Closure.call\n" |
410 " 0 StackVar scope=1 begin=0 end=4 name=this\n" | 410 " 0 StackVar scope=1 begin=0 end=4 name=this\n" |
411 " 1 CurrentCtx scope=0 begin=0 end=0" | 411 " 1 CurrentCtx scope=0 begin=0 end=0" |
412 " name=:current_context_var\n" | 412 " name=:current_context_var\n" |
413 | 413 |
414 // a shares value1, saves entry ctx. | 414 // a shares value1, saves entry ctx. |
415 "a\n" | 415 "a\n" |
416 " 0 CurrentCtx scope=0 begin=0 end=0" | 416 " 0 CurrentCtx scope=0 begin=0 end=0" |
417 " name=:current_context_var\n" | 417 " name=:current_context_var\n" |
418 " 1 ContextLevel level=1 scope=2 begin=4 end=70\n" | 418 " 1 ContextLevel level=1 scope=2 begin=4 end=71\n" |
419 " 2 ContextVar level=1 begin=10 end=70 name=value1\n" | 419 " 2 ContextVar level=1 begin=10 end=71 name=value1\n" |
420 " 3 StackVar scope=2 begin=12 end=70 name=b\n", | 420 " 3 StackVar scope=2 begin=12 end=71 name=b\n", |
421 CaptureVarsAtLine(lib, "a", 7)); | 421 CaptureVarsAtLine(lib, "a", 7)); |
422 } | 422 } |
423 | 423 |
424 | 424 |
425 TEST_CASE(Parser_AllocateVariables_Issue7681) { | 425 TEST_CASE(Parser_AllocateVariables_Issue7681) { |
426 // This is a distilled version of the program from Issue 7681. | 426 // This is a distilled version of the program from Issue 7681. |
427 // | 427 // |
428 // When we create the closure at line 11, we need to make sure to | 428 // When we create the closure at line 11, we need to make sure to |
429 // save the entry context instead of chaining to the parent context. | 429 // save the entry context instead of chaining to the parent context. |
430 // | 430 // |
(...skipping 15 matching lines...) Expand all Loading... |
446 " return y;\n" | 446 " return y;\n" |
447 " };\n" | 447 " };\n" |
448 " };\n" | 448 " };\n" |
449 " x.onX(new Y());\n" | 449 " x.onX(new Y());\n" |
450 "}\n"; | 450 "}\n"; |
451 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); | 451 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); |
452 EXPECT_VALID(lib); | 452 EXPECT_VALID(lib); |
453 EXPECT_STREQ( | 453 EXPECT_STREQ( |
454 // This frame saves the entry context instead of chaining. Good. | 454 // This frame saves the entry context instead of chaining. Good. |
455 "doIt.<anonymous closure>\n" | 455 "doIt.<anonymous closure>\n" |
456 " 0 ContextLevel level=1 scope=1 begin=41 end=62\n" | 456 " 0 ContextLevel level=1 scope=1 begin=41 end=65\n" |
457 " 1 ContextVar level=1 begin=42 end=62 name=y\n" | 457 " 1 ContextVar level=1 begin=42 end=65 name=y\n" |
458 " 2 CurrentCtx scope=0 begin=0 end=0" | 458 " 2 CurrentCtx scope=0 begin=0 end=0" |
459 " name=:current_context_var\n" | 459 " name=:current_context_var\n" |
460 | 460 |
461 // Closure call saves current context. | 461 // Closure call saves current context. |
462 "_Closure.call\n" | 462 "_Closure.call\n" |
463 " 0 StackVar scope=1 begin=0 end=4 name=this\n" | 463 " 0 StackVar scope=1 begin=0 end=4 name=this\n" |
464 " 1 CurrentCtx scope=0 begin=0 end=0" | 464 " 1 CurrentCtx scope=0 begin=0 end=0" |
465 " name=:current_context_var\n" | 465 " name=:current_context_var\n" |
466 | 466 |
467 "X.onX\n" | 467 "X.onX\n" |
468 " 0 StackVar scope=1 begin=0 end=0 name=this\n" | 468 " 0 StackVar scope=1 begin=0 end=0 name=this\n" |
469 " 1 CurrentCtx scope=0 begin=0 end=0" | 469 " 1 CurrentCtx scope=0 begin=0 end=0" |
470 " name=:current_context_var\n" | 470 " name=:current_context_var\n" |
471 | 471 |
472 // No context is saved here since no vars are captured. | 472 // No context is saved here since no vars are captured. |
473 "doIt\n" | 473 "doIt\n" |
474 " 0 CurrentCtx scope=0 begin=0 end=0" | 474 " 0 CurrentCtx scope=0 begin=0 end=0" |
475 " name=:current_context_var\n" | 475 " name=:current_context_var\n" |
476 " 1 StackVar scope=2 begin=35 end=77 name=x\n", | 476 " 1 StackVar scope=2 begin=35 end=80 name=x\n", |
477 CaptureVarsAtLine(lib, "doIt", 12)); | 477 CaptureVarsAtLine(lib, "doIt", 12)); |
478 } | 478 } |
479 | 479 |
480 | 480 |
481 TEST_CASE(Parser_AllocateVariables_CaptureLoopVar) { | 481 TEST_CASE(Parser_AllocateVariables_CaptureLoopVar) { |
482 // This test verifies that... | 482 // This test verifies that... |
483 // | 483 // |
484 // https://code.google.com/p/dart/issues/detail?id=18561 | 484 // https://code.google.com/p/dart/issues/detail?id=18561 |
485 // | 485 // |
486 // ...stays fixed. | 486 // ...stays fixed. |
487 const char* kScriptChars = | 487 const char* kScriptChars = |
488 "int outer() {\n" | 488 "int outer() {\n" |
489 " for(int i = 0; i < 1; i++) {\n" | 489 " for(int i = 0; i < 1; i++) {\n" |
490 " var value = 11 + i;\n" | 490 " var value = 11 + i;\n" |
491 " int inner() {\n" | 491 " int inner() {\n" |
492 " return value;\n" // line 5 | 492 " return value;\n" // line 5 |
493 " }\n" | 493 " }\n" |
494 " return inner();\n" | 494 " return inner();\n" |
495 " }\n" | 495 " }\n" |
496 "}\n"; | 496 "}\n"; |
497 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); | 497 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); |
498 EXPECT_VALID(lib); | 498 EXPECT_VALID(lib); |
499 EXPECT_STREQ( | 499 EXPECT_STREQ( |
500 // inner function captures variable value. That's fine. | 500 // inner function captures variable value. That's fine. |
501 "outer.inner\n" | 501 "outer.inner\n" |
502 " 0 ContextVar level=0 begin=32 end=42 name=value\n" | 502 " 0 ContextVar level=0 begin=33 end=43 name=value\n" |
503 " 1 CurrentCtx scope=0 begin=0 end=0" | 503 " 1 CurrentCtx scope=0 begin=0 end=0" |
504 " name=:current_context_var\n" | 504 " name=:current_context_var\n" |
505 | 505 |
506 // Closure call saves current context. | 506 // Closure call saves current context. |
507 "_Closure.call\n" | 507 "_Closure.call\n" |
508 " 0 StackVar scope=1 begin=0 end=4 name=this\n" | 508 " 0 StackVar scope=1 begin=0 end=4 name=this\n" |
509 " 1 CurrentCtx scope=0 begin=0 end=0" | 509 " 1 CurrentCtx scope=0 begin=0 end=0" |
510 " name=:current_context_var\n" | 510 " name=:current_context_var\n" |
511 | 511 |
512 // The outer function saves the entry context, even though the | 512 // The outer function saves the entry context, even though the |
513 // captured variable is in a loop. Good. | 513 // captured variable is in a loop. Good. |
514 "outer\n" | 514 "outer\n" |
515 " 0 CurrentCtx scope=0 begin=0 end=0" | 515 " 0 CurrentCtx scope=0 begin=0 end=0" |
516 " name=:current_context_var\n" | 516 " name=:current_context_var\n" |
517 " 1 StackVar scope=3 begin=12 end=50 name=i\n" | 517 " 1 StackVar scope=3 begin=12 end=52 name=i\n" |
518 " 2 ContextLevel level=1 scope=4 begin=20 end=50\n" | 518 " 2 ContextLevel level=1 scope=4 begin=20 end=52\n" |
519 " 3 ContextVar level=1 begin=28 end=50 name=value\n" | 519 " 3 ContextVar level=1 begin=28 end=52 name=value\n" |
520 " 4 StackVar scope=4 begin=30 end=50 name=inner\n", | 520 " 4 StackVar scope=4 begin=30 end=52 name=inner\n", |
521 CaptureVarsAtLine(lib, "outer", 5)); | 521 CaptureVarsAtLine(lib, "outer", 5)); |
522 } | 522 } |
523 | 523 |
524 TEST_CASE(Parser_AllocateVariables_MiddleChain) { | 524 TEST_CASE(Parser_AllocateVariables_MiddleChain) { |
525 const char* kScriptChars = | 525 const char* kScriptChars = |
526 "a() {\n" | 526 "a() {\n" |
527 " int x = 11;\n" | 527 " int x = 11;\n" |
528 " b() {\n" | 528 " b() {\n" |
529 " for (int i = 0; i < 1; i++) {\n" | 529 " for (int i = 0; i < 1; i++) {\n" |
530 " int d() {\n" | 530 " int d() {\n" |
531 " return i;\n" | 531 " return i;\n" |
532 " }\n" | 532 " }\n" |
533 " }\n" | 533 " }\n" |
534 " int c() {\n" | 534 " int c() {\n" |
535 " return x + 1;\n" // line 10 | 535 " return x + 1;\n" // line 10 |
536 " }\n" | 536 " }\n" |
537 " return c();\n" | 537 " return c();\n" |
538 " }\n" | 538 " }\n" |
539 " return b();\n" | 539 " return b();\n" |
540 "}\n"; | 540 "}\n"; |
541 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); | 541 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); |
542 EXPECT_VALID(lib); | 542 EXPECT_VALID(lib); |
543 EXPECT_STREQ( | 543 EXPECT_STREQ( |
544 "a.b.c\n" | 544 "a.b.c\n" |
545 " 0 ContextVar level=0 begin=50 end=62 name=x\n" | 545 " 0 ContextVar level=0 begin=51 end=64 name=x\n" |
546 " 1 CurrentCtx scope=0 begin=0 end=0" | 546 " 1 CurrentCtx scope=0 begin=0 end=0" |
547 " name=:current_context_var\n" | 547 " name=:current_context_var\n" |
548 "_Closure.call\n" | 548 "_Closure.call\n" |
549 " 0 StackVar scope=1 begin=0 end=4 name=this\n" | 549 " 0 StackVar scope=1 begin=0 end=4 name=this\n" |
550 " 1 CurrentCtx scope=0 begin=0 end=0" | 550 " 1 CurrentCtx scope=0 begin=0 end=0" |
551 " name=:current_context_var\n" | 551 " name=:current_context_var\n" |
552 | 552 |
553 // Doesn't save the entry context. Chains to parent instead. | 553 // Doesn't save the entry context. Chains to parent instead. |
554 "a.b\n" | 554 "a.b\n" |
555 " 0 ContextVar level=0 begin=12 end=71 name=x\n" | 555 " 0 ContextVar level=0 begin=12 end=73 name=x\n" |
556 " 1 CurrentCtx scope=0 begin=0 end=0" | 556 " 1 CurrentCtx scope=0 begin=0 end=0" |
557 " name=:current_context_var\n" | 557 " name=:current_context_var\n" |
558 " 2 StackVar scope=2 begin=47 end=71 name=c\n" | 558 " 2 StackVar scope=2 begin=48 end=73 name=c\n" |
559 " 3 ContextLevel level=1 scope=3 begin=18 end=47\n" | 559 " 3 ContextLevel level=1 scope=3 begin=18 end=48\n" |
560 " 4 ContextVar level=1 begin=22 end=47 name=i\n" | 560 " 4 ContextVar level=1 begin=22 end=48 name=i\n" |
561 " 5 StackVar scope=4 begin=32 end=47 name=d\n" | 561 " 5 StackVar scope=4 begin=33 end=48 name=d\n" |
562 | 562 |
563 "_Closure.call\n" | 563 "_Closure.call\n" |
564 " 0 StackVar scope=1 begin=0 end=4 name=this\n" | 564 " 0 StackVar scope=1 begin=0 end=4 name=this\n" |
565 " 1 CurrentCtx scope=0 begin=0 end=0" | 565 " 1 CurrentCtx scope=0 begin=0 end=0" |
566 " name=:current_context_var\n" | 566 " name=:current_context_var\n" |
567 | 567 |
568 "a\n" | 568 "a\n" |
569 " 0 CurrentCtx scope=0 begin=0 end=0" | 569 " 0 CurrentCtx scope=0 begin=0 end=0" |
570 " name=:current_context_var\n" | 570 " name=:current_context_var\n" |
571 " 1 ContextLevel level=1 scope=2 begin=3 end=79\n" | 571 " 1 ContextLevel level=1 scope=2 begin=3 end=81\n" |
572 " 2 ContextVar level=1 begin=9 end=79 name=x\n" | 572 " 2 ContextVar level=1 begin=9 end=81 name=x\n" |
573 " 3 StackVar scope=2 begin=11 end=79 name=b\n", | 573 " 3 StackVar scope=2 begin=11 end=81 name=b\n", |
574 CaptureVarsAtLine(lib, "a", 10)); | 574 CaptureVarsAtLine(lib, "a", 10)); |
575 } | 575 } |
576 | 576 |
577 #endif // !PRODUCT | 577 #endif // !PRODUCT |
578 | 578 |
579 } // namespace dart | 579 } // namespace dart |
OLD | NEW |