|
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
|
2 /* |
|
3 * Any copyright is dedicated to the Public Domain. |
|
4 * http://creativecommons.org/licenses/publicdomain/ |
|
5 */ |
|
6 |
|
7 var actual; |
|
8 var expect = "pass"; |
|
9 |
|
10 var x = "fail"; |
|
11 function f() { |
|
12 var x = "pass"; |
|
13 delete(eval("actual = x")); |
|
14 } |
|
15 f(); |
|
16 assertEq(actual, expect); |
|
17 |
|
18 function g() { return 1 } |
|
19 function h() { function g() { throw 2; } eval('g()')++; } |
|
20 |
|
21 try { |
|
22 h(); |
|
23 assertEq(0, -1); |
|
24 } catch (e) { |
|
25 assertEq(e, 2); |
|
26 } |
|
27 |
|
28 var lhs_prefix = ["", "++", "--", "", "", "[", "[y, " ]; |
|
29 var lhs_suffix = [" = 'no'", "", "", "++", "--", ", y] = [3, 4]", "] = [5, 6]"]; |
|
30 |
|
31 for (var i = 0; i < lhs_prefix.length; i++) { |
|
32 try { |
|
33 eval(lhs_prefix[i] + "eval('x')" + lhs_suffix[i]); |
|
34 assertEq(i, -2); |
|
35 } catch (e) { |
|
36 /* |
|
37 * NB: JSOP_SETCALL throws only JSMSG_BAD_LEFTSIDE_OF_ASS, it does not |
|
38 * specialize for ++ and -- as the compiler's error reporting does. See |
|
39 * the next section's forked assertEq code. |
|
40 */ |
|
41 assertEq(e.message, "invalid assignment left-hand side"); |
|
42 } |
|
43 } |
|
44 |
|
45 /* Destructuring desugars in the obvious way, so y must be 5 here. */ |
|
46 assertEq(y, 5); |
|
47 |
|
48 /* Now test for strict mode rejecting any SETCALL variant at compile time. */ |
|
49 for (var i = 0; i < lhs_prefix.length; i++) { |
|
50 try { |
|
51 eval("(function () { 'use strict'; " + lhs_prefix[i] + "foo('x')" + lhs_suffix[i] + "; })"); |
|
52 assertEq(i, -3); |
|
53 } catch (e) { |
|
54 if (/\+\+|\-\-/.test(lhs_prefix[i] || lhs_suffix[i])) |
|
55 assertEq(e.message, "invalid increment/decrement operand"); |
|
56 else |
|
57 assertEq(e.message, "invalid assignment left-hand side"); |
|
58 } |
|
59 } |
|
60 |
|
61 /* |
|
62 * The useless delete is optimized away, but the SETCALL must not be. It's not |
|
63 * an early error, though. |
|
64 */ |
|
65 var fooArg; |
|
66 function foo(arg) { fooArg = arg; } |
|
67 try { |
|
68 eval("delete (foo('x') = 42);"); |
|
69 assertEq(0, -4); |
|
70 } catch (e) { |
|
71 assertEq(e.message, "invalid assignment left-hand side"); |
|
72 } |
|
73 assertEq(fooArg, 'x'); |
|
74 |
|
75 /* Delete of a call expression is not an error at all, even in strict mode. */ |
|
76 function g() { |
|
77 "use strict"; |
|
78 assertEq(delete Object(), true); |
|
79 } |
|
80 g(); |
|
81 |
|
82 reportCompare(0, 0, "ok"); |