summaryrefslogtreecommitdiff
path: root/op_crates/webidl/00_webidl.js
diff options
context:
space:
mode:
authorLuca Casonato <lucacasonato@yahoo.com>2021-04-20 14:47:22 +0200
committerGitHub <noreply@github.com>2021-04-20 14:47:22 +0200
commit9e6cd91014ac4a0d34556b0d09cbe25e4e0930c6 (patch)
tree4523790510a17676c987039feb03f208a258dc16 /op_crates/webidl/00_webidl.js
parent115197ffb06aad2a3045e8478980ab911b5a5eeb (diff)
chore: align fetch to spec (#10203)
This commit aligns the `fetch` API and the `Request` / `Response` classes belonging to it to the spec. This commit enables all the relevant `fetch` WPT tests. Spec compliance is now at around 90%. Performance is essentially identical now (within 1% of 1.9.0).
Diffstat (limited to 'op_crates/webidl/00_webidl.js')
-rw-r--r--op_crates/webidl/00_webidl.js97
1 files changed, 47 insertions, 50 deletions
diff --git a/op_crates/webidl/00_webidl.js b/op_crates/webidl/00_webidl.js
index 63946c9a1..6bf98be06 100644
--- a/op_crates/webidl/00_webidl.js
+++ b/op_crates/webidl/00_webidl.js
@@ -375,40 +375,12 @@
return V;
}
- const abByteLengthGetter = Object.getOwnPropertyDescriptor(
- ArrayBuffer.prototype,
- "byteLength",
- ).get;
-
function isNonSharedArrayBuffer(V) {
- try {
- // This will throw on SharedArrayBuffers, but not detached ArrayBuffers.
- // (The spec says it should throw, but the spec conflicts with implementations: https://github.com/tc39/ecma262/issues/678)
- abByteLengthGetter.call(V);
-
- return true;
- } catch {
- return false;
- }
+ return V instanceof ArrayBuffer;
}
- let sabByteLengthGetter;
-
function isSharedArrayBuffer(V) {
- // TODO(lucacasonato): vulnerable to prototype pollution. Needs to happen
- // here because SharedArrayBuffer is not available during snapshotting.
- if (!sabByteLengthGetter) {
- sabByteLengthGetter = Object.getOwnPropertyDescriptor(
- SharedArrayBuffer.prototype,
- "byteLength",
- ).get;
- }
- try {
- sabByteLengthGetter.call(V);
- return true;
- } catch {
- return false;
- }
+ return V instanceof SharedArrayBuffer;
}
function isArrayBufferDetached(V) {
@@ -439,14 +411,8 @@
return V;
};
- const dvByteLengthGetter = Object.getOwnPropertyDescriptor(
- DataView.prototype,
- "byteLength",
- ).get;
converters.DataView = (V, opts = {}) => {
- try {
- dvByteLengthGetter.call(V);
- } catch (e) {
+ if (!(V instanceof DataView)) {
throw makeException(TypeError, "is not a DataView", opts);
}
@@ -614,10 +580,19 @@
}
}
+ function isEmptyObject(V) {
+ for (const _ in V) return false;
+ return true;
+ }
+
function createDictionaryConverter(name, ...dictionaries) {
+ let hasRequiredKey = false;
const allMembers = [];
for (const members of dictionaries) {
for (const member of members) {
+ if (member.required) {
+ hasRequiredKey = true;
+ }
allMembers.push(member);
}
}
@@ -628,6 +603,29 @@
return a.key < b.key ? -1 : 1;
});
+ const defaultValues = {};
+ for (const member of allMembers) {
+ if ("defaultValue" in member) {
+ const idlMemberValue = member.defaultValue;
+ const imvType = typeof idlMemberValue;
+ // Copy by value types can be directly assigned, copy by reference types
+ // need to be re-created for each allocation.
+ if (
+ imvType === "number" || imvType === "boolean" ||
+ imvType === "string" || imvType === "bigint" ||
+ imvType === "undefined"
+ ) {
+ defaultValues[member.key] = idlMemberValue;
+ } else {
+ Object.defineProperty(defaultValues, member.key, {
+ get() {
+ return member.defaultValue;
+ },
+ });
+ }
+ }
+ }
+
return function (V, opts = {}) {
const typeV = type(V);
switch (typeV) {
@@ -644,7 +642,14 @@
}
const esDict = V;
- const idlDict = {};
+ const idlDict = { ...defaultValues };
+
+ // NOTE: fast path Null and Undefined and empty objects.
+ if (
+ (V === undefined || V === null || isEmptyObject(V)) && !hasRequiredKey
+ ) {
+ return idlDict;
+ }
for (const member of allMembers) {
const key = member.key;
@@ -656,20 +661,12 @@
esMemberValue = esDict[key];
}
- const context = `'${key}' of '${name}'${
- opts.context ? ` (${opts.context})` : ""
- }`;
-
if (esMemberValue !== undefined) {
+ const context = `'${key}' of '${name}'${
+ opts.context ? ` (${opts.context})` : ""
+ }`;
const converter = member.converter;
- const idlMemberValue = converter(esMemberValue, {
- ...opts,
- context,
- });
- idlDict[key] = idlMemberValue;
- } else if ("defaultValue" in member) {
- const defaultValue = member.defaultValue;
- const idlMemberValue = defaultValue;
+ const idlMemberValue = converter(esMemberValue, { ...opts, context });
idlDict[key] = idlMemberValue;
} else if (member.required) {
throw makeException(