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