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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
function getLogString(obj) {
let log = getWatchtowerLog();
return log.map(item => {
assertEq(item.object, obj);
if (typeof item.extra === "symbol") {
item.extra = "<symbol>";
}
return item.kind + (item.extra ? ": " + item.extra : "");
}).join("\n");
}
function testBasic() {
let o = {};
addWatchtowerTarget(o);
o.x = 1;
o.y = 2;
o[Symbol()] = 3;
Object.defineProperty(o, "foo", {enumerable: false, configurable: false, value: 1});
Object.defineProperty(o, "getter", {get() { return 123; }});
o.__proto__ = {};
o.__proto__ = null;
o[12345] = 1; // Sparse elements are included for now.
delete o.x;
Object.defineProperty(o, "y", {writable: false});
Object.defineProperty(o, "x", {value: 0});
Object.seal(o);
Object.freeze(o);
let log = getLogString(o);
assertEq(log,
`add-prop: x
add-prop: y
add-prop: <symbol>
add-prop: foo
add-prop: getter
proto-change
proto-change
add-prop: 12345
remove-prop: x
change-prop: y
add-prop: x
freeze-or-seal
freeze-or-seal`);
}
for (var i = 0; i < 20; i++) {
testBasic();
}
// Object.assign edge case.
function testAssign() {
let o = {};
o.x = 1;
delete o.x;
let from = {x: 1, y: 2, z: 3, a: 4};
addWatchtowerTarget(o);
addWatchtowerTarget(from);
Object.assign(o, from);
let log = getLogString(o);
assertEq(log, "add-prop: x\nadd-prop: y\nadd-prop: z\nadd-prop: a");
}
testAssign();
function testJit() {
for (var i = 0; i < 20; i++) {
let o = {};
addWatchtowerTarget(o);
o.x = 1;
o.y = 2;
let log = getLogString(o);
assertEq(log, "add-prop: x\nadd-prop: y");
}
}
testJit();
// array.length is a custom data property.
function testCustomDataProp() {
let o = [];
addWatchtowerTarget(o);
Object.defineProperty(o, "length", {writable: false});
let log = getLogString(o);
assertEq(log, "change-prop: length");
}
for (var i = 0; i < 20; i++) {
testCustomDataProp();
}
|