Chromium Code Reviews| 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 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 208 Isolate::Current()->debugger()->StackTrace(); | 208 Isolate::Current()->debugger()->StackTrace(); |
| 209 intptr_t num_frames = stack->Length(); | 209 intptr_t num_frames = stack->Length(); |
| 210 const int kBufferLen = 2048; | 210 const int kBufferLen = 2048; |
| 211 char* buffer = new char[kBufferLen]; | 211 char* buffer = new char[kBufferLen]; |
| 212 char* pos = buffer; | 212 char* pos = buffer; |
| 213 LocalVarDescriptors& var_desc = LocalVarDescriptors::Handle(); | 213 LocalVarDescriptors& var_desc = LocalVarDescriptors::Handle(); |
| 214 for (intptr_t i = 0; i < num_frames; i++) { | 214 for (intptr_t i = 0; i < num_frames; i++) { |
| 215 ActivationFrame* frame = stack->FrameAt(i); | 215 ActivationFrame* frame = stack->FrameAt(i); |
| 216 var_desc = frame->code().var_descriptors(); | 216 var_desc = frame->code().var_descriptors(); |
| 217 const char* var_str = SkipIndex(var_desc.ToCString()); | 217 const char* var_str = SkipIndex(var_desc.ToCString()); |
| 218 const char* function_str = String::Handle( | |
| 219 frame->function().QualifiedUserVisibleName()).ToCString(); | |
| 218 pos += OS::SNPrint(pos, (kBufferLen - (pos - buffer)), | 220 pos += OS::SNPrint(pos, (kBufferLen - (pos - buffer)), |
| 219 "%s\n%s", | 221 "%s\n%s", |
| 220 frame->function().ToQualifiedCString(), | 222 function_str, |
| 221 var_str); | 223 var_str); |
| 222 delete [] var_str; | 224 delete [] var_str; |
| 223 } | 225 } |
| 224 pos[0] = '\0'; | 226 pos[0] = '\0'; |
| 225 saved_vars = buffer; | 227 saved_vars = buffer; |
| 226 } | 228 } |
| 227 | 229 |
| 228 | 230 |
| 229 // Uses the debugger to pause the program and capture the variable | 231 // Uses the debugger to pause the program and capture the variable |
| 230 // descriptors for all frames on the stack. | 232 // descriptors for all frames on the stack. |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 254 " var value = 11;\n" | 256 " var value = 11;\n" |
| 255 " int f(var param) {\n" | 257 " int f(var param) {\n" |
| 256 " return param + value;\n" // line 4 | 258 " return param + value;\n" // line 4 |
| 257 " }\n" | 259 " }\n" |
| 258 " return f(22);\n" | 260 " return f(22);\n" |
| 259 "}\n"; | 261 "}\n"; |
| 260 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); | 262 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); |
| 261 EXPECT_VALID(lib); | 263 EXPECT_VALID(lib); |
| 262 EXPECT_STREQ( | 264 EXPECT_STREQ( |
| 263 // function f uses one ctx var at (0); doesn't save ctx. | 265 // function f uses one ctx var at (0); doesn't save ctx. |
| 264 "::.main_f\n" | 266 "main.f\n" |
| 265 " 0 ContextVar level=0 begin=14 end=28 name=value\n" | 267 " 0 ContextVar level=0 begin=14 end=28 name=value\n" |
| 266 " 1 StackVar scope=1 begin=16 end=28 name=param\n" | 268 " 1 StackVar scope=1 begin=16 end=28 name=param\n" |
| 267 " 2 CurrentCtx scope=0 begin=0 end=0" | 269 " 2 CurrentCtx scope=0 begin=0 end=0" |
| 268 " name=:current_context_var\n" | 270 " name=:current_context_var\n" |
| 269 | 271 |
| 270 // Closure call saves current context. | 272 // Closure call saves current context. |
| 271 "(dynamic, dynamic) => int.call\n" | 273 "_FunctionImpl.call\n" |
| 272 " 0 StackVar scope=1 begin=0 end=0 name=this\n" | 274 " 0 StackVar scope=1 begin=0 end=4 name=this\n" |
|
Florian Schneider
2015/01/29 17:27:21
This change is because _FunctionImpl is now the ow
| |
| 273 " 1 CurrentCtx scope=0 begin=0 end=0" | 275 " 1 CurrentCtx scope=0 begin=0 end=0" |
| 274 " name=:current_context_var\n" | 276 " name=:current_context_var\n" |
| 275 | 277 |
| 276 // function main uses one ctx var at (1); saves caller ctx. | 278 // function main uses one ctx var at (1); saves caller ctx. |
| 277 "::.main\n" | 279 "main\n" |
| 278 " 0 ContextLevel level=1 scope=1 begin=2 end=37\n" | 280 " 0 ContextLevel level=1 scope=1 begin=2 end=37\n" |
| 279 " 1 CurrentCtx scope=0 begin=0 end=0" | 281 " 1 CurrentCtx scope=0 begin=0 end=0" |
| 280 " name=:current_context_var\n" | 282 " name=:current_context_var\n" |
| 281 " 2 ContextVar level=1 begin=7 end=37 name=value\n" | 283 " 2 ContextVar level=1 begin=7 end=37 name=value\n" |
| 282 " 3 StackVar scope=2 begin=12 end=37 name=f\n", | 284 " 3 StackVar scope=2 begin=12 end=37 name=f\n", |
| 283 CaptureVarsAtLine(lib, "main", 4)); | 285 CaptureVarsAtLine(lib, "main", 4)); |
| 284 } | 286 } |
| 285 | 287 |
| 286 | 288 |
| 287 TEST_CASE(Parser_AllocateVariables_NestedCapturedVar) { | 289 TEST_CASE(Parser_AllocateVariables_NestedCapturedVar) { |
| 288 const char* kScriptChars = | 290 const char* kScriptChars = |
| 289 "int a() {\n" | 291 "int a() {\n" |
| 290 " int b() {\n" | 292 " int b() {\n" |
| 291 " var value = 11;\n" | 293 " var value = 11;\n" |
| 292 " int c() {\n" | 294 " int c() {\n" |
| 293 " return value;\n" // line 5 | 295 " return value;\n" // line 5 |
| 294 " }\n" | 296 " }\n" |
| 295 " return c();\n" | 297 " return c();\n" |
| 296 " }\n" | 298 " }\n" |
| 297 " return b();\n" | 299 " return b();\n" |
| 298 "}\n"; | 300 "}\n"; |
| 299 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); | 301 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); |
| 300 EXPECT_VALID(lib); | 302 EXPECT_VALID(lib); |
| 301 EXPECT_STREQ( | 303 EXPECT_STREQ( |
| 302 // Innermost function uses captured variable 'value' from middle | 304 // Innermost function uses captured variable 'value' from middle |
| 303 // function. | 305 // function. |
| 304 "::.a_b_c\n" | 306 "a.b.c\n" |
| 305 " 0 ContextVar level=0 begin=20 end=30 name=value\n" | 307 " 0 ContextVar level=0 begin=20 end=30 name=value\n" |
| 306 " 1 CurrentCtx scope=0 begin=0 end=0" | 308 " 1 CurrentCtx scope=0 begin=0 end=0" |
| 307 " name=:current_context_var\n" | 309 " name=:current_context_var\n" |
| 308 | 310 |
| 309 // Closure call saves current context. | 311 // Closure call saves current context. |
| 310 "(dynamic) => int.call\n" | 312 "_FunctionImpl.call\n" |
| 311 " 0 StackVar scope=1 begin=0 end=0 name=this\n" | 313 " 0 StackVar scope=1 begin=0 end=4 name=this\n" |
| 312 " 1 CurrentCtx scope=0 begin=0 end=0" | 314 " 1 CurrentCtx scope=0 begin=0 end=0" |
| 313 " name=:current_context_var\n" | 315 " name=:current_context_var\n" |
| 314 | 316 |
| 315 // Middle function saves the entry context. Notice that this | 317 // Middle function saves the entry context. Notice that this |
| 316 // happens here and not in the outermost function. We always | 318 // happens here and not in the outermost function. We always |
| 317 // save the entry context at the last possible moment. | 319 // save the entry context at the last possible moment. |
| 318 "::.a_b\n" | 320 "a.b\n" |
| 319 " 0 ContextLevel level=1 scope=1 begin=8 end=38\n" | 321 " 0 ContextLevel level=1 scope=1 begin=8 end=38\n" |
| 320 " 1 CurrentCtx scope=0 begin=0 end=0" | 322 " 1 CurrentCtx scope=0 begin=0 end=0" |
| 321 " name=:current_context_var\n" | 323 " name=:current_context_var\n" |
| 322 " 2 ContextVar level=1 begin=13 end=38 name=value\n" | 324 " 2 ContextVar level=1 begin=13 end=38 name=value\n" |
| 323 " 3 StackVar scope=2 begin=18 end=38 name=c\n" | 325 " 3 StackVar scope=2 begin=18 end=38 name=c\n" |
| 324 | 326 |
| 325 // Closure call saves current context. | 327 // Closure call saves current context. |
| 326 "(dynamic) => int.call\n" | 328 "_FunctionImpl.call\n" |
| 327 " 0 StackVar scope=1 begin=0 end=0 name=this\n" | 329 " 0 StackVar scope=1 begin=0 end=4 name=this\n" |
| 328 " 1 CurrentCtx scope=0 begin=0 end=0" | 330 " 1 CurrentCtx scope=0 begin=0 end=0" |
| 329 " name=:current_context_var\n" | 331 " name=:current_context_var\n" |
| 330 | 332 |
| 331 // Outermost function neglects to save the entry context. We | 333 // Outermost function neglects to save the entry context. We |
| 332 // don't save the entry context if the function has no captured | 334 // don't save the entry context if the function has no captured |
| 333 // variables. | 335 // variables. |
| 334 "::.a\n" | 336 "a\n" |
| 335 " 0 CurrentCtx scope=0 begin=0 end=0" | 337 " 0 CurrentCtx scope=0 begin=0 end=0" |
| 336 " name=:current_context_var\n" | 338 " name=:current_context_var\n" |
| 337 " 1 StackVar scope=2 begin=6 end=46 name=b\n", | 339 " 1 StackVar scope=2 begin=6 end=46 name=b\n", |
| 338 CaptureVarsAtLine(lib, "a", 5)); | 340 CaptureVarsAtLine(lib, "a", 5)); |
| 339 } | 341 } |
| 340 | 342 |
| 341 | 343 |
| 342 TEST_CASE(Parser_AllocateVariables_TwoChains) { | 344 TEST_CASE(Parser_AllocateVariables_TwoChains) { |
| 343 const char* kScriptChars = | 345 const char* kScriptChars = |
| 344 "int a() {\n" | 346 "int a() {\n" |
| 345 " var value1 = 11;\n" | 347 " var value1 = 11;\n" |
| 346 " int b() {\n" | 348 " int b() {\n" |
| 347 " int aa() {\n" | 349 " int aa() {\n" |
| 348 " var value2 = 12;\n" | 350 " var value2 = 12;\n" |
| 349 " int bb() {\n" | 351 " int bb() {\n" |
| 350 " return value2;\n" // line 7 | 352 " return value2;\n" // line 7 |
| 351 " }\n" | 353 " }\n" |
| 352 " return bb();\n" | 354 " return bb();\n" |
| 353 " }\n" | 355 " }\n" |
| 354 " return value1 + aa();\n" | 356 " return value1 + aa();\n" |
| 355 " }\n" | 357 " }\n" |
| 356 " return b();\n" | 358 " return b();\n" |
| 357 "}\n"; | 359 "}\n"; |
| 358 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); | 360 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); |
| 359 EXPECT_VALID(lib); | 361 EXPECT_VALID(lib); |
| 360 | 362 |
| 361 EXPECT_STREQ( | 363 EXPECT_STREQ( |
| 362 // bb captures only value2 from aa. No others. | 364 // bb captures only value2 from aa. No others. |
| 363 "::.a_b_aa_bb\n" | 365 "a.b.aa.bb\n" |
| 364 " 0 ContextVar level=0 begin=32 end=42 name=value2\n" | 366 " 0 ContextVar level=0 begin=32 end=42 name=value2\n" |
| 365 " 1 CurrentCtx scope=0 begin=0 end=0" | 367 " 1 CurrentCtx scope=0 begin=0 end=0" |
| 366 " name=:current_context_var\n" | 368 " name=:current_context_var\n" |
| 367 | 369 |
| 368 // Closure call saves current context. | 370 // Closure call saves current context. |
| 369 "(dynamic) => int.call\n" | 371 "_FunctionImpl.call\n" |
| 370 " 0 StackVar scope=1 begin=0 end=0 name=this\n" | 372 " 0 StackVar scope=1 begin=0 end=4 name=this\n" |
| 371 " 1 CurrentCtx scope=0 begin=0 end=0" | 373 " 1 CurrentCtx scope=0 begin=0 end=0" |
| 372 " name=:current_context_var\n" | 374 " name=:current_context_var\n" |
| 373 | 375 |
| 374 // aa shares value2. Notice that we save the entry ctx instead | 376 // aa shares value2. Notice that we save the entry ctx instead |
| 375 // of chaining from b. This keeps us from holding onto closures | 377 // of chaining from b. This keeps us from holding onto closures |
| 376 // that we would never access. | 378 // that we would never access. |
| 377 "::.a_b_aa\n" | 379 "a.b.aa\n" |
| 378 " 0 ContextLevel level=1 scope=1 begin=20 end=50\n" | 380 " 0 ContextLevel level=1 scope=1 begin=20 end=50\n" |
| 379 " 1 CurrentCtx scope=0 begin=0 end=0" | 381 " 1 CurrentCtx scope=0 begin=0 end=0" |
| 380 " name=:current_context_var\n" | 382 " name=:current_context_var\n" |
| 381 " 2 ContextVar level=1 begin=25 end=50 name=value2\n" | 383 " 2 ContextVar level=1 begin=25 end=50 name=value2\n" |
| 382 " 3 StackVar scope=2 begin=30 end=50 name=bb\n" | 384 " 3 StackVar scope=2 begin=30 end=50 name=bb\n" |
| 383 | 385 |
| 384 // Closure call saves current context. | 386 // Closure call saves current context. |
| 385 "(dynamic) => int.call\n" | 387 "_FunctionImpl.call\n" |
| 386 " 0 StackVar scope=1 begin=0 end=0 name=this\n" | 388 " 0 StackVar scope=1 begin=0 end=4 name=this\n" |
| 387 " 1 CurrentCtx scope=0 begin=0 end=0" | 389 " 1 CurrentCtx scope=0 begin=0 end=0" |
| 388 " name=:current_context_var\n" | 390 " name=:current_context_var\n" |
| 389 | 391 |
| 390 // b captures value1 from a. | 392 // b captures value1 from a. |
| 391 "::.a_b\n" | 393 "a.b\n" |
| 392 " 0 ContextVar level=0 begin=14 end=60 name=value1\n" | 394 " 0 ContextVar level=0 begin=14 end=60 name=value1\n" |
| 393 " 1 CurrentCtx scope=0 begin=0 end=0" | 395 " 1 CurrentCtx scope=0 begin=0 end=0" |
| 394 " name=:current_context_var\n" | 396 " name=:current_context_var\n" |
| 395 " 2 StackVar scope=2 begin=18 end=60 name=aa\n" | 397 " 2 StackVar scope=2 begin=18 end=60 name=aa\n" |
| 396 | 398 |
| 397 // Closure call saves current context. | 399 // Closure call saves current context. |
| 398 "(dynamic) => int.call\n" | 400 "_FunctionImpl.call\n" |
| 399 " 0 StackVar scope=1 begin=0 end=0 name=this\n" | 401 " 0 StackVar scope=1 begin=0 end=4 name=this\n" |
| 400 " 1 CurrentCtx scope=0 begin=0 end=0" | 402 " 1 CurrentCtx scope=0 begin=0 end=0" |
| 401 " name=:current_context_var\n" | 403 " name=:current_context_var\n" |
| 402 | 404 |
| 403 // a shares value1, saves entry ctx. | 405 // a shares value1, saves entry ctx. |
| 404 "::.a\n" | 406 "a\n" |
| 405 " 0 ContextLevel level=1 scope=1 begin=2 end=68\n" | 407 " 0 ContextLevel level=1 scope=1 begin=2 end=68\n" |
| 406 " 1 CurrentCtx scope=0 begin=0 end=0" | 408 " 1 CurrentCtx scope=0 begin=0 end=0" |
| 407 " name=:current_context_var\n" | 409 " name=:current_context_var\n" |
| 408 " 2 ContextVar level=1 begin=7 end=68 name=value1\n" | 410 " 2 ContextVar level=1 begin=7 end=68 name=value1\n" |
| 409 " 3 StackVar scope=2 begin=12 end=68 name=b\n", | 411 " 3 StackVar scope=2 begin=12 end=68 name=b\n", |
| 410 CaptureVarsAtLine(lib, "a", 7)); | 412 CaptureVarsAtLine(lib, "a", 7)); |
| 411 } | 413 } |
| 412 | 414 |
| 413 | 415 |
| 414 TEST_CASE(Parser_AllocateVariables_Issue7681) { | 416 TEST_CASE(Parser_AllocateVariables_Issue7681) { |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 434 " y.onY = () {\n" // line 12 | 436 " y.onY = () {\n" // line 12 |
| 435 " return y;\n" | 437 " return y;\n" |
| 436 " };\n" | 438 " };\n" |
| 437 " };\n" | 439 " };\n" |
| 438 " x.onX(new Y());\n" | 440 " x.onX(new Y());\n" |
| 439 "}\n"; | 441 "}\n"; |
| 440 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); | 442 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); |
| 441 EXPECT_VALID(lib); | 443 EXPECT_VALID(lib); |
| 442 EXPECT_STREQ( | 444 EXPECT_STREQ( |
| 443 // This frame saves the entry context instead of chaining. Good. | 445 // This frame saves the entry context instead of chaining. Good. |
| 444 "::.doIt_<anonymous closure>\n" | 446 "doIt.<anonymous closure>\n" |
| 445 " 0 ContextLevel level=1 scope=1 begin=41 end=62\n" | 447 " 0 ContextLevel level=1 scope=1 begin=41 end=62\n" |
| 446 " 1 ContextVar level=1 begin=42 end=62 name=y\n" | 448 " 1 ContextVar level=1 begin=42 end=62 name=y\n" |
| 447 " 2 CurrentCtx scope=0 begin=0 end=0" | 449 " 2 CurrentCtx scope=0 begin=0 end=0" |
| 448 " name=:current_context_var\n" | 450 " name=:current_context_var\n" |
| 449 | 451 |
| 450 // Closure call saves current context. | 452 // Closure call saves current context. |
| 451 "(dynamic, dynamic) => dynamic.call\n" | 453 "_FunctionImpl.call\n" |
| 452 " 0 StackVar scope=1 begin=0 end=0 name=this\n" | 454 " 0 StackVar scope=1 begin=0 end=4 name=this\n" |
| 453 " 1 CurrentCtx scope=0 begin=0 end=0" | 455 " 1 CurrentCtx scope=0 begin=0 end=0" |
| 454 " name=:current_context_var\n" | 456 " name=:current_context_var\n" |
| 455 | 457 |
| 456 "X.onX\n" | 458 "X.onX\n" |
| 457 " 0 StackVar scope=1 begin=0 end=0 name=this\n" | 459 " 0 StackVar scope=1 begin=0 end=0 name=this\n" |
| 458 " 1 CurrentCtx scope=0 begin=0 end=0" | 460 " 1 CurrentCtx scope=0 begin=0 end=0" |
| 459 " name=:current_context_var\n" | 461 " name=:current_context_var\n" |
| 460 | 462 |
| 461 // No context is saved here since no vars are captured. | 463 // No context is saved here since no vars are captured. |
| 462 "::.doIt\n" | 464 "doIt\n" |
| 463 " 0 CurrentCtx scope=0 begin=0 end=0" | 465 " 0 CurrentCtx scope=0 begin=0 end=0" |
| 464 " name=:current_context_var\n" | 466 " name=:current_context_var\n" |
| 465 " 1 StackVar scope=2 begin=29 end=77 name=x\n", | 467 " 1 StackVar scope=2 begin=29 end=77 name=x\n", |
| 466 CaptureVarsAtLine(lib, "doIt", 12)); | 468 CaptureVarsAtLine(lib, "doIt", 12)); |
| 467 } | 469 } |
| 468 | 470 |
| 469 | 471 |
| 470 TEST_CASE(Parser_AllocateVariables_CaptureLoopVar) { | 472 TEST_CASE(Parser_AllocateVariables_CaptureLoopVar) { |
| 471 // This test verifies that... | 473 // This test verifies that... |
| 472 // | 474 // |
| 473 // https://code.google.com/p/dart/issues/detail?id=18561 | 475 // https://code.google.com/p/dart/issues/detail?id=18561 |
| 474 // | 476 // |
| 475 // ...stays fixed. | 477 // ...stays fixed. |
| 476 const char* kScriptChars = | 478 const char* kScriptChars = |
| 477 "int outer() {\n" | 479 "int outer() {\n" |
| 478 " for(int i = 0; i < 1; i++) {\n" | 480 " for(int i = 0; i < 1; i++) {\n" |
| 479 " var value = 11 + i;\n" | 481 " var value = 11 + i;\n" |
| 480 " int inner() {\n" | 482 " int inner() {\n" |
| 481 " return value;\n" // line 5 | 483 " return value;\n" // line 5 |
| 482 " }\n" | 484 " }\n" |
| 483 " return inner();\n" | 485 " return inner();\n" |
| 484 " }\n" | 486 " }\n" |
| 485 "}\n"; | 487 "}\n"; |
| 486 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); | 488 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); |
| 487 EXPECT_VALID(lib); | 489 EXPECT_VALID(lib); |
| 488 EXPECT_STREQ( | 490 EXPECT_STREQ( |
| 489 // inner function captures variable value. That's fine. | 491 // inner function captures variable value. That's fine. |
| 490 "::.outer_inner\n" | 492 "outer.inner\n" |
| 491 " 0 ContextVar level=0 begin=32 end=42 name=value\n" | 493 " 0 ContextVar level=0 begin=32 end=42 name=value\n" |
| 492 " 1 CurrentCtx scope=0 begin=0 end=0" | 494 " 1 CurrentCtx scope=0 begin=0 end=0" |
| 493 " name=:current_context_var\n" | 495 " name=:current_context_var\n" |
| 494 | 496 |
| 495 // Closure call saves current context. | 497 // Closure call saves current context. |
| 496 "(dynamic) => int.call\n" | 498 "_FunctionImpl.call\n" |
| 497 " 0 StackVar scope=1 begin=0 end=0 name=this\n" | 499 " 0 StackVar scope=1 begin=0 end=4 name=this\n" |
| 498 " 1 CurrentCtx scope=0 begin=0 end=0" | 500 " 1 CurrentCtx scope=0 begin=0 end=0" |
| 499 " name=:current_context_var\n" | 501 " name=:current_context_var\n" |
| 500 | 502 |
| 501 // The outer function saves the entry context, even though the | 503 // The outer function saves the entry context, even though the |
| 502 // captured variable is in a loop. Good. | 504 // captured variable is in a loop. Good. |
| 503 "::.outer\n" | 505 "outer\n" |
| 504 " 0 CurrentCtx scope=0 begin=0 end=0" | 506 " 0 CurrentCtx scope=0 begin=0 end=0" |
| 505 " name=:current_context_var\n" | 507 " name=:current_context_var\n" |
| 506 " 1 StackVar scope=3 begin=9 end=50 name=i\n" | 508 " 1 StackVar scope=3 begin=9 end=50 name=i\n" |
| 507 " 2 ContextLevel level=1 scope=4 begin=20 end=50\n" | 509 " 2 ContextLevel level=1 scope=4 begin=20 end=50\n" |
| 508 " 3 ContextVar level=1 begin=23 end=50 name=value\n" | 510 " 3 ContextVar level=1 begin=23 end=50 name=value\n" |
| 509 " 4 StackVar scope=4 begin=30 end=50 name=inner\n", | 511 " 4 StackVar scope=4 begin=30 end=50 name=inner\n", |
| 510 CaptureVarsAtLine(lib, "outer", 5)); | 512 CaptureVarsAtLine(lib, "outer", 5)); |
| 511 } | 513 } |
| 512 | 514 |
| 513 TEST_CASE(Parser_AllocateVariables_MiddleChain) { | 515 TEST_CASE(Parser_AllocateVariables_MiddleChain) { |
| 514 const char* kScriptChars = | 516 const char* kScriptChars = |
| 515 "a() {\n" | 517 "a() {\n" |
| 516 " int x = 11;\n" | 518 " int x = 11;\n" |
| 517 " b() {\n" | 519 " b() {\n" |
| 518 " for (int i = 0; i < 1; i++) {\n" | 520 " for (int i = 0; i < 1; i++) {\n" |
| 519 " int d() {\n" | 521 " int d() {\n" |
| 520 " return i;\n" | 522 " return i;\n" |
| 521 " }\n" | 523 " }\n" |
| 522 " }\n" | 524 " }\n" |
| 523 " int c() {\n" | 525 " int c() {\n" |
| 524 " return x + 1;\n" // line 10 | 526 " return x + 1;\n" // line 10 |
| 525 " }\n" | 527 " }\n" |
| 526 " return c();\n" | 528 " return c();\n" |
| 527 " }\n" | 529 " }\n" |
| 528 " return b();\n" | 530 " return b();\n" |
| 529 "}\n"; | 531 "}\n"; |
| 530 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); | 532 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); |
| 531 EXPECT_VALID(lib); | 533 EXPECT_VALID(lib); |
| 532 EXPECT_STREQ( | 534 EXPECT_STREQ( |
| 533 "::.a_b_c\n" | 535 "a.b.c\n" |
| 534 " 0 ContextVar level=0 begin=48 end=60 name=x\n" | 536 " 0 ContextVar level=0 begin=48 end=60 name=x\n" |
| 535 " 1 CurrentCtx scope=0 begin=0 end=0" | 537 " 1 CurrentCtx scope=0 begin=0 end=0" |
| 536 " name=:current_context_var\n" | 538 " name=:current_context_var\n" |
| 537 "(dynamic) => int.call\n" | 539 "_FunctionImpl.call\n" |
| 538 " 0 StackVar scope=1 begin=0 end=0 name=this\n" | 540 " 0 StackVar scope=1 begin=0 end=4 name=this\n" |
| 539 " 1 CurrentCtx scope=0 begin=0 end=0" | 541 " 1 CurrentCtx scope=0 begin=0 end=0" |
| 540 " name=:current_context_var\n" | 542 " name=:current_context_var\n" |
| 541 | 543 |
| 542 // Doesn't save the entry context. Chains to parent instead. | 544 // Doesn't save the entry context. Chains to parent instead. |
| 543 "::.a_b\n" | 545 "a.b\n" |
| 544 " 0 ContextVar level=0 begin=12 end=68 name=x\n" | 546 " 0 ContextVar level=0 begin=12 end=68 name=x\n" |
| 545 " 1 CurrentCtx scope=0 begin=0 end=0" | 547 " 1 CurrentCtx scope=0 begin=0 end=0" |
| 546 " name=:current_context_var\n" | 548 " name=:current_context_var\n" |
| 547 " 2 StackVar scope=2 begin=46 end=68 name=c\n" | 549 " 2 StackVar scope=2 begin=46 end=68 name=c\n" |
| 548 " 3 ContextLevel level=1 scope=3 begin=18 end=46\n" | 550 " 3 ContextLevel level=1 scope=3 begin=18 end=46\n" |
| 549 " 4 ContextVar level=1 begin=19 end=46 name=i\n" | 551 " 4 ContextVar level=1 begin=19 end=46 name=i\n" |
| 550 " 5 StackVar scope=4 begin=32 end=46 name=d\n" | 552 " 5 StackVar scope=4 begin=32 end=46 name=d\n" |
| 551 | 553 |
| 552 "(dynamic) => dynamic.call\n" | 554 "_FunctionImpl.call\n" |
| 553 " 0 StackVar scope=1 begin=0 end=0 name=this\n" | 555 " 0 StackVar scope=1 begin=0 end=4 name=this\n" |
| 554 " 1 CurrentCtx scope=0 begin=0 end=0" | 556 " 1 CurrentCtx scope=0 begin=0 end=0" |
| 555 " name=:current_context_var\n" | 557 " name=:current_context_var\n" |
| 556 | 558 |
| 557 "::.a\n" | 559 "a\n" |
| 558 " 0 ContextLevel level=1 scope=1 begin=1 end=76\n" | 560 " 0 ContextLevel level=1 scope=1 begin=1 end=76\n" |
| 559 " 1 CurrentCtx scope=0 begin=0 end=0" | 561 " 1 CurrentCtx scope=0 begin=0 end=0" |
| 560 " name=:current_context_var\n" | 562 " name=:current_context_var\n" |
| 561 " 2 ContextVar level=1 begin=6 end=76 name=x\n" | 563 " 2 ContextVar level=1 begin=6 end=76 name=x\n" |
| 562 " 3 StackVar scope=2 begin=11 end=76 name=b\n", | 564 " 3 StackVar scope=2 begin=11 end=76 name=b\n", |
| 563 CaptureVarsAtLine(lib, "a", 10)); | 565 CaptureVarsAtLine(lib, "a", 10)); |
| 564 } | 566 } |
| 565 | 567 |
| 566 } // namespace dart | 568 } // namespace dart |
| OLD | NEW |