forked from v8/v8
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This CL adds a slow (generic) implementation of isSubsetOf method to set methods. Bug: v8:13556 Change-Id: Id80e7f3be598ea07cca7f5051377899730e2a103 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4656300 Reviewed-by: Shu-yu Guo <syg@chromium.org> Commit-Queue: Rezvan Mahdavi Hezaveh <rezvan@chromium.org> Cr-Commit-Position: refs/heads/main@{#89240}
- Loading branch information
Showing
6 changed files
with
250 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
// Copyright 2023 the V8 project authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
namespace collections { | ||
|
||
// https://tc39.es/proposal-set-methods/#sec-set.prototype.issubsetof | ||
transitioning javascript builtin SetPrototypeIsSubsetOf( | ||
js-implicit context: NativeContext, | ||
receiver: JSAny)(other: JSAny): Boolean { | ||
const methodName: constexpr string = 'Set.prototype.isSubsetOf'; | ||
|
||
// 1. Let O be the this value. | ||
// 2. Perform ? RequireInternalSlot(O, [[SetData]]). | ||
const o = Cast<JSSet>(receiver) otherwise | ||
ThrowTypeError( | ||
MessageTemplate::kIncompatibleMethodReceiver, methodName, receiver); | ||
|
||
const table = Cast<OrderedHashSet>(o.table) otherwise unreachable; | ||
|
||
// 3. Let otherRec be ? GetSetRecord(other). | ||
let otherRec = GetSetRecord(other, methodName); | ||
|
||
// 4. Let thisSize be the number of elements in O.[[SetData]]. | ||
const thisSize = | ||
LoadOrderedHashTableMetadata(table, kOrderedHashSetNumberOfElementsIndex); | ||
|
||
// 5. If thisSize > otherRec.[[Size]], return false. | ||
if (thisSize > Convert<int32>(otherRec.size)) { | ||
return False; | ||
} | ||
|
||
// 6. Let index be 0. | ||
let thisIter = collections::NewOrderedHashSetIterator(table); | ||
let key: JSAny; | ||
|
||
// 7. Repeat, while index < thisSize, | ||
while (true) { | ||
try { | ||
// a. Let e be O.[[SetData]][index]. | ||
key = thisIter.Next() otherwise Done; | ||
} label Done { | ||
// 8. Return true. | ||
return True; | ||
} | ||
|
||
// b. Set index to index + 1. | ||
// c. Let inOther be ToBoolean(? Call(otherRec.[[Has]], otherRec.[[Set]], « | ||
// e »)). | ||
const inOther = | ||
ToBoolean(Call(context, otherRec.has, otherRec.object, key)); | ||
|
||
// d. If inOther is false, return false. | ||
if (!inOther) { | ||
return False; | ||
} | ||
// e. NOTE: The number of elements in O.[[SetData]] may have increased | ||
// during execution of otherRec.[[Has]]. | ||
// f. Set thisSize to the number of elements of O.[[SetData]]. | ||
// We have used `collections::NewOrderedHashSetIterator` which allows | ||
// changes on the table. | ||
} | ||
unreachable; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
// Copyright 2023 the V8 project authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
// | ||
// Flags: --harmony-set-methods | ||
|
||
(function TestIsSubsetOfSetFirstShorterIsSubset() { | ||
const firstSet = new Set(); | ||
firstSet.add(42); | ||
firstSet.add(43); | ||
|
||
const otherSet = new Set(); | ||
otherSet.add(42); | ||
otherSet.add(43); | ||
otherSet.add(47); | ||
|
||
assertEquals(firstSet.isSubsetOf(otherSet), true); | ||
})(); | ||
|
||
(function TestIsSubsetOfSetFirstShorterIsNotSubset() { | ||
const firstSet = new Set(); | ||
firstSet.add(42); | ||
firstSet.add(43); | ||
|
||
const otherSet = new Set(); | ||
otherSet.add(42); | ||
otherSet.add(46); | ||
otherSet.add(47); | ||
|
||
assertEquals(firstSet.isSubsetOf(otherSet), false); | ||
})(); | ||
|
||
(function TestIsSubsetOfSetSecondShorter() { | ||
const firstSet = new Set(); | ||
firstSet.add(42); | ||
firstSet.add(43); | ||
firstSet.add(44); | ||
|
||
const otherSet = new Set(); | ||
otherSet.add(42); | ||
otherSet.add(44); | ||
|
||
assertEquals(firstSet.isSubsetOf(otherSet), false); | ||
})(); | ||
|
||
(function TestIsSubsetOfMapFirstShorterIsSubset() { | ||
const firstSet = new Set(); | ||
firstSet.add(42); | ||
firstSet.add(43); | ||
|
||
const other = new Map(); | ||
other.set(42); | ||
other.set(43); | ||
other.set(47); | ||
|
||
assertEquals(firstSet.isSubsetOf(other), true); | ||
})(); | ||
|
||
(function TestIsSubsetOfMapFirstShorterIsNotSubset() { | ||
const firstSet = new Set(); | ||
firstSet.add(42); | ||
firstSet.add(43); | ||
|
||
const other = new Map(); | ||
other.set(42); | ||
other.set(46); | ||
other.set(47); | ||
|
||
assertEquals(firstSet.isSubsetOf(other), false); | ||
})(); | ||
|
||
(function TestIsSubsetOfMapSecondShorter() { | ||
const firstSet = new Set(); | ||
firstSet.add(42); | ||
firstSet.add(43); | ||
firstSet.add(44); | ||
|
||
const other = new Map(); | ||
other.set(42); | ||
other.set(43); | ||
|
||
assertEquals(firstSet.isSubsetOf(other), false); | ||
})(); | ||
|
||
(function TestIsSubsetOfSetLikeObjectFirstShorterIsSubset() { | ||
const SetLike = { | ||
arr: [42, 44, 45], | ||
size: 3, | ||
keys() { | ||
return this.arr[Symbol.iterator](); | ||
}, | ||
has(key) { | ||
return this.arr.indexOf(key) != -1; | ||
} | ||
}; | ||
|
||
const firstSet = new Set(); | ||
firstSet.add(42); | ||
firstSet.add(45); | ||
|
||
assertEquals(firstSet.isSubsetOf(SetLike), true); | ||
})(); | ||
|
||
(function TestIsSubsetOfSetLikeObjectFirstShorterIsNotSubset() { | ||
const SetLike = { | ||
arr: [42, 44, 45], | ||
size: 3, | ||
keys() { | ||
return this.arr[Symbol.iterator](); | ||
}, | ||
has(key) { | ||
return this.arr.indexOf(key) != -1; | ||
} | ||
}; | ||
|
||
const firstSet = new Set(); | ||
firstSet.add(42); | ||
firstSet.add(43); | ||
|
||
assertEquals(firstSet.isSubsetOf(SetLike), false); | ||
})(); | ||
|
||
(function TestIsSubsetOfSetLikeObjectSecondShorter() { | ||
const SetLike = { | ||
arr: [42, 43], | ||
size: 3, | ||
keys() { | ||
return this.arr[Symbol.iterator](); | ||
}, | ||
has(key) { | ||
return this.arr.indexOf(key) != -1; | ||
} | ||
}; | ||
|
||
const firstSet = new Set(); | ||
firstSet.add(42); | ||
firstSet.add(43); | ||
firstSet.add(44); | ||
|
||
assertEquals(firstSet.isSubsetOf(SetLike), false); | ||
})(); | ||
|
||
(function TestIsSubsetOfSetEqualLengthIsSubset() { | ||
const SetLike = { | ||
arr: [42, 43, 45], | ||
size: 3, | ||
keys() { | ||
return this.arr[Symbol.iterator](); | ||
}, | ||
has(key) { | ||
return this.arr.indexOf(key) != -1; | ||
} | ||
}; | ||
|
||
const firstSet = new Set(); | ||
firstSet.add(42); | ||
firstSet.add(43); | ||
firstSet.add(45); | ||
|
||
assertEquals(firstSet.isSubsetOf(SetLike), true); | ||
})(); | ||
|
||
(function TestIsSubsetOfSetEqualLengthIsNotSubset() { | ||
const SetLike = { | ||
arr: [42, 44, 45], | ||
size: 3, | ||
keys() { | ||
return this.arr[Symbol.iterator](); | ||
}, | ||
has(key) { | ||
return this.arr.indexOf(key) != -1; | ||
} | ||
}; | ||
|
||
const firstSet = new Set(); | ||
firstSet.add(42); | ||
firstSet.add(43); | ||
firstSet.add(45); | ||
|
||
assertEquals(firstSet.isSubsetOf(SetLike), false); | ||
})(); |