blob: f7f95da88c99592e792e9e6b45b13d2ce4b1c545 [file] [log] [blame]
Steve Block1e0659c2011-05-24 12:43:12 +01001// 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
28function CheckStrictMode(code, exception) {
29 assertDoesNotThrow(code);
30 assertThrows("'use strict';\n" + code, exception);
31 assertThrows('"use strict";\n' + code, exception);
32 assertDoesNotThrow("\
33 function outer() {\
34 function inner() {\n"
35 + code +
36 "\n}\
37 }");
38 assertThrows("\
39 function outer() {\
40 'use strict';\
41 function inner() {\n"
42 + code +
43 "\n}\
44 }", exception);
45}
46
47function CheckFunctionConstructorStrictMode() {
48 var args = [];
49 for (var i = 0; i < arguments.length; i ++) {
50 args[i] = arguments[i];
51 }
52 // Create non-strict function. No exception.
53 args[arguments.length] = "";
54 assertDoesNotThrow(function() {
55 Function.apply(this, args);
56 });
57 // Create strict mode function. Exception expected.
58 args[arguments.length] = "'use strict';";
59 assertThrows(function() {
60 Function.apply(this, args);
61 }, SyntaxError);
62}
63
64// Incorrect 'use strict' directive.
65(function UseStrictEscape() {
66 "use\\x20strict";
67 with ({}) {};
68})();
69
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000070// Incorrectly place 'use strict' directive.
71assertThrows("function foo (x) 'use strict'; {}", SyntaxError);
72
Steve Block1e0659c2011-05-24 12:43:12 +010073// 'use strict' in non-directive position.
74(function UseStrictNonDirective() {
75 void(0);
76 "use strict";
77 with ({}) {};
78})();
79
80// Multiple directives, including "use strict".
81assertThrows('\
82"directive 1";\
83"another directive";\
84"use strict";\
85"directive after strict";\
86"and one more";\
87with({}) {}', SyntaxError);
88
89// 'with' disallowed in strict mode.
90CheckStrictMode("with({}) {}", SyntaxError);
91
92// Function named 'eval'.
93CheckStrictMode("function eval() {}", SyntaxError);
94
95// Function named 'arguments'.
96CheckStrictMode("function arguments() {}", SyntaxError);
97
98// Function parameter named 'eval'.
99CheckStrictMode("function foo(a, b, eval, c, d) {}", SyntaxError);
100
101// Function parameter named 'arguments'.
102CheckStrictMode("function foo(a, b, arguments, c, d) {}", SyntaxError);
103
104// Property accessor parameter named 'eval'.
105CheckStrictMode("var o = { set foo(eval) {} }", SyntaxError);
106
107// Property accessor parameter named 'arguments'.
108CheckStrictMode("var o = { set foo(arguments) {} }", SyntaxError);
109
110// Duplicate function parameter name.
111CheckStrictMode("function foo(a, b, c, d, b) {}", SyntaxError);
112
113// Function constructor: eval parameter name.
114CheckFunctionConstructorStrictMode("eval");
115
116// Function constructor: arguments parameter name.
117CheckFunctionConstructorStrictMode("arguments");
118
119// Function constructor: duplicate parameter name.
120CheckFunctionConstructorStrictMode("a", "b", "c", "b");
121CheckFunctionConstructorStrictMode("a,b,c,b");
122
123// catch(eval)
124CheckStrictMode("try{}catch(eval){};", SyntaxError);
125
126// catch(arguments)
127CheckStrictMode("try{}catch(arguments){};", SyntaxError);
128
129// var eval
130CheckStrictMode("var eval;", SyntaxError);
131
132// var arguments
133CheckStrictMode("var arguments;", SyntaxError);
134
135// Strict mode applies to the function in which the directive is used..
136assertThrows('\
137function foo(eval) {\
138 "use strict";\
139}', SyntaxError);
140
141// Strict mode doesn't affect the outer stop of strict code.
142(function NotStrict(eval) {
143 function Strict() {
144 "use strict";
145 }
146 with ({}) {};
147})();
148
149// Octal literal
150CheckStrictMode("var x = 012");
151CheckStrictMode("012");
152CheckStrictMode("'Hello octal\\032'");
153CheckStrictMode("function octal() { return 012; }");
154CheckStrictMode("function octal() { return '\\032'; }");
155
156(function ValidEscape() {
157 "use strict";
158 var x = '\0';
159 var y = "\0";
160})();
161
162// Octal before "use strict"
163assertThrows('\
164 function strict() {\
165 "octal\\032directive";\
166 "use strict";\
167 }', SyntaxError);
168
Steve Block1e0659c2011-05-24 12:43:12 +0100169(function StrictModeNonDuplicate() {
170 "use strict";
171 var x = { 123 : 1, "0123" : 2 };
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100172 var x = {
173 123: 1,
174 '123.00000000000000000000000000000000000000000000000000000000000000000001':
175 2
176 };
Steve Block1e0659c2011-05-24 12:43:12 +0100177})();
178
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000179// Duplicate data properties are allowed in ES6
180(function StrictModeDuplicateES6() {
181 'use strict';
182 var x = {
183 123: 1,
184 123.00000000000000000000000000000000000000000000000000000000000000000001: 2
185 };
186 var x = { dupe : 1, nondupe: 3, dupe : 2 };
187 var x = { '1234' : 1, '2345' : 2, '1234' : 3 };
188 var x = { '1234' : 1, '2345' : 2, 1234 : 3 };
189 var x = { 3.14 : 1, 2.71 : 2, 3.14 : 3 };
190 var x = { 3.14 : 1, '3.14' : 2 };
Steve Block1e0659c2011-05-24 12:43:12 +0100191
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000192 var x = { get foo() { }, get foo() { } };
193 var x = { get foo(){}, get 'foo'(){}};
194 var x = { get 12(){}, get '12'(){}};
Steve Block1e0659c2011-05-24 12:43:12 +0100195
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000196 // Two setters
197 var x = { set foo(v) { }, set foo(v) { } };
198 var x = { set foo(v) { }, set 'foo'(v) { } };
199 var x = { set 13(v) { }, set '13'(v) { } };
Steve Block1e0659c2011-05-24 12:43:12 +0100200
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000201 // Setter and data
202 var x = { foo: 'data', set foo(v) { } };
203 var x = { set foo(v) { }, foo: 'data' };
204 var x = { foo: 'data', set 'foo'(v) { } };
205 var x = { set foo(v) { }, 'foo': 'data' };
206 var x = { 'foo': 'data', set foo(v) { } };
207 var x = { set 'foo'(v) { }, foo: 'data' };
208 var x = { 'foo': 'data', set 'foo'(v) { } };
209 var x = { set 'foo'(v) { }, 'foo': 'data' };
210 var x = { 12: 1, set '12'(v){}};
211 var x = { 12: 1, set 12(v){}};
212 var x = { '12': 1, set '12'(v){}};
213 var x = { '12': 1, set 12(v){}};
214
215 // Getter and data
216 var x = { foo: 'data', get foo() { } };
217 var x = { get foo() { }, foo: 'data' };
218 var x = { 'foo': 'data', get foo() { } };
219 var x = { get 'foo'() { }, 'foo': 'data' };
220 var x = { '12': 1, get '12'(){}};
221 var x = { '12': 1, get 12(){}};
222})();
Steve Block1e0659c2011-05-24 12:43:12 +0100223
224// Assignment to eval or arguments
225CheckStrictMode("function strict() { eval = undefined; }", SyntaxError);
226CheckStrictMode("function strict() { arguments = undefined; }", SyntaxError);
227CheckStrictMode("function strict() { print(eval = undefined); }", SyntaxError);
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100228CheckStrictMode("function strict() { print(arguments = undefined); }",
229 SyntaxError);
Steve Block1e0659c2011-05-24 12:43:12 +0100230CheckStrictMode("function strict() { var x = eval = undefined; }", SyntaxError);
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100231CheckStrictMode("function strict() { var x = arguments = undefined; }",
232 SyntaxError);
Steve Block1e0659c2011-05-24 12:43:12 +0100233
234// Compound assignment to eval or arguments
235CheckStrictMode("function strict() { eval *= undefined; }", SyntaxError);
236CheckStrictMode("function strict() { arguments /= undefined; }", SyntaxError);
237CheckStrictMode("function strict() { print(eval %= undefined); }", SyntaxError);
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100238CheckStrictMode("function strict() { print(arguments %= undefined); }",
239 SyntaxError);
240CheckStrictMode("function strict() { var x = eval += undefined; }",
241 SyntaxError);
242CheckStrictMode("function strict() { var x = arguments -= undefined; }",
243 SyntaxError);
Steve Block1e0659c2011-05-24 12:43:12 +0100244CheckStrictMode("function strict() { eval <<= undefined; }", SyntaxError);
245CheckStrictMode("function strict() { arguments >>= undefined; }", SyntaxError);
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100246CheckStrictMode("function strict() { print(eval >>>= undefined); }",
247 SyntaxError);
248CheckStrictMode("function strict() { print(arguments &= undefined); }",
249 SyntaxError);
250CheckStrictMode("function strict() { var x = eval ^= undefined; }",
251 SyntaxError);
252CheckStrictMode("function strict() { var x = arguments |= undefined; }",
253 SyntaxError);
Steve Block1e0659c2011-05-24 12:43:12 +0100254
255// Postfix increment with eval or arguments
256CheckStrictMode("function strict() { eval++; }", SyntaxError);
257CheckStrictMode("function strict() { arguments++; }", SyntaxError);
258CheckStrictMode("function strict() { print(eval++); }", SyntaxError);
259CheckStrictMode("function strict() { print(arguments++); }", SyntaxError);
260CheckStrictMode("function strict() { var x = eval++; }", SyntaxError);
261CheckStrictMode("function strict() { var x = arguments++; }", SyntaxError);
262
263// Postfix decrement with eval or arguments
264CheckStrictMode("function strict() { eval--; }", SyntaxError);
265CheckStrictMode("function strict() { arguments--; }", SyntaxError);
266CheckStrictMode("function strict() { print(eval--); }", SyntaxError);
267CheckStrictMode("function strict() { print(arguments--); }", SyntaxError);
268CheckStrictMode("function strict() { var x = eval--; }", SyntaxError);
269CheckStrictMode("function strict() { var x = arguments--; }", SyntaxError);
270
271// Prefix increment with eval or arguments
272CheckStrictMode("function strict() { ++eval; }", SyntaxError);
273CheckStrictMode("function strict() { ++arguments; }", SyntaxError);
274CheckStrictMode("function strict() { print(++eval); }", SyntaxError);
275CheckStrictMode("function strict() { print(++arguments); }", SyntaxError);
276CheckStrictMode("function strict() { var x = ++eval; }", SyntaxError);
277CheckStrictMode("function strict() { var x = ++arguments; }", SyntaxError);
278
279// Prefix decrement with eval or arguments
280CheckStrictMode("function strict() { --eval; }", SyntaxError);
281CheckStrictMode("function strict() { --arguments; }", SyntaxError);
282CheckStrictMode("function strict() { print(--eval); }", SyntaxError);
283CheckStrictMode("function strict() { print(--arguments); }", SyntaxError);
284CheckStrictMode("function strict() { var x = --eval; }", SyntaxError);
285CheckStrictMode("function strict() { var x = --arguments; }", SyntaxError);
286
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100287// Delete of an unqualified identifier
288CheckStrictMode("delete unqualified;", SyntaxError);
289CheckStrictMode("function strict() { delete unqualified; }", SyntaxError);
290CheckStrictMode("function function_name() { delete function_name; }",
291 SyntaxError);
292CheckStrictMode("function strict(parameter) { delete parameter; }",
293 SyntaxError);
294CheckStrictMode("function strict() { var variable; delete variable; }",
295 SyntaxError);
296CheckStrictMode("var variable; delete variable;", SyntaxError);
297
298(function TestStrictDelete() {
299 "use strict";
300 // "delete this" is allowed in strict mode and should work.
301 function strict_delete() { delete this; }
302 strict_delete();
303})();
304
Steve Block1e0659c2011-05-24 12:43:12 +0100305// Prefix unary operators other than delete, ++, -- are valid in strict mode
306(function StrictModeUnaryOperators() {
307 "use strict";
308 var x = [void eval, typeof eval, +eval, -eval, ~eval, !eval];
309 var y = [void arguments, typeof arguments,
310 +arguments, -arguments, ~arguments, !arguments];
311})();
312
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000313// 7.6.1.2 Future Reserved Words in strict mode
314var future_strict_reserved_words = [
Steve Block1e0659c2011-05-24 12:43:12 +0100315 "implements",
316 "interface",
317 "let",
318 "package",
319 "private",
320 "protected",
321 "public",
322 "static",
323 "yield" ];
324
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000325function testFutureStrictReservedWord(word) {
Steve Block1e0659c2011-05-24 12:43:12 +0100326 // Simple use of each reserved word
327 CheckStrictMode("var " + word + " = 1;", SyntaxError);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000328 CheckStrictMode("typeof (" + word + ");", SyntaxError);
Steve Block1e0659c2011-05-24 12:43:12 +0100329
330 // object literal properties
331 eval("var x = { " + word + " : 42 };");
332 eval("var x = { get " + word + " () {} };");
333 eval("var x = { set " + word + " (value) {} };");
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000334 eval("var x = { get " + word + " () { 'use strict'; } };");
335 eval("var x = { set " + word + " (value) { 'use strict'; } };");
Steve Block1e0659c2011-05-24 12:43:12 +0100336
337 // object literal with string literal property names
338 eval("var x = { '" + word + "' : 42 };");
339 eval("var x = { get '" + word + "' () { } };");
340 eval("var x = { set '" + word + "' (value) { } };");
341 eval("var x = { get '" + word + "' () { 'use strict'; } };");
342 eval("var x = { set '" + word + "' (value) { 'use strict'; } };");
343
344 // Function names and arguments, strict and non-strict contexts
345 CheckStrictMode("function " + word + " () {}", SyntaxError);
346 CheckStrictMode("function foo (" + word + ") {}", SyntaxError);
347 CheckStrictMode("function foo (" + word + ", " + word + ") {}", SyntaxError);
348 CheckStrictMode("function foo (a, " + word + ") {}", SyntaxError);
349 CheckStrictMode("function foo (" + word + ", a) {}", SyntaxError);
350 CheckStrictMode("function foo (a, " + word + ", b) {}", SyntaxError);
351 CheckStrictMode("var foo = function (" + word + ") {}", SyntaxError);
352
353 // Function names and arguments when the body is strict
354 assertThrows("function " + word + " () { 'use strict'; }", SyntaxError);
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100355 assertThrows("function foo (" + word + ", " + word + ") { 'use strict'; }",
356 SyntaxError);
Steve Block1e0659c2011-05-24 12:43:12 +0100357 assertThrows("function foo (a, " + word + ") { 'use strict'; }", SyntaxError);
358 assertThrows("function foo (" + word + ", a) { 'use strict'; }", SyntaxError);
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100359 assertThrows("function foo (a, " + word + ", b) { 'use strict'; }",
360 SyntaxError);
361 assertThrows("var foo = function (" + word + ") { 'use strict'; }",
362 SyntaxError);
Steve Block1e0659c2011-05-24 12:43:12 +0100363
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000364 // setter parameter when the body is strict
365 CheckStrictMode("var x = { set foo(" + word + ") {} };", SyntaxError);
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100366 assertThrows("var x = { set foo(" + word + ") { 'use strict'; } };",
367 SyntaxError);
Steve Block1e0659c2011-05-24 12:43:12 +0100368}
369
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000370for (var i = 0; i < future_strict_reserved_words.length; i++) {
371 testFutureStrictReservedWord(future_strict_reserved_words[i]);
Steve Block1e0659c2011-05-24 12:43:12 +0100372}
373
Ben Murdoch8b112d22011-06-08 16:22:53 +0100374function testAssignToUndefined(test, should_throw) {
Steve Block1e0659c2011-05-24 12:43:12 +0100375 try {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100376 test();
Steve Block1e0659c2011-05-24 12:43:12 +0100377 } catch (e) {
378 assertTrue(should_throw, "strict mode");
379 assertInstanceof(e, ReferenceError, "strict mode");
380 return;
381 }
382 assertFalse(should_throw, "strict mode");
383}
384
Steve Block1e0659c2011-05-24 12:43:12 +0100385function repeat(n, f) {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100386 for (var i = 0; i < n; i ++) { f(); }
Steve Block1e0659c2011-05-24 12:43:12 +0100387}
388
Ben Murdoch8b112d22011-06-08 16:22:53 +0100389function assignToUndefined() {
390 "use strict";
391 possibly_undefined_variable_for_strict_mode_test = "should throw?";
392}
393
394testAssignToUndefined(assignToUndefined, true);
395testAssignToUndefined(assignToUndefined, true);
396testAssignToUndefined(assignToUndefined, true);
397
Steve Block1e0659c2011-05-24 12:43:12 +0100398possibly_undefined_variable_for_strict_mode_test = "value";
Ben Murdoch8b112d22011-06-08 16:22:53 +0100399
400testAssignToUndefined(assignToUndefined, false);
401testAssignToUndefined(assignToUndefined, false);
402testAssignToUndefined(assignToUndefined, false);
403
Steve Block1e0659c2011-05-24 12:43:12 +0100404delete possibly_undefined_variable_for_strict_mode_test;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100405
406testAssignToUndefined(assignToUndefined, true);
407testAssignToUndefined(assignToUndefined, true);
408testAssignToUndefined(assignToUndefined, true);
409
410repeat(10, function() { testAssignToUndefined(assignToUndefined, true); });
411possibly_undefined_variable_for_strict_mode_test = "value";
412repeat(10, function() { testAssignToUndefined(assignToUndefined, false); });
413delete possibly_undefined_variable_for_strict_mode_test;
414repeat(10, function() { testAssignToUndefined(assignToUndefined, true); });
Steve Block1e0659c2011-05-24 12:43:12 +0100415possibly_undefined_variable_for_strict_mode_test = undefined;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100416repeat(10, function() { testAssignToUndefined(assignToUndefined, false); });
417
418function assignToUndefinedWithEval() {
419 "use strict";
420 possibly_undefined_variable_for_strict_mode_test_with_eval = "should throw?";
421 eval("");
422}
423
424testAssignToUndefined(assignToUndefinedWithEval, true);
425testAssignToUndefined(assignToUndefinedWithEval, true);
426testAssignToUndefined(assignToUndefinedWithEval, true);
427
428possibly_undefined_variable_for_strict_mode_test_with_eval = "value";
429
430testAssignToUndefined(assignToUndefinedWithEval, false);
431testAssignToUndefined(assignToUndefinedWithEval, false);
432testAssignToUndefined(assignToUndefinedWithEval, false);
433
434delete possibly_undefined_variable_for_strict_mode_test_with_eval;
435
436testAssignToUndefined(assignToUndefinedWithEval, true);
437testAssignToUndefined(assignToUndefinedWithEval, true);
438testAssignToUndefined(assignToUndefinedWithEval, true);
439
440repeat(10, function() {
441 testAssignToUndefined(assignToUndefinedWithEval, true);
442 });
443possibly_undefined_variable_for_strict_mode_test_with_eval = "value";
444repeat(10, function() {
445 testAssignToUndefined(assignToUndefinedWithEval, false);
446 });
447delete possibly_undefined_variable_for_strict_mode_test_with_eval;
448repeat(10, function() {
449 testAssignToUndefined(assignToUndefinedWithEval, true);
450 });
451possibly_undefined_variable_for_strict_mode_test_with_eval = undefined;
452repeat(10, function() {
453 testAssignToUndefined(assignToUndefinedWithEval, false);
454 });
455
456
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100457
458(function testDeleteNonConfigurable() {
459 function delete_property(o) {
460 "use strict";
461 delete o.property;
462 }
463 function delete_element(o, i) {
464 "use strict";
465 delete o[i];
466 }
467
468 var object = {};
469
470 Object.defineProperty(object, "property", { value: "property_value" });
471 Object.defineProperty(object, "1", { value: "one" });
472 Object.defineProperty(object, 7, { value: "seven" });
473 Object.defineProperty(object, 3.14, { value: "pi" });
474
475 assertThrows(function() { delete_property(object); }, TypeError);
476 assertEquals(object.property, "property_value");
477 assertThrows(function() { delete_element(object, "1"); }, TypeError);
478 assertThrows(function() { delete_element(object, 1); }, TypeError);
479 assertEquals(object[1], "one");
480 assertThrows(function() { delete_element(object, "7"); }, TypeError);
481 assertThrows(function() { delete_element(object, 7); }, TypeError);
482 assertEquals(object[7], "seven");
483 assertThrows(function() { delete_element(object, "3.14"); }, TypeError);
484 assertThrows(function() { delete_element(object, 3.14); }, TypeError);
485 assertEquals(object[3.14], "pi");
486})();
487
488// Not transforming this in Function.call and Function.apply.
489(function testThisTransformCallApply() {
490 function non_strict() {
491 return this;
492 }
493 function strict() {
494 "use strict";
495 return this;
496 }
497
498 var global_object = (function() { return this; })();
499 var object = {};
500
501 // Non-strict call.
502 assertTrue(non_strict.call(null) === global_object);
503 assertTrue(non_strict.call(undefined) === global_object);
504 assertEquals(typeof non_strict.call(7), "object");
505 assertEquals(typeof non_strict.call("Hello"), "object");
506 assertTrue(non_strict.call(object) === object);
507
508 // Non-strict apply.
509 assertTrue(non_strict.apply(null) === global_object);
510 assertTrue(non_strict.apply(undefined) === global_object);
511 assertEquals(typeof non_strict.apply(7), "object");
512 assertEquals(typeof non_strict.apply("Hello"), "object");
513 assertTrue(non_strict.apply(object) === object);
514
515 // Strict call.
516 assertTrue(strict.call(null) === null);
517 assertTrue(strict.call(undefined) === undefined);
518 assertEquals(typeof strict.call(7), "number");
519 assertEquals(typeof strict.call("Hello"), "string");
520 assertTrue(strict.call(object) === object);
521
522 // Strict apply.
523 assertTrue(strict.apply(null) === null);
524 assertTrue(strict.apply(undefined) === undefined);
525 assertEquals(typeof strict.apply(7), "number");
526 assertEquals(typeof strict.apply("Hello"), "string");
527 assertTrue(strict.apply(object) === object);
528})();
529
530(function testThisTransform() {
531 try {
532 function strict() {
533 "use strict";
534 return typeof(this);
535 }
536 function nonstrict() {
537 return typeof(this);
538 }
539
540 // Concat to avoid symbol.
541 var strict_name = "str" + "ict";
542 var nonstrict_name = "non" + "str" + "ict";
543 var strict_number = 17;
544 var nonstrict_number = 19;
545 var strict_name_get = "str" + "ict" + "get";
546 var nonstrict_name_get = "non" + "str" + "ict" + "get"
547 var strict_number_get = 23;
548 var nonstrict_number_get = 29;
549
550 function install(t) {
551 t.prototype.strict = strict;
552 t.prototype.nonstrict = nonstrict;
553 t.prototype[strict_number] = strict;
554 t.prototype[nonstrict_number] = nonstrict;
555 Object.defineProperty(t.prototype, strict_name_get,
556 { get: function() { return strict; },
557 configurable: true });
558 Object.defineProperty(t.prototype, nonstrict_name_get,
559 { get: function() { return nonstrict; },
560 configurable: true });
561 Object.defineProperty(t.prototype, strict_number_get,
562 { get: function() { return strict; },
563 configurable: true });
564 Object.defineProperty(t.prototype, nonstrict_number_get,
565 { get: function() { return nonstrict; },
566 configurable: true });
567 }
568
569 function cleanup(t) {
570 delete t.prototype.strict;
571 delete t.prototype.nonstrict;
572 delete t.prototype[strict_number];
573 delete t.prototype[nonstrict_number];
574 delete t.prototype[strict_name_get];
575 delete t.prototype[nonstrict_name_get];
576 delete t.prototype[strict_number_get];
577 delete t.prototype[nonstrict_number_get];
578 }
579
580 // Set up fakes
581 install(String);
582 install(Number);
583 install(Boolean)
584
585 function callStrict(o) {
586 return o.strict();
587 }
588 function callNonStrict(o) {
589 return o.nonstrict();
590 }
591 function callKeyedStrict(o) {
592 return o[strict_name]();
593 }
594 function callKeyedNonStrict(o) {
595 return o[nonstrict_name]();
596 }
597 function callIndexedStrict(o) {
598 return o[strict_number]();
599 }
600 function callIndexedNonStrict(o) {
601 return o[nonstrict_number]();
602 }
603 function callStrictGet(o) {
604 return o.strictget();
605 }
606 function callNonStrictGet(o) {
607 return o.nonstrictget();
608 }
609 function callKeyedStrictGet(o) {
610 return o[strict_name_get]();
611 }
612 function callKeyedNonStrictGet(o) {
613 return o[nonstrict_name_get]();
614 }
615 function callIndexedStrictGet(o) {
616 return o[strict_number_get]();
617 }
618 function callIndexedNonStrictGet(o) {
619 return o[nonstrict_number_get]();
620 }
621
622 for (var i = 0; i < 10; i ++) {
623 assertEquals(("hello").strict(), "string");
624 assertEquals(("hello").nonstrict(), "object");
625 assertEquals(("hello")[strict_name](), "string");
626 assertEquals(("hello")[nonstrict_name](), "object");
627 assertEquals(("hello")[strict_number](), "string");
628 assertEquals(("hello")[nonstrict_number](), "object");
629
630 assertEquals((10 + i).strict(), "number");
631 assertEquals((10 + i).nonstrict(), "object");
632 assertEquals((10 + i)[strict_name](), "number");
633 assertEquals((10 + i)[nonstrict_name](), "object");
634 assertEquals((10 + i)[strict_number](), "number");
635 assertEquals((10 + i)[nonstrict_number](), "object");
636
637 assertEquals((true).strict(), "boolean");
638 assertEquals((true).nonstrict(), "object");
639 assertEquals((true)[strict_name](), "boolean");
640 assertEquals((true)[nonstrict_name](), "object");
641 assertEquals((true)[strict_number](), "boolean");
642 assertEquals((true)[nonstrict_number](), "object");
643
644 assertEquals((false).strict(), "boolean");
645 assertEquals((false).nonstrict(), "object");
646 assertEquals((false)[strict_name](), "boolean");
647 assertEquals((false)[nonstrict_name](), "object");
648 assertEquals((false)[strict_number](), "boolean");
649 assertEquals((false)[nonstrict_number](), "object");
650
651 assertEquals(callStrict("howdy"), "string");
652 assertEquals(callNonStrict("howdy"), "object");
653 assertEquals(callKeyedStrict("howdy"), "string");
654 assertEquals(callKeyedNonStrict("howdy"), "object");
655 assertEquals(callIndexedStrict("howdy"), "string");
656 assertEquals(callIndexedNonStrict("howdy"), "object");
657
658 assertEquals(callStrict(17 + i), "number");
659 assertEquals(callNonStrict(17 + i), "object");
660 assertEquals(callKeyedStrict(17 + i), "number");
661 assertEquals(callKeyedNonStrict(17 + i), "object");
662 assertEquals(callIndexedStrict(17 + i), "number");
663 assertEquals(callIndexedNonStrict(17 + i), "object");
664
665 assertEquals(callStrict(true), "boolean");
666 assertEquals(callNonStrict(true), "object");
667 assertEquals(callKeyedStrict(true), "boolean");
668 assertEquals(callKeyedNonStrict(true), "object");
669 assertEquals(callIndexedStrict(true), "boolean");
670 assertEquals(callIndexedNonStrict(true), "object");
671
672 assertEquals(callStrict(false), "boolean");
673 assertEquals(callNonStrict(false), "object");
674 assertEquals(callKeyedStrict(false), "boolean");
675 assertEquals(callKeyedNonStrict(false), "object");
676 assertEquals(callIndexedStrict(false), "boolean");
677 assertEquals(callIndexedNonStrict(false), "object");
678
679 // All of the above, with getters
680 assertEquals(("hello").strictget(), "string");
681 assertEquals(("hello").nonstrictget(), "object");
682 assertEquals(("hello")[strict_name_get](), "string");
683 assertEquals(("hello")[nonstrict_name_get](), "object");
684 assertEquals(("hello")[strict_number_get](), "string");
685 assertEquals(("hello")[nonstrict_number_get](), "object");
686
687 assertEquals((10 + i).strictget(), "number");
688 assertEquals((10 + i).nonstrictget(), "object");
689 assertEquals((10 + i)[strict_name_get](), "number");
690 assertEquals((10 + i)[nonstrict_name_get](), "object");
691 assertEquals((10 + i)[strict_number_get](), "number");
692 assertEquals((10 + i)[nonstrict_number_get](), "object");
693
694 assertEquals((true).strictget(), "boolean");
695 assertEquals((true).nonstrictget(), "object");
696 assertEquals((true)[strict_name_get](), "boolean");
697 assertEquals((true)[nonstrict_name_get](), "object");
698 assertEquals((true)[strict_number_get](), "boolean");
699 assertEquals((true)[nonstrict_number_get](), "object");
700
701 assertEquals((false).strictget(), "boolean");
702 assertEquals((false).nonstrictget(), "object");
703 assertEquals((false)[strict_name_get](), "boolean");
704 assertEquals((false)[nonstrict_name_get](), "object");
705 assertEquals((false)[strict_number_get](), "boolean");
706 assertEquals((false)[nonstrict_number_get](), "object");
707
708 assertEquals(callStrictGet("howdy"), "string");
709 assertEquals(callNonStrictGet("howdy"), "object");
710 assertEquals(callKeyedStrictGet("howdy"), "string");
711 assertEquals(callKeyedNonStrictGet("howdy"), "object");
712 assertEquals(callIndexedStrictGet("howdy"), "string");
713 assertEquals(callIndexedNonStrictGet("howdy"), "object");
714
715 assertEquals(callStrictGet(17 + i), "number");
716 assertEquals(callNonStrictGet(17 + i), "object");
717 assertEquals(callKeyedStrictGet(17 + i), "number");
718 assertEquals(callKeyedNonStrictGet(17 + i), "object");
719 assertEquals(callIndexedStrictGet(17 + i), "number");
720 assertEquals(callIndexedNonStrictGet(17 + i), "object");
721
722 assertEquals(callStrictGet(true), "boolean");
723 assertEquals(callNonStrictGet(true), "object");
724 assertEquals(callKeyedStrictGet(true), "boolean");
725 assertEquals(callKeyedNonStrictGet(true), "object");
726 assertEquals(callIndexedStrictGet(true), "boolean");
727 assertEquals(callIndexedNonStrictGet(true), "object");
728
729 assertEquals(callStrictGet(false), "boolean");
730 assertEquals(callNonStrictGet(false), "object");
731 assertEquals(callKeyedStrictGet(false), "boolean");
732 assertEquals(callKeyedNonStrictGet(false), "object");
733 assertEquals(callIndexedStrictGet(false), "boolean");
734 assertEquals(callIndexedNonStrictGet(false), "object");
735
736 }
737 } finally {
738 // Cleanup
739 cleanup(String);
740 cleanup(Number);
741 cleanup(Boolean);
742 }
743})();
744
745
746(function ObjectEnvironment() {
747 var o = {};
748 Object.defineProperty(o, "foo", { value: "FOO", writable: false });
749 assertThrows(
750 function () {
751 with (o) {
752 (function() {
753 "use strict";
754 foo = "Hello";
755 })();
756 }
757 },
758 TypeError);
759})();
760
761
762(function TestSetPropertyWithoutSetter() {
763 var o = { get foo() { return "Yey"; } };
764 assertThrows(
765 function broken() {
766 "use strict";
767 o.foo = (0xBADBAD00 >> 1);
768 },
769 TypeError);
770})();
771
772
773(function TestSetPropertyNonConfigurable() {
774 var frozen = Object.freeze({});
775 var sealed = Object.seal({});
776
777 function strict(o) {
778 "use strict";
779 o.property = "value";
780 }
781
782 assertThrows(function() { strict(frozen); }, TypeError);
783 assertThrows(function() { strict(sealed); }, TypeError);
784})();
785
786
787(function TestAssignmentToReadOnlyProperty() {
788 "use strict";
789
790 var o = {};
791 Object.defineProperty(o, "property", { value: 7 });
792
793 assertThrows(function() { o.property = "new value"; }, TypeError);
794 assertThrows(function() { o.property += 10; }, TypeError);
795 assertThrows(function() { o.property -= 10; }, TypeError);
796 assertThrows(function() { o.property *= 10; }, TypeError);
797 assertThrows(function() { o.property /= 10; }, TypeError);
798 assertThrows(function() { o.property++; }, TypeError);
799 assertThrows(function() { o.property--; }, TypeError);
800 assertThrows(function() { ++o.property; }, TypeError);
801 assertThrows(function() { --o.property; }, TypeError);
802
803 var name = "prop" + "erty"; // to avoid symbol path.
804 assertThrows(function() { o[name] = "new value"; }, TypeError);
805 assertThrows(function() { o[name] += 10; }, TypeError);
806 assertThrows(function() { o[name] -= 10; }, TypeError);
807 assertThrows(function() { o[name] *= 10; }, TypeError);
808 assertThrows(function() { o[name] /= 10; }, TypeError);
809 assertThrows(function() { o[name]++; }, TypeError);
810 assertThrows(function() { o[name]--; }, TypeError);
811 assertThrows(function() { ++o[name]; }, TypeError);
812 assertThrows(function() { --o[name]; }, TypeError);
813
814 assertEquals(o.property, 7);
815})();
816
817
818(function TestAssignmentToReadOnlyLoop() {
819 var name = "prop" + "erty"; // to avoid symbol path.
820 var o = {};
821 Object.defineProperty(o, "property", { value: 7 });
822
823 function strict(o, name) {
824 "use strict";
825 o[name] = "new value";
826 }
827
828 for (var i = 0; i < 10; i ++) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000829 var exception = false;
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100830 try {
831 strict(o, name);
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100832 } catch(e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000833 exception = true;
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100834 assertInstanceof(e, TypeError);
835 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000836 assertTrue(exception);
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100837 }
838})();
839
840
841// Specialized KeyedStoreIC experiencing miss.
842(function testKeyedStoreICStrict() {
843 var o = [9,8,7,6,5,4,3,2,1];
844
845 function test(o, i, v) {
846 "use strict";
847 o[i] = v;
848 }
849
850 for (var i = 0; i < 10; i ++) {
851 test(o, 5, 17); // start specialized for smi indices
852 assertEquals(o[5], 17);
853 test(o, "a", 19);
854 assertEquals(o["a"], 19);
855 test(o, "5", 29);
856 assertEquals(o[5], 29);
857 test(o, 100000, 31);
858 assertEquals(o[100000], 31);
859 }
860})();
861
862
863(function TestSetElementWithoutSetter() {
864 "use strict";
865
866 var o = { };
867 Object.defineProperty(o, 0, { get : function() { } });
868
869 var zero_smi = 0;
870 var zero_number = new Number(0);
871 var zero_symbol = "0";
872 var zero_string = "-0-".substring(1,2);
873
874 assertThrows(function() { o[zero_smi] = "new value"; }, TypeError);
875 assertThrows(function() { o[zero_number] = "new value"; }, TypeError);
876 assertThrows(function() { o[zero_symbol] = "new value"; }, TypeError);
877 assertThrows(function() { o[zero_string] = "new value"; }, TypeError);
878})();
879
880
881(function TestSetElementNonConfigurable() {
882 "use strict";
883 var frozen = Object.freeze({});
884 var sealed = Object.seal({});
885
886 var zero_number = 0;
887 var zero_symbol = "0";
888 var zero_string = "-0-".substring(1,2);
889
890 assertThrows(function() { frozen[zero_number] = "value"; }, TypeError);
891 assertThrows(function() { sealed[zero_number] = "value"; }, TypeError);
892 assertThrows(function() { frozen[zero_symbol] = "value"; }, TypeError);
893 assertThrows(function() { sealed[zero_symbol] = "value"; }, TypeError);
894 assertThrows(function() { frozen[zero_string] = "value"; }, TypeError);
895 assertThrows(function() { sealed[zero_string] = "value"; }, TypeError);
896})();
897
898
899(function TestAssignmentToReadOnlyElement() {
900 "use strict";
901
902 var o = {};
903 Object.defineProperty(o, 7, { value: 17 });
904
905 var seven_smi = 7;
906 var seven_number = new Number(7);
907 var seven_symbol = "7";
908 var seven_string = "-7-".substring(1,2);
909
910 // Index with number.
911 assertThrows(function() { o[seven_smi] = "value"; }, TypeError);
912 assertThrows(function() { o[seven_smi] += 10; }, TypeError);
913 assertThrows(function() { o[seven_smi] -= 10; }, TypeError);
914 assertThrows(function() { o[seven_smi] *= 10; }, TypeError);
915 assertThrows(function() { o[seven_smi] /= 10; }, TypeError);
916 assertThrows(function() { o[seven_smi]++; }, TypeError);
917 assertThrows(function() { o[seven_smi]--; }, TypeError);
918 assertThrows(function() { ++o[seven_smi]; }, TypeError);
919 assertThrows(function() { --o[seven_smi]; }, TypeError);
920
921 assertThrows(function() { o[seven_number] = "value"; }, TypeError);
922 assertThrows(function() { o[seven_number] += 10; }, TypeError);
923 assertThrows(function() { o[seven_number] -= 10; }, TypeError);
924 assertThrows(function() { o[seven_number] *= 10; }, TypeError);
925 assertThrows(function() { o[seven_number] /= 10; }, TypeError);
926 assertThrows(function() { o[seven_number]++; }, TypeError);
927 assertThrows(function() { o[seven_number]--; }, TypeError);
928 assertThrows(function() { ++o[seven_number]; }, TypeError);
929 assertThrows(function() { --o[seven_number]; }, TypeError);
930
931 assertThrows(function() { o[seven_symbol] = "value"; }, TypeError);
932 assertThrows(function() { o[seven_symbol] += 10; }, TypeError);
933 assertThrows(function() { o[seven_symbol] -= 10; }, TypeError);
934 assertThrows(function() { o[seven_symbol] *= 10; }, TypeError);
935 assertThrows(function() { o[seven_symbol] /= 10; }, TypeError);
936 assertThrows(function() { o[seven_symbol]++; }, TypeError);
937 assertThrows(function() { o[seven_symbol]--; }, TypeError);
938 assertThrows(function() { ++o[seven_symbol]; }, TypeError);
939 assertThrows(function() { --o[seven_symbol]; }, TypeError);
940
941 assertThrows(function() { o[seven_string] = "value"; }, TypeError);
942 assertThrows(function() { o[seven_string] += 10; }, TypeError);
943 assertThrows(function() { o[seven_string] -= 10; }, TypeError);
944 assertThrows(function() { o[seven_string] *= 10; }, TypeError);
945 assertThrows(function() { o[seven_string] /= 10; }, TypeError);
946 assertThrows(function() { o[seven_string]++; }, TypeError);
947 assertThrows(function() { o[seven_string]--; }, TypeError);
948 assertThrows(function() { ++o[seven_string]; }, TypeError);
949 assertThrows(function() { --o[seven_string]; }, TypeError);
950
951 assertEquals(o[seven_number], 17);
952 assertEquals(o[seven_symbol], 17);
953 assertEquals(o[seven_string], 17);
954})();
955
956
957(function TestAssignmentToReadOnlyLoop() {
958 "use strict";
959
960 var o = {};
961 Object.defineProperty(o, 7, { value: 17 });
962
963 var seven_smi = 7;
964 var seven_number = new Number(7);
965 var seven_symbol = "7";
966 var seven_string = "-7-".substring(1,2);
967
968 for (var i = 0; i < 10; i ++) {
969 assertThrows(function() { o[seven_smi] = "value" }, TypeError);
970 assertThrows(function() { o[seven_number] = "value" }, TypeError);
971 assertThrows(function() { o[seven_symbol] = "value" }, TypeError);
972 assertThrows(function() { o[seven_string] = "value" }, TypeError);
973 }
974
975 assertEquals(o[7], 17);
976})();
977
978
979(function TestAssignmentToStringLength() {
980 "use strict";
981
982 var str_val = "string";
983 var str_obj = new String(str_val);
984 var str_cat = str_val + str_val + str_obj;
985
986 assertThrows(function() { str_val.length = 1; }, TypeError);
987 assertThrows(function() { str_obj.length = 1; }, TypeError);
988 assertThrows(function() { str_cat.length = 1; }, TypeError);
989})();
Steve Block44f0eee2011-05-26 01:26:41 +0100990
991
992(function TestArgumentsAliasing() {
993 function strict(a, b) {
994 "use strict";
995 a = "c";
996 b = "d";
997 return [a, b, arguments[0], arguments[1]];
998 }
999
1000 function nonstrict(a, b) {
1001 a = "c";
1002 b = "d";
1003 return [a, b, arguments[0], arguments[1]];
1004 }
1005
1006 assertEquals(["c", "d", "a", "b"], strict("a", "b"));
1007 assertEquals(["c", "d", "c", "d"], nonstrict("a", "b"));
1008})();
1009
1010
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001011function CheckFunctionPillDescriptor(func, name) {
Steve Block44f0eee2011-05-26 01:26:41 +01001012
1013 function CheckPill(pill) {
1014 assertEquals("function", typeof pill);
1015 assertInstanceof(pill, Function);
1016 pill.property = "value";
1017 assertEquals(pill.value, undefined);
1018 assertThrows(function() { 'use strict'; pill.property = "value"; },
1019 TypeError);
1020 assertThrows(pill, TypeError);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001021 assertEquals(undefined, pill.prototype);
1022 }
1023
1024 // Poisoned accessors are no longer own properties
1025 func = Object.getPrototypeOf(func);
1026 var descriptor = Object.getOwnPropertyDescriptor(func, name);
1027 CheckPill(descriptor.get)
1028 CheckPill(descriptor.set);
1029 assertFalse(descriptor.enumerable);
1030 // In ES6, restricted function properties are configurable
1031 assertTrue(descriptor.configurable);
1032}
1033
1034
1035function CheckArgumentsPillDescriptor(func, name) {
1036
1037 function CheckPill(pill) {
1038 assertEquals("function", typeof pill);
1039 assertInstanceof(pill, Function);
1040 pill.property = "value";
1041 assertEquals(pill.value, undefined);
1042 assertThrows(function() { 'use strict'; pill.property = "value"; },
1043 TypeError);
1044 assertThrows(pill, TypeError);
1045 assertEquals(undefined, pill.prototype);
Steve Block44f0eee2011-05-26 01:26:41 +01001046 }
1047
1048 var descriptor = Object.getOwnPropertyDescriptor(func, name);
1049 CheckPill(descriptor.get)
1050 CheckPill(descriptor.set);
1051 assertFalse(descriptor.enumerable);
1052 assertFalse(descriptor.configurable);
1053}
1054
1055
1056(function TestStrictFunctionPills() {
1057 function strict() {
1058 "use strict";
1059 }
1060 assertThrows(function() { strict.caller; }, TypeError);
1061 assertThrows(function() { strict.arguments; }, TypeError);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001062 assertThrows(function() { strict.caller = 42; }, TypeError);
1063 assertThrows(function() { strict.arguments = 42; }, TypeError);
Steve Block44f0eee2011-05-26 01:26:41 +01001064
1065 var another = new Function("'use strict'");
1066 assertThrows(function() { another.caller; }, TypeError);
1067 assertThrows(function() { another.arguments; }, TypeError);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001068 assertThrows(function() { another.caller = 42; }, TypeError);
1069 assertThrows(function() { another.arguments = 42; }, TypeError);
Steve Block44f0eee2011-05-26 01:26:41 +01001070
1071 var third = (function() { "use strict"; return function() {}; })();
1072 assertThrows(function() { third.caller; }, TypeError);
1073 assertThrows(function() { third.arguments; }, TypeError);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001074 assertThrows(function() { third.caller = 42; }, TypeError);
1075 assertThrows(function() { third.arguments = 42; }, TypeError);
Steve Block44f0eee2011-05-26 01:26:41 +01001076
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001077 CheckFunctionPillDescriptor(strict, "caller");
1078 CheckFunctionPillDescriptor(strict, "arguments");
1079 CheckFunctionPillDescriptor(another, "caller");
1080 CheckFunctionPillDescriptor(another, "arguments");
1081 CheckFunctionPillDescriptor(third, "caller");
1082 CheckFunctionPillDescriptor(third, "arguments");
Steve Block44f0eee2011-05-26 01:26:41 +01001083})();
1084
1085
1086(function TestStrictFunctionWritablePrototype() {
1087 "use strict";
1088 function TheClass() {
1089 }
1090 assertThrows(function() { TheClass.caller; }, TypeError);
1091 assertThrows(function() { TheClass.arguments; }, TypeError);
1092
1093 // Strict functions must have writable prototype.
1094 TheClass.prototype = {
1095 func: function() { return "func_value"; },
1096 get accessor() { return "accessor_value"; },
1097 property: "property_value",
1098 };
1099
1100 var o = new TheClass();
1101 assertEquals(o.func(), "func_value");
1102 assertEquals(o.accessor, "accessor_value");
1103 assertEquals(o.property, "property_value");
1104})();
1105
1106
1107(function TestStrictArgumentPills() {
1108 function strict() {
1109 "use strict";
1110 return arguments;
1111 }
1112
1113 var args = strict();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001114 CheckArgumentsPillDescriptor(args, "caller");
1115 CheckArgumentsPillDescriptor(args, "callee");
Steve Block44f0eee2011-05-26 01:26:41 +01001116
1117 args = strict(17, "value", strict);
1118 assertEquals(17, args[0])
1119 assertEquals("value", args[1])
1120 assertEquals(strict, args[2]);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001121 CheckArgumentsPillDescriptor(args, "caller");
1122 CheckArgumentsPillDescriptor(args, "callee");
Steve Block44f0eee2011-05-26 01:26:41 +01001123
1124 function outer() {
1125 "use strict";
1126 function inner() {
1127 return arguments;
1128 }
1129 return inner;
1130 }
1131
1132 var args = outer()();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001133 CheckArgumentsPillDescriptor(args, "caller");
1134 CheckArgumentsPillDescriptor(args, "callee");
Steve Block44f0eee2011-05-26 01:26:41 +01001135
1136 args = outer()(17, "value", strict);
1137 assertEquals(17, args[0])
1138 assertEquals("value", args[1])
1139 assertEquals(strict, args[2]);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001140 CheckArgumentsPillDescriptor(args, "caller");
1141 CheckArgumentsPillDescriptor(args, "callee");
Steve Block44f0eee2011-05-26 01:26:41 +01001142})();
1143
1144
1145(function TestNonStrictFunctionCallerPillSimple() {
1146 function return_my_caller() {
1147 return return_my_caller.caller;
1148 }
1149
1150 function strict() {
1151 "use strict";
Ben Murdochda12d292016-06-02 14:46:10 +01001152 // Returning result via local variable to avoid tail call elimination.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001153 var res = return_my_caller();
1154 return res;
Steve Block44f0eee2011-05-26 01:26:41 +01001155 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001156 assertSame(null, strict());
Steve Block44f0eee2011-05-26 01:26:41 +01001157
1158 function non_strict() {
1159 return return_my_caller();
1160 }
1161 assertSame(non_strict(), non_strict);
1162})();
1163
1164
1165(function TestNonStrictFunctionCallerPill() {
1166 function strict(n) {
1167 "use strict";
Ben Murdochda12d292016-06-02 14:46:10 +01001168 // Returning result via local variable to avoid tail call elimination.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001169 var res = non_strict(n);
1170 return res;
Steve Block44f0eee2011-05-26 01:26:41 +01001171 }
1172
1173 function recurse(n, then) {
1174 if (n > 0) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001175 return recurse(n - 1, then);
Steve Block44f0eee2011-05-26 01:26:41 +01001176 } else {
1177 return then();
1178 }
1179 }
1180
1181 function non_strict(n) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001182 return recurse(n, function() { return non_strict.caller; });
Steve Block44f0eee2011-05-26 01:26:41 +01001183 }
1184
1185 function test(n) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001186 return recurse(n, function() { return strict(n); });
Steve Block44f0eee2011-05-26 01:26:41 +01001187 }
1188
1189 for (var i = 0; i < 10; i ++) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001190 assertSame(null, test(i));
1191 }
1192})();
1193
1194
1195(function TestNonStrictFunctionCallerDescriptorPill() {
1196 function strict(n) {
1197 "use strict";
Ben Murdochda12d292016-06-02 14:46:10 +01001198 // Returning result via local variable to avoid tail call elimination.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001199 var res = non_strict(n);
1200 return res;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001201 }
1202
1203 function recurse(n, then) {
1204 if (n > 0) {
1205 return recurse(n - 1, then);
1206 } else {
1207 return then();
1208 }
1209 }
1210
1211 function non_strict(n) {
1212 return recurse(n, function() {
1213 return Object.getOwnPropertyDescriptor(non_strict, "caller").value;
1214 });
1215 }
1216
1217 function test(n) {
1218 return recurse(n, function() { return strict(n); });
1219 }
1220
1221 for (var i = 0; i < 10; i ++) {
1222 assertSame(null, test(i));
Steve Block44f0eee2011-05-26 01:26:41 +01001223 }
1224})();
Ben Murdoch257744e2011-11-30 15:57:28 +00001225
1226
1227(function TestStrictModeEval() {
1228 "use strict";
1229 eval("var eval_local = 10;");
1230 assertThrows(function() { return eval_local; }, ReferenceError);
1231})();