blob: 62d003f9fabb75e62c032767864a2861d483fd01 [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
Emily Bernierd0a1eb72015-03-24 16:35:39 -040028// Flags: --turbo-deoptimization --noharmony-scoping
29// Flags: --noharmony-classes --noharmony-object-literals
30
Steve Block1e0659c2011-05-24 12:43:12 +010031function CheckStrictMode(code, exception) {
32 assertDoesNotThrow(code);
33 assertThrows("'use strict';\n" + code, exception);
34 assertThrows('"use strict";\n' + code, exception);
35 assertDoesNotThrow("\
36 function outer() {\
37 function inner() {\n"
38 + code +
39 "\n}\
40 }");
41 assertThrows("\
42 function outer() {\
43 'use strict';\
44 function inner() {\n"
45 + code +
46 "\n}\
47 }", exception);
48}
49
50function CheckFunctionConstructorStrictMode() {
51 var args = [];
52 for (var i = 0; i < arguments.length; i ++) {
53 args[i] = arguments[i];
54 }
55 // Create non-strict function. No exception.
56 args[arguments.length] = "";
57 assertDoesNotThrow(function() {
58 Function.apply(this, args);
59 });
60 // Create strict mode function. Exception expected.
61 args[arguments.length] = "'use strict';";
62 assertThrows(function() {
63 Function.apply(this, args);
64 }, SyntaxError);
65}
66
67// Incorrect 'use strict' directive.
68(function UseStrictEscape() {
69 "use\\x20strict";
70 with ({}) {};
71})();
72
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000073// Incorrectly place 'use strict' directive.
74assertThrows("function foo (x) 'use strict'; {}", SyntaxError);
75
Steve Block1e0659c2011-05-24 12:43:12 +010076// 'use strict' in non-directive position.
77(function UseStrictNonDirective() {
78 void(0);
79 "use strict";
80 with ({}) {};
81})();
82
83// Multiple directives, including "use strict".
84assertThrows('\
85"directive 1";\
86"another directive";\
87"use strict";\
88"directive after strict";\
89"and one more";\
90with({}) {}', SyntaxError);
91
92// 'with' disallowed in strict mode.
93CheckStrictMode("with({}) {}", SyntaxError);
94
95// Function named 'eval'.
96CheckStrictMode("function eval() {}", SyntaxError);
97
98// Function named 'arguments'.
99CheckStrictMode("function arguments() {}", SyntaxError);
100
101// Function parameter named 'eval'.
102CheckStrictMode("function foo(a, b, eval, c, d) {}", SyntaxError);
103
104// Function parameter named 'arguments'.
105CheckStrictMode("function foo(a, b, arguments, c, d) {}", SyntaxError);
106
107// Property accessor parameter named 'eval'.
108CheckStrictMode("var o = { set foo(eval) {} }", SyntaxError);
109
110// Property accessor parameter named 'arguments'.
111CheckStrictMode("var o = { set foo(arguments) {} }", SyntaxError);
112
113// Duplicate function parameter name.
114CheckStrictMode("function foo(a, b, c, d, b) {}", SyntaxError);
115
116// Function constructor: eval parameter name.
117CheckFunctionConstructorStrictMode("eval");
118
119// Function constructor: arguments parameter name.
120CheckFunctionConstructorStrictMode("arguments");
121
122// Function constructor: duplicate parameter name.
123CheckFunctionConstructorStrictMode("a", "b", "c", "b");
124CheckFunctionConstructorStrictMode("a,b,c,b");
125
126// catch(eval)
127CheckStrictMode("try{}catch(eval){};", SyntaxError);
128
129// catch(arguments)
130CheckStrictMode("try{}catch(arguments){};", SyntaxError);
131
132// var eval
133CheckStrictMode("var eval;", SyntaxError);
134
135// var arguments
136CheckStrictMode("var arguments;", SyntaxError);
137
138// Strict mode applies to the function in which the directive is used..
139assertThrows('\
140function foo(eval) {\
141 "use strict";\
142}', SyntaxError);
143
144// Strict mode doesn't affect the outer stop of strict code.
145(function NotStrict(eval) {
146 function Strict() {
147 "use strict";
148 }
149 with ({}) {};
150})();
151
152// Octal literal
153CheckStrictMode("var x = 012");
154CheckStrictMode("012");
155CheckStrictMode("'Hello octal\\032'");
156CheckStrictMode("function octal() { return 012; }");
157CheckStrictMode("function octal() { return '\\032'; }");
158
159(function ValidEscape() {
160 "use strict";
161 var x = '\0';
162 var y = "\0";
163})();
164
165// Octal before "use strict"
166assertThrows('\
167 function strict() {\
168 "octal\\032directive";\
169 "use strict";\
170 }', SyntaxError);
171
172// Duplicate data properties.
173CheckStrictMode("var x = { dupe : 1, nondupe: 3, dupe : 2 };", SyntaxError);
174CheckStrictMode("var x = { '1234' : 1, '2345' : 2, '1234' : 3 };", SyntaxError);
175CheckStrictMode("var x = { '1234' : 1, '2345' : 2, 1234 : 3 };", SyntaxError);
176CheckStrictMode("var x = { 3.14 : 1, 2.71 : 2, 3.14 : 3 };", SyntaxError);
177CheckStrictMode("var x = { 3.14 : 1, '3.14' : 2 };", SyntaxError);
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100178CheckStrictMode("var x = { \
179 123: 1, \
180 123.00000000000000000000000000000000000000000000000000000000000000000001: 2 \
181}", SyntaxError);
Steve Block1e0659c2011-05-24 12:43:12 +0100182
183// Non-conflicting data properties.
184(function StrictModeNonDuplicate() {
185 "use strict";
186 var x = { 123 : 1, "0123" : 2 };
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100187 var x = {
188 123: 1,
189 '123.00000000000000000000000000000000000000000000000000000000000000000001':
190 2
191 };
Steve Block1e0659c2011-05-24 12:43:12 +0100192})();
193
194// Two getters (non-strict)
195assertThrows("var x = { get foo() { }, get foo() { } };", SyntaxError);
196assertThrows("var x = { get foo(){}, get 'foo'(){}};", SyntaxError);
197assertThrows("var x = { get 12(){}, get '12'(){}};", SyntaxError);
198
199// Two setters (non-strict)
200assertThrows("var x = { set foo(v) { }, set foo(v) { } };", SyntaxError);
201assertThrows("var x = { set foo(v) { }, set 'foo'(v) { } };", SyntaxError);
202assertThrows("var x = { set 13(v) { }, set '13'(v) { } };", SyntaxError);
203
204// Setter and data (non-strict)
205assertThrows("var x = { foo: 'data', set foo(v) { } };", SyntaxError);
206assertThrows("var x = { set foo(v) { }, foo: 'data' };", SyntaxError);
207assertThrows("var x = { foo: 'data', set 'foo'(v) { } };", SyntaxError);
208assertThrows("var x = { set foo(v) { }, 'foo': 'data' };", SyntaxError);
209assertThrows("var x = { 'foo': 'data', set foo(v) { } };", SyntaxError);
210assertThrows("var x = { set 'foo'(v) { }, foo: 'data' };", SyntaxError);
211assertThrows("var x = { 'foo': 'data', set 'foo'(v) { } };", SyntaxError);
212assertThrows("var x = { set 'foo'(v) { }, 'foo': 'data' };", SyntaxError);
213assertThrows("var x = { 12: 1, set '12'(v){}};", SyntaxError);
214assertThrows("var x = { 12: 1, set 12(v){}};", SyntaxError);
215assertThrows("var x = { '12': 1, set '12'(v){}};", SyntaxError);
216assertThrows("var x = { '12': 1, set 12(v){}};", SyntaxError);
217
218// Getter and data (non-strict)
219assertThrows("var x = { foo: 'data', get foo() { } };", SyntaxError);
220assertThrows("var x = { get foo() { }, foo: 'data' };", SyntaxError);
221assertThrows("var x = { 'foo': 'data', get foo() { } };", SyntaxError);
222assertThrows("var x = { get 'foo'() { }, 'foo': 'data' };", SyntaxError);
223assertThrows("var x = { '12': 1, get '12'(){}};", SyntaxError);
224assertThrows("var x = { '12': 1, get 12(){}};", SyntaxError);
225
226// Assignment to eval or arguments
227CheckStrictMode("function strict() { eval = undefined; }", SyntaxError);
228CheckStrictMode("function strict() { arguments = undefined; }", SyntaxError);
229CheckStrictMode("function strict() { print(eval = undefined); }", SyntaxError);
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100230CheckStrictMode("function strict() { print(arguments = undefined); }",
231 SyntaxError);
Steve Block1e0659c2011-05-24 12:43:12 +0100232CheckStrictMode("function strict() { var x = eval = undefined; }", SyntaxError);
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100233CheckStrictMode("function strict() { var x = arguments = undefined; }",
234 SyntaxError);
Steve Block1e0659c2011-05-24 12:43:12 +0100235
236// Compound assignment to eval or arguments
237CheckStrictMode("function strict() { eval *= undefined; }", SyntaxError);
238CheckStrictMode("function strict() { arguments /= undefined; }", SyntaxError);
239CheckStrictMode("function strict() { print(eval %= undefined); }", SyntaxError);
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100240CheckStrictMode("function strict() { print(arguments %= undefined); }",
241 SyntaxError);
242CheckStrictMode("function strict() { var x = eval += undefined; }",
243 SyntaxError);
244CheckStrictMode("function strict() { var x = arguments -= undefined; }",
245 SyntaxError);
Steve Block1e0659c2011-05-24 12:43:12 +0100246CheckStrictMode("function strict() { eval <<= undefined; }", SyntaxError);
247CheckStrictMode("function strict() { arguments >>= undefined; }", SyntaxError);
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100248CheckStrictMode("function strict() { print(eval >>>= undefined); }",
249 SyntaxError);
250CheckStrictMode("function strict() { print(arguments &= undefined); }",
251 SyntaxError);
252CheckStrictMode("function strict() { var x = eval ^= undefined; }",
253 SyntaxError);
254CheckStrictMode("function strict() { var x = arguments |= undefined; }",
255 SyntaxError);
Steve Block1e0659c2011-05-24 12:43:12 +0100256
257// Postfix increment with eval or arguments
258CheckStrictMode("function strict() { eval++; }", SyntaxError);
259CheckStrictMode("function strict() { arguments++; }", SyntaxError);
260CheckStrictMode("function strict() { print(eval++); }", SyntaxError);
261CheckStrictMode("function strict() { print(arguments++); }", SyntaxError);
262CheckStrictMode("function strict() { var x = eval++; }", SyntaxError);
263CheckStrictMode("function strict() { var x = arguments++; }", SyntaxError);
264
265// Postfix decrement with eval or arguments
266CheckStrictMode("function strict() { eval--; }", SyntaxError);
267CheckStrictMode("function strict() { arguments--; }", SyntaxError);
268CheckStrictMode("function strict() { print(eval--); }", SyntaxError);
269CheckStrictMode("function strict() { print(arguments--); }", SyntaxError);
270CheckStrictMode("function strict() { var x = eval--; }", SyntaxError);
271CheckStrictMode("function strict() { var x = arguments--; }", SyntaxError);
272
273// Prefix increment with eval or arguments
274CheckStrictMode("function strict() { ++eval; }", SyntaxError);
275CheckStrictMode("function strict() { ++arguments; }", SyntaxError);
276CheckStrictMode("function strict() { print(++eval); }", SyntaxError);
277CheckStrictMode("function strict() { print(++arguments); }", SyntaxError);
278CheckStrictMode("function strict() { var x = ++eval; }", SyntaxError);
279CheckStrictMode("function strict() { var x = ++arguments; }", SyntaxError);
280
281// Prefix decrement with eval or arguments
282CheckStrictMode("function strict() { --eval; }", SyntaxError);
283CheckStrictMode("function strict() { --arguments; }", SyntaxError);
284CheckStrictMode("function strict() { print(--eval); }", SyntaxError);
285CheckStrictMode("function strict() { print(--arguments); }", SyntaxError);
286CheckStrictMode("function strict() { var x = --eval; }", SyntaxError);
287CheckStrictMode("function strict() { var x = --arguments; }", SyntaxError);
288
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100289// Use of const in strict mode is disallowed in anticipation of ES Harmony.
290CheckStrictMode("const x = 0;", SyntaxError);
291CheckStrictMode("for (const x = 0; false;) {}", SyntaxError);
292CheckStrictMode("function strict() { const x = 0; }", SyntaxError);
293
294// Strict mode only allows functions in SourceElements
295CheckStrictMode("if (true) { function invalid() {} }", SyntaxError);
296CheckStrictMode("for (;false;) { function invalid() {} }", SyntaxError);
297CheckStrictMode("{ function invalid() {} }", SyntaxError);
298CheckStrictMode("try { function invalid() {} } catch(e) {}", SyntaxError);
299CheckStrictMode("try { } catch(e) { function invalid() {} }", SyntaxError);
300CheckStrictMode("function outer() {{ function invalid() {} }}", SyntaxError);
301
302// Delete of an unqualified identifier
303CheckStrictMode("delete unqualified;", SyntaxError);
304CheckStrictMode("function strict() { delete unqualified; }", SyntaxError);
305CheckStrictMode("function function_name() { delete function_name; }",
306 SyntaxError);
307CheckStrictMode("function strict(parameter) { delete parameter; }",
308 SyntaxError);
309CheckStrictMode("function strict() { var variable; delete variable; }",
310 SyntaxError);
311CheckStrictMode("var variable; delete variable;", SyntaxError);
312
313(function TestStrictDelete() {
314 "use strict";
315 // "delete this" is allowed in strict mode and should work.
316 function strict_delete() { delete this; }
317 strict_delete();
318})();
319
Steve Block1e0659c2011-05-24 12:43:12 +0100320// Prefix unary operators other than delete, ++, -- are valid in strict mode
321(function StrictModeUnaryOperators() {
322 "use strict";
323 var x = [void eval, typeof eval, +eval, -eval, ~eval, !eval];
324 var y = [void arguments, typeof arguments,
325 +arguments, -arguments, ~arguments, !arguments];
326})();
327
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000328// 7.6.1.2 Future Reserved Words in strict mode
329var future_strict_reserved_words = [
Steve Block1e0659c2011-05-24 12:43:12 +0100330 "implements",
331 "interface",
332 "let",
333 "package",
334 "private",
335 "protected",
336 "public",
337 "static",
338 "yield" ];
339
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000340function testFutureStrictReservedWord(word) {
Steve Block1e0659c2011-05-24 12:43:12 +0100341 // Simple use of each reserved word
342 CheckStrictMode("var " + word + " = 1;", SyntaxError);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000343 CheckStrictMode("typeof (" + word + ");", SyntaxError);
Steve Block1e0659c2011-05-24 12:43:12 +0100344
345 // object literal properties
346 eval("var x = { " + word + " : 42 };");
347 eval("var x = { get " + word + " () {} };");
348 eval("var x = { set " + word + " (value) {} };");
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000349 eval("var x = { get " + word + " () { 'use strict'; } };");
350 eval("var x = { set " + word + " (value) { 'use strict'; } };");
Steve Block1e0659c2011-05-24 12:43:12 +0100351
352 // object literal with string literal property names
353 eval("var x = { '" + word + "' : 42 };");
354 eval("var x = { get '" + word + "' () { } };");
355 eval("var x = { set '" + word + "' (value) { } };");
356 eval("var x = { get '" + word + "' () { 'use strict'; } };");
357 eval("var x = { set '" + word + "' (value) { 'use strict'; } };");
358
359 // Function names and arguments, strict and non-strict contexts
360 CheckStrictMode("function " + word + " () {}", SyntaxError);
361 CheckStrictMode("function foo (" + word + ") {}", SyntaxError);
362 CheckStrictMode("function foo (" + word + ", " + word + ") {}", SyntaxError);
363 CheckStrictMode("function foo (a, " + word + ") {}", SyntaxError);
364 CheckStrictMode("function foo (" + word + ", a) {}", SyntaxError);
365 CheckStrictMode("function foo (a, " + word + ", b) {}", SyntaxError);
366 CheckStrictMode("var foo = function (" + word + ") {}", SyntaxError);
367
368 // Function names and arguments when the body is strict
369 assertThrows("function " + word + " () { 'use strict'; }", SyntaxError);
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100370 assertThrows("function foo (" + word + ", " + word + ") { 'use strict'; }",
371 SyntaxError);
Steve Block1e0659c2011-05-24 12:43:12 +0100372 assertThrows("function foo (a, " + word + ") { 'use strict'; }", SyntaxError);
373 assertThrows("function foo (" + word + ", a) { 'use strict'; }", SyntaxError);
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100374 assertThrows("function foo (a, " + word + ", b) { 'use strict'; }",
375 SyntaxError);
376 assertThrows("var foo = function (" + word + ") { 'use strict'; }",
377 SyntaxError);
Steve Block1e0659c2011-05-24 12:43:12 +0100378
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000379 // setter parameter when the body is strict
380 CheckStrictMode("var x = { set foo(" + word + ") {} };", SyntaxError);
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100381 assertThrows("var x = { set foo(" + word + ") { 'use strict'; } };",
382 SyntaxError);
Steve Block1e0659c2011-05-24 12:43:12 +0100383}
384
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000385for (var i = 0; i < future_strict_reserved_words.length; i++) {
386 testFutureStrictReservedWord(future_strict_reserved_words[i]);
Steve Block1e0659c2011-05-24 12:43:12 +0100387}
388
Ben Murdoch8b112d22011-06-08 16:22:53 +0100389function testAssignToUndefined(test, should_throw) {
Steve Block1e0659c2011-05-24 12:43:12 +0100390 try {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100391 test();
Steve Block1e0659c2011-05-24 12:43:12 +0100392 } catch (e) {
393 assertTrue(should_throw, "strict mode");
394 assertInstanceof(e, ReferenceError, "strict mode");
395 return;
396 }
397 assertFalse(should_throw, "strict mode");
398}
399
Steve Block1e0659c2011-05-24 12:43:12 +0100400function repeat(n, f) {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100401 for (var i = 0; i < n; i ++) { f(); }
Steve Block1e0659c2011-05-24 12:43:12 +0100402}
403
Ben Murdoch8b112d22011-06-08 16:22:53 +0100404function assignToUndefined() {
405 "use strict";
406 possibly_undefined_variable_for_strict_mode_test = "should throw?";
407}
408
409testAssignToUndefined(assignToUndefined, true);
410testAssignToUndefined(assignToUndefined, true);
411testAssignToUndefined(assignToUndefined, true);
412
Steve Block1e0659c2011-05-24 12:43:12 +0100413possibly_undefined_variable_for_strict_mode_test = "value";
Ben Murdoch8b112d22011-06-08 16:22:53 +0100414
415testAssignToUndefined(assignToUndefined, false);
416testAssignToUndefined(assignToUndefined, false);
417testAssignToUndefined(assignToUndefined, false);
418
Steve Block1e0659c2011-05-24 12:43:12 +0100419delete possibly_undefined_variable_for_strict_mode_test;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100420
421testAssignToUndefined(assignToUndefined, true);
422testAssignToUndefined(assignToUndefined, true);
423testAssignToUndefined(assignToUndefined, true);
424
425repeat(10, function() { testAssignToUndefined(assignToUndefined, true); });
426possibly_undefined_variable_for_strict_mode_test = "value";
427repeat(10, function() { testAssignToUndefined(assignToUndefined, false); });
428delete possibly_undefined_variable_for_strict_mode_test;
429repeat(10, function() { testAssignToUndefined(assignToUndefined, true); });
Steve Block1e0659c2011-05-24 12:43:12 +0100430possibly_undefined_variable_for_strict_mode_test = undefined;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100431repeat(10, function() { testAssignToUndefined(assignToUndefined, false); });
432
433function assignToUndefinedWithEval() {
434 "use strict";
435 possibly_undefined_variable_for_strict_mode_test_with_eval = "should throw?";
436 eval("");
437}
438
439testAssignToUndefined(assignToUndefinedWithEval, true);
440testAssignToUndefined(assignToUndefinedWithEval, true);
441testAssignToUndefined(assignToUndefinedWithEval, true);
442
443possibly_undefined_variable_for_strict_mode_test_with_eval = "value";
444
445testAssignToUndefined(assignToUndefinedWithEval, false);
446testAssignToUndefined(assignToUndefinedWithEval, false);
447testAssignToUndefined(assignToUndefinedWithEval, false);
448
449delete possibly_undefined_variable_for_strict_mode_test_with_eval;
450
451testAssignToUndefined(assignToUndefinedWithEval, true);
452testAssignToUndefined(assignToUndefinedWithEval, true);
453testAssignToUndefined(assignToUndefinedWithEval, true);
454
455repeat(10, function() {
456 testAssignToUndefined(assignToUndefinedWithEval, true);
457 });
458possibly_undefined_variable_for_strict_mode_test_with_eval = "value";
459repeat(10, function() {
460 testAssignToUndefined(assignToUndefinedWithEval, false);
461 });
462delete possibly_undefined_variable_for_strict_mode_test_with_eval;
463repeat(10, function() {
464 testAssignToUndefined(assignToUndefinedWithEval, true);
465 });
466possibly_undefined_variable_for_strict_mode_test_with_eval = undefined;
467repeat(10, function() {
468 testAssignToUndefined(assignToUndefinedWithEval, false);
469 });
470
471
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100472
473(function testDeleteNonConfigurable() {
474 function delete_property(o) {
475 "use strict";
476 delete o.property;
477 }
478 function delete_element(o, i) {
479 "use strict";
480 delete o[i];
481 }
482
483 var object = {};
484
485 Object.defineProperty(object, "property", { value: "property_value" });
486 Object.defineProperty(object, "1", { value: "one" });
487 Object.defineProperty(object, 7, { value: "seven" });
488 Object.defineProperty(object, 3.14, { value: "pi" });
489
490 assertThrows(function() { delete_property(object); }, TypeError);
491 assertEquals(object.property, "property_value");
492 assertThrows(function() { delete_element(object, "1"); }, TypeError);
493 assertThrows(function() { delete_element(object, 1); }, TypeError);
494 assertEquals(object[1], "one");
495 assertThrows(function() { delete_element(object, "7"); }, TypeError);
496 assertThrows(function() { delete_element(object, 7); }, TypeError);
497 assertEquals(object[7], "seven");
498 assertThrows(function() { delete_element(object, "3.14"); }, TypeError);
499 assertThrows(function() { delete_element(object, 3.14); }, TypeError);
500 assertEquals(object[3.14], "pi");
501})();
502
503// Not transforming this in Function.call and Function.apply.
504(function testThisTransformCallApply() {
505 function non_strict() {
506 return this;
507 }
508 function strict() {
509 "use strict";
510 return this;
511 }
512
513 var global_object = (function() { return this; })();
514 var object = {};
515
516 // Non-strict call.
517 assertTrue(non_strict.call(null) === global_object);
518 assertTrue(non_strict.call(undefined) === global_object);
519 assertEquals(typeof non_strict.call(7), "object");
520 assertEquals(typeof non_strict.call("Hello"), "object");
521 assertTrue(non_strict.call(object) === object);
522
523 // Non-strict apply.
524 assertTrue(non_strict.apply(null) === global_object);
525 assertTrue(non_strict.apply(undefined) === global_object);
526 assertEquals(typeof non_strict.apply(7), "object");
527 assertEquals(typeof non_strict.apply("Hello"), "object");
528 assertTrue(non_strict.apply(object) === object);
529
530 // Strict call.
531 assertTrue(strict.call(null) === null);
532 assertTrue(strict.call(undefined) === undefined);
533 assertEquals(typeof strict.call(7), "number");
534 assertEquals(typeof strict.call("Hello"), "string");
535 assertTrue(strict.call(object) === object);
536
537 // Strict apply.
538 assertTrue(strict.apply(null) === null);
539 assertTrue(strict.apply(undefined) === undefined);
540 assertEquals(typeof strict.apply(7), "number");
541 assertEquals(typeof strict.apply("Hello"), "string");
542 assertTrue(strict.apply(object) === object);
543})();
544
545(function testThisTransform() {
546 try {
547 function strict() {
548 "use strict";
549 return typeof(this);
550 }
551 function nonstrict() {
552 return typeof(this);
553 }
554
555 // Concat to avoid symbol.
556 var strict_name = "str" + "ict";
557 var nonstrict_name = "non" + "str" + "ict";
558 var strict_number = 17;
559 var nonstrict_number = 19;
560 var strict_name_get = "str" + "ict" + "get";
561 var nonstrict_name_get = "non" + "str" + "ict" + "get"
562 var strict_number_get = 23;
563 var nonstrict_number_get = 29;
564
565 function install(t) {
566 t.prototype.strict = strict;
567 t.prototype.nonstrict = nonstrict;
568 t.prototype[strict_number] = strict;
569 t.prototype[nonstrict_number] = nonstrict;
570 Object.defineProperty(t.prototype, strict_name_get,
571 { get: function() { return strict; },
572 configurable: true });
573 Object.defineProperty(t.prototype, nonstrict_name_get,
574 { get: function() { return nonstrict; },
575 configurable: true });
576 Object.defineProperty(t.prototype, strict_number_get,
577 { get: function() { return strict; },
578 configurable: true });
579 Object.defineProperty(t.prototype, nonstrict_number_get,
580 { get: function() { return nonstrict; },
581 configurable: true });
582 }
583
584 function cleanup(t) {
585 delete t.prototype.strict;
586 delete t.prototype.nonstrict;
587 delete t.prototype[strict_number];
588 delete t.prototype[nonstrict_number];
589 delete t.prototype[strict_name_get];
590 delete t.prototype[nonstrict_name_get];
591 delete t.prototype[strict_number_get];
592 delete t.prototype[nonstrict_number_get];
593 }
594
595 // Set up fakes
596 install(String);
597 install(Number);
598 install(Boolean)
599
600 function callStrict(o) {
601 return o.strict();
602 }
603 function callNonStrict(o) {
604 return o.nonstrict();
605 }
606 function callKeyedStrict(o) {
607 return o[strict_name]();
608 }
609 function callKeyedNonStrict(o) {
610 return o[nonstrict_name]();
611 }
612 function callIndexedStrict(o) {
613 return o[strict_number]();
614 }
615 function callIndexedNonStrict(o) {
616 return o[nonstrict_number]();
617 }
618 function callStrictGet(o) {
619 return o.strictget();
620 }
621 function callNonStrictGet(o) {
622 return o.nonstrictget();
623 }
624 function callKeyedStrictGet(o) {
625 return o[strict_name_get]();
626 }
627 function callKeyedNonStrictGet(o) {
628 return o[nonstrict_name_get]();
629 }
630 function callIndexedStrictGet(o) {
631 return o[strict_number_get]();
632 }
633 function callIndexedNonStrictGet(o) {
634 return o[nonstrict_number_get]();
635 }
636
637 for (var i = 0; i < 10; i ++) {
638 assertEquals(("hello").strict(), "string");
639 assertEquals(("hello").nonstrict(), "object");
640 assertEquals(("hello")[strict_name](), "string");
641 assertEquals(("hello")[nonstrict_name](), "object");
642 assertEquals(("hello")[strict_number](), "string");
643 assertEquals(("hello")[nonstrict_number](), "object");
644
645 assertEquals((10 + i).strict(), "number");
646 assertEquals((10 + i).nonstrict(), "object");
647 assertEquals((10 + i)[strict_name](), "number");
648 assertEquals((10 + i)[nonstrict_name](), "object");
649 assertEquals((10 + i)[strict_number](), "number");
650 assertEquals((10 + i)[nonstrict_number](), "object");
651
652 assertEquals((true).strict(), "boolean");
653 assertEquals((true).nonstrict(), "object");
654 assertEquals((true)[strict_name](), "boolean");
655 assertEquals((true)[nonstrict_name](), "object");
656 assertEquals((true)[strict_number](), "boolean");
657 assertEquals((true)[nonstrict_number](), "object");
658
659 assertEquals((false).strict(), "boolean");
660 assertEquals((false).nonstrict(), "object");
661 assertEquals((false)[strict_name](), "boolean");
662 assertEquals((false)[nonstrict_name](), "object");
663 assertEquals((false)[strict_number](), "boolean");
664 assertEquals((false)[nonstrict_number](), "object");
665
666 assertEquals(callStrict("howdy"), "string");
667 assertEquals(callNonStrict("howdy"), "object");
668 assertEquals(callKeyedStrict("howdy"), "string");
669 assertEquals(callKeyedNonStrict("howdy"), "object");
670 assertEquals(callIndexedStrict("howdy"), "string");
671 assertEquals(callIndexedNonStrict("howdy"), "object");
672
673 assertEquals(callStrict(17 + i), "number");
674 assertEquals(callNonStrict(17 + i), "object");
675 assertEquals(callKeyedStrict(17 + i), "number");
676 assertEquals(callKeyedNonStrict(17 + i), "object");
677 assertEquals(callIndexedStrict(17 + i), "number");
678 assertEquals(callIndexedNonStrict(17 + i), "object");
679
680 assertEquals(callStrict(true), "boolean");
681 assertEquals(callNonStrict(true), "object");
682 assertEquals(callKeyedStrict(true), "boolean");
683 assertEquals(callKeyedNonStrict(true), "object");
684 assertEquals(callIndexedStrict(true), "boolean");
685 assertEquals(callIndexedNonStrict(true), "object");
686
687 assertEquals(callStrict(false), "boolean");
688 assertEquals(callNonStrict(false), "object");
689 assertEquals(callKeyedStrict(false), "boolean");
690 assertEquals(callKeyedNonStrict(false), "object");
691 assertEquals(callIndexedStrict(false), "boolean");
692 assertEquals(callIndexedNonStrict(false), "object");
693
694 // All of the above, with getters
695 assertEquals(("hello").strictget(), "string");
696 assertEquals(("hello").nonstrictget(), "object");
697 assertEquals(("hello")[strict_name_get](), "string");
698 assertEquals(("hello")[nonstrict_name_get](), "object");
699 assertEquals(("hello")[strict_number_get](), "string");
700 assertEquals(("hello")[nonstrict_number_get](), "object");
701
702 assertEquals((10 + i).strictget(), "number");
703 assertEquals((10 + i).nonstrictget(), "object");
704 assertEquals((10 + i)[strict_name_get](), "number");
705 assertEquals((10 + i)[nonstrict_name_get](), "object");
706 assertEquals((10 + i)[strict_number_get](), "number");
707 assertEquals((10 + i)[nonstrict_number_get](), "object");
708
709 assertEquals((true).strictget(), "boolean");
710 assertEquals((true).nonstrictget(), "object");
711 assertEquals((true)[strict_name_get](), "boolean");
712 assertEquals((true)[nonstrict_name_get](), "object");
713 assertEquals((true)[strict_number_get](), "boolean");
714 assertEquals((true)[nonstrict_number_get](), "object");
715
716 assertEquals((false).strictget(), "boolean");
717 assertEquals((false).nonstrictget(), "object");
718 assertEquals((false)[strict_name_get](), "boolean");
719 assertEquals((false)[nonstrict_name_get](), "object");
720 assertEquals((false)[strict_number_get](), "boolean");
721 assertEquals((false)[nonstrict_number_get](), "object");
722
723 assertEquals(callStrictGet("howdy"), "string");
724 assertEquals(callNonStrictGet("howdy"), "object");
725 assertEquals(callKeyedStrictGet("howdy"), "string");
726 assertEquals(callKeyedNonStrictGet("howdy"), "object");
727 assertEquals(callIndexedStrictGet("howdy"), "string");
728 assertEquals(callIndexedNonStrictGet("howdy"), "object");
729
730 assertEquals(callStrictGet(17 + i), "number");
731 assertEquals(callNonStrictGet(17 + i), "object");
732 assertEquals(callKeyedStrictGet(17 + i), "number");
733 assertEquals(callKeyedNonStrictGet(17 + i), "object");
734 assertEquals(callIndexedStrictGet(17 + i), "number");
735 assertEquals(callIndexedNonStrictGet(17 + i), "object");
736
737 assertEquals(callStrictGet(true), "boolean");
738 assertEquals(callNonStrictGet(true), "object");
739 assertEquals(callKeyedStrictGet(true), "boolean");
740 assertEquals(callKeyedNonStrictGet(true), "object");
741 assertEquals(callIndexedStrictGet(true), "boolean");
742 assertEquals(callIndexedNonStrictGet(true), "object");
743
744 assertEquals(callStrictGet(false), "boolean");
745 assertEquals(callNonStrictGet(false), "object");
746 assertEquals(callKeyedStrictGet(false), "boolean");
747 assertEquals(callKeyedNonStrictGet(false), "object");
748 assertEquals(callIndexedStrictGet(false), "boolean");
749 assertEquals(callIndexedNonStrictGet(false), "object");
750
751 }
752 } finally {
753 // Cleanup
754 cleanup(String);
755 cleanup(Number);
756 cleanup(Boolean);
757 }
758})();
759
760
761(function ObjectEnvironment() {
762 var o = {};
763 Object.defineProperty(o, "foo", { value: "FOO", writable: false });
764 assertThrows(
765 function () {
766 with (o) {
767 (function() {
768 "use strict";
769 foo = "Hello";
770 })();
771 }
772 },
773 TypeError);
774})();
775
776
777(function TestSetPropertyWithoutSetter() {
778 var o = { get foo() { return "Yey"; } };
779 assertThrows(
780 function broken() {
781 "use strict";
782 o.foo = (0xBADBAD00 >> 1);
783 },
784 TypeError);
785})();
786
787
788(function TestSetPropertyNonConfigurable() {
789 var frozen = Object.freeze({});
790 var sealed = Object.seal({});
791
792 function strict(o) {
793 "use strict";
794 o.property = "value";
795 }
796
797 assertThrows(function() { strict(frozen); }, TypeError);
798 assertThrows(function() { strict(sealed); }, TypeError);
799})();
800
801
802(function TestAssignmentToReadOnlyProperty() {
803 "use strict";
804
805 var o = {};
806 Object.defineProperty(o, "property", { value: 7 });
807
808 assertThrows(function() { o.property = "new value"; }, TypeError);
809 assertThrows(function() { o.property += 10; }, TypeError);
810 assertThrows(function() { o.property -= 10; }, TypeError);
811 assertThrows(function() { o.property *= 10; }, TypeError);
812 assertThrows(function() { o.property /= 10; }, TypeError);
813 assertThrows(function() { o.property++; }, TypeError);
814 assertThrows(function() { o.property--; }, TypeError);
815 assertThrows(function() { ++o.property; }, TypeError);
816 assertThrows(function() { --o.property; }, TypeError);
817
818 var name = "prop" + "erty"; // to avoid symbol path.
819 assertThrows(function() { o[name] = "new value"; }, TypeError);
820 assertThrows(function() { o[name] += 10; }, TypeError);
821 assertThrows(function() { o[name] -= 10; }, TypeError);
822 assertThrows(function() { o[name] *= 10; }, TypeError);
823 assertThrows(function() { o[name] /= 10; }, TypeError);
824 assertThrows(function() { o[name]++; }, TypeError);
825 assertThrows(function() { o[name]--; }, TypeError);
826 assertThrows(function() { ++o[name]; }, TypeError);
827 assertThrows(function() { --o[name]; }, TypeError);
828
829 assertEquals(o.property, 7);
830})();
831
832
833(function TestAssignmentToReadOnlyLoop() {
834 var name = "prop" + "erty"; // to avoid symbol path.
835 var o = {};
836 Object.defineProperty(o, "property", { value: 7 });
837
838 function strict(o, name) {
839 "use strict";
840 o[name] = "new value";
841 }
842
843 for (var i = 0; i < 10; i ++) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000844 var exception = false;
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100845 try {
846 strict(o, name);
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100847 } catch(e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000848 exception = true;
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100849 assertInstanceof(e, TypeError);
850 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000851 assertTrue(exception);
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100852 }
853})();
854
855
856// Specialized KeyedStoreIC experiencing miss.
857(function testKeyedStoreICStrict() {
858 var o = [9,8,7,6,5,4,3,2,1];
859
860 function test(o, i, v) {
861 "use strict";
862 o[i] = v;
863 }
864
865 for (var i = 0; i < 10; i ++) {
866 test(o, 5, 17); // start specialized for smi indices
867 assertEquals(o[5], 17);
868 test(o, "a", 19);
869 assertEquals(o["a"], 19);
870 test(o, "5", 29);
871 assertEquals(o[5], 29);
872 test(o, 100000, 31);
873 assertEquals(o[100000], 31);
874 }
875})();
876
877
878(function TestSetElementWithoutSetter() {
879 "use strict";
880
881 var o = { };
882 Object.defineProperty(o, 0, { get : function() { } });
883
884 var zero_smi = 0;
885 var zero_number = new Number(0);
886 var zero_symbol = "0";
887 var zero_string = "-0-".substring(1,2);
888
889 assertThrows(function() { o[zero_smi] = "new value"; }, TypeError);
890 assertThrows(function() { o[zero_number] = "new value"; }, TypeError);
891 assertThrows(function() { o[zero_symbol] = "new value"; }, TypeError);
892 assertThrows(function() { o[zero_string] = "new value"; }, TypeError);
893})();
894
895
896(function TestSetElementNonConfigurable() {
897 "use strict";
898 var frozen = Object.freeze({});
899 var sealed = Object.seal({});
900
901 var zero_number = 0;
902 var zero_symbol = "0";
903 var zero_string = "-0-".substring(1,2);
904
905 assertThrows(function() { frozen[zero_number] = "value"; }, TypeError);
906 assertThrows(function() { sealed[zero_number] = "value"; }, TypeError);
907 assertThrows(function() { frozen[zero_symbol] = "value"; }, TypeError);
908 assertThrows(function() { sealed[zero_symbol] = "value"; }, TypeError);
909 assertThrows(function() { frozen[zero_string] = "value"; }, TypeError);
910 assertThrows(function() { sealed[zero_string] = "value"; }, TypeError);
911})();
912
913
914(function TestAssignmentToReadOnlyElement() {
915 "use strict";
916
917 var o = {};
918 Object.defineProperty(o, 7, { value: 17 });
919
920 var seven_smi = 7;
921 var seven_number = new Number(7);
922 var seven_symbol = "7";
923 var seven_string = "-7-".substring(1,2);
924
925 // Index with number.
926 assertThrows(function() { o[seven_smi] = "value"; }, TypeError);
927 assertThrows(function() { o[seven_smi] += 10; }, TypeError);
928 assertThrows(function() { o[seven_smi] -= 10; }, TypeError);
929 assertThrows(function() { o[seven_smi] *= 10; }, TypeError);
930 assertThrows(function() { o[seven_smi] /= 10; }, TypeError);
931 assertThrows(function() { o[seven_smi]++; }, TypeError);
932 assertThrows(function() { o[seven_smi]--; }, TypeError);
933 assertThrows(function() { ++o[seven_smi]; }, TypeError);
934 assertThrows(function() { --o[seven_smi]; }, TypeError);
935
936 assertThrows(function() { o[seven_number] = "value"; }, TypeError);
937 assertThrows(function() { o[seven_number] += 10; }, TypeError);
938 assertThrows(function() { o[seven_number] -= 10; }, TypeError);
939 assertThrows(function() { o[seven_number] *= 10; }, TypeError);
940 assertThrows(function() { o[seven_number] /= 10; }, TypeError);
941 assertThrows(function() { o[seven_number]++; }, TypeError);
942 assertThrows(function() { o[seven_number]--; }, TypeError);
943 assertThrows(function() { ++o[seven_number]; }, TypeError);
944 assertThrows(function() { --o[seven_number]; }, TypeError);
945
946 assertThrows(function() { o[seven_symbol] = "value"; }, TypeError);
947 assertThrows(function() { o[seven_symbol] += 10; }, TypeError);
948 assertThrows(function() { o[seven_symbol] -= 10; }, TypeError);
949 assertThrows(function() { o[seven_symbol] *= 10; }, TypeError);
950 assertThrows(function() { o[seven_symbol] /= 10; }, TypeError);
951 assertThrows(function() { o[seven_symbol]++; }, TypeError);
952 assertThrows(function() { o[seven_symbol]--; }, TypeError);
953 assertThrows(function() { ++o[seven_symbol]; }, TypeError);
954 assertThrows(function() { --o[seven_symbol]; }, TypeError);
955
956 assertThrows(function() { o[seven_string] = "value"; }, TypeError);
957 assertThrows(function() { o[seven_string] += 10; }, TypeError);
958 assertThrows(function() { o[seven_string] -= 10; }, TypeError);
959 assertThrows(function() { o[seven_string] *= 10; }, TypeError);
960 assertThrows(function() { o[seven_string] /= 10; }, TypeError);
961 assertThrows(function() { o[seven_string]++; }, TypeError);
962 assertThrows(function() { o[seven_string]--; }, TypeError);
963 assertThrows(function() { ++o[seven_string]; }, TypeError);
964 assertThrows(function() { --o[seven_string]; }, TypeError);
965
966 assertEquals(o[seven_number], 17);
967 assertEquals(o[seven_symbol], 17);
968 assertEquals(o[seven_string], 17);
969})();
970
971
972(function TestAssignmentToReadOnlyLoop() {
973 "use strict";
974
975 var o = {};
976 Object.defineProperty(o, 7, { value: 17 });
977
978 var seven_smi = 7;
979 var seven_number = new Number(7);
980 var seven_symbol = "7";
981 var seven_string = "-7-".substring(1,2);
982
983 for (var i = 0; i < 10; i ++) {
984 assertThrows(function() { o[seven_smi] = "value" }, TypeError);
985 assertThrows(function() { o[seven_number] = "value" }, TypeError);
986 assertThrows(function() { o[seven_symbol] = "value" }, TypeError);
987 assertThrows(function() { o[seven_string] = "value" }, TypeError);
988 }
989
990 assertEquals(o[7], 17);
991})();
992
993
994(function TestAssignmentToStringLength() {
995 "use strict";
996
997 var str_val = "string";
998 var str_obj = new String(str_val);
999 var str_cat = str_val + str_val + str_obj;
1000
1001 assertThrows(function() { str_val.length = 1; }, TypeError);
1002 assertThrows(function() { str_obj.length = 1; }, TypeError);
1003 assertThrows(function() { str_cat.length = 1; }, TypeError);
1004})();
Steve Block44f0eee2011-05-26 01:26:41 +01001005
1006
1007(function TestArgumentsAliasing() {
1008 function strict(a, b) {
1009 "use strict";
1010 a = "c";
1011 b = "d";
1012 return [a, b, arguments[0], arguments[1]];
1013 }
1014
1015 function nonstrict(a, b) {
1016 a = "c";
1017 b = "d";
1018 return [a, b, arguments[0], arguments[1]];
1019 }
1020
1021 assertEquals(["c", "d", "a", "b"], strict("a", "b"));
1022 assertEquals(["c", "d", "c", "d"], nonstrict("a", "b"));
1023})();
1024
1025
1026function CheckPillDescriptor(func, name) {
1027
1028 function CheckPill(pill) {
1029 assertEquals("function", typeof pill);
1030 assertInstanceof(pill, Function);
1031 pill.property = "value";
1032 assertEquals(pill.value, undefined);
1033 assertThrows(function() { 'use strict'; pill.property = "value"; },
1034 TypeError);
1035 assertThrows(pill, TypeError);
1036 assertEquals(pill.prototype, (function(){}).prototype);
1037 var d = Object.getOwnPropertyDescriptor(pill, "prototype");
1038 assertFalse(d.writable);
1039 assertFalse(d.configurable);
1040 assertFalse(d.enumerable);
1041 }
1042
1043 var descriptor = Object.getOwnPropertyDescriptor(func, name);
1044 CheckPill(descriptor.get)
1045 CheckPill(descriptor.set);
1046 assertFalse(descriptor.enumerable);
1047 assertFalse(descriptor.configurable);
1048}
1049
1050
1051(function TestStrictFunctionPills() {
1052 function strict() {
1053 "use strict";
1054 }
1055 assertThrows(function() { strict.caller; }, TypeError);
1056 assertThrows(function() { strict.arguments; }, TypeError);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001057 assertThrows(function() { strict.caller = 42; }, TypeError);
1058 assertThrows(function() { strict.arguments = 42; }, TypeError);
Steve Block44f0eee2011-05-26 01:26:41 +01001059
1060 var another = new Function("'use strict'");
1061 assertThrows(function() { another.caller; }, TypeError);
1062 assertThrows(function() { another.arguments; }, TypeError);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001063 assertThrows(function() { another.caller = 42; }, TypeError);
1064 assertThrows(function() { another.arguments = 42; }, TypeError);
Steve Block44f0eee2011-05-26 01:26:41 +01001065
1066 var third = (function() { "use strict"; return function() {}; })();
1067 assertThrows(function() { third.caller; }, TypeError);
1068 assertThrows(function() { third.arguments; }, TypeError);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001069 assertThrows(function() { third.caller = 42; }, TypeError);
1070 assertThrows(function() { third.arguments = 42; }, TypeError);
Steve Block44f0eee2011-05-26 01:26:41 +01001071
1072 CheckPillDescriptor(strict, "caller");
1073 CheckPillDescriptor(strict, "arguments");
1074 CheckPillDescriptor(another, "caller");
1075 CheckPillDescriptor(another, "arguments");
1076 CheckPillDescriptor(third, "caller");
1077 CheckPillDescriptor(third, "arguments");
1078})();
1079
1080
1081(function TestStrictFunctionWritablePrototype() {
1082 "use strict";
1083 function TheClass() {
1084 }
1085 assertThrows(function() { TheClass.caller; }, TypeError);
1086 assertThrows(function() { TheClass.arguments; }, TypeError);
1087
1088 // Strict functions must have writable prototype.
1089 TheClass.prototype = {
1090 func: function() { return "func_value"; },
1091 get accessor() { return "accessor_value"; },
1092 property: "property_value",
1093 };
1094
1095 var o = new TheClass();
1096 assertEquals(o.func(), "func_value");
1097 assertEquals(o.accessor, "accessor_value");
1098 assertEquals(o.property, "property_value");
1099})();
1100
1101
1102(function TestStrictArgumentPills() {
1103 function strict() {
1104 "use strict";
1105 return arguments;
1106 }
1107
1108 var args = strict();
1109 CheckPillDescriptor(args, "caller");
1110 CheckPillDescriptor(args, "callee");
1111
1112 args = strict(17, "value", strict);
1113 assertEquals(17, args[0])
1114 assertEquals("value", args[1])
1115 assertEquals(strict, args[2]);
1116 CheckPillDescriptor(args, "caller");
1117 CheckPillDescriptor(args, "callee");
1118
1119 function outer() {
1120 "use strict";
1121 function inner() {
1122 return arguments;
1123 }
1124 return inner;
1125 }
1126
1127 var args = outer()();
1128 CheckPillDescriptor(args, "caller");
1129 CheckPillDescriptor(args, "callee");
1130
1131 args = outer()(17, "value", strict);
1132 assertEquals(17, args[0])
1133 assertEquals("value", args[1])
1134 assertEquals(strict, args[2]);
1135 CheckPillDescriptor(args, "caller");
1136 CheckPillDescriptor(args, "callee");
1137})();
1138
1139
1140(function TestNonStrictFunctionCallerPillSimple() {
1141 function return_my_caller() {
1142 return return_my_caller.caller;
1143 }
1144
1145 function strict() {
1146 "use strict";
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001147 return return_my_caller();
Steve Block44f0eee2011-05-26 01:26:41 +01001148 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001149 assertSame(null, strict());
Steve Block44f0eee2011-05-26 01:26:41 +01001150
1151 function non_strict() {
1152 return return_my_caller();
1153 }
1154 assertSame(non_strict(), non_strict);
1155})();
1156
1157
1158(function TestNonStrictFunctionCallerPill() {
1159 function strict(n) {
1160 "use strict";
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001161 return non_strict(n);
Steve Block44f0eee2011-05-26 01:26:41 +01001162 }
1163
1164 function recurse(n, then) {
1165 if (n > 0) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001166 return recurse(n - 1, then);
Steve Block44f0eee2011-05-26 01:26:41 +01001167 } else {
1168 return then();
1169 }
1170 }
1171
1172 function non_strict(n) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001173 return recurse(n, function() { return non_strict.caller; });
Steve Block44f0eee2011-05-26 01:26:41 +01001174 }
1175
1176 function test(n) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001177 return recurse(n, function() { return strict(n); });
Steve Block44f0eee2011-05-26 01:26:41 +01001178 }
1179
1180 for (var i = 0; i < 10; i ++) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001181 assertSame(null, test(i));
1182 }
1183})();
1184
1185
1186(function TestNonStrictFunctionCallerDescriptorPill() {
1187 function strict(n) {
1188 "use strict";
1189 return non_strict(n);
1190 }
1191
1192 function recurse(n, then) {
1193 if (n > 0) {
1194 return recurse(n - 1, then);
1195 } else {
1196 return then();
1197 }
1198 }
1199
1200 function non_strict(n) {
1201 return recurse(n, function() {
1202 return Object.getOwnPropertyDescriptor(non_strict, "caller").value;
1203 });
1204 }
1205
1206 function test(n) {
1207 return recurse(n, function() { return strict(n); });
1208 }
1209
1210 for (var i = 0; i < 10; i ++) {
1211 assertSame(null, test(i));
Steve Block44f0eee2011-05-26 01:26:41 +01001212 }
1213})();
Ben Murdoch257744e2011-11-30 15:57:28 +00001214
1215
1216(function TestStrictModeEval() {
1217 "use strict";
1218 eval("var eval_local = 10;");
1219 assertThrows(function() { return eval_local; }, ReferenceError);
1220})();