diff --git a/crates/cli-support/src/js/mod.rs b/crates/cli-support/src/js/mod.rs index 3ba5be3a719..1f2eae6f94b 100644 --- a/crates/cli-support/src/js/mod.rs +++ b/crates/cli-support/src/js/mod.rs @@ -1714,10 +1714,10 @@ __wbg_set_wasm(wasm);" if !self.should_write_global("text_encoder") { return Ok(()); } - self.expose_text_processor("TextEncoder", "encode", "('utf-8')", None) + self.expose_text_processor("const", "TextEncoder", "encode", "('utf-8')", None) } - fn expose_text_decoder(&mut self) -> Result<(), Error> { + fn expose_text_decoder(&mut self, mem: &MemView, memory: MemoryId) -> Result<(), Error> { if !self.should_write_global("text_decoder") { return Ok(()); } @@ -1729,32 +1729,82 @@ __wbg_set_wasm(wasm);" // `ignoreBOM` is needed so that the BOM will be preserved when sending a string from Rust to JS // `fatal` is needed to catch any weird encoding bugs when sending a string from Rust to JS self.expose_text_processor( + "let", "TextDecoder", "decode", "('utf-8', { ignoreBOM: true, fatal: true })", init, )?; + let text_decoder_decode = self.generate_text_decoder_decode(mem, memory)?; + match &self.config.mode { + OutputMode::Bundler { .. } | OutputMode::Web => { + // For targets that can run in a browser, we need a workaround for the fact that + // (at least) Safari 16 to 18 has a TextDecoder that can't decode anymore after + // processing 2GiB of data. The workaround is that we keep track of how much the + // decoder has decoded and just create a new decoder when we're getting close to + // the limit. + // See MAX_SAFARI_DECODE_BYTES below for link to bug report. + + let cached_text_processor = self.generate_cached_text_processor_init( + "TextDecoder", + "decode", + "('utf-8', { ignoreBOM: true, fatal: true })", + )?; + + // Maximum number of bytes Safari can handle for one TextDecoder is 2GiB (2147483648) + // but empirically it seems to crash a bit before the end, so we remove 1MiB of margin. + // Workaround for a bug in Safari. + // See https://github.com/rustwasm/wasm-bindgen/issues/4471 + const MAX_SAFARI_DECODE_BYTES: u32 = 2147483648 - 1048576; + self.global(&format!( + " + const MAX_SAFARI_DECODE_BYTES = {0}; + let numBytesDecoded = 0; + function decodeText(ptr, len) {{ + numBytesDecoded += len; + if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) {{ + {1} + cachedTextDecoder.decode(); + numBytesDecoded = len; + }} + return {2}; + }} + ", + MAX_SAFARI_DECODE_BYTES, cached_text_processor, text_decoder_decode, + )); + } + _ => { + // For any non-browser target, we can just use the TextDecoder without any workarounds. + // For browser-targets, see the workaround for Safari above. + self.global(&format!( + " + function decodeText(ptr, len) {{ + return {}; + }} + ", + text_decoder_decode, + )); + } + } + Ok(()) } fn expose_text_processor( &mut self, + decl_kind: &str, s: &str, op: &str, args: &str, init: Option<&str>, ) -> Result<(), Error> { + let cached_text_processor_init = self.generate_cached_text_processor_init(s, op, args)?; match &self.config.mode { OutputMode::Node { .. } => { - let name = self.import_name(&JsImport { - name: JsImportName::Module { - module: "util".to_string(), - name: s.to_string(), - }, - fields: Vec::new(), - })?; - self.global(&format!("let cached{} = new {}{};", s, name, args)); + // decl_kind is the kind of the kind of the declaration: let or const + // cached_text_processor_init is the rest of the statement for initializing a cached text processor + self.global(&format!("{} {}", decl_kind, cached_text_processor_init)); } OutputMode::Bundler { browser_only: false, @@ -1766,13 +1816,15 @@ __wbg_set_wasm(wasm);" ", s )); - self.global(&format!("let cached{0} = new l{0}{1};", s, args)); + self.global(&format!("{} {}", decl_kind, cached_text_processor_init)); } OutputMode::Deno | OutputMode::Web | OutputMode::NoModules { .. } | OutputMode::Bundler { browser_only: true } => { - self.global(&format!("const cached{0} = (typeof {0} !== 'undefined' ? new {0}{1} : {{ {2}: () => {{ throw Error('{0} not available') }} }} );", s, args, op)) + // decl_kind is the kind of the kind of the declaration: let or const + // cached_text_processor_init is the rest of the statement for initializing a cached text processor + self.global(&format!("{} {}", decl_kind, cached_text_processor_init)) } }; @@ -1795,9 +1847,43 @@ __wbg_set_wasm(wasm);" Ok(()) } + /// Generates a partial text processor statement, everything except the declaration kind, + /// i.e. everything except for `const` or `let` which the caller needs to handle itself. + fn generate_cached_text_processor_init( + &mut self, + s: &str, + op: &str, + args: &str, + ) -> Result { + let new_cached_text_procesor = match &self.config.mode { + OutputMode::Node { .. } => { + let name = self.import_name(&JsImport { + name: JsImportName::Module { + module: "util".to_string(), + name: s.to_string(), + }, + fields: Vec::new(), + })?; + format!("cached{} = new {}{};", s, name, args) + } + OutputMode::Bundler { + browser_only: false, + } => { + format!("cached{0} = new l{0}{1};", s, args) + } + OutputMode::Deno + | OutputMode::Web + | OutputMode::NoModules { .. } + | OutputMode::Bundler { browser_only: true } => { + format!("cached{0} = (typeof {0} !== 'undefined' ? new {0}{1} : {{ {2}: () => {{ throw Error('{0} not available') }} }} );", s, args, op) + } + }; + Ok(new_cached_text_procesor) + } + fn expose_get_string_from_wasm(&mut self, memory: MemoryId) -> Result { - self.expose_text_decoder()?; let mem = self.expose_uint8_memory(memory); + self.expose_text_decoder(&mem, memory)?; let ret = MemView { name: "getStringFromWasm".into(), num: mem.num, @@ -1807,6 +1893,23 @@ __wbg_set_wasm(wasm);" return Ok(ret); } + self.global(&format!( + " + function {}(ptr, len) {{ + ptr = ptr >>> 0; + return decodeText(ptr, len); + }} + ", + ret, + )); + Ok(ret) + } + + fn generate_text_decoder_decode( + &self, + mem: &MemView, + memory: MemoryId, + ) -> Result { // Typically we try to give a raw view of memory out to `TextDecoder` to // avoid copying too much data. If, however, a `SharedArrayBuffer` is // being used it looks like that is rejected by `TextDecoder` or @@ -1818,16 +1921,10 @@ __wbg_set_wasm(wasm);" let is_shared = self.module.memories.get(memory).shared; let method = if is_shared { "slice" } else { "subarray" }; - self.global(&format!( - " - function {}(ptr, len) {{ - ptr = ptr >>> 0; - return cachedTextDecoder.decode({}().{}(ptr, ptr + len)); - }} - ", - ret, mem, method - )); - Ok(ret) + Ok(format!( + "cachedTextDecoder.decode({}().{}(ptr, ptr + len))", + mem, method + )) } fn expose_get_cached_string_from_wasm( diff --git a/crates/cli/tests/reference/anyref-import-catch.js b/crates/cli/tests/reference/anyref-import-catch.js index 97101e26dba..5d40e08aaee 100644 --- a/crates/cli/tests/reference/anyref-import-catch.js +++ b/crates/cli/tests/reference/anyref-import-catch.js @@ -19,12 +19,6 @@ function handleError(f, args) { } } -const lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder; - -let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); - -cachedTextDecoder.decode(); - let cachedUint8ArrayMemory0 = null; function getUint8ArrayMemory0() { @@ -34,9 +28,27 @@ function getUint8ArrayMemory0() { return cachedUint8ArrayMemory0; } +const lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder; + +let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); + +cachedTextDecoder.decode(); + +const MAX_SAFARI_DECODE_BYTES = 2146435072; +let numBytesDecoded = 0; +function decodeText(ptr, len) { + numBytesDecoded += len; + if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) { + cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); + cachedTextDecoder.decode(); + numBytesDecoded = len; + } + return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); +} + function getStringFromWasm0(ptr, len) { ptr = ptr >>> 0; - return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); + return decodeText(ptr, len); } function takeFromExternrefTable0(idx) { diff --git a/crates/cli/tests/reference/builder.js b/crates/cli/tests/reference/builder.js index b63d64f2f5b..22d94a4a7aa 100644 --- a/crates/cli/tests/reference/builder.js +++ b/crates/cli/tests/reference/builder.js @@ -4,12 +4,6 @@ export function __wbg_set_wasm(val) { } -const lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder; - -let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); - -cachedTextDecoder.decode(); - let cachedUint8ArrayMemory0 = null; function getUint8ArrayMemory0() { @@ -19,9 +13,27 @@ function getUint8ArrayMemory0() { return cachedUint8ArrayMemory0; } +const lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder; + +let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); + +cachedTextDecoder.decode(); + +const MAX_SAFARI_DECODE_BYTES = 2146435072; +let numBytesDecoded = 0; +function decodeText(ptr, len) { + numBytesDecoded += len; + if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) { + cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); + cachedTextDecoder.decode(); + numBytesDecoded = len; + } + return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); +} + function getStringFromWasm0(ptr, len) { ptr = ptr >>> 0; - return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); + return decodeText(ptr, len); } const ClassBuilderFinalization = (typeof FinalizationRegistry === 'undefined') diff --git a/crates/cli/tests/reference/constructor.js b/crates/cli/tests/reference/constructor.js index c0a781c3c94..386aebdc2e0 100644 --- a/crates/cli/tests/reference/constructor.js +++ b/crates/cli/tests/reference/constructor.js @@ -4,12 +4,6 @@ export function __wbg_set_wasm(val) { } -const lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder; - -let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); - -cachedTextDecoder.decode(); - let cachedUint8ArrayMemory0 = null; function getUint8ArrayMemory0() { @@ -19,9 +13,27 @@ function getUint8ArrayMemory0() { return cachedUint8ArrayMemory0; } +const lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder; + +let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); + +cachedTextDecoder.decode(); + +const MAX_SAFARI_DECODE_BYTES = 2146435072; +let numBytesDecoded = 0; +function decodeText(ptr, len) { + numBytesDecoded += len; + if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) { + cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); + cachedTextDecoder.decode(); + numBytesDecoded = len; + } + return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); +} + function getStringFromWasm0(ptr, len) { ptr = ptr >>> 0; - return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); + return decodeText(ptr, len); } const ClassConstructorFinalization = (typeof FinalizationRegistry === 'undefined') diff --git a/crates/cli/tests/reference/echo.js b/crates/cli/tests/reference/echo.js index c786581f554..d4bd41c34cd 100644 --- a/crates/cli/tests/reference/echo.js +++ b/crates/cli/tests/reference/echo.js @@ -82,7 +82,7 @@ function getUint8ArrayMemory0() { const lTextEncoder = typeof TextEncoder === 'undefined' ? (0, module.require)('util').TextEncoder : TextEncoder; -let cachedTextEncoder = new lTextEncoder('utf-8'); +const cachedTextEncoder = new lTextEncoder('utf-8'); const encodeString = (typeof cachedTextEncoder.encodeInto === 'function' ? function (arg, view) { @@ -155,9 +155,21 @@ let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true cachedTextDecoder.decode(); +const MAX_SAFARI_DECODE_BYTES = 2146435072; +let numBytesDecoded = 0; +function decodeText(ptr, len) { + numBytesDecoded += len; + if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) { + cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); + cachedTextDecoder.decode(); + numBytesDecoded = len; + } + return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); +} + function getStringFromWasm0(ptr, len) { ptr = ptr >>> 0; - return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); + return decodeText(ptr, len); } /** * @param {number} a diff --git a/crates/cli/tests/reference/enums.js b/crates/cli/tests/reference/enums.js index 10d698dc7e5..681568524c6 100644 --- a/crates/cli/tests/reference/enums.js +++ b/crates/cli/tests/reference/enums.js @@ -4,12 +4,6 @@ export function __wbg_set_wasm(val) { } -const lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder; - -let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); - -cachedTextDecoder.decode(); - let cachedUint8ArrayMemory0 = null; function getUint8ArrayMemory0() { @@ -19,9 +13,27 @@ function getUint8ArrayMemory0() { return cachedUint8ArrayMemory0; } +const lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder; + +let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); + +cachedTextDecoder.decode(); + +const MAX_SAFARI_DECODE_BYTES = 2146435072; +let numBytesDecoded = 0; +function decodeText(ptr, len) { + numBytesDecoded += len; + if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) { + cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); + cachedTextDecoder.decode(); + numBytesDecoded = len; + } + return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); +} + function getStringFromWasm0(ptr, len) { ptr = ptr >>> 0; - return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); + return decodeText(ptr, len); } /** * @param {Color} color diff --git a/crates/cli/tests/reference/getter-setter.js b/crates/cli/tests/reference/getter-setter.js index a9df5536a5b..27ac91ca49e 100644 --- a/crates/cli/tests/reference/getter-setter.js +++ b/crates/cli/tests/reference/getter-setter.js @@ -4,12 +4,6 @@ export function __wbg_set_wasm(val) { } -const lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder; - -let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); - -cachedTextDecoder.decode(); - let cachedUint8ArrayMemory0 = null; function getUint8ArrayMemory0() { @@ -19,9 +13,27 @@ function getUint8ArrayMemory0() { return cachedUint8ArrayMemory0; } +const lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder; + +let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); + +cachedTextDecoder.decode(); + +const MAX_SAFARI_DECODE_BYTES = 2146435072; +let numBytesDecoded = 0; +function decodeText(ptr, len) { + numBytesDecoded += len; + if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) { + cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); + cachedTextDecoder.decode(); + numBytesDecoded = len; + } + return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); +} + function getStringFromWasm0(ptr, len) { ptr = ptr >>> 0; - return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); + return decodeText(ptr, len); } function isLikeNone(x) { @@ -32,7 +44,7 @@ let WASM_VECTOR_LEN = 0; const lTextEncoder = typeof TextEncoder === 'undefined' ? (0, module.require)('util').TextEncoder : TextEncoder; -let cachedTextEncoder = new lTextEncoder('utf-8'); +const cachedTextEncoder = new lTextEncoder('utf-8'); const encodeString = (typeof cachedTextEncoder.encodeInto === 'function' ? function (arg, view) { diff --git a/crates/cli/tests/reference/getter-setter.wat b/crates/cli/tests/reference/getter-setter.wat index 7834c0fccf8..47036eab44f 100644 --- a/crates/cli/tests/reference/getter-setter.wat +++ b/crates/cli/tests/reference/getter-setter.wat @@ -11,16 +11,16 @@ (type (;9;) (func (param i32 f64))) (import "./reference_test_bg.js" "__wbindgen_init_externref_table" (func (;0;) (type 0))) (func $__wbindgen_realloc (;1;) (type 8) (param i32 i32 i32 i32) (result i32)) - (func $__wbindgen_malloc (;2;) (type 6) (param i32 i32) (result i32)) - (func $foo_set_weird (;3;) (type 7) (param i32 i32 i32)) - (func $__wbg_set_foo_y (;4;) (type 9) (param i32 f64)) - (func $__wbg_get_foo_y (;5;) (type 4) (param i32) (result f64)) - (func $__wbg_get_foo_x (;6;) (type 3) (param i32) (result i32)) - (func $foo_set_z (;7;) (type 9) (param i32 f64)) - (func $foo_set_lone_setter (;8;) (type 9) (param i32 f64)) - (func $foo_z (;9;) (type 4) (param i32) (result f64)) - (func $foo_lone_getter (;10;) (type 4) (param i32) (result f64)) - (func $__wbg_set_foo_x (;11;) (type 5) (param i32 i32)) + (func $__wbg_set_foo_y (;2;) (type 9) (param i32 f64)) + (func $__wbindgen_malloc (;3;) (type 6) (param i32 i32) (result i32)) + (func $__wbg_get_foo_y (;4;) (type 4) (param i32) (result f64)) + (func $__wbg_get_foo_x (;5;) (type 3) (param i32) (result i32)) + (func $__wbg_set_foo_x (;6;) (type 5) (param i32 i32)) + (func $foo_set_weird (;7;) (type 7) (param i32 i32 i32)) + (func $foo_set_z (;8;) (type 9) (param i32 f64)) + (func $foo_set_lone_setter (;9;) (type 9) (param i32 f64)) + (func $foo_z (;10;) (type 4) (param i32) (result f64)) + (func $foo_lone_getter (;11;) (type 4) (param i32) (result f64)) (func $foo_weird (;12;) (type 3) (param i32) (result i32)) (func $foo_x_static (;13;) (type 1) (result i32)) (func $__wbg_foo_free (;14;) (type 5) (param i32 i32)) diff --git a/crates/cli/tests/reference/import-getter-setter.js b/crates/cli/tests/reference/import-getter-setter.js index adaca3bab4d..570fd5f6f80 100644 --- a/crates/cli/tests/reference/import-getter-setter.js +++ b/crates/cli/tests/reference/import-getter-setter.js @@ -4,12 +4,6 @@ export function __wbg_set_wasm(val) { } -const lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder; - -let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); - -cachedTextDecoder.decode(); - let cachedUint8ArrayMemory0 = null; function getUint8ArrayMemory0() { @@ -19,9 +13,27 @@ function getUint8ArrayMemory0() { return cachedUint8ArrayMemory0; } +const lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder; + +let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); + +cachedTextDecoder.decode(); + +const MAX_SAFARI_DECODE_BYTES = 2146435072; +let numBytesDecoded = 0; +function decodeText(ptr, len) { + numBytesDecoded += len; + if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) { + cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); + cachedTextDecoder.decode(); + numBytesDecoded = len; + } + return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); +} + function getStringFromWasm0(ptr, len) { ptr = ptr >>> 0; - return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); + return decodeText(ptr, len); } export function exported() { diff --git a/crates/cli/tests/reference/import.js b/crates/cli/tests/reference/import.js index 5fd514c7295..5f1bbf7c4fa 100644 --- a/crates/cli/tests/reference/import.js +++ b/crates/cli/tests/reference/import.js @@ -21,12 +21,6 @@ function handleError(f, args) { } } -const lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder; - -let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); - -cachedTextDecoder.decode(); - let cachedUint8ArrayMemory0 = null; function getUint8ArrayMemory0() { @@ -36,9 +30,27 @@ function getUint8ArrayMemory0() { return cachedUint8ArrayMemory0; } +const lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder; + +let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); + +cachedTextDecoder.decode(); + +const MAX_SAFARI_DECODE_BYTES = 2146435072; +let numBytesDecoded = 0; +function decodeText(ptr, len) { + numBytesDecoded += len; + if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) { + cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); + cachedTextDecoder.decode(); + numBytesDecoded = len; + } + return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); +} + function getStringFromWasm0(ptr, len) { ptr = ptr >>> 0; - return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); + return decodeText(ptr, len); } function takeFromExternrefTable0(idx) { diff --git a/crates/cli/tests/reference/int128.js b/crates/cli/tests/reference/int128.js index 32de778621c..924d1145893 100644 --- a/crates/cli/tests/reference/int128.js +++ b/crates/cli/tests/reference/int128.js @@ -4,12 +4,6 @@ export function __wbg_set_wasm(val) { } -const lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder; - -let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); - -cachedTextDecoder.decode(); - let cachedUint8ArrayMemory0 = null; function getUint8ArrayMemory0() { @@ -19,9 +13,27 @@ function getUint8ArrayMemory0() { return cachedUint8ArrayMemory0; } +const lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder; + +let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); + +cachedTextDecoder.decode(); + +const MAX_SAFARI_DECODE_BYTES = 2146435072; +let numBytesDecoded = 0; +function decodeText(ptr, len) { + numBytesDecoded += len; + if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) { + cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); + cachedTextDecoder.decode(); + numBytesDecoded = len; + } + return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); +} + function getStringFromWasm0(ptr, len) { ptr = ptr >>> 0; - return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); + return decodeText(ptr, len); } /** * @param {bigint} a diff --git a/crates/cli/tests/reference/intrinsic-only.js b/crates/cli/tests/reference/intrinsic-only.js index 26525348f80..da958103915 100644 --- a/crates/cli/tests/reference/intrinsic-only.js +++ b/crates/cli/tests/reference/intrinsic-only.js @@ -4,12 +4,6 @@ export function __wbg_set_wasm(val) { } -const lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder; - -let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); - -cachedTextDecoder.decode(); - let cachedUint8ArrayMemory0 = null; function getUint8ArrayMemory0() { @@ -19,9 +13,27 @@ function getUint8ArrayMemory0() { return cachedUint8ArrayMemory0; } +const lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder; + +let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); + +cachedTextDecoder.decode(); + +const MAX_SAFARI_DECODE_BYTES = 2146435072; +let numBytesDecoded = 0; +function decodeText(ptr, len) { + numBytesDecoded += len; + if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) { + cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); + cachedTextDecoder.decode(); + numBytesDecoded = len; + } + return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); +} + function getStringFromWasm0(ptr, len) { ptr = ptr >>> 0; - return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); + return decodeText(ptr, len); } function takeFromExternrefTable0(idx) { diff --git a/crates/cli/tests/reference/keyword.js b/crates/cli/tests/reference/keyword.js index bfda76214e4..9fcb97bb7d6 100644 --- a/crates/cli/tests/reference/keyword.js +++ b/crates/cli/tests/reference/keyword.js @@ -4,12 +4,6 @@ export function __wbg_set_wasm(val) { } -const lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder; - -let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); - -cachedTextDecoder.decode(); - let cachedUint8ArrayMemory0 = null; function getUint8ArrayMemory0() { @@ -19,9 +13,27 @@ function getUint8ArrayMemory0() { return cachedUint8ArrayMemory0; } +const lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder; + +let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); + +cachedTextDecoder.decode(); + +const MAX_SAFARI_DECODE_BYTES = 2146435072; +let numBytesDecoded = 0; +function decodeText(ptr, len) { + numBytesDecoded += len; + if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) { + cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); + cachedTextDecoder.decode(); + numBytesDecoded = len; + } + return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); +} + function getStringFromWasm0(ptr, len) { ptr = ptr >>> 0; - return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); + return decodeText(ptr, len); } export function exported() { diff --git a/crates/cli/tests/reference/modules.js b/crates/cli/tests/reference/modules.js index ed323e4f0a9..9b1a3e458a8 100644 --- a/crates/cli/tests/reference/modules.js +++ b/crates/cli/tests/reference/modules.js @@ -4,12 +4,6 @@ export function __wbg_set_wasm(val) { } -const lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder; - -let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); - -cachedTextDecoder.decode(); - let cachedUint8ArrayMemory0 = null; function getUint8ArrayMemory0() { @@ -19,9 +13,27 @@ function getUint8ArrayMemory0() { return cachedUint8ArrayMemory0; } +const lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder; + +let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); + +cachedTextDecoder.decode(); + +const MAX_SAFARI_DECODE_BYTES = 2146435072; +let numBytesDecoded = 0; +function decodeText(ptr, len) { + numBytesDecoded += len; + if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) { + cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); + cachedTextDecoder.decode(); + numBytesDecoded = len; + } + return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); +} + function getStringFromWasm0(ptr, len) { ptr = ptr >>> 0; - return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); + return decodeText(ptr, len); } export function exported() { diff --git a/crates/cli/tests/reference/raw.js b/crates/cli/tests/reference/raw.js index 4e9035bbf26..7e6953bb65f 100644 --- a/crates/cli/tests/reference/raw.js +++ b/crates/cli/tests/reference/raw.js @@ -4,12 +4,6 @@ export function __wbg_set_wasm(val) { } -const lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder; - -let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); - -cachedTextDecoder.decode(); - let cachedUint8ArrayMemory0 = null; function getUint8ArrayMemory0() { @@ -19,9 +13,27 @@ function getUint8ArrayMemory0() { return cachedUint8ArrayMemory0; } +const lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder; + +let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); + +cachedTextDecoder.decode(); + +const MAX_SAFARI_DECODE_BYTES = 2146435072; +let numBytesDecoded = 0; +function decodeText(ptr, len) { + numBytesDecoded += len; + if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) { + cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); + cachedTextDecoder.decode(); + numBytesDecoded = len; + } + return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); +} + function getStringFromWasm0(ptr, len) { ptr = ptr >>> 0; - return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); + return decodeText(ptr, len); } /** * @param {number} test diff --git a/crates/cli/tests/reference/result.js b/crates/cli/tests/reference/result.js index ddc18ed8148..10dbe5296e0 100644 --- a/crates/cli/tests/reference/result.js +++ b/crates/cli/tests/reference/result.js @@ -4,12 +4,6 @@ export function __wbg_set_wasm(val) { } -const lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder; - -let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); - -cachedTextDecoder.decode(); - let cachedUint8ArrayMemory0 = null; function getUint8ArrayMemory0() { @@ -19,9 +13,27 @@ function getUint8ArrayMemory0() { return cachedUint8ArrayMemory0; } +const lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder; + +let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); + +cachedTextDecoder.decode(); + +const MAX_SAFARI_DECODE_BYTES = 2146435072; +let numBytesDecoded = 0; +function decodeText(ptr, len) { + numBytesDecoded += len; + if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) { + cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); + cachedTextDecoder.decode(); + numBytesDecoded = len; + } + return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); +} + function getStringFromWasm0(ptr, len) { ptr = ptr >>> 0; - return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); + return decodeText(ptr, len); } function takeFromExternrefTable0(idx) { diff --git a/crates/cli/tests/reference/self-type.js b/crates/cli/tests/reference/self-type.js index 57075362366..4dd3c57d908 100644 --- a/crates/cli/tests/reference/self-type.js +++ b/crates/cli/tests/reference/self-type.js @@ -4,12 +4,6 @@ export function __wbg_set_wasm(val) { } -const lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder; - -let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); - -cachedTextDecoder.decode(); - let cachedUint8ArrayMemory0 = null; function getUint8ArrayMemory0() { @@ -19,9 +13,27 @@ function getUint8ArrayMemory0() { return cachedUint8ArrayMemory0; } +const lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder; + +let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); + +cachedTextDecoder.decode(); + +const MAX_SAFARI_DECODE_BYTES = 2146435072; +let numBytesDecoded = 0; +function decodeText(ptr, len) { + numBytesDecoded += len; + if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) { + cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); + cachedTextDecoder.decode(); + numBytesDecoded = len; + } + return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); +} + function getStringFromWasm0(ptr, len) { ptr = ptr >>> 0; - return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); + return decodeText(ptr, len); } const TestFinalization = (typeof FinalizationRegistry === 'undefined') diff --git a/crates/cli/tests/reference/static.js b/crates/cli/tests/reference/static.js index 34aa7975e7a..b6359d49a78 100644 --- a/crates/cli/tests/reference/static.js +++ b/crates/cli/tests/reference/static.js @@ -14,12 +14,6 @@ function addToExternrefTable0(obj) { return idx; } -const lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder; - -let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); - -cachedTextDecoder.decode(); - let cachedUint8ArrayMemory0 = null; function getUint8ArrayMemory0() { @@ -29,9 +23,27 @@ function getUint8ArrayMemory0() { return cachedUint8ArrayMemory0; } +const lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder; + +let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); + +cachedTextDecoder.decode(); + +const MAX_SAFARI_DECODE_BYTES = 2146435072; +let numBytesDecoded = 0; +function decodeText(ptr, len) { + numBytesDecoded += len; + if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) { + cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); + cachedTextDecoder.decode(); + numBytesDecoded = len; + } + return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); +} + function getStringFromWasm0(ptr, len) { ptr = ptr >>> 0; - return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); + return decodeText(ptr, len); } export function exported() { diff --git a/crates/cli/tests/reference/string-arg.js b/crates/cli/tests/reference/string-arg.js index 9d52328a50f..f5880089464 100644 --- a/crates/cli/tests/reference/string-arg.js +++ b/crates/cli/tests/reference/string-arg.js @@ -4,12 +4,6 @@ export function __wbg_set_wasm(val) { } -const lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder; - -let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); - -cachedTextDecoder.decode(); - let cachedUint8ArrayMemory0 = null; function getUint8ArrayMemory0() { @@ -19,16 +13,34 @@ function getUint8ArrayMemory0() { return cachedUint8ArrayMemory0; } +const lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder; + +let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); + +cachedTextDecoder.decode(); + +const MAX_SAFARI_DECODE_BYTES = 2146435072; +let numBytesDecoded = 0; +function decodeText(ptr, len) { + numBytesDecoded += len; + if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) { + cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); + cachedTextDecoder.decode(); + numBytesDecoded = len; + } + return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); +} + function getStringFromWasm0(ptr, len) { ptr = ptr >>> 0; - return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); + return decodeText(ptr, len); } let WASM_VECTOR_LEN = 0; const lTextEncoder = typeof TextEncoder === 'undefined' ? (0, module.require)('util').TextEncoder : TextEncoder; -let cachedTextEncoder = new lTextEncoder('utf-8'); +const cachedTextEncoder = new lTextEncoder('utf-8'); const encodeString = (typeof cachedTextEncoder.encodeInto === 'function' ? function (arg, view) { diff --git a/crates/cli/tests/reference/typescript-type.js b/crates/cli/tests/reference/typescript-type.js index 0f861886fcf..d2b9f8d22b1 100644 --- a/crates/cli/tests/reference/typescript-type.js +++ b/crates/cli/tests/reference/typescript-type.js @@ -4,12 +4,6 @@ export function __wbg_set_wasm(val) { } -const lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder; - -let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); - -cachedTextDecoder.decode(); - let cachedUint8ArrayMemory0 = null; function getUint8ArrayMemory0() { @@ -19,9 +13,27 @@ function getUint8ArrayMemory0() { return cachedUint8ArrayMemory0; } +const lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder; + +let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); + +cachedTextDecoder.decode(); + +const MAX_SAFARI_DECODE_BYTES = 2146435072; +let numBytesDecoded = 0; +function decodeText(ptr, len) { + numBytesDecoded += len; + if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) { + cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); + cachedTextDecoder.decode(); + numBytesDecoded = len; + } + return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); +} + function getStringFromWasm0(ptr, len) { ptr = ptr >>> 0; - return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); + return decodeText(ptr, len); } /** * @param {number | string} a diff --git a/crates/cli/tests/reference/wasm-export-types.js b/crates/cli/tests/reference/wasm-export-types.js index de290e90502..83850ccf666 100644 --- a/crates/cli/tests/reference/wasm-export-types.js +++ b/crates/cli/tests/reference/wasm-export-types.js @@ -1,9 +1,5 @@ let wasm; -const cachedTextDecoder = (typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }) : { decode: () => { throw Error('TextDecoder not available') } } ); - -if (typeof TextDecoder !== 'undefined') { cachedTextDecoder.decode(); }; - let cachedUint8ArrayMemory0 = null; function getUint8ArrayMemory0() { @@ -13,9 +9,25 @@ function getUint8ArrayMemory0() { return cachedUint8ArrayMemory0; } +let cachedTextDecoder = (typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }) : { decode: () => { throw Error('TextDecoder not available') } } ); + +if (typeof TextDecoder !== 'undefined') { cachedTextDecoder.decode(); }; + +const MAX_SAFARI_DECODE_BYTES = 2146435072; +let numBytesDecoded = 0; +function decodeText(ptr, len) { + numBytesDecoded += len; + if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) { + cachedTextDecoder = (typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }) : { decode: () => { throw Error('TextDecoder not available') } } ); + cachedTextDecoder.decode(); + numBytesDecoded = len; + } + return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); +} + function getStringFromWasm0(ptr, len) { ptr = ptr >>> 0; - return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); + return decodeText(ptr, len); } let WASM_VECTOR_LEN = 0; diff --git a/crates/cli/tests/reference/web-sys.js b/crates/cli/tests/reference/web-sys.js index 37300cfdcaa..8daef035103 100644 --- a/crates/cli/tests/reference/web-sys.js +++ b/crates/cli/tests/reference/web-sys.js @@ -4,12 +4,6 @@ export function __wbg_set_wasm(val) { } -const lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder; - -let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); - -cachedTextDecoder.decode(); - let cachedUint8ArrayMemory0 = null; function getUint8ArrayMemory0() { @@ -19,9 +13,27 @@ function getUint8ArrayMemory0() { return cachedUint8ArrayMemory0; } +const lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder; + +let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); + +cachedTextDecoder.decode(); + +const MAX_SAFARI_DECODE_BYTES = 2146435072; +let numBytesDecoded = 0; +function decodeText(ptr, len) { + numBytesDecoded += len; + if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) { + cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); + cachedTextDecoder.decode(); + numBytesDecoded = len; + } + return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); +} + function getStringFromWasm0(ptr, len) { ptr = ptr >>> 0; - return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); + return decodeText(ptr, len); } function addToExternrefTable0(obj) { @@ -108,7 +120,7 @@ let WASM_VECTOR_LEN = 0; const lTextEncoder = typeof TextEncoder === 'undefined' ? (0, module.require)('util').TextEncoder : TextEncoder; -let cachedTextEncoder = new lTextEncoder('utf-8'); +const cachedTextEncoder = new lTextEncoder('utf-8'); const encodeString = (typeof cachedTextEncoder.encodeInto === 'function' ? function (arg, view) {