diff --git a/.github/workflows/documentation.yaml b/.github/workflows/documentation.yaml index 0316e631027..31996b46da1 100644 --- a/.github/workflows/documentation.yaml +++ b/.github/workflows/documentation.yaml @@ -1,10 +1,10 @@ +name: Documentation + on: push: branches: - 'master' -name: Documentation - jobs: documentation: name: Documentation diff --git a/.github/workflows/js.yaml b/.github/workflows/test-js.yaml similarity index 72% rename from .github/workflows/js.yaml rename to .github/workflows/test-js.yaml index d05e21ce80f..1f8df5f5b88 100644 --- a/.github/workflows/js.yaml +++ b/.github/workflows/test-js.yaml @@ -1,3 +1,8 @@ +name: Runtime tests - JS + +env: + RUST_BACKTRACE: 1 + on: push: branches: @@ -8,24 +13,29 @@ on: # this is _not_ a regex, see: https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#filter-pattern-cheat-sheet - '[0-9]+.[0-9]+.[0-9]+*' -name: wasmer-js tests - -env: - RUST_BACKTRACE: 1 - jobs: - wasmer-js: - name: wasmer-js + test: + name: Test on NodeJS + runs-on: ubuntu-latest + steps: - uses: actions/checkout@v2 + - name: Install Rust uses: actions-rs/toolchain@v1 with: profile: minimal override: true + + - name: Install NodeJS + uses: actions/setup-node@v2 + with: + node-version: 16 + - name: Install wasm-pack run: | curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh - - name: Test wasmer-js + + - name: Compile Wasmer to WebAssembly and test with a JavaScript host run: make test-js diff --git a/.github/workflows/main.yaml b/.github/workflows/test-sys.yaml similarity index 99% rename from .github/workflows/main.yaml rename to .github/workflows/test-sys.yaml index 62af5c26356..d2337642fc4 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/test-sys.yaml @@ -1,4 +1,4 @@ -name: core tests +name: Runtime tests env: RUST_BACKTRACE: 1 diff --git a/Cargo.lock b/Cargo.lock index add3708d5ac..327f2ca4e39 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -857,8 +857,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" dependencies = [ "cfg-if 1.0.0", + "js-sys", "libc", "wasi", + "wasm-bindgen", ] [[package]] @@ -1160,6 +1162,15 @@ dependencies = [ "libc", ] +[[package]] +name = "matchers" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f099785f7595cc4b4553a174ce30dd7589ef93391ff414dbb67f62392b9e0ce1" +dependencies = [ + "regex-automata", +] + [[package]] name = "maybe-uninit" version = "2.0.0" @@ -1670,6 +1681,9 @@ name = "regex-automata" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax", +] [[package]] name = "regex-syntax" @@ -1926,12 +1940,27 @@ dependencies = [ "syn", ] +[[package]] +name = "sharded-slab" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79c719719ee05df97490f80a45acfc99e5a30ce98a1e4fb67aee422745ae14e3" +dependencies = [ + "lazy_static", +] + [[package]] name = "shlex" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2" +[[package]] +name = "slab" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c307a32c1c5c437f38c7fd45d753050587732ba8628319fbdf12a7e289ccc590" + [[package]] name = "smallvec" version = "1.6.1" @@ -1993,9 +2022,9 @@ dependencies = [ [[package]] name = "tar" -version = "0.4.36" +version = "0.4.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8190d9cdacf6ee1b080605fd719b58d80a9fcbcea64db6744b26f743da02e447" +checksum = "d6f5515d3add52e0bbdcad7b83c388bb36ba7b754dda3b5f5bc2d38640cdba5c" dependencies = [ "filetime", "libc", @@ -2048,6 +2077,17 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "test-env-log" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3e4b132a630cc8a0d06cfcb400da67adef3d0087a94b3332d4692908f0c2544" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "test-generator" version = "0.1.0" @@ -2098,6 +2138,15 @@ dependencies = [ "syn", ] +[[package]] +name = "thread_local" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8018d24e04c95ac8790716a5987d0fec4f8b27249ffa0f7d33f1369bdfb88cbd" +dependencies = [ + "once_cell", +] + [[package]] name = "time" version = "0.1.43" @@ -2160,6 +2209,32 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "tracing-subscriber" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab69019741fca4d98be3c62d2b75254528b5432233fd8a4d2739fec20278de48" +dependencies = [ + "lazy_static", + "matchers", + "regex", + "sharded-slab", + "thread_local", + "tracing", + "tracing-core", +] + +[[package]] +name = "tracing-wasm" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ae741706df70547fca8715f74a8569677666e7be3454313af70f6e158034485" +dependencies = [ + "tracing", + "tracing-subscriber", + "wasm-bindgen", +] + [[package]] name = "treeline" version = "0.1.0" @@ -2520,6 +2595,7 @@ dependencies = [ "wasmer-engine-staticlib", "wasmer-engine-universal", "wasmer-types", + "wasmer-vfs", "wasmer-vm", "wasmer-wasi", "wasmer-wasi-experimental-io-devices", @@ -2763,6 +2839,18 @@ dependencies = [ "thiserror", ] +[[package]] +name = "wasmer-vfs" +version = "2.0.0" +dependencies = [ + "libc", + "serde", + "slab", + "thiserror", + "tracing", + "typetag", +] + [[package]] name = "wasmer-vm" version = "2.0.0" @@ -2787,15 +2875,19 @@ dependencies = [ name = "wasmer-wasi" version = "2.0.0" dependencies = [ - "bincode", + "cfg-if 1.0.0", "generational-arena", "getrandom", "libc", "serde", "thiserror", "tracing", + "tracing-wasm", "typetag", + "wasm-bindgen", + "wasm-bindgen-test", "wasmer", + "wasmer-vfs", "wasmer-wasi-types", "winapi", ] @@ -2830,7 +2922,6 @@ dependencies = [ "serde", "tempfile", "thiserror", - "typetag", "wasmer", "wasmer-wasi", "wast", @@ -2851,7 +2942,10 @@ dependencies = [ "rustc_version 0.4.0", "serial_test", "tempfile", + "test-env-log", "test-generator", + "tracing", + "tracing-subscriber", "wasmer", "wasmer-cache", "wasmer-compiler", diff --git a/Cargo.toml b/Cargo.toml index c95ec2cdd89..a19e0789477 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,6 +44,7 @@ members = [ "lib/engine-dylib", "lib/engine-staticlib", "lib/object", + "lib/vfs", "lib/vm", "lib/wasi", "lib/wasi-types", @@ -55,6 +56,7 @@ members = [ "tests/integration/ios", "fuzz", ] +resolver = "2" [build-dependencies] test-generator = { path = "tests/lib/test-generator" } @@ -72,6 +74,10 @@ wasmer-engine-dummy = { path = "tests/lib/engine-dummy" } compiler-test-derive = { path = "tests/lib/compiler-test-derive" } tempfile = "3.1" loupe = "0.1" +# For logging tests using the `RUST_LOG=debug` when testing +test-env-log = { version = "0.2", default-features = false, features = ["trace"] } +tracing = { version = "0.1", default-features = false, features = ["log"] } +tracing-subscriber = { version = "0.2", default-features = false, features = ["env-filter", "fmt"] } [features] # Don't add the compiler features in default, please add them on the Makefile @@ -80,7 +86,6 @@ default = [ "wat", "wast", "universal", - "dylib", "staticlib", "cache", "wasi", @@ -285,4 +290,4 @@ required-features = ["cranelift"] [[example]] name = "features" path = "examples/features.rs" -required-features = ["cranelift"] \ No newline at end of file +required-features = ["cranelift"] diff --git a/Makefile b/Makefile index e70be08727c..9c0d92e5c28 100644 --- a/Makefile +++ b/Makefile @@ -318,10 +318,12 @@ ifneq (, $(LIBC)) endif $(info Enabled Compilers: $(bold)$(green)$(subst $(space),$(reset)$(comma)$(space)$(bold)$(green),$(compilers))$(reset).) $(info Testing the following compilers & engines:) -$(info * API: $(bold)$(green)${compilers_engines}$(reset)) -$(info * C-API: $(bold)$(green)${capi_compilers_engines}$(reset)) +$(info   * API: $(bold)$(green)${compilers_engines}$(reset),) +$(info   * C-API: $(bold)$(green)${capi_compilers_engines}$(reset).) $(info Cargo features:) -$(info * Compilers: `$(bold)$(green)${compiler_features}$(reset)`.) +$(info   * Compilers: `$(bold)$(green)${compiler_features}$(reset)`.) +$(info Rust version: $(bold)$(green)$(shell rustc --version)$(reset).) +$(info NodeJS version: $(bold)$(green)$(shell node --version)$(reset).) $(info ) $(info ) $(info --------------) @@ -358,7 +360,7 @@ build-wasmer: cargo build --release --manifest-path lib/cli/Cargo.toml $(compiler_features) --bin wasmer build-wasmer-debug: - cargo build --manifest-path lib/cli/Cargo.toml $(compiler_features) --bin wasmer + cargo build --manifest-path lib/cli/Cargo.toml $(compiler_features) --features "debug" --bin wasmer bench: cargo bench $(compiler_features) @@ -505,9 +507,13 @@ test-packages: cargo test --manifest-path lib/compiler-singlepass/Cargo.toml --release --no-default-features --features=std cargo test --manifest-path lib/cli/Cargo.toml $(compiler_features) --release -test-js: +test-js: test-js-api test-js-wasi + +test-js-api: cd lib/api && wasm-pack test --node -- --no-default-features --features js-default,wat +test-js-wasi: + cd lib/wasi && wasm-pack test --node -- --no-default-features --features test-js ##### # diff --git a/lib/api/src/js/externals/memory.rs b/lib/api/src/js/externals/memory.rs index 4dc868d1fbf..cf1e782fce2 100644 --- a/lib/api/src/js/externals/memory.rs +++ b/lib/api/src/js/externals/memory.rs @@ -288,7 +288,10 @@ impl Memory { unimplemented!("The view function is not yet implemented in Wasmer Javascript"); } - /// example view + /// A theoretical alais to `Self::view::` but it returns a `js::Uint8Array` in this case. + /// + /// This code is going to be refactored. Use it as your own risks. + #[doc(hidden)] pub fn uint8view(&self) -> js_sys::Uint8Array { js_sys::Uint8Array::new(&self.vm_memory.memory.buffer()) } diff --git a/lib/api/src/js/import_object.rs b/lib/api/src/js/import_object.rs index 63bb41d50f6..4bd1f92fbe6 100644 --- a/lib/api/src/js/import_object.rs +++ b/lib/api/src/js/import_object.rs @@ -115,6 +115,23 @@ impl ImportObject { } } +impl Into for ImportObject { + fn into(self) -> js_sys::Object { + let guard = self.map.lock().unwrap(); + let map = guard.borrow(); + + let imports = js_sys::Object::new(); + for (module, ns) in map.iter() { + let import_namespace = js_sys::Object::new(); + for (name, exp) in ns.get_namespace_exports() { + js_sys::Reflect::set(&import_namespace, &name.into(), exp.as_jsvalue()).unwrap(); + } + js_sys::Reflect::set(&imports, &module.into(), &import_namespace.into()).unwrap(); + } + imports + } +} + impl NamedResolver for ImportObject { fn resolve_by_name(&self, module: &str, name: &str) -> Option { self.get_export(module, name) diff --git a/lib/api/src/sys/externals/memory.rs b/lib/api/src/sys/externals/memory.rs index b5b6ba5cc7e..4fa3a9ba3cc 100644 --- a/lib/api/src/sys/externals/memory.rs +++ b/lib/api/src/sys/externals/memory.rs @@ -226,6 +226,14 @@ impl Memory { unsafe { MemoryView::new(base as _, length as u32) } } + /// A shortcut to [`Self::view::`][self::view]. + /// + /// This code is going to be refactored. Use it as your own risks. + #[doc(hidden)] + pub fn uint8view(&self) -> MemoryView { + self.view() + } + pub(crate) fn from_vm_export(store: &Store, vm_memory: VMMemory) -> Self { Self { store: store.clone(), diff --git a/lib/c-api/src/wasm_c_api/wasi/capture_files.rs b/lib/c-api/src/wasm_c_api/wasi/capture_files.rs index f5c62d7446d..85ae72dd1e3 100644 --- a/lib/c-api/src/wasm_c_api/wasi/capture_files.rs +++ b/lib/c-api/src/wasm_c_api/wasi/capture_files.rs @@ -1,12 +1,11 @@ //! Default implementations for capturing the stdout/stderr output of a WASI program. -use serde::{Deserialize, Serialize}; use std::collections::VecDeque; use std::io::{self, Read, Seek, Write}; use wasmer_wasi::{WasiFile, WasiFsError}; /// For capturing stdout/stderr. Stores all output in a string. -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug)] pub struct OutputCapturer { pub(crate) buffer: VecDeque, } @@ -19,7 +18,6 @@ impl OutputCapturer { } } -#[typetag::serde] impl WasiFile for OutputCapturer { fn last_accessed(&self) -> u64 { 0 diff --git a/lib/cli/Cargo.toml b/lib/cli/Cargo.toml index 85347a74dd4..484a140c445 100644 --- a/lib/cli/Cargo.toml +++ b/lib/cli/Cargo.toml @@ -35,11 +35,12 @@ wasmer-engine-universal = { version = "2.0.0", path = "../engine-universal", opt wasmer-engine-dylib = { version = "2.0.0", path = "../engine-dylib", optional = true } wasmer-engine-staticlib = { version = "2.0.0", path = "../engine-staticlib", optional = true } wasmer-vm = { version = "2.0.0", path = "../vm" } -wasmer-wasi = { version = "2.0.0", path = "../wasi", default-features = false, optional = true } +wasmer-wasi = { version = "2.0.0", path = "../wasi", optional = true } wasmer-wasi-experimental-io-devices = { version = "2.0.0", path = "../wasi-experimental-io-devices", optional = true } wasmer-wast = { version = "2.0.0", path = "../../tests/lib/wast", optional = true } wasmer-cache = { version = "2.0.0", path = "../cache", optional = true } wasmer-types = { version = "2.0.0", path = "../types" } +wasmer-vfs = { version = "2.0.0", path = "../vfs", default-features = false, features = ["host-fs"] } atty = "0.2" colored = "2.0" anyhow = "1.0" diff --git a/lib/cli/src/commands/run.rs b/lib/cli/src/commands/run.rs index c515c10f1f5..653ea4e72f6 100644 --- a/lib/cli/src/commands/run.rs +++ b/lib/cli/src/commands/run.rs @@ -64,6 +64,9 @@ pub struct Run { #[structopt(long = "debug", short = "d")] debug: bool, + #[structopt(short, long, parse(from_occurrences))] + verbose: u8, + /// Application arguments #[structopt(name = "--", multiple = true)] args: Vec, @@ -74,7 +77,7 @@ impl Run { pub fn execute(&self) -> Result<()> { #[cfg(feature = "debug")] if self.debug { - logging::set_up_logging().unwrap(); + logging::set_up_logging(self.verbose).unwrap(); } self.inner_execute().with_context(|| { format!( diff --git a/lib/cli/src/logging.rs b/lib/cli/src/logging.rs index fd2eaafc025..d60a45fbf33 100644 --- a/lib/cli/src/logging.rs +++ b/lib/cli/src/logging.rs @@ -1,10 +1,14 @@ //! Logging functions for the debug feature. use crate::utils::wasmer_should_print_color; +use anyhow::Result; use fern::colors::{Color, ColoredLevelConfig}; use std::time; +/// The debug level +pub type DebugLevel = log::LevelFilter; + /// Subroutine to instantiate the loggers -pub fn set_up_logging() -> Result<(), String> { +pub fn set_up_logging(verbose: u8) -> Result<(), String> { let colors_line = ColoredLevelConfig::new() .error(Color::Red) .warn(Color::Yellow) @@ -12,8 +16,12 @@ pub fn set_up_logging() -> Result<(), String> { let should_color = wasmer_should_print_color(); let colors_level = colors_line.info(Color::Green); + let level = match verbose { + 1 => DebugLevel::Debug, + _ => DebugLevel::Trace, + }; let dispatch = fern::Dispatch::new() - .level(log::LevelFilter::Debug) + .level(level) .chain({ let base = if should_color { fern::Dispatch::new().format(move |out, message, record| { diff --git a/lib/engine/src/artifact.rs b/lib/engine/src/artifact.rs index 0f1058602e1..e8185d14a7f 100644 --- a/lib/engine/src/artifact.rs +++ b/lib/engine/src/artifact.rs @@ -179,7 +179,7 @@ pub trait Artifact: Send + Sync + Upcastable + MemoryUsage { } // Implementation of `Upcastable` taken from https://users.rust-lang.org/t/why-does-downcasting-not-work-for-subtraits/33286/7 . -/// Trait needed to get downcasting from `WasiFile` to work. +/// Trait needed to get downcasting of `Engine`s to work. pub trait Upcastable { fn upcast_any_ref(&'_ self) -> &'_ dyn Any; fn upcast_any_mut(&'_ mut self) -> &'_ mut dyn Any; diff --git a/lib/types/src/memory_view.rs b/lib/types/src/memory_view.rs index 172dd1ce5f8..732e687319f 100644 --- a/lib/types/src/memory_view.rs +++ b/lib/types/src/memory_view.rs @@ -1,7 +1,7 @@ use crate::lib::std::cell::Cell; use crate::lib::std::marker::PhantomData; use crate::lib::std::ops::Deref; -use crate::lib::std::ops::{Bound, RangeBounds}; +// use crate::lib::std::ops::{Bound, RangeBounds}; use crate::lib::std::slice; use crate::lib::std::sync::atomic::{ AtomicI16, AtomicI32, AtomicI64, AtomicI8, AtomicU16, AtomicU32, AtomicU64, AtomicU8, @@ -68,29 +68,20 @@ where } } - /// Creates a subarray view from this MemoryView. - pub fn subarray(&self, range: impl RangeBounds) -> Self { - let start: usize = match range.start_bound() { - Bound::Unbounded => 0, - Bound::Included(start) => *start, - Bound::Excluded(start) => *start + 1, - }; - let end: usize = match range.end_bound() { - Bound::Unbounded => self.length, - Bound::Included(end) => *end, - Bound::Excluded(end) => *end - 1, - }; + /// Creates a subarray view from this `MemoryView`. + pub fn subarray(&self, start: u32, end: u32) -> Self { assert!( - start < self.length, + (start as usize) < self.length, "The range start is bigger than current length" ); assert!( - end < self.length, + (end as usize) < self.length, "The range end is bigger than current length" ); + Self { - ptr: unsafe { self.ptr.add(start) }, - length: (end - start), + ptr: unsafe { self.ptr.add(start as usize) }, + length: (end - start) as usize, _phantom: PhantomData, } } diff --git a/lib/vfs/Cargo.toml b/lib/vfs/Cargo.toml new file mode 100644 index 00000000000..b99e630ab7f --- /dev/null +++ b/lib/vfs/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "wasmer-vfs" +version = "2.0.0" +description = "Wasmer Virtual FileSystem" +authors = ["Wasmer Engineering Team "] +license = "MIT" +edition = "2018" + +[dependencies] +libc = { version = "^0.2", default-features = false, optional = true } +thiserror = "1" +tracing = { version = "0.1" } +typetag = { version = "0.1", optional = true } +serde = { version = "1.0", default-features = false, features = ["derive"], optional = true } +slab = { version = "0.4", optional = true } + +[features] +default = ["host-fs", "mem-fs"] +host-fs = ["libc"] +mem-fs = ["slab"] +enable-serde = [ + "serde", + "typetag" +] +no-time = [] \ No newline at end of file diff --git a/lib/vfs/src/host_fs.rs b/lib/vfs/src/host_fs.rs new file mode 100644 index 00000000000..19475768e51 --- /dev/null +++ b/lib/vfs/src/host_fs.rs @@ -0,0 +1,728 @@ +use crate::{ + DirEntry, FileDescriptor, FileType, FsError, Metadata, OpenOptions, OpenOptionsConfig, ReadDir, + Result, VirtualFile, +}; +#[cfg(feature = "enable-serde")] +use serde::{de, Deserialize, Serialize}; +use std::convert::TryInto; +use std::fs; +use std::io::{self, Read, Seek, Write}; +#[cfg(unix)] +use std::os::unix::io::{AsRawFd, RawFd}; +#[cfg(windows)] +use std::os::windows::io::{AsRawHandle, RawHandle}; +use std::path::{Path, PathBuf}; +use std::time::{SystemTime, UNIX_EPOCH}; +use tracing::debug; + +trait TryIntoFileDescriptor { + type Error; + + fn try_into_filedescriptor(&self) -> std::result::Result; +} + +#[cfg(unix)] +impl TryIntoFileDescriptor for T +where + T: AsRawFd, +{ + type Error = FsError; + + fn try_into_filedescriptor(&self) -> std::result::Result { + Ok(FileDescriptor( + self.as_raw_fd() + .try_into() + .map_err(|_| FsError::InvalidFd)?, + )) + } +} + +#[cfg(unix)] +impl TryInto for FileDescriptor { + type Error = FsError; + + fn try_into(self) -> std::result::Result { + self.0.try_into().map_err(|_| FsError::InvalidFd) + } +} + +#[cfg(windows)] +impl TryIntoFileDescriptor for T +where + T: AsRawHandle, +{ + type Error = FsError; + + fn try_into_filedescriptor(&self) -> std::result::Result { + Ok(FileDescriptor(self.as_raw_handle() as usize)) + } +} + +#[cfg(windows)] +impl TryInto for FileDescriptor { + type Error = FsError; + + fn try_into(self) -> std::result::Result { + Ok(self.0 as RawHandle) + } +} + +#[derive(Debug, Default, Clone)] +#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +pub struct FileSystem; + +impl crate::FileSystem for FileSystem { + fn read_dir(&self, path: &Path) -> Result { + let read_dir = fs::read_dir(path)?; + let data = read_dir + .map(|entry| { + let entry = entry?; + let metadata = entry.metadata()?; + Ok(DirEntry { + path: entry.path(), + metadata: Ok(metadata.try_into()?), + }) + }) + .collect::, io::Error>>() + .map_err::(Into::into)?; + Ok(ReadDir::new(data)) + } + + fn create_dir(&self, path: &Path) -> Result<()> { + fs::create_dir(path).map_err(Into::into) + } + + fn remove_dir(&self, path: &Path) -> Result<()> { + fs::remove_dir(path).map_err(Into::into) + } + + fn rename(&self, from: &Path, to: &Path) -> Result<()> { + fs::rename(from, to).map_err(Into::into) + } + + fn remove_file(&self, path: &Path) -> Result<()> { + fs::remove_file(path).map_err(Into::into) + } + + fn new_open_options(&self) -> OpenOptions { + OpenOptions::new(Box::new(FileOpener)) + } + + fn metadata(&self, path: &Path) -> Result { + fs::metadata(path) + .and_then(TryInto::try_into) + .map_err(Into::into) + } +} + +impl TryInto for fs::Metadata { + type Error = io::Error; + + fn try_into(self) -> std::result::Result { + let filetype = self.file_type(); + let (char_device, block_device, socket, fifo) = { + #[cfg(unix)] + { + use std::os::unix::fs::FileTypeExt; + ( + filetype.is_char_device(), + filetype.is_block_device(), + filetype.is_socket(), + filetype.is_fifo(), + ) + } + #[cfg(not(unix))] + { + (false, false, false, false) + } + }; + + Ok(Metadata { + ft: FileType { + dir: filetype.is_dir(), + file: filetype.is_file(), + symlink: filetype.is_symlink(), + char_device, + block_device, + socket, + fifo, + }, + accessed: self + .accessed() + .and_then(|time| { + time.duration_since(UNIX_EPOCH) + .map_err(|e| io::Error::new(io::ErrorKind::Other, e)) + }) + .map_or(0, |time| time.as_nanos() as u64), + created: self + .created() + .and_then(|time| { + time.duration_since(UNIX_EPOCH) + .map_err(|e| io::Error::new(io::ErrorKind::Other, e)) + }) + .map_or(0, |time| time.as_nanos() as u64), + modified: self + .modified() + .and_then(|time| { + time.duration_since(UNIX_EPOCH) + .map_err(|e| io::Error::new(io::ErrorKind::Other, e)) + }) + .map_or(0, |time| time.as_nanos() as u64), + len: self.len(), + }) + } +} + +#[derive(Debug, Clone)] +pub struct FileOpener; + +impl crate::FileOpener for FileOpener { + fn open(&mut self, path: &Path, conf: &OpenOptionsConfig) -> Result> { + // TODO: handle create implying write, etc. + let read = conf.read(); + let write = conf.write(); + let append = conf.append(); + let mut oo = fs::OpenOptions::new(); + oo.read(conf.read()) + .write(conf.write()) + .create_new(conf.create_new()) + .create(conf.create()) + .append(conf.append()) + .truncate(conf.truncate()) + .open(path) + .map_err(Into::into) + .map(|file| { + Box::new(File::new(file, path.to_owned(), read, write, append)) + as Box + }) + } +} + +/// A thin wrapper around `std::fs::File` +#[derive(Debug)] +#[cfg_attr(feature = "enable-serde", derive(Serialize))] +pub struct File { + #[cfg_attr(feature = "enable-serde", serde(skip_serializing))] + pub inner: fs::File, + pub host_path: PathBuf, + flags: u16, +} + +#[cfg(feature = "enable-serde")] +impl<'de> Deserialize<'de> for File { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + #[serde(field_identifier, rename_all = "snake_case")] + enum Field { + HostPath, + Flags, + } + + struct FileVisitor; + + impl<'de> de::Visitor<'de> for FileVisitor { + type Value = File; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("struct File") + } + + fn visit_seq(self, mut seq: V) -> std::result::Result + where + V: de::SeqAccess<'de>, + { + let host_path = seq + .next_element()? + .ok_or_else(|| de::Error::invalid_length(0, &self))?; + let flags = seq + .next_element()? + .ok_or_else(|| de::Error::invalid_length(1, &self))?; + let inner = fs::OpenOptions::new() + .read(flags & File::READ != 0) + .write(flags & File::WRITE != 0) + .append(flags & File::APPEND != 0) + .open(&host_path) + .map_err(|_| de::Error::custom("Could not open file on this system"))?; + Ok(File { + inner, + host_path, + flags, + }) + } + + fn visit_map(self, mut map: V) -> std::result::Result + where + V: de::MapAccess<'de>, + { + let mut host_path = None; + let mut flags = None; + while let Some(key) = map.next_key()? { + match key { + Field::HostPath => { + if host_path.is_some() { + return Err(de::Error::duplicate_field("host_path")); + } + host_path = Some(map.next_value()?); + } + Field::Flags => { + if flags.is_some() { + return Err(de::Error::duplicate_field("flags")); + } + flags = Some(map.next_value()?); + } + } + } + let host_path = host_path.ok_or_else(|| de::Error::missing_field("host_path"))?; + let flags = flags.ok_or_else(|| de::Error::missing_field("flags"))?; + let inner = fs::OpenOptions::new() + .read(flags & File::READ != 0) + .write(flags & File::WRITE != 0) + .append(flags & File::APPEND != 0) + .open(&host_path) + .map_err(|_| de::Error::custom("Could not open file on this system"))?; + Ok(File { + inner, + host_path, + flags, + }) + } + } + + const FIELDS: &[&str] = &["host_path", "flags"]; + deserializer.deserialize_struct("File", FIELDS, FileVisitor) + } +} + +impl File { + const READ: u16 = 1; + const WRITE: u16 = 2; + const APPEND: u16 = 4; + + /// creates a new host file from a `std::fs::File` and a path + pub fn new(file: fs::File, host_path: PathBuf, read: bool, write: bool, append: bool) -> Self { + let mut flags = 0; + + if read { + flags |= Self::READ; + } + + if write { + flags |= Self::WRITE; + } + + if append { + flags |= Self::APPEND; + } + + Self { + inner: file, + host_path, + flags, + } + } + + pub fn metadata(&self) -> fs::Metadata { + self.inner.metadata().unwrap() + } +} + +impl Read for File { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + self.inner.read(buf) + } + + fn read_to_end(&mut self, buf: &mut Vec) -> io::Result { + self.inner.read_to_end(buf) + } + + fn read_to_string(&mut self, buf: &mut String) -> io::Result { + self.inner.read_to_string(buf) + } + + fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> { + self.inner.read_exact(buf) + } +} + +impl Seek for File { + fn seek(&mut self, pos: io::SeekFrom) -> io::Result { + self.inner.seek(pos) + } +} + +impl Write for File { + fn write(&mut self, buf: &[u8]) -> io::Result { + self.inner.write(buf) + } + + fn flush(&mut self) -> io::Result<()> { + self.inner.flush() + } + + fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { + self.inner.write_all(buf) + } + + fn write_fmt(&mut self, fmt: ::std::fmt::Arguments) -> io::Result<()> { + self.inner.write_fmt(fmt) + } +} + +#[cfg_attr(feature = "enable-serde", typetag::serde)] +impl VirtualFile for File { + fn last_accessed(&self) -> u64 { + self.metadata() + .accessed() + .ok() + .and_then(|ct| ct.duration_since(SystemTime::UNIX_EPOCH).ok()) + .map(|ct| ct.as_nanos() as u64) + .unwrap_or(0) + } + + fn last_modified(&self) -> u64 { + self.metadata() + .modified() + .ok() + .and_then(|ct| ct.duration_since(SystemTime::UNIX_EPOCH).ok()) + .map(|ct| ct.as_nanos() as u64) + .unwrap_or(0) + } + + fn created_time(&self) -> u64 { + self.metadata() + .created() + .ok() + .and_then(|ct| ct.duration_since(SystemTime::UNIX_EPOCH).ok()) + .map(|ct| ct.as_nanos() as u64) + .unwrap_or(0) + } + + fn size(&self) -> u64 { + self.metadata().len() + } + + fn set_len(&mut self, new_size: u64) -> Result<()> { + fs::File::set_len(&self.inner, new_size).map_err(Into::into) + } + + fn unlink(&mut self) -> Result<()> { + fs::remove_file(&self.host_path).map_err(Into::into) + } + fn sync_to_disk(&self) -> Result<()> { + self.inner.sync_all().map_err(Into::into) + } + + fn bytes_available(&self) -> Result { + host_file_bytes_available(self.inner.try_into_filedescriptor()?) + } +} + +#[cfg(unix)] +fn host_file_bytes_available(host_fd: FileDescriptor) -> Result { + let mut bytes_found: libc::c_int = 0; + let result = unsafe { libc::ioctl(host_fd.try_into()?, libc::FIONREAD, &mut bytes_found) }; + + match result { + // success + 0 => Ok(bytes_found.try_into().unwrap_or(0)), + libc::EBADF => Err(FsError::InvalidFd), + libc::EFAULT => Err(FsError::InvalidData), + libc::EINVAL => Err(FsError::InvalidInput), + _ => Err(FsError::IOError), + } +} + +#[cfg(not(unix))] +fn host_file_bytes_available(_host_fd: FileDescriptor) -> Result { + unimplemented!("host_file_bytes_available not yet implemented for non-Unix-like targets. This probably means the program tried to use wasi::poll_oneoff") +} + +/// A wrapper type around Stdout that implements `VirtualFile` and +/// `Serialize` + `Deserialize`. +#[derive(Debug, Default)] +#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +pub struct Stdout; + +impl Read for Stdout { + fn read(&mut self, _buf: &mut [u8]) -> io::Result { + Err(io::Error::new( + io::ErrorKind::Other, + "can not read from stdout", + )) + } + + fn read_to_end(&mut self, _buf: &mut Vec) -> io::Result { + Err(io::Error::new( + io::ErrorKind::Other, + "can not read from stdout", + )) + } + + fn read_to_string(&mut self, _buf: &mut String) -> io::Result { + Err(io::Error::new( + io::ErrorKind::Other, + "can not read from stdout", + )) + } + + fn read_exact(&mut self, _buf: &mut [u8]) -> io::Result<()> { + Err(io::Error::new( + io::ErrorKind::Other, + "can not read from stdout", + )) + } +} + +impl Seek for Stdout { + fn seek(&mut self, _pos: io::SeekFrom) -> io::Result { + Err(io::Error::new(io::ErrorKind::Other, "can not seek stdout")) + } +} + +impl Write for Stdout { + fn write(&mut self, buf: &[u8]) -> io::Result { + io::stdout().write(buf) + } + + fn flush(&mut self) -> io::Result<()> { + io::stdout().flush() + } + + fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { + io::stdout().write_all(buf) + } + + fn write_fmt(&mut self, fmt: ::std::fmt::Arguments) -> io::Result<()> { + io::stdout().write_fmt(fmt) + } +} + +#[cfg_attr(feature = "enable-serde", typetag::serde)] +impl VirtualFile for Stdout { + fn last_accessed(&self) -> u64 { + 0 + } + + fn last_modified(&self) -> u64 { + 0 + } + + fn created_time(&self) -> u64 { + 0 + } + + fn size(&self) -> u64 { + 0 + } + + fn set_len(&mut self, _new_size: u64) -> Result<()> { + debug!("Calling VirtualFile::set_len on stdout; this is probably a bug"); + Err(FsError::PermissionDenied) + } + + fn unlink(&mut self) -> Result<()> { + Ok(()) + } + + fn bytes_available(&self) -> Result { + host_file_bytes_available(io::stdout().try_into_filedescriptor()?) + } + + fn get_fd(&self) -> Option { + io::stdout().try_into_filedescriptor().ok() + } +} + +/// A wrapper type around Stderr that implements `VirtualFile` and +/// `Serialize` + `Deserialize`. +#[derive(Debug, Default)] +#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +pub struct Stderr; + +impl Read for Stderr { + fn read(&mut self, _buf: &mut [u8]) -> io::Result { + Err(io::Error::new( + io::ErrorKind::Other, + "can not read from stderr", + )) + } + + fn read_to_end(&mut self, _buf: &mut Vec) -> io::Result { + Err(io::Error::new( + io::ErrorKind::Other, + "can not read from stderr", + )) + } + + fn read_to_string(&mut self, _buf: &mut String) -> io::Result { + Err(io::Error::new( + io::ErrorKind::Other, + "can not read from stderr", + )) + } + + fn read_exact(&mut self, _buf: &mut [u8]) -> io::Result<()> { + Err(io::Error::new( + io::ErrorKind::Other, + "can not read from stderr", + )) + } +} + +impl Seek for Stderr { + fn seek(&mut self, _pos: io::SeekFrom) -> io::Result { + Err(io::Error::new(io::ErrorKind::Other, "can not seek stderr")) + } +} + +impl Write for Stderr { + fn write(&mut self, buf: &[u8]) -> io::Result { + io::stderr().write(buf) + } + + fn flush(&mut self) -> io::Result<()> { + io::stderr().flush() + } + + fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { + io::stderr().write_all(buf) + } + + fn write_fmt(&mut self, fmt: ::std::fmt::Arguments) -> io::Result<()> { + io::stderr().write_fmt(fmt) + } +} + +#[cfg_attr(feature = "enable-serde", typetag::serde)] +impl VirtualFile for Stderr { + fn last_accessed(&self) -> u64 { + 0 + } + + fn last_modified(&self) -> u64 { + 0 + } + + fn created_time(&self) -> u64 { + 0 + } + + fn size(&self) -> u64 { + 0 + } + + fn set_len(&mut self, _new_size: u64) -> Result<()> { + debug!("Calling VirtualFile::set_len on stderr; this is probably a bug"); + Err(FsError::PermissionDenied) + } + + fn unlink(&mut self) -> Result<()> { + Ok(()) + } + + fn bytes_available(&self) -> Result { + host_file_bytes_available(io::stderr().try_into_filedescriptor()?) + } + + fn get_fd(&self) -> Option { + io::stderr().try_into_filedescriptor().ok() + } +} + +/// A wrapper type around Stdin that implements `VirtualFile` and +/// `Serialize` + `Deserialize`. +#[derive(Debug, Default)] +#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +pub struct Stdin; +impl Read for Stdin { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + io::stdin().read(buf) + } + + fn read_to_end(&mut self, buf: &mut Vec) -> io::Result { + io::stdin().read_to_end(buf) + } + + fn read_to_string(&mut self, buf: &mut String) -> io::Result { + io::stdin().read_to_string(buf) + } + + fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> { + io::stdin().read_exact(buf) + } +} + +impl Seek for Stdin { + fn seek(&mut self, _pos: io::SeekFrom) -> io::Result { + Err(io::Error::new(io::ErrorKind::Other, "can not seek stdin")) + } +} + +impl Write for Stdin { + fn write(&mut self, _buf: &[u8]) -> io::Result { + Err(io::Error::new( + io::ErrorKind::Other, + "can not write to stdin", + )) + } + + fn flush(&mut self) -> io::Result<()> { + Err(io::Error::new( + io::ErrorKind::Other, + "can not write to stdin", + )) + } + + fn write_all(&mut self, _buf: &[u8]) -> io::Result<()> { + Err(io::Error::new( + io::ErrorKind::Other, + "can not write to stdin", + )) + } + + fn write_fmt(&mut self, _fmt: ::std::fmt::Arguments) -> io::Result<()> { + Err(io::Error::new( + io::ErrorKind::Other, + "can not write to stdin", + )) + } +} + +#[cfg_attr(feature = "enable-serde", typetag::serde)] +impl VirtualFile for Stdin { + fn last_accessed(&self) -> u64 { + 0 + } + + fn last_modified(&self) -> u64 { + 0 + } + + fn created_time(&self) -> u64 { + 0 + } + + fn size(&self) -> u64 { + 0 + } + + fn set_len(&mut self, _new_size: u64) -> Result<()> { + debug!("Calling VirtualFile::set_len on stdin; this is probably a bug"); + Err(FsError::PermissionDenied) + } + + fn unlink(&mut self) -> Result<()> { + Ok(()) + } + + fn bytes_available(&self) -> Result { + host_file_bytes_available(io::stdin().try_into_filedescriptor()?) + } + + fn get_fd(&self) -> Option { + io::stdin().try_into_filedescriptor().ok() + } +} diff --git a/lib/vfs/src/lib.rs b/lib/vfs/src/lib.rs new file mode 100644 index 00000000000..d69f52e8c13 --- /dev/null +++ b/lib/vfs/src/lib.rs @@ -0,0 +1,450 @@ +use std::any::Any; +use std::ffi::OsString; +use std::fmt; +use std::io::{self, Read, Seek, Write}; +use std::path::{Path, PathBuf}; +use thiserror::Error; + +#[cfg(all(not(feature = "host-fs"), not(feature = "mem-fs")))] +compile_error!("At least the `host-fs` or the `mem-fs` feature must be enabled. Please, pick one."); + +#[cfg(all(feature = "mem-fs", feature = "enable-serde"))] +compile_error!("`mem-fs` does not support `enable-serde` for the moment."); + +#[cfg(feature = "host-fs")] +pub mod host_fs; +#[cfg(feature = "mem-fs")] +pub mod mem_fs; + +pub type Result = std::result::Result; + +#[derive(Debug)] +#[repr(transparent)] +pub struct FileDescriptor(usize); + +pub trait FileSystem: fmt::Debug + Send + Sync + 'static { + fn read_dir(&self, path: &Path) -> Result; + fn create_dir(&self, path: &Path) -> Result<()>; + fn remove_dir(&self, path: &Path) -> Result<()>; + fn rename(&self, from: &Path, to: &Path) -> Result<()>; + fn metadata(&self, path: &Path) -> Result; + /// This method gets metadata without following symlinks in the path. + /// Currently identical to `metadata` because symlinks aren't implemented + /// yet. + fn symlink_metadata(&self, path: &Path) -> Result { + self.metadata(path) + } + fn remove_file(&self, path: &Path) -> Result<()>; + fn new_open_options(&self) -> OpenOptions; +} + +pub trait FileOpener { + fn open(&mut self, path: &Path, conf: &OpenOptionsConfig) -> Result>; +} + +#[derive(Debug, Clone)] +pub struct OpenOptionsConfig { + read: bool, + write: bool, + create_new: bool, + create: bool, + append: bool, + truncate: bool, +} + +impl OpenOptionsConfig { + pub const fn read(&self) -> bool { + self.read + } + + pub const fn write(&self) -> bool { + self.write + } + + pub const fn create_new(&self) -> bool { + self.create_new + } + + pub const fn create(&self) -> bool { + self.create + } + + pub const fn append(&self) -> bool { + self.append + } + + pub const fn truncate(&self) -> bool { + self.truncate + } +} + +// TODO: manually implement debug + +pub struct OpenOptions { + opener: Box, + conf: OpenOptionsConfig, +} + +impl OpenOptions { + pub fn new(opener: Box) -> Self { + Self { + opener, + conf: OpenOptionsConfig { + read: false, + write: false, + create_new: false, + create: false, + append: false, + truncate: false, + }, + } + } + + pub fn read(&mut self, read: bool) -> &mut Self { + self.conf.read = read; + self + } + + pub fn write(&mut self, write: bool) -> &mut Self { + self.conf.write = write; + self + } + + pub fn append(&mut self, append: bool) -> &mut Self { + self.conf.append = append; + self + } + + pub fn truncate(&mut self, truncate: bool) -> &mut Self { + self.conf.truncate = truncate; + self + } + + pub fn create(&mut self, create: bool) -> &mut Self { + self.conf.create = create; + self + } + + pub fn create_new(&mut self, create_new: bool) -> &mut Self { + self.conf.create_new = create_new; + self + } + + pub fn open>(&mut self, path: P) -> Result> { + self.opener.open(path.as_ref(), &self.conf) + } +} + +/// This trait relies on your file closing when it goes out of scope via `Drop` +#[cfg_attr(feature = "enable-serde", typetag::serde)] +pub trait VirtualFile: fmt::Debug + Send + Write + Read + Seek + 'static + Upcastable { + /// the last time the file was accessed in nanoseconds as a UNIX timestamp + fn last_accessed(&self) -> u64; + + /// the last time the file was modified in nanoseconds as a UNIX timestamp + fn last_modified(&self) -> u64; + + /// the time at which the file was created in nanoseconds as a UNIX timestamp + fn created_time(&self) -> u64; + + /// the size of the file in bytes + fn size(&self) -> u64; + + /// Change the size of the file, if the `new_size` is greater than the current size + /// the extra bytes will be allocated and zeroed + fn set_len(&mut self, new_size: u64) -> Result<()>; + + /// Request deletion of the file + fn unlink(&mut self) -> Result<()>; + + /// Store file contents and metadata to disk + /// Default implementation returns `Ok(())`. You should implement this method if you care + /// about flushing your cache to permanent storage + fn sync_to_disk(&self) -> Result<()> { + Ok(()) + } + + /// Returns the number of bytes available. This function must not block + fn bytes_available(&self) -> Result; + + /// Used for polling. Default returns `None` because this method cannot be implemented for most types + /// Returns the underlying host fd + fn get_fd(&self) -> Option { + None + } +} + +// Implementation of `Upcastable` taken from https://users.rust-lang.org/t/why-does-downcasting-not-work-for-subtraits/33286/7 . +/// Trait needed to get downcasting from `VirtualFile` to work. +pub trait Upcastable { + fn upcast_any_ref(&'_ self) -> &'_ dyn Any; + fn upcast_any_mut(&'_ mut self) -> &'_ mut dyn Any; + fn upcast_any_box(self: Box) -> Box; +} + +impl Upcastable for T { + #[inline] + fn upcast_any_ref(&'_ self) -> &'_ dyn Any { + self + } + #[inline] + fn upcast_any_mut(&'_ mut self) -> &'_ mut dyn Any { + self + } + #[inline] + fn upcast_any_box(self: Box) -> Box { + self + } +} + +impl dyn VirtualFile + 'static { + #[inline] + pub fn downcast_ref(&'_ self) -> Option<&'_ T> { + self.upcast_any_ref().downcast_ref::() + } + #[inline] + pub fn downcast_mut(&'_ mut self) -> Option<&'_ mut T> { + self.upcast_any_mut().downcast_mut::() + } +} + +/// Error type for external users +#[derive(Error, Copy, Clone, Debug, PartialEq, Eq)] +pub enum FsError { + /// The fd given as a base was not a directory so the operation was not possible + #[error("fd not a directory")] + BaseNotDirectory, + /// Expected a file but found not a file + #[error("fd not a file")] + NotAFile, + /// The fd given was not usable + #[error("invalid fd")] + InvalidFd, + /// File exists + #[error("file exists")] + AlreadyExists, + /// The filesystem has failed to lock a resource. + #[error("lock error")] + Lock, + /// Something failed when doing IO. These errors can generally not be handled. + /// It may work if tried again. + #[error("io error")] + IOError, + /// The address was in use + #[error("address is in use")] + AddressInUse, + /// The address could not be found + #[error("address could not be found")] + AddressNotAvailable, + /// A pipe was closed + #[error("broken pipe (was closed)")] + BrokenPipe, + /// The connection was aborted + #[error("connection aborted")] + ConnectionAborted, + /// The connection request was refused + #[error("connection refused")] + ConnectionRefused, + /// The connection was reset + #[error("connection reset")] + ConnectionReset, + /// The operation was interrupted before it could finish + #[error("operation interrupted")] + Interrupted, + /// Invalid internal data, if the argument data is invalid, use `InvalidInput` + #[error("invalid internal data")] + InvalidData, + /// The provided data is invalid + #[error("invalid input")] + InvalidInput, + /// Could not perform the operation because there was not an open connection + #[error("connection is not open")] + NotConnected, + /// The requested file or directory could not be found + #[error("entity not found")] + EntityNotFound, + /// The requested device couldn't be accessed + #[error("can't access device")] + NoDevice, + /// Caller was not allowed to perform this operation + #[error("permission denied")] + PermissionDenied, + /// The operation did not complete within the given amount of time + #[error("time out")] + TimedOut, + /// Found EOF when EOF was not expected + #[error("unexpected eof")] + UnexpectedEof, + /// Operation would block, this error lets the caller know that they can try again + #[error("blocking operation. try again")] + WouldBlock, + /// A call to write returned 0 + #[error("write returned 0")] + WriteZero, + /// Directory not Empty + #[error("directory not empty")] + DirectoryNotEmpty, + /// Some other unhandled error. If you see this, it's probably a bug. + #[error("unknown error found")] + UnknownError, +} + +impl From for FsError { + fn from(io_error: io::Error) -> Self { + match io_error.kind() { + io::ErrorKind::AddrInUse => FsError::AddressInUse, + io::ErrorKind::AddrNotAvailable => FsError::AddressNotAvailable, + io::ErrorKind::AlreadyExists => FsError::AlreadyExists, + io::ErrorKind::BrokenPipe => FsError::BrokenPipe, + io::ErrorKind::ConnectionAborted => FsError::ConnectionAborted, + io::ErrorKind::ConnectionRefused => FsError::ConnectionRefused, + io::ErrorKind::ConnectionReset => FsError::ConnectionReset, + io::ErrorKind::Interrupted => FsError::Interrupted, + io::ErrorKind::InvalidData => FsError::InvalidData, + io::ErrorKind::InvalidInput => FsError::InvalidInput, + io::ErrorKind::NotConnected => FsError::NotConnected, + io::ErrorKind::NotFound => FsError::EntityNotFound, + io::ErrorKind::PermissionDenied => FsError::PermissionDenied, + io::ErrorKind::TimedOut => FsError::TimedOut, + io::ErrorKind::UnexpectedEof => FsError::UnexpectedEof, + io::ErrorKind::WouldBlock => FsError::WouldBlock, + io::ErrorKind::WriteZero => FsError::WriteZero, + io::ErrorKind::Other => FsError::IOError, + // if the following triggers, a new error type was added to this non-exhaustive enum + _ => FsError::UnknownError, + } + } +} + +#[derive(Debug)] +pub struct ReadDir { + // TODO: to do this properly we need some kind of callback to the core FS abstraction + data: Vec, + index: usize, +} + +impl ReadDir { + pub fn new(data: Vec) -> Self { + Self { data, index: 0 } + } +} + +#[derive(Debug, Clone)] +pub struct DirEntry { + pub path: PathBuf, + // weird hack, to fix this we probably need an internal trait object or callbacks or something + pub metadata: Result, +} + +impl DirEntry { + pub fn path(&self) -> PathBuf { + self.path.clone() + } + + pub fn metadata(&self) -> Result { + self.metadata.clone() + } + + pub fn file_type(&self) -> Result { + let metadata = self.metadata.clone()?; + Ok(metadata.file_type()) + } + + pub fn file_name(&self) -> OsString { + self.path + .file_name() + .unwrap_or_else(|| self.path.as_os_str()) + .to_owned() + } +} + +#[allow(clippy::len_without_is_empty)] // Clippy thinks it's an iterator. +#[derive(Clone, Debug, Default)] +// TODO: review this, proper solution would probably use a trait object internally +pub struct Metadata { + pub ft: FileType, + pub accessed: u64, + pub created: u64, + pub modified: u64, + pub len: u64, +} + +impl Metadata { + pub fn is_file(&self) -> bool { + self.ft.is_file() + } + + pub fn is_dir(&self) -> bool { + self.ft.is_dir() + } + + pub fn accessed(&self) -> u64 { + self.accessed + } + + pub fn created(&self) -> u64 { + self.created + } + + pub fn modified(&self) -> u64 { + self.modified + } + + pub fn file_type(&self) -> FileType { + self.ft.clone() + } + + pub fn len(&self) -> u64 { + self.len + } +} + +#[derive(Clone, Debug, Default)] +// TODO: review this, proper solution would probably use a trait object internally +pub struct FileType { + pub dir: bool, + pub file: bool, + pub symlink: bool, + // TODO: the following 3 only exist on unix in the standard FS API. + // We should mirror that API and extend with that trait too. + pub char_device: bool, + pub block_device: bool, + pub socket: bool, + pub fifo: bool, +} + +impl FileType { + pub fn is_dir(&self) -> bool { + self.dir + } + pub fn is_file(&self) -> bool { + self.file + } + pub fn is_symlink(&self) -> bool { + self.symlink + } + pub fn is_char_device(&self) -> bool { + self.char_device + } + pub fn is_block_device(&self) -> bool { + self.block_device + } + pub fn is_socket(&self) -> bool { + self.socket + } + pub fn is_fifo(&self) -> bool { + self.fifo + } +} + +impl Iterator for ReadDir { + type Item = Result; + + fn next(&mut self) -> Option> { + if let Some(v) = self.data.get(self.index).cloned() { + self.index += 1; + return Some(Ok(v)); + } + None + } +} diff --git a/lib/vfs/src/mem_fs/file.rs b/lib/vfs/src/mem_fs/file.rs new file mode 100644 index 00000000000..58474665f22 --- /dev/null +++ b/lib/vfs/src/mem_fs/file.rs @@ -0,0 +1,965 @@ +//! This module contains the `FileHandle` and `File` +//! implementations. They aren't exposed to the public API. Only +//! `FileHandle` can be used through the `VirtualFile` trait object. + +use super::*; +use crate::{FileDescriptor, FsError, Result, VirtualFile}; +use std::cmp; +use std::convert::TryInto; +use std::fmt; +use std::io::{self, Read, Seek, Write}; +use std::str; + +/// A file handle. The file system doesn't return the [`File`] type +/// directly, but rather this `FileHandle` type, which contains the +/// inode, the flags, and (a light copy of) the filesystem. For each +/// operations, it is checked that the permissions allow the +/// operations to be executed, and then it is checked that the file +/// still exists in the file system. After that, the operation is +/// delegated to the file itself. +#[derive(Clone)] +pub(super) struct FileHandle { + inode: Inode, + filesystem: FileSystem, + readable: bool, + writable: bool, +} + +impl FileHandle { + pub(super) fn new( + inode: Inode, + filesystem: FileSystem, + readable: bool, + writable: bool, + ) -> Self { + Self { + inode, + filesystem, + readable, + writable, + } + } +} + +impl VirtualFile for FileHandle { + fn last_accessed(&self) -> u64 { + let fs = match self.filesystem.inner.try_read() { + Ok(fs) => fs, + _ => return 0, + }; + + let node = match fs.storage.get(self.inode) { + Some(node) => node, + _ => return 0, + }; + + node.metadata().accessed + } + + fn last_modified(&self) -> u64 { + let fs = match self.filesystem.inner.try_read() { + Ok(fs) => fs, + _ => return 0, + }; + + let node = match fs.storage.get(self.inode) { + Some(node) => node, + _ => return 0, + }; + + node.metadata().modified + } + + fn created_time(&self) -> u64 { + let fs = match self.filesystem.inner.try_read() { + Ok(fs) => fs, + _ => return 0, + }; + + let node = match fs.storage.get(self.inode) { + Some(node) => node, + _ => return 0, + }; + + node.metadata().created + } + + fn size(&self) -> u64 { + let fs = match self.filesystem.inner.try_read() { + Ok(fs) => fs, + _ => return 0, + }; + + match fs.storage.get(self.inode) { + Some(Node::File { file, .. }) => file.buffer.len().try_into().unwrap_or(0), + _ => 0, + } + } + + fn set_len(&mut self, new_size: u64) -> Result<()> { + let mut fs = self + .filesystem + .inner + .try_write() + .map_err(|_| FsError::Lock)?; + + match fs.storage.get_mut(self.inode) { + Some(Node::File { file, .. }) => file + .buffer + .resize(new_size.try_into().map_err(|_| FsError::UnknownError)?, 0), + _ => return Err(FsError::NotAFile), + } + + Ok(()) + } + + fn unlink(&mut self) -> Result<()> { + let (inode_of_parent, position, inode_of_file) = { + // Read lock. + let fs = self + .filesystem + .inner + .try_read() + .map_err(|_| FsError::Lock)?; + + // The inode of the file. + let inode_of_file = self.inode; + + // Find the position of the file in the parent, and the + // inode of the parent. + let (position, inode_of_parent) = fs + .storage + .iter() + .find_map(|(inode_of_parent, node)| match node { + Node::Directory { children, .. } => { + children.iter().enumerate().find_map(|(nth, inode)| { + if inode == &inode_of_file { + Some((nth, inode_of_parent)) + } else { + None + } + }) + } + + _ => None, + }) + .ok_or(FsError::BaseNotDirectory)?; + + (inode_of_parent, position, inode_of_file) + }; + + { + // Write lock. + let mut fs = self + .filesystem + .inner + .try_write() + .map_err(|_| FsError::Lock)?; + + // Remove the file from the storage. + fs.storage.remove(inode_of_file); + + // Remove the child from the parent directory. + fs.remove_child_from_node(inode_of_parent, position)?; + } + + Ok(()) + } + + fn bytes_available(&self) -> Result { + let fs = self + .filesystem + .inner + .try_read() + .map_err(|_| FsError::Lock)?; + + match fs.storage.get(self.inode) { + Some(Node::File { file, .. }) => Ok(file.buffer.len() - file.cursor), + _ => Err(FsError::NotAFile), + } + } + + fn get_fd(&self) -> Option { + Some(FileDescriptor(self.inode)) + } +} + +#[cfg(test)] +mod test_virtual_file { + use crate::{mem_fs::*, FileDescriptor, FileSystem as FS}; + use std::thread::sleep; + use std::time::Duration; + + macro_rules! path { + ($path:expr) => { + std::path::Path::new($path) + }; + } + + #[test] + fn test_last_accessed() { + let fs = FileSystem::default(); + + let file = fs + .new_open_options() + .write(true) + .create_new(true) + .open(path!("/foo.txt")) + .expect("failed to create a new file"); + let last_accessed_time = file.last_accessed(); + + assert!(last_accessed_time > 0, "last accessed time is not zero"); + + sleep(Duration::from_secs(3)); + + let file = fs + .new_open_options() + .read(true) + .open(path!("/foo.txt")) + .expect("failed to open a file"); + let next_last_accessed_time = file.last_accessed(); + + assert!( + next_last_accessed_time > last_accessed_time, + "the last accessed time is updated" + ); + } + + #[test] + fn test_last_modified() { + let fs = FileSystem::default(); + + let file = fs + .new_open_options() + .write(true) + .create_new(true) + .open(path!("/foo.txt")) + .expect("failed to create a new file"); + + assert!(file.last_modified() > 0, "last modified time is not zero"); + } + + #[test] + fn test_created_time() { + let fs = FileSystem::default(); + + let file = fs + .new_open_options() + .write(true) + .create_new(true) + .open(path!("/foo.txt")) + .expect("failed to create a new file"); + let created_time = file.created_time(); + + assert!(created_time > 0, "created time is not zero"); + + let file = fs + .new_open_options() + .read(true) + .open(path!("/foo.txt")) + .expect("failed to create a new file"); + let next_created_time = file.created_time(); + + assert_eq!( + next_created_time, created_time, + "created time stays constant" + ); + } + + #[test] + fn test_size() { + let fs = FileSystem::default(); + + let file = fs + .new_open_options() + .write(true) + .create_new(true) + .open(path!("/foo.txt")) + .expect("failed to create a new file"); + + assert_eq!(file.size(), 0, "new file is empty"); + } + + #[test] + fn test_set_len() { + let fs = FileSystem::default(); + + let mut file = fs + .new_open_options() + .write(true) + .create_new(true) + .open(path!("/foo.txt")) + .expect("failed to create a new file"); + + assert!(matches!(file.set_len(7), Ok(())), "setting a new length"); + assert_eq!(file.size(), 7, "file has a new length"); + } + + #[test] + fn test_unlink() { + let fs = FileSystem::default(); + + let mut file = fs + .new_open_options() + .write(true) + .create_new(true) + .open(path!("/foo.txt")) + .expect("failed to create a new file"); + + { + let fs_inner = fs.inner.read().unwrap(); + + assert_eq!(fs_inner.storage.len(), 2, "storage has the new file"); + assert!( + matches!( + fs_inner.storage.get(ROOT_INODE), + Some(Node::Directory { + inode: ROOT_INODE, + name, + children, + .. + }) if name == "/" && children == &[1] + ), + "`/` contains `foo.txt`", + ); + assert!( + matches!( + fs_inner.storage.get(1), + Some(Node::File { + inode: 1, + name, + .. + }) if name == "foo.txt" + ), + "`foo.txt` exists and is a file", + ); + } + + assert_eq!(file.unlink(), Ok(()), "unlinking the file"); + + { + let fs_inner = fs.inner.read().unwrap(); + + assert_eq!( + fs_inner.storage.len(), + 1, + "storage no longer has the new file" + ); + assert!( + matches!( + fs_inner.storage.get(ROOT_INODE), + Some(Node::Directory { + inode: ROOT_INODE, + name, + children, + .. + }) if name == "/" && children.is_empty() + ), + "`/` is empty", + ); + } + } + + #[test] + fn test_bytes_available() { + let fs = FileSystem::default(); + + let mut file = fs + .new_open_options() + .write(true) + .create_new(true) + .open(path!("/foo.txt")) + .expect("failed to create a new file"); + + assert_eq!(file.bytes_available(), Ok(0), "zero bytes available"); + assert_eq!(file.set_len(7), Ok(()), "resizing the file"); + assert_eq!(file.bytes_available(), Ok(7), "seven bytes available"); + } + + #[test] + fn test_fd() { + let fs = FileSystem::default(); + + let file = fs + .new_open_options() + .write(true) + .create_new(true) + .open(path!("/foo.txt")) + .expect("failed to create a new file"); + + assert!( + matches!(file.get_fd(), Some(FileDescriptor(1))), + "reading the file descriptor", + ); + } +} + +impl Read for FileHandle { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + if !self.readable { + return Err(io::Error::new( + io::ErrorKind::PermissionDenied, + format!( + "the file (inode `{}) doesn't have the `read` permission", + self.inode + ), + )); + } + + let mut fs = + self.filesystem.inner.try_write().map_err(|_| { + io::Error::new(io::ErrorKind::Other, "failed to acquire a write lock") + })?; + + let file = match fs.storage.get_mut(self.inode) { + Some(Node::File { file, .. }) => file, + _ => { + return Err(io::Error::new( + io::ErrorKind::NotFound, + format!("inode `{}` doesn't match a file", self.inode), + )) + } + }; + + file.read(buf) + } + + fn read_to_end(&mut self, buf: &mut Vec) -> io::Result { + if !self.readable { + return Err(io::Error::new( + io::ErrorKind::PermissionDenied, + format!( + "the file (inode `{}) doesn't have the `read` permission", + self.inode + ), + )); + } + + let mut fs = + self.filesystem.inner.try_write().map_err(|_| { + io::Error::new(io::ErrorKind::Other, "failed to acquire a write lock") + })?; + + let file = match fs.storage.get_mut(self.inode) { + Some(Node::File { file, .. }) => file, + _ => { + return Err(io::Error::new( + io::ErrorKind::NotFound, + format!("inode `{}` doesn't match a file", self.inode), + )) + } + }; + + file.read_to_end(buf) + } + + fn read_to_string(&mut self, buf: &mut String) -> io::Result { + // SAFETY: `String::as_mut_vec` cannot check that modifcations + // of the `Vec` will produce a valid UTF-8 string. In our + // case, we use `str::from_utf8` to ensure that the UTF-8 + // constraint still hold before returning. + let mut bytes_buffer = unsafe { buf.as_mut_vec() }; + bytes_buffer.clear(); + let read = self.read_to_end(&mut bytes_buffer)?; + + if str::from_utf8(&bytes_buffer).is_err() { + Err(io::Error::new( + io::ErrorKind::InvalidData, + "buffer did not contain valid UTF-8", + )) + } else { + Ok(read) + } + } + + fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> { + if !self.readable { + return Err(io::Error::new( + io::ErrorKind::PermissionDenied, + format!( + "the file (inode `{}) doesn't have the `read` permission", + self.inode + ), + )); + } + + let mut fs = + self.filesystem.inner.try_write().map_err(|_| { + io::Error::new(io::ErrorKind::Other, "failed to acquire a write lock") + })?; + + let file = match fs.storage.get_mut(self.inode) { + Some(Node::File { file, .. }) => file, + _ => { + return Err(io::Error::new( + io::ErrorKind::NotFound, + format!("inode `{}` doesn't match a file", self.inode), + )) + } + }; + + file.read_exact(buf) + } +} + +impl Seek for FileHandle { + fn seek(&mut self, position: io::SeekFrom) -> io::Result { + let mut fs = + self.filesystem.inner.try_write().map_err(|_| { + io::Error::new(io::ErrorKind::Other, "failed to acquire a write lock") + })?; + + let file = match fs.storage.get_mut(self.inode) { + Some(Node::File { file, .. }) => file, + _ => { + return Err(io::Error::new( + io::ErrorKind::NotFound, + format!("inode `{}` doesn't match a file", self.inode), + )) + } + }; + + file.seek(position) + } +} + +impl Write for FileHandle { + fn write(&mut self, buf: &[u8]) -> io::Result { + if !self.writable { + return Err(io::Error::new( + io::ErrorKind::PermissionDenied, + format!( + "the file (inode `{}) doesn't have the `write` permission", + self.inode + ), + )); + } + + let mut fs = + self.filesystem.inner.try_write().map_err(|_| { + io::Error::new(io::ErrorKind::Other, "failed to acquire a write lock") + })?; + + let file = match fs.storage.get_mut(self.inode) { + Some(Node::File { file, .. }) => file, + _ => { + return Err(io::Error::new( + io::ErrorKind::NotFound, + format!("inode `{}` doesn't match a file", self.inode), + )) + } + }; + + file.write(buf) + } + + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } + + #[allow(clippy::unused_io_amount)] + fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { + self.write(buf)?; + + Ok(()) + } +} + +#[cfg(test)] +mod test_read_write_seek { + use crate::{mem_fs::*, FileSystem as FS}; + use std::io; + + macro_rules! path { + ($path:expr) => { + std::path::Path::new($path) + }; + } + + #[test] + fn test_writing_at_various_positions() { + let fs = FileSystem::default(); + + let mut file = fs + .new_open_options() + .read(true) + .write(true) + .create_new(true) + .open(path!("/foo.txt")) + .expect("failed to create a new file"); + + assert!( + matches!(file.write(b"foo"), Ok(3)), + "writing `foo` at the end of the file", + ); + assert_eq!(file.size(), 3, "checking the size of the file"); + + assert!( + matches!(file.write(b"bar"), Ok(3)), + "writing `bar` at the end of the file", + ); + assert_eq!(file.size(), 6, "checking the size of the file"); + + assert!( + matches!(file.seek(io::SeekFrom::Start(0)), Ok(0)), + "seeking to 0", + ); + + assert!( + matches!(file.write(b"baz"), Ok(3)), + "writing `baz` at the beginning of the file", + ); + assert_eq!(file.size(), 9, "checking the size of the file"); + + assert!( + matches!(file.write(b"qux"), Ok(3)), + "writing `qux` in the middle of the file", + ); + assert_eq!(file.size(), 12, "checking the size of the file"); + + assert!( + matches!(file.seek(io::SeekFrom::Start(0)), Ok(0)), + "seeking to 0", + ); + + let mut string = String::new(); + assert!( + matches!(file.read_to_string(&mut string), Ok(12)), + "reading `bazquxfoobar`", + ); + assert_eq!(string, "bazquxfoobar"); + + assert!( + matches!(file.seek(io::SeekFrom::Current(-6)), Ok(6)), + "seeking to 6", + ); + + let mut string = String::new(); + assert!( + matches!(file.read_to_string(&mut string), Ok(6)), + "reading `foobar`", + ); + assert_eq!(string, "foobar"); + + assert!( + matches!(file.seek(io::SeekFrom::End(0)), Ok(12)), + "seeking to 12", + ); + + let mut string = String::new(); + assert!( + matches!(file.read_to_string(&mut string), Ok(0)), + "reading ``", + ); + assert_eq!(string, ""); + } + + #[test] + fn test_reading() { + let fs = FileSystem::default(); + + let mut file = fs + .new_open_options() + .read(true) + .write(true) + .create_new(true) + .open(path!("/foo.txt")) + .expect("failed to create a new file"); + + assert!( + matches!(file.write(b"foobarbazqux"), Ok(12)), + "writing `foobarbazqux`", + ); + + assert!( + matches!(file.seek(io::SeekFrom::Start(0)), Ok(0)), + "seeking to 0", + ); + + let mut buffer = [0; 6]; + assert!( + matches!(file.read(&mut buffer[..]), Ok(6)), + "reading 6 bytes", + ); + assert_eq!(buffer, b"foobar"[..], "checking the 6 bytes"); + + assert!( + matches!(file.seek(io::SeekFrom::Start(0)), Ok(0)), + "seeking to 0", + ); + + let mut buffer = [0; 16]; + assert!( + matches!(file.read(&mut buffer[..]), Ok(12)), + "reading more bytes than available", + ); + assert_eq!(buffer[..12], b"foobarbazqux"[..], "checking the 12 bytes"); + } + + #[test] + fn test_reading_to_the_end() { + let fs = FileSystem::default(); + + let mut file = fs + .new_open_options() + .read(true) + .write(true) + .create_new(true) + .open(path!("/foo.txt")) + .expect("failed to create a new file"); + + assert!( + matches!(file.write(b"foobarbazqux"), Ok(12)), + "writing `foobarbazqux`", + ); + + assert!( + matches!(file.seek(io::SeekFrom::Start(0)), Ok(0)), + "seeking to 0", + ); + + let mut buffer = Vec::new(); + assert!( + matches!(file.read_to_end(&mut buffer), Ok(12)), + "reading all bytes", + ); + assert_eq!(buffer, b"foobarbazqux"[..], "checking all the bytes"); + } + + #[test] + fn test_reading_to_string() { + let fs = FileSystem::default(); + + let mut file = fs + .new_open_options() + .read(true) + .write(true) + .create_new(true) + .open(path!("/foo.txt")) + .expect("failed to create a new file"); + + assert!( + matches!(file.write(b"foobarbazqux"), Ok(12)), + "writing `foobarbazqux`", + ); + + assert!( + matches!(file.seek(io::SeekFrom::Start(6)), Ok(6)), + "seeking to 0", + ); + + let mut string = String::new(); + assert!( + matches!(file.read_to_string(&mut string), Ok(6)), + "reading a string", + ); + assert_eq!(string, "bazqux", "checking the string"); + } + + #[test] + fn test_reading_exact_buffer() { + let fs = FileSystem::default(); + + let mut file = fs + .new_open_options() + .read(true) + .write(true) + .create_new(true) + .open(path!("/foo.txt")) + .expect("failed to create a new file"); + + assert!( + matches!(file.write(b"foobarbazqux"), Ok(12)), + "writing `foobarbazqux`", + ); + + assert!( + matches!(file.seek(io::SeekFrom::Start(6)), Ok(6)), + "seeking to 0", + ); + + let mut buffer = [0; 16]; + assert!( + matches!(file.read_exact(&mut buffer), Err(_)), + "failing to read an exact buffer", + ); + + assert!( + matches!(file.seek(io::SeekFrom::End(-5)), Ok(7)), + "seeking to 7", + ); + + let mut buffer = [0; 3]; + assert!( + matches!(file.read_exact(&mut buffer), Ok(())), + "failing to read an exact buffer", + ); + } +} + +impl fmt::Debug for FileHandle { + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + formatter + .debug_struct("FileHandle") + .field("inode", &self.inode) + .finish() + } +} + +/// The real file! It is simply a buffer of bytes with a cursor that +/// represents a read/write position in the buffer. +#[derive(Debug)] +pub(super) struct File { + buffer: Vec, + cursor: usize, +} + +impl File { + pub(super) fn new() -> Self { + Self { + buffer: Vec::new(), + cursor: 0, + } + } + + pub(super) fn truncate(&mut self) { + self.buffer.clear(); + self.cursor = 0; + } +} + +impl Read for File { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + let max_to_read = cmp::min(self.buffer.len() - self.cursor, buf.len()); + let data_to_copy = &self.buffer[self.cursor..][..max_to_read]; + + // SAFETY: `buf[..max_to_read]` and `data_to_copy` have the same size, due to + // how `max_to_read` is computed. + buf[..max_to_read].copy_from_slice(data_to_copy); + + self.cursor += max_to_read; + + Ok(max_to_read) + } + + fn read_to_end(&mut self, buf: &mut Vec) -> io::Result { + let data_to_copy = &self.buffer[self.cursor..]; + let max_to_read = data_to_copy.len(); + + // `buf` is too small to contain the data. Let's resize it. + if max_to_read > buf.len() { + // Let's resize the capacity if needed. + if max_to_read > buf.capacity() { + buf.reserve_exact(max_to_read - buf.capacity()); + } + + // SAFETY: The space is reserved, and it's going to be + // filled with `copy_from_slice` below. + unsafe { buf.set_len(max_to_read) } + } + + // SAFETY: `buf` and `data_to_copy` have the same size, see + // above. + buf.copy_from_slice(data_to_copy); + + self.cursor += max_to_read; + + Ok(max_to_read) + } + + fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> { + if buf.len() > (self.buffer.len() - self.cursor) { + return Err(io::Error::new( + io::ErrorKind::UnexpectedEof, + "not enough data available in file", + )); + } + + let max_to_read = cmp::min(buf.len(), self.buffer.len() - self.cursor); + let data_to_copy = &self.buffer[self.cursor..][..max_to_read]; + + // SAFETY: `buf` and `data_to_copy` have the same size. + buf.copy_from_slice(data_to_copy); + + self.cursor += data_to_copy.len(); + + Ok(()) + } +} + +impl Seek for File { + fn seek(&mut self, position: io::SeekFrom) -> io::Result { + let to_err = |_| io::ErrorKind::InvalidInput; + + // Calculate the next cursor. + let next_cursor: i64 = match position { + // Calculate from the beginning, so `0 + offset`. + io::SeekFrom::Start(offset) => offset.try_into().map_err(to_err)?, + + // Calculate from the end, so `buffer.len() + offset`. + io::SeekFrom::End(offset) => { + TryInto::::try_into(self.buffer.len()).map_err(to_err)? + offset + } + + // Calculate from the current cursor, so `cursor + offset`. + io::SeekFrom::Current(offset) => { + TryInto::::try_into(self.cursor).map_err(to_err)? + offset + } + }; + + // It's an error to seek before byte 0. + if next_cursor < 0 { + return Err(io::Error::new( + io::ErrorKind::InvalidInput, + "seeking before the byte 0", + )); + } + + // In this implementation, it's an error to seek beyond the + // end of the buffer. + self.cursor = cmp::min(self.buffer.len(), next_cursor.try_into().map_err(to_err)?); + + Ok(self.cursor.try_into().map_err(to_err)?) + } +} + +impl Write for File { + fn write(&mut self, buf: &[u8]) -> io::Result { + match self.cursor { + // The cursor is at the end of the buffer: happy path! + position if position == self.buffer.len() => { + self.buffer.extend_from_slice(buf); + self.cursor += buf.len(); + } + + // The cursor is at the beginning of the buffer (and the + // buffer is not empty, otherwise it would have been + // caught by the previous arm): almost a happy path! + 0 => { + let mut new_buffer = Vec::with_capacity(self.buffer.len() + buf.len()); + new_buffer.extend_from_slice(buf); + new_buffer.append(&mut self.buffer); + + self.buffer = new_buffer; + self.cursor += buf.len(); + } + + // The cursor is somewhere in the buffer: not the happy path. + position => { + self.buffer.reserve_exact(buf.len()); + + let mut remainder = self.buffer.split_off(position); + self.buffer.extend_from_slice(buf); + self.buffer.append(&mut remainder); + + self.cursor += buf.len(); + } + } + + Ok(buf.len()) + } + + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } +} diff --git a/lib/vfs/src/mem_fs/file_opener.rs b/lib/vfs/src/mem_fs/file_opener.rs new file mode 100644 index 00000000000..08348aabfa4 --- /dev/null +++ b/lib/vfs/src/mem_fs/file_opener.rs @@ -0,0 +1,384 @@ +use super::*; +use crate::{FileType, FsError, Metadata, OpenOptionsConfig, Result, VirtualFile}; +use std::io::{self, Seek}; +use std::path::Path; + +/// The type that is responsible to open a file. +#[derive(Debug, Clone)] +pub struct FileOpener { + pub(super) filesystem: FileSystem, +} + +impl crate::FileOpener for FileOpener { + fn open(&mut self, path: &Path, conf: &OpenOptionsConfig) -> Result> { + let read = conf.read(); + let mut write = conf.write(); + let append = conf.append(); + let mut truncate = conf.truncate(); + let mut create = conf.create(); + let create_new = conf.create_new(); + + // If `create_new` is used, `create` and `truncate ` are ignored. + if create_new { + create = false; + truncate = false; + } + + // To truncate a file, `write` must be used. + if truncate && !write { + return Err(FsError::PermissionDenied); + } + + // `append` is semantically equivalent to `write` + `append` + // but let's keep them exclusive. + if append { + write = false; + } + + let (inode_of_parent, maybe_inode_of_file, name_of_file) = { + // Read lock. + let fs = self + .filesystem + .inner + .try_read() + .map_err(|_| FsError::Lock)?; + + // Check the path has a parent. + let parent_of_path = path.parent().ok_or(FsError::BaseNotDirectory)?; + + // Check the file name. + let name_of_file = path + .file_name() + .ok_or(FsError::InvalidInput)? + .to_os_string(); + + // Find the parent inode. + let inode_of_parent = fs.inode_of_parent(parent_of_path)?; + + // Find the inode of the file if it exists. + let maybe_inode_of_file = fs + .from_parent_get_position_and_inode_of_file(inode_of_parent, &name_of_file)? + .map(|(_nth, inode)| inode); + + (inode_of_parent, maybe_inode_of_file, name_of_file) + }; + + let inode_of_file = match maybe_inode_of_file { + // The file already exists, and a _new_ one _must_ be + // created; it's not OK. + Some(_inode_of_file) if create_new => return Err(FsError::AlreadyExists), + + // The file already exists; it's OK. + Some(inode_of_file) => { + // Write lock. + let mut fs = self + .filesystem + .inner + .try_write() + .map_err(|_| FsError::Lock)?; + + match fs.storage.get_mut(inode_of_file) { + Some(Node::File { metadata, file, .. }) => { + // Update the accessed time. + metadata.accessed = time(); + + // Truncate if needed. + if truncate { + file.truncate(); + } + + // Move the cursor to the end if needed. + if append { + file.seek(io::SeekFrom::End(0))?; + } + } + + _ => return Err(FsError::NotAFile), + } + + inode_of_file + } + + // The file doesn't already exist; it's OK to create it if: + // 1. `create_new` is used with `write` or `append`, + // 2. `create` is used with `write` or `append`. + None if (create_new || create) && (write || append) => { + // Write lock. + let mut fs = self + .filesystem + .inner + .try_write() + .map_err(|_| FsError::Lock)?; + + let file = File::new(); + + // Creating the file in the storage. + let inode_of_file = fs.storage.vacant_entry().key(); + let real_inode_of_file = fs.storage.insert(Node::File { + inode: inode_of_file, + name: name_of_file, + file, + metadata: { + let time = time(); + + Metadata { + ft: FileType { + file: true, + ..Default::default() + }, + accessed: time, + created: time, + modified: time, + len: 0, + } + }, + }); + + assert_eq!( + inode_of_file, real_inode_of_file, + "new file inode should have been correctly calculated", + ); + + // Adding the new directory to its parent. + fs.add_child_to_node(inode_of_parent, inode_of_file)?; + + inode_of_file + } + + None => return Err(FsError::PermissionDenied), + }; + + Ok(Box::new(FileHandle::new( + inode_of_file, + self.filesystem.clone(), + read, + write || append || truncate, + ))) + } +} + +#[cfg(test)] +mod test_file_opener { + use crate::{mem_fs::*, FileSystem as FS, FsError}; + use std::io; + + macro_rules! path { + ($path:expr) => { + std::path::Path::new($path) + }; + } + + #[test] + fn test_create_new_file() { + let fs = FileSystem::default(); + + assert!( + matches!( + fs.new_open_options() + .write(true) + .create_new(true) + .open(path!("/foo.txt")), + Ok(_), + ), + "creating a new file", + ); + + { + let fs_inner = fs.inner.read().unwrap(); + + assert_eq!(fs_inner.storage.len(), 2, "storage has the new file"); + assert!( + matches!( + fs_inner.storage.get(ROOT_INODE), + Some(Node::Directory { + inode: ROOT_INODE, + name, + children, + .. + }) if name == "/" && children == &[1] + ), + "`/` contains `foo.txt`", + ); + assert!( + matches!( + fs_inner.storage.get(1), + Some(Node::File { + inode: 1, + name, + .. + }) if name == "foo.txt" + ), + "`foo.txt` exists and is a file", + ); + } + + assert!( + matches!( + fs.new_open_options() + .write(true) + .create_new(true) + .open(path!("/foo.txt")), + Err(FsError::AlreadyExists) + ), + "creating a new file that already exist", + ); + + assert!( + matches!( + fs.new_open_options() + .write(true) + .create_new(true) + .open(path!("/foo/bar.txt")), + Err(FsError::NotAFile), + ), + "creating a file in a directory that doesn't exist", + ); + + assert_eq!(fs.remove_file(path!("/foo.txt")), Ok(()), "removing a file"); + + assert!( + matches!( + fs.new_open_options() + .write(false) + .create_new(true) + .open(path!("/foo.txt")), + Err(FsError::PermissionDenied), + ), + "creating a file without the `write` option", + ); + } + + #[test] + fn test_truncate_a_read_only_file() { + let fs = FileSystem::default(); + + assert!( + matches!( + fs.new_open_options() + .write(false) + .truncate(true) + .open(path!("/foo.txt")), + Err(FsError::PermissionDenied), + ), + "truncating a read-only file", + ); + } + + #[test] + fn test_truncate() { + let fs = FileSystem::default(); + + let mut file = fs + .new_open_options() + .write(true) + .create_new(true) + .open(path!("/foo.txt")) + .expect("failed to create a new file"); + + assert!( + matches!(file.write(b"foobar"), Ok(6)), + "writing `foobar` at the end of the file", + ); + + assert!( + matches!(file.seek(io::SeekFrom::Current(0)), Ok(6)), + "checking the current position is 6", + ); + assert!( + matches!(file.seek(io::SeekFrom::End(0)), Ok(6)), + "checking the size is 6", + ); + + let mut file = fs + .new_open_options() + .write(true) + .truncate(true) + .open(path!("/foo.txt")) + .expect("failed to open + truncate `foo.txt`"); + + assert!( + matches!(file.seek(io::SeekFrom::Current(0)), Ok(0)), + "checking the current position is 0", + ); + assert!( + matches!(file.seek(io::SeekFrom::End(0)), Ok(0)), + "checking the size is 0", + ); + } + + #[test] + fn test_append() { + let fs = FileSystem::default(); + + let mut file = fs + .new_open_options() + .write(true) + .create_new(true) + .open(path!("/foo.txt")) + .expect("failed to create a new file"); + + assert!( + matches!(file.write(b"foobar"), Ok(6)), + "writing `foobar` at the end of the file", + ); + + assert!( + matches!(file.seek(io::SeekFrom::Current(0)), Ok(6)), + "checking the current position is 6", + ); + assert!( + matches!(file.seek(io::SeekFrom::End(0)), Ok(6)), + "checking the size is 6", + ); + + let mut file = fs + .new_open_options() + .write(true) + .append(true) + .open(path!("/foo.txt")) + .expect("failed to open `foo.txt`"); + + assert!( + matches!(file.seek(io::SeekFrom::Current(0)), Ok(6)), + "checking the current position is 6", + ); + assert!( + matches!(file.seek(io::SeekFrom::End(0)), Ok(6)), + "checking the size is 6", + ); + } + + #[test] + fn test_opening_a_file_that_already_exists() { + let fs = FileSystem::default(); + + assert!( + matches!( + fs.new_open_options() + .write(true) + .create_new(true) + .open(path!("/foo.txt")), + Ok(_), + ), + "creating a _new_ file", + ); + + assert!( + matches!( + fs.new_open_options() + .create_new(true) + .open(path!("/foo.txt")), + Err(FsError::AlreadyExists), + ), + "creating a _new_ file that already exists", + ); + + assert!( + matches!( + fs.new_open_options().read(true).open(path!("/foo.txt")), + Ok(_), + ), + "opening a file that already exists", + ); + } +} diff --git a/lib/vfs/src/mem_fs/filesystem.rs b/lib/vfs/src/mem_fs/filesystem.rs new file mode 100644 index 00000000000..6f08142ce76 --- /dev/null +++ b/lib/vfs/src/mem_fs/filesystem.rs @@ -0,0 +1,1264 @@ +//! This module contains the [`FileSystem`] type itself. + +use super::*; +use crate::{DirEntry, FileType, FsError, Metadata, OpenOptions, ReadDir, Result}; +use slab::Slab; +use std::convert::identity; +use std::ffi::OsString; +use std::fmt; +use std::path::{Component, Path, PathBuf}; +use std::sync::{Arc, RwLock}; + +/// The in-memory file system! +/// +/// It's a thin wrapper around [`FileSystemInner`]. This `FileSystem` +/// type can be cloned, it's a light copy of the `FileSystemInner` +/// (which is behind a `Arc` + `RwLock`. +#[derive(Clone, Default)] +pub struct FileSystem { + pub(super) inner: Arc>, +} + +impl crate::FileSystem for FileSystem { + fn read_dir(&self, path: &Path) -> Result { + // Read lock. + let fs = self.inner.try_read().map_err(|_| FsError::Lock)?; + + // Canonicalize the path. + let (path, inode_of_directory) = fs.canonicalize(path)?; + + // Check it's a directory and fetch the immediate children as `DirEntry`. + let children = match fs.storage.get(inode_of_directory) { + Some(Node::Directory { children, .. }) => children + .iter() + .filter_map(|inode| fs.storage.get(*inode)) + .map(|node| DirEntry { + path: { + let mut entry_path = path.to_path_buf(); + entry_path.push(node.name()); + + entry_path + }, + metadata: Ok(node.metadata().clone()), + }) + .collect(), + + _ => return Err(FsError::InvalidInput), + }; + + Ok(ReadDir::new(children)) + } + + fn create_dir(&self, path: &Path) -> Result<()> { + let (inode_of_parent, name_of_directory) = { + // Read lock. + let fs = self.inner.try_read().map_err(|_| FsError::Lock)?; + + // Canonicalize the path without checking the path exists, + // because it's about to be created. + let path = fs.canonicalize_without_inode(path)?; + + // Check the path has a parent. + let parent_of_path = path.parent().ok_or(FsError::BaseNotDirectory)?; + + // Check the directory name. + let name_of_directory = path + .file_name() + .ok_or(FsError::InvalidInput)? + .to_os_string(); + + // Find the parent inode. + let inode_of_parent = fs.inode_of_parent(parent_of_path)?; + + (inode_of_parent, name_of_directory) + }; + + { + // Write lock. + let mut fs = self.inner.try_write().map_err(|_| FsError::Lock)?; + + // Creating the directory in the storage. + let inode_of_directory = fs.storage.vacant_entry().key(); + let real_inode_of_directory = fs.storage.insert(Node::Directory { + inode: inode_of_directory, + name: name_of_directory, + children: Vec::new(), + metadata: { + let time = time(); + + Metadata { + ft: FileType { + dir: true, + ..Default::default() + }, + accessed: time, + created: time, + modified: time, + len: 0, + } + }, + }); + + assert_eq!( + inode_of_directory, real_inode_of_directory, + "new directory inode should have been correctly calculated", + ); + + // Adding the new directory to its parent. + fs.add_child_to_node(inode_of_parent, inode_of_directory)?; + } + + Ok(()) + } + + fn remove_dir(&self, path: &Path) -> Result<()> { + let (inode_of_parent, position, inode_of_directory) = { + // Read lock. + let fs = self.inner.try_read().map_err(|_| FsError::Lock)?; + + // Canonicalize the path. + let (path, _) = fs.canonicalize(path)?; + + // Check the path has a parent. + let parent_of_path = path.parent().ok_or(FsError::BaseNotDirectory)?; + + // Check the directory name. + let name_of_directory = path + .file_name() + .ok_or(FsError::InvalidInput)? + .to_os_string(); + + // Find the parent inode. + let inode_of_parent = fs.inode_of_parent(parent_of_path)?; + + // Get the child index to remove in the parent node, in + // addition to the inode of the directory to remove. + let (position, inode_of_directory) = fs + .from_parent_get_position_and_inode_of_directory( + inode_of_parent, + &name_of_directory, + DirectoryMustBeEmpty::Yes, + )?; + + (inode_of_parent, position, inode_of_directory) + }; + + { + // Write lock. + let mut fs = self.inner.try_write().map_err(|_| FsError::Lock)?; + + // Remove the directory from the storage. + fs.storage.remove(inode_of_directory); + + // Remove the child from the parent directory. + fs.remove_child_from_node(inode_of_parent, position)?; + } + + Ok(()) + } + + fn rename(&self, from: &Path, to: &Path) -> Result<()> { + let ( + (position_of_from, inode, inode_of_from_parent), + (inode_of_to_parent, name_of_to_directory), + ) = { + // Read lock. + let fs = self.inner.try_read().map_err(|_| FsError::Lock)?; + + let from = fs.canonicalize_without_inode(from)?; + let to = fs.canonicalize_without_inode(to)?; + + // Check the paths have parents. + let parent_of_from = from.parent().ok_or(FsError::BaseNotDirectory)?; + let parent_of_to = to.parent().ok_or(FsError::BaseNotDirectory)?; + + // Check the directory names. + let name_of_from_directory = from + .file_name() + .ok_or(FsError::InvalidInput)? + .to_os_string(); + let name_of_to_directory = to.file_name().ok_or(FsError::InvalidInput)?.to_os_string(); + + // Find the parent inodes. + let inode_of_from_parent = fs.inode_of_parent(parent_of_from)?; + let inode_of_to_parent = fs.inode_of_parent(parent_of_to)?; + + // Get the child indexes to update in the parent nodes, in + // addition to the inode of the directory to update. + let (position_of_from, inode) = fs.from_parent_get_position_and_inode_of_directory( + inode_of_from_parent, + &name_of_from_directory, + DirectoryMustBeEmpty::No, + )?; + + ( + (position_of_from, inode, inode_of_from_parent), + (inode_of_to_parent, name_of_to_directory), + ) + }; + + { + // Write lock. + let mut fs = self.inner.try_write().map_err(|_| FsError::Lock)?; + + // Update the directory name, and update the modified + // time. + fs.update_node_name(inode, name_of_to_directory)?; + + // Remove the directory from its parent, and update the + // modified time. + fs.remove_child_from_node(inode_of_from_parent, position_of_from)?; + + // Add the directory to its new parent, and update the + // modified time. + fs.add_child_to_node(inode_of_to_parent, inode)?; + } + + Ok(()) + } + + fn metadata(&self, path: &Path) -> Result { + // Read lock. + let fs = self.inner.try_read().map_err(|_| FsError::Lock)?; + + Ok(fs + .storage + .get(fs.inode_of(path)?) + .ok_or(FsError::UnknownError)? + .metadata() + .clone()) + } + + fn remove_file(&self, path: &Path) -> Result<()> { + let (inode_of_parent, position, inode_of_file) = { + // Read lock. + let fs = self.inner.try_read().map_err(|_| FsError::Lock)?; + + // Canonicalize the path. + let path = fs.canonicalize_without_inode(path)?; + + // Check the path has a parent. + let parent_of_path = path.parent().ok_or(FsError::BaseNotDirectory)?; + + // Check the file name. + let name_of_file = path + .file_name() + .ok_or(FsError::InvalidInput)? + .to_os_string(); + + // Find the parent inode. + let inode_of_parent = fs.inode_of_parent(parent_of_path)?; + + // Find the inode of the file if it exists, along with its position. + let maybe_position_and_inode_of_file = + fs.from_parent_get_position_and_inode_of_file(inode_of_parent, &name_of_file)?; + + match maybe_position_and_inode_of_file { + Some((position, inode_of_file)) => (inode_of_parent, position, inode_of_file), + None => return Err(FsError::NotAFile), + } + }; + + { + // Write lock. + let mut fs = self.inner.try_write().map_err(|_| FsError::Lock)?; + + // Remove the file from the storage. + fs.storage.remove(inode_of_file); + + // Remove the child from the parent directory. + fs.remove_child_from_node(inode_of_parent, position)?; + } + + Ok(()) + } + + fn new_open_options(&self) -> OpenOptions { + OpenOptions::new(Box::new(FileOpener { + filesystem: self.clone(), + })) + } +} + +impl fmt::Debug for FileSystem { + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + let fs: &FileSystemInner = &self.inner.read().unwrap(); + + fs.fmt(formatter) + } +} + +/// The core of the file system. It contains a collection of `Node`s, +/// indexed by their respective `Inode` in a slab. +pub(super) struct FileSystemInner { + pub(super) storage: Slab, +} + +impl FileSystemInner { + /// Get the inode associated to a path if it exists. + pub(super) fn inode_of(&self, path: &Path) -> Result { + // SAFETY: The root node always exists, so it's safe to unwrap here. + let mut node = self.storage.get(ROOT_INODE).unwrap(); + let mut components = path.components(); + + match components.next() { + Some(Component::RootDir) => {} + _ => return Err(FsError::BaseNotDirectory), + } + + for component in components { + node = match node { + Node::Directory { children, .. } => children + .iter() + .filter_map(|inode| self.storage.get(*inode)) + .find_map(|node| { + if node.name() == component.as_os_str() { + Some(node) + } else { + None + } + }) + .ok_or(FsError::NotAFile)?, + _ => return Err(FsError::BaseNotDirectory), + }; + } + + Ok(node.inode()) + } + + /// Get the inode associated to a “parent path”. The returned + /// inode necessarily represents a directory. + pub(super) fn inode_of_parent(&self, parent_path: &Path) -> Result { + let inode_of_parent = self.inode_of(parent_path)?; + + // Ensure it is a directory. + match self.storage.get(inode_of_parent) { + Some(Node::Directory { .. }) => Ok(inode_of_parent), + _ => Err(FsError::BaseNotDirectory), + } + } + + /// From the inode of a parent node (so, a directory), returns the + /// child index of `name_of_directory` along with its inode. + pub(super) fn from_parent_get_position_and_inode_of_directory( + &self, + inode_of_parent: Inode, + name_of_directory: &OsString, + directory_must_be_empty: DirectoryMustBeEmpty, + ) -> Result<(usize, Inode)> { + match self.storage.get(inode_of_parent) { + Some(Node::Directory { children, .. }) => children + .iter() + .enumerate() + .filter_map(|(nth, inode)| self.storage.get(*inode).map(|node| (nth, node))) + .find_map(|(nth, node)| match node { + Node::Directory { + inode, + name, + children, + .. + } if name.as_os_str() == name_of_directory => { + if directory_must_be_empty.no() || children.is_empty() { + Some(Ok((nth, *inode))) + } else { + Some(Err(FsError::DirectoryNotEmpty)) + } + } + + _ => None, + }) + .ok_or(FsError::InvalidInput) + .and_then(identity), // flatten + _ => Err(FsError::BaseNotDirectory), + } + } + + /// From the inode of a parent node (so, a directory), returns the + /// child index of `name_of_file` along with its inode. + pub(super) fn from_parent_get_position_and_inode_of_file( + &self, + inode_of_parent: Inode, + name_of_file: &OsString, + ) -> Result> { + match self.storage.get(inode_of_parent) { + Some(Node::Directory { children, .. }) => children + .iter() + .enumerate() + .filter_map(|(nth, inode)| self.storage.get(*inode).map(|node| (nth, node))) + .find_map(|(nth, node)| match node { + Node::File { inode, name, .. } if name.as_os_str() == name_of_file => { + Some(Some((nth, *inode))) + } + + _ => None, + }) + .or(Some(None)) + .ok_or(FsError::InvalidInput), + + _ => Err(FsError::BaseNotDirectory), + } + } + + /// Set a new name for the node represented by `inode`. + pub(super) fn update_node_name(&mut self, inode: Inode, new_name: OsString) -> Result<()> { + let node = self.storage.get_mut(inode).ok_or(FsError::UnknownError)?; + + node.set_name(new_name); + node.metadata_mut().modified = time(); + + Ok(()) + } + + /// Add a child to a directory node represented by `inode`. + /// + /// This function also updates the modified time of the directory. + /// + /// # Safety + /// + /// `inode` must represents an existing directory. + pub(super) fn add_child_to_node(&mut self, inode: Inode, new_child: Inode) -> Result<()> { + match self.storage.get_mut(inode) { + Some(Node::Directory { + children, + metadata: Metadata { modified, .. }, + .. + }) => { + children.push(new_child); + *modified = time(); + + Ok(()) + } + _ => Err(FsError::UnknownError), + } + } + + /// Remove the child at position `position` of a directory node + /// represented by `inode`. + /// + /// This function also updates the modified time of the directory. + /// + /// # Safety + /// + /// `inode` must represents an existing directory. + pub(super) fn remove_child_from_node(&mut self, inode: Inode, position: usize) -> Result<()> { + match self.storage.get_mut(inode) { + Some(Node::Directory { + children, + metadata: Metadata { modified, .. }, + .. + }) => { + children.remove(position); + *modified = time(); + + Ok(()) + } + _ => Err(FsError::UnknownError), + } + } + + /// Canonicalize a path, i.e. try to resolve to a canonical, + /// absolute form of the path with all intermediate components + /// normalized: + /// + /// * A path must starts with a root (`/`), + /// * A path can contain `..` or `.` components, + /// * A path must not contain a Windows prefix (`C:` or `\\server`), + /// * A normalized path exists in the file system. + pub(super) fn canonicalize(&self, path: &Path) -> Result<(PathBuf, Inode)> { + let new_path = self.canonicalize_without_inode(path)?; + let inode = self.inode_of(&new_path)?; + + Ok((new_path, inode)) + } + + /// Like `Self::canonicalize` but without returning the inode of + /// the path, which means that there is no guarantee that the path + /// exists in the file system. + pub(super) fn canonicalize_without_inode(&self, path: &Path) -> Result { + let mut components = path.components(); + + match components.next() { + Some(Component::RootDir) => {} + _ => return Err(FsError::InvalidInput), + } + + let mut new_path = PathBuf::with_capacity(path.as_os_str().len()); + new_path.push("/"); + + for component in components { + match component { + // That's an error to get a `RootDir` a second time. + Component::RootDir => return Err(FsError::UnknownError), + + // Nothing to do on `new_path`. + Component::CurDir => (), + + // Pop the lastly inserted component on `new_path` if + // any, otherwise it's an error. + Component::ParentDir => { + if !new_path.pop() { + return Err(FsError::InvalidInput); + } + } + + // A normal + Component::Normal(name) => { + new_path.push(name); + } + + // We don't support Windows path prefix. + Component::Prefix(_) => return Err(FsError::InvalidInput), + } + } + + Ok(new_path) + } +} + +impl fmt::Debug for FileSystemInner { + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + writeln!( + formatter, + "\n{inode:<8} {ty:<4} name", + inode = "inode", + ty = "type", + )?; + + fn debug( + nodes: Vec<&Node>, + slf: &FileSystemInner, + formatter: &mut fmt::Formatter<'_>, + indentation: usize, + ) -> fmt::Result { + for node in nodes { + writeln!( + formatter, + "{inode:<8} {ty:<4} {indentation_symbol:indentation_width$}{name}", + inode = node.inode(), + ty = match node { + Node::File { .. } => "file", + Node::Directory { .. } => "dir", + }, + name = node.name().to_string_lossy(), + indentation_symbol = " ", + indentation_width = indentation * 2 + 1, + )?; + + if let Node::Directory { children, .. } = node { + debug( + children + .iter() + .filter_map(|inode| slf.storage.get(*inode)) + .collect(), + slf, + formatter, + indentation + 1, + )?; + } + } + + Ok(()) + } + + debug( + vec![self.storage.get(ROOT_INODE).unwrap()], + &self, + formatter, + 0, + ) + } +} + +impl Default for FileSystemInner { + fn default() -> Self { + let time = time(); + + let mut slab = Slab::new(); + slab.insert(Node::Directory { + inode: ROOT_INODE, + name: OsString::from("/"), + children: Vec::new(), + metadata: Metadata { + ft: FileType { + dir: true, + ..Default::default() + }, + accessed: time, + created: time, + modified: time, + len: 0, + }, + }); + + Self { storage: slab } + } +} + +#[cfg(test)] +mod test_filesystem { + use crate::{mem_fs::*, DirEntry, FileSystem as FS, FileType, FsError}; + + macro_rules! path { + ($path:expr) => { + std::path::Path::new($path) + }; + + (buf $path:expr) => { + std::path::PathBuf::from($path) + }; + } + + #[test] + fn test_new_filesystem() { + let fs = FileSystem::default(); + let fs_inner = fs.inner.read().unwrap(); + + assert_eq!(fs_inner.storage.len(), 1, "storage has a root"); + assert!( + matches!( + fs_inner.storage.get(ROOT_INODE), + Some(Node::Directory { + inode: ROOT_INODE, + name, + children, + .. + }) if name == "/" && children.is_empty(), + ), + "storage has a well-defined root", + ); + } + + #[test] + fn test_create_dir() { + let fs = FileSystem::default(); + + assert_eq!( + fs.create_dir(path!("/")), + Err(FsError::BaseNotDirectory), + "creating a directory that has no parent", + ); + + assert_eq!(fs.create_dir(path!("/foo")), Ok(()), "creating a directory",); + + { + let fs_inner = fs.inner.read().unwrap(); + assert_eq!( + fs_inner.storage.len(), + 2, + "storage contains the new directory" + ); + assert!( + matches!( + fs_inner.storage.get(ROOT_INODE), + Some(Node::Directory { + inode: ROOT_INODE, + name, + children, + .. + }) if name == "/" && children == &[1] + ), + "the root is updated and well-defined", + ); + assert!( + matches!( + fs_inner.storage.get(1), + Some(Node::Directory { + inode: 1, + name, + children, + .. + }) if name == "foo" && children.is_empty(), + ), + "the new directory is well-defined", + ); + } + + assert_eq!( + fs.create_dir(path!("/foo/bar")), + Ok(()), + "creating a sub-directory", + ); + + { + let fs_inner = fs.inner.read().unwrap(); + assert_eq!( + fs_inner.storage.len(), + 3, + "storage contains the new sub-directory", + ); + assert!( + matches!( + fs_inner.storage.get(ROOT_INODE), + Some(Node::Directory { + inode: ROOT_INODE, + name, + children, + .. + }) if name == "/" && children == &[1] + ), + "the root is updated again and well-defined", + ); + assert!( + matches!( + fs_inner.storage.get(1), + Some(Node::Directory { + inode: 1, + name, + children, + .. + }) if name == "foo" && children == &[2] + ), + "the new directory is updated and well-defined", + ); + assert!( + matches!( + fs_inner.storage.get(2), + Some(Node::Directory { + inode: 2, + name, + children, + .. + }) if name == "bar" && children.is_empty() + ), + "the new directory is well-defined", + ); + } + } + + #[test] + fn test_remove_dir() { + let fs = FileSystem::default(); + + assert_eq!( + fs.remove_dir(path!("/")), + Err(FsError::BaseNotDirectory), + "removing a directory that has no parent", + ); + + assert_eq!( + fs.remove_dir(path!("/foo")), + Err(FsError::NotAFile), + "cannot remove a directory that doesn't exist", + ); + + assert_eq!(fs.create_dir(path!("/foo")), Ok(()), "creating a directory",); + + assert_eq!( + fs.create_dir(path!("/foo/bar")), + Ok(()), + "creating a sub-directory", + ); + + { + let fs_inner = fs.inner.read().unwrap(); + assert_eq!( + fs_inner.storage.len(), + 3, + "storage contains all the directories", + ); + } + + assert_eq!( + fs.remove_dir(path!("/foo")), + Err(FsError::DirectoryNotEmpty), + "removing a directory that has children", + ); + + assert_eq!( + fs.remove_dir(path!("/foo/bar")), + Ok(()), + "removing a sub-directory", + ); + + assert_eq!(fs.remove_dir(path!("/foo")), Ok(()), "removing a directory",); + + { + let fs_inner = fs.inner.read().unwrap(); + assert_eq!( + fs_inner.storage.len(), + 1, + "storage contains all the directories", + ); + } + } + + #[test] + fn test_rename() { + let fs = FileSystem::default(); + + assert_eq!( + fs.rename(path!("/"), path!("/bar")), + Err(FsError::BaseNotDirectory), + "renaming a directory that has no parent", + ); + assert_eq!( + fs.rename(path!("/foo"), path!("/")), + Err(FsError::BaseNotDirectory), + "renaming to a directory that has no parent", + ); + + assert_eq!(fs.create_dir(path!("/foo")), Ok(())); + assert_eq!(fs.create_dir(path!("/foo/qux")), Ok(())); + + assert_eq!( + fs.rename(path!("/foo"), path!("/bar/baz")), + Err(FsError::NotAFile), + "renaming to a directory that has parent that doesn't exist", + ); + + assert_eq!(fs.create_dir(path!("/bar")), Ok(())); + + { + let fs_inner = fs.inner.read().unwrap(); + + assert_eq!(fs_inner.storage.len(), 4, "storage has all directories"); + assert!( + matches!( + fs_inner.storage.get(ROOT_INODE), + Some(Node::Directory { + inode: ROOT_INODE, + name, + children, + .. + }) if name == "/" && children == &[1, 3] + ), + "`/` contains `foo` and `bar`", + ); + assert!( + matches!( + fs_inner.storage.get(1), + Some(Node::Directory { + inode: 1, + name, + children, + .. + }) if name == "foo" && children == &[2] + ), + "`foo` contains `qux`", + ); + assert!( + matches!( + fs_inner.storage.get(2), + Some(Node::Directory { + inode: 2, + name, + children, + .. + }) if name == "qux" && children.is_empty() + ), + "`qux` is empty", + ); + assert!( + matches!( + fs_inner.storage.get(3), + Some(Node::Directory { + inode: 3, + name, + children, + .. + }) if name == "bar" && children.is_empty() + ), + "`bar` is empty", + ); + } + + assert_eq!( + fs.rename(path!("/foo"), path!("/bar/baz")), + Ok(()), + "renaming a directory", + ); + + { + let fs_inner = fs.inner.read().unwrap(); + + assert_eq!( + fs_inner.storage.len(), + 4, + "storage has still all directories" + ); + assert!( + matches!( + fs_inner.storage.get(ROOT_INODE), + Some(Node::Directory { + inode: ROOT_INODE, + name, + children, + .. + }) if name == "/" && children == &[3] + ), + "`/` contains `bar`", + ); + assert!( + matches!( + fs_inner.storage.get(1), + Some(Node::Directory { + inode: 1, + name, + children, + .. + }) if name == "baz" && children == &[2] + ), + "`foo` has been renamed to `baz` and contains `qux`", + ); + assert!( + matches!( + fs_inner.storage.get(2), + Some(Node::Directory { + inode: 2, + name, + children, + .. + }) if name == "qux" && children.is_empty() + ), + "`qux` is empty", + ); + assert!( + matches!( + fs_inner.storage.get(3), + Some(Node::Directory { + inode: 3, + name, + children, + .. + }) if name == "bar" && children == &[1] + ), + "`bar` contains `baz` (ex `foo`)", + ); + } + } + + #[test] + fn test_metadata() { + use std::thread::sleep; + use std::time::Duration; + + let fs = FileSystem::default(); + let root_metadata = fs.metadata(path!("/")); + + assert!(matches!( + root_metadata, + Ok(Metadata { + ft: FileType { dir: true, .. }, + accessed, + created, + modified, + len: 0 + }) if accessed == created && created == modified && modified > 0 + )); + + assert_eq!(fs.create_dir(path!("/foo")), Ok(())); + + let foo_metadata = fs.metadata(path!("/foo")); + assert!(foo_metadata.is_ok()); + let foo_metadata = foo_metadata.unwrap(); + + assert!(matches!( + foo_metadata, + Metadata { + ft: FileType { dir: true, .. }, + accessed, + created, + modified, + len: 0 + } if accessed == created && created == modified && modified > 0 + )); + + sleep(Duration::from_secs(3)); + + assert_eq!(fs.rename(path!("/foo"), path!("/bar")), Ok(())); + + assert!( + matches!( + fs.metadata(path!("/bar")), + Ok(Metadata { + ft: FileType { dir: true, .. }, + accessed, + created, + modified, + len: 0 + }) if + accessed == foo_metadata.accessed && + created == foo_metadata.created && + modified > foo_metadata.modified + ), + "the modified time is updated when file is renamed", + ); + assert!( + matches!( + fs.metadata(path!("/")), + Ok(Metadata { + ft: FileType { dir: true, .. }, + accessed, + created, + modified, + len: 0 + }) if + accessed == foo_metadata.accessed && + created == foo_metadata.created && + modified > foo_metadata.modified + ), + "the modified time of the parent is updated when file is renamed", + ); + } + + #[test] + fn test_remove_file() { + let fs = FileSystem::default(); + + assert!( + matches!( + fs.new_open_options() + .write(true) + .create_new(true) + .open(path!("/foo.txt")), + Ok(_) + ), + "creating a new file", + ); + + { + let fs_inner = fs.inner.read().unwrap(); + + assert_eq!(fs_inner.storage.len(), 2, "storage has all files"); + assert!( + matches!( + fs_inner.storage.get(ROOT_INODE), + Some(Node::Directory { + inode: ROOT_INODE, + name, + children, + .. + }) if name == "/" && children == &[1] + ), + "`/` contains `foo.txt`", + ); + assert!( + matches!( + fs_inner.storage.get(1), + Some(Node::File { + inode: 1, + name, + .. + }) if name == "foo.txt" + ), + "`foo.txt` exists and is a file", + ); + } + + assert_eq!( + fs.remove_file(path!("/foo.txt")), + Ok(()), + "removing a file that exists", + ); + + { + let fs_inner = fs.inner.read().unwrap(); + + assert_eq!(fs_inner.storage.len(), 1, "storage no longer has the file"); + assert!( + matches!( + fs_inner.storage.get(ROOT_INODE), + Some(Node::Directory { + inode: ROOT_INODE, + name, + children, + .. + }) if name == "/" && children == &[] + ), + "`/` is empty", + ); + } + + assert_eq!( + fs.remove_file(path!("/foo.txt")), + Err(FsError::NotAFile), + "removing a file that exists", + ); + } + + #[test] + fn test_readdir() { + let fs = FileSystem::default(); + + assert_eq!(fs.create_dir(path!("/foo")), Ok(()), "creating `foo`"); + assert_eq!(fs.create_dir(path!("/foo/sub")), Ok(()), "creating `sub`"); + assert_eq!(fs.create_dir(path!("/bar")), Ok(()), "creating `bar`"); + assert_eq!(fs.create_dir(path!("/baz")), Ok(()), "creating `bar`"); + assert!( + matches!( + fs.new_open_options() + .write(true) + .create_new(true) + .open(path!("/a.txt")), + Ok(_) + ), + "creating `a.txt`", + ); + assert!( + matches!( + fs.new_open_options() + .write(true) + .create_new(true) + .open(path!("/b.txt")), + Ok(_) + ), + "creating `b.txt`", + ); + + let readdir = fs.read_dir(path!("/")); + + assert!(readdir.is_ok(), "reading the directory `/`"); + + let mut readdir = readdir.unwrap(); + + assert!( + matches!( + readdir.next(), + Some(Ok(DirEntry { + path, + metadata: Ok(Metadata { ft, .. }), + })) + if path == path!(buf "/foo") && ft.is_dir() + ), + "checking entry #1", + ); + assert!( + matches!( + readdir.next(), + Some(Ok(DirEntry { + path, + metadata: Ok(Metadata { ft, .. }), + })) + if path == path!(buf "/bar") && ft.is_dir() + ), + "checking entry #2", + ); + assert!( + matches!( + readdir.next(), + Some(Ok(DirEntry { + path, + metadata: Ok(Metadata { ft, .. }), + })) + if path == path!(buf "/baz") && ft.is_dir() + ), + "checking entry #3", + ); + assert!( + matches!( + readdir.next(), + Some(Ok(DirEntry { + path, + metadata: Ok(Metadata { ft, .. }), + })) + if path == path!(buf "/a.txt") && ft.is_file() + ), + "checking entry #4", + ); + assert!( + matches!( + readdir.next(), + Some(Ok(DirEntry { + path, + metadata: Ok(Metadata { ft, .. }), + })) + if path == path!(buf "/b.txt") && ft.is_file() + ), + "checking entry #5", + ); + assert!(matches!(readdir.next(), None), "no more entries"); + } + + #[test] + fn test_canonicalize() { + let fs = FileSystem::default(); + + assert_eq!(fs.create_dir(path!("/foo")), Ok(()), "creating `foo`"); + assert_eq!(fs.create_dir(path!("/foo/bar")), Ok(()), "creating `bar`"); + assert_eq!( + fs.create_dir(path!("/foo/bar/baz")), + Ok(()), + "creating `baz`", + ); + assert_eq!( + fs.create_dir(path!("/foo/bar/baz/qux")), + Ok(()), + "creating `qux`", + ); + assert!( + matches!( + fs.new_open_options() + .write(true) + .create_new(true) + .open(path!("/foo/bar/baz/qux/hello.txt")), + Ok(_) + ), + "creating `hello.txt`", + ); + + let fs_inner = fs.inner.read().unwrap(); + + assert_eq!( + fs_inner.canonicalize(path!("/")), + Ok((path!(buf "/"), ROOT_INODE)), + "canonicalizing `/`", + ); + assert_eq!( + fs_inner.canonicalize(path!("foo")), + Err(FsError::InvalidInput), + "canonicalizing `foo`", + ); + assert_eq!( + fs_inner.canonicalize(path!("/././././foo/")), + Ok((path!(buf "/foo"), 1)), + "canonicalizing `/././././foo/`", + ); + assert_eq!( + fs_inner.canonicalize(path!("/foo/bar//")), + Ok((path!(buf "/foo/bar"), 2)), + "canonicalizing `/foo/bar//`", + ); + assert_eq!( + fs_inner.canonicalize(path!("/foo/bar/../bar")), + Ok((path!(buf "/foo/bar"), 2)), + "canonicalizing `/foo/bar/../bar`", + ); + assert_eq!( + fs_inner.canonicalize(path!("/foo/bar/../..")), + Ok((path!(buf "/"), ROOT_INODE)), + "canonicalizing `/foo/bar/../..`", + ); + assert_eq!( + fs_inner.canonicalize(path!("/foo/bar/../../..")), + Err(FsError::InvalidInput), + "canonicalizing `/foo/bar/../../..`", + ); + assert_eq!( + fs_inner.canonicalize(path!("C:/foo/")), + Err(FsError::InvalidInput), + "canonicalizing `C:/foo/`", + ); + assert_eq!( + fs_inner.canonicalize(path!( + "/foo/./../foo/bar/../../foo/bar/./baz/./../baz/qux/../../baz/./qux/hello.txt" + )), + Ok((path!(buf "/foo/bar/baz/qux/hello.txt"), 5)), + "canonicalizing a crazily stupid path name", + ); + } +} + +pub(super) enum DirectoryMustBeEmpty { + Yes, + No, +} + +impl DirectoryMustBeEmpty { + pub(super) fn yes(&self) -> bool { + matches!(self, Self::Yes) + } + + pub(super) fn no(&self) -> bool { + !self.yes() + } +} diff --git a/lib/vfs/src/mem_fs/mod.rs b/lib/vfs/src/mem_fs/mod.rs new file mode 100644 index 00000000000..87737e37036 --- /dev/null +++ b/lib/vfs/src/mem_fs/mod.rs @@ -0,0 +1,98 @@ +mod file; +mod file_opener; +mod filesystem; +mod stdio; + +use file::{File, FileHandle}; +pub use file_opener::FileOpener; +pub use filesystem::FileSystem; +pub use stdio::{Stderr, Stdin, Stdout}; + +use crate::Metadata; +use std::ffi::{OsStr, OsString}; + +type Inode = usize; +const ROOT_INODE: Inode = 0; + +#[derive(Debug)] +enum Node { + File { + inode: Inode, + name: OsString, + file: File, + metadata: Metadata, + }, + Directory { + inode: Inode, + name: OsString, + children: Vec, + metadata: Metadata, + }, +} + +impl Node { + fn inode(&self) -> Inode { + *match self { + Self::File { inode, .. } => inode, + Self::Directory { inode, .. } => inode, + } + } + + fn name(&self) -> &OsStr { + match self { + Self::File { name, .. } => name.as_os_str(), + Self::Directory { name, .. } => name.as_os_str(), + } + } + + fn metadata(&self) -> &Metadata { + match self { + Self::File { metadata, .. } => metadata, + Self::Directory { metadata, .. } => metadata, + } + } + + fn metadata_mut(&mut self) -> &mut Metadata { + match self { + Self::File { metadata, .. } => metadata, + Self::Directory { metadata, .. } => metadata, + } + } + + fn set_name(&mut self, new_name: OsString) { + match self { + Self::File { name, .. } => *name = new_name, + Self::Directory { name, .. } => *name = new_name, + } + } +} + +fn time() -> u64 { + #[cfg(not(feature = "no-time"))] + { + // SAFETY: It's very unlikely that the system returns a time that + // is before `UNIX_EPOCH` :-). + std::time::SystemTime::now() + .duration_since(std::time::SystemTime::UNIX_EPOCH) + .unwrap() + .as_secs() + } + + #[cfg(feature = "no-time")] + { + 0 + } +} + +// If the `host-fs` feature is not enabled, let's write a +// `TryInto` implementation for `FileDescriptor`, otherwise on +// Unix, it conflicts with `TryInto` (where `RawFd` is an alias +// to `i32`). +#[cfg(not(all(unix, feature = "host-fs")))] +impl std::convert::TryInto for crate::FileDescriptor { + type Error = crate::FsError; + + fn try_into(self) -> std::result::Result { + self.0.try_into().map_err(|_| crate::FsError::InvalidFd) + } +} diff --git a/lib/vfs/src/mem_fs/stdio.rs b/lib/vfs/src/mem_fs/stdio.rs new file mode 100644 index 00000000000..db47ef33b41 --- /dev/null +++ b/lib/vfs/src/mem_fs/stdio.rs @@ -0,0 +1,342 @@ +//! This module contains the standard I/O streams, i.e. “emulated” +//! `stdin`, `stdout` and `stderr`. + +use crate::{FileDescriptor, FsError, Result, VirtualFile}; +use std::io::{self, Read, Seek, Write}; + +macro_rules! impl_virtualfile_on_std_streams { + ($name:ident { readable: $readable:expr, writable: $writable:expr $(,)* }) => { + /// A wrapper type around the standard I/O stream of the same + /// name that implements `VirtualFile`. + #[derive(Debug, Default)] + pub struct $name { + pub buf: Vec, + } + + impl $name { + const fn is_readable(&self) -> bool { + $readable + } + + const fn is_writable(&self) -> bool { + $writable + } + } + + impl VirtualFile for $name { + fn last_accessed(&self) -> u64 { + 0 + } + + fn last_modified(&self) -> u64 { + 0 + } + + fn created_time(&self) -> u64 { + 0 + } + + fn size(&self) -> u64 { + 0 + } + + fn set_len(&mut self, _new_size: u64) -> Result<()> { + Err(FsError::PermissionDenied) + } + + fn unlink(&mut self) -> Result<()> { + Ok(()) + } + + fn bytes_available(&self) -> Result { + unimplemented!(); + } + + fn get_fd(&self) -> Option { + None + } + } + + impl_virtualfile_on_std_streams!(impl Seek for $name); + impl_virtualfile_on_std_streams!(impl Read for $name); + impl_virtualfile_on_std_streams!(impl Write for $name); + }; + + (impl Seek for $name:ident) => { + impl Seek for $name { + fn seek(&mut self, _pos: io::SeekFrom) -> io::Result { + Err(io::Error::new( + io::ErrorKind::PermissionDenied, + concat!("cannot seek `", stringify!($name), "`"), + )) + } + } + }; + + (impl Read for $name:ident) => { + impl Read for $name { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + if self.is_readable() { + let length = self.buf.as_slice().read(buf)?; + + // Remove what has been consumed. + self.buf.drain(..length); + + Ok(length) + } else { + Err(io::Error::new( + io::ErrorKind::PermissionDenied, + concat!("cannot read from `", stringify!($name), "`"), + )) + } + } + + fn read_to_end(&mut self, buf: &mut Vec) -> io::Result { + if self.is_readable() { + let length = self.buf.as_slice().read_to_end(buf)?; + + // Remove what has been consumed. + self.buf.clear(); + + Ok(length) + } else { + Err(io::Error::new( + io::ErrorKind::PermissionDenied, + concat!("cannot read from `", stringify!($name), "`"), + )) + } + } + + fn read_to_string(&mut self, buf: &mut String) -> io::Result { + if self.is_readable() { + let length = self.buf.as_slice().read_to_string(buf)?; + + // Remove what has been consumed. + self.buf.drain(..length); + + Ok(length) + } else { + Err(io::Error::new( + io::ErrorKind::PermissionDenied, + concat!("cannot read from `", stringify!($name), "`"), + )) + } + } + + fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> { + if self.is_readable() { + self.buf.as_slice().read_exact(buf)?; + + self.buf.drain(..buf.len()); + + Ok(()) + } else { + Err(io::Error::new( + io::ErrorKind::PermissionDenied, + concat!("cannot read from `", stringify!($name), "`"), + )) + } + } + } + }; + + (impl Write for $name:ident) => { + impl Write for $name { + fn write(&mut self, buf: &[u8]) -> io::Result { + if self.is_writable() { + self.buf.write(buf) + } else { + Err(io::Error::new( + io::ErrorKind::PermissionDenied, + concat!("cannot write to `", stringify!($name), "`"), + )) + } + } + + fn flush(&mut self) -> io::Result<()> { + if self.is_writable() { + self.buf.flush() + } else { + Err(io::Error::new( + io::ErrorKind::PermissionDenied, + concat!("cannot flush `", stringify!($name), "`"), + )) + } + } + + fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { + if self.is_writable() { + self.buf.write_all(buf) + } else { + Err(io::Error::new( + io::ErrorKind::PermissionDenied, + concat!("cannot write to `", stringify!($name), "`"), + )) + } + } + } + }; +} + +impl_virtualfile_on_std_streams!(Stdin { + readable: true, + writable: false, +}); +impl_virtualfile_on_std_streams!(Stdout { + readable: false, + writable: true, +}); +impl_virtualfile_on_std_streams!(Stderr { + readable: false, + writable: true, +}); + +#[cfg(test)] +mod test_read_write_seek { + use crate::mem_fs::*; + use std::io::{self, Read, Seek, Write}; + + #[test] + fn test_read_stdin() { + let mut stdin = Stdin { + buf: vec![b'f', b'o', b'o', b'b', b'a', b'r'], + }; + let mut buffer = [0; 3]; + + assert!( + matches!(stdin.read(&mut buffer), Ok(3)), + "reading bytes from `stdin`", + ); + assert_eq!( + buffer, + [b'f', b'o', b'o'], + "checking the bytes read from `stdin`" + ); + + let mut buffer = Vec::new(); + + assert!( + matches!(stdin.read_to_end(&mut buffer), Ok(3)), + "reading bytes again from `stdin`", + ); + assert_eq!( + buffer, + &[b'b', b'a', b'r'], + "checking the bytes read from `stdin`" + ); + + let mut buffer = [0; 1]; + + assert!( + stdin.read_exact(&mut buffer).is_err(), + "cannot read bytes again because `stdin` has fully consumed", + ); + } + + #[test] + fn test_write_stdin() { + let mut stdin = Stdin { buf: vec![] }; + + assert!(stdin.write(b"bazqux").is_err(), "cannot write into `stdin`"); + } + + #[test] + fn test_seek_stdin() { + let mut stdin = Stdin { + buf: vec![b'f', b'o', b'o', b'b', b'a', b'r'], + }; + + assert!( + stdin.seek(io::SeekFrom::End(0)).is_err(), + "cannot seek `stdin`", + ); + } + + #[test] + fn test_read_stdout() { + let mut stdout = Stdout { + buf: vec![b'f', b'o', b'o', b'b', b'a', b'r'], + }; + let mut buffer = String::new(); + + assert!( + stdout.read_to_string(&mut buffer).is_err(), + "cannot read from `stdout`" + ); + } + + #[test] + fn test_write_stdout() { + let mut stdout = Stdout { buf: vec![] }; + + assert!( + matches!(stdout.write(b"baz"), Ok(3)), + "writing into `stdout`", + ); + assert!( + matches!(stdout.write(b"qux"), Ok(3)), + "writing again into `stdout`", + ); + assert_eq!( + stdout.buf, + &[b'b', b'a', b'z', b'q', b'u', b'x'], + "checking the content of `stdout`", + ); + } + + #[test] + fn test_seek_stdout() { + let mut stdout = Stdout { + buf: vec![b'f', b'o', b'o', b'b', b'a', b'r'], + }; + + assert!( + stdout.seek(io::SeekFrom::End(0)).is_err(), + "cannot seek `stdout`", + ); + } + + #[test] + fn test_read_stderr() { + let mut stderr = Stderr { + buf: vec![b'f', b'o', b'o', b'b', b'a', b'r'], + }; + let mut buffer = String::new(); + + assert!( + stderr.read_to_string(&mut buffer).is_err(), + "cannot read from `stderr`" + ); + } + + #[test] + fn test_write_stderr() { + let mut stderr = Stderr { buf: vec![] }; + + assert!( + matches!(stderr.write(b"baz"), Ok(3)), + "writing into `stderr`", + ); + assert!( + matches!(stderr.write(b"qux"), Ok(3)), + "writing again into `stderr`", + ); + assert_eq!( + stderr.buf, + &[b'b', b'a', b'z', b'q', b'u', b'x'], + "checking the content of `stderr`", + ); + } + + #[test] + fn test_seek_stderr() { + let mut stderr = Stderr { + buf: vec![b'f', b'o', b'o', b'b', b'a', b'r'], + }; + + assert!( + stderr.seek(io::SeekFrom::End(0)).is_err(), + "cannot seek `stderr`", + ); + } +} diff --git a/lib/wasi-experimental-io-devices/Cargo.toml b/lib/wasi-experimental-io-devices/Cargo.toml index bbd6c249d59..a82bd03df95 100644 --- a/lib/wasi-experimental-io-devices/Cargo.toml +++ b/lib/wasi-experimental-io-devices/Cargo.toml @@ -14,7 +14,7 @@ edition = "2018" maintenance = { status = "experimental" } [dependencies] -wasmer-wasi = { version = "2.0.0", path = "../wasi" } +wasmer-wasi = { version = "2.0.0", path = "../wasi", default-features=false } tracing = "0.1" minifb = "0.19" ref_thread_local = "0.1" diff --git a/lib/wasi-experimental-io-devices/src/lib.rs b/lib/wasi-experimental-io-devices/src/lib.rs index 8c78aff0795..18e8949291a 100644 --- a/lib/wasi-experimental-io-devices/src/lib.rs +++ b/lib/wasi-experimental-io-devices/src/lib.rs @@ -4,7 +4,7 @@ use std::convert::TryInto; use std::io::{Read, Seek, SeekFrom, Write}; use tracing::debug; use wasmer_wasi::types::*; -use wasmer_wasi::{Fd, WasiFile, WasiFs, WasiFsError, ALL_RIGHTS, VIRTUAL_ROOT_FD}; +use wasmer_wasi::{Fd, VirtualFile, WasiFs, WasiFsError, ALL_RIGHTS, VIRTUAL_ROOT_FD}; use minifb::{Key, KeyRepeat, MouseButton, Scale, Window, WindowOptions}; @@ -404,7 +404,7 @@ impl Write for FrameBuffer { } #[typetag::serde] -impl WasiFile for FrameBuffer { +impl VirtualFile for FrameBuffer { fn last_accessed(&self) -> u64 { 0 } diff --git a/lib/wasi/Cargo.toml b/lib/wasi/Cargo.toml index be2dac2c867..dfdb83a6611 100644 --- a/lib/wasi/Cargo.toml +++ b/lib/wasi/Cargo.toml @@ -10,22 +10,51 @@ license = "MIT" readme = "README.md" edition = "2018" +[lib] +crate-type = ["cdylib", "rlib"] + [dependencies] -bincode = "1" +cfg-if = "1.0" thiserror = "1" generational-arena = { version = "0.2", features = ["serde"] } -libc = { version = "^0.2", default-features = false } -tracing = { version = "0.1" } +tracing = "0.1" getrandom = "0.2" -typetag = "0.1" -serde = { version = "1.0", features = ["derive"] } wasmer-wasi-types = { path = "../wasi-types", version = "2.0.0" } -wasmer = { path = "../api", version = "2.0.0", default-features = false, features = ["sys"] } +wasmer = { path = "../api", version = "2.0.0", default-features = false } +wasmer-vfs = { path = "../vfs", version = "2.0.0", default-features = false } +typetag = { version = "0.1", optional = true } +serde = { version = "1.0", default-features = false, features = ["derive"], optional = true } +bincode = { version = "1.3", optional = true } + +[target.'cfg(unix)'.dependencies] +libc = { version = "^0.2", default-features = false } [target.'cfg(windows)'.dependencies] winapi = "0.3" +[target.'cfg(target_arch = "wasm32")'.dependencies] +wasm-bindgen = "0.2.74" + +[target.'cfg(target_arch = "wasm32")'.dev-dependencies] +wasm-bindgen-test = "0.3.0" +tracing-wasm = "0.2" + [features] -default = ["logging"] +default = ["sys-default"] + +sys = ["wasmer/sys-default"] +sys-default = ["sys", "logging", "host-fs"] + +js = ["wasmer/js-default", "mem-fs", "wasmer-vfs/no-time", "getrandom/js"] +js-default = ["js"] +test-js = ["js", "wasmer/js-default", "wasmer/wat"] + +host-fs = ["wasmer-vfs/host-fs"] +mem-fs = ["wasmer-vfs/mem-fs"] + logging = ["tracing/log"] -disable-all-logging = ["tracing/release_max_level_off", "tracing/max_level_off"] \ No newline at end of file +disable-all-logging = [ + "tracing/release_max_level_off", + "tracing/max_level_off" +] +enable-serde = ["typetag", "serde", "bincode"] diff --git a/lib/wasi/src/lib.rs b/lib/wasi/src/lib.rs index 181f485b982..1057340063b 100644 --- a/lib/wasi/src/lib.rs +++ b/lib/wasi/src/lib.rs @@ -12,6 +12,27 @@ //! [WASI plugin example](https://github.com/wasmerio/wasmer/blob/master/examples/plugin.rs) //! for an example of how to extend WASI using the WASI FS API. +#[cfg(all(not(feature = "sys"), not(feature = "js")))] +compile_error!("At least the `sys` or the `js` feature must be enabled. Please, pick one."); + +#[cfg(all(feature = "sys", feature = "js"))] +compile_error!( + "Cannot have both `sys` and `js` features enabled at the same time. Please, pick one." +); + +#[cfg(all(feature = "sys", target_arch = "wasm32"))] +compile_error!("The `sys` feature must be enabled only for non-`wasm32` target."); + +#[cfg(all(feature = "js", not(target_arch = "wasm32")))] +compile_error!( + "The `js` feature must be enabled only for the `wasm32` target (either `wasm32-unknown-unknown` or `wasm32-wasi`)." +); + +#[cfg(all(feature = "host-fs", feature = "mem-fs"))] +compile_error!( + "Cannot have both `host-fs` and `mem-fs` features enabled at the same time. Please, pick one." +); + #[macro_use] mod macros; mod ptr; @@ -22,11 +43,16 @@ mod utils; use crate::syscalls::*; pub use crate::state::{ - Fd, Pipe, Stderr, Stdin, Stdout, WasiFile, WasiFs, WasiFsError, WasiState, WasiStateBuilder, - WasiStateCreationError, ALL_RIGHTS, VIRTUAL_ROOT_FD, + Fd, Pipe, Stderr, Stdin, Stdout, WasiFs, WasiState, WasiStateBuilder, WasiStateCreationError, + ALL_RIGHTS, VIRTUAL_ROOT_FD, }; pub use crate::syscalls::types; pub use crate::utils::{get_wasi_version, get_wasi_versions, is_wasi_module, WasiVersion}; +#[deprecated(since = "2.1.0", note = "Please use `wasmer_vfs::FsError`")] +pub use wasmer_vfs::FsError as WasiFsError; +#[deprecated(since = "2.1.0", note = "Please use `wasmer_vfs::VirtualFile`")] +pub use wasmer_vfs::VirtualFile as WasiFile; +pub use wasmer_vfs::{FsError, VirtualFile}; use thiserror::Error; use wasmer::{ diff --git a/lib/wasi/src/macros.rs b/lib/wasi/src/macros.rs index 07f480ffe82..8cec82ae04b 100644 --- a/lib/wasi/src/macros.rs +++ b/lib/wasi/src/macros.rs @@ -31,6 +31,6 @@ macro_rules! wasi_try { /// corrupted. macro_rules! get_input_str { ($memory:expr, $data:expr, $len:expr) => {{ - wasi_try!($data.get_utf8_str($memory, $len), __WASI_EINVAL) + wasi_try!($data.get_utf8_string($memory, $len), __WASI_EINVAL) }}; } diff --git a/lib/wasi/src/ptr.rs b/lib/wasi/src/ptr.rs index 9be529ab619..7a472dcd451 100644 --- a/lib/wasi/src/ptr.rs +++ b/lib/wasi/src/ptr.rs @@ -82,7 +82,16 @@ impl WasmPtr { } #[inline(always)] - pub unsafe fn get_utf8_str(self, memory: &Memory, str_len: u32) -> Option<&str> { - self.0.get_utf8_str(memory, str_len) + pub unsafe fn get_utf8_str<'a>( + self, + memory: &'a Memory, + str_len: u32, + ) -> Option> { + self.0.get_utf8_str(memory, str_len).map(Into::into) + } + + #[inline(always)] + pub unsafe fn get_utf8_string(self, memory: &Memory, str_len: u32) -> Option { + self.0.get_utf8_string(memory, str_len) } } diff --git a/lib/wasi/src/state/builder.rs b/lib/wasi/src/state/builder.rs index e950decd110..904f075c15e 100644 --- a/lib/wasi/src/state/builder.rs +++ b/lib/wasi/src/state/builder.rs @@ -1,10 +1,11 @@ //! Builder system for configuring a [`WasiState`] and creating it. -use crate::state::{WasiFile, WasiFs, WasiFsError, WasiState}; +use crate::state::{default_fs_backing, WasiFs, WasiState}; use crate::syscalls::types::{__WASI_STDERR_FILENO, __WASI_STDIN_FILENO, __WASI_STDOUT_FILENO}; use crate::WasiEnv; use std::path::{Path, PathBuf}; use thiserror::Error; +use wasmer_vfs::{FsError, VirtualFile}; /// Creates an empty [`WasiStateBuilder`]. /// @@ -37,15 +38,18 @@ pub struct WasiStateBuilder { args: Vec>, envs: Vec<(Vec, Vec)>, preopens: Vec, + vfs_preopens: Vec, #[allow(clippy::type_complexity)] setup_fs_fn: Option Result<(), String> + Send>>, - stdout_override: Option>, - stderr_override: Option>, - stdin_override: Option>, + stdout_override: Option>, + stderr_override: Option>, + stdin_override: Option>, + fs_override: Option>, } impl std::fmt::Debug for WasiStateBuilder { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + // TODO: update this when stable f.debug_struct("WasiStateBuilder") .field("args", &self.args) .field("envs", &self.envs) @@ -76,7 +80,7 @@ pub enum WasiStateCreationError { #[error("wasi filesystem setup error: `{0}`")] WasiFsSetupError(String), #[error(transparent)] - WasiFsError(WasiFsError), + FileSystemError(FsError), } fn validate_mapped_dir_alias(alias: &str) -> Result<(), WasiStateCreationError> { @@ -219,6 +223,19 @@ impl WasiStateBuilder { Ok(self) } + /// Preopen the given directories from the + /// Virtual FS. + pub fn preopen_vfs_dirs(&mut self, po_dirs: I) -> Result<&mut Self, WasiStateCreationError> + where + I: IntoIterator, + { + for po_dir in po_dirs { + self.vfs_preopens.push(po_dir); + } + + Ok(self) + } + /// Preopen a directory with a different name exposed to the WASI. pub fn map_dir( &mut self, @@ -260,7 +277,7 @@ impl WasiStateBuilder { /// Overwrite the default WASI `stdout`, if you want to hold on to the /// original `stdout` use [`WasiFs::swap_file`] after building. - pub fn stdout(&mut self, new_file: Box) -> &mut Self { + pub fn stdout(&mut self, new_file: Box) -> &mut Self { self.stdout_override = Some(new_file); self @@ -268,7 +285,7 @@ impl WasiStateBuilder { /// Overwrite the default WASI `stderr`, if you want to hold on to the /// original `stderr` use [`WasiFs::swap_file`] after building. - pub fn stderr(&mut self, new_file: Box) -> &mut Self { + pub fn stderr(&mut self, new_file: Box) -> &mut Self { self.stderr_override = Some(new_file); self @@ -276,13 +293,22 @@ impl WasiStateBuilder { /// Overwrite the default WASI `stdin`, if you want to hold on to the /// original `stdin` use [`WasiFs::swap_file`] after building. - pub fn stdin(&mut self, new_file: Box) -> &mut Self { + pub fn stdin(&mut self, new_file: Box) -> &mut Self { self.stdin_override = Some(new_file); self } - /// Setup the WASI filesystem before running + /// Sets the FileSystem to be used with this WASI instance. + /// + /// This is usually used in case a custom `wasmer_vfs::FileSystem` is needed. + pub fn set_fs(&mut self, fs: Box) -> &mut Self { + self.fs_override = Some(fs); + + self + } + + /// Configure the WASI filesystem before running. // TODO: improve ergonomics on this function pub fn setup_fs( &mut self, @@ -296,6 +322,22 @@ impl WasiStateBuilder { /// Consumes the [`WasiStateBuilder`] and produces a [`WasiState`] /// /// Returns the error from `WasiFs::new` if there's an error + /// + /// # Calling `build` multiple times + /// + /// Calling this method multiple times might not produce a + /// determinisic result. This method is changing the builder's + /// internal state. The values set with the following methods are + /// reset to their defaults: + /// + /// * [Self::set_fs], + /// * [Self::stdin], + /// * [Self::stdout], + /// * [Self::stderr]. + /// + /// Ideally, the builder must be refactord to update `&mut self` + /// to `mut self` for every _builder method_, but it will break + /// existing code. It will be addressed in a next major release. pub fn build(&mut self) -> Result { for (i, arg) in self.args.iter().enumerate() { for b in arg.iter() { @@ -359,29 +401,38 @@ impl WasiStateBuilder { } } - // self.preopens are checked in [`PreopenDirBuilder::build`] + let fs_backing = self + .fs_override + .take() + .unwrap_or_else(|| default_fs_backing()); - let mut wasi_fs = WasiFs::new_with_preopen(&self.preopens) + // self.preopens are checked in [`PreopenDirBuilder::build`] + let mut wasi_fs = WasiFs::new_with_preopen(&self.preopens, &self.vfs_preopens, fs_backing) .map_err(WasiStateCreationError::WasiFsCreationError)?; + // set up the file system, overriding base files and calling the setup function if let Some(stdin_override) = self.stdin_override.take() { wasi_fs .swap_file(__WASI_STDIN_FILENO, stdin_override) - .map_err(WasiStateCreationError::WasiFsError)?; + .map_err(WasiStateCreationError::FileSystemError)?; } + if let Some(stdout_override) = self.stdout_override.take() { wasi_fs .swap_file(__WASI_STDOUT_FILENO, stdout_override) - .map_err(WasiStateCreationError::WasiFsError)?; + .map_err(WasiStateCreationError::FileSystemError)?; } + if let Some(stderr_override) = self.stderr_override.take() { wasi_fs .swap_file(__WASI_STDERR_FILENO, stderr_override) - .map_err(WasiStateCreationError::WasiFsError)?; + .map_err(WasiStateCreationError::FileSystemError)?; } + if let Some(f) = &self.setup_fs_fn { f(&mut wasi_fs).map_err(WasiStateCreationError::WasiFsSetupError)?; } + Ok(WasiState { fs: wasi_fs, args: self.args.clone(), @@ -402,9 +453,17 @@ impl WasiStateBuilder { /// Consumes the [`WasiStateBuilder`] and produces a [`WasiEnv`] /// - /// Returns the error from `WasiFs::new` if there's an error + /// Returns the error from `WasiFs::new` if there's an error. + /// + /// # Calling `finalize` multiple times + /// + /// Calling this method multiple times might not produce a + /// determinisic result. This method is calling [Self::build], + /// which is changing the builder's internal state. See + /// [Self::build]'s documentation to learn more. pub fn finalize(&mut self) -> Result { let state = self.build()?; + Ok(WasiEnv::new(state)) } } diff --git a/lib/wasi/src/state/mod.rs b/lib/wasi/src/state/mod.rs index 4766b8006ab..81c76fcea78 100644 --- a/lib/wasi/src/state/mod.rs +++ b/lib/wasi/src/state/mod.rs @@ -10,7 +10,7 @@ //! `generate_import_object` function. These are directories that the caller has given //! the WASI module permission to access. //! -//! You can implement `WasiFile` for your own types to get custom behavior and extend WASI, see the +//! You can implement `VirtualFile` for your own types to get custom behavior and extend WASI, see the //! [WASI plugin example](https://github.com/wasmerio/wasmer/blob/master/examples/plugin.rs). #![allow(clippy::cognitive_complexity, clippy::too_many_arguments)] @@ -23,18 +23,19 @@ pub use self::types::*; use crate::syscalls::types::*; use generational_arena::Arena; pub use generational_arena::Index as Inode; +#[cfg(feature = "enable-serde")] use serde::{Deserialize, Serialize}; use std::collections::HashMap; use std::{ borrow::Borrow, cell::Cell, - fs, io::Write, path::{Path, PathBuf}, - time::SystemTime, }; use tracing::debug; +use wasmer_vfs::{FileSystem, FsError, OpenOptions, VirtualFile}; + /// the fd value of the virtual root pub const VIRTUAL_ROOT_FD: __wasi_fd_t = 3; /// all the rights enabled @@ -58,7 +59,8 @@ const STDERR_DEFAULT_RIGHTS: __wasi_rights_t = STDOUT_DEFAULT_RIGHTS; pub const MAX_SYMLINKS: u32 = 128; /// A file that Wasi knows about that may or may not be open -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug)] +#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] pub struct InodeVal { pub stat: __wasi_filestat_t, pub is_preopened: bool, @@ -68,11 +70,12 @@ pub struct InodeVal { /// The core of the filesystem abstraction. Includes directories, /// files, and symlinks. -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug)] +#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] pub enum Kind { File { /// The open file, if it's open - handle: Option>, + handle: Option>, /// The path on the host system where the file is located /// This is deprecated and will be removed soon path: PathBuf, @@ -86,7 +89,7 @@ pub enum Kind { /// Parent directory parent: Option, /// The path on the host system where the directory is located - // TODO: wrap it like WasiFile + // TODO: wrap it like VirtualFile path: PathBuf, /// The entries of a directory are lazily filled. entries: HashMap, @@ -117,7 +120,8 @@ pub enum Kind { }, } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug)] +#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] pub struct Fd { pub rights: __wasi_rights_t, pub rights_inheriting: __wasi_rights_t, @@ -125,7 +129,7 @@ pub struct Fd { pub offset: u64, /// Flags that determine how the [`Fd`] can be used. /// - /// Used when reopening a [`HostFile`] during [`WasiState`] deserialization. + /// Used when reopening a [`VirtualFile`] during [`WasiState`] deserialization. pub open_flags: u16, pub inode: Inode, } @@ -150,9 +154,10 @@ impl Fd { pub const CREATE: u16 = 16; } -#[derive(Debug, Serialize, Deserialize)] /// Warning, modifying these fields directly may cause invariants to break and /// should be considered unsafe. These fields may be made private in a future release +#[derive(Debug)] +#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] pub struct WasiFs { //pub repo: Repo, pub preopen_fds: Vec, @@ -163,12 +168,111 @@ pub struct WasiFs { inode_counter: Cell, /// for fds still open after the file has been deleted pub orphan_fds: HashMap, + #[cfg_attr(feature = "enable-serde", serde(skip, default = "default_fs_backing"))] + fs_backing: Box, +} + +/// Returns the default filesystem backing +pub(crate) fn default_fs_backing() -> Box { + cfg_if::cfg_if! { + if #[cfg(feature = "host-fs")] { + Box::new(wasmer_vfs::host_fs::FileSystem::default()) + } else if #[cfg(feature = "mem-fs")] { + Box::new(wasmer_vfs::mem_fs::FileSystem::default()) + } else { + Box::new(FallbackFileSystem::default()) + } + } +} + +#[derive(Debug, Default)] +pub struct FallbackFileSystem; + +impl FallbackFileSystem { + fn fail() -> ! { + panic!("No filesystem set for wasmer-wasi, please enable either the `host-fs` or `mem-fs` feature or set your custom filesystem with `WasiStateBuilder::set_fs`"); + } +} + +impl FileSystem for FallbackFileSystem { + fn read_dir(&self, _path: &Path) -> Result { + Self::fail(); + } + fn create_dir(&self, _path: &Path) -> Result<(), FsError> { + Self::fail(); + } + fn remove_dir(&self, _path: &Path) -> Result<(), FsError> { + Self::fail(); + } + fn rename(&self, _from: &Path, _to: &Path) -> Result<(), FsError> { + Self::fail(); + } + fn metadata(&self, _path: &Path) -> Result { + Self::fail(); + } + fn symlink_metadata(&self, _path: &Path) -> Result { + Self::fail(); + } + fn remove_file(&self, _path: &Path) -> Result<(), FsError> { + Self::fail(); + } + fn new_open_options(&self) -> wasmer_vfs::OpenOptions { + Self::fail(); + } } impl WasiFs { /// Created for the builder API. like `new` but with more information - pub(crate) fn new_with_preopen(preopens: &[PreopenedDir]) -> Result { - let (mut wasi_fs, root_inode) = Self::new_init()?; + pub(crate) fn new_with_preopen( + preopens: &[PreopenedDir], + vfs_preopens: &[String], + fs_backing: Box, + ) -> Result { + let (mut wasi_fs, root_inode) = Self::new_init(fs_backing)?; + + for preopen_name in vfs_preopens { + let kind = Kind::Dir { + parent: Some(root_inode), + path: PathBuf::from(preopen_name), + entries: Default::default(), + }; + let rights = __WASI_RIGHT_FD_ADVISE + | __WASI_RIGHT_FD_TELL + | __WASI_RIGHT_FD_SEEK + | __WASI_RIGHT_FD_READ + | __WASI_RIGHT_PATH_OPEN + | __WASI_RIGHT_FD_READDIR + | __WASI_RIGHT_PATH_READLINK + | __WASI_RIGHT_PATH_FILESTAT_GET + | __WASI_RIGHT_FD_FILESTAT_GET + | __WASI_RIGHT_PATH_LINK_SOURCE + | __WASI_RIGHT_PATH_RENAME_SOURCE + | __WASI_RIGHT_POLL_FD_READWRITE + | __WASI_RIGHT_SOCK_SHUTDOWN; + let inode = wasi_fs + .create_inode(kind, true, preopen_name.clone()) + .map_err(|e| { + format!( + "Failed to create inode for preopened dir (name `{}`): WASI error code: {}", + preopen_name, e + ) + })?; + let fd_flags = Fd::READ; + let fd = wasi_fs + .create_fd(rights, rights, 0, fd_flags, inode) + .map_err(|e| format!("Could not open fd for file {:?}: {}", preopen_name, e))?; + if let Kind::Root { entries } = &mut wasi_fs.inodes[root_inode].kind { + let existing_entry = entries.insert(preopen_name.clone(), inode); + if existing_entry.is_some() { + return Err(format!( + "Found duplicate entry for alias `{}`", + preopen_name + )); + } + assert!(existing_entry.is_none()) + } + wasi_fs.preopen_fds.push(fd); + } for PreopenedDir { path, @@ -294,7 +398,7 @@ impl WasiFs { /// Private helper function to init the filesystem, called in `new` and /// `new_with_preopen` - fn new_init() -> Result<(Self, Inode), String> { + fn new_init(fs_backing: Box) -> Result<(Self, Inode), String> { debug!("Initializing WASI filesystem"); let inodes = Arena::new(); let mut wasi_fs = Self { @@ -305,6 +409,7 @@ impl WasiFs { next_fd: Cell::new(3), inode_counter: Cell::new(1024), orphan_fds: HashMap::new(), + fs_backing, }; wasi_fs.create_stdin(); wasi_fs.create_stdout(); @@ -341,36 +446,36 @@ impl WasiFs { Ok((wasi_fs, root_inode)) } - /// Get the `WasiFile` object at stdout - pub fn stdout(&self) -> Result<&Option>, WasiFsError> { + /// Get the `VirtualFile` object at stdout + pub fn stdout(&self) -> Result<&Option>, FsError> { self.std_dev_get(__WASI_STDOUT_FILENO) } - /// Get the `WasiFile` object at stdout mutably - pub fn stdout_mut(&mut self) -> Result<&mut Option>, WasiFsError> { + /// Get the `VirtualFile` object at stdout mutably + pub fn stdout_mut(&mut self) -> Result<&mut Option>, FsError> { self.std_dev_get_mut(__WASI_STDOUT_FILENO) } - /// Get the `WasiFile` object at stderr - pub fn stderr(&self) -> Result<&Option>, WasiFsError> { + /// Get the `VirtualFile` object at stderr + pub fn stderr(&self) -> Result<&Option>, FsError> { self.std_dev_get(__WASI_STDERR_FILENO) } - /// Get the `WasiFile` object at stderr mutably - pub fn stderr_mut(&mut self) -> Result<&mut Option>, WasiFsError> { + /// Get the `VirtualFile` object at stderr mutably + pub fn stderr_mut(&mut self) -> Result<&mut Option>, FsError> { self.std_dev_get_mut(__WASI_STDERR_FILENO) } - /// Get the `WasiFile` object at stdin - pub fn stdin(&self) -> Result<&Option>, WasiFsError> { + /// Get the `VirtualFile` object at stdin + pub fn stdin(&self) -> Result<&Option>, FsError> { self.std_dev_get(__WASI_STDIN_FILENO) } - /// Get the `WasiFile` object at stdin mutably - pub fn stdin_mut(&mut self) -> Result<&mut Option>, WasiFsError> { + /// Get the `VirtualFile` object at stdin mutably + pub fn stdin_mut(&mut self) -> Result<&mut Option>, FsError> { self.std_dev_get_mut(__WASI_STDIN_FILENO) } /// Internal helper function to get a standard device handle. /// Expects one of `__WASI_STDIN_FILENO`, `__WASI_STDOUT_FILENO`, `__WASI_STDERR_FILENO`. - fn std_dev_get(&self, fd: __wasi_fd_t) -> Result<&Option>, WasiFsError> { + fn std_dev_get(&self, fd: __wasi_fd_t) -> Result<&Option>, FsError> { if let Some(fd) = self.fd_map.get(&fd) { if let Kind::File { ref handle, .. } = self.inodes[fd.inode].kind { Ok(handle) @@ -380,7 +485,7 @@ impl WasiFs { } } else { // this should only trigger if we made a mistake in this crate - Err(WasiFsError::NoDevice) + Err(FsError::NoDevice) } } /// Internal helper function to mutably get a standard device handle. @@ -388,7 +493,7 @@ impl WasiFs { fn std_dev_get_mut( &mut self, fd: __wasi_fd_t, - ) -> Result<&mut Option>, WasiFsError> { + ) -> Result<&mut Option>, FsError> { if let Some(fd) = self.fd_map.get_mut(&fd) { if let Kind::File { ref mut handle, .. } = self.inodes[fd.inode].kind { Ok(handle) @@ -398,7 +503,7 @@ impl WasiFs { } } else { // this should only trigger if we made a mistake in this crate - Err(WasiFsError::NoDevice) + Err(FsError::NoDevice) } } @@ -426,8 +531,8 @@ impl WasiFs { rights: __wasi_rights_t, rights_inheriting: __wasi_rights_t, flags: __wasi_fdflags_t, - ) -> Result<__wasi_fd_t, WasiFsError> { - let base_fd = self.get_fd(base).map_err(WasiFsError::from_wasi_err)?; + ) -> Result<__wasi_fd_t, FsError> { + let base_fd = self.get_fd(base).map_err(fs_error_from_wasi_err)?; // TODO: check permissions here? probably not, but this should be // an explicit choice, so justify it in a comment when we remove this one let mut cur_inode = base_fd.inode; @@ -440,7 +545,7 @@ impl WasiFs { Kind::Dir { ref entries, .. } | Kind::Root { ref entries } => { if let Some(_entry) = entries.get(&segment_name) { // TODO: this should be fixed - return Err(WasiFsError::AlreadyExists); + return Err(FsError::AlreadyExists); } let kind = Kind::Dir { @@ -464,7 +569,7 @@ impl WasiFs { cur_inode = inode; } - _ => return Err(WasiFsError::BaseNotDirectory), + _ => return Err(FsError::BaseNotDirectory), } } @@ -476,7 +581,7 @@ impl WasiFs { Fd::READ | Fd::WRITE, cur_inode, ) - .map_err(WasiFsError::from_wasi_err) + .map_err(fs_error_from_wasi_err) } /// Opens a user-supplied file in the directory specified with the @@ -486,14 +591,14 @@ impl WasiFs { pub fn open_file_at( &mut self, base: __wasi_fd_t, - file: Box, + file: Box, open_flags: u16, name: String, rights: __wasi_rights_t, rights_inheriting: __wasi_rights_t, flags: __wasi_fdflags_t, - ) -> Result<__wasi_fd_t, WasiFsError> { - let base_fd = self.get_fd(base).map_err(WasiFsError::from_wasi_err)?; + ) -> Result<__wasi_fd_t, FsError> { + let base_fd = self.get_fd(base).map_err(fs_error_from_wasi_err)?; // TODO: check permissions here? probably not, but this should be // an explicit choice, so justify it in a comment when we remove this one let base_inode = base_fd.inode; @@ -502,7 +607,7 @@ impl WasiFs { Kind::Dir { ref entries, .. } | Kind::Root { ref entries } => { if let Some(_entry) = entries.get(&name) { // TODO: eventually change the logic here to allow overwrites - return Err(WasiFsError::AlreadyExists); + return Err(FsError::AlreadyExists); } let kind = Kind::File { @@ -513,7 +618,7 @@ impl WasiFs { let inode = self .create_inode(kind, false, name.clone()) - .map_err(|_| WasiFsError::IOError)?; + .map_err(|_| FsError::IOError)?; // reborrow to insert match &mut self.inodes[base_inode].kind { Kind::Dir { @@ -526,9 +631,9 @@ impl WasiFs { } self.create_fd(rights, rights_inheriting, flags, open_flags, inode) - .map_err(WasiFsError::from_wasi_err) + .map_err(fs_error_from_wasi_err) } - _ => Err(WasiFsError::BaseNotDirectory), + _ => Err(FsError::BaseNotDirectory), } } @@ -539,8 +644,8 @@ impl WasiFs { pub fn swap_file( &mut self, fd: __wasi_fd_t, - file: Box, - ) -> Result>, WasiFsError> { + file: Box, + ) -> Result>, FsError> { let mut ret = Some(file); match fd { __WASI_STDIN_FILENO => { @@ -553,14 +658,14 @@ impl WasiFs { std::mem::swap(self.stderr_mut()?, &mut ret); } _ => { - let base_fd = self.get_fd(fd).map_err(WasiFsError::from_wasi_err)?; + let base_fd = self.get_fd(fd).map_err(fs_error_from_wasi_err)?; let base_inode = base_fd.inode; match &mut self.inodes[base_inode].kind { Kind::File { ref mut handle, .. } => { std::mem::swap(handle, &mut ret); } - _ => return Err(WasiFsError::NotAFile), + _ => return Err(FsError::NotAFile), } } } @@ -657,7 +762,11 @@ impl WasiFs { cd.push(component); cd }; - let metadata = file.symlink_metadata().ok().ok_or(__WASI_EINVAL)?; + let metadata = self + .fs_backing + .symlink_metadata(&file) + .ok() + .ok_or(__WASI_EINVAL)?; let file_type = metadata.file_type(); // we want to insert newly opened dirs and files, but not transient symlinks // TODO: explain why (think about this deeply when well rested) @@ -699,7 +808,7 @@ impl WasiFs { } else { #[cfg(unix)] { - use std::os::unix::fs::FileTypeExt; + //use std::os::unix::fs::FileTypeExt; let file_type: __wasi_filetype_t = if file_type.is_char_device() { __WASI_FILETYPE_CHARACTER_DEVICE @@ -1060,13 +1169,13 @@ impl WasiFs { __WASI_STDIN_FILENO => (), __WASI_STDOUT_FILENO => self .stdout_mut() - .map_err(WasiFsError::into_wasi_err)? + .map_err(fs_error_into_wasi_err)? .as_mut() .and_then(|f| f.flush().ok()) .ok_or(__WASI_EIO)?, __WASI_STDERR_FILENO => self .stderr_mut() - .map_err(WasiFsError::into_wasi_err)? + .map_err(fs_error_into_wasi_err)? .as_mut() .and_then(|f| f.flush().ok()) .ok_or(__WASI_EIO)?, @@ -1193,7 +1302,7 @@ impl WasiFs { fn create_stdout(&mut self) { self.create_std_dev_inner( - Box::new(Stdout), + Box::new(Stdout::default()), "stdout", __WASI_STDOUT_FILENO, STDOUT_DEFAULT_RIGHTS, @@ -1202,7 +1311,7 @@ impl WasiFs { } fn create_stdin(&mut self) { self.create_std_dev_inner( - Box::new(Stdin), + Box::new(Stdin::default()), "stdin", __WASI_STDIN_FILENO, STDIN_DEFAULT_RIGHTS, @@ -1211,7 +1320,7 @@ impl WasiFs { } fn create_stderr(&mut self) { self.create_std_dev_inner( - Box::new(Stderr), + Box::new(Stderr::default()), "stderr", __WASI_STDERR_FILENO, STDERR_DEFAULT_RIGHTS, @@ -1221,7 +1330,7 @@ impl WasiFs { fn create_std_dev_inner( &mut self, - handle: Box, + handle: Box, name: &'static str, raw_fd: __wasi_fd_t, rights: __wasi_rights_t, @@ -1271,9 +1380,9 @@ impl WasiFs { ..__wasi_filestat_t::default() }) } - None => path.metadata().ok()?, + None => self.fs_backing.metadata(path).ok()?, }, - Kind::Dir { path, .. } => path.metadata().ok()?, + Kind::Dir { path, .. } => self.fs_backing.metadata(path).ok()?, Kind::Symlink { base_po_dir, path_to_symlink, @@ -1283,7 +1392,7 @@ impl WasiFs { let base_po_inode_v = &self.inodes[*base_po_inode]; match &base_po_inode_v.kind { Kind::Root { .. } => { - path_to_symlink.clone().symlink_metadata().ok()? + self.fs_backing.symlink_metadata(path_to_symlink).ok()? } Kind::Dir { path, .. } => { let mut real_path = path.clone(); @@ -1294,7 +1403,7 @@ impl WasiFs { // TODO: adjust size of symlink, too // for all paths adjusted think about this real_path.push(path_to_symlink); - real_path.symlink_metadata().ok()? + self.fs_backing.symlink_metadata(&real_path).ok()? } // if this triggers, there's a bug in the symlink code _ => unreachable!("Symlink pointing to something that's not a directory as its base preopened directory"), @@ -1303,26 +1412,11 @@ impl WasiFs { _ => return None, }; Some(__wasi_filestat_t { - st_filetype: host_file_type_to_wasi_file_type(md.file_type()), + st_filetype: virtual_file_type_to_wasi_file_type(md.file_type()), st_size: md.len(), - st_atim: md - .accessed() - .ok()? - .duration_since(SystemTime::UNIX_EPOCH) - .ok()? - .as_nanos() as u64, - st_mtim: md - .modified() - .ok()? - .duration_since(SystemTime::UNIX_EPOCH) - .ok()? - .as_nanos() as u64, - st_ctim: md - .created() - .ok() - .and_then(|ct| ct.duration_since(SystemTime::UNIX_EPOCH).ok()) - .map(|ct| ct.as_nanos() as u64) - .unwrap_or(0), + st_atim: md.accessed(), + st_mtim: md.modified(), + st_ctim: md.created(), ..__wasi_filestat_t::default() }) } @@ -1383,6 +1477,55 @@ impl WasiFs { } } +// Implementations of direct to FS calls so that we can easily change their implementation +impl WasiState { + pub(crate) fn fs_read_dir>( + &self, + path: P, + ) -> Result { + self.fs + .fs_backing + .read_dir(path.as_ref()) + .map_err(fs_error_into_wasi_err) + } + + pub(crate) fn fs_create_dir>(&self, path: P) -> Result<(), __wasi_errno_t> { + self.fs + .fs_backing + .create_dir(path.as_ref()) + .map_err(fs_error_into_wasi_err) + } + + pub(crate) fn fs_remove_dir>(&self, path: P) -> Result<(), __wasi_errno_t> { + self.fs + .fs_backing + .remove_dir(path.as_ref()) + .map_err(fs_error_into_wasi_err) + } + + pub(crate) fn fs_rename, Q: AsRef>( + &self, + from: P, + to: Q, + ) -> Result<(), __wasi_errno_t> { + self.fs + .fs_backing + .rename(from.as_ref(), to.as_ref()) + .map_err(fs_error_into_wasi_err) + } + + pub(crate) fn fs_remove_file>(&self, path: P) -> Result<(), __wasi_errno_t> { + self.fs + .fs_backing + .remove_file(path.as_ref()) + .map_err(fs_error_into_wasi_err) + } + + pub(crate) fn fs_new_open_options(&self) -> OpenOptions { + self.fs.fs_backing.new_open_options() + } +} + /// Top level data type containing all* the state with which WASI can /// interact. /// @@ -1411,7 +1554,8 @@ impl WasiFs { /// # Ok(()) /// # } /// ``` -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug)] +#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] pub struct WasiState { pub fs: WasiFs, pub args: Vec>, @@ -1427,17 +1571,19 @@ impl WasiState { } /// Turn the WasiState into bytes + #[cfg(feature = "enable-serde")] pub fn freeze(&self) -> Option> { bincode::serialize(self).ok() } /// Get a WasiState from bytes + #[cfg(feature = "enable-serde")] pub fn unfreeze(bytes: &[u8]) -> Option { bincode::deserialize(bytes).ok() } } -pub fn host_file_type_to_wasi_file_type(file_type: fs::FileType) -> __wasi_filetype_t { +pub fn virtual_file_type_to_wasi_file_type(file_type: wasmer_vfs::FileType) -> __wasi_filetype_t { // TODO: handle other file types if file_type.is_dir() { __WASI_FILETYPE_DIRECTORY diff --git a/lib/wasi/src/state/types.rs b/lib/wasi/src/state/types.rs index 8f6b2377893..5276de8d364 100644 --- a/lib/wasi/src/state/types.rs +++ b/lib/wasi/src/state/types.rs @@ -1,249 +1,73 @@ /// types for use in the WASI filesystem use crate::syscalls::types::*; -use serde::{de, Deserialize, Serialize}; -use std::any::Any; +#[cfg(feature = "enable-serde")] +use serde::{Deserialize, Serialize}; #[cfg(unix)] use std::convert::TryInto; -use std::fmt; use std::{ collections::VecDeque, - fs, io::{self, Read, Seek, Write}, - path::PathBuf, - time::SystemTime, }; -use thiserror::Error; -use tracing::debug; -/// Error type for external users -#[derive(Error, Copy, Clone, Debug, PartialEq, Eq)] -#[allow(dead_code)] -// dead code beacuse this is for external use -pub enum WasiFsError { - /// The fd given as a base was not a directory so the operation was not possible - #[error("fd not a directory")] - BaseNotDirectory, - /// Expected a file but found not a file - #[error("fd not a file")] - NotAFile, - /// The fd given was not usable - #[error("invalid fd")] - InvalidFd, - /// File exists - #[error("file exists")] - AlreadyExists, - /// Something failed when doing IO. These errors can generally not be handled. - /// It may work if tried again. - #[error("io error")] - IOError, - /// The address was in use - #[error("address is in use")] - AddressInUse, - /// The address could not be found - #[error("address could not be found")] - AddressNotAvailable, - /// A pipe was closed - #[error("broken pipe (was closed)")] - BrokenPipe, - /// The connection was aborted - #[error("connection aborted")] - ConnectionAborted, - /// The connection request was refused - #[error("connection refused")] - ConnectionRefused, - /// The connection was reset - #[error("connection reset")] - ConnectionReset, - /// The operation was interrupted before it could finish - #[error("operation interrupted")] - Interrupted, - /// Invalid internal data, if the argument data is invalid, use `InvalidInput` - #[error("invalid internal data")] - InvalidData, - /// The provided data is invalid - #[error("invalid input")] - InvalidInput, - /// Could not perform the operation because there was not an open connection - #[error("connection is not open")] - NotConnected, - /// The requested file or directory could not be found - #[error("entity not found")] - EntityNotFound, - /// The requested device couldn't be accessed - #[error("can't access device")] - NoDevice, - /// Caller was not allowed to perform this operation - #[error("permission denied")] - PermissionDenied, - /// The operation did not complete within the given amount of time - #[error("time out")] - TimedOut, - /// Found EOF when EOF was not expected - #[error("unexpected eof")] - UnexpectedEof, - /// Operation would block, this error lets the caller know that they can try again - #[error("blocking operation. try again")] - WouldBlock, - /// A call to write returned 0 - #[error("write returned 0")] - WriteZero, - /// A WASI error without an external name. If you encounter this it means - /// that there's probably a bug on our side (maybe as simple as forgetting to wrap - /// this error, but perhaps something broke) - #[error("unknown error: {0}")] - UnknownError(__wasi_errno_t), -} - -impl WasiFsError { - pub fn from_wasi_err(err: __wasi_errno_t) -> WasiFsError { - match err { - __WASI_EBADF => WasiFsError::InvalidFd, - __WASI_EEXIST => WasiFsError::AlreadyExists, - __WASI_EIO => WasiFsError::IOError, - __WASI_EADDRINUSE => WasiFsError::AddressInUse, - __WASI_EADDRNOTAVAIL => WasiFsError::AddressNotAvailable, - __WASI_EPIPE => WasiFsError::BrokenPipe, - __WASI_ECONNABORTED => WasiFsError::ConnectionAborted, - __WASI_ECONNREFUSED => WasiFsError::ConnectionRefused, - __WASI_ECONNRESET => WasiFsError::ConnectionReset, - __WASI_EINTR => WasiFsError::Interrupted, - __WASI_EINVAL => WasiFsError::InvalidInput, - __WASI_ENOTCONN => WasiFsError::NotConnected, - __WASI_ENODEV => WasiFsError::NoDevice, - __WASI_ENOENT => WasiFsError::EntityNotFound, - __WASI_EPERM => WasiFsError::PermissionDenied, - __WASI_ETIMEDOUT => WasiFsError::TimedOut, - __WASI_EPROTO => WasiFsError::UnexpectedEof, - __WASI_EAGAIN => WasiFsError::WouldBlock, - __WASI_ENOSPC => WasiFsError::WriteZero, - _ => WasiFsError::UnknownError(err), - } - } - - pub fn into_wasi_err(self) -> __wasi_errno_t { - match self { - WasiFsError::AlreadyExists => __WASI_EEXIST, - WasiFsError::AddressInUse => __WASI_EADDRINUSE, - WasiFsError::AddressNotAvailable => __WASI_EADDRNOTAVAIL, - WasiFsError::BaseNotDirectory => __WASI_ENOTDIR, - WasiFsError::BrokenPipe => __WASI_EPIPE, - WasiFsError::ConnectionAborted => __WASI_ECONNABORTED, - WasiFsError::ConnectionRefused => __WASI_ECONNREFUSED, - WasiFsError::ConnectionReset => __WASI_ECONNRESET, - WasiFsError::Interrupted => __WASI_EINTR, - WasiFsError::InvalidData => __WASI_EIO, - WasiFsError::InvalidFd => __WASI_EBADF, - WasiFsError::InvalidInput => __WASI_EINVAL, - WasiFsError::IOError => __WASI_EIO, - WasiFsError::NoDevice => __WASI_ENODEV, - WasiFsError::NotAFile => __WASI_EINVAL, - WasiFsError::NotConnected => __WASI_ENOTCONN, - WasiFsError::EntityNotFound => __WASI_ENOENT, - WasiFsError::PermissionDenied => __WASI_EPERM, - WasiFsError::TimedOut => __WASI_ETIMEDOUT, - WasiFsError::UnexpectedEof => __WASI_EPROTO, - WasiFsError::WouldBlock => __WASI_EAGAIN, - WasiFsError::WriteZero => __WASI_ENOSPC, - WasiFsError::UnknownError(ec) => ec, - } - } -} - -/// This trait relies on your file closing when it goes out of scope via `Drop` -#[typetag::serde(tag = "type")] -pub trait WasiFile: fmt::Debug + Send + Write + Read + Seek + 'static + Upcastable { - /// the last time the file was accessed in nanoseconds as a UNIX timestamp - fn last_accessed(&self) -> __wasi_timestamp_t; - - /// the last time the file was modified in nanoseconds as a UNIX timestamp - fn last_modified(&self) -> __wasi_timestamp_t; - - /// the time at which the file was created in nanoseconds as a UNIX timestamp - fn created_time(&self) -> __wasi_timestamp_t; - - /// set the last time the file was accessed in nanoseconds as a UNIX timestamp - fn set_last_accessed(&self, _last_accessed: __wasi_timestamp_t) { - debug!("{:?} did nothing in WasiFile::set_last_accessed due to using the default implementation", self); - } - - /// set the last time the file was modified in nanoseconds as a UNIX timestamp - fn set_last_modified(&self, _last_modified: __wasi_timestamp_t) { - debug!("{:?} did nothing in WasiFile::set_last_modified due to using the default implementation", self); - } - - /// set the time at which the file was created in nanoseconds as a UNIX timestamp - fn set_created_time(&self, _created_time: __wasi_timestamp_t) { - debug!( - "{:?} did nothing in WasiFile::set_created_time to using the default implementation", - self - ); - } - - /// the size of the file in bytes - fn size(&self) -> u64; - - /// Change the size of the file, if the `new_size` is greater than the current size - /// the extra bytes will be allocated and zeroed - fn set_len(&mut self, _new_size: __wasi_filesize_t) -> Result<(), WasiFsError>; - - /// Request deletion of the file - fn unlink(&mut self) -> Result<(), WasiFsError>; - - /// Store file contents and metadata to disk - /// Default implementation returns `Ok(())`. You should implement this method if you care - /// about flushing your cache to permanent storage - fn sync_to_disk(&self) -> Result<(), WasiFsError> { - Ok(()) - } - - /// Moves the file to a new location - /// NOTE: the signature of this function will change before stabilization - // TODO: stablizie this in 0.7.0 or 0.8.0 by removing default impl - fn rename_file(&self, _new_name: &std::path::Path) -> Result<(), WasiFsError> { - panic!("Default implementation for now as this method is unstable; this default implementation or this entire method may be removed in a future release."); - } - - /// Returns the number of bytes available. This function must not block - fn bytes_available(&self) -> Result; - - /// Used for polling. Default returns `None` because this method cannot be implemented for most types - /// Returns the underlying host fd - fn get_raw_fd(&self) -> Option { - None - } -} - -// Implementation of `Upcastable` taken from https://users.rust-lang.org/t/why-does-downcasting-not-work-for-subtraits/33286/7 . -/// Trait needed to get downcasting from `WasiFile` to work. -pub trait Upcastable { - fn upcast_any_ref(&'_ self) -> &'_ dyn Any; - fn upcast_any_mut(&'_ mut self) -> &'_ mut dyn Any; - fn upcast_any_box(self: Box) -> Box; -} - -impl Upcastable for T { - #[inline] - fn upcast_any_ref(&'_ self) -> &'_ dyn Any { - self - } - #[inline] - fn upcast_any_mut(&'_ mut self) -> &'_ mut dyn Any { - self - } - #[inline] - fn upcast_any_box(self: Box) -> Box { - self - } -} - -impl dyn WasiFile + 'static { - #[inline] - pub fn downcast_ref(&'_ self) -> Option<&'_ T> { - self.upcast_any_ref().downcast_ref::() - } - #[inline] - pub fn downcast_mut(&'_ mut self) -> Option<&'_ mut T> { - self.upcast_any_mut().downcast_mut::() +#[cfg(feature = "host-fs")] +pub use wasmer_vfs::host_fs::{Stderr, Stdin, Stdout}; +#[cfg(feature = "mem-fs")] +pub use wasmer_vfs::mem_fs::{Stderr, Stdin, Stdout}; + +use wasmer_vfs::{FsError, VirtualFile}; + +pub fn fs_error_from_wasi_err(err: __wasi_errno_t) -> FsError { + match err { + __WASI_EBADF => FsError::InvalidFd, + __WASI_EEXIST => FsError::AlreadyExists, + __WASI_EIO => FsError::IOError, + __WASI_EADDRINUSE => FsError::AddressInUse, + __WASI_EADDRNOTAVAIL => FsError::AddressNotAvailable, + __WASI_EPIPE => FsError::BrokenPipe, + __WASI_ECONNABORTED => FsError::ConnectionAborted, + __WASI_ECONNREFUSED => FsError::ConnectionRefused, + __WASI_ECONNRESET => FsError::ConnectionReset, + __WASI_EINTR => FsError::Interrupted, + __WASI_EINVAL => FsError::InvalidInput, + __WASI_ENOTCONN => FsError::NotConnected, + __WASI_ENODEV => FsError::NoDevice, + __WASI_ENOENT => FsError::EntityNotFound, + __WASI_EPERM => FsError::PermissionDenied, + __WASI_ETIMEDOUT => FsError::TimedOut, + __WASI_EPROTO => FsError::UnexpectedEof, + __WASI_EAGAIN => FsError::WouldBlock, + __WASI_ENOSPC => FsError::WriteZero, + __WASI_ENOTEMPTY => FsError::DirectoryNotEmpty, + _ => FsError::UnknownError, + } +} + +pub fn fs_error_into_wasi_err(fs_error: FsError) -> __wasi_errno_t { + match fs_error { + FsError::AlreadyExists => __WASI_EEXIST, + FsError::AddressInUse => __WASI_EADDRINUSE, + FsError::AddressNotAvailable => __WASI_EADDRNOTAVAIL, + FsError::BaseNotDirectory => __WASI_ENOTDIR, + FsError::BrokenPipe => __WASI_EPIPE, + FsError::ConnectionAborted => __WASI_ECONNABORTED, + FsError::ConnectionRefused => __WASI_ECONNREFUSED, + FsError::ConnectionReset => __WASI_ECONNRESET, + FsError::Interrupted => __WASI_EINTR, + FsError::InvalidData => __WASI_EIO, + FsError::InvalidFd => __WASI_EBADF, + FsError::InvalidInput => __WASI_EINVAL, + FsError::IOError => __WASI_EIO, + FsError::NoDevice => __WASI_ENODEV, + FsError::NotAFile => __WASI_EINVAL, + FsError::NotConnected => __WASI_ENOTCONN, + FsError::EntityNotFound => __WASI_ENOENT, + FsError::PermissionDenied => __WASI_EPERM, + FsError::TimedOut => __WASI_ETIMEDOUT, + FsError::UnexpectedEof => __WASI_EPROTO, + FsError::WouldBlock => __WASI_EAGAIN, + FsError::WriteZero => __WASI_ENOSPC, + FsError::DirectoryNotEmpty => __WASI_ENOTEMPTY, + FsError::Lock | FsError::UnknownError => __WASI_EIO, } } @@ -363,19 +187,19 @@ impl PollEventBuilder { #[cfg(unix)] pub(crate) fn poll( - selfs: &[&dyn WasiFile], + selfs: &[&dyn VirtualFile], events: &[PollEventSet], seen_events: &mut [PollEventSet], -) -> Result { +) -> Result { if !(selfs.len() == events.len() && events.len() == seen_events.len()) { - return Err(WasiFsError::InvalidInput); + return Err(FsError::InvalidInput); } let mut fds = selfs .iter() .enumerate() - .filter_map(|(i, s)| s.get_raw_fd().map(|rfd| (i, rfd))) + .filter_map(|(i, s)| s.get_fd().map(|rfd| (i, rfd))) .map(|(i, host_fd)| libc::pollfd { - fd: host_fd, + fd: host_fd.try_into().unwrap(), events: poll_event_set_to_platform_poll_events(events[i]), revents: 0, }) @@ -384,7 +208,7 @@ pub(crate) fn poll( if result < 0 { // TODO: check errno and return value - return Err(WasiFsError::IOError); + return Err(FsError::IOError); } // convert result and write back values for (i, fd) in fds.into_iter().enumerate() { @@ -396,583 +220,18 @@ pub(crate) fn poll( #[cfg(not(unix))] pub(crate) fn poll( - _selfs: &[&dyn WasiFile], + _selfs: &[&dyn VirtualFile], _events: &[PollEventSet], _seen_events: &mut [PollEventSet], -) -> Result<(), WasiFsError> { - unimplemented!("HostFile::poll in WasiFile is not implemented for non-Unix-like targets yet"); +) -> Result<(), FsError> { + unimplemented!("VirtualFile::poll is not implemented for non-Unix-like targets yet"); } pub trait WasiPath {} -/// A thin wrapper around `std::fs::File` -#[derive(Debug, Serialize)] -pub struct HostFile { - #[serde(skip_serializing)] - pub inner: fs::File, - pub host_path: PathBuf, - flags: u16, -} - -impl<'de> Deserialize<'de> for HostFile { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - #[derive(Deserialize)] - #[serde(field_identifier, rename_all = "snake_case")] - enum Field { - HostPath, - Flags, - } - - struct HostFileVisitor; - - impl<'de> de::Visitor<'de> for HostFileVisitor { - type Value = HostFile; - - fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { - formatter.write_str("struct HostFile") - } - - fn visit_seq(self, mut seq: V) -> Result - where - V: de::SeqAccess<'de>, - { - let host_path = seq - .next_element()? - .ok_or_else(|| de::Error::invalid_length(0, &self))?; - let flags = seq - .next_element()? - .ok_or_else(|| de::Error::invalid_length(1, &self))?; - let inner = std::fs::OpenOptions::new() - .read(flags & HostFile::READ != 0) - .write(flags & HostFile::WRITE != 0) - .append(flags & HostFile::APPEND != 0) - .open(&host_path) - .map_err(|_| de::Error::custom("Could not open file on this system"))?; - Ok(HostFile { - inner, - host_path, - flags, - }) - } - - fn visit_map(self, mut map: V) -> Result - where - V: de::MapAccess<'de>, - { - let mut host_path = None; - let mut flags = None; - while let Some(key) = map.next_key()? { - match key { - Field::HostPath => { - if host_path.is_some() { - return Err(de::Error::duplicate_field("host_path")); - } - host_path = Some(map.next_value()?); - } - Field::Flags => { - if flags.is_some() { - return Err(de::Error::duplicate_field("flags")); - } - flags = Some(map.next_value()?); - } - } - } - let host_path = host_path.ok_or_else(|| de::Error::missing_field("host_path"))?; - let flags = flags.ok_or_else(|| de::Error::missing_field("flags"))?; - let inner = std::fs::OpenOptions::new() - .read(flags & HostFile::READ != 0) - .write(flags & HostFile::WRITE != 0) - .append(flags & HostFile::APPEND != 0) - .open(&host_path) - .map_err(|_| de::Error::custom("Could not open file on this system"))?; - Ok(HostFile { - inner, - host_path, - flags, - }) - } - } - - const FIELDS: &[&str] = &["host_path", "flags"]; - deserializer.deserialize_struct("HostFile", FIELDS, HostFileVisitor) - } -} - -impl HostFile { - const READ: u16 = 1; - const WRITE: u16 = 2; - const APPEND: u16 = 4; - - /// creates a new host file from a `std::fs::File` and a path - pub fn new(file: fs::File, host_path: PathBuf, read: bool, write: bool, append: bool) -> Self { - let mut flags = 0; - if read { - flags |= Self::READ; - } - if write { - flags |= Self::WRITE; - } - if append { - flags |= Self::APPEND; - } - Self { - inner: file, - host_path, - flags, - } - } - - pub fn metadata(&self) -> fs::Metadata { - self.inner.metadata().unwrap() - } -} - -impl Read for HostFile { - fn read(&mut self, buf: &mut [u8]) -> io::Result { - self.inner.read(buf) - } - fn read_to_end(&mut self, buf: &mut Vec) -> io::Result { - self.inner.read_to_end(buf) - } - fn read_to_string(&mut self, buf: &mut String) -> io::Result { - self.inner.read_to_string(buf) - } - fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> { - self.inner.read_exact(buf) - } -} -impl Seek for HostFile { - fn seek(&mut self, pos: io::SeekFrom) -> io::Result { - self.inner.seek(pos) - } -} -impl Write for HostFile { - fn write(&mut self, buf: &[u8]) -> io::Result { - self.inner.write(buf) - } - fn flush(&mut self) -> io::Result<()> { - self.inner.flush() - } - fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { - self.inner.write_all(buf) - } - fn write_fmt(&mut self, fmt: ::std::fmt::Arguments) -> io::Result<()> { - self.inner.write_fmt(fmt) - } -} - -#[typetag::serde] -impl WasiFile for HostFile { - fn last_accessed(&self) -> u64 { - self.metadata() - .accessed() - .ok() - .and_then(|ct| ct.duration_since(SystemTime::UNIX_EPOCH).ok()) - .map(|ct| ct.as_nanos() as u64) - .unwrap_or(0) - } - - fn set_last_accessed(&self, _last_accessed: __wasi_timestamp_t) { - // TODO: figure out how to do this - } - - fn last_modified(&self) -> u64 { - self.metadata() - .modified() - .ok() - .and_then(|ct| ct.duration_since(SystemTime::UNIX_EPOCH).ok()) - .map(|ct| ct.as_nanos() as u64) - .unwrap_or(0) - } - - fn set_last_modified(&self, _last_modified: __wasi_timestamp_t) { - // TODO: figure out how to do this - } - - fn created_time(&self) -> u64 { - self.metadata() - .created() - .ok() - .and_then(|ct| ct.duration_since(SystemTime::UNIX_EPOCH).ok()) - .map(|ct| ct.as_nanos() as u64) - .unwrap_or(0) - } - - fn set_created_time(&self, _created_time: __wasi_timestamp_t) { - // TODO: figure out how to do this - } - - fn size(&self) -> u64 { - self.metadata().len() - } - - fn set_len(&mut self, new_size: __wasi_filesize_t) -> Result<(), WasiFsError> { - fs::File::set_len(&self.inner, new_size).map_err(Into::into) - } - - fn unlink(&mut self) -> Result<(), WasiFsError> { - std::fs::remove_file(&self.host_path).map_err(Into::into) - } - fn sync_to_disk(&self) -> Result<(), WasiFsError> { - self.inner.sync_all().map_err(Into::into) - } - - fn rename_file(&self, new_name: &std::path::Path) -> Result<(), WasiFsError> { - std::fs::rename(&self.host_path, new_name).map_err(Into::into) - } - - fn bytes_available(&self) -> Result { - // unwrap is safe because of get_raw_fd implementation - let host_fd = self.get_raw_fd().unwrap(); - - host_file_bytes_available(host_fd) - } - - #[cfg(unix)] - fn get_raw_fd(&self) -> Option { - use std::os::unix::io::AsRawFd; - Some(self.inner.as_raw_fd()) - } - #[cfg(not(unix))] - fn get_raw_fd(&self) -> Option { - unimplemented!( - "HostFile::get_raw_fd in WasiFile is not implemented for non-Unix-like targets yet" - ); - } -} - -impl From for WasiFsError { - fn from(io_error: io::Error) -> Self { - match io_error.kind() { - io::ErrorKind::AddrInUse => WasiFsError::AddressInUse, - io::ErrorKind::AddrNotAvailable => WasiFsError::AddressNotAvailable, - io::ErrorKind::AlreadyExists => WasiFsError::AlreadyExists, - io::ErrorKind::BrokenPipe => WasiFsError::BrokenPipe, - io::ErrorKind::ConnectionAborted => WasiFsError::ConnectionAborted, - io::ErrorKind::ConnectionRefused => WasiFsError::ConnectionRefused, - io::ErrorKind::ConnectionReset => WasiFsError::ConnectionReset, - io::ErrorKind::Interrupted => WasiFsError::Interrupted, - io::ErrorKind::InvalidData => WasiFsError::InvalidData, - io::ErrorKind::InvalidInput => WasiFsError::InvalidInput, - io::ErrorKind::NotConnected => WasiFsError::NotConnected, - io::ErrorKind::NotFound => WasiFsError::EntityNotFound, - io::ErrorKind::PermissionDenied => WasiFsError::PermissionDenied, - io::ErrorKind::TimedOut => WasiFsError::TimedOut, - io::ErrorKind::UnexpectedEof => WasiFsError::UnexpectedEof, - io::ErrorKind::WouldBlock => WasiFsError::WouldBlock, - io::ErrorKind::WriteZero => WasiFsError::WriteZero, - io::ErrorKind::Other => WasiFsError::IOError, - // if the following triggers, a new error type was added to this non-exhaustive enum - _ => WasiFsError::UnknownError(__WASI_EIO), - } - } -} - -#[cfg(unix)] -fn host_file_bytes_available(host_fd: i32) -> Result { - let mut bytes_found = 0 as libc::c_int; - let result = unsafe { libc::ioctl(host_fd, libc::FIONREAD, &mut bytes_found) }; - - match result { - // success - 0 => Ok(bytes_found.try_into().unwrap_or(0)), - libc::EBADF => Err(WasiFsError::InvalidFd), - libc::EFAULT => Err(WasiFsError::InvalidData), - libc::EINVAL => Err(WasiFsError::InvalidInput), - _ => Err(WasiFsError::IOError), - } -} - -#[cfg(not(unix))] -fn host_file_bytes_available(_raw_fd: i32) -> Result { - unimplemented!("host_file_bytes_available not yet implemented for non-Unix-like targets. This probably means the program tried to use wasi::poll_oneoff") -} - -/// A wrapper type around Stdout that implements `WasiFile` and -/// `Serialize` + `Deserialize`. -#[derive(Debug, Serialize, Deserialize)] -pub struct Stdout; -impl Read for Stdout { - fn read(&mut self, _buf: &mut [u8]) -> io::Result { - Err(io::Error::new( - io::ErrorKind::Other, - "can not read from stdout", - )) - } - fn read_to_end(&mut self, _buf: &mut Vec) -> io::Result { - Err(io::Error::new( - io::ErrorKind::Other, - "can not read from stdout", - )) - } - fn read_to_string(&mut self, _buf: &mut String) -> io::Result { - Err(io::Error::new( - io::ErrorKind::Other, - "can not read from stdout", - )) - } - fn read_exact(&mut self, _buf: &mut [u8]) -> io::Result<()> { - Err(io::Error::new( - io::ErrorKind::Other, - "can not read from stdout", - )) - } -} -impl Seek for Stdout { - fn seek(&mut self, _pos: io::SeekFrom) -> io::Result { - Err(io::Error::new(io::ErrorKind::Other, "can not seek stdout")) - } -} -impl Write for Stdout { - fn write(&mut self, buf: &[u8]) -> io::Result { - io::stdout().write(buf) - } - fn flush(&mut self) -> io::Result<()> { - io::stdout().flush() - } - fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { - io::stdout().write_all(buf) - } - fn write_fmt(&mut self, fmt: ::std::fmt::Arguments) -> io::Result<()> { - io::stdout().write_fmt(fmt) - } -} - -#[typetag::serde] -impl WasiFile for Stdout { - fn last_accessed(&self) -> u64 { - 0 - } - fn last_modified(&self) -> u64 { - 0 - } - fn created_time(&self) -> u64 { - 0 - } - fn size(&self) -> u64 { - 0 - } - fn set_len(&mut self, _new_size: __wasi_filesize_t) -> Result<(), WasiFsError> { - debug!("Calling WasiFile::set_len on stdout; this is probably a bug"); - Err(WasiFsError::PermissionDenied) - } - fn unlink(&mut self) -> Result<(), WasiFsError> { - Ok(()) - } - - fn bytes_available(&self) -> Result { - // unwrap is safe because of get_raw_fd implementation - let host_fd = self.get_raw_fd().unwrap(); - - host_file_bytes_available(host_fd) - } - - #[cfg(unix)] - fn get_raw_fd(&self) -> Option { - use std::os::unix::io::AsRawFd; - Some(io::stdout().as_raw_fd()) - } - - #[cfg(not(unix))] - fn get_raw_fd(&self) -> Option { - unimplemented!( - "Stdout::get_raw_fd in WasiFile is not implemented for non-Unix-like targets yet" - ); - } -} - -/// A wrapper type around Stderr that implements `WasiFile` and -/// `Serialize` + `Deserialize`. -#[derive(Debug, Serialize, Deserialize)] -pub struct Stderr; -impl Read for Stderr { - fn read(&mut self, _buf: &mut [u8]) -> io::Result { - Err(io::Error::new( - io::ErrorKind::Other, - "can not read from stderr", - )) - } - fn read_to_end(&mut self, _buf: &mut Vec) -> io::Result { - Err(io::Error::new( - io::ErrorKind::Other, - "can not read from stderr", - )) - } - fn read_to_string(&mut self, _buf: &mut String) -> io::Result { - Err(io::Error::new( - io::ErrorKind::Other, - "can not read from stderr", - )) - } - fn read_exact(&mut self, _buf: &mut [u8]) -> io::Result<()> { - Err(io::Error::new( - io::ErrorKind::Other, - "can not read from stderr", - )) - } -} -impl Seek for Stderr { - fn seek(&mut self, _pos: io::SeekFrom) -> io::Result { - Err(io::Error::new(io::ErrorKind::Other, "can not seek stderr")) - } -} -impl Write for Stderr { - fn write(&mut self, buf: &[u8]) -> io::Result { - io::stderr().write(buf) - } - fn flush(&mut self) -> io::Result<()> { - io::stderr().flush() - } - fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { - io::stderr().write_all(buf) - } - fn write_fmt(&mut self, fmt: ::std::fmt::Arguments) -> io::Result<()> { - io::stderr().write_fmt(fmt) - } -} - -#[typetag::serde] -impl WasiFile for Stderr { - fn last_accessed(&self) -> u64 { - 0 - } - fn last_modified(&self) -> u64 { - 0 - } - fn created_time(&self) -> u64 { - 0 - } - fn size(&self) -> u64 { - 0 - } - fn set_len(&mut self, _new_size: __wasi_filesize_t) -> Result<(), WasiFsError> { - debug!("Calling WasiFile::set_len on stderr; this is probably a bug"); - Err(WasiFsError::PermissionDenied) - } - fn unlink(&mut self) -> Result<(), WasiFsError> { - Ok(()) - } - - fn bytes_available(&self) -> Result { - // unwrap is safe because of get_raw_fd implementation - let host_fd = self.get_raw_fd().unwrap(); - - host_file_bytes_available(host_fd) - } - - #[cfg(unix)] - fn get_raw_fd(&self) -> Option { - use std::os::unix::io::AsRawFd; - Some(io::stderr().as_raw_fd()) - } - - #[cfg(not(unix))] - fn get_raw_fd(&self) -> Option { - unimplemented!( - "Stderr::get_raw_fd in WasiFile is not implemented for non-Unix-like targets yet" - ); - } -} - -/// A wrapper type around Stdin that implements `WasiFile` and -/// `Serialize` + `Deserialize`. -#[derive(Debug, Serialize, Deserialize)] -pub struct Stdin; -impl Read for Stdin { - fn read(&mut self, buf: &mut [u8]) -> io::Result { - io::stdin().read(buf) - } - fn read_to_end(&mut self, buf: &mut Vec) -> io::Result { - io::stdin().read_to_end(buf) - } - fn read_to_string(&mut self, buf: &mut String) -> io::Result { - io::stdin().read_to_string(buf) - } - fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> { - io::stdin().read_exact(buf) - } -} -impl Seek for Stdin { - fn seek(&mut self, _pos: io::SeekFrom) -> io::Result { - Err(io::Error::new(io::ErrorKind::Other, "can not seek stdin")) - } -} -impl Write for Stdin { - fn write(&mut self, _buf: &[u8]) -> io::Result { - Err(io::Error::new( - io::ErrorKind::Other, - "can not write to stdin", - )) - } - fn flush(&mut self) -> io::Result<()> { - Err(io::Error::new( - io::ErrorKind::Other, - "can not write to stdin", - )) - } - fn write_all(&mut self, _buf: &[u8]) -> io::Result<()> { - Err(io::Error::new( - io::ErrorKind::Other, - "can not write to stdin", - )) - } - fn write_fmt(&mut self, _fmt: ::std::fmt::Arguments) -> io::Result<()> { - Err(io::Error::new( - io::ErrorKind::Other, - "can not write to stdin", - )) - } -} - -#[typetag::serde] -impl WasiFile for Stdin { - fn last_accessed(&self) -> u64 { - 0 - } - fn last_modified(&self) -> u64 { - 0 - } - fn created_time(&self) -> u64 { - 0 - } - fn size(&self) -> u64 { - 0 - } - fn set_len(&mut self, _new_size: __wasi_filesize_t) -> Result<(), WasiFsError> { - debug!("Calling WasiFile::set_len on stdin; this is probably a bug"); - Err(WasiFsError::PermissionDenied) - } - - fn unlink(&mut self) -> Result<(), WasiFsError> { - Ok(()) - } - - fn bytes_available(&self) -> Result { - // unwrap is safe because of get_raw_fd implementation - let host_fd = self.get_raw_fd().unwrap(); - - host_file_bytes_available(host_fd) - } - - #[cfg(unix)] - fn get_raw_fd(&self) -> Option { - use std::os::unix::io::AsRawFd; - Some(io::stdin().as_raw_fd()) - } - - #[cfg(not(unix))] - fn get_raw_fd(&self) -> Option { - unimplemented!( - "Stdin::get_raw_fd in WasiFile is not implemented for non-Unix-like targets yet" - ); - } -} - /// For piping stdio. Stores all output / input in a byte-vector. -#[derive(Debug, Default, Serialize, Deserialize)] +#[derive(Debug, Default)] +#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] pub struct Pipe { buffer: VecDeque, } @@ -1012,8 +271,8 @@ impl Seek for Pipe { } } -#[typetag::serde] -impl WasiFile for Pipe { +#[cfg_attr(feature = "enable-serde", typetag::serde)] +impl VirtualFile for Pipe { fn last_accessed(&self) -> u64 { 0 } @@ -1026,14 +285,14 @@ impl WasiFile for Pipe { fn size(&self) -> u64 { self.buffer.len() as u64 } - fn set_len(&mut self, len: u64) -> Result<(), WasiFsError> { + fn set_len(&mut self, len: u64) -> Result<(), FsError> { self.buffer.resize(len as usize, 0); Ok(()) } - fn unlink(&mut self) -> Result<(), WasiFsError> { + fn unlink(&mut self) -> Result<(), FsError> { Ok(()) } - fn bytes_available(&self) -> Result { + fn bytes_available(&self) -> Result { Ok(self.buffer.len()) } } diff --git a/lib/wasi/src/syscalls/mod.rs b/lib/wasi/src/syscalls/mod.rs index 921ef315d06..ac6a546c0d7 100644 --- a/lib/wasi/src/syscalls/mod.rs +++ b/lib/wasi/src/syscalls/mod.rs @@ -11,6 +11,8 @@ pub mod types { target_vendor = "apple" ))] pub mod unix; +#[cfg(any(target_arch = "wasm32"))] +pub mod wasm32; #[cfg(any(target_os = "windows"))] pub mod windows; @@ -20,9 +22,9 @@ use self::types::*; use crate::{ ptr::{Array, WasmPtr}, state::{ - self, host_file_type_to_wasi_file_type, iterate_poll_events, poll, Fd, HostFile, Inode, - InodeVal, Kind, PollEvent, PollEventBuilder, WasiFile, WasiFsError, WasiState, - MAX_SYMLINKS, + self, fs_error_into_wasi_err, iterate_poll_events, poll, + virtual_file_type_to_wasi_file_type, Fd, Inode, InodeVal, Kind, PollEvent, + PollEventBuilder, WasiState, MAX_SYMLINKS, }, WasiEnv, WasiError, }; @@ -31,6 +33,7 @@ use std::convert::{Infallible, TryInto}; use std::io::{self, Read, Seek, Write}; use tracing::{debug, trace}; use wasmer::{Memory, RuntimeError, Value, WasmCell}; +use wasmer_vfs::{FsError, VirtualFile}; #[cfg(any( target_os = "freebsd", @@ -43,6 +46,9 @@ pub use unix::*; #[cfg(any(target_os = "windows"))] pub use windows::*; +#[cfg(any(target_arch = "wasm32"))] +pub use wasm32::*; + fn write_bytes_inner( mut write_loc: T, memory: &Memory, @@ -90,9 +96,10 @@ fn read_bytes( bytes_read += reader.read(&mut raw_bytes).map_err(|_| __WASI_EIO)? as u32; unsafe { memory - .view::() + .uint8view() .subarray( - iov_inner.buf as usize..=(iov_inner.buf as usize + iov_inner.buf_len as usize), + iov_inner.buf as u32, + iov_inner.buf as u32 + iov_inner.buf_len as u32, ) .copy_from(&raw_bytes); } @@ -363,7 +370,7 @@ pub fn fd_allocate( match &mut state.fs.inodes[inode].kind { Kind::File { handle, .. } => { if let Some(handle) = handle { - wasi_try!(handle.set_len(new_size).map_err(WasiFsError::into_wasi_err)); + wasi_try!(handle.set_len(new_size).map_err(fs_error_into_wasi_err)); } else { return __WASI_EBADF; } @@ -558,7 +565,7 @@ pub fn fd_filestat_set_size( match &mut state.fs.inodes[inode].kind { Kind::File { handle, .. } => { if let Some(handle) = handle { - wasi_try!(handle.set_len(st_size).map_err(WasiFsError::into_wasi_err)); + wasi_try!(handle.set_len(st_size).map_err(fs_error_into_wasi_err)); } else { return __WASI_EBADF; } @@ -615,12 +622,6 @@ pub fn fd_filestat_set_times( wasi_try!(get_current_time_in_nanos()) }; inode.stat.st_atim = time_to_set; - // TODO: set it for more than just files - if let Kind::File { handle, .. } = &mut inode.kind { - if let Some(handle) = handle { - handle.set_last_accessed(time_to_set); - } - } } if fst_flags & __WASI_FILESTAT_SET_MTIM != 0 || fst_flags & __WASI_FILESTAT_SET_MTIM_NOW != 0 { @@ -630,12 +631,6 @@ pub fn fd_filestat_set_times( wasi_try!(get_current_time_in_nanos()) }; inode.stat.st_mtim = time_to_set; - // TODO: set it for more than just files - if let Kind::File { handle, .. } = &mut inode.kind { - if let Some(handle) = handle { - handle.set_last_modified(time_to_set); - } - } } __WASI_ESUCCESS @@ -673,7 +668,7 @@ pub fn fd_pread( let bytes_read = match fd { __WASI_STDIN_FILENO => { if let Some(ref mut stdin) = - wasi_try!(state.fs.stdin_mut().map_err(WasiFsError::into_wasi_err)) + wasi_try!(state.fs.stdin_mut().map_err(fs_error_into_wasi_err)) { wasi_try!(read_bytes(stdin, memory, &iov_cells)) } else { @@ -822,7 +817,7 @@ pub fn fd_pwrite( __WASI_STDIN_FILENO => return __WASI_EINVAL, __WASI_STDOUT_FILENO => { if let Some(ref mut stdout) = - wasi_try!(state.fs.stdout_mut().map_err(WasiFsError::into_wasi_err)) + wasi_try!(state.fs.stdout_mut().map_err(fs_error_into_wasi_err)) { wasi_try!(write_bytes(stdout, memory, &iovs_arr_cell)) } else { @@ -831,7 +826,7 @@ pub fn fd_pwrite( } __WASI_STDERR_FILENO => { if let Some(ref mut stderr) = - wasi_try!(state.fs.stderr_mut().map_err(WasiFsError::into_wasi_err)) + wasi_try!(state.fs.stderr_mut().map_err(fs_error_into_wasi_err)) { wasi_try!(write_bytes(stderr, memory, &iovs_arr_cell)) } else { @@ -908,7 +903,7 @@ pub fn fd_read( let bytes_read = match fd { __WASI_STDIN_FILENO => { if let Some(ref mut stdin) = - wasi_try!(state.fs.stdin_mut().map_err(WasiFsError::into_wasi_err)) + wasi_try!(state.fs.stdin_mut().map_err(fs_error_into_wasi_err)) { wasi_try!(read_bytes(stdin, memory, &iovs_arr_cell)) } else { @@ -996,20 +991,26 @@ pub fn fd_readdir( let entries: Vec<(String, u8, u64)> = match &state.fs.inodes[working_dir.inode].kind { Kind::Dir { path, entries, .. } => { + debug!("Reading dir {:?}", path); // TODO: refactor this code // we need to support multiple calls, // simple and obviously correct implementation for now: // maintain consistent order via lexacographic sorting - let fs_info = wasi_try!(wasi_try!(std::fs::read_dir(path).map_err(|_| __WASI_EIO)) + let fs_info = wasi_try!(wasi_try!(state.fs_read_dir(path)) .collect::, _>>() .map_err(|_| __WASI_EIO)); let mut entry_vec = wasi_try!(fs_info .into_iter() - .map(|entry| Ok(( - entry.file_name().to_string_lossy().to_string(), - host_file_type_to_wasi_file_type(entry.file_type().map_err(|_| __WASI_EIO)?), - 0, // TODO: inode - ))) + .map(|entry| { + let filename = entry.file_name().to_string_lossy().to_string(); + debug!("Getting file: {:?}", filename); + let filetype = virtual_file_type_to_wasi_file_type( + entry.file_type().map_err(|_| __WASI_EIO)?, + ); + Ok(( + filename, filetype, 0, // TODO: inode + )) + }) .collect::, _>>()); entry_vec.extend( entries @@ -1028,6 +1029,7 @@ pub fn fd_readdir( entry_vec } Kind::Root { entries } => { + debug!("Reading root"); let sorted_entries = { let mut entry_vec: Vec<(String, Inode)> = entries.iter().map(|(a, b)| (a.clone(), *b)).collect(); @@ -1202,7 +1204,7 @@ pub fn fd_sync(env: &WasiEnv, fd: __wasi_fd_t) -> __wasi_errno_t { match &mut state.fs.inodes[inode].kind { Kind::File { handle, .. } => { if let Some(h) = handle { - wasi_try!(h.sync_to_disk().map_err(WasiFsError::into_wasi_err)); + wasi_try!(h.sync_to_disk().map_err(fs_error_into_wasi_err)); } else { return __WASI_EINVAL; } @@ -1279,7 +1281,7 @@ pub fn fd_write( __WASI_STDIN_FILENO => return __WASI_EINVAL, __WASI_STDOUT_FILENO => { if let Some(ref mut stdout) = - wasi_try!(state.fs.stdout_mut().map_err(WasiFsError::into_wasi_err)) + wasi_try!(state.fs.stdout_mut().map_err(fs_error_into_wasi_err)) { wasi_try!(write_bytes(stdout, memory, &iovs_arr_cell)) } else { @@ -1288,7 +1290,7 @@ pub fn fd_write( } __WASI_STDERR_FILENO => { if let Some(ref mut stderr) = - wasi_try!(state.fs.stderr_mut().map_err(WasiFsError::into_wasi_err)) + wasi_try!(state.fs.stderr_mut().map_err(fs_error_into_wasi_err)) { wasi_try!(write_bytes(stderr, memory, &iovs_arr_cell)) } else { @@ -1371,7 +1373,7 @@ pub fn path_create_directory( let path_string = unsafe { get_input_str!(memory, path, path_len) }; debug!("=> fd: {}, path: {}", fd, &path_string); - let path = std::path::PathBuf::from(path_string); + let path = std::path::PathBuf::from(&path_string); let path_vec = wasi_try!(path .components() .map(|comp| { @@ -1415,7 +1417,7 @@ pub fn path_create_directory( if adjusted_path.exists() && !adjusted_path.is_dir() { return __WASI_ENOTDIR; } else if !adjusted_path.exists() { - wasi_try!(std::fs::create_dir(&adjusted_path).ok(), __WASI_EIO); + wasi_try!(state.fs_create_dir(&adjusted_path)); } let kind = Kind::Dir { parent: Some(cur_dir_inode), @@ -1477,7 +1479,7 @@ pub fn path_filestat_get( let file_inode = wasi_try!(state.fs.get_inode_at_path( fd, - path_string, + &path_string, flags & __WASI_LOOKUP_SYMLINK_FOLLOW != 0, )); let stat = if state.fs.inodes[file_inode].is_preopened { @@ -1541,7 +1543,7 @@ pub fn path_filestat_set_times( let file_inode = wasi_try!(state.fs.get_inode_at_path( fd, - path_string, + &path_string, flags & __WASI_LOOKUP_SYMLINK_FOLLOW != 0, )); let stat = wasi_try!(state @@ -1558,12 +1560,6 @@ pub fn path_filestat_set_times( wasi_try!(get_current_time_in_nanos()) }; inode.stat.st_atim = time_to_set; - // TODO: set it for more than just files - if let Kind::File { handle, .. } = &mut inode.kind { - if let Some(handle) = handle { - handle.set_last_accessed(time_to_set); - } - } } if fst_flags & __WASI_FILESTAT_SET_MTIM != 0 || fst_flags & __WASI_FILESTAT_SET_MTIM_NOW != 0 { let time_to_set = if fst_flags & __WASI_FILESTAT_SET_MTIM != 0 { @@ -1572,12 +1568,6 @@ pub fn path_filestat_set_times( wasi_try!(get_current_time_in_nanos()) }; inode.stat.st_mtim = time_to_set; - // TODO: set it for more than just files - if let Kind::File { handle, .. } = &mut inode.kind { - if let Some(handle) = handle { - handle.set_last_modified(time_to_set); - } - } } __WASI_ESUCCESS @@ -1621,7 +1611,7 @@ pub fn path_link( let target_fd = wasi_try!(state.fs.get_fd(new_fd)); debug!( "=> source_fd: {}, source_path: {}, target_fd: {}, target_path: {}", - old_fd, old_path_str, new_fd, new_path_str + old_fd, &old_path_str, new_fd, new_path_str ); if !(has_rights(source_fd.rights, __WASI_RIGHT_PATH_LINK_SOURCE) @@ -1632,10 +1622,10 @@ pub fn path_link( let source_inode = wasi_try!(state.fs.get_inode_at_path( old_fd, - old_path_str, + &old_path_str, old_flags & __WASI_LOOKUP_SYMLINK_FOLLOW != 0, )); - let target_path_arg = std::path::PathBuf::from(new_path_str); + let target_path_arg = std::path::PathBuf::from(&new_path_str); let (target_parent_inode, new_entry_name) = wasi_try!(state .fs @@ -1724,10 +1714,10 @@ pub fn path_open( debug!("=> fd: {}, path: {}", dirfd, &path_string); - let path_arg = std::path::PathBuf::from(path_string); + let path_arg = std::path::PathBuf::from(&path_string); let maybe_inode = state.fs.get_inode_at_path( dirfd, - path_string, + &path_string, dirflags & __WASI_LOOKUP_SYMLINK_FOLLOW != 0, ); @@ -1736,6 +1726,7 @@ pub fn path_open( // COMMENTED OUT: WASI isn't giving appropriate rights here when opening // TODO: look into this; file a bug report if this is a bug let adjusted_rights = /*fs_rights_base &*/ working_dir_rights_inheriting; + let mut open_options = state.fs_new_open_options(); let inode = if let Ok(inode) = maybe_inode { // Happy path, we found the file we're trying to open match &mut state.fs.inodes[inode].kind { @@ -1756,7 +1747,6 @@ pub fn path_open( if o_flags & __WASI_O_EXCL != 0 && path.exists() { return __WASI_EEXIST; } - let mut open_options = std::fs::OpenOptions::new(); let write_permission = adjusted_rights & __WASI_RIGHT_FD_WRITE != 0; // append, truncate, and create all require the permission to write let (append_permission, truncate_permission, create_permission) = @@ -1786,13 +1776,9 @@ pub fn path_open( if o_flags & __WASI_O_TRUNC != 0 { open_flags |= Fd::TRUNCATE; } - *handle = Some(Box::new(HostFile::new( - wasi_try!(open_options.open(&path).map_err(|_| __WASI_EIO)), - path.to_path_buf(), - true, - adjusted_rights & __WASI_RIGHT_FD_WRITE != 0, - false, - ))); + *handle = Some(wasi_try!(open_options + .open(&path) + .map_err(fs_error_into_wasi_err))); } Kind::Buffer { .. } => unimplemented!("wasi::path_open for Buffer type files"), Kind::Dir { .. } | Kind::Root { .. } => { @@ -1839,7 +1825,6 @@ pub fn path_open( // once we got the data we need from the parent, we lookup the host file // todo: extra check that opening with write access is okay let handle = { - let mut open_options = std::fs::OpenOptions::new(); let open_options = open_options .read(true) .append(fs_flags & __WASI_FDFLAG_APPEND != 0) @@ -1849,16 +1834,12 @@ pub fn path_open( .create_new(true); open_flags |= Fd::READ | Fd::WRITE | Fd::CREATE | Fd::TRUNCATE; - Some(Box::new(HostFile::new( - wasi_try!(open_options.open(&new_file_host_path).map_err(|e| { + Some(wasi_try!(open_options.open(&new_file_host_path).map_err( + |e| { debug!("Error opening file {}", e); - __WASI_EIO - })), - new_file_host_path.clone(), - true, - true, - true, - )) as Box) + fs_error_into_wasi_err(e) + } + ))) }; let new_inode = { @@ -1937,7 +1918,7 @@ pub fn path_readlink( return __WASI_EACCES; } let path_str = unsafe { get_input_str!(memory, path, path_len) }; - let inode = wasi_try!(state.fs.get_inode_at_path(dir_fd, path_str, false)); + let inode = wasi_try!(state.fs.get_inode_at_path(dir_fd, &path_str, false)); if let Kind::Symlink { relative_path, .. } = &state.fs.inodes[inode].kind { let rel_path_str = relative_path.to_string_lossy(); @@ -1978,17 +1959,15 @@ pub fn path_remove_directory( let base_dir = wasi_try!(state.fs.fd_map.get(&fd), __WASI_EBADF); let path_str = unsafe { get_input_str!(memory, path, path_len) }; - let inode = wasi_try!(state.fs.get_inode_at_path(fd, path_str, false)); + let inode = wasi_try!(state.fs.get_inode_at_path(fd, &path_str, false)); let (parent_inode, childs_name) = wasi_try!(state .fs - .get_parent_inode_at_path(fd, std::path::Path::new(path_str), false)); + .get_parent_inode_at_path(fd, std::path::Path::new(&path_str), false)); let host_path_to_remove = match &state.fs.inodes[inode].kind { Kind::Dir { entries, path, .. } => { - if !entries.is_empty() - || wasi_try!(std::fs::read_dir(path).ok(), __WASI_EIO).count() != 0 - { + if !entries.is_empty() || wasi_try!(state.fs_read_dir(path)).count() != 0 { return __WASI_ENOTEMPTY; } path.clone() @@ -2011,7 +1990,7 @@ pub fn path_remove_directory( ), } - if std::fs::remove_dir(path_str).is_err() { + if state.fs_remove_dir(path_str).is_err() { // reinsert to prevent FS from being in bad state if let Kind::Dir { ref mut entries, .. @@ -2056,10 +2035,10 @@ pub fn path_rename( ); let (memory, mut state) = env.get_memory_and_wasi_state(0); let source_str = unsafe { get_input_str!(memory, old_path, old_path_len) }; - let source_path = std::path::Path::new(source_str); + let source_path = std::path::Path::new(&source_str); let target_str = unsafe { get_input_str!(memory, new_path, new_path_len) }; - let target_path = std::path::Path::new(target_str); - debug!("=> rename from {} to {}", source_str, target_str); + let target_path = std::path::Path::new(&target_str); + debug!("=> rename from {} to {}", &source_str, &target_str); { let source_fd = wasi_try!(state.fs.get_fd(old_fd)); @@ -2101,17 +2080,23 @@ pub fn path_rename( match &mut state.fs.inodes[source_entry].kind { Kind::File { - handle, - ref mut path, - .. + handle, ref path, .. } => { + // TODO: investigate why handle is not always there, it probably should be. + // My best guess is the fact that a handle means currently open and a path + // just means reference to host file on disk. But ideally those concepts + // could just be unified even if there's a `Box` which just + // implements the logic of "I'm not actually a file, I'll try to be as needed". let result = if let Some(h) = handle { - h.rename_file(&host_adjusted_target_path) - .map_err(|e| e.into_wasi_err()) + state.fs_rename(&source_path, &host_adjusted_target_path) } else { - let out = - std::fs::rename(&path, &host_adjusted_target_path).map_err(|_| __WASI_EIO); - *path = host_adjusted_target_path; + let path_clone = path.clone(); + let out = state.fs_rename(&path_clone, &host_adjusted_target_path); + if let Kind::File { ref mut path, .. } = &mut state.fs.inodes[source_entry].kind { + *path = host_adjusted_target_path; + } else { + unreachable!() + } out }; // if the above operation failed we have to revert the previous change and then fail @@ -2170,11 +2155,11 @@ pub fn path_symlink( } // get the depth of the parent + 1 (UNDER INVESTIGATION HMMMMMMMM THINK FISH ^ THINK FISH) - let old_path_path = std::path::Path::new(old_path_str); + let old_path_path = std::path::Path::new(&old_path_str); let (source_inode, _) = wasi_try!(state.fs.get_parent_inode_at_path(fd, old_path_path, true)); let depth = wasi_try!(state.fs.path_depth_from_fd(fd, source_inode)) - 1; - let new_path_path = std::path::Path::new(new_path_str); + let new_path_path = std::path::Path::new(&new_path_str); let (target_parent_inode, entry_name) = wasi_try!(state.fs.get_parent_inode_at_path(fd, new_path_path, true)); @@ -2191,7 +2176,7 @@ pub fn path_symlink( } } - let mut source_path = std::path::Path::new(old_path_str); + let mut source_path = std::path::Path::new(&old_path_str); let mut relative_path = std::path::PathBuf::new(); for _ in 0..depth { relative_path.push(".."); @@ -2247,11 +2232,11 @@ pub fn path_unlink_file( let path_str = unsafe { get_input_str!(memory, path, path_len) }; debug!("Requested file: {}", path_str); - let inode = wasi_try!(state.fs.get_inode_at_path(fd, path_str, false)); + let inode = wasi_try!(state.fs.get_inode_at_path(fd, &path_str, false)); let (parent_inode, childs_name) = wasi_try!(state .fs - .get_parent_inode_at_path(fd, std::path::Path::new(path_str), false)); + .get_parent_inode_at_path(fd, std::path::Path::new(&path_str), false)); let removed_inode = match &mut state.fs.inodes[parent_inode].kind { Kind::Dir { @@ -2274,12 +2259,13 @@ pub fn path_unlink_file( match &mut state.fs.inodes[removed_inode].kind { Kind::File { handle, path, .. } => { if let Some(h) = handle { - wasi_try!(h.unlink().map_err(WasiFsError::into_wasi_err)); + wasi_try!(h.unlink().map_err(fs_error_into_wasi_err)); } else { // File is closed // problem with the abstraction, we can't call unlink because there's no handle - // TODO: replace this code - wasi_try!(std::fs::remove_file(path).map_err(|_| __WASI_EIO)); + // drop mutable borrow on `path` + let path = path.clone(); + wasi_try!(state.fs_remove_file(path)); } } Kind::Dir { .. } | Kind::Root { .. } => return __WASI_EISDIR, @@ -2393,19 +2379,19 @@ pub fn poll_oneoff( }; if let Some(fd) = fd { - let wasi_file_ref: &dyn WasiFile = match fd { + let wasi_file_ref: &dyn VirtualFile = match fd { __WASI_STDERR_FILENO => wasi_try!( - wasi_try!(state.fs.stderr().map_err(WasiFsError::into_wasi_err)).as_ref(), + wasi_try!(state.fs.stderr().map_err(fs_error_into_wasi_err)).as_ref(), __WASI_EBADF ) .as_ref(), __WASI_STDIN_FILENO => wasi_try!( - wasi_try!(state.fs.stdin().map_err(WasiFsError::into_wasi_err)).as_ref(), + wasi_try!(state.fs.stdin().map_err(fs_error_into_wasi_err)).as_ref(), __WASI_EBADF ) .as_ref(), __WASI_STDOUT_FILENO => wasi_try!( - wasi_try!(state.fs.stdout().map_err(WasiFsError::into_wasi_err)).as_ref(), + wasi_try!(state.fs.stdout().map_err(fs_error_into_wasi_err)).as_ref(), __WASI_EBADF ) .as_ref(), @@ -2450,7 +2436,7 @@ pub fn poll_oneoff( in_events.as_slice(), seen_events.as_mut_slice() ) - .map_err(|e| e.into_wasi_err())); + .map_err(fs_error_into_wasi_err)); for (i, seen_event) in seen_events.into_iter().enumerate() { let mut flags = 0; @@ -2464,12 +2450,12 @@ pub fn poll_oneoff( PollEvent::PollInvalid => error = __WASI_EINVAL, PollEvent::PollIn => { bytes_available = - wasi_try!(fds[i].bytes_available().map_err(|e| e.into_wasi_err())); + wasi_try!(fds[i].bytes_available().map_err(fs_error_into_wasi_err)); error = __WASI_ESUCCESS; } PollEvent::PollOut => { bytes_available = - wasi_try!(fds[i].bytes_available().map_err(|e| e.into_wasi_err())); + wasi_try!(fds[i].bytes_available().map_err(fs_error_into_wasi_err)); error = __WASI_ESUCCESS; } } @@ -2539,8 +2525,8 @@ pub fn random_get(env: &WasiEnv, buf: u32, buf_len: u32) -> __wasi_errno_t { Ok(()) => { unsafe { memory - .view::() - .subarray(buf as usize..=(buf as usize + buf_len as usize)) + .uint8view() + .subarray(buf as u32, (buf as u32 + buf_len as u32)) .copy_from(&u8_buffer); } __WASI_ESUCCESS diff --git a/lib/wasi/src/syscalls/wasm32.rs b/lib/wasi/src/syscalls/wasm32.rs new file mode 100644 index 00000000000..4c512138a40 --- /dev/null +++ b/lib/wasi/src/syscalls/wasm32.rs @@ -0,0 +1,25 @@ +use crate::syscalls::types::*; +use std::mem; +use wasmer::WasmCell; + +pub fn platform_clock_res_get( + clock_id: __wasi_clockid_t, + resolution: WasmCell<__wasi_timestamp_t>, +) -> __wasi_errno_t { + let t_out = 1 * 1_000_000_000; + resolution.set(t_out as __wasi_timestamp_t); + + // TODO: map output of clock_getres to __wasi_errno_t + __WASI_ESUCCESS +} + +pub fn platform_clock_time_get( + clock_id: __wasi_clockid_t, + precision: __wasi_timestamp_t, + time: WasmCell<__wasi_timestamp_t>, +) -> __wasi_errno_t { + let t_out = 1 * 1_000_000_000; + time.set(t_out as __wasi_timestamp_t); + + __WASI_ESUCCESS +} diff --git a/lib/wasi/tests/envvar.rs b/lib/wasi/tests/envvar.rs new file mode 100644 index 00000000000..a76f23115b9 --- /dev/null +++ b/lib/wasi/tests/envvar.rs @@ -0,0 +1,28 @@ +// WASI: +// env: DOG=1 +// env: CAT=2 + +use std::env; + +fn get_env_var(var_name: &str) -> Result { + env::var(var_name) +} + +fn main() { + let mut env_vars = env::vars() + .map(|(key, value)| format!("{}={}", key, value)) + .collect::>(); + + env_vars.sort(); + + println!("Env vars:"); + for e in env_vars { + println!("{}", e); + } + + env::set_var("WASI_ENVVAR_TEST", "HELLO"); + + println!("DOG {:?}", get_env_var("DOG")); + println!("DOG_TYPE {:?}", get_env_var("DOG_TYPE")); + println!("SET VAR {:?}", env::var("WASI_ENVVAR_TEST")); +} diff --git a/lib/wasi/tests/envvar.wasm b/lib/wasi/tests/envvar.wasm new file mode 100755 index 00000000000..31a87aca698 Binary files /dev/null and b/lib/wasi/tests/envvar.wasm differ diff --git a/lib/wasi/tests/envvar.wat b/lib/wasi/tests/envvar.wat new file mode 100644 index 00000000000..08b1cab3299 --- /dev/null +++ b/lib/wasi/tests/envvar.wat @@ -0,0 +1,25993 @@ +(module + (type $t0 (func (param i32 i32) (result i32))) + (type $t1 (func (param i32 i32 i32) (result i32))) + (type $t2 (func (param i32))) + (type $t3 (func (param i32 i32))) + (type $t4 (func (param i32 i32 i32))) + (type $t5 (func (param i32) (result i32))) + (type $t6 (func (param i32 i32 i32 i32))) + (type $t7 (func)) + (type $t8 (func (param i32) (result i64))) + (type $t9 (func (param i32 i32 i32 i32) (result i32))) + (type $t10 (func (result i32))) + (type $t11 (func (param i32 i32 i32 i32 i32))) + (type $t12 (func (param i32 i32 i32 i32 i32 i32) (result i32))) + (type $t13 (func (param i32 i32 i32 i32 i32 i32 i32) (result i32))) + (type $t14 (func (param i64 i32 i32) (result i32))) + (import "wasi_snapshot_preview1" "proc_exit" (func $wasi_snapshot_preview1.proc_exit (type $t2))) + (import "wasi_snapshot_preview1" "fd_write" (func $wasi_snapshot_preview1.fd_write (type $t9))) + (import "wasi_snapshot_preview1" "fd_prestat_get" (func $wasi_snapshot_preview1.fd_prestat_get (type $t0))) + (import "wasi_snapshot_preview1" "fd_prestat_dir_name" (func $wasi_snapshot_preview1.fd_prestat_dir_name (type $t1))) + (import "wasi_snapshot_preview1" "environ_sizes_get" (func $wasi_snapshot_preview1.environ_sizes_get (type $t0))) + (import "wasi_snapshot_preview1" "environ_get" (func $wasi_snapshot_preview1.environ_get (type $t0))) + (func $_start (type $t7) + (local $l0 i32) + call $f154 + call $f152 + call $f33 + local.tee $l0 + if $I0 + local.get $l0 + call $wasi_snapshot_preview1.proc_exit + unreachable + end) + (func $f7 (type $t2) (param $p0 i32) + (local $l1 i32) (local $l2 i32) + global.get $g0 + i32.const 96 + i32.sub + local.tee $l1 + global.set $g0 + loop $L0 + block $B1 + local.get $l2 + i32.const -1 + i32.eq + br_if $B1 + local.get $l1 + local.get $l2 + local.get $p0 + call $f9 + local.get $l1 + i32.load + local.get $l1 + i32.load offset=4 + call $f10 + local.get $l2 + i32.const -1 + i32.add + local.set $l2 + br $L0 + end + end + local.get $l1 + i32.const 96 + i32.add + global.set $g0) + (func $f8 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + local.get $p0 + i32.load + local.get $p0 + i32.load offset=8 + local.get $p1 + i32.load + local.get $p1 + i32.load offset=8 + call $f27 + i32.const 255 + i32.and + i32.const 255 + i32.eq) + (func $f9 (type $t4) (param $p0 i32) (param $p1 i32) (param $p2 i32) + i32.const 2 + local.get $p1 + i32.lt_u + if $I0 + local.get $p1 + i32.const 2 + call $f174 + unreachable + end + local.get $p0 + i32.const 2 + local.get $p1 + i32.sub + i32.store offset=4 + local.get $p0 + local.get $p2 + local.get $p1 + i32.const 12 + i32.mul + i32.add + i32.store) + (func $f10 (type $t3) (param $p0 i32) (param $p1 i32) + (local $l2 i32) (local $l3 i32) + global.get $g0 + i32.const 16 + i32.sub + local.tee $l2 + global.set $g0 + block $B0 + local.get $p1 + i32.const 2 + i32.lt_u + br_if $B0 + local.get $p0 + i32.const 12 + i32.add + local.get $p0 + call $f8 + i32.eqz + br_if $B0 + local.get $l2 + i32.const 8 + i32.add + local.get $p0 + i32.const 8 + i32.add + i32.load + i32.store + local.get $l2 + local.get $p0 + i64.load align=4 + i64.store + local.get $p1 + i32.const -2 + i32.add + local.set $p1 + loop $L1 + block $B2 + local.get $p0 + i32.const 8 + i32.add + local.get $p0 + i32.const 20 + i32.add + i32.load + i32.store + local.get $p0 + local.get $p0 + i32.const 12 + i32.add + local.tee $l3 + i64.load align=4 + i64.store align=4 + local.get $p1 + i32.eqz + br_if $B2 + local.get $p0 + i32.const 24 + i32.add + local.get $l2 + call $f8 + i32.eqz + br_if $B2 + local.get $p1 + i32.const -1 + i32.add + local.set $p1 + local.get $l3 + local.set $p0 + br $L1 + end + end + local.get $p0 + i32.const 12 + i32.add + local.get $l2 + i64.load + i64.store align=4 + local.get $p0 + i32.const 20 + i32.add + local.get $l2 + i32.const 8 + i32.add + i32.load + i32.store + end + local.get $l2 + i32.const 16 + i32.add + global.set $g0) + (func $f11 (type $t4) (param $p0 i32) (param $p1 i32) (param $p2 i32) + (local $l3 i32) + global.get $g0 + i32.const 32 + i32.sub + local.tee $l3 + global.set $g0 + local.get $l3 + i32.const 8 + i32.add + local.get $p2 + call $f13 + local.get $l3 + i32.const 0 + i32.store offset=24 + local.get $l3 + local.get $l3 + i64.load offset=8 + i64.store offset=16 + local.get $l3 + i32.const 16 + i32.add + local.get $p1 + local.get $p2 + call $f17 + local.get $p0 + i32.const 8 + i32.add + local.get $l3 + i32.load offset=24 + i32.store + local.get $p0 + local.get $l3 + i64.load offset=16 + i64.store align=4 + local.get $l3 + i32.const 32 + i32.add + global.set $g0) + (func $f12 (type $t7) + call $f169 + unreachable) + (func $f13 (type $t3) (param $p0 i32) (param $p1 i32) + (local $l2 i32) + block $B0 + local.get $p1 + i32.const -1 + i32.gt_s + if $I1 + block $B2 + local.get $p1 + i32.eqz + if $I3 + i32.const 1 + local.set $l2 + br $B2 + end + local.get $p1 + i32.const 1 + call $f36 + local.tee $l2 + i32.eqz + br_if $B0 + end + local.get $p0 + local.get $p1 + i32.store offset=4 + local.get $p0 + local.get $l2 + i32.store + return + end + call $f12 + unreachable + end + local.get $p1 + i32.const 1 + call $f168 + unreachable) + (func $f14 (type $t4) (param $p0 i32) (param $p1 i32) (param $p2 i32) + (local $l3 i32) + block $B0 + block $B1 + local.get $p0 + i32.load offset=4 + local.tee $l3 + local.get $p1 + i32.sub + local.get $p2 + i32.lt_u + if $I2 + local.get $p1 + local.get $p2 + i32.add + local.tee $p2 + local.get $p1 + i32.lt_u + br_if $B0 + local.get $l3 + i32.const 1 + i32.shl + local.tee $p1 + local.get $p2 + local.get $p1 + local.get $p2 + i32.gt_u + select + local.tee $p1 + i32.const 0 + i32.lt_s + br_if $B0 + block $B3 (result i32) + local.get $l3 + i32.eqz + if $I4 + local.get $p1 + i32.const 1 + call $f36 + br $B3 + end + local.get $p0 + i32.load + local.get $l3 + i32.const 1 + local.get $p1 + call $f37 + end + local.tee $p2 + i32.eqz + br_if $B1 + local.get $p0 + local.get $p1 + i32.store offset=4 + local.get $p0 + local.get $p2 + i32.store + end + return + end + local.get $p1 + i32.const 1 + call $f168 + unreachable + end + call $f169 + unreachable) + (func $f15 (type $t2) (param $p0 i32) + local.get $p0 + i32.load offset=4 + if $I0 + local.get $p0 + i32.load + call $f145 + end) + (func $f16 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + local.get $p0 + i32.load + local.tee $p0 + i32.load + local.get $p0 + i32.load offset=8 + local.get $p1 + call $f224) + (func $f17 (type $t4) (param $p0 i32) (param $p1 i32) (param $p2 i32) + (local $l3 i32) + local.get $p0 + local.get $p0 + i32.load offset=8 + local.get $p2 + call $f14 + local.get $p0 + local.get $p0 + i32.load offset=8 + local.tee $l3 + local.get $p2 + i32.add + i32.store offset=8 + local.get $l3 + local.get $p0 + i32.load + i32.add + local.get $p2 + local.get $p1 + local.get $p2 + call $f26) + (func $f18 (type $t2) (param $p0 i32) + (local $l1 i32) (local $l2 i32) (local $l3 i32) (local $l4 i64) + global.get $g0 + i32.const 32 + i32.sub + local.tee $l1 + global.set $g0 + loop $L0 + block $B1 + block $B2 + local.get $p0 + i32.load offset=8 + local.tee $l2 + local.get $p0 + i32.load offset=12 + i32.eq + if $I3 + local.get $l1 + i32.const 0 + i32.store offset=16 + br $B2 + end + local.get $p0 + local.get $l2 + i32.const 12 + i32.add + i32.store offset=8 + local.get $l1 + i32.const 24 + i32.add + local.tee $l3 + local.get $l2 + i32.const 8 + i32.add + i32.load + i32.store + local.get $l1 + local.get $l2 + i64.load align=4 + local.tee $l4 + i64.store offset=16 + local.get $l4 + i32.wrap_i64 + br_if $B1 + end + local.get $l1 + i32.const 16 + i32.add + local.tee $l2 + i32.load + if $I4 + local.get $l2 + call $f15 + end + local.get $l1 + local.get $p0 + i64.load align=4 + i64.store offset=16 + local.get $l1 + i32.const 16 + i32.add + local.tee $p0 + i32.load offset=4 + if $I5 + local.get $p0 + i32.load + call $f145 + end + local.get $l1 + i32.const 32 + i32.add + global.set $g0 + return + end + local.get $l1 + i32.const 8 + i32.add + local.get $l3 + i32.load + local.tee $l2 + i32.store + local.get $l1 + local.get $l1 + i64.load offset=16 + local.tee $l4 + i64.store + local.get $l3 + local.get $l2 + i32.store + local.get $l1 + local.get $l4 + i64.store offset=16 + local.get $l1 + i32.const 16 + i32.add + call $f15 + br $L0 + end + unreachable) + (func $f19 (type $t2) (param $p0 i32) + (local $l1 i32) + local.get $p0 + i32.const 4 + i32.add + local.set $l1 + block $B0 + local.get $p0 + i32.load + if $I1 + local.get $l1 + i32.load + i32.eqz + br_if $B0 + end + local.get $l1 + call $f15 + end) + (func $f20 (type $t1) (param $p0 i32) (param $p1 i32) (param $p2 i32) (result i32) + local.get $p0 + local.get $p1 + local.get $p2 + call $f28) + (func $f21 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + local.get $p0 + i32.load + local.get $p0 + i32.load offset=8 + local.get $p1 + call $f225) + (func $f22 (type $t4) (param $p0 i32) (param $p1 i32) (param $p2 i32) + (local $l3 i32) + global.get $g0 + i32.const 16 + i32.sub + local.tee $l3 + global.set $g0 + block $B0 + local.get $p1 + local.get $p2 + i32.const 1048756 + call $f20 + if $I1 + local.get $l3 + i32.const 1048759 + i32.const 1 + call $f11 + local.get $p0 + i32.const 0 + i32.store + local.get $p0 + i32.const 12 + i32.add + local.get $l3 + i32.const 8 + i32.add + i32.load + i32.store + local.get $p0 + local.get $l3 + i64.load + i64.store offset=4 align=4 + br $B0 + end + local.get $p1 + local.get $p2 + i32.const 1048760 + call $f20 + if $I2 + local.get $l3 + i32.const 1048763 + i32.const 1 + call $f11 + local.get $p0 + i32.const 0 + i32.store + local.get $p0 + i32.const 12 + i32.add + local.get $l3 + i32.const 8 + i32.add + i32.load + i32.store + local.get $p0 + local.get $l3 + i64.load + i64.store offset=4 align=4 + br $B0 + end + local.get $p0 + i64.const 1 + i64.store align=4 + end + local.get $l3 + i32.const 16 + i32.add + global.set $g0) + (func $f23 (type $t7) + (local $l0 i32) (local $l1 i32) (local $l2 i32) (local $l3 i32) (local $l4 i64) + global.get $g0 + i32.const 80 + i32.sub + local.tee $l0 + global.set $g0 + block $B0 + i32.const 24 + i32.const 4 + call $f36 + local.tee $l1 + if $I1 + local.get $l0 + i32.const -64 + i32.sub + i32.const 1048764 + i32.const 5 + call $f11 + local.get $l0 + i32.const 40 + i32.add + i32.const 1048769 + i32.const 5 + call $f11 + local.get $l1 + i32.const 8 + i32.add + local.get $l0 + i32.const 72 + i32.add + i32.load + i32.store + local.get $l1 + local.get $l0 + i64.load offset=64 + i64.store align=4 + local.get $l1 + local.get $l0 + i64.load offset=40 + i64.store offset=12 align=4 + local.get $l1 + i32.const 20 + i32.add + local.get $l0 + i32.const 48 + i32.add + local.tee $l2 + i32.load + i32.store + local.get $l1 + call $f7 + local.get $l0 + i64.const 4 + i64.store offset=56 + local.get $l0 + i64.const 1 + i64.store offset=44 align=4 + local.get $l0 + i32.const 1048784 + i32.store offset=40 + local.get $l0 + i32.const 40 + i32.add + call $f115 + local.get $l0 + local.get $l1 + i32.const 24 + i32.add + local.tee $l3 + i32.store offset=76 + local.get $l0 + local.get $l1 + i32.store offset=72 + local.get $l0 + i32.const 2 + i32.store offset=68 + local.get $l0 + local.get $l1 + i32.store offset=64 + loop $L2 + local.get $l1 + local.get $l3 + i32.eq + if $I3 + local.get $l0 + i32.const 0 + i32.store offset=40 + br $B0 + end + local.get $l0 + local.get $l1 + i32.const 12 + i32.add + i32.store offset=72 + local.get $l2 + local.get $l1 + i32.const 8 + i32.add + i32.load + i32.store + local.get $l0 + local.get $l1 + i64.load align=4 + local.tee $l4 + i64.store offset=40 + local.get $l4 + i32.wrap_i64 + i32.eqz + br_if $B0 + local.get $l0 + i32.const 8 + i32.add + local.get $l2 + i32.load + local.tee $l1 + i32.store + local.get $l0 + local.get $l0 + i64.load offset=40 + local.tee $l4 + i64.store + local.get $l0 + i32.const 24 + i32.add + local.get $l1 + i32.store + local.get $l0 + local.get $l4 + i64.store offset=16 + local.get $l0 + i32.const 1 + i32.store offset=60 + local.get $l0 + i64.const 2 + i64.store offset=44 align=4 + local.get $l0 + i32.const 1048796 + i32.store offset=40 + local.get $l0 + i32.const 1 + i32.store offset=36 + local.get $l0 + local.get $l0 + i32.const 32 + i32.add + i32.store offset=56 + local.get $l0 + local.get $l0 + i32.const 16 + i32.add + i32.store offset=32 + local.get $l0 + i32.const 40 + i32.add + call $f115 + local.get $l0 + i32.const 16 + i32.add + call $f15 + local.get $l0 + i32.load offset=76 + local.set $l3 + local.get $l0 + i32.load offset=72 + local.set $l1 + br $L2 + end + unreachable + end + i32.const 24 + i32.const 4 + call $f168 + unreachable + end + local.get $l0 + i32.const -64 + i32.sub + call $f18 + call $f94 + local.get $l0 + i32.const -64 + i32.sub + i32.const 1048756 + i32.const 3 + call $f22 + local.get $l0 + i32.const 60 + i32.add + local.tee $l1 + i32.const 1 + i32.store + local.get $l0 + i32.const 2 + i32.store offset=20 + local.get $l0 + i64.const 2 + i64.store offset=44 align=4 + local.get $l0 + i32.const 1048840 + i32.store offset=40 + local.get $l0 + local.get $l0 + i32.const -64 + i32.sub + i32.store offset=16 + local.get $l0 + local.get $l0 + i32.const 16 + i32.add + i32.store offset=56 + local.get $l0 + i32.const 40 + i32.add + call $f115 + local.get $l0 + i32.const -64 + i32.sub + call $f19 + local.get $l0 + i32.const -64 + i32.sub + i32.const 1048884 + i32.const 8 + call $f22 + local.get $l1 + i32.const 1 + i32.store + local.get $l0 + i32.const 2 + i32.store offset=20 + local.get $l0 + i64.const 2 + i64.store offset=44 align=4 + local.get $l0 + i32.const 1048868 + i32.store offset=40 + local.get $l0 + local.get $l0 + i32.const -64 + i32.sub + i32.store offset=16 + local.get $l0 + local.get $l0 + i32.const 16 + i32.add + i32.store offset=56 + local.get $l0 + i32.const 40 + i32.add + call $f115 + local.get $l0 + i32.const -64 + i32.sub + call $f19 + local.get $l0 + i32.const -64 + i32.sub + call $f90 + local.get $l1 + i32.const 1 + i32.store + local.get $l0 + i32.const 2 + i32.store offset=20 + local.get $l0 + i64.const 2 + i64.store offset=44 align=4 + local.get $l0 + i32.const 1048900 + i32.store offset=40 + local.get $l0 + local.get $l0 + i32.const -64 + i32.sub + i32.store offset=16 + local.get $l0 + local.get $l0 + i32.const 16 + i32.add + i32.store offset=56 + local.get $l0 + i32.const 40 + i32.add + call $f115 + local.get $l0 + i32.const -64 + i32.sub + call $f19 + local.get $l0 + i32.const 80 + i32.add + global.set $g0) + (func $__original_main (type $t10) (result i32) + call $f33) + (func $main (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + call $f33) + (func $f26 (type $t6) (param $p0 i32) (param $p1 i32) (param $p2 i32) (param $p3 i32) + (local $l4 i32) + global.get $g0 + i32.const 96 + i32.sub + local.tee $l4 + global.set $g0 + local.get $l4 + local.get $p1 + i32.store offset=8 + local.get $l4 + local.get $p3 + i32.store offset=12 + local.get $p1 + local.get $p3 + i32.eq + if $I0 + local.get $p0 + local.get $p2 + local.get $p1 + call $f162 + drop + local.get $l4 + i32.const 96 + i32.add + global.set $g0 + return + end + local.get $l4 + i32.const 60 + i32.add + i32.const 4 + i32.store + local.get $l4 + i32.const 52 + i32.add + i32.const 5 + i32.store + local.get $l4 + i32.const 36 + i32.add + i32.const 3 + i32.store + local.get $l4 + i64.const 3 + i64.store offset=20 align=4 + local.get $l4 + i32.const 1048976 + i32.store offset=16 + local.get $l4 + i32.const 5 + i32.store offset=44 + local.get $l4 + local.get $l4 + i32.const 8 + i32.add + i32.store offset=64 + local.get $l4 + local.get $l4 + i32.const 12 + i32.add + i32.store offset=68 + local.get $l4 + i64.const 4 + i64.store offset=88 + local.get $l4 + i64.const 1 + i64.store offset=76 align=4 + local.get $l4 + i32.const 1049052 + i32.store offset=72 + local.get $l4 + local.get $l4 + i32.const 40 + i32.add + i32.store offset=32 + local.get $l4 + local.get $l4 + i32.const 72 + i32.add + i32.store offset=56 + local.get $l4 + local.get $l4 + i32.const 68 + i32.add + i32.store offset=48 + local.get $l4 + local.get $l4 + i32.const -64 + i32.sub + i32.store offset=40 + local.get $l4 + i32.const 16 + i32.add + i32.const 1049136 + call $f177 + unreachable) + (func $f27 (type $t9) (param $p0 i32) (param $p1 i32) (param $p2 i32) (param $p3 i32) (result i32) + local.get $p0 + local.get $p2 + local.get $p3 + local.get $p1 + local.get $p1 + local.get $p3 + i32.gt_u + select + call $f167 + local.tee $p0 + if $I0 + i32.const -1 + i32.const 1 + local.get $p0 + i32.const 0 + i32.lt_s + select + return + end + i32.const -1 + local.get $p1 + local.get $p3 + i32.ne + local.get $p1 + local.get $p3 + i32.lt_u + select) + (func $f28 (type $t1) (param $p0 i32) (param $p1 i32) (param $p2 i32) (result i32) + local.get $p1 + i32.const 3 + i32.eq + if $I0 (result i32) + local.get $p0 + local.get $p2 + i32.eq + if $I1 + i32.const 1 + return + end + local.get $p0 + local.get $p2 + local.get $p1 + call $f167 + i32.eqz + else + i32.const 0 + end) + (func $f29 (type $t2) (param $p0 i32) + nop) + (func $f30 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + (local $l2 i32) (local $l3 i32) + global.get $g0 + i32.const 16 + i32.sub + local.tee $l2 + global.set $g0 + local.get $p0 + i32.const 4 + i32.add + local.set $l3 + block $B0 + local.get $p0 + i32.load + i32.const 1 + i32.ne + if $I1 + local.get $l2 + local.get $p1 + i32.const 1049172 + i32.const 2 + call $f222 + local.get $l2 + local.get $l3 + i32.store offset=12 + local.get $l2 + local.get $l2 + i32.const 12 + i32.add + i32.const 1049176 + call $f206 + br $B0 + end + local.get $l2 + local.get $p1 + i32.const 1049152 + i32.const 3 + call $f222 + local.get $l2 + local.get $l3 + i32.store offset=12 + local.get $l2 + local.get $l2 + i32.const 12 + i32.add + i32.const 1049156 + call $f206 + end + local.get $l2 + call $f207 + local.get $l2 + i32.const 16 + i32.add + global.set $g0) + (func $f31 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + local.get $p0 + i32.load + local.set $p0 + local.get $p1 + call $f220 + i32.eqz + if $I0 + local.get $p1 + call $f221 + i32.eqz + if $I1 + local.get $p0 + local.get $p1 + call $f178 + return + end + local.get $p0 + local.get $p1 + call $f230 + return + end + local.get $p0 + local.get $p1 + call $f226) + (func $f32 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + local.get $p0 + i32.load + local.get $p1 + call $f140) + (func $f33 (type $t10) (result i32) + (local $l0 i32) (local $l1 i32) + global.get $g0 + i32.const 16 + i32.sub + local.tee $l0 + global.set $g0 + local.get $l0 + i32.const 3 + i32.store offset=12 + local.get $l0 + i32.const 12 + i32.add + call $f139 + local.get $l0 + i32.const 16 + i32.add + global.set $g0) + (func $f34 (type $t5) (param $p0 i32) (result i32) + (local $l1 i32) + global.get $g0 + i32.const 16 + i32.sub + local.tee $l1 + global.set $g0 + local.get $p0 + i32.load + call_indirect (type $t7) $T0 + local.get $l1 + i32.const 0 + i32.store8 offset=15 + local.get $l1 + i32.const 15 + i32.add + i32.load8_u + local.get $l1 + i32.const 16 + i32.add + global.set $g0) + (func $f35 (type $t5) (param $p0 i32) (result i32) + (local $l1 i32) + global.get $g0 + i32.const 16 + i32.sub + local.tee $l1 + global.set $g0 + local.get $l1 + local.get $p0 + i32.load + i32.store offset=12 + local.get $l1 + i32.const 12 + i32.add + call $f34 + local.get $l1 + i32.const 16 + i32.add + global.set $g0) + (func $f36 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + local.get $p0 + local.get $p1 + call $f129) + (func $f37 (type $t9) (param $p0 i32) (param $p1 i32) (param $p2 i32) (param $p3 i32) (result i32) + local.get $p0 + local.get $p1 + local.get $p2 + local.get $p3 + call $f130) + (func $f38 (type $t8) (param $p0 i32) (result i64) + i64.const 8634666484767235598) + (func $f39 (type $t8) (param $p0 i32) (result i64) + i64.const 9212946136330284990) + (func $f40 (type $t8) (param $p0 i32) (result i64) + i64.const 1229646359891580772) + (func $f41 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + local.get $p0 + i32.load + local.set $p0 + local.get $p1 + call $f220 + i32.eqz + if $I0 + local.get $p1 + call $f221 + i32.eqz + if $I1 + local.get $p0 + i64.load8_u + i32.const 1 + local.get $p1 + call $f214 + return + end + local.get $p0 + local.get $p1 + call $f229 + return + end + local.get $p0 + local.get $p1 + call $f200) + (func $f42 (type $t1) (param $p0 i32) (param $p1 i32) (param $p2 i32) (result i32) + (local $l3 i32) (local $l4 i32) (local $l5 i32) (local $l6 i32) (local $l7 i32) (local $l8 i32) (local $l9 i32) (local $l10 i32) (local $l11 i32) (local $l12 i32) (local $l13 i64) + global.get $g0 + i32.const 80 + i32.sub + local.tee $l3 + global.set $g0 + block $B0 (result i32) + i32.const 1 + local.get $p2 + i32.const 1050388 + i32.const 1 + call $f218 + br_if $B0 + drop + local.get $l3 + i32.const 8 + i32.add + local.get $p0 + local.get $p1 + call $f195 + local.get $l3 + local.get $l3 + i32.load offset=8 + local.get $l3 + i32.load offset=12 + call $f195 + local.get $l3 + local.get $l3 + i64.load + i64.store offset=16 + local.get $l3 + i32.const 40 + i32.add + local.get $l3 + i32.const 16 + i32.add + call $f196 + local.get $l3 + i32.load offset=40 + local.tee $l4 + if $I1 + local.get $l3 + i32.const 48 + i32.add + local.set $l10 + local.get $l3 + i32.const -64 + i32.sub + local.set $l11 + loop $L2 + local.get $l3 + i32.load offset=52 + local.set $l7 + local.get $l3 + i32.load offset=48 + local.set $l8 + local.get $l3 + i32.load offset=44 + local.set $p0 + local.get $l3 + i32.const 4 + i32.store offset=64 + local.get $l3 + i32.const 4 + i32.store offset=48 + local.get $l3 + local.get $l4 + i32.store offset=40 + local.get $l3 + local.get $p0 + local.get $l4 + i32.add + i32.store offset=44 + i32.const 4 + local.set $l4 + loop $L3 + block $B4 + block $B5 + block $B6 + block $B7 (result i64) + block $B8 + block $B9 + block $B10 + block $B11 + block $B12 + block $B13 + block $B14 + local.get $l4 + i32.const 4 + i32.ne + if $I15 + local.get $l10 + call $f184 + local.tee $l4 + i32.const 1114112 + i32.ne + br_if $B14 + end + local.get $l3 + i32.load offset=40 + local.tee $l5 + local.get $l3 + i32.load offset=44 + local.tee $p0 + i32.ne + if $I16 + local.get $l3 + local.get $l5 + i32.const 1 + i32.add + local.tee $p1 + i32.store offset=40 + i32.const 2 + local.set $l4 + block $B17 (result i32) + local.get $l5 + i32.load8_s + local.tee $l6 + i32.const -1 + i32.gt_s + if $I18 + local.get $l6 + i32.const 255 + i32.and + br $B17 + end + block $B19 (result i32) + local.get $p0 + local.get $p1 + i32.eq + if $I20 + local.get $p0 + local.set $p1 + i32.const 0 + br $B19 + end + local.get $l3 + local.get $l5 + i32.const 2 + i32.add + local.tee $p1 + i32.store offset=40 + local.get $l5 + i32.load8_u offset=1 + i32.const 63 + i32.and + end + local.tee $l12 + local.get $l6 + i32.const 31 + i32.and + local.tee $l9 + i32.const 6 + i32.shl + i32.or + local.get $l6 + i32.const 255 + i32.and + local.tee $l6 + i32.const 223 + i32.le_u + br_if $B17 + drop + block $B21 (result i32) + local.get $p0 + local.get $p1 + i32.eq + if $I22 + local.get $p0 + local.set $l5 + i32.const 0 + br $B21 + end + local.get $l3 + local.get $p1 + i32.const 1 + i32.add + local.tee $l5 + i32.store offset=40 + local.get $p1 + i32.load8_u + i32.const 63 + i32.and + end + local.get $l12 + i32.const 6 + i32.shl + i32.or + local.tee $p1 + local.get $l9 + i32.const 12 + i32.shl + i32.or + local.get $l6 + i32.const 240 + i32.lt_u + br_if $B17 + drop + local.get $p0 + local.get $l5 + i32.eq + if $I23 (result i32) + i32.const 0 + else + local.get $l3 + local.get $l5 + i32.const 1 + i32.add + i32.store offset=40 + local.get $l5 + i32.load8_u + i32.const 63 + i32.and + end + local.get $l9 + i32.const 18 + i32.shl + i32.const 1835008 + i32.and + local.get $p1 + i32.const 6 + i32.shl + i32.or + i32.or + end + local.tee $p0 + i32.const -9 + i32.add + local.tee $l5 + i32.const 30 + i32.le_u + br_if $B11 + local.get $p0 + i32.const 92 + i32.eq + br_if $B9 + local.get $p0 + i32.const 1114112 + i32.ne + br_if $B10 + end + local.get $l3 + i32.load offset=64 + i32.const 4 + i32.eq + br_if $B13 + local.get $l11 + call $f184 + local.tee $l4 + i32.const 1114112 + i32.eq + br_if $B13 + end + local.get $p2 + i32.load offset=24 + local.get $l4 + local.get $p2 + i32.const 28 + i32.add + i32.load + i32.load offset=16 + call_indirect (type $t0) $T0 + br_if $B12 + local.get $l3 + i32.load offset=48 + local.set $l4 + br $L3 + end + loop $L24 + local.get $l7 + i32.eqz + br_if $B4 + local.get $l3 + local.get $l8 + i32.store offset=28 + local.get $l3 + i32.const 1 + i32.store offset=60 + local.get $l3 + i32.const 1 + i32.store offset=52 + local.get $l3 + i32.const 1051688 + i32.store offset=48 + local.get $l3 + i32.const 1 + i32.store offset=44 + local.get $l3 + i32.const 1051680 + i32.store offset=40 + local.get $l3 + i32.const 13 + i32.store offset=36 + local.get $l7 + i32.const -1 + i32.add + local.set $l7 + local.get $l8 + i32.const 1 + i32.add + local.set $l8 + local.get $l3 + local.get $l3 + i32.const 32 + i32.add + i32.store offset=56 + local.get $l3 + local.get $l3 + i32.const 28 + i32.add + i32.store offset=32 + local.get $p2 + local.get $l3 + i32.const 40 + i32.add + call $f219 + i32.eqz + br_if $L24 + end + end + i32.const 1 + br $B0 + end + i32.const 116 + local.set $p1 + block $B25 + local.get $l5 + i32.const 1 + i32.sub + br_table $B6 $B10 $B10 $B25 $B10 $B10 $B10 $B10 $B10 $B10 $B10 $B10 $B10 $B10 $B10 $B10 $B10 $B10 $B10 $B10 $B10 $B10 $B10 $B10 $B9 $B10 $B10 $B10 $B10 $B9 $B5 + end + i32.const 114 + local.set $p1 + br $B5 + end + local.get $p0 + i32.const 1 + i32.or + i32.clz + i32.const 2 + i32.shr_u + i32.const 7 + i32.xor + i64.extend_i32_u + i64.const 21474836480 + i64.or + local.get $p0 + call $f198 + br_if $B7 + drop + i32.const 1 + local.set $l4 + local.get $p0 + call $f199 + i32.eqz + br_if $B8 + end + local.get $p0 + local.set $p1 + br $B5 + end + local.get $p0 + i32.const 1 + i32.or + i32.clz + i32.const 2 + i32.shr_u + i32.const 7 + i32.xor + i64.extend_i32_u + i64.const 21474836480 + i64.or + end + local.set $l13 + i32.const 3 + local.set $l4 + local.get $p0 + local.set $p1 + br $B5 + end + i32.const 110 + local.set $p1 + end + local.get $l3 + local.get $l13 + i64.store offset=56 + local.get $l3 + local.get $p1 + i32.store offset=52 + local.get $l3 + local.get $l4 + i32.store offset=48 + br $L3 + end + end + local.get $l3 + i32.const 40 + i32.add + local.get $l3 + i32.const 16 + i32.add + call $f196 + local.get $l3 + i32.load offset=40 + local.tee $l4 + br_if $L2 + end + end + local.get $p2 + i32.const 1050388 + i32.const 1 + call $f218 + end + local.get $l3 + i32.const 80 + i32.add + global.set $g0) + (func $f43 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + (local $l2 i32) (local $l3 i32) + global.get $g0 + i32.const 16 + i32.sub + local.tee $l2 + global.set $g0 + local.get $p0 + i32.load + local.tee $p0 + i32.load offset=8 + local.set $l3 + local.get $p0 + i32.load + local.set $p0 + local.get $l2 + local.get $p1 + call $f223 + local.get $l3 + if $I0 + loop $L1 + local.get $l2 + local.get $p0 + i32.store offset=12 + local.get $l2 + local.get $l2 + i32.const 12 + i32.add + call $f203 + local.get $p0 + i32.const 1 + i32.add + local.set $p0 + local.get $l3 + i32.const -1 + i32.add + local.tee $l3 + br_if $L1 + end + end + local.get $l2 + call $f208 + local.get $l2 + i32.const 16 + i32.add + global.set $g0) + (func $f44 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + local.get $p0 + i32.load + local.tee $p0 + i32.load + local.get $p0 + i32.load offset=8 + local.get $p1 + call $f42) + (func $f45 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + local.get $p0 + i32.load + local.get $p1 + call $f188) + (func $f46 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + local.get $p0 + i32.load + local.get $p0 + i32.load offset=4 + local.get $p1 + call $f225) + (func $f47 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + local.get $p0 + i32.load + local.get $p1 + call $f229) + (func $f48 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + (local $l2 i32) (local $l3 i32) (local $l4 i64) + global.get $g0 + i32.const 16 + i32.sub + local.tee $l2 + global.set $g0 + local.get $l2 + i32.const 0 + i32.store offset=4 + block $B0 (result i32) + block $B1 + local.get $p1 + i32.const 128 + i32.ge_u + if $I2 + local.get $p1 + i32.const 2048 + i32.lt_u + br_if $B1 + local.get $p1 + i32.const 65536 + i32.lt_u + if $I3 + local.get $l2 + local.get $p1 + i32.const 63 + i32.and + i32.const 128 + i32.or + i32.store8 offset=6 + local.get $l2 + local.get $p1 + i32.const 6 + i32.shr_u + i32.const 63 + i32.and + i32.const 128 + i32.or + i32.store8 offset=5 + local.get $l2 + local.get $p1 + i32.const 12 + i32.shr_u + i32.const 15 + i32.and + i32.const 224 + i32.or + i32.store8 offset=4 + i32.const 3 + br $B0 + end + local.get $l2 + local.get $p1 + i32.const 63 + i32.and + i32.const 128 + i32.or + i32.store8 offset=7 + local.get $l2 + local.get $p1 + i32.const 18 + i32.shr_u + i32.const 240 + i32.or + i32.store8 offset=4 + local.get $l2 + local.get $p1 + i32.const 6 + i32.shr_u + i32.const 63 + i32.and + i32.const 128 + i32.or + i32.store8 offset=6 + local.get $l2 + local.get $p1 + i32.const 12 + i32.shr_u + i32.const 63 + i32.and + i32.const 128 + i32.or + i32.store8 offset=5 + i32.const 4 + br $B0 + end + local.get $l2 + local.get $p1 + i32.store8 offset=4 + i32.const 1 + br $B0 + end + local.get $l2 + local.get $p1 + i32.const 63 + i32.and + i32.const 128 + i32.or + i32.store8 offset=5 + local.get $l2 + local.get $p1 + i32.const 6 + i32.shr_u + i32.const 31 + i32.and + i32.const 192 + i32.or + i32.store8 offset=4 + i32.const 2 + end + local.set $p1 + local.get $l2 + i32.const 8 + i32.add + local.get $p0 + i32.load + local.get $l2 + i32.const 4 + i32.add + local.get $p1 + call $f49 + i32.const 0 + local.set $p1 + local.get $l2 + i32.load8_u offset=8 + i32.const 3 + i32.ne + if $I4 + local.get $l2 + i64.load offset=8 + local.set $l4 + local.get $p0 + i32.load8_u offset=4 + i32.const 2 + i32.eq + if $I5 + local.get $p0 + i32.const 8 + i32.add + i32.load + local.tee $p1 + i32.load + local.get $p1 + i32.load offset=4 + i32.load + call_indirect (type $t2) $T0 + local.get $p1 + i32.load offset=4 + local.tee $l3 + i32.load offset=4 + if $I6 + local.get $l3 + i32.load offset=8 + drop + local.get $p1 + i32.load + call $f145 + end + local.get $p0 + i32.load offset=8 + call $f145 + end + local.get $p0 + local.get $l4 + i64.store offset=4 align=4 + i32.const 1 + local.set $p1 + end + local.get $l2 + i32.const 16 + i32.add + global.set $g0 + local.get $p1) + (func $f49 (type $t6) (param $p0 i32) (param $p1 i32) (param $p2 i32) (param $p3 i32) + (local $l4 i32) + global.get $g0 + i32.const 32 + i32.sub + local.tee $p1 + global.set $g0 + block $B0 + block $B1 + block $B2 + block $B3 + block $B4 + block $B5 + local.get $p3 + if $I6 + loop $L7 + local.get $p1 + local.get $p3 + i32.store offset=12 + local.get $p1 + local.get $p2 + i32.store offset=8 + local.get $p1 + i32.const 16 + i32.add + i32.const 2 + local.get $p1 + i32.const 8 + i32.add + call $f142 + block $B8 + local.get $p1 + i32.load16_u offset=16 + i32.const 1 + i32.ne + if $I9 + local.get $p1 + i32.load offset=20 + local.tee $l4 + i32.eqz + if $I10 + i32.const 28 + i32.const 1 + call $f36 + local.tee $p2 + i32.eqz + br_if $B2 + local.get $p2 + i32.const 24 + i32.add + i32.const 1050942 + i32.load align=1 + i32.store align=1 + local.get $p2 + i32.const 16 + i32.add + i32.const 1050934 + i64.load align=1 + i64.store align=1 + local.get $p2 + i32.const 8 + i32.add + i32.const 1050926 + i64.load align=1 + i64.store align=1 + local.get $p2 + i32.const 1050918 + i64.load align=1 + i64.store align=1 + i32.const 12 + i32.const 4 + call $f36 + local.tee $p3 + i32.eqz + br_if $B1 + local.get $p3 + i64.const 120259084316 + i64.store offset=4 align=4 + local.get $p3 + local.get $p2 + i32.store + i32.const 12 + i32.const 4 + call $f36 + local.tee $p2 + br_if $B4 + i32.const 12 + i32.const 4 + call $f168 + unreachable + end + local.get $p3 + local.get $l4 + i32.lt_u + br_if $B0 + local.get $p2 + local.get $l4 + i32.add + local.set $p2 + local.get $p3 + local.get $l4 + i32.sub + local.set $p3 + br $B8 + end + local.get $p1 + local.get $p1 + i32.load16_u offset=18 + i32.store16 offset=30 + local.get $p1 + i32.const 30 + i32.add + i32.load16_u + local.tee $l4 + call $f101 + i32.const 255 + i32.and + i32.const 15 + i32.ne + br_if $B5 + end + local.get $p3 + br_if $L7 + end + end + local.get $p0 + i32.const 3 + i32.store8 + br $B3 + end + local.get $p0 + i32.const 0 + i32.store + local.get $p0 + i32.const 4 + i32.add + local.get $l4 + i32.store + br $B3 + end + local.get $p2 + i32.const 14 + i32.store8 offset=8 + local.get $p2 + i32.const 1050348 + i32.store offset=4 + local.get $p2 + local.get $p3 + i32.store + local.get $p2 + local.get $p1 + i32.load16_u offset=16 align=1 + i32.store16 offset=9 align=1 + local.get $p2 + i32.const 11 + i32.add + local.get $p1 + i32.const 18 + i32.add + i32.load8_u + i32.store8 + local.get $p0 + i32.const 4 + i32.add + local.get $p2 + i32.store + local.get $p0 + i32.const 2 + i32.store + end + local.get $p1 + i32.const 32 + i32.add + global.set $g0 + return + end + i32.const 28 + i32.const 1 + call $f168 + unreachable + end + i32.const 12 + i32.const 4 + call $f168 + unreachable + end + local.get $l4 + local.get $p3 + call $f174 + unreachable) + (func $f50 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + (local $l2 i32) (local $l3 i32) (local $l4 i64) + global.get $g0 + i32.const 16 + i32.sub + local.tee $l2 + global.set $g0 + local.get $l2 + i32.const 0 + i32.store offset=4 + block $B0 (result i32) + block $B1 + local.get $p1 + i32.const 128 + i32.ge_u + if $I2 + local.get $p1 + i32.const 2048 + i32.lt_u + br_if $B1 + local.get $p1 + i32.const 65536 + i32.lt_u + if $I3 + local.get $l2 + local.get $p1 + i32.const 63 + i32.and + i32.const 128 + i32.or + i32.store8 offset=6 + local.get $l2 + local.get $p1 + i32.const 6 + i32.shr_u + i32.const 63 + i32.and + i32.const 128 + i32.or + i32.store8 offset=5 + local.get $l2 + local.get $p1 + i32.const 12 + i32.shr_u + i32.const 15 + i32.and + i32.const 224 + i32.or + i32.store8 offset=4 + i32.const 3 + br $B0 + end + local.get $l2 + local.get $p1 + i32.const 63 + i32.and + i32.const 128 + i32.or + i32.store8 offset=7 + local.get $l2 + local.get $p1 + i32.const 18 + i32.shr_u + i32.const 240 + i32.or + i32.store8 offset=4 + local.get $l2 + local.get $p1 + i32.const 6 + i32.shr_u + i32.const 63 + i32.and + i32.const 128 + i32.or + i32.store8 offset=6 + local.get $l2 + local.get $p1 + i32.const 12 + i32.shr_u + i32.const 63 + i32.and + i32.const 128 + i32.or + i32.store8 offset=5 + i32.const 4 + br $B0 + end + local.get $l2 + local.get $p1 + i32.store8 offset=4 + i32.const 1 + br $B0 + end + local.get $l2 + local.get $p1 + i32.const 63 + i32.and + i32.const 128 + i32.or + i32.store8 offset=5 + local.get $l2 + local.get $p1 + i32.const 6 + i32.shr_u + i32.const 31 + i32.and + i32.const 192 + i32.or + i32.store8 offset=4 + i32.const 2 + end + local.set $p1 + local.get $l2 + i32.const 8 + i32.add + local.get $p0 + i32.load + local.get $l2 + i32.const 4 + i32.add + local.get $p1 + call $f51 + i32.const 0 + local.set $p1 + local.get $l2 + i32.load8_u offset=8 + i32.const 3 + i32.ne + if $I4 + local.get $l2 + i64.load offset=8 + local.set $l4 + local.get $p0 + i32.load8_u offset=4 + i32.const 2 + i32.eq + if $I5 + local.get $p0 + i32.const 8 + i32.add + i32.load + local.tee $p1 + i32.load + local.get $p1 + i32.load offset=4 + i32.load + call_indirect (type $t2) $T0 + local.get $p1 + i32.load offset=4 + local.tee $l3 + i32.load offset=4 + if $I6 + local.get $l3 + i32.load offset=8 + drop + local.get $p1 + i32.load + call $f145 + end + local.get $p0 + i32.load offset=8 + call $f145 + end + local.get $p0 + local.get $l4 + i64.store offset=4 align=4 + i32.const 1 + local.set $p1 + end + local.get $l2 + i32.const 16 + i32.add + global.set $g0 + local.get $p1) + (func $f51 (type $t6) (param $p0 i32) (param $p1 i32) (param $p2 i32) (param $p3 i32) + (local $l4 i32) (local $l5 i32) (local $l6 i32) + global.get $g0 + i32.const 32 + i32.sub + local.tee $l5 + global.set $g0 + block $B0 + block $B1 + block $B2 + block $B3 + block $B4 + block $B5 + block $B6 + local.get $p3 + if $I7 + loop $L8 + local.get $p1 + i32.load + local.tee $l4 + i32.load offset=4 + br_if $B4 + local.get $l4 + i32.const -1 + i32.store offset=4 + local.get $l5 + i32.const 8 + i32.add + local.get $l4 + i32.const 8 + i32.add + local.get $p2 + local.get $p3 + call $f103 + local.get $l4 + local.get $l4 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + block $B9 + local.get $l5 + i32.load offset=8 + i32.const 1 + i32.ne + if $I10 + local.get $l5 + i32.load offset=12 + local.tee $l4 + i32.eqz + if $I11 + i32.const 28 + i32.const 1 + call $f36 + local.tee $p1 + i32.eqz + br_if $B3 + local.get $p1 + i32.const 24 + i32.add + i32.const 1050942 + i32.load align=1 + i32.store align=1 + local.get $p1 + i32.const 16 + i32.add + i32.const 1050934 + i64.load align=1 + i64.store align=1 + local.get $p1 + i32.const 8 + i32.add + i32.const 1050926 + i64.load align=1 + i64.store align=1 + local.get $p1 + i32.const 1050918 + i64.load align=1 + i64.store align=1 + i32.const 12 + i32.const 4 + call $f36 + local.tee $p2 + i32.eqz + br_if $B2 + local.get $p2 + i64.const 120259084316 + i64.store offset=4 align=4 + local.get $p2 + local.get $p1 + i32.store + i32.const 12 + i32.const 4 + call $f36 + local.tee $p1 + br_if $B5 + i32.const 12 + i32.const 4 + call $f168 + unreachable + end + local.get $p3 + local.get $l4 + i32.lt_u + br_if $B1 + local.get $p2 + local.get $l4 + i32.add + local.set $p2 + local.get $p3 + local.get $l4 + i32.sub + local.set $p3 + br $B9 + end + block $B12 (result i32) + block $B13 + block $B14 + block $B15 + local.get $l5 + i32.load8_u offset=12 + local.tee $l4 + i32.const 1 + i32.sub + br_table $B13 $B14 $B15 + end + local.get $l5 + i32.load offset=16 + call $f101 + i32.const 255 + i32.and + br $B12 + end + local.get $l5 + i32.load offset=16 + i32.load8_u offset=8 + br $B12 + end + local.get $l5 + i32.load8_u offset=13 + end + i32.const 15 + i32.ne + br_if $B6 + local.get $l4 + i32.const 2 + i32.lt_u + br_if $B9 + local.get $l5 + i32.load offset=16 + local.tee $l4 + i32.load + local.get $l4 + i32.load offset=4 + i32.load + call_indirect (type $t2) $T0 + local.get $l4 + i32.load offset=4 + local.tee $l6 + i32.load offset=4 + if $I16 + local.get $l6 + i32.load offset=8 + drop + local.get $l4 + i32.load + call $f145 + end + local.get $l4 + call $f145 + end + local.get $p3 + br_if $L8 + end + end + local.get $p0 + i32.const 3 + i32.store8 + br $B0 + end + local.get $p0 + local.get $l5 + i64.load offset=12 align=4 + i64.store align=4 + br $B0 + end + local.get $p1 + i32.const 14 + i32.store8 offset=8 + local.get $p1 + i32.const 1050348 + i32.store offset=4 + local.get $p1 + local.get $p2 + i32.store + local.get $p1 + local.get $l5 + i32.load16_u offset=24 align=1 + i32.store16 offset=9 align=1 + local.get $p1 + i32.const 11 + i32.add + local.get $l5 + i32.const 26 + i32.add + i32.load8_u + i32.store8 + local.get $p0 + i32.const 4 + i32.add + local.get $p1 + i32.store + local.get $p0 + i32.const 2 + i32.store + br $B0 + end + i32.const 1049320 + i32.const 16 + local.get $l5 + i32.const 24 + i32.add + i32.const 1049620 + call $f192 + unreachable + end + i32.const 28 + i32.const 1 + call $f168 + unreachable + end + i32.const 12 + i32.const 4 + call $f168 + unreachable + end + local.get $l4 + local.get $p3 + call $f174 + unreachable + end + local.get $l5 + i32.const 32 + i32.add + global.set $g0) + (func $f52 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + (local $l2 i32) + global.get $g0 + i32.const 32 + i32.sub + local.tee $l2 + global.set $g0 + local.get $l2 + local.get $p0 + i32.store offset=4 + local.get $l2 + i32.const 24 + i32.add + local.get $p1 + i32.const 16 + i32.add + i64.load align=4 + i64.store + local.get $l2 + i32.const 16 + i32.add + local.get $p1 + i32.const 8 + i32.add + i64.load align=4 + i64.store + local.get $l2 + local.get $p1 + i64.load align=4 + i64.store offset=8 + local.get $l2 + i32.const 4 + i32.add + i32.const 1049216 + local.get $l2 + i32.const 8 + i32.add + call $f179 + local.get $l2 + i32.const 32 + i32.add + global.set $g0) + (func $f53 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + (local $l2 i32) + global.get $g0 + i32.const 32 + i32.sub + local.tee $l2 + global.set $g0 + local.get $l2 + local.get $p0 + i32.store offset=4 + local.get $l2 + i32.const 24 + i32.add + local.get $p1 + i32.const 16 + i32.add + i64.load align=4 + i64.store + local.get $l2 + i32.const 16 + i32.add + local.get $p1 + i32.const 8 + i32.add + i64.load align=4 + i64.store + local.get $l2 + local.get $p1 + i64.load align=4 + i64.store offset=8 + local.get $l2 + i32.const 4 + i32.add + i32.const 1049240 + local.get $l2 + i32.const 8 + i32.add + call $f179 + local.get $l2 + i32.const 32 + i32.add + global.set $g0) + (func $f54 (type $t2) (param $p0 i32) + (local $l1 i32) (local $l2 i32) (local $l3 i32) (local $l4 i32) (local $l5 i32) (local $l6 i64) + global.get $g0 + i32.const 96 + i32.sub + local.tee $l1 + global.set $g0 + i32.const 1 + local.set $l2 + block $B0 + block $B1 + i32.const 1060568 + i32.load + i32.const 1 + i32.ne + if $I2 + i32.const 1060568 + i64.const 1 + i64.store + br $B1 + end + i32.const 1060572 + i32.load + i32.const 1 + i32.gt_u + br_if $B0 + end + i32.const 1060500 + i32.load + local.tee $l2 + i32.const 2 + i32.gt_u + if $I3 + i32.const 1 + local.set $l2 + br $B0 + end + block $B4 + block $B5 + block $B6 + local.get $l2 + i32.const 1 + i32.sub + br_table $B5 $B4 $B6 + end + local.get $l1 + i32.const -64 + i32.sub + i32.const 1050160 + i32.const 14 + call $f88 + block $B7 + local.get $l1 + i32.load offset=64 + local.tee $l4 + i32.eqz + if $I8 + i32.const 5 + local.set $l2 + br $B7 + end + local.get $l1 + i32.load offset=68 + block $B9 + block $B10 + local.get $l1 + i32.const 72 + i32.add + i32.load + i32.const -1 + i32.add + local.tee $l2 + i32.const 3 + i32.gt_u + br_if $B10 + block $B11 + block $B12 + local.get $l2 + i32.const 1 + i32.sub + br_table $B10 $B10 $B11 $B12 + end + i32.const 4 + local.set $l2 + i32.const 1 + local.set $l3 + local.get $l4 + i32.const 1050174 + i32.eq + br_if $B9 + local.get $l4 + i32.load8_u + i32.const 48 + i32.ne + br_if $B10 + br $B9 + end + i32.const 1 + local.set $l2 + i32.const 3 + local.set $l3 + local.get $l4 + i32.const 1051508 + i32.eq + br_if $B9 + local.get $l4 + i32.load align=1 + i32.const 1819047270 + i32.eq + br_if $B9 + end + i32.const 0 + local.set $l2 + i32.const 2 + local.set $l3 + end + i32.eqz + br_if $B7 + local.get $l4 + call $f145 + end + i32.const 1060500 + i32.const 1 + local.get $l3 + local.get $l2 + i32.const 5 + i32.eq + local.tee $l3 + select + i32.store + i32.const 4 + local.get $l2 + local.get $l3 + select + local.set $l2 + br $B0 + end + i32.const 4 + local.set $l2 + br $B0 + end + i32.const 0 + local.set $l2 + end + local.get $l1 + local.get $l2 + i32.store8 offset=35 + block $B13 + block $B14 + local.get $p0 + i32.load offset=12 + local.tee $l2 + if $I15 + local.get $l1 + local.get $l2 + i32.store offset=36 + local.get $l1 + i32.const 24 + i32.add + local.get $p0 + call $f187 + local.get $l1 + i32.load offset=24 + local.tee $l2 + local.get $l1 + i32.load offset=28 + i32.load offset=12 + call_indirect (type $t8) $T0 + local.set $l6 + local.get $l2 + i32.const 0 + local.get $l6 + i64.const 1229646359891580772 + i64.eq + select + br_if $B14 + local.get $l1 + i32.const 16 + i32.add + local.get $p0 + call $f187 + local.get $l1 + i32.load offset=16 + local.tee $l2 + local.get $l1 + i32.load offset=20 + i32.load offset=12 + call_indirect (type $t8) $T0 + local.set $l6 + i32.const 8 + local.set $p0 + i32.const 1051792 + local.set $l3 + local.get $l2 + i32.eqz + local.get $l6 + i64.const 8634666484767235598 + i64.ne + i32.or + i32.eqz + if $I16 + local.get $l2 + i32.load + local.set $l3 + local.get $l2 + i32.load offset=8 + local.set $p0 + end + local.get $l1 + local.get $l3 + i32.store offset=40 + br $B13 + end + i32.const 1049576 + i32.const 43 + i32.const 1049516 + call $f172 + unreachable + end + local.get $l1 + local.get $l2 + i32.load + i32.store offset=40 + local.get $l2 + i32.load offset=4 + local.set $p0 + end + local.get $l1 + local.get $p0 + i32.store offset=44 + i32.const 0 + local.set $p0 + i32.const 1060556 + i32.load + i32.const 1 + i32.ne + if $I17 + i32.const 1060556 + i64.const 1 + i64.store align=4 + i32.const 1060564 + i32.const 0 + i32.store + end + local.get $l1 + call $f81 + local.tee $l2 + i32.store offset=52 + block $B18 + local.get $l2 + i32.load offset=16 + local.tee $l3 + if $I19 + local.get $l2 + i32.const 16 + i32.add + i32.const 0 + local.get $l3 + select + local.tee $p0 + i32.load offset=4 + local.tee $l4 + i32.const -1 + i32.add + local.set $l3 + local.get $l4 + i32.eqz + br_if $B18 + local.get $p0 + i32.load + local.set $p0 + end + local.get $l1 + local.get $l3 + i32.const 9 + local.get $p0 + select + i32.store offset=60 + local.get $l1 + local.get $p0 + i32.const 1051800 + local.get $p0 + select + i32.store offset=56 + local.get $l1 + local.get $l1 + i32.const 35 + i32.add + i32.store offset=76 + local.get $l1 + local.get $l1 + i32.const 36 + i32.add + i32.store offset=72 + local.get $l1 + local.get $l1 + i32.const 40 + i32.add + i32.store offset=68 + local.get $l1 + local.get $l1 + i32.const 56 + i32.add + i32.store offset=64 + i32.const 0 + local.set $l4 + local.get $l1 + i32.const 8 + i32.add + i32.const 0 + local.get $l1 + call $f114 + local.get $l1 + i32.load offset=12 + local.set $p0 + block $B20 + local.get $l1 + i32.load offset=8 + local.tee $l3 + if $I21 + local.get $l1 + local.get $p0 + i32.store offset=84 + local.get $l1 + local.get $l3 + i32.store offset=80 + local.get $l1 + i32.const -64 + i32.sub + local.get $l1 + i32.const 80 + i32.add + i32.const 1051848 + call $f131 + local.get $l1 + local.get $l1 + i32.load offset=80 + local.get $l1 + i32.load offset=84 + call $f114 + block $B22 + local.get $l1 + i32.load + local.tee $l4 + i32.eqz + br_if $B22 + local.get $l4 + local.get $l1 + i32.load offset=4 + local.tee $l5 + i32.load + call_indirect (type $t2) $T0 + local.get $l5 + i32.load offset=4 + i32.eqz + br_if $B22 + local.get $l5 + i32.load offset=8 + drop + local.get $l4 + call $f145 + end + i32.const 1 + local.set $l4 + br $B20 + end + local.get $l1 + i32.const -64 + i32.sub + local.get $l1 + i32.const 88 + i32.add + i32.const 1051812 + call $f131 + end + local.get $l2 + local.get $l2 + i32.load + local.tee $l2 + i32.const -1 + i32.add + i32.store + local.get $l2 + i32.const 1 + i32.eq + if $I23 + local.get $l1 + i32.const 52 + i32.add + call $f78 + end + block $B24 + local.get $l4 + i32.const 1 + i32.xor + local.get $l3 + i32.const 0 + i32.ne + i32.and + i32.eqz + br_if $B24 + local.get $l3 + local.get $p0 + i32.load + call_indirect (type $t2) $T0 + local.get $p0 + i32.load offset=4 + i32.eqz + br_if $B24 + local.get $p0 + i32.load offset=8 + drop + local.get $l3 + call $f145 + end + local.get $l1 + i32.const 96 + i32.add + global.set $g0 + return + end + local.get $l3 + i32.const 0 + call $f173 + unreachable) + (func $f55 (type $t4) (param $p0 i32) (param $p1 i32) (param $p2 i32) + (local $l3 i32) + global.get $g0 + i32.const 16 + i32.sub + local.tee $l3 + global.set $g0 + local.get $l3 + local.get $p1 + i32.store offset=12 + local.get $l3 + local.get $p0 + i32.store offset=8 + local.get $l3 + i32.const 8 + i32.add + i32.const 1052068 + i32.const 0 + local.get $p2 + call $f134 + unreachable) + (func $f56 (type $t2) (param $p0 i32) + (local $l1 i32) + local.get $p0 + i32.load + local.tee $p0 + i32.load8_u offset=4 + i32.eqz + if $I0 + local.get $p0 + i32.const 0 + i32.store8 offset=4 + local.get $p0 + i32.load + local.set $l1 + local.get $p0 + i32.const 1 + i32.store + local.get $l1 + i32.load + local.tee $p0 + local.get $p0 + i32.load + local.tee $p0 + i32.const -1 + i32.add + i32.store + local.get $p0 + i32.const 1 + i32.eq + if $I1 + local.get $l1 + call $f57 + end + local.get $l1 + call $f145 + return + end + i32.const 1052440 + i32.const 32 + i32.const 1052424 + call $f55 + unreachable) + (func $f57 (type $t2) (param $p0 i32) + (local $l1 i32) (local $l2 i32) (local $l3 i32) (local $l4 i32) (local $l5 i32) + global.get $g0 + i32.const 16 + i32.sub + local.tee $l2 + global.set $g0 + local.get $p0 + i32.load + local.tee $l3 + i32.const 16 + i32.add + local.set $l4 + block $B0 + local.get $l3 + i32.const 28 + i32.add + i32.load8_u + i32.const 2 + i32.eq + br_if $B0 + local.get $l3 + i32.const 29 + i32.add + i32.load8_u + br_if $B0 + local.get $l2 + i32.const 8 + i32.add + local.get $l4 + call $f79 + local.get $l2 + i32.load8_u offset=8 + i32.const 2 + i32.ne + br_if $B0 + local.get $l2 + i32.load offset=12 + local.tee $l1 + i32.load + local.get $l1 + i32.load offset=4 + i32.load + call_indirect (type $t2) $T0 + local.get $l1 + i32.load offset=4 + local.tee $l5 + i32.load offset=4 + if $I1 + local.get $l5 + i32.load offset=8 + drop + local.get $l1 + i32.load + call $f145 + end + local.get $l1 + call $f145 + end + local.get $l3 + i32.const 20 + i32.add + i32.load + if $I2 + local.get $l4 + i32.load + call $f145 + end + local.get $p0 + i32.load + local.tee $l1 + local.get $l1 + i32.load offset=4 + local.tee $l1 + i32.const -1 + i32.add + i32.store offset=4 + local.get $l1 + i32.const 1 + i32.eq + if $I3 + local.get $p0 + i32.load + call $f145 + end + local.get $l2 + i32.const 16 + i32.add + global.set $g0) + (func $f58 (type $t1) (param $p0 i32) (param $p1 i32) (param $p2 i32) (result i32) + (local $l3 i32) (local $l4 i32) + global.get $g0 + i32.const 32 + i32.sub + local.tee $l3 + global.set $g0 + block $B0 (result i32) + local.get $p2 + i32.load + i32.const 1 + i32.eq + if $I1 + i32.const 1051512 + local.set $p2 + i32.const 9 + br $B0 + end + local.get $l3 + i32.const 16 + i32.add + local.get $p2 + i32.load offset=4 + local.get $p2 + i32.const 8 + i32.add + i32.load + call $f201 + i32.const 1051512 + local.get $l3 + i32.load offset=20 + local.get $l3 + i32.load offset=16 + i32.const 1 + i32.eq + local.tee $l4 + select + local.set $p2 + i32.const 9 + local.get $l3 + i32.const 24 + i32.add + i32.load + local.get $l4 + select + end + local.set $l4 + local.get $l3 + i32.const 8 + i32.add + local.get $p2 + local.get $l4 + call $f195 + local.get $l3 + i32.load offset=8 + local.get $l3 + i32.load offset=12 + local.get $p1 + call $f197 + block $B2 + local.get $p0 + i32.load + local.tee $p2 + i32.eqz + br_if $B2 + local.get $p0 + i32.load offset=4 + i32.eqz + br_if $B2 + local.get $p2 + call $f145 + end + local.get $l3 + i32.const 32 + i32.add + global.set $g0) + (func $f59 (type $t3) (param $p0 i32) (param $p1 i32) + (local $l2 i32) + global.get $g0 + i32.const 16 + i32.sub + local.tee $l2 + global.set $g0 + local.get $l2 + local.get $p0 + i32.load + i32.store offset=12 + local.get $l2 + i32.const 12 + i32.add + local.get $p1 + call $f60 + local.get $l2 + i32.const 16 + i32.add + global.set $g0) + (func $f60 (type $t3) (param $p0 i32) (param $p1 i32) + (local $l2 i32) (local $l3 i32) (local $l4 i32) (local $l5 i32) (local $l6 i32) (local $l7 i32) + local.get $p0 + i32.load + local.tee $p0 + i32.load8_u + local.get $p0 + i32.const 0 + i32.store8 + i32.const 1 + i32.and + if $I0 + i32.const 1 + local.set $l4 + loop $L1 + block $B2 + block $B3 + block $B4 + i32.const 1060577 + i32.load8_u + i32.eqz + if $I5 + i32.const 1060496 + i32.load + local.set $l2 + i32.const 1060496 + local.get $l4 + i32.const 10 + i32.eq + i32.store + i32.const 1060577 + i32.const 0 + i32.store8 + local.get $l2 + i32.const 1 + i32.le_u + if $I6 + local.get $l2 + i32.const 1 + i32.sub + br_if $B2 + i32.const 1051360 + i32.const 31 + i32.const 1051344 + call $f55 + unreachable + end + local.get $l2 + i32.load + local.tee $p1 + local.get $l2 + i32.load offset=8 + local.tee $l3 + i32.const 3 + i32.shl + i32.add + local.set $l5 + local.get $l2 + i32.load offset=4 + local.set $l7 + local.get $p1 + local.set $p0 + local.get $l3 + i32.eqz + br_if $B4 + loop $L7 + local.get $p0 + i32.load + local.tee $l3 + i32.eqz + if $I8 + local.get $p0 + i32.const 8 + i32.add + local.set $p0 + br $B4 + end + local.get $l3 + local.get $p0 + i32.const 4 + i32.add + i32.load + call $f80 + local.get $p0 + i32.const 8 + i32.add + local.tee $p0 + local.get $l5 + i32.ne + br_if $L7 + end + br $B3 + end + i32.const 1052440 + i32.const 32 + i32.const 1052424 + call $f55 + unreachable + end + local.get $p0 + local.get $l5 + i32.eq + br_if $B3 + loop $L9 + local.get $p0 + i32.load + local.tee $l3 + i32.eqz + br_if $B3 + local.get $l3 + local.get $p0 + i32.const 4 + i32.add + i32.load + local.tee $l6 + i32.load + call_indirect (type $t2) $T0 + local.get $l6 + i32.load offset=4 + if $I10 + local.get $l6 + i32.load offset=8 + drop + local.get $l3 + call $f145 + end + local.get $p0 + i32.const 8 + i32.add + local.tee $p0 + local.get $l5 + i32.ne + br_if $L9 + end + end + local.get $l7 + if $I11 + local.get $p1 + call $f145 + end + local.get $l2 + call $f145 + end + local.get $l4 + local.get $l4 + i32.const 10 + i32.lt_u + local.tee $p0 + i32.add + local.set $l4 + local.get $p0 + br_if $L1 + end + return + end + i32.const 1049576 + i32.const 43 + i32.const 1049516 + call $f172 + unreachable) + (func $f61 (type $t2) (param $p0 i32) + block $B0 + local.get $p0 + i32.load8_u offset=4 + br_if $B0 + i32.const 1060568 + i32.load + i32.const 1 + i32.ne + if $I1 + i32.const 1060568 + i64.const 1 + i64.store + br $B0 + end + i32.const 1060572 + i32.load + i32.eqz + br_if $B0 + local.get $p0 + i32.load + i32.const 1 + i32.store8 offset=4 + end + local.get $p0 + i32.load + i32.load + i32.const 0 + i32.store8) + (func $f62 (type $t2) (param $p0 i32) + (local $l1 i32) (local $l2 i32) + local.get $p0 + i32.load8_u offset=4 + i32.const 2 + i32.eq + if $I0 + local.get $p0 + i32.const 8 + i32.add + i32.load + local.tee $l1 + i32.load + local.get $l1 + i32.load offset=4 + i32.load + call_indirect (type $t2) $T0 + local.get $l1 + i32.load offset=4 + local.tee $l2 + i32.load offset=4 + if $I1 + local.get $l2 + i32.load offset=8 + drop + local.get $l1 + i32.load + call $f145 + end + local.get $p0 + i32.load offset=8 + call $f145 + end) + (func $f63 (type $t2) (param $p0 i32) + (local $l1 i32) + block $B0 + local.get $p0 + i32.load offset=4 + local.tee $l1 + i32.eqz + br_if $B0 + local.get $p0 + i32.const 8 + i32.add + i32.load + i32.eqz + br_if $B0 + local.get $l1 + call $f145 + end) + (func $f64 (type $t2) (param $p0 i32) + (local $l1 i32) + local.get $p0 + i32.load + local.get $p0 + i32.load offset=4 + i32.load + call_indirect (type $t2) $T0 + local.get $p0 + i32.load offset=4 + local.tee $l1 + i32.load offset=4 + if $I0 + local.get $l1 + i32.load offset=8 + drop + local.get $p0 + i32.load + call $f145 + end) + (func $f65 (type $t2) (param $p0 i32) + (local $l1 i32) + block $B0 + local.get $p0 + i32.load + local.tee $l1 + i32.eqz + br_if $B0 + local.get $p0 + i32.load offset=4 + i32.eqz + br_if $B0 + local.get $l1 + call $f145 + end) + (func $f66 (type $t2) (param $p0 i32) + local.get $p0 + i32.const 8 + i32.add + i32.load + if $I0 + local.get $p0 + i32.load offset=4 + call $f145 + end) + (func $f67 (type $t5) (param $p0 i32) (result i32) + local.get $p0 + i32.eqz + if $I0 + i32.const 1049576 + i32.const 43 + i32.const 1049516 + call $f172 + unreachable + end + local.get $p0) + (func $f68 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + local.get $p0 + i32.load + local.get $p1 + call $f48) + (func $f69 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + local.get $p0 + i32.load + local.get $p1 + call $f50) + (func $f70 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + (local $l2 i32) (local $l3 i32) + global.get $g0 + i32.const 16 + i32.sub + local.tee $l2 + global.set $g0 + block $B0 + local.get $p0 + i32.load + local.tee $p0 + block $B1 (result i32) + block $B2 + local.get $p1 + i32.const 128 + i32.ge_u + if $I3 + local.get $l2 + i32.const 0 + i32.store offset=12 + local.get $p1 + i32.const 2048 + i32.lt_u + br_if $B2 + local.get $p1 + i32.const 65536 + i32.lt_u + if $I4 + local.get $l2 + local.get $p1 + i32.const 63 + i32.and + i32.const 128 + i32.or + i32.store8 offset=14 + local.get $l2 + local.get $p1 + i32.const 6 + i32.shr_u + i32.const 63 + i32.and + i32.const 128 + i32.or + i32.store8 offset=13 + local.get $l2 + local.get $p1 + i32.const 12 + i32.shr_u + i32.const 15 + i32.and + i32.const 224 + i32.or + i32.store8 offset=12 + i32.const 3 + br $B1 + end + local.get $l2 + local.get $p1 + i32.const 63 + i32.and + i32.const 128 + i32.or + i32.store8 offset=15 + local.get $l2 + local.get $p1 + i32.const 18 + i32.shr_u + i32.const 240 + i32.or + i32.store8 offset=12 + local.get $l2 + local.get $p1 + i32.const 6 + i32.shr_u + i32.const 63 + i32.and + i32.const 128 + i32.or + i32.store8 offset=14 + local.get $l2 + local.get $p1 + i32.const 12 + i32.shr_u + i32.const 63 + i32.and + i32.const 128 + i32.or + i32.store8 offset=13 + i32.const 4 + br $B1 + end + local.get $p0 + i32.load offset=8 + local.tee $l3 + local.get $p0 + i32.load offset=4 + i32.eq + if $I5 (result i32) + local.get $p0 + i32.const 1 + call $f71 + local.get $p0 + i32.load offset=8 + else + local.get $l3 + end + local.get $p0 + i32.load + i32.add + local.get $p1 + i32.store8 + local.get $p0 + local.get $p0 + i32.load offset=8 + i32.const 1 + i32.add + i32.store offset=8 + br $B0 + end + local.get $l2 + local.get $p1 + i32.const 63 + i32.and + i32.const 128 + i32.or + i32.store8 offset=13 + local.get $l2 + local.get $p1 + i32.const 6 + i32.shr_u + i32.const 31 + i32.and + i32.const 192 + i32.or + i32.store8 offset=12 + i32.const 2 + end + local.tee $p1 + call $f71 + local.get $p0 + local.get $p0 + i32.load offset=8 + local.tee $l3 + local.get $p1 + i32.add + i32.store offset=8 + local.get $l3 + local.get $p0 + i32.load + i32.add + local.get $l2 + i32.const 12 + i32.add + local.get $p1 + call $f162 + drop + end + local.get $l2 + i32.const 16 + i32.add + global.set $g0 + i32.const 0) + (func $f71 (type $t3) (param $p0 i32) (param $p1 i32) + (local $l2 i32) (local $l3 i32) + block $B0 + block $B1 + local.get $p0 + i32.load offset=4 + local.tee $l2 + local.get $p0 + i32.load offset=8 + local.tee $l3 + i32.sub + local.get $p1 + i32.lt_u + if $I2 + local.get $p1 + local.get $l3 + i32.add + local.tee $p1 + local.get $l3 + i32.lt_u + br_if $B0 + local.get $l2 + i32.const 1 + i32.shl + local.tee $l3 + local.get $p1 + local.get $l3 + local.get $p1 + i32.gt_u + select + local.tee $p1 + i32.const 0 + i32.lt_s + br_if $B0 + block $B3 (result i32) + local.get $l2 + i32.eqz + if $I4 + local.get $p1 + i32.const 1 + call $f36 + br $B3 + end + local.get $p0 + i32.load + local.get $l2 + i32.const 1 + local.get $p1 + call $f37 + end + local.tee $l2 + i32.eqz + br_if $B1 + local.get $p0 + local.get $p1 + i32.store offset=4 + local.get $p0 + local.get $l2 + i32.store + end + return + end + local.get $p1 + i32.const 1 + call $f168 + unreachable + end + call $f169 + unreachable) + (func $f72 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + (local $l2 i32) + global.get $g0 + i32.const 32 + i32.sub + local.tee $l2 + global.set $g0 + local.get $l2 + local.get $p0 + i32.load + i32.store offset=4 + local.get $l2 + i32.const 24 + i32.add + local.get $p1 + i32.const 16 + i32.add + i64.load align=4 + i64.store + local.get $l2 + i32.const 16 + i32.add + local.get $p1 + i32.const 8 + i32.add + i64.load align=4 + i64.store + local.get $l2 + local.get $p1 + i64.load align=4 + i64.store offset=8 + local.get $l2 + i32.const 4 + i32.add + i32.const 1049216 + local.get $l2 + i32.const 8 + i32.add + call $f179 + local.get $l2 + i32.const 32 + i32.add + global.set $g0) + (func $f73 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + (local $l2 i32) + global.get $g0 + i32.const 32 + i32.sub + local.tee $l2 + global.set $g0 + local.get $l2 + local.get $p0 + i32.load + i32.store offset=4 + local.get $l2 + i32.const 24 + i32.add + local.get $p1 + i32.const 16 + i32.add + i64.load align=4 + i64.store + local.get $l2 + i32.const 16 + i32.add + local.get $p1 + i32.const 8 + i32.add + i64.load align=4 + i64.store + local.get $l2 + local.get $p1 + i64.load align=4 + i64.store offset=8 + local.get $l2 + i32.const 4 + i32.add + i32.const 1049240 + local.get $l2 + i32.const 8 + i32.add + call $f179 + local.get $l2 + i32.const 32 + i32.add + global.set $g0) + (func $f74 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + (local $l2 i32) + global.get $g0 + i32.const 32 + i32.sub + local.tee $l2 + global.set $g0 + local.get $l2 + local.get $p0 + i32.load + i32.store offset=4 + local.get $l2 + i32.const 24 + i32.add + local.get $p1 + i32.const 16 + i32.add + i64.load align=4 + i64.store + local.get $l2 + i32.const 16 + i32.add + local.get $p1 + i32.const 8 + i32.add + i64.load align=4 + i64.store + local.get $l2 + local.get $p1 + i64.load align=4 + i64.store offset=8 + local.get $l2 + i32.const 4 + i32.add + i32.const 1049264 + local.get $l2 + i32.const 8 + i32.add + call $f179 + local.get $l2 + i32.const 32 + i32.add + global.set $g0) + (func $f75 (type $t1) (param $p0 i32) (param $p1 i32) (param $p2 i32) (result i32) + (local $l3 i32) (local $l4 i64) + global.get $g0 + i32.const 16 + i32.sub + local.tee $l3 + global.set $g0 + local.get $l3 + i32.const 8 + i32.add + local.get $p0 + i32.load + local.tee $p0 + i32.load + local.get $p1 + local.get $p2 + call $f51 + i32.const 0 + local.set $p1 + local.get $l3 + i32.load8_u offset=8 + i32.const 3 + i32.ne + if $I0 + local.get $l3 + i64.load offset=8 + local.set $l4 + local.get $p0 + i32.load8_u offset=4 + i32.const 2 + i32.eq + if $I1 + local.get $p0 + i32.const 8 + i32.add + i32.load + local.tee $p1 + i32.load + local.get $p1 + i32.load offset=4 + i32.load + call_indirect (type $t2) $T0 + local.get $p1 + i32.load offset=4 + local.tee $p2 + i32.load offset=4 + if $I2 + local.get $p2 + i32.load offset=8 + drop + local.get $p1 + i32.load + call $f145 + end + local.get $p0 + i32.load offset=8 + call $f145 + end + local.get $p0 + local.get $l4 + i64.store offset=4 align=4 + i32.const 1 + local.set $p1 + end + local.get $l3 + i32.const 16 + i32.add + global.set $g0 + local.get $p1) + (func $f76 (type $t1) (param $p0 i32) (param $p1 i32) (param $p2 i32) (result i32) + (local $l3 i32) (local $l4 i64) + global.get $g0 + i32.const 16 + i32.sub + local.tee $l3 + global.set $g0 + local.get $l3 + i32.const 8 + i32.add + local.get $p0 + i32.load + local.tee $p0 + i32.load + local.get $p1 + local.get $p2 + call $f49 + i32.const 0 + local.set $p1 + local.get $l3 + i32.load8_u offset=8 + i32.const 3 + i32.ne + if $I0 + local.get $l3 + i64.load offset=8 + local.set $l4 + local.get $p0 + i32.load8_u offset=4 + i32.const 2 + i32.eq + if $I1 + local.get $p0 + i32.const 8 + i32.add + i32.load + local.tee $p1 + i32.load + local.get $p1 + i32.load offset=4 + i32.load + call_indirect (type $t2) $T0 + local.get $p1 + i32.load offset=4 + local.tee $p2 + i32.load offset=4 + if $I2 + local.get $p2 + i32.load offset=8 + drop + local.get $p1 + i32.load + call $f145 + end + local.get $p0 + i32.load offset=8 + call $f145 + end + local.get $p0 + local.get $l4 + i64.store offset=4 align=4 + i32.const 1 + local.set $p1 + end + local.get $l3 + i32.const 16 + i32.add + global.set $g0 + local.get $p1) + (func $f77 (type $t1) (param $p0 i32) (param $p1 i32) (param $p2 i32) (result i32) + (local $l3 i32) + local.get $p0 + i32.load + local.tee $p0 + local.get $p2 + call $f71 + local.get $p0 + local.get $p0 + i32.load offset=8 + local.tee $l3 + local.get $p2 + i32.add + i32.store offset=8 + local.get $l3 + local.get $p0 + i32.load + i32.add + local.get $p1 + local.get $p2 + call $f162 + drop + i32.const 0) + (func $f78 (type $t2) (param $p0 i32) + (local $l1 i32) (local $l2 i32) + block $B0 + local.get $p0 + i32.load + local.tee $l1 + i32.const 16 + i32.add + i32.load + local.tee $l2 + i32.eqz + br_if $B0 + local.get $l2 + i32.const 0 + i32.store8 + local.get $l1 + i32.const 20 + i32.add + i32.load + i32.eqz + br_if $B0 + local.get $l1 + i32.load offset=16 + call $f145 + end + local.get $l1 + i32.const 28 + i32.add + i32.load + call $f145 + local.get $p0 + i32.load + local.tee $l1 + local.get $l1 + i32.load offset=4 + local.tee $l1 + i32.const -1 + i32.add + i32.store offset=4 + local.get $l1 + i32.const 1 + i32.eq + if $I1 + local.get $p0 + i32.load + call $f145 + end) + (func $f79 (type $t3) (param $p0 i32) (param $p1 i32) + (local $l2 i32) (local $l3 i32) (local $l4 i32) (local $l5 i32) (local $l6 i32) (local $l7 i32) + global.get $g0 + i32.const 32 + i32.sub + local.tee $l4 + global.set $g0 + block $B0 + block $B1 + local.get $p1 + i32.load offset=8 + local.tee $l6 + i32.eqz + if $I2 + i32.const 3 + local.set $l3 + br $B1 + end + block $B3 (result i32) + loop $L4 + local.get $p1 + i32.const 1 + i32.store8 offset=13 + block $B5 + block $B6 + block $B7 + local.get $p1 + i32.load8_u offset=12 + local.tee $l2 + i32.const 2 + i32.ne + if $I8 + local.get $p1 + i32.load offset=8 + local.tee $l3 + local.get $l5 + i32.lt_u + br_if $B7 + local.get $l3 + local.get $l5 + i32.sub + local.set $l3 + block $B9 + local.get $l2 + i32.const 1 + i32.eq + br_if $B9 + local.get $p1 + i32.load + local.set $l2 + local.get $l4 + local.get $l3 + i32.store offset=12 + local.get $l4 + local.get $l2 + local.get $l5 + i32.add + i32.store offset=8 + local.get $l4 + i32.const 16 + i32.add + i32.const 1 + local.get $l4 + i32.const 8 + i32.add + call $f142 + local.get $l4 + i32.load16_u offset=16 + i32.const 1 + i32.eq + if $I10 + local.get $l4 + local.get $l4 + i32.load16_u offset=18 + i32.store16 offset=30 + local.get $l4 + i32.const 30 + i32.add + i32.load16_u + local.tee $l2 + i32.const 8 + i32.eq + br_if $B9 + local.get $p1 + i32.const 0 + i32.store8 offset=13 + i32.const 0 + local.get $l2 + call $f101 + i32.const 255 + i32.and + i32.const 15 + i32.ne + br_if $B3 + drop + br $B5 + end + local.get $l4 + i32.load offset=20 + local.set $l3 + end + local.get $p1 + i32.const 0 + i32.store8 offset=13 + local.get $l3 + i32.eqz + br_if $B6 + local.get $l3 + local.get $l5 + i32.add + local.set $l5 + br $B5 + end + i32.const 1049576 + i32.const 43 + i32.const 1049516 + call $f172 + unreachable + end + local.get $l5 + local.get $l3 + call $f174 + unreachable + end + block $B11 + i32.const 33 + i32.const 1 + call $f36 + local.tee $l2 + if $I12 + local.get $l2 + i32.const 32 + i32.add + i32.const 1050454 + i32.load8_u + i32.store8 + local.get $l2 + i32.const 24 + i32.add + i32.const 1050446 + i64.load align=1 + i64.store align=1 + local.get $l2 + i32.const 16 + i32.add + i32.const 1050438 + i64.load align=1 + i64.store align=1 + local.get $l2 + i32.const 8 + i32.add + i32.const 1050430 + i64.load align=1 + i64.store align=1 + local.get $l2 + i32.const 1050422 + i64.load align=1 + i64.store align=1 + i32.const 12 + i32.const 4 + call $f36 + local.tee $l3 + i32.eqz + br_if $B11 + local.get $l3 + i64.const 141733920801 + i64.store offset=4 align=4 + local.get $l3 + local.get $l2 + i32.store + i32.const 12 + i32.const 4 + call $f36 + local.tee $l2 + i32.eqz + if $I13 + i32.const 12 + i32.const 4 + call $f168 + unreachable + end + local.get $l2 + i32.const 14 + i32.store8 offset=8 + local.get $l2 + i32.const 1050348 + i32.store offset=4 + local.get $l2 + local.get $l3 + i32.store + local.get $l2 + local.get $l4 + i32.load16_u offset=16 align=1 + i32.store16 offset=9 align=1 + local.get $l2 + i32.const 11 + i32.add + local.get $l4 + i32.const 18 + i32.add + i32.load8_u + i32.store8 + i32.const 2 + br $B3 + end + i32.const 33 + i32.const 1 + call $f168 + unreachable + end + i32.const 12 + i32.const 4 + call $f168 + unreachable + end + local.get $l5 + local.get $l6 + i32.lt_u + br_if $L4 + end + i32.const 3 + end + local.set $l3 + local.get $l5 + i32.eqz + br_if $B1 + local.get $p1 + i32.load offset=8 + local.tee $l6 + local.get $l5 + i32.lt_u + br_if $B0 + local.get $p1 + i32.const 0 + i32.store offset=8 + local.get $l6 + local.get $l5 + i32.sub + local.tee $l6 + i32.eqz + br_if $B1 + local.get $p1 + i32.load + local.tee $l7 + local.get $l5 + local.get $l7 + i32.add + local.get $l6 + call $f159 + local.get $p1 + local.get $l6 + i32.store offset=8 + end + local.get $p0 + local.get $l3 + i32.store + local.get $p0 + i32.const 4 + i32.add + local.get $l2 + i32.store + local.get $l4 + i32.const 32 + i32.add + global.set $g0 + return + end + i32.const 1049792 + i32.const 28 + i32.const 1049776 + call $f172 + unreachable) + (func $f80 (type $t3) (param $p0 i32) (param $p1 i32) + (local $l2 i32) (local $l3 i32) (local $l4 i32) + global.get $g0 + local.tee $l2 + local.get $l2 + local.get $p1 + i32.load offset=4 + local.tee $l2 + i32.const 15 + i32.add + i32.const -16 + i32.and + i32.sub + local.tee $l4 + global.set $g0 + local.get $l4 + local.get $p0 + local.get $l2 + call $f162 + local.get $p1 + i32.load offset=12 + call_indirect (type $t2) $T0 + local.get $l2 + if $I0 + local.get $p1 + i32.load offset=8 + drop + local.get $p0 + call $f145 + end + global.set $g0) + (func $f81 (type $t10) (result i32) + (local $l0 i32) (local $l1 i32) (local $l2 i32) + global.get $g0 + i32.const 32 + i32.sub + local.tee $l1 + global.set $g0 + block $B0 + block $B1 + i32.const 1060560 + i32.load + local.tee $l0 + i32.const 1 + i32.add + i32.const 0 + i32.gt_s + if $I2 + i32.const 1060560 + local.get $l0 + i32.store + i32.const 1060564 + i32.load + local.tee $l2 + i32.eqz + if $I3 + local.get $l1 + i32.const 0 + i32.store offset=8 + local.get $l1 + i32.const 8 + i32.add + call $f85 + local.set $l2 + i32.const 1060560 + i32.load + br_if $B0 + i32.const 1060560 + i32.const -1 + i32.store + block $B4 + i32.const 1060564 + i32.load + local.tee $l0 + i32.eqz + br_if $B4 + local.get $l0 + local.get $l0 + i32.load + local.tee $l0 + i32.const -1 + i32.add + i32.store + local.get $l0 + i32.const 1 + i32.ne + br_if $B4 + i32.const 1060564 + call $f78 + end + i32.const 1060564 + local.get $l2 + i32.store + i32.const 1060560 + i32.const 1060560 + i32.load + i32.const 1 + i32.add + local.tee $l0 + i32.store + end + local.get $l0 + br_if $B0 + i32.const 1060560 + i32.const -1 + i32.store + local.get $l2 + local.get $l2 + i32.load + local.tee $l0 + i32.const 1 + i32.add + i32.store + local.get $l0 + i32.const -1 + i32.le_s + br_if $B1 + i32.const 1060560 + i32.const 1060560 + i32.load + i32.const 1 + i32.add + i32.store + local.get $l1 + i32.const 32 + i32.add + global.set $g0 + local.get $l2 + return + end + i32.const 1049336 + i32.const 24 + local.get $l1 + i32.const 24 + i32.add + i32.const 1049652 + call $f192 + unreachable + end + unreachable + end + i32.const 1049320 + i32.const 16 + local.get $l1 + i32.const 24 + i32.add + i32.const 1049620 + call $f192 + unreachable) + (func $f82 (type $t7) + (local $l0 i32) (local $l1 i32) (local $l2 i32) (local $l3 i32) (local $l4 i32) (local $l5 i32) + global.get $g0 + i32.const 96 + i32.sub + local.tee $l0 + global.set $g0 + i32.const 1060556 + i32.load + i32.const 1 + i32.ne + if $I0 + i32.const 1060556 + i64.const 1 + i64.store align=4 + i32.const 1060564 + i32.const 0 + i32.store + end + call $f81 + local.tee $l1 + i32.const 0 + local.get $l1 + i32.load offset=24 + local.tee $l3 + local.get $l3 + i32.const 2 + i32.eq + local.tee $l3 + select + i32.store offset=24 + local.get $l0 + local.get $l1 + i32.store offset=8 + block $B1 + local.get $l3 + br_if $B1 + block $B2 + block $B3 + local.get $l0 + i32.load offset=8 + local.tee $l3 + i32.const 28 + i32.add + local.tee $l4 + i32.load + local.tee $l1 + i32.load8_u + i32.eqz + if $I4 + local.get $l1 + i32.const 1 + i32.store8 + i32.const 0 + local.set $l1 + block $B5 + i32.const 1060568 + i32.load + i32.const 1 + i32.eq + if $I6 + i32.const 1060572 + i32.load + local.set $l1 + br $B5 + end + i32.const 1060568 + i64.const 1 + i64.store + end + i32.const 1060572 + local.get $l1 + i32.store + local.get $l3 + i32.const 32 + i32.add + i32.load8_u + br_if $B3 + local.get $l3 + i32.const 24 + i32.add + local.tee $l2 + local.get $l2 + i32.load + local.tee $l2 + i32.const 1 + local.get $l2 + select + i32.store + local.get $l2 + if $I7 + local.get $l2 + i32.const 2 + i32.ne + if $I8 + i32.const 1049912 + i32.const 23 + i32.const 1049896 + call $f55 + unreachable + end + local.get $l0 + i32.load offset=8 + i32.const 24 + i32.add + local.tee $l5 + i32.load + local.set $l2 + local.get $l5 + i32.const 0 + i32.store + local.get $l0 + local.get $l2 + i32.store offset=12 + local.get $l2 + i32.const 2 + i32.ne + br_if $B2 + block $B9 + local.get $l1 + br_if $B9 + i32.const 1060568 + i32.load + i32.const 1 + i32.ne + if $I10 + i32.const 1060568 + i64.const 1 + i64.store + br $B9 + end + i32.const 1060572 + i32.load + i32.eqz + br_if $B9 + local.get $l3 + i32.const 1 + i32.store8 offset=32 + end + local.get $l4 + i32.load + i32.const 0 + i32.store8 + br $B1 + end + local.get $l0 + i32.load offset=8 + i32.const 36 + i32.add + local.tee $l0 + local.get $l4 + i32.load + call $f83 + local.get $l0 + i32.load + drop + i32.const 1052356 + i32.const 29 + i32.const 1052340 + call $f55 + unreachable + end + i32.const 1052440 + i32.const 32 + i32.const 1052424 + call $f55 + unreachable + end + local.get $l0 + local.get $l4 + i32.store offset=72 + local.get $l0 + local.get $l1 + i32.const 0 + i32.ne + i32.store8 offset=76 + i32.const 1049668 + i32.const 43 + local.get $l0 + i32.const 72 + i32.add + i32.const 1049728 + call $f192 + unreachable + end + local.get $l0 + i32.const 60 + i32.add + i32.const 4 + i32.store + local.get $l0 + i32.const 52 + i32.add + i32.const 14 + i32.store + local.get $l0 + i32.const 36 + i32.add + i32.const 3 + i32.store + local.get $l0 + local.get $l0 + i32.const 12 + i32.add + i32.store offset=64 + local.get $l0 + i32.const 1049936 + i32.store offset=68 + local.get $l0 + i64.const 3 + i64.store offset=20 align=4 + local.get $l0 + i32.const 1049552 + i32.store offset=16 + local.get $l0 + i32.const 14 + i32.store offset=44 + local.get $l0 + i64.const 4 + i64.store offset=88 + local.get $l0 + i64.const 1 + i64.store offset=76 align=4 + local.get $l0 + i32.const 1049972 + i32.store offset=72 + local.get $l0 + local.get $l0 + i32.const 40 + i32.add + i32.store offset=32 + local.get $l0 + local.get $l0 + i32.const 72 + i32.add + i32.store offset=56 + local.get $l0 + local.get $l0 + i32.const 68 + i32.add + i32.store offset=48 + local.get $l0 + local.get $l0 + i32.const -64 + i32.sub + i32.store offset=40 + local.get $l0 + i32.const 16 + i32.add + i32.const 1049980 + call $f84 + unreachable + end + local.get $l0 + i32.load offset=8 + local.tee $l1 + local.get $l1 + i32.load + local.tee $l1 + i32.const -1 + i32.add + i32.store + local.get $l1 + i32.const 1 + i32.eq + if $I11 + local.get $l0 + i32.const 8 + i32.add + call $f78 + end + local.get $l0 + i32.const 96 + i32.add + global.set $g0) + (func $f83 (type $t3) (param $p0 i32) (param $p1 i32) + local.get $p0 + local.get $p0 + i32.load offset=4 + local.tee $p0 + local.get $p1 + local.get $p0 + select + i32.store offset=4 + local.get $p0 + i32.eqz + local.get $p0 + local.get $p1 + i32.eq + i32.or + i32.eqz + if $I0 + i32.const 1051056 + i32.const 54 + i32.const 1051040 + call $f55 + unreachable + end) + (func $f84 (type $t3) (param $p0 i32) (param $p1 i32) + (local $l2 i32) + global.get $g0 + i32.const 32 + i32.sub + local.tee $l2 + global.set $g0 + local.get $l2 + local.get $p1 + i32.load + local.get $p1 + i32.load offset=4 + local.get $p1 + i32.load offset=8 + local.get $p1 + i32.load offset=12 + call $f186 + local.get $l2 + local.get $p0 + i32.store offset=24 + local.get $l2 + i32.const 1049532 + i32.store offset=20 + local.get $l2 + i32.const 1 + i32.store offset=16 + local.get $l2 + local.get $l2 + i32.store offset=28 + local.get $l2 + i32.const 16 + i32.add + call $f133 + unreachable) + (func $f85 (type $t5) (param $p0 i32) (result i32) + (local $l1 i32) (local $l2 i32) (local $l3 i32) (local $l4 i32) (local $l5 i64) + global.get $g0 + i32.const 48 + i32.sub + local.tee $l1 + global.set $g0 + block $B0 + block $B1 + block $B2 + block $B3 + block $B4 (result i32) + i32.const 0 + local.get $p0 + i32.load + local.tee $l2 + i32.eqz + br_if $B4 + drop + local.get $l1 + local.get $p0 + i64.load offset=4 align=4 + i64.store offset=36 align=4 + local.get $l1 + local.get $l2 + i32.store offset=32 + local.get $l1 + i32.const 16 + i32.add + local.get $l1 + i32.const 32 + i32.add + call $f170 + local.get $l1 + i32.const 8 + i32.add + i32.const 0 + local.get $l1 + i32.load offset=16 + local.tee $p0 + local.get $l1 + i32.load offset=24 + call $f193 + local.get $l1 + i32.load offset=8 + br_if $B3 + local.get $l1 + i32.const 40 + i32.add + local.get $l1 + i32.const 24 + i32.add + i32.load + i32.store + local.get $l1 + local.get $l1 + i64.load offset=16 + i64.store offset=32 + local.get $l1 + local.get $l1 + i32.const 32 + i32.add + call $f86 + local.get $l1 + i32.load offset=4 + local.set $l4 + local.get $l1 + i32.load + end + local.set $l2 + i32.const 1060576 + i32.load8_u + br_if $B2 + i32.const 1060576 + i32.const 1 + i32.store8 + block $B5 + i32.const 1060472 + i64.load + local.tee $l5 + i64.const -1 + i64.ne + if $I6 + i32.const 1060472 + local.get $l5 + i64.const 1 + i64.add + i64.store + local.get $l5 + i64.const 0 + i64.ne + br_if $B5 + i32.const 1049576 + i32.const 43 + i32.const 1049516 + call $f172 + unreachable + end + i32.const 1050012 + i32.const 55 + i32.const 1049996 + call $f55 + unreachable + end + i32.const 1060576 + i32.const 0 + i32.store8 + i32.const 1 + i32.const 1 + call $f36 + local.tee $l3 + i32.eqz + br_if $B1 + local.get $l3 + i32.const 0 + i32.store8 + i32.const 48 + i32.const 8 + call $f36 + local.tee $p0 + i32.eqz + br_if $B0 + local.get $p0 + i64.const 1 + i64.store offset=36 align=4 + local.get $p0 + i32.const 0 + i32.store offset=24 + local.get $p0 + local.get $l4 + i32.store offset=20 + local.get $p0 + local.get $l2 + i32.store offset=16 + local.get $p0 + local.get $l5 + i64.store offset=8 + local.get $p0 + i64.const 4294967297 + i64.store + local.get $p0 + local.get $l3 + i64.extend_i32_u + i64.store offset=28 align=4 + local.get $l1 + i32.const 48 + i32.add + global.set $g0 + local.get $p0 + return + end + local.get $l1 + i32.load offset=12 + local.set $l2 + local.get $l1 + i32.const 40 + i32.add + local.get $l1 + i64.load offset=20 align=4 + i64.store + local.get $l1 + local.get $p0 + i32.store offset=36 + local.get $l1 + local.get $l2 + i32.store offset=32 + i32.const 1050067 + i32.const 47 + local.get $l1 + i32.const 32 + i32.add + i32.const 1049636 + call $f192 + unreachable + end + i32.const 1052440 + i32.const 32 + i32.const 1052424 + call $f55 + unreachable + end + i32.const 1 + i32.const 1 + call $f168 + unreachable + end + i32.const 48 + i32.const 8 + call $f168 + unreachable) + (func $f86 (type $t3) (param $p0 i32) (param $p1 i32) + (local $l2 i32) (local $l3 i32) (local $l4 i32) (local $l5 i32) + block $B0 + block $B1 + block $B2 + block $B3 + local.get $p1 + i32.load offset=4 + local.tee $l2 + local.get $p1 + i32.load offset=8 + local.tee $l3 + i32.eq + if $I4 + local.get $l3 + i32.const 1 + i32.add + local.tee $l2 + local.get $l3 + i32.lt_u + local.get $l2 + i32.const 0 + i32.lt_s + i32.or + br_if $B2 + block $B5 (result i32) + local.get $l3 + i32.eqz + if $I6 + local.get $l2 + i32.const 1 + call $f36 + br $B5 + end + local.get $p1 + i32.load + local.get $l3 + i32.const 1 + local.get $l2 + call $f37 + end + local.tee $l5 + i32.eqz + br_if $B3 + local.get $p1 + local.get $l2 + i32.store offset=4 + local.get $p1 + local.get $l5 + i32.store + end + local.get $l2 + local.get $l3 + i32.eq + if $I7 + local.get $p1 + i32.const 1 + call $f71 + local.get $p1 + i32.load offset=8 + local.set $l3 + local.get $p1 + i32.load offset=4 + local.set $l2 + end + local.get $p1 + local.get $l3 + i32.const 1 + i32.add + local.tee $l4 + i32.store offset=8 + local.get $l3 + local.get $p1 + i32.load + local.tee $l5 + i32.add + i32.const 0 + i32.store8 + local.get $l2 + local.get $l4 + i32.eq + if $I8 + local.get $l5 + local.set $p1 + local.get $l2 + local.set $l4 + br $B0 + end + local.get $l2 + local.get $l4 + i32.lt_u + br_if $B1 + local.get $l4 + i32.eqz + if $I9 + i32.const 0 + local.set $l4 + i32.const 1 + local.set $p1 + local.get $l2 + i32.eqz + br_if $B0 + local.get $l5 + call $f145 + br $B0 + end + local.get $l5 + local.get $l2 + i32.const 1 + local.get $l4 + call $f37 + local.tee $p1 + br_if $B0 + local.get $l4 + i32.const 1 + call $f168 + unreachable + end + local.get $l2 + i32.const 1 + call $f168 + unreachable + end + call $f169 + unreachable + end + i32.const 1049820 + i32.const 36 + i32.const 1049776 + call $f172 + unreachable + end + local.get $p0 + local.get $l4 + i32.store offset=4 + local.get $p0 + local.get $p1 + i32.store) + (func $f87 (type $t2) (param $p0 i32) + (local $l1 i32) (local $l2 i32) (local $l3 i32) + global.get $g0 + i32.const 16 + i32.sub + local.tee $l2 + global.set $g0 + local.get $p0 + i32.load + i32.const 24 + i32.add + local.tee $l3 + i32.load + local.set $l1 + local.get $l3 + i32.const 2 + i32.store + block $B0 + block $B1 + block $B2 + block $B3 + local.get $l1 + i32.const 2 + i32.le_u + if $I4 + local.get $l1 + i32.const 1 + i32.sub + br_if $B2 + br $B3 + end + i32.const 1050132 + i32.const 28 + i32.const 1050116 + call $f55 + unreachable + end + local.get $p0 + i32.load + local.tee $l3 + i32.const 28 + i32.add + local.tee $l1 + i32.load + local.tee $p0 + i32.load8_u + br_if $B1 + local.get $p0 + i32.const 1 + i32.store8 + i32.const 0 + local.set $p0 + block $B5 + i32.const 1060568 + i32.load + i32.const 1 + i32.eq + if $I6 + i32.const 1060572 + i32.load + local.set $p0 + br $B5 + end + i32.const 1060568 + i64.const 1 + i64.store + end + i32.const 1060572 + local.get $p0 + i32.store + local.get $l3 + i32.const 32 + i32.add + i32.load8_u + br_if $B0 + local.get $l1 + i32.load + i32.const 0 + i32.store8 + end + local.get $l2 + i32.const 16 + i32.add + global.set $g0 + return + end + i32.const 1052440 + i32.const 32 + i32.const 1052424 + call $f55 + unreachable + end + local.get $l2 + local.get $l1 + i32.store offset=8 + local.get $l2 + local.get $p0 + i32.const 0 + i32.ne + i32.store8 offset=12 + i32.const 1049668 + i32.const 43 + local.get $l2 + i32.const 8 + i32.add + i32.const 1049728 + call $f192 + unreachable) + (func $f88 (type $t4) (param $p0 i32) (param $p1 i32) (param $p2 i32) + (local $l3 i32) (local $l4 i32) (local $l5 i32) (local $l6 i32) (local $l7 i32) (local $l8 i32) (local $l9 i64) + global.get $g0 + i32.const 80 + i32.sub + local.tee $l3 + global.set $g0 + local.get $l3 + local.get $p2 + i32.store offset=28 + local.get $l3 + local.get $p1 + i32.store offset=24 + block $B0 + block $B1 + block $B2 + local.get $p2 + i32.const 1 + i32.add + local.tee $l4 + i32.const -1 + i32.le_s + br_if $B2 + block $B3 + local.get $l4 + if $I4 + local.get $l4 + i32.const 1 + call $f36 + local.tee $l6 + br_if $B3 + local.get $l4 + i32.const 1 + call $f168 + unreachable + end + call $f169 + unreachable + end + local.get $l3 + i32.const 16 + i32.add + i32.const 0 + local.get $l6 + local.get $p1 + local.get $p2 + call $f162 + local.tee $p1 + local.get $p2 + call $f193 + block $B5 + block $B6 + local.get $l3 + i32.load offset=16 + i32.eqz + if $I7 + local.get $l3 + local.get $p2 + i32.store offset=48 + local.get $l3 + local.get $l4 + i32.store offset=44 + local.get $l3 + local.get $p1 + i32.store offset=40 + local.get $l3 + i32.const 8 + i32.add + local.get $l3 + i32.const 40 + i32.add + call $f86 + local.get $l3 + i32.load offset=12 + local.set $l7 + local.get $l3 + i32.load offset=8 + local.tee $l6 + call $f155 + local.tee $l4 + br_if $B6 + br $B5 + end + local.get $l3 + i32.load offset=20 + local.set $p0 + local.get $l3 + i32.const 52 + i32.add + local.get $p2 + i32.store + local.get $l3 + i32.const 48 + i32.add + local.get $l4 + i32.store + local.get $l3 + local.get $p1 + i32.store offset=44 + local.get $l3 + local.get $p0 + i32.store offset=40 + local.get $l3 + i32.const -64 + i32.sub + local.get $l3 + i32.const 40 + i32.add + call $f91 + local.get $l3 + local.get $l3 + i64.load offset=64 + i64.store offset=32 + local.get $l3 + i32.const 60 + i32.add + i32.const 2 + i32.store + local.get $l3 + i32.const 76 + i32.add + i32.const 15 + i32.store + local.get $l3 + i64.const 2 + i64.store offset=44 align=4 + local.get $l3 + i32.const 1050212 + i32.store offset=40 + local.get $l3 + i32.const 16 + i32.store offset=68 + local.get $l3 + local.get $l3 + i32.const -64 + i32.sub + i32.store offset=56 + local.get $l3 + local.get $l3 + i32.const 32 + i32.add + i32.store offset=72 + local.get $l3 + local.get $l3 + i32.const 24 + i32.add + i32.store offset=64 + local.get $l3 + i32.const 40 + i32.add + i32.const 1050248 + call $f84 + unreachable + end + block $B8 + block $B9 + local.get $l4 + i32.load8_u + if $I10 + local.get $l4 + i32.const 1 + i32.add + local.set $l5 + i32.const 0 + local.set $p2 + loop $L11 + local.get $p2 + local.get $l5 + i32.add + local.get $p2 + i32.const 1 + i32.add + local.tee $p1 + local.set $p2 + i32.load8_u + br_if $L11 + end + local.get $p1 + i32.const -1 + i32.eq + br_if $B1 + local.get $p1 + i32.const -1 + i32.le_s + br_if $B2 + local.get $p1 + br_if $B9 + end + i32.const 1 + local.set $l5 + i32.const 0 + local.set $p1 + br $B8 + end + local.get $p1 + i32.const 1 + call $f36 + local.tee $l5 + i32.eqz + br_if $B0 + end + local.get $l5 + local.get $l4 + local.get $p1 + call $f162 + drop + local.get $p1 + i64.extend_i32_u + local.tee $l9 + i64.const 32 + i64.shl + local.get $l9 + i64.or + local.set $l9 + end + local.get $l6 + i32.const 0 + i32.store8 + local.get $l7 + if $I12 + local.get $l6 + call $f145 + end + local.get $p0 + local.get $l9 + i64.store32 offset=4 + local.get $p0 + local.get $l5 + i32.store + local.get $p0 + i32.const 8 + i32.add + local.get $l9 + i64.const 32 + i64.shr_u + i64.store32 + local.get $l3 + i32.const 80 + i32.add + global.set $g0 + return + end + call $f12 + unreachable + end + local.get $p1 + i32.const 0 + call $f173 + unreachable + end + local.get $p1 + i32.const 1 + call $f168 + unreachable) + (func $f89 (type $t2) (param $p0 i32) + (local $l1 i32) (local $l2 i32) (local $l3 i32) + global.get $g0 + i32.const 16 + i32.sub + local.tee $l2 + global.set $g0 + block $B0 + block $B1 + i32.const 35 + i32.const 1 + call $f36 + local.tee $l1 + if $I2 + local.get $l1 + i32.const 31 + i32.add + i32.const 1052599 + i32.load align=1 + i32.store align=1 + local.get $l1 + i32.const 24 + i32.add + i32.const 1052592 + i64.load align=1 + i64.store align=1 + local.get $l1 + i32.const 16 + i32.add + i32.const 1052584 + i64.load align=1 + i64.store align=1 + local.get $l1 + i32.const 8 + i32.add + i32.const 1052576 + i64.load align=1 + i64.store align=1 + local.get $l1 + i32.const 1052568 + i64.load align=1 + i64.store align=1 + i32.const 12 + i32.const 4 + call $f36 + local.tee $l3 + i32.eqz + br_if $B1 + local.get $l3 + i64.const 150323855395 + i64.store offset=4 align=4 + local.get $l3 + local.get $l1 + i32.store + i32.const 12 + i32.const 4 + call $f36 + local.tee $l1 + i32.eqz + br_if $B0 + local.get $l1 + i32.const 16 + i32.store8 offset=8 + local.get $l1 + i32.const 1050348 + i32.store offset=4 + local.get $l1 + local.get $l3 + i32.store + local.get $l1 + local.get $l2 + i32.load16_u offset=13 align=1 + i32.store16 offset=9 align=1 + local.get $l1 + i32.const 11 + i32.add + local.get $l2 + i32.const 15 + i32.add + i32.load8_u + i32.store8 + local.get $p0 + i32.const 8 + i32.add + local.get $l1 + i32.store + local.get $p0 + i64.const 8589934593 + i64.store align=4 + local.get $l2 + i32.const 16 + i32.add + global.set $g0 + return + end + i32.const 35 + i32.const 1 + call $f168 + unreachable + end + i32.const 12 + i32.const 4 + call $f168 + unreachable + end + i32.const 12 + i32.const 4 + call $f168 + unreachable) + (func $f90 (type $t2) (param $p0 i32) + (local $l1 i32) (local $l2 i32) (local $l3 i32) (local $l4 i32) (local $l5 i32) + global.get $g0 + i32.const -64 + i32.add + local.tee $l1 + global.set $g0 + local.get $l1 + i32.const 8 + i32.add + i32.const 1048812 + i32.const 16 + call $f88 + block $B0 + local.get $l1 + i32.load offset=8 + local.tee $l2 + if $I1 + local.get $l1 + i32.load offset=12 + local.set $l3 + local.get $l1 + i32.const 40 + i32.add + local.get $l2 + local.get $l1 + i32.const 16 + i32.add + i32.load + local.tee $l4 + call $f201 + i32.const 1 + local.set $l5 + block $B2 + local.get $l1 + i32.load offset=40 + i32.const 1 + i32.ne + if $I3 + i32.const 0 + local.set $l5 + br $B2 + end + local.get $l1 + local.get $l1 + i64.load offset=44 align=4 + i64.store offset=52 align=4 + local.get $l1 + local.get $l4 + i32.store offset=48 + local.get $l1 + local.get $l3 + i32.store offset=44 + local.get $l1 + local.get $l2 + i32.store offset=40 + local.get $l1 + i32.const 24 + i32.add + local.get $l1 + i32.const 40 + i32.add + call $f170 + local.get $l1 + i32.load offset=32 + local.set $l4 + local.get $l1 + i32.load offset=28 + local.set $l3 + local.get $l1 + i32.load offset=24 + local.set $l2 + end + local.get $p0 + i32.const 12 + i32.add + local.get $l4 + i32.store + local.get $p0 + i32.const 8 + i32.add + local.get $l3 + i32.store + local.get $p0 + local.get $l2 + i32.store offset=4 + br $B0 + end + local.get $p0 + i32.const 0 + i32.store offset=4 + i32.const 1 + local.set $l5 + end + local.get $p0 + local.get $l5 + i32.store + local.get $l1 + i32.const -64 + i32.sub + global.set $g0) + (func $f91 (type $t3) (param $p0 i32) (param $p1 i32) + (local $l2 i32) (local $l3 i32) (local $l4 i32) + global.get $g0 + i32.const 16 + i32.sub + local.tee $l3 + global.set $g0 + block $B0 + block $B1 + i32.const 33 + i32.const 1 + call $f36 + local.tee $l2 + if $I2 + local.get $l2 + i32.const 32 + i32.add + i32.const 1050421 + i32.load8_u + i32.store8 + local.get $l2 + i32.const 24 + i32.add + i32.const 1050413 + i64.load align=1 + i64.store align=1 + local.get $l2 + i32.const 16 + i32.add + i32.const 1050405 + i64.load align=1 + i64.store align=1 + local.get $l2 + i32.const 8 + i32.add + i32.const 1050397 + i64.load align=1 + i64.store align=1 + local.get $l2 + i32.const 1050389 + i64.load align=1 + i64.store align=1 + i32.const 12 + i32.const 4 + call $f36 + local.tee $l4 + i32.eqz + br_if $B1 + local.get $l4 + i64.const 141733920801 + i64.store offset=4 align=4 + local.get $l4 + local.get $l2 + i32.store + i32.const 12 + i32.const 4 + call $f36 + local.tee $l2 + i32.eqz + br_if $B0 + local.get $l2 + i32.const 11 + i32.store8 offset=8 + local.get $l2 + i32.const 1050348 + i32.store offset=4 + local.get $l2 + local.get $l4 + i32.store + local.get $l2 + local.get $l3 + i32.load16_u offset=13 align=1 + i32.store16 offset=9 align=1 + local.get $l2 + i32.const 11 + i32.add + local.get $l3 + i32.const 15 + i32.add + i32.load8_u + i32.store8 + local.get $p0 + i32.const 2 + i32.store8 + local.get $p0 + local.get $l3 + i32.load16_u offset=10 align=1 + i32.store16 offset=1 align=1 + local.get $p0 + i32.const 3 + i32.add + local.get $l3 + i32.const 12 + i32.add + i32.load8_u + i32.store8 + local.get $p0 + i32.const 4 + i32.add + local.get $l2 + i32.store + local.get $p1 + i32.const 8 + i32.add + i32.load + if $I3 + local.get $p1 + i32.load offset=4 + call $f145 + end + local.get $l3 + i32.const 16 + i32.add + global.set $g0 + return + end + i32.const 33 + i32.const 1 + call $f168 + unreachable + end + i32.const 12 + i32.const 4 + call $f168 + unreachable + end + i32.const 12 + i32.const 4 + call $f168 + unreachable) + (func $f92 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + (local $l2 i32) (local $l3 i32) (local $l4 i32) + global.get $g0 + i32.const -64 + i32.add + local.tee $l2 + global.set $g0 + block $B0 + block $B1 + block $B2 + block $B3 + local.get $p0 + i32.load8_u + i32.const 1 + i32.sub + br_table $B1 $B2 $B3 + end + local.get $l2 + local.get $p0 + i32.const 4 + i32.add + i32.load + local.tee $p0 + i32.store offset=4 + local.get $l2 + i32.const 8 + i32.add + local.get $p0 + call $f104 + local.get $l2 + i32.const 60 + i32.add + i32.const 2 + i32.store + local.get $l2 + i32.const 36 + i32.add + i32.const 17 + i32.store + local.get $l2 + i64.const 3 + i64.store offset=44 align=4 + local.get $l2 + i32.const 1050772 + i32.store offset=40 + local.get $l2 + i32.const 18 + i32.store offset=28 + local.get $l2 + local.get $l2 + i32.const 24 + i32.add + i32.store offset=56 + local.get $l2 + local.get $l2 + i32.const 4 + i32.add + i32.store offset=32 + local.get $l2 + local.get $l2 + i32.const 8 + i32.add + i32.store offset=24 + local.get $p1 + local.get $l2 + i32.const 40 + i32.add + call $f219 + local.set $p0 + local.get $l2 + i32.load offset=12 + i32.eqz + br_if $B0 + local.get $l2 + i32.load offset=8 + call $f145 + br $B0 + end + local.get $p0 + i32.const 4 + i32.add + i32.load + local.tee $p0 + i32.load + local.get $p1 + local.get $p0 + i32.load offset=4 + i32.load offset=32 + call_indirect (type $t0) $T0 + local.set $p0 + br $B0 + end + i32.const 1050455 + local.set $l3 + i32.const 22 + local.set $l4 + block $B4 + block $B5 (result i32) + block $B6 + block $B7 + block $B8 + block $B9 + block $B10 + block $B11 + block $B12 + block $B13 + block $B14 + block $B15 + block $B16 + block $B17 + block $B18 + block $B19 + block $B20 + block $B21 + block $B22 + local.get $p0 + i32.load8_u offset=1 + i32.const 1 + i32.sub + br_table $B21 $B20 $B19 $B18 $B17 $B16 $B15 $B14 $B13 $B12 $B11 $B10 $B9 $B8 $B7 $B6 $B4 $B22 + end + i32.const 1050736 + local.set $l3 + i32.const 16 + local.set $l4 + br $B4 + end + i32.const 1050719 + local.set $l3 + i32.const 17 + local.set $l4 + br $B4 + end + i32.const 1050701 + local.set $l3 + i32.const 18 + local.set $l4 + br $B4 + end + i32.const 1050685 + local.set $l3 + i32.const 16 + local.set $l4 + br $B4 + end + i32.const 1050667 + local.set $l3 + i32.const 18 + local.set $l4 + br $B4 + end + i32.const 1050654 + local.set $l3 + i32.const 13 + local.set $l4 + br $B4 + end + i32.const 1050640 + br $B5 + end + i32.const 1050619 + local.set $l3 + i32.const 21 + local.set $l4 + br $B4 + end + i32.const 1050608 + local.set $l3 + i32.const 11 + local.set $l4 + br $B4 + end + i32.const 1050587 + local.set $l3 + i32.const 21 + local.set $l4 + br $B4 + end + i32.const 1050566 + local.set $l3 + i32.const 21 + local.set $l4 + br $B4 + end + i32.const 1050543 + local.set $l3 + i32.const 23 + local.set $l4 + br $B4 + end + i32.const 1050531 + local.set $l3 + i32.const 12 + local.set $l4 + br $B4 + end + i32.const 1050522 + local.set $l3 + i32.const 9 + local.set $l4 + br $B4 + end + i32.const 1050512 + local.set $l3 + i32.const 10 + local.set $l4 + br $B4 + end + i32.const 1050491 + local.set $l3 + i32.const 21 + local.set $l4 + br $B4 + end + i32.const 1050477 + end + local.set $l3 + i32.const 14 + local.set $l4 + end + local.get $l2 + i32.const 60 + i32.add + i32.const 1 + i32.store + local.get $l2 + local.get $l4 + i32.store offset=28 + local.get $l2 + local.get $l3 + i32.store offset=24 + local.get $l2 + i32.const 19 + i32.store offset=12 + local.get $l2 + i64.const 1 + i64.store offset=44 align=4 + local.get $l2 + i32.const 1050752 + i32.store offset=40 + local.get $l2 + local.get $l2 + i32.const 24 + i32.add + i32.store offset=8 + local.get $l2 + local.get $l2 + i32.const 8 + i32.add + i32.store offset=56 + local.get $p1 + local.get $l2 + i32.const 40 + i32.add + call $f219 + local.set $p0 + end + local.get $l2 + i32.const -64 + i32.sub + global.set $g0 + local.get $p0) + (func $f93 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + local.get $p0 + i32.load + local.get $p0 + i32.load offset=4 + local.get $p1 + call $f42) + (func $f94 (type $t7) + (local $l0 i32) (local $l1 i32) (local $l2 i32) (local $l3 i32) (local $l4 i32) (local $l5 i32) (local $l6 i64) (local $l7 i64) + global.get $g0 + i32.const 80 + i32.sub + local.tee $l0 + global.set $g0 + local.get $l0 + i32.const 16 + i32.store offset=44 + local.get $l0 + i32.const 1048812 + i32.store offset=40 + local.get $l0 + i32.const 5 + i32.store offset=52 + local.get $l0 + i32.const 1048828 + i32.store offset=48 + i32.const 17 + i32.const 1 + call $f36 + local.tee $l2 + if $I0 + local.get $l0 + i32.const 32 + i32.add + i32.const 0 + local.get $l2 + i32.const 1048812 + i32.const 16 + call $f162 + local.tee $l2 + i32.const 16 + call $f193 + block $B1 + local.get $l0 + i32.load offset=32 + if $I2 + local.get $l0 + i32.load offset=36 + local.set $l1 + local.get $l0 + i32.const 76 + i32.add + i32.const 16 + i32.store + local.get $l0 + i32.const 72 + i32.add + i32.const 17 + i32.store + local.get $l0 + local.get $l2 + i32.store offset=68 + local.get $l0 + local.get $l1 + i32.store offset=64 + local.get $l0 + i32.const 56 + i32.add + local.get $l0 + i32.const -64 + i32.sub + call $f91 + local.get $l0 + i64.load offset=56 + local.tee $l6 + i64.const 8 + i64.shr_u + local.set $l7 + local.get $l6 + i32.wrap_i64 + local.set $l1 + br $B1 + end + local.get $l0 + i32.const 16 + i32.store offset=72 + local.get $l0 + i32.const 17 + i32.store offset=68 + local.get $l0 + local.get $l2 + i32.store offset=64 + local.get $l0 + i32.const 24 + i32.add + local.get $l0 + i32.const -64 + i32.sub + call $f86 + local.get $l0 + i32.load offset=28 + local.set $l4 + local.get $l0 + i32.load offset=24 + local.set $l2 + i32.const 6 + i32.const 1 + call $f36 + local.tee $l1 + i32.eqz + if $I3 + i32.const 6 + i32.const 1 + call $f168 + unreachable + end + local.get $l0 + i32.const 16 + i32.add + i32.const 0 + local.get $l1 + i32.const 1048828 + i32.const 5 + call $f162 + local.tee $l1 + i32.const 5 + call $f193 + local.get $l0 + i32.load offset=16 + if $I4 + local.get $l0 + i32.load offset=20 + local.set $l3 + local.get $l0 + i32.const 76 + i32.add + i32.const 5 + i32.store + local.get $l0 + i32.const 72 + i32.add + i32.const 6 + i32.store + local.get $l0 + local.get $l1 + i32.store offset=68 + local.get $l0 + local.get $l3 + i32.store offset=64 + local.get $l0 + i32.const 56 + i32.add + local.get $l0 + i32.const -64 + i32.sub + call $f91 + local.get $l0 + i64.load offset=56 + local.set $l6 + local.get $l2 + i32.const 0 + i32.store8 + local.get $l6 + i64.const 8 + i64.shr_u + local.set $l7 + local.get $l6 + i32.wrap_i64 + local.set $l1 + local.get $l4 + i32.eqz + br_if $B1 + local.get $l2 + call $f145 + br $B1 + end + local.get $l0 + i32.const 5 + i32.store offset=72 + local.get $l0 + i32.const 6 + i32.store offset=68 + local.get $l0 + local.get $l1 + i32.store offset=64 + local.get $l0 + i32.const 8 + i32.add + local.get $l0 + i32.const -64 + i32.sub + call $f86 + local.get $l0 + i32.load offset=12 + block $B5 (result i32) + i32.const 3 + local.get $l2 + local.get $l0 + i32.load offset=8 + local.tee $l3 + call $f158 + i32.const -1 + i32.ne + br_if $B5 + drop + i32.const 1061076 + i64.load32_u + i64.const 24 + i64.shl + local.set $l7 + i32.const 0 + end + local.set $l1 + local.get $l3 + i32.const 0 + i32.store8 + if $I6 + local.get $l3 + call $f145 + end + local.get $l2 + i32.const 0 + i32.store8 + local.get $l4 + i32.eqz + br_if $B1 + local.get $l2 + call $f145 + end + local.get $l1 + i32.const 255 + i32.and + i32.const 3 + i32.eq + if $I7 + local.get $l0 + i32.const 80 + i32.add + global.set $g0 + return + end + local.get $l0 + local.get $l1 + i64.extend_i32_u + i64.const 255 + i64.and + local.get $l7 + i64.const 8 + i64.shl + i64.or + i64.store offset=64 + local.get $l0 + i32.const 40 + i32.add + local.get $l0 + i32.const 48 + i32.add + local.get $l0 + i32.const -64 + i32.sub + call $f95 + unreachable + end + i32.const 17 + i32.const 1 + call $f168 + unreachable) + (func $f95 (type $t4) (param $p0 i32) (param $p1 i32) (param $p2 i32) + (local $l3 i32) + global.get $g0 + i32.const 48 + i32.sub + local.tee $l3 + global.set $g0 + local.get $l3 + i32.const 44 + i32.add + i32.const 15 + i32.store + local.get $l3 + i32.const 36 + i32.add + i32.const 16 + i32.store + local.get $l3 + i32.const 20 + i32.add + i32.const 3 + i32.store + local.get $l3 + i64.const 3 + i64.store offset=4 align=4 + local.get $l3 + i32.const 1050308 + i32.store + local.get $l3 + local.get $p2 + i32.store offset=40 + local.get $l3 + local.get $p1 + i32.store offset=32 + local.get $l3 + i32.const 16 + i32.store offset=28 + local.get $l3 + local.get $p0 + i32.store offset=24 + local.get $l3 + local.get $l3 + i32.const 24 + i32.add + i32.store offset=16 + local.get $l3 + i32.const 1050332 + call $f84 + unreachable) + (func $f96 (type $t3) (param $p0 i32) (param $p1 i32) + local.get $p0 + i32.const 0 + i32.store) + (func $f97 (type $t8) (param $p0 i32) (result i64) + i64.const 6492544822980680759) + (func $f98 (type $t5) (param $p0 i32) (result i32) + i32.const 0) + (func $f99 (type $t3) (param $p0 i32) (param $p1 i32) + local.get $p0 + local.get $p1 + i32.load offset=8 + i32.store offset=4 + local.get $p0 + local.get $p1 + i32.load + i32.store) + (func $f100 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + local.get $p0 + i32.load + local.get $p0 + i32.load offset=8 + local.get $p1 + call $f224) + (func $f101 (type $t5) (param $p0 i32) (result i32) + (local $l1 i32) + i32.const 16 + local.set $l1 + block $B0 + local.get $p0 + i32.const 65535 + i32.gt_u + br_if $B0 + local.get $p0 + i32.const 65535 + i32.and + i32.const -2 + i32.add + local.tee $p0 + i32.const 71 + i32.gt_u + br_if $B0 + block $B1 + block $B2 + block $B3 + block $B4 + block $B5 + block $B6 + block $B7 + block $B8 + block $B9 + block $B10 + block $B11 + block $B12 + block $B13 + block $B14 + local.get $p0 + i32.const 1 + i32.sub + br_table $B7 $B8 $B0 $B1 $B0 $B0 $B0 $B0 $B0 $B0 $B9 $B14 $B13 $B0 $B0 $B0 $B0 $B2 $B0 $B0 $B0 $B0 $B0 $B0 $B5 $B4 $B0 $B0 $B0 $B0 $B0 $B0 $B0 $B0 $B0 $B0 $B0 $B0 $B0 $B0 $B0 $B6 $B0 $B0 $B0 $B0 $B0 $B0 $B0 $B0 $B10 $B0 $B0 $B0 $B0 $B0 $B0 $B0 $B0 $B0 $B12 $B11 $B0 $B0 $B0 $B0 $B0 $B0 $B0 $B0 $B3 $B12 + end + i32.const 2 + return + end + i32.const 3 + return + end + i32.const 1 + return + end + i32.const 8 + return + end + i32.const 5 + return + end + i32.const 4 + return + end + i32.const 7 + return + end + i32.const 6 + return + end + i32.const 0 + return + end + i32.const 15 + return + end + i32.const 11 + return + end + i32.const 13 + return + end + i32.const 9 + return + end + i32.const 10 + local.set $l1 + end + local.get $l1) + (func $f102 (type $t6) (param $p0 i32) (param $p1 i32) (param $p2 i32) (param $p3 i32) + (local $l4 i32) (local $l5 i32) (local $l6 i32) (local $l7 i64) + global.get $g0 + i32.const 32 + i32.sub + local.tee $l4 + global.set $g0 + block $B0 + block $B1 + local.get $p1 + i32.load offset=8 + local.get $p3 + i32.add + local.get $p1 + i32.load offset=4 + i32.le_u + br_if $B1 + local.get $l4 + i32.const 16 + i32.add + local.get $p1 + call $f79 + local.get $l4 + i32.load offset=20 + local.set $l5 + local.get $l4 + i32.load offset=16 + local.tee $l6 + i32.const 255 + i32.and + i32.const 3 + i32.ne + if $I2 + local.get $p0 + i32.const 1 + i32.store + local.get $p0 + local.get $l6 + i64.extend_i32_u + local.get $l5 + i64.extend_i32_u + i64.const 32 + i64.shl + i64.or + i64.store offset=4 align=4 + br $B0 + end + local.get $l6 + i32.const 3 + i32.and + i32.const 2 + i32.ne + br_if $B1 + local.get $l5 + i32.load + local.get $l5 + i32.load offset=4 + i32.load + call_indirect (type $t2) $T0 + local.get $l5 + i32.load offset=4 + local.tee $l6 + i32.load offset=4 + if $I3 + local.get $l6 + i32.load offset=8 + drop + local.get $l5 + i32.load + call $f145 + end + local.get $l5 + call $f145 + end + local.get $p1 + i32.load offset=4 + local.get $p3 + i32.gt_u + if $I4 + local.get $p1 + local.get $p3 + call $f71 + local.get $p1 + local.get $p1 + i32.load offset=8 + local.tee $l5 + local.get $p3 + i32.add + i32.store offset=8 + local.get $l5 + local.get $p1 + i32.load + i32.add + local.get $p2 + local.get $p3 + call $f162 + drop + local.get $p0 + i32.const 0 + i32.store + local.get $p0 + local.get $p3 + i32.store offset=4 + br $B0 + end + local.get $p1 + i32.const 1 + i32.store8 offset=13 + block $B5 (result i32) + local.get $p1 + i32.load8_u offset=12 + i32.const -1 + i32.add + local.tee $l5 + i32.const 1 + i32.le_u + if $I6 + local.get $l5 + i32.const 1 + i32.sub + i32.eqz + if $I7 + i32.const 1049576 + i32.const 43 + i32.const 1049516 + call $f172 + unreachable + end + local.get $p3 + i64.extend_i32_u + local.set $l7 + i32.const 0 + br $B5 + end + local.get $l4 + local.get $p3 + i32.store offset=12 + local.get $l4 + local.get $p2 + i32.store offset=8 + local.get $l4 + i32.const 16 + i32.add + i32.const 1 + local.get $l4 + i32.const 8 + i32.add + call $f142 + local.get $l4 + i32.load16_u offset=16 + i32.const 1 + i32.ne + if $I8 + local.get $l4 + i64.load32_u offset=20 + local.set $l7 + i32.const 0 + br $B5 + end + local.get $l4 + local.get $l4 + i32.load16_u offset=18 + i32.store16 offset=30 + local.get $p3 + i64.extend_i32_u + local.get $l4 + i32.const 30 + i32.add + i32.load16_u + local.tee $p2 + i64.extend_i32_u + i64.const 65535 + i64.and + i64.const 32 + i64.shl + local.get $p2 + i32.const 8 + i32.eq + select + local.set $l7 + local.get $p2 + i32.const 8 + i32.ne + end + local.set $p2 + local.get $p0 + local.get $l7 + i64.store offset=4 align=4 + local.get $p0 + local.get $p2 + i32.store + local.get $p1 + i32.const 0 + i32.store8 offset=13 + end + local.get $l4 + i32.const 32 + i32.add + global.set $g0) + (func $f103 (type $t6) (param $p0 i32) (param $p1 i32) (param $p2 i32) (param $p3 i32) + (local $l4 i32) (local $l5 i32) (local $l6 i32) (local $l7 i32) (local $l8 i32) (local $l9 i32) (local $l10 i64) + global.get $g0 + i32.const 32 + i32.sub + local.tee $l4 + global.set $g0 + block $B0 + block $B1 + local.get $p1 + i32.load8_u offset=16 + i32.eqz + br_if $B1 + local.get $l4 + i32.const 16 + i32.add + local.get $p1 + call $f79 + block $B2 + block $B3 + local.get $l4 + i32.load8_u offset=16 + i32.const 3 + i32.eq + if $I4 + local.get $p1 + i32.load8_u offset=12 + i32.const 2 + i32.ne + br_if $B3 + i32.const 1049576 + i32.const 43 + i32.const 1049516 + call $f172 + unreachable + end + local.get $l4 + i64.load offset=16 + local.tee $l10 + i64.const 255 + i64.and + i64.const 3 + i64.ne + br_if $B2 + end + local.get $p1 + i32.const 0 + i32.store8 offset=16 + br $B1 + end + local.get $l10 + i32.wrap_i64 + local.tee $l5 + i32.const 255 + i32.and + i32.const 3 + i32.ne + if $I5 + local.get $p0 + i32.const 1 + i32.store + local.get $p0 + local.get $l10 + i64.store offset=4 align=4 + br $B0 + end + local.get $l5 + i32.const 3 + i32.and + i32.const 2 + i32.ne + br_if $B1 + local.get $l10 + i64.const 32 + i64.shr_u + i32.wrap_i64 + local.tee $l5 + i32.load + local.get $l5 + i32.load offset=4 + i32.load + call_indirect (type $t2) $T0 + local.get $l5 + i32.load offset=4 + local.tee $l7 + i32.load offset=4 + if $I6 + local.get $l7 + i32.load offset=8 + drop + local.get $l5 + i32.load + call $f145 + end + local.get $l5 + call $f145 + end + local.get $l4 + i32.const 8 + i32.add + local.get $p2 + local.get $p3 + call $f194 + local.get $l4 + i32.load offset=8 + i32.eqz + if $I7 + local.get $p0 + local.get $p1 + local.get $p2 + local.get $p3 + call $f102 + br $B0 + end + block $B8 + local.get $l4 + i32.load offset=12 + local.tee $l5 + i32.const -1 + i32.ne + if $I9 + local.get $l5 + i32.const 1 + i32.add + local.set $l7 + local.get $l5 + local.get $p3 + i32.lt_u + br_if $B8 + local.get $l7 + local.get $p3 + call $f173 + unreachable + end + i32.const 1054816 + i32.const 44 + i32.const 1054860 + call $f172 + unreachable + end + local.get $l4 + i32.const 16 + i32.add + local.get $p1 + local.get $p2 + local.get $l7 + call $f102 + local.get $l4 + i32.const 24 + i32.add + i32.load + local.set $l6 + local.get $l4 + i32.load offset=20 + local.set $l5 + block $B10 + local.get $l4 + i32.load offset=16 + local.tee $l8 + i32.const 1 + i32.le_u + if $I11 + local.get $l8 + i32.const 1 + i32.sub + br_if $B10 + local.get $p0 + i32.const 1 + i32.store + local.get $p0 + local.get $l5 + i64.extend_i32_u + local.get $l6 + i64.extend_i32_u + i64.const 32 + i64.shl + i64.or + i64.store offset=4 align=4 + br $B0 + end + local.get $l5 + i32.const 255 + i32.and + i32.const 2 + i32.lt_u + br_if $B10 + local.get $l6 + i32.load + local.get $l6 + i32.load offset=4 + i32.load + call_indirect (type $t2) $T0 + local.get $l6 + i32.load offset=4 + local.tee $l8 + i32.load offset=4 + if $I12 + local.get $l8 + i32.load offset=8 + drop + local.get $l6 + i32.load + call $f145 + end + local.get $l6 + call $f145 + end + local.get $p1 + i32.const 1 + i32.store8 offset=16 + local.get $l4 + i32.const 16 + i32.add + local.get $p1 + call $f79 + block $B13 + block $B14 + block $B15 + block $B16 + local.get $l4 + i32.load8_u offset=16 + i32.const 3 + i32.eq + if $I17 + local.get $p1 + i32.load8_u offset=12 + i32.const 2 + i32.ne + br_if $B16 + i32.const 1049576 + i32.const 43 + i32.const 1049516 + call $f172 + unreachable + end + local.get $l4 + i64.load8_u offset=16 + i64.const 3 + i64.ne + br_if $B15 + end + local.get $p1 + i32.const 0 + i32.store8 offset=16 + local.get $l5 + local.get $l7 + i32.eq + br_if $B14 + br $B13 + end + local.get $l4 + i32.load offset=20 + local.set $l6 + local.get $l5 + local.get $l7 + i32.ne + local.get $l4 + i32.load offset=16 + local.tee $l8 + i32.const 255 + i32.and + i32.const 3 + i32.ne + i32.or + local.get $l8 + i32.const 3 + i32.and + i32.const 2 + i32.eq + if $I18 + local.get $l6 + i32.load + local.get $l6 + i32.load offset=4 + i32.load + call_indirect (type $t2) $T0 + local.get $l6 + i32.load offset=4 + local.tee $l8 + i32.load offset=4 + if $I19 + local.get $l8 + i32.load offset=8 + drop + local.get $l6 + i32.load + call $f145 + end + local.get $l6 + call $f145 + end + br_if $B13 + end + local.get $l4 + i32.const 16 + i32.add + local.get $p1 + local.get $p2 + local.get $l7 + i32.add + local.get $p3 + local.get $l7 + i32.sub + call $f102 + local.get $l4 + i32.load offset=16 + i32.const 1 + i32.ne + if $I20 + local.get $p0 + i32.const 0 + i32.store + local.get $p0 + local.get $l4 + i32.load offset=20 + local.get $l5 + i32.add + i32.store offset=4 + br $B0 + end + local.get $p0 + i32.const 0 + i32.store + local.get $p0 + local.get $l5 + i32.store offset=4 + local.get $l4 + i32.load8_u offset=20 + i32.const 2 + i32.lt_u + br_if $B0 + local.get $l4 + i32.const 24 + i32.add + i32.load + local.tee $p0 + i32.load + local.get $p0 + i32.load offset=4 + i32.load + call_indirect (type $t2) $T0 + local.get $p0 + i32.load offset=4 + local.tee $p1 + i32.load offset=4 + if $I21 + local.get $p1 + i32.load offset=8 + drop + local.get $p0 + i32.load + call $f145 + end + local.get $p0 + call $f145 + br $B0 + end + local.get $p0 + i32.const 0 + i32.store + local.get $p0 + local.get $l5 + i32.store offset=4 + end + local.get $l4 + i32.const 32 + i32.add + global.set $g0) + (func $f104 (type $t3) (param $p0 i32) (param $p1 i32) + (local $l2 i32) (local $l3 i32) (local $l4 i32) (local $l5 i32) + global.get $g0 + i32.const 1056 + i32.sub + local.tee $l2 + global.set $g0 + local.get $l2 + i32.const 8 + i32.add + i32.const 1024 + call $f166 + drop + block $B0 + block $B1 + block $B2 + block $B3 + local.get $p1 + local.get $l2 + i32.const 8 + i32.add + call $f165 + i32.const 0 + i32.ge_s + if $I4 + local.get $l2 + i32.load8_u offset=8 + if $I5 + local.get $l2 + i32.const 9 + i32.add + local.set $l4 + i32.const 0 + local.set $p1 + loop $L6 + local.get $p1 + local.get $l4 + i32.add + local.get $p1 + i32.const 1 + i32.add + local.tee $l3 + local.set $p1 + i32.load8_u + br_if $L6 + end + local.get $l3 + i32.const -1 + i32.eq + br_if $B3 + end + local.get $l2 + i32.const 1032 + i32.add + local.get $l2 + i32.const 8 + i32.add + local.get $l3 + call $f201 + local.get $l2 + i32.load offset=1032 + i32.const 1 + i32.eq + br_if $B2 + local.get $l2 + i32.const 1040 + i32.add + i32.load + local.tee $p1 + i32.const -1 + i32.le_s + br_if $B1 + local.get $l2 + i32.load offset=1036 + local.set $l4 + block $B7 + local.get $p1 + i32.eqz + if $I8 + i32.const 1 + local.set $l3 + br $B7 + end + local.get $p1 + i32.const 1 + call $f36 + local.tee $l3 + i32.eqz + br_if $B0 + end + local.get $l3 + local.get $l4 + local.get $p1 + call $f162 + local.set $l3 + local.get $p0 + local.get $p1 + i32.store offset=8 + local.get $p0 + local.get $p1 + i32.store offset=4 + local.get $p0 + local.get $l3 + i32.store + local.get $l2 + i32.const 1056 + i32.add + global.set $g0 + return + end + i32.const 1052516 + i32.const 18 + i32.const 1052500 + call $f55 + unreachable + end + local.get $l3 + i32.const 0 + call $f173 + unreachable + end + local.get $l2 + local.get $l2 + i64.load offset=1036 align=4 + i64.store offset=1048 + i32.const 1049668 + i32.const 43 + local.get $l2 + i32.const 1048 + i32.add + i32.const 1049712 + call $f192 + unreachable + end + call $f12 + unreachable + end + local.get $p1 + i32.const 1 + call $f168 + unreachable) + (func $f105 (type $t6) (param $p0 i32) (param $p1 i32) (param $p2 i32) (param $p3 i32) + local.get $p0 + local.get $p1 + i32.load + local.get $p2 + local.get $p3 + local.get $p1 + i32.load offset=4 + i32.load offset=12 + call_indirect (type $t6) $T0) + (func $f106 (type $t6) (param $p0 i32) (param $p1 i32) (param $p2 i32) (param $p3 i32) + local.get $p0 + local.get $p1 + i32.load + local.get $p2 + local.get $p3 + local.get $p1 + i32.load offset=4 + i32.load offset=16 + call_indirect (type $t6) $T0) + (func $f107 (type $t3) (param $p0 i32) (param $p1 i32) + local.get $p0 + local.get $p1 + i32.load + local.get $p1 + i32.load offset=4 + i32.load offset=20 + call_indirect (type $t3) $T0) + (func $f108 (type $t6) (param $p0 i32) (param $p1 i32) (param $p2 i32) (param $p3 i32) + local.get $p0 + local.get $p1 + i32.load + local.get $p2 + local.get $p3 + local.get $p1 + i32.load offset=4 + i32.load offset=24 + call_indirect (type $t6) $T0) + (func $f109 (type $t4) (param $p0 i32) (param $p1 i32) (param $p2 i32) + (local $l3 i32) (local $l4 i32) + global.get $g0 + i32.const 32 + i32.sub + local.tee $l3 + global.set $g0 + local.get $p1 + i32.load + local.set $l4 + local.get $p1 + i32.load offset=4 + local.set $p1 + local.get $l3 + i32.const 24 + i32.add + local.get $p2 + i32.const 16 + i32.add + i64.load align=4 + i64.store + local.get $l3 + i32.const 16 + i32.add + local.get $p2 + i32.const 8 + i32.add + i64.load align=4 + i64.store + local.get $l3 + local.get $p2 + i64.load align=4 + i64.store offset=8 + local.get $p0 + local.get $l4 + local.get $l3 + i32.const 8 + i32.add + local.get $p1 + i32.load offset=28 + call_indirect (type $t4) $T0 + local.get $l3 + i32.const 32 + i32.add + global.set $g0) + (func $f110 (type $t6) (param $p0 i32) (param $p1 i32) (param $p2 i32) (param $p3 i32) + global.get $g0 + i32.const 32 + i32.sub + local.tee $p1 + global.set $g0 + local.get $p1 + local.get $p3 + i32.store offset=12 + local.get $p1 + local.get $p2 + i32.store offset=8 + i32.const 1 + local.set $p2 + local.get $p1 + i32.const 16 + i32.add + i32.const 2 + local.get $p1 + i32.const 8 + i32.add + call $f142 + block $B0 + local.get $p1 + i32.load16_u offset=16 + i32.const 1 + i32.ne + if $I1 + local.get $p0 + local.get $p1 + i32.load offset=20 + i32.store offset=4 + i32.const 0 + local.set $p2 + br $B0 + end + local.get $p1 + local.get $p1 + i32.load16_u offset=18 + i32.store16 offset=30 + local.get $p0 + local.get $p1 + i32.const 30 + i32.add + i32.load16_u + i64.extend_i32_u + i64.const 65535 + i64.and + i64.const 32 + i64.shl + i64.store offset=4 align=4 + end + local.get $p0 + local.get $p2 + i32.store + local.get $p1 + i32.const 32 + i32.add + global.set $g0) + (func $f111 (type $t5) (param $p0 i32) (result i32) + (local $l1 i32) (local $l2 i32) (local $l3 i32) (local $l4 i32) (local $l5 i32) (local $l6 i32) + block $B0 + block $B1 + block $B2 + block $B3 + i32.const 1060577 + i32.load8_u + i32.eqz + if $I4 + i32.const 1060577 + i32.const 1 + i32.store8 + block $B5 + i32.const 1060496 + i32.load + local.tee $l1 + i32.const 1 + i32.le_u + if $I6 + local.get $l1 + i32.const 1 + i32.sub + i32.eqz + br_if $B5 + i32.const 12 + i32.const 4 + call $f36 + local.tee $l1 + i32.eqz + br_if $B3 + local.get $l1 + i32.const 0 + i32.store offset=8 + local.get $l1 + i64.const 4 + i64.store align=4 + i32.const 1060496 + local.get $l1 + i32.store + end + block $B7 + local.get $l1 + i32.load offset=8 + local.tee $l2 + local.get $l1 + i32.load offset=4 + i32.ne + if $I8 + local.get $l1 + i32.load + local.set $l3 + br $B7 + end + local.get $l2 + i32.const 1 + i32.add + local.tee $l4 + local.get $l2 + i32.lt_u + br_if $B1 + local.get $l2 + i32.const 1 + i32.shl + local.tee $l3 + local.get $l4 + local.get $l3 + local.get $l4 + i32.gt_u + select + local.tee $l4 + i32.const 536870911 + i32.and + local.tee $l3 + local.get $l4 + i32.ne + br_if $B1 + local.get $l4 + i32.const 3 + i32.shl + local.tee $l5 + i32.const 0 + i32.lt_s + br_if $B1 + local.get $l3 + local.get $l4 + i32.eq + i32.const 2 + i32.shl + local.set $l6 + block $B9 (result i32) + local.get $l2 + i32.eqz + if $I10 + local.get $l5 + local.get $l6 + call $f36 + br $B9 + end + local.get $l1 + i32.load + local.get $l2 + i32.const 3 + i32.shl + i32.const 4 + local.get $l5 + call $f37 + end + local.tee $l3 + i32.eqz + br_if $B2 + local.get $l1 + local.get $l4 + i32.store offset=4 + local.get $l1 + local.get $l3 + i32.store + local.get $l1 + i32.load offset=8 + local.set $l2 + end + local.get $l3 + local.get $l2 + i32.const 3 + i32.shl + i32.add + local.tee $l2 + i32.const 1051724 + i32.store offset=4 + local.get $l2 + local.get $p0 + i32.store + i32.const 1 + local.set $l2 + local.get $l1 + local.get $l1 + i32.load offset=8 + i32.const 1 + i32.add + i32.store offset=8 + i32.const 1060577 + i32.const 0 + i32.store8 + br $B0 + end + i32.const 1060577 + i32.const 0 + i32.store8 + local.get $p0 + i32.const 1051724 + i32.load + call_indirect (type $t2) $T0 + i32.const 1051728 + i32.load + i32.eqz + br_if $B0 + i32.const 1051732 + i32.load + drop + local.get $p0 + call $f145 + i32.const 0 + return + end + i32.const 1052440 + i32.const 32 + i32.const 1052424 + call $f55 + unreachable + end + i32.const 12 + i32.const 4 + call $f168 + unreachable + end + local.get $l5 + local.get $l6 + call $f168 + unreachable + end + call $f169 + unreachable + end + local.get $l2) + (func $f112 (type $t10) (result i32) + (local $l0 i32) (local $l1 i32) (local $l2 i32) (local $l3 i32) (local $l4 i32) + global.get $g0 + i32.const 16 + i32.sub + local.tee $l1 + global.set $g0 + block $B0 + block $B1 + block $B2 + block $B3 + block $B4 + i32.const 1060492 + i32.load8_u + i32.eqz + if $I5 + i32.const 1060492 + i32.const 1 + i32.store8 + block $B6 + i32.const 1060488 + i32.load + local.tee $l0 + i32.const 1 + i32.le_u + if $I7 + local.get $l0 + i32.const 1 + i32.sub + i32.eqz + if $I8 + i32.const 1060492 + i32.const 0 + i32.store8 + call $f190 + unreachable + end + i32.const 4 + i32.const 4 + call $f36 + local.tee $l0 + i32.eqz + br_if $B4 + local.get $l0 + i32.const 1060488 + i32.store + local.get $l0 + call $f111 + i32.const 1024 + i32.const 1 + call $f36 + local.tee $l3 + i32.eqz + br_if $B3 + local.get $l1 + i32.const 12 + i32.add + local.tee $l4 + local.get $l1 + i32.const 15 + i32.add + i32.load8_u + i32.store8 + local.get $l1 + local.get $l1 + i32.load16_u offset=13 align=1 + i32.store16 offset=10 + i32.const 40 + i32.const 4 + call $f36 + local.tee $l0 + i32.eqz + br_if $B2 + local.get $l0 + i32.const 0 + i32.store8 offset=32 + local.get $l0 + i32.const 0 + i32.store16 offset=28 + local.get $l0 + i64.const 1024 + i64.store offset=20 align=4 + local.get $l0 + local.get $l3 + i32.store offset=16 + local.get $l0 + i64.const 1 + i64.store offset=8 align=4 + local.get $l0 + i64.const 4294967297 + i64.store align=4 + local.get $l0 + local.get $l1 + i32.load16_u offset=10 + i32.store16 offset=33 align=1 + local.get $l0 + i32.const 0 + i32.store8 offset=36 + local.get $l0 + local.get $l1 + i32.load16_u offset=7 align=1 + i32.store16 offset=37 align=1 + local.get $l0 + i32.const 35 + i32.add + local.get $l4 + i32.load8_u + i32.store8 + local.get $l0 + i32.const 39 + i32.add + local.get $l1 + i32.const 9 + i32.add + i32.load8_u + i32.store8 + i32.eqz + br_if $B6 + local.get $l0 + local.get $l0 + i32.load + local.tee $l2 + i32.const 1 + i32.add + i32.store + local.get $l2 + i32.const -1 + i32.le_s + br_if $B1 + i32.const 4 + i32.const 4 + call $f36 + local.tee $l2 + i32.eqz + br_if $B0 + i32.const 1060488 + local.get $l2 + i32.store + local.get $l2 + local.get $l0 + i32.store + br $B6 + end + local.get $l0 + i32.load + local.tee $l0 + local.get $l0 + i32.load + local.tee $l2 + i32.const 1 + i32.add + i32.store + local.get $l2 + i32.const -1 + i32.le_s + br_if $B1 + end + i32.const 1060492 + i32.const 0 + i32.store8 + local.get $l1 + i32.const 16 + i32.add + global.set $g0 + local.get $l0 + return + end + i32.const 1052440 + i32.const 32 + i32.const 1052424 + call $f55 + unreachable + end + i32.const 4 + i32.const 4 + call $f168 + unreachable + end + i32.const 1024 + i32.const 1 + call $f168 + unreachable + end + i32.const 40 + i32.const 4 + call $f168 + unreachable + end + unreachable + end + i32.const 4 + i32.const 4 + call $f168 + unreachable) + (func $f113 (type $t4) (param $p0 i32) (param $p1 i32) (param $p2 i32) + (local $l3 i32) (local $l4 i32) + global.get $g0 + i32.const 48 + i32.sub + local.tee $l3 + global.set $g0 + local.get $p1 + i32.load + local.set $p1 + block $B0 + i32.const 1060568 + i32.load + i32.const 1 + i32.eq + if $I1 + i32.const 1060572 + i32.load + local.set $l4 + br $B0 + end + i32.const 1060568 + i64.const 1 + i64.store + end + i32.const 1060572 + local.get $l4 + i32.store + local.get $l3 + local.get $l4 + i32.const 0 + i32.ne + i32.store8 offset=4 + local.get $l3 + local.get $p1 + i32.const 8 + i32.add + i32.store + local.get $l3 + i32.const 3 + i32.store8 offset=12 + local.get $l3 + local.get $l3 + i32.store offset=8 + local.get $l3 + i32.const 40 + i32.add + local.get $p2 + i32.const 16 + i32.add + i64.load align=4 + i64.store + local.get $l3 + i32.const 32 + i32.add + local.get $p2 + i32.const 8 + i32.add + i64.load align=4 + i64.store + local.get $l3 + local.get $p2 + i64.load align=4 + i64.store offset=24 + block $B2 + block $B3 + block $B4 + block $B5 + local.get $l3 + i32.const 8 + i32.add + i32.const 1050964 + local.get $l3 + i32.const 24 + i32.add + call $f179 + if $I6 + local.get $l3 + i32.load8_u offset=12 + i32.const 3 + i32.eq + if $I7 + i32.const 15 + i32.const 1 + call $f36 + local.tee $p1 + i32.eqz + br_if $B4 + local.get $p1 + i32.const 7 + i32.add + i32.const 1050953 + i64.load align=1 + i64.store align=1 + local.get $p1 + i32.const 1050946 + i64.load align=1 + i64.store align=1 + i32.const 12 + i32.const 4 + call $f36 + local.tee $p2 + i32.eqz + br_if $B3 + local.get $p2 + i64.const 64424509455 + i64.store offset=4 align=4 + local.get $p2 + local.get $p1 + i32.store + i32.const 12 + i32.const 4 + call $f36 + local.tee $p1 + i32.eqz + br_if $B2 + local.get $p1 + i32.const 16 + i32.store8 offset=8 + local.get $p1 + i32.const 1050348 + i32.store offset=4 + local.get $p1 + local.get $p2 + i32.store + local.get $p1 + local.get $l3 + i32.load16_u offset=24 align=1 + i32.store16 offset=9 align=1 + local.get $p1 + i32.const 11 + i32.add + local.get $l3 + i32.const 26 + i32.add + i32.load8_u + i32.store8 + local.get $p0 + i32.const 4 + i32.add + local.get $p1 + i32.store + local.get $p0 + i32.const 2 + i32.store + br $B5 + end + local.get $p0 + local.get $l3 + i64.load offset=12 align=4 + i64.store align=4 + br $B5 + end + local.get $p0 + i32.const 3 + i32.store8 + local.get $l3 + i32.load8_u offset=12 + i32.const 2 + i32.ne + br_if $B5 + local.get $l3 + i32.const 16 + i32.add + i32.load + local.tee $p0 + i32.load + local.get $p0 + i32.load offset=4 + i32.load + call_indirect (type $t2) $T0 + local.get $p0 + i32.load offset=4 + local.tee $p1 + i32.load offset=4 + if $I8 + local.get $p1 + i32.load offset=8 + drop + local.get $p0 + i32.load + call $f145 + end + local.get $l3 + i32.load offset=16 + call $f145 + end + block $B9 + local.get $l3 + i32.load8_u offset=4 + br_if $B9 + i32.const 1060568 + i32.load + i32.const 1 + i32.ne + if $I10 + i32.const 1060568 + i64.const 1 + i64.store + br $B9 + end + i32.const 1060572 + i32.load + i32.eqz + br_if $B9 + local.get $l3 + i32.load + i32.const 1 + i32.store8 offset=28 + end + local.get $l3 + i32.const 48 + i32.add + global.set $g0 + return + end + i32.const 15 + i32.const 1 + call $f168 + unreachable + end + i32.const 12 + i32.const 4 + call $f168 + unreachable + end + i32.const 12 + i32.const 4 + call $f168 + unreachable) + (func $f114 (type $t4) (param $p0 i32) (param $p1 i32) (param $p2 i32) + (local $l3 i32) (local $l4 i32) (local $l5 i32) + global.get $g0 + i32.const 16 + i32.sub + local.tee $l3 + global.set $g0 + block $B0 + block $B1 + i32.const 1060540 + i32.load + i32.const 1 + i32.ne + if $I2 + i32.const 1060540 + i64.const 1 + i64.store align=4 + i32.const 1060548 + i32.const 0 + i32.store + br $B1 + end + i32.const 1060544 + i32.load + br_if $B0 + i32.const 1060548 + i32.load + local.set $l4 + end + i32.const 1060548 + local.get $p1 + i32.store + i32.const 1060552 + i32.load + local.set $l5 + i32.const 1060552 + local.get $p2 + i32.store + i32.const 1060544 + i32.const 0 + i32.store + block $B3 + local.get $l4 + i32.eqz + br_if $B3 + local.get $l3 + local.get $l4 + local.get $l5 + i32.load offset=20 + call_indirect (type $t3) $T0 + local.get $l3 + i32.load8_u + i32.const 2 + i32.ne + br_if $B3 + local.get $l3 + i32.load offset=4 + local.tee $p1 + i32.load + local.get $p1 + i32.load offset=4 + i32.load + call_indirect (type $t2) $T0 + local.get $p1 + i32.load offset=4 + local.tee $p2 + i32.load offset=4 + if $I4 + local.get $p2 + i32.load offset=8 + drop + local.get $p1 + i32.load + call $f145 + end + local.get $p1 + call $f145 + end + local.get $p0 + local.get $l4 + i32.store + local.get $p0 + local.get $l5 + i32.store offset=4 + local.get $l3 + i32.const 16 + i32.add + global.set $g0 + return + end + i32.const 1049320 + i32.const 16 + local.get $l3 + i32.const 8 + i32.add + i32.const 1049620 + call $f192 + unreachable) + (func $f115 (type $t2) (param $p0 i32) + (local $l1 i32) (local $l2 i32) (local $l3 i32) + global.get $g0 + i32.const 96 + i32.sub + local.tee $l1 + global.set $g0 + local.get $l1 + i32.const 24 + i32.add + local.get $p0 + i32.const 16 + i32.add + i64.load align=4 + i64.store + local.get $l1 + i32.const 16 + i32.add + local.get $p0 + i32.const 8 + i32.add + i64.load align=4 + i64.store + local.get $l1 + local.get $p0 + i64.load align=4 + i64.store offset=8 + local.get $l1 + i32.const 6 + i32.store offset=36 + local.get $l1 + i32.const 1050912 + i32.store offset=32 + block $B0 + block $B1 + block $B2 + i32.const 1060524 + i32.load + i32.const 1 + i32.ne + if $I3 + i32.const 1060524 + i64.const -4294967295 + i64.store align=4 + i32.const 1060532 + i32.const 0 + i32.store + local.get $l1 + i32.const 56 + i32.add + local.set $l2 + br $B2 + end + local.get $l1 + i32.const 56 + i32.add + local.set $l2 + i32.const 1060528 + i32.load + br_if $B1 + i32.const 1060528 + i32.const -1 + i32.store + local.get $l1 + i32.const 56 + i32.add + local.set $l2 + i32.const 1060532 + i32.load + local.tee $p0 + i32.eqz + br_if $B2 + i32.const 1060536 + i32.load + local.set $l3 + local.get $l1 + i32.const 88 + i32.add + local.get $l1 + i32.const 24 + i32.add + i64.load + i64.store + local.get $l1 + i32.const 80 + i32.add + local.get $l1 + i32.const 16 + i32.add + i64.load + i64.store + local.get $l1 + local.get $l1 + i64.load offset=8 + i64.store offset=72 + local.get $l1 + i32.const 56 + i32.add + local.get $p0 + local.get $l1 + i32.const 72 + i32.add + local.get $l3 + i32.load offset=28 + call_indirect (type $t4) $T0 + i32.const 1060528 + i32.const 1060528 + i32.load + i32.const 1 + i32.add + i32.store + br $B0 + end + i32.const 1060528 + i32.const 0 + i32.store + end + local.get $l1 + call $f112 + local.tee $p0 + i32.store offset=48 + local.get $l1 + i32.const 88 + i32.add + local.get $l1 + i32.const 24 + i32.add + i64.load + i64.store + local.get $l1 + i32.const 80 + i32.add + local.get $l1 + i32.const 16 + i32.add + i64.load + i64.store + local.get $l1 + local.get $l1 + i64.load offset=8 + i64.store offset=72 + local.get $l2 + local.get $l1 + i32.const 48 + i32.add + local.get $l1 + i32.const 72 + i32.add + call $f113 + local.get $p0 + local.get $p0 + i32.load + local.tee $p0 + i32.const -1 + i32.add + i32.store + local.get $p0 + i32.const 1 + i32.eq + if $I4 + local.get $l1 + i32.const 48 + i32.add + call $f57 + end + local.get $l1 + i32.const 56 + i32.add + local.set $l2 + end + block $B5 + local.get $l1 + i32.load offset=56 + local.tee $p0 + i32.const 255 + i32.and + i32.const 4 + i32.ne + if $I6 + local.get $l1 + local.get $l2 + i32.load offset=4 + i32.store offset=44 + local.get $l1 + local.get $p0 + i32.store offset=40 + br $B5 + end + local.get $l1 + call $f112 + local.tee $p0 + i32.store offset=56 + local.get $l1 + i32.const 88 + i32.add + local.get $l1 + i32.const 24 + i32.add + i64.load + i64.store + local.get $l1 + i32.const 80 + i32.add + local.get $l1 + i32.const 16 + i32.add + i64.load + i64.store + local.get $l1 + local.get $l1 + i64.load offset=8 + i64.store offset=72 + local.get $l1 + i32.const 40 + i32.add + local.get $l1 + i32.const 56 + i32.add + local.get $l1 + i32.const 72 + i32.add + call $f113 + local.get $p0 + local.get $p0 + i32.load + local.tee $p0 + i32.const -1 + i32.add + i32.store + local.get $p0 + i32.const 1 + i32.eq + if $I7 + local.get $l1 + i32.const 56 + i32.add + call $f57 + end + local.get $l1 + i32.load8_u offset=40 + local.set $p0 + end + local.get $p0 + i32.const 255 + i32.and + i32.const 3 + i32.eq + if $I8 + local.get $p0 + i32.const 3 + i32.and + i32.const 2 + i32.eq + if $I9 + local.get $l1 + i32.load offset=44 + local.tee $p0 + i32.load + local.get $p0 + i32.load offset=4 + i32.load + call_indirect (type $t2) $T0 + local.get $p0 + i32.load offset=4 + local.tee $l2 + i32.load offset=4 + if $I10 + local.get $l2 + i32.load offset=8 + drop + local.get $p0 + i32.load + call $f145 + end + local.get $p0 + call $f145 + end + local.get $l1 + i32.const 96 + i32.add + global.set $g0 + return + end + local.get $l1 + local.get $l1 + i64.load offset=40 + i64.store offset=48 + local.get $l1 + i32.const 92 + i32.add + i32.const 2 + i32.store + local.get $l1 + i32.const 68 + i32.add + i32.const 15 + i32.store + local.get $l1 + i64.const 2 + i64.store offset=76 align=4 + local.get $l1 + i32.const 1050856 + i32.store offset=72 + local.get $l1 + i32.const 19 + i32.store offset=60 + local.get $l1 + local.get $l1 + i32.const 56 + i32.add + i32.store offset=88 + local.get $l1 + local.get $l1 + i32.const 48 + i32.add + i32.store offset=64 + local.get $l1 + local.get $l1 + i32.const 32 + i32.add + i32.store offset=56 + local.get $l1 + i32.const 72 + i32.add + i32.const 1050896 + call $f84 + unreachable) + (func $f116 (type $t6) (param $p0 i32) (param $p1 i32) (param $p2 i32) (param $p3 i32) + (local $l4 i32) (local $l5 i32) + global.get $g0 + i32.const 32 + i32.sub + local.tee $p1 + global.set $g0 + local.get $p3 + i32.const 3 + i32.shl + local.set $p3 + local.get $p2 + i32.const -8 + i32.add + local.set $l4 + block $B0 (result i32) + loop $L1 + local.get $p3 + i32.eqz + if $I2 + i32.const 0 + local.set $l5 + i32.const 1 + br $B0 + end + local.get $p3 + i32.const -8 + i32.add + local.set $p3 + local.get $l4 + i32.const 8 + i32.add + local.set $l4 + local.get $p2 + i32.load offset=4 + local.set $l5 + local.get $p2 + i32.const 8 + i32.add + local.set $p2 + local.get $l5 + i32.eqz + br_if $L1 + end + local.get $l4 + i32.load + end + local.set $p2 + local.get $p1 + local.get $l5 + i32.store offset=12 + local.get $p1 + local.get $p2 + i32.store offset=8 + local.get $p1 + i32.const 16 + i32.add + i32.const 2 + local.get $p1 + i32.const 8 + i32.add + call $f142 + local.get $p0 + block $B3 (result i32) + local.get $p1 + i32.load16_u offset=16 + i32.const 1 + i32.ne + if $I4 + local.get $p0 + local.get $p1 + i32.load offset=20 + i32.store offset=4 + i32.const 0 + br $B3 + end + local.get $p1 + local.get $p1 + i32.load16_u offset=18 + i32.store16 offset=30 + local.get $p0 + local.get $p1 + i32.const 30 + i32.add + i32.load16_u + i64.extend_i32_u + i64.const 65535 + i64.and + i64.const 32 + i64.shl + i64.store offset=4 align=4 + i32.const 1 + end + i32.store + local.get $p1 + i32.const 32 + i32.add + global.set $g0) + (func $f117 (type $t4) (param $p0 i32) (param $p1 i32) (param $p2 i32) + (local $l3 i32) + global.get $g0 + i32.const 48 + i32.sub + local.tee $l3 + global.set $g0 + local.get $l3 + i32.const 3 + i32.store8 offset=12 + local.get $l3 + local.get $p1 + i32.store offset=8 + local.get $l3 + i32.const 40 + i32.add + local.get $p2 + i32.const 16 + i32.add + i64.load align=4 + i64.store + local.get $l3 + i32.const 32 + i32.add + local.get $p2 + i32.const 8 + i32.add + i64.load align=4 + i64.store + local.get $l3 + local.get $p2 + i64.load align=4 + i64.store offset=24 + block $B0 + block $B1 + block $B2 + block $B3 + local.get $l3 + i32.const 8 + i32.add + i32.const 1050988 + local.get $l3 + i32.const 24 + i32.add + call $f179 + if $I4 + local.get $l3 + i32.load8_u offset=12 + i32.const 3 + i32.eq + if $I5 + i32.const 15 + i32.const 1 + call $f36 + local.tee $p1 + i32.eqz + br_if $B3 + local.get $p1 + i32.const 7 + i32.add + i32.const 1050953 + i64.load align=1 + i64.store align=1 + local.get $p1 + i32.const 1050946 + i64.load align=1 + i64.store align=1 + i32.const 12 + i32.const 4 + call $f36 + local.tee $p2 + i32.eqz + br_if $B2 + local.get $p2 + i64.const 64424509455 + i64.store offset=4 align=4 + local.get $p2 + local.get $p1 + i32.store + i32.const 12 + i32.const 4 + call $f36 + local.tee $p1 + i32.eqz + br_if $B1 + local.get $p1 + i32.const 16 + i32.store8 offset=8 + local.get $p1 + i32.const 1050348 + i32.store offset=4 + local.get $p1 + local.get $p2 + i32.store + local.get $p1 + local.get $l3 + i32.load16_u offset=24 align=1 + i32.store16 offset=9 align=1 + local.get $p1 + i32.const 11 + i32.add + local.get $l3 + i32.const 26 + i32.add + i32.load8_u + i32.store8 + local.get $p0 + i32.const 4 + i32.add + local.get $p1 + i32.store + local.get $p0 + i32.const 2 + i32.store + br $B0 + end + local.get $p0 + local.get $l3 + i64.load offset=12 align=4 + i64.store align=4 + br $B0 + end + local.get $p0 + i32.const 3 + i32.store8 + local.get $l3 + i32.load8_u offset=12 + i32.const 2 + i32.ne + br_if $B0 + local.get $l3 + i32.const 16 + i32.add + i32.load + local.tee $p0 + i32.load + local.get $p0 + i32.load offset=4 + i32.load + call_indirect (type $t2) $T0 + local.get $p0 + i32.load offset=4 + local.tee $p1 + i32.load offset=4 + if $I6 + local.get $p1 + i32.load offset=8 + drop + local.get $p0 + i32.load + call $f145 + end + local.get $l3 + i32.load offset=16 + call $f145 + br $B0 + end + i32.const 15 + i32.const 1 + call $f168 + unreachable + end + i32.const 12 + i32.const 4 + call $f168 + unreachable + end + i32.const 12 + i32.const 4 + call $f168 + unreachable + end + local.get $l3 + i32.const 48 + i32.add + global.set $g0) + (func $f118 (type $t1) (param $p0 i32) (param $p1 i32) (param $p2 i32) (result i32) + (local $l3 i32) (local $l4 i64) + global.get $g0 + i32.const 16 + i32.sub + local.tee $l3 + global.set $g0 + local.get $l3 + i32.const 8 + i32.add + local.get $p0 + i32.load + local.get $p1 + local.get $p2 + call $f51 + i32.const 0 + local.set $p1 + local.get $l3 + i32.load8_u offset=8 + i32.const 3 + i32.ne + if $I0 + local.get $l3 + i64.load offset=8 + local.set $l4 + local.get $p0 + i32.load8_u offset=4 + i32.const 2 + i32.eq + if $I1 + local.get $p0 + i32.const 8 + i32.add + i32.load + local.tee $p1 + i32.load + local.get $p1 + i32.load offset=4 + i32.load + call_indirect (type $t2) $T0 + local.get $p1 + i32.load offset=4 + local.tee $p2 + i32.load offset=4 + if $I2 + local.get $p2 + i32.load offset=8 + drop + local.get $p1 + i32.load + call $f145 + end + local.get $p0 + i32.load offset=8 + call $f145 + end + local.get $p0 + local.get $l4 + i64.store offset=4 align=4 + i32.const 1 + local.set $p1 + end + local.get $l3 + i32.const 16 + i32.add + global.set $g0 + local.get $p1) + (func $f119 (type $t1) (param $p0 i32) (param $p1 i32) (param $p2 i32) (result i32) + (local $l3 i32) (local $l4 i64) + global.get $g0 + i32.const 16 + i32.sub + local.tee $l3 + global.set $g0 + local.get $l3 + i32.const 8 + i32.add + local.get $p0 + i32.load + local.get $p1 + local.get $p2 + call $f49 + i32.const 0 + local.set $p1 + local.get $l3 + i32.load8_u offset=8 + i32.const 3 + i32.ne + if $I0 + local.get $l3 + i64.load offset=8 + local.set $l4 + local.get $p0 + i32.load8_u offset=4 + i32.const 2 + i32.eq + if $I1 + local.get $p0 + i32.const 8 + i32.add + i32.load + local.tee $p1 + i32.load + local.get $p1 + i32.load offset=4 + i32.load + call_indirect (type $t2) $T0 + local.get $p1 + i32.load offset=4 + local.tee $p2 + i32.load offset=4 + if $I2 + local.get $p2 + i32.load offset=8 + drop + local.get $p1 + i32.load + call $f145 + end + local.get $p0 + i32.load offset=8 + call $f145 + end + local.get $p0 + local.get $l4 + i64.store offset=4 align=4 + i32.const 1 + local.set $p1 + end + local.get $l3 + i32.const 16 + i32.add + global.set $g0 + local.get $p1) + (func $f120 (type $t3) (param $p0 i32) (param $p1 i32) + local.get $p0 + i32.const 3 + i32.store8) + (func $f121 (type $t2) (param $p0 i32) + (local $l1 i32) (local $l2 i32) (local $l3 i32) (local $l4 i32) (local $l5 i32) + global.get $g0 + i32.const 16 + i32.sub + local.tee $l3 + global.set $g0 + local.get $l3 + i32.const 2 + i32.or + local.set $l4 + i32.const 1060504 + i32.load + local.set $l1 + loop $L0 + block $B1 + block $B2 + block $B3 + block $B4 + block $B5 + local.get $l1 + local.tee $l2 + i32.const 3 + i32.gt_u + br_if $B5 + block $B6 + block $B7 + local.get $l2 + i32.const 1 + i32.sub + br_table $B4 $B5 $B6 $B7 + end + i32.const 1060504 + i32.const 2 + i32.const 1060504 + i32.load + local.tee $l1 + local.get $l1 + local.get $l2 + i32.eq + select + i32.store + local.get $l1 + local.get $l2 + i32.ne + br_if $L0 + local.get $l3 + i32.const 1060504 + i32.store + local.get $p0 + local.get $l2 + i32.const 1 + i32.eq + i32.const 1051124 + i32.load + call_indirect (type $t3) $T0 + local.get $l3 + i32.const 3 + i32.store offset=4 + local.get $l3 + call $f122 + end + local.get $l3 + i32.const 16 + i32.add + global.set $g0 + return + end + local.get $l2 + i32.const 3 + i32.and + i32.const 2 + i32.eq + if $I8 + loop $L9 + i32.const 1060556 + i32.load + i32.const 1 + i32.ne + if $I10 + i32.const 1060556 + i64.const 1 + i64.store align=4 + i32.const 1060564 + i32.const 0 + i32.store + end + local.get $l2 + local.set $l1 + call $f81 + local.set $l5 + i32.const 1060504 + local.get $l4 + i32.const 1060504 + i32.load + local.tee $l2 + local.get $l1 + local.get $l2 + i32.eq + select + i32.store + local.get $l3 + i32.const 0 + i32.store8 offset=8 + local.get $l3 + local.get $l5 + i32.store + local.get $l3 + local.get $l1 + i32.const -4 + i32.and + i32.store offset=4 + local.get $l1 + local.get $l2 + i32.eq + if $I11 + local.get $l3 + i32.load8_u offset=8 + i32.eqz + br_if $B3 + br $B2 + end + block $B12 + local.get $l3 + i32.load + local.tee $l1 + i32.eqz + br_if $B12 + local.get $l1 + local.get $l1 + i32.load + local.tee $l1 + i32.const -1 + i32.add + i32.store + local.get $l1 + i32.const 1 + i32.ne + br_if $B12 + local.get $l3 + call $f78 + end + local.get $l2 + i32.const 3 + i32.and + i32.const 2 + i32.eq + br_if $L9 + br $B1 + end + unreachable + end + i32.const 1051172 + i32.const 57 + i32.const 1051156 + call $f55 + unreachable + end + i32.const 1051248 + i32.const 42 + i32.const 1051232 + call $f55 + unreachable + end + loop $L13 + call $f82 + local.get $l3 + i32.load8_u offset=8 + i32.eqz + br_if $L13 + end + end + local.get $l3 + i32.load + local.tee $l2 + i32.eqz + br_if $B1 + local.get $l2 + local.get $l2 + i32.load + local.tee $l2 + i32.const -1 + i32.add + i32.store + local.get $l2 + i32.const 1 + i32.ne + br_if $B1 + local.get $l3 + call $f78 + i32.const 1060504 + i32.load + local.set $l1 + br $L0 + end + i32.const 1060504 + i32.load + local.set $l1 + br $L0 + end + unreachable) + (func $f122 (type $t2) (param $p0 i32) + (local $l1 i32) (local $l2 i32) (local $l3 i32) + global.get $g0 + i32.const -64 + i32.add + local.tee $l1 + global.set $g0 + local.get $p0 + i32.load + local.tee $l2 + i32.load + local.set $l3 + local.get $l2 + local.get $p0 + i32.load offset=4 + i32.store + local.get $l1 + local.get $l3 + i32.const 3 + i32.and + local.tee $p0 + i32.store offset=12 + local.get $p0 + i32.const 2 + i32.eq + if $I0 + block $B1 + local.get $l3 + i32.const -4 + i32.and + local.tee $p0 + if $I2 + loop $L3 + local.get $p0 + i32.load offset=4 + local.get $p0 + i32.load + local.set $l2 + local.get $p0 + i32.const 0 + i32.store + local.get $l2 + i32.eqz + br_if $B1 + local.get $p0 + i32.const 1 + i32.store8 offset=8 + local.get $l1 + local.get $l2 + i32.store offset=16 + local.get $l1 + i32.const 16 + i32.add + call $f87 + local.get $l1 + i32.load offset=16 + local.tee $p0 + local.get $p0 + i32.load + local.tee $p0 + i32.const -1 + i32.add + i32.store + local.get $p0 + i32.const 1 + i32.eq + if $I4 + local.get $l1 + i32.const 16 + i32.add + call $f78 + end + local.tee $p0 + br_if $L3 + end + end + local.get $l1 + i32.const -64 + i32.sub + global.set $g0 + return + end + i32.const 1049576 + i32.const 43 + i32.const 1049516 + call $f172 + unreachable + end + local.get $l1 + i32.const 52 + i32.add + i32.const 14 + i32.store + local.get $l1 + i32.const 36 + i32.add + i32.const 2 + i32.store + local.get $l1 + i64.const 3 + i64.store offset=20 align=4 + local.get $l1 + i32.const 1049492 + i32.store offset=16 + local.get $l1 + i32.const 14 + i32.store offset=44 + local.get $l1 + local.get $l1 + i32.const 12 + i32.add + i32.store offset=56 + local.get $l1 + i32.const 1049936 + i32.store offset=60 + local.get $l1 + local.get $l1 + i32.const 40 + i32.add + i32.store offset=32 + local.get $l1 + local.get $l1 + i32.const 60 + i32.add + i32.store offset=48 + local.get $l1 + local.get $l1 + i32.const 56 + i32.add + i32.store offset=40 + local.get $l1 + i32.const 16 + i32.add + i32.const 1051292 + call $f84 + unreachable) + (func $f123 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + (local $l2 i32) (local $l3 i32) (local $l4 i32) (local $l5 i32) (local $l6 i64) + global.get $g0 + i32.const -64 + i32.add + local.tee $l2 + global.set $g0 + local.get $p0 + i32.load8_u + local.set $l3 + local.get $l2 + i32.const 40 + i32.add + call $f89 + block $B0 + local.get $l2 + i32.load offset=40 + i32.const 1 + i32.ne + if $I1 + local.get $l2 + i32.const 48 + i32.add + i64.load + local.set $l6 + local.get $l2 + i32.load offset=44 + local.set $l4 + br $B0 + end + local.get $l2 + i32.load8_u offset=44 + i32.const 2 + i32.ge_u + if $I2 + local.get $l2 + i32.const 48 + i32.add + i32.load + local.tee $p0 + i32.load + local.get $p0 + i32.load offset=4 + i32.load + call_indirect (type $t2) $T0 + local.get $p0 + i32.load offset=4 + local.tee $l5 + i32.load offset=4 + if $I3 + local.get $l5 + i32.load offset=8 + drop + local.get $p0 + i32.load + call $f145 + end + local.get $p0 + call $f145 + end + end + local.get $l2 + local.get $l6 + i64.store offset=4 align=4 + local.get $l2 + local.get $l4 + i32.store + local.get $l2 + local.get $l3 + i32.store8 offset=12 + local.get $l2 + i32.const 16 + i32.add + local.get $p1 + local.get $l3 + local.get $l2 + call $f143 + block $B4 + block $B5 + local.get $l2 + i32.const 16 + i32.add + i32.load + i32.const 1052603 + i32.const 17 + call $f218 + br_if $B5 + local.get $l3 + i32.eqz + if $I6 + local.get $l2 + i64.const 4 + i64.store offset=56 + local.get $l2 + i64.const 1 + i64.store offset=44 align=4 + local.get $l2 + i32.const 1051500 + i32.store offset=40 + local.get $p1 + local.get $l2 + i32.const 40 + i32.add + call $f219 + br_if $B5 + end + i32.const 0 + local.set $p0 + local.get $l2 + i32.load + local.tee $p1 + i32.eqz + br_if $B4 + local.get $l2 + i32.load offset=4 + i32.eqz + br_if $B4 + local.get $p1 + call $f145 + br $B4 + end + i32.const 1 + local.set $p0 + local.get $l2 + i32.load + local.tee $p1 + i32.eqz + br_if $B4 + local.get $l2 + i32.load offset=4 + i32.eqz + br_if $B4 + local.get $p1 + call $f145 + end + local.get $l2 + i32.const -64 + i32.sub + global.set $g0 + local.get $p0) + (func $f124 (type $t1) (param $p0 i32) (param $p1 i32) (param $p2 i32) (result i32) + (local $l3 i32) + global.get $g0 + i32.const 32 + i32.sub + local.tee $p0 + global.set $g0 + block $B0 (result i32) + local.get $p2 + i32.load + i32.const 1 + i32.eq + if $I1 + i32.const 1051512 + local.set $p2 + i32.const 9 + br $B0 + end + local.get $p0 + i32.const 16 + i32.add + local.get $p2 + i32.load offset=4 + local.get $p2 + i32.const 8 + i32.add + i32.load + call $f201 + i32.const 1051512 + local.get $p0 + i32.load offset=20 + local.get $p0 + i32.load offset=16 + i32.const 1 + i32.eq + local.tee $l3 + select + local.set $p2 + i32.const 9 + local.get $p0 + i32.const 24 + i32.add + i32.load + local.get $l3 + select + end + local.set $l3 + local.get $p0 + i32.const 8 + i32.add + local.get $p2 + local.get $l3 + call $f195 + local.get $p0 + i32.load offset=8 + local.get $p0 + i32.load offset=12 + local.get $p1 + call $f197 + local.get $p0 + i32.const 32 + i32.add + global.set $g0) + (func $f125 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + i32.const 1051521 + i32.const 25 + local.get $p1 + call $f224) + (func $f126 (type $t2) (param $p0 i32) + (local $l1 i32) (local $l2 i32) + global.get $g0 + i32.const 48 + i32.sub + local.tee $l1 + global.set $g0 + local.get $l1 + i32.const 32 + i32.add + local.get $p0 + i32.const 16 + i32.add + i64.load align=4 + i64.store + local.get $l1 + i32.const 24 + i32.add + local.get $p0 + i32.const 8 + i32.add + i64.load align=4 + i64.store + local.get $l1 + local.get $p0 + i64.load align=4 + i64.store offset=16 + local.get $l1 + i32.const 8 + i32.add + local.get $l1 + i32.const 40 + i32.add + local.get $l1 + i32.const 16 + i32.add + call $f117 + local.get $l1 + i32.load8_u offset=8 + i32.const 2 + i32.eq + if $I0 + local.get $l1 + i32.load offset=12 + local.tee $p0 + i32.load + local.get $p0 + i32.load offset=4 + i32.load + call_indirect (type $t2) $T0 + local.get $p0 + i32.load offset=4 + local.tee $l2 + i32.load offset=4 + if $I1 + local.get $l2 + i32.load offset=8 + drop + local.get $p0 + i32.load + call $f145 + end + local.get $p0 + call $f145 + end + local.get $l1 + i32.const 48 + i32.add + global.set $g0) + (func $f127 (type $t2) (param $p0 i32) + (local $l1 i32) + global.get $g0 + i32.const 32 + i32.sub + local.tee $l1 + global.set $g0 + local.get $l1 + i32.const 20 + i32.add + i32.const 1 + i32.store + local.get $l1 + i64.const 2 + i64.store offset=4 align=4 + local.get $l1 + i32.const 1051660 + i32.store + local.get $l1 + i32.const 4 + i32.store offset=28 + local.get $l1 + local.get $p0 + i32.store offset=24 + local.get $l1 + local.get $l1 + i32.const 24 + i32.add + i32.store offset=16 + local.get $l1 + call $f126 + unreachable) + (func $f128 (type $t3) (param $p0 i32) (param $p1 i32) + (local $l2 i32) + global.get $g0 + i32.const -64 + i32.add + local.tee $p1 + global.set $g0 + local.get $p1 + i32.const 20 + i32.store offset=12 + local.get $p1 + local.get $p0 + i32.store offset=20 + local.get $p1 + local.get $p1 + i32.const 20 + i32.add + i32.store offset=8 + local.get $p1 + i32.const 52 + i32.add + i32.const 1 + i32.store + local.get $p1 + i64.const 2 + i64.store offset=36 align=4 + local.get $p1 + i32.const 1051776 + i32.store offset=32 + local.get $p1 + local.get $p1 + i32.const 8 + i32.add + i32.store offset=48 + local.get $p1 + i32.const 24 + i32.add + local.get $p1 + i32.const 56 + i32.add + local.get $p1 + i32.const 32 + i32.add + call $f117 + local.get $p1 + i32.load8_u offset=24 + i32.const 2 + i32.eq + if $I0 + local.get $p1 + i32.load offset=28 + local.tee $p0 + i32.load + local.get $p0 + i32.load offset=4 + i32.load + call_indirect (type $t2) $T0 + local.get $p0 + i32.load offset=4 + local.tee $l2 + i32.load offset=4 + if $I1 + local.get $l2 + i32.load offset=8 + drop + local.get $p0 + i32.load + call $f145 + end + local.get $p0 + call $f145 + end + local.get $p1 + i32.const -64 + i32.sub + global.set $g0) + (func $f129 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + local.get $p1 + i32.const 8 + i32.gt_u + local.get $p1 + local.get $p0 + i32.gt_u + i32.or + i32.eqz + if $I0 + local.get $p0 + call $f144 + return + end + local.get $p0 + local.get $p1 + call $f150) + (func $f130 (type $t9) (param $p0 i32) (param $p1 i32) (param $p2 i32) (param $p3 i32) (result i32) + local.get $p2 + i32.const 8 + i32.le_u + i32.const 0 + local.get $p2 + local.get $p3 + i32.le_u + select + i32.eqz + if $I0 + local.get $p3 + local.get $p2 + call $f150 + local.tee $p2 + i32.eqz + if $I1 + i32.const 0 + return + end + local.get $p2 + local.get $p0 + local.get $p3 + local.get $p1 + local.get $p1 + local.get $p3 + i32.gt_u + select + call $f162 + local.get $p0 + call $f145 + return + end + local.get $p0 + local.get $p3 + call $f147) + (func $f131 (type $t4) (param $p0 i32) (param $p1 i32) (param $p2 i32) + (local $l3 i32) (local $l4 i32) (local $l5 i32) + global.get $g0 + i32.const -64 + i32.add + local.tee $l3 + global.set $g0 + local.get $l3 + i32.const 20 + i32.add + i32.const 3 + i32.store + local.get $l3 + i32.const 52 + i32.add + i32.const 22 + i32.store + local.get $l3 + i32.const 44 + i32.add + i32.const 19 + i32.store + local.get $l3 + i64.const 4 + i64.store offset=4 align=4 + local.get $l3 + i32.const 1051912 + i32.store + local.get $l3 + i32.const 19 + i32.store offset=36 + local.get $l3 + local.get $p0 + i32.load offset=8 + i32.store offset=48 + local.get $l3 + local.get $p0 + i32.load offset=4 + i32.store offset=40 + local.get $l3 + local.get $p0 + i32.load + i32.store offset=32 + local.get $l3 + local.get $l3 + i32.const 32 + i32.add + i32.store offset=16 + local.get $l3 + i32.const 24 + i32.add + local.get $p1 + local.get $l3 + local.get $p2 + i32.load offset=28 + local.tee $l4 + call_indirect (type $t4) $T0 + local.get $l3 + i32.load8_u offset=24 + i32.const 2 + i32.eq + if $I0 + local.get $l3 + i32.load offset=28 + local.tee $p2 + i32.load + local.get $p2 + i32.load offset=4 + i32.load + call_indirect (type $t2) $T0 + local.get $p2 + i32.load offset=4 + local.tee $l5 + i32.load offset=4 + if $I1 + local.get $l5 + i32.load offset=8 + drop + local.get $p2 + i32.load + call $f145 + end + local.get $p2 + call $f145 + end + block $B2 + block $B3 + block $B4 + block $B5 + local.get $p0 + i32.load offset=12 + i32.load8_u + local.tee $p0 + i32.const -3 + i32.add + i32.const 255 + i32.and + local.tee $p2 + i32.const 1 + i32.add + i32.const 0 + local.get $p2 + i32.const 2 + i32.lt_u + select + i32.const 1 + i32.sub + br_table $B3 $B4 $B5 + end + i32.const 1060578 + i32.load8_u + br_if $B2 + i32.const 1060578 + i32.const 1 + i32.store8 + local.get $l3 + i32.const 52 + i32.add + i32.const 1 + i32.store + local.get $l3 + i64.const 1 + i64.store offset=36 align=4 + local.get $l3 + i32.const 1050752 + i32.store offset=32 + local.get $l3 + i32.const 23 + i32.store offset=4 + local.get $l3 + local.get $p0 + i32.store8 offset=63 + local.get $l3 + local.get $l3 + i32.store offset=48 + local.get $l3 + local.get $l3 + i32.const 63 + i32.add + i32.store + local.get $l3 + i32.const 24 + i32.add + local.get $p1 + local.get $l3 + i32.const 32 + i32.add + local.get $l4 + call_indirect (type $t4) $T0 + i32.const 1060578 + i32.const 0 + i32.store8 + local.get $l3 + i32.load8_u offset=24 + i32.const 2 + i32.ne + br_if $B3 + local.get $l3 + i32.load offset=28 + local.tee $p0 + i32.load + local.get $p0 + i32.load offset=4 + i32.load + call_indirect (type $t2) $T0 + local.get $p0 + i32.load offset=4 + local.tee $p1 + i32.load offset=4 + if $I6 + local.get $p1 + i32.load offset=8 + drop + local.get $p0 + i32.load + call $f145 + end + local.get $p0 + call $f145 + br $B3 + end + i32.const 1060480 + i32.load8_u + i32.const 1060480 + i32.const 0 + i32.store8 + i32.eqz + br_if $B3 + local.get $l3 + i64.const 4 + i64.store offset=48 + local.get $l3 + i64.const 1 + i64.store offset=36 align=4 + local.get $l3 + i32.const 1052024 + i32.store offset=32 + local.get $l3 + local.get $p1 + local.get $l3 + i32.const 32 + i32.add + local.get $l4 + call_indirect (type $t4) $T0 + local.get $l3 + i32.load8_u + i32.const 2 + i32.ne + br_if $B3 + local.get $l3 + i32.load offset=4 + local.tee $p0 + i32.load + local.get $p0 + i32.load offset=4 + i32.load + call_indirect (type $t2) $T0 + local.get $p0 + i32.load offset=4 + local.tee $p1 + i32.load offset=4 + if $I7 + local.get $p1 + i32.load offset=8 + drop + local.get $p0 + i32.load + call $f145 + end + local.get $p0 + call $f145 + end + local.get $l3 + i32.const -64 + i32.sub + global.set $g0 + return + end + i32.const 1052440 + i32.const 32 + i32.const 1052424 + call $f55 + unreachable) + (func $f132 (type $t2) (param $p0 i32) + local.get $p0 + local.get $p0 + i32.load + local.tee $p0 + i32.load + local.get $p0 + i32.load offset=4 + i32.load offset=12 + call_indirect (type $t5) $T0 + i32.store) + (func $f133 (type $t2) (param $p0 i32) + (local $l1 i32) (local $l2 i32) (local $l3 i32) (local $l4 i32) (local $l5 i64) + global.get $g0 + i32.const 48 + i32.sub + local.tee $l1 + global.set $g0 + local.get $p0 + i32.load offset=12 + call $f67 + local.set $l2 + local.get $p0 + i32.load offset=8 + call $f67 + local.set $l3 + local.get $l1 + i32.const 8 + i32.add + local.get $l2 + call $f187 + local.get $l1 + i64.load offset=8 + local.set $l5 + local.get $l2 + i32.load offset=8 + local.set $l4 + local.get $l1 + local.get $l2 + i32.load offset=12 + i32.store offset=28 + local.get $l1 + local.get $l4 + i32.store offset=24 + local.get $l1 + local.get $l5 + i64.store offset=16 + local.get $l1 + i32.const 0 + i32.store offset=36 + local.get $l1 + local.get $l3 + i32.store offset=32 + local.get $l1 + i32.const 32 + i32.add + i32.const 1052032 + local.get $p0 + i32.load offset=8 + local.get $l1 + i32.const 16 + i32.add + call $f134 + unreachable) + (func $f134 (type $t6) (param $p0 i32) (param $p1 i32) (param $p2 i32) (param $p3 i32) + (local $l4 i32) (local $l5 i32) (local $l6 i32) (local $l7 i32) (local $l8 i32) + global.get $g0 + i32.const 80 + i32.sub + local.tee $l4 + global.set $g0 + i32.const 1 + local.set $l5 + local.get $p3 + i32.load offset=12 + local.set $l6 + local.get $p3 + i32.load offset=8 + local.set $l7 + local.get $p3 + i32.load offset=4 + local.set $l8 + local.get $p3 + i32.load + local.set $p3 + block $B0 + block $B1 + block $B2 + i32.const 1060568 + i32.load + i32.const 1 + i32.ne + if $I3 + i32.const 1060568 + i64.const 4294967297 + i64.store + br $B2 + end + i32.const 1060572 + i32.const 1060572 + i32.load + i32.const 1 + i32.add + local.tee $l5 + i32.store + local.get $l5 + i32.const 2 + i32.gt_u + br_if $B1 + end + local.get $l4 + i32.const 24 + i32.add + local.get $p3 + local.get $l8 + local.get $l7 + local.get $l6 + call $f186 + local.get $l4 + local.get $p2 + i32.store offset=48 + local.get $l4 + i32.const 1049532 + i32.store offset=44 + local.get $l4 + i32.const 1 + i32.store offset=40 + i32.const 1060512 + i32.load + local.set $p2 + local.get $l4 + local.get $l4 + i32.const 24 + i32.add + i32.store offset=52 + local.get $p2 + i32.const -1 + i32.gt_s + if $I4 + i32.const 1060512 + local.get $p2 + i32.const 1 + i32.add + i32.store + block $B5 + i32.const 1060520 + i32.load + local.tee $p2 + i32.eqz + if $I6 + local.get $l4 + i32.const 8 + i32.add + local.get $p0 + local.get $p1 + i32.load offset=16 + call_indirect (type $t3) $T0 + local.get $l4 + local.get $l4 + i64.load offset=8 + i64.store offset=40 + local.get $l4 + i32.const 40 + i32.add + call $f54 + br $B5 + end + i32.const 1060516 + i32.load + local.get $l4 + i32.const 16 + i32.add + local.get $p0 + local.get $p1 + i32.load offset=16 + call_indirect (type $t3) $T0 + local.get $l4 + local.get $l4 + i64.load offset=16 + i64.store offset=40 + local.get $l4 + i32.const 40 + i32.add + local.get $p2 + i32.load offset=12 + call_indirect (type $t3) $T0 + end + i32.const 1060512 + i32.const 1060512 + i32.load + i32.const -1 + i32.add + i32.store + local.get $l5 + i32.const 1 + i32.le_u + br_if $B0 + local.get $l4 + i64.const 4 + i64.store offset=72 + local.get $l4 + i64.const 1 + i64.store offset=60 align=4 + local.get $l4 + i32.const 1052208 + i32.store offset=56 + local.get $l4 + i32.const 56 + i32.add + call $f126 + unreachable + end + local.get $l4 + i64.const 4 + i64.store offset=72 + local.get $l4 + i64.const 1 + i64.store offset=60 align=4 + local.get $l4 + i32.const 1052560 + i32.store offset=56 + local.get $l4 + i32.const 56 + i32.add + call $f127 + unreachable + end + local.get $l4 + i64.const 4 + i64.store offset=72 + local.get $l4 + i64.const 1 + i64.store offset=60 align=4 + local.get $l4 + i32.const 1052156 + i32.store offset=56 + local.get $l4 + i32.const 56 + i32.add + call $f126 + unreachable + end + global.get $g0 + i32.const 48 + i32.sub + local.tee $p2 + global.set $g0 + local.get $p2 + local.get $p1 + i32.store offset=4 + local.get $p2 + local.get $p0 + i32.store + unreachable) + (func $f135 (type $t3) (param $p0 i32) (param $p1 i32) + (local $l2 i32) (local $l3 i32) (local $l4 i32) (local $l5 i32) + global.get $g0 + i32.const -64 + i32.add + local.tee $l2 + global.set $g0 + local.get $p1 + i32.load offset=4 + local.tee $l3 + i32.eqz + if $I0 + local.get $p1 + i32.const 4 + i32.add + local.set $l3 + local.get $p1 + i32.load + local.set $l4 + local.get $l2 + i32.const 0 + i32.store offset=32 + local.get $l2 + i64.const 1 + i64.store offset=24 + local.get $l2 + local.get $l2 + i32.const 24 + i32.add + i32.store offset=36 + local.get $l2 + i32.const 56 + i32.add + local.get $l4 + i32.const 16 + i32.add + i64.load align=4 + i64.store + local.get $l2 + i32.const 48 + i32.add + local.get $l4 + i32.const 8 + i32.add + i64.load align=4 + i64.store + local.get $l2 + local.get $l4 + i64.load align=4 + i64.store offset=40 + local.get $l2 + i32.const 36 + i32.add + i32.const 1049264 + local.get $l2 + i32.const 40 + i32.add + call $f179 + drop + local.get $l2 + i32.const 16 + i32.add + local.tee $l4 + local.get $l2 + i32.load offset=32 + i32.store + local.get $l2 + local.get $l2 + i64.load offset=24 + i64.store offset=8 + block $B1 + local.get $p1 + i32.load offset=4 + local.tee $l5 + i32.eqz + br_if $B1 + local.get $p1 + i32.const 8 + i32.add + i32.load + i32.eqz + br_if $B1 + local.get $l5 + call $f145 + end + local.get $l3 + local.get $l2 + i64.load offset=8 + i64.store align=4 + local.get $l3 + i32.const 8 + i32.add + local.get $l4 + i32.load + i32.store + local.get $l3 + i32.load + local.set $l3 + end + local.get $p1 + i32.const 1 + i32.store offset=4 + local.get $p1 + i32.const 12 + i32.add + i32.load + local.set $l4 + local.get $p1 + i32.const 8 + i32.add + local.tee $p1 + i32.load + local.set $l5 + local.get $p1 + i64.const 0 + i64.store align=4 + i32.const 12 + i32.const 4 + call $f36 + local.tee $p1 + i32.eqz + if $I2 + i32.const 12 + i32.const 4 + call $f168 + unreachable + end + local.get $p1 + local.get $l4 + i32.store offset=8 + local.get $p1 + local.get $l5 + i32.store offset=4 + local.get $p1 + local.get $l3 + i32.store + local.get $p0 + i32.const 1052052 + i32.store offset=4 + local.get $p0 + local.get $p1 + i32.store + local.get $l2 + i32.const -64 + i32.sub + global.set $g0) + (func $f136 (type $t3) (param $p0 i32) (param $p1 i32) + (local $l2 i32) (local $l3 i32) (local $l4 i32) (local $l5 i32) + global.get $g0 + i32.const -64 + i32.add + local.tee $l2 + global.set $g0 + local.get $p1 + i32.const 4 + i32.add + local.set $l4 + local.get $p1 + i32.load offset=4 + i32.eqz + if $I0 + local.get $p1 + i32.load + local.set $l3 + local.get $l2 + i32.const 0 + i32.store offset=32 + local.get $l2 + i64.const 1 + i64.store offset=24 + local.get $l2 + local.get $l2 + i32.const 24 + i32.add + i32.store offset=36 + local.get $l2 + i32.const 56 + i32.add + local.get $l3 + i32.const 16 + i32.add + i64.load align=4 + i64.store + local.get $l2 + i32.const 48 + i32.add + local.get $l3 + i32.const 8 + i32.add + i64.load align=4 + i64.store + local.get $l2 + local.get $l3 + i64.load align=4 + i64.store offset=40 + local.get $l2 + i32.const 36 + i32.add + i32.const 1049264 + local.get $l2 + i32.const 40 + i32.add + call $f179 + drop + local.get $l2 + i32.const 16 + i32.add + local.tee $l3 + local.get $l2 + i32.load offset=32 + i32.store + local.get $l2 + local.get $l2 + i64.load offset=24 + i64.store offset=8 + block $B1 + local.get $p1 + i32.load offset=4 + local.tee $l5 + i32.eqz + br_if $B1 + local.get $p1 + i32.const 8 + i32.add + i32.load + i32.eqz + br_if $B1 + local.get $l5 + call $f145 + end + local.get $l4 + local.get $l2 + i64.load offset=8 + i64.store align=4 + local.get $l4 + i32.const 8 + i32.add + local.get $l3 + i32.load + i32.store + end + local.get $p0 + i32.const 1052052 + i32.store offset=4 + local.get $p0 + local.get $l4 + i32.store + local.get $l2 + i32.const -64 + i32.sub + global.set $g0) + (func $f137 (type $t3) (param $p0 i32) (param $p1 i32) + (local $l2 i32) (local $l3 i32) + local.get $p1 + i32.load + local.set $l2 + local.get $p1 + i32.const 0 + i32.store + block $B0 + local.get $l2 + if $I1 + local.get $p1 + i32.load offset=4 + local.set $l3 + i32.const 8 + i32.const 4 + call $f36 + local.tee $p1 + i32.eqz + br_if $B0 + local.get $p1 + local.get $l3 + i32.store offset=4 + local.get $p1 + local.get $l2 + i32.store + local.get $p0 + i32.const 1052088 + i32.store offset=4 + local.get $p0 + local.get $p1 + i32.store + return + end + unreachable + end + i32.const 8 + i32.const 4 + call $f168 + unreachable) + (func $f138 (type $t3) (param $p0 i32) (param $p1 i32) + local.get $p1 + i32.load + i32.eqz + if $I0 + unreachable + end + local.get $p0 + i32.const 1052088 + i32.store offset=4 + local.get $p0 + local.get $p1 + i32.store) + (func $f139 (type $t5) (param $p0 i32) (result i32) + (local $l1 i32) (local $l2 i32) (local $l3 i32) (local $l4 i32) + global.get $g0 + i32.const 32 + i32.sub + local.tee $l1 + global.set $g0 + local.get $l1 + i32.const 1049192 + i32.store offset=4 + local.get $l1 + local.get $p0 + i32.store + block $B0 + block $B1 + block $B2 + i32.const 4 + i32.const 1 + call $f36 + local.tee $p0 + if $I3 + local.get $p0 + i32.const 1852399981 + i32.store align=1 + local.get $l1 + i64.const 17179869188 + i64.store offset=12 align=4 + local.get $l1 + local.get $p0 + i32.store offset=8 + local.get $l1 + i32.const 8 + i32.add + call $f85 + local.set $l2 + block $B4 + i32.const 1060556 + i32.load + i32.const 1 + i32.ne + if $I5 + i32.const 1060556 + i64.const 1 + i64.store align=4 + i32.const 1060564 + i32.const 0 + i32.store + br $B4 + end + i32.const 1060560 + i32.load + local.tee $p0 + i32.const 1 + i32.add + i32.const 0 + i32.le_s + br_if $B2 + i32.const 1060564 + i32.load + br_if $B1 + local.get $p0 + br_if $B0 + end + i32.const 0 + local.set $p0 + i32.const 1060564 + local.get $l2 + i32.store + i32.const 1060560 + i32.const 0 + i32.store + local.get $l1 + i32.const 0 + i32.store offset=24 + local.get $l1 + i32.const 0 + i32.store offset=28 + local.get $l1 + local.get $l1 + i32.store offset=8 + block $B6 (result i32) + local.get $l1 + i32.const 8 + i32.add + call $f132 + i32.const 0 + if $I7 + i32.const 1060572 + block $B8 (result i32) + i32.const 1060568 + i32.load + i32.const 1 + i32.eq + if $I9 + i32.const 1060572 + i32.load + i32.const -1 + i32.add + br $B8 + end + i32.const 1060568 + i64.const 1 + i64.store + i32.const -1 + end + i32.store + i32.const 1 + local.set $p0 + local.get $l1 + i32.load offset=28 + local.set $l3 + local.get $l1 + i32.load offset=24 + br $B6 + end + local.get $l1 + i32.load offset=8 + end + local.set $l2 + i32.const 1060504 + i32.load + i32.const 3 + i32.ne + if $I10 + local.get $l1 + i32.const 1 + i32.store8 offset=28 + local.get $l1 + local.get $l1 + i32.const 28 + i32.add + i32.store offset=8 + local.get $l1 + i32.const 8 + i32.add + call $f121 + end + i32.const 101 + local.get $l2 + local.get $p0 + select + block $B11 + local.get $p0 + i32.eqz + br_if $B11 + local.get $l2 + local.get $l3 + i32.load + call_indirect (type $t2) $T0 + local.get $l3 + i32.load offset=4 + i32.eqz + br_if $B11 + local.get $l3 + i32.load offset=8 + drop + local.get $l2 + call $f145 + end + local.get $l1 + i32.const 32 + i32.add + global.set $g0 + return + end + i32.const 4 + i32.const 1 + call $f168 + unreachable + end + i32.const 1049336 + i32.const 24 + local.get $l1 + i32.const 8 + i32.add + i32.const 1049652 + call $f192 + unreachable + end + i32.const 1051600 + i32.const 38 + i32.const 1051584 + call $f55 + unreachable + end + i32.const 1049320 + i32.const 16 + local.get $l1 + i32.const 8 + i32.add + i32.const 1049620 + call $f192 + unreachable) + (func $f140 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + (local $l2 i32) + global.get $g0 + i32.const 16 + i32.sub + local.tee $l2 + global.set $g0 + block $B0 + local.get $p0 + i32.load + i32.eqz + if $I1 + local.get $l2 + local.get $p1 + i32.const 1052266 + i32.const 10 + call $f222 + br $B0 + end + local.get $l2 + local.get $p1 + i32.const 1052256 + i32.const 10 + call $f222 + local.get $l2 + local.get $p0 + i32.store offset=12 + local.get $l2 + local.get $l2 + i32.const 12 + i32.add + i32.const 1049288 + call $f206 + end + local.get $l2 + call $f207 + local.get $l2 + i32.const 16 + i32.add + global.set $g0) + (func $f141 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + (local $l2 i32) + global.get $g0 + i32.const 16 + i32.sub + local.tee $l2 + global.set $g0 + local.get $l2 + local.get $p1 + i32.const 1052276 + i32.const 8 + call $f222 + local.get $l2 + local.get $p0 + i32.store offset=12 + local.get $l2 + local.get $l2 + i32.const 12 + i32.add + i32.const 1049856 + call $f206 + local.get $l2 + local.get $p0 + i32.const 4 + i32.add + i32.store offset=12 + local.get $l2 + local.get $l2 + i32.const 12 + i32.add + i32.const 1052284 + call $f206 + local.get $l2 + call $f207 + local.get $l2 + i32.const 16 + i32.add + global.set $g0) + (func $f142 (type $t4) (param $p0 i32) (param $p1 i32) (param $p2 i32) + (local $l3 i32) + global.get $g0 + i32.const 16 + i32.sub + local.tee $l3 + global.set $g0 + local.get $p0 + block $B0 (result i32) + local.get $p1 + local.get $p2 + i32.const 1 + local.get $l3 + i32.const 12 + i32.add + call $wasi_snapshot_preview1.fd_write + local.tee $p1 + i32.eqz + if $I1 + local.get $p0 + i32.const 4 + i32.add + local.get $l3 + i32.load offset=12 + i32.store + i32.const 0 + br $B0 + end + local.get $p0 + local.get $p1 + i32.store16 offset=2 + i32.const 1 + end + i32.store16 + local.get $l3 + i32.const 16 + i32.add + global.set $g0) + (func $f143 (type $t6) (param $p0 i32) (param $p1 i32) (param $p2 i32) (param $p3 i32) + local.get $p0 + local.get $p2 + i32.store8 offset=16 + local.get $p0 + i32.const 0 + i32.store offset=4 + local.get $p0 + local.get $p1 + i32.store + local.get $p0 + local.get $p3 + i32.store offset=8 + local.get $p0 + i32.const 12 + i32.add + i32.const 1051392 + i32.store) + (func $f144 (type $t5) (param $p0 i32) (result i32) + (local $l1 i32) (local $l2 i32) (local $l3 i32) (local $l4 i32) (local $l5 i32) (local $l6 i32) (local $l7 i32) (local $l8 i32) (local $l9 i32) (local $l10 i32) (local $l11 i32) + global.get $g0 + i32.const 16 + i32.sub + local.tee $l11 + global.set $g0 + block $B0 + block $B1 + block $B2 + block $B3 + block $B4 + block $B5 + block $B6 + block $B7 + block $B8 + block $B9 + block $B10 + local.get $p0 + i32.const 236 + i32.le_u + if $I11 + i32.const 1060580 + i32.load + local.tee $l5 + i32.const 16 + local.get $p0 + i32.const 19 + i32.add + i32.const -16 + i32.and + local.get $p0 + i32.const 11 + i32.lt_u + select + local.tee $l6 + i32.const 3 + i32.shr_u + local.tee $p0 + i32.shr_u + local.tee $l1 + i32.const 3 + i32.and + if $I12 + local.get $l1 + i32.const 1 + i32.and + local.get $p0 + i32.or + i32.const 1 + i32.xor + local.tee $l2 + i32.const 3 + i32.shl + local.tee $l4 + i32.const 1060628 + i32.add + i32.load + local.tee $l1 + i32.const 8 + i32.add + local.set $p0 + block $B13 + local.get $l1 + i32.load offset=8 + local.tee $l3 + local.get $l4 + i32.const 1060620 + i32.add + local.tee $l4 + i32.eq + if $I14 + i32.const 1060580 + local.get $l5 + i32.const -2 + local.get $l2 + i32.rotl + i32.and + i32.store + br $B13 + end + i32.const 1060596 + i32.load + drop + local.get $l4 + local.get $l3 + i32.store offset=8 + local.get $l3 + local.get $l4 + i32.store offset=12 + end + local.get $l1 + local.get $l2 + i32.const 3 + i32.shl + local.tee $l2 + i32.const 3 + i32.or + i32.store offset=4 + local.get $l1 + local.get $l2 + i32.add + local.tee $l1 + local.get $l1 + i32.load offset=4 + i32.const 1 + i32.or + i32.store offset=4 + br $B0 + end + local.get $l6 + i32.const 1060588 + i32.load + local.tee $l8 + i32.le_u + br_if $B10 + local.get $l1 + if $I15 + block $B16 + i32.const 2 + local.get $p0 + i32.shl + local.tee $l2 + i32.const 0 + local.get $l2 + i32.sub + i32.or + local.get $l1 + local.get $p0 + i32.shl + i32.and + local.tee $p0 + i32.const 0 + local.get $p0 + i32.sub + i32.and + i32.const -1 + i32.add + local.tee $p0 + local.get $p0 + i32.const 12 + i32.shr_u + i32.const 16 + i32.and + local.tee $p0 + i32.shr_u + local.tee $l1 + i32.const 5 + i32.shr_u + i32.const 8 + i32.and + local.tee $l2 + local.get $p0 + i32.or + local.get $l1 + local.get $l2 + i32.shr_u + local.tee $p0 + i32.const 2 + i32.shr_u + i32.const 4 + i32.and + local.tee $l1 + i32.or + local.get $p0 + local.get $l1 + i32.shr_u + local.tee $p0 + i32.const 1 + i32.shr_u + i32.const 2 + i32.and + local.tee $l1 + i32.or + local.get $p0 + local.get $l1 + i32.shr_u + local.tee $p0 + i32.const 1 + i32.shr_u + i32.const 1 + i32.and + local.tee $l1 + i32.or + local.get $p0 + local.get $l1 + i32.shr_u + i32.add + local.tee $l2 + i32.const 3 + i32.shl + local.tee $l3 + i32.const 1060628 + i32.add + i32.load + local.tee $l1 + i32.load offset=8 + local.tee $p0 + local.get $l3 + i32.const 1060620 + i32.add + local.tee $l3 + i32.eq + if $I17 + i32.const 1060580 + local.get $l5 + i32.const -2 + local.get $l2 + i32.rotl + i32.and + local.tee $l5 + i32.store + br $B16 + end + i32.const 1060596 + i32.load + drop + local.get $l3 + local.get $p0 + i32.store offset=8 + local.get $p0 + local.get $l3 + i32.store offset=12 + end + local.get $l1 + i32.const 8 + i32.add + local.set $p0 + local.get $l1 + local.get $l6 + i32.const 3 + i32.or + i32.store offset=4 + local.get $l1 + local.get $l2 + i32.const 3 + i32.shl + local.tee $l2 + i32.add + local.get $l2 + local.get $l6 + i32.sub + local.tee $l4 + i32.store + local.get $l1 + local.get $l6 + i32.add + local.tee $l6 + local.get $l4 + i32.const 1 + i32.or + i32.store offset=4 + local.get $l8 + if $I18 + local.get $l8 + i32.const 3 + i32.shr_u + local.tee $l3 + i32.const 3 + i32.shl + i32.const 1060620 + i32.add + local.set $l1 + i32.const 1060600 + i32.load + local.set $l2 + block $B19 (result i32) + local.get $l5 + i32.const 1 + local.get $l3 + i32.shl + local.tee $l3 + i32.and + i32.eqz + if $I20 + i32.const 1060580 + local.get $l3 + local.get $l5 + i32.or + i32.store + local.get $l1 + br $B19 + end + local.get $l1 + i32.load offset=8 + end + local.tee $l3 + local.get $l2 + i32.store offset=12 + local.get $l1 + local.get $l2 + i32.store offset=8 + local.get $l2 + local.get $l1 + i32.store offset=12 + local.get $l2 + local.get $l3 + i32.store offset=8 + end + i32.const 1060600 + local.get $l6 + i32.store + i32.const 1060588 + local.get $l4 + i32.store + br $B0 + end + i32.const 1060584 + i32.load + local.tee $l10 + i32.eqz + br_if $B10 + local.get $l10 + i32.const 0 + local.get $l10 + i32.sub + i32.and + i32.const -1 + i32.add + local.tee $p0 + local.get $p0 + i32.const 12 + i32.shr_u + i32.const 16 + i32.and + local.tee $p0 + i32.shr_u + local.tee $l1 + i32.const 5 + i32.shr_u + i32.const 8 + i32.and + local.tee $l2 + local.get $p0 + i32.or + local.get $l1 + local.get $l2 + i32.shr_u + local.tee $p0 + i32.const 2 + i32.shr_u + i32.const 4 + i32.and + local.tee $l1 + i32.or + local.get $p0 + local.get $l1 + i32.shr_u + local.tee $p0 + i32.const 1 + i32.shr_u + i32.const 2 + i32.and + local.tee $l1 + i32.or + local.get $p0 + local.get $l1 + i32.shr_u + local.tee $p0 + i32.const 1 + i32.shr_u + i32.const 1 + i32.and + local.tee $l1 + i32.or + local.get $p0 + local.get $l1 + i32.shr_u + i32.add + i32.const 2 + i32.shl + i32.const 1060884 + i32.add + i32.load + local.tee $l1 + i32.load offset=4 + i32.const -8 + i32.and + local.get $l6 + i32.sub + local.set $l2 + local.get $l1 + local.set $l4 + loop $L21 + block $B22 + local.get $l4 + i32.load offset=16 + local.tee $p0 + i32.eqz + if $I23 + local.get $l4 + i32.const 20 + i32.add + i32.load + local.tee $p0 + i32.eqz + br_if $B22 + end + local.get $p0 + i32.load offset=4 + i32.const -8 + i32.and + local.get $l6 + i32.sub + local.tee $l3 + local.get $l2 + local.get $l3 + local.get $l2 + i32.lt_u + local.tee $l3 + select + local.set $l2 + local.get $p0 + local.get $l1 + local.get $l3 + select + local.set $l1 + local.get $p0 + local.set $l4 + br $L21 + end + end + local.get $l1 + i32.load offset=24 + local.set $l9 + local.get $l1 + local.get $l1 + i32.load offset=12 + local.tee $l3 + i32.ne + if $I24 + i32.const 1060596 + i32.load + local.get $l1 + i32.load offset=8 + local.tee $p0 + i32.le_u + if $I25 + local.get $p0 + i32.load offset=12 + drop + end + local.get $l3 + local.get $p0 + i32.store offset=8 + local.get $p0 + local.get $l3 + i32.store offset=12 + br $B1 + end + local.get $l1 + i32.const 20 + i32.add + local.tee $l4 + i32.load + local.tee $p0 + i32.eqz + if $I26 + local.get $l1 + i32.load offset=16 + local.tee $p0 + i32.eqz + br_if $B9 + local.get $l1 + i32.const 16 + i32.add + local.set $l4 + end + loop $L27 + local.get $l4 + local.set $l7 + local.get $p0 + local.tee $l3 + i32.const 20 + i32.add + local.tee $l4 + i32.load + local.tee $p0 + br_if $L27 + local.get $l3 + i32.const 16 + i32.add + local.set $l4 + local.get $l3 + i32.load offset=16 + local.tee $p0 + br_if $L27 + end + local.get $l7 + i32.const 0 + i32.store + br $B1 + end + i32.const -1 + local.set $l6 + local.get $p0 + i32.const -65 + i32.gt_u + br_if $B10 + local.get $p0 + i32.const 19 + i32.add + local.tee $p0 + i32.const -16 + i32.and + local.set $l6 + i32.const 1060584 + i32.load + local.tee $l8 + i32.eqz + br_if $B10 + i32.const 0 + local.get $l6 + i32.sub + local.set $l4 + block $B28 + block $B29 + block $B30 + block $B31 (result i32) + i32.const 0 + local.get $p0 + i32.const 8 + i32.shr_u + local.tee $p0 + i32.eqz + br_if $B31 + drop + i32.const 31 + local.get $l6 + i32.const 16777215 + i32.gt_u + br_if $B31 + drop + local.get $p0 + local.get $p0 + i32.const 1048320 + i32.add + i32.const 16 + i32.shr_u + i32.const 8 + i32.and + local.tee $p0 + i32.shl + local.tee $l1 + local.get $l1 + i32.const 520192 + i32.add + i32.const 16 + i32.shr_u + i32.const 4 + i32.and + local.tee $l1 + i32.shl + local.tee $l2 + local.get $l2 + i32.const 245760 + i32.add + i32.const 16 + i32.shr_u + i32.const 2 + i32.and + local.tee $l2 + i32.shl + i32.const 15 + i32.shr_u + local.get $p0 + local.get $l1 + i32.or + local.get $l2 + i32.or + i32.sub + local.tee $p0 + i32.const 1 + i32.shl + local.get $l6 + local.get $p0 + i32.const 21 + i32.add + i32.shr_u + i32.const 1 + i32.and + i32.or + i32.const 28 + i32.add + end + local.tee $l7 + i32.const 2 + i32.shl + i32.const 1060884 + i32.add + i32.load + local.tee $l2 + i32.eqz + if $I32 + i32.const 0 + local.set $p0 + br $B30 + end + local.get $l6 + i32.const 0 + i32.const 25 + local.get $l7 + i32.const 1 + i32.shr_u + i32.sub + local.get $l7 + i32.const 31 + i32.eq + select + i32.shl + local.set $l1 + i32.const 0 + local.set $p0 + loop $L33 + block $B34 + local.get $l2 + i32.load offset=4 + i32.const -8 + i32.and + local.get $l6 + i32.sub + local.tee $l5 + local.get $l4 + i32.ge_u + br_if $B34 + local.get $l2 + local.set $l3 + local.get $l5 + local.tee $l4 + br_if $B34 + i32.const 0 + local.set $l4 + local.get $l2 + local.set $p0 + br $B29 + end + local.get $p0 + local.get $l2 + i32.const 20 + i32.add + i32.load + local.tee $l5 + local.get $l5 + local.get $l2 + local.get $l1 + i32.const 29 + i32.shr_u + i32.const 4 + i32.and + i32.add + i32.const 16 + i32.add + i32.load + local.tee $l2 + i32.eq + select + local.get $p0 + local.get $l5 + select + local.set $p0 + local.get $l1 + local.get $l2 + i32.const 0 + i32.ne + i32.shl + local.set $l1 + local.get $l2 + br_if $L33 + end + end + local.get $p0 + local.get $l3 + i32.or + i32.eqz + if $I35 + i32.const 2 + local.get $l7 + i32.shl + local.tee $p0 + i32.const 0 + local.get $p0 + i32.sub + i32.or + local.get $l8 + i32.and + local.tee $p0 + i32.eqz + br_if $B10 + local.get $p0 + i32.const 0 + local.get $p0 + i32.sub + i32.and + i32.const -1 + i32.add + local.tee $p0 + local.get $p0 + i32.const 12 + i32.shr_u + i32.const 16 + i32.and + local.tee $p0 + i32.shr_u + local.tee $l1 + i32.const 5 + i32.shr_u + i32.const 8 + i32.and + local.tee $l2 + local.get $p0 + i32.or + local.get $l1 + local.get $l2 + i32.shr_u + local.tee $p0 + i32.const 2 + i32.shr_u + i32.const 4 + i32.and + local.tee $l1 + i32.or + local.get $p0 + local.get $l1 + i32.shr_u + local.tee $p0 + i32.const 1 + i32.shr_u + i32.const 2 + i32.and + local.tee $l1 + i32.or + local.get $p0 + local.get $l1 + i32.shr_u + local.tee $p0 + i32.const 1 + i32.shr_u + i32.const 1 + i32.and + local.tee $l1 + i32.or + local.get $p0 + local.get $l1 + i32.shr_u + i32.add + i32.const 2 + i32.shl + i32.const 1060884 + i32.add + i32.load + local.set $p0 + end + local.get $p0 + i32.eqz + br_if $B28 + end + loop $L36 + local.get $p0 + i32.load offset=4 + i32.const -8 + i32.and + local.get $l6 + i32.sub + local.tee $l5 + local.get $l4 + i32.lt_u + local.set $l1 + local.get $l5 + local.get $l4 + local.get $l1 + select + local.set $l4 + local.get $p0 + local.get $l3 + local.get $l1 + select + local.set $l3 + local.get $p0 + i32.load offset=16 + local.tee $l2 + if $I37 (result i32) + local.get $l2 + else + local.get $p0 + i32.const 20 + i32.add + i32.load + end + local.tee $p0 + br_if $L36 + end + end + local.get $l3 + i32.eqz + br_if $B10 + local.get $l4 + i32.const 1060588 + i32.load + local.get $l6 + i32.sub + i32.ge_u + br_if $B10 + local.get $l3 + i32.load offset=24 + local.set $l7 + local.get $l3 + local.get $l3 + i32.load offset=12 + local.tee $l1 + i32.ne + if $I38 + i32.const 1060596 + i32.load + local.get $l3 + i32.load offset=8 + local.tee $p0 + i32.le_u + if $I39 + local.get $p0 + i32.load offset=12 + drop + end + local.get $l1 + local.get $p0 + i32.store offset=8 + local.get $p0 + local.get $l1 + i32.store offset=12 + br $B2 + end + local.get $l3 + i32.const 20 + i32.add + local.tee $l2 + i32.load + local.tee $p0 + i32.eqz + if $I40 + local.get $l3 + i32.load offset=16 + local.tee $p0 + i32.eqz + br_if $B8 + local.get $l3 + i32.const 16 + i32.add + local.set $l2 + end + loop $L41 + local.get $l2 + local.set $l5 + local.get $p0 + local.tee $l1 + i32.const 20 + i32.add + local.tee $l2 + i32.load + local.tee $p0 + br_if $L41 + local.get $l1 + i32.const 16 + i32.add + local.set $l2 + local.get $l1 + i32.load offset=16 + local.tee $p0 + br_if $L41 + end + local.get $l5 + i32.const 0 + i32.store + br $B2 + end + i32.const 1060588 + i32.load + local.tee $l1 + local.get $l6 + i32.ge_u + if $I42 + i32.const 1060600 + i32.load + local.set $p0 + block $B43 + local.get $l1 + local.get $l6 + i32.sub + local.tee $l2 + i32.const 16 + i32.ge_u + if $I44 + local.get $p0 + local.get $l6 + i32.add + local.tee $l3 + local.get $l2 + i32.const 1 + i32.or + i32.store offset=4 + i32.const 1060588 + local.get $l2 + i32.store + i32.const 1060600 + local.get $l3 + i32.store + local.get $p0 + local.get $l1 + i32.add + local.get $l2 + i32.store + local.get $p0 + local.get $l6 + i32.const 3 + i32.or + i32.store offset=4 + br $B43 + end + local.get $p0 + local.get $l1 + i32.const 3 + i32.or + i32.store offset=4 + local.get $p0 + local.get $l1 + i32.add + local.tee $l1 + local.get $l1 + i32.load offset=4 + i32.const 1 + i32.or + i32.store offset=4 + i32.const 1060600 + i32.const 0 + i32.store + i32.const 1060588 + i32.const 0 + i32.store + end + local.get $p0 + i32.const 8 + i32.add + local.set $p0 + br $B0 + end + i32.const 1060592 + i32.load + local.tee $l1 + local.get $l6 + i32.gt_u + if $I45 + i32.const 1060604 + i32.load + local.tee $p0 + local.get $l6 + i32.add + local.tee $l2 + local.get $l1 + local.get $l6 + i32.sub + local.tee $l1 + i32.const 1 + i32.or + i32.store offset=4 + i32.const 1060592 + local.get $l1 + i32.store + i32.const 1060604 + local.get $l2 + i32.store + local.get $p0 + local.get $l6 + i32.const 3 + i32.or + i32.store offset=4 + local.get $p0 + i32.const 8 + i32.add + local.set $p0 + br $B0 + end + i32.const 0 + local.set $p0 + local.get $l6 + i32.const 71 + i32.add + local.tee $l4 + block $B46 (result i32) + i32.const 1061052 + i32.load + if $I47 + i32.const 1061060 + i32.load + br $B46 + end + i32.const 1061064 + i64.const -1 + i64.store align=4 + i32.const 1061056 + i64.const 281474976776192 + i64.store align=4 + i32.const 1061052 + local.get $l11 + i32.const 12 + i32.add + i32.const -16 + i32.and + i32.const 1431655768 + i32.xor + i32.store + i32.const 1061072 + i32.const 0 + i32.store + i32.const 1061024 + i32.const 0 + i32.store + i32.const 65536 + end + local.tee $l2 + i32.add + local.tee $l5 + i32.const 0 + local.get $l2 + i32.sub + local.tee $l7 + i32.and + local.tee $l2 + local.get $l6 + i32.le_u + if $I48 + i32.const 1061076 + i32.const 48 + i32.store + br $B0 + end + block $B49 + i32.const 1061020 + i32.load + local.tee $p0 + i32.eqz + br_if $B49 + i32.const 1061012 + i32.load + local.tee $l3 + local.get $l2 + i32.add + local.tee $l8 + local.get $l3 + i32.gt_u + i32.const 0 + local.get $l8 + local.get $p0 + i32.le_u + select + br_if $B49 + i32.const 0 + local.set $p0 + i32.const 1061076 + i32.const 48 + i32.store + br $B0 + end + i32.const 1061024 + i32.load8_u + i32.const 4 + i32.and + br_if $B5 + block $B50 + block $B51 + i32.const 1060604 + i32.load + local.tee $l3 + if $I52 + i32.const 1061028 + local.set $p0 + loop $L53 + local.get $p0 + i32.load + local.tee $l8 + local.get $l3 + i32.le_u + if $I54 + local.get $l8 + local.get $p0 + i32.load offset=4 + i32.add + local.get $l3 + i32.gt_u + br_if $B51 + end + local.get $p0 + i32.load offset=8 + local.tee $p0 + br_if $L53 + end + end + i32.const 0 + call $f153 + local.tee $l1 + i32.const -1 + i32.eq + br_if $B6 + local.get $l2 + local.set $l5 + i32.const 1061056 + i32.load + local.tee $p0 + i32.const -1 + i32.add + local.tee $l3 + local.get $l1 + i32.and + if $I55 + local.get $l2 + local.get $l1 + i32.sub + local.get $l1 + local.get $l3 + i32.add + i32.const 0 + local.get $p0 + i32.sub + i32.and + i32.add + local.set $l5 + end + local.get $l5 + local.get $l6 + i32.le_u + local.get $l5 + i32.const 2147483646 + i32.gt_u + i32.or + br_if $B6 + i32.const 1061020 + i32.load + local.tee $p0 + if $I56 + i32.const 1061012 + i32.load + local.tee $l3 + local.get $l5 + i32.add + local.tee $l7 + local.get $l3 + i32.le_u + local.get $l7 + local.get $p0 + i32.gt_u + i32.or + br_if $B6 + end + local.get $l5 + call $f153 + local.tee $p0 + local.get $l1 + i32.ne + br_if $B50 + br $B4 + end + local.get $l5 + local.get $l1 + i32.sub + local.get $l7 + i32.and + local.tee $l5 + i32.const 2147483646 + i32.gt_u + br_if $B6 + local.get $l5 + call $f153 + local.tee $l1 + local.get $p0 + i32.load + local.get $p0 + i32.load offset=4 + i32.add + i32.eq + br_if $B7 + local.get $l1 + local.set $p0 + end + local.get $l6 + i32.const 72 + i32.add + local.get $l5 + i32.le_u + local.get $l5 + i32.const 2147483646 + i32.gt_u + i32.or + local.get $p0 + local.tee $l1 + i32.const -1 + i32.eq + i32.or + i32.eqz + if $I57 + i32.const 1061060 + i32.load + local.tee $p0 + local.get $l4 + local.get $l5 + i32.sub + i32.add + i32.const 0 + local.get $p0 + i32.sub + i32.and + local.tee $p0 + i32.const 2147483646 + i32.gt_u + br_if $B4 + local.get $p0 + call $f153 + i32.const -1 + i32.ne + if $I58 + local.get $p0 + local.get $l5 + i32.add + local.set $l5 + br $B4 + end + i32.const 0 + local.get $l5 + i32.sub + call $f153 + drop + br $B6 + end + local.get $l1 + i32.const -1 + i32.ne + br_if $B4 + br $B6 + end + i32.const 0 + local.set $l3 + br $B1 + end + i32.const 0 + local.set $l1 + br $B2 + end + local.get $l1 + i32.const -1 + i32.ne + br_if $B4 + end + i32.const 1061024 + i32.const 1061024 + i32.load + i32.const 4 + i32.or + i32.store + end + local.get $l2 + i32.const 2147483646 + i32.gt_u + br_if $B3 + local.get $l2 + call $f153 + local.tee $l1 + i32.const 0 + call $f153 + local.tee $p0 + i32.ge_u + local.get $l1 + i32.const -1 + i32.eq + i32.or + local.get $p0 + i32.const -1 + i32.eq + i32.or + br_if $B3 + local.get $p0 + local.get $l1 + i32.sub + local.tee $l5 + local.get $l6 + i32.const 56 + i32.add + i32.le_u + br_if $B3 + end + i32.const 1061012 + i32.const 1061012 + i32.load + local.get $l5 + i32.add + local.tee $p0 + i32.store + local.get $p0 + i32.const 1061016 + i32.load + i32.gt_u + if $I59 + i32.const 1061016 + local.get $p0 + i32.store + end + block $B60 + block $B61 + block $B62 + i32.const 1060604 + i32.load + local.tee $l7 + if $I63 + i32.const 1061028 + local.set $p0 + loop $L64 + local.get $l1 + local.get $p0 + i32.load + local.tee $l2 + local.get $p0 + i32.load offset=4 + local.tee $l3 + i32.add + i32.eq + br_if $B62 + local.get $p0 + i32.load offset=8 + local.tee $p0 + br_if $L64 + end + br $B61 + end + i32.const 1060596 + i32.load + local.tee $p0 + i32.const 0 + local.get $l1 + local.get $p0 + i32.ge_u + select + i32.eqz + if $I65 + i32.const 1060596 + local.get $l1 + i32.store + end + i32.const 0 + local.set $p0 + i32.const 1061032 + local.get $l5 + i32.store + i32.const 1061028 + local.get $l1 + i32.store + i32.const 1060612 + i32.const -1 + i32.store + i32.const 1060616 + i32.const 1061052 + i32.load + i32.store + i32.const 1061040 + i32.const 0 + i32.store + loop $L66 + local.get $p0 + i32.const 1060628 + i32.add + local.get $p0 + i32.const 1060620 + i32.add + local.tee $l2 + i32.store + local.get $p0 + i32.const 1060632 + i32.add + local.get $l2 + i32.store + local.get $p0 + i32.const 8 + i32.add + local.tee $p0 + i32.const 256 + i32.ne + br_if $L66 + end + local.get $l1 + i32.const -8 + local.get $l1 + i32.sub + i32.const 15 + i32.and + i32.const 0 + local.get $l1 + i32.const 8 + i32.add + i32.const 15 + i32.and + select + local.tee $p0 + i32.add + local.tee $l2 + local.get $l5 + i32.const -56 + i32.add + local.tee $l3 + local.get $p0 + i32.sub + local.tee $p0 + i32.const 1 + i32.or + i32.store offset=4 + i32.const 1060608 + i32.const 1061068 + i32.load + i32.store + i32.const 1060592 + local.get $p0 + i32.store + i32.const 1060604 + local.get $l2 + i32.store + local.get $l1 + local.get $l3 + i32.add + i32.const 56 + i32.store offset=4 + br $B60 + end + local.get $p0 + i32.load8_u offset=12 + i32.const 8 + i32.and + local.get $l1 + local.get $l7 + i32.le_u + i32.or + local.get $l2 + local.get $l7 + i32.gt_u + i32.or + br_if $B61 + local.get $l7 + i32.const -8 + local.get $l7 + i32.sub + i32.const 15 + i32.and + i32.const 0 + local.get $l7 + i32.const 8 + i32.add + i32.const 15 + i32.and + select + local.tee $l1 + i32.add + local.tee $l2 + i32.const 1060592 + i32.load + local.get $l5 + i32.add + local.tee $l4 + local.get $l1 + i32.sub + local.tee $l1 + i32.const 1 + i32.or + i32.store offset=4 + local.get $p0 + local.get $l3 + local.get $l5 + i32.add + i32.store offset=4 + i32.const 1060608 + i32.const 1061068 + i32.load + i32.store + i32.const 1060592 + local.get $l1 + i32.store + i32.const 1060604 + local.get $l2 + i32.store + local.get $l4 + local.get $l7 + i32.add + i32.const 56 + i32.store offset=4 + br $B60 + end + local.get $l1 + i32.const 1060596 + i32.load + local.tee $l3 + i32.lt_u + if $I67 + i32.const 1060596 + local.get $l1 + i32.store + local.get $l1 + local.set $l3 + end + local.get $l1 + local.get $l5 + i32.add + local.set $l2 + i32.const 1061028 + local.set $p0 + block $B68 + block $B69 + block $B70 + block $B71 + block $B72 + block $B73 + loop $L74 + local.get $l2 + local.get $p0 + i32.load + i32.ne + if $I75 + local.get $p0 + i32.load offset=8 + local.tee $p0 + br_if $L74 + br $B73 + end + end + local.get $p0 + i32.load8_u offset=12 + i32.const 8 + i32.and + i32.eqz + br_if $B72 + end + i32.const 1061028 + local.set $p0 + loop $L76 + local.get $p0 + i32.load + local.tee $l2 + local.get $l7 + i32.le_u + if $I77 + local.get $l2 + local.get $p0 + i32.load offset=4 + i32.add + local.tee $l3 + local.get $l7 + i32.gt_u + br_if $B71 + end + local.get $p0 + i32.load offset=8 + local.set $p0 + br $L76 + end + unreachable + end + local.get $p0 + local.get $l1 + i32.store + local.get $p0 + local.get $p0 + i32.load offset=4 + local.get $l5 + i32.add + i32.store offset=4 + local.get $l1 + i32.const -8 + local.get $l1 + i32.sub + i32.const 15 + i32.and + i32.const 0 + local.get $l1 + i32.const 8 + i32.add + i32.const 15 + i32.and + select + i32.add + local.tee $l8 + local.get $l6 + i32.const 3 + i32.or + i32.store offset=4 + local.get $l2 + i32.const -8 + local.get $l2 + i32.sub + i32.const 15 + i32.and + i32.const 0 + local.get $l2 + i32.const 8 + i32.add + i32.const 15 + i32.and + select + i32.add + local.tee $l1 + local.get $l8 + i32.sub + local.get $l6 + i32.sub + local.set $p0 + local.get $l6 + local.get $l8 + i32.add + local.set $l4 + local.get $l1 + local.get $l7 + i32.eq + if $I78 + i32.const 1060604 + local.get $l4 + i32.store + i32.const 1060592 + i32.const 1060592 + i32.load + local.get $p0 + i32.add + local.tee $p0 + i32.store + local.get $l4 + local.get $p0 + i32.const 1 + i32.or + i32.store offset=4 + br $B69 + end + local.get $l1 + i32.const 1060600 + i32.load + i32.eq + if $I79 + i32.const 1060600 + local.get $l4 + i32.store + i32.const 1060588 + i32.const 1060588 + i32.load + local.get $p0 + i32.add + local.tee $p0 + i32.store + local.get $l4 + local.get $p0 + i32.const 1 + i32.or + i32.store offset=4 + local.get $p0 + local.get $l4 + i32.add + local.get $p0 + i32.store + br $B69 + end + local.get $l1 + i32.load offset=4 + local.tee $l6 + i32.const 3 + i32.and + i32.const 1 + i32.eq + if $I80 + local.get $l6 + i32.const -8 + i32.and + local.set $l9 + block $B81 + local.get $l6 + i32.const 255 + i32.le_u + if $I82 + local.get $l1 + i32.load offset=8 + local.tee $l3 + local.get $l6 + i32.const 3 + i32.shr_u + local.tee $l6 + i32.const 3 + i32.shl + i32.const 1060620 + i32.add + i32.ne + drop + local.get $l3 + local.get $l1 + i32.load offset=12 + local.tee $l2 + i32.eq + if $I83 + i32.const 1060580 + i32.const 1060580 + i32.load + i32.const -2 + local.get $l6 + i32.rotl + i32.and + i32.store + br $B81 + end + local.get $l2 + local.get $l3 + i32.store offset=8 + local.get $l3 + local.get $l2 + i32.store offset=12 + br $B81 + end + local.get $l1 + i32.load offset=24 + local.set $l7 + block $B84 + local.get $l1 + local.get $l1 + i32.load offset=12 + local.tee $l5 + i32.ne + if $I85 + local.get $l3 + local.get $l1 + i32.load offset=8 + local.tee $l2 + i32.le_u + if $I86 + local.get $l2 + i32.load offset=12 + drop + end + local.get $l5 + local.get $l2 + i32.store offset=8 + local.get $l2 + local.get $l5 + i32.store offset=12 + br $B84 + end + block $B87 + local.get $l1 + i32.const 20 + i32.add + local.tee $l2 + i32.load + local.tee $l6 + br_if $B87 + local.get $l1 + i32.const 16 + i32.add + local.tee $l2 + i32.load + local.tee $l6 + br_if $B87 + i32.const 0 + local.set $l5 + br $B84 + end + loop $L88 + local.get $l2 + local.set $l3 + local.get $l6 + local.tee $l5 + i32.const 20 + i32.add + local.tee $l2 + i32.load + local.tee $l6 + br_if $L88 + local.get $l5 + i32.const 16 + i32.add + local.set $l2 + local.get $l5 + i32.load offset=16 + local.tee $l6 + br_if $L88 + end + local.get $l3 + i32.const 0 + i32.store + end + local.get $l7 + i32.eqz + br_if $B81 + block $B89 + local.get $l1 + local.get $l1 + i32.load offset=28 + local.tee $l2 + i32.const 2 + i32.shl + i32.const 1060884 + i32.add + local.tee $l3 + i32.load + i32.eq + if $I90 + local.get $l3 + local.get $l5 + i32.store + local.get $l5 + br_if $B89 + i32.const 1060584 + i32.const 1060584 + i32.load + i32.const -2 + local.get $l2 + i32.rotl + i32.and + i32.store + br $B81 + end + local.get $l7 + i32.const 16 + i32.const 20 + local.get $l7 + i32.load offset=16 + local.get $l1 + i32.eq + select + i32.add + local.get $l5 + i32.store + local.get $l5 + i32.eqz + br_if $B81 + end + local.get $l5 + local.get $l7 + i32.store offset=24 + local.get $l1 + i32.load offset=16 + local.tee $l2 + if $I91 + local.get $l5 + local.get $l2 + i32.store offset=16 + local.get $l2 + local.get $l5 + i32.store offset=24 + end + local.get $l1 + i32.load offset=20 + local.tee $l2 + i32.eqz + br_if $B81 + local.get $l5 + i32.const 20 + i32.add + local.get $l2 + i32.store + local.get $l2 + local.get $l5 + i32.store offset=24 + end + local.get $l1 + local.get $l9 + i32.add + local.set $l1 + local.get $p0 + local.get $l9 + i32.add + local.set $p0 + end + local.get $l1 + local.get $l1 + i32.load offset=4 + i32.const -2 + i32.and + i32.store offset=4 + local.get $p0 + local.get $l4 + i32.add + local.get $p0 + i32.store + local.get $l4 + local.get $p0 + i32.const 1 + i32.or + i32.store offset=4 + local.get $p0 + i32.const 255 + i32.le_u + if $I92 + local.get $p0 + i32.const 3 + i32.shr_u + local.tee $l1 + i32.const 3 + i32.shl + i32.const 1060620 + i32.add + local.set $p0 + block $B93 (result i32) + i32.const 1060580 + i32.load + local.tee $l2 + i32.const 1 + local.get $l1 + i32.shl + local.tee $l1 + i32.and + i32.eqz + if $I94 + i32.const 1060580 + local.get $l1 + local.get $l2 + i32.or + i32.store + local.get $p0 + br $B93 + end + local.get $p0 + i32.load offset=8 + end + local.tee $l2 + local.get $l4 + i32.store offset=12 + local.get $p0 + local.get $l4 + i32.store offset=8 + local.get $l4 + local.get $p0 + i32.store offset=12 + local.get $l4 + local.get $l2 + i32.store offset=8 + br $B69 + end + local.get $l4 + block $B95 (result i32) + i32.const 0 + local.get $p0 + i32.const 8 + i32.shr_u + local.tee $l1 + i32.eqz + br_if $B95 + drop + i32.const 31 + local.get $p0 + i32.const 16777215 + i32.gt_u + br_if $B95 + drop + local.get $l1 + local.get $l1 + i32.const 1048320 + i32.add + i32.const 16 + i32.shr_u + i32.const 8 + i32.and + local.tee $l1 + i32.shl + local.tee $l2 + local.get $l2 + i32.const 520192 + i32.add + i32.const 16 + i32.shr_u + i32.const 4 + i32.and + local.tee $l2 + i32.shl + local.tee $l3 + local.get $l3 + i32.const 245760 + i32.add + i32.const 16 + i32.shr_u + i32.const 2 + i32.and + local.tee $l3 + i32.shl + i32.const 15 + i32.shr_u + local.get $l1 + local.get $l2 + i32.or + local.get $l3 + i32.or + i32.sub + local.tee $l1 + i32.const 1 + i32.shl + local.get $p0 + local.get $l1 + i32.const 21 + i32.add + i32.shr_u + i32.const 1 + i32.and + i32.or + i32.const 28 + i32.add + end + local.tee $l2 + i32.store offset=28 + local.get $l4 + i64.const 0 + i64.store offset=16 align=4 + local.get $l2 + i32.const 2 + i32.shl + i32.const 1060884 + i32.add + local.set $l1 + i32.const 1060584 + i32.load + local.tee $l3 + i32.const 1 + local.get $l2 + i32.shl + local.tee $l6 + i32.and + i32.eqz + if $I96 + local.get $l1 + local.get $l4 + i32.store + i32.const 1060584 + local.get $l3 + local.get $l6 + i32.or + i32.store + local.get $l4 + local.get $l1 + i32.store offset=24 + local.get $l4 + local.get $l4 + i32.store offset=8 + local.get $l4 + local.get $l4 + i32.store offset=12 + br $B69 + end + local.get $p0 + i32.const 0 + i32.const 25 + local.get $l2 + i32.const 1 + i32.shr_u + i32.sub + local.get $l2 + i32.const 31 + i32.eq + select + i32.shl + local.set $l2 + local.get $l1 + i32.load + local.set $l1 + loop $L97 + local.get $l1 + local.tee $l3 + i32.load offset=4 + i32.const -8 + i32.and + local.get $p0 + i32.eq + br_if $B70 + local.get $l2 + i32.const 29 + i32.shr_u + local.set $l1 + local.get $l2 + i32.const 1 + i32.shl + local.set $l2 + local.get $l3 + local.get $l1 + i32.const 4 + i32.and + i32.add + i32.const 16 + i32.add + local.tee $l6 + i32.load + local.tee $l1 + br_if $L97 + end + local.get $l6 + local.get $l4 + i32.store + local.get $l4 + local.get $l3 + i32.store offset=24 + local.get $l4 + local.get $l4 + i32.store offset=12 + local.get $l4 + local.get $l4 + i32.store offset=8 + br $B69 + end + local.get $l1 + i32.const -8 + local.get $l1 + i32.sub + i32.const 15 + i32.and + i32.const 0 + local.get $l1 + i32.const 8 + i32.add + i32.const 15 + i32.and + select + local.tee $p0 + i32.add + local.tee $l4 + local.get $l5 + i32.const -56 + i32.add + local.tee $l2 + local.get $p0 + i32.sub + local.tee $p0 + i32.const 1 + i32.or + i32.store offset=4 + local.get $l1 + local.get $l2 + i32.add + i32.const 56 + i32.store offset=4 + local.get $l7 + local.get $l3 + i32.const 55 + local.get $l3 + i32.sub + i32.const 15 + i32.and + i32.const 0 + local.get $l3 + i32.const -55 + i32.add + i32.const 15 + i32.and + select + i32.add + i32.const -63 + i32.add + local.tee $l2 + local.get $l2 + local.get $l7 + i32.const 16 + i32.add + i32.lt_u + select + local.tee $l2 + i32.const 35 + i32.store offset=4 + i32.const 1060608 + i32.const 1061068 + i32.load + i32.store + i32.const 1060592 + local.get $p0 + i32.store + i32.const 1060604 + local.get $l4 + i32.store + local.get $l2 + i32.const 16 + i32.add + i32.const 1061036 + i64.load align=4 + i64.store align=4 + local.get $l2 + i32.const 1061028 + i64.load align=4 + i64.store offset=8 align=4 + i32.const 1061036 + local.get $l2 + i32.const 8 + i32.add + i32.store + i32.const 1061032 + local.get $l5 + i32.store + i32.const 1061028 + local.get $l1 + i32.store + i32.const 1061040 + i32.const 0 + i32.store + local.get $l2 + i32.const 36 + i32.add + local.set $p0 + loop $L98 + local.get $p0 + i32.const 7 + i32.store + local.get $p0 + i32.const 4 + i32.add + local.tee $p0 + local.get $l3 + i32.lt_u + br_if $L98 + end + local.get $l2 + local.get $l7 + i32.eq + br_if $B60 + local.get $l2 + local.get $l2 + i32.load offset=4 + i32.const -2 + i32.and + i32.store offset=4 + local.get $l2 + local.get $l2 + local.get $l7 + i32.sub + local.tee $l3 + i32.store + local.get $l7 + local.get $l3 + i32.const 1 + i32.or + i32.store offset=4 + local.get $l3 + i32.const 255 + i32.le_u + if $I99 + local.get $l3 + i32.const 3 + i32.shr_u + local.tee $l1 + i32.const 3 + i32.shl + i32.const 1060620 + i32.add + local.set $p0 + block $B100 (result i32) + i32.const 1060580 + i32.load + local.tee $l2 + i32.const 1 + local.get $l1 + i32.shl + local.tee $l1 + i32.and + i32.eqz + if $I101 + i32.const 1060580 + local.get $l1 + local.get $l2 + i32.or + i32.store + local.get $p0 + br $B100 + end + local.get $p0 + i32.load offset=8 + end + local.tee $l4 + local.get $l7 + i32.store offset=12 + local.get $p0 + local.get $l7 + i32.store offset=8 + local.get $l7 + local.get $p0 + i32.store offset=12 + local.get $l7 + local.get $l4 + i32.store offset=8 + br $B60 + end + local.get $l7 + i64.const 0 + i64.store offset=16 align=4 + local.get $l7 + i32.const 28 + i32.add + block $B102 (result i32) + i32.const 0 + local.get $l3 + i32.const 8 + i32.shr_u + local.tee $l1 + i32.eqz + br_if $B102 + drop + i32.const 31 + local.get $l3 + i32.const 16777215 + i32.gt_u + br_if $B102 + drop + local.get $l1 + local.get $l1 + i32.const 1048320 + i32.add + i32.const 16 + i32.shr_u + i32.const 8 + i32.and + local.tee $p0 + i32.shl + local.tee $l1 + local.get $l1 + i32.const 520192 + i32.add + i32.const 16 + i32.shr_u + i32.const 4 + i32.and + local.tee $l1 + i32.shl + local.tee $l2 + local.get $l2 + i32.const 245760 + i32.add + i32.const 16 + i32.shr_u + i32.const 2 + i32.and + local.tee $l2 + i32.shl + i32.const 15 + i32.shr_u + local.get $p0 + local.get $l1 + i32.or + local.get $l2 + i32.or + i32.sub + local.tee $p0 + i32.const 1 + i32.shl + local.get $l3 + local.get $p0 + i32.const 21 + i32.add + i32.shr_u + i32.const 1 + i32.and + i32.or + i32.const 28 + i32.add + end + local.tee $p0 + i32.store + local.get $p0 + i32.const 2 + i32.shl + i32.const 1060884 + i32.add + local.set $l1 + i32.const 1060584 + i32.load + local.tee $l2 + i32.const 1 + local.get $p0 + i32.shl + local.tee $l4 + i32.and + i32.eqz + if $I103 + local.get $l1 + local.get $l7 + i32.store + i32.const 1060584 + local.get $l2 + local.get $l4 + i32.or + i32.store + local.get $l7 + i32.const 24 + i32.add + local.get $l1 + i32.store + local.get $l7 + local.get $l7 + i32.store offset=8 + local.get $l7 + local.get $l7 + i32.store offset=12 + br $B60 + end + local.get $l3 + i32.const 0 + i32.const 25 + local.get $p0 + i32.const 1 + i32.shr_u + i32.sub + local.get $p0 + i32.const 31 + i32.eq + select + i32.shl + local.set $p0 + local.get $l1 + i32.load + local.set $l1 + loop $L104 + local.get $l1 + local.tee $l2 + i32.load offset=4 + i32.const -8 + i32.and + local.get $l3 + i32.eq + br_if $B68 + local.get $p0 + i32.const 29 + i32.shr_u + local.set $l1 + local.get $p0 + i32.const 1 + i32.shl + local.set $p0 + local.get $l2 + local.get $l1 + i32.const 4 + i32.and + i32.add + i32.const 16 + i32.add + local.tee $l4 + i32.load + local.tee $l1 + br_if $L104 + end + local.get $l4 + local.get $l7 + i32.store + local.get $l7 + i32.const 24 + i32.add + local.get $l2 + i32.store + local.get $l7 + local.get $l7 + i32.store offset=12 + local.get $l7 + local.get $l7 + i32.store offset=8 + br $B60 + end + local.get $l3 + i32.load offset=8 + local.set $p0 + local.get $l3 + local.get $l4 + i32.store offset=8 + local.get $p0 + local.get $l4 + i32.store offset=12 + local.get $l4 + i32.const 0 + i32.store offset=24 + local.get $l4 + local.get $p0 + i32.store offset=8 + local.get $l4 + local.get $l3 + i32.store offset=12 + end + local.get $l8 + i32.const 8 + i32.add + local.set $p0 + br $B0 + end + local.get $l2 + i32.load offset=8 + local.set $p0 + local.get $l2 + local.get $l7 + i32.store offset=8 + local.get $p0 + local.get $l7 + i32.store offset=12 + local.get $l7 + i32.const 24 + i32.add + i32.const 0 + i32.store + local.get $l7 + local.get $p0 + i32.store offset=8 + local.get $l7 + local.get $l2 + i32.store offset=12 + end + i32.const 1060592 + i32.load + local.tee $l1 + local.get $l6 + i32.le_u + br_if $B3 + i32.const 1060604 + i32.load + local.tee $p0 + local.get $l6 + i32.add + local.tee $l2 + local.get $l1 + local.get $l6 + i32.sub + local.tee $l1 + i32.const 1 + i32.or + i32.store offset=4 + i32.const 1060592 + local.get $l1 + i32.store + i32.const 1060604 + local.get $l2 + i32.store + local.get $p0 + local.get $l6 + i32.const 3 + i32.or + i32.store offset=4 + local.get $p0 + i32.const 8 + i32.add + local.set $p0 + br $B0 + end + i32.const 0 + local.set $p0 + i32.const 1061076 + i32.const 48 + i32.store + br $B0 + end + block $B105 + local.get $l7 + i32.eqz + br_if $B105 + block $B106 + local.get $l3 + i32.load offset=28 + local.tee $p0 + i32.const 2 + i32.shl + i32.const 1060884 + i32.add + local.tee $l2 + i32.load + local.get $l3 + i32.eq + if $I107 + local.get $l2 + local.get $l1 + i32.store + local.get $l1 + br_if $B106 + i32.const 1060584 + local.get $l8 + i32.const -2 + local.get $p0 + i32.rotl + i32.and + local.tee $l8 + i32.store + br $B105 + end + local.get $l7 + i32.const 16 + i32.const 20 + local.get $l7 + i32.load offset=16 + local.get $l3 + i32.eq + select + i32.add + local.get $l1 + i32.store + local.get $l1 + i32.eqz + br_if $B105 + end + local.get $l1 + local.get $l7 + i32.store offset=24 + local.get $l3 + i32.load offset=16 + local.tee $p0 + if $I108 + local.get $l1 + local.get $p0 + i32.store offset=16 + local.get $p0 + local.get $l1 + i32.store offset=24 + end + local.get $l3 + i32.const 20 + i32.add + i32.load + local.tee $p0 + i32.eqz + br_if $B105 + local.get $l1 + i32.const 20 + i32.add + local.get $p0 + i32.store + local.get $p0 + local.get $l1 + i32.store offset=24 + end + block $B109 + local.get $l4 + i32.const 15 + i32.le_u + if $I110 + local.get $l3 + local.get $l4 + local.get $l6 + i32.add + local.tee $p0 + i32.const 3 + i32.or + i32.store offset=4 + local.get $p0 + local.get $l3 + i32.add + local.tee $p0 + local.get $p0 + i32.load offset=4 + i32.const 1 + i32.or + i32.store offset=4 + br $B109 + end + local.get $l3 + local.get $l6 + i32.add + local.tee $l5 + local.get $l4 + i32.const 1 + i32.or + i32.store offset=4 + local.get $l3 + local.get $l6 + i32.const 3 + i32.or + i32.store offset=4 + local.get $l4 + local.get $l5 + i32.add + local.get $l4 + i32.store + local.get $l4 + i32.const 255 + i32.le_u + if $I111 + local.get $l4 + i32.const 3 + i32.shr_u + local.tee $l1 + i32.const 3 + i32.shl + i32.const 1060620 + i32.add + local.set $p0 + block $B112 (result i32) + i32.const 1060580 + i32.load + local.tee $l2 + i32.const 1 + local.get $l1 + i32.shl + local.tee $l1 + i32.and + i32.eqz + if $I113 + i32.const 1060580 + local.get $l1 + local.get $l2 + i32.or + i32.store + local.get $p0 + br $B112 + end + local.get $p0 + i32.load offset=8 + end + local.tee $l2 + local.get $l5 + i32.store offset=12 + local.get $p0 + local.get $l5 + i32.store offset=8 + local.get $l5 + local.get $p0 + i32.store offset=12 + local.get $l5 + local.get $l2 + i32.store offset=8 + br $B109 + end + local.get $l5 + block $B114 (result i32) + i32.const 0 + local.get $l4 + i32.const 8 + i32.shr_u + local.tee $l1 + i32.eqz + br_if $B114 + drop + i32.const 31 + local.get $l4 + i32.const 16777215 + i32.gt_u + br_if $B114 + drop + local.get $l1 + local.get $l1 + i32.const 1048320 + i32.add + i32.const 16 + i32.shr_u + i32.const 8 + i32.and + local.tee $p0 + i32.shl + local.tee $l1 + local.get $l1 + i32.const 520192 + i32.add + i32.const 16 + i32.shr_u + i32.const 4 + i32.and + local.tee $l1 + i32.shl + local.tee $l2 + local.get $l2 + i32.const 245760 + i32.add + i32.const 16 + i32.shr_u + i32.const 2 + i32.and + local.tee $l2 + i32.shl + i32.const 15 + i32.shr_u + local.get $p0 + local.get $l1 + i32.or + local.get $l2 + i32.or + i32.sub + local.tee $p0 + i32.const 1 + i32.shl + local.get $l4 + local.get $p0 + i32.const 21 + i32.add + i32.shr_u + i32.const 1 + i32.and + i32.or + i32.const 28 + i32.add + end + local.tee $p0 + i32.store offset=28 + local.get $l5 + i64.const 0 + i64.store offset=16 align=4 + local.get $p0 + i32.const 2 + i32.shl + i32.const 1060884 + i32.add + local.set $l1 + local.get $l8 + i32.const 1 + local.get $p0 + i32.shl + local.tee $l2 + i32.and + i32.eqz + if $I115 + local.get $l1 + local.get $l5 + i32.store + i32.const 1060584 + local.get $l2 + local.get $l8 + i32.or + i32.store + local.get $l5 + local.get $l1 + i32.store offset=24 + local.get $l5 + local.get $l5 + i32.store offset=8 + local.get $l5 + local.get $l5 + i32.store offset=12 + br $B109 + end + local.get $l4 + i32.const 0 + i32.const 25 + local.get $p0 + i32.const 1 + i32.shr_u + i32.sub + local.get $p0 + i32.const 31 + i32.eq + select + i32.shl + local.set $p0 + local.get $l1 + i32.load + local.set $l6 + block $B116 + loop $L117 + local.get $l6 + local.tee $l1 + i32.load offset=4 + i32.const -8 + i32.and + local.get $l4 + i32.eq + br_if $B116 + local.get $p0 + i32.const 29 + i32.shr_u + local.set $l2 + local.get $p0 + i32.const 1 + i32.shl + local.set $p0 + local.get $l1 + local.get $l2 + i32.const 4 + i32.and + i32.add + i32.const 16 + i32.add + local.tee $l2 + i32.load + local.tee $l6 + br_if $L117 + end + local.get $l2 + local.get $l5 + i32.store + local.get $l5 + local.get $l1 + i32.store offset=24 + local.get $l5 + local.get $l5 + i32.store offset=12 + local.get $l5 + local.get $l5 + i32.store offset=8 + br $B109 + end + local.get $l1 + i32.load offset=8 + local.set $p0 + local.get $l1 + local.get $l5 + i32.store offset=8 + local.get $p0 + local.get $l5 + i32.store offset=12 + local.get $l5 + i32.const 0 + i32.store offset=24 + local.get $l5 + local.get $p0 + i32.store offset=8 + local.get $l5 + local.get $l1 + i32.store offset=12 + end + local.get $l3 + i32.const 8 + i32.add + local.set $p0 + br $B0 + end + block $B118 + local.get $l9 + i32.eqz + br_if $B118 + block $B119 + local.get $l1 + i32.load offset=28 + local.tee $p0 + i32.const 2 + i32.shl + i32.const 1060884 + i32.add + local.tee $l4 + i32.load + local.get $l1 + i32.eq + if $I120 + local.get $l4 + local.get $l3 + i32.store + local.get $l3 + br_if $B119 + i32.const 1060584 + local.get $l10 + i32.const -2 + local.get $p0 + i32.rotl + i32.and + i32.store + br $B118 + end + local.get $l9 + i32.const 16 + i32.const 20 + local.get $l9 + i32.load offset=16 + local.get $l1 + i32.eq + select + i32.add + local.get $l3 + i32.store + local.get $l3 + i32.eqz + br_if $B118 + end + local.get $l3 + local.get $l9 + i32.store offset=24 + local.get $l1 + i32.load offset=16 + local.tee $p0 + if $I121 + local.get $l3 + local.get $p0 + i32.store offset=16 + local.get $p0 + local.get $l3 + i32.store offset=24 + end + local.get $l1 + i32.const 20 + i32.add + i32.load + local.tee $p0 + i32.eqz + br_if $B118 + local.get $l3 + i32.const 20 + i32.add + local.get $p0 + i32.store + local.get $p0 + local.get $l3 + i32.store offset=24 + end + block $B122 + local.get $l2 + i32.const 15 + i32.le_u + if $I123 + local.get $l1 + local.get $l2 + local.get $l6 + i32.add + local.tee $p0 + i32.const 3 + i32.or + i32.store offset=4 + local.get $p0 + local.get $l1 + i32.add + local.tee $p0 + local.get $p0 + i32.load offset=4 + i32.const 1 + i32.or + i32.store offset=4 + br $B122 + end + local.get $l1 + local.get $l6 + i32.add + local.tee $l7 + local.get $l2 + i32.const 1 + i32.or + i32.store offset=4 + local.get $l1 + local.get $l6 + i32.const 3 + i32.or + i32.store offset=4 + local.get $l2 + local.get $l7 + i32.add + local.get $l2 + i32.store + local.get $l8 + if $I124 + local.get $l8 + i32.const 3 + i32.shr_u + local.tee $l3 + i32.const 3 + i32.shl + i32.const 1060620 + i32.add + local.set $p0 + i32.const 1060600 + i32.load + local.set $l4 + block $B125 (result i32) + i32.const 1 + local.get $l3 + i32.shl + local.tee $l3 + local.get $l5 + i32.and + i32.eqz + if $I126 + i32.const 1060580 + local.get $l3 + local.get $l5 + i32.or + i32.store + local.get $p0 + br $B125 + end + local.get $p0 + i32.load offset=8 + end + local.tee $l3 + local.get $l4 + i32.store offset=12 + local.get $p0 + local.get $l4 + i32.store offset=8 + local.get $l4 + local.get $p0 + i32.store offset=12 + local.get $l4 + local.get $l3 + i32.store offset=8 + end + i32.const 1060600 + local.get $l7 + i32.store + i32.const 1060588 + local.get $l2 + i32.store + end + local.get $l1 + i32.const 8 + i32.add + local.set $p0 + end + local.get $l11 + i32.const 16 + i32.add + global.set $g0 + local.get $p0) + (func $f145 (type $t2) (param $p0 i32) + (local $l1 i32) (local $l2 i32) (local $l3 i32) (local $l4 i32) (local $l5 i32) (local $l6 i32) (local $l7 i32) + block $B0 + local.get $p0 + i32.eqz + br_if $B0 + local.get $p0 + i32.const -8 + i32.add + local.tee $l3 + local.get $p0 + i32.const -4 + i32.add + i32.load + local.tee $l1 + i32.const -8 + i32.and + local.tee $p0 + i32.add + local.set $l5 + block $B1 + local.get $l1 + i32.const 1 + i32.and + br_if $B1 + local.get $l1 + i32.const 3 + i32.and + i32.eqz + br_if $B0 + local.get $l3 + local.get $l3 + i32.load + local.tee $l2 + i32.sub + local.tee $l3 + i32.const 1060596 + i32.load + local.tee $l4 + i32.lt_u + br_if $B0 + local.get $p0 + local.get $l2 + i32.add + local.set $p0 + local.get $l3 + i32.const 1060600 + i32.load + i32.ne + if $I2 + local.get $l2 + i32.const 255 + i32.le_u + if $I3 + local.get $l3 + i32.load offset=8 + local.tee $l4 + local.get $l2 + i32.const 3 + i32.shr_u + local.tee $l2 + i32.const 3 + i32.shl + i32.const 1060620 + i32.add + i32.ne + drop + local.get $l4 + local.get $l3 + i32.load offset=12 + local.tee $l1 + i32.eq + if $I4 + i32.const 1060580 + i32.const 1060580 + i32.load + i32.const -2 + local.get $l2 + i32.rotl + i32.and + i32.store + br $B1 + end + local.get $l1 + local.get $l4 + i32.store offset=8 + local.get $l4 + local.get $l1 + i32.store offset=12 + br $B1 + end + local.get $l3 + i32.load offset=24 + local.set $l6 + block $B5 + local.get $l3 + local.get $l3 + i32.load offset=12 + local.tee $l1 + i32.ne + if $I6 + local.get $l4 + local.get $l3 + i32.load offset=8 + local.tee $l2 + i32.le_u + if $I7 + local.get $l2 + i32.load offset=12 + drop + end + local.get $l1 + local.get $l2 + i32.store offset=8 + local.get $l2 + local.get $l1 + i32.store offset=12 + br $B5 + end + block $B8 + local.get $l3 + i32.const 20 + i32.add + local.tee $l2 + i32.load + local.tee $l4 + br_if $B8 + local.get $l3 + i32.const 16 + i32.add + local.tee $l2 + i32.load + local.tee $l4 + br_if $B8 + i32.const 0 + local.set $l1 + br $B5 + end + loop $L9 + local.get $l2 + local.set $l7 + local.get $l4 + local.tee $l1 + i32.const 20 + i32.add + local.tee $l2 + i32.load + local.tee $l4 + br_if $L9 + local.get $l1 + i32.const 16 + i32.add + local.set $l2 + local.get $l1 + i32.load offset=16 + local.tee $l4 + br_if $L9 + end + local.get $l7 + i32.const 0 + i32.store + end + local.get $l6 + i32.eqz + br_if $B1 + block $B10 + local.get $l3 + local.get $l3 + i32.load offset=28 + local.tee $l2 + i32.const 2 + i32.shl + i32.const 1060884 + i32.add + local.tee $l4 + i32.load + i32.eq + if $I11 + local.get $l4 + local.get $l1 + i32.store + local.get $l1 + br_if $B10 + i32.const 1060584 + i32.const 1060584 + i32.load + i32.const -2 + local.get $l2 + i32.rotl + i32.and + i32.store + br $B1 + end + local.get $l6 + i32.const 16 + i32.const 20 + local.get $l6 + i32.load offset=16 + local.get $l3 + i32.eq + select + i32.add + local.get $l1 + i32.store + local.get $l1 + i32.eqz + br_if $B1 + end + local.get $l1 + local.get $l6 + i32.store offset=24 + local.get $l3 + i32.load offset=16 + local.tee $l2 + if $I12 + local.get $l1 + local.get $l2 + i32.store offset=16 + local.get $l2 + local.get $l1 + i32.store offset=24 + end + local.get $l3 + i32.load offset=20 + local.tee $l2 + i32.eqz + br_if $B1 + local.get $l1 + i32.const 20 + i32.add + local.get $l2 + i32.store + local.get $l2 + local.get $l1 + i32.store offset=24 + br $B1 + end + local.get $l5 + i32.load offset=4 + local.tee $l1 + i32.const 3 + i32.and + i32.const 3 + i32.ne + br_if $B1 + local.get $l5 + local.get $l1 + i32.const -2 + i32.and + i32.store offset=4 + i32.const 1060588 + local.get $p0 + i32.store + local.get $p0 + local.get $l3 + i32.add + local.get $p0 + i32.store + local.get $l3 + local.get $p0 + i32.const 1 + i32.or + i32.store offset=4 + return + end + local.get $l5 + local.get $l3 + i32.le_u + br_if $B0 + local.get $l5 + i32.load offset=4 + local.tee $l1 + i32.const 1 + i32.and + i32.eqz + br_if $B0 + block $B13 + local.get $l1 + i32.const 2 + i32.and + i32.eqz + if $I14 + local.get $l5 + i32.const 1060604 + i32.load + i32.eq + if $I15 + i32.const 1060604 + local.get $l3 + i32.store + i32.const 1060592 + i32.const 1060592 + i32.load + local.get $p0 + i32.add + local.tee $p0 + i32.store + local.get $l3 + local.get $p0 + i32.const 1 + i32.or + i32.store offset=4 + local.get $l3 + i32.const 1060600 + i32.load + i32.ne + br_if $B0 + i32.const 1060588 + i32.const 0 + i32.store + i32.const 1060600 + i32.const 0 + i32.store + return + end + local.get $l5 + i32.const 1060600 + i32.load + i32.eq + if $I16 + i32.const 1060600 + local.get $l3 + i32.store + i32.const 1060588 + i32.const 1060588 + i32.load + local.get $p0 + i32.add + local.tee $p0 + i32.store + local.get $l3 + local.get $p0 + i32.const 1 + i32.or + i32.store offset=4 + local.get $p0 + local.get $l3 + i32.add + local.get $p0 + i32.store + return + end + local.get $l1 + i32.const -8 + i32.and + local.get $p0 + i32.add + local.set $p0 + block $B17 + local.get $l1 + i32.const 255 + i32.le_u + if $I18 + local.get $l5 + i32.load offset=12 + local.set $l2 + local.get $l5 + i32.load offset=8 + local.tee $l4 + local.get $l1 + i32.const 3 + i32.shr_u + local.tee $l1 + i32.const 3 + i32.shl + i32.const 1060620 + i32.add + local.tee $l7 + i32.ne + if $I19 + i32.const 1060596 + i32.load + drop + end + local.get $l2 + local.get $l4 + i32.eq + if $I20 + i32.const 1060580 + i32.const 1060580 + i32.load + i32.const -2 + local.get $l1 + i32.rotl + i32.and + i32.store + br $B17 + end + local.get $l2 + local.get $l7 + i32.ne + if $I21 + i32.const 1060596 + i32.load + drop + end + local.get $l2 + local.get $l4 + i32.store offset=8 + local.get $l4 + local.get $l2 + i32.store offset=12 + br $B17 + end + local.get $l5 + i32.load offset=24 + local.set $l6 + block $B22 + local.get $l5 + local.get $l5 + i32.load offset=12 + local.tee $l1 + i32.ne + if $I23 + i32.const 1060596 + i32.load + local.get $l5 + i32.load offset=8 + local.tee $l2 + i32.le_u + if $I24 + local.get $l2 + i32.load offset=12 + drop + end + local.get $l1 + local.get $l2 + i32.store offset=8 + local.get $l2 + local.get $l1 + i32.store offset=12 + br $B22 + end + block $B25 + local.get $l5 + i32.const 20 + i32.add + local.tee $l2 + i32.load + local.tee $l4 + br_if $B25 + local.get $l5 + i32.const 16 + i32.add + local.tee $l2 + i32.load + local.tee $l4 + br_if $B25 + i32.const 0 + local.set $l1 + br $B22 + end + loop $L26 + local.get $l2 + local.set $l7 + local.get $l4 + local.tee $l1 + i32.const 20 + i32.add + local.tee $l2 + i32.load + local.tee $l4 + br_if $L26 + local.get $l1 + i32.const 16 + i32.add + local.set $l2 + local.get $l1 + i32.load offset=16 + local.tee $l4 + br_if $L26 + end + local.get $l7 + i32.const 0 + i32.store + end + local.get $l6 + i32.eqz + br_if $B17 + block $B27 + local.get $l5 + local.get $l5 + i32.load offset=28 + local.tee $l2 + i32.const 2 + i32.shl + i32.const 1060884 + i32.add + local.tee $l4 + i32.load + i32.eq + if $I28 + local.get $l4 + local.get $l1 + i32.store + local.get $l1 + br_if $B27 + i32.const 1060584 + i32.const 1060584 + i32.load + i32.const -2 + local.get $l2 + i32.rotl + i32.and + i32.store + br $B17 + end + local.get $l6 + i32.const 16 + i32.const 20 + local.get $l6 + i32.load offset=16 + local.get $l5 + i32.eq + select + i32.add + local.get $l1 + i32.store + local.get $l1 + i32.eqz + br_if $B17 + end + local.get $l1 + local.get $l6 + i32.store offset=24 + local.get $l5 + i32.load offset=16 + local.tee $l2 + if $I29 + local.get $l1 + local.get $l2 + i32.store offset=16 + local.get $l2 + local.get $l1 + i32.store offset=24 + end + local.get $l5 + i32.load offset=20 + local.tee $l2 + i32.eqz + br_if $B17 + local.get $l1 + i32.const 20 + i32.add + local.get $l2 + i32.store + local.get $l2 + local.get $l1 + i32.store offset=24 + end + local.get $p0 + local.get $l3 + i32.add + local.get $p0 + i32.store + local.get $l3 + local.get $p0 + i32.const 1 + i32.or + i32.store offset=4 + local.get $l3 + i32.const 1060600 + i32.load + i32.ne + br_if $B13 + i32.const 1060588 + local.get $p0 + i32.store + return + end + local.get $l5 + local.get $l1 + i32.const -2 + i32.and + i32.store offset=4 + local.get $p0 + local.get $l3 + i32.add + local.get $p0 + i32.store + local.get $l3 + local.get $p0 + i32.const 1 + i32.or + i32.store offset=4 + end + local.get $p0 + i32.const 255 + i32.le_u + if $I30 + local.get $p0 + i32.const 3 + i32.shr_u + local.tee $l1 + i32.const 3 + i32.shl + i32.const 1060620 + i32.add + local.set $p0 + block $B31 (result i32) + i32.const 1060580 + i32.load + local.tee $l2 + i32.const 1 + local.get $l1 + i32.shl + local.tee $l1 + i32.and + i32.eqz + if $I32 + i32.const 1060580 + local.get $l1 + local.get $l2 + i32.or + i32.store + local.get $p0 + br $B31 + end + local.get $p0 + i32.load offset=8 + end + local.tee $l2 + local.get $l3 + i32.store offset=12 + local.get $p0 + local.get $l3 + i32.store offset=8 + local.get $l3 + local.get $p0 + i32.store offset=12 + local.get $l3 + local.get $l2 + i32.store offset=8 + return + end + local.get $l3 + i64.const 0 + i64.store offset=16 align=4 + local.get $l3 + i32.const 28 + i32.add + block $B33 (result i32) + i32.const 0 + local.get $p0 + i32.const 8 + i32.shr_u + local.tee $l1 + i32.eqz + br_if $B33 + drop + i32.const 31 + local.get $p0 + i32.const 16777215 + i32.gt_u + br_if $B33 + drop + local.get $l1 + local.get $l1 + i32.const 1048320 + i32.add + i32.const 16 + i32.shr_u + i32.const 8 + i32.and + local.tee $l1 + i32.shl + local.tee $l2 + local.get $l2 + i32.const 520192 + i32.add + i32.const 16 + i32.shr_u + i32.const 4 + i32.and + local.tee $l2 + i32.shl + local.tee $l4 + local.get $l4 + i32.const 245760 + i32.add + i32.const 16 + i32.shr_u + i32.const 2 + i32.and + local.tee $l4 + i32.shl + i32.const 15 + i32.shr_u + local.get $l1 + local.get $l2 + i32.or + local.get $l4 + i32.or + i32.sub + local.tee $l1 + i32.const 1 + i32.shl + local.get $p0 + local.get $l1 + i32.const 21 + i32.add + i32.shr_u + i32.const 1 + i32.and + i32.or + i32.const 28 + i32.add + end + local.tee $l2 + i32.store + local.get $l2 + i32.const 2 + i32.shl + i32.const 1060884 + i32.add + local.set $l1 + block $B34 + i32.const 1060584 + i32.load + local.tee $l4 + i32.const 1 + local.get $l2 + i32.shl + local.tee $l7 + i32.and + i32.eqz + if $I35 + local.get $l1 + local.get $l3 + i32.store + i32.const 1060584 + local.get $l4 + local.get $l7 + i32.or + i32.store + local.get $l3 + i32.const 24 + i32.add + local.get $l1 + i32.store + local.get $l3 + local.get $l3 + i32.store offset=8 + local.get $l3 + local.get $l3 + i32.store offset=12 + br $B34 + end + local.get $p0 + i32.const 0 + i32.const 25 + local.get $l2 + i32.const 1 + i32.shr_u + i32.sub + local.get $l2 + i32.const 31 + i32.eq + select + i32.shl + local.set $l2 + local.get $l1 + i32.load + local.set $l1 + block $B36 + loop $L37 + local.get $l1 + local.tee $l4 + i32.load offset=4 + i32.const -8 + i32.and + local.get $p0 + i32.eq + br_if $B36 + local.get $l2 + i32.const 29 + i32.shr_u + local.set $l1 + local.get $l2 + i32.const 1 + i32.shl + local.set $l2 + local.get $l4 + local.get $l1 + i32.const 4 + i32.and + i32.add + i32.const 16 + i32.add + local.tee $l7 + i32.load + local.tee $l1 + br_if $L37 + end + local.get $l7 + local.get $l3 + i32.store + local.get $l3 + local.get $l3 + i32.store offset=12 + local.get $l3 + i32.const 24 + i32.add + local.get $l4 + i32.store + local.get $l3 + local.get $l3 + i32.store offset=8 + br $B34 + end + local.get $l4 + i32.load offset=8 + local.set $p0 + local.get $l4 + local.get $l3 + i32.store offset=8 + local.get $p0 + local.get $l3 + i32.store offset=12 + local.get $l3 + i32.const 24 + i32.add + i32.const 0 + i32.store + local.get $l3 + local.get $p0 + i32.store offset=8 + local.get $l3 + local.get $l4 + i32.store offset=12 + end + i32.const 1060612 + i32.const 1060612 + i32.load + i32.const -1 + i32.add + local.tee $p0 + i32.store + local.get $p0 + br_if $B0 + i32.const 1061036 + local.set $l3 + loop $L38 + local.get $l3 + i32.load + local.tee $p0 + i32.const 8 + i32.add + local.set $l3 + local.get $p0 + br_if $L38 + end + i32.const 1060612 + i32.const -1 + i32.store + end) + (func $f146 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + (local $l2 i32) + block $B0 + block $B1 (result i32) + i32.const 0 + local.get $p0 + i32.eqz + br_if $B1 + drop + local.get $p0 + local.get $p1 + i32.mul + local.tee $l2 + local.get $p0 + local.get $p1 + i32.or + i32.const 65536 + i32.lt_u + br_if $B1 + drop + local.get $l2 + i32.const -1 + local.get $l2 + local.get $p0 + i32.div_u + local.get $p1 + i32.eq + select + end + local.tee $l2 + call $f144 + local.tee $p0 + i32.eqz + br_if $B0 + local.get $p0 + i32.const -4 + i32.add + i32.load8_u + i32.const 3 + i32.and + i32.eqz + br_if $B0 + local.get $p0 + local.get $l2 + call $f166 + drop + end + local.get $p0) + (func $f147 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + (local $l2 i32) (local $l3 i32) (local $l4 i32) (local $l5 i32) (local $l6 i32) (local $l7 i32) (local $l8 i32) (local $l9 i32) (local $l10 i32) (local $l11 i32) (local $l12 i32) + local.get $p0 + i32.eqz + if $I0 + local.get $p1 + call $f144 + return + end + local.get $p1 + i32.const -64 + i32.ge_u + if $I1 + i32.const 1061076 + i32.const 48 + i32.store + i32.const 0 + return + end + local.get $p0 + i32.const -8 + i32.add + local.set $l6 + i32.const 1060596 + i32.load + local.set $l11 + local.get $p0 + i32.const -4 + i32.add + local.tee $l7 + i32.load + local.tee $l8 + i32.const 3 + i32.and + local.tee $l5 + i32.const 1 + i32.eq + local.get $l8 + i32.const -8 + i32.and + local.tee $l2 + i32.const 1 + i32.lt_s + i32.or + drop + i32.const 16 + local.get $p1 + i32.const 19 + i32.add + i32.const -16 + i32.and + local.get $p1 + i32.const 11 + i32.lt_u + select + local.set $l3 + block $B2 + block $B3 + local.get $l5 + i32.eqz + if $I4 + local.get $l3 + i32.const 256 + i32.lt_u + local.get $l2 + local.get $l3 + i32.const 4 + i32.or + i32.lt_u + i32.or + br_if $B3 + local.get $l2 + local.get $l3 + i32.sub + i32.const 1061060 + i32.load + i32.const 1 + i32.shl + i32.le_u + br_if $B2 + br $B3 + end + local.get $l2 + local.get $l6 + i32.add + local.set $l4 + local.get $l2 + local.get $l3 + i32.ge_u + if $I5 + local.get $l2 + local.get $l3 + i32.sub + local.tee $p1 + i32.const 16 + i32.lt_u + br_if $B2 + local.get $l7 + local.get $l3 + local.get $l8 + i32.const 1 + i32.and + i32.or + i32.const 2 + i32.or + i32.store + local.get $l3 + local.get $l6 + i32.add + local.tee $l2 + local.get $p1 + i32.const 3 + i32.or + i32.store offset=4 + local.get $l4 + local.get $l4 + i32.load offset=4 + i32.const 1 + i32.or + i32.store offset=4 + local.get $l2 + local.get $p1 + call $f148 + local.get $p0 + return + end + local.get $l4 + i32.const 1060604 + i32.load + i32.eq + if $I6 + i32.const 1060592 + i32.load + local.get $l2 + i32.add + local.tee $l2 + local.get $l3 + i32.le_u + br_if $B3 + local.get $l7 + local.get $l3 + local.get $l8 + i32.const 1 + i32.and + i32.or + i32.const 2 + i32.or + i32.store + i32.const 1060604 + local.get $l3 + local.get $l6 + i32.add + local.tee $p1 + i32.store + i32.const 1060592 + local.get $l2 + local.get $l3 + i32.sub + local.tee $l2 + i32.store + local.get $p1 + local.get $l2 + i32.const 1 + i32.or + i32.store offset=4 + local.get $p0 + return + end + local.get $l4 + i32.const 1060600 + i32.load + i32.eq + if $I7 + i32.const 1060588 + i32.load + local.get $l2 + i32.add + local.tee $l2 + local.get $l3 + i32.lt_u + br_if $B3 + block $B8 + local.get $l2 + local.get $l3 + i32.sub + local.tee $p1 + i32.const 16 + i32.ge_u + if $I9 + local.get $l7 + local.get $l3 + local.get $l8 + i32.const 1 + i32.and + i32.or + i32.const 2 + i32.or + i32.store + local.get $l3 + local.get $l6 + i32.add + local.tee $l5 + local.get $p1 + i32.const 1 + i32.or + i32.store offset=4 + local.get $l2 + local.get $l6 + i32.add + local.tee $l2 + local.get $p1 + i32.store + local.get $l2 + local.get $l2 + i32.load offset=4 + i32.const -2 + i32.and + i32.store offset=4 + br $B8 + end + local.get $l7 + local.get $l8 + i32.const 1 + i32.and + local.get $l2 + i32.or + i32.const 2 + i32.or + i32.store + local.get $l2 + local.get $l6 + i32.add + local.tee $p1 + local.get $p1 + i32.load offset=4 + i32.const 1 + i32.or + i32.store offset=4 + i32.const 0 + local.set $p1 + i32.const 0 + local.set $l5 + end + i32.const 1060600 + local.get $l5 + i32.store + i32.const 1060588 + local.get $p1 + i32.store + local.get $p0 + return + end + local.get $l4 + i32.load offset=4 + local.tee $l5 + i32.const 2 + i32.and + br_if $B3 + local.get $l5 + i32.const -8 + i32.and + local.get $l2 + i32.add + local.tee $l9 + local.get $l3 + i32.lt_u + br_if $B3 + local.get $l9 + local.get $l3 + i32.sub + local.set $l12 + block $B10 + local.get $l5 + i32.const 255 + i32.le_u + if $I11 + local.get $l4 + i32.load offset=8 + local.tee $l2 + local.get $l5 + i32.const 3 + i32.shr_u + local.tee $l5 + i32.const 3 + i32.shl + i32.const 1060620 + i32.add + i32.ne + drop + local.get $l2 + local.get $l4 + i32.load offset=12 + local.tee $p1 + i32.eq + if $I12 + i32.const 1060580 + i32.const 1060580 + i32.load + i32.const -2 + local.get $l5 + i32.rotl + i32.and + i32.store + br $B10 + end + local.get $p1 + local.get $l2 + i32.store offset=8 + local.get $l2 + local.get $p1 + i32.store offset=12 + br $B10 + end + local.get $l4 + i32.load offset=24 + local.set $l10 + block $B13 + local.get $l4 + local.get $l4 + i32.load offset=12 + local.tee $l2 + i32.ne + if $I14 + local.get $l11 + local.get $l4 + i32.load offset=8 + local.tee $p1 + i32.le_u + if $I15 + local.get $p1 + i32.load offset=12 + drop + end + local.get $l2 + local.get $p1 + i32.store offset=8 + local.get $p1 + local.get $l2 + i32.store offset=12 + br $B13 + end + block $B16 + local.get $l4 + i32.const 20 + i32.add + local.tee $p1 + i32.load + local.tee $l5 + br_if $B16 + local.get $l4 + i32.const 16 + i32.add + local.tee $p1 + i32.load + local.tee $l5 + br_if $B16 + i32.const 0 + local.set $l2 + br $B13 + end + loop $L17 + local.get $p1 + local.set $l11 + local.get $l5 + local.tee $l2 + i32.const 20 + i32.add + local.tee $p1 + i32.load + local.tee $l5 + br_if $L17 + local.get $l2 + i32.const 16 + i32.add + local.set $p1 + local.get $l2 + i32.load offset=16 + local.tee $l5 + br_if $L17 + end + local.get $l11 + i32.const 0 + i32.store + end + local.get $l10 + i32.eqz + br_if $B10 + block $B18 + local.get $l4 + local.get $l4 + i32.load offset=28 + local.tee $p1 + i32.const 2 + i32.shl + i32.const 1060884 + i32.add + local.tee $l5 + i32.load + i32.eq + if $I19 + local.get $l5 + local.get $l2 + i32.store + local.get $l2 + br_if $B18 + i32.const 1060584 + i32.const 1060584 + i32.load + i32.const -2 + local.get $p1 + i32.rotl + i32.and + i32.store + br $B10 + end + local.get $l10 + i32.const 16 + i32.const 20 + local.get $l10 + i32.load offset=16 + local.get $l4 + i32.eq + select + i32.add + local.get $l2 + i32.store + local.get $l2 + i32.eqz + br_if $B10 + end + local.get $l2 + local.get $l10 + i32.store offset=24 + local.get $l4 + i32.load offset=16 + local.tee $p1 + if $I20 + local.get $l2 + local.get $p1 + i32.store offset=16 + local.get $p1 + local.get $l2 + i32.store offset=24 + end + local.get $l4 + i32.load offset=20 + local.tee $p1 + i32.eqz + br_if $B10 + local.get $l2 + i32.const 20 + i32.add + local.get $p1 + i32.store + local.get $p1 + local.get $l2 + i32.store offset=24 + end + local.get $l12 + i32.const 15 + i32.le_u + if $I21 + local.get $l7 + local.get $l8 + i32.const 1 + i32.and + local.get $l9 + i32.or + i32.const 2 + i32.or + i32.store + local.get $l6 + local.get $l9 + i32.add + local.tee $p1 + local.get $p1 + i32.load offset=4 + i32.const 1 + i32.or + i32.store offset=4 + local.get $p0 + return + end + local.get $l7 + local.get $l3 + local.get $l8 + i32.const 1 + i32.and + i32.or + i32.const 2 + i32.or + i32.store + local.get $l3 + local.get $l6 + i32.add + local.tee $p1 + local.get $l12 + i32.const 3 + i32.or + i32.store offset=4 + local.get $l6 + local.get $l9 + i32.add + local.tee $l2 + local.get $l2 + i32.load offset=4 + i32.const 1 + i32.or + i32.store offset=4 + local.get $p1 + local.get $l12 + call $f148 + local.get $p0 + return + end + local.get $p1 + call $f144 + local.tee $l2 + i32.eqz + if $I22 + i32.const 0 + return + end + local.get $l2 + local.get $p0 + local.get $l7 + i32.load + local.tee $l2 + i32.const -8 + i32.and + i32.const 4 + i32.const 8 + local.get $l2 + i32.const 3 + i32.and + select + i32.sub + local.tee $l2 + local.get $p1 + local.get $l2 + local.get $p1 + i32.lt_u + select + call $f162 + local.get $p0 + call $f145 + local.set $p0 + end + local.get $p0) + (func $f148 (type $t3) (param $p0 i32) (param $p1 i32) + (local $l2 i32) (local $l3 i32) (local $l4 i32) (local $l5 i32) (local $l6 i32) (local $l7 i32) + local.get $p0 + local.get $p1 + i32.add + local.set $l5 + block $B0 + block $B1 + local.get $p0 + i32.load offset=4 + local.tee $l2 + i32.const 1 + i32.and + br_if $B1 + local.get $l2 + i32.const 3 + i32.and + i32.eqz + br_if $B0 + local.get $p0 + i32.load + local.tee $l3 + local.get $p1 + i32.add + local.set $p1 + local.get $p0 + local.get $l3 + i32.sub + local.tee $p0 + i32.const 1060600 + i32.load + i32.ne + if $I2 + i32.const 1060596 + i32.load + local.set $l4 + local.get $l3 + i32.const 255 + i32.le_u + if $I3 + local.get $p0 + i32.load offset=8 + local.tee $l4 + local.get $l3 + i32.const 3 + i32.shr_u + local.tee $l3 + i32.const 3 + i32.shl + i32.const 1060620 + i32.add + i32.ne + drop + local.get $l4 + local.get $p0 + i32.load offset=12 + local.tee $l2 + i32.eq + if $I4 + i32.const 1060580 + i32.const 1060580 + i32.load + i32.const -2 + local.get $l3 + i32.rotl + i32.and + i32.store + br $B1 + end + local.get $l2 + local.get $l4 + i32.store offset=8 + local.get $l4 + local.get $l2 + i32.store offset=12 + br $B1 + end + local.get $p0 + i32.load offset=24 + local.set $l6 + block $B5 + local.get $p0 + local.get $p0 + i32.load offset=12 + local.tee $l2 + i32.ne + if $I6 + local.get $l4 + local.get $p0 + i32.load offset=8 + local.tee $l3 + i32.le_u + if $I7 + local.get $l3 + i32.load offset=12 + drop + end + local.get $l2 + local.get $l3 + i32.store offset=8 + local.get $l3 + local.get $l2 + i32.store offset=12 + br $B5 + end + block $B8 + local.get $p0 + i32.const 20 + i32.add + local.tee $l3 + i32.load + local.tee $l4 + br_if $B8 + local.get $p0 + i32.const 16 + i32.add + local.tee $l3 + i32.load + local.tee $l4 + br_if $B8 + i32.const 0 + local.set $l2 + br $B5 + end + loop $L9 + local.get $l3 + local.set $l7 + local.get $l4 + local.tee $l2 + i32.const 20 + i32.add + local.tee $l3 + i32.load + local.tee $l4 + br_if $L9 + local.get $l2 + i32.const 16 + i32.add + local.set $l3 + local.get $l2 + i32.load offset=16 + local.tee $l4 + br_if $L9 + end + local.get $l7 + i32.const 0 + i32.store + end + local.get $l6 + i32.eqz + br_if $B1 + block $B10 + local.get $p0 + local.get $p0 + i32.load offset=28 + local.tee $l3 + i32.const 2 + i32.shl + i32.const 1060884 + i32.add + local.tee $l4 + i32.load + i32.eq + if $I11 + local.get $l4 + local.get $l2 + i32.store + local.get $l2 + br_if $B10 + i32.const 1060584 + i32.const 1060584 + i32.load + i32.const -2 + local.get $l3 + i32.rotl + i32.and + i32.store + br $B1 + end + local.get $l6 + i32.const 16 + i32.const 20 + local.get $l6 + i32.load offset=16 + local.get $p0 + i32.eq + select + i32.add + local.get $l2 + i32.store + local.get $l2 + i32.eqz + br_if $B1 + end + local.get $l2 + local.get $l6 + i32.store offset=24 + local.get $p0 + i32.load offset=16 + local.tee $l3 + if $I12 + local.get $l2 + local.get $l3 + i32.store offset=16 + local.get $l3 + local.get $l2 + i32.store offset=24 + end + local.get $p0 + i32.load offset=20 + local.tee $l3 + i32.eqz + br_if $B1 + local.get $l2 + i32.const 20 + i32.add + local.get $l3 + i32.store + local.get $l3 + local.get $l2 + i32.store offset=24 + br $B1 + end + local.get $l5 + i32.load offset=4 + local.tee $l2 + i32.const 3 + i32.and + i32.const 3 + i32.ne + br_if $B1 + local.get $l5 + local.get $l2 + i32.const -2 + i32.and + i32.store offset=4 + i32.const 1060588 + local.get $p1 + i32.store + local.get $l5 + local.get $p1 + i32.store + local.get $p0 + local.get $p1 + i32.const 1 + i32.or + i32.store offset=4 + return + end + block $B13 + local.get $l5 + i32.load offset=4 + local.tee $l2 + i32.const 2 + i32.and + i32.eqz + if $I14 + local.get $l5 + i32.const 1060604 + i32.load + i32.eq + if $I15 + i32.const 1060604 + local.get $p0 + i32.store + i32.const 1060592 + i32.const 1060592 + i32.load + local.get $p1 + i32.add + local.tee $p1 + i32.store + local.get $p0 + local.get $p1 + i32.const 1 + i32.or + i32.store offset=4 + local.get $p0 + i32.const 1060600 + i32.load + i32.ne + br_if $B0 + i32.const 1060588 + i32.const 0 + i32.store + i32.const 1060600 + i32.const 0 + i32.store + return + end + local.get $l5 + i32.const 1060600 + i32.load + i32.eq + if $I16 + i32.const 1060600 + local.get $p0 + i32.store + i32.const 1060588 + i32.const 1060588 + i32.load + local.get $p1 + i32.add + local.tee $p1 + i32.store + local.get $p0 + local.get $p1 + i32.const 1 + i32.or + i32.store offset=4 + local.get $p0 + local.get $p1 + i32.add + local.get $p1 + i32.store + return + end + i32.const 1060596 + i32.load + local.set $l3 + local.get $l2 + i32.const -8 + i32.and + local.get $p1 + i32.add + local.set $p1 + block $B17 + local.get $l2 + i32.const 255 + i32.le_u + if $I18 + local.get $l5 + i32.load offset=8 + local.tee $l4 + local.get $l2 + i32.const 3 + i32.shr_u + local.tee $l2 + i32.const 3 + i32.shl + i32.const 1060620 + i32.add + i32.ne + drop + local.get $l4 + local.get $l5 + i32.load offset=12 + local.tee $l3 + i32.eq + if $I19 + i32.const 1060580 + i32.const 1060580 + i32.load + i32.const -2 + local.get $l2 + i32.rotl + i32.and + i32.store + br $B17 + end + local.get $l3 + local.get $l4 + i32.store offset=8 + local.get $l4 + local.get $l3 + i32.store offset=12 + br $B17 + end + local.get $l5 + i32.load offset=24 + local.set $l6 + block $B20 + local.get $l5 + local.get $l5 + i32.load offset=12 + local.tee $l2 + i32.ne + if $I21 + local.get $l3 + local.get $l5 + i32.load offset=8 + local.tee $l3 + i32.le_u + if $I22 + local.get $l3 + i32.load offset=12 + drop + end + local.get $l2 + local.get $l3 + i32.store offset=8 + local.get $l3 + local.get $l2 + i32.store offset=12 + br $B20 + end + block $B23 + local.get $l5 + i32.const 20 + i32.add + local.tee $l3 + i32.load + local.tee $l4 + br_if $B23 + local.get $l5 + i32.const 16 + i32.add + local.tee $l3 + i32.load + local.tee $l4 + br_if $B23 + i32.const 0 + local.set $l2 + br $B20 + end + loop $L24 + local.get $l3 + local.set $l7 + local.get $l4 + local.tee $l2 + i32.const 20 + i32.add + local.tee $l3 + i32.load + local.tee $l4 + br_if $L24 + local.get $l2 + i32.const 16 + i32.add + local.set $l3 + local.get $l2 + i32.load offset=16 + local.tee $l4 + br_if $L24 + end + local.get $l7 + i32.const 0 + i32.store + end + local.get $l6 + i32.eqz + br_if $B17 + block $B25 + local.get $l5 + local.get $l5 + i32.load offset=28 + local.tee $l3 + i32.const 2 + i32.shl + i32.const 1060884 + i32.add + local.tee $l4 + i32.load + i32.eq + if $I26 + local.get $l4 + local.get $l2 + i32.store + local.get $l2 + br_if $B25 + i32.const 1060584 + i32.const 1060584 + i32.load + i32.const -2 + local.get $l3 + i32.rotl + i32.and + i32.store + br $B17 + end + local.get $l6 + i32.const 16 + i32.const 20 + local.get $l6 + i32.load offset=16 + local.get $l5 + i32.eq + select + i32.add + local.get $l2 + i32.store + local.get $l2 + i32.eqz + br_if $B17 + end + local.get $l2 + local.get $l6 + i32.store offset=24 + local.get $l5 + i32.load offset=16 + local.tee $l3 + if $I27 + local.get $l2 + local.get $l3 + i32.store offset=16 + local.get $l3 + local.get $l2 + i32.store offset=24 + end + local.get $l5 + i32.load offset=20 + local.tee $l3 + i32.eqz + br_if $B17 + local.get $l2 + i32.const 20 + i32.add + local.get $l3 + i32.store + local.get $l3 + local.get $l2 + i32.store offset=24 + end + local.get $p0 + local.get $p1 + i32.add + local.get $p1 + i32.store + local.get $p0 + local.get $p1 + i32.const 1 + i32.or + i32.store offset=4 + local.get $p0 + i32.const 1060600 + i32.load + i32.ne + br_if $B13 + i32.const 1060588 + local.get $p1 + i32.store + return + end + local.get $l5 + local.get $l2 + i32.const -2 + i32.and + i32.store offset=4 + local.get $p0 + local.get $p1 + i32.add + local.get $p1 + i32.store + local.get $p0 + local.get $p1 + i32.const 1 + i32.or + i32.store offset=4 + end + local.get $p1 + i32.const 255 + i32.le_u + if $I28 + local.get $p1 + i32.const 3 + i32.shr_u + local.tee $l2 + i32.const 3 + i32.shl + i32.const 1060620 + i32.add + local.set $p1 + block $B29 (result i32) + i32.const 1060580 + i32.load + local.tee $l3 + i32.const 1 + local.get $l2 + i32.shl + local.tee $l2 + i32.and + i32.eqz + if $I30 + i32.const 1060580 + local.get $l2 + local.get $l3 + i32.or + i32.store + local.get $p1 + br $B29 + end + local.get $p1 + i32.load offset=8 + end + local.tee $l3 + local.get $p0 + i32.store offset=12 + local.get $p1 + local.get $p0 + i32.store offset=8 + local.get $p0 + local.get $p1 + i32.store offset=12 + local.get $p0 + local.get $l3 + i32.store offset=8 + return + end + local.get $p0 + i64.const 0 + i64.store offset=16 align=4 + local.get $p0 + i32.const 28 + i32.add + block $B31 (result i32) + i32.const 0 + local.get $p1 + i32.const 8 + i32.shr_u + local.tee $l2 + i32.eqz + br_if $B31 + drop + i32.const 31 + local.get $p1 + i32.const 16777215 + i32.gt_u + br_if $B31 + drop + local.get $l2 + local.get $l2 + i32.const 1048320 + i32.add + i32.const 16 + i32.shr_u + i32.const 8 + i32.and + local.tee $l2 + i32.shl + local.tee $l3 + local.get $l3 + i32.const 520192 + i32.add + i32.const 16 + i32.shr_u + i32.const 4 + i32.and + local.tee $l3 + i32.shl + local.tee $l4 + local.get $l4 + i32.const 245760 + i32.add + i32.const 16 + i32.shr_u + i32.const 2 + i32.and + local.tee $l4 + i32.shl + i32.const 15 + i32.shr_u + local.get $l2 + local.get $l3 + i32.or + local.get $l4 + i32.or + i32.sub + local.tee $l2 + i32.const 1 + i32.shl + local.get $p1 + local.get $l2 + i32.const 21 + i32.add + i32.shr_u + i32.const 1 + i32.and + i32.or + i32.const 28 + i32.add + end + local.tee $l3 + i32.store + local.get $l3 + i32.const 2 + i32.shl + i32.const 1060884 + i32.add + local.set $l2 + i32.const 1060584 + i32.load + local.tee $l4 + i32.const 1 + local.get $l3 + i32.shl + local.tee $l7 + i32.and + i32.eqz + if $I32 + local.get $l2 + local.get $p0 + i32.store + i32.const 1060584 + local.get $l4 + local.get $l7 + i32.or + i32.store + local.get $p0 + i32.const 24 + i32.add + local.get $l2 + i32.store + local.get $p0 + local.get $p0 + i32.store offset=8 + local.get $p0 + local.get $p0 + i32.store offset=12 + return + end + local.get $p1 + i32.const 0 + i32.const 25 + local.get $l3 + i32.const 1 + i32.shr_u + i32.sub + local.get $l3 + i32.const 31 + i32.eq + select + i32.shl + local.set $l3 + local.get $l2 + i32.load + local.set $l2 + block $B33 + loop $L34 + local.get $l2 + local.tee $l4 + i32.load offset=4 + i32.const -8 + i32.and + local.get $p1 + i32.eq + br_if $B33 + local.get $l3 + i32.const 29 + i32.shr_u + local.set $l2 + local.get $l3 + i32.const 1 + i32.shl + local.set $l3 + local.get $l4 + local.get $l2 + i32.const 4 + i32.and + i32.add + i32.const 16 + i32.add + local.tee $l7 + i32.load + local.tee $l2 + br_if $L34 + end + local.get $l7 + local.get $p0 + i32.store + local.get $p0 + i32.const 24 + i32.add + local.get $l4 + i32.store + local.get $p0 + local.get $p0 + i32.store offset=12 + local.get $p0 + local.get $p0 + i32.store offset=8 + return + end + local.get $l4 + i32.load offset=8 + local.set $p1 + local.get $l4 + local.get $p0 + i32.store offset=8 + local.get $p1 + local.get $p0 + i32.store offset=12 + local.get $p0 + i32.const 24 + i32.add + i32.const 0 + i32.store + local.get $p0 + local.get $p1 + i32.store offset=8 + local.get $p0 + local.get $l4 + i32.store offset=12 + end) + (func $f149 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + (local $l2 i32) (local $l3 i32) (local $l4 i32) (local $l5 i32) (local $l6 i32) + block $B0 + local.get $p0 + i32.const 16 + local.get $p0 + i32.const 16 + i32.gt_u + select + local.tee $l3 + local.get $l3 + i32.const -1 + i32.add + i32.and + i32.eqz + if $I1 + local.get $l3 + local.set $p0 + br $B0 + end + i32.const 32 + local.set $l2 + loop $L2 + local.get $l2 + local.tee $p0 + i32.const 1 + i32.shl + local.set $l2 + local.get $p0 + local.get $l3 + i32.lt_u + br_if $L2 + end + end + i32.const -64 + local.get $p0 + i32.sub + local.get $p1 + i32.le_u + if $I3 + i32.const 1061076 + i32.const 48 + i32.store + i32.const 0 + return + end + i32.const 16 + local.get $p1 + i32.const 19 + i32.add + i32.const -16 + i32.and + local.get $p1 + i32.const 11 + i32.lt_u + select + local.tee $l3 + i32.const 12 + i32.or + local.get $p0 + i32.add + call $f144 + local.tee $l2 + i32.eqz + if $I4 + i32.const 0 + return + end + local.get $l2 + i32.const -8 + i32.add + local.set $p1 + block $B5 + local.get $p0 + i32.const -1 + i32.add + local.get $l2 + i32.and + i32.eqz + if $I6 + local.get $p1 + local.set $p0 + br $B5 + end + local.get $l2 + i32.const -4 + i32.add + local.tee $l5 + i32.load + local.tee $l6 + i32.const -8 + i32.and + local.get $p0 + local.get $l2 + i32.add + i32.const -1 + i32.add + i32.const 0 + local.get $p0 + i32.sub + i32.and + i32.const -8 + i32.add + local.tee $l2 + local.get $p0 + local.get $l2 + i32.add + local.get $l2 + local.get $p1 + i32.sub + i32.const 15 + i32.gt_u + select + local.tee $p0 + local.get $p1 + i32.sub + local.tee $l2 + i32.sub + local.set $l4 + local.get $l6 + i32.const 3 + i32.and + i32.eqz + if $I7 + local.get $p0 + local.get $l4 + i32.store offset=4 + local.get $p0 + local.get $p1 + i32.load + local.get $l2 + i32.add + i32.store + br $B5 + end + local.get $p0 + local.get $l4 + local.get $p0 + i32.load offset=4 + i32.const 1 + i32.and + i32.or + i32.const 2 + i32.or + i32.store offset=4 + local.get $p0 + local.get $l4 + i32.add + local.tee $l4 + local.get $l4 + i32.load offset=4 + i32.const 1 + i32.or + i32.store offset=4 + local.get $l5 + local.get $l2 + local.get $l5 + i32.load + i32.const 1 + i32.and + i32.or + i32.const 2 + i32.or + i32.store + local.get $p0 + local.get $p0 + i32.load offset=4 + i32.const 1 + i32.or + i32.store offset=4 + local.get $p1 + local.get $l2 + call $f148 + end + block $B8 + local.get $p0 + i32.load offset=4 + local.tee $p1 + i32.const 3 + i32.and + i32.eqz + br_if $B8 + local.get $p1 + i32.const -8 + i32.and + local.tee $l2 + local.get $l3 + i32.const 16 + i32.add + i32.le_u + br_if $B8 + local.get $p0 + local.get $l3 + local.get $p1 + i32.const 1 + i32.and + i32.or + i32.const 2 + i32.or + i32.store offset=4 + local.get $p0 + local.get $l3 + i32.add + local.tee $p1 + local.get $l2 + local.get $l3 + i32.sub + local.tee $l3 + i32.const 3 + i32.or + i32.store offset=4 + local.get $p0 + local.get $l2 + i32.add + local.tee $l2 + local.get $l2 + i32.load offset=4 + i32.const 1 + i32.or + i32.store offset=4 + local.get $p1 + local.get $l3 + call $f148 + end + local.get $p0 + i32.const 8 + i32.add) + (func $f150 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + local.get $p0 + i32.const 16 + i32.le_u + if $I0 + local.get $p1 + call $f144 + return + end + local.get $p0 + local.get $p1 + call $f149) + (func $f151 (type $t2) (param $p0 i32) + local.get $p0 + call $wasi_snapshot_preview1.proc_exit + unreachable) + (func $f152 (type $t7) + (local $l0 i32) (local $l1 i32) (local $l2 i32) (local $l3 i32) (local $l4 i32) (local $l5 i32) (local $l6 i32) + global.get $g0 + i32.const 16 + i32.sub + local.tee $l2 + global.set $g0 + i32.const 3 + local.set $l1 + block $B0 + block $B1 + block $B2 + block $B3 + block $B4 + loop $L5 + local.get $l1 + local.get $l2 + i32.const 8 + i32.add + call $wasi_snapshot_preview1.fd_prestat_get + local.tee $l0 + i32.const 8 + i32.gt_u + br_if $B3 + block $B6 + block $B7 + local.get $l0 + i32.const 1 + i32.sub + br_table $B3 $B3 $B3 $B3 $B3 $B3 $B3 $B6 $B7 + end + local.get $l2 + i32.load8_u offset=8 + i32.eqz + if $I8 + local.get $l2 + i32.load offset=12 + local.tee $l0 + i32.const 1 + i32.add + call $f144 + local.tee $l3 + i32.eqz + br_if $B1 + local.get $l1 + local.get $l3 + local.get $l0 + call $wasi_snapshot_preview1.fd_prestat_dir_name + br_if $B4 + local.get $l3 + local.get $l2 + i32.load offset=12 + i32.add + i32.const 0 + i32.store8 + local.get $l1 + i32.const -1 + i32.le_s + br_if $B0 + block $B9 + i32.const 1061088 + i32.load + local.tee $l0 + i32.const 1061084 + i32.load + i32.ne + if $I10 + i32.const 1061080 + i32.load + local.set $l4 + br $B9 + end + i32.const 8 + local.get $l0 + i32.const 1 + i32.shl + i32.const 4 + local.get $l0 + select + local.tee $l6 + call $f146 + local.tee $l4 + i32.eqz + br_if $B2 + local.get $l4 + i32.const 1061080 + i32.load + local.tee $l5 + local.get $l0 + i32.const 3 + i32.shl + call $f162 + local.set $l0 + local.get $l5 + call $f145 + i32.const 1061084 + local.get $l6 + i32.store + i32.const 1061080 + local.get $l0 + i32.store + i32.const 1061088 + i32.load + local.set $l0 + end + i32.const 1061088 + local.get $l0 + i32.const 1 + i32.add + i32.store + local.get $l4 + local.get $l0 + i32.const 3 + i32.shl + i32.add + local.tee $l0 + local.get $l1 + i32.store offset=4 + local.get $l0 + local.get $l3 + i32.store + end + local.get $l1 + i32.const 1 + i32.add + local.tee $l0 + local.get $l1 + i32.lt_u + local.get $l0 + local.set $l1 + i32.eqz + br_if $L5 + end + end + local.get $l2 + i32.const 16 + i32.add + global.set $g0 + return + end + local.get $l3 + call $f145 + end + i32.const 71 + call $f151 + unreachable + end + local.get $l3 + call $f145 + end + i32.const 70 + call $f151 + unreachable + end + unreachable) + (func $f153 (type $t5) (param $p0 i32) (result i32) + local.get $p0 + i32.eqz + if $I0 + memory.size + i32.const 16 + i32.shl + return + end + local.get $p0 + i32.const 65535 + i32.and + local.get $p0 + i32.const -1 + i32.le_s + i32.or + i32.eqz + if $I1 + local.get $p0 + i32.const 16 + i32.shr_u + memory.grow + local.tee $p0 + i32.const -1 + i32.eq + if $I2 + i32.const 1061076 + i32.const 48 + i32.store + i32.const -1 + return + end + local.get $p0 + i32.const 16 + i32.shl + return + end + unreachable) + (func $f154 (type $t7) + (local $l0 i32) (local $l1 i32) (local $l2 i32) + global.get $g0 + i32.const 16 + i32.sub + local.tee $l0 + global.set $g0 + block $B0 + block $B1 + local.get $l0 + i32.const 12 + i32.add + local.get $l0 + i32.const 8 + i32.add + call $wasi_snapshot_preview1.environ_sizes_get + br_if $B1 + local.get $l0 + i32.load offset=12 + local.tee $l1 + i32.eqz + br_if $B0 + block $B2 + block $B3 + local.get $l1 + i32.const 1 + i32.add + local.tee $l2 + local.get $l1 + i32.lt_u + br_if $B3 + local.get $l0 + i32.load offset=8 + call $f144 + local.tee $l0 + i32.eqz + br_if $B3 + local.get $l2 + i32.const 4 + call $f146 + local.tee $l1 + br_if $B2 + local.get $l0 + call $f145 + end + i32.const 70 + call $f151 + unreachable + end + local.get $l1 + local.get $l0 + call $wasi_snapshot_preview1.environ_get + if $I4 + local.get $l0 + call $f145 + local.get $l1 + call $f145 + br $B1 + end + i32.const 1060484 + local.get $l1 + i32.store + end + i32.const 71 + call $f151 + unreachable + end + local.get $l0 + i32.const 16 + i32.add + global.set $g0) + (func $f155 (type $t5) (param $p0 i32) (result i32) + (local $l1 i32) (local $l2 i32) (local $l3 i32) (local $l4 i32) + block $B0 + local.get $p0 + call $f161 + local.tee $l1 + local.get $p0 + i32.sub + local.tee $l4 + i32.eqz + br_if $B0 + local.get $l1 + i32.load8_u + br_if $B0 + i32.const 1060484 + i32.load + local.tee $l2 + i32.eqz + br_if $B0 + local.get $l2 + i32.load + local.tee $l1 + i32.eqz + br_if $B0 + local.get $l2 + i32.const 4 + i32.add + local.set $l2 + loop $L1 + block $B2 + local.get $p0 + local.get $l1 + local.get $l4 + call $f163 + i32.eqz + if $I3 + local.get $l1 + local.get $l4 + i32.add + local.tee $l1 + i32.load8_u + i32.const 61 + i32.eq + br_if $B2 + end + local.get $l2 + i32.load + local.set $l1 + local.get $l2 + i32.const 4 + i32.add + local.set $l2 + local.get $l1 + br_if $L1 + br $B0 + end + end + local.get $l1 + i32.const 1 + i32.add + local.set $l3 + end + local.get $l3) + (func $f156 (type $t1) (param $p0 i32) (param $p1 i32) (param $p2 i32) (result i32) + (local $l3 i32) (local $l4 i32) (local $l5 i32) (local $l6 i32) + block $B0 + i32.const 1060484 + i32.load + local.tee $l4 + i32.eqz + br_if $B0 + local.get $l4 + i32.load + local.tee $l3 + i32.eqz + br_if $B0 + local.get $p1 + i32.const 1 + i32.add + local.set $l6 + local.get $l4 + local.set $p1 + loop $L1 + local.get $p0 + local.get $l3 + local.get $l6 + call $f163 + i32.eqz + if $I2 + local.get $p1 + local.get $p0 + i32.store + local.get $l3 + local.get $p2 + call $f157 + i32.const 0 + return + end + local.get $l5 + i32.const 1 + i32.add + local.set $l5 + local.get $p1 + i32.load offset=4 + local.set $l3 + local.get $p1 + i32.const 4 + i32.add + local.set $p1 + local.get $l3 + br_if $L1 + end + end + local.get $l5 + i32.const 2 + i32.shl + local.tee $l6 + i32.const 8 + i32.add + local.set $l3 + block $B3 + block $B4 + i32.const 1061096 + i32.load + local.tee $p1 + local.get $l4 + i32.eq + if $I5 + local.get $l4 + local.get $l3 + call $f147 + local.tee $l3 + br_if $B4 + br $B3 + end + local.get $l3 + call $f144 + local.tee $l3 + i32.eqz + br_if $B3 + local.get $l5 + if $I6 + local.get $l3 + local.get $l4 + local.get $l6 + call $f162 + drop + end + local.get $p1 + call $f145 + end + i32.const 1061096 + local.get $l3 + i32.store + i32.const 1060484 + local.get $l3 + i32.store + local.get $l3 + local.get $l5 + i32.const 2 + i32.shl + i32.add + local.tee $p1 + local.get $p0 + i32.store + local.get $p1 + i32.const 4 + i32.add + i32.const 0 + i32.store + local.get $p2 + if $I7 + i32.const 0 + local.get $p2 + call $f157 + end + i32.const 0 + return + end + local.get $p2 + call $f145 + i32.const -1) + (func $f157 (type $t3) (param $p0 i32) (param $p1 i32) + (local $l2 i32) (local $l3 i32) (local $l4 i32) (local $l5 i32) + i32.const 1061104 + i32.load + local.tee $l3 + if $I0 + i32.const 1061100 + i32.load + local.set $l2 + loop $L1 + local.get $p0 + local.get $l2 + i32.load + local.tee $l4 + i32.eq + if $I2 + local.get $l2 + local.get $p1 + i32.store + local.get $p0 + call $f145 + return + end + local.get $p1 + i32.eqz + local.get $l4 + i32.or + i32.eqz + if $I3 + local.get $l2 + local.get $p1 + i32.store + i32.const 0 + local.set $p1 + end + local.get $l2 + i32.const 4 + i32.add + local.set $l2 + local.get $l5 + i32.const 1 + i32.add + local.tee $l5 + local.get $l3 + i32.lt_u + br_if $L1 + end + end + block $B4 + local.get $p1 + i32.eqz + br_if $B4 + i32.const 1061100 + i32.load + local.get $l3 + i32.const 2 + i32.shl + i32.const 4 + i32.add + call $f147 + local.tee $p0 + i32.eqz + br_if $B4 + i32.const 1061100 + local.get $p0 + i32.store + i32.const 1061104 + i32.const 1061104 + i32.load + local.tee $l2 + i32.const 1 + i32.add + i32.store + local.get $p0 + local.get $l2 + i32.const 2 + i32.shl + i32.add + local.get $p1 + i32.store + end) + (func $f158 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + (local $l2 i32) (local $l3 i32) (local $l4 i32) + block $B0 + block $B1 + local.get $p0 + i32.eqz + br_if $B1 + local.get $p0 + call $f161 + local.tee $l3 + local.get $p0 + i32.sub + local.tee $l2 + i32.eqz + br_if $B1 + local.get $l3 + i32.load8_u + i32.eqz + br_if $B0 + end + i32.const 1061076 + i32.const 28 + i32.store + i32.const -1 + return + end + local.get $l2 + local.get $p1 + call $f160 + local.tee $l3 + i32.add + i32.const 2 + i32.add + call $f144 + local.tee $l4 + i32.eqz + if $I2 + i32.const -1 + return + end + local.get $l4 + local.get $p0 + local.get $l2 + call $f162 + local.tee $p0 + local.get $l2 + i32.add + local.tee $l4 + i32.const 61 + i32.store8 + local.get $l4 + i32.const 1 + i32.add + local.get $p1 + local.get $l3 + i32.const 1 + i32.add + call $f162 + drop + local.get $p0 + local.get $l2 + local.get $p0 + call $f156) + (func $f159 (type $t4) (param $p0 i32) (param $p1 i32) (param $p2 i32) + (local $l3 i32) (local $l4 i32) (local $l5 i32) (local $l6 i32) + block $B0 + local.get $p0 + local.get $p1 + i32.eq + br_if $B0 + local.get $p1 + local.get $p0 + i32.sub + local.get $p2 + i32.sub + i32.const 0 + local.get $p2 + i32.const 1 + i32.shl + i32.sub + i32.le_u + if $I1 + local.get $p0 + local.get $p1 + local.get $p2 + call $f162 + drop + br $B0 + end + local.get $p0 + local.get $p1 + i32.xor + i32.const 3 + i32.and + local.set $l3 + block $B2 + block $B3 + local.get $p0 + local.get $p1 + i32.lt_u + if $I4 + local.get $l3 + if $I5 + local.get $p0 + local.set $l3 + br $B2 + end + local.get $p0 + i32.const 3 + i32.and + i32.eqz + if $I6 + local.get $p0 + local.set $l3 + br $B3 + end + local.get $p0 + local.set $l3 + loop $L7 + local.get $p2 + i32.eqz + br_if $B0 + local.get $l3 + local.get $p1 + i32.load8_u + i32.store8 + local.get $p1 + i32.const 1 + i32.add + local.set $p1 + local.get $p2 + i32.const -1 + i32.add + local.set $p2 + local.get $l3 + i32.const 1 + i32.add + local.tee $l3 + i32.const 3 + i32.and + br_if $L7 + end + br $B3 + end + block $B8 + local.get $l3 + if $I9 + local.get $p2 + local.set $l3 + br $B8 + end + block $B10 + local.get $p0 + local.get $p2 + i32.add + i32.const 3 + i32.and + i32.eqz + if $I11 + local.get $p2 + local.set $l3 + br $B10 + end + local.get $p1 + i32.const -1 + i32.add + local.set $l4 + local.get $p0 + i32.const -1 + i32.add + local.set $l5 + loop $L12 + local.get $p2 + i32.eqz + br_if $B0 + local.get $p2 + local.get $l5 + i32.add + local.tee $l6 + local.get $p2 + local.get $l4 + i32.add + i32.load8_u + i32.store8 + local.get $p2 + i32.const -1 + i32.add + local.tee $l3 + local.set $p2 + local.get $l6 + i32.const 3 + i32.and + br_if $L12 + end + end + local.get $l3 + i32.const 4 + i32.lt_u + br_if $B8 + local.get $p0 + i32.const -4 + i32.add + local.set $p2 + local.get $p1 + i32.const -4 + i32.add + local.set $l4 + loop $L13 + local.get $p2 + local.get $l3 + i32.add + local.get $l3 + local.get $l4 + i32.add + i32.load + i32.store + local.get $l3 + i32.const -4 + i32.add + local.tee $l3 + i32.const 3 + i32.gt_u + br_if $L13 + end + end + local.get $l3 + i32.eqz + br_if $B0 + local.get $p1 + i32.const -1 + i32.add + local.set $p1 + local.get $p0 + i32.const -1 + i32.add + local.set $p0 + loop $L14 + local.get $p0 + local.get $l3 + i32.add + local.get $p1 + local.get $l3 + i32.add + i32.load8_u + i32.store8 + local.get $l3 + i32.const -1 + i32.add + local.tee $l3 + br_if $L14 + end + br $B0 + end + local.get $p2 + i32.const 4 + i32.lt_u + br_if $B2 + local.get $p2 + local.set $p0 + loop $L15 + local.get $l3 + local.get $p1 + i32.load + i32.store + local.get $p1 + i32.const 4 + i32.add + local.set $p1 + local.get $l3 + i32.const 4 + i32.add + local.set $l3 + local.get $p0 + i32.const -4 + i32.add + local.tee $p0 + i32.const 3 + i32.gt_u + br_if $L15 + end + local.get $p2 + i32.const 3 + i32.and + local.set $p2 + end + local.get $p2 + i32.eqz + br_if $B0 + loop $L16 + local.get $l3 + local.get $p1 + i32.load8_u + i32.store8 + local.get $l3 + i32.const 1 + i32.add + local.set $l3 + local.get $p1 + i32.const 1 + i32.add + local.set $p1 + local.get $p2 + i32.const -1 + i32.add + local.tee $p2 + br_if $L16 + end + end) + (func $f160 (type $t5) (param $p0 i32) (result i32) + (local $l1 i32) (local $l2 i32) (local $l3 i32) + block $B0 + block $B1 + block $B2 + local.get $p0 + local.tee $l1 + i32.const 3 + i32.and + i32.eqz + br_if $B2 + local.get $p0 + i32.load8_u + i32.eqz + if $I3 + i32.const 0 + return + end + local.get $p0 + i32.const 1 + i32.add + local.set $l1 + loop $L4 + local.get $l1 + i32.const 3 + i32.and + i32.eqz + br_if $B2 + local.get $l1 + i32.load8_u + local.get $l1 + i32.const 1 + i32.add + local.tee $l3 + local.set $l1 + br_if $L4 + end + br $B1 + end + local.get $l1 + i32.const -4 + i32.add + local.set $l1 + loop $L5 + local.get $l1 + i32.const 4 + i32.add + local.tee $l1 + i32.load + local.tee $l2 + i32.const -1 + i32.xor + local.get $l2 + i32.const -16843009 + i32.add + i32.and + i32.const -2139062144 + i32.and + i32.eqz + br_if $L5 + end + local.get $l2 + i32.const 255 + i32.and + i32.eqz + if $I6 + local.get $l1 + local.get $p0 + i32.sub + return + end + loop $L7 + local.get $l1 + i32.load8_u offset=1 + local.get $l1 + i32.const 1 + i32.add + local.tee $l2 + local.set $l1 + br_if $L7 + end + br $B0 + end + local.get $l3 + i32.const -1 + i32.add + local.set $l2 + end + local.get $l2 + local.get $p0 + i32.sub) + (func $f161 (type $t5) (param $p0 i32) (result i32) + (local $l1 i32) + block $B0 + local.get $p0 + i32.const 3 + i32.and + if $I1 + loop $L2 + local.get $p0 + i32.load8_u + local.tee $l1 + i32.eqz + local.get $l1 + i32.const 61 + i32.eq + i32.or + br_if $B0 + local.get $p0 + i32.const 1 + i32.add + local.tee $p0 + i32.const 3 + i32.and + br_if $L2 + end + end + block $B3 + local.get $p0 + i32.load + local.tee $l1 + i32.const -1 + i32.xor + local.get $l1 + i32.const -16843009 + i32.add + i32.and + i32.const -2139062144 + i32.and + br_if $B3 + loop $L4 + local.get $l1 + i32.const 1027423549 + i32.xor + local.tee $l1 + i32.const -1 + i32.xor + local.get $l1 + i32.const -16843009 + i32.add + i32.and + i32.const -2139062144 + i32.and + br_if $B3 + local.get $p0 + i32.load offset=4 + local.set $l1 + local.get $p0 + i32.const 4 + i32.add + local.set $p0 + local.get $l1 + i32.const -16843009 + i32.add + local.get $l1 + i32.const -1 + i32.xor + i32.and + i32.const -2139062144 + i32.and + i32.eqz + br_if $L4 + end + end + local.get $p0 + i32.const -1 + i32.add + local.set $p0 + loop $L5 + local.get $p0 + i32.const 1 + i32.add + local.tee $p0 + i32.load8_u + local.tee $l1 + i32.eqz + br_if $B0 + local.get $l1 + i32.const 61 + i32.ne + br_if $L5 + end + end + local.get $p0) + (func $f162 (type $t1) (param $p0 i32) (param $p1 i32) (param $p2 i32) (result i32) + (local $l3 i32) (local $l4 i32) (local $l5 i32) (local $l6 i32) (local $l7 i32) (local $l8 i32) (local $l9 i32) (local $l10 i32) + block $B0 + local.get $p2 + i32.eqz + local.get $p1 + i32.const 3 + i32.and + i32.eqz + i32.or + i32.eqz + if $I1 + local.get $p0 + local.set $l3 + loop $L2 + local.get $l3 + local.get $p1 + i32.load8_u + i32.store8 + local.get $p2 + i32.const -1 + i32.add + local.set $l4 + local.get $l3 + i32.const 1 + i32.add + local.set $l3 + local.get $p1 + i32.const 1 + i32.add + local.set $p1 + local.get $p2 + i32.const 1 + i32.eq + br_if $B0 + local.get $l4 + local.set $p2 + local.get $p1 + i32.const 3 + i32.and + br_if $L2 + end + br $B0 + end + local.get $p2 + local.set $l4 + local.get $p0 + local.set $l3 + end + block $B3 + local.get $l3 + i32.const 3 + i32.and + local.tee $p2 + i32.eqz + if $I4 + block $B5 + local.get $l4 + i32.const 16 + i32.lt_u + if $I6 + local.get $l4 + local.set $p2 + br $B5 + end + local.get $l4 + i32.const -16 + i32.add + local.set $p2 + loop $L7 + local.get $l3 + local.get $p1 + i32.load + i32.store + local.get $l3 + i32.const 4 + i32.add + local.get $p1 + i32.const 4 + i32.add + i32.load + i32.store + local.get $l3 + i32.const 8 + i32.add + local.get $p1 + i32.const 8 + i32.add + i32.load + i32.store + local.get $l3 + i32.const 12 + i32.add + local.get $p1 + i32.const 12 + i32.add + i32.load + i32.store + local.get $l3 + i32.const 16 + i32.add + local.set $l3 + local.get $p1 + i32.const 16 + i32.add + local.set $p1 + local.get $l4 + i32.const -16 + i32.add + local.tee $l4 + i32.const 15 + i32.gt_u + br_if $L7 + end + end + local.get $p2 + i32.const 8 + i32.and + if $I8 + local.get $l3 + local.get $p1 + i64.load align=4 + i64.store align=4 + local.get $l3 + i32.const 8 + i32.add + local.set $l3 + local.get $p1 + i32.const 8 + i32.add + local.set $p1 + end + local.get $p2 + i32.const 4 + i32.and + if $I9 + local.get $l3 + local.get $p1 + i32.load + i32.store + local.get $l3 + i32.const 4 + i32.add + local.set $l3 + local.get $p1 + i32.const 4 + i32.add + local.set $p1 + end + local.get $p2 + i32.const 2 + i32.and + if $I10 + local.get $l3 + local.get $p1 + i32.load8_u + i32.store8 + local.get $l3 + local.get $p1 + i32.load8_u offset=1 + i32.store8 offset=1 + local.get $l3 + i32.const 2 + i32.add + local.set $l3 + local.get $p1 + i32.const 2 + i32.add + local.set $p1 + end + local.get $p2 + i32.const 1 + i32.and + i32.eqz + br_if $B3 + local.get $l3 + local.get $p1 + i32.load8_u + i32.store8 + local.get $p0 + return + end + block $B11 + local.get $l4 + i32.const 32 + i32.lt_u + br_if $B11 + local.get $p2 + i32.const -1 + i32.add + local.tee $p2 + i32.const 2 + i32.gt_u + br_if $B11 + block $B12 + block $B13 + block $B14 + local.get $p2 + i32.const 1 + i32.sub + br_table $B13 $B12 $B14 + end + local.get $l3 + local.get $p1 + i32.load8_u offset=1 + i32.store8 offset=1 + local.get $l3 + local.get $p1 + i32.load + local.tee $l5 + i32.store8 + local.get $l3 + local.get $p1 + i32.load8_u offset=2 + i32.store8 offset=2 + local.get $l4 + i32.const -3 + i32.add + local.set $l8 + local.get $l3 + i32.const 3 + i32.add + local.set $l9 + local.get $l4 + i32.const -20 + i32.add + i32.const -16 + i32.and + local.set $l10 + i32.const 0 + local.set $p2 + loop $L15 + local.get $p2 + local.get $l9 + i32.add + local.tee $l3 + local.get $p1 + local.get $p2 + i32.add + local.tee $l6 + i32.const 4 + i32.add + i32.load + local.tee $l7 + i32.const 8 + i32.shl + local.get $l5 + i32.const 24 + i32.shr_u + i32.or + i32.store + local.get $l3 + i32.const 4 + i32.add + local.get $l6 + i32.const 8 + i32.add + i32.load + local.tee $l5 + i32.const 8 + i32.shl + local.get $l7 + i32.const 24 + i32.shr_u + i32.or + i32.store + local.get $l3 + i32.const 8 + i32.add + local.get $l6 + i32.const 12 + i32.add + i32.load + local.tee $l7 + i32.const 8 + i32.shl + local.get $l5 + i32.const 24 + i32.shr_u + i32.or + i32.store + local.get $l3 + i32.const 12 + i32.add + local.get $l6 + i32.const 16 + i32.add + i32.load + local.tee $l5 + i32.const 8 + i32.shl + local.get $l7 + i32.const 24 + i32.shr_u + i32.or + i32.store + local.get $p2 + i32.const 16 + i32.add + local.set $p2 + local.get $l8 + i32.const -16 + i32.add + local.tee $l8 + i32.const 16 + i32.gt_u + br_if $L15 + end + local.get $p2 + local.get $l9 + i32.add + local.set $l3 + local.get $p1 + local.get $p2 + i32.add + i32.const 3 + i32.add + local.set $p1 + local.get $l4 + local.get $l10 + i32.sub + i32.const -19 + i32.add + local.set $l4 + br $B11 + end + local.get $l3 + local.get $p1 + i32.load + local.tee $l5 + i32.store8 + local.get $l3 + local.get $p1 + i32.load8_u offset=1 + i32.store8 offset=1 + local.get $l4 + i32.const -2 + i32.add + local.set $l8 + local.get $l3 + i32.const 2 + i32.add + local.set $l9 + local.get $l4 + i32.const -20 + i32.add + i32.const -16 + i32.and + local.set $l10 + i32.const 0 + local.set $p2 + loop $L16 + local.get $p2 + local.get $l9 + i32.add + local.tee $l3 + local.get $p1 + local.get $p2 + i32.add + local.tee $l6 + i32.const 4 + i32.add + i32.load + local.tee $l7 + i32.const 16 + i32.shl + local.get $l5 + i32.const 16 + i32.shr_u + i32.or + i32.store + local.get $l3 + i32.const 4 + i32.add + local.get $l6 + i32.const 8 + i32.add + i32.load + local.tee $l5 + i32.const 16 + i32.shl + local.get $l7 + i32.const 16 + i32.shr_u + i32.or + i32.store + local.get $l3 + i32.const 8 + i32.add + local.get $l6 + i32.const 12 + i32.add + i32.load + local.tee $l7 + i32.const 16 + i32.shl + local.get $l5 + i32.const 16 + i32.shr_u + i32.or + i32.store + local.get $l3 + i32.const 12 + i32.add + local.get $l6 + i32.const 16 + i32.add + i32.load + local.tee $l5 + i32.const 16 + i32.shl + local.get $l7 + i32.const 16 + i32.shr_u + i32.or + i32.store + local.get $p2 + i32.const 16 + i32.add + local.set $p2 + local.get $l8 + i32.const -16 + i32.add + local.tee $l8 + i32.const 17 + i32.gt_u + br_if $L16 + end + local.get $p2 + local.get $l9 + i32.add + local.set $l3 + local.get $p1 + local.get $p2 + i32.add + i32.const 2 + i32.add + local.set $p1 + local.get $l4 + local.get $l10 + i32.sub + i32.const -18 + i32.add + local.set $l4 + br $B11 + end + local.get $l3 + local.get $p1 + i32.load + local.tee $l5 + i32.store8 + local.get $l4 + i32.const -1 + i32.add + local.set $l8 + local.get $l3 + i32.const 1 + i32.add + local.set $l9 + local.get $l4 + i32.const -20 + i32.add + i32.const -16 + i32.and + local.set $l10 + i32.const 0 + local.set $p2 + loop $L17 + local.get $p2 + local.get $l9 + i32.add + local.tee $l3 + local.get $p1 + local.get $p2 + i32.add + local.tee $l6 + i32.const 4 + i32.add + i32.load + local.tee $l7 + i32.const 24 + i32.shl + local.get $l5 + i32.const 8 + i32.shr_u + i32.or + i32.store + local.get $l3 + i32.const 4 + i32.add + local.get $l6 + i32.const 8 + i32.add + i32.load + local.tee $l5 + i32.const 24 + i32.shl + local.get $l7 + i32.const 8 + i32.shr_u + i32.or + i32.store + local.get $l3 + i32.const 8 + i32.add + local.get $l6 + i32.const 12 + i32.add + i32.load + local.tee $l7 + i32.const 24 + i32.shl + local.get $l5 + i32.const 8 + i32.shr_u + i32.or + i32.store + local.get $l3 + i32.const 12 + i32.add + local.get $l6 + i32.const 16 + i32.add + i32.load + local.tee $l5 + i32.const 24 + i32.shl + local.get $l7 + i32.const 8 + i32.shr_u + i32.or + i32.store + local.get $p2 + i32.const 16 + i32.add + local.set $p2 + local.get $l8 + i32.const -16 + i32.add + local.tee $l8 + i32.const 18 + i32.gt_u + br_if $L17 + end + local.get $p2 + local.get $l9 + i32.add + local.set $l3 + local.get $p1 + local.get $p2 + i32.add + i32.const 1 + i32.add + local.set $p1 + local.get $l4 + local.get $l10 + i32.sub + i32.const -17 + i32.add + local.set $l4 + end + local.get $l4 + i32.const 16 + i32.and + if $I18 + local.get $l3 + local.get $p1 + i32.load16_u align=1 + i32.store16 align=1 + local.get $l3 + local.get $p1 + i32.load8_u offset=2 + i32.store8 offset=2 + local.get $l3 + local.get $p1 + i32.load8_u offset=3 + i32.store8 offset=3 + local.get $l3 + local.get $p1 + i32.load8_u offset=4 + i32.store8 offset=4 + local.get $l3 + local.get $p1 + i32.load8_u offset=5 + i32.store8 offset=5 + local.get $l3 + local.get $p1 + i32.load8_u offset=6 + i32.store8 offset=6 + local.get $l3 + local.get $p1 + i32.load8_u offset=7 + i32.store8 offset=7 + local.get $l3 + local.get $p1 + i32.load8_u offset=8 + i32.store8 offset=8 + local.get $l3 + local.get $p1 + i32.load8_u offset=9 + i32.store8 offset=9 + local.get $l3 + local.get $p1 + i32.load8_u offset=10 + i32.store8 offset=10 + local.get $l3 + local.get $p1 + i32.load8_u offset=11 + i32.store8 offset=11 + local.get $l3 + local.get $p1 + i32.load8_u offset=12 + i32.store8 offset=12 + local.get $l3 + local.get $p1 + i32.load8_u offset=13 + i32.store8 offset=13 + local.get $l3 + local.get $p1 + i32.load8_u offset=14 + i32.store8 offset=14 + local.get $l3 + local.get $p1 + i32.load8_u offset=15 + i32.store8 offset=15 + local.get $l3 + i32.const 16 + i32.add + local.set $l3 + local.get $p1 + i32.const 16 + i32.add + local.set $p1 + end + local.get $l4 + i32.const 8 + i32.and + if $I19 + local.get $l3 + local.get $p1 + i32.load8_u + i32.store8 + local.get $l3 + local.get $p1 + i32.load8_u offset=1 + i32.store8 offset=1 + local.get $l3 + local.get $p1 + i32.load8_u offset=2 + i32.store8 offset=2 + local.get $l3 + local.get $p1 + i32.load8_u offset=3 + i32.store8 offset=3 + local.get $l3 + local.get $p1 + i32.load8_u offset=4 + i32.store8 offset=4 + local.get $l3 + local.get $p1 + i32.load8_u offset=5 + i32.store8 offset=5 + local.get $l3 + local.get $p1 + i32.load8_u offset=6 + i32.store8 offset=6 + local.get $l3 + local.get $p1 + i32.load8_u offset=7 + i32.store8 offset=7 + local.get $l3 + i32.const 8 + i32.add + local.set $l3 + local.get $p1 + i32.const 8 + i32.add + local.set $p1 + end + local.get $l4 + i32.const 4 + i32.and + if $I20 + local.get $l3 + local.get $p1 + i32.load8_u + i32.store8 + local.get $l3 + local.get $p1 + i32.load8_u offset=1 + i32.store8 offset=1 + local.get $l3 + local.get $p1 + i32.load8_u offset=2 + i32.store8 offset=2 + local.get $l3 + local.get $p1 + i32.load8_u offset=3 + i32.store8 offset=3 + local.get $l3 + i32.const 4 + i32.add + local.set $l3 + local.get $p1 + i32.const 4 + i32.add + local.set $p1 + end + local.get $l4 + i32.const 2 + i32.and + if $I21 + local.get $l3 + local.get $p1 + i32.load8_u + i32.store8 + local.get $l3 + local.get $p1 + i32.load8_u offset=1 + i32.store8 offset=1 + local.get $l3 + i32.const 2 + i32.add + local.set $l3 + local.get $p1 + i32.const 2 + i32.add + local.set $p1 + end + local.get $l4 + i32.const 1 + i32.and + i32.eqz + br_if $B3 + local.get $l3 + local.get $p1 + i32.load8_u + i32.store8 + end + local.get $p0) + (func $f163 (type $t1) (param $p0 i32) (param $p1 i32) (param $p2 i32) (result i32) + (local $l3 i32) (local $l4 i32) (local $l5 i32) + local.get $p2 + i32.eqz + if $I0 + i32.const 0 + return + end + block $B1 + local.get $p0 + i32.load8_u + local.tee $l3 + i32.eqz + br_if $B1 + local.get $p0 + i32.const 1 + i32.add + local.set $p0 + local.get $p2 + i32.const -1 + i32.add + local.set $p2 + loop $L2 + local.get $p1 + i32.load8_u + local.tee $l5 + local.get $l3 + i32.ne + if $I3 + local.get $l3 + local.set $l4 + br $B1 + end + local.get $p2 + i32.eqz + if $I4 + local.get $l3 + local.set $l4 + br $B1 + end + local.get $l5 + i32.eqz + if $I5 + local.get $l3 + local.set $l4 + br $B1 + end + local.get $p2 + i32.const -1 + i32.add + local.set $p2 + local.get $p1 + i32.const 1 + i32.add + local.set $p1 + local.get $p0 + i32.load8_u + local.set $l3 + local.get $p0 + i32.const 1 + i32.add + local.set $p0 + local.get $l3 + br_if $L2 + end + end + local.get $l4 + i32.const 255 + i32.and + local.get $p1 + i32.load8_u + i32.sub) + (func $f164 (type $t5) (param $p0 i32) (result i32) + (local $l1 i32) (local $l2 i32) (local $l3 i32) (local $l4 i32) + i32.const 1061132 + i32.load + local.tee $l2 + i32.eqz + if $I0 + i32.const 1061132 + i32.const 1061108 + i32.store + i32.const 1061108 + local.set $l2 + end + block $B1 + block $B2 + loop $L3 + local.get $p0 + local.get $l1 + i32.const 1052624 + i32.add + i32.load8_u + i32.ne + if $I4 + i32.const 77 + local.set $l3 + local.get $l1 + i32.const 1 + i32.add + local.tee $l1 + i32.const 77 + i32.ne + br_if $L3 + br $B2 + end + end + local.get $l1 + local.tee $l3 + br_if $B2 + i32.const 1052704 + local.set $p0 + br $B1 + end + i32.const 1052704 + local.set $l1 + loop $L5 + local.get $l1 + i32.load8_u + local.get $l1 + i32.const 1 + i32.add + local.tee $p0 + local.set $l1 + br_if $L5 + local.get $p0 + local.set $l1 + local.get $l3 + i32.const -1 + i32.add + local.tee $l3 + br_if $L5 + end + end + local.get $l2 + i32.load offset=20 + drop + local.get $p0) + (func $f165 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + (local $l2 i32) + local.get $p0 + call $f164 + local.tee $p0 + call $f160 + local.tee $l2 + i32.const 1024 + i32.ge_u + if $I0 + local.get $p1 + local.get $p0 + i32.const 1023 + call $f162 + i32.const 1023 + i32.add + i32.const 0 + i32.store8 + i32.const 68 + return + end + local.get $p1 + local.get $p0 + local.get $l2 + i32.const 1 + i32.add + call $f162 + drop + i32.const 0) + (func $f166 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + (local $l2 i32) (local $l3 i32) + block $B0 + local.get $p1 + i32.eqz + br_if $B0 + local.get $p0 + i32.const 0 + i32.store8 + local.get $p0 + local.get $p1 + i32.add + local.tee $l2 + i32.const -1 + i32.add + i32.const 0 + i32.store8 + local.get $p1 + i32.const 3 + i32.lt_u + br_if $B0 + local.get $p0 + i32.const 0 + i32.store8 offset=2 + local.get $p0 + i32.const 0 + i32.store8 offset=1 + local.get $l2 + i32.const -3 + i32.add + i32.const 0 + i32.store8 + local.get $l2 + i32.const -2 + i32.add + i32.const 0 + i32.store8 + local.get $p1 + i32.const 7 + i32.lt_u + br_if $B0 + local.get $p0 + i32.const 0 + i32.store8 offset=3 + local.get $l2 + i32.const -4 + i32.add + i32.const 0 + i32.store8 + local.get $p1 + i32.const 9 + i32.lt_u + br_if $B0 + local.get $p0 + i32.const 0 + local.get $p0 + i32.sub + i32.const 3 + i32.and + local.tee $l3 + i32.add + local.tee $l2 + i32.const 0 + i32.store + local.get $l2 + local.get $p1 + local.get $l3 + i32.sub + i32.const -4 + i32.and + local.tee $l3 + i32.add + local.tee $p1 + i32.const -4 + i32.add + i32.const 0 + i32.store + local.get $l3 + i32.const 9 + i32.lt_u + br_if $B0 + local.get $l2 + i32.const 0 + i32.store offset=8 + local.get $l2 + i32.const 0 + i32.store offset=4 + local.get $p1 + i32.const -8 + i32.add + i32.const 0 + i32.store + local.get $p1 + i32.const -12 + i32.add + i32.const 0 + i32.store + local.get $l3 + i32.const 25 + i32.lt_u + br_if $B0 + local.get $l2 + i32.const 0 + i32.store offset=24 + local.get $l2 + i32.const 0 + i32.store offset=20 + local.get $l2 + i32.const 0 + i32.store offset=16 + local.get $l2 + i32.const 0 + i32.store offset=12 + local.get $p1 + i32.const -16 + i32.add + i32.const 0 + i32.store + local.get $p1 + i32.const -20 + i32.add + i32.const 0 + i32.store + local.get $p1 + i32.const -24 + i32.add + i32.const 0 + i32.store + local.get $p1 + i32.const -28 + i32.add + i32.const 0 + i32.store + local.get $l3 + local.get $l2 + i32.const 4 + i32.and + i32.const 24 + i32.or + local.tee $l3 + i32.sub + local.tee $p1 + i32.const 32 + i32.lt_u + br_if $B0 + local.get $l2 + local.get $l3 + i32.add + local.set $l2 + loop $L1 + local.get $l2 + i64.const 0 + i64.store + local.get $l2 + i32.const 24 + i32.add + i64.const 0 + i64.store + local.get $l2 + i32.const 16 + i32.add + i64.const 0 + i64.store + local.get $l2 + i32.const 8 + i32.add + i64.const 0 + i64.store + local.get $l2 + i32.const 32 + i32.add + local.set $l2 + local.get $p1 + i32.const -32 + i32.add + local.tee $p1 + i32.const 31 + i32.gt_u + br_if $L1 + end + end + local.get $p0) + (func $f167 (type $t1) (param $p0 i32) (param $p1 i32) (param $p2 i32) (result i32) + (local $l3 i32) (local $l4 i32) (local $l5 i32) + block $B0 + local.get $p2 + i32.eqz + br_if $B0 + loop $L1 + local.get $p0 + i32.load8_u + local.tee $l4 + local.get $p1 + i32.load8_u + local.tee $l5 + i32.eq + if $I2 + local.get $p1 + i32.const 1 + i32.add + local.set $p1 + local.get $p0 + i32.const 1 + i32.add + local.set $p0 + local.get $p2 + i32.const -1 + i32.add + local.tee $p2 + br_if $L1 + br $B0 + end + end + local.get $l4 + local.get $l5 + i32.sub + local.set $l3 + end + local.get $l3) + (func $f168 (type $t3) (param $p0 i32) (param $p1 i32) + local.get $p0 + local.get $p1 + i32.const 1060508 + i32.load + local.tee $p0 + i32.const 21 + local.get $p0 + select + call_indirect (type $t3) $T0 + unreachable) + (func $f169 (type $t7) + i32.const 1054301 + i32.const 17 + i32.const 1054320 + call $f172 + unreachable) + (func $f170 (type $t3) (param $p0 i32) (param $p1 i32) + local.get $p0 + local.get $p1 + i64.load align=4 + i64.store align=4 + local.get $p0 + i32.const 8 + i32.add + local.get $p1 + i32.const 8 + i32.add + i32.load + i32.store) + (func $f171 (type $t4) (param $p0 i32) (param $p1 i32) (param $p2 i32) + (local $l3 i32) + global.get $g0 + i32.const 48 + i32.sub + local.tee $l3 + global.set $g0 + local.get $l3 + local.get $p2 + i32.store offset=4 + local.get $l3 + local.get $p1 + i32.store + local.get $l3 + i32.const 28 + i32.add + i32.const 2 + i32.store + local.get $l3 + i32.const 44 + i32.add + i32.const 20 + i32.store + local.get $l3 + i64.const 2 + i64.store offset=12 align=4 + local.get $l3 + i32.const 1054472 + i32.store offset=8 + local.get $l3 + i32.const 20 + i32.store offset=36 + local.get $l3 + local.get $l3 + i32.const 32 + i32.add + i32.store offset=24 + local.get $l3 + local.get $l3 + i32.store offset=40 + local.get $l3 + local.get $l3 + i32.const 4 + i32.add + i32.store offset=32 + local.get $l3 + i32.const 8 + i32.add + local.get $p0 + call $f177 + unreachable) + (func $f172 (type $t4) (param $p0 i32) (param $p1 i32) (param $p2 i32) + (local $l3 i32) + global.get $g0 + i32.const 32 + i32.sub + local.tee $l3 + global.set $g0 + local.get $l3 + i64.const 4 + i64.store offset=16 + local.get $l3 + i64.const 1 + i64.store offset=4 align=4 + local.get $l3 + local.get $p1 + i32.store offset=28 + local.get $l3 + local.get $p0 + i32.store offset=24 + local.get $l3 + local.get $l3 + i32.const 24 + i32.add + i32.store + local.get $l3 + local.get $p2 + call $f177 + unreachable) + (func $f173 (type $t3) (param $p0 i32) (param $p1 i32) + (local $l2 i32) + global.get $g0 + i32.const 48 + i32.sub + local.tee $l2 + global.set $g0 + local.get $l2 + local.get $p1 + i32.store offset=4 + local.get $l2 + local.get $p0 + i32.store + local.get $l2 + i32.const 28 + i32.add + i32.const 2 + i32.store + local.get $l2 + i32.const 44 + i32.add + i32.const 20 + i32.store + local.get $l2 + i64.const 2 + i64.store offset=12 align=4 + local.get $l2 + i32.const 1054716 + i32.store offset=8 + local.get $l2 + i32.const 20 + i32.store offset=36 + local.get $l2 + local.get $l2 + i32.const 32 + i32.add + i32.store offset=24 + local.get $l2 + local.get $l2 + i32.const 4 + i32.add + i32.store offset=40 + local.get $l2 + local.get $l2 + i32.store offset=32 + local.get $l2 + i32.const 8 + i32.add + i32.const 1054732 + call $f177 + unreachable) + (func $f174 (type $t3) (param $p0 i32) (param $p1 i32) + (local $l2 i32) + global.get $g0 + i32.const 48 + i32.sub + local.tee $l2 + global.set $g0 + local.get $l2 + local.get $p1 + i32.store offset=4 + local.get $l2 + local.get $p0 + i32.store + local.get $l2 + i32.const 28 + i32.add + i32.const 2 + i32.store + local.get $l2 + i32.const 44 + i32.add + i32.const 20 + i32.store + local.get $l2 + i64.const 2 + i64.store offset=12 align=4 + local.get $l2 + i32.const 1054784 + i32.store offset=8 + local.get $l2 + i32.const 20 + i32.store offset=36 + local.get $l2 + local.get $l2 + i32.const 32 + i32.add + i32.store offset=24 + local.get $l2 + local.get $l2 + i32.const 4 + i32.add + i32.store offset=40 + local.get $l2 + local.get $l2 + i32.store offset=32 + local.get $l2 + i32.const 8 + i32.add + i32.const 1054800 + call $f177 + unreachable) + (func $f175 (type $t1) (param $p0 i32) (param $p1 i32) (param $p2 i32) (result i32) + (local $l3 i32) (local $l4 i32) (local $l5 i32) (local $l6 i32) (local $l7 i32) (local $l8 i32) (local $l9 i32) (local $l10 i32) (local $l11 i32) (local $l12 i32) (local $l13 i32) (local $l14 i32) + local.get $p0 + i32.load offset=16 + local.set $l3 + block $B0 + block $B1 + block $B2 + block $B3 + local.get $p0 + i32.load offset=8 + local.tee $l13 + i32.const 1 + i32.ne + if $I4 + local.get $l3 + br_if $B3 + local.get $p0 + i32.load offset=24 + local.get $p1 + local.get $p2 + local.get $p0 + i32.const 28 + i32.add + i32.load + i32.load offset=12 + call_indirect (type $t1) $T0 + local.set $l3 + br $B1 + end + local.get $l3 + i32.eqz + br_if $B2 + end + block $B5 + local.get $p2 + i32.eqz + if $I6 + i32.const 0 + local.set $p2 + br $B5 + end + local.get $p1 + local.get $p2 + i32.add + local.set $l7 + local.get $p0 + i32.const 20 + i32.add + i32.load + i32.const 1 + i32.add + local.set $l10 + local.get $p1 + local.tee $l3 + local.set $l11 + loop $L7 + local.get $l3 + i32.const 1 + i32.add + local.set $l5 + block $B8 + block $B9 (result i32) + local.get $l3 + i32.load8_s + local.tee $l4 + i32.const -1 + i32.le_s + if $I10 + block $B11 (result i32) + local.get $l5 + local.get $l7 + i32.eq + if $I12 + i32.const 0 + local.set $l8 + local.get $l7 + br $B11 + end + local.get $l3 + i32.load8_u offset=1 + i32.const 63 + i32.and + local.set $l8 + local.get $l3 + i32.const 2 + i32.add + local.tee $l5 + end + local.set $l3 + local.get $l4 + i32.const 31 + i32.and + local.set $l9 + local.get $l8 + local.get $l9 + i32.const 6 + i32.shl + i32.or + local.get $l4 + i32.const 255 + i32.and + local.tee $l14 + i32.const 223 + i32.le_u + br_if $B9 + drop + block $B13 (result i32) + local.get $l3 + local.get $l7 + i32.eq + if $I14 + i32.const 0 + local.set $l12 + local.get $l7 + br $B13 + end + local.get $l3 + i32.load8_u + i32.const 63 + i32.and + local.set $l12 + local.get $l3 + i32.const 1 + i32.add + local.tee $l5 + end + local.set $l4 + local.get $l12 + local.get $l8 + i32.const 6 + i32.shl + i32.or + local.set $l8 + local.get $l8 + local.get $l9 + i32.const 12 + i32.shl + i32.or + local.get $l14 + i32.const 240 + i32.lt_u + br_if $B9 + drop + block $B15 (result i32) + local.get $l4 + local.get $l7 + i32.eq + if $I16 + local.get $l5 + local.set $l3 + i32.const 0 + br $B15 + end + local.get $l4 + i32.const 1 + i32.add + local.set $l3 + local.get $l4 + i32.load8_u + i32.const 63 + i32.and + end + local.get $l9 + i32.const 18 + i32.shl + i32.const 1835008 + i32.and + local.get $l8 + i32.const 6 + i32.shl + i32.or + i32.or + local.tee $l4 + i32.const 1114112 + i32.ne + br_if $B8 + br $B5 + end + local.get $l4 + i32.const 255 + i32.and + end + local.set $l4 + local.get $l5 + local.set $l3 + end + local.get $l10 + i32.const -1 + i32.add + local.tee $l10 + if $I17 + local.get $l6 + local.get $l11 + i32.sub + local.get $l3 + i32.add + local.set $l6 + local.get $l3 + local.set $l11 + local.get $l3 + local.get $l7 + i32.ne + br_if $L7 + br $B5 + end + end + local.get $l4 + i32.const 1114112 + i32.eq + br_if $B5 + block $B18 + local.get $l6 + i32.eqz + local.get $p2 + local.get $l6 + i32.eq + i32.or + i32.eqz + if $I19 + i32.const 0 + local.set $l3 + local.get $l6 + local.get $p2 + i32.ge_u + br_if $B18 + local.get $p1 + local.get $l6 + i32.add + i32.load8_s + i32.const -64 + i32.lt_s + br_if $B18 + end + local.get $p1 + local.set $l3 + end + local.get $l6 + local.get $p2 + local.get $l3 + select + local.set $p2 + local.get $l3 + local.get $p1 + local.get $l3 + select + local.set $p1 + end + local.get $l13 + br_if $B2 + br $B0 + end + i32.const 0 + local.set $l5 + local.get $p2 + if $I20 + local.get $p2 + local.set $l4 + local.get $p1 + local.set $l3 + loop $L21 + local.get $l5 + local.get $l3 + i32.load8_u + i32.const 192 + i32.and + i32.const 128 + i32.eq + i32.add + local.set $l5 + local.get $l3 + i32.const 1 + i32.add + local.set $l3 + local.get $l4 + i32.const -1 + i32.add + local.tee $l4 + br_if $L21 + end + end + local.get $p2 + local.get $l5 + i32.sub + local.get $p0 + i32.load offset=12 + local.tee $l7 + i32.ge_u + br_if $B0 + i32.const 0 + local.set $l6 + i32.const 0 + local.set $l5 + local.get $p2 + if $I22 + local.get $p2 + local.set $l4 + local.get $p1 + local.set $l3 + loop $L23 + local.get $l5 + local.get $l3 + i32.load8_u + i32.const 192 + i32.and + i32.const 128 + i32.eq + i32.add + local.set $l5 + local.get $l3 + i32.const 1 + i32.add + local.set $l3 + local.get $l4 + i32.const -1 + i32.add + local.tee $l4 + br_if $L23 + end + end + local.get $l5 + local.get $p2 + i32.sub + local.get $l7 + i32.add + local.tee $l3 + local.set $l4 + block $B24 + block $B25 + block $B26 + i32.const 0 + local.get $p0 + i32.load8_u offset=48 + local.tee $l5 + local.get $l5 + i32.const 3 + i32.eq + select + i32.const 1 + i32.sub + br_table $B25 $B26 $B25 $B24 + end + local.get $l3 + i32.const 1 + i32.shr_u + local.set $l6 + local.get $l3 + i32.const 1 + i32.add + i32.const 1 + i32.shr_u + local.set $l4 + br $B24 + end + i32.const 0 + local.set $l4 + local.get $l3 + local.set $l6 + end + local.get $l6 + i32.const 1 + i32.add + local.set $l3 + block $B27 + loop $L28 + local.get $l3 + i32.const -1 + i32.add + local.tee $l3 + i32.eqz + br_if $B27 + local.get $p0 + i32.load offset=24 + local.get $p0 + i32.load offset=4 + local.get $p0 + i32.load offset=28 + i32.load offset=16 + call_indirect (type $t0) $T0 + i32.eqz + br_if $L28 + end + i32.const 1 + return + end + local.get $p0 + i32.load offset=4 + local.set $l5 + i32.const 1 + local.set $l3 + local.get $p0 + i32.load offset=24 + local.get $p1 + local.get $p2 + local.get $p0 + i32.load offset=28 + i32.load offset=12 + call_indirect (type $t1) $T0 + br_if $B1 + local.get $l4 + i32.const 1 + i32.add + local.set $l3 + local.get $p0 + i32.load offset=28 + local.set $p1 + local.get $p0 + i32.load offset=24 + local.set $p0 + loop $L29 + local.get $l3 + i32.const -1 + i32.add + local.tee $l3 + i32.eqz + if $I30 + i32.const 0 + return + end + local.get $p0 + local.get $l5 + local.get $p1 + i32.load offset=16 + call_indirect (type $t0) $T0 + i32.eqz + br_if $L29 + end + i32.const 1 + return + end + local.get $l3 + return + end + local.get $p0 + i32.load offset=24 + local.get $p1 + local.get $p2 + local.get $p0 + i32.const 28 + i32.add + i32.load + i32.load offset=12 + call_indirect (type $t1) $T0) + (func $f176 (type $t6) (param $p0 i32) (param $p1 i32) (param $p2 i32) (param $p3 i32) + (local $l4 i32) (local $l5 i32) (local $l6 i32) (local $l7 i32) (local $l8 i32) (local $l9 i32) + global.get $g0 + i32.const 112 + i32.sub + local.tee $l4 + global.set $g0 + local.get $l4 + local.get $p3 + i32.store offset=12 + local.get $l4 + local.get $p2 + i32.store offset=8 + i32.const 1 + local.set $l8 + local.get $p1 + local.set $l6 + block $B0 + local.get $p1 + i32.const 257 + i32.lt_u + br_if $B0 + i32.const 0 + local.get $p1 + i32.sub + local.set $l7 + i32.const 256 + local.set $l5 + loop $L1 + block $B2 + local.get $l5 + local.get $p1 + i32.ge_u + br_if $B2 + local.get $p0 + local.get $l5 + i32.add + i32.load8_s + i32.const -65 + i32.le_s + br_if $B2 + i32.const 0 + local.set $l8 + local.get $l5 + local.set $l6 + br $B0 + end + local.get $l5 + i32.const -1 + i32.add + local.set $l6 + i32.const 0 + local.set $l8 + local.get $l5 + i32.const 1 + i32.eq + br_if $B0 + local.get $l5 + local.get $l7 + i32.add + local.get $l6 + local.set $l5 + i32.const 1 + i32.ne + br_if $L1 + end + end + local.get $l4 + local.get $l6 + i32.store offset=20 + local.get $l4 + local.get $p0 + i32.store offset=16 + local.get $l4 + i32.const 0 + i32.const 5 + local.get $l8 + select + i32.store offset=28 + local.get $l4 + i32.const 1054336 + i32.const 1055231 + local.get $l8 + select + i32.store offset=24 + block $B3 + block $B4 + block $B5 + local.get $p2 + local.get $p1 + i32.gt_u + local.tee $l5 + local.get $p3 + local.get $p1 + i32.gt_u + i32.or + i32.eqz + if $I6 + local.get $p2 + local.get $p3 + i32.gt_u + br_if $B5 + block $B7 + local.get $p2 + i32.eqz + local.get $p1 + local.get $p2 + i32.eq + i32.or + i32.eqz + if $I8 + local.get $p1 + local.get $p2 + i32.le_u + br_if $B7 + local.get $p0 + local.get $p2 + i32.add + i32.load8_s + i32.const -64 + i32.lt_s + br_if $B7 + end + local.get $p3 + local.set $p2 + end + local.get $l4 + local.get $p2 + i32.store offset=32 + local.get $p2 + i32.eqz + local.get $p1 + local.get $p2 + i32.eq + i32.or + br_if $B4 + local.get $p1 + i32.const 1 + i32.add + local.set $p3 + loop $L9 + local.get $p2 + local.get $p1 + i32.lt_u + if $I10 + local.get $p0 + local.get $p2 + i32.add + i32.load8_s + i32.const -64 + i32.ge_s + br_if $B4 + end + local.get $p2 + i32.const -1 + i32.add + local.set $l5 + local.get $p2 + i32.const 1 + i32.eq + br_if $B3 + local.get $p2 + local.get $p3 + i32.eq + local.get $l5 + local.set $p2 + i32.eqz + br_if $L9 + end + br $B3 + end + local.get $l4 + local.get $p2 + local.get $p3 + local.get $l5 + select + i32.store offset=40 + local.get $l4 + i32.const 68 + i32.add + i32.const 3 + i32.store + local.get $l4 + i32.const 92 + i32.add + i32.const 86 + i32.store + local.get $l4 + i32.const 84 + i32.add + i32.const 86 + i32.store + local.get $l4 + i64.const 3 + i64.store offset=52 align=4 + local.get $l4 + i32.const 1055272 + i32.store offset=48 + local.get $l4 + i32.const 20 + i32.store offset=76 + local.get $l4 + local.get $l4 + i32.const 72 + i32.add + i32.store offset=64 + local.get $l4 + local.get $l4 + i32.const 24 + i32.add + i32.store offset=88 + local.get $l4 + local.get $l4 + i32.const 16 + i32.add + i32.store offset=80 + local.get $l4 + local.get $l4 + i32.const 40 + i32.add + i32.store offset=72 + local.get $l4 + i32.const 48 + i32.add + i32.const 1055296 + call $f177 + unreachable + end + local.get $l4 + i32.const 100 + i32.add + i32.const 86 + i32.store + local.get $l4 + i32.const 92 + i32.add + i32.const 86 + i32.store + local.get $l4 + i32.const 84 + i32.add + i32.const 20 + i32.store + local.get $l4 + i32.const 68 + i32.add + i32.const 4 + i32.store + local.get $l4 + i64.const 4 + i64.store offset=52 align=4 + local.get $l4 + i32.const 1055348 + i32.store offset=48 + local.get $l4 + i32.const 20 + i32.store offset=76 + local.get $l4 + local.get $l4 + i32.const 72 + i32.add + i32.store offset=64 + local.get $l4 + local.get $l4 + i32.const 24 + i32.add + i32.store offset=96 + local.get $l4 + local.get $l4 + i32.const 16 + i32.add + i32.store offset=88 + local.get $l4 + local.get $l4 + i32.const 12 + i32.add + i32.store offset=80 + local.get $l4 + local.get $l4 + i32.const 8 + i32.add + i32.store offset=72 + local.get $l4 + i32.const 48 + i32.add + i32.const 1055380 + call $f177 + unreachable + end + local.get $p2 + local.set $l5 + end + block $B11 + local.get $p1 + local.get $l5 + i32.eq + br_if $B11 + i32.const 1 + local.set $l6 + block $B12 + block $B13 + block $B14 + local.get $p0 + local.get $l5 + i32.add + local.tee $l7 + i32.load8_s + local.tee $p2 + i32.const -1 + i32.le_s + if $I15 + i32.const 0 + local.set $l8 + local.get $p0 + local.get $p1 + i32.add + local.tee $p3 + local.set $p1 + local.get $p3 + local.get $l7 + i32.const 1 + i32.add + i32.ne + if $I16 + local.get $l7 + i32.load8_u offset=1 + i32.const 63 + i32.and + local.set $l8 + local.get $l7 + i32.const 2 + i32.add + local.set $p1 + end + local.get $p2 + i32.const 31 + i32.and + local.set $l7 + local.get $p2 + i32.const 255 + i32.and + i32.const 223 + i32.gt_u + br_if $B14 + local.get $l8 + local.get $l7 + i32.const 6 + i32.shl + i32.or + local.set $p1 + br $B13 + end + local.get $l4 + local.get $p2 + i32.const 255 + i32.and + i32.store offset=36 + local.get $l4 + i32.const 40 + i32.add + local.set $p2 + br $B12 + end + i32.const 0 + local.set $p0 + local.get $p3 + local.set $l6 + local.get $p1 + local.get $p3 + i32.ne + if $I17 (result i32) + local.get $p1 + i32.const 1 + i32.add + local.set $l6 + local.get $p1 + i32.load8_u + i32.const 63 + i32.and + else + i32.const 0 + end + local.get $l8 + i32.const 6 + i32.shl + i32.or + local.set $p0 + local.get $p2 + i32.const 255 + i32.and + i32.const 240 + i32.lt_u + if $I18 + local.get $p0 + local.get $l7 + i32.const 12 + i32.shl + i32.or + local.set $p1 + br $B13 + end + i32.const 0 + local.set $p2 + local.get $p3 + local.get $l6 + i32.ne + if $I19 (result i32) + local.get $l6 + i32.load8_u + i32.const 63 + i32.and + else + i32.const 0 + end + local.get $l7 + i32.const 18 + i32.shl + i32.const 1835008 + i32.and + local.get $p0 + i32.const 6 + i32.shl + i32.or + i32.or + local.tee $p1 + i32.const 1114112 + i32.eq + br_if $B11 + end + local.get $l4 + local.get $p1 + i32.store offset=36 + i32.const 1 + local.set $l6 + local.get $l4 + i32.const 40 + i32.add + local.set $p2 + local.get $p1 + i32.const 128 + i32.lt_u + br_if $B12 + i32.const 2 + local.set $l6 + local.get $p1 + i32.const 2048 + i32.lt_u + br_if $B12 + i32.const 3 + i32.const 4 + local.get $p1 + i32.const 65536 + i32.lt_u + select + local.set $l6 + end + local.get $l4 + local.get $l5 + i32.store offset=40 + local.get $l4 + local.get $l5 + local.get $l6 + i32.add + i32.store offset=44 + local.get $l4 + i32.const 68 + i32.add + i32.const 5 + i32.store + local.get $l4 + i32.const 108 + i32.add + i32.const 86 + i32.store + local.get $l4 + i32.const 100 + i32.add + i32.const 86 + i32.store + local.get $l4 + i32.const 92 + i32.add + i32.const 87 + i32.store + local.get $l4 + i32.const 84 + i32.add + i32.const 88 + i32.store + local.get $l4 + i64.const 5 + i64.store offset=52 align=4 + local.get $l4 + i32.const 1055448 + i32.store offset=48 + local.get $l4 + local.get $p2 + i32.store offset=88 + local.get $l4 + i32.const 20 + i32.store offset=76 + local.get $l4 + local.get $l4 + i32.const 72 + i32.add + i32.store offset=64 + local.get $l4 + local.get $l4 + i32.const 24 + i32.add + i32.store offset=104 + local.get $l4 + local.get $l4 + i32.const 16 + i32.add + i32.store offset=96 + local.get $l4 + local.get $l4 + i32.const 36 + i32.add + i32.store offset=80 + local.get $l4 + local.get $l4 + i32.const 32 + i32.add + i32.store offset=72 + local.get $l4 + i32.const 48 + i32.add + i32.const 1055488 + call $f177 + unreachable + end + i32.const 1054488 + i32.const 43 + i32.const 1054552 + call $f172 + unreachable) + (func $f177 (type $t3) (param $p0 i32) (param $p1 i32) + (local $l2 i32) + global.get $g0 + i32.const 16 + i32.sub + local.tee $l2 + global.set $g0 + local.get $l2 + local.get $p1 + i32.store offset=12 + local.get $l2 + local.get $p0 + i32.store offset=8 + local.get $l2 + i32.const 1054376 + i32.store offset=4 + local.get $l2 + i32.const 1 + i32.store + local.get $l2 + call $f133 + unreachable) + (func $f178 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + local.get $p0 + i64.load32_u + i32.const 1 + local.get $p1 + call $f214) + (func $f179 (type $t1) (param $p0 i32) (param $p1 i32) (param $p2 i32) (result i32) + (local $l3 i32) (local $l4 i32) (local $l5 i32) (local $l6 i32) (local $l7 i32) (local $l8 i32) (local $l9 i32) (local $l10 i32) + global.get $g0 + i32.const -64 + i32.add + local.tee $l3 + global.set $g0 + local.get $l3 + i32.const 36 + i32.add + local.get $p1 + i32.store + local.get $l3 + i32.const 52 + i32.add + local.get $p2 + i32.const 20 + i32.add + i32.load + local.tee $l4 + i32.store + local.get $l3 + i32.const 3 + i32.store8 offset=56 + local.get $l3 + i32.const 44 + i32.add + local.get $p2 + i32.load offset=16 + local.tee $l5 + local.get $l4 + i32.const 3 + i32.shl + i32.add + i32.store + local.get $l3 + i64.const 137438953472 + i64.store offset=8 + local.get $l3 + local.get $p0 + i32.store offset=32 + local.get $l3 + i32.const 0 + i32.store offset=24 + local.get $l3 + i32.const 0 + i32.store offset=16 + local.get $l3 + local.get $l5 + i32.store offset=48 + local.get $l3 + local.get $l5 + i32.store offset=40 + block $B0 + block $B1 + block $B2 + block $B3 + local.get $p2 + i32.load offset=8 + local.tee $l6 + i32.eqz + if $I4 + local.get $p2 + i32.load + local.set $l8 + local.get $p2 + i32.load offset=4 + local.tee $l9 + local.get $l4 + local.get $l4 + local.get $l9 + i32.gt_u + select + local.tee $l6 + i32.eqz + br_if $B3 + i32.const 1 + local.set $l4 + local.get $p0 + local.get $l8 + i32.load + local.get $l8 + i32.load offset=4 + local.get $p1 + i32.load offset=12 + call_indirect (type $t1) $T0 + br_if $B0 + local.get $l8 + i32.const 12 + i32.add + local.set $p2 + i32.const 1 + local.set $l7 + loop $L5 + local.get $l5 + i32.load + local.get $l3 + i32.const 8 + i32.add + local.get $l5 + i32.const 4 + i32.add + i32.load + call_indirect (type $t0) $T0 + if $I6 + br $B0 + end + local.get $l7 + local.get $l6 + i32.ge_u + br_if $B3 + local.get $p2 + i32.const -4 + i32.add + local.set $p0 + local.get $p2 + i32.load + local.set $p1 + local.get $p2 + i32.const 8 + i32.add + local.set $p2 + local.get $l5 + i32.const 8 + i32.add + local.set $l5 + local.get $l7 + i32.const 1 + i32.add + local.set $l7 + local.get $l3 + i32.load offset=32 + local.get $p0 + i32.load + local.get $p1 + local.get $l3 + i32.load offset=36 + i32.load offset=12 + call_indirect (type $t1) $T0 + i32.eqz + br_if $L5 + end + br $B0 + end + local.get $p2 + i32.load + local.set $l8 + local.get $p2 + i32.load offset=4 + local.tee $l9 + local.get $p2 + i32.const 12 + i32.add + i32.load + local.tee $p2 + local.get $p2 + local.get $l9 + i32.gt_u + select + local.tee $l10 + i32.eqz + br_if $B3 + i32.const 1 + local.set $l4 + local.get $p0 + local.get $l8 + i32.load + local.get $l8 + i32.load offset=4 + local.get $p1 + i32.load offset=12 + call_indirect (type $t1) $T0 + br_if $B0 + local.get $l8 + i32.const 12 + i32.add + local.set $p2 + local.get $l6 + i32.const 16 + i32.add + local.set $l5 + i32.const 1 + local.set $l7 + loop $L7 + local.get $l3 + local.get $l5 + i32.const -8 + i32.add + i32.load + i32.store offset=12 + local.get $l3 + local.get $l5 + i32.const 16 + i32.add + i32.load8_u + i32.store8 offset=56 + local.get $l3 + local.get $l5 + i32.const -4 + i32.add + i32.load + i32.store offset=8 + i32.const 0 + local.set $p1 + i32.const 0 + local.set $p0 + block $B8 + block $B9 + block $B10 + block $B11 + local.get $l5 + i32.const 8 + i32.add + i32.load + i32.const 1 + i32.sub + br_table $B10 $B9 $B8 $B11 + end + local.get $l5 + i32.const 12 + i32.add + i32.load + local.set $l4 + i32.const 1 + local.set $p0 + br $B8 + end + local.get $l5 + i32.const 12 + i32.add + i32.load + local.tee $l6 + local.get $l3 + i32.load offset=52 + local.tee $l4 + i32.lt_u + if $I12 + local.get $l3 + i32.load offset=48 + local.get $l6 + i32.const 3 + i32.shl + i32.add + local.tee $l6 + i32.load offset=4 + i32.const 89 + i32.ne + br_if $B8 + local.get $l6 + i32.load + i32.load + local.set $l4 + i32.const 1 + local.set $p0 + br $B8 + end + i32.const 1055836 + local.get $l6 + local.get $l4 + call $f171 + unreachable + end + local.get $l3 + i32.load offset=40 + local.tee $l6 + local.get $l3 + i32.load offset=44 + i32.eq + br_if $B8 + local.get $l3 + local.get $l6 + i32.const 8 + i32.add + i32.store offset=40 + local.get $l6 + i32.load offset=4 + i32.const 89 + i32.ne + br_if $B8 + local.get $l6 + i32.load + i32.load + local.set $l4 + i32.const 1 + local.set $p0 + end + local.get $l3 + local.get $l4 + i32.store offset=20 + local.get $l3 + local.get $p0 + i32.store offset=16 + block $B13 + block $B14 (result i32) + block $B15 + block $B16 + block $B17 + block $B18 + block $B19 + local.get $l5 + i32.load + i32.const 1 + i32.sub + br_table $B18 $B19 $B13 $B15 + end + local.get $l3 + i32.load offset=40 + local.tee $p0 + local.get $l3 + i32.load offset=44 + i32.ne + br_if $B17 + br $B13 + end + local.get $l5 + i32.const 4 + i32.add + i32.load + local.tee $p0 + local.get $l3 + i32.load offset=52 + local.tee $l4 + i32.ge_u + br_if $B16 + local.get $l3 + i32.load offset=48 + local.get $p0 + i32.const 3 + i32.shl + i32.add + local.tee $p0 + i32.load offset=4 + i32.const 89 + i32.ne + br_if $B13 + local.get $p0 + i32.load + i32.load + br $B14 + end + local.get $l3 + local.get $p0 + i32.const 8 + i32.add + i32.store offset=40 + local.get $p0 + i32.load offset=4 + i32.const 89 + i32.ne + br_if $B13 + local.get $p0 + i32.load + i32.load + br $B14 + end + i32.const 1055836 + local.get $p0 + local.get $l4 + call $f171 + unreachable + end + local.get $l5 + i32.const 4 + i32.add + i32.load + end + local.set $l4 + i32.const 1 + local.set $p1 + end + local.get $l3 + local.get $l4 + i32.store offset=28 + local.get $l3 + local.get $p1 + i32.store offset=24 + block $B20 + local.get $l5 + i32.const -16 + i32.add + i32.load + i32.const 1 + i32.ne + if $I21 + local.get $l3 + i32.load offset=40 + local.tee $l4 + local.get $l3 + i32.load offset=44 + i32.eq + br_if $B2 + local.get $l3 + local.get $l4 + i32.const 8 + i32.add + i32.store offset=40 + br $B20 + end + local.get $l5 + i32.const -12 + i32.add + i32.load + local.tee $p0 + local.get $l3 + i32.load offset=52 + local.tee $p1 + i32.ge_u + br_if $B1 + local.get $l3 + i32.load offset=48 + local.get $p0 + i32.const 3 + i32.shl + i32.add + local.set $l4 + end + local.get $l4 + i32.load + local.get $l3 + i32.const 8 + i32.add + local.get $l4 + i32.const 4 + i32.add + i32.load + call_indirect (type $t0) $T0 + if $I22 + i32.const 1 + local.set $l4 + br $B0 + end + local.get $l7 + local.get $l10 + i32.ge_u + br_if $B3 + local.get $p2 + i32.const -4 + i32.add + local.set $p0 + local.get $p2 + i32.load + local.set $p1 + local.get $p2 + i32.const 8 + i32.add + local.set $p2 + local.get $l5 + i32.const 36 + i32.add + local.set $l5 + i32.const 1 + local.set $l4 + local.get $l7 + i32.const 1 + i32.add + local.set $l7 + local.get $l3 + i32.load offset=32 + local.get $p0 + i32.load + local.get $p1 + local.get $l3 + i32.load offset=36 + i32.load offset=12 + call_indirect (type $t1) $T0 + i32.eqz + br_if $L7 + end + br $B0 + end + local.get $l9 + local.get $l7 + i32.gt_u + if $I23 + i32.const 1 + local.set $l4 + local.get $l3 + i32.load offset=32 + local.get $l8 + local.get $l7 + i32.const 3 + i32.shl + i32.add + local.tee $p0 + i32.load + local.get $p0 + i32.load offset=4 + local.get $l3 + i32.load offset=36 + i32.load offset=12 + call_indirect (type $t1) $T0 + br_if $B0 + end + i32.const 0 + local.set $l4 + br $B0 + end + i32.const 1054488 + i32.const 43 + i32.const 1054552 + call $f172 + unreachable + end + i32.const 1055820 + local.get $p0 + local.get $p1 + call $f171 + unreachable + end + local.get $l3 + i32.const -64 + i32.sub + global.set $g0 + local.get $l4) + (func $f180 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + (local $l2 i32) (local $l3 i32) (local $l4 i32) + global.get $g0 + i32.const 32 + i32.sub + local.tee $l2 + global.set $g0 + block $B0 + local.get $p0 + local.get $p1 + call $f181 + br_if $B0 + local.get $p1 + i32.const 28 + i32.add + i32.load + local.set $l3 + local.get $p1 + i32.load offset=24 + local.get $l2 + i64.const 4 + i64.store offset=24 + local.get $l2 + i64.const 1 + i64.store offset=12 align=4 + local.get $l2 + i32.const 1054340 + i32.store offset=8 + local.get $l3 + local.get $l2 + i32.const 8 + i32.add + call $f179 + br_if $B0 + local.get $p0 + i32.const 4 + i32.add + local.get $p1 + call $f181 + local.get $l2 + i32.const 32 + i32.add + global.set $g0 + return + end + local.get $l2 + i32.const 32 + i32.add + global.set $g0 + i32.const 1) + (func $f181 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + (local $l2 i32) (local $l3 i32) (local $l4 i32) + global.get $g0 + i32.const 128 + i32.sub + local.tee $l4 + global.set $g0 + block $B0 + block $B1 + block $B2 (result i32) + block $B3 + local.get $p1 + i32.load + local.tee $l3 + i32.const 16 + i32.and + i32.eqz + if $I4 + local.get $p0 + i32.load + local.set $l2 + local.get $l3 + i32.const 32 + i32.and + br_if $B3 + local.get $l2 + i64.extend_i32_u + i32.const 1 + local.get $p1 + call $f214 + br $B2 + end + local.get $p0 + i32.load + local.set $l2 + i32.const 0 + local.set $p0 + loop $L5 + local.get $p0 + local.get $l4 + i32.add + i32.const 127 + i32.add + local.get $l2 + i32.const 15 + i32.and + local.tee $l3 + i32.const 48 + i32.or + local.get $l3 + i32.const 87 + i32.add + local.get $l3 + i32.const 10 + i32.lt_u + select + i32.store8 + local.get $p0 + i32.const -1 + i32.add + local.set $p0 + local.get $l2 + i32.const 4 + i32.shr_u + local.tee $l2 + br_if $L5 + end + local.get $p0 + i32.const 128 + i32.add + local.tee $l2 + i32.const 129 + i32.ge_u + br_if $B1 + local.get $p1 + i32.const 1 + i32.const 1055569 + i32.const 2 + local.get $p0 + local.get $l4 + i32.add + i32.const 128 + i32.add + i32.const 0 + local.get $p0 + i32.sub + call $f216 + br $B2 + end + i32.const 0 + local.set $p0 + loop $L6 + local.get $p0 + local.get $l4 + i32.add + i32.const 127 + i32.add + local.get $l2 + i32.const 15 + i32.and + local.tee $l3 + i32.const 48 + i32.or + local.get $l3 + i32.const 55 + i32.add + local.get $l3 + i32.const 10 + i32.lt_u + select + i32.store8 + local.get $p0 + i32.const -1 + i32.add + local.set $p0 + local.get $l2 + i32.const 4 + i32.shr_u + local.tee $l2 + br_if $L6 + end + local.get $p0 + i32.const 128 + i32.add + local.tee $l2 + i32.const 129 + i32.ge_u + br_if $B0 + local.get $p1 + i32.const 1 + i32.const 1055569 + i32.const 2 + local.get $p0 + local.get $l4 + i32.add + i32.const 128 + i32.add + i32.const 0 + local.get $p0 + i32.sub + call $f216 + end + local.get $l4 + i32.const 128 + i32.add + global.set $g0 + return + end + local.get $l2 + i32.const 128 + call $f174 + unreachable + end + local.get $l2 + i32.const 128 + call $f174 + unreachable) + (func $f182 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + local.get $p1 + i32.load offset=24 + i32.const 1054348 + i32.const 11 + local.get $p1 + i32.const 28 + i32.add + i32.load + i32.load offset=12 + call_indirect (type $t1) $T0) + (func $f183 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + local.get $p1 + i32.load offset=24 + i32.const 1054359 + i32.const 14 + local.get $p1 + i32.const 28 + i32.add + i32.load + i32.load offset=12 + call_indirect (type $t1) $T0) + (func $f184 (type $t5) (param $p0 i32) (result i32) + (local $l1 i32) (local $l2 i32) + i32.const 1114112 + local.set $l1 + block $B0 + block $B1 + block $B2 + block $B3 + local.get $p0 + i32.load + i32.const 1 + i32.sub + br_table $B2 $B3 $B1 $B0 + end + local.get $p0 + i32.const 1 + i32.store + i32.const 92 + return + end + local.get $p0 + i32.const 0 + i32.store + local.get $p0 + i32.load offset=4 + return + end + block $B4 + block $B5 + block $B6 + block $B7 + block $B8 + local.get $p0 + i32.const 12 + i32.add + i32.load8_u + i32.const 1 + i32.sub + br_table $B4 $B5 $B6 $B7 $B8 $B0 + end + local.get $p0 + i32.const 4 + i32.store8 offset=12 + i32.const 92 + return + end + local.get $p0 + i32.const 3 + i32.store8 offset=12 + i32.const 117 + return + end + local.get $p0 + i32.const 2 + i32.store8 offset=12 + i32.const 123 + return + end + local.get $p0 + i32.load offset=4 + local.get $p0 + i32.const 8 + i32.add + i32.load + local.tee $l1 + i32.const 2 + i32.shl + i32.const 28 + i32.and + i32.shr_u + i32.const 15 + i32.and + local.tee $l2 + i32.const 48 + i32.or + local.get $l2 + i32.const 87 + i32.add + local.get $l2 + i32.const 10 + i32.lt_u + select + local.set $l2 + local.get $l1 + if $I9 + local.get $p0 + local.get $l1 + i32.const -1 + i32.add + i32.store offset=8 + local.get $l2 + return + end + local.get $p0 + i32.const 1 + i32.store8 offset=12 + local.get $l2 + return + end + local.get $p0 + i32.const 0 + i32.store8 offset=12 + i32.const 125 + local.set $l1 + end + local.get $l1) + (func $f185 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + local.get $p1 + local.get $p0 + i32.load + local.get $p0 + i32.load offset=4 + call $f175) + (func $f186 (type $t11) (param $p0 i32) (param $p1 i32) (param $p2 i32) (param $p3 i32) (param $p4 i32) + local.get $p0 + local.get $p4 + i32.store offset=12 + local.get $p0 + local.get $p3 + i32.store offset=8 + local.get $p0 + local.get $p2 + i32.store offset=4 + local.get $p0 + local.get $p1 + i32.store) + (func $f187 (type $t3) (param $p0 i32) (param $p1 i32) + local.get $p0 + local.get $p1 + i64.load align=4 + i64.store align=4) + (func $f188 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + (local $l2 i32) + global.get $g0 + i32.const 48 + i32.sub + local.tee $l2 + global.set $g0 + local.get $l2 + i32.const 20 + i32.add + i32.const 20 + i32.store + local.get $l2 + i32.const 12 + i32.add + i32.const 20 + i32.store + local.get $l2 + i32.const 86 + i32.store offset=4 + local.get $l2 + local.get $p0 + i32.store + local.get $l2 + local.get $p0 + i32.const 12 + i32.add + i32.store offset=16 + local.get $l2 + local.get $p0 + i32.const 8 + i32.add + i32.store offset=8 + local.get $p1 + i32.const 28 + i32.add + i32.load + local.set $p0 + local.get $p1 + i32.load offset=24 + local.get $l2 + i32.const 44 + i32.add + i32.const 3 + i32.store + local.get $l2 + i64.const 3 + i64.store offset=28 align=4 + local.get $l2 + i32.const 1054396 + i32.store offset=24 + local.get $l2 + local.get $l2 + i32.store offset=40 + local.get $p0 + local.get $l2 + i32.const 24 + i32.add + call $f179 + local.get $l2 + i32.const 48 + i32.add + global.set $g0) + (func $f189 (type $t11) (param $p0 i32) (param $p1 i32) (param $p2 i32) (param $p3 i32) (param $p4 i32) + (local $l5 i32) (local $l6 i32) (local $l7 i32) (local $l8 i32) (local $l9 i64) (local $l10 i64) (local $l11 i64) (local $l12 i64) (local $l13 i64) + global.get $g0 + i32.const 80 + i32.sub + local.tee $l5 + global.set $g0 + i32.const 1 + local.set $l7 + block $B0 + local.get $p0 + i32.load8_u offset=4 + br_if $B0 + local.get $p0 + i32.load8_u offset=5 + local.set $l8 + local.get $p0 + i32.load + local.tee $l6 + i32.load8_u + i32.const 4 + i32.and + i32.eqz + if $I1 + local.get $l6 + i32.load offset=24 + i32.const 1055537 + i32.const 1055539 + local.get $l8 + select + i32.const 2 + i32.const 3 + local.get $l8 + select + local.get $l6 + i32.const 28 + i32.add + i32.load + i32.load offset=12 + call_indirect (type $t1) $T0 + br_if $B0 + local.get $p0 + i32.load + local.tee $l6 + i32.load offset=24 + local.get $p1 + local.get $p2 + local.get $l6 + i32.const 28 + i32.add + i32.load + i32.load offset=12 + call_indirect (type $t1) $T0 + br_if $B0 + local.get $p0 + i32.load + local.tee $p1 + i32.load offset=24 + i32.const 1054592 + i32.const 2 + local.get $p1 + i32.const 28 + i32.add + i32.load + i32.load offset=12 + call_indirect (type $t1) $T0 + br_if $B0 + local.get $p3 + local.get $p0 + i32.load + local.get $p4 + i32.load offset=12 + call_indirect (type $t0) $T0 + local.set $l7 + br $B0 + end + local.get $l8 + i32.eqz + if $I2 + local.get $l6 + i32.load offset=24 + i32.const 1055532 + i32.const 3 + local.get $l6 + i32.const 28 + i32.add + i32.load + i32.load offset=12 + call_indirect (type $t1) $T0 + br_if $B0 + local.get $p0 + i32.load + local.set $l6 + end + local.get $l5 + i32.const 1 + i32.store8 offset=23 + local.get $l5 + local.get $l5 + i32.const 23 + i32.add + i32.store offset=16 + local.get $l6 + i64.load offset=8 align=4 + local.set $l9 + local.get $l6 + i64.load offset=16 align=4 + local.set $l10 + local.get $l5 + i32.const 52 + i32.add + i32.const 1055504 + i32.store + local.get $l5 + local.get $l6 + i64.load offset=24 align=4 + i64.store offset=8 + local.get $l6 + i64.load offset=32 align=4 + local.set $l11 + local.get $l6 + i64.load offset=40 align=4 + local.set $l12 + local.get $l5 + local.get $l6 + i32.load8_u offset=48 + i32.store8 offset=72 + local.get $l6 + i64.load align=4 + local.set $l13 + local.get $l5 + local.get $l12 + i64.store offset=64 + local.get $l5 + local.get $l11 + i64.store offset=56 + local.get $l5 + local.get $l10 + i64.store offset=40 + local.get $l5 + local.get $l9 + i64.store offset=32 + local.get $l5 + local.get $l13 + i64.store offset=24 + local.get $l5 + local.get $l5 + i32.const 8 + i32.add + i32.store offset=48 + local.get $l5 + i32.const 8 + i32.add + local.get $p1 + local.get $p2 + call $f205 + br_if $B0 + local.get $l5 + i32.const 8 + i32.add + i32.const 1054592 + i32.const 2 + call $f205 + br_if $B0 + local.get $p3 + local.get $l5 + i32.const 24 + i32.add + local.get $p4 + i32.load offset=12 + call_indirect (type $t0) $T0 + br_if $B0 + local.get $l5 + i32.load offset=48 + i32.const 1055535 + i32.const 2 + local.get $l5 + i32.load offset=52 + i32.load offset=12 + call_indirect (type $t1) $T0 + local.set $l7 + end + local.get $p0 + i32.const 1 + i32.store8 offset=5 + local.get $p0 + local.get $l7 + i32.store8 offset=4 + local.get $l5 + i32.const 80 + i32.add + global.set $g0) + (func $f190 (type $t7) + (local $l0 i32) + global.get $g0 + i32.const 48 + i32.sub + local.tee $l0 + global.set $g0 + local.get $l0 + i32.const 36 + i32.store offset=12 + local.get $l0 + i32.const 1050796 + i32.store offset=8 + local.get $l0 + i32.const 36 + i32.add + i32.const 1 + i32.store + local.get $l0 + i64.const 1 + i64.store offset=20 align=4 + local.get $l0 + i32.const 1054568 + i32.store offset=16 + local.get $l0 + i32.const 86 + i32.store offset=44 + local.get $l0 + local.get $l0 + i32.const 40 + i32.add + i32.store offset=32 + local.get $l0 + local.get $l0 + i32.const 8 + i32.add + i32.store offset=40 + local.get $l0 + i32.const 16 + i32.add + i32.const 1054576 + call $f177 + unreachable) + (func $f191 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + local.get $p0 + i32.load + local.get $p1 + local.get $p0 + i32.load offset=4 + i32.load offset=12 + call_indirect (type $t0) $T0) + (func $f192 (type $t6) (param $p0 i32) (param $p1 i32) (param $p2 i32) (param $p3 i32) + (local $l4 i32) + global.get $g0 + i32.const -64 + i32.add + local.tee $l4 + global.set $g0 + local.get $l4 + local.get $p1 + i32.store offset=12 + local.get $l4 + local.get $p0 + i32.store offset=8 + local.get $l4 + local.get $p3 + i32.store offset=20 + local.get $l4 + local.get $p2 + i32.store offset=16 + local.get $l4 + i32.const 44 + i32.add + i32.const 2 + i32.store + local.get $l4 + i32.const 60 + i32.add + i32.const 90 + i32.store + local.get $l4 + i64.const 2 + i64.store offset=28 align=4 + local.get $l4 + i32.const 1054596 + i32.store offset=24 + local.get $l4 + i32.const 86 + i32.store offset=52 + local.get $l4 + local.get $l4 + i32.const 48 + i32.add + i32.store offset=40 + local.get $l4 + local.get $l4 + i32.const 16 + i32.add + i32.store offset=56 + local.get $l4 + local.get $l4 + i32.const 8 + i32.add + i32.store offset=48 + local.get $l4 + i32.const 24 + i32.add + i32.const 1054636 + call $f177 + unreachable) + (func $f193 (type $t6) (param $p0 i32) (param $p1 i32) (param $p2 i32) (param $p3 i32) + (local $l4 i32) (local $l5 i32) (local $l6 i32) (local $l7 i32) (local $l8 i32) (local $l9 i32) + block $B0 + block $B1 + local.get $p2 + i32.const 3 + i32.and + local.tee $l4 + i32.eqz + br_if $B1 + i32.const 4 + local.get $l4 + i32.sub + local.tee $l4 + i32.eqz + br_if $B1 + local.get $p3 + local.get $l4 + local.get $l4 + local.get $p3 + i32.gt_u + select + local.set $l5 + i32.const 0 + local.set $l4 + local.get $p1 + i32.const 255 + i32.and + local.set $l8 + loop $L2 + local.get $l4 + local.get $l5 + i32.eq + br_if $B1 + local.get $p2 + local.get $l4 + i32.add + local.get $l4 + i32.const 1 + i32.add + local.set $l4 + i32.load8_u + local.tee $l6 + local.get $l8 + i32.ne + br_if $L2 + end + i32.const 1 + local.set $p3 + local.get $l6 + local.get $p1 + i32.const 255 + i32.and + i32.eq + i32.const 1 + i32.add + i32.const 1 + i32.and + local.get $l4 + i32.add + i32.const -1 + i32.add + local.set $l4 + br $B0 + end + local.get $p1 + i32.const 255 + i32.and + local.set $l8 + block $B3 + block $B4 + local.get $p3 + i32.const 8 + i32.lt_u + br_if $B4 + local.get $l5 + local.get $p3 + i32.const -8 + i32.add + local.tee $l6 + i32.gt_u + br_if $B4 + local.get $l8 + i32.const 16843009 + i32.mul + local.set $l4 + loop $L5 + local.get $p2 + local.get $l5 + i32.add + local.tee $l7 + i32.const 4 + i32.add + i32.load + local.get $l4 + i32.xor + local.tee $l9 + i32.const -1 + i32.xor + local.get $l9 + i32.const -16843009 + i32.add + i32.and + local.get $l7 + i32.load + local.get $l4 + i32.xor + local.tee $l7 + i32.const -1 + i32.xor + local.get $l7 + i32.const -16843009 + i32.add + i32.and + i32.or + i32.const -2139062144 + i32.and + i32.eqz + if $I6 + local.get $l5 + i32.const 8 + i32.add + local.tee $l5 + local.get $l6 + i32.le_u + br_if $L5 + end + end + local.get $l5 + local.get $p3 + i32.gt_u + br_if $B3 + end + local.get $p2 + local.get $l5 + i32.add + local.set $p2 + local.get $p3 + local.get $l5 + i32.sub + local.set $l6 + i32.const 0 + local.set $p3 + i32.const 0 + local.set $l4 + block $B7 + loop $L8 + local.get $l4 + local.get $l6 + i32.eq + br_if $B7 + local.get $p2 + local.get $l4 + i32.add + local.get $l4 + i32.const 1 + i32.add + local.set $l4 + i32.load8_u + local.tee $l7 + local.get $l8 + i32.ne + br_if $L8 + end + i32.const 1 + local.set $p3 + local.get $l7 + local.get $p1 + i32.const 255 + i32.and + i32.eq + i32.const 1 + i32.add + i32.const 1 + i32.and + local.get $l4 + i32.add + i32.const -1 + i32.add + local.set $l4 + end + local.get $l4 + local.get $l5 + i32.add + local.set $l4 + br $B0 + end + local.get $l5 + local.get $p3 + call $f174 + unreachable + end + local.get $p0 + local.get $l4 + i32.store offset=4 + local.get $p0 + local.get $p3 + i32.store) + (func $f194 (type $t4) (param $p0 i32) (param $p1 i32) (param $p2 i32) + (local $l3 i32) (local $l4 i32) (local $l5 i32) (local $l6 i32) (local $l7 i32) (local $l8 i32) + local.get $p2 + i32.const 0 + local.get $p2 + i32.const 4 + local.get $p1 + i32.const 3 + i32.and + local.tee $l6 + i32.sub + i32.const 0 + local.get $l6 + select + local.tee $l5 + i32.sub + i32.const 7 + i32.and + local.get $p2 + local.get $l5 + i32.lt_u + local.tee $l4 + select + local.tee $l3 + i32.sub + local.set $l6 + block $B0 (result i32) + block $B1 + block $B2 + local.get $p2 + local.get $l3 + i32.ge_u + if $I3 + local.get $p2 + local.get $l5 + local.get $l4 + select + local.set $l8 + local.get $p1 + local.get $l6 + i32.add + local.get $p1 + local.get $p2 + i32.add + local.tee $l4 + i32.sub + local.set $l7 + local.get $l4 + i32.const -1 + i32.add + local.set $l5 + block $B4 + loop $L5 + local.get $l3 + i32.eqz + br_if $B4 + local.get $l7 + i32.const 1 + i32.add + local.set $l7 + local.get $l3 + i32.const -1 + i32.add + local.set $l3 + local.get $l5 + i32.load8_u + local.get $l5 + i32.const -1 + i32.add + local.set $l5 + i32.const 10 + i32.ne + br_if $L5 + end + local.get $l6 + local.get $l7 + i32.sub + local.set $l3 + br $B1 + end + loop $L6 + local.get $l6 + local.tee $l3 + local.get $l8 + i32.gt_u + if $I7 + local.get $l3 + i32.const -8 + i32.add + local.set $l6 + local.get $p1 + local.get $l3 + i32.add + local.tee $l5 + i32.const -4 + i32.add + i32.load + i32.const 168430090 + i32.xor + local.tee $l4 + i32.const -1 + i32.xor + local.get $l4 + i32.const -16843009 + i32.add + i32.and + local.get $l5 + i32.const -8 + i32.add + i32.load + i32.const 168430090 + i32.xor + local.tee $l4 + i32.const -1 + i32.xor + local.get $l4 + i32.const -16843009 + i32.add + i32.and + i32.or + i32.const -2139062144 + i32.and + i32.eqz + br_if $L6 + end + end + local.get $l3 + local.get $p2 + i32.gt_u + br_if $B2 + local.get $p1 + i32.const -1 + i32.add + local.set $p2 + loop $L8 + i32.const 0 + local.get $l3 + i32.eqz + br_if $B0 + drop + local.get $p2 + local.get $l3 + i32.add + local.get $l3 + i32.const -1 + i32.add + local.set $l3 + i32.load8_u + i32.const 10 + i32.ne + br_if $L8 + end + br $B1 + end + local.get $l6 + local.get $p2 + call $f174 + unreachable + end + local.get $l3 + local.get $p2 + call $f173 + unreachable + end + i32.const 1 + end + local.set $p1 + local.get $p0 + local.get $l3 + i32.store offset=4 + local.get $p0 + local.get $p1 + i32.store) + (func $f195 (type $t4) (param $p0 i32) (param $p1 i32) (param $p2 i32) + local.get $p0 + local.get $p2 + i32.store offset=4 + local.get $p0 + local.get $p1 + i32.store) + (func $f196 (type $t3) (param $p0 i32) (param $p1 i32) + (local $l2 i32) (local $l3 i32) (local $l4 i32) (local $l5 i32) (local $l6 i32) (local $l7 i32) (local $l8 i32) (local $l9 i32) (local $l10 i32) (local $l11 i32) + block $B0 + block $B1 + block $B2 + block $B3 + block $B4 + block $B5 + local.get $p1 + i32.load offset=4 + local.tee $l2 + if $I6 + local.get $p1 + i32.load + local.set $l7 + block $B7 + block $B8 + block $B9 + block $B10 + block $B11 + block $B12 + loop $L13 + local.get $l3 + i32.const 1 + i32.add + local.set $l5 + block $B14 (result i32) + local.get $l5 + local.get $l3 + local.get $l7 + i32.add + local.tee $l9 + i32.load8_u + local.tee $l10 + i32.const 24 + i32.shl + i32.const 24 + i32.shr_s + local.tee $l11 + i32.const -1 + i32.gt_s + br_if $B14 + drop + block $B15 + block $B16 + block $B17 + local.get $l10 + i32.const 1054975 + i32.add + i32.load8_u + i32.const -2 + i32.add + local.tee $l6 + i32.const 2 + i32.le_u + if $I18 + local.get $l6 + i32.const 1 + i32.sub + br_table $B16 $B15 $B17 + end + local.get $l2 + local.get $l3 + i32.lt_u + br_if $B8 + local.get $l2 + local.get $l3 + i32.le_u + br_if $B7 + local.get $p0 + local.get $l3 + i32.store offset=4 + local.get $p0 + local.get $l7 + i32.store + local.get $p1 + local.get $l2 + local.get $l5 + i32.sub + i32.store offset=4 + local.get $p1 + local.get $l5 + local.get $l7 + i32.add + i32.store + br $B2 + end + local.get $l3 + i32.const 2 + i32.add + local.get $l5 + local.get $l7 + i32.add + local.tee $l4 + i32.const 0 + local.get $l2 + local.get $l5 + i32.gt_u + select + local.tee $l6 + i32.const 1054337 + local.get $l6 + select + i32.load8_u + i32.const 192 + i32.and + i32.const 128 + i32.eq + br_if $B14 + drop + local.get $l2 + local.get $l3 + i32.lt_u + br_if $B8 + local.get $l2 + local.get $l3 + i32.le_u + br_if $B7 + br $B3 + end + local.get $l5 + local.get $l7 + i32.add + local.tee $l4 + i32.const 0 + local.get $l2 + local.get $l5 + i32.gt_u + select + local.tee $l6 + i32.const 1054337 + local.get $l6 + select + i32.load8_u + local.set $l8 + block $B19 + block $B20 + local.get $l10 + i32.const -224 + i32.add + local.tee $l6 + i32.const 13 + i32.gt_u + br_if $B20 + block $B21 + block $B22 + local.get $l6 + i32.const 1 + i32.sub + br_table $B20 $B20 $B20 $B20 $B20 $B20 $B20 $B20 $B20 $B20 $B20 $B20 $B21 $B22 + end + local.get $l8 + i32.const 224 + i32.and + i32.const 160 + i32.eq + br_if $B19 + br $B9 + end + local.get $l8 + i32.const 24 + i32.shl + i32.const 24 + i32.shr_s + i32.const -1 + i32.gt_s + local.get $l8 + i32.const 160 + i32.ge_u + i32.or + br_if $B9 + br $B19 + end + local.get $l11 + i32.const 31 + i32.add + i32.const 255 + i32.and + i32.const 11 + i32.le_u + if $I23 + local.get $l8 + i32.const 24 + i32.shl + i32.const 24 + i32.shr_s + i32.const -1 + i32.gt_s + local.get $l8 + i32.const 192 + i32.ge_u + i32.or + br_if $B9 + br $B19 + end + local.get $l11 + i32.const 254 + i32.and + i32.const 238 + i32.ne + local.get $l8 + i32.const 191 + i32.gt_u + i32.or + local.get $l8 + i32.const 24 + i32.shl + i32.const 24 + i32.shr_s + i32.const -1 + i32.gt_s + i32.or + br_if $B9 + end + local.get $l3 + i32.const 3 + i32.add + local.get $l7 + local.get $l3 + i32.const 2 + i32.add + local.tee $l4 + i32.add + local.tee $l6 + i32.const 0 + local.get $l2 + local.get $l4 + i32.gt_u + select + local.tee $l5 + i32.const 1054337 + local.get $l5 + select + i32.load8_u + i32.const 192 + i32.and + i32.const 128 + i32.eq + br_if $B14 + drop + local.get $l2 + local.get $l3 + i32.lt_u + br_if $B8 + local.get $l3 + i32.const -3 + i32.gt_u + br_if $B5 + local.get $l2 + local.get $l4 + i32.lt_u + br_if $B4 + br $B1 + end + local.get $l5 + local.get $l7 + i32.add + local.tee $l4 + i32.const 0 + local.get $l2 + local.get $l5 + i32.gt_u + select + local.tee $l6 + i32.const 1054337 + local.get $l6 + select + i32.load8_u + local.set $l8 + block $B24 + block $B25 + local.get $l10 + i32.const -240 + i32.add + local.tee $l6 + i32.const 4 + i32.gt_u + br_if $B25 + block $B26 + block $B27 + local.get $l6 + i32.const 1 + i32.sub + br_table $B25 $B25 $B25 $B26 $B27 + end + local.get $l8 + i32.const 112 + i32.add + i32.const 255 + i32.and + i32.const 48 + i32.lt_u + br_if $B24 + br $B10 + end + local.get $l8 + i32.const 24 + i32.shl + i32.const 24 + i32.shr_s + i32.const -1 + i32.gt_s + local.get $l8 + i32.const 144 + i32.ge_u + i32.or + br_if $B10 + br $B24 + end + local.get $l8 + i32.const 191 + i32.gt_u + local.get $l11 + i32.const 15 + i32.add + i32.const 255 + i32.and + i32.const 2 + i32.gt_u + i32.or + local.get $l8 + i32.const 24 + i32.shl + i32.const 24 + i32.shr_s + i32.const -1 + i32.gt_s + i32.or + br_if $B10 + end + local.get $l7 + local.get $l3 + i32.const 2 + i32.add + local.tee $l4 + i32.add + local.tee $l6 + i32.const 0 + local.get $l2 + local.get $l4 + i32.gt_u + select + local.tee $l5 + i32.const 1054337 + local.get $l5 + select + i32.load8_u + i32.const 192 + i32.and + i32.const 128 + i32.ne + br_if $B12 + local.get $l7 + local.get $l3 + i32.const 3 + i32.add + local.tee $l4 + i32.add + local.tee $l6 + i32.const 0 + local.get $l2 + local.get $l4 + i32.gt_u + select + local.tee $l5 + i32.const 1054337 + local.get $l5 + select + i32.load8_u + i32.const 192 + i32.and + i32.const 128 + i32.ne + br_if $B11 + local.get $l3 + i32.const 4 + i32.add + end + local.tee $l3 + local.get $l2 + i32.lt_u + br_if $L13 + end + local.get $p1 + i64.const 1 + i64.store align=4 + local.get $p0 + local.get $l2 + i32.store offset=4 + local.get $p0 + local.get $l7 + i32.store + local.get $p0 + i32.const 8 + i32.add + i64.const 1 + i64.store align=4 + return + end + local.get $l2 + local.get $l3 + i32.lt_u + br_if $B8 + local.get $l3 + i32.const -3 + i32.gt_u + br_if $B5 + local.get $l2 + local.get $l4 + i32.lt_u + br_if $B4 + br $B1 + end + local.get $l2 + local.get $l3 + i32.lt_u + br_if $B8 + local.get $l3 + i32.const -4 + i32.gt_u + br_if $B5 + local.get $l2 + local.get $l4 + i32.lt_u + br_if $B4 + local.get $p1 + local.get $l6 + i32.store + local.get $p0 + local.get $l3 + i32.store offset=4 + local.get $p0 + local.get $l7 + i32.store + local.get $p1 + local.get $l2 + local.get $l4 + i32.sub + i32.store offset=4 + local.get $p0 + i32.const 12 + i32.add + i32.const 3 + i32.store + br $B0 + end + local.get $l2 + local.get $l3 + i32.lt_u + br_if $B8 + local.get $l2 + local.get $l3 + i32.le_u + br_if $B7 + br $B3 + end + local.get $l2 + local.get $l3 + i32.lt_u + br_if $B8 + local.get $l2 + local.get $l3 + i32.le_u + br_if $B7 + br $B3 + end + local.get $l3 + local.get $l2 + call $f173 + unreachable + end + local.get $l5 + local.get $l2 + call $f173 + unreachable + end + local.get $p0 + i32.const 0 + i32.store + return + end + local.get $l3 + local.get $l4 + call $f174 + unreachable + end + local.get $l4 + local.get $l2 + call $f173 + unreachable + end + local.get $p1 + local.get $l4 + i32.store + local.get $p0 + local.get $l3 + i32.store offset=4 + local.get $p0 + local.get $l7 + i32.store + local.get $p1 + local.get $l2 + local.get $l5 + i32.sub + i32.store offset=4 + end + local.get $p0 + i32.const 12 + i32.add + i32.const 1 + i32.store + br $B0 + end + local.get $p1 + local.get $l6 + i32.store + local.get $p0 + local.get $l3 + i32.store offset=4 + local.get $p0 + local.get $l7 + i32.store + local.get $p1 + local.get $l2 + local.get $l4 + i32.sub + i32.store offset=4 + local.get $p0 + i32.const 12 + i32.add + i32.const 2 + i32.store + end + local.get $p0 + i32.const 8 + i32.add + local.get $l9 + i32.store) + (func $f197 (type $t1) (param $p0 i32) (param $p1 i32) (param $p2 i32) (result i32) + (local $l3 i32) (local $l4 i32) (local $l5 i32) (local $l6 i32) + global.get $g0 + i32.const 32 + i32.sub + local.tee $l3 + global.set $g0 + block $B0 + block $B1 + local.get $p1 + if $I2 + local.get $l3 + local.get $p1 + i32.store offset=12 + local.get $l3 + local.get $p0 + i32.store offset=8 + local.get $l3 + i32.const 16 + i32.add + local.get $l3 + i32.const 8 + i32.add + call $f196 + local.get $l3 + i32.load offset=16 + local.tee $p0 + if $I3 + loop $L4 + local.get $l3 + i32.load offset=28 + local.set $l5 + local.get $l3 + i32.load offset=20 + local.tee $l6 + local.get $p1 + i32.eq + br_if $B1 + i32.const 1 + local.set $l4 + local.get $p2 + i32.load offset=24 + local.get $p0 + local.get $l6 + local.get $p2 + i32.load offset=28 + i32.load offset=12 + call_indirect (type $t1) $T0 + br_if $B0 + local.get $l5 + if $I5 + local.get $p2 + i32.load offset=24 + i32.const 65533 + local.get $p2 + i32.load offset=28 + i32.load offset=16 + call_indirect (type $t0) $T0 + br_if $B0 + end + local.get $l3 + i32.const 16 + i32.add + local.get $l3 + i32.const 8 + i32.add + call $f196 + local.get $l3 + i32.load offset=16 + local.tee $p0 + br_if $L4 + end + end + i32.const 0 + local.set $l4 + br $B0 + end + local.get $p2 + i32.const 1054336 + i32.const 0 + call $f175 + local.set $l4 + br $B0 + end + local.get $l5 + i32.eqz + if $I6 + local.get $p2 + local.get $p0 + local.get $p1 + call $f175 + local.set $l4 + br $B0 + end + i32.const 1054876 + i32.const 35 + i32.const 1054936 + call $f172 + unreachable + end + local.get $l3 + i32.const 32 + i32.add + global.set $g0 + local.get $l4) + (func $f198 (type $t5) (param $p0 i32) (result i32) + (local $l1 i32) (local $l2 i32) + block $B0 (result i32) + local.get $p0 + i32.const 2048 + i32.ge_u + if $I1 + block $B2 + block $B3 + block $B4 + block $B5 + block $B6 + local.get $p0 + i32.const 65536 + i32.ge_u + if $I7 + local.get $p0 + i32.const 12 + i32.shr_u + i32.const -16 + i32.add + local.tee $l1 + i32.const 256 + i32.lt_u + br_if $B6 + i32.const 1055916 + local.get $l1 + i32.const 256 + call $f171 + unreachable + end + local.get $p0 + i32.const 6 + i32.shr_u + i32.const -32 + i32.add + local.tee $l1 + i32.const 991 + i32.gt_u + br_if $B5 + i32.const 1059132 + i32.load + local.tee $l2 + local.get $l1 + i32.const 1059152 + i32.add + i32.load8_u + local.tee $l1 + i32.le_u + br_if $B4 + i32.const 1059128 + i32.load + local.get $l1 + i32.const 3 + i32.shl + i32.add + br $B0 + end + local.get $p0 + i32.const 6 + i32.shr_u + i32.const 63 + i32.and + local.get $l1 + i32.const 1060144 + i32.add + i32.load8_u + i32.const 6 + i32.shl + i32.or + local.tee $l1 + i32.const 1059140 + i32.load + local.tee $l2 + i32.ge_u + br_if $B3 + i32.const 1059148 + i32.load + local.tee $l2 + i32.const 1059136 + i32.load + local.get $l1 + i32.add + i32.load8_u + local.tee $l1 + i32.le_u + br_if $B2 + i32.const 1059144 + i32.load + local.get $l1 + i32.const 3 + i32.shl + i32.add + br $B0 + end + i32.const 1055884 + local.get $l1 + i32.const 992 + call $f171 + unreachable + end + i32.const 1055900 + local.get $l1 + local.get $l2 + call $f171 + unreachable + end + i32.const 1055932 + local.get $l1 + local.get $l2 + call $f171 + unreachable + end + i32.const 1055948 + local.get $l1 + local.get $l2 + call $f171 + unreachable + end + local.get $p0 + i32.const 3 + i32.shr_u + i32.const 536870904 + i32.and + i32.const 1058872 + i32.add + end + i64.load + i64.const 1 + local.get $p0 + i32.const 63 + i32.and + i64.extend_i32_u + i64.shl + i64.and + i64.const 0 + i64.ne) + (func $f199 (type $t5) (param $p0 i32) (result i32) + (local $l1 i32) + local.get $p0 + i32.const 65536 + i32.ge_u + if $I0 + block $B1 + local.get $p0 + i32.const 131072 + i32.ge_u + if $I2 + local.get $p0 + i32.const -195102 + i32.add + i32.const 722658 + i32.lt_u + local.get $p0 + i32.const -191457 + i32.add + i32.const 3103 + i32.lt_u + i32.or + local.get $p0 + i32.const 2097150 + i32.and + i32.const 178206 + i32.eq + local.get $p0 + i32.const -183970 + i32.add + i32.const 14 + i32.lt_u + i32.or + i32.or + local.get $p0 + i32.const -173783 + i32.add + i32.const 41 + i32.lt_u + local.get $p0 + i32.const -177973 + i32.add + i32.const 11 + i32.lt_u + i32.or + i32.or + br_if $B1 + local.get $p0 + i32.const -918000 + i32.add + i32.const 196111 + i32.gt_u + return + end + local.get $p0 + i32.const 1056653 + i32.const 35 + i32.const 1056723 + i32.const 166 + i32.const 1056889 + i32.const 408 + call $f227 + local.set $l1 + end + local.get $l1 + return + end + local.get $p0 + i32.const 1055964 + i32.const 41 + i32.const 1056046 + i32.const 293 + i32.const 1056339 + i32.const 314 + call $f227) + (func $f200 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + (local $l2 i32) (local $l3 i32) (local $l4 i32) + global.get $g0 + i32.const 128 + i32.sub + local.tee $l3 + global.set $g0 + local.get $p0 + i32.load8_u + local.set $l2 + i32.const 0 + local.set $p0 + loop $L0 + local.get $p0 + local.get $l3 + i32.add + i32.const 127 + i32.add + local.get $l2 + i32.const 15 + i32.and + local.tee $l4 + i32.const 48 + i32.or + local.get $l4 + i32.const 87 + i32.add + local.get $l4 + i32.const 10 + i32.lt_u + select + i32.store8 + local.get $p0 + i32.const -1 + i32.add + local.set $p0 + local.get $l2 + i32.const 4 + i32.shr_u + local.tee $l2 + br_if $L0 + end + local.get $p0 + i32.const 128 + i32.add + local.tee $l2 + i32.const 129 + i32.ge_u + if $I1 + local.get $l2 + i32.const 128 + call $f174 + unreachable + end + local.get $p1 + i32.const 1 + i32.const 1055569 + i32.const 2 + local.get $p0 + local.get $l3 + i32.add + i32.const 128 + i32.add + i32.const 0 + local.get $p0 + i32.sub + call $f216 + local.get $l3 + i32.const 128 + i32.add + global.set $g0) + (func $f201 (type $t4) (param $p0 i32) (param $p1 i32) (param $p2 i32) + (local $l3 i32) (local $l4 i64) + global.get $g0 + i32.const 16 + i32.sub + local.tee $l3 + global.set $g0 + local.get $l3 + i32.const 8 + i32.add + local.get $p1 + local.get $p2 + call $f202 + local.get $p0 + block $B0 (result i32) + local.get $l3 + i64.load offset=8 + local.tee $l4 + i64.const 1095216660480 + i64.and + i64.const 8589934592 + i64.ne + if $I1 + local.get $p0 + local.get $l4 + i64.store offset=4 align=4 + i32.const 1 + br $B0 + end + local.get $p0 + local.get $p1 + i32.store offset=4 + local.get $p0 + i32.const 8 + i32.add + local.get $p2 + i32.store + i32.const 0 + end + i32.store + local.get $l3 + i32.const 16 + i32.add + global.set $g0) + (func $f202 (type $t4) (param $p0 i32) (param $p1 i32) (param $p2 i32) + (local $l3 i32) (local $l4 i32) (local $l5 i32) (local $l6 i32) (local $l7 i32) (local $l8 i32) + block $B0 + block $B1 + block $B2 + block $B3 + block $B4 + block $B5 + local.get $p2 + i32.eqz + br_if $B5 + i32.const 0 + local.get $p1 + i32.sub + i32.const 0 + local.get $p1 + i32.const 3 + i32.and + select + local.set $l8 + local.get $p2 + i32.const -7 + i32.add + i32.const 0 + local.get $p2 + i32.const 7 + i32.gt_u + select + local.set $l7 + loop $L6 + block $B7 + block $B8 + block $B9 + local.get $p1 + local.get $l3 + i32.add + i32.load8_u + local.tee $l5 + i32.const 24 + i32.shl + i32.const 24 + i32.shr_s + local.tee $l6 + i32.const -1 + i32.le_s + if $I10 + block $B11 + block $B12 + block $B13 + local.get $l5 + i32.const 1054975 + i32.add + i32.load8_u + i32.const -2 + i32.add + local.tee $l4 + i32.const 2 + i32.le_u + if $I14 + local.get $l4 + i32.const 1 + i32.sub + br_table $B12 $B11 $B13 + end + br $B3 + end + local.get $l3 + i32.const 1 + i32.add + local.tee $l4 + local.get $p2 + i32.ge_u + if $I15 + br $B2 + end + local.get $p1 + local.get $l4 + i32.add + i32.load8_u + i32.const 192 + i32.and + i32.const 128 + i32.eq + br_if $B9 + br $B3 + end + local.get $l3 + i32.const 1 + i32.add + local.tee $l4 + local.get $p2 + i32.ge_u + if $I16 + br $B2 + end + local.get $p1 + local.get $l4 + i32.add + i32.load8_u + local.set $l4 + block $B17 + block $B18 + local.get $l5 + i32.const -224 + i32.add + local.tee $l5 + i32.const 13 + i32.gt_u + br_if $B18 + block $B19 + block $B20 + local.get $l5 + i32.const 1 + i32.sub + br_table $B18 $B18 $B18 $B18 $B18 $B18 $B18 $B18 $B18 $B18 $B18 $B18 $B19 $B20 + end + local.get $l4 + i32.const 224 + i32.and + i32.const 160 + i32.ne + br_if $B4 + br $B17 + end + local.get $l4 + i32.const 24 + i32.shl + i32.const 24 + i32.shr_s + i32.const -1 + i32.gt_s + br_if $B4 + local.get $l4 + i32.const 160 + i32.lt_u + br_if $B17 + br $B4 + end + local.get $l6 + i32.const 31 + i32.add + i32.const 255 + i32.and + i32.const 11 + i32.le_u + if $I21 + local.get $l4 + i32.const 24 + i32.shl + i32.const 24 + i32.shr_s + i32.const -1 + i32.gt_s + local.get $l4 + i32.const 192 + i32.ge_u + i32.or + br_if $B4 + br $B17 + end + local.get $l6 + i32.const 254 + i32.and + i32.const 238 + i32.ne + local.get $l4 + i32.const 191 + i32.gt_u + i32.or + local.get $l4 + i32.const 24 + i32.shl + i32.const 24 + i32.shr_s + i32.const -1 + i32.gt_s + i32.or + br_if $B4 + end + local.get $l3 + i32.const 2 + i32.add + local.tee $l4 + local.get $p2 + i32.ge_u + if $I22 + br $B2 + end + local.get $p1 + local.get $l4 + i32.add + i32.load8_u + i32.const 192 + i32.and + i32.const 128 + i32.eq + br_if $B9 + br $B1 + end + local.get $l3 + i32.const 1 + i32.add + local.tee $l4 + local.get $p2 + i32.ge_u + if $I23 + br $B2 + end + local.get $p1 + local.get $l4 + i32.add + i32.load8_u + local.set $l4 + block $B24 + block $B25 + local.get $l5 + i32.const -240 + i32.add + local.tee $l5 + i32.const 4 + i32.gt_u + br_if $B25 + block $B26 + block $B27 + local.get $l5 + i32.const 1 + i32.sub + br_table $B25 $B25 $B25 $B26 $B27 + end + local.get $l4 + i32.const 112 + i32.add + i32.const 255 + i32.and + i32.const 48 + i32.ge_u + br_if $B3 + br $B24 + end + local.get $l4 + i32.const 24 + i32.shl + i32.const 24 + i32.shr_s + i32.const -1 + i32.gt_s + br_if $B3 + local.get $l4 + i32.const 144 + i32.lt_u + br_if $B24 + br $B3 + end + local.get $l4 + i32.const 191 + i32.gt_u + local.get $l6 + i32.const 15 + i32.add + i32.const 255 + i32.and + i32.const 2 + i32.gt_u + i32.or + local.get $l4 + i32.const 24 + i32.shl + i32.const 24 + i32.shr_s + i32.const -1 + i32.gt_s + i32.or + br_if $B3 + end + local.get $l3 + i32.const 2 + i32.add + local.tee $l4 + local.get $p2 + i32.ge_u + if $I28 + br $B2 + end + local.get $p1 + local.get $l4 + i32.add + i32.load8_u + i32.const 192 + i32.and + i32.const 128 + i32.ne + br_if $B1 + local.get $l3 + i32.const 3 + i32.add + local.tee $l4 + local.get $p2 + i32.ge_u + if $I29 + br $B2 + end + local.get $p1 + local.get $l4 + i32.add + i32.load8_u + i32.const 192 + i32.and + i32.const 128 + i32.eq + br_if $B9 + local.get $p0 + i32.const 769 + i32.store16 offset=4 + br $B0 + end + local.get $l8 + local.get $l3 + i32.sub + i32.const 3 + i32.and + br_if $B8 + block $B30 + local.get $l3 + local.get $l7 + i32.ge_u + br_if $B30 + loop $L31 + local.get $p1 + local.get $l3 + i32.add + local.tee $l4 + i32.const 4 + i32.add + i32.load + local.get $l4 + i32.load + i32.or + i32.const -2139062144 + i32.and + br_if $B30 + local.get $l3 + i32.const 8 + i32.add + local.tee $l3 + local.get $l7 + i32.lt_u + br_if $L31 + end + end + local.get $l3 + local.get $p2 + i32.ge_u + br_if $B7 + loop $L32 + local.get $p1 + local.get $l3 + i32.add + i32.load8_s + i32.const 0 + i32.lt_s + br_if $B7 + local.get $p2 + local.get $l3 + i32.const 1 + i32.add + local.tee $l3 + i32.ne + br_if $L32 + end + br $B5 + end + local.get $l4 + i32.const 1 + i32.add + local.set $l3 + br $B7 + end + local.get $l3 + i32.const 1 + i32.add + local.set $l3 + end + local.get $l3 + local.get $p2 + i32.lt_u + br_if $L6 + end + end + local.get $p0 + i32.const 2 + i32.store8 offset=4 + return + end + local.get $p0 + i32.const 257 + i32.store16 offset=4 + local.get $p0 + local.get $l3 + i32.store + return + end + local.get $p0 + i32.const 257 + i32.store16 offset=4 + br $B0 + end + local.get $p0 + i32.const 0 + i32.store8 offset=4 + br $B0 + end + local.get $p0 + i32.const 513 + i32.store16 offset=4 + end + local.get $p0 + local.get $l3 + i32.store) + (func $f203 (type $t3) (param $p0 i32) (param $p1 i32) + (local $l2 i32) (local $l3 i32) (local $l4 i32) (local $l5 i64) (local $l6 i64) (local $l7 i64) (local $l8 i64) (local $l9 i64) + global.get $g0 + i32.const 80 + i32.sub + local.tee $l2 + global.set $g0 + block $B0 (result i32) + i32.const 1 + local.get $p0 + i32.load8_u offset=4 + br_if $B0 + drop + local.get $p0 + i32.load8_u offset=5 + local.set $l4 + local.get $p0 + i32.load + local.tee $l3 + i32.load8_u + i32.const 4 + i32.and + i32.eqz + if $I1 + local.get $p1 + local.get $l4 + if $I2 (result i32) + i32.const 1 + local.get $l3 + i32.load offset=24 + i32.const 1055537 + i32.const 2 + local.get $l3 + i32.const 28 + i32.add + i32.load + i32.load offset=12 + call_indirect (type $t1) $T0 + br_if $B0 + drop + local.get $p0 + i32.load + else + local.get $l3 + end + i32.const 1049316 + i32.load + call_indirect (type $t0) $T0 + br $B0 + end + local.get $l4 + i32.eqz + if $I3 + i32.const 1 + local.get $l3 + i32.load offset=24 + i32.const 1055549 + i32.const 1 + local.get $l3 + i32.const 28 + i32.add + i32.load + i32.load offset=12 + call_indirect (type $t1) $T0 + br_if $B0 + drop + local.get $p0 + i32.load + local.set $l3 + end + local.get $l2 + i32.const 1 + i32.store8 offset=23 + local.get $l2 + local.get $l2 + i32.const 23 + i32.add + i32.store offset=16 + local.get $l3 + i64.load offset=8 align=4 + local.set $l5 + local.get $l3 + i64.load offset=16 align=4 + local.set $l6 + local.get $l2 + i32.const 52 + i32.add + i32.const 1055504 + i32.store + local.get $l2 + local.get $l3 + i64.load offset=24 align=4 + i64.store offset=8 + local.get $l3 + i64.load offset=32 align=4 + local.set $l7 + local.get $l3 + i64.load offset=40 align=4 + local.set $l8 + local.get $l2 + local.get $l3 + i32.load8_u offset=48 + i32.store8 offset=72 + local.get $l3 + i64.load align=4 + local.set $l9 + local.get $l2 + local.get $l8 + i64.store offset=64 + local.get $l2 + local.get $l7 + i64.store offset=56 + local.get $l2 + local.get $l6 + i64.store offset=40 + local.get $l2 + local.get $l5 + i64.store offset=32 + local.get $l2 + local.get $l9 + i64.store offset=24 + local.get $l2 + local.get $l2 + i32.const 8 + i32.add + i32.store offset=48 + i32.const 1 + local.get $p1 + local.get $l2 + i32.const 24 + i32.add + i32.const 1049316 + i32.load + call_indirect (type $t0) $T0 + br_if $B0 + drop + local.get $l2 + i32.load offset=48 + i32.const 1055535 + i32.const 2 + local.get $l2 + i32.load offset=52 + i32.load offset=12 + call_indirect (type $t1) $T0 + end + local.set $p1 + local.get $p0 + i32.const 1 + i32.store8 offset=5 + local.get $p0 + local.get $p1 + i32.store8 offset=4 + local.get $l2 + i32.const 80 + i32.add + global.set $g0) + (func $f204 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + (local $l2 i32) (local $l3 i32) (local $l4 i32) (local $l5 i64) + local.get $p1 + i32.load offset=24 + i32.const 39 + local.get $p1 + i32.const 28 + i32.add + i32.load + i32.load offset=16 + call_indirect (type $t0) $T0 + i32.eqz + if $I0 + i32.const 2 + local.set $l2 + block $B1 + block $B2 + block $B3 + local.get $p0 + i32.load + local.tee $p0 + i32.const -9 + i32.add + local.tee $l3 + i32.const 30 + i32.gt_u + if $I4 + local.get $p0 + i32.const 92 + i32.ne + br_if $B3 + br $B2 + end + i32.const 116 + local.set $l4 + block $B5 + block $B6 + local.get $l3 + i32.const 1 + i32.sub + br_table $B5 $B3 $B3 $B6 $B3 $B3 $B3 $B3 $B3 $B3 $B3 $B3 $B3 $B3 $B3 $B3 $B3 $B3 $B3 $B3 $B3 $B3 $B3 $B3 $B2 $B3 $B3 $B3 $B3 $B2 $B1 + end + i32.const 114 + local.set $l4 + br $B1 + end + i32.const 110 + local.set $l4 + br $B1 + end + block $B7 (result i64) + block $B8 + local.get $p0 + call $f198 + i32.eqz + if $I9 + local.get $p0 + call $f199 + i32.eqz + br_if $B8 + i32.const 1 + local.set $l2 + br $B2 + end + local.get $p0 + i32.const 1 + i32.or + i32.clz + i32.const 2 + i32.shr_u + i32.const 7 + i32.xor + i64.extend_i32_u + i64.const 21474836480 + i64.or + br $B7 + end + local.get $p0 + i32.const 1 + i32.or + i32.clz + i32.const 2 + i32.shr_u + i32.const 7 + i32.xor + i64.extend_i32_u + i64.const 21474836480 + i64.or + end + local.set $l5 + i32.const 3 + local.set $l2 + end + local.get $p0 + local.set $l4 + end + loop $L10 + local.get $l2 + local.set $l3 + i32.const 92 + local.set $p0 + i32.const 1 + local.set $l2 + block $B11 + block $B12 + block $B13 + block $B14 + local.get $l3 + i32.const 1 + i32.sub + br_table $B12 $B11 $B14 $B13 + end + block $B15 + block $B16 + block $B17 + block $B18 + block $B19 + local.get $l5 + i64.const 32 + i64.shr_u + i32.wrap_i64 + i32.const 255 + i32.and + i32.const 1 + i32.sub + br_table $B15 $B16 $B17 $B18 $B19 $B13 + end + local.get $l5 + i64.const -1095216660481 + i64.and + i64.const 17179869184 + i64.or + local.set $l5 + i32.const 3 + local.set $l2 + br $B11 + end + local.get $l5 + i64.const -1095216660481 + i64.and + i64.const 12884901888 + i64.or + local.set $l5 + i32.const 117 + local.set $p0 + i32.const 3 + local.set $l2 + br $B11 + end + local.get $l5 + i64.const -1095216660481 + i64.and + i64.const 8589934592 + i64.or + local.set $l5 + i32.const 123 + local.set $p0 + i32.const 3 + local.set $l2 + br $B11 + end + local.get $l4 + local.get $l5 + i32.wrap_i64 + local.tee $l3 + i32.const 2 + i32.shl + i32.const 28 + i32.and + i32.shr_u + i32.const 15 + i32.and + local.tee $p0 + i32.const 48 + i32.or + local.get $p0 + i32.const 87 + i32.add + local.get $p0 + i32.const 10 + i32.lt_u + select + local.set $p0 + local.get $l3 + if $I20 + local.get $l5 + i64.const -1 + i64.add + i64.const 4294967295 + i64.and + local.get $l5 + i64.const -4294967296 + i64.and + i64.or + local.set $l5 + i32.const 3 + local.set $l2 + br $B11 + end + local.get $l5 + i64.const -1095216660481 + i64.and + i64.const 4294967296 + i64.or + local.set $l5 + i32.const 3 + local.set $l2 + br $B11 + end + local.get $l5 + i64.const -1095216660481 + i64.and + local.set $l5 + i32.const 125 + local.set $p0 + i32.const 3 + local.set $l2 + br $B11 + end + local.get $p1 + i32.load offset=24 + i32.const 39 + local.get $p1 + i32.load offset=28 + i32.load offset=16 + call_indirect (type $t0) $T0 + return + end + i32.const 0 + local.set $l2 + local.get $l4 + local.set $p0 + end + local.get $p1 + i32.load offset=24 + local.get $p0 + local.get $p1 + i32.load offset=28 + i32.load offset=16 + call_indirect (type $t0) $T0 + i32.eqz + br_if $L10 + end + end + i32.const 1) + (func $f205 (type $t1) (param $p0 i32) (param $p1 i32) (param $p2 i32) (result i32) + (local $l3 i32) (local $l4 i32) (local $l5 i32) (local $l6 i32) (local $l7 i32) (local $l8 i32) (local $l9 i32) + global.get $g0 + i32.const 48 + i32.sub + local.tee $l3 + global.set $g0 + block $B0 (result i32) + i32.const 0 + local.get $p2 + i32.eqz + br_if $B0 + drop + local.get $l3 + i32.const 40 + i32.add + local.set $l8 + block $B1 + block $B2 + block $B3 + block $B4 + loop $L5 + local.get $p0 + i32.load offset=8 + i32.load8_u + if $I6 + local.get $p0 + i32.load + i32.const 1055528 + i32.const 4 + local.get $p0 + i32.load offset=4 + i32.load offset=12 + call_indirect (type $t1) $T0 + br_if $B1 + end + local.get $l3 + i32.const 10 + i32.store offset=40 + local.get $l3 + i64.const 4294967306 + i64.store offset=32 + local.get $l3 + local.get $p2 + i32.store offset=28 + local.get $l3 + i32.const 0 + i32.store offset=24 + local.get $l3 + local.get $p2 + i32.store offset=20 + local.get $l3 + local.get $p1 + i32.store offset=16 + local.get $l3 + i32.const 8 + i32.add + i32.const 10 + local.get $p1 + local.get $p2 + call $f193 + block $B7 (result i32) + block $B8 + block $B9 + local.get $l3 + i32.load offset=8 + i32.const 1 + i32.eq + if $I10 + local.get $l3 + i32.load offset=12 + local.set $l4 + loop $L11 + local.get $l3 + local.get $l4 + local.get $l3 + i32.load offset=24 + i32.add + i32.const 1 + i32.add + local.tee $l4 + i32.store offset=24 + block $B12 + local.get $l4 + local.get $l3 + i32.load offset=36 + local.tee $l5 + i32.lt_u + if $I13 + local.get $l3 + i32.load offset=20 + local.set $l7 + br $B12 + end + local.get $l3 + i32.load offset=20 + local.tee $l7 + local.get $l4 + i32.lt_u + br_if $B12 + local.get $l5 + i32.const 5 + i32.ge_u + br_if $B4 + local.get $l4 + local.get $l5 + i32.sub + local.tee $l6 + local.get $l3 + i32.load offset=16 + i32.add + local.tee $l9 + local.get $l8 + i32.eq + br_if $B8 + local.get $l9 + local.get $l8 + local.get $l5 + call $f167 + i32.eqz + br_if $B8 + end + local.get $l3 + i32.load offset=28 + local.tee $l6 + local.get $l4 + i32.lt_u + local.get $l7 + local.get $l6 + i32.lt_u + i32.or + br_if $B9 + local.get $l3 + local.get $l3 + local.get $l5 + i32.add + i32.const 39 + i32.add + i32.load8_u + local.get $l3 + i32.load offset=16 + local.get $l4 + i32.add + local.get $l6 + local.get $l4 + i32.sub + call $f193 + local.get $l3 + i32.load offset=4 + local.set $l4 + local.get $l3 + i32.load + i32.const 1 + i32.eq + br_if $L11 + end + end + local.get $l3 + local.get $l3 + i32.load offset=28 + i32.store offset=24 + end + local.get $p0 + i32.load offset=8 + i32.const 0 + i32.store8 + local.get $p2 + br $B7 + end + local.get $p0 + i32.load offset=8 + i32.const 1 + i32.store8 + local.get $l6 + i32.const 1 + i32.add + end + local.set $l4 + local.get $p0 + i32.load offset=4 + local.set $l5 + local.get $p0 + i32.load + local.get $l4 + i32.eqz + local.get $p2 + local.get $l4 + i32.eq + i32.or + local.tee $l6 + i32.eqz + if $I14 + local.get $p2 + local.get $l4 + i32.le_u + br_if $B3 + local.get $p1 + local.get $l4 + i32.add + i32.load8_s + i32.const -65 + i32.le_s + br_if $B3 + end + local.get $p1 + local.get $l4 + local.get $l5 + i32.load offset=12 + call_indirect (type $t1) $T0 + br_if $B1 + local.get $l6 + i32.eqz + if $I15 + local.get $p2 + local.get $l4 + i32.le_u + br_if $B2 + local.get $p1 + local.get $l4 + i32.add + i32.load8_s + i32.const -65 + i32.le_s + br_if $B2 + end + local.get $p1 + local.get $l4 + i32.add + local.set $p1 + local.get $p2 + local.get $l4 + i32.sub + local.tee $p2 + br_if $L5 + end + i32.const 0 + br $B0 + end + local.get $l5 + i32.const 4 + call $f173 + unreachable + end + local.get $p1 + local.get $p2 + i32.const 0 + local.get $l4 + call $f176 + unreachable + end + local.get $p1 + local.get $p2 + local.get $l4 + local.get $p2 + call $f176 + unreachable + end + i32.const 1 + end + local.get $l3 + i32.const 48 + i32.add + global.set $g0) + (func $f206 (type $t4) (param $p0 i32) (param $p1 i32) (param $p2 i32) + (local $l3 i32) (local $l4 i32) (local $l5 i32) (local $l6 i64) (local $l7 i64) (local $l8 i64) (local $l9 i64) (local $l10 i64) + global.get $g0 + i32.const 80 + i32.sub + local.tee $l3 + global.set $g0 + local.get $p0 + block $B0 (result i32) + i32.const 1 + local.get $p0 + i32.load8_u offset=8 + br_if $B0 + drop + local.get $p0 + i32.load offset=4 + local.set $l5 + local.get $p0 + i32.load + local.tee $l4 + i32.load8_u + i32.const 4 + i32.and + i32.eqz + if $I1 + i32.const 1 + local.get $l4 + i32.load offset=24 + i32.const 1055537 + i32.const 1055547 + local.get $l5 + select + i32.const 2 + i32.const 1 + local.get $l5 + select + local.get $l4 + i32.const 28 + i32.add + i32.load + i32.load offset=12 + call_indirect (type $t1) $T0 + br_if $B0 + drop + local.get $p1 + local.get $p0 + i32.load + local.get $p2 + i32.load offset=12 + call_indirect (type $t0) $T0 + br $B0 + end + local.get $l5 + i32.eqz + if $I2 + i32.const 1 + local.get $l4 + i32.load offset=24 + i32.const 1055545 + i32.const 2 + local.get $l4 + i32.const 28 + i32.add + i32.load + i32.load offset=12 + call_indirect (type $t1) $T0 + br_if $B0 + drop + local.get $p0 + i32.load + local.set $l4 + end + local.get $l3 + i32.const 1 + i32.store8 offset=23 + local.get $l3 + local.get $l3 + i32.const 23 + i32.add + i32.store offset=16 + local.get $l4 + i64.load offset=8 align=4 + local.set $l6 + local.get $l4 + i64.load offset=16 align=4 + local.set $l7 + local.get $l3 + i32.const 52 + i32.add + i32.const 1055504 + i32.store + local.get $l3 + local.get $l4 + i64.load offset=24 align=4 + i64.store offset=8 + local.get $l4 + i64.load offset=32 align=4 + local.set $l8 + local.get $l4 + i64.load offset=40 align=4 + local.set $l9 + local.get $l3 + local.get $l4 + i32.load8_u offset=48 + i32.store8 offset=72 + local.get $l4 + i64.load align=4 + local.set $l10 + local.get $l3 + local.get $l9 + i64.store offset=64 + local.get $l3 + local.get $l8 + i64.store offset=56 + local.get $l3 + local.get $l7 + i64.store offset=40 + local.get $l3 + local.get $l6 + i64.store offset=32 + local.get $l3 + local.get $l10 + i64.store offset=24 + local.get $l3 + local.get $l3 + i32.const 8 + i32.add + i32.store offset=48 + i32.const 1 + local.get $p1 + local.get $l3 + i32.const 24 + i32.add + local.get $p2 + i32.load offset=12 + call_indirect (type $t0) $T0 + br_if $B0 + drop + local.get $l3 + i32.load offset=48 + i32.const 1055535 + i32.const 2 + local.get $l3 + i32.load offset=52 + i32.load offset=12 + call_indirect (type $t1) $T0 + end + i32.store8 offset=8 + local.get $p0 + local.get $p0 + i32.load offset=4 + i32.const 1 + i32.add + i32.store offset=4 + local.get $l3 + i32.const 80 + i32.add + global.set $g0) + (func $f207 (type $t5) (param $p0 i32) (result i32) + (local $l1 i32) (local $l2 i32) + local.get $p0 + i32.load8_u offset=8 + local.set $l1 + local.get $p0 + i32.load offset=4 + local.tee $l2 + if $I0 + local.get $l1 + i32.const 255 + i32.and + local.set $l1 + local.get $p0 + block $B1 (result i32) + i32.const 1 + local.get $l1 + br_if $B1 + drop + block $B2 + local.get $l2 + i32.const 1 + i32.ne + br_if $B2 + local.get $p0 + i32.load8_u offset=9 + i32.eqz + br_if $B2 + local.get $p0 + i32.load + local.tee $l2 + i32.load8_u + i32.const 4 + i32.and + br_if $B2 + i32.const 1 + local.get $l2 + i32.load offset=24 + i32.const 1055548 + i32.const 1 + local.get $l2 + i32.const 28 + i32.add + i32.load + i32.load offset=12 + call_indirect (type $t1) $T0 + br_if $B1 + drop + end + local.get $p0 + i32.load + local.tee $l1 + i32.load offset=24 + i32.const 1054952 + i32.const 1 + local.get $l1 + i32.const 28 + i32.add + i32.load + i32.load offset=12 + call_indirect (type $t1) $T0 + end + local.tee $l1 + i32.store8 offset=8 + end + local.get $l1 + i32.const 255 + i32.and + i32.const 0 + i32.ne) + (func $f208 (type $t5) (param $p0 i32) (result i32) + (local $l1 i32) + i32.const 1 + local.set $l1 + local.get $p0 + i32.load8_u offset=4 + if $I0 (result i32) + i32.const 1 + else + local.get $p0 + i32.load + local.tee $p0 + i32.load offset=24 + i32.const 1055568 + i32.const 1 + local.get $p0 + i32.const 28 + i32.add + i32.load + i32.load offset=12 + call_indirect (type $t1) $T0 + end) + (func $f209 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + (local $l2 i32) + global.get $g0 + i32.const 16 + i32.sub + local.tee $l2 + global.set $g0 + local.get $l2 + i32.const 0 + i32.store offset=12 + local.get $p0 + local.get $l2 + i32.const 12 + i32.add + block $B0 (result i32) + block $B1 + local.get $p1 + i32.const 128 + i32.ge_u + if $I2 + local.get $p1 + i32.const 2048 + i32.lt_u + br_if $B1 + local.get $p1 + i32.const 65536 + i32.lt_u + if $I3 + local.get $l2 + local.get $p1 + i32.const 63 + i32.and + i32.const 128 + i32.or + i32.store8 offset=14 + local.get $l2 + local.get $p1 + i32.const 6 + i32.shr_u + i32.const 63 + i32.and + i32.const 128 + i32.or + i32.store8 offset=13 + local.get $l2 + local.get $p1 + i32.const 12 + i32.shr_u + i32.const 15 + i32.and + i32.const 224 + i32.or + i32.store8 offset=12 + i32.const 3 + br $B0 + end + local.get $l2 + local.get $p1 + i32.const 63 + i32.and + i32.const 128 + i32.or + i32.store8 offset=15 + local.get $l2 + local.get $p1 + i32.const 18 + i32.shr_u + i32.const 240 + i32.or + i32.store8 offset=12 + local.get $l2 + local.get $p1 + i32.const 6 + i32.shr_u + i32.const 63 + i32.and + i32.const 128 + i32.or + i32.store8 offset=14 + local.get $l2 + local.get $p1 + i32.const 12 + i32.shr_u + i32.const 63 + i32.and + i32.const 128 + i32.or + i32.store8 offset=13 + i32.const 4 + br $B0 + end + local.get $l2 + local.get $p1 + i32.store8 offset=12 + i32.const 1 + br $B0 + end + local.get $l2 + local.get $p1 + i32.const 63 + i32.and + i32.const 128 + i32.or + i32.store8 offset=13 + local.get $l2 + local.get $p1 + i32.const 6 + i32.shr_u + i32.const 31 + i32.and + i32.const 192 + i32.or + i32.store8 offset=12 + i32.const 2 + end + call $f205 + local.get $l2 + i32.const 16 + i32.add + global.set $g0) + (func $f210 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + (local $l2 i32) + global.get $g0 + i32.const 32 + i32.sub + local.tee $l2 + global.set $g0 + local.get $l2 + local.get $p0 + i32.store offset=4 + local.get $l2 + i32.const 24 + i32.add + local.get $p1 + i32.const 16 + i32.add + i64.load align=4 + i64.store + local.get $l2 + i32.const 16 + i32.add + local.get $p1 + i32.const 8 + i32.add + i64.load align=4 + i64.store + local.get $l2 + local.get $p1 + i64.load align=4 + i64.store offset=8 + local.get $l2 + i32.const 4 + i32.add + i32.const 1055772 + local.get $l2 + i32.const 8 + i32.add + call $f179 + local.get $l2 + i32.const 32 + i32.add + global.set $g0) + (func $f211 (type $t1) (param $p0 i32) (param $p1 i32) (param $p2 i32) (result i32) + local.get $p0 + i32.load + local.get $p1 + local.get $p2 + call $f205) + (func $f212 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + local.get $p0 + i32.load + local.get $p1 + call $f209) + (func $f213 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + (local $l2 i32) + global.get $g0 + i32.const 32 + i32.sub + local.tee $l2 + global.set $g0 + local.get $l2 + local.get $p0 + i32.load + i32.store offset=4 + local.get $l2 + i32.const 24 + i32.add + local.get $p1 + i32.const 16 + i32.add + i64.load align=4 + i64.store + local.get $l2 + i32.const 16 + i32.add + local.get $p1 + i32.const 8 + i32.add + i64.load align=4 + i64.store + local.get $l2 + local.get $p1 + i64.load align=4 + i64.store offset=8 + local.get $l2 + i32.const 4 + i32.add + i32.const 1055772 + local.get $l2 + i32.const 8 + i32.add + call $f179 + local.get $l2 + i32.const 32 + i32.add + global.set $g0) + (func $f214 (type $t14) (param $p0 i64) (param $p1 i32) (param $p2 i32) (result i32) + (local $l3 i32) (local $l4 i32) (local $l5 i32) (local $l6 i32) (local $l7 i32) (local $l8 i64) + global.get $g0 + i32.const 48 + i32.sub + local.tee $l5 + global.set $g0 + i32.const 39 + local.set $l3 + block $B0 + local.get $p0 + i64.const 10000 + i64.lt_u + if $I1 + local.get $p0 + local.set $l8 + br $B0 + end + loop $L2 + local.get $l5 + i32.const 9 + i32.add + local.get $l3 + i32.add + local.tee $l4 + i32.const -4 + i32.add + local.get $p0 + local.get $p0 + i64.const 10000 + i64.div_u + local.tee $l8 + i64.const 10000 + i64.mul + i64.sub + i32.wrap_i64 + local.tee $l6 + i32.const 65535 + i32.and + i32.const 100 + i32.div_u + local.tee $l7 + i32.const 1 + i32.shl + i32.const 1055571 + i32.add + i32.load16_u align=1 + i32.store16 align=1 + local.get $l4 + i32.const -2 + i32.add + local.get $l6 + local.get $l7 + i32.const 100 + i32.mul + i32.sub + i32.const 65535 + i32.and + i32.const 1 + i32.shl + i32.const 1055571 + i32.add + i32.load16_u align=1 + i32.store16 align=1 + local.get $l3 + i32.const -4 + i32.add + local.set $l3 + local.get $p0 + i64.const 99999999 + i64.gt_u + local.get $l8 + local.set $p0 + br_if $L2 + end + end + local.get $l8 + i32.wrap_i64 + local.tee $l4 + i32.const 99 + i32.gt_s + if $I3 + local.get $l3 + i32.const -2 + i32.add + local.tee $l3 + local.get $l5 + i32.const 9 + i32.add + i32.add + local.get $l8 + i32.wrap_i64 + local.tee $l4 + local.get $l4 + i32.const 65535 + i32.and + i32.const 100 + i32.div_u + local.tee $l4 + i32.const 100 + i32.mul + i32.sub + i32.const 65535 + i32.and + i32.const 1 + i32.shl + i32.const 1055571 + i32.add + i32.load16_u align=1 + i32.store16 align=1 + end + block $B4 + local.get $l4 + i32.const 10 + i32.ge_s + if $I5 + local.get $l3 + i32.const -2 + i32.add + local.tee $l3 + local.get $l5 + i32.const 9 + i32.add + i32.add + local.get $l4 + i32.const 1 + i32.shl + i32.const 1055571 + i32.add + i32.load16_u align=1 + i32.store16 align=1 + br $B4 + end + local.get $l3 + i32.const -1 + i32.add + local.tee $l3 + local.get $l5 + i32.const 9 + i32.add + i32.add + local.get $l4 + i32.const 48 + i32.add + i32.store8 + end + local.get $p2 + local.get $p1 + i32.const 1054336 + i32.const 0 + local.get $l5 + i32.const 9 + i32.add + local.get $l3 + i32.add + i32.const 39 + local.get $l3 + i32.sub + call $f216 + local.get $l5 + i32.const 48 + i32.add + global.set $g0) + (func $f215 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + (local $l2 i32) (local $l3 i32) + global.get $g0 + i32.const 32 + i32.sub + local.tee $l2 + global.set $g0 + local.get $p1 + i32.const 28 + i32.add + i32.load + local.set $l3 + local.get $p1 + i32.load offset=24 + local.get $l2 + i32.const 24 + i32.add + local.get $p0 + i32.const 16 + i32.add + i64.load align=4 + i64.store + local.get $l2 + i32.const 16 + i32.add + local.get $p0 + i32.const 8 + i32.add + i64.load align=4 + i64.store + local.get $l2 + local.get $p0 + i64.load align=4 + i64.store offset=8 + local.get $l3 + local.get $l2 + i32.const 8 + i32.add + call $f179 + local.get $l2 + i32.const 32 + i32.add + global.set $g0) + (func $f216 (type $t12) (param $p0 i32) (param $p1 i32) (param $p2 i32) (param $p3 i32) (param $p4 i32) (param $p5 i32) (result i32) + (local $l6 i32) (local $l7 i32) (local $l8 i32) (local $l9 i32) (local $l10 i32) + block $B0 (result i32) + local.get $p1 + if $I1 + i32.const 43 + i32.const 1114112 + local.get $p0 + i32.load + local.tee $l10 + i32.const 1 + i32.and + local.tee $p1 + select + local.set $l9 + local.get $p1 + local.get $p5 + i32.add + br $B0 + end + local.get $p0 + i32.load + local.set $l10 + i32.const 45 + local.set $l9 + local.get $p5 + i32.const 1 + i32.add + end + local.set $l8 + block $B2 + local.get $l10 + i32.const 4 + i32.and + i32.eqz + if $I3 + i32.const 0 + local.set $p2 + br $B2 + end + local.get $p3 + if $I4 + local.get $p3 + local.set $l7 + local.get $p2 + local.set $p1 + loop $L5 + local.get $l6 + local.get $p1 + i32.load8_u + i32.const 192 + i32.and + i32.const 128 + i32.eq + i32.add + local.set $l6 + local.get $p1 + i32.const 1 + i32.add + local.set $p1 + local.get $l7 + i32.const -1 + i32.add + local.tee $l7 + br_if $L5 + end + end + local.get $p3 + local.get $l8 + i32.add + local.get $l6 + i32.sub + local.set $l8 + end + block $B6 + block $B7 + local.get $p0 + i32.load offset=8 + i32.const 1 + i32.ne + if $I8 + local.get $p0 + local.get $l9 + local.get $p2 + local.get $p3 + call $f217 + br_if $B7 + br $B6 + end + local.get $p0 + i32.const 12 + i32.add + i32.load + local.tee $l7 + local.get $l8 + i32.le_u + if $I9 + local.get $p0 + local.get $l9 + local.get $p2 + local.get $p3 + call $f217 + br_if $B7 + br $B6 + end + block $B10 + local.get $l10 + i32.const 8 + i32.and + i32.eqz + if $I11 + i32.const 0 + local.set $p1 + local.get $l7 + local.get $l8 + i32.sub + local.tee $l7 + local.set $l8 + block $B12 + block $B13 + block $B14 + i32.const 1 + local.get $p0 + i32.load8_u offset=48 + local.tee $l6 + local.get $l6 + i32.const 3 + i32.eq + select + i32.const 1 + i32.sub + br_table $B13 $B14 $B13 $B12 + end + local.get $l7 + i32.const 1 + i32.shr_u + local.set $p1 + local.get $l7 + i32.const 1 + i32.add + i32.const 1 + i32.shr_u + local.set $l8 + br $B12 + end + i32.const 0 + local.set $l8 + local.get $l7 + local.set $p1 + end + local.get $p1 + i32.const 1 + i32.add + local.set $p1 + loop $L15 + local.get $p1 + i32.const -1 + i32.add + local.tee $p1 + i32.eqz + br_if $B10 + local.get $p0 + i32.load offset=24 + local.get $p0 + i32.load offset=4 + local.get $p0 + i32.load offset=28 + i32.load offset=16 + call_indirect (type $t0) $T0 + i32.eqz + br_if $L15 + end + i32.const 1 + return + end + local.get $p0 + i32.const 1 + i32.store8 offset=48 + local.get $p0 + i32.const 48 + i32.store offset=4 + local.get $p0 + local.get $l9 + local.get $p2 + local.get $p3 + call $f217 + br_if $B7 + i32.const 0 + local.set $p1 + local.get $l7 + local.get $l8 + i32.sub + local.tee $p2 + local.set $p3 + block $B16 + block $B17 + block $B18 + i32.const 1 + local.get $p0 + i32.load8_u offset=48 + local.tee $l7 + local.get $l7 + i32.const 3 + i32.eq + select + i32.const 1 + i32.sub + br_table $B17 $B18 $B17 $B16 + end + local.get $p2 + i32.const 1 + i32.shr_u + local.set $p1 + local.get $p2 + i32.const 1 + i32.add + i32.const 1 + i32.shr_u + local.set $p3 + br $B16 + end + i32.const 0 + local.set $p3 + local.get $p2 + local.set $p1 + end + local.get $p1 + i32.const 1 + i32.add + local.set $p1 + block $B19 + loop $L20 + local.get $p1 + i32.const -1 + i32.add + local.tee $p1 + i32.eqz + br_if $B19 + local.get $p0 + i32.load offset=24 + local.get $p0 + i32.load offset=4 + local.get $p0 + i32.load offset=28 + i32.load offset=16 + call_indirect (type $t0) $T0 + i32.eqz + br_if $L20 + end + i32.const 1 + return + end + local.get $p0 + i32.load offset=4 + local.set $p1 + local.get $p0 + i32.load offset=24 + local.get $p4 + local.get $p5 + local.get $p0 + i32.load offset=28 + i32.load offset=12 + call_indirect (type $t1) $T0 + br_if $B7 + local.get $p3 + i32.const 1 + i32.add + local.set $l6 + local.get $p0 + i32.load offset=28 + local.set $p2 + local.get $p0 + i32.load offset=24 + local.set $p0 + loop $L21 + local.get $l6 + i32.const -1 + i32.add + local.tee $l6 + i32.eqz + if $I22 + i32.const 0 + return + end + local.get $p0 + local.get $p1 + local.get $p2 + i32.load offset=16 + call_indirect (type $t0) $T0 + i32.eqz + br_if $L21 + end + br $B7 + end + local.get $p0 + i32.load offset=4 + local.set $p1 + local.get $p0 + local.get $l9 + local.get $p2 + local.get $p3 + call $f217 + br_if $B7 + local.get $p0 + i32.load offset=24 + local.get $p4 + local.get $p5 + local.get $p0 + i32.load offset=28 + i32.load offset=12 + call_indirect (type $t1) $T0 + br_if $B7 + local.get $l8 + i32.const 1 + i32.add + local.set $l6 + local.get $p0 + i32.load offset=28 + local.set $p2 + local.get $p0 + i32.load offset=24 + local.set $p0 + loop $L23 + local.get $l6 + i32.const -1 + i32.add + local.tee $l6 + i32.eqz + if $I24 + i32.const 0 + return + end + local.get $p0 + local.get $p1 + local.get $p2 + i32.load offset=16 + call_indirect (type $t0) $T0 + i32.eqz + br_if $L23 + end + end + i32.const 1 + return + end + local.get $p0 + i32.load offset=24 + local.get $p4 + local.get $p5 + local.get $p0 + i32.const 28 + i32.add + i32.load + i32.load offset=12 + call_indirect (type $t1) $T0) + (func $f217 (type $t9) (param $p0 i32) (param $p1 i32) (param $p2 i32) (param $p3 i32) (result i32) + block $B0 (result i32) + local.get $p1 + i32.const 1114112 + i32.ne + if $I1 + i32.const 1 + local.get $p0 + i32.load offset=24 + local.get $p1 + local.get $p0 + i32.const 28 + i32.add + i32.load + i32.load offset=16 + call_indirect (type $t0) $T0 + br_if $B0 + drop + end + local.get $p2 + i32.eqz + if $I2 + i32.const 0 + return + end + local.get $p0 + i32.load offset=24 + local.get $p2 + local.get $p3 + local.get $p0 + i32.const 28 + i32.add + i32.load + i32.load offset=12 + call_indirect (type $t1) $T0 + end) + (func $f218 (type $t1) (param $p0 i32) (param $p1 i32) (param $p2 i32) (result i32) + local.get $p0 + i32.load offset=24 + local.get $p1 + local.get $p2 + local.get $p0 + i32.const 28 + i32.add + i32.load + i32.load offset=12 + call_indirect (type $t1) $T0) + (func $f219 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + (local $l2 i32) (local $l3 i32) + global.get $g0 + i32.const 32 + i32.sub + local.tee $l2 + global.set $g0 + local.get $p0 + i32.const 28 + i32.add + i32.load + local.set $l3 + local.get $p0 + i32.load offset=24 + local.get $l2 + i32.const 24 + i32.add + local.get $p1 + i32.const 16 + i32.add + i64.load align=4 + i64.store + local.get $l2 + i32.const 16 + i32.add + local.get $p1 + i32.const 8 + i32.add + i64.load align=4 + i64.store + local.get $l2 + local.get $p1 + i64.load align=4 + i64.store offset=8 + local.get $l3 + local.get $l2 + i32.const 8 + i32.add + call $f179 + local.get $l2 + i32.const 32 + i32.add + global.set $g0) + (func $f220 (type $t5) (param $p0 i32) (result i32) + local.get $p0 + i32.load8_u + i32.const 16 + i32.and + i32.const 4 + i32.shr_u) + (func $f221 (type $t5) (param $p0 i32) (result i32) + local.get $p0 + i32.load8_u + i32.const 32 + i32.and + i32.const 5 + i32.shr_u) + (func $f222 (type $t6) (param $p0 i32) (param $p1 i32) (param $p2 i32) (param $p3 i32) + local.get $p0 + local.get $p1 + i32.load offset=24 + local.get $p2 + local.get $p3 + local.get $p1 + i32.const 28 + i32.add + i32.load + i32.load offset=12 + call_indirect (type $t1) $T0 + i32.store8 offset=8 + local.get $p0 + local.get $p1 + i32.store + local.get $p0 + local.get $p3 + i32.eqz + i32.store8 offset=9 + local.get $p0 + i32.const 0 + i32.store offset=4) + (func $f223 (type $t3) (param $p0 i32) (param $p1 i32) + (local $l2 i32) + local.get $p1 + i32.load offset=24 + i32.const 1055550 + i32.const 1 + local.get $p1 + i32.const 28 + i32.add + i32.load + i32.load offset=12 + call_indirect (type $t1) $T0 + local.set $l2 + local.get $p0 + i32.const 0 + i32.store8 offset=5 + local.get $p0 + local.get $l2 + i32.store8 offset=4 + local.get $p0 + local.get $p1 + i32.store) + (func $f224 (type $t1) (param $p0 i32) (param $p1 i32) (param $p2 i32) (result i32) + (local $l3 i32) (local $l4 i32) (local $l5 i32) (local $l6 i32) (local $l7 i32) (local $l8 i32) (local $l9 i32) (local $l10 i32) (local $l11 i32) (local $l12 i32) (local $l13 i32) (local $l14 i32) (local $l15 i64) + global.get $g0 + i32.const 32 + i32.sub + local.tee $l8 + global.set $g0 + i32.const 1 + local.set $l10 + block $B0 + block $B1 + local.get $p2 + i32.load offset=24 + i32.const 34 + local.get $p2 + i32.const 28 + i32.add + i32.load + i32.load offset=16 + call_indirect (type $t0) $T0 + br_if $B1 + block $B2 + local.get $p1 + i32.eqz + br_if $B2 + local.get $p0 + local.get $p1 + i32.add + local.set $l12 + local.get $p0 + local.tee $l6 + local.set $l13 + loop $L3 + block $B4 + local.get $l6 + i32.const 1 + i32.add + local.set $l4 + block $B5 + block $B6 (result i32) + local.get $l6 + i32.load8_s + local.tee $l7 + i32.const -1 + i32.le_s + if $I7 + block $B8 (result i32) + local.get $l4 + local.get $l12 + i32.eq + if $I9 + i32.const 0 + local.set $l5 + local.get $l12 + br $B8 + end + local.get $l6 + i32.load8_u offset=1 + i32.const 63 + i32.and + local.set $l5 + local.get $l6 + i32.const 2 + i32.add + local.tee $l4 + end + local.set $l6 + local.get $l5 + local.get $l7 + i32.const 31 + i32.and + local.tee $l11 + i32.const 6 + i32.shl + i32.or + local.get $l7 + i32.const 255 + i32.and + local.tee $l14 + i32.const 223 + i32.le_u + br_if $B6 + drop + block $B10 (result i32) + local.get $l6 + local.get $l12 + i32.eq + if $I11 + i32.const 0 + local.set $l10 + local.get $l12 + br $B10 + end + local.get $l6 + i32.load8_u + i32.const 63 + i32.and + local.set $l10 + local.get $l6 + i32.const 1 + i32.add + local.tee $l4 + end + local.set $l7 + local.get $l10 + local.get $l5 + i32.const 6 + i32.shl + i32.or + local.tee $l5 + local.get $l11 + i32.const 12 + i32.shl + i32.or + local.get $l14 + i32.const 240 + i32.lt_u + br_if $B6 + drop + block $B12 (result i32) + local.get $l7 + local.get $l12 + i32.eq + if $I13 + local.get $l4 + local.set $l6 + i32.const 0 + br $B12 + end + local.get $l7 + i32.const 1 + i32.add + local.set $l6 + local.get $l7 + i32.load8_u + i32.const 63 + i32.and + end + local.get $l11 + i32.const 18 + i32.shl + i32.const 1835008 + i32.and + local.get $l5 + i32.const 6 + i32.shl + i32.or + i32.or + local.tee $l5 + i32.const 1114112 + i32.ne + br_if $B5 + br $B4 + end + local.get $l7 + i32.const 255 + i32.and + end + local.set $l5 + local.get $l4 + local.set $l6 + end + i32.const 2 + local.set $l4 + block $B14 + block $B15 + block $B16 + block $B17 + local.get $l5 + i32.const -9 + i32.add + local.tee $l11 + i32.const 30 + i32.gt_u + if $I18 + local.get $l5 + i32.const 92 + i32.ne + br_if $B17 + br $B16 + end + i32.const 116 + local.set $l7 + block $B19 + block $B20 + local.get $l11 + i32.const 1 + i32.sub + br_table $B19 $B17 $B17 $B20 $B17 $B17 $B17 $B17 $B17 $B17 $B17 $B17 $B17 $B17 $B17 $B17 $B17 $B17 $B17 $B17 $B17 $B17 $B17 $B17 $B16 $B17 $B17 $B17 $B17 $B16 $B15 + end + i32.const 114 + local.set $l7 + br $B15 + end + i32.const 110 + local.set $l7 + br $B15 + end + local.get $l5 + call $f198 + i32.eqz + if $I21 + local.get $l5 + call $f199 + br_if $B14 + end + local.get $l5 + i32.const 1 + i32.or + i32.clz + i32.const 2 + i32.shr_u + i32.const 7 + i32.xor + i64.extend_i32_u + i64.const 21474836480 + i64.or + local.set $l15 + i32.const 3 + local.set $l4 + end + local.get $l5 + local.set $l7 + end + local.get $l8 + local.get $p1 + i32.store offset=4 + local.get $l8 + local.get $p0 + i32.store + local.get $l8 + local.get $l3 + i32.store offset=8 + local.get $l8 + local.get $l9 + i32.store offset=12 + block $B22 + block $B23 + local.get $l9 + local.get $l3 + i32.lt_u + br_if $B23 + local.get $l3 + i32.eqz + local.get $p1 + local.get $l3 + i32.eq + i32.or + i32.eqz + if $I24 + local.get $l3 + local.get $p1 + i32.ge_u + br_if $B23 + local.get $p0 + local.get $l3 + i32.add + i32.load8_s + i32.const -65 + i32.le_s + br_if $B23 + end + local.get $l9 + i32.eqz + local.get $p1 + local.get $l9 + i32.eq + i32.or + i32.eqz + if $I25 + local.get $l9 + local.get $p1 + i32.ge_u + br_if $B23 + local.get $p0 + local.get $l9 + i32.add + i32.load8_s + i32.const -65 + i32.le_s + br_if $B23 + end + local.get $p2 + i32.load offset=24 + local.get $p0 + local.get $l3 + i32.add + local.get $l9 + local.get $l3 + i32.sub + local.get $p2 + i32.load offset=28 + i32.load offset=12 + call_indirect (type $t1) $T0 + i32.eqz + br_if $B22 + i32.const 1 + local.set $l10 + br $B1 + end + local.get $l8 + local.get $l8 + i32.const 12 + i32.add + i32.store offset=24 + local.get $l8 + local.get $l8 + i32.const 8 + i32.add + i32.store offset=20 + local.get $l8 + local.get $l8 + i32.store offset=16 + local.get $l8 + i32.const 16 + i32.add + local.tee $p0 + i32.load + local.tee $p1 + i32.load + local.get $p1 + i32.load offset=4 + local.get $p0 + i32.load offset=4 + i32.load + local.get $p0 + i32.load offset=8 + i32.load + call $f176 + unreachable + end + loop $L26 + local.get $l4 + local.set $l11 + i32.const 1 + local.set $l10 + i32.const 92 + local.set $l3 + i32.const 1 + local.set $l4 + block $B27 + block $B28 (result i64) + block $B29 + block $B30 + block $B31 + block $B32 + local.get $l11 + i32.const 1 + i32.sub + br_table $B31 $B27 $B32 $B30 + end + block $B33 + block $B34 + block $B35 + block $B36 + local.get $l15 + i64.const 32 + i64.shr_u + i32.wrap_i64 + i32.const 255 + i32.and + i32.const 1 + i32.sub + br_table $B33 $B34 $B35 $B36 $B29 $B30 + end + local.get $l15 + i64.const -1095216660481 + i64.and + i64.const 12884901888 + i64.or + local.set $l15 + i32.const 3 + local.set $l4 + i32.const 117 + local.set $l3 + br $B27 + end + local.get $l15 + i64.const -1095216660481 + i64.and + i64.const 8589934592 + i64.or + local.set $l15 + i32.const 3 + local.set $l4 + i32.const 123 + local.set $l3 + br $B27 + end + local.get $l7 + local.get $l15 + i32.wrap_i64 + local.tee $l11 + i32.const 2 + i32.shl + i32.const 28 + i32.and + i32.shr_u + i32.const 15 + i32.and + local.tee $l4 + i32.const 48 + i32.or + local.get $l4 + i32.const 87 + i32.add + local.get $l4 + i32.const 10 + i32.lt_u + select + local.set $l3 + local.get $l15 + i64.const -1 + i64.add + i64.const 4294967295 + i64.and + local.get $l15 + i64.const -4294967296 + i64.and + i64.or + local.get $l11 + br_if $B28 + drop + local.get $l15 + i64.const -1095216660481 + i64.and + i64.const 4294967296 + i64.or + br $B28 + end + local.get $l15 + i64.const -1095216660481 + i64.and + local.set $l15 + i32.const 3 + local.set $l4 + i32.const 125 + local.set $l3 + br $B27 + end + i32.const 0 + local.set $l4 + local.get $l7 + local.set $l3 + br $B27 + end + block $B37 (result i32) + i32.const 1 + local.get $l5 + i32.const 128 + i32.lt_u + br_if $B37 + drop + i32.const 2 + local.get $l5 + i32.const 2048 + i32.lt_u + br_if $B37 + drop + i32.const 3 + i32.const 4 + local.get $l5 + i32.const 65536 + i32.lt_u + select + end + local.get $l9 + i32.add + local.set $l3 + br $B14 + end + local.get $l15 + i64.const -1095216660481 + i64.and + i64.const 17179869184 + i64.or + end + local.set $l15 + i32.const 3 + local.set $l4 + end + local.get $p2 + i32.load offset=24 + local.get $l3 + local.get $p2 + i32.load offset=28 + i32.load offset=16 + call_indirect (type $t0) $T0 + i32.eqz + br_if $L26 + end + br $B1 + end + local.get $l9 + local.get $l13 + i32.sub + local.get $l6 + i32.add + local.set $l9 + local.get $l6 + local.set $l13 + local.get $l6 + local.get $l12 + i32.ne + br_if $L3 + end + end + local.get $l3 + i32.eqz + local.get $p1 + local.get $l3 + i32.eq + i32.or + br_if $B2 + local.get $l3 + local.get $p1 + i32.ge_u + br_if $B0 + local.get $p0 + local.get $l3 + i32.add + i32.load8_s + i32.const -65 + i32.le_s + br_if $B0 + end + i32.const 1 + local.set $l10 + local.get $p2 + i32.load offset=24 + local.get $p0 + local.get $l3 + i32.add + local.get $p1 + local.get $l3 + i32.sub + local.get $p2 + i32.load offset=28 + i32.load offset=12 + call_indirect (type $t1) $T0 + br_if $B1 + local.get $p2 + i32.load offset=24 + i32.const 34 + local.get $p2 + i32.load offset=28 + i32.load offset=16 + call_indirect (type $t0) $T0 + local.set $l10 + end + local.get $l8 + i32.const 32 + i32.add + global.set $g0 + local.get $l10 + return + end + local.get $p0 + local.get $p1 + local.get $l3 + local.get $p1 + call $f176 + unreachable) + (func $f225 (type $t1) (param $p0 i32) (param $p1 i32) (param $p2 i32) (result i32) + local.get $p2 + local.get $p0 + local.get $p1 + call $f175) + (func $f226 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + (local $l2 i32) (local $l3 i32) (local $l4 i32) + global.get $g0 + i32.const 128 + i32.sub + local.tee $l3 + global.set $g0 + local.get $p0 + i32.load + local.set $l2 + i32.const 0 + local.set $p0 + loop $L0 + local.get $p0 + local.get $l3 + i32.add + i32.const 127 + i32.add + local.get $l2 + i32.const 15 + i32.and + local.tee $l4 + i32.const 48 + i32.or + local.get $l4 + i32.const 87 + i32.add + local.get $l4 + i32.const 10 + i32.lt_u + select + i32.store8 + local.get $p0 + i32.const -1 + i32.add + local.set $p0 + local.get $l2 + i32.const 4 + i32.shr_u + local.tee $l2 + br_if $L0 + end + local.get $p0 + i32.const 128 + i32.add + local.tee $l2 + i32.const 129 + i32.ge_u + if $I1 + local.get $l2 + i32.const 128 + call $f174 + unreachable + end + local.get $p1 + i32.const 1 + i32.const 1055569 + i32.const 2 + local.get $p0 + local.get $l3 + i32.add + i32.const 128 + i32.add + i32.const 0 + local.get $p0 + i32.sub + call $f216 + local.get $l3 + i32.const 128 + i32.add + global.set $g0) + (func $f227 (type $t13) (param $p0 i32) (param $p1 i32) (param $p2 i32) (param $p3 i32) (param $p4 i32) (param $p5 i32) (param $p6 i32) (result i32) + (local $l7 i32) (local $l8 i32) (local $l9 i32) (local $l10 i32) (local $l11 i32) (local $l12 i32) (local $l13 i32) + i32.const 1 + local.set $l9 + block $B0 + block $B1 + local.get $p2 + i32.eqz + br_if $B1 + local.get $p1 + local.get $p2 + i32.const 1 + i32.shl + i32.add + local.set $l10 + local.get $p0 + i32.const 65280 + i32.and + i32.const 8 + i32.shr_u + local.set $l11 + local.get $p0 + i32.const 255 + i32.and + local.set $l13 + block $B2 + loop $L3 + local.get $p1 + i32.const 2 + i32.add + local.set $l12 + local.get $l7 + local.get $p1 + i32.load8_u offset=1 + local.tee $p2 + i32.add + local.set $l8 + local.get $l11 + local.get $p1 + i32.load8_u + local.tee $p1 + i32.ne + if $I4 + local.get $p1 + local.get $l11 + i32.gt_u + br_if $B1 + local.get $l8 + local.set $l7 + local.get $l12 + local.tee $p1 + local.get $l10 + i32.ne + br_if $L3 + br $B1 + end + local.get $l8 + local.get $l7 + i32.ge_u + if $I5 + local.get $l8 + local.get $p4 + i32.gt_u + br_if $B2 + local.get $p3 + local.get $l7 + i32.add + local.set $p1 + block $B6 + loop $L7 + local.get $p2 + i32.eqz + br_if $B6 + local.get $p2 + i32.const -1 + i32.add + local.set $p2 + local.get $p1 + i32.load8_u + local.get $p1 + i32.const 1 + i32.add + local.set $p1 + local.get $l13 + i32.ne + br_if $L7 + end + i32.const 0 + local.set $l9 + br $B0 + end + local.get $l8 + local.set $l7 + local.get $l12 + local.tee $p1 + local.get $l10 + i32.ne + br_if $L3 + br $B1 + end + end + local.get $l7 + local.get $l8 + call $f174 + unreachable + end + local.get $l8 + local.get $p4 + call $f173 + unreachable + end + local.get $p6 + i32.eqz + br_if $B0 + local.get $p5 + local.get $p6 + i32.add + local.set $p3 + local.get $p0 + i32.const 65535 + i32.and + local.set $p1 + loop $L8 + block $B9 + local.get $p5 + i32.const 1 + i32.add + local.set $p0 + block $B10 (result i32) + local.get $p0 + local.get $p5 + i32.load8_u + local.tee $p2 + i32.const 24 + i32.shl + i32.const 24 + i32.shr_s + local.tee $p4 + i32.const 0 + i32.ge_s + br_if $B10 + drop + local.get $p0 + local.get $p3 + i32.eq + br_if $B9 + local.get $p5 + i32.load8_u offset=1 + local.get $p4 + i32.const 127 + i32.and + i32.const 8 + i32.shl + i32.or + local.set $p2 + local.get $p5 + i32.const 2 + i32.add + end + local.set $p5 + local.get $p1 + local.get $p2 + i32.sub + local.tee $p1 + i32.const 0 + i32.lt_s + br_if $B0 + local.get $l9 + i32.const 1 + i32.xor + local.set $l9 + local.get $p3 + local.get $p5 + i32.ne + br_if $L8 + br $B0 + end + end + i32.const 1054488 + i32.const 43 + i32.const 1054552 + call $f172 + unreachable + end + local.get $l9 + i32.const 1 + i32.and) + (func $f228 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + (local $l2 i32) (local $l3 i32) + global.get $g0 + i32.const 16 + i32.sub + local.tee $l2 + global.set $g0 + local.get $p1 + i32.load offset=24 + i32.const 1060424 + i32.const 9 + local.get $p1 + i32.const 28 + i32.add + i32.load + i32.load offset=12 + call_indirect (type $t1) $T0 + local.set $l3 + local.get $l2 + i32.const 0 + i32.store8 offset=5 + local.get $l2 + local.get $l3 + i32.store8 offset=4 + local.get $l2 + local.get $p1 + i32.store + local.get $l2 + local.get $p0 + i32.store offset=12 + local.get $l2 + i32.const 1060433 + i32.const 11 + local.get $l2 + i32.const 12 + i32.add + i32.const 1060400 + call $f189 + local.get $l2 + local.get $p0 + i32.const 4 + i32.add + i32.store offset=12 + local.get $l2 + i32.const 1060444 + i32.const 9 + local.get $l2 + i32.const 12 + i32.add + i32.const 1060456 + call $f189 + local.get $l2 + i32.load8_u offset=4 + local.set $p1 + local.get $l2 + i32.load8_u offset=5 + if $I0 + local.get $p1 + i32.const 255 + i32.and + local.set $p0 + local.get $l2 + block $B1 (result i32) + i32.const 1 + local.get $p0 + br_if $B1 + drop + local.get $l2 + i32.load + local.tee $p0 + i32.const 28 + i32.add + i32.load + i32.load offset=12 + local.set $p1 + local.get $p0 + i32.load offset=24 + local.set $l3 + local.get $p0 + i32.load8_u + i32.const 4 + i32.and + i32.eqz + if $I2 + local.get $l3 + i32.const 1055543 + i32.const 2 + local.get $p1 + call_indirect (type $t1) $T0 + br $B1 + end + local.get $l3 + i32.const 1055542 + i32.const 1 + local.get $p1 + call_indirect (type $t1) $T0 + end + local.tee $p1 + i32.store8 offset=4 + end + local.get $l2 + i32.const 16 + i32.add + global.set $g0 + local.get $p1 + i32.const 255 + i32.and + i32.const 0 + i32.ne) + (func $f229 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + (local $l2 i32) (local $l3 i32) (local $l4 i32) + global.get $g0 + i32.const 128 + i32.sub + local.tee $l3 + global.set $g0 + local.get $p0 + i32.load8_u + local.set $l2 + i32.const 0 + local.set $p0 + loop $L0 + local.get $p0 + local.get $l3 + i32.add + i32.const 127 + i32.add + local.get $l2 + i32.const 15 + i32.and + local.tee $l4 + i32.const 48 + i32.or + local.get $l4 + i32.const 55 + i32.add + local.get $l4 + i32.const 10 + i32.lt_u + select + i32.store8 + local.get $p0 + i32.const -1 + i32.add + local.set $p0 + local.get $l2 + i32.const 4 + i32.shr_u + local.tee $l2 + br_if $L0 + end + local.get $p0 + i32.const 128 + i32.add + local.tee $l2 + i32.const 129 + i32.ge_u + if $I1 + local.get $l2 + i32.const 128 + call $f174 + unreachable + end + local.get $p1 + i32.const 1 + i32.const 1055569 + i32.const 2 + local.get $p0 + local.get $l3 + i32.add + i32.const 128 + i32.add + i32.const 0 + local.get $p0 + i32.sub + call $f216 + local.get $l3 + i32.const 128 + i32.add + global.set $g0) + (func $f230 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + (local $l2 i32) (local $l3 i32) (local $l4 i32) + global.get $g0 + i32.const 128 + i32.sub + local.tee $l3 + global.set $g0 + local.get $p0 + i32.load + local.set $l2 + i32.const 0 + local.set $p0 + loop $L0 + local.get $p0 + local.get $l3 + i32.add + i32.const 127 + i32.add + local.get $l2 + i32.const 15 + i32.and + local.tee $l4 + i32.const 48 + i32.or + local.get $l4 + i32.const 55 + i32.add + local.get $l4 + i32.const 10 + i32.lt_u + select + i32.store8 + local.get $p0 + i32.const -1 + i32.add + local.set $p0 + local.get $l2 + i32.const 4 + i32.shr_u + local.tee $l2 + br_if $L0 + end + local.get $p0 + i32.const 128 + i32.add + local.tee $l2 + i32.const 129 + i32.ge_u + if $I1 + local.get $l2 + i32.const 128 + call $f174 + unreachable + end + local.get $p1 + i32.const 1 + i32.const 1055569 + i32.const 2 + local.get $p0 + local.get $l3 + i32.add + i32.const 128 + i32.add + i32.const 0 + local.get $p0 + i32.sub + call $f216 + local.get $l3 + i32.const 128 + i32.add + global.set $g0) + (func $f231 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + (local $l2 i64) + local.get $p0 + i32.load + local.tee $p0 + i64.extend_i32_s + local.tee $l2 + local.get $l2 + i64.const 63 + i64.shr_s + local.tee $l2 + i64.add + local.get $l2 + i64.xor + local.get $p0 + i32.const -1 + i32.xor + i32.const 31 + i32.shr_u + local.get $p1 + call $f214) + (func $f232 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + local.get $p0 + i32.load + local.get $p1 + call $f181) + (func $f233 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + (local $l2 i32) (local $l3 i32) (local $l4 i32) + global.get $g0 + i32.const 128 + i32.sub + local.tee $l4 + global.set $g0 + local.get $p0 + i32.load + local.set $p0 + block $B0 + block $B1 + block $B2 (result i32) + block $B3 + local.get $p1 + i32.load + local.tee $l3 + i32.const 16 + i32.and + i32.eqz + if $I4 + local.get $p0 + i32.load8_u + local.set $l2 + local.get $l3 + i32.const 32 + i32.and + br_if $B3 + local.get $l2 + i64.extend_i32_u + i64.const 255 + i64.and + i32.const 1 + local.get $p1 + call $f214 + br $B2 + end + local.get $p0 + i32.load8_u + local.set $l2 + i32.const 0 + local.set $p0 + loop $L5 + local.get $p0 + local.get $l4 + i32.add + i32.const 127 + i32.add + local.get $l2 + i32.const 15 + i32.and + local.tee $l3 + i32.const 48 + i32.or + local.get $l3 + i32.const 87 + i32.add + local.get $l3 + i32.const 10 + i32.lt_u + select + i32.store8 + local.get $p0 + i32.const -1 + i32.add + local.set $p0 + local.get $l2 + i32.const 4 + i32.shr_u + local.tee $l2 + br_if $L5 + end + local.get $p0 + i32.const 128 + i32.add + local.tee $l2 + i32.const 129 + i32.ge_u + br_if $B1 + local.get $p1 + i32.const 1 + i32.const 1055569 + i32.const 2 + local.get $p0 + local.get $l4 + i32.add + i32.const 128 + i32.add + i32.const 0 + local.get $p0 + i32.sub + call $f216 + br $B2 + end + i32.const 0 + local.set $p0 + loop $L6 + local.get $p0 + local.get $l4 + i32.add + i32.const 127 + i32.add + local.get $l2 + i32.const 15 + i32.and + local.tee $l3 + i32.const 48 + i32.or + local.get $l3 + i32.const 55 + i32.add + local.get $l3 + i32.const 10 + i32.lt_u + select + i32.store8 + local.get $p0 + i32.const -1 + i32.add + local.set $p0 + local.get $l2 + i32.const 4 + i32.shr_u + local.tee $l2 + br_if $L6 + end + local.get $p0 + i32.const 128 + i32.add + local.tee $l2 + i32.const 129 + i32.ge_u + br_if $B0 + local.get $p1 + i32.const 1 + i32.const 1055569 + i32.const 2 + local.get $p0 + local.get $l4 + i32.add + i32.const 128 + i32.add + i32.const 0 + local.get $p0 + i32.sub + call $f216 + end + local.get $l4 + i32.const 128 + i32.add + global.set $g0 + return + end + local.get $l2 + i32.const 128 + call $f174 + unreachable + end + local.get $l2 + i32.const 128 + call $f174 + unreachable) + (func $f234 (type $t0) (param $p0 i32) (param $p1 i32) (result i32) + (local $l2 i32) + global.get $g0 + i32.const 16 + i32.sub + local.tee $l2 + global.set $g0 + block $B0 (result i32) + local.get $p0 + i32.load + local.tee $p0 + i32.load8_u + i32.const 1 + i32.ne + if $I1 + local.get $p1 + i32.load offset=24 + i32.const 1060420 + i32.const 4 + local.get $p1 + i32.const 28 + i32.add + i32.load + i32.load offset=12 + call_indirect (type $t1) $T0 + br $B0 + end + local.get $l2 + local.get $p1 + i32.load offset=24 + i32.const 1060416 + i32.const 4 + local.get $p1 + i32.const 28 + i32.add + i32.load + i32.load offset=12 + call_indirect (type $t1) $T0 + i32.store8 offset=8 + local.get $l2 + local.get $p1 + i32.store + local.get $l2 + i32.const 0 + i32.store8 offset=9 + local.get $l2 + i32.const 0 + i32.store offset=4 + local.get $l2 + local.get $p0 + i32.const 1 + i32.add + i32.store offset=12 + local.get $l2 + local.get $l2 + i32.const 12 + i32.add + i32.const 1055552 + call $f206 + local.get $l2 + i32.load8_u offset=8 + local.set $p1 + local.get $l2 + i32.load offset=4 + local.tee $p0 + if $I2 + local.get $p1 + i32.const 255 + i32.and + local.set $p1 + local.get $l2 + block $B3 (result i32) + i32.const 1 + local.get $p1 + br_if $B3 + drop + block $B4 + local.get $p0 + i32.const 1 + i32.ne + br_if $B4 + local.get $l2 + i32.load8_u offset=9 + i32.eqz + br_if $B4 + local.get $l2 + i32.load + local.tee $p0 + i32.load8_u + i32.const 4 + i32.and + br_if $B4 + i32.const 1 + local.get $p0 + i32.load offset=24 + i32.const 1055548 + i32.const 1 + local.get $p0 + i32.const 28 + i32.add + i32.load + i32.load offset=12 + call_indirect (type $t1) $T0 + br_if $B3 + drop + end + local.get $l2 + i32.load + local.tee $p0 + i32.load offset=24 + i32.const 1054952 + i32.const 1 + local.get $p0 + i32.const 28 + i32.add + i32.load + i32.load offset=12 + call_indirect (type $t1) $T0 + end + local.tee $p1 + i32.store8 offset=8 + end + local.get $p1 + i32.const 255 + i32.and + i32.const 0 + i32.ne + end + local.get $l2 + i32.const 16 + i32.add + global.set $g0) + (table $T0 104 104 funcref) + (memory $memory 17) + (global $g0 (mut i32) (i32.const 1048576)) + (global $__data_end i32 (i32.const 1061136)) + (global $__heap_base i32 (i32.const 1061136)) + (export "memory" (memory 0)) + (export "__data_end" (global 1)) + (export "__heap_base" (global 2)) + (export "_start" (func $_start)) + (export "__original_main" (func $__original_main)) + (export "main" (func $main)) + (elem $e0 (i32.const 1) $f21 $f30 $f23 $f215 $f31 $f29 $f32 $f29 $f16 $f29 $f34 $f35 $f47 $f31 $f92 $f93 $f231 $f21 $f46 $f178 $f128 $f45 $f123 $f132 $f29 $f76 $f68 $f72 $f75 $f69 $f73 $f77 $f70 $f74 $f44 $f41 $f29 $f39 $f183 $f66 $f141 $f182 $f29 $f228 $f61 $f125 $f15 $f99 $f96 $f97 $f98 $f21 $f100 $f62 $f118 $f50 $f53 $f119 $f48 $f52 $f60 $f59 $f65 $f124 $f58 $f56 $f110 $f116 $f120 $f49 $f117 $f64 $f105 $f106 $f107 $f108 $f109 $f63 $f135 $f136 $f38 $f137 $f138 $f40 $f43 $f185 $f180 $f204 $f178 $f191 $f29 $f39 $f29 $f205 $f209 $f210 $f29 $f233 $f211 $f212 $f213 $f232 $f234) + (data $d0 (i32.const 1048576) "/rustc/3ed3b8bb7b100afecf7d5f52eafbb70fec27f537/src/libcore/slice/mod.rs\00\00\10\00H\00\00\00\f6\0a\00\00\0a\00\00\00\00\00\10\00H\00\00\00\fc\0a\00\00\0e\00\00\00assertion failed: index < len<::core::macros::panic macros>\00\85\00\10\00\1e\00\00\00\03\00\00\00\0a\00\00\00DOG1CAT2DOG=1CAT=2Env vars:\0a\c6\00\10\00\0a\00\00\00\0a\00\00\00\d8\00\10\00\00\00\00\00\d8\00\10\00\01\00\00\00WASI_ENVVAR_TESTHELLODOG \00\00\00\01\01\10\00\04\00\00\00\d8\00\10\00\01\00\00\00DOG_TYPE \00\00\00\18\01\10\00\09\00\00\00\d8\00\10\00\01\00\00\00DOG_TYPESET VAR <\01\10\00\08\00\00\00\d8\00\10\00\01\00\00\00assertion failed: `(left == right)`\0a left: ``,\0a right: ``: T\01\10\00-\00\00\00\81\01\10\00\0c\00\00\00\8d\01\10\00\03\00\00\00destination and source slices have different lengths\a8\01\10\004\00\00\00/rustc/3ed3b8bb7b100afecf7d5f52eafbb70fec27f537/src/libcore/macros/mod.rs\00\00\00\e4\01\10\00I\00\00\00\17\00\00\00\0d\00\00\00Err\00\06\00\00\00\04\00\00\00\04\00\00\00\07\00\00\00Ok\00\00\08\00\00\00\04\00\00\00\04\00\00\00\09\00\00\00\0a\00\00\00\04\00\00\00\04\00\00\00\0b\00\00\00\0b\00\00\00\0c\00\00\00\19\00\00\00\04\00\00\00\04\00\00\00\1a\00\00\00\1b\00\00\00\1c\00\00\00\19\00\00\00\04\00\00\00\04\00\00\00\1d\00\00\00\1e\00\00\00\1f\00\00\00\19\00\00\00\04\00\00\00\04\00\00\00 \00\00\00!\00\00\00\22\00\00\00\19\00\00\00\04\00\00\00\04\00\00\00#\00\00\00\19\00\00\00\04\00\00\00\04\00\00\00$\00\00\00already borrowedalready mutably borrowed/rustc/3ed3b8bb7b100afecf7d5f52eafbb70fec27f537/src/libcore/macros/mod.rsassertion failed: `(left == right)`\0a left: ``,\0a right: ``\00Y\03\10\00-\00\00\00\86\03\10\00\0c\00\00\00\92\03\10\00\01\00\00\00\10\03\10\00I\00\00\00\0f\00\00\00(\00\00\00%\00\00\00\00\00\00\00\01\00\00\00&\00\00\00`: \00Y\03\10\00-\00\00\00\86\03\10\00\0c\00\00\00\cc\03\10\00\03\00\00\00called `Option::unwrap()` on a `None` value\00%\00\00\00\00\00\00\00\01\00\00\00'\00\00\00(\00\00\00\10\00\00\00\04\00\00\00)\00\00\00%\00\00\00\00\00\00\00\01\00\00\00*\00\00\00called `Result::unwrap()` on an `Err` value\00+\00\00\00\08\00\00\00\04\00\00\00,\00\00\00-\00\00\00\08\00\00\00\04\00\00\00.\00\00\00<::core::macros::panic macros>\00\00\90\04\10\00\1e\00\00\00\03\00\00\00\0a\00\00\00assertion failed: end <= lenTried to shrink to a larger capacity\19\00\00\00\04\00\00\00\04\00\00\00\0e\00\00\00src/libstd/thread/mod.rs\10\05\10\00\18\00\00\00\89\03\00\00\13\00\00\00inconsistent park state\00\02\00\00\00park state changed unexpectedly\00T\05\10\00\1f\00\00\00\10\05\10\00\18\00\00\00\86\03\00\00\0d\00\00\00\10\05\10\00\18\00\00\00\1f\04\00\00\11\00\00\00failed to generate unique thread ID: bitspace exhaustedthread name may not contain interior null bytes\00\00\10\05\10\00\18\00\00\00\94\04\00\00\12\00\00\00inconsistent state in unparkRUST_BACKTRACE0failed to get environment variable `\00?\06\10\00$\00\00\00\cc\03\10\00\03\00\00\00src/libstd/env.rs\00\00\00t\06\10\00\11\00\00\00\fb\00\00\00\1d\00\00\00failed to set environment variable `` to `\00\00\98\06\10\00$\00\00\00\bc\06\10\00\06\00\00\00\cc\03\10\00\03\00\00\00t\06\10\00\11\00\00\00K\01\00\00\09\00\00\00/\00\00\00\0c\00\00\00\04\00\00\000\00\00\001\00\00\001\00\00\002\00\00\003\00\00\004\00\00\005\00\00\00\22data provided contains a nul bytefailed to write the buffered dataunexpected end of fileother os erroroperation interruptedwrite zerotimed outinvalid datainvalid input parameteroperation would blockentity already existsbroken pipeaddress not availableaddress in usenot connectedconnection abortedconnection resetconnection refusedpermission deniedentity not found6\07\10\00\00\00\00\00 (os error )6\07\10\00\00\00\00\00\88\08\10\00\0b\00\00\00\93\08\10\00\01\00\00\00cannot access stdout during shutdownfailed printing to : \00\00\00\d0\08\10\00\13\00\00\00\e3\08\10\00\02\00\00\00src/libstd/io/stdio.rs\00\00\f8\08\10\00\16\00\00\00\18\03\00\00\09\00\00\00stdoutfailed to write whole bufferformatter error\00\00\006\00\00\00\0c\00\00\00\04\00\00\007\00\00\008\00\00\009\00\00\006\00\00\00\0c\00\00\00\04\00\00\00:\00\00\00;\00\00\00<\00\00\00src/libstd/sync/condvar.rs\00\00\84\09\10\00\1a\00\00\00H\02\00\00\12\00\00\00attempted to use a condition variable with two mutexes\00\00\19\00\00\00\04\00\00\00\04\00\00\00=\00\00\00>\00\00\00src/libstd/sync/once.rs\00\fc\09\10\00\17\00\00\00\a8\01\00\00\15\00\00\00assertion failed: state_and_queue & STATE_MASK == RUNNING\00\00\00\fc\09\10\00\17\00\00\00\8c\01\00\00\15\00\00\00Once instance has previously been poisoned\00\00\fc\09\10\00\17\00\00\00\e9\01\00\00\09\00\00\00src/libstd/sys_common/at_exit_imp.rs\ac\0a\10\00$\00\00\001\00\00\00\0d\00\00\00assertion failed: queue != DONE\00?\00\00\00\10\00\00\00\04\00\00\00@\00\00\00A\00\00\00note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.\0a\14\0b\10\00X\00\00\00fullPoisonError { inner: .. }src/libstd/sys_common/thread_info.rs\00\00\9a\0b\10\00$\00\00\00(\00\00\00\1a\00\00\00assertion failed: c.borrow().is_none()fatal runtime error: \0a\f6\0b\10\00\15\00\00\00\0b\0c\10\00\01\00\00\00\5cx\00\00\1c\0c\10\00\02\00\00\00\01\00\00\00\00\00\00\00 \00\00\00\08\00\00\00\03") + (data $d1 (i32.const 1051716) "\02\00\00\00\03\00\00\00\19\00\00\00\04\00\00\00\04\00\00\00B\00\00\00memory allocation of bytes failed\00\00\5c\0c\10\00\15\00\00\00q\0c\10\00\0d\00\00\00Box\00\00\00%\00\00\00\00\00\00\00\01\00\00\00C\00\00\00D\00\00\00E\00\00\00F\00\00\00G\00\00\00\00\00\00\00H\00\00\00\08\00\00\00\04\00\00\00I\00\00\00J\00\00\00K\00\00\00L\00\00\00M\00\00\00\00\00\00\00thread '' panicked at '', \00\00\ec\0c\10\00\08\00\00\00\f4\0c\10\00\0f\00\00\00\03\0d\10\00\03\00\00\00\0b\0c\10\00\01\00\00\00note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.\0a\00(\0d\10\00O\00\00\00N\00\00\00\10\00\00\00\04\00\00\00O\00\00\00P\00\00\00/\00\00\00\0c\00\00\00\04\00\00\00Q\00\00\00+\00\00\00\08\00\00\00\04\00\00\00R\00\00\00S\00\00\00+\00\00\00\08\00\00\00\04\00\00\00T\00\00\00thread panicked while processing panic. aborting.\0a\00\00\c8\0d\10\002\00\00\00thread panicked while panicking. aborting.\0a\00\04\0e\10\00+\00\00\00failed to initiate panic, error 8\0e\10\00 \00\00\00NotUnicodeNotPresentNulError\19\00\00\00\04\00\00\00\04\00\00\00U\00\00\00src/libstd/sys/wasi/../wasm/condvar.rs\00\00\8c\0e\10\00&\00\00\00\17\00\00\00\09\00\00\00can't block with web assemblysrc/libstd/sys/wasi/../wasm/mutex.rs\00\00\00\e1\0e\10\00$\00\00\00\16\00\00\00\09\00\00\00cannot recursively acquire mutexsrc/libstd/sys/wasi/os.rs\00\00\008\0f\10\00\19\00\00\00$\00\00\00\0d\00\00\00strerror_r failurerwlock locked for writing\00v\0f\10\00\19\00\00\00operation not supported on wasm yetstack backtrace:\0a\00\00\00\00\00\19\12D;\02?,G\14=30\0a\1b\06FKE7\0fI\0e\17\03@\1d<+6\1fJ-\1c\01 %)!\08\0c\15\16\22.\108>\0b41\18/A\099\11#C2B:\05\04&('\0d*\1e5\07\1aH\13$L\ff\00\00Success\00Illegal byte sequence\00Domain error\00Result not representable\00Not a tty\00Permission denied\00Operation not permitted\00No such file or directory\00No such process\00File exists\00Value too large for data type\00No space left on device\00Out of memory\00Resource busy\00Interrupted system call\00Resource temporarily unavailable\00Invalid seek\00Cross-device link\00Read-only file system\00Directory not empty\00Connection reset by peer\00Operation timed out\00Connection refused\00Host is unreachable\00Address in use\00Broken pipe\00I/O error\00No such device or address\00No such device\00Not a directory\00Is a directory\00Text file busy\00Exec format error\00Invalid argument\00Argument list too long\00Symbolic link loop\00Filename too long\00Too many open files in system\00No file descriptors available\00Bad file descriptor\00No child process\00Bad address\00File too large\00Too many links\00No locks available\00Resource deadlock would occur\00State not recoverable\00Previous owner died\00Operation canceled\00Function not implemented\00No message of desired type\00Identifier removed\00Link has been severed\00Protocol error\00Bad message\00Not a socket\00Destination address required\00Message too large\00Protocol wrong type for socket\00Protocol not available\00Protocol not supported\00Not supported\00Address family not supported by protocol\00Address not available\00Network is down\00Network unreachable\00Connection reset by network\00Connection aborted\00No buffer space available\00Socket is connected\00Socket not connected\00Operation already in progress\00Operation in progress\00Stale file handle\00Quota exceeded\00Multihop attempted\00Capabilities insufficient\00No error information\00\00src/liballoc/raw_vec.rscapacity overflow\00\00F\16\10\00\17\00\00\00\09\03\00\00\05\00\00\00`\00..\82\16\10\00\02\00\00\00BorrowErrorBorrowMutError\00\00\00[\00\00\00\00\00\00\00\01\00\00\00\5c\00\00\00:\00\00\00\80\16\10\00\00\00\00\00\b8\16\10\00\01\00\00\00\b8\16\10\00\01\00\00\00index out of bounds: the len is but the index is \00\00\d4\16\10\00 \00\00\00\f4\16\10\00\12\00\00\00called `Option::unwrap()` on a `None` valuesrc/libcore/option.rsC\17\10\00\15\00\00\00}\01\00\00\15\00\00\00\80\16\10\00\00\00\00\00C\17\10\00\15\00\00\00\a4\04\00\00\05\00\00\00: \00\00\80\16\10\00\00\00\00\00\80\17\10\00\02\00\00\00src/libcore/result.rs\00\00\00\94\17\10\00\15\00\00\00\a4\04\00\00\05\00\00\00src/libcore/slice/mod.rsindex out of range for slice of length \d4\17\10\00\06\00\00\00\da\17\10\00\22\00\00\00\bc\17\10\00\18\00\00\00r\0a\00\00\05\00\00\00slice index starts at but ends at \00\1c\18\10\00\16\00\00\002\18\10\00\0d\00\00\00\bc\17\10\00\18\00\00\00x\0a\00\00\05\00\00\00attempted to index slice up to maximum usize\bc\17\10\00\18\00\00\00~\0a\00\00\05\00\00\00assertion failed: broken.is_empty()src/libcore/str/lossy.rs\00\bf\18\10\00\18\00\00\00\9b\00\00\00\11\00\00\00)src/libcore/str/mod.rs\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01") + (data $d2 (i32.const 1055169) "\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\03\03\03\03\03\03\03\03\03\03\03\03\03\03\03\03\04\04\04\04\04") + (data $d3 (i32.const 1055231) "[...]byte index is out of bounds of `\00\00\00\04\1a\10\00\0b\00\00\00\0f\1a\10\00\16\00\00\00\80\16\10\00\01\00\00\00\e9\18\10\00\16\00\00\00\04\08\00\00\09\00\00\00begin <= end ( <= ) when slicing `\00\00P\1a\10\00\0e\00\00\00^\1a\10\00\04\00\00\00b\1a\10\00\10\00\00\00\80\16\10\00\01\00\00\00\e9\18\10\00\16\00\00\00\08\08\00\00\05\00\00\00 is not a char boundary; it is inside (bytes ) of `\04\1a\10\00\0b\00\00\00\a4\1a\10\00&\00\00\00\ca\1a\10\00\08\00\00\00\d2\1a\10\00\06\00\00\00\80\16\10\00\01\00\00\00\e9\18\10\00\16\00\00\00\15\08\00\00\05\00\00\00]\00\00\00\0c\00\00\00\04\00\00\00^\00\00\00_\00\00\00`\00\00\00 {\0a,\0a, { } }(\0a(,\0a[\00a\00\00\00\04\00\00\00\04\00\00\00b\00\00\00]0x00010203040506070809101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899\00a\00\00\00\04\00\00\00\04\00\00\00c\00\00\00d\00\00\00e\00\00\00src/libcore/fmt/mod.rs\00\004\1c\10\00\16\00\00\00S\04\00\00(\00\00\004\1c\10\00\16\00\00\00^\04\00\00(\00\00\00src/libcore/unicode/bool_trie.rsl\1c\10\00 \00\00\00'\00\00\00\19\00\00\00l\1c\10\00 \00\00\00(\00\00\00 \00\00\00l\1c\10\00 \00\00\00*\00\00\00\19\00\00\00l\1c\10\00 \00\00\00+\00\00\00\18\00\00\00l\1c\10\00 \00\00\00,\00\00\00 \00\00\00\00\01\03\05\05\06\06\03\07\06\08\08\09\11\0a\1c\0b\19\0c\14\0d\12\0e\0d\0f\04\10\03\12\12\13\09\16\01\17\05\18\02\19\03\1a\07\1c\02\1d\01\1f\16 \03+\04,\02-\0b.\010\031\022\01\a7\02\a9\02\aa\04\ab\08\fa\02\fb\05\fd\04\fe\03\ff\09\adxy\8b\8d\a20WX\8b\8c\90\1c\1d\dd\0e\0fKL\fb\fc./?\5c]_\b5\e2\84\8d\8e\91\92\a9\b1\ba\bb\c5\c6\c9\ca\de\e4\e5\ff\00\04\11\12)147:;=IJ]\84\8e\92\a9\b1\b4\ba\bb\c6\ca\ce\cf\e4\e5\00\04\0d\0e\11\12)14:;EFIJ^de\84\91\9b\9d\c9\ce\cf\0d\11)EIWde\8d\91\a9\b4\ba\bb\c5\c9\df\e4\e5\f0\04\0d\11EIde\80\81\84\b2\bc\be\bf\d5\d7\f0\f1\83\85\8b\a4\a6\be\bf\c5\c7\ce\cf\da\dbH\98\bd\cd\c6\ce\cfINOWY^_\89\8e\8f\b1\b6\b7\bf\c1\c6\c7\d7\11\16\17[\5c\f6\f7\fe\ff\80\0dmq\de\df\0e\0f\1fno\1c\1d_}~\ae\af\bb\bc\fa\16\17\1e\1fFGNOXZ\5c^~\7f\b5\c5\d4\d5\dc\f0\f1\f5rs\8ftu\96\97/_&./\a7\af\b7\bf\c7\cf\d7\df\9a@\97\980\8f\1f\c0\c1\ce\ffNOZ[\07\08\0f\10'/\ee\efno7=?BE\90\91\fe\ffSgu\c8\c9\d0\d1\d8\d9\e7\fe\ff\00 _\22\82\df\04\82D\08\1b\04\06\11\81\ac\0e\80\ab5\1e\15\80\e0\03\19\08\01\04/\044\04\07\03\01\07\06\07\11\0aP\0f\12\07U\08\02\04\1c\0a\09\03\08\03\07\03\02\03\03\03\0c\04\05\03\0b\06\01\0e\15\05:\03\11\07\06\05\10\07W\07\02\07\15\0dP\04C\03-\03\01\04\11\06\0f\0c:\04\1d%_ m\04j%\80\c8\05\82\b0\03\1a\06\82\fd\03Y\07\15\0b\17\09\14\0c\14\0cj\06\0a\06\1a\06Y\07+\05F\0a,\04\0c\04\01\031\0b,\04\1a\06\0b\03\80\ac\06\0a\06\1fAL\04-\03t\08<\03\0f\03<\078\08+\05\82\ff\11\18\08/\11-\03 \10!\0f\80\8c\04\82\97\19\0b\15\88\94\05/\05;\07\02\0e\18\09\80\b00t\0c\80\d6\1a\0c\05\80\ff\05\80\b6\05$\0c\9b\c6\0a\d20\10\84\8d\037\09\81\5c\14\80\b8\08\80\c705\04\0a\068\08F\08\0c\06t\0b\1e\03Z\04Y\09\80\83\18\1c\0a\16\09H\08\80\8a\06\ab\a4\0c\17\041\a1\04\81\da&\07\0c\05\05\80\a5\11\81m\10x(*\06L\04\80\8d\04\80\be\03\1b\03\0f\0d\00\06\01\01\03\01\04\02\08\08\09\02\0a\05\0b\02\10\01\11\04\12\05\13\11\14\02\15\02\17\02\19\04\1c\05\1d\08$\01j\03k\02\bc\02\d1\02\d4\0c\d5\09\d6\02\d7\02\da\01\e0\05\e1\02\e8\02\ee \f0\04\f9\06\fa\02\0c';>NO\8f\9e\9e\9f\06\07\096=>V\f3\d0\d1\04\14\1867VW\bd5\ce\cf\e0\12\87\89\8e\9e\04\0d\0e\11\12)14:EFIJNOdeZ\5c\b6\b7\1b\1c\a8\a9\d8\d9\097\90\91\a8\07\0a;>fi\8f\92o_\ee\efZb\9a\9b'(U\9d\a0\a1\a3\a4\a7\a8\ad\ba\bc\c4\06\0b\0c\15\1d:?EQ\a6\a7\cc\cd\a0\07\19\1a\22%>?\c5\c6\04 #%&(38:HJLPSUVXZ\5c^`cefksx}\7f\8a\a4\aa\af\b0\c0\d0\0cr\a3\a4\cb\ccno^\22{\05\03\04-\03e\04\01/.\80\82\1d\031\0f\1c\04$\09\1e\05+\05D\04\0e*\80\aa\06$\04$\04(\084\0b\01\80\90\817\09\16\0a\08\80\989\03c\08\090\16\05!\03\1b\05\01@8\04K\05/\04\0a\07\09\07@ '\04\0c\096\03:\05\1a\07\04\0c\07PI73\0d3\07.\08\0a\81&\1f\80\81(\08*\80\86\17\09N\04\1e\0fC\0e\19\07\0a\06G\09'\09u\0b?A*\06;\05\0a\06Q\06\01\05\10\03\05\80\8b` H\08\0a\80\a6^\22E\0b\0a\06\0d\139\07\0a6,\04\10\80\c0\00\00\00\00\00\0e") + (data $d5 (i32.const 1057330) "\f8\ff\fb\ff\ff\ff\07\00\00\00\00\00\00\14\fe!\fe\00\0c\00\00\00\02\00\00\00\00\00\00P\1e \80\00\0c\00\00@\06\00\00\00\00\00\00\10\869\02\00\00\00#\00\be!\00\00\0c\00\00\fc\02\00\00\00\00\00\00\d0\1e \c0\00\0c\00\00\00\04\00\00\00\00\00\00@\01 \80\00\00\00\00\00\11\00\00\00\00\00\00\c0\c1=`\00\0c\00\00\00\02\00\00\00\00\00\00\90D0`\00\0c\00\00\00\03\00\00\00\00\00\00X\1e \80\00\0c\00\00\00\00\84\5c\80") + (data $d6 (i32.const 1057486) "\f2\07\80\7f") + (data $d7 (i32.const 1057502) "\f2\1f\00?") + (data $d8 (i32.const 1057515) "\03\00\00\a0\02\00\00\00\00\00\00\fe\7f\df\e0\ff\fe\ff\ff\ff\1f@") + (data $d9 (i32.const 1057549) "\e0\fdf\00\00\00\c3\01\00\1e\00d \00 \00\00\00\00\00\00\00\e0\00\00\00\00\00\00\1c\00\00\00\1c\00\00\00\0c\00\00\00\0c\00\00\00\00\00\00\00\b0?@\fe\0f \00\00\00\00\008\00\00\00\00\00\00`\00\00\00\00\02\00\00\00\00\00\00\87\01\04\0e\00\00\80\09\00\00\00\00\00\00@\7f\e5\1f\f8\9f\00\00\00\00\00\00\ff\7f\0f\00\00\00\00\00\f0\17\04\00\00\00\00\f8\0f\00\03\00\00\00<;\00\00\00\00\00\00@\a3\03\00\00\00\00\00\00\f0\cf\00\00\00\f7\ff\fd!\10\03\ff\ff\ff\ff\ff\ff\ff\fb\00\10\00\00\00\00\00\00\00\00\ff\ff\ff\ff\01\00\00\00\00\00\00\80\03\00\00\00\00\00\00\00\00\80\00\00\00\00\ff\ff\ff\ff\00\00\00\00\00\fc\00\00\00\00\00\06") + (data $d10 (i32.const 1057773) "\80\f7?\00\00\00\c0") + (data $d11 (i32.const 1057790) "\03\00D\08\00\00`\00\00\000\00\00\00\ff\ff\03\80\00\00\00\00\c0?\00\00\80\ff\03\00\00\00\00\00\07\00\00\00\00\00\c83\00\00\00\00 \00\00\00\00\00\00\00\00~f\00\08\10\00\00\00\00\00\10\00\00\00\00\00\00\9d\c1\02\00\00\00\000@\00\00\00\00\00 !\00\00\00\00\00@\00\00\00\00\ff\ff\00\00\ff\ff") + (data $d12 (i32.const 1057903) "\01\00\00\00\02\00\03") + (data $d13 (i32.const 1057936) "\04\00\00\05\00\00\00\00\00\00\00\00\06\00\00\00\00\00\00\00\00\07\00\00\08\09\0a\00\0b\0c\0d\0e\0f\00\00\10\11\12\00\00\13\14\15\16\00\00\17\18\19\1a\1b\00\1c\00\00\00\1d\00\00\00\00\00\00\1e\1f !\00\00\00\00\00\22\00#\00$%&\00\00\00\00'") + (data $d14 (i32.const 1058131) "()") + (data $d15 (i32.const 1058149) "*+") + (data $d16 (i32.const 1058202) ",") + (data $d17 (i32.const 1058221) "-.\00\00/") + (data $d18 (i32.const 1058256) "012") + (data $d19 (i32.const 1058280) "3\00\00\00)\00\00\00\00\00\004") + (data $d20 (i32.const 1058315) "5\006") + (data $d21 (i32.const 1058344) "78\00\008889") + (data $d22 (i32.const 1058423) " \00\00\00\00\01") + (data $d23 (i32.const 1058438) "\c0\07n\f0\00\00\00\00\00\87\00\00\00\00`\00\00\00\00\00\00\00\f0\00\00\00\c0\ff\01\00\00\00\00\00\02\00\00\00\00\00\00\ff\7f\00\00\00\00\00\00\80\03\00\00\00\00\00x\06\07\00\00\00\80\ef\1f\00\00\00\00\00\00\00\08\00\03\00\00\00\00\00\c0\7f\00\1e") + (data $d24 (i32.const 1058533) "\80\d3@\00\00\00\80\f8\07\00\00\03\00\00\00\00\00\00X\01\00\80\00\c0\1f\1f\00\00\00\00\00\00\00\00\ff\5c\00\00@") + (data $d25 (i32.const 1058582) "\f9\a5\0d") + (data $d26 (i32.const 1058597) "\80<\b0\01\00\000") + (data $d27 (i32.const 1058614) "\f8\a7\01") + (data $d28 (i32.const 1058629) "(\bf\00\00\00\00\e0\bc\0f\00\00\00\00\00\00\00\80\ff\06\00\00\f0\0c\01\00\00\00\fe\07\00\00\00\00\f8y\80\00~\0e\00\00\00\00\00\fc\7f\03") + (data $d29 (i32.const 1058686) "\7f\bf\00\00\fc\ff\ff\fcm\00\00\00\00\00\00\00~\b4\bf") + (data $d30 (i32.const 1058714) "\a3") + (data $d31 (i32.const 1058726) "\18\00\00\00\00\00\00\00\1f\00\00\00\00\00\00\00\7f\00\00\80\00\00\00\00\00\00\00\80\07\00\00\00\00\00\00\00\00`\00\00\00\00\00\00\00\00\a0\c3\07\f8\e7\0f\00\00\00<\00\00\1c\00\00\00\00\00\00\00\ff\ff\ff\ff\ff\ff\7f\f8\ff\ff\ff\ff\ff\1f \00\10\00\00\f8\fe\ff\00\00\7f\ff\ff\f9\db\07\00\00\00\00\00\00\00\f0\00\00\00\00\7f\00\00\00\00\00\f0\07") + (data $d32 (i32.const 1058852) "\ff\ff\ff\ff\ff\ff\ff\ff\ff\ff\ff\ff\ff\ff\ff\ff\ff\ff") + (data $d33 (i32.const 1058968) "\ff\ff\ff\ff\ff\ff\ff\ff\ff\ff\ff\ff\ff\ff") + (data $d34 (i32.const 1059016) "\f8\03") + (data $d35 (i32.const 1059050) "\fe\ff\ff\ff\ff\bf\b6") + (data $d36 (i32.const 1059066) "\ff\07\00\00\00\00\00\f8\ff\ff\00\00\01") + (data $d37 (i32.const 1059090) "\c0\9f\9f=\00\00\00\00\02\00\00\00\ff\ff\ff\07") + (data $d38 (i32.const 1059116) "\c0\ff\01\00\00\00\00\00\00\f8\0f \18\22\10\00J\00\00\00h$\10\00\00\02\00\00h&\10\00:\00\00\00\00\01\02\03\04\05\06\07\08\09\08\0a\0b\0c\0d\0e\0f\10\11\12\13\14\02\15\16\17\18\19\1a\1b\1c\1d\1e\1f \02\02\02\02\02\02\02\02\02\02!\02\02\02\02\02\02\02\02\02\02\02\02\02\02\22#$%&\02'\02(\02\02\02)*+\02,-./0\02\021\02\02\022\02\02\02\02\02\02\02\023\02\024\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\025\026\027\02\02\02\02\02\02\02\028\029\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02:;<\02\02\02\02=\02\02>?@ABCDEF\02\02\02G\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02H\02\02\02\02\02\02\02\02\02\02\02I\02\02\02\02\02;\02\00\01\02\02\02\02\03\02\02\02\02\04\02\05\06\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\07\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02a\00\00\00\04\00\00\00\04\00\00\00f\00\00\00SomeNoneUtf8Errorvalid_up_toerror_len\00\00\00a\00\00\00\04\00\00\00\04\00\00\00g") + (data $d39 (i32.const 1060472) "\01\00\00\00\00\00\00\00\01\00\00\00\e40\10")) diff --git a/lib/wasi/tests/js.rs b/lib/wasi/tests/js.rs new file mode 100644 index 00000000000..909e050fde4 --- /dev/null +++ b/lib/wasi/tests/js.rs @@ -0,0 +1,135 @@ +#![cfg(feature = "js")] + +use wasm_bindgen_test::*; +use wasmer::{Instance, Module, Store}; +use wasmer_wasi::{Stdin, Stdout, WasiState}; + +#[wasm_bindgen_test] +fn test_stdout() { + let store = Store::default(); + let module = Module::new(&store, br#" + (module + ;; Import the required fd_write WASI function which will write the given io vectors to stdout + ;; The function signature for fd_write is: + ;; (File Descriptor, *iovs, iovs_len, nwritten) -> Returns number of bytes written + (import "wasi_unstable" "fd_write" (func $fd_write (param i32 i32 i32 i32) (result i32))) + + (memory 1) + (export "memory" (memory 0)) + + ;; Write 'hello world\n' to memory at an offset of 8 bytes + ;; Note the trailing newline which is required for the text to appear + (data (i32.const 8) "hello world\n") + + (func $main (export "_start") + ;; Creating a new io vector within linear memory + (i32.store (i32.const 0) (i32.const 8)) ;; iov.iov_base - This is a pointer to the start of the 'hello world\n' string + (i32.store (i32.const 4) (i32.const 12)) ;; iov.iov_len - The length of the 'hello world\n' string + + (call $fd_write + (i32.const 1) ;; file_descriptor - 1 for stdout + (i32.const 0) ;; *iovs - The pointer to the iov array, which is stored at memory location 0 + (i32.const 1) ;; iovs_len - We're printing 1 string stored in an iov - so one. + (i32.const 20) ;; nwritten - A place in memory to store the number of bytes written + ) + drop ;; Discard the number of bytes written from the top of the stack + ) + ) + "#).unwrap(); + + // Create the `WasiEnv`. + // let stdout = Stdout::default(); + let mut wasi_env = WasiState::new("command-name") + .args(&["Gordon"]) + // .stdout(Box::new(stdout)) + .finalize() + .unwrap(); + + // Generate an `ImportObject`. + let import_object = wasi_env.import_object(&module).unwrap(); + + // Let's instantiate the module with the imports. + let instance = Instance::new(&module, &import_object).unwrap(); + + // Let's call the `_start` function, which is our `main` function in Rust. + let start = instance.exports.get_function("_start").unwrap(); + start.call(&[]).unwrap(); + + let state = wasi_env.state(); + let stdout = state.fs.stdout().unwrap().as_ref().unwrap(); + let stdout = stdout.downcast_ref::().unwrap(); + let stdout_as_str = std::str::from_utf8(&stdout.buf).unwrap(); + assert_eq!(stdout_as_str, "hello world\n"); +} +#[wasm_bindgen_test] +fn test_env() { + let store = Store::default(); + let module = Module::new(&store, include_bytes!("envvar.wasm")).unwrap(); + + tracing_wasm::set_as_global_default_with_config({ + let mut builder = tracing_wasm::WASMLayerConfigBuilder::new(); + builder.set_console_config(tracing_wasm::ConsoleConfig::ReportWithoutConsoleColor); + builder.build() + }); + + // Create the `WasiEnv`. + // let stdout = Stdout::default(); + let mut wasi_state_builder = WasiState::new("command-name"); + wasi_state_builder + .args(&["Gordon"]) + .env("DOG", "X") + .env("TEST", "VALUE") + .env("TEST2", "VALUE2"); + // panic!("envs: {:?}", wasi_state_builder.envs); + let mut wasi_env = wasi_state_builder + // .stdout(Box::new(stdout)) + .finalize() + .unwrap(); + + // Generate an `ImportObject`. + let import_object = wasi_env.import_object(&module).unwrap(); + + // Let's instantiate the module with the imports. + let instance = Instance::new(&module, &import_object).unwrap(); + + // Let's call the `_start` function, which is our `main` function in Rust. + let start = instance.exports.get_function("_start").unwrap(); + start.call(&[]).unwrap(); + + let state = wasi_env.state(); + let stdout = state.fs.stdout().unwrap().as_ref().unwrap(); + let stdout = stdout.downcast_ref::().unwrap(); + let stdout_as_str = std::str::from_utf8(&stdout.buf).unwrap(); + assert_eq!(stdout_as_str, "Env vars:\nDOG=X\nTEST2=VALUE2\nTEST=VALUE\nDOG Ok(\"X\")\nDOG_TYPE Err(NotPresent)\nSET VAR Ok(\"HELLO\")\n"); +} + +#[wasm_bindgen_test] +fn test_stdin() { + let store = Store::default(); + let module = Module::new(&store, include_bytes!("stdin-hello.wasm")).unwrap(); + + // Create the `WasiEnv`. + let mut stdin = Stdin::default(); + stdin.buf = "Hello, stdin!".as_bytes().to_owned(); + let mut wasi_env = WasiState::new("command-name") + .stdin(Box::new(stdin)) + .finalize() + .unwrap(); + + // Generate an `ImportObject`. + let import_object = wasi_env.import_object(&module).unwrap(); + + // Let's instantiate the module with the imports. + let instance = Instance::new(&module, &import_object).unwrap(); + + // Let's call the `_start` function, which is our `main` function in Rust. + let start = instance.exports.get_function("_start").unwrap(); + let result = start.call(&[]); + assert!(result.is_err()); + // let status = result.unwrap_err().downcast::().unwrap(); + let state = wasi_env.state(); + let stdin = state.fs.stdin().unwrap().as_ref().unwrap(); + let stdin = stdin.downcast_ref::().unwrap(); + // We assure stdin is now empty + assert_eq!(stdin.buf.len(), 0); +} diff --git a/lib/wasi/tests/stdin-hello.wasm b/lib/wasi/tests/stdin-hello.wasm new file mode 100644 index 00000000000..5974bcb97b3 Binary files /dev/null and b/lib/wasi/tests/stdin-hello.wasm differ diff --git a/tests/ignores.txt b/tests/ignores.txt index 0deb2277124..e02ce8b74c9 100644 --- a/tests/ignores.txt +++ b/tests/ignores.txt @@ -118,6 +118,6 @@ windows wasitests::unstable::path_link windows wasitests::unstable::path_symlink windows wasitests::unstable::mapdir_with_leading_slash -# This test is meant to only run on Unix -windows wasitests::unstable::unix_open_special_files -windows wasitests::snapshot1::unix_open_special_files +# This tests are disabled for now +wasitests::unstable::unix_open_special_files +wasitests::snapshot1::unix_open_special_files diff --git a/tests/lib/compiler-test-derive/src/lib.rs b/tests/lib/compiler-test-derive/src/lib.rs index 490d497a0ab..f9dbc7d5f4e 100644 --- a/tests/lib/compiler-test-derive/src/lib.rs +++ b/tests/lib/compiler-test-derive/src/lib.rs @@ -85,7 +85,7 @@ pub fn compiler_test(attrs: TokenStream, input: TokenStream) -> TokenStream { new_sig.ident = test_name; new_sig.inputs = ::syn::punctuated::Punctuated::new(); let f = quote! { - #[test] + #[test_env_log::test] #attrs #[cfg(feature = #engine_feature_name)] #new_sig { diff --git a/tests/lib/compiler-test-derive/src/tests.rs b/tests/lib/compiler-test-derive/src/tests.rs index a6ae9d9b9fb..ae44f2d1e3b 100644 --- a/tests/lib/compiler-test-derive/src/tests.rs +++ b/tests/lib/compiler-test-derive/src/tests.rs @@ -54,7 +54,7 @@ gen_tests! { #[cfg(feature = "singlepass")] mod singlepass { use super::*; - #[test] + #[test_env_log::test] #[cold] #[cfg(feature = "universal")] fn universal() { @@ -63,7 +63,7 @@ gen_tests! { crate::Compiler::Singlepass )) } - #[test] + #[test_env_log::test] #[cold] #[cfg(feature = "dylib")] fn dylib() { @@ -77,7 +77,7 @@ gen_tests! { #[cfg(feature = "cranelift")] mod cranelift { use super::*; - #[test] + #[test_env_log::test] #[cold] #[cfg(feature = "universal")] fn universal() { @@ -86,7 +86,7 @@ gen_tests! { crate::Compiler::Cranelift )) } - #[test] + #[test_env_log::test] #[cold] #[cfg(feature = "dylib")] fn dylib() { @@ -100,7 +100,7 @@ gen_tests! { #[cfg(feature = "llvm")] mod llvm { use super::*; - #[test] + #[test_env_log::test] #[cold] #[cfg(feature = "universal")] fn universal() { @@ -109,7 +109,7 @@ gen_tests! { crate::Compiler::LLVM )) } - #[test] + #[test_env_log::test] #[cold] #[cfg(feature = "dylib")] fn dylib() { diff --git a/tests/lib/wast/Cargo.toml b/tests/lib/wast/Cargo.toml index 9f44668734f..7b86aefdf9f 100644 --- a/tests/lib/wast/Cargo.toml +++ b/tests/lib/wast/Cargo.toml @@ -18,7 +18,6 @@ wast = "37.0" serde = "1" tempfile = "3" thiserror = "1.0" -typetag = "0.1" [features] default = ["wat"] diff --git a/tests/lib/wast/src/wasi_wast.rs b/tests/lib/wast/src/wasi_wast.rs index 1a577f4a270..a588d59f994 100644 --- a/tests/lib/wast/src/wasi_wast.rs +++ b/tests/lib/wast/src/wasi_wast.rs @@ -1,12 +1,11 @@ use anyhow::Context; -use serde::{Deserialize, Serialize}; use std::fs::File; use std::io::{self, Read, Seek, Write}; use std::path::PathBuf; use wasmer::{ImportObject, Instance, Module, Store}; use wasmer_wasi::types::{__wasi_filesize_t, __wasi_timestamp_t}; use wasmer_wasi::{ - generate_import_object_from_env, get_wasi_version, Pipe, WasiEnv, WasiFile, WasiFsError, + generate_import_object_from_env, get_wasi_version, FsError, Pipe, VirtualFile, WasiEnv, WasiState, WasiVersion, }; use wast::parser::{self, Parse, ParseBuffer, Parser}; @@ -468,7 +467,7 @@ mod test { } } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug)] struct OutputCapturerer { output: Vec, } @@ -530,8 +529,7 @@ impl Write for OutputCapturerer { } } -#[typetag::serde] -impl WasiFile for OutputCapturerer { +impl VirtualFile for OutputCapturerer { fn last_accessed(&self) -> __wasi_timestamp_t { 0 } @@ -544,13 +542,13 @@ impl WasiFile for OutputCapturerer { fn size(&self) -> u64 { 0 } - fn set_len(&mut self, _new_size: __wasi_filesize_t) -> Result<(), WasiFsError> { + fn set_len(&mut self, _new_size: __wasi_filesize_t) -> Result<(), FsError> { Ok(()) } - fn unlink(&mut self) -> Result<(), WasiFsError> { + fn unlink(&mut self) -> Result<(), FsError> { Ok(()) } - fn bytes_available(&self) -> Result { + fn bytes_available(&self) -> Result { Ok(1024) } }