blob: 0308edde96a37dd0ca0675196fb7d4501a550d2f [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// 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
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 class a { static foo() { return one + 6; } }
53 {
54 let z = one + 3;
55 const v = one + 5;
56 class b { static foo() { return one + 7; } }
57 assertEquals(1, eval('one'));
58 assertEquals(2, eval('x'));
59 assertEquals(3, eval('y'));
60 assertEquals(4, eval('z'));
61 assertEquals(5, eval('u'));
62 assertEquals(6, eval('v'));
63 assertEquals(7, eval('a.foo()'));
64 assertEquals(8, eval('b.foo()'));
65 }
66}
67
68f2(1);
69
70// Lookup in and through block contexts.
71function f3(one) {
72 var x = one + 1;
73 let y = one + 2;
74 const u = one + 4;
75 class a { static foo() { return one + 6; } }
76 {
77 let z = one + 3;
78 const v = one + 5;
79 class b { static foo() { return one + 7; } }
80 assertEquals(1, one);
81 assertEquals(2, x);
82 assertEquals(3, y);
83 assertEquals(4, z);
84 assertEquals(5, u);
85 assertEquals(6, v);
86 assertEquals(7, a.foo());
87 assertEquals(8, b.foo());
88 }
89}
90for (var j = 0; j < 5; ++j) f3(1);
91%OptimizeFunctionOnNextCall(f3);
92f3(1);
93
94
95
96// Dynamic lookup from closure.
97function f4(one) {
98 var x = one + 1;
99 let y = one + 2;
100 const u = one + 4;
101 class a { static foo() { return one + 6; } }
102 {
103 let z = one + 3;
104 const v = one + 5;
105 class b { static foo() { return one + 7; } }
106 function f() {
107 assertEquals(1, eval('one'));
108 assertEquals(2, eval('x'));
109 assertEquals(3, eval('y'));
110 assertEquals(4, eval('z'));
111 assertEquals(5, eval('u'));
112 assertEquals(6, eval('v'));
113 assertEquals(7, eval('a.foo()'));
114 assertEquals(8, eval('b.foo()'));
115 }
116 f();
117 }
118}
119f4(1);
120
121
122// Lookup from closure.
123function f5(one) {
124 var x = one + 1;
125 let y = one + 2;
126 const u = one + 4;
127 class a { static foo() { return one + 6; } }
128 {
129 let z = one + 3;
130 const v = one + 5;
131 class b { static foo() { return one + 7; } }
132 function f() {
133 assertEquals(1, one);
134 assertEquals(2, x);
135 assertEquals(3, y);
136 assertEquals(4, z);
137 assertEquals(5, u);
138 assertEquals(6, v);
139 assertEquals(7, a.foo());
140 assertEquals(8, b.foo());
141 }
142 f();
143 }
144}
145f5(1);
146
147
148// Return from block.
149function f6() {
150 let x = 1;
151 const u = 3;
152 {
153 let y = 2;
154 const v = 4;
155 return x + y;
156 }
157}
158assertEquals(3, f6(6));
159
160
161// Variable shadowing and lookup.
162function f7(a) {
163 let b = 1;
164 var c = 1;
165 var d = 1;
166 const e = 1;
167 class f { static foo() { return 1; } }
168 { // let variables shadowing argument, let, const, class and var variables
169 let a = 2;
170 let b = 2;
171 let c = 2;
172 let e = 2;
173 let f = 2;
174 assertEquals(2,a);
175 assertEquals(2,b);
176 assertEquals(2,c);
177 assertEquals(2,e);
178 assertEquals(2,f);
179 }
180 { // const variables shadowing argument, let, const and var variables
181 const a = 2;
182 const b = 2;
183 const c = 2;
184 const e = 2;
185 const f = 2;
186 assertEquals(2,a);
187 assertEquals(2,b);
188 assertEquals(2,c);
189 assertEquals(2,e);
190 assertEquals(2,f);
191 }
192 { // class variables shadowing argument, let, const and var variables
193 class a { static foo() { return 2; } }
194 class b { static foo() { return 2; } }
195 class c { static foo() { return 2; } }
196 class d { static foo() { return 2; } }
197 class e { static foo() { return 2; } }
198 class f { static foo() { return 2; } }
199 assertEquals(2,a.foo());
200 assertEquals(2,b.foo());
201 assertEquals(2,c.foo());
202 assertEquals(2,e.foo());
203 assertEquals(2,f.foo());
204 }
205 try {
206 throw 'stuff1';
207 } catch (a) {
208 assertEquals('stuff1',a);
209 // catch variable shadowing argument
210 a = 2;
211 assertEquals(2,a);
212 {
213 // let variable shadowing catch variable
214 let a = 3;
215 assertEquals(3,a);
216 try {
217 throw 'stuff2';
218 } catch (a) {
219 assertEquals('stuff2',a);
220 // catch variable shadowing let variable
221 a = 4;
222 assertEquals(4,a);
223 }
224 assertEquals(3,a);
225 }
226 assertEquals(2,a);
227 }
228 try {
229 throw 'stuff3';
230 } catch (c) {
231 // catch variable shadowing var variable
232 assertEquals('stuff3',c);
233 {
234 // const variable shadowing catch variable
235 const c = 3;
236 assertEquals(3,c);
237 }
238 assertEquals('stuff3',c);
239 try {
240 throw 'stuff4';
241 } catch(c) {
242 assertEquals('stuff4',c);
243 // catch variable shadowing catch variable
244 c = 3;
245 assertEquals(3,c);
246 }
247 (function(c) {
248 // argument shadowing catch variable
249 c = 3;
250 assertEquals(3,c);
251 })();
252 assertEquals('stuff3', c);
253 (function() {
254 // var variable shadowing catch variable
255 var c = 3;
256 })();
257 assertEquals('stuff3', c);
258 c = 2;
259 }
260 assertEquals(1,c);
261 (function(a,b,c,e,f) {
262 // arguments shadowing argument, let, const, class and var variable
263 a = 2;
264 b = 2;
265 c = 2;
266 e = 2;
267 f = 2;
268 assertEquals(2,a);
269 assertEquals(2,b);
270 assertEquals(2,c);
271 assertEquals(2,e);
272 assertEquals(2,f);
273 // var variable shadowing var variable
274 var d = 2;
275 })(1,1);
276 assertEquals(1,a);
277 assertEquals(1,b);
278 assertEquals(1,c);
279 assertEquals(1,d);
280 assertEquals(1,e);
281 assertEquals(1,f.foo());
282}
283f7(1);
284
285
286// Ensure let and const variables are block local
287// and var variables function local.
288function f8() {
289 var let_accessors = [];
290 var var_accessors = [];
291 var const_accessors = [];
292 var class_accessors = [];
293 for (var i = 0; i < 10; i++) {
294 let x = i;
295 var y = i;
296 const z = i;
297 class a { static foo() { return x; } }
298 let_accessors[i] = function() { return x; }
299 var_accessors[i] = function() { return y; }
300 const_accessors[i] = function() { return z; }
301 class_accessors[i] = function() { return a; }
302 }
303 for (var j = 0; j < 10; j++) {
304 y = j + 10;
305 assertEquals(j, let_accessors[j]());
306 assertEquals(y, var_accessors[j]());
307 assertEquals(j, const_accessors[j]());
308 assertEquals(j, class_accessors[j]().foo());
309 }
310}
311f8();