blob: 5fb404a7990913cc953fe400315a3e4e455ced4a [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
169// Duplicate data properties.
170CheckStrictMode("var x = { dupe : 1, nondupe: 3, dupe : 2 };", SyntaxError);
171CheckStrictMode("var x = { '1234' : 1, '2345' : 2, '1234' : 3 };", SyntaxError);
172CheckStrictMode("var x = { '1234' : 1, '2345' : 2, 1234 : 3 };", SyntaxError);
173CheckStrictMode("var x = { 3.14 : 1, 2.71 : 2, 3.14 : 3 };", SyntaxError);
174CheckStrictMode("var x = { 3.14 : 1, '3.14' : 2 };", SyntaxError);
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100175CheckStrictMode("var x = { \
176 123: 1, \
177 123.00000000000000000000000000000000000000000000000000000000000000000001: 2 \
178}", SyntaxError);
Steve Block1e0659c2011-05-24 12:43:12 +0100179
180// Non-conflicting data properties.
181(function StrictModeNonDuplicate() {
182 "use strict";
183 var x = { 123 : 1, "0123" : 2 };
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100184 var x = {
185 123: 1,
186 '123.00000000000000000000000000000000000000000000000000000000000000000001':
187 2
188 };
Steve Block1e0659c2011-05-24 12:43:12 +0100189})();
190
191// Two getters (non-strict)
192assertThrows("var x = { get foo() { }, get foo() { } };", SyntaxError);
193assertThrows("var x = { get foo(){}, get 'foo'(){}};", SyntaxError);
194assertThrows("var x = { get 12(){}, get '12'(){}};", SyntaxError);
195
196// Two setters (non-strict)
197assertThrows("var x = { set foo(v) { }, set foo(v) { } };", SyntaxError);
198assertThrows("var x = { set foo(v) { }, set 'foo'(v) { } };", SyntaxError);
199assertThrows("var x = { set 13(v) { }, set '13'(v) { } };", SyntaxError);
200
201// Setter and data (non-strict)
202assertThrows("var x = { foo: 'data', set foo(v) { } };", SyntaxError);
203assertThrows("var x = { set foo(v) { }, foo: 'data' };", SyntaxError);
204assertThrows("var x = { foo: 'data', set 'foo'(v) { } };", SyntaxError);
205assertThrows("var x = { set foo(v) { }, 'foo': 'data' };", SyntaxError);
206assertThrows("var x = { 'foo': 'data', set foo(v) { } };", SyntaxError);
207assertThrows("var x = { set 'foo'(v) { }, foo: 'data' };", SyntaxError);
208assertThrows("var x = { 'foo': 'data', set 'foo'(v) { } };", SyntaxError);
209assertThrows("var x = { set 'foo'(v) { }, 'foo': 'data' };", SyntaxError);
210assertThrows("var x = { 12: 1, set '12'(v){}};", SyntaxError);
211assertThrows("var x = { 12: 1, set 12(v){}};", SyntaxError);
212assertThrows("var x = { '12': 1, set '12'(v){}};", SyntaxError);
213assertThrows("var x = { '12': 1, set 12(v){}};", SyntaxError);
214
215// Getter and data (non-strict)
216assertThrows("var x = { foo: 'data', get foo() { } };", SyntaxError);
217assertThrows("var x = { get foo() { }, foo: 'data' };", SyntaxError);
218assertThrows("var x = { 'foo': 'data', get foo() { } };", SyntaxError);
219assertThrows("var x = { get 'foo'() { }, 'foo': 'data' };", SyntaxError);
220assertThrows("var x = { '12': 1, get '12'(){}};", SyntaxError);
221assertThrows("var x = { '12': 1, get 12(){}};", SyntaxError);
222
223// Assignment to eval or arguments
224CheckStrictMode("function strict() { eval = undefined; }", SyntaxError);
225CheckStrictMode("function strict() { arguments = undefined; }", SyntaxError);
226CheckStrictMode("function strict() { print(eval = undefined); }", SyntaxError);
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100227CheckStrictMode("function strict() { print(arguments = undefined); }",
228 SyntaxError);
Steve Block1e0659c2011-05-24 12:43:12 +0100229CheckStrictMode("function strict() { var x = eval = undefined; }", SyntaxError);
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100230CheckStrictMode("function strict() { var x = arguments = undefined; }",
231 SyntaxError);
Steve Block1e0659c2011-05-24 12:43:12 +0100232
233// Compound assignment to eval or arguments
234CheckStrictMode("function strict() { eval *= undefined; }", SyntaxError);
235CheckStrictMode("function strict() { arguments /= undefined; }", SyntaxError);
236CheckStrictMode("function strict() { print(eval %= undefined); }", SyntaxError);
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100237CheckStrictMode("function strict() { print(arguments %= undefined); }",
238 SyntaxError);
239CheckStrictMode("function strict() { var x = eval += undefined; }",
240 SyntaxError);
241CheckStrictMode("function strict() { var x = arguments -= undefined; }",
242 SyntaxError);
Steve Block1e0659c2011-05-24 12:43:12 +0100243CheckStrictMode("function strict() { eval <<= undefined; }", SyntaxError);
244CheckStrictMode("function strict() { arguments >>= undefined; }", SyntaxError);
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100245CheckStrictMode("function strict() { print(eval >>>= undefined); }",
246 SyntaxError);
247CheckStrictMode("function strict() { print(arguments &= undefined); }",
248 SyntaxError);
249CheckStrictMode("function strict() { var x = eval ^= undefined; }",
250 SyntaxError);
251CheckStrictMode("function strict() { var x = arguments |= undefined; }",
252 SyntaxError);
Steve Block1e0659c2011-05-24 12:43:12 +0100253
254// Postfix increment with eval or arguments
255CheckStrictMode("function strict() { eval++; }", SyntaxError);
256CheckStrictMode("function strict() { arguments++; }", SyntaxError);
257CheckStrictMode("function strict() { print(eval++); }", SyntaxError);
258CheckStrictMode("function strict() { print(arguments++); }", SyntaxError);
259CheckStrictMode("function strict() { var x = eval++; }", SyntaxError);
260CheckStrictMode("function strict() { var x = arguments++; }", SyntaxError);
261
262// Postfix decrement with eval or arguments
263CheckStrictMode("function strict() { eval--; }", SyntaxError);
264CheckStrictMode("function strict() { arguments--; }", SyntaxError);
265CheckStrictMode("function strict() { print(eval--); }", SyntaxError);
266CheckStrictMode("function strict() { print(arguments--); }", SyntaxError);
267CheckStrictMode("function strict() { var x = eval--; }", SyntaxError);
268CheckStrictMode("function strict() { var x = arguments--; }", SyntaxError);
269
270// Prefix increment with eval or arguments
271CheckStrictMode("function strict() { ++eval; }", SyntaxError);
272CheckStrictMode("function strict() { ++arguments; }", SyntaxError);
273CheckStrictMode("function strict() { print(++eval); }", SyntaxError);
274CheckStrictMode("function strict() { print(++arguments); }", SyntaxError);
275CheckStrictMode("function strict() { var x = ++eval; }", SyntaxError);
276CheckStrictMode("function strict() { var x = ++arguments; }", SyntaxError);
277
278// Prefix decrement with eval or arguments
279CheckStrictMode("function strict() { --eval; }", SyntaxError);
280CheckStrictMode("function strict() { --arguments; }", SyntaxError);
281CheckStrictMode("function strict() { print(--eval); }", SyntaxError);
282CheckStrictMode("function strict() { print(--arguments); }", SyntaxError);
283CheckStrictMode("function strict() { var x = --eval; }", SyntaxError);
284CheckStrictMode("function strict() { var x = --arguments; }", SyntaxError);
285
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100286// Use of const in strict mode is disallowed in anticipation of ES Harmony.
287CheckStrictMode("const x = 0;", SyntaxError);
288CheckStrictMode("for (const x = 0; false;) {}", SyntaxError);
289CheckStrictMode("function strict() { const x = 0; }", SyntaxError);
290
291// Strict mode only allows functions in SourceElements
292CheckStrictMode("if (true) { function invalid() {} }", SyntaxError);
293CheckStrictMode("for (;false;) { function invalid() {} }", SyntaxError);
294CheckStrictMode("{ function invalid() {} }", SyntaxError);
295CheckStrictMode("try { function invalid() {} } catch(e) {}", SyntaxError);
296CheckStrictMode("try { } catch(e) { function invalid() {} }", SyntaxError);
297CheckStrictMode("function outer() {{ function invalid() {} }}", SyntaxError);
298
299// Delete of an unqualified identifier
300CheckStrictMode("delete unqualified;", SyntaxError);
301CheckStrictMode("function strict() { delete unqualified; }", SyntaxError);
302CheckStrictMode("function function_name() { delete function_name; }",
303 SyntaxError);
304CheckStrictMode("function strict(parameter) { delete parameter; }",
305 SyntaxError);
306CheckStrictMode("function strict() { var variable; delete variable; }",
307 SyntaxError);
308CheckStrictMode("var variable; delete variable;", SyntaxError);
309
310(function TestStrictDelete() {
311 "use strict";
312 // "delete this" is allowed in strict mode and should work.
313 function strict_delete() { delete this; }
314 strict_delete();
315})();
316
Steve Block1e0659c2011-05-24 12:43:12 +0100317// Prefix unary operators other than delete, ++, -- are valid in strict mode
318(function StrictModeUnaryOperators() {
319 "use strict";
320 var x = [void eval, typeof eval, +eval, -eval, ~eval, !eval];
321 var y = [void arguments, typeof arguments,
322 +arguments, -arguments, ~arguments, !arguments];
323})();
324
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000325// 7.6.1.2 Future Reserved Words in strict mode
326var future_strict_reserved_words = [
Steve Block1e0659c2011-05-24 12:43:12 +0100327 "implements",
328 "interface",
329 "let",
330 "package",
331 "private",
332 "protected",
333 "public",
334 "static",
335 "yield" ];
336
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000337function testFutureStrictReservedWord(word) {
Steve Block1e0659c2011-05-24 12:43:12 +0100338 // Simple use of each reserved word
339 CheckStrictMode("var " + word + " = 1;", SyntaxError);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000340 CheckStrictMode("typeof (" + word + ");", SyntaxError);
Steve Block1e0659c2011-05-24 12:43:12 +0100341
342 // object literal properties
343 eval("var x = { " + word + " : 42 };");
344 eval("var x = { get " + word + " () {} };");
345 eval("var x = { set " + word + " (value) {} };");
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000346 eval("var x = { get " + word + " () { 'use strict'; } };");
347 eval("var x = { set " + word + " (value) { 'use strict'; } };");
Steve Block1e0659c2011-05-24 12:43:12 +0100348
349 // object literal with string literal property names
350 eval("var x = { '" + word + "' : 42 };");
351 eval("var x = { get '" + word + "' () { } };");
352 eval("var x = { set '" + word + "' (value) { } };");
353 eval("var x = { get '" + word + "' () { 'use strict'; } };");
354 eval("var x = { set '" + word + "' (value) { 'use strict'; } };");
355
356 // Function names and arguments, strict and non-strict contexts
357 CheckStrictMode("function " + word + " () {}", SyntaxError);
358 CheckStrictMode("function foo (" + word + ") {}", SyntaxError);
359 CheckStrictMode("function foo (" + word + ", " + word + ") {}", SyntaxError);
360 CheckStrictMode("function foo (a, " + word + ") {}", SyntaxError);
361 CheckStrictMode("function foo (" + word + ", a) {}", SyntaxError);
362 CheckStrictMode("function foo (a, " + word + ", b) {}", SyntaxError);
363 CheckStrictMode("var foo = function (" + word + ") {}", SyntaxError);
364
365 // Function names and arguments when the body is strict
366 assertThrows("function " + word + " () { 'use strict'; }", SyntaxError);
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100367 assertThrows("function foo (" + word + ", " + word + ") { 'use strict'; }",
368 SyntaxError);
Steve Block1e0659c2011-05-24 12:43:12 +0100369 assertThrows("function foo (a, " + word + ") { 'use strict'; }", SyntaxError);
370 assertThrows("function foo (" + word + ", a) { 'use strict'; }", SyntaxError);
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100371 assertThrows("function foo (a, " + word + ", b) { 'use strict'; }",
372 SyntaxError);
373 assertThrows("var foo = function (" + word + ") { 'use strict'; }",
374 SyntaxError);
Steve Block1e0659c2011-05-24 12:43:12 +0100375
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000376 // setter parameter when the body is strict
377 CheckStrictMode("var x = { set foo(" + word + ") {} };", SyntaxError);
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100378 assertThrows("var x = { set foo(" + word + ") { 'use strict'; } };",
379 SyntaxError);
Steve Block1e0659c2011-05-24 12:43:12 +0100380}
381
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000382for (var i = 0; i < future_strict_reserved_words.length; i++) {
383 testFutureStrictReservedWord(future_strict_reserved_words[i]);
Steve Block1e0659c2011-05-24 12:43:12 +0100384}
385
Ben Murdoch8b112d22011-06-08 16:22:53 +0100386function testAssignToUndefined(test, should_throw) {
Steve Block1e0659c2011-05-24 12:43:12 +0100387 try {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100388 test();
Steve Block1e0659c2011-05-24 12:43:12 +0100389 } catch (e) {
390 assertTrue(should_throw, "strict mode");
391 assertInstanceof(e, ReferenceError, "strict mode");
392 return;
393 }
394 assertFalse(should_throw, "strict mode");
395}
396
Steve Block1e0659c2011-05-24 12:43:12 +0100397function repeat(n, f) {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100398 for (var i = 0; i < n; i ++) { f(); }
Steve Block1e0659c2011-05-24 12:43:12 +0100399}
400
Ben Murdoch8b112d22011-06-08 16:22:53 +0100401function assignToUndefined() {
402 "use strict";
403 possibly_undefined_variable_for_strict_mode_test = "should throw?";
404}
405
406testAssignToUndefined(assignToUndefined, true);
407testAssignToUndefined(assignToUndefined, true);
408testAssignToUndefined(assignToUndefined, true);
409
Steve Block1e0659c2011-05-24 12:43:12 +0100410possibly_undefined_variable_for_strict_mode_test = "value";
Ben Murdoch8b112d22011-06-08 16:22:53 +0100411
412testAssignToUndefined(assignToUndefined, false);
413testAssignToUndefined(assignToUndefined, false);
414testAssignToUndefined(assignToUndefined, false);
415
Steve Block1e0659c2011-05-24 12:43:12 +0100416delete possibly_undefined_variable_for_strict_mode_test;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100417
418testAssignToUndefined(assignToUndefined, true);
419testAssignToUndefined(assignToUndefined, true);
420testAssignToUndefined(assignToUndefined, true);
421
422repeat(10, function() { testAssignToUndefined(assignToUndefined, true); });
423possibly_undefined_variable_for_strict_mode_test = "value";
424repeat(10, function() { testAssignToUndefined(assignToUndefined, false); });
425delete possibly_undefined_variable_for_strict_mode_test;
426repeat(10, function() { testAssignToUndefined(assignToUndefined, true); });
Steve Block1e0659c2011-05-24 12:43:12 +0100427possibly_undefined_variable_for_strict_mode_test = undefined;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100428repeat(10, function() { testAssignToUndefined(assignToUndefined, false); });
429
430function assignToUndefinedWithEval() {
431 "use strict";
432 possibly_undefined_variable_for_strict_mode_test_with_eval = "should throw?";
433 eval("");
434}
435
436testAssignToUndefined(assignToUndefinedWithEval, true);
437testAssignToUndefined(assignToUndefinedWithEval, true);
438testAssignToUndefined(assignToUndefinedWithEval, true);
439
440possibly_undefined_variable_for_strict_mode_test_with_eval = "value";
441
442testAssignToUndefined(assignToUndefinedWithEval, false);
443testAssignToUndefined(assignToUndefinedWithEval, false);
444testAssignToUndefined(assignToUndefinedWithEval, false);
445
446delete possibly_undefined_variable_for_strict_mode_test_with_eval;
447
448testAssignToUndefined(assignToUndefinedWithEval, true);
449testAssignToUndefined(assignToUndefinedWithEval, true);
450testAssignToUndefined(assignToUndefinedWithEval, true);
451
452repeat(10, function() {
453 testAssignToUndefined(assignToUndefinedWithEval, true);
454 });
455possibly_undefined_variable_for_strict_mode_test_with_eval = "value";
456repeat(10, function() {
457 testAssignToUndefined(assignToUndefinedWithEval, false);
458 });
459delete possibly_undefined_variable_for_strict_mode_test_with_eval;
460repeat(10, function() {
461 testAssignToUndefined(assignToUndefinedWithEval, true);
462 });
463possibly_undefined_variable_for_strict_mode_test_with_eval = undefined;
464repeat(10, function() {
465 testAssignToUndefined(assignToUndefinedWithEval, false);
466 });
467
468
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100469
470(function testDeleteNonConfigurable() {
471 function delete_property(o) {
472 "use strict";
473 delete o.property;
474 }
475 function delete_element(o, i) {
476 "use strict";
477 delete o[i];
478 }
479
480 var object = {};
481
482 Object.defineProperty(object, "property", { value: "property_value" });
483 Object.defineProperty(object, "1", { value: "one" });
484 Object.defineProperty(object, 7, { value: "seven" });
485 Object.defineProperty(object, 3.14, { value: "pi" });
486
487 assertThrows(function() { delete_property(object); }, TypeError);
488 assertEquals(object.property, "property_value");
489 assertThrows(function() { delete_element(object, "1"); }, TypeError);
490 assertThrows(function() { delete_element(object, 1); }, TypeError);
491 assertEquals(object[1], "one");
492 assertThrows(function() { delete_element(object, "7"); }, TypeError);
493 assertThrows(function() { delete_element(object, 7); }, TypeError);
494 assertEquals(object[7], "seven");
495 assertThrows(function() { delete_element(object, "3.14"); }, TypeError);
496 assertThrows(function() { delete_element(object, 3.14); }, TypeError);
497 assertEquals(object[3.14], "pi");
498})();
499
500// Not transforming this in Function.call and Function.apply.
501(function testThisTransformCallApply() {
502 function non_strict() {
503 return this;
504 }
505 function strict() {
506 "use strict";
507 return this;
508 }
509
510 var global_object = (function() { return this; })();
511 var object = {};
512
513 // Non-strict call.
514 assertTrue(non_strict.call(null) === global_object);
515 assertTrue(non_strict.call(undefined) === global_object);
516 assertEquals(typeof non_strict.call(7), "object");
517 assertEquals(typeof non_strict.call("Hello"), "object");
518 assertTrue(non_strict.call(object) === object);
519
520 // Non-strict apply.
521 assertTrue(non_strict.apply(null) === global_object);
522 assertTrue(non_strict.apply(undefined) === global_object);
523 assertEquals(typeof non_strict.apply(7), "object");
524 assertEquals(typeof non_strict.apply("Hello"), "object");
525 assertTrue(non_strict.apply(object) === object);
526
527 // Strict call.
528 assertTrue(strict.call(null) === null);
529 assertTrue(strict.call(undefined) === undefined);
530 assertEquals(typeof strict.call(7), "number");
531 assertEquals(typeof strict.call("Hello"), "string");
532 assertTrue(strict.call(object) === object);
533
534 // Strict apply.
535 assertTrue(strict.apply(null) === null);
536 assertTrue(strict.apply(undefined) === undefined);
537 assertEquals(typeof strict.apply(7), "number");
538 assertEquals(typeof strict.apply("Hello"), "string");
539 assertTrue(strict.apply(object) === object);
540})();
541
542(function testThisTransform() {
543 try {
544 function strict() {
545 "use strict";
546 return typeof(this);
547 }
548 function nonstrict() {
549 return typeof(this);
550 }
551
552 // Concat to avoid symbol.
553 var strict_name = "str" + "ict";
554 var nonstrict_name = "non" + "str" + "ict";
555 var strict_number = 17;
556 var nonstrict_number = 19;
557 var strict_name_get = "str" + "ict" + "get";
558 var nonstrict_name_get = "non" + "str" + "ict" + "get"
559 var strict_number_get = 23;
560 var nonstrict_number_get = 29;
561
562 function install(t) {
563 t.prototype.strict = strict;
564 t.prototype.nonstrict = nonstrict;
565 t.prototype[strict_number] = strict;
566 t.prototype[nonstrict_number] = nonstrict;
567 Object.defineProperty(t.prototype, strict_name_get,
568 { get: function() { return strict; },
569 configurable: true });
570 Object.defineProperty(t.prototype, nonstrict_name_get,
571 { get: function() { return nonstrict; },
572 configurable: true });
573 Object.defineProperty(t.prototype, strict_number_get,
574 { get: function() { return strict; },
575 configurable: true });
576 Object.defineProperty(t.prototype, nonstrict_number_get,
577 { get: function() { return nonstrict; },
578 configurable: true });
579 }
580
581 function cleanup(t) {
582 delete t.prototype.strict;
583 delete t.prototype.nonstrict;
584 delete t.prototype[strict_number];
585 delete t.prototype[nonstrict_number];
586 delete t.prototype[strict_name_get];
587 delete t.prototype[nonstrict_name_get];
588 delete t.prototype[strict_number_get];
589 delete t.prototype[nonstrict_number_get];
590 }
591
592 // Set up fakes
593 install(String);
594 install(Number);
595 install(Boolean)
596
597 function callStrict(o) {
598 return o.strict();
599 }
600 function callNonStrict(o) {
601 return o.nonstrict();
602 }
603 function callKeyedStrict(o) {
604 return o[strict_name]();
605 }
606 function callKeyedNonStrict(o) {
607 return o[nonstrict_name]();
608 }
609 function callIndexedStrict(o) {
610 return o[strict_number]();
611 }
612 function callIndexedNonStrict(o) {
613 return o[nonstrict_number]();
614 }
615 function callStrictGet(o) {
616 return o.strictget();
617 }
618 function callNonStrictGet(o) {
619 return o.nonstrictget();
620 }
621 function callKeyedStrictGet(o) {
622 return o[strict_name_get]();
623 }
624 function callKeyedNonStrictGet(o) {
625 return o[nonstrict_name_get]();
626 }
627 function callIndexedStrictGet(o) {
628 return o[strict_number_get]();
629 }
630 function callIndexedNonStrictGet(o) {
631 return o[nonstrict_number_get]();
632 }
633
634 for (var i = 0; i < 10; i ++) {
635 assertEquals(("hello").strict(), "string");
636 assertEquals(("hello").nonstrict(), "object");
637 assertEquals(("hello")[strict_name](), "string");
638 assertEquals(("hello")[nonstrict_name](), "object");
639 assertEquals(("hello")[strict_number](), "string");
640 assertEquals(("hello")[nonstrict_number](), "object");
641
642 assertEquals((10 + i).strict(), "number");
643 assertEquals((10 + i).nonstrict(), "object");
644 assertEquals((10 + i)[strict_name](), "number");
645 assertEquals((10 + i)[nonstrict_name](), "object");
646 assertEquals((10 + i)[strict_number](), "number");
647 assertEquals((10 + i)[nonstrict_number](), "object");
648
649 assertEquals((true).strict(), "boolean");
650 assertEquals((true).nonstrict(), "object");
651 assertEquals((true)[strict_name](), "boolean");
652 assertEquals((true)[nonstrict_name](), "object");
653 assertEquals((true)[strict_number](), "boolean");
654 assertEquals((true)[nonstrict_number](), "object");
655
656 assertEquals((false).strict(), "boolean");
657 assertEquals((false).nonstrict(), "object");
658 assertEquals((false)[strict_name](), "boolean");
659 assertEquals((false)[nonstrict_name](), "object");
660 assertEquals((false)[strict_number](), "boolean");
661 assertEquals((false)[nonstrict_number](), "object");
662
663 assertEquals(callStrict("howdy"), "string");
664 assertEquals(callNonStrict("howdy"), "object");
665 assertEquals(callKeyedStrict("howdy"), "string");
666 assertEquals(callKeyedNonStrict("howdy"), "object");
667 assertEquals(callIndexedStrict("howdy"), "string");
668 assertEquals(callIndexedNonStrict("howdy"), "object");
669
670 assertEquals(callStrict(17 + i), "number");
671 assertEquals(callNonStrict(17 + i), "object");
672 assertEquals(callKeyedStrict(17 + i), "number");
673 assertEquals(callKeyedNonStrict(17 + i), "object");
674 assertEquals(callIndexedStrict(17 + i), "number");
675 assertEquals(callIndexedNonStrict(17 + i), "object");
676
677 assertEquals(callStrict(true), "boolean");
678 assertEquals(callNonStrict(true), "object");
679 assertEquals(callKeyedStrict(true), "boolean");
680 assertEquals(callKeyedNonStrict(true), "object");
681 assertEquals(callIndexedStrict(true), "boolean");
682 assertEquals(callIndexedNonStrict(true), "object");
683
684 assertEquals(callStrict(false), "boolean");
685 assertEquals(callNonStrict(false), "object");
686 assertEquals(callKeyedStrict(false), "boolean");
687 assertEquals(callKeyedNonStrict(false), "object");
688 assertEquals(callIndexedStrict(false), "boolean");
689 assertEquals(callIndexedNonStrict(false), "object");
690
691 // All of the above, with getters
692 assertEquals(("hello").strictget(), "string");
693 assertEquals(("hello").nonstrictget(), "object");
694 assertEquals(("hello")[strict_name_get](), "string");
695 assertEquals(("hello")[nonstrict_name_get](), "object");
696 assertEquals(("hello")[strict_number_get](), "string");
697 assertEquals(("hello")[nonstrict_number_get](), "object");
698
699 assertEquals((10 + i).strictget(), "number");
700 assertEquals((10 + i).nonstrictget(), "object");
701 assertEquals((10 + i)[strict_name_get](), "number");
702 assertEquals((10 + i)[nonstrict_name_get](), "object");
703 assertEquals((10 + i)[strict_number_get](), "number");
704 assertEquals((10 + i)[nonstrict_number_get](), "object");
705
706 assertEquals((true).strictget(), "boolean");
707 assertEquals((true).nonstrictget(), "object");
708 assertEquals((true)[strict_name_get](), "boolean");
709 assertEquals((true)[nonstrict_name_get](), "object");
710 assertEquals((true)[strict_number_get](), "boolean");
711 assertEquals((true)[nonstrict_number_get](), "object");
712
713 assertEquals((false).strictget(), "boolean");
714 assertEquals((false).nonstrictget(), "object");
715 assertEquals((false)[strict_name_get](), "boolean");
716 assertEquals((false)[nonstrict_name_get](), "object");
717 assertEquals((false)[strict_number_get](), "boolean");
718 assertEquals((false)[nonstrict_number_get](), "object");
719
720 assertEquals(callStrictGet("howdy"), "string");
721 assertEquals(callNonStrictGet("howdy"), "object");
722 assertEquals(callKeyedStrictGet("howdy"), "string");
723 assertEquals(callKeyedNonStrictGet("howdy"), "object");
724 assertEquals(callIndexedStrictGet("howdy"), "string");
725 assertEquals(callIndexedNonStrictGet("howdy"), "object");
726
727 assertEquals(callStrictGet(17 + i), "number");
728 assertEquals(callNonStrictGet(17 + i), "object");
729 assertEquals(callKeyedStrictGet(17 + i), "number");
730 assertEquals(callKeyedNonStrictGet(17 + i), "object");
731 assertEquals(callIndexedStrictGet(17 + i), "number");
732 assertEquals(callIndexedNonStrictGet(17 + i), "object");
733
734 assertEquals(callStrictGet(true), "boolean");
735 assertEquals(callNonStrictGet(true), "object");
736 assertEquals(callKeyedStrictGet(true), "boolean");
737 assertEquals(callKeyedNonStrictGet(true), "object");
738 assertEquals(callIndexedStrictGet(true), "boolean");
739 assertEquals(callIndexedNonStrictGet(true), "object");
740
741 assertEquals(callStrictGet(false), "boolean");
742 assertEquals(callNonStrictGet(false), "object");
743 assertEquals(callKeyedStrictGet(false), "boolean");
744 assertEquals(callKeyedNonStrictGet(false), "object");
745 assertEquals(callIndexedStrictGet(false), "boolean");
746 assertEquals(callIndexedNonStrictGet(false), "object");
747
748 }
749 } finally {
750 // Cleanup
751 cleanup(String);
752 cleanup(Number);
753 cleanup(Boolean);
754 }
755})();
756
757
758(function ObjectEnvironment() {
759 var o = {};
760 Object.defineProperty(o, "foo", { value: "FOO", writable: false });
761 assertThrows(
762 function () {
763 with (o) {
764 (function() {
765 "use strict";
766 foo = "Hello";
767 })();
768 }
769 },
770 TypeError);
771})();
772
773
774(function TestSetPropertyWithoutSetter() {
775 var o = { get foo() { return "Yey"; } };
776 assertThrows(
777 function broken() {
778 "use strict";
779 o.foo = (0xBADBAD00 >> 1);
780 },
781 TypeError);
782})();
783
784
785(function TestSetPropertyNonConfigurable() {
786 var frozen = Object.freeze({});
787 var sealed = Object.seal({});
788
789 function strict(o) {
790 "use strict";
791 o.property = "value";
792 }
793
794 assertThrows(function() { strict(frozen); }, TypeError);
795 assertThrows(function() { strict(sealed); }, TypeError);
796})();
797
798
799(function TestAssignmentToReadOnlyProperty() {
800 "use strict";
801
802 var o = {};
803 Object.defineProperty(o, "property", { value: 7 });
804
805 assertThrows(function() { o.property = "new value"; }, TypeError);
806 assertThrows(function() { o.property += 10; }, TypeError);
807 assertThrows(function() { o.property -= 10; }, TypeError);
808 assertThrows(function() { o.property *= 10; }, TypeError);
809 assertThrows(function() { o.property /= 10; }, TypeError);
810 assertThrows(function() { o.property++; }, TypeError);
811 assertThrows(function() { o.property--; }, TypeError);
812 assertThrows(function() { ++o.property; }, TypeError);
813 assertThrows(function() { --o.property; }, TypeError);
814
815 var name = "prop" + "erty"; // to avoid symbol path.
816 assertThrows(function() { o[name] = "new value"; }, TypeError);
817 assertThrows(function() { o[name] += 10; }, TypeError);
818 assertThrows(function() { o[name] -= 10; }, TypeError);
819 assertThrows(function() { o[name] *= 10; }, TypeError);
820 assertThrows(function() { o[name] /= 10; }, TypeError);
821 assertThrows(function() { o[name]++; }, TypeError);
822 assertThrows(function() { o[name]--; }, TypeError);
823 assertThrows(function() { ++o[name]; }, TypeError);
824 assertThrows(function() { --o[name]; }, TypeError);
825
826 assertEquals(o.property, 7);
827})();
828
829
830(function TestAssignmentToReadOnlyLoop() {
831 var name = "prop" + "erty"; // to avoid symbol path.
832 var o = {};
833 Object.defineProperty(o, "property", { value: 7 });
834
835 function strict(o, name) {
836 "use strict";
837 o[name] = "new value";
838 }
839
840 for (var i = 0; i < 10; i ++) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000841 var exception = false;
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100842 try {
843 strict(o, name);
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100844 } catch(e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000845 exception = true;
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100846 assertInstanceof(e, TypeError);
847 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000848 assertTrue(exception);
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100849 }
850})();
851
852
853// Specialized KeyedStoreIC experiencing miss.
854(function testKeyedStoreICStrict() {
855 var o = [9,8,7,6,5,4,3,2,1];
856
857 function test(o, i, v) {
858 "use strict";
859 o[i] = v;
860 }
861
862 for (var i = 0; i < 10; i ++) {
863 test(o, 5, 17); // start specialized for smi indices
864 assertEquals(o[5], 17);
865 test(o, "a", 19);
866 assertEquals(o["a"], 19);
867 test(o, "5", 29);
868 assertEquals(o[5], 29);
869 test(o, 100000, 31);
870 assertEquals(o[100000], 31);
871 }
872})();
873
874
875(function TestSetElementWithoutSetter() {
876 "use strict";
877
878 var o = { };
879 Object.defineProperty(o, 0, { get : function() { } });
880
881 var zero_smi = 0;
882 var zero_number = new Number(0);
883 var zero_symbol = "0";
884 var zero_string = "-0-".substring(1,2);
885
886 assertThrows(function() { o[zero_smi] = "new value"; }, TypeError);
887 assertThrows(function() { o[zero_number] = "new value"; }, TypeError);
888 assertThrows(function() { o[zero_symbol] = "new value"; }, TypeError);
889 assertThrows(function() { o[zero_string] = "new value"; }, TypeError);
890})();
891
892
893(function TestSetElementNonConfigurable() {
894 "use strict";
895 var frozen = Object.freeze({});
896 var sealed = Object.seal({});
897
898 var zero_number = 0;
899 var zero_symbol = "0";
900 var zero_string = "-0-".substring(1,2);
901
902 assertThrows(function() { frozen[zero_number] = "value"; }, TypeError);
903 assertThrows(function() { sealed[zero_number] = "value"; }, TypeError);
904 assertThrows(function() { frozen[zero_symbol] = "value"; }, TypeError);
905 assertThrows(function() { sealed[zero_symbol] = "value"; }, TypeError);
906 assertThrows(function() { frozen[zero_string] = "value"; }, TypeError);
907 assertThrows(function() { sealed[zero_string] = "value"; }, TypeError);
908})();
909
910
911(function TestAssignmentToReadOnlyElement() {
912 "use strict";
913
914 var o = {};
915 Object.defineProperty(o, 7, { value: 17 });
916
917 var seven_smi = 7;
918 var seven_number = new Number(7);
919 var seven_symbol = "7";
920 var seven_string = "-7-".substring(1,2);
921
922 // Index with number.
923 assertThrows(function() { o[seven_smi] = "value"; }, TypeError);
924 assertThrows(function() { o[seven_smi] += 10; }, TypeError);
925 assertThrows(function() { o[seven_smi] -= 10; }, TypeError);
926 assertThrows(function() { o[seven_smi] *= 10; }, TypeError);
927 assertThrows(function() { o[seven_smi] /= 10; }, TypeError);
928 assertThrows(function() { o[seven_smi]++; }, TypeError);
929 assertThrows(function() { o[seven_smi]--; }, TypeError);
930 assertThrows(function() { ++o[seven_smi]; }, TypeError);
931 assertThrows(function() { --o[seven_smi]; }, TypeError);
932
933 assertThrows(function() { o[seven_number] = "value"; }, TypeError);
934 assertThrows(function() { o[seven_number] += 10; }, TypeError);
935 assertThrows(function() { o[seven_number] -= 10; }, TypeError);
936 assertThrows(function() { o[seven_number] *= 10; }, TypeError);
937 assertThrows(function() { o[seven_number] /= 10; }, TypeError);
938 assertThrows(function() { o[seven_number]++; }, TypeError);
939 assertThrows(function() { o[seven_number]--; }, TypeError);
940 assertThrows(function() { ++o[seven_number]; }, TypeError);
941 assertThrows(function() { --o[seven_number]; }, TypeError);
942
943 assertThrows(function() { o[seven_symbol] = "value"; }, TypeError);
944 assertThrows(function() { o[seven_symbol] += 10; }, TypeError);
945 assertThrows(function() { o[seven_symbol] -= 10; }, TypeError);
946 assertThrows(function() { o[seven_symbol] *= 10; }, TypeError);
947 assertThrows(function() { o[seven_symbol] /= 10; }, TypeError);
948 assertThrows(function() { o[seven_symbol]++; }, TypeError);
949 assertThrows(function() { o[seven_symbol]--; }, TypeError);
950 assertThrows(function() { ++o[seven_symbol]; }, TypeError);
951 assertThrows(function() { --o[seven_symbol]; }, TypeError);
952
953 assertThrows(function() { o[seven_string] = "value"; }, TypeError);
954 assertThrows(function() { o[seven_string] += 10; }, TypeError);
955 assertThrows(function() { o[seven_string] -= 10; }, TypeError);
956 assertThrows(function() { o[seven_string] *= 10; }, TypeError);
957 assertThrows(function() { o[seven_string] /= 10; }, TypeError);
958 assertThrows(function() { o[seven_string]++; }, TypeError);
959 assertThrows(function() { o[seven_string]--; }, TypeError);
960 assertThrows(function() { ++o[seven_string]; }, TypeError);
961 assertThrows(function() { --o[seven_string]; }, TypeError);
962
963 assertEquals(o[seven_number], 17);
964 assertEquals(o[seven_symbol], 17);
965 assertEquals(o[seven_string], 17);
966})();
967
968
969(function TestAssignmentToReadOnlyLoop() {
970 "use strict";
971
972 var o = {};
973 Object.defineProperty(o, 7, { value: 17 });
974
975 var seven_smi = 7;
976 var seven_number = new Number(7);
977 var seven_symbol = "7";
978 var seven_string = "-7-".substring(1,2);
979
980 for (var i = 0; i < 10; i ++) {
981 assertThrows(function() { o[seven_smi] = "value" }, TypeError);
982 assertThrows(function() { o[seven_number] = "value" }, TypeError);
983 assertThrows(function() { o[seven_symbol] = "value" }, TypeError);
984 assertThrows(function() { o[seven_string] = "value" }, TypeError);
985 }
986
987 assertEquals(o[7], 17);
988})();
989
990
991(function TestAssignmentToStringLength() {
992 "use strict";
993
994 var str_val = "string";
995 var str_obj = new String(str_val);
996 var str_cat = str_val + str_val + str_obj;
997
998 assertThrows(function() { str_val.length = 1; }, TypeError);
999 assertThrows(function() { str_obj.length = 1; }, TypeError);
1000 assertThrows(function() { str_cat.length = 1; }, TypeError);
1001})();
Steve Block44f0eee2011-05-26 01:26:41 +01001002
1003
1004(function TestArgumentsAliasing() {
1005 function strict(a, b) {
1006 "use strict";
1007 a = "c";
1008 b = "d";
1009 return [a, b, arguments[0], arguments[1]];
1010 }
1011
1012 function nonstrict(a, b) {
1013 a = "c";
1014 b = "d";
1015 return [a, b, arguments[0], arguments[1]];
1016 }
1017
1018 assertEquals(["c", "d", "a", "b"], strict("a", "b"));
1019 assertEquals(["c", "d", "c", "d"], nonstrict("a", "b"));
1020})();
1021
1022
1023function CheckPillDescriptor(func, name) {
1024
1025 function CheckPill(pill) {
1026 assertEquals("function", typeof pill);
1027 assertInstanceof(pill, Function);
1028 pill.property = "value";
1029 assertEquals(pill.value, undefined);
1030 assertThrows(function() { 'use strict'; pill.property = "value"; },
1031 TypeError);
1032 assertThrows(pill, TypeError);
1033 assertEquals(pill.prototype, (function(){}).prototype);
1034 var d = Object.getOwnPropertyDescriptor(pill, "prototype");
1035 assertFalse(d.writable);
1036 assertFalse(d.configurable);
1037 assertFalse(d.enumerable);
1038 }
1039
1040 var descriptor = Object.getOwnPropertyDescriptor(func, name);
1041 CheckPill(descriptor.get)
1042 CheckPill(descriptor.set);
1043 assertFalse(descriptor.enumerable);
1044 assertFalse(descriptor.configurable);
1045}
1046
1047
1048(function TestStrictFunctionPills() {
1049 function strict() {
1050 "use strict";
1051 }
1052 assertThrows(function() { strict.caller; }, TypeError);
1053 assertThrows(function() { strict.arguments; }, TypeError);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001054 assertThrows(function() { strict.caller = 42; }, TypeError);
1055 assertThrows(function() { strict.arguments = 42; }, TypeError);
Steve Block44f0eee2011-05-26 01:26:41 +01001056
1057 var another = new Function("'use strict'");
1058 assertThrows(function() { another.caller; }, TypeError);
1059 assertThrows(function() { another.arguments; }, TypeError);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001060 assertThrows(function() { another.caller = 42; }, TypeError);
1061 assertThrows(function() { another.arguments = 42; }, TypeError);
Steve Block44f0eee2011-05-26 01:26:41 +01001062
1063 var third = (function() { "use strict"; return function() {}; })();
1064 assertThrows(function() { third.caller; }, TypeError);
1065 assertThrows(function() { third.arguments; }, TypeError);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001066 assertThrows(function() { third.caller = 42; }, TypeError);
1067 assertThrows(function() { third.arguments = 42; }, TypeError);
Steve Block44f0eee2011-05-26 01:26:41 +01001068
1069 CheckPillDescriptor(strict, "caller");
1070 CheckPillDescriptor(strict, "arguments");
1071 CheckPillDescriptor(another, "caller");
1072 CheckPillDescriptor(another, "arguments");
1073 CheckPillDescriptor(third, "caller");
1074 CheckPillDescriptor(third, "arguments");
1075})();
1076
1077
1078(function TestStrictFunctionWritablePrototype() {
1079 "use strict";
1080 function TheClass() {
1081 }
1082 assertThrows(function() { TheClass.caller; }, TypeError);
1083 assertThrows(function() { TheClass.arguments; }, TypeError);
1084
1085 // Strict functions must have writable prototype.
1086 TheClass.prototype = {
1087 func: function() { return "func_value"; },
1088 get accessor() { return "accessor_value"; },
1089 property: "property_value",
1090 };
1091
1092 var o = new TheClass();
1093 assertEquals(o.func(), "func_value");
1094 assertEquals(o.accessor, "accessor_value");
1095 assertEquals(o.property, "property_value");
1096})();
1097
1098
1099(function TestStrictArgumentPills() {
1100 function strict() {
1101 "use strict";
1102 return arguments;
1103 }
1104
1105 var args = strict();
1106 CheckPillDescriptor(args, "caller");
1107 CheckPillDescriptor(args, "callee");
1108
1109 args = strict(17, "value", strict);
1110 assertEquals(17, args[0])
1111 assertEquals("value", args[1])
1112 assertEquals(strict, args[2]);
1113 CheckPillDescriptor(args, "caller");
1114 CheckPillDescriptor(args, "callee");
1115
1116 function outer() {
1117 "use strict";
1118 function inner() {
1119 return arguments;
1120 }
1121 return inner;
1122 }
1123
1124 var args = outer()();
1125 CheckPillDescriptor(args, "caller");
1126 CheckPillDescriptor(args, "callee");
1127
1128 args = outer()(17, "value", strict);
1129 assertEquals(17, args[0])
1130 assertEquals("value", args[1])
1131 assertEquals(strict, args[2]);
1132 CheckPillDescriptor(args, "caller");
1133 CheckPillDescriptor(args, "callee");
1134})();
1135
1136
1137(function TestNonStrictFunctionCallerPillSimple() {
1138 function return_my_caller() {
1139 return return_my_caller.caller;
1140 }
1141
1142 function strict() {
1143 "use strict";
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001144 return return_my_caller();
Steve Block44f0eee2011-05-26 01:26:41 +01001145 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001146 assertSame(null, strict());
Steve Block44f0eee2011-05-26 01:26:41 +01001147
1148 function non_strict() {
1149 return return_my_caller();
1150 }
1151 assertSame(non_strict(), non_strict);
1152})();
1153
1154
1155(function TestNonStrictFunctionCallerPill() {
1156 function strict(n) {
1157 "use strict";
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001158 return non_strict(n);
Steve Block44f0eee2011-05-26 01:26:41 +01001159 }
1160
1161 function recurse(n, then) {
1162 if (n > 0) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001163 return recurse(n - 1, then);
Steve Block44f0eee2011-05-26 01:26:41 +01001164 } else {
1165 return then();
1166 }
1167 }
1168
1169 function non_strict(n) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001170 return recurse(n, function() { return non_strict.caller; });
Steve Block44f0eee2011-05-26 01:26:41 +01001171 }
1172
1173 function test(n) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001174 return recurse(n, function() { return strict(n); });
Steve Block44f0eee2011-05-26 01:26:41 +01001175 }
1176
1177 for (var i = 0; i < 10; i ++) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001178 assertSame(null, test(i));
1179 }
1180})();
1181
1182
1183(function TestNonStrictFunctionCallerDescriptorPill() {
1184 function strict(n) {
1185 "use strict";
1186 return non_strict(n);
1187 }
1188
1189 function recurse(n, then) {
1190 if (n > 0) {
1191 return recurse(n - 1, then);
1192 } else {
1193 return then();
1194 }
1195 }
1196
1197 function non_strict(n) {
1198 return recurse(n, function() {
1199 return Object.getOwnPropertyDescriptor(non_strict, "caller").value;
1200 });
1201 }
1202
1203 function test(n) {
1204 return recurse(n, function() { return strict(n); });
1205 }
1206
1207 for (var i = 0; i < 10; i ++) {
1208 assertSame(null, test(i));
Steve Block44f0eee2011-05-26 01:26:41 +01001209 }
1210})();
Ben Murdoch257744e2011-11-30 15:57:28 +00001211
1212
1213(function TestStrictModeEval() {
1214 "use strict";
1215 eval("var eval_local = 10;");
1216 assertThrows(function() { return eval_local; }, ReferenceError);
1217})();