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
|
// https://tc39.es/proposal-weakrefs/#sec-keepduringjob
// When the abstract operation KeepDuringJob is called with a target object
// reference, it adds the target to an identity Set that will point strongly at
// the target until the end of the current Job.
//
// https://tc39.es/proposal-weakrefs/#sec-weakref-invariants
// When WeakRef.prototype.deref is called, the referent (if it's not already
// dead) is kept alive so that subsequent, synchronous accesses also return the
// object.
let wr;
{
let obj = {};
wr = new WeakRef(obj);
obj = null;
}
// obj is out of block scope now, should be GCed.
gc();
assertEq(undefined == wr.deref(), false);
// test for target is in another zone.
var g = newGlobal({newCompartment: true});
var wr2 = new g.WeakRef({});
assertEq(undefined == wr2.deref(), false);
let wr3 = g.eval("new WeakRef({})");
let wr4 = new WeakRef(evalcx('({})', newGlobal({newCompartment: true})));
let wr5 = new g.WeakRef(evalcx('({})', newGlobal({newCompartment: true})));
var that = this;
(function(){
let wr6 = new g.WeakRef(newGlobal({newCompartment: true}));
let wr7 = new WeakRef(wr6);
let wr8 = new WeakRef(that);
wr6 = null;
wr7 = null;
wr8 = null;
})();
gc();
let wr1;
// Allocate the object in the function to prevent marked as a singleton so the
// object won't be kept alive by IC stub.
function allocObj() { return {}; }
(function () {
let obj = allocObj();
wr1 = new WeakRef(obj);
obj = null;
})();
assertEq(undefined === wr1.deref(), false);
gc();
// See https://tc39.es/proposal-weakrefs/#sec-weakref-invariants
// This list is reset when synchronous work is done using the
// ClearKeptObjects abstract operation.
//
// TODO:
// Bug 1603070: The shell has no way to start a new task.
//
// In shell, there's no window object hence there isn't a setTimeout nor event
// handler, so we use this function to simulate that.
// The timeout function in shell doesn't launch a new job, and it will cause
// this test file timeout so I didn't use it here.
function simulateEndOfJob(fn) {
clearKeptObjects();
gc();
fn();
}
simulateEndOfJob(() => {
assertEq(undefined, wr1.deref());
});
|