diff --git a/cli/js/40_testing.js b/cli/js/40_testing.js index a34eb5aff1..87567a17e5 100644 --- a/cli/js/40_testing.js +++ b/cli/js/40_testing.js @@ -16,14 +16,12 @@ const { ArrayPrototypeShift, DateNow, Error, - FunctionPrototype, Map, MapPrototypeGet, MapPrototypeHas, MapPrototypeSet, MathCeil, ObjectKeys, - ObjectPrototypeIsPrototypeOf, Promise, SafeArrayIterator, Set, @@ -1294,7 +1292,7 @@ function createTestContext(desc) { let stepDesc; if (typeof nameOrFnOrOptions === "string") { - if (!(ObjectPrototypeIsPrototypeOf(FunctionPrototype, maybeFn))) { + if (typeof maybeFn !== "function") { throw new TypeError("Expected function for second argument."); } stepDesc = { diff --git a/cli/tests/integration/node_unit_tests.rs b/cli/tests/integration/node_unit_tests.rs index 1508ad9ac7..273066b093 100644 --- a/cli/tests/integration/node_unit_tests.rs +++ b/cli/tests/integration/node_unit_tests.rs @@ -52,6 +52,7 @@ util::unit_test_factory!( assertion_error_test, buffer_test, child_process_test, + console_test, crypto_cipher_test = crypto / crypto_cipher_test, crypto_cipher_gcm_test = crypto / crypto_cipher_gcm_test, crypto_hash_test = crypto / crypto_hash_test, diff --git a/cli/tests/unit/console_test.ts b/cli/tests/unit/console_test.ts index 7d46759761..031512f792 100644 --- a/cli/tests/unit/console_test.ts +++ b/cli/tests/unit/console_test.ts @@ -1845,18 +1845,36 @@ Deno.test(function consoleLogShouldNotThrowErrorWhenInvalidDateIsPassed() { // console.log(new Proxy(new Set(), {})) Deno.test(function consoleLogShouldNotThrowErrorWhenInputIsProxiedSet() { mockConsole((console, out) => { - const proxiedSet = new Proxy(new Set(), {}); + const proxiedSet = new Proxy(new Set([1, 2]), {}); console.log(proxiedSet); - assertEquals(stripColor(out.toString()), "Set {}\n"); + assertEquals(stripColor(out.toString()), "Set(2) { 1, 2 }\n"); }); }); // console.log(new Proxy(new Map(), {})) Deno.test(function consoleLogShouldNotThrowErrorWhenInputIsProxiedMap() { mockConsole((console, out) => { - const proxiedMap = new Proxy(new Map(), {}); + const proxiedMap = new Proxy(new Map([[1, 1], [2, 2]]), {}); console.log(proxiedMap); - assertEquals(stripColor(out.toString()), "Map {}\n"); + assertEquals(stripColor(out.toString()), "Map(2) { 1 => 1, 2 => 2 }\n"); + }); +}); + +// console.log(new Proxy(new Uint8Array(), {})) +Deno.test(function consoleLogShouldNotThrowErrorWhenInputIsProxiedTypedArray() { + mockConsole((console, out) => { + const proxiedUint8Array = new Proxy(new Uint8Array([1, 2]), {}); + console.log(proxiedUint8Array); + assertEquals(stripColor(out.toString()), "Uint8Array(2) [ 1, 2 ]\n"); + }); +}); + +// console.log(new Proxy(new RegExp(), {})) +Deno.test(function consoleLogShouldNotThrowErrorWhenInputIsProxiedRegExp() { + mockConsole((console, out) => { + const proxiedRegExp = new Proxy(/aaaa/, {}); + console.log(proxiedRegExp); + assertEquals(stripColor(out.toString()), "/aaaa/\n"); }); }); @@ -1869,6 +1887,15 @@ Deno.test(function consoleLogShouldNotThrowErrorWhenInputIsProxiedDate() { }); }); +// console.log(new Proxy(new Error(), {})) +Deno.test(function consoleLogShouldNotThrowErrorWhenInputIsProxiedError() { + mockConsole((console, out) => { + const proxiedError = new Proxy(new Error("message"), {}); + console.log(proxiedError); + assertStringIncludes(stripColor(out.toString()), "Error: message\n"); + }); +}); + // console.dir test Deno.test(function consoleDir() { mockConsole((console, out) => { diff --git a/cli/tests/unit_node/console_test.ts b/cli/tests/unit_node/console_test.ts new file mode 100644 index 0000000000..583e98e229 --- /dev/null +++ b/cli/tests/unit_node/console_test.ts @@ -0,0 +1,28 @@ +// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. + +import vm from "node:vm"; +import { stripColor } from "../../../test_util/std/fmt/colors.ts"; +import { assertStringIncludes } from "../../../test_util/std/assert/mod.ts"; + +Deno.test(function inspectCrossRealmObjects() { + assertStringIncludes( + stripColor( + Deno.inspect(vm.runInNewContext(`new Error("This is an error")`)), + ), + "Error: This is an error", + ); + assertStringIncludes( + stripColor( + Deno.inspect( + vm.runInNewContext(`new AggregateError([], "This is an error")`), + ), + ), + "AggregateError: This is an error", + ); + assertStringIncludes( + stripColor( + Deno.inspect(vm.runInNewContext(`new Date("2018-12-10T02:26:59.002Z")`)), + ), + "2018-12-10T02:26:59.002Z", + ); +}); diff --git a/cli/tests/unit_node/util_test.ts b/cli/tests/unit_node/util_test.ts index 3cb5e43661..2e2bb00210 100644 --- a/cli/tests/unit_node/util_test.ts +++ b/cli/tests/unit_node/util_test.ts @@ -8,6 +8,7 @@ import { } from "../../../test_util/std/assert/mod.ts"; import { stripColor } from "../../../test_util/std/fmt/colors.ts"; import * as util from "node:util"; +import { Buffer } from "node:buffer"; Deno.test({ name: "[util] format", @@ -130,9 +131,11 @@ Deno.test({ fn() { const java = new Error(); const nodejs = Reflect.construct(Error, [], Object); + const bun = new DOMException(); const deno = "Future"; assert(util.isError(java)); assert(util.isError(nodejs)); + assert(util.isError(bun)); assert(!util.isError(deno)); }, }); @@ -190,6 +193,40 @@ Deno.test({ }, }); +Deno.test({ + name: "[util] isDate", + fn() { + // Test verifies the method is exposed. See _util/_util_types_test for details + assert(util.isDate(new Date())); + }, +}); + +Deno.test({ + name: "[util] isBuffer", + fn() { + assert(util.isBuffer(new Buffer(4))); + assert(!util.isBuffer(new Uint8Array(4))); + }, +}); + +Deno.test({ + name: "[util] types.isTypedArray", + fn() { + assert(util.types.isTypedArray(new Buffer(4))); + assert(util.types.isTypedArray(new Uint8Array(4))); + assert(!util.types.isTypedArray(new DataView(new ArrayBuffer(4)))); + }, +}); + +Deno.test({ + name: "[util] types.isNativeError", + fn() { + assert(util.types.isNativeError(new Error())); + assert(util.types.isNativeError(new TypeError())); + assert(!util.types.isNativeError(new DOMException())); + }, +}); + Deno.test({ name: "[util] TextDecoder", fn() { @@ -216,14 +253,6 @@ Deno.test({ }, }); -Deno.test({ - name: "[util] isDate", - fn() { - // Test verifies the method is exposed. See _util/_util_types_test for details - assert(util.types.isDate(new Date())); - }, -}); - Deno.test({ name: "[util] getSystemErrorName()", fn() { diff --git a/ext/broadcast_channel/01_broadcast_channel.js b/ext/broadcast_channel/01_broadcast_channel.js index bc779f6f69..d365781c11 100644 --- a/ext/broadcast_channel/01_broadcast_channel.js +++ b/ext/broadcast_channel/01_broadcast_channel.js @@ -13,7 +13,7 @@ import { setTarget, } from "ext:deno_web/02_event.js"; import { defer } from "ext:deno_web/02_timers.js"; -import DOMException from "ext:deno_web/01_dom_exception.js"; +import { DOMException } from "ext:deno_web/01_dom_exception.js"; const { op_broadcast_recv, op_broadcast_send, diff --git a/ext/console/01_console.js b/ext/console/01_console.js index 83c759d573..0ca8b04ff6 100644 --- a/ext/console/01_console.js +++ b/ext/console/01_console.js @@ -4,9 +4,7 @@ import { core, internals, primordials } from "ext:core/mod.js"; const { - AggregateErrorPrototype, Array, - ArrayBufferIsView, ArrayBufferPrototypeGetByteLength, ArrayIsArray, ArrayPrototypeFill, @@ -29,18 +27,16 @@ const { Boolean, BooleanPrototypeValueOf, DateNow, - DatePrototype, DatePrototypeGetTime, DatePrototypeToISOString, Error, - ErrorCaptureStackTrace, ErrorPrototype, + ErrorCaptureStackTrace, ErrorPrototypeToString, FunctionPrototypeBind, FunctionPrototypeCall, FunctionPrototypeToString, NumberIsNaN, - MapPrototype, MapPrototypeDelete, MapPrototypeEntries, MapPrototypeForEach, @@ -93,7 +89,6 @@ const { SafeSet, SafeSetIterator, SafeStringIterator, - SetPrototype, SetPrototypeAdd, SetPrototypeHas, SetPrototypeGetSize, @@ -128,12 +123,38 @@ const { SymbolToStringTag, TypedArrayPrototypeGetByteLength, TypedArrayPrototypeGetLength, - TypedArrayPrototypeGetSymbolToStringTag, Uint8Array, - WeakMapPrototypeHas, - WeakSetPrototypeHas, } = primordials; -const ops = core.ops; +const { + isAnyArrayBuffer, + isArgumentsObject, + isArrayBuffer, + isAsyncFunction, + isBigIntObject, + isBooleanObject, + isBoxedPrimitive, + isDataView, + isDate, + isGeneratorFunction, + isMap, + isMapIterator, + isModuleNamespaceObject, + isNativeError, + isNumberObject, + isPromise, + isRegExp, + isSet, + isSetIterator, + isStringObject, + isTypedArray, + isWeakSet, + isWeakMap, +} = core; +const { + op_get_non_index_property_names, + op_get_constructor_name, + op_preview_entries, +} = core.ensureFastOps(true); let noColor = () => false; @@ -263,187 +284,17 @@ function getSharedArrayBufferByteLength(value) { return FunctionPrototypeCall(_getSharedArrayBufferByteLength, value); } -function isObjectLike(value) { - return value !== null && typeof value === "object"; -} - -function isAnyArrayBuffer(value) { - return ops.op_is_any_arraybuffer(value); -} - -function isArgumentsObject(value) { - return core.isArgumentsObject(value); -} - -function isArrayBuffer(value) { - try { - ArrayBufferPrototypeGetByteLength(value); - return true; - } catch { - return false; - } -} - -function isAsyncFunction(value) { - return core.isAsyncFunction(value); -} - -function isBooleanObject(value) { - if (!isObjectLike(value)) { - return false; - } - - try { - BooleanPrototypeValueOf(value); - return true; - } catch { - return false; - } -} - -function isBoxedPrimitive( - value, -) { +// The name property is used to allow cross realms to make a determination +// This is the same as WHATWG's structuredClone algorithm +// https://github.com/whatwg/html/pull/5150 +function isAggregateError(value) { return ( - isBooleanObject(value) || - isStringObject(value) || - isNumberObject(value) || - isSymbolObject(value) || - isBigIntObject(value) + isNativeError(value) && + value.name === "AggregateError" && + ArrayIsArray(value.errors) ); } -function isDataView(value) { - return ( - ArrayBufferIsView(value) && - TypedArrayPrototypeGetSymbolToStringTag(value) === undefined - ); -} - -function isTypedArray(value) { - return TypedArrayPrototypeGetSymbolToStringTag(value) !== undefined; -} - -function isGeneratorFunction(value) { - return core.isGeneratorFunction(value); -} - -function isMap(value) { - try { - MapPrototypeGetSize(value); - return true; - } catch { - return false; - } -} - -function isMapIterator(value) { - return core.isMapIterator(value); -} - -function isModuleNamespaceObject(value) { - return core.isModuleNamespaceObject(value); -} - -function isNativeError(value) { - return core.isNativeError(value); -} - -function isNumberObject(value) { - if (!isObjectLike(value)) { - return false; - } - - try { - NumberPrototypeValueOf(value); - return true; - } catch { - return false; - } -} - -function isBigIntObject(value) { - if (!isObjectLike(value)) { - return false; - } - - try { - BigIntPrototypeValueOf(value); - return true; - } catch { - return false; - } -} - -function isPromise(value) { - return core.isPromise(value); -} - -function isRegExp(value) { - return core.isRegExp(value); -} - -function isSet(value) { - try { - SetPrototypeGetSize(value); - return true; - } catch { - return false; - } -} - -function isSetIterator(value) { - return core.isSetIterator(value); -} - -function isStringObject(value) { - if (!isObjectLike(value)) { - return false; - } - - try { - StringPrototypeValueOf(value); - return true; - } catch { - return false; - } -} - -function isSymbolObject(value) { - if (!isObjectLike(value)) { - return false; - } - - try { - SymbolPrototypeValueOf(value); - return true; - } catch { - return false; - } -} - -function isWeakMap( - value, -) { - try { - WeakMapPrototypeHas(value, null); - return true; - } catch { - return false; - } -} - -function isWeakSet( - value, -) { - try { - WeakSetPrototypeHas(value, null); - return true; - } catch { - return false; - } -} - const kObjectType = 0; const kArrayType = 1; const kArrayExtrasType = 2; @@ -778,7 +629,7 @@ function formatRaw(ctx, value, recurseTimes, typedArray, proxyDetails) { let extrasType = kObjectType; - if (proxyDetails != null && ctx.showProxy) { + if (proxyDetails !== null && ctx.showProxy) { return `Proxy ` + formatValue(ctx, proxyDetails, recurseTimes); } else { // Iterators and the rest are split to reduce checks. @@ -791,7 +642,7 @@ function formatRaw(ctx, value, recurseTimes, typedArray, proxyDetails) { const prefix = (constructor !== "Array" || tag !== "") ? getPrefix(constructor, tag, "Array", `(${value.length})`) : ""; - keys = ops.op_get_non_index_property_names(value, filter); + keys = op_get_non_index_property_names(value, filter); braces = [`${prefix}[`, "]"]; if ( value.length === 0 && keys.length === 0 && protoProps === undefined @@ -800,31 +651,43 @@ function formatRaw(ctx, value, recurseTimes, typedArray, proxyDetails) { } extrasType = kArrayExtrasType; formatter = formatArray; - } else if (isSet(value)) { - const size = SetPrototypeGetSize(value); + } else if ( + (proxyDetails === null && isSet(value)) || + (proxyDetails !== null && isSet(proxyDetails[0])) + ) { + const set = proxyDetails?.[0] ?? value; + const size = SetPrototypeGetSize(set); const prefix = getPrefix(constructor, tag, "Set", `(${size})`); - keys = getKeys(value, ctx.showHidden); + keys = getKeys(set, ctx.showHidden); formatter = constructor !== null - ? FunctionPrototypeBind(formatSet, null, value) - : FunctionPrototypeBind(formatSet, null, SetPrototypeValues(value)); + ? FunctionPrototypeBind(formatSet, null, set) + : FunctionPrototypeBind(formatSet, null, SetPrototypeValues(set)); if (size === 0 && keys.length === 0 && protoProps === undefined) { return `${prefix}{}`; } braces = [`${prefix}{`, "}"]; - } else if (isMap(value)) { - const size = MapPrototypeGetSize(value); + } else if ( + (proxyDetails === null && isMap(value)) || + (proxyDetails !== null && isMap(proxyDetails[0])) + ) { + const map = proxyDetails?.[0] ?? value; + const size = MapPrototypeGetSize(map); const prefix = getPrefix(constructor, tag, "Map", `(${size})`); - keys = getKeys(value, ctx.showHidden); + keys = getKeys(map, ctx.showHidden); formatter = constructor !== null - ? FunctionPrototypeBind(formatMap, null, value) - : FunctionPrototypeBind(formatMap, null, MapPrototypeEntries(value)); + ? FunctionPrototypeBind(formatMap, null, map) + : FunctionPrototypeBind(formatMap, null, MapPrototypeEntries(map)); if (size === 0 && keys.length === 0 && protoProps === undefined) { return `${prefix}{}`; } braces = [`${prefix}{`, "}"]; - } else if (isTypedArray(value)) { - keys = core.ops.op_get_non_index_property_names(value, filter); - const bound = value; + } else if ( + (proxyDetails === null && isTypedArray(value)) || + (proxyDetails !== null && isTypedArray(proxyDetails[0])) + ) { + const typedArray = proxyDetails?.[0] ?? value; + keys = op_get_non_index_property_names(typedArray, filter); + const bound = typedArray; const fallback = ""; if (constructor === null) { // TODO(wafuwafu13): Implement @@ -832,23 +695,31 @@ function formatRaw(ctx, value, recurseTimes, typedArray, proxyDetails) { // // Reconstruct the array information. // bound = new primordials[fallback](value); } - const size = TypedArrayPrototypeGetLength(value); + const size = TypedArrayPrototypeGetLength(typedArray); const prefix = getPrefix(constructor, tag, fallback, `(${size})`); braces = [`${prefix}[`, "]"]; - if (value.length === 0 && keys.length === 0 && !ctx.showHidden) { + if (typedArray.length === 0 && keys.length === 0 && !ctx.showHidden) { return `${braces[0]}]`; } // Special handle the value. The original value is required below. The // bound function is required to reconstruct missing information. formatter = FunctionPrototypeBind(formatTypedArray, null, bound, size); extrasType = kArrayExtrasType; - } else if (isMapIterator(value)) { - keys = getKeys(value, ctx.showHidden); + } else if ( + (proxyDetails === null && isMapIterator(value)) || + (proxyDetails !== null && isMapIterator(proxyDetails[0])) + ) { + const mapIterator = proxyDetails?.[0] ?? value; + keys = getKeys(mapIterator, ctx.showHidden); braces = getIteratorBraces("Map", tag); // Add braces to the formatter parameters. formatter = FunctionPrototypeBind(formatIterator, null, braces); - } else if (isSetIterator(value)) { - keys = getKeys(value, ctx.showHidden); + } else if ( + (proxyDetails === null && isSetIterator(value)) || + (proxyDetails !== null && isSetIterator(proxyDetails[0])) + ) { + const setIterator = proxyDetails?.[0] ?? value; + keys = getKeys(setIterator, ctx.showHidden); braces = getIteratorBraces("Set", tag); // Add braces to the formatter parameters. formatter = FunctionPrototypeBind(formatIterator, null, braces); @@ -873,10 +744,14 @@ function formatRaw(ctx, value, recurseTimes, typedArray, proxyDetails) { if (keys.length === 0 && protoProps === undefined) { return ctx.stylize(base, "special"); } - } else if (isRegExp(value)) { + } else if ( + (proxyDetails === null && isRegExp(value)) || + (proxyDetails !== null && isRegExp(proxyDetails[0])) + ) { + const regExp = proxyDetails?.[0] ?? value; // Make RegExps say that they are RegExps base = RegExpPrototypeToString( - constructor !== null ? value : new SafeRegExp(value), + constructor !== null ? regExp : new SafeRegExp(regExp), ); const prefix = getPrefix(constructor, tag, "RegExp"); if (prefix !== "RegExp ") { @@ -888,8 +763,11 @@ function formatRaw(ctx, value, recurseTimes, typedArray, proxyDetails) { ) { return ctx.stylize(base, "regexp"); } - } else if (ObjectPrototypeIsPrototypeOf(DatePrototype, value)) { - const date = proxyDetails ? proxyDetails[0] : value; + } else if ( + (proxyDetails === null && isDate(value)) || + (proxyDetails !== null && isDate(proxyDetails[0])) + ) { + const date = proxyDetails?.[0] ?? value; if (NumberIsNaN(DatePrototypeGetTime(date))) { return ctx.stylize("Invalid Date", "date"); } else { @@ -898,8 +776,16 @@ function formatRaw(ctx, value, recurseTimes, typedArray, proxyDetails) { return ctx.stylize(base, "date"); } } - } else if (ObjectPrototypeIsPrototypeOf(ErrorPrototype, value)) { - base = inspectError(value, ctx); + } else if ( + (proxyDetails === null && + (isNativeError(value) || + ObjectPrototypeIsPrototypeOf(ErrorPrototype, value))) || + (proxyDetails !== null && + (isNativeError(proxyDetails[0]) || + ObjectPrototypeIsPrototypeOf(ErrorPrototype, proxyDetails[0]))) + ) { + const error = proxyDetails?.[0] ?? value; + base = inspectError(error, ctx); if (keys.length === 0 && protoProps === undefined) { return base; } @@ -1180,7 +1066,7 @@ function getConstructorName(obj, ctx, recurseTimes, protoProps) { return null; } - const res = core.ops.op_get_constructor_name(tmp); + const res = op_get_constructor_name(tmp); if (recurseTimes > ctx.depth && ctx.depth !== null) { return `${res} `; @@ -1290,7 +1176,7 @@ function formatArray(ctx, value, recurseTimes) { function getCtxStyle(value, constructor, tag) { let fallback = ""; if (constructor === null) { - fallback = core.ops.op_get_constructor_name(value); + fallback = op_get_constructor_name(value); if (fallback === tag) { fallback = "Object"; } @@ -1433,7 +1319,7 @@ function getIteratorBraces(type, tag) { const iteratorRegExp = new SafeRegExp(" Iterator] {$"); function formatIterator(braces, ctx, value, recurseTimes) { - const { 0: entries, 1: isKeyValue } = ops.op_preview_entries(value, true); + const { 0: entries, 1: isKeyValue } = op_preview_entries(value, true); if (isKeyValue) { // Mark entry iterators as such. braces[0] = StringPrototypeReplace( @@ -1498,7 +1384,7 @@ function inspectError(value, ctx) { let finalMessage = MapPrototypeGet(refMap, value) ?? ""; - if (ObjectPrototypeIsPrototypeOf(AggregateErrorPrototype, value)) { + if (isAggregateError(value)) { const stackLines = StringPrototypeSplit(value.stack, "\n"); while (true) { const line = ArrayPrototypeShift(stackLines); @@ -1635,12 +1521,12 @@ function formatWeakCollection(ctx) { } function formatWeakSet(ctx, value, recurseTimes) { - const entries = ops.op_preview_entries(value, false); + const entries = op_preview_entries(value, false); return formatSetIterInner(ctx, recurseTimes, entries, kWeak); } function formatWeakMap(ctx, value, recurseTimes) { - const entries = ops.op_preview_entries(value, false); + const entries = op_preview_entries(value, false); return formatMapIterInner(ctx, recurseTimes, entries, kWeak); } @@ -3278,14 +3164,14 @@ class Console { const toTable = (header, body) => this.log(cliTable(header, body)); let resultData; - const isSet = ObjectPrototypeIsPrototypeOf(SetPrototype, data); - const isMap = ObjectPrototypeIsPrototypeOf(MapPrototype, data); + const isSetObject = isSet(data); + const isMapObject = isMap(data); const valuesKey = "Values"; - const indexKey = isSet || isMap ? "(iter idx)" : "(idx)"; + const indexKey = isSetObject || isMapObject ? "(iter idx)" : "(idx)"; - if (isSet) { + if (isSetObject) { resultData = [...new SafeSetIterator(data)]; - } else if (isMap) { + } else if (isMapObject) { let idx = 0; resultData = {}; @@ -3342,7 +3228,7 @@ class Console { const headerProps = properties || [ ...new SafeArrayIterator(headerKeys), - !isMap && hasPrimitives && valuesKey, + !isMapObject && hasPrimitives && valuesKey, ]; const header = ArrayPrototypeFilter([ indexKey, diff --git a/ext/console/lib.rs b/ext/console/lib.rs index fd4d917d89..87fc8327da 100644 --- a/ext/console/lib.rs +++ b/ext/console/lib.rs @@ -5,7 +5,7 @@ use std::path::PathBuf; deno_core::extension!( deno_console, - ops = [op_is_any_arraybuffer, op_preview_entries,], + ops = [op_preview_entries], esm = ["01_console.js"], ); @@ -13,11 +13,6 @@ pub fn get_declaration() -> PathBuf { PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("lib.deno_console.d.ts") } -#[op2(fast)] -fn op_is_any_arraybuffer(value: &v8::Value) -> bool { - value.is_array_buffer() || value.is_shared_array_buffer() -} - #[op2] pub fn op_preview_entries<'s>( scope: &mut v8::HandleScope<'s>, diff --git a/ext/crypto/00_crypto.js b/ext/crypto/00_crypto.js index 5e207e629d..06dd0f41a6 100644 --- a/ext/crypto/00_crypto.js +++ b/ext/crypto/00_crypto.js @@ -20,10 +20,9 @@ const { import * as webidl from "ext:deno_webidl/00_webidl.js"; import { createFilteredInspectProxy } from "ext:deno_console/01_console.js"; -import DOMException from "ext:deno_web/01_dom_exception.js"; +import { DOMException } from "ext:deno_web/01_dom_exception.js"; const { ArrayBufferIsView, - ArrayBufferPrototype, ArrayBufferPrototypeGetByteLength, ArrayBufferPrototypeSlice, ArrayPrototypeEvery, @@ -58,6 +57,11 @@ const { WeakMapPrototypeGet, WeakMapPrototypeSet, } = primordials; +const { + isArrayBuffer, + isTypedArray, + isDataView, +} = core; // P-521 is not yet supported. const supportedNamedCurves = ["P-256", "P-384"]; @@ -280,26 +284,22 @@ function normalizeAlgorithm(algorithm, op) { * @returns {Uint8Array} */ function copyBuffer(input) { - if (ArrayBufferIsView(input)) { - if (TypedArrayPrototypeGetSymbolToStringTag(input) !== undefined) { - // TypedArray - return TypedArrayPrototypeSlice( - new Uint8Array( - TypedArrayPrototypeGetBuffer(/** @type {Uint8Array} */ (input)), - TypedArrayPrototypeGetByteOffset(/** @type {Uint8Array} */ (input)), - TypedArrayPrototypeGetByteLength(/** @type {Uint8Array} */ (input)), - ), - ); - } else { - // DataView - return TypedArrayPrototypeSlice( - new Uint8Array( - DataViewPrototypeGetBuffer(/** @type {DataView} */ (input)), - DataViewPrototypeGetByteOffset(/** @type {DataView} */ (input)), - DataViewPrototypeGetByteLength(/** @type {DataView} */ (input)), - ), - ); - } + if (isTypedArray(input)) { + return TypedArrayPrototypeSlice( + new Uint8Array( + TypedArrayPrototypeGetBuffer(/** @type {Uint8Array} */ (input)), + TypedArrayPrototypeGetByteOffset(/** @type {Uint8Array} */ (input)), + TypedArrayPrototypeGetByteLength(/** @type {Uint8Array} */ (input)), + ), + ); + } else if (isDataView(input)) { + return TypedArrayPrototypeSlice( + new Uint8Array( + DataViewPrototypeGetBuffer(/** @type {DataView} */ (input)), + DataViewPrototypeGetByteOffset(/** @type {DataView} */ (input)), + DataViewPrototypeGetByteLength(/** @type {DataView} */ (input)), + ), + ); } // ArrayBuffer return TypedArrayPrototypeSlice( @@ -944,19 +944,13 @@ class SubtleCrypto { // 2. if (format !== "jwk") { - if ( - ArrayBufferIsView(keyData) || - ObjectPrototypeIsPrototypeOf(ArrayBufferPrototype, keyData) - ) { + if (ArrayBufferIsView(keyData) || isArrayBuffer(keyData)) { keyData = copyBuffer(keyData); } else { throw new TypeError("keyData is a JsonWebKey"); } } else { - if ( - ArrayBufferIsView(keyData) || - ObjectPrototypeIsPrototypeOf(ArrayBufferPrototype, keyData) - ) { + if (ArrayBufferIsView(keyData) || isArrayBuffer(keyData)) { throw new TypeError("keyData is not a JsonWebKey"); } } @@ -4778,10 +4772,7 @@ webidl.converters["BufferSource or JsonWebKey"] = ( opts, ) => { // Union for (BufferSource or JsonWebKey) - if ( - ArrayBufferIsView(V) || - ObjectPrototypeIsPrototypeOf(ArrayBufferPrototype, V) - ) { + if (ArrayBufferIsView(V) || isArrayBuffer(V)) { return webidl.converters.BufferSource(V, prefix, context, opts); } return webidl.converters.JsonWebKey(V, prefix, context, opts); diff --git a/ext/fetch/22_body.js b/ext/fetch/22_body.js index b10540883c..2d633ae396 100644 --- a/ext/fetch/22_body.js +++ b/ext/fetch/22_body.js @@ -37,7 +37,6 @@ import { readableStreamThrowIfErrored, } from "ext:deno_web/06_streams.js"; const { - ArrayBufferPrototype, ArrayBufferIsView, ArrayPrototypeMap, DataViewPrototypeGetBuffer, @@ -46,8 +45,6 @@ const { JSONParse, ObjectDefineProperties, ObjectPrototypeIsPrototypeOf, - // TODO(lucacasonato): add SharedArrayBuffer to primordials - // SharedArrayBufferPrototype TypedArrayPrototypeGetBuffer, TypedArrayPrototypeGetByteLength, TypedArrayPrototypeGetByteOffset, @@ -56,6 +53,10 @@ const { TypeError, Uint8Array, } = primordials; +const { + isAnyArrayBuffer, + isArrayBuffer, +} = core; /** * @param {Uint8Array | string} chunk @@ -412,7 +413,7 @@ function extractBody(object) { ); } source = TypedArrayPrototypeSlice(object); - } else if (ObjectPrototypeIsPrototypeOf(ArrayBufferPrototype, object)) { + } else if (isArrayBuffer(object)) { source = TypedArrayPrototypeSlice(new Uint8Array(object)); } else if (ObjectPrototypeIsPrototypeOf(FormDataPrototype, object)) { const res = formDataToBlob(object); @@ -461,11 +462,7 @@ webidl.converters["BodyInit_DOMString"] = (V, prefix, context, opts) => { return webidl.converters["URLSearchParams"](V, prefix, context, opts); } if (typeof V === "object") { - if ( - ObjectPrototypeIsPrototypeOf(ArrayBufferPrototype, V) || - // deno-lint-ignore prefer-primordials - ObjectPrototypeIsPrototypeOf(SharedArrayBuffer.prototype, V) - ) { + if (isAnyArrayBuffer(V)) { return webidl.converters["ArrayBuffer"](V, prefix, context, opts); } if (ArrayBufferIsView(V)) { diff --git a/ext/fetch/26_fetch.js b/ext/fetch/26_fetch.js index 38605d5c96..b53013e492 100644 --- a/ext/fetch/26_fetch.js +++ b/ext/fetch/26_fetch.js @@ -51,7 +51,7 @@ const { StringPrototypeStartsWith, StringPrototypeToLowerCase, TypeError, - Uint8ArrayPrototype, + TypedArrayPrototypeGetSymbolToStringTag, } = primordials; const REQUEST_BODY_HEADER_NAMES = [ @@ -131,7 +131,7 @@ async function mainFetch(req, recursive, terminator) { const stream = req.body.streamOrStatic; const body = stream.body; - if (ObjectPrototypeIsPrototypeOf(Uint8ArrayPrototype, body)) { + if (TypedArrayPrototypeGetSymbolToStringTag(body) === "Uint8Array") { reqBody = body; } else if (typeof body === "string") { reqBody = core.encode(body); diff --git a/ext/fetch/27_eventsource.js b/ext/fetch/27_eventsource.js index a7f8ba77df..fa1d928e55 100644 --- a/ext/fetch/27_eventsource.js +++ b/ext/fetch/27_eventsource.js @@ -7,7 +7,7 @@ import { core, primordials } from "ext:core/mod.js"; import * as webidl from "ext:deno_webidl/00_webidl.js"; import { createFilteredInspectProxy } from "ext:deno_console/01_console.js"; import { URL } from "ext:deno_url/00_url.js"; -import DOMException from "ext:deno_web/01_dom_exception.js"; +import { DOMException } from "ext:deno_web/01_dom_exception.js"; import { defineEventHandler, EventTarget, diff --git a/ext/ffi/00_ffi.js b/ext/ffi/00_ffi.js index 9dd675f887..db58dda802 100644 --- a/ext/ffi/00_ffi.js +++ b/ext/ffi/00_ffi.js @@ -4,7 +4,6 @@ import { core, primordials } from "ext:core/mod.js"; const ops = core.ops; const { ArrayBufferIsView, - ArrayBufferPrototype, ArrayBufferPrototypeGetByteLength, ArrayPrototypeMap, ArrayPrototypeJoin, @@ -16,7 +15,6 @@ const { NumberIsSafeInteger, TypedArrayPrototypeGetBuffer, TypedArrayPrototypeGetByteLength, - TypedArrayPrototypeGetSymbolToStringTag, TypeError, Uint8Array, Int32Array, @@ -32,6 +30,11 @@ const { SafeArrayIterator, SafeWeakMap, } = primordials; +const { + isArrayBuffer, + isDataView, + isTypedArray, +} = core; import { pathFromURL } from "ext:deno_web/00_infra.js"; const { op_ffi_call_nonblocking, @@ -46,14 +49,10 @@ const { * @returns {number} */ function getBufferSourceByteLength(source) { - if (ArrayBufferIsView(source)) { - if (TypedArrayPrototypeGetSymbolToStringTag(source) !== undefined) { - // TypedArray - return TypedArrayPrototypeGetByteLength(source); - } else { - // DataView - return DataViewPrototypeGetByteLength(source); - } + if (isTypedArray(source)) { + return TypedArrayPrototypeGetByteLength(source); + } else if (isDataView(source)) { + return DataViewPrototypeGetByteLength(source); } return ArrayBufferPrototypeGetByteLength(source); } @@ -232,7 +231,7 @@ class UnsafePointer { } else { pointer = ops.op_ffi_ptr_of(value); } - } else if (ObjectPrototypeIsPrototypeOf(ArrayBufferPrototype, value)) { + } else if (isArrayBuffer(value)) { if (value.length === 0) { pointer = ops.op_ffi_ptr_of_exact(new Uint8Array(value)); } else { diff --git a/ext/fs/30_fs.js b/ext/fs/30_fs.js index 4426373034..b0d3beeda4 100644 --- a/ext/fs/30_fs.js +++ b/ext/fs/30_fs.js @@ -37,7 +37,6 @@ const { const { ArrayPrototypeFilter, Date, - DatePrototype, DatePrototypeGetTime, Error, Function, @@ -51,6 +50,9 @@ const { SymbolIterator, Uint32Array, } = primordials; +const { + isDate, +} = core; import { read, readSync, write, writeSync } from "ext:deno_io/12_io.js"; import * as abortSignal from "ext:deno_web/03_abort_signal.js"; import { @@ -416,7 +418,7 @@ async function link(oldpath, newpath) { } function toUnixTimeFromEpoch(value) { - if (ObjectPrototypeIsPrototypeOf(DatePrototype, value)) { + if (isDate(value)) { const time = DatePrototypeGetTime(value); const seconds = MathTrunc(time / 1e3); const nanoseconds = MathTrunc(time - (seconds * 1e3)) * 1e6; diff --git a/ext/http/00_serve.js b/ext/http/00_serve.js index 26632c2ba7..131f056a77 100644 --- a/ext/http/00_serve.js +++ b/ext/http/00_serve.js @@ -44,8 +44,8 @@ const { PromisePrototypeThen, Symbol, TypeError, + TypedArrayPrototypeGetSymbolToStringTag, Uint8Array, - Uint8ArrayPrototype, } = primordials; const { @@ -397,7 +397,7 @@ function fastSyncResponseOrStream(req, respBody, status, innerRequest) { const stream = respBody.streamOrStatic; const body = stream.body; - if (ObjectPrototypeIsPrototypeOf(Uint8ArrayPrototype, body)) { + if (TypedArrayPrototypeGetSymbolToStringTag(body) === "Uint8Array") { innerRequest?.close(); op_http_set_response_body_bytes(req, body, status); return; diff --git a/ext/http/01_http.js b/ext/http/01_http.js index c873889b76..64951ee0fe 100644 --- a/ext/http/01_http.js +++ b/ext/http/01_http.js @@ -60,8 +60,8 @@ const { Symbol, SymbolAsyncIterator, TypeError, + TypedArrayPrototypeGetSymbolToStringTag, Uint8Array, - Uint8ArrayPrototype, } = primordials; const { op_http_accept, @@ -272,7 +272,7 @@ function createRespondWith( } const isStreamingResponseBody = !( typeof respBody === "string" || - ObjectPrototypeIsPrototypeOf(Uint8ArrayPrototype, respBody) + TypedArrayPrototypeGetSymbolToStringTag(respBody) === "Uint8Array" ); try { await op_http_write_headers( @@ -339,7 +339,9 @@ function createRespondWith( while (true) { const { value, done } = await reader.read(); if (done) break; - if (!ObjectPrototypeIsPrototypeOf(Uint8ArrayPrototype, value)) { + if ( + TypedArrayPrototypeGetSymbolToStringTag(value) !== "Uint8Array" + ) { await reader.cancel(new TypeError("Value not a Uint8Array")); break; } diff --git a/ext/kv/01_db.ts b/ext/kv/01_db.ts index b0757a1959..d607704a5d 100644 --- a/ext/kv/01_db.ts +++ b/ext/kv/01_db.ts @@ -1,6 +1,8 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. -// @ts-ignore internal api +import { core, primordials } from "ext:core/mod.js"; +import { SymbolDispose } from "ext:deno_web/00_infra.js"; +import { ReadableStream } from "ext:deno_web/06_streams.js"; const { AsyncGeneratorPrototype, BigIntPrototypeToString, @@ -10,19 +12,17 @@ const { StringPrototypeReplace, SymbolFor, SymbolToStringTag, - Uint8ArrayPrototype, + TypedArrayPrototypeGetSymbolToStringTag, Error, -} = globalThis.__bootstrap.primordials; -import { SymbolDispose } from "ext:deno_web/00_infra.js"; -import { ReadableStream } from "ext:deno_web/06_streams.js"; -const core = Deno.core; -const ops = core.ops; +} = primordials; const { op_kv_atomic_write, op_kv_database_open, op_kv_dequeue_next_message, + op_kv_encode_cursor, op_kv_finish_dequeued_message, op_kv_snapshot_read, + op_kv_watch, op_kv_watch_next, } = core.ensureFastOps(); @@ -30,7 +30,7 @@ const encodeCursor: ( selector: [Deno.KvKey | null, Deno.KvKey | null, Deno.KvKey | null], boundaryKey: Deno.KvKey, ) => string = (selector, boundaryKey) => - ops.op_kv_encode_cursor(selector, boundaryKey); + op_kv_encode_cursor(selector, boundaryKey); async function openKv(path: string) { const rid = await op_kv_database_open(path); @@ -319,7 +319,7 @@ class Kv { watch(keys: Deno.KvKey[], options = {}) { const raw = options.raw ?? false; - const rid = ops.op_kv_watch(this.#rid, keys); + const rid = op_kv_watch(this.#rid, keys); const lastEntries: (Deno.KvEntryMaybe | undefined)[] = Array.from( { length: keys.length }, () => undefined, @@ -585,7 +585,7 @@ function deserializeValue(entry: RawKvEntry): Deno.KvEntry { } function serializeValue(value: unknown): RawValue { - if (ObjectPrototypeIsPrototypeOf(Uint8ArrayPrototype, value)) { + if (TypedArrayPrototypeGetSymbolToStringTag(value) === "Uint8Array") { return { kind: "bytes", value, diff --git a/ext/node/polyfills/internal/console/constructor.mjs b/ext/node/polyfills/internal/console/constructor.mjs index e9160cf700..45bca66754 100644 --- a/ext/node/polyfills/internal/console/constructor.mjs +++ b/ext/node/polyfills/internal/console/constructor.mjs @@ -5,7 +5,9 @@ // deno-lint-ignore-file prefer-primordials import { core } from "ext:core/mod.js"; -const ops = core.ops; +const { + op_preview_entries, +} = core.ensureFastOps(true); // Mock trace for now const trace = () => {}; @@ -502,7 +504,7 @@ const consoleMethods = { let isKeyValue = false; let i = 0; if (mapIter) { - const res = ops.op_preview_entries(tabularData, true); + const res = op_preview_entries(tabularData, true); tabularData = res[0]; isKeyValue = res[1]; } @@ -537,7 +539,7 @@ const consoleMethods = { const setIter = isSetIterator(tabularData); if (setIter) { - tabularData = ops.op_preview_entries(tabularData, false); + tabularData = op_preview_entries(tabularData, false); } const setlike = setIter || mapIter || isSet(tabularData); diff --git a/ext/node/polyfills/internal/util/types.ts b/ext/node/polyfills/internal/util/types.ts index 3e2004c2ba..58b1b1045e 100644 --- a/ext/node/polyfills/internal/util/types.ts +++ b/ext/node/polyfills/internal/util/types.ts @@ -24,17 +24,16 @@ // TODO(petamoriken): enable prefer-primordials for node polyfills // deno-lint-ignore-file prefer-primordials +import { primordials } from "ext:core/mod.js"; import * as bindingTypes from "ext:deno_node/internal_binding/types.ts"; export { isCryptoKey, isKeyObject, } from "ext:deno_node/internal/crypto/_keys.ts"; - -// https://tc39.es/ecma262/#sec-get-%typedarray%.prototype-@@tostringtag -const _getTypedArrayToStringTag = Object.getOwnPropertyDescriptor( - Object.getPrototypeOf(Uint8Array).prototype, - Symbol.toStringTag, -)!.get!; +const { + ArrayBufferIsView, + TypedArrayPrototypeGetSymbolToStringTag, +} = primordials; export function isArrayBufferView( value: unknown, @@ -51,98 +50,82 @@ export function isArrayBufferView( | Uint8ClampedArray | Uint16Array | Uint32Array { - return ArrayBuffer.isView(value); + return ArrayBufferIsView(value); } export function isBigInt64Array(value: unknown): value is BigInt64Array { - return _getTypedArrayToStringTag.call(value) === "BigInt64Array"; + return TypedArrayPrototypeGetSymbolToStringTag(value) === "BigInt64Array"; } export function isBigUint64Array(value: unknown): value is BigUint64Array { - return _getTypedArrayToStringTag.call(value) === "BigUint64Array"; + return TypedArrayPrototypeGetSymbolToStringTag(value) === "BigUint64Array"; } export function isFloat32Array(value: unknown): value is Float32Array { - return _getTypedArrayToStringTag.call(value) === "Float32Array"; + return TypedArrayPrototypeGetSymbolToStringTag(value) === "Float32Array"; } export function isFloat64Array(value: unknown): value is Float64Array { - return _getTypedArrayToStringTag.call(value) === "Float64Array"; + return TypedArrayPrototypeGetSymbolToStringTag(value) === "Float64Array"; } export function isInt8Array(value: unknown): value is Int8Array { - return _getTypedArrayToStringTag.call(value) === "Int8Array"; + return TypedArrayPrototypeGetSymbolToStringTag(value) === "Int8Array"; } export function isInt16Array(value: unknown): value is Int16Array { - return _getTypedArrayToStringTag.call(value) === "Int16Array"; + return TypedArrayPrototypeGetSymbolToStringTag(value) === "Int16Array"; } export function isInt32Array(value: unknown): value is Int32Array { - return _getTypedArrayToStringTag.call(value) === "Int32Array"; -} - -export type TypedArray = - | BigInt64Array - | BigUint64Array - | Float32Array - | Float64Array - | Int8Array - | Int16Array - | Int32Array - | Uint8Array - | Uint8ClampedArray - | Uint16Array - | Uint32Array; - -export function isTypedArray(value: unknown): value is TypedArray { - return _getTypedArrayToStringTag.call(value) !== undefined; + return TypedArrayPrototypeGetSymbolToStringTag(value) === "Int32Array"; } export function isUint8Array(value: unknown): value is Uint8Array { - return _getTypedArrayToStringTag.call(value) === "Uint8Array"; + return TypedArrayPrototypeGetSymbolToStringTag(value) === "Uint8Array"; } export function isUint8ClampedArray( value: unknown, ): value is Uint8ClampedArray { - return _getTypedArrayToStringTag.call(value) === "Uint8ClampedArray"; + return TypedArrayPrototypeGetSymbolToStringTag(value) === "Uint8ClampedArray"; } export function isUint16Array(value: unknown): value is Uint16Array { - return _getTypedArrayToStringTag.call(value) === "Uint16Array"; + return TypedArrayPrototypeGetSymbolToStringTag(value) === "Uint16Array"; } export function isUint32Array(value: unknown): value is Uint32Array { - return _getTypedArrayToStringTag.call(value) === "Uint32Array"; + return TypedArrayPrototypeGetSymbolToStringTag(value) === "Uint32Array"; } export const { // isExternal, - isDate, + isAnyArrayBuffer, isArgumentsObject, + isArrayBuffer, + isAsyncFunction, isBigIntObject, isBooleanObject, - isNumberObject, - isStringObject, - isSymbolObject, - isNativeError, - isRegExp, - isAsyncFunction, + isBoxedPrimitive, + isDataView, + isDate, isGeneratorFunction, isGeneratorObject, - isPromise, isMap, - isSet, isMapIterator, + isModuleNamespaceObject, + isNativeError, + isNumberObject, + isPromise, + isProxy, + isRegExp, + isSet, isSetIterator, + isSharedArrayBuffer, + isStringObject, + isSymbolObject, + isTypedArray, isWeakMap, isWeakSet, - isArrayBuffer, - isDataView, - isSharedArrayBuffer, - isProxy, - isModuleNamespaceObject, - isAnyArrayBuffer, - isBoxedPrimitive, } = bindingTypes; diff --git a/ext/node/polyfills/internal_binding/types.ts b/ext/node/polyfills/internal_binding/types.ts index aa3781944f..2d301ba1b2 100644 --- a/ext/node/polyfills/internal_binding/types.ts +++ b/ext/node/polyfills/internal_binding/types.ts @@ -21,319 +21,35 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. -// TODO(petamoriken): enable prefer-primordials for node polyfills -// deno-lint-ignore-file prefer-primordials +import { core } from "ext:core/mod.js"; -const { core } = globalThis.__bootstrap; -const { ops } = core; - -// https://tc39.es/ecma262/#sec-bigint.prototype.valueof -const _bigIntValueOf = BigInt.prototype.valueOf; - -// https://tc39.es/ecma262/#sec-boolean.prototype.valueof -const _booleanValueOf = Boolean.prototype.valueOf; - -// https://tc39.es/ecma262/#sec-date.prototype.valueof -const _dateValueOf = Date.prototype.valueOf; - -// https://tc39.es/ecma262/#sec-number.prototype.valueof -const _numberValueOf = Number.prototype.valueOf; - -// https://tc39.es/ecma262/#sec-string.prototype.valueof -const _stringValueOf = String.prototype.valueOf; - -// https://tc39.es/ecma262/#sec-symbol.prototype.valueof -const _symbolValueOf = Symbol.prototype.valueOf; - -// https://tc39.es/ecma262/#sec-weakmap.prototype.has -const _weakMapHas = WeakMap.prototype.has; - -// https://tc39.es/ecma262/#sec-weakset.prototype.has -const _weakSetHas = WeakSet.prototype.has; - -// https://tc39.es/ecma262/#sec-get-arraybuffer.prototype.bytelength -const _getArrayBufferByteLength = Object.getOwnPropertyDescriptor( - ArrayBuffer.prototype, - "byteLength", -)!.get!; - -// https://tc39.es/ecma262/#sec-get-sharedarraybuffer.prototype.bytelength -let _getSharedArrayBufferByteLength; - -// https://tc39.es/ecma262/#sec-get-%typedarray%.prototype-@@tostringtag -const _getTypedArrayToStringTag = Object.getOwnPropertyDescriptor( - Object.getPrototypeOf(Uint8Array).prototype, - Symbol.toStringTag, -)!.get!; - -// https://tc39.es/ecma262/#sec-get-set.prototype.size -const _getSetSize = Object.getOwnPropertyDescriptor( - Set.prototype, - "size", -)!.get!; - -// https://tc39.es/ecma262/#sec-get-map.prototype.size -const _getMapSize = Object.getOwnPropertyDescriptor( - Map.prototype, - "size", -)!.get!; - -function isObjectLike( - value: unknown, -): value is Record { - return value !== null && typeof value === "object"; -} - -export function isAnyArrayBuffer( - value: unknown, -): value is ArrayBuffer | SharedArrayBuffer { - return ops.op_is_any_arraybuffer(value); -} - -export function isArgumentsObject(value: unknown): value is IArguments { - return core.isArgumentsObject(value); -} - -export function isArrayBuffer(value: unknown): value is ArrayBuffer { - try { - _getArrayBufferByteLength.call(value); - return true; - } catch { - return false; - } -} - -export function isAsyncFunction( - value: unknown, -): value is (...args: unknown[]) => Promise { - return core.isAsyncFunction(value); -} - -// deno-lint-ignore ban-types -export function isBooleanObject(value: unknown): value is Boolean { - if (!isObjectLike(value)) { - return false; - } - - try { - _booleanValueOf.call(value); - return true; - } catch { - return false; - } -} - -export function isBoxedPrimitive( - value: unknown, - // deno-lint-ignore ban-types -): value is Boolean | String | Number | Symbol | BigInt { - return ( - isBooleanObject(value) || - isStringObject(value) || - isNumberObject(value) || - isSymbolObject(value) || - isBigIntObject(value) - ); -} - -export function isDataView(value: unknown): value is DataView { - return ( - ArrayBuffer.isView(value) && - _getTypedArrayToStringTag.call(value) === undefined - ); -} - -export function isDate(value: unknown): value is Date { - try { - _dateValueOf.call(value); - return true; - } catch { - return false; - } -} - -export function isGeneratorFunction( - value: unknown, -): value is GeneratorFunction { - return core.isGeneratorFunction(value); -} - -export function isGeneratorObject(value: unknown): value is Generator { - return core.isGeneratorObject(value); -} - -export function isMap(value: unknown): value is Map { - try { - _getMapSize.call(value); - return true; - } catch { - return false; - } -} - -export function isMapIterator( - value: unknown, -): value is IterableIterator<[unknown, unknown]> { - return core.isMapIterator(value); -} - -export function isModuleNamespaceObject( - value: unknown, -): value is Record { - return core.isModuleNamespaceObject(value); -} - -export function isNativeError(value: unknown): value is Error { - return core.isNativeError(value); -} - -// deno-lint-ignore ban-types -export function isNumberObject(value: unknown): value is Number { - if (!isObjectLike(value)) { - return false; - } - - try { - _numberValueOf.call(value); - return true; - } catch { - return false; - } -} - -export function isBigIntObject(value: unknown): value is bigint { - if (!isObjectLike(value)) { - return false; - } - - try { - _bigIntValueOf.call(value); - return true; - } catch { - return false; - } -} - -export function isPromise(value: unknown): value is Promise { - return core.isPromise(value); -} - -export function isProxy( - value: unknown, -): value is Record { - return core.isProxy(value); -} - -export function isRegExp(value: unknown): value is RegExp { - return core.isRegExp(value); -} - -export function isSet(value: unknown): value is Set { - try { - _getSetSize.call(value); - return true; - } catch { - return false; - } -} - -export function isSetIterator( - value: unknown, -): value is IterableIterator { - return core.isSetIterator(value); -} - -export function isSharedArrayBuffer( - value: unknown, -): value is SharedArrayBuffer { - // TODO(kt3k): add SharedArrayBuffer to primordials - _getSharedArrayBufferByteLength ??= Object.getOwnPropertyDescriptor( - SharedArrayBuffer.prototype, - "byteLength", - )!.get!; - - try { - _getSharedArrayBufferByteLength.call(value); - return true; - } catch { - return false; - } -} - -// deno-lint-ignore ban-types -export function isStringObject(value: unknown): value is String { - if (!isObjectLike(value)) { - return false; - } - - try { - _stringValueOf.call(value); - return true; - } catch { - return false; - } -} - -// deno-lint-ignore ban-types -export function isSymbolObject(value: unknown): value is Symbol { - if (!isObjectLike(value)) { - return false; - } - - try { - _symbolValueOf.call(value); - return true; - } catch { - return false; - } -} - -export function isWeakMap( - value: unknown, -): value is WeakMap, unknown> { - try { - // deno-lint-ignore no-explicit-any - _weakMapHas.call(value, null as any); - return true; - } catch { - return false; - } -} - -export function isWeakSet( - value: unknown, -): value is WeakSet> { - try { - // deno-lint-ignore no-explicit-any - _weakSetHas.call(value, null as any); - return true; - } catch { - return false; - } -} - -export default { - isAsyncFunction, - isGeneratorFunction, +export const { + // isExternal, isAnyArrayBuffer, - isArrayBuffer, isArgumentsObject, + isArrayBuffer, + isAsyncFunction, + isBigIntObject, + isBooleanObject, isBoxedPrimitive, isDataView, - // isExternal, + isDate, + isGeneratorFunction, + isGeneratorObject, isMap, isMapIterator, isModuleNamespaceObject, isNativeError, + isNumberObject, isPromise, + isProxy, + isRegExp, isSet, isSetIterator, + isSharedArrayBuffer, + isStringObject, + isSymbolObject, + isTypedArray, isWeakMap, isWeakSet, - isRegExp, - isDate, - isStringObject, - isNumberObject, - isBooleanObject, - isBigIntObject, -}; +} = core; diff --git a/ext/web/01_dom_exception.js b/ext/web/01_dom_exception.js index 99e917f0fd..14cabc286c 100644 --- a/ext/web/01_dom_exception.js +++ b/ext/web/01_dom_exception.js @@ -210,4 +210,4 @@ for (let i = 0; i < entries.length; ++i) { ObjectDefineProperty(DOMException.prototype, key, desc); } -export default DOMException; +export { DOMException, DOMExceptionPrototype }; diff --git a/ext/web/02_event.js b/ext/web/02_event.js index 80ae81b99f..d014b7a735 100644 --- a/ext/web/02_event.js +++ b/ext/web/02_event.js @@ -7,7 +7,7 @@ import { core, primordials } from "ext:core/mod.js"; import * as webidl from "ext:deno_webidl/00_webidl.js"; -import DOMException from "ext:deno_web/01_dom_exception.js"; +import { DOMException } from "ext:deno_web/01_dom_exception.js"; import { createFilteredInspectProxy } from "ext:deno_console/01_console.js"; const { ArrayPrototypeFilter, diff --git a/ext/web/02_structured_clone.js b/ext/web/02_structured_clone.js index 72778e8033..13275e2d89 100644 --- a/ext/web/02_structured_clone.js +++ b/ext/web/02_structured_clone.js @@ -7,10 +7,9 @@ /// import { core, primordials } from "ext:core/mod.js"; -import DOMException from "ext:deno_web/01_dom_exception.js"; +import { DOMException } from "ext:deno_web/01_dom_exception.js"; const { ArrayBuffer, - ArrayBufferPrototype, ArrayBufferPrototypeGetByteLength, ArrayBufferPrototypeSlice, ArrayBufferIsView, @@ -38,6 +37,9 @@ const { Float32Array, Float64Array, } = primordials; +const { + isArrayBuffer, +} = core; const objectCloneMemo = new SafeWeakMap(); @@ -61,7 +63,7 @@ function cloneArrayBuffer( function structuredClone(value) { // Performance optimization for buffers, otherwise // `serialize/deserialize` will allocate new buffer. - if (ObjectPrototypeIsPrototypeOf(ArrayBufferPrototype, value)) { + if (isArrayBuffer(value)) { const cloned = cloneArrayBuffer( value, 0, diff --git a/ext/web/05_base64.js b/ext/web/05_base64.js index 63e9d95f83..c6e92d3907 100644 --- a/ext/web/05_base64.js +++ b/ext/web/05_base64.js @@ -9,7 +9,7 @@ import { core, primordials } from "ext:core/mod.js"; const ops = core.ops; import * as webidl from "ext:deno_webidl/00_webidl.js"; -import DOMException from "ext:deno_web/01_dom_exception.js"; +import { DOMException } from "ext:deno_web/01_dom_exception.js"; const { ObjectPrototypeIsPrototypeOf, TypeErrorPrototype, diff --git a/ext/web/06_streams.js b/ext/web/06_streams.js index 65f6ac05e1..49c1eb41c4 100644 --- a/ext/web/06_streams.js +++ b/ext/web/06_streams.js @@ -36,7 +36,6 @@ import { const { ArrayBuffer, ArrayBufferIsView, - ArrayBufferPrototype, ArrayBufferPrototypeGetByteLength, ArrayBufferPrototypeSlice, ArrayPrototypeMap, @@ -96,6 +95,12 @@ const { WeakMapPrototypeSet, queueMicrotask, } = primordials; +const { + isAnyArrayBuffer, + isArrayBuffer, + isSharedArrayBuffer, + isTypedArray, +} = core; import { createFilteredInspectProxy } from "ext:deno_console/01_console.js"; import { assert, AssertionError } from "ext:deno_web/00_infra.js"; @@ -272,8 +277,7 @@ class Queue { * @returns {boolean} */ function isDetachedBuffer(O) { - // deno-lint-ignore prefer-primordials - if (ObjectPrototypeIsPrototypeOf(SharedArrayBuffer.prototype, O)) { + if (isSharedArrayBuffer(O)) { return false; } return ArrayBufferPrototypeGetByteLength(O) === 0 && @@ -286,11 +290,7 @@ function isDetachedBuffer(O) { */ function canTransferArrayBuffer(O) { assert(typeof O === "object"); - assert( - ObjectPrototypeIsPrototypeOf(ArrayBufferPrototype, O) || - // deno-lint-ignore prefer-primordials - ObjectPrototypeIsPrototypeOf(SharedArrayBuffer.prototype, O), - ); + assert(isAnyArrayBuffer(O)); if (isDetachedBuffer(O)) { return false; } @@ -311,8 +311,7 @@ function transferArrayBuffer(O) { * @returns {number} */ function getArrayBufferByteLength(O) { - // deno-lint-ignore prefer-primordials - if (ObjectPrototypeIsPrototypeOf(SharedArrayBuffer.prototype, O)) { + if (isSharedArrayBuffer(O)) { // TODO(petamoriken): use primordials // deno-lint-ignore prefer-primordials return O.byteLength; @@ -328,8 +327,7 @@ function getArrayBufferByteLength(O) { function cloneAsUint8Array(O) { assert(typeof O === "object"); assert(ArrayBufferIsView(O)); - if (TypedArrayPrototypeGetSymbolToStringTag(O) !== undefined) { - // TypedArray + if (isTypedArray(O)) { return TypedArrayPrototypeSlice( new Uint8Array( TypedArrayPrototypeGetBuffer(/** @type {Uint8Array} */ (O)), @@ -338,7 +336,6 @@ function cloneAsUint8Array(O) { ), ); } else { - // DataView return TypedArrayPrototypeSlice( new Uint8Array( DataViewPrototypeGetBuffer(/** @type {DataView} */ (O)), @@ -1340,15 +1337,7 @@ function readableByteStreamControllerEnqueue(controller, chunk) { } let buffer, byteLength, byteOffset; - if (TypedArrayPrototypeGetSymbolToStringTag(chunk) === undefined) { - buffer = DataViewPrototypeGetBuffer(/** @type {DataView} */ (chunk)); - byteLength = DataViewPrototypeGetByteLength( - /** @type {DataView} */ (chunk), - ); - byteOffset = DataViewPrototypeGetByteOffset( - /** @type {DataView} */ (chunk), - ); - } else { + if (isTypedArray(chunk)) { buffer = TypedArrayPrototypeGetBuffer(/** @type {Uint8Array}} */ (chunk)); byteLength = TypedArrayPrototypeGetByteLength( /** @type {Uint8Array} */ (chunk), @@ -1356,6 +1345,14 @@ function readableByteStreamControllerEnqueue(controller, chunk) { byteOffset = TypedArrayPrototypeGetByteOffset( /** @type {Uint8Array} */ (chunk), ); + } else { + buffer = DataViewPrototypeGetBuffer(/** @type {DataView} */ (chunk)); + byteLength = DataViewPrototypeGetByteLength( + /** @type {DataView} */ (chunk), + ); + byteOffset = DataViewPrototypeGetByteOffset( + /** @type {DataView} */ (chunk), + ); } if (isDetachedBuffer(buffer)) { @@ -1461,7 +1458,7 @@ function readableByteStreamControllerEnqueueClonedChunkToQueue( ) { let cloneResult; try { - if (ObjectPrototypeIsPrototypeOf(ArrayBufferPrototype, buffer)) { + if (isArrayBuffer(buffer)) { cloneResult = ArrayBufferPrototypeSlice( buffer, byteOffset, @@ -2292,11 +2289,7 @@ function readableByteStreamControllerRespondWithNewView(controller, view) { assert(controller[_pendingPullIntos].length !== 0); let buffer, byteLength, byteOffset; - if (TypedArrayPrototypeGetSymbolToStringTag(view) === undefined) { - buffer = DataViewPrototypeGetBuffer(/** @type {DataView} */ (view)); - byteLength = DataViewPrototypeGetByteLength(/** @type {DataView} */ (view)); - byteOffset = DataViewPrototypeGetByteOffset(/** @type {DataView} */ (view)); - } else { + if (isTypedArray(view)) { buffer = TypedArrayPrototypeGetBuffer(/** @type {Uint8Array}} */ (view)); byteLength = TypedArrayPrototypeGetByteLength( /** @type {Uint8Array} */ (view), @@ -2304,7 +2297,12 @@ function readableByteStreamControllerRespondWithNewView(controller, view) { byteOffset = TypedArrayPrototypeGetByteOffset( /** @type {Uint8Array} */ (view), ); + } else { + buffer = DataViewPrototypeGetBuffer(/** @type {DataView} */ (view)); + byteLength = DataViewPrototypeGetByteLength(/** @type {DataView} */ (view)); + byteOffset = DataViewPrototypeGetByteOffset(/** @type {DataView} */ (view)); } + assert(!isDetachedBuffer(buffer)); const firstDescriptor = controller[_pendingPullIntos][0]; const state = controller[_stream][_state]; @@ -3364,14 +3362,14 @@ function readableByteStreamTee(stream) { } if (chunk !== undefined) { let byteLength; - if (TypedArrayPrototypeGetSymbolToStringTag(chunk) === undefined) { - byteLength = DataViewPrototypeGetByteLength( - /** @type {DataView} */ (chunk), - ); - } else { + if (isTypedArray(chunk)) { byteLength = TypedArrayPrototypeGetByteLength( /** @type {Uint8Array} */ (chunk), ); + } else { + byteLength = DataViewPrototypeGetByteLength( + /** @type {DataView} */ (chunk), + ); } assert(byteLength === 0); if (!byobCanceled) { @@ -5581,16 +5579,16 @@ class ReadableStreamBYOBReader { } let buffer, byteLength; - if (TypedArrayPrototypeGetSymbolToStringTag(view) === undefined) { - buffer = DataViewPrototypeGetBuffer(/** @type {DataView} */ (view)); - byteLength = DataViewPrototypeGetByteLength( - /** @type {DataView} */ (view), - ); - } else { + if (isTypedArray(view)) { buffer = TypedArrayPrototypeGetBuffer(/** @type {Uint8Array} */ (view)); byteLength = TypedArrayPrototypeGetByteLength( /** @type {Uint8Array} */ (view), ); + } else { + buffer = DataViewPrototypeGetBuffer(/** @type {DataView} */ (view)); + byteLength = DataViewPrototypeGetByteLength( + /** @type {DataView} */ (view), + ); } if (byteLength === 0) { return PromiseReject( @@ -5613,7 +5611,7 @@ class ReadableStreamBYOBReader { if (options.min === 0) { return PromiseReject(new TypeError("options.min must be non-zero")); } - if (TypedArrayPrototypeGetSymbolToStringTag(view) !== undefined) { + if (isTypedArray(view)) { if (options.min > TypedArrayPrototypeGetLength(view)) { return PromiseReject( new RangeError("options.min must be smaller or equal to view's size"), @@ -5745,12 +5743,12 @@ class ReadableStreamBYOBRequest { } let buffer, byteLength; - if (TypedArrayPrototypeGetSymbolToStringTag(this[_view]) === undefined) { - buffer = DataViewPrototypeGetBuffer(this[_view]); - byteLength = DataViewPrototypeGetByteLength(this[_view]); - } else { + if (isTypedArray(this[_view])) { buffer = TypedArrayPrototypeGetBuffer(this[_view]); byteLength = TypedArrayPrototypeGetByteLength(this[_view]); + } else { + buffer = DataViewPrototypeGetBuffer(this[_view]); + byteLength = DataViewPrototypeGetByteLength(this[_view]); } if (isDetachedBuffer(buffer)) { throw new TypeError( @@ -5774,10 +5772,10 @@ class ReadableStreamBYOBRequest { } let buffer; - if (TypedArrayPrototypeGetSymbolToStringTag(view) === undefined) { - buffer = DataViewPrototypeGetBuffer(view); - } else { + if (isTypedArray(view)) { buffer = TypedArrayPrototypeGetBuffer(view); + } else { + buffer = DataViewPrototypeGetBuffer(view); } if (isDetachedBuffer(buffer)) { throw new TypeError( @@ -5864,16 +5862,16 @@ class ReadableByteStreamController { const arg1 = "Argument 1"; chunk = webidl.converters.ArrayBufferView(chunk, prefix, arg1); let buffer, byteLength; - if (TypedArrayPrototypeGetSymbolToStringTag(chunk) === undefined) { - buffer = DataViewPrototypeGetBuffer(/** @type {DataView} */ (chunk)); - byteLength = DataViewPrototypeGetByteLength( - /** @type {DataView} */ (chunk), - ); - } else { + if (isTypedArray(chunk)) { buffer = TypedArrayPrototypeGetBuffer(/** @type {Uint8Array} */ (chunk)); byteLength = TypedArrayPrototypeGetByteLength( /** @type {Uint8Array} */ (chunk), ); + } else { + buffer = DataViewPrototypeGetBuffer(/** @type {DataView} */ (chunk)); + byteLength = DataViewPrototypeGetByteLength( + /** @type {DataView} */ (chunk), + ); } if (byteLength === 0) { throw webidl.makeException( diff --git a/ext/web/08_text_encoding.js b/ext/web/08_text_encoding.js index 2b7eb35bb9..e563c8bd4a 100644 --- a/ext/web/08_text_encoding.js +++ b/ext/web/08_text_encoding.js @@ -17,23 +17,26 @@ const { DataViewPrototypeGetBuffer, DataViewPrototypeGetByteLength, DataViewPrototypeGetByteOffset, + ObjectPrototypeIsPrototypeOf, PromiseReject, PromiseResolve, // TODO(lucacasonato): add SharedArrayBuffer to primordials - // SharedArrayBufferPrototype + // SharedArrayBufferPrototype, StringPrototypeCharCodeAt, StringPrototypeSlice, SymbolFor, - TypedArrayPrototypeSubarray, TypedArrayPrototypeGetBuffer, TypedArrayPrototypeGetByteLength, TypedArrayPrototypeGetByteOffset, - TypedArrayPrototypeGetSymbolToStringTag, - Uint8Array, - ObjectPrototypeIsPrototypeOf, - ArrayBufferIsView, + TypedArrayPrototypeSubarray, Uint32Array, + Uint8Array, } = primordials; +const { + isDataView, + isSharedArrayBuffer, + isTypedArray, +} = core; class TextDecoder { /** @type {string} */ @@ -111,51 +114,37 @@ class TextDecoder { try { /** @type {ArrayBufferLike} */ let buffer = input; - if (ArrayBufferIsView(input)) { - if (TypedArrayPrototypeGetSymbolToStringTag(input) !== undefined) { - // TypedArray - buffer = TypedArrayPrototypeGetBuffer( - /** @type {Uint8Array} */ (input), - ); - } else { - // DataView - buffer = DataViewPrototypeGetBuffer(/** @type {DataView} */ (input)); - } + if (isTypedArray(input)) { + buffer = TypedArrayPrototypeGetBuffer( + /** @type {Uint8Array} */ (input), + ); + } else if (isDataView(input)) { + buffer = DataViewPrototypeGetBuffer(/** @type {DataView} */ (input)); } // Note from spec: implementations are strongly encouraged to use an implementation strategy that avoids this copy. // When doing so they will have to make sure that changes to input do not affect future calls to decode(). - if ( - ObjectPrototypeIsPrototypeOf( - // deno-lint-ignore prefer-primordials - SharedArrayBuffer.prototype, - buffer, - ) - ) { + if (isSharedArrayBuffer(buffer)) { // We clone the data into a non-shared ArrayBuffer so we can pass it // to Rust. // `input` is now a Uint8Array, and calling the TypedArray constructor // with a TypedArray argument copies the data. - if (ArrayBufferIsView(input)) { - if (TypedArrayPrototypeGetSymbolToStringTag(input) !== undefined) { - // TypedArray - input = new Uint8Array( - buffer, - TypedArrayPrototypeGetByteOffset( - /** @type {Uint8Array} */ (input), - ), - TypedArrayPrototypeGetByteLength( - /** @type {Uint8Array} */ (input), - ), - ); - } else { - // DataView - input = new Uint8Array( - buffer, - DataViewPrototypeGetByteOffset(/** @type {DataView} */ (input)), - DataViewPrototypeGetByteLength(/** @type {DataView} */ (input)), - ); - } + if (isTypedArray(input)) { + input = new Uint8Array( + buffer, + TypedArrayPrototypeGetByteOffset( + /** @type {Uint8Array} */ (input), + ), + TypedArrayPrototypeGetByteLength( + /** @type {Uint8Array} */ (input), + ), + ); + } else if (isDataView(input)) { + input = new Uint8Array( + buffer, + DataViewPrototypeGetByteOffset(/** @type {DataView} */ (input)), + DataViewPrototypeGetByteLength(/** @type {DataView} */ (input)), + ); } else { input = new Uint8Array(buffer); } diff --git a/ext/web/09_file.js b/ext/web/09_file.js index 4288802af1..c38fbd1017 100644 --- a/ext/web/09_file.js +++ b/ext/web/09_file.js @@ -16,10 +16,9 @@ import * as webidl from "ext:deno_webidl/00_webidl.js"; import { ReadableStream } from "ext:deno_web/06_streams.js"; import { URL } from "ext:deno_url/00_url.js"; const { - ArrayBufferPrototype, - ArrayBufferPrototypeSlice, - ArrayBufferPrototypeGetByteLength, ArrayBufferIsView, + ArrayBufferPrototypeGetByteLength, + ArrayBufferPrototypeSlice, ArrayPrototypePush, AsyncGeneratorPrototypeNext, DataViewPrototypeGetBuffer, @@ -31,23 +30,26 @@ const { MathMin, ObjectPrototypeIsPrototypeOf, RegExpPrototypeTest, - // TODO(lucacasonato): add SharedArrayBuffer to primordials - // SharedArrayBufferPrototype SafeFinalizationRegistry, SafeRegExp, StringPrototypeCharAt, - StringPrototypeToLowerCase, StringPrototypeSlice, + StringPrototypeToLowerCase, Symbol, SymbolFor, - TypedArrayPrototypeSet, + TypeError, TypedArrayPrototypeGetBuffer, TypedArrayPrototypeGetByteLength, TypedArrayPrototypeGetByteOffset, - TypedArrayPrototypeGetSymbolToStringTag, - TypeError, + TypedArrayPrototypeSet, Uint8Array, } = primordials; +const { + isAnyArrayBuffer, + isArrayBuffer, + isDataView, + isTypedArray, +} = core; import { createFilteredInspectProxy } from "ext:deno_console/01_console.js"; const { op_blob_read_part, @@ -129,34 +131,30 @@ function processBlobParts(parts, endings) { let size = 0; for (let i = 0; i < parts.length; ++i) { const element = parts[i]; - if (ObjectPrototypeIsPrototypeOf(ArrayBufferPrototype, element)) { + if (isArrayBuffer(element)) { const chunk = new Uint8Array(ArrayBufferPrototypeSlice(element, 0)); ArrayPrototypePush(processedParts, BlobReference.fromUint8Array(chunk)); size += ArrayBufferPrototypeGetByteLength(element); - } else if (ArrayBufferIsView(element)) { - if (TypedArrayPrototypeGetSymbolToStringTag(element) !== undefined) { - // TypedArray - const chunk = new Uint8Array( - TypedArrayPrototypeGetBuffer(/** @type {Uint8Array} */ (element)), - TypedArrayPrototypeGetByteOffset(/** @type {Uint8Array} */ (element)), - TypedArrayPrototypeGetByteLength(/** @type {Uint8Array} */ (element)), - ); - size += TypedArrayPrototypeGetByteLength( - /** @type {Uint8Array} */ (element), - ); - ArrayPrototypePush(processedParts, BlobReference.fromUint8Array(chunk)); - } else { - // DataView - const chunk = new Uint8Array( - DataViewPrototypeGetBuffer(/** @type {DataView} */ (element)), - DataViewPrototypeGetByteOffset(/** @type {DataView} */ (element)), - DataViewPrototypeGetByteLength(/** @type {DataView} */ (element)), - ); - size += DataViewPrototypeGetByteLength( - /** @type {DataView} */ (element), - ); - ArrayPrototypePush(processedParts, BlobReference.fromUint8Array(chunk)); - } + } else if (isTypedArray(element)) { + const chunk = new Uint8Array( + TypedArrayPrototypeGetBuffer(/** @type {Uint8Array} */ (element)), + TypedArrayPrototypeGetByteOffset(/** @type {Uint8Array} */ (element)), + TypedArrayPrototypeGetByteLength(/** @type {Uint8Array} */ (element)), + ); + size += TypedArrayPrototypeGetByteLength( + /** @type {Uint8Array} */ (element), + ); + ArrayPrototypePush(processedParts, BlobReference.fromUint8Array(chunk)); + } else if (isDataView(element)) { + const chunk = new Uint8Array( + DataViewPrototypeGetBuffer(/** @type {DataView} */ (element)), + DataViewPrototypeGetByteOffset(/** @type {DataView} */ (element)), + DataViewPrototypeGetByteLength(/** @type {DataView} */ (element)), + ); + size += DataViewPrototypeGetByteLength( + /** @type {DataView} */ (element), + ); + ArrayPrototypePush(processedParts, BlobReference.fromUint8Array(chunk)); } else if (ObjectPrototypeIsPrototypeOf(BlobPrototype, element)) { ArrayPrototypePush(processedParts, element); size += element.size; @@ -446,11 +444,7 @@ webidl.converters["BlobPart"] = (V, prefix, context, opts) => { if (ObjectPrototypeIsPrototypeOf(BlobPrototype, V)) { return webidl.converters["Blob"](V, prefix, context, opts); } - if ( - ObjectPrototypeIsPrototypeOf(ArrayBufferPrototype, V) || - // deno-lint-ignore prefer-primordials - ObjectPrototypeIsPrototypeOf(SharedArrayBuffer.prototype, V) - ) { + if (isAnyArrayBuffer(V)) { return webidl.converters["ArrayBuffer"](V, prefix, context, opts); } if (ArrayBufferIsView(V)) { diff --git a/ext/web/10_filereader.js b/ext/web/10_filereader.js index 36f4a51887..2a75ff8d6c 100644 --- a/ext/web/10_filereader.js +++ b/ext/web/10_filereader.js @@ -18,7 +18,7 @@ import { forgivingBase64Encode } from "ext:deno_web/00_infra.js"; import { EventTarget, ProgressEvent } from "ext:deno_web/02_event.js"; import { decode, TextDecoder } from "ext:deno_web/08_text_encoding.js"; import { parseMimeType } from "ext:deno_web/01_mimesniff.js"; -import DOMException from "ext:deno_web/01_dom_exception.js"; +import { DOMException } from "ext:deno_web/01_dom_exception.js"; const { ArrayPrototypePush, ArrayPrototypeReduce, diff --git a/ext/web/12_location.js b/ext/web/12_location.js index 8ba9be6342..5cc8502624 100644 --- a/ext/web/12_location.js +++ b/ext/web/12_location.js @@ -3,7 +3,7 @@ /// import { URL } from "ext:deno_url/00_url.js"; -import DOMException from "ext:deno_web/01_dom_exception.js"; +import { DOMException } from "ext:deno_web/01_dom_exception.js"; import { primordials } from "ext:core/mod.js"; const { Error, diff --git a/ext/web/13_message_port.js b/ext/web/13_message_port.js index 71adae1f46..0fddfc2e84 100644 --- a/ext/web/13_message_port.js +++ b/ext/web/13_message_port.js @@ -18,9 +18,8 @@ import { setIsTrusted, } from "ext:deno_web/02_event.js"; import { isDetachedBuffer } from "ext:deno_web/06_streams.js"; -import DOMException from "ext:deno_web/01_dom_exception.js"; +import { DOMException } from "ext:deno_web/01_dom_exception.js"; const { - ArrayBufferPrototype, ArrayBufferPrototypeGetByteLength, ArrayPrototypeFilter, ArrayPrototypeIncludes, @@ -31,6 +30,9 @@ const { SymbolIterator, TypeError, } = primordials; +const { + isArrayBuffer, +} = core; const { op_message_port_recv_message, } = core.ensureFastOps(); @@ -282,7 +284,7 @@ function serializeJsMessageData(data, transferables) { const hostObjects = []; for (let i = 0, j = 0; i < transferables.length; i++) { const t = transferables[i]; - if (ObjectPrototypeIsPrototypeOf(ArrayBufferPrototype, t)) { + if (isArrayBuffer(t)) { if ( ArrayBufferPrototypeGetByteLength(t) === 0 && isDetachedBuffer(t) @@ -329,9 +331,7 @@ function serializeJsMessageData(data, transferables) { kind: "messagePort", data: id, }); - } else if ( - ObjectPrototypeIsPrototypeOf(ArrayBufferPrototype, transferable) - ) { + } else if (isArrayBuffer(transferable)) { ArrayPrototypePush(serializedTransferables, { kind: "arrayBuffer", data: transferredArrayBuffers[arrayBufferI], diff --git a/ext/web/15_performance.js b/ext/web/15_performance.js index f5ec960769..b686f75ddc 100644 --- a/ext/web/15_performance.js +++ b/ext/web/15_performance.js @@ -19,7 +19,7 @@ import { structuredClone } from "ext:deno_web/02_structured_clone.js"; import { createFilteredInspectProxy } from "ext:deno_console/01_console.js"; import { EventTarget } from "ext:deno_web/02_event.js"; import { opNow } from "ext:deno_web/02_timers.js"; -import DOMException from "ext:deno_web/01_dom_exception.js"; +import { DOMException } from "ext:deno_web/01_dom_exception.js"; const illegalConstructorKey = Symbol("illegalConstructorKey"); let performanceEntries = []; diff --git a/ext/web/16_image_data.js b/ext/web/16_image_data.js index 63e35733e7..c7f8795f57 100644 --- a/ext/web/16_image_data.js +++ b/ext/web/16_image_data.js @@ -1,7 +1,7 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. import * as webidl from "ext:deno_webidl/00_webidl.js"; -import DOMException from "ext:deno_web/01_dom_exception.js"; +import { DOMException } from "ext:deno_web/01_dom_exception.js"; import { createFilteredInspectProxy } from "ext:deno_console/01_console.js"; const primordials = globalThis.__bootstrap.primordials; const { diff --git a/ext/web/internal.d.ts b/ext/web/internal.d.ts index 6b81e3fe34..c980ddceeb 100644 --- a/ext/web/internal.d.ts +++ b/ext/web/internal.d.ts @@ -47,7 +47,7 @@ declare module "ext:deno_web/00_infra.js" { } declare module "ext:deno_web/01_dom_exception.js" { - export = DOMException; + const DOMException: DOMException; } declare module "ext:deno_web/01_mimesniff.js" { diff --git a/ext/webgpu/01_webgpu.js b/ext/webgpu/01_webgpu.js index 3e8978fef5..c8258621f8 100644 --- a/ext/webgpu/01_webgpu.js +++ b/ext/webgpu/01_webgpu.js @@ -10,11 +10,10 @@ import { core, primordials } from "ext:core/mod.js"; const ops = core.ops; import * as webidl from "ext:deno_webidl/00_webidl.js"; import { EventTarget } from "ext:deno_web/02_event.js"; -import DOMException from "ext:deno_web/01_dom_exception.js"; +import { DOMException } from "ext:deno_web/01_dom_exception.js"; import { createFilteredInspectProxy } from "ext:deno_console/01_console.js"; const { ArrayBuffer, - ArrayBufferIsView, ArrayIsArray, ArrayPrototypeFilter, ArrayPrototypeMap, @@ -45,9 +44,12 @@ const { SymbolIterator, TypeError, Uint32Array, - Uint32ArrayPrototype, Uint8Array, } = primordials; +const { + isDataView, + isTypedArray, +} = core; const { op_webgpu_buffer_get_map_async, op_webgpu_request_adapter, @@ -1690,17 +1692,14 @@ class GPUQueue { }); /** @type {ArrayBufferLike} */ let abLike = data; - if (ArrayBufferIsView(data)) { - if (TypedArrayPrototypeGetSymbolToStringTag(data) !== undefined) { - // TypedArray - abLike = TypedArrayPrototypeGetBuffer( - /** @type {Uint8Array} */ (data), - ); - } else { - // DataView - abLike = DataViewPrototypeGetBuffer(/** @type {DataView} */ (data)); - } + if (isTypedArray(data)) { + abLike = TypedArrayPrototypeGetBuffer( + /** @type {Uint8Array} */ (data), + ); + } else if (isDataView(data)) { + abLike = DataViewPrototypeGetBuffer(/** @type {DataView} */ (data)); } + const { err } = ops.op_webgpu_write_buffer( device.rid, bufferRid, @@ -1744,16 +1743,12 @@ class GPUQueue { /** @type {ArrayBufferLike} */ let abLike = data; - if (ArrayBufferIsView(data)) { - if (TypedArrayPrototypeGetSymbolToStringTag(data) !== undefined) { - // TypedArray - abLike = TypedArrayPrototypeGetBuffer( - /** @type {Uint8Array} */ (data), - ); - } else { - // DataView - abLike = DataViewPrototypeGetBuffer(/** @type {DataView} */ (data)); - } + if (isTypedArray(data)) { + abLike = TypedArrayPrototypeGetBuffer( + /** @type {Uint8Array} */ (data), + ); + } else if (isDataView(data)) { + abLike = DataViewPrototypeGetBuffer(/** @type {DataView} */ (data)); } const { err } = ops.op_webgpu_write_texture( @@ -3778,10 +3773,8 @@ class GPURenderPassEncoder { selfContext: "this", }); if ( - !(ObjectPrototypeIsPrototypeOf( - Uint32ArrayPrototype, - dynamicOffsetsData, - )) + TypedArrayPrototypeGetSymbolToStringTag(dynamicOffsetsData) !== + "Uint32Array" ) { dynamicOffsetsData = new Uint32Array(dynamicOffsetsData ?? []); dynamicOffsetsDataStart = 0; @@ -4337,10 +4330,8 @@ class GPUComputePassEncoder { selfContext: "this", }); if ( - !(ObjectPrototypeIsPrototypeOf( - Uint32ArrayPrototype, - dynamicOffsetsData, - )) + TypedArrayPrototypeGetSymbolToStringTag(dynamicOffsetsData) !== + "Uint32Array" ) { dynamicOffsetsData = new Uint32Array(dynamicOffsetsData ?? []); dynamicOffsetsDataStart = 0; @@ -4555,10 +4546,8 @@ class GPURenderBundleEncoder { selfContext: "this", }); if ( - !(ObjectPrototypeIsPrototypeOf( - Uint32ArrayPrototype, - dynamicOffsetsData, - )) + TypedArrayPrototypeGetSymbolToStringTag(dynamicOffsetsData) !== + "Uint32Array" ) { dynamicOffsetsData = new Uint32Array(dynamicOffsetsData ?? []); dynamicOffsetsDataStart = 0; diff --git a/ext/webidl/00_webidl.js b/ext/webidl/00_webidl.js index 3713c7d097..a702e73241 100644 --- a/ext/webidl/00_webidl.js +++ b/ext/webidl/00_webidl.js @@ -8,7 +8,6 @@ import { core, primordials } from "ext:core/mod.js"; const { - ArrayBufferPrototype, ArrayBufferIsView, ArrayPrototypeForEach, ArrayPrototypePush, @@ -67,7 +66,7 @@ const { SetPrototypeDelete, SetPrototypeAdd, // TODO(lucacasonato): add SharedArrayBuffer to primordials - // SharedArrayBufferPrototype + // SharedArrayBufferPrototype, String, StringPrototypeCharCodeAt, StringPrototypeToWellFormed, @@ -82,6 +81,12 @@ const { Uint8Array, Uint8ClampedArray, } = primordials; +const { + isArrayBuffer, + isDataView, + isSharedArrayBuffer, + isTypedArray, +} = core; function makeException(ErrorType, message, prefix, context) { return new ErrorType( @@ -456,27 +461,13 @@ function convertCallbackFunction(V, prefix, context, _opts) { return V; } -function isDataView(V) { - return ArrayBufferIsView(V) && - TypedArrayPrototypeGetSymbolToStringTag(V) === undefined; -} - -function isNonSharedArrayBuffer(V) { - return ObjectPrototypeIsPrototypeOf(ArrayBufferPrototype, V); -} - -function isSharedArrayBuffer(V) { - // deno-lint-ignore prefer-primordials - return ObjectPrototypeIsPrototypeOf(SharedArrayBuffer.prototype, V); -} - converters.ArrayBuffer = ( V, prefix = undefined, context = undefined, opts = {}, ) => { - if (!isNonSharedArrayBuffer(V)) { + if (!isArrayBuffer(V)) { if (opts.allowShared && !isSharedArrayBuffer(V)) { throw makeException( TypeError, @@ -511,7 +502,10 @@ converters.DataView = ( ); } - if (!opts.allowShared && isSharedArrayBuffer(DataViewPrototypeGetBuffer(V))) { + if ( + !opts.allowShared && + isSharedArrayBuffer(DataViewPrototypeGetBuffer(V)) + ) { throw makeException( TypeError, "is backed by a SharedArrayBuffer, which is not allowed", @@ -588,7 +582,7 @@ converters.ArrayBufferView = ( ); } let buffer; - if (TypedArrayPrototypeGetSymbolToStringTag(V) !== undefined) { + if (isTypedArray(V)) { buffer = TypedArrayPrototypeGetBuffer(V); } else { buffer = DataViewPrototypeGetBuffer(V); @@ -613,7 +607,7 @@ converters.BufferSource = ( ) => { if (ArrayBufferIsView(V)) { let buffer; - if (TypedArrayPrototypeGetSymbolToStringTag(V) !== undefined) { + if (isTypedArray(V)) { buffer = TypedArrayPrototypeGetBuffer(V); } else { buffer = DataViewPrototypeGetBuffer(V); @@ -630,7 +624,7 @@ converters.BufferSource = ( return V; } - if (!opts.allowShared && !isNonSharedArrayBuffer(V)) { + if (!opts.allowShared && !isArrayBuffer(V)) { throw makeException( TypeError, "is not an ArrayBuffer or a view on one", @@ -641,7 +635,7 @@ converters.BufferSource = ( if ( opts.allowShared && !isSharedArrayBuffer(V) && - !isNonSharedArrayBuffer(V) + !isArrayBuffer(V) ) { throw makeException( TypeError, diff --git a/ext/websocket/01_websocket.js b/ext/websocket/01_websocket.js index 57689d1ae8..fdcb0be999 100644 --- a/ext/websocket/01_websocket.js +++ b/ext/websocket/01_websocket.js @@ -7,7 +7,7 @@ import { URL } from "ext:deno_url/00_url.js"; import * as webidl from "ext:deno_webidl/00_webidl.js"; import { createFilteredInspectProxy } from "ext:deno_console/01_console.js"; import { HTTP_TOKEN_CODE_POINT_RE } from "ext:deno_web/00_infra.js"; -import DOMException from "ext:deno_web/01_dom_exception.js"; +import { DOMException } from "ext:deno_web/01_dom_exception.js"; import { CloseEvent, defineEventHandler, @@ -21,7 +21,6 @@ import { import { Blob, BlobPrototype } from "ext:deno_web/09_file.js"; import { getLocationHref } from "ext:deno_web/12_location.js"; const { - ArrayBufferPrototype, ArrayBufferIsView, ArrayPrototypeJoin, ArrayPrototypeMap, @@ -29,21 +28,24 @@ const { ErrorPrototypeToString, ObjectDefineProperties, ObjectPrototypeIsPrototypeOf, + PromisePrototypeCatch, PromisePrototypeThen, RegExpPrototypeExec, SafeSet, SetPrototypeGetSize, - // TODO(lucacasonato): add SharedArrayBuffer to primordials - // SharedArrayBufferPrototype String, StringPrototypeEndsWith, StringPrototypeToLowerCase, Symbol, - SymbolIterator, - PromisePrototypeCatch, SymbolFor, + SymbolIterator, TypedArrayPrototypeGetByteLength, + Uint8Array, } = primordials; +const { + isAnyArrayBuffer, + isArrayBuffer, +} = core; import { op_ws_check_permission_and_cancel_handle, op_ws_close, @@ -80,11 +82,7 @@ webidl.converters["WebSocketSend"] = (V, prefix, context, opts) => { return webidl.converters["Blob"](V, prefix, context, opts); } if (typeof V === "object") { - if ( - ObjectPrototypeIsPrototypeOf(ArrayBufferPrototype, V) || - // deno-lint-ignore prefer-primordials - ObjectPrototypeIsPrototypeOf(SharedArrayBuffer.prototype, V) - ) { + if (isAnyArrayBuffer(V)) { return webidl.converters["ArrayBuffer"](V, prefix, context, opts); } if (ArrayBufferIsView(V)) { @@ -329,8 +327,7 @@ class WebSocket extends EventTarget { if (ArrayBufferIsView(data)) { op_ws_send_binary(this[_rid], data); - } else if (ObjectPrototypeIsPrototypeOf(ArrayBufferPrototype, data)) { - // deno-lint-ignore prefer-primordials + } else if (isArrayBuffer(data)) { op_ws_send_binary(this[_rid], new Uint8Array(data)); } else if (ObjectPrototypeIsPrototypeOf(BlobPrototype, data)) { PromisePrototypeThen( diff --git a/ext/websocket/02_websocketstream.js b/ext/websocket/02_websocketstream.js index d7ef5ea57d..0641b968d4 100644 --- a/ext/websocket/02_websocketstream.js +++ b/ext/websocket/02_websocketstream.js @@ -6,7 +6,7 @@ import { core, primordials } from "ext:core/mod.js"; import * as webidl from "ext:deno_webidl/00_webidl.js"; import { createFilteredInspectProxy } from "ext:deno_console/01_console.js"; import { Deferred, writableStreamClose } from "ext:deno_web/06_streams.js"; -import DOMException from "ext:deno_web/01_dom_exception.js"; +import { DOMException } from "ext:deno_web/01_dom_exception.js"; import { add, remove } from "ext:deno_web/03_abort_signal.js"; import { fillHeaders, @@ -29,7 +29,7 @@ const { SymbolFor, TypeError, TypedArrayPrototypeGetByteLength, - Uint8ArrayPrototype, + TypedArrayPrototypeGetSymbolToStringTag, } = primordials; import { op_ws_check_permission_and_cancel_handle, @@ -214,7 +214,8 @@ class WebSocketStream { if (typeof chunk === "string") { await op_ws_send_text_async(this[_rid], chunk); } else if ( - ObjectPrototypeIsPrototypeOf(Uint8ArrayPrototype, chunk) + TypedArrayPrototypeGetSymbolToStringTag(chunk) === + "Uint8Array" ) { await op_ws_send_binary_async(this[_rid], chunk); } else { diff --git a/runtime/js/98_global_scope.js b/runtime/js/98_global_scope.js index 0c3bf7ea79..14b11cbde4 100644 --- a/runtime/js/98_global_scope.js +++ b/runtime/js/98_global_scope.js @@ -36,7 +36,7 @@ import * as fetch from "ext:deno_fetch/26_fetch.js"; import * as eventSource from "ext:deno_fetch/27_eventsource.js"; import * as messagePort from "ext:deno_web/13_message_port.js"; import * as webidl from "ext:deno_webidl/00_webidl.js"; -import DOMException from "ext:deno_web/01_dom_exception.js"; +import { DOMException } from "ext:deno_web/01_dom_exception.js"; import * as abortSignal from "ext:deno_web/03_abort_signal.js"; import * as globalInterfaces from "ext:deno_web/04_global_interfaces.js"; import * as webStorage from "ext:deno_webstorage/01_webstorage.js"; diff --git a/runtime/js/99_main.js b/runtime/js/99_main.js index 2e1b962e34..625d77f403 100644 --- a/runtime/js/99_main.js +++ b/runtime/js/99_main.js @@ -27,6 +27,9 @@ const { SymbolIterator, TypeError, } = primordials; +const { + isNativeError, +} = core; import * as util from "ext:runtime/06_util.js"; import * as event from "ext:deno_web/02_event.js"; import * as location from "ext:deno_web/12_location.js"; @@ -52,7 +55,7 @@ import { } from "ext:runtime/90_deno_ns.js"; import { errors } from "ext:runtime/01_errors.js"; import * as webidl from "ext:deno_webidl/00_webidl.js"; -import DOMException from "ext:deno_web/01_dom_exception.js"; +import { DOMException } from "ext:deno_web/01_dom_exception.js"; import { mainRuntimeGlobalProperties, memoizeLazy, @@ -235,7 +238,10 @@ const opPpid = memoizeLazy(() => ops.op_ppid()); setNoColorFn(() => ops.op_bootstrap_no_color() || !ops.op_bootstrap_is_tty()); function formatException(error) { - if (ObjectPrototypeIsPrototypeOf(ErrorPrototype, error)) { + if ( + isNativeError(error) || + ObjectPrototypeIsPrototypeOf(ErrorPrototype, error) + ) { return null; } else if (typeof error == "string") { return `Uncaught ${