Skip to content

Commit

Permalink
fix(webidl): properly implement setlike (#17363)
Browse files Browse the repository at this point in the history
  • Loading branch information
crowlKats authored and dsherret committed Jan 13, 2023
1 parent c4be3a0 commit 95d4fb6
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 52 deletions.
59 changes: 7 additions & 52 deletions ext/webgpu/src/01_webgpu.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,9 @@
SafeArrayIterator,
SafePromiseAll,
Set,
SetPrototypeEntries,
SetPrototypeForEach,
SetPrototypeHas,
SetPrototypeKeys,
SetPrototypeValues,
Symbol,
SymbolFor,
SymbolIterator,
TypeError,
Uint32Array,
Uint32ArrayPrototype,
Expand Down Expand Up @@ -602,60 +597,20 @@

function createGPUSupportedFeatures(features) {
/** @type {GPUSupportedFeatures} */
const adapterFeatures = webidl.createBranded(GPUSupportedFeatures);
adapterFeatures[_features] = new Set(features);
return adapterFeatures;
const supportedFeatures = webidl.createBranded(GPUSupportedFeatures);
supportedFeatures[webidl.setlikeInner] = new Set(features);
return webidl.setlike(
supportedFeatures,
GPUSupportedFeaturesPrototype,
true,
);
}

class GPUSupportedFeatures {
/** @type {Set<string>} */
[_features];

constructor() {
webidl.illegalConstructor();
}

/** @return {IterableIterator<[string, string]>} */
entries() {
webidl.assertBranded(this, GPUSupportedFeaturesPrototype);
return SetPrototypeEntries(this[_features]);
}

/** @return {void} */
forEach(callbackfn, thisArg) {
webidl.assertBranded(this, GPUSupportedFeaturesPrototype);
SetPrototypeForEach(this[_features], callbackfn, thisArg);
}

/** @return {boolean} */
has(value) {
webidl.assertBranded(this, GPUSupportedFeaturesPrototype);
return SetPrototypeHas(this[_features], value);
}

/** @return {IterableIterator<string>} */
keys() {
webidl.assertBranded(this, GPUSupportedFeaturesPrototype);
return SetPrototypeKeys(this[_features]);
}

/** @return {IterableIterator<string>} */
values() {
webidl.assertBranded(this, GPUSupportedFeaturesPrototype);
return SetPrototypeValues(this[_features]);
}

/** @return {number} */
get size() {
webidl.assertBranded(this, GPUSupportedFeaturesPrototype);
return this[_features].size;
}

[SymbolIterator]() {
webidl.assertBranded(this, GPUSupportedFeaturesPrototype);
return this[_features][SymbolIterator]();
}

[SymbolFor("Deno.privateCustomInspect")](inspect) {
return `${this.constructor.name} ${
inspect([...new SafeArrayIterator(this.values())])
Expand Down
112 changes: 112 additions & 0 deletions ext/webidl/00_webidl.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,14 @@
ReflectOwnKeys,
RegExpPrototypeTest,
Set,
SetPrototypeEntries,
SetPrototypeForEach,
SetPrototypeKeys,
SetPrototypeValues,
SetPrototypeHas,
SetPrototypeClear,
SetPrototypeDelete,
SetPrototypeAdd,
// TODO(lucacasonato): add SharedArrayBuffer to primordials
// SharedArrayBuffer,
String,
Expand Down Expand Up @@ -1048,6 +1056,108 @@
});
}

const setlikeInner = Symbol("[[set]]");

// Ref: https://webidl.spec.whatwg.org/#es-setlike
function setlike(obj, objPrototype, readonly) {
ObjectDefineProperties(obj, {
size: {
configurable: true,
enumerable: true,
get() {
assertBranded(this, objPrototype);
return obj[setlikeInner].size;
},
},
[SymbolIterator]: {
configurable: true,
enumerable: false,
writable: true,
value() {
assertBranded(this, objPrototype);
return obj[setlikeInner][SymbolIterator]();
},
},
entries: {
configurable: true,
enumerable: true,
writable: true,
value() {
assertBranded(this, objPrototype);
return SetPrototypeEntries(obj[setlikeInner]);
},
},
keys: {
configurable: true,
enumerable: true,
writable: true,
value() {
assertBranded(this, objPrototype);
return SetPrototypeKeys(obj[setlikeInner]);
},
},
values: {
configurable: true,
enumerable: true,
writable: true,
value() {
assertBranded(this, objPrototype);
return SetPrototypeValues(obj[setlikeInner]);
},
},
forEach: {
configurable: true,
enumerable: true,
writable: true,
value(callbackfn, thisArg) {
assertBranded(this, objPrototype);
return SetPrototypeForEach(obj[setlikeInner], callbackfn, thisArg);
},
},
has: {
configurable: true,
enumerable: true,
writable: true,
value(value) {
assertBranded(this, objPrototype);
return SetPrototypeHas(obj[setlikeInner], value);
},
},
});

if (!readonly) {
ObjectDefineProperties(obj, {
add: {
configurable: true,
enumerable: true,
writable: true,
value(value) {
assertBranded(this, objPrototype);
return SetPrototypeAdd(obj[setlikeInner], value);
},
},
delete: {
configurable: true,
enumerable: true,
writable: true,
value(value) {
assertBranded(this, objPrototype);
return SetPrototypeDelete(obj[setlikeInner], value);
},
},
clear: {
configurable: true,
enumerable: true,
writable: true,
value() {
assertBranded(this, objPrototype);
return SetPrototypeClear(obj[setlikeInner]);
},
},
});
}
}

window.__bootstrap ??= {};
window.__bootstrap.webidl = {
type,
Expand All @@ -1068,5 +1178,7 @@
illegalConstructor,
mixinPairIterable,
configurePrototype,
setlike,
setlikeInner,
};
})(this);

0 comments on commit 95d4fb6

Please sign in to comment.