1014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Copyright 2015 the V8 project authors. All rights reserved.
2014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// found in the LICENSE file.
4014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch// Flags: --harmony-do-expressions --allow-natives-syntax
6014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
7014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfunction returnValue(v) { return v; }
8014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfunction MyError() {}
9014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvar global = this;
10014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
11014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfunction TestBasic() {
12014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Looping and lexical declarations
13014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  assertEquals(512, returnValue(do {
14014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    let n = 2;
15014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (let i = 0; i < 4; i++) n <<= 2;
16014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }));
17014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
18014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Strings do the right thing
19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  assertEquals("spooky halloween", returnValue(do {
20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    "happy halloween".replace('happy', 'spooky');
21014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }));
22014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Do expressions with no completion produce an undefined value
24014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  assertEquals(undefined, returnValue(do {}));
25014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  assertEquals(undefined, returnValue(do { var x = 99; }));
26014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  assertEquals(undefined, returnValue(do { function f() {}; }));
27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  assertEquals(undefined, returnValue(do { let z = 33; }));
28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Propagation of exception
30014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  assertThrows(function() {
31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    (do {
32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      throw new MyError();
33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      "potatoes";
34014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    });
35014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }, MyError);
36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  assertThrows(function() {
38014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return do {
39014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      throw new MyError();
40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      "potatoes";
41014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    };
42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }, MyError);
43014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
44014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Return value within do-block overrides `return |do-expression|`
45014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  assertEquals("inner-return", (function() {
46014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return "outer-return" + do {
47014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return "inner-return";
48014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      "";
49014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    };
50014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  })());
51014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
52014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var count = 0, n = 1;
53014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Breaking out |do-expression|
54014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  assertEquals(3, (function() {
55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (var i = 0; i < 10; ++i) (count += 2 * do { if (i === 3) break; ++n });
56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return i;
57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  })());
58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // (2 * 2) + (2 * 3) + (2 * 4)
59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  assertEquals(18, count);
60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Continue in |do-expression|
62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  count = 0, n = 1;
63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  assertEquals([1, 3, 5, 7, 9], (function() {
64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    var values = [];
65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (var i = 0; i < 10; ++i) {
66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      count += 2 * (do {
67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if ((i & 1) === 0) continue;
68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        values.push(i);
69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        ++n;
70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }) + 1;
71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // (2*2) + 1 + (2*3) + 1 + (2*4) + 1 + (2*5) + 1 + (2*6) + 1
73014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return values;
74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  })());
75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  assertEquals(count, 45);
76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  assertThrows("(do { break; });", SyntaxError);
78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  assertThrows("(do { continue; });", SyntaxError);
79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Real-world use case for desugaring
81014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var array = [1, 2, 3, 4, 5], iterable = [6, 7, 8,9];
82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  assertEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], do {
83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (var element of iterable) array.push(element);
84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    array;
85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  });
86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Nested do-expressions
88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  assertEquals(125, do { (do { (do { 5 * 5 * 5 }) }) });
89014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
90014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Directives are not honoured
91014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  (do {
92014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    "use strict";
93014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    foo = 80;
94014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    assertEquals(foo, 80);
95014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  });
96014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Non-empty operand stack testing
98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var O = {
99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    method1() {
100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      let x = 256;
101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return x + do {
102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        for (var i = 0; i < 4; ++i) x += i;
103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } + 17;
104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    },
105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    method2() {
106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      let x = 256;
107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      this.reset();
108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return x + do {
109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        for (var i = 0; i < this.length(); ++i) x += this.index() * 2;
110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      };
111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    },
112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    _index: 0,
113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    index() {
114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return ++this._index;
115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    },
116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    _length: 4,
117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    length() { return this._length; },
118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    reset() { this._index = 0; }
119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  };
120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  assertEquals(535, O["method" + do { 1 } + ""]());
121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  assertEquals(532, O["method" + do { ({ valueOf() { return "2"; } }); }]());
122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  assertEquals(532, O[
123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      do { let s = ""; for (let c of "method") s += c; } + "2"]());
124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTestBasic();
126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfunction TestDeoptimization1() {
129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  function f(v) {
130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return 88 + do {
131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      v.a * v.b + v.c;
132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    };
133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var o1 = {};
136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  o1.a = 10;
137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  o1.b = 5;
138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  o1.c = 50;
139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var o2 = {};
141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  o2.c = 100;
142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  o2.a = 10;
143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  o2.b = 10;
144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  assertEquals(188, f(o1));
146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  assertEquals(188, f(o1));
147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  %OptimizeFunctionOnNextCall(f);
148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  assertEquals(188, f(o1));
149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  assertOptimized(f);
150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  assertEquals(288, f(o2));
151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  assertUnoptimized(f);
152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  assertEquals(288, f(o2));
153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTestDeoptimization1();
155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfunction TestInParameterInitializers() {
158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var first_name = "George";
159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var last_name = "Jetson";
160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  function fn1(name = do { first_name + " " + last_name }) {
161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return name;
162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  assertEquals("George Jetson", fn1());
164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var _items = [1, 2, 3, NaN, 4, 5];
166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  function fn2(items = do {
167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    let items = [];
168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (var el of _items) {
169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (el !== el) {
170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        items;
171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      items.push(el), items;
174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }) {
176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return items;
177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  assertEquals([1, 2, 3], fn2());
179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  function thrower() { throw new MyError(); }
181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  function fn3(exception = do {  try { thrower(); } catch (e) { e } }) {
182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return exception;
183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  assertDoesNotThrow(fn3);
185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  assertInstanceof(fn3(), MyError);
186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  function fn4(exception = do { throw new MyError() }) {}
188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  function catcher(fn) {
189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    try {
190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      fn();
191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      assertUnreachable("fn() initializer should throw");
192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } catch (e) {
193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      assertInstanceof(e, MyError);
194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  catcher(fn4);
197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTestInParameterInitializers();
199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfunction TestWithEval() {
202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  (function sloppy1() {
203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    assertEquals(do { eval("var x = 5"), x }, 5);
204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    assertEquals(x, 5);
205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  })();
206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  assertThrows(function strict1() {
208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    "use strict";
209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    (do { eval("var x = 5"), x }, 5);
210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }, ReferenceError);
211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  assertThrows(function strict2() {
213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    (do { eval("'use strict'; var x = 5"), x }, 5);
214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }, ReferenceError);
215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTestWithEval();
217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfunction TestHoisting() {
220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  (do { var a = 1; });
221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  assertEquals(a, 1);
222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  assertEquals(global.a, undefined);
223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  (do {
225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (let it of [1, 2, 3, 4, 5]) {
226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      var b = it;
227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  });
229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  assertEquals(b, 5);
230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  assertEquals(global.b, undefined);
231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  {
233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    let x = 1
234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // TODO(caitp): ensure VariableStatements in |do-expressions| in parameter
236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // initializers, are evaluated in the same VariableEnvironment as they would
237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // be for eval().
238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // function f1(a = do { var x = 2 }, b = x) { return b }
239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // assertEquals(1, f1())
240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // function f2(a = x, b = do { var x = 2 }) { return a }
242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // assertEquals(1, f2())
243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    function f3({a = do { var x = 2 }, b = x}) { return b }
245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    assertEquals(2, f3({}))
246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    function f4({a = x, b = do { var x = 2 }}) { return b }
248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    assertEquals(undefined, f4({}))
249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    function f5(a = do { var y = 0 }) {}
251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    assertThrows(() => y, ReferenceError)
252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // TODO(caitp): Always block-scope function declarations in |do| expressions
255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //(do {
256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //  assertEquals(true, inner_func());
257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //  function inner_func() { return true; }
258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //});
259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //assertThrows(function() { return innerFunc(); }, ReferenceError);
260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTestHoisting();
262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// v8:4661
265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfunction tryFinallySimple() { (do { try {} finally {} }); }
267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochtryFinallySimple();
268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochtryFinallySimple();
269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochtryFinallySimple();
270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochtryFinallySimple();
271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvar finallyRanCount = 0;
273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfunction tryFinallyDoExpr() {
274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return (do {
275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    try {
276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      throw "BOO";
277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } catch (e) {
278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      "Caught: " + e + " (" + finallyRanCount + ")"
279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } finally {
280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ++finallyRanCount;
281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  });
283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochassertEquals("Caught: BOO (0)", tryFinallyDoExpr());
285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochassertEquals(1, finallyRanCount);
286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochassertEquals("Caught: BOO (1)", tryFinallyDoExpr());
287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochassertEquals(2, finallyRanCount);
288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochassertEquals("Caught: BOO (2)", tryFinallyDoExpr());
289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochassertEquals(3, finallyRanCount);
290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochassertEquals("Caught: BOO (3)", tryFinallyDoExpr());
291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochassertEquals(4, finallyRanCount);
292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfunction TestOSR() {
295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  var numbers = do {
296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    let nums = [];
297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (let i = 0; i < 1000; ++i) {
298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      let value = (Math.random() * 100) | 0;
299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      nums.push(value === 0 ? 1 : value), nums;
300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  };
302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  assertEquals(numbers.length, 1000);
303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfor (var i = 0; i < 64; ++i) TestOSR();
306