1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
// Make sure we get the proper side effects.
// |delete super[expr]| applies ToPropertyKey on |expr| before throwing.
class base {
constructor() { }
}
class derived extends base {
constructor() { super(); }
testDeleteElem() {
let sideEffect = 0;
let key = {
toString() {
sideEffect++;
return "";
}
};
assertThrowsInstanceOf(() => delete super[key], ReferenceError);
assertEq(sideEffect, 1);
}
testDeleteElemPropValFirst() {
// The deletion error is a reference error, but by munging the prototype
// chain, we can force a type error from JSOP_SUPERBASE.
let key = {
toString() {
Object.setPrototypeOf(derived.prototype, null);
return "";
}
};
delete super[key];
}
}
class derivedTestDeleteElem extends base {
constructor() {
let sideEffect = 0;
let key = {
toString() {
sideEffect++;
return "";
}
};
assertThrowsInstanceOf(() => delete super[key], ReferenceError);
assertEq(sideEffect, 0);
super();
assertThrowsInstanceOf(() => delete super[key], ReferenceError);
assertEq(sideEffect, 1);
Object.setPrototypeOf(derivedTestDeleteElem.prototype, null);
assertThrowsInstanceOf(() => delete super[key], TypeError);
assertEq(sideEffect, 2);
return {};
}
}
var d = new derived();
d.testDeleteElem();
assertThrowsInstanceOf(() => d.testDeleteElemPropValFirst(), TypeError);
new derivedTestDeleteElem();
if (typeof reportCompare === 'function')
reportCompare(0,0,"OK");
|