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 --expose-natives-as=builtins 29 30// Check that the ScopeIterator can properly recreate the scope at 31// every point when stepping through functions. 32 33var Debug = debug.Debug; 34 35function listener(event, exec_state, event_data, data) { 36 if (event == Debug.DebugEvent.Break) { 37 // Access scope details. 38 var scope_count = exec_state.frame().scopeCount(); 39 for (var i = 0; i < scope_count; i++) { 40 var scope = exec_state.frame().scope(i); 41 // assertTrue(scope.isScope()); 42 scope.scopeType(); 43 scope.scopeObject(); 44 } 45 46 // Do steps until we reach the global scope again. 47 if (true) { 48 exec_state.prepareStep(Debug.StepAction.StepInMin, 1); 49 } 50 } 51} 52 53Debug.setListener(listener); 54 55 56function test1() { 57 debugger; 58 with ({x:1}) { 59 x = 2; 60 } 61} 62test1(); 63 64 65function test2() { 66 if (true) { 67 with ({}) { 68 debugger; 69 } 70 } else { 71 with ({}) { 72 return 10; 73 } 74 } 75} 76test2(); 77 78 79function test3() { 80 if (true) { 81 debugger; 82 } else { 83 with ({}) { 84 return 10; 85 } 86 } 87} 88test3(); 89 90 91function test4() { 92 debugger; 93 with ({x:1}) x = 1 94} 95test4(); 96 97 98function test5() { 99 debugger; 100 var dummy = 1; 101 with ({}) { 102 with ({}) { 103 dummy = 2; 104 } 105 } 106 dummy = 3; 107} 108test5(); 109 110 111function test6() { 112 debugger; 113 try { 114 throw 'stuff'; 115 } catch (e) { 116 e = 1; 117 } 118} 119test6(); 120 121 122function test7() { 123 debugger; 124 function foo() {} 125} 126test7(); 127 128 129function test8() { 130 debugger; 131 (function foo() {})(); 132} 133test8(); 134 135 136var q = 42; 137var prefixes = [ "debugger; ", 138 "if (false) { try { throw 0; } catch(x) { return x; } }; debugger; " ]; 139var bodies = [ "1", 140 "1 ", 141 "1;", 142 "1; ", 143 "q", 144 "q ", 145 "q;", 146 "q; ", 147 "try { throw 'stuff' } catch (e) { e = 1; }", 148 "try { throw 'stuff' } catch (e) { e = 1; } ", 149 "try { throw 'stuff' } catch (e) { e = 1; };", 150 "try { throw 'stuff' } catch (e) { e = 1; }; " ]; 151var with_bodies = [ "with ({}) {}", 152 "with ({x:1}) x", 153 "with ({x:1}) x = 1", 154 "with ({x:1}) x ", 155 "with ({x:1}) x = 1 ", 156 "with ({x:1}) x;", 157 "with ({x:1}) x = 1;", 158 "with ({x:1}) x; ", 159 "with ({x:1}) x = 1; " ]; 160 161 162function test9() { 163 debugger; 164 for (var i = 0; i < prefixes.length; ++i) { 165 var pre = prefixes[i]; 166 for (var j = 0; j < bodies.length; ++j) { 167 var body = bodies[j]; 168 eval(pre + body); 169 eval("'use strict'; " + pre + body); 170 } 171 for (var j = 0; j < with_bodies.length; ++j) { 172 var body = with_bodies[j]; 173 eval(pre + body); 174 } 175 } 176} 177test9(); 178 179 180function test10() { 181 debugger; 182 with ({}) { 183 return 10; 184 } 185} 186test10(); 187 188 189function test11() { 190 debugger; 191 try { 192 throw 'stuff'; 193 } catch (e) { 194 return 10; 195 } 196} 197test11(); 198 199 200// Test global eval and function constructor. 201for (var i = 0; i < prefixes.length; ++i) { 202 var pre = prefixes[i]; 203 for (var j = 0; j < bodies.length; ++j) { 204 var body = bodies[j]; 205 eval(pre + body); 206 eval("'use strict'; " + pre + body); 207 Function(pre + body)(); 208 } 209 for (var j = 0; j < with_bodies.length; ++j) { 210 var body = with_bodies[j]; 211 eval(pre + body); 212 Function(pre + body)(); 213 } 214} 215 216 217try { 218 with({}) { 219 debugger; 220 eval("{}$%:^"); 221 } 222} catch(e) { 223 nop(); 224} 225 226// Return from function constructed with Function constructor. 227var anon = 12; 228for (var i = 0; i < prefixes.length; ++i) { 229 var pre = prefixes[i]; 230 Function(pre + "return 42")(); 231 Function(pre + "return 42 ")(); 232 Function(pre + "return 42;")(); 233 Function(pre + "return 42; ")(); 234 Function(pre + "return anon")(); 235 Function(pre + "return anon ")(); 236 Function(pre + "return anon;")(); 237 Function(pre + "return anon; ")(); 238} 239 240 241function nop() {} 242 243 244function stress() { 245 debugger; 246 247 L: with ({x:12}) { 248 break L; 249 } 250 251 252 with ({x: 'outer'}) { 253 label: { 254 with ({x: 'inner'}) { 255 break label; 256 } 257 } 258 } 259 260 261 with ({x: 'outer'}) { 262 label: { 263 with ({x: 'inner'}) { 264 break label; 265 } 266 } 267 nop(); 268 } 269 270 271 with ({x: 'outer'}) { 272 label: { 273 with ({x: 'middle'}) { 274 with ({x: 'inner'}) { 275 break label; 276 } 277 } 278 } 279 } 280 281 282 with ({x: 'outer'}) { 283 label: { 284 with ({x: 'middle'}) { 285 with ({x: 'inner'}) { 286 break label; 287 } 288 } 289 } 290 nop(); 291 } 292 293 294 with ({x: 'outer'}) { 295 for (var i = 0; i < 3; ++i) { 296 with ({x: 'inner' + i}) { 297 continue; 298 } 299 } 300 } 301 302 303 with ({x: 'outer'}) { 304 label: for (var i = 0; i < 3; ++i) { 305 with ({x: 'middle' + i}) { 306 for (var j = 0; j < 3; ++j) { 307 with ({x: 'inner' + j}) { 308 continue label; 309 } 310 } 311 } 312 } 313 } 314 315 316 with ({x: 'outer'}) { 317 try { 318 with ({x: 'inner'}) { 319 throw 0; 320 } 321 } catch (e) { 322 } 323 } 324 325 326 with ({x: 'outer'}) { 327 try { 328 with ({x: 'inner'}) { 329 throw 0; 330 } 331 } catch (e) { 332 nop(); 333 } 334 } 335 336 337 with ({x: 'outer'}) { 338 try { 339 with ({x: 'middle'}) { 340 with ({x: 'inner'}) { 341 throw 0; 342 } 343 } 344 } catch (e) { 345 } 346 } 347 348 349 try { 350 with ({x: 'outer'}) { 351 try { 352 with ({x: 'inner'}) { 353 throw 0; 354 } 355 } finally { 356 } 357 } 358 } catch (e) { 359 } 360 361 362 try { 363 with ({x: 'outer'}) { 364 try { 365 with ({x: 'inner'}) { 366 throw 0; 367 } 368 } finally { 369 nop(); 370 } 371 } 372 } catch (e) { 373 } 374 375 376 function stress1() { 377 with ({x:12}) { 378 return x; 379 } 380 } 381 stress1(); 382 383 384 function stress2() { 385 with ({x: 'outer'}) { 386 with ({x: 'inner'}) { 387 return x; 388 } 389 } 390 } 391 stress2(); 392 393 function stress3() { 394 try { 395 with ({x: 'inner'}) { 396 throw 0; 397 } 398 } catch (e) { 399 return e; 400 } 401 } 402 stress3(); 403 404 405 function stress4() { 406 try { 407 with ({x: 'inner'}) { 408 throw 0; 409 } 410 } catch (e) { 411 with ({x: 'inner'}) { 412 return e; 413 } 414 } 415 } 416 stress4(); 417 418} 419stress(); 420 421 422// With block as the last(!) statement in global code. 423with ({}) { debugger; }