| 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 |