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: --allow-natives-syntax --harmony-scoping
29// Test functionality of block scopes.
30
31"use strict";
32
33// Hoisting of var declarations.
34function f1() {
35  {
36    var x = 1;
37    var y;
38  }
39  assertEquals(1, x)
40  assertEquals(undefined, y)
41}
42for (var j = 0; j < 5; ++j) f1();
43%OptimizeFunctionOnNextCall(f1);
44f1();
45assertTrue(%GetOptimizationStatus(f1) != 2);
46
47// Dynamic lookup in and through block contexts.
48function f2(one) {
49  var x = one + 1;
50  let y = one + 2;
51  const u = one + 4;
52  {
53    let z = one + 3;
54    const v = one + 5;
55    assertEquals(1, eval('one'));
56    assertEquals(2, eval('x'));
57    assertEquals(3, eval('y'));
58    assertEquals(4, eval('z'));
59    assertEquals(5, eval('u'));
60    assertEquals(6, eval('v'));
61  }
62}
63
64f2(1);
65
66// Lookup in and through block contexts.
67function f3(one) {
68  var x = one + 1;
69  let y = one + 2;
70  const u = one + 4;
71  {
72    let z = one + 3;
73    const v = one + 5;
74    assertEquals(1, one);
75    assertEquals(2, x);
76    assertEquals(3, y);
77    assertEquals(4, z);
78    assertEquals(5, u);
79    assertEquals(6, v);
80  }
81}
82for (var j = 0; j < 5; ++j) f3(1);
83%OptimizeFunctionOnNextCall(f3);
84f3(1);
85assertTrue(%GetOptimizationStatus(f3) != 2);
86
87
88
89// Dynamic lookup from closure.
90function f4(one) {
91  var x = one + 1;
92  let y = one + 2;
93  const u = one + 4;
94  {
95    let z = one + 3;
96    const v = one + 5;
97    function f() {
98      assertEquals(1, eval('one'));
99      assertEquals(2, eval('x'));
100      assertEquals(3, eval('y'));
101      assertEquals(4, eval('z'));
102      assertEquals(5, eval('u'));
103      assertEquals(6, eval('v'));
104    };
105  }
106}
107f4(1);
108
109
110// Lookup from closure.
111function f5(one) {
112  var x = one + 1;
113  let y = one + 2;
114  const u = one + 4;
115  {
116    let z = one + 3;
117    const v = one + 5;
118    function f() {
119      assertEquals(1, one);
120      assertEquals(2, x);
121      assertEquals(3, y);
122      assertEquals(4, z);
123      assertEquals(5, u);
124      assertEquals(6, v);
125    };
126  }
127}
128f5(1);
129
130
131// Return from block.
132function f6() {
133  let x = 1;
134  const u = 3;
135  {
136    let y = 2;
137    const v = 4;
138    return x + y;
139  }
140}
141assertEquals(3, f6(6));
142
143
144// Variable shadowing and lookup.
145function f7(a) {
146  let b = 1;
147  var c = 1;
148  var d = 1;
149  const e = 1;
150  { // let variables shadowing argument, let, const and var variables
151    let a = 2;
152    let b = 2;
153    let c = 2;
154    let e = 2;
155    assertEquals(2,a);
156    assertEquals(2,b);
157    assertEquals(2,c);
158    assertEquals(2,e);
159  }
160  { // const variables shadowing argument, let, const and var variables
161    const a = 2;
162    const b = 2;
163    const c = 2;
164    const e = 2;
165    assertEquals(2,a);
166    assertEquals(2,b);
167    assertEquals(2,c);
168    assertEquals(2,e);
169  }
170  try {
171    throw 'stuff1';
172  } catch (a) {
173    assertEquals('stuff1',a);
174    // catch variable shadowing argument
175    a = 2;
176    assertEquals(2,a);
177    {
178      // let variable shadowing catch variable
179      let a = 3;
180      assertEquals(3,a);
181      try {
182        throw 'stuff2';
183      } catch (a) {
184        assertEquals('stuff2',a);
185        // catch variable shadowing let variable
186        a = 4;
187        assertEquals(4,a);
188      }
189      assertEquals(3,a);
190    }
191    assertEquals(2,a);
192  }
193  try {
194    throw 'stuff3';
195  } catch (c) {
196    // catch variable shadowing var variable
197    assertEquals('stuff3',c);
198    {
199      // const variable shadowing catch variable
200      const c = 3;
201      assertEquals(3,c);
202    }
203    assertEquals('stuff3',c);
204    try {
205      throw 'stuff4';
206    } catch(c) {
207      assertEquals('stuff4',c);
208      // catch variable shadowing catch variable
209      c = 3;
210      assertEquals(3,c);
211    }
212    (function(c) {
213      // argument shadowing catch variable
214      c = 3;
215      assertEquals(3,c);
216    })();
217    assertEquals('stuff3', c);
218    (function() {
219      // var variable shadowing catch variable
220      var c = 3;
221    })();
222    assertEquals('stuff3', c);
223    c = 2;
224  }
225  assertEquals(1,c);
226  (function(a,b,c,e) {
227    // arguments shadowing argument, let, const and var variable
228    a = 2;
229    b = 2;
230    c = 2;
231    e = 2;
232    assertEquals(2,a);
233    assertEquals(2,b);
234    assertEquals(2,c);
235    assertEquals(2,e);
236    // var variable shadowing var variable
237    var d = 2;
238  })(1,1);
239  assertEquals(1,a);
240  assertEquals(1,b);
241  assertEquals(1,c);
242  assertEquals(1,d);
243  assertEquals(1,e);
244}
245f7(1);
246
247
248// Ensure let and const variables are block local
249// and var variables function local.
250function f8() {
251  var let_accessors = [];
252  var var_accessors = [];
253  var const_accessors = [];
254  for (var i = 0; i < 10; i++) {
255    let x = i;
256    var y = i;
257    const z = i;
258    let_accessors[i] = function() { return x; }
259    var_accessors[i] = function() { return y; }
260    const_accessors[i] = function() { return z; }
261  }
262  for (var j = 0; j < 10; j++) {
263    y = j + 10;
264    assertEquals(j, let_accessors[j]());
265    assertEquals(y, var_accessors[j]());
266    assertEquals(j, const_accessors[j]());
267  }
268}
269f8();
270