Source code

Revision control

Copy as Markdown

Other Tools

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// ES2017 draft rev 0e10c9f29fca1385980c08a7d5e7bb3eb775e2e4
// 23.2.1.1 Set, steps 6-8
function SetConstructorInit(iterable) {
var set = this;
// Step 6.a.
var adder = set.add;
// Step 6.b.
if (!IsCallable(adder)) {
ThrowTypeError(JSMSG_NOT_FUNCTION, typeof adder);
}
// Steps 6.c-8.
for (var nextValue of allowContentIter(iterable)) {
callContentFunction(adder, set, nextValue);
}
}
// ES2018 draft rev f83aa38282c2a60c6916ebc410bfdf105a0f6a54
// 23.2.3.6 Set.prototype.forEach ( callbackfn [ , thisArg ] )
function SetForEach(callbackfn, thisArg = undefined) {
// Step 1.
var S = this;
// Steps 2-3.
if (!IsObject(S) || (S = GuardToSetObject(S)) === null) {
return callFunction(
CallSetMethodIfWrapped,
this,
callbackfn,
thisArg,
"SetForEach"
);
}
// Step 4.
if (!IsCallable(callbackfn)) {
ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn));
}
// Steps 5-8.
var values = callFunction(std_Set_values, S);
// Inlined: SetIteratorNext
var setIterationResult = globalSetIterationResult;
while (true) {
var done = GetNextSetEntryForIterator(values, setIterationResult);
if (done) {
break;
}
var value = setIterationResult[0];
setIterationResult[0] = null;
callContentFunction(callbackfn, thisArg, value, value, S);
}
}
// ES6 final draft 23.2.2.2.
// Uncloned functions with `$` prefix are allocated as extended function
// to store the original name in `SetCanonicalName`.
function $SetSpecies() {
// Step 1.
return this;
}
SetCanonicalName($SetSpecies, "get [Symbol.species]");
var globalSetIterationResult = CreateSetIterationResult();
function SetIteratorNext() {
// Step 1.
var O = this;
// Steps 2-3.
if (!IsObject(O) || (O = GuardToSetIterator(O)) === null) {
return callFunction(
CallSetIteratorMethodIfWrapped,
this,
"SetIteratorNext"
);
}
// Steps 4-5 (implemented in GetNextSetEntryForIterator).
// Steps 8-9 (omitted).
var setIterationResult = globalSetIterationResult;
var retVal = { value: undefined, done: true };
// Steps 10.a, 11.
var done = GetNextSetEntryForIterator(O, setIterationResult);
if (!done) {
// Steps 10.b-c (omitted).
// Step 6.
var itemKind = UnsafeGetInt32FromReservedSlot(O, ITERATOR_SLOT_ITEM_KIND);
var result;
if (itemKind === ITEM_KIND_VALUE) {
// Step 10.d.i.
result = setIterationResult[0];
} else {
// Step 10.d.ii.
assert(itemKind === ITEM_KIND_KEY_AND_VALUE, itemKind);
result = [setIterationResult[0], setIterationResult[0]];
}
setIterationResult[0] = null;
retVal.value = result;
retVal.done = false;
}
// Steps 7, 10.d, 12.
return retVal;
}
#ifdef NIGHTLY_BUILD
// GetSetRecord ( obj )
//
function GetSetRecord(obj) {
// Step 1.
if (!IsObject(obj)) {
ThrowTypeError(JSMSG_OBJECT_REQUIRED, obj === null ? "null" : typeof obj);
}
// Step 2.
var rawSize = obj.size;
// Step 3.
var numSize = +rawSize;
// Steps 4-5.
if (numSize !== numSize) {
if (rawSize === undefined) {
ThrowTypeError(JSMSG_UNEXPECTED_TYPE, "size", "undefined");
} else {
ThrowTypeError(JSMSG_UNEXPECTED_TYPE, "size", "NaN");
}
}
// Step 6.
var intSize = ToInteger(numSize);
// Step 7.
if (intSize < 0) {
ThrowRangeError(JSMSG_SET_NEGATIVE_SIZE);
}
// Step 8.
var has = obj.has;
// Step 9.
if (!IsCallable(has)) {
ThrowTypeError(JSMSG_PROPERTY_NOT_CALLABLE, "has");
}
// Step 10.
var keys = obj.keys;
// Step 11.
if (!IsCallable(keys)) {
ThrowTypeError(JSMSG_PROPERTY_NOT_CALLABLE, "keys");
}
// Step 12.
return { set: obj, size: intSize, has, keys };
}
// 7.4.2 GetIteratorFromMethod ( obj, method )
//
// ES2024 draft rev a103b287cd19bdc51c7a3d8d7c1431b1506a74e2
function GetIteratorFromMethod(setRec) {
// Step 1.
var keysIter = callContentFunction(setRec.keys, setRec.set);
// Step 2.
if (!IsObject(keysIter)) {
ThrowTypeError(
JSMSG_OBJECT_REQUIRED,
keysIter === null ? "null" : typeof keysIter
);
}
// Step 3. (Implemented in caller.)
// Step 4.
return keysIter;
}
// Set.prototype.union ( other )
//
function SetUnion(other) {
// Step 1.
var O = this;
// Step 2.
if (!IsObject(O) || (O = GuardToSetObject(O)) === null) {
return callFunction(CallSetMethodIfWrapped, this, other, "SetUnion");
}
// Step 3.
var otherRec = GetSetRecord(other);
// Step 4.
var keysIter = GetIteratorFromMethod(otherRec);
var keysIterNext = keysIter.next;
// Steps 5 and 8-9. (Reordered)
var result = SetCopy(O);
// Steps 6-7.
for (var nextValue of allowContentIterWithNext(keysIter, keysIterNext)) {
// Step 7.a and 7.b.i. (Implicit through for-of loop)
// Steps 7.b.ii-iii. (Implicit through std_Set_add)
// Step 7.b.iii.1.
callFunction(std_Set_add, result, nextValue);
}
// Step 10.
return result;
}
// Set.prototype.intersection ( other )
//
function SetIntersection(other) {
// Step 1.
var O = this;
// Step 2.
if (!IsObject(O) || (O = GuardToSetObject(O)) === null) {
return callFunction(CallSetMethodIfWrapped, this, other, "SetIntersection");
}
// Step 3.
var otherRec = GetSetRecord(other);
// Steps 4 and 8-9. (Reordered)
var Set = GetBuiltinConstructor("Set");
var result = new Set();
// Step 5.
var thisSize = callFunction(std_Set_size, O);
// Steps 6-7.
if (thisSize <= otherRec.size) {
// Steps 6.a-b.
var values = callFunction(std_Set_values, O);
var setIterationResult = globalSetIterationResult;
while (true) {
var done = GetNextSetEntryForIterator(values, setIterationResult);
if (done) {
break;
}
var value = setIterationResult[0];
setIterationResult[0] = null;
// Steps 6.b.i-ii. (Implicit through SetIterator)
// Steps 6.b.iii.1-2.
if (callContentFunction(otherRec.has, otherRec.set, value)) {
// Steps 6.b.iii.2.a-b. (Implicit through std_Set_add)
// Step 6.b.iii.2.c.i.
callFunction(std_Set_add, result, value);
}
// Steps 6.b.iii.3-4. (Implicit through SetIterator)
}
} else {
// Step 7.a.
var keysIter = GetIteratorFromMethod(otherRec);
// Steps 7.b-c.
for (var nextValue of allowContentIterWithNext(keysIter, keysIter.next)) {
// Step 7.c.i and 7.c.ii.1. (Implicit through for-of loop)
// Steps 7.c.ii.2-4. (Implicit through std_Set_add)
// Steps 7.c.ii.5-6.
if (callFunction(std_Set_has, O, nextValue)) {
callFunction(std_Set_add, result, nextValue);
}
}
}
// Step 10.
return result;
}
// Set.prototype.difference ( other )
//
function SetDifference(other) {
// Step 1.
var O = this;
// Step 2.
if (!IsObject(O) || (O = GuardToSetObject(O)) === null) {
return callFunction(CallSetMethodIfWrapped, this, other, "SetDifference");
}
// Step 3.
var otherRec = GetSetRecord(other);
// Steps 4 and 8-9. (Reordered)
var result = SetCopy(O);
// Step 5.
var thisSize = callFunction(std_Set_size, O);
// Steps 6-7.
if (thisSize <= otherRec.size) {
// Steps 6.a-b.
var values = callFunction(std_Set_values, result);
var setIterationResult = globalSetIterationResult;
while (true) {
var done = GetNextSetEntryForIterator(values, setIterationResult);
if (done) {
break;
}
var value = setIterationResult[0];
setIterationResult[0] = null;
// Steps 6.b.i-ii. (Implicit through SetIterator)
// Steps 6.b.iii.1-2.
if (callContentFunction(otherRec.has, otherRec.set, value)) {
callFunction(std_Set_delete, result, value);
}
}
} else {
// Step 7.a.
var keysIter = GetIteratorFromMethod(otherRec);
// Steps 7.b-c.
for (var nextValue of allowContentIterWithNext(keysIter, keysIter.next)) {
// Step 7.c.i and 7.c.ii.1. (Implicit through for-of loop)
// Steps 7.c.ii.2-3.
callFunction(std_Set_delete, result, nextValue);
}
}
// Step 10.
return result;
}
// Set.prototype.symmetricDifference ( other )
//
function SetSymmetricDifference(other) {
// Step 1.
var O = this;
// Step 2.
if (!IsObject(O) || (O = GuardToSetObject(O)) === null) {
return callFunction(
CallSetMethodIfWrapped,
this,
other,
"SetSymmetricDifference"
);
}
// Step 3.
var otherRec = GetSetRecord(other);
// Step 4.
var keysIter = GetIteratorFromMethod(otherRec);
var keysIterNext = keysIter.next;
// Steps 5 and 8-9. (Reordered)
var result = SetCopy(O);
// Steps 6-7.
for (var nextValue of allowContentIterWithNext(keysIter, keysIterNext)) {
// Step 7.a and 7.b.i. (Implicit through for-of loop)
// Steps 7.b.ii-iii. (Implicit through std_Set_has)
// Steps 7.b.iv-v.
if (callFunction(std_Set_has, O, nextValue)) {
// Step 7.b.iv.1.
callFunction(std_Set_delete, result, nextValue);
} else {
// Step 7.b.v.1.
callFunction(std_Set_add, result, nextValue);
}
}
// Step 10.
return result;
}
// Set.prototype.isSubsetOf ( other )
//
function SetIsSubsetOf(other) {
// Step 1.
var O = this;
// Step 2.
if (!IsObject(O) || (O = GuardToSetObject(O)) === null) {
return callFunction(CallSetMethodIfWrapped, this, other, "SetIsSubsetOf");
}
// Step 3.
var otherRec = GetSetRecord(other);
// Step 4.
var thisSize = callFunction(std_Set_size, O);
// Step 5.
if (thisSize > otherRec.size) {
return false;
}
// Steps 6-7.
var values = callFunction(std_Set_values, O);
var setIterationResult = globalSetIterationResult;
while (true) {
var done = GetNextSetEntryForIterator(values, setIterationResult);
if (done) {
break;
}
var value = setIterationResult[0];
setIterationResult[0] = null;
// Steps 7.a-b. (Implicit through SetIterator)
// Steps 7.c-d.
if (!callContentFunction(otherRec.has, otherRec.set, value)) {
return false;
}
// Steps 7.e-f. (Implicit through SetIterator)
}
// Step 7.
return true;
}
// Set.prototype.isSupersetOf ( other )
//
function SetIsSupersetOf(other) {
// Step 1.
var O = this;
// Step 2.
if (!IsObject(O) || (O = GuardToSetObject(O)) === null) {
return callFunction(CallSetMethodIfWrapped, this, other, "SetIsSupersetOf");
}
// Step 3.
var otherRec = GetSetRecord(other);
// Step 4.
var thisSize = callFunction(std_Set_size, O);
// Step 5.
if (thisSize < otherRec.size) {
return false;
}
// Step 6.
var keysIter = GetIteratorFromMethod(otherRec);
// Steps 7-8.
for (var nextValue of allowContentIterWithNext(keysIter, keysIter.next)) {
// Step 8.a and 8.b.i. (Implicit through for-of loop)
// Step 8.b.ii.
if (!callFunction(std_Set_has, O, nextValue)) {
// Step 8.b.ii.1. (Implicit through for-of loop)
// Step 8.b.ii.2.
return false;
}
}
// Step 9.
return true;
}
// Set.prototype.isDisjointFrom ( other )
//
function SetIsDisjointFrom(other) {
// Step 1.
var O = this;
// Step 2.
if (!IsObject(O) || (O = GuardToSetObject(O)) === null) {
return callFunction(
CallSetMethodIfWrapped,
this,
other,
"SetIsDisjointFrom"
);
}
// Step 3.
var otherRec = GetSetRecord(other);
// Step 4.
var thisSize = callFunction(std_Set_size, O);
// Steps 5-6.
if (thisSize <= otherRec.size) {
// Steps 5.a-b.
var values = callFunction(std_Set_values, O);
var setIterationResult = globalSetIterationResult;
while (true) {
var done = GetNextSetEntryForIterator(values, setIterationResult);
if (done) {
break;
}
var value = setIterationResult[0];
setIterationResult[0] = null;
// Step 5.b.i-ii. (Implicit through SetIterator)
// Steps 5.b.iii.1-2.
if (callContentFunction(otherRec.has, otherRec.set, value)) {
return false;
}
// Steps 5.b.iii.3-4. (Implicit through SetIterator)
}
} else {
// Step 6.a.
var keysIter = GetIteratorFromMethod(otherRec);
// Steps 6.b-c.
for (var nextValue of allowContentIterWithNext(keysIter, keysIter.next)) {
// Step 6.c.i and 6.c.ii.1. (Implicit through for-of loop)
// Step 6.c.ii.2.
if (callFunction(std_Set_has, O, nextValue)) {
// Step 6.c.ii.2.a. (Implicit through for-of loop)
// Step 6.c.ii.2.b.
return false;
}
}
}
// Step 7.
return true;
}
#endif