| 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 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 270 "(dynamic, dynamic) => int.call\n" | 270 "(dynamic, dynamic) => int.call\n" |
| 271 " 0 StackVar scope=1 begin=0 end=0 name=this\n" | 271 " 0 StackVar scope=1 begin=0 end=0 name=this\n" |
| 272 " 1 CurrentCtx scope=0 begin=0 end=0" | 272 " 1 CurrentCtx scope=0 begin=0 end=0" |
| 273 " name=:current_context_var\n" | 273 " name=:current_context_var\n" |
| 274 | 274 |
| 275 // function main uses one ctx var at (1); saves caller ctx. | 275 // function main uses one ctx var at (1); saves caller ctx. |
| 276 "::.main\n" | 276 "::.main\n" |
| 277 " 0 ContextLevel level=1 scope=1 begin=2 end=37\n" | 277 " 0 ContextLevel level=1 scope=1 begin=2 end=37\n" |
| 278 " 1 CurrentCtx scope=0 begin=0 end=0" | 278 " 1 CurrentCtx scope=0 begin=0 end=0" |
| 279 " name=:current_context_var\n" | 279 " name=:current_context_var\n" |
| 280 " 2 SavedEntryCtx scope=0 begin=0 end=0" | 280 " 2 ContextVar level=1 begin=7 end=37 name=value\n" |
| 281 " name=:saved_entry_context_var\n" | 281 " 3 StackVar scope=2 begin=12 end=37 name=f\n", |
| 282 " 3 ContextVar level=1 begin=7 end=37 name=value\n" | |
| 283 " 4 StackVar scope=2 begin=12 end=37 name=f\n", | |
| 284 CaptureVarsAtLine(lib, "main", 4)); | 282 CaptureVarsAtLine(lib, "main", 4)); |
| 285 } | 283 } |
| 286 | 284 |
| 287 | 285 |
| 288 TEST_CASE(Parser_AllocateVariables_NestedCapturedVar) { | 286 TEST_CASE(Parser_AllocateVariables_NestedCapturedVar) { |
| 289 const char* kScriptChars = | 287 const char* kScriptChars = |
| 290 "int a() {\n" | 288 "int a() {\n" |
| 291 " int b() {\n" | 289 " int b() {\n" |
| 292 " var value = 11;\n" | 290 " var value = 11;\n" |
| 293 " int c() {\n" | 291 " int c() {\n" |
| (...skipping 19 matching lines...) Expand all Loading... |
| 313 " 1 CurrentCtx scope=0 begin=0 end=0" | 311 " 1 CurrentCtx scope=0 begin=0 end=0" |
| 314 " name=:current_context_var\n" | 312 " name=:current_context_var\n" |
| 315 | 313 |
| 316 // Middle function saves the entry context. Notice that this | 314 // Middle function saves the entry context. Notice that this |
| 317 // happens here and not in the outermost function. We always | 315 // happens here and not in the outermost function. We always |
| 318 // save the entry context at the last possible moment. | 316 // save the entry context at the last possible moment. |
| 319 "::.a_b\n" | 317 "::.a_b\n" |
| 320 " 0 ContextLevel level=1 scope=1 begin=8 end=38\n" | 318 " 0 ContextLevel level=1 scope=1 begin=8 end=38\n" |
| 321 " 1 CurrentCtx scope=0 begin=0 end=0" | 319 " 1 CurrentCtx scope=0 begin=0 end=0" |
| 322 " name=:current_context_var\n" | 320 " name=:current_context_var\n" |
| 323 " 2 SavedEntryCtx scope=0 begin=0 end=0" | 321 " 2 ContextVar level=1 begin=13 end=38 name=value\n" |
| 324 " name=:saved_entry_context_var\n" | 322 " 3 StackVar scope=2 begin=18 end=38 name=c\n" |
| 325 " 3 ContextVar level=1 begin=13 end=38 name=value\n" | |
| 326 " 4 StackVar scope=2 begin=18 end=38 name=c\n" | |
| 327 | 323 |
| 328 // Closure call saves current context. | 324 // Closure call saves current context. |
| 329 "(dynamic) => int.call\n" | 325 "(dynamic) => int.call\n" |
| 330 " 0 StackVar scope=1 begin=0 end=0 name=this\n" | 326 " 0 StackVar scope=1 begin=0 end=0 name=this\n" |
| 331 " 1 CurrentCtx scope=0 begin=0 end=0" | 327 " 1 CurrentCtx scope=0 begin=0 end=0" |
| 332 " name=:current_context_var\n" | 328 " name=:current_context_var\n" |
| 333 | 329 |
| 334 // Outermost function neglects to save the entry context. We | 330 // Outermost function neglects to save the entry context. We |
| 335 // don't save the entry context if the function has no captured | 331 // don't save the entry context if the function has no captured |
| 336 // variables. | 332 // variables. |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 374 " 1 CurrentCtx scope=0 begin=0 end=0" | 370 " 1 CurrentCtx scope=0 begin=0 end=0" |
| 375 " name=:current_context_var\n" | 371 " name=:current_context_var\n" |
| 376 | 372 |
| 377 // aa shares value2. Notice that we save the entry ctx instead | 373 // aa shares value2. Notice that we save the entry ctx instead |
| 378 // of chaining from b. This keeps us from holding onto closures | 374 // of chaining from b. This keeps us from holding onto closures |
| 379 // that we would never access. | 375 // that we would never access. |
| 380 "::.a_b_aa\n" | 376 "::.a_b_aa\n" |
| 381 " 0 ContextLevel level=1 scope=1 begin=20 end=50\n" | 377 " 0 ContextLevel level=1 scope=1 begin=20 end=50\n" |
| 382 " 1 CurrentCtx scope=0 begin=0 end=0" | 378 " 1 CurrentCtx scope=0 begin=0 end=0" |
| 383 " name=:current_context_var\n" | 379 " name=:current_context_var\n" |
| 384 " 2 SavedEntryCtx scope=0 begin=0 end=0" | 380 " 2 ContextVar level=1 begin=25 end=50 name=value2\n" |
| 385 " name=:saved_entry_context_var\n" | 381 " 3 StackVar scope=2 begin=30 end=50 name=bb\n" |
| 386 " 3 ContextVar level=1 begin=25 end=50 name=value2\n" | |
| 387 " 4 StackVar scope=2 begin=30 end=50 name=bb\n" | |
| 388 | 382 |
| 389 // Closure call saves current context. | 383 // Closure call saves current context. |
| 390 "(dynamic) => int.call\n" | 384 "(dynamic) => int.call\n" |
| 391 " 0 StackVar scope=1 begin=0 end=0 name=this\n" | 385 " 0 StackVar scope=1 begin=0 end=0 name=this\n" |
| 392 " 1 CurrentCtx scope=0 begin=0 end=0" | 386 " 1 CurrentCtx scope=0 begin=0 end=0" |
| 393 " name=:current_context_var\n" | 387 " name=:current_context_var\n" |
| 394 | 388 |
| 395 // b captures value1 from a. | 389 // b captures value1 from a. |
| 396 "::.a_b\n" | 390 "::.a_b\n" |
| 397 " 0 ContextVar level=0 begin=14 end=60 name=value1\n" | 391 " 0 ContextVar level=0 begin=14 end=60 name=value1\n" |
| 398 " 1 CurrentCtx scope=0 begin=0 end=0" | 392 " 1 CurrentCtx scope=0 begin=0 end=0" |
| 399 " name=:current_context_var\n" | 393 " name=:current_context_var\n" |
| 400 " 2 StackVar scope=2 begin=18 end=60 name=aa\n" | 394 " 2 StackVar scope=2 begin=18 end=60 name=aa\n" |
| 401 | 395 |
| 402 // Closure call saves current context. | 396 // Closure call saves current context. |
| 403 "(dynamic) => int.call\n" | 397 "(dynamic) => int.call\n" |
| 404 " 0 StackVar scope=1 begin=0 end=0 name=this\n" | 398 " 0 StackVar scope=1 begin=0 end=0 name=this\n" |
| 405 " 1 CurrentCtx scope=0 begin=0 end=0" | 399 " 1 CurrentCtx scope=0 begin=0 end=0" |
| 406 " name=:current_context_var\n" | 400 " name=:current_context_var\n" |
| 407 | 401 |
| 408 // a shares value1, saves entry ctx. | 402 // a shares value1, saves entry ctx. |
| 409 "::.a\n" | 403 "::.a\n" |
| 410 " 0 ContextLevel level=1 scope=1 begin=2 end=68\n" | 404 " 0 ContextLevel level=1 scope=1 begin=2 end=68\n" |
| 411 " 1 CurrentCtx scope=0 begin=0 end=0" | 405 " 1 CurrentCtx scope=0 begin=0 end=0" |
| 412 " name=:current_context_var\n" | 406 " name=:current_context_var\n" |
| 413 " 2 SavedEntryCtx scope=0 begin=0 end=0" | 407 " 2 ContextVar level=1 begin=7 end=68 name=value1\n" |
| 414 " name=:saved_entry_context_var\n" | 408 " 3 StackVar scope=2 begin=12 end=68 name=b\n", |
| 415 " 3 ContextVar level=1 begin=7 end=68 name=value1\n" | |
| 416 " 4 StackVar scope=2 begin=12 end=68 name=b\n", | |
| 417 CaptureVarsAtLine(lib, "a", 7)); | 409 CaptureVarsAtLine(lib, "a", 7)); |
| 418 } | 410 } |
| 419 | 411 |
| 420 | 412 |
| 421 TEST_CASE(Parser_AllocateVariables_Issue7681) { | 413 TEST_CASE(Parser_AllocateVariables_Issue7681) { |
| 422 // This is a distilled version of the program from Issue 7681. | 414 // This is a distilled version of the program from Issue 7681. |
| 423 // | 415 // |
| 424 // When we create the closure at line 11, we need to make sure to | 416 // When we create the closure at line 11, we need to make sure to |
| 425 // save the entry context instead of chaining to the parent context. | 417 // save the entry context instead of chaining to the parent context. |
| 426 // | 418 // |
| (...skipping 19 matching lines...) Expand all Loading... |
| 446 "}\n"; | 438 "}\n"; |
| 447 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); | 439 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); |
| 448 EXPECT_VALID(lib); | 440 EXPECT_VALID(lib); |
| 449 EXPECT_STREQ( | 441 EXPECT_STREQ( |
| 450 // This frame saves the entry context instead of chaining. Good. | 442 // This frame saves the entry context instead of chaining. Good. |
| 451 "::.doIt_<anonymous closure>\n" | 443 "::.doIt_<anonymous closure>\n" |
| 452 " 0 ContextLevel level=1 scope=1 begin=41 end=62\n" | 444 " 0 ContextLevel level=1 scope=1 begin=41 end=62\n" |
| 453 " 1 ContextVar level=1 begin=42 end=62 name=y\n" | 445 " 1 ContextVar level=1 begin=42 end=62 name=y\n" |
| 454 " 2 CurrentCtx scope=0 begin=0 end=0" | 446 " 2 CurrentCtx scope=0 begin=0 end=0" |
| 455 " name=:current_context_var\n" | 447 " name=:current_context_var\n" |
| 456 " 3 SavedEntryCtx scope=0 begin=0 end=0" | |
| 457 " name=:saved_entry_context_var\n" | |
| 458 | 448 |
| 459 // Closure call saves current context. | 449 // Closure call saves current context. |
| 460 "(dynamic, dynamic) => dynamic.call\n" | 450 "(dynamic, dynamic) => dynamic.call\n" |
| 461 " 0 StackVar scope=1 begin=0 end=0 name=this\n" | 451 " 0 StackVar scope=1 begin=0 end=0 name=this\n" |
| 462 " 1 CurrentCtx scope=0 begin=0 end=0" | 452 " 1 CurrentCtx scope=0 begin=0 end=0" |
| 463 " name=:current_context_var\n" | 453 " name=:current_context_var\n" |
| 464 | 454 |
| 465 "X.onX\n" | 455 "X.onX\n" |
| 466 " 0 StackVar scope=1 begin=0 end=0 name=this\n" | 456 " 0 StackVar scope=1 begin=0 end=0 name=this\n" |
| 467 " 1 CurrentCtx scope=0 begin=0 end=0" | 457 " 1 CurrentCtx scope=0 begin=0 end=0" |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 505 "(dynamic) => int.call\n" | 495 "(dynamic) => int.call\n" |
| 506 " 0 StackVar scope=1 begin=0 end=0 name=this\n" | 496 " 0 StackVar scope=1 begin=0 end=0 name=this\n" |
| 507 " 1 CurrentCtx scope=0 begin=0 end=0" | 497 " 1 CurrentCtx scope=0 begin=0 end=0" |
| 508 " name=:current_context_var\n" | 498 " name=:current_context_var\n" |
| 509 | 499 |
| 510 // The outer function saves the entry context, even though the | 500 // The outer function saves the entry context, even though the |
| 511 // captured variable is in a loop. Good. | 501 // captured variable is in a loop. Good. |
| 512 "::.outer\n" | 502 "::.outer\n" |
| 513 " 0 CurrentCtx scope=0 begin=0 end=0" | 503 " 0 CurrentCtx scope=0 begin=0 end=0" |
| 514 " name=:current_context_var\n" | 504 " name=:current_context_var\n" |
| 515 " 1 SavedEntryCtx scope=0 begin=0 end=0" | 505 " 1 StackVar scope=3 begin=9 end=50 name=i\n" |
| 516 " name=:saved_entry_context_var\n" | 506 " 2 ContextLevel level=1 scope=4 begin=20 end=50\n" |
| 517 " 2 StackVar scope=3 begin=9 end=50 name=i\n" | 507 " 3 ContextVar level=1 begin=23 end=50 name=value\n" |
| 518 " 3 ContextLevel level=1 scope=4 begin=20 end=50\n" | 508 " 4 StackVar scope=4 begin=30 end=50 name=inner\n", |
| 519 " 4 ContextVar level=1 begin=23 end=50 name=value\n" | |
| 520 " 5 StackVar scope=4 begin=30 end=50 name=inner\n", | |
| 521 CaptureVarsAtLine(lib, "outer", 5)); | 509 CaptureVarsAtLine(lib, "outer", 5)); |
| 522 } | 510 } |
| 523 | 511 |
| 524 TEST_CASE(Parser_AllocateVariables_MiddleChain) { | 512 TEST_CASE(Parser_AllocateVariables_MiddleChain) { |
| 525 const char* kScriptChars = | 513 const char* kScriptChars = |
| 526 "a() {\n" | 514 "a() {\n" |
| 527 " int x = 11;\n" | 515 " int x = 11;\n" |
| 528 " b() {\n" | 516 " b() {\n" |
| 529 " for (int i = 0; i < 1; i++) {\n" | 517 " for (int i = 0; i < 1; i++) {\n" |
| 530 " int d() {\n" | 518 " int d() {\n" |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 562 | 550 |
| 563 "(dynamic) => dynamic.call\n" | 551 "(dynamic) => dynamic.call\n" |
| 564 " 0 StackVar scope=1 begin=0 end=0 name=this\n" | 552 " 0 StackVar scope=1 begin=0 end=0 name=this\n" |
| 565 " 1 CurrentCtx scope=0 begin=0 end=0" | 553 " 1 CurrentCtx scope=0 begin=0 end=0" |
| 566 " name=:current_context_var\n" | 554 " name=:current_context_var\n" |
| 567 | 555 |
| 568 "::.a\n" | 556 "::.a\n" |
| 569 " 0 ContextLevel level=1 scope=1 begin=1 end=76\n" | 557 " 0 ContextLevel level=1 scope=1 begin=1 end=76\n" |
| 570 " 1 CurrentCtx scope=0 begin=0 end=0" | 558 " 1 CurrentCtx scope=0 begin=0 end=0" |
| 571 " name=:current_context_var\n" | 559 " name=:current_context_var\n" |
| 572 " 2 SavedEntryCtx scope=0 begin=0 end=0" | 560 " 2 ContextVar level=1 begin=6 end=76 name=x\n" |
| 573 " name=:saved_entry_context_var\n" | 561 " 3 StackVar scope=2 begin=11 end=76 name=b\n", |
| 574 " 3 ContextVar level=1 begin=6 end=76 name=x\n" | |
| 575 " 4 StackVar scope=2 begin=11 end=76 name=b\n", | |
| 576 CaptureVarsAtLine(lib, "a", 10)); | 562 CaptureVarsAtLine(lib, "a", 10)); |
| 577 } | 563 } |
| 578 | 564 |
| 579 } // namespace dart | 565 } // namespace dart |
| OLD | NEW |