| OLD | NEW |
| (Empty) |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | |
| 2 // Redistribution and use in source and binary forms, with or without | |
| 3 // modification, are permitted provided that the following conditions are | |
| 4 // met: | |
| 5 // | |
| 6 // * Redistributions of source code must retain the above copyright | |
| 7 // notice, this list of conditions and the following disclaimer. | |
| 8 // * Redistributions in binary form must reproduce the above | |
| 9 // copyright notice, this list of conditions and the following | |
| 10 // disclaimer in the documentation and/or other materials provided | |
| 11 // with the distribution. | |
| 12 // * Neither the name of Google Inc. nor the names of its | |
| 13 // contributors may be used to endorse or promote products derived | |
| 14 // from this software without specific prior written permission. | |
| 15 // | |
| 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
| 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
| 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
| 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
| 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
| 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
| 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
| 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
| 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 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. | |
| 27 | |
| 28 // Flags: --expose-debug-as debug --allow-natives-syntax --noanalyze-environment
-liveness | |
| 29 // The functions used for testing backtraces. They are at the top to make the | |
| 30 // testing of source line/column easier. | |
| 31 | |
| 32 // Get the Debug object exposed from the debug context global object. | |
| 33 var Debug = debug.Debug; | |
| 34 | |
| 35 var test_name; | |
| 36 var listener_delegate; | |
| 37 var listener_called; | |
| 38 var exception; | |
| 39 var begin_test_count = 0; | |
| 40 var end_test_count = 0; | |
| 41 var break_count = 0; | |
| 42 | |
| 43 | |
| 44 // Debug event listener which delegates. | |
| 45 function listener(event, exec_state, event_data, data) { | |
| 46 try { | |
| 47 if (event == Debug.DebugEvent.Break) { | |
| 48 break_count++; | |
| 49 listener_called = true; | |
| 50 listener_delegate(exec_state); | |
| 51 } | |
| 52 } catch (e) { | |
| 53 exception = e; | |
| 54 } | |
| 55 } | |
| 56 | |
| 57 // Add the debug event listener. | |
| 58 Debug.setListener(listener); | |
| 59 | |
| 60 | |
| 61 // Initialize for a new test. | |
| 62 function BeginTest(name) { | |
| 63 test_name = name; | |
| 64 listener_delegate = null; | |
| 65 listener_called = false; | |
| 66 exception = null; | |
| 67 begin_test_count++; | |
| 68 } | |
| 69 | |
| 70 | |
| 71 // Check result of a test. | |
| 72 function EndTest() { | |
| 73 assertTrue(listener_called, "listerner not called for " + test_name); | |
| 74 assertNull(exception, test_name + " / " + exception); | |
| 75 end_test_count++; | |
| 76 } | |
| 77 | |
| 78 | |
| 79 // Check that two scope are the same. | |
| 80 function assertScopeMirrorEquals(scope1, scope2) { | |
| 81 assertEquals(scope1.scopeType(), scope2.scopeType()); | |
| 82 assertEquals(scope1.frameIndex(), scope2.frameIndex()); | |
| 83 assertEquals(scope1.scopeIndex(), scope2.scopeIndex()); | |
| 84 assertPropertiesEqual(scope1.scopeObject().value(), scope2.scopeObject().value
()); | |
| 85 } | |
| 86 | |
| 87 function CheckFastAllScopes(scopes, exec_state) | |
| 88 { | |
| 89 var fast_all_scopes = exec_state.frame().allScopes(true); | |
| 90 var length = fast_all_scopes.length; | |
| 91 assertTrue(scopes.length >= length); | |
| 92 for (var i = 0; i < scopes.length && i < length; i++) { | |
| 93 var scope = fast_all_scopes[length - i - 1]; | |
| 94 assertTrue(scope.isScope()); | |
| 95 assertEquals(scopes[scopes.length - i - 1], scope.scopeType()); | |
| 96 } | |
| 97 } | |
| 98 | |
| 99 | |
| 100 // Check that the scope chain contains the expected types of scopes. | |
| 101 function CheckScopeChain(scopes, exec_state) { | |
| 102 var all_scopes = exec_state.frame().allScopes(); | |
| 103 assertEquals(scopes.length, exec_state.frame().scopeCount()); | |
| 104 assertEquals(scopes.length, all_scopes.length, "FrameMirror.allScopes length")
; | |
| 105 for (var i = 0; i < scopes.length; i++) { | |
| 106 var scope = exec_state.frame().scope(i); | |
| 107 assertTrue(scope.isScope()); | |
| 108 assertEquals(scopes[i], scope.scopeType()); | |
| 109 assertScopeMirrorEquals(all_scopes[i], scope); | |
| 110 | |
| 111 // Check the global object when hitting the global scope. | |
| 112 if (scopes[i] == debug.ScopeType.Global) { | |
| 113 // Objects don't have same class (one is "global", other is "Object", | |
| 114 // so just check the properties directly. | |
| 115 assertPropertiesEqual(this, scope.scopeObject().value()); | |
| 116 } | |
| 117 } | |
| 118 CheckFastAllScopes(scopes, exec_state); | |
| 119 } | |
| 120 | |
| 121 | |
| 122 // Check that the scope chain contains the expected names of scopes. | |
| 123 function CheckScopeChainNames(names, exec_state) { | |
| 124 var all_scopes = exec_state.frame().allScopes(); | |
| 125 assertEquals(names.length, all_scopes.length, "FrameMirror.allScopes length"); | |
| 126 for (var i = 0; i < names.length; i++) { | |
| 127 var scope = exec_state.frame().scope(i); | |
| 128 assertTrue(scope.isScope()); | |
| 129 assertEquals(names[i], scope.details().name()) | |
| 130 } | |
| 131 } | |
| 132 | |
| 133 | |
| 134 // Check that the scope contains at least minimum_content. For functions just | |
| 135 // check that there is a function. | |
| 136 function CheckScopeContent(minimum_content, number, exec_state) { | |
| 137 var scope = exec_state.frame().scope(number); | |
| 138 var minimum_count = 0; | |
| 139 for (var p in minimum_content) { | |
| 140 var property_mirror = scope.scopeObject().property(p); | |
| 141 assertFalse(property_mirror.isUndefined(), | |
| 142 'property ' + p + ' not found in scope'); | |
| 143 if (typeof(minimum_content[p]) === 'function') { | |
| 144 assertTrue(property_mirror.value().isFunction()); | |
| 145 } else { | |
| 146 assertEquals(minimum_content[p], property_mirror.value().value(), | |
| 147 'property ' + p + ' has unexpected value'); | |
| 148 } | |
| 149 minimum_count++; | |
| 150 } | |
| 151 | |
| 152 // 'arguments' and might be exposed in the local and closure scope. Just | |
| 153 // ignore this. | |
| 154 var scope_size = scope.scopeObject().properties().length; | |
| 155 if (!scope.scopeObject().property('arguments').isUndefined()) { | |
| 156 scope_size--; | |
| 157 } | |
| 158 // Ditto for 'this'. | |
| 159 if (!scope.scopeObject().property('this').isUndefined()) { | |
| 160 scope_size--; | |
| 161 } | |
| 162 // Temporary variables introduced by the parser have not been materialized. | |
| 163 assertTrue(scope.scopeObject().property('').isUndefined()); | |
| 164 | |
| 165 if (scope_size < minimum_count) { | |
| 166 print('Names found in scope:'); | |
| 167 var names = scope.scopeObject().propertyNames(); | |
| 168 for (var i = 0; i < names.length; i++) { | |
| 169 print(names[i]); | |
| 170 } | |
| 171 } | |
| 172 assertTrue(scope_size >= minimum_count); | |
| 173 } | |
| 174 | |
| 175 // Check that the scopes have positions as expected. | |
| 176 function CheckScopeChainPositions(positions, exec_state) { | |
| 177 var all_scopes = exec_state.frame().allScopes(); | |
| 178 assertEquals(positions.length, all_scopes.length, "FrameMirror.allScopes lengt
h"); | |
| 179 for (var i = 0; i < positions.length; i++) { | |
| 180 var scope = exec_state.frame().scope(i); | |
| 181 assertTrue(scope.isScope()); | |
| 182 var position = positions[i]; | |
| 183 if (!position) | |
| 184 continue; | |
| 185 | |
| 186 assertEquals(position.start, scope.details().startPosition()) | |
| 187 assertEquals(position.end, scope.details().endPosition()) | |
| 188 } | |
| 189 } | |
| 190 | |
| 191 // Simple empty local scope. | |
| 192 BeginTest("Local 1"); | |
| 193 | |
| 194 function local_1() { | |
| 195 debugger; | |
| 196 } | |
| 197 | |
| 198 listener_delegate = function(exec_state) { | |
| 199 CheckScopeChain([debug.ScopeType.Local, | |
| 200 debug.ScopeType.Script, | |
| 201 debug.ScopeType.Global], exec_state); | |
| 202 CheckScopeContent({}, 0, exec_state); | |
| 203 }; | |
| 204 local_1(); | |
| 205 EndTest(); | |
| 206 | |
| 207 | |
| 208 // Local scope with a parameter. | |
| 209 BeginTest("Local 2"); | |
| 210 | |
| 211 function local_2(a) { | |
| 212 debugger; | |
| 213 } | |
| 214 | |
| 215 listener_delegate = function(exec_state) { | |
| 216 CheckScopeChain([debug.ScopeType.Local, | |
| 217 debug.ScopeType.Script, | |
| 218 debug.ScopeType.Global], exec_state); | |
| 219 CheckScopeContent({a:1}, 0, exec_state); | |
| 220 }; | |
| 221 local_2(1); | |
| 222 EndTest(); | |
| 223 | |
| 224 | |
| 225 // Local scope with a parameter and a local variable. | |
| 226 BeginTest("Local 3"); | |
| 227 | |
| 228 function local_3(a) { | |
| 229 var x = 3; | |
| 230 debugger; | |
| 231 } | |
| 232 | |
| 233 listener_delegate = function(exec_state) { | |
| 234 CheckScopeChain([debug.ScopeType.Local, | |
| 235 debug.ScopeType.Script, | |
| 236 debug.ScopeType.Global], exec_state); | |
| 237 CheckScopeContent({a:1,x:3}, 0, exec_state); | |
| 238 }; | |
| 239 local_3(1); | |
| 240 EndTest(); | |
| 241 | |
| 242 | |
| 243 // Local scope with parameters and local variables. | |
| 244 BeginTest("Local 4"); | |
| 245 | |
| 246 function local_4(a, b) { | |
| 247 var x = 3; | |
| 248 var y = 4; | |
| 249 debugger; | |
| 250 } | |
| 251 | |
| 252 listener_delegate = function(exec_state) { | |
| 253 CheckScopeChain([debug.ScopeType.Local, | |
| 254 debug.ScopeType.Script, | |
| 255 debug.ScopeType.Global], exec_state); | |
| 256 CheckScopeContent({a:1,b:2,x:3,y:4}, 0, exec_state); | |
| 257 }; | |
| 258 local_4(1, 2); | |
| 259 EndTest(); | |
| 260 | |
| 261 | |
| 262 // Empty local scope with use of eval. | |
| 263 BeginTest("Local 5"); | |
| 264 | |
| 265 function local_5() { | |
| 266 eval(''); | |
| 267 debugger; | |
| 268 } | |
| 269 | |
| 270 listener_delegate = function(exec_state) { | |
| 271 CheckScopeChain([debug.ScopeType.Local, | |
| 272 debug.ScopeType.Script, | |
| 273 debug.ScopeType.Global], exec_state); | |
| 274 CheckScopeContent({}, 0, exec_state); | |
| 275 }; | |
| 276 local_5(); | |
| 277 EndTest(); | |
| 278 | |
| 279 | |
| 280 // Local introducing local variable using eval. | |
| 281 BeginTest("Local 6"); | |
| 282 | |
| 283 function local_6() { | |
| 284 eval('var i = 5'); | |
| 285 debugger; | |
| 286 } | |
| 287 | |
| 288 listener_delegate = function(exec_state) { | |
| 289 CheckScopeChain([debug.ScopeType.Local, | |
| 290 debug.ScopeType.Script, | |
| 291 debug.ScopeType.Global], exec_state); | |
| 292 CheckScopeContent({i:5}, 0, exec_state); | |
| 293 }; | |
| 294 local_6(); | |
| 295 EndTest(); | |
| 296 | |
| 297 | |
| 298 // Local scope with parameters, local variables and local variable introduced | |
| 299 // using eval. | |
| 300 BeginTest("Local 7"); | |
| 301 | |
| 302 function local_7(a, b) { | |
| 303 var x = 3; | |
| 304 var y = 4; | |
| 305 eval('var i = 5'); | |
| 306 eval('var j = 6'); | |
| 307 debugger; | |
| 308 } | |
| 309 | |
| 310 listener_delegate = function(exec_state) { | |
| 311 CheckScopeChain([debug.ScopeType.Local, | |
| 312 debug.ScopeType.Script, | |
| 313 debug.ScopeType.Global], exec_state); | |
| 314 CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6}, 0, exec_state); | |
| 315 }; | |
| 316 local_7(1, 2); | |
| 317 EndTest(); | |
| 318 | |
| 319 | |
| 320 // Single empty with block. | |
| 321 BeginTest("With 1"); | |
| 322 | |
| 323 function with_1() { | |
| 324 with({}) { | |
| 325 debugger; | |
| 326 } | |
| 327 } | |
| 328 | |
| 329 listener_delegate = function(exec_state) { | |
| 330 CheckScopeChain([debug.ScopeType.With, | |
| 331 debug.ScopeType.Local, | |
| 332 debug.ScopeType.Script, | |
| 333 debug.ScopeType.Global], exec_state); | |
| 334 CheckScopeContent({}, 0, exec_state); | |
| 335 }; | |
| 336 with_1(); | |
| 337 EndTest(); | |
| 338 | |
| 339 | |
| 340 // Nested empty with blocks. | |
| 341 BeginTest("With 2"); | |
| 342 | |
| 343 function with_2() { | |
| 344 with({}) { | |
| 345 with({}) { | |
| 346 debugger; | |
| 347 } | |
| 348 } | |
| 349 } | |
| 350 | |
| 351 listener_delegate = function(exec_state) { | |
| 352 CheckScopeChain([debug.ScopeType.With, | |
| 353 debug.ScopeType.With, | |
| 354 debug.ScopeType.Local, | |
| 355 debug.ScopeType.Script, | |
| 356 debug.ScopeType.Global], exec_state); | |
| 357 CheckScopeContent({}, 0, exec_state); | |
| 358 CheckScopeContent({}, 1, exec_state); | |
| 359 }; | |
| 360 with_2(); | |
| 361 EndTest(); | |
| 362 | |
| 363 | |
| 364 // With block using an in-place object literal. | |
| 365 BeginTest("With 3"); | |
| 366 | |
| 367 function with_3() { | |
| 368 with({a:1,b:2}) { | |
| 369 debugger; | |
| 370 } | |
| 371 } | |
| 372 | |
| 373 listener_delegate = function(exec_state) { | |
| 374 CheckScopeChain([debug.ScopeType.With, | |
| 375 debug.ScopeType.Local, | |
| 376 debug.ScopeType.Script, | |
| 377 debug.ScopeType.Global], exec_state); | |
| 378 CheckScopeContent({a:1,b:2}, 0, exec_state); | |
| 379 }; | |
| 380 with_3(); | |
| 381 EndTest(); | |
| 382 | |
| 383 | |
| 384 // Nested with blocks using in-place object literals. | |
| 385 BeginTest("With 4"); | |
| 386 | |
| 387 function with_4() { | |
| 388 with({a:1,b:2}) { | |
| 389 with({a:2,b:1}) { | |
| 390 debugger; | |
| 391 } | |
| 392 } | |
| 393 } | |
| 394 | |
| 395 listener_delegate = function(exec_state) { | |
| 396 CheckScopeChain([debug.ScopeType.With, | |
| 397 debug.ScopeType.With, | |
| 398 debug.ScopeType.Local, | |
| 399 debug.ScopeType.Script, | |
| 400 debug.ScopeType.Global], exec_state); | |
| 401 CheckScopeContent({a:2,b:1}, 0, exec_state); | |
| 402 CheckScopeContent({a:1,b:2}, 1, exec_state); | |
| 403 }; | |
| 404 with_4(); | |
| 405 EndTest(); | |
| 406 | |
| 407 | |
| 408 // Nested with blocks using existing object. | |
| 409 BeginTest("With 5"); | |
| 410 | |
| 411 var with_object = {c:3,d:4}; | |
| 412 function with_5() { | |
| 413 with(with_object) { | |
| 414 with(with_object) { | |
| 415 debugger; | |
| 416 } | |
| 417 } | |
| 418 } | |
| 419 | |
| 420 listener_delegate = function(exec_state) { | |
| 421 CheckScopeChain([debug.ScopeType.With, | |
| 422 debug.ScopeType.With, | |
| 423 debug.ScopeType.Local, | |
| 424 debug.ScopeType.Script, | |
| 425 debug.ScopeType.Global], exec_state); | |
| 426 CheckScopeContent(with_object, 0, exec_state); | |
| 427 CheckScopeContent(with_object, 1, exec_state); | |
| 428 assertEquals(exec_state.frame().scope(0).scopeObject(), | |
| 429 exec_state.frame().scope(1).scopeObject()); | |
| 430 assertEquals(with_object, exec_state.frame().scope(1).scopeObject().value()); | |
| 431 }; | |
| 432 with_5(); | |
| 433 EndTest(); | |
| 434 | |
| 435 | |
| 436 // Nested with blocks using existing object in global code. | |
| 437 BeginTest("With 6"); | |
| 438 listener_delegate = function(exec_state) { | |
| 439 CheckScopeChain([debug.ScopeType.With, | |
| 440 debug.ScopeType.With, | |
| 441 debug.ScopeType.Script, | |
| 442 debug.ScopeType.Global], exec_state); | |
| 443 CheckScopeContent(with_object, 0, exec_state); | |
| 444 CheckScopeContent(with_object, 1, exec_state); | |
| 445 assertEquals(exec_state.frame().scope(0).scopeObject(), | |
| 446 exec_state.frame().scope(1).scopeObject()); | |
| 447 assertEquals(with_object, exec_state.frame().scope(1).scopeObject().value()); | |
| 448 }; | |
| 449 | |
| 450 var with_object = {c:3,d:4}; | |
| 451 with(with_object) { | |
| 452 with(with_object) { | |
| 453 debugger; | |
| 454 } | |
| 455 } | |
| 456 EndTest(); | |
| 457 | |
| 458 | |
| 459 // With block in function that is marked for optimization while being executed. | |
| 460 BeginTest("With 7"); | |
| 461 | |
| 462 function with_7() { | |
| 463 with({}) { | |
| 464 %OptimizeFunctionOnNextCall(with_7); | |
| 465 debugger; | |
| 466 } | |
| 467 } | |
| 468 | |
| 469 listener_delegate = function(exec_state) { | |
| 470 CheckScopeChain([debug.ScopeType.With, | |
| 471 debug.ScopeType.Local, | |
| 472 debug.ScopeType.Script, | |
| 473 debug.ScopeType.Global], exec_state); | |
| 474 CheckScopeContent({}, 0, exec_state); | |
| 475 }; | |
| 476 with_7(); | |
| 477 EndTest(); | |
| 478 | |
| 479 | |
| 480 // Simple closure formed by returning an inner function referering the outer | |
| 481 // functions arguments. | |
| 482 BeginTest("Closure 1"); | |
| 483 | |
| 484 function closure_1(a) { | |
| 485 function f() { | |
| 486 debugger; | |
| 487 return a; | |
| 488 }; | |
| 489 return f; | |
| 490 } | |
| 491 | |
| 492 listener_delegate = function(exec_state) { | |
| 493 CheckScopeChain([debug.ScopeType.Local, | |
| 494 debug.ScopeType.Closure, | |
| 495 debug.ScopeType.Script, | |
| 496 debug.ScopeType.Global], exec_state); | |
| 497 CheckScopeContent({a:1}, 1, exec_state); | |
| 498 CheckScopeChainNames(["f", "closure_1", undefined, undefined], exec_state); | |
| 499 }; | |
| 500 closure_1(1)(); | |
| 501 EndTest(); | |
| 502 | |
| 503 | |
| 504 // Simple closure formed by returning an inner function referering the outer | |
| 505 // functions arguments. Due to VM optimizations parts of the actual closure is | |
| 506 // missing from the debugger information. | |
| 507 BeginTest("Closure 2"); | |
| 508 | |
| 509 function closure_2(a, b) { | |
| 510 var x = a + 2; | |
| 511 var y = b + 2; | |
| 512 function f() { | |
| 513 debugger; | |
| 514 return a + x; | |
| 515 }; | |
| 516 return f; | |
| 517 } | |
| 518 | |
| 519 listener_delegate = function(exec_state) { | |
| 520 CheckScopeChain([debug.ScopeType.Local, | |
| 521 debug.ScopeType.Closure, | |
| 522 debug.ScopeType.Script, | |
| 523 debug.ScopeType.Global], exec_state); | |
| 524 CheckScopeContent({a:1,x:3}, 1, exec_state); | |
| 525 CheckScopeChainNames(["f", "closure_2", undefined, undefined], exec_state); | |
| 526 }; | |
| 527 closure_2(1, 2)(); | |
| 528 EndTest(); | |
| 529 | |
| 530 | |
| 531 // Simple closure formed by returning an inner function referering the outer | |
| 532 // functions arguments. Using all arguments and locals from the outer function | |
| 533 // in the inner function makes these part of the debugger information on the | |
| 534 // closure. | |
| 535 BeginTest("Closure 3"); | |
| 536 | |
| 537 function closure_3(a, b) { | |
| 538 var x = a + 2; | |
| 539 var y = b + 2; | |
| 540 function f() { | |
| 541 debugger; | |
| 542 return a + b + x + y; | |
| 543 }; | |
| 544 return f; | |
| 545 } | |
| 546 | |
| 547 listener_delegate = function(exec_state) { | |
| 548 CheckScopeChain([debug.ScopeType.Local, | |
| 549 debug.ScopeType.Closure, | |
| 550 debug.ScopeType.Script, | |
| 551 debug.ScopeType.Global], exec_state); | |
| 552 CheckScopeContent({a:1,b:2,x:3,y:4}, 1, exec_state); | |
| 553 CheckScopeChainNames(["f", "closure_3", undefined, undefined], exec_state); | |
| 554 }; | |
| 555 closure_3(1, 2)(); | |
| 556 EndTest(); | |
| 557 | |
| 558 | |
| 559 | |
| 560 // Simple closure formed by returning an inner function referering the outer | |
| 561 // functions arguments. Using all arguments and locals from the outer function | |
| 562 // in the inner function makes these part of the debugger information on the | |
| 563 // closure. Use the inner function as well... | |
| 564 BeginTest("Closure 4"); | |
| 565 | |
| 566 function closure_4(a, b) { | |
| 567 var x = a + 2; | |
| 568 var y = b + 2; | |
| 569 function f() { | |
| 570 debugger; | |
| 571 if (f) { | |
| 572 return a + b + x + y; | |
| 573 } | |
| 574 }; | |
| 575 return f; | |
| 576 } | |
| 577 | |
| 578 listener_delegate = function(exec_state) { | |
| 579 CheckScopeChain([debug.ScopeType.Local, | |
| 580 debug.ScopeType.Closure, | |
| 581 debug.ScopeType.Script, | |
| 582 debug.ScopeType.Global], exec_state); | |
| 583 CheckScopeContent({a:1,b:2,x:3,y:4,f:function(){}}, 1, exec_state); | |
| 584 CheckScopeChainNames(["f", "closure_4", undefined, undefined], exec_state); | |
| 585 }; | |
| 586 closure_4(1, 2)(); | |
| 587 EndTest(); | |
| 588 | |
| 589 | |
| 590 | |
| 591 // Simple closure formed by returning an inner function referering the outer | |
| 592 // functions arguments. In the presence of eval all arguments and locals | |
| 593 // (including the inner function itself) from the outer function becomes part of | |
| 594 // the debugger infformation on the closure. | |
| 595 BeginTest("Closure 5"); | |
| 596 | |
| 597 function closure_5(a, b) { | |
| 598 var x = 3; | |
| 599 var y = 4; | |
| 600 function f() { | |
| 601 eval(''); | |
| 602 debugger; | |
| 603 return 1; | |
| 604 }; | |
| 605 return f; | |
| 606 } | |
| 607 | |
| 608 listener_delegate = function(exec_state) { | |
| 609 CheckScopeChain([debug.ScopeType.Local, | |
| 610 debug.ScopeType.Closure, | |
| 611 debug.ScopeType.Script, | |
| 612 debug.ScopeType.Global], exec_state); | |
| 613 CheckScopeContent({a:1,b:2,x:3,y:4,f:function(){}}, 1, exec_state); | |
| 614 CheckScopeChainNames(["f", "closure_5", undefined, undefined], exec_state) | |
| 615 }; | |
| 616 closure_5(1, 2)(); | |
| 617 EndTest(); | |
| 618 | |
| 619 | |
| 620 // Two closures. Due to optimizations only the parts actually used are provided | |
| 621 // through the debugger information. | |
| 622 BeginTest("Closure 6"); | |
| 623 function closure_6(a, b) { | |
| 624 function f(a, b) { | |
| 625 var x = 3; | |
| 626 var y = 4; | |
| 627 return function() { | |
| 628 var x = 3; | |
| 629 var y = 4; | |
| 630 debugger; | |
| 631 some_global = a; | |
| 632 return f; | |
| 633 }; | |
| 634 } | |
| 635 return f(a, b); | |
| 636 } | |
| 637 | |
| 638 listener_delegate = function(exec_state) { | |
| 639 CheckScopeChain([debug.ScopeType.Local, | |
| 640 debug.ScopeType.Closure, | |
| 641 debug.ScopeType.Closure, | |
| 642 debug.ScopeType.Script, | |
| 643 debug.ScopeType.Global], exec_state); | |
| 644 CheckScopeContent({a:1}, 1, exec_state); | |
| 645 CheckScopeContent({f:function(){}}, 2, exec_state); | |
| 646 CheckScopeChainNames([undefined, "f", "closure_6", undefined, undefined], | |
| 647 exec_state); | |
| 648 }; | |
| 649 closure_6(1, 2)(); | |
| 650 EndTest(); | |
| 651 | |
| 652 | |
| 653 // Two closures. In the presence of eval all information is provided as the | |
| 654 // compiler cannot determine which parts are used. | |
| 655 BeginTest("Closure 7"); | |
| 656 function closure_7(a, b) { | |
| 657 var x = 3; | |
| 658 var y = 4; | |
| 659 eval('var i = 5'); | |
| 660 eval('var j = 6'); | |
| 661 function f(a, b) { | |
| 662 var x = 3; | |
| 663 var y = 4; | |
| 664 eval('var i = 5'); | |
| 665 eval('var j = 6'); | |
| 666 return function() { | |
| 667 debugger; | |
| 668 some_global = a; | |
| 669 return f; | |
| 670 }; | |
| 671 } | |
| 672 return f(a, b); | |
| 673 } | |
| 674 | |
| 675 listener_delegate = function(exec_state) { | |
| 676 CheckScopeChain([debug.ScopeType.Local, | |
| 677 debug.ScopeType.Closure, | |
| 678 debug.ScopeType.Closure, | |
| 679 debug.ScopeType.Script, | |
| 680 debug.ScopeType.Global], exec_state); | |
| 681 CheckScopeContent({}, 0, exec_state); | |
| 682 CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6}, 1, exec_state); | |
| 683 CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6,f:function(){}}, 2, exec_state); | |
| 684 CheckScopeChainNames([undefined, "f", "closure_7", undefined, undefined], | |
| 685 exec_state); | |
| 686 }; | |
| 687 closure_7(1, 2)(); | |
| 688 EndTest(); | |
| 689 | |
| 690 | |
| 691 // Closure that may be optimized out. | |
| 692 BeginTest("Closure 8"); | |
| 693 function closure_8() { | |
| 694 (function inner(x) { | |
| 695 debugger; | |
| 696 })(2); | |
| 697 } | |
| 698 | |
| 699 listener_delegate = function(exec_state) { | |
| 700 CheckScopeChain([debug.ScopeType.Local, | |
| 701 debug.ScopeType.Script, | |
| 702 debug.ScopeType.Global], exec_state); | |
| 703 CheckScopeContent({x: 2}, 0, exec_state); | |
| 704 CheckScopeChainNames(["inner", undefined, undefined], exec_state); | |
| 705 }; | |
| 706 closure_8(); | |
| 707 EndTest(); | |
| 708 | |
| 709 | |
| 710 BeginTest("Closure 9"); | |
| 711 function closure_9() { | |
| 712 eval("var y = 1;"); | |
| 713 eval("var z = 1;"); | |
| 714 (function inner(x) { | |
| 715 y++; | |
| 716 z++; | |
| 717 debugger; | |
| 718 })(2); | |
| 719 } | |
| 720 | |
| 721 listener_delegate = function(exec_state) { | |
| 722 CheckScopeChain([debug.ScopeType.Local, | |
| 723 debug.ScopeType.Closure, | |
| 724 debug.ScopeType.Script, | |
| 725 debug.ScopeType.Global], exec_state); | |
| 726 CheckScopeChainNames(["inner", "closure_9", undefined, undefined], | |
| 727 exec_state); | |
| 728 }; | |
| 729 closure_9(); | |
| 730 EndTest(); | |
| 731 | |
| 732 | |
| 733 // Test a mixture of scopes. | |
| 734 BeginTest("The full monty"); | |
| 735 function the_full_monty(a, b) { | |
| 736 var x = 3; | |
| 737 var y = 4; | |
| 738 eval('var i = 5'); | |
| 739 eval('var j = 6'); | |
| 740 function f(a, b) { | |
| 741 var x = 9; | |
| 742 var y = 10; | |
| 743 eval('var i = 11'); | |
| 744 eval('var j = 12'); | |
| 745 with ({j:13}){ | |
| 746 return function() { | |
| 747 var x = 14; | |
| 748 with ({a:15}) { | |
| 749 with ({b:16}) { | |
| 750 debugger; | |
| 751 some_global = a; | |
| 752 return f; | |
| 753 } | |
| 754 } | |
| 755 }; | |
| 756 } | |
| 757 } | |
| 758 return f(a, b); | |
| 759 } | |
| 760 | |
| 761 listener_delegate = function(exec_state) { | |
| 762 CheckScopeChain([debug.ScopeType.With, | |
| 763 debug.ScopeType.With, | |
| 764 debug.ScopeType.Local, | |
| 765 debug.ScopeType.With, | |
| 766 debug.ScopeType.Closure, | |
| 767 debug.ScopeType.Closure, | |
| 768 debug.ScopeType.Script, | |
| 769 debug.ScopeType.Global], exec_state); | |
| 770 CheckScopeContent({b:16}, 0, exec_state); | |
| 771 CheckScopeContent({a:15}, 1, exec_state); | |
| 772 CheckScopeContent({x:14}, 2, exec_state); | |
| 773 CheckScopeContent({j:13}, 3, exec_state); | |
| 774 CheckScopeContent({a:1,b:2,x:9,y:10,i:11,j:12}, 4, exec_state); | |
| 775 CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6,f:function(){}}, 5, exec_state); | |
| 776 CheckScopeChainNames([undefined, undefined, undefined, "f", "f", | |
| 777 "the_full_monty", undefined, undefined], exec_state); | |
| 778 }; | |
| 779 the_full_monty(1, 2)(); | |
| 780 EndTest(); | |
| 781 | |
| 782 | |
| 783 BeginTest("Closure inside With 1"); | |
| 784 function closure_in_with_1() { | |
| 785 with({x:1}) { | |
| 786 (function inner(x) { | |
| 787 debugger; | |
| 788 })(2); | |
| 789 } | |
| 790 } | |
| 791 | |
| 792 listener_delegate = function(exec_state) { | |
| 793 CheckScopeChain([debug.ScopeType.Local, | |
| 794 debug.ScopeType.With, | |
| 795 debug.ScopeType.Script, | |
| 796 debug.ScopeType.Global], exec_state); | |
| 797 CheckScopeContent({x: 2}, 0, exec_state); | |
| 798 CheckScopeContent({x: 1}, 1, exec_state); | |
| 799 }; | |
| 800 closure_in_with_1(); | |
| 801 EndTest(); | |
| 802 | |
| 803 | |
| 804 BeginTest("Closure inside With 2"); | |
| 805 function closure_in_with_2() { | |
| 806 with({x:1}) { | |
| 807 (function inner(x) { | |
| 808 with({x:3}) { | |
| 809 debugger; | |
| 810 } | |
| 811 })(2); | |
| 812 } | |
| 813 } | |
| 814 | |
| 815 listener_delegate = function(exec_state) { | |
| 816 CheckScopeChain([debug.ScopeType.With, | |
| 817 debug.ScopeType.Local, | |
| 818 debug.ScopeType.With, | |
| 819 debug.ScopeType.Script, | |
| 820 debug.ScopeType.Global], exec_state); | |
| 821 CheckScopeContent({x: 3}, 0, exec_state); | |
| 822 CheckScopeContent({x: 2}, 1, exec_state); | |
| 823 CheckScopeContent({x: 1}, 2, exec_state); | |
| 824 CheckScopeChainNames(["inner", "inner", "closure_in_with_2", | |
| 825 undefined, undefined], exec_state); | |
| 826 }; | |
| 827 closure_in_with_2(); | |
| 828 EndTest(); | |
| 829 | |
| 830 | |
| 831 BeginTest("Closure inside With 3"); | |
| 832 function createClosure(a) { | |
| 833 var b = a + 1; | |
| 834 return function closure() { | |
| 835 var c = b; | |
| 836 (function inner(x) { | |
| 837 with({x:c}) { | |
| 838 debugger; | |
| 839 } | |
| 840 })(2); | |
| 841 }; | |
| 842 } | |
| 843 | |
| 844 function closure_in_with_3() { | |
| 845 var f = createClosure(0); | |
| 846 f(); | |
| 847 } | |
| 848 | |
| 849 listener_delegate = function(exec_state) { | |
| 850 CheckScopeChain([debug.ScopeType.With, | |
| 851 debug.ScopeType.Local, | |
| 852 debug.ScopeType.Closure, | |
| 853 debug.ScopeType.Closure, | |
| 854 debug.ScopeType.Script, | |
| 855 debug.ScopeType.Global], exec_state); | |
| 856 CheckScopeChainNames(["inner", "inner", "closure", "createClosure", | |
| 857 undefined, undefined], exec_state); | |
| 858 } | |
| 859 closure_in_with_3(); | |
| 860 EndTest(); | |
| 861 | |
| 862 | |
| 863 BeginTest("Closure inside With 4"); | |
| 864 listener_delegate = function(exec_state) { | |
| 865 CheckScopeChain([debug.ScopeType.Local, | |
| 866 debug.ScopeType.With, | |
| 867 debug.ScopeType.Script, | |
| 868 debug.ScopeType.Global], exec_state); | |
| 869 CheckScopeContent({x: 2}, 0, exec_state); | |
| 870 CheckScopeContent({x: 1}, 1, exec_state); | |
| 871 CheckScopeChainNames([undefined, undefined, undefined, undefined], | |
| 872 exec_state); | |
| 873 }; | |
| 874 | |
| 875 with({x:1}) { | |
| 876 (function(x) { | |
| 877 debugger; | |
| 878 })(2); | |
| 879 } | |
| 880 EndTest(); | |
| 881 | |
| 882 | |
| 883 // Test global scope. | |
| 884 BeginTest("Global"); | |
| 885 listener_delegate = function(exec_state) { | |
| 886 CheckScopeChain([debug.ScopeType.Script, debug.ScopeType.Global], | |
| 887 exec_state); | |
| 888 CheckScopeChainNames([undefined, undefined], exec_state); | |
| 889 }; | |
| 890 debugger; | |
| 891 EndTest(); | |
| 892 | |
| 893 | |
| 894 BeginTest("Catch block 1"); | |
| 895 function catch_block_1() { | |
| 896 try { | |
| 897 throw 'Exception'; | |
| 898 } catch (e) { | |
| 899 debugger; | |
| 900 } | |
| 901 }; | |
| 902 | |
| 903 | |
| 904 listener_delegate = function(exec_state) { | |
| 905 CheckScopeChain([debug.ScopeType.Catch, | |
| 906 debug.ScopeType.Local, | |
| 907 debug.ScopeType.Script, | |
| 908 debug.ScopeType.Global], exec_state); | |
| 909 CheckScopeContent({e:'Exception'}, 0, exec_state); | |
| 910 CheckScopeChainNames(["catch_block_1", "catch_block_1", | |
| 911 undefined, undefined], exec_state); | |
| 912 }; | |
| 913 catch_block_1(); | |
| 914 EndTest(); | |
| 915 | |
| 916 | |
| 917 BeginTest("Catch block 2"); | |
| 918 function catch_block_2() { | |
| 919 try { | |
| 920 throw 'Exception'; | |
| 921 } catch (e) { | |
| 922 with({n:10}) { | |
| 923 debugger; | |
| 924 } | |
| 925 } | |
| 926 }; | |
| 927 | |
| 928 | |
| 929 listener_delegate = function(exec_state) { | |
| 930 CheckScopeChain([debug.ScopeType.With, | |
| 931 debug.ScopeType.Catch, | |
| 932 debug.ScopeType.Local, | |
| 933 debug.ScopeType.Script, | |
| 934 debug.ScopeType.Global], exec_state); | |
| 935 CheckScopeContent({n:10}, 0, exec_state); | |
| 936 CheckScopeContent({e:'Exception'}, 1, exec_state); | |
| 937 CheckScopeChainNames(["catch_block_2", "catch_block_2", "catch_block_2", | |
| 938 undefined, undefined], exec_state); | |
| 939 }; | |
| 940 catch_block_2(); | |
| 941 EndTest(); | |
| 942 | |
| 943 | |
| 944 BeginTest("Catch block 3"); | |
| 945 function catch_block_3() { | |
| 946 // Do eval to dynamically declare a local variable so that the context's | |
| 947 // extension slot is initialized with JSContextExtensionObject. | |
| 948 eval("var y = 78;"); | |
| 949 try { | |
| 950 throw 'Exception'; | |
| 951 } catch (e) { | |
| 952 debugger; | |
| 953 } | |
| 954 }; | |
| 955 | |
| 956 | |
| 957 listener_delegate = function(exec_state) { | |
| 958 CheckScopeChain([debug.ScopeType.Catch, | |
| 959 debug.ScopeType.Local, | |
| 960 debug.ScopeType.Script, | |
| 961 debug.ScopeType.Global], exec_state); | |
| 962 CheckScopeContent({e:'Exception'}, 0, exec_state); | |
| 963 CheckScopeContent({y:78}, 1, exec_state); | |
| 964 CheckScopeChainNames(["catch_block_3", "catch_block_3", | |
| 965 undefined, undefined], exec_state); | |
| 966 }; | |
| 967 catch_block_3(); | |
| 968 EndTest(); | |
| 969 | |
| 970 | |
| 971 BeginTest("Catch block 4"); | |
| 972 function catch_block_4() { | |
| 973 // Do eval to dynamically declare a local variable so that the context's | |
| 974 // extension slot is initialized with JSContextExtensionObject. | |
| 975 eval("var y = 98;"); | |
| 976 try { | |
| 977 throw 'Exception'; | |
| 978 } catch (e) { | |
| 979 with({n:10}) { | |
| 980 debugger; | |
| 981 } | |
| 982 } | |
| 983 }; | |
| 984 | |
| 985 listener_delegate = function(exec_state) { | |
| 986 CheckScopeChain([debug.ScopeType.With, | |
| 987 debug.ScopeType.Catch, | |
| 988 debug.ScopeType.Local, | |
| 989 debug.ScopeType.Script, | |
| 990 debug.ScopeType.Global], exec_state); | |
| 991 CheckScopeContent({n:10}, 0, exec_state); | |
| 992 CheckScopeContent({e:'Exception'}, 1, exec_state); | |
| 993 CheckScopeContent({y:98}, 2, exec_state); | |
| 994 CheckScopeChainNames(["catch_block_4", "catch_block_4", "catch_block_4", | |
| 995 undefined, undefined], exec_state); | |
| 996 }; | |
| 997 catch_block_4(); | |
| 998 EndTest(); | |
| 999 | |
| 1000 | |
| 1001 // Test catch in global scope. | |
| 1002 BeginTest("Catch block 5"); | |
| 1003 listener_delegate = function(exec_state) { | |
| 1004 CheckScopeChain([debug.ScopeType.Catch, | |
| 1005 debug.ScopeType.Script, | |
| 1006 debug.ScopeType.Global], exec_state); | |
| 1007 CheckScopeContent({e:'Exception'}, 0, exec_state); | |
| 1008 CheckScopeChainNames([undefined, undefined, undefined], exec_state); | |
| 1009 }; | |
| 1010 | |
| 1011 try { | |
| 1012 throw 'Exception'; | |
| 1013 } catch (e) { | |
| 1014 debugger; | |
| 1015 } | |
| 1016 | |
| 1017 EndTest(); | |
| 1018 | |
| 1019 | |
| 1020 // Closure inside catch in global code. | |
| 1021 BeginTest("Catch block 6"); | |
| 1022 listener_delegate = function(exec_state) { | |
| 1023 CheckScopeChain([debug.ScopeType.Local, | |
| 1024 debug.ScopeType.Catch, | |
| 1025 debug.ScopeType.Script, | |
| 1026 debug.ScopeType.Global], exec_state); | |
| 1027 CheckScopeContent({x: 2}, 0, exec_state); | |
| 1028 CheckScopeContent({e:'Exception'}, 1, exec_state); | |
| 1029 CheckScopeChainNames([undefined, undefined, undefined, undefined], | |
| 1030 exec_state); | |
| 1031 }; | |
| 1032 | |
| 1033 try { | |
| 1034 throw 'Exception'; | |
| 1035 } catch (e) { | |
| 1036 (function(x) { | |
| 1037 debugger; | |
| 1038 })(2); | |
| 1039 } | |
| 1040 EndTest(); | |
| 1041 | |
| 1042 | |
| 1043 // Catch block in function that is marked for optimization while being executed. | |
| 1044 BeginTest("Catch block 7"); | |
| 1045 function catch_block_7() { | |
| 1046 %OptimizeFunctionOnNextCall(catch_block_7); | |
| 1047 try { | |
| 1048 throw 'Exception'; | |
| 1049 } catch (e) { | |
| 1050 debugger; | |
| 1051 } | |
| 1052 }; | |
| 1053 | |
| 1054 | |
| 1055 listener_delegate = function(exec_state) { | |
| 1056 CheckScopeChain([debug.ScopeType.Catch, | |
| 1057 debug.ScopeType.Local, | |
| 1058 debug.ScopeType.Script, | |
| 1059 debug.ScopeType.Global], exec_state); | |
| 1060 CheckScopeContent({e:'Exception'}, 0, exec_state); | |
| 1061 CheckScopeChainNames(["catch_block_7", "catch_block_7", | |
| 1062 undefined, undefined], exec_state); | |
| 1063 }; | |
| 1064 catch_block_7(); | |
| 1065 EndTest(); | |
| 1066 | |
| 1067 | |
| 1068 BeginTest("Classes and methods 1"); | |
| 1069 | |
| 1070 listener_delegate = function(exec_state) { | |
| 1071 "use strict" | |
| 1072 CheckScopeChain([debug.ScopeType.Local, | |
| 1073 debug.ScopeType.Script, | |
| 1074 debug.ScopeType.Global], exec_state); | |
| 1075 CheckScopeContent({}, 1, exec_state); | |
| 1076 CheckScopeChainNames(["m", undefined, undefined], exec_state); | |
| 1077 }; | |
| 1078 | |
| 1079 (function() { | |
| 1080 "use strict"; | |
| 1081 class C1 { | |
| 1082 m() { | |
| 1083 debugger; | |
| 1084 } | |
| 1085 } | |
| 1086 new C1().m(); | |
| 1087 })(); | |
| 1088 | |
| 1089 EndTest(); | |
| 1090 | |
| 1091 BeginTest("Scope positions"); | |
| 1092 var code1 = "function f() { \n" + | |
| 1093 " var a = 1; \n" + | |
| 1094 " function b() { \n" + | |
| 1095 " debugger; \n" + | |
| 1096 " return a + 1; \n" + | |
| 1097 " } \n" + | |
| 1098 " b(); \n" + | |
| 1099 "} \n" + | |
| 1100 "f(); \n"; | |
| 1101 | |
| 1102 listener_delegate = function(exec_state) { | |
| 1103 CheckScopeChainPositions( | |
| 1104 [{start: 58, end: 118}, {start: 10, end: 162}, {}, {}], exec_state); | |
| 1105 } | |
| 1106 eval(code1); | |
| 1107 EndTest(); | |
| 1108 | |
| 1109 | |
| 1110 function catch_block_2() { | |
| 1111 try { | |
| 1112 throw 'Exception'; | |
| 1113 } catch (e) { | |
| 1114 with({n:10}) { | |
| 1115 debugger; | |
| 1116 } | |
| 1117 } | |
| 1118 }; | |
| 1119 | |
| 1120 BeginTest("Scope positions in catch and 'with' statement"); | |
| 1121 var code2 = "function catch_block() { \n" + | |
| 1122 " try { \n" + | |
| 1123 " throw 'Exception'; \n" + | |
| 1124 " } catch (e) { \n" + | |
| 1125 " with({n : 10}) { \n" + | |
| 1126 " debugger; \n" + | |
| 1127 " } \n" + | |
| 1128 " } \n" + | |
| 1129 "} \n" + | |
| 1130 "catch_block(); \n"; | |
| 1131 | |
| 1132 listener_delegate = function(exec_state) { | |
| 1133 CheckScopeChainPositions([{start: 131, end: 173}, | |
| 1134 {start: 94, end: 199}, | |
| 1135 {start: 20, end: 225}, | |
| 1136 {}, {}], exec_state); | |
| 1137 } | |
| 1138 eval(code2); | |
| 1139 EndTest(); | |
| 1140 | |
| 1141 BeginTest("Scope positions in for statement"); | |
| 1142 var code3 = "function for_statement() { \n" + | |
| 1143 " for (let i = 0; i < 1; i++) { \n" + | |
| 1144 " debugger; \n" + | |
| 1145 " } \n" + | |
| 1146 "} \n" + | |
| 1147 "for_statement(); \n"; | |
| 1148 | |
| 1149 listener_delegate = function(exec_state) { | |
| 1150 CheckScopeChain([debug.ScopeType.Block, | |
| 1151 debug.ScopeType.Local, | |
| 1152 debug.ScopeType.Script, | |
| 1153 debug.ScopeType.Global], exec_state); | |
| 1154 CheckScopeChainPositions( | |
| 1155 [{start: 52, end: 111}, {start: 22, end: 145}, {}, {}], exec_state); | |
| 1156 } | |
| 1157 eval(code3); | |
| 1158 EndTest(); | |
| 1159 | |
| 1160 BeginTest("Scope positions in for statement with lexical block"); | |
| 1161 var code4 = "function for_statement() { \n" + | |
| 1162 " for (let i = 0; i < 1; i++) { \n" + | |
| 1163 " let j; \n" + | |
| 1164 " debugger; \n" + | |
| 1165 " } \n" + | |
| 1166 "} \n" + | |
| 1167 "for_statement(); \n"; | |
| 1168 | |
| 1169 listener_delegate = function(exec_state) { | |
| 1170 CheckScopeChain([debug.ScopeType.Block, | |
| 1171 debug.ScopeType.Block, | |
| 1172 debug.ScopeType.Local, | |
| 1173 debug.ScopeType.Script, | |
| 1174 debug.ScopeType.Global], exec_state); | |
| 1175 CheckScopeChainPositions([{start: 66, end: 147}, | |
| 1176 {start: 52, end: 147}, | |
| 1177 {start: 22, end: 181}, | |
| 1178 {}, {}], exec_state); | |
| 1179 } | |
| 1180 eval(code4); | |
| 1181 EndTest(); | |
| 1182 | |
| 1183 BeginTest("Scope positions in lexical for each statement"); | |
| 1184 var code5 = "function for_each_statement() { \n" + | |
| 1185 " for (let i of [0]) { \n" + | |
| 1186 " debugger; \n" + | |
| 1187 " } \n" + | |
| 1188 "} \n" + | |
| 1189 "for_each_statement(); \n"; | |
| 1190 | |
| 1191 listener_delegate = function(exec_state) { | |
| 1192 CheckScopeChain([debug.ScopeType.Block, | |
| 1193 debug.ScopeType.Local, | |
| 1194 debug.ScopeType.Script, | |
| 1195 debug.ScopeType.Global], exec_state); | |
| 1196 CheckScopeChainPositions( | |
| 1197 [{start: 55, end: 111}, {start: 27, end: 145}, {}, {}], exec_state); | |
| 1198 } | |
| 1199 eval(code5); | |
| 1200 EndTest(); | |
| 1201 | |
| 1202 BeginTest("Scope positions in lexical for each statement with lexical block"); | |
| 1203 var code6 = "function for_each_statement() { \n" + | |
| 1204 " for (let i of [0]) { \n" + | |
| 1205 " let j; \n" + | |
| 1206 " debugger; \n" + | |
| 1207 " } \n" + | |
| 1208 "} \n" + | |
| 1209 "for_each_statement(); \n"; | |
| 1210 | |
| 1211 listener_delegate = function(exec_state) { | |
| 1212 CheckScopeChain([debug.ScopeType.Block, | |
| 1213 debug.ScopeType.Block, | |
| 1214 debug.ScopeType.Local, | |
| 1215 debug.ScopeType.Script, | |
| 1216 debug.ScopeType.Global], exec_state); | |
| 1217 CheckScopeChainPositions([{start: 57, end: 147}, | |
| 1218 {start: 55, end: 147}, | |
| 1219 {start: 27, end: 181}, | |
| 1220 {}, {}], exec_state); | |
| 1221 } | |
| 1222 eval(code6); | |
| 1223 EndTest(); | |
| 1224 | |
| 1225 BeginTest("Scope positions in non-lexical for each statement"); | |
| 1226 var code7 = "function for_each_statement() { \n" + | |
| 1227 " var i; \n" + | |
| 1228 " for (i of [0]) { \n" + | |
| 1229 " debugger; \n" + | |
| 1230 " } \n" + | |
| 1231 "} \n" + | |
| 1232 "for_each_statement(); \n"; | |
| 1233 | |
| 1234 listener_delegate = function(exec_state) { | |
| 1235 CheckScopeChain([debug.ScopeType.Local, | |
| 1236 debug.ScopeType.Script, | |
| 1237 debug.ScopeType.Global], exec_state); | |
| 1238 CheckScopeChainPositions([{start: 27, end: 181}, {}, {}], exec_state); | |
| 1239 } | |
| 1240 eval(code7); | |
| 1241 EndTest(); | |
| 1242 | |
| 1243 BeginTest( | |
| 1244 "Scope positions in non-lexical for each statement with lexical block"); | |
| 1245 var code8 = "function for_each_statement() { \n" + | |
| 1246 " var i; \n" + | |
| 1247 " for (i of [0]) { \n" + | |
| 1248 " let j; \n" + | |
| 1249 " debugger; \n" + | |
| 1250 " } \n" + | |
| 1251 "} \n" + | |
| 1252 "for_each_statement(); \n"; | |
| 1253 | |
| 1254 listener_delegate = function(exec_state) { | |
| 1255 CheckScopeChain([debug.ScopeType.Block, | |
| 1256 debug.ScopeType.Local, | |
| 1257 debug.ScopeType.Script, | |
| 1258 debug.ScopeType.Global], exec_state); | |
| 1259 CheckScopeChainPositions( | |
| 1260 [{start: 89, end: 183}, {start: 27, end: 217}, {}, {}], exec_state); | |
| 1261 } | |
| 1262 eval(code8); | |
| 1263 EndTest(); | |
| 1264 | |
| 1265 assertEquals(begin_test_count, break_count, | |
| 1266 'one or more tests did not enter the debugger'); | |
| 1267 assertEquals(begin_test_count, end_test_count, | |
| 1268 'one or more tests did not have its result checked'); | |
| OLD | NEW |