Attachment #8676409: Handle cross-compartment WeakSets for bug #1198352

View | Details | Raw Unified | Return to bug 1198352
Collapse All | Expand All

(-)a/js/src/builtin/WeakSet.js (-4 / +4 lines)
Line     Link Here 
 Lines 2-18    Link Here 
2
 * License, v. 2.0. If a copy of the MPL was not distributed with this
2
 * License, v. 2.0. If a copy of the MPL was not distributed with this
3
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
3
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
4
5
// 23.4.3.1
5
// 23.4.3.1
6
function WeakSet_add(value) {
6
function WeakSet_add(value) {
7
    // Steps 1-3.
7
    // Steps 1-3.
8
    var S = this;
8
    var S = this;
9
    if (!IsObject(S) || !IsWeakSet(S))
9
    if (!IsObject(S) || !IsWeakSet(S))
10
        ThrowTypeError(JSMSG_INCOMPATIBLE_PROTO, "WeakSet", "add", typeof S);
10
        return callFunction(CallWeakSetMethodIfWrapped, this, value, "WeakSet_add");
11
11
12
    // Step 4.,6.
12
    // Step 4.,6.
13
    let entries = UnsafeGetReservedSlot(this, WEAKSET_MAP_SLOT);
13
    let entries = UnsafeGetReservedSlot(this, WEAKSET_MAP_SLOT);
14
    if (!entries)
14
    if (!entries)
15
        ThrowTypeError(JSMSG_INCOMPATIBLE_PROTO, "WeakSet", "add", typeof S);
15
        ThrowTypeError(JSMSG_INCOMPATIBLE_PROTO, "WeakSet", "add", typeof S);
16
16
17
    // Step 5.
17
    // Step 5.
18
    if (!IsObject(value))
18
    if (!IsObject(value))
 Lines 25-41   function WeakSet_add(value) { Link Here 
25
    return S;
25
    return S;
26
}
26
}
27
27
28
// 23.4.3.2
28
// 23.4.3.2
29
function WeakSet_clear() {
29
function WeakSet_clear() {
30
    // Step 1-3.
30
    // Step 1-3.
31
    var S = this;
31
    var S = this;
32
    if (!IsObject(S) || !IsWeakSet(S))
32
    if (!IsObject(S) || !IsWeakSet(S))
33
        ThrowTypeError(JSMSG_INCOMPATIBLE_PROTO, "WeakSet", "clear", typeof S);
33
        return callFunction(CallWeakSetMethodIfWrapped, this, "WeakSet_clear");
34
34
35
    // Step 4.
35
    // Step 4.
36
    let entries = UnsafeGetReservedSlot(this, WEAKSET_MAP_SLOT);
36
    let entries = UnsafeGetReservedSlot(this, WEAKSET_MAP_SLOT);
37
    if (!entries)
37
    if (!entries)
38
        ThrowTypeError(JSMSG_INCOMPATIBLE_PROTO, "WeakSet", "clear", typeof S);
38
        ThrowTypeError(JSMSG_INCOMPATIBLE_PROTO, "WeakSet", "clear", typeof S);
39
39
40
    // Step 5.
40
    // Step 5.
41
    callFunction(std_WeakMap_clear, entries);
41
    callFunction(std_WeakMap_clear, entries);
 Lines 44-60   function WeakSet_clear() { Link Here 
44
    return undefined;
44
    return undefined;
45
}
45
}
46
46
47
// 23.4.3.4
47
// 23.4.3.4
48
function WeakSet_delete(value) {
48
function WeakSet_delete(value) {
49
    // Steps 1-3.
49
    // Steps 1-3.
50
    var S = this;
50
    var S = this;
51
    if (!IsObject(S) || !IsWeakSet(S))
51
    if (!IsObject(S) || !IsWeakSet(S))
52
        ThrowTypeError(JSMSG_INCOMPATIBLE_PROTO, "WeakSet", "delete", typeof S);
52
        return callFunction(CallWeakSetMethodIfWrapped, this, value, "WeakSet_delete");
53
53
54
    // Step 4.,6.
54
    // Step 4.,6.
55
    let entries = UnsafeGetReservedSlot(this, WEAKSET_MAP_SLOT);
55
    let entries = UnsafeGetReservedSlot(this, WEAKSET_MAP_SLOT);
56
    if (!entries)
56
    if (!entries)
57
        ThrowTypeError(JSMSG_INCOMPATIBLE_PROTO, "WeakSet", "delete", typeof S);
57
        ThrowTypeError(JSMSG_INCOMPATIBLE_PROTO, "WeakSet", "delete", typeof S);
58
58
59
    // Step 5.
59
    // Step 5.
60
    if (!IsObject(value))
60
    if (!IsObject(value))
 Lines 64-80   function WeakSet_delete(value) { Link Here 
64
    return callFunction(std_WeakMap_delete, entries, value);
64
    return callFunction(std_WeakMap_delete, entries, value);
65
}
65
}
66
66
67
// 23.4.3.5
67
// 23.4.3.5
68
function WeakSet_has(value) {
68
function WeakSet_has(value) {
69
    // Steps 1-3.
69
    // Steps 1-3.
70
    var S = this;
70
    var S = this;
71
    if (!IsObject(S) || !IsWeakSet(S))
71
    if (!IsObject(S) || !IsWeakSet(S))
72
        ThrowTypeError(JSMSG_INCOMPATIBLE_PROTO, "WeakSet", "has", typeof S);
72
        return callFunction(CallWeakSetMethodIfWrapped, this, value, "WeakSet_has");
73
73
74
    // Step 4-5.
74
    // Step 4-5.
75
    let entries = UnsafeGetReservedSlot(this, WEAKSET_MAP_SLOT);
75
    let entries = UnsafeGetReservedSlot(this, WEAKSET_MAP_SLOT);
76
    if (!entries)
76
    if (!entries)
77
        ThrowTypeError(JSMSG_INCOMPATIBLE_PROTO, "WeakSet", "has", typeof S);
77
        ThrowTypeError(JSMSG_INCOMPATIBLE_PROTO, "WeakSet", "has", typeof S);
78
78
79
    // Step 6.
79
    // Step 6.
80
    if (!IsObject(value))
80
    if (!IsObject(value))
(-)a/js/src/jit-test/tests/collections/WeakSet-clear.js (+8 lines)
Line     Link Here 
 Lines 35-42   ws.add(value); Link Here 
35
value = null;
35
value = null;
36
ws.clear();
36
ws.clear();
37
gc();
37
gc();
38
var value2 = {};
38
var value2 = {};
39
ws.add(value2);
39
ws.add(value2);
40
value2 = null;
40
value2 = null;
41
gc();
41
gc();
42
ws.clear();
42
ws.clear();
43
44
// Clearing a cross-compartment WeakSet with a live value
45
ws = new (newGlobal().WeakSet);
46
value = {};
47
WeakSet.prototype.add.call(ws, value);
48
assertEq(WeakSet.prototype.has.call(ws, value), true);
49
WeakSet.prototype.clear.call(ws);
50
assertEq(WeakSet.prototype.has.call(ws, value), false);
(-)a/js/src/jit-test/tests/collections/WeakSet-delete.js (+8 lines)
Line     Link Here 
 Lines 24-31   assertEq(ws.add(value), ws); Link Here 
24
assertEq(ws.has(value), true);
24
assertEq(ws.has(value), true);
25
assertEq(ws.delete(value), true);
25
assertEq(ws.delete(value), true);
26
assertEq(ws.has(value), false);
26
assertEq(ws.has(value), false);
27
assertEq(ws.delete(value), false);
27
assertEq(ws.delete(value), false);
28
assertEq(ws.has(value), false);
28
assertEq(ws.has(value), false);
29
29
30
// Delete primitive
30
// Delete primitive
31
assertEq(ws.delete(15), false);
31
assertEq(ws.delete(15), false);
32
33
// Delete with cross-compartment WeakSet
34
ws = new (newGlobal().WeakSet);
35
WeakSet.prototype.add.call(ws, value);
36
assertEq(WeakSet.prototype.has.call(ws, value), true);
37
assertEq(WeakSet.prototype.delete.call(ws, value), true);
38
assertEq(WeakSet.prototype.has.call(ws, value), false);
39
assertEq(WeakSet.prototype.delete.call(ws, value), false);
(-)a/js/src/vm/SelfHosting.cpp (+2 lines)
Line     Link Here 
 Lines 1530-1545   static const JSFunctionSpec intrinsic_fu Link Here 
1530
          CallNonGenericSelfhostedMethod<Is<TypedArrayObject>>, 2, 0),
1530
          CallNonGenericSelfhostedMethod<Is<TypedArrayObject>>, 2, 0),
1531
1531
1532
    JS_FN("CallLegacyGeneratorMethodIfWrapped",
1532
    JS_FN("CallLegacyGeneratorMethodIfWrapped",
1533
          CallNonGenericSelfhostedMethod<Is<LegacyGeneratorObject>>, 2, 0),
1533
          CallNonGenericSelfhostedMethod<Is<LegacyGeneratorObject>>, 2, 0),
1534
    JS_FN("CallStarGeneratorMethodIfWrapped",
1534
    JS_FN("CallStarGeneratorMethodIfWrapped",
1535
          CallNonGenericSelfhostedMethod<Is<StarGeneratorObject>>, 2, 0),
1535
          CallNonGenericSelfhostedMethod<Is<StarGeneratorObject>>, 2, 0),
1536
1536
1537
    JS_FN("IsWeakSet",               intrinsic_IsWeakSet,               1,0),
1537
    JS_FN("IsWeakSet",               intrinsic_IsWeakSet,               1,0),
1538
    JS_FN("CallWeakSetMethodIfWrapped",
1539
          CallNonGenericSelfhostedMethod<Is<WeakSetObject>>, 2, 0),
1538
1540
1539
    // See builtin/TypedObject.h for descriptors of the typedobj functions.
1541
    // See builtin/TypedObject.h for descriptors of the typedobj functions.
1540
    JS_FN("NewOpaqueTypedObject",           js::NewOpaqueTypedObject, 1, 0),
1542
    JS_FN("NewOpaqueTypedObject",           js::NewOpaqueTypedObject, 1, 0),
1541
    JS_FN("NewDerivedTypedObject",          js::NewDerivedTypedObject, 3, 0),
1543
    JS_FN("NewDerivedTypedObject",          js::NewDerivedTypedObject, 3, 0),
1542
    JS_FN("TypedObjectBuffer",              TypedObject::GetBuffer, 1, 0),
1544
    JS_FN("TypedObjectBuffer",              TypedObject::GetBuffer, 1, 0),
1543
    JS_FN("TypedObjectByteOffset",          TypedObject::GetByteOffset, 1, 0),
1545
    JS_FN("TypedObjectByteOffset",          TypedObject::GetByteOffset, 1, 0),
1544
    JS_FN("AttachTypedObject",              js::AttachTypedObject, 3, 0),
1546
    JS_FN("AttachTypedObject",              js::AttachTypedObject, 3, 0),
1545
    JS_FN("TypedObjectIsAttached",          js::TypedObjectIsAttached, 1, 0),
1547
    JS_FN("TypedObjectIsAttached",          js::TypedObjectIsAttached, 1, 0),

Return to bug 1198352