From daeca252adc026b2285158a66dff266f9126242e Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Mon, 22 Jan 2024 00:31:19 +0900 Subject: [PATCH 01/24] feat: Geometry Interfaces Module Co-authored-by: ud2 --- Cargo.lock | 101 ++ Cargo.toml | 7 + cli/build.rs | 1 + cli/tsc/dts/lib.deno.shared_globals.d.ts | 1 + cli/tsc/mod.rs | 1 + ext/geometry/00_init.js | 27 + ext/geometry/01_geometry.js | 2117 ++++++++++++++++++++++ ext/geometry/Cargo.toml | 18 + ext/geometry/README.md | 108 ++ ext/geometry/lib.deno_geometry.d.ts | 602 ++++++ ext/geometry/lib.rs | 269 +++ ext/webidl/00_webidl.js | 3 + ext/webidl/internal.d.ts | 6 + runtime/Cargo.toml | 2 + runtime/js/98_global_scope_window.js | 103 ++ runtime/js/98_global_scope_worker.js | 36 + runtime/lib.rs | 1 + runtime/shared.rs | 1 + runtime/snapshot.rs | 1 + runtime/web_worker.rs | 1 + runtime/worker.rs | 1 + tests/integration/js_unit_tests.rs | 1 + tests/unit/geometry_test.ts | 1195 ++++++++++++ tests/unit/test_util.ts | 1 + tests/wpt/runner/expectation.json | 205 ++- tools/core_import_map.json | 2 + tools/jsdoc_checker.js | 1 + 27 files changed, 4811 insertions(+), 1 deletion(-) create mode 100644 ext/geometry/00_init.js create mode 100644 ext/geometry/01_geometry.js create mode 100644 ext/geometry/Cargo.toml create mode 100644 ext/geometry/README.md create mode 100644 ext/geometry/lib.deno_geometry.d.ts create mode 100644 ext/geometry/lib.rs create mode 100644 tests/unit/geometry_test.ts diff --git a/Cargo.lock b/Cargo.lock index b054e9fe7ca836..ef2955de3a89dc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -192,6 +192,15 @@ version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +[[package]] +name = "approx" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" +dependencies = [ + "num-traits", +] + [[package]] name = "arbitrary" version = "1.3.2" @@ -1748,6 +1757,14 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "deno_geometry" +version = "0.1.0" +dependencies = [ + "deno_core", + "nalgebra", +] + [[package]] name = "deno_graph" version = "0.86.7" @@ -2218,6 +2235,7 @@ dependencies = [ "deno_fetch", "deno_ffi", "deno_fs", + "deno_geometry", "deno_http", "deno_io", "deno_kv", @@ -4836,6 +4854,16 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" +[[package]] +name = "matrixmultiply" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7574c1cf36da4798ab73da5b215bbf444f50718207754cb522201d78d1cd0ff2" +dependencies = [ + "autocfg", + "rawpointer", +] + [[package]] name = "md-5" version = "0.10.6" @@ -4994,6 +5022,21 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "nalgebra" +version = "0.33.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26aecdf64b707efd1310e3544d709c5c0ac61c13756046aaaba41be5c4f66a3b" +dependencies = [ + "approx", + "matrixmultiply", + "num-complex", + "num-rational", + "num-traits", + "simba", + "typenum", +] + [[package]] name = "napi-build" version = "1.2.1" @@ -5165,6 +5208,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "num-complex" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23c6602fda94a57c990fe0df199a035d83576b496aa29f4e634a8ac6004e68a6" +dependencies = [ + "num-traits", +] + [[package]] name = "num-conv" version = "0.1.0" @@ -5191,6 +5243,17 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.18" @@ -6141,6 +6204,12 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8cc3bcbdb1ddfc11e700e62968e6b4cc9c75bb466464ad28fb61c5b2c964418b" +[[package]] +name = "rawpointer" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" + [[package]] name = "rayon" version = "1.10.0" @@ -6590,6 +6659,15 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad97d4ce1560a5e27cec89519dc8300d1aa6035b099821261c651486a19e44d5" +[[package]] +name = "safe_arch" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f398075ce1e6a179b46f51bd88d0598b92b00d3551f1a2d4ac49e771b56ac354" +dependencies = [ + "bytemuck", +] + [[package]] name = "saffron" version = "0.1.0" @@ -6907,6 +6985,19 @@ dependencies = [ "rand_core", ] +[[package]] +name = "simba" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3a386a501cd104797982c15ae17aafe8b9261315b5d07e3ec803f2ea26be0fa" +dependencies = [ + "approx", + "num-complex", + "num-traits", + "paste", + "wide", +] + [[package]] name = "simd-abstraction" version = "0.7.1" @@ -8764,6 +8855,16 @@ dependencies = [ "web-sys", ] +[[package]] +name = "wide" +version = "0.7.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81a1851a719f11d1d2fea40e15c72f6c00de8c142d7ac47c1441cc7e4d0d5bc6" +dependencies = [ + "bytemuck", + "safe_arch", +] + [[package]] name = "widestring" version = "1.1.0" diff --git a/Cargo.toml b/Cargo.toml index fa2813caedcf3a..8dff7d175d9b53 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,7 @@ members = [ "ext/fetch", "ext/ffi", "ext/fs", + "ext/geometry", "ext/http", "ext/io", "ext/kv", @@ -78,6 +79,7 @@ deno_crypto = { version = "0.198.0", path = "./ext/crypto" } deno_fetch = { version = "0.208.0", path = "./ext/fetch" } deno_ffi = { version = "0.171.0", path = "./ext/ffi" } deno_fs = { version = "0.94.0", path = "./ext/fs" } +deno_geometry = { version = "0.1.0", path = "./ext/geometry" } deno_http = { version = "0.182.0", path = "./ext/http" } deno_io = { version = "0.94.0", path = "./ext/io" } deno_kv = { version = "0.92.0", path = "./ext/kv" } @@ -227,6 +229,9 @@ opentelemetry_sdk = "0.27.0" hkdf = "0.12.3" rsa = { version = "0.9.3", default-features = false, features = ["std", "pem", "hazmat"] } # hazmat needed for PrehashSigner in ext/node +# geometry +nalgebra = { version = "0.33.2", default-features = false, features = ["std"] } + # webgpu raw-window-handle = "0.6.0" wgpu-core = "0.21.1" @@ -297,6 +302,8 @@ opt-level = 3 opt-level = 3 [profile.release.package.deno_ffi] opt-level = 3 +[profile.release.package.deno_geometry] +opt-level = 3 [profile.release.package.deno_http] opt-level = 3 [profile.release.package.deno_napi] diff --git a/cli/build.rs b/cli/build.rs index 83290599e6bf06..69bb1d5fcbad75 100644 --- a/cli/build.rs +++ b/cli/build.rs @@ -146,6 +146,7 @@ mod ts { op_crate_libs.insert("deno.url", deno_url::get_declaration()); op_crate_libs.insert("deno.web", deno_web::get_declaration()); op_crate_libs.insert("deno.fetch", deno_fetch::get_declaration()); + op_crate_libs.insert("deno.geometry", deno_geometry::get_declaration()); op_crate_libs.insert("deno.webgpu", deno_webgpu_get_declaration()); op_crate_libs.insert("deno.websocket", deno_websocket::get_declaration()); op_crate_libs.insert("deno.webstorage", deno_webstorage::get_declaration()); diff --git a/cli/tsc/dts/lib.deno.shared_globals.d.ts b/cli/tsc/dts/lib.deno.shared_globals.d.ts index a469525270b588..d8ef7794055080 100644 --- a/cli/tsc/dts/lib.deno.shared_globals.d.ts +++ b/cli/tsc/dts/lib.deno.shared_globals.d.ts @@ -11,6 +11,7 @@ /// /// /// +/// /// /// /// diff --git a/cli/tsc/mod.rs b/cli/tsc/mod.rs index 3176c50d5c7e70..0b7508717789c2 100644 --- a/cli/tsc/mod.rs +++ b/cli/tsc/mod.rs @@ -103,6 +103,7 @@ pub fn get_types_declaration_file_text() -> String { "deno.webstorage", "deno.canvas", "deno.crypto", + "deno.geometry", "deno.broadcast_channel", "deno.net", "deno.shared_globals", diff --git a/ext/geometry/00_init.js b/ext/geometry/00_init.js new file mode 100644 index 00000000000000..d1b89bac5cadc6 --- /dev/null +++ b/ext/geometry/00_init.js @@ -0,0 +1,27 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +import { core } from "ext:core/mod.js"; + +const lazyLoad = core.createLazyLoader("ext:deno_geometry/01_geometry.js"); + +let geometry; + +/** + * @param {(transformList: string, prefix: string) => { matrix: Float64Array, is2D: boolean }} transformListParser + * @param {boolean} enableWindowFeatures + */ +export function createGeometryLoader( + transformListParser, + enableWindowFeatures, +) { + return () => { + if (geometry !== undefined) { + return geometry; + } + + geometry = lazyLoad(); + geometry.init(transformListParser, enableWindowFeatures); + + return geometry; + }; +} diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js new file mode 100644 index 00000000000000..8b5957ee4e2610 --- /dev/null +++ b/ext/geometry/01_geometry.js @@ -0,0 +1,2117 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +import { primordials } from "ext:core/mod.js"; +import { + op_geometry_flip_x_self, + op_geometry_flip_y_self, + op_geometry_invert_2d_self, + op_geometry_invert_self, + op_geometry_multiply, + op_geometry_multiply_self, + op_geometry_premultiply_point_self, + op_geometry_premultiply_self, + op_geometry_rotate_axis_angle_self, + op_geometry_rotate_from_vector_self, + op_geometry_rotate_self, + op_geometry_scale_self, + op_geometry_scale_with_origin_self, + op_geometry_skew_self, + op_geometry_translate_self, +} from "ext:core/ops"; +const { + ArrayPrototypeJoin, + Float32Array, + Float64Array, + MathMax, + MathMin, + NumberIsFinite, + ObjectDefineProperty, + ObjectIs, + ObjectPrototypeIsPrototypeOf, + Symbol, + SymbolFor, + SymbolIterator, + TypeError, + TypedArrayPrototypeEvery, + TypedArrayPrototypeJoin, +} = primordials; + +import { createFilteredInspectProxy } from "ext:deno_console/01_console.js"; +import * as webidl from "ext:deno_webidl/00_webidl.js"; +import { DOMException } from "ext:deno_web/01_dom_exception.js"; + +webidl.converters.DOMPointInit = webidl.createDictionaryConverter( + "DOMPointInit", + [ + { + key: "x", + converter: webidl.converters["unrestricted double"], + defaultValue: 0, + }, + { + key: "y", + converter: webidl.converters["unrestricted double"], + defaultValue: 0, + }, + { + key: "z", + converter: webidl.converters["unrestricted double"], + defaultValue: 0, + }, + { + key: "w", + converter: webidl.converters["unrestricted double"], + defaultValue: 1, + }, + ], +); + +webidl.converters.DOMRectInit = webidl.createDictionaryConverter( + "DOMRectInit", + [ + { + key: "x", + converter: webidl.converters["unrestricted double"], + defaultValue: 0, + }, + { + key: "y", + converter: webidl.converters["unrestricted double"], + defaultValue: 0, + }, + { + key: "width", + converter: webidl.converters["unrestricted double"], + defaultValue: 0, + }, + { + key: "height", + converter: webidl.converters["unrestricted double"], + defaultValue: 0, + }, + ], +); + +webidl.converters.DOMQuadInit = webidl.createDictionaryConverter( + "DOMQuadInit", + [ + { + key: "p1", + converter: webidl.converters.DOMPointInit, + }, + { + key: "p2", + converter: webidl.converters.DOMPointInit, + }, + { + key: "p3", + converter: webidl.converters.DOMPointInit, + }, + { + key: "p4", + converter: webidl.converters.DOMPointInit, + }, + ], +); + +/** @type {webidl.Dictionary} */ +const dictDOMMatrix2DInit = [ + { + key: "a", + converter: webidl.converters["unrestricted double"], + }, + { + key: "b", + converter: webidl.converters["unrestricted double"], + }, + { + key: "c", + converter: webidl.converters["unrestricted double"], + }, + { + key: "d", + converter: webidl.converters["unrestricted double"], + }, + { + key: "e", + converter: webidl.converters["unrestricted double"], + }, + { + key: "f", + converter: webidl.converters["unrestricted double"], + }, + { + key: "m11", + converter: webidl.converters["unrestricted double"], + }, + { + key: "m12", + converter: webidl.converters["unrestricted double"], + }, + { + key: "m21", + converter: webidl.converters["unrestricted double"], + }, + { + key: "m22", + converter: webidl.converters["unrestricted double"], + }, + { + key: "m41", + converter: webidl.converters["unrestricted double"], + }, + { + key: "m42", + converter: webidl.converters["unrestricted double"], + }, +]; + +webidl.converters.DOMMatrix2DInit = webidl.createDictionaryConverter( + "DOMMatrix2DInit", + dictDOMMatrix2DInit, +); + +webidl.converters.DOMMatrixInit = webidl.createDictionaryConverter( + "DOMMatrixInit", + dictDOMMatrix2DInit, + [ + { + key: "m13", + converter: webidl.converters["unrestricted double"], + defaultValue: 0, + }, + { + key: "m14", + converter: webidl.converters["unrestricted double"], + defaultValue: 0, + }, + { + key: "m23", + converter: webidl.converters["unrestricted double"], + defaultValue: 0, + }, + { + key: "m24", + converter: webidl.converters["unrestricted double"], + defaultValue: 0, + }, + { + key: "m31", + converter: webidl.converters["unrestricted double"], + defaultValue: 0, + }, + { + key: "m32", + converter: webidl.converters["unrestricted double"], + defaultValue: 0, + }, + { + key: "m33", + converter: webidl.converters["unrestricted double"], + defaultValue: 1, + }, + { + key: "m34", + converter: webidl.converters["unrestricted double"], + defaultValue: 0, + }, + { + key: "m43", + converter: webidl.converters["unrestricted double"], + defaultValue: 0, + }, + { + key: "m44", + converter: webidl.converters["unrestricted double"], + defaultValue: 1, + }, + { + key: "is2D", + converter: webidl.converters["boolean"], + }, + ], +); + +const _raw = Symbol("[[raw]]"); +// Property to prevent writing values when an immutable instance is changed to +// a mutable instance by Object.setPrototypeOf +// TODO(petamoriken): Implementing resistance to Object.setPrototypeOf in the WebIDL layer +const _writable = Symbol("[[writable]]"); +const _brand = webidl.brand; + +class DOMPointReadOnly { + [_writable] = false; + /** @type {Float64Array} */ + [_raw]; + + constructor(x = 0, y = 0, z = 0, w = 1) { + this[_raw] = new Float64Array([ + webidl.converters["unrestricted double"](x), + webidl.converters["unrestricted double"](y), + webidl.converters["unrestricted double"](z), + webidl.converters["unrestricted double"](w), + ]); + this[_brand] = _brand; + } + + static fromPoint(other = {}) { + other = webidl.converters.DOMPointInit( + other, + "Failed to execute 'DOMPointReadOnly.fromPoint'", + "Argument 1", + ); + const point = webidl.createBranded(DOMPointReadOnly); + point[_writable] = false; + point[_raw] = new Float64Array([ + other.x, + other.y, + other.z, + other.w, + ]); + return point; + } + + get x() { + webidl.assertBranded(this, DOMPointReadOnlyPrototype); + return this[_raw][0]; + } + get y() { + webidl.assertBranded(this, DOMPointReadOnlyPrototype); + return this[_raw][1]; + } + get z() { + webidl.assertBranded(this, DOMPointReadOnlyPrototype); + return this[_raw][2]; + } + get w() { + webidl.assertBranded(this, DOMPointReadOnlyPrototype); + return this[_raw][3]; + } + + matrixTransform(matrix = {}) { + webidl.assertBranded(this, DOMPointReadOnlyPrototype); + const prefix = "Failed to execute 'matrixTransform' on 'DOMPointReadOnly'"; + if (!ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, matrix)) { + const _matrix = webidl.converters.DOMMatrixInit( + matrix, + prefix, + "Argument 1", + ); + validateAndFixupMatrixDictionary(_matrix, prefix); + matrix = {}; + initMatrixFromDictonary(matrix, _matrix); + } + + const point = webidl.createBranded(DOMPoint); + point[_writable] = true; + point[_raw] = new Float64Array(this[_raw]); + op_geometry_premultiply_point_self(matrix[_raw], point[_raw]); + return point; + } + + toJSON() { + webidl.assertBranded(this, DOMPointReadOnlyPrototype); + const raw = this[_raw]; + return { + x: raw[0], + y: raw[1], + z: raw[2], + w: raw[3], + }; + } + + [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { + return inspect( + createFilteredInspectProxy({ + object: this, + evaluate: ObjectPrototypeIsPrototypeOf(DOMPointReadOnlyPrototype, this), + keys: [ + "x", + "y", + "z", + "w", + ], + }), + inspectOptions, + ); + } +} + +webidl.configureInterface(DOMPointReadOnly); +const DOMPointReadOnlyPrototype = DOMPointReadOnly.prototype; + +class DOMPoint extends DOMPointReadOnly { + [_writable] = true; + + static fromPoint(other = {}) { + other = webidl.converters.DOMPointInit( + other, + "Failed to execute 'DOMPoint.fromPoint'", + "Argument 1", + ); + const point = webidl.createBranded(DOMPoint); + point[_writable] = true; + point[_raw] = new Float64Array([ + other.x, + other.y, + other.z, + other.w, + ]); + return point; + } + + get x() { + webidl.assertBranded(this, DOMPointPrototype); + return this[_raw][0]; + } + set x(value) { + webidl.assertBranded(this, DOMPointPrototype); + assertWritable(this); + this[_raw][0] = webidl.converters["unrestricted double"](value); + } + get y() { + webidl.assertBranded(this, DOMPointPrototype); + return this[_raw][1]; + } + set y(value) { + webidl.assertBranded(this, DOMPointPrototype); + assertWritable(this); + this[_raw][1] = webidl.converters["unrestricted double"](value); + } + get z() { + webidl.assertBranded(this, DOMPointPrototype); + return this[_raw][2]; + } + set z(value) { + webidl.assertBranded(this, DOMPointPrototype); + assertWritable(this); + this[_raw][2] = webidl.converters["unrestricted double"](value); + } + get w() { + webidl.assertBranded(this, DOMPointPrototype); + return this[_raw][3]; + } + set w(value) { + webidl.assertBranded(this, DOMPointPrototype); + assertWritable(this); + this[_raw][3] = webidl.converters["unrestricted double"](value); + } + + [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { + return inspect( + createFilteredInspectProxy({ + object: this, + evaluate: ObjectPrototypeIsPrototypeOf(DOMPointPrototype, this), + keys: [ + "x", + "y", + "z", + "w", + ], + }), + inspectOptions, + ); + } +} + +webidl.configureInterface(DOMPoint); +const DOMPointPrototype = DOMPoint.prototype; + +class DOMRectReadOnly { + [_writable] = false; + /** @type {Float64Array} */ + [_raw]; + + constructor(x = 0, y = 0, width = 0, height = 0) { + this[_raw] = new Float64Array([ + webidl.converters["unrestricted double"](x), + webidl.converters["unrestricted double"](y), + webidl.converters["unrestricted double"](width), + webidl.converters["unrestricted double"](height), + ]); + this[_brand] = _brand; + } + + static fromRect(other = {}) { + other = webidl.converters.DOMRectInit( + other, + "Failed to execute 'DOMRectReadOnly.fromRect'", + "Argument 1", + ); + const rect = webidl.createBranded(DOMRectReadOnly); + rect[_writable] = false; + rect[_raw] = new Float64Array([ + other.x, + other.y, + other.width, + other.height, + ]); + return rect; + } + + get x() { + webidl.assertBranded(this, DOMRectReadOnlyPrototype); + return this[_raw][0]; + } + get y() { + webidl.assertBranded(this, DOMRectReadOnlyPrototype); + return this[_raw][1]; + } + get width() { + webidl.assertBranded(this, DOMRectReadOnlyPrototype); + return this[_raw][2]; + } + get height() { + webidl.assertBranded(this, DOMRectReadOnlyPrototype); + return this[_raw][3]; + } + get top() { + webidl.assertBranded(this, DOMRectReadOnlyPrototype); + const raw = this[_raw]; + return MathMin(raw[1], raw[1] + raw[3]); + } + get right() { + webidl.assertBranded(this, DOMRectReadOnlyPrototype); + const raw = this[_raw]; + return MathMax(raw[0], raw[0] + raw[2]); + } + get bottom() { + webidl.assertBranded(this, DOMRectReadOnlyPrototype); + const raw = this[_raw]; + return MathMax(raw[1], raw[1] + raw[3]); + } + get left() { + webidl.assertBranded(this, DOMRectReadOnlyPrototype); + const raw = this[_raw]; + return MathMin(raw[0], raw[0] + raw[2]); + } + + toJSON() { + webidl.assertBranded(this, DOMRectReadOnlyPrototype); + const raw = this[_raw]; + return { + x: raw[0], + y: raw[1], + width: raw[2], + height: raw[3], + top: MathMin(raw[1], raw[1] + raw[3]), + right: MathMax(raw[0], raw[0] + raw[2]), + bottom: MathMax(raw[1], raw[1] + raw[3]), + left: MathMin(raw[0], raw[0] + raw[2]), + }; + } + + [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { + return inspect( + createFilteredInspectProxy({ + object: this, + evaluate: ObjectPrototypeIsPrototypeOf(DOMRectReadOnlyPrototype, this), + keys: [ + "x", + "y", + "width", + "height", + "top", + "right", + "bottom", + "left", + ], + }), + inspectOptions, + ); + } +} + +webidl.configureInterface(DOMRectReadOnly); +const DOMRectReadOnlyPrototype = DOMRectReadOnly.prototype; + +class DOMRect extends DOMRectReadOnly { + [_writable] = true; + + static fromRect(other = {}) { + other = webidl.converters.DOMRectInit( + other, + "Failed to execute 'DOMRect.fromRect'", + "Argument 1", + ); + const rect = webidl.createBranded(DOMRect); + rect[_writable] = true; + rect[_raw] = new Float64Array([ + other.x, + other.y, + other.width, + other.height, + ]); + return rect; + } + + get x() { + webidl.assertBranded(this, DOMRectPrototype); + return this[_raw][0]; + } + set x(value) { + webidl.assertBranded(this, DOMRectPrototype); + assertWritable(this); + this[_raw][0] = webidl.converters["unrestricted double"](value); + } + get y() { + webidl.assertBranded(this, DOMRectPrototype); + return this[_raw][1]; + } + set y(value) { + webidl.assertBranded(this, DOMRectPrototype); + assertWritable(this); + this[_raw][1] = webidl.converters["unrestricted double"](value); + } + get width() { + webidl.assertBranded(this, DOMRectPrototype); + return this[_raw][2]; + } + set width(value) { + webidl.assertBranded(this, DOMRectPrototype); + assertWritable(this); + this[_raw][2] = webidl.converters["unrestricted double"](value); + } + get height() { + webidl.assertBranded(this, DOMRectPrototype); + return this[_raw][3]; + } + set height(value) { + webidl.assertBranded(this, DOMRectPrototype); + assertWritable(this); + this[_raw][3] = webidl.converters["unrestricted double"](value); + } + + [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { + return inspect( + createFilteredInspectProxy({ + object: this, + evaluate: ObjectPrototypeIsPrototypeOf(DOMRectPrototype, this), + keys: [ + "x", + "y", + "width", + "height", + "top", + "right", + "bottom", + "left", + ], + }), + inspectOptions, + ); + } +} + +webidl.configureInterface(DOMRect); +const DOMRectPrototype = DOMRect.prototype; + +const _p1 = Symbol("[[p1]]"); +const _p2 = Symbol("[[p2]]"); +const _p3 = Symbol("[[p3]]"); +const _p4 = Symbol("[[p4]]"); + +class DOMQuad { + /** @type {DOMPoint} */ + [_p1]; + /** @type {DOMPoint} */ + [_p2]; + /** @type {DOMPoint} */ + [_p3]; + /** @type {DOMPoint} */ + [_p4]; + + constructor(p1 = {}, p2 = {}, p3 = {}, p4 = {}) { + this[_p1] = DOMPoint.fromPoint(p1); + this[_p2] = DOMPoint.fromPoint(p2); + this[_p3] = DOMPoint.fromPoint(p3); + this[_p4] = DOMPoint.fromPoint(p4); + this[_brand] = _brand; + } + + static fromRect(other = {}) { + other = webidl.converters.DOMRectInit( + other, + "Failed to execute 'DOMQuad.fromRect'", + "Argument 1", + ); + const { x, y, width, height } = other; + const quad = webidl.createBranded(DOMQuad); + quad[_p1] = new DOMPoint(x, y, 0, 1); + quad[_p2] = new DOMPoint(x + width, y, 0, 1); + quad[_p3] = new DOMPoint(x + width, y + height, 0, 1); + quad[_p4] = new DOMPoint(x, y + height, 0, 1); + return quad; + } + + static fromQuad(other = {}) { + other = webidl.converters.DOMQuadInit( + other, + "Failed to execute 'DOMQuad.fromQuad'", + "Argument 1", + ); + const quad = webidl.createBranded(DOMQuad); + quad[_p1] = DOMPoint.fromPoint(other.p1); + quad[_p2] = DOMPoint.fromPoint(other.p2); + quad[_p3] = DOMPoint.fromPoint(other.p3); + quad[_p4] = DOMPoint.fromPoint(other.p4); + return quad; + } + + get p1() { + webidl.assertBranded(this, DOMQuadPrototype); + return this[_p1]; + } + get p2() { + webidl.assertBranded(this, DOMQuadPrototype); + return this[_p2]; + } + get p3() { + webidl.assertBranded(this, DOMQuadPrototype); + return this[_p3]; + } + get p4() { + webidl.assertBranded(this, DOMQuadPrototype); + return this[_p4]; + } + + getBounds() { + webidl.assertBranded(this, DOMQuadPrototype); + const { x: p1x, y: p1y } = this[_p1]; + const { x: p2x, y: p2y } = this[_p2]; + const { x: p3x, y: p3y } = this[_p3]; + const { x: p4x, y: p4y } = this[_p4]; + + const left = MathMin(p1x, p2x, p3x, p4x); + const top = MathMin(p1y, p2y, p3y, p4y); + const right = MathMax(p1x, p2x, p3x, p4x); + const bottom = MathMax(p1y, p2y, p3y, p4y); + + const bounds = webidl.createBranded(DOMRect); + bounds[_writable] = true; + bounds[_raw] = new Float64Array([ + left, + top, + right - left, + bottom - top, + ]); + return bounds; + } + + toJSON() { + webidl.assertBranded(this, DOMQuadPrototype); + return { + p1: this[_p1], + p2: this[_p2], + p3: this[_p3], + p4: this[_p4], + }; + } + + [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { + return inspect( + createFilteredInspectProxy({ + object: this, + evaluate: ObjectPrototypeIsPrototypeOf(DOMQuadPrototype, this), + keys: [ + "p1", + "p2", + "p3", + "p4", + ], + }), + inspectOptions, + ); + } +} + +webidl.configureInterface(DOMQuad); +const DOMQuadPrototype = DOMQuad.prototype; + +/* + * NOTE: column-major order + * + * For a 2D 3x2 matrix, the index of properties in + * | a c 0 e | | 0 4 _ 12 | + * | b d 0 f | | 1 5 _ 13 | + * | 0 0 1 0 | is | _ _ _ _ | + * | 0 0 0 1 | | _ _ _ _ | + */ +const INDEX_A = 0; +const INDEX_B = 1; +const INDEX_C = 4; +const INDEX_D = 5; +const INDEX_E = 12; +const INDEX_F = 13; + +/* + * NOTE: column-major order + * + * The index of properties in + * | m11 m21 m31 m41 | | 0 4 8 12 | + * | m12 m22 m32 m42 | | 1 5 9 13 | + * | m13 m23 m33 m43 | is | 2 6 10 14 | + * | m14 m24 m34 m44 | | 3 7 11 15 | + */ +const INDEX_M11 = 0; +const INDEX_M12 = 1; +const INDEX_M13 = 2; +const INDEX_M14 = 3; +const INDEX_M21 = 4; +const INDEX_M22 = 5; +const INDEX_M23 = 6; +const INDEX_M24 = 7; +const INDEX_M31 = 8; +const INDEX_M32 = 9; +const INDEX_M33 = 10; +const INDEX_M34 = 11; +const INDEX_M41 = 12; +const INDEX_M42 = 13; +const INDEX_M43 = 14; +const INDEX_M44 = 15; + +const _is2D = Symbol("[[is2D]]"); + +class DOMMatrixReadOnly { + [_writable] = false; + /** @type {Float64Array} */ + [_raw]; + /** @type {boolean} */ + [_is2D]; + + constructor(init = undefined) { + const prefix = `Failed to construct '${this.constructor.name}'`; + this[_brand] = _brand; + if (init === undefined) { + // deno-fmt-ignore + this[_raw] = new Float64Array([ + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1, + ]); + this[_is2D] = true; + } else if ( + webidl.type(init) === "Object" && init[SymbolIterator] !== undefined + ) { + init = webidl.converters["sequence"]( + init, + prefix, + "Argument 1", + ); + initMatrixFromSequence(this, init, prefix); + } else { + init = webidl.converters.DOMString( + init, + prefix, + "Argument 1", + ); + const { matrix, is2D } = parseTransformList(init, prefix); + this[_raw] = matrix; + this[_is2D] = is2D; + } + } + + static fromMatrix(other = {}) { + const prefix = "Failed to execute 'DOMMatrixReadOnly.fromMatrix'"; + const matrix = webidl.createBranded(DOMMatrixReadOnly); + matrix[_writable] = false; + // fast path for DOMMatrix or DOMMatrixReadOnly + if (ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other)) { + initMatrixFromMatrix(matrix, other); + } else { + other = webidl.converters.DOMMatrixInit(other, prefix, "Argument 1"); + validateAndFixupMatrixDictionary(other, prefix); + initMatrixFromDictonary(matrix, other); + } + return matrix; + } + + static fromFloat32Array(float32) { + const prefix = "Failed to execute 'DOMMatrixReadOnly.fromFloat32Array'"; + webidl.requiredArguments(arguments.length, 1, prefix); + float32 = webidl.converters.Float32Array(float32, prefix, "Argument 1"); + const matrix = webidl.createBranded(DOMMatrixReadOnly); + matrix[_writable] = false; + initMatrixFromSequence(matrix, float32, prefix); + return matrix; + } + + static fromFloat64Array(float64) { + const prefix = "Failed to execute 'DOMMatrixReadOnly.fromFloat64Array'"; + webidl.requiredArguments(arguments.length, 1, prefix); + float64 = webidl.converters.Float64Array(float64, prefix, "Argument 1"); + const matrix = webidl.createBranded(DOMMatrixReadOnly); + matrix[_writable] = false; + initMatrixFromSequence(matrix, float64, prefix); + return matrix; + } + + get a() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][INDEX_A]; + } + get b() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][INDEX_B]; + } + get c() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][INDEX_C]; + } + get d() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][INDEX_D]; + } + get e() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][INDEX_E]; + } + get f() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][INDEX_F]; + } + get m11() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][INDEX_M11]; + } + get m12() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][INDEX_M12]; + } + get m13() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][INDEX_M13]; + } + get m14() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][INDEX_M14]; + } + get m21() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][INDEX_M21]; + } + get m22() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][INDEX_M22]; + } + get m23() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][INDEX_M23]; + } + get m24() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][INDEX_M24]; + } + get m31() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][INDEX_M31]; + } + get m32() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][INDEX_M32]; + } + get m33() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][INDEX_M33]; + } + get m34() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][INDEX_M34]; + } + get m41() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][INDEX_M41]; + } + get m42() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][INDEX_M42]; + } + get m43() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][INDEX_M43]; + } + get m44() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_raw][INDEX_M44]; + } + get is2D() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return this[_is2D]; + } + get isIdentity() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return isIdentityMatrix(this); + } + + translate(tx = 0, ty = 0, tz = 0) { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + tx = webidl.converters["unrestricted double"](tx); + ty = webidl.converters["unrestricted double"](ty); + tz = webidl.converters["unrestricted double"](tz); + const matrix = webidl.createBranded(DOMMatrix); + matrix[_writable] = true; + matrix[_raw] = new Float64Array(this[_raw]); + op_geometry_translate_self( + tx, + ty, + tz, + matrix[_raw], + ); + matrix[_is2D] = this[_is2D] && tz === 0; + return matrix; + } + + scale( + scaleX = 1, + scaleY = scaleX, + scaleZ = 1, + originX = 0, + originY = 0, + originZ = 0, + ) { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + scaleX = webidl.converters["unrestricted double"](scaleX); + scaleY = webidl.converters["unrestricted double"](scaleY); + scaleZ = webidl.converters["unrestricted double"](scaleZ); + originX = webidl.converters["unrestricted double"](originX); + originY = webidl.converters["unrestricted double"](originY); + originZ = webidl.converters["unrestricted double"](originZ); + const matrix = webidl.createBranded(DOMMatrix); + matrix[_writable] = true; + matrix[_raw] = new Float64Array(this[_raw]); + if (originX === 0 && originY === 0 && originZ === 0) { + op_geometry_scale_self( + scaleX, + scaleY, + scaleZ, + matrix[_raw], + ); + } else { + op_geometry_scale_with_origin_self( + scaleX, + scaleY, + scaleZ, + originX, + originY, + originZ, + matrix[_raw], + ); + } + matrix[_is2D] = this[_is2D] && scaleZ === 1 && originZ === 0; + return matrix; + } + + scaleNonUniform(scaleX = 1, scaleY = 1) { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + scaleX = webidl.converters["unrestricted double"](scaleX); + scaleY = webidl.converters["unrestricted double"](scaleY); + const matrix = webidl.createBranded(DOMMatrix); + matrix[_writable] = true; + matrix[_raw] = new Float64Array(this[_raw]); + op_geometry_scale_self( + scaleX, + scaleY, + 1, + matrix[_raw], + ); + matrix[_is2D] = this[_is2D]; + return matrix; + } + + scale3d(scale = 1, originX = 0, originY = 0, originZ = 0) { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + scale = webidl.converters["unrestricted double"](scale); + originX = webidl.converters["unrestricted double"](originX); + originY = webidl.converters["unrestricted double"](originY); + originZ = webidl.converters["unrestricted double"](originZ); + const matrix = webidl.createBranded(DOMMatrix); + matrix[_writable] = true; + matrix[_raw] = new Float64Array(this[_raw]); + if (originX === 0 && originY === 0 && originZ === 0) { + op_geometry_scale_self( + scale, + scale, + scale, + matrix[_raw], + ); + } else { + op_geometry_scale_with_origin_self( + scale, + scale, + scale, + originX, + originY, + originZ, + matrix[_raw], + ); + } + matrix[_is2D] = this[_is2D] && scale === 1 && originZ === 0; + return matrix; + } + + rotate(rotX = 0, rotY, rotZ) { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + rotX = webidl.converters["unrestricted double"](rotX); + if (rotY === undefined && rotZ === undefined) { + rotZ = rotX; + rotX = 0; + rotY = 0; + } else { + rotY = rotY !== undefined + ? webidl.converters["unrestricted double"](rotY) + : 0; + rotZ = rotZ !== undefined + ? webidl.converters["unrestricted double"](rotZ) + : 0; + } + const matrix = webidl.createBranded(DOMMatrix); + matrix[_writable] = true; + matrix[_raw] = new Float64Array(this[_raw]); + op_geometry_rotate_self( + rotX, + rotY, + rotZ, + matrix[_raw], + ); + matrix[_is2D] = this[_is2D] && rotX === 0 && rotY === 0; + return matrix; + } + + rotateFromVector(x = 0, y = 0) { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + x = webidl.converters["unrestricted double"](x); + y = webidl.converters["unrestricted double"](y); + const matrix = webidl.createBranded(DOMMatrix); + matrix[_writable] = true; + matrix[_raw] = new Float64Array(this[_raw]); + op_geometry_rotate_from_vector_self( + x, + y, + matrix[_raw], + ); + matrix[_is2D] = this[_is2D]; + return matrix; + } + + rotateAxisAngle(x = 0, y = 0, z = 0, angle = 0) { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + x = webidl.converters["unrestricted double"](x); + y = webidl.converters["unrestricted double"](y); + z = webidl.converters["unrestricted double"](z); + angle = webidl.converters["unrestricted double"](angle); + const matrix = webidl.createBranded(DOMMatrix); + matrix[_writable] = true; + matrix[_raw] = new Float64Array(this[_raw]); + if (x !== 0 || y !== 0 || z !== 0) { + op_geometry_rotate_axis_angle_self( + x, + y, + z, + angle, + matrix[_raw], + ); + } + matrix[_is2D] = this[_is2D] && x === 0 && y === 0; + return matrix; + } + + skewX(sx = 0) { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + sx = webidl.converters["unrestricted double"](sx); + const matrix = webidl.createBranded(DOMMatrix); + matrix[_writable] = true; + matrix[_raw] = new Float64Array(this[_raw]); + op_geometry_skew_self( + sx, + 0, + matrix[_raw], + ); + matrix[_is2D] = this[_is2D]; + return matrix; + } + + skewY(sy = 0) { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + sy = webidl.converters["unrestricted double"](sy); + const matrix = webidl.createBranded(DOMMatrix); + matrix[_writable] = true; + matrix[_raw] = new Float64Array(this[_raw]); + op_geometry_skew_self( + 0, + sy, + matrix[_raw], + ); + matrix[_is2D] = this[_is2D]; + return matrix; + } + + multiply(other = {}) { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + const prefix = "Failed to execute 'multiply' on 'DOMMatrixReadOnly'"; + if (!ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other)) { + const _other = webidl.converters.DOMMatrixInit( + other, + prefix, + "Argument 1", + ); + validateAndFixupMatrixDictionary(_other, prefix); + other = {}; + initMatrixFromDictonary(other, _other); + } + const matrix = webidl.createBranded(DOMMatrix); + matrix[_writable] = true; + matrix[_raw] = new Float64Array(16); + op_geometry_multiply(this[_raw], other[_raw], matrix[_raw]); + matrix[_is2D] = this[_is2D] && other[_is2D]; + return matrix; + } + + flipX() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + const matrix = webidl.createBranded(DOMMatrix); + matrix[_writable] = true; + matrix[_raw] = new Float64Array(this[_raw]); + op_geometry_flip_x_self(matrix[_raw]); + matrix[_is2D] = this[_is2D]; + return matrix; + } + + flipY() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + const matrix = webidl.createBranded(DOMMatrix); + matrix[_writable] = true; + matrix[_raw] = new Float64Array(this[_raw]); + op_geometry_flip_y_self(matrix[_raw]); + matrix[_is2D] = this[_is2D]; + return matrix; + } + + inverse() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + const matrix = webidl.createBranded(DOMMatrix); + matrix[_writable] = true; + matrix[_raw] = new Float64Array(this[_raw]); + let invertible; + if (this[_is2D]) { + invertible = op_geometry_invert_2d_self(matrix[_raw]); + } else { + invertible = op_geometry_invert_self(matrix[_raw]); + } + matrix[_is2D] = this[_is2D] && invertible; + return matrix; + } + + transformPoint(point = {}) { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + point = webidl.converters.DOMPointInit( + point, + "Failed to execute 'transformPoint' on 'DOMMatrixReadOnly'", + "Argument 1", + ); + const result = webidl.createBranded(DOMPoint); + result[_writable] = true; + result[_raw] = new Float64Array([ + point.x, + point.y, + point.z, + point.w, + ]); + op_geometry_premultiply_point_self(this[_raw], result[_raw]); + return result; + } + + toFloat32Array() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return new Float32Array(this[_raw]); + } + + toFloat64Array() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + return new Float64Array(this[_raw]); + } + + toJSON() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + const raw = this[_raw]; + return { + a: raw[INDEX_A], + b: raw[INDEX_B], + c: raw[INDEX_C], + d: raw[INDEX_D], + e: raw[INDEX_E], + f: raw[INDEX_F], + m11: raw[INDEX_M11], + m12: raw[INDEX_M12], + m13: raw[INDEX_M13], + m14: raw[INDEX_M14], + m21: raw[INDEX_M21], + m22: raw[INDEX_M22], + m23: raw[INDEX_M23], + m24: raw[INDEX_M24], + m31: raw[INDEX_M31], + m32: raw[INDEX_M32], + m33: raw[INDEX_M33], + m34: raw[INDEX_M34], + m41: raw[INDEX_M41], + m42: raw[INDEX_M42], + m43: raw[INDEX_M43], + m44: raw[INDEX_M44], + is2D: this[_is2D], + isIdentity: isIdentityMatrix(this), + }; + } + + [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { + return inspect( + createFilteredInspectProxy({ + object: this, + evaluate: ObjectPrototypeIsPrototypeOf( + DOMMatrixReadOnlyPrototype, + this, + ), + keys: [ + "a", + "b", + "c", + "d", + "e", + "f", + "m11", + "m12", + "m13", + "m14", + "m21", + "m22", + "m23", + "m24", + "m31", + "m32", + "m33", + "m34", + "m41", + "m42", + "m43", + "m44", + "is2D", + "isIdentity", + ], + }), + inspectOptions, + ); + } +} + +webidl.configureInterface(DOMMatrixReadOnly); +const DOMMatrixReadOnlyPrototype = DOMMatrixReadOnly.prototype; + +class DOMMatrix extends DOMMatrixReadOnly { + [_writable] = true; + + static fromMatrix(other = {}) { + const prefix = "Failed to execute 'DOMMatrix.fromMatrix'"; + const matrix = webidl.createBranded(DOMMatrix); + matrix[_writable] = true; + // fast path for DOMMatrix or DOMMatrixReadOnly + if (ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other)) { + initMatrixFromMatrix(matrix, other); + } else { + other = webidl.converters.DOMMatrixInit(other, prefix, "Argument 1"); + validateAndFixupMatrixDictionary(other, prefix); + initMatrixFromDictonary(matrix, other); + } + return matrix; + } + + static fromFloat32Array(float32) { + const prefix = "Failed to execute 'DOMMatrix.fromFloat32Array'"; + webidl.requiredArguments(arguments.length, 1, prefix); + float32 = webidl.converters.Float32Array(float32, prefix, "Argument 1"); + const matrix = webidl.createBranded(DOMMatrix); + matrix[_writable] = true; + initMatrixFromSequence(matrix, float32, prefix); + return matrix; + } + + static fromFloat64Array(float64) { + const prefix = "Failed to execute 'DOMMatrix.fromFloat64Array'"; + webidl.requiredArguments(arguments.length, 1, prefix); + float64 = webidl.converters.Float64Array(float64, prefix, "Argument 1"); + const matrix = webidl.createBranded(DOMMatrix); + matrix[_writable] = true; + initMatrixFromSequence(matrix, float64, prefix); + return matrix; + } + + get a() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][INDEX_A]; + } + set a(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + this[_raw][INDEX_A] = webidl.converters["unrestricted double"](value); + } + get b() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][INDEX_B]; + } + set b(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + this[_raw][INDEX_B] = webidl.converters["unrestricted double"](value); + } + get c() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][INDEX_C]; + } + set c(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + this[_raw][INDEX_C] = webidl.converters["unrestricted double"](value); + } + get d() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][INDEX_D]; + } + set d(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + this[_raw][INDEX_D] = webidl.converters["unrestricted double"](value); + } + get e() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][INDEX_E]; + } + set e(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + this[_raw][INDEX_E] = webidl.converters["unrestricted double"](value); + } + get f() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][INDEX_F]; + } + set f(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + this[_raw][INDEX_F] = webidl.converters["unrestricted double"](value); + } + get m11() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][INDEX_M11]; + } + set m11(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + this[_raw][INDEX_M11] = webidl.converters["unrestricted double"](value); + } + get m12() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][INDEX_M12]; + } + set m12(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + this[_raw][INDEX_M12] = webidl.converters["unrestricted double"](value); + } + get m13() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][INDEX_M13]; + } + set m13(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + if (value !== 0) { + this[_is2D] = false; + } + this[_raw][INDEX_M13] = webidl.converters["unrestricted double"](value); + } + get m14() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][INDEX_M14]; + } + set m14(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + if (value !== 0) { + this[_is2D] = false; + } + this[_raw][INDEX_M14] = webidl.converters["unrestricted double"](value); + } + get m21() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][INDEX_M21]; + } + set m21(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + this[_raw][INDEX_M21] = webidl.converters["unrestricted double"](value); + } + get m22() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][INDEX_M22]; + } + set m22(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + this[_raw][INDEX_M22] = webidl.converters["unrestricted double"](value); + } + get m23() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][INDEX_M23]; + } + set m23(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + if (value !== 0) { + this[_is2D] = false; + } + this[_raw][INDEX_M23] = webidl.converters["unrestricted double"](value); + } + get m24() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][INDEX_M24]; + } + set m24(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + if (value !== 0) { + this[_is2D] = false; + } + this[_raw][INDEX_M24] = webidl.converters["unrestricted double"](value); + } + get m31() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][INDEX_M31]; + } + set m31(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + if (value !== 0) { + this[_is2D] = false; + } + this[_raw][INDEX_M31] = webidl.converters["unrestricted double"](value); + } + get m32() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][INDEX_M32]; + } + set m32(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + if (value !== 0) { + this[_is2D] = false; + } + this[_raw][INDEX_M32] = webidl.converters["unrestricted double"](value); + } + get m33() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][INDEX_M33]; + } + set m33(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + if (value !== 1) { + this[_is2D] = false; + } + this[_raw][INDEX_M33] = webidl.converters["unrestricted double"](value); + } + get m34() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][INDEX_M34]; + } + set m34(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + if (value !== 0) { + this[_is2D] = false; + } + this[_raw][INDEX_M34] = webidl.converters["unrestricted double"](value); + } + get m41() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][INDEX_M41]; + } + set m41(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + this[_raw][INDEX_M41] = webidl.converters["unrestricted double"](value); + } + get m42() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][INDEX_M42]; + } + set m42(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + this[_raw][INDEX_M42] = webidl.converters["unrestricted double"](value); + } + get m43() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][INDEX_M43]; + } + set m43(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + if (value !== 0) { + this[_is2D] = false; + } + this[_raw][INDEX_M43] = webidl.converters["unrestricted double"](value); + } + get m44() { + webidl.assertBranded(this, DOMMatrixPrototype); + return this[_raw][INDEX_M44]; + } + set m44(value) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + if (value !== 1) { + this[_is2D] = false; + } + this[_raw][INDEX_M44] = webidl.converters["unrestricted double"](value); + } + + multiplySelf(other = {}) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + const prefix = "Failed to execute 'multiplySelf' on 'DOMMatrix'"; + if (!ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other)) { + const _other = webidl.converters.DOMMatrixInit( + other, + prefix, + "Argument 1", + ); + validateAndFixupMatrixDictionary(_other, prefix); + other = {}; + initMatrixFromDictonary(other, _other); + } else if (this[_raw] === other[_raw]) { + other = {}; + initMatrixFromMatrix(other, this); + } + + op_geometry_multiply_self(other[_raw], this[_raw]); + this[_is2D] &&= other[_is2D]; + return this; + } + + preMultiplySelf(other = {}) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + const prefix = "Failed to execute 'premultiplySelf' on 'DOMMatrix'"; + if (!ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other)) { + const _other = webidl.converters.DOMMatrixInit( + other, + prefix, + "Argument 1", + ); + validateAndFixupMatrixDictionary(_other, prefix); + other = {}; + initMatrixFromDictonary(other, _other); + } else if (this[_raw] === other[_raw]) { + other = {}; + initMatrixFromMatrix(other, this); + } + + op_geometry_premultiply_self(other[_raw], this[_raw]); + this[_is2D] &&= other[_is2D]; + return this; + } + + translateSelf(tx = 0, ty = 0, tz = 0) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + tx = webidl.converters["unrestricted double"](tx); + ty = webidl.converters["unrestricted double"](ty); + tz = webidl.converters["unrestricted double"](tz); + op_geometry_translate_self( + tx, + ty, + tz, + this[_raw], + ); + this[_is2D] &&= tz === 0; + return this; + } + + scaleSelf( + scaleX = 1, + scaleY = scaleX, + scaleZ = 1, + originX = 0, + originY = 0, + originZ = 0, + ) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + scaleX = webidl.converters["unrestricted double"](scaleX); + scaleY = webidl.converters["unrestricted double"](scaleY); + scaleZ = webidl.converters["unrestricted double"](scaleZ); + originX = webidl.converters["unrestricted double"](originX); + originY = webidl.converters["unrestricted double"](originY); + originZ = webidl.converters["unrestricted double"](originZ); + if (originX === 0 && originY === 0 && originZ === 0) { + op_geometry_scale_self( + scaleX, + scaleY, + scaleZ, + this[_raw], + ); + } else { + op_geometry_scale_with_origin_self( + scaleX, + scaleY, + scaleZ, + originX, + originY, + originZ, + this[_raw], + ); + } + this[_is2D] &&= scaleZ === 1 && originZ === 0; + return this; + } + + scale3dSelf(scale = 1, originX = 0, originY = 0, originZ = 0) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + scale = webidl.converters["unrestricted double"](scale); + originX = webidl.converters["unrestricted double"](originX); + originY = webidl.converters["unrestricted double"](originY); + originZ = webidl.converters["unrestricted double"](originZ); + if (originX === 0 && originY === 0 && originZ === 0) { + op_geometry_scale_self( + scale, + scale, + scale, + this[_raw], + ); + } else { + op_geometry_scale_with_origin_self( + scale, + scale, + scale, + originX, + originY, + originZ, + this[_raw], + ); + } + this[_is2D] &&= scale === 1 && originZ === 0; + return this; + } + + rotateSelf(rotX = 0, rotY, rotZ) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + rotX = webidl.converters["unrestricted double"](rotX); + if (rotY === undefined && rotZ === undefined) { + rotZ = rotX; + rotX = 0; + rotY = 0; + } else { + rotY = rotY !== undefined + ? webidl.converters["unrestricted double"](rotY) + : 0; + rotZ = rotZ !== undefined + ? webidl.converters["unrestricted double"](rotZ) + : 0; + } + op_geometry_rotate_self( + rotX, + rotY, + rotZ, + this[_raw], + ); + this[_is2D] &&= rotX === 0 && rotY === 0; + return this; + } + + rotateFromVectorSelf(x = 0, y = 0) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + x = webidl.converters["unrestricted double"](x); + y = webidl.converters["unrestricted double"](y); + op_geometry_rotate_from_vector_self( + x, + y, + this[_raw], + ); + return this; + } + + rotateAxisAngleSelf(x = 0, y = 0, z = 0, angle = 0) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + x = webidl.converters["unrestricted double"](x); + y = webidl.converters["unrestricted double"](y); + z = webidl.converters["unrestricted double"](z); + angle = webidl.converters["unrestricted double"](angle); + if (x !== 0 || y !== 0 || z !== 0) { + op_geometry_rotate_axis_angle_self( + x, + y, + z, + angle, + this[_raw], + ); + } + this[_is2D] &&= x === 0 && y === 0; + return this; + } + + skewXSelf(sx = 0) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + sx = webidl.converters["unrestricted double"](sx); + op_geometry_skew_self( + sx, + 0, + this[_raw], + ); + return this; + } + + skewYSelf(sy = 0) { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + sy = webidl.converters["unrestricted double"](sy); + op_geometry_skew_self( + 0, + sy, + this[_raw], + ); + return this; + } + + invertSelf() { + webidl.assertBranded(this, DOMMatrixPrototype); + assertWritable(this); + let invertible; + if (this[_is2D]) { + invertible = op_geometry_invert_2d_self(this[_raw]); + } else { + invertible = op_geometry_invert_self(this[_raw]); + } + this[_is2D] &&= invertible; + return this; + } + + [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { + return inspect( + createFilteredInspectProxy({ + object: this, + evaluate: ObjectPrototypeIsPrototypeOf(DOMMatrixPrototype, this), + keys: [ + "a", + "b", + "c", + "d", + "e", + "f", + "m11", + "m12", + "m13", + "m14", + "m21", + "m22", + "m23", + "m24", + "m31", + "m32", + "m33", + "m34", + "m41", + "m42", + "m43", + "m44", + "is2D", + "isIdentity", + ], + }), + inspectOptions, + ); + } +} + +webidl.configureInterface(DOMMatrix); +const DOMMatrixPrototype = DOMMatrix.prototype; + +/** + * TODO(petamoriken): Support this by updating WebIDL's brand features + * @param {DOMRect | DOMPoint | DOMMatrix} self + */ +function assertWritable(self) { + if (self[_writable] !== true) { + throw new TypeError("Illegal invocation"); + } +} + +/** + * https://tc39.es/ecma262/#sec-samevaluezero + * @param {number} x + * @param {number} y + */ +function sameValueZero(x, y) { + return x === y || ObjectIs(x, y); +} + +/** + * https://drafts.fxtf.org/geometry/#matrix-validate-and-fixup-2d + * @param {object} dict + * @param {string} prefix + */ +function validateAndFixup2DMatrixDictionary(dict, prefix) { + if ( + ( + dict.a !== undefined && dict.m11 !== undefined && + !sameValueZero(dict.a, dict.m11) + ) || + ( + dict.b !== undefined && dict.m12 !== undefined && + !sameValueZero(dict.b, dict.m12) + ) || + ( + dict.c !== undefined && dict.m21 !== undefined && + !sameValueZero(dict.c, dict.m21) + ) || + ( + dict.d !== undefined && dict.m22 !== undefined && + !sameValueZero(dict.d, dict.m22) + ) || + ( + dict.e !== undefined && dict.m41 !== undefined && + !sameValueZero(dict.e, dict.m41) + ) || + ( + dict.f !== undefined && dict.m42 !== undefined && + !sameValueZero(dict.f, dict.m42) + ) + ) { + throw new TypeError(`${prefix}: Inconsistent 2d matrix value`); + } + if (dict.m11 === undefined) dict.m11 = dict.a ?? 1; + if (dict.m12 === undefined) dict.m12 = dict.b ?? 0; + if (dict.m21 === undefined) dict.m21 = dict.c ?? 0; + if (dict.m22 === undefined) dict.m22 = dict.d ?? 1; + if (dict.m41 === undefined) dict.m41 = dict.e ?? 0; + if (dict.m42 === undefined) dict.m42 = dict.f ?? 0; +} + +/** + * https://drafts.fxtf.org/geometry/#matrix-validate-and-fixup + * @param {object} dict + * @param {string} prefix + */ +function validateAndFixupMatrixDictionary(dict, prefix) { + validateAndFixup2DMatrixDictionary(dict, prefix); + const is2DCanBeTrue = dict.m13 === 0 && + dict.m14 === 0 && + dict.m23 === 0 && + dict.m24 === 0 && + dict.m31 === 0 && + dict.m32 === 0 && + dict.m33 === 1 && + dict.m34 === 0 && + dict.m43 === 0 && + dict.m44 === 1; + if (dict.is2D === true && !is2DCanBeTrue) { + throw new TypeError( + `${prefix}: is2D property is true but the input matrix is a 3d matrix`, + ); + } + if (dict.is2D === undefined) { + dict.is2D = is2DCanBeTrue; + } +} + +/** + * @param {object} target + * @param {number[] | Float32Array | Float64Array} seq + * @param {string} prefix + */ +function initMatrixFromSequence(target, seq, prefix) { + if (seq.length === 6) { + const { 0: a, 1: b, 2: c, 3: d, 4: e, 5: f } = seq; + // deno-fmt-ignore + target[_raw] = new Float64Array([ + a, b, 0, 0, + c, d, 0, 0, + 0, 0, 1, 0, + e, f, 0, 1, + ]); + target[_is2D] = true; + } else if (seq.length === 16) { + target[_raw] = new Float64Array(seq); + target[_is2D] = false; + } else { + throw new TypeError( + `${prefix}: The sequence must contain 6 elements for a 2D matrix or 16 elements for a 3D matrix`, + ); + } +} + +/** + * @param {object} target + * @param {object} dict + */ +function initMatrixFromDictonary(target, dict) { + if (dict.is2D) { + const { m11, m12, m21, m22, m41, m42 } = dict; + // deno-fmt-ignore + target[_raw] = new Float64Array([ + m11, m12, 0, 0, + m21, m22, 0, 0, + 0, 0, 1, 0, + m41, m42, 0, 1, + ]); + target[_is2D] = true; + } else { + const { + m11, + m12, + m13, + m14, + m21, + m22, + m23, + m24, + m31, + m32, + m33, + m34, + m41, + m42, + m43, + m44, + } = dict; + // deno-fmt-ignore + target[_raw] = new Float64Array([ + m11, m12, m13, m14, + m21, m22, m23, m24, + m31, m32, m33, m34, + m41, m42, m43, m44, + ]); + target[_is2D] = false; + } +} + +/** + * @param {object} target + * @type {DOMMatrixReadOnly} matrix + */ +function initMatrixFromMatrix(target, matrix) { + target[_raw] = new Float64Array(matrix[_raw]); + target[_is2D] = matrix[_is2D]; +} + +/** + * https://drafts.fxtf.org/geometry/#dom-dommatrixreadonly-isidentity + * @param {DOMMatrixReadOnly} matrix + */ +function isIdentityMatrix(matrix) { + const raw = matrix[_raw]; + return ( + raw[INDEX_M11] === 1 && + raw[INDEX_M12] === 0 && + raw[INDEX_M13] === 0 && + raw[INDEX_M14] === 0 && + raw[INDEX_M21] === 0 && + raw[INDEX_M22] === 1 && + raw[INDEX_M23] === 0 && + raw[INDEX_M24] === 0 && + raw[INDEX_M31] === 0 && + raw[INDEX_M32] === 0 && + raw[INDEX_M33] === 1 && + raw[INDEX_M34] === 0 && + raw[INDEX_M41] === 0 && + raw[INDEX_M42] === 0 && + raw[INDEX_M43] === 0 && + raw[INDEX_M44] === 1 + ); +} + +/** + * CSS parser + * @type {((transformList: string, prefix: string) => { matrix: Float64Array, is2D: boolean })} + */ +let parseTransformList; + +/** + * @param {(transformList: string, prefix: string) => { matrix: Float64Array, is2D: boolean }} transformListParser + * @param {boolean} enableWindowFeatures + */ +function init(transformListParser, enableWindowFeatures) { + parseTransformList = transformListParser; + + if (enableWindowFeatures) { + // https://drafts.fxtf.org/geometry/#dommatrixreadonly-stringification-behavior + ObjectDefineProperty(DOMMatrixReadOnlyPrototype, "toString", { + value: function toString() { + webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + const raw = this[_raw]; + if (!TypedArrayPrototypeEvery(raw, (value) => NumberIsFinite(value))) { + throw new DOMException( + "Failed to execute 'toString' on 'DOMMatrixReadOnly': Cannot be serialized with NaN or Infinity values", + "InvalidStateError", + ); + } + if (this[_is2D]) { + return `matrix(${ + ArrayPrototypeJoin([ + raw[INDEX_A], + raw[INDEX_B], + raw[INDEX_C], + raw[INDEX_D], + raw[INDEX_E], + raw[INDEX_F], + ], ", ") + })`; + } else { + return `matrix3d(${TypedArrayPrototypeJoin(raw, ", ")})`; + } + }, + writable: true, + enumerable: true, + configurable: true, + }); + + // https://drafts.fxtf.org/geometry/#dom-dommatrix-setmatrixvalue + ObjectDefineProperty(DOMMatrixPrototype, "setMatrixValue", { + value: function setMatrixValue(transformList) { + webidl.assertBranded(this, DOMMatrixPrototype); + const prefix = "Failed to execute 'setMatrixValue' on 'DOMMatrix'"; + webidl.requiredArguments(arguments.length, 1, prefix); + transformList = webidl.converters.DOMString( + transformList, + prefix, + "Argument 1", + ); + const { matrix, is2D } = parseTransformList(transformList, prefix); + this[_raw] = matrix; + this[_is2D] = is2D; + }, + writable: true, + enumerable: true, + configurable: true, + }); + } +} + +export { + DOMMatrix, + DOMMatrixPrototype, + DOMMatrixReadOnly, + DOMMatrixReadOnlyPrototype, + DOMPoint, + DOMPointPrototype, + DOMPointReadOnly, + DOMPointReadOnlyPrototype, + DOMQuad, + DOMQuadPrototype, + DOMRect, + DOMRectPrototype, + DOMRectReadOnly, + DOMRectReadOnlyPrototype, + init, +}; diff --git a/ext/geometry/Cargo.toml b/ext/geometry/Cargo.toml new file mode 100644 index 00000000000000..9ab2c7c698eaeb --- /dev/null +++ b/ext/geometry/Cargo.toml @@ -0,0 +1,18 @@ +# Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +[package] +name = "deno_geometry" +version = "0.1.0" +authors.workspace = true +edition.workspace = true +license.workspace = true +readme = "README.md" +repository.workspace = true +description = "Geometry Interfaces Module API implementation for Deno" + +[lib] +path = "lib.rs" + +[dependencies] +deno_core.workspace = true +nalgebra.workspace = true diff --git a/ext/geometry/README.md b/ext/geometry/README.md new file mode 100644 index 00000000000000..09465490254c8e --- /dev/null +++ b/ext/geometry/README.md @@ -0,0 +1,108 @@ +# deno_geometry + +This crate implements the Geometry Interfaces Module API. + +Spec: https://drafts.fxtf.org/geometry/ + +## Usage Example + +From javascript, include the extension's source: + +```javascript +import { core } from "ext:core/mod.js"; +import { createGeometryLoader } from "ext:deno_geometry/00_init.js"; +``` + +For environments that do not have a CSS `` parser, such as Web Worker, configure as follows: + +```javascript +const loadGeometry = createGeometryLoader((_transformList, prefix) => { + throw new TypeError( + `${prefix}: Cannot parse CSS on Workers`, + ); +}, /* enableWindowFeatures */ false); +``` + +On the other hand, in environments with a CSS `` parser, you can configure as follows: + +```javascript +const loadGeometry = createGeometryLoader((transformList, prefix) => { + try { + // parse by yourself + const { sequence, is2D } = parse(transformList); + return { + matrix: new Float64Array(sequence), + is2D, + }; + } catch { + throw new TypeError( + `${prefix}: Invalid string: ${transformList}`, + ); + } +}, /* enableWindowFeatures */ true); +``` + +Then define to globalThis: + +```javascript +Object.defineProperties(globalThis, { + DOMMatrix: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMMatrix, + loadGeometry, + ), + DOMMatrixReadOnly: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMMatrixReadOnly, + loadGeometry, + ), + DOMPoint: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMPoint, + loadGeometry, + ), + DOMPointReadOnly: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMPointReadOnly, + loadGeometry, + ), + DOMQuad: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMQuad, + loadGeometry, + ), + DOMRect: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMRect, + loadGeometry, + ), + DOMRectReadOnly: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMRectReadOnly, + loadGeometry, + ), +}); +``` + +Then from rust, provide: +`deno_geometry::deno_geometry::init_ops_and_esm()` in the `extensions` +field of your `RuntimeOptions` + +## Dependencies + +- **deno_webidl**: Provided by the `deno_webidl` crate +- **deno_web**: Provided by the `deno_web` crate +- **deno_console**: Provided by the `deno_console` crate + +## Provided ops + +Following ops are provided, which can be accessed through `Deno.ops`: + +- op_geometry_translate_self +- op_geometry_scale_self +- op_geometry_scale_with_origin_self +- op_geometry_rotate_self +- op_geometry_rotate_from_vector_self +- op_geometry_rotate_axis_angle_self +- op_geometry_skew_self +- op_geometry_multiply +- op_geometry_multiply_self +- op_geometry_premultiply_self +- op_geometry_flip_x_self +- op_geometry_flip_y_self +- op_geometry_invert_self +- op_geometry_invert_2d_self +- op_geometry_premultiply_point_self diff --git a/ext/geometry/lib.deno_geometry.d.ts b/ext/geometry/lib.deno_geometry.d.ts new file mode 100644 index 00000000000000..44b06d763ebf50 --- /dev/null +++ b/ext/geometry/lib.deno_geometry.d.ts @@ -0,0 +1,602 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +// deno-lint-ignore-file no-var + +/// +/// + +/** @category Geometry Interfaces Module API */ +declare interface DOMMatrix2DInit { + a?: number; + b?: number; + c?: number; + d?: number; + e?: number; + f?: number; + m11?: number; + m12?: number; + m21?: number; + m22?: number; + m41?: number; + m42?: number; +} + +/** @category Geometry Interfaces Module API */ +declare interface DOMMatrixInit extends DOMMatrix2DInit { + is2D?: boolean; + m13?: number; + m14?: number; + m23?: number; + m24?: number; + m31?: number; + m32?: number; + m33?: number; + m34?: number; + m43?: number; + m44?: number; +} + +/** + * A 4×4 matrix (column-major order), suitable for 2D and 3D operations including rotation and translation. + * [MDN](https://developer.mozilla.org/docs/Web/API/DOMMatrix) + * + * ``` + * | m11 m21 m31 m41 | + * | m12 m22 m32 m42 | + * | m13 m23 m33 m43 | + * | m14 m24 m34 m44 | + * ``` + * + * @category Geometry Interfaces Module API + */ +declare interface DOMMatrix extends DOMMatrixReadOnly { + a: number; + b: number; + c: number; + d: number; + e: number; + f: number; + m11: number; + m12: number; + m13: number; + m14: number; + m21: number; + m22: number; + m23: number; + m24: number; + m31: number; + m32: number; + m33: number; + m34: number; + m41: number; + m42: number; + m43: number; + m44: number; + /** + * Modifies the matrix by inverting it. + * If the matrix can't be inverted, its components are all set to `NaN`, and is2D property is set to `false`. + */ + invertSelf(): DOMMatrix; + /** + * Modifies the matrix by post-multiplying it with the specified DOMMatrix. + * This is equivalent to the dot product `Aâ‹…B`, where matrix `A` is the source matrix and `B` is the matrix given as an input to the method. + * + * @param other + */ + multiplySelf(other?: DOMMatrixInit): DOMMatrix; + /** + * Modifies the matrix by pre-multiplying it with the specified DOMMatrix. + * This is equivalent to the dot product Bâ‹…A, where matrix `A` is the source matrix and `B` is the matrix given as an input to the method. + * + * @param other + */ + preMultiplySelf(other?: DOMMatrixInit): DOMMatrix; + /** + * Modifies the matrix by rotating it by the specified angle around the given vector. + * + * @param x + * @param y + * @param z + * @param angle in degrees + */ + rotateAxisAngleSelf( + x?: number, + y?: number, + z?: number, + angle?: number, + ): DOMMatrix; + /** + * Modifies the matrix by rotating it by the angle between the specified vector and `(1, 0)`. + * + * @param x + * @param y + */ + rotateFromVectorSelf(x?: number, y?: number): DOMMatrix; + /** + * Modifies the matrix by rotating itself around each axis by the specified number of degrees. + * + * @param rotZ yaw angle in degrees + */ + rotateSelf(rotZ?: number): DOMMatrix; + /** + * Modifies the matrix by rotating itself around each axis by the specified number of degrees. + * + * @param rotX roll angle in degrees + * @param rotY pitch angle in degrees + * @param rotZ yaw angle in degrees + */ + rotateSelf(rotX?: number, rotY?: number, rotZ?: number): DOMMatrix; + /** + * Modifies the matrix by applying the specified scaling factor to all three axes, centered on the given origin. + * + * @param scale + * @param originX + * @param originY + * @param originZ + */ + scale3dSelf( + scale?: number, + originX?: number, + originY?: number, + originZ?: number, + ): DOMMatrix; + /** + * Modifies the matrix by applying the specified scaling factors, with the center located at the specified origin. Also returns itself. + * By default, the X and Z axes are scaled by `1` and the Y axis is given the same scaling value as the X axis. + * The default origin is `(0, 0, 0)`. + * + * @param scaleX + * @param scaleY + * @param scaleZ + * @param originX + * @param originY + * @param originZ + */ + scaleSelf( + scaleX?: number, + scaleY?: number, + scaleZ?: number, + originX?: number, + originY?: number, + originZ?: number, + ): DOMMatrix; + /** + * NOTE: Not available in Worker + * + * Replaces the contents of the matrix with the matrix described by the specified transform or transforms. + * + * @param transformList + */ + setMatrixValue(transformList: string): DOMMatrix; + /** + * Modifies the matrix by applying the specified skew transformation along the X-axis. + * + * @param sx in degrees + */ + skewXSelf(sx?: number): DOMMatrix; + /** + * Modifies the matrix by applying the specified skew transformation along the Y-axis. + * + * @param sy in degrees + */ + skewYSelf(sy?: number): DOMMatrix; + /** + * Modifies the matrix by applying the specified vector. The default vector is `(0, 0, 0)`. + * + * @param tx + * @param ty + * @param tz + */ + translateSelf(tx?: number, ty?: number, tz?: number): DOMMatrix; +} + +/** + * A 4×4 matrix (column-major order), suitable for 2D and 3D operations including rotation and translation. + * [MDN](https://developer.mozilla.org/docs/Web/API/DOMMatrix) + * + * ``` + * | m11 m21 m31 m41 | + * | m12 m22 m32 m42 | + * | m13 m23 m33 m43 | + * | m14 m24 m34 m44 | + * ``` + * + * @category Geometry Interfaces Module API + */ +declare var DOMMatrix: { + prototype: DOMMatrix; + new (init?: number[]): DOMMatrix; + new (init: DOMMatrix | DOMMatrixReadOnly): DOMMatrix; + /** NOTE: Not available in Worker */ + new (init: string): DOMMatrix; + fromFloat32Array(array32: Float32Array): DOMMatrix; + fromFloat64Array(array64: Float64Array): DOMMatrix; + fromMatrix(other?: DOMMatrixInit): DOMMatrix; +}; + +/** + * A read-only 4×4 matrix (column-major order), suitable for 2D and 3D operations including rotation and translation. + * [MDN](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly) + * + * ``` + * | m11 m21 m31 m41 | + * | m12 m22 m32 m42 | + * | m13 m23 m33 m43 | + * | m14 m24 m34 m44 | + * ``` + * + * @category Geometry Interfaces Module API + */ +declare interface DOMMatrixReadOnly { + readonly a: number; + readonly b: number; + readonly c: number; + readonly d: number; + readonly e: number; + readonly f: number; + readonly is2D: boolean; + readonly isIdentity: boolean; + readonly m11: number; + readonly m12: number; + readonly m13: number; + readonly m14: number; + readonly m21: number; + readonly m22: number; + readonly m23: number; + readonly m24: number; + readonly m31: number; + readonly m32: number; + readonly m33: number; + readonly m34: number; + readonly m41: number; + readonly m42: number; + readonly m43: number; + readonly m44: number; + /** Returns a new `DOMMatrix` created by flipping the source matrix around its X-axis. */ + flipX(): DOMMatrix; + /** Returns a new `DOMMatrix` created by flipping the source matrix around its Y-axis. */ + flipY(): DOMMatrix; + /** + * Returns a new `DOMMatrix` created by inverting the source matrix. + * If the matrix cannot be inverted, the new matrix's components are all set to `NaN` and its is2D property is set to `false`. + */ + inverse(): DOMMatrix; + /** + * Returns a new `DOMMatrix` created by computing the dot product of the source matrix and the specified matrix: `Aâ‹…B`. + * + * @param other + */ + multiply(other?: DOMMatrixInit): DOMMatrix; + /** + * Returns a new `DOMMatrix` created by rotating the source matrix around each of its axes by the specified number of degrees. + * + * @param rotZ yaw angle in degrees + */ + rotate(rotZ?: number): DOMMatrix; + /** + * Returns a new `DOMMatrix` created by rotating the source matrix around each of its axes by the specified number of degrees. + * + * @param rotX roll angle in degrees + * @param rotY pitch angle in degrees + * @param rotZ yaw angle in degrees + */ + rotate(rotX?: number, rotY?: number, rotZ?: number): DOMMatrix; + /** + * Returns a new DOMMatrix created by rotating the source matrix by the given angle around the specified vector. + * + * @param x + * @param y + * @param z + * @param angle in degrees + */ + rotateAxisAngle( + x?: number, + y?: number, + z?: number, + angle?: number, + ): DOMMatrix; + /** + * Returns a new `DOMMatrix` created by rotating the source matrix by the angle between the specified vector and `(1, 0)`. + * + * @param x + * @param y + */ + rotateFromVector(x?: number, y?: number): DOMMatrix; + /** + * Returns a new `DOMMatrix` created by scaling the source matrix by the amount specified for each axis, centered on the given origin. + * By default, the X and Z axes are scaled by `1` and the Y axis is given the same scaling value as the X axis. + * The default origin is `(0, 0, 0)`. + * + * @param scaleX + * @param scaleY + * @param scaleZ + * @param originX + * @param originY + * @param originZ + */ + scale( + scaleX?: number, + scaleY?: number, + scaleZ?: number, + originX?: number, + originY?: number, + originZ?: number, + ): DOMMatrix; + /** + * Returns a new `DOMMatrix` created by scaling the source 3D matrix by the given factor along all its axes, centered on the specified origin point. + * The default origin is `(0, 0, 0)`. + * + * @param scale + * @param originX + * @param originY + * @param originZ + */ + scale3d( + scale?: number, + originX?: number, + originY?: number, + originZ?: number, + ): DOMMatrix; + /** + * Returns a new `DOMMatrix` created by applying the specified scaling on the X, Y, and Z axes, centered at the given origin. + * By default, the X and Y axes' scaling factors are both `1`. + * + * @deprecated Supported for legacy reasons to be compatible with `SVGMatrix` as defined in SVG 1.1. Use `scale()` instead. + * + * @param scaleX + * @param scaleY + */ + scaleNonUniform(scaleX?: number, scaleY?: number): DOMMatrix; + /** + * Returns a new DOMMatrix created by applying the specified skew transformation to the source matrix along its X-axis. + * + * @param sx in degrees + */ + skewX(sx?: number): DOMMatrix; + /** + * Returns a new DOMMatrix created by applying the specified skew transformation to the source matrix along its Y-axis. + * + * @param sy in degrees + */ + skewY(sy?: number): DOMMatrix; + toFloat32Array(): Float32Array; + toFloat64Array(): Float64Array; + toJSON(): { + a: number; + b: number; + c: number; + d: number; + e: number; + f: number; + is2D: boolean; + isIdentity: boolean; + m11: number; + m12: number; + m13: number; + m14: number; + m21: number; + m22: number; + m23: number; + m24: number; + m31: number; + m32: number; + m33: number; + m34: number; + m41: number; + m42: number; + m43: number; + m44: number; + }; + transformPoint(point?: DOMPointInit): DOMPoint; + translate(tx?: number, ty?: number, tz?: number): DOMMatrix; + /** NOTE: Not available in Worker */ + toString(): string; +} + +/** + * A read-only 4×4 matrix (column-major order), suitable for 2D and 3D operations including rotation and translation. + * [MDN](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly) + * + * ``` + * | m11 m21 m31 m41 | + * | m12 m22 m32 m42 | + * | m13 m23 m33 m43 | + * | m14 m24 m34 m44 | + * ``` + * + * @category Geometry Interfaces Module API + */ +declare var DOMMatrixReadOnly: { + prototype: DOMMatrixReadOnly; + new (init?: number[]): DOMMatrixReadOnly; + new (init: DOMMatrix | DOMMatrixReadOnly): DOMMatrixReadOnly; + /** Not available in Worker */ + new (init: string): DOMMatrixReadOnly; + fromFloat32Array(array32: Float32Array): DOMMatrixReadOnly; + fromFloat64Array(array64: Float64Array): DOMMatrixReadOnly; + fromMatrix(other?: DOMMatrixInit): DOMMatrixReadOnly; +}; + +/** @category Geometry Interfaces Module API */ +declare interface DOMPointInit { + w?: number; + x?: number; + y?: number; + z?: number; +} + +/** + * A object represents a 2D or 3D point in a coordinate system; it includes values for the coordinates in up to three dimensions, as well as an optional perspective value. + * [MDN](https://developer.mozilla.org/docs/Web/API/DOMPoint) + * + * @category Geometry Interfaces Module API + */ +declare interface DOMPoint extends DOMPointReadOnly { + w: number; + x: number; + y: number; + z: number; +} + +/** + * A object represents a 2D or 3D point in a coordinate system; it includes values for the coordinates in up to three dimensions, as well as an optional perspective value. + * [MDN](https://developer.mozilla.org/docs/Web/API/DOMPoint) + * + * @category Geometry Interfaces Module API + */ +declare var DOMPoint: { + prototype: DOMPoint; + new (x?: number, y?: number, z?: number, w?: number): DOMPoint; + fromPoint(other?: DOMPointInit): DOMPoint; +}; + +/** + * A read-only object represents a 2D or 3D point in a coordinate system; it includes values for the coordinates in up to three dimensions, as well as an optional perspective value. + * [MDN](https://developer.mozilla.org/docs/Web/API/DOMPointReadOnly) + * + * @category Geometry Interfaces Module API + */ +declare interface DOMPointReadOnly { + readonly w: number; + readonly x: number; + readonly y: number; + readonly z: number; + matrixTransform(matrix?: DOMMatrixInit): DOMPoint; + toJSON(): { + w: number; + x: number; + y: number; + z: number; + }; +} + +/** + * A read-only object represents a 2D or 3D point in a coordinate system; it includes values for the coordinates in up to three dimensions, as well as an optional perspective value. + * [MDN](https://developer.mozilla.org/docs/Web/API/DOMPointReadOnly) + * + * @category Geometry Interfaces Module API + */ +declare var DOMPointReadOnly: { + prototype: DOMPointReadOnly; + new (x?: number, y?: number, z?: number, w?: number): DOMPointReadOnly; + fromPoint(other?: DOMPointInit): DOMPointReadOnly; +}; + +/** @category Geometry Interfaces Module API */ +declare interface DOMQuadInit { + p1?: DOMPointInit; + p2?: DOMPointInit; + p3?: DOMPointInit; + p4?: DOMPointInit; +} + +/** + * A collection of four DOMPoints defining the corners of an arbitrary quadrilateral. + * [MDN](https://developer.mozilla.org/docs/Web/API/DOMQuad) + * + * @category Geometry Interfaces Module API + */ +declare interface DOMQuad { + readonly p1: DOMPoint; + readonly p2: DOMPoint; + readonly p3: DOMPoint; + readonly p4: DOMPoint; + getBounds(): DOMRect; + toJSON(): { + p1: DOMPoint; + p2: DOMPoint; + p3: DOMPoint; + p4: DOMPoint; + }; +} + +/** + * A collection of four DOMPoints defining the corners of an arbitrary quadrilateral. + * [MDN](https://developer.mozilla.org/docs/Web/API/DOMQuad) + * + * @category Geometry Interfaces Module API + */ +declare var DOMQuad: { + prototype: DOMQuad; + new ( + p1?: DOMPointInit, + p2?: DOMPointInit, + p3?: DOMPointInit, + p4?: DOMPointInit, + ): DOMQuad; + fromQuad(other?: DOMQuadInit): DOMQuad; + fromRect(other?: DOMRectInit): DOMQuad; +}; + +/** @category Geometry Interfaces Module API */ +declare interface DOMRectInit { + height?: number; + width?: number; + x?: number; + y?: number; +} + +/** + * [MDN](https://developer.mozilla.org/docs/Web/API/DOMRect) + * + * @category Geometry Interfaces Module API + */ +declare interface DOMRect extends DOMRectReadOnly { + height: number; + width: number; + x: number; + y: number; +} + +/** + * [MDN](https://developer.mozilla.org/docs/Web/API/DOMRect) + * + * @category Geometry Interfaces Module API + */ +declare var DOMRect: { + prototype: DOMRect; + new (x?: number, y?: number, width?: number, height?: number): DOMRect; + fromRect(other?: DOMRectInit): DOMRect; +}; + +/** + * [MDN](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly) + * + * @category Geometry Interfaces Module API + */ +declare interface DOMRectReadOnly { + readonly bottom: number; + readonly height: number; + readonly left: number; + readonly right: number; + readonly top: number; + readonly width: number; + readonly x: number; + readonly y: number; + toJSON(): { + bottom: number; + height: number; + left: number; + right: number; + top: number; + width: number; + x: number; + y: number; + }; +} + +/** + * [MDN](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly) + * + * @category Geometry Interfaces Module API + */ +declare var DOMRectReadOnly: { + prototype: DOMRectReadOnly; + new ( + x?: number, + y?: number, + width?: number, + height?: number, + ): DOMRectReadOnly; + fromRect(other?: DOMRectInit): DOMRectReadOnly; +}; diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs new file mode 100644 index 00000000000000..16879f4ddf2071 --- /dev/null +++ b/ext/geometry/lib.rs @@ -0,0 +1,269 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +use deno_core::op2; +use nalgebra::Matrix3; +use nalgebra::Matrix4; +use nalgebra::Matrix4x2; +use nalgebra::Matrix4x3; +use nalgebra::MatrixView4; +use nalgebra::MatrixViewMut4; +use nalgebra::Rotation3; +use nalgebra::UnitVector3; +use nalgebra::Vector3; +use nalgebra::Vector4; +use nalgebra::VectorViewMut4; +use std::path::PathBuf; + +deno_core::extension!( + deno_geometry, + deps = [deno_webidl, deno_web, deno_console], + ops = [ + op_geometry_translate_self, + op_geometry_scale_self, + op_geometry_scale_with_origin_self, + op_geometry_rotate_self, + op_geometry_rotate_from_vector_self, + op_geometry_rotate_axis_angle_self, + op_geometry_skew_self, + op_geometry_multiply, + op_geometry_multiply_self, + op_geometry_premultiply_self, + op_geometry_flip_x_self, + op_geometry_flip_y_self, + op_geometry_invert_self, + op_geometry_invert_2d_self, + op_geometry_premultiply_point_self, + ], + esm = ["00_init.js"], + lazy_loaded_esm = ["01_geometry.js"], +); + +pub fn get_declaration() -> PathBuf { + PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("lib.deno_geometry.d.ts") +} + +#[op2(fast)] +pub fn op_geometry_translate_self( + x: f64, + y: f64, + z: f64, + #[buffer] inout: &mut [f64], +) { + let shift = Vector3::new(x, y, z); + let mut inout = MatrixViewMut4::from_slice(inout); + inout.prepend_translation_mut(&shift); +} + +#[op2(fast)] +pub fn op_geometry_scale_self( + x: f64, + y: f64, + z: f64, + #[buffer] inout: &mut [f64], +) { + let scaling = Vector3::new(x, y, z); + let mut inout = MatrixViewMut4::from_slice(inout); + inout.prepend_nonuniform_scaling_mut(&scaling); +} + +#[op2(fast)] +pub fn op_geometry_scale_with_origin_self( + x: f64, + y: f64, + z: f64, + origin_x: f64, + origin_y: f64, + origin_z: f64, + #[buffer] inout: &mut [f64], +) { + let scaling = Vector3::new(x, y, z); + let mut shift = Vector3::new(origin_x, origin_y, origin_z); + let mut inout = MatrixViewMut4::from_slice(inout); + inout.prepend_translation_mut(&shift); + inout.prepend_nonuniform_scaling_mut(&scaling); + shift.neg_mut(); + inout.prepend_translation_mut(&shift); +} + +#[op2(fast)] +pub fn op_geometry_rotate_self( + roll_degrees: f64, + pitch_degrees: f64, + yaw_degrees: f64, + #[buffer] inout: &mut [f64], +) { + let rotation = Rotation3::from_euler_angles( + roll_degrees.to_radians(), + pitch_degrees.to_radians(), + yaw_degrees.to_radians(), + ) + .to_homogeneous(); + let mut inout = MatrixViewMut4::from_slice(inout); + let mut result = Matrix4x3::zeros(); + inout.mul_to(&rotation.fixed_view::<4, 3>(0, 0), &mut result); + inout.set_column(0, &result.column(0)); + inout.set_column(1, &result.column(1)); + inout.set_column(2, &result.column(2)); +} + +#[op2(fast)] +pub fn op_geometry_rotate_from_vector_self( + x: f64, + y: f64, + #[buffer] inout: &mut [f64], +) { + let rotation = + Rotation3::from_axis_angle(&Vector3::z_axis(), y.atan2(x)).to_homogeneous(); + let mut inout = MatrixViewMut4::from_slice(inout); + let mut result = Matrix4x3::zeros(); + inout.mul_to(&rotation.fixed_view::<4, 3>(0, 0), &mut result); + inout.set_column(0, &result.column(0)); + inout.set_column(1, &result.column(1)); + inout.set_column(2, &result.column(2)); +} + +#[op2(fast)] +pub fn op_geometry_rotate_axis_angle_self( + x: f64, + y: f64, + z: f64, + angle_degrees: f64, + #[buffer] inout: &mut [f64], +) { + let rotation = Rotation3::from_axis_angle( + &UnitVector3::new_normalize(Vector3::new(x, y, z)), + angle_degrees.to_radians(), + ) + .to_homogeneous(); + let mut inout = MatrixViewMut4::from_slice(inout); + let mut result = Matrix4x3::zeros(); + inout.mul_to(&rotation.fixed_view::<4, 3>(0, 0), &mut result); + inout.set_column(0, &result.column(0)); + inout.set_column(1, &result.column(1)); + inout.set_column(2, &result.column(2)); +} + +#[op2(fast)] +pub fn op_geometry_skew_self( + x_degrees: f64, + y_degrees: f64, + #[buffer] inout: &mut [f64], +) { + let skew = Matrix4x2::new( + 1.0, + x_degrees.to_radians().tan(), + y_degrees.to_radians().tan(), + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + ); + let mut inout = MatrixViewMut4::from_slice(inout); + let mut result = Matrix4x2::zeros(); + inout.mul_to(&skew, &mut result); + inout.set_column(0, &result.column(0)); + inout.set_column(1, &result.column(1)); +} + +#[op2(fast)] +pub fn op_geometry_multiply( + #[buffer] lhs: &[f64], + #[buffer] rhs: &[f64], + #[buffer] out: &mut [f64], +) { + let lhs = MatrixView4::from_slice(lhs); + let rhs = MatrixView4::from_slice(rhs); + let mut out = MatrixViewMut4::from_slice(out); + lhs.mul_to(&rhs, &mut out); +} + +#[op2(fast)] +pub fn op_geometry_multiply_self( + #[buffer] rhs: &[f64], + #[buffer] inout: &mut [f64], +) { + let rhs = MatrixView4::from_slice(rhs); + let mut inout = MatrixViewMut4::from_slice(inout); + let mut result = Matrix4::zeros(); + inout.mul_to(&rhs, &mut result); + inout.copy_from(&result); +} + +#[op2(fast)] +pub fn op_geometry_premultiply_self( + #[buffer] lhs: &[f64], + #[buffer] inout: &mut [f64], +) { + let lhs = MatrixView4::from_slice(lhs); + let mut inout = MatrixViewMut4::from_slice(inout); + let mut result = Matrix4::zeros(); + lhs.mul_to(&inout, &mut result); + inout.copy_from(&result); +} + +#[op2(fast)] +pub fn op_geometry_flip_x_self(#[buffer] inout: &mut [f64]) { + let mut inout = MatrixViewMut4::from_slice(inout); + inout.column_mut(0).neg_mut(); +} + +#[op2(fast)] +pub fn op_geometry_flip_y_self(#[buffer] inout: &mut [f64]) { + let mut inout = MatrixViewMut4::from_slice(inout); + inout.column_mut(1).neg_mut(); +} + +#[op2(fast)] +pub fn op_geometry_invert_self(#[buffer] inout: &mut [f64]) -> bool { + if inout.iter().any(|&x| x.is_infinite()) { + inout.fill(f64::NAN); + return false; + } + + let mut inout = MatrixViewMut4::from_slice(inout); + if !inout.try_inverse_mut() { + inout.fill(f64::NAN); + return false; + } + + true +} + +#[op2(fast)] +pub fn op_geometry_invert_2d_self(#[buffer] inout: &mut [f64]) -> bool { + if inout.iter().any(|&x| x.is_infinite()) { + inout.fill(f64::NAN); + return false; + } + + let mut matrix = Matrix3::new( + inout[0], inout[4], inout[12], inout[1], inout[5], inout[13], 0.0, 0.0, 1.0, + ); + if !matrix.try_inverse_mut() { + inout.fill(f64::NAN); + return false; + } + + let matrix = matrix.as_slice(); + inout[0] = matrix[0]; + inout[1] = matrix[1]; + inout[4] = matrix[3]; + inout[5] = matrix[4]; + inout[12] = matrix[6]; + inout[13] = matrix[7]; + + true +} + +#[op2(fast)] +pub fn op_geometry_premultiply_point_self( + #[buffer] lhs: &[f64], + #[buffer] inout: &mut [f64], +) { + let lhs = MatrixView4::from_slice(lhs); + let mut inout = VectorViewMut4::from_slice(inout); + let mut result = Vector4::zeros(); + lhs.mul_to(&inout, &mut result); + inout.copy_from(&result); +} diff --git a/ext/webidl/00_webidl.js b/ext/webidl/00_webidl.js index b3c3b299f03cbd..e7252cb0ece4d9 100644 --- a/ext/webidl/00_webidl.js +++ b/ext/webidl/00_webidl.js @@ -679,6 +679,9 @@ converters["UVString?"] = createNullableConverter( converters["sequence"] = createSequenceConverter( converters.double, ); +converters["sequence"] = createSequenceConverter( + converters["unrestricted double"], +); converters["sequence"] = createSequenceConverter( converters.object, ); diff --git a/ext/webidl/internal.d.ts b/ext/webidl/internal.d.ts index a884d982aabb2f..adfb6713563c80 100644 --- a/ext/webidl/internal.d.ts +++ b/ext/webidl/internal.d.ts @@ -348,6 +348,12 @@ declare module "ext:deno_webidl/00_webidl.js" { context?: string, opts?: any, ): number[]; + ["sequence"]( + v: any, + prefix?: string, + context?: string, + opts?: any, + ): number[]; [type: string]: ( v: any, diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index 9826a7459db2a4..7ed5dec94d895c 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -51,6 +51,7 @@ deno_crypto.workspace = true deno_fetch.workspace = true deno_ffi.workspace = true deno_fs = { workspace = true, features = ["sync_fs"] } +deno_geometry.workspace = true deno_http.workspace = true deno_io.workspace = true deno_net.workspace = true @@ -82,6 +83,7 @@ deno_crypto.workspace = true deno_fetch.workspace = true deno_ffi.workspace = true deno_fs = { workspace = true, features = ["sync_fs"] } +deno_geometry.workspace = true deno_http.workspace = true deno_io.workspace = true deno_kv.workspace = true diff --git a/runtime/js/98_global_scope_window.js b/runtime/js/98_global_scope_window.js index c42a940a829796..2aee67d70cf069 100644 --- a/runtime/js/98_global_scope_window.js +++ b/runtime/js/98_global_scope_window.js @@ -7,18 +7,93 @@ import { op_bootstrap_user_agent, } from "ext:core/ops"; const { + ArrayPrototypeMap, + ArrayPrototypeSome, + Float64Array, + Number, + NumberIsNaN, ObjectDefineProperties, ObjectPrototypeIsPrototypeOf, + SafeRegExp, + StringPrototypeMatch, + StringPrototypeSplit, SymbolFor, + TypeError, } = primordials; import * as location from "ext:deno_web/12_location.js"; import * as console from "ext:deno_console/01_console.js"; import * as webidl from "ext:deno_webidl/00_webidl.js"; +import { DOMException } from "ext:deno_web/01_dom_exception.js"; import * as globalInterfaces from "ext:deno_web/04_global_interfaces.js"; import * as webStorage from "ext:deno_webstorage/01_webstorage.js"; import * as prompt from "ext:runtime/41_prompt.js"; import { loadWebGPU } from "ext:deno_webgpu/00_init.js"; +import { createGeometryLoader } from "ext:deno_geometry/00_init.js"; + +const MATRIX_PATTERN = new SafeRegExp( + /^\s*matrix(3d)?\(([-\+0-9.e,\s]+)\)\s*$/iu, +); + +const loadGeometry = createGeometryLoader((transformList, prefix) => { + if (transformList === "") { + return { + // deno-fmt-ignore + matrix: new Float64Array([ + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1, + ]), + is2D: true, + }; + } + + // Currently only parsing of a single matrix, matrix3d function without units + // as arguments is implemented + // TODO(petamoriken): Add CSS parser such as lightningcss to support more cases + const matrixMatch = StringPrototypeMatch(transformList, MATRIX_PATTERN); + if (matrixMatch !== null) { + const is2D = matrixMatch[1] === undefined; + /** @type {number[]} */ + const seq = ArrayPrototypeMap( + StringPrototypeSplit(matrixMatch[2], ","), + (str) => Number(str), + ); + if ( + is2D && seq.length !== 6 || + !is2D && seq.length !== 16 || + ArrayPrototypeSome(seq, (num) => NumberIsNaN(num)) + ) { + throw new DOMException( + `${prefix}: Failed to parse '${transformList}'`, + "SyntaxError", + ); + } + if (is2D) { + const { 0: a, 1: b, 2: c, 3: d, 4: e, 5: f } = seq; + return { + // deno-fmt-ignore + matrix: new Float64Array([ + a, b, 0, 0, + c, d, 0, 0, + 0, 0, 1, 0, + e, f, 0, 1, + ]), + is2D, + }; + } else { + return { + matrix: new Float64Array(seq), + is2D, + }; + } + } + + throw new TypeError( + `${prefix}: CSS parser is not fully implemented`, + ); +}, true); class Navigator { constructor() { @@ -121,6 +196,34 @@ const mainRuntimeGlobalProperties = { localStorage: core.propGetterOnly(webStorage.localStorage), sessionStorage: core.propGetterOnly(webStorage.sessionStorage), Storage: core.propNonEnumerable(webStorage.Storage), + DOMMatrix: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMMatrix, + loadGeometry, + ), + DOMMatrixReadOnly: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMMatrixReadOnly, + loadGeometry, + ), + DOMPoint: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMPoint, + loadGeometry, + ), + DOMPointReadOnly: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMPointReadOnly, + loadGeometry, + ), + DOMQuad: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMQuad, + loadGeometry, + ), + DOMRect: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMRect, + loadGeometry, + ), + DOMRectReadOnly: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMRectReadOnly, + loadGeometry, + ), }; export { mainRuntimeGlobalProperties, memoizeLazy }; diff --git a/runtime/js/98_global_scope_worker.js b/runtime/js/98_global_scope_worker.js index f10bb2830dbbb6..d1fb739964363f 100644 --- a/runtime/js/98_global_scope_worker.js +++ b/runtime/js/98_global_scope_worker.js @@ -10,6 +10,7 @@ const { ObjectDefineProperties, ObjectPrototypeIsPrototypeOf, SymbolFor, + TypeError, } = primordials; import * as location from "ext:deno_web/12_location.js"; @@ -17,6 +18,13 @@ import * as console from "ext:deno_console/01_console.js"; import * as webidl from "ext:deno_webidl/00_webidl.js"; import * as globalInterfaces from "ext:deno_web/04_global_interfaces.js"; import { loadWebGPU } from "ext:deno_webgpu/00_init.js"; +import { createGeometryLoader } from "ext:deno_geometry/00_init.js"; + +const loadGeometry = createGeometryLoader((_transformList, prefix) => { + throw new TypeError( + `${prefix}: Cannot parse CSS on Workers`, + ); +}, false); function memoizeLazy(f) { let v_ = null; @@ -115,6 +123,34 @@ const workerRuntimeGlobalProperties = { WorkerNavigator: core.propNonEnumerable(WorkerNavigator), navigator: core.propGetterOnly(() => workerNavigator), self: core.propGetterOnly(() => globalThis), + DOMMatrix: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMMatrix, + loadGeometry, + ), + DOMMatrixReadOnly: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMMatrixReadOnly, + loadGeometry, + ), + DOMPoint: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMPoint, + loadGeometry, + ), + DOMPointReadOnly: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMPointReadOnly, + loadGeometry, + ), + DOMQuad: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMQuad, + loadGeometry, + ), + DOMRect: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMRect, + loadGeometry, + ), + DOMRectReadOnly: core.propNonEnumerableLazyLoaded( + (geometry) => geometry.DOMRectReadOnly, + loadGeometry, + ), }; export { workerRuntimeGlobalProperties }; diff --git a/runtime/lib.rs b/runtime/lib.rs index 3e48ec89c0a59a..ea8f8f2c928ad2 100644 --- a/runtime/lib.rs +++ b/runtime/lib.rs @@ -10,6 +10,7 @@ pub use deno_crypto; pub use deno_fetch; pub use deno_ffi; pub use deno_fs; +pub use deno_geometry; pub use deno_http; pub use deno_io; pub use deno_kv; diff --git a/runtime/shared.rs b/runtime/shared.rs index 1a9f2e66be1814..321e0a0d573a3f 100644 --- a/runtime/shared.rs +++ b/runtime/shared.rs @@ -22,6 +22,7 @@ extension!(runtime, deno_web, deno_fetch, deno_cache, + deno_geometry, deno_websocket, deno_webstorage, deno_crypto, diff --git a/runtime/snapshot.rs b/runtime/snapshot.rs index 8d008eeab0043a..d7aad4720ef7e7 100644 --- a/runtime/snapshot.rs +++ b/runtime/snapshot.rs @@ -281,6 +281,7 @@ pub fn create_runtime_snapshot( deno_webgpu::deno_webgpu::init_ops_and_esm(), deno_canvas::deno_canvas::init_ops_and_esm(), deno_fetch::deno_fetch::init_ops_and_esm::(Default::default()), + deno_geometry::deno_geometry::init_ops_and_esm(), deno_cache::deno_cache::init_ops_and_esm::(None), deno_websocket::deno_websocket::init_ops_and_esm::( "".to_owned(), diff --git a/runtime/web_worker.rs b/runtime/web_worker.rs index 270fc1ab9f77b7..83068596f3aa92 100644 --- a/runtime/web_worker.rs +++ b/runtime/web_worker.rs @@ -462,6 +462,7 @@ impl WebWorker { ..Default::default() }, ), + deno_geometry::deno_geometry::init_ops_and_esm(), deno_cache::deno_cache::init_ops_and_esm::( create_cache, ), diff --git a/runtime/worker.rs b/runtime/worker.rs index de29b66291fb8e..52c7a8d89c31f8 100644 --- a/runtime/worker.rs +++ b/runtime/worker.rs @@ -372,6 +372,7 @@ impl MainWorker { ..Default::default() }, ), + deno_geometry::deno_geometry::init_ops_and_esm(), deno_cache::deno_cache::init_ops_and_esm::( create_cache, ), diff --git a/tests/integration/js_unit_tests.rs b/tests/integration/js_unit_tests.rs index 9ecec8b426c844..b241fb041b5d33 100644 --- a/tests/integration/js_unit_tests.rs +++ b/tests/integration/js_unit_tests.rs @@ -39,6 +39,7 @@ util::unit_test_factory!( filereader_test, files_test, fs_events_test, + geometry_test, get_random_values_test, globals_test, headers_test, diff --git a/tests/unit/geometry_test.ts b/tests/unit/geometry_test.ts new file mode 100644 index 00000000000000..b4910c3e6f5ec6 --- /dev/null +++ b/tests/unit/geometry_test.ts @@ -0,0 +1,1195 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. +import { + assertAlmostEquals, + assertEquals, + assertStrictEquals, + assertThrows, +} from "./test_util.ts"; + +Deno.test(function matrixTransformPoint() { + const point = new DOMPoint(1, 2, 3, 4); + // deno-fmt-ignore + const matrix = DOMMatrix.fromMatrix({ + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }); + const point2 = point.matrixTransform(matrix); + const point3 = matrix.transformPoint(point); + assertEquals( + point, + new DOMPoint(1, 2, 3, 4), + ); + assertEquals( + point2, + new DOMPoint(30, 70, 110, 150), + ); + assertEquals( + point3, + new DOMPoint(30, 70, 110, 150), + ); +}); + +Deno.test(function matrixTranslate() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.translate(1, 2, 3); + assertEquals( + matrix, + DOMMatrix.fromMatrix(init), + ); + assertEquals( + matrix2, + // deno-fmt-ignore + DOMMatrix.fromMatrix({ + m11: 1, m21: 2, m31: 3, m41: 1 * 1 + 2 * 2 + 3 * 3 + 4 * 1, + m12: 5, m22: 6, m32: 7, m42: 5 * 1 + 6 * 2 + 7 * 3 + 8 * 1, + m13: 9, m23: 10, m33: 11, m43: 9 * 1 + 10 * 2 + 11 * 3 + 12 * 1, + m14: 13, m24: 14, m34: 15, m44: 13 * 1 + 14 * 2 + 15 * 3 + 16 * 1, + }), + ); +}); + +Deno.test(function matrixTranslateSelf() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.translateSelf(1, 2, 3); + assertStrictEquals( + matrix, + matrix2, + ); + assertEquals( + matrix, + // deno-fmt-ignore + DOMMatrix.fromMatrix({ + m11: 1, m21: 2, m31: 3, m41: 1 * 1 + 2 * 2 + 3 * 3 + 4 * 1, + m12: 5, m22: 6, m32: 7, m42: 5 * 1 + 6 * 2 + 7 * 3 + 8 * 1, + m13: 9, m23: 10, m33: 11, m43: 9 * 1 + 10 * 2 + 11 * 3 + 12 * 1, + m14: 13, m24: 14, m34: 15, m44: 13 * 1 + 14 * 2 + 15 * 3 + 16 * 1, + }), + ); +}); + +Deno.test(function matrixScale() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.scale(1, 2, 3); + assertEquals( + matrix, + DOMMatrix.fromMatrix(init), + ); + assertEquals( + matrix2, + // deno-fmt-ignore + DOMMatrix.fromMatrix({ + m11: 1, m21: 2 * 2, m31: 3 * 3, m41: 4, + m12: 5, m22: 6 * 2, m32: 7 * 3, m42: 8, + m13: 9, m23: 10 * 2, m33: 11 * 3, m43: 12, + m14: 13, m24: 14 * 2, m34: 15 * 3, m44: 16, + }), + ); +}); + +Deno.test(function matrixScaleSelf() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.scaleSelf(1, 2, 3); + assertStrictEquals( + matrix, + matrix2, + ); + assertEquals( + matrix, + // deno-fmt-ignore + DOMMatrix.fromMatrix({ + m11: 1, m21: 2 * 2, m31: 3 * 3, m41: 4, + m12: 5, m22: 6 * 2, m32: 7 * 3, m42: 8, + m13: 9, m23: 10 * 2, m33: 11 * 3, m43: 12, + m14: 13, m24: 14 * 2, m34: 15 * 3, m44: 16, + }), + ); +}); + +Deno.test(function matrixScaleWithOrigin() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.scale(1, 2, 3, 4, 5, 6); + assertEquals( + matrix, + DOMMatrix.fromMatrix(init), + ); + assertEquals( + matrix2, + // deno-fmt-ignore + DOMMatrix.fromMatrix({ + m11: 1, m21: 2 * 2, m31: 3 * 3, m41: -42, + m12: 5, m22: 6 * 2, m32: 7 * 3, m42: -106, + m13: 9, m23: 10 * 2, m33: 11 * 3, m43: -170, + m14: 13, m24: 14 * 2, m34: 15 * 3, m44: -234, + }), + ); +}); + +Deno.test(function matrixScaleWithOriginSelf() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.scaleSelf(1, 2, 3, 4, 5, 6); + assertStrictEquals( + matrix, + matrix2, + ); + assertEquals( + matrix, + // deno-fmt-ignore + DOMMatrix.fromMatrix({ + m11: 1, m21: 2 * 2, m31: 3 * 3, m41: -42, + m12: 5, m22: 6 * 2, m32: 7 * 3, m42: -106, + m13: 9, m23: 10 * 2, m33: 11 * 3, m43: -170, + m14: 13, m24: 14 * 2, m34: 15 * 3, m44: -234, + }), + ); +}); + +Deno.test(function matrixScaleNonUniform() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.scaleNonUniform(1, 2); + assertEquals( + matrix, + DOMMatrix.fromMatrix(init), + ); + assertEquals( + matrix2, + // deno-fmt-ignore + DOMMatrix.fromMatrix({ + m11: 1, m21: 2 * 2, m31: 3, m41: 4, + m12: 5, m22: 6 * 2, m32: 7, m42: 8, + m13: 9, m23: 10 * 2, m33: 11, m43: 12, + m14: 13, m24: 14 * 2, m34: 15, m44: 16, + }), + ); +}); + +Deno.test(function matrixScale3d() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.scale3d(2); + assertEquals( + matrix, + DOMMatrix.fromMatrix(init), + ); + assertEquals( + matrix2, + // deno-fmt-ignore + DOMMatrix.fromMatrix({ + m11: 1 * 2, m21: 2 * 2, m31: 3 * 2, m41: 4, + m12: 5 * 2, m22: 6 * 2, m32: 7 * 2, m42: 8, + m13: 9 * 2, m23: 10 * 2, m33: 11 * 2, m43: 12, + m14: 13 * 2, m24: 14 * 2, m34: 15 * 2, m44: 16, + }), + ); +}); + +Deno.test(function matrixScale3dSelf() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.scale3dSelf(2); + assertStrictEquals( + matrix, + matrix2, + ); + assertEquals( + matrix, + // deno-fmt-ignore + DOMMatrix.fromMatrix({ + m11: 1 * 2, m21: 2 * 2, m31: 3 * 2, m41: 4, + m12: 5 * 2, m22: 6 * 2, m32: 7 * 2, m42: 8, + m13: 9 * 2, m23: 10 * 2, m33: 11 * 2, m43: 12, + m14: 13 * 2, m24: 14 * 2, m34: 15 * 2, m44: 16, + }), + ); +}); + +Deno.test(function matrixScale3dWithOrigin() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.scale3d(2, 4, 5, 6); + assertEquals( + matrix, + DOMMatrix.fromMatrix(init), + ); + assertEquals( + matrix2, + // deno-fmt-ignore + DOMMatrix.fromMatrix({ + m11: 1 * 2, m21: 2 * 2, m31: 3 * 2, m41: -28, + m12: 5 * 2, m22: 6 * 2, m32: 7 * 2, m42: -84, + m13: 9 * 2, m23: 10 * 2, m33: 11 * 2, m43: -140, + m14: 13 * 2, m24: 14 * 2, m34: 15 * 2, m44: -196, + }), + ); +}); + +Deno.test(function matrixScale3dWithOriginSelf() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.scale3dSelf(2, 4, 5, 6); + assertStrictEquals( + matrix, + matrix2, + ); + assertEquals( + matrix, + // deno-fmt-ignore + DOMMatrix.fromMatrix({ + m11: 1 * 2, m21: 2 * 2, m31: 3 * 2, m41: -28, + m12: 5 * 2, m22: 6 * 2, m32: 7 * 2, m42: -84, + m13: 9 * 2, m23: 10 * 2, m33: 11 * 2, m43: -140, + m14: 13 * 2, m24: 14 * 2, m34: 15 * 2, m44: -196, + }), + ); +}); + +Deno.test(function matrixRotate() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + // deno-fmt-ignore + const expect = { + m11: -3, m21: -2, m31: -1, m41: 4, + m12: -7, m22: -6, m32: -5, m42: 8, + m13: -11, m23: -10, m33: -9, m43: 12, + m14: -15, m24: -14, m34: -13, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.rotate(0, 90, 180); + assertEquals( + matrix, + DOMMatrix.fromMatrix(init), + ); + for ( + const [key, value] of Object.entries(expect) as [ + keyof typeof expect, + number, + ][] + ) { + assertAlmostEquals( + matrix2[key], + value, + ); + } +}); + +Deno.test(function matrixRotateSelf() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + // deno-fmt-ignore + const expect = { + m11: -3, m21: -2, m31: -1, m41: 4, + m12: -7, m22: -6, m32: -5, m42: 8, + m13: -11, m23: -10, m33: -9, m43: 12, + m14: -15, m24: -14, m34: -13, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.rotateSelf(0, 90, 180); + assertStrictEquals( + matrix, + matrix2, + ); + for ( + const [key, value] of Object.entries(expect) as [ + keyof typeof expect, + number, + ][] + ) { + assertAlmostEquals( + matrix[key], + value, + ); + } +}); + +Deno.test(function matrixRotateFromVector() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + // deno-fmt-ignore + const expect = { + m11: 2.121320343559643, m21: 0.7071067811865476, m31: 3, m41: 4, + m12: 7.778174593052023, m22: 0.7071067811865479, m32: 7, m42: 8, + m13: 13.435028842544405, m23: 0.7071067811865470, m33: 11, m43: 12, + m14: 19.091883092036785, m24: 0.7071067811865461, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.rotateFromVector(1, 1); + assertEquals( + matrix, + DOMMatrix.fromMatrix(init), + ); + for ( + const [key, value] of Object.entries(expect) as [ + keyof typeof expect, + number, + ][] + ) { + assertAlmostEquals( + matrix2[key], + value, + ); + } +}); + +Deno.test(function matrixRotateFromVectorSelf() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + // deno-fmt-ignore + const expect = { + m11: 2.121320343559643, m21: 0.7071067811865476, m31: 3, m41: 4, + m12: 7.778174593052023, m22: 0.7071067811865479, m32: 7, m42: 8, + m13: 13.435028842544405, m23: 0.7071067811865470, m33: 11, m43: 12, + m14: 19.091883092036785, m24: 0.7071067811865461, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.rotateFromVectorSelf(1, 1); + assertStrictEquals( + matrix, + matrix2, + ); + for ( + const [key, value] of Object.entries(expect) as [ + keyof typeof expect, + number, + ][] + ) { + assertAlmostEquals( + matrix[key], + value, + ); + } +}); + +Deno.test(function matrixRotateAxisAngle() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + // deno-fmt-ignore + const expect = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5.228294835332138, m22: 4.854398120227125, m32: 7.6876363080712045, m42: 8, + m13: 9.456589670664275, m23: 7.708796240454249, m33: 12.3752726161424090, m43: 12, + m14: 13.684884505996411, m24: 10.563194360681376, m34: 17.0629089242136120, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.rotateAxisAngle(1, 2, 3, 30); + assertEquals( + matrix, + DOMMatrix.fromMatrix(init), + ); + for ( + const [key, value] of Object.entries(expect) as [ + keyof typeof expect, + number, + ][] + ) { + assertAlmostEquals( + matrix2[key], + value, + ); + } +}); + +Deno.test(function matrixRotateAxisAngleSelf() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + // deno-fmt-ignore + const expect = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5.228294835332138, m22: 4.854398120227125, m32: 7.6876363080712045, m42: 8, + m13: 9.456589670664275, m23: 7.708796240454249, m33: 12.3752726161424090, m43: 12, + m14: 13.684884505996411, m24: 10.563194360681376, m34: 17.0629089242136120, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.rotateAxisAngleSelf(1, 2, 3, 30); + assertStrictEquals( + matrix, + matrix2, + ); + for ( + const [key, value] of Object.entries(expect) as [ + keyof typeof expect, + number, + ][] + ) { + assertAlmostEquals( + matrix[key], + value, + ); + } +}); + +Deno.test(function matrixSkewX() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + // deno-fmt-ignore + const expect = { + m11: 1, m21: 2.5773502691896257, m31: 3, m41: 4, + m12: 5, m22: 8.8867513459481270, m32: 7, m42: 8, + m13: 9, m23: 15.1961524227066300, m33: 11, m43: 12, + m14: 13, m24: 21.5055534994651330, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.skewX(30); + assertEquals( + matrix, + DOMMatrix.fromMatrix(init), + ); + for ( + const [key, value] of Object.entries(expect) as [ + keyof typeof expect, + number, + ][] + ) { + assertAlmostEquals( + matrix2[key], + value, + ); + } +}); + +Deno.test(function matrixSkewXSelf() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + // deno-fmt-ignore + const expect = { + m11: 1, m21: 2.5773502691896257, m31: 3, m41: 4, + m12: 5, m22: 8.8867513459481270, m32: 7, m42: 8, + m13: 9, m23: 15.1961524227066300, m33: 11, m43: 12, + m14: 13, m24: 21.5055534994651330, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.skewXSelf(30); + assertStrictEquals( + matrix, + matrix2, + ); + for ( + const [key, value] of Object.entries(expect) as [ + keyof typeof expect, + number, + ][] + ) { + assertAlmostEquals( + matrix[key], + value, + ); + } +}); + +Deno.test(function matrixSkewY() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + // deno-fmt-ignore + const expect = { + m11: 2.1547005383792515, m21: 2, m31: 3, m41: 4, + m12: 8.4641016151377530, m22: 6, m32: 7, m42: 8, + m13: 14.7735026918962560, m23: 10, m33: 11, m43: 12, + m14: 21.0829037686547600, m24: 14, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.skewY(30); + assertEquals( + matrix, + DOMMatrix.fromMatrix(init), + ); + for ( + const [key, value] of Object.entries(expect) as [ + keyof typeof expect, + number, + ][] + ) { + assertAlmostEquals( + matrix2[key], + value, + ); + } +}); + +Deno.test(function matrixSkewYSelf() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + // deno-fmt-ignore + const expect = { + m11: 2.1547005383792515, m21: 2, m31: 3, m41: 4, + m12: 8.4641016151377530, m22: 6, m32: 7, m42: 8, + m13: 14.7735026918962560, m23: 10, m33: 11, m43: 12, + m14: 21.0829037686547600, m24: 14, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.skewYSelf(30); + assertStrictEquals( + matrix, + matrix2, + ); + for ( + const [key, value] of Object.entries(expect) as [ + keyof typeof expect, + number, + ][] + ) { + assertAlmostEquals( + matrix[key], + value, + ); + } +}); + +Deno.test(function matrixMultiply() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.multiply({ m11: 1, m22: 2, m33: 3, m44: 4 }); + assertEquals( + matrix, + DOMMatrix.fromMatrix(init), + ); + assertEquals( + matrix2, + // deno-fmt-ignore + DOMMatrix.fromMatrix({ + m11: 1 * 1, m21: 2 * 2, m31: 3 * 3, m41: 4 * 4, + m12: 5 * 1, m22: 6 * 2, m32: 7 * 3, m42: 8 * 4, + m13: 9 * 1, m23: 10 * 2, m33: 11 * 3, m43: 12 * 4, + m14: 13 * 1, m24: 14 * 2, m34: 15 * 3, m44: 16 * 4, + }), + ); +}); + +Deno.test(function matrixMultiplySelf() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.multiplySelf({ m11: 1, m22: 2, m33: 3, m44: 4 }); + assertStrictEquals( + matrix, + matrix2, + ); + assertEquals( + matrix, + // deno-fmt-ignore + DOMMatrix.fromMatrix({ + m11: 1 * 1, m21: 2 * 2, m31: 3 * 3, m41: 4 * 4, + m12: 5 * 1, m22: 6 * 2, m32: 7 * 3, m42: 8 * 4, + m13: 9 * 1, m23: 10 * 2, m33: 11 * 3, m43: 12 * 4, + m14: 13 * 1, m24: 14 * 2, m34: 15 * 3, m44: 16 * 4, + }), + ); +}); + +Deno.test(function matrixMultiplySelfWithSelf() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.multiplySelf(matrix); + assertStrictEquals( + matrix, + matrix2, + ); + assertEquals( + matrix, + // deno-fmt-ignore + DOMMatrix.fromMatrix({ + m11: 90, m21: 100, m31: 110, m41: 120, + m12: 202, m22: 228, m32: 254, m42: 280, + m13: 314, m23: 356, m33: 398, m43: 440, + m14: 426, m24: 484, m34: 542, m44: 600, + }), + ); +}); + +Deno.test(function matrixPreMultiplySelf() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.preMultiplySelf({ m11: 1, m22: 2, m33: 3, m44: 4 }); + assertStrictEquals( + matrix, + matrix2, + ); + assertEquals( + matrix, + // deno-fmt-ignore + DOMMatrix.fromMatrix({ + m11: 1 * 1, m21: 2 * 1, m31: 3 * 1, m41: 4 * 1, + m12: 5 * 2, m22: 6 * 2, m32: 7 * 2, m42: 8 * 2, + m13: 9 * 3, m23: 10 * 3, m33: 11 * 3, m43: 12 * 3, + m14: 13 * 4, m24: 14 * 4, m34: 15 * 4, m44: 16 * 4, + }), + ); +}); + +Deno.test(function matrixPreMultiplySelfWithSelf() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.preMultiplySelf(matrix); + assertStrictEquals( + matrix, + matrix2, + ); + assertEquals( + matrix, + // deno-fmt-ignore + DOMMatrix.fromMatrix({ + m11: 90, m21: 100, m31: 110, m41: 120, + m12: 202, m22: 228, m32: 254, m42: 280, + m13: 314, m23: 356, m33: 398, m43: 440, + m14: 426, m24: 484, m34: 542, m44: 600, + }), + ); +}); + +Deno.test(function matrixFlipX() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.flipX(); + assertEquals( + matrix, + DOMMatrix.fromMatrix(init), + ); + assertEquals( + matrix2, + // deno-fmt-ignore + DOMMatrix.fromMatrix({ + m11: -1, m21: 2, m31: 3, m41: 4, + m12: -5, m22: 6, m32: 7, m42: 8, + m13: -9, m23: 10, m33: 11, m43: 12, + m14: -13, m24: 14, m34: 15, m44: 16, + }), + ); +}); + +Deno.test(function matrixFlipY() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 5, m22: 6, m32: 7, m42: 8, + m13: 9, m23: 10, m33: 11, m43: 12, + m14: 13, m24: 14, m34: 15, m44: 16, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.flipY(); + assertEquals( + matrix, + DOMMatrix.fromMatrix(init), + ); + assertEquals( + matrix2, + // deno-fmt-ignore + DOMMatrix.fromMatrix({ + m11: 1, m21: -2, m31: 3, m41: 4, + m12: 5, m22: -6, m32: 7, m42: 8, + m13: 9, m23: -10, m33: 11, m43: 12, + m14: 13, m24: -14, m34: 15, m44: 16, + }), + ); +}); + +Deno.test(function matrixInverse() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 0, m22: 1, m32: 7, m42: 8, + m13: 0, m23: 0, m33: 1, m43: 12, + m14: 0, m24: 0, m34: 0, m44: 1, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.inverse(); + assertEquals( + matrix, + DOMMatrix.fromMatrix(init), + ); + assertEquals( + matrix2, + // deno-fmt-ignore + DOMMatrix.fromMatrix({ + m11: 1, m21: -2, m31: 11, m41: -120, + m12: 0, m22: 1, m32: -7, m42: 76, + m13: 0, m23: 0, m33: 1, m43: -12, + m14: 0, m24: 0, m34: 0, m44: 1, + }), + ); +}); + +Deno.test(function matrixInvertSelf() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 3, m41: 4, + m12: 0, m22: 1, m32: 7, m42: 8, + m13: 0, m23: 0, m33: 1, m43: 12, + m14: 0, m24: 0, m34: 0, m44: 1, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.invertSelf(); + assertStrictEquals( + matrix, + matrix2, + ); + assertEquals( + matrix, + // deno-fmt-ignore + DOMMatrix.fromMatrix({ + m11: 1, m21: -2, m31: 11, m41: -120, + m12: 0, m22: 1, m32: -7, m42: 76, + m13: 0, m23: 0, m33: 1, m43: -12, + m14: 0, m24: 0, m34: 0, m44: 1, + }), + ); +}); + +Deno.test(function matrixInverse2D() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 0, m41: 4, + m12: 0, m22: 1, m32: 0, m42: 8, + m13: 0, m23: 0, m33: 1, m43: 0, + m14: 0, m24: 0, m34: 0, m44: 1, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.inverse(); + assertEquals( + matrix, + DOMMatrix.fromMatrix(init), + ); + assertEquals( + matrix2, + // deno-fmt-ignore + DOMMatrix.fromMatrix({ + m11: 1, m21: -2, m31: 0, m41: 12, + m12: 0, m22: 1, m32: 0, m42: -8, + m13: 0, m23: 0, m33: 1, m43: 0, + m14: 0, m24: 0, m34: 0, m44: 1, + }), + ); +}); + +Deno.test(function matrixInvert2DSelf() { + // deno-fmt-ignore + const init = { + m11: 1, m21: 2, m31: 0, m41: 4, + m12: 0, m22: 1, m32: 0, m42: 8, + m13: 0, m23: 0, m33: 1, m43: 0, + m14: 0, m24: 0, m34: 0, m44: 1, + }; + const matrix = DOMMatrix.fromMatrix(init); + const matrix2 = matrix.invertSelf(); + assertStrictEquals( + matrix, + matrix2, + ); + assertEquals( + matrix, + // deno-fmt-ignore + DOMMatrix.fromMatrix({ + m11: 1, m21: -2, m31: 0, m41: 12, + m12: 0, m22: 1, m32: 0, m42: -8, + m13: 0, m23: 0, m33: 1, m43: 0, + m14: 0, m24: 0, m34: 0, m44: 1, + }), + ); +}); + +Deno.test(function prototypeOverwrite() { + const point = new DOMPointReadOnly(); + Object.setPrototypeOf(point, DOMPoint.prototype); + assertThrows( + () => { + // @ts-ignore test + point.x = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + point.y = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + point.z = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + point.w = 1; + }, + TypeError, + "Illegal invocation", + ); + + const rect = new DOMRectReadOnly(); + Object.setPrototypeOf(rect, DOMRect.prototype); + assertThrows( + () => { + // @ts-ignore test + rect.x = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + rect.y = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + rect.width = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + rect.height = 1; + }, + TypeError, + "Illegal invocation", + ); + + const matrix = new DOMMatrixReadOnly(); + Object.setPrototypeOf(matrix, DOMMatrix.prototype); + assertThrows( + () => { + // @ts-ignore test + matrix.a = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + matrix.b = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + matrix.c = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + matrix.d = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + matrix.e = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + matrix.f = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + matrix.m11 = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + matrix.m12 = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + matrix.m13 = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + matrix.m14 = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + matrix.m21 = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + matrix.m22 = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + matrix.m23 = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + matrix.m24 = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + matrix.m31 = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + matrix.m32 = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + matrix.m33 = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + matrix.m34 = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + matrix.m41 = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + matrix.m42 = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + matrix.m43 = 1; + }, + TypeError, + "Illegal invocation", + ); + assertThrows( + () => { + // @ts-ignore test + matrix.m44 = 1; + }, + TypeError, + "Illegal invocation", + ); +}); diff --git a/tests/unit/test_util.ts b/tests/unit/test_util.ts index 6e7865ea7a43d4..c4fa660b986e69 100644 --- a/tests/unit/test_util.ts +++ b/tests/unit/test_util.ts @@ -6,6 +6,7 @@ export { colors }; import { join, resolve } from "@std/path"; export { assert, + assertAlmostEquals, assertEquals, assertFalse, AssertionError, diff --git a/tests/wpt/runner/expectation.json b/tests/wpt/runner/expectation.json index 6025ce42a46d81..bafb919a70df77 100644 --- a/tests/wpt/runner/expectation.json +++ b/tests/wpt/runner/expectation.json @@ -14231,12 +14231,215 @@ "eventsource-constructor-stringify.window.html": false, "eventsource-cross-origin.window.html": false, "eventsource-reconnect.window.html": false, - "request-status-error.window.html": false, "eventsource-constructor-empty-url.any.serviceworker.html": false, "eventsource-constructor-empty-url.any.sharedworker.html": false, "eventsource-constructor-url-bogus.any.serviceworker.html": false, "eventsource-constructor-url-bogus.any.sharedworker.html": false, "request-credentials.window.html": false, "request-redirect.window.html": false + }, + "css": { + "geometry": { + "DOMMatrix-001.html": [ + "new DOMMatrix(\"none\")", + "new DOMMatrix(\" none\")", + "new DOMMatrix(\"none \")", + "new DOMMatrix(\"NONE\")", + "new DOMMatrix(\"none/**/\")", + "new DOMMatrix(\"/**/none\")", + "new DOMMatrix(\"scale(2) translateX(5px) translateY(5px)\")", + "new DOMMatrix(\"scale(2, 2) translateX(5px) translateY(5px)\")", + "new DOMMatrix(\"scale(2)translateX(5px)translateY(5px)\")", + "new DOMMatrix(\"scale(2) translateX(calc(2 * 2.5px)) translateY(5px)\")", + "new DOMMatrix(\"scale(2) translateX(5px) translateY(5px) rotate(5deg) rotate(-5deg)\")", + "new DOMMatrix(\"translateX (5px)\")", + "new DOMMatrix(\"scale(2 2) translateX(5) translateY(5)\")", + "new DOMMatrix(\"scale(2, 2), translateX(5) ,translateY(5)\")", + "new DOMMatrix(\"translateX(5em)\")", + "new DOMMatrix(\"translateX(5ex)\")", + "new DOMMatrix(\"translateX(5ch)\")", + "new DOMMatrix(\"translateX(5rem)\")", + "new DOMMatrix(\"translateX(5cqw)\")", + "new DOMMatrix(\"translateX(5cqh)\")", + "new DOMMatrix(\"translateX(5cqb)\")", + "new DOMMatrix(\"translateX(5cqi)\")", + "new DOMMatrix(\"translateX(5cqmin)\")", + "new DOMMatrix(\"translateX(5cqmax)\")", + "new DOMMatrix(\"translateX(5vw)\")", + "new DOMMatrix(\"translateX(5vh)\")", + "new DOMMatrix(\"translateX(5vb)\")", + "new DOMMatrix(\"translateX(5vi)\")", + "new DOMMatrix(\"translateX(5vmin)\")", + "new DOMMatrix(\"translateX(5vmax)\")", + "new DOMMatrix(\"translateX(5%)\")", + "new DOMMatrix(\"rotate(5)\")", + "new DOMMatrix(\"rotate(5, 5, 5)\")", + "new DOMMatrix(\"rotate(5, 5px, 5px)\")", + "new DOMMatrix(\"rotate(5deg, 5px, 5px)\")", + "new DOMMatrix(\" \")", + "new DOMMatrix(\"/**/\")", + "new DOMMatrix(\"\\0\")", + "new DOMMatrix(\";\")", + "new DOMMatrix(\"none;\")", + "new DOMMatrix(\"null\")", + "new DOMMatrix(null)", + "new DOMMatrix(\"undefined\")", + "new DOMMatrix(\"inherit\")", + "new DOMMatrix(\"initial\")", + "new DOMMatrix(\"unset\")", + "new DOMMatrix(\"scale(2, 2), translateX(5px) translateY(5px)\")", + "new DOMMatrixReadOnly(\"none\")", + "new DOMMatrixReadOnly(\" none\")", + "new DOMMatrixReadOnly(\"none \")", + "new DOMMatrixReadOnly(\"NONE\")", + "new DOMMatrixReadOnly(\"none/**/\")", + "new DOMMatrixReadOnly(\"/**/none\")", + "new DOMMatrixReadOnly(\"scale(2) translateX(5px) translateY(5px)\")", + "new DOMMatrixReadOnly(\"scale(2, 2) translateX(5px) translateY(5px)\")", + "new DOMMatrixReadOnly(\"scale(2)translateX(5px)translateY(5px)\")", + "new DOMMatrixReadOnly(\"scale(2) translateX(calc(2 * 2.5px)) translateY(5px)\")", + "new DOMMatrixReadOnly(\"scale(2) translateX(5px) translateY(5px) rotate(5deg) rotate(-5deg)\")", + "new DOMMatrixReadOnly(\"translateX (5px)\")", + "new DOMMatrixReadOnly(\"scale(2 2) translateX(5) translateY(5)\")", + "new DOMMatrixReadOnly(\"scale(2, 2), translateX(5) ,translateY(5)\")", + "new DOMMatrixReadOnly(\"translateX(5em)\")", + "new DOMMatrixReadOnly(\"translateX(5ex)\")", + "new DOMMatrixReadOnly(\"translateX(5ch)\")", + "new DOMMatrixReadOnly(\"translateX(5rem)\")", + "new DOMMatrixReadOnly(\"translateX(5cqw)\")", + "new DOMMatrixReadOnly(\"translateX(5cqh)\")", + "new DOMMatrixReadOnly(\"translateX(5cqb)\")", + "new DOMMatrixReadOnly(\"translateX(5cqi)\")", + "new DOMMatrixReadOnly(\"translateX(5cqmin)\")", + "new DOMMatrixReadOnly(\"translateX(5cqmax)\")", + "new DOMMatrixReadOnly(\"translateX(5vw)\")", + "new DOMMatrixReadOnly(\"translateX(5vh)\")", + "new DOMMatrixReadOnly(\"translateX(5vb)\")", + "new DOMMatrixReadOnly(\"translateX(5vi)\")", + "new DOMMatrixReadOnly(\"translateX(5vmin)\")", + "new DOMMatrixReadOnly(\"translateX(5vmax)\")", + "new DOMMatrixReadOnly(\"translateX(5%)\")", + "new DOMMatrixReadOnly(\"rotate(5)\")", + "new DOMMatrixReadOnly(\"rotate(5, 5, 5)\")", + "new DOMMatrixReadOnly(\"rotate(5, 5px, 5px)\")", + "new DOMMatrixReadOnly(\"rotate(5deg, 5px, 5px)\")", + "new DOMMatrixReadOnly(\" \")", + "new DOMMatrixReadOnly(\"/**/\")", + "new DOMMatrixReadOnly(\"\\0\")", + "new DOMMatrixReadOnly(\";\")", + "new DOMMatrixReadOnly(\"none;\")", + "new DOMMatrixReadOnly(\"null\")", + "new DOMMatrixReadOnly(null)", + "new DOMMatrixReadOnly(\"undefined\")", + "new DOMMatrixReadOnly(\"inherit\")", + "new DOMMatrixReadOnly(\"initial\")", + "new DOMMatrixReadOnly(\"unset\")", + "new DOMMatrixReadOnly(\"scale(2, 2), translateX(5px) translateY(5px)\")" + ], + "DOMMatrix-002.html": true, + "DOMMatrix-003.html": true, + "DOMMatrix-a-f-alias.html": true, + "DOMMatrix-attributes.html": true, + "DOMMatrix-css-string.worker.html": true, + "DOMMatrix-invert-invertible.html": true, + "DOMMatrix-invert-non-invertible.html": true, + "DOMMatrix-invert-preserves-2d.html": true, + "DOMMatrix-newobject.html": true, + "DOMMatrix-stringifier.html": [ + "WebKitCSSMatrix stringifier: identity (2d)", + "WebKitCSSMatrix stringifier: identity (3d)", + "WebKitCSSMatrix stringifier: NaN (2d)", + "WebKitCSSMatrix stringifier: NaN (3d)", + "WebKitCSSMatrix stringifier: Infinity (2d)", + "WebKitCSSMatrix stringifier: Infinity (3d)", + "WebKitCSSMatrix stringifier: -Infinity (2d)", + "WebKitCSSMatrix stringifier: -Infinity (3d)", + "WebKitCSSMatrix stringifier: 1/3 (2d)", + "WebKitCSSMatrix stringifier: 1/3 (3d)", + "WebKitCSSMatrix stringifier: 1/300000 (2d)", + "WebKitCSSMatrix stringifier: 1/300000 (3d)", + "WebKitCSSMatrix stringifier: 1/300000000 (2d)", + "WebKitCSSMatrix stringifier: 1/300000000 (3d)", + "WebKitCSSMatrix stringifier: 100000 + (1/3) (2d)", + "WebKitCSSMatrix stringifier: 100000 + (1/3) (3d)", + "WebKitCSSMatrix stringifier: Math.pow(2, 53) + 1 (2d)", + "WebKitCSSMatrix stringifier: Math.pow(2, 53) + 1 (3d)", + "WebKitCSSMatrix stringifier: Math.pow(2, 53) + 2 (2d)", + "WebKitCSSMatrix stringifier: Math.pow(2, 53) + 2 (3d)", + "WebKitCSSMatrix stringifier: Number.MAX_VALUE (2d)", + "WebKitCSSMatrix stringifier: Number.MAX_VALUE (3d)", + "WebKitCSSMatrix stringifier: Number.MIN_VALUE (2d)", + "WebKitCSSMatrix stringifier: Number.MIN_VALUE (3d)", + "WebKitCSSMatrix stringifier: throwing getters (2d)", + "WebKitCSSMatrix stringifier: throwing getters (3d)" + ], + "DOMMatrix2DInit-validate-fixup.html": false, + "DOMMatrixInit-validate-fixup.html": true, + "DOMPoint-001.html": true, + "DOMPoint-002.html": true, + "DOMQuad-001.html": true, + "DOMQuad-002.html": true, + "DOMQuad-nan.html": true, + "DOMRect-001.html": true, + "DOMRect-002.html": true, + "DOMRect-nan.html": true, + "DOMRectList.html": false, + "WebKitCSSMatrix.html": false, + "WebKitCSSMatrix.worker.html": true, + "historical.html": true, + "idlharness.any.html": [ + "DOMPointReadOnly interface: existence and properties of interface object", + "DOMPoint interface: existence and properties of interface object", + "DOMRectReadOnly interface: existence and properties of interface object", + "DOMRect interface: existence and properties of interface object", + "DOMRectList interface: existence and properties of interface object", + "DOMRectList interface object length", + "DOMRectList interface object name", + "DOMRectList interface: existence and properties of interface prototype object", + "DOMRectList interface: existence and properties of interface prototype object's \"constructor\" property", + "DOMRectList interface: existence and properties of interface prototype object's @@unscopables property", + "DOMRectList interface: attribute length", + "DOMRectList interface: operation item(unsigned long)", + "DOMQuad interface: existence and properties of interface object", + "DOMMatrixReadOnly interface: existence and properties of interface object", + "DOMMatrix interface: existence and properties of interface object" + ], + "idlharness.any.worker.html": [ + "DOMPointReadOnly interface: existence and properties of interface object", + "DOMPoint interface: existence and properties of interface object", + "DOMRectReadOnly interface: existence and properties of interface object", + "DOMRect interface: existence and properties of interface object", + "DOMQuad interface: existence and properties of interface object", + "DOMMatrixReadOnly interface: existence and properties of interface object", + "DOMMatrix interface: existence and properties of interface object" + ], + "spec-examples.html": true, + "structured-serialization.html": [ + "DOMPointReadOnly clone: basic", + "DOMPointReadOnly clone: custom property", + "DOMPointReadOnly clone: non-initial values", + "DOMPoint clone: basic", + "DOMPoint clone: custom property", + "DOMPoint clone: non-initial values", + "DOMRectReadOnly clone: basic", + "DOMRectReadOnly clone: custom property", + "DOMRectReadOnly clone: non-initial values", + "DOMRect clone: basic", + "DOMRect clone: custom property", + "DOMRect clone: non-initial values", + "DOMQuad clone: basic", + "DOMQuad clone: custom property", + "DOMQuad clone: non-initial values", + "DOMMatrixReadOnly clone: basic", + "DOMMatrixReadOnly clone: custom property", + "DOMMatrixReadOnly clone: non-initial values (2d)", + "DOMMatrixReadOnly clone: non-initial values (3d)", + "DOMMatrix clone: basic", + "DOMMatrix clone: custom property", + "DOMMatrix clone: non-initial values (2d)", + "DOMMatrix clone: non-initial values (3d)", + "DOMRectList clone" + ] + } } } diff --git a/tools/core_import_map.json b/tools/core_import_map.json index d38221eb4c8a04..00c47a030791c1 100644 --- a/tools/core_import_map.json +++ b/tools/core_import_map.json @@ -17,6 +17,8 @@ "ext:deno_fetch/26_fetch.js": "../ext/fetch/26_fetch.js", "ext:deno_ffi/00_ffi.js": "../ext/ffi/00_ffi.js", "ext:deno_fs/30_fs.js": "../ext/fs/30_fs.js", + "ext:deno_geometry/00_init.js": "../ext/geometry/00_init.js", + "ext:deno_geometry/01_geometry.js": "../ext/geometry/01_geometry.js", "ext:deno_http/00_serve.ts": "../ext/http/00_serve.ts", "ext:deno_http/01_http.js": "../ext/http/01_http.js", "ext:deno_io/12_io.js": "../ext/io/12_io.js", diff --git a/tools/jsdoc_checker.js b/tools/jsdoc_checker.js index 034782136c13e7..ecac03c8948134 100755 --- a/tools/jsdoc_checker.js +++ b/tools/jsdoc_checker.js @@ -13,6 +13,7 @@ const libs = [ join(ROOT_PATH, "ext/webstorage/lib.deno_webstorage.d.ts"), join(ROOT_PATH, "ext/canvas/lib.deno_canvas.d.ts"), join(ROOT_PATH, "ext/crypto/lib.deno_crypto.d.ts"), + join(ROOT_PATH, "ext/geometry/lib.deno_geometry.d.ts"), join(ROOT_PATH, "ext/net/lib.deno_net.d.ts"), join(ROOT_PATH, "cli/tsc/dts/lib.deno.ns.d.ts"), join(ROOT_PATH, "cli/tsc/dts/lib.deno.shared_globals.d.ts"), From 18e451d8452e9e98fd573c7361d9e4d851466cf0 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Thu, 2 Jan 2025 22:13:04 +0900 Subject: [PATCH 02/24] migrate to op2++ --- ext/geometry/00_init.js | 2 +- ext/geometry/01_geometry.js | 817 +++++++----------- ext/geometry/Cargo.toml | 2 +- ext/geometry/README.md | 30 +- ext/geometry/lib.deno_geometry.d.ts | 2 +- ext/geometry/lib.rs | 1222 ++++++++++++++++++++++----- tests/unit/geometry_test.ts | 2 +- 7 files changed, 1332 insertions(+), 745 deletions(-) diff --git a/ext/geometry/00_init.js b/ext/geometry/00_init.js index d1b89bac5cadc6..ea5e20870f2c87 100644 --- a/ext/geometry/00_init.js +++ b/ext/geometry/00_init.js @@ -1,4 +1,4 @@ -// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. +// Copyright 2018-2025 the Deno authors. MIT license. import { core } from "ext:core/mod.js"; diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 8b5957ee4e2610..4a9595d85769e0 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -1,30 +1,13 @@ -// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. +// Copyright 2018-2025 the Deno authors. MIT license. import { primordials } from "ext:core/mod.js"; -import { - op_geometry_flip_x_self, - op_geometry_flip_y_self, - op_geometry_invert_2d_self, - op_geometry_invert_self, - op_geometry_multiply, - op_geometry_multiply_self, - op_geometry_premultiply_point_self, - op_geometry_premultiply_self, - op_geometry_rotate_axis_angle_self, - op_geometry_rotate_from_vector_self, - op_geometry_rotate_self, - op_geometry_scale_self, - op_geometry_scale_with_origin_self, - op_geometry_skew_self, - op_geometry_translate_self, -} from "ext:core/ops"; +import { Matrix, op_create_matrix_identity, Point, Rect } from "ext:core/ops"; const { ArrayPrototypeJoin, Float32Array, Float64Array, MathMax, MathMin, - NumberIsFinite, ObjectDefineProperty, ObjectIs, ObjectPrototypeIsPrototypeOf, @@ -32,7 +15,6 @@ const { SymbolFor, SymbolIterator, TypeError, - TypedArrayPrototypeEvery, TypedArrayPrototypeJoin, } = primordials; @@ -232,7 +214,7 @@ webidl.converters.DOMMatrixInit = webidl.createDictionaryConverter( ], ); -const _raw = Symbol("[[raw]]"); +const _inner = Symbol("[[inner]]"); // Property to prevent writing values when an immutable instance is changed to // a mutable instance by Object.setPrototypeOf // TODO(petamoriken): Implementing resistance to Object.setPrototypeOf in the WebIDL layer @@ -241,20 +223,19 @@ const _brand = webidl.brand; class DOMPointReadOnly { [_writable] = false; - /** @type {Float64Array} */ - [_raw]; + [_inner]; constructor(x = 0, y = 0, z = 0, w = 1) { - this[_raw] = new Float64Array([ + this[_inner] = new Point( webidl.converters["unrestricted double"](x), webidl.converters["unrestricted double"](y), webidl.converters["unrestricted double"](z), webidl.converters["unrestricted double"](w), - ]); + ); this[_brand] = _brand; } - static fromPoint(other = {}) { + static fromPoint(other = { __proto__: null }) { other = webidl.converters.DOMPointInit( other, "Failed to execute 'DOMPointReadOnly.fromPoint'", @@ -262,61 +243,62 @@ class DOMPointReadOnly { ); const point = webidl.createBranded(DOMPointReadOnly); point[_writable] = false; - point[_raw] = new Float64Array([ + point[_inner] = new Point( other.x, other.y, other.z, other.w, - ]); + ); return point; } get x() { webidl.assertBranded(this, DOMPointReadOnlyPrototype); - return this[_raw][0]; + return this[_inner].x; } get y() { webidl.assertBranded(this, DOMPointReadOnlyPrototype); - return this[_raw][1]; + return this[_inner].y; } get z() { webidl.assertBranded(this, DOMPointReadOnlyPrototype); - return this[_raw][2]; + return this[_inner].z; } get w() { webidl.assertBranded(this, DOMPointReadOnlyPrototype); - return this[_raw][3]; + return this[_inner].w; } - matrixTransform(matrix = {}) { + matrixTransform(matrix = { __proto__: null }) { webidl.assertBranded(this, DOMPointReadOnlyPrototype); const prefix = "Failed to execute 'matrixTransform' on 'DOMPointReadOnly'"; - if (!ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, matrix)) { + if ( + other === null || + !ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, matrix) + ) { const _matrix = webidl.converters.DOMMatrixInit( matrix, prefix, "Argument 1", ); validateAndFixupMatrixDictionary(_matrix, prefix); - matrix = {}; + matrix = { __proto__: null }; initMatrixFromDictonary(matrix, _matrix); } - const point = webidl.createBranded(DOMPoint); point[_writable] = true; - point[_raw] = new Float64Array(this[_raw]); - op_geometry_premultiply_point_self(matrix[_raw], point[_raw]); + point[_inner] = this[_inner].matrixTransform(matrix[_inner]); return point; } toJSON() { webidl.assertBranded(this, DOMPointReadOnlyPrototype); - const raw = this[_raw]; + const inner = this[_inner]; return { - x: raw[0], - y: raw[1], - z: raw[2], - w: raw[3], + x: inner.x, + y: inner.y, + z: inner.z, + w: inner.w, }; } @@ -343,7 +325,7 @@ const DOMPointReadOnlyPrototype = DOMPointReadOnly.prototype; class DOMPoint extends DOMPointReadOnly { [_writable] = true; - static fromPoint(other = {}) { + static fromPoint(other = { __proto__: null }) { other = webidl.converters.DOMPointInit( other, "Failed to execute 'DOMPoint.fromPoint'", @@ -351,50 +333,50 @@ class DOMPoint extends DOMPointReadOnly { ); const point = webidl.createBranded(DOMPoint); point[_writable] = true; - point[_raw] = new Float64Array([ + point[_inner] = new Point( other.x, other.y, other.z, other.w, - ]); + ); return point; } get x() { webidl.assertBranded(this, DOMPointPrototype); - return this[_raw][0]; + return this[_inner].x; } set x(value) { webidl.assertBranded(this, DOMPointPrototype); assertWritable(this); - this[_raw][0] = webidl.converters["unrestricted double"](value); + this[_inner].x = webidl.converters["unrestricted double"](value); } get y() { webidl.assertBranded(this, DOMPointPrototype); - return this[_raw][1]; + return this[_inner].y; } set y(value) { webidl.assertBranded(this, DOMPointPrototype); assertWritable(this); - this[_raw][1] = webidl.converters["unrestricted double"](value); + this[_inner].y = webidl.converters["unrestricted double"](value); } get z() { webidl.assertBranded(this, DOMPointPrototype); - return this[_raw][2]; + return this[_inner].x; } set z(value) { webidl.assertBranded(this, DOMPointPrototype); assertWritable(this); - this[_raw][2] = webidl.converters["unrestricted double"](value); + this[_inner].z = webidl.converters["unrestricted double"](value); } get w() { webidl.assertBranded(this, DOMPointPrototype); - return this[_raw][3]; + return this[_inner].w; } set w(value) { webidl.assertBranded(this, DOMPointPrototype); assertWritable(this); - this[_raw][3] = webidl.converters["unrestricted double"](value); + this[_inner].x = webidl.converters["unrestricted double"](value); } [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { @@ -419,20 +401,19 @@ const DOMPointPrototype = DOMPoint.prototype; class DOMRectReadOnly { [_writable] = false; - /** @type {Float64Array} */ - [_raw]; + [_inner]; constructor(x = 0, y = 0, width = 0, height = 0) { - this[_raw] = new Float64Array([ + this[_inner] = new Rect( webidl.converters["unrestricted double"](x), webidl.converters["unrestricted double"](y), webidl.converters["unrestricted double"](width), webidl.converters["unrestricted double"](height), - ]); + ); this[_brand] = _brand; } - static fromRect(other = {}) { + static fromRect(other = { __proto__: null }) { other = webidl.converters.DOMRectInit( other, "Failed to execute 'DOMRectReadOnly.fromRect'", @@ -440,64 +421,64 @@ class DOMRectReadOnly { ); const rect = webidl.createBranded(DOMRectReadOnly); rect[_writable] = false; - rect[_raw] = new Float64Array([ + rect[_inner] = new Rect( other.x, other.y, other.width, other.height, - ]); + ); return rect; } get x() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); - return this[_raw][0]; + return this[_inner].x; } get y() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); - return this[_raw][1]; + return this[_inner].y; } get width() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); - return this[_raw][2]; + return this[_inner].width; } get height() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); - return this[_raw][3]; + return this[_inner].height; } get top() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); - const raw = this[_raw]; - return MathMin(raw[1], raw[1] + raw[3]); + const { y, height } = this[_inner]; + return MathMin(y, y + height); } get right() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); - const raw = this[_raw]; - return MathMax(raw[0], raw[0] + raw[2]); + const { x, width } = this[_inner]; + return MathMax(x, x + width); } get bottom() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); - const raw = this[_raw]; - return MathMax(raw[1], raw[1] + raw[3]); + const { y, height } = this[_inner]; + return MathMax(y, y + height); } get left() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); - const raw = this[_raw]; - return MathMin(raw[0], raw[0] + raw[2]); + const { x, width } = this[_inner]; + return MathMin(x, x + width); } toJSON() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); - const raw = this[_raw]; + const { x, y, width, height } = this[_inner]; return { - x: raw[0], - y: raw[1], - width: raw[2], - height: raw[3], - top: MathMin(raw[1], raw[1] + raw[3]), - right: MathMax(raw[0], raw[0] + raw[2]), - bottom: MathMax(raw[1], raw[1] + raw[3]), - left: MathMin(raw[0], raw[0] + raw[2]), + x, + y, + width, + height, + top: MathMin(y, y + height), + right: MathMax(x, x + width), + bottom: MathMax(y, y + height), + left: MathMin(x, x + width), }; } @@ -528,7 +509,7 @@ const DOMRectReadOnlyPrototype = DOMRectReadOnly.prototype; class DOMRect extends DOMRectReadOnly { [_writable] = true; - static fromRect(other = {}) { + static fromRect(other = { __proto__: null }) { other = webidl.converters.DOMRectInit( other, "Failed to execute 'DOMRect.fromRect'", @@ -536,50 +517,50 @@ class DOMRect extends DOMRectReadOnly { ); const rect = webidl.createBranded(DOMRect); rect[_writable] = true; - rect[_raw] = new Float64Array([ + rect[_inner] = new Rect( other.x, other.y, other.width, other.height, - ]); + ); return rect; } get x() { webidl.assertBranded(this, DOMRectPrototype); - return this[_raw][0]; + return this[_inner].x; } set x(value) { webidl.assertBranded(this, DOMRectPrototype); assertWritable(this); - this[_raw][0] = webidl.converters["unrestricted double"](value); + this[_inner].x = webidl.converters["unrestricted double"](value); } get y() { webidl.assertBranded(this, DOMRectPrototype); - return this[_raw][1]; + return this[_inner].y; } set y(value) { webidl.assertBranded(this, DOMRectPrototype); assertWritable(this); - this[_raw][1] = webidl.converters["unrestricted double"](value); + this[_inner].y = webidl.converters["unrestricted double"](value); } get width() { webidl.assertBranded(this, DOMRectPrototype); - return this[_raw][2]; + return this[_inner].width; } set width(value) { webidl.assertBranded(this, DOMRectPrototype); assertWritable(this); - this[_raw][2] = webidl.converters["unrestricted double"](value); + this[_inner].width = webidl.converters["unrestricted double"](value); } get height() { webidl.assertBranded(this, DOMRectPrototype); - return this[_raw][3]; + return this[_inner].height; } set height(value) { webidl.assertBranded(this, DOMRectPrototype); assertWritable(this); - this[_raw][3] = webidl.converters["unrestricted double"](value); + this[_inner].height = webidl.converters["unrestricted double"](value); } [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { @@ -621,7 +602,12 @@ class DOMQuad { /** @type {DOMPoint} */ [_p4]; - constructor(p1 = {}, p2 = {}, p3 = {}, p4 = {}) { + constructor( + p1 = { __proto__: null }, + p2 = { __proto__: null }, + p3 = { __proto__: null }, + p4 = { __proto__: null }, + ) { this[_p1] = DOMPoint.fromPoint(p1); this[_p2] = DOMPoint.fromPoint(p2); this[_p3] = DOMPoint.fromPoint(p3); @@ -629,7 +615,7 @@ class DOMQuad { this[_brand] = _brand; } - static fromRect(other = {}) { + static fromRect(other = { __proto__: null }) { other = webidl.converters.DOMRectInit( other, "Failed to execute 'DOMQuad.fromRect'", @@ -644,7 +630,7 @@ class DOMQuad { return quad; } - static fromQuad(other = {}) { + static fromQuad(other = { __proto__: null }) { other = webidl.converters.DOMQuadInit( other, "Failed to execute 'DOMQuad.fromQuad'", @@ -689,12 +675,12 @@ class DOMQuad { const bounds = webidl.createBranded(DOMRect); bounds[_writable] = true; - bounds[_raw] = new Float64Array([ + bounds[_inner] = new Rect( left, top, right - left, bottom - top, - ]); + ); return bounds; } @@ -728,69 +714,15 @@ class DOMQuad { webidl.configureInterface(DOMQuad); const DOMQuadPrototype = DOMQuad.prototype; -/* - * NOTE: column-major order - * - * For a 2D 3x2 matrix, the index of properties in - * | a c 0 e | | 0 4 _ 12 | - * | b d 0 f | | 1 5 _ 13 | - * | 0 0 1 0 | is | _ _ _ _ | - * | 0 0 0 1 | | _ _ _ _ | - */ -const INDEX_A = 0; -const INDEX_B = 1; -const INDEX_C = 4; -const INDEX_D = 5; -const INDEX_E = 12; -const INDEX_F = 13; - -/* - * NOTE: column-major order - * - * The index of properties in - * | m11 m21 m31 m41 | | 0 4 8 12 | - * | m12 m22 m32 m42 | | 1 5 9 13 | - * | m13 m23 m33 m43 | is | 2 6 10 14 | - * | m14 m24 m34 m44 | | 3 7 11 15 | - */ -const INDEX_M11 = 0; -const INDEX_M12 = 1; -const INDEX_M13 = 2; -const INDEX_M14 = 3; -const INDEX_M21 = 4; -const INDEX_M22 = 5; -const INDEX_M23 = 6; -const INDEX_M24 = 7; -const INDEX_M31 = 8; -const INDEX_M32 = 9; -const INDEX_M33 = 10; -const INDEX_M34 = 11; -const INDEX_M41 = 12; -const INDEX_M42 = 13; -const INDEX_M43 = 14; -const INDEX_M44 = 15; - -const _is2D = Symbol("[[is2D]]"); - class DOMMatrixReadOnly { [_writable] = false; - /** @type {Float64Array} */ - [_raw]; - /** @type {boolean} */ - [_is2D]; + [_inner]; constructor(init = undefined) { const prefix = `Failed to construct '${this.constructor.name}'`; this[_brand] = _brand; if (init === undefined) { - // deno-fmt-ignore - this[_raw] = new Float64Array([ - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1, - ]); - this[_is2D] = true; + this[_inner] = op_create_matrix_identity(); } else if ( webidl.type(init) === "Object" && init[SymbolIterator] !== undefined ) { @@ -807,18 +739,20 @@ class DOMMatrixReadOnly { "Argument 1", ); const { matrix, is2D } = parseTransformList(init, prefix); - this[_raw] = matrix; - this[_is2D] = is2D; + this[_inner] = new Matrix(matrix, is2D); } } - static fromMatrix(other = {}) { + static fromMatrix(other = { __proto__: null }) { const prefix = "Failed to execute 'DOMMatrixReadOnly.fromMatrix'"; const matrix = webidl.createBranded(DOMMatrixReadOnly); matrix[_writable] = false; // fast path for DOMMatrix or DOMMatrixReadOnly - if (ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other)) { - initMatrixFromMatrix(matrix, other); + if ( + other !== null && + ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other) + ) { + matrix[_inner] = other[_inner].clone(); } else { other = webidl.converters.DOMMatrixInit(other, prefix, "Argument 1"); validateAndFixupMatrixDictionary(other, prefix); @@ -849,99 +783,99 @@ class DOMMatrixReadOnly { get a() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][INDEX_A]; + return this[_inner].a; } get b() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][INDEX_B]; + return this[_inner].b; } get c() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][INDEX_C]; + return this[_inner].c; } get d() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][INDEX_D]; + return this[_inner].d; } get e() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][INDEX_E]; + return this[_inner].e; } get f() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][INDEX_F]; + return this[_inner].f; } get m11() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][INDEX_M11]; + return this[_inner].m11; } get m12() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][INDEX_M12]; + return this[_inner].m12; } get m13() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][INDEX_M13]; + return this[_inner].m13; } get m14() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][INDEX_M14]; + return this[_inner].m14; } get m21() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][INDEX_M21]; + return this[_inner].m21; } get m22() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][INDEX_M22]; + return this[_inner].m22; } get m23() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][INDEX_M23]; + return this[_inner].m23; } get m24() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][INDEX_M24]; + return this[_inner].m24; } get m31() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][INDEX_M31]; + return this[_inner].m31; } get m32() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][INDEX_M32]; + return this[_inner].m32; } get m33() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][INDEX_M33]; + return this[_inner].m33; } get m34() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][INDEX_M34]; + return this[_inner].m34; } get m41() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][INDEX_M41]; + return this[_inner].m41; } get m42() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][INDEX_M42]; + return this[_inner].m42; } get m43() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][INDEX_M43]; + return this[_inner].m43; } get m44() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_raw][INDEX_M44]; + return this[_inner].m44; } get is2D() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return this[_is2D]; + return this[_inner].is2D; } get isIdentity() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return isIdentityMatrix(this); + return this[_inner].isIdentity; } translate(tx = 0, ty = 0, tz = 0) { @@ -951,14 +885,7 @@ class DOMMatrixReadOnly { tz = webidl.converters["unrestricted double"](tz); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_raw] = new Float64Array(this[_raw]); - op_geometry_translate_self( - tx, - ty, - tz, - matrix[_raw], - ); - matrix[_is2D] = this[_is2D] && tz === 0; + matrix[_inner] = this[_inner].clone().translate(tx, ty, tz); return matrix; } @@ -979,26 +906,18 @@ class DOMMatrixReadOnly { originZ = webidl.converters["unrestricted double"](originZ); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_raw] = new Float64Array(this[_raw]); if (originX === 0 && originY === 0 && originZ === 0) { - op_geometry_scale_self( - scaleX, - scaleY, - scaleZ, - matrix[_raw], - ); + matrix[_inner] = this[_inner].clone().scale(scaleX, scaleY, scaleZ); } else { - op_geometry_scale_with_origin_self( + matrix[_inner] = this[_inner].clone().scaleWithOrigin( scaleX, scaleY, scaleZ, originX, originY, originZ, - matrix[_raw], ); } - matrix[_is2D] = this[_is2D] && scaleZ === 1 && originZ === 0; return matrix; } @@ -1008,14 +927,11 @@ class DOMMatrixReadOnly { scaleY = webidl.converters["unrestricted double"](scaleY); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_raw] = new Float64Array(this[_raw]); - op_geometry_scale_self( + matrix[_inner] = this[_inner].clone().scale( scaleX, scaleY, 1, - matrix[_raw], ); - matrix[_is2D] = this[_is2D]; return matrix; } @@ -1027,26 +943,18 @@ class DOMMatrixReadOnly { originZ = webidl.converters["unrestricted double"](originZ); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_raw] = new Float64Array(this[_raw]); if (originX === 0 && originY === 0 && originZ === 0) { - op_geometry_scale_self( - scale, - scale, - scale, - matrix[_raw], - ); + matrix[_inner] = this[_inner].clone().scale(scale, scale, scale); } else { - op_geometry_scale_with_origin_self( + matrix[_inner] = this[_inner].clone().scaleWithOrigin( scale, scale, scale, originX, originY, originZ, - matrix[_raw], ); } - matrix[_is2D] = this[_is2D] && scale === 1 && originZ === 0; return matrix; } @@ -1067,14 +975,11 @@ class DOMMatrixReadOnly { } const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_raw] = new Float64Array(this[_raw]); - op_geometry_rotate_self( + matrix[_inner] = this[_inner].clone().rotate( rotX, rotY, rotZ, - matrix[_raw], ); - matrix[_is2D] = this[_is2D] && rotX === 0 && rotY === 0; return matrix; } @@ -1084,13 +989,7 @@ class DOMMatrixReadOnly { y = webidl.converters["unrestricted double"](y); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_raw] = new Float64Array(this[_raw]); - op_geometry_rotate_from_vector_self( - x, - y, - matrix[_raw], - ); - matrix[_is2D] = this[_is2D]; + matrix[_inner] = this[_inner].clone().rotateFromVector(x, y); return matrix; } @@ -1102,17 +1001,14 @@ class DOMMatrixReadOnly { angle = webidl.converters["unrestricted double"](angle); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_raw] = new Float64Array(this[_raw]); if (x !== 0 || y !== 0 || z !== 0) { - op_geometry_rotate_axis_angle_self( + matrix[_inner] = this[_inner].clone().rotateAxisAngle( x, y, z, angle, - matrix[_raw], ); } - matrix[_is2D] = this[_is2D] && x === 0 && y === 0; return matrix; } @@ -1121,13 +1017,7 @@ class DOMMatrixReadOnly { sx = webidl.converters["unrestricted double"](sx); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_raw] = new Float64Array(this[_raw]); - op_geometry_skew_self( - sx, - 0, - matrix[_raw], - ); - matrix[_is2D] = this[_is2D]; + matrix[_inner] = this[_inner].clone().skewX(sx); return matrix; } @@ -1136,34 +1026,29 @@ class DOMMatrixReadOnly { sy = webidl.converters["unrestricted double"](sy); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_raw] = new Float64Array(this[_raw]); - op_geometry_skew_self( - 0, - sy, - matrix[_raw], - ); - matrix[_is2D] = this[_is2D]; + matrix[_inner] = this[_inner].clone().skewY(sy); return matrix; } - multiply(other = {}) { + multiply(other = { __proto__: null }) { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); const prefix = "Failed to execute 'multiply' on 'DOMMatrixReadOnly'"; - if (!ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other)) { + if ( + other === null || + !ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other) + ) { const _other = webidl.converters.DOMMatrixInit( other, prefix, "Argument 1", ); validateAndFixupMatrixDictionary(_other, prefix); - other = {}; + other = { __proto__: null }; initMatrixFromDictonary(other, _other); } const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_raw] = new Float64Array(16); - op_geometry_multiply(this[_raw], other[_raw], matrix[_raw]); - matrix[_is2D] = this[_is2D] && other[_is2D]; + matrix[_inner] = this[_inner].multiply(other[_inner]); return matrix; } @@ -1171,9 +1056,7 @@ class DOMMatrixReadOnly { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_raw] = new Float64Array(this[_raw]); - op_geometry_flip_x_self(matrix[_raw]); - matrix[_is2D] = this[_is2D]; + matrix[_inner] = this[_inner].clone().flipX(); return matrix; } @@ -1181,9 +1064,7 @@ class DOMMatrixReadOnly { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_raw] = new Float64Array(this[_raw]); - op_geometry_flip_y_self(matrix[_raw]); - matrix[_is2D] = this[_is2D]; + matrix[_inner] = this[_inner].clone().flipY(); return matrix; } @@ -1191,74 +1072,78 @@ class DOMMatrixReadOnly { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_raw] = new Float64Array(this[_raw]); - let invertible; - if (this[_is2D]) { - invertible = op_geometry_invert_2d_self(matrix[_raw]); - } else { - invertible = op_geometry_invert_self(matrix[_raw]); - } - matrix[_is2D] = this[_is2D] && invertible; + matrix[_inner] = this[_inner].clone().inverse(); return matrix; } - transformPoint(point = {}) { + transformPoint(point = { __proto__: null }) { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - point = webidl.converters.DOMPointInit( - point, - "Failed to execute 'transformPoint' on 'DOMMatrixReadOnly'", - "Argument 1", - ); + if ( + other === null || + !ObjectPrototypeIsPrototypeOf(DOMPointReadOnlyPrototype, point) + ) { + const _point = webidl.converters.DOMPointInit( + point, + "Failed to execute 'transformPoint' on 'DOMMatrixReadOnly'", + "Argument 1", + ); + point = { + [_inner]: new Point( + _point.x, + _point.y, + _point.z, + _point.w, + ), + }; + } const result = webidl.createBranded(DOMPoint); result[_writable] = true; - result[_raw] = new Float64Array([ - point.x, - point.y, - point.z, - point.w, - ]); - op_geometry_premultiply_point_self(this[_raw], result[_raw]); + result[_inner] = this[_inner].transformPoint(point[_inner]); return result; } toFloat32Array() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return new Float32Array(this[_raw]); + return new Float32Array( + new Float64Array( + this[_inner].toBuffer(), + ), + ); } toFloat64Array() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - return new Float64Array(this[_raw]); + return new Float64Array(this[_inner].toBuffer()); } toJSON() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - const raw = this[_raw]; + const inner = this[_inner]; return { - a: raw[INDEX_A], - b: raw[INDEX_B], - c: raw[INDEX_C], - d: raw[INDEX_D], - e: raw[INDEX_E], - f: raw[INDEX_F], - m11: raw[INDEX_M11], - m12: raw[INDEX_M12], - m13: raw[INDEX_M13], - m14: raw[INDEX_M14], - m21: raw[INDEX_M21], - m22: raw[INDEX_M22], - m23: raw[INDEX_M23], - m24: raw[INDEX_M24], - m31: raw[INDEX_M31], - m32: raw[INDEX_M32], - m33: raw[INDEX_M33], - m34: raw[INDEX_M34], - m41: raw[INDEX_M41], - m42: raw[INDEX_M42], - m43: raw[INDEX_M43], - m44: raw[INDEX_M44], - is2D: this[_is2D], - isIdentity: isIdentityMatrix(this), + a: inner.a, + b: inner.b, + c: inner.c, + d: inner.d, + e: inner.e, + f: inner.f, + m11: inner.m11, + m12: inner.m12, + m13: inner.m13, + m14: inner.m14, + m21: inner.m21, + m22: inner.m22, + m23: inner.m23, + m24: inner.m24, + m31: inner.m31, + m32: inner.m32, + m33: inner.m33, + m34: inner.m34, + m41: inner.m41, + m42: inner.m42, + m43: inner.m43, + m44: inner.m44, + is2D: inner.is2D, + isIdentity: inner.isIdentity, }; } @@ -1308,13 +1193,16 @@ const DOMMatrixReadOnlyPrototype = DOMMatrixReadOnly.prototype; class DOMMatrix extends DOMMatrixReadOnly { [_writable] = true; - static fromMatrix(other = {}) { + static fromMatrix(other = { __proto__: null }) { const prefix = "Failed to execute 'DOMMatrix.fromMatrix'"; const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; // fast path for DOMMatrix or DOMMatrixReadOnly - if (ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other)) { - initMatrixFromMatrix(matrix, other); + if ( + other !== null && + ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other) + ) { + matrix[_inner] = other[_inner].clone(); } else { other = webidl.converters.DOMMatrixInit(other, prefix, "Argument 1"); validateAndFixupMatrixDictionary(other, prefix); @@ -1345,276 +1233,242 @@ class DOMMatrix extends DOMMatrixReadOnly { get a() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][INDEX_A]; + return this[_inner].a; } set a(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_raw][INDEX_A] = webidl.converters["unrestricted double"](value); + this[_inner].a = webidl.converters["unrestricted double"](value); } get b() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][INDEX_B]; + return this[_inner].b; } set b(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_raw][INDEX_B] = webidl.converters["unrestricted double"](value); + this[_inner].b = webidl.converters["unrestricted double"](value); } get c() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][INDEX_C]; + return this[_inner].c; } set c(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_raw][INDEX_C] = webidl.converters["unrestricted double"](value); + this[_inner].c = webidl.converters["unrestricted double"](value); } get d() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][INDEX_D]; + return this[_inner].d; } set d(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_raw][INDEX_D] = webidl.converters["unrestricted double"](value); + this[_inner].d = webidl.converters["unrestricted double"](value); } get e() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][INDEX_E]; + return this[_inner].e; } set e(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_raw][INDEX_E] = webidl.converters["unrestricted double"](value); + this[_inner].e = webidl.converters["unrestricted double"](value); } get f() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][INDEX_F]; + return this[_inner].f; } set f(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_raw][INDEX_F] = webidl.converters["unrestricted double"](value); + this[_inner].f = webidl.converters["unrestricted double"](value); } get m11() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][INDEX_M11]; + return this[_inner].m11; } set m11(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_raw][INDEX_M11] = webidl.converters["unrestricted double"](value); + this[_inner].m11 = webidl.converters["unrestricted double"](value); } get m12() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][INDEX_M12]; + return this[_inner].m12; } set m12(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_raw][INDEX_M12] = webidl.converters["unrestricted double"](value); + this[_inner].m12 = webidl.converters["unrestricted double"](value); } get m13() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][INDEX_M13]; + return this[_inner].m13; } set m13(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - if (value !== 0) { - this[_is2D] = false; - } - this[_raw][INDEX_M13] = webidl.converters["unrestricted double"](value); + this[_inner].m13 = webidl.converters["unrestricted double"](value); } get m14() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][INDEX_M14]; + return this[_inner].m14; } set m14(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - if (value !== 0) { - this[_is2D] = false; - } - this[_raw][INDEX_M14] = webidl.converters["unrestricted double"](value); + this[_inner].m14 = webidl.converters["unrestricted double"](value); } get m21() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][INDEX_M21]; + return this[_inner].m21; } set m21(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_raw][INDEX_M21] = webidl.converters["unrestricted double"](value); + this[_inner].m21 = webidl.converters["unrestricted double"](value); } get m22() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][INDEX_M22]; + return this[_inner].m22; } set m22(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_raw][INDEX_M22] = webidl.converters["unrestricted double"](value); + this[_inner].m22 = webidl.converters["unrestricted double"](value); } get m23() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][INDEX_M23]; + return this[_inner].m23; } set m23(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - if (value !== 0) { - this[_is2D] = false; - } - this[_raw][INDEX_M23] = webidl.converters["unrestricted double"](value); + this[_inner].m23 = webidl.converters["unrestricted double"](value); } get m24() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][INDEX_M24]; + return this[_inner].m24; } set m24(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - if (value !== 0) { - this[_is2D] = false; - } - this[_raw][INDEX_M24] = webidl.converters["unrestricted double"](value); + this[_inner].m24 = webidl.converters["unrestricted double"](value); } get m31() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][INDEX_M31]; + return this[_inner].m31; } set m31(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - if (value !== 0) { - this[_is2D] = false; - } - this[_raw][INDEX_M31] = webidl.converters["unrestricted double"](value); + this[_inner].m31 = webidl.converters["unrestricted double"](value); } get m32() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][INDEX_M32]; + return this[_inner].m32; } set m32(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - if (value !== 0) { - this[_is2D] = false; - } - this[_raw][INDEX_M32] = webidl.converters["unrestricted double"](value); + this[_inner].m32 = webidl.converters["unrestricted double"](value); } get m33() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][INDEX_M33]; + return this[_inner].m33; } set m33(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - if (value !== 1) { - this[_is2D] = false; - } - this[_raw][INDEX_M33] = webidl.converters["unrestricted double"](value); + this[_inner].m33 = webidl.converters["unrestricted double"](value); } get m34() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][INDEX_M34]; + return this[_inner].m34; } set m34(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - if (value !== 0) { - this[_is2D] = false; - } - this[_raw][INDEX_M34] = webidl.converters["unrestricted double"](value); + this[_inner].m34 = webidl.converters["unrestricted double"](value); } get m41() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][INDEX_M41]; + return this[_inner].m41; } set m41(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_raw][INDEX_M41] = webidl.converters["unrestricted double"](value); + this[_inner].m41 = webidl.converters["unrestricted double"](value); } get m42() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][INDEX_M42]; + return this[_inner].m42; } set m42(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_raw][INDEX_M42] = webidl.converters["unrestricted double"](value); + this[_inner].m42 = webidl.converters["unrestricted double"](value); } get m43() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][INDEX_M43]; + return this[_inner].m43; } set m43(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - if (value !== 0) { - this[_is2D] = false; - } - this[_raw][INDEX_M43] = webidl.converters["unrestricted double"](value); + this[_inner].m43 = webidl.converters["unrestricted double"](value); } get m44() { webidl.assertBranded(this, DOMMatrixPrototype); - return this[_raw][INDEX_M44]; + return this[_inner].m44; } set m44(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - if (value !== 1) { - this[_is2D] = false; - } - this[_raw][INDEX_M44] = webidl.converters["unrestricted double"](value); + this[_inner].m44 = webidl.converters["unrestricted double"](value); } - multiplySelf(other = {}) { + multiplySelf(other = { __proto__: null }) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); const prefix = "Failed to execute 'multiplySelf' on 'DOMMatrix'"; - if (!ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other)) { + if ( + other === null || + !ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other) + ) { const _other = webidl.converters.DOMMatrixInit( other, prefix, "Argument 1", ); validateAndFixupMatrixDictionary(_other, prefix); - other = {}; + other = { __proto__: null }; initMatrixFromDictonary(other, _other); - } else if (this[_raw] === other[_raw]) { - other = {}; - initMatrixFromMatrix(other, this); } - - op_geometry_multiply_self(other[_raw], this[_raw]); - this[_is2D] &&= other[_is2D]; + this[_inner].multiplySelf(other[_inner]); return this; } - preMultiplySelf(other = {}) { + preMultiplySelf(other = { __proto__: null }) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); const prefix = "Failed to execute 'premultiplySelf' on 'DOMMatrix'"; - if (!ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other)) { + if ( + other === null || + !ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other) + ) { const _other = webidl.converters.DOMMatrixInit( other, prefix, "Argument 1", ); validateAndFixupMatrixDictionary(_other, prefix); - other = {}; + other = { __proto__: null }; initMatrixFromDictonary(other, _other); - } else if (this[_raw] === other[_raw]) { - other = {}; - initMatrixFromMatrix(other, this); } - - op_geometry_premultiply_self(other[_raw], this[_raw]); - this[_is2D] &&= other[_is2D]; + this[_inner].preMultiplySelf(other[_inner]); return this; } @@ -1624,13 +1478,7 @@ class DOMMatrix extends DOMMatrixReadOnly { tx = webidl.converters["unrestricted double"](tx); ty = webidl.converters["unrestricted double"](ty); tz = webidl.converters["unrestricted double"](tz); - op_geometry_translate_self( - tx, - ty, - tz, - this[_raw], - ); - this[_is2D] &&= tz === 0; + this[_inner].translate(tx, ty, tz); return this; } @@ -1651,24 +1499,17 @@ class DOMMatrix extends DOMMatrixReadOnly { originY = webidl.converters["unrestricted double"](originY); originZ = webidl.converters["unrestricted double"](originZ); if (originX === 0 && originY === 0 && originZ === 0) { - op_geometry_scale_self( - scaleX, - scaleY, - scaleZ, - this[_raw], - ); + this[_inner].scale(scaleX, scaleY, scaleZ); } else { - op_geometry_scale_with_origin_self( + this[_inner].scaleWithOrigin( scaleX, scaleY, scaleZ, originX, originY, originZ, - this[_raw], ); } - this[_is2D] &&= scaleZ === 1 && originZ === 0; return this; } @@ -1680,24 +1521,17 @@ class DOMMatrix extends DOMMatrixReadOnly { originY = webidl.converters["unrestricted double"](originY); originZ = webidl.converters["unrestricted double"](originZ); if (originX === 0 && originY === 0 && originZ === 0) { - op_geometry_scale_self( - scale, - scale, - scale, - this[_raw], - ); + this[_inner].scale(scale, scale, scale); } else { - op_geometry_scale_with_origin_self( + this[_inner].scaleWithOrigin( scale, scale, scale, originX, originY, originZ, - this[_raw], ); } - this[_is2D] &&= scale === 1 && originZ === 0; return this; } @@ -1717,13 +1551,11 @@ class DOMMatrix extends DOMMatrixReadOnly { ? webidl.converters["unrestricted double"](rotZ) : 0; } - op_geometry_rotate_self( + this[_inner].rotateSelf( rotX, rotY, rotZ, - this[_raw], ); - this[_is2D] &&= rotX === 0 && rotY === 0; return this; } @@ -1732,11 +1564,7 @@ class DOMMatrix extends DOMMatrixReadOnly { assertWritable(this); x = webidl.converters["unrestricted double"](x); y = webidl.converters["unrestricted double"](y); - op_geometry_rotate_from_vector_self( - x, - y, - this[_raw], - ); + this[_inner].rotateFromVectorSelf(x, y); return this; } @@ -1748,15 +1576,13 @@ class DOMMatrix extends DOMMatrixReadOnly { z = webidl.converters["unrestricted double"](z); angle = webidl.converters["unrestricted double"](angle); if (x !== 0 || y !== 0 || z !== 0) { - op_geometry_rotate_axis_angle_self( + this[_inner].rotateAxisAngleSelf( x, y, z, angle, - this[_raw], ); } - this[_is2D] &&= x === 0 && y === 0; return this; } @@ -1764,11 +1590,7 @@ class DOMMatrix extends DOMMatrixReadOnly { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); sx = webidl.converters["unrestricted double"](sx); - op_geometry_skew_self( - sx, - 0, - this[_raw], - ); + this[_inner].skewXSelf(sx); return this; } @@ -1776,24 +1598,14 @@ class DOMMatrix extends DOMMatrixReadOnly { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); sy = webidl.converters["unrestricted double"](sy); - op_geometry_skew_self( - 0, - sy, - this[_raw], - ); + this[_inner].skewYSelf(sy); return this; } invertSelf() { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - let invertible; - if (this[_is2D]) { - invertible = op_geometry_invert_2d_self(this[_raw]); - } else { - invertible = op_geometry_invert_self(this[_raw]); - } - this[_is2D] &&= invertible; + this[_inner].inverse(); return this; } @@ -1934,16 +1746,14 @@ function initMatrixFromSequence(target, seq, prefix) { if (seq.length === 6) { const { 0: a, 1: b, 2: c, 3: d, 4: e, 5: f } = seq; // deno-fmt-ignore - target[_raw] = new Float64Array([ + target[_inner] = new Matrix(new Float64Array([ a, b, 0, 0, c, d, 0, 0, 0, 0, 1, 0, e, f, 0, 1, - ]); - target[_is2D] = true; + ]), /* is2D */ true); } else if (seq.length === 16) { - target[_raw] = new Float64Array(seq); - target[_is2D] = false; + target[_inner] = new Matrix(new Float64Array(seq), /* is2D */ false); } else { throw new TypeError( `${prefix}: The sequence must contain 6 elements for a 2D matrix or 16 elements for a 3D matrix`, @@ -1959,78 +1769,30 @@ function initMatrixFromDictonary(target, dict) { if (dict.is2D) { const { m11, m12, m21, m22, m41, m42 } = dict; // deno-fmt-ignore - target[_raw] = new Float64Array([ + target[_inner] = new Matrix(new Float64Array([ m11, m12, 0, 0, m21, m22, 0, 0, 0, 0, 1, 0, m41, m42, 0, 1, - ]); - target[_is2D] = true; + ]), /* is2D */ true); } else { + // deno-fmt-ignore const { - m11, - m12, - m13, - m14, - m21, - m22, - m23, - m24, - m31, - m32, - m33, - m34, - m41, - m42, - m43, - m44, + m11, m12, m13, m14, + m21, m22, m23, m24, + m31, m32, m33, m34, + m41, m42, m43, m44, } = dict; // deno-fmt-ignore - target[_raw] = new Float64Array([ + target[_inner] = new Matrix(new Float64Array([ m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44, - ]); - target[_is2D] = false; + ]), /* is2D */ false); } } -/** - * @param {object} target - * @type {DOMMatrixReadOnly} matrix - */ -function initMatrixFromMatrix(target, matrix) { - target[_raw] = new Float64Array(matrix[_raw]); - target[_is2D] = matrix[_is2D]; -} - -/** - * https://drafts.fxtf.org/geometry/#dom-dommatrixreadonly-isidentity - * @param {DOMMatrixReadOnly} matrix - */ -function isIdentityMatrix(matrix) { - const raw = matrix[_raw]; - return ( - raw[INDEX_M11] === 1 && - raw[INDEX_M12] === 0 && - raw[INDEX_M13] === 0 && - raw[INDEX_M14] === 0 && - raw[INDEX_M21] === 0 && - raw[INDEX_M22] === 1 && - raw[INDEX_M23] === 0 && - raw[INDEX_M24] === 0 && - raw[INDEX_M31] === 0 && - raw[INDEX_M32] === 0 && - raw[INDEX_M33] === 1 && - raw[INDEX_M34] === 0 && - raw[INDEX_M41] === 0 && - raw[INDEX_M42] === 0 && - raw[INDEX_M43] === 0 && - raw[INDEX_M44] === 1 - ); -} - /** * CSS parser * @type {((transformList: string, prefix: string) => { matrix: Float64Array, is2D: boolean })} @@ -2047,28 +1809,31 @@ function init(transformListParser, enableWindowFeatures) { if (enableWindowFeatures) { // https://drafts.fxtf.org/geometry/#dommatrixreadonly-stringification-behavior ObjectDefineProperty(DOMMatrixReadOnlyPrototype, "toString", { + __proto__: null, value: function toString() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - const raw = this[_raw]; - if (!TypedArrayPrototypeEvery(raw, (value) => NumberIsFinite(value))) { + const inner = this[_inner]; + if (!inner.isFinite) { throw new DOMException( "Failed to execute 'toString' on 'DOMMatrixReadOnly': Cannot be serialized with NaN or Infinity values", "InvalidStateError", ); } - if (this[_is2D]) { + if (inner.is2D) { return `matrix(${ ArrayPrototypeJoin([ - raw[INDEX_A], - raw[INDEX_B], - raw[INDEX_C], - raw[INDEX_D], - raw[INDEX_E], - raw[INDEX_F], + inner.a, + inner.b, + inner.c, + inner.d, + inner.e, + inner.f, ], ", ") })`; } else { - return `matrix3d(${TypedArrayPrototypeJoin(raw, ", ")})`; + return `matrix3d(${ + TypedArrayPrototypeJoin(new Float64Array(inner.toBuffer()), ", ") + })`; } }, writable: true, @@ -2078,6 +1843,7 @@ function init(transformListParser, enableWindowFeatures) { // https://drafts.fxtf.org/geometry/#dom-dommatrix-setmatrixvalue ObjectDefineProperty(DOMMatrixPrototype, "setMatrixValue", { + __proto__: null, value: function setMatrixValue(transformList) { webidl.assertBranded(this, DOMMatrixPrototype); const prefix = "Failed to execute 'setMatrixValue' on 'DOMMatrix'"; @@ -2088,8 +1854,7 @@ function init(transformListParser, enableWindowFeatures) { "Argument 1", ); const { matrix, is2D } = parseTransformList(transformList, prefix); - this[_raw] = matrix; - this[_is2D] = is2D; + this[_inner] = new Matrix(matrix, is2D); }, writable: true, enumerable: true, diff --git a/ext/geometry/Cargo.toml b/ext/geometry/Cargo.toml index 9ab2c7c698eaeb..e831ea7c98edde 100644 --- a/ext/geometry/Cargo.toml +++ b/ext/geometry/Cargo.toml @@ -1,4 +1,4 @@ -# Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. +# Copyright 2018-2025 the Deno authors. MIT license. [package] name = "deno_geometry" diff --git a/ext/geometry/README.md b/ext/geometry/README.md index 09465490254c8e..3d5ad3ce4f60a1 100644 --- a/ext/geometry/README.md +++ b/ext/geometry/README.md @@ -13,7 +13,8 @@ import { core } from "ext:core/mod.js"; import { createGeometryLoader } from "ext:deno_geometry/00_init.js"; ``` -For environments that do not have a CSS `` parser, such as Web Worker, configure as follows: +For environments that do not have a CSS `` parser, such as Web +Worker, configure as follows: ```javascript const loadGeometry = createGeometryLoader((_transformList, prefix) => { @@ -23,7 +24,8 @@ const loadGeometry = createGeometryLoader((_transformList, prefix) => { }, /* enableWindowFeatures */ false); ``` -On the other hand, in environments with a CSS `` parser, you can configure as follows: +On the other hand, in environments with a CSS `` parser, you can +configure as follows: ```javascript const loadGeometry = createGeometryLoader((transformList, prefix) => { @@ -77,9 +79,8 @@ Object.defineProperties(globalThis, { }); ``` -Then from rust, provide: -`deno_geometry::deno_geometry::init_ops_and_esm()` in the `extensions` -field of your `RuntimeOptions` +Then from rust, provide: `deno_geometry::deno_geometry::init_ops_and_esm()` in +the `extensions` field of your `RuntimeOptions` ## Dependencies @@ -91,18 +92,7 @@ field of your `RuntimeOptions` Following ops are provided, which can be accessed through `Deno.ops`: -- op_geometry_translate_self -- op_geometry_scale_self -- op_geometry_scale_with_origin_self -- op_geometry_rotate_self -- op_geometry_rotate_from_vector_self -- op_geometry_rotate_axis_angle_self -- op_geometry_skew_self -- op_geometry_multiply -- op_geometry_multiply_self -- op_geometry_premultiply_self -- op_geometry_flip_x_self -- op_geometry_flip_y_self -- op_geometry_invert_self -- op_geometry_invert_2d_self -- op_geometry_premultiply_point_self +- op_create_matrix_identity +- Matrix +- Point +- Rect diff --git a/ext/geometry/lib.deno_geometry.d.ts b/ext/geometry/lib.deno_geometry.d.ts index 44b06d763ebf50..3868044319bbc7 100644 --- a/ext/geometry/lib.deno_geometry.d.ts +++ b/ext/geometry/lib.deno_geometry.d.ts @@ -1,4 +1,4 @@ -// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. +// Copyright 2018-2025 the Deno authors. MIT license. // deno-lint-ignore-file no-var diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 16879f4ddf2071..cd7bd76c1e02d3 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -1,39 +1,29 @@ -// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. +// Copyright 2018-2025 the Deno authors. MIT license. +use std::cell::Cell; +use std::cell::RefCell; +use std::mem; +use std::path::PathBuf; +use std::slice; + +use deno_core::cppgc; use deno_core::op2; +use deno_core::v8; +use deno_core::GarbageCollected; use nalgebra::Matrix3; use nalgebra::Matrix4; use nalgebra::Matrix4x2; use nalgebra::Matrix4x3; -use nalgebra::MatrixView4; -use nalgebra::MatrixViewMut4; use nalgebra::Rotation3; use nalgebra::UnitVector3; use nalgebra::Vector3; use nalgebra::Vector4; -use nalgebra::VectorViewMut4; -use std::path::PathBuf; deno_core::extension!( deno_geometry, deps = [deno_webidl, deno_web, deno_console], - ops = [ - op_geometry_translate_self, - op_geometry_scale_self, - op_geometry_scale_with_origin_self, - op_geometry_rotate_self, - op_geometry_rotate_from_vector_self, - op_geometry_rotate_axis_angle_self, - op_geometry_skew_self, - op_geometry_multiply, - op_geometry_multiply_self, - op_geometry_premultiply_self, - op_geometry_flip_x_self, - op_geometry_flip_y_self, - op_geometry_invert_self, - op_geometry_invert_2d_self, - op_geometry_premultiply_point_self, - ], + ops = [op_create_matrix_identity], + objects = [Point, Rect, Matrix], esm = ["00_init.js"], lazy_loaded_esm = ["01_geometry.js"], ); @@ -42,228 +32,1070 @@ pub fn get_declaration() -> PathBuf { PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("lib.deno_geometry.d.ts") } -#[op2(fast)] -pub fn op_geometry_translate_self( - x: f64, - y: f64, - z: f64, - #[buffer] inout: &mut [f64], -) { - let shift = Vector3::new(x, y, z); - let mut inout = MatrixViewMut4::from_slice(inout); - inout.prepend_translation_mut(&shift); +pub struct Point { + x: Cell, + y: Cell, + z: Cell, + w: Cell, } -#[op2(fast)] -pub fn op_geometry_scale_self( - x: f64, - y: f64, - z: f64, - #[buffer] inout: &mut [f64], -) { - let scaling = Vector3::new(x, y, z); - let mut inout = MatrixViewMut4::from_slice(inout); - inout.prepend_nonuniform_scaling_mut(&scaling); +impl GarbageCollected for Point {} + +#[op2] +impl Point { + #[constructor] + #[cppgc] + pub fn constructor(x: f64, y: f64, z: f64, w: f64) -> Point { + Point { + x: Cell::new(x), + y: Cell::new(y), + z: Cell::new(z), + w: Cell::new(w), + } + } + + #[fast] + #[getter] + pub fn x(&self) -> f64 { + self.x.get() + } + + #[fast] + #[setter] + pub fn x(&self, value: f64) { + self.x.set(value) + } + + #[fast] + #[getter] + pub fn y(&self) -> f64 { + self.y.get() + } + + #[fast] + #[setter] + pub fn y(&self, value: f64) { + self.y.set(value) + } + + #[fast] + #[getter] + pub fn z(&self) -> f64 { + self.z.get() + } + + #[fast] + #[setter] + pub fn z(&self, value: f64) { + self.z.set(value) + } + + #[fast] + #[getter] + pub fn w(&self) -> f64 { + self.w.get() + } + + #[fast] + #[setter] + pub fn w(&self, value: f64) { + self.w.set(value) + } + + #[cppgc] + pub fn matrixTransform(&self, matrix: v8::Local) -> Point { + let matrix = cast_to_matrix(matrix); + let out = Point { + x: Cell::new(0.0), + y: Cell::new(0.0), + z: Cell::new(0.0), + w: Cell::new(0.0), + }; + matrix_transform_point(&matrix, self, &out); + out + } } -#[op2(fast)] -pub fn op_geometry_scale_with_origin_self( - x: f64, - y: f64, - z: f64, +pub struct Rect { + x: Cell, + y: Cell, + width: Cell, + height: Cell, +} + +impl GarbageCollected for Rect {} + +#[op2] +impl Rect { + #[constructor] + #[cppgc] + pub fn constructor(x: f64, y: f64, width: f64, height: f64) -> Rect { + Rect { + x: Cell::new(x), + y: Cell::new(y), + width: Cell::new(width), + height: Cell::new(height), + } + } + + #[fast] + #[getter] + pub fn x(&self) -> f64 { + self.x.get() + } + + #[fast] + #[setter] + pub fn x(&self, value: f64) { + self.x.set(value) + } + + #[fast] + #[getter] + pub fn y(&self) -> f64 { + self.y.get() + } + + #[fast] + #[setter] + pub fn y(&self, value: f64) { + self.y.set(value) + } + + #[fast] + #[getter] + pub fn width(&self) -> f64 { + self.width.get() + } + + #[fast] + #[setter] + pub fn width(&self, value: f64) { + self.width.set(value) + } + + #[fast] + #[getter] + pub fn height(&self) -> f64 { + self.height.get() + } + + #[fast] + #[setter] + pub fn height(&self, value: f64) { + self.height.set(value) + } +} + +#[derive(Clone)] +pub struct Matrix { + inner: RefCell>, + is_2d: Cell, +} + +impl GarbageCollected for Matrix {} + +/* + * NOTE: column-major order + * + * For a 2D 3x2 matrix, the index of properties in + * | a c 0 e | | 0 4 _ 12 | + * | b d 0 f | | 1 5 _ 13 | + * | 0 0 1 0 | is | _ _ _ _ | + * | 0 0 0 1 | | _ _ _ _ | + */ +const INDEX_A: usize = 0; +const INDEX_B: usize = 1; +const INDEX_C: usize = 4; +const INDEX_D: usize = 5; +const INDEX_E: usize = 12; +const INDEX_F: usize = 13; + +/* + * NOTE: column-major order + * + * The index of properties in + * | m11 m21 m31 m41 | | 0 4 8 12 | + * | m12 m22 m32 m42 | | 1 5 9 13 | + * | m13 m23 m33 m43 | is | 2 6 10 14 | + * | m14 m24 m34 m44 | | 3 7 11 15 | + */ +const INDEX_M11: usize = 0; +const INDEX_M12: usize = 1; +const INDEX_M13: usize = 2; +const INDEX_M14: usize = 3; +const INDEX_M21: usize = 4; +const INDEX_M22: usize = 5; +const INDEX_M23: usize = 6; +const INDEX_M24: usize = 7; +const INDEX_M31: usize = 8; +const INDEX_M32: usize = 9; +const INDEX_M33: usize = 10; +const INDEX_M34: usize = 11; +const INDEX_M41: usize = 12; +const INDEX_M42: usize = 13; +const INDEX_M43: usize = 14; +const INDEX_M44: usize = 15; + +#[op2] +impl Matrix { + #[constructor] + #[cppgc] + pub fn constructor(#[buffer] buffer: &[f64], is_2d: bool) -> Matrix { + Matrix { + inner: RefCell::new(Matrix4::from_column_slice(buffer)), + is_2d: Cell::new(is_2d), + } + } + + #[cppgc] + pub fn clone(&self) -> Matrix { + self.clone() + } + + #[fast] + #[getter] + pub fn a(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_A) } + } + + #[fast] + #[setter] + pub fn a(&self, value: f64) { + // SAFETY: in-range access + unsafe { + *self.inner.borrow_mut().get_unchecked_mut(INDEX_A) = value; + } + } + + #[fast] + #[getter] + pub fn b(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_B) } + } + + #[fast] + #[setter] + pub fn b(&self, value: f64) { + // SAFETY: in-range access + unsafe { + *self.inner.borrow_mut().get_unchecked_mut(INDEX_B) = value; + } + } + + #[fast] + #[getter] + pub fn c(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_C) } + } + + #[fast] + #[setter] + pub fn c(&self, value: f64) { + // SAFETY: in-range access + unsafe { + *self.inner.borrow_mut().get_unchecked_mut(INDEX_C) = value; + } + } + + #[fast] + #[getter] + pub fn d(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_D) } + } + + #[fast] + #[setter] + pub fn d(&self, value: f64) { + // SAFETY: in-range access + unsafe { + *self.inner.borrow_mut().get_unchecked_mut(INDEX_D) = value; + } + } + + #[fast] + #[getter] + pub fn e(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_E) } + } + + #[fast] + #[setter] + pub fn e(&self, value: f64) { + // SAFETY: in-range access + unsafe { + *self.inner.borrow_mut().get_unchecked_mut(INDEX_E) = value; + } + } + + #[fast] + #[getter] + pub fn f(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_F) } + } + + #[fast] + #[setter] + pub fn f(&self, value: f64) { + // SAFETY: in-range access + unsafe { + *self.inner.borrow_mut().get_unchecked_mut(INDEX_F) = value; + } + } + + #[fast] + #[getter] + pub fn m11(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M11) } + } + + #[fast] + #[setter] + pub fn m11(&self, value: f64) { + // SAFETY: in-range access + unsafe { + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M11) = value; + } + } + + #[fast] + #[getter] + pub fn m12(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M12) } + } + + #[fast] + #[setter] + pub fn m12(&self, value: f64) { + // SAFETY: in-range access + unsafe { + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M12) = value; + } + } + + #[fast] + #[getter] + pub fn m13(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M13) } + } + + #[fast] + #[setter] + pub fn m13(&self, value: f64) { + // SAFETY: in-range access + unsafe { + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M13) = value; + } + if value != 0.0 { + self.is_2d.set(false); + } + } + + #[fast] + #[getter] + pub fn m14(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M14) } + } + + #[fast] + #[setter] + pub fn m14(&self, value: f64) { + // SAFETY: in-range access + unsafe { + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M14) = value; + } + if value != 0.0 { + self.is_2d.set(false); + } + } + + #[fast] + #[getter] + pub fn m21(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M21) } + } + + #[fast] + #[setter] + pub fn m21(&self, value: f64) { + // SAFETY: in-range access + unsafe { + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M21) = value; + } + } + + #[fast] + #[getter] + pub fn m22(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M22) } + } + + #[fast] + #[setter] + pub fn m22(&self, value: f64) { + // SAFETY: in-range access + unsafe { + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M22) = value; + } + } + + #[fast] + #[getter] + pub fn m23(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M23) } + } + + #[fast] + #[setter] + pub fn m23(&self, value: f64) { + // SAFETY: in-range access + unsafe { + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M23) = value; + } + if value != 0.0 { + self.is_2d.set(false); + } + } + + #[fast] + #[getter] + pub fn m24(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M24) } + } + + #[fast] + #[setter] + pub fn m24(&self, value: f64) { + // SAFETY: in-range access + unsafe { + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M24) = value; + } + if value != 0.0 { + self.is_2d.set(false); + } + } + + #[fast] + #[getter] + pub fn m31(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M31) } + } + + #[fast] + #[setter] + pub fn m31(&self, value: f64) { + // SAFETY: in-range access + unsafe { + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M31) = value; + } + if value != 0.0 { + self.is_2d.set(false); + } + } + + #[fast] + #[getter] + pub fn m32(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M32) } + } + + #[fast] + #[setter] + pub fn m32(&self, value: f64) { + // SAFETY: in-range access + unsafe { + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M32) = value; + } + if value != 0.0 { + self.is_2d.set(false); + } + } + + #[fast] + #[getter] + pub fn m33(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M33) } + } + + #[fast] + #[setter] + pub fn m33(&self, value: f64) { + // SAFETY: in-range access + unsafe { + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M33) = value; + } + if value != 1.0 { + self.is_2d.set(false); + } + } + + #[fast] + #[getter] + pub fn m34(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M34) } + } + + #[fast] + #[setter] + pub fn m34(&self, value: f64) { + // SAFETY: in-range access + unsafe { + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M34) = value; + } + if value != 0.0 { + self.is_2d.set(false); + } + } + + #[fast] + #[getter] + pub fn m41(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M41) } + } + + #[fast] + #[setter] + pub fn m41(&self, value: f64) { + // SAFETY: in-range access + unsafe { + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M41) = value; + } + } + + #[fast] + #[getter] + pub fn m42(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M42) } + } + + #[fast] + #[setter] + pub fn m42(&self, value: f64) { + // SAFETY: in-range access + unsafe { + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M42) = value; + } + } + + #[fast] + #[getter] + pub fn m43(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M43) } + } + + #[fast] + #[setter] + pub fn m43(&self, value: f64) { + // SAFETY: in-range access + unsafe { + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M43) = value; + } + if value != 0.0 { + self.is_2d.set(false); + } + } + + #[fast] + #[getter] + pub fn m44(&self) -> f64 { + // SAFETY: in-range access + unsafe { *self.inner.borrow().get_unchecked(INDEX_M44) } + } + + #[fast] + #[setter] + pub fn m44(&self, value: f64) { + // SAFETY: in-range access + unsafe { + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M44) = value; + } + if value != 1.0 { + self.is_2d.set(false); + } + } + + #[fast] + #[getter] + pub fn is_2d(&self) -> bool { + self.is_2d.get() + } + + #[fast] + #[getter] + pub fn is_identity(&self) -> bool { + let inner = self.inner.borrow(); + // SAFETY: in-range access + unsafe { + *inner.get_unchecked(INDEX_M11) == 1.0 + && *inner.get_unchecked(INDEX_M12) == 0.0 + && *inner.get_unchecked(INDEX_M13) == 0.0 + && *inner.get_unchecked(INDEX_M14) == 0.0 + && *inner.get_unchecked(INDEX_M21) == 0.0 + && *inner.get_unchecked(INDEX_M22) == 1.0 + && *inner.get_unchecked(INDEX_M23) == 0.0 + && *inner.get_unchecked(INDEX_M24) == 0.0 + && *inner.get_unchecked(INDEX_M31) == 0.0 + && *inner.get_unchecked(INDEX_M32) == 0.0 + && *inner.get_unchecked(INDEX_M33) == 1.0 + && *inner.get_unchecked(INDEX_M34) == 0.0 + && *inner.get_unchecked(INDEX_M41) == 0.0 + && *inner.get_unchecked(INDEX_M42) == 0.0 + && *inner.get_unchecked(INDEX_M43) == 0.0 + && *inner.get_unchecked(INDEX_M44) == 1.0 + } + } + + #[fast] + #[getter] + pub fn is_finite(&self) -> bool { + self + .inner + .borrow() + .into_iter() + .all(|&item| item.is_finite()) + } + + #[arraybuffer] + pub fn to_buffer(&self) -> Vec { + // SAFETY: in-range access + unsafe { + slice::from_raw_parts( + self.inner.borrow().as_slice().as_ptr() as *mut u8, + 128, + ) + } + .to_vec() + } + + #[cppgc] + pub fn translate(&self, tx: f64, ty: f64, tz: f64) -> Matrix { + let out = self.clone(); + matrix_translate(&out, tx, ty, tz); + out + } + + #[fast] + pub fn translate_self(&self, tx: f64, ty: f64, tz: f64) { + matrix_translate(self, tx, ty, tz); + } + + #[cppgc] + pub fn scale(&self, sx: f64, sy: f64, sz: f64) -> Matrix { + let out = self.clone(); + matrix_scale(&out, sx, sy, sz); + out + } + + #[fast] + pub fn scale_self(&self, sx: f64, sy: f64, sz: f64) { + matrix_scale(self, sx, sy, sz); + } + + #[cppgc] + pub fn scale_with_origin( + &self, + sx: f64, + sy: f64, + sz: f64, + origin_x: f64, + origin_y: f64, + origin_z: f64, + ) -> Matrix { + let out = self.clone(); + matrix_scale_with_origin(&out, sx, sy, sz, origin_x, origin_y, origin_z); + out + } + + #[fast] + pub fn scale_with_origin_self( + &self, + sx: f64, + sy: f64, + sz: f64, + origin_x: f64, + origin_y: f64, + origin_z: f64, + ) { + matrix_scale_with_origin(self, sx, sy, sz, origin_x, origin_y, origin_z); + } + + #[cppgc] + pub fn rotate(&self, roll_deg: f64, pitch_deg: f64, yaw_deg: f64) -> Matrix { + let out = self.clone(); + matrix_rotate(&out, roll_deg, pitch_deg, yaw_deg); + out + } + + #[fast] + pub fn rotate_self(&self, roll_deg: f64, pitch_deg: f64, yaw_deg: f64) { + matrix_rotate(self, roll_deg, pitch_deg, yaw_deg); + } + + #[cppgc] + pub fn rotate_from_vector(&self, x: f64, y: f64) -> Matrix { + let out = self.clone(); + matrix_rotate_from_vector(&out, x, y); + out + } + + #[fast] + pub fn rotate_from_vector_self(&self, x: f64, y: f64) { + matrix_rotate_from_vector(self, x, y); + } + + #[cppgc] + pub fn rotate_axis_angle( + &self, + x: f64, + y: f64, + z: f64, + angle_deg: f64, + ) -> Matrix { + let out = self.clone(); + matrix_rotate_axis_angle(&out, x, y, z, angle_deg); + out + } + + #[fast] + pub fn rotate_axis_angle_self(&self, x: f64, y: f64, z: f64, angle_deg: f64) { + matrix_rotate_axis_angle(self, x, y, z, angle_deg); + } + + #[cppgc] + pub fn skew_x(&self, x_deg: f64) -> Matrix { + let out = self.clone(); + matrix_skew_x(&out, x_deg); + out + } + + #[fast] + pub fn skew_x_self(&self, x_deg: f64) { + matrix_skew_x(self, x_deg); + } + + #[cppgc] + pub fn skew_y(&self, y_deg: f64) -> Matrix { + let out = self.clone(); + matrix_skew_y(&out, y_deg); + out + } + + #[fast] + pub fn skew_y_self(&self, y_deg: f64) { + matrix_skew_y(self, y_deg); + } + + #[cppgc] + pub fn multiply(&self, other: v8::Local) -> Matrix { + let other = cast_to_matrix(other); + let out = Matrix { + inner: RefCell::new(Matrix4::zeros()), + is_2d: Cell::new(true), + }; + matrix_multiply(&out, self, &other); + out + } + + #[fast] + pub fn multiply_self(&self, other: v8::Local) { + let other = cast_to_matrix(other); + let result = Matrix { + inner: RefCell::new(Matrix4::zeros()), + is_2d: Cell::new(true), + }; + matrix_multiply(&result, self, &other); + self.inner.borrow_mut().copy_from(&result.inner.borrow()); + self.is_2d.set(result.is_2d.get()); + } + + #[fast] + pub fn pre_multiply_self(&self, other: v8::Local) { + let other = cast_to_matrix(other); + let result = Matrix { + inner: RefCell::new(Matrix4::zeros()), + is_2d: Cell::new(true), + }; + matrix_multiply(&result, &other, self); + self.inner.borrow_mut().copy_from(&result.inner.borrow()); + self.is_2d.set(result.is_2d.get()); + } + + #[cppgc] + pub fn flip_x(&self) -> Matrix { + let out = self.clone(); + matrix_flip_x(&out); + out + } + + #[cppgc] + pub fn flip_y(&self) -> Matrix { + let out = self.clone(); + matrix_flip_y(&out); + out + } + + #[cppgc] + pub fn inverse(&self) -> Matrix { + let out = self.clone(); + matrix_inverse(&out); + out + } + + #[fast] + pub fn invert_self(&self) { + matrix_inverse(self); + } + + #[cppgc] + pub fn transformPoint(&self, point: v8::Local) -> Point { + let point = cast_to_point(point); + let out = Point { + x: Cell::new(0.0), + y: Cell::new(0.0), + z: Cell::new(0.0), + w: Cell::new(0.0), + }; + matrix_transform_point(self, &point, &out); + out + } +} + +#[op2] +pub fn op_create_matrix_identity<'a>( + scope: &mut v8::HandleScope<'a>, +) -> v8::Local<'a, v8::Object> { + cppgc::make_cppgc_object( + scope, + Matrix { + inner: RefCell::new(Matrix4::identity()), + is_2d: Cell::new(true), + }, + ) +} + +fn cast_to_point(obj: v8::Local<'_, v8::Object>) -> v8::Local<'_, Point> { + // SAFETY: cast v8::Local + unsafe { mem::transmute(obj) } +} + +fn cast_to_matrix(obj: v8::Local<'_, v8::Object>) -> v8::Local<'_, Matrix> { + // SAFETY: cast v8::Local + unsafe { mem::transmute(obj) } +} + +#[inline] +fn matrix_translate(matrix: &Matrix, tx: f64, ty: f64, tz: f64) { + let mut inner = matrix.inner.borrow_mut(); + let is_2d = matrix.is_2d.get(); + let shift = Vector3::new(tx, ty, tz); + inner.prepend_translation_mut(&shift); + matrix.is_2d.set(is_2d && tz == 0.0); +} + +#[inline] +fn matrix_scale(matrix: &Matrix, sx: f64, sy: f64, sz: f64) { + let mut inner = matrix.inner.borrow_mut(); + let is_2d = matrix.is_2d.get(); + let scaling = Vector3::new(sx, sy, sz); + inner.prepend_nonuniform_scaling_mut(&scaling); + matrix.is_2d.set(is_2d && sz == 0.0); +} + +#[inline] +fn matrix_scale_with_origin( + matrix: &Matrix, + sx: f64, + sy: f64, + sz: f64, origin_x: f64, origin_y: f64, origin_z: f64, - #[buffer] inout: &mut [f64], ) { - let scaling = Vector3::new(x, y, z); + let mut inner = matrix.inner.borrow_mut(); + let is_2d = matrix.is_2d.get(); + let scaling = Vector3::new(sx, sy, sz); let mut shift = Vector3::new(origin_x, origin_y, origin_z); - let mut inout = MatrixViewMut4::from_slice(inout); - inout.prepend_translation_mut(&shift); - inout.prepend_nonuniform_scaling_mut(&scaling); + inner.prepend_translation_mut(&shift); + inner.prepend_nonuniform_scaling_mut(&scaling); shift.neg_mut(); - inout.prepend_translation_mut(&shift); + inner.prepend_translation_mut(&shift); + matrix.is_2d.set(is_2d && sz == 0.0 && origin_z == 0.0); } -#[op2(fast)] -pub fn op_geometry_rotate_self( - roll_degrees: f64, - pitch_degrees: f64, - yaw_degrees: f64, - #[buffer] inout: &mut [f64], -) { +#[inline] +fn matrix_rotate(matrix: &Matrix, roll_deg: f64, pitch_deg: f64, yaw_deg: f64) { + let mut inner = matrix.inner.borrow_mut(); + let is_2d = matrix.is_2d.get(); let rotation = Rotation3::from_euler_angles( - roll_degrees.to_radians(), - pitch_degrees.to_radians(), - yaw_degrees.to_radians(), + roll_deg.to_radians(), + pitch_deg.to_radians(), + yaw_deg.to_radians(), ) .to_homogeneous(); - let mut inout = MatrixViewMut4::from_slice(inout); let mut result = Matrix4x3::zeros(); - inout.mul_to(&rotation.fixed_view::<4, 3>(0, 0), &mut result); - inout.set_column(0, &result.column(0)); - inout.set_column(1, &result.column(1)); - inout.set_column(2, &result.column(2)); + inner.mul_to(&rotation.fixed_view::<4, 3>(0, 0), &mut result); + inner.set_column(0, &result.column(0)); + inner.set_column(1, &result.column(1)); + inner.set_column(2, &result.column(2)); + matrix + .is_2d + .set(is_2d && pitch_deg == 0.0 && yaw_deg == 0.0); } -#[op2(fast)] -pub fn op_geometry_rotate_from_vector_self( - x: f64, - y: f64, - #[buffer] inout: &mut [f64], -) { +#[inline] +fn matrix_rotate_from_vector(matrix: &Matrix, x: f64, y: f64) { + let mut inner = matrix.inner.borrow_mut(); let rotation = Rotation3::from_axis_angle(&Vector3::z_axis(), y.atan2(x)).to_homogeneous(); - let mut inout = MatrixViewMut4::from_slice(inout); let mut result = Matrix4x3::zeros(); - inout.mul_to(&rotation.fixed_view::<4, 3>(0, 0), &mut result); - inout.set_column(0, &result.column(0)); - inout.set_column(1, &result.column(1)); - inout.set_column(2, &result.column(2)); + inner.mul_to(&rotation.fixed_view::<4, 3>(0, 0), &mut result); + inner.set_column(0, &result.column(0)); + inner.set_column(1, &result.column(1)); + inner.set_column(2, &result.column(2)); } -#[op2(fast)] -pub fn op_geometry_rotate_axis_angle_self( +#[inline] +fn matrix_rotate_axis_angle( + matrix: &Matrix, x: f64, y: f64, z: f64, - angle_degrees: f64, - #[buffer] inout: &mut [f64], + angle_deg: f64, ) { + let mut inner = matrix.inner.borrow_mut(); + let is_2d = matrix.is_2d.get(); let rotation = Rotation3::from_axis_angle( &UnitVector3::new_normalize(Vector3::new(x, y, z)), - angle_degrees.to_radians(), + angle_deg.to_radians(), ) .to_homogeneous(); - let mut inout = MatrixViewMut4::from_slice(inout); let mut result = Matrix4x3::zeros(); - inout.mul_to(&rotation.fixed_view::<4, 3>(0, 0), &mut result); - inout.set_column(0, &result.column(0)); - inout.set_column(1, &result.column(1)); - inout.set_column(2, &result.column(2)); + inner.mul_to(&rotation.fixed_view::<4, 3>(0, 0), &mut result); + inner.set_column(0, &result.column(0)); + inner.set_column(1, &result.column(1)); + inner.set_column(2, &result.column(2)); + matrix.is_2d.set(is_2d && x == 0.0 && y == 0.0); } -#[op2(fast)] -pub fn op_geometry_skew_self( - x_degrees: f64, - y_degrees: f64, - #[buffer] inout: &mut [f64], -) { - let skew = Matrix4x2::new( - 1.0, - x_degrees.to_radians().tan(), - y_degrees.to_radians().tan(), - 1.0, - 0.0, - 0.0, - 0.0, - 0.0, - ); - let mut inout = MatrixViewMut4::from_slice(inout); +#[inline] +fn matrix_skew_x(matrix: &Matrix, x_deg: f64) { + let mut inner = matrix.inner.borrow_mut(); + let skew = + Matrix4x2::new(1.0, x_deg.to_radians().tan(), 0.0, 1.0, 0.0, 0.0, 0.0, 0.0); let mut result = Matrix4x2::zeros(); - inout.mul_to(&skew, &mut result); - inout.set_column(0, &result.column(0)); - inout.set_column(1, &result.column(1)); -} - -#[op2(fast)] -pub fn op_geometry_multiply( - #[buffer] lhs: &[f64], - #[buffer] rhs: &[f64], - #[buffer] out: &mut [f64], -) { - let lhs = MatrixView4::from_slice(lhs); - let rhs = MatrixView4::from_slice(rhs); - let mut out = MatrixViewMut4::from_slice(out); - lhs.mul_to(&rhs, &mut out); + inner.mul_to(&skew, &mut result); + inner.set_column(0, &result.column(0)); + inner.set_column(1, &result.column(1)); } -#[op2(fast)] -pub fn op_geometry_multiply_self( - #[buffer] rhs: &[f64], - #[buffer] inout: &mut [f64], -) { - let rhs = MatrixView4::from_slice(rhs); - let mut inout = MatrixViewMut4::from_slice(inout); - let mut result = Matrix4::zeros(); - inout.mul_to(&rhs, &mut result); - inout.copy_from(&result); +#[inline] +fn matrix_skew_y(matrix: &Matrix, y_deg: f64) { + let mut inner = matrix.inner.borrow_mut(); + let skew = + Matrix4x2::new(1.0, 0.0, y_deg.to_radians().tan(), 1.0, 0.0, 0.0, 0.0, 0.0); + let mut result = Matrix4x2::zeros(); + inner.mul_to(&skew, &mut result); + inner.set_column(0, &result.column(0)); + inner.set_column(1, &result.column(1)); } -#[op2(fast)] -pub fn op_geometry_premultiply_self( - #[buffer] lhs: &[f64], - #[buffer] inout: &mut [f64], -) { - let lhs = MatrixView4::from_slice(lhs); - let mut inout = MatrixViewMut4::from_slice(inout); +#[inline] +fn matrix_multiply(out: &Matrix, lhs: &Matrix, rhs: &Matrix) { + let lhs_inner = lhs.inner.borrow(); + let lhs_is_2d = lhs.is_2d.get(); + let rhs_inner = rhs.inner.borrow(); + let rhs_is_2d = rhs.is_2d.get(); + let mut out_inner = out.inner.borrow_mut(); let mut result = Matrix4::zeros(); - lhs.mul_to(&inout, &mut result); - inout.copy_from(&result); + lhs_inner.mul_to(&rhs_inner, &mut result); + out_inner.copy_from(&result); + out.is_2d.set(lhs_is_2d && rhs_is_2d); } -#[op2(fast)] -pub fn op_geometry_flip_x_self(#[buffer] inout: &mut [f64]) { - let mut inout = MatrixViewMut4::from_slice(inout); - inout.column_mut(0).neg_mut(); +#[inline] +fn matrix_flip_x(matrix: &Matrix) { + let mut inner = matrix.inner.borrow_mut(); + inner.column_mut(0).neg_mut(); } -#[op2(fast)] -pub fn op_geometry_flip_y_self(#[buffer] inout: &mut [f64]) { - let mut inout = MatrixViewMut4::from_slice(inout); - inout.column_mut(1).neg_mut(); +#[inline] +fn matrix_flip_y(matrix: &Matrix) { + let mut inner = matrix.inner.borrow_mut(); + inner.column_mut(1).neg_mut(); } -#[op2(fast)] -pub fn op_geometry_invert_self(#[buffer] inout: &mut [f64]) -> bool { - if inout.iter().any(|&x| x.is_infinite()) { - inout.fill(f64::NAN); - return false; +#[inline] +fn matrix_inverse(matrix: &Matrix) { + let mut inner = matrix.inner.borrow_mut(); + let is_2d = matrix.is_2d.get(); + if inner.iter().any(|&x| x.is_infinite()) { + inner.fill(f64::NAN); + matrix.is_2d.set(false); + return; } - - let mut inout = MatrixViewMut4::from_slice(inout); - if !inout.try_inverse_mut() { - inout.fill(f64::NAN); - return false; + if is_2d { + // SAFETY: in-range access + let mut matrix3 = unsafe { + Matrix3::new( + *inner.get_unchecked(0), + *inner.get_unchecked(4), + *inner.get_unchecked(12), + *inner.get_unchecked(1), + *inner.get_unchecked(5), + *inner.get_unchecked(13), + 0.0, + 0.0, + 1.0, + ) + }; + if !matrix3.try_inverse_mut() { + inner.fill(f64::NAN); + matrix.is_2d.set(false); + return; + } + // SAFETY: in-range access + unsafe { + *inner.get_unchecked_mut(0) = *matrix3.get_unchecked(0); + *inner.get_unchecked_mut(1) = *matrix3.get_unchecked(1); + *inner.get_unchecked_mut(4) = *matrix3.get_unchecked(3); + *inner.get_unchecked_mut(5) = *matrix3.get_unchecked(4); + *inner.get_unchecked_mut(12) = *matrix3.get_unchecked(6); + *inner.get_unchecked_mut(13) = *matrix3.get_unchecked(7); + } + } else if !inner.try_inverse_mut() { + inner.fill(f64::NAN); } - - true } -#[op2(fast)] -pub fn op_geometry_invert_2d_self(#[buffer] inout: &mut [f64]) -> bool { - if inout.iter().any(|&x| x.is_infinite()) { - inout.fill(f64::NAN); - return false; - } - - let mut matrix = Matrix3::new( - inout[0], inout[4], inout[12], inout[1], inout[5], inout[13], 0.0, 0.0, 1.0, - ); - if !matrix.try_inverse_mut() { - inout.fill(f64::NAN); - return false; - } - - let matrix = matrix.as_slice(); - inout[0] = matrix[0]; - inout[1] = matrix[1]; - inout[4] = matrix[3]; - inout[5] = matrix[4]; - inout[12] = matrix[6]; - inout[13] = matrix[7]; - - true -} - -#[op2(fast)] -pub fn op_geometry_premultiply_point_self( - #[buffer] lhs: &[f64], - #[buffer] inout: &mut [f64], -) { - let lhs = MatrixView4::from_slice(lhs); - let mut inout = VectorViewMut4::from_slice(inout); +fn matrix_transform_point(matrix: &Matrix, point: &Point, out: &Point) { + let inner = matrix.inner.borrow(); + let point = + Vector4::new(point.x.get(), point.y.get(), point.z.get(), point.w.get()); let mut result = Vector4::zeros(); - lhs.mul_to(&inout, &mut result); - inout.copy_from(&result); + inner.mul_to(&point, &mut result); + out.x.set(result.x); + out.y.set(result.y); + out.z.set(result.z); + out.w.set(result.w); } diff --git a/tests/unit/geometry_test.ts b/tests/unit/geometry_test.ts index b4910c3e6f5ec6..37ae864411dd77 100644 --- a/tests/unit/geometry_test.ts +++ b/tests/unit/geometry_test.ts @@ -1,4 +1,4 @@ -// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. +// Copyright 2018-2025 the Deno authors. MIT license. import { assertAlmostEquals, assertEquals, From 4d3ff7fb0682e0be25a65ba1dce7fbca3d8618f6 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Fri, 3 Jan 2025 00:06:07 +0900 Subject: [PATCH 03/24] fix lib.deno_geometry.d.ts --- ext/geometry/lib.deno_geometry.d.ts | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/ext/geometry/lib.deno_geometry.d.ts b/ext/geometry/lib.deno_geometry.d.ts index 3868044319bbc7..800993ee4f3976 100644 --- a/ext/geometry/lib.deno_geometry.d.ts +++ b/ext/geometry/lib.deno_geometry.d.ts @@ -6,7 +6,7 @@ /// /** @category Geometry Interfaces Module API */ -declare interface DOMMatrix2DInit { +interface DOMMatrix2DInit { a?: number; b?: number; c?: number; @@ -22,7 +22,7 @@ declare interface DOMMatrix2DInit { } /** @category Geometry Interfaces Module API */ -declare interface DOMMatrixInit extends DOMMatrix2DInit { +interface DOMMatrixInit extends DOMMatrix2DInit { is2D?: boolean; m13?: number; m14?: number; @@ -49,7 +49,7 @@ declare interface DOMMatrixInit extends DOMMatrix2DInit { * * @category Geometry Interfaces Module API */ -declare interface DOMMatrix extends DOMMatrixReadOnly { +interface DOMMatrix extends DOMMatrixReadOnly { a: number; b: number; c: number; @@ -227,7 +227,7 @@ declare var DOMMatrix: { * * @category Geometry Interfaces Module API */ -declare interface DOMMatrixReadOnly { +interface DOMMatrixReadOnly { readonly a: number; readonly b: number; readonly c: number; @@ -418,7 +418,7 @@ declare var DOMMatrixReadOnly: { }; /** @category Geometry Interfaces Module API */ -declare interface DOMPointInit { +interface DOMPointInit { w?: number; x?: number; y?: number; @@ -431,7 +431,7 @@ declare interface DOMPointInit { * * @category Geometry Interfaces Module API */ -declare interface DOMPoint extends DOMPointReadOnly { +interface DOMPoint extends DOMPointReadOnly { w: number; x: number; y: number; @@ -456,7 +456,7 @@ declare var DOMPoint: { * * @category Geometry Interfaces Module API */ -declare interface DOMPointReadOnly { +interface DOMPointReadOnly { readonly w: number; readonly x: number; readonly y: number; @@ -483,7 +483,7 @@ declare var DOMPointReadOnly: { }; /** @category Geometry Interfaces Module API */ -declare interface DOMQuadInit { +interface DOMQuadInit { p1?: DOMPointInit; p2?: DOMPointInit; p3?: DOMPointInit; @@ -496,7 +496,7 @@ declare interface DOMQuadInit { * * @category Geometry Interfaces Module API */ -declare interface DOMQuad { +interface DOMQuad { readonly p1: DOMPoint; readonly p2: DOMPoint; readonly p3: DOMPoint; @@ -529,7 +529,7 @@ declare var DOMQuad: { }; /** @category Geometry Interfaces Module API */ -declare interface DOMRectInit { +interface DOMRectInit { height?: number; width?: number; x?: number; @@ -541,7 +541,7 @@ declare interface DOMRectInit { * * @category Geometry Interfaces Module API */ -declare interface DOMRect extends DOMRectReadOnly { +interface DOMRect extends DOMRectReadOnly { height: number; width: number; x: number; @@ -564,7 +564,7 @@ declare var DOMRect: { * * @category Geometry Interfaces Module API */ -declare interface DOMRectReadOnly { +interface DOMRectReadOnly { readonly bottom: number; readonly height: number; readonly left: number; From efe2b0feb5c841a726f712d9cf6ac99fce01378f Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Fri, 3 Jan 2025 18:44:54 +0900 Subject: [PATCH 04/24] fix --- ext/geometry/01_geometry.js | 127 +++++++++++++++++++++++++------- ext/geometry/README.md | 8 +- ext/geometry/lib.rs | 142 ++++++++++++++++++++++-------------- 3 files changed, 192 insertions(+), 85 deletions(-) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 4a9595d85769e0..e6b421d491d915 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -1,7 +1,12 @@ // Copyright 2018-2025 the Deno authors. MIT license. import { primordials } from "ext:core/mod.js"; -import { Matrix, op_create_matrix_identity, Point, Rect } from "ext:core/ops"; +import { + DOMMatrixInner, + DOMPointInner, + DOMRectInner, + op_geometry_create_matrix_identity, +} from "ext:core/ops"; const { ArrayPrototypeJoin, Float32Array, @@ -226,7 +231,7 @@ class DOMPointReadOnly { [_inner]; constructor(x = 0, y = 0, z = 0, w = 1) { - this[_inner] = new Point( + this[_inner] = new DOMPointInner( webidl.converters["unrestricted double"](x), webidl.converters["unrestricted double"](y), webidl.converters["unrestricted double"](z), @@ -243,7 +248,7 @@ class DOMPointReadOnly { ); const point = webidl.createBranded(DOMPointReadOnly); point[_writable] = false; - point[_inner] = new Point( + point[_inner] = new DOMPointInner( other.x, other.y, other.z, @@ -256,14 +261,17 @@ class DOMPointReadOnly { webidl.assertBranded(this, DOMPointReadOnlyPrototype); return this[_inner].x; } + get y() { webidl.assertBranded(this, DOMPointReadOnlyPrototype); return this[_inner].y; } + get z() { webidl.assertBranded(this, DOMPointReadOnlyPrototype); return this[_inner].z; } + get w() { webidl.assertBranded(this, DOMPointReadOnlyPrototype); return this[_inner].w; @@ -273,7 +281,7 @@ class DOMPointReadOnly { webidl.assertBranded(this, DOMPointReadOnlyPrototype); const prefix = "Failed to execute 'matrixTransform' on 'DOMPointReadOnly'"; if ( - other === null || + matrix === null || !ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, matrix) ) { const _matrix = webidl.converters.DOMMatrixInit( @@ -333,7 +341,7 @@ class DOMPoint extends DOMPointReadOnly { ); const point = webidl.createBranded(DOMPoint); point[_writable] = true; - point[_inner] = new Point( + point[_inner] = new DOMPointInner( other.x, other.y, other.z, @@ -351,6 +359,7 @@ class DOMPoint extends DOMPointReadOnly { assertWritable(this); this[_inner].x = webidl.converters["unrestricted double"](value); } + get y() { webidl.assertBranded(this, DOMPointPrototype); return this[_inner].y; @@ -360,6 +369,7 @@ class DOMPoint extends DOMPointReadOnly { assertWritable(this); this[_inner].y = webidl.converters["unrestricted double"](value); } + get z() { webidl.assertBranded(this, DOMPointPrototype); return this[_inner].x; @@ -369,6 +379,7 @@ class DOMPoint extends DOMPointReadOnly { assertWritable(this); this[_inner].z = webidl.converters["unrestricted double"](value); } + get w() { webidl.assertBranded(this, DOMPointPrototype); return this[_inner].w; @@ -404,7 +415,7 @@ class DOMRectReadOnly { [_inner]; constructor(x = 0, y = 0, width = 0, height = 0) { - this[_inner] = new Rect( + this[_inner] = new DOMRectInner( webidl.converters["unrestricted double"](x), webidl.converters["unrestricted double"](y), webidl.converters["unrestricted double"](width), @@ -421,7 +432,7 @@ class DOMRectReadOnly { ); const rect = webidl.createBranded(DOMRectReadOnly); rect[_writable] = false; - rect[_inner] = new Rect( + rect[_inner] = new DOMRectInner( other.x, other.y, other.width, @@ -434,33 +445,40 @@ class DOMRectReadOnly { webidl.assertBranded(this, DOMRectReadOnlyPrototype); return this[_inner].x; } + get y() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); return this[_inner].y; } + get width() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); return this[_inner].width; } + get height() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); return this[_inner].height; } + get top() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); const { y, height } = this[_inner]; return MathMin(y, y + height); } + get right() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); const { x, width } = this[_inner]; return MathMax(x, x + width); } + get bottom() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); const { y, height } = this[_inner]; return MathMax(y, y + height); } + get left() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); const { x, width } = this[_inner]; @@ -517,7 +535,7 @@ class DOMRect extends DOMRectReadOnly { ); const rect = webidl.createBranded(DOMRect); rect[_writable] = true; - rect[_inner] = new Rect( + rect[_inner] = new DOMRectInner( other.x, other.y, other.width, @@ -535,6 +553,7 @@ class DOMRect extends DOMRectReadOnly { assertWritable(this); this[_inner].x = webidl.converters["unrestricted double"](value); } + get y() { webidl.assertBranded(this, DOMRectPrototype); return this[_inner].y; @@ -544,6 +563,7 @@ class DOMRect extends DOMRectReadOnly { assertWritable(this); this[_inner].y = webidl.converters["unrestricted double"](value); } + get width() { webidl.assertBranded(this, DOMRectPrototype); return this[_inner].width; @@ -553,6 +573,7 @@ class DOMRect extends DOMRectReadOnly { assertWritable(this); this[_inner].width = webidl.converters["unrestricted double"](value); } + get height() { webidl.assertBranded(this, DOMRectPrototype); return this[_inner].height; @@ -648,14 +669,17 @@ class DOMQuad { webidl.assertBranded(this, DOMQuadPrototype); return this[_p1]; } + get p2() { webidl.assertBranded(this, DOMQuadPrototype); return this[_p2]; } + get p3() { webidl.assertBranded(this, DOMQuadPrototype); return this[_p3]; } + get p4() { webidl.assertBranded(this, DOMQuadPrototype); return this[_p4]; @@ -675,7 +699,7 @@ class DOMQuad { const bounds = webidl.createBranded(DOMRect); bounds[_writable] = true; - bounds[_inner] = new Rect( + bounds[_inner] = new DOMRectInner( left, top, right - left, @@ -722,7 +746,7 @@ class DOMMatrixReadOnly { const prefix = `Failed to construct '${this.constructor.name}'`; this[_brand] = _brand; if (init === undefined) { - this[_inner] = op_create_matrix_identity(); + this[_inner] = op_geometry_create_matrix_identity(); } else if ( webidl.type(init) === "Object" && init[SymbolIterator] !== undefined ) { @@ -739,7 +763,7 @@ class DOMMatrixReadOnly { "Argument 1", ); const { matrix, is2D } = parseTransformList(init, prefix); - this[_inner] = new Matrix(matrix, is2D); + this[_inner] = new DOMMatrixInner(matrix, is2D); } } @@ -785,94 +809,117 @@ class DOMMatrixReadOnly { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].a; } + get b() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].b; } + get c() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].c; } + get d() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].d; } + get e() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].e; } + get f() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].f; } + get m11() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].m11; } + get m12() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].m12; } + get m13() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].m13; } + get m14() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].m14; } + get m21() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].m21; } + get m22() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].m22; } + get m23() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].m23; } + get m24() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].m24; } + get m31() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].m31; } + get m32() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].m32; } + get m33() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].m33; } + get m34() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].m34; } + get m41() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].m41; } + get m42() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].m42; } + get m43() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].m43; } + get m44() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].m44; } + get is2D() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].is2D; } + get isIdentity() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); return this[_inner].isIdentity; @@ -907,7 +954,11 @@ class DOMMatrixReadOnly { const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; if (originX === 0 && originY === 0 && originZ === 0) { - matrix[_inner] = this[_inner].clone().scale(scaleX, scaleY, scaleZ); + matrix[_inner] = this[_inner].clone().scaleWithoutOrigin( + scaleX, + scaleY, + scaleZ, + ); } else { matrix[_inner] = this[_inner].clone().scaleWithOrigin( scaleX, @@ -927,7 +978,7 @@ class DOMMatrixReadOnly { scaleY = webidl.converters["unrestricted double"](scaleY); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_inner] = this[_inner].clone().scale( + matrix[_inner] = this[_inner].clone().scaleWithoutOrigin( scaleX, scaleY, 1, @@ -1079,7 +1130,7 @@ class DOMMatrixReadOnly { transformPoint(point = { __proto__: null }) { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); if ( - other === null || + point === null || !ObjectPrototypeIsPrototypeOf(DOMPointReadOnlyPrototype, point) ) { const _point = webidl.converters.DOMPointInit( @@ -1088,7 +1139,7 @@ class DOMMatrixReadOnly { "Argument 1", ); point = { - [_inner]: new Point( + [_inner]: new DOMPointInner( _point.x, _point.y, _point.z, @@ -1240,6 +1291,7 @@ class DOMMatrix extends DOMMatrixReadOnly { assertWritable(this); this[_inner].a = webidl.converters["unrestricted double"](value); } + get b() { webidl.assertBranded(this, DOMMatrixPrototype); return this[_inner].b; @@ -1249,6 +1301,7 @@ class DOMMatrix extends DOMMatrixReadOnly { assertWritable(this); this[_inner].b = webidl.converters["unrestricted double"](value); } + get c() { webidl.assertBranded(this, DOMMatrixPrototype); return this[_inner].c; @@ -1258,6 +1311,7 @@ class DOMMatrix extends DOMMatrixReadOnly { assertWritable(this); this[_inner].c = webidl.converters["unrestricted double"](value); } + get d() { webidl.assertBranded(this, DOMMatrixPrototype); return this[_inner].d; @@ -1267,6 +1321,7 @@ class DOMMatrix extends DOMMatrixReadOnly { assertWritable(this); this[_inner].d = webidl.converters["unrestricted double"](value); } + get e() { webidl.assertBranded(this, DOMMatrixPrototype); return this[_inner].e; @@ -1276,6 +1331,7 @@ class DOMMatrix extends DOMMatrixReadOnly { assertWritable(this); this[_inner].e = webidl.converters["unrestricted double"](value); } + get f() { webidl.assertBranded(this, DOMMatrixPrototype); return this[_inner].f; @@ -1285,6 +1341,7 @@ class DOMMatrix extends DOMMatrixReadOnly { assertWritable(this); this[_inner].f = webidl.converters["unrestricted double"](value); } + get m11() { webidl.assertBranded(this, DOMMatrixPrototype); return this[_inner].m11; @@ -1294,6 +1351,7 @@ class DOMMatrix extends DOMMatrixReadOnly { assertWritable(this); this[_inner].m11 = webidl.converters["unrestricted double"](value); } + get m12() { webidl.assertBranded(this, DOMMatrixPrototype); return this[_inner].m12; @@ -1303,6 +1361,7 @@ class DOMMatrix extends DOMMatrixReadOnly { assertWritable(this); this[_inner].m12 = webidl.converters["unrestricted double"](value); } + get m13() { webidl.assertBranded(this, DOMMatrixPrototype); return this[_inner].m13; @@ -1312,6 +1371,7 @@ class DOMMatrix extends DOMMatrixReadOnly { assertWritable(this); this[_inner].m13 = webidl.converters["unrestricted double"](value); } + get m14() { webidl.assertBranded(this, DOMMatrixPrototype); return this[_inner].m14; @@ -1321,6 +1381,7 @@ class DOMMatrix extends DOMMatrixReadOnly { assertWritable(this); this[_inner].m14 = webidl.converters["unrestricted double"](value); } + get m21() { webidl.assertBranded(this, DOMMatrixPrototype); return this[_inner].m21; @@ -1330,6 +1391,7 @@ class DOMMatrix extends DOMMatrixReadOnly { assertWritable(this); this[_inner].m21 = webidl.converters["unrestricted double"](value); } + get m22() { webidl.assertBranded(this, DOMMatrixPrototype); return this[_inner].m22; @@ -1339,6 +1401,7 @@ class DOMMatrix extends DOMMatrixReadOnly { assertWritable(this); this[_inner].m22 = webidl.converters["unrestricted double"](value); } + get m23() { webidl.assertBranded(this, DOMMatrixPrototype); return this[_inner].m23; @@ -1348,6 +1411,7 @@ class DOMMatrix extends DOMMatrixReadOnly { assertWritable(this); this[_inner].m23 = webidl.converters["unrestricted double"](value); } + get m24() { webidl.assertBranded(this, DOMMatrixPrototype); return this[_inner].m24; @@ -1357,6 +1421,7 @@ class DOMMatrix extends DOMMatrixReadOnly { assertWritable(this); this[_inner].m24 = webidl.converters["unrestricted double"](value); } + get m31() { webidl.assertBranded(this, DOMMatrixPrototype); return this[_inner].m31; @@ -1366,6 +1431,7 @@ class DOMMatrix extends DOMMatrixReadOnly { assertWritable(this); this[_inner].m31 = webidl.converters["unrestricted double"](value); } + get m32() { webidl.assertBranded(this, DOMMatrixPrototype); return this[_inner].m32; @@ -1375,6 +1441,7 @@ class DOMMatrix extends DOMMatrixReadOnly { assertWritable(this); this[_inner].m32 = webidl.converters["unrestricted double"](value); } + get m33() { webidl.assertBranded(this, DOMMatrixPrototype); return this[_inner].m33; @@ -1384,6 +1451,7 @@ class DOMMatrix extends DOMMatrixReadOnly { assertWritable(this); this[_inner].m33 = webidl.converters["unrestricted double"](value); } + get m34() { webidl.assertBranded(this, DOMMatrixPrototype); return this[_inner].m34; @@ -1393,6 +1461,7 @@ class DOMMatrix extends DOMMatrixReadOnly { assertWritable(this); this[_inner].m34 = webidl.converters["unrestricted double"](value); } + get m41() { webidl.assertBranded(this, DOMMatrixPrototype); return this[_inner].m41; @@ -1402,6 +1471,7 @@ class DOMMatrix extends DOMMatrixReadOnly { assertWritable(this); this[_inner].m41 = webidl.converters["unrestricted double"](value); } + get m42() { webidl.assertBranded(this, DOMMatrixPrototype); return this[_inner].m42; @@ -1411,6 +1481,7 @@ class DOMMatrix extends DOMMatrixReadOnly { assertWritable(this); this[_inner].m42 = webidl.converters["unrestricted double"](value); } + get m43() { webidl.assertBranded(this, DOMMatrixPrototype); return this[_inner].m43; @@ -1420,6 +1491,7 @@ class DOMMatrix extends DOMMatrixReadOnly { assertWritable(this); this[_inner].m43 = webidl.converters["unrestricted double"](value); } + get m44() { webidl.assertBranded(this, DOMMatrixPrototype); return this[_inner].m44; @@ -1478,7 +1550,7 @@ class DOMMatrix extends DOMMatrixReadOnly { tx = webidl.converters["unrestricted double"](tx); ty = webidl.converters["unrestricted double"](ty); tz = webidl.converters["unrestricted double"](tz); - this[_inner].translate(tx, ty, tz); + this[_inner].translateSelf(tx, ty, tz); return this; } @@ -1499,9 +1571,9 @@ class DOMMatrix extends DOMMatrixReadOnly { originY = webidl.converters["unrestricted double"](originY); originZ = webidl.converters["unrestricted double"](originZ); if (originX === 0 && originY === 0 && originZ === 0) { - this[_inner].scale(scaleX, scaleY, scaleZ); + this[_inner].scaleWithoutOriginSelf(scaleX, scaleY, scaleZ); } else { - this[_inner].scaleWithOrigin( + this[_inner].scaleWithOriginSelf( scaleX, scaleY, scaleZ, @@ -1521,9 +1593,9 @@ class DOMMatrix extends DOMMatrixReadOnly { originY = webidl.converters["unrestricted double"](originY); originZ = webidl.converters["unrestricted double"](originZ); if (originX === 0 && originY === 0 && originZ === 0) { - this[_inner].scale(scale, scale, scale); + this[_inner].scaleWithoutOriginSelf(scale, scale, scale); } else { - this[_inner].scaleWithOrigin( + this[_inner].scaleWithOriginSelf( scale, scale, scale, @@ -1605,7 +1677,7 @@ class DOMMatrix extends DOMMatrixReadOnly { invertSelf() { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_inner].inverse(); + this[_inner].invertSelf(); return this; } @@ -1746,14 +1818,17 @@ function initMatrixFromSequence(target, seq, prefix) { if (seq.length === 6) { const { 0: a, 1: b, 2: c, 3: d, 4: e, 5: f } = seq; // deno-fmt-ignore - target[_inner] = new Matrix(new Float64Array([ + target[_inner] = new DOMMatrixInner(new Float64Array([ a, b, 0, 0, c, d, 0, 0, 0, 0, 1, 0, e, f, 0, 1, ]), /* is2D */ true); } else if (seq.length === 16) { - target[_inner] = new Matrix(new Float64Array(seq), /* is2D */ false); + target[_inner] = new DOMMatrixInner( + new Float64Array(seq), + /* is2D */ false, + ); } else { throw new TypeError( `${prefix}: The sequence must contain 6 elements for a 2D matrix or 16 elements for a 3D matrix`, @@ -1769,7 +1844,7 @@ function initMatrixFromDictonary(target, dict) { if (dict.is2D) { const { m11, m12, m21, m22, m41, m42 } = dict; // deno-fmt-ignore - target[_inner] = new Matrix(new Float64Array([ + target[_inner] = new DOMMatrixInner(new Float64Array([ m11, m12, 0, 0, m21, m22, 0, 0, 0, 0, 1, 0, @@ -1784,7 +1859,7 @@ function initMatrixFromDictonary(target, dict) { m41, m42, m43, m44, } = dict; // deno-fmt-ignore - target[_inner] = new Matrix(new Float64Array([ + target[_inner] = new DOMMatrixInner(new Float64Array([ m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, @@ -1854,7 +1929,7 @@ function init(transformListParser, enableWindowFeatures) { "Argument 1", ); const { matrix, is2D } = parseTransformList(transformList, prefix); - this[_inner] = new Matrix(matrix, is2D); + this[_inner] = new DOMMatrixInner(matrix, is2D); }, writable: true, enumerable: true, diff --git a/ext/geometry/README.md b/ext/geometry/README.md index 3d5ad3ce4f60a1..7e10bfeecd4a1a 100644 --- a/ext/geometry/README.md +++ b/ext/geometry/README.md @@ -92,7 +92,7 @@ the `extensions` field of your `RuntimeOptions` Following ops are provided, which can be accessed through `Deno.ops`: -- op_create_matrix_identity -- Matrix -- Point -- Rect +- op_geometry_create_matrix_identity +- DOMMatrixInner +- DOMPointInner +- DOMRectInner diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index cd7bd76c1e02d3..2fd8c897473430 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -22,8 +22,8 @@ use nalgebra::Vector4; deno_core::extension!( deno_geometry, deps = [deno_webidl, deno_web, deno_console], - ops = [op_create_matrix_identity], - objects = [Point, Rect, Matrix], + ops = [op_geometry_create_matrix_identity], + objects = [DOMPointInner, DOMRectInner, DOMMatrixInner], esm = ["00_init.js"], lazy_loaded_esm = ["01_geometry.js"], ); @@ -32,21 +32,21 @@ pub fn get_declaration() -> PathBuf { PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("lib.deno_geometry.d.ts") } -pub struct Point { +pub struct DOMPointInner { x: Cell, y: Cell, z: Cell, w: Cell, } -impl GarbageCollected for Point {} +impl GarbageCollected for DOMPointInner {} #[op2] -impl Point { +impl DOMPointInner { #[constructor] #[cppgc] - pub fn constructor(x: f64, y: f64, z: f64, w: f64) -> Point { - Point { + pub fn constructor(x: f64, y: f64, z: f64, w: f64) -> DOMPointInner { + DOMPointInner { x: Cell::new(x), y: Cell::new(y), z: Cell::new(z), @@ -103,9 +103,12 @@ impl Point { } #[cppgc] - pub fn matrixTransform(&self, matrix: v8::Local) -> Point { + pub fn matrix_transform( + &self, + matrix: v8::Local, + ) -> DOMPointInner { let matrix = cast_to_matrix(matrix); - let out = Point { + let out = DOMPointInner { x: Cell::new(0.0), y: Cell::new(0.0), z: Cell::new(0.0), @@ -116,21 +119,21 @@ impl Point { } } -pub struct Rect { +pub struct DOMRectInner { x: Cell, y: Cell, width: Cell, height: Cell, } -impl GarbageCollected for Rect {} +impl GarbageCollected for DOMRectInner {} #[op2] -impl Rect { +impl DOMRectInner { #[constructor] #[cppgc] - pub fn constructor(x: f64, y: f64, width: f64, height: f64) -> Rect { - Rect { + pub fn constructor(x: f64, y: f64, width: f64, height: f64) -> DOMRectInner { + DOMRectInner { x: Cell::new(x), y: Cell::new(y), width: Cell::new(width), @@ -188,12 +191,12 @@ impl Rect { } #[derive(Clone)] -pub struct Matrix { +pub struct DOMMatrixInner { inner: RefCell>, is_2d: Cell, } -impl GarbageCollected for Matrix {} +impl GarbageCollected for DOMMatrixInner {} /* * NOTE: column-major order @@ -238,18 +241,18 @@ const INDEX_M43: usize = 14; const INDEX_M44: usize = 15; #[op2] -impl Matrix { +impl DOMMatrixInner { #[constructor] #[cppgc] - pub fn constructor(#[buffer] buffer: &[f64], is_2d: bool) -> Matrix { - Matrix { + pub fn constructor(#[buffer] buffer: &[f64], is_2d: bool) -> DOMMatrixInner { + DOMMatrixInner { inner: RefCell::new(Matrix4::from_column_slice(buffer)), is_2d: Cell::new(is_2d), } } #[cppgc] - pub fn clone(&self) -> Matrix { + pub fn clone(&self) -> DOMMatrixInner { self.clone() } @@ -689,7 +692,7 @@ impl Matrix { } #[cppgc] - pub fn translate(&self, tx: f64, ty: f64, tz: f64) -> Matrix { + pub fn translate(&self, tx: f64, ty: f64, tz: f64) -> DOMMatrixInner { let out = self.clone(); matrix_translate(&out, tx, ty, tz); out @@ -701,14 +704,19 @@ impl Matrix { } #[cppgc] - pub fn scale(&self, sx: f64, sy: f64, sz: f64) -> Matrix { + pub fn scale_without_origin( + &self, + sx: f64, + sy: f64, + sz: f64, + ) -> DOMMatrixInner { let out = self.clone(); matrix_scale(&out, sx, sy, sz); out } #[fast] - pub fn scale_self(&self, sx: f64, sy: f64, sz: f64) { + pub fn scale_without_origin_self(&self, sx: f64, sy: f64, sz: f64) { matrix_scale(self, sx, sy, sz); } @@ -721,7 +729,7 @@ impl Matrix { origin_x: f64, origin_y: f64, origin_z: f64, - ) -> Matrix { + ) -> DOMMatrixInner { let out = self.clone(); matrix_scale_with_origin(&out, sx, sy, sz, origin_x, origin_y, origin_z); out @@ -741,7 +749,12 @@ impl Matrix { } #[cppgc] - pub fn rotate(&self, roll_deg: f64, pitch_deg: f64, yaw_deg: f64) -> Matrix { + pub fn rotate( + &self, + roll_deg: f64, + pitch_deg: f64, + yaw_deg: f64, + ) -> DOMMatrixInner { let out = self.clone(); matrix_rotate(&out, roll_deg, pitch_deg, yaw_deg); out @@ -753,7 +766,7 @@ impl Matrix { } #[cppgc] - pub fn rotate_from_vector(&self, x: f64, y: f64) -> Matrix { + pub fn rotate_from_vector(&self, x: f64, y: f64) -> DOMMatrixInner { let out = self.clone(); matrix_rotate_from_vector(&out, x, y); out @@ -771,7 +784,7 @@ impl Matrix { y: f64, z: f64, angle_deg: f64, - ) -> Matrix { + ) -> DOMMatrixInner { let out = self.clone(); matrix_rotate_axis_angle(&out, x, y, z, angle_deg); out @@ -783,7 +796,7 @@ impl Matrix { } #[cppgc] - pub fn skew_x(&self, x_deg: f64) -> Matrix { + pub fn skew_x(&self, x_deg: f64) -> DOMMatrixInner { let out = self.clone(); matrix_skew_x(&out, x_deg); out @@ -795,7 +808,7 @@ impl Matrix { } #[cppgc] - pub fn skew_y(&self, y_deg: f64) -> Matrix { + pub fn skew_y(&self, y_deg: f64) -> DOMMatrixInner { let out = self.clone(); matrix_skew_y(&out, y_deg); out @@ -807,9 +820,9 @@ impl Matrix { } #[cppgc] - pub fn multiply(&self, other: v8::Local) -> Matrix { + pub fn multiply(&self, other: v8::Local) -> DOMMatrixInner { let other = cast_to_matrix(other); - let out = Matrix { + let out = DOMMatrixInner { inner: RefCell::new(Matrix4::zeros()), is_2d: Cell::new(true), }; @@ -820,7 +833,7 @@ impl Matrix { #[fast] pub fn multiply_self(&self, other: v8::Local) { let other = cast_to_matrix(other); - let result = Matrix { + let result = DOMMatrixInner { inner: RefCell::new(Matrix4::zeros()), is_2d: Cell::new(true), }; @@ -832,7 +845,7 @@ impl Matrix { #[fast] pub fn pre_multiply_self(&self, other: v8::Local) { let other = cast_to_matrix(other); - let result = Matrix { + let result = DOMMatrixInner { inner: RefCell::new(Matrix4::zeros()), is_2d: Cell::new(true), }; @@ -842,21 +855,21 @@ impl Matrix { } #[cppgc] - pub fn flip_x(&self) -> Matrix { + pub fn flip_x(&self) -> DOMMatrixInner { let out = self.clone(); matrix_flip_x(&out); out } #[cppgc] - pub fn flip_y(&self) -> Matrix { + pub fn flip_y(&self) -> DOMMatrixInner { let out = self.clone(); matrix_flip_y(&out); out } #[cppgc] - pub fn inverse(&self) -> Matrix { + pub fn inverse(&self) -> DOMMatrixInner { let out = self.clone(); matrix_inverse(&out); out @@ -868,9 +881,9 @@ impl Matrix { } #[cppgc] - pub fn transformPoint(&self, point: v8::Local) -> Point { + pub fn transform_point(&self, point: v8::Local) -> DOMPointInner { let point = cast_to_point(point); - let out = Point { + let out = DOMPointInner { x: Cell::new(0.0), y: Cell::new(0.0), z: Cell::new(0.0), @@ -882,30 +895,36 @@ impl Matrix { } #[op2] -pub fn op_create_matrix_identity<'a>( +pub fn op_geometry_create_matrix_identity<'a>( scope: &mut v8::HandleScope<'a>, ) -> v8::Local<'a, v8::Object> { cppgc::make_cppgc_object( scope, - Matrix { + DOMMatrixInner { inner: RefCell::new(Matrix4::identity()), is_2d: Cell::new(true), }, ) } -fn cast_to_point(obj: v8::Local<'_, v8::Object>) -> v8::Local<'_, Point> { +#[inline] +fn cast_to_point( + obj: v8::Local<'_, v8::Object>, +) -> v8::Local<'_, DOMPointInner> { // SAFETY: cast v8::Local unsafe { mem::transmute(obj) } } -fn cast_to_matrix(obj: v8::Local<'_, v8::Object>) -> v8::Local<'_, Matrix> { +#[inline] +fn cast_to_matrix( + obj: v8::Local<'_, v8::Object>, +) -> v8::Local<'_, DOMMatrixInner> { // SAFETY: cast v8::Local unsafe { mem::transmute(obj) } } #[inline] -fn matrix_translate(matrix: &Matrix, tx: f64, ty: f64, tz: f64) { +fn matrix_translate(matrix: &DOMMatrixInner, tx: f64, ty: f64, tz: f64) { let mut inner = matrix.inner.borrow_mut(); let is_2d = matrix.is_2d.get(); let shift = Vector3::new(tx, ty, tz); @@ -914,7 +933,7 @@ fn matrix_translate(matrix: &Matrix, tx: f64, ty: f64, tz: f64) { } #[inline] -fn matrix_scale(matrix: &Matrix, sx: f64, sy: f64, sz: f64) { +fn matrix_scale(matrix: &DOMMatrixInner, sx: f64, sy: f64, sz: f64) { let mut inner = matrix.inner.borrow_mut(); let is_2d = matrix.is_2d.get(); let scaling = Vector3::new(sx, sy, sz); @@ -924,7 +943,7 @@ fn matrix_scale(matrix: &Matrix, sx: f64, sy: f64, sz: f64) { #[inline] fn matrix_scale_with_origin( - matrix: &Matrix, + matrix: &DOMMatrixInner, sx: f64, sy: f64, sz: f64, @@ -944,7 +963,12 @@ fn matrix_scale_with_origin( } #[inline] -fn matrix_rotate(matrix: &Matrix, roll_deg: f64, pitch_deg: f64, yaw_deg: f64) { +fn matrix_rotate( + matrix: &DOMMatrixInner, + roll_deg: f64, + pitch_deg: f64, + yaw_deg: f64, +) { let mut inner = matrix.inner.borrow_mut(); let is_2d = matrix.is_2d.get(); let rotation = Rotation3::from_euler_angles( @@ -964,7 +988,7 @@ fn matrix_rotate(matrix: &Matrix, roll_deg: f64, pitch_deg: f64, yaw_deg: f64) { } #[inline] -fn matrix_rotate_from_vector(matrix: &Matrix, x: f64, y: f64) { +fn matrix_rotate_from_vector(matrix: &DOMMatrixInner, x: f64, y: f64) { let mut inner = matrix.inner.borrow_mut(); let rotation = Rotation3::from_axis_angle(&Vector3::z_axis(), y.atan2(x)).to_homogeneous(); @@ -977,7 +1001,7 @@ fn matrix_rotate_from_vector(matrix: &Matrix, x: f64, y: f64) { #[inline] fn matrix_rotate_axis_angle( - matrix: &Matrix, + matrix: &DOMMatrixInner, x: f64, y: f64, z: f64, @@ -999,7 +1023,7 @@ fn matrix_rotate_axis_angle( } #[inline] -fn matrix_skew_x(matrix: &Matrix, x_deg: f64) { +fn matrix_skew_x(matrix: &DOMMatrixInner, x_deg: f64) { let mut inner = matrix.inner.borrow_mut(); let skew = Matrix4x2::new(1.0, x_deg.to_radians().tan(), 0.0, 1.0, 0.0, 0.0, 0.0, 0.0); @@ -1010,7 +1034,7 @@ fn matrix_skew_x(matrix: &Matrix, x_deg: f64) { } #[inline] -fn matrix_skew_y(matrix: &Matrix, y_deg: f64) { +fn matrix_skew_y(matrix: &DOMMatrixInner, y_deg: f64) { let mut inner = matrix.inner.borrow_mut(); let skew = Matrix4x2::new(1.0, 0.0, y_deg.to_radians().tan(), 1.0, 0.0, 0.0, 0.0, 0.0); @@ -1021,7 +1045,11 @@ fn matrix_skew_y(matrix: &Matrix, y_deg: f64) { } #[inline] -fn matrix_multiply(out: &Matrix, lhs: &Matrix, rhs: &Matrix) { +fn matrix_multiply( + out: &DOMMatrixInner, + lhs: &DOMMatrixInner, + rhs: &DOMMatrixInner, +) { let lhs_inner = lhs.inner.borrow(); let lhs_is_2d = lhs.is_2d.get(); let rhs_inner = rhs.inner.borrow(); @@ -1034,19 +1062,19 @@ fn matrix_multiply(out: &Matrix, lhs: &Matrix, rhs: &Matrix) { } #[inline] -fn matrix_flip_x(matrix: &Matrix) { +fn matrix_flip_x(matrix: &DOMMatrixInner) { let mut inner = matrix.inner.borrow_mut(); inner.column_mut(0).neg_mut(); } #[inline] -fn matrix_flip_y(matrix: &Matrix) { +fn matrix_flip_y(matrix: &DOMMatrixInner) { let mut inner = matrix.inner.borrow_mut(); inner.column_mut(1).neg_mut(); } #[inline] -fn matrix_inverse(matrix: &Matrix) { +fn matrix_inverse(matrix: &DOMMatrixInner) { let mut inner = matrix.inner.borrow_mut(); let is_2d = matrix.is_2d.get(); if inner.iter().any(|&x| x.is_infinite()) { @@ -1088,7 +1116,11 @@ fn matrix_inverse(matrix: &Matrix) { } } -fn matrix_transform_point(matrix: &Matrix, point: &Point, out: &Point) { +fn matrix_transform_point( + matrix: &DOMMatrixInner, + point: &DOMPointInner, + out: &DOMPointInner, +) { let inner = matrix.inner.borrow(); let point = Vector4::new(point.x.get(), point.y.get(), point.z.get(), point.w.get()); From 73959f52f7a1c684d63eb9be234385b966df170e Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sun, 5 Jan 2025 01:51:33 +0900 Subject: [PATCH 05/24] migrate DOMPointInit to ext/geometry/lib.rs --- Cargo.lock | 18 ++++++++++-------- Cargo.toml | 2 +- ext/geometry/01_geometry.js | 24 ++---------------------- ext/geometry/lib.rs | 25 +++++++++++++++++++++++++ 4 files changed, 38 insertions(+), 31 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ef2955de3a89dc..83ea7500817703 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1535,9 +1535,9 @@ dependencies = [ [[package]] name = "deno_core" -version = "0.327.0" +version = "0.328.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaf8dff204b9c2415deb47b9f30d4d38b0925d0d88f1f9074e8e76f59e6d7ded" +checksum = "f2cfbe655223c33ed41ad3a4d8527ad2f69da9192d411273ff27083356f7b3ba" dependencies = [ "anyhow", "az", @@ -1763,6 +1763,7 @@ version = "0.1.0" dependencies = [ "deno_core", "nalgebra", + "thiserror 2.0.3", ] [[package]] @@ -2123,10 +2124,11 @@ dependencies = [ [[package]] name = "deno_ops" -version = "0.203.0" +version = "0.204.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b146ca74cac431843486ade58e2accc16c11315fb2c6934590a52a73c56b7ec3" +checksum = "92b6db630a454b9faa2a2b60d91eefe26ad0ee9f2c7ca191dc9b4af5db33862f" dependencies = [ + "indexmap 2.3.0", "proc-macro-rules", "proc-macro2", "quote", @@ -6876,9 +6878,9 @@ dependencies = [ [[package]] name = "serde_v8" -version = "0.236.0" +version = "0.237.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e23b3abce64010612f88f4ff689a959736f99eb3dc0dbf1c7903434b8bd8cda5" +checksum = "be6dcdeb2f531fb20b47a98b47f528d0933b93931e1e5bb8e59f84db994bfa5e" dependencies = [ "num-bigint", "serde", @@ -8510,9 +8512,9 @@ dependencies = [ [[package]] name = "v8" -version = "130.0.2" +version = "130.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ee0be58935708fa4d7efb970c6cf9f2d9511d24ee24246481a65b6ee167348d" +checksum = "8b61316a57fcd7e5f3840fe085f13e6dfd37e92d73b040033d2f598c7a1984c3" dependencies = [ "bindgen", "bitflags 2.6.0", diff --git a/Cargo.toml b/Cargo.toml index 8dff7d175d9b53..ebeacc42b1a7f9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,7 +49,7 @@ repository = "https://github.com/denoland/deno" [workspace.dependencies] deno_ast = { version = "=0.44.0", features = ["transpiling"] } -deno_core = { version = "0.327.0" } +deno_core = { version = "0.328.0" } deno_bench_util = { version = "0.178.0", path = "./bench_util" } deno_config = { version = "=0.42.0", features = ["workspace", "sync"] } diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index e6b421d491d915..6daa0e98c5b4ad 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -241,19 +241,9 @@ class DOMPointReadOnly { } static fromPoint(other = { __proto__: null }) { - other = webidl.converters.DOMPointInit( - other, - "Failed to execute 'DOMPointReadOnly.fromPoint'", - "Argument 1", - ); const point = webidl.createBranded(DOMPointReadOnly); point[_writable] = false; - point[_inner] = new DOMPointInner( - other.x, - other.y, - other.z, - other.w, - ); + point[_inner] = DOMPointInner.fromPoint(other); return point; } @@ -334,19 +324,9 @@ class DOMPoint extends DOMPointReadOnly { [_writable] = true; static fromPoint(other = { __proto__: null }) { - other = webidl.converters.DOMPointInit( - other, - "Failed to execute 'DOMPoint.fromPoint'", - "Argument 1", - ); const point = webidl.createBranded(DOMPoint); point[_writable] = true; - point[_inner] = new DOMPointInner( - other.x, - other.y, - other.z, - other.w, - ); + point[_inner] = DOMPointInner.fromPoint(other); return point; } diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 2fd8c897473430..8627956d85cb13 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -10,6 +10,7 @@ use deno_core::cppgc; use deno_core::op2; use deno_core::v8; use deno_core::GarbageCollected; +use deno_core::WebIDL; use nalgebra::Matrix3; use nalgebra::Matrix4; use nalgebra::Matrix4x2; @@ -32,6 +33,19 @@ pub fn get_declaration() -> PathBuf { PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("lib.deno_geometry.d.ts") } +#[derive(WebIDL)] +#[webidl(dictionary)] +pub struct DOMPointInit { + #[webidl(default = 0.0)] + x: f64, + #[webidl(default = 0.0)] + y: f64, + #[webidl(default = 0.0)] + z: f64, + #[webidl(default = 1.0)] + w: f64, +} + pub struct DOMPointInner { x: Cell, y: Cell, @@ -54,6 +68,17 @@ impl DOMPointInner { } } + #[static_method] + #[cppgc] + pub fn from_point(#[webidl] init: DOMPointInit) -> DOMPointInner { + DOMPointInner { + x: Cell::new(init.x), + y: Cell::new(init.y), + z: Cell::new(init.z), + w: Cell::new(init.w), + } + } + #[fast] #[getter] pub fn x(&self) -> f64 { From 48fa87b94a4f61b89d8212cba2f3b4013214d5df Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sun, 5 Jan 2025 01:59:56 +0900 Subject: [PATCH 06/24] fix --- ext/geometry/01_geometry.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 6daa0e98c5b4ad..22b08a6bfe52a1 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -975,7 +975,11 @@ class DOMMatrixReadOnly { const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; if (originX === 0 && originY === 0 && originZ === 0) { - matrix[_inner] = this[_inner].clone().scale(scale, scale, scale); + matrix[_inner] = this[_inner].clone().scaleWithoutOrigin( + scale, + scale, + scale, + ); } else { matrix[_inner] = this[_inner].clone().scaleWithOrigin( scale, From 81021203c331029a136196c9474bdbde80239a55 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sun, 5 Jan 2025 02:52:29 +0900 Subject: [PATCH 07/24] migrate DOMMatrixInit to ext/geometry/lib.rs --- ext/geometry/01_geometry.js | 310 +++++------------------------------- ext/geometry/Cargo.toml | 1 + ext/geometry/lib.rs | 146 +++++++++++++++++ runtime/errors.rs | 8 + 4 files changed, 197 insertions(+), 268 deletions(-) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 22b08a6bfe52a1..f206550936133a 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -101,124 +101,6 @@ webidl.converters.DOMQuadInit = webidl.createDictionaryConverter( ], ); -/** @type {webidl.Dictionary} */ -const dictDOMMatrix2DInit = [ - { - key: "a", - converter: webidl.converters["unrestricted double"], - }, - { - key: "b", - converter: webidl.converters["unrestricted double"], - }, - { - key: "c", - converter: webidl.converters["unrestricted double"], - }, - { - key: "d", - converter: webidl.converters["unrestricted double"], - }, - { - key: "e", - converter: webidl.converters["unrestricted double"], - }, - { - key: "f", - converter: webidl.converters["unrestricted double"], - }, - { - key: "m11", - converter: webidl.converters["unrestricted double"], - }, - { - key: "m12", - converter: webidl.converters["unrestricted double"], - }, - { - key: "m21", - converter: webidl.converters["unrestricted double"], - }, - { - key: "m22", - converter: webidl.converters["unrestricted double"], - }, - { - key: "m41", - converter: webidl.converters["unrestricted double"], - }, - { - key: "m42", - converter: webidl.converters["unrestricted double"], - }, -]; - -webidl.converters.DOMMatrix2DInit = webidl.createDictionaryConverter( - "DOMMatrix2DInit", - dictDOMMatrix2DInit, -); - -webidl.converters.DOMMatrixInit = webidl.createDictionaryConverter( - "DOMMatrixInit", - dictDOMMatrix2DInit, - [ - { - key: "m13", - converter: webidl.converters["unrestricted double"], - defaultValue: 0, - }, - { - key: "m14", - converter: webidl.converters["unrestricted double"], - defaultValue: 0, - }, - { - key: "m23", - converter: webidl.converters["unrestricted double"], - defaultValue: 0, - }, - { - key: "m24", - converter: webidl.converters["unrestricted double"], - defaultValue: 0, - }, - { - key: "m31", - converter: webidl.converters["unrestricted double"], - defaultValue: 0, - }, - { - key: "m32", - converter: webidl.converters["unrestricted double"], - defaultValue: 0, - }, - { - key: "m33", - converter: webidl.converters["unrestricted double"], - defaultValue: 1, - }, - { - key: "m34", - converter: webidl.converters["unrestricted double"], - defaultValue: 0, - }, - { - key: "m43", - converter: webidl.converters["unrestricted double"], - defaultValue: 0, - }, - { - key: "m44", - converter: webidl.converters["unrestricted double"], - defaultValue: 1, - }, - { - key: "is2D", - converter: webidl.converters["boolean"], - }, - ], -); - const _inner = Symbol("[[inner]]"); // Property to prevent writing values when an immutable instance is changed to // a mutable instance by Object.setPrototypeOf @@ -269,23 +151,19 @@ class DOMPointReadOnly { matrixTransform(matrix = { __proto__: null }) { webidl.assertBranded(this, DOMPointReadOnlyPrototype); - const prefix = "Failed to execute 'matrixTransform' on 'DOMPointReadOnly'"; + let matrixInner; + // fast path for DOMMatrix or DOMMatrixReadOnly if ( - matrix === null || - !ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, matrix) + matrix !== null && + ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, matrix) ) { - const _matrix = webidl.converters.DOMMatrixInit( - matrix, - prefix, - "Argument 1", - ); - validateAndFixupMatrixDictionary(_matrix, prefix); - matrix = { __proto__: null }; - initMatrixFromDictonary(matrix, _matrix); + matrixInner = matrix[_inner]; + } else { + matrixInner = DOMMatrixInner.fromMatrix(matrix); } const point = webidl.createBranded(DOMPoint); point[_writable] = true; - point[_inner] = this[_inner].matrixTransform(matrix[_inner]); + point[_inner] = this[_inner].matrixTransform(matrixInner); return point; } @@ -748,7 +626,6 @@ class DOMMatrixReadOnly { } static fromMatrix(other = { __proto__: null }) { - const prefix = "Failed to execute 'DOMMatrixReadOnly.fromMatrix'"; const matrix = webidl.createBranded(DOMMatrixReadOnly); matrix[_writable] = false; // fast path for DOMMatrix or DOMMatrixReadOnly @@ -758,9 +635,7 @@ class DOMMatrixReadOnly { ) { matrix[_inner] = other[_inner].clone(); } else { - other = webidl.converters.DOMMatrixInit(other, prefix, "Argument 1"); - validateAndFixupMatrixDictionary(other, prefix); - initMatrixFromDictonary(matrix, other); + matrix[_inner] = DOMMatrixInner.fromMatrix(other); } return matrix; } @@ -1067,23 +942,19 @@ class DOMMatrixReadOnly { multiply(other = { __proto__: null }) { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - const prefix = "Failed to execute 'multiply' on 'DOMMatrixReadOnly'"; + let otherInner; + // fast path for DOMMatrix or DOMMatrixReadOnly if ( - other === null || - !ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other) + other !== null && + ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other) ) { - const _other = webidl.converters.DOMMatrixInit( - other, - prefix, - "Argument 1", - ); - validateAndFixupMatrixDictionary(_other, prefix); - other = { __proto__: null }; - initMatrixFromDictonary(other, _other); + otherInner = other[_inner]; + } else { + otherInner = DOMMatrixInner.fromMatrix(other); } const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_inner] = this[_inner].multiply(other[_inner]); + matrix[_inner] = this[_inner].multiply(otherInner); return matrix; } @@ -1113,27 +984,19 @@ class DOMMatrixReadOnly { transformPoint(point = { __proto__: null }) { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); + let pointInner; + // fast path for DOMPoint or DOMPointReadOnly if ( - point === null || - !ObjectPrototypeIsPrototypeOf(DOMPointReadOnlyPrototype, point) + point !== null && + ObjectPrototypeIsPrototypeOf(DOMPointReadOnlyPrototype, point) ) { - const _point = webidl.converters.DOMPointInit( - point, - "Failed to execute 'transformPoint' on 'DOMMatrixReadOnly'", - "Argument 1", - ); - point = { - [_inner]: new DOMPointInner( - _point.x, - _point.y, - _point.z, - _point.w, - ), - }; + pointInner = point[_inner]; + } else { + pointInner = DOMPointInner.fromPoint(point); } const result = webidl.createBranded(DOMPoint); result[_writable] = true; - result[_inner] = this[_inner].transformPoint(point[_inner]); + result[_inner] = this[_inner].transformPoint(pointInner); return result; } @@ -1229,7 +1092,6 @@ class DOMMatrix extends DOMMatrixReadOnly { [_writable] = true; static fromMatrix(other = { __proto__: null }) { - const prefix = "Failed to execute 'DOMMatrix.fromMatrix'"; const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; // fast path for DOMMatrix or DOMMatrixReadOnly @@ -1239,9 +1101,7 @@ class DOMMatrix extends DOMMatrixReadOnly { ) { matrix[_inner] = other[_inner].clone(); } else { - other = webidl.converters.DOMMatrixInit(other, prefix, "Argument 1"); - validateAndFixupMatrixDictionary(other, prefix); - initMatrixFromDictonary(matrix, other); + matrix[_inner] = DOMMatrixInner.fromMatrix(other); } return matrix; } @@ -1489,42 +1349,34 @@ class DOMMatrix extends DOMMatrixReadOnly { multiplySelf(other = { __proto__: null }) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - const prefix = "Failed to execute 'multiplySelf' on 'DOMMatrix'"; + let otherInner; + // fast path for DOMMatrix or DOMMatrixReadOnly if ( - other === null || - !ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other) + other !== null && + ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other) ) { - const _other = webidl.converters.DOMMatrixInit( - other, - prefix, - "Argument 1", - ); - validateAndFixupMatrixDictionary(_other, prefix); - other = { __proto__: null }; - initMatrixFromDictonary(other, _other); + otherInner = other[_inner]; + } else { + otherInner = DOMMatrixInner.fromMatrix(other); } - this[_inner].multiplySelf(other[_inner]); + this[_inner].multiplySelf(otherInner); return this; } preMultiplySelf(other = { __proto__: null }) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - const prefix = "Failed to execute 'premultiplySelf' on 'DOMMatrix'"; + let otherInner; + // fast path for DOMMatrix or DOMMatrixReadOnly if ( - other === null || - !ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other) + other !== null && + ObjectPrototypeIsPrototypeOf(DOMMatrixReadOnlyPrototype, other) ) { - const _other = webidl.converters.DOMMatrixInit( - other, - prefix, - "Argument 1", - ); - validateAndFixupMatrixDictionary(_other, prefix); - other = { __proto__: null }; - initMatrixFromDictonary(other, _other); + otherInner = other[_inner]; + } else { + otherInner = DOMMatrixInner.fromMatrix(other); } - this[_inner].preMultiplySelf(other[_inner]); + this[_inner].preMultiplySelf(otherInner); return this; } @@ -1715,84 +1567,6 @@ function assertWritable(self) { } } -/** - * https://tc39.es/ecma262/#sec-samevaluezero - * @param {number} x - * @param {number} y - */ -function sameValueZero(x, y) { - return x === y || ObjectIs(x, y); -} - -/** - * https://drafts.fxtf.org/geometry/#matrix-validate-and-fixup-2d - * @param {object} dict - * @param {string} prefix - */ -function validateAndFixup2DMatrixDictionary(dict, prefix) { - if ( - ( - dict.a !== undefined && dict.m11 !== undefined && - !sameValueZero(dict.a, dict.m11) - ) || - ( - dict.b !== undefined && dict.m12 !== undefined && - !sameValueZero(dict.b, dict.m12) - ) || - ( - dict.c !== undefined && dict.m21 !== undefined && - !sameValueZero(dict.c, dict.m21) - ) || - ( - dict.d !== undefined && dict.m22 !== undefined && - !sameValueZero(dict.d, dict.m22) - ) || - ( - dict.e !== undefined && dict.m41 !== undefined && - !sameValueZero(dict.e, dict.m41) - ) || - ( - dict.f !== undefined && dict.m42 !== undefined && - !sameValueZero(dict.f, dict.m42) - ) - ) { - throw new TypeError(`${prefix}: Inconsistent 2d matrix value`); - } - if (dict.m11 === undefined) dict.m11 = dict.a ?? 1; - if (dict.m12 === undefined) dict.m12 = dict.b ?? 0; - if (dict.m21 === undefined) dict.m21 = dict.c ?? 0; - if (dict.m22 === undefined) dict.m22 = dict.d ?? 1; - if (dict.m41 === undefined) dict.m41 = dict.e ?? 0; - if (dict.m42 === undefined) dict.m42 = dict.f ?? 0; -} - -/** - * https://drafts.fxtf.org/geometry/#matrix-validate-and-fixup - * @param {object} dict - * @param {string} prefix - */ -function validateAndFixupMatrixDictionary(dict, prefix) { - validateAndFixup2DMatrixDictionary(dict, prefix); - const is2DCanBeTrue = dict.m13 === 0 && - dict.m14 === 0 && - dict.m23 === 0 && - dict.m24 === 0 && - dict.m31 === 0 && - dict.m32 === 0 && - dict.m33 === 1 && - dict.m34 === 0 && - dict.m43 === 0 && - dict.m44 === 1; - if (dict.is2D === true && !is2DCanBeTrue) { - throw new TypeError( - `${prefix}: is2D property is true but the input matrix is a 3d matrix`, - ); - } - if (dict.is2D === undefined) { - dict.is2D = is2DCanBeTrue; - } -} - /** * @param {object} target * @param {number[] | Float32Array | Float64Array} seq diff --git a/ext/geometry/Cargo.toml b/ext/geometry/Cargo.toml index e831ea7c98edde..0ab9e48e270c0f 100644 --- a/ext/geometry/Cargo.toml +++ b/ext/geometry/Cargo.toml @@ -16,3 +16,4 @@ path = "lib.rs" [dependencies] deno_core.workspace = true nalgebra.workspace = true +thiserror.workspace = true diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 8627956d85cb13..ea28c3172aa9d0 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -33,6 +33,12 @@ pub fn get_declaration() -> PathBuf { PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("lib.deno_geometry.d.ts") } +#[derive(Debug, thiserror::Error)] +pub enum GeometryError { + #[error("Inconsistent 2d matrix value")] + Inconsistent2DMatrix, // TypeError +} + #[derive(WebIDL)] #[webidl(dictionary)] pub struct DOMPointInit { @@ -215,6 +221,57 @@ impl DOMRectInner { } } +#[derive(WebIDL)] +#[webidl(dictionary)] +pub struct DOMMatrixInit { + #[webidl(default = None)] + a: Option, + #[webidl(default = None)] + b: Option, + #[webidl(default = None)] + c: Option, + #[webidl(default = None)] + d: Option, + #[webidl(default = None)] + e: Option, + #[webidl(default = None)] + f: Option, + #[webidl(default = None)] + m11: Option, + #[webidl(default = None)] + m12: Option, + #[webidl(default = 0.0)] + m13: f64, + #[webidl(default = 0.0)] + m14: f64, + #[webidl(default = None)] + m21: Option, + #[webidl(default = None)] + m22: Option, + #[webidl(default = 0.0)] + m23: f64, + #[webidl(default = 0.0)] + m24: f64, + #[webidl(default = 0.0)] + m31: f64, + #[webidl(default = 0.0)] + m32: f64, + #[webidl(default = 1.0)] + m33: f64, + #[webidl(default = 0.0)] + m34: f64, + #[webidl(default = None)] + m41: Option, + #[webidl(default = None)] + m42: Option, + #[webidl(default = 0.0)] + m43: f64, + #[webidl(default = 1.0)] + m44: f64, + #[webidl(default = None)] + is_2d: Option, +} + #[derive(Clone)] pub struct DOMMatrixInner { inner: RefCell>, @@ -276,6 +333,95 @@ impl DOMMatrixInner { } } + #[static_method] + #[cppgc] + pub fn from_matrix( + #[webidl] init: DOMMatrixInit, + ) -> Result { + macro_rules! fixup { + ($value3d:expr, $value2d:expr, $default:expr) => {{ + if let Some(value3d) = $value3d { + if let Some(value2d) = $value2d { + if !(value3d == value2d || value3d.is_nan() && value2d.is_nan()) { + return Err(GeometryError::Inconsistent2DMatrix); + } + } + value3d + } else if let Some(value2d) = $value2d { + value2d + } else { + $default + } + }}; + } + + let m11 = fixup!(init.m11, init.a, 1.0); + let m12 = fixup!(init.m12, init.b, 0.0); + let m21 = fixup!(init.m21, init.c, 0.0); + let m22 = fixup!(init.m22, init.d, 1.0); + let m41 = fixup!(init.m41, init.e, 0.0); + let m42 = fixup!(init.m42, init.f, 0.0); + + let is_2d = { + let is_2d_can_be_true = init.m13 == 0.0 + && init.m14 == 0.0 + && init.m23 == 0.0 + && init.m24 == 0.0 + && init.m31 == 0.0 + && init.m32 == 0.0 + && init.m33 == 1.0 + && init.m34 == 0.0 + && init.m43 == 0.0 + && init.m44 == 1.0; + if let Some(is_2d) = init.is_2d { + if is_2d && !is_2d_can_be_true { + return Err(GeometryError::Inconsistent2DMatrix); + } else { + is_2d + } + } else { + is_2d_can_be_true + } + }; + + if is_2d { + Ok(DOMMatrixInner { + #[rustfmt::skip] + inner: RefCell::new(Matrix4::new( + m11, m21, 0.0, m41, + m12, m22, 0.0, m42, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0, + )), + is_2d: Cell::new(true), + }) + } else { + let DOMMatrixInit { + m13, + m14, + m23, + m24, + m31, + m32, + m33, + m34, + m43, + m44, + .. + } = init; + Ok(DOMMatrixInner { + #[rustfmt::skip] + inner: RefCell::new(Matrix4::new( + m11, m21, m31, m41, + m12, m22, m32, m42, + m13, m23, m33, m43, + m14, m24, m34, m44, + )), + is_2d: Cell::new(false), + }) + } + } + #[cppgc] pub fn clone(&self) -> DOMMatrixInner { self.clone() diff --git a/runtime/errors.rs b/runtime/errors.rs index 7b61395866b1ce..3a2d4568f3208e 100644 --- a/runtime/errors.rs +++ b/runtime/errors.rs @@ -37,6 +37,7 @@ use deno_ffi::ReprError; use deno_ffi::StaticError; use deno_fs::FsOpsError; use deno_fs::FsOpsErrorKind; +use deno_geometry::GeometryError; use deno_http::HttpError; use deno_http::HttpNextError; use deno_http::WebSocketUpgradeError; @@ -692,6 +693,12 @@ fn get_broadcast_channel_error(error: &BroadcastChannelError) -> &'static str { } } +fn get_geometry_error(error: &GeometryError) -> &'static str { + match error { + GeometryError::Inconsistent2DMatrix => "TypeError", + } +} + fn get_fetch_error(error: &FetchError) -> &'static str { match error { FetchError::Resource(e) => get_error_class_name(e).unwrap_or("Error"), @@ -1768,6 +1775,7 @@ pub fn get_error_class_name(e: &AnyError) -> Option<&'static str> { .or_else(|| e.downcast_ref::().map(get_http_start_error)) .or_else(|| e.downcast_ref::().map(get_process_error)) .or_else(|| e.downcast_ref::().map(get_os_error)) + .or_else(|| e.downcast_ref::().map(get_geometry_error)) .or_else(|| e.downcast_ref::().map(get_sync_fetch_error)) .or_else(|| { e.downcast_ref::() From 34b91e9faff9e9444e3896db2440bcc311c0be36 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sun, 5 Jan 2025 03:35:06 +0900 Subject: [PATCH 08/24] tweak --- ext/geometry/01_geometry.js | 182 ++++++++-------------------------- ext/geometry/lib.rs | 192 ++++++++++++++++++------------------ 2 files changed, 141 insertions(+), 233 deletions(-) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index f206550936133a..82f90f299afbb7 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -14,7 +14,6 @@ const { MathMax, MathMin, ObjectDefineProperty, - ObjectIs, ObjectPrototypeIsPrototypeOf, Symbol, SymbolFor, @@ -113,12 +112,7 @@ class DOMPointReadOnly { [_inner]; constructor(x = 0, y = 0, z = 0, w = 1) { - this[_inner] = new DOMPointInner( - webidl.converters["unrestricted double"](x), - webidl.converters["unrestricted double"](y), - webidl.converters["unrestricted double"](z), - webidl.converters["unrestricted double"](w), - ); + this[_inner] = new DOMPointInner(x, y, z, w); this[_brand] = _brand; } @@ -215,7 +209,7 @@ class DOMPoint extends DOMPointReadOnly { set x(value) { webidl.assertBranded(this, DOMPointPrototype); assertWritable(this); - this[_inner].x = webidl.converters["unrestricted double"](value); + this[_inner].x = value; } get y() { @@ -225,7 +219,7 @@ class DOMPoint extends DOMPointReadOnly { set y(value) { webidl.assertBranded(this, DOMPointPrototype); assertWritable(this); - this[_inner].y = webidl.converters["unrestricted double"](value); + this[_inner].y = value; } get z() { @@ -235,7 +229,7 @@ class DOMPoint extends DOMPointReadOnly { set z(value) { webidl.assertBranded(this, DOMPointPrototype); assertWritable(this); - this[_inner].z = webidl.converters["unrestricted double"](value); + this[_inner].z = value; } get w() { @@ -245,7 +239,7 @@ class DOMPoint extends DOMPointReadOnly { set w(value) { webidl.assertBranded(this, DOMPointPrototype); assertWritable(this); - this[_inner].x = webidl.converters["unrestricted double"](value); + this[_inner].x = value; } [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { @@ -782,9 +776,6 @@ class DOMMatrixReadOnly { translate(tx = 0, ty = 0, tz = 0) { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - tx = webidl.converters["unrestricted double"](tx); - ty = webidl.converters["unrestricted double"](ty); - tz = webidl.converters["unrestricted double"](tz); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; matrix[_inner] = this[_inner].clone().translate(tx, ty, tz); @@ -800,12 +791,6 @@ class DOMMatrixReadOnly { originZ = 0, ) { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - scaleX = webidl.converters["unrestricted double"](scaleX); - scaleY = webidl.converters["unrestricted double"](scaleY); - scaleZ = webidl.converters["unrestricted double"](scaleZ); - originX = webidl.converters["unrestricted double"](originX); - originY = webidl.converters["unrestricted double"](originY); - originZ = webidl.converters["unrestricted double"](originZ); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; if (originX === 0 && originY === 0 && originZ === 0) { @@ -829,8 +814,6 @@ class DOMMatrixReadOnly { scaleNonUniform(scaleX = 1, scaleY = 1) { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - scaleX = webidl.converters["unrestricted double"](scaleX); - scaleY = webidl.converters["unrestricted double"](scaleY); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; matrix[_inner] = this[_inner].clone().scaleWithoutOrigin( @@ -843,10 +826,6 @@ class DOMMatrixReadOnly { scale3d(scale = 1, originX = 0, originY = 0, originZ = 0) { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - scale = webidl.converters["unrestricted double"](scale); - originX = webidl.converters["unrestricted double"](originX); - originY = webidl.converters["unrestricted double"](originY); - originZ = webidl.converters["unrestricted double"](originZ); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; if (originX === 0 && originY === 0 && originZ === 0) { @@ -870,18 +849,13 @@ class DOMMatrixReadOnly { rotate(rotX = 0, rotY, rotZ) { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - rotX = webidl.converters["unrestricted double"](rotX); if (rotY === undefined && rotZ === undefined) { rotZ = rotX; rotX = 0; rotY = 0; } else { - rotY = rotY !== undefined - ? webidl.converters["unrestricted double"](rotY) - : 0; - rotZ = rotZ !== undefined - ? webidl.converters["unrestricted double"](rotZ) - : 0; + rotY = rotY !== undefined ? rotY : 0; + rotZ = rotZ !== undefined ? rotZ : 0; } const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; @@ -895,8 +869,6 @@ class DOMMatrixReadOnly { rotateFromVector(x = 0, y = 0) { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - x = webidl.converters["unrestricted double"](x); - y = webidl.converters["unrestricted double"](y); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; matrix[_inner] = this[_inner].clone().rotateFromVector(x, y); @@ -905,26 +877,19 @@ class DOMMatrixReadOnly { rotateAxisAngle(x = 0, y = 0, z = 0, angle = 0) { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - x = webidl.converters["unrestricted double"](x); - y = webidl.converters["unrestricted double"](y); - z = webidl.converters["unrestricted double"](z); - angle = webidl.converters["unrestricted double"](angle); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - if (x !== 0 || y !== 0 || z !== 0) { - matrix[_inner] = this[_inner].clone().rotateAxisAngle( - x, - y, - z, - angle, - ); - } + matrix[_inner] = this[_inner].clone().rotateAxisAngle( + x, + y, + z, + angle, + ); return matrix; } skewX(sx = 0) { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - sx = webidl.converters["unrestricted double"](sx); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; matrix[_inner] = this[_inner].clone().skewX(sx); @@ -933,7 +898,6 @@ class DOMMatrixReadOnly { skewY(sy = 0) { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - sy = webidl.converters["unrestricted double"](sy); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; matrix[_inner] = this[_inner].clone().skewY(sy); @@ -1133,7 +1097,7 @@ class DOMMatrix extends DOMMatrixReadOnly { set a(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_inner].a = webidl.converters["unrestricted double"](value); + this[_inner].a = value; } get b() { @@ -1143,7 +1107,7 @@ class DOMMatrix extends DOMMatrixReadOnly { set b(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_inner].b = webidl.converters["unrestricted double"](value); + this[_inner].b = value; } get c() { @@ -1153,7 +1117,7 @@ class DOMMatrix extends DOMMatrixReadOnly { set c(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_inner].c = webidl.converters["unrestricted double"](value); + this[_inner].c = value; } get d() { @@ -1163,7 +1127,7 @@ class DOMMatrix extends DOMMatrixReadOnly { set d(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_inner].d = webidl.converters["unrestricted double"](value); + this[_inner].d = value; } get e() { @@ -1173,7 +1137,7 @@ class DOMMatrix extends DOMMatrixReadOnly { set e(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_inner].e = webidl.converters["unrestricted double"](value); + this[_inner].e = value; } get f() { @@ -1183,7 +1147,7 @@ class DOMMatrix extends DOMMatrixReadOnly { set f(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_inner].f = webidl.converters["unrestricted double"](value); + this[_inner].f = value; } get m11() { @@ -1193,7 +1157,7 @@ class DOMMatrix extends DOMMatrixReadOnly { set m11(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_inner].m11 = webidl.converters["unrestricted double"](value); + this[_inner].m11 = value; } get m12() { @@ -1203,7 +1167,7 @@ class DOMMatrix extends DOMMatrixReadOnly { set m12(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_inner].m12 = webidl.converters["unrestricted double"](value); + this[_inner].m12 = value; } get m13() { @@ -1213,7 +1177,7 @@ class DOMMatrix extends DOMMatrixReadOnly { set m13(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_inner].m13 = webidl.converters["unrestricted double"](value); + this[_inner].m13 = value; } get m14() { @@ -1223,7 +1187,7 @@ class DOMMatrix extends DOMMatrixReadOnly { set m14(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_inner].m14 = webidl.converters["unrestricted double"](value); + this[_inner].m14 = value; } get m21() { @@ -1233,7 +1197,7 @@ class DOMMatrix extends DOMMatrixReadOnly { set m21(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_inner].m21 = webidl.converters["unrestricted double"](value); + this[_inner].m21 = value; } get m22() { @@ -1243,7 +1207,7 @@ class DOMMatrix extends DOMMatrixReadOnly { set m22(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_inner].m22 = webidl.converters["unrestricted double"](value); + this[_inner].m22 = value; } get m23() { @@ -1253,7 +1217,7 @@ class DOMMatrix extends DOMMatrixReadOnly { set m23(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_inner].m23 = webidl.converters["unrestricted double"](value); + this[_inner].m23 = value; } get m24() { @@ -1263,7 +1227,7 @@ class DOMMatrix extends DOMMatrixReadOnly { set m24(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_inner].m24 = webidl.converters["unrestricted double"](value); + this[_inner].m24 = value; } get m31() { @@ -1273,7 +1237,7 @@ class DOMMatrix extends DOMMatrixReadOnly { set m31(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_inner].m31 = webidl.converters["unrestricted double"](value); + this[_inner].m31 = value; } get m32() { @@ -1283,7 +1247,7 @@ class DOMMatrix extends DOMMatrixReadOnly { set m32(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_inner].m32 = webidl.converters["unrestricted double"](value); + this[_inner].m32 = value; } get m33() { @@ -1293,7 +1257,7 @@ class DOMMatrix extends DOMMatrixReadOnly { set m33(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_inner].m33 = webidl.converters["unrestricted double"](value); + this[_inner].m33 = value; } get m34() { @@ -1303,7 +1267,7 @@ class DOMMatrix extends DOMMatrixReadOnly { set m34(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_inner].m34 = webidl.converters["unrestricted double"](value); + this[_inner].m34 = value; } get m41() { @@ -1313,7 +1277,7 @@ class DOMMatrix extends DOMMatrixReadOnly { set m41(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_inner].m41 = webidl.converters["unrestricted double"](value); + this[_inner].m41 = value; } get m42() { @@ -1323,7 +1287,7 @@ class DOMMatrix extends DOMMatrixReadOnly { set m42(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_inner].m42 = webidl.converters["unrestricted double"](value); + this[_inner].m42 = value; } get m43() { @@ -1333,7 +1297,7 @@ class DOMMatrix extends DOMMatrixReadOnly { set m43(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_inner].m43 = webidl.converters["unrestricted double"](value); + this[_inner].m43 = value; } get m44() { @@ -1343,7 +1307,7 @@ class DOMMatrix extends DOMMatrixReadOnly { set m44(value) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - this[_inner].m44 = webidl.converters["unrestricted double"](value); + this[_inner].m44 = value; } multiplySelf(other = { __proto__: null }) { @@ -1383,9 +1347,6 @@ class DOMMatrix extends DOMMatrixReadOnly { translateSelf(tx = 0, ty = 0, tz = 0) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - tx = webidl.converters["unrestricted double"](tx); - ty = webidl.converters["unrestricted double"](ty); - tz = webidl.converters["unrestricted double"](tz); this[_inner].translateSelf(tx, ty, tz); return this; } @@ -1400,12 +1361,6 @@ class DOMMatrix extends DOMMatrixReadOnly { ) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - scaleX = webidl.converters["unrestricted double"](scaleX); - scaleY = webidl.converters["unrestricted double"](scaleY); - scaleZ = webidl.converters["unrestricted double"](scaleZ); - originX = webidl.converters["unrestricted double"](originX); - originY = webidl.converters["unrestricted double"](originY); - originZ = webidl.converters["unrestricted double"](originZ); if (originX === 0 && originY === 0 && originZ === 0) { this[_inner].scaleWithoutOriginSelf(scaleX, scaleY, scaleZ); } else { @@ -1424,10 +1379,6 @@ class DOMMatrix extends DOMMatrixReadOnly { scale3dSelf(scale = 1, originX = 0, originY = 0, originZ = 0) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - scale = webidl.converters["unrestricted double"](scale); - originX = webidl.converters["unrestricted double"](originX); - originY = webidl.converters["unrestricted double"](originY); - originZ = webidl.converters["unrestricted double"](originZ); if (originX === 0 && originY === 0 && originZ === 0) { this[_inner].scaleWithoutOriginSelf(scale, scale, scale); } else { @@ -1446,18 +1397,13 @@ class DOMMatrix extends DOMMatrixReadOnly { rotateSelf(rotX = 0, rotY, rotZ) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - rotX = webidl.converters["unrestricted double"](rotX); if (rotY === undefined && rotZ === undefined) { rotZ = rotX; rotX = 0; rotY = 0; } else { - rotY = rotY !== undefined - ? webidl.converters["unrestricted double"](rotY) - : 0; - rotZ = rotZ !== undefined - ? webidl.converters["unrestricted double"](rotZ) - : 0; + rotY = rotY !== undefined ? rotY : 0; + rotZ = rotZ !== undefined ? rotZ : 0; } this[_inner].rotateSelf( rotX, @@ -1470,8 +1416,6 @@ class DOMMatrix extends DOMMatrixReadOnly { rotateFromVectorSelf(x = 0, y = 0) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - x = webidl.converters["unrestricted double"](x); - y = webidl.converters["unrestricted double"](y); this[_inner].rotateFromVectorSelf(x, y); return this; } @@ -1479,25 +1423,18 @@ class DOMMatrix extends DOMMatrixReadOnly { rotateAxisAngleSelf(x = 0, y = 0, z = 0, angle = 0) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - x = webidl.converters["unrestricted double"](x); - y = webidl.converters["unrestricted double"](y); - z = webidl.converters["unrestricted double"](z); - angle = webidl.converters["unrestricted double"](angle); - if (x !== 0 || y !== 0 || z !== 0) { - this[_inner].rotateAxisAngleSelf( - x, - y, - z, - angle, - ); - } + this[_inner].rotateAxisAngleSelf( + x, + y, + z, + angle, + ); return this; } skewXSelf(sx = 0) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - sx = webidl.converters["unrestricted double"](sx); this[_inner].skewXSelf(sx); return this; } @@ -1505,7 +1442,6 @@ class DOMMatrix extends DOMMatrixReadOnly { skewYSelf(sy = 0) { webidl.assertBranded(this, DOMMatrixPrototype); assertWritable(this); - sy = webidl.converters["unrestricted double"](sy); this[_inner].skewYSelf(sy); return this; } @@ -1594,38 +1530,6 @@ function initMatrixFromSequence(target, seq, prefix) { } } -/** - * @param {object} target - * @param {object} dict - */ -function initMatrixFromDictonary(target, dict) { - if (dict.is2D) { - const { m11, m12, m21, m22, m41, m42 } = dict; - // deno-fmt-ignore - target[_inner] = new DOMMatrixInner(new Float64Array([ - m11, m12, 0, 0, - m21, m22, 0, 0, - 0, 0, 1, 0, - m41, m42, 0, 1, - ]), /* is2D */ true); - } else { - // deno-fmt-ignore - const { - m11, m12, m13, m14, - m21, m22, m23, m24, - m31, m32, m33, m34, - m41, m42, m43, m44, - } = dict; - // deno-fmt-ignore - target[_inner] = new DOMMatrixInner(new Float64Array([ - m11, m12, m13, m14, - m21, m22, m23, m24, - m31, m32, m33, m34, - m41, m42, m43, m44, - ]), /* is2D */ false); - } -} - /** * CSS parser * @type {((transformList: string, prefix: string) => { matrix: Float64Array, is2D: boolean })} diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index ea28c3172aa9d0..79bada84b1a843 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -65,7 +65,12 @@ impl GarbageCollected for DOMPointInner {} impl DOMPointInner { #[constructor] #[cppgc] - pub fn constructor(x: f64, y: f64, z: f64, w: f64) -> DOMPointInner { + pub fn constructor( + #[webidl] x: f64, + #[webidl] y: f64, + #[webidl] z: f64, + #[webidl] w: f64, + ) -> DOMPointInner { DOMPointInner { x: Cell::new(x), y: Cell::new(y), @@ -91,9 +96,8 @@ impl DOMPointInner { self.x.get() } - #[fast] #[setter] - pub fn x(&self, value: f64) { + pub fn x(&self, #[webidl] value: f64) { self.x.set(value) } @@ -103,9 +107,8 @@ impl DOMPointInner { self.y.get() } - #[fast] #[setter] - pub fn y(&self, value: f64) { + pub fn y(&self, #[webidl] value: f64) { self.y.set(value) } @@ -115,9 +118,8 @@ impl DOMPointInner { self.z.get() } - #[fast] #[setter] - pub fn z(&self, value: f64) { + pub fn z(&self, #[webidl] value: f64) { self.z.set(value) } @@ -127,9 +129,8 @@ impl DOMPointInner { self.w.get() } - #[fast] #[setter] - pub fn w(&self, value: f64) { + pub fn w(&self, #[webidl] value: f64) { self.w.set(value) } @@ -434,9 +435,8 @@ impl DOMMatrixInner { unsafe { *self.inner.borrow().get_unchecked(INDEX_A) } } - #[fast] #[setter] - pub fn a(&self, value: f64) { + pub fn a(&self, #[webidl] value: f64) { // SAFETY: in-range access unsafe { *self.inner.borrow_mut().get_unchecked_mut(INDEX_A) = value; @@ -450,9 +450,8 @@ impl DOMMatrixInner { unsafe { *self.inner.borrow().get_unchecked(INDEX_B) } } - #[fast] #[setter] - pub fn b(&self, value: f64) { + pub fn b(&self, #[webidl] value: f64) { // SAFETY: in-range access unsafe { *self.inner.borrow_mut().get_unchecked_mut(INDEX_B) = value; @@ -466,9 +465,8 @@ impl DOMMatrixInner { unsafe { *self.inner.borrow().get_unchecked(INDEX_C) } } - #[fast] #[setter] - pub fn c(&self, value: f64) { + pub fn c(&self, #[webidl] value: f64) { // SAFETY: in-range access unsafe { *self.inner.borrow_mut().get_unchecked_mut(INDEX_C) = value; @@ -482,9 +480,8 @@ impl DOMMatrixInner { unsafe { *self.inner.borrow().get_unchecked(INDEX_D) } } - #[fast] #[setter] - pub fn d(&self, value: f64) { + pub fn d(&self, #[webidl] value: f64) { // SAFETY: in-range access unsafe { *self.inner.borrow_mut().get_unchecked_mut(INDEX_D) = value; @@ -498,9 +495,8 @@ impl DOMMatrixInner { unsafe { *self.inner.borrow().get_unchecked(INDEX_E) } } - #[fast] #[setter] - pub fn e(&self, value: f64) { + pub fn e(&self, #[webidl] value: f64) { // SAFETY: in-range access unsafe { *self.inner.borrow_mut().get_unchecked_mut(INDEX_E) = value; @@ -514,9 +510,8 @@ impl DOMMatrixInner { unsafe { *self.inner.borrow().get_unchecked(INDEX_F) } } - #[fast] #[setter] - pub fn f(&self, value: f64) { + pub fn f(&self, #[webidl] value: f64) { // SAFETY: in-range access unsafe { *self.inner.borrow_mut().get_unchecked_mut(INDEX_F) = value; @@ -530,9 +525,8 @@ impl DOMMatrixInner { unsafe { *self.inner.borrow().get_unchecked(INDEX_M11) } } - #[fast] #[setter] - pub fn m11(&self, value: f64) { + pub fn m11(&self, #[webidl] value: f64) { // SAFETY: in-range access unsafe { *self.inner.borrow_mut().get_unchecked_mut(INDEX_M11) = value; @@ -546,9 +540,8 @@ impl DOMMatrixInner { unsafe { *self.inner.borrow().get_unchecked(INDEX_M12) } } - #[fast] #[setter] - pub fn m12(&self, value: f64) { + pub fn m12(&self, #[webidl] value: f64) { // SAFETY: in-range access unsafe { *self.inner.borrow_mut().get_unchecked_mut(INDEX_M12) = value; @@ -562,9 +555,8 @@ impl DOMMatrixInner { unsafe { *self.inner.borrow().get_unchecked(INDEX_M13) } } - #[fast] #[setter] - pub fn m13(&self, value: f64) { + pub fn m13(&self, #[webidl] value: f64) { // SAFETY: in-range access unsafe { *self.inner.borrow_mut().get_unchecked_mut(INDEX_M13) = value; @@ -581,9 +573,8 @@ impl DOMMatrixInner { unsafe { *self.inner.borrow().get_unchecked(INDEX_M14) } } - #[fast] #[setter] - pub fn m14(&self, value: f64) { + pub fn m14(&self, #[webidl] value: f64) { // SAFETY: in-range access unsafe { *self.inner.borrow_mut().get_unchecked_mut(INDEX_M14) = value; @@ -600,9 +591,8 @@ impl DOMMatrixInner { unsafe { *self.inner.borrow().get_unchecked(INDEX_M21) } } - #[fast] #[setter] - pub fn m21(&self, value: f64) { + pub fn m21(&self, #[webidl] value: f64) { // SAFETY: in-range access unsafe { *self.inner.borrow_mut().get_unchecked_mut(INDEX_M21) = value; @@ -616,9 +606,8 @@ impl DOMMatrixInner { unsafe { *self.inner.borrow().get_unchecked(INDEX_M22) } } - #[fast] #[setter] - pub fn m22(&self, value: f64) { + pub fn m22(&self, #[webidl] value: f64) { // SAFETY: in-range access unsafe { *self.inner.borrow_mut().get_unchecked_mut(INDEX_M22) = value; @@ -632,9 +621,8 @@ impl DOMMatrixInner { unsafe { *self.inner.borrow().get_unchecked(INDEX_M23) } } - #[fast] #[setter] - pub fn m23(&self, value: f64) { + pub fn m23(&self, #[webidl] value: f64) { // SAFETY: in-range access unsafe { *self.inner.borrow_mut().get_unchecked_mut(INDEX_M23) = value; @@ -651,9 +639,8 @@ impl DOMMatrixInner { unsafe { *self.inner.borrow().get_unchecked(INDEX_M24) } } - #[fast] #[setter] - pub fn m24(&self, value: f64) { + pub fn m24(&self, #[webidl] value: f64) { // SAFETY: in-range access unsafe { *self.inner.borrow_mut().get_unchecked_mut(INDEX_M24) = value; @@ -670,9 +657,8 @@ impl DOMMatrixInner { unsafe { *self.inner.borrow().get_unchecked(INDEX_M31) } } - #[fast] #[setter] - pub fn m31(&self, value: f64) { + pub fn m31(&self, #[webidl] value: f64) { // SAFETY: in-range access unsafe { *self.inner.borrow_mut().get_unchecked_mut(INDEX_M31) = value; @@ -689,9 +675,8 @@ impl DOMMatrixInner { unsafe { *self.inner.borrow().get_unchecked(INDEX_M32) } } - #[fast] #[setter] - pub fn m32(&self, value: f64) { + pub fn m32(&self, #[webidl] value: f64) { // SAFETY: in-range access unsafe { *self.inner.borrow_mut().get_unchecked_mut(INDEX_M32) = value; @@ -708,9 +693,8 @@ impl DOMMatrixInner { unsafe { *self.inner.borrow().get_unchecked(INDEX_M33) } } - #[fast] #[setter] - pub fn m33(&self, value: f64) { + pub fn m33(&self, #[webidl] value: f64) { // SAFETY: in-range access unsafe { *self.inner.borrow_mut().get_unchecked_mut(INDEX_M33) = value; @@ -727,9 +711,8 @@ impl DOMMatrixInner { unsafe { *self.inner.borrow().get_unchecked(INDEX_M34) } } - #[fast] #[setter] - pub fn m34(&self, value: f64) { + pub fn m34(&self, #[webidl] value: f64) { // SAFETY: in-range access unsafe { *self.inner.borrow_mut().get_unchecked_mut(INDEX_M34) = value; @@ -746,9 +729,8 @@ impl DOMMatrixInner { unsafe { *self.inner.borrow().get_unchecked(INDEX_M41) } } - #[fast] #[setter] - pub fn m41(&self, value: f64) { + pub fn m41(&self, #[webidl] value: f64) { // SAFETY: in-range access unsafe { *self.inner.borrow_mut().get_unchecked_mut(INDEX_M41) = value; @@ -762,9 +744,8 @@ impl DOMMatrixInner { unsafe { *self.inner.borrow().get_unchecked(INDEX_M42) } } - #[fast] #[setter] - pub fn m42(&self, value: f64) { + pub fn m42(&self, #[webidl] value: f64) { // SAFETY: in-range access unsafe { *self.inner.borrow_mut().get_unchecked_mut(INDEX_M42) = value; @@ -778,9 +759,8 @@ impl DOMMatrixInner { unsafe { *self.inner.borrow().get_unchecked(INDEX_M43) } } - #[fast] #[setter] - pub fn m43(&self, value: f64) { + pub fn m43(&self, #[webidl] value: f64) { // SAFETY: in-range access unsafe { *self.inner.borrow_mut().get_unchecked_mut(INDEX_M43) = value; @@ -797,9 +777,8 @@ impl DOMMatrixInner { unsafe { *self.inner.borrow().get_unchecked(INDEX_M44) } } - #[fast] #[setter] - pub fn m44(&self, value: f64) { + pub fn m44(&self, #[webidl] value: f64) { // SAFETY: in-range access unsafe { *self.inner.borrow_mut().get_unchecked_mut(INDEX_M44) = value; @@ -863,58 +842,70 @@ impl DOMMatrixInner { } #[cppgc] - pub fn translate(&self, tx: f64, ty: f64, tz: f64) -> DOMMatrixInner { + pub fn translate( + &self, + #[webidl] tx: f64, + #[webidl] ty: f64, + #[webidl] tz: f64, + ) -> DOMMatrixInner { let out = self.clone(); matrix_translate(&out, tx, ty, tz); out } - #[fast] - pub fn translate_self(&self, tx: f64, ty: f64, tz: f64) { + pub fn translate_self( + &self, + #[webidl] tx: f64, + #[webidl] ty: f64, + #[webidl] tz: f64, + ) { matrix_translate(self, tx, ty, tz); } #[cppgc] pub fn scale_without_origin( &self, - sx: f64, - sy: f64, - sz: f64, + #[webidl] sx: f64, + #[webidl] sy: f64, + #[webidl] sz: f64, ) -> DOMMatrixInner { let out = self.clone(); matrix_scale(&out, sx, sy, sz); out } - #[fast] - pub fn scale_without_origin_self(&self, sx: f64, sy: f64, sz: f64) { + pub fn scale_without_origin_self( + &self, + #[webidl] sx: f64, + #[webidl] sy: f64, + #[webidl] sz: f64, + ) { matrix_scale(self, sx, sy, sz); } #[cppgc] pub fn scale_with_origin( &self, - sx: f64, - sy: f64, - sz: f64, - origin_x: f64, - origin_y: f64, - origin_z: f64, + #[webidl] sx: f64, + #[webidl] sy: f64, + #[webidl] sz: f64, + #[webidl] origin_x: f64, + #[webidl] origin_y: f64, + #[webidl] origin_z: f64, ) -> DOMMatrixInner { let out = self.clone(); matrix_scale_with_origin(&out, sx, sy, sz, origin_x, origin_y, origin_z); out } - #[fast] pub fn scale_with_origin_self( &self, - sx: f64, - sy: f64, - sz: f64, - origin_x: f64, - origin_y: f64, - origin_z: f64, + #[webidl] sx: f64, + #[webidl] sy: f64, + #[webidl] sz: f64, + #[webidl] origin_x: f64, + #[webidl] origin_y: f64, + #[webidl] origin_z: f64, ) { matrix_scale_with_origin(self, sx, sy, sz, origin_x, origin_y, origin_z); } @@ -922,71 +913,81 @@ impl DOMMatrixInner { #[cppgc] pub fn rotate( &self, - roll_deg: f64, - pitch_deg: f64, - yaw_deg: f64, + #[webidl] roll_deg: f64, + #[webidl] pitch_deg: f64, + #[webidl] yaw_deg: f64, ) -> DOMMatrixInner { let out = self.clone(); matrix_rotate(&out, roll_deg, pitch_deg, yaw_deg); out } - #[fast] - pub fn rotate_self(&self, roll_deg: f64, pitch_deg: f64, yaw_deg: f64) { + pub fn rotate_self( + &self, + #[webidl] roll_deg: f64, + #[webidl] pitch_deg: f64, + #[webidl] yaw_deg: f64, + ) { matrix_rotate(self, roll_deg, pitch_deg, yaw_deg); } #[cppgc] - pub fn rotate_from_vector(&self, x: f64, y: f64) -> DOMMatrixInner { + pub fn rotate_from_vector( + &self, + #[webidl] x: f64, + #[webidl] y: f64, + ) -> DOMMatrixInner { let out = self.clone(); matrix_rotate_from_vector(&out, x, y); out } - #[fast] - pub fn rotate_from_vector_self(&self, x: f64, y: f64) { + pub fn rotate_from_vector_self(&self, #[webidl] x: f64, #[webidl] y: f64) { matrix_rotate_from_vector(self, x, y); } #[cppgc] pub fn rotate_axis_angle( &self, - x: f64, - y: f64, - z: f64, - angle_deg: f64, + #[webidl] x: f64, + #[webidl] y: f64, + #[webidl] z: f64, + #[webidl] angle_deg: f64, ) -> DOMMatrixInner { let out = self.clone(); matrix_rotate_axis_angle(&out, x, y, z, angle_deg); out } - #[fast] - pub fn rotate_axis_angle_self(&self, x: f64, y: f64, z: f64, angle_deg: f64) { + pub fn rotate_axis_angle_self( + &self, + #[webidl] x: f64, + #[webidl] y: f64, + #[webidl] z: f64, + #[webidl] angle_deg: f64, + ) { matrix_rotate_axis_angle(self, x, y, z, angle_deg); } #[cppgc] - pub fn skew_x(&self, x_deg: f64) -> DOMMatrixInner { + pub fn skew_x(&self, #[webidl] x_deg: f64) -> DOMMatrixInner { let out = self.clone(); matrix_skew_x(&out, x_deg); out } - #[fast] - pub fn skew_x_self(&self, x_deg: f64) { + pub fn skew_x_self(&self, #[webidl] x_deg: f64) { matrix_skew_x(self, x_deg); } #[cppgc] - pub fn skew_y(&self, y_deg: f64) -> DOMMatrixInner { + pub fn skew_y(&self, #[webidl] y_deg: f64) -> DOMMatrixInner { let out = self.clone(); matrix_skew_y(&out, y_deg); out } - #[fast] - pub fn skew_y_self(&self, y_deg: f64) { + pub fn skew_y_self(&self, #[webidl] y_deg: f64) { matrix_skew_y(self, y_deg); } @@ -1178,6 +1179,9 @@ fn matrix_rotate_axis_angle( z: f64, angle_deg: f64, ) { + if x == 0.0 && y == 0.0 && z == 0.0 { + return; + } let mut inner = matrix.inner.borrow_mut(); let is_2d = matrix.is_2d.get(); let rotation = Rotation3::from_axis_angle( From 048fe96c1eaab00dad8090139203fc85bc2e42e9 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sun, 5 Jan 2025 16:42:41 +0900 Subject: [PATCH 09/24] tweak --- ext/geometry/01_geometry.js | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 82f90f299afbb7..8a31ed7ebd9242 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -778,7 +778,7 @@ class DOMMatrixReadOnly { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_inner] = this[_inner].clone().translate(tx, ty, tz); + matrix[_inner] = this[_inner].translate(tx, ty, tz); return matrix; } @@ -794,13 +794,13 @@ class DOMMatrixReadOnly { const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; if (originX === 0 && originY === 0 && originZ === 0) { - matrix[_inner] = this[_inner].clone().scaleWithoutOrigin( + matrix[_inner] = this[_inner].scaleWithoutOrigin( scaleX, scaleY, scaleZ, ); } else { - matrix[_inner] = this[_inner].clone().scaleWithOrigin( + matrix[_inner] = this[_inner].scaleWithOrigin( scaleX, scaleY, scaleZ, @@ -816,7 +816,7 @@ class DOMMatrixReadOnly { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_inner] = this[_inner].clone().scaleWithoutOrigin( + matrix[_inner] = this[_inner].scaleWithoutOrigin( scaleX, scaleY, 1, @@ -829,13 +829,13 @@ class DOMMatrixReadOnly { const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; if (originX === 0 && originY === 0 && originZ === 0) { - matrix[_inner] = this[_inner].clone().scaleWithoutOrigin( + matrix[_inner] = this[_inner].scaleWithoutOrigin( scale, scale, scale, ); } else { - matrix[_inner] = this[_inner].clone().scaleWithOrigin( + matrix[_inner] = this[_inner].scaleWithOrigin( scale, scale, scale, @@ -859,7 +859,7 @@ class DOMMatrixReadOnly { } const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_inner] = this[_inner].clone().rotate( + matrix[_inner] = this[_inner].rotate( rotX, rotY, rotZ, @@ -871,7 +871,7 @@ class DOMMatrixReadOnly { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_inner] = this[_inner].clone().rotateFromVector(x, y); + matrix[_inner] = this[_inner].rotateFromVector(x, y); return matrix; } @@ -879,7 +879,7 @@ class DOMMatrixReadOnly { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_inner] = this[_inner].clone().rotateAxisAngle( + matrix[_inner] = this[_inner].rotateAxisAngle( x, y, z, @@ -892,7 +892,7 @@ class DOMMatrixReadOnly { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_inner] = this[_inner].clone().skewX(sx); + matrix[_inner] = this[_inner].skewX(sx); return matrix; } @@ -900,7 +900,7 @@ class DOMMatrixReadOnly { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_inner] = this[_inner].clone().skewY(sy); + matrix[_inner] = this[_inner].skewY(sy); return matrix; } @@ -926,7 +926,7 @@ class DOMMatrixReadOnly { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_inner] = this[_inner].clone().flipX(); + matrix[_inner] = this[_inner].flipX(); return matrix; } @@ -934,7 +934,7 @@ class DOMMatrixReadOnly { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_inner] = this[_inner].clone().flipY(); + matrix[_inner] = this[_inner].flipY(); return matrix; } @@ -942,7 +942,7 @@ class DOMMatrixReadOnly { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); const matrix = webidl.createBranded(DOMMatrix); matrix[_writable] = true; - matrix[_inner] = this[_inner].clone().inverse(); + matrix[_inner] = this[_inner].inverse(); return matrix; } From fd84470aaa64ae875a9c6dd0c80ae6629696745d Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Sun, 12 Jan 2025 02:05:30 +0900 Subject: [PATCH 10/24] update --- ext/geometry/01_geometry.js | 73 +++++--------------- ext/geometry/README.md | 2 +- ext/geometry/lib.rs | 131 +++++++++++++++++++++++------------- 3 files changed, 102 insertions(+), 104 deletions(-) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 8a31ed7ebd9242..fa123ba27cc641 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -1,12 +1,7 @@ // Copyright 2018-2025 the Deno authors. MIT license. import { primordials } from "ext:core/mod.js"; -import { - DOMMatrixInner, - DOMPointInner, - DOMRectInner, - op_geometry_create_matrix_identity, -} from "ext:core/ops"; +import { DOMMatrixInner, DOMPointInner, DOMRectInner } from "ext:core/ops"; const { ArrayPrototypeJoin, Float32Array, @@ -267,29 +262,14 @@ class DOMRectReadOnly { [_inner]; constructor(x = 0, y = 0, width = 0, height = 0) { - this[_inner] = new DOMRectInner( - webidl.converters["unrestricted double"](x), - webidl.converters["unrestricted double"](y), - webidl.converters["unrestricted double"](width), - webidl.converters["unrestricted double"](height), - ); + this[_inner] = new DOMRectInner(x, y, width, height); this[_brand] = _brand; } static fromRect(other = { __proto__: null }) { - other = webidl.converters.DOMRectInit( - other, - "Failed to execute 'DOMRectReadOnly.fromRect'", - "Argument 1", - ); const rect = webidl.createBranded(DOMRectReadOnly); rect[_writable] = false; - rect[_inner] = new DOMRectInner( - other.x, - other.y, - other.width, - other.height, - ); + rect[_inner] = DOMRectInner.fromRect(other); return rect; } @@ -315,41 +295,28 @@ class DOMRectReadOnly { get top() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); - const { y, height } = this[_inner]; - return MathMin(y, y + height); + return this[_inner].top; } get right() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); - const { x, width } = this[_inner]; - return MathMax(x, x + width); + return this[_inner].right; } get bottom() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); - const { y, height } = this[_inner]; - return MathMax(y, y + height); + return this[_inner].bottom; } get left() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); - const { x, width } = this[_inner]; - return MathMin(x, x + width); + return this[_inner].left; } toJSON() { webidl.assertBranded(this, DOMRectReadOnlyPrototype); - const { x, y, width, height } = this[_inner]; - return { - x, - y, - width, - height, - top: MathMin(y, y + height), - right: MathMax(x, x + width), - bottom: MathMax(y, y + height), - left: MathMin(x, x + width), - }; + const { x, y, width, height, top, right, bottom, left } = this[_inner]; + return { x, y, width, height, top, right, bottom, left }; } [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { @@ -380,19 +347,9 @@ class DOMRect extends DOMRectReadOnly { [_writable] = true; static fromRect(other = { __proto__: null }) { - other = webidl.converters.DOMRectInit( - other, - "Failed to execute 'DOMRect.fromRect'", - "Argument 1", - ); const rect = webidl.createBranded(DOMRect); rect[_writable] = true; - rect[_inner] = new DOMRectInner( - other.x, - other.y, - other.width, - other.height, - ); + rect[_inner] = DOMRectInner.fromRect(other); return rect; } @@ -403,7 +360,7 @@ class DOMRect extends DOMRectReadOnly { set x(value) { webidl.assertBranded(this, DOMRectPrototype); assertWritable(this); - this[_inner].x = webidl.converters["unrestricted double"](value); + this[_inner].x = value; } get y() { @@ -413,7 +370,7 @@ class DOMRect extends DOMRectReadOnly { set y(value) { webidl.assertBranded(this, DOMRectPrototype); assertWritable(this); - this[_inner].y = webidl.converters["unrestricted double"](value); + this[_inner].y = value; } get width() { @@ -423,7 +380,7 @@ class DOMRect extends DOMRectReadOnly { set width(value) { webidl.assertBranded(this, DOMRectPrototype); assertWritable(this); - this[_inner].width = webidl.converters["unrestricted double"](value); + this[_inner].width = value; } get height() { @@ -433,7 +390,7 @@ class DOMRect extends DOMRectReadOnly { set height(value) { webidl.assertBranded(this, DOMRectPrototype); assertWritable(this); - this[_inner].height = webidl.converters["unrestricted double"](value); + this[_inner].height = value; } [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { @@ -598,7 +555,7 @@ class DOMMatrixReadOnly { const prefix = `Failed to construct '${this.constructor.name}'`; this[_brand] = _brand; if (init === undefined) { - this[_inner] = op_geometry_create_matrix_identity(); + this[_inner] = DOMMatrixInner.identity(); } else if ( webidl.type(init) === "Object" && init[SymbolIterator] !== undefined ) { diff --git a/ext/geometry/README.md b/ext/geometry/README.md index 7e10bfeecd4a1a..1ba0d3ee175074 100644 --- a/ext/geometry/README.md +++ b/ext/geometry/README.md @@ -87,12 +87,12 @@ the `extensions` field of your `RuntimeOptions` - **deno_webidl**: Provided by the `deno_webidl` crate - **deno_web**: Provided by the `deno_web` crate - **deno_console**: Provided by the `deno_console` crate +- **deno_error**: Provided by the `deno_error` crate ## Provided ops Following ops are provided, which can be accessed through `Deno.ops`: -- op_geometry_create_matrix_identity - DOMMatrixInner - DOMPointInner - DOMRectInner diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 5645f0fdbb2eb5..94c45f0cd4bf80 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -6,7 +6,6 @@ use std::mem; use std::path::PathBuf; use std::slice; -use deno_core::cppgc; use deno_core::op2; use deno_core::v8; use deno_core::GarbageCollected; @@ -23,7 +22,6 @@ use nalgebra::Vector4; deno_core::extension!( deno_geometry, deps = [deno_webidl, deno_web, deno_console], - ops = [op_geometry_create_matrix_identity], objects = [DOMPointInner, DOMRectInner, DOMMatrixInner], esm = ["00_init.js"], lazy_loaded_esm = ["01_geometry.js"], @@ -140,7 +138,9 @@ impl DOMPointInner { &self, matrix: v8::Local, ) -> DOMPointInner { - let matrix = cast_to_matrix(matrix); + // SAFETY: cast v8::Local + let matrix: v8::Local<'_, DOMMatrixInner> = + unsafe { mem::transmute(matrix) }; let out = DOMPointInner { x: Cell::new(0.0), y: Cell::new(0.0), @@ -152,6 +152,19 @@ impl DOMPointInner { } } +#[derive(WebIDL)] +#[webidl(dictionary)] +pub struct DOMRectInit { + #[webidl(default = 0.0)] + x: f64, + #[webidl(default = 0.0)] + y: f64, + #[webidl(default = 0.0)] + width: f64, + #[webidl(default = 0.0)] + height: f64, +} + pub struct DOMRectInner { x: Cell, y: Cell, @@ -165,7 +178,12 @@ impl GarbageCollected for DOMRectInner {} impl DOMRectInner { #[constructor] #[cppgc] - pub fn constructor(x: f64, y: f64, width: f64, height: f64) -> DOMRectInner { + pub fn constructor( + #[webidl] x: f64, + #[webidl] y: f64, + #[webidl] width: f64, + #[webidl] height: f64, + ) -> DOMRectInner { DOMRectInner { x: Cell::new(x), y: Cell::new(y), @@ -174,15 +192,25 @@ impl DOMRectInner { } } + #[static_method] + #[cppgc] + pub fn from_rect(#[webidl] init: DOMRectInit) -> DOMRectInner { + DOMRectInner { + x: Cell::new(init.x), + y: Cell::new(init.y), + width: Cell::new(init.width), + height: Cell::new(init.height), + } + } + #[fast] #[getter] pub fn x(&self) -> f64 { self.x.get() } - #[fast] #[setter] - pub fn x(&self, value: f64) { + pub fn x(&self, #[webidl] value: f64) { self.x.set(value) } @@ -192,9 +220,8 @@ impl DOMRectInner { self.y.get() } - #[fast] #[setter] - pub fn y(&self, value: f64) { + pub fn y(&self, #[webidl] value: f64) { self.y.set(value) } @@ -204,9 +231,8 @@ impl DOMRectInner { self.width.get() } - #[fast] #[setter] - pub fn width(&self, value: f64) { + pub fn width(&self, #[webidl] value: f64) { self.width.set(value) } @@ -216,11 +242,42 @@ impl DOMRectInner { self.height.get() } - #[fast] #[setter] - pub fn height(&self, value: f64) { + pub fn height(&self, #[webidl] value: f64) { self.height.set(value) } + + #[fast] + #[getter] + pub fn top(&self) -> f64 { + let y = self.y.get(); + let height = self.height.get(); + y.min(y + height) + } + + #[fast] + #[getter] + pub fn right(&self) -> f64 { + let x = self.x.get(); + let width = self.width.get(); + x.max(x + width) + } + + #[fast] + #[getter] + pub fn bottom(&self) -> f64 { + let y = self.y.get(); + let height = self.height.get(); + y.max(y + height) + } + + #[fast] + #[getter] + pub fn left(&self) -> f64 { + let x = self.x.get(); + let width = self.width.get(); + x.min(x + width) + } } #[derive(WebIDL)] @@ -424,6 +481,15 @@ impl DOMMatrixInner { } } + #[static_method] + #[cppgc] + pub fn identity() -> DOMMatrixInner { + DOMMatrixInner { + inner: RefCell::new(Matrix4::identity()), + is_2d: Cell::new(true), + } + } + #[cppgc] pub fn clone(&self) -> DOMMatrixInner { self.clone() @@ -994,7 +1060,8 @@ impl DOMMatrixInner { #[cppgc] pub fn multiply(&self, other: v8::Local) -> DOMMatrixInner { - let other = cast_to_matrix(other); + // SAFETY: cast v8::Local + let other: v8::Local<'_, DOMMatrixInner> = unsafe { mem::transmute(other) }; let out = DOMMatrixInner { inner: RefCell::new(Matrix4::zeros()), is_2d: Cell::new(true), @@ -1005,7 +1072,8 @@ impl DOMMatrixInner { #[fast] pub fn multiply_self(&self, other: v8::Local) { - let other = cast_to_matrix(other); + // SAFETY: cast v8::Local + let other: v8::Local<'_, DOMMatrixInner> = unsafe { mem::transmute(other) }; let result = DOMMatrixInner { inner: RefCell::new(Matrix4::zeros()), is_2d: Cell::new(true), @@ -1017,7 +1085,8 @@ impl DOMMatrixInner { #[fast] pub fn pre_multiply_self(&self, other: v8::Local) { - let other = cast_to_matrix(other); + // SAFETY: cast v8::Local + let other: v8::Local<'_, DOMMatrixInner> = unsafe { mem::transmute(other) }; let result = DOMMatrixInner { inner: RefCell::new(Matrix4::zeros()), is_2d: Cell::new(true), @@ -1055,7 +1124,8 @@ impl DOMMatrixInner { #[cppgc] pub fn transform_point(&self, point: v8::Local) -> DOMPointInner { - let point = cast_to_point(point); + // SAFETY: cast v8::Local + let point: v8::Local<'_, DOMPointInner> = unsafe { mem::transmute(point) }; let out = DOMPointInner { x: Cell::new(0.0), y: Cell::new(0.0), @@ -1067,35 +1137,6 @@ impl DOMMatrixInner { } } -#[op2] -pub fn op_geometry_create_matrix_identity<'a>( - scope: &mut v8::HandleScope<'a>, -) -> v8::Local<'a, v8::Object> { - cppgc::make_cppgc_object( - scope, - DOMMatrixInner { - inner: RefCell::new(Matrix4::identity()), - is_2d: Cell::new(true), - }, - ) -} - -#[inline] -fn cast_to_point( - obj: v8::Local<'_, v8::Object>, -) -> v8::Local<'_, DOMPointInner> { - // SAFETY: cast v8::Local - unsafe { mem::transmute(obj) } -} - -#[inline] -fn cast_to_matrix( - obj: v8::Local<'_, v8::Object>, -) -> v8::Local<'_, DOMMatrixInner> { - // SAFETY: cast v8::Local - unsafe { mem::transmute(obj) } -} - #[inline] fn matrix_translate(matrix: &DOMMatrixInner, tx: f64, ty: f64, tz: f64) { let mut inner = matrix.inner.borrow_mut(); From ecc75e6e6088e8d55c6e554cc9eca1ab05543b27 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Mon, 13 Jan 2025 01:36:50 +0900 Subject: [PATCH 11/24] update --- ext/geometry/01_geometry.js | 272 +++++++++++++++--------------------- ext/geometry/README.md | 2 +- ext/geometry/lib.rs | 159 ++++++++++++++++++++- 3 files changed, 274 insertions(+), 159 deletions(-) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index fa123ba27cc641..07f639f424ad9c 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -1,13 +1,16 @@ // Copyright 2018-2025 the Deno authors. MIT license. import { primordials } from "ext:core/mod.js"; -import { DOMMatrixInner, DOMPointInner, DOMRectInner } from "ext:core/ops"; +import { + DOMMatrixInner, + DOMPointInner, + DOMQuadInner, + DOMRectInner, +} from "ext:core/ops"; const { ArrayPrototypeJoin, Float32Array, Float64Array, - MathMax, - MathMin, ObjectDefineProperty, ObjectPrototypeIsPrototypeOf, Symbol, @@ -21,80 +24,6 @@ import { createFilteredInspectProxy } from "ext:deno_console/01_console.js"; import * as webidl from "ext:deno_webidl/00_webidl.js"; import { DOMException } from "ext:deno_web/01_dom_exception.js"; -webidl.converters.DOMPointInit = webidl.createDictionaryConverter( - "DOMPointInit", - [ - { - key: "x", - converter: webidl.converters["unrestricted double"], - defaultValue: 0, - }, - { - key: "y", - converter: webidl.converters["unrestricted double"], - defaultValue: 0, - }, - { - key: "z", - converter: webidl.converters["unrestricted double"], - defaultValue: 0, - }, - { - key: "w", - converter: webidl.converters["unrestricted double"], - defaultValue: 1, - }, - ], -); - -webidl.converters.DOMRectInit = webidl.createDictionaryConverter( - "DOMRectInit", - [ - { - key: "x", - converter: webidl.converters["unrestricted double"], - defaultValue: 0, - }, - { - key: "y", - converter: webidl.converters["unrestricted double"], - defaultValue: 0, - }, - { - key: "width", - converter: webidl.converters["unrestricted double"], - defaultValue: 0, - }, - { - key: "height", - converter: webidl.converters["unrestricted double"], - defaultValue: 0, - }, - ], -); - -webidl.converters.DOMQuadInit = webidl.createDictionaryConverter( - "DOMQuadInit", - [ - { - key: "p1", - converter: webidl.converters.DOMPointInit, - }, - { - key: "p2", - converter: webidl.converters.DOMPointInit, - }, - { - key: "p3", - converter: webidl.converters.DOMPointInit, - }, - { - key: "p4", - converter: webidl.converters.DOMPointInit, - }, - ], -); - const _inner = Symbol("[[inner]]"); // Property to prevent writing values when an immutable instance is changed to // a mutable instance by Object.setPrototypeOf @@ -104,6 +33,7 @@ const _brand = webidl.brand; class DOMPointReadOnly { [_writable] = false; + /** @type {DOMPointInner} */ [_inner]; constructor(x = 0, y = 0, z = 0, w = 1) { @@ -158,13 +88,8 @@ class DOMPointReadOnly { toJSON() { webidl.assertBranded(this, DOMPointReadOnlyPrototype); - const inner = this[_inner]; - return { - x: inner.x, - y: inner.y, - z: inner.z, - w: inner.w, - }; + const { x, y, z, w } = this[_inner]; + return { x, y, z, w }; } [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { @@ -189,6 +114,8 @@ const DOMPointReadOnlyPrototype = DOMPointReadOnly.prototype; class DOMPoint extends DOMPointReadOnly { [_writable] = true; + /** @type {DOMPointInner} */ + [_inner]; static fromPoint(other = { __proto__: null }) { const point = webidl.createBranded(DOMPoint); @@ -219,7 +146,7 @@ class DOMPoint extends DOMPointReadOnly { get z() { webidl.assertBranded(this, DOMPointPrototype); - return this[_inner].x; + return this[_inner].z; } set z(value) { webidl.assertBranded(this, DOMPointPrototype); @@ -259,6 +186,7 @@ const DOMPointPrototype = DOMPoint.prototype; class DOMRectReadOnly { [_writable] = false; + /** @type {DOMRectInner} */ [_inner]; constructor(x = 0, y = 0, width = 0, height = 0) { @@ -345,6 +273,8 @@ const DOMRectReadOnlyPrototype = DOMRectReadOnly.prototype; class DOMRect extends DOMRectReadOnly { [_writable] = true; + /** @type {DOMRectInner} */ + [_inner]; static fromRect(other = { __proto__: null }) { const rect = webidl.createBranded(DOMRect); @@ -423,13 +353,15 @@ const _p3 = Symbol("[[p3]]"); const _p4 = Symbol("[[p4]]"); class DOMQuad { - /** @type {DOMPoint} */ + /** @type {DOMQuadInner} */ + [_inner]; + /** @type {DOMPoint=} */ [_p1]; - /** @type {DOMPoint} */ + /** @type {DOMPoint=} */ [_p2]; - /** @type {DOMPoint} */ + /** @type {DOMPoint=} */ [_p3]; - /** @type {DOMPoint} */ + /** @type {DOMPoint=} */ [_p4]; constructor( @@ -438,82 +370,83 @@ class DOMQuad { p3 = { __proto__: null }, p4 = { __proto__: null }, ) { - this[_p1] = DOMPoint.fromPoint(p1); - this[_p2] = DOMPoint.fromPoint(p2); - this[_p3] = DOMPoint.fromPoint(p3); - this[_p4] = DOMPoint.fromPoint(p4); + this[_inner] = new DOMQuadInner(p1, p2, p3, p4); this[_brand] = _brand; } static fromRect(other = { __proto__: null }) { - other = webidl.converters.DOMRectInit( - other, - "Failed to execute 'DOMQuad.fromRect'", - "Argument 1", - ); - const { x, y, width, height } = other; const quad = webidl.createBranded(DOMQuad); - quad[_p1] = new DOMPoint(x, y, 0, 1); - quad[_p2] = new DOMPoint(x + width, y, 0, 1); - quad[_p3] = new DOMPoint(x + width, y + height, 0, 1); - quad[_p4] = new DOMPoint(x, y + height, 0, 1); + quad[_inner] = DOMQuadInner.fromRect(other); + quad[_p1] = undefined; + quad[_p2] = undefined; + quad[_p3] = undefined; + quad[_p4] = undefined; return quad; } static fromQuad(other = { __proto__: null }) { - other = webidl.converters.DOMQuadInit( - other, - "Failed to execute 'DOMQuad.fromQuad'", - "Argument 1", - ); const quad = webidl.createBranded(DOMQuad); - quad[_p1] = DOMPoint.fromPoint(other.p1); - quad[_p2] = DOMPoint.fromPoint(other.p2); - quad[_p3] = DOMPoint.fromPoint(other.p3); - quad[_p4] = DOMPoint.fromPoint(other.p4); + quad[_inner] = DOMQuadInner.fromQuad(other); + quad[_p1] = undefined; + quad[_p2] = undefined; + quad[_p3] = undefined; + quad[_p4] = undefined; return quad; } get p1() { webidl.assertBranded(this, DOMQuadPrototype); - return this[_p1]; + if (this[_p1] !== undefined) { + return this[_p1]; + } + const point = webidl.createBranded(DOMPoint); + point[_writable] = true; + point[_inner] = this[_inner].p1; + this[_p1] = point; + return point; } get p2() { webidl.assertBranded(this, DOMQuadPrototype); - return this[_p2]; + if (this[_p2] !== undefined) { + return this[_p2]; + } + const point = webidl.createBranded(DOMPoint); + point[_writable] = true; + point[_inner] = this[_inner].p2; + this[_p2] = point; + return point; } get p3() { webidl.assertBranded(this, DOMQuadPrototype); - return this[_p3]; + if (this[_p3] !== undefined) { + return this[_p3]; + } + const point = webidl.createBranded(DOMPoint); + point[_writable] = true; + point[_inner] = this[_inner].p3; + this[_p3] = point; + return point; } get p4() { webidl.assertBranded(this, DOMQuadPrototype); - return this[_p4]; + if (this[_p4] !== undefined) { + return this[_p4]; + } + const point = webidl.createBranded(DOMPoint); + point[_writable] = true; + point[_inner] = this[_inner].p4; + this[_p4] = point; + return point; } getBounds() { webidl.assertBranded(this, DOMQuadPrototype); - const { x: p1x, y: p1y } = this[_p1]; - const { x: p2x, y: p2y } = this[_p2]; - const { x: p3x, y: p3y } = this[_p3]; - const { x: p4x, y: p4y } = this[_p4]; - - const left = MathMin(p1x, p2x, p3x, p4x); - const top = MathMin(p1y, p2y, p3y, p4y); - const right = MathMax(p1x, p2x, p3x, p4x); - const bottom = MathMax(p1y, p2y, p3y, p4y); - const bounds = webidl.createBranded(DOMRect); bounds[_writable] = true; - bounds[_inner] = new DOMRectInner( - left, - top, - right - left, - bottom - top, - ); + bounds[_inner] = this[_inner].fromBounds(); return bounds; } @@ -937,32 +870,57 @@ class DOMMatrixReadOnly { toJSON() { webidl.assertBranded(this, DOMMatrixReadOnlyPrototype); - const inner = this[_inner]; + const { + a, + b, + c, + d, + e, + f, + m11, + m12, + m13, + m14, + m21, + m22, + m23, + m24, + m31, + m32, + m33, + m34, + m41, + m42, + m43, + m44, + is2D, + isIdentity, + } = this[_inner]; return { - a: inner.a, - b: inner.b, - c: inner.c, - d: inner.d, - e: inner.e, - f: inner.f, - m11: inner.m11, - m12: inner.m12, - m13: inner.m13, - m14: inner.m14, - m21: inner.m21, - m22: inner.m22, - m23: inner.m23, - m24: inner.m24, - m31: inner.m31, - m32: inner.m32, - m33: inner.m33, - m34: inner.m34, - m41: inner.m41, - m42: inner.m42, - m43: inner.m43, - m44: inner.m44, - is2D: inner.is2D, - isIdentity: inner.isIdentity, + a, + b, + c, + d, + e, + f, + m11, + m12, + m13, + m14, + m21, + m22, + m23, + m24, + m31, + m32, + m33, + m34, + m41, + m42, + m43, + m44, + is2D, + isIdentity, }; } diff --git a/ext/geometry/README.md b/ext/geometry/README.md index 1ba0d3ee175074..8c2f421b10d5e4 100644 --- a/ext/geometry/README.md +++ b/ext/geometry/README.md @@ -87,7 +87,6 @@ the `extensions` field of your `RuntimeOptions` - **deno_webidl**: Provided by the `deno_webidl` crate - **deno_web**: Provided by the `deno_web` crate - **deno_console**: Provided by the `deno_console` crate -- **deno_error**: Provided by the `deno_error` crate ## Provided ops @@ -95,4 +94,5 @@ Following ops are provided, which can be accessed through `Deno.ops`: - DOMMatrixInner - DOMPointInner +- DOMQuadInner - DOMRectInner diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 94c45f0cd4bf80..39699e910cafa3 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -2,8 +2,10 @@ use std::cell::Cell; use std::cell::RefCell; +use std::cell::UnsafeCell; use std::mem; use std::path::PathBuf; +use std::ptr; use std::slice; use deno_core::op2; @@ -22,7 +24,7 @@ use nalgebra::Vector4; deno_core::extension!( deno_geometry, deps = [deno_webidl, deno_web, deno_console], - objects = [DOMPointInner, DOMRectInner, DOMMatrixInner], + objects = [DOMPointInner, DOMRectInner, DOMQuadInner, DOMMatrixInner], esm = ["00_init.js"], lazy_loaded_esm = ["01_geometry.js"], ); @@ -280,6 +282,161 @@ impl DOMRectInner { } } +#[derive(WebIDL)] +#[webidl(dictionary)] +pub struct DOMQuadInit { + p1: DOMPointInit, + p2: DOMPointInit, + p3: DOMPointInit, + p4: DOMPointInit, +} + +pub struct DOMQuadInner { + p1: UnsafeCell, + p2: UnsafeCell, + p3: UnsafeCell, + p4: UnsafeCell, +} + +impl GarbageCollected for DOMQuadInner {} + +#[op2] +impl DOMQuadInner { + #[constructor] + #[cppgc] + pub fn constructor( + #[webidl] p1: DOMPointInit, + #[webidl] p2: DOMPointInit, + #[webidl] p3: DOMPointInit, + #[webidl] p4: DOMPointInit, + ) -> DOMQuadInner { + #[inline] + fn from_point(point: DOMPointInit) -> DOMPointInner { + DOMPointInner { + x: Cell::new(point.x), + y: Cell::new(point.y), + z: Cell::new(point.z), + w: Cell::new(point.w), + } + } + + DOMQuadInner { + p1: UnsafeCell::new(from_point(p1)), + p2: UnsafeCell::new(from_point(p2)), + p3: UnsafeCell::new(from_point(p3)), + p4: UnsafeCell::new(from_point(p4)), + } + } + + #[static_method] + #[cppgc] + pub fn from_rect(#[webidl] rect: DOMRectInit) -> DOMQuadInner { + let DOMRectInit { + x, + y, + width, + height, + } = rect; + DOMQuadInner { + p1: UnsafeCell::new(DOMPointInner { + x: Cell::new(x), + y: Cell::new(y), + z: Cell::new(0.0), + w: Cell::new(1.0), + }), + p2: UnsafeCell::new(DOMPointInner { + x: Cell::new(x + width), + y: Cell::new(y), + z: Cell::new(0.0), + w: Cell::new(1.0), + }), + p3: UnsafeCell::new(DOMPointInner { + x: Cell::new(x + width), + y: Cell::new(y + height), + z: Cell::new(0.0), + w: Cell::new(1.0), + }), + p4: UnsafeCell::new(DOMPointInner { + x: Cell::new(x), + y: Cell::new(y + height), + z: Cell::new(0.0), + w: Cell::new(1.0), + }), + } + } + + #[static_method] + #[cppgc] + pub fn from_quad(#[webidl] quad: DOMQuadInit) -> DOMQuadInner { + #[inline] + fn from_point(point: DOMPointInit) -> DOMPointInner { + DOMPointInner { + x: Cell::new(point.x), + y: Cell::new(point.y), + z: Cell::new(point.z), + w: Cell::new(point.w), + } + } + + DOMQuadInner { + p1: UnsafeCell::new(from_point(quad.p1)), + p2: UnsafeCell::new(from_point(quad.p2)), + p3: UnsafeCell::new(from_point(quad.p3)), + p4: UnsafeCell::new(from_point(quad.p4)), + } + } + + #[cppgc] + #[getter] + pub fn p1(&self) -> DOMPointInner { + // SAFETY: ptr is alive + unsafe { ptr::read(self.p1.get()) } + } + + #[cppgc] + #[getter] + pub fn p2(&self) -> DOMPointInner { + // SAFETY: ptr is alive + unsafe { ptr::read(self.p2.get()) } + } + + #[cppgc] + #[getter] + pub fn p3(&self) -> DOMPointInner { + // SAFETY: ptr is alive + unsafe { ptr::read(self.p3.get()) } + } + + #[cppgc] + #[getter] + pub fn p4(&self) -> DOMPointInner { + // SAFETY: ptr is alive + unsafe { ptr::read(self.p4.get()) } + } + + #[cppgc] + pub fn get_bounds(&self) -> DOMRectInner { + // SAFETY: ptr is alive + let p1 = unsafe { ptr::read(self.p1.get()) }; + // SAFETY: ptr is alive + let p2 = unsafe { ptr::read(self.p2.get()) }; + // SAFETY: ptr is alive + let p3 = unsafe { ptr::read(self.p3.get()) }; + // SAFETY: ptr is alive + let p4 = unsafe { ptr::read(self.p4.get()) }; + let left = p1.x.get().min(p2.x.get()).min(p3.x.get()).min(p4.x.get()); + let top = p1.y.get().min(p2.y.get()).min(p3.y.get()).min(p4.y.get()); + let right = p1.x.get().max(p2.x.get()).max(p3.x.get()).max(p4.x.get()); + let bottom = p1.y.get().max(p2.y.get()).max(p3.y.get()).max(p4.y.get()); + DOMRectInner { + x: Cell::new(left), + y: Cell::new(top), + width: Cell::new(right - left), + height: Cell::new(bottom - top), + } + } +} + #[derive(WebIDL)] #[webidl(dictionary)] pub struct DOMMatrixInit { From 7cc681ca35d10cd277b8f170064128f1cf86d01f Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Mon, 13 Jan 2025 10:31:31 +0900 Subject: [PATCH 12/24] fix --- ext/geometry/01_geometry.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index 07f639f424ad9c..db7beec3faea40 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -114,8 +114,6 @@ const DOMPointReadOnlyPrototype = DOMPointReadOnly.prototype; class DOMPoint extends DOMPointReadOnly { [_writable] = true; - /** @type {DOMPointInner} */ - [_inner]; static fromPoint(other = { __proto__: null }) { const point = webidl.createBranded(DOMPoint); @@ -273,8 +271,6 @@ const DOMRectReadOnlyPrototype = DOMRectReadOnly.prototype; class DOMRect extends DOMRectReadOnly { [_writable] = true; - /** @type {DOMRectInner} */ - [_inner]; static fromRect(other = { __proto__: null }) { const rect = webidl.createBranded(DOMRect); @@ -482,6 +478,7 @@ const DOMQuadPrototype = DOMQuad.prototype; class DOMMatrixReadOnly { [_writable] = false; + /** @type {DOMMatrixInner} */ [_inner]; constructor(init = undefined) { From 3f9b0ee7af9276a9fe8adfa6eeb8d72dfa0f425e Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Mon, 13 Jan 2025 10:31:54 +0900 Subject: [PATCH 13/24] refactor --- Cargo.toml | 1 + ext/geometry/lib.rs | 130 +++++++++++++++++--------------------------- 2 files changed, 51 insertions(+), 80 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 47c5c7356e7e04..8b2da31561f9ec 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -230,6 +230,7 @@ hkdf = "0.12.3" rsa = { version = "0.9.3", default-features = false, features = ["std", "pem", "hazmat"] } # hazmat needed for PrehashSigner in ext/node # geometry +# TODO(petamoriken): Prefer to use glam as well as wgpu, but glam is not sufficient for mutable operations nalgebra = { version = "0.33.2", default-features = false, features = ["std"] } # webgpu diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 39699e910cafa3..115f435d7db9b5 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -54,10 +54,7 @@ pub struct DOMPointInit { } pub struct DOMPointInner { - x: Cell, - y: Cell, - z: Cell, - w: Cell, + inner: RefCell>, } impl GarbageCollected for DOMPointInner {} @@ -73,10 +70,7 @@ impl DOMPointInner { #[webidl] w: f64, ) -> DOMPointInner { DOMPointInner { - x: Cell::new(x), - y: Cell::new(y), - z: Cell::new(z), - w: Cell::new(w), + inner: RefCell::new(Vector4::new(x, y, z, w)), } } @@ -84,55 +78,52 @@ impl DOMPointInner { #[cppgc] pub fn from_point(#[webidl] init: DOMPointInit) -> DOMPointInner { DOMPointInner { - x: Cell::new(init.x), - y: Cell::new(init.y), - z: Cell::new(init.z), - w: Cell::new(init.w), + inner: RefCell::new(Vector4::new(init.x, init.y, init.z, init.w)), } } #[fast] #[getter] pub fn x(&self) -> f64 { - self.x.get() + self.inner.borrow().x } #[setter] pub fn x(&self, #[webidl] value: f64) { - self.x.set(value) + self.inner.borrow_mut().x = value } #[fast] #[getter] pub fn y(&self) -> f64 { - self.y.get() + self.inner.borrow().y } #[setter] pub fn y(&self, #[webidl] value: f64) { - self.y.set(value) + self.inner.borrow_mut().y = value } #[fast] #[getter] pub fn z(&self) -> f64 { - self.z.get() + self.inner.borrow().z } #[setter] pub fn z(&self, #[webidl] value: f64) { - self.z.set(value) + self.inner.borrow_mut().z = value } #[fast] #[getter] pub fn w(&self) -> f64 { - self.w.get() + self.inner.borrow().w } #[setter] pub fn w(&self, #[webidl] value: f64) { - self.w.set(value) + self.inner.borrow_mut().w = value } #[cppgc] @@ -144,10 +135,7 @@ impl DOMPointInner { let matrix: v8::Local<'_, DOMMatrixInner> = unsafe { mem::transmute(matrix) }; let out = DOMPointInner { - x: Cell::new(0.0), - y: Cell::new(0.0), - z: Cell::new(0.0), - w: Cell::new(0.0), + inner: RefCell::new(Vector4::zeros()), }; matrix_transform_point(&matrix, self, &out); out @@ -313,10 +301,7 @@ impl DOMQuadInner { #[inline] fn from_point(point: DOMPointInit) -> DOMPointInner { DOMPointInner { - x: Cell::new(point.x), - y: Cell::new(point.y), - z: Cell::new(point.z), - w: Cell::new(point.w), + inner: RefCell::new(Vector4::new(point.x, point.y, point.z, point.w)), } } @@ -339,28 +324,16 @@ impl DOMQuadInner { } = rect; DOMQuadInner { p1: UnsafeCell::new(DOMPointInner { - x: Cell::new(x), - y: Cell::new(y), - z: Cell::new(0.0), - w: Cell::new(1.0), + inner: RefCell::new(Vector4::new(x, y, 0.0, 1.0)), }), p2: UnsafeCell::new(DOMPointInner { - x: Cell::new(x + width), - y: Cell::new(y), - z: Cell::new(0.0), - w: Cell::new(1.0), + inner: RefCell::new(Vector4::new(x + width, y, 0.0, 1.0)), }), p3: UnsafeCell::new(DOMPointInner { - x: Cell::new(x + width), - y: Cell::new(y + height), - z: Cell::new(0.0), - w: Cell::new(1.0), + inner: RefCell::new(Vector4::new(x + width, y + height, 0.0, 1.0)), }), p4: UnsafeCell::new(DOMPointInner { - x: Cell::new(x), - y: Cell::new(y + height), - z: Cell::new(0.0), - w: Cell::new(1.0), + inner: RefCell::new(Vector4::new(x, y + height, 0.0, 1.0)), }), } } @@ -371,10 +344,7 @@ impl DOMQuadInner { #[inline] fn from_point(point: DOMPointInit) -> DOMPointInner { DOMPointInner { - x: Cell::new(point.x), - y: Cell::new(point.y), - z: Cell::new(point.z), - w: Cell::new(point.w), + inner: RefCell::new(Vector4::new(point.x, point.y, point.z, point.w)), } } @@ -424,10 +394,14 @@ impl DOMQuadInner { let p3 = unsafe { ptr::read(self.p3.get()) }; // SAFETY: ptr is alive let p4 = unsafe { ptr::read(self.p4.get()) }; - let left = p1.x.get().min(p2.x.get()).min(p3.x.get()).min(p4.x.get()); - let top = p1.y.get().min(p2.y.get()).min(p3.y.get()).min(p4.y.get()); - let right = p1.x.get().max(p2.x.get()).max(p3.x.get()).max(p4.x.get()); - let bottom = p1.y.get().max(p2.y.get()).max(p3.y.get()).max(p4.y.get()); + let p1 = p1.inner.borrow(); + let p2 = p2.inner.borrow(); + let p3 = p3.inner.borrow(); + let p4 = p4.inner.borrow(); + let left = p1.x.min(p2.x).min(p3.x).min(p4.x); + let top = p1.y.min(p2.y).min(p3.y).min(p4.y); + let right = p1.x.max(p2.x).max(p3.x).max(p4.x); + let bottom = p1.y.max(p2.y).max(p3.y).max(p4.y); DOMRectInner { x: Cell::new(left), y: Cell::new(top), @@ -577,7 +551,6 @@ impl DOMMatrixInner { let m22 = fixup!(init.m22, init.d, 1.0); let m41 = fixup!(init.m41, init.e, 0.0); let m42 = fixup!(init.m42, init.f, 0.0); - let is_2d = { let is_2d_can_be_true = init.m13 == 0.0 && init.m14 == 0.0 @@ -1059,7 +1032,7 @@ impl DOMMatrixInner { unsafe { slice::from_raw_parts( self.inner.borrow().as_slice().as_ptr() as *mut u8, - 128, + mem::size_of::() * 16, ) } .to_vec() @@ -1094,7 +1067,7 @@ impl DOMMatrixInner { #[webidl] sz: f64, ) -> DOMMatrixInner { let out = self.clone(); - matrix_scale(&out, sx, sy, sz); + matrix_scale_without_origin(&out, sx, sy, sz); out } @@ -1104,7 +1077,7 @@ impl DOMMatrixInner { #[webidl] sy: f64, #[webidl] sz: f64, ) { - matrix_scale(self, sx, sy, sz); + matrix_scale_without_origin(self, sx, sy, sz); } #[cppgc] @@ -1284,10 +1257,7 @@ impl DOMMatrixInner { // SAFETY: cast v8::Local let point: v8::Local<'_, DOMPointInner> = unsafe { mem::transmute(point) }; let out = DOMPointInner { - x: Cell::new(0.0), - y: Cell::new(0.0), - z: Cell::new(0.0), - w: Cell::new(0.0), + inner: RefCell::new(Vector4::zeros()), }; matrix_transform_point(self, &point, &out); out @@ -1304,7 +1274,12 @@ fn matrix_translate(matrix: &DOMMatrixInner, tx: f64, ty: f64, tz: f64) { } #[inline] -fn matrix_scale(matrix: &DOMMatrixInner, sx: f64, sy: f64, sz: f64) { +fn matrix_scale_without_origin( + matrix: &DOMMatrixInner, + sx: f64, + sy: f64, + sz: f64, +) { let mut inner = matrix.inner.borrow_mut(); let is_2d = matrix.is_2d.get(); let scaling = Vector3::new(sx, sy, sz); @@ -1460,12 +1435,12 @@ fn matrix_inverse(matrix: &DOMMatrixInner) { // SAFETY: in-range access let mut matrix3 = unsafe { Matrix3::new( - *inner.get_unchecked(0), - *inner.get_unchecked(4), - *inner.get_unchecked(12), - *inner.get_unchecked(1), - *inner.get_unchecked(5), - *inner.get_unchecked(13), + *inner.get_unchecked(INDEX_A), + *inner.get_unchecked(INDEX_C), + *inner.get_unchecked(INDEX_E), + *inner.get_unchecked(INDEX_B), + *inner.get_unchecked(INDEX_D), + *inner.get_unchecked(INDEX_F), 0.0, 0.0, 1.0, @@ -1478,12 +1453,12 @@ fn matrix_inverse(matrix: &DOMMatrixInner) { } // SAFETY: in-range access unsafe { - *inner.get_unchecked_mut(0) = *matrix3.get_unchecked(0); - *inner.get_unchecked_mut(1) = *matrix3.get_unchecked(1); - *inner.get_unchecked_mut(4) = *matrix3.get_unchecked(3); - *inner.get_unchecked_mut(5) = *matrix3.get_unchecked(4); - *inner.get_unchecked_mut(12) = *matrix3.get_unchecked(6); - *inner.get_unchecked_mut(13) = *matrix3.get_unchecked(7); + *inner.get_unchecked_mut(INDEX_A) = *matrix3.get_unchecked(0); + *inner.get_unchecked_mut(INDEX_B) = *matrix3.get_unchecked(1); + *inner.get_unchecked_mut(INDEX_C) = *matrix3.get_unchecked(3); + *inner.get_unchecked_mut(INDEX_D) = *matrix3.get_unchecked(4); + *inner.get_unchecked_mut(INDEX_E) = *matrix3.get_unchecked(6); + *inner.get_unchecked_mut(INDEX_F) = *matrix3.get_unchecked(7); } } else if !inner.try_inverse_mut() { inner.fill(f64::NAN); @@ -1496,12 +1471,7 @@ fn matrix_transform_point( out: &DOMPointInner, ) { let inner = matrix.inner.borrow(); - let point = - Vector4::new(point.x.get(), point.y.get(), point.z.get(), point.w.get()); - let mut result = Vector4::zeros(); + let point = point.inner.borrow(); + let mut result = out.inner.borrow_mut(); inner.mul_to(&point, &mut result); - out.x.set(result.x); - out.y.set(result.y); - out.z.set(result.z); - out.w.set(result.w); } From c28e753480a0d4cca2a953151929a3298b3dd26e Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Mon, 13 Jan 2025 11:26:36 +0900 Subject: [PATCH 14/24] use `unrestricted double` --- ext/geometry/lib.rs | 519 ++++++++++++++++++++++++-------------------- 1 file changed, 288 insertions(+), 231 deletions(-) diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 115f435d7db9b5..0af1871a6af4fd 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -10,6 +10,7 @@ use std::slice; use deno_core::op2; use deno_core::v8; +use deno_core::webidl; use deno_core::GarbageCollected; use deno_core::WebIDL; use nalgebra::Matrix3; @@ -43,14 +44,14 @@ pub enum GeometryError { #[derive(WebIDL)] #[webidl(dictionary)] pub struct DOMPointInit { - #[webidl(default = 0.0)] - x: f64, - #[webidl(default = 0.0)] - y: f64, - #[webidl(default = 0.0)] - z: f64, - #[webidl(default = 1.0)] - w: f64, + #[webidl(default = webidl::UnrestrictedDouble(0.0))] + x: webidl::UnrestrictedDouble, + #[webidl(default = webidl::UnrestrictedDouble(0.0))] + y: webidl::UnrestrictedDouble, + #[webidl(default = webidl::UnrestrictedDouble(0.0))] + z: webidl::UnrestrictedDouble, + #[webidl(default = webidl::UnrestrictedDouble(1.0))] + w: webidl::UnrestrictedDouble, } pub struct DOMPointInner { @@ -64,13 +65,13 @@ impl DOMPointInner { #[constructor] #[cppgc] pub fn constructor( - #[webidl] x: f64, - #[webidl] y: f64, - #[webidl] z: f64, - #[webidl] w: f64, + #[webidl] x: webidl::UnrestrictedDouble, + #[webidl] y: webidl::UnrestrictedDouble, + #[webidl] z: webidl::UnrestrictedDouble, + #[webidl] w: webidl::UnrestrictedDouble, ) -> DOMPointInner { DOMPointInner { - inner: RefCell::new(Vector4::new(x, y, z, w)), + inner: RefCell::new(Vector4::new(*x, *y, *z, *w)), } } @@ -78,7 +79,7 @@ impl DOMPointInner { #[cppgc] pub fn from_point(#[webidl] init: DOMPointInit) -> DOMPointInner { DOMPointInner { - inner: RefCell::new(Vector4::new(init.x, init.y, init.z, init.w)), + inner: RefCell::new(Vector4::new(*init.x, *init.y, *init.z, *init.w)), } } @@ -89,8 +90,8 @@ impl DOMPointInner { } #[setter] - pub fn x(&self, #[webidl] value: f64) { - self.inner.borrow_mut().x = value + pub fn x(&self, #[webidl] value: webidl::UnrestrictedDouble) { + self.inner.borrow_mut().x = *value } #[fast] @@ -100,8 +101,8 @@ impl DOMPointInner { } #[setter] - pub fn y(&self, #[webidl] value: f64) { - self.inner.borrow_mut().y = value + pub fn y(&self, #[webidl] value: webidl::UnrestrictedDouble) { + self.inner.borrow_mut().y = *value } #[fast] @@ -111,8 +112,8 @@ impl DOMPointInner { } #[setter] - pub fn z(&self, #[webidl] value: f64) { - self.inner.borrow_mut().z = value + pub fn z(&self, #[webidl] value: webidl::UnrestrictedDouble) { + self.inner.borrow_mut().z = *value } #[fast] @@ -122,8 +123,8 @@ impl DOMPointInner { } #[setter] - pub fn w(&self, #[webidl] value: f64) { - self.inner.borrow_mut().w = value + pub fn w(&self, #[webidl] value: webidl::UnrestrictedDouble) { + self.inner.borrow_mut().w = *value } #[cppgc] @@ -145,14 +146,14 @@ impl DOMPointInner { #[derive(WebIDL)] #[webidl(dictionary)] pub struct DOMRectInit { - #[webidl(default = 0.0)] - x: f64, - #[webidl(default = 0.0)] - y: f64, - #[webidl(default = 0.0)] - width: f64, - #[webidl(default = 0.0)] - height: f64, + #[webidl(default = webidl::UnrestrictedDouble(0.0))] + x: webidl::UnrestrictedDouble, + #[webidl(default = webidl::UnrestrictedDouble(0.0))] + y: webidl::UnrestrictedDouble, + #[webidl(default = webidl::UnrestrictedDouble(0.0))] + width: webidl::UnrestrictedDouble, + #[webidl(default = webidl::UnrestrictedDouble(0.0))] + height: webidl::UnrestrictedDouble, } pub struct DOMRectInner { @@ -169,16 +170,16 @@ impl DOMRectInner { #[constructor] #[cppgc] pub fn constructor( - #[webidl] x: f64, - #[webidl] y: f64, - #[webidl] width: f64, - #[webidl] height: f64, + #[webidl] x: webidl::UnrestrictedDouble, + #[webidl] y: webidl::UnrestrictedDouble, + #[webidl] width: webidl::UnrestrictedDouble, + #[webidl] height: webidl::UnrestrictedDouble, ) -> DOMRectInner { DOMRectInner { - x: Cell::new(x), - y: Cell::new(y), - width: Cell::new(width), - height: Cell::new(height), + x: Cell::new(*x), + y: Cell::new(*y), + width: Cell::new(*width), + height: Cell::new(*height), } } @@ -186,10 +187,10 @@ impl DOMRectInner { #[cppgc] pub fn from_rect(#[webidl] init: DOMRectInit) -> DOMRectInner { DOMRectInner { - x: Cell::new(init.x), - y: Cell::new(init.y), - width: Cell::new(init.width), - height: Cell::new(init.height), + x: Cell::new(*init.x), + y: Cell::new(*init.y), + width: Cell::new(*init.width), + height: Cell::new(*init.height), } } @@ -200,8 +201,8 @@ impl DOMRectInner { } #[setter] - pub fn x(&self, #[webidl] value: f64) { - self.x.set(value) + pub fn x(&self, #[webidl] value: webidl::UnrestrictedDouble) { + self.x.set(*value) } #[fast] @@ -211,8 +212,8 @@ impl DOMRectInner { } #[setter] - pub fn y(&self, #[webidl] value: f64) { - self.y.set(value) + pub fn y(&self, #[webidl] value: webidl::UnrestrictedDouble) { + self.y.set(*value) } #[fast] @@ -222,8 +223,8 @@ impl DOMRectInner { } #[setter] - pub fn width(&self, #[webidl] value: f64) { - self.width.set(value) + pub fn width(&self, #[webidl] value: webidl::UnrestrictedDouble) { + self.width.set(*value) } #[fast] @@ -233,8 +234,8 @@ impl DOMRectInner { } #[setter] - pub fn height(&self, #[webidl] value: f64) { - self.height.set(value) + pub fn height(&self, #[webidl] value: webidl::UnrestrictedDouble) { + self.height.set(*value) } #[fast] @@ -242,7 +243,7 @@ impl DOMRectInner { pub fn top(&self) -> f64 { let y = self.y.get(); let height = self.height.get(); - y.min(y + height) + minimum(y, y + height) } #[fast] @@ -250,7 +251,7 @@ impl DOMRectInner { pub fn right(&self) -> f64 { let x = self.x.get(); let width = self.width.get(); - x.max(x + width) + maximum(x, x + width) } #[fast] @@ -258,7 +259,7 @@ impl DOMRectInner { pub fn bottom(&self) -> f64 { let y = self.y.get(); let height = self.height.get(); - y.max(y + height) + maximum(y, y + height) } #[fast] @@ -266,7 +267,7 @@ impl DOMRectInner { pub fn left(&self) -> f64 { let x = self.x.get(); let width = self.width.get(); - x.min(x + width) + minimum(x, x + width) } } @@ -301,7 +302,9 @@ impl DOMQuadInner { #[inline] fn from_point(point: DOMPointInit) -> DOMPointInner { DOMPointInner { - inner: RefCell::new(Vector4::new(point.x, point.y, point.z, point.w)), + inner: RefCell::new(Vector4::new( + *point.x, *point.y, *point.z, *point.w, + )), } } @@ -324,16 +327,16 @@ impl DOMQuadInner { } = rect; DOMQuadInner { p1: UnsafeCell::new(DOMPointInner { - inner: RefCell::new(Vector4::new(x, y, 0.0, 1.0)), + inner: RefCell::new(Vector4::new(*x, *y, 0.0, 1.0)), }), p2: UnsafeCell::new(DOMPointInner { - inner: RefCell::new(Vector4::new(x + width, y, 0.0, 1.0)), + inner: RefCell::new(Vector4::new(*x + *width, *y, 0.0, 1.0)), }), p3: UnsafeCell::new(DOMPointInner { - inner: RefCell::new(Vector4::new(x + width, y + height, 0.0, 1.0)), + inner: RefCell::new(Vector4::new(*x + *width, *y + *height, 0.0, 1.0)), }), p4: UnsafeCell::new(DOMPointInner { - inner: RefCell::new(Vector4::new(x, y + height, 0.0, 1.0)), + inner: RefCell::new(Vector4::new(*x, *y + *height, 0.0, 1.0)), }), } } @@ -344,7 +347,9 @@ impl DOMQuadInner { #[inline] fn from_point(point: DOMPointInit) -> DOMPointInner { DOMPointInner { - inner: RefCell::new(Vector4::new(point.x, point.y, point.z, point.w)), + inner: RefCell::new(Vector4::new( + *point.x, *point.y, *point.z, *point.w, + )), } } @@ -398,10 +403,10 @@ impl DOMQuadInner { let p2 = p2.inner.borrow(); let p3 = p3.inner.borrow(); let p4 = p4.inner.borrow(); - let left = p1.x.min(p2.x).min(p3.x).min(p4.x); - let top = p1.y.min(p2.y).min(p3.y).min(p4.y); - let right = p1.x.max(p2.x).max(p3.x).max(p4.x); - let bottom = p1.y.max(p2.y).max(p3.y).max(p4.y); + let left = minimum(minimum(p1.x, p2.x), minimum(p3.x, p4.x)); + let top = minimum(minimum(p1.y, p2.y), minimum(p3.y, p4.y)); + let right = maximum(maximum(p1.x, p2.x), maximum(p3.x, p4.x)); + let bottom = maximum(maximum(p1.y, p2.y), maximum(p3.y, p4.y)); DOMRectInner { x: Cell::new(left), y: Cell::new(top), @@ -415,49 +420,49 @@ impl DOMQuadInner { #[webidl(dictionary)] pub struct DOMMatrixInit { #[webidl(default = None)] - a: Option, + a: Option, #[webidl(default = None)] - b: Option, + b: Option, #[webidl(default = None)] - c: Option, + c: Option, #[webidl(default = None)] - d: Option, + d: Option, #[webidl(default = None)] - e: Option, + e: Option, #[webidl(default = None)] - f: Option, + f: Option, #[webidl(default = None)] - m11: Option, + m11: Option, #[webidl(default = None)] - m12: Option, - #[webidl(default = 0.0)] - m13: f64, - #[webidl(default = 0.0)] - m14: f64, + m12: Option, + #[webidl(default = webidl::UnrestrictedDouble(0.0))] + m13: webidl::UnrestrictedDouble, + #[webidl(default = webidl::UnrestrictedDouble(0.0))] + m14: webidl::UnrestrictedDouble, #[webidl(default = None)] - m21: Option, + m21: Option, #[webidl(default = None)] - m22: Option, - #[webidl(default = 0.0)] - m23: f64, - #[webidl(default = 0.0)] - m24: f64, - #[webidl(default = 0.0)] - m31: f64, - #[webidl(default = 0.0)] - m32: f64, - #[webidl(default = 1.0)] - m33: f64, - #[webidl(default = 0.0)] - m34: f64, + m22: Option, + #[webidl(default = webidl::UnrestrictedDouble(0.0))] + m23: webidl::UnrestrictedDouble, + #[webidl(default = webidl::UnrestrictedDouble(0.0))] + m24: webidl::UnrestrictedDouble, + #[webidl(default = webidl::UnrestrictedDouble(0.0))] + m31: webidl::UnrestrictedDouble, + #[webidl(default = webidl::UnrestrictedDouble(0.0))] + m32: webidl::UnrestrictedDouble, + #[webidl(default = webidl::UnrestrictedDouble(1.0))] + m33: webidl::UnrestrictedDouble, + #[webidl(default = webidl::UnrestrictedDouble(0.0))] + m34: webidl::UnrestrictedDouble, #[webidl(default = None)] - m41: Option, + m41: Option, #[webidl(default = None)] - m42: Option, - #[webidl(default = 0.0)] - m43: f64, - #[webidl(default = 1.0)] - m44: f64, + m42: Option, + #[webidl(default = webidl::UnrestrictedDouble(0.0))] + m43: webidl::UnrestrictedDouble, + #[webidl(default = webidl::UnrestrictedDouble(1.0))] + m44: webidl::UnrestrictedDouble, #[webidl(default = None)] is_2d: Option, } @@ -532,7 +537,7 @@ impl DOMMatrixInner { ($value3d:expr, $value2d:expr, $default:expr) => {{ if let Some(value3d) = $value3d { if let Some(value2d) = $value2d { - if !(value3d == value2d || value3d.is_nan() && value2d.is_nan()) { + if !(*value3d == *value2d || value3d.is_nan() && value2d.is_nan()) { return Err(GeometryError::Inconsistent2DMatrix); } } @@ -540,7 +545,7 @@ impl DOMMatrixInner { } else if let Some(value2d) = $value2d { value2d } else { - $default + webidl::UnrestrictedDouble($default) } }}; } @@ -552,16 +557,16 @@ impl DOMMatrixInner { let m41 = fixup!(init.m41, init.e, 0.0); let m42 = fixup!(init.m42, init.f, 0.0); let is_2d = { - let is_2d_can_be_true = init.m13 == 0.0 - && init.m14 == 0.0 - && init.m23 == 0.0 - && init.m24 == 0.0 - && init.m31 == 0.0 - && init.m32 == 0.0 - && init.m33 == 1.0 - && init.m34 == 0.0 - && init.m43 == 0.0 - && init.m44 == 1.0; + let is_2d_can_be_true = *init.m13 == 0.0 + && *init.m14 == 0.0 + && *init.m23 == 0.0 + && *init.m24 == 0.0 + && *init.m31 == 0.0 + && *init.m32 == 0.0 + && *init.m33 == 1.0 + && *init.m34 == 0.0 + && *init.m43 == 0.0 + && *init.m44 == 1.0; if let Some(is_2d) = init.is_2d { if is_2d && !is_2d_can_be_true { return Err(GeometryError::Inconsistent2DMatrix); @@ -577,10 +582,10 @@ impl DOMMatrixInner { Ok(DOMMatrixInner { #[rustfmt::skip] inner: RefCell::new(Matrix4::new( - m11, m21, 0.0, m41, - m12, m22, 0.0, m42, - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0, + *m11, *m21, 0.0, *m41, + *m12, *m22, 0.0, *m42, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0, )), is_2d: Cell::new(true), }) @@ -601,10 +606,10 @@ impl DOMMatrixInner { Ok(DOMMatrixInner { #[rustfmt::skip] inner: RefCell::new(Matrix4::new( - m11, m21, m31, m41, - m12, m22, m32, m42, - m13, m23, m33, m43, - m14, m24, m34, m44, + *m11, *m21, *m31, *m41, + *m12, *m22, *m32, *m42, + *m13, *m23, *m33, *m43, + *m14, *m24, *m34, *m44, )), is_2d: Cell::new(false), }) @@ -633,10 +638,10 @@ impl DOMMatrixInner { } #[setter] - pub fn a(&self, #[webidl] value: f64) { + pub fn a(&self, #[webidl] value: webidl::UnrestrictedDouble) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_A) = value; + *self.inner.borrow_mut().get_unchecked_mut(INDEX_A) = *value; } } @@ -648,10 +653,10 @@ impl DOMMatrixInner { } #[setter] - pub fn b(&self, #[webidl] value: f64) { + pub fn b(&self, #[webidl] value: webidl::UnrestrictedDouble) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_B) = value; + *self.inner.borrow_mut().get_unchecked_mut(INDEX_B) = *value; } } @@ -663,10 +668,10 @@ impl DOMMatrixInner { } #[setter] - pub fn c(&self, #[webidl] value: f64) { + pub fn c(&self, #[webidl] value: webidl::UnrestrictedDouble) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_C) = value; + *self.inner.borrow_mut().get_unchecked_mut(INDEX_C) = *value; } } @@ -678,10 +683,10 @@ impl DOMMatrixInner { } #[setter] - pub fn d(&self, #[webidl] value: f64) { + pub fn d(&self, #[webidl] value: webidl::UnrestrictedDouble) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_D) = value; + *self.inner.borrow_mut().get_unchecked_mut(INDEX_D) = *value; } } @@ -693,10 +698,10 @@ impl DOMMatrixInner { } #[setter] - pub fn e(&self, #[webidl] value: f64) { + pub fn e(&self, #[webidl] value: webidl::UnrestrictedDouble) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_E) = value; + *self.inner.borrow_mut().get_unchecked_mut(INDEX_E) = *value; } } @@ -708,10 +713,10 @@ impl DOMMatrixInner { } #[setter] - pub fn f(&self, #[webidl] value: f64) { + pub fn f(&self, #[webidl] value: webidl::UnrestrictedDouble) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_F) = value; + *self.inner.borrow_mut().get_unchecked_mut(INDEX_F) = *value; } } @@ -723,10 +728,10 @@ impl DOMMatrixInner { } #[setter] - pub fn m11(&self, #[webidl] value: f64) { + pub fn m11(&self, #[webidl] value: webidl::UnrestrictedDouble) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M11) = value; + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M11) = *value; } } @@ -738,10 +743,10 @@ impl DOMMatrixInner { } #[setter] - pub fn m12(&self, #[webidl] value: f64) { + pub fn m12(&self, #[webidl] value: webidl::UnrestrictedDouble) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M12) = value; + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M12) = *value; } } @@ -753,12 +758,12 @@ impl DOMMatrixInner { } #[setter] - pub fn m13(&self, #[webidl] value: f64) { + pub fn m13(&self, #[webidl] value: webidl::UnrestrictedDouble) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M13) = value; + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M13) = *value; } - if value != 0.0 { + if *value != 0.0 { self.is_2d.set(false); } } @@ -771,12 +776,12 @@ impl DOMMatrixInner { } #[setter] - pub fn m14(&self, #[webidl] value: f64) { + pub fn m14(&self, #[webidl] value: webidl::UnrestrictedDouble) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M14) = value; + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M14) = *value; } - if value != 0.0 { + if *value != 0.0 { self.is_2d.set(false); } } @@ -789,10 +794,10 @@ impl DOMMatrixInner { } #[setter] - pub fn m21(&self, #[webidl] value: f64) { + pub fn m21(&self, #[webidl] value: webidl::UnrestrictedDouble) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M21) = value; + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M21) = *value; } } @@ -804,10 +809,10 @@ impl DOMMatrixInner { } #[setter] - pub fn m22(&self, #[webidl] value: f64) { + pub fn m22(&self, #[webidl] value: webidl::UnrestrictedDouble) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M22) = value; + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M22) = *value; } } @@ -819,12 +824,12 @@ impl DOMMatrixInner { } #[setter] - pub fn m23(&self, #[webidl] value: f64) { + pub fn m23(&self, #[webidl] value: webidl::UnrestrictedDouble) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M23) = value; + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M23) = *value; } - if value != 0.0 { + if *value != 0.0 { self.is_2d.set(false); } } @@ -837,12 +842,12 @@ impl DOMMatrixInner { } #[setter] - pub fn m24(&self, #[webidl] value: f64) { + pub fn m24(&self, #[webidl] value: webidl::UnrestrictedDouble) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M24) = value; + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M24) = *value; } - if value != 0.0 { + if *value != 0.0 { self.is_2d.set(false); } } @@ -855,12 +860,12 @@ impl DOMMatrixInner { } #[setter] - pub fn m31(&self, #[webidl] value: f64) { + pub fn m31(&self, #[webidl] value: webidl::UnrestrictedDouble) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M31) = value; + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M31) = *value; } - if value != 0.0 { + if *value != 0.0 { self.is_2d.set(false); } } @@ -873,12 +878,12 @@ impl DOMMatrixInner { } #[setter] - pub fn m32(&self, #[webidl] value: f64) { + pub fn m32(&self, #[webidl] value: webidl::UnrestrictedDouble) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M32) = value; + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M32) = *value; } - if value != 0.0 { + if *value != 0.0 { self.is_2d.set(false); } } @@ -891,12 +896,12 @@ impl DOMMatrixInner { } #[setter] - pub fn m33(&self, #[webidl] value: f64) { + pub fn m33(&self, #[webidl] value: webidl::UnrestrictedDouble) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M33) = value; + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M33) = *value; } - if value != 1.0 { + if *value != 1.0 { self.is_2d.set(false); } } @@ -909,12 +914,12 @@ impl DOMMatrixInner { } #[setter] - pub fn m34(&self, #[webidl] value: f64) { + pub fn m34(&self, #[webidl] value: webidl::UnrestrictedDouble) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M34) = value; + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M34) = *value; } - if value != 0.0 { + if *value != 0.0 { self.is_2d.set(false); } } @@ -927,10 +932,10 @@ impl DOMMatrixInner { } #[setter] - pub fn m41(&self, #[webidl] value: f64) { + pub fn m41(&self, #[webidl] value: webidl::UnrestrictedDouble) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M41) = value; + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M41) = *value; } } @@ -942,10 +947,10 @@ impl DOMMatrixInner { } #[setter] - pub fn m42(&self, #[webidl] value: f64) { + pub fn m42(&self, #[webidl] value: webidl::UnrestrictedDouble) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M42) = value; + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M42) = *value; } } @@ -957,12 +962,12 @@ impl DOMMatrixInner { } #[setter] - pub fn m43(&self, #[webidl] value: f64) { + pub fn m43(&self, #[webidl] value: webidl::UnrestrictedDouble) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M43) = value; + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M43) = *value; } - if value != 0.0 { + if *value != 0.0 { self.is_2d.set(false); } } @@ -975,12 +980,12 @@ impl DOMMatrixInner { } #[setter] - pub fn m44(&self, #[webidl] value: f64) { + pub fn m44(&self, #[webidl] value: webidl::UnrestrictedDouble) { // SAFETY: in-range access unsafe { - *self.inner.borrow_mut().get_unchecked_mut(INDEX_M44) = value; + *self.inner.borrow_mut().get_unchecked_mut(INDEX_M44) = *value; } - if value != 1.0 { + if *value != 1.0 { self.is_2d.set(false); } } @@ -1041,151 +1046,165 @@ impl DOMMatrixInner { #[cppgc] pub fn translate( &self, - #[webidl] tx: f64, - #[webidl] ty: f64, - #[webidl] tz: f64, + #[webidl] tx: webidl::UnrestrictedDouble, + #[webidl] ty: webidl::UnrestrictedDouble, + #[webidl] tz: webidl::UnrestrictedDouble, ) -> DOMMatrixInner { let out = self.clone(); - matrix_translate(&out, tx, ty, tz); + matrix_translate(&out, *tx, *ty, *tz); out } pub fn translate_self( &self, - #[webidl] tx: f64, - #[webidl] ty: f64, - #[webidl] tz: f64, + #[webidl] tx: webidl::UnrestrictedDouble, + #[webidl] ty: webidl::UnrestrictedDouble, + #[webidl] tz: webidl::UnrestrictedDouble, ) { - matrix_translate(self, tx, ty, tz); + matrix_translate(self, *tx, *ty, *tz); } #[cppgc] pub fn scale_without_origin( &self, - #[webidl] sx: f64, - #[webidl] sy: f64, - #[webidl] sz: f64, + #[webidl] sx: webidl::UnrestrictedDouble, + #[webidl] sy: webidl::UnrestrictedDouble, + #[webidl] sz: webidl::UnrestrictedDouble, ) -> DOMMatrixInner { let out = self.clone(); - matrix_scale_without_origin(&out, sx, sy, sz); + matrix_scale_without_origin(&out, *sx, *sy, *sz); out } pub fn scale_without_origin_self( &self, - #[webidl] sx: f64, - #[webidl] sy: f64, - #[webidl] sz: f64, + #[webidl] sx: webidl::UnrestrictedDouble, + #[webidl] sy: webidl::UnrestrictedDouble, + #[webidl] sz: webidl::UnrestrictedDouble, ) { - matrix_scale_without_origin(self, sx, sy, sz); + matrix_scale_without_origin(self, *sx, *sy, *sz); } #[cppgc] pub fn scale_with_origin( &self, - #[webidl] sx: f64, - #[webidl] sy: f64, - #[webidl] sz: f64, - #[webidl] origin_x: f64, - #[webidl] origin_y: f64, - #[webidl] origin_z: f64, + #[webidl] sx: webidl::UnrestrictedDouble, + #[webidl] sy: webidl::UnrestrictedDouble, + #[webidl] sz: webidl::UnrestrictedDouble, + #[webidl] origin_x: webidl::UnrestrictedDouble, + #[webidl] origin_y: webidl::UnrestrictedDouble, + #[webidl] origin_z: webidl::UnrestrictedDouble, ) -> DOMMatrixInner { let out = self.clone(); - matrix_scale_with_origin(&out, sx, sy, sz, origin_x, origin_y, origin_z); + matrix_scale_with_origin( + &out, *sx, *sy, *sz, *origin_x, *origin_y, *origin_z, + ); out } pub fn scale_with_origin_self( &self, - #[webidl] sx: f64, - #[webidl] sy: f64, - #[webidl] sz: f64, - #[webidl] origin_x: f64, - #[webidl] origin_y: f64, - #[webidl] origin_z: f64, + #[webidl] sx: webidl::UnrestrictedDouble, + #[webidl] sy: webidl::UnrestrictedDouble, + #[webidl] sz: webidl::UnrestrictedDouble, + #[webidl] origin_x: webidl::UnrestrictedDouble, + #[webidl] origin_y: webidl::UnrestrictedDouble, + #[webidl] origin_z: webidl::UnrestrictedDouble, ) { - matrix_scale_with_origin(self, sx, sy, sz, origin_x, origin_y, origin_z); + matrix_scale_with_origin( + self, *sx, *sy, *sz, *origin_x, *origin_y, *origin_z, + ); } #[cppgc] pub fn rotate( &self, - #[webidl] roll_deg: f64, - #[webidl] pitch_deg: f64, - #[webidl] yaw_deg: f64, + #[webidl] roll_deg: webidl::UnrestrictedDouble, + #[webidl] pitch_deg: webidl::UnrestrictedDouble, + #[webidl] yaw_deg: webidl::UnrestrictedDouble, ) -> DOMMatrixInner { let out = self.clone(); - matrix_rotate(&out, roll_deg, pitch_deg, yaw_deg); + matrix_rotate(&out, *roll_deg, *pitch_deg, *yaw_deg); out } pub fn rotate_self( &self, - #[webidl] roll_deg: f64, - #[webidl] pitch_deg: f64, - #[webidl] yaw_deg: f64, + #[webidl] roll_deg: webidl::UnrestrictedDouble, + #[webidl] pitch_deg: webidl::UnrestrictedDouble, + #[webidl] yaw_deg: webidl::UnrestrictedDouble, ) { - matrix_rotate(self, roll_deg, pitch_deg, yaw_deg); + matrix_rotate(self, *roll_deg, *pitch_deg, *yaw_deg); } #[cppgc] pub fn rotate_from_vector( &self, - #[webidl] x: f64, - #[webidl] y: f64, + #[webidl] x: webidl::UnrestrictedDouble, + #[webidl] y: webidl::UnrestrictedDouble, ) -> DOMMatrixInner { let out = self.clone(); - matrix_rotate_from_vector(&out, x, y); + matrix_rotate_from_vector(&out, *x, *y); out } - pub fn rotate_from_vector_self(&self, #[webidl] x: f64, #[webidl] y: f64) { - matrix_rotate_from_vector(self, x, y); + pub fn rotate_from_vector_self( + &self, + #[webidl] x: webidl::UnrestrictedDouble, + #[webidl] y: webidl::UnrestrictedDouble, + ) { + matrix_rotate_from_vector(self, *x, *y); } #[cppgc] pub fn rotate_axis_angle( &self, - #[webidl] x: f64, - #[webidl] y: f64, - #[webidl] z: f64, - #[webidl] angle_deg: f64, + #[webidl] x: webidl::UnrestrictedDouble, + #[webidl] y: webidl::UnrestrictedDouble, + #[webidl] z: webidl::UnrestrictedDouble, + #[webidl] angle_deg: webidl::UnrestrictedDouble, ) -> DOMMatrixInner { let out = self.clone(); - matrix_rotate_axis_angle(&out, x, y, z, angle_deg); + matrix_rotate_axis_angle(&out, *x, *y, *z, *angle_deg); out } pub fn rotate_axis_angle_self( &self, - #[webidl] x: f64, - #[webidl] y: f64, - #[webidl] z: f64, - #[webidl] angle_deg: f64, + #[webidl] x: webidl::UnrestrictedDouble, + #[webidl] y: webidl::UnrestrictedDouble, + #[webidl] z: webidl::UnrestrictedDouble, + #[webidl] angle_deg: webidl::UnrestrictedDouble, ) { - matrix_rotate_axis_angle(self, x, y, z, angle_deg); + matrix_rotate_axis_angle(self, *x, *y, *z, *angle_deg); } #[cppgc] - pub fn skew_x(&self, #[webidl] x_deg: f64) -> DOMMatrixInner { + pub fn skew_x( + &self, + #[webidl] x_deg: webidl::UnrestrictedDouble, + ) -> DOMMatrixInner { let out = self.clone(); - matrix_skew_x(&out, x_deg); + matrix_skew_x(&out, *x_deg); out } - pub fn skew_x_self(&self, #[webidl] x_deg: f64) { - matrix_skew_x(self, x_deg); + pub fn skew_x_self(&self, #[webidl] x_deg: webidl::UnrestrictedDouble) { + matrix_skew_x(self, *x_deg); } #[cppgc] - pub fn skew_y(&self, #[webidl] y_deg: f64) -> DOMMatrixInner { + pub fn skew_y( + &self, + #[webidl] y_deg: webidl::UnrestrictedDouble, + ) -> DOMMatrixInner { let out = self.clone(); - matrix_skew_y(&out, y_deg); + matrix_skew_y(&out, *y_deg); out } - pub fn skew_y_self(&self, #[webidl] y_deg: f64) { - matrix_skew_y(self, y_deg); + pub fn skew_y_self(&self, #[webidl] y_deg: webidl::UnrestrictedDouble) { + matrix_skew_y(self, *y_deg); } #[cppgc] @@ -1264,6 +1283,44 @@ impl DOMMatrixInner { } } +// TODO(petamoriken) Use f64::maximum instead https://github.com/rust-lang/rust/issues/91079 +#[inline] +fn maximum(a: f64, b: f64) -> f64 { + if a > b { + a + } else if b > a { + b + } else if a == b { + if a.is_sign_positive() && b.is_sign_negative() { + a + } else { + b + } + } else { + // At least one input is NaN. Use `+` to perform NaN propagation and quieting. + a + b + } +} + +// TODO(petamoriken) Use f64::minimum instead https://github.com/rust-lang/rust/issues/91079 +#[inline] +fn minimum(a: f64, b: f64) -> f64 { + if a < b { + a + } else if b < a { + b + } else if a == b { + if a.is_sign_negative() && b.is_sign_positive() { + a + } else { + b + } + } else { + // At least one input is NaN. Use `+` to perform NaN propagation and quieting. + a + b + } +} + #[inline] fn matrix_translate(matrix: &DOMMatrixInner, tx: f64, ty: f64, tz: f64) { let mut inner = matrix.inner.borrow_mut(); From 416959239867360c45f2a417c960c52f8fb81640 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Mon, 13 Jan 2025 13:03:34 +0900 Subject: [PATCH 15/24] fix --- ext/geometry/lib.rs | 44 ++++++++++++++++++-------------------------- 1 file changed, 18 insertions(+), 26 deletions(-) diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 0af1871a6af4fd..72a396dada7468 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -9,7 +9,6 @@ use std::ptr; use std::slice; use deno_core::op2; -use deno_core::v8; use deno_core::webidl; use deno_core::GarbageCollected; use deno_core::WebIDL; @@ -54,6 +53,7 @@ pub struct DOMPointInit { w: webidl::UnrestrictedDouble, } +#[derive(Debug)] pub struct DOMPointInner { inner: RefCell>, } @@ -130,15 +130,12 @@ impl DOMPointInner { #[cppgc] pub fn matrix_transform( &self, - matrix: v8::Local, + #[cppgc] matrix: &DOMMatrixInner, ) -> DOMPointInner { - // SAFETY: cast v8::Local - let matrix: v8::Local<'_, DOMMatrixInner> = - unsafe { mem::transmute(matrix) }; let out = DOMPointInner { inner: RefCell::new(Vector4::zeros()), }; - matrix_transform_point(&matrix, self, &out); + matrix_transform_point(matrix, self, &out); out } } @@ -156,6 +153,7 @@ pub struct DOMRectInit { height: webidl::UnrestrictedDouble, } +#[derive(Debug)] pub struct DOMRectInner { x: Cell, y: Cell, @@ -280,6 +278,7 @@ pub struct DOMQuadInit { p4: DOMPointInit, } +#[derive(Debug)] pub struct DOMQuadInner { p1: UnsafeCell, p2: UnsafeCell, @@ -467,7 +466,7 @@ pub struct DOMMatrixInit { is_2d: Option, } -#[derive(Clone)] +#[derive(Debug, Clone)] pub struct DOMMatrixInner { inner: RefCell>, is_2d: Cell, @@ -1208,39 +1207,33 @@ impl DOMMatrixInner { } #[cppgc] - pub fn multiply(&self, other: v8::Local) -> DOMMatrixInner { - // SAFETY: cast v8::Local - let other: v8::Local<'_, DOMMatrixInner> = unsafe { mem::transmute(other) }; + pub fn multiply(&self, #[cppgc] other: &DOMMatrixInner) -> DOMMatrixInner { let out = DOMMatrixInner { inner: RefCell::new(Matrix4::zeros()), is_2d: Cell::new(true), }; - matrix_multiply(&out, self, &other); + matrix_multiply(&out, self, other); out } #[fast] - pub fn multiply_self(&self, other: v8::Local) { - // SAFETY: cast v8::Local - let other: v8::Local<'_, DOMMatrixInner> = unsafe { mem::transmute(other) }; + pub fn multiply_self(&self, #[cppgc] other: &DOMMatrixInner) { let result = DOMMatrixInner { inner: RefCell::new(Matrix4::zeros()), is_2d: Cell::new(true), }; - matrix_multiply(&result, self, &other); + matrix_multiply(&result, self, other); self.inner.borrow_mut().copy_from(&result.inner.borrow()); self.is_2d.set(result.is_2d.get()); } #[fast] - pub fn pre_multiply_self(&self, other: v8::Local) { - // SAFETY: cast v8::Local - let other: v8::Local<'_, DOMMatrixInner> = unsafe { mem::transmute(other) }; + pub fn pre_multiply_self(&self, #[cppgc] other: &DOMMatrixInner) { let result = DOMMatrixInner { inner: RefCell::new(Matrix4::zeros()), is_2d: Cell::new(true), }; - matrix_multiply(&result, &other, self); + matrix_multiply(&result, other, self); self.inner.borrow_mut().copy_from(&result.inner.borrow()); self.is_2d.set(result.is_2d.get()); } @@ -1272,13 +1265,14 @@ impl DOMMatrixInner { } #[cppgc] - pub fn transform_point(&self, point: v8::Local) -> DOMPointInner { - // SAFETY: cast v8::Local - let point: v8::Local<'_, DOMPointInner> = unsafe { mem::transmute(point) }; + pub fn transform_point( + &self, + #[cppgc] point: &DOMPointInner, + ) -> DOMPointInner { let out = DOMPointInner { inner: RefCell::new(Vector4::zeros()), }; - matrix_transform_point(self, &point, &out); + matrix_transform_point(self, point, &out); out } } @@ -1461,9 +1455,7 @@ fn matrix_multiply( let rhs_inner = rhs.inner.borrow(); let rhs_is_2d = rhs.is_2d.get(); let mut out_inner = out.inner.borrow_mut(); - let mut result = Matrix4::zeros(); - lhs_inner.mul_to(&rhs_inner, &mut result); - out_inner.copy_from(&result); + lhs_inner.mul_to(&rhs_inner, &mut out_inner); out.is_2d.set(lhs_is_2d && rhs_is_2d); } From c16c83252b18d2b72efe3eef2dbb0e983504f80c Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Mon, 13 Jan 2025 23:33:10 +0900 Subject: [PATCH 16/24] fix --- ext/geometry/01_geometry.js | 4 ++-- ext/geometry/lib.rs | 12 +++++++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/ext/geometry/01_geometry.js b/ext/geometry/01_geometry.js index db7beec3faea40..81ed2c5f18c0db 100644 --- a/ext/geometry/01_geometry.js +++ b/ext/geometry/01_geometry.js @@ -159,7 +159,7 @@ class DOMPoint extends DOMPointReadOnly { set w(value) { webidl.assertBranded(this, DOMPointPrototype); assertWritable(this); - this[_inner].x = value; + this[_inner].w = value; } [SymbolFor("Deno.privateCustomInspect")](inspect, inspectOptions) { @@ -442,7 +442,7 @@ class DOMQuad { webidl.assertBranded(this, DOMQuadPrototype); const bounds = webidl.createBranded(DOMRect); bounds[_writable] = true; - bounds[_inner] = this[_inner].fromBounds(); + bounds[_inner] = this[_inner].getBounds(); return bounds; } diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 72a396dada7468..9bddb827615c4b 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -75,6 +75,7 @@ impl DOMPointInner { } } + #[reentrant] #[static_method] #[cppgc] pub fn from_point(#[webidl] init: DOMPointInit) -> DOMPointInner { @@ -181,6 +182,7 @@ impl DOMRectInner { } } + #[reentrant] #[static_method] #[cppgc] pub fn from_rect(#[webidl] init: DOMRectInit) -> DOMRectInner { @@ -291,6 +293,7 @@ impl GarbageCollected for DOMQuadInner {} #[op2] impl DOMQuadInner { #[constructor] + #[reentrant] #[cppgc] pub fn constructor( #[webidl] p1: DOMPointInit, @@ -315,6 +318,7 @@ impl DOMQuadInner { } } + #[reentrant] #[static_method] #[cppgc] pub fn from_rect(#[webidl] rect: DOMRectInit) -> DOMQuadInner { @@ -340,6 +344,7 @@ impl DOMQuadInner { } } + #[reentrant] #[static_method] #[cppgc] pub fn from_quad(#[webidl] quad: DOMQuadInit) -> DOMQuadInner { @@ -527,6 +532,7 @@ impl DOMMatrixInner { } } + #[reentrant] #[static_method] #[cppgc] pub fn from_matrix( @@ -1335,7 +1341,7 @@ fn matrix_scale_without_origin( let is_2d = matrix.is_2d.get(); let scaling = Vector3::new(sx, sy, sz); inner.prepend_nonuniform_scaling_mut(&scaling); - matrix.is_2d.set(is_2d && sz == 0.0); + matrix.is_2d.set(is_2d && sz == 1.0); } #[inline] @@ -1356,7 +1362,7 @@ fn matrix_scale_with_origin( inner.prepend_nonuniform_scaling_mut(&scaling); shift.neg_mut(); inner.prepend_translation_mut(&shift); - matrix.is_2d.set(is_2d && sz == 0.0 && origin_z == 0.0); + matrix.is_2d.set(is_2d && sz == 1.0 && origin_z == 0.0); } #[inline] @@ -1381,7 +1387,7 @@ fn matrix_rotate( inner.set_column(2, &result.column(2)); matrix .is_2d - .set(is_2d && pitch_deg == 0.0 && yaw_deg == 0.0); + .set(is_2d && roll_deg == 0.0 && pitch_deg == 0.0); } #[inline] From 41cce868a4a663bedbc826121c80842e6d0183ae Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Tue, 14 Jan 2025 02:12:11 +0900 Subject: [PATCH 17/24] tweak --- ext/geometry/lib.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 9bddb827615c4b..2a3c12579102f1 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -40,7 +40,7 @@ pub enum GeometryError { Inconsistent2DMatrix, } -#[derive(WebIDL)] +#[derive(WebIDL, Debug)] #[webidl(dictionary)] pub struct DOMPointInit { #[webidl(default = webidl::UnrestrictedDouble(0.0))] @@ -141,7 +141,7 @@ impl DOMPointInner { } } -#[derive(WebIDL)] +#[derive(WebIDL, Debug)] #[webidl(dictionary)] pub struct DOMRectInit { #[webidl(default = webidl::UnrestrictedDouble(0.0))] @@ -271,7 +271,7 @@ impl DOMRectInner { } } -#[derive(WebIDL)] +#[derive(WebIDL, Debug)] #[webidl(dictionary)] pub struct DOMQuadInit { p1: DOMPointInit, @@ -420,7 +420,7 @@ impl DOMQuadInner { } } -#[derive(WebIDL)] +#[derive(WebIDL, Debug)] #[webidl(dictionary)] pub struct DOMMatrixInit { #[webidl(default = None)] From 4f1d78337ff3d7c5ec7b32e4f07db4956813fffd Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Tue, 14 Jan 2025 06:33:59 +0900 Subject: [PATCH 18/24] tweak --- runtime/errors.rs | 1969 --------------------------------------------- 1 file changed, 1969 deletions(-) delete mode 100644 runtime/errors.rs diff --git a/runtime/errors.rs b/runtime/errors.rs deleted file mode 100644 index f441e58671eaae..00000000000000 --- a/runtime/errors.rs +++ /dev/null @@ -1,1969 +0,0 @@ -// Copyright 2018-2025 the Deno authors. MIT license. - -//! There are many types of errors in Deno: -//! - AnyError: a generic wrapper that can encapsulate any type of error. -//! - JsError: a container for the error message and stack trace for exceptions -//! thrown in JavaScript code. We use this to pretty-print stack traces. -//! - Diagnostic: these are errors that originate in TypeScript's compiler. -//! They're similar to JsError, in that they have line numbers. But -//! Diagnostics are compile-time type errors, whereas JsErrors are runtime -//! exceptions. - -use std::env; -use std::error::Error; -use std::io; -use std::sync::Arc; - -use deno_broadcast_channel::BroadcastChannelError; -use deno_cache::CacheError; -use deno_canvas::CanvasError; -use deno_core::error::AnyError; -use deno_core::serde_json; -use deno_core::url; -use deno_core::ModuleResolutionError; -use deno_cron::CronError; -use deno_crypto::DecryptError; -use deno_crypto::EncryptError; -use deno_crypto::ExportKeyError; -use deno_crypto::GenerateKeyError; -use deno_crypto::ImportKeyError; -use deno_fetch::FetchError; -use deno_fetch::HttpClientCreateError; -use deno_ffi::CallError; -use deno_ffi::CallbackError; -use deno_ffi::DlfcnError; -use deno_ffi::IRError; -use deno_ffi::ReprError; -use deno_ffi::StaticError; -use deno_fs::FsOpsError; -use deno_fs::FsOpsErrorKind; -use deno_geometry::GeometryError; -use deno_http::HttpError; -use deno_http::HttpNextError; -use deno_http::WebSocketUpgradeError; -use deno_io::fs::FsError; -use deno_kv::KvCheckError; -use deno_kv::KvError; -use deno_kv::KvErrorKind; -use deno_kv::KvMutationError; -use deno_napi::NApiError; -use deno_net::ops::NetError; -use deno_permissions::ChildPermissionError; -use deno_permissions::NetDescriptorFromUrlParseError; -use deno_permissions::PathResolveError; -use deno_permissions::PermissionCheckError; -use deno_permissions::RunDescriptorParseError; -use deno_permissions::SysDescriptorParseError; -use deno_tls::TlsError; -use deno_web::BlobError; -use deno_web::CompressionError; -use deno_web::MessagePortError; -use deno_web::StreamResourceError; -use deno_web::WebError; -use deno_websocket::HandshakeError; -use deno_websocket::WebsocketError; -use deno_webstorage::WebStorageError; -use rustyline::error::ReadlineError; - -use crate::ops::fs_events::FsEventsError; -use crate::ops::http::HttpStartError; -use crate::ops::os::OsError; -use crate::ops::permissions::PermissionError; -use crate::ops::process::CheckRunPermissionError; -use crate::ops::process::ProcessError; -use crate::ops::signal::SignalError; -use crate::ops::tty::TtyError; -use crate::ops::web_worker::SyncFetchError; -use crate::ops::worker_host::CreateWorkerError; - -fn get_run_descriptor_parse_error(e: &RunDescriptorParseError) -> &'static str { - match e { - RunDescriptorParseError::Which(_) => "Error", - RunDescriptorParseError::PathResolve(e) => get_path_resolve_error(e), - RunDescriptorParseError::EmptyRunQuery => "Error", - } -} - -fn get_sys_descriptor_parse_error(e: &SysDescriptorParseError) -> &'static str { - match e { - SysDescriptorParseError::InvalidKind(_) => "TypeError", - SysDescriptorParseError::Empty => "Error", - } -} - -fn get_path_resolve_error(e: &PathResolveError) -> &'static str { - match e { - PathResolveError::CwdResolve(e) => get_io_error_class(e), - PathResolveError::EmptyPath => "Error", - } -} - -fn get_permission_error_class(e: &PermissionError) -> &'static str { - match e { - PermissionError::InvalidPermissionName(_) => "ReferenceError", - PermissionError::PathResolve(e) => get_path_resolve_error(e), - PermissionError::NetDescriptorParse(_) => "URIError", - PermissionError::SysDescriptorParse(e) => get_sys_descriptor_parse_error(e), - PermissionError::RunDescriptorParse(e) => get_run_descriptor_parse_error(e), - } -} - -fn get_permission_check_error_class(e: &PermissionCheckError) -> &'static str { - match e { - PermissionCheckError::PermissionDenied(_) => "NotCapable", - PermissionCheckError::InvalidFilePath(_) => "URIError", - PermissionCheckError::NetDescriptorForUrlParse(e) => match e { - NetDescriptorFromUrlParseError::MissingHost(_) => "TypeError", - NetDescriptorFromUrlParseError::Host(_) => "URIError", - }, - PermissionCheckError::SysDescriptorParse(e) => { - get_sys_descriptor_parse_error(e) - } - PermissionCheckError::PathResolve(e) => get_path_resolve_error(e), - PermissionCheckError::HostParse(_) => "URIError", - } -} - -fn get_dlopen_error_class(error: &dlopen2::Error) -> &'static str { - use dlopen2::Error::*; - match error { - NullCharacter(_) => "InvalidData", - OpeningLibraryError(ref e) => get_io_error_class(e), - SymbolGettingError(ref e) => get_io_error_class(e), - AddrNotMatchingDll(ref e) => get_io_error_class(e), - NullSymbol => "NotFound", - } -} - -fn get_env_var_error_class(error: &env::VarError) -> &'static str { - use env::VarError::*; - match error { - NotPresent => "NotFound", - NotUnicode(..) => "InvalidData", - } -} - -fn get_io_error_class(error: &io::Error) -> &'static str { - use io::ErrorKind::*; - match error.kind() { - NotFound => "NotFound", - PermissionDenied => "PermissionDenied", - ConnectionRefused => "ConnectionRefused", - ConnectionReset => "ConnectionReset", - ConnectionAborted => "ConnectionAborted", - NotConnected => "NotConnected", - AddrInUse => "AddrInUse", - AddrNotAvailable => "AddrNotAvailable", - BrokenPipe => "BrokenPipe", - AlreadyExists => "AlreadyExists", - InvalidInput => "TypeError", - InvalidData => "InvalidData", - TimedOut => "TimedOut", - Interrupted => "Interrupted", - WriteZero => "WriteZero", - UnexpectedEof => "UnexpectedEof", - Other => "Error", - WouldBlock => "WouldBlock", - // Non-exhaustive enum - might add new variants - // in the future - kind => { - let kind_str = kind.to_string(); - match kind_str.as_str() { - "FilesystemLoop" => "FilesystemLoop", - "IsADirectory" => "IsADirectory", - "NetworkUnreachable" => "NetworkUnreachable", - "NotADirectory" => "NotADirectory", - _ => "Error", - } - } - } -} - -fn get_module_resolution_error_class( - _: &ModuleResolutionError, -) -> &'static str { - "URIError" -} - -fn get_notify_error_class(error: ¬ify::Error) -> &'static str { - use notify::ErrorKind::*; - match error.kind { - Generic(_) => "Error", - Io(ref e) => get_io_error_class(e), - PathNotFound => "NotFound", - WatchNotFound => "NotFound", - InvalidConfig(_) => "InvalidData", - MaxFilesWatch => "Error", - } -} - -fn get_regex_error_class(error: ®ex::Error) -> &'static str { - use regex::Error::*; - match error { - Syntax(_) => "SyntaxError", - CompiledTooBig(_) => "RangeError", - _ => "Error", - } -} - -fn get_serde_json_error_class( - error: &serde_json::error::Error, -) -> &'static str { - use deno_core::serde_json::error::*; - match error.classify() { - Category::Io => error - .source() - .and_then(|e| e.downcast_ref::()) - .map(get_io_error_class) - .unwrap(), - Category::Syntax => "SyntaxError", - Category::Data => "InvalidData", - Category::Eof => "UnexpectedEof", - } -} - -fn get_url_parse_error_class(_error: &url::ParseError) -> &'static str { - "URIError" -} - -fn get_hyper_error_class(_error: &hyper::Error) -> &'static str { - "Http" -} - -fn get_hyper_util_error_class( - _error: &hyper_util::client::legacy::Error, -) -> &'static str { - "Http" -} - -fn get_hyper_v014_error_class(_error: &hyper_v014::Error) -> &'static str { - "Http" -} - -#[cfg(unix)] -pub fn get_nix_error_class(error: &nix::Error) -> &'static str { - match error { - nix::Error::ECHILD => "NotFound", - nix::Error::EINVAL => "TypeError", - nix::Error::ENOENT => "NotFound", - nix::Error::ENOTTY => "BadResource", - nix::Error::EPERM => "PermissionDenied", - nix::Error::ESRCH => "NotFound", - nix::Error::ELOOP => "FilesystemLoop", - nix::Error::ENOTDIR => "NotADirectory", - nix::Error::ENETUNREACH => "NetworkUnreachable", - nix::Error::EISDIR => "IsADirectory", - nix::Error::UnknownErrno => "Error", - &nix::Error::ENOTSUP => unreachable!(), - _ => "Error", - } -} - -fn get_webgpu_error_class(e: &deno_webgpu::InitError) -> &'static str { - match e { - deno_webgpu::InitError::Resource(e) => { - get_error_class_name(e).unwrap_or("Error") - } - deno_webgpu::InitError::InvalidAdapter(_) => "Error", - deno_webgpu::InitError::RequestDevice(_) => "DOMExceptionOperationError", - deno_webgpu::InitError::InvalidDevice(_) => "Error", - } -} - -fn get_webgpu_buffer_error_class( - e: &deno_webgpu::buffer::BufferError, -) -> &'static str { - match e { - deno_webgpu::buffer::BufferError::Resource(e) => { - get_error_class_name(e).unwrap_or("Error") - } - deno_webgpu::buffer::BufferError::InvalidUsage => "TypeError", - deno_webgpu::buffer::BufferError::Access(_) => "DOMExceptionOperationError", - } -} - -fn get_webgpu_bundle_error_class( - e: &deno_webgpu::bundle::BundleError, -) -> &'static str { - match e { - deno_webgpu::bundle::BundleError::Resource(e) => { - get_error_class_name(e).unwrap_or("Error") - } - deno_webgpu::bundle::BundleError::InvalidSize => "TypeError", - } -} - -fn get_webgpu_byow_error_class( - e: &deno_webgpu::byow::ByowError, -) -> &'static str { - match e { - deno_webgpu::byow::ByowError::WebGPUNotInitiated => "TypeError", - deno_webgpu::byow::ByowError::InvalidParameters => "TypeError", - deno_webgpu::byow::ByowError::CreateSurface(_) => "Error", - deno_webgpu::byow::ByowError::InvalidSystem => "TypeError", - #[cfg(any( - target_os = "windows", - target_os = "linux", - target_os = "freebsd", - target_os = "openbsd" - ))] - deno_webgpu::byow::ByowError::NullWindow => "TypeError", - #[cfg(any( - target_os = "linux", - target_os = "freebsd", - target_os = "openbsd" - ))] - deno_webgpu::byow::ByowError::NullDisplay => "TypeError", - #[cfg(target_os = "macos")] - deno_webgpu::byow::ByowError::NSViewDisplay => "TypeError", - } -} - -fn get_webgpu_render_pass_error_class( - e: &deno_webgpu::render_pass::RenderPassError, -) -> &'static str { - match e { - deno_webgpu::render_pass::RenderPassError::Resource(e) => { - get_error_class_name(e).unwrap_or("Error") - } - deno_webgpu::render_pass::RenderPassError::InvalidSize => "TypeError", - } -} - -fn get_webgpu_surface_error_class( - e: &deno_webgpu::surface::SurfaceError, -) -> &'static str { - match e { - deno_webgpu::surface::SurfaceError::Resource(e) => { - get_error_class_name(e).unwrap_or("Error") - } - deno_webgpu::surface::SurfaceError::Surface(_) => "Error", - deno_webgpu::surface::SurfaceError::InvalidStatus => "Error", - } -} - -fn get_crypto_decrypt_error_class(e: &DecryptError) -> &'static str { - match e { - DecryptError::General(e) => get_crypto_shared_error_class(e), - DecryptError::Pkcs1(_) => "Error", - DecryptError::Failed => "DOMExceptionOperationError", - DecryptError::InvalidLength => "TypeError", - DecryptError::InvalidCounterLength => "TypeError", - DecryptError::InvalidTagLength => "TypeError", - DecryptError::InvalidKeyOrIv => "DOMExceptionOperationError", - DecryptError::TooMuchData => "DOMExceptionOperationError", - DecryptError::InvalidIvLength => "TypeError", - DecryptError::Rsa(_) => "DOMExceptionOperationError", - } -} - -fn get_crypto_encrypt_error_class(e: &EncryptError) -> &'static str { - match e { - EncryptError::General(e) => get_crypto_shared_error_class(e), - EncryptError::InvalidKeyOrIv => "DOMExceptionOperationError", - EncryptError::Failed => "DOMExceptionOperationError", - EncryptError::InvalidLength => "TypeError", - EncryptError::InvalidIvLength => "TypeError", - EncryptError::InvalidCounterLength => "TypeError", - EncryptError::TooMuchData => "DOMExceptionOperationError", - } -} - -fn get_crypto_shared_error_class(e: &deno_crypto::SharedError) -> &'static str { - match e { - deno_crypto::SharedError::ExpectedValidPrivateKey => "TypeError", - deno_crypto::SharedError::ExpectedValidPublicKey => "TypeError", - deno_crypto::SharedError::ExpectedValidPrivateECKey => "TypeError", - deno_crypto::SharedError::ExpectedValidPublicECKey => "TypeError", - deno_crypto::SharedError::ExpectedPrivateKey => "TypeError", - deno_crypto::SharedError::ExpectedPublicKey => "TypeError", - deno_crypto::SharedError::ExpectedSecretKey => "TypeError", - deno_crypto::SharedError::FailedDecodePrivateKey => { - "DOMExceptionOperationError" - } - deno_crypto::SharedError::FailedDecodePublicKey => { - "DOMExceptionOperationError" - } - deno_crypto::SharedError::UnsupportedFormat => { - "DOMExceptionNotSupportedError" - } - } -} - -fn get_crypto_ed25519_error_class( - e: &deno_crypto::Ed25519Error, -) -> &'static str { - match e { - deno_crypto::Ed25519Error::FailedExport => "DOMExceptionOperationError", - deno_crypto::Ed25519Error::Der(_) => "Error", - deno_crypto::Ed25519Error::KeyRejected(_) => "Error", - } -} - -fn get_crypto_export_key_error_class(e: &ExportKeyError) -> &'static str { - match e { - ExportKeyError::General(e) => get_crypto_shared_error_class(e), - ExportKeyError::Der(_) => "Error", - ExportKeyError::UnsupportedNamedCurve => "DOMExceptionNotSupportedError", - } -} - -fn get_crypto_generate_key_error_class(e: &GenerateKeyError) -> &'static str { - match e { - GenerateKeyError::General(e) => get_crypto_shared_error_class(e), - GenerateKeyError::BadPublicExponent => "DOMExceptionOperationError", - GenerateKeyError::InvalidHMACKeyLength => "DOMExceptionOperationError", - GenerateKeyError::FailedRSAKeySerialization => "DOMExceptionOperationError", - GenerateKeyError::InvalidAESKeyLength => "DOMExceptionOperationError", - GenerateKeyError::FailedRSAKeyGeneration => "DOMExceptionOperationError", - GenerateKeyError::FailedECKeyGeneration => "DOMExceptionOperationError", - GenerateKeyError::FailedKeyGeneration => "DOMExceptionOperationError", - } -} - -fn get_crypto_import_key_error_class(e: &ImportKeyError) -> &'static str { - match e { - ImportKeyError::General(e) => get_crypto_shared_error_class(e), - ImportKeyError::InvalidModulus => "DOMExceptionDataError", - ImportKeyError::InvalidPublicExponent => "DOMExceptionDataError", - ImportKeyError::InvalidPrivateExponent => "DOMExceptionDataError", - ImportKeyError::InvalidFirstPrimeFactor => "DOMExceptionDataError", - ImportKeyError::InvalidSecondPrimeFactor => "DOMExceptionDataError", - ImportKeyError::InvalidFirstCRTExponent => "DOMExceptionDataError", - ImportKeyError::InvalidSecondCRTExponent => "DOMExceptionDataError", - ImportKeyError::InvalidCRTCoefficient => "DOMExceptionDataError", - ImportKeyError::InvalidB64Coordinate => "DOMExceptionDataError", - ImportKeyError::InvalidRSAPublicKey => "DOMExceptionDataError", - ImportKeyError::InvalidRSAPrivateKey => "DOMExceptionDataError", - ImportKeyError::UnsupportedAlgorithm => "DOMExceptionDataError", - ImportKeyError::PublicKeyTooLong => "DOMExceptionDataError", - ImportKeyError::PrivateKeyTooLong => "DOMExceptionDataError", - ImportKeyError::InvalidP256ECPoint => "DOMExceptionDataError", - ImportKeyError::InvalidP384ECPoint => "DOMExceptionDataError", - ImportKeyError::InvalidP521ECPoint => "DOMExceptionDataError", - ImportKeyError::UnsupportedNamedCurve => "DOMExceptionDataError", - ImportKeyError::CurveMismatch => "DOMExceptionDataError", - ImportKeyError::InvalidKeyData => "DOMExceptionDataError", - ImportKeyError::InvalidJWKPrivateKey => "DOMExceptionDataError", - ImportKeyError::EllipticCurve(_) => "DOMExceptionDataError", - ImportKeyError::ExpectedValidPkcs8Data => "DOMExceptionDataError", - ImportKeyError::MalformedParameters => "DOMExceptionDataError", - ImportKeyError::Spki(_) => "DOMExceptionDataError", - ImportKeyError::InvalidP256ECSPKIData => "DOMExceptionDataError", - ImportKeyError::InvalidP384ECSPKIData => "DOMExceptionDataError", - ImportKeyError::InvalidP521ECSPKIData => "DOMExceptionDataError", - ImportKeyError::Der(_) => "DOMExceptionDataError", - } -} - -fn get_crypto_x448_error_class(e: &deno_crypto::X448Error) -> &'static str { - match e { - deno_crypto::X448Error::FailedExport => "DOMExceptionOperationError", - deno_crypto::X448Error::Der(_) => "Error", - } -} - -fn get_crypto_x25519_error_class(e: &deno_crypto::X25519Error) -> &'static str { - match e { - deno_crypto::X25519Error::FailedExport => "DOMExceptionOperationError", - deno_crypto::X25519Error::Der(_) => "Error", - } -} - -fn get_crypto_error_class(e: &deno_crypto::Error) -> &'static str { - match e { - deno_crypto::Error::Der(_) => "Error", - deno_crypto::Error::JoinError(_) => "Error", - deno_crypto::Error::MissingArgumentHash => "TypeError", - deno_crypto::Error::MissingArgumentSaltLength => "TypeError", - deno_crypto::Error::Other(e) => get_error_class_name(e).unwrap_or("Error"), - deno_crypto::Error::UnsupportedAlgorithm => "TypeError", - deno_crypto::Error::KeyRejected(_) => "Error", - deno_crypto::Error::RSA(_) => "Error", - deno_crypto::Error::Pkcs1(_) => "Error", - deno_crypto::Error::Unspecified(_) => "Error", - deno_crypto::Error::InvalidKeyFormat => "TypeError", - deno_crypto::Error::MissingArgumentPublicKey => "TypeError", - deno_crypto::Error::P256Ecdsa(_) => "Error", - deno_crypto::Error::DecodePrivateKey => "TypeError", - deno_crypto::Error::MissingArgumentNamedCurve => "TypeError", - deno_crypto::Error::MissingArgumentInfo => "TypeError", - deno_crypto::Error::HKDFLengthTooLarge => "DOMExceptionOperationError", - deno_crypto::Error::General(e) => get_crypto_shared_error_class(e), - deno_crypto::Error::Base64Decode(_) => "Error", - deno_crypto::Error::DataInvalidSize => "TypeError", - deno_crypto::Error::InvalidKeyLength => "TypeError", - deno_crypto::Error::EncryptionError => "DOMExceptionOperationError", - deno_crypto::Error::DecryptionError => "DOMExceptionOperationError", - deno_crypto::Error::ArrayBufferViewLengthExceeded(_) => { - "DOMExceptionQuotaExceededError" - } - } -} - -fn get_napi_error_class(e: &NApiError) -> &'static str { - match e { - NApiError::InvalidPath - | NApiError::LibLoading(_) - | NApiError::ModuleNotFound(_) => "TypeError", - NApiError::Permission(e) => get_permission_check_error_class(e), - } -} - -fn get_web_error_class(e: &WebError) -> &'static str { - match e { - WebError::Base64Decode => "DOMExceptionInvalidCharacterError", - WebError::InvalidEncodingLabel(_) => "RangeError", - WebError::BufferTooLong => "TypeError", - WebError::ValueTooLarge => "RangeError", - WebError::BufferTooSmall => "RangeError", - WebError::DataInvalid => "TypeError", - WebError::DataError(_) => "Error", - } -} - -fn get_web_compression_error_class(e: &CompressionError) -> &'static str { - match e { - CompressionError::UnsupportedFormat => "TypeError", - CompressionError::ResourceClosed => "TypeError", - CompressionError::IoTypeError(_) => "TypeError", - CompressionError::Io(e) => get_io_error_class(e), - } -} - -fn get_web_message_port_error_class(e: &MessagePortError) -> &'static str { - match e { - MessagePortError::InvalidTransfer => "TypeError", - MessagePortError::NotReady => "TypeError", - MessagePortError::TransferSelf => "TypeError", - MessagePortError::Canceled(e) => { - let io_err: io::Error = e.to_owned().into(); - get_io_error_class(&io_err) - } - MessagePortError::Resource(e) => get_error_class_name(e).unwrap_or("Error"), - } -} - -fn get_web_stream_resource_error_class( - e: &StreamResourceError, -) -> &'static str { - match e { - StreamResourceError::Canceled(e) => { - let io_err: io::Error = e.to_owned().into(); - get_io_error_class(&io_err) - } - StreamResourceError::Js(_) => "TypeError", - } -} - -fn get_web_blob_error_class(e: &BlobError) -> &'static str { - match e { - BlobError::BlobPartNotFound => "TypeError", - BlobError::SizeLargerThanBlobPart => "TypeError", - BlobError::BlobURLsNotSupported => "TypeError", - BlobError::Url(_) => "Error", - } -} - -fn get_ffi_repr_error_class(e: &ReprError) -> &'static str { - match e { - ReprError::InvalidOffset => "TypeError", - ReprError::InvalidArrayBuffer => "TypeError", - ReprError::DestinationLengthTooShort => "RangeError", - ReprError::InvalidCString => "TypeError", - ReprError::CStringTooLong => "TypeError", - ReprError::InvalidBool => "TypeError", - ReprError::InvalidU8 => "TypeError", - ReprError::InvalidI8 => "TypeError", - ReprError::InvalidU16 => "TypeError", - ReprError::InvalidI16 => "TypeError", - ReprError::InvalidU32 => "TypeError", - ReprError::InvalidI32 => "TypeError", - ReprError::InvalidU64 => "TypeError", - ReprError::InvalidI64 => "TypeError", - ReprError::InvalidF32 => "TypeError", - ReprError::InvalidF64 => "TypeError", - ReprError::InvalidPointer => "TypeError", - ReprError::Permission(e) => get_permission_check_error_class(e), - } -} - -fn get_ffi_dlfcn_error_class(e: &DlfcnError) -> &'static str { - match e { - DlfcnError::RegisterSymbol { .. } => "Error", - DlfcnError::Dlopen(_) => "Error", - DlfcnError::Permission(e) => get_permission_check_error_class(e), - DlfcnError::Other(e) => get_error_class_name(e).unwrap_or("Error"), - } -} - -fn get_ffi_static_error_class(e: &StaticError) -> &'static str { - match e { - StaticError::Dlfcn(e) => get_ffi_dlfcn_error_class(e), - StaticError::InvalidTypeVoid => "TypeError", - StaticError::InvalidTypeStruct => "TypeError", - StaticError::Resource(e) => get_error_class_name(e).unwrap_or("Error"), - } -} - -fn get_ffi_callback_error_class(e: &CallbackError) -> &'static str { - match e { - CallbackError::Resource(e) => get_error_class_name(e).unwrap_or("Error"), - CallbackError::Other(e) => get_error_class_name(e).unwrap_or("Error"), - CallbackError::Permission(e) => get_permission_check_error_class(e), - } -} - -fn get_ffi_call_error_class(e: &CallError) -> &'static str { - match e { - CallError::IR(_) => "TypeError", - CallError::NonblockingCallFailure(_) => "Error", - CallError::InvalidSymbol(_) => "TypeError", - CallError::Permission(e) => get_permission_check_error_class(e), - CallError::Callback(e) => get_ffi_callback_error_class(e), - CallError::Resource(e) => get_error_class_name(e).unwrap_or("Error"), - } -} - -fn get_webstorage_class_name(e: &WebStorageError) -> &'static str { - match e { - WebStorageError::ContextNotSupported => "DOMExceptionNotSupportedError", - WebStorageError::Sqlite(_) => "Error", - WebStorageError::Io(e) => get_io_error_class(e), - WebStorageError::StorageExceeded => "DOMExceptionQuotaExceededError", - } -} - -fn get_tls_error_class(e: &TlsError) -> &'static str { - match e { - TlsError::Rustls(_) => "Error", - TlsError::UnableAddPemFileToCert(e) => get_io_error_class(e), - TlsError::CertInvalid - | TlsError::CertsNotFound - | TlsError::KeysNotFound - | TlsError::KeyDecode => "InvalidData", - } -} - -pub fn get_cron_error_class(e: &CronError) -> &'static str { - match e { - CronError::Resource(e) => { - deno_core::error::get_custom_error_class(e).unwrap_or("Error") - } - CronError::NameExceeded(_) => "TypeError", - CronError::NameInvalid => "TypeError", - CronError::AlreadyExists => "TypeError", - CronError::TooManyCrons => "TypeError", - CronError::InvalidCron => "TypeError", - CronError::InvalidBackoff => "TypeError", - CronError::AcquireError(_) => "Error", - CronError::Other(e) => get_error_class_name(e).unwrap_or("Error"), - } -} - -fn get_canvas_error(e: &CanvasError) -> &'static str { - match e { - CanvasError::UnsupportedColorType(_) => "TypeError", - CanvasError::Image(_) => "Error", - } -} - -pub fn get_cache_error(error: &CacheError) -> &'static str { - match error { - CacheError::Sqlite(_) => "Error", - CacheError::JoinError(_) => "Error", - CacheError::Resource(err) => { - deno_core::error::get_custom_error_class(err).unwrap_or("Error") - } - CacheError::Other(e) => get_error_class_name(e).unwrap_or("Error"), - CacheError::Io(err) => get_io_error_class(err), - } -} - -fn get_broadcast_channel_error(error: &BroadcastChannelError) -> &'static str { - match error { - BroadcastChannelError::Resource(err) => { - deno_core::error::get_custom_error_class(err).unwrap() - } - BroadcastChannelError::MPSCSendError(_) => "Error", - BroadcastChannelError::BroadcastSendError(_) => "Error", - BroadcastChannelError::Other(err) => { - get_error_class_name(err).unwrap_or("Error") - } - } -} - -fn get_geometry_error(error: &GeometryError) -> &'static str { - match error { - GeometryError::Inconsistent2DMatrix => "TypeError", - } -} - -fn get_fetch_error(error: &FetchError) -> &'static str { - match error { - FetchError::Resource(e) => get_error_class_name(e).unwrap_or("Error"), - FetchError::Permission(e) => get_permission_check_error_class(e), - FetchError::NetworkError => "TypeError", - FetchError::FsNotGet(_) => "TypeError", - FetchError::PathToUrl(_) => "TypeError", - FetchError::InvalidUrl(_) => "TypeError", - FetchError::InvalidHeaderName(_) => "TypeError", - FetchError::InvalidHeaderValue(_) => "TypeError", - FetchError::DataUrl(_) => "TypeError", - FetchError::Base64(_) => "TypeError", - FetchError::BlobNotFound => "TypeError", - FetchError::SchemeNotSupported(_) => "TypeError", - FetchError::RequestCanceled => "TypeError", - FetchError::Http(_) => "Error", - FetchError::ClientCreate(e) => get_http_client_create_error(e), - FetchError::Url(e) => get_url_parse_error_class(e), - FetchError::Method(_) => "TypeError", - FetchError::ClientSend(_) => "TypeError", - FetchError::RequestBuilderHook(_) => "TypeError", - FetchError::Io(e) => get_io_error_class(e), - } -} - -fn get_http_client_create_error(error: &HttpClientCreateError) -> &'static str { - match error { - HttpClientCreateError::Tls(_) => "TypeError", - HttpClientCreateError::InvalidUserAgent(_) => "TypeError", - HttpClientCreateError::InvalidProxyUrl => "TypeError", - HttpClientCreateError::HttpVersionSelectionInvalid => "TypeError", - HttpClientCreateError::RootCertStore(_) => "TypeError", - } -} - -fn get_websocket_error(error: &WebsocketError) -> &'static str { - match error { - WebsocketError::Resource(e) => get_error_class_name(e).unwrap_or("Error"), - WebsocketError::Permission(e) => get_permission_check_error_class(e), - WebsocketError::Url(e) => get_url_parse_error_class(e), - WebsocketError::Io(e) => get_io_error_class(e), - WebsocketError::WebSocket(_) => "TypeError", - WebsocketError::ConnectionFailed(_) => "DOMExceptionNetworkError", - WebsocketError::Uri(_) => "Error", - WebsocketError::Canceled(e) => { - let io_err: io::Error = e.to_owned().into(); - get_io_error_class(&io_err) - } - } -} - -fn get_websocket_handshake_error(error: &HandshakeError) -> &'static str { - match error { - HandshakeError::RootStoreError(e) => { - get_error_class_name(e).unwrap_or("Error") - } - HandshakeError::Tls(e) => get_tls_error_class(e), - HandshakeError::MissingPath => "TypeError", - HandshakeError::Http(_) => "Error", - HandshakeError::InvalidHostname(_) => "TypeError", - HandshakeError::Io(e) => get_io_error_class(e), - HandshakeError::Rustls(_) => "Error", - HandshakeError::H2(_) => "Error", - HandshakeError::NoH2Alpn => "Error", - HandshakeError::InvalidStatusCode(_) => "Error", - HandshakeError::WebSocket(_) => "TypeError", - HandshakeError::HeaderName(_) => "TypeError", - HandshakeError::HeaderValue(_) => "TypeError", - } -} - -fn get_fs_ops_error(error: &FsOpsError) -> &'static str { - use FsOpsErrorKind::*; - match error.as_kind() { - Io(e) => get_io_error_class(e), - OperationError(e) => get_fs_error(&e.err), - Permission(e) => get_permission_check_error_class(e), - Resource(e) | Other(e) => get_error_class_name(e).unwrap_or("Error"), - InvalidUtf8(_) => "InvalidData", - StripPrefix(_) => "Error", - Canceled(e) => { - let io_err: io::Error = e.to_owned().into(); - get_io_error_class(&io_err) - } - InvalidSeekMode(_) => "TypeError", - InvalidControlCharacter(_) => "Error", - InvalidCharacter(_) => "Error", - #[cfg(windows)] - InvalidTrailingCharacter => "Error", - NotCapableAccess { .. } => "NotCapable", - NotCapable(_) => "NotCapable", - } -} - -fn get_kv_error(error: &KvError) -> &'static str { - use KvErrorKind::*; - match error.as_kind() { - DatabaseHandler(e) | Resource(e) | Kv(e) => { - get_error_class_name(e).unwrap_or("Error") - } - TooManyRanges(_) => "TypeError", - TooManyEntries(_) => "TypeError", - TooManyChecks(_) => "TypeError", - TooManyMutations(_) => "TypeError", - TooManyKeys(_) => "TypeError", - InvalidLimit => "TypeError", - InvalidBoundaryKey => "TypeError", - KeyTooLargeToRead(_) => "TypeError", - KeyTooLargeToWrite(_) => "TypeError", - TotalMutationTooLarge(_) => "TypeError", - TotalKeyTooLarge(_) => "TypeError", - Io(e) => get_io_error_class(e), - QueueMessageNotFound => "TypeError", - StartKeyNotInKeyspace => "TypeError", - EndKeyNotInKeyspace => "TypeError", - StartKeyGreaterThanEndKey => "TypeError", - InvalidCheck(e) => match e { - KvCheckError::InvalidVersionstamp => "TypeError", - KvCheckError::Io(e) => get_io_error_class(e), - }, - InvalidMutation(e) => match e { - KvMutationError::BigInt(_) => "Error", - KvMutationError::Io(e) => get_io_error_class(e), - KvMutationError::InvalidMutationWithValue(_) => "TypeError", - KvMutationError::InvalidMutationWithoutValue(_) => "TypeError", - }, - InvalidEnqueue(e) => get_io_error_class(e), - EmptyKey => "TypeError", - ValueTooLarge(_) => "TypeError", - EnqueuePayloadTooLarge(_) => "TypeError", - InvalidCursor => "TypeError", - CursorOutOfBounds => "TypeError", - InvalidRange => "TypeError", - } -} - -fn get_net_error(error: &NetError) -> &'static str { - match error { - NetError::ListenerClosed => "BadResource", - NetError::ListenerBusy => "Busy", - NetError::SocketClosed => "BadResource", - NetError::SocketClosedNotConnected => "NotConnected", - NetError::SocketBusy => "Busy", - NetError::Io(e) => get_io_error_class(e), - NetError::AcceptTaskOngoing => "Busy", - NetError::RootCertStore(e) | NetError::Resource(e) => { - get_error_class_name(e).unwrap_or("Error") - } - NetError::Permission(e) => get_permission_check_error_class(e), - NetError::NoResolvedAddress => "Error", - NetError::AddrParse(_) => "Error", - NetError::Map(e) => get_net_map_error(e), - NetError::Canceled(e) => { - let io_err: io::Error = e.to_owned().into(); - get_io_error_class(&io_err) - } - NetError::DnsNotFound(_) => "NotFound", - NetError::DnsNotConnected(_) => "NotConnected", - NetError::DnsTimedOut(_) => "TimedOut", - NetError::Dns(_) => "Error", - NetError::UnsupportedRecordType => "NotSupported", - NetError::InvalidUtf8(_) => "InvalidData", - NetError::UnexpectedKeyType => "Error", - NetError::InvalidHostname(_) => "TypeError", - NetError::TcpStreamBusy => "Busy", - NetError::Rustls(_) => "Error", - NetError::Tls(e) => get_tls_error_class(e), - NetError::ListenTlsRequiresKey => "InvalidData", - NetError::Reunite(_) => "Error", - } -} - -fn get_net_map_error(error: &deno_net::io::MapError) -> &'static str { - match error { - deno_net::io::MapError::Io(e) => get_io_error_class(e), - deno_net::io::MapError::NoResources => "Error", - } -} - -fn get_child_permission_error(e: &ChildPermissionError) -> &'static str { - match e { - ChildPermissionError::Escalation => "NotCapable", - ChildPermissionError::PathResolve(e) => get_path_resolve_error(e), - ChildPermissionError::NetDescriptorParse(_) => "URIError", - ChildPermissionError::EnvDescriptorParse(_) => "Error", - ChildPermissionError::SysDescriptorParse(e) => { - get_sys_descriptor_parse_error(e) - } - ChildPermissionError::RunDescriptorParse(e) => { - get_run_descriptor_parse_error(e) - } - } -} - -fn get_create_worker_error(error: &CreateWorkerError) -> &'static str { - match error { - CreateWorkerError::ClassicWorkers => "DOMExceptionNotSupportedError", - CreateWorkerError::Permission(e) => get_child_permission_error(e), - CreateWorkerError::ModuleResolution(e) => { - get_module_resolution_error_class(e) - } - CreateWorkerError::Io(e) => get_io_error_class(e), - CreateWorkerError::MessagePort(e) => get_web_message_port_error_class(e), - } -} - -fn get_tty_error(error: &TtyError) -> &'static str { - match error { - TtyError::Resource(e) | TtyError::Other(e) => { - get_error_class_name(e).unwrap_or("Error") - } - TtyError::Io(e) => get_io_error_class(e), - #[cfg(unix)] - TtyError::Nix(e) => get_nix_error_class(e), - } -} - -fn get_readline_error(error: &ReadlineError) -> &'static str { - match error { - ReadlineError::Io(e) => get_io_error_class(e), - ReadlineError::Eof => "Error", - ReadlineError::Interrupted => "Error", - #[cfg(unix)] - ReadlineError::Errno(e) => get_nix_error_class(e), - ReadlineError::WindowResized => "Error", - #[cfg(windows)] - ReadlineError::Decode(_) => "Error", - #[cfg(windows)] - ReadlineError::SystemError(_) => "Error", - _ => "Error", - } -} - -fn get_signal_error(error: &SignalError) -> &'static str { - match error { - SignalError::InvalidSignalStr(_) => "TypeError", - SignalError::InvalidSignalInt(_) => "TypeError", - SignalError::SignalNotAllowed(_) => "TypeError", - SignalError::Io(e) => get_io_error_class(e), - } -} - -fn get_fs_events_error(error: &FsEventsError) -> &'static str { - match error { - FsEventsError::Resource(e) => get_error_class_name(e).unwrap_or("Error"), - FsEventsError::Permission(e) => get_permission_check_error_class(e), - FsEventsError::Notify(e) => get_notify_error_class(e), - FsEventsError::Canceled(e) => { - let io_err: io::Error = e.to_owned().into(); - get_io_error_class(&io_err) - } - } -} - -fn get_http_start_error(error: &HttpStartError) -> &'static str { - match error { - HttpStartError::TcpStreamInUse => "Busy", - HttpStartError::TlsStreamInUse => "Busy", - HttpStartError::UnixSocketInUse => "Busy", - HttpStartError::ReuniteTcp(_) => "Error", - #[cfg(unix)] - HttpStartError::ReuniteUnix(_) => "Error", - HttpStartError::Io(e) => get_io_error_class(e), - HttpStartError::Other(e) => get_error_class_name(e).unwrap_or("Error"), - } -} - -fn get_process_error(error: &ProcessError) -> &'static str { - match error { - ProcessError::SpawnFailed { error, .. } => get_process_error(error), - ProcessError::FailedResolvingCwd(e) | ProcessError::Io(e) => { - get_io_error_class(e) - } - ProcessError::Permission(e) => get_permission_check_error_class(e), - ProcessError::Resource(e) => get_error_class_name(e).unwrap_or("Error"), - ProcessError::BorrowMut(_) => "Error", - ProcessError::Which(_) => "Error", - ProcessError::ChildProcessAlreadyTerminated => "TypeError", - ProcessError::Signal(e) => get_signal_error(e), - ProcessError::MissingCmd => "Error", - ProcessError::InvalidPid => "TypeError", - #[cfg(unix)] - ProcessError::Nix(e) => get_nix_error_class(e), - ProcessError::RunPermission(e) => match e { - CheckRunPermissionError::Permission(e) => { - get_permission_check_error_class(e) - } - CheckRunPermissionError::Other(e) => { - get_error_class_name(e).unwrap_or("Error") - } - }, - } -} - -fn get_http_error(error: &HttpError) -> &'static str { - match error { - HttpError::Canceled(e) => { - let io_err: io::Error = e.to_owned().into(); - get_io_error_class(&io_err) - } - HttpError::HyperV014(e) => get_hyper_v014_error_class(e), - HttpError::InvalidHeaderName(_) => "Error", - HttpError::InvalidHeaderValue(_) => "Error", - HttpError::Http(_) => "Error", - HttpError::ResponseHeadersAlreadySent => "Http", - HttpError::ConnectionClosedWhileSendingResponse => "Http", - HttpError::AlreadyInUse => "Http", - HttpError::Io(e) => get_io_error_class(e), - HttpError::NoResponseHeaders => "Http", - HttpError::ResponseAlreadyCompleted => "Http", - HttpError::UpgradeBodyUsed => "Http", - HttpError::Resource(e) | HttpError::Other(e) => { - get_error_class_name(e).unwrap_or("Error") - } - } -} - -fn get_http_next_error(error: &HttpNextError) -> &'static str { - match error { - HttpNextError::Io(e) => get_io_error_class(e), - HttpNextError::WebSocketUpgrade(e) => get_websocket_upgrade_error(e), - HttpNextError::Hyper(e) => get_hyper_error_class(e), - HttpNextError::JoinError(_) => "Error", - HttpNextError::Canceled(e) => { - let io_err: io::Error = e.to_owned().into(); - get_io_error_class(&io_err) - } - HttpNextError::UpgradeUnavailable(_) => "Error", - HttpNextError::HttpPropertyExtractor(e) | HttpNextError::Resource(e) => { - get_error_class_name(e).unwrap_or("Error") - } - } -} - -fn get_websocket_upgrade_error(error: &WebSocketUpgradeError) -> &'static str { - match error { - WebSocketUpgradeError::InvalidHeaders => "Http", - WebSocketUpgradeError::HttpParse(_) => "Error", - WebSocketUpgradeError::Http(_) => "Error", - WebSocketUpgradeError::Utf8(_) => "Error", - WebSocketUpgradeError::InvalidHeaderName(_) => "Error", - WebSocketUpgradeError::InvalidHeaderValue(_) => "Error", - WebSocketUpgradeError::InvalidHttpStatusLine => "Http", - WebSocketUpgradeError::UpgradeBufferAlreadyCompleted => "Http", - } -} - -fn get_fs_error(e: &FsError) -> &'static str { - match &e { - FsError::Io(e) => get_io_error_class(e), - FsError::FileBusy => "Busy", - FsError::NotSupported => "NotSupported", - FsError::NotCapable(_) => "NotCapable", - } -} - -mod node { - pub use deno_node::ops::blocklist::BlocklistError; - pub use deno_node::ops::crypto::cipher::CipherContextError; - pub use deno_node::ops::crypto::cipher::CipherError; - pub use deno_node::ops::crypto::cipher::DecipherContextError; - pub use deno_node::ops::crypto::cipher::DecipherError; - pub use deno_node::ops::crypto::digest::HashError; - pub use deno_node::ops::crypto::keys::AsymmetricPrivateKeyDerError; - pub use deno_node::ops::crypto::keys::AsymmetricPrivateKeyError; - pub use deno_node::ops::crypto::keys::AsymmetricPublicKeyDerError; - pub use deno_node::ops::crypto::keys::AsymmetricPublicKeyError; - pub use deno_node::ops::crypto::keys::AsymmetricPublicKeyJwkError; - pub use deno_node::ops::crypto::keys::EcJwkError; - pub use deno_node::ops::crypto::keys::EdRawError; - pub use deno_node::ops::crypto::keys::ExportPrivateKeyPemError; - pub use deno_node::ops::crypto::keys::ExportPublicKeyPemError; - pub use deno_node::ops::crypto::keys::GenerateRsaPssError; - pub use deno_node::ops::crypto::keys::RsaJwkError; - pub use deno_node::ops::crypto::keys::RsaPssParamsParseError; - pub use deno_node::ops::crypto::keys::X509PublicKeyError; - pub use deno_node::ops::crypto::sign::KeyObjectHandlePrehashedSignAndVerifyError; - pub use deno_node::ops::crypto::x509::X509Error; - pub use deno_node::ops::crypto::DiffieHellmanError; - pub use deno_node::ops::crypto::EcdhEncodePubKey; - pub use deno_node::ops::crypto::HkdfError; - pub use deno_node::ops::crypto::Pbkdf2Error; - pub use deno_node::ops::crypto::PrivateEncryptDecryptError; - pub use deno_node::ops::crypto::ScryptAsyncError; - pub use deno_node::ops::crypto::SignEd25519Error; - pub use deno_node::ops::crypto::VerifyEd25519Error; - pub use deno_node::ops::fs::FsError; - pub use deno_node::ops::http::ConnError; - pub use deno_node::ops::http2::Http2Error; - pub use deno_node::ops::idna::IdnaError; - pub use deno_node::ops::ipc::IpcError; - pub use deno_node::ops::ipc::IpcJsonStreamError; - use deno_node::ops::os::priority::PriorityError; - pub use deno_node::ops::os::OsError; - pub use deno_node::ops::require::RequireError; - use deno_node::ops::require::RequireErrorKind; - pub use deno_node::ops::worker_threads::WorkerThreadsFilenameError; - pub use deno_node::ops::zlib::brotli::BrotliError; - pub use deno_node::ops::zlib::mode::ModeError; - pub use deno_node::ops::zlib::ZlibError; - - use super::get_error_class_name; - use super::get_io_error_class; - use super::get_permission_check_error_class; - use super::get_serde_json_error_class; - use super::get_url_parse_error_class; - - pub fn get_blocklist_error(error: &BlocklistError) -> &'static str { - match error { - BlocklistError::AddrParse(_) => "Error", - BlocklistError::IpNetwork(_) => "Error", - BlocklistError::InvalidAddress => "Error", - BlocklistError::IpVersionMismatch => "Error", - } - } - - pub fn get_fs_error(error: &FsError) -> &'static str { - match error { - FsError::Permission(e) => get_permission_check_error_class(e), - FsError::Io(e) => get_io_error_class(e), - #[cfg(windows)] - FsError::PathHasNoRoot => "Error", - #[cfg(not(any(unix, windows)))] - FsError::UnsupportedPlatform => "Error", - FsError::Fs(e) => super::get_fs_error(e), - } - } - - pub fn get_idna_error(error: &IdnaError) -> &'static str { - match error { - IdnaError::InvalidInput => "RangeError", - IdnaError::InputTooLong => "Error", - IdnaError::IllegalInput => "RangeError", - } - } - - pub fn get_ipc_json_stream_error(error: &IpcJsonStreamError) -> &'static str { - match error { - IpcJsonStreamError::Io(e) => get_io_error_class(e), - IpcJsonStreamError::SimdJson(_) => "Error", - } - } - - pub fn get_ipc_error(error: &IpcError) -> &'static str { - match error { - IpcError::Resource(e) => get_error_class_name(e).unwrap_or("Error"), - IpcError::IpcJsonStream(e) => get_ipc_json_stream_error(e), - IpcError::Canceled(e) => { - let io_err: std::io::Error = e.to_owned().into(); - get_io_error_class(&io_err) - } - IpcError::SerdeJson(e) => get_serde_json_error_class(e), - } - } - - pub fn get_worker_threads_filename_error( - error: &WorkerThreadsFilenameError, - ) -> &'static str { - match error { - WorkerThreadsFilenameError::Permission(e) => { - get_error_class_name(e).unwrap_or("Error") - } - WorkerThreadsFilenameError::UrlParse(e) => get_url_parse_error_class(e), - WorkerThreadsFilenameError::InvalidRelativeUrl => "Error", - WorkerThreadsFilenameError::UrlFromPathString => "Error", - WorkerThreadsFilenameError::UrlToPathString => "Error", - WorkerThreadsFilenameError::UrlToPath => "Error", - WorkerThreadsFilenameError::FileNotFound(_) => "Error", - WorkerThreadsFilenameError::Fs(e) => super::get_io_error_class(e), - } - } - - pub fn get_require_error(error: &RequireError) -> &'static str { - use RequireErrorKind::*; - match error.as_kind() { - UrlParse(e) => get_url_parse_error_class(e), - Permission(e) => get_error_class_name(e).unwrap_or("Error"), - PackageExportsResolve(_) - | PackageJsonLoad(_) - | ClosestPkgJson(_) - | FilePathConversion(_) - | UrlConversion(_) - | ReadModule(_) - | PackageImportsResolve(_) => "Error", - Fs(e) | UnableToGetCwd(e) => super::get_io_error_class(e), - } - } - - pub fn get_http2_error(error: &Http2Error) -> &'static str { - match error { - Http2Error::Resource(e) => get_error_class_name(e).unwrap_or("Error"), - Http2Error::UrlParse(e) => get_url_parse_error_class(e), - Http2Error::H2(_) => "Error", - } - } - - pub fn get_os_error(error: &OsError) -> &'static str { - match error { - OsError::Priority(e) => match e { - PriorityError::Io(e) => get_io_error_class(e), - #[cfg(windows)] - PriorityError::InvalidPriority => "TypeError", - }, - OsError::Permission(e) => get_permission_check_error_class(e), - OsError::FailedToGetCpuInfo => "TypeError", - OsError::FailedToGetUserInfo(e) => get_io_error_class(e), - } - } - - pub fn get_brotli_error(error: &BrotliError) -> &'static str { - match error { - BrotliError::InvalidEncoderMode => "TypeError", - BrotliError::CompressFailed => "TypeError", - BrotliError::DecompressFailed => "TypeError", - BrotliError::Join(_) => "Error", - BrotliError::Resource(e) => get_error_class_name(e).unwrap_or("Error"), - BrotliError::Io(e) => get_io_error_class(e), - } - } - - pub fn get_mode_error(_: &ModeError) -> &'static str { - "Error" - } - - pub fn get_zlib_error(e: &ZlibError) -> &'static str { - match e { - ZlibError::NotInitialized => "TypeError", - ZlibError::Mode(e) => get_mode_error(e), - ZlibError::Other(e) => get_error_class_name(e).unwrap_or("Error"), - } - } - - pub fn get_crypto_cipher_context_error( - e: &CipherContextError, - ) -> &'static str { - match e { - CipherContextError::ContextInUse => "TypeError", - CipherContextError::Cipher(e) => get_crypto_cipher_error(e), - CipherContextError::Resource(e) => { - get_error_class_name(e).unwrap_or("Error") - } - } - } - - pub fn get_crypto_cipher_error(e: &CipherError) -> &'static str { - match e { - CipherError::InvalidIvLength => "TypeError", - CipherError::InvalidKeyLength => "RangeError", - CipherError::InvalidInitializationVector => "TypeError", - CipherError::CannotPadInputData => "TypeError", - CipherError::UnknownCipher(_) => "TypeError", - } - } - - pub fn get_crypto_decipher_context_error( - e: &DecipherContextError, - ) -> &'static str { - match e { - DecipherContextError::ContextInUse => "TypeError", - DecipherContextError::Decipher(e) => get_crypto_decipher_error(e), - DecipherContextError::Resource(e) => { - get_error_class_name(e).unwrap_or("Error") - } - } - } - - pub fn get_crypto_decipher_error(e: &DecipherError) -> &'static str { - match e { - DecipherError::InvalidIvLength => "TypeError", - DecipherError::InvalidKeyLength => "RangeError", - DecipherError::InvalidInitializationVector => "TypeError", - DecipherError::CannotUnpadInputData => "TypeError", - DecipherError::DataAuthenticationFailed => "TypeError", - DecipherError::SetAutoPaddingFalseAes128GcmUnsupported => "TypeError", - DecipherError::SetAutoPaddingFalseAes256GcmUnsupported => "TypeError", - DecipherError::UnknownCipher(_) => "TypeError", - } - } - - pub fn get_x509_error(_: &X509Error) -> &'static str { - "Error" - } - - pub fn get_crypto_key_object_handle_prehashed_sign_and_verify_error( - e: &KeyObjectHandlePrehashedSignAndVerifyError, - ) -> &'static str { - match e { - KeyObjectHandlePrehashedSignAndVerifyError::InvalidDsaSignatureEncoding => "TypeError", - KeyObjectHandlePrehashedSignAndVerifyError::KeyIsNotPrivate => "TypeError", - KeyObjectHandlePrehashedSignAndVerifyError::DigestNotAllowedForRsaSignature(_) => "TypeError", - KeyObjectHandlePrehashedSignAndVerifyError::FailedToSignDigestWithRsa => "Error", - KeyObjectHandlePrehashedSignAndVerifyError::DigestNotAllowedForRsaPssSignature(_) => "TypeError", - KeyObjectHandlePrehashedSignAndVerifyError::FailedToSignDigestWithRsaPss => "Error", - KeyObjectHandlePrehashedSignAndVerifyError::FailedToSignDigestWithDsa => "TypeError", - KeyObjectHandlePrehashedSignAndVerifyError::RsaPssHashAlgorithmUnsupported => "TypeError", - KeyObjectHandlePrehashedSignAndVerifyError::PrivateKeyDisallowsUsage { .. } => "TypeError", - KeyObjectHandlePrehashedSignAndVerifyError::FailedToSignDigest => "TypeError", - KeyObjectHandlePrehashedSignAndVerifyError::X25519KeyCannotBeUsedForSigning => "TypeError", - KeyObjectHandlePrehashedSignAndVerifyError::Ed25519KeyCannotBeUsedForPrehashedSigning => "TypeError", - KeyObjectHandlePrehashedSignAndVerifyError::DhKeyCannotBeUsedForSigning => "TypeError", - KeyObjectHandlePrehashedSignAndVerifyError::KeyIsNotPublicOrPrivate => "TypeError", - KeyObjectHandlePrehashedSignAndVerifyError::InvalidDsaSignature => "TypeError", - KeyObjectHandlePrehashedSignAndVerifyError::X25519KeyCannotBeUsedForVerification => "TypeError", - KeyObjectHandlePrehashedSignAndVerifyError::Ed25519KeyCannotBeUsedForPrehashedVerification => "TypeError", - KeyObjectHandlePrehashedSignAndVerifyError::DhKeyCannotBeUsedForVerification => "TypeError", - } - } - - pub fn get_crypto_hash_error(_: &HashError) -> &'static str { - "Error" - } - - pub fn get_asymmetric_public_key_jwk_error( - e: &AsymmetricPublicKeyJwkError, - ) -> &'static str { - match e { - AsymmetricPublicKeyJwkError::UnsupportedJwkEcCurveP224 => "TypeError", - AsymmetricPublicKeyJwkError::JwkExportNotImplementedForKeyType => { - "TypeError" - } - AsymmetricPublicKeyJwkError::KeyIsNotAsymmetricPublicKey => "TypeError", - } - } - - pub fn get_generate_rsa_pss_error(_: &GenerateRsaPssError) -> &'static str { - "TypeError" - } - - pub fn get_asymmetric_private_key_der_error( - e: &AsymmetricPrivateKeyDerError, - ) -> &'static str { - match e { - AsymmetricPrivateKeyDerError::KeyIsNotAsymmetricPrivateKey => "TypeError", - AsymmetricPrivateKeyDerError::InvalidRsaPrivateKey => "TypeError", - AsymmetricPrivateKeyDerError::ExportingNonRsaPrivateKeyAsPkcs1Unsupported => "TypeError", - AsymmetricPrivateKeyDerError::InvalidEcPrivateKey => "TypeError", - AsymmetricPrivateKeyDerError::ExportingNonEcPrivateKeyAsSec1Unsupported => "TypeError", - AsymmetricPrivateKeyDerError::ExportingNonRsaPssPrivateKeyAsPkcs8Unsupported => "Error", - AsymmetricPrivateKeyDerError::InvalidDsaPrivateKey => "TypeError", - AsymmetricPrivateKeyDerError::InvalidX25519PrivateKey => "TypeError", - AsymmetricPrivateKeyDerError::InvalidEd25519PrivateKey => "TypeError", - AsymmetricPrivateKeyDerError::InvalidDhPrivateKey => "TypeError", - AsymmetricPrivateKeyDerError::UnsupportedKeyType(_) => "TypeError", - } - } - - pub fn get_asymmetric_public_key_der_error( - _: &AsymmetricPublicKeyDerError, - ) -> &'static str { - "TypeError" - } - - pub fn get_export_public_key_pem_error( - e: &ExportPublicKeyPemError, - ) -> &'static str { - match e { - ExportPublicKeyPemError::AsymmetricPublicKeyDer(e) => { - get_asymmetric_public_key_der_error(e) - } - ExportPublicKeyPemError::VeryLargeData => "TypeError", - ExportPublicKeyPemError::Der(_) => "Error", - } - } - - pub fn get_export_private_key_pem_error( - e: &ExportPrivateKeyPemError, - ) -> &'static str { - match e { - ExportPrivateKeyPemError::AsymmetricPublicKeyDer(e) => { - get_asymmetric_private_key_der_error(e) - } - ExportPrivateKeyPemError::VeryLargeData => "TypeError", - ExportPrivateKeyPemError::Der(_) => "Error", - } - } - - pub fn get_x509_public_key_error(e: &X509PublicKeyError) -> &'static str { - match e { - X509PublicKeyError::X509(_) => "Error", - X509PublicKeyError::Rsa(_) => "Error", - X509PublicKeyError::Asn1(_) => "Error", - X509PublicKeyError::Ec(_) => "Error", - X509PublicKeyError::UnsupportedEcNamedCurve => "TypeError", - X509PublicKeyError::MissingEcParameters => "TypeError", - X509PublicKeyError::MalformedDssPublicKey => "TypeError", - X509PublicKeyError::UnsupportedX509KeyType => "TypeError", - } - } - - pub fn get_rsa_jwk_error(e: &RsaJwkError) -> &'static str { - match e { - RsaJwkError::Base64(_) => "Error", - RsaJwkError::Rsa(_) => "Error", - RsaJwkError::MissingRsaPrivateComponent => "TypeError", - } - } - - pub fn get_ec_jwk_error(e: &EcJwkError) -> &'static str { - match e { - EcJwkError::Ec(_) => "Error", - EcJwkError::UnsupportedCurve(_) => "TypeError", - } - } - - pub fn get_ed_raw_error(e: &EdRawError) -> &'static str { - match e { - EdRawError::Ed25519Signature(_) => "Error", - EdRawError::InvalidEd25519Key => "TypeError", - EdRawError::UnsupportedCurve => "TypeError", - } - } - - pub fn get_pbkdf2_error(e: &Pbkdf2Error) -> &'static str { - match e { - Pbkdf2Error::UnsupportedDigest(_) => "TypeError", - Pbkdf2Error::Join(_) => "Error", - } - } - - pub fn get_scrypt_async_error(e: &ScryptAsyncError) -> &'static str { - match e { - ScryptAsyncError::Join(_) => "Error", - ScryptAsyncError::Other(e) => get_error_class_name(e).unwrap_or("Error"), - } - } - - pub fn get_hkdf_error_error(e: &HkdfError) -> &'static str { - match e { - HkdfError::ExpectedSecretKey => "TypeError", - HkdfError::HkdfExpandFailed => "TypeError", - HkdfError::UnsupportedDigest(_) => "TypeError", - HkdfError::Join(_) => "Error", - } - } - - pub fn get_rsa_pss_params_parse_error( - _: &RsaPssParamsParseError, - ) -> &'static str { - "TypeError" - } - - pub fn get_asymmetric_private_key_error( - e: &AsymmetricPrivateKeyError, - ) -> &'static str { - match e { - AsymmetricPrivateKeyError::InvalidPemPrivateKeyInvalidUtf8(_) => "TypeError", - AsymmetricPrivateKeyError::InvalidEncryptedPemPrivateKey => "TypeError", - AsymmetricPrivateKeyError::InvalidPemPrivateKey => "TypeError", - AsymmetricPrivateKeyError::EncryptedPrivateKeyRequiresPassphraseToDecrypt => "TypeError", - AsymmetricPrivateKeyError::InvalidPkcs1PrivateKey => "TypeError", - AsymmetricPrivateKeyError::InvalidSec1PrivateKey => "TypeError", - AsymmetricPrivateKeyError::UnsupportedPemLabel(_) => "TypeError", - AsymmetricPrivateKeyError::RsaPssParamsParse(e) => get_rsa_pss_params_parse_error(e), - AsymmetricPrivateKeyError::InvalidEncryptedPkcs8PrivateKey => "TypeError", - AsymmetricPrivateKeyError::InvalidPkcs8PrivateKey => "TypeError", - AsymmetricPrivateKeyError::Pkcs1PrivateKeyDoesNotSupportEncryptionWithPassphrase => "TypeError", - AsymmetricPrivateKeyError::Sec1PrivateKeyDoesNotSupportEncryptionWithPassphrase => "TypeError", - AsymmetricPrivateKeyError::UnsupportedEcNamedCurve => "TypeError", - AsymmetricPrivateKeyError::InvalidPrivateKey => "TypeError", - AsymmetricPrivateKeyError::InvalidDsaPrivateKey => "TypeError", - AsymmetricPrivateKeyError::MalformedOrMissingNamedCurveInEcParameters => "TypeError", - AsymmetricPrivateKeyError::UnsupportedKeyType(_) => "TypeError", - AsymmetricPrivateKeyError::UnsupportedKeyFormat(_) => "TypeError", - AsymmetricPrivateKeyError::InvalidX25519PrivateKey => "TypeError", - AsymmetricPrivateKeyError::X25519PrivateKeyIsWrongLength => "TypeError", - AsymmetricPrivateKeyError::InvalidEd25519PrivateKey => "TypeError", - AsymmetricPrivateKeyError::MissingDhParameters => "TypeError", - AsymmetricPrivateKeyError::UnsupportedPrivateKeyOid => "TypeError", - } - } - - pub fn get_asymmetric_public_key_error( - e: &AsymmetricPublicKeyError, - ) -> &'static str { - match e { - AsymmetricPublicKeyError::InvalidPemPrivateKeyInvalidUtf8(_) => { - "TypeError" - } - AsymmetricPublicKeyError::InvalidPemPublicKey => "TypeError", - AsymmetricPublicKeyError::InvalidPkcs1PublicKey => "TypeError", - AsymmetricPublicKeyError::AsymmetricPrivateKey(e) => { - get_asymmetric_private_key_error(e) - } - AsymmetricPublicKeyError::InvalidX509Certificate => "TypeError", - AsymmetricPublicKeyError::X509(_) => "Error", - AsymmetricPublicKeyError::X509PublicKey(e) => { - get_x509_public_key_error(e) - } - AsymmetricPublicKeyError::UnsupportedPemLabel(_) => "TypeError", - AsymmetricPublicKeyError::InvalidSpkiPublicKey => "TypeError", - AsymmetricPublicKeyError::UnsupportedKeyType(_) => "TypeError", - AsymmetricPublicKeyError::UnsupportedKeyFormat(_) => "TypeError", - AsymmetricPublicKeyError::Spki(_) => "Error", - AsymmetricPublicKeyError::Pkcs1(_) => "Error", - AsymmetricPublicKeyError::RsaPssParamsParse(_) => "TypeError", - AsymmetricPublicKeyError::MalformedDssPublicKey => "TypeError", - AsymmetricPublicKeyError::MalformedOrMissingNamedCurveInEcParameters => { - "TypeError" - } - AsymmetricPublicKeyError::MalformedOrMissingPublicKeyInEcSpki => { - "TypeError" - } - AsymmetricPublicKeyError::Ec(_) => "Error", - AsymmetricPublicKeyError::UnsupportedEcNamedCurve => "TypeError", - AsymmetricPublicKeyError::MalformedOrMissingPublicKeyInX25519Spki => { - "TypeError" - } - AsymmetricPublicKeyError::X25519PublicKeyIsTooShort => "TypeError", - AsymmetricPublicKeyError::InvalidEd25519PublicKey => "TypeError", - AsymmetricPublicKeyError::MissingDhParameters => "TypeError", - AsymmetricPublicKeyError::MalformedDhParameters => "TypeError", - AsymmetricPublicKeyError::MalformedOrMissingPublicKeyInDhSpki => { - "TypeError" - } - AsymmetricPublicKeyError::UnsupportedPrivateKeyOid => "TypeError", - } - } - - pub fn get_private_encrypt_decrypt_error( - e: &PrivateEncryptDecryptError, - ) -> &'static str { - match e { - PrivateEncryptDecryptError::Pkcs8(_) => "Error", - PrivateEncryptDecryptError::Spki(_) => "Error", - PrivateEncryptDecryptError::Utf8(_) => "Error", - PrivateEncryptDecryptError::Rsa(_) => "Error", - PrivateEncryptDecryptError::UnknownPadding => "TypeError", - } - } - - pub fn get_ecdh_encode_pub_key_error(e: &EcdhEncodePubKey) -> &'static str { - match e { - EcdhEncodePubKey::InvalidPublicKey => "TypeError", - EcdhEncodePubKey::UnsupportedCurve => "TypeError", - EcdhEncodePubKey::Sec1(_) => "Error", - } - } - - pub fn get_diffie_hellman_error(_: &DiffieHellmanError) -> &'static str { - "TypeError" - } - - pub fn get_sign_ed25519_error(_: &SignEd25519Error) -> &'static str { - "TypeError" - } - - pub fn get_verify_ed25519_error(_: &VerifyEd25519Error) -> &'static str { - "TypeError" - } - - pub fn get_conn_error(e: &ConnError) -> &'static str { - match e { - ConnError::Resource(e) => get_error_class_name(e).unwrap_or("Error"), - ConnError::Permission(e) => get_permission_check_error_class(e), - ConnError::InvalidUrl(_) => "TypeError", - ConnError::InvalidHeaderName(_) => "TypeError", - ConnError::InvalidHeaderValue(_) => "TypeError", - ConnError::Url(e) => get_url_parse_error_class(e), - ConnError::Method(_) => "TypeError", - ConnError::Io(e) => get_io_error_class(e), - ConnError::Hyper(e) => super::get_hyper_error_class(e), - ConnError::TlsStreamBusy => "Busy", - ConnError::TcpStreamBusy => "Busy", - ConnError::ReuniteTcp(_) => "Error", - ConnError::Canceled(_) => "Error", - } - } -} - -fn get_os_error(error: &OsError) -> &'static str { - match error { - OsError::Permission(e) => get_permission_check_error_class(e), - OsError::InvalidUtf8(_) => "InvalidData", - OsError::EnvEmptyKey => "TypeError", - OsError::EnvInvalidKey(_) => "TypeError", - OsError::EnvInvalidValue(_) => "TypeError", - OsError::Io(e) => get_io_error_class(e), - OsError::Var(e) => get_env_var_error_class(e), - } -} - -fn get_sync_fetch_error(error: &SyncFetchError) -> &'static str { - match error { - SyncFetchError::BlobUrlsNotSupportedInContext => "TypeError", - SyncFetchError::Io(e) => get_io_error_class(e), - SyncFetchError::InvalidScriptUrl => "TypeError", - SyncFetchError::InvalidStatusCode(_) => "TypeError", - SyncFetchError::ClassicScriptSchemeUnsupportedInWorkers(_) => "TypeError", - SyncFetchError::InvalidUri(_) => "Error", - SyncFetchError::InvalidMimeType(_) => "DOMExceptionNetworkError", - SyncFetchError::MissingMimeType => "DOMExceptionNetworkError", - SyncFetchError::Fetch(e) => get_fetch_error(e), - SyncFetchError::Join(_) => "Error", - SyncFetchError::Other(e) => get_error_class_name(e).unwrap_or("Error"), - } -} - -pub fn get_error_class_name(e: &AnyError) -> Option<&'static str> { - deno_core::error::get_custom_error_class(e) - .or_else(|| { - e.downcast_ref::() - .map(get_child_permission_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_permission_check_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_permission_error_class) - }) - .or_else(|| e.downcast_ref::().map(get_fs_error)) - .or_else(|| { - e.downcast_ref::() - .map(node::get_blocklist_error) - }) - .or_else(|| e.downcast_ref::().map(node::get_fs_error)) - .or_else(|| { - e.downcast_ref::() - .map(node::get_idna_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_ipc_json_stream_error) - }) - .or_else(|| e.downcast_ref::().map(node::get_ipc_error)) - .or_else(|| { - e.downcast_ref::() - .map(node::get_worker_threads_filename_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_require_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_http2_error) - }) - .or_else(|| e.downcast_ref::().map(node::get_os_error)) - .or_else(|| { - e.downcast_ref::() - .map(node::get_brotli_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_mode_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_zlib_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_crypto_cipher_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_crypto_cipher_context_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_crypto_decipher_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_crypto_decipher_context_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_x509_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_crypto_key_object_handle_prehashed_sign_and_verify_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_crypto_hash_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_asymmetric_public_key_jwk_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_generate_rsa_pss_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_asymmetric_private_key_der_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_asymmetric_public_key_der_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_export_public_key_pem_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_export_private_key_pem_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_rsa_jwk_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_ec_jwk_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_ed_raw_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_pbkdf2_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_scrypt_async_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_hkdf_error_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_rsa_pss_params_parse_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_asymmetric_private_key_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_asymmetric_public_key_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_private_encrypt_decrypt_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_ecdh_encode_pub_key_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_diffie_hellman_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_sign_ed25519_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_verify_ed25519_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(node::get_conn_error) - }) - .or_else(|| e.downcast_ref::().map(get_napi_error_class)) - .or_else(|| e.downcast_ref::().map(get_web_error_class)) - .or_else(|| { - e.downcast_ref::() - .map(get_create_worker_error) - }) - .or_else(|| e.downcast_ref::().map(get_tty_error)) - .or_else(|| e.downcast_ref::().map(get_readline_error)) - .or_else(|| e.downcast_ref::().map(get_signal_error)) - .or_else(|| e.downcast_ref::().map(get_fs_events_error)) - .or_else(|| e.downcast_ref::().map(get_http_start_error)) - .or_else(|| e.downcast_ref::().map(get_process_error)) - .or_else(|| e.downcast_ref::().map(get_os_error)) - .or_else(|| e.downcast_ref::().map(get_geometry_error)) - .or_else(|| e.downcast_ref::().map(get_sync_fetch_error)) - .or_else(|| { - e.downcast_ref::() - .map(get_web_compression_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_web_message_port_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_web_stream_resource_error_class) - }) - .or_else(|| e.downcast_ref::().map(get_web_blob_error_class)) - .or_else(|| e.downcast_ref::().map(|_| "TypeError")) - .or_else(|| e.downcast_ref::().map(get_ffi_repr_error_class)) - .or_else(|| e.downcast_ref::().map(get_http_error)) - .or_else(|| e.downcast_ref::().map(get_http_next_error)) - .or_else(|| { - e.downcast_ref::() - .map(get_websocket_upgrade_error) - }) - .or_else(|| e.downcast_ref::().map(get_fs_ops_error)) - .or_else(|| { - e.downcast_ref::() - .map(get_ffi_dlfcn_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_ffi_static_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_ffi_callback_error_class) - }) - .or_else(|| e.downcast_ref::().map(get_ffi_call_error_class)) - .or_else(|| e.downcast_ref::().map(get_tls_error_class)) - .or_else(|| e.downcast_ref::().map(get_cron_error_class)) - .or_else(|| e.downcast_ref::().map(get_canvas_error)) - .or_else(|| e.downcast_ref::().map(get_cache_error)) - .or_else(|| e.downcast_ref::().map(get_websocket_error)) - .or_else(|| { - e.downcast_ref::() - .map(get_websocket_handshake_error) - }) - .or_else(|| e.downcast_ref::().map(get_kv_error)) - .or_else(|| e.downcast_ref::().map(get_fetch_error)) - .or_else(|| { - e.downcast_ref::() - .map(get_http_client_create_error) - }) - .or_else(|| e.downcast_ref::().map(get_net_error)) - .or_else(|| { - e.downcast_ref::() - .map(get_net_map_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_broadcast_channel_error) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_webgpu_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_webgpu_buffer_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_webgpu_bundle_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_webgpu_byow_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_webgpu_render_pass_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_webgpu_surface_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_crypto_decrypt_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_crypto_encrypt_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_crypto_shared_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_crypto_ed25519_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_crypto_export_key_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_crypto_generate_key_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_crypto_import_key_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_crypto_x448_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_crypto_x25519_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_crypto_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_webstorage_class_name) - }) - .or_else(|| { - e.downcast_ref::() - .map(|_| "TypeError") - }) - .or_else(|| { - e.downcast_ref::() - .map(get_dlopen_error_class) - }) - .or_else(|| e.downcast_ref::().map(get_hyper_error_class)) - .or_else(|| { - e.downcast_ref::() - .map(get_hyper_util_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_hyper_v014_error_class) - }) - .or_else(|| { - e.downcast_ref::>() - .map(|e| get_hyper_v014_error_class(e)) - }) - .or_else(|| { - e.downcast_ref::().map(|e| { - let io_err: io::Error = e.to_owned().into(); - get_io_error_class(&io_err) - }) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_env_var_error_class) - }) - .or_else(|| e.downcast_ref::().map(get_io_error_class)) - .or_else(|| { - e.downcast_ref::() - .map(get_module_resolution_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_notify_error_class) - }) - .or_else(|| e.downcast_ref::().map(get_regex_error_class)) - .or_else(|| { - e.downcast_ref::() - .map(get_serde_json_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(get_url_parse_error_class) - }) - .or_else(|| { - e.downcast_ref::() - .map(|_| "TypeError") - }) - .or_else(|| { - #[cfg(unix)] - let maybe_get_nix_error_class = - || e.downcast_ref::().map(get_nix_error_class); - #[cfg(not(unix))] - let maybe_get_nix_error_class = || Option::<&'static str>::None; - (maybe_get_nix_error_class)() - }) -} - From dfa4af12b093ac3a504d7fe98004ad7affd1c91a Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Fri, 24 Jan 2025 01:38:32 +0900 Subject: [PATCH 19/24] fix --- ext/geometry/lib.rs | 156 ++++++++++++++++++++++++++------------------ 1 file changed, 92 insertions(+), 64 deletions(-) diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 2a3c12579102f1..4586bfa781586b 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -2,13 +2,14 @@ use std::cell::Cell; use std::cell::RefCell; -use std::cell::UnsafeCell; use std::mem; use std::path::PathBuf; -use std::ptr; use std::slice; +use deno_core::cppgc; +use deno_core::cppgc::SameObject; use deno_core::op2; +use deno_core::v8; use deno_core::webidl; use deno_core::GarbageCollected; use deno_core::WebIDL; @@ -280,12 +281,11 @@ pub struct DOMQuadInit { p4: DOMPointInit, } -#[derive(Debug)] pub struct DOMQuadInner { - p1: UnsafeCell, - p2: UnsafeCell, - p3: UnsafeCell, - p4: UnsafeCell, + p1: SameObject, + p2: SameObject, + p3: SameObject, + p4: SameObject, } impl GarbageCollected for DOMQuadInner {} @@ -296,32 +296,56 @@ impl DOMQuadInner { #[reentrant] #[cppgc] pub fn constructor( + scope: &mut v8::HandleScope, #[webidl] p1: DOMPointInit, #[webidl] p2: DOMPointInit, #[webidl] p3: DOMPointInit, #[webidl] p4: DOMPointInit, ) -> DOMQuadInner { #[inline] - fn from_point(point: DOMPointInit) -> DOMPointInner { - DOMPointInner { + fn from_point( + scope: &mut v8::HandleScope, + point: DOMPointInit, + ) -> SameObject { + let obj = SameObject::new(); + obj.get(scope, |_| DOMPointInner { inner: RefCell::new(Vector4::new( *point.x, *point.y, *point.z, *point.w, )), - } + }); + obj } DOMQuadInner { - p1: UnsafeCell::new(from_point(p1)), - p2: UnsafeCell::new(from_point(p2)), - p3: UnsafeCell::new(from_point(p3)), - p4: UnsafeCell::new(from_point(p4)), + p1: from_point(scope, p1), + p2: from_point(scope, p2), + p3: from_point(scope, p3), + p4: from_point(scope, p4), } } #[reentrant] #[static_method] #[cppgc] - pub fn from_rect(#[webidl] rect: DOMRectInit) -> DOMQuadInner { + pub fn from_rect( + scope: &mut v8::HandleScope, + #[webidl] rect: DOMRectInit, + ) -> DOMQuadInner { + #[inline] + fn create_point( + scope: &mut v8::HandleScope, + x: f64, + y: f64, + z: f64, + w: f64, + ) -> SameObject { + let obj = SameObject::new(); + obj.get(scope, |_| DOMPointInner { + inner: RefCell::new(Vector4::new(x, y, z, w)), + }); + obj + } + let DOMRectInit { x, y, @@ -329,84 +353,88 @@ impl DOMQuadInner { height, } = rect; DOMQuadInner { - p1: UnsafeCell::new(DOMPointInner { - inner: RefCell::new(Vector4::new(*x, *y, 0.0, 1.0)), - }), - p2: UnsafeCell::new(DOMPointInner { - inner: RefCell::new(Vector4::new(*x + *width, *y, 0.0, 1.0)), - }), - p3: UnsafeCell::new(DOMPointInner { - inner: RefCell::new(Vector4::new(*x + *width, *y + *height, 0.0, 1.0)), - }), - p4: UnsafeCell::new(DOMPointInner { - inner: RefCell::new(Vector4::new(*x, *y + *height, 0.0, 1.0)), - }), + p1: create_point(scope, *x, *y, 0.0, 1.0), + p2: create_point(scope, *x + *width, *y, 0.0, 1.0), + p3: create_point(scope, *x + *width, *y + *height, 0.0, 1.0), + p4: create_point(scope, *x, *y + *height, 0.0, 1.0), } } #[reentrant] #[static_method] #[cppgc] - pub fn from_quad(#[webidl] quad: DOMQuadInit) -> DOMQuadInner { + pub fn from_quad( + scope: &mut v8::HandleScope, + #[webidl] quad: DOMQuadInit, + ) -> DOMQuadInner { #[inline] - fn from_point(point: DOMPointInit) -> DOMPointInner { - DOMPointInner { + fn from_point( + scope: &mut v8::HandleScope, + point: DOMPointInit, + ) -> SameObject { + let obj = SameObject::new(); + obj.get(scope, |_| DOMPointInner { inner: RefCell::new(Vector4::new( *point.x, *point.y, *point.z, *point.w, )), - } + }); + obj } DOMQuadInner { - p1: UnsafeCell::new(from_point(quad.p1)), - p2: UnsafeCell::new(from_point(quad.p2)), - p3: UnsafeCell::new(from_point(quad.p3)), - p4: UnsafeCell::new(from_point(quad.p4)), + p1: from_point(scope, quad.p1), + p2: from_point(scope, quad.p2), + p3: from_point(scope, quad.p3), + p4: from_point(scope, quad.p4), } } - #[cppgc] #[getter] - pub fn p1(&self) -> DOMPointInner { - // SAFETY: ptr is alive - unsafe { ptr::read(self.p1.get()) } + #[global] + pub fn p1(&self, scope: &mut v8::HandleScope) -> v8::Global { + self.p1.get(scope, |_| unreachable!()) } - #[cppgc] #[getter] - pub fn p2(&self) -> DOMPointInner { - // SAFETY: ptr is alive - unsafe { ptr::read(self.p2.get()) } + #[global] + pub fn p2(&self, scope: &mut v8::HandleScope) -> v8::Global { + self.p2.get(scope, |_| unreachable!()) } - #[cppgc] #[getter] - pub fn p3(&self) -> DOMPointInner { - // SAFETY: ptr is alive - unsafe { ptr::read(self.p3.get()) } + #[global] + pub fn p3(&self, scope: &mut v8::HandleScope) -> v8::Global { + self.p3.get(scope, |_| unreachable!()) } - #[cppgc] #[getter] - pub fn p4(&self) -> DOMPointInner { - // SAFETY: ptr is alive - unsafe { ptr::read(self.p4.get()) } + #[global] + pub fn p4(&self, scope: &mut v8::HandleScope) -> v8::Global { + self.p4.get(scope, |_| unreachable!()) } #[cppgc] - pub fn get_bounds(&self) -> DOMRectInner { - // SAFETY: ptr is alive - let p1 = unsafe { ptr::read(self.p1.get()) }; - // SAFETY: ptr is alive - let p2 = unsafe { ptr::read(self.p2.get()) }; - // SAFETY: ptr is alive - let p3 = unsafe { ptr::read(self.p3.get()) }; - // SAFETY: ptr is alive - let p4 = unsafe { ptr::read(self.p4.get()) }; - let p1 = p1.inner.borrow(); - let p2 = p2.inner.borrow(); - let p3 = p3.inner.borrow(); - let p4 = p4.inner.borrow(); + pub fn get_bounds(&self, scope: &mut v8::HandleScope) -> DOMRectInner { + let p1 = self.p1.get(scope, |_| unreachable!()); + let p2 = self.p2.get(scope, |_| unreachable!()); + let p3 = self.p3.get(scope, |_| unreachable!()); + let p4 = self.p4.get(scope, |_| unreachable!()); + let p1 = v8::Local::new(scope, p1); + let p2 = v8::Local::new(scope, p2); + let p3 = v8::Local::new(scope, p3); + let p4 = v8::Local::new(scope, p4); + let p1 = cppgc::try_unwrap_cppgc_object::(scope, p1.cast()) + .unwrap(); + let p2 = cppgc::try_unwrap_cppgc_object::(scope, p2.cast()) + .unwrap(); + let p3 = cppgc::try_unwrap_cppgc_object::(scope, p3.cast()) + .unwrap(); + let p4 = cppgc::try_unwrap_cppgc_object::(scope, p4.cast()) + .unwrap(); + let p1 = *p1.inner.borrow(); + let p2 = *p2.inner.borrow(); + let p3 = *p3.inner.borrow(); + let p4 = *p4.inner.borrow(); let left = minimum(minimum(p1.x, p2.x), minimum(p3.x, p4.x)); let top = minimum(minimum(p1.y, p2.y), minimum(p3.y, p4.y)); let right = maximum(maximum(p1.x, p2.x), maximum(p3.x, p4.x)); From 65e579e9cb72b748d57dee411158f6f030c4f43d Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Fri, 24 Jan 2025 01:38:42 +0900 Subject: [PATCH 20/24] update expectation.json --- tests/wpt/runner/expectation.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/wpt/runner/expectation.json b/tests/wpt/runner/expectation.json index 65e1fa8ae2691a..5d1ce692c5030b 100644 --- a/tests/wpt/runner/expectation.json +++ b/tests/wpt/runner/expectation.json @@ -14447,7 +14447,8 @@ "DOMMatrix clone: non-initial values (2d)", "DOMMatrix clone: non-initial values (3d)", "DOMRectList clone" - ] + ], + "DOMMatrix-invertSelf.html": true } } } From a37d7692125f3b9ce8db065ddac967acf28c249f Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Fri, 24 Jan 2025 01:58:01 +0900 Subject: [PATCH 21/24] fix --- tests/integration/lsp_tests.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/integration/lsp_tests.rs b/tests/integration/lsp_tests.rs index 196184f3e08d91..0df43e81294965 100644 --- a/tests/integration/lsp_tests.rs +++ b/tests/integration/lsp_tests.rs @@ -5762,7 +5762,7 @@ fn lsp_jsr_auto_import_completion() { json!({ "triggerKind": 1 }), ); assert!(!list.is_incomplete); - assert_eq!(list.items.len(), 268); + assert_eq!(list.items.len(), 275); let item = list.items.iter().find(|i| i.label == "add").unwrap(); assert_eq!(&item.label, "add"); assert_eq!( @@ -5842,7 +5842,7 @@ fn lsp_jsr_auto_import_completion_import_map() { json!({ "triggerKind": 1 }), ); assert!(!list.is_incomplete); - assert_eq!(list.items.len(), 268); + assert_eq!(list.items.len(), 275); let item = list.items.iter().find(|i| i.label == "add").unwrap(); assert_eq!(&item.label, "add"); assert_eq!(json!(&item.label_details), json!({ "description": "add" })); From 15613a3d5b06e86782a950e8d1675824516ce243 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Fri, 24 Jan 2025 02:07:10 +0900 Subject: [PATCH 22/24] tweak --- tests/wpt/runner/expectation.json | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/wpt/runner/expectation.json b/tests/wpt/runner/expectation.json index 5d1ce692c5030b..fe39ee5a36b3b0 100644 --- a/tests/wpt/runner/expectation.json +++ b/tests/wpt/runner/expectation.json @@ -14239,6 +14239,7 @@ "eventsource-constructor-stringify.window.html": false, "eventsource-cross-origin.window.html": false, "eventsource-reconnect.window.html": false, + "request-status-error.window.html": false, "eventsource-constructor-empty-url.any.serviceworker.html": false, "eventsource-constructor-empty-url.any.sharedworker.html": false, "eventsource-constructor-url-bogus.any.serviceworker.html": false, From 5a5bea6005d5e896d932089156b0d238ae6e1463 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Fri, 24 Jan 2025 14:11:43 +0900 Subject: [PATCH 23/24] remove LSP global symbols count tests --- tests/integration/lsp_tests.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/integration/lsp_tests.rs b/tests/integration/lsp_tests.rs index 0df43e81294965..d3944581807dc1 100644 --- a/tests/integration/lsp_tests.rs +++ b/tests/integration/lsp_tests.rs @@ -5762,7 +5762,6 @@ fn lsp_jsr_auto_import_completion() { json!({ "triggerKind": 1 }), ); assert!(!list.is_incomplete); - assert_eq!(list.items.len(), 275); let item = list.items.iter().find(|i| i.label == "add").unwrap(); assert_eq!(&item.label, "add"); assert_eq!( @@ -5842,7 +5841,6 @@ fn lsp_jsr_auto_import_completion_import_map() { json!({ "triggerKind": 1 }), ); assert!(!list.is_incomplete); - assert_eq!(list.items.len(), 275); let item = list.items.iter().find(|i| i.label == "add").unwrap(); assert_eq!(&item.label, "add"); assert_eq!(json!(&item.label_details), json!({ "description": "add" })); From cd5927246f506d579783f65e520424a90a3a6787 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Fri, 24 Jan 2025 14:37:32 +0900 Subject: [PATCH 24/24] refactor --- ext/geometry/lib.rs | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/ext/geometry/lib.rs b/ext/geometry/lib.rs index 4586bfa781586b..b12b9a24a502ca 100644 --- a/ext/geometry/lib.rs +++ b/ext/geometry/lib.rs @@ -415,22 +415,21 @@ impl DOMQuadInner { #[cppgc] pub fn get_bounds(&self, scope: &mut v8::HandleScope) -> DOMRectInner { - let p1 = self.p1.get(scope, |_| unreachable!()); - let p2 = self.p2.get(scope, |_| unreachable!()); - let p3 = self.p3.get(scope, |_| unreachable!()); - let p4 = self.p4.get(scope, |_| unreachable!()); - let p1 = v8::Local::new(scope, p1); - let p2 = v8::Local::new(scope, p2); - let p3 = v8::Local::new(scope, p3); - let p4 = v8::Local::new(scope, p4); - let p1 = cppgc::try_unwrap_cppgc_object::(scope, p1.cast()) - .unwrap(); - let p2 = cppgc::try_unwrap_cppgc_object::(scope, p2.cast()) - .unwrap(); - let p3 = cppgc::try_unwrap_cppgc_object::(scope, p3.cast()) - .unwrap(); - let p4 = cppgc::try_unwrap_cppgc_object::(scope, p4.cast()) - .unwrap(); + #[inline] + fn get_ptr( + scope: &mut v8::HandleScope, + value: &SameObject, + ) -> cppgc::Ptr { + let value = value.get(scope, |_| unreachable!()); + let value = v8::Local::new(scope, value); + cppgc::try_unwrap_cppgc_object::(scope, value.cast()) + .unwrap() + } + + let p1 = get_ptr(scope, &self.p1); + let p2 = get_ptr(scope, &self.p2); + let p3 = get_ptr(scope, &self.p3); + let p4 = get_ptr(scope, &self.p4); let p1 = *p1.inner.borrow(); let p2 = *p2.inner.borrow(); let p3 = *p3.inner.borrow();