|
1 load(libdir + "asserts.js"); |
|
2 |
|
3 function check_one(expected, f, err) { |
|
4 var failed = true; |
|
5 try { |
|
6 f(); |
|
7 failed = false; |
|
8 } catch (ex) { |
|
9 var s = ex.toString(); |
|
10 assertEq(s.slice(0, 11), "TypeError: "); |
|
11 assertEq(s.slice(-err.length), err, "" + f); |
|
12 assertEq(s.slice(11, -err.length), expected); |
|
13 } |
|
14 if (!failed) |
|
15 throw new Error("didn't fail"); |
|
16 } |
|
17 ieval = eval; |
|
18 function check(expr, expected=expr) { |
|
19 var end, err; |
|
20 for ([end, err] of [[".random_prop", " is undefined"], ["()", " is not a function"]]) { |
|
21 var statement = "o = {};" + expr + end, f; |
|
22 var cases = [ |
|
23 // Global scope |
|
24 function () { |
|
25 ieval("var o, undef;\n" + statement); |
|
26 }, |
|
27 // Function scope |
|
28 Function("o", "undef", statement), |
|
29 // Function scope with variables |
|
30 Function("var o, undef;\n" + statement), |
|
31 // Function scope with some different arugments |
|
32 Function("arg1", "arg2", "var o, undef;\n" + statement), |
|
33 // Deoptimized function scope |
|
34 Function("o", "undef", "with (Object) {}\n" + statement), |
|
35 // Inside with |
|
36 Function("with (Object) { " + statement + " }"), |
|
37 // Closure |
|
38 Function("o", "undef", "function myfunc() { return o + undef; }\n" + statement), |
|
39 // Let definitions in a block |
|
40 Function("{ let o, undef;\n" + statement + "}"), |
|
41 // Let block |
|
42 Function("let (o, undef) { " + statement + " }"), |
|
43 // Let block with some other variables |
|
44 Function("var v1, v2; let (o, undef) { " + statement + " }"), |
|
45 // Shadowed let block |
|
46 Function("o", "undef", "let (o, undef) { " + statement + " }"), |
|
47 // Let in a switch |
|
48 Function("var x = 4; switch (x) { case 4: let o, undef;" + statement + "\ncase 6: break;}"), |
|
49 // The more lets the merrier |
|
50 Function("let (x=4, y=5) { x + y; }\nlet (a, b, c) { a + b - c; }\nlet (o, undef) {" + statement + " }"), |
|
51 // Let destructuring |
|
52 Function("o", "undef", "let ([] = 4) {} let (o, undef) { " + statement + " }"), |
|
53 // Try-catch blocks |
|
54 Function("o", "undef", "try { let q = 4; try { let p = 4; } catch (e) {} } catch (e) {} let (o, undef) { " + statement + " }") |
|
55 ]; |
|
56 |
|
57 try { |
|
58 // Let in for-in |
|
59 check_one(expected, |
|
60 Function("var undef, o; for (let z in [1, 2]) { " + statement + " }"), |
|
61 err); |
|
62 } catch (ex) { |
|
63 // Bug 831120. See bug 942804 comment 5. |
|
64 if (expected == 'undef' && err == ' is undefined') |
|
65 check_one(expected + end, |
|
66 Function("var undef, o; for (let z in [1, 2]) { " + statement + " }"), |
|
67 err); |
|
68 else |
|
69 throw ex; |
|
70 } |
|
71 |
|
72 for (var f of cases) { |
|
73 check_one(expected, f, err); |
|
74 } |
|
75 } |
|
76 } |
|
77 |
|
78 check("undef"); |
|
79 check("o.b"); |
|
80 check("o.length"); |
|
81 check("o[true]"); |
|
82 check("o[false]"); |
|
83 check("o[null]"); |
|
84 check("o[0]"); |
|
85 check("o[1]"); |
|
86 check("o[3]"); |
|
87 check("o[256]"); |
|
88 check("o[65536]"); |
|
89 check("o[268435455]"); |
|
90 check("o['1.1']"); |
|
91 check("o[4 + 'h']", "o['4h']"); |
|
92 check("this.x"); |
|
93 check("ieval(undef)", "ieval(...)"); |
|
94 check("ieval.call()", "ieval.call(...)"); |
|
95 check("ieval(...[])", "ieval(...)"); |
|
96 check("ieval(...[undef])", "ieval(...)"); |
|
97 check("ieval(...[undef, undef])", "ieval(...)"); |
|
98 |
|
99 for (let tok of ["|", "^", "&", "==", "!==", "===", "!==", "<", "<=", ">", ">=", |
|
100 ">>", "<<", ">>>", "+", "-", "*", "/", "%"]) { |
|
101 check("o[(undef " + tok + " 4)]"); |
|
102 } |
|
103 |
|
104 check("o[!(o)]"); |
|
105 check("o[~(o)]"); |
|
106 check("o[+ (o)]"); |
|
107 check("o[- (o)]"); |
|
108 |
|
109 // A few one off tests |
|
110 check_one("6", (function () { 6() }), " is not a function"); |
|
111 check_one("Array.prototype.reverse.call(...)", (function () { Array.prototype.reverse.call('123'); }), " is read-only"); |
|
112 check_one("null", function () { var [{ x }] = [null, {}]; }, " has no properties"); |
|
113 check_one("x", function () { ieval("let (x) { var [a, b, [c0, c1]] = [x, x, x]; }") }, " is undefined"); |
|
114 |
|
115 // Check fallback behavior |
|
116 assertThrowsInstanceOf(function () { for (let x of undefined) {} }, TypeError); |