From d0dd236f778d5978f1893ccf3a9e89d8a67fd395 Mon Sep 17 00:00:00 2001 From: BlobMaster41 <96896824+BlobMaster41@users.noreply.github.com> Date: Sun, 3 Nov 2024 17:17:56 -0500 Subject: [PATCH 01/23] Modified toml --- .idea/.gitignore | 8 ++++++++ .idea/modules.xml | 8 ++++++++ .idea/rust_runtime.iml | 12 ++++++++++++ .idea/vcs.xml | 6 ++++++ Cargo.toml | 5 +++++ README.md | 2 +- example/Cargo.toml | 4 ++++ 7 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/modules.xml create mode 100644 .idea/rust_runtime.iml create mode 100644 .idea/vcs.xml diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..33cd640 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/rust_runtime.iml b/.idea/rust_runtime.iml new file mode 100644 index 0000000..0c25ece --- /dev/null +++ b/.idea/rust_runtime.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 5b1dcf6..83b9016 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,11 @@ edition = "2021" [workspace] members = ["example"] +[profile.release] +opt-level = "z" # or "s" for size-speed balance +lto = true # Link Time Optimization for smaller binary +codegen-units = 1 # Ensures code is optimized across the board +panic = "abort" # Avoids including panic runtime support [dependencies] diff --git a/README.md b/README.md index 2409020..e7ef9a7 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ ## Compilation ```sh cargo build --release -p example -wasm-opt -O2 -Oz ../target/wasm32-unknown-unknown/release/example.wasm -o ./rust.wasm +wasm-opt -O2 -Oz --strip-debug --strip-dwarf --dce ../target/wasm32-unknown-unknown/release/example.wasm -o ./rust.wasm ``` ## Testing diff --git a/example/Cargo.toml b/example/Cargo.toml index ddec4b8..ae37c1d 100644 --- a/example/Cargo.toml +++ b/example/Cargo.toml @@ -7,6 +7,10 @@ edition = "2021" crate-type = ["cdylib"] [profile.release] +opt-level = "z" # or "s" for size-speed balance +lto = true # Link Time Optimization for smaller binary +codegen-units = 1 # Ensures code is optimized across the board +panic = "abort" # Avoids including panic runtime support strip = true [dependencies] From 26bcb70f60a5c90d8734a0a7bc72b958d39b98d6 Mon Sep 17 00:00:00 2001 From: BlobMaster41 <96896824+BlobMaster41@users.noreply.github.com> Date: Sun, 3 Nov 2024 18:10:10 -0500 Subject: [PATCH 02/23] Changed nostd (partial) --- .cargo/config | 2 - Cargo.lock | 55 + Cargo.toml | 8 +- README.md | 2 +- done.js | 9057 +------------------------------------------- example/Cargo.toml | 4 +- rust.wasm | Bin 0 -> 19101 bytes src/allocator.rs | 57 +- src/lib.rs | 3 + src/mem.rs | 32 +- 10 files changed, 162 insertions(+), 9058 deletions(-) delete mode 100644 .cargo/config create mode 100644 rust.wasm diff --git a/.cargo/config b/.cargo/config deleted file mode 100644 index 435ed75..0000000 --- a/.cargo/config +++ /dev/null @@ -1,2 +0,0 @@ -[build] -target = "wasm32-unknown-unknown" \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 0f7d129..88e186b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,12 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + [[package]] name = "example" version = "0.1.0" @@ -17,12 +23,61 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "libc" +version = "0.2.161" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" + +[[package]] +name = "memory_units" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3" + [[package]] name = "rust_runtime" version = "0.1.0" +dependencies = [ + "wee_alloc", +] [[package]] name = "wasm_allocator" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c8f71f7436c9b614d8b94613c053fb38e87fd22796cc27c780ee97ec9a085b1" + +[[package]] +name = "wee_alloc" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e" +dependencies = [ + "cfg-if", + "libc", + "memory_units", + "winapi", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/Cargo.toml b/Cargo.toml index 83b9016..378ce63 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,12 +6,10 @@ edition = "2021" [workspace] members = ["example"] -[profile.release] -opt-level = "z" # or "s" for size-speed balance -lto = true # Link Time Optimization for smaller binary -codegen-units = 1 # Ensures code is optimized across the board -panic = "abort" # Avoids including panic runtime support +[build] +target = "wasm32-unknown-unknown" [dependencies] +wee_alloc = "0.4.5" diff --git a/README.md b/README.md index e7ef9a7..2be6f2b 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ ## Compilation ```sh cargo build --release -p example -wasm-opt -O2 -Oz --strip-debug --strip-dwarf --dce ../target/wasm32-unknown-unknown/release/example.wasm -o ./rust.wasm +wasm-opt -O3 -Oz --strip-debug --strip-dwarf --dce --disable-multimemory --disable-fp16 --disable-mutable-globals --disable-gc --disable-multivalue --disable-nontrapping-float-to-int --disable-threads --mvp-features --remove-unused-module-elements ./target/wasm32-unknown-unknown/release/example.wasm -o ./rust.wasm ``` ## Testing diff --git a/done.js b/done.js index 2be7399..49bb262 100644 --- a/done.js +++ b/done.js @@ -1,9016 +1,61 @@ -import * as env from 'env'; - var bufferView; - var base64ReverseLookup = new Uint8Array(123/*'z'+1*/); - for (var i = 25; i >= 0; --i) { - base64ReverseLookup[48+i] = 52+i; // '0-9' - base64ReverseLookup[65+i] = i; // 'A-Z' - base64ReverseLookup[97+i] = 26+i; // 'a-z' - } - base64ReverseLookup[43] = 62; // '+' - base64ReverseLookup[47] = 63; // '/' - /** @noinline Inlining this function would mean expanding the base64 string 4x times in the source code, which Closure seems to be happy to do. */ - function base64DecodeToExistingUint8Array(uint8Array, offset, b64) { - var b1, b2, i = 0, j = offset, bLength = b64.length, end = offset + (bLength*3>>2) - (b64[bLength-2] == '=') - (b64[bLength-1] == '='); - for (; i < bLength; i += 4) { - b1 = base64ReverseLookup[b64.charCodeAt(i+1)]; - b2 = base64ReverseLookup[b64.charCodeAt(i+2)]; - uint8Array[j++] = base64ReverseLookup[b64.charCodeAt(i)] << 2 | b1 >> 4; - if (j < end) uint8Array[j++] = b1 << 4 | b2 >> 2; - if (j < end) uint8Array[j++] = b2 << 6 | base64ReverseLookup[b64.charCodeAt(i+3)]; - } - } -function initActiveSegments(imports) { - base64DecodeToExistingUint8Array(bufferView, 1048576, "AwAAAAwAAAAEAAAABAAAAAUAAAAGAAAAL3J1c3QvZGVwcy9kbG1hbGxvYy0wLjIuNi9zcmMvZGxtYWxsb2MucnNhc3NlcnRpb24gZmFpbGVkOiBwc2l6ZSA+PSBzaXplICsgbWluX292ZXJoZWFkABgAEAApAAAAqAQAAAkAAABhc3NlcnRpb24gZmFpbGVkOiBwc2l6ZSA8PSBzaXplICsgbWF4X292ZXJoZWFkAAAYABAAKQAAAK4EAAANAAAAbWVtb3J5IGFsbG9jYXRpb24gb2YgIGJ5dGVzIGZhaWxlZAAAwAAQABUAAADVABAADQAAAHN0ZC9zcmMvYWxsb2MucnP0ABAAEAAAAGMBAAAJAAAAAwAAAAwAAAAEAAAABwAAAAAAAAAIAAAABAAAAAgAAAAAAAAACAAAAAQAAAAJAAAACgAAAAsAAAAMAAAADQAAABAAAAAEAAAADgAAAA8AAAAQAAAAEQAAAEVycm9yAAAAEgAAAAwAAAAEAAAAEwAAABQAAAAVAAAAY2FwYWNpdHkgb3ZlcmZsb3cAAACMARAAEQAAAGFsbG9jL3NyYy9yYXdfdmVjLnJzqAEQABQAAAAYAAAABQAAAAAAAAAAAAAAAQAAABYAAABhIGZvcm1hdHRpbmcgdHJhaXQgaW1wbGVtZW50YXRpb24gcmV0dXJuZWQgYW4gZXJyb3Igd2hlbiB0aGUgdW5kZXJseWluZyBzdHJlYW0gZGlkIG5vdGFsbG9jL3NyYy9mbXQucnMAADICEAAQAAAAfgIAAA4AAABbY2FsbGVkIGBPcHRpb246OnVud3JhcCgpYCBvbiBhIGBOb25lYCB2YWx1ZWluZGV4IG91dCBvZiBib3VuZHM6IHRoZSBsZW4gaXMgIGJ1dCB0aGUgaW5kZXggaXMgAACAAhAAIAAAAKACEAASAAAAOiAAAAEAAAAAAAAAxAIQAAIAAAAAAAAADAAAAAQAAAAZAAAAGgAAABsAAAAgICAgLCAsCgpdY29yZS9zcmMvZm10L251bS5ycwAAAPoCEAATAAAAZgAAABcAAAAweDAwMDEwMjAzMDQwNTA2MDcwODA5MTAxMTEyMTMxNDE1MTYxNzE4MTkyMDIxMjIyMzI0MjUyNjI3MjgyOTMwMzEzMjMzMzQzNTM2MzczODM5NDA0MTQyNDM0NDQ1NDY0NzQ4NDk1MDUxNTI1MzU0NTU1NjU3NTg1OTYwNjE2MjYzNjQ2NTY2Njc2ODY5NzA3MTcyNzM3NDc1NzY3Nzc4Nzk4MDgxODI4Mzg0ODU4Njg3ODg4OTkwOTE5MjkzOTQ5NTk2OTc5ODk5cmFuZ2Ugc3RhcnQgaW5kZXggIG91dCBvZiByYW5nZSBmb3Igc2xpY2Ugb2YgbGVuZ3RoIAAA6gMQABIAAAD8AxAAIgAAAHJhbmdlIGVuZCBpbmRleCAwBBAAEAAAAPwDEAAiAAAAL3J1c3RjLzNlOWJkOGI1NjZhNDdjNWQxYzFkYmM3ZTA0M2I0YjdmYTUzMzBlY2EvbGlicmFyeS9hbGxvYy9zcmMvY29sbGVjdGlvbnMvYnRyZWUvbWFwL2VudHJ5LnJzUAQQAGAAAABxAQAANgAAAC9ydXN0Yy8zZTliZDhiNTY2YTQ3YzVkMWMxZGJjN2UwNDNiNGI3ZmE1MzMwZWNhL2xpYnJhcnkvYWxsb2Mvc3JjL2NvbGxlY3Rpb25zL2J0cmVlL25vZGUucnNhc3NlcnRpb24gZmFpbGVkOiBlZGdlLmhlaWdodCA9PSBzZWxmLmhlaWdodCAtIDEAwAQQAFsAAACvAgAACQAAAGludGVybmFsIGVycm9yOiBlbnRlcmVkIHVucmVhY2hhYmxlIGNvZGU6IGVtcHR5IGludGVybmFsIG5vZGUAAABcBRAAPQAAAMAEEABbAAAAKwUAAB8AAABhc3NlcnRpb24gZmFpbGVkOiBzZWxmLmhlaWdodCA+IDAAAADABBAAWwAAAGICAAAJAAAAYXNzZXJ0aW9uIGZhaWxlZDogc3JjLmxlbigpID09IGRzdC5sZW4oKcAEEABbAAAALwcAAAUAAADABBAAWwAAAK8EAAAjAAAAwAQQAFsAAADvBAAAJAAAAGFzc2VydGlvbiBmYWlsZWQ6IGVkZ2UuaGVpZ2h0ID09IHNlbGYubm9kZS5oZWlnaHQgLSAxAAAAwAQQAFsAAADwAwAACQAAAGFzc2VydGlvbiBmYWlsZWQ6IG9sZF9yaWdodF9sZW4gKyBjb3VudCA8PSBDQVBBQ0lUWQDABBAAWwAAANwFAAANAAAAYXNzZXJ0aW9uIGZhaWxlZDogb2xkX2xlZnRfbGVuID49IGNvdW50AMAEEABbAAAA3QUAAA0AAABpbnRlcm5hbCBlcnJvcjogZW50ZXJlZCB1bnJlYWNoYWJsZSBjb2RlwAQQAFsAAAAMBgAAFgAAAGFzc2VydGlvbiBmYWlsZWQ6IG9sZF9sZWZ0X2xlbiArIGNvdW50IDw9IENBUEFDSVRZAADABBAAWwAAABsGAAANAAAAYXNzZXJ0aW9uIGZhaWxlZDogb2xkX3JpZ2h0X2xlbiA+PSBjb3VudMAEEABbAAAAHAYAAA0AAADABBAAWwAAAEwGAAAWAAAAYXNzZXJ0aW9uIGZhaWxlZDogbWF0Y2ggdHJhY2tfZWRnZV9pZHggewogICAgTGVmdE9yUmlnaHQ6OkxlZnQoaWR4KSA9PiBpZHggPD0gb2xkX2xlZnRfbGVuLAogICAgTGVmdE9yUmlnaHQ6OlJpZ2h0KGlkeCkgPT4gaWR4IDw9IHJpZ2h0X2xlbiwKfQAAwAQQAFsAAACuBQAACQAAAGFzc2VydGlvbiBmYWlsZWQ6IG5ld19sZWZ0X2xlbiA8PSBDQVBBQ0lUWQAAwAQQAFsAAABhBQAACQAAAGNhcGFjaXR5IG92ZXJmbG93AAAApAgQABEAAAAvcnVzdGMvM2U5YmQ4YjU2NmE0N2M1ZDFjMWRiYzdlMDQzYjRiN2ZhNTMzMGVjYS9saWJyYXJ5L2FsbG9jL3NyYy92ZWMvc3BlY19mcm9tX2l0ZXJfbmVzdGVkLnJzAADACBAAXgAAADkAAAASAAAAL3J1c3RjLzNlOWJkOGI1NjZhNDdjNWQxYzFkYmM3ZTA0M2I0YjdmYTUzMzBlY2EvbGlicmFyeS9hbGxvYy9zcmMvY29sbGVjdGlvbnMvYnRyZWUvbWFwL2VudHJ5LnJzMAkQAGAAAAA1AgAAKgAAAC9ydXN0Yy8zZTliZDhiNTY2YTQ3YzVkMWMxZGJjN2UwNDNiNGI3ZmE1MzMwZWNhL2xpYnJhcnkvYWxsb2Mvc3JjL3ZlYy9tb2QucnOgCRAATAAAAEAMAAANAAAAAAAAAAQAAAAEAAAAHQAAAHNyYy9tZW0ucnMAAAwKEAAKAAAANwAAABcAAAAMChAACgAAAIYAAAARAAAADAoQAAoAAACtAAAAEQAAAENlbGwgbm90IGZvdW5kAABIChAADgAAAAwKEAAKAAAA1AAAABEAAAAMChAACgAAAPMAAAANAAAARXhlY3V0ZToge31TZXQgZW52aXJvbm1lbnQ6IIsKEAARAAAAT24gZGVwbG95OiB7fU1lbSBzaXplOg=="); -} -function wasm2js_trap() { throw new Error('abort'); } +module.exports = loadWebAssembly -function asmFunc(imports) { - var buffer = new ArrayBuffer(1114112); - var HEAP8 = new Int8Array(buffer); - var HEAP16 = new Int16Array(buffer); - var HEAP32 = new Int32Array(buffer); - var HEAPU8 = new Uint8Array(buffer); - var HEAPU16 = new Uint16Array(buffer); - var HEAPU32 = new Uint32Array(buffer); - var HEAPF32 = new Float32Array(buffer); - var HEAPF64 = new Float64Array(buffer); - var Math_imul = Math.imul; - var Math_fround = Math.fround; - var Math_abs = Math.abs; - var Math_clz32 = Math.clz32; - var Math_min = Math.min; - var Math_max = Math.max; - var Math_floor = Math.floor; - var Math_ceil = Math.ceil; - var Math_trunc = Math.trunc; - var Math_sqrt = Math.sqrt; - var env = imports.env; - var _ZN12rust_runtime3mem3log17hfd3cd80676177765E = env.log; - var __stack_pointer = 1048576; - var global$1 = 1051820; - var global$2 = 1051824; - var __wasm_intrinsics_temp_i64 = 0; - var __wasm_intrinsics_temp_i64$hi = 0; - var i64toi32_i32$HIGH_BITS = 0; - function __rust_alloc($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - return __rdl_alloc($0 | 0, $1 | 0) | 0 | 0; - } - - function __rust_dealloc($0, $1, $2) { - $0 = $0 | 0; - $1 = $1 | 0; - $2 = $2 | 0; - __rdl_dealloc($0 | 0, $1 | 0, $2 | 0); - return; - } - - function __rust_realloc($0, $1, $2, $3) { - $0 = $0 | 0; - $1 = $1 | 0; - $2 = $2 | 0; - $3 = $3 | 0; - return __rdl_realloc($0 | 0, $1 | 0, $2 | 0, $3 | 0) | 0 | 0; - } - - function __rust_alloc_error_handler($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - __rg_oom($0 | 0, $1 | 0); - return; - } - - function _ZN36_$LT$T$u20$as$u20$core__any__Any$GT$7type_id17h1116370b49193673E($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - var i64toi32_i32$1 = 0, i64toi32_i32$0 = 0; - i64toi32_i32$1 = $0; - i64toi32_i32$0 = 1676365868; - HEAP32[(i64toi32_i32$1 + 8 | 0) >> 2] = -691315347; - HEAP32[(i64toi32_i32$1 + 12 | 0) >> 2] = i64toi32_i32$0; - i64toi32_i32$0 = -1182065807; - HEAP32[i64toi32_i32$1 >> 2] = 1470513528; - HEAP32[(i64toi32_i32$1 + 4 | 0) >> 2] = i64toi32_i32$0; - } - - function _ZN36_$LT$T$u20$as$u20$core__any__Any$GT$7type_id17h698f49bbed3b63dfE($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - var i64toi32_i32$1 = 0, i64toi32_i32$0 = 0; - i64toi32_i32$1 = $0; - i64toi32_i32$0 = 2063459409; - HEAP32[(i64toi32_i32$1 + 8 | 0) >> 2] = 2100447575; - HEAP32[(i64toi32_i32$1 + 12 | 0) >> 2] = i64toi32_i32$0; - i64toi32_i32$0 = -718796931; - HEAP32[i64toi32_i32$1 >> 2] = -1437107046; - HEAP32[(i64toi32_i32$1 + 4 | 0) >> 2] = i64toi32_i32$0; - } - - function _ZN5alloc7raw_vec19RawVec$LT$T$C$A$GT$7reserve21do_reserve_and_handle17h5e9daeeab98ea459E($0, $1, $2) { - $0 = $0 | 0; - $1 = $1 | 0; - $2 = $2 | 0; - var $3 = 0, $4 = 0; - $3 = __stack_pointer - 32 | 0; - __stack_pointer = $3; - label$1 : { - $2 = $1 + $2 | 0; - if ($2 >>> 0 >= $1 >>> 0) { - break label$1 - } - _ZN5alloc7raw_vec12handle_error17h7f22430f64ae98acE(0 | 0, 0 | 0); - wasm2js_trap(); - } - $4 = HEAP32[$0 >> 2] | 0; - $1 = $4 << 1 | 0; - $1 = $1 >>> 0 > $2 >>> 0 ? $1 : $2; - $1 = $1 >>> 0 > 8 >>> 0 ? $1 : 8; - $2 = ($1 ^ -1 | 0) >>> 31 | 0; - label$2 : { - label$3 : { - if ($4) { - break label$3 - } - $4 = 0; - break label$2; - } - HEAP32[($3 + 28 | 0) >> 2] = $4; - HEAP32[($3 + 20 | 0) >> 2] = HEAP32[($0 + 4 | 0) >> 2] | 0; - $4 = 1; - } - HEAP32[($3 + 24 | 0) >> 2] = $4; - _ZN5alloc7raw_vec11finish_grow17ha2d904593814b148E($3 + 8 | 0 | 0, $2 | 0, $1 | 0, $3 + 20 | 0 | 0); - label$4 : { - if ((HEAP32[($3 + 8 | 0) >> 2] | 0 | 0) != (1 | 0)) { - break label$4 - } - _ZN5alloc7raw_vec12handle_error17h7f22430f64ae98acE(HEAP32[($3 + 12 | 0) >> 2] | 0 | 0, HEAP32[($3 + 16 | 0) >> 2] | 0 | 0); - wasm2js_trap(); - } - $2 = HEAP32[($3 + 12 | 0) >> 2] | 0; - HEAP32[$0 >> 2] = $1; - HEAP32[($0 + 4 | 0) >> 2] = $2; - __stack_pointer = $3 + 32 | 0; - } - - function _ZN4core3fmt5Write9write_fmt17h44df5905957d3a1fE($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - return _ZN4core3fmt5write17hd273a061a774381dE($0 | 0, 1048576 | 0, $1 | 0) | 0 | 0; - } - - function _ZN4core3ptr42drop_in_place$LT$alloc__string__String$GT$17hb5bccdeece555eeeE($0) { - $0 = $0 | 0; - var $1 = 0; - label$1 : { - $1 = HEAP32[$0 >> 2] | 0; - if (!$1) { - break label$1 - } - __rust_dealloc(HEAP32[($0 + 4 | 0) >> 2] | 0 | 0, $1 | 0, 1 | 0); - } - } - - function _ZN4core3ptr77drop_in_place$LT$std__panicking__begin_panic_handler__FormatStringPayload$GT$17hec524af3f69d5a53E($0) { - $0 = $0 | 0; - var $1 = 0; - label$1 : { - $1 = HEAP32[$0 >> 2] | 0; - if (($1 | -2147483648 | 0 | 0) == (-2147483648 | 0)) { - break label$1 - } - __rust_dealloc(HEAP32[($0 + 4 | 0) >> 2] | 0 | 0, $1 | 0, 1 | 0); - } - } - - function _ZN4core5panic12PanicPayload6as_str17hd887f5dc9940e8f0E($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - HEAP32[$0 >> 2] = 0; - } - - function _ZN58_$LT$alloc__string__String$u20$as$u20$core__fmt__Write$GT$10write_char17h9231f70fbd335441E($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - var $2 = 0, $3 = 0; - $2 = __stack_pointer - 16 | 0; - __stack_pointer = $2; - label$1 : { - label$2 : { - label$3 : { - label$4 : { - if ($1 >>> 0 < 128 >>> 0) { - break label$4 - } - HEAP32[($2 + 12 | 0) >> 2] = 0; - if ($1 >>> 0 < 2048 >>> 0) { - break label$3 - } - label$5 : { - if ($1 >>> 0 >= 65536 >>> 0) { - break label$5 - } - HEAP8[($2 + 14 | 0) >> 0] = $1 & 63 | 0 | 128 | 0; - HEAP8[($2 + 12 | 0) >> 0] = $1 >>> 12 | 0 | 224 | 0; - HEAP8[($2 + 13 | 0) >> 0] = ($1 >>> 6 | 0) & 63 | 0 | 128 | 0; - $1 = 3; - break label$2; - } - HEAP8[($2 + 15 | 0) >> 0] = $1 & 63 | 0 | 128 | 0; - HEAP8[($2 + 12 | 0) >> 0] = $1 >>> 18 | 0 | 240 | 0; - HEAP8[($2 + 14 | 0) >> 0] = ($1 >>> 6 | 0) & 63 | 0 | 128 | 0; - HEAP8[($2 + 13 | 0) >> 0] = ($1 >>> 12 | 0) & 63 | 0 | 128 | 0; - $1 = 4; - break label$2; - } - label$6 : { - $3 = HEAP32[($0 + 8 | 0) >> 2] | 0; - if (($3 | 0) != (HEAP32[$0 >> 2] | 0 | 0)) { - break label$6 - } - _ZN5alloc7raw_vec19RawVec$LT$T$C$A$GT$8grow_one17hcf301c28e3aef7c4E($0 | 0); - } - HEAP32[($0 + 8 | 0) >> 2] = $3 + 1 | 0; - HEAP8[((HEAP32[($0 + 4 | 0) >> 2] | 0) + $3 | 0) >> 0] = $1; - break label$1; - } - HEAP8[($2 + 13 | 0) >> 0] = $1 & 63 | 0 | 128 | 0; - HEAP8[($2 + 12 | 0) >> 0] = $1 >>> 6 | 0 | 192 | 0; - $1 = 2; - } - label$7 : { - $3 = HEAP32[($0 + 8 | 0) >> 2] | 0; - if (((HEAP32[$0 >> 2] | 0) - $3 | 0) >>> 0 >= $1 >>> 0) { - break label$7 - } - _ZN5alloc7raw_vec19RawVec$LT$T$C$A$GT$7reserve21do_reserve_and_handle17h5e9daeeab98ea459E($0 | 0, $3 | 0, $1 | 0); - $3 = HEAP32[($0 + 8 | 0) >> 2] | 0; - } - memcpy((HEAP32[($0 + 4 | 0) >> 2] | 0) + $3 | 0 | 0, $2 + 12 | 0 | 0, $1 | 0) | 0; - HEAP32[($0 + 8 | 0) >> 2] = $3 + $1 | 0; - } - __stack_pointer = $2 + 16 | 0; - return 0 | 0; - } - - function _ZN5alloc7raw_vec19RawVec$LT$T$C$A$GT$8grow_one17hcf301c28e3aef7c4E($0) { - $0 = $0 | 0; - var $1 = 0, $2 = 0, $3 = 0, $4 = 0; - $1 = __stack_pointer - 32 | 0; - __stack_pointer = $1; - label$1 : { - $2 = HEAP32[$0 >> 2] | 0; - if (($2 | 0) != (-1 | 0)) { - break label$1 - } - _ZN5alloc7raw_vec12handle_error17h7f22430f64ae98acE(0 | 0, 0 | 0); - wasm2js_trap(); - } - $3 = $2 << 1 | 0; - $4 = $2 + 1 | 0; - $3 = $3 >>> 0 > $4 >>> 0 ? $3 : $4; - $3 = $3 >>> 0 > 8 >>> 0 ? $3 : 8; - $4 = ($3 ^ -1 | 0) >>> 31 | 0; - label$2 : { - label$3 : { - if ($2) { - break label$3 - } - $2 = 0; - break label$2; - } - HEAP32[($1 + 28 | 0) >> 2] = $2; - HEAP32[($1 + 20 | 0) >> 2] = HEAP32[($0 + 4 | 0) >> 2] | 0; - $2 = 1; - } - HEAP32[($1 + 24 | 0) >> 2] = $2; - _ZN5alloc7raw_vec11finish_grow17ha2d904593814b148E($1 + 8 | 0 | 0, $4 | 0, $3 | 0, $1 + 20 | 0 | 0); - label$4 : { - if ((HEAP32[($1 + 8 | 0) >> 2] | 0 | 0) != (1 | 0)) { - break label$4 - } - _ZN5alloc7raw_vec12handle_error17h7f22430f64ae98acE(HEAP32[($1 + 12 | 0) >> 2] | 0 | 0, HEAP32[($1 + 16 | 0) >> 2] | 0 | 0); - wasm2js_trap(); - } - $2 = HEAP32[($1 + 12 | 0) >> 2] | 0; - HEAP32[$0 >> 2] = $3; - HEAP32[($0 + 4 | 0) >> 2] = $2; - __stack_pointer = $1 + 32 | 0; - } - - function _ZN58_$LT$alloc__string__String$u20$as$u20$core__fmt__Write$GT$9write_str17h9c2d3e9aafc08637E($0, $1, $2) { - $0 = $0 | 0; - $1 = $1 | 0; - $2 = $2 | 0; - var $3 = 0; - label$1 : { - $3 = HEAP32[($0 + 8 | 0) >> 2] | 0; - if (((HEAP32[$0 >> 2] | 0) - $3 | 0) >>> 0 >= $2 >>> 0) { - break label$1 - } - _ZN5alloc7raw_vec19RawVec$LT$T$C$A$GT$7reserve21do_reserve_and_handle17h5e9daeeab98ea459E($0 | 0, $3 | 0, $2 | 0); - $3 = HEAP32[($0 + 8 | 0) >> 2] | 0; - } - memcpy((HEAP32[($0 + 4 | 0) >> 2] | 0) + $3 | 0 | 0, $1 | 0, $2 | 0) | 0; - HEAP32[($0 + 8 | 0) >> 2] = $3 + $2 | 0; - return 0 | 0; - } - - function _ZN5alloc7raw_vec11finish_grow17ha2d904593814b148E($0, $1, $2, $3) { - $0 = $0 | 0; - $1 = $1 | 0; - $2 = $2 | 0; - $3 = $3 | 0; - var $4 = 0; - label$1 : { - label$2 : { - label$3 : { - if (!$1) { - break label$3 - } - if (($2 | 0) <= (-1 | 0)) { - break label$2 - } - label$4 : { - label$5 : { - label$6 : { - if (!(HEAP32[($3 + 4 | 0) >> 2] | 0)) { - break label$6 - } - label$7 : { - $4 = HEAP32[($3 + 8 | 0) >> 2] | 0; - if ($4) { - break label$7 - } - label$8 : { - if ($2) { - break label$8 - } - $3 = $1; - break label$4; - } - HEAPU8[(0 + 1051325 | 0) >> 0] | 0; - break label$5; - } - $3 = __rust_realloc(HEAP32[$3 >> 2] | 0 | 0, $4 | 0, $1 | 0, $2 | 0) | 0; - break label$4; - } - label$9 : { - if ($2) { - break label$9 - } - $3 = $1; - break label$4; - } - HEAPU8[(0 + 1051325 | 0) >> 0] | 0; - } - $3 = __rust_alloc($2 | 0, $1 | 0) | 0; - } - label$10 : { - if (!$3) { - break label$10 - } - HEAP32[($0 + 8 | 0) >> 2] = $2; - HEAP32[($0 + 4 | 0) >> 2] = $3; - HEAP32[$0 >> 2] = 0; - return; - } - HEAP32[($0 + 8 | 0) >> 2] = $2; - HEAP32[($0 + 4 | 0) >> 2] = $1; - break label$1; - } - HEAP32[($0 + 4 | 0) >> 2] = 0; - break label$1; - } - HEAP32[($0 + 4 | 0) >> 2] = 0; - } - HEAP32[$0 >> 2] = 1; - } - - function _ZN8dlmalloc8dlmalloc17Dlmalloc$LT$A$GT$12unlink_chunk17h20421146e3e4e9ccE($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - var $2 = 0, $4 = 0, $3 = 0, $5 = 0, wasm2js_i32$0 = 0, wasm2js_i32$1 = 0; - $2 = HEAP32[($0 + 12 | 0) >> 2] | 0; - label$1 : { - label$2 : { - label$3 : { - if ($1 >>> 0 < 256 >>> 0) { - break label$3 - } - $3 = HEAP32[($0 + 24 | 0) >> 2] | 0; - label$4 : { - label$5 : { - label$6 : { - if (($2 | 0) != ($0 | 0)) { - break label$6 - } - $2 = HEAP32[($0 + 20 | 0) >> 2] | 0; - $1 = HEAP32[($0 + ($2 ? 20 : 16) | 0) >> 2] | 0; - if ($1) { - break label$5 - } - $2 = 0; - break label$4; - } - $1 = HEAP32[($0 + 8 | 0) >> 2] | 0; - HEAP32[($1 + 12 | 0) >> 2] = $2; - HEAP32[($2 + 8 | 0) >> 2] = $1; - break label$4; - } - $4 = $2 ? $0 + 20 | 0 : $0 + 16 | 0; - label$7 : while (1) { - $5 = $4; - $2 = $1; - $1 = HEAP32[($2 + 20 | 0) >> 2] | 0; - $4 = $1 ? $2 + 20 | 0 : $2 + 16 | 0; - $1 = HEAP32[($2 + ($1 ? 20 : 16) | 0) >> 2] | 0; - if ($1) { - continue label$7 - } - break label$7; - }; - HEAP32[$5 >> 2] = 0; - } - if (!$3) { - break label$1 - } - label$8 : { - $1 = ((HEAP32[($0 + 28 | 0) >> 2] | 0) << 2 | 0) + 1051348 | 0; - if ((HEAP32[$1 >> 2] | 0 | 0) == ($0 | 0)) { - break label$8 - } - HEAP32[($3 + ((HEAP32[($3 + 16 | 0) >> 2] | 0 | 0) == ($0 | 0) ? 16 : 20) | 0) >> 2] = $2; - if (!$2) { - break label$1 - } - break label$2; - } - HEAP32[$1 >> 2] = $2; - if ($2) { - break label$2 - } - (wasm2js_i32$0 = 0, wasm2js_i32$1 = (HEAP32[(0 + 1051760 | 0) >> 2] | 0) & (__wasm_rotl_i32(-2 | 0, HEAP32[($0 + 28 | 0) >> 2] | 0 | 0) | 0) | 0), HEAP32[(wasm2js_i32$0 + 1051760 | 0) >> 2] = wasm2js_i32$1; - break label$1; - } - label$9 : { - $4 = HEAP32[($0 + 8 | 0) >> 2] | 0; - if (($2 | 0) == ($4 | 0)) { - break label$9 - } - HEAP32[($4 + 12 | 0) >> 2] = $2; - HEAP32[($2 + 8 | 0) >> 2] = $4; - return; - } - (wasm2js_i32$0 = 0, wasm2js_i32$1 = (HEAP32[(0 + 1051756 | 0) >> 2] | 0) & (__wasm_rotl_i32(-2 | 0, $1 >>> 3 | 0 | 0) | 0) | 0), HEAP32[(wasm2js_i32$0 + 1051756 | 0) >> 2] = wasm2js_i32$1; - return; - } - HEAP32[($2 + 24 | 0) >> 2] = $3; - label$10 : { - $1 = HEAP32[($0 + 16 | 0) >> 2] | 0; - if (!$1) { - break label$10 - } - HEAP32[($2 + 16 | 0) >> 2] = $1; - HEAP32[($1 + 24 | 0) >> 2] = $2; - } - $1 = HEAP32[($0 + 20 | 0) >> 2] | 0; - if (!$1) { - break label$1 - } - HEAP32[($2 + 20 | 0) >> 2] = $1; - HEAP32[($1 + 24 | 0) >> 2] = $2; - return; - } - } - - function _ZN8dlmalloc8dlmalloc17Dlmalloc$LT$A$GT$13dispose_chunk17hb68dd003b737d09cE($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - var $3 = 0, $2 = 0; - $2 = $0 + $1 | 0; - label$1 : { - label$2 : { - $3 = HEAP32[($0 + 4 | 0) >> 2] | 0; - if ($3 & 1 | 0) { - break label$2 - } - if (!($3 & 2 | 0)) { - break label$1 - } - $3 = HEAP32[$0 >> 2] | 0; - $1 = $3 + $1 | 0; - label$3 : { - $0 = $0 - $3 | 0; - if (($0 | 0) != (HEAP32[(0 + 1051772 | 0) >> 2] | 0 | 0)) { - break label$3 - } - if (((HEAP32[($2 + 4 | 0) >> 2] | 0) & 3 | 0 | 0) != (3 | 0)) { - break label$2 - } - HEAP32[(0 + 1051764 | 0) >> 2] = $1; - HEAP32[($2 + 4 | 0) >> 2] = (HEAP32[($2 + 4 | 0) >> 2] | 0) & -2 | 0; - HEAP32[($0 + 4 | 0) >> 2] = $1 | 1 | 0; - HEAP32[$2 >> 2] = $1; - break label$1; - } - _ZN8dlmalloc8dlmalloc17Dlmalloc$LT$A$GT$12unlink_chunk17h20421146e3e4e9ccE($0 | 0, $3 | 0); - } - label$4 : { - label$5 : { - label$6 : { - label$7 : { - $3 = HEAP32[($2 + 4 | 0) >> 2] | 0; - if ($3 & 2 | 0) { - break label$7 - } - if (($2 | 0) == (HEAP32[(0 + 1051776 | 0) >> 2] | 0 | 0)) { - break label$5 - } - if (($2 | 0) == (HEAP32[(0 + 1051772 | 0) >> 2] | 0 | 0)) { - break label$4 - } - $3 = $3 & -8 | 0; - _ZN8dlmalloc8dlmalloc17Dlmalloc$LT$A$GT$12unlink_chunk17h20421146e3e4e9ccE($2 | 0, $3 | 0); - $1 = $3 + $1 | 0; - HEAP32[($0 + 4 | 0) >> 2] = $1 | 1 | 0; - HEAP32[($0 + $1 | 0) >> 2] = $1; - if (($0 | 0) != (HEAP32[(0 + 1051772 | 0) >> 2] | 0 | 0)) { - break label$6 - } - HEAP32[(0 + 1051764 | 0) >> 2] = $1; - return; - } - HEAP32[($2 + 4 | 0) >> 2] = $3 & -2 | 0; - HEAP32[($0 + 4 | 0) >> 2] = $1 | 1 | 0; - HEAP32[($0 + $1 | 0) >> 2] = $1; - } - label$8 : { - if ($1 >>> 0 < 256 >>> 0) { - break label$8 - } - _ZN8dlmalloc8dlmalloc17Dlmalloc$LT$A$GT$18insert_large_chunk17h8e4702b854476b2fE($0 | 0, $1 | 0); - return; - } - $2 = ($1 & 248 | 0) + 1051492 | 0; - label$9 : { - label$10 : { - $3 = HEAP32[(0 + 1051756 | 0) >> 2] | 0; - $1 = 1 << ($1 >>> 3 | 0) | 0; - if ($3 & $1 | 0) { - break label$10 - } - HEAP32[(0 + 1051756 | 0) >> 2] = $3 | $1 | 0; - $1 = $2; - break label$9; - } - $1 = HEAP32[($2 + 8 | 0) >> 2] | 0; - } - HEAP32[($2 + 8 | 0) >> 2] = $0; - HEAP32[($1 + 12 | 0) >> 2] = $0; - HEAP32[($0 + 12 | 0) >> 2] = $2; - HEAP32[($0 + 8 | 0) >> 2] = $1; - return; - } - HEAP32[(0 + 1051776 | 0) >> 2] = $0; - $1 = (HEAP32[(0 + 1051768 | 0) >> 2] | 0) + $1 | 0; - HEAP32[(0 + 1051768 | 0) >> 2] = $1; - HEAP32[($0 + 4 | 0) >> 2] = $1 | 1 | 0; - if (($0 | 0) != (HEAP32[(0 + 1051772 | 0) >> 2] | 0 | 0)) { - break label$1 - } - HEAP32[(0 + 1051764 | 0) >> 2] = 0; - HEAP32[(0 + 1051772 | 0) >> 2] = 0; - return; - } - HEAP32[(0 + 1051772 | 0) >> 2] = $0; - $1 = (HEAP32[(0 + 1051764 | 0) >> 2] | 0) + $1 | 0; - HEAP32[(0 + 1051764 | 0) >> 2] = $1; - HEAP32[($0 + 4 | 0) >> 2] = $1 | 1 | 0; - HEAP32[($0 + $1 | 0) >> 2] = $1; - return; - } - } - - function _ZN8dlmalloc8dlmalloc17Dlmalloc$LT$A$GT$18insert_large_chunk17h8e4702b854476b2fE($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - var $2 = 0, $3 = 0, $4 = 0, $5 = 0; - $2 = 0; - label$1 : { - if ($1 >>> 0 < 256 >>> 0) { - break label$1 - } - $2 = 31; - if ($1 >>> 0 > 16777215 >>> 0) { - break label$1 - } - $2 = Math_clz32($1 >>> 8 | 0); - $2 = ((($1 >>> (6 - $2 | 0) | 0) & 1 | 0) - ($2 << 1 | 0) | 0) + 62 | 0; - } - HEAP32[($0 + 16 | 0) >> 2] = 0; - HEAP32[($0 + 20 | 0) >> 2] = 0; - HEAP32[($0 + 28 | 0) >> 2] = $2; - $3 = ($2 << 2 | 0) + 1051348 | 0; - label$2 : { - $4 = 1 << $2 | 0; - if ((HEAP32[(0 + 1051760 | 0) >> 2] | 0) & $4 | 0) { - break label$2 - } - HEAP32[$3 >> 2] = $0; - HEAP32[($0 + 24 | 0) >> 2] = $3; - HEAP32[($0 + 12 | 0) >> 2] = $0; - HEAP32[($0 + 8 | 0) >> 2] = $0; - HEAP32[(0 + 1051760 | 0) >> 2] = HEAP32[(0 + 1051760 | 0) >> 2] | 0 | $4 | 0; - return; - } - label$3 : { - label$4 : { - label$5 : { - $4 = HEAP32[$3 >> 2] | 0; - if (((HEAP32[($4 + 4 | 0) >> 2] | 0) & -8 | 0 | 0) != ($1 | 0)) { - break label$5 - } - $2 = $4; - break label$4; - } - $3 = $1 << (($2 | 0) == (31 | 0) ? 0 : 25 - ($2 >>> 1 | 0) | 0) | 0; - label$6 : while (1) { - $5 = ($4 + (($3 >>> 29 | 0) & 4 | 0) | 0) + 16 | 0; - $2 = HEAP32[$5 >> 2] | 0; - if (!$2) { - break label$3 - } - $3 = $3 << 1 | 0; - $4 = $2; - if (((HEAP32[($2 + 4 | 0) >> 2] | 0) & -8 | 0 | 0) != ($1 | 0)) { - continue label$6 - } - break label$6; - }; - } - $3 = HEAP32[($2 + 8 | 0) >> 2] | 0; - HEAP32[($3 + 12 | 0) >> 2] = $0; - HEAP32[($2 + 8 | 0) >> 2] = $0; - HEAP32[($0 + 24 | 0) >> 2] = 0; - HEAP32[($0 + 12 | 0) >> 2] = $2; - HEAP32[($0 + 8 | 0) >> 2] = $3; - return; - } - HEAP32[$5 >> 2] = $0; - HEAP32[($0 + 24 | 0) >> 2] = $4; - HEAP32[($0 + 12 | 0) >> 2] = $0; - HEAP32[($0 + 8 | 0) >> 2] = $0; - } - - function _ZN8dlmalloc8dlmalloc17Dlmalloc$LT$A$GT$4free17hcade36dd23206a7bE($0) { - $0 = $0 | 0; - var $1 = 0, $2 = 0, $3 = 0, $4 = 0, $5 = 0; - $1 = $0 + -8 | 0; - $2 = HEAP32[($0 + -4 | 0) >> 2] | 0; - $0 = $2 & -8 | 0; - $3 = $1 + $0 | 0; - label$1 : { - label$2 : { - if ($2 & 1 | 0) { - break label$2 - } - if (!($2 & 2 | 0)) { - break label$1 - } - $2 = HEAP32[$1 >> 2] | 0; - $0 = $2 + $0 | 0; - label$3 : { - $1 = $1 - $2 | 0; - if (($1 | 0) != (HEAP32[(0 + 1051772 | 0) >> 2] | 0 | 0)) { - break label$3 - } - if (((HEAP32[($3 + 4 | 0) >> 2] | 0) & 3 | 0 | 0) != (3 | 0)) { - break label$2 - } - HEAP32[(0 + 1051764 | 0) >> 2] = $0; - HEAP32[($3 + 4 | 0) >> 2] = (HEAP32[($3 + 4 | 0) >> 2] | 0) & -2 | 0; - HEAP32[($1 + 4 | 0) >> 2] = $0 | 1 | 0; - HEAP32[$3 >> 2] = $0; - return; - } - _ZN8dlmalloc8dlmalloc17Dlmalloc$LT$A$GT$12unlink_chunk17h20421146e3e4e9ccE($1 | 0, $2 | 0); - } - label$4 : { - label$5 : { - label$6 : { - label$7 : { - label$8 : { - label$9 : { - $2 = HEAP32[($3 + 4 | 0) >> 2] | 0; - if ($2 & 2 | 0) { - break label$9 - } - if (($3 | 0) == (HEAP32[(0 + 1051776 | 0) >> 2] | 0 | 0)) { - break label$7 - } - if (($3 | 0) == (HEAP32[(0 + 1051772 | 0) >> 2] | 0 | 0)) { - break label$6 - } - $2 = $2 & -8 | 0; - _ZN8dlmalloc8dlmalloc17Dlmalloc$LT$A$GT$12unlink_chunk17h20421146e3e4e9ccE($3 | 0, $2 | 0); - $0 = $2 + $0 | 0; - HEAP32[($1 + 4 | 0) >> 2] = $0 | 1 | 0; - HEAP32[($1 + $0 | 0) >> 2] = $0; - if (($1 | 0) != (HEAP32[(0 + 1051772 | 0) >> 2] | 0 | 0)) { - break label$8 - } - HEAP32[(0 + 1051764 | 0) >> 2] = $0; - return; - } - HEAP32[($3 + 4 | 0) >> 2] = $2 & -2 | 0; - HEAP32[($1 + 4 | 0) >> 2] = $0 | 1 | 0; - HEAP32[($1 + $0 | 0) >> 2] = $0; - } - if ($0 >>> 0 < 256 >>> 0) { - break label$5 - } - _ZN8dlmalloc8dlmalloc17Dlmalloc$LT$A$GT$18insert_large_chunk17h8e4702b854476b2fE($1 | 0, $0 | 0); - $1 = 0; - $0 = (HEAP32[(0 + 1051796 | 0) >> 2] | 0) + -1 | 0; - HEAP32[(0 + 1051796 | 0) >> 2] = $0; - if ($0) { - break label$1 - } - label$10 : { - $0 = HEAP32[(0 + 1051484 | 0) >> 2] | 0; - if (!$0) { - break label$10 - } - $1 = 0; - label$11 : while (1) { - $1 = $1 + 1 | 0; - $0 = HEAP32[($0 + 8 | 0) >> 2] | 0; - if ($0) { - continue label$11 - } - break label$11; - }; - } - HEAP32[(0 + 1051796 | 0) >> 2] = $1 >>> 0 > 4095 >>> 0 ? $1 : 4095; - return; - } - HEAP32[(0 + 1051776 | 0) >> 2] = $1; - $0 = (HEAP32[(0 + 1051768 | 0) >> 2] | 0) + $0 | 0; - HEAP32[(0 + 1051768 | 0) >> 2] = $0; - HEAP32[($1 + 4 | 0) >> 2] = $0 | 1 | 0; - label$12 : { - if (($1 | 0) != (HEAP32[(0 + 1051772 | 0) >> 2] | 0 | 0)) { - break label$12 - } - HEAP32[(0 + 1051764 | 0) >> 2] = 0; - HEAP32[(0 + 1051772 | 0) >> 2] = 0; - } - $4 = HEAP32[(0 + 1051788 | 0) >> 2] | 0; - if ($0 >>> 0 <= $4 >>> 0) { - break label$1 - } - $0 = HEAP32[(0 + 1051776 | 0) >> 2] | 0; - if (!$0) { - break label$1 - } - $2 = 0; - $5 = HEAP32[(0 + 1051768 | 0) >> 2] | 0; - if ($5 >>> 0 < 41 >>> 0) { - break label$4 - } - $1 = 1051476; - label$13 : while (1) { - label$14 : { - $3 = HEAP32[$1 >> 2] | 0; - if ($3 >>> 0 > $0 >>> 0) { - break label$14 - } - if ($0 >>> 0 < ($3 + (HEAP32[($1 + 4 | 0) >> 2] | 0) | 0) >>> 0) { - break label$4 - } - } - $1 = HEAP32[($1 + 8 | 0) >> 2] | 0; - continue label$13; - }; - } - HEAP32[(0 + 1051772 | 0) >> 2] = $1; - $0 = (HEAP32[(0 + 1051764 | 0) >> 2] | 0) + $0 | 0; - HEAP32[(0 + 1051764 | 0) >> 2] = $0; - HEAP32[($1 + 4 | 0) >> 2] = $0 | 1 | 0; - HEAP32[($1 + $0 | 0) >> 2] = $0; - return; - } - $3 = ($0 & 248 | 0) + 1051492 | 0; - label$15 : { - label$16 : { - $2 = HEAP32[(0 + 1051756 | 0) >> 2] | 0; - $0 = 1 << ($0 >>> 3 | 0) | 0; - if ($2 & $0 | 0) { - break label$16 - } - HEAP32[(0 + 1051756 | 0) >> 2] = $2 | $0 | 0; - $0 = $3; - break label$15; - } - $0 = HEAP32[($3 + 8 | 0) >> 2] | 0; - } - HEAP32[($3 + 8 | 0) >> 2] = $1; - HEAP32[($0 + 12 | 0) >> 2] = $1; - HEAP32[($1 + 12 | 0) >> 2] = $3; - HEAP32[($1 + 8 | 0) >> 2] = $0; - return; - } - label$17 : { - $1 = HEAP32[(0 + 1051484 | 0) >> 2] | 0; - if (!$1) { - break label$17 - } - $2 = 0; - label$18 : while (1) { - $2 = $2 + 1 | 0; - $1 = HEAP32[($1 + 8 | 0) >> 2] | 0; - if ($1) { - continue label$18 - } - break label$18; - }; - } - HEAP32[(0 + 1051796 | 0) >> 2] = $2 >>> 0 > 4095 >>> 0 ? $2 : 4095; - if ($5 >>> 0 <= $4 >>> 0) { - break label$1 - } - HEAP32[(0 + 1051788 | 0) >> 2] = -1; - } - } - - function _ZN8dlmalloc8dlmalloc17Dlmalloc$LT$A$GT$6malloc17hd9c2c8577ef4c61dE($0) { - $0 = $0 | 0; - var $7 = 0, $6 = 0, $2 = 0, $3 = 0, $8 = 0, $9 = 0, $5 = 0, $4 = 0, i64toi32_i32$1 = 0, $1 = 0, i64toi32_i32$2 = 0, i64toi32_i32$0 = 0, $247 = 0, $261 = 0, $618 = 0, $693 = 0, $10 = 0, $10$hi = 0, $721 = 0, $928 = 0, wasm2js_i32$0 = 0, wasm2js_i32$1 = 0; - $1 = __stack_pointer - 16 | 0; - __stack_pointer = $1; - label$1 : { - label$2 : { - label$3 : { - label$4 : { - label$5 : { - label$6 : { - label$7 : { - label$8 : { - if ($0 >>> 0 < 245 >>> 0) { - break label$8 - } - label$9 : { - if ($0 >>> 0 < -65587 >>> 0) { - break label$9 - } - $0 = 0; - break label$1; - } - $2 = $0 + 11 | 0; - $3 = $2 & -8 | 0; - $4 = HEAP32[(0 + 1051760 | 0) >> 2] | 0; - if (!$4) { - break label$4 - } - $5 = 31; - label$10 : { - if ($0 >>> 0 > 16777204 >>> 0) { - break label$10 - } - $0 = Math_clz32($2 >>> 8 | 0); - $5 = ((($3 >>> (6 - $0 | 0) | 0) & 1 | 0) - ($0 << 1 | 0) | 0) + 62 | 0; - } - $2 = 0 - $3 | 0; - label$11 : { - $6 = HEAP32[(($5 << 2 | 0) + 1051348 | 0) >> 2] | 0; - if ($6) { - break label$11 - } - $0 = 0; - $7 = 0; - break label$7; - } - $0 = 0; - $8 = $3 << (($5 | 0) == (31 | 0) ? 0 : 25 - ($5 >>> 1 | 0) | 0) | 0; - $7 = 0; - label$12 : while (1) { - label$13 : { - $9 = (HEAP32[($6 + 4 | 0) >> 2] | 0) & -8 | 0; - if ($9 >>> 0 < $3 >>> 0) { - break label$13 - } - $9 = $9 - $3 | 0; - if ($9 >>> 0 >= $2 >>> 0) { - break label$13 - } - $2 = $9; - $7 = $6; - if ($2) { - break label$13 - } - $2 = 0; - $7 = $6; - $0 = $6; - break label$6; - } - $9 = HEAP32[($6 + 20 | 0) >> 2] | 0; - $6 = HEAP32[(($6 + (($8 >>> 29 | 0) & 4 | 0) | 0) + 16 | 0) >> 2] | 0; - $0 = $9 ? (($9 | 0) != ($6 | 0) ? $9 : $0) : $0; - $8 = $8 << 1 | 0; - if (!$6) { - break label$7 - } - continue label$12; - }; - } - label$14 : { - $6 = HEAP32[(0 + 1051756 | 0) >> 2] | 0; - $3 = $0 >>> 0 < 11 >>> 0 ? 16 : ($0 + 11 | 0) & 504 | 0; - $2 = $3 >>> 3 | 0; - $0 = $6 >>> $2 | 0; - if (!($0 & 3 | 0)) { - break label$14 - } - label$15 : { - label$16 : { - $8 = (($0 ^ -1 | 0) & 1 | 0) + $2 | 0; - $3 = $8 << 3 | 0; - $0 = $3 + 1051492 | 0; - $2 = HEAP32[($3 + 1051500 | 0) >> 2] | 0; - $7 = HEAP32[($2 + 8 | 0) >> 2] | 0; - if (($0 | 0) == ($7 | 0)) { - break label$16 - } - HEAP32[($7 + 12 | 0) >> 2] = $0; - HEAP32[($0 + 8 | 0) >> 2] = $7; - break label$15; - } - (wasm2js_i32$0 = 0, wasm2js_i32$1 = $6 & (__wasm_rotl_i32(-2 | 0, $8 | 0) | 0) | 0), HEAP32[(wasm2js_i32$0 + 1051756 | 0) >> 2] = wasm2js_i32$1; - } - $0 = $2 + 8 | 0; - HEAP32[($2 + 4 | 0) >> 2] = $3 | 3 | 0; - $3 = $2 + $3 | 0; - HEAP32[($3 + 4 | 0) >> 2] = HEAP32[($3 + 4 | 0) >> 2] | 0 | 1 | 0; - break label$1; - } - if ($3 >>> 0 <= (HEAP32[(0 + 1051764 | 0) >> 2] | 0) >>> 0) { - break label$4 - } - label$17 : { - label$18 : { - label$19 : { - if ($0) { - break label$19 - } - $0 = HEAP32[(0 + 1051760 | 0) >> 2] | 0; - if (!$0) { - break label$4 - } - $7 = HEAP32[(((__wasm_ctz_i32($0 | 0) | 0) << 2 | 0) + 1051348 | 0) >> 2] | 0; - $2 = ((HEAP32[($7 + 4 | 0) >> 2] | 0) & -8 | 0) - $3 | 0; - $6 = $7; - label$20 : while (1) { - label$21 : { - $0 = HEAP32[($7 + 16 | 0) >> 2] | 0; - if ($0) { - break label$21 - } - $0 = HEAP32[($7 + 20 | 0) >> 2] | 0; - if ($0) { - break label$21 - } - $5 = HEAP32[($6 + 24 | 0) >> 2] | 0; - label$22 : { - label$23 : { - label$24 : { - $0 = HEAP32[($6 + 12 | 0) >> 2] | 0; - if (($0 | 0) != ($6 | 0)) { - break label$24 - } - $0 = HEAP32[($6 + 20 | 0) >> 2] | 0; - $7 = HEAP32[($6 + ($0 ? 20 : 16) | 0) >> 2] | 0; - if ($7) { - break label$23 - } - $0 = 0; - break label$22; - } - $7 = HEAP32[($6 + 8 | 0) >> 2] | 0; - HEAP32[($7 + 12 | 0) >> 2] = $0; - HEAP32[($0 + 8 | 0) >> 2] = $7; - break label$22; - } - $8 = $0 ? $6 + 20 | 0 : $6 + 16 | 0; - label$25 : while (1) { - $9 = $8; - $0 = $7; - $7 = HEAP32[($0 + 20 | 0) >> 2] | 0; - $8 = $7 ? $0 + 20 | 0 : $0 + 16 | 0; - $7 = HEAP32[($0 + ($7 ? 20 : 16) | 0) >> 2] | 0; - if ($7) { - continue label$25 - } - break label$25; - }; - HEAP32[$9 >> 2] = 0; - } - if (!$5) { - break label$17 - } - label$26 : { - $7 = ((HEAP32[($6 + 28 | 0) >> 2] | 0) << 2 | 0) + 1051348 | 0; - if ((HEAP32[$7 >> 2] | 0 | 0) == ($6 | 0)) { - break label$26 - } - HEAP32[($5 + ((HEAP32[($5 + 16 | 0) >> 2] | 0 | 0) == ($6 | 0) ? 16 : 20) | 0) >> 2] = $0; - if (!$0) { - break label$17 - } - break label$18; - } - HEAP32[$7 >> 2] = $0; - if ($0) { - break label$18 - } - (wasm2js_i32$0 = 0, wasm2js_i32$1 = (HEAP32[(0 + 1051760 | 0) >> 2] | 0) & (__wasm_rotl_i32(-2 | 0, HEAP32[($6 + 28 | 0) >> 2] | 0 | 0) | 0) | 0), HEAP32[(wasm2js_i32$0 + 1051760 | 0) >> 2] = wasm2js_i32$1; - break label$17; - } - $7 = ((HEAP32[($0 + 4 | 0) >> 2] | 0) & -8 | 0) - $3 | 0; - $247 = $7; - $7 = $7 >>> 0 < $2 >>> 0; - $2 = $7 ? $247 : $2; - $6 = $7 ? $0 : $6; - $7 = $0; - continue label$20; - }; - } - label$27 : { - label$28 : { - $261 = $0 << $2 | 0; - $0 = 2 << $2 | 0; - $9 = __wasm_ctz_i32($261 & ($0 | (0 - $0 | 0) | 0) | 0 | 0) | 0; - $2 = $9 << 3 | 0; - $7 = $2 + 1051492 | 0; - $0 = HEAP32[($2 + 1051500 | 0) >> 2] | 0; - $8 = HEAP32[($0 + 8 | 0) >> 2] | 0; - if (($7 | 0) == ($8 | 0)) { - break label$28 - } - HEAP32[($8 + 12 | 0) >> 2] = $7; - HEAP32[($7 + 8 | 0) >> 2] = $8; - break label$27; - } - (wasm2js_i32$0 = 0, wasm2js_i32$1 = $6 & (__wasm_rotl_i32(-2 | 0, $9 | 0) | 0) | 0), HEAP32[(wasm2js_i32$0 + 1051756 | 0) >> 2] = wasm2js_i32$1; - } - HEAP32[($0 + 4 | 0) >> 2] = $3 | 3 | 0; - $8 = $0 + $3 | 0; - $7 = $2 - $3 | 0; - HEAP32[($8 + 4 | 0) >> 2] = $7 | 1 | 0; - HEAP32[($0 + $2 | 0) >> 2] = $7; - label$29 : { - $6 = HEAP32[(0 + 1051764 | 0) >> 2] | 0; - if (!$6) { - break label$29 - } - $2 = ($6 & -8 | 0) + 1051492 | 0; - $3 = HEAP32[(0 + 1051772 | 0) >> 2] | 0; - label$30 : { - label$31 : { - $9 = HEAP32[(0 + 1051756 | 0) >> 2] | 0; - $6 = 1 << ($6 >>> 3 | 0) | 0; - if ($9 & $6 | 0) { - break label$31 - } - HEAP32[(0 + 1051756 | 0) >> 2] = $9 | $6 | 0; - $6 = $2; - break label$30; - } - $6 = HEAP32[($2 + 8 | 0) >> 2] | 0; - } - HEAP32[($2 + 8 | 0) >> 2] = $3; - HEAP32[($6 + 12 | 0) >> 2] = $3; - HEAP32[($3 + 12 | 0) >> 2] = $2; - HEAP32[($3 + 8 | 0) >> 2] = $6; - } - $0 = $0 + 8 | 0; - HEAP32[(0 + 1051772 | 0) >> 2] = $8; - HEAP32[(0 + 1051764 | 0) >> 2] = $7; - break label$1; - } - HEAP32[($0 + 24 | 0) >> 2] = $5; - label$32 : { - $7 = HEAP32[($6 + 16 | 0) >> 2] | 0; - if (!$7) { - break label$32 - } - HEAP32[($0 + 16 | 0) >> 2] = $7; - HEAP32[($7 + 24 | 0) >> 2] = $0; - } - $7 = HEAP32[($6 + 20 | 0) >> 2] | 0; - if (!$7) { - break label$17 - } - HEAP32[($0 + 20 | 0) >> 2] = $7; - HEAP32[($7 + 24 | 0) >> 2] = $0; - } - label$33 : { - label$34 : { - label$35 : { - if ($2 >>> 0 < 16 >>> 0) { - break label$35 - } - HEAP32[($6 + 4 | 0) >> 2] = $3 | 3 | 0; - $3 = $6 + $3 | 0; - HEAP32[($3 + 4 | 0) >> 2] = $2 | 1 | 0; - HEAP32[($3 + $2 | 0) >> 2] = $2; - $8 = HEAP32[(0 + 1051764 | 0) >> 2] | 0; - if (!$8) { - break label$34 - } - $7 = ($8 & -8 | 0) + 1051492 | 0; - $0 = HEAP32[(0 + 1051772 | 0) >> 2] | 0; - label$36 : { - label$37 : { - $9 = HEAP32[(0 + 1051756 | 0) >> 2] | 0; - $8 = 1 << ($8 >>> 3 | 0) | 0; - if ($9 & $8 | 0) { - break label$37 - } - HEAP32[(0 + 1051756 | 0) >> 2] = $9 | $8 | 0; - $8 = $7; - break label$36; - } - $8 = HEAP32[($7 + 8 | 0) >> 2] | 0; - } - HEAP32[($7 + 8 | 0) >> 2] = $0; - HEAP32[($8 + 12 | 0) >> 2] = $0; - HEAP32[($0 + 12 | 0) >> 2] = $7; - HEAP32[($0 + 8 | 0) >> 2] = $8; - break label$34; - } - $0 = $2 + $3 | 0; - HEAP32[($6 + 4 | 0) >> 2] = $0 | 3 | 0; - $0 = $6 + $0 | 0; - HEAP32[($0 + 4 | 0) >> 2] = HEAP32[($0 + 4 | 0) >> 2] | 0 | 1 | 0; - break label$33; - } - HEAP32[(0 + 1051772 | 0) >> 2] = $3; - HEAP32[(0 + 1051764 | 0) >> 2] = $2; - } - $0 = $6 + 8 | 0; - break label$1; - } - label$38 : { - if ($0 | $7 | 0) { - break label$38 - } - $7 = 0; - $0 = 2 << $5 | 0; - $0 = ($0 | (0 - $0 | 0) | 0) & $4 | 0; - if (!$0) { - break label$4 - } - $0 = HEAP32[(((__wasm_ctz_i32($0 | 0) | 0) << 2 | 0) + 1051348 | 0) >> 2] | 0; - } - if (!$0) { - break label$5 - } - } - label$39 : while (1) { - $6 = (HEAP32[($0 + 4 | 0) >> 2] | 0) & -8 | 0; - $9 = $6 - $3 | 0; - $5 = $9 >>> 0 < $2 >>> 0; - $4 = $5 ? $0 : $7; - $8 = $6 >>> 0 < $3 >>> 0; - $9 = $5 ? $9 : $2; - label$40 : { - $6 = HEAP32[($0 + 16 | 0) >> 2] | 0; - if ($6) { - break label$40 - } - $6 = HEAP32[($0 + 20 | 0) >> 2] | 0; - } - $7 = $8 ? $7 : $4; - $2 = $8 ? $2 : $9; - $0 = $6; - if ($0) { - continue label$39 - } - break label$39; - }; - } - if (!$7) { - break label$4 - } - label$41 : { - $0 = HEAP32[(0 + 1051764 | 0) >> 2] | 0; - if ($0 >>> 0 < $3 >>> 0) { - break label$41 - } - if ($2 >>> 0 >= ($0 - $3 | 0) >>> 0) { - break label$4 - } - } - $5 = HEAP32[($7 + 24 | 0) >> 2] | 0; - label$42 : { - label$43 : { - label$44 : { - $0 = HEAP32[($7 + 12 | 0) >> 2] | 0; - if (($0 | 0) != ($7 | 0)) { - break label$44 - } - $0 = HEAP32[($7 + 20 | 0) >> 2] | 0; - $6 = HEAP32[($7 + ($0 ? 20 : 16) | 0) >> 2] | 0; - if ($6) { - break label$43 - } - $0 = 0; - break label$42; - } - $6 = HEAP32[($7 + 8 | 0) >> 2] | 0; - HEAP32[($6 + 12 | 0) >> 2] = $0; - HEAP32[($0 + 8 | 0) >> 2] = $6; - break label$42; - } - $8 = $0 ? $7 + 20 | 0 : $7 + 16 | 0; - label$45 : while (1) { - $9 = $8; - $0 = $6; - $6 = HEAP32[($0 + 20 | 0) >> 2] | 0; - $8 = $6 ? $0 + 20 | 0 : $0 + 16 | 0; - $6 = HEAP32[($0 + ($6 ? 20 : 16) | 0) >> 2] | 0; - if ($6) { - continue label$45 - } - break label$45; - }; - HEAP32[$9 >> 2] = 0; - } - if (!$5) { - break label$2 - } - label$46 : { - $6 = ((HEAP32[($7 + 28 | 0) >> 2] | 0) << 2 | 0) + 1051348 | 0; - if ((HEAP32[$6 >> 2] | 0 | 0) == ($7 | 0)) { - break label$46 - } - HEAP32[($5 + ((HEAP32[($5 + 16 | 0) >> 2] | 0 | 0) == ($7 | 0) ? 16 : 20) | 0) >> 2] = $0; - if (!$0) { - break label$2 - } - break label$3; - } - HEAP32[$6 >> 2] = $0; - if ($0) { - break label$3 - } - (wasm2js_i32$0 = 0, wasm2js_i32$1 = (HEAP32[(0 + 1051760 | 0) >> 2] | 0) & (__wasm_rotl_i32(-2 | 0, HEAP32[($7 + 28 | 0) >> 2] | 0 | 0) | 0) | 0), HEAP32[(wasm2js_i32$0 + 1051760 | 0) >> 2] = wasm2js_i32$1; - break label$2; - } - label$47 : { - label$48 : { - label$49 : { - label$50 : { - label$51 : { - label$52 : { - $0 = HEAP32[(0 + 1051764 | 0) >> 2] | 0; - if ($0 >>> 0 >= $3 >>> 0) { - break label$52 - } - label$53 : { - $0 = HEAP32[(0 + 1051768 | 0) >> 2] | 0; - if ($0 >>> 0 > $3 >>> 0) { - break label$53 - } - _ZN61_$LT$dlmalloc__sys__System$u20$as$u20$dlmalloc__Allocator$GT$5alloc17hb2750b8aaf9916efE($1 + 4 | 0 | 0, 1051800 | 0, ($3 + 65583 | 0) & -65536 | 0 | 0); - label$54 : { - $6 = HEAP32[($1 + 4 | 0) >> 2] | 0; - if ($6) { - break label$54 - } - $0 = 0; - break label$1; - } - $5 = HEAP32[($1 + 12 | 0) >> 2] | 0; - $9 = HEAP32[($1 + 8 | 0) >> 2] | 0; - $0 = (HEAP32[(0 + 1051780 | 0) >> 2] | 0) + $9 | 0; - HEAP32[(0 + 1051780 | 0) >> 2] = $0; - $2 = HEAP32[(0 + 1051784 | 0) >> 2] | 0; - HEAP32[(0 + 1051784 | 0) >> 2] = $2 >>> 0 > $0 >>> 0 ? $2 : $0; - label$55 : { - label$56 : { - label$57 : { - $2 = HEAP32[(0 + 1051776 | 0) >> 2] | 0; - if (!$2) { - break label$57 - } - $0 = 1051476; - label$58 : while (1) { - $7 = HEAP32[$0 >> 2] | 0; - $8 = HEAP32[($0 + 4 | 0) >> 2] | 0; - if (($6 | 0) == ($7 + $8 | 0 | 0)) { - break label$56 - } - $0 = HEAP32[($0 + 8 | 0) >> 2] | 0; - if ($0) { - continue label$58 - } - break label$55; - }; - } - label$59 : { - label$60 : { - $0 = HEAP32[(0 + 1051792 | 0) >> 2] | 0; - if (!$0) { - break label$60 - } - if ($6 >>> 0 >= $0 >>> 0) { - break label$59 - } - } - HEAP32[(0 + 1051792 | 0) >> 2] = $6; - } - HEAP32[(0 + 1051796 | 0) >> 2] = 4095; - HEAP32[(0 + 1051488 | 0) >> 2] = $5; - HEAP32[(0 + 1051480 | 0) >> 2] = $9; - HEAP32[(0 + 1051476 | 0) >> 2] = $6; - HEAP32[(0 + 1051504 | 0) >> 2] = 1051492; - HEAP32[(0 + 1051512 | 0) >> 2] = 1051500; - HEAP32[(0 + 1051500 | 0) >> 2] = 1051492; - HEAP32[(0 + 1051520 | 0) >> 2] = 1051508; - HEAP32[(0 + 1051508 | 0) >> 2] = 1051500; - HEAP32[(0 + 1051528 | 0) >> 2] = 1051516; - HEAP32[(0 + 1051516 | 0) >> 2] = 1051508; - HEAP32[(0 + 1051536 | 0) >> 2] = 1051524; - HEAP32[(0 + 1051524 | 0) >> 2] = 1051516; - HEAP32[(0 + 1051544 | 0) >> 2] = 1051532; - HEAP32[(0 + 1051532 | 0) >> 2] = 1051524; - HEAP32[(0 + 1051552 | 0) >> 2] = 1051540; - HEAP32[(0 + 1051540 | 0) >> 2] = 1051532; - HEAP32[(0 + 1051560 | 0) >> 2] = 1051548; - HEAP32[(0 + 1051548 | 0) >> 2] = 1051540; - HEAP32[(0 + 1051568 | 0) >> 2] = 1051556; - HEAP32[(0 + 1051556 | 0) >> 2] = 1051548; - HEAP32[(0 + 1051564 | 0) >> 2] = 1051556; - HEAP32[(0 + 1051576 | 0) >> 2] = 1051564; - HEAP32[(0 + 1051572 | 0) >> 2] = 1051564; - HEAP32[(0 + 1051584 | 0) >> 2] = 1051572; - HEAP32[(0 + 1051580 | 0) >> 2] = 1051572; - HEAP32[(0 + 1051592 | 0) >> 2] = 1051580; - HEAP32[(0 + 1051588 | 0) >> 2] = 1051580; - HEAP32[(0 + 1051600 | 0) >> 2] = 1051588; - HEAP32[(0 + 1051596 | 0) >> 2] = 1051588; - HEAP32[(0 + 1051608 | 0) >> 2] = 1051596; - HEAP32[(0 + 1051604 | 0) >> 2] = 1051596; - HEAP32[(0 + 1051616 | 0) >> 2] = 1051604; - HEAP32[(0 + 1051612 | 0) >> 2] = 1051604; - HEAP32[(0 + 1051624 | 0) >> 2] = 1051612; - HEAP32[(0 + 1051620 | 0) >> 2] = 1051612; - HEAP32[(0 + 1051632 | 0) >> 2] = 1051620; - HEAP32[(0 + 1051640 | 0) >> 2] = 1051628; - HEAP32[(0 + 1051628 | 0) >> 2] = 1051620; - HEAP32[(0 + 1051648 | 0) >> 2] = 1051636; - HEAP32[(0 + 1051636 | 0) >> 2] = 1051628; - HEAP32[(0 + 1051656 | 0) >> 2] = 1051644; - HEAP32[(0 + 1051644 | 0) >> 2] = 1051636; - HEAP32[(0 + 1051664 | 0) >> 2] = 1051652; - HEAP32[(0 + 1051652 | 0) >> 2] = 1051644; - HEAP32[(0 + 1051672 | 0) >> 2] = 1051660; - HEAP32[(0 + 1051660 | 0) >> 2] = 1051652; - HEAP32[(0 + 1051680 | 0) >> 2] = 1051668; - HEAP32[(0 + 1051668 | 0) >> 2] = 1051660; - HEAP32[(0 + 1051688 | 0) >> 2] = 1051676; - HEAP32[(0 + 1051676 | 0) >> 2] = 1051668; - HEAP32[(0 + 1051696 | 0) >> 2] = 1051684; - HEAP32[(0 + 1051684 | 0) >> 2] = 1051676; - HEAP32[(0 + 1051704 | 0) >> 2] = 1051692; - HEAP32[(0 + 1051692 | 0) >> 2] = 1051684; - HEAP32[(0 + 1051712 | 0) >> 2] = 1051700; - HEAP32[(0 + 1051700 | 0) >> 2] = 1051692; - HEAP32[(0 + 1051720 | 0) >> 2] = 1051708; - HEAP32[(0 + 1051708 | 0) >> 2] = 1051700; - HEAP32[(0 + 1051728 | 0) >> 2] = 1051716; - HEAP32[(0 + 1051716 | 0) >> 2] = 1051708; - HEAP32[(0 + 1051736 | 0) >> 2] = 1051724; - HEAP32[(0 + 1051724 | 0) >> 2] = 1051716; - HEAP32[(0 + 1051744 | 0) >> 2] = 1051732; - HEAP32[(0 + 1051732 | 0) >> 2] = 1051724; - HEAP32[(0 + 1051752 | 0) >> 2] = 1051740; - HEAP32[(0 + 1051740 | 0) >> 2] = 1051732; - $0 = ($6 + 15 | 0) & -8 | 0; - $2 = $0 + -8 | 0; - HEAP32[(0 + 1051776 | 0) >> 2] = $2; - HEAP32[(0 + 1051748 | 0) >> 2] = 1051740; - $618 = $6 - $0 | 0; - $0 = $9 + -40 | 0; - $7 = ($618 + $0 | 0) + 8 | 0; - HEAP32[(0 + 1051768 | 0) >> 2] = $7; - HEAP32[($2 + 4 | 0) >> 2] = $7 | 1 | 0; - HEAP32[(($6 + $0 | 0) + 4 | 0) >> 2] = 40; - HEAP32[(0 + 1051788 | 0) >> 2] = 2097152; - break label$47; - } - if ($2 >>> 0 >= $6 >>> 0) { - break label$55 - } - if ($7 >>> 0 > $2 >>> 0) { - break label$55 - } - $7 = HEAP32[($0 + 12 | 0) >> 2] | 0; - if ($7 & 1 | 0) { - break label$55 - } - if (($7 >>> 1 | 0 | 0) == ($5 | 0)) { - break label$51 - } - } - $0 = HEAP32[(0 + 1051792 | 0) >> 2] | 0; - HEAP32[(0 + 1051792 | 0) >> 2] = $6 >>> 0 > $0 >>> 0 ? $0 : $6; - $7 = $6 + $9 | 0; - $0 = 1051476; - label$61 : { - label$62 : { - label$63 : { - label$64 : while (1) { - $8 = HEAP32[$0 >> 2] | 0; - if (($8 | 0) == ($7 | 0)) { - break label$63 - } - $0 = HEAP32[($0 + 8 | 0) >> 2] | 0; - if ($0) { - continue label$64 - } - break label$62; - }; - } - $7 = HEAP32[($0 + 12 | 0) >> 2] | 0; - if ($7 & 1 | 0) { - break label$62 - } - if (($7 >>> 1 | 0 | 0) == ($5 | 0)) { - break label$61 - } - } - $0 = 1051476; - label$65 : { - label$66 : while (1) { - label$67 : { - $7 = HEAP32[$0 >> 2] | 0; - if ($7 >>> 0 > $2 >>> 0) { - break label$67 - } - $7 = $7 + (HEAP32[($0 + 4 | 0) >> 2] | 0) | 0; - if ($2 >>> 0 < $7 >>> 0) { - break label$65 - } - } - $0 = HEAP32[($0 + 8 | 0) >> 2] | 0; - continue label$66; - }; - } - $0 = ($6 + 15 | 0) & -8 | 0; - $8 = $0 + -8 | 0; - HEAP32[(0 + 1051776 | 0) >> 2] = $8; - $693 = $6 - $0 | 0; - $0 = $9 + -40 | 0; - $4 = ($693 + $0 | 0) + 8 | 0; - HEAP32[(0 + 1051768 | 0) >> 2] = $4; - HEAP32[($8 + 4 | 0) >> 2] = $4 | 1 | 0; - HEAP32[(($6 + $0 | 0) + 4 | 0) >> 2] = 40; - HEAP32[(0 + 1051788 | 0) >> 2] = 2097152; - $0 = (($7 + -32 | 0) & -8 | 0) + -8 | 0; - $8 = $0 >>> 0 < ($2 + 16 | 0) >>> 0 ? $2 : $0; - HEAP32[($8 + 4 | 0) >> 2] = 27; - i64toi32_i32$2 = 0; - i64toi32_i32$0 = HEAP32[(i64toi32_i32$2 + 1051476 | 0) >> 2] | 0; - i64toi32_i32$1 = HEAP32[(i64toi32_i32$2 + 1051480 | 0) >> 2] | 0; - $10 = i64toi32_i32$0; - $10$hi = i64toi32_i32$1; - i64toi32_i32$2 = 0; - i64toi32_i32$1 = HEAP32[(i64toi32_i32$2 + 1051484 | 0) >> 2] | 0; - i64toi32_i32$0 = HEAP32[(i64toi32_i32$2 + 1051488 | 0) >> 2] | 0; - $721 = i64toi32_i32$1; - i64toi32_i32$1 = $8 + 16 | 0; - HEAP32[i64toi32_i32$1 >> 2] = $721; - HEAP32[(i64toi32_i32$1 + 4 | 0) >> 2] = i64toi32_i32$0; - i64toi32_i32$0 = $10$hi; - i64toi32_i32$1 = $8; - HEAP32[($8 + 8 | 0) >> 2] = $10; - HEAP32[($8 + 12 | 0) >> 2] = i64toi32_i32$0; - HEAP32[(0 + 1051488 | 0) >> 2] = $5; - HEAP32[(0 + 1051480 | 0) >> 2] = $9; - HEAP32[(0 + 1051476 | 0) >> 2] = $6; - HEAP32[(0 + 1051484 | 0) >> 2] = $8 + 8 | 0; - $0 = $8 + 28 | 0; - label$68 : while (1) { - HEAP32[$0 >> 2] = 7; - $0 = $0 + 4 | 0; - if ($0 >>> 0 < $7 >>> 0) { - continue label$68 - } - break label$68; - }; - if (($8 | 0) == ($2 | 0)) { - break label$47 - } - HEAP32[($8 + 4 | 0) >> 2] = (HEAP32[($8 + 4 | 0) >> 2] | 0) & -2 | 0; - $0 = $8 - $2 | 0; - HEAP32[($2 + 4 | 0) >> 2] = $0 | 1 | 0; - HEAP32[$8 >> 2] = $0; - label$69 : { - if ($0 >>> 0 < 256 >>> 0) { - break label$69 - } - _ZN8dlmalloc8dlmalloc17Dlmalloc$LT$A$GT$18insert_large_chunk17h8e4702b854476b2fE($2 | 0, $0 | 0); - break label$47; - } - $7 = ($0 & 248 | 0) + 1051492 | 0; - label$70 : { - label$71 : { - $6 = HEAP32[(0 + 1051756 | 0) >> 2] | 0; - $0 = 1 << ($0 >>> 3 | 0) | 0; - if ($6 & $0 | 0) { - break label$71 - } - HEAP32[(0 + 1051756 | 0) >> 2] = $6 | $0 | 0; - $0 = $7; - break label$70; - } - $0 = HEAP32[($7 + 8 | 0) >> 2] | 0; - } - HEAP32[($7 + 8 | 0) >> 2] = $2; - HEAP32[($0 + 12 | 0) >> 2] = $2; - HEAP32[($2 + 12 | 0) >> 2] = $7; - HEAP32[($2 + 8 | 0) >> 2] = $0; - break label$47; - } - HEAP32[$0 >> 2] = $6; - HEAP32[($0 + 4 | 0) >> 2] = (HEAP32[($0 + 4 | 0) >> 2] | 0) + $9 | 0; - $7 = (($6 + 15 | 0) & -8 | 0) + -8 | 0; - HEAP32[($7 + 4 | 0) >> 2] = $3 | 3 | 0; - $2 = (($8 + 15 | 0) & -8 | 0) + -8 | 0; - $0 = $7 + $3 | 0; - $3 = $2 - $0 | 0; - if (($2 | 0) == (HEAP32[(0 + 1051776 | 0) >> 2] | 0 | 0)) { - break label$50 - } - if (($2 | 0) == (HEAP32[(0 + 1051772 | 0) >> 2] | 0 | 0)) { - break label$49 - } - label$72 : { - $6 = HEAP32[($2 + 4 | 0) >> 2] | 0; - if (($6 & 3 | 0 | 0) != (1 | 0)) { - break label$72 - } - $6 = $6 & -8 | 0; - _ZN8dlmalloc8dlmalloc17Dlmalloc$LT$A$GT$12unlink_chunk17h20421146e3e4e9ccE($2 | 0, $6 | 0); - $3 = $6 + $3 | 0; - $2 = $2 + $6 | 0; - $6 = HEAP32[($2 + 4 | 0) >> 2] | 0; - } - HEAP32[($2 + 4 | 0) >> 2] = $6 & -2 | 0; - HEAP32[($0 + 4 | 0) >> 2] = $3 | 1 | 0; - HEAP32[($0 + $3 | 0) >> 2] = $3; - label$73 : { - if ($3 >>> 0 < 256 >>> 0) { - break label$73 - } - _ZN8dlmalloc8dlmalloc17Dlmalloc$LT$A$GT$18insert_large_chunk17h8e4702b854476b2fE($0 | 0, $3 | 0); - break label$48; - } - $2 = ($3 & 248 | 0) + 1051492 | 0; - label$74 : { - label$75 : { - $6 = HEAP32[(0 + 1051756 | 0) >> 2] | 0; - $3 = 1 << ($3 >>> 3 | 0) | 0; - if ($6 & $3 | 0) { - break label$75 - } - HEAP32[(0 + 1051756 | 0) >> 2] = $6 | $3 | 0; - $3 = $2; - break label$74; - } - $3 = HEAP32[($2 + 8 | 0) >> 2] | 0; - } - HEAP32[($2 + 8 | 0) >> 2] = $0; - HEAP32[($3 + 12 | 0) >> 2] = $0; - HEAP32[($0 + 12 | 0) >> 2] = $2; - HEAP32[($0 + 8 | 0) >> 2] = $3; - break label$48; - } - $2 = $0 - $3 | 0; - HEAP32[(0 + 1051768 | 0) >> 2] = $2; - $0 = HEAP32[(0 + 1051776 | 0) >> 2] | 0; - $7 = $0 + $3 | 0; - HEAP32[(0 + 1051776 | 0) >> 2] = $7; - HEAP32[($7 + 4 | 0) >> 2] = $2 | 1 | 0; - HEAP32[($0 + 4 | 0) >> 2] = $3 | 3 | 0; - $0 = $0 + 8 | 0; - break label$1; - } - $2 = HEAP32[(0 + 1051772 | 0) >> 2] | 0; - label$76 : { - label$77 : { - $7 = $0 - $3 | 0; - if ($7 >>> 0 > 15 >>> 0) { - break label$77 - } - HEAP32[(0 + 1051772 | 0) >> 2] = 0; - HEAP32[(0 + 1051764 | 0) >> 2] = 0; - HEAP32[($2 + 4 | 0) >> 2] = $0 | 3 | 0; - $0 = $2 + $0 | 0; - HEAP32[($0 + 4 | 0) >> 2] = HEAP32[($0 + 4 | 0) >> 2] | 0 | 1 | 0; - break label$76; - } - HEAP32[(0 + 1051764 | 0) >> 2] = $7; - $6 = $2 + $3 | 0; - HEAP32[(0 + 1051772 | 0) >> 2] = $6; - HEAP32[($6 + 4 | 0) >> 2] = $7 | 1 | 0; - HEAP32[($2 + $0 | 0) >> 2] = $7; - HEAP32[($2 + 4 | 0) >> 2] = $3 | 3 | 0; - } - $0 = $2 + 8 | 0; - break label$1; - } - HEAP32[($0 + 4 | 0) >> 2] = $8 + $9 | 0; - $0 = HEAP32[(0 + 1051776 | 0) >> 2] | 0; - $2 = ($0 + 15 | 0) & -8 | 0; - $7 = $2 + -8 | 0; - HEAP32[(0 + 1051776 | 0) >> 2] = $7; - $928 = $0 - $2 | 0; - $2 = (HEAP32[(0 + 1051768 | 0) >> 2] | 0) + $9 | 0; - $6 = ($928 + $2 | 0) + 8 | 0; - HEAP32[(0 + 1051768 | 0) >> 2] = $6; - HEAP32[($7 + 4 | 0) >> 2] = $6 | 1 | 0; - HEAP32[(($0 + $2 | 0) + 4 | 0) >> 2] = 40; - HEAP32[(0 + 1051788 | 0) >> 2] = 2097152; - break label$47; - } - HEAP32[(0 + 1051776 | 0) >> 2] = $0; - $3 = (HEAP32[(0 + 1051768 | 0) >> 2] | 0) + $3 | 0; - HEAP32[(0 + 1051768 | 0) >> 2] = $3; - HEAP32[($0 + 4 | 0) >> 2] = $3 | 1 | 0; - break label$48; - } - HEAP32[(0 + 1051772 | 0) >> 2] = $0; - $3 = (HEAP32[(0 + 1051764 | 0) >> 2] | 0) + $3 | 0; - HEAP32[(0 + 1051764 | 0) >> 2] = $3; - HEAP32[($0 + 4 | 0) >> 2] = $3 | 1 | 0; - HEAP32[($0 + $3 | 0) >> 2] = $3; - } - $0 = $7 + 8 | 0; - break label$1; - } - $0 = 0; - $2 = HEAP32[(0 + 1051768 | 0) >> 2] | 0; - if ($2 >>> 0 <= $3 >>> 0) { - break label$1 - } - $2 = $2 - $3 | 0; - HEAP32[(0 + 1051768 | 0) >> 2] = $2; - $0 = HEAP32[(0 + 1051776 | 0) >> 2] | 0; - $7 = $0 + $3 | 0; - HEAP32[(0 + 1051776 | 0) >> 2] = $7; - HEAP32[($7 + 4 | 0) >> 2] = $2 | 1 | 0; - HEAP32[($0 + 4 | 0) >> 2] = $3 | 3 | 0; - $0 = $0 + 8 | 0; - break label$1; - } - HEAP32[($0 + 24 | 0) >> 2] = $5; - label$78 : { - $6 = HEAP32[($7 + 16 | 0) >> 2] | 0; - if (!$6) { - break label$78 - } - HEAP32[($0 + 16 | 0) >> 2] = $6; - HEAP32[($6 + 24 | 0) >> 2] = $0; - } - $6 = HEAP32[($7 + 20 | 0) >> 2] | 0; - if (!$6) { - break label$2 - } - HEAP32[($0 + 20 | 0) >> 2] = $6; - HEAP32[($6 + 24 | 0) >> 2] = $0; - } - label$79 : { - label$80 : { - if ($2 >>> 0 < 16 >>> 0) { - break label$80 - } - HEAP32[($7 + 4 | 0) >> 2] = $3 | 3 | 0; - $0 = $7 + $3 | 0; - HEAP32[($0 + 4 | 0) >> 2] = $2 | 1 | 0; - HEAP32[($0 + $2 | 0) >> 2] = $2; - label$81 : { - if ($2 >>> 0 < 256 >>> 0) { - break label$81 - } - _ZN8dlmalloc8dlmalloc17Dlmalloc$LT$A$GT$18insert_large_chunk17h8e4702b854476b2fE($0 | 0, $2 | 0); - break label$79; - } - $3 = ($2 & 248 | 0) + 1051492 | 0; - label$82 : { - label$83 : { - $6 = HEAP32[(0 + 1051756 | 0) >> 2] | 0; - $2 = 1 << ($2 >>> 3 | 0) | 0; - if ($6 & $2 | 0) { - break label$83 - } - HEAP32[(0 + 1051756 | 0) >> 2] = $6 | $2 | 0; - $2 = $3; - break label$82; - } - $2 = HEAP32[($3 + 8 | 0) >> 2] | 0; - } - HEAP32[($3 + 8 | 0) >> 2] = $0; - HEAP32[($2 + 12 | 0) >> 2] = $0; - HEAP32[($0 + 12 | 0) >> 2] = $3; - HEAP32[($0 + 8 | 0) >> 2] = $2; - break label$79; - } - $0 = $2 + $3 | 0; - HEAP32[($7 + 4 | 0) >> 2] = $0 | 3 | 0; - $0 = $7 + $0 | 0; - HEAP32[($0 + 4 | 0) >> 2] = HEAP32[($0 + 4 | 0) >> 2] | 0 | 1 | 0; - } - $0 = $7 + 8 | 0; - } - __stack_pointer = $1 + 16 | 0; - return $0 | 0; - } - - function _ZN8dlmalloc8dlmalloc17Dlmalloc$LT$A$GT$8memalign17h816986e35e0be861E($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - var $2 = 0, $4 = 0, $3 = 0, $5 = 0, $6 = 0; - $2 = 0; - label$1 : { - $0 = $0 >>> 0 > 16 >>> 0 ? $0 : 16; - if ((-65587 - $0 | 0) >>> 0 <= $1 >>> 0) { - break label$1 - } - $3 = $1 >>> 0 < 11 >>> 0 ? 16 : ($1 + 11 | 0) & -8 | 0; - $1 = _ZN8dlmalloc8dlmalloc17Dlmalloc$LT$A$GT$6malloc17hd9c2c8577ef4c61dE(($0 + $3 | 0) + 12 | 0 | 0) | 0; - if (!$1) { - break label$1 - } - $2 = $1 + -8 | 0; - label$2 : { - label$3 : { - $4 = $0 + -1 | 0; - if ($4 & $1 | 0) { - break label$3 - } - $0 = $2; - break label$2; - } - $5 = $1 + -4 | 0; - $6 = HEAP32[$5 >> 2] | 0; - $1 = (($4 + $1 | 0) & (0 - $0 | 0) | 0) + -8 | 0; - $0 = $1 + (($1 - $2 | 0) >>> 0 > 16 >>> 0 ? 0 : $0) | 0; - $1 = $0 - $2 | 0; - $4 = ($6 & -8 | 0) - $1 | 0; - label$4 : { - if (!($6 & 3 | 0)) { - break label$4 - } - HEAP32[($0 + 4 | 0) >> 2] = $4 | ((HEAP32[($0 + 4 | 0) >> 2] | 0) & 1 | 0) | 0 | 2 | 0; - $4 = $0 + $4 | 0; - HEAP32[($4 + 4 | 0) >> 2] = HEAP32[($4 + 4 | 0) >> 2] | 0 | 1 | 0; - HEAP32[$5 >> 2] = $1 | ((HEAP32[$5 >> 2] | 0) & 1 | 0) | 0 | 2 | 0; - $4 = $2 + $1 | 0; - HEAP32[($4 + 4 | 0) >> 2] = HEAP32[($4 + 4 | 0) >> 2] | 0 | 1 | 0; - _ZN8dlmalloc8dlmalloc17Dlmalloc$LT$A$GT$13dispose_chunk17hb68dd003b737d09cE($2 | 0, $1 | 0); - break label$2; - } - $2 = HEAP32[$2 >> 2] | 0; - HEAP32[($0 + 4 | 0) >> 2] = $4; - HEAP32[$0 >> 2] = $2 + $1 | 0; - } - label$5 : { - $1 = HEAP32[($0 + 4 | 0) >> 2] | 0; - if (!($1 & 3 | 0)) { - break label$5 - } - $2 = $1 & -8 | 0; - if ($2 >>> 0 <= ($3 + 16 | 0) >>> 0) { - break label$5 - } - HEAP32[($0 + 4 | 0) >> 2] = $3 | ($1 & 1 | 0) | 0 | 2 | 0; - $1 = $0 + $3 | 0; - $3 = $2 - $3 | 0; - HEAP32[($1 + 4 | 0) >> 2] = $3 | 3 | 0; - $2 = $0 + $2 | 0; - HEAP32[($2 + 4 | 0) >> 2] = HEAP32[($2 + 4 | 0) >> 2] | 0 | 1 | 0; - _ZN8dlmalloc8dlmalloc17Dlmalloc$LT$A$GT$13dispose_chunk17hb68dd003b737d09cE($1 | 0, $3 | 0); - } - $2 = $0 + 8 | 0; - } - return $2 | 0; - } - - function _ZN3std3sys9backtrace26__rust_end_short_backtrace17h64c5c3eeff5e218cE($0) { - $0 = $0 | 0; - _ZN3std9panicking19begin_panic_handler28_$u7b$$u7b$closure$u7d$$u7d$17hae7a24cfbe5dc9e9E($0 | 0); - wasm2js_trap(); - } - - function _ZN3std9panicking19begin_panic_handler28_$u7b$$u7b$closure$u7d$$u7d$17hae7a24cfbe5dc9e9E($0) { - $0 = $0 | 0; - var $2 = 0, $1 = 0, $3 = 0, $24 = 0, $37 = 0; - $1 = __stack_pointer - 16 | 0; - __stack_pointer = $1; - $2 = HEAP32[($0 + 12 | 0) >> 2] | 0; - label$1 : { - label$2 : { - label$3 : { - switch (HEAP32[($0 + 4 | 0) >> 2] | 0 | 0) { - case 0: - if ($2) { - break label$2 - } - $2 = 1; - $3 = 0; - break label$1; - case 1: - break label$3; - default: - break label$2; - }; - } - if ($2) { - break label$2 - } - $2 = HEAP32[$0 >> 2] | 0; - $3 = HEAP32[($2 + 4 | 0) >> 2] | 0; - $2 = HEAP32[$2 >> 2] | 0; - break label$1; - } - HEAP32[$1 >> 2] = -2147483648; - HEAP32[($1 + 12 | 0) >> 2] = $0; - $24 = HEAP32[($0 + 24 | 0) >> 2] | 0; - $0 = HEAP32[($0 + 28 | 0) >> 2] | 0; - _ZN3std9panicking20rust_panic_with_hook17h142fb958becc9908E($1 | 0, 1048912 | 0, $24 | 0, HEAPU8[($0 + 28 | 0) >> 0] | 0 | 0, HEAPU8[($0 + 29 | 0) >> 0] | 0 | 0); - wasm2js_trap(); - } - HEAP32[($1 + 4 | 0) >> 2] = $3; - HEAP32[$1 >> 2] = $2; - $37 = HEAP32[($0 + 24 | 0) >> 2] | 0; - $0 = HEAP32[($0 + 28 | 0) >> 2] | 0; - _ZN3std9panicking20rust_panic_with_hook17h142fb958becc9908E($1 | 0, 1048884 | 0, $37 | 0, HEAPU8[($0 + 28 | 0) >> 0] | 0 | 0, HEAPU8[($0 + 29 | 0) >> 0] | 0 | 0); - wasm2js_trap(); - } - - function _ZN3std5alloc24default_alloc_error_hook17h708687752e0edcfaE($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - var $2 = 0, i64toi32_i32$1 = 0, i64toi32_i32$0 = 0, i64toi32_i32$2 = 0, i64toi32_i32$4 = 0, i64toi32_i32$3 = 0, $12 = 0, $13 = 0, $15$hi = 0, $18$hi = 0, $19 = 0; - $2 = __stack_pointer - 48 | 0; - __stack_pointer = $2; - label$1 : { - if (!(HEAPU8[(0 + 1051324 | 0) >> 0] | 0)) { - break label$1 - } - HEAP32[($2 + 12 | 0) >> 2] = 2; - HEAP32[($2 + 8 | 0) >> 2] = 1048804; - i64toi32_i32$1 = $2; - i64toi32_i32$0 = 0; - HEAP32[($2 + 20 | 0) >> 2] = 1; - HEAP32[($2 + 24 | 0) >> 2] = i64toi32_i32$0; - HEAP32[($2 + 44 | 0) >> 2] = $1; - $13 = $2; - i64toi32_i32$0 = 0; - i64toi32_i32$2 = 1; - i64toi32_i32$1 = 0; - i64toi32_i32$3 = 32; - i64toi32_i32$4 = i64toi32_i32$3 & 31 | 0; - if (32 >>> 0 <= (i64toi32_i32$3 & 63 | 0) >>> 0) { - i64toi32_i32$1 = i64toi32_i32$2 << i64toi32_i32$4 | 0; - $12 = 0; - } else { - i64toi32_i32$1 = ((1 << i64toi32_i32$4 | 0) - 1 | 0) & (i64toi32_i32$2 >>> (32 - i64toi32_i32$4 | 0) | 0) | 0 | (i64toi32_i32$0 << i64toi32_i32$4 | 0) | 0; - $12 = i64toi32_i32$2 << i64toi32_i32$4 | 0; - } - $15$hi = i64toi32_i32$1; - i64toi32_i32$1 = 0; - $18$hi = i64toi32_i32$1; - i64toi32_i32$1 = $15$hi; - i64toi32_i32$0 = $12; - i64toi32_i32$2 = $18$hi; - i64toi32_i32$3 = $2 + 44 | 0; - i64toi32_i32$2 = i64toi32_i32$1 | i64toi32_i32$2 | 0; - $19 = i64toi32_i32$0 | i64toi32_i32$3 | 0; - i64toi32_i32$0 = $13; - HEAP32[(i64toi32_i32$0 + 32 | 0) >> 2] = $19; - HEAP32[(i64toi32_i32$0 + 36 | 0) >> 2] = i64toi32_i32$2; - HEAP32[($2 + 16 | 0) >> 2] = $2 + 32 | 0; - _ZN4core9panicking9panic_fmt17hb2f16849466f57b6E($2 + 8 | 0 | 0, 1048836 | 0); - wasm2js_trap(); - } - __stack_pointer = $2 + 48 | 0; - } - - function __rdl_alloc($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - label$1 : { - if ($1 >>> 0 < 9 >>> 0) { - break label$1 - } - return _ZN8dlmalloc8dlmalloc17Dlmalloc$LT$A$GT$8memalign17h816986e35e0be861E($1 | 0, $0 | 0) | 0 | 0; - } - return _ZN8dlmalloc8dlmalloc17Dlmalloc$LT$A$GT$6malloc17hd9c2c8577ef4c61dE($0 | 0) | 0 | 0; - } - - function __rdl_dealloc($0, $1, $2) { - $0 = $0 | 0; - $1 = $1 | 0; - $2 = $2 | 0; - var $3 = 0, $4 = 0; - label$1 : { - label$2 : { - $3 = HEAP32[($0 + -4 | 0) >> 2] | 0; - $4 = $3 & -8 | 0; - $3 = $3 & 3 | 0; - if ($4 >>> 0 < (($3 ? 4 : 8) + $1 | 0) >>> 0) { - break label$2 - } - label$3 : { - if (!$3) { - break label$3 - } - if ($4 >>> 0 > ($1 + 39 | 0) >>> 0) { - break label$1 - } - } - _ZN8dlmalloc8dlmalloc17Dlmalloc$LT$A$GT$4free17hcade36dd23206a7bE($0 | 0); - return; - } - _ZN4core9panicking5panic17h9f0a34b0744fbd45E(1048641 | 0, 46 | 0, 1048688 | 0); - wasm2js_trap(); - } - _ZN4core9panicking5panic17h9f0a34b0744fbd45E(1048704 | 0, 46 | 0, 1048752 | 0); - wasm2js_trap(); - } - - function __rdl_realloc($0, $1, $2, $3) { - $0 = $0 | 0; - $1 = $1 | 0; - $2 = $2 | 0; - $3 = $3 | 0; - var $7 = 0, $5 = 0, $8 = 0, $4 = 0, $6 = 0, $9 = 0; - label$1 : { - label$2 : { - label$3 : { - label$4 : { - label$5 : { - $4 = $0 + -4 | 0; - $5 = HEAP32[$4 >> 2] | 0; - $6 = $5 & -8 | 0; - $7 = $5 & 3 | 0; - if ($6 >>> 0 < (($7 ? 4 : 8) + $1 | 0) >>> 0) { - break label$5 - } - $8 = $1 + 39 | 0; - label$6 : { - if (!$7) { - break label$6 - } - if ($6 >>> 0 > $8 >>> 0) { - break label$4 - } - } - label$7 : { - label$8 : { - label$9 : { - if ($2 >>> 0 < 9 >>> 0) { - break label$9 - } - $2 = _ZN8dlmalloc8dlmalloc17Dlmalloc$LT$A$GT$8memalign17h816986e35e0be861E($2 | 0, $3 | 0) | 0; - if ($2) { - break label$8 - } - return 0 | 0; - } - $2 = 0; - if ($3 >>> 0 > -65588 >>> 0) { - break label$7 - } - $1 = $3 >>> 0 < 11 >>> 0 ? 16 : ($3 + 11 | 0) & -8 | 0; - label$10 : { - label$11 : { - if ($7) { - break label$11 - } - if ($1 >>> 0 < 256 >>> 0) { - break label$10 - } - if ($6 >>> 0 < ($1 | 4 | 0) >>> 0) { - break label$10 - } - if (($6 - $1 | 0) >>> 0 >= 131073 >>> 0) { - break label$10 - } - return $0 | 0; - } - $8 = $0 + -8 | 0; - $7 = $8 + $6 | 0; - label$12 : { - label$13 : { - label$14 : { - label$15 : { - label$16 : { - if ($6 >>> 0 >= $1 >>> 0) { - break label$16 - } - if (($7 | 0) == (HEAP32[(0 + 1051776 | 0) >> 2] | 0 | 0)) { - break label$12 - } - if (($7 | 0) == (HEAP32[(0 + 1051772 | 0) >> 2] | 0 | 0)) { - break label$14 - } - $5 = HEAP32[($7 + 4 | 0) >> 2] | 0; - if ($5 & 2 | 0) { - break label$10 - } - $9 = $5 & -8 | 0; - $5 = $9 + $6 | 0; - if ($5 >>> 0 < $1 >>> 0) { - break label$10 - } - _ZN8dlmalloc8dlmalloc17Dlmalloc$LT$A$GT$12unlink_chunk17h20421146e3e4e9ccE($7 | 0, $9 | 0); - $3 = $5 - $1 | 0; - if ($3 >>> 0 < 16 >>> 0) { - break label$15 - } - HEAP32[$4 >> 2] = $1 | ((HEAP32[$4 >> 2] | 0) & 1 | 0) | 0 | 2 | 0; - $1 = $8 + $1 | 0; - HEAP32[($1 + 4 | 0) >> 2] = $3 | 3 | 0; - $2 = $8 + $5 | 0; - HEAP32[($2 + 4 | 0) >> 2] = HEAP32[($2 + 4 | 0) >> 2] | 0 | 1 | 0; - _ZN8dlmalloc8dlmalloc17Dlmalloc$LT$A$GT$13dispose_chunk17hb68dd003b737d09cE($1 | 0, $3 | 0); - return $0 | 0; - } - $3 = $6 - $1 | 0; - if ($3 >>> 0 > 15 >>> 0) { - break label$13 - } - return $0 | 0; - } - HEAP32[$4 >> 2] = $5 | ((HEAP32[$4 >> 2] | 0) & 1 | 0) | 0 | 2 | 0; - $1 = $8 + $5 | 0; - HEAP32[($1 + 4 | 0) >> 2] = HEAP32[($1 + 4 | 0) >> 2] | 0 | 1 | 0; - return $0 | 0; - } - $7 = (HEAP32[(0 + 1051764 | 0) >> 2] | 0) + $6 | 0; - if ($7 >>> 0 < $1 >>> 0) { - break label$10 - } - label$17 : { - label$18 : { - $3 = $7 - $1 | 0; - if ($3 >>> 0 > 15 >>> 0) { - break label$18 - } - HEAP32[$4 >> 2] = $5 & 1 | 0 | $7 | 0 | 2 | 0; - $1 = $8 + $7 | 0; - HEAP32[($1 + 4 | 0) >> 2] = HEAP32[($1 + 4 | 0) >> 2] | 0 | 1 | 0; - $3 = 0; - $1 = 0; - break label$17; - } - HEAP32[$4 >> 2] = $1 | ($5 & 1 | 0) | 0 | 2 | 0; - $1 = $8 + $1 | 0; - HEAP32[($1 + 4 | 0) >> 2] = $3 | 1 | 0; - $2 = $8 + $7 | 0; - HEAP32[$2 >> 2] = $3; - HEAP32[($2 + 4 | 0) >> 2] = (HEAP32[($2 + 4 | 0) >> 2] | 0) & -2 | 0; - } - HEAP32[(0 + 1051772 | 0) >> 2] = $1; - HEAP32[(0 + 1051764 | 0) >> 2] = $3; - return $0 | 0; - } - HEAP32[$4 >> 2] = $1 | ($5 & 1 | 0) | 0 | 2 | 0; - $1 = $8 + $1 | 0; - HEAP32[($1 + 4 | 0) >> 2] = $3 | 3 | 0; - HEAP32[($7 + 4 | 0) >> 2] = HEAP32[($7 + 4 | 0) >> 2] | 0 | 1 | 0; - _ZN8dlmalloc8dlmalloc17Dlmalloc$LT$A$GT$13dispose_chunk17hb68dd003b737d09cE($1 | 0, $3 | 0); - return $0 | 0; - } - $7 = (HEAP32[(0 + 1051768 | 0) >> 2] | 0) + $6 | 0; - if ($7 >>> 0 > $1 >>> 0) { - break label$1 - } - } - $1 = _ZN8dlmalloc8dlmalloc17Dlmalloc$LT$A$GT$6malloc17hd9c2c8577ef4c61dE($3 | 0) | 0; - if (!$1) { - break label$7 - } - $2 = HEAP32[$4 >> 2] | 0; - $2 = ($2 & 3 | 0 ? -4 : -8) + ($2 & -8 | 0) | 0; - $1 = memcpy($1 | 0, $0 | 0, ($2 >>> 0 < $3 >>> 0 ? $2 : $3) | 0) | 0; - _ZN8dlmalloc8dlmalloc17Dlmalloc$LT$A$GT$4free17hcade36dd23206a7bE($0 | 0); - return $1 | 0; - } - memcpy($2 | 0, $0 | 0, ($1 >>> 0 < $3 >>> 0 ? $1 : $3) | 0) | 0; - $3 = HEAP32[$4 >> 2] | 0; - $7 = $3 & -8 | 0; - $3 = $3 & 3 | 0; - if ($7 >>> 0 < (($3 ? 4 : 8) + $1 | 0) >>> 0) { - break label$3 - } - label$19 : { - if (!$3) { - break label$19 - } - if ($7 >>> 0 > $8 >>> 0) { - break label$2 - } - } - _ZN8dlmalloc8dlmalloc17Dlmalloc$LT$A$GT$4free17hcade36dd23206a7bE($0 | 0); - } - return $2 | 0; - } - _ZN4core9panicking5panic17h9f0a34b0744fbd45E(1048641 | 0, 46 | 0, 1048688 | 0); - wasm2js_trap(); - } - _ZN4core9panicking5panic17h9f0a34b0744fbd45E(1048704 | 0, 46 | 0, 1048752 | 0); - wasm2js_trap(); - } - _ZN4core9panicking5panic17h9f0a34b0744fbd45E(1048641 | 0, 46 | 0, 1048688 | 0); - wasm2js_trap(); - } - _ZN4core9panicking5panic17h9f0a34b0744fbd45E(1048704 | 0, 46 | 0, 1048752 | 0); - wasm2js_trap(); - } - HEAP32[$4 >> 2] = $1 | ($5 & 1 | 0) | 0 | 2 | 0; - $3 = $8 + $1 | 0; - $1 = $7 - $1 | 0; - HEAP32[($3 + 4 | 0) >> 2] = $1 | 1 | 0; - HEAP32[(0 + 1051768 | 0) >> 2] = $1; - HEAP32[(0 + 1051776 | 0) >> 2] = $3; - return $0 | 0; - } - - function rust_begin_unwind($0) { - $0 = $0 | 0; - var i64toi32_i32$0 = 0, i64toi32_i32$2 = 0, i64toi32_i32$1 = 0, $1 = 0, $2 = 0, $12 = 0, $17 = 0, $24 = 0; - $1 = __stack_pointer - 32 | 0; - __stack_pointer = $1; - $2 = HEAP32[($0 + 24 | 0) >> 2] | 0; - i64toi32_i32$2 = $0 + 16 | 0; - i64toi32_i32$0 = HEAP32[i64toi32_i32$2 >> 2] | 0; - i64toi32_i32$1 = HEAP32[(i64toi32_i32$2 + 4 | 0) >> 2] | 0; - $12 = i64toi32_i32$0; - i64toi32_i32$0 = $1 + 16 | 0; - HEAP32[i64toi32_i32$0 >> 2] = $12; - HEAP32[(i64toi32_i32$0 + 4 | 0) >> 2] = i64toi32_i32$1; - i64toi32_i32$2 = $0 + 8 | 0; - i64toi32_i32$1 = HEAP32[i64toi32_i32$2 >> 2] | 0; - i64toi32_i32$0 = HEAP32[(i64toi32_i32$2 + 4 | 0) >> 2] | 0; - $17 = i64toi32_i32$1; - i64toi32_i32$1 = $1 + 8 | 0; - HEAP32[i64toi32_i32$1 >> 2] = $17; - HEAP32[(i64toi32_i32$1 + 4 | 0) >> 2] = i64toi32_i32$0; - HEAP32[($1 + 28 | 0) >> 2] = $0; - HEAP32[($1 + 24 | 0) >> 2] = $2; - i64toi32_i32$2 = $0; - i64toi32_i32$0 = HEAP32[i64toi32_i32$2 >> 2] | 0; - i64toi32_i32$1 = HEAP32[(i64toi32_i32$2 + 4 | 0) >> 2] | 0; - $24 = i64toi32_i32$0; - i64toi32_i32$0 = $1; - HEAP32[i64toi32_i32$0 >> 2] = $24; - HEAP32[(i64toi32_i32$0 + 4 | 0) >> 2] = i64toi32_i32$1; - _ZN3std3sys9backtrace26__rust_end_short_backtrace17h64c5c3eeff5e218cE(i64toi32_i32$0 | 0); - wasm2js_trap(); - } - - function _ZN102_$LT$std__panicking__begin_panic_handler__FormatStringPayload$u20$as$u20$core__panic__PanicPayload$GT$8take_box17hfdafd7cd188838afE($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - var i64toi32_i32$0 = 0, i64toi32_i32$1 = 0, i64toi32_i32$2 = 0, $2 = 0, $3 = 0, $5 = 0, $4 = 0, $5$hi = 0, $24 = 0, $30 = 0, $33 = 0, $73 = 0; - $2 = __stack_pointer - 64 | 0; - __stack_pointer = $2; - label$1 : { - if ((HEAP32[$1 >> 2] | 0 | 0) != (-2147483648 | 0)) { - break label$1 - } - $3 = HEAP32[($1 + 12 | 0) >> 2] | 0; - $4 = ($2 + 28 | 0) + 8 | 0; - HEAP32[$4 >> 2] = 0; - i64toi32_i32$1 = $2; - i64toi32_i32$0 = 1; - HEAP32[(i64toi32_i32$1 + 28 | 0) >> 2] = 0; - HEAP32[(i64toi32_i32$1 + 32 | 0) >> 2] = i64toi32_i32$0; - i64toi32_i32$2 = $3 + 16 | 0; - i64toi32_i32$0 = HEAP32[i64toi32_i32$2 >> 2] | 0; - i64toi32_i32$1 = HEAP32[(i64toi32_i32$2 + 4 | 0) >> 2] | 0; - $24 = i64toi32_i32$0; - i64toi32_i32$0 = ($2 + 40 | 0) + 16 | 0; - HEAP32[i64toi32_i32$0 >> 2] = $24; - HEAP32[(i64toi32_i32$0 + 4 | 0) >> 2] = i64toi32_i32$1; - i64toi32_i32$2 = $3 + 8 | 0; - i64toi32_i32$1 = HEAP32[i64toi32_i32$2 >> 2] | 0; - i64toi32_i32$0 = HEAP32[(i64toi32_i32$2 + 4 | 0) >> 2] | 0; - $30 = i64toi32_i32$1; - i64toi32_i32$1 = ($2 + 40 | 0) + 8 | 0; - HEAP32[i64toi32_i32$1 >> 2] = $30; - HEAP32[(i64toi32_i32$1 + 4 | 0) >> 2] = i64toi32_i32$0; - i64toi32_i32$2 = $3; - i64toi32_i32$0 = HEAP32[i64toi32_i32$2 >> 2] | 0; - i64toi32_i32$1 = HEAP32[(i64toi32_i32$2 + 4 | 0) >> 2] | 0; - $33 = i64toi32_i32$0; - i64toi32_i32$0 = $2; - HEAP32[(i64toi32_i32$0 + 40 | 0) >> 2] = $33; - HEAP32[(i64toi32_i32$0 + 44 | 0) >> 2] = i64toi32_i32$1; - _ZN4core3fmt5write17hd273a061a774381dE(i64toi32_i32$0 + 28 | 0 | 0, 1048576 | 0, i64toi32_i32$0 + 40 | 0 | 0) | 0; - $3 = HEAP32[$4 >> 2] | 0; - HEAP32[((i64toi32_i32$0 + 16 | 0) + 8 | 0) >> 2] = $3; - i64toi32_i32$2 = i64toi32_i32$0; - i64toi32_i32$1 = HEAP32[(i64toi32_i32$0 + 28 | 0) >> 2] | 0; - i64toi32_i32$0 = HEAP32[(i64toi32_i32$0 + 32 | 0) >> 2] | 0; - $5 = i64toi32_i32$1; - $5$hi = i64toi32_i32$0; - i64toi32_i32$1 = $2; - HEAP32[(i64toi32_i32$1 + 16 | 0) >> 2] = $5; - HEAP32[(i64toi32_i32$1 + 20 | 0) >> 2] = i64toi32_i32$0; - HEAP32[($1 + 8 | 0) >> 2] = $3; - i64toi32_i32$1 = $1; - HEAP32[i64toi32_i32$1 >> 2] = $5; - HEAP32[(i64toi32_i32$1 + 4 | 0) >> 2] = i64toi32_i32$0; - } - i64toi32_i32$2 = $1; - i64toi32_i32$0 = HEAP32[$1 >> 2] | 0; - i64toi32_i32$1 = HEAP32[($1 + 4 | 0) >> 2] | 0; - $5 = i64toi32_i32$0; - $5$hi = i64toi32_i32$1; - i64toi32_i32$0 = $1; - i64toi32_i32$1 = 1; - HEAP32[i64toi32_i32$0 >> 2] = 0; - HEAP32[(i64toi32_i32$0 + 4 | 0) >> 2] = i64toi32_i32$1; - $3 = $2 + 8 | 0; - $1 = i64toi32_i32$0 + 8 | 0; - HEAP32[$3 >> 2] = HEAP32[$1 >> 2] | 0; - HEAP32[$1 >> 2] = 0; - HEAPU8[(0 + 1051325 | 0) >> 0] | 0; - i64toi32_i32$1 = $5$hi; - i64toi32_i32$0 = $2; - HEAP32[i64toi32_i32$0 >> 2] = $5; - HEAP32[(i64toi32_i32$0 + 4 | 0) >> 2] = i64toi32_i32$1; - label$2 : { - $1 = __rust_alloc(12 | 0, 4 | 0) | 0; - if (!$1) { - break label$2 - } - i64toi32_i32$2 = i64toi32_i32$0; - i64toi32_i32$1 = HEAP32[i64toi32_i32$0 >> 2] | 0; - i64toi32_i32$0 = HEAP32[(i64toi32_i32$0 + 4 | 0) >> 2] | 0; - $73 = i64toi32_i32$1; - i64toi32_i32$1 = $1; - HEAP32[i64toi32_i32$1 >> 2] = $73; - HEAP32[(i64toi32_i32$1 + 4 | 0) >> 2] = i64toi32_i32$0; - HEAP32[(i64toi32_i32$1 + 8 | 0) >> 2] = HEAP32[$3 >> 2] | 0; - HEAP32[($0 + 4 | 0) >> 2] = 1048852; - HEAP32[$0 >> 2] = i64toi32_i32$1; - __stack_pointer = $2 + 64 | 0; - return; - } - _ZN5alloc5alloc18handle_alloc_error17h123ae56be4092711E(4 | 0, 12 | 0); - wasm2js_trap(); - } - - function _ZN102_$LT$std__panicking__begin_panic_handler__FormatStringPayload$u20$as$u20$core__panic__PanicPayload$GT$3get17h3875705a18b9af03E($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - var i64toi32_i32$0 = 0, i64toi32_i32$1 = 0, i64toi32_i32$2 = 0, $2 = 0, $3 = 0, $4 = 0, $5 = 0, $24 = 0, $30 = 0, $33 = 0; - $2 = __stack_pointer - 48 | 0; - __stack_pointer = $2; - label$1 : { - if ((HEAP32[$1 >> 2] | 0 | 0) != (-2147483648 | 0)) { - break label$1 - } - $3 = HEAP32[($1 + 12 | 0) >> 2] | 0; - $4 = ($2 + 12 | 0) + 8 | 0; - HEAP32[$4 >> 2] = 0; - i64toi32_i32$1 = $2; - i64toi32_i32$0 = 1; - HEAP32[(i64toi32_i32$1 + 12 | 0) >> 2] = 0; - HEAP32[(i64toi32_i32$1 + 16 | 0) >> 2] = i64toi32_i32$0; - i64toi32_i32$2 = $3 + 16 | 0; - i64toi32_i32$0 = HEAP32[i64toi32_i32$2 >> 2] | 0; - i64toi32_i32$1 = HEAP32[(i64toi32_i32$2 + 4 | 0) >> 2] | 0; - $24 = i64toi32_i32$0; - i64toi32_i32$0 = ($2 + 24 | 0) + 16 | 0; - HEAP32[i64toi32_i32$0 >> 2] = $24; - HEAP32[(i64toi32_i32$0 + 4 | 0) >> 2] = i64toi32_i32$1; - i64toi32_i32$2 = $3 + 8 | 0; - i64toi32_i32$1 = HEAP32[i64toi32_i32$2 >> 2] | 0; - i64toi32_i32$0 = HEAP32[(i64toi32_i32$2 + 4 | 0) >> 2] | 0; - $30 = i64toi32_i32$1; - i64toi32_i32$1 = ($2 + 24 | 0) + 8 | 0; - HEAP32[i64toi32_i32$1 >> 2] = $30; - HEAP32[(i64toi32_i32$1 + 4 | 0) >> 2] = i64toi32_i32$0; - i64toi32_i32$2 = $3; - i64toi32_i32$0 = HEAP32[i64toi32_i32$2 >> 2] | 0; - i64toi32_i32$1 = HEAP32[(i64toi32_i32$2 + 4 | 0) >> 2] | 0; - $33 = i64toi32_i32$0; - i64toi32_i32$0 = $2; - HEAP32[(i64toi32_i32$0 + 24 | 0) >> 2] = $33; - HEAP32[(i64toi32_i32$0 + 28 | 0) >> 2] = i64toi32_i32$1; - _ZN4core3fmt5write17hd273a061a774381dE(i64toi32_i32$0 + 12 | 0 | 0, 1048576 | 0, i64toi32_i32$0 + 24 | 0 | 0) | 0; - $3 = HEAP32[$4 >> 2] | 0; - HEAP32[(i64toi32_i32$0 + 8 | 0) >> 2] = $3; - i64toi32_i32$2 = i64toi32_i32$0; - i64toi32_i32$1 = HEAP32[(i64toi32_i32$0 + 12 | 0) >> 2] | 0; - i64toi32_i32$0 = HEAP32[(i64toi32_i32$0 + 16 | 0) >> 2] | 0; - $5 = i64toi32_i32$1; - i64toi32_i32$1 = $2; - HEAP32[i64toi32_i32$1 >> 2] = $5; - HEAP32[(i64toi32_i32$1 + 4 | 0) >> 2] = i64toi32_i32$0; - HEAP32[($1 + 8 | 0) >> 2] = $3; - i64toi32_i32$1 = $1; - HEAP32[i64toi32_i32$1 >> 2] = $5; - HEAP32[(i64toi32_i32$1 + 4 | 0) >> 2] = i64toi32_i32$0; - } - HEAP32[($0 + 4 | 0) >> 2] = 1048852; - HEAP32[$0 >> 2] = $1; - __stack_pointer = $2 + 48 | 0; - } - - function _ZN95_$LT$std__panicking__begin_panic_handler__FormatStringPayload$u20$as$u20$core__fmt__Display$GT$3fmt17h778dceefa8ea4afeE($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - var i64toi32_i32$0 = 0, i64toi32_i32$1 = 0, i64toi32_i32$2 = 0, $2 = 0, $22 = 0, $28 = 0, $31 = 0; - $2 = __stack_pointer - 32 | 0; - __stack_pointer = $2; - label$1 : { - label$2 : { - if ((HEAP32[$0 >> 2] | 0 | 0) == (-2147483648 | 0)) { - break label$2 - } - $0 = _ZN4core3fmt9Formatter9write_str17h7b04ca2eef2f5010E($1 | 0, HEAP32[($0 + 4 | 0) >> 2] | 0 | 0, HEAP32[($0 + 8 | 0) >> 2] | 0 | 0) | 0; - break label$1; - } - $0 = HEAP32[($0 + 12 | 0) >> 2] | 0; - i64toi32_i32$2 = $0 + 16 | 0; - i64toi32_i32$0 = HEAP32[i64toi32_i32$2 >> 2] | 0; - i64toi32_i32$1 = HEAP32[(i64toi32_i32$2 + 4 | 0) >> 2] | 0; - $22 = i64toi32_i32$0; - i64toi32_i32$0 = ($2 + 8 | 0) + 16 | 0; - HEAP32[i64toi32_i32$0 >> 2] = $22; - HEAP32[(i64toi32_i32$0 + 4 | 0) >> 2] = i64toi32_i32$1; - i64toi32_i32$2 = $0 + 8 | 0; - i64toi32_i32$1 = HEAP32[i64toi32_i32$2 >> 2] | 0; - i64toi32_i32$0 = HEAP32[(i64toi32_i32$2 + 4 | 0) >> 2] | 0; - $28 = i64toi32_i32$1; - i64toi32_i32$1 = ($2 + 8 | 0) + 8 | 0; - HEAP32[i64toi32_i32$1 >> 2] = $28; - HEAP32[(i64toi32_i32$1 + 4 | 0) >> 2] = i64toi32_i32$0; - i64toi32_i32$2 = $0; - i64toi32_i32$0 = HEAP32[$0 >> 2] | 0; - i64toi32_i32$1 = HEAP32[($0 + 4 | 0) >> 2] | 0; - $31 = i64toi32_i32$0; - i64toi32_i32$0 = $2; - HEAP32[(i64toi32_i32$0 + 8 | 0) >> 2] = $31; - HEAP32[(i64toi32_i32$0 + 12 | 0) >> 2] = i64toi32_i32$1; - $0 = _ZN4core3fmt5write17hd273a061a774381dE(HEAP32[($1 + 20 | 0) >> 2] | 0 | 0, HEAP32[($1 + 24 | 0) >> 2] | 0 | 0, i64toi32_i32$0 + 8 | 0 | 0) | 0; - } - __stack_pointer = $2 + 32 | 0; - return $0 | 0; - } - - function _ZN99_$LT$std__panicking__begin_panic_handler__StaticStrPayload$u20$as$u20$core__panic__PanicPayload$GT$8take_box17hdbb807c1367ee940E($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - var $2 = 0, $3 = 0; - HEAPU8[(0 + 1051325 | 0) >> 0] | 0; - $2 = HEAP32[($1 + 4 | 0) >> 2] | 0; - $3 = HEAP32[$1 >> 2] | 0; - label$1 : { - $1 = __rust_alloc(8 | 0, 4 | 0) | 0; - if (!$1) { - break label$1 - } - HEAP32[($1 + 4 | 0) >> 2] = $2; - HEAP32[$1 >> 2] = $3; - HEAP32[($0 + 4 | 0) >> 2] = 1048868; - HEAP32[$0 >> 2] = $1; - return; - } - _ZN5alloc5alloc18handle_alloc_error17h123ae56be4092711E(4 | 0, 8 | 0); - wasm2js_trap(); - } - - function _ZN99_$LT$std__panicking__begin_panic_handler__StaticStrPayload$u20$as$u20$core__panic__PanicPayload$GT$3get17hd2f9ef478e42b077E($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - HEAP32[($0 + 4 | 0) >> 2] = 1048868; - HEAP32[$0 >> 2] = $1; - } - - function _ZN99_$LT$std__panicking__begin_panic_handler__StaticStrPayload$u20$as$u20$core__panic__PanicPayload$GT$6as_str17h231eb7cfbc685441E($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - var i64toi32_i32$0 = 0, i64toi32_i32$2 = 0, i64toi32_i32$1 = 0, $4 = 0; - i64toi32_i32$2 = $1; - i64toi32_i32$0 = HEAP32[i64toi32_i32$2 >> 2] | 0; - i64toi32_i32$1 = HEAP32[(i64toi32_i32$2 + 4 | 0) >> 2] | 0; - $4 = i64toi32_i32$0; - i64toi32_i32$0 = $0; - HEAP32[i64toi32_i32$0 >> 2] = $4; - HEAP32[(i64toi32_i32$0 + 4 | 0) >> 2] = i64toi32_i32$1; - } - - function _ZN92_$LT$std__panicking__begin_panic_handler__StaticStrPayload$u20$as$u20$core__fmt__Display$GT$3fmt17h7d6d1d4c62b643baE($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - return _ZN4core3fmt9Formatter9write_str17h7b04ca2eef2f5010E($1 | 0, HEAP32[$0 >> 2] | 0 | 0, HEAP32[($0 + 4 | 0) >> 2] | 0 | 0) | 0 | 0; - } - - function _ZN3std9panicking20rust_panic_with_hook17h142fb958becc9908E($0, $1, $2, $3, $4) { - $0 = $0 | 0; - $1 = $1 | 0; - $2 = $2 | 0; - $3 = $3 | 0; - $4 = $4 | 0; - var $5 = 0, $6 = 0, i64toi32_i32$1 = 0; - $5 = __stack_pointer - 32 | 0; - __stack_pointer = $5; - $6 = HEAP32[(0 + 1051344 | 0) >> 2] | 0; - HEAP32[(0 + 1051344 | 0) >> 2] = $6 + 1 | 0; - label$1 : { - label$2 : { - if (($6 | 0) < (0 | 0)) { - break label$2 - } - if (HEAPU8[(0 + 1051804 | 0) >> 0] | 0) { - break label$1 - } - HEAP8[(0 + 1051804 | 0) >> 0] = 1; - HEAP32[(0 + 1051800 | 0) >> 2] = (HEAP32[(0 + 1051800 | 0) >> 2] | 0) + 1 | 0; - $6 = HEAP32[(0 + 1051332 | 0) >> 2] | 0; - if (($6 | 0) <= (-1 | 0)) { - break label$2 - } - HEAP32[(0 + 1051332 | 0) >> 2] = $6 + 1 | 0; - label$3 : { - if (!(HEAP32[(0 + 1051336 | 0) >> 2] | 0)) { - break label$3 - } - FUNCTION_TABLE[HEAP32[($1 + 20 | 0) >> 2] | 0 | 0]($5 + 8 | 0, $0); - HEAP8[($5 + 29 | 0) >> 0] = $4; - HEAP8[($5 + 28 | 0) >> 0] = $3; - HEAP32[($5 + 24 | 0) >> 2] = $2; - i64toi32_i32$1 = HEAP32[($5 + 12 | 0) >> 2] | 0; - HEAP32[($5 + 16 | 0) >> 2] = HEAP32[($5 + 8 | 0) >> 2] | 0; - HEAP32[($5 + 20 | 0) >> 2] = i64toi32_i32$1; - FUNCTION_TABLE[HEAP32[((HEAP32[(0 + 1051340 | 0) >> 2] | 0) + 20 | 0) >> 2] | 0 | 0](HEAP32[(0 + 1051336 | 0) >> 2] | 0, $5 + 16 | 0); - $6 = (HEAP32[(0 + 1051332 | 0) >> 2] | 0) + -1 | 0; - } - HEAP32[(0 + 1051332 | 0) >> 2] = $6; - HEAP8[(0 + 1051804 | 0) >> 0] = 0; - if (!$3) { - break label$2 - } - rust_panic($0 | 0, $1 | 0); - } - wasm2js_trap(); - } - FUNCTION_TABLE[HEAP32[($1 + 24 | 0) >> 2] | 0 | 0]($5, $0); - wasm2js_trap(); - } - - function rust_panic($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - __rust_start_panic($0 | 0, $1 | 0) | 0; - wasm2js_trap(); - } - - function __rg_oom($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - var $2 = 0; - $2 = HEAP32[(0 + 1051328 | 0) >> 2] | 0; - FUNCTION_TABLE[($2 ? $2 : 2) | 0]($1, $0); - wasm2js_trap(); - } - - function __rust_start_panic($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - wasm2js_trap(); - } - - function _ZN61_$LT$dlmalloc__sys__System$u20$as$u20$dlmalloc__Allocator$GT$5alloc17hb2750b8aaf9916efE($0, $1, $2) { - $0 = $0 | 0; - $1 = $1 | 0; - $2 = $2 | 0; - var $3 = 0, $10 = 0; - $3 = __wasm_memory_grow($2 >>> 16 | 0 | 0); - HEAP32[($0 + 8 | 0) >> 2] = 0; - $10 = $2 & -65536 | 0; - $2 = ($3 | 0) == (-1 | 0); - HEAP32[($0 + 4 | 0) >> 2] = $2 ? 0 : $10; - HEAP32[$0 >> 2] = $2 ? 0 : $3 << 16 | 0; - } - - function _ZN4core3fmt5Write9write_fmt17h12c6d34f0ecf8d3dE($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - return _ZN4core3fmt5write17hd273a061a774381dE($0 | 0, 1048948 | 0, $1 | 0) | 0 | 0; - } - - function _ZN4core3ptr42drop_in_place$LT$alloc__string__String$GT$17h0f9d5bab53e46359E($0) { - $0 = $0 | 0; - var $1 = 0; - label$1 : { - $1 = HEAP32[$0 >> 2] | 0; - if (!$1) { - break label$1 - } - __rust_dealloc(HEAP32[($0 + 4 | 0) >> 2] | 0 | 0, $1 | 0, 1 | 0); - } - } - - function _ZN53_$LT$core__fmt__Error$u20$as$u20$core__fmt__Debug$GT$3fmt17hc7b9dec108bfb98cE($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - return _ZN4core3fmt9Formatter9write_str17h7b04ca2eef2f5010E($1 | 0, 1048940 | 0, 5 | 0) | 0 | 0; - } - - function _ZN5alloc7raw_vec17capacity_overflow17hf270d28094a4efafE() { - var $0 = 0; - $0 = __stack_pointer - 32 | 0; - __stack_pointer = $0; - HEAP32[($0 + 24 | 0) >> 2] = 0; - HEAP32[($0 + 12 | 0) >> 2] = 1; - HEAP32[($0 + 8 | 0) >> 2] = 1048992; - HEAP32[($0 + 16 | 0) >> 2] = 4; - HEAP32[($0 + 20 | 0) >> 2] = 0; - _ZN4core9panicking9panic_fmt17hb2f16849466f57b6E($0 + 8 | 0 | 0, 1049020 | 0); - wasm2js_trap(); - } - - function _ZN5alloc7raw_vec19RawVec$LT$T$C$A$GT$7reserve21do_reserve_and_handle17h1929fa6bfa2184fdE($0, $1, $2) { - $0 = $0 | 0; - $1 = $1 | 0; - $2 = $2 | 0; - var $3 = 0, $4 = 0; - $3 = __stack_pointer - 32 | 0; - __stack_pointer = $3; - label$1 : { - $2 = $1 + $2 | 0; - if ($2 >>> 0 >= $1 >>> 0) { - break label$1 - } - _ZN5alloc7raw_vec12handle_error17h7f22430f64ae98acE(0 | 0, 0 | 0); - wasm2js_trap(); - } - $4 = HEAP32[$0 >> 2] | 0; - $1 = $4 << 1 | 0; - $1 = $1 >>> 0 > $2 >>> 0 ? $1 : $2; - $1 = $1 >>> 0 > 8 >>> 0 ? $1 : 8; - $2 = ($1 ^ -1 | 0) >>> 31 | 0; - label$2 : { - label$3 : { - if ($4) { - break label$3 - } - $4 = 0; - break label$2; - } - HEAP32[($3 + 28 | 0) >> 2] = $4; - HEAP32[($3 + 20 | 0) >> 2] = HEAP32[($0 + 4 | 0) >> 2] | 0; - $4 = 1; - } - HEAP32[($3 + 24 | 0) >> 2] = $4; - _ZN5alloc7raw_vec11finish_grow17h7b9ce5ade3738748E($3 + 8 | 0 | 0, $2 | 0, $1 | 0, $3 + 20 | 0 | 0); - label$4 : { - if ((HEAP32[($3 + 8 | 0) >> 2] | 0 | 0) != (1 | 0)) { - break label$4 - } - _ZN5alloc7raw_vec12handle_error17h7f22430f64ae98acE(HEAP32[($3 + 12 | 0) >> 2] | 0 | 0, HEAP32[($3 + 16 | 0) >> 2] | 0 | 0); - wasm2js_trap(); - } - $2 = HEAP32[($3 + 12 | 0) >> 2] | 0; - HEAP32[$0 >> 2] = $1; - HEAP32[($0 + 4 | 0) >> 2] = $2; - __stack_pointer = $3 + 32 | 0; - } - - function _ZN5alloc7raw_vec12handle_error17h7f22430f64ae98acE($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - label$1 : { - if ($0) { - break label$1 - } - _ZN5alloc7raw_vec17capacity_overflow17hf270d28094a4efafE(); - wasm2js_trap(); - } - _ZN5alloc5alloc18handle_alloc_error17h123ae56be4092711E($0 | 0, $1 | 0); - wasm2js_trap(); - } - - function _ZN5alloc7raw_vec11finish_grow17h7b9ce5ade3738748E($0, $1, $2, $3) { - $0 = $0 | 0; - $1 = $1 | 0; - $2 = $2 | 0; - $3 = $3 | 0; - var $4 = 0, $5 = 0, $6 = 0; - $4 = 1; - $5 = 0; - $6 = 4; - label$1 : { - if (!$1) { - break label$1 - } - if (($2 | 0) < (0 | 0)) { - break label$1 - } - label$2 : { - label$3 : { - label$4 : { - label$5 : { - label$6 : { - if (!(HEAP32[($3 + 4 | 0) >> 2] | 0)) { - break label$6 - } - label$7 : { - $4 = HEAP32[($3 + 8 | 0) >> 2] | 0; - if ($4) { - break label$7 - } - label$8 : { - if ($2) { - break label$8 - } - $4 = 1; - break label$4; - } - HEAPU8[(0 + 1051325 | 0) >> 0] | 0; - $4 = __rust_alloc($2 | 0, 1 | 0) | 0; - break label$5; - } - $4 = __rust_realloc(HEAP32[$3 >> 2] | 0 | 0, $4 | 0, 1 | 0, $2 | 0) | 0; - break label$5; - } - label$9 : { - if ($2) { - break label$9 - } - $4 = 1; - break label$4; - } - HEAPU8[(0 + 1051325 | 0) >> 0] | 0; - $4 = __rust_alloc($2 | 0, 1 | 0) | 0; - } - if (!$4) { - break label$3 - } - } - HEAP32[($0 + 4 | 0) >> 2] = $4; - $4 = 0; - break label$2; - } - $4 = 1; - HEAP32[($0 + 4 | 0) >> 2] = 1; - } - $6 = 8; - $5 = $2; - } - HEAP32[($0 + $6 | 0) >> 2] = $5; - HEAP32[$0 >> 2] = $4; - } - - function _ZN5alloc7raw_vec19RawVec$LT$T$C$A$GT$8grow_one17h1fc259ca8e381992E($0) { - $0 = $0 | 0; - var $1 = 0, $2 = 0, $3 = 0, $4 = 0; - $1 = __stack_pointer - 32 | 0; - __stack_pointer = $1; - label$1 : { - $2 = HEAP32[$0 >> 2] | 0; - if (($2 | 0) != (-1 | 0)) { - break label$1 - } - _ZN5alloc7raw_vec12handle_error17h7f22430f64ae98acE(0 | 0, 0 | 0); - wasm2js_trap(); - } - $3 = $2 << 1 | 0; - $4 = $2 + 1 | 0; - $3 = $3 >>> 0 > $4 >>> 0 ? $3 : $4; - $3 = $3 >>> 0 > 8 >>> 0 ? $3 : 8; - $4 = ($3 ^ -1 | 0) >>> 31 | 0; - label$2 : { - label$3 : { - if ($2) { - break label$3 - } - $2 = 0; - break label$2; - } - HEAP32[($1 + 28 | 0) >> 2] = $2; - HEAP32[($1 + 20 | 0) >> 2] = HEAP32[($0 + 4 | 0) >> 2] | 0; - $2 = 1; - } - HEAP32[($1 + 24 | 0) >> 2] = $2; - _ZN5alloc7raw_vec11finish_grow17h7b9ce5ade3738748E($1 + 8 | 0 | 0, $4 | 0, $3 | 0, $1 + 20 | 0 | 0); - label$4 : { - if ((HEAP32[($1 + 8 | 0) >> 2] | 0 | 0) != (1 | 0)) { - break label$4 - } - _ZN5alloc7raw_vec12handle_error17h7f22430f64ae98acE(HEAP32[($1 + 12 | 0) >> 2] | 0 | 0, HEAP32[($1 + 16 | 0) >> 2] | 0 | 0); - wasm2js_trap(); - } - $2 = HEAP32[($1 + 12 | 0) >> 2] | 0; - HEAP32[$0 >> 2] = $3; - HEAP32[($0 + 4 | 0) >> 2] = $2; - __stack_pointer = $1 + 32 | 0; - } - - function _ZN5alloc5alloc18handle_alloc_error17h123ae56be4092711E($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - __rust_alloc_error_handler($1 | 0, $0 | 0); - wasm2js_trap(); - } - - function _ZN5alloc3fmt6format12format_inner17hfada08777d0a48e9E($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - var $3 = 0, $7 = 0, $2 = 0, $5 = 0, $6 = 0, i64toi32_i32$0 = 0, $4 = 0, $8 = 0, i64toi32_i32$1 = 0, $101 = 0; - $2 = __stack_pointer - 16 | 0; - __stack_pointer = $2; - label$1 : { - label$2 : { - label$3 : { - label$4 : { - label$5 : { - $3 = HEAP32[($1 + 4 | 0) >> 2] | 0; - if (!$3) { - break label$5 - } - $4 = HEAP32[$1 >> 2] | 0; - $5 = $3 & 3 | 0; - label$6 : { - label$7 : { - if ($3 >>> 0 >= 4 >>> 0) { - break label$7 - } - $3 = 0; - $6 = 0; - break label$6; - } - $7 = $4 + 28 | 0; - $8 = $3 & -4 | 0; - $3 = 0; - $6 = 0; - label$8 : while (1) { - $3 = (HEAP32[$7 >> 2] | 0) + ((HEAP32[($7 + -8 | 0) >> 2] | 0) + ((HEAP32[($7 + -16 | 0) >> 2] | 0) + ((HEAP32[($7 + -24 | 0) >> 2] | 0) + $3 | 0) | 0) | 0) | 0; - $7 = $7 + 32 | 0; - $6 = $6 + 4 | 0; - if (($8 | 0) != ($6 | 0)) { - continue label$8 - } - break label$8; - }; - } - label$9 : { - if (!$5) { - break label$9 - } - $7 = (($6 << 3 | 0) + $4 | 0) + 4 | 0; - label$10 : while (1) { - $3 = (HEAP32[$7 >> 2] | 0) + $3 | 0; - $7 = $7 + 8 | 0; - $5 = $5 + -1 | 0; - if ($5) { - continue label$10 - } - break label$10; - }; - } - label$11 : { - if (!(HEAP32[($1 + 12 | 0) >> 2] | 0)) { - break label$11 - } - if (($3 | 0) < (0 | 0)) { - break label$5 - } - if ($3 >>> 0 < 16 >>> 0 & !(HEAP32[($4 + 4 | 0) >> 2] | 0) | 0) { - break label$5 - } - $3 = $3 << 1 | 0; - } - if ($3) { - break label$4 - } - } - $7 = 1; - $3 = 0; - break label$3; - } - $5 = 0; - if (($3 | 0) < (0 | 0)) { - break label$2 - } - HEAPU8[(0 + 1051325 | 0) >> 0] | 0; - $5 = 1; - $7 = __rust_alloc($3 | 0, 1 | 0) | 0; - if (!$7) { - break label$2 - } - } - HEAP32[($2 + 8 | 0) >> 2] = 0; - HEAP32[($2 + 4 | 0) >> 2] = $7; - HEAP32[$2 >> 2] = $3; - if (!(_ZN4core3fmt5write17hd273a061a774381dE($2 | 0, 1048948 | 0, $1 | 0) | 0)) { - break label$1 - } - _ZN4core6result13unwrap_failed17h63e31ad259971ff4E(1049052 | 0, 86 | 0, $2 + 15 | 0 | 0, 1049036 | 0, 1049156 | 0); - wasm2js_trap(); - } - _ZN5alloc7raw_vec12handle_error17h7f22430f64ae98acE($5 | 0, $3 | 0); - wasm2js_trap(); - } - i64toi32_i32$0 = HEAP32[$2 >> 2] | 0; - i64toi32_i32$1 = HEAP32[($2 + 4 | 0) >> 2] | 0; - $101 = i64toi32_i32$0; - i64toi32_i32$0 = $0; - HEAP32[i64toi32_i32$0 >> 2] = $101; - HEAP32[(i64toi32_i32$0 + 4 | 0) >> 2] = i64toi32_i32$1; - HEAP32[(i64toi32_i32$0 + 8 | 0) >> 2] = HEAP32[($2 + 8 | 0) >> 2] | 0; - __stack_pointer = $2 + 16 | 0; - } - - function _ZN5alloc6string6String4push17heffbdde4b7aa7c44E($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - var $2 = 0, $3 = 0; - $2 = __stack_pointer - 16 | 0; - __stack_pointer = $2; - label$1 : { - label$2 : { - label$3 : { - label$4 : { - if ($1 >>> 0 < 128 >>> 0) { - break label$4 - } - HEAP32[($2 + 12 | 0) >> 2] = 0; - if ($1 >>> 0 < 2048 >>> 0) { - break label$3 - } - label$5 : { - if ($1 >>> 0 >= 65536 >>> 0) { - break label$5 - } - HEAP8[($2 + 14 | 0) >> 0] = $1 & 63 | 0 | 128 | 0; - HEAP8[($2 + 12 | 0) >> 0] = $1 >>> 12 | 0 | 224 | 0; - HEAP8[($2 + 13 | 0) >> 0] = ($1 >>> 6 | 0) & 63 | 0 | 128 | 0; - $1 = 3; - break label$2; - } - HEAP8[($2 + 15 | 0) >> 0] = $1 & 63 | 0 | 128 | 0; - HEAP8[($2 + 12 | 0) >> 0] = $1 >>> 18 | 0 | 240 | 0; - HEAP8[($2 + 14 | 0) >> 0] = ($1 >>> 6 | 0) & 63 | 0 | 128 | 0; - HEAP8[($2 + 13 | 0) >> 0] = ($1 >>> 12 | 0) & 63 | 0 | 128 | 0; - $1 = 4; - break label$2; - } - label$6 : { - $3 = HEAP32[($0 + 8 | 0) >> 2] | 0; - if (($3 | 0) != (HEAP32[$0 >> 2] | 0 | 0)) { - break label$6 - } - _ZN5alloc7raw_vec19RawVec$LT$T$C$A$GT$8grow_one17h1fc259ca8e381992E($0 | 0); - } - HEAP32[($0 + 8 | 0) >> 2] = $3 + 1 | 0; - HEAP8[((HEAP32[($0 + 4 | 0) >> 2] | 0) + $3 | 0) >> 0] = $1; - break label$1; - } - HEAP8[($2 + 13 | 0) >> 0] = $1 & 63 | 0 | 128 | 0; - HEAP8[($2 + 12 | 0) >> 0] = $1 >>> 6 | 0 | 192 | 0; - $1 = 2; - } - label$7 : { - $3 = HEAP32[($0 + 8 | 0) >> 2] | 0; - if (((HEAP32[$0 >> 2] | 0) - $3 | 0) >>> 0 >= $1 >>> 0) { - break label$7 - } - _ZN5alloc7raw_vec19RawVec$LT$T$C$A$GT$7reserve21do_reserve_and_handle17h1929fa6bfa2184fdE($0 | 0, $3 | 0, $1 | 0); - $3 = HEAP32[($0 + 8 | 0) >> 2] | 0; - } - memcpy((HEAP32[($0 + 4 | 0) >> 2] | 0) + $3 | 0 | 0, $2 + 12 | 0 | 0, $1 | 0) | 0; - HEAP32[($0 + 8 | 0) >> 2] = $3 + $1 | 0; - } - __stack_pointer = $2 + 16 | 0; - } - - function _ZN58_$LT$alloc__string__String$u20$as$u20$core__fmt__Write$GT$9write_str17h9c2d3e9aafc08637E_52($0, $1, $2) { - $0 = $0 | 0; - $1 = $1 | 0; - $2 = $2 | 0; - var $3 = 0; - label$1 : { - $3 = HEAP32[($0 + 8 | 0) >> 2] | 0; - if (((HEAP32[$0 >> 2] | 0) - $3 | 0) >>> 0 >= $2 >>> 0) { - break label$1 - } - _ZN5alloc7raw_vec19RawVec$LT$T$C$A$GT$7reserve21do_reserve_and_handle17h1929fa6bfa2184fdE($0 | 0, $3 | 0, $2 | 0); - $3 = HEAP32[($0 + 8 | 0) >> 2] | 0; - } - memcpy((HEAP32[($0 + 4 | 0) >> 2] | 0) + $3 | 0 | 0, $1 | 0, $2 | 0) | 0; - HEAP32[($0 + 8 | 0) >> 2] = $3 + $2 | 0; - return 0 | 0; - } - - function _ZN58_$LT$alloc__string__String$u20$as$u20$core__fmt__Write$GT$10write_char17h9231f70fbd335441E_53($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - _ZN5alloc6string6String4push17heffbdde4b7aa7c44E($0 | 0, $1 | 0); - return 0 | 0; - } - - function _ZN4core9panicking9panic_fmt17hb2f16849466f57b6E($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - var i64toi32_i32$0 = 0, i64toi32_i32$2 = 0, i64toi32_i32$1 = 0, $2 = 0, $10 = 0, $15 = 0, $21 = 0; - $2 = __stack_pointer - 32 | 0; - __stack_pointer = $2; - i64toi32_i32$2 = $0 + 16 | 0; - i64toi32_i32$0 = HEAP32[i64toi32_i32$2 >> 2] | 0; - i64toi32_i32$1 = HEAP32[(i64toi32_i32$2 + 4 | 0) >> 2] | 0; - $10 = i64toi32_i32$0; - i64toi32_i32$0 = $2 + 16 | 0; - HEAP32[i64toi32_i32$0 >> 2] = $10; - HEAP32[(i64toi32_i32$0 + 4 | 0) >> 2] = i64toi32_i32$1; - i64toi32_i32$2 = $0 + 8 | 0; - i64toi32_i32$1 = HEAP32[i64toi32_i32$2 >> 2] | 0; - i64toi32_i32$0 = HEAP32[(i64toi32_i32$2 + 4 | 0) >> 2] | 0; - $15 = i64toi32_i32$1; - i64toi32_i32$1 = $2 + 8 | 0; - HEAP32[i64toi32_i32$1 >> 2] = $15; - HEAP32[(i64toi32_i32$1 + 4 | 0) >> 2] = i64toi32_i32$0; - HEAP16[($2 + 28 | 0) >> 1] = 1; - HEAP32[($2 + 24 | 0) >> 2] = $1; - i64toi32_i32$2 = $0; - i64toi32_i32$0 = HEAP32[i64toi32_i32$2 >> 2] | 0; - i64toi32_i32$1 = HEAP32[(i64toi32_i32$2 + 4 | 0) >> 2] | 0; - $21 = i64toi32_i32$0; - i64toi32_i32$0 = $2; - HEAP32[i64toi32_i32$0 >> 2] = $21; - HEAP32[(i64toi32_i32$0 + 4 | 0) >> 2] = i64toi32_i32$1; - rust_begin_unwind(i64toi32_i32$0 | 0); - wasm2js_trap(); - } - - function _ZN4core5slice5index26slice_start_index_len_fail17h65432e022682bf05E($0, $1, $2) { - $0 = $0 | 0; - $1 = $1 | 0; - $2 = $2 | 0; - var $3 = 0, i64toi32_i32$1 = 0, i64toi32_i32$0 = 0, i64toi32_i32$2 = 0, i64toi32_i32$3 = 0, i64toi32_i32$4 = 0, $16 = 0, $4 = 0, $15 = 0, $4$hi = 0, $21$hi = 0, $22 = 0, $26$hi = 0, $27 = 0; - $3 = __stack_pointer - 48 | 0; - __stack_pointer = $3; - HEAP32[$3 >> 2] = $0; - HEAP32[($3 + 4 | 0) >> 2] = $1; - HEAP32[($3 + 12 | 0) >> 2] = 2; - HEAP32[($3 + 8 | 0) >> 2] = 1049632; - i64toi32_i32$1 = $3; - i64toi32_i32$0 = 0; - HEAP32[($3 + 20 | 0) >> 2] = 2; - HEAP32[($3 + 24 | 0) >> 2] = i64toi32_i32$0; - $15 = $3; - i64toi32_i32$0 = 0; - i64toi32_i32$2 = 1; - i64toi32_i32$1 = 0; - i64toi32_i32$3 = 32; - i64toi32_i32$4 = i64toi32_i32$3 & 31 | 0; - if (32 >>> 0 <= (i64toi32_i32$3 & 63 | 0) >>> 0) { - i64toi32_i32$1 = i64toi32_i32$2 << i64toi32_i32$4 | 0; - $16 = 0; - } else { - i64toi32_i32$1 = ((1 << i64toi32_i32$4 | 0) - 1 | 0) & (i64toi32_i32$2 >>> (32 - i64toi32_i32$4 | 0) | 0) | 0 | (i64toi32_i32$0 << i64toi32_i32$4 | 0) | 0; - $16 = i64toi32_i32$2 << i64toi32_i32$4 | 0; - } - $4 = $16; - $4$hi = i64toi32_i32$1; - i64toi32_i32$1 = 0; - $21$hi = i64toi32_i32$1; - i64toi32_i32$1 = $4$hi; - i64toi32_i32$0 = $4; - i64toi32_i32$2 = $21$hi; - i64toi32_i32$3 = $3 + 4 | 0; - i64toi32_i32$2 = i64toi32_i32$1 | i64toi32_i32$2 | 0; - $22 = i64toi32_i32$0 | i64toi32_i32$3 | 0; - i64toi32_i32$0 = $15; - HEAP32[(i64toi32_i32$0 + 40 | 0) >> 2] = $22; - HEAP32[(i64toi32_i32$0 + 44 | 0) >> 2] = i64toi32_i32$2; - i64toi32_i32$2 = i64toi32_i32$1; - i64toi32_i32$2 = 0; - $26$hi = i64toi32_i32$2; - i64toi32_i32$2 = i64toi32_i32$1; - i64toi32_i32$1 = $4; - i64toi32_i32$0 = $26$hi; - i64toi32_i32$3 = $3; - i64toi32_i32$0 = i64toi32_i32$2 | i64toi32_i32$0 | 0; - $27 = i64toi32_i32$1 | $3 | 0; - i64toi32_i32$1 = $3; - HEAP32[($3 + 32 | 0) >> 2] = $27; - HEAP32[($3 + 36 | 0) >> 2] = i64toi32_i32$0; - HEAP32[($3 + 16 | 0) >> 2] = $3 + 32 | 0; - _ZN4core9panicking9panic_fmt17hb2f16849466f57b6E($3 + 8 | 0 | 0, $2 | 0); - wasm2js_trap(); - } - - function _ZN4core9panicking18panic_bounds_check17hb583f390c1467acdE($0, $1, $2) { - $0 = $0 | 0; - $1 = $1 | 0; - $2 = $2 | 0; - var $3 = 0, i64toi32_i32$1 = 0, i64toi32_i32$0 = 0, i64toi32_i32$2 = 0, i64toi32_i32$3 = 0, i64toi32_i32$4 = 0, $16 = 0, $4 = 0, $15 = 0, $4$hi = 0, $20$hi = 0, $21 = 0, $26$hi = 0, $27 = 0; - $3 = __stack_pointer - 48 | 0; - __stack_pointer = $3; - HEAP32[($3 + 4 | 0) >> 2] = $1; - HEAP32[$3 >> 2] = $0; - HEAP32[($3 + 12 | 0) >> 2] = 2; - HEAP32[($3 + 8 | 0) >> 2] = 1049268; - i64toi32_i32$1 = $3; - i64toi32_i32$0 = 0; - HEAP32[($3 + 20 | 0) >> 2] = 2; - HEAP32[($3 + 24 | 0) >> 2] = i64toi32_i32$0; - $15 = $3; - i64toi32_i32$0 = 0; - i64toi32_i32$2 = 1; - i64toi32_i32$1 = 0; - i64toi32_i32$3 = 32; - i64toi32_i32$4 = i64toi32_i32$3 & 31 | 0; - if (32 >>> 0 <= (i64toi32_i32$3 & 63 | 0) >>> 0) { - i64toi32_i32$1 = i64toi32_i32$2 << i64toi32_i32$4 | 0; - $16 = 0; - } else { - i64toi32_i32$1 = ((1 << i64toi32_i32$4 | 0) - 1 | 0) & (i64toi32_i32$2 >>> (32 - i64toi32_i32$4 | 0) | 0) | 0 | (i64toi32_i32$0 << i64toi32_i32$4 | 0) | 0; - $16 = i64toi32_i32$2 << i64toi32_i32$4 | 0; - } - $4 = $16; - $4$hi = i64toi32_i32$1; - i64toi32_i32$1 = 0; - $20$hi = i64toi32_i32$1; - i64toi32_i32$1 = $4$hi; - i64toi32_i32$0 = $4; - i64toi32_i32$2 = $20$hi; - i64toi32_i32$3 = $3; - i64toi32_i32$2 = i64toi32_i32$1 | i64toi32_i32$2 | 0; - $21 = i64toi32_i32$0 | $3 | 0; - i64toi32_i32$0 = $15; - HEAP32[(i64toi32_i32$0 + 40 | 0) >> 2] = $21; - HEAP32[(i64toi32_i32$0 + 44 | 0) >> 2] = i64toi32_i32$2; - i64toi32_i32$2 = i64toi32_i32$1; - i64toi32_i32$2 = 0; - $26$hi = i64toi32_i32$2; - i64toi32_i32$2 = i64toi32_i32$1; - i64toi32_i32$1 = $4; - i64toi32_i32$0 = $26$hi; - i64toi32_i32$3 = $3 + 4 | 0; - i64toi32_i32$0 = i64toi32_i32$2 | i64toi32_i32$0 | 0; - $27 = i64toi32_i32$1 | i64toi32_i32$3 | 0; - i64toi32_i32$1 = $3; - HEAP32[($3 + 32 | 0) >> 2] = $27; - HEAP32[($3 + 36 | 0) >> 2] = i64toi32_i32$0; - HEAP32[($3 + 16 | 0) >> 2] = $3 + 32 | 0; - _ZN4core9panicking9panic_fmt17hb2f16849466f57b6E($3 + 8 | 0 | 0, $2 | 0); - wasm2js_trap(); - } - - function _ZN4core5slice5index24slice_end_index_len_fail17h02d344349d5072f8E($0, $1, $2) { - $0 = $0 | 0; - $1 = $1 | 0; - $2 = $2 | 0; - var $3 = 0, i64toi32_i32$1 = 0, i64toi32_i32$0 = 0, i64toi32_i32$2 = 0, i64toi32_i32$3 = 0, i64toi32_i32$4 = 0, $16 = 0, $4 = 0, $15 = 0, $4$hi = 0, $21$hi = 0, $22 = 0, $26$hi = 0, $27 = 0; - $3 = __stack_pointer - 48 | 0; - __stack_pointer = $3; - HEAP32[$3 >> 2] = $0; - HEAP32[($3 + 4 | 0) >> 2] = $1; - HEAP32[($3 + 12 | 0) >> 2] = 2; - HEAP32[($3 + 8 | 0) >> 2] = 1049664; - i64toi32_i32$1 = $3; - i64toi32_i32$0 = 0; - HEAP32[($3 + 20 | 0) >> 2] = 2; - HEAP32[($3 + 24 | 0) >> 2] = i64toi32_i32$0; - $15 = $3; - i64toi32_i32$0 = 0; - i64toi32_i32$2 = 1; - i64toi32_i32$1 = 0; - i64toi32_i32$3 = 32; - i64toi32_i32$4 = i64toi32_i32$3 & 31 | 0; - if (32 >>> 0 <= (i64toi32_i32$3 & 63 | 0) >>> 0) { - i64toi32_i32$1 = i64toi32_i32$2 << i64toi32_i32$4 | 0; - $16 = 0; - } else { - i64toi32_i32$1 = ((1 << i64toi32_i32$4 | 0) - 1 | 0) & (i64toi32_i32$2 >>> (32 - i64toi32_i32$4 | 0) | 0) | 0 | (i64toi32_i32$0 << i64toi32_i32$4 | 0) | 0; - $16 = i64toi32_i32$2 << i64toi32_i32$4 | 0; - } - $4 = $16; - $4$hi = i64toi32_i32$1; - i64toi32_i32$1 = 0; - $21$hi = i64toi32_i32$1; - i64toi32_i32$1 = $4$hi; - i64toi32_i32$0 = $4; - i64toi32_i32$2 = $21$hi; - i64toi32_i32$3 = $3 + 4 | 0; - i64toi32_i32$2 = i64toi32_i32$1 | i64toi32_i32$2 | 0; - $22 = i64toi32_i32$0 | i64toi32_i32$3 | 0; - i64toi32_i32$0 = $15; - HEAP32[(i64toi32_i32$0 + 40 | 0) >> 2] = $22; - HEAP32[(i64toi32_i32$0 + 44 | 0) >> 2] = i64toi32_i32$2; - i64toi32_i32$2 = i64toi32_i32$1; - i64toi32_i32$2 = 0; - $26$hi = i64toi32_i32$2; - i64toi32_i32$2 = i64toi32_i32$1; - i64toi32_i32$1 = $4; - i64toi32_i32$0 = $26$hi; - i64toi32_i32$3 = $3; - i64toi32_i32$0 = i64toi32_i32$2 | i64toi32_i32$0 | 0; - $27 = i64toi32_i32$1 | $3 | 0; - i64toi32_i32$1 = $3; - HEAP32[($3 + 32 | 0) >> 2] = $27; - HEAP32[($3 + 36 | 0) >> 2] = i64toi32_i32$0; - HEAP32[($3 + 16 | 0) >> 2] = $3 + 32 | 0; - _ZN4core9panicking9panic_fmt17hb2f16849466f57b6E($3 + 8 | 0 | 0, $2 | 0); - wasm2js_trap(); - } - - function _ZN4core3fmt9Formatter3pad17hc540d40003d38a61E($0, $1, $2) { - $0 = $0 | 0; - $1 = $1 | 0; - $2 = $2 | 0; - var $3 = 0, $8 = 0, $7 = 0, $5 = 0, $6 = 0, $4 = 0; - $3 = HEAP32[($0 + 8 | 0) >> 2] | 0; - label$1 : { - label$2 : { - $4 = HEAP32[$0 >> 2] | 0; - if ($4) { - break label$2 - } - if (!($3 & 1 | 0)) { - break label$1 - } - } - label$3 : { - if (!($3 & 1 | 0)) { - break label$3 - } - $5 = $1 + $2 | 0; - label$4 : { - label$5 : { - $6 = HEAP32[($0 + 12 | 0) >> 2] | 0; - if ($6) { - break label$5 - } - $7 = 0; - $8 = $1; - break label$4; - } - $7 = 0; - $8 = $1; - label$6 : while (1) { - $3 = $8; - if (($3 | 0) == ($5 | 0)) { - break label$3 - } - label$7 : { - label$8 : { - $8 = HEAP8[$3 >> 0] | 0; - if (($8 | 0) <= (-1 | 0)) { - break label$8 - } - $8 = $3 + 1 | 0; - break label$7; - } - label$9 : { - if ($8 >>> 0 >= -32 >>> 0) { - break label$9 - } - $8 = $3 + 2 | 0; - break label$7; - } - label$10 : { - if ($8 >>> 0 >= -16 >>> 0) { - break label$10 - } - $8 = $3 + 3 | 0; - break label$7; - } - $8 = $3 + 4 | 0; - } - $7 = ($8 - $3 | 0) + $7 | 0; - $6 = $6 + -1 | 0; - if ($6) { - continue label$6 - } - break label$6; - }; - } - if (($8 | 0) == ($5 | 0)) { - break label$3 - } - label$11 : { - $3 = HEAP8[$8 >> 0] | 0; - if (($3 | 0) > (-1 | 0)) { - break label$11 - } - } - label$12 : { - label$13 : { - if (!$7) { - break label$13 - } - label$14 : { - if ($7 >>> 0 >= $2 >>> 0) { - break label$14 - } - if ((HEAP8[($1 + $7 | 0) >> 0] | 0 | 0) > (-65 | 0)) { - break label$13 - } - $3 = 0; - break label$12; - } - if (($7 | 0) == ($2 | 0)) { - break label$13 - } - $3 = 0; - break label$12; - } - $3 = $1; - } - $2 = $3 ? $7 : $2; - $1 = $3 ? $3 : $1; - } - label$15 : { - if ($4) { - break label$15 - } - return FUNCTION_TABLE[HEAP32[((HEAP32[($0 + 24 | 0) >> 2] | 0) + 12 | 0) >> 2] | 0 | 0](HEAP32[($0 + 20 | 0) >> 2] | 0, $1, $2) | 0 | 0; - } - $4 = HEAP32[($0 + 4 | 0) >> 2] | 0; - label$16 : { - label$17 : { - if ($2 >>> 0 < 16 >>> 0) { - break label$17 - } - $3 = _ZN4core3str5count14do_count_chars17h03769f4f70ff5154E($1 | 0, $2 | 0) | 0; - break label$16; - } - label$18 : { - if ($2) { - break label$18 - } - $3 = 0; - break label$16; - } - $6 = $2 & 3 | 0; - label$19 : { - label$20 : { - if ($2 >>> 0 >= 4 >>> 0) { - break label$20 - } - $3 = 0; - $7 = 0; - break label$19; - } - $5 = $2 & 12 | 0; - $3 = 0; - $7 = 0; - label$21 : while (1) { - $8 = $1 + $7 | 0; - $3 = ((($3 + ((HEAP8[$8 >> 0] | 0 | 0) > (-65 | 0)) | 0) + ((HEAP8[($8 + 1 | 0) >> 0] | 0 | 0) > (-65 | 0)) | 0) + ((HEAP8[($8 + 2 | 0) >> 0] | 0 | 0) > (-65 | 0)) | 0) + ((HEAP8[($8 + 3 | 0) >> 0] | 0 | 0) > (-65 | 0)) | 0; - $7 = $7 + 4 | 0; - if (($5 | 0) != ($7 | 0)) { - continue label$21 - } - break label$21; - }; - } - if (!$6) { - break label$16 - } - $8 = $1 + $7 | 0; - label$22 : while (1) { - $3 = $3 + ((HEAP8[$8 >> 0] | 0 | 0) > (-65 | 0)) | 0; - $8 = $8 + 1 | 0; - $6 = $6 + -1 | 0; - if ($6) { - continue label$22 - } - break label$22; - }; - } - label$23 : { - label$24 : { - if ($4 >>> 0 <= $3 >>> 0) { - break label$24 - } - $5 = $4 - $3 | 0; - $3 = 0; - label$25 : { - label$26 : { - switch (HEAPU8[($0 + 32 | 0) >> 0] | 0 | 0) { - case 1: - $3 = $5; - $5 = 0; - break label$25; - case 2: - break label$26; - default: - break label$25; - }; - } - $3 = $5 >>> 1 | 0; - $5 = ($5 + 1 | 0) >>> 1 | 0; - } - $3 = $3 + 1 | 0; - $6 = HEAP32[($0 + 16 | 0) >> 2] | 0; - $8 = HEAP32[($0 + 24 | 0) >> 2] | 0; - $7 = HEAP32[($0 + 20 | 0) >> 2] | 0; - label$28 : while (1) { - $3 = $3 + -1 | 0; - if (!$3) { - break label$23 - } - if (!(FUNCTION_TABLE[HEAP32[($8 + 16 | 0) >> 2] | 0 | 0]($7, $6) | 0)) { - continue label$28 - } - break label$28; - }; - return 1 | 0; - } - return FUNCTION_TABLE[HEAP32[((HEAP32[($0 + 24 | 0) >> 2] | 0) + 12 | 0) >> 2] | 0 | 0](HEAP32[($0 + 20 | 0) >> 2] | 0, $1, $2) | 0 | 0; - } - label$29 : { - if (!(FUNCTION_TABLE[HEAP32[($8 + 12 | 0) >> 2] | 0 | 0]($7, $1, $2) | 0)) { - break label$29 - } - return 1 | 0; - } - $3 = 0; - label$30 : while (1) { - label$31 : { - if (($5 | 0) != ($3 | 0)) { - break label$31 - } - return $5 >>> 0 < $5 >>> 0 | 0; - } - $3 = $3 + 1 | 0; - if (!(FUNCTION_TABLE[HEAP32[($8 + 16 | 0) >> 2] | 0 | 0]($7, $6) | 0)) { - continue label$30 - } - break label$30; - }; - return ($3 + -1 | 0) >>> 0 < $5 >>> 0 | 0; - } - return FUNCTION_TABLE[HEAP32[((HEAP32[($0 + 24 | 0) >> 2] | 0) + 12 | 0) >> 2] | 0 | 0](HEAP32[($0 + 20 | 0) >> 2] | 0, $1, $2) | 0 | 0; - } - - function _ZN4core9panicking5panic17h9f0a34b0744fbd45E($0, $1, $2) { - $0 = $0 | 0; - $1 = $1 | 0; - $2 = $2 | 0; - var $3 = 0; - $3 = __stack_pointer - 32 | 0; - __stack_pointer = $3; - HEAP32[($3 + 16 | 0) >> 2] = 0; - HEAP32[($3 + 4 | 0) >> 2] = 1; - HEAP32[($3 + 8 | 0) >> 2] = 4; - HEAP32[($3 + 12 | 0) >> 2] = 0; - HEAP32[($3 + 28 | 0) >> 2] = $1; - HEAP32[($3 + 24 | 0) >> 2] = $0; - HEAP32[$3 >> 2] = $3 + 24 | 0; - _ZN4core9panicking9panic_fmt17hb2f16849466f57b6E($3 | 0, $2 | 0); - wasm2js_trap(); - } - - function _ZN4core3fmt3num3imp52_$LT$impl$u20$core__fmt__Display$u20$for$u20$u32$GT$3fmt17h5732d357c58d2b36E($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - var i64toi32_i32$1 = 0; - i64toi32_i32$1 = 0; - return _ZN4core3fmt3num3imp7fmt_u6417h6f5511515637a348E(HEAP32[$0 >> 2] | 0 | 0, i64toi32_i32$1 | 0, 1 | 0, $1 | 0) | 0 | 0; - } - - function _ZN4core3fmt5write17hd273a061a774381dE($0, $1, $2) { - $0 = $0 | 0; - $1 = $1 | 0; - $2 = $2 | 0; - var $3 = 0, $7 = 0, $6 = 0, $11 = 0, $4 = 0, $12 = 0, $9 = 0, $5 = 0, $10 = 0, $8 = 0; - $3 = __stack_pointer - 48 | 0; - __stack_pointer = $3; - HEAP8[($3 + 44 | 0) >> 0] = 3; - HEAP32[($3 + 28 | 0) >> 2] = 32; - $4 = 0; - HEAP32[($3 + 40 | 0) >> 2] = 0; - HEAP32[($3 + 36 | 0) >> 2] = $1; - HEAP32[($3 + 32 | 0) >> 2] = $0; - HEAP32[($3 + 20 | 0) >> 2] = 0; - HEAP32[($3 + 12 | 0) >> 2] = 0; - label$1 : { - label$2 : { - label$3 : { - label$4 : { - label$5 : { - $5 = HEAP32[($2 + 16 | 0) >> 2] | 0; - if ($5) { - break label$5 - } - $0 = HEAP32[($2 + 12 | 0) >> 2] | 0; - if (!$0) { - break label$4 - } - $1 = HEAP32[($2 + 8 | 0) >> 2] | 0; - $6 = $0 << 3 | 0; - $4 = (($0 + -1 | 0) & 536870911 | 0) + 1 | 0; - $0 = HEAP32[$2 >> 2] | 0; - label$6 : while (1) { - label$7 : { - $7 = HEAP32[($0 + 4 | 0) >> 2] | 0; - if (!$7) { - break label$7 - } - if (FUNCTION_TABLE[HEAP32[((HEAP32[($3 + 36 | 0) >> 2] | 0) + 12 | 0) >> 2] | 0 | 0](HEAP32[($3 + 32 | 0) >> 2] | 0, HEAP32[$0 >> 2] | 0, $7) | 0) { - break label$3 - } - } - if (FUNCTION_TABLE[HEAP32[($1 + 4 | 0) >> 2] | 0 | 0](HEAP32[$1 >> 2] | 0, $3 + 12 | 0) | 0) { - break label$3 - } - $1 = $1 + 8 | 0; - $0 = $0 + 8 | 0; - $6 = $6 + -8 | 0; - if ($6) { - continue label$6 - } - break label$4; - }; - } - $1 = HEAP32[($2 + 20 | 0) >> 2] | 0; - if (!$1) { - break label$4 - } - $8 = $1 << 5 | 0; - $4 = (($1 + -1 | 0) & 134217727 | 0) + 1 | 0; - $9 = HEAP32[($2 + 8 | 0) >> 2] | 0; - $0 = HEAP32[$2 >> 2] | 0; - $6 = 0; - label$8 : while (1) { - label$9 : { - $1 = HEAP32[($0 + 4 | 0) >> 2] | 0; - if (!$1) { - break label$9 - } - if (FUNCTION_TABLE[HEAP32[((HEAP32[($3 + 36 | 0) >> 2] | 0) + 12 | 0) >> 2] | 0 | 0](HEAP32[($3 + 32 | 0) >> 2] | 0, HEAP32[$0 >> 2] | 0, $1) | 0) { - break label$3 - } - } - $1 = $5 + $6 | 0; - HEAP32[($3 + 28 | 0) >> 2] = HEAP32[($1 + 16 | 0) >> 2] | 0; - HEAP8[($3 + 44 | 0) >> 0] = HEAPU8[($1 + 28 | 0) >> 0] | 0; - HEAP32[($3 + 40 | 0) >> 2] = HEAP32[($1 + 24 | 0) >> 2] | 0; - $7 = HEAP32[($1 + 12 | 0) >> 2] | 0; - $10 = 0; - $11 = 0; - label$10 : { - label$11 : { - switch (HEAP32[($1 + 8 | 0) >> 2] | 0 | 0) { - case 1: - $12 = $7 << 3 | 0; - $11 = 0; - $12 = $9 + $12 | 0; - if (HEAP32[($12 + 4 | 0) >> 2] | 0) { - break label$10 - } - $7 = HEAP32[$12 >> 2] | 0; - break; - case 2: - break label$10; - default: - break label$11; - }; - } - $11 = 1; - } - HEAP32[($3 + 16 | 0) >> 2] = $7; - HEAP32[($3 + 12 | 0) >> 2] = $11; - $7 = HEAP32[($1 + 4 | 0) >> 2] | 0; - label$13 : { - label$14 : { - switch (HEAP32[$1 >> 2] | 0 | 0) { - case 1: - $11 = $7 << 3 | 0; - $11 = $9 + $11 | 0; - if (HEAP32[($11 + 4 | 0) >> 2] | 0) { - break label$13 - } - $7 = HEAP32[$11 >> 2] | 0; - break; - case 2: - break label$13; - default: - break label$14; - }; - } - $10 = 1; - } - HEAP32[($3 + 24 | 0) >> 2] = $7; - HEAP32[($3 + 20 | 0) >> 2] = $10; - $1 = $9 + ((HEAP32[($1 + 20 | 0) >> 2] | 0) << 3 | 0) | 0; - if (FUNCTION_TABLE[HEAP32[($1 + 4 | 0) >> 2] | 0 | 0](HEAP32[$1 >> 2] | 0, $3 + 12 | 0) | 0) { - break label$3 - } - $0 = $0 + 8 | 0; - $6 = $6 + 32 | 0; - if (($8 | 0) != ($6 | 0)) { - continue label$8 - } - break label$8; - }; - } - if ($4 >>> 0 >= (HEAP32[($2 + 4 | 0) >> 2] | 0) >>> 0) { - break label$2 - } - $1 = (HEAP32[$2 >> 2] | 0) + ($4 << 3 | 0) | 0; - if (!(FUNCTION_TABLE[HEAP32[((HEAP32[($3 + 36 | 0) >> 2] | 0) + 12 | 0) >> 2] | 0 | 0](HEAP32[($3 + 32 | 0) >> 2] | 0, HEAP32[$1 >> 2] | 0, HEAP32[($1 + 4 | 0) >> 2] | 0) | 0)) { - break label$2 - } - } - $1 = 1; - break label$1; - } - $1 = 0; - } - __stack_pointer = $3 + 48 | 0; - return $1 | 0; - } - - function _ZN4core3fmt3num3imp51_$LT$impl$u20$core__fmt__Display$u20$for$u20$u8$GT$3fmt17h96ec540fce0e8c05E($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - var i64toi32_i32$1 = 0; - i64toi32_i32$1 = 0; - return _ZN4core3fmt3num3imp7fmt_u6417h6f5511515637a348E(HEAPU8[$0 >> 0] | 0 | 0, i64toi32_i32$1 | 0, 1 | 0, $1 | 0) | 0 | 0; - } - - function _ZN4core6result13unwrap_failed17h63e31ad259971ff4E($0, $1, $2, $3, $4) { - $0 = $0 | 0; - $1 = $1 | 0; - $2 = $2 | 0; - $3 = $3 | 0; - $4 = $4 | 0; - var $5 = 0, i64toi32_i32$1 = 0, i64toi32_i32$0 = 0, i64toi32_i32$2 = 0, i64toi32_i32$4 = 0, i64toi32_i32$3 = 0, $19 = 0, $21 = 0, $20 = 0, $22$hi = 0, $25$hi = 0, $26 = 0, $27 = 0, $29$hi = 0, $32$hi = 0, $33 = 0; - $5 = __stack_pointer - 64 | 0; - __stack_pointer = $5; - HEAP32[($5 + 12 | 0) >> 2] = $1; - HEAP32[($5 + 8 | 0) >> 2] = $0; - HEAP32[($5 + 20 | 0) >> 2] = $3; - HEAP32[($5 + 16 | 0) >> 2] = $2; - HEAP32[($5 + 28 | 0) >> 2] = 2; - HEAP32[($5 + 24 | 0) >> 2] = 1049288; - i64toi32_i32$1 = $5; - i64toi32_i32$0 = 0; - HEAP32[($5 + 36 | 0) >> 2] = 2; - HEAP32[($5 + 40 | 0) >> 2] = i64toi32_i32$0; - $20 = $5; - i64toi32_i32$0 = 0; - i64toi32_i32$2 = 23; - i64toi32_i32$1 = 0; - i64toi32_i32$3 = 32; - i64toi32_i32$4 = i64toi32_i32$3 & 31 | 0; - if (32 >>> 0 <= (i64toi32_i32$3 & 63 | 0) >>> 0) { - i64toi32_i32$1 = i64toi32_i32$2 << i64toi32_i32$4 | 0; - $19 = 0; - } else { - i64toi32_i32$1 = ((1 << i64toi32_i32$4 | 0) - 1 | 0) & (i64toi32_i32$2 >>> (32 - i64toi32_i32$4 | 0) | 0) | 0 | (i64toi32_i32$0 << i64toi32_i32$4 | 0) | 0; - $19 = i64toi32_i32$2 << i64toi32_i32$4 | 0; - } - $22$hi = i64toi32_i32$1; - i64toi32_i32$1 = 0; - $25$hi = i64toi32_i32$1; - i64toi32_i32$1 = $22$hi; - i64toi32_i32$0 = $19; - i64toi32_i32$2 = $25$hi; - i64toi32_i32$3 = $5 + 16 | 0; - i64toi32_i32$2 = i64toi32_i32$1 | i64toi32_i32$2 | 0; - $26 = i64toi32_i32$0 | i64toi32_i32$3 | 0; - i64toi32_i32$0 = $20; - HEAP32[(i64toi32_i32$0 + 56 | 0) >> 2] = $26; - HEAP32[(i64toi32_i32$0 + 60 | 0) >> 2] = i64toi32_i32$2; - $27 = $5; - i64toi32_i32$2 = 0; - i64toi32_i32$1 = 24; - i64toi32_i32$0 = 0; - i64toi32_i32$3 = 32; - i64toi32_i32$4 = i64toi32_i32$3 & 31 | 0; - if (32 >>> 0 <= (i64toi32_i32$3 & 63 | 0) >>> 0) { - i64toi32_i32$0 = i64toi32_i32$1 << i64toi32_i32$4 | 0; - $21 = 0; - } else { - i64toi32_i32$0 = ((1 << i64toi32_i32$4 | 0) - 1 | 0) & (i64toi32_i32$1 >>> (32 - i64toi32_i32$4 | 0) | 0) | 0 | (i64toi32_i32$2 << i64toi32_i32$4 | 0) | 0; - $21 = i64toi32_i32$1 << i64toi32_i32$4 | 0; - } - $29$hi = i64toi32_i32$0; - i64toi32_i32$0 = 0; - $32$hi = i64toi32_i32$0; - i64toi32_i32$0 = $29$hi; - i64toi32_i32$2 = $21; - i64toi32_i32$1 = $32$hi; - i64toi32_i32$3 = $5 + 8 | 0; - i64toi32_i32$1 = i64toi32_i32$0 | i64toi32_i32$1 | 0; - $33 = i64toi32_i32$2 | i64toi32_i32$3 | 0; - i64toi32_i32$2 = $27; - HEAP32[(i64toi32_i32$2 + 48 | 0) >> 2] = $33; - HEAP32[(i64toi32_i32$2 + 52 | 0) >> 2] = i64toi32_i32$1; - HEAP32[($5 + 32 | 0) >> 2] = $5 + 48 | 0; - _ZN4core9panicking9panic_fmt17hb2f16849466f57b6E($5 + 24 | 0 | 0, $4 | 0); - wasm2js_trap(); - } - - function _ZN4core6option13unwrap_failed17h98817bc8a3accaffE($0) { - $0 = $0 | 0; - _ZN4core9panicking5panic17h9f0a34b0744fbd45E(1049173 | 0, 43 | 0, $0 | 0); - wasm2js_trap(); - } - - function _ZN44_$LT$$RF$T$u20$as$u20$core__fmt__Display$GT$3fmt17h0e730352ba1d2064E($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - return _ZN4core3fmt9Formatter3pad17hc540d40003d38a61E($1 | 0, HEAP32[$0 >> 2] | 0 | 0, HEAP32[($0 + 4 | 0) >> 2] | 0 | 0) | 0 | 0; - } - - function _ZN42_$LT$$RF$T$u20$as$u20$core__fmt__Debug$GT$3fmt17h02f2c499cdd866a1E($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - return FUNCTION_TABLE[HEAP32[((HEAP32[($0 + 4 | 0) >> 2] | 0) + 12 | 0) >> 2] | 0 | 0](HEAP32[$0 >> 2] | 0, $1) | 0 | 0; - } - - function _ZN68_$LT$core__fmt__builders__PadAdapter$u20$as$u20$core__fmt__Write$GT$9write_str17hcef790f9881e69b1E($0, $1, $2) { - $0 = $0 | 0; - $1 = $1 | 0; - $2 = $2 | 0; - var $14 = 0, $9 = 0, $11 = 0, $13 = 0, $12 = 0, $8 = 0, $15 = 0, $4 = 0, $5 = 0, $6 = 0, $7 = 0, $10 = 0, $3 = 0, $72 = 0; - $3 = $1 + -1 | 0; - $4 = HEAP32[($0 + 4 | 0) >> 2] | 0; - $5 = HEAP32[$0 >> 2] | 0; - $6 = HEAP32[($0 + 8 | 0) >> 2] | 0; - $7 = 0; - $8 = 0; - $9 = 0; - $10 = 0; - label$1 : { - label$2 : while (1) { - if ($10 & 1 | 0) { - break label$1 - } - label$3 : { - label$4 : { - if ($9 >>> 0 > $2 >>> 0) { - break label$4 - } - label$5 : while (1) { - $11 = $1 + $9 | 0; - label$6 : { - label$7 : { - label$8 : { - label$9 : { - $12 = $2 - $9 | 0; - if ($12 >>> 0 > 7 >>> 0) { - break label$9 - } - if (($2 | 0) != ($9 | 0)) { - break label$8 - } - $9 = $2; - break label$4; - } - label$10 : { - label$11 : { - $13 = ($11 + 3 | 0) & -4 | 0; - $14 = $13 - $11 | 0; - if (!$14) { - break label$11 - } - $0 = 0; - label$12 : while (1) { - if ((HEAPU8[($11 + $0 | 0) >> 0] | 0 | 0) == (10 | 0)) { - break label$6 - } - $0 = $0 + 1 | 0; - if (($14 | 0) != ($0 | 0)) { - continue label$12 - } - break label$12; - }; - $15 = $12 + -8 | 0; - if ($14 >>> 0 <= $15 >>> 0) { - break label$10 - } - break label$7; - } - $15 = $12 + -8 | 0; - } - label$13 : while (1) { - $0 = HEAP32[$13 >> 2] | 0; - $72 = 16843008 - ($0 ^ 168430090 | 0) | 0 | $0 | 0; - $0 = HEAP32[($13 + 4 | 0) >> 2] | 0; - if ((($72 & (16843008 - ($0 ^ 168430090 | 0) | 0 | $0 | 0) | 0) & -2139062144 | 0 | 0) != (-2139062144 | 0)) { - break label$7 - } - $13 = $13 + 8 | 0; - $14 = $14 + 8 | 0; - if ($14 >>> 0 <= $15 >>> 0) { - continue label$13 - } - break label$7; - }; - } - $0 = 0; - label$14 : while (1) { - if ((HEAPU8[($11 + $0 | 0) >> 0] | 0 | 0) == (10 | 0)) { - break label$6 - } - $0 = $0 + 1 | 0; - if (($12 | 0) != ($0 | 0)) { - continue label$14 - } - break label$14; - }; - $9 = $2; - break label$4; - } - label$15 : { - if (($14 | 0) != ($12 | 0)) { - break label$15 - } - $9 = $2; - break label$4; - } - label$16 : while (1) { - label$17 : { - if ((HEAPU8[($11 + $14 | 0) >> 0] | 0 | 0) != (10 | 0)) { - break label$17 - } - $0 = $14; - break label$6; - } - $14 = $14 + 1 | 0; - if (($12 | 0) != ($14 | 0)) { - continue label$16 - } - break label$16; - }; - $9 = $2; - break label$4; - } - $14 = $0 + $9 | 0; - $9 = $14 + 1 | 0; - label$18 : { - if ($14 >>> 0 >= $2 >>> 0) { - break label$18 - } - if ((HEAPU8[($11 + $0 | 0) >> 0] | 0 | 0) != (10 | 0)) { - break label$18 - } - $11 = $9; - $0 = $9; - break label$3; - } - if ($9 >>> 0 <= $2 >>> 0) { - continue label$5 - } - break label$5; - }; - } - $10 = 1; - $11 = $8; - $0 = $2; - if (($11 | 0) == ($0 | 0)) { - break label$1 - } - } - label$19 : { - label$20 : { - if (!(HEAPU8[$6 >> 0] | 0)) { - break label$20 - } - if (FUNCTION_TABLE[HEAP32[($4 + 12 | 0) >> 2] | 0 | 0]($5, 1049328, 4) | 0) { - break label$19 - } - } - $13 = $0 - $8 | 0; - $14 = 0; - label$21 : { - if (($0 | 0) == ($8 | 0)) { - break label$21 - } - $14 = (HEAPU8[($3 + $0 | 0) >> 0] | 0 | 0) == (10 | 0); - } - $0 = $1 + $8 | 0; - HEAP8[$6 >> 0] = $14; - $8 = $11; - if (!(FUNCTION_TABLE[HEAP32[($4 + 12 | 0) >> 2] | 0 | 0]($5, $0, $13) | 0)) { - continue label$2 - } - } - break label$2; - }; - $7 = 1; - } - return $7 | 0; - } - - function _ZN68_$LT$core__fmt__builders__PadAdapter$u20$as$u20$core__fmt__Write$GT$10write_char17h8982d69464cb262aE($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - var $2 = 0, $3 = 0; - $2 = HEAP32[($0 + 4 | 0) >> 2] | 0; - $3 = HEAP32[$0 >> 2] | 0; - label$1 : { - $0 = HEAP32[($0 + 8 | 0) >> 2] | 0; - if (!(HEAPU8[$0 >> 0] | 0)) { - break label$1 - } - if (!(FUNCTION_TABLE[HEAP32[($2 + 12 | 0) >> 2] | 0 | 0]($3, 1049328, 4) | 0)) { - break label$1 - } - return 1 | 0; - } - HEAP8[$0 >> 0] = ($1 | 0) == (10 | 0); - return FUNCTION_TABLE[HEAP32[($2 + 16 | 0) >> 2] | 0 | 0]($3, $1) | 0 | 0; - } - - function _ZN4core3fmt8builders8DebugSet5entry17h7036b50f83a7398eE($0, $1, $2) { - $0 = $0 | 0; - $1 = $1 | 0; - $2 = $2 | 0; - var $3 = 0, $6 = 0, i64toi32_i32$0 = 0, $4 = 0, i64toi32_i32$1 = 0, $7 = 0, $5 = 0, $45 = 0, $52 = 0, $64 = 0; - $3 = __stack_pointer - 64 | 0; - __stack_pointer = $3; - $4 = 1; - label$1 : { - if (HEAPU8[($0 + 4 | 0) >> 0] | 0) { - break label$1 - } - $5 = HEAPU8[($0 + 5 | 0) >> 0] | 0; - label$2 : { - label$3 : { - $6 = HEAP32[$0 >> 2] | 0; - $7 = HEAP32[($6 + 28 | 0) >> 2] | 0; - if ($7 & 4 | 0) { - break label$3 - } - $4 = 1; - if (!($5 & 1 | 0)) { - break label$2 - } - if (!(FUNCTION_TABLE[HEAP32[((HEAP32[($6 + 24 | 0) >> 2] | 0) + 12 | 0) >> 2] | 0 | 0](HEAP32[($6 + 20 | 0) >> 2] | 0, 1049332, 2) | 0)) { - break label$2 - } - break label$1; - } - $4 = 1; - label$4 : { - if ($5 & 1 | 0) { - break label$4 - } - if (FUNCTION_TABLE[HEAP32[((HEAP32[($6 + 24 | 0) >> 2] | 0) + 12 | 0) >> 2] | 0 | 0](HEAP32[($6 + 20 | 0) >> 2] | 0, 1049336, 1) | 0) { - break label$1 - } - $7 = HEAP32[($6 + 28 | 0) >> 2] | 0; - } - $4 = 1; - HEAP8[($3 + 27 | 0) >> 0] = 1; - i64toi32_i32$0 = HEAP32[($6 + 20 | 0) >> 2] | 0; - i64toi32_i32$1 = HEAP32[($6 + 24 | 0) >> 2] | 0; - $45 = i64toi32_i32$0; - i64toi32_i32$0 = $3; - HEAP32[($3 + 12 | 0) >> 2] = $45; - HEAP32[($3 + 16 | 0) >> 2] = i64toi32_i32$1; - HEAP32[($3 + 52 | 0) >> 2] = 1049304; - HEAP32[($3 + 20 | 0) >> 2] = $3 + 27 | 0; - i64toi32_i32$1 = HEAP32[($6 + 8 | 0) >> 2] | 0; - i64toi32_i32$0 = HEAP32[($6 + 12 | 0) >> 2] | 0; - $52 = i64toi32_i32$1; - i64toi32_i32$1 = $3; - HEAP32[($3 + 36 | 0) >> 2] = $52; - HEAP32[($3 + 40 | 0) >> 2] = i64toi32_i32$0; - i64toi32_i32$0 = HEAP32[$6 >> 2] | 0; - i64toi32_i32$1 = HEAP32[($6 + 4 | 0) >> 2] | 0; - HEAP32[($3 + 56 | 0) >> 2] = $7; - HEAP32[($3 + 44 | 0) >> 2] = HEAP32[($6 + 16 | 0) >> 2] | 0; - HEAP8[($3 + 60 | 0) >> 0] = HEAPU8[($6 + 32 | 0) >> 0] | 0; - $64 = i64toi32_i32$0; - i64toi32_i32$0 = $3; - HEAP32[($3 + 28 | 0) >> 2] = $64; - HEAP32[($3 + 32 | 0) >> 2] = i64toi32_i32$1; - HEAP32[($3 + 48 | 0) >> 2] = $3 + 12 | 0; - if (FUNCTION_TABLE[HEAP32[($2 + 12 | 0) >> 2] | 0 | 0]($1, $3 + 28 | 0) | 0) { - break label$1 - } - $4 = FUNCTION_TABLE[HEAP32[((HEAP32[($3 + 52 | 0) >> 2] | 0) + 12 | 0) >> 2] | 0 | 0](HEAP32[($3 + 48 | 0) >> 2] | 0, 1049334, 2) | 0; - break label$1; - } - $4 = FUNCTION_TABLE[HEAP32[($2 + 12 | 0) >> 2] | 0 | 0]($1, $6) | 0; - } - HEAP8[($0 + 5 | 0) >> 0] = 1; - HEAP8[($0 + 4 | 0) >> 0] = $4; - __stack_pointer = $3 + 64 | 0; - return $0 | 0; - } - - function _ZN4core3fmt8builders9DebugList6finish17h4ef7645c675cb82eE($0) { - $0 = $0 | 0; - var $1 = 0; - $1 = 1; - label$1 : { - if (HEAPU8[($0 + 4 | 0) >> 0] | 0) { - break label$1 - } - $1 = HEAP32[$0 >> 2] | 0; - $1 = FUNCTION_TABLE[HEAP32[((HEAP32[($1 + 24 | 0) >> 2] | 0) + 12 | 0) >> 2] | 0 | 0](HEAP32[($1 + 20 | 0) >> 2] | 0, 1049337, 1) | 0; - } - HEAP8[($0 + 4 | 0) >> 0] = $1; - return $1 | 0; - } - - function _ZN4core3fmt9Formatter12pad_integral17hc60d9805b485ef36E($0, $1, $2, $3, $4, $5) { - $0 = $0 | 0; - $1 = $1 | 0; - $2 = $2 | 0; - $3 = $3 | 0; - $4 = $4 | 0; - $5 = $5 | 0; - var $12 = 0, $6 = 0, $10 = 0, $9 = 0, $7 = 0, $8 = 0, $11 = 0; - label$1 : { - label$2 : { - if ($1) { - break label$2 - } - $6 = $5 + 1 | 0; - $7 = HEAP32[($0 + 28 | 0) >> 2] | 0; - $8 = 45; - break label$1; - } - $7 = HEAP32[($0 + 28 | 0) >> 2] | 0; - $1 = $7 & 1 | 0; - $8 = $1 ? 43 : 1114112; - $6 = $1 + $5 | 0; - } - label$3 : { - label$4 : { - if ($7 & 4 | 0) { - break label$4 - } - $2 = 0; - break label$3; - } - label$5 : { - label$6 : { - if ($3 >>> 0 < 16 >>> 0) { - break label$6 - } - $1 = _ZN4core3str5count14do_count_chars17h03769f4f70ff5154E($2 | 0, $3 | 0) | 0; - break label$5; - } - label$7 : { - if ($3) { - break label$7 - } - $1 = 0; - break label$5; - } - $9 = $3 & 3 | 0; - label$8 : { - label$9 : { - if ($3 >>> 0 >= 4 >>> 0) { - break label$9 - } - $1 = 0; - $10 = 0; - break label$8; - } - $11 = $3 & 12 | 0; - $1 = 0; - $10 = 0; - label$10 : while (1) { - $12 = $2 + $10 | 0; - $1 = ((($1 + ((HEAP8[$12 >> 0] | 0 | 0) > (-65 | 0)) | 0) + ((HEAP8[($12 + 1 | 0) >> 0] | 0 | 0) > (-65 | 0)) | 0) + ((HEAP8[($12 + 2 | 0) >> 0] | 0 | 0) > (-65 | 0)) | 0) + ((HEAP8[($12 + 3 | 0) >> 0] | 0 | 0) > (-65 | 0)) | 0; - $10 = $10 + 4 | 0; - if (($11 | 0) != ($10 | 0)) { - continue label$10 - } - break label$10; - }; - } - if (!$9) { - break label$5 - } - $12 = $2 + $10 | 0; - label$11 : while (1) { - $1 = $1 + ((HEAP8[$12 >> 0] | 0 | 0) > (-65 | 0)) | 0; - $12 = $12 + 1 | 0; - $9 = $9 + -1 | 0; - if ($9) { - continue label$11 - } - break label$11; - }; - } - $6 = $1 + $6 | 0; - } - label$12 : { - if (HEAP32[$0 >> 2] | 0) { - break label$12 - } - label$13 : { - $1 = HEAP32[($0 + 20 | 0) >> 2] | 0; - $12 = HEAP32[($0 + 24 | 0) >> 2] | 0; - if (!(_ZN4core3fmt9Formatter12pad_integral12write_prefix17h581ad47c6930a5a3E($1 | 0, $12 | 0, $8 | 0, $2 | 0, $3 | 0) | 0)) { - break label$13 - } - return 1 | 0; - } - return FUNCTION_TABLE[HEAP32[($12 + 12 | 0) >> 2] | 0 | 0]($1, $4, $5) | 0 | 0; - } - label$14 : { - label$15 : { - label$16 : { - label$17 : { - $1 = HEAP32[($0 + 4 | 0) >> 2] | 0; - if ($1 >>> 0 > $6 >>> 0) { - break label$17 - } - $1 = HEAP32[($0 + 20 | 0) >> 2] | 0; - $12 = HEAP32[($0 + 24 | 0) >> 2] | 0; - if (!(_ZN4core3fmt9Formatter12pad_integral12write_prefix17h581ad47c6930a5a3E($1 | 0, $12 | 0, $8 | 0, $2 | 0, $3 | 0) | 0)) { - break label$16 - } - return 1 | 0; - } - if (!($7 & 8 | 0)) { - break label$15 - } - $9 = HEAP32[($0 + 16 | 0) >> 2] | 0; - HEAP32[($0 + 16 | 0) >> 2] = 48; - $7 = HEAPU8[($0 + 32 | 0) >> 0] | 0; - $11 = 1; - HEAP8[($0 + 32 | 0) >> 0] = 1; - $12 = HEAP32[($0 + 20 | 0) >> 2] | 0; - $10 = HEAP32[($0 + 24 | 0) >> 2] | 0; - if (_ZN4core3fmt9Formatter12pad_integral12write_prefix17h581ad47c6930a5a3E($12 | 0, $10 | 0, $8 | 0, $2 | 0, $3 | 0) | 0) { - break label$14 - } - $1 = ($1 - $6 | 0) + 1 | 0; - label$18 : { - label$19 : while (1) { - $1 = $1 + -1 | 0; - if (!$1) { - break label$18 - } - if (!(FUNCTION_TABLE[HEAP32[($10 + 16 | 0) >> 2] | 0 | 0]($12, 48) | 0)) { - continue label$19 - } - break label$19; - }; - return 1 | 0; - } - label$20 : { - if (!(FUNCTION_TABLE[HEAP32[($10 + 12 | 0) >> 2] | 0 | 0]($12, $4, $5) | 0)) { - break label$20 - } - return 1 | 0; - } - HEAP8[($0 + 32 | 0) >> 0] = $7; - HEAP32[($0 + 16 | 0) >> 2] = $9; - return 0 | 0; - } - $11 = FUNCTION_TABLE[HEAP32[($12 + 12 | 0) >> 2] | 0 | 0]($1, $4, $5) | 0; - break label$14; - } - $6 = $1 - $6 | 0; - label$21 : { - label$22 : { - label$23 : { - $1 = HEAPU8[($0 + 32 | 0) >> 0] | 0; - switch ($1 | 0) { - case 2: - break label$22; - case 1: - case 3: - break label$23; - default: - break label$21; - }; - } - $1 = $6; - $6 = 0; - break label$21; - } - $1 = $6 >>> 1 | 0; - $6 = ($6 + 1 | 0) >>> 1 | 0; - } - $1 = $1 + 1 | 0; - $9 = HEAP32[($0 + 16 | 0) >> 2] | 0; - $12 = HEAP32[($0 + 24 | 0) >> 2] | 0; - $10 = HEAP32[($0 + 20 | 0) >> 2] | 0; - label$24 : { - label$25 : while (1) { - $1 = $1 + -1 | 0; - if (!$1) { - break label$24 - } - if (!(FUNCTION_TABLE[HEAP32[($12 + 16 | 0) >> 2] | 0 | 0]($10, $9) | 0)) { - continue label$25 - } - break label$25; - }; - return 1 | 0; - } - $11 = 1; - if (_ZN4core3fmt9Formatter12pad_integral12write_prefix17h581ad47c6930a5a3E($10 | 0, $12 | 0, $8 | 0, $2 | 0, $3 | 0) | 0) { - break label$14 - } - if (FUNCTION_TABLE[HEAP32[($12 + 12 | 0) >> 2] | 0 | 0]($10, $4, $5) | 0) { - break label$14 - } - $1 = 0; - label$26 : while (1) { - label$27 : { - if (($6 | 0) != ($1 | 0)) { - break label$27 - } - return $6 >>> 0 < $6 >>> 0 | 0; - } - $1 = $1 + 1 | 0; - if (!(FUNCTION_TABLE[HEAP32[($12 + 16 | 0) >> 2] | 0 | 0]($10, $9) | 0)) { - continue label$26 - } - break label$26; - }; - return ($1 + -1 | 0) >>> 0 < $6 >>> 0 | 0; - } - return $11 | 0; - } - - function _ZN4core3fmt5Write9write_fmt17h7b710d0d35de0c2bE($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - return _ZN4core3fmt5write17hd273a061a774381dE($0 | 0, 1049304 | 0, $1 | 0) | 0 | 0; - } - - function _ZN4core3str5count14do_count_chars17h03769f4f70ff5154E($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - var $2 = 0, $9 = 0, $8 = 0, $3 = 0, $6 = 0, $4 = 0, $5 = 0, $7 = 0, $132 = 0, $141 = 0, $150 = 0; - label$1 : { - label$2 : { - $2 = ($0 + 3 | 0) & -4 | 0; - $3 = $2 - $0 | 0; - if ($1 >>> 0 < $3 >>> 0) { - break label$2 - } - $4 = $1 - $3 | 0; - if ($4 >>> 0 < 4 >>> 0) { - break label$2 - } - $5 = $4 & 3 | 0; - $6 = 0; - $1 = 0; - label$3 : { - $7 = ($2 | 0) == ($0 | 0); - if ($7) { - break label$3 - } - $1 = 0; - label$4 : { - label$5 : { - $8 = $0 - $2 | 0; - if ($8 >>> 0 <= -4 >>> 0) { - break label$5 - } - $9 = 0; - break label$4; - } - $9 = 0; - label$6 : while (1) { - $2 = $0 + $9 | 0; - $1 = ((($1 + ((HEAP8[$2 >> 0] | 0 | 0) > (-65 | 0)) | 0) + ((HEAP8[($2 + 1 | 0) >> 0] | 0 | 0) > (-65 | 0)) | 0) + ((HEAP8[($2 + 2 | 0) >> 0] | 0 | 0) > (-65 | 0)) | 0) + ((HEAP8[($2 + 3 | 0) >> 0] | 0 | 0) > (-65 | 0)) | 0; - $9 = $9 + 4 | 0; - if ($9) { - continue label$6 - } - break label$6; - }; - } - if ($7) { - break label$3 - } - $2 = $0 + $9 | 0; - label$7 : while (1) { - $1 = $1 + ((HEAP8[$2 >> 0] | 0 | 0) > (-65 | 0)) | 0; - $2 = $2 + 1 | 0; - $8 = $8 + 1 | 0; - if ($8) { - continue label$7 - } - break label$7; - }; - } - $9 = $0 + $3 | 0; - label$8 : { - if (!$5) { - break label$8 - } - $2 = $9 + ($4 & -4 | 0) | 0; - $6 = (HEAP8[$2 >> 0] | 0 | 0) > (-65 | 0); - if (($5 | 0) == (1 | 0)) { - break label$8 - } - $6 = $6 + ((HEAP8[($2 + 1 | 0) >> 0] | 0 | 0) > (-65 | 0)) | 0; - if (($5 | 0) == (2 | 0)) { - break label$8 - } - $6 = $6 + ((HEAP8[($2 + 2 | 0) >> 0] | 0 | 0) > (-65 | 0)) | 0; - } - $3 = $4 >>> 2 | 0; - $8 = $6 + $1 | 0; - label$9 : while (1) { - $4 = $9; - if (!$3) { - break label$1 - } - $6 = $3 >>> 0 < 192 >>> 0 ? $3 : 192; - $7 = $6 & 3 | 0; - $5 = $6 << 2 | 0; - $2 = 0; - label$10 : { - if ($3 >>> 0 < 4 >>> 0) { - break label$10 - } - $0 = $9 + ($5 & 1008 | 0) | 0; - $2 = 0; - $1 = $9; - label$11 : while (1) { - $9 = HEAP32[($1 + 12 | 0) >> 2] | 0; - $132 = (($9 ^ -1 | 0) >>> 7 | 0 | ($9 >>> 6 | 0) | 0) & 16843009 | 0; - $9 = HEAP32[($1 + 8 | 0) >> 2] | 0; - $141 = (($9 ^ -1 | 0) >>> 7 | 0 | ($9 >>> 6 | 0) | 0) & 16843009 | 0; - $9 = HEAP32[($1 + 4 | 0) >> 2] | 0; - $150 = (($9 ^ -1 | 0) >>> 7 | 0 | ($9 >>> 6 | 0) | 0) & 16843009 | 0; - $9 = HEAP32[$1 >> 2] | 0; - $2 = $132 + ($141 + ($150 + (((($9 ^ -1 | 0) >>> 7 | 0 | ($9 >>> 6 | 0) | 0) & 16843009 | 0) + $2 | 0) | 0) | 0) | 0; - $1 = $1 + 16 | 0; - if (($1 | 0) != ($0 | 0)) { - continue label$11 - } - break label$11; - }; - } - $3 = $3 - $6 | 0; - $9 = $4 + $5 | 0; - $8 = (Math_imul((($2 >>> 8 | 0) & 16711935 | 0) + ($2 & 16711935 | 0) | 0, 65537) >>> 16 | 0) + $8 | 0; - if (!$7) { - continue label$9 - } - break label$9; - }; - $2 = $4 + (($6 & 252 | 0) << 2 | 0) | 0; - $1 = HEAP32[$2 >> 2] | 0; - $1 = (($1 ^ -1 | 0) >>> 7 | 0 | ($1 >>> 6 | 0) | 0) & 16843009 | 0; - label$12 : { - if (($7 | 0) == (1 | 0)) { - break label$12 - } - $9 = HEAP32[($2 + 4 | 0) >> 2] | 0; - $1 = ((($9 ^ -1 | 0) >>> 7 | 0 | ($9 >>> 6 | 0) | 0) & 16843009 | 0) + $1 | 0; - if (($7 | 0) == (2 | 0)) { - break label$12 - } - $2 = HEAP32[($2 + 8 | 0) >> 2] | 0; - $1 = ((($2 ^ -1 | 0) >>> 7 | 0 | ($2 >>> 6 | 0) | 0) & 16843009 | 0) + $1 | 0; - } - return (Math_imul((($1 >>> 8 | 0) & 459007 | 0) + ($1 & 16711935 | 0) | 0, 65537) >>> 16 | 0) + $8 | 0 | 0; - } - label$13 : { - if ($1) { - break label$13 - } - return 0 | 0; - } - $9 = $1 & 3 | 0; - label$14 : { - label$15 : { - if ($1 >>> 0 >= 4 >>> 0) { - break label$15 - } - $8 = 0; - $2 = 0; - break label$14; - } - $3 = $1 & -4 | 0; - $8 = 0; - $2 = 0; - label$16 : while (1) { - $1 = $0 + $2 | 0; - $8 = ((($8 + ((HEAP8[$1 >> 0] | 0 | 0) > (-65 | 0)) | 0) + ((HEAP8[($1 + 1 | 0) >> 0] | 0 | 0) > (-65 | 0)) | 0) + ((HEAP8[($1 + 2 | 0) >> 0] | 0 | 0) > (-65 | 0)) | 0) + ((HEAP8[($1 + 3 | 0) >> 0] | 0 | 0) > (-65 | 0)) | 0; - $2 = $2 + 4 | 0; - if (($3 | 0) != ($2 | 0)) { - continue label$16 - } - break label$16; - }; - } - if (!$9) { - break label$1 - } - $1 = $0 + $2 | 0; - label$17 : while (1) { - $8 = $8 + ((HEAP8[$1 >> 0] | 0 | 0) > (-65 | 0)) | 0; - $1 = $1 + 1 | 0; - $9 = $9 + -1 | 0; - if ($9) { - continue label$17 - } - break label$17; - }; - } - return $8 | 0; - } - - function _ZN4core3fmt9Formatter12pad_integral12write_prefix17h581ad47c6930a5a3E($0, $1, $2, $3, $4) { - $0 = $0 | 0; - $1 = $1 | 0; - $2 = $2 | 0; - $3 = $3 | 0; - $4 = $4 | 0; - label$1 : { - if (($2 | 0) == (1114112 | 0)) { - break label$1 - } - if (!(FUNCTION_TABLE[HEAP32[($1 + 16 | 0) >> 2] | 0 | 0]($0, $2) | 0)) { - break label$1 - } - return 1 | 0; - } - label$2 : { - if ($3) { - break label$2 - } - return 0 | 0; - } - return FUNCTION_TABLE[HEAP32[($1 + 12 | 0) >> 2] | 0 | 0]($0, $3, $4) | 0 | 0; - } - - function _ZN4core3fmt9Formatter9write_str17h7b04ca2eef2f5010E($0, $1, $2) { - $0 = $0 | 0; - $1 = $1 | 0; - $2 = $2 | 0; - return FUNCTION_TABLE[HEAP32[((HEAP32[($0 + 24 | 0) >> 2] | 0) + 12 | 0) >> 2] | 0 | 0](HEAP32[($0 + 20 | 0) >> 2] | 0, $1, $2) | 0 | 0; - } - - function _ZN4core3fmt9Formatter10debug_list17hd710ece3eac84443E($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - var $2 = 0; - $2 = FUNCTION_TABLE[HEAP32[((HEAP32[($1 + 24 | 0) >> 2] | 0) + 12 | 0) >> 2] | 0 | 0](HEAP32[($1 + 20 | 0) >> 2] | 0, 1049172, 1) | 0; - HEAP8[($0 + 5 | 0) >> 0] = 0; - HEAP8[($0 + 4 | 0) >> 0] = $2; - HEAP32[$0 >> 2] = $1; - } - - function _ZN4core3str5count23char_count_general_case17ha75d4189ecacd84eE($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - var $5 = 0, $3 = 0, $2 = 0, $4 = 0; - label$1 : { - if ($1) { - break label$1 - } - return 0 | 0; - } - $2 = $1 & 3 | 0; - label$2 : { - label$3 : { - if ($1 >>> 0 >= 4 >>> 0) { - break label$3 - } - $1 = 0; - $3 = 0; - break label$2; - } - $4 = $1 & -4 | 0; - $1 = 0; - $3 = 0; - label$4 : while (1) { - $5 = $0 + $3 | 0; - $1 = ((($1 + ((HEAP8[$5 >> 0] | 0 | 0) > (-65 | 0)) | 0) + ((HEAP8[($5 + 1 | 0) >> 0] | 0 | 0) > (-65 | 0)) | 0) + ((HEAP8[($5 + 2 | 0) >> 0] | 0 | 0) > (-65 | 0)) | 0) + ((HEAP8[($5 + 3 | 0) >> 0] | 0 | 0) > (-65 | 0)) | 0; - $3 = $3 + 4 | 0; - if (($4 | 0) != ($3 | 0)) { - continue label$4 - } - break label$4; - }; - } - label$5 : { - if (!$2) { - break label$5 - } - $5 = $0 + $3 | 0; - label$6 : while (1) { - $1 = $1 + ((HEAP8[$5 >> 0] | 0 | 0) > (-65 | 0)) | 0; - $5 = $5 + 1 | 0; - $2 = $2 + -1 | 0; - if ($2) { - continue label$6 - } - break label$6; - }; - } - return $1 | 0; - } - - function _ZN4core3fmt3num52_$LT$impl$u20$core__fmt__UpperHex$u20$for$u20$i8$GT$3fmt17h8bec9e17aa3a250bE($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - var $3 = 0, $4 = 0, $2 = 0; - $2 = __stack_pointer - 128 | 0; - __stack_pointer = $2; - $3 = HEAPU8[$0 >> 0] | 0; - $0 = 0; - label$1 : while (1) { - $4 = $3 & 15 | 0; - HEAP8[(($2 + $0 | 0) + 127 | 0) >> 0] = $4 >>> 0 < 10 >>> 0 ? $4 | 48 | 0 : $4 + 55 | 0; - $0 = $0 + -1 | 0; - $4 = $3 & 255 | 0; - $3 = $4 >>> 4 | 0; - if ($4 >>> 0 >= 16 >>> 0) { - continue label$1 - } - break label$1; - }; - label$2 : { - $3 = $0 + 128 | 0; - if ($3 >>> 0 < 129 >>> 0) { - break label$2 - } - _ZN4core5slice5index26slice_start_index_len_fail17h65432e022682bf05E($3 | 0, 128 | 0, 1049360 | 0); - wasm2js_trap(); - } - $0 = _ZN4core3fmt9Formatter12pad_integral17hc60d9805b485ef36E($1 | 0, 1 | 0, 1049376 | 0, 2 | 0, ($2 + $0 | 0) + 128 | 0 | 0, 0 - $0 | 0 | 0) | 0; - __stack_pointer = $2 + 128 | 0; - return $0 | 0; - } - - function _ZN4core3fmt3num52_$LT$impl$u20$core__fmt__LowerHex$u20$for$u20$i8$GT$3fmt17hbd8bbf103c04b7d4E($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - var $3 = 0, $4 = 0, $2 = 0; - $2 = __stack_pointer - 128 | 0; - __stack_pointer = $2; - $3 = HEAPU8[$0 >> 0] | 0; - $0 = 0; - label$1 : while (1) { - $4 = $3 & 15 | 0; - HEAP8[(($2 + $0 | 0) + 127 | 0) >> 0] = $4 >>> 0 < 10 >>> 0 ? $4 | 48 | 0 : $4 + 87 | 0; - $0 = $0 + -1 | 0; - $4 = $3 & 255 | 0; - $3 = $4 >>> 4 | 0; - if ($4 >>> 0 >= 16 >>> 0) { - continue label$1 - } - break label$1; - }; - label$2 : { - $3 = $0 + 128 | 0; - if ($3 >>> 0 < 129 >>> 0) { - break label$2 - } - _ZN4core5slice5index26slice_start_index_len_fail17h65432e022682bf05E($3 | 0, 128 | 0, 1049360 | 0); - wasm2js_trap(); - } - $0 = _ZN4core3fmt9Formatter12pad_integral17hc60d9805b485ef36E($1 | 0, 1 | 0, 1049376 | 0, 2 | 0, ($2 + $0 | 0) + 128 | 0 | 0, 0 - $0 | 0 | 0) | 0; - __stack_pointer = $2 + 128 | 0; - return $0 | 0; - } - - function _ZN4core3fmt3num3imp7fmt_u6417h6f5511515637a348E($0, $0$hi, $1, $2) { - $0 = $0 | 0; - $0$hi = $0$hi | 0; - $1 = $1 | 0; - $2 = $2 | 0; - var i64toi32_i32$2 = 0, $4 = 0, i64toi32_i32$0 = 0, i64toi32_i32$1 = 0, $6 = 0, i64toi32_i32$3 = 0, i64toi32_i32$5 = 0, $3 = 0, $5 = 0, $5$hi = 0, $7 = 0, $8 = 0, $18 = 0, $19 = 0, $20 = 0, $21 = 0, $22 = 0, $23 = 0, $24 = 0, $26 = 0, $27 = 0, $28 = 0, $29 = 0, $30 = 0, $25 = 0, $25$hi = 0; - $3 = __stack_pointer - 48 | 0; - __stack_pointer = $3; - $4 = 39; - label$1 : { - label$2 : { - i64toi32_i32$0 = $0$hi; - i64toi32_i32$2 = $0; - i64toi32_i32$1 = 0; - i64toi32_i32$3 = 1e4; - if (i64toi32_i32$0 >>> 0 > i64toi32_i32$1 >>> 0 | ((i64toi32_i32$0 | 0) == (i64toi32_i32$1 | 0) & i64toi32_i32$2 >>> 0 >= i64toi32_i32$3 >>> 0 | 0) | 0) { - break label$2 - } - i64toi32_i32$2 = i64toi32_i32$0; - $5 = $0; - $5$hi = i64toi32_i32$2; - break label$1; - } - $4 = 39; - label$3 : while (1) { - $6 = ($3 + 9 | 0) + $4 | 0; - i64toi32_i32$2 = $0$hi; - i64toi32_i32$0 = 0; - i64toi32_i32$0 = __wasm_i64_udiv($0 | 0, i64toi32_i32$2 | 0, 1e4 | 0, i64toi32_i32$0 | 0) | 0; - i64toi32_i32$2 = i64toi32_i32$HIGH_BITS; - $5 = i64toi32_i32$0; - $5$hi = i64toi32_i32$2; - i64toi32_i32$0 = 0; - i64toi32_i32$0 = __wasm_i64_mul($5 | 0, i64toi32_i32$2 | 0, 1e4 | 0, i64toi32_i32$0 | 0) | 0; - i64toi32_i32$2 = i64toi32_i32$HIGH_BITS; - $25 = i64toi32_i32$0; - $25$hi = i64toi32_i32$2; - i64toi32_i32$2 = $0$hi; - i64toi32_i32$3 = $0; - i64toi32_i32$0 = $25$hi; - i64toi32_i32$1 = $25; - i64toi32_i32$5 = (i64toi32_i32$3 >>> 0 < i64toi32_i32$1 >>> 0) + i64toi32_i32$0 | 0; - i64toi32_i32$5 = i64toi32_i32$2 - i64toi32_i32$5 | 0; - $7 = i64toi32_i32$3 - i64toi32_i32$1 | 0; - $8 = (($7 & 65535 | 0) >>> 0) / (100 >>> 0) | 0; - $18 = ($8 << 1 | 0) + 1049378 | 0; - $19 = $6 + -4 | 0; - $20 = HEAPU8[$18 >> 0] | 0 | ((HEAPU8[($18 + 1 | 0) >> 0] | 0) << 8 | 0) | 0; - HEAP8[$19 >> 0] = $20; - HEAP8[($19 + 1 | 0) >> 0] = $20 >>> 8 | 0; - $21 = ((($7 - Math_imul($8, 100) | 0) & 65535 | 0) << 1 | 0) + 1049378 | 0; - $22 = $6 + -2 | 0; - $23 = HEAPU8[$21 >> 0] | 0 | ((HEAPU8[($21 + 1 | 0) >> 0] | 0) << 8 | 0) | 0; - HEAP8[$22 >> 0] = $23; - HEAP8[($22 + 1 | 0) >> 0] = $23 >>> 8 | 0; - $4 = $4 + -4 | 0; - i64toi32_i32$5 = i64toi32_i32$2; - i64toi32_i32$5 = i64toi32_i32$2; - i64toi32_i32$2 = i64toi32_i32$3; - i64toi32_i32$3 = 0; - i64toi32_i32$1 = 99999999; - $6 = i64toi32_i32$5 >>> 0 > i64toi32_i32$3 >>> 0 | ((i64toi32_i32$5 | 0) == (i64toi32_i32$3 | 0) & i64toi32_i32$2 >>> 0 > i64toi32_i32$1 >>> 0 | 0) | 0; - i64toi32_i32$2 = $5$hi; - $0 = $5; - $0$hi = i64toi32_i32$2; - if ($6) { - continue label$3 - } - break label$3; - }; - } - label$4 : { - label$5 : { - i64toi32_i32$2 = $5$hi; - i64toi32_i32$1 = $5; - i64toi32_i32$5 = 0; - i64toi32_i32$3 = 99; - if (i64toi32_i32$2 >>> 0 > i64toi32_i32$5 >>> 0 | ((i64toi32_i32$2 | 0) == (i64toi32_i32$5 | 0) & i64toi32_i32$1 >>> 0 > i64toi32_i32$3 >>> 0 | 0) | 0) { - break label$5 - } - i64toi32_i32$1 = i64toi32_i32$2; - i64toi32_i32$1 = i64toi32_i32$2; - $6 = $5; - break label$4; - } - $4 = $4 + -2 | 0; - i64toi32_i32$1 = $5$hi; - $6 = $5; - $6 = (($6 & 65535 | 0) >>> 0) / (100 >>> 0) | 0; - $24 = ((($5 - Math_imul($6, 100) | 0) & 65535 | 0) << 1 | 0) + 1049378 | 0; - $26 = ($3 + 9 | 0) + $4 | 0; - $27 = HEAPU8[$24 >> 0] | 0 | ((HEAPU8[($24 + 1 | 0) >> 0] | 0) << 8 | 0) | 0; - HEAP8[$26 >> 0] = $27; - HEAP8[($26 + 1 | 0) >> 0] = $27 >>> 8 | 0; - } - label$6 : { - label$7 : { - if ($6 >>> 0 < 10 >>> 0) { - break label$7 - } - $4 = $4 + -2 | 0; - $28 = ($6 << 1 | 0) + 1049378 | 0; - $29 = ($3 + 9 | 0) + $4 | 0; - $30 = HEAPU8[$28 >> 0] | 0 | ((HEAPU8[($28 + 1 | 0) >> 0] | 0) << 8 | 0) | 0; - HEAP8[$29 >> 0] = $30; - HEAP8[($29 + 1 | 0) >> 0] = $30 >>> 8 | 0; - break label$6; - } - $4 = $4 + -1 | 0; - HEAP8[(($3 + 9 | 0) + $4 | 0) >> 0] = $6 | 48 | 0; - } - $4 = _ZN4core3fmt9Formatter12pad_integral17hc60d9805b485ef36E($2 | 0, $1 | 0, 1 | 0, 0 | 0, ($3 + 9 | 0) + $4 | 0 | 0, 39 - $4 | 0 | 0) | 0; - __stack_pointer = $3 + 48 | 0; - return $4 | 0; - } - - function memcpy($0, $1, $2) { - $0 = $0 | 0; - $1 = $1 | 0; - $2 = $2 | 0; - var $3 = 0, $5 = 0, $6 = 0, $4 = 0, $9 = 0, $8 = 0, $7 = 0, $10 = 0, $66 = 0; - label$1 : { - label$2 : { - if ($2 >>> 0 >= 16 >>> 0) { - break label$2 - } - $3 = $0; - break label$1; - } - $4 = (0 - $0 | 0) & 3 | 0; - $5 = $0 + $4 | 0; - label$3 : { - if (!$4) { - break label$3 - } - $3 = $0; - $6 = $1; - label$4 : while (1) { - HEAP8[$3 >> 0] = HEAPU8[$6 >> 0] | 0; - $6 = $6 + 1 | 0; - $3 = $3 + 1 | 0; - if ($3 >>> 0 < $5 >>> 0) { - continue label$4 - } - break label$4; - }; - } - $7 = $2 - $4 | 0; - $8 = $7 & -4 | 0; - $3 = $5 + $8 | 0; - label$5 : { - label$6 : { - $9 = $1 + $4 | 0; - if (!($9 & 3 | 0)) { - break label$6 - } - if (($8 | 0) < (1 | 0)) { - break label$5 - } - $6 = $9 << 3 | 0; - $2 = $6 & 24 | 0; - $10 = $9 & -4 | 0; - $1 = $10 + 4 | 0; - $4 = (0 - $6 | 0) & 24 | 0; - $6 = HEAP32[$10 >> 2] | 0; - label$7 : while (1) { - $66 = $6 >>> $2 | 0; - $6 = HEAP32[$1 >> 2] | 0; - HEAP32[$5 >> 2] = $66 | ($6 << $4 | 0) | 0; - $1 = $1 + 4 | 0; - $5 = $5 + 4 | 0; - if ($5 >>> 0 < $3 >>> 0) { - continue label$7 - } - break label$5; - }; - } - if (($8 | 0) < (1 | 0)) { - break label$5 - } - $1 = $9; - label$8 : while (1) { - HEAP32[$5 >> 2] = HEAP32[$1 >> 2] | 0; - $1 = $1 + 4 | 0; - $5 = $5 + 4 | 0; - if ($5 >>> 0 < $3 >>> 0) { - continue label$8 - } - break label$8; - }; - } - $2 = $7 & 3 | 0; - $1 = $9 + $8 | 0; - } - label$9 : { - if (!$2) { - break label$9 - } - $5 = $3 + $2 | 0; - label$10 : while (1) { - HEAP8[$3 >> 0] = HEAPU8[$1 >> 0] | 0; - $1 = $1 + 1 | 0; - $3 = $3 + 1 | 0; - if ($3 >>> 0 < $5 >>> 0) { - continue label$10 - } - break label$10; - }; - } - return $0 | 0; - } - - function _ZN17compiler_builtins3mem7memmove17h66fcfbf60419fbe2E($0, $1, $2) { - $0 = $0 | 0; - $1 = $1 | 0; - $2 = $2 | 0; - var $4 = 0, $5 = 0, $8 = 0, $6 = 0, $3 = 0, $7 = 0, $9 = 0, $10 = 0, $81 = 0, $164 = 0; - label$1 : { - label$2 : { - label$3 : { - label$4 : { - if (($0 - $1 | 0) >>> 0 >= $2 >>> 0) { - break label$4 - } - $3 = $1 + $2 | 0; - $4 = $0 + $2 | 0; - label$5 : { - if ($2 >>> 0 >= 16 >>> 0) { - break label$5 - } - $5 = $0; - break label$2; - } - $5 = $4 & -4 | 0; - $6 = $4 & 3 | 0; - $7 = 0 - $6 | 0; - label$6 : { - if (!$6) { - break label$6 - } - $8 = ($1 + $2 | 0) + -1 | 0; - label$7 : while (1) { - $4 = $4 + -1 | 0; - HEAP8[$4 >> 0] = HEAPU8[$8 >> 0] | 0; - $8 = $8 + -1 | 0; - if ($5 >>> 0 < $4 >>> 0) { - continue label$7 - } - break label$7; - }; - } - $9 = $2 - $6 | 0; - $6 = $9 & -4 | 0; - $4 = $5 - $6 | 0; - label$8 : { - $7 = $3 + $7 | 0; - if (!($7 & 3 | 0)) { - break label$8 - } - if (($6 | 0) < (1 | 0)) { - break label$3 - } - $8 = $7 << 3 | 0; - $2 = $8 & 24 | 0; - $10 = $7 & -4 | 0; - $1 = $10 + -4 | 0; - $3 = (0 - $8 | 0) & 24 | 0; - $8 = HEAP32[$10 >> 2] | 0; - label$9 : while (1) { - $5 = $5 + -4 | 0; - $81 = $8 << $3 | 0; - $8 = HEAP32[$1 >> 2] | 0; - HEAP32[$5 >> 2] = $81 | ($8 >>> $2 | 0) | 0; - $1 = $1 + -4 | 0; - if ($4 >>> 0 < $5 >>> 0) { - continue label$9 - } - break label$3; - }; - } - if (($6 | 0) < (1 | 0)) { - break label$3 - } - $1 = ($9 + $1 | 0) + -4 | 0; - label$10 : while (1) { - $5 = $5 + -4 | 0; - HEAP32[$5 >> 2] = HEAP32[$1 >> 2] | 0; - $1 = $1 + -4 | 0; - if ($4 >>> 0 < $5 >>> 0) { - continue label$10 - } - break label$3; - }; - } - label$11 : { - label$12 : { - if ($2 >>> 0 >= 16 >>> 0) { - break label$12 - } - $4 = $0; - break label$11; - } - $3 = (0 - $0 | 0) & 3 | 0; - $5 = $0 + $3 | 0; - label$13 : { - if (!$3) { - break label$13 - } - $4 = $0; - $8 = $1; - label$14 : while (1) { - HEAP8[$4 >> 0] = HEAPU8[$8 >> 0] | 0; - $8 = $8 + 1 | 0; - $4 = $4 + 1 | 0; - if ($4 >>> 0 < $5 >>> 0) { - continue label$14 - } - break label$14; - }; - } - $9 = $2 - $3 | 0; - $7 = $9 & -4 | 0; - $4 = $5 + $7 | 0; - label$15 : { - label$16 : { - $6 = $1 + $3 | 0; - if (!($6 & 3 | 0)) { - break label$16 - } - if (($7 | 0) < (1 | 0)) { - break label$15 - } - $8 = $6 << 3 | 0; - $2 = $8 & 24 | 0; - $10 = $6 & -4 | 0; - $1 = $10 + 4 | 0; - $3 = (0 - $8 | 0) & 24 | 0; - $8 = HEAP32[$10 >> 2] | 0; - label$17 : while (1) { - $164 = $8 >>> $2 | 0; - $8 = HEAP32[$1 >> 2] | 0; - HEAP32[$5 >> 2] = $164 | ($8 << $3 | 0) | 0; - $1 = $1 + 4 | 0; - $5 = $5 + 4 | 0; - if ($5 >>> 0 < $4 >>> 0) { - continue label$17 - } - break label$15; - }; - } - if (($7 | 0) < (1 | 0)) { - break label$15 - } - $1 = $6; - label$18 : while (1) { - HEAP32[$5 >> 2] = HEAP32[$1 >> 2] | 0; - $1 = $1 + 4 | 0; - $5 = $5 + 4 | 0; - if ($5 >>> 0 < $4 >>> 0) { - continue label$18 - } - break label$18; - }; - } - $2 = $9 & 3 | 0; - $1 = $6 + $7 | 0; - } - if (!$2) { - break label$1 - } - $5 = $4 + $2 | 0; - label$19 : while (1) { - HEAP8[$4 >> 0] = HEAPU8[$1 >> 0] | 0; - $1 = $1 + 1 | 0; - $4 = $4 + 1 | 0; - if ($4 >>> 0 < $5 >>> 0) { - continue label$19 - } - break label$1; - }; - } - $1 = $9 & 3 | 0; - if (!$1) { - break label$1 - } - $3 = $7 + (0 - $6 | 0) | 0; - $5 = $4 - $1 | 0; - } - $1 = $3 + -1 | 0; - label$20 : while (1) { - $4 = $4 + -1 | 0; - HEAP8[$4 >> 0] = HEAPU8[$1 >> 0] | 0; - $1 = $1 + -1 | 0; - if ($5 >>> 0 < $4 >>> 0) { - continue label$20 - } - break label$20; - }; - } - return $0 | 0; - } - - function memmove($0, $1, $2) { - $0 = $0 | 0; - $1 = $1 | 0; - $2 = $2 | 0; - return _ZN17compiler_builtins3mem7memmove17h66fcfbf60419fbe2E($0 | 0, $1 | 0, $2 | 0) | 0 | 0; - } - - function _ZN5alloc11collections5btree4node210Handle$LT$alloc__collections__btree__node__NodeRef$LT$alloc__collections__btree__node__marker__Mut$C$K$C$V$C$alloc__collections__btree__node__marker__Leaf$GT$$C$alloc__collections__btree__node__marker__Edge$GT$16insert_recursing17h01740383b348720fE($0, $1, $2, $3, $4) { - $0 = $0 | 0; - $1 = $1 | 0; - $2 = $2 | 0; - $3 = $3 | 0; - $4 = $4 | 0; - var $6 = 0, $5 = 0, $8 = 0, i64toi32_i32$1 = 0, i64toi32_i32$0 = 0, $11 = 0, $7 = 0, $12 = 0, $10 = 0, $9 = 0, $17 = 0, $14 = 0, $16 = 0, $15 = 0, $13 = 0, $18 = 0, $19 = 0, $74 = 0, $101 = 0, $116 = 0, $143 = 0, $160 = 0, $187 = 0, $202 = 0, $229 = 0, $234 = 0, $269 = 0, $331 = 0, $345 = 0, $389 = 0, $399 = 0, $415 = 0, $432 = 0, $586 = 0, $603 = 0, $693 = 0, $734 = 0, $739 = 0, $755 = 0, $770 = 0, $871 = 0, $890 = 0, $923 = 0; - $5 = __stack_pointer - 80 | 0; - __stack_pointer = $5; - label$1 : { - label$2 : { - label$3 : { - label$4 : { - label$5 : { - label$6 : { - label$7 : { - label$8 : { - label$9 : { - label$10 : { - label$11 : { - label$12 : { - label$13 : { - label$14 : { - label$15 : { - label$16 : { - label$17 : { - label$18 : { - label$19 : { - label$20 : { - $6 = HEAP32[$1 >> 2] | 0; - $7 = HEAPU16[($6 + 182 | 0) >> 1] | 0; - if ($7 >>> 0 < 11 >>> 0) { - break label$20 - } - HEAPU8[(0 + 1051325 | 0) >> 0] | 0; - $8 = HEAP32[($1 + 4 | 0) >> 2] | 0; - $9 = HEAP32[($1 + 8 | 0) >> 2] | 0; - $7 = __rust_alloc(184 | 0, 4 | 0) | 0; - if (!$7) { - break label$12 - } - HEAP16[($7 + 182 | 0) >> 1] = 0; - HEAP32[$7 >> 2] = 0; - if ($9 >>> 0 < 5 >>> 0) { - break label$19 - } - switch ($9 + -5 | 0 | 0) { - case 1: - break label$16; - case 0: - break label$17; - default: - break label$18; - }; - } - $10 = $6 + 4 | 0; - $8 = HEAP32[($1 + 8 | 0) >> 2] | 0; - $11 = $10 + ($8 << 2 | 0) | 0; - $1 = HEAP32[($1 + 4 | 0) >> 2] | 0; - $12 = $8 + 1 | 0; - if ($12 >>> 0 <= $7 >>> 0) { - break label$14 - } - HEAP32[$11 >> 2] = $2; - break label$13; - } - $1 = (HEAPU16[($6 + 182 | 0) >> 1] | 0) + -5 | 0; - HEAP16[($7 + 182 | 0) >> 1] = $1; - $12 = ($5 + 48 | 0) + 8 | 0; - HEAP32[$12 >> 2] = HEAP32[($6 + 104 | 0) >> 2] | 0; - i64toi32_i32$0 = HEAP32[($6 + 96 | 0) >> 2] | 0; - i64toi32_i32$1 = HEAP32[($6 + 100 | 0) >> 2] | 0; - $74 = i64toi32_i32$0; - i64toi32_i32$0 = $5; - HEAP32[($5 + 48 | 0) >> 2] = $74; - HEAP32[($5 + 52 | 0) >> 2] = i64toi32_i32$1; - if ($1 >>> 0 >= 12 >>> 0) { - break label$11 - } - $11 = HEAP32[($6 + 20 | 0) >> 2] | 0; - memcpy($7 + 4 | 0 | 0, $6 + 24 | 0 | 0, $1 << 2 | 0 | 0) | 0; - memcpy($7 + 48 | 0 | 0, $6 + 108 | 0 | 0, Math_imul($1, 12) | 0) | 0; - HEAP16[($6 + 182 | 0) >> 1] = 4; - HEAP32[(($5 + 32 | 0) + 8 | 0) >> 2] = HEAP32[$12 >> 2] | 0; - i64toi32_i32$1 = HEAP32[($5 + 48 | 0) >> 2] | 0; - i64toi32_i32$0 = HEAP32[($5 + 52 | 0) >> 2] | 0; - $101 = i64toi32_i32$1; - i64toi32_i32$1 = $5; - HEAP32[($5 + 32 | 0) >> 2] = $101; - HEAP32[($5 + 36 | 0) >> 2] = i64toi32_i32$0; - break label$7; - } - $1 = (HEAPU16[($6 + 182 | 0) >> 1] | 0) + -7 | 0; - HEAP16[($7 + 182 | 0) >> 1] = $1; - $12 = ($5 + 48 | 0) + 8 | 0; - HEAP32[$12 >> 2] = HEAP32[($6 + 128 | 0) >> 2] | 0; - i64toi32_i32$0 = HEAP32[($6 + 120 | 0) >> 2] | 0; - i64toi32_i32$1 = HEAP32[($6 + 124 | 0) >> 2] | 0; - $116 = i64toi32_i32$0; - i64toi32_i32$0 = $5; - HEAP32[($5 + 48 | 0) >> 2] = $116; - HEAP32[($5 + 52 | 0) >> 2] = i64toi32_i32$1; - if ($1 >>> 0 >= 12 >>> 0) { - break label$10 - } - $11 = HEAP32[($6 + 28 | 0) >> 2] | 0; - memcpy($7 + 4 | 0 | 0, $6 + 32 | 0 | 0, $1 << 2 | 0 | 0) | 0; - memcpy($7 + 48 | 0 | 0, $6 + 132 | 0 | 0, Math_imul($1, 12) | 0) | 0; - HEAP16[($6 + 182 | 0) >> 1] = 6; - HEAP32[(($5 + 32 | 0) + 8 | 0) >> 2] = HEAP32[$12 >> 2] | 0; - i64toi32_i32$1 = HEAP32[($5 + 48 | 0) >> 2] | 0; - i64toi32_i32$0 = HEAP32[($5 + 52 | 0) >> 2] | 0; - $143 = i64toi32_i32$1; - i64toi32_i32$1 = $5; - HEAP32[($5 + 32 | 0) >> 2] = $143; - HEAP32[($5 + 36 | 0) >> 2] = i64toi32_i32$0; - $9 = $9 + -7 | 0; - break label$15; - } - $1 = (HEAPU16[($6 + 182 | 0) >> 1] | 0) + -6 | 0; - HEAP16[($7 + 182 | 0) >> 1] = $1; - $12 = ($5 + 48 | 0) + 8 | 0; - HEAP32[$12 >> 2] = HEAP32[($6 + 116 | 0) >> 2] | 0; - i64toi32_i32$0 = HEAP32[($6 + 108 | 0) >> 2] | 0; - i64toi32_i32$1 = HEAP32[($6 + 112 | 0) >> 2] | 0; - $160 = i64toi32_i32$0; - i64toi32_i32$0 = $5; - HEAP32[($5 + 48 | 0) >> 2] = $160; - HEAP32[($5 + 52 | 0) >> 2] = i64toi32_i32$1; - if ($1 >>> 0 >= 12 >>> 0) { - break label$9 - } - $11 = HEAP32[($6 + 24 | 0) >> 2] | 0; - memcpy($7 + 4 | 0 | 0, $6 + 28 | 0 | 0, $1 << 2 | 0 | 0) | 0; - memcpy($7 + 48 | 0 | 0, $6 + 120 | 0 | 0, Math_imul($1, 12) | 0) | 0; - $9 = 5; - HEAP16[($6 + 182 | 0) >> 1] = 5; - HEAP32[(($5 + 32 | 0) + 8 | 0) >> 2] = HEAP32[$12 >> 2] | 0; - i64toi32_i32$1 = HEAP32[($5 + 48 | 0) >> 2] | 0; - i64toi32_i32$0 = HEAP32[($5 + 52 | 0) >> 2] | 0; - $187 = i64toi32_i32$1; - i64toi32_i32$1 = $5; - HEAP32[($5 + 32 | 0) >> 2] = $187; - HEAP32[($5 + 36 | 0) >> 2] = i64toi32_i32$0; - break label$7; - } - $1 = (HEAPU16[($6 + 182 | 0) >> 1] | 0) + -6 | 0; - HEAP16[($7 + 182 | 0) >> 1] = $1; - $12 = ($5 + 48 | 0) + 8 | 0; - HEAP32[$12 >> 2] = HEAP32[($6 + 116 | 0) >> 2] | 0; - i64toi32_i32$0 = HEAP32[($6 + 108 | 0) >> 2] | 0; - i64toi32_i32$1 = HEAP32[($6 + 112 | 0) >> 2] | 0; - $202 = i64toi32_i32$0; - i64toi32_i32$0 = $5; - HEAP32[($5 + 48 | 0) >> 2] = $202; - HEAP32[($5 + 52 | 0) >> 2] = i64toi32_i32$1; - if ($1 >>> 0 >= 12 >>> 0) { - break label$8 - } - $11 = HEAP32[($6 + 24 | 0) >> 2] | 0; - memcpy($7 + 4 | 0 | 0, $6 + 28 | 0 | 0, $1 << 2 | 0 | 0) | 0; - memcpy($7 + 48 | 0 | 0, $6 + 120 | 0 | 0, Math_imul($1, 12) | 0) | 0; - HEAP16[($6 + 182 | 0) >> 1] = 5; - HEAP32[(($5 + 32 | 0) + 8 | 0) >> 2] = HEAP32[$12 >> 2] | 0; - i64toi32_i32$1 = HEAP32[($5 + 48 | 0) >> 2] | 0; - i64toi32_i32$0 = HEAP32[($5 + 52 | 0) >> 2] | 0; - $229 = i64toi32_i32$1; - i64toi32_i32$1 = $5; - HEAP32[($5 + 32 | 0) >> 2] = $229; - HEAP32[($5 + 36 | 0) >> 2] = i64toi32_i32$0; - $9 = 0; - } - $13 = 0; - $14 = $7; - break label$6; - } - $234 = $10 + ($12 << 2 | 0) | 0; - $10 = $7 - $8 | 0; - memmove($234 | 0, $11 | 0, $10 << 2 | 0 | 0) | 0; - HEAP32[$11 >> 2] = $2; - $11 = $6 + 48 | 0; - memmove($11 + Math_imul($12, 12) | 0 | 0, $11 + Math_imul($8, 12) | 0 | 0, Math_imul($10, 12) | 0) | 0; - } - $11 = $6 + Math_imul($8, 12) | 0; - HEAP32[($11 + 56 | 0) >> 2] = HEAP32[($3 + 8 | 0) >> 2] | 0; - i64toi32_i32$0 = HEAP32[$3 >> 2] | 0; - i64toi32_i32$1 = HEAP32[($3 + 4 | 0) >> 2] | 0; - $269 = i64toi32_i32$0; - i64toi32_i32$0 = $11 + 48 | 0; - HEAP32[i64toi32_i32$0 >> 2] = $269; - HEAP32[(i64toi32_i32$0 + 4 | 0) >> 2] = i64toi32_i32$1; - HEAP16[($6 + 182 | 0) >> 1] = $7 + 1 | 0; - HEAP32[($0 + 8 | 0) >> 2] = $8; - HEAP32[($0 + 4 | 0) >> 2] = $1; - HEAP32[$0 >> 2] = $6; - break label$5; - } - _ZN5alloc5alloc18handle_alloc_error17h123ae56be4092711E(4 | 0, 184 | 0); - wasm2js_trap(); - } - _ZN4core5slice5index24slice_end_index_len_fail17h02d344349d5072f8E($1 | 0, 11 | 0, 1050144 | 0); - wasm2js_trap(); - } - _ZN4core5slice5index24slice_end_index_len_fail17h02d344349d5072f8E($1 | 0, 11 | 0, 1050144 | 0); - wasm2js_trap(); - } - _ZN4core5slice5index24slice_end_index_len_fail17h02d344349d5072f8E($1 | 0, 11 | 0, 1050144 | 0); - wasm2js_trap(); - } - _ZN4core5slice5index24slice_end_index_len_fail17h02d344349d5072f8E($1 | 0, 11 | 0, 1050144 | 0); - wasm2js_trap(); - } - $13 = $8; - $14 = $6; - } - $1 = ($14 + 4 | 0) + ($9 << 2 | 0) | 0; - label$21 : { - label$22 : { - $10 = HEAPU16[($14 + 182 | 0) >> 1] | 0; - if ($10 >>> 0 > $9 >>> 0) { - break label$22 - } - HEAP32[$1 >> 2] = $2; - break label$21; - } - $12 = $10 - $9 | 0; - memmove($1 + 4 | 0 | 0, $1 | 0, $12 << 2 | 0 | 0) | 0; - HEAP32[$1 >> 2] = $2; - $1 = $14 + Math_imul($9, 12) | 0; - memmove($1 + 60 | 0 | 0, $1 + 48 | 0 | 0, Math_imul($12, 12) | 0) | 0; - } - $1 = $14 + Math_imul($9, 12) | 0; - HEAP32[($1 + 56 | 0) >> 2] = HEAP32[($3 + 8 | 0) >> 2] | 0; - i64toi32_i32$1 = HEAP32[$3 >> 2] | 0; - i64toi32_i32$0 = HEAP32[($3 + 4 | 0) >> 2] | 0; - $331 = i64toi32_i32$1; - i64toi32_i32$1 = $1 + 48 | 0; - HEAP32[i64toi32_i32$1 >> 2] = $331; - HEAP32[(i64toi32_i32$1 + 4 | 0) >> 2] = i64toi32_i32$0; - $12 = ($5 + 16 | 0) + 8 | 0; - HEAP32[$12 >> 2] = HEAP32[(($5 + 32 | 0) + 8 | 0) >> 2] | 0; - HEAP16[($14 + 182 | 0) >> 1] = $10 + 1 | 0; - i64toi32_i32$0 = HEAP32[($5 + 32 | 0) >> 2] | 0; - i64toi32_i32$1 = HEAP32[($5 + 36 | 0) >> 2] | 0; - $345 = i64toi32_i32$0; - i64toi32_i32$0 = $5; - HEAP32[($5 + 16 | 0) >> 2] = $345; - HEAP32[($5 + 20 | 0) >> 2] = i64toi32_i32$1; - label$23 : { - label$24 : { - label$25 : { - $1 = HEAP32[$6 >> 2] | 0; - if ($1) { - break label$25 - } - $3 = 0; - break label$24; - } - $10 = $5 + 68 | 0; - $3 = 0; - label$26 : while (1) { - if (($8 | 0) != ($3 | 0)) { - break label$4 - } - $3 = HEAPU16[($6 + 180 | 0) >> 1] | 0; - label$27 : { - label$28 : { - label$29 : { - label$30 : { - label$31 : { - label$32 : { - label$33 : { - label$34 : { - $2 = HEAPU16[($1 + 182 | 0) >> 1] | 0; - if ($2 >>> 0 < 11 >>> 0) { - break label$34 - } - $6 = $8 + 1 | 0; - if ($3 >>> 0 < 5 >>> 0) { - break label$33 - } - switch ($3 + -5 | 0 | 0) { - case 1: - break label$30; - case 0: - break label$31; - default: - break label$32; - }; - } - $10 = $1 + 4 | 0; - $15 = $3 << 2 | 0; - $8 = $10 + $15 | 0; - $6 = $3 + 1 | 0; - $12 = $2 + 1 | 0; - label$35 : { - label$36 : { - if ($3 >>> 0 < $2 >>> 0) { - break label$36 - } - HEAP32[$8 >> 2] = $11; - $8 = $1 + Math_imul($3, 12) | 0; - i64toi32_i32$1 = HEAP32[($5 + 16 | 0) >> 2] | 0; - i64toi32_i32$0 = HEAP32[($5 + 20 | 0) >> 2] | 0; - $389 = i64toi32_i32$1; - i64toi32_i32$1 = $8 + 48 | 0; - HEAP32[i64toi32_i32$1 >> 2] = $389; - HEAP32[(i64toi32_i32$1 + 4 | 0) >> 2] = i64toi32_i32$0; - HEAP32[($8 + 56 | 0) >> 2] = HEAP32[($5 + 24 | 0) >> 2] | 0; - break label$35; - } - $16 = $6 << 2 | 0; - $399 = $10 + $16 | 0; - $10 = $2 - $3 | 0; - $17 = $10 << 2 | 0; - memmove($399 | 0, $8 | 0, $17 | 0) | 0; - HEAP32[$8 >> 2] = $11; - $8 = $1 + 48 | 0; - $415 = $8 + Math_imul($6, 12) | 0; - $8 = $8 + Math_imul($3, 12) | 0; - memmove($415 | 0, $8 | 0, Math_imul($10, 12) | 0) | 0; - HEAP32[($8 + 8 | 0) >> 2] = HEAP32[(($5 + 16 | 0) + 8 | 0) >> 2] | 0; - i64toi32_i32$0 = HEAP32[($5 + 16 | 0) >> 2] | 0; - i64toi32_i32$1 = HEAP32[($5 + 20 | 0) >> 2] | 0; - $432 = i64toi32_i32$0; - i64toi32_i32$0 = $8; - HEAP32[$8 >> 2] = $432; - HEAP32[($8 + 4 | 0) >> 2] = i64toi32_i32$1; - $8 = $1 + 184 | 0; - memmove(($8 + $15 | 0) + 8 | 0 | 0, $8 + $16 | 0 | 0, $17 | 0) | 0; - } - HEAP16[($1 + 182 | 0) >> 1] = $12; - HEAP32[(($1 + ($6 << 2 | 0) | 0) + 184 | 0) >> 2] = $7; - $11 = $2 + 2 | 0; - if ($6 >>> 0 >= $11 >>> 0) { - break label$23 - } - label$37 : { - $2 = $2 - $3 | 0; - $8 = ($2 + 1 | 0) & 3 | 0; - if (!$8) { - break label$37 - } - $3 = ($1 + ($3 << 2 | 0) | 0) + 188 | 0; - label$38 : while (1) { - $7 = HEAP32[$3 >> 2] | 0; - HEAP16[($7 + 180 | 0) >> 1] = $6; - HEAP32[$7 >> 2] = $1; - $3 = $3 + 4 | 0; - $6 = $6 + 1 | 0; - $8 = $8 + -1 | 0; - if ($8) { - continue label$38 - } - break label$38; - }; - } - if ($2 >>> 0 < 3 >>> 0) { - break label$23 - } - $3 = (($6 << 2 | 0) + $1 | 0) + 196 | 0; - label$39 : while (1) { - $8 = HEAP32[($3 + -12 | 0) >> 2] | 0; - HEAP16[($8 + 180 | 0) >> 1] = $6; - HEAP32[$8 >> 2] = $1; - $8 = HEAP32[($3 + -8 | 0) >> 2] | 0; - HEAP16[($8 + 180 | 0) >> 1] = $6 + 1 | 0; - HEAP32[$8 >> 2] = $1; - $8 = HEAP32[($3 + -4 | 0) >> 2] | 0; - HEAP16[($8 + 180 | 0) >> 1] = $6 + 2 | 0; - HEAP32[$8 >> 2] = $1; - $8 = HEAP32[$3 >> 2] | 0; - HEAP16[($8 + 180 | 0) >> 1] = $6 + 3 | 0; - HEAP32[$8 >> 2] = $1; - $3 = $3 + 16 | 0; - $6 = $6 + 4 | 0; - if (($11 | 0) != ($6 | 0)) { - continue label$39 - } - break label$23; - }; - } - HEAP32[($5 + 40 | 0) >> 2] = 4; - HEAP32[($5 + 36 | 0) >> 2] = $6; - HEAP32[($5 + 32 | 0) >> 2] = $1; - _ZN5alloc11collections5btree4node212Handle$LT$alloc__collections__btree__node__NodeRef$LT$alloc__collections__btree__node__marker__Mut$C$K$C$V$C$alloc__collections__btree__node__marker__Internal$GT$$C$alloc__collections__btree__node__marker__KV$GT$5split17h714854686ba3ee4cE($5 + 48 | 0 | 0, $5 + 32 | 0 | 0); - $1 = HEAP32[($5 + 48 | 0) >> 2] | 0; - break label$28; - } - HEAP32[($5 + 40 | 0) >> 2] = 6; - HEAP32[($5 + 36 | 0) >> 2] = $6; - HEAP32[($5 + 32 | 0) >> 2] = $1; - $3 = $3 + -7 | 0; - break label$29; - } - HEAP32[($5 + 40 | 0) >> 2] = 5; - HEAP32[($5 + 36 | 0) >> 2] = $6; - HEAP32[($5 + 32 | 0) >> 2] = $1; - _ZN5alloc11collections5btree4node212Handle$LT$alloc__collections__btree__node__NodeRef$LT$alloc__collections__btree__node__marker__Mut$C$K$C$V$C$alloc__collections__btree__node__marker__Internal$GT$$C$alloc__collections__btree__node__marker__KV$GT$5split17h714854686ba3ee4cE($5 + 48 | 0 | 0, $5 + 32 | 0 | 0); - $6 = HEAP32[($5 + 48 | 0) >> 2] | 0; - $1 = HEAPU16[($6 + 182 | 0) >> 1] | 0; - $3 = $1 + 1 | 0; - label$40 : { - label$41 : { - label$42 : { - if ($1 >>> 0 < 6 >>> 0) { - break label$42 - } - $8 = $1 + -5 | 0; - memmove($6 + 28 | 0 | 0, $6 + 24 | 0 | 0, $8 << 2 | 0 | 0) | 0; - HEAP32[($6 + 24 | 0) >> 2] = $11; - memmove($6 + 120 | 0 | 0, $6 + 108 | 0 | 0, Math_imul($8, 12) | 0) | 0; - HEAP32[($6 + 116 | 0) >> 2] = HEAP32[$12 >> 2] | 0; - i64toi32_i32$1 = HEAP32[($5 + 16 | 0) >> 2] | 0; - i64toi32_i32$0 = HEAP32[($5 + 20 | 0) >> 2] | 0; - $586 = i64toi32_i32$1; - i64toi32_i32$1 = $6; - HEAP32[($6 + 108 | 0) >> 2] = $586; - HEAP32[($6 + 112 | 0) >> 2] = i64toi32_i32$0; - memmove($6 + 212 | 0 | 0, $6 + 208 | 0 | 0, ($1 << 2 | 0) + -20 | 0 | 0) | 0; - HEAP16[($6 + 182 | 0) >> 1] = $3; - HEAP32[($6 + 208 | 0) >> 2] = $7; - break label$41; - } - HEAP32[($6 + 24 | 0) >> 2] = $11; - i64toi32_i32$0 = HEAP32[($5 + 16 | 0) >> 2] | 0; - i64toi32_i32$1 = HEAP32[($5 + 20 | 0) >> 2] | 0; - $603 = i64toi32_i32$0; - i64toi32_i32$0 = $6; - HEAP32[($6 + 108 | 0) >> 2] = $603; - HEAP32[($6 + 112 | 0) >> 2] = i64toi32_i32$1; - HEAP32[($6 + 208 | 0) >> 2] = $7; - HEAP16[($6 + 182 | 0) >> 1] = $3; - HEAP32[($6 + 116 | 0) >> 2] = HEAP32[$12 >> 2] | 0; - if (($1 | 0) != (5 | 0)) { - break label$40 - } - } - $7 = $1 & 3 | 0; - $3 = 6; - label$43 : { - if (($1 + -5 | 0) >>> 0 < 3 >>> 0) { - break label$43 - } - $2 = ($1 & 65532 | 0) + -8 | 0; - $1 = 6; - $8 = 0; - label$44 : while (1) { - $3 = $6 + $8 | 0; - $11 = HEAP32[($3 + 208 | 0) >> 2] | 0; - HEAP16[($11 + 180 | 0) >> 1] = $1; - HEAP32[$11 >> 2] = $6; - $11 = HEAP32[($3 + 212 | 0) >> 2] | 0; - HEAP16[($11 + 180 | 0) >> 1] = $1 + 1 | 0; - HEAP32[$11 >> 2] = $6; - $11 = HEAP32[($3 + 216 | 0) >> 2] | 0; - HEAP16[($11 + 180 | 0) >> 1] = $1 + 2 | 0; - HEAP32[$11 >> 2] = $6; - $3 = HEAP32[($3 + 220 | 0) >> 2] | 0; - HEAP16[($3 + 180 | 0) >> 1] = $1 + 3 | 0; - HEAP32[$3 >> 2] = $6; - $8 = $8 + 16 | 0; - $11 = $1 + -6 | 0; - $3 = $1 + 4 | 0; - $1 = $3; - if (($11 | 0) != ($2 | 0)) { - continue label$44 - } - break label$44; - }; - } - if (!$7) { - break label$40 - } - $1 = ($6 + ($3 << 2 | 0) | 0) + 184 | 0; - label$45 : while (1) { - $8 = HEAP32[$1 >> 2] | 0; - HEAP16[($8 + 180 | 0) >> 1] = $3; - HEAP32[$8 >> 2] = $6; - $1 = $1 + 4 | 0; - $3 = $3 + 1 | 0; - $7 = $7 + -1 | 0; - if ($7) { - continue label$45 - } - break label$45; - }; - } - HEAP32[($5 + 8 | 0) >> 2] = HEAP32[($10 + 8 | 0) >> 2] | 0; - i64toi32_i32$1 = HEAP32[$10 >> 2] | 0; - i64toi32_i32$0 = HEAP32[($10 + 4 | 0) >> 2] | 0; - $693 = i64toi32_i32$1; - i64toi32_i32$1 = $5; - HEAP32[$5 >> 2] = $693; - HEAP32[($5 + 4 | 0) >> 2] = i64toi32_i32$0; - break label$27; - } - HEAP32[($5 + 40 | 0) >> 2] = 5; - HEAP32[($5 + 36 | 0) >> 2] = $6; - HEAP32[($5 + 32 | 0) >> 2] = $1; - $3 = 0; - } - _ZN5alloc11collections5btree4node212Handle$LT$alloc__collections__btree__node__NodeRef$LT$alloc__collections__btree__node__marker__Mut$C$K$C$V$C$alloc__collections__btree__node__marker__Internal$GT$$C$alloc__collections__btree__node__marker__KV$GT$5split17h714854686ba3ee4cE($5 + 48 | 0 | 0, $5 + 32 | 0 | 0); - $1 = HEAP32[($5 + 56 | 0) >> 2] | 0; - } - $17 = $1 + 4 | 0; - $16 = $3 << 2 | 0; - $2 = $17 + $16 | 0; - $6 = $3 + 1 | 0; - $8 = HEAPU16[($1 + 182 | 0) >> 1] | 0; - $15 = $8 + 1 | 0; - label$46 : { - label$47 : { - if ($8 >>> 0 > $3 >>> 0) { - break label$47 - } - HEAP32[$2 >> 2] = $11; - $11 = $1 + Math_imul($3, 12) | 0; - HEAP32[($11 + 56 | 0) >> 2] = HEAP32[$12 >> 2] | 0; - i64toi32_i32$0 = HEAP32[($5 + 16 | 0) >> 2] | 0; - i64toi32_i32$1 = HEAP32[($5 + 20 | 0) >> 2] | 0; - $734 = i64toi32_i32$0; - i64toi32_i32$0 = $11 + 48 | 0; - HEAP32[i64toi32_i32$0 >> 2] = $734; - HEAP32[(i64toi32_i32$0 + 4 | 0) >> 2] = i64toi32_i32$1; - break label$46; - } - $18 = $6 << 2 | 0; - $739 = $17 + $18 | 0; - $17 = $8 - $3 | 0; - $19 = $17 << 2 | 0; - memmove($739 | 0, $2 | 0, $19 | 0) | 0; - HEAP32[$2 >> 2] = $11; - $11 = $1 + 48 | 0; - $755 = $11 + Math_imul($6, 12) | 0; - $11 = $11 + Math_imul($3, 12) | 0; - memmove($755 | 0, $11 | 0, Math_imul($17, 12) | 0) | 0; - HEAP32[($11 + 8 | 0) >> 2] = HEAP32[$12 >> 2] | 0; - i64toi32_i32$1 = HEAP32[($5 + 16 | 0) >> 2] | 0; - i64toi32_i32$0 = HEAP32[($5 + 20 | 0) >> 2] | 0; - $770 = i64toi32_i32$1; - i64toi32_i32$1 = $11; - HEAP32[i64toi32_i32$1 >> 2] = $770; - HEAP32[(i64toi32_i32$1 + 4 | 0) >> 2] = i64toi32_i32$0; - $11 = $1 + 184 | 0; - memmove(($11 + $16 | 0) + 8 | 0 | 0, $11 + $18 | 0 | 0, $19 | 0) | 0; - } - HEAP32[(($1 + ($6 << 2 | 0) | 0) + 184 | 0) >> 2] = $7; - HEAP16[($1 + 182 | 0) >> 1] = $15; - label$48 : { - $11 = $8 + 2 | 0; - if ($6 >>> 0 >= $11 >>> 0) { - break label$48 - } - label$49 : { - $2 = $8 - $3 | 0; - $8 = ($2 + 1 | 0) & 3 | 0; - if (!$8) { - break label$49 - } - $3 = ($1 + $16 | 0) + 188 | 0; - label$50 : while (1) { - $7 = HEAP32[$3 >> 2] | 0; - HEAP16[($7 + 180 | 0) >> 1] = $6; - HEAP32[$7 >> 2] = $1; - $3 = $3 + 4 | 0; - $6 = $6 + 1 | 0; - $8 = $8 + -1 | 0; - if ($8) { - continue label$50 - } - break label$50; - }; - } - if ($2 >>> 0 < 3 >>> 0) { - break label$48 - } - $3 = ($1 + ($6 << 2 | 0) | 0) + 196 | 0; - label$51 : while (1) { - $8 = HEAP32[($3 + -12 | 0) >> 2] | 0; - HEAP16[($8 + 180 | 0) >> 1] = $6; - HEAP32[$8 >> 2] = $1; - $8 = HEAP32[($3 + -8 | 0) >> 2] | 0; - HEAP16[($8 + 180 | 0) >> 1] = $6 + 1 | 0; - HEAP32[$8 >> 2] = $1; - $8 = HEAP32[($3 + -4 | 0) >> 2] | 0; - HEAP16[($8 + 180 | 0) >> 1] = $6 + 2 | 0; - HEAP32[$8 >> 2] = $1; - $8 = HEAP32[$3 >> 2] | 0; - HEAP16[($8 + 180 | 0) >> 1] = $6 + 3 | 0; - HEAP32[$8 >> 2] = $1; - $3 = $3 + 16 | 0; - $6 = $6 + 4 | 0; - if (($11 | 0) != ($6 | 0)) { - continue label$51 - } - break label$51; - }; - } - HEAP32[($5 + 8 | 0) >> 2] = HEAP32[($10 + 8 | 0) >> 2] | 0; - i64toi32_i32$0 = HEAP32[$10 >> 2] | 0; - i64toi32_i32$1 = HEAP32[($10 + 4 | 0) >> 2] | 0; - $871 = i64toi32_i32$0; - i64toi32_i32$0 = $5; - HEAP32[$5 >> 2] = $871; - HEAP32[($5 + 4 | 0) >> 2] = i64toi32_i32$1; - $6 = HEAP32[($5 + 48 | 0) >> 2] | 0; - if (!$6) { - break label$23 - } - } - $11 = HEAP32[($5 + 64 | 0) >> 2] | 0; - $3 = HEAP32[($5 + 60 | 0) >> 2] | 0; - $7 = HEAP32[($5 + 56 | 0) >> 2] | 0; - $8 = HEAP32[($5 + 52 | 0) >> 2] | 0; - HEAP32[$12 >> 2] = HEAP32[($5 + 8 | 0) >> 2] | 0; - i64toi32_i32$1 = HEAP32[$5 >> 2] | 0; - i64toi32_i32$0 = HEAP32[($5 + 4 | 0) >> 2] | 0; - $890 = i64toi32_i32$1; - i64toi32_i32$1 = $5; - HEAP32[($5 + 16 | 0) >> 2] = $890; - HEAP32[($5 + 20 | 0) >> 2] = i64toi32_i32$0; - $1 = HEAP32[$6 >> 2] | 0; - if ($1) { - continue label$26 - } - break label$26; - }; - } - $1 = HEAP32[$4 >> 2] | 0; - $8 = HEAP32[$1 >> 2] | 0; - if (!$8) { - break label$3 - } - HEAPU8[(0 + 1051325 | 0) >> 0] | 0; - $2 = HEAP32[($1 + 4 | 0) >> 2] | 0; - $6 = __rust_alloc(232 | 0, 4 | 0) | 0; - if (!$6) { - break label$2 - } - HEAP32[($6 + 184 | 0) >> 2] = $8; - HEAP16[($6 + 182 | 0) >> 1] = 0; - HEAP32[$6 >> 2] = 0; - HEAP16[($8 + 180 | 0) >> 1] = 0; - HEAP32[$8 >> 2] = $6; - HEAP32[($1 + 4 | 0) >> 2] = $2 + 1 | 0; - HEAP32[$1 >> 2] = $6; - if (($2 | 0) != ($3 | 0)) { - break label$1 - } - i64toi32_i32$0 = HEAP32[($5 + 16 | 0) >> 2] | 0; - i64toi32_i32$1 = HEAP32[($5 + 20 | 0) >> 2] | 0; - $923 = i64toi32_i32$0; - i64toi32_i32$0 = $6; - HEAP32[($6 + 48 | 0) >> 2] = $923; - HEAP32[($6 + 52 | 0) >> 2] = i64toi32_i32$1; - HEAP32[($6 + 4 | 0) >> 2] = $11; - HEAP16[($6 + 182 | 0) >> 1] = 1; - HEAP32[($6 + 188 | 0) >> 2] = $7; - HEAP32[($6 + 56 | 0) >> 2] = HEAP32[($5 + 24 | 0) >> 2] | 0; - HEAP16[($7 + 180 | 0) >> 1] = 1; - HEAP32[$7 >> 2] = $6; - } - HEAP32[($0 + 8 | 0) >> 2] = $9; - HEAP32[($0 + 4 | 0) >> 2] = $13; - HEAP32[$0 >> 2] = $14; - } - __stack_pointer = $5 + 80 | 0; - return; - } - _ZN4core9panicking5panic17h9f0a34b0744fbd45E(1050176 | 0, 53 | 0, 1050232 | 0); - wasm2js_trap(); - } - _ZN4core6option13unwrap_failed17h98817bc8a3accaffE(1049776 | 0); - wasm2js_trap(); - } - _ZN5alloc5alloc18handle_alloc_error17h123ae56be4092711E(4 | 0, 232 | 0); - wasm2js_trap(); - } - _ZN4core9panicking5panic17h9f0a34b0744fbd45E(1049883 | 0, 48 | 0, 1049932 | 0); - wasm2js_trap(); - } - - function _ZN5alloc11collections5btree4node212Handle$LT$alloc__collections__btree__node__NodeRef$LT$alloc__collections__btree__node__marker__Mut$C$K$C$V$C$alloc__collections__btree__node__marker__Internal$GT$$C$alloc__collections__btree__node__marker__KV$GT$5split17h714854686ba3ee4cE($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - var $2 = 0, $7 = 0, $8 = 0, $10 = 0, $6 = 0, $5 = 0, $3 = 0, i64toi32_i32$0 = 0, i64toi32_i32$1 = 0, $9 = 0, $4 = 0, $48 = 0, $11 = 0, $93 = 0, $146 = 0; - $2 = __stack_pointer - 32 | 0; - __stack_pointer = $2; - HEAPU8[(0 + 1051325 | 0) >> 0] | 0; - $3 = HEAP32[$1 >> 2] | 0; - $4 = HEAPU16[($3 + 182 | 0) >> 1] | 0; - label$1 : { - label$2 : { - label$3 : { - label$4 : { - label$5 : { - $5 = __rust_alloc(232 | 0, 4 | 0) | 0; - if (!$5) { - break label$5 - } - HEAP32[$5 >> 2] = 0; - $6 = HEAPU16[($3 + 182 | 0) >> 1] | 0; - $7 = HEAP32[($1 + 8 | 0) >> 2] | 0; - $8 = $6 + ($7 ^ -1 | 0) | 0; - HEAP16[($5 + 182 | 0) >> 1] = $8; - $9 = $3 + 48 | 0; - $10 = $9 + Math_imul($7, 12) | 0; - HEAP32[(($2 + 16 | 0) + 8 | 0) >> 2] = HEAP32[($10 + 8 | 0) >> 2] | 0; - i64toi32_i32$0 = HEAP32[$10 >> 2] | 0; - i64toi32_i32$1 = HEAP32[($10 + 4 | 0) >> 2] | 0; - $48 = i64toi32_i32$0; - i64toi32_i32$0 = $2; - HEAP32[($2 + 16 | 0) >> 2] = $48; - HEAP32[($2 + 20 | 0) >> 2] = i64toi32_i32$1; - if ($8 >>> 0 >= 12 >>> 0) { - break label$4 - } - $10 = $7 + 1 | 0; - if (($6 - $10 | 0 | 0) != ($8 | 0)) { - break label$3 - } - $6 = $3 + 4 | 0; - $11 = HEAP32[($6 + ($7 << 2 | 0) | 0) >> 2] | 0; - memcpy($5 + 4 | 0 | 0, $6 + ($10 << 2 | 0) | 0 | 0, $8 << 2 | 0 | 0) | 0; - memcpy($5 + 48 | 0 | 0, $9 + Math_imul($10, 12) | 0 | 0, Math_imul($8, 12) | 0) | 0; - HEAP16[($3 + 182 | 0) >> 1] = $7; - HEAP32[($2 + 8 | 0) >> 2] = HEAP32[(($2 + 16 | 0) + 8 | 0) >> 2] | 0; - i64toi32_i32$1 = HEAP32[($2 + 16 | 0) >> 2] | 0; - i64toi32_i32$0 = HEAP32[($2 + 20 | 0) >> 2] | 0; - $93 = i64toi32_i32$1; - i64toi32_i32$1 = $2; - HEAP32[$2 >> 2] = $93; - HEAP32[($2 + 4 | 0) >> 2] = i64toi32_i32$0; - $8 = HEAPU16[($5 + 182 | 0) >> 1] | 0; - $10 = $8 + 1 | 0; - if ($8 >>> 0 >= 12 >>> 0) { - break label$2 - } - $6 = $4 - $7 | 0; - if (($6 | 0) != ($10 | 0)) { - break label$1 - } - $10 = memcpy($5 + 184 | 0 | 0, ($3 + ($7 << 2 | 0) | 0) + 188 | 0 | 0, $6 << 2 | 0 | 0) | 0; - $6 = HEAP32[($1 + 4 | 0) >> 2] | 0; - $7 = 0; - label$6 : { - label$7 : while (1) { - $1 = HEAP32[($10 + ($7 << 2 | 0) | 0) >> 2] | 0; - HEAP16[($1 + 180 | 0) >> 1] = $7; - HEAP32[$1 >> 2] = $5; - if ($7 >>> 0 >= $8 >>> 0) { - break label$6 - } - $7 = $7 + ($7 >>> 0 < $8 >>> 0) | 0; - if ($7 >>> 0 <= $8 >>> 0) { - continue label$7 - } - break label$7; - }; - } - HEAP32[($0 + 16 | 0) >> 2] = $11; - HEAP32[($0 + 4 | 0) >> 2] = $6; - HEAP32[$0 >> 2] = $3; - i64toi32_i32$0 = HEAP32[$2 >> 2] | 0; - i64toi32_i32$1 = HEAP32[($2 + 4 | 0) >> 2] | 0; - $146 = i64toi32_i32$0; - i64toi32_i32$0 = $0; - HEAP32[($0 + 20 | 0) >> 2] = $146; - HEAP32[($0 + 24 | 0) >> 2] = i64toi32_i32$1; - HEAP32[($0 + 12 | 0) >> 2] = $6; - HEAP32[($0 + 8 | 0) >> 2] = $5; - HEAP32[($0 + 28 | 0) >> 2] = HEAP32[($2 + 8 | 0) >> 2] | 0; - __stack_pointer = $2 + 32 | 0; - return; - } - _ZN5alloc5alloc18handle_alloc_error17h123ae56be4092711E(4 | 0, 232 | 0); - wasm2js_trap(); - } - _ZN4core5slice5index24slice_end_index_len_fail17h02d344349d5072f8E($8 | 0, 11 | 0, 1050144 | 0); - wasm2js_trap(); - } - _ZN4core9panicking5panic17h9f0a34b0744fbd45E(1050088 | 0, 40 | 0, 1050128 | 0); - wasm2js_trap(); - } - _ZN4core5slice5index24slice_end_index_len_fail17h02d344349d5072f8E($10 | 0, 12 | 0, 1050160 | 0); - wasm2js_trap(); - } - _ZN4core9panicking5panic17h9f0a34b0744fbd45E(1050088 | 0, 40 | 0, 1050128 | 0); - wasm2js_trap(); - } - - function _ZN5alloc11collections5btree4node29BalancingContext$LT$K$C$V$GT$15bulk_steal_left17hdff94e2f76df3257E($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - var $8 = 0, $9 = 0, $3 = 0, $4 = 0, $6 = 0, $7 = 0, i64toi32_i32$0 = 0, i64toi32_i32$1 = 0, $12 = 0, $2 = 0, $5 = 0, $10 = 0, $11 = 0, $13 = 0, $14 = 0, $15 = 0, $16 = 0, $17 = 0, $15$hi = 0, $18 = 0, $19 = 0, $19$hi = 0; - $2 = __stack_pointer - 32 | 0; - __stack_pointer = $2; - label$1 : { - label$2 : { - label$3 : { - label$4 : { - label$5 : { - label$6 : { - $3 = HEAP32[($0 + 20 | 0) >> 2] | 0; - $4 = HEAPU16[($3 + 182 | 0) >> 1] | 0; - $5 = $4 + $1 | 0; - if ($5 >>> 0 >= 12 >>> 0) { - break label$6 - } - $6 = HEAP32[($0 + 12 | 0) >> 2] | 0; - $7 = HEAPU16[($6 + 182 | 0) >> 1] | 0; - if ($7 >>> 0 < $1 >>> 0) { - break label$5 - } - $8 = $7 - $1 | 0; - HEAP16[($6 + 182 | 0) >> 1] = $8; - HEAP16[($3 + 182 | 0) >> 1] = $5; - $9 = $3 + 4 | 0; - $10 = $1 << 2 | 0; - $11 = $4 << 2 | 0; - memmove($9 + $10 | 0 | 0, $9 | 0, $11 | 0) | 0; - $12 = $3 + 48 | 0; - memmove($12 + Math_imul($1, 12) | 0 | 0, $12 | 0, Math_imul($4, 12) | 0) | 0; - $4 = $8 + 1 | 0; - $7 = $7 - $4 | 0; - if (($7 | 0) != ($1 + -1 | 0 | 0)) { - break label$4 - } - $13 = $6 + 4 | 0; - memcpy($9 | 0, $13 + ($4 << 2 | 0) | 0 | 0, $7 << 2 | 0 | 0) | 0; - $9 = $6 + 48 | 0; - $7 = Math_imul($7, 12); - $12 = memcpy($12 | 0, $9 + Math_imul($4, 12) | 0 | 0, $7 | 0) | 0; - $9 = $9 + Math_imul($8, 12) | 0; - $14 = HEAP32[($9 + 8 | 0) >> 2] | 0; - HEAP32[($2 + 8 | 0) >> 2] = $14; - i64toi32_i32$0 = HEAP32[$9 >> 2] | 0; - i64toi32_i32$1 = HEAP32[($9 + 4 | 0) >> 2] | 0; - $15 = i64toi32_i32$0; - $15$hi = i64toi32_i32$1; - $9 = HEAP32[$0 >> 2] | 0; - $16 = HEAP32[($0 + 8 | 0) >> 2] | 0; - $17 = ($9 + ($16 << 2 | 0) | 0) + 4 | 0; - $18 = HEAP32[$17 >> 2] | 0; - HEAP32[$17 >> 2] = HEAP32[($13 + ($8 << 2 | 0) | 0) >> 2] | 0; - i64toi32_i32$0 = $2; - HEAP32[i64toi32_i32$0 >> 2] = $15; - HEAP32[(i64toi32_i32$0 + 4 | 0) >> 2] = i64toi32_i32$1; - $8 = $9 + Math_imul($16, 12) | 0; - $9 = $8 + 48 | 0; - i64toi32_i32$1 = HEAP32[$9 >> 2] | 0; - i64toi32_i32$0 = HEAP32[($9 + 4 | 0) >> 2] | 0; - $19 = i64toi32_i32$1; - $19$hi = i64toi32_i32$0; - i64toi32_i32$0 = $15$hi; - i64toi32_i32$1 = $9; - HEAP32[$9 >> 2] = $15; - HEAP32[($9 + 4 | 0) >> 2] = i64toi32_i32$0; - $8 = $8 + 56 | 0; - $9 = HEAP32[$8 >> 2] | 0; - HEAP32[$8 >> 2] = $14; - HEAP32[($3 + $10 | 0) >> 2] = $18; - $8 = $12 + $7 | 0; - HEAP32[($8 + 8 | 0) >> 2] = $9; - i64toi32_i32$0 = $19$hi; - i64toi32_i32$1 = $8; - HEAP32[$8 >> 2] = $19; - HEAP32[($8 + 4 | 0) >> 2] = i64toi32_i32$0; - $8 = HEAP32[($0 + 24 | 0) >> 2] | 0; - label$7 : { - if (HEAP32[($0 + 16 | 0) >> 2] | 0) { - break label$7 - } - if (!$8) { - break label$2 - } - break label$1; - } - if (!$8) { - break label$1 - } - $0 = $3 + 184 | 0; - $1 = $1 << 2 | 0; - memmove($0 + $1 | 0 | 0, $0 | 0, $11 + 4 | 0 | 0) | 0; - memcpy($0 | 0, ($6 + ($4 << 2 | 0) | 0) + 184 | 0 | 0, $1 | 0) | 0; - $8 = $5 + 1 | 0; - $6 = $8 & 3 | 0; - $1 = 0; - if ($5 >>> 0 < 3 >>> 0) { - break label$3 - } - $0 = $3 + 196 | 0; - $4 = $8 & 60 | 0; - $1 = 0; - label$8 : while (1) { - $8 = HEAP32[($0 + -12 | 0) >> 2] | 0; - HEAP16[($8 + 180 | 0) >> 1] = $1; - HEAP32[$8 >> 2] = $3; - $8 = HEAP32[($0 + -8 | 0) >> 2] | 0; - HEAP16[($8 + 180 | 0) >> 1] = $1 + 1 | 0; - HEAP32[$8 >> 2] = $3; - $8 = HEAP32[($0 + -4 | 0) >> 2] | 0; - HEAP16[($8 + 180 | 0) >> 1] = $1 + 2 | 0; - HEAP32[$8 >> 2] = $3; - $8 = HEAP32[$0 >> 2] | 0; - HEAP16[($8 + 180 | 0) >> 1] = $1 + 3 | 0; - HEAP32[$8 >> 2] = $3; - $0 = $0 + 16 | 0; - $1 = $1 + 4 | 0; - if (($4 | 0) != ($1 | 0)) { - continue label$8 - } - break label$3; - }; - } - _ZN4core9panicking5panic17h9f0a34b0744fbd45E(1050248 | 0, 51 | 0, 1050300 | 0); - wasm2js_trap(); - } - _ZN4core9panicking5panic17h9f0a34b0744fbd45E(1050316 | 0, 39 | 0, 1050356 | 0); - wasm2js_trap(); - } - _ZN4core9panicking5panic17h9f0a34b0744fbd45E(1050088 | 0, 40 | 0, 1050128 | 0); - wasm2js_trap(); - } - if (!$6) { - break label$2 - } - $0 = (($1 << 2 | 0) + $3 | 0) + 184 | 0; - label$9 : while (1) { - $8 = HEAP32[$0 >> 2] | 0; - HEAP16[($8 + 180 | 0) >> 1] = $1; - HEAP32[$8 >> 2] = $3; - $0 = $0 + 4 | 0; - $1 = $1 + 1 | 0; - $6 = $6 + -1 | 0; - if ($6) { - continue label$9 - } - break label$9; - }; - } - __stack_pointer = $2 + 32 | 0; - return; - } - _ZN4core9panicking5panic17h9f0a34b0744fbd45E(1050372 | 0, 40 | 0, 1050412 | 0); - wasm2js_trap(); - } - - function _ZN5alloc11collections5btree4node29BalancingContext$LT$K$C$V$GT$16bulk_steal_right17h9c412c550e5d39d3E($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - var $7 = 0, $3 = 0, $4 = 0, $6 = 0, $14 = 0, $9 = 0, i64toi32_i32$0 = 0, $12 = 0, i64toi32_i32$1 = 0, $8 = 0, $15 = 0, $2 = 0, $5 = 0, $10 = 0, $11 = 0, $13 = 0, $17 = 0, $13$hi = 0, $16 = 0, $18 = 0, $18$hi = 0, $126 = 0; - $2 = __stack_pointer - 32 | 0; - __stack_pointer = $2; - label$1 : { - label$2 : { - label$3 : { - label$4 : { - label$5 : { - label$6 : { - $3 = HEAP32[($0 + 12 | 0) >> 2] | 0; - $4 = HEAPU16[($3 + 182 | 0) >> 1] | 0; - $5 = $4 + $1 | 0; - if ($5 >>> 0 >= 12 >>> 0) { - break label$6 - } - $6 = HEAP32[($0 + 20 | 0) >> 2] | 0; - $7 = HEAPU16[($6 + 182 | 0) >> 1] | 0; - if ($7 >>> 0 < $1 >>> 0) { - break label$5 - } - HEAP16[($3 + 182 | 0) >> 1] = $5; - $8 = $7 - $1 | 0; - HEAP16[($6 + 182 | 0) >> 1] = $8; - $9 = $6 + 48 | 0; - $10 = $1 + -1 | 0; - $11 = Math_imul($10, 12); - $7 = $9 + $11 | 0; - $12 = HEAP32[($7 + 8 | 0) >> 2] | 0; - HEAP32[($2 + 8 | 0) >> 2] = $12; - i64toi32_i32$0 = HEAP32[$7 >> 2] | 0; - i64toi32_i32$1 = HEAP32[($7 + 4 | 0) >> 2] | 0; - $13 = i64toi32_i32$0; - $13$hi = i64toi32_i32$1; - $7 = HEAP32[$0 >> 2] | 0; - $14 = HEAP32[($0 + 8 | 0) >> 2] | 0; - $15 = ($7 + ($14 << 2 | 0) | 0) + 4 | 0; - $16 = HEAP32[$15 >> 2] | 0; - $17 = $1 << 2 | 0; - HEAP32[$15 >> 2] = HEAP32[($6 + $17 | 0) >> 2] | 0; - i64toi32_i32$0 = $2; - HEAP32[i64toi32_i32$0 >> 2] = $13; - HEAP32[(i64toi32_i32$0 + 4 | 0) >> 2] = i64toi32_i32$1; - $7 = $7 + Math_imul($14, 12) | 0; - $14 = $7 + 48 | 0; - i64toi32_i32$1 = HEAP32[$14 >> 2] | 0; - i64toi32_i32$0 = HEAP32[($14 + 4 | 0) >> 2] | 0; - $18 = i64toi32_i32$1; - $18$hi = i64toi32_i32$0; - i64toi32_i32$0 = $13$hi; - i64toi32_i32$1 = $14; - HEAP32[i64toi32_i32$1 >> 2] = $13; - HEAP32[(i64toi32_i32$1 + 4 | 0) >> 2] = i64toi32_i32$0; - $7 = $7 + 56 | 0; - $14 = HEAP32[$7 >> 2] | 0; - HEAP32[$7 >> 2] = $12; - $12 = $3 + 4 | 0; - HEAP32[($12 + ($4 << 2 | 0) | 0) >> 2] = $16; - $15 = $3 + 48 | 0; - $7 = $15 + Math_imul($4, 12) | 0; - i64toi32_i32$0 = $18$hi; - i64toi32_i32$1 = $7; - HEAP32[$7 >> 2] = $18; - HEAP32[($7 + 4 | 0) >> 2] = i64toi32_i32$0; - HEAP32[($7 + 8 | 0) >> 2] = $14; - $7 = $4 + 1 | 0; - if (($10 | 0) != ($5 - $7 | 0 | 0)) { - break label$4 - } - $126 = $12 + ($7 << 2 | 0) | 0; - $12 = $6 + 4 | 0; - memcpy($126 | 0, $12 | 0, $10 << 2 | 0 | 0) | 0; - memcpy($15 + Math_imul($7, 12) | 0 | 0, $9 | 0, $11 | 0) | 0; - $14 = $8 << 2 | 0; - memmove($12 | 0, $12 + $17 | 0 | 0, $14 | 0) | 0; - memmove($9 | 0, $9 + Math_imul($1, 12) | 0 | 0, Math_imul($8, 12) | 0) | 0; - $9 = HEAP32[($0 + 24 | 0) >> 2] | 0; - label$7 : { - if (HEAP32[($0 + 16 | 0) >> 2] | 0) { - break label$7 - } - if (!$9) { - break label$2 - } - break label$1; - } - if (!$9) { - break label$1 - } - $0 = $6 + 184 | 0; - $9 = $1 << 2 | 0; - memcpy(($3 + ($7 << 2 | 0) | 0) + 184 | 0 | 0, $0 | 0, $9 | 0) | 0; - memmove($0 | 0, $0 + $9 | 0 | 0, $14 + 4 | 0 | 0) | 0; - label$8 : { - $0 = $1 & 3 | 0; - if (!$0) { - break label$8 - } - $1 = (($4 << 2 | 0) + $3 | 0) + 188 | 0; - label$9 : while (1) { - $4 = HEAP32[$1 >> 2] | 0; - HEAP16[($4 + 180 | 0) >> 1] = $7; - HEAP32[$4 >> 2] = $3; - $1 = $1 + 4 | 0; - $7 = $7 + 1 | 0; - $0 = $0 + -1 | 0; - if ($0) { - continue label$9 - } - break label$9; - }; - } - label$10 : { - if ($10 >>> 0 < 3 >>> 0) { - break label$10 - } - $0 = $7 << 2 | 0; - label$11 : while (1) { - $1 = $3 + $0 | 0; - $4 = HEAP32[($1 + 184 | 0) >> 2] | 0; - HEAP16[($4 + 180 | 0) >> 1] = $7; - HEAP32[$4 >> 2] = $3; - $4 = HEAP32[($1 + 188 | 0) >> 2] | 0; - HEAP16[($4 + 180 | 0) >> 1] = $7 + 1 | 0; - HEAP32[$4 >> 2] = $3; - $4 = HEAP32[($1 + 192 | 0) >> 2] | 0; - HEAP16[($4 + 180 | 0) >> 1] = $7 + 2 | 0; - HEAP32[$4 >> 2] = $3; - $1 = HEAP32[($1 + 196 | 0) >> 2] | 0; - $4 = $7 + 3 | 0; - HEAP16[($1 + 180 | 0) >> 1] = $4; - HEAP32[$1 >> 2] = $3; - $7 = $7 + 4 | 0; - $0 = $0 + 16 | 0; - if (($4 | 0) != ($5 | 0)) { - continue label$11 - } - break label$11; - }; - } - if (($8 | 0) == (-1 | 0)) { - break label$2 - } - $0 = $8 + 1 | 0; - $1 = $0 & 3 | 0; - $7 = 0; - if ($8 >>> 0 < 3 >>> 0) { - break label$3 - } - $3 = $6 + 196 | 0; - $4 = $0 & -4 | 0; - $7 = 0; - label$12 : while (1) { - $0 = HEAP32[($3 + -12 | 0) >> 2] | 0; - HEAP16[($0 + 180 | 0) >> 1] = $7; - HEAP32[$0 >> 2] = $6; - $0 = HEAP32[($3 + -8 | 0) >> 2] | 0; - HEAP16[($0 + 180 | 0) >> 1] = $7 + 1 | 0; - HEAP32[$0 >> 2] = $6; - $0 = HEAP32[($3 + -4 | 0) >> 2] | 0; - HEAP16[($0 + 180 | 0) >> 1] = $7 + 2 | 0; - HEAP32[$0 >> 2] = $6; - $0 = HEAP32[$3 >> 2] | 0; - HEAP16[($0 + 180 | 0) >> 1] = $7 + 3 | 0; - HEAP32[$0 >> 2] = $6; - $3 = $3 + 16 | 0; - $7 = $7 + 4 | 0; - if (($4 | 0) != ($7 | 0)) { - continue label$12 - } - break label$3; - }; - } - _ZN4core9panicking5panic17h9f0a34b0744fbd45E(1050428 | 0, 50 | 0, 1050480 | 0); - wasm2js_trap(); - } - _ZN4core9panicking5panic17h9f0a34b0744fbd45E(1050496 | 0, 40 | 0, 1050536 | 0); - wasm2js_trap(); - } - _ZN4core9panicking5panic17h9f0a34b0744fbd45E(1050088 | 0, 40 | 0, 1050128 | 0); - wasm2js_trap(); - } - if (!$1) { - break label$2 - } - $3 = (($7 << 2 | 0) + $6 | 0) + 184 | 0; - label$13 : while (1) { - $0 = HEAP32[$3 >> 2] | 0; - HEAP16[($0 + 180 | 0) >> 1] = $7; - HEAP32[$0 >> 2] = $6; - $3 = $3 + 4 | 0; - $7 = $7 + 1 | 0; - $1 = $1 + -1 | 0; - if ($1) { - continue label$13 - } - break label$13; - }; - } - __stack_pointer = $2 + 32 | 0; - return; - } - _ZN4core9panicking5panic17h9f0a34b0744fbd45E(1050372 | 0, 40 | 0, 1050552 | 0); - wasm2js_trap(); - } - - function _ZN5alloc11collections5btree4node29BalancingContext$LT$K$C$V$GT$8do_merge17h3854facd3939f96eE($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - var $13 = 0, $11 = 0, $16 = 0, $5 = 0, $3 = 0, $15 = 0, $14 = 0, $2 = 0, $4 = 0, $6 = 0, $7 = 0, $8 = 0, $12 = 0, $17 = 0, i64toi32_i32$0 = 0, i64toi32_i32$1 = 0, $9 = 0, $10 = 0, $97 = 0, $116 = 0; - $2 = __stack_pointer - 16 | 0; - __stack_pointer = $2; - label$1 : { - label$2 : { - $3 = HEAP32[($1 + 12 | 0) >> 2] | 0; - $4 = HEAPU16[($3 + 182 | 0) >> 1] | 0; - $5 = $4 + 1 | 0; - $6 = HEAP32[($1 + 20 | 0) >> 2] | 0; - $7 = HEAPU16[($6 + 182 | 0) >> 1] | 0; - $8 = $5 + $7 | 0; - if ($8 >>> 0 >= 12 >>> 0) { - break label$2 - } - $9 = HEAP32[($1 + 16 | 0) >> 2] | 0; - $10 = HEAP32[($1 + 4 | 0) >> 2] | 0; - $11 = HEAP32[$1 >> 2] | 0; - $12 = HEAPU16[($11 + 182 | 0) >> 1] | 0; - HEAP16[($3 + 182 | 0) >> 1] = $8; - $13 = HEAP32[($1 + 8 | 0) >> 2] | 0; - $1 = $11 + ($13 << 2 | 0) | 0; - $14 = $1 + 4 | 0; - $15 = HEAP32[$14 >> 2] | 0; - $16 = $12 + ($13 ^ -1 | 0) | 0; - $17 = $16 << 2 | 0; - memmove($14 | 0, $1 + 8 | 0 | 0, $17 | 0) | 0; - $1 = $3 + 4 | 0; - HEAP32[($1 + ($4 << 2 | 0) | 0) >> 2] = $15; - memcpy($1 + ($5 << 2 | 0) | 0 | 0, $6 + 4 | 0 | 0, $7 << 2 | 0 | 0) | 0; - $14 = $2 + 8 | 0; - $1 = $11 + Math_imul($13, 12) | 0; - HEAP32[$14 >> 2] = HEAP32[($1 + 56 | 0) >> 2] | 0; - $15 = $1 + 48 | 0; - i64toi32_i32$0 = HEAP32[$15 >> 2] | 0; - i64toi32_i32$1 = HEAP32[($15 + 4 | 0) >> 2] | 0; - $97 = i64toi32_i32$0; - i64toi32_i32$0 = $2; - HEAP32[$2 >> 2] = $97; - HEAP32[($2 + 4 | 0) >> 2] = i64toi32_i32$1; - memmove($15 | 0, $1 + 60 | 0 | 0, Math_imul($16, 12) | 0) | 0; - $1 = $3 + 48 | 0; - $15 = $1 + Math_imul($4, 12) | 0; - HEAP32[($15 + 8 | 0) >> 2] = HEAP32[$14 >> 2] | 0; - i64toi32_i32$1 = HEAP32[$2 >> 2] | 0; - i64toi32_i32$0 = HEAP32[($2 + 4 | 0) >> 2] | 0; - $116 = i64toi32_i32$1; - i64toi32_i32$1 = $15; - HEAP32[$15 >> 2] = $116; - HEAP32[($15 + 4 | 0) >> 2] = i64toi32_i32$0; - memcpy($1 + Math_imul($5, 12) | 0 | 0, $6 + 48 | 0 | 0, Math_imul($7, 12) | 0) | 0; - $15 = 184; - $1 = $13 + 1 | 0; - $14 = $11 + ($1 << 2 | 0) | 0; - memmove($14 + 184 | 0 | 0, $14 + 188 | 0 | 0, $17 | 0) | 0; - label$3 : { - if ($1 >>> 0 >= $12 >>> 0) { - break label$3 - } - $17 = ($12 - $13 | 0) + -2 | 0; - label$4 : { - $16 = $16 & 3 | 0; - if (!$16) { - break label$4 - } - $13 = (($13 << 2 | 0) + $11 | 0) + 188 | 0; - label$5 : while (1) { - $14 = HEAP32[$13 >> 2] | 0; - HEAP16[($14 + 180 | 0) >> 1] = $1; - HEAP32[$14 >> 2] = $11; - $13 = $13 + 4 | 0; - $1 = $1 + 1 | 0; - $16 = $16 + -1 | 0; - if ($16) { - continue label$5 - } - break label$5; - }; - } - if ($17 >>> 0 < 3 >>> 0) { - break label$3 - } - $13 = (($1 << 2 | 0) + $11 | 0) + 196 | 0; - label$6 : while (1) { - $16 = HEAP32[($13 + -12 | 0) >> 2] | 0; - HEAP16[($16 + 180 | 0) >> 1] = $1; - HEAP32[$16 >> 2] = $11; - $16 = HEAP32[($13 + -8 | 0) >> 2] | 0; - HEAP16[($16 + 180 | 0) >> 1] = $1 + 1 | 0; - HEAP32[$16 >> 2] = $11; - $16 = HEAP32[($13 + -4 | 0) >> 2] | 0; - HEAP16[($16 + 180 | 0) >> 1] = $1 + 2 | 0; - HEAP32[$16 >> 2] = $11; - $16 = HEAP32[$13 >> 2] | 0; - HEAP16[($16 + 180 | 0) >> 1] = $1 + 3 | 0; - HEAP32[$16 >> 2] = $11; - $13 = $13 + 16 | 0; - $1 = $1 + 4 | 0; - if (($12 | 0) != ($1 | 0)) { - continue label$6 - } - break label$6; - }; - } - HEAP16[($11 + 182 | 0) >> 1] = (HEAPU16[($11 + 182 | 0) >> 1] | 0) + -1 | 0; - label$7 : { - if ($10 >>> 0 < 2 >>> 0) { - break label$7 - } - $1 = $7 + 1 | 0; - if (($1 | 0) != ($8 - $4 | 0 | 0)) { - break label$1 - } - memcpy(($3 + 184 | 0) + ($5 << 2 | 0) | 0 | 0, $6 + 184 | 0 | 0, $1 << 2 | 0 | 0) | 0; - label$8 : { - $11 = $1 & 3 | 0; - if (!$11) { - break label$8 - } - $1 = (($4 << 2 | 0) + $3 | 0) + 188 | 0; - label$9 : while (1) { - $13 = HEAP32[$1 >> 2] | 0; - HEAP16[($13 + 180 | 0) >> 1] = $5; - HEAP32[$13 >> 2] = $3; - $1 = $1 + 4 | 0; - $5 = $5 + 1 | 0; - $11 = $11 + -1 | 0; - if ($11) { - continue label$9 - } - break label$9; - }; - } - $15 = 232; - if ($7 >>> 0 < 3 >>> 0) { - break label$7 - } - $11 = $5 << 2 | 0; - label$10 : while (1) { - $1 = $3 + $11 | 0; - $13 = HEAP32[($1 + 184 | 0) >> 2] | 0; - HEAP16[($13 + 180 | 0) >> 1] = $5; - HEAP32[$13 >> 2] = $3; - $13 = HEAP32[($1 + 188 | 0) >> 2] | 0; - HEAP16[($13 + 180 | 0) >> 1] = $5 + 1 | 0; - HEAP32[$13 >> 2] = $3; - $13 = HEAP32[($1 + 192 | 0) >> 2] | 0; - HEAP16[($13 + 180 | 0) >> 1] = $5 + 2 | 0; - HEAP32[$13 >> 2] = $3; - $1 = HEAP32[($1 + 196 | 0) >> 2] | 0; - $13 = $5 + 3 | 0; - HEAP16[($1 + 180 | 0) >> 1] = $13; - HEAP32[$1 >> 2] = $3; - $5 = $5 + 4 | 0; - $11 = $11 + 16 | 0; - if (($13 | 0) != ($8 | 0)) { - continue label$10 - } - break label$10; - }; - } - __rust_dealloc($6 | 0, $15 | 0, 4 | 0); - HEAP32[($0 + 4 | 0) >> 2] = $9; - HEAP32[$0 >> 2] = $3; - __stack_pointer = $2 + 16 | 0; - return; - } - _ZN4core9panicking5panic17h9f0a34b0744fbd45E(1050728 | 0, 42 | 0, 1050772 | 0); - wasm2js_trap(); - } - _ZN4core9panicking5panic17h9f0a34b0744fbd45E(1050088 | 0, 40 | 0, 1050128 | 0); - wasm2js_trap(); - } - - function _ZN5alloc11collections5btree6remove259_$LT$impl$u20$alloc__collections__btree__node__Handle$LT$alloc__collections__btree__node__NodeRef$LT$alloc__collections__btree__node__marker__Mut$C$K$C$V$C$alloc__collections__btree__node__marker__Leaf$GT$$C$alloc__collections__btree__node__marker__KV$GT$$GT$14remove_leaf_kv17h1338e9b021c47ae4E($0, $1, $2) { - $0 = $0 | 0; - $1 = $1 | 0; - $2 = $2 | 0; - var $3 = 0, $6 = 0, $13 = 0, $10 = 0, $9 = 0, $7 = 0, i64toi32_i32$1 = 0, $17 = 0, $4 = 0, $12 = 0, i64toi32_i32$0 = 0, $5 = 0, $16 = 0, $15 = 0, $21 = 0, i64toi32_i32$2 = 0, $18 = 0, $19 = 0, $14 = 0, $20 = 0, $23 = 0, $11 = 0, $22 = 0, $8 = 0, $66 = 0, $332 = 0, $375 = 0, $394 = 0, $594 = 0; - $3 = __stack_pointer - 128 | 0; - __stack_pointer = $3; - $4 = HEAP32[$1 >> 2] | 0; - $5 = HEAP32[($1 + 8 | 0) >> 2] | 0; - $6 = $4 + ($5 << 2 | 0) | 0; - $7 = $6 + 4 | 0; - $8 = HEAP32[$7 >> 2] | 0; - $9 = HEAPU16[($4 + 182 | 0) >> 1] | 0; - $10 = ($5 ^ -1 | 0) + $9 | 0; - memmove($7 | 0, $6 + 8 | 0 | 0, $10 << 2 | 0 | 0) | 0; - $11 = ($3 + 24 | 0) + 8 | 0; - $6 = $4 + Math_imul($5, 12) | 0; - HEAP32[$11 >> 2] = HEAP32[($6 + 56 | 0) >> 2] | 0; - $7 = $6 + 48 | 0; - i64toi32_i32$2 = $7; - i64toi32_i32$0 = HEAP32[$7 >> 2] | 0; - i64toi32_i32$1 = HEAP32[($7 + 4 | 0) >> 2] | 0; - $66 = i64toi32_i32$0; - i64toi32_i32$0 = $3; - HEAP32[($3 + 24 | 0) >> 2] = $66; - HEAP32[($3 + 28 | 0) >> 2] = i64toi32_i32$1; - memmove($7 | 0, $6 + 60 | 0 | 0, Math_imul($10, 12) | 0) | 0; - $6 = $9 + -1 | 0; - HEAP16[($4 + 182 | 0) >> 1] = $6; - $12 = HEAP32[($1 + 4 | 0) >> 2] | 0; - label$1 : { - if (($6 & 65535 | 0) >>> 0 > 4 >>> 0) { - break label$1 - } - $1 = HEAP32[$4 >> 2] | 0; - if (!$1) { - break label$1 - } - $7 = $12 + 1 | 0; - label$2 : { - label$3 : { - label$4 : { - label$5 : { - label$6 : { - $9 = HEAPU16[($4 + 180 | 0) >> 1] | 0; - if ($9) { - break label$6 - } - if (HEAPU16[($1 + 182 | 0) >> 1] | 0) { - break label$5 - } - HEAP32[($3 + 72 | 0) >> 2] = 1; - HEAP32[($3 + 68 | 0) >> 2] = 1050012; - i64toi32_i32$0 = $3; - i64toi32_i32$1 = 0; - HEAP32[($3 + 80 | 0) >> 2] = 0; - HEAP32[($3 + 84 | 0) >> 2] = i64toi32_i32$1; - HEAP32[($3 + 76 | 0) >> 2] = $3 + 124 | 0; - _ZN4core9panicking9panic_fmt17hb2f16849466f57b6E($3 + 68 | 0 | 0, 1050020 | 0); - wasm2js_trap(); - } - label$7 : { - $9 = $9 + -1 | 0; - $10 = HEAP32[(($1 + ($9 << 2 | 0) | 0) + 184 | 0) >> 2] | 0; - $13 = HEAPU16[($10 + 182 | 0) >> 1] | 0; - $6 = $6 & 65535 | 0; - if ((($13 + $6 | 0) + 1 | 0) >>> 0 < 12 >>> 0) { - break label$7 - } - HEAP32[($3 + 92 | 0) >> 2] = $12; - HEAP32[($3 + 88 | 0) >> 2] = $4; - HEAP32[($3 + 84 | 0) >> 2] = $12; - HEAP32[($3 + 80 | 0) >> 2] = $10; - HEAP32[($3 + 76 | 0) >> 2] = $9; - HEAP32[($3 + 72 | 0) >> 2] = $7; - HEAP32[($3 + 68 | 0) >> 2] = $1; - _ZN5alloc11collections5btree4node29BalancingContext$LT$K$C$V$GT$15bulk_steal_left17hdff94e2f76df3257E($3 + 68 | 0 | 0, 1 | 0); - $5 = $5 + 1 | 0; - break label$2; - } - HEAP32[($3 + 92 | 0) >> 2] = $12; - HEAP32[($3 + 88 | 0) >> 2] = $4; - HEAP32[($3 + 84 | 0) >> 2] = $12; - HEAP32[($3 + 80 | 0) >> 2] = $10; - HEAP32[($3 + 76 | 0) >> 2] = $9; - HEAP32[($3 + 72 | 0) >> 2] = $7; - HEAP32[($3 + 68 | 0) >> 2] = $1; - if ($5 >>> 0 > $6 >>> 0) { - break label$4 - } - $5 = ($5 + $13 | 0) + 1 | 0; - _ZN5alloc11collections5btree4node29BalancingContext$LT$K$C$V$GT$8do_merge17h3854facd3939f96eE($3 + 16 | 0 | 0, $3 + 68 | 0 | 0); - $12 = HEAP32[($3 + 20 | 0) >> 2] | 0; - $4 = HEAP32[($3 + 16 | 0) >> 2] | 0; - break label$2; - } - label$8 : { - $9 = $6 & 65535 | 0; - $6 = HEAP32[($1 + 188 | 0) >> 2] | 0; - if ((($9 + (HEAPU16[($6 + 182 | 0) >> 1] | 0) | 0) + 1 | 0) >>> 0 < 12 >>> 0) { - break label$8 - } - HEAP32[($3 + 92 | 0) >> 2] = $12; - HEAP32[($3 + 88 | 0) >> 2] = $6; - HEAP32[($3 + 84 | 0) >> 2] = $12; - HEAP32[($3 + 80 | 0) >> 2] = $4; - HEAP32[($3 + 76 | 0) >> 2] = 0; - HEAP32[($3 + 72 | 0) >> 2] = $7; - HEAP32[($3 + 68 | 0) >> 2] = $1; - _ZN5alloc11collections5btree4node29BalancingContext$LT$K$C$V$GT$16bulk_steal_right17h9c412c550e5d39d3E($3 + 68 | 0 | 0, 1 | 0); - break label$2; - } - HEAP32[($3 + 92 | 0) >> 2] = $12; - HEAP32[($3 + 88 | 0) >> 2] = $6; - HEAP32[($3 + 84 | 0) >> 2] = $12; - HEAP32[($3 + 80 | 0) >> 2] = $4; - HEAP32[($3 + 76 | 0) >> 2] = 0; - HEAP32[($3 + 72 | 0) >> 2] = $7; - HEAP32[($3 + 68 | 0) >> 2] = $1; - if ($5 >>> 0 > $9 >>> 0) { - break label$3 - } - _ZN5alloc11collections5btree4node29BalancingContext$LT$K$C$V$GT$8do_merge17h3854facd3939f96eE($3 + 8 | 0 | 0, $3 + 68 | 0 | 0); - $12 = HEAP32[($3 + 12 | 0) >> 2] | 0; - $4 = HEAP32[($3 + 8 | 0) >> 2] | 0; - break label$2; - } - _ZN4core9panicking5panic17h9f0a34b0744fbd45E(1050568 | 0, 142 | 0, 1050712 | 0); - wasm2js_trap(); - } - _ZN4core9panicking5panic17h9f0a34b0744fbd45E(1050568 | 0, 142 | 0, 1050712 | 0); - wasm2js_trap(); - } - $9 = HEAP32[$4 >> 2] | 0; - if (!$9) { - break label$1 - } - $6 = HEAPU16[($9 + 182 | 0) >> 1] | 0; - if ($6 >>> 0 > 4 >>> 0) { - break label$1 - } - $14 = $12 + 1 | 0; - label$9 : { - label$10 : { - label$11 : { - label$12 : while (1) { - $1 = $14; - $15 = $9; - $9 = HEAP32[$9 >> 2] | 0; - if (!$9) { - break label$11 - } - $16 = $6 & 65535 | 0; - $14 = $1 + 1 | 0; - label$13 : { - label$14 : { - label$15 : { - label$16 : { - $6 = HEAPU16[($15 + 180 | 0) >> 1] | 0; - if ($6) { - break label$16 - } - label$17 : { - $6 = HEAPU16[($9 + 182 | 0) >> 1] | 0; - if ($6) { - break label$17 - } - HEAP32[($3 + 100 | 0) >> 2] = 1; - HEAP32[($3 + 96 | 0) >> 2] = 1050012; - i64toi32_i32$0 = $3; - i64toi32_i32$1 = 0; - HEAP32[($3 + 108 | 0) >> 2] = 0; - HEAP32[($3 + 112 | 0) >> 2] = i64toi32_i32$1; - HEAP32[($3 + 104 | 0) >> 2] = $3 + 124 | 0; - _ZN4core9panicking9panic_fmt17hb2f16849466f57b6E($3 + 96 | 0 | 0, 1050020 | 0); - wasm2js_trap(); - } - HEAP32[($3 + 92 | 0) >> 2] = $1; - HEAP32[($3 + 84 | 0) >> 2] = $1; - HEAP32[($3 + 80 | 0) >> 2] = $15; - $13 = 0; - HEAP32[($3 + 76 | 0) >> 2] = 0; - HEAP32[($3 + 72 | 0) >> 2] = $14; - HEAP32[($3 + 68 | 0) >> 2] = $9; - $10 = HEAP32[($9 + 188 | 0) >> 2] | 0; - HEAP32[($3 + 88 | 0) >> 2] = $10; - $1 = $16 + 1 | 0; - $17 = HEAPU16[($10 + 182 | 0) >> 1] | 0; - $18 = $1 + $17 | 0; - if ($18 >>> 0 >= 12 >>> 0) { - break label$15 - } - $7 = $15; - $15 = $10; - $19 = $16; - $16 = $17; - break label$13; - } - HEAP32[($3 + 64 | 0) >> 2] = $1; - HEAP32[($3 + 60 | 0) >> 2] = $15; - HEAP32[($3 + 56 | 0) >> 2] = $1; - HEAP32[($3 + 44 | 0) >> 2] = $14; - $13 = $6 + -1 | 0; - HEAP32[($3 + 48 | 0) >> 2] = $13; - HEAP32[($3 + 40 | 0) >> 2] = $9; - $7 = HEAP32[(($9 + ($13 << 2 | 0) | 0) + 184 | 0) >> 2] | 0; - HEAP32[($3 + 52 | 0) >> 2] = $7; - $19 = HEAPU16[($7 + 182 | 0) >> 1] | 0; - if ((($16 + $19 | 0) + 1 | 0) >>> 0 < 12 >>> 0) { - break label$14 - } - _ZN5alloc11collections5btree4node29BalancingContext$LT$K$C$V$GT$15bulk_steal_left17hdff94e2f76df3257E($3 + 40 | 0 | 0, 5 - $16 | 0 | 0); - break label$1; - } - _ZN5alloc11collections5btree4node29BalancingContext$LT$K$C$V$GT$16bulk_steal_right17h9c412c550e5d39d3E($3 + 68 | 0 | 0, 5 - $16 | 0 | 0); - break label$1; - } - $1 = $19 + 1 | 0; - $18 = $1 + $16 | 0; - $6 = HEAPU16[($9 + 182 | 0) >> 1] | 0; - } - HEAP16[($7 + 182 | 0) >> 1] = $18; - $10 = $9 + ($13 << 2 | 0) | 0; - $17 = $10 + 4 | 0; - $20 = HEAP32[$17 >> 2] | 0; - $332 = $10 + 8 | 0; - $21 = $6 & 65535 | 0; - $10 = $21 + ($13 ^ -1 | 0) | 0; - $22 = $10 << 2 | 0; - memmove($17 | 0, $332 | 0, $22 | 0) | 0; - $6 = $7 + 4 | 0; - HEAP32[($6 + ($19 << 2 | 0) | 0) >> 2] = $20; - $23 = $1 << 2 | 0; - memcpy($6 + $23 | 0 | 0, $15 + 4 | 0 | 0, $16 << 2 | 0 | 0) | 0; - $17 = ($3 + 96 | 0) + 8 | 0; - $6 = $9 + Math_imul($13, 12) | 0; - HEAP32[$17 >> 2] = HEAP32[($6 + 56 | 0) >> 2] | 0; - $20 = $6 + 48 | 0; - i64toi32_i32$2 = $20; - i64toi32_i32$1 = HEAP32[i64toi32_i32$2 >> 2] | 0; - i64toi32_i32$0 = HEAP32[(i64toi32_i32$2 + 4 | 0) >> 2] | 0; - $375 = i64toi32_i32$1; - i64toi32_i32$1 = $3; - HEAP32[($3 + 96 | 0) >> 2] = $375; - HEAP32[($3 + 100 | 0) >> 2] = i64toi32_i32$0; - memmove(i64toi32_i32$2 | 0, $6 + 60 | 0 | 0, Math_imul($10, 12) | 0) | 0; - $6 = $7 + 48 | 0; - $10 = $6 + Math_imul($19, 12) | 0; - HEAP32[($10 + 8 | 0) >> 2] = HEAP32[$17 >> 2] | 0; - i64toi32_i32$2 = $3; - i64toi32_i32$0 = HEAP32[($3 + 96 | 0) >> 2] | 0; - i64toi32_i32$1 = HEAP32[($3 + 100 | 0) >> 2] | 0; - $394 = i64toi32_i32$0; - i64toi32_i32$0 = $10; - HEAP32[$10 >> 2] = $394; - HEAP32[($10 + 4 | 0) >> 2] = i64toi32_i32$1; - memcpy($6 + Math_imul($1, 12) | 0 | 0, $15 + 48 | 0 | 0, Math_imul($16, 12) | 0) | 0; - $6 = $13 + 1 | 0; - $17 = $9 + ($6 << 2 | 0) | 0; - $10 = $17 + 184 | 0; - memmove($10 | 0, $17 + 188 | 0 | 0, $22 | 0) | 0; - label$18 : { - if ($21 >>> 0 <= $6 >>> 0) { - break label$18 - } - $20 = ($21 - $13 | 0) + -2 | 0; - label$19 : { - $13 = ($21 - $6 | 0) & 3 | 0; - if (!$13) { - break label$19 - } - label$20 : while (1) { - $17 = HEAP32[$10 >> 2] | 0; - HEAP16[($17 + 180 | 0) >> 1] = $6; - HEAP32[$17 >> 2] = $9; - $10 = $10 + 4 | 0; - $6 = $6 + 1 | 0; - $13 = $13 + -1 | 0; - if ($13) { - continue label$20 - } - break label$20; - }; - } - if ($20 >>> 0 < 3 >>> 0) { - break label$18 - } - $10 = ($9 + ($6 << 2 | 0) | 0) + 196 | 0; - label$21 : while (1) { - $13 = HEAP32[($10 + -12 | 0) >> 2] | 0; - HEAP16[($13 + 180 | 0) >> 1] = $6; - HEAP32[$13 >> 2] = $9; - $13 = HEAP32[($10 + -8 | 0) >> 2] | 0; - HEAP16[($13 + 180 | 0) >> 1] = $6 + 1 | 0; - HEAP32[$13 >> 2] = $9; - $13 = HEAP32[($10 + -4 | 0) >> 2] | 0; - HEAP16[($13 + 180 | 0) >> 1] = $6 + 2 | 0; - HEAP32[$13 >> 2] = $9; - $13 = HEAP32[$10 >> 2] | 0; - HEAP16[($13 + 180 | 0) >> 1] = $6 + 3 | 0; - HEAP32[$13 >> 2] = $9; - $10 = $10 + 16 | 0; - $6 = $6 + 4 | 0; - if (($21 | 0) != ($6 | 0)) { - continue label$21 - } - break label$21; - }; - } - HEAP16[($9 + 182 | 0) >> 1] = (HEAPU16[($9 + 182 | 0) >> 1] | 0) + -1 | 0; - $17 = 184; - label$22 : { - if ($14 >>> 0 < 2 >>> 0) { - break label$22 - } - $6 = $16 + 1 | 0; - if (($6 | 0) != ($18 - $19 | 0 | 0)) { - break label$10 - } - memcpy(($7 + 184 | 0) + $23 | 0 | 0, $15 + 184 | 0 | 0, $6 << 2 | 0 | 0) | 0; - label$23 : { - $21 = $18 - $1 | 0; - $10 = ($21 + 1 | 0) & 3 | 0; - if (!$10) { - break label$23 - } - $6 = ($7 + $23 | 0) + 184 | 0; - label$24 : while (1) { - $13 = HEAP32[$6 >> 2] | 0; - HEAP16[($13 + 180 | 0) >> 1] = $1; - HEAP32[$13 >> 2] = $7; - $6 = $6 + 4 | 0; - $1 = $1 + 1 | 0; - $10 = $10 + -1 | 0; - if ($10) { - continue label$24 - } - break label$24; - }; - } - $17 = 232; - if ($21 >>> 0 < 3 >>> 0) { - break label$22 - } - $10 = $1 << 2 | 0; - label$25 : while (1) { - $6 = $7 + $10 | 0; - $13 = HEAP32[($6 + 184 | 0) >> 2] | 0; - HEAP16[($13 + 180 | 0) >> 1] = $1; - HEAP32[$13 >> 2] = $7; - $13 = HEAP32[($6 + 188 | 0) >> 2] | 0; - HEAP16[($13 + 180 | 0) >> 1] = $1 + 1 | 0; - HEAP32[$13 >> 2] = $7; - $13 = HEAP32[($6 + 192 | 0) >> 2] | 0; - HEAP16[($13 + 180 | 0) >> 1] = $1 + 2 | 0; - HEAP32[$13 >> 2] = $7; - $6 = HEAP32[($6 + 196 | 0) >> 2] | 0; - $13 = $1 + 3 | 0; - HEAP16[($6 + 180 | 0) >> 1] = $13; - HEAP32[$6 >> 2] = $7; - $1 = $1 + 4 | 0; - $10 = $10 + 16 | 0; - if (($13 | 0) != ($18 | 0)) { - continue label$25 - } - break label$25; - }; - } - __rust_dealloc($15 | 0, $17 | 0, 4 | 0); - $6 = HEAPU16[($9 + 182 | 0) >> 1] | 0; - if ($6 >>> 0 <= 4 >>> 0) { - continue label$12 - } - break label$1; - }; - } - if (!($6 & 65535 | 0)) { - break label$9 - } - break label$1; - } - _ZN4core9panicking5panic17h9f0a34b0744fbd45E(1050088 | 0, 40 | 0, 1050128 | 0); - wasm2js_trap(); - } - HEAP8[$2 >> 0] = 1; - } - HEAP32[$0 >> 2] = $8; - i64toi32_i32$2 = $3; - i64toi32_i32$1 = HEAP32[($3 + 24 | 0) >> 2] | 0; - i64toi32_i32$0 = HEAP32[($3 + 28 | 0) >> 2] | 0; - $594 = i64toi32_i32$1; - i64toi32_i32$1 = $0; - HEAP32[(i64toi32_i32$1 + 4 | 0) >> 2] = $594; - HEAP32[(i64toi32_i32$1 + 8 | 0) >> 2] = i64toi32_i32$0; - HEAP32[(i64toi32_i32$1 + 24 | 0) >> 2] = $5; - HEAP32[(i64toi32_i32$1 + 20 | 0) >> 2] = $12; - HEAP32[(i64toi32_i32$1 + 16 | 0) >> 2] = $4; - HEAP32[(i64toi32_i32$1 + 12 | 0) >> 2] = HEAP32[$11 >> 2] | 0; - __stack_pointer = $3 + 128 | 0; - } - - function _ZN5alloc11collections5btree6remove269_$LT$impl$u20$alloc__collections__btree__node__Handle$LT$alloc__collections__btree__node__NodeRef$LT$alloc__collections__btree__node__marker__Mut$C$K$C$V$C$alloc__collections__btree__node__marker__LeafOrInternal$GT$$C$alloc__collections__btree__node__marker__KV$GT$$GT$18remove_kv_tracking17h9cdde6bfc5849410E($0, $1, $2) { - $0 = $0 | 0; - $1 = $1 | 0; - $2 = $2 | 0; - var $3 = 0, $5 = 0, i64toi32_i32$1 = 0, $4 = 0, $6 = 0, i64toi32_i32$5 = 0, i64toi32_i32$0 = 0, i64toi32_i32$4 = 0, i64toi32_i32$2 = 0, i64toi32_i32$3 = 0, $7 = 0, $21 = 0, $92 = 0, $112 = 0, $8 = 0, $9 = 0, $9$hi = 0, $161 = 0, $210 = 0; - $3 = __stack_pointer - 80 | 0; - __stack_pointer = $3; - $4 = HEAP32[($1 + 8 | 0) >> 2] | 0; - $5 = HEAP32[$1 >> 2] | 0; - label$1 : { - label$2 : { - $6 = HEAP32[($1 + 4 | 0) >> 2] | 0; - if ($6) { - break label$2 - } - HEAP32[($3 + 16 | 0) >> 2] = $4; - HEAP32[($3 + 12 | 0) >> 2] = 0; - HEAP32[($3 + 8 | 0) >> 2] = $5; - _ZN5alloc11collections5btree6remove259_$LT$impl$u20$alloc__collections__btree__node__Handle$LT$alloc__collections__btree__node__NodeRef$LT$alloc__collections__btree__node__marker__Mut$C$K$C$V$C$alloc__collections__btree__node__marker__Leaf$GT$$C$alloc__collections__btree__node__marker__KV$GT$$GT$14remove_leaf_kv17h1338e9b021c47ae4E($0 | 0, $3 + 8 | 0 | 0, $2 | 0); - break label$1; - } - $1 = HEAP32[(($5 + ($4 << 2 | 0) | 0) + 184 | 0) >> 2] | 0; - label$3 : { - $4 = $6 + -1 | 0; - if (!$4) { - break label$3 - } - $5 = $6 + -2 | 0; - label$4 : { - $6 = $4 & 3 | 0; - if (!$6) { - break label$4 - } - label$5 : while (1) { - $4 = $4 + -1 | 0; - $1 = HEAP32[(($1 + ((HEAPU16[($1 + 182 | 0) >> 1] | 0) << 2 | 0) | 0) + 184 | 0) >> 2] | 0; - $6 = $6 + -1 | 0; - if ($6) { - continue label$5 - } - break label$5; - }; - } - if ($5 >>> 0 < 3 >>> 0) { - break label$3 - } - label$6 : while (1) { - $1 = HEAP32[(($1 + ((HEAPU16[($1 + 182 | 0) >> 1] | 0) << 2 | 0) | 0) + 184 | 0) >> 2] | 0; - $1 = HEAP32[(($1 + ((HEAPU16[($1 + 182 | 0) >> 1] | 0) << 2 | 0) | 0) + 184 | 0) >> 2] | 0; - $1 = HEAP32[(($1 + ((HEAPU16[($1 + 182 | 0) >> 1] | 0) << 2 | 0) | 0) + 184 | 0) >> 2] | 0; - $1 = HEAP32[(($1 + ((HEAPU16[($1 + 182 | 0) >> 1] | 0) << 2 | 0) | 0) + 184 | 0) >> 2] | 0; - $4 = $4 + -4 | 0; - if ($4) { - continue label$6 - } - break label$6; - }; - } - HEAP32[($3 + 20 | 0) >> 2] = $1; - $92 = $3; - i64toi32_i32$2 = $1; - i64toi32_i32$0 = HEAPU16[($1 + 182 | 0) >> 1] | 0; - i64toi32_i32$1 = 0; - i64toi32_i32$2 = i64toi32_i32$0; - i64toi32_i32$0 = 0; - i64toi32_i32$3 = 32; - i64toi32_i32$4 = i64toi32_i32$3 & 31 | 0; - if (32 >>> 0 <= (i64toi32_i32$3 & 63 | 0) >>> 0) { - i64toi32_i32$0 = i64toi32_i32$2 << i64toi32_i32$4 | 0; - $21 = 0; - } else { - i64toi32_i32$0 = ((1 << i64toi32_i32$4 | 0) - 1 | 0) & (i64toi32_i32$2 >>> (32 - i64toi32_i32$4 | 0) | 0) | 0 | (i64toi32_i32$1 << i64toi32_i32$4 | 0) | 0; - $21 = i64toi32_i32$2 << i64toi32_i32$4 | 0; - } - i64toi32_i32$1 = $21; - i64toi32_i32$2 = -1; - i64toi32_i32$3 = 0; - i64toi32_i32$4 = i64toi32_i32$1 + i64toi32_i32$3 | 0; - i64toi32_i32$5 = i64toi32_i32$0 + i64toi32_i32$2 | 0; - if (i64toi32_i32$4 >>> 0 < i64toi32_i32$3 >>> 0) { - i64toi32_i32$5 = i64toi32_i32$5 + 1 | 0 - } - i64toi32_i32$1 = $92; - HEAP32[(i64toi32_i32$1 + 24 | 0) >> 2] = i64toi32_i32$4; - HEAP32[(i64toi32_i32$1 + 28 | 0) >> 2] = i64toi32_i32$5; - _ZN5alloc11collections5btree6remove259_$LT$impl$u20$alloc__collections__btree__node__Handle$LT$alloc__collections__btree__node__NodeRef$LT$alloc__collections__btree__node__marker__Mut$C$K$C$V$C$alloc__collections__btree__node__marker__Leaf$GT$$C$alloc__collections__btree__node__marker__KV$GT$$GT$14remove_leaf_kv17h1338e9b021c47ae4E($3 + 32 | 0 | 0, $3 + 20 | 0 | 0, $2 | 0); - $6 = ($3 + 64 | 0) + 8 | 0; - HEAP32[$6 >> 2] = HEAP32[(($3 + 32 | 0) + 12 | 0) >> 2] | 0; - i64toi32_i32$0 = $3; - i64toi32_i32$5 = HEAP32[($3 + 36 | 0) >> 2] | 0; - i64toi32_i32$1 = HEAP32[($3 + 40 | 0) >> 2] | 0; - $112 = i64toi32_i32$5; - i64toi32_i32$5 = $3; - HEAP32[($3 + 64 | 0) >> 2] = $112; - HEAP32[($3 + 68 | 0) >> 2] = i64toi32_i32$1; - $5 = HEAP32[($3 + 32 | 0) >> 2] | 0; - $2 = HEAP32[($3 + 52 | 0) >> 2] | 0; - label$7 : { - $4 = HEAP32[($3 + 56 | 0) >> 2] | 0; - $1 = HEAP32[($3 + 48 | 0) >> 2] | 0; - if ($4 >>> 0 < (HEAPU16[($1 + 182 | 0) >> 1] | 0) >>> 0) { - break label$7 - } - label$8 : while (1) { - $2 = $2 + 1 | 0; - $4 = HEAPU16[($1 + 180 | 0) >> 1] | 0; - $1 = HEAP32[$1 >> 2] | 0; - if ($4 >>> 0 >= (HEAPU16[($1 + 182 | 0) >> 1] | 0) >>> 0) { - continue label$8 - } - break label$8; - }; - } - $7 = ($1 + ($4 << 2 | 0) | 0) + 4 | 0; - $8 = HEAP32[$7 >> 2] | 0; - HEAP32[$7 >> 2] = $5; - $5 = $1 + Math_imul($4, 12) | 0; - $7 = $5 + 56 | 0; - HEAP32[(($3 + 32 | 0) + 8 | 0) >> 2] = HEAP32[$7 >> 2] | 0; - $5 = $5 + 48 | 0; - i64toi32_i32$0 = $5; - i64toi32_i32$1 = HEAP32[$5 >> 2] | 0; - i64toi32_i32$5 = HEAP32[($5 + 4 | 0) >> 2] | 0; - $9 = i64toi32_i32$1; - $9$hi = i64toi32_i32$5; - i64toi32_i32$0 = $3; - i64toi32_i32$5 = HEAP32[($3 + 64 | 0) >> 2] | 0; - i64toi32_i32$1 = HEAP32[($3 + 68 | 0) >> 2] | 0; - $161 = i64toi32_i32$5; - i64toi32_i32$5 = $5; - HEAP32[$5 >> 2] = $161; - HEAP32[($5 + 4 | 0) >> 2] = i64toi32_i32$1; - HEAP32[$7 >> 2] = HEAP32[$6 >> 2] | 0; - i64toi32_i32$1 = $9$hi; - i64toi32_i32$5 = $3; - HEAP32[($3 + 32 | 0) >> 2] = $9; - HEAP32[($3 + 36 | 0) >> 2] = i64toi32_i32$1; - $5 = $4 + 1 | 0; - label$9 : { - if (!$2) { - break label$9 - } - $4 = ($1 + ($5 << 2 | 0) | 0) + 184 | 0; - label$10 : { - label$11 : { - $5 = $2 & 7 | 0; - if ($5) { - break label$11 - } - $6 = $2; - break label$10; - } - $6 = $2; - label$12 : while (1) { - $6 = $6 + -1 | 0; - $1 = HEAP32[$4 >> 2] | 0; - $4 = $1 + 184 | 0; - $5 = $5 + -1 | 0; - if ($5) { - continue label$12 - } - break label$12; - }; - } - $5 = 0; - if ($2 >>> 0 < 8 >>> 0) { - break label$9 - } - label$13 : while (1) { - $1 = HEAP32[((HEAP32[((HEAP32[((HEAP32[((HEAP32[((HEAP32[((HEAP32[((HEAP32[$4 >> 2] | 0) + 184 | 0) >> 2] | 0) + 184 | 0) >> 2] | 0) + 184 | 0) >> 2] | 0) + 184 | 0) >> 2] | 0) + 184 | 0) >> 2] | 0) + 184 | 0) >> 2] | 0) + 184 | 0) >> 2] | 0; - $4 = $1 + 184 | 0; - $6 = $6 + -8 | 0; - if ($6) { - continue label$13 - } - break label$13; - }; - } - HEAP32[$0 >> 2] = $8; - i64toi32_i32$0 = $3; - i64toi32_i32$1 = HEAP32[($3 + 32 | 0) >> 2] | 0; - i64toi32_i32$5 = HEAP32[($3 + 36 | 0) >> 2] | 0; - $210 = i64toi32_i32$1; - i64toi32_i32$1 = $0; - HEAP32[(i64toi32_i32$1 + 4 | 0) >> 2] = $210; - HEAP32[(i64toi32_i32$1 + 8 | 0) >> 2] = i64toi32_i32$5; - HEAP32[(i64toi32_i32$1 + 24 | 0) >> 2] = $5; - HEAP32[(i64toi32_i32$1 + 20 | 0) >> 2] = 0; - HEAP32[(i64toi32_i32$1 + 16 | 0) >> 2] = $1; - HEAP32[(i64toi32_i32$1 + 12 | 0) >> 2] = HEAP32[($3 + 40 | 0) >> 2] | 0; - } - __stack_pointer = $3 + 80 | 0; - } - - function _ZN5alloc7raw_vec19RawVec$LT$T$C$A$GT$7reserve21do_reserve_and_handle17h3c2f1fde18393d5eE_llvm_5589736827978271673($0, $1, $2) { - $0 = $0 | 0; - $1 = $1 | 0; - $2 = $2 | 0; - var $3 = 0, $4 = 0; - $3 = __stack_pointer - 32 | 0; - __stack_pointer = $3; - label$1 : { - $2 = $1 + $2 | 0; - if ($2 >>> 0 >= $1 >>> 0) { - break label$1 - } - _ZN5alloc7raw_vec12handle_error17h7f22430f64ae98acE(0 | 0, 0 | 0); - wasm2js_trap(); - } - $4 = HEAP32[$0 >> 2] | 0; - $1 = $4 << 1 | 0; - $1 = $1 >>> 0 > $2 >>> 0 ? $1 : $2; - $1 = $1 >>> 0 > 8 >>> 0 ? $1 : 8; - $2 = ($1 ^ -1 | 0) >>> 31 | 0; - label$2 : { - label$3 : { - if ($4) { - break label$3 - } - $4 = 0; - break label$2; - } - HEAP32[($3 + 28 | 0) >> 2] = $4; - HEAP32[($3 + 20 | 0) >> 2] = HEAP32[($0 + 4 | 0) >> 2] | 0; - $4 = 1; - } - HEAP32[($3 + 24 | 0) >> 2] = $4; - _ZN5alloc7raw_vec11finish_grow17h2a582f1f38547224E_llvm_5589736827978271673($3 + 8 | 0 | 0, $2 | 0, $1 | 0, $3 + 20 | 0 | 0); - label$4 : { - if ((HEAP32[($3 + 8 | 0) >> 2] | 0 | 0) != (1 | 0)) { - break label$4 - } - _ZN5alloc7raw_vec12handle_error17h7f22430f64ae98acE(HEAP32[($3 + 12 | 0) >> 2] | 0 | 0, HEAP32[($3 + 16 | 0) >> 2] | 0 | 0); - wasm2js_trap(); - } - $2 = HEAP32[($3 + 12 | 0) >> 2] | 0; - HEAP32[$0 >> 2] = $1; - HEAP32[($0 + 4 | 0) >> 2] = $2; - __stack_pointer = $3 + 32 | 0; - } - - function _ZN5alloc11collections5btree3map25BTreeMap$LT$K$C$V$C$A$GT$6insert17ha01c5540b97f764fE($0, $1, $2, $3) { - $0 = $0 | 0; - $1 = $1 | 0; - $2 = $2 | 0; - $3 = $3 | 0; - var $10 = 0, $4 = 0, i64toi32_i32$1 = 0, i64toi32_i32$0 = 0, $7 = 0, i64toi32_i32$2 = 0, $5 = 0, $11 = 0, $12 = 0, $6 = 0, $8 = 0, $9 = 0, $75 = 0, $95 = 0, $123 = 0, $126 = 0; - $4 = __stack_pointer - 48 | 0; - __stack_pointer = $4; - label$1 : { - label$2 : { - label$3 : { - label$4 : { - label$5 : { - $5 = HEAP32[$1 >> 2] | 0; - if (!$5) { - break label$5 - } - $6 = HEAP32[($1 + 4 | 0) >> 2] | 0; - label$6 : while (1) { - $7 = $5 + 4 | 0; - $8 = HEAPU16[($5 + 182 | 0) >> 1] | 0; - $9 = Math_imul($8, 12); - $10 = 0; - $11 = -1; - label$7 : { - label$8 : while (1) { - label$9 : { - if (($9 | 0) != ($10 | 0)) { - break label$9 - } - $11 = $8; - break label$7; - } - $12 = HEAP32[$7 >> 2] | 0; - $11 = $11 + 1 | 0; - $10 = $10 + 12 | 0; - $7 = $7 + 4 | 0; - $12 = $12 >>> 0 > $2 >>> 0 ? -1 : ($12 | 0) != ($2 | 0); - if (($12 | 0) == (1 | 0)) { - continue label$8 - } - break label$8; - }; - if (!($12 & 255 | 0)) { - break label$3 - } - } - if (!$6) { - break label$4 - } - $6 = $6 + -1 | 0; - $5 = HEAP32[(($5 + ($11 << 2 | 0) | 0) + 184 | 0) >> 2] | 0; - continue label$6; - }; - } - $7 = 0; - HEAPU8[(0 + 1051325 | 0) >> 0] | 0; - $10 = __rust_alloc(184 | 0, 4 | 0) | 0; - if (!$10) { - break label$1 - } - HEAP16[($10 + 182 | 0) >> 1] = 1; - HEAP32[$10 >> 2] = 0; - HEAP32[($10 + 4 | 0) >> 2] = $2; - i64toi32_i32$1 = $1; - i64toi32_i32$0 = 1; - HEAP32[(i64toi32_i32$1 + 4 | 0) >> 2] = 0; - HEAP32[(i64toi32_i32$1 + 8 | 0) >> 2] = i64toi32_i32$0; - HEAP32[i64toi32_i32$1 >> 2] = $10; - i64toi32_i32$2 = $3; - i64toi32_i32$0 = HEAP32[i64toi32_i32$2 >> 2] | 0; - i64toi32_i32$1 = HEAP32[(i64toi32_i32$2 + 4 | 0) >> 2] | 0; - $75 = i64toi32_i32$0; - i64toi32_i32$0 = $10; - HEAP32[($10 + 48 | 0) >> 2] = $75; - HEAP32[($10 + 52 | 0) >> 2] = i64toi32_i32$1; - HEAP32[($10 + 56 | 0) >> 2] = HEAP32[(i64toi32_i32$2 + 8 | 0) >> 2] | 0; - break label$2; - } - $7 = 0; - HEAP32[($4 + 16 | 0) >> 2] = 0; - HEAP32[($4 + 12 | 0) >> 2] = $5; - HEAP32[($4 + 8 | 0) >> 2] = $2; - HEAP32[($4 + 4 | 0) >> 2] = $1; - HEAP32[($4 + 20 | 0) >> 2] = $11; - HEAP32[($4 + 32 | 0) >> 2] = $11; - i64toi32_i32$2 = $4; - i64toi32_i32$1 = HEAP32[($4 + 12 | 0) >> 2] | 0; - i64toi32_i32$0 = HEAP32[($4 + 16 | 0) >> 2] | 0; - $95 = i64toi32_i32$1; - i64toi32_i32$1 = $4; - HEAP32[($4 + 24 | 0) >> 2] = $95; - HEAP32[($4 + 28 | 0) >> 2] = i64toi32_i32$0; - _ZN5alloc11collections5btree4node210Handle$LT$alloc__collections__btree__node__NodeRef$LT$alloc__collections__btree__node__marker__Mut$C$K$C$V$C$alloc__collections__btree__node__marker__Leaf$GT$$C$alloc__collections__btree__node__marker__Edge$GT$16insert_recursing17h01740383b348720fE($4 + 36 | 0 | 0, $4 + 24 | 0 | 0, $2 | 0, $3 | 0, $4 + 4 | 0 | 0); - $10 = HEAP32[($4 + 4 | 0) >> 2] | 0; - HEAP32[($10 + 8 | 0) >> 2] = (HEAP32[($10 + 8 | 0) >> 2] | 0) + 1 | 0; - break label$2; - } - $10 = $5 + $10 | 0; - $7 = $10 + 44 | 0; - HEAP32[($0 + 12 | 0) >> 2] = HEAP32[$7 >> 2] | 0; - $10 = $10 + 36 | 0; - i64toi32_i32$2 = $10; - i64toi32_i32$0 = HEAP32[$10 >> 2] | 0; - i64toi32_i32$1 = HEAP32[($10 + 4 | 0) >> 2] | 0; - $123 = i64toi32_i32$0; - i64toi32_i32$0 = $0; - HEAP32[(i64toi32_i32$0 + 4 | 0) >> 2] = $123; - HEAP32[(i64toi32_i32$0 + 8 | 0) >> 2] = i64toi32_i32$1; - i64toi32_i32$2 = $3; - i64toi32_i32$1 = HEAP32[i64toi32_i32$2 >> 2] | 0; - i64toi32_i32$0 = HEAP32[(i64toi32_i32$2 + 4 | 0) >> 2] | 0; - $126 = i64toi32_i32$1; - i64toi32_i32$1 = $10; - HEAP32[$10 >> 2] = $126; - HEAP32[($10 + 4 | 0) >> 2] = i64toi32_i32$0; - HEAP32[$7 >> 2] = HEAP32[(i64toi32_i32$2 + 8 | 0) >> 2] | 0; - $7 = 1; - } - HEAP32[$0 >> 2] = $7; - __stack_pointer = $4 + 48 | 0; - return; - } - _ZN5alloc5alloc18handle_alloc_error17h123ae56be4092711E(4 | 0, 184 | 0); - wasm2js_trap(); - } - - function _ZN5alloc11collections5btree3map25BTreeMap$LT$K$C$V$C$A$GT$6remove17hc793cbb765ab111dE($0, $1, $2) { - $0 = $0 | 0; - $1 = $1 | 0; - $2 = $2 | 0; - var $3 = 0, i64toi32_i32$0 = 0, i64toi32_i32$1 = 0, i64toi32_i32$2 = 0, $9 = 0, $10 = 0, $4 = 0, $6 = 0, $5 = 0, $7 = 0, $8 = 0, $82 = 0, $85 = 0, $96 = 0, $99 = 0, $123 = 0, $126 = 0, $129 = 0; - $3 = __stack_pointer - 96 | 0; - __stack_pointer = $3; - label$1 : { - label$2 : { - label$3 : { - label$4 : { - $4 = HEAP32[$1 >> 2] | 0; - if ($4) { - break label$4 - } - $2 = 0; - break label$3; - } - $5 = HEAP32[$2 >> 2] | 0; - $6 = HEAP32[($1 + 4 | 0) >> 2] | 0; - label$5 : while (1) { - $7 = HEAPU16[($4 + 182 | 0) >> 1] | 0; - $8 = $7 << 2 | 0; - $2 = 0; - $9 = -1; - label$6 : { - label$7 : { - label$8 : while (1) { - label$9 : { - if (($8 | 0) != ($2 | 0)) { - break label$9 - } - $9 = $7; - break label$7; - } - $10 = $4 + $2 | 0; - $9 = $9 + 1 | 0; - $2 = $2 + 4 | 0; - $10 = HEAP32[($10 + 4 | 0) >> 2] | 0; - $10 = $10 >>> 0 > $5 >>> 0 ? -1 : ($10 | 0) != ($5 | 0); - if (($10 | 0) == (1 | 0)) { - continue label$8 - } - break label$8; - }; - if (!($10 & 255 | 0)) { - break label$6 - } - } - label$10 : { - if ($6) { - break label$10 - } - $2 = 0; - break label$3; - } - $6 = $6 + -1 | 0; - $4 = HEAP32[(($4 + ($9 << 2 | 0) | 0) + 184 | 0) >> 2] | 0; - continue label$5; - } - break label$5; - }; - HEAP32[($3 + 40 | 0) >> 2] = $1; - HEAP32[($3 + 36 | 0) >> 2] = $9; - HEAP32[($3 + 32 | 0) >> 2] = $6; - HEAP32[($3 + 28 | 0) >> 2] = $4; - HEAP8[($3 + 47 | 0) >> 0] = 0; - _ZN5alloc11collections5btree6remove269_$LT$impl$u20$alloc__collections__btree__node__Handle$LT$alloc__collections__btree__node__NodeRef$LT$alloc__collections__btree__node__marker__Mut$C$K$C$V$C$alloc__collections__btree__node__marker__LeafOrInternal$GT$$C$alloc__collections__btree__node__marker__KV$GT$$GT$18remove_kv_tracking17h9cdde6bfc5849410E($3 + 68 | 0 | 0, $3 + 28 | 0 | 0, $3 + 47 | 0 | 0); - $2 = ($3 + 48 | 0) + 8 | 0; - i64toi32_i32$2 = ($3 + 68 | 0) + 8 | 0; - i64toi32_i32$0 = HEAP32[i64toi32_i32$2 >> 2] | 0; - i64toi32_i32$1 = HEAP32[(i64toi32_i32$2 + 4 | 0) >> 2] | 0; - $82 = i64toi32_i32$0; - i64toi32_i32$0 = $2; - HEAP32[i64toi32_i32$0 >> 2] = $82; - HEAP32[(i64toi32_i32$0 + 4 | 0) >> 2] = i64toi32_i32$1; - i64toi32_i32$2 = $3; - i64toi32_i32$1 = HEAP32[($3 + 68 | 0) >> 2] | 0; - i64toi32_i32$0 = HEAP32[($3 + 72 | 0) >> 2] | 0; - $85 = i64toi32_i32$1; - i64toi32_i32$1 = $3; - HEAP32[($3 + 48 | 0) >> 2] = $85; - HEAP32[($3 + 52 | 0) >> 2] = i64toi32_i32$0; - HEAP32[($1 + 8 | 0) >> 2] = (HEAP32[($1 + 8 | 0) >> 2] | 0) + -1 | 0; - label$11 : { - label$12 : { - if (HEAPU8[($3 + 47 | 0) >> 0] | 0) { - break label$12 - } - i64toi32_i32$2 = $2; - i64toi32_i32$0 = HEAP32[i64toi32_i32$2 >> 2] | 0; - i64toi32_i32$1 = HEAP32[(i64toi32_i32$2 + 4 | 0) >> 2] | 0; - $96 = i64toi32_i32$0; - i64toi32_i32$0 = ($3 + 8 | 0) + 8 | 0; - HEAP32[i64toi32_i32$0 >> 2] = $96; - HEAP32[(i64toi32_i32$0 + 4 | 0) >> 2] = i64toi32_i32$1; - i64toi32_i32$2 = $3; - i64toi32_i32$1 = HEAP32[($3 + 48 | 0) >> 2] | 0; - i64toi32_i32$0 = HEAP32[($3 + 52 | 0) >> 2] | 0; - $99 = i64toi32_i32$1; - i64toi32_i32$1 = $3; - HEAP32[($3 + 8 | 0) >> 2] = $99; - HEAP32[($3 + 12 | 0) >> 2] = i64toi32_i32$0; - break label$11; - } - $2 = HEAP32[$1 >> 2] | 0; - if (!$2) { - break label$2 - } - $9 = HEAP32[($1 + 4 | 0) >> 2] | 0; - if (!$9) { - break label$1 - } - HEAP32[($1 + 4 | 0) >> 2] = $9 + -1 | 0; - $9 = HEAP32[($2 + 184 | 0) >> 2] | 0; - HEAP32[$1 >> 2] = $9; - HEAP32[$9 >> 2] = 0; - __rust_dealloc($2 | 0, 232 | 0, 4 | 0); - i64toi32_i32$2 = ($3 + 48 | 0) + 8 | 0; - i64toi32_i32$0 = HEAP32[i64toi32_i32$2 >> 2] | 0; - i64toi32_i32$1 = HEAP32[(i64toi32_i32$2 + 4 | 0) >> 2] | 0; - $123 = i64toi32_i32$0; - i64toi32_i32$0 = ($3 + 8 | 0) + 8 | 0; - HEAP32[i64toi32_i32$0 >> 2] = $123; - HEAP32[(i64toi32_i32$0 + 4 | 0) >> 2] = i64toi32_i32$1; - i64toi32_i32$2 = $3; - i64toi32_i32$1 = HEAP32[($3 + 48 | 0) >> 2] | 0; - i64toi32_i32$0 = HEAP32[($3 + 52 | 0) >> 2] | 0; - $126 = i64toi32_i32$1; - i64toi32_i32$1 = $3; - HEAP32[($3 + 8 | 0) >> 2] = $126; - HEAP32[($3 + 12 | 0) >> 2] = i64toi32_i32$0; - } - i64toi32_i32$2 = $3; - i64toi32_i32$0 = HEAP32[($3 + 12 | 0) >> 2] | 0; - i64toi32_i32$1 = HEAP32[($3 + 16 | 0) >> 2] | 0; - $129 = i64toi32_i32$0; - i64toi32_i32$0 = $0; - HEAP32[(i64toi32_i32$0 + 4 | 0) >> 2] = $129; - HEAP32[(i64toi32_i32$0 + 8 | 0) >> 2] = i64toi32_i32$1; - HEAP32[(i64toi32_i32$0 + 12 | 0) >> 2] = HEAP32[(($3 + 8 | 0) + 12 | 0) >> 2] | 0; - $2 = 1; - } - HEAP32[$0 >> 2] = $2; - __stack_pointer = $3 + 96 | 0; - return; - } - _ZN4core6option13unwrap_failed17h98817bc8a3accaffE(1051024 | 0); - wasm2js_trap(); - } - _ZN4core9panicking5panic17h9f0a34b0744fbd45E(1050036 | 0, 33 | 0, 1050072 | 0); - wasm2js_trap(); - } - - function _ZN5alloc7raw_vec11finish_grow17h2a582f1f38547224E_llvm_5589736827978271673($0, $1, $2, $3) { - $0 = $0 | 0; - $1 = $1 | 0; - $2 = $2 | 0; - $3 = $3 | 0; - var $4 = 0, $5 = 0, $6 = 0; - $4 = 1; - $5 = 0; - $6 = 4; - label$1 : { - if (!$1) { - break label$1 - } - if (($2 | 0) < (0 | 0)) { - break label$1 - } - label$2 : { - label$3 : { - label$4 : { - label$5 : { - label$6 : { - if (!(HEAP32[($3 + 4 | 0) >> 2] | 0)) { - break label$6 - } - label$7 : { - $4 = HEAP32[($3 + 8 | 0) >> 2] | 0; - if ($4) { - break label$7 - } - label$8 : { - if ($2) { - break label$8 - } - $4 = 1; - break label$4; - } - HEAPU8[(0 + 1051325 | 0) >> 0] | 0; - $4 = __rust_alloc($2 | 0, 1 | 0) | 0; - break label$5; - } - $4 = __rust_realloc(HEAP32[$3 >> 2] | 0 | 0, $4 | 0, 1 | 0, $2 | 0) | 0; - break label$5; - } - label$9 : { - if ($2) { - break label$9 - } - $4 = 1; - break label$4; - } - HEAPU8[(0 + 1051325 | 0) >> 0] | 0; - $4 = __rust_alloc($2 | 0, 1 | 0) | 0; - } - if (!$4) { - break label$3 - } - } - HEAP32[($0 + 4 | 0) >> 2] = $4; - $4 = 0; - break label$2; - } - $4 = 1; - HEAP32[($0 + 4 | 0) >> 2] = 1; - } - $6 = 8; - $5 = $2; - } - HEAP32[($0 + $6 | 0) >> 2] = $5; - HEAP32[$0 >> 2] = $4; - } - - function _ZN98_$LT$alloc__vec__Vec$LT$T$GT$$u20$as$u20$alloc__vec__spec_from_iter__SpecFromIter$LT$T$C$I$GT$$GT$9from_iter17hace63ed3f33297cdE($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - var $2 = 0, $6 = 0, $5 = 0, $3 = 0, $9 = 0, $4 = 0, i64toi32_i32$0 = 0, $10 = 0, $7 = 0, i64toi32_i32$1 = 0, $8 = 0, $11 = 0, $12 = 0, $237 = 0; - $2 = __stack_pointer - 48 | 0; - __stack_pointer = $2; - $3 = HEAP32[($1 + 8 | 0) >> 2] | 0; - label$1 : { - label$2 : { - label$3 : { - label$4 : { - label$5 : { - label$6 : { - $4 = HEAP32[$1 >> 2] | 0; - if ($4) { - break label$6 - } - if (!$3) { - break label$5 - } - $5 = (HEAP32[($1 + 12 | 0) >> 2] | 0) - $3 | 0; - break label$3; - } - $6 = (HEAP32[($1 + 4 | 0) >> 2] | 0) - $4 | 0; - if ($3) { - break label$4 - } - $5 = $6; - break label$3; - } - i64toi32_i32$1 = $2; - i64toi32_i32$0 = 1; - HEAP32[($2 + 12 | 0) >> 2] = 0; - HEAP32[($2 + 16 | 0) >> 2] = i64toi32_i32$0; - $6 = 0; - break label$2; - } - $5 = ((HEAP32[($1 + 12 | 0) >> 2] | 0) - $3 | 0) + $6 | 0; - if ($5 >>> 0 < $6 >>> 0) { - break label$1 - } - } - label$7 : { - label$8 : { - label$9 : { - label$10 : { - label$11 : { - if ($5) { - break label$11 - } - $7 = 1; - break label$10; - } - $6 = 0; - if (($5 | 0) < (0 | 0)) { - break label$9 - } - HEAPU8[(0 + 1051325 | 0) >> 0] | 0; - $6 = 1; - $7 = __rust_alloc($5 | 0, 1 | 0) | 0; - if (!$7) { - break label$9 - } - } - $6 = 0; - HEAP32[($2 + 20 | 0) >> 2] = 0; - HEAP32[($2 + 16 | 0) >> 2] = $7; - HEAP32[($2 + 12 | 0) >> 2] = $5; - $8 = HEAP32[($1 + 12 | 0) >> 2] | 0; - $1 = HEAP32[($1 + 4 | 0) >> 2] | 0; - label$12 : { - label$13 : { - label$14 : { - if ($4) { - break label$14 - } - if (!$3) { - break label$2 - } - $6 = $8 - $3 | 0; - break label$13; - } - $9 = $1 - $4 | 0; - label$15 : { - if ($3) { - break label$15 - } - $6 = $9; - break label$13; - } - $6 = ($8 - $3 | 0) + $9 | 0; - if ($6 >>> 0 < $9 >>> 0) { - break label$12 - } - } - if ($6 >>> 0 > $5 >>> 0) { - break label$8 - } - $6 = 0; - break label$7; - } - HEAP32[($2 + 40 | 0) >> 2] = 0; - HEAP32[($2 + 28 | 0) >> 2] = 1; - HEAP32[($2 + 24 | 0) >> 2] = 1050808; - i64toi32_i32$1 = $2; - i64toi32_i32$0 = 0; - HEAP32[($2 + 32 | 0) >> 2] = 4; - HEAP32[($2 + 36 | 0) >> 2] = i64toi32_i32$0; - _ZN4core9panicking9panic_fmt17hb2f16849466f57b6E($2 + 24 | 0 | 0, 1051116 | 0); - wasm2js_trap(); - } - _ZN5alloc7raw_vec12handle_error17h7f22430f64ae98acE($6 | 0, $5 | 0); - wasm2js_trap(); - } - _ZN5alloc7raw_vec19RawVec$LT$T$C$A$GT$7reserve21do_reserve_and_handle17h3c2f1fde18393d5eE_llvm_5589736827978271673($2 + 12 | 0 | 0, 0 | 0, $6 | 0); - $7 = HEAP32[($2 + 16 | 0) >> 2] | 0; - $6 = HEAP32[($2 + 20 | 0) >> 2] | 0; - } - label$16 : { - if (!$4) { - break label$16 - } - if (($4 | 0) == ($1 | 0)) { - break label$16 - } - $5 = $1 - $4 | 0; - $10 = $5 & 3 | 0; - label$17 : { - label$18 : { - if (($4 - $1 | 0) >>> 0 <= -4 >>> 0) { - break label$18 - } - $1 = 0; - break label$17; - } - $11 = $7 + $6 | 0; - $12 = $5 & -4 | 0; - $1 = 0; - label$19 : while (1) { - $5 = $11 + $1 | 0; - $9 = $4 + $1 | 0; - HEAP8[$5 >> 0] = HEAPU8[$9 >> 0] | 0; - HEAP8[($5 + 1 | 0) >> 0] = HEAPU8[($9 + 1 | 0) >> 0] | 0; - HEAP8[($5 + 2 | 0) >> 0] = HEAPU8[($9 + 2 | 0) >> 0] | 0; - HEAP8[($5 + 3 | 0) >> 0] = HEAPU8[($9 + 3 | 0) >> 0] | 0; - $1 = $1 + 4 | 0; - if (($12 | 0) != ($1 | 0)) { - continue label$19 - } - break label$19; - }; - $6 = $6 + $1 | 0; - } - if (!$10) { - break label$16 - } - $1 = $4 + $1 | 0; - label$20 : while (1) { - HEAP8[($7 + $6 | 0) >> 0] = HEAPU8[$1 >> 0] | 0; - $1 = $1 + 1 | 0; - $6 = $6 + 1 | 0; - $10 = $10 + -1 | 0; - if ($10) { - continue label$20 - } - break label$20; - }; - } - if (!$3) { - break label$2 - } - if (($3 | 0) == ($8 | 0)) { - break label$2 - } - $1 = $8 - $3 | 0; - $10 = $1 & 3 | 0; - label$21 : { - label$22 : { - if (($3 - $8 | 0) >>> 0 <= -4 >>> 0) { - break label$22 - } - $1 = 0; - break label$21; - } - $4 = $7 + $6 | 0; - $11 = $1 & -4 | 0; - $1 = 0; - label$23 : while (1) { - $5 = $4 + $1 | 0; - $9 = $3 + $1 | 0; - HEAP8[$5 >> 0] = HEAPU8[$9 >> 0] | 0; - HEAP8[($5 + 1 | 0) >> 0] = HEAPU8[($9 + 1 | 0) >> 0] | 0; - HEAP8[($5 + 2 | 0) >> 0] = HEAPU8[($9 + 2 | 0) >> 0] | 0; - HEAP8[($5 + 3 | 0) >> 0] = HEAPU8[($9 + 3 | 0) >> 0] | 0; - $1 = $1 + 4 | 0; - if (($11 | 0) != ($1 | 0)) { - continue label$23 - } - break label$23; - }; - $6 = $6 + $1 | 0; - } - if (!$10) { - break label$2 - } - $1 = $3 + $1 | 0; - label$24 : while (1) { - HEAP8[($7 + $6 | 0) >> 0] = HEAPU8[$1 >> 0] | 0; - $1 = $1 + 1 | 0; - $6 = $6 + 1 | 0; - $10 = $10 + -1 | 0; - if ($10) { - continue label$24 - } - break label$24; - }; - } - HEAP32[($2 + 20 | 0) >> 2] = $6; - i64toi32_i32$0 = HEAP32[($2 + 12 | 0) >> 2] | 0; - i64toi32_i32$1 = HEAP32[($2 + 16 | 0) >> 2] | 0; - $237 = i64toi32_i32$0; - i64toi32_i32$0 = $0; - HEAP32[i64toi32_i32$0 >> 2] = $237; - HEAP32[(i64toi32_i32$0 + 4 | 0) >> 2] = i64toi32_i32$1; - HEAP32[(i64toi32_i32$0 + 8 | 0) >> 2] = HEAP32[(($2 + 12 | 0) + 8 | 0) >> 2] | 0; - __stack_pointer = $2 + 48 | 0; - return; - } - HEAP32[($2 + 40 | 0) >> 2] = 0; - HEAP32[($2 + 28 | 0) >> 2] = 1; - HEAP32[($2 + 24 | 0) >> 2] = 1050808; - i64toi32_i32$0 = $2; - i64toi32_i32$1 = 0; - HEAP32[($2 + 32 | 0) >> 2] = 4; - HEAP32[($2 + 36 | 0) >> 2] = i64toi32_i32$1; - _ZN4core9panicking9panic_fmt17hb2f16849466f57b6E($2 + 24 | 0 | 0, 1050912 | 0); - wasm2js_trap(); - } - - function _ZN42_$LT$$RF$T$u20$as$u20$core__fmt__Debug$GT$3fmt17h48376aecd7558ddcE($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - var $2 = 0, $3 = 0; - $2 = __stack_pointer - 16 | 0; - __stack_pointer = $2; - $3 = HEAP32[($0 + 4 | 0) >> 2] | 0; - $0 = HEAP32[$0 >> 2] | 0; - _ZN4core3fmt9Formatter10debug_list17hd710ece3eac84443E($2 + 4 | 0 | 0, $1 | 0); - label$1 : { - if (!$3) { - break label$1 - } - label$2 : while (1) { - HEAP32[($2 + 12 | 0) >> 2] = $0; - _ZN4core3fmt8builders8DebugSet5entry17h7036b50f83a7398eE($2 + 4 | 0 | 0, $2 + 12 | 0 | 0, 1051132 | 0) | 0; - $0 = $0 + 1 | 0; - $3 = $3 + -1 | 0; - if ($3) { - continue label$2 - } - break label$2; - }; - } - $0 = _ZN4core3fmt8builders9DebugList6finish17h4ef7645c675cb82eE($2 + 4 | 0 | 0) | 0; - __stack_pointer = $2 + 16 | 0; - return $0 | 0; - } - - function _ZN42_$LT$$RF$T$u20$as$u20$core__fmt__Debug$GT$3fmt17hc2f10bc6239b2f43E($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - var $2 = 0; - $0 = HEAP32[$0 >> 2] | 0; - label$1 : { - $2 = HEAP32[($1 + 28 | 0) >> 2] | 0; - if ($2 & 16 | 0) { - break label$1 - } - label$2 : { - if ($2 & 32 | 0) { - break label$2 - } - return _ZN4core3fmt3num3imp51_$LT$impl$u20$core__fmt__Display$u20$for$u20$u8$GT$3fmt17h96ec540fce0e8c05E($0 | 0, $1 | 0) | 0 | 0; - } - return _ZN4core3fmt3num52_$LT$impl$u20$core__fmt__UpperHex$u20$for$u20$i8$GT$3fmt17h8bec9e17aa3a250bE($0 | 0, $1 | 0) | 0 | 0; - } - return _ZN4core3fmt3num52_$LT$impl$u20$core__fmt__LowerHex$u20$for$u20$i8$GT$3fmt17hbd8bbf103c04b7d4E($0 | 0, $1 | 0) | 0 | 0; - } - - function _ZN12rust_runtime3mem6WACell8new_data17h26cb5cb718c9ee73E($0, $1, $2) { - $0 = $0 | 0; - $1 = $1 | 0; - $2 = $2 | 0; - var $3 = 0, $4 = 0, $5 = 0, $6 = 0, $10 = 0, $11 = 0, $7 = 0, $8 = 0, $9 = 0; - $3 = __stack_pointer - 48 | 0; - __stack_pointer = $3; - $4 = 0; - HEAPU8[(0 + 1051325 | 0) >> 0] | 0; - $5 = $2 + 8 | 0; - $6 = __rust_alloc($5 | 0, 1 | 0) | 0; - HEAP32[($3 + 12 | 0) >> 2] = $0 << 24 | 0 | (($0 & 65280 | 0) << 8 | 0) | 0 | (($0 >>> 8 | 0) & 65280 | 0 | ($0 >>> 24 | 0) | 0) | 0; - HEAP32[($3 + 16 | 0) >> 2] = $2 << 24 | 0 | (($2 & 65280 | 0) << 8 | 0) | 0 | (($2 >>> 8 | 0) & 65280 | 0 | ($2 >>> 24 | 0) | 0) | 0; - HEAP32[($3 + 20 | 0) >> 2] = $1; - $7 = $1 + $2 | 0; - HEAP32[($3 + 32 | 0) >> 2] = $3 + 16 | 0; - $8 = ($3 + 16 | 0) + 4 | 0; - $9 = ($3 + 12 | 0) + 4 | 0; - $0 = $3 + 12 | 0; - $1 = 1; - label$1 : { - label$2 : { - label$3 : while (1) { - label$4 : { - label$5 : { - label$6 : { - label$7 : { - if ($1 & 1 | 0) { - break label$7 - } - $10 = $0; - break label$6; - } - label$8 : { - if (!$0) { - break label$8 - } - if (($0 | 0) == ($9 | 0)) { - break label$8 - } - $1 = 1; - $10 = $0 + 1 | 0; - break label$4; - } - $10 = 0; - $0 = HEAP32[($3 + 32 | 0) >> 2] | 0; - if (!$0) { - break label$6 - } - if (($8 | 0) == ($0 | 0)) { - break label$6 - } - $11 = $3 + 32 | 0; - $1 = 1; - break label$5; - } - $0 = HEAP32[($3 + 20 | 0) >> 2] | 0; - if (!$0) { - break label$2 - } - if (($7 | 0) == ($0 | 0)) { - break label$2 - } - $11 = $3 + 20 | 0; - $1 = 0; - } - HEAP32[$11 >> 2] = $0 + 1 | 0; - } - if (($5 | 0) == ($4 | 0)) { - break label$1 - } - HEAP8[($6 + $4 | 0) >> 0] = HEAPU8[$0 >> 0] | 0; - $4 = $4 + 1 | 0; - $0 = $10; - continue label$3; - }; - } - HEAP32[($3 + 28 | 0) >> 2] = 1; - HEAP32[($3 + 20 | 0) >> 2] = $2; - HEAP32[($3 + 24 | 0) >> 2] = $6; - $0 = $6 + 8 | 0; - _ZN5alloc11collections5btree3map25BTreeMap$LT$K$C$V$C$A$GT$6insert17ha01c5540b97f764fE($3 + 32 | 0 | 0, 1051808 | 0, $0 | 0, $3 + 20 | 0 | 0); - label$9 : { - if (!(HEAP32[($3 + 32 | 0) >> 2] | 0)) { - break label$9 - } - __rust_dealloc(HEAP32[($3 + 40 | 0) >> 2] | 0 | 0, HEAP32[($3 + 36 | 0) >> 2] | 0 | 0, 1 | 0); - } - __stack_pointer = $3 + 48 | 0; - return $0 | 0; - } - _ZN4core9panicking18panic_bounds_check17hb583f390c1467acdE($5 | 0, $5 | 0, 1051176 | 0); - wasm2js_trap(); - } - - function _ZN12rust_runtime3mem6WACell8new_size17h2ed2900047365a20E($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - var $2 = 0, $3 = 0, $4 = 0, $7 = 0, $5 = 0, $8 = 0, $6 = 0; - $2 = __stack_pointer - 32 | 0; - __stack_pointer = $2; - $3 = 0; - HEAPU8[(0 + 1051325 | 0) >> 0] | 0; - $4 = $1 + 8 | 0; - $5 = __rust_alloc($4 | 0, 1 | 0) | 0; - HEAP32[($2 + 4 | 0) >> 2] = $0 << 24 | 0 | (($0 & 65280 | 0) << 8 | 0) | 0 | (($0 >>> 8 | 0) & 65280 | 0 | ($0 >>> 24 | 0) | 0) | 0; - HEAP32[($2 + 16 | 0) >> 2] = $1 << 24 | 0 | (($1 & 65280 | 0) << 8 | 0) | 0 | (($1 >>> 8 | 0) & 65280 | 0 | ($1 >>> 24 | 0) | 0) | 0; - $6 = ($2 + 4 | 0) + 4 | 0; - $0 = $2 + 4 | 0; - $7 = 0; - label$1 : { - label$2 : { - label$3 : while (1) { - label$4 : { - label$5 : { - if (!$0) { - break label$5 - } - if (($0 | 0) == ($6 | 0)) { - break label$5 - } - $8 = $0 + 1 | 0; - break label$4; - } - if (($3 | 0) == (4 | 0)) { - break label$2 - } - $0 = ($2 + 16 | 0) + $3 | 0; - $3 = $3 + 1 | 0; - $8 = 0; - } - if (($4 | 0) == ($7 | 0)) { - break label$1 - } - HEAP8[($5 + $7 | 0) >> 0] = HEAPU8[$0 >> 0] | 0; - $7 = $7 + 1 | 0; - $0 = $8; - continue label$3; - }; - } - HEAP32[($2 + 12 | 0) >> 2] = 1; - HEAP32[($2 + 4 | 0) >> 2] = $1; - HEAP32[($2 + 8 | 0) >> 2] = $5; - $0 = $5 + 8 | 0; - _ZN5alloc11collections5btree3map25BTreeMap$LT$K$C$V$C$A$GT$6insert17ha01c5540b97f764fE($2 + 16 | 0 | 0, 1051808 | 0, $0 | 0, $2 + 4 | 0 | 0); - label$6 : { - if (!(HEAP32[($2 + 16 | 0) >> 2] | 0)) { - break label$6 - } - __rust_dealloc(HEAP32[($2 + 24 | 0) >> 2] | 0 | 0, HEAP32[($2 + 20 | 0) >> 2] | 0 | 0, 1 | 0); - } - __stack_pointer = $2 + 32 | 0; - return $0 | 0; - } - _ZN4core9panicking18panic_bounds_check17hb583f390c1467acdE($4 | 0, $4 | 0, 1051192 | 0); - wasm2js_trap(); - } - - function _ZN12rust_runtime3mem8WABuffer8from_ref17hd15e58422a800be2E($0) { - $0 = $0 | 0; - var $1 = 0, $8 = 0, $3 = 0, $7 = 0, $2 = 0, $4 = 0, $6 = 0, $5 = 0; - label$1 : { - $1 = HEAP32[(0 + 1051808 | 0) >> 2] | 0; - if (!$1) { - break label$1 - } - $2 = HEAP32[(0 + 1051812 | 0) >> 2] | 0; - label$2 : while (1) { - $3 = $1 + 44 | 0; - $4 = $1 + 4 | 0; - $5 = HEAPU16[($1 + 182 | 0) >> 1] | 0; - $6 = $5 << 2 | 0; - $7 = -1; - label$3 : { - label$4 : { - label$5 : while (1) { - label$6 : { - if ($6) { - break label$6 - } - $7 = $5; - break label$4; - } - $8 = HEAP32[$4 >> 2] | 0; - $7 = $7 + 1 | 0; - $3 = $3 + 12 | 0; - $6 = $6 + -4 | 0; - $4 = $4 + 4 | 0; - $8 = $8 >>> 0 > $0 >>> 0 ? -1 : ($8 | 0) != ($0 | 0); - if (($8 | 0) == (1 | 0)) { - continue label$5 - } - break label$5; - }; - if (!($8 & 255 | 0)) { - break label$3 - } - } - if (!$2) { - break label$1 - } - $2 = $2 + -1 | 0; - $1 = HEAP32[(($1 + ($7 << 2 | 0) | 0) + 184 | 0) >> 2] | 0; - continue label$2; - } - break label$2; - }; - HEAP32[$3 >> 2] = (HEAP32[$3 >> 2] | 0) + 1 | 0; - } - return $0 | 0; - } - - function _ZN12rust_runtime3mem7WAArray8from_ref17hc48303b07ff6a176E($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - var $12 = 0, $6 = 0, $7 = 0, $10 = 0, $11 = 0, $8 = 0, $5 = 0, $2 = 0, $3 = 0, $4 = 0, $9 = 0, $13 = 0; - $2 = __stack_pointer - 32 | 0; - __stack_pointer = $2; - label$1 : { - label$2 : { - $3 = HEAP32[(0 + 1051808 | 0) >> 2] | 0; - if (!$3) { - break label$2 - } - $4 = HEAP32[(0 + 1051812 | 0) >> 2] | 0; - $5 = $4; - $6 = $3; - label$3 : { - label$4 : while (1) { - $7 = $6 + 44 | 0; - $8 = $6 + 4 | 0; - $9 = HEAPU16[($6 + 182 | 0) >> 1] | 0; - $10 = $9 << 2 | 0; - $11 = -1; - label$5 : { - label$6 : { - label$7 : while (1) { - label$8 : { - if ($10) { - break label$8 - } - $11 = $9; - break label$6; - } - $12 = HEAP32[$8 >> 2] | 0; - $11 = $11 + 1 | 0; - $7 = $7 + 12 | 0; - $10 = $10 + -4 | 0; - $8 = $8 + 4 | 0; - $12 = $12 >>> 0 > $1 >>> 0 ? -1 : ($12 | 0) != ($1 | 0); - if (($12 | 0) == (1 | 0)) { - continue label$7 - } - break label$7; - }; - if (!($12 & 255 | 0)) { - break label$5 - } - } - if (!$5) { - break label$3 - } - $5 = $5 + -1 | 0; - $6 = HEAP32[(($6 + ($11 << 2 | 0) | 0) + 184 | 0) >> 2] | 0; - continue label$4; - } - break label$4; - }; - HEAP32[$7 >> 2] = (HEAP32[$7 >> 2] | 0) + 1 | 0; - $4 = HEAP32[(0 + 1051812 | 0) >> 2] | 0; - } - $5 = $4; - $6 = $3; - label$9 : while (1) { - $7 = $6 + 40 | 0; - $8 = $6 + 4 | 0; - $9 = HEAPU16[($6 + 182 | 0) >> 1] | 0; - $10 = $9 << 2 | 0; - $11 = -1; - label$10 : { - label$11 : { - label$12 : while (1) { - label$13 : { - if ($10) { - break label$13 - } - $11 = $9; - break label$11; - } - $12 = HEAP32[$8 >> 2] | 0; - $11 = $11 + 1 | 0; - $7 = $7 + 12 | 0; - $10 = $10 + -4 | 0; - $8 = $8 + 4 | 0; - $12 = $12 >>> 0 > $1 >>> 0 ? -1 : ($12 | 0) != ($1 | 0); - if (($12 | 0) == (1 | 0)) { - continue label$12 - } - break label$12; - }; - if (!($12 & 255 | 0)) { - break label$10 - } - } - if (!$5) { - break label$2 - } - $5 = $5 + -1 | 0; - $6 = HEAP32[(($6 + ($11 << 2 | 0) | 0) + 184 | 0) >> 2] | 0; - continue label$9; - } - break label$9; - }; - $10 = HEAP32[($7 + -4 | 0) >> 2] | 0; - if ($10 >>> 0 <= 3 >>> 0) { - break label$1 - } - $13 = (HEAP32[$7 >> 2] | 0) + 8 | 0; - $6 = HEAPU8[$13 >> 0] | 0 | ((HEAPU8[($13 + 1 | 0) >> 0] | 0) << 8 | 0) | 0 | ((HEAPU8[($13 + 2 | 0) >> 0] | 0) << 16 | 0 | ((HEAPU8[($13 + 3 | 0) >> 0] | 0) << 24 | 0) | 0) | 0; - label$14 : { - label$15 : while (1) { - $7 = $3 + 44 | 0; - $8 = $3 + 4 | 0; - $5 = HEAPU16[($3 + 182 | 0) >> 1] | 0; - $10 = $5 << 2 | 0; - $11 = -1; - label$16 : { - label$17 : { - label$18 : while (1) { - label$19 : { - if ($10) { - break label$19 - } - $11 = $5; - break label$17; - } - $12 = HEAP32[$8 >> 2] | 0; - $11 = $11 + 1 | 0; - $7 = $7 + 12 | 0; - $10 = $10 + -4 | 0; - $8 = $8 + 4 | 0; - $12 = $12 >>> 0 > $6 >>> 0 ? -1 : ($12 | 0) != ($6 | 0); - if (($12 | 0) == (1 | 0)) { - continue label$18 - } - break label$18; - }; - if (!($12 & 255 | 0)) { - break label$16 - } - } - if (!$4) { - break label$14 - } - $4 = $4 + -1 | 0; - $3 = HEAP32[(($3 + ($11 << 2 | 0) | 0) + 184 | 0) >> 2] | 0; - continue label$15; - } - break label$15; - }; - HEAP32[$7 >> 2] = (HEAP32[$7 >> 2] | 0) + 1 | 0; - } - HEAP32[($0 + 4 | 0) >> 2] = $6; - HEAP32[$0 >> 2] = $1; - __stack_pointer = $2 + 32 | 0; - return; - } - HEAP32[($2 + 24 | 0) >> 2] = 0; - HEAP32[($2 + 12 | 0) >> 2] = 1; - HEAP32[($2 + 8 | 0) >> 2] = 1051224; - HEAP32[($2 + 16 | 0) >> 2] = 4; - HEAP32[($2 + 20 | 0) >> 2] = 0; - _ZN4core9panicking9panic_fmt17hb2f16849466f57b6E($2 + 8 | 0 | 0, 1051248 | 0); - wasm2js_trap(); - } - _ZN4core5slice5index24slice_end_index_len_fail17h02d344349d5072f8E(4 | 0, $10 | 0, 1051160 | 0); - wasm2js_trap(); - } - - function _ZN12rust_runtime3mem8WAString3new17h3b4e78424fef5447E($0, $1, $2) { - $0 = $0 | 0; - $1 = $1 | 0; - $2 = $2 | 0; - var $3 = 0, $4 = 0, $5 = 0; - $3 = __stack_pointer - 32 | 0; - __stack_pointer = $3; - $4 = $1 + $2 | 0; - label$1 : { - label$2 : { - if ($2 >>> 0 < 16 >>> 0) { - break label$2 - } - $2 = _ZN4core3str5count14do_count_chars17h03769f4f70ff5154E($1 | 0, $2 | 0) | 0; - break label$1; - } - $2 = _ZN4core3str5count23char_count_general_case17ha75d4189ecacd84eE($1 | 0, $2 | 0) | 0; - } - HEAP32[($3 + 24 | 0) >> 2] = $4; - HEAP32[($3 + 20 | 0) >> 2] = $1; - HEAP32[($3 + 16 | 0) >> 2] = ($3 + 30 | 0) + 2 | 0; - HEAP16[($3 + 30 | 0) >> 1] = $2; - HEAP32[($3 + 12 | 0) >> 2] = $3 + 30 | 0; - _ZN98_$LT$alloc__vec__Vec$LT$T$GT$$u20$as$u20$alloc__vec__spec_from_iter__SpecFromIter$LT$T$C$I$GT$$GT$9from_iter17hace63ed3f33297cdE($3 | 0, $3 + 12 | 0 | 0); - $5 = HEAP32[($3 + 4 | 0) >> 2] | 0; - $4 = HEAP32[($3 + 8 | 0) >> 2] | 0; - $1 = _ZN12rust_runtime3mem6WACell8new_data17h26cb5cb718c9ee73E(1 | 0, $5 | 0, $4 | 0) | 0; - HEAPU8[(0 + 1051325 | 0) >> 0] | 0; - label$3 : { - $2 = __rust_alloc(12 | 0, 1 | 0) | 0; - if (!$2) { - break label$3 - } - HEAP8[($2 + 8 | 0) >> 0] = $4; - HEAP8[($2 + 9 | 0) >> 0] = $4 >>> 8 | 0; - HEAP8[($2 + 10 | 0) >> 0] = $4 >>> 16 | 0; - HEAP8[($2 + 11 | 0) >> 0] = $4 >>> 24 | 0; - HEAP8[($2 + 4 | 0) >> 0] = $1; - HEAP8[($2 + 5 | 0) >> 0] = $1 >>> 8 | 0; - HEAP8[($2 + 6 | 0) >> 0] = $1 >>> 16 | 0; - HEAP8[($2 + 7 | 0) >> 0] = $1 >>> 24 | 0; - HEAP8[$2 >> 0] = $1; - HEAP8[($2 + 1 | 0) >> 0] = $1 >>> 8 | 0; - HEAP8[($2 + 2 | 0) >> 0] = $1 >>> 16 | 0; - HEAP8[($2 + 3 | 0) >> 0] = $1 >>> 24 | 0; - $4 = _ZN12rust_runtime3mem6WACell8new_data17h26cb5cb718c9ee73E(2 | 0, $2 | 0, 12 | 0) | 0; - __rust_dealloc($2 | 0, 12 | 0, 1 | 0); - label$4 : { - $2 = HEAP32[$3 >> 2] | 0; - if (!$2) { - break label$4 - } - __rust_dealloc($5 | 0, $2 | 0, 1 | 0); - } - HEAP32[($0 + 4 | 0) >> 2] = $1; - HEAP32[$0 >> 2] = $4; - __stack_pointer = $3 + 32 | 0; - return; - } - _ZN5alloc7raw_vec12handle_error17h7f22430f64ae98acE(1 | 0, 12 | 0); - wasm2js_trap(); - } - - function _ZN12rust_runtime3mem7log_str17hac61e78d5ba71dcfE($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - var $2 = 0, $4 = 0, $10 = 0, $5 = 0, $7 = 0, $9 = 0, $6 = 0, $3 = 0, $8 = 0; - $2 = __stack_pointer - 32 | 0; - __stack_pointer = $2; - _ZN12rust_runtime3mem8WAString3new17h3b4e78424fef5447E($2 | 0, $0 | 0, $1 | 0); - $3 = HEAP32[($2 + 4 | 0) >> 2] | 0; - $4 = HEAP32[$2 >> 2] | 0; - _ZN12rust_runtime3mem3log17hfd3cd80676177765E($4 | 0); - label$1 : { - $5 = HEAP32[(0 + 1051808 | 0) >> 2] | 0; - if (!$5) { - break label$1 - } - $6 = HEAP32[(0 + 1051812 | 0) >> 2] | 0; - label$2 : { - label$3 : while (1) { - $7 = $5 + 44 | 0; - $0 = $5 + 4 | 0; - $8 = HEAPU16[($5 + 182 | 0) >> 1] | 0; - $1 = $8 << 2 | 0; - $9 = -1; - label$4 : { - label$5 : { - label$6 : while (1) { - label$7 : { - if ($1) { - break label$7 - } - $9 = $8; - break label$5; - } - $10 = HEAP32[$0 >> 2] | 0; - $9 = $9 + 1 | 0; - $7 = $7 + 12 | 0; - $1 = $1 + -4 | 0; - $0 = $0 + 4 | 0; - $10 = $10 >>> 0 > $4 >>> 0 ? -1 : ($10 | 0) != ($4 | 0); - if (($10 | 0) == (1 | 0)) { - continue label$6 - } - break label$6; - }; - if (!($10 & 255 | 0)) { - break label$4 - } - } - if (!$6) { - break label$2 - } - $6 = $6 + -1 | 0; - $5 = HEAP32[(($5 + ($9 << 2 | 0) | 0) + 184 | 0) >> 2] | 0; - continue label$3; - } - break label$3; - }; - label$8 : { - $1 = HEAP32[$7 >> 2] | 0; - if ($1 >>> 0 > 1 >>> 0) { - break label$8 - } - HEAP32[($2 + 12 | 0) >> 2] = $4; - _ZN5alloc11collections5btree3map25BTreeMap$LT$K$C$V$C$A$GT$6remove17hc793cbb765ab111dE($2 + 16 | 0 | 0, 1051808 | 0, $2 + 12 | 0 | 0); - if (!(HEAP32[($2 + 16 | 0) >> 2] | 0)) { - break label$2 - } - __rust_dealloc(HEAP32[($2 + 24 | 0) >> 2] | 0 | 0, HEAP32[($2 + 20 | 0) >> 2] | 0 | 0, 1 | 0); - break label$2; - } - HEAP32[$7 >> 2] = $1 + -1 | 0; - } - $4 = HEAP32[(0 + 1051808 | 0) >> 2] | 0; - if (!$4) { - break label$1 - } - $5 = HEAP32[(0 + 1051812 | 0) >> 2] | 0; - label$9 : while (1) { - $7 = $4 + 44 | 0; - $0 = $4 + 4 | 0; - $6 = HEAPU16[($4 + 182 | 0) >> 1] | 0; - $1 = $6 << 2 | 0; - $9 = -1; - label$10 : { - label$11 : { - label$12 : while (1) { - label$13 : { - if ($1) { - break label$13 - } - $9 = $6; - break label$11; - } - $10 = HEAP32[$0 >> 2] | 0; - $9 = $9 + 1 | 0; - $7 = $7 + 12 | 0; - $1 = $1 + -4 | 0; - $0 = $0 + 4 | 0; - $10 = $10 >>> 0 > $3 >>> 0 ? -1 : ($10 | 0) != ($3 | 0); - if (($10 | 0) == (1 | 0)) { - continue label$12 - } - break label$12; - }; - if (!($10 & 255 | 0)) { - break label$10 - } - } - if (!$5) { - break label$1 - } - $5 = $5 + -1 | 0; - $4 = HEAP32[(($4 + ($9 << 2 | 0) | 0) + 184 | 0) >> 2] | 0; - continue label$9; - } - break label$9; - }; - label$14 : { - $1 = HEAP32[$7 >> 2] | 0; - if ($1 >>> 0 > 1 >>> 0) { - break label$14 - } - HEAP32[($2 + 12 | 0) >> 2] = $3; - _ZN5alloc11collections5btree3map25BTreeMap$LT$K$C$V$C$A$GT$6remove17hc793cbb765ab111dE($2 + 16 | 0 | 0, 1051808 | 0, $2 + 12 | 0 | 0); - if (!(HEAP32[($2 + 16 | 0) >> 2] | 0)) { - break label$1 - } - __rust_dealloc(HEAP32[($2 + 24 | 0) >> 2] | 0 | 0, HEAP32[($2 + 20 | 0) >> 2] | 0 | 0, 1 | 0); - break label$1; - } - HEAP32[$7 >> 2] = $1 + -1 | 0; - } - __stack_pointer = $2 + 32 | 0; - } - - function execute($0) { - $0 = $0 | 0; - _ZN12rust_runtime3mem7log_str17hac61e78d5ba71dcfE(1051264 | 0, 11 | 0); - return $0 | 0; - } - - function setEnvironment($0) { - $0 = $0 | 0; - var $1 = 0, $2 = 0, $10 = 0, $7 = 0, $9 = 0, $6 = 0, $4 = 0, $5 = 0, i64toi32_i32$0 = 0, i64toi32_i32$1 = 0, i64toi32_i32$2 = 0, $3 = 0, $8 = 0, i64toi32_i32$4 = 0, i64toi32_i32$3 = 0, $20 = 0, $80 = 0, $82$hi = 0, $85$hi = 0, $86 = 0; - $1 = __stack_pointer - 64 | 0; - __stack_pointer = $1; - _ZN12rust_runtime3mem7WAArray8from_ref17hc48303b07ff6a176E($1 | 0, $0 | 0); - label$1 : { - label$2 : { - $2 = HEAP32[(0 + 1051808 | 0) >> 2] | 0; - if (!$2) { - break label$2 - } - $3 = HEAP32[($1 + 4 | 0) >> 2] | 0; - $4 = HEAP32[$1 >> 2] | 0; - $5 = HEAP32[(0 + 1051812 | 0) >> 2] | 0; - label$3 : while (1) { - $6 = $2 + 36 | 0; - $7 = $2 + 4 | 0; - $8 = HEAPU16[($2 + 182 | 0) >> 1] | 0; - $0 = $8 << 2 | 0; - $9 = -1; - label$4 : { - label$5 : while (1) { - label$6 : { - if ($0) { - break label$6 - } - $9 = $8; - break label$4; - } - $10 = HEAP32[$7 >> 2] | 0; - $9 = $9 + 1 | 0; - $6 = $6 + 12 | 0; - $0 = $0 + -4 | 0; - $7 = $7 + 4 | 0; - $10 = $10 >>> 0 > $3 >>> 0 ? -1 : ($10 | 0) != ($3 | 0); - if (($10 | 0) == (1 | 0)) { - continue label$5 - } - break label$5; - }; - if (!($10 & 255 | 0)) { - break label$1 - } - } - if (!$5) { - break label$2 - } - $5 = $5 + -1 | 0; - $2 = HEAP32[(($2 + ($9 << 2 | 0) | 0) + 184 | 0) >> 2] | 0; - continue label$3; - }; - } - HEAP32[($1 + 56 | 0) >> 2] = 0; - HEAP32[($1 + 44 | 0) >> 2] = 1; - HEAP32[($1 + 40 | 0) >> 2] = 1051224; - i64toi32_i32$1 = $1; - i64toi32_i32$0 = 0; - HEAP32[($1 + 48 | 0) >> 2] = 4; - HEAP32[($1 + 52 | 0) >> 2] = i64toi32_i32$0; - _ZN4core9panicking9panic_fmt17hb2f16849466f57b6E($1 + 40 | 0 | 0, 1051232 | 0); - wasm2js_trap(); - } - HEAP32[($1 + 36 | 0) >> 2] = HEAP32[$6 >> 2] | 0; - HEAP32[($1 + 32 | 0) >> 2] = $3; - HEAP32[($1 + 44 | 0) >> 2] = 1; - HEAP32[($1 + 40 | 0) >> 2] = 1051292; - i64toi32_i32$1 = $1; - i64toi32_i32$0 = 0; - HEAP32[($1 + 52 | 0) >> 2] = 1; - HEAP32[($1 + 56 | 0) >> 2] = i64toi32_i32$0; - $80 = $1; - i64toi32_i32$0 = 0; - i64toi32_i32$2 = 28; - i64toi32_i32$1 = 0; - i64toi32_i32$3 = 32; - i64toi32_i32$4 = i64toi32_i32$3 & 31 | 0; - if (32 >>> 0 <= (i64toi32_i32$3 & 63 | 0) >>> 0) { - i64toi32_i32$1 = i64toi32_i32$2 << i64toi32_i32$4 | 0; - $20 = 0; - } else { - i64toi32_i32$1 = ((1 << i64toi32_i32$4 | 0) - 1 | 0) & (i64toi32_i32$2 >>> (32 - i64toi32_i32$4 | 0) | 0) | 0 | (i64toi32_i32$0 << i64toi32_i32$4 | 0) | 0; - $20 = i64toi32_i32$2 << i64toi32_i32$4 | 0; - } - $82$hi = i64toi32_i32$1; - i64toi32_i32$1 = 0; - $85$hi = i64toi32_i32$1; - i64toi32_i32$1 = $82$hi; - i64toi32_i32$0 = $20; - i64toi32_i32$2 = $85$hi; - i64toi32_i32$3 = $1 + 32 | 0; - i64toi32_i32$2 = i64toi32_i32$1 | i64toi32_i32$2 | 0; - $86 = i64toi32_i32$0 | i64toi32_i32$3 | 0; - i64toi32_i32$0 = $80; - HEAP32[(i64toi32_i32$0 + 24 | 0) >> 2] = $86; - HEAP32[(i64toi32_i32$0 + 28 | 0) >> 2] = i64toi32_i32$2; - HEAP32[($1 + 48 | 0) >> 2] = $1 + 24 | 0; - _ZN5alloc3fmt6format12format_inner17hfada08777d0a48e9E($1 + 12 | 0 | 0, $1 + 40 | 0 | 0); - $0 = HEAP32[($1 + 16 | 0) >> 2] | 0; - _ZN12rust_runtime3mem7log_str17hac61e78d5ba71dcfE($0 | 0, HEAP32[($1 + 20 | 0) >> 2] | 0 | 0); - label$7 : { - $7 = HEAP32[($1 + 12 | 0) >> 2] | 0; - if (!$7) { - break label$7 - } - __rust_dealloc($0 | 0, $7 | 0, 1 | 0); - } - label$8 : { - $2 = HEAP32[(0 + 1051808 | 0) >> 2] | 0; - if (!$2) { - break label$8 - } - $5 = HEAP32[(0 + 1051812 | 0) >> 2] | 0; - label$9 : { - label$10 : while (1) { - $6 = $2 + 44 | 0; - $7 = $2 + 4 | 0; - $8 = HEAPU16[($2 + 182 | 0) >> 1] | 0; - $0 = $8 << 2 | 0; - $9 = -1; - label$11 : { - label$12 : { - label$13 : while (1) { - label$14 : { - if ($0) { - break label$14 - } - $9 = $8; - break label$12; - } - $10 = HEAP32[$7 >> 2] | 0; - $9 = $9 + 1 | 0; - $6 = $6 + 12 | 0; - $0 = $0 + -4 | 0; - $7 = $7 + 4 | 0; - $10 = $10 >>> 0 > $4 >>> 0 ? -1 : ($10 | 0) != ($4 | 0); - if (($10 | 0) == (1 | 0)) { - continue label$13 - } - break label$13; - }; - if (!($10 & 255 | 0)) { - break label$11 - } - } - if (!$5) { - break label$9 - } - $5 = $5 + -1 | 0; - $2 = HEAP32[(($2 + ($9 << 2 | 0) | 0) + 184 | 0) >> 2] | 0; - continue label$10; - } - break label$10; - }; - label$15 : { - $0 = HEAP32[$6 >> 2] | 0; - if ($0 >>> 0 > 1 >>> 0) { - break label$15 - } - HEAP32[($1 + 12 | 0) >> 2] = $4; - _ZN5alloc11collections5btree3map25BTreeMap$LT$K$C$V$C$A$GT$6remove17hc793cbb765ab111dE($1 + 40 | 0 | 0, 1051808 | 0, $1 + 12 | 0 | 0); - if (!(HEAP32[($1 + 40 | 0) >> 2] | 0)) { - break label$9 - } - __rust_dealloc(HEAP32[($1 + 48 | 0) >> 2] | 0 | 0, HEAP32[($1 + 44 | 0) >> 2] | 0 | 0, 1 | 0); - break label$9; - } - HEAP32[$6 >> 2] = $0 + -1 | 0; - } - $4 = HEAP32[(0 + 1051808 | 0) >> 2] | 0; - if (!$4) { - break label$8 - } - $2 = HEAP32[(0 + 1051812 | 0) >> 2] | 0; - label$16 : while (1) { - $6 = $4 + 44 | 0; - $7 = $4 + 4 | 0; - $5 = HEAPU16[($4 + 182 | 0) >> 1] | 0; - $0 = $5 << 2 | 0; - $9 = -1; - label$17 : { - label$18 : { - label$19 : while (1) { - label$20 : { - if ($0) { - break label$20 - } - $9 = $5; - break label$18; - } - $10 = HEAP32[$7 >> 2] | 0; - $9 = $9 + 1 | 0; - $6 = $6 + 12 | 0; - $0 = $0 + -4 | 0; - $7 = $7 + 4 | 0; - $10 = $10 >>> 0 > $3 >>> 0 ? -1 : ($10 | 0) != ($3 | 0); - if (($10 | 0) == (1 | 0)) { - continue label$19 - } - break label$19; - }; - if (!($10 & 255 | 0)) { - break label$17 - } - } - if (!$2) { - break label$8 - } - $2 = $2 + -1 | 0; - $4 = HEAP32[(($4 + ($9 << 2 | 0) | 0) + 184 | 0) >> 2] | 0; - continue label$16; - } - break label$16; - }; - label$21 : { - $0 = HEAP32[$6 >> 2] | 0; - if ($0 >>> 0 > 1 >>> 0) { - break label$21 - } - HEAP32[($1 + 12 | 0) >> 2] = $3; - _ZN5alloc11collections5btree3map25BTreeMap$LT$K$C$V$C$A$GT$6remove17hc793cbb765ab111dE($1 + 40 | 0 | 0, 1051808 | 0, $1 + 12 | 0 | 0); - if (!(HEAP32[($1 + 40 | 0) >> 2] | 0)) { - break label$8 - } - __rust_dealloc(HEAP32[($1 + 48 | 0) >> 2] | 0 | 0, HEAP32[($1 + 44 | 0) >> 2] | 0 | 0, 1 | 0); - break label$8; - } - HEAP32[$6 >> 2] = $0 + -1 | 0; - } - __stack_pointer = $1 + 64 | 0; - } - - function onDeploy($0) { - $0 = $0 | 0; - _ZN12rust_runtime3mem7log_str17hac61e78d5ba71dcfE(1051300 | 0, 13 | 0); - } - - function __new($0, $1) { - $0 = $0 | 0; - $1 = $1 | 0; - return _ZN12rust_runtime3mem6WACell8new_size17h2ed2900047365a20E($1 | 0, $0 | 0) | 0 | 0; - } - - function __unpin($0) { - $0 = $0 | 0; - var $1 = 0, $8 = 0, $3 = 0, $7 = 0, $2 = 0, $4 = 0, $6 = 0, $5 = 0; - label$1 : { - $1 = HEAP32[(0 + 1051808 | 0) >> 2] | 0; - if (!$1) { - break label$1 - } - $2 = HEAP32[(0 + 1051812 | 0) >> 2] | 0; - label$2 : while (1) { - $3 = $1 + 44 | 0; - $4 = $1 + 4 | 0; - $5 = HEAPU16[($1 + 182 | 0) >> 1] | 0; - $6 = $5 << 2 | 0; - $7 = -1; - label$3 : { - label$4 : { - label$5 : while (1) { - label$6 : { - if ($6) { - break label$6 - } - $7 = $5; - break label$4; - } - $8 = HEAP32[$4 >> 2] | 0; - $7 = $7 + 1 | 0; - $3 = $3 + 12 | 0; - $6 = $6 + -4 | 0; - $4 = $4 + 4 | 0; - $8 = $8 >>> 0 > $0 >>> 0 ? -1 : ($8 | 0) != ($0 | 0); - if (($8 | 0) == (1 | 0)) { - continue label$5 - } - break label$5; - }; - if (!($8 & 255 | 0)) { - break label$3 - } - } - if (!$2) { - break label$1 - } - $2 = $2 + -1 | 0; - $1 = HEAP32[(($1 + ($7 << 2 | 0) | 0) + 184 | 0) >> 2] | 0; - continue label$2; - } - break label$2; - }; - HEAP32[$3 >> 2] = (HEAP32[$3 >> 2] | 0) + -1 | 0; - } - _ZN12rust_runtime3mem7log_str17hac61e78d5ba71dcfE(1051313 | 0, 9 | 0); - } - - function __collect() { - - } - - function _ZN17compiler_builtins3int3mul3Mul3mul17h070e9a1c69faec5bE(var$0, var$0$hi, var$1, var$1$hi) { - var$0 = var$0 | 0; - var$0$hi = var$0$hi | 0; - var$1 = var$1 | 0; - var$1$hi = var$1$hi | 0; - var i64toi32_i32$4 = 0, i64toi32_i32$0 = 0, i64toi32_i32$1 = 0, var$2 = 0, i64toi32_i32$2 = 0, i64toi32_i32$3 = 0, var$3 = 0, var$4 = 0, var$5 = 0, $21 = 0, $22 = 0, var$6 = 0, $24 = 0, $17 = 0, $18 = 0, $23 = 0, $29 = 0, $45 = 0, $56$hi = 0, $62$hi = 0; - i64toi32_i32$0 = var$1$hi; - var$2 = var$1; - var$4 = var$2 >>> 16 | 0; - i64toi32_i32$0 = var$0$hi; - var$3 = var$0; - var$5 = var$3 >>> 16 | 0; - $17 = Math_imul(var$4, var$5); - $18 = var$2; - i64toi32_i32$2 = var$3; - i64toi32_i32$1 = 0; - i64toi32_i32$3 = 32; - i64toi32_i32$4 = i64toi32_i32$3 & 31 | 0; - if (32 >>> 0 <= (i64toi32_i32$3 & 63 | 0) >>> 0) { - i64toi32_i32$1 = 0; - $21 = i64toi32_i32$0 >>> i64toi32_i32$4 | 0; - } else { - i64toi32_i32$1 = i64toi32_i32$0 >>> i64toi32_i32$4 | 0; - $21 = (((1 << i64toi32_i32$4 | 0) - 1 | 0) & i64toi32_i32$0 | 0) << (32 - i64toi32_i32$4 | 0) | 0 | (i64toi32_i32$2 >>> i64toi32_i32$4 | 0) | 0; - } - $23 = $17 + Math_imul($18, $21) | 0; - i64toi32_i32$1 = var$1$hi; - i64toi32_i32$0 = var$1; - i64toi32_i32$2 = 0; - i64toi32_i32$3 = 32; - i64toi32_i32$4 = i64toi32_i32$3 & 31 | 0; - if (32 >>> 0 <= (i64toi32_i32$3 & 63 | 0) >>> 0) { - i64toi32_i32$2 = 0; - $22 = i64toi32_i32$1 >>> i64toi32_i32$4 | 0; - } else { - i64toi32_i32$2 = i64toi32_i32$1 >>> i64toi32_i32$4 | 0; - $22 = (((1 << i64toi32_i32$4 | 0) - 1 | 0) & i64toi32_i32$1 | 0) << (32 - i64toi32_i32$4 | 0) | 0 | (i64toi32_i32$0 >>> i64toi32_i32$4 | 0) | 0; +loadWebAssembly.supported = typeof WebAssembly !== 'undefined' + +function loadWebAssembly (opts) { + if (!loadWebAssembly.supported) return null + + var imp = opts && opts.imports + var wasm = toUint8Array('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NgIAQYiMwABB/IvAADYCAEH8i8AAQfSLwAA2AgBBoIzAACACNgIAQYSMwABB/IvAADYCAEGYjMAAIANBKGsiADYCACACIABBAXI2AgQgACACakEoNgIEQayMwABBgICAATYCAAwICyABIARJIAEgAk9yDQAgACgCDEUNAwtBsIzAAEGwjMAAKAIAIgAgAiAAIAJJGzYCACACIANqIQRB9InAACEAAkACQANAIAQgACgCACIGRwRAIAAoAggiAA0BDAILCyAAKAIMRQ0BC0H0icAAIQADQAJAIAEgACgCACIETwRAIAEgBCAAKAIEaiIGSQ0BCyAAKAIIIQAMAQsLQaCMwAAgAjYCAEGYjMAAIANBKGsiADYCACACIABBAXI2AgQgACACakEoNgIEQayMwABBgICAATYCACABIAZBIGtBeHFBCGsiACAAIAFBEGpJGyIEQRs2AgRB9InAACkCACEJIARBEGpB/InAACkCADcCACAEIAk3AghB+InAACADNgIAQfSJwAAgAjYCAEH8icAAIARBCGo2AgBBgIrAAEEANgIAIARBHGohAANAIABBBzYCACAAQQRqIgAgBkkNAAsgASAERg0HIAQgBCgCBEF+cTYCBCABIAQgAWsiAEEBcjYCBCAEIAA2AgAgAEGAAk8EQCABIAAQNwwICyAAQfgBcUGEisAAaiECAn9BjIzAACgCACIEQQEgAEEDdnQiAHFFBEBBjIzAACAAIARyNgIAIAIMAQsgAigCCAshACACIAE2AgggACABNgIMIAEgAjYCDCABIAA2AggMBwsgACACNgIAIAAgACgCBCADajYCBCACIAVBA3I2AgQgBkEPakF4cUEIayIDIAIgBWoiAGshBSADQaCMwAAoAgBGDQMgA0GcjMAAKAIARg0EIAMoAgQiAUEDcUEBRgRAIAMgAUF4cSIBEBEgASAFaiEFIAEgA2oiAygCBCEBCyADIAFBfnE2AgQgACAFQQFyNgIEIAAgBWogBTYCACAFQYACTwRAIAAgBRA3DAYLIAVB+AFxQYSKwABqIQECf0GMjMAAKAIAIgRBASAFQQN2dCIDcUUEQEGMjMAAIAMgBHI2AgAgAQwBCyABKAIICyEEIAEgADYCCCAEIAA2AgwgACABNgIMIAAgBDYCCAwFC0GYjMAAIAAgBWsiATYCAEGgjMAAQaCMwAAo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BCkCEDcCACAAQQhqIARBGGooAgA2AgALIARBIGokAA8LEAILAAsjAEFAaiIAJAAgAEHWADYCDCAAQcyAwAA2AgggAEG8gMAANgIUIAAgBEEfajYCECAAQQI2AhwgAEHIgcAANgIYIABCAjcCJCAAIABBEGqtQoCAgIAghDcDOCAAIABBCGqtQoCAgIAwhDcDMCAAIABBMGo2AiAgAEEYakG0gcAAEAMACwsAIABB/IbAABA7CwsAIABBkIfAABA7CxYAQdyIwAAgACABECdBFGoiABAyIAALbQEDfyAAKAIIIgQgACgCACIDRgRAIwBBEGsiAiQAIAJBCGogACADQQFBBEEEECIgAigCCCIDQYGAgIB4RwRAIAIoAgwaIAMQAQALIAJBEGokAAsgACAEQQFqNgIIIAAoAgQgBEECdGogATYCAAsYAQF/IABBEGsiASABKAIAQQFqNgIAIAALkgEBAn8jAEEwayIBJAAgAEEUayIAKAIEIgJBAk8EQCAAIAJBAWs2AgQLIAFBATYCECABQaSHwAA2AgwgAUIBNwIYIAFBATYCKCABQeSIwAAoAgA2AiwgASABQSRqNgIUIAEgAUEsajYCJCABIAFBDGoQLiABKAIEIgAgASgCCBAsIAEoAgAgAEEBECYgAUEwaiQAC68BAQR/IwBBEGsiACQAIABCgICAgMAANwIEIABBADYCDEHkiMAAKAIAQQJ0IQFB4IjAACgCACECA0AgAQRAAkAgAigCAEEUayIDKAIERQRAIANBFBAKDAELIABBBGogA0EUahAyCyACQQRqIQIgAUEEayEBDAELC0HciMAAKAIAQeCIwAAoAgBBBBAmQeSIwAAgAEEMaigCADYCAEHciMAAIAApAgQ3AgAgAEEQaiQACwkAIABBADYCAAu6AgEEf0EfIQIgAEIANwIQIAFB////B00EQCABQQYgAUEIdmciA2t2QQFxIANBAXRrQT5qIQILIAAgAjYCHCACQQJ0QfSIwABqIQRBASACdCIDQZCMwAAoAgBxRQRAIAQgADYCACAAIAQ2AhggACAANgIMIAAgADYCCEGQjMAAQZCMwAAoAgAgA3I2AgAPCwJAAkAgASAEKAIAIgMoAgRBeHFGBEAgAyECDAELIAFBGSACQQF2a0EAIAJBH0cbdCEFA0AgAyAFQR12QQRxakEQaiIEKAIAIgJFDQIgBUEBdCEFIAIhAyACKAIEQXhxIAFHDQALCyACKAIIIgEgADYCDCACIAA2AgggAEEANgIYIAAgAjYCDCAAIAE2AggPCyAEIAA2AgAgACADNgIYIAAgADYCDCAAIAA2AggLewECfyMAQRBrIgMkAEHwiMAAQfCIwAAoAgAiBEEBajYCAAJAIARBAEgNAAJAQbyMwAAtAABFBEBBuIzAAEG4jMAAKAIAQQFqNgIAQeyIwAAoAgBBAE4NAQwCCyADQQhqIAAgARECAAALQbyMwABBADoAACACRQ0AAAsACwwAIAAgASkCADcDAAu2AgEHfwJAIAJBEEkEQCAAIQMMAQsgAEEAIABrQQNxIgRqIQUgBARAIAAhAyABIQYDQCADIAYtAAA6AAAgBkEBaiEGIANBAWoiAyAFSQ0ACwsgBSACIARrIghBfHEiB2ohAwJAIAEgBGoiBEEDcQRAIAdBAEwNASAEQQN0IgJBGHEhCSAEQXxxIgZBBGohAUEAIAJrQRhxIQIgBigCACEGA0AgBSAGIAl2IAEoAgAiBiACdHI2AgAgAUEEaiEBIAVBBGoiBSADSQ0ACwwBCyAHQQBMDQAgBCEBA0AgBSABKAIANgIAIAFBBGohASAFQQRqIgUgA0kNAAsLIAhBA3EhAiAEIAdqIQELIAIEQCACIANqIQIDQCADIAEtAAA6AAAgAUEBaiEBIANBAWoiAyACSQ0ACwsgAAuaAQEDfyMAQUBqIgIkACACIAAQKiACKAIAIAIoAgQhACACQQE2AhwgAiABNgIYIAJBATYCJCACQQQ2AjQgAiAAQRRqNgI4IAIgACgCEDYCPCACQQA2AiggAiACQTBqNgIgIAIgAkE4ajYCMCACQQxqIAJBGGoQLiACKAIQIgQgAigCFBAsIAIoAgwgBEEBECYgABArIAJBQGskAAsL6QgDAEGAgMAACzkHAAAADAAAAAQAAAAIAAAACQAAAAoAAABhbGxvYy9zcmMvcmF3X3ZlYy5ycxgAEAAUAAAAGAAAAAUAQcSAwAALlQgBAAAACwAAAGEgZm9ybWF0dGluZyB0cmFpdCBpbXBsZW1lbnRhdGlvbiByZXR1cm5lZCBhbiBlcnJvciB3aGVuIHRoZSB1bmRlcmx5aW5nIHN0cmVhbSBkaWQgbm90YWxsb2Mvc3JjL2ZtdC5ycwAAogAQABAAAAB+AgAADgAAAFs6IAABAAAAAAAAAMUAEAACAAAAAAAAAAwAAAAEAAAADAAAAA0AAAAOAAAAICAgICwgLAoKXWNvcmUvc3JjL2ZtdC9udW0ucnMAAAD6ABAAEwAAAGYAAAAXAAAAMHgwMDAxMDIwMzA0MDUwNjA3MDgwOTEwMTExMjEzMTQxNTE2MTcxODE5MjAyMTIyMjMyNDI1MjYyNzI4MjkzMDMxMzIzMzM0MzUzNjM3MzgzOTQwNDE0MjQzNDQ0NTQ2NDc0ODQ5NTA1MTUyNTM1NDU1NTY1NzU4NTk2MDYxNjI2MzY0NjU2NjY3Njg2OTcwNzE3MjczNzQ3NTc2Nzc3ODc5ODA4MTgyODM4NDg1ODY4Nzg4ODk5MDkxOTI5Mzk0OTU5Njk3OTg5OXJhbmdlIHN0YXJ0IGluZGV4ICBvdXQgb2YgcmFuZ2UgZm9yIHNsaWNlIG9mIGxlbmd0aCAAAOoBEAASAAAA/AEQACIAAAByYW5nZSBlbmQgaW5kZXggMAIQABAAAAD8ARAAIgAAAGNhcGFjaXR5IG92ZXJmbG93AAAAUAIQABEAAAAvcnVzdGMvYzZkYjFjYTNjOTNhZDY5NjkyYTRjNGI1NTQyZjI2ZmRhNGJmM2FlYy9saWJyYXJ5L2FsbG9jL3NyYy92ZWMvc3BlY19mcm9tX2l0ZXJfbmVzdGVkLnJzAABsAhAAXgAAADkAAAASAAAAL3J1c3RjL2M2ZGIxY2EzYzkzYWQ2OTY5MmE0YzRiNTU0MmYyNmZkYTRiZjNhZWMvbGlicmFyeS9hbGxvYy9zcmMvdmVjL21vZC5yc9wCEABMAAAAPwwAAA0AAABzcmNcbWVtLnJzAAA4AxAACgAAAB4AAAAXAAAARXhlY3V0ZTogAAAAVAMQAAkAAABTZXQgZW52aXJvbm1lbnQ6IAAAAGgDEAARAAAAT24gZGVwbG95OiAAhAMQAAsAAABNZW0gc2l6ZTogAACYAxAACgAAAC9ydXN0L2RlcHMvZGxtYWxsb2MtMC4yLjYvc3JjL2RsbWFsbG9jLnJzYXNzZXJ0aW9uIGZhaWxlZDogcHNpemUgPj0gc2l6ZSArIG1pbl9vdmVyaGVhZACsAxAAKQAAAKgEAAAJAAAAYXNzZXJ0aW9uIGZhaWxlZDogcHNpemUgPD0gc2l6ZSArIG1heF9vdmVyaGVhZAAArAMQACkAAACuBAAADQAAAEVycm9yAEHgiMAACwEEAFUJcHJvZHVjZXJzAghsYW5ndWFnZQEEUnVzdAAMcHJvY2Vzc2VkLWJ5AQVydXN0YyUxLjgyLjAtbmlnaHRseSAoYzZkYjFjYTNjIDIwMjQtMDgtMjUpAEkPdGFyZ2V0X2ZlYXR1cmVzBCsPbXV0YWJsZS1nbG9iYWxzKwhzaWduLWV4dCsPcmVmZXJlbmNlLXR5cGVzKwptdWx0aXZhbHVl') + var ready = null + + var mod = { + buffer: wasm, + memory: null, + exports: null, + realloc: realloc, + onload: onload } - $29 = $23 + Math_imul($22, var$3) | 0; - var$2 = var$2 & 65535 | 0; - var$3 = var$3 & 65535 | 0; - var$6 = Math_imul(var$2, var$3); - var$2 = (var$6 >>> 16 | 0) + Math_imul(var$2, var$5) | 0; - $45 = $29 + (var$2 >>> 16 | 0) | 0; - var$2 = (var$2 & 65535 | 0) + Math_imul(var$4, var$3) | 0; - i64toi32_i32$2 = 0; - i64toi32_i32$1 = $45 + (var$2 >>> 16 | 0) | 0; - i64toi32_i32$0 = 0; - i64toi32_i32$3 = 32; - i64toi32_i32$4 = i64toi32_i32$3 & 31 | 0; - if (32 >>> 0 <= (i64toi32_i32$3 & 63 | 0) >>> 0) { - i64toi32_i32$0 = i64toi32_i32$1 << i64toi32_i32$4 | 0; - $24 = 0; - } else { - i64toi32_i32$0 = ((1 << i64toi32_i32$4 | 0) - 1 | 0) & (i64toi32_i32$1 >>> (32 - i64toi32_i32$4 | 0) | 0) | 0 | (i64toi32_i32$2 << i64toi32_i32$4 | 0) | 0; - $24 = i64toi32_i32$1 << i64toi32_i32$4 | 0; + + onload(function () {}) + + return mod + + function realloc (size) { + mod.exports.memory.grow(Math.max(0, Math.ceil(Math.abs(size - mod.memory.length) / 65536))) + mod.memory = new Uint8Array(mod.exports.memory.buffer) } - $56$hi = i64toi32_i32$0; - i64toi32_i32$0 = 0; - $62$hi = i64toi32_i32$0; - i64toi32_i32$0 = $56$hi; - i64toi32_i32$2 = $24; - i64toi32_i32$1 = $62$hi; - i64toi32_i32$3 = var$2 << 16 | 0 | (var$6 & 65535 | 0) | 0; - i64toi32_i32$1 = i64toi32_i32$0 | i64toi32_i32$1 | 0; - i64toi32_i32$2 = i64toi32_i32$2 | i64toi32_i32$3 | 0; - i64toi32_i32$HIGH_BITS = i64toi32_i32$1; - return i64toi32_i32$2 | 0; - } - - function _ZN17compiler_builtins3int4udiv10divmod_u6417h6026910b5ed08e40E(var$0, var$0$hi, var$1, var$1$hi) { - var$0 = var$0 | 0; - var$0$hi = var$0$hi | 0; - var$1 = var$1 | 0; - var$1$hi = var$1$hi | 0; - var i64toi32_i32$2 = 0, i64toi32_i32$3 = 0, i64toi32_i32$4 = 0, i64toi32_i32$1 = 0, i64toi32_i32$0 = 0, i64toi32_i32$5 = 0, var$2 = 0, var$3 = 0, var$4 = 0, var$5 = 0, var$5$hi = 0, var$6 = 0, var$6$hi = 0, i64toi32_i32$6 = 0, $37 = 0, $38 = 0, $39 = 0, $40 = 0, $41 = 0, $42 = 0, $43 = 0, $44 = 0, var$8$hi = 0, $45 = 0, $46 = 0, $47 = 0, $48 = 0, var$7$hi = 0, $49 = 0, $63$hi = 0, $65 = 0, $65$hi = 0, $120$hi = 0, $129$hi = 0, $134$hi = 0, var$8 = 0, $140 = 0, $140$hi = 0, $142$hi = 0, $144 = 0, $144$hi = 0, $151 = 0, $151$hi = 0, $154$hi = 0, var$7 = 0, $165$hi = 0; - label$1 : { - label$2 : { - label$3 : { - label$4 : { - label$5 : { - label$6 : { - label$7 : { - label$8 : { - label$9 : { - label$10 : { - label$11 : { - i64toi32_i32$0 = var$0$hi; - i64toi32_i32$2 = var$0; - i64toi32_i32$1 = 0; - i64toi32_i32$3 = 32; - i64toi32_i32$4 = i64toi32_i32$3 & 31 | 0; - if (32 >>> 0 <= (i64toi32_i32$3 & 63 | 0) >>> 0) { - i64toi32_i32$1 = 0; - $37 = i64toi32_i32$0 >>> i64toi32_i32$4 | 0; - } else { - i64toi32_i32$1 = i64toi32_i32$0 >>> i64toi32_i32$4 | 0; - $37 = (((1 << i64toi32_i32$4 | 0) - 1 | 0) & i64toi32_i32$0 | 0) << (32 - i64toi32_i32$4 | 0) | 0 | (i64toi32_i32$2 >>> i64toi32_i32$4 | 0) | 0; - } - var$2 = $37; - if (var$2) { - i64toi32_i32$1 = var$1$hi; - var$3 = var$1; - if (!var$3) { - break label$11 - } - i64toi32_i32$0 = var$3; - i64toi32_i32$2 = 0; - i64toi32_i32$3 = 32; - i64toi32_i32$4 = i64toi32_i32$3 & 31 | 0; - if (32 >>> 0 <= (i64toi32_i32$3 & 63 | 0) >>> 0) { - i64toi32_i32$2 = 0; - $38 = i64toi32_i32$1 >>> i64toi32_i32$4 | 0; - } else { - i64toi32_i32$2 = i64toi32_i32$1 >>> i64toi32_i32$4 | 0; - $38 = (((1 << i64toi32_i32$4 | 0) - 1 | 0) & i64toi32_i32$1 | 0) << (32 - i64toi32_i32$4 | 0) | 0 | (i64toi32_i32$0 >>> i64toi32_i32$4 | 0) | 0; - } - var$4 = $38; - if (!var$4) { - break label$9 - } - var$2 = Math_clz32(var$4) - Math_clz32(var$2) | 0; - if (var$2 >>> 0 <= 31 >>> 0) { - break label$8 - } - break label$2; - } - i64toi32_i32$2 = var$1$hi; - i64toi32_i32$1 = var$1; - i64toi32_i32$0 = 1; - i64toi32_i32$3 = 0; - if (i64toi32_i32$2 >>> 0 > i64toi32_i32$0 >>> 0 | ((i64toi32_i32$2 | 0) == (i64toi32_i32$0 | 0) & i64toi32_i32$1 >>> 0 >= i64toi32_i32$3 >>> 0 | 0) | 0) { - break label$2 - } - i64toi32_i32$1 = var$0$hi; - var$2 = var$0; - i64toi32_i32$1 = i64toi32_i32$2; - i64toi32_i32$1 = i64toi32_i32$2; - var$3 = var$1; - var$2 = (var$2 >>> 0) / (var$3 >>> 0) | 0; - i64toi32_i32$1 = 0; - __wasm_intrinsics_temp_i64 = var$0 - Math_imul(var$2, var$3) | 0; - __wasm_intrinsics_temp_i64$hi = i64toi32_i32$1; - i64toi32_i32$1 = 0; - i64toi32_i32$2 = var$2; - i64toi32_i32$HIGH_BITS = i64toi32_i32$1; - return i64toi32_i32$2 | 0; - } - i64toi32_i32$2 = var$1$hi; - i64toi32_i32$3 = var$1; - i64toi32_i32$1 = 0; - i64toi32_i32$0 = 32; - i64toi32_i32$4 = i64toi32_i32$0 & 31 | 0; - if (32 >>> 0 <= (i64toi32_i32$0 & 63 | 0) >>> 0) { - i64toi32_i32$1 = 0; - $39 = i64toi32_i32$2 >>> i64toi32_i32$4 | 0; - } else { - i64toi32_i32$1 = i64toi32_i32$2 >>> i64toi32_i32$4 | 0; - $39 = (((1 << i64toi32_i32$4 | 0) - 1 | 0) & i64toi32_i32$2 | 0) << (32 - i64toi32_i32$4 | 0) | 0 | (i64toi32_i32$3 >>> i64toi32_i32$4 | 0) | 0; - } - var$3 = $39; - i64toi32_i32$1 = var$0$hi; - if (!var$0) { - break label$7 - } - if (!var$3) { - break label$6 - } - var$4 = var$3 + -1 | 0; - if (var$4 & var$3 | 0) { - break label$6 - } - i64toi32_i32$1 = 0; - i64toi32_i32$2 = var$4 & var$2 | 0; - i64toi32_i32$3 = 0; - i64toi32_i32$0 = 32; - i64toi32_i32$4 = i64toi32_i32$0 & 31 | 0; - if (32 >>> 0 <= (i64toi32_i32$0 & 63 | 0) >>> 0) { - i64toi32_i32$3 = i64toi32_i32$2 << i64toi32_i32$4 | 0; - $40 = 0; - } else { - i64toi32_i32$3 = ((1 << i64toi32_i32$4 | 0) - 1 | 0) & (i64toi32_i32$2 >>> (32 - i64toi32_i32$4 | 0) | 0) | 0 | (i64toi32_i32$1 << i64toi32_i32$4 | 0) | 0; - $40 = i64toi32_i32$2 << i64toi32_i32$4 | 0; - } - $63$hi = i64toi32_i32$3; - i64toi32_i32$3 = var$0$hi; - i64toi32_i32$1 = var$0; - i64toi32_i32$2 = 0; - i64toi32_i32$0 = -1; - i64toi32_i32$2 = i64toi32_i32$3 & i64toi32_i32$2 | 0; - $65 = i64toi32_i32$1 & i64toi32_i32$0 | 0; - $65$hi = i64toi32_i32$2; - i64toi32_i32$2 = $63$hi; - i64toi32_i32$3 = $40; - i64toi32_i32$1 = $65$hi; - i64toi32_i32$0 = $65; - i64toi32_i32$1 = i64toi32_i32$2 | i64toi32_i32$1 | 0; - __wasm_intrinsics_temp_i64 = i64toi32_i32$3 | i64toi32_i32$0 | 0; - __wasm_intrinsics_temp_i64$hi = i64toi32_i32$1; - i64toi32_i32$1 = 0; - i64toi32_i32$3 = var$2 >>> ((__wasm_ctz_i32(var$3 | 0) | 0) & 31 | 0) | 0; - i64toi32_i32$HIGH_BITS = i64toi32_i32$1; - return i64toi32_i32$3 | 0; - } - } - var$4 = var$3 + -1 | 0; - if (!(var$4 & var$3 | 0)) { - break label$5 - } - var$2 = (Math_clz32(var$3) + 33 | 0) - Math_clz32(var$2) | 0; - var$3 = 0 - var$2 | 0; - break label$3; - } - var$3 = 63 - var$2 | 0; - var$2 = var$2 + 1 | 0; - break label$3; - } - var$4 = (var$2 >>> 0) / (var$3 >>> 0) | 0; - i64toi32_i32$3 = 0; - i64toi32_i32$2 = var$2 - Math_imul(var$4, var$3) | 0; - i64toi32_i32$1 = 0; - i64toi32_i32$0 = 32; - i64toi32_i32$4 = i64toi32_i32$0 & 31 | 0; - if (32 >>> 0 <= (i64toi32_i32$0 & 63 | 0) >>> 0) { - i64toi32_i32$1 = i64toi32_i32$2 << i64toi32_i32$4 | 0; - $41 = 0; - } else { - i64toi32_i32$1 = ((1 << i64toi32_i32$4 | 0) - 1 | 0) & (i64toi32_i32$2 >>> (32 - i64toi32_i32$4 | 0) | 0) | 0 | (i64toi32_i32$3 << i64toi32_i32$4 | 0) | 0; - $41 = i64toi32_i32$2 << i64toi32_i32$4 | 0; - } - __wasm_intrinsics_temp_i64 = $41; - __wasm_intrinsics_temp_i64$hi = i64toi32_i32$1; - i64toi32_i32$1 = 0; - i64toi32_i32$2 = var$4; - i64toi32_i32$HIGH_BITS = i64toi32_i32$1; - return i64toi32_i32$2 | 0; - } - var$2 = Math_clz32(var$3) - Math_clz32(var$2) | 0; - if (var$2 >>> 0 < 31 >>> 0) { - break label$4 - } - break label$2; - } - i64toi32_i32$2 = var$0$hi; - i64toi32_i32$2 = 0; - __wasm_intrinsics_temp_i64 = var$4 & var$0 | 0; - __wasm_intrinsics_temp_i64$hi = i64toi32_i32$2; - if ((var$3 | 0) == (1 | 0)) { - break label$1 - } - i64toi32_i32$2 = var$0$hi; - i64toi32_i32$2 = 0; - $120$hi = i64toi32_i32$2; - i64toi32_i32$2 = var$0$hi; - i64toi32_i32$3 = var$0; - i64toi32_i32$1 = $120$hi; - i64toi32_i32$0 = __wasm_ctz_i32(var$3 | 0) | 0; - i64toi32_i32$4 = i64toi32_i32$0 & 31 | 0; - if (32 >>> 0 <= (i64toi32_i32$0 & 63 | 0) >>> 0) { - i64toi32_i32$1 = 0; - $42 = i64toi32_i32$2 >>> i64toi32_i32$4 | 0; - } else { - i64toi32_i32$1 = i64toi32_i32$2 >>> i64toi32_i32$4 | 0; - $42 = (((1 << i64toi32_i32$4 | 0) - 1 | 0) & i64toi32_i32$2 | 0) << (32 - i64toi32_i32$4 | 0) | 0 | (i64toi32_i32$3 >>> i64toi32_i32$4 | 0) | 0; - } - i64toi32_i32$3 = $42; - i64toi32_i32$HIGH_BITS = i64toi32_i32$1; - return i64toi32_i32$3 | 0; - } - var$3 = 63 - var$2 | 0; - var$2 = var$2 + 1 | 0; - } - i64toi32_i32$3 = var$0$hi; - i64toi32_i32$3 = 0; - $129$hi = i64toi32_i32$3; - i64toi32_i32$3 = var$0$hi; - i64toi32_i32$2 = var$0; - i64toi32_i32$1 = $129$hi; - i64toi32_i32$0 = var$2 & 63 | 0; - i64toi32_i32$4 = i64toi32_i32$0 & 31 | 0; - if (32 >>> 0 <= (i64toi32_i32$0 & 63 | 0) >>> 0) { - i64toi32_i32$1 = 0; - $43 = i64toi32_i32$3 >>> i64toi32_i32$4 | 0; - } else { - i64toi32_i32$1 = i64toi32_i32$3 >>> i64toi32_i32$4 | 0; - $43 = (((1 << i64toi32_i32$4 | 0) - 1 | 0) & i64toi32_i32$3 | 0) << (32 - i64toi32_i32$4 | 0) | 0 | (i64toi32_i32$2 >>> i64toi32_i32$4 | 0) | 0; - } - var$5 = $43; - var$5$hi = i64toi32_i32$1; - i64toi32_i32$1 = var$0$hi; - i64toi32_i32$1 = 0; - $134$hi = i64toi32_i32$1; - i64toi32_i32$1 = var$0$hi; - i64toi32_i32$3 = var$0; - i64toi32_i32$2 = $134$hi; - i64toi32_i32$0 = var$3 & 63 | 0; - i64toi32_i32$4 = i64toi32_i32$0 & 31 | 0; - if (32 >>> 0 <= (i64toi32_i32$0 & 63 | 0) >>> 0) { - i64toi32_i32$2 = i64toi32_i32$3 << i64toi32_i32$4 | 0; - $44 = 0; - } else { - i64toi32_i32$2 = ((1 << i64toi32_i32$4 | 0) - 1 | 0) & (i64toi32_i32$3 >>> (32 - i64toi32_i32$4 | 0) | 0) | 0 | (i64toi32_i32$1 << i64toi32_i32$4 | 0) | 0; - $44 = i64toi32_i32$3 << i64toi32_i32$4 | 0; - } - var$0 = $44; - var$0$hi = i64toi32_i32$2; - label$13 : { - if (var$2) { - i64toi32_i32$2 = var$1$hi; - i64toi32_i32$1 = var$1; - i64toi32_i32$3 = -1; - i64toi32_i32$0 = -1; - i64toi32_i32$4 = i64toi32_i32$1 + i64toi32_i32$0 | 0; - i64toi32_i32$5 = i64toi32_i32$2 + i64toi32_i32$3 | 0; - if (i64toi32_i32$4 >>> 0 < i64toi32_i32$0 >>> 0) { - i64toi32_i32$5 = i64toi32_i32$5 + 1 | 0 - } - var$8 = i64toi32_i32$4; - var$8$hi = i64toi32_i32$5; - label$15 : while (1) { - i64toi32_i32$5 = var$5$hi; - i64toi32_i32$2 = var$5; - i64toi32_i32$1 = 0; - i64toi32_i32$0 = 1; - i64toi32_i32$3 = i64toi32_i32$0 & 31 | 0; - if (32 >>> 0 <= (i64toi32_i32$0 & 63 | 0) >>> 0) { - i64toi32_i32$1 = i64toi32_i32$2 << i64toi32_i32$3 | 0; - $45 = 0; - } else { - i64toi32_i32$1 = ((1 << i64toi32_i32$3 | 0) - 1 | 0) & (i64toi32_i32$2 >>> (32 - i64toi32_i32$3 | 0) | 0) | 0 | (i64toi32_i32$5 << i64toi32_i32$3 | 0) | 0; - $45 = i64toi32_i32$2 << i64toi32_i32$3 | 0; - } - $140 = $45; - $140$hi = i64toi32_i32$1; - i64toi32_i32$1 = var$0$hi; - i64toi32_i32$5 = var$0; - i64toi32_i32$2 = 0; - i64toi32_i32$0 = 63; - i64toi32_i32$3 = i64toi32_i32$0 & 31 | 0; - if (32 >>> 0 <= (i64toi32_i32$0 & 63 | 0) >>> 0) { - i64toi32_i32$2 = 0; - $46 = i64toi32_i32$1 >>> i64toi32_i32$3 | 0; - } else { - i64toi32_i32$2 = i64toi32_i32$1 >>> i64toi32_i32$3 | 0; - $46 = (((1 << i64toi32_i32$3 | 0) - 1 | 0) & i64toi32_i32$1 | 0) << (32 - i64toi32_i32$3 | 0) | 0 | (i64toi32_i32$5 >>> i64toi32_i32$3 | 0) | 0; - } - $142$hi = i64toi32_i32$2; - i64toi32_i32$2 = $140$hi; - i64toi32_i32$1 = $140; - i64toi32_i32$5 = $142$hi; - i64toi32_i32$0 = $46; - i64toi32_i32$5 = i64toi32_i32$2 | i64toi32_i32$5 | 0; - var$5 = i64toi32_i32$1 | i64toi32_i32$0 | 0; - var$5$hi = i64toi32_i32$5; - $144 = var$5; - $144$hi = i64toi32_i32$5; - i64toi32_i32$5 = var$8$hi; - i64toi32_i32$5 = var$5$hi; - i64toi32_i32$5 = var$8$hi; - i64toi32_i32$2 = var$8; - i64toi32_i32$1 = var$5$hi; - i64toi32_i32$0 = var$5; - i64toi32_i32$3 = i64toi32_i32$2 - i64toi32_i32$0 | 0; - i64toi32_i32$6 = i64toi32_i32$2 >>> 0 < i64toi32_i32$0 >>> 0; - i64toi32_i32$4 = i64toi32_i32$6 + i64toi32_i32$1 | 0; - i64toi32_i32$4 = i64toi32_i32$5 - i64toi32_i32$4 | 0; - i64toi32_i32$5 = i64toi32_i32$3; - i64toi32_i32$2 = 0; - i64toi32_i32$0 = 63; - i64toi32_i32$1 = i64toi32_i32$0 & 31 | 0; - if (32 >>> 0 <= (i64toi32_i32$0 & 63 | 0) >>> 0) { - i64toi32_i32$2 = i64toi32_i32$4 >> 31 | 0; - $47 = i64toi32_i32$4 >> i64toi32_i32$1 | 0; - } else { - i64toi32_i32$2 = i64toi32_i32$4 >> i64toi32_i32$1 | 0; - $47 = (((1 << i64toi32_i32$1 | 0) - 1 | 0) & i64toi32_i32$4 | 0) << (32 - i64toi32_i32$1 | 0) | 0 | (i64toi32_i32$5 >>> i64toi32_i32$1 | 0) | 0; - } - var$6 = $47; - var$6$hi = i64toi32_i32$2; - i64toi32_i32$2 = var$1$hi; - i64toi32_i32$2 = var$6$hi; - i64toi32_i32$4 = var$6; - i64toi32_i32$5 = var$1$hi; - i64toi32_i32$0 = var$1; - i64toi32_i32$5 = i64toi32_i32$2 & i64toi32_i32$5 | 0; - $151 = i64toi32_i32$4 & i64toi32_i32$0 | 0; - $151$hi = i64toi32_i32$5; - i64toi32_i32$5 = $144$hi; - i64toi32_i32$2 = $144; - i64toi32_i32$4 = $151$hi; - i64toi32_i32$0 = $151; - i64toi32_i32$1 = i64toi32_i32$2 - i64toi32_i32$0 | 0; - i64toi32_i32$6 = i64toi32_i32$2 >>> 0 < i64toi32_i32$0 >>> 0; - i64toi32_i32$3 = i64toi32_i32$6 + i64toi32_i32$4 | 0; - i64toi32_i32$3 = i64toi32_i32$5 - i64toi32_i32$3 | 0; - var$5 = i64toi32_i32$1; - var$5$hi = i64toi32_i32$3; - i64toi32_i32$3 = var$0$hi; - i64toi32_i32$5 = var$0; - i64toi32_i32$2 = 0; - i64toi32_i32$0 = 1; - i64toi32_i32$4 = i64toi32_i32$0 & 31 | 0; - if (32 >>> 0 <= (i64toi32_i32$0 & 63 | 0) >>> 0) { - i64toi32_i32$2 = i64toi32_i32$5 << i64toi32_i32$4 | 0; - $48 = 0; - } else { - i64toi32_i32$2 = ((1 << i64toi32_i32$4 | 0) - 1 | 0) & (i64toi32_i32$5 >>> (32 - i64toi32_i32$4 | 0) | 0) | 0 | (i64toi32_i32$3 << i64toi32_i32$4 | 0) | 0; - $48 = i64toi32_i32$5 << i64toi32_i32$4 | 0; - } - $154$hi = i64toi32_i32$2; - i64toi32_i32$2 = var$7$hi; - i64toi32_i32$2 = $154$hi; - i64toi32_i32$3 = $48; - i64toi32_i32$5 = var$7$hi; - i64toi32_i32$0 = var$7; - i64toi32_i32$5 = i64toi32_i32$2 | i64toi32_i32$5 | 0; - var$0 = i64toi32_i32$3 | i64toi32_i32$0 | 0; - var$0$hi = i64toi32_i32$5; - i64toi32_i32$5 = var$6$hi; - i64toi32_i32$2 = var$6; - i64toi32_i32$3 = 0; - i64toi32_i32$0 = 1; - i64toi32_i32$3 = i64toi32_i32$5 & i64toi32_i32$3 | 0; - var$6 = i64toi32_i32$2 & i64toi32_i32$0 | 0; - var$6$hi = i64toi32_i32$3; - var$7 = var$6; - var$7$hi = i64toi32_i32$3; - var$2 = var$2 + -1 | 0; - if (var$2) { - continue label$15 - } - break label$15; - }; - break label$13; - } + + function onload (cb) { + if (mod.exports) return cb() + + if (ready) { + ready.then(cb.bind(null, null)).catch(cb) + return } - i64toi32_i32$3 = var$5$hi; - __wasm_intrinsics_temp_i64 = var$5; - __wasm_intrinsics_temp_i64$hi = i64toi32_i32$3; - i64toi32_i32$3 = var$0$hi; - i64toi32_i32$5 = var$0; - i64toi32_i32$2 = 0; - i64toi32_i32$0 = 1; - i64toi32_i32$4 = i64toi32_i32$0 & 31 | 0; - if (32 >>> 0 <= (i64toi32_i32$0 & 63 | 0) >>> 0) { - i64toi32_i32$2 = i64toi32_i32$5 << i64toi32_i32$4 | 0; - $49 = 0; - } else { - i64toi32_i32$2 = ((1 << i64toi32_i32$4 | 0) - 1 | 0) & (i64toi32_i32$5 >>> (32 - i64toi32_i32$4 | 0) | 0) | 0 | (i64toi32_i32$3 << i64toi32_i32$4 | 0) | 0; - $49 = i64toi32_i32$5 << i64toi32_i32$4 | 0; + + try { + if (opts && opts.async) throw new Error('async') + setup({instance: new WebAssembly.Instance(new WebAssembly.Module(wasm), imp)}) + } catch (err) { + ready = WebAssembly.instantiate(wasm, imp).then(setup) } - $165$hi = i64toi32_i32$2; - i64toi32_i32$2 = var$6$hi; - i64toi32_i32$2 = $165$hi; - i64toi32_i32$3 = $49; - i64toi32_i32$5 = var$6$hi; - i64toi32_i32$0 = var$6; - i64toi32_i32$5 = i64toi32_i32$2 | i64toi32_i32$5 | 0; - i64toi32_i32$3 = i64toi32_i32$3 | i64toi32_i32$0 | 0; - i64toi32_i32$HIGH_BITS = i64toi32_i32$5; - return i64toi32_i32$3 | 0; - } - i64toi32_i32$3 = var$0$hi; - __wasm_intrinsics_temp_i64 = var$0; - __wasm_intrinsics_temp_i64$hi = i64toi32_i32$3; - i64toi32_i32$3 = 0; - var$0 = 0; - var$0$hi = i64toi32_i32$3; - } - i64toi32_i32$3 = var$0$hi; - i64toi32_i32$5 = var$0; - i64toi32_i32$HIGH_BITS = i64toi32_i32$3; - return i64toi32_i32$5 | 0; - } - - function __wasm_ctz_i32(var$0) { - var$0 = var$0 | 0; - if (var$0) { - return 31 - Math_clz32((var$0 + -1 | 0) ^ var$0 | 0) | 0 | 0 - } - return 32 | 0; - } - - function __wasm_i64_mul(var$0, var$0$hi, var$1, var$1$hi) { - var$0 = var$0 | 0; - var$0$hi = var$0$hi | 0; - var$1 = var$1 | 0; - var$1$hi = var$1$hi | 0; - var i64toi32_i32$0 = 0, i64toi32_i32$1 = 0; - i64toi32_i32$0 = var$0$hi; - i64toi32_i32$0 = var$1$hi; - i64toi32_i32$0 = var$0$hi; - i64toi32_i32$1 = var$1$hi; - i64toi32_i32$1 = _ZN17compiler_builtins3int3mul3Mul3mul17h070e9a1c69faec5bE(var$0 | 0, i64toi32_i32$0 | 0, var$1 | 0, i64toi32_i32$1 | 0) | 0; - i64toi32_i32$0 = i64toi32_i32$HIGH_BITS; - i64toi32_i32$HIGH_BITS = i64toi32_i32$0; - return i64toi32_i32$1 | 0; - } - - function __wasm_i64_udiv(var$0, var$0$hi, var$1, var$1$hi) { - var$0 = var$0 | 0; - var$0$hi = var$0$hi | 0; - var$1 = var$1 | 0; - var$1$hi = var$1$hi | 0; - var i64toi32_i32$0 = 0, i64toi32_i32$1 = 0; - i64toi32_i32$0 = var$0$hi; - i64toi32_i32$0 = var$1$hi; - i64toi32_i32$0 = var$0$hi; - i64toi32_i32$1 = var$1$hi; - i64toi32_i32$1 = _ZN17compiler_builtins3int4udiv10divmod_u6417h6026910b5ed08e40E(var$0 | 0, i64toi32_i32$0 | 0, var$1 | 0, i64toi32_i32$1 | 0) | 0; - i64toi32_i32$0 = i64toi32_i32$HIGH_BITS; - i64toi32_i32$HIGH_BITS = i64toi32_i32$0; - return i64toi32_i32$1 | 0; - } - - function __wasm_rotl_i32(var$0, var$1) { - var$0 = var$0 | 0; - var$1 = var$1 | 0; - var var$2 = 0; - var$2 = var$1 & 31 | 0; - var$1 = (0 - var$1 | 0) & 31 | 0; - return ((-1 >>> var$2 | 0) & var$0 | 0) << var$2 | 0 | (((-1 << var$1 | 0) & var$0 | 0) >>> var$1 | 0) | 0 | 0; - } - - bufferView = HEAPU8; - initActiveSegments(imports); - var FUNCTION_TABLE = [null, _ZN4core3fmt3num3imp52_$LT$impl$u20$core__fmt__Display$u20$for$u20$u32$GT$3fmt17h5732d357c58d2b36E, _ZN3std5alloc24default_alloc_error_hook17h708687752e0edcfaE, _ZN4core3ptr42drop_in_place$LT$alloc__string__String$GT$17hb5bccdeece555eeeE, _ZN58_$LT$alloc__string__String$u20$as$u20$core__fmt__Write$GT$9write_str17h9c2d3e9aafc08637E, _ZN58_$LT$alloc__string__String$u20$as$u20$core__fmt__Write$GT$10write_char17h9231f70fbd335441E, _ZN4core3fmt5Write9write_fmt17h44df5905957d3a1fE, _ZN36_$LT$T$u20$as$u20$core__any__Any$GT$7type_id17h698f49bbed3b63dfE, _ZN36_$LT$T$u20$as$u20$core__any__Any$GT$7type_id17h1116370b49193673E, _ZN92_$LT$std__panicking__begin_panic_handler__StaticStrPayload$u20$as$u20$core__fmt__Display$GT$3fmt17h7d6d1d4c62b643baE, _ZN99_$LT$std__panicking__begin_panic_handler__StaticStrPayload$u20$as$u20$core__panic__PanicPayload$GT$8take_box17hdbb807c1367ee940E, _ZN99_$LT$std__panicking__begin_panic_handler__StaticStrPayload$u20$as$u20$core__panic__PanicPayload$GT$3get17hd2f9ef478e42b077E, _ZN99_$LT$std__panicking__begin_panic_handler__StaticStrPayload$u20$as$u20$core__panic__PanicPayload$GT$6as_str17h231eb7cfbc685441E, _ZN4core3ptr77drop_in_place$LT$std__panicking__begin_panic_handler__FormatStringPayload$GT$17hec524af3f69d5a53E, _ZN95_$LT$std__panicking__begin_panic_handler__FormatStringPayload$u20$as$u20$core__fmt__Display$GT$3fmt17h778dceefa8ea4afeE, _ZN102_$LT$std__panicking__begin_panic_handler__FormatStringPayload$u20$as$u20$core__panic__PanicPayload$GT$8take_box17hfdafd7cd188838afE, _ZN102_$LT$std__panicking__begin_panic_handler__FormatStringPayload$u20$as$u20$core__panic__PanicPayload$GT$3get17h3875705a18b9af03E, _ZN4core5panic12PanicPayload6as_str17hd887f5dc9940e8f0E, _ZN4core3ptr42drop_in_place$LT$alloc__string__String$GT$17h0f9d5bab53e46359E, _ZN58_$LT$alloc__string__String$u20$as$u20$core__fmt__Write$GT$9write_str17h9c2d3e9aafc08637E_52, _ZN58_$LT$alloc__string__String$u20$as$u20$core__fmt__Write$GT$10write_char17h9231f70fbd335441E_53, _ZN4core3fmt5Write9write_fmt17h12c6d34f0ecf8d3dE, _ZN53_$LT$core__fmt__Error$u20$as$u20$core__fmt__Debug$GT$3fmt17hc7b9dec108bfb98cE, _ZN42_$LT$$RF$T$u20$as$u20$core__fmt__Debug$GT$3fmt17h02f2c499cdd866a1E, _ZN44_$LT$$RF$T$u20$as$u20$core__fmt__Display$GT$3fmt17h0e730352ba1d2064E, _ZN68_$LT$core__fmt__builders__PadAdapter$u20$as$u20$core__fmt__Write$GT$9write_str17hcef790f9881e69b1E, _ZN68_$LT$core__fmt__builders__PadAdapter$u20$as$u20$core__fmt__Write$GT$10write_char17h8982d69464cb262aE, _ZN4core3fmt5Write9write_fmt17h7b710d0d35de0c2bE, _ZN42_$LT$$RF$T$u20$as$u20$core__fmt__Debug$GT$3fmt17h48376aecd7558ddcE, _ZN42_$LT$$RF$T$u20$as$u20$core__fmt__Debug$GT$3fmt17hc2f10bc6239b2f43E]; - function __wasm_memory_size() { - return buffer.byteLength / 65536 | 0; - } - - function __wasm_memory_grow(pagesToAdd) { - pagesToAdd = pagesToAdd | 0; - var oldPages = __wasm_memory_size() | 0; - var newPages = oldPages + pagesToAdd | 0; - if ((oldPages < newPages) && (newPages < 65536)) { - var newBuffer = new ArrayBuffer(Math_imul(newPages, 65536)); - var newHEAP8 = new Int8Array(newBuffer); - newHEAP8.set(HEAP8); - HEAP8 = new Int8Array(newBuffer); - HEAP16 = new Int16Array(newBuffer); - HEAP32 = new Int32Array(newBuffer); - HEAPU8 = new Uint8Array(newBuffer); - HEAPU16 = new Uint16Array(newBuffer); - HEAPU32 = new Uint32Array(newBuffer); - HEAPF32 = new Float32Array(newBuffer); - HEAPF64 = new Float64Array(newBuffer); - buffer = newBuffer; - bufferView = HEAPU8; + + onload(cb) } - return oldPages; - } - - return { - "memory": Object.create(Object.prototype, { - "grow": { - "value": __wasm_memory_grow - }, - "buffer": { - "get": function () { - return buffer; - } - - } - }), - "execute": execute, - "setEnvironment": setEnvironment, - "onDeploy": onDeploy, - "__new": __new, - "__unpin": __unpin, - "__collect": __collect, - "__pin": _ZN12rust_runtime3mem8WABuffer8from_ref17hd15e58422a800be2E, - "__data_end": { - get value() { - return global$1; - }, - set value(_global$1) { - global$1 = _global$1; - } - }, - "__heap_base": { - get value() { - return global$2; - }, - set value(_global$2) { - global$2 = _global$2; - } + + function setup (w) { + mod.exports = w.instance.exports + mod.memory = mod.exports.memory && mod.exports.memory.buffer && new Uint8Array(mod.exports.memory.buffer) } - }; } -var retasmFunc = asmFunc({ - "env": env, -}); -export var memory = retasmFunc.memory; -export var execute = retasmFunc.execute; -export var setEnvironment = retasmFunc.setEnvironment; -export var onDeploy = retasmFunc.onDeploy; -export var __new = retasmFunc.__new; -export var __unpin = retasmFunc.__unpin; -export var __collect = retasmFunc.__collect; -export var __pin = retasmFunc.__pin; -export var __data_end = retasmFunc.__data_end; -export var __heap_base = retasmFunc.__heap_base; +function toUint8Array (s) { + if (typeof atob === 'function') return new Uint8Array(atob(s).split('').map(charCodeAt)) + return (require('buf' + 'fer').Buffer).from(s, 'base64') +} + +function charCodeAt (c) { + return c.charCodeAt(0) +} diff --git a/example/Cargo.toml b/example/Cargo.toml index ae37c1d..3393d9d 100644 --- a/example/Cargo.toml +++ b/example/Cargo.toml @@ -7,14 +7,14 @@ edition = "2021" crate-type = ["cdylib"] [profile.release] -opt-level = "z" # or "s" for size-speed balance +opt-level = "s" # or "s" for size-speed balance lto = true # Link Time Optimization for smaller binary codegen-units = 1 # Ensures code is optimized across the board panic = "abort" # Avoids including panic runtime support strip = true [dependencies] -rust_runtime = {path="../"} +rust_runtime = {path=".."} hex = "0.4.3" wasm_allocator = "0.1.1" diff --git a/rust.wasm b/rust.wasm new file mode 100644 index 0000000000000000000000000000000000000000..d7f81190c75301030d71de5c440341fda27e58be GIT binary patch literal 19101 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 literal 0 HcmV?d00001 diff --git a/src/allocator.rs b/src/allocator.rs index 95a7c3d..24ab217 100644 --- a/src/allocator.rs +++ b/src/allocator.rs @@ -1,5 +1,5 @@ use core::slice; -use std::{alloc::System, io::Write}; +use alloc::alloc::{alloc, alloc_zeroed, Layout, GlobalAlloc, dealloc, realloc}; pub struct WaAllocator; @@ -14,56 +14,57 @@ pub struct WaCell { } impl WaAllocator { - fn layout(layout: std::alloc::Layout) -> std::alloc::Layout { + fn layout(layout: Layout) -> Layout { unsafe { - std::alloc::Layout::from_size_align_unchecked( - layout.size() + std::mem::size_of::(), + Layout::from_size_align_unchecked( + layout.size() + size_of::(), layout.align(), ) } } unsafe fn write_header(ptr: *mut u8, id: u32, size: usize) { - slice::from_raw_parts_mut(ptr, 4) - .write(&id.to_le_bytes()) - .unwrap(); - slice::from_raw_parts_mut(ptr.wrapping_add(4), 4) - .write(&(size as u32).to_le_bytes()) - .unwrap(); + // Write the `id` as little-endian bytes into the first 4 bytes + slice::from_raw_parts_mut(ptr, 4).copy_from_slice(&id.to_le_bytes()); + + // Write the `size` (cast to u32) as little-endian bytes into the next 4 bytes + slice::from_raw_parts_mut(ptr.add(4), 4).copy_from_slice(&(size as u32).to_le_bytes()); } } -unsafe impl std::alloc::GlobalAlloc for WaAllocator { - unsafe fn alloc(&self, layout: std::alloc::Layout) -> *mut u8 { +unsafe impl GlobalAlloc for WaAllocator { + unsafe fn alloc(&self, layout: Layout) -> *mut u8 { let size = layout.size(); let layout = WaAllocator::layout(layout); - let ptr = System.alloc(layout); + let ptr = alloc(layout); WaAllocator::write_header(ptr, 1, size); - ptr.wrapping_add(std::mem::size_of::()) + ptr.wrapping_add(size_of::()) } - unsafe fn alloc_zeroed(&self, layout: std::alloc::Layout) -> *mut u8 { - let size = layout.size(); + unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { let layout = WaAllocator::layout(layout); - let ptr = System.alloc_zeroed(layout); - WaAllocator::write_header(ptr, 1, size); - - ptr.wrapping_add(std::mem::size_of::()) + dealloc(ptr.wrapping_sub(size_of::()), layout); } - unsafe fn dealloc(&self, ptr: *mut u8, layout: std::alloc::Layout) { + unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { + let size = layout.size(); let layout = WaAllocator::layout(layout); - System.dealloc(ptr.wrapping_sub(std::mem::size_of::()), layout); + let ptr = alloc_zeroed(layout); + WaAllocator::write_header(ptr, 1, size); + + ptr.wrapping_add(size_of::()) } - unsafe fn realloc(&self, ptr: *mut u8, layout: std::alloc::Layout, new_size: usize) -> *mut u8 { + unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { let layout = WaAllocator::layout(layout); - System - .realloc( - ptr.wrapping_sub(std::mem::size_of::()), + realloc( + ptr.wrapping_sub(size_of::()), layout, - new_size + std::mem::size_of::(), + new_size + size_of::(), ) - .wrapping_add(std::mem::size_of::()) + .wrapping_add(size_of::()) } } + +#[global_allocator] +static GLOBAL: WaAllocator = WaAllocator; diff --git a/src/lib.rs b/src/lib.rs index 8c20ebd..5552fdf 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,8 @@ #![feature(ptr_internals)] +#![no_std] +extern crate alloc; + pub mod allocator; pub mod constant; pub mod env; diff --git a/src/mem.rs b/src/mem.rs index 7102218..ee93fea 100644 --- a/src/mem.rs +++ b/src/mem.rs @@ -1,12 +1,17 @@ use core::slice; -use std::{alloc::Layout, io::Write, mem, ptr}; -extern crate alloc; +use alloc::boxed::Box; +use alloc::vec::Vec; +use core::mem; +use alloc::alloc::{alloc, Layout, dealloc}; +use alloc::{format}; // Import format and String from alloc -static mut MEMORY: Vec = Vec::new(); +extern crate alloc; pub type WaPtr = u32; +static mut MEMORY: Vec = Vec::new(); + pub struct Cursor<'a> { inner: &'a [u8], pos: usize, @@ -51,13 +56,13 @@ impl WaCell { const fn usize() -> usize { mem::size_of::() } - const fn layout(size: usize) -> std::alloc::Layout { - unsafe { std::alloc::Layout::from_size_align_unchecked(size + WaCell::usize(), 1) } + const fn layout(size: usize) -> Layout { + unsafe { Layout::from_size_align_unchecked(size + WaCell::usize(), 1) } } pub fn new(size: usize, id: u32) -> Box { unsafe { let layout = WaCell::layout(size); - let ptr = std::alloc::alloc(layout); + let ptr = alloc(layout); let mut cell = Box::::from_raw(ptr.cast()); cell.gc_info1 = 0; cell.mm_info = ptr as usize; @@ -69,7 +74,7 @@ impl WaCell { pub fn new_data(id: u32, data: &[u8]) -> Box { let mut cell = WaCell::new(data.len(), id); - cell.data_mut().write(data).unwrap(); + cell.data_mut().copy_from_slice(data); // Use `copy_from_slice` instead of `write` cell } @@ -86,7 +91,7 @@ impl WaCell { if let Some(index) = MEMORY.iter().position(|cell_ptr| *cell_ptr == ptr) { MEMORY.remove(index); } - std::alloc::dealloc(Box::into_raw(self) as *mut u8, layout); + dealloc(Box::into_raw(self) as *mut u8, layout); } } else { self.dec(); @@ -275,11 +280,9 @@ pub fn new(size: usize, id: u32) -> WaPtr { #[no_mangle] #[export_name = "__pin"] pub fn pin(ptr: WaPtr) -> WaPtr { - unsafe { - let mut cell = WaCell::from_raw(ptr); - cell.inc(); - cell.to_raw() - } + let mut cell = WaCell::from_raw(ptr); + cell.inc(); + cell.to_raw() } #[no_mangle] @@ -307,6 +310,7 @@ pub fn collect() { new.push(cell.to_raw()); } } - MEMORY = new + MEMORY.clear(); // Clear the old memory + MEMORY.extend(new); // Update with the new elements } } From 5800d12e90f48ab912bc6818e6ad4b52b2881c6f Mon Sep 17 00:00:00 2001 From: BlobMaster41 <96896824+BlobMaster41@users.noreply.github.com> Date: Sun, 3 Nov 2024 18:13:03 -0500 Subject: [PATCH 03/23] Update done.js --- done.js | 4588 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 4537 insertions(+), 51 deletions(-) diff --git a/done.js b/done.js index 49bb262..9bc6964 100644 --- a/done.js +++ b/done.js @@ -1,61 +1,4547 @@ +import * as env from 'env'; -module.exports = loadWebAssembly - -loadWebAssembly.supported = typeof WebAssembly !== 'undefined' - -function loadWebAssembly (opts) { - if (!loadWebAssembly.supported) return null - - var imp = opts && opts.imports - var wasm = toUint8Array('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NgIAQYiMwABB/IvAADYCAEH8i8AAQfSLwAA2AgBBoIzAACACNgIAQYSMwABB/IvAADYCAEGYjMAAIANBKGsiADYCACACIABBAXI2AgQgACACakEoNgIEQayMwABBgICAATYCAAwICyABIARJIAEgAk9yDQAgACgCDEUNAwtBsIzAAEGwjMAAKAIAIgAgAiAAIAJJGzYCACACIANqIQRB9InAACEAAkACQANAIAQgACgCACIGRwRAIAAoAggiAA0BDAILCyAAKAIMRQ0BC0H0icAAIQADQAJAIAEgACgCACIETwRAIAEgBCAAKAIEaiIGSQ0BCyAAKAIIIQAMAQsLQaCMwAAgAjYCAEGYjMAAIANBKGsiADYCACACIABBAXI2AgQgACACakEoNgIEQayMwABBgICAATYCACABIAZBIGtBeHFBCGsiACAAIAFBEGpJGyIEQRs2AgRB9InAACkCACEJIARBEGpB/InAACkCADcCACAEIAk3AghB+InAACADNgIAQfSJwAAgAjYCAEH8icAAIARBCGo2AgBBgIrAAEEANgIAIARBHGohAANAIABBBzYCACAAQQRqIgAgBkkNAAsgASAERg0HIAQgBCgCBEF+cTYCBCABIAQgAWsiAEEBcjYCBCAEIAA2AgAgAEGAAk8EQCABIAAQNwwICyAAQfgBcUGEisAAaiECAn9BjIzAACgCACIEQQEgAEEDdnQiAHFFBEBBjIzAACAAIARyNgIAIAIMAQsgAigCCAshACACIAE2AgggACABNgIMIAEgAjYCDCABIAA2AggMBwsgACACNgIAIAAgACgCBCADajYCBCACIAVBA3I2AgQgBkEPakF4cUEIayIDIAIgBWoiAGshBSADQaCMwAAoAgBGDQMgA0GcjMAAKAIARg0EIAMoAgQiAUEDcUEBRgRAIAMgAUF4cSIBEBEgASAFaiEFIAEgA2oiAygCBCEBCyADIAFBfnE2AgQgACAFQQFyNgIEIAAgBWogBTYCACAFQYACTwRAIAAgBRA3DAYLIAVB+AFxQYSKwABqIQECf0GMjMAAKAIAIgRBASAFQQN2dCIDcUUEQEGMjMAAIAMgBHI2AgAgAQwBCyABKAIICyEEIAEgADYCCCAEIAA2AgwgACABNgIMIAAgBDYCCAwFC0GYjMAAIAAgBWsiATYCAEGgjMAAQaCMwAAo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BCkCEDcCACAAQQhqIARBGGooAgA2AgALIARBIGokAA8LEAILAAsjAEFAaiIAJAAgAEHWADYCDCAAQcyAwAA2AgggAEG8gMAANgIUIAAgBEEfajYCECAAQQI2AhwgAEHIgcAANgIYIABCAjcCJCAAIABBEGqtQoCAgIAghDcDOCAAIABBCGqtQoCAgIAwhDcDMCAAIABBMGo2AiAgAEEYakG0gcAAEAMACwsAIABB/IbAABA7CwsAIABBkIfAABA7CxYAQdyIwAAgACABECdBFGoiABAyIAALbQEDfyAAKAIIIgQgACgCACIDRgRAIwBBEGsiAiQAIAJBCGogACADQQFBBEEEECIgAigCCCIDQYGAgIB4RwRAIAIoAgwaIAMQAQALIAJBEGokAAsgACAEQQFqNgIIIAAoAgQgBEECdGogATYCAAsYAQF/IABBEGsiASABKAIAQQFqNgIAIAALkgEBAn8jAEEwayIBJAAgAEEUayIAKAIEIgJBAk8EQCAAIAJBAWs2AgQLIAFBATYCECABQaSHwAA2AgwgAUIBNwIYIAFBATYCKCABQeSIwAAoAgA2AiwgASABQSRqNgIUIAEgAUEsajYCJCABIAFBDGoQLiABKAIEIgAgASgCCBAsIAEoAgAgAEEBECYgAUEwaiQAC68BAQR/IwBBEGsiACQAIABCgICAgMAANwIEIABBADYCDEHkiMAAKAIAQQJ0IQFB4IjAACgCACECA0AgAQRAAkAgAigCAEEUayIDKAIERQRAIANBFBAKDAELIABBBGogA0EUahAyCyACQQRqIQIgAUEEayEBDAELC0HciMAAKAIAQeCIwAAoAgBBBBAmQeSIwAAgAEEMaigCADYCAEHciMAAIAApAgQ3AgAgAEEQaiQACwkAIABBADYCAAu6AgEEf0EfIQIgAEIANwIQIAFB////B00EQCABQQYgAUEIdmciA2t2QQFxIANBAXRrQT5qIQILIAAgAjYCHCACQQJ0QfSIwABqIQRBASACdCIDQZCMwAAoAgBxRQRAIAQgADYCACAAIAQ2AhggACAANgIMIAAgADYCCEGQjMAAQZCMwAAoAgAgA3I2AgAPCwJAAkAgASAEKAIAIgMoAgRBeHFGBEAgAyECDAELIAFBGSACQQF2a0EAIAJBH0cbdCEFA0AgAyAFQR12QQRxakEQaiIEKAIAIgJFDQIgBUEBdCEFIAIhAyACKAIEQXhxIAFHDQALCyACKAIIIgEgADYCDCACIAA2AgggAEEANgIYIAAgAjYCDCAAIAE2AggPCyAEIAA2AgAgACADNgIYIAAgADYCDCAAIAA2AggLewECfyMAQRBrIgMkAEHwiMAAQfCIwAAoAgAiBEEBajYCAAJAIARBAEgNAAJAQbyMwAAtAABFBEBBuIzAAEG4jMAAKAIAQQFqNgIAQeyIwAAoAgBBAE4NAQwCCyADQQhqIAAgARECAAALQbyMwABBADoAACACRQ0AAAsACwwAIAAgASkCADcDAAu2AgEHfwJAIAJBEEkEQCAAIQMMAQsgAEEAIABrQQNxIgRqIQUgBARAIAAhAyABIQYDQCADIAYtAAA6AAAgBkEBaiEGIANBAWoiAyAFSQ0ACwsgBSACIARrIghBfHEiB2ohAwJAIAEgBGoiBEEDcQRAIAdBAEwNASAEQQN0IgJBGHEhCSAEQXxxIgZBBGohAUEAIAJrQRhxIQIgBigCACEGA0AgBSAGIAl2IAEoAgAiBiACdHI2AgAgAUEEaiEBIAVBBGoiBSADSQ0ACwwBCyAHQQBMDQAgBCEBA0AgBSABKAIANgIAIAFBBGohASAFQQRqIgUgA0kNAAsLIAhBA3EhAiAEIAdqIQELIAIEQCACIANqIQIDQCADIAEtAAA6AAAgAUEBaiEBIANBAWoiAyACSQ0ACwsgAAuaAQEDfyMAQUBqIgIkACACIAAQKiACKAIAIAIoAgQhACACQQE2AhwgAiABNgIYIAJBATYCJCACQQQ2AjQgAiAAQRRqNgI4IAIgACgCEDYCPCACQQA2AiggAiACQTBqNgIgIAIgAkE4ajYCMCACQQxqIAJBGGoQLiACKAIQIgQgAigCFBAsIAIoAgwgBEEBECYgABArIAJBQGskAAsL6QgDAEGAgMAACzkHAAAADAAAAAQAAAAIAAAACQAAAAoAAABhbGxvYy9zcmMvcmF3X3ZlYy5ycxgAEAAUAAAAGAAAAAUAQcSAwAALlQgBAAAACwAAAGEgZm9ybWF0dGluZyB0cmFpdCBpbXBsZW1lbnRhdGlvbiByZXR1cm5lZCBhbiBlcnJvciB3aGVuIHRoZSB1bmRlcmx5aW5nIHN0cmVhbSBkaWQgbm90YWxsb2Mvc3JjL2ZtdC5ycwAAogAQABAAAAB+AgAADgAAAFs6IAABAAAAAAAAAMUAEAACAAAAAAAAAAwAAAAEAAAADAAAAA0AAAAOAAAAICAgICwgLAoKXWNvcmUvc3JjL2ZtdC9udW0ucnMAAAD6ABAAEwAAAGYAAAAXAAAAMHgwMDAxMDIwMzA0MDUwNjA3MDgwOTEwMTExMjEzMTQxNTE2MTcxODE5MjAyMTIyMjMyNDI1MjYyNzI4MjkzMDMxMzIzMzM0MzUzNjM3MzgzOTQwNDE0MjQzNDQ0NTQ2NDc0ODQ5NTA1MTUyNTM1NDU1NTY1NzU4NTk2MDYxNjI2MzY0NjU2NjY3Njg2OTcwNzE3MjczNzQ3NTc2Nzc3ODc5ODA4MTgyODM4NDg1ODY4Nzg4ODk5MDkxOTI5Mzk0OTU5Njk3OTg5OXJhbmdlIHN0YXJ0IGluZGV4ICBvdXQgb2YgcmFuZ2UgZm9yIHNsaWNlIG9mIGxlbmd0aCAAAOoBEAASAAAA/AEQACIAAAByYW5nZSBlbmQgaW5kZXggMAIQABAAAAD8ARAAIgAAAGNhcGFjaXR5IG92ZXJmbG93AAAAUAIQABEAAAAvcnVzdGMvYzZkYjFjYTNjOTNhZDY5NjkyYTRjNGI1NTQyZjI2ZmRhNGJmM2FlYy9saWJyYXJ5L2FsbG9jL3NyYy92ZWMvc3BlY19mcm9tX2l0ZXJfbmVzdGVkLnJzAABsAhAAXgAAADkAAAASAAAAL3J1c3RjL2M2ZGIxY2EzYzkzYWQ2OTY5MmE0YzRiNTU0MmYyNmZkYTRiZjNhZWMvbGlicmFyeS9hbGxvYy9zcmMvdmVjL21vZC5yc9wCEABMAAAAPwwAAA0AAABzcmNcbWVtLnJzAAA4AxAACgAAAB4AAAAXAAAARXhlY3V0ZTogAAAAVAMQAAkAAABTZXQgZW52aXJvbm1lbnQ6IAAAAGgDEAARAAAAT24gZGVwbG95OiAAhAMQAAsAAABNZW0gc2l6ZTogAACYAxAACgAAAC9ydXN0L2RlcHMvZGxtYWxsb2MtMC4yLjYvc3JjL2RsbWFsbG9jLnJzYXNzZXJ0aW9uIGZhaWxlZDogcHNpemUgPj0gc2l6ZSArIG1pbl9vdmVyaGVhZACsAxAAKQAAAKgEAAAJAAAAYXNzZXJ0aW9uIGZhaWxlZDogcHNpemUgPD0gc2l6ZSArIG1heF9vdmVyaGVhZAAArAMQACkAAACuBAAADQAAAEVycm9yAEHgiMAACwEEAFUJcHJvZHVjZXJzAghsYW5ndWFnZQEEUnVzdAAMcHJvY2Vzc2VkLWJ5AQVydXN0YyUxLjgyLjAtbmlnaHRseSAoYzZkYjFjYTNjIDIwMjQtMDgtMjUpAEkPdGFyZ2V0X2ZlYXR1cmVzBCsPbXV0YWJsZS1nbG9iYWxzKwhzaWduLWV4dCsPcmVmZXJlbmNlLXR5cGVzKwptdWx0aXZhbHVl') - var ready = null - - var mod = { - buffer: wasm, - memory: null, - exports: null, - realloc: realloc, - onload: onload + var bufferView; + var base64ReverseLookup = new Uint8Array(123/*'z'+1*/); + for (var i = 25; i >= 0; --i) { + base64ReverseLookup[48+i] = 52+i; // '0-9' + base64ReverseLookup[65+i] = i; // 'A-Z' + base64ReverseLookup[97+i] = 26+i; // 'a-z' } - - onload(function () {}) - - return mod - - function realloc (size) { - mod.exports.memory.grow(Math.max(0, Math.ceil(Math.abs(size - mod.memory.length) / 65536))) - mod.memory = new Uint8Array(mod.exports.memory.buffer) + base64ReverseLookup[43] = 62; // '+' + base64ReverseLookup[47] = 63; // '/' + /** @noinline Inlining this function would mean expanding the base64 string 4x times in the source code, which Closure seems to be happy to do. */ + function base64DecodeToExistingUint8Array(uint8Array, offset, b64) { + var b1, b2, i = 0, j = offset, bLength = b64.length, end = offset + (bLength*3>>2) - (b64[bLength-2] == '=') - (b64[bLength-1] == '='); + for (; i < bLength; i += 4) { + b1 = base64ReverseLookup[b64.charCodeAt(i+1)]; + b2 = base64ReverseLookup[b64.charCodeAt(i+2)]; + uint8Array[j++] = base64ReverseLookup[b64.charCodeAt(i)] << 2 | b1 >> 4; + if (j < end) uint8Array[j++] = b1 << 4 | b2 >> 2; + if (j < end) uint8Array[j++] = b2 << 6 | base64ReverseLookup[b64.charCodeAt(i+3)]; + } } +function initActiveSegments(imports) { + base64DecodeToExistingUint8Array(bufferView, 1048576, "BwAAAAwAAAAEAAAACAAAAAkAAAAKAAAAYWxsb2Mvc3JjL3Jhd192ZWMucnMYABAAFAAAABgAAAAF"); + base64DecodeToExistingUint8Array(bufferView, 1048644, "AQAAAAsAAABhIGZvcm1hdHRpbmcgdHJhaXQgaW1wbGVtZW50YXRpb24gcmV0dXJuZWQgYW4gZXJyb3Igd2hlbiB0aGUgdW5kZXJseWluZyBzdHJlYW0gZGlkIG5vdGFsbG9jL3NyYy9mbXQucnMAAKIAEAAQAAAAfgIAAA4AAABbOiAAAQAAAAAAAADFABAAAgAAAAAAAAAMAAAABAAAAAwAAAANAAAADgAAACAgICAsICwKCl1jb3JlL3NyYy9mbXQvbnVtLnJzAAAA+gAQABMAAABmAAAAFwAAADB4MDAwMTAyMDMwNDA1MDYwNzA4MDkxMDExMTIxMzE0MTUxNjE3MTgxOTIwMjEyMjIzMjQyNTI2MjcyODI5MzAzMTMyMzMzNDM1MzYzNzM4Mzk0MDQxNDI0MzQ0NDU0NjQ3NDg0OTUwNTE1MjUzNTQ1NTU2NTc1ODU5NjA2MTYyNjM2NDY1NjY2NzY4Njk3MDcxNzI3Mzc0NzU3Njc3Nzg3OTgwODE4MjgzODQ4NTg2ODc4ODg5OTA5MTkyOTM5NDk1OTY5Nzk4OTlyYW5nZSBzdGFydCBpbmRleCAgb3V0IG9mIHJhbmdlIGZvciBzbGljZSBvZiBsZW5ndGggAADqARAAEgAAAPwBEAAiAAAAcmFuZ2UgZW5kIGluZGV4IDACEAAQAAAA/AEQACIAAABjYXBhY2l0eSBvdmVyZmxvdwAAAFACEAARAAAAL3J1c3RjL2M2ZGIxY2EzYzkzYWQ2OTY5MmE0YzRiNTU0MmYyNmZkYTRiZjNhZWMvbGlicmFyeS9hbGxvYy9zcmMvdmVjL3NwZWNfZnJvbV9pdGVyX25lc3RlZC5ycwAAbAIQAF4AAAA5AAAAEgAAAC9ydXN0Yy9jNmRiMWNhM2M5M2FkNjk2OTJhNGM0YjU1NDJmMjZmZGE0YmYzYWVjL2xpYnJhcnkvYWxsb2Mvc3JjL3ZlYy9tb2QucnPcAhAATAAAAD8MAAANAAAAc3JjXG1lbS5ycwAAOAMQAAoAAAAeAAAAFwAAAEV4ZWN1dGU6IAAAAFQDEAAJAAAAU2V0IGVudmlyb25tZW50OiAAAABoAxAAEQAAAE9uIGRlcGxveTogAIQDEAALAAAATWVtIHNpemU6IAAAmAMQAAoAAAAvcnVzdC9kZXBzL2RsbWFsbG9jLTAuMi42L3NyYy9kbG1hbGxvYy5yc2Fzc2VydGlvbiBmYWlsZWQ6IHBzaXplID49IHNpemUgKyBtaW5fb3ZlcmhlYWQArAMQACkAAACoBAAACQAAAGFzc2VydGlvbiBmYWlsZWQ6IHBzaXplIDw9IHNpemUgKyBtYXhfb3ZlcmhlYWQAAKwDEAApAAAArgQAAA0AAABFcnJvcg=="); + base64DecodeToExistingUint8Array(bufferView, 1049696, "BA=="); +} +function wasm2js_trap() { throw new Error('abort'); } - function onload (cb) { - if (mod.exports) return cb() - - if (ready) { - ready.then(cb.bind(null, null)).catch(cb) - return +function asmFunc(imports) { + var buffer = new ArrayBuffer(1114112); + var HEAP8 = new Int8Array(buffer); + var HEAP16 = new Int16Array(buffer); + var HEAP32 = new Int32Array(buffer); + var HEAPU8 = new Uint8Array(buffer); + var HEAPU16 = new Uint16Array(buffer); + var HEAPU32 = new Uint32Array(buffer); + var HEAPF32 = new Float32Array(buffer); + var HEAPF64 = new Float64Array(buffer); + var Math_imul = Math.imul; + var Math_fround = Math.fround; + var Math_abs = Math.abs; + var Math_clz32 = Math.clz32; + var Math_min = Math.min; + var Math_max = Math.max; + var Math_floor = Math.floor; + var Math_ceil = Math.ceil; + var Math_trunc = Math.trunc; + var Math_sqrt = Math.sqrt; + var env = imports.env; + var fimport$0 = env.log; + var global$0 = 1048576; + var global$1 = 1050173; + var global$2 = 1050176; + var __wasm_intrinsics_temp_i64 = 0; + var __wasm_intrinsics_temp_i64$hi = 0; + var i64toi32_i32$HIGH_BITS = 0; + function $0($0_1) { + $0_1 = $0_1 | 0; + if (!$0_1) { + $1() + } + wasm2js_trap(); + } + + function $1() { + var $0_1 = 0; + $0_1 = global$0 - 32 | 0; + global$0 = $0_1; + HEAP32[($0_1 + 24 | 0) >> 2] = 0; + HEAP32[($0_1 + 12 | 0) >> 2] = 1; + HEAP32[($0_1 + 8 | 0) >> 2] = 1049188; + HEAP32[($0_1 + 16 | 0) >> 2] = 4; + HEAP32[($0_1 + 20 | 0) >> 2] = 0; + $2($0_1 + 8 | 0 | 0, 1048620 | 0); + wasm2js_trap(); + } + + function $2($0_1, $1_1) { + $0_1 = $0_1 | 0; + $1_1 = $1_1 | 0; + var i64toi32_i32$0 = 0, i64toi32_i32$1 = 0, $2_1 = 0, i64toi32_i32$2 = 0, $3_1 = 0, $4_1 = 0, $13_1 = 0, $19_1 = 0, $25_1 = 0, $34_1 = 0, $38_1 = 0, $45_1 = 0; + $2_1 = global$0 - 32 | 0; + global$0 = $2_1; + $3_1 = $2_1 + 16 | 0; + i64toi32_i32$2 = $0_1 + 16 | 0; + i64toi32_i32$0 = HEAP32[i64toi32_i32$2 >> 2] | 0; + i64toi32_i32$1 = HEAP32[(i64toi32_i32$2 + 4 | 0) >> 2] | 0; + $13_1 = i64toi32_i32$0; + i64toi32_i32$0 = $3_1; + HEAP32[i64toi32_i32$0 >> 2] = $13_1; + HEAP32[(i64toi32_i32$0 + 4 | 0) >> 2] = i64toi32_i32$1; + $4_1 = $2_1 + 8 | 0; + i64toi32_i32$2 = $0_1 + 8 | 0; + i64toi32_i32$1 = HEAP32[i64toi32_i32$2 >> 2] | 0; + i64toi32_i32$0 = HEAP32[(i64toi32_i32$2 + 4 | 0) >> 2] | 0; + $19_1 = i64toi32_i32$1; + i64toi32_i32$1 = $4_1; + HEAP32[i64toi32_i32$1 >> 2] = $19_1; + HEAP32[(i64toi32_i32$1 + 4 | 0) >> 2] = i64toi32_i32$0; + HEAP16[($2_1 + 28 | 0) >> 1] = 1; + HEAP32[($2_1 + 24 | 0) >> 2] = $1_1; + i64toi32_i32$2 = $0_1; + i64toi32_i32$0 = HEAP32[$0_1 >> 2] | 0; + i64toi32_i32$1 = HEAP32[($0_1 + 4 | 0) >> 2] | 0; + $25_1 = i64toi32_i32$0; + i64toi32_i32$0 = $2_1; + HEAP32[i64toi32_i32$0 >> 2] = $25_1; + HEAP32[(i64toi32_i32$0 + 4 | 0) >> 2] = i64toi32_i32$1; + $0_1 = global$0 - 32 | 0; + global$0 = $0_1; + $1_1 = HEAP32[(i64toi32_i32$0 + 24 | 0) >> 2] | 0; + i64toi32_i32$2 = $3_1; + i64toi32_i32$1 = HEAP32[i64toi32_i32$2 >> 2] | 0; + i64toi32_i32$0 = HEAP32[(i64toi32_i32$2 + 4 | 0) >> 2] | 0; + $34_1 = i64toi32_i32$1; + i64toi32_i32$1 = $0_1 + 16 | 0; + HEAP32[i64toi32_i32$1 >> 2] = $34_1; + HEAP32[(i64toi32_i32$1 + 4 | 0) >> 2] = i64toi32_i32$0; + i64toi32_i32$2 = $4_1; + i64toi32_i32$0 = HEAP32[i64toi32_i32$2 >> 2] | 0; + i64toi32_i32$1 = HEAP32[(i64toi32_i32$2 + 4 | 0) >> 2] | 0; + $38_1 = i64toi32_i32$0; + i64toi32_i32$0 = $0_1 + 8 | 0; + HEAP32[i64toi32_i32$0 >> 2] = $38_1; + HEAP32[(i64toi32_i32$0 + 4 | 0) >> 2] = i64toi32_i32$1; + HEAP32[($0_1 + 28 | 0) >> 2] = $2_1; + HEAP32[($0_1 + 24 | 0) >> 2] = $1_1; + i64toi32_i32$2 = $2_1; + i64toi32_i32$1 = HEAP32[$2_1 >> 2] | 0; + i64toi32_i32$0 = HEAP32[($2_1 + 4 | 0) >> 2] | 0; + $45_1 = i64toi32_i32$1; + i64toi32_i32$1 = $0_1; + HEAP32[$0_1 >> 2] = $45_1; + HEAP32[($0_1 + 4 | 0) >> 2] = i64toi32_i32$0; + $2_1 = 0; + $1_1 = global$0 - 16 | 0; + global$0 = $1_1; + $3_1 = HEAP32[($0_1 + 12 | 0) >> 2] | 0; + label$1 : { + label$2 : { + label$3 : { + switch (HEAP32[($0_1 + 4 | 0) >> 2] | 0 | 0) { + case 0: + if ($3_1) { + break label$2 + } + $3_1 = 1; + break label$1; + case 1: + break label$3; + default: + break label$2; + }; } - - try { - if (opts && opts.async) throw new Error('async') - setup({instance: new WebAssembly.Instance(new WebAssembly.Module(wasm), imp)}) - } catch (err) { - ready = WebAssembly.instantiate(wasm, imp).then(setup) + if ($3_1) { + break label$2 } - - onload(cb) + $3_1 = HEAP32[$0_1 >> 2] | 0; + $2_1 = HEAP32[($3_1 + 4 | 0) >> 2] | 0; + $3_1 = HEAP32[$3_1 >> 2] | 0; + break label$1; + } + HEAP32[$1_1 >> 2] = -2147483648; + HEAP32[($1_1 + 12 | 0) >> 2] = $0_1; + $0_1 = HEAP32[($0_1 + 28 | 0) >> 2] | 0; + $2_1 = HEAPU8[($0_1 + 28 | 0) >> 0] | 0; + HEAPU8[($0_1 + 29 | 0) >> 0] | 0; + $55($1_1 | 0, 5 | 0, $2_1 | 0); + wasm2js_trap(); } - - function setup (w) { - mod.exports = w.instance.exports - mod.memory = mod.exports.memory && mod.exports.memory.buffer && new Uint8Array(mod.exports.memory.buffer) + HEAP32[($1_1 + 4 | 0) >> 2] = $2_1; + HEAP32[$1_1 >> 2] = $3_1; + $0_1 = HEAP32[($0_1 + 28 | 0) >> 2] | 0; + $2_1 = HEAPU8[($0_1 + 28 | 0) >> 0] | 0; + HEAPU8[($0_1 + 29 | 0) >> 0] | 0; + $55($1_1 | 0, 6 | 0, $2_1 | 0); + wasm2js_trap(); + } + + function $3($0_1, $1_1, $2_1) { + $0_1 = $0_1 | 0; + $1_1 = $1_1 | 0; + $2_1 = $2_1 | 0; + var $3_1 = 0, $4_1 = 0, $39_1 = 0, $30_1 = 0; + $3_1 = global$0 - 32 | 0; + global$0 = $3_1; + $2_1 = $1_1 + $2_1 | 0; + if ($1_1 >>> 0 > $2_1 >>> 0) { + $0(0 | 0); + wasm2js_trap(); } + $1_1 = HEAP32[$0_1 >> 2] | 0; + $4_1 = $1_1 << 1 | 0; + $2_1 = $2_1 >>> 0 < $4_1 >>> 0 ? $4_1 : $2_1; + $2_1 = $2_1 >>> 0 <= 8 >>> 0 ? 8 : $2_1; + if (($2_1 | 0) < (0 | 0)) { + $0(0 | 0); + wasm2js_trap(); + } + $30_1 = $3_1; + if ($1_1) { + HEAP32[($3_1 + 28 | 0) >> 2] = $1_1; + HEAP32[($3_1 + 20 | 0) >> 2] = HEAP32[($0_1 + 4 | 0) >> 2] | 0; + $39_1 = 1; + } else { + $39_1 = 0 + } + HEAP32[($30_1 + 24 | 0) >> 2] = $39_1; + $4($3_1 + 8 | 0 | 0, $2_1 | 0, $3_1 + 20 | 0 | 0); + if ((HEAP32[($3_1 + 8 | 0) >> 2] | 0 | 0) == (1 | 0)) { + HEAP32[($3_1 + 16 | 0) >> 2] | 0; + $0(HEAP32[($3_1 + 12 | 0) >> 2] | 0 | 0); + wasm2js_trap(); + } + $1_1 = HEAP32[($3_1 + 12 | 0) >> 2] | 0; + HEAP32[$0_1 >> 2] = $2_1; + HEAP32[($0_1 + 4 | 0) >> 2] = $1_1; + global$0 = $3_1 + 32 | 0; + } + + function $4($0_1, $1_1, $2_1) { + $0_1 = $0_1 | 0; + $1_1 = $1_1 | 0; + $2_1 = $2_1 | 0; + var $3_1 = 0, $14_1 = 0; + label$1 : { + if (HEAP32[($2_1 + 4 | 0) >> 2] | 0) { + $3_1 = HEAP32[($2_1 + 8 | 0) >> 2] | 0; + if ($3_1) { + $14_1 = $5(HEAP32[$2_1 >> 2] | 0 | 0, $3_1 | 0, $1_1 | 0) | 0; + break label$1; + } + } + HEAPU8[1049704 >> 0] | 0; + $14_1 = $6($1_1 | 0) | 0; + } + $2_1 = $14_1; + HEAP32[($0_1 + 8 | 0) >> 2] = $1_1; + HEAP32[($0_1 + 4 | 0) >> 2] = $2_1 ? $2_1 : 1; + HEAP32[$0_1 >> 2] = !$2_1; + } + + function $5($0_1, $1_1, $2_1) { + $0_1 = $0_1 | 0; + $1_1 = $1_1 | 0; + $2_1 = $2_1 | 0; + var $3_1 = 0, $4_1 = 0, $5_1 = 0, $6_1 = 0, $7_1 = 0, $202 = 0, $8_1 = 0; + label$1 : { + label$2 : { + $4_1 = $0_1 - 4 | 0; + $6_1 = HEAP32[$4_1 >> 2] | 0; + $3_1 = $6_1 & -8 | 0; + $5_1 = $6_1 & 3 | 0; + if ($3_1 >>> 0 >= (($5_1 ? 4 : 8) + $1_1 | 0) >>> 0) { + if ($3_1 >>> 0 > ($1_1 + 39 | 0) >>> 0 ? $5_1 : 0) { + break label$2 + } + $1_1 = $2_1 >>> 0 < 11 >>> 0 ? 16 : ($2_1 + 11 | 0) & -8 | 0; + label$4 : { + label$5 : { + if (!$5_1) { + if ($1_1 >>> 0 < 256 >>> 0 | $3_1 >>> 0 < ($1_1 | 4 | 0) >>> 0 | 0 | ($3_1 - $1_1 | 0) >>> 0 >= 131073 >>> 0 | 0) { + break label$5 + } + break label$4; + } + $5_1 = $0_1 - 8 | 0; + $7_1 = $5_1 + $3_1 | 0; + label$7 : { + label$8 : { + label$9 : { + if ($1_1 >>> 0 > $3_1 >>> 0) { + if (($7_1 | 0) == (HEAP32[1050144 >> 2] | 0 | 0)) { + break label$7 + } + if (($7_1 | 0) == (HEAP32[1050140 >> 2] | 0 | 0)) { + break label$8 + } + $6_1 = HEAP32[($7_1 + 4 | 0) >> 2] | 0; + if ($6_1 & 2 | 0) { + break label$5 + } + $6_1 = $6_1 & -8 | 0; + $3_1 = $6_1 + $3_1 | 0; + if ($3_1 >>> 0 < $1_1 >>> 0) { + break label$5 + } + $16($7_1 | 0, $6_1 | 0); + $2_1 = $3_1 - $1_1 | 0; + if ($2_1 >>> 0 < 16 >>> 0) { + break label$9 + } + HEAP32[$4_1 >> 2] = $1_1 | ((HEAP32[$4_1 >> 2] | 0) & 1 | 0) | 0 | 2 | 0; + $1_1 = $1_1 + $5_1 | 0; + HEAP32[($1_1 + 4 | 0) >> 2] = $2_1 | 3 | 0; + $4_1 = $3_1 + $5_1 | 0; + HEAP32[($4_1 + 4 | 0) >> 2] = HEAP32[($4_1 + 4 | 0) >> 2] | 0 | 1 | 0; + $17($1_1 | 0, $2_1 | 0); + return $0_1 | 0; + } + $2_1 = $3_1 - $1_1 | 0; + if ($2_1 >>> 0 <= 15 >>> 0) { + break label$4 + } + HEAP32[$4_1 >> 2] = $1_1 | ($6_1 & 1 | 0) | 0 | 2 | 0; + $1_1 = $1_1 + $5_1 | 0; + HEAP32[($1_1 + 4 | 0) >> 2] = $2_1 | 3 | 0; + HEAP32[($7_1 + 4 | 0) >> 2] = HEAP32[($7_1 + 4 | 0) >> 2] | 0 | 1 | 0; + $17($1_1 | 0, $2_1 | 0); + return $0_1 | 0; + } + HEAP32[$4_1 >> 2] = $3_1 | ((HEAP32[$4_1 >> 2] | 0) & 1 | 0) | 0 | 2 | 0; + $1_1 = $3_1 + $5_1 | 0; + HEAP32[($1_1 + 4 | 0) >> 2] = HEAP32[($1_1 + 4 | 0) >> 2] | 0 | 1 | 0; + return $0_1 | 0; + } + $3_1 = (HEAP32[1050132 >> 2] | 0) + $3_1 | 0; + if ($3_1 >>> 0 < $1_1 >>> 0) { + break label$5 + } + label$11 : { + $2_1 = $3_1 - $1_1 | 0; + if ($2_1 >>> 0 <= 15 >>> 0) { + HEAP32[$4_1 >> 2] = $6_1 & 1 | 0 | $3_1 | 0 | 2 | 0; + $1_1 = $3_1 + $5_1 | 0; + HEAP32[($1_1 + 4 | 0) >> 2] = HEAP32[($1_1 + 4 | 0) >> 2] | 0 | 1 | 0; + $2_1 = 0; + $1_1 = 0; + break label$11; + } + HEAP32[$4_1 >> 2] = $1_1 | ($6_1 & 1 | 0) | 0 | 2 | 0; + $1_1 = $1_1 + $5_1 | 0; + HEAP32[($1_1 + 4 | 0) >> 2] = $2_1 | 1 | 0; + $4_1 = $3_1 + $5_1 | 0; + HEAP32[$4_1 >> 2] = $2_1; + HEAP32[($4_1 + 4 | 0) >> 2] = (HEAP32[($4_1 + 4 | 0) >> 2] | 0) & -2 | 0; + } + HEAP32[1050140 >> 2] = $1_1; + HEAP32[1050132 >> 2] = $2_1; + return $0_1 | 0; + } + $3_1 = (HEAP32[1050136 >> 2] | 0) + $3_1 | 0; + if ($3_1 >>> 0 > $1_1 >>> 0) { + break label$1 + } + } + $1_1 = $6($2_1 | 0) | 0; + if (!$1_1) { + return 0 | 0 + } + $202 = $1_1; + $1_1 = HEAP32[$4_1 >> 2] | 0; + $1_1 = ($1_1 & 3 | 0 ? -4 : -8) + ($1_1 & -8 | 0) | 0; + $8_1 = $57($202 | 0, $0_1 | 0, ($1_1 >>> 0 < $2_1 >>> 0 ? $1_1 : $2_1) | 0) | 0; + $14($0_1 | 0); + $0_1 = $8_1; + } + return $0_1 | 0; + } + $15(1049557 | 0, 1049604 | 0); + wasm2js_trap(); + } + $15(1049620 | 0, 1049668 | 0); + wasm2js_trap(); + } + HEAP32[$4_1 >> 2] = $1_1 | ($6_1 & 1 | 0) | 0 | 2 | 0; + $2_1 = $1_1 + $5_1 | 0; + $1_1 = $3_1 - $1_1 | 0; + HEAP32[($2_1 + 4 | 0) >> 2] = $1_1 | 1 | 0; + HEAP32[1050136 >> 2] = $1_1; + HEAP32[1050144 >> 2] = $2_1; + return $0_1 | 0; + } + + function $6($0_1) { + $0_1 = $0_1 | 0; + var $1_1 = 0, $2_1 = 0, $3_1 = 0, $4_1 = 0, $5_1 = 0, $6_1 = 0, $7_1 = 0, i64toi32_i32$1 = 0, i64toi32_i32$2 = 0, i64toi32_i32$0 = 0, $8_1 = 0, $318 = 0, $383 = 0, $740 = 0, $824 = 0, $1004 = 0, $241 = 0, $9_1 = 0, $9$hi = 0, $691 = 0, wasm2js_i32$0 = 0, wasm2js_i32$1 = 0; + label$1 : { + label$2 : { + label$3 : { + label$4 : { + label$5 : { + label$6 : { + label$7 : { + label$8 : { + if ($0_1 >>> 0 >= 245 >>> 0) { + if ($0_1 >>> 0 >= -65587 >>> 0) { + break label$4 + } + $1_1 = $0_1 + 11 | 0; + $5_1 = $1_1 & -8 | 0; + $8_1 = HEAP32[1050128 >> 2] | 0; + if (!$8_1) { + break label$5 + } + $7_1 = 31; + $3_1 = 0 - $5_1 | 0; + if ($0_1 >>> 0 <= 16777204 >>> 0) { + $0_1 = Math_clz32($1_1 >>> 8 | 0); + $7_1 = ((($5_1 >>> (6 - $0_1 | 0) | 0) & 1 | 0) - ($0_1 << 1 | 0) | 0) + 62 | 0; + } + $2_1 = HEAP32[(($7_1 << 2 | 0) + 1049716 | 0) >> 2] | 0; + if (!$2_1) { + $0_1 = 0; + $1_1 = 0; + break label$8; + } + $0_1 = 0; + $4_1 = $5_1 << (($7_1 | 0) != (31 | 0) ? 25 - ($7_1 >>> 1 | 0) | 0 : 0) | 0; + $1_1 = 0; + label$12 : while (1) { + label$13 : { + $6_1 = (HEAP32[($2_1 + 4 | 0) >> 2] | 0) & -8 | 0; + if ($6_1 >>> 0 < $5_1 >>> 0) { + break label$13 + } + $6_1 = $6_1 - $5_1 | 0; + if ($6_1 >>> 0 >= $3_1 >>> 0) { + break label$13 + } + $1_1 = $2_1; + $3_1 = $6_1; + if ($3_1) { + break label$13 + } + $3_1 = 0; + $0_1 = $1_1; + break label$7; + } + $6_1 = HEAP32[($2_1 + 20 | 0) >> 2] | 0; + $2_1 = HEAP32[(($2_1 + (($4_1 >>> 29 | 0) & 4 | 0) | 0) + 16 | 0) >> 2] | 0; + $0_1 = $6_1 ? (($6_1 | 0) != ($2_1 | 0) ? $6_1 : $0_1) : $0_1; + $4_1 = $4_1 << 1 | 0; + if ($2_1) { + continue label$12 + } + break label$12; + }; + break label$8; + } + $2_1 = HEAP32[1050124 >> 2] | 0; + $5_1 = $0_1 >>> 0 < 11 >>> 0 ? 16 : ($0_1 + 11 | 0) & 504 | 0; + $0_1 = $5_1 >>> 3 | 0; + $1_1 = $2_1 >>> $0_1 | 0; + if ($1_1 & 3 | 0) { + label$15 : { + $6_1 = (($1_1 ^ -1 | 0) & 1 | 0) + $0_1 | 0; + $0_1 = $6_1 << 3 | 0; + $4_1 = $0_1 + 1049860 | 0; + $1_1 = HEAP32[($0_1 + 1049868 | 0) >> 2] | 0; + $3_1 = HEAP32[($1_1 + 8 | 0) >> 2] | 0; + if (($4_1 | 0) != ($3_1 | 0)) { + HEAP32[($3_1 + 12 | 0) >> 2] = $4_1; + HEAP32[($4_1 + 8 | 0) >> 2] = $3_1; + break label$15; + } + (wasm2js_i32$0 = 1050124, wasm2js_i32$1 = $2_1 & (__wasm_rotl_i32(-2 | 0, $6_1 | 0) | 0) | 0), HEAP32[wasm2js_i32$0 >> 2] = wasm2js_i32$1; + } + HEAP32[($1_1 + 4 | 0) >> 2] = $0_1 | 3 | 0; + $0_1 = $0_1 + $1_1 | 0; + HEAP32[($0_1 + 4 | 0) >> 2] = HEAP32[($0_1 + 4 | 0) >> 2] | 0 | 1 | 0; + return $1_1 + 8 | 0 | 0; + } + if ($5_1 >>> 0 <= (HEAP32[1050132 >> 2] | 0) >>> 0) { + break label$5 + } + label$17 : { + label$18 : { + if (!$1_1) { + $0_1 = HEAP32[1050128 >> 2] | 0; + if (!$0_1) { + break label$5 + } + $1_1 = HEAP32[(((__wasm_ctz_i32($0_1 | 0) | 0) << 2 | 0) + 1049716 | 0) >> 2] | 0; + $3_1 = ((HEAP32[($1_1 + 4 | 0) >> 2] | 0) & -8 | 0) - $5_1 | 0; + $2_1 = $1_1; + label$20 : while (1) { + label$21 : { + $0_1 = HEAP32[($1_1 + 16 | 0) >> 2] | 0; + if ($0_1) { + break label$21 + } + $0_1 = HEAP32[($1_1 + 20 | 0) >> 2] | 0; + if ($0_1) { + break label$21 + } + $7_1 = HEAP32[($2_1 + 24 | 0) >> 2] | 0; + label$22 : { + label$23 : { + $0_1 = HEAP32[($2_1 + 12 | 0) >> 2] | 0; + if (($2_1 | 0) == ($0_1 | 0)) { + $0_1 = HEAP32[($2_1 + 20 | 0) >> 2] | 0; + $1_1 = HEAP32[($2_1 + ($0_1 ? 20 : 16) | 0) >> 2] | 0; + if ($1_1) { + break label$23 + } + $0_1 = 0; + break label$22; + } + $1_1 = HEAP32[($2_1 + 8 | 0) >> 2] | 0; + HEAP32[($1_1 + 12 | 0) >> 2] = $0_1; + HEAP32[($0_1 + 8 | 0) >> 2] = $1_1; + break label$22; + } + $4_1 = $0_1 ? $2_1 + 20 | 0 : $2_1 + 16 | 0; + label$25 : while (1) { + $6_1 = $4_1; + $0_1 = $1_1; + $1_1 = HEAP32[($0_1 + 20 | 0) >> 2] | 0; + $4_1 = $1_1 ? $0_1 + 20 | 0 : $0_1 + 16 | 0; + $1_1 = HEAP32[($0_1 + ($1_1 ? 20 : 16) | 0) >> 2] | 0; + if ($1_1) { + continue label$25 + } + break label$25; + }; + HEAP32[$6_1 >> 2] = 0; + } + if (!$7_1) { + break label$17 + } + $1_1 = ((HEAP32[($2_1 + 28 | 0) >> 2] | 0) << 2 | 0) + 1049716 | 0; + if (($2_1 | 0) != (HEAP32[$1_1 >> 2] | 0 | 0)) { + HEAP32[($7_1 + ((HEAP32[($7_1 + 16 | 0) >> 2] | 0 | 0) == ($2_1 | 0) ? 16 : 20) | 0) >> 2] = $0_1; + if (!$0_1) { + break label$17 + } + break label$18; + } + HEAP32[$1_1 >> 2] = $0_1; + if ($0_1) { + break label$18 + } + (wasm2js_i32$0 = 1050128, wasm2js_i32$1 = (HEAP32[1050128 >> 2] | 0) & (__wasm_rotl_i32(-2 | 0, HEAP32[($2_1 + 28 | 0) >> 2] | 0 | 0) | 0) | 0), HEAP32[wasm2js_i32$0 >> 2] = wasm2js_i32$1; + break label$17; + } + $1_1 = ((HEAP32[($0_1 + 4 | 0) >> 2] | 0) & -8 | 0) - $5_1 | 0; + $241 = $1_1; + $1_1 = $1_1 >>> 0 < $3_1 >>> 0; + $3_1 = $1_1 ? $241 : $3_1; + $2_1 = $1_1 ? $0_1 : $2_1; + $1_1 = $0_1; + continue label$20; + }; + } + label$27 : { + $4_1 = 2 << $0_1 | 0; + $6_1 = __wasm_ctz_i32(($4_1 | (0 - $4_1 | 0) | 0) & ($1_1 << $0_1 | 0) | 0 | 0) | 0; + $1_1 = $6_1 << 3 | 0; + $4_1 = $1_1 + 1049860 | 0; + $0_1 = HEAP32[($1_1 + 1049868 | 0) >> 2] | 0; + $3_1 = HEAP32[($0_1 + 8 | 0) >> 2] | 0; + if (($4_1 | 0) != ($3_1 | 0)) { + HEAP32[($3_1 + 12 | 0) >> 2] = $4_1; + HEAP32[($4_1 + 8 | 0) >> 2] = $3_1; + break label$27; + } + (wasm2js_i32$0 = 1050124, wasm2js_i32$1 = $2_1 & (__wasm_rotl_i32(-2 | 0, $6_1 | 0) | 0) | 0), HEAP32[wasm2js_i32$0 >> 2] = wasm2js_i32$1; + } + HEAP32[($0_1 + 4 | 0) >> 2] = $5_1 | 3 | 0; + $6_1 = $0_1 + $5_1 | 0; + $4_1 = $1_1 - $5_1 | 0; + HEAP32[($6_1 + 4 | 0) >> 2] = $4_1 | 1 | 0; + HEAP32[($0_1 + $1_1 | 0) >> 2] = $4_1; + $3_1 = HEAP32[1050132 >> 2] | 0; + if ($3_1) { + $1_1 = ($3_1 & -8 | 0) + 1049860 | 0; + $2_1 = HEAP32[1050140 >> 2] | 0; + label$30 : { + $5_1 = HEAP32[1050124 >> 2] | 0; + $3_1 = 1 << ($3_1 >>> 3 | 0) | 0; + if (!($5_1 & $3_1 | 0)) { + HEAP32[1050124 >> 2] = $3_1 | $5_1 | 0; + $318 = $1_1; + break label$30; + } + $318 = HEAP32[($1_1 + 8 | 0) >> 2] | 0; + } + $3_1 = $318; + HEAP32[($1_1 + 8 | 0) >> 2] = $2_1; + HEAP32[($3_1 + 12 | 0) >> 2] = $2_1; + HEAP32[($2_1 + 12 | 0) >> 2] = $1_1; + HEAP32[($2_1 + 8 | 0) >> 2] = $3_1; + } + HEAP32[1050140 >> 2] = $6_1; + HEAP32[1050132 >> 2] = $4_1; + break label$1; + } + HEAP32[($0_1 + 24 | 0) >> 2] = $7_1; + $1_1 = HEAP32[($2_1 + 16 | 0) >> 2] | 0; + if ($1_1) { + HEAP32[($0_1 + 16 | 0) >> 2] = $1_1; + HEAP32[($1_1 + 24 | 0) >> 2] = $0_1; + } + $1_1 = HEAP32[($2_1 + 20 | 0) >> 2] | 0; + if (!$1_1) { + break label$17 + } + HEAP32[($0_1 + 20 | 0) >> 2] = $1_1; + HEAP32[($1_1 + 24 | 0) >> 2] = $0_1; + } + label$33 : { + label$34 : { + if ($3_1 >>> 0 >= 16 >>> 0) { + HEAP32[($2_1 + 4 | 0) >> 2] = $5_1 | 3 | 0; + $4_1 = $2_1 + $5_1 | 0; + HEAP32[($4_1 + 4 | 0) >> 2] = $3_1 | 1 | 0; + HEAP32[($3_1 + $4_1 | 0) >> 2] = $3_1; + $6_1 = HEAP32[1050132 >> 2] | 0; + if (!$6_1) { + break label$34 + } + $0_1 = ($6_1 & -8 | 0) + 1049860 | 0; + $1_1 = HEAP32[1050140 >> 2] | 0; + label$36 : { + $5_1 = HEAP32[1050124 >> 2] | 0; + $6_1 = 1 << ($6_1 >>> 3 | 0) | 0; + if (!($5_1 & $6_1 | 0)) { + HEAP32[1050124 >> 2] = $5_1 | $6_1 | 0; + $383 = $0_1; + break label$36; + } + $383 = HEAP32[($0_1 + 8 | 0) >> 2] | 0; + } + $6_1 = $383; + HEAP32[($0_1 + 8 | 0) >> 2] = $1_1; + HEAP32[($6_1 + 12 | 0) >> 2] = $1_1; + HEAP32[($1_1 + 12 | 0) >> 2] = $0_1; + HEAP32[($1_1 + 8 | 0) >> 2] = $6_1; + break label$34; + } + $0_1 = $3_1 + $5_1 | 0; + HEAP32[($2_1 + 4 | 0) >> 2] = $0_1 | 3 | 0; + $0_1 = $0_1 + $2_1 | 0; + HEAP32[($0_1 + 4 | 0) >> 2] = HEAP32[($0_1 + 4 | 0) >> 2] | 0 | 1 | 0; + break label$33; + } + HEAP32[1050140 >> 2] = $4_1; + HEAP32[1050132 >> 2] = $3_1; + } + return $2_1 + 8 | 0 | 0; + } + if (!($0_1 | $1_1 | 0)) { + $1_1 = 0; + $0_1 = 2 << $7_1 | 0; + $0_1 = ($0_1 | (0 - $0_1 | 0) | 0) & $8_1 | 0; + if (!$0_1) { + break label$5 + } + $0_1 = HEAP32[(((__wasm_ctz_i32($0_1 | 0) | 0) << 2 | 0) + 1049716 | 0) >> 2] | 0; + } + if (!$0_1) { + break label$6 + } + } + label$39 : while (1) { + $4_1 = (HEAP32[($0_1 + 4 | 0) >> 2] | 0) & -8 | 0; + $6_1 = $4_1 - $5_1 | 0; + $7_1 = $6_1 >>> 0 < $3_1 >>> 0; + $8_1 = $7_1 ? $0_1 : $1_1; + $2_1 = HEAP32[($0_1 + 16 | 0) >> 2] | 0; + if (!$2_1) { + $2_1 = HEAP32[($0_1 + 20 | 0) >> 2] | 0 + } + $0_1 = $4_1 >>> 0 < $5_1 >>> 0; + $1_1 = $0_1 ? $1_1 : $8_1; + $3_1 = $0_1 ? $3_1 : $7_1 ? $6_1 : $3_1; + $0_1 = $2_1; + if ($0_1) { + continue label$39 + } + break label$39; + }; + } + if (!$1_1) { + break label$5 + } + $0_1 = HEAP32[1050132 >> 2] | 0; + if ($5_1 >>> 0 <= $0_1 >>> 0 & $3_1 >>> 0 >= ($0_1 - $5_1 | 0) >>> 0 | 0) { + break label$5 + } + $7_1 = HEAP32[($1_1 + 24 | 0) >> 2] | 0; + label$41 : { + label$42 : { + $0_1 = HEAP32[($1_1 + 12 | 0) >> 2] | 0; + if (($1_1 | 0) == ($0_1 | 0)) { + $0_1 = HEAP32[($1_1 + 20 | 0) >> 2] | 0; + $2_1 = HEAP32[($1_1 + ($0_1 ? 20 : 16) | 0) >> 2] | 0; + if ($2_1) { + break label$42 + } + $0_1 = 0; + break label$41; + } + $2_1 = HEAP32[($1_1 + 8 | 0) >> 2] | 0; + HEAP32[($2_1 + 12 | 0) >> 2] = $0_1; + HEAP32[($0_1 + 8 | 0) >> 2] = $2_1; + break label$41; + } + $4_1 = $0_1 ? $1_1 + 20 | 0 : $1_1 + 16 | 0; + label$44 : while (1) { + $6_1 = $4_1; + $0_1 = $2_1; + $2_1 = HEAP32[($0_1 + 20 | 0) >> 2] | 0; + $4_1 = $2_1 ? $0_1 + 20 | 0 : $0_1 + 16 | 0; + $2_1 = HEAP32[($0_1 + ($2_1 ? 20 : 16) | 0) >> 2] | 0; + if ($2_1) { + continue label$44 + } + break label$44; + }; + HEAP32[$6_1 >> 2] = 0; + } + if (!$7_1) { + break label$2 + } + $2_1 = ((HEAP32[($1_1 + 28 | 0) >> 2] | 0) << 2 | 0) + 1049716 | 0; + if (($1_1 | 0) != (HEAP32[$2_1 >> 2] | 0 | 0)) { + HEAP32[($7_1 + ((HEAP32[($7_1 + 16 | 0) >> 2] | 0 | 0) == ($1_1 | 0) ? 16 : 20) | 0) >> 2] = $0_1; + if (!$0_1) { + break label$2 + } + break label$3; + } + HEAP32[$2_1 >> 2] = $0_1; + if ($0_1) { + break label$3 + } + (wasm2js_i32$0 = 1050128, wasm2js_i32$1 = (HEAP32[1050128 >> 2] | 0) & (__wasm_rotl_i32(-2 | 0, HEAP32[($1_1 + 28 | 0) >> 2] | 0 | 0) | 0) | 0), HEAP32[wasm2js_i32$0 >> 2] = wasm2js_i32$1; + break label$2; + } + label$46 : { + label$47 : { + label$48 : { + label$49 : { + label$50 : { + $1_1 = HEAP32[1050132 >> 2] | 0; + if ($5_1 >>> 0 > $1_1 >>> 0) { + $0_1 = HEAP32[1050136 >> 2] | 0; + if ($5_1 >>> 0 >= $0_1 >>> 0) { + $3_1 = 0; + $0_1 = $5_1 + 65583 | 0; + $1_1 = __wasm_memory_grow($0_1 >>> 16 | 0 | 0); + $4_1 = ($1_1 | 0) == (-1 | 0); + if ($4_1) { + break label$4 + } + $2_1 = $1_1 << 16 | 0; + if (!$2_1) { + break label$4 + } + $3_1 = $4_1 ? 0 : $0_1 & -65536 | 0; + $0_1 = $3_1 + (HEAP32[1050148 >> 2] | 0) | 0; + HEAP32[1050148 >> 2] = $0_1; + $1_1 = HEAP32[1050152 >> 2] | 0; + HEAP32[1050152 >> 2] = $0_1 >>> 0 < $1_1 >>> 0 ? $1_1 : $0_1; + label$53 : { + label$54 : { + $1_1 = HEAP32[1050144 >> 2] | 0; + if ($1_1) { + $0_1 = 1049844; + label$56 : while (1) { + $4_1 = HEAP32[$0_1 >> 2] | 0; + $6_1 = HEAP32[($0_1 + 4 | 0) >> 2] | 0; + if (($4_1 + $6_1 | 0 | 0) == ($2_1 | 0)) { + break label$54 + } + $0_1 = HEAP32[($0_1 + 8 | 0) >> 2] | 0; + if ($0_1) { + continue label$56 + } + break label$56; + }; + break label$53; + } + $0_1 = HEAP32[1050160 >> 2] | 0; + if (!($0_1 >>> 0 <= $2_1 >>> 0 ? $0_1 : 0)) { + HEAP32[1050160 >> 2] = $2_1 + } + HEAP32[1050164 >> 2] = 4095; + HEAP32[1049848 >> 2] = $3_1; + HEAP32[1049844 >> 2] = $2_1; + HEAP32[1049872 >> 2] = 1049860; + HEAP32[1049880 >> 2] = 1049868; + HEAP32[1049868 >> 2] = 1049860; + HEAP32[1049888 >> 2] = 1049876; + HEAP32[1049876 >> 2] = 1049868; + HEAP32[1049896 >> 2] = 1049884; + HEAP32[1049884 >> 2] = 1049876; + HEAP32[1049904 >> 2] = 1049892; + HEAP32[1049892 >> 2] = 1049884; + HEAP32[1049912 >> 2] = 1049900; + HEAP32[1049900 >> 2] = 1049892; + HEAP32[1049920 >> 2] = 1049908; + HEAP32[1049908 >> 2] = 1049900; + HEAP32[1049928 >> 2] = 1049916; + HEAP32[1049916 >> 2] = 1049908; + HEAP32[1049856 >> 2] = 0; + HEAP32[1049936 >> 2] = 1049924; + HEAP32[1049924 >> 2] = 1049916; + HEAP32[1049932 >> 2] = 1049924; + HEAP32[1049944 >> 2] = 1049932; + HEAP32[1049940 >> 2] = 1049932; + HEAP32[1049952 >> 2] = 1049940; + HEAP32[1049948 >> 2] = 1049940; + HEAP32[1049960 >> 2] = 1049948; + HEAP32[1049956 >> 2] = 1049948; + HEAP32[1049968 >> 2] = 1049956; + HEAP32[1049964 >> 2] = 1049956; + HEAP32[1049976 >> 2] = 1049964; + HEAP32[1049972 >> 2] = 1049964; + HEAP32[1049984 >> 2] = 1049972; + HEAP32[1049980 >> 2] = 1049972; + HEAP32[1049992 >> 2] = 1049980; + HEAP32[1049988 >> 2] = 1049980; + HEAP32[105e4 >> 2] = 1049988; + HEAP32[1050008 >> 2] = 1049996; + HEAP32[1049996 >> 2] = 1049988; + HEAP32[1050016 >> 2] = 1050004; + HEAP32[1050004 >> 2] = 1049996; + HEAP32[1050024 >> 2] = 1050012; + HEAP32[1050012 >> 2] = 1050004; + HEAP32[1050032 >> 2] = 1050020; + HEAP32[1050020 >> 2] = 1050012; + HEAP32[1050040 >> 2] = 1050028; + HEAP32[1050028 >> 2] = 1050020; + HEAP32[1050048 >> 2] = 1050036; + HEAP32[1050036 >> 2] = 1050028; + HEAP32[1050056 >> 2] = 1050044; + HEAP32[1050044 >> 2] = 1050036; + HEAP32[1050064 >> 2] = 1050052; + HEAP32[1050052 >> 2] = 1050044; + HEAP32[1050072 >> 2] = 1050060; + HEAP32[1050060 >> 2] = 1050052; + HEAP32[1050080 >> 2] = 1050068; + HEAP32[1050068 >> 2] = 1050060; + HEAP32[1050088 >> 2] = 1050076; + HEAP32[1050076 >> 2] = 1050068; + HEAP32[1050096 >> 2] = 1050084; + HEAP32[1050084 >> 2] = 1050076; + HEAP32[1050104 >> 2] = 1050092; + HEAP32[1050092 >> 2] = 1050084; + HEAP32[1050112 >> 2] = 1050100; + HEAP32[1050100 >> 2] = 1050092; + HEAP32[1050120 >> 2] = 1050108; + HEAP32[1050108 >> 2] = 1050100; + HEAP32[1050144 >> 2] = $2_1; + HEAP32[1050116 >> 2] = 1050108; + $0_1 = $3_1 - 40 | 0; + HEAP32[1050136 >> 2] = $0_1; + HEAP32[($2_1 + 4 | 0) >> 2] = $0_1 | 1 | 0; + HEAP32[(($0_1 + $2_1 | 0) + 4 | 0) >> 2] = 40; + HEAP32[1050156 >> 2] = 2097152; + break label$46; + } + if ($1_1 >>> 0 < $4_1 >>> 0 | $1_1 >>> 0 >= $2_1 >>> 0 | 0) { + break label$53 + } + if (!(HEAP32[($0_1 + 12 | 0) >> 2] | 0)) { + break label$50 + } + } + $0_1 = HEAP32[1050160 >> 2] | 0; + HEAP32[1050160 >> 2] = $0_1 >>> 0 < $2_1 >>> 0 ? $0_1 : $2_1; + $4_1 = $2_1 + $3_1 | 0; + $0_1 = 1049844; + label$58 : { + label$59 : { + label$60 : while (1) { + $6_1 = HEAP32[$0_1 >> 2] | 0; + if (($4_1 | 0) != ($6_1 | 0)) { + $0_1 = HEAP32[($0_1 + 8 | 0) >> 2] | 0; + if ($0_1) { + continue label$60 + } + break label$59; + } + break label$60; + }; + if (!(HEAP32[($0_1 + 12 | 0) >> 2] | 0)) { + break label$58 + } + } + $0_1 = 1049844; + label$62 : while (1) { + label$63 : { + $4_1 = HEAP32[$0_1 >> 2] | 0; + if ($1_1 >>> 0 >= $4_1 >>> 0) { + $6_1 = $4_1 + (HEAP32[($0_1 + 4 | 0) >> 2] | 0) | 0; + if ($1_1 >>> 0 < $6_1 >>> 0) { + break label$63 + } + } + $0_1 = HEAP32[($0_1 + 8 | 0) >> 2] | 0; + continue label$62; + } + break label$62; + }; + HEAP32[1050144 >> 2] = $2_1; + $0_1 = $3_1 - 40 | 0; + HEAP32[1050136 >> 2] = $0_1; + HEAP32[($2_1 + 4 | 0) >> 2] = $0_1 | 1 | 0; + HEAP32[(($0_1 + $2_1 | 0) + 4 | 0) >> 2] = 40; + HEAP32[1050156 >> 2] = 2097152; + $0_1 = (($6_1 - 32 | 0) & -8 | 0) - 8 | 0; + $4_1 = $0_1 >>> 0 < ($1_1 + 16 | 0) >>> 0 ? $1_1 : $0_1; + HEAP32[($4_1 + 4 | 0) >> 2] = 27; + i64toi32_i32$2 = 1049844; + i64toi32_i32$0 = HEAP32[i64toi32_i32$2 >> 2] | 0; + i64toi32_i32$1 = HEAP32[(i64toi32_i32$2 + 4 | 0) >> 2] | 0; + $9_1 = i64toi32_i32$0; + $9$hi = i64toi32_i32$1; + i64toi32_i32$2 = 1049852; + i64toi32_i32$1 = HEAP32[i64toi32_i32$2 >> 2] | 0; + i64toi32_i32$0 = HEAP32[(i64toi32_i32$2 + 4 | 0) >> 2] | 0; + $691 = i64toi32_i32$1; + i64toi32_i32$1 = $4_1 + 16 | 0; + HEAP32[i64toi32_i32$1 >> 2] = $691; + HEAP32[(i64toi32_i32$1 + 4 | 0) >> 2] = i64toi32_i32$0; + i64toi32_i32$0 = $9$hi; + i64toi32_i32$1 = $4_1; + HEAP32[($4_1 + 8 | 0) >> 2] = $9_1; + HEAP32[($4_1 + 12 | 0) >> 2] = i64toi32_i32$0; + HEAP32[1049848 >> 2] = $3_1; + HEAP32[1049844 >> 2] = $2_1; + HEAP32[1049852 >> 2] = $4_1 + 8 | 0; + HEAP32[1049856 >> 2] = 0; + $0_1 = $4_1 + 28 | 0; + label$65 : while (1) { + HEAP32[$0_1 >> 2] = 7; + $0_1 = $0_1 + 4 | 0; + if ($0_1 >>> 0 < $6_1 >>> 0) { + continue label$65 + } + break label$65; + }; + if (($1_1 | 0) == ($4_1 | 0)) { + break label$46 + } + HEAP32[($4_1 + 4 | 0) >> 2] = (HEAP32[($4_1 + 4 | 0) >> 2] | 0) & -2 | 0; + $0_1 = $4_1 - $1_1 | 0; + HEAP32[($1_1 + 4 | 0) >> 2] = $0_1 | 1 | 0; + HEAP32[$4_1 >> 2] = $0_1; + if ($0_1 >>> 0 >= 256 >>> 0) { + $54($1_1 | 0, $0_1 | 0); + break label$46; + } + $2_1 = ($0_1 & 248 | 0) + 1049860 | 0; + label$67 : { + $4_1 = HEAP32[1050124 >> 2] | 0; + $0_1 = 1 << ($0_1 >>> 3 | 0) | 0; + if (!($4_1 & $0_1 | 0)) { + HEAP32[1050124 >> 2] = $0_1 | $4_1 | 0; + $740 = $2_1; + break label$67; + } + $740 = HEAP32[($2_1 + 8 | 0) >> 2] | 0; + } + $0_1 = $740; + HEAP32[($2_1 + 8 | 0) >> 2] = $1_1; + HEAP32[($0_1 + 12 | 0) >> 2] = $1_1; + HEAP32[($1_1 + 12 | 0) >> 2] = $2_1; + HEAP32[($1_1 + 8 | 0) >> 2] = $0_1; + break label$46; + } + HEAP32[$0_1 >> 2] = $2_1; + HEAP32[($0_1 + 4 | 0) >> 2] = (HEAP32[($0_1 + 4 | 0) >> 2] | 0) + $3_1 | 0; + HEAP32[($2_1 + 4 | 0) >> 2] = $5_1 | 3 | 0; + $3_1 = (($6_1 + 15 | 0) & -8 | 0) - 8 | 0; + $0_1 = $2_1 + $5_1 | 0; + $5_1 = $3_1 - $0_1 | 0; + if (($3_1 | 0) == (HEAP32[1050144 >> 2] | 0 | 0)) { + break label$49 + } + if (($3_1 | 0) == (HEAP32[1050140 >> 2] | 0 | 0)) { + break label$48 + } + $1_1 = HEAP32[($3_1 + 4 | 0) >> 2] | 0; + if (($1_1 & 3 | 0 | 0) == (1 | 0)) { + $1_1 = $1_1 & -8 | 0; + $16($3_1 | 0, $1_1 | 0); + $5_1 = $1_1 + $5_1 | 0; + $3_1 = $1_1 + $3_1 | 0; + $1_1 = HEAP32[($3_1 + 4 | 0) >> 2] | 0; + } + HEAP32[($3_1 + 4 | 0) >> 2] = $1_1 & -2 | 0; + HEAP32[($0_1 + 4 | 0) >> 2] = $5_1 | 1 | 0; + HEAP32[($0_1 + $5_1 | 0) >> 2] = $5_1; + if ($5_1 >>> 0 >= 256 >>> 0) { + $54($0_1 | 0, $5_1 | 0); + break label$47; + } + $1_1 = ($5_1 & 248 | 0) + 1049860 | 0; + label$71 : { + $4_1 = HEAP32[1050124 >> 2] | 0; + $3_1 = 1 << ($5_1 >>> 3 | 0) | 0; + if (!($4_1 & $3_1 | 0)) { + HEAP32[1050124 >> 2] = $3_1 | $4_1 | 0; + $824 = $1_1; + break label$71; + } + $824 = HEAP32[($1_1 + 8 | 0) >> 2] | 0; + } + $4_1 = $824; + HEAP32[($1_1 + 8 | 0) >> 2] = $0_1; + HEAP32[($4_1 + 12 | 0) >> 2] = $0_1; + HEAP32[($0_1 + 12 | 0) >> 2] = $1_1; + HEAP32[($0_1 + 8 | 0) >> 2] = $4_1; + break label$47; + } + $1_1 = $0_1 - $5_1 | 0; + HEAP32[1050136 >> 2] = $1_1; + $0_1 = HEAP32[1050144 >> 2] | 0; + $2_1 = $0_1 + $5_1 | 0; + HEAP32[1050144 >> 2] = $2_1; + HEAP32[($2_1 + 4 | 0) >> 2] = $1_1 | 1 | 0; + HEAP32[($0_1 + 4 | 0) >> 2] = $5_1 | 3 | 0; + $3_1 = $0_1 + 8 | 0; + break label$4; + } + $0_1 = HEAP32[1050140 >> 2] | 0; + label$73 : { + $2_1 = $1_1 - $5_1 | 0; + if ($2_1 >>> 0 <= 15 >>> 0) { + HEAP32[1050140 >> 2] = 0; + HEAP32[1050132 >> 2] = 0; + HEAP32[($0_1 + 4 | 0) >> 2] = $1_1 | 3 | 0; + $1_1 = $0_1 + $1_1 | 0; + HEAP32[($1_1 + 4 | 0) >> 2] = HEAP32[($1_1 + 4 | 0) >> 2] | 0 | 1 | 0; + break label$73; + } + HEAP32[1050132 >> 2] = $2_1; + $4_1 = $0_1 + $5_1 | 0; + HEAP32[1050140 >> 2] = $4_1; + HEAP32[($4_1 + 4 | 0) >> 2] = $2_1 | 1 | 0; + HEAP32[($0_1 + $1_1 | 0) >> 2] = $2_1; + HEAP32[($0_1 + 4 | 0) >> 2] = $5_1 | 3 | 0; + } + break label$1; + } + HEAP32[($0_1 + 4 | 0) >> 2] = $3_1 + $6_1 | 0; + $0_1 = HEAP32[1050144 >> 2] | 0; + $1_1 = ($0_1 + 15 | 0) & -8 | 0; + $2_1 = $1_1 - 8 | 0; + HEAP32[1050144 >> 2] = $2_1; + $4_1 = (HEAP32[1050136 >> 2] | 0) + $3_1 | 0; + $1_1 = ($4_1 + ($0_1 - $1_1 | 0) | 0) + 8 | 0; + HEAP32[1050136 >> 2] = $1_1; + HEAP32[($2_1 + 4 | 0) >> 2] = $1_1 | 1 | 0; + HEAP32[(($0_1 + $4_1 | 0) + 4 | 0) >> 2] = 40; + HEAP32[1050156 >> 2] = 2097152; + break label$46; + } + HEAP32[1050144 >> 2] = $0_1; + $1_1 = (HEAP32[1050136 >> 2] | 0) + $5_1 | 0; + HEAP32[1050136 >> 2] = $1_1; + HEAP32[($0_1 + 4 | 0) >> 2] = $1_1 | 1 | 0; + break label$47; + } + HEAP32[1050140 >> 2] = $0_1; + $1_1 = (HEAP32[1050132 >> 2] | 0) + $5_1 | 0; + HEAP32[1050132 >> 2] = $1_1; + HEAP32[($0_1 + 4 | 0) >> 2] = $1_1 | 1 | 0; + HEAP32[($0_1 + $1_1 | 0) >> 2] = $1_1; + } + return $2_1 + 8 | 0 | 0; + } + $3_1 = 0; + $0_1 = HEAP32[1050136 >> 2] | 0; + if ($0_1 >>> 0 <= $5_1 >>> 0) { + break label$4 + } + $1_1 = $0_1 - $5_1 | 0; + HEAP32[1050136 >> 2] = $1_1; + $0_1 = HEAP32[1050144 >> 2] | 0; + $2_1 = $0_1 + $5_1 | 0; + HEAP32[1050144 >> 2] = $2_1; + HEAP32[($2_1 + 4 | 0) >> 2] = $1_1 | 1 | 0; + HEAP32[($0_1 + 4 | 0) >> 2] = $5_1 | 3 | 0; + break label$1; + } + return $3_1 | 0; + } + HEAP32[($0_1 + 24 | 0) >> 2] = $7_1; + $2_1 = HEAP32[($1_1 + 16 | 0) >> 2] | 0; + if ($2_1) { + HEAP32[($0_1 + 16 | 0) >> 2] = $2_1; + HEAP32[($2_1 + 24 | 0) >> 2] = $0_1; + } + $2_1 = HEAP32[($1_1 + 20 | 0) >> 2] | 0; + if (!$2_1) { + break label$2 + } + HEAP32[($0_1 + 20 | 0) >> 2] = $2_1; + HEAP32[($2_1 + 24 | 0) >> 2] = $0_1; + } + label$76 : { + if ($3_1 >>> 0 >= 16 >>> 0) { + HEAP32[($1_1 + 4 | 0) >> 2] = $5_1 | 3 | 0; + $0_1 = $1_1 + $5_1 | 0; + HEAP32[($0_1 + 4 | 0) >> 2] = $3_1 | 1 | 0; + HEAP32[($0_1 + $3_1 | 0) >> 2] = $3_1; + if ($3_1 >>> 0 >= 256 >>> 0) { + $54($0_1 | 0, $3_1 | 0); + break label$76; + } + $2_1 = ($3_1 & 248 | 0) + 1049860 | 0; + label$79 : { + $4_1 = HEAP32[1050124 >> 2] | 0; + $3_1 = 1 << ($3_1 >>> 3 | 0) | 0; + if (!($4_1 & $3_1 | 0)) { + HEAP32[1050124 >> 2] = $3_1 | $4_1 | 0; + $1004 = $2_1; + break label$79; + } + $1004 = HEAP32[($2_1 + 8 | 0) >> 2] | 0; + } + $4_1 = $1004; + HEAP32[($2_1 + 8 | 0) >> 2] = $0_1; + HEAP32[($4_1 + 12 | 0) >> 2] = $0_1; + HEAP32[($0_1 + 12 | 0) >> 2] = $2_1; + HEAP32[($0_1 + 8 | 0) >> 2] = $4_1; + break label$76; + } + $0_1 = $3_1 + $5_1 | 0; + HEAP32[($1_1 + 4 | 0) >> 2] = $0_1 | 3 | 0; + $0_1 = $0_1 + $1_1 | 0; + HEAP32[($0_1 + 4 | 0) >> 2] = HEAP32[($0_1 + 4 | 0) >> 2] | 0 | 1 | 0; + } + return $1_1 + 8 | 0 | 0; + } + return $0_1 + 8 | 0 | 0; + } + + function $7($0_1, $1_1) { + $0_1 = $0_1 | 0; + $1_1 = $1_1 | 0; + return FUNCTION_TABLE[HEAP32[((HEAP32[($1_1 + 24 | 0) >> 2] | 0) + 12 | 0) >> 2] | 0 | 0](HEAP32[($1_1 + 20 | 0) >> 2] | 0, 1049684, 5) | 0 | 0; + } + + function $8($0_1) { + $0_1 = $0_1 | 0; + var $1_1 = 0; + $1_1 = HEAP32[$0_1 >> 2] | 0; + if ($1_1) { + $9(HEAP32[($0_1 + 4 | 0) >> 2] | 0 | 0, $1_1 | 0) + } + } + + function $9($0_1, $1_1) { + $0_1 = $0_1 | 0; + $1_1 = $1_1 | 0; + var $2_1 = 0, $3_1 = 0; + label$1 : { + $2_1 = HEAP32[($0_1 - 4 | 0) >> 2] | 0; + $3_1 = $2_1 & -8 | 0; + $2_1 = $2_1 & 3 | 0; + if ($3_1 >>> 0 >= (($2_1 ? 4 : 8) + $1_1 | 0) >>> 0) { + if ($3_1 >>> 0 > ($1_1 + 39 | 0) >>> 0 ? $2_1 : 0) { + break label$1 + } + $14($0_1 | 0); + return; + } + $15(1049557 | 0, 1049604 | 0); + wasm2js_trap(); + } + $15(1049620 | 0, 1049668 | 0); + wasm2js_trap(); + } + + function $10($0_1, $1_1, $2_1) { + $0_1 = $0_1 | 0; + $1_1 = $1_1 | 0; + $2_1 = $2_1 | 0; + var $3_1 = 0; + $3_1 = HEAP32[($0_1 + 8 | 0) >> 2] | 0; + if ($2_1 >>> 0 > ((HEAP32[$0_1 >> 2] | 0) - $3_1 | 0) >>> 0) { + $3($0_1 | 0, $3_1 | 0, $2_1 | 0); + $3_1 = HEAP32[($0_1 + 8 | 0) >> 2] | 0; + } + $57((HEAP32[($0_1 + 4 | 0) >> 2] | 0) + $3_1 | 0 | 0, $1_1 | 0, $2_1 | 0) | 0; + HEAP32[($0_1 + 8 | 0) >> 2] = $2_1 + $3_1 | 0; + return 0 | 0; + } + + function $11($0_1, $1_1) { + $0_1 = $0_1 | 0; + $1_1 = $1_1 | 0; + var $2_1 = 0, $3_1 = 0, $5_1 = 0, $4_1 = 0, $31_1 = 0, $6_1 = 0, $7_1 = 0, $87 = 0, $78 = 0; + $3_1 = global$0 - 16 | 0; + global$0 = $3_1; + label$1 : { + label$2 : { + label$3 : { + if ($1_1 >>> 0 >= 128 >>> 0) { + HEAP32[($3_1 + 12 | 0) >> 2] = 0; + if ($1_1 >>> 0 < 2048 >>> 0) { + break label$3 + } + if ($1_1 >>> 0 < 65536 >>> 0) { + HEAP8[($3_1 + 14 | 0) >> 0] = $1_1 & 63 | 0 | 128 | 0; + HEAP8[($3_1 + 12 | 0) >> 0] = $1_1 >>> 12 | 0 | 224 | 0; + HEAP8[($3_1 + 13 | 0) >> 0] = ($1_1 >>> 6 | 0) & 63 | 0 | 128 | 0; + $31_1 = 3; + break label$2; + } + HEAP8[($3_1 + 15 | 0) >> 0] = $1_1 & 63 | 0 | 128 | 0; + HEAP8[($3_1 + 12 | 0) >> 0] = $1_1 >>> 18 | 0 | 240 | 0; + HEAP8[($3_1 + 14 | 0) >> 0] = ($1_1 >>> 6 | 0) & 63 | 0 | 128 | 0; + HEAP8[($3_1 + 13 | 0) >> 0] = ($1_1 >>> 12 | 0) & 63 | 0 | 128 | 0; + $31_1 = 4; + break label$2; + } + $6_1 = HEAP32[($0_1 + 8 | 0) >> 2] | 0; + $4_1 = HEAP32[$0_1 >> 2] | 0; + if (($6_1 | 0) == ($4_1 | 0)) { + $2_1 = global$0 - 32 | 0; + global$0 = $2_1; + if (($4_1 | 0) == (-1 | 0)) { + $0(0 | 0); + wasm2js_trap(); + } + $5_1 = $4_1 << 1 | 0; + $7_1 = $4_1 + 1 | 0; + $5_1 = $5_1 >>> 0 > $7_1 >>> 0 ? $5_1 : $7_1; + $5_1 = $5_1 >>> 0 <= 8 >>> 0 ? 8 : $5_1; + if (($5_1 | 0) < (0 | 0)) { + $0(0 | 0); + wasm2js_trap(); + } + $78 = $2_1; + if ($4_1) { + HEAP32[($2_1 + 28 | 0) >> 2] = $4_1; + HEAP32[($2_1 + 20 | 0) >> 2] = HEAP32[($0_1 + 4 | 0) >> 2] | 0; + $87 = 1; + } else { + $87 = 0 + } + HEAP32[($78 + 24 | 0) >> 2] = $87; + $4($2_1 + 8 | 0 | 0, $5_1 | 0, $2_1 + 20 | 0 | 0); + if ((HEAP32[($2_1 + 8 | 0) >> 2] | 0 | 0) == (1 | 0)) { + HEAP32[($2_1 + 16 | 0) >> 2] | 0; + $0(HEAP32[($2_1 + 12 | 0) >> 2] | 0 | 0); + wasm2js_trap(); + } + $4_1 = HEAP32[($2_1 + 12 | 0) >> 2] | 0; + HEAP32[$0_1 >> 2] = $5_1; + HEAP32[($0_1 + 4 | 0) >> 2] = $4_1; + global$0 = $2_1 + 32 | 0; + } + HEAP32[($0_1 + 8 | 0) >> 2] = $6_1 + 1 | 0; + HEAP8[((HEAP32[($0_1 + 4 | 0) >> 2] | 0) + $6_1 | 0) >> 0] = $1_1; + break label$1; + } + HEAP8[($3_1 + 13 | 0) >> 0] = $1_1 & 63 | 0 | 128 | 0; + HEAP8[($3_1 + 12 | 0) >> 0] = $1_1 >>> 6 | 0 | 192 | 0; + $31_1 = 2; + } + $1_1 = $31_1; + $2_1 = HEAP32[($0_1 + 8 | 0) >> 2] | 0; + if ($1_1 >>> 0 > ((HEAP32[$0_1 >> 2] | 0) - $2_1 | 0) >>> 0) { + $3($0_1 | 0, $2_1 | 0, $1_1 | 0); + $2_1 = HEAP32[($0_1 + 8 | 0) >> 2] | 0; + } + $57((HEAP32[($0_1 + 4 | 0) >> 2] | 0) + $2_1 | 0 | 0, $3_1 + 12 | 0 | 0, $1_1 | 0) | 0; + HEAP32[($0_1 + 8 | 0) >> 2] = $1_1 + $2_1 | 0; + } + global$0 = $3_1 + 16 | 0; + return 0 | 0; + } + + function $12($0_1, $1_1) { + $0_1 = $0_1 | 0; + $1_1 = $1_1 | 0; + return $13($0_1 | 0, 1048576 | 0, $1_1 | 0) | 0 | 0; + } + + function $13($0_1, $1_1, $2_1) { + $0_1 = $0_1 | 0; + $1_1 = $1_1 | 0; + $2_1 = $2_1 | 0; + var $3_1 = 0, $4_1 = 0, $5_1 = 0, $6_1 = 0, $7_1 = 0, $8_1 = 0, $10_1 = 0, $9_1 = 0, $12_1 = 0, $190 = 0, $11_1 = 0; + $3_1 = global$0 - 48 | 0; + global$0 = $3_1; + HEAP8[($3_1 + 44 | 0) >> 0] = 3; + HEAP32[($3_1 + 28 | 0) >> 2] = 32; + HEAP32[($3_1 + 40 | 0) >> 2] = 0; + HEAP32[($3_1 + 36 | 0) >> 2] = $1_1; + HEAP32[($3_1 + 32 | 0) >> 2] = $0_1; + HEAP32[($3_1 + 20 | 0) >> 2] = 0; + HEAP32[($3_1 + 12 | 0) >> 2] = 0; + label$1 : { + label$2 : { + label$3 : { + label$4 : { + $10_1 = HEAP32[($2_1 + 16 | 0) >> 2] | 0; + if (!$10_1) { + $0_1 = HEAP32[($2_1 + 12 | 0) >> 2] | 0; + if (!$0_1) { + break label$4 + } + $1_1 = HEAP32[($2_1 + 8 | 0) >> 2] | 0; + $5_1 = $0_1 << 3 | 0; + $7_1 = (($0_1 - 1 | 0) & 536870911 | 0) + 1 | 0; + $0_1 = HEAP32[$2_1 >> 2] | 0; + label$6 : while (1) { + $4_1 = HEAP32[($0_1 + 4 | 0) >> 2] | 0; + if ($4_1) { + if (FUNCTION_TABLE[HEAP32[((HEAP32[($3_1 + 36 | 0) >> 2] | 0) + 12 | 0) >> 2] | 0 | 0](HEAP32[($3_1 + 32 | 0) >> 2] | 0, HEAP32[$0_1 >> 2] | 0, $4_1) | 0) { + break label$3 + } + } + if (FUNCTION_TABLE[HEAP32[($1_1 + 4 | 0) >> 2] | 0 | 0](HEAP32[$1_1 >> 2] | 0, $3_1 + 12 | 0) | 0) { + break label$3 + } + $1_1 = $1_1 + 8 | 0; + $0_1 = $0_1 + 8 | 0; + $5_1 = $5_1 - 8 | 0; + if ($5_1) { + continue label$6 + } + break label$6; + }; + break label$4; + } + $0_1 = HEAP32[($2_1 + 20 | 0) >> 2] | 0; + if (!$0_1) { + break label$4 + } + $11_1 = $0_1 << 5 | 0; + $7_1 = (($0_1 - 1 | 0) & 134217727 | 0) + 1 | 0; + $8_1 = HEAP32[($2_1 + 8 | 0) >> 2] | 0; + $0_1 = HEAP32[$2_1 >> 2] | 0; + label$8 : while (1) { + $1_1 = HEAP32[($0_1 + 4 | 0) >> 2] | 0; + if ($1_1) { + if (FUNCTION_TABLE[HEAP32[((HEAP32[($3_1 + 36 | 0) >> 2] | 0) + 12 | 0) >> 2] | 0 | 0](HEAP32[($3_1 + 32 | 0) >> 2] | 0, HEAP32[$0_1 >> 2] | 0, $1_1) | 0) { + break label$3 + } + } + $1_1 = $5_1 + $10_1 | 0; + HEAP32[($3_1 + 28 | 0) >> 2] = HEAP32[($1_1 + 16 | 0) >> 2] | 0; + HEAP8[($3_1 + 44 | 0) >> 0] = HEAPU8[($1_1 + 28 | 0) >> 0] | 0; + HEAP32[($3_1 + 40 | 0) >> 2] = HEAP32[($1_1 + 24 | 0) >> 2] | 0; + $4_1 = HEAP32[($1_1 + 12 | 0) >> 2] | 0; + $9_1 = 0; + $6_1 = 0; + label$10 : { + label$11 : { + switch ((HEAP32[($1_1 + 8 | 0) >> 2] | 0) - 1 | 0 | 0) { + case 0: + $12_1 = ($4_1 << 3 | 0) + $8_1 | 0; + if (HEAP32[($12_1 + 4 | 0) >> 2] | 0) { + break label$10 + } + $4_1 = HEAP32[$12_1 >> 2] | 0; + break; + case 1: + break label$10; + default: + break label$11; + }; + } + $6_1 = 1; + } + HEAP32[($3_1 + 16 | 0) >> 2] = $4_1; + HEAP32[($3_1 + 12 | 0) >> 2] = $6_1; + $4_1 = HEAP32[($1_1 + 4 | 0) >> 2] | 0; + label$13 : { + label$14 : { + switch ((HEAP32[$1_1 >> 2] | 0) - 1 | 0 | 0) { + case 0: + $6_1 = ($4_1 << 3 | 0) + $8_1 | 0; + if (HEAP32[($6_1 + 4 | 0) >> 2] | 0) { + break label$13 + } + $4_1 = HEAP32[$6_1 >> 2] | 0; + break; + case 1: + break label$13; + default: + break label$14; + }; + } + $9_1 = 1; + } + HEAP32[($3_1 + 24 | 0) >> 2] = $4_1; + HEAP32[($3_1 + 20 | 0) >> 2] = $9_1; + $1_1 = $8_1 + ((HEAP32[($1_1 + 20 | 0) >> 2] | 0) << 3 | 0) | 0; + if (FUNCTION_TABLE[HEAP32[($1_1 + 4 | 0) >> 2] | 0 | 0](HEAP32[$1_1 >> 2] | 0, $3_1 + 12 | 0) | 0) { + break label$3 + } + $0_1 = $0_1 + 8 | 0; + $5_1 = $5_1 + 32 | 0; + if (($11_1 | 0) != ($5_1 | 0)) { + continue label$8 + } + break label$8; + }; + } + if ($7_1 >>> 0 >= (HEAP32[($2_1 + 4 | 0) >> 2] | 0) >>> 0) { + break label$2 + } + $0_1 = (HEAP32[$2_1 >> 2] | 0) + ($7_1 << 3 | 0) | 0; + if (!(FUNCTION_TABLE[HEAP32[((HEAP32[($3_1 + 36 | 0) >> 2] | 0) + 12 | 0) >> 2] | 0 | 0](HEAP32[($3_1 + 32 | 0) >> 2] | 0, HEAP32[$0_1 >> 2] | 0, HEAP32[($0_1 + 4 | 0) >> 2] | 0) | 0)) { + break label$2 + } + } + $190 = 1; + break label$1; + } + $190 = 0; + } + global$0 = $3_1 + 48 | 0; + return $190 | 0; + } + + function $14($0_1) { + $0_1 = $0_1 | 0; + var $1_1 = 0, $2_1 = 0, $3_1 = 0, $4_1 = 0, $5_1 = 0, $167 = 0, $59 = 0; + $1_1 = $0_1 - 8 | 0; + $3_1 = HEAP32[($0_1 - 4 | 0) >> 2] | 0; + $0_1 = $3_1 & -8 | 0; + $2_1 = $1_1 + $0_1 | 0; + label$1 : { + label$2 : { + if ($3_1 & 1 | 0) { + break label$2 + } + if (!($3_1 & 2 | 0)) { + break label$1 + } + $3_1 = HEAP32[$1_1 >> 2] | 0; + $0_1 = $3_1 + $0_1 | 0; + $1_1 = $1_1 - $3_1 | 0; + if (($1_1 | 0) == (HEAP32[1050140 >> 2] | 0 | 0)) { + if (((HEAP32[($2_1 + 4 | 0) >> 2] | 0) & 3 | 0 | 0) != (3 | 0)) { + break label$2 + } + HEAP32[1050132 >> 2] = $0_1; + HEAP32[($2_1 + 4 | 0) >> 2] = (HEAP32[($2_1 + 4 | 0) >> 2] | 0) & -2 | 0; + HEAP32[($1_1 + 4 | 0) >> 2] = $0_1 | 1 | 0; + HEAP32[$2_1 >> 2] = $0_1; + return; + } + $16($1_1 | 0, $3_1 | 0); + } + label$4 : { + label$5 : { + label$6 : { + label$7 : { + label$8 : { + $3_1 = HEAP32[($2_1 + 4 | 0) >> 2] | 0; + if (!($3_1 & 2 | 0)) { + if (($2_1 | 0) == (HEAP32[1050144 >> 2] | 0 | 0)) { + break label$7 + } + if (($2_1 | 0) == (HEAP32[1050140 >> 2] | 0 | 0)) { + break label$6 + } + $59 = $2_1; + $2_1 = $3_1 & -8 | 0; + $16($59 | 0, $2_1 | 0); + $0_1 = $0_1 + $2_1 | 0; + HEAP32[($1_1 + 4 | 0) >> 2] = $0_1 | 1 | 0; + HEAP32[($0_1 + $1_1 | 0) >> 2] = $0_1; + if (($1_1 | 0) != (HEAP32[1050140 >> 2] | 0 | 0)) { + break label$8 + } + HEAP32[1050132 >> 2] = $0_1; + return; + } + HEAP32[($2_1 + 4 | 0) >> 2] = $3_1 & -2 | 0; + HEAP32[($1_1 + 4 | 0) >> 2] = $0_1 | 1 | 0; + HEAP32[($0_1 + $1_1 | 0) >> 2] = $0_1; + } + if ($0_1 >>> 0 < 256 >>> 0) { + break label$5 + } + $54($1_1 | 0, $0_1 | 0); + $1_1 = 0; + $0_1 = (HEAP32[1050164 >> 2] | 0) - 1 | 0; + HEAP32[1050164 >> 2] = $0_1; + if ($0_1) { + break label$1 + } + $0_1 = HEAP32[1049852 >> 2] | 0; + if ($0_1) { + label$11 : while (1) { + $1_1 = $1_1 + 1 | 0; + $0_1 = HEAP32[($0_1 + 8 | 0) >> 2] | 0; + if ($0_1) { + continue label$11 + } + break label$11; + } + } + HEAP32[1050164 >> 2] = $1_1 >>> 0 <= 4095 >>> 0 ? 4095 : $1_1; + return; + } + HEAP32[1050144 >> 2] = $1_1; + $0_1 = (HEAP32[1050136 >> 2] | 0) + $0_1 | 0; + HEAP32[1050136 >> 2] = $0_1; + HEAP32[($1_1 + 4 | 0) >> 2] = $0_1 | 1 | 0; + if ((HEAP32[1050140 >> 2] | 0 | 0) == ($1_1 | 0)) { + HEAP32[1050132 >> 2] = 0; + HEAP32[1050140 >> 2] = 0; + } + $3_1 = HEAP32[1050156 >> 2] | 0; + if ($0_1 >>> 0 <= $3_1 >>> 0) { + break label$1 + } + $2_1 = HEAP32[1050144 >> 2] | 0; + if (!$2_1) { + break label$1 + } + $0_1 = 0; + $4_1 = HEAP32[1050136 >> 2] | 0; + if ($4_1 >>> 0 < 41 >>> 0) { + break label$4 + } + $1_1 = 1049844; + label$13 : while (1) { + $5_1 = HEAP32[$1_1 >> 2] | 0; + if ($2_1 >>> 0 >= $5_1 >>> 0) { + if ($2_1 >>> 0 < ($5_1 + (HEAP32[($1_1 + 4 | 0) >> 2] | 0) | 0) >>> 0) { + break label$4 + } + } + $1_1 = HEAP32[($1_1 + 8 | 0) >> 2] | 0; + continue label$13; + }; + } + HEAP32[1050140 >> 2] = $1_1; + $0_1 = (HEAP32[1050132 >> 2] | 0) + $0_1 | 0; + HEAP32[1050132 >> 2] = $0_1; + HEAP32[($1_1 + 4 | 0) >> 2] = $0_1 | 1 | 0; + HEAP32[($0_1 + $1_1 | 0) >> 2] = $0_1; + return; + } + $2_1 = ($0_1 & 248 | 0) + 1049860 | 0; + label$15 : { + $3_1 = HEAP32[1050124 >> 2] | 0; + $0_1 = 1 << ($0_1 >>> 3 | 0) | 0; + if (!($3_1 & $0_1 | 0)) { + HEAP32[1050124 >> 2] = $0_1 | $3_1 | 0; + $167 = $2_1; + break label$15; + } + $167 = HEAP32[($2_1 + 8 | 0) >> 2] | 0; + } + $0_1 = $167; + HEAP32[($2_1 + 8 | 0) >> 2] = $1_1; + HEAP32[($0_1 + 12 | 0) >> 2] = $1_1; + HEAP32[($1_1 + 12 | 0) >> 2] = $2_1; + HEAP32[($1_1 + 8 | 0) >> 2] = $0_1; + return; + } + $1_1 = HEAP32[1049852 >> 2] | 0; + if ($1_1) { + label$18 : while (1) { + $0_1 = $0_1 + 1 | 0; + $1_1 = HEAP32[($1_1 + 8 | 0) >> 2] | 0; + if ($1_1) { + continue label$18 + } + break label$18; + } + } + HEAP32[1050164 >> 2] = $0_1 >>> 0 <= 4095 >>> 0 ? 4095 : $0_1; + if ($3_1 >>> 0 >= $4_1 >>> 0) { + break label$1 + } + HEAP32[1050156 >> 2] = -1; + } + } + + function $15($0_1, $1_1) { + $0_1 = $0_1 | 0; + $1_1 = $1_1 | 0; + var $2_1 = 0; + $2_1 = global$0 - 32 | 0; + global$0 = $2_1; + HEAP32[($2_1 + 16 | 0) >> 2] = 0; + HEAP32[($2_1 + 4 | 0) >> 2] = 1; + HEAP32[($2_1 + 8 | 0) >> 2] = 4; + HEAP32[($2_1 + 12 | 0) >> 2] = 0; + HEAP32[($2_1 + 28 | 0) >> 2] = 46; + HEAP32[($2_1 + 24 | 0) >> 2] = $0_1; + HEAP32[$2_1 >> 2] = $2_1 + 24 | 0; + $2($2_1 | 0, $1_1 | 0); + wasm2js_trap(); + } + + function $16($0_1, $1_1) { + $0_1 = $0_1 | 0; + $1_1 = $1_1 | 0; + var $2_1 = 0, $3_1 = 0, $4_1 = 0, $5_1 = 0, wasm2js_i32$0 = 0, wasm2js_i32$1 = 0; + $2_1 = HEAP32[($0_1 + 12 | 0) >> 2] | 0; + label$1 : { + label$2 : { + if ($1_1 >>> 0 >= 256 >>> 0) { + $3_1 = HEAP32[($0_1 + 24 | 0) >> 2] | 0; + label$4 : { + label$5 : { + if (($0_1 | 0) == ($2_1 | 0)) { + $2_1 = HEAP32[($0_1 + 20 | 0) >> 2] | 0; + $1_1 = HEAP32[($0_1 + ($2_1 ? 20 : 16) | 0) >> 2] | 0; + if ($1_1) { + break label$5 + } + $2_1 = 0; + break label$4; + } + $1_1 = HEAP32[($0_1 + 8 | 0) >> 2] | 0; + HEAP32[($1_1 + 12 | 0) >> 2] = $2_1; + HEAP32[($2_1 + 8 | 0) >> 2] = $1_1; + break label$4; + } + $4_1 = $2_1 ? $0_1 + 20 | 0 : $0_1 + 16 | 0; + label$7 : while (1) { + $5_1 = $4_1; + $2_1 = $1_1; + $1_1 = HEAP32[($2_1 + 20 | 0) >> 2] | 0; + $4_1 = $1_1 ? $2_1 + 20 | 0 : $2_1 + 16 | 0; + $1_1 = HEAP32[($2_1 + ($1_1 ? 20 : 16) | 0) >> 2] | 0; + if ($1_1) { + continue label$7 + } + break label$7; + }; + HEAP32[$5_1 >> 2] = 0; + } + if (!$3_1) { + break label$1 + } + $1_1 = ((HEAP32[($0_1 + 28 | 0) >> 2] | 0) << 2 | 0) + 1049716 | 0; + if (($0_1 | 0) != (HEAP32[$1_1 >> 2] | 0 | 0)) { + HEAP32[($3_1 + ((HEAP32[($3_1 + 16 | 0) >> 2] | 0 | 0) == ($0_1 | 0) ? 16 : 20) | 0) >> 2] = $2_1; + if (!$2_1) { + break label$1 + } + break label$2; + } + HEAP32[$1_1 >> 2] = $2_1; + if ($2_1) { + break label$2 + } + (wasm2js_i32$0 = 1050128, wasm2js_i32$1 = (HEAP32[1050128 >> 2] | 0) & (__wasm_rotl_i32(-2 | 0, HEAP32[($0_1 + 28 | 0) >> 2] | 0 | 0) | 0) | 0), HEAP32[wasm2js_i32$0 >> 2] = wasm2js_i32$1; + break label$1; + } + $0_1 = HEAP32[($0_1 + 8 | 0) >> 2] | 0; + if (($0_1 | 0) != ($2_1 | 0)) { + HEAP32[($0_1 + 12 | 0) >> 2] = $2_1; + HEAP32[($2_1 + 8 | 0) >> 2] = $0_1; + return; + } + (wasm2js_i32$0 = 1050124, wasm2js_i32$1 = (HEAP32[1050124 >> 2] | 0) & (__wasm_rotl_i32(-2 | 0, $1_1 >>> 3 | 0 | 0) | 0) | 0), HEAP32[wasm2js_i32$0 >> 2] = wasm2js_i32$1; + return; + } + HEAP32[($2_1 + 24 | 0) >> 2] = $3_1; + $1_1 = HEAP32[($0_1 + 16 | 0) >> 2] | 0; + if ($1_1) { + HEAP32[($2_1 + 16 | 0) >> 2] = $1_1; + HEAP32[($1_1 + 24 | 0) >> 2] = $2_1; + } + $0_1 = HEAP32[($0_1 + 20 | 0) >> 2] | 0; + if (!$0_1) { + break label$1 + } + HEAP32[($2_1 + 20 | 0) >> 2] = $0_1; + HEAP32[($0_1 + 24 | 0) >> 2] = $2_1; + } + } + + function $17($0_1, $1_1) { + $0_1 = $0_1 | 0; + $1_1 = $1_1 | 0; + var $2_1 = 0, $3_1 = 0, $99 = 0, $52_1 = 0; + $2_1 = $0_1 + $1_1 | 0; + label$1 : { + label$2 : { + $3_1 = HEAP32[($0_1 + 4 | 0) >> 2] | 0; + if ($3_1 & 1 | 0) { + break label$2 + } + if (!($3_1 & 2 | 0)) { + break label$1 + } + $3_1 = HEAP32[$0_1 >> 2] | 0; + $1_1 = $3_1 + $1_1 | 0; + $0_1 = $0_1 - $3_1 | 0; + if (($0_1 | 0) == (HEAP32[1050140 >> 2] | 0 | 0)) { + if (((HEAP32[($2_1 + 4 | 0) >> 2] | 0) & 3 | 0 | 0) != (3 | 0)) { + break label$2 + } + HEAP32[1050132 >> 2] = $1_1; + HEAP32[($2_1 + 4 | 0) >> 2] = (HEAP32[($2_1 + 4 | 0) >> 2] | 0) & -2 | 0; + HEAP32[($0_1 + 4 | 0) >> 2] = $1_1 | 1 | 0; + HEAP32[$2_1 >> 2] = $1_1; + break label$1; + } + $16($0_1 | 0, $3_1 | 0); + } + label$4 : { + label$5 : { + label$6 : { + $3_1 = HEAP32[($2_1 + 4 | 0) >> 2] | 0; + if (!($3_1 & 2 | 0)) { + if (($2_1 | 0) == (HEAP32[1050144 >> 2] | 0 | 0)) { + break label$5 + } + if (($2_1 | 0) == (HEAP32[1050140 >> 2] | 0 | 0)) { + break label$4 + } + $52_1 = $2_1; + $2_1 = $3_1 & -8 | 0; + $16($52_1 | 0, $2_1 | 0); + $1_1 = $1_1 + $2_1 | 0; + HEAP32[($0_1 + 4 | 0) >> 2] = $1_1 | 1 | 0; + HEAP32[($0_1 + $1_1 | 0) >> 2] = $1_1; + if (($0_1 | 0) != (HEAP32[1050140 >> 2] | 0 | 0)) { + break label$6 + } + HEAP32[1050132 >> 2] = $1_1; + return; + } + HEAP32[($2_1 + 4 | 0) >> 2] = $3_1 & -2 | 0; + HEAP32[($0_1 + 4 | 0) >> 2] = $1_1 | 1 | 0; + HEAP32[($0_1 + $1_1 | 0) >> 2] = $1_1; + } + if ($1_1 >>> 0 >= 256 >>> 0) { + $54($0_1 | 0, $1_1 | 0); + return; + } + $2_1 = ($1_1 & 248 | 0) + 1049860 | 0; + label$9 : { + $3_1 = HEAP32[1050124 >> 2] | 0; + $1_1 = 1 << ($1_1 >>> 3 | 0) | 0; + if (!($3_1 & $1_1 | 0)) { + HEAP32[1050124 >> 2] = $1_1 | $3_1 | 0; + $99 = $2_1; + break label$9; + } + $99 = HEAP32[($2_1 + 8 | 0) >> 2] | 0; + } + $1_1 = $99; + HEAP32[($2_1 + 8 | 0) >> 2] = $0_1; + HEAP32[($1_1 + 12 | 0) >> 2] = $0_1; + HEAP32[($0_1 + 12 | 0) >> 2] = $2_1; + HEAP32[($0_1 + 8 | 0) >> 2] = $1_1; + return; + } + HEAP32[1050144 >> 2] = $0_1; + $1_1 = (HEAP32[1050136 >> 2] | 0) + $1_1 | 0; + HEAP32[1050136 >> 2] = $1_1; + HEAP32[($0_1 + 4 | 0) >> 2] = $1_1 | 1 | 0; + if (($0_1 | 0) != (HEAP32[1050140 >> 2] | 0 | 0)) { + break label$1 + } + HEAP32[1050132 >> 2] = 0; + HEAP32[1050140 >> 2] = 0; + return; + } + HEAP32[1050140 >> 2] = $0_1; + $1_1 = (HEAP32[1050132 >> 2] | 0) + $1_1 | 0; + HEAP32[1050132 >> 2] = $1_1; + HEAP32[($0_1 + 4 | 0) >> 2] = $1_1 | 1 | 0; + HEAP32[($0_1 + $1_1 | 0) >> 2] = $1_1; + } + } + + function $18($0_1) { + $0_1 = $0_1 | 0; + var $1_1 = 0, i64toi32_i32$1 = 0, i64toi32_i32$2 = 0, i64toi32_i32$0 = 0, i64toi32_i32$3 = 0, $15_1 = 0; + $1_1 = global$0 - 48 | 0; + global$0 = $1_1; + HEAP32[$1_1 >> 2] = $0_1; + HEAP32[($1_1 + 4 | 0) >> 2] = 128; + HEAP32[($1_1 + 12 | 0) >> 2] = 2; + HEAP32[($1_1 + 8 | 0) >> 2] = 1049120; + i64toi32_i32$1 = $1_1; + i64toi32_i32$0 = 0; + HEAP32[($1_1 + 20 | 0) >> 2] = 2; + HEAP32[($1_1 + 24 | 0) >> 2] = i64toi32_i32$0; + i64toi32_i32$0 = 0; + i64toi32_i32$2 = $1_1 + 4 | 0; + i64toi32_i32$1 = 1; + i64toi32_i32$3 = 0; + i64toi32_i32$1 = i64toi32_i32$0 | i64toi32_i32$1 | 0; + $15_1 = i64toi32_i32$2 | i64toi32_i32$3 | 0; + i64toi32_i32$2 = $1_1; + HEAP32[($1_1 + 40 | 0) >> 2] = $15_1; + HEAP32[($1_1 + 44 | 0) >> 2] = i64toi32_i32$1; + i64toi32_i32$1 = 0; + i64toi32_i32$0 = $1_1; + i64toi32_i32$2 = 1; + i64toi32_i32$3 = 0; + i64toi32_i32$2 = i64toi32_i32$1 | i64toi32_i32$2 | 0; + i64toi32_i32$0 = $1_1; + HEAP32[($1_1 + 32 | 0) >> 2] = $1_1 | i64toi32_i32$3 | 0; + HEAP32[($1_1 + 36 | 0) >> 2] = i64toi32_i32$2; + HEAP32[($1_1 + 16 | 0) >> 2] = $1_1 + 32 | 0; + $2($1_1 + 8 | 0 | 0, 1048848 | 0); + wasm2js_trap(); + } + + function $19($0_1, $1_1) { + $0_1 = $0_1 | 0; + $1_1 = $1_1 | 0; + var i64toi32_i32$1 = 0; + i64toi32_i32$1 = 0; + return $20(HEAP32[$0_1 >> 2] | 0 | 0, i64toi32_i32$1 | 0, $1_1 | 0) | 0 | 0; + } + + function $20($0_1, $0$hi, $1_1) { + $0_1 = $0_1 | 0; + $0$hi = $0$hi | 0; + $1_1 = $1_1 | 0; + var i64toi32_i32$2 = 0, $2_1 = 0, i64toi32_i32$0 = 0, i64toi32_i32$1 = 0, i64toi32_i32$3 = 0, $7_1 = 0, $3_1 = 0, i64toi32_i32$5 = 0, $4_1 = 0, $7$hi = 0, $5_1 = 0, i64toi32_i32$4 = 0, $6_1 = 0, $20_1 = 0, $22_1 = 0, $23_1 = 0, $24_1 = 0, $25_1 = 0, $26_1 = 0, $27_1 = 0, $28_1 = 0, $29_1 = 0, $30_1 = 0, $31_1 = 0, $32_1 = 0, $21_1 = 0, $25$hi = 0, $8_1 = 0, $9_1 = 0; + $4_1 = global$0 - 48 | 0; + global$0 = $4_1; + $2_1 = 39; + label$1 : { + i64toi32_i32$0 = $0$hi; + i64toi32_i32$2 = $0_1; + i64toi32_i32$1 = 0; + i64toi32_i32$3 = 1e4; + if (i64toi32_i32$0 >>> 0 < i64toi32_i32$1 >>> 0 | ((i64toi32_i32$0 | 0) == (i64toi32_i32$1 | 0) & i64toi32_i32$2 >>> 0 < i64toi32_i32$3 >>> 0 | 0) | 0) { + i64toi32_i32$2 = i64toi32_i32$0; + $7_1 = $0_1; + $7$hi = i64toi32_i32$2; + break label$1; + } + label$3 : while (1) { + $3_1 = ($4_1 + 9 | 0) + $2_1 | 0; + $21_1 = $3_1 - 4 | 0; + i64toi32_i32$2 = $0$hi; + i64toi32_i32$0 = 0; + i64toi32_i32$0 = __wasm_i64_udiv($0_1 | 0, i64toi32_i32$2 | 0, 1e4 | 0, i64toi32_i32$0 | 0) | 0; + i64toi32_i32$2 = i64toi32_i32$HIGH_BITS; + $7_1 = i64toi32_i32$0; + $7$hi = i64toi32_i32$2; + i64toi32_i32$0 = 0; + i64toi32_i32$0 = __wasm_i64_mul($7_1 | 0, i64toi32_i32$2 | 0, 55536 | 0, i64toi32_i32$0 | 0) | 0; + i64toi32_i32$2 = i64toi32_i32$HIGH_BITS; + $25$hi = i64toi32_i32$2; + i64toi32_i32$2 = $0$hi; + i64toi32_i32$2 = $25$hi; + i64toi32_i32$3 = i64toi32_i32$0; + i64toi32_i32$0 = $0$hi; + i64toi32_i32$1 = $0_1; + i64toi32_i32$4 = i64toi32_i32$3 + i64toi32_i32$1 | 0; + i64toi32_i32$5 = i64toi32_i32$2 + i64toi32_i32$0 | 0; + if (i64toi32_i32$4 >>> 0 < i64toi32_i32$1 >>> 0) { + i64toi32_i32$5 = i64toi32_i32$5 + 1 | 0 + } + $5_1 = i64toi32_i32$4; + $6_1 = (($5_1 & 65535 | 0) >>> 0) / (100 >>> 0) | 0; + $20_1 = ($6_1 << 1 | 0) + 1048866 | 0; + $22_1 = $21_1; + $23_1 = HEAPU8[$20_1 >> 0] | 0 | ((HEAPU8[($20_1 + 1 | 0) >> 0] | 0) << 8 | 0) | 0; + HEAP8[$22_1 >> 0] = $23_1; + HEAP8[($22_1 + 1 | 0) >> 0] = $23_1 >>> 8 | 0; + $24_1 = (((Math_imul($6_1, -100) + $5_1 | 0) & 65535 | 0) << 1 | 0) + 1048866 | 0; + $25_1 = $3_1 - 2 | 0; + $26_1 = HEAPU8[$24_1 >> 0] | 0 | ((HEAPU8[($24_1 + 1 | 0) >> 0] | 0) << 8 | 0) | 0; + HEAP8[$25_1 >> 0] = $26_1; + HEAP8[($25_1 + 1 | 0) >> 0] = $26_1 >>> 8 | 0; + $2_1 = $2_1 - 4 | 0; + i64toi32_i32$5 = $0$hi; + i64toi32_i32$2 = $0_1; + i64toi32_i32$3 = 0; + i64toi32_i32$1 = 99999999; + $8_1 = i64toi32_i32$5 >>> 0 > i64toi32_i32$3 >>> 0 | ((i64toi32_i32$5 | 0) == (i64toi32_i32$3 | 0) & i64toi32_i32$2 >>> 0 > i64toi32_i32$1 >>> 0 | 0) | 0; + i64toi32_i32$2 = $7$hi; + $0_1 = $7_1; + $0$hi = i64toi32_i32$2; + if ($8_1) { + continue label$3 + } + break label$3; + }; + } + label$4 : { + i64toi32_i32$2 = $7$hi; + i64toi32_i32$1 = $7_1; + i64toi32_i32$5 = 0; + i64toi32_i32$3 = 99; + if (i64toi32_i32$2 >>> 0 < i64toi32_i32$5 >>> 0 | ((i64toi32_i32$2 | 0) == (i64toi32_i32$5 | 0) & i64toi32_i32$1 >>> 0 <= i64toi32_i32$3 >>> 0 | 0) | 0) { + i64toi32_i32$1 = i64toi32_i32$2; + i64toi32_i32$1 = i64toi32_i32$2; + $3_1 = $7_1; + break label$4; + } + $2_1 = $2_1 - 2 | 0; + i64toi32_i32$1 = $7$hi; + $5_1 = $7_1; + $3_1 = (($7_1 & 65535 | 0) >>> 0) / (100 >>> 0) | 0; + $27_1 = (((Math_imul($3_1, -100) + $7_1 | 0) & 65535 | 0) << 1 | 0) + 1048866 | 0; + $28_1 = $2_1 + ($4_1 + 9 | 0) | 0; + $29_1 = HEAPU8[$27_1 >> 0] | 0 | ((HEAPU8[($27_1 + 1 | 0) >> 0] | 0) << 8 | 0) | 0; + HEAP8[$28_1 >> 0] = $29_1; + HEAP8[($28_1 + 1 | 0) >> 0] = $29_1 >>> 8 | 0; + } + label$6 : { + if ($3_1 >>> 0 >= 10 >>> 0) { + $2_1 = $2_1 - 2 | 0; + $30_1 = ($3_1 << 1 | 0) + 1048866 | 0; + $31_1 = $2_1 + ($4_1 + 9 | 0) | 0; + $32_1 = HEAPU8[$30_1 >> 0] | 0 | ((HEAPU8[($30_1 + 1 | 0) >> 0] | 0) << 8 | 0) | 0; + HEAP8[$31_1 >> 0] = $32_1; + HEAP8[($31_1 + 1 | 0) >> 0] = $32_1 >>> 8 | 0; + break label$6; + } + $2_1 = $2_1 - 1 | 0; + HEAP8[($2_1 + ($4_1 + 9 | 0) | 0) >> 0] = $3_1 | 48 | 0; + } + $9_1 = $21($1_1 | 0, 1 | 0, 0 | 0, ($4_1 + 9 | 0) + $2_1 | 0 | 0, 39 - $2_1 | 0 | 0) | 0; + global$0 = $4_1 + 48 | 0; + return $9_1 | 0; + } + + function $21($0_1, $1_1, $2_1, $3_1, $4_1) { + $0_1 = $0_1 | 0; + $1_1 = $1_1 | 0; + $2_1 = $2_1 | 0; + $3_1 = $3_1 | 0; + $4_1 = $4_1 | 0; + var $5_1 = 0, $6_1 = 0, $7_1 = 0, $8_1 = 0, $9_1 = 0, $10_1 = 0, $11_1 = 0, $12_1 = 0; + $7_1 = HEAP32[($0_1 + 28 | 0) >> 2] | 0; + $5_1 = $7_1 & 1 | 0; + $10_1 = $5_1 ? 43 : 1114112; + $6_1 = $4_1 + $5_1 | 0; + label$1 : { + if (!($7_1 & 4 | 0)) { + $1_1 = 0; + break label$1; + } + label$3 : { + if (!$2_1) { + break label$3 + } + $8_1 = $2_1 & 3 | 0; + if (!$8_1) { + break label$3 + } + $5_1 = $1_1; + label$4 : while (1) { + $9_1 = $9_1 + ((HEAP8[$5_1 >> 0] | 0 | 0) > (-65 | 0)) | 0; + $5_1 = $5_1 + 1 | 0; + $8_1 = $8_1 - 1 | 0; + if ($8_1) { + continue label$4 + } + break label$4; + }; + } + $6_1 = $6_1 + $9_1 | 0; + } + if (!(HEAP32[$0_1 >> 2] | 0)) { + $5_1 = HEAP32[($0_1 + 20 | 0) >> 2] | 0; + $0_1 = HEAP32[($0_1 + 24 | 0) >> 2] | 0; + if ($22($5_1 | 0, $0_1 | 0, $10_1 | 0, $1_1 | 0, $2_1 | 0) | 0) { + return 1 | 0 + } + return FUNCTION_TABLE[HEAP32[($0_1 + 12 | 0) >> 2] | 0 | 0]($5_1, $3_1, $4_1) | 0 | 0; + } + label$7 : { + label$8 : { + label$9 : { + $8_1 = HEAP32[($0_1 + 4 | 0) >> 2] | 0; + if ($6_1 >>> 0 >= $8_1 >>> 0) { + $5_1 = HEAP32[($0_1 + 20 | 0) >> 2] | 0; + $0_1 = HEAP32[($0_1 + 24 | 0) >> 2] | 0; + if (!($22($5_1 | 0, $0_1 | 0, $10_1 | 0, $1_1 | 0, $2_1 | 0) | 0)) { + break label$9 + } + return 1 | 0; + } + if (!($7_1 & 8 | 0)) { + break label$8 + } + $11_1 = HEAP32[($0_1 + 16 | 0) >> 2] | 0; + HEAP32[($0_1 + 16 | 0) >> 2] = 48; + $12_1 = HEAPU8[($0_1 + 32 | 0) >> 0] | 0; + $5_1 = 1; + HEAP8[($0_1 + 32 | 0) >> 0] = 1; + $7_1 = HEAP32[($0_1 + 20 | 0) >> 2] | 0; + $9_1 = HEAP32[($0_1 + 24 | 0) >> 2] | 0; + if ($22($7_1 | 0, $9_1 | 0, $10_1 | 0, $1_1 | 0, $2_1 | 0) | 0) { + break label$7 + } + $5_1 = ($8_1 - $6_1 | 0) + 1 | 0; + label$11 : { + label$12 : while (1) { + $5_1 = $5_1 - 1 | 0; + if (!$5_1) { + break label$11 + } + if (!(FUNCTION_TABLE[HEAP32[($9_1 + 16 | 0) >> 2] | 0 | 0]($7_1, 48) | 0)) { + continue label$12 + } + break label$12; + }; + return 1 | 0; + } + if (FUNCTION_TABLE[HEAP32[($9_1 + 12 | 0) >> 2] | 0 | 0]($7_1, $3_1, $4_1) | 0) { + return 1 | 0 + } + HEAP8[($0_1 + 32 | 0) >> 0] = $12_1; + HEAP32[($0_1 + 16 | 0) >> 2] = $11_1; + return 0 | 0; + } + $5_1 = FUNCTION_TABLE[HEAP32[($0_1 + 12 | 0) >> 2] | 0 | 0]($5_1, $3_1, $4_1) | 0; + break label$7; + } + $6_1 = $8_1 - $6_1 | 0; + label$14 : { + label$15 : { + label$16 : { + $5_1 = HEAPU8[($0_1 + 32 | 0) >> 0] | 0; + switch ($5_1 - 1 | 0 | 0) { + case 1: + break label$15; + case 0: + case 2: + break label$16; + default: + break label$14; + }; + } + $5_1 = $6_1; + $6_1 = 0; + break label$14; + } + $5_1 = $6_1 >>> 1 | 0; + $6_1 = ($6_1 + 1 | 0) >>> 1 | 0; + } + $5_1 = $5_1 + 1 | 0; + $8_1 = HEAP32[($0_1 + 16 | 0) >> 2] | 0; + $7_1 = HEAP32[($0_1 + 24 | 0) >> 2] | 0; + $0_1 = HEAP32[($0_1 + 20 | 0) >> 2] | 0; + label$17 : { + label$18 : while (1) { + $5_1 = $5_1 - 1 | 0; + if (!$5_1) { + break label$17 + } + if (!(FUNCTION_TABLE[HEAP32[($7_1 + 16 | 0) >> 2] | 0 | 0]($0_1, $8_1) | 0)) { + continue label$18 + } + break label$18; + }; + return 1 | 0; + } + $5_1 = 1; + if ($22($0_1 | 0, $7_1 | 0, $10_1 | 0, $1_1 | 0, $2_1 | 0) | 0) { + break label$7 + } + if (FUNCTION_TABLE[HEAP32[($7_1 + 12 | 0) >> 2] | 0 | 0]($0_1, $3_1, $4_1) | 0) { + break label$7 + } + $5_1 = 0; + label$19 : while (1) { + if (($5_1 | 0) == ($6_1 | 0)) { + return 0 | 0 + } + $5_1 = $5_1 + 1 | 0; + if (!(FUNCTION_TABLE[HEAP32[($7_1 + 16 | 0) >> 2] | 0 | 0]($0_1, $8_1) | 0)) { + continue label$19 + } + break label$19; + }; + return ($5_1 - 1 | 0) >>> 0 < $6_1 >>> 0 | 0; + } + return $5_1 | 0; + } + + function $22($0_1, $1_1, $2_1, $3_1, $4_1) { + $0_1 = $0_1 | 0; + $1_1 = $1_1 | 0; + $2_1 = $2_1 | 0; + $3_1 = $3_1 | 0; + $4_1 = $4_1 | 0; + label$1 : { + if (($2_1 | 0) == (1114112 | 0)) { + break label$1 + } + if (!(FUNCTION_TABLE[HEAP32[($1_1 + 16 | 0) >> 2] | 0 | 0]($0_1, $2_1) | 0)) { + break label$1 + } + return 1 | 0; + } + if (!$3_1) { + return 0 | 0 + } + return FUNCTION_TABLE[HEAP32[($1_1 + 12 | 0) >> 2] | 0 | 0]($0_1, $3_1, $4_1) | 0 | 0; + } + + function $23($0_1, $1_1) { + $0_1 = $0_1 | 0; + $1_1 = $1_1 | 0; + var $2_1 = 0, $3_1 = 0, $4_1 = 0, $6_1 = 0, $5_1 = 0, $7_1 = 0, $8_1 = 0, $189 = 0, $9_1 = 0, $118 = 0, $128 = 0, $138 = 0; + $5_1 = ($0_1 + 3 | 0) & -4 | 0; + $3_1 = $0_1 - $5_1 | 0; + $7_1 = $1_1 + $3_1 | 0; + $4_1 = $7_1 & 3 | 0; + $1_1 = 0; + if (($0_1 | 0) != ($5_1 | 0)) { + if ($3_1 >>> 0 <= -4 >>> 0) { + label$3 : while (1) { + $6_1 = $0_1 + $8_1 | 0; + $1_1 = ((($1_1 + ((HEAP8[$6_1 >> 0] | 0 | 0) > (-65 | 0)) | 0) + ((HEAP8[($6_1 + 1 | 0) >> 0] | 0 | 0) > (-65 | 0)) | 0) + ((HEAP8[($6_1 + 2 | 0) >> 0] | 0 | 0) > (-65 | 0)) | 0) + ((HEAP8[($6_1 + 3 | 0) >> 0] | 0 | 0) > (-65 | 0)) | 0; + $8_1 = $8_1 + 4 | 0; + if ($8_1) { + continue label$3 + } + break label$3; + } + } + label$4 : while (1) { + $1_1 = $1_1 + ((HEAP8[$0_1 >> 0] | 0 | 0) > (-65 | 0)) | 0; + $0_1 = $0_1 + 1 | 0; + $3_1 = $3_1 + 1 | 0; + if ($3_1) { + continue label$4 + } + break label$4; + }; + } + label$5 : { + if (!$4_1) { + break label$5 + } + $0_1 = $5_1 + ($7_1 & -4 | 0) | 0; + $2_1 = (HEAP8[$0_1 >> 0] | 0 | 0) > (-65 | 0); + if (($4_1 | 0) == (1 | 0)) { + break label$5 + } + $2_1 = $2_1 + ((HEAP8[($0_1 + 1 | 0) >> 0] | 0 | 0) > (-65 | 0)) | 0; + if (($4_1 | 0) == (2 | 0)) { + break label$5 + } + $2_1 = $2_1 + ((HEAP8[($0_1 + 2 | 0) >> 0] | 0 | 0) > (-65 | 0)) | 0; + } + $3_1 = $7_1 >>> 2 | 0; + $4_1 = $1_1 + $2_1 | 0; + label$6 : { + label$7 : while (1) { + $2_1 = $5_1; + if (!$3_1) { + break label$6 + } + $6_1 = $3_1 >>> 0 >= 192 >>> 0 ? 192 : $3_1; + $7_1 = $6_1 & 3 | 0; + $5_1 = $6_1 << 2 | 0; + $1_1 = 0; + if ($3_1 >>> 0 >= 4 >>> 0) { + $8_1 = $2_1 + ($5_1 & 1008 | 0) | 0; + $0_1 = $2_1; + label$9 : while (1) { + $9_1 = HEAP32[$0_1 >> 2] | 0; + $118 = $1_1 + ((($9_1 ^ -1 | 0) >>> 7 | 0 | ($9_1 >>> 6 | 0) | 0) & 16843009 | 0) | 0; + $1_1 = HEAP32[($0_1 + 4 | 0) >> 2] | 0; + $128 = $118 + ((($1_1 ^ -1 | 0) >>> 7 | 0 | ($1_1 >>> 6 | 0) | 0) & 16843009 | 0) | 0; + $1_1 = HEAP32[($0_1 + 8 | 0) >> 2] | 0; + $138 = $128 + ((($1_1 ^ -1 | 0) >>> 7 | 0 | ($1_1 >>> 6 | 0) | 0) & 16843009 | 0) | 0; + $1_1 = HEAP32[($0_1 + 12 | 0) >> 2] | 0; + $1_1 = $138 + ((($1_1 ^ -1 | 0) >>> 7 | 0 | ($1_1 >>> 6 | 0) | 0) & 16843009 | 0) | 0; + $0_1 = $0_1 + 16 | 0; + if (($0_1 | 0) != ($8_1 | 0)) { + continue label$9 + } + break label$9; + }; + } + $3_1 = $3_1 - $6_1 | 0; + $5_1 = $2_1 + $5_1 | 0; + $4_1 = (Math_imul((($1_1 >>> 8 | 0) & 16711935 | 0) + ($1_1 & 16711935 | 0) | 0, 65537) >>> 16 | 0) + $4_1 | 0; + if (!$7_1) { + continue label$7 + } + break label$7; + }; + label$10 : { + $0_1 = $2_1 + (($6_1 & 252 | 0) << 2 | 0) | 0; + $1_1 = HEAP32[$0_1 >> 2] | 0; + $1_1 = (($1_1 ^ -1 | 0) >>> 7 | 0 | ($1_1 >>> 6 | 0) | 0) & 16843009 | 0; + $189 = $1_1; + if (($7_1 | 0) == (1 | 0)) { + break label$10 + } + $2_1 = HEAP32[($0_1 + 4 | 0) >> 2] | 0; + $1_1 = $1_1 + ((($2_1 ^ -1 | 0) >>> 7 | 0 | ($2_1 >>> 6 | 0) | 0) & 16843009 | 0) | 0; + $189 = $1_1; + if (($7_1 | 0) == (2 | 0)) { + break label$10 + } + $0_1 = HEAP32[($0_1 + 8 | 0) >> 2] | 0; + $189 = $1_1 + ((($0_1 ^ -1 | 0) >>> 7 | 0 | ($0_1 >>> 6 | 0) | 0) & 16843009 | 0) | 0; + } + $0_1 = $189; + $4_1 = (Math_imul((($0_1 >>> 8 | 0) & 459007 | 0) + ($0_1 & 16711935 | 0) | 0, 65537) >>> 16 | 0) + $4_1 | 0; + } + return $4_1 | 0; + } + + function $24($0_1, $1_1) { + $0_1 = $0_1 | 0; + $1_1 = $1_1 | 0; + var $2_1 = 0, $3_1 = 0, $5_1 = 0, $4_1 = 0, $6_1 = 0, $7_1 = 0, $45_1 = 0, $8_1 = 0, $87 = 0, $9_1 = 0, $75 = 0, $76 = 0; + $3_1 = HEAP32[($0_1 + 4 | 0) >> 2] | 0; + $4_1 = HEAP32[$0_1 >> 2] | 0; + label$1 : { + $0_1 = !((HEAP32[($1_1 + 8 | 0) >> 2] | 0) & 1 | 0); + $8_1 = HEAP32[$1_1 >> 2] | 0; + if (!($0_1 & !$8_1 | 0)) { + label$3 : { + if ($0_1) { + break label$3 + } + $9_1 = $3_1 + $4_1 | 0; + label$4 : { + $7_1 = HEAP32[($1_1 + 12 | 0) >> 2] | 0; + if (!$7_1) { + $2_1 = $4_1; + break label$4; + } + $2_1 = $4_1; + label$6 : while (1) { + $0_1 = $2_1; + if (($0_1 | 0) == ($9_1 | 0)) { + break label$3 + } + label$7 : { + $2_1 = HEAP8[$0_1 >> 0] | 0; + $45_1 = $0_1 + 1 | 0; + if (($2_1 | 0) >= (0 | 0)) { + break label$7 + } + $45_1 = $0_1 + 2 | 0; + if ($2_1 >>> 0 < -32 >>> 0) { + break label$7 + } + $45_1 = $0_1 + 3 | 0; + if ($2_1 >>> 0 < -16 >>> 0) { + break label$7 + } + $45_1 = $0_1 + 4 | 0; + } + $2_1 = $45_1; + $6_1 = ($2_1 - $0_1 | 0) + $6_1 | 0; + $5_1 = $5_1 + 1 | 0; + if (($7_1 | 0) != ($5_1 | 0)) { + continue label$6 + } + break label$6; + }; + } + if (($2_1 | 0) == ($9_1 | 0)) { + break label$3 + } + HEAP8[$2_1 >> 0] | 0; + $75 = $6_1; + $76 = $3_1; + label$8 : { + label$9 : { + if (!$6_1) { + break label$9 + } + if ($3_1 >>> 0 > $6_1 >>> 0) { + if ((HEAP8[($4_1 + $6_1 | 0) >> 0] | 0 | 0) > (-65 | 0)) { + break label$9 + } + $87 = 0; + break label$8; + } + if (($3_1 | 0) == ($6_1 | 0)) { + break label$9 + } + $87 = 0; + break label$8; + } + $87 = $4_1; + } + $0_1 = $87; + $3_1 = $0_1 ? $75 : $76; + $4_1 = $0_1 ? $0_1 : $4_1; + } + if (!$8_1) { + break label$1 + } + $8_1 = HEAP32[($1_1 + 4 | 0) >> 2] | 0; + label$11 : { + if ($3_1 >>> 0 >= 16 >>> 0) { + $2_1 = $23($4_1 | 0, $3_1 | 0) | 0; + break label$11; + } + if (!$3_1) { + $2_1 = 0; + break label$11; + } + $6_1 = $3_1 & 3 | 0; + label$14 : { + if ($3_1 >>> 0 < 4 >>> 0) { + $2_1 = 0; + $7_1 = 0; + break label$14; + } + $2_1 = 0; + $0_1 = $4_1; + $7_1 = $3_1 & 12 | 0; + $5_1 = $7_1; + label$16 : while (1) { + $2_1 = ((($2_1 + ((HEAP8[$0_1 >> 0] | 0 | 0) > (-65 | 0)) | 0) + ((HEAP8[($0_1 + 1 | 0) >> 0] | 0 | 0) > (-65 | 0)) | 0) + ((HEAP8[($0_1 + 2 | 0) >> 0] | 0 | 0) > (-65 | 0)) | 0) + ((HEAP8[($0_1 + 3 | 0) >> 0] | 0 | 0) > (-65 | 0)) | 0; + $0_1 = $0_1 + 4 | 0; + $5_1 = $5_1 - 4 | 0; + if ($5_1) { + continue label$16 + } + break label$16; + }; + } + if (!$6_1) { + break label$11 + } + $0_1 = $4_1 + $7_1 | 0; + label$17 : while (1) { + $2_1 = $2_1 + ((HEAP8[$0_1 >> 0] | 0 | 0) > (-65 | 0)) | 0; + $0_1 = $0_1 + 1 | 0; + $6_1 = $6_1 - 1 | 0; + if ($6_1) { + continue label$17 + } + break label$17; + }; + } + label$18 : { + if ($2_1 >>> 0 < $8_1 >>> 0) { + $5_1 = $8_1 - $2_1 | 0; + $0_1 = 0; + label$20 : { + label$21 : { + switch ((HEAPU8[($1_1 + 32 | 0) >> 0] | 0) - 1 | 0 | 0) { + case 0: + $0_1 = $5_1; + $5_1 = 0; + break label$20; + case 1: + break label$21; + default: + break label$20; + }; + } + $0_1 = $5_1 >>> 1 | 0; + $5_1 = ($5_1 + 1 | 0) >>> 1 | 0; + } + $0_1 = $0_1 + 1 | 0; + $2_1 = HEAP32[($1_1 + 16 | 0) >> 2] | 0; + $7_1 = HEAP32[($1_1 + 24 | 0) >> 2] | 0; + $1_1 = HEAP32[($1_1 + 20 | 0) >> 2] | 0; + label$23 : while (1) { + $0_1 = $0_1 - 1 | 0; + if (!$0_1) { + break label$18 + } + if (!(FUNCTION_TABLE[HEAP32[($7_1 + 16 | 0) >> 2] | 0 | 0]($1_1, $2_1) | 0)) { + continue label$23 + } + break label$23; + }; + return 1 | 0; + } + break label$1; + } + if (FUNCTION_TABLE[HEAP32[($7_1 + 12 | 0) >> 2] | 0 | 0]($1_1, $4_1, $3_1) | 0) { + return 1 | 0 + } + $0_1 = 0; + label$25 : while (1) { + if (($0_1 | 0) == ($5_1 | 0)) { + return 0 | 0 + } + $0_1 = $0_1 + 1 | 0; + if (!(FUNCTION_TABLE[HEAP32[($7_1 + 16 | 0) >> 2] | 0 | 0]($1_1, $2_1) | 0)) { + continue label$25 + } + break label$25; + }; + return ($0_1 - 1 | 0) >>> 0 < $5_1 >>> 0 | 0; + } + return FUNCTION_TABLE[HEAP32[((HEAP32[($1_1 + 24 | 0) >> 2] | 0) + 12 | 0) >> 2] | 0 | 0](HEAP32[($1_1 + 20 | 0) >> 2] | 0, $4_1, $3_1) | 0 | 0; + } + return FUNCTION_TABLE[HEAP32[((HEAP32[($1_1 + 24 | 0) >> 2] | 0) + 12 | 0) >> 2] | 0 | 0](HEAP32[($1_1 + 20 | 0) >> 2] | 0, $4_1, $3_1) | 0 | 0; + } + + function $25($0_1, $1_1) { + $0_1 = $0_1 | 0; + $1_1 = $1_1 | 0; + return FUNCTION_TABLE[HEAP32[((HEAP32[($0_1 + 4 | 0) >> 2] | 0) + 12 | 0) >> 2] | 0 | 0](HEAP32[$0_1 >> 2] | 0, $1_1) | 0 | 0; + } + + function $26($0_1, $1_1, $2_1) { + $0_1 = $0_1 | 0; + $1_1 = $1_1 | 0; + $2_1 = $2_1 | 0; + var $3_1 = 0, $4_1 = 0, $5_1 = 0, $6_1 = 0, $7_1 = 0, $9_1 = 0, $8_1 = 0, $10_1 = 0, $11_1 = 0, $12_1 = 0, $140 = 0, $13_1 = 0, $69 = 0, $14_1 = 0; + $13_1 = $1_1 - 1 | 0; + $10_1 = HEAP32[($0_1 + 4 | 0) >> 2] | 0; + $11_1 = HEAP32[$0_1 >> 2] | 0; + $12_1 = HEAP32[($0_1 + 8 | 0) >> 2] | 0; + label$1 : { + label$2 : while (1) { + if ($6_1) { + break label$1 + } + label$3 : { + label$4 : { + if ($2_1 >>> 0 < $4_1 >>> 0) { + break label$4 + } + label$5 : while (1) { + $6_1 = $1_1 + $4_1 | 0; + label$6 : { + label$7 : { + label$8 : { + $7_1 = $2_1 - $4_1 | 0; + if ($7_1 >>> 0 <= 7 >>> 0) { + if (($2_1 | 0) != ($4_1 | 0)) { + break label$8 + } + $4_1 = $2_1; + break label$4; + } + label$10 : { + $5_1 = ($6_1 + 3 | 0) & -4 | 0; + $3_1 = $5_1 - $6_1 | 0; + if ($3_1) { + $0_1 = 0; + label$12 : while (1) { + if ((HEAPU8[($0_1 + $6_1 | 0) >> 0] | 0 | 0) == (10 | 0)) { + break label$6 + } + $0_1 = $0_1 + 1 | 0; + if (($3_1 | 0) != ($0_1 | 0)) { + continue label$12 + } + break label$12; + }; + $0_1 = $7_1 - 8 | 0; + if ($3_1 >>> 0 <= $0_1 >>> 0) { + break label$10 + } + break label$7; + } + $0_1 = $7_1 - 8 | 0; + } + label$13 : while (1) { + $9_1 = HEAP32[$5_1 >> 2] | 0; + $69 = 16843008 - ($9_1 ^ 168430090 | 0) | 0 | $9_1 | 0; + $9_1 = HEAP32[($5_1 + 4 | 0) >> 2] | 0; + if ((($69 & (16843008 - ($9_1 ^ 168430090 | 0) | 0 | $9_1 | 0) | 0) & -2139062144 | 0 | 0) != (-2139062144 | 0)) { + break label$7 + } + $5_1 = $5_1 + 8 | 0; + $3_1 = $3_1 + 8 | 0; + if ($3_1 >>> 0 <= $0_1 >>> 0) { + continue label$13 + } + break label$13; + }; + break label$7; + } + $0_1 = 0; + label$14 : while (1) { + if ((HEAPU8[($0_1 + $6_1 | 0) >> 0] | 0 | 0) == (10 | 0)) { + break label$6 + } + $0_1 = $0_1 + 1 | 0; + if (($7_1 | 0) != ($0_1 | 0)) { + continue label$14 + } + break label$14; + }; + $4_1 = $2_1; + break label$4; + } + if (($3_1 | 0) == ($7_1 | 0)) { + $4_1 = $2_1; + break label$4; + } + $5_1 = $3_1 + $6_1 | 0; + $7_1 = ($2_1 - $3_1 | 0) - $4_1 | 0; + $0_1 = 0; + label$16 : { + label$17 : while (1) { + if ((HEAPU8[($0_1 + $5_1 | 0) >> 0] | 0 | 0) == (10 | 0)) { + break label$16 + } + $0_1 = $0_1 + 1 | 0; + if (($7_1 | 0) != ($0_1 | 0)) { + continue label$17 + } + break label$17; + }; + $4_1 = $2_1; + break label$4; + } + $0_1 = $0_1 + $3_1 | 0; + } + $3_1 = $0_1 + $4_1 | 0; + $4_1 = $3_1 + 1 | 0; + label$18 : { + if ($2_1 >>> 0 <= $3_1 >>> 0) { + break label$18 + } + if ((HEAPU8[($0_1 + $6_1 | 0) >> 0] | 0 | 0) != (10 | 0)) { + break label$18 + } + $6_1 = 0; + $3_1 = $4_1; + $140 = $3_1; + break label$3; + } + if ($2_1 >>> 0 >= $4_1 >>> 0) { + continue label$5 + } + break label$5; + }; + } + if (($2_1 | 0) == ($8_1 | 0)) { + break label$1 + } + $6_1 = 1; + $3_1 = $8_1; + $140 = $2_1; + } + $0_1 = $140; + label$19 : { + if (HEAPU8[$12_1 >> 0] | 0) { + if (FUNCTION_TABLE[HEAP32[($10_1 + 12 | 0) >> 2] | 0 | 0]($11_1, 1048816, 4) | 0) { + break label$19 + } + } + $5_1 = 0; + if (($0_1 | 0) != ($8_1 | 0)) { + $5_1 = (HEAPU8[($0_1 + $13_1 | 0) >> 0] | 0 | 0) == (10 | 0) + } + $0_1 = $0_1 - $8_1 | 0; + $7_1 = $1_1 + $8_1 | 0; + HEAP8[$12_1 >> 0] = $5_1; + $8_1 = $3_1; + if (!(FUNCTION_TABLE[HEAP32[($10_1 + 12 | 0) >> 2] | 0 | 0]($11_1, $7_1, $0_1) | 0)) { + continue label$2 + } + } + break label$2; + }; + $14_1 = 1; + } + return $14_1 | 0; + } + + function $27($0_1, $1_1) { + $0_1 = $0_1 | 0; + $1_1 = $1_1 | 0; + var $2_1 = 0, $3_1 = 0; + $2_1 = HEAP32[($0_1 + 4 | 0) >> 2] | 0; + $3_1 = HEAP32[$0_1 >> 2] | 0; + label$1 : { + $0_1 = HEAP32[($0_1 + 8 | 0) >> 2] | 0; + if (!(HEAPU8[$0_1 >> 0] | 0)) { + break label$1 + } + if (!(FUNCTION_TABLE[HEAP32[($2_1 + 12 | 0) >> 2] | 0 | 0]($3_1, 1048816, 4) | 0)) { + break label$1 + } + return 1 | 0; + } + HEAP8[$0_1 >> 0] = ($1_1 | 0) == (10 | 0); + return FUNCTION_TABLE[HEAP32[($2_1 + 16 | 0) >> 2] | 0 | 0]($3_1, $1_1) | 0 | 0; + } + + function $28($0_1, $1_1) { + $0_1 = $0_1 | 0; + $1_1 = $1_1 | 0; + return $13($0_1 | 0, 1048792 | 0, $1_1 | 0) | 0 | 0; + } + + function $29($0_1, $1_1) { + $0_1 = $0_1 | 0; + $1_1 = $1_1 | 0; + var $2_1 = 0, $3_1 = 0, $4_1 = 0; + $3_1 = HEAP32[($1_1 + 8 | 0) >> 2] | 0; + label$1 : { + label$2 : { + label$3 : { + $2_1 = HEAP32[$1_1 >> 2] | 0; + if (!$2_1) { + $4_1 = 1; + if ($3_1) { + break label$3 + } + $2_1 = 0; + $1_1 = 0; + break label$1; + } + $2_1 = (HEAP32[($1_1 + 4 | 0) >> 2] | 0) - $2_1 | 0; + if ($3_1) { + break label$2 + } + $4_1 = 1; + $1_1 = $2_1; + break label$1; + } + $2_1 = (HEAP32[($1_1 + 12 | 0) >> 2] | 0) - $3_1 | 0; + $1_1 = $2_1; + break label$1; + } + $1_1 = ((HEAP32[($1_1 + 12 | 0) >> 2] | 0) - $3_1 | 0) + $2_1 | 0; + $4_1 = $1_1 >>> 0 >= $2_1 >>> 0; + $2_1 = $1_1 >>> 0 < $2_1 >>> 0 ? -1 : $1_1; + } + HEAP32[($0_1 + 8 | 0) >> 2] = $1_1; + HEAP32[($0_1 + 4 | 0) >> 2] = $4_1; + HEAP32[$0_1 >> 2] = $2_1; + } + + function $30($0_1, $1_1) { + $0_1 = $0_1 | 0; + $1_1 = $1_1 | 0; + var $2_1 = 0, $3_1 = 0, $4_1 = 0; + $2_1 = global$0 - 16 | 0; + global$0 = $2_1; + label$1 : { + if (($1_1 | 0) < (0 | 0)) { + break label$1 + } + label$2 : { + if (!$1_1) { + $1_1 = 0; + $3_1 = 1; + break label$2; + } + $4_1 = 1; + $31($2_1 + 8 | 0 | 0, 1 | 0, $1_1 | 0); + $3_1 = HEAP32[($2_1 + 8 | 0) >> 2] | 0; + if (!$3_1) { + break label$1 + } + } + HEAP32[($0_1 + 4 | 0) >> 2] = $3_1; + HEAP32[$0_1 >> 2] = $1_1; + global$0 = $2_1 + 16 | 0; + return; + } + $0($4_1 | 0); + wasm2js_trap(); + } + + function $31($0_1, $1_1, $2_1) { + $0_1 = $0_1 | 0; + $1_1 = $1_1 | 0; + $2_1 = $2_1 | 0; + if ($2_1) { + $1_1 = $34($2_1 | 0) | 0 + } + HEAP32[($0_1 + 4 | 0) >> 2] = $2_1; + HEAP32[$0_1 >> 2] = $1_1; + } + + function $32($0_1, $1_1) { + $0_1 = $0_1 | 0; + $1_1 = $1_1 | 0; + var $2_1 = 0, $3_1 = 0; + $2_1 = global$0 - 16 | 0; + global$0 = $2_1; + label$1 : { + $3_1 = HEAP32[($0_1 + 8 | 0) >> 2] | 0; + if (((HEAP32[$0_1 >> 2] | 0) - $3_1 | 0) >>> 0 >= $1_1 >>> 0) { + break label$1 + } + $33($2_1 + 8 | 0 | 0, $0_1 | 0, $3_1 | 0, $1_1 | 0, 1 | 0, 1 | 0); + $0_1 = HEAP32[($2_1 + 8 | 0) >> 2] | 0; + if (($0_1 | 0) == (-2147483647 | 0)) { + break label$1 + } + HEAP32[($2_1 + 12 | 0) >> 2] | 0; + $0($0_1 | 0); + wasm2js_trap(); + } + global$0 = $2_1 + 16 | 0; + } + + function $33($0_1, $1_1, $2_1, $3_1, $4_1, $5_1) { + $0_1 = $0_1 | 0; + $1_1 = $1_1 | 0; + $2_1 = $2_1 | 0; + $3_1 = $3_1 | 0; + $4_1 = $4_1 | 0; + $5_1 = $5_1 | 0; + var $6_1 = 0, i64toi32_i32$0 = 0, $7_1 = 0, i64toi32_i32$1 = 0, $8_1 = 0, $9_1 = 0, i64toi32_i32$4 = 0, $10_1 = 0, $95 = 0, i64toi32_i32$3 = 0, $23_1 = 0, $72 = 0, $28$hi = 0, $49$hi = 0, $11_1 = 0, $11$hi = 0, i64toi32_i32$2 = 0, $60 = 0; + $6_1 = global$0 - 32 | 0; + global$0 = $6_1; + label$1 : { + $3_1 = $2_1 + $3_1 | 0; + if ($2_1 >>> 0 > $3_1 >>> 0) { + $2_1 = 0; + break label$1; + } + $2_1 = 0; + i64toi32_i32$0 = 0; + $28$hi = i64toi32_i32$0; + $7_1 = ($5_1 | 0) == (1 | 0) ? 8 : 4; + $8_1 = HEAP32[$1_1 >> 2] | 0; + $9_1 = $8_1 << 1 | 0; + $3_1 = $3_1 >>> 0 < $9_1 >>> 0 ? $9_1 : $3_1; + $9_1 = $3_1 >>> 0 < $7_1 >>> 0 ? $7_1 : $3_1; + i64toi32_i32$0 = 0; + $49$hi = i64toi32_i32$0; + i64toi32_i32$0 = $28$hi; + i64toi32_i32$1 = $49$hi; + i64toi32_i32$1 = __wasm_i64_mul((($4_1 + $5_1 | 0) - 1 | 0) & (0 - $4_1 | 0) | 0 | 0, i64toi32_i32$0 | 0, $9_1 | 0, i64toi32_i32$1 | 0) | 0; + i64toi32_i32$0 = i64toi32_i32$HIGH_BITS; + $11_1 = i64toi32_i32$1; + $11$hi = i64toi32_i32$0; + i64toi32_i32$2 = i64toi32_i32$1; + i64toi32_i32$1 = 0; + i64toi32_i32$3 = 32; + i64toi32_i32$4 = i64toi32_i32$3 & 31 | 0; + if (32 >>> 0 <= (i64toi32_i32$3 & 63 | 0) >>> 0) { + i64toi32_i32$1 = 0; + $23_1 = i64toi32_i32$0 >>> i64toi32_i32$4 | 0; + } else { + i64toi32_i32$1 = i64toi32_i32$0 >>> i64toi32_i32$4 | 0; + $23_1 = (((1 << i64toi32_i32$4 | 0) - 1 | 0) & i64toi32_i32$0 | 0) << (32 - i64toi32_i32$4 | 0) | 0 | (i64toi32_i32$2 >>> i64toi32_i32$4 | 0) | 0; + } + if ($23_1) { + break label$1 + } + i64toi32_i32$1 = $11$hi; + $7_1 = $11_1; + if ($7_1 >>> 0 > (-2147483648 - $4_1 | 0) >>> 0) { + break label$1 + } + $60 = $6_1; + if ($8_1) { + HEAP32[($6_1 + 28 | 0) >> 2] = Math_imul($5_1, $8_1); + HEAP32[($6_1 + 20 | 0) >> 2] = HEAP32[($1_1 + 4 | 0) >> 2] | 0; + $72 = $4_1; + } else { + $72 = 0 + } + HEAP32[($60 + 24 | 0) >> 2] = $72; + $8_1 = $6_1 + 8 | 0; + $2_1 = global$0 - 16 | 0; + global$0 = $2_1; + label$5 : { + $5_1 = $6_1 + 20 | 0; + if (HEAP32[($5_1 + 4 | 0) >> 2] | 0) { + $10_1 = HEAP32[($5_1 + 8 | 0) >> 2] | 0; + if (!$10_1) { + $31($2_1 + 8 | 0 | 0, $4_1 | 0, $7_1 | 0); + $5_1 = HEAP32[($2_1 + 8 | 0) >> 2] | 0; + $95 = HEAP32[($2_1 + 12 | 0) >> 2] | 0; + break label$5; + } + $5_1 = $5(HEAP32[$5_1 >> 2] | 0 | 0, $10_1 | 0, $7_1 | 0) | 0; + $95 = $7_1; + break label$5; + } + $31($2_1 | 0, $4_1 | 0, $7_1 | 0); + $5_1 = HEAP32[$2_1 >> 2] | 0; + $95 = HEAP32[($2_1 + 4 | 0) >> 2] | 0; + } + $10_1 = $95; + HEAP32[($8_1 + 4 | 0) >> 2] = $5_1 ? $5_1 : $4_1; + HEAP32[$8_1 >> 2] = !$5_1; + HEAP32[($8_1 + 8 | 0) >> 2] = $5_1 ? $10_1 : $7_1; + global$0 = $2_1 + 16 | 0; + if (!(HEAP32[($6_1 + 8 | 0) >> 2] | 0)) { + $2_1 = HEAP32[($6_1 + 12 | 0) >> 2] | 0; + HEAP32[$1_1 >> 2] = $9_1; + HEAP32[($1_1 + 4 | 0) >> 2] = $2_1; + $2_1 = -2147483647; + break label$1; + } + $3_1 = HEAP32[($6_1 + 16 | 0) >> 2] | 0; + $2_1 = HEAP32[($6_1 + 12 | 0) >> 2] | 0; + } + HEAP32[($0_1 + 4 | 0) >> 2] = $3_1; + HEAP32[$0_1 >> 2] = $2_1; + global$0 = $6_1 + 32 | 0; + } + + function $34($0_1) { + $0_1 = $0_1 | 0; + HEAPU8[1049704 >> 0] | 0; + return $6($0_1 | 0) | 0 | 0; + } + + function $35($0_1, $1_1) { + $0_1 = $0_1 | 0; + $1_1 = $1_1 | 0; + var $2_1 = 0, $3_1 = 0, $4_1 = 0, i64toi32_i32$0 = 0, i64toi32_i32$1 = 0, $6_1 = 0, $9_1 = 0, $5_1 = 0, $7_1 = 0, $8_1 = 0, $10_1 = 0, $73 = 0, $76 = 0; + $2_1 = global$0 + -64 | 0; + global$0 = $2_1; + $3_1 = HEAP32[($0_1 + 4 | 0) >> 2] | 0; + $4_1 = HEAP32[$0_1 >> 2] | 0; + $0_1 = FUNCTION_TABLE[HEAP32[((HEAP32[($1_1 + 24 | 0) >> 2] | 0) + 12 | 0) >> 2] | 0 | 0](HEAP32[($1_1 + 20 | 0) >> 2] | 0, 1048772, 1) | 0; + label$1 : while (1) { + $6_1 = $8_1; + label$2 : { + label$3 : { + if ($3_1) { + $8_1 = 1; + $10_1 = $0_1 & 1 | 0; + $0_1 = 1; + if ($10_1) { + break label$2 + } + $9_1 = HEAP32[($1_1 + 28 | 0) >> 2] | 0; + if (!($9_1 & 4 | 0)) { + if (!($6_1 & 1 | 0)) { + break label$3 + } + if (!(FUNCTION_TABLE[HEAP32[((HEAP32[($1_1 + 24 | 0) >> 2] | 0) + 12 | 0) >> 2] | 0 | 0](HEAP32[($1_1 + 20 | 0) >> 2] | 0, 1048820, 2) | 0)) { + break label$3 + } + break label$2; + } + $5_1 = HEAP32[($1_1 + 24 | 0) >> 2] | 0; + $7_1 = HEAP32[($1_1 + 20 | 0) >> 2] | 0; + if (!($6_1 & 1 | 0)) { + if (FUNCTION_TABLE[HEAP32[($5_1 + 12 | 0) >> 2] | 0 | 0]($7_1, 1048824, 1) | 0) { + break label$2 + } + } + HEAP8[($2_1 + 27 | 0) >> 0] = 1; + HEAP32[($2_1 + 16 | 0) >> 2] = $5_1; + HEAP32[($2_1 + 12 | 0) >> 2] = $7_1; + HEAP32[($2_1 + 56 | 0) >> 2] = $9_1; + HEAP32[($2_1 + 52 | 0) >> 2] = 1048792; + HEAP8[($2_1 + 60 | 0) >> 0] = HEAPU8[($1_1 + 32 | 0) >> 0] | 0; + HEAP32[($2_1 + 44 | 0) >> 2] = HEAP32[($1_1 + 16 | 0) >> 2] | 0; + i64toi32_i32$0 = HEAP32[($1_1 + 8 | 0) >> 2] | 0; + i64toi32_i32$1 = HEAP32[($1_1 + 12 | 0) >> 2] | 0; + $73 = i64toi32_i32$0; + i64toi32_i32$0 = $2_1; + HEAP32[($2_1 + 36 | 0) >> 2] = $73; + HEAP32[($2_1 + 40 | 0) >> 2] = i64toi32_i32$1; + i64toi32_i32$1 = HEAP32[$1_1 >> 2] | 0; + i64toi32_i32$0 = HEAP32[($1_1 + 4 | 0) >> 2] | 0; + $76 = i64toi32_i32$1; + i64toi32_i32$1 = $2_1; + HEAP32[($2_1 + 28 | 0) >> 2] = $76; + HEAP32[($2_1 + 32 | 0) >> 2] = i64toi32_i32$0; + HEAP32[($2_1 + 20 | 0) >> 2] = $2_1 + 27 | 0; + HEAP32[($2_1 + 48 | 0) >> 2] = $2_1 + 12 | 0; + if (!($36($4_1 | 0, $2_1 + 28 | 0 | 0) | 0)) { + $0_1 = FUNCTION_TABLE[HEAP32[((HEAP32[($2_1 + 52 | 0) >> 2] | 0) + 12 | 0) >> 2] | 0 | 0](HEAP32[($2_1 + 48 | 0) >> 2] | 0, 1048822, 2) | 0; + break label$2; + } + break label$2; + } + $3_1 = 1; + if (!($0_1 & 1 | 0)) { + $3_1 = FUNCTION_TABLE[HEAP32[((HEAP32[($1_1 + 24 | 0) >> 2] | 0) + 12 | 0) >> 2] | 0 | 0](HEAP32[($1_1 + 20 | 0) >> 2] | 0, 1048825, 1) | 0 + } + global$0 = $2_1 - -64 | 0; + return $3_1 | 0; + } + $0_1 = $36($4_1 | 0, $1_1 | 0) | 0; + } + $4_1 = $4_1 + 1 | 0; + $3_1 = $3_1 - 1 | 0; + continue label$1; + }; + } + + function $36($0_1, $1_1) { + $0_1 = $0_1 | 0; + $1_1 = $1_1 | 0; + var $2_1 = 0, $3_1 = 0, $5_1 = 0, $6_1 = 0, $4_1 = 0, $22_1 = 0, i64toi32_i32$1 = 0; + $4_1 = global$0 - 128 | 0; + global$0 = $4_1; + label$1 : { + label$2 : { + label$3 : { + $2_1 = HEAP32[($1_1 + 28 | 0) >> 2] | 0; + if (!($2_1 & 16 | 0)) { + if ($2_1 & 32 | 0) { + break label$3 + } + i64toi32_i32$1 = 0; + $22_1 = $20(HEAPU8[$0_1 >> 0] | 0 | 0, i64toi32_i32$1 | 0, $1_1 | 0) | 0; + break label$1; + } + $0_1 = HEAPU8[$0_1 >> 0] | 0; + $2_1 = 127; + label$5 : while (1) { + $3_1 = $2_1; + $5_1 = $4_1 + $2_1 | 0; + $2_1 = $0_1 & 15 | 0; + HEAP8[$5_1 >> 0] = $2_1 >>> 0 < 10 >>> 0 ? $2_1 | 48 | 0 : $2_1 + 87 | 0; + $2_1 = $3_1 - 1 | 0; + $6_1 = $0_1 & 255 | 0; + $0_1 = $6_1 >>> 4 | 0; + if ($6_1 >>> 0 >= 16 >>> 0) { + continue label$5 + } + break label$5; + }; + break label$2; + } + $0_1 = HEAPU8[$0_1 >> 0] | 0; + $2_1 = 127; + label$6 : while (1) { + $3_1 = $2_1; + $5_1 = $4_1 + $2_1 | 0; + $2_1 = $0_1 & 15 | 0; + HEAP8[$5_1 >> 0] = $2_1 >>> 0 < 10 >>> 0 ? $2_1 | 48 | 0 : $2_1 + 55 | 0; + $2_1 = $3_1 - 1 | 0; + $6_1 = $0_1 & 255 | 0; + $0_1 = $6_1 >>> 4 | 0; + if ($6_1 >>> 0 >= 16 >>> 0) { + continue label$6 + } + break label$6; + }; + if ($3_1 >>> 0 >= 129 >>> 0) { + $18($3_1 | 0); + wasm2js_trap(); + } + $22_1 = $21($1_1 | 0, 1048864 | 0, 2 | 0, $5_1 | 0, 128 - $3_1 | 0 | 0) | 0; + break label$1; + } + if ($3_1 >>> 0 >= 129 >>> 0) { + $18($3_1 | 0); + wasm2js_trap(); + } + $22_1 = $21($1_1 | 0, 1048864 | 0, 2 | 0, $5_1 | 0, 128 - $3_1 | 0 | 0) | 0; + } + global$0 = $4_1 + 128 | 0; + return $22_1 | 0; + } + + function $37($0_1, $1_1, $2_1) { + $0_1 = $0_1 | 0; + $1_1 = $1_1 | 0; + $2_1 = $2_1 | 0; + if ($0_1) { + $9($1_1 | 0, Math_imul($0_1, $2_1) | 0) + } + } + + function $38($0_1, $1_1) { + $0_1 = $0_1 | 0; + $1_1 = $1_1 | 0; + var $2_1 = 0; + $2_1 = $34($0_1 + 20 | 0 | 0) | 0; + HEAP32[($2_1 + 16 | 0) >> 2] = $0_1; + HEAP32[($2_1 + 12 | 0) >> 2] = $1_1; + HEAP32[($2_1 + 4 | 0) >> 2] = 0; + HEAP32[$2_1 >> 2] = $2_1; + return $2_1 | 0; + } + + function $39($0_1, $1_1, $2_1) { + $0_1 = $0_1 | 0; + $1_1 = $1_1 | 0; + $2_1 = $2_1 | 0; + var $8_1 = 0; + $0_1 = $38($2_1 | 0, $0_1 | 0) | 0; + $8_1 = $1_1; + $1_1 = HEAP32[($0_1 + 16 | 0) >> 2] | 0; + $57($0_1 + 20 | 0 | 0, $8_1 | 0, ($1_1 >>> 0 < $2_1 >>> 0 ? $1_1 : $2_1) | 0) | 0; + return $0_1 | 0; + } + + function $40($0_1) { + $0_1 = $0_1 | 0; + var $2_1 = 0, $1_1 = 0, $3_1 = 0, $4_1 = 0, $5_1 = 0, $6_1 = 0, $7_1 = 0, $8_1 = 0, $9_1 = 0, $10_1 = 0, $67 = 0, $11_1 = 0, $12_1 = 0, $123 = 0, $204 = 0; + label$1 : { + label$2 : { + label$3 : { + label$4 : { + label$5 : { + $2_1 = HEAP32[($0_1 + 4 | 0) >> 2] | 0; + switch ($2_1 | 0) { + case 1: + break label$3; + case 0: + break label$5; + default: + break label$4; + }; + } + $3_1 = $0_1 + 20 | 0; + $10_1 = HEAP32[1049700 >> 2] | 0; + $4_1 = $10_1 << 2 | 0; + $11_1 = (HEAP32[($0_1 + 16 | 0) >> 2] | 0) + 20 | 0; + $2_1 = HEAP32[1049696 >> 2] | 0; + $1_1 = $2_1; + label$6 : while (1) { + if (!$4_1) { + break label$1 + } + if ((HEAP32[$1_1 >> 2] | 0 | 0) == ($3_1 | 0)) { + break label$2 + } + $4_1 = $4_1 - 4 | 0; + $6_1 = $6_1 + 1 | 0; + $1_1 = $1_1 + 4 | 0; + continue label$6; + }; + } + HEAP32[($0_1 + 4 | 0) >> 2] = $2_1 - 1 | 0; + } + $9($0_1 | 0, 20 | 0); + return; + } + label$7 : { + label$8 : { + label$9 : { + $7_1 = ($10_1 + ($6_1 ^ -1 | 0) | 0) << 2 | 0; + $2_1 = $2_1 + ($6_1 << 2 | 0) | 0; + $1_1 = $2_1 + 4 | 0; + if ($7_1 >>> 0 > ($2_1 - $1_1 | 0) >>> 0) { + $8_1 = $1_1 + $7_1 | 0; + $3_1 = $2_1 + $7_1 | 0; + $67 = $2_1; + if ($7_1 >>> 0 < 16 >>> 0) { + break label$8 + } + $5_1 = $3_1 & -4 | 0; + $6_1 = $3_1 & 3 | 0; + $12_1 = 0 - $6_1 | 0; + if ($6_1) { + $4_1 = $8_1 - 1 | 0; + label$12 : while (1) { + $3_1 = $3_1 - 1 | 0; + HEAP8[$3_1 >> 0] = HEAPU8[$4_1 >> 0] | 0; + $4_1 = $4_1 - 1 | 0; + if ($3_1 >>> 0 > $5_1 >>> 0) { + continue label$12 + } + break label$12; + }; + } + $7_1 = $7_1 - $6_1 | 0; + $9_1 = $7_1 & -4 | 0; + $3_1 = $5_1 - $9_1 | 0; + $8_1 = $12_1 + $8_1 | 0; + if ($8_1 & 3 | 0) { + if (($9_1 | 0) <= (0 | 0)) { + break label$9 + } + $2_1 = $8_1 << 3 | 0; + $6_1 = $2_1 & 24 | 0; + $4_1 = $8_1 & -4 | 0; + $1_1 = $4_1 - 4 | 0; + $2_1 = (0 - $2_1 | 0) & 24 | 0; + $4_1 = HEAP32[$4_1 >> 2] | 0; + label$14 : while (1) { + $5_1 = $5_1 - 4 | 0; + $123 = $4_1 << $2_1 | 0; + $4_1 = HEAP32[$1_1 >> 2] | 0; + HEAP32[$5_1 >> 2] = $123 | ($4_1 >>> $6_1 | 0) | 0; + $1_1 = $1_1 - 4 | 0; + if ($3_1 >>> 0 < $5_1 >>> 0) { + continue label$14 + } + break label$14; + }; + break label$9; + } + if (($9_1 | 0) <= (0 | 0)) { + break label$9 + } + $1_1 = ($1_1 + $7_1 | 0) - 4 | 0; + label$15 : while (1) { + $5_1 = $5_1 - 4 | 0; + HEAP32[$5_1 >> 2] = HEAP32[$1_1 >> 2] | 0; + $1_1 = $1_1 - 4 | 0; + if ($3_1 >>> 0 < $5_1 >>> 0) { + continue label$15 + } + break label$15; + }; + break label$9; + } + label$16 : { + if ($7_1 >>> 0 < 16 >>> 0) { + $3_1 = $2_1; + break label$16; + } + $6_1 = (0 - $2_1 | 0) & 3 | 0; + $5_1 = $2_1 + $6_1 | 0; + if ($6_1) { + $3_1 = $2_1; + $4_1 = $1_1; + label$19 : while (1) { + HEAP8[$3_1 >> 0] = HEAPU8[$4_1 >> 0] | 0; + $4_1 = $4_1 + 1 | 0; + $3_1 = $3_1 + 1 | 0; + if ($3_1 >>> 0 < $5_1 >>> 0) { + continue label$19 + } + break label$19; + }; + } + $8_1 = $7_1 - $6_1 | 0; + $9_1 = $8_1 & -4 | 0; + $3_1 = $5_1 + $9_1 | 0; + label$20 : { + $2_1 = $1_1 + $6_1 | 0; + if ($2_1 & 3 | 0) { + if (($9_1 | 0) <= (0 | 0)) { + break label$20 + } + $6_1 = $2_1 << 3 | 0; + $7_1 = $6_1 & 24 | 0; + $4_1 = $2_1 & -4 | 0; + $1_1 = $4_1 + 4 | 0; + $6_1 = (0 - $6_1 | 0) & 24 | 0; + $4_1 = HEAP32[$4_1 >> 2] | 0; + label$22 : while (1) { + $204 = $4_1 >>> $7_1 | 0; + $4_1 = HEAP32[$1_1 >> 2] | 0; + HEAP32[$5_1 >> 2] = $204 | ($4_1 << $6_1 | 0) | 0; + $1_1 = $1_1 + 4 | 0; + $5_1 = $5_1 + 4 | 0; + if ($5_1 >>> 0 < $3_1 >>> 0) { + continue label$22 + } + break label$22; + }; + break label$20; + } + if (($9_1 | 0) <= (0 | 0)) { + break label$20 + } + $1_1 = $2_1; + label$23 : while (1) { + HEAP32[$5_1 >> 2] = HEAP32[$1_1 >> 2] | 0; + $1_1 = $1_1 + 4 | 0; + $5_1 = $5_1 + 4 | 0; + if ($5_1 >>> 0 < $3_1 >>> 0) { + continue label$23 + } + break label$23; + }; + } + $7_1 = $8_1 & 3 | 0; + $1_1 = $2_1 + $9_1 | 0; + } + if (!$7_1) { + break label$7 + } + $2_1 = $3_1 + $7_1 | 0; + label$24 : while (1) { + HEAP8[$3_1 >> 0] = HEAPU8[$1_1 >> 0] | 0; + $1_1 = $1_1 + 1 | 0; + $3_1 = $3_1 + 1 | 0; + if ($3_1 >>> 0 < $2_1 >>> 0) { + continue label$24 + } + break label$24; + }; + break label$7; + } + $2_1 = $7_1 & 3 | 0; + if (!$2_1) { + break label$7 + } + $8_1 = $8_1 - $9_1 | 0; + $67 = $3_1 - $2_1 | 0; + } + $2_1 = $67; + $1_1 = $8_1 - 1 | 0; + label$25 : while (1) { + $3_1 = $3_1 - 1 | 0; + HEAP8[$3_1 >> 0] = HEAPU8[$1_1 >> 0] | 0; + $1_1 = $1_1 - 1 | 0; + if ($2_1 >>> 0 < $3_1 >>> 0) { + continue label$25 + } + break label$25; + }; + } + HEAP32[1049700 >> 2] = $10_1 - 1 | 0; + } + $9($0_1 | 0, $11_1 | 0); + } + + function $41($0_1, $1_1) { + $0_1 = $0_1 | 0; + $1_1 = $1_1 | 0; + var i64toi32_i32$1 = 0, i64toi32_i32$2 = 0, i64toi32_i32$0 = 0, $2_1 = 0, i64toi32_i32$3 = 0, $3_1 = 0, $27_1 = 0; + $2_1 = $1_1 - 20 | 0; + HEAP32[($2_1 + 4 | 0) >> 2] = (HEAP32[($2_1 + 4 | 0) >> 2] | 0) + 1 | 0; + $3_1 = HEAP32[($2_1 + 16 | 0) >> 2] | 0; + if ($3_1 >>> 0 <= 3 >>> 0) { + $0_1 = global$0 - 48 | 0; + global$0 = $0_1; + HEAP32[$0_1 >> 2] = 4; + HEAP32[($0_1 + 4 | 0) >> 2] = $3_1; + HEAP32[($0_1 + 12 | 0) >> 2] = 2; + HEAP32[($0_1 + 8 | 0) >> 2] = 1049152; + i64toi32_i32$1 = $0_1; + i64toi32_i32$0 = 0; + HEAP32[($0_1 + 20 | 0) >> 2] = 2; + HEAP32[($0_1 + 24 | 0) >> 2] = i64toi32_i32$0; + i64toi32_i32$0 = 0; + i64toi32_i32$2 = $0_1 + 4 | 0; + i64toi32_i32$1 = 1; + i64toi32_i32$3 = 0; + i64toi32_i32$1 = i64toi32_i32$0 | i64toi32_i32$1 | 0; + $27_1 = i64toi32_i32$2 | i64toi32_i32$3 | 0; + i64toi32_i32$2 = $0_1; + HEAP32[($0_1 + 40 | 0) >> 2] = $27_1; + HEAP32[($0_1 + 44 | 0) >> 2] = i64toi32_i32$1; + i64toi32_i32$1 = 0; + i64toi32_i32$0 = $0_1; + i64toi32_i32$2 = 1; + i64toi32_i32$3 = 0; + i64toi32_i32$2 = i64toi32_i32$1 | i64toi32_i32$2 | 0; + i64toi32_i32$0 = $0_1; + HEAP32[($0_1 + 32 | 0) >> 2] = $0_1 | i64toi32_i32$3 | 0; + HEAP32[($0_1 + 36 | 0) >> 2] = i64toi32_i32$2; + HEAP32[($0_1 + 16 | 0) >> 2] = $0_1 + 32 | 0; + $2($0_1 + 8 | 0 | 0, 1049412 | 0); + wasm2js_trap(); + } + $1_1 = (HEAPU8[$1_1 >> 0] | 0 | ((HEAPU8[($1_1 + 1 | 0) >> 0] | 0) << 8 | 0) | 0 | ((HEAPU8[($1_1 + 2 | 0) >> 0] | 0) << 16 | 0 | ((HEAPU8[($1_1 + 3 | 0) >> 0] | 0) << 24 | 0) | 0) | 0) - 20 | 0; + HEAP32[($1_1 + 4 | 0) >> 2] = (HEAP32[($1_1 + 4 | 0) >> 2] | 0) + 1 | 0; + HEAP32[($0_1 + 4 | 0) >> 2] = $1_1; + HEAP32[$0_1 >> 2] = $2_1; + } + + function $42($0_1, $1_1) { + $0_1 = $0_1 | 0; + $1_1 = $1_1 | 0; + var $2_1 = 0; + $2_1 = HEAP32[($0_1 + 4 | 0) >> 2] | 0; + if ($2_1 >>> 0 >= 2 >>> 0) { + HEAP32[($0_1 + 4 | 0) >> 2] = $2_1 - 1 | 0 + } + $0_1 = HEAP32[($1_1 + 4 | 0) >> 2] | 0; + if ($0_1 >>> 0 >= 2 >>> 0) { + HEAP32[($1_1 + 4 | 0) >> 2] = $0_1 - 1 | 0 + } + } + + function $43($0_1, $1_1) { + $0_1 = $0_1 | 0; + $1_1 = $1_1 | 0; + var $2_1 = 0, $3_1 = 0, $4_1 = 0, $5_1 = 0, $6_1 = 0, $7_1 = 0, i64toi32_i32$1 = 0, $11_1 = 0, $12_1 = 0, $152 = 0, $8_1 = 0; + $2_1 = global$0 - 96 | 0; + global$0 = $2_1; + label$1 : { + if ($1_1 >>> 0 >= 16 >>> 0) { + $4_1 = $23($0_1 | 0, $1_1 | 0) | 0; + break label$1; + } + if (!$1_1) { + break label$1 + } + $5_1 = $1_1 & 3 | 0; + if ($1_1 >>> 0 >= 4 >>> 0) { + $3_1 = $0_1; + $7_1 = $1_1 & 12 | 0; + $6_1 = $7_1; + label$4 : while (1) { + $4_1 = ((($4_1 + ((HEAP8[$3_1 >> 0] | 0 | 0) > (-65 | 0)) | 0) + ((HEAP8[($3_1 + 1 | 0) >> 0] | 0 | 0) > (-65 | 0)) | 0) + ((HEAP8[($3_1 + 2 | 0) >> 0] | 0 | 0) > (-65 | 0)) | 0) + ((HEAP8[($3_1 + 3 | 0) >> 0] | 0 | 0) > (-65 | 0)) | 0; + $3_1 = $3_1 + 4 | 0; + $6_1 = $6_1 - 4 | 0; + if ($6_1) { + continue label$4 + } + break label$4; + }; + } + if (!$5_1) { + break label$1 + } + $3_1 = $0_1 + $7_1 | 0; + label$5 : while (1) { + $4_1 = $4_1 + ((HEAP8[$3_1 >> 0] | 0 | 0) > (-65 | 0)) | 0; + $3_1 = $3_1 + 1 | 0; + $5_1 = $5_1 - 1 | 0; + if ($5_1) { + continue label$5 + } + break label$5; + }; + } + $5_1 = $2_1 + 48 | 0; + HEAP32[($2_1 + 32 | 0) >> 2] = $5_1; + HEAP16[($2_1 + 46 | 0) >> 1] = $4_1; + HEAP32[($2_1 + 36 | 0) >> 2] = $0_1; + HEAP32[($2_1 + 40 | 0) >> 2] = $0_1 + $1_1 | 0; + HEAP32[($2_1 + 28 | 0) >> 2] = $2_1 + 46 | 0; + $4_1 = $2_1 + 28 | 0; + $29($2_1 + 60 | 0 | 0, $4_1 | 0); + label$6 : { + if ((HEAP32[($2_1 + 64 | 0) >> 2] | 0 | 0) == (1 | 0)) { + $30($2_1 + 16 | 0 | 0, HEAP32[($2_1 + 68 | 0) >> 2] | 0 | 0); + $3_1 = 0; + HEAP32[($2_1 + 56 | 0) >> 2] = 0; + i64toi32_i32$1 = HEAP32[($2_1 + 20 | 0) >> 2] | 0; + HEAP32[($2_1 + 48 | 0) >> 2] = HEAP32[($2_1 + 16 | 0) >> 2] | 0; + HEAP32[($2_1 + 52 | 0) >> 2] = i64toi32_i32$1; + $29($2_1 + 72 | 0 | 0, $4_1 | 0); + if ((HEAP32[($2_1 + 76 | 0) >> 2] | 0 | 0) == (1 | 0)) { + $32($5_1 | 0, HEAP32[($2_1 + 80 | 0) >> 2] | 0 | 0); + $5_1 = HEAP32[($2_1 + 52 | 0) >> 2] | 0; + $6_1 = HEAP32[($2_1 + 56 | 0) >> 2] | 0; + $4_1 = $5_1 + $6_1 | 0; + label$9 : while (1) { + HEAP8[($3_1 + $4_1 | 0) >> 0] = HEAPU8[(($2_1 + 46 | 0) + $3_1 | 0) >> 0] | 0; + $3_1 = $3_1 + 1 | 0; + if (($3_1 | 0) != (2 | 0)) { + continue label$9 + } + break label$9; + }; + if ($1_1) { + $7_1 = $3_1 + $4_1 | 0; + $4_1 = 0; + label$11 : while (1) { + HEAP8[($4_1 + $7_1 | 0) >> 0] = HEAPU8[($0_1 + $4_1 | 0) >> 0] | 0; + $4_1 = $4_1 + 1 | 0; + if (($1_1 | 0) != ($4_1 | 0)) { + continue label$11 + } + break label$11; + }; + $152 = ($3_1 + $6_1 | 0) + $4_1 | 0; + } else { + $152 = $3_1 + $6_1 | 0 + } + $0_1 = $152; + $7_1 = HEAP32[($2_1 + 48 | 0) >> 2] | 0; + $6_1 = $39(1 | 0, $5_1 | 0, $0_1 | 0) | 0; + HEAP32[($2_1 + 36 | 0) >> 2] = $0_1; + $0_1 = $6_1 + 20 | 0; + HEAP32[($2_1 + 32 | 0) >> 2] = $0_1; + HEAP32[($2_1 + 28 | 0) >> 2] = $0_1; + $30($2_1 + 8 | 0 | 0, 12 | 0); + $1_1 = HEAP32[($2_1 + 12 | 0) >> 2] | 0; + HEAP32[($2_1 + 76 | 0) >> 2] = $1_1; + HEAP32[($2_1 + 72 | 0) >> 2] = HEAP32[($2_1 + 8 | 0) >> 2] | 0; + $4_1 = 0; + $3_1 = 0; + label$13 : while (1) { + HEAP32[($2_1 + 80 | 0) >> 2] = $4_1; + if (($3_1 | 0) == (12 | 0)) { + break label$6 + } + $32($2_1 + 72 | 0 | 0, 4 | 0); + $1_1 = HEAP32[($2_1 + 76 | 0) >> 2] | 0; + $0_1 = HEAP32[($2_1 + 80 | 0) >> 2] | 0; + $11_1 = $1_1 + $0_1 | 0; + $12_1 = HEAP32[(($2_1 + 28 | 0) + $3_1 | 0) >> 2] | 0; + HEAP8[$11_1 >> 0] = $12_1; + HEAP8[($11_1 + 1 | 0) >> 0] = $12_1 >>> 8 | 0; + HEAP8[($11_1 + 2 | 0) >> 0] = $12_1 >>> 16 | 0; + HEAP8[($11_1 + 3 | 0) >> 0] = $12_1 >>> 24 | 0; + $3_1 = $3_1 + 4 | 0; + $4_1 = $0_1 + 4 | 0; + continue label$13; + }; + } + HEAP32[($2_1 + 88 | 0) >> 2] = 0; + HEAP32[($2_1 + 76 | 0) >> 2] = 1; + HEAP32[($2_1 + 72 | 0) >> 2] = 1049188; + i64toi32_i32$1 = 0; + HEAP32[($2_1 + 80 | 0) >> 2] = 4; + HEAP32[($2_1 + 84 | 0) >> 2] = i64toi32_i32$1; + $2($2_1 + 72 | 0 | 0, 1049384 | 0); + wasm2js_trap(); + } + HEAP32[($2_1 + 88 | 0) >> 2] = 0; + HEAP32[($2_1 + 76 | 0) >> 2] = 1; + HEAP32[($2_1 + 72 | 0) >> 2] = 1049188; + i64toi32_i32$1 = 0; + HEAP32[($2_1 + 80 | 0) >> 2] = 4; + HEAP32[($2_1 + 84 | 0) >> 2] = i64toi32_i32$1; + $2($2_1 + 72 | 0 | 0, 1049292 | 0); + wasm2js_trap(); + } + $8_1 = HEAP32[($2_1 + 72 | 0) >> 2] | 0; + $0_1 = $39(2 | 0, $1_1 | 0, $4_1 | 0) | 0; + $37($8_1 | 0, $1_1 | 0, 1 | 0); + $37($7_1 | 0, $5_1 | 0, 1 | 0); + fimport$0($0_1 + 20 | 0 | 0); + $40($0_1 | 0); + $40($6_1 | 0); + global$0 = $2_1 + 96 | 0; + } + + function $44($0_1) { + $0_1 = $0_1 | 0; + var $1_1 = 0, $3_1 = 0, $2_1 = 0; + $1_1 = global$0 + -64 | 0; + global$0 = $1_1; + $41($1_1 | 0, $0_1 | 0); + $2_1 = HEAP32[$1_1 >> 2] | 0; + $0_1 = HEAP32[($1_1 + 4 | 0) >> 2] | 0; + HEAP32[($1_1 + 28 | 0) >> 2] = 1; + HEAP32[($1_1 + 24 | 0) >> 2] = 1049440; + HEAP32[($1_1 + 36 | 0) >> 2] = 1; + HEAP32[($1_1 + 52 | 0) >> 2] = 4; + HEAP32[($1_1 + 56 | 0) >> 2] = $0_1 + 20 | 0; + HEAP32[($1_1 + 60 | 0) >> 2] = HEAP32[($0_1 + 16 | 0) >> 2] | 0; + HEAP32[($1_1 + 40 | 0) >> 2] = 0; + HEAP32[($1_1 + 32 | 0) >> 2] = $1_1 + 48 | 0; + HEAP32[($1_1 + 48 | 0) >> 2] = $1_1 + 56 | 0; + $45($1_1 + 12 | 0 | 0, $1_1 + 24 | 0 | 0); + $3_1 = HEAP32[($1_1 + 16 | 0) >> 2] | 0; + $43($3_1 | 0, HEAP32[($1_1 + 20 | 0) >> 2] | 0 | 0); + $37(HEAP32[($1_1 + 12 | 0) >> 2] | 0 | 0, $3_1 | 0, 1 | 0); + $3_1 = HEAP32[($0_1 + 4 | 0) >> 2] | 0; + if ($3_1 >>> 0 >= 2 >>> 0) { + HEAP32[($0_1 + 4 | 0) >> 2] = $3_1 - 1 | 0 + } + $0_1 = HEAP32[($2_1 + 4 | 0) >> 2] | 0; + if ($0_1 >>> 0 >= 2 >>> 0) { + HEAP32[($2_1 + 4 | 0) >> 2] = $0_1 - 1 | 0 + } + global$0 = $1_1 - -64 | 0; + return $2_1 + 20 | 0 | 0; + } + + function $45($0_1, $1_1) { + $0_1 = $0_1 | 0; + $1_1 = $1_1 | 0; + var $2_1 = 0, $4_1 = 0, $3_1 = 0, $5_1 = 0, i64toi32_i32$0 = 0, i64toi32_i32$1 = 0, i64toi32_i32$2 = 0, $6_1 = 0, $7_1 = 0, $8_1 = 0, $9_1 = 0, i64toi32_i32$3 = 0, $21_1 = 0, $122 = 0, $146 = 0, $151 = 0; + $4_1 = global$0 - 32 | 0; + global$0 = $4_1; + $8_1 = HEAP32[($1_1 + 12 | 0) >> 2] | 0; + $6_1 = HEAP32[$1_1 >> 2] | 0; + label$1 : { + label$2 : { + label$3 : { + label$4 : { + label$5 : { + label$6 : { + label$7 : { + label$8 : { + label$9 : { + label$10 : { + label$11 : { + label$12 : { + label$13 : { + $5_1 = HEAP32[($1_1 + 4 | 0) >> 2] | 0; + switch ($5_1 | 0) { + case 1: + break label$11; + case 0: + break label$13; + default: + break label$12; + }; + } + if ($8_1) { + break label$7 + } + $21_1 = 1; + break label$10; + } + $7_1 = $5_1 & 3 | 0; + label$14 : { + if ($5_1 >>> 0 < 4 >>> 0) { + $5_1 = 0; + break label$14; + } + $2_1 = $6_1 + 28 | 0; + $5_1 = $5_1 & -4 | 0; + $9_1 = $5_1; + label$16 : while (1) { + $3_1 = (HEAP32[$2_1 >> 2] | 0) + ((HEAP32[($2_1 - 8 | 0) >> 2] | 0) + ((HEAP32[($2_1 - 16 | 0) >> 2] | 0) + ((HEAP32[($2_1 - 24 | 0) >> 2] | 0) + $3_1 | 0) | 0) | 0) | 0; + $2_1 = $2_1 + 32 | 0; + $9_1 = $9_1 - 4 | 0; + if ($9_1) { + continue label$16 + } + break label$16; + }; + } + if (!$7_1) { + break label$8 + } + break label$9; + } + if ($8_1) { + $7_1 = $5_1 & 3 | 0; + $5_1 = 0; + break label$9; + } + $2_1 = HEAP32[($6_1 + 4 | 0) >> 2] | 0; + $21_1 = HEAP32[$6_1 >> 2] | 0; + } + $1_1 = $21_1; + $30($4_1 + 8 | 0 | 0, $2_1 | 0); + $3_1 = HEAP32[($4_1 + 8 | 0) >> 2] | 0; + $1_1 = $57(HEAP32[($4_1 + 12 | 0) >> 2] | 0 | 0, $1_1 | 0, $2_1 | 0) | 0; + HEAP32[($0_1 + 8 | 0) >> 2] = $2_1; + HEAP32[($0_1 + 4 | 0) >> 2] = $1_1; + HEAP32[$0_1 >> 2] = $3_1; + break label$4; + } + $2_1 = (($5_1 << 3 | 0) + $6_1 | 0) + 4 | 0; + label$18 : while (1) { + $3_1 = (HEAP32[$2_1 >> 2] | 0) + $3_1 | 0; + $2_1 = $2_1 + 8 | 0; + $7_1 = $7_1 - 1 | 0; + if ($7_1) { + continue label$18 + } + break label$18; + }; + } + if ($8_1) { + if (($3_1 | 0) < (0 | 0)) { + break label$7 + } + if (!(HEAP32[($6_1 + 4 | 0) >> 2] | 0) & $3_1 >>> 0 < 16 >>> 0 | 0) { + break label$7 + } + $3_1 = $3_1 << 1 | 0; + } + if (($3_1 | 0) < (0 | 0)) { + break label$3 + } + if ($3_1) { + break label$6 + } + } + $2_1 = 1; + $3_1 = 0; + break label$5; + } + HEAPU8[1049704 >> 0] | 0; + $2_1 = $6($3_1 | 0) | 0; + if (!$2_1) { + break label$2 + } + } + HEAP32[($4_1 + 24 | 0) >> 2] = 0; + HEAP32[($4_1 + 20 | 0) >> 2] = $2_1; + HEAP32[($4_1 + 16 | 0) >> 2] = $3_1; + if ($13($4_1 + 16 | 0 | 0, 1048576 | 0, $1_1 | 0) | 0) { + break label$1 + } + i64toi32_i32$2 = $4_1; + i64toi32_i32$0 = HEAP32[($4_1 + 16 | 0) >> 2] | 0; + i64toi32_i32$1 = HEAP32[($4_1 + 20 | 0) >> 2] | 0; + $122 = i64toi32_i32$0; + i64toi32_i32$0 = $0_1; + HEAP32[$0_1 >> 2] = $122; + HEAP32[($0_1 + 4 | 0) >> 2] = i64toi32_i32$1; + HEAP32[($0_1 + 8 | 0) >> 2] = HEAP32[($4_1 + 24 | 0) >> 2] | 0; + } + global$0 = $4_1 + 32 | 0; + return; + } + $1(); + } + wasm2js_trap(); + } + $0_1 = global$0 + -64 | 0; + global$0 = $0_1; + HEAP32[($0_1 + 12 | 0) >> 2] = 86; + HEAP32[($0_1 + 8 | 0) >> 2] = 1048652; + HEAP32[($0_1 + 20 | 0) >> 2] = 1048636; + HEAP32[($0_1 + 16 | 0) >> 2] = $4_1 + 31 | 0; + HEAP32[($0_1 + 28 | 0) >> 2] = 2; + HEAP32[($0_1 + 24 | 0) >> 2] = 1048776; + i64toi32_i32$0 = $0_1; + i64toi32_i32$1 = 0; + HEAP32[($0_1 + 36 | 0) >> 2] = 2; + HEAP32[($0_1 + 40 | 0) >> 2] = i64toi32_i32$1; + i64toi32_i32$1 = 0; + i64toi32_i32$2 = $0_1 + 16 | 0; + i64toi32_i32$0 = 2; + i64toi32_i32$3 = 0; + i64toi32_i32$0 = i64toi32_i32$1 | i64toi32_i32$0 | 0; + $146 = i64toi32_i32$2 | i64toi32_i32$3 | 0; + i64toi32_i32$2 = $0_1; + HEAP32[($0_1 + 56 | 0) >> 2] = $146; + HEAP32[($0_1 + 60 | 0) >> 2] = i64toi32_i32$0; + i64toi32_i32$0 = 0; + i64toi32_i32$1 = $0_1 + 8 | 0; + i64toi32_i32$2 = 3; + i64toi32_i32$3 = 0; + i64toi32_i32$2 = i64toi32_i32$0 | i64toi32_i32$2 | 0; + $151 = i64toi32_i32$1 | i64toi32_i32$3 | 0; + i64toi32_i32$1 = $0_1; + HEAP32[($0_1 + 48 | 0) >> 2] = $151; + HEAP32[($0_1 + 52 | 0) >> 2] = i64toi32_i32$2; + HEAP32[($0_1 + 32 | 0) >> 2] = $0_1 + 48 | 0; + $2($0_1 + 24 | 0 | 0, 1048756 | 0); + wasm2js_trap(); + } + + function $46($0_1) { + $0_1 = $0_1 | 0; + $58($0_1 | 0, 1049468 | 0); + } + + function $47($0_1) { + $0_1 = $0_1 | 0; + $58($0_1 | 0, 1049488 | 0); + } + + function $48($0_1, $1_1) { + $0_1 = $0_1 | 0; + $1_1 = $1_1 | 0; + $0_1 = ($38($0_1 | 0, $1_1 | 0) | 0) + 20 | 0; + $49(1049692 | 0, $0_1 | 0); + return $0_1 | 0; + } + + function $49($0_1, $1_1) { + $0_1 = $0_1 | 0; + $1_1 = $1_1 | 0; + var $3_1 = 0, $2_1 = 0, $4_1 = 0; + $4_1 = HEAP32[($0_1 + 8 | 0) >> 2] | 0; + $3_1 = HEAP32[$0_1 >> 2] | 0; + if (($4_1 | 0) == ($3_1 | 0)) { + $2_1 = global$0 - 16 | 0; + global$0 = $2_1; + $33($2_1 + 8 | 0 | 0, $0_1 | 0, $3_1 | 0, 1 | 0, 4 | 0, 4 | 0); + $3_1 = HEAP32[($2_1 + 8 | 0) >> 2] | 0; + if (($3_1 | 0) != (-2147483647 | 0)) { + HEAP32[($2_1 + 12 | 0) >> 2] | 0; + $0($3_1 | 0); + wasm2js_trap(); + } + global$0 = $2_1 + 16 | 0; + } + HEAP32[($0_1 + 8 | 0) >> 2] = $4_1 + 1 | 0; + HEAP32[((HEAP32[($0_1 + 4 | 0) >> 2] | 0) + ($4_1 << 2 | 0) | 0) >> 2] = $1_1; + } + + function $50($0_1) { + $0_1 = $0_1 | 0; + var $1_1 = 0; + $1_1 = $0_1 - 16 | 0; + HEAP32[$1_1 >> 2] = (HEAP32[$1_1 >> 2] | 0) + 1 | 0; + return $0_1 | 0; + } + + function $51($0_1) { + $0_1 = $0_1 | 0; + var $1_1 = 0, $2_1 = 0; + $1_1 = global$0 - 48 | 0; + global$0 = $1_1; + $0_1 = $0_1 - 20 | 0; + $2_1 = HEAP32[($0_1 + 4 | 0) >> 2] | 0; + if ($2_1 >>> 0 >= 2 >>> 0) { + HEAP32[($0_1 + 4 | 0) >> 2] = $2_1 - 1 | 0 + } + HEAP32[($1_1 + 16 | 0) >> 2] = 1; + HEAP32[($1_1 + 12 | 0) >> 2] = 1049508; + HEAP32[($1_1 + 24 | 0) >> 2] = 1; + HEAP32[($1_1 + 28 | 0) >> 2] = 0; + HEAP32[($1_1 + 40 | 0) >> 2] = 1; + HEAP32[($1_1 + 44 | 0) >> 2] = HEAP32[1049700 >> 2] | 0; + HEAP32[($1_1 + 20 | 0) >> 2] = $1_1 + 36 | 0; + HEAP32[($1_1 + 36 | 0) >> 2] = $1_1 + 44 | 0; + $45($1_1 | 0, $1_1 + 12 | 0 | 0); + $0_1 = HEAP32[($1_1 + 4 | 0) >> 2] | 0; + $43($0_1 | 0, HEAP32[($1_1 + 8 | 0) >> 2] | 0 | 0); + $37(HEAP32[$1_1 >> 2] | 0 | 0, $0_1 | 0, 1 | 0); + global$0 = $1_1 + 48 | 0; + } + + function $52() { + var $0_1 = 0, i64toi32_i32$0 = 0, $1_1 = 0, $2_1 = 0, $3_1 = 0, i64toi32_i32$1 = 0, $34_1 = 0; + $0_1 = global$0 - 16 | 0; + global$0 = $0_1; + i64toi32_i32$1 = $0_1; + i64toi32_i32$0 = 4; + HEAP32[($0_1 + 4 | 0) >> 2] = 0; + HEAP32[($0_1 + 8 | 0) >> 2] = i64toi32_i32$0; + HEAP32[($0_1 + 12 | 0) >> 2] = 0; + $1_1 = (HEAP32[1049700 >> 2] | 0) << 2 | 0; + $2_1 = HEAP32[1049696 >> 2] | 0; + label$1 : while (1) { + if ($1_1) { + label$3 : { + $3_1 = (HEAP32[$2_1 >> 2] | 0) - 20 | 0; + if (!(HEAP32[($3_1 + 4 | 0) >> 2] | 0)) { + $9($3_1 | 0, 20 | 0); + break label$3; + } + $49($0_1 + 4 | 0 | 0, $3_1 + 20 | 0 | 0); + } + $2_1 = $2_1 + 4 | 0; + $1_1 = $1_1 - 4 | 0; + continue label$1; + } + break label$1; + }; + $37(HEAP32[1049692 >> 2] | 0 | 0, HEAP32[1049696 >> 2] | 0 | 0, 4 | 0); + HEAP32[1049700 >> 2] = HEAP32[($0_1 + 12 | 0) >> 2] | 0; + i64toi32_i32$0 = HEAP32[($0_1 + 4 | 0) >> 2] | 0; + i64toi32_i32$1 = HEAP32[($0_1 + 8 | 0) >> 2] | 0; + $34_1 = i64toi32_i32$0; + i64toi32_i32$0 = 1049692; + HEAP32[i64toi32_i32$0 >> 2] = $34_1; + HEAP32[(i64toi32_i32$0 + 4 | 0) >> 2] = i64toi32_i32$1; + global$0 = $0_1 + 16 | 0; + } + + function $53($0_1, $1_1) { + $0_1 = $0_1 | 0; + $1_1 = $1_1 | 0; + HEAP32[$0_1 >> 2] = 0; + } + + function $54($0_1, $1_1) { + $0_1 = $0_1 | 0; + $1_1 = $1_1 | 0; + var $2_1 = 0, $3_1 = 0, $4_1 = 0, $5_1 = 0; + $2_1 = 31; + HEAP32[($0_1 + 16 | 0) >> 2] = 0; + HEAP32[($0_1 + 20 | 0) >> 2] = 0; + if ($1_1 >>> 0 <= 16777215 >>> 0) { + $3_1 = Math_clz32($1_1 >>> 8 | 0); + $2_1 = ((($1_1 >>> (6 - $3_1 | 0) | 0) & 1 | 0) - ($3_1 << 1 | 0) | 0) + 62 | 0; + } + HEAP32[($0_1 + 28 | 0) >> 2] = $2_1; + $4_1 = ($2_1 << 2 | 0) + 1049716 | 0; + $3_1 = 1 << $2_1 | 0; + if (!($3_1 & (HEAP32[1050128 >> 2] | 0) | 0)) { + HEAP32[$4_1 >> 2] = $0_1; + HEAP32[($0_1 + 24 | 0) >> 2] = $4_1; + HEAP32[($0_1 + 12 | 0) >> 2] = $0_1; + HEAP32[($0_1 + 8 | 0) >> 2] = $0_1; + HEAP32[1050128 >> 2] = HEAP32[1050128 >> 2] | 0 | $3_1 | 0; + return; + } + label$3 : { + label$4 : { + $3_1 = HEAP32[$4_1 >> 2] | 0; + if (($1_1 | 0) == ((HEAP32[($3_1 + 4 | 0) >> 2] | 0) & -8 | 0 | 0)) { + $2_1 = $3_1; + break label$4; + } + $5_1 = $1_1 << (($2_1 | 0) != (31 | 0) ? 25 - ($2_1 >>> 1 | 0) | 0 : 0) | 0; + label$6 : while (1) { + $4_1 = ($3_1 + (($5_1 >>> 29 | 0) & 4 | 0) | 0) + 16 | 0; + $2_1 = HEAP32[$4_1 >> 2] | 0; + if (!$2_1) { + break label$3 + } + $5_1 = $5_1 << 1 | 0; + $3_1 = $2_1; + if (((HEAP32[($2_1 + 4 | 0) >> 2] | 0) & -8 | 0 | 0) != ($1_1 | 0)) { + continue label$6 + } + break label$6; + }; + } + $1_1 = HEAP32[($2_1 + 8 | 0) >> 2] | 0; + HEAP32[($1_1 + 12 | 0) >> 2] = $0_1; + HEAP32[($2_1 + 8 | 0) >> 2] = $0_1; + HEAP32[($0_1 + 24 | 0) >> 2] = 0; + HEAP32[($0_1 + 12 | 0) >> 2] = $2_1; + HEAP32[($0_1 + 8 | 0) >> 2] = $1_1; + return; + } + HEAP32[$4_1 >> 2] = $0_1; + HEAP32[($0_1 + 24 | 0) >> 2] = $3_1; + HEAP32[($0_1 + 12 | 0) >> 2] = $0_1; + HEAP32[($0_1 + 8 | 0) >> 2] = $0_1; + } + + function $55($0_1, $1_1, $2_1) { + $0_1 = $0_1 | 0; + $1_1 = $1_1 | 0; + $2_1 = $2_1 | 0; + var $3_1 = 0, $4_1 = 0; + $3_1 = global$0 - 16 | 0; + global$0 = $3_1; + $4_1 = HEAP32[1049712 >> 2] | 0; + HEAP32[1049712 >> 2] = $4_1 + 1 | 0; + label$1 : { + if (($4_1 | 0) < (0 | 0)) { + break label$1 + } + label$2 : { + if (!(HEAPU8[1050172 >> 0] | 0)) { + HEAP32[1050168 >> 2] = (HEAP32[1050168 >> 2] | 0) + 1 | 0; + if ((HEAP32[1049708 >> 2] | 0 | 0) >= (0 | 0)) { + break label$2 + } + break label$1; + } + FUNCTION_TABLE[$1_1 | 0]($3_1 + 8 | 0, $0_1); + wasm2js_trap(); + } + HEAP8[1050172 >> 0] = 0; + if (!$2_1) { + break label$1 + } + wasm2js_trap(); + } + wasm2js_trap(); + } + + function $56($0_1, $1_1) { + $0_1 = $0_1 | 0; + $1_1 = $1_1 | 0; + var i64toi32_i32$0 = 0, i64toi32_i32$2 = 0, i64toi32_i32$1 = 0, $4_1 = 0; + i64toi32_i32$2 = $1_1; + i64toi32_i32$0 = HEAP32[i64toi32_i32$2 >> 2] | 0; + i64toi32_i32$1 = HEAP32[(i64toi32_i32$2 + 4 | 0) >> 2] | 0; + $4_1 = i64toi32_i32$0; + i64toi32_i32$0 = $0_1; + HEAP32[i64toi32_i32$0 >> 2] = $4_1; + HEAP32[(i64toi32_i32$0 + 4 | 0) >> 2] = i64toi32_i32$1; + } + + function $57($0_1, $1_1, $2_1) { + $0_1 = $0_1 | 0; + $1_1 = $1_1 | 0; + $2_1 = $2_1 | 0; + var $3_1 = 0, $4_1 = 0, $5_1 = 0, $6_1 = 0, $7_1 = 0, $8_1 = 0, $9_1 = 0, $63 = 0; + label$1 : { + if ($2_1 >>> 0 < 16 >>> 0) { + $3_1 = $0_1; + break label$1; + } + $4_1 = (0 - $0_1 | 0) & 3 | 0; + $5_1 = $0_1 + $4_1 | 0; + if ($4_1) { + $3_1 = $0_1; + $6_1 = $1_1; + label$4 : while (1) { + HEAP8[$3_1 >> 0] = HEAPU8[$6_1 >> 0] | 0; + $6_1 = $6_1 + 1 | 0; + $3_1 = $3_1 + 1 | 0; + if ($3_1 >>> 0 < $5_1 >>> 0) { + continue label$4 + } + break label$4; + }; + } + $8_1 = $2_1 - $4_1 | 0; + $7_1 = $8_1 & -4 | 0; + $3_1 = $5_1 + $7_1 | 0; + label$5 : { + $4_1 = $1_1 + $4_1 | 0; + if ($4_1 & 3 | 0) { + if (($7_1 | 0) <= (0 | 0)) { + break label$5 + } + $2_1 = $4_1 << 3 | 0; + $9_1 = $2_1 & 24 | 0; + $6_1 = $4_1 & -4 | 0; + $1_1 = $6_1 + 4 | 0; + $2_1 = (0 - $2_1 | 0) & 24 | 0; + $6_1 = HEAP32[$6_1 >> 2] | 0; + label$7 : while (1) { + $63 = $6_1 >>> $9_1 | 0; + $6_1 = HEAP32[$1_1 >> 2] | 0; + HEAP32[$5_1 >> 2] = $63 | ($6_1 << $2_1 | 0) | 0; + $1_1 = $1_1 + 4 | 0; + $5_1 = $5_1 + 4 | 0; + if ($5_1 >>> 0 < $3_1 >>> 0) { + continue label$7 + } + break label$7; + }; + break label$5; + } + if (($7_1 | 0) <= (0 | 0)) { + break label$5 + } + $1_1 = $4_1; + label$8 : while (1) { + HEAP32[$5_1 >> 2] = HEAP32[$1_1 >> 2] | 0; + $1_1 = $1_1 + 4 | 0; + $5_1 = $5_1 + 4 | 0; + if ($5_1 >>> 0 < $3_1 >>> 0) { + continue label$8 + } + break label$8; + }; + } + $2_1 = $8_1 & 3 | 0; + $1_1 = $4_1 + $7_1 | 0; + } + if ($2_1) { + $2_1 = $2_1 + $3_1 | 0; + label$10 : while (1) { + HEAP8[$3_1 >> 0] = HEAPU8[$1_1 >> 0] | 0; + $1_1 = $1_1 + 1 | 0; + $3_1 = $3_1 + 1 | 0; + if ($3_1 >>> 0 < $2_1 >>> 0) { + continue label$10 + } + break label$10; + }; + } + return $0_1 | 0; + } + + function $58($0_1, $1_1) { + $0_1 = $0_1 | 0; + $1_1 = $1_1 | 0; + var $2_1 = 0, $4_1 = 0, $5_1 = 0; + $2_1 = global$0 + -64 | 0; + global$0 = $2_1; + $41($2_1 | 0, $0_1 | 0); + $5_1 = HEAP32[$2_1 >> 2] | 0; + $0_1 = HEAP32[($2_1 + 4 | 0) >> 2] | 0; + HEAP32[($2_1 + 28 | 0) >> 2] = 1; + HEAP32[($2_1 + 24 | 0) >> 2] = $1_1; + HEAP32[($2_1 + 36 | 0) >> 2] = 1; + HEAP32[($2_1 + 52 | 0) >> 2] = 4; + HEAP32[($2_1 + 56 | 0) >> 2] = $0_1 + 20 | 0; + HEAP32[($2_1 + 60 | 0) >> 2] = HEAP32[($0_1 + 16 | 0) >> 2] | 0; + HEAP32[($2_1 + 40 | 0) >> 2] = 0; + HEAP32[($2_1 + 32 | 0) >> 2] = $2_1 + 48 | 0; + HEAP32[($2_1 + 48 | 0) >> 2] = $2_1 + 56 | 0; + $45($2_1 + 12 | 0 | 0, $2_1 + 24 | 0 | 0); + $4_1 = HEAP32[($2_1 + 16 | 0) >> 2] | 0; + $43($4_1 | 0, HEAP32[($2_1 + 20 | 0) >> 2] | 0 | 0); + $37(HEAP32[($2_1 + 12 | 0) >> 2] | 0 | 0, $4_1 | 0, 1 | 0); + $42($5_1 | 0, $0_1 | 0); + global$0 = $2_1 - -64 | 0; + } + + function _ZN17compiler_builtins3int3mul3Mul3mul17h070e9a1c69faec5bE(var$0, var$0$hi, var$1, var$1$hi) { + var$0 = var$0 | 0; + var$0$hi = var$0$hi | 0; + var$1 = var$1 | 0; + var$1$hi = var$1$hi | 0; + var i64toi32_i32$4 = 0, i64toi32_i32$0 = 0, i64toi32_i32$1 = 0, var$2 = 0, i64toi32_i32$2 = 0, i64toi32_i32$3 = 0, var$3 = 0, var$4 = 0, var$5 = 0, $21_1 = 0, $22_1 = 0, var$6 = 0, $24_1 = 0, $17_1 = 0, $18_1 = 0, $23_1 = 0, $29_1 = 0, $45_1 = 0, $56$hi = 0, $62$hi = 0; + i64toi32_i32$0 = var$1$hi; + var$2 = var$1; + var$4 = var$2 >>> 16 | 0; + i64toi32_i32$0 = var$0$hi; + var$3 = var$0; + var$5 = var$3 >>> 16 | 0; + $17_1 = Math_imul(var$4, var$5); + $18_1 = var$2; + i64toi32_i32$2 = var$3; + i64toi32_i32$1 = 0; + i64toi32_i32$3 = 32; + i64toi32_i32$4 = i64toi32_i32$3 & 31 | 0; + if (32 >>> 0 <= (i64toi32_i32$3 & 63 | 0) >>> 0) { + i64toi32_i32$1 = 0; + $21_1 = i64toi32_i32$0 >>> i64toi32_i32$4 | 0; + } else { + i64toi32_i32$1 = i64toi32_i32$0 >>> i64toi32_i32$4 | 0; + $21_1 = (((1 << i64toi32_i32$4 | 0) - 1 | 0) & i64toi32_i32$0 | 0) << (32 - i64toi32_i32$4 | 0) | 0 | (i64toi32_i32$2 >>> i64toi32_i32$4 | 0) | 0; + } + $23_1 = $17_1 + Math_imul($18_1, $21_1) | 0; + i64toi32_i32$1 = var$1$hi; + i64toi32_i32$0 = var$1; + i64toi32_i32$2 = 0; + i64toi32_i32$3 = 32; + i64toi32_i32$4 = i64toi32_i32$3 & 31 | 0; + if (32 >>> 0 <= (i64toi32_i32$3 & 63 | 0) >>> 0) { + i64toi32_i32$2 = 0; + $22_1 = i64toi32_i32$1 >>> i64toi32_i32$4 | 0; + } else { + i64toi32_i32$2 = i64toi32_i32$1 >>> i64toi32_i32$4 | 0; + $22_1 = (((1 << i64toi32_i32$4 | 0) - 1 | 0) & i64toi32_i32$1 | 0) << (32 - i64toi32_i32$4 | 0) | 0 | (i64toi32_i32$0 >>> i64toi32_i32$4 | 0) | 0; + } + $29_1 = $23_1 + Math_imul($22_1, var$3) | 0; + var$2 = var$2 & 65535 | 0; + var$3 = var$3 & 65535 | 0; + var$6 = Math_imul(var$2, var$3); + var$2 = (var$6 >>> 16 | 0) + Math_imul(var$2, var$5) | 0; + $45_1 = $29_1 + (var$2 >>> 16 | 0) | 0; + var$2 = (var$2 & 65535 | 0) + Math_imul(var$4, var$3) | 0; + i64toi32_i32$2 = 0; + i64toi32_i32$1 = $45_1 + (var$2 >>> 16 | 0) | 0; + i64toi32_i32$0 = 0; + i64toi32_i32$3 = 32; + i64toi32_i32$4 = i64toi32_i32$3 & 31 | 0; + if (32 >>> 0 <= (i64toi32_i32$3 & 63 | 0) >>> 0) { + i64toi32_i32$0 = i64toi32_i32$1 << i64toi32_i32$4 | 0; + $24_1 = 0; + } else { + i64toi32_i32$0 = ((1 << i64toi32_i32$4 | 0) - 1 | 0) & (i64toi32_i32$1 >>> (32 - i64toi32_i32$4 | 0) | 0) | 0 | (i64toi32_i32$2 << i64toi32_i32$4 | 0) | 0; + $24_1 = i64toi32_i32$1 << i64toi32_i32$4 | 0; + } + $56$hi = i64toi32_i32$0; + i64toi32_i32$0 = 0; + $62$hi = i64toi32_i32$0; + i64toi32_i32$0 = $56$hi; + i64toi32_i32$2 = $24_1; + i64toi32_i32$1 = $62$hi; + i64toi32_i32$3 = var$2 << 16 | 0 | (var$6 & 65535 | 0) | 0; + i64toi32_i32$1 = i64toi32_i32$0 | i64toi32_i32$1 | 0; + i64toi32_i32$2 = i64toi32_i32$2 | i64toi32_i32$3 | 0; + i64toi32_i32$HIGH_BITS = i64toi32_i32$1; + return i64toi32_i32$2 | 0; + } + + function _ZN17compiler_builtins3int4udiv10divmod_u6417h6026910b5ed08e40E(var$0, var$0$hi, var$1, var$1$hi) { + var$0 = var$0 | 0; + var$0$hi = var$0$hi | 0; + var$1 = var$1 | 0; + var$1$hi = var$1$hi | 0; + var i64toi32_i32$2 = 0, i64toi32_i32$3 = 0, i64toi32_i32$4 = 0, i64toi32_i32$1 = 0, i64toi32_i32$0 = 0, i64toi32_i32$5 = 0, var$2 = 0, var$3 = 0, var$4 = 0, var$5 = 0, var$5$hi = 0, var$6 = 0, var$6$hi = 0, i64toi32_i32$6 = 0, $37_1 = 0, $38_1 = 0, $39_1 = 0, $40_1 = 0, $41_1 = 0, $42_1 = 0, $43_1 = 0, $44_1 = 0, var$8$hi = 0, $45_1 = 0, $46_1 = 0, $47_1 = 0, $48_1 = 0, var$7$hi = 0, $49_1 = 0, $63$hi = 0, $65 = 0, $65$hi = 0, $120$hi = 0, $129$hi = 0, $134$hi = 0, var$8 = 0, $140 = 0, $140$hi = 0, $142$hi = 0, $144 = 0, $144$hi = 0, $151 = 0, $151$hi = 0, $154$hi = 0, var$7 = 0, $165$hi = 0; + label$1 : { + label$2 : { + label$3 : { + label$4 : { + label$5 : { + label$6 : { + label$7 : { + label$8 : { + label$9 : { + label$10 : { + label$11 : { + i64toi32_i32$0 = var$0$hi; + i64toi32_i32$2 = var$0; + i64toi32_i32$1 = 0; + i64toi32_i32$3 = 32; + i64toi32_i32$4 = i64toi32_i32$3 & 31 | 0; + if (32 >>> 0 <= (i64toi32_i32$3 & 63 | 0) >>> 0) { + i64toi32_i32$1 = 0; + $37_1 = i64toi32_i32$0 >>> i64toi32_i32$4 | 0; + } else { + i64toi32_i32$1 = i64toi32_i32$0 >>> i64toi32_i32$4 | 0; + $37_1 = (((1 << i64toi32_i32$4 | 0) - 1 | 0) & i64toi32_i32$0 | 0) << (32 - i64toi32_i32$4 | 0) | 0 | (i64toi32_i32$2 >>> i64toi32_i32$4 | 0) | 0; + } + var$2 = $37_1; + if (var$2) { + i64toi32_i32$1 = var$1$hi; + var$3 = var$1; + if (!var$3) { + break label$11 + } + i64toi32_i32$0 = var$3; + i64toi32_i32$2 = 0; + i64toi32_i32$3 = 32; + i64toi32_i32$4 = i64toi32_i32$3 & 31 | 0; + if (32 >>> 0 <= (i64toi32_i32$3 & 63 | 0) >>> 0) { + i64toi32_i32$2 = 0; + $38_1 = i64toi32_i32$1 >>> i64toi32_i32$4 | 0; + } else { + i64toi32_i32$2 = i64toi32_i32$1 >>> i64toi32_i32$4 | 0; + $38_1 = (((1 << i64toi32_i32$4 | 0) - 1 | 0) & i64toi32_i32$1 | 0) << (32 - i64toi32_i32$4 | 0) | 0 | (i64toi32_i32$0 >>> i64toi32_i32$4 | 0) | 0; + } + var$4 = $38_1; + if (!var$4) { + break label$9 + } + var$2 = Math_clz32(var$4) - Math_clz32(var$2) | 0; + if (var$2 >>> 0 <= 31 >>> 0) { + break label$8 + } + break label$2; + } + i64toi32_i32$2 = var$1$hi; + i64toi32_i32$1 = var$1; + i64toi32_i32$0 = 1; + i64toi32_i32$3 = 0; + if (i64toi32_i32$2 >>> 0 > i64toi32_i32$0 >>> 0 | ((i64toi32_i32$2 | 0) == (i64toi32_i32$0 | 0) & i64toi32_i32$1 >>> 0 >= i64toi32_i32$3 >>> 0 | 0) | 0) { + break label$2 + } + i64toi32_i32$1 = var$0$hi; + var$2 = var$0; + i64toi32_i32$1 = i64toi32_i32$2; + i64toi32_i32$1 = i64toi32_i32$2; + var$3 = var$1; + var$2 = (var$2 >>> 0) / (var$3 >>> 0) | 0; + i64toi32_i32$1 = 0; + __wasm_intrinsics_temp_i64 = var$0 - Math_imul(var$2, var$3) | 0; + __wasm_intrinsics_temp_i64$hi = i64toi32_i32$1; + i64toi32_i32$1 = 0; + i64toi32_i32$2 = var$2; + i64toi32_i32$HIGH_BITS = i64toi32_i32$1; + return i64toi32_i32$2 | 0; + } + i64toi32_i32$2 = var$1$hi; + i64toi32_i32$3 = var$1; + i64toi32_i32$1 = 0; + i64toi32_i32$0 = 32; + i64toi32_i32$4 = i64toi32_i32$0 & 31 | 0; + if (32 >>> 0 <= (i64toi32_i32$0 & 63 | 0) >>> 0) { + i64toi32_i32$1 = 0; + $39_1 = i64toi32_i32$2 >>> i64toi32_i32$4 | 0; + } else { + i64toi32_i32$1 = i64toi32_i32$2 >>> i64toi32_i32$4 | 0; + $39_1 = (((1 << i64toi32_i32$4 | 0) - 1 | 0) & i64toi32_i32$2 | 0) << (32 - i64toi32_i32$4 | 0) | 0 | (i64toi32_i32$3 >>> i64toi32_i32$4 | 0) | 0; + } + var$3 = $39_1; + i64toi32_i32$1 = var$0$hi; + if (!var$0) { + break label$7 + } + if (!var$3) { + break label$6 + } + var$4 = var$3 + -1 | 0; + if (var$4 & var$3 | 0) { + break label$6 + } + i64toi32_i32$1 = 0; + i64toi32_i32$2 = var$4 & var$2 | 0; + i64toi32_i32$3 = 0; + i64toi32_i32$0 = 32; + i64toi32_i32$4 = i64toi32_i32$0 & 31 | 0; + if (32 >>> 0 <= (i64toi32_i32$0 & 63 | 0) >>> 0) { + i64toi32_i32$3 = i64toi32_i32$2 << i64toi32_i32$4 | 0; + $40_1 = 0; + } else { + i64toi32_i32$3 = ((1 << i64toi32_i32$4 | 0) - 1 | 0) & (i64toi32_i32$2 >>> (32 - i64toi32_i32$4 | 0) | 0) | 0 | (i64toi32_i32$1 << i64toi32_i32$4 | 0) | 0; + $40_1 = i64toi32_i32$2 << i64toi32_i32$4 | 0; + } + $63$hi = i64toi32_i32$3; + i64toi32_i32$3 = var$0$hi; + i64toi32_i32$1 = var$0; + i64toi32_i32$2 = 0; + i64toi32_i32$0 = -1; + i64toi32_i32$2 = i64toi32_i32$3 & i64toi32_i32$2 | 0; + $65 = i64toi32_i32$1 & i64toi32_i32$0 | 0; + $65$hi = i64toi32_i32$2; + i64toi32_i32$2 = $63$hi; + i64toi32_i32$3 = $40_1; + i64toi32_i32$1 = $65$hi; + i64toi32_i32$0 = $65; + i64toi32_i32$1 = i64toi32_i32$2 | i64toi32_i32$1 | 0; + __wasm_intrinsics_temp_i64 = i64toi32_i32$3 | i64toi32_i32$0 | 0; + __wasm_intrinsics_temp_i64$hi = i64toi32_i32$1; + i64toi32_i32$1 = 0; + i64toi32_i32$3 = var$2 >>> ((__wasm_ctz_i32(var$3 | 0) | 0) & 31 | 0) | 0; + i64toi32_i32$HIGH_BITS = i64toi32_i32$1; + return i64toi32_i32$3 | 0; + } + } + var$4 = var$3 + -1 | 0; + if (!(var$4 & var$3 | 0)) { + break label$5 + } + var$2 = (Math_clz32(var$3) + 33 | 0) - Math_clz32(var$2) | 0; + var$3 = 0 - var$2 | 0; + break label$3; + } + var$3 = 63 - var$2 | 0; + var$2 = var$2 + 1 | 0; + break label$3; + } + var$4 = (var$2 >>> 0) / (var$3 >>> 0) | 0; + i64toi32_i32$3 = 0; + i64toi32_i32$2 = var$2 - Math_imul(var$4, var$3) | 0; + i64toi32_i32$1 = 0; + i64toi32_i32$0 = 32; + i64toi32_i32$4 = i64toi32_i32$0 & 31 | 0; + if (32 >>> 0 <= (i64toi32_i32$0 & 63 | 0) >>> 0) { + i64toi32_i32$1 = i64toi32_i32$2 << i64toi32_i32$4 | 0; + $41_1 = 0; + } else { + i64toi32_i32$1 = ((1 << i64toi32_i32$4 | 0) - 1 | 0) & (i64toi32_i32$2 >>> (32 - i64toi32_i32$4 | 0) | 0) | 0 | (i64toi32_i32$3 << i64toi32_i32$4 | 0) | 0; + $41_1 = i64toi32_i32$2 << i64toi32_i32$4 | 0; + } + __wasm_intrinsics_temp_i64 = $41_1; + __wasm_intrinsics_temp_i64$hi = i64toi32_i32$1; + i64toi32_i32$1 = 0; + i64toi32_i32$2 = var$4; + i64toi32_i32$HIGH_BITS = i64toi32_i32$1; + return i64toi32_i32$2 | 0; + } + var$2 = Math_clz32(var$3) - Math_clz32(var$2) | 0; + if (var$2 >>> 0 < 31 >>> 0) { + break label$4 + } + break label$2; + } + i64toi32_i32$2 = var$0$hi; + i64toi32_i32$2 = 0; + __wasm_intrinsics_temp_i64 = var$4 & var$0 | 0; + __wasm_intrinsics_temp_i64$hi = i64toi32_i32$2; + if ((var$3 | 0) == (1 | 0)) { + break label$1 + } + i64toi32_i32$2 = var$0$hi; + i64toi32_i32$2 = 0; + $120$hi = i64toi32_i32$2; + i64toi32_i32$2 = var$0$hi; + i64toi32_i32$3 = var$0; + i64toi32_i32$1 = $120$hi; + i64toi32_i32$0 = __wasm_ctz_i32(var$3 | 0) | 0; + i64toi32_i32$4 = i64toi32_i32$0 & 31 | 0; + if (32 >>> 0 <= (i64toi32_i32$0 & 63 | 0) >>> 0) { + i64toi32_i32$1 = 0; + $42_1 = i64toi32_i32$2 >>> i64toi32_i32$4 | 0; + } else { + i64toi32_i32$1 = i64toi32_i32$2 >>> i64toi32_i32$4 | 0; + $42_1 = (((1 << i64toi32_i32$4 | 0) - 1 | 0) & i64toi32_i32$2 | 0) << (32 - i64toi32_i32$4 | 0) | 0 | (i64toi32_i32$3 >>> i64toi32_i32$4 | 0) | 0; + } + i64toi32_i32$3 = $42_1; + i64toi32_i32$HIGH_BITS = i64toi32_i32$1; + return i64toi32_i32$3 | 0; + } + var$3 = 63 - var$2 | 0; + var$2 = var$2 + 1 | 0; + } + i64toi32_i32$3 = var$0$hi; + i64toi32_i32$3 = 0; + $129$hi = i64toi32_i32$3; + i64toi32_i32$3 = var$0$hi; + i64toi32_i32$2 = var$0; + i64toi32_i32$1 = $129$hi; + i64toi32_i32$0 = var$2 & 63 | 0; + i64toi32_i32$4 = i64toi32_i32$0 & 31 | 0; + if (32 >>> 0 <= (i64toi32_i32$0 & 63 | 0) >>> 0) { + i64toi32_i32$1 = 0; + $43_1 = i64toi32_i32$3 >>> i64toi32_i32$4 | 0; + } else { + i64toi32_i32$1 = i64toi32_i32$3 >>> i64toi32_i32$4 | 0; + $43_1 = (((1 << i64toi32_i32$4 | 0) - 1 | 0) & i64toi32_i32$3 | 0) << (32 - i64toi32_i32$4 | 0) | 0 | (i64toi32_i32$2 >>> i64toi32_i32$4 | 0) | 0; + } + var$5 = $43_1; + var$5$hi = i64toi32_i32$1; + i64toi32_i32$1 = var$0$hi; + i64toi32_i32$1 = 0; + $134$hi = i64toi32_i32$1; + i64toi32_i32$1 = var$0$hi; + i64toi32_i32$3 = var$0; + i64toi32_i32$2 = $134$hi; + i64toi32_i32$0 = var$3 & 63 | 0; + i64toi32_i32$4 = i64toi32_i32$0 & 31 | 0; + if (32 >>> 0 <= (i64toi32_i32$0 & 63 | 0) >>> 0) { + i64toi32_i32$2 = i64toi32_i32$3 << i64toi32_i32$4 | 0; + $44_1 = 0; + } else { + i64toi32_i32$2 = ((1 << i64toi32_i32$4 | 0) - 1 | 0) & (i64toi32_i32$3 >>> (32 - i64toi32_i32$4 | 0) | 0) | 0 | (i64toi32_i32$1 << i64toi32_i32$4 | 0) | 0; + $44_1 = i64toi32_i32$3 << i64toi32_i32$4 | 0; + } + var$0 = $44_1; + var$0$hi = i64toi32_i32$2; + label$13 : { + if (var$2) { + i64toi32_i32$2 = var$1$hi; + i64toi32_i32$1 = var$1; + i64toi32_i32$3 = -1; + i64toi32_i32$0 = -1; + i64toi32_i32$4 = i64toi32_i32$1 + i64toi32_i32$0 | 0; + i64toi32_i32$5 = i64toi32_i32$2 + i64toi32_i32$3 | 0; + if (i64toi32_i32$4 >>> 0 < i64toi32_i32$0 >>> 0) { + i64toi32_i32$5 = i64toi32_i32$5 + 1 | 0 + } + var$8 = i64toi32_i32$4; + var$8$hi = i64toi32_i32$5; + label$15 : while (1) { + i64toi32_i32$5 = var$5$hi; + i64toi32_i32$2 = var$5; + i64toi32_i32$1 = 0; + i64toi32_i32$0 = 1; + i64toi32_i32$3 = i64toi32_i32$0 & 31 | 0; + if (32 >>> 0 <= (i64toi32_i32$0 & 63 | 0) >>> 0) { + i64toi32_i32$1 = i64toi32_i32$2 << i64toi32_i32$3 | 0; + $45_1 = 0; + } else { + i64toi32_i32$1 = ((1 << i64toi32_i32$3 | 0) - 1 | 0) & (i64toi32_i32$2 >>> (32 - i64toi32_i32$3 | 0) | 0) | 0 | (i64toi32_i32$5 << i64toi32_i32$3 | 0) | 0; + $45_1 = i64toi32_i32$2 << i64toi32_i32$3 | 0; + } + $140 = $45_1; + $140$hi = i64toi32_i32$1; + i64toi32_i32$1 = var$0$hi; + i64toi32_i32$5 = var$0; + i64toi32_i32$2 = 0; + i64toi32_i32$0 = 63; + i64toi32_i32$3 = i64toi32_i32$0 & 31 | 0; + if (32 >>> 0 <= (i64toi32_i32$0 & 63 | 0) >>> 0) { + i64toi32_i32$2 = 0; + $46_1 = i64toi32_i32$1 >>> i64toi32_i32$3 | 0; + } else { + i64toi32_i32$2 = i64toi32_i32$1 >>> i64toi32_i32$3 | 0; + $46_1 = (((1 << i64toi32_i32$3 | 0) - 1 | 0) & i64toi32_i32$1 | 0) << (32 - i64toi32_i32$3 | 0) | 0 | (i64toi32_i32$5 >>> i64toi32_i32$3 | 0) | 0; + } + $142$hi = i64toi32_i32$2; + i64toi32_i32$2 = $140$hi; + i64toi32_i32$1 = $140; + i64toi32_i32$5 = $142$hi; + i64toi32_i32$0 = $46_1; + i64toi32_i32$5 = i64toi32_i32$2 | i64toi32_i32$5 | 0; + var$5 = i64toi32_i32$1 | i64toi32_i32$0 | 0; + var$5$hi = i64toi32_i32$5; + $144 = var$5; + $144$hi = i64toi32_i32$5; + i64toi32_i32$5 = var$8$hi; + i64toi32_i32$5 = var$5$hi; + i64toi32_i32$5 = var$8$hi; + i64toi32_i32$2 = var$8; + i64toi32_i32$1 = var$5$hi; + i64toi32_i32$0 = var$5; + i64toi32_i32$3 = i64toi32_i32$2 - i64toi32_i32$0 | 0; + i64toi32_i32$6 = i64toi32_i32$2 >>> 0 < i64toi32_i32$0 >>> 0; + i64toi32_i32$4 = i64toi32_i32$6 + i64toi32_i32$1 | 0; + i64toi32_i32$4 = i64toi32_i32$5 - i64toi32_i32$4 | 0; + i64toi32_i32$5 = i64toi32_i32$3; + i64toi32_i32$2 = 0; + i64toi32_i32$0 = 63; + i64toi32_i32$1 = i64toi32_i32$0 & 31 | 0; + if (32 >>> 0 <= (i64toi32_i32$0 & 63 | 0) >>> 0) { + i64toi32_i32$2 = i64toi32_i32$4 >> 31 | 0; + $47_1 = i64toi32_i32$4 >> i64toi32_i32$1 | 0; + } else { + i64toi32_i32$2 = i64toi32_i32$4 >> i64toi32_i32$1 | 0; + $47_1 = (((1 << i64toi32_i32$1 | 0) - 1 | 0) & i64toi32_i32$4 | 0) << (32 - i64toi32_i32$1 | 0) | 0 | (i64toi32_i32$5 >>> i64toi32_i32$1 | 0) | 0; + } + var$6 = $47_1; + var$6$hi = i64toi32_i32$2; + i64toi32_i32$2 = var$1$hi; + i64toi32_i32$2 = var$6$hi; + i64toi32_i32$4 = var$6; + i64toi32_i32$5 = var$1$hi; + i64toi32_i32$0 = var$1; + i64toi32_i32$5 = i64toi32_i32$2 & i64toi32_i32$5 | 0; + $151 = i64toi32_i32$4 & i64toi32_i32$0 | 0; + $151$hi = i64toi32_i32$5; + i64toi32_i32$5 = $144$hi; + i64toi32_i32$2 = $144; + i64toi32_i32$4 = $151$hi; + i64toi32_i32$0 = $151; + i64toi32_i32$1 = i64toi32_i32$2 - i64toi32_i32$0 | 0; + i64toi32_i32$6 = i64toi32_i32$2 >>> 0 < i64toi32_i32$0 >>> 0; + i64toi32_i32$3 = i64toi32_i32$6 + i64toi32_i32$4 | 0; + i64toi32_i32$3 = i64toi32_i32$5 - i64toi32_i32$3 | 0; + var$5 = i64toi32_i32$1; + var$5$hi = i64toi32_i32$3; + i64toi32_i32$3 = var$0$hi; + i64toi32_i32$5 = var$0; + i64toi32_i32$2 = 0; + i64toi32_i32$0 = 1; + i64toi32_i32$4 = i64toi32_i32$0 & 31 | 0; + if (32 >>> 0 <= (i64toi32_i32$0 & 63 | 0) >>> 0) { + i64toi32_i32$2 = i64toi32_i32$5 << i64toi32_i32$4 | 0; + $48_1 = 0; + } else { + i64toi32_i32$2 = ((1 << i64toi32_i32$4 | 0) - 1 | 0) & (i64toi32_i32$5 >>> (32 - i64toi32_i32$4 | 0) | 0) | 0 | (i64toi32_i32$3 << i64toi32_i32$4 | 0) | 0; + $48_1 = i64toi32_i32$5 << i64toi32_i32$4 | 0; + } + $154$hi = i64toi32_i32$2; + i64toi32_i32$2 = var$7$hi; + i64toi32_i32$2 = $154$hi; + i64toi32_i32$3 = $48_1; + i64toi32_i32$5 = var$7$hi; + i64toi32_i32$0 = var$7; + i64toi32_i32$5 = i64toi32_i32$2 | i64toi32_i32$5 | 0; + var$0 = i64toi32_i32$3 | i64toi32_i32$0 | 0; + var$0$hi = i64toi32_i32$5; + i64toi32_i32$5 = var$6$hi; + i64toi32_i32$2 = var$6; + i64toi32_i32$3 = 0; + i64toi32_i32$0 = 1; + i64toi32_i32$3 = i64toi32_i32$5 & i64toi32_i32$3 | 0; + var$6 = i64toi32_i32$2 & i64toi32_i32$0 | 0; + var$6$hi = i64toi32_i32$3; + var$7 = var$6; + var$7$hi = i64toi32_i32$3; + var$2 = var$2 + -1 | 0; + if (var$2) { + continue label$15 + } + break label$15; + }; + break label$13; + } + } + i64toi32_i32$3 = var$5$hi; + __wasm_intrinsics_temp_i64 = var$5; + __wasm_intrinsics_temp_i64$hi = i64toi32_i32$3; + i64toi32_i32$3 = var$0$hi; + i64toi32_i32$5 = var$0; + i64toi32_i32$2 = 0; + i64toi32_i32$0 = 1; + i64toi32_i32$4 = i64toi32_i32$0 & 31 | 0; + if (32 >>> 0 <= (i64toi32_i32$0 & 63 | 0) >>> 0) { + i64toi32_i32$2 = i64toi32_i32$5 << i64toi32_i32$4 | 0; + $49_1 = 0; + } else { + i64toi32_i32$2 = ((1 << i64toi32_i32$4 | 0) - 1 | 0) & (i64toi32_i32$5 >>> (32 - i64toi32_i32$4 | 0) | 0) | 0 | (i64toi32_i32$3 << i64toi32_i32$4 | 0) | 0; + $49_1 = i64toi32_i32$5 << i64toi32_i32$4 | 0; + } + $165$hi = i64toi32_i32$2; + i64toi32_i32$2 = var$6$hi; + i64toi32_i32$2 = $165$hi; + i64toi32_i32$3 = $49_1; + i64toi32_i32$5 = var$6$hi; + i64toi32_i32$0 = var$6; + i64toi32_i32$5 = i64toi32_i32$2 | i64toi32_i32$5 | 0; + i64toi32_i32$3 = i64toi32_i32$3 | i64toi32_i32$0 | 0; + i64toi32_i32$HIGH_BITS = i64toi32_i32$5; + return i64toi32_i32$3 | 0; + } + i64toi32_i32$3 = var$0$hi; + __wasm_intrinsics_temp_i64 = var$0; + __wasm_intrinsics_temp_i64$hi = i64toi32_i32$3; + i64toi32_i32$3 = 0; + var$0 = 0; + var$0$hi = i64toi32_i32$3; + } + i64toi32_i32$3 = var$0$hi; + i64toi32_i32$5 = var$0; + i64toi32_i32$HIGH_BITS = i64toi32_i32$3; + return i64toi32_i32$5 | 0; + } + + function __wasm_ctz_i32(var$0) { + var$0 = var$0 | 0; + if (var$0) { + return 31 - Math_clz32((var$0 + -1 | 0) ^ var$0 | 0) | 0 | 0 + } + return 32 | 0; + } + + function __wasm_i64_mul(var$0, var$0$hi, var$1, var$1$hi) { + var$0 = var$0 | 0; + var$0$hi = var$0$hi | 0; + var$1 = var$1 | 0; + var$1$hi = var$1$hi | 0; + var i64toi32_i32$0 = 0, i64toi32_i32$1 = 0; + i64toi32_i32$0 = var$0$hi; + i64toi32_i32$0 = var$1$hi; + i64toi32_i32$0 = var$0$hi; + i64toi32_i32$1 = var$1$hi; + i64toi32_i32$1 = _ZN17compiler_builtins3int3mul3Mul3mul17h070e9a1c69faec5bE(var$0 | 0, i64toi32_i32$0 | 0, var$1 | 0, i64toi32_i32$1 | 0) | 0; + i64toi32_i32$0 = i64toi32_i32$HIGH_BITS; + i64toi32_i32$HIGH_BITS = i64toi32_i32$0; + return i64toi32_i32$1 | 0; + } + + function __wasm_i64_udiv(var$0, var$0$hi, var$1, var$1$hi) { + var$0 = var$0 | 0; + var$0$hi = var$0$hi | 0; + var$1 = var$1 | 0; + var$1$hi = var$1$hi | 0; + var i64toi32_i32$0 = 0, i64toi32_i32$1 = 0; + i64toi32_i32$0 = var$0$hi; + i64toi32_i32$0 = var$1$hi; + i64toi32_i32$0 = var$0$hi; + i64toi32_i32$1 = var$1$hi; + i64toi32_i32$1 = _ZN17compiler_builtins3int4udiv10divmod_u6417h6026910b5ed08e40E(var$0 | 0, i64toi32_i32$0 | 0, var$1 | 0, i64toi32_i32$1 | 0) | 0; + i64toi32_i32$0 = i64toi32_i32$HIGH_BITS; + i64toi32_i32$HIGH_BITS = i64toi32_i32$0; + return i64toi32_i32$1 | 0; + } + + function __wasm_rotl_i32(var$0, var$1) { + var$0 = var$0 | 0; + var$1 = var$1 | 0; + var var$2 = 0; + var$2 = var$1 & 31 | 0; + var$1 = (0 - var$1 | 0) & 31 | 0; + return ((-1 >>> var$2 | 0) & var$0 | 0) << var$2 | 0 | (((-1 << var$1 | 0) & var$0 | 0) >>> var$1 | 0) | 0 | 0; + } + + bufferView = HEAPU8; + initActiveSegments(imports); + var FUNCTION_TABLE = [null, $19, $25, $24, $35, $53, $56, $8, $10, $11, $12, $7, $26, $27, $28]; + function __wasm_memory_size() { + return buffer.byteLength / 65536 | 0; + } + + function __wasm_memory_grow(pagesToAdd) { + pagesToAdd = pagesToAdd | 0; + var oldPages = __wasm_memory_size() | 0; + var newPages = oldPages + pagesToAdd | 0; + if ((oldPages < newPages) && (newPages < 65536)) { + var newBuffer = new ArrayBuffer(Math_imul(newPages, 65536)); + var newHEAP8 = new Int8Array(newBuffer); + newHEAP8.set(HEAP8); + HEAP8 = new Int8Array(newBuffer); + HEAP16 = new Int16Array(newBuffer); + HEAP32 = new Int32Array(newBuffer); + HEAPU8 = new Uint8Array(newBuffer); + HEAPU16 = new Uint16Array(newBuffer); + HEAPU32 = new Uint32Array(newBuffer); + HEAPF32 = new Float32Array(newBuffer); + HEAPF64 = new Float64Array(newBuffer); + buffer = newBuffer; + bufferView = HEAPU8; + } + return oldPages; + } + + return { + "memory": Object.create(Object.prototype, { + "grow": { + "value": __wasm_memory_grow + }, + "buffer": { + "get": function () { + return buffer; + } + + } + }), + "execute": $44, + "setEnvironment": $46, + "onDeploy": $47, + "__new": $48, + "__pin": $50, + "__unpin": $51, + "__collect": $52, + "__data_end": { + get value() { + return global$1; + }, + set value(_global$1) { + global$1 = _global$1; + } + }, + "__heap_base": { + get value() { + return global$2; + }, + set value(_global$2) { + global$2 = _global$2; + } + } + }; } -function toUint8Array (s) { - if (typeof atob === 'function') return new Uint8Array(atob(s).split('').map(charCodeAt)) - return (require('buf' + 'fer').Buffer).from(s, 'base64') -} - -function charCodeAt (c) { - return c.charCodeAt(0) -} +var retasmFunc = asmFunc({ + "env": env, +}); +export var memory = retasmFunc.memory; +export var execute = retasmFunc.execute; +export var setEnvironment = retasmFunc.setEnvironment; +export var onDeploy = retasmFunc.onDeploy; +export var __new = retasmFunc.__new; +export var __pin = retasmFunc.__pin; +export var __unpin = retasmFunc.__unpin; +export var __collect = retasmFunc.__collect; +export var __data_end = retasmFunc.__data_end; +export var __heap_base = retasmFunc.__heap_base; From 500d59a9defd191cc2c58255dfe3e9b6871687f0 Mon Sep 17 00:00:00 2001 From: Miksa Date: Wed, 6 Nov 2024 10:19:02 +0100 Subject: [PATCH 04/23] Add memory mapping --- .cargo/config.toml | 2 + Cargo.lock | 6 +- Cargo.toml | 3 +- Makefile.toml | 46 +++++++++ done.js | 22 ++--- example/Cargo.lock | 181 ---------------------------------- example/Cargo.toml | 4 +- example/src/lib.rs | 8 ++ src/allocator.rs | 70 ------------- src/blockchain/address.rs | 11 +++ src/blockchain/environment.rs | 87 ++++++++++++++++ src/blockchain/mod.rs | 7 ++ src/blockchain/transaction.rs | 5 + src/constant.rs | 2 + src/contract/mod.rs | 1 + src/contract/op_20.rs | 3 + src/env/global.rs | 13 ++- src/lib.rs | 78 ++++++++++++++- src/math/abi.rs | 0 src/math/bytes.rs | 0 src/math/mod.rs | 0 src/mem.rs | 132 ++++++++++--------------- src/utils.rs | 35 +++++++ 23 files changed, 363 insertions(+), 353 deletions(-) create mode 100644 .cargo/config.toml create mode 100644 Makefile.toml delete mode 100644 example/Cargo.lock delete mode 100644 src/allocator.rs create mode 100644 src/blockchain/address.rs create mode 100644 src/blockchain/environment.rs create mode 100644 src/blockchain/mod.rs create mode 100644 src/blockchain/transaction.rs create mode 100644 src/contract/mod.rs create mode 100644 src/contract/op_20.rs create mode 100644 src/math/abi.rs create mode 100644 src/math/bytes.rs create mode 100644 src/math/mod.rs create mode 100644 src/utils.rs diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 0000000..435ed75 --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,2 @@ +[build] +target = "wasm32-unknown-unknown" \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 88e186b..df36734 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,8 +13,8 @@ name = "example" version = "0.1.0" dependencies = [ "hex", + "lol_alloc", "rust_runtime", - "wasm_allocator", ] [[package]] @@ -43,8 +43,8 @@ dependencies = [ ] [[package]] -name = "wasm_allocator" -version = "0.1.1" +name = "scopeguard" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c8f71f7436c9b614d8b94613c053fb38e87fd22796cc27c780ee97ec9a085b1" diff --git a/Cargo.toml b/Cargo.toml index 378ce63..ef6e0d7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,4 +12,5 @@ target = "wasm32-unknown-unknown" [dependencies] wee_alloc = "0.4.5" - +[features] +std = [] \ No newline at end of file diff --git a/Makefile.toml b/Makefile.toml new file mode 100644 index 0000000..dca5ba3 --- /dev/null +++ b/Makefile.toml @@ -0,0 +1,46 @@ +[tasks.format] +install_crate = "rustfmt" +command = "cargo" +args = ["fmt", "--", "--emit=files"] + +[tasks.clean] +command = "cargo" +args = ["clean"] + +[tasks.build] +command = "cargo" +args = ["build", "--release", "-p", "example"] +dependencies = ["clean"] + +[tasks.opt] +command = "wasm-opt" +args = [ + "-O2", + "-Oz", + "--strip-debug", + "--strip-dwarf", + "--dce", + "--disable-multimemory", + "--disable-fp16", + "--disable-mutable-globals", + "--disable-gc", + "--disable-multivalue", + "--disable-nontrapping-float-to-int", + "--disable-threads", + "--mvp-features", + "--remove-unused-module-elements", + "target/wasm32-unknown-unknown/release/example.wasm", + "-o", + "target/wasm32-unknown-unknown/release/example.wasm" +] +dependencies = ["build"] + +[tasks.super] +command = "echo" +args = ["hello", "world"] +dependencies = ["build"] + +[tasks.test] +command = "cargo" +args = ["test"] +dependencies = ["clean"] \ No newline at end of file diff --git a/done.js b/done.js index 9bc6964..96a82f0 100644 --- a/done.js +++ b/done.js @@ -2912,7 +2912,7 @@ function asmFunc(imports) { if ($6_1 >>> 0 >= 16 >>> 0) { continue label$5 } - break label$5; + break label$7; }; break label$2; } @@ -2998,6 +2998,7 @@ function asmFunc(imports) { default: break label$4; }; + break label$3; } $3_1 = $0_1 + 20 | 0; $10_1 = HEAP32[1049700 >> 2] | 0; @@ -4416,14 +4417,6 @@ function asmFunc(imports) { return i64toi32_i32$5 | 0; } - function __wasm_ctz_i32(var$0) { - var$0 = var$0 | 0; - if (var$0) { - return 31 - Math_clz32((var$0 + -1 | 0) ^ var$0 | 0) | 0 | 0 - } - return 32 | 0; - } - function __wasm_i64_mul(var$0, var$0$hi, var$1, var$1$hi) { var$0 = var$0 | 0; var$0$hi = var$0$hi | 0; @@ -4456,13 +4449,12 @@ function asmFunc(imports) { return i64toi32_i32$1 | 0; } - function __wasm_rotl_i32(var$0, var$1) { + function __wasm_ctz_i32(var$0) { var$0 = var$0 | 0; - var$1 = var$1 | 0; - var var$2 = 0; - var$2 = var$1 & 31 | 0; - var$1 = (0 - var$1 | 0) & 31 | 0; - return ((-1 >>> var$2 | 0) & var$0 | 0) << var$2 | 0 | (((-1 << var$1 | 0) & var$0 | 0) >>> var$1 | 0) | 0 | 0; + if (var$0) { + return 31 - Math_clz32((var$0 + -1 | 0) ^ var$0 | 0) | 0 | 0 + } + return 32 | 0; } bufferView = HEAPU8; diff --git a/example/Cargo.lock b/example/Cargo.lock deleted file mode 100644 index dd554d5..0000000 --- a/example/Cargo.lock +++ /dev/null @@ -1,181 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "bumpalo" -version = "3.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "example" -version = "0.1.0" -dependencies = [ - "rust_runtime", - "wasm-bindgen", -] - -[[package]] -name = "itoa" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" - -[[package]] -name = "log" -version = "0.4.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" - -[[package]] -name = "memchr" -version = "2.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" - -[[package]] -name = "once_cell" -version = "1.20.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" - -[[package]] -name = "proc-macro2" -version = "1.0.88" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c3a7fc5db1e57d5a779a352c8cdb57b29aa4c40cc69c3a68a7fedc815fbf2f9" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rust_runtime" -version = "0.1.0" - -[[package]] -name = "ryu" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" - -[[package]] -name = "serde" -version = "1.0.210" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.210" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.132" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" -dependencies = [ - "itoa", - "memchr", - "ryu", - "serde", -] - -[[package]] -name = "syn" -version = "2.0.82" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83540f837a8afc019423a8edb95b52a8effe46957ee402287f4292fae35be021" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "unicode-ident" -version = "1.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" - -[[package]] -name = "wasm-bindgen" -version = "0.2.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" -dependencies = [ - "cfg-if", - "once_cell", - "serde", - "serde_json", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" diff --git a/example/Cargo.toml b/example/Cargo.toml index 3393d9d..ab3831f 100644 --- a/example/Cargo.toml +++ b/example/Cargo.toml @@ -16,6 +16,6 @@ strip = true [dependencies] rust_runtime = {path=".."} hex = "0.4.3" -wasm_allocator = "0.1.1" +lol_alloc = "0.4.1" -[features] +[features] \ No newline at end of file diff --git a/example/src/lib.rs b/example/src/lib.rs index 7188407..309d6c4 100644 --- a/example/src/lib.rs +++ b/example/src/lib.rs @@ -1 +1,9 @@ +#![no_std] use rust_runtime; + +#[cfg(target_arch = "wasm32")] +use lol_alloc::LeakingPageAllocator; + +#[cfg(target_arch = "wasm32")] +#[global_allocator] +static ALLOCATOR: LeakingPageAllocator = LeakingPageAllocator; diff --git a/src/allocator.rs b/src/allocator.rs deleted file mode 100644 index 24ab217..0000000 --- a/src/allocator.rs +++ /dev/null @@ -1,70 +0,0 @@ -use core::slice; -use alloc::alloc::{alloc, alloc_zeroed, Layout, GlobalAlloc, dealloc, realloc}; - -pub struct WaAllocator; - -pub struct WaCell { - /* - pub mm_info: usize, - pub gc_info1: usize, - pub gc_info2: usize, - */ - pub rt_id: u32, - pub rt_size: u32, -} - -impl WaAllocator { - fn layout(layout: Layout) -> Layout { - unsafe { - Layout::from_size_align_unchecked( - layout.size() + size_of::(), - layout.align(), - ) - } - } - unsafe fn write_header(ptr: *mut u8, id: u32, size: usize) { - // Write the `id` as little-endian bytes into the first 4 bytes - slice::from_raw_parts_mut(ptr, 4).copy_from_slice(&id.to_le_bytes()); - - // Write the `size` (cast to u32) as little-endian bytes into the next 4 bytes - slice::from_raw_parts_mut(ptr.add(4), 4).copy_from_slice(&(size as u32).to_le_bytes()); - } -} - -unsafe impl GlobalAlloc for WaAllocator { - unsafe fn alloc(&self, layout: Layout) -> *mut u8 { - let size = layout.size(); - let layout = WaAllocator::layout(layout); - let ptr = alloc(layout); - WaAllocator::write_header(ptr, 1, size); - - ptr.wrapping_add(size_of::()) - } - - unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { - let layout = WaAllocator::layout(layout); - dealloc(ptr.wrapping_sub(size_of::()), layout); - } - - unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { - let size = layout.size(); - let layout = WaAllocator::layout(layout); - let ptr = alloc_zeroed(layout); - WaAllocator::write_header(ptr, 1, size); - - ptr.wrapping_add(size_of::()) - } - - unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { - let layout = WaAllocator::layout(layout); - realloc( - ptr.wrapping_sub(size_of::()), - layout, - new_size + size_of::(), - ) - .wrapping_add(size_of::()) - } -} - -#[global_allocator] -static GLOBAL: WaAllocator = WaAllocator; diff --git a/src/blockchain/address.rs b/src/blockchain/address.rs new file mode 100644 index 0000000..f05455f --- /dev/null +++ b/src/blockchain/address.rs @@ -0,0 +1,11 @@ +pub struct Address { + pub bytes: [u8; crate::constant::ADDRESS_BYTE_LENGTH], +} + +impl crate::utils::ToHex for Address { + fn get_bytes<'a>(&'a self) -> &'a [u8] { + self.bytes.as_ref() + } +} + +impl Address {} diff --git a/src/blockchain/environment.rs b/src/blockchain/environment.rs new file mode 100644 index 0000000..a7cd3ae --- /dev/null +++ b/src/blockchain/environment.rs @@ -0,0 +1,87 @@ +use alloc::{format, string::ToString}; + +use crate::utils::ToHex; + +pub struct Environment { + pub sender: super::Address, + pub origin: super::Address, + pub transaction: [u8; crate::constant::TRANSACTION_HASH_LENGHT], + pub block_hash: [u8; crate::constant::BLOCK_HASH_LENGHT], + pub owner: super::Address, + pub address: super::Address, + pub timestamp: u64, + pub safe_rnd: u64, +} + +impl ToString for Environment { + fn to_string(&self) -> alloc::string::String { + format!("Environment\n sender: {}, origin: {}, transaction: {:?}, block_hash: {:?}, owner: {}, address: {}, timestamp: {}, safe_rnd: {}", self.sender.to_hex(), self.origin.to_hex(), self.transaction, self.block_hash, self.owner.to_hex(), self.address.to_hex(), self.timestamp, self.safe_rnd) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_environment_decoding() { + let buffer = crate::mem::WaBuffer::from_bytes(&[ + 68, 102, 250, 135, 110, 248, 85, 140, 109, 85, 18, 71, 53, 174, 144, 79, 221, 222, 214, + 225, 179, 36, 87, 124, 87, 68, 62, 237, 41, 255, 124, 217, 68, 102, 250, 135, 110, 248, + 85, 140, 109, 85, 18, 71, 53, 174, 144, 79, 221, 222, 214, 225, 179, 36, 87, 124, 87, + 68, 62, 237, 41, 255, 124, 217, 71, 126, 176, 13, 215, 90, 186, 198, 64, 192, 122, 134, + 241, 188, 208, 24, 18, 40, 247, 207, 24, 222, 218, 124, 183, 138, 219, 244, 109, 179, + 19, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 68, 102, 250, 135, 110, 248, 85, 140, 109, 85, 18, 71, 53, 174, 144, + 79, 221, 222, 214, 225, 179, 36, 87, 124, 87, 68, 62, 237, 41, 255, 124, 217, 160, 10, + 9, 97, 12, 133, 130, 89, 89, 178, 82, 39, 219, 188, 247, 242, 177, 44, 196, 106, 249, + 60, 52, 210, 109, 42, 21, 191, 62, 6, 187, 249, 212, 188, 107, 254, 146, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + ]); + let environment = unsafe { buffer.into_type::().unwrap() }; + assert_eq!( + environment.sender.bytes, + [ + 68, 102, 250, 135, 110, 248, 85, 140, 109, 85, 18, 71, 53, 174, 144, 79, 221, 222, + 214, 225, 179, 36, 87, 124, 87, 68, 62, 237, 41, 255, 124, 217 + ] + ); + assert_eq!( + environment.origin.bytes, + [ + 68, 102, 250, 135, 110, 248, 85, 140, 109, 85, 18, 71, 53, 174, 144, 79, 221, 222, + 214, 225, 179, 36, 87, 124, 87, 68, 62, 237, 41, 255, 124, 217 + ] + ); + assert_eq!( + environment.transaction, + [ + 71, 126, 176, 13, 215, 90, 186, 198, 64, 192, 122, 134, 241, 188, 208, 24, 18, 40, + 247, 207, 24, 222, 218, 124, 183, 138, 219, 244, 109, 179, 19, 37 + ] + ); + assert_eq!( + environment.block_hash, + [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1 + ] + ); + assert_eq!( + environment.owner.bytes, + [ + 68, 102, 250, 135, 110, 248, 85, 140, 109, 85, 18, 71, 53, 174, 144, 79, 221, 222, + 214, 225, 179, 36, 87, 124, 87, 68, 62, 237, 41, 255, 124, 217 + ] + ); + assert_eq!( + environment.address.bytes, + [ + 160, 10, 9, 97, 12, 133, 130, 89, 89, 178, 82, 39, 219, 188, 247, 242, 177, 44, + 196, 106, 249, 60, 52, 210, 109, 42, 21, 191, 62, 6, 187, 249 + ] + ); + assert_eq!(environment.timestamp, 1730845326548); + assert_eq!(environment.safe_rnd, 0); + } +} diff --git a/src/blockchain/mod.rs b/src/blockchain/mod.rs new file mode 100644 index 0000000..6379381 --- /dev/null +++ b/src/blockchain/mod.rs @@ -0,0 +1,7 @@ +pub mod address; +pub mod environment; +pub mod transaction; + +pub use address::Address; +pub use environment::Environment; +pub use transaction::Transaction; diff --git a/src/blockchain/transaction.rs b/src/blockchain/transaction.rs new file mode 100644 index 0000000..3e7b39c --- /dev/null +++ b/src/blockchain/transaction.rs @@ -0,0 +1,5 @@ +pub struct Transaction { + pub sender: super::Address, + pub origin: super::Address, + pub hash: [u8; 32], +} diff --git a/src/constant.rs b/src/constant.rs index d61d6a1..21d0fe5 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -1 +1,3 @@ pub const ADDRESS_BYTE_LENGTH: usize = 32; +pub const TRANSACTION_HASH_LENGHT: usize = 32; +pub const BLOCK_HASH_LENGHT: usize = 32; diff --git a/src/contract/mod.rs b/src/contract/mod.rs new file mode 100644 index 0000000..8229185 --- /dev/null +++ b/src/contract/mod.rs @@ -0,0 +1 @@ +pub mod op_20; diff --git a/src/contract/op_20.rs b/src/contract/op_20.rs new file mode 100644 index 0000000..127aaa5 --- /dev/null +++ b/src/contract/op_20.rs @@ -0,0 +1,3 @@ +pub struct OP20Params {} + +pub trait OP20Trait {} diff --git a/src/env/global.rs b/src/env/global.rs index 3a03f83..67d8d09 100644 --- a/src/env/global.rs +++ b/src/env/global.rs @@ -1,3 +1,12 @@ -pub struct Address { - bytes: [u8; crate::constant::ADDRESS_BYTE_LENGTH], +pub struct Block {} + +pub struct Transaction {} + +pub struct Contract {} +pub struct BlockChainEnvironment { + pub block: Block, + pub transaction: Transaction, + pub contract: Contract, } + +pub static mut ENVIRONMENT: Option = None; diff --git a/src/lib.rs b/src/lib.rs index 5552fdf..c41ef55 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,9 +1,85 @@ -#![feature(ptr_internals)] +#![no_std] +use alloc::{format, string::ToString}; +use blockchain::transaction; +use mem::{WaBuffer, WaCell, WaPtr}; +use utils::ToHex; +extern crate alloc; #![no_std] extern crate alloc; pub mod allocator; pub mod constant; +pub mod contract; pub mod env; pub mod mem; +pub mod utils; + +#[cfg(not(test))] +#[cfg(not(feature = "std"))] +#[cfg(target_arch = "wasm32")] +#[panic_handler] +fn panic(_panic: &core::panic::PanicInfo<'_>) -> ! { + core::arch::wasm32::unreachable() +} + +#[link(wasm_import_module = "env")] +extern "C" { + pub fn log(buffer: WaPtr); +} + +pub fn log_str(text: &str) { + unsafe { + let string = WaBuffer::from_str(text); + log(string.ptr()); + } +} + +#[no_mangle] +pub fn execute(ptr: WaPtr) -> WaPtr { + let buffer = WaBuffer::from_raw(ptr); + log_str(&alloc::format!("Execute: {:?}", buffer.data())); + buffer.to_raw() +} + +#[no_mangle] +#[export_name = "setEnvironment"] +pub fn set_environment(ptr: WaPtr) { + let buffer = WaBuffer::from_raw(ptr); + log_str(&alloc::format!("Set environment: {:?}", buffer.data())); + unsafe { + let environment: &mut crate::blockchain::Environment = buffer.into_type().unwrap(); + + log_str(&environment.to_string()); + } +} + +#[no_mangle] +#[export_name = "onDeploy"] +pub fn on_deploy(ptr: WaPtr) { + let buffer = WaBuffer::from_raw(ptr); + //log_str(&format!("On deploy: {:?}", buffer.data())); +} + +#[no_mangle] +#[export_name = "__new"] +pub fn new(size: usize, id: u32) -> WaPtr { + log_str(&format!("__new: {} {}", size, id)); + WaCell::new(size, id).to_raw() +} + +#[no_mangle] +#[export_name = "__pin"] +pub fn pin(ptr: WaPtr) -> WaPtr { + //let cell = WaCell::from_raw(ptr); + //log_str(&format!("Pin: {}, {:?}", ptr, cell.data())); + //WaCell::from_raw(ptr).to_raw() + ptr +} + +#[no_mangle] +#[export_name = "__unpin"] +pub fn unpin(ptr: WaPtr) { + //let cell = WaCell::from_raw(ptr); + //log_str(&format!("Unpin: {}, {:?}", ptr, cell.data())); +} diff --git a/src/math/abi.rs b/src/math/abi.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/math/bytes.rs b/src/math/bytes.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/math/mod.rs b/src/math/mod.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/mem.rs b/src/mem.rs index ee93fea..d926aca 100644 --- a/src/mem.rs +++ b/src/mem.rs @@ -31,11 +31,7 @@ impl<'a> Cursor<'a> { } pub fn read_u32(&mut self) -> u32 { - let result = u32::from_le_bytes( - self.inner[self.pos as usize..self.pos + 4] - .try_into() - .unwrap(), - ); + let result = u32::from_le_bytes(self.inner[self.pos..self.pos + 4].try_into().unwrap()); self.pos += 4; result } @@ -51,15 +47,15 @@ pub struct WaCell { impl WaCell { const fn size() -> WaPtr { - mem::size_of::() as WaPtr + size_of::() as WaPtr } const fn usize() -> usize { - mem::size_of::() + size_of::() } const fn layout(size: usize) -> Layout { unsafe { Layout::from_size_align_unchecked(size + WaCell::usize(), 1) } } - pub fn new(size: usize, id: u32) -> Box { + pub fn new<'a>(size: usize, id: u32) -> &'a mut WaCell { unsafe { let layout = WaCell::layout(size); let ptr = alloc(layout); @@ -78,9 +74,8 @@ impl WaCell { cell } - pub fn leak(mut self: Box) { - self.dec(); - Box::leak(self); + pub fn from_raw<'a>(ptr: WaPtr) -> &'a mut WaCell { + unsafe { NonNull::::new_unchecked((ptr - WaCell::size()) as *mut WaCell).as_mut() } } pub fn drop(mut self: Box) { @@ -121,108 +116,77 @@ impl WaCell { (self as *const Self as *const u8 as WaPtr) + WaCell::size() } - pub fn data<'a>(self: &Box) -> &[u8] { + pub fn data<'a>(&self) -> &'a [u8] { unsafe { slice::from_raw_parts(self.ptr() as *const u8, self.rt_size as usize) } } - pub fn data_mut<'a>(self: &mut Box) -> &mut [u8] { + pub fn data_mut(&mut self) -> &mut [u8] { unsafe { slice::from_raw_parts_mut(self.ptr() as *mut u8, self.rt_size as usize) } } - pub fn cursor<'a>(self: &mut Box) -> Cursor { + pub fn cursor(&mut self) -> Cursor { Cursor::new(self.data_mut()) } } -pub struct WaArray { - cell: Box, - buffer: Box, +pub struct WaBuffer<'a> { + buffer: &'a mut WaCell, + pointer: &'a mut WaCell, } -impl WaArray { - pub fn from_raw(ptr: WaPtr) -> WaArray { - let mut cell = WaCell::from_raw(ptr); - cell.inc(); - let mut cursor = cell.cursor(); - let buffer_ptr = cursor.read_u32(); - let mut buffer = WaCell::from_raw(buffer_ptr); - buffer.inc(); - WaArray { cell, buffer } - } - - pub fn ptr(&self) -> WaPtr { - self.cell.ptr() - } - - pub fn data(&self) -> &[u8] { - self.buffer.data() - } - - pub fn to_raw(mut self) -> WaPtr { - self.buffer.dec(); - self.buffer.to_raw(); - self.cell.dec(); - self.cell.to_raw() - } - - pub fn leak(self) { - self.cell.leak(); - self.buffer.leak(); - } - - pub fn drop(self) { - self.cell.drop(); - self.buffer.drop(); - } -} - -pub struct WaString { - cell: Box, - buffer: Box, -} -impl WaString { - pub fn new(text: &str) -> WaString { - let len = (text.chars().count()) as u16; +impl<'a> WaBuffer<'a> { + pub fn from_str(s: &str) -> WaBuffer<'a> { + let len = (s.chars().count()) as u16; let str_data = len .to_le_bytes() .iter() - // Write string itself - .chain(text.as_bytes()) + .chain(s.as_bytes()) .cloned() .collect::>(); - let buffer = WaCell::new_data(1, &str_data); - let cell = WaCell::new_data( + WaBuffer::from_bytes(&str_data) + } + pub fn from_bytes(bytes: &[u8]) -> WaBuffer<'a> { + let buffer = WaCell::new_data(1, bytes); + let pointer = WaCell::new_data( 2, &[ buffer.ptr().to_le_bytes(), buffer.ptr().to_le_bytes(), - (str_data.len() as u32).to_le_bytes(), + (bytes.len() as u32).to_le_bytes(), ] .concat(), ); - - WaString { cell, buffer } + WaBuffer { pointer, buffer } + } + pub fn from_raw(ptr: WaPtr) -> WaBuffer<'a> { + let pointer = WaCell::from_raw(ptr); + let mut cursor = pointer.cursor(); + let buffer_ptr = cursor.read_u32(); + let buffer = WaCell::from_raw(buffer_ptr); + WaBuffer { pointer, buffer } } pub fn ptr(&self) -> WaPtr { - self.cell.ptr() + self.pointer.ptr() } pub fn data(&self) -> &[u8] { self.buffer.data() } - pub fn to_raw(mut self) -> WaPtr { - self.buffer.dec(); - self.buffer.to_raw(); - self.cell.dec(); - self.cell.to_raw() + pub fn to_raw(self) -> WaPtr { + self.pointer.to_raw() } - fn leak(self) { - self.cell.leak(); - self.buffer.leak(); - } + pub unsafe fn into_type(&self) -> Result<&'a mut T, alloc::string::String> { + /* + super::log_str(&alloc::format!("Data: {:?}", self.cell.data())); + super::log_str(&self.buffer.ptr().to_string()); + super::log_str(&alloc::format!("Data: {:?}", self.buffer.data())); + */ + if core::mem::size_of::() <= self.buffer.rt_size as usize { + #[cfg(feature = "std")] + println!("Casting memory"); fn drop(self) { self.cell.drop(); @@ -314,3 +278,15 @@ pub fn collect() { MEMORY.extend(new); // Update with the new elements } } + +/* +pub fn alloc_box_buffer(len: usize) -> Box<[u8]> { + if len == 0 { + return >::default(); + } + let layout = Layout::array::(len).unwrap(); + let ptr = unsafe { alloc::alloc::alloc(layout) }; + let slice_ptr = core::ptr::slice_from_raw_parts_mut(ptr, len); + unsafe { Box::from_raw(slice_ptr) } +} + */ diff --git a/src/utils.rs b/src/utils.rs new file mode 100644 index 0000000..8b507ce --- /dev/null +++ b/src/utils.rs @@ -0,0 +1,35 @@ +const BASE64_TABLE: [char; 16] = [ + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', +]; +pub trait ToHex { + fn get_bytes<'a>(&'a self) -> &'a [u8]; + fn to_hex<'a>(&'a self) -> alloc::string::String { + let bytes = self.get_bytes(); + let mut string = alloc::string::String::with_capacity(bytes.len() * 2 + 3); + string.push_str("0x"); + + for byte in bytes.iter() { + string.push(BASE64_TABLE[(*byte >> 4) as usize]); + string.push(BASE64_TABLE[(*byte & 0xf) as usize]); + } + string + } +} + +#[cfg(test)] +mod tests { + use super::*; + + pub struct TestHex(alloc::vec::Vec); + impl ToHex for TestHex { + fn get_bytes<'a>(&'a self) -> &'a [u8] { + &self.0 + } + } + + #[test] + fn it_works() { + let v = TestHex(alloc::vec![0xda, 0x02, 0xa1, 0x1f]); + assert_eq!(v.to_hex(), alloc::string::String::from("0xda02a11f")); + } +} From 309302fb77ed95adc520631c8442860da98935ac Mon Sep 17 00:00:00 2001 From: Miksa Date: Thu, 19 Dec 2024 00:02:55 +0100 Subject: [PATCH 05/23] Squash code for working contract --- .cargo/config.toml | 2 - Cargo.lock | 77 +- Cargo.toml | 27 +- README.md | 42 +- done.js | 4539 ------------------------------ example/.cargo/config.toml | 2 + example/Cargo.toml | 12 +- example/src/contract.rs | 168 ++ example/src/lib.rs | 38 +- rust-toolchain | 5 +- src/blockchain/address.rs | 30 +- src/blockchain/block.rs | 9 + src/blockchain/environment.rs | 126 +- src/blockchain/mod.rs | 6 +- src/blockchain/transaction.rs | 27 +- src/constant.rs | 9 +- src/contract/mod.rs | 34 + src/contract/op_20.rs | 427 ++- src/cursor/mod.rs | 68 + src/cursor/reader.rs | 130 + src/cursor/writer.rs | 128 + src/env/address.rs | 12 + src/env/global.rs | 43 +- src/env/mod.rs | 33 +- src/env/sha.rs | 55 + src/env/store.rs | 82 + src/error.rs | 51 + src/event/mod.rs | 125 + src/lib.rs | 91 +- src/math/abi.rs | 63 + src/math/bytes.rs | 13 + src/math/mod.rs | 2 + src/mem.rs | 281 +- src/prelude.rs | 4 + src/storage/array_merger.rs | 41 + src/storage/key.rs | 1 + src/storage/map.rs | 136 + src/storage/mod.rs | 65 + src/storage/multi_address_map.rs | 46 + src/storage/stored.rs | 167 ++ src/storage/stored_map.rs | 53 + src/storage/stored_string.rs | 127 + src/storage/value.rs | 161 ++ src/types.rs | 2 + src/utils.rs | 41 +- 45 files changed, 2596 insertions(+), 5005 deletions(-) delete mode 100644 done.js create mode 100644 example/.cargo/config.toml create mode 100644 example/src/contract.rs create mode 100644 src/blockchain/block.rs create mode 100644 src/cursor/mod.rs create mode 100644 src/cursor/reader.rs create mode 100644 src/cursor/writer.rs create mode 100644 src/env/address.rs create mode 100644 src/env/sha.rs create mode 100644 src/env/store.rs create mode 100644 src/error.rs create mode 100644 src/event/mod.rs create mode 100644 src/prelude.rs create mode 100644 src/storage/array_merger.rs create mode 100644 src/storage/key.rs create mode 100644 src/storage/map.rs create mode 100644 src/storage/mod.rs create mode 100644 src/storage/multi_address_map.rs create mode 100644 src/storage/stored.rs create mode 100644 src/storage/stored_map.rs create mode 100644 src/storage/stored_string.rs create mode 100644 src/storage/value.rs create mode 100644 src/types.rs diff --git a/.cargo/config.toml b/.cargo/config.toml index 435ed75..e69de29 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,2 +0,0 @@ -[build] -target = "wasm32-unknown-unknown" \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index df36734..9393fe1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,81 +3,70 @@ version = 3 [[package]] -name = "cfg-if" -version = "0.1.10" +name = "autocfg" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "ethnum" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b90ca2580b73ab6a1f724b76ca11ab632df820fd6040c336200d2c1df7b3c82c" [[package]] name = "example" version = "0.1.0" dependencies = [ - "hex", "lol_alloc", "rust_runtime", + "sha2-const", ] [[package]] -name = "hex" -version = "0.4.3" +name = "lock_api" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "libc" -version = "0.2.161" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] [[package]] -name = "memory_units" -version = "0.4.0" +name = "lol_alloc" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3" +checksum = "83e5106554cabc97552dcadf54f57560ae6af3276652f82ca2be06120dc4c5dc" +dependencies = [ + "spin", +] [[package]] name = "rust_runtime" version = "0.1.0" dependencies = [ - "wee_alloc", + "ethnum", + "sha2-const", ] [[package]] name = "scopeguard" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c8f71f7436c9b614d8b94613c053fb38e87fd22796cc27c780ee97ec9a085b1" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] -name = "wee_alloc" -version = "0.4.5" +name = "sha2-const" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e" -dependencies = [ - "cfg-if", - "libc", - "memory_units", - "winapi", -] +checksum = "5edcd790916d95ff81bdc1505b09c74d30d47a755929cc8c71c59cbbfa99f91b" [[package]] -name = "winapi" -version = "0.3.9" +name = "spin" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", + "lock_api", ] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/Cargo.toml b/Cargo.toml index ef6e0d7..5e2aebc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,16 +1,29 @@ -[package] -name = "rust_runtime" +[workspace.package] version = "0.1.0" +authors = ["Martin Miksanik"] +description = "Rust runtime for OP_NET" +documentation = "https://dev.opnet.org/" edition = "2021" +[workspace.dependencies] +# This crate is much larger than expected. Avoid using it unless absolutely necessary. +ethnum = "1.5.0" +lol_alloc = "0.4.1" +rust_runtime = { path = "." } +sha2-const = "0.1.2" + +[package] +name = "rust_runtime" +version = { workspace = true } +edition = { workspace = true } + [workspace] members = ["example"] -[build] -target = "wasm32-unknown-unknown" - [dependencies] -wee_alloc = "0.4.5" +# This crate is much larger than expected. Avoid using it unless absolutely necessary. +ethnum = { workspace = true } +sha2-const = {workspace = true } [features] -std = [] \ No newline at end of file +std = [] diff --git a/README.md b/README.md index 2be6f2b..7e3ae45 100644 --- a/README.md +++ b/README.md @@ -1,38 +1,40 @@ # Rust runtime for OP_NET VM + * Rust contract is able to run under [op-vm](https://github.com/btc-vision/op-vm) * The interface is defined by [btc-runtime](https://github.com/btc-vision/btc-runtime) * Library is tested like: [opnet-unit-test](https://github.com/btc-vision/opnet-unit-test) +* Reference contract: [OP_20](https://github.com/btc-vision/OP_20) ## Compilation + ```sh -cargo build --release -p example -wasm-opt -O3 -Oz --strip-debug --strip-dwarf --dce --disable-multimemory --disable-fp16 --disable-mutable-globals --disable-gc --disable-multivalue --disable-nontrapping-float-to-int --disable-threads --mvp-features --remove-unused-module-elements ./target/wasm32-unknown-unknown/release/example.wasm -o ./rust.wasm +rustup install nightly # ensure that you have last nightly version +cargo build --release -p example --target wasm32-unknown-unknown +wasm-opt -O2 -Oz --strip-debug --strip-dwarf --dce --disable-multimemory --disable-fp16 --disable-mutable-globals --disable-gc --disable-multivalue --disable-nontrapping-float-to-int --disable-threads --mvp-features --remove-unused-module-elements ./target/wasm32-unknown-unknown/release/example.wasm -o ./rust.wasm ``` ## Testing + +### With opnet-unit-test on wasm interpreter + ```sh cp ./rust.wasm ../opnet-unit-test/bytecode/rust.wasm -node build/tests/rust.js +node build/tests/rust.js ``` -## Size -* Compiled code from [moto library](https://github.com/btc-vision/moto): 23KB (23464B) -* Unoptimized code from current Rust library: 31KB (31359B) - incomplete -* Optimized code with wasm-opt: 22KB (21778B) - incomplete +### Without wasm32 runtime -## Structure -* `./src/` - Library providing the interface and helper functions for contract interaction -* `./example/` - Sample smart contract, similar to contract used in unit tests +```sh +cargo test --target x86_64-unknown-linux-gnu +``` + +## Size (outdated) -## TODO -### Buffer operations and manipulations -* Investigate if it’s possible to directly map structs to memory -* Write memory manipulation methods (`readAddress`, `readUint32`, etc.) -* Create unit tests and check for memory leaks +* Compiled code from [moto library](https://github.com/btc-vision/OP_20): 24KB (24689) +* Unoptimized code from current Rust library: 45KB (45584) +* Optimized code with wasm-opt: 33KB (33573) -## Contract helpers -* Coding methods like `byte4`, `encodeSelector`, `hash`, etc. -* Decoding passed buffers (`set_environment`, `execute`, `on_deploy`) into correct structures +## Structure -## Smart contract and unit tests -* Copy basic functionality from OP20 contract to examples, as needed +* `./src/` - Library providing the interface and helper functions for contract interaction +* `./example/` - Sample smart contract, similar to contract used in unit tests diff --git a/done.js b/done.js deleted file mode 100644 index 96a82f0..0000000 --- a/done.js +++ /dev/null @@ -1,4539 +0,0 @@ -import * as env from 'env'; - - var bufferView; - var base64ReverseLookup = new Uint8Array(123/*'z'+1*/); - for (var i = 25; i >= 0; --i) { - base64ReverseLookup[48+i] = 52+i; // '0-9' - base64ReverseLookup[65+i] = i; // 'A-Z' - base64ReverseLookup[97+i] = 26+i; // 'a-z' - } - base64ReverseLookup[43] = 62; // '+' - base64ReverseLookup[47] = 63; // '/' - /** @noinline Inlining this function would mean expanding the base64 string 4x times in the source code, which Closure seems to be happy to do. */ - function base64DecodeToExistingUint8Array(uint8Array, offset, b64) { - var b1, b2, i = 0, j = offset, bLength = b64.length, end = offset + (bLength*3>>2) - (b64[bLength-2] == '=') - (b64[bLength-1] == '='); - for (; i < bLength; i += 4) { - b1 = base64ReverseLookup[b64.charCodeAt(i+1)]; - b2 = base64ReverseLookup[b64.charCodeAt(i+2)]; - uint8Array[j++] = base64ReverseLookup[b64.charCodeAt(i)] << 2 | b1 >> 4; - if (j < end) uint8Array[j++] = b1 << 4 | b2 >> 2; - if (j < end) uint8Array[j++] = b2 << 6 | base64ReverseLookup[b64.charCodeAt(i+3)]; - } - } -function initActiveSegments(imports) { - base64DecodeToExistingUint8Array(bufferView, 1048576, "BwAAAAwAAAAEAAAACAAAAAkAAAAKAAAAYWxsb2Mvc3JjL3Jhd192ZWMucnMYABAAFAAAABgAAAAF"); - base64DecodeToExistingUint8Array(bufferView, 1048644, "AQAAAAsAAABhIGZvcm1hdHRpbmcgdHJhaXQgaW1wbGVtZW50YXRpb24gcmV0dXJuZWQgYW4gZXJyb3Igd2hlbiB0aGUgdW5kZXJseWluZyBzdHJlYW0gZGlkIG5vdGFsbG9jL3NyYy9mbXQucnMAAKIAEAAQAAAAfgIAAA4AAABbOiAAAQAAAAAAAADFABAAAgAAAAAAAAAMAAAABAAAAAwAAAANAAAADgAAACAgICAsICwKCl1jb3JlL3NyYy9mbXQvbnVtLnJzAAAA+gAQABMAAABmAAAAFwAAADB4MDAwMTAyMDMwNDA1MDYwNzA4MDkxMDExMTIxMzE0MTUxNjE3MTgxOTIwMjEyMjIzMjQyNTI2MjcyODI5MzAzMTMyMzMzNDM1MzYzNzM4Mzk0MDQxNDI0MzQ0NDU0NjQ3NDg0OTUwNTE1MjUzNTQ1NTU2NTc1ODU5NjA2MTYyNjM2NDY1NjY2NzY4Njk3MDcxNzI3Mzc0NzU3Njc3Nzg3OTgwODE4MjgzODQ4NTg2ODc4ODg5OTA5MTkyOTM5NDk1OTY5Nzk4OTlyYW5nZSBzdGFydCBpbmRleCAgb3V0IG9mIHJhbmdlIGZvciBzbGljZSBvZiBsZW5ndGggAADqARAAEgAAAPwBEAAiAAAAcmFuZ2UgZW5kIGluZGV4IDACEAAQAAAA/AEQACIAAABjYXBhY2l0eSBvdmVyZmxvdwAAAFACEAARAAAAL3J1c3RjL2M2ZGIxY2EzYzkzYWQ2OTY5MmE0YzRiNTU0MmYyNmZkYTRiZjNhZWMvbGlicmFyeS9hbGxvYy9zcmMvdmVjL3NwZWNfZnJvbV9pdGVyX25lc3RlZC5ycwAAbAIQAF4AAAA5AAAAEgAAAC9ydXN0Yy9jNmRiMWNhM2M5M2FkNjk2OTJhNGM0YjU1NDJmMjZmZGE0YmYzYWVjL2xpYnJhcnkvYWxsb2Mvc3JjL3ZlYy9tb2QucnPcAhAATAAAAD8MAAANAAAAc3JjXG1lbS5ycwAAOAMQAAoAAAAeAAAAFwAAAEV4ZWN1dGU6IAAAAFQDEAAJAAAAU2V0IGVudmlyb25tZW50OiAAAABoAxAAEQAAAE9uIGRlcGxveTogAIQDEAALAAAATWVtIHNpemU6IAAAmAMQAAoAAAAvcnVzdC9kZXBzL2RsbWFsbG9jLTAuMi42L3NyYy9kbG1hbGxvYy5yc2Fzc2VydGlvbiBmYWlsZWQ6IHBzaXplID49IHNpemUgKyBtaW5fb3ZlcmhlYWQArAMQACkAAACoBAAACQAAAGFzc2VydGlvbiBmYWlsZWQ6IHBzaXplIDw9IHNpemUgKyBtYXhfb3ZlcmhlYWQAAKwDEAApAAAArgQAAA0AAABFcnJvcg=="); - base64DecodeToExistingUint8Array(bufferView, 1049696, "BA=="); -} -function wasm2js_trap() { throw new Error('abort'); } - -function asmFunc(imports) { - var buffer = new ArrayBuffer(1114112); - var HEAP8 = new Int8Array(buffer); - var HEAP16 = new Int16Array(buffer); - var HEAP32 = new Int32Array(buffer); - var HEAPU8 = new Uint8Array(buffer); - var HEAPU16 = new Uint16Array(buffer); - var HEAPU32 = new Uint32Array(buffer); - var HEAPF32 = new Float32Array(buffer); - var HEAPF64 = new Float64Array(buffer); - var Math_imul = Math.imul; - var Math_fround = Math.fround; - var Math_abs = Math.abs; - var Math_clz32 = Math.clz32; - var Math_min = Math.min; - var Math_max = Math.max; - var Math_floor = Math.floor; - var Math_ceil = Math.ceil; - var Math_trunc = Math.trunc; - var Math_sqrt = Math.sqrt; - var env = imports.env; - var fimport$0 = env.log; - var global$0 = 1048576; - var global$1 = 1050173; - var global$2 = 1050176; - var __wasm_intrinsics_temp_i64 = 0; - var __wasm_intrinsics_temp_i64$hi = 0; - var i64toi32_i32$HIGH_BITS = 0; - function $0($0_1) { - $0_1 = $0_1 | 0; - if (!$0_1) { - $1() - } - wasm2js_trap(); - } - - function $1() { - var $0_1 = 0; - $0_1 = global$0 - 32 | 0; - global$0 = $0_1; - HEAP32[($0_1 + 24 | 0) >> 2] = 0; - HEAP32[($0_1 + 12 | 0) >> 2] = 1; - HEAP32[($0_1 + 8 | 0) >> 2] = 1049188; - HEAP32[($0_1 + 16 | 0) >> 2] = 4; - HEAP32[($0_1 + 20 | 0) >> 2] = 0; - $2($0_1 + 8 | 0 | 0, 1048620 | 0); - wasm2js_trap(); - } - - function $2($0_1, $1_1) { - $0_1 = $0_1 | 0; - $1_1 = $1_1 | 0; - var i64toi32_i32$0 = 0, i64toi32_i32$1 = 0, $2_1 = 0, i64toi32_i32$2 = 0, $3_1 = 0, $4_1 = 0, $13_1 = 0, $19_1 = 0, $25_1 = 0, $34_1 = 0, $38_1 = 0, $45_1 = 0; - $2_1 = global$0 - 32 | 0; - global$0 = $2_1; - $3_1 = $2_1 + 16 | 0; - i64toi32_i32$2 = $0_1 + 16 | 0; - i64toi32_i32$0 = HEAP32[i64toi32_i32$2 >> 2] | 0; - i64toi32_i32$1 = HEAP32[(i64toi32_i32$2 + 4 | 0) >> 2] | 0; - $13_1 = i64toi32_i32$0; - i64toi32_i32$0 = $3_1; - HEAP32[i64toi32_i32$0 >> 2] = $13_1; - HEAP32[(i64toi32_i32$0 + 4 | 0) >> 2] = i64toi32_i32$1; - $4_1 = $2_1 + 8 | 0; - i64toi32_i32$2 = $0_1 + 8 | 0; - i64toi32_i32$1 = HEAP32[i64toi32_i32$2 >> 2] | 0; - i64toi32_i32$0 = HEAP32[(i64toi32_i32$2 + 4 | 0) >> 2] | 0; - $19_1 = i64toi32_i32$1; - i64toi32_i32$1 = $4_1; - HEAP32[i64toi32_i32$1 >> 2] = $19_1; - HEAP32[(i64toi32_i32$1 + 4 | 0) >> 2] = i64toi32_i32$0; - HEAP16[($2_1 + 28 | 0) >> 1] = 1; - HEAP32[($2_1 + 24 | 0) >> 2] = $1_1; - i64toi32_i32$2 = $0_1; - i64toi32_i32$0 = HEAP32[$0_1 >> 2] | 0; - i64toi32_i32$1 = HEAP32[($0_1 + 4 | 0) >> 2] | 0; - $25_1 = i64toi32_i32$0; - i64toi32_i32$0 = $2_1; - HEAP32[i64toi32_i32$0 >> 2] = $25_1; - HEAP32[(i64toi32_i32$0 + 4 | 0) >> 2] = i64toi32_i32$1; - $0_1 = global$0 - 32 | 0; - global$0 = $0_1; - $1_1 = HEAP32[(i64toi32_i32$0 + 24 | 0) >> 2] | 0; - i64toi32_i32$2 = $3_1; - i64toi32_i32$1 = HEAP32[i64toi32_i32$2 >> 2] | 0; - i64toi32_i32$0 = HEAP32[(i64toi32_i32$2 + 4 | 0) >> 2] | 0; - $34_1 = i64toi32_i32$1; - i64toi32_i32$1 = $0_1 + 16 | 0; - HEAP32[i64toi32_i32$1 >> 2] = $34_1; - HEAP32[(i64toi32_i32$1 + 4 | 0) >> 2] = i64toi32_i32$0; - i64toi32_i32$2 = $4_1; - i64toi32_i32$0 = HEAP32[i64toi32_i32$2 >> 2] | 0; - i64toi32_i32$1 = HEAP32[(i64toi32_i32$2 + 4 | 0) >> 2] | 0; - $38_1 = i64toi32_i32$0; - i64toi32_i32$0 = $0_1 + 8 | 0; - HEAP32[i64toi32_i32$0 >> 2] = $38_1; - HEAP32[(i64toi32_i32$0 + 4 | 0) >> 2] = i64toi32_i32$1; - HEAP32[($0_1 + 28 | 0) >> 2] = $2_1; - HEAP32[($0_1 + 24 | 0) >> 2] = $1_1; - i64toi32_i32$2 = $2_1; - i64toi32_i32$1 = HEAP32[$2_1 >> 2] | 0; - i64toi32_i32$0 = HEAP32[($2_1 + 4 | 0) >> 2] | 0; - $45_1 = i64toi32_i32$1; - i64toi32_i32$1 = $0_1; - HEAP32[$0_1 >> 2] = $45_1; - HEAP32[($0_1 + 4 | 0) >> 2] = i64toi32_i32$0; - $2_1 = 0; - $1_1 = global$0 - 16 | 0; - global$0 = $1_1; - $3_1 = HEAP32[($0_1 + 12 | 0) >> 2] | 0; - label$1 : { - label$2 : { - label$3 : { - switch (HEAP32[($0_1 + 4 | 0) >> 2] | 0 | 0) { - case 0: - if ($3_1) { - break label$2 - } - $3_1 = 1; - break label$1; - case 1: - break label$3; - default: - break label$2; - }; - } - if ($3_1) { - break label$2 - } - $3_1 = HEAP32[$0_1 >> 2] | 0; - $2_1 = HEAP32[($3_1 + 4 | 0) >> 2] | 0; - $3_1 = HEAP32[$3_1 >> 2] | 0; - break label$1; - } - HEAP32[$1_1 >> 2] = -2147483648; - HEAP32[($1_1 + 12 | 0) >> 2] = $0_1; - $0_1 = HEAP32[($0_1 + 28 | 0) >> 2] | 0; - $2_1 = HEAPU8[($0_1 + 28 | 0) >> 0] | 0; - HEAPU8[($0_1 + 29 | 0) >> 0] | 0; - $55($1_1 | 0, 5 | 0, $2_1 | 0); - wasm2js_trap(); - } - HEAP32[($1_1 + 4 | 0) >> 2] = $2_1; - HEAP32[$1_1 >> 2] = $3_1; - $0_1 = HEAP32[($0_1 + 28 | 0) >> 2] | 0; - $2_1 = HEAPU8[($0_1 + 28 | 0) >> 0] | 0; - HEAPU8[($0_1 + 29 | 0) >> 0] | 0; - $55($1_1 | 0, 6 | 0, $2_1 | 0); - wasm2js_trap(); - } - - function $3($0_1, $1_1, $2_1) { - $0_1 = $0_1 | 0; - $1_1 = $1_1 | 0; - $2_1 = $2_1 | 0; - var $3_1 = 0, $4_1 = 0, $39_1 = 0, $30_1 = 0; - $3_1 = global$0 - 32 | 0; - global$0 = $3_1; - $2_1 = $1_1 + $2_1 | 0; - if ($1_1 >>> 0 > $2_1 >>> 0) { - $0(0 | 0); - wasm2js_trap(); - } - $1_1 = HEAP32[$0_1 >> 2] | 0; - $4_1 = $1_1 << 1 | 0; - $2_1 = $2_1 >>> 0 < $4_1 >>> 0 ? $4_1 : $2_1; - $2_1 = $2_1 >>> 0 <= 8 >>> 0 ? 8 : $2_1; - if (($2_1 | 0) < (0 | 0)) { - $0(0 | 0); - wasm2js_trap(); - } - $30_1 = $3_1; - if ($1_1) { - HEAP32[($3_1 + 28 | 0) >> 2] = $1_1; - HEAP32[($3_1 + 20 | 0) >> 2] = HEAP32[($0_1 + 4 | 0) >> 2] | 0; - $39_1 = 1; - } else { - $39_1 = 0 - } - HEAP32[($30_1 + 24 | 0) >> 2] = $39_1; - $4($3_1 + 8 | 0 | 0, $2_1 | 0, $3_1 + 20 | 0 | 0); - if ((HEAP32[($3_1 + 8 | 0) >> 2] | 0 | 0) == (1 | 0)) { - HEAP32[($3_1 + 16 | 0) >> 2] | 0; - $0(HEAP32[($3_1 + 12 | 0) >> 2] | 0 | 0); - wasm2js_trap(); - } - $1_1 = HEAP32[($3_1 + 12 | 0) >> 2] | 0; - HEAP32[$0_1 >> 2] = $2_1; - HEAP32[($0_1 + 4 | 0) >> 2] = $1_1; - global$0 = $3_1 + 32 | 0; - } - - function $4($0_1, $1_1, $2_1) { - $0_1 = $0_1 | 0; - $1_1 = $1_1 | 0; - $2_1 = $2_1 | 0; - var $3_1 = 0, $14_1 = 0; - label$1 : { - if (HEAP32[($2_1 + 4 | 0) >> 2] | 0) { - $3_1 = HEAP32[($2_1 + 8 | 0) >> 2] | 0; - if ($3_1) { - $14_1 = $5(HEAP32[$2_1 >> 2] | 0 | 0, $3_1 | 0, $1_1 | 0) | 0; - break label$1; - } - } - HEAPU8[1049704 >> 0] | 0; - $14_1 = $6($1_1 | 0) | 0; - } - $2_1 = $14_1; - HEAP32[($0_1 + 8 | 0) >> 2] = $1_1; - HEAP32[($0_1 + 4 | 0) >> 2] = $2_1 ? $2_1 : 1; - HEAP32[$0_1 >> 2] = !$2_1; - } - - function $5($0_1, $1_1, $2_1) { - $0_1 = $0_1 | 0; - $1_1 = $1_1 | 0; - $2_1 = $2_1 | 0; - var $3_1 = 0, $4_1 = 0, $5_1 = 0, $6_1 = 0, $7_1 = 0, $202 = 0, $8_1 = 0; - label$1 : { - label$2 : { - $4_1 = $0_1 - 4 | 0; - $6_1 = HEAP32[$4_1 >> 2] | 0; - $3_1 = $6_1 & -8 | 0; - $5_1 = $6_1 & 3 | 0; - if ($3_1 >>> 0 >= (($5_1 ? 4 : 8) + $1_1 | 0) >>> 0) { - if ($3_1 >>> 0 > ($1_1 + 39 | 0) >>> 0 ? $5_1 : 0) { - break label$2 - } - $1_1 = $2_1 >>> 0 < 11 >>> 0 ? 16 : ($2_1 + 11 | 0) & -8 | 0; - label$4 : { - label$5 : { - if (!$5_1) { - if ($1_1 >>> 0 < 256 >>> 0 | $3_1 >>> 0 < ($1_1 | 4 | 0) >>> 0 | 0 | ($3_1 - $1_1 | 0) >>> 0 >= 131073 >>> 0 | 0) { - break label$5 - } - break label$4; - } - $5_1 = $0_1 - 8 | 0; - $7_1 = $5_1 + $3_1 | 0; - label$7 : { - label$8 : { - label$9 : { - if ($1_1 >>> 0 > $3_1 >>> 0) { - if (($7_1 | 0) == (HEAP32[1050144 >> 2] | 0 | 0)) { - break label$7 - } - if (($7_1 | 0) == (HEAP32[1050140 >> 2] | 0 | 0)) { - break label$8 - } - $6_1 = HEAP32[($7_1 + 4 | 0) >> 2] | 0; - if ($6_1 & 2 | 0) { - break label$5 - } - $6_1 = $6_1 & -8 | 0; - $3_1 = $6_1 + $3_1 | 0; - if ($3_1 >>> 0 < $1_1 >>> 0) { - break label$5 - } - $16($7_1 | 0, $6_1 | 0); - $2_1 = $3_1 - $1_1 | 0; - if ($2_1 >>> 0 < 16 >>> 0) { - break label$9 - } - HEAP32[$4_1 >> 2] = $1_1 | ((HEAP32[$4_1 >> 2] | 0) & 1 | 0) | 0 | 2 | 0; - $1_1 = $1_1 + $5_1 | 0; - HEAP32[($1_1 + 4 | 0) >> 2] = $2_1 | 3 | 0; - $4_1 = $3_1 + $5_1 | 0; - HEAP32[($4_1 + 4 | 0) >> 2] = HEAP32[($4_1 + 4 | 0) >> 2] | 0 | 1 | 0; - $17($1_1 | 0, $2_1 | 0); - return $0_1 | 0; - } - $2_1 = $3_1 - $1_1 | 0; - if ($2_1 >>> 0 <= 15 >>> 0) { - break label$4 - } - HEAP32[$4_1 >> 2] = $1_1 | ($6_1 & 1 | 0) | 0 | 2 | 0; - $1_1 = $1_1 + $5_1 | 0; - HEAP32[($1_1 + 4 | 0) >> 2] = $2_1 | 3 | 0; - HEAP32[($7_1 + 4 | 0) >> 2] = HEAP32[($7_1 + 4 | 0) >> 2] | 0 | 1 | 0; - $17($1_1 | 0, $2_1 | 0); - return $0_1 | 0; - } - HEAP32[$4_1 >> 2] = $3_1 | ((HEAP32[$4_1 >> 2] | 0) & 1 | 0) | 0 | 2 | 0; - $1_1 = $3_1 + $5_1 | 0; - HEAP32[($1_1 + 4 | 0) >> 2] = HEAP32[($1_1 + 4 | 0) >> 2] | 0 | 1 | 0; - return $0_1 | 0; - } - $3_1 = (HEAP32[1050132 >> 2] | 0) + $3_1 | 0; - if ($3_1 >>> 0 < $1_1 >>> 0) { - break label$5 - } - label$11 : { - $2_1 = $3_1 - $1_1 | 0; - if ($2_1 >>> 0 <= 15 >>> 0) { - HEAP32[$4_1 >> 2] = $6_1 & 1 | 0 | $3_1 | 0 | 2 | 0; - $1_1 = $3_1 + $5_1 | 0; - HEAP32[($1_1 + 4 | 0) >> 2] = HEAP32[($1_1 + 4 | 0) >> 2] | 0 | 1 | 0; - $2_1 = 0; - $1_1 = 0; - break label$11; - } - HEAP32[$4_1 >> 2] = $1_1 | ($6_1 & 1 | 0) | 0 | 2 | 0; - $1_1 = $1_1 + $5_1 | 0; - HEAP32[($1_1 + 4 | 0) >> 2] = $2_1 | 1 | 0; - $4_1 = $3_1 + $5_1 | 0; - HEAP32[$4_1 >> 2] = $2_1; - HEAP32[($4_1 + 4 | 0) >> 2] = (HEAP32[($4_1 + 4 | 0) >> 2] | 0) & -2 | 0; - } - HEAP32[1050140 >> 2] = $1_1; - HEAP32[1050132 >> 2] = $2_1; - return $0_1 | 0; - } - $3_1 = (HEAP32[1050136 >> 2] | 0) + $3_1 | 0; - if ($3_1 >>> 0 > $1_1 >>> 0) { - break label$1 - } - } - $1_1 = $6($2_1 | 0) | 0; - if (!$1_1) { - return 0 | 0 - } - $202 = $1_1; - $1_1 = HEAP32[$4_1 >> 2] | 0; - $1_1 = ($1_1 & 3 | 0 ? -4 : -8) + ($1_1 & -8 | 0) | 0; - $8_1 = $57($202 | 0, $0_1 | 0, ($1_1 >>> 0 < $2_1 >>> 0 ? $1_1 : $2_1) | 0) | 0; - $14($0_1 | 0); - $0_1 = $8_1; - } - return $0_1 | 0; - } - $15(1049557 | 0, 1049604 | 0); - wasm2js_trap(); - } - $15(1049620 | 0, 1049668 | 0); - wasm2js_trap(); - } - HEAP32[$4_1 >> 2] = $1_1 | ($6_1 & 1 | 0) | 0 | 2 | 0; - $2_1 = $1_1 + $5_1 | 0; - $1_1 = $3_1 - $1_1 | 0; - HEAP32[($2_1 + 4 | 0) >> 2] = $1_1 | 1 | 0; - HEAP32[1050136 >> 2] = $1_1; - HEAP32[1050144 >> 2] = $2_1; - return $0_1 | 0; - } - - function $6($0_1) { - $0_1 = $0_1 | 0; - var $1_1 = 0, $2_1 = 0, $3_1 = 0, $4_1 = 0, $5_1 = 0, $6_1 = 0, $7_1 = 0, i64toi32_i32$1 = 0, i64toi32_i32$2 = 0, i64toi32_i32$0 = 0, $8_1 = 0, $318 = 0, $383 = 0, $740 = 0, $824 = 0, $1004 = 0, $241 = 0, $9_1 = 0, $9$hi = 0, $691 = 0, wasm2js_i32$0 = 0, wasm2js_i32$1 = 0; - label$1 : { - label$2 : { - label$3 : { - label$4 : { - label$5 : { - label$6 : { - label$7 : { - label$8 : { - if ($0_1 >>> 0 >= 245 >>> 0) { - if ($0_1 >>> 0 >= -65587 >>> 0) { - break label$4 - } - $1_1 = $0_1 + 11 | 0; - $5_1 = $1_1 & -8 | 0; - $8_1 = HEAP32[1050128 >> 2] | 0; - if (!$8_1) { - break label$5 - } - $7_1 = 31; - $3_1 = 0 - $5_1 | 0; - if ($0_1 >>> 0 <= 16777204 >>> 0) { - $0_1 = Math_clz32($1_1 >>> 8 | 0); - $7_1 = ((($5_1 >>> (6 - $0_1 | 0) | 0) & 1 | 0) - ($0_1 << 1 | 0) | 0) + 62 | 0; - } - $2_1 = HEAP32[(($7_1 << 2 | 0) + 1049716 | 0) >> 2] | 0; - if (!$2_1) { - $0_1 = 0; - $1_1 = 0; - break label$8; - } - $0_1 = 0; - $4_1 = $5_1 << (($7_1 | 0) != (31 | 0) ? 25 - ($7_1 >>> 1 | 0) | 0 : 0) | 0; - $1_1 = 0; - label$12 : while (1) { - label$13 : { - $6_1 = (HEAP32[($2_1 + 4 | 0) >> 2] | 0) & -8 | 0; - if ($6_1 >>> 0 < $5_1 >>> 0) { - break label$13 - } - $6_1 = $6_1 - $5_1 | 0; - if ($6_1 >>> 0 >= $3_1 >>> 0) { - break label$13 - } - $1_1 = $2_1; - $3_1 = $6_1; - if ($3_1) { - break label$13 - } - $3_1 = 0; - $0_1 = $1_1; - break label$7; - } - $6_1 = HEAP32[($2_1 + 20 | 0) >> 2] | 0; - $2_1 = HEAP32[(($2_1 + (($4_1 >>> 29 | 0) & 4 | 0) | 0) + 16 | 0) >> 2] | 0; - $0_1 = $6_1 ? (($6_1 | 0) != ($2_1 | 0) ? $6_1 : $0_1) : $0_1; - $4_1 = $4_1 << 1 | 0; - if ($2_1) { - continue label$12 - } - break label$12; - }; - break label$8; - } - $2_1 = HEAP32[1050124 >> 2] | 0; - $5_1 = $0_1 >>> 0 < 11 >>> 0 ? 16 : ($0_1 + 11 | 0) & 504 | 0; - $0_1 = $5_1 >>> 3 | 0; - $1_1 = $2_1 >>> $0_1 | 0; - if ($1_1 & 3 | 0) { - label$15 : { - $6_1 = (($1_1 ^ -1 | 0) & 1 | 0) + $0_1 | 0; - $0_1 = $6_1 << 3 | 0; - $4_1 = $0_1 + 1049860 | 0; - $1_1 = HEAP32[($0_1 + 1049868 | 0) >> 2] | 0; - $3_1 = HEAP32[($1_1 + 8 | 0) >> 2] | 0; - if (($4_1 | 0) != ($3_1 | 0)) { - HEAP32[($3_1 + 12 | 0) >> 2] = $4_1; - HEAP32[($4_1 + 8 | 0) >> 2] = $3_1; - break label$15; - } - (wasm2js_i32$0 = 1050124, wasm2js_i32$1 = $2_1 & (__wasm_rotl_i32(-2 | 0, $6_1 | 0) | 0) | 0), HEAP32[wasm2js_i32$0 >> 2] = wasm2js_i32$1; - } - HEAP32[($1_1 + 4 | 0) >> 2] = $0_1 | 3 | 0; - $0_1 = $0_1 + $1_1 | 0; - HEAP32[($0_1 + 4 | 0) >> 2] = HEAP32[($0_1 + 4 | 0) >> 2] | 0 | 1 | 0; - return $1_1 + 8 | 0 | 0; - } - if ($5_1 >>> 0 <= (HEAP32[1050132 >> 2] | 0) >>> 0) { - break label$5 - } - label$17 : { - label$18 : { - if (!$1_1) { - $0_1 = HEAP32[1050128 >> 2] | 0; - if (!$0_1) { - break label$5 - } - $1_1 = HEAP32[(((__wasm_ctz_i32($0_1 | 0) | 0) << 2 | 0) + 1049716 | 0) >> 2] | 0; - $3_1 = ((HEAP32[($1_1 + 4 | 0) >> 2] | 0) & -8 | 0) - $5_1 | 0; - $2_1 = $1_1; - label$20 : while (1) { - label$21 : { - $0_1 = HEAP32[($1_1 + 16 | 0) >> 2] | 0; - if ($0_1) { - break label$21 - } - $0_1 = HEAP32[($1_1 + 20 | 0) >> 2] | 0; - if ($0_1) { - break label$21 - } - $7_1 = HEAP32[($2_1 + 24 | 0) >> 2] | 0; - label$22 : { - label$23 : { - $0_1 = HEAP32[($2_1 + 12 | 0) >> 2] | 0; - if (($2_1 | 0) == ($0_1 | 0)) { - $0_1 = HEAP32[($2_1 + 20 | 0) >> 2] | 0; - $1_1 = HEAP32[($2_1 + ($0_1 ? 20 : 16) | 0) >> 2] | 0; - if ($1_1) { - break label$23 - } - $0_1 = 0; - break label$22; - } - $1_1 = HEAP32[($2_1 + 8 | 0) >> 2] | 0; - HEAP32[($1_1 + 12 | 0) >> 2] = $0_1; - HEAP32[($0_1 + 8 | 0) >> 2] = $1_1; - break label$22; - } - $4_1 = $0_1 ? $2_1 + 20 | 0 : $2_1 + 16 | 0; - label$25 : while (1) { - $6_1 = $4_1; - $0_1 = $1_1; - $1_1 = HEAP32[($0_1 + 20 | 0) >> 2] | 0; - $4_1 = $1_1 ? $0_1 + 20 | 0 : $0_1 + 16 | 0; - $1_1 = HEAP32[($0_1 + ($1_1 ? 20 : 16) | 0) >> 2] | 0; - if ($1_1) { - continue label$25 - } - break label$25; - }; - HEAP32[$6_1 >> 2] = 0; - } - if (!$7_1) { - break label$17 - } - $1_1 = ((HEAP32[($2_1 + 28 | 0) >> 2] | 0) << 2 | 0) + 1049716 | 0; - if (($2_1 | 0) != (HEAP32[$1_1 >> 2] | 0 | 0)) { - HEAP32[($7_1 + ((HEAP32[($7_1 + 16 | 0) >> 2] | 0 | 0) == ($2_1 | 0) ? 16 : 20) | 0) >> 2] = $0_1; - if (!$0_1) { - break label$17 - } - break label$18; - } - HEAP32[$1_1 >> 2] = $0_1; - if ($0_1) { - break label$18 - } - (wasm2js_i32$0 = 1050128, wasm2js_i32$1 = (HEAP32[1050128 >> 2] | 0) & (__wasm_rotl_i32(-2 | 0, HEAP32[($2_1 + 28 | 0) >> 2] | 0 | 0) | 0) | 0), HEAP32[wasm2js_i32$0 >> 2] = wasm2js_i32$1; - break label$17; - } - $1_1 = ((HEAP32[($0_1 + 4 | 0) >> 2] | 0) & -8 | 0) - $5_1 | 0; - $241 = $1_1; - $1_1 = $1_1 >>> 0 < $3_1 >>> 0; - $3_1 = $1_1 ? $241 : $3_1; - $2_1 = $1_1 ? $0_1 : $2_1; - $1_1 = $0_1; - continue label$20; - }; - } - label$27 : { - $4_1 = 2 << $0_1 | 0; - $6_1 = __wasm_ctz_i32(($4_1 | (0 - $4_1 | 0) | 0) & ($1_1 << $0_1 | 0) | 0 | 0) | 0; - $1_1 = $6_1 << 3 | 0; - $4_1 = $1_1 + 1049860 | 0; - $0_1 = HEAP32[($1_1 + 1049868 | 0) >> 2] | 0; - $3_1 = HEAP32[($0_1 + 8 | 0) >> 2] | 0; - if (($4_1 | 0) != ($3_1 | 0)) { - HEAP32[($3_1 + 12 | 0) >> 2] = $4_1; - HEAP32[($4_1 + 8 | 0) >> 2] = $3_1; - break label$27; - } - (wasm2js_i32$0 = 1050124, wasm2js_i32$1 = $2_1 & (__wasm_rotl_i32(-2 | 0, $6_1 | 0) | 0) | 0), HEAP32[wasm2js_i32$0 >> 2] = wasm2js_i32$1; - } - HEAP32[($0_1 + 4 | 0) >> 2] = $5_1 | 3 | 0; - $6_1 = $0_1 + $5_1 | 0; - $4_1 = $1_1 - $5_1 | 0; - HEAP32[($6_1 + 4 | 0) >> 2] = $4_1 | 1 | 0; - HEAP32[($0_1 + $1_1 | 0) >> 2] = $4_1; - $3_1 = HEAP32[1050132 >> 2] | 0; - if ($3_1) { - $1_1 = ($3_1 & -8 | 0) + 1049860 | 0; - $2_1 = HEAP32[1050140 >> 2] | 0; - label$30 : { - $5_1 = HEAP32[1050124 >> 2] | 0; - $3_1 = 1 << ($3_1 >>> 3 | 0) | 0; - if (!($5_1 & $3_1 | 0)) { - HEAP32[1050124 >> 2] = $3_1 | $5_1 | 0; - $318 = $1_1; - break label$30; - } - $318 = HEAP32[($1_1 + 8 | 0) >> 2] | 0; - } - $3_1 = $318; - HEAP32[($1_1 + 8 | 0) >> 2] = $2_1; - HEAP32[($3_1 + 12 | 0) >> 2] = $2_1; - HEAP32[($2_1 + 12 | 0) >> 2] = $1_1; - HEAP32[($2_1 + 8 | 0) >> 2] = $3_1; - } - HEAP32[1050140 >> 2] = $6_1; - HEAP32[1050132 >> 2] = $4_1; - break label$1; - } - HEAP32[($0_1 + 24 | 0) >> 2] = $7_1; - $1_1 = HEAP32[($2_1 + 16 | 0) >> 2] | 0; - if ($1_1) { - HEAP32[($0_1 + 16 | 0) >> 2] = $1_1; - HEAP32[($1_1 + 24 | 0) >> 2] = $0_1; - } - $1_1 = HEAP32[($2_1 + 20 | 0) >> 2] | 0; - if (!$1_1) { - break label$17 - } - HEAP32[($0_1 + 20 | 0) >> 2] = $1_1; - HEAP32[($1_1 + 24 | 0) >> 2] = $0_1; - } - label$33 : { - label$34 : { - if ($3_1 >>> 0 >= 16 >>> 0) { - HEAP32[($2_1 + 4 | 0) >> 2] = $5_1 | 3 | 0; - $4_1 = $2_1 + $5_1 | 0; - HEAP32[($4_1 + 4 | 0) >> 2] = $3_1 | 1 | 0; - HEAP32[($3_1 + $4_1 | 0) >> 2] = $3_1; - $6_1 = HEAP32[1050132 >> 2] | 0; - if (!$6_1) { - break label$34 - } - $0_1 = ($6_1 & -8 | 0) + 1049860 | 0; - $1_1 = HEAP32[1050140 >> 2] | 0; - label$36 : { - $5_1 = HEAP32[1050124 >> 2] | 0; - $6_1 = 1 << ($6_1 >>> 3 | 0) | 0; - if (!($5_1 & $6_1 | 0)) { - HEAP32[1050124 >> 2] = $5_1 | $6_1 | 0; - $383 = $0_1; - break label$36; - } - $383 = HEAP32[($0_1 + 8 | 0) >> 2] | 0; - } - $6_1 = $383; - HEAP32[($0_1 + 8 | 0) >> 2] = $1_1; - HEAP32[($6_1 + 12 | 0) >> 2] = $1_1; - HEAP32[($1_1 + 12 | 0) >> 2] = $0_1; - HEAP32[($1_1 + 8 | 0) >> 2] = $6_1; - break label$34; - } - $0_1 = $3_1 + $5_1 | 0; - HEAP32[($2_1 + 4 | 0) >> 2] = $0_1 | 3 | 0; - $0_1 = $0_1 + $2_1 | 0; - HEAP32[($0_1 + 4 | 0) >> 2] = HEAP32[($0_1 + 4 | 0) >> 2] | 0 | 1 | 0; - break label$33; - } - HEAP32[1050140 >> 2] = $4_1; - HEAP32[1050132 >> 2] = $3_1; - } - return $2_1 + 8 | 0 | 0; - } - if (!($0_1 | $1_1 | 0)) { - $1_1 = 0; - $0_1 = 2 << $7_1 | 0; - $0_1 = ($0_1 | (0 - $0_1 | 0) | 0) & $8_1 | 0; - if (!$0_1) { - break label$5 - } - $0_1 = HEAP32[(((__wasm_ctz_i32($0_1 | 0) | 0) << 2 | 0) + 1049716 | 0) >> 2] | 0; - } - if (!$0_1) { - break label$6 - } - } - label$39 : while (1) { - $4_1 = (HEAP32[($0_1 + 4 | 0) >> 2] | 0) & -8 | 0; - $6_1 = $4_1 - $5_1 | 0; - $7_1 = $6_1 >>> 0 < $3_1 >>> 0; - $8_1 = $7_1 ? $0_1 : $1_1; - $2_1 = HEAP32[($0_1 + 16 | 0) >> 2] | 0; - if (!$2_1) { - $2_1 = HEAP32[($0_1 + 20 | 0) >> 2] | 0 - } - $0_1 = $4_1 >>> 0 < $5_1 >>> 0; - $1_1 = $0_1 ? $1_1 : $8_1; - $3_1 = $0_1 ? $3_1 : $7_1 ? $6_1 : $3_1; - $0_1 = $2_1; - if ($0_1) { - continue label$39 - } - break label$39; - }; - } - if (!$1_1) { - break label$5 - } - $0_1 = HEAP32[1050132 >> 2] | 0; - if ($5_1 >>> 0 <= $0_1 >>> 0 & $3_1 >>> 0 >= ($0_1 - $5_1 | 0) >>> 0 | 0) { - break label$5 - } - $7_1 = HEAP32[($1_1 + 24 | 0) >> 2] | 0; - label$41 : { - label$42 : { - $0_1 = HEAP32[($1_1 + 12 | 0) >> 2] | 0; - if (($1_1 | 0) == ($0_1 | 0)) { - $0_1 = HEAP32[($1_1 + 20 | 0) >> 2] | 0; - $2_1 = HEAP32[($1_1 + ($0_1 ? 20 : 16) | 0) >> 2] | 0; - if ($2_1) { - break label$42 - } - $0_1 = 0; - break label$41; - } - $2_1 = HEAP32[($1_1 + 8 | 0) >> 2] | 0; - HEAP32[($2_1 + 12 | 0) >> 2] = $0_1; - HEAP32[($0_1 + 8 | 0) >> 2] = $2_1; - break label$41; - } - $4_1 = $0_1 ? $1_1 + 20 | 0 : $1_1 + 16 | 0; - label$44 : while (1) { - $6_1 = $4_1; - $0_1 = $2_1; - $2_1 = HEAP32[($0_1 + 20 | 0) >> 2] | 0; - $4_1 = $2_1 ? $0_1 + 20 | 0 : $0_1 + 16 | 0; - $2_1 = HEAP32[($0_1 + ($2_1 ? 20 : 16) | 0) >> 2] | 0; - if ($2_1) { - continue label$44 - } - break label$44; - }; - HEAP32[$6_1 >> 2] = 0; - } - if (!$7_1) { - break label$2 - } - $2_1 = ((HEAP32[($1_1 + 28 | 0) >> 2] | 0) << 2 | 0) + 1049716 | 0; - if (($1_1 | 0) != (HEAP32[$2_1 >> 2] | 0 | 0)) { - HEAP32[($7_1 + ((HEAP32[($7_1 + 16 | 0) >> 2] | 0 | 0) == ($1_1 | 0) ? 16 : 20) | 0) >> 2] = $0_1; - if (!$0_1) { - break label$2 - } - break label$3; - } - HEAP32[$2_1 >> 2] = $0_1; - if ($0_1) { - break label$3 - } - (wasm2js_i32$0 = 1050128, wasm2js_i32$1 = (HEAP32[1050128 >> 2] | 0) & (__wasm_rotl_i32(-2 | 0, HEAP32[($1_1 + 28 | 0) >> 2] | 0 | 0) | 0) | 0), HEAP32[wasm2js_i32$0 >> 2] = wasm2js_i32$1; - break label$2; - } - label$46 : { - label$47 : { - label$48 : { - label$49 : { - label$50 : { - $1_1 = HEAP32[1050132 >> 2] | 0; - if ($5_1 >>> 0 > $1_1 >>> 0) { - $0_1 = HEAP32[1050136 >> 2] | 0; - if ($5_1 >>> 0 >= $0_1 >>> 0) { - $3_1 = 0; - $0_1 = $5_1 + 65583 | 0; - $1_1 = __wasm_memory_grow($0_1 >>> 16 | 0 | 0); - $4_1 = ($1_1 | 0) == (-1 | 0); - if ($4_1) { - break label$4 - } - $2_1 = $1_1 << 16 | 0; - if (!$2_1) { - break label$4 - } - $3_1 = $4_1 ? 0 : $0_1 & -65536 | 0; - $0_1 = $3_1 + (HEAP32[1050148 >> 2] | 0) | 0; - HEAP32[1050148 >> 2] = $0_1; - $1_1 = HEAP32[1050152 >> 2] | 0; - HEAP32[1050152 >> 2] = $0_1 >>> 0 < $1_1 >>> 0 ? $1_1 : $0_1; - label$53 : { - label$54 : { - $1_1 = HEAP32[1050144 >> 2] | 0; - if ($1_1) { - $0_1 = 1049844; - label$56 : while (1) { - $4_1 = HEAP32[$0_1 >> 2] | 0; - $6_1 = HEAP32[($0_1 + 4 | 0) >> 2] | 0; - if (($4_1 + $6_1 | 0 | 0) == ($2_1 | 0)) { - break label$54 - } - $0_1 = HEAP32[($0_1 + 8 | 0) >> 2] | 0; - if ($0_1) { - continue label$56 - } - break label$56; - }; - break label$53; - } - $0_1 = HEAP32[1050160 >> 2] | 0; - if (!($0_1 >>> 0 <= $2_1 >>> 0 ? $0_1 : 0)) { - HEAP32[1050160 >> 2] = $2_1 - } - HEAP32[1050164 >> 2] = 4095; - HEAP32[1049848 >> 2] = $3_1; - HEAP32[1049844 >> 2] = $2_1; - HEAP32[1049872 >> 2] = 1049860; - HEAP32[1049880 >> 2] = 1049868; - HEAP32[1049868 >> 2] = 1049860; - HEAP32[1049888 >> 2] = 1049876; - HEAP32[1049876 >> 2] = 1049868; - HEAP32[1049896 >> 2] = 1049884; - HEAP32[1049884 >> 2] = 1049876; - HEAP32[1049904 >> 2] = 1049892; - HEAP32[1049892 >> 2] = 1049884; - HEAP32[1049912 >> 2] = 1049900; - HEAP32[1049900 >> 2] = 1049892; - HEAP32[1049920 >> 2] = 1049908; - HEAP32[1049908 >> 2] = 1049900; - HEAP32[1049928 >> 2] = 1049916; - HEAP32[1049916 >> 2] = 1049908; - HEAP32[1049856 >> 2] = 0; - HEAP32[1049936 >> 2] = 1049924; - HEAP32[1049924 >> 2] = 1049916; - HEAP32[1049932 >> 2] = 1049924; - HEAP32[1049944 >> 2] = 1049932; - HEAP32[1049940 >> 2] = 1049932; - HEAP32[1049952 >> 2] = 1049940; - HEAP32[1049948 >> 2] = 1049940; - HEAP32[1049960 >> 2] = 1049948; - HEAP32[1049956 >> 2] = 1049948; - HEAP32[1049968 >> 2] = 1049956; - HEAP32[1049964 >> 2] = 1049956; - HEAP32[1049976 >> 2] = 1049964; - HEAP32[1049972 >> 2] = 1049964; - HEAP32[1049984 >> 2] = 1049972; - HEAP32[1049980 >> 2] = 1049972; - HEAP32[1049992 >> 2] = 1049980; - HEAP32[1049988 >> 2] = 1049980; - HEAP32[105e4 >> 2] = 1049988; - HEAP32[1050008 >> 2] = 1049996; - HEAP32[1049996 >> 2] = 1049988; - HEAP32[1050016 >> 2] = 1050004; - HEAP32[1050004 >> 2] = 1049996; - HEAP32[1050024 >> 2] = 1050012; - HEAP32[1050012 >> 2] = 1050004; - HEAP32[1050032 >> 2] = 1050020; - HEAP32[1050020 >> 2] = 1050012; - HEAP32[1050040 >> 2] = 1050028; - HEAP32[1050028 >> 2] = 1050020; - HEAP32[1050048 >> 2] = 1050036; - HEAP32[1050036 >> 2] = 1050028; - HEAP32[1050056 >> 2] = 1050044; - HEAP32[1050044 >> 2] = 1050036; - HEAP32[1050064 >> 2] = 1050052; - HEAP32[1050052 >> 2] = 1050044; - HEAP32[1050072 >> 2] = 1050060; - HEAP32[1050060 >> 2] = 1050052; - HEAP32[1050080 >> 2] = 1050068; - HEAP32[1050068 >> 2] = 1050060; - HEAP32[1050088 >> 2] = 1050076; - HEAP32[1050076 >> 2] = 1050068; - HEAP32[1050096 >> 2] = 1050084; - HEAP32[1050084 >> 2] = 1050076; - HEAP32[1050104 >> 2] = 1050092; - HEAP32[1050092 >> 2] = 1050084; - HEAP32[1050112 >> 2] = 1050100; - HEAP32[1050100 >> 2] = 1050092; - HEAP32[1050120 >> 2] = 1050108; - HEAP32[1050108 >> 2] = 1050100; - HEAP32[1050144 >> 2] = $2_1; - HEAP32[1050116 >> 2] = 1050108; - $0_1 = $3_1 - 40 | 0; - HEAP32[1050136 >> 2] = $0_1; - HEAP32[($2_1 + 4 | 0) >> 2] = $0_1 | 1 | 0; - HEAP32[(($0_1 + $2_1 | 0) + 4 | 0) >> 2] = 40; - HEAP32[1050156 >> 2] = 2097152; - break label$46; - } - if ($1_1 >>> 0 < $4_1 >>> 0 | $1_1 >>> 0 >= $2_1 >>> 0 | 0) { - break label$53 - } - if (!(HEAP32[($0_1 + 12 | 0) >> 2] | 0)) { - break label$50 - } - } - $0_1 = HEAP32[1050160 >> 2] | 0; - HEAP32[1050160 >> 2] = $0_1 >>> 0 < $2_1 >>> 0 ? $0_1 : $2_1; - $4_1 = $2_1 + $3_1 | 0; - $0_1 = 1049844; - label$58 : { - label$59 : { - label$60 : while (1) { - $6_1 = HEAP32[$0_1 >> 2] | 0; - if (($4_1 | 0) != ($6_1 | 0)) { - $0_1 = HEAP32[($0_1 + 8 | 0) >> 2] | 0; - if ($0_1) { - continue label$60 - } - break label$59; - } - break label$60; - }; - if (!(HEAP32[($0_1 + 12 | 0) >> 2] | 0)) { - break label$58 - } - } - $0_1 = 1049844; - label$62 : while (1) { - label$63 : { - $4_1 = HEAP32[$0_1 >> 2] | 0; - if ($1_1 >>> 0 >= $4_1 >>> 0) { - $6_1 = $4_1 + (HEAP32[($0_1 + 4 | 0) >> 2] | 0) | 0; - if ($1_1 >>> 0 < $6_1 >>> 0) { - break label$63 - } - } - $0_1 = HEAP32[($0_1 + 8 | 0) >> 2] | 0; - continue label$62; - } - break label$62; - }; - HEAP32[1050144 >> 2] = $2_1; - $0_1 = $3_1 - 40 | 0; - HEAP32[1050136 >> 2] = $0_1; - HEAP32[($2_1 + 4 | 0) >> 2] = $0_1 | 1 | 0; - HEAP32[(($0_1 + $2_1 | 0) + 4 | 0) >> 2] = 40; - HEAP32[1050156 >> 2] = 2097152; - $0_1 = (($6_1 - 32 | 0) & -8 | 0) - 8 | 0; - $4_1 = $0_1 >>> 0 < ($1_1 + 16 | 0) >>> 0 ? $1_1 : $0_1; - HEAP32[($4_1 + 4 | 0) >> 2] = 27; - i64toi32_i32$2 = 1049844; - i64toi32_i32$0 = HEAP32[i64toi32_i32$2 >> 2] | 0; - i64toi32_i32$1 = HEAP32[(i64toi32_i32$2 + 4 | 0) >> 2] | 0; - $9_1 = i64toi32_i32$0; - $9$hi = i64toi32_i32$1; - i64toi32_i32$2 = 1049852; - i64toi32_i32$1 = HEAP32[i64toi32_i32$2 >> 2] | 0; - i64toi32_i32$0 = HEAP32[(i64toi32_i32$2 + 4 | 0) >> 2] | 0; - $691 = i64toi32_i32$1; - i64toi32_i32$1 = $4_1 + 16 | 0; - HEAP32[i64toi32_i32$1 >> 2] = $691; - HEAP32[(i64toi32_i32$1 + 4 | 0) >> 2] = i64toi32_i32$0; - i64toi32_i32$0 = $9$hi; - i64toi32_i32$1 = $4_1; - HEAP32[($4_1 + 8 | 0) >> 2] = $9_1; - HEAP32[($4_1 + 12 | 0) >> 2] = i64toi32_i32$0; - HEAP32[1049848 >> 2] = $3_1; - HEAP32[1049844 >> 2] = $2_1; - HEAP32[1049852 >> 2] = $4_1 + 8 | 0; - HEAP32[1049856 >> 2] = 0; - $0_1 = $4_1 + 28 | 0; - label$65 : while (1) { - HEAP32[$0_1 >> 2] = 7; - $0_1 = $0_1 + 4 | 0; - if ($0_1 >>> 0 < $6_1 >>> 0) { - continue label$65 - } - break label$65; - }; - if (($1_1 | 0) == ($4_1 | 0)) { - break label$46 - } - HEAP32[($4_1 + 4 | 0) >> 2] = (HEAP32[($4_1 + 4 | 0) >> 2] | 0) & -2 | 0; - $0_1 = $4_1 - $1_1 | 0; - HEAP32[($1_1 + 4 | 0) >> 2] = $0_1 | 1 | 0; - HEAP32[$4_1 >> 2] = $0_1; - if ($0_1 >>> 0 >= 256 >>> 0) { - $54($1_1 | 0, $0_1 | 0); - break label$46; - } - $2_1 = ($0_1 & 248 | 0) + 1049860 | 0; - label$67 : { - $4_1 = HEAP32[1050124 >> 2] | 0; - $0_1 = 1 << ($0_1 >>> 3 | 0) | 0; - if (!($4_1 & $0_1 | 0)) { - HEAP32[1050124 >> 2] = $0_1 | $4_1 | 0; - $740 = $2_1; - break label$67; - } - $740 = HEAP32[($2_1 + 8 | 0) >> 2] | 0; - } - $0_1 = $740; - HEAP32[($2_1 + 8 | 0) >> 2] = $1_1; - HEAP32[($0_1 + 12 | 0) >> 2] = $1_1; - HEAP32[($1_1 + 12 | 0) >> 2] = $2_1; - HEAP32[($1_1 + 8 | 0) >> 2] = $0_1; - break label$46; - } - HEAP32[$0_1 >> 2] = $2_1; - HEAP32[($0_1 + 4 | 0) >> 2] = (HEAP32[($0_1 + 4 | 0) >> 2] | 0) + $3_1 | 0; - HEAP32[($2_1 + 4 | 0) >> 2] = $5_1 | 3 | 0; - $3_1 = (($6_1 + 15 | 0) & -8 | 0) - 8 | 0; - $0_1 = $2_1 + $5_1 | 0; - $5_1 = $3_1 - $0_1 | 0; - if (($3_1 | 0) == (HEAP32[1050144 >> 2] | 0 | 0)) { - break label$49 - } - if (($3_1 | 0) == (HEAP32[1050140 >> 2] | 0 | 0)) { - break label$48 - } - $1_1 = HEAP32[($3_1 + 4 | 0) >> 2] | 0; - if (($1_1 & 3 | 0 | 0) == (1 | 0)) { - $1_1 = $1_1 & -8 | 0; - $16($3_1 | 0, $1_1 | 0); - $5_1 = $1_1 + $5_1 | 0; - $3_1 = $1_1 + $3_1 | 0; - $1_1 = HEAP32[($3_1 + 4 | 0) >> 2] | 0; - } - HEAP32[($3_1 + 4 | 0) >> 2] = $1_1 & -2 | 0; - HEAP32[($0_1 + 4 | 0) >> 2] = $5_1 | 1 | 0; - HEAP32[($0_1 + $5_1 | 0) >> 2] = $5_1; - if ($5_1 >>> 0 >= 256 >>> 0) { - $54($0_1 | 0, $5_1 | 0); - break label$47; - } - $1_1 = ($5_1 & 248 | 0) + 1049860 | 0; - label$71 : { - $4_1 = HEAP32[1050124 >> 2] | 0; - $3_1 = 1 << ($5_1 >>> 3 | 0) | 0; - if (!($4_1 & $3_1 | 0)) { - HEAP32[1050124 >> 2] = $3_1 | $4_1 | 0; - $824 = $1_1; - break label$71; - } - $824 = HEAP32[($1_1 + 8 | 0) >> 2] | 0; - } - $4_1 = $824; - HEAP32[($1_1 + 8 | 0) >> 2] = $0_1; - HEAP32[($4_1 + 12 | 0) >> 2] = $0_1; - HEAP32[($0_1 + 12 | 0) >> 2] = $1_1; - HEAP32[($0_1 + 8 | 0) >> 2] = $4_1; - break label$47; - } - $1_1 = $0_1 - $5_1 | 0; - HEAP32[1050136 >> 2] = $1_1; - $0_1 = HEAP32[1050144 >> 2] | 0; - $2_1 = $0_1 + $5_1 | 0; - HEAP32[1050144 >> 2] = $2_1; - HEAP32[($2_1 + 4 | 0) >> 2] = $1_1 | 1 | 0; - HEAP32[($0_1 + 4 | 0) >> 2] = $5_1 | 3 | 0; - $3_1 = $0_1 + 8 | 0; - break label$4; - } - $0_1 = HEAP32[1050140 >> 2] | 0; - label$73 : { - $2_1 = $1_1 - $5_1 | 0; - if ($2_1 >>> 0 <= 15 >>> 0) { - HEAP32[1050140 >> 2] = 0; - HEAP32[1050132 >> 2] = 0; - HEAP32[($0_1 + 4 | 0) >> 2] = $1_1 | 3 | 0; - $1_1 = $0_1 + $1_1 | 0; - HEAP32[($1_1 + 4 | 0) >> 2] = HEAP32[($1_1 + 4 | 0) >> 2] | 0 | 1 | 0; - break label$73; - } - HEAP32[1050132 >> 2] = $2_1; - $4_1 = $0_1 + $5_1 | 0; - HEAP32[1050140 >> 2] = $4_1; - HEAP32[($4_1 + 4 | 0) >> 2] = $2_1 | 1 | 0; - HEAP32[($0_1 + $1_1 | 0) >> 2] = $2_1; - HEAP32[($0_1 + 4 | 0) >> 2] = $5_1 | 3 | 0; - } - break label$1; - } - HEAP32[($0_1 + 4 | 0) >> 2] = $3_1 + $6_1 | 0; - $0_1 = HEAP32[1050144 >> 2] | 0; - $1_1 = ($0_1 + 15 | 0) & -8 | 0; - $2_1 = $1_1 - 8 | 0; - HEAP32[1050144 >> 2] = $2_1; - $4_1 = (HEAP32[1050136 >> 2] | 0) + $3_1 | 0; - $1_1 = ($4_1 + ($0_1 - $1_1 | 0) | 0) + 8 | 0; - HEAP32[1050136 >> 2] = $1_1; - HEAP32[($2_1 + 4 | 0) >> 2] = $1_1 | 1 | 0; - HEAP32[(($0_1 + $4_1 | 0) + 4 | 0) >> 2] = 40; - HEAP32[1050156 >> 2] = 2097152; - break label$46; - } - HEAP32[1050144 >> 2] = $0_1; - $1_1 = (HEAP32[1050136 >> 2] | 0) + $5_1 | 0; - HEAP32[1050136 >> 2] = $1_1; - HEAP32[($0_1 + 4 | 0) >> 2] = $1_1 | 1 | 0; - break label$47; - } - HEAP32[1050140 >> 2] = $0_1; - $1_1 = (HEAP32[1050132 >> 2] | 0) + $5_1 | 0; - HEAP32[1050132 >> 2] = $1_1; - HEAP32[($0_1 + 4 | 0) >> 2] = $1_1 | 1 | 0; - HEAP32[($0_1 + $1_1 | 0) >> 2] = $1_1; - } - return $2_1 + 8 | 0 | 0; - } - $3_1 = 0; - $0_1 = HEAP32[1050136 >> 2] | 0; - if ($0_1 >>> 0 <= $5_1 >>> 0) { - break label$4 - } - $1_1 = $0_1 - $5_1 | 0; - HEAP32[1050136 >> 2] = $1_1; - $0_1 = HEAP32[1050144 >> 2] | 0; - $2_1 = $0_1 + $5_1 | 0; - HEAP32[1050144 >> 2] = $2_1; - HEAP32[($2_1 + 4 | 0) >> 2] = $1_1 | 1 | 0; - HEAP32[($0_1 + 4 | 0) >> 2] = $5_1 | 3 | 0; - break label$1; - } - return $3_1 | 0; - } - HEAP32[($0_1 + 24 | 0) >> 2] = $7_1; - $2_1 = HEAP32[($1_1 + 16 | 0) >> 2] | 0; - if ($2_1) { - HEAP32[($0_1 + 16 | 0) >> 2] = $2_1; - HEAP32[($2_1 + 24 | 0) >> 2] = $0_1; - } - $2_1 = HEAP32[($1_1 + 20 | 0) >> 2] | 0; - if (!$2_1) { - break label$2 - } - HEAP32[($0_1 + 20 | 0) >> 2] = $2_1; - HEAP32[($2_1 + 24 | 0) >> 2] = $0_1; - } - label$76 : { - if ($3_1 >>> 0 >= 16 >>> 0) { - HEAP32[($1_1 + 4 | 0) >> 2] = $5_1 | 3 | 0; - $0_1 = $1_1 + $5_1 | 0; - HEAP32[($0_1 + 4 | 0) >> 2] = $3_1 | 1 | 0; - HEAP32[($0_1 + $3_1 | 0) >> 2] = $3_1; - if ($3_1 >>> 0 >= 256 >>> 0) { - $54($0_1 | 0, $3_1 | 0); - break label$76; - } - $2_1 = ($3_1 & 248 | 0) + 1049860 | 0; - label$79 : { - $4_1 = HEAP32[1050124 >> 2] | 0; - $3_1 = 1 << ($3_1 >>> 3 | 0) | 0; - if (!($4_1 & $3_1 | 0)) { - HEAP32[1050124 >> 2] = $3_1 | $4_1 | 0; - $1004 = $2_1; - break label$79; - } - $1004 = HEAP32[($2_1 + 8 | 0) >> 2] | 0; - } - $4_1 = $1004; - HEAP32[($2_1 + 8 | 0) >> 2] = $0_1; - HEAP32[($4_1 + 12 | 0) >> 2] = $0_1; - HEAP32[($0_1 + 12 | 0) >> 2] = $2_1; - HEAP32[($0_1 + 8 | 0) >> 2] = $4_1; - break label$76; - } - $0_1 = $3_1 + $5_1 | 0; - HEAP32[($1_1 + 4 | 0) >> 2] = $0_1 | 3 | 0; - $0_1 = $0_1 + $1_1 | 0; - HEAP32[($0_1 + 4 | 0) >> 2] = HEAP32[($0_1 + 4 | 0) >> 2] | 0 | 1 | 0; - } - return $1_1 + 8 | 0 | 0; - } - return $0_1 + 8 | 0 | 0; - } - - function $7($0_1, $1_1) { - $0_1 = $0_1 | 0; - $1_1 = $1_1 | 0; - return FUNCTION_TABLE[HEAP32[((HEAP32[($1_1 + 24 | 0) >> 2] | 0) + 12 | 0) >> 2] | 0 | 0](HEAP32[($1_1 + 20 | 0) >> 2] | 0, 1049684, 5) | 0 | 0; - } - - function $8($0_1) { - $0_1 = $0_1 | 0; - var $1_1 = 0; - $1_1 = HEAP32[$0_1 >> 2] | 0; - if ($1_1) { - $9(HEAP32[($0_1 + 4 | 0) >> 2] | 0 | 0, $1_1 | 0) - } - } - - function $9($0_1, $1_1) { - $0_1 = $0_1 | 0; - $1_1 = $1_1 | 0; - var $2_1 = 0, $3_1 = 0; - label$1 : { - $2_1 = HEAP32[($0_1 - 4 | 0) >> 2] | 0; - $3_1 = $2_1 & -8 | 0; - $2_1 = $2_1 & 3 | 0; - if ($3_1 >>> 0 >= (($2_1 ? 4 : 8) + $1_1 | 0) >>> 0) { - if ($3_1 >>> 0 > ($1_1 + 39 | 0) >>> 0 ? $2_1 : 0) { - break label$1 - } - $14($0_1 | 0); - return; - } - $15(1049557 | 0, 1049604 | 0); - wasm2js_trap(); - } - $15(1049620 | 0, 1049668 | 0); - wasm2js_trap(); - } - - function $10($0_1, $1_1, $2_1) { - $0_1 = $0_1 | 0; - $1_1 = $1_1 | 0; - $2_1 = $2_1 | 0; - var $3_1 = 0; - $3_1 = HEAP32[($0_1 + 8 | 0) >> 2] | 0; - if ($2_1 >>> 0 > ((HEAP32[$0_1 >> 2] | 0) - $3_1 | 0) >>> 0) { - $3($0_1 | 0, $3_1 | 0, $2_1 | 0); - $3_1 = HEAP32[($0_1 + 8 | 0) >> 2] | 0; - } - $57((HEAP32[($0_1 + 4 | 0) >> 2] | 0) + $3_1 | 0 | 0, $1_1 | 0, $2_1 | 0) | 0; - HEAP32[($0_1 + 8 | 0) >> 2] = $2_1 + $3_1 | 0; - return 0 | 0; - } - - function $11($0_1, $1_1) { - $0_1 = $0_1 | 0; - $1_1 = $1_1 | 0; - var $2_1 = 0, $3_1 = 0, $5_1 = 0, $4_1 = 0, $31_1 = 0, $6_1 = 0, $7_1 = 0, $87 = 0, $78 = 0; - $3_1 = global$0 - 16 | 0; - global$0 = $3_1; - label$1 : { - label$2 : { - label$3 : { - if ($1_1 >>> 0 >= 128 >>> 0) { - HEAP32[($3_1 + 12 | 0) >> 2] = 0; - if ($1_1 >>> 0 < 2048 >>> 0) { - break label$3 - } - if ($1_1 >>> 0 < 65536 >>> 0) { - HEAP8[($3_1 + 14 | 0) >> 0] = $1_1 & 63 | 0 | 128 | 0; - HEAP8[($3_1 + 12 | 0) >> 0] = $1_1 >>> 12 | 0 | 224 | 0; - HEAP8[($3_1 + 13 | 0) >> 0] = ($1_1 >>> 6 | 0) & 63 | 0 | 128 | 0; - $31_1 = 3; - break label$2; - } - HEAP8[($3_1 + 15 | 0) >> 0] = $1_1 & 63 | 0 | 128 | 0; - HEAP8[($3_1 + 12 | 0) >> 0] = $1_1 >>> 18 | 0 | 240 | 0; - HEAP8[($3_1 + 14 | 0) >> 0] = ($1_1 >>> 6 | 0) & 63 | 0 | 128 | 0; - HEAP8[($3_1 + 13 | 0) >> 0] = ($1_1 >>> 12 | 0) & 63 | 0 | 128 | 0; - $31_1 = 4; - break label$2; - } - $6_1 = HEAP32[($0_1 + 8 | 0) >> 2] | 0; - $4_1 = HEAP32[$0_1 >> 2] | 0; - if (($6_1 | 0) == ($4_1 | 0)) { - $2_1 = global$0 - 32 | 0; - global$0 = $2_1; - if (($4_1 | 0) == (-1 | 0)) { - $0(0 | 0); - wasm2js_trap(); - } - $5_1 = $4_1 << 1 | 0; - $7_1 = $4_1 + 1 | 0; - $5_1 = $5_1 >>> 0 > $7_1 >>> 0 ? $5_1 : $7_1; - $5_1 = $5_1 >>> 0 <= 8 >>> 0 ? 8 : $5_1; - if (($5_1 | 0) < (0 | 0)) { - $0(0 | 0); - wasm2js_trap(); - } - $78 = $2_1; - if ($4_1) { - HEAP32[($2_1 + 28 | 0) >> 2] = $4_1; - HEAP32[($2_1 + 20 | 0) >> 2] = HEAP32[($0_1 + 4 | 0) >> 2] | 0; - $87 = 1; - } else { - $87 = 0 - } - HEAP32[($78 + 24 | 0) >> 2] = $87; - $4($2_1 + 8 | 0 | 0, $5_1 | 0, $2_1 + 20 | 0 | 0); - if ((HEAP32[($2_1 + 8 | 0) >> 2] | 0 | 0) == (1 | 0)) { - HEAP32[($2_1 + 16 | 0) >> 2] | 0; - $0(HEAP32[($2_1 + 12 | 0) >> 2] | 0 | 0); - wasm2js_trap(); - } - $4_1 = HEAP32[($2_1 + 12 | 0) >> 2] | 0; - HEAP32[$0_1 >> 2] = $5_1; - HEAP32[($0_1 + 4 | 0) >> 2] = $4_1; - global$0 = $2_1 + 32 | 0; - } - HEAP32[($0_1 + 8 | 0) >> 2] = $6_1 + 1 | 0; - HEAP8[((HEAP32[($0_1 + 4 | 0) >> 2] | 0) + $6_1 | 0) >> 0] = $1_1; - break label$1; - } - HEAP8[($3_1 + 13 | 0) >> 0] = $1_1 & 63 | 0 | 128 | 0; - HEAP8[($3_1 + 12 | 0) >> 0] = $1_1 >>> 6 | 0 | 192 | 0; - $31_1 = 2; - } - $1_1 = $31_1; - $2_1 = HEAP32[($0_1 + 8 | 0) >> 2] | 0; - if ($1_1 >>> 0 > ((HEAP32[$0_1 >> 2] | 0) - $2_1 | 0) >>> 0) { - $3($0_1 | 0, $2_1 | 0, $1_1 | 0); - $2_1 = HEAP32[($0_1 + 8 | 0) >> 2] | 0; - } - $57((HEAP32[($0_1 + 4 | 0) >> 2] | 0) + $2_1 | 0 | 0, $3_1 + 12 | 0 | 0, $1_1 | 0) | 0; - HEAP32[($0_1 + 8 | 0) >> 2] = $1_1 + $2_1 | 0; - } - global$0 = $3_1 + 16 | 0; - return 0 | 0; - } - - function $12($0_1, $1_1) { - $0_1 = $0_1 | 0; - $1_1 = $1_1 | 0; - return $13($0_1 | 0, 1048576 | 0, $1_1 | 0) | 0 | 0; - } - - function $13($0_1, $1_1, $2_1) { - $0_1 = $0_1 | 0; - $1_1 = $1_1 | 0; - $2_1 = $2_1 | 0; - var $3_1 = 0, $4_1 = 0, $5_1 = 0, $6_1 = 0, $7_1 = 0, $8_1 = 0, $10_1 = 0, $9_1 = 0, $12_1 = 0, $190 = 0, $11_1 = 0; - $3_1 = global$0 - 48 | 0; - global$0 = $3_1; - HEAP8[($3_1 + 44 | 0) >> 0] = 3; - HEAP32[($3_1 + 28 | 0) >> 2] = 32; - HEAP32[($3_1 + 40 | 0) >> 2] = 0; - HEAP32[($3_1 + 36 | 0) >> 2] = $1_1; - HEAP32[($3_1 + 32 | 0) >> 2] = $0_1; - HEAP32[($3_1 + 20 | 0) >> 2] = 0; - HEAP32[($3_1 + 12 | 0) >> 2] = 0; - label$1 : { - label$2 : { - label$3 : { - label$4 : { - $10_1 = HEAP32[($2_1 + 16 | 0) >> 2] | 0; - if (!$10_1) { - $0_1 = HEAP32[($2_1 + 12 | 0) >> 2] | 0; - if (!$0_1) { - break label$4 - } - $1_1 = HEAP32[($2_1 + 8 | 0) >> 2] | 0; - $5_1 = $0_1 << 3 | 0; - $7_1 = (($0_1 - 1 | 0) & 536870911 | 0) + 1 | 0; - $0_1 = HEAP32[$2_1 >> 2] | 0; - label$6 : while (1) { - $4_1 = HEAP32[($0_1 + 4 | 0) >> 2] | 0; - if ($4_1) { - if (FUNCTION_TABLE[HEAP32[((HEAP32[($3_1 + 36 | 0) >> 2] | 0) + 12 | 0) >> 2] | 0 | 0](HEAP32[($3_1 + 32 | 0) >> 2] | 0, HEAP32[$0_1 >> 2] | 0, $4_1) | 0) { - break label$3 - } - } - if (FUNCTION_TABLE[HEAP32[($1_1 + 4 | 0) >> 2] | 0 | 0](HEAP32[$1_1 >> 2] | 0, $3_1 + 12 | 0) | 0) { - break label$3 - } - $1_1 = $1_1 + 8 | 0; - $0_1 = $0_1 + 8 | 0; - $5_1 = $5_1 - 8 | 0; - if ($5_1) { - continue label$6 - } - break label$6; - }; - break label$4; - } - $0_1 = HEAP32[($2_1 + 20 | 0) >> 2] | 0; - if (!$0_1) { - break label$4 - } - $11_1 = $0_1 << 5 | 0; - $7_1 = (($0_1 - 1 | 0) & 134217727 | 0) + 1 | 0; - $8_1 = HEAP32[($2_1 + 8 | 0) >> 2] | 0; - $0_1 = HEAP32[$2_1 >> 2] | 0; - label$8 : while (1) { - $1_1 = HEAP32[($0_1 + 4 | 0) >> 2] | 0; - if ($1_1) { - if (FUNCTION_TABLE[HEAP32[((HEAP32[($3_1 + 36 | 0) >> 2] | 0) + 12 | 0) >> 2] | 0 | 0](HEAP32[($3_1 + 32 | 0) >> 2] | 0, HEAP32[$0_1 >> 2] | 0, $1_1) | 0) { - break label$3 - } - } - $1_1 = $5_1 + $10_1 | 0; - HEAP32[($3_1 + 28 | 0) >> 2] = HEAP32[($1_1 + 16 | 0) >> 2] | 0; - HEAP8[($3_1 + 44 | 0) >> 0] = HEAPU8[($1_1 + 28 | 0) >> 0] | 0; - HEAP32[($3_1 + 40 | 0) >> 2] = HEAP32[($1_1 + 24 | 0) >> 2] | 0; - $4_1 = HEAP32[($1_1 + 12 | 0) >> 2] | 0; - $9_1 = 0; - $6_1 = 0; - label$10 : { - label$11 : { - switch ((HEAP32[($1_1 + 8 | 0) >> 2] | 0) - 1 | 0 | 0) { - case 0: - $12_1 = ($4_1 << 3 | 0) + $8_1 | 0; - if (HEAP32[($12_1 + 4 | 0) >> 2] | 0) { - break label$10 - } - $4_1 = HEAP32[$12_1 >> 2] | 0; - break; - case 1: - break label$10; - default: - break label$11; - }; - } - $6_1 = 1; - } - HEAP32[($3_1 + 16 | 0) >> 2] = $4_1; - HEAP32[($3_1 + 12 | 0) >> 2] = $6_1; - $4_1 = HEAP32[($1_1 + 4 | 0) >> 2] | 0; - label$13 : { - label$14 : { - switch ((HEAP32[$1_1 >> 2] | 0) - 1 | 0 | 0) { - case 0: - $6_1 = ($4_1 << 3 | 0) + $8_1 | 0; - if (HEAP32[($6_1 + 4 | 0) >> 2] | 0) { - break label$13 - } - $4_1 = HEAP32[$6_1 >> 2] | 0; - break; - case 1: - break label$13; - default: - break label$14; - }; - } - $9_1 = 1; - } - HEAP32[($3_1 + 24 | 0) >> 2] = $4_1; - HEAP32[($3_1 + 20 | 0) >> 2] = $9_1; - $1_1 = $8_1 + ((HEAP32[($1_1 + 20 | 0) >> 2] | 0) << 3 | 0) | 0; - if (FUNCTION_TABLE[HEAP32[($1_1 + 4 | 0) >> 2] | 0 | 0](HEAP32[$1_1 >> 2] | 0, $3_1 + 12 | 0) | 0) { - break label$3 - } - $0_1 = $0_1 + 8 | 0; - $5_1 = $5_1 + 32 | 0; - if (($11_1 | 0) != ($5_1 | 0)) { - continue label$8 - } - break label$8; - }; - } - if ($7_1 >>> 0 >= (HEAP32[($2_1 + 4 | 0) >> 2] | 0) >>> 0) { - break label$2 - } - $0_1 = (HEAP32[$2_1 >> 2] | 0) + ($7_1 << 3 | 0) | 0; - if (!(FUNCTION_TABLE[HEAP32[((HEAP32[($3_1 + 36 | 0) >> 2] | 0) + 12 | 0) >> 2] | 0 | 0](HEAP32[($3_1 + 32 | 0) >> 2] | 0, HEAP32[$0_1 >> 2] | 0, HEAP32[($0_1 + 4 | 0) >> 2] | 0) | 0)) { - break label$2 - } - } - $190 = 1; - break label$1; - } - $190 = 0; - } - global$0 = $3_1 + 48 | 0; - return $190 | 0; - } - - function $14($0_1) { - $0_1 = $0_1 | 0; - var $1_1 = 0, $2_1 = 0, $3_1 = 0, $4_1 = 0, $5_1 = 0, $167 = 0, $59 = 0; - $1_1 = $0_1 - 8 | 0; - $3_1 = HEAP32[($0_1 - 4 | 0) >> 2] | 0; - $0_1 = $3_1 & -8 | 0; - $2_1 = $1_1 + $0_1 | 0; - label$1 : { - label$2 : { - if ($3_1 & 1 | 0) { - break label$2 - } - if (!($3_1 & 2 | 0)) { - break label$1 - } - $3_1 = HEAP32[$1_1 >> 2] | 0; - $0_1 = $3_1 + $0_1 | 0; - $1_1 = $1_1 - $3_1 | 0; - if (($1_1 | 0) == (HEAP32[1050140 >> 2] | 0 | 0)) { - if (((HEAP32[($2_1 + 4 | 0) >> 2] | 0) & 3 | 0 | 0) != (3 | 0)) { - break label$2 - } - HEAP32[1050132 >> 2] = $0_1; - HEAP32[($2_1 + 4 | 0) >> 2] = (HEAP32[($2_1 + 4 | 0) >> 2] | 0) & -2 | 0; - HEAP32[($1_1 + 4 | 0) >> 2] = $0_1 | 1 | 0; - HEAP32[$2_1 >> 2] = $0_1; - return; - } - $16($1_1 | 0, $3_1 | 0); - } - label$4 : { - label$5 : { - label$6 : { - label$7 : { - label$8 : { - $3_1 = HEAP32[($2_1 + 4 | 0) >> 2] | 0; - if (!($3_1 & 2 | 0)) { - if (($2_1 | 0) == (HEAP32[1050144 >> 2] | 0 | 0)) { - break label$7 - } - if (($2_1 | 0) == (HEAP32[1050140 >> 2] | 0 | 0)) { - break label$6 - } - $59 = $2_1; - $2_1 = $3_1 & -8 | 0; - $16($59 | 0, $2_1 | 0); - $0_1 = $0_1 + $2_1 | 0; - HEAP32[($1_1 + 4 | 0) >> 2] = $0_1 | 1 | 0; - HEAP32[($0_1 + $1_1 | 0) >> 2] = $0_1; - if (($1_1 | 0) != (HEAP32[1050140 >> 2] | 0 | 0)) { - break label$8 - } - HEAP32[1050132 >> 2] = $0_1; - return; - } - HEAP32[($2_1 + 4 | 0) >> 2] = $3_1 & -2 | 0; - HEAP32[($1_1 + 4 | 0) >> 2] = $0_1 | 1 | 0; - HEAP32[($0_1 + $1_1 | 0) >> 2] = $0_1; - } - if ($0_1 >>> 0 < 256 >>> 0) { - break label$5 - } - $54($1_1 | 0, $0_1 | 0); - $1_1 = 0; - $0_1 = (HEAP32[1050164 >> 2] | 0) - 1 | 0; - HEAP32[1050164 >> 2] = $0_1; - if ($0_1) { - break label$1 - } - $0_1 = HEAP32[1049852 >> 2] | 0; - if ($0_1) { - label$11 : while (1) { - $1_1 = $1_1 + 1 | 0; - $0_1 = HEAP32[($0_1 + 8 | 0) >> 2] | 0; - if ($0_1) { - continue label$11 - } - break label$11; - } - } - HEAP32[1050164 >> 2] = $1_1 >>> 0 <= 4095 >>> 0 ? 4095 : $1_1; - return; - } - HEAP32[1050144 >> 2] = $1_1; - $0_1 = (HEAP32[1050136 >> 2] | 0) + $0_1 | 0; - HEAP32[1050136 >> 2] = $0_1; - HEAP32[($1_1 + 4 | 0) >> 2] = $0_1 | 1 | 0; - if ((HEAP32[1050140 >> 2] | 0 | 0) == ($1_1 | 0)) { - HEAP32[1050132 >> 2] = 0; - HEAP32[1050140 >> 2] = 0; - } - $3_1 = HEAP32[1050156 >> 2] | 0; - if ($0_1 >>> 0 <= $3_1 >>> 0) { - break label$1 - } - $2_1 = HEAP32[1050144 >> 2] | 0; - if (!$2_1) { - break label$1 - } - $0_1 = 0; - $4_1 = HEAP32[1050136 >> 2] | 0; - if ($4_1 >>> 0 < 41 >>> 0) { - break label$4 - } - $1_1 = 1049844; - label$13 : while (1) { - $5_1 = HEAP32[$1_1 >> 2] | 0; - if ($2_1 >>> 0 >= $5_1 >>> 0) { - if ($2_1 >>> 0 < ($5_1 + (HEAP32[($1_1 + 4 | 0) >> 2] | 0) | 0) >>> 0) { - break label$4 - } - } - $1_1 = HEAP32[($1_1 + 8 | 0) >> 2] | 0; - continue label$13; - }; - } - HEAP32[1050140 >> 2] = $1_1; - $0_1 = (HEAP32[1050132 >> 2] | 0) + $0_1 | 0; - HEAP32[1050132 >> 2] = $0_1; - HEAP32[($1_1 + 4 | 0) >> 2] = $0_1 | 1 | 0; - HEAP32[($0_1 + $1_1 | 0) >> 2] = $0_1; - return; - } - $2_1 = ($0_1 & 248 | 0) + 1049860 | 0; - label$15 : { - $3_1 = HEAP32[1050124 >> 2] | 0; - $0_1 = 1 << ($0_1 >>> 3 | 0) | 0; - if (!($3_1 & $0_1 | 0)) { - HEAP32[1050124 >> 2] = $0_1 | $3_1 | 0; - $167 = $2_1; - break label$15; - } - $167 = HEAP32[($2_1 + 8 | 0) >> 2] | 0; - } - $0_1 = $167; - HEAP32[($2_1 + 8 | 0) >> 2] = $1_1; - HEAP32[($0_1 + 12 | 0) >> 2] = $1_1; - HEAP32[($1_1 + 12 | 0) >> 2] = $2_1; - HEAP32[($1_1 + 8 | 0) >> 2] = $0_1; - return; - } - $1_1 = HEAP32[1049852 >> 2] | 0; - if ($1_1) { - label$18 : while (1) { - $0_1 = $0_1 + 1 | 0; - $1_1 = HEAP32[($1_1 + 8 | 0) >> 2] | 0; - if ($1_1) { - continue label$18 - } - break label$18; - } - } - HEAP32[1050164 >> 2] = $0_1 >>> 0 <= 4095 >>> 0 ? 4095 : $0_1; - if ($3_1 >>> 0 >= $4_1 >>> 0) { - break label$1 - } - HEAP32[1050156 >> 2] = -1; - } - } - - function $15($0_1, $1_1) { - $0_1 = $0_1 | 0; - $1_1 = $1_1 | 0; - var $2_1 = 0; - $2_1 = global$0 - 32 | 0; - global$0 = $2_1; - HEAP32[($2_1 + 16 | 0) >> 2] = 0; - HEAP32[($2_1 + 4 | 0) >> 2] = 1; - HEAP32[($2_1 + 8 | 0) >> 2] = 4; - HEAP32[($2_1 + 12 | 0) >> 2] = 0; - HEAP32[($2_1 + 28 | 0) >> 2] = 46; - HEAP32[($2_1 + 24 | 0) >> 2] = $0_1; - HEAP32[$2_1 >> 2] = $2_1 + 24 | 0; - $2($2_1 | 0, $1_1 | 0); - wasm2js_trap(); - } - - function $16($0_1, $1_1) { - $0_1 = $0_1 | 0; - $1_1 = $1_1 | 0; - var $2_1 = 0, $3_1 = 0, $4_1 = 0, $5_1 = 0, wasm2js_i32$0 = 0, wasm2js_i32$1 = 0; - $2_1 = HEAP32[($0_1 + 12 | 0) >> 2] | 0; - label$1 : { - label$2 : { - if ($1_1 >>> 0 >= 256 >>> 0) { - $3_1 = HEAP32[($0_1 + 24 | 0) >> 2] | 0; - label$4 : { - label$5 : { - if (($0_1 | 0) == ($2_1 | 0)) { - $2_1 = HEAP32[($0_1 + 20 | 0) >> 2] | 0; - $1_1 = HEAP32[($0_1 + ($2_1 ? 20 : 16) | 0) >> 2] | 0; - if ($1_1) { - break label$5 - } - $2_1 = 0; - break label$4; - } - $1_1 = HEAP32[($0_1 + 8 | 0) >> 2] | 0; - HEAP32[($1_1 + 12 | 0) >> 2] = $2_1; - HEAP32[($2_1 + 8 | 0) >> 2] = $1_1; - break label$4; - } - $4_1 = $2_1 ? $0_1 + 20 | 0 : $0_1 + 16 | 0; - label$7 : while (1) { - $5_1 = $4_1; - $2_1 = $1_1; - $1_1 = HEAP32[($2_1 + 20 | 0) >> 2] | 0; - $4_1 = $1_1 ? $2_1 + 20 | 0 : $2_1 + 16 | 0; - $1_1 = HEAP32[($2_1 + ($1_1 ? 20 : 16) | 0) >> 2] | 0; - if ($1_1) { - continue label$7 - } - break label$7; - }; - HEAP32[$5_1 >> 2] = 0; - } - if (!$3_1) { - break label$1 - } - $1_1 = ((HEAP32[($0_1 + 28 | 0) >> 2] | 0) << 2 | 0) + 1049716 | 0; - if (($0_1 | 0) != (HEAP32[$1_1 >> 2] | 0 | 0)) { - HEAP32[($3_1 + ((HEAP32[($3_1 + 16 | 0) >> 2] | 0 | 0) == ($0_1 | 0) ? 16 : 20) | 0) >> 2] = $2_1; - if (!$2_1) { - break label$1 - } - break label$2; - } - HEAP32[$1_1 >> 2] = $2_1; - if ($2_1) { - break label$2 - } - (wasm2js_i32$0 = 1050128, wasm2js_i32$1 = (HEAP32[1050128 >> 2] | 0) & (__wasm_rotl_i32(-2 | 0, HEAP32[($0_1 + 28 | 0) >> 2] | 0 | 0) | 0) | 0), HEAP32[wasm2js_i32$0 >> 2] = wasm2js_i32$1; - break label$1; - } - $0_1 = HEAP32[($0_1 + 8 | 0) >> 2] | 0; - if (($0_1 | 0) != ($2_1 | 0)) { - HEAP32[($0_1 + 12 | 0) >> 2] = $2_1; - HEAP32[($2_1 + 8 | 0) >> 2] = $0_1; - return; - } - (wasm2js_i32$0 = 1050124, wasm2js_i32$1 = (HEAP32[1050124 >> 2] | 0) & (__wasm_rotl_i32(-2 | 0, $1_1 >>> 3 | 0 | 0) | 0) | 0), HEAP32[wasm2js_i32$0 >> 2] = wasm2js_i32$1; - return; - } - HEAP32[($2_1 + 24 | 0) >> 2] = $3_1; - $1_1 = HEAP32[($0_1 + 16 | 0) >> 2] | 0; - if ($1_1) { - HEAP32[($2_1 + 16 | 0) >> 2] = $1_1; - HEAP32[($1_1 + 24 | 0) >> 2] = $2_1; - } - $0_1 = HEAP32[($0_1 + 20 | 0) >> 2] | 0; - if (!$0_1) { - break label$1 - } - HEAP32[($2_1 + 20 | 0) >> 2] = $0_1; - HEAP32[($0_1 + 24 | 0) >> 2] = $2_1; - } - } - - function $17($0_1, $1_1) { - $0_1 = $0_1 | 0; - $1_1 = $1_1 | 0; - var $2_1 = 0, $3_1 = 0, $99 = 0, $52_1 = 0; - $2_1 = $0_1 + $1_1 | 0; - label$1 : { - label$2 : { - $3_1 = HEAP32[($0_1 + 4 | 0) >> 2] | 0; - if ($3_1 & 1 | 0) { - break label$2 - } - if (!($3_1 & 2 | 0)) { - break label$1 - } - $3_1 = HEAP32[$0_1 >> 2] | 0; - $1_1 = $3_1 + $1_1 | 0; - $0_1 = $0_1 - $3_1 | 0; - if (($0_1 | 0) == (HEAP32[1050140 >> 2] | 0 | 0)) { - if (((HEAP32[($2_1 + 4 | 0) >> 2] | 0) & 3 | 0 | 0) != (3 | 0)) { - break label$2 - } - HEAP32[1050132 >> 2] = $1_1; - HEAP32[($2_1 + 4 | 0) >> 2] = (HEAP32[($2_1 + 4 | 0) >> 2] | 0) & -2 | 0; - HEAP32[($0_1 + 4 | 0) >> 2] = $1_1 | 1 | 0; - HEAP32[$2_1 >> 2] = $1_1; - break label$1; - } - $16($0_1 | 0, $3_1 | 0); - } - label$4 : { - label$5 : { - label$6 : { - $3_1 = HEAP32[($2_1 + 4 | 0) >> 2] | 0; - if (!($3_1 & 2 | 0)) { - if (($2_1 | 0) == (HEAP32[1050144 >> 2] | 0 | 0)) { - break label$5 - } - if (($2_1 | 0) == (HEAP32[1050140 >> 2] | 0 | 0)) { - break label$4 - } - $52_1 = $2_1; - $2_1 = $3_1 & -8 | 0; - $16($52_1 | 0, $2_1 | 0); - $1_1 = $1_1 + $2_1 | 0; - HEAP32[($0_1 + 4 | 0) >> 2] = $1_1 | 1 | 0; - HEAP32[($0_1 + $1_1 | 0) >> 2] = $1_1; - if (($0_1 | 0) != (HEAP32[1050140 >> 2] | 0 | 0)) { - break label$6 - } - HEAP32[1050132 >> 2] = $1_1; - return; - } - HEAP32[($2_1 + 4 | 0) >> 2] = $3_1 & -2 | 0; - HEAP32[($0_1 + 4 | 0) >> 2] = $1_1 | 1 | 0; - HEAP32[($0_1 + $1_1 | 0) >> 2] = $1_1; - } - if ($1_1 >>> 0 >= 256 >>> 0) { - $54($0_1 | 0, $1_1 | 0); - return; - } - $2_1 = ($1_1 & 248 | 0) + 1049860 | 0; - label$9 : { - $3_1 = HEAP32[1050124 >> 2] | 0; - $1_1 = 1 << ($1_1 >>> 3 | 0) | 0; - if (!($3_1 & $1_1 | 0)) { - HEAP32[1050124 >> 2] = $1_1 | $3_1 | 0; - $99 = $2_1; - break label$9; - } - $99 = HEAP32[($2_1 + 8 | 0) >> 2] | 0; - } - $1_1 = $99; - HEAP32[($2_1 + 8 | 0) >> 2] = $0_1; - HEAP32[($1_1 + 12 | 0) >> 2] = $0_1; - HEAP32[($0_1 + 12 | 0) >> 2] = $2_1; - HEAP32[($0_1 + 8 | 0) >> 2] = $1_1; - return; - } - HEAP32[1050144 >> 2] = $0_1; - $1_1 = (HEAP32[1050136 >> 2] | 0) + $1_1 | 0; - HEAP32[1050136 >> 2] = $1_1; - HEAP32[($0_1 + 4 | 0) >> 2] = $1_1 | 1 | 0; - if (($0_1 | 0) != (HEAP32[1050140 >> 2] | 0 | 0)) { - break label$1 - } - HEAP32[1050132 >> 2] = 0; - HEAP32[1050140 >> 2] = 0; - return; - } - HEAP32[1050140 >> 2] = $0_1; - $1_1 = (HEAP32[1050132 >> 2] | 0) + $1_1 | 0; - HEAP32[1050132 >> 2] = $1_1; - HEAP32[($0_1 + 4 | 0) >> 2] = $1_1 | 1 | 0; - HEAP32[($0_1 + $1_1 | 0) >> 2] = $1_1; - } - } - - function $18($0_1) { - $0_1 = $0_1 | 0; - var $1_1 = 0, i64toi32_i32$1 = 0, i64toi32_i32$2 = 0, i64toi32_i32$0 = 0, i64toi32_i32$3 = 0, $15_1 = 0; - $1_1 = global$0 - 48 | 0; - global$0 = $1_1; - HEAP32[$1_1 >> 2] = $0_1; - HEAP32[($1_1 + 4 | 0) >> 2] = 128; - HEAP32[($1_1 + 12 | 0) >> 2] = 2; - HEAP32[($1_1 + 8 | 0) >> 2] = 1049120; - i64toi32_i32$1 = $1_1; - i64toi32_i32$0 = 0; - HEAP32[($1_1 + 20 | 0) >> 2] = 2; - HEAP32[($1_1 + 24 | 0) >> 2] = i64toi32_i32$0; - i64toi32_i32$0 = 0; - i64toi32_i32$2 = $1_1 + 4 | 0; - i64toi32_i32$1 = 1; - i64toi32_i32$3 = 0; - i64toi32_i32$1 = i64toi32_i32$0 | i64toi32_i32$1 | 0; - $15_1 = i64toi32_i32$2 | i64toi32_i32$3 | 0; - i64toi32_i32$2 = $1_1; - HEAP32[($1_1 + 40 | 0) >> 2] = $15_1; - HEAP32[($1_1 + 44 | 0) >> 2] = i64toi32_i32$1; - i64toi32_i32$1 = 0; - i64toi32_i32$0 = $1_1; - i64toi32_i32$2 = 1; - i64toi32_i32$3 = 0; - i64toi32_i32$2 = i64toi32_i32$1 | i64toi32_i32$2 | 0; - i64toi32_i32$0 = $1_1; - HEAP32[($1_1 + 32 | 0) >> 2] = $1_1 | i64toi32_i32$3 | 0; - HEAP32[($1_1 + 36 | 0) >> 2] = i64toi32_i32$2; - HEAP32[($1_1 + 16 | 0) >> 2] = $1_1 + 32 | 0; - $2($1_1 + 8 | 0 | 0, 1048848 | 0); - wasm2js_trap(); - } - - function $19($0_1, $1_1) { - $0_1 = $0_1 | 0; - $1_1 = $1_1 | 0; - var i64toi32_i32$1 = 0; - i64toi32_i32$1 = 0; - return $20(HEAP32[$0_1 >> 2] | 0 | 0, i64toi32_i32$1 | 0, $1_1 | 0) | 0 | 0; - } - - function $20($0_1, $0$hi, $1_1) { - $0_1 = $0_1 | 0; - $0$hi = $0$hi | 0; - $1_1 = $1_1 | 0; - var i64toi32_i32$2 = 0, $2_1 = 0, i64toi32_i32$0 = 0, i64toi32_i32$1 = 0, i64toi32_i32$3 = 0, $7_1 = 0, $3_1 = 0, i64toi32_i32$5 = 0, $4_1 = 0, $7$hi = 0, $5_1 = 0, i64toi32_i32$4 = 0, $6_1 = 0, $20_1 = 0, $22_1 = 0, $23_1 = 0, $24_1 = 0, $25_1 = 0, $26_1 = 0, $27_1 = 0, $28_1 = 0, $29_1 = 0, $30_1 = 0, $31_1 = 0, $32_1 = 0, $21_1 = 0, $25$hi = 0, $8_1 = 0, $9_1 = 0; - $4_1 = global$0 - 48 | 0; - global$0 = $4_1; - $2_1 = 39; - label$1 : { - i64toi32_i32$0 = $0$hi; - i64toi32_i32$2 = $0_1; - i64toi32_i32$1 = 0; - i64toi32_i32$3 = 1e4; - if (i64toi32_i32$0 >>> 0 < i64toi32_i32$1 >>> 0 | ((i64toi32_i32$0 | 0) == (i64toi32_i32$1 | 0) & i64toi32_i32$2 >>> 0 < i64toi32_i32$3 >>> 0 | 0) | 0) { - i64toi32_i32$2 = i64toi32_i32$0; - $7_1 = $0_1; - $7$hi = i64toi32_i32$2; - break label$1; - } - label$3 : while (1) { - $3_1 = ($4_1 + 9 | 0) + $2_1 | 0; - $21_1 = $3_1 - 4 | 0; - i64toi32_i32$2 = $0$hi; - i64toi32_i32$0 = 0; - i64toi32_i32$0 = __wasm_i64_udiv($0_1 | 0, i64toi32_i32$2 | 0, 1e4 | 0, i64toi32_i32$0 | 0) | 0; - i64toi32_i32$2 = i64toi32_i32$HIGH_BITS; - $7_1 = i64toi32_i32$0; - $7$hi = i64toi32_i32$2; - i64toi32_i32$0 = 0; - i64toi32_i32$0 = __wasm_i64_mul($7_1 | 0, i64toi32_i32$2 | 0, 55536 | 0, i64toi32_i32$0 | 0) | 0; - i64toi32_i32$2 = i64toi32_i32$HIGH_BITS; - $25$hi = i64toi32_i32$2; - i64toi32_i32$2 = $0$hi; - i64toi32_i32$2 = $25$hi; - i64toi32_i32$3 = i64toi32_i32$0; - i64toi32_i32$0 = $0$hi; - i64toi32_i32$1 = $0_1; - i64toi32_i32$4 = i64toi32_i32$3 + i64toi32_i32$1 | 0; - i64toi32_i32$5 = i64toi32_i32$2 + i64toi32_i32$0 | 0; - if (i64toi32_i32$4 >>> 0 < i64toi32_i32$1 >>> 0) { - i64toi32_i32$5 = i64toi32_i32$5 + 1 | 0 - } - $5_1 = i64toi32_i32$4; - $6_1 = (($5_1 & 65535 | 0) >>> 0) / (100 >>> 0) | 0; - $20_1 = ($6_1 << 1 | 0) + 1048866 | 0; - $22_1 = $21_1; - $23_1 = HEAPU8[$20_1 >> 0] | 0 | ((HEAPU8[($20_1 + 1 | 0) >> 0] | 0) << 8 | 0) | 0; - HEAP8[$22_1 >> 0] = $23_1; - HEAP8[($22_1 + 1 | 0) >> 0] = $23_1 >>> 8 | 0; - $24_1 = (((Math_imul($6_1, -100) + $5_1 | 0) & 65535 | 0) << 1 | 0) + 1048866 | 0; - $25_1 = $3_1 - 2 | 0; - $26_1 = HEAPU8[$24_1 >> 0] | 0 | ((HEAPU8[($24_1 + 1 | 0) >> 0] | 0) << 8 | 0) | 0; - HEAP8[$25_1 >> 0] = $26_1; - HEAP8[($25_1 + 1 | 0) >> 0] = $26_1 >>> 8 | 0; - $2_1 = $2_1 - 4 | 0; - i64toi32_i32$5 = $0$hi; - i64toi32_i32$2 = $0_1; - i64toi32_i32$3 = 0; - i64toi32_i32$1 = 99999999; - $8_1 = i64toi32_i32$5 >>> 0 > i64toi32_i32$3 >>> 0 | ((i64toi32_i32$5 | 0) == (i64toi32_i32$3 | 0) & i64toi32_i32$2 >>> 0 > i64toi32_i32$1 >>> 0 | 0) | 0; - i64toi32_i32$2 = $7$hi; - $0_1 = $7_1; - $0$hi = i64toi32_i32$2; - if ($8_1) { - continue label$3 - } - break label$3; - }; - } - label$4 : { - i64toi32_i32$2 = $7$hi; - i64toi32_i32$1 = $7_1; - i64toi32_i32$5 = 0; - i64toi32_i32$3 = 99; - if (i64toi32_i32$2 >>> 0 < i64toi32_i32$5 >>> 0 | ((i64toi32_i32$2 | 0) == (i64toi32_i32$5 | 0) & i64toi32_i32$1 >>> 0 <= i64toi32_i32$3 >>> 0 | 0) | 0) { - i64toi32_i32$1 = i64toi32_i32$2; - i64toi32_i32$1 = i64toi32_i32$2; - $3_1 = $7_1; - break label$4; - } - $2_1 = $2_1 - 2 | 0; - i64toi32_i32$1 = $7$hi; - $5_1 = $7_1; - $3_1 = (($7_1 & 65535 | 0) >>> 0) / (100 >>> 0) | 0; - $27_1 = (((Math_imul($3_1, -100) + $7_1 | 0) & 65535 | 0) << 1 | 0) + 1048866 | 0; - $28_1 = $2_1 + ($4_1 + 9 | 0) | 0; - $29_1 = HEAPU8[$27_1 >> 0] | 0 | ((HEAPU8[($27_1 + 1 | 0) >> 0] | 0) << 8 | 0) | 0; - HEAP8[$28_1 >> 0] = $29_1; - HEAP8[($28_1 + 1 | 0) >> 0] = $29_1 >>> 8 | 0; - } - label$6 : { - if ($3_1 >>> 0 >= 10 >>> 0) { - $2_1 = $2_1 - 2 | 0; - $30_1 = ($3_1 << 1 | 0) + 1048866 | 0; - $31_1 = $2_1 + ($4_1 + 9 | 0) | 0; - $32_1 = HEAPU8[$30_1 >> 0] | 0 | ((HEAPU8[($30_1 + 1 | 0) >> 0] | 0) << 8 | 0) | 0; - HEAP8[$31_1 >> 0] = $32_1; - HEAP8[($31_1 + 1 | 0) >> 0] = $32_1 >>> 8 | 0; - break label$6; - } - $2_1 = $2_1 - 1 | 0; - HEAP8[($2_1 + ($4_1 + 9 | 0) | 0) >> 0] = $3_1 | 48 | 0; - } - $9_1 = $21($1_1 | 0, 1 | 0, 0 | 0, ($4_1 + 9 | 0) + $2_1 | 0 | 0, 39 - $2_1 | 0 | 0) | 0; - global$0 = $4_1 + 48 | 0; - return $9_1 | 0; - } - - function $21($0_1, $1_1, $2_1, $3_1, $4_1) { - $0_1 = $0_1 | 0; - $1_1 = $1_1 | 0; - $2_1 = $2_1 | 0; - $3_1 = $3_1 | 0; - $4_1 = $4_1 | 0; - var $5_1 = 0, $6_1 = 0, $7_1 = 0, $8_1 = 0, $9_1 = 0, $10_1 = 0, $11_1 = 0, $12_1 = 0; - $7_1 = HEAP32[($0_1 + 28 | 0) >> 2] | 0; - $5_1 = $7_1 & 1 | 0; - $10_1 = $5_1 ? 43 : 1114112; - $6_1 = $4_1 + $5_1 | 0; - label$1 : { - if (!($7_1 & 4 | 0)) { - $1_1 = 0; - break label$1; - } - label$3 : { - if (!$2_1) { - break label$3 - } - $8_1 = $2_1 & 3 | 0; - if (!$8_1) { - break label$3 - } - $5_1 = $1_1; - label$4 : while (1) { - $9_1 = $9_1 + ((HEAP8[$5_1 >> 0] | 0 | 0) > (-65 | 0)) | 0; - $5_1 = $5_1 + 1 | 0; - $8_1 = $8_1 - 1 | 0; - if ($8_1) { - continue label$4 - } - break label$4; - }; - } - $6_1 = $6_1 + $9_1 | 0; - } - if (!(HEAP32[$0_1 >> 2] | 0)) { - $5_1 = HEAP32[($0_1 + 20 | 0) >> 2] | 0; - $0_1 = HEAP32[($0_1 + 24 | 0) >> 2] | 0; - if ($22($5_1 | 0, $0_1 | 0, $10_1 | 0, $1_1 | 0, $2_1 | 0) | 0) { - return 1 | 0 - } - return FUNCTION_TABLE[HEAP32[($0_1 + 12 | 0) >> 2] | 0 | 0]($5_1, $3_1, $4_1) | 0 | 0; - } - label$7 : { - label$8 : { - label$9 : { - $8_1 = HEAP32[($0_1 + 4 | 0) >> 2] | 0; - if ($6_1 >>> 0 >= $8_1 >>> 0) { - $5_1 = HEAP32[($0_1 + 20 | 0) >> 2] | 0; - $0_1 = HEAP32[($0_1 + 24 | 0) >> 2] | 0; - if (!($22($5_1 | 0, $0_1 | 0, $10_1 | 0, $1_1 | 0, $2_1 | 0) | 0)) { - break label$9 - } - return 1 | 0; - } - if (!($7_1 & 8 | 0)) { - break label$8 - } - $11_1 = HEAP32[($0_1 + 16 | 0) >> 2] | 0; - HEAP32[($0_1 + 16 | 0) >> 2] = 48; - $12_1 = HEAPU8[($0_1 + 32 | 0) >> 0] | 0; - $5_1 = 1; - HEAP8[($0_1 + 32 | 0) >> 0] = 1; - $7_1 = HEAP32[($0_1 + 20 | 0) >> 2] | 0; - $9_1 = HEAP32[($0_1 + 24 | 0) >> 2] | 0; - if ($22($7_1 | 0, $9_1 | 0, $10_1 | 0, $1_1 | 0, $2_1 | 0) | 0) { - break label$7 - } - $5_1 = ($8_1 - $6_1 | 0) + 1 | 0; - label$11 : { - label$12 : while (1) { - $5_1 = $5_1 - 1 | 0; - if (!$5_1) { - break label$11 - } - if (!(FUNCTION_TABLE[HEAP32[($9_1 + 16 | 0) >> 2] | 0 | 0]($7_1, 48) | 0)) { - continue label$12 - } - break label$12; - }; - return 1 | 0; - } - if (FUNCTION_TABLE[HEAP32[($9_1 + 12 | 0) >> 2] | 0 | 0]($7_1, $3_1, $4_1) | 0) { - return 1 | 0 - } - HEAP8[($0_1 + 32 | 0) >> 0] = $12_1; - HEAP32[($0_1 + 16 | 0) >> 2] = $11_1; - return 0 | 0; - } - $5_1 = FUNCTION_TABLE[HEAP32[($0_1 + 12 | 0) >> 2] | 0 | 0]($5_1, $3_1, $4_1) | 0; - break label$7; - } - $6_1 = $8_1 - $6_1 | 0; - label$14 : { - label$15 : { - label$16 : { - $5_1 = HEAPU8[($0_1 + 32 | 0) >> 0] | 0; - switch ($5_1 - 1 | 0 | 0) { - case 1: - break label$15; - case 0: - case 2: - break label$16; - default: - break label$14; - }; - } - $5_1 = $6_1; - $6_1 = 0; - break label$14; - } - $5_1 = $6_1 >>> 1 | 0; - $6_1 = ($6_1 + 1 | 0) >>> 1 | 0; - } - $5_1 = $5_1 + 1 | 0; - $8_1 = HEAP32[($0_1 + 16 | 0) >> 2] | 0; - $7_1 = HEAP32[($0_1 + 24 | 0) >> 2] | 0; - $0_1 = HEAP32[($0_1 + 20 | 0) >> 2] | 0; - label$17 : { - label$18 : while (1) { - $5_1 = $5_1 - 1 | 0; - if (!$5_1) { - break label$17 - } - if (!(FUNCTION_TABLE[HEAP32[($7_1 + 16 | 0) >> 2] | 0 | 0]($0_1, $8_1) | 0)) { - continue label$18 - } - break label$18; - }; - return 1 | 0; - } - $5_1 = 1; - if ($22($0_1 | 0, $7_1 | 0, $10_1 | 0, $1_1 | 0, $2_1 | 0) | 0) { - break label$7 - } - if (FUNCTION_TABLE[HEAP32[($7_1 + 12 | 0) >> 2] | 0 | 0]($0_1, $3_1, $4_1) | 0) { - break label$7 - } - $5_1 = 0; - label$19 : while (1) { - if (($5_1 | 0) == ($6_1 | 0)) { - return 0 | 0 - } - $5_1 = $5_1 + 1 | 0; - if (!(FUNCTION_TABLE[HEAP32[($7_1 + 16 | 0) >> 2] | 0 | 0]($0_1, $8_1) | 0)) { - continue label$19 - } - break label$19; - }; - return ($5_1 - 1 | 0) >>> 0 < $6_1 >>> 0 | 0; - } - return $5_1 | 0; - } - - function $22($0_1, $1_1, $2_1, $3_1, $4_1) { - $0_1 = $0_1 | 0; - $1_1 = $1_1 | 0; - $2_1 = $2_1 | 0; - $3_1 = $3_1 | 0; - $4_1 = $4_1 | 0; - label$1 : { - if (($2_1 | 0) == (1114112 | 0)) { - break label$1 - } - if (!(FUNCTION_TABLE[HEAP32[($1_1 + 16 | 0) >> 2] | 0 | 0]($0_1, $2_1) | 0)) { - break label$1 - } - return 1 | 0; - } - if (!$3_1) { - return 0 | 0 - } - return FUNCTION_TABLE[HEAP32[($1_1 + 12 | 0) >> 2] | 0 | 0]($0_1, $3_1, $4_1) | 0 | 0; - } - - function $23($0_1, $1_1) { - $0_1 = $0_1 | 0; - $1_1 = $1_1 | 0; - var $2_1 = 0, $3_1 = 0, $4_1 = 0, $6_1 = 0, $5_1 = 0, $7_1 = 0, $8_1 = 0, $189 = 0, $9_1 = 0, $118 = 0, $128 = 0, $138 = 0; - $5_1 = ($0_1 + 3 | 0) & -4 | 0; - $3_1 = $0_1 - $5_1 | 0; - $7_1 = $1_1 + $3_1 | 0; - $4_1 = $7_1 & 3 | 0; - $1_1 = 0; - if (($0_1 | 0) != ($5_1 | 0)) { - if ($3_1 >>> 0 <= -4 >>> 0) { - label$3 : while (1) { - $6_1 = $0_1 + $8_1 | 0; - $1_1 = ((($1_1 + ((HEAP8[$6_1 >> 0] | 0 | 0) > (-65 | 0)) | 0) + ((HEAP8[($6_1 + 1 | 0) >> 0] | 0 | 0) > (-65 | 0)) | 0) + ((HEAP8[($6_1 + 2 | 0) >> 0] | 0 | 0) > (-65 | 0)) | 0) + ((HEAP8[($6_1 + 3 | 0) >> 0] | 0 | 0) > (-65 | 0)) | 0; - $8_1 = $8_1 + 4 | 0; - if ($8_1) { - continue label$3 - } - break label$3; - } - } - label$4 : while (1) { - $1_1 = $1_1 + ((HEAP8[$0_1 >> 0] | 0 | 0) > (-65 | 0)) | 0; - $0_1 = $0_1 + 1 | 0; - $3_1 = $3_1 + 1 | 0; - if ($3_1) { - continue label$4 - } - break label$4; - }; - } - label$5 : { - if (!$4_1) { - break label$5 - } - $0_1 = $5_1 + ($7_1 & -4 | 0) | 0; - $2_1 = (HEAP8[$0_1 >> 0] | 0 | 0) > (-65 | 0); - if (($4_1 | 0) == (1 | 0)) { - break label$5 - } - $2_1 = $2_1 + ((HEAP8[($0_1 + 1 | 0) >> 0] | 0 | 0) > (-65 | 0)) | 0; - if (($4_1 | 0) == (2 | 0)) { - break label$5 - } - $2_1 = $2_1 + ((HEAP8[($0_1 + 2 | 0) >> 0] | 0 | 0) > (-65 | 0)) | 0; - } - $3_1 = $7_1 >>> 2 | 0; - $4_1 = $1_1 + $2_1 | 0; - label$6 : { - label$7 : while (1) { - $2_1 = $5_1; - if (!$3_1) { - break label$6 - } - $6_1 = $3_1 >>> 0 >= 192 >>> 0 ? 192 : $3_1; - $7_1 = $6_1 & 3 | 0; - $5_1 = $6_1 << 2 | 0; - $1_1 = 0; - if ($3_1 >>> 0 >= 4 >>> 0) { - $8_1 = $2_1 + ($5_1 & 1008 | 0) | 0; - $0_1 = $2_1; - label$9 : while (1) { - $9_1 = HEAP32[$0_1 >> 2] | 0; - $118 = $1_1 + ((($9_1 ^ -1 | 0) >>> 7 | 0 | ($9_1 >>> 6 | 0) | 0) & 16843009 | 0) | 0; - $1_1 = HEAP32[($0_1 + 4 | 0) >> 2] | 0; - $128 = $118 + ((($1_1 ^ -1 | 0) >>> 7 | 0 | ($1_1 >>> 6 | 0) | 0) & 16843009 | 0) | 0; - $1_1 = HEAP32[($0_1 + 8 | 0) >> 2] | 0; - $138 = $128 + ((($1_1 ^ -1 | 0) >>> 7 | 0 | ($1_1 >>> 6 | 0) | 0) & 16843009 | 0) | 0; - $1_1 = HEAP32[($0_1 + 12 | 0) >> 2] | 0; - $1_1 = $138 + ((($1_1 ^ -1 | 0) >>> 7 | 0 | ($1_1 >>> 6 | 0) | 0) & 16843009 | 0) | 0; - $0_1 = $0_1 + 16 | 0; - if (($0_1 | 0) != ($8_1 | 0)) { - continue label$9 - } - break label$9; - }; - } - $3_1 = $3_1 - $6_1 | 0; - $5_1 = $2_1 + $5_1 | 0; - $4_1 = (Math_imul((($1_1 >>> 8 | 0) & 16711935 | 0) + ($1_1 & 16711935 | 0) | 0, 65537) >>> 16 | 0) + $4_1 | 0; - if (!$7_1) { - continue label$7 - } - break label$7; - }; - label$10 : { - $0_1 = $2_1 + (($6_1 & 252 | 0) << 2 | 0) | 0; - $1_1 = HEAP32[$0_1 >> 2] | 0; - $1_1 = (($1_1 ^ -1 | 0) >>> 7 | 0 | ($1_1 >>> 6 | 0) | 0) & 16843009 | 0; - $189 = $1_1; - if (($7_1 | 0) == (1 | 0)) { - break label$10 - } - $2_1 = HEAP32[($0_1 + 4 | 0) >> 2] | 0; - $1_1 = $1_1 + ((($2_1 ^ -1 | 0) >>> 7 | 0 | ($2_1 >>> 6 | 0) | 0) & 16843009 | 0) | 0; - $189 = $1_1; - if (($7_1 | 0) == (2 | 0)) { - break label$10 - } - $0_1 = HEAP32[($0_1 + 8 | 0) >> 2] | 0; - $189 = $1_1 + ((($0_1 ^ -1 | 0) >>> 7 | 0 | ($0_1 >>> 6 | 0) | 0) & 16843009 | 0) | 0; - } - $0_1 = $189; - $4_1 = (Math_imul((($0_1 >>> 8 | 0) & 459007 | 0) + ($0_1 & 16711935 | 0) | 0, 65537) >>> 16 | 0) + $4_1 | 0; - } - return $4_1 | 0; - } - - function $24($0_1, $1_1) { - $0_1 = $0_1 | 0; - $1_1 = $1_1 | 0; - var $2_1 = 0, $3_1 = 0, $5_1 = 0, $4_1 = 0, $6_1 = 0, $7_1 = 0, $45_1 = 0, $8_1 = 0, $87 = 0, $9_1 = 0, $75 = 0, $76 = 0; - $3_1 = HEAP32[($0_1 + 4 | 0) >> 2] | 0; - $4_1 = HEAP32[$0_1 >> 2] | 0; - label$1 : { - $0_1 = !((HEAP32[($1_1 + 8 | 0) >> 2] | 0) & 1 | 0); - $8_1 = HEAP32[$1_1 >> 2] | 0; - if (!($0_1 & !$8_1 | 0)) { - label$3 : { - if ($0_1) { - break label$3 - } - $9_1 = $3_1 + $4_1 | 0; - label$4 : { - $7_1 = HEAP32[($1_1 + 12 | 0) >> 2] | 0; - if (!$7_1) { - $2_1 = $4_1; - break label$4; - } - $2_1 = $4_1; - label$6 : while (1) { - $0_1 = $2_1; - if (($0_1 | 0) == ($9_1 | 0)) { - break label$3 - } - label$7 : { - $2_1 = HEAP8[$0_1 >> 0] | 0; - $45_1 = $0_1 + 1 | 0; - if (($2_1 | 0) >= (0 | 0)) { - break label$7 - } - $45_1 = $0_1 + 2 | 0; - if ($2_1 >>> 0 < -32 >>> 0) { - break label$7 - } - $45_1 = $0_1 + 3 | 0; - if ($2_1 >>> 0 < -16 >>> 0) { - break label$7 - } - $45_1 = $0_1 + 4 | 0; - } - $2_1 = $45_1; - $6_1 = ($2_1 - $0_1 | 0) + $6_1 | 0; - $5_1 = $5_1 + 1 | 0; - if (($7_1 | 0) != ($5_1 | 0)) { - continue label$6 - } - break label$6; - }; - } - if (($2_1 | 0) == ($9_1 | 0)) { - break label$3 - } - HEAP8[$2_1 >> 0] | 0; - $75 = $6_1; - $76 = $3_1; - label$8 : { - label$9 : { - if (!$6_1) { - break label$9 - } - if ($3_1 >>> 0 > $6_1 >>> 0) { - if ((HEAP8[($4_1 + $6_1 | 0) >> 0] | 0 | 0) > (-65 | 0)) { - break label$9 - } - $87 = 0; - break label$8; - } - if (($3_1 | 0) == ($6_1 | 0)) { - break label$9 - } - $87 = 0; - break label$8; - } - $87 = $4_1; - } - $0_1 = $87; - $3_1 = $0_1 ? $75 : $76; - $4_1 = $0_1 ? $0_1 : $4_1; - } - if (!$8_1) { - break label$1 - } - $8_1 = HEAP32[($1_1 + 4 | 0) >> 2] | 0; - label$11 : { - if ($3_1 >>> 0 >= 16 >>> 0) { - $2_1 = $23($4_1 | 0, $3_1 | 0) | 0; - break label$11; - } - if (!$3_1) { - $2_1 = 0; - break label$11; - } - $6_1 = $3_1 & 3 | 0; - label$14 : { - if ($3_1 >>> 0 < 4 >>> 0) { - $2_1 = 0; - $7_1 = 0; - break label$14; - } - $2_1 = 0; - $0_1 = $4_1; - $7_1 = $3_1 & 12 | 0; - $5_1 = $7_1; - label$16 : while (1) { - $2_1 = ((($2_1 + ((HEAP8[$0_1 >> 0] | 0 | 0) > (-65 | 0)) | 0) + ((HEAP8[($0_1 + 1 | 0) >> 0] | 0 | 0) > (-65 | 0)) | 0) + ((HEAP8[($0_1 + 2 | 0) >> 0] | 0 | 0) > (-65 | 0)) | 0) + ((HEAP8[($0_1 + 3 | 0) >> 0] | 0 | 0) > (-65 | 0)) | 0; - $0_1 = $0_1 + 4 | 0; - $5_1 = $5_1 - 4 | 0; - if ($5_1) { - continue label$16 - } - break label$16; - }; - } - if (!$6_1) { - break label$11 - } - $0_1 = $4_1 + $7_1 | 0; - label$17 : while (1) { - $2_1 = $2_1 + ((HEAP8[$0_1 >> 0] | 0 | 0) > (-65 | 0)) | 0; - $0_1 = $0_1 + 1 | 0; - $6_1 = $6_1 - 1 | 0; - if ($6_1) { - continue label$17 - } - break label$17; - }; - } - label$18 : { - if ($2_1 >>> 0 < $8_1 >>> 0) { - $5_1 = $8_1 - $2_1 | 0; - $0_1 = 0; - label$20 : { - label$21 : { - switch ((HEAPU8[($1_1 + 32 | 0) >> 0] | 0) - 1 | 0 | 0) { - case 0: - $0_1 = $5_1; - $5_1 = 0; - break label$20; - case 1: - break label$21; - default: - break label$20; - }; - } - $0_1 = $5_1 >>> 1 | 0; - $5_1 = ($5_1 + 1 | 0) >>> 1 | 0; - } - $0_1 = $0_1 + 1 | 0; - $2_1 = HEAP32[($1_1 + 16 | 0) >> 2] | 0; - $7_1 = HEAP32[($1_1 + 24 | 0) >> 2] | 0; - $1_1 = HEAP32[($1_1 + 20 | 0) >> 2] | 0; - label$23 : while (1) { - $0_1 = $0_1 - 1 | 0; - if (!$0_1) { - break label$18 - } - if (!(FUNCTION_TABLE[HEAP32[($7_1 + 16 | 0) >> 2] | 0 | 0]($1_1, $2_1) | 0)) { - continue label$23 - } - break label$23; - }; - return 1 | 0; - } - break label$1; - } - if (FUNCTION_TABLE[HEAP32[($7_1 + 12 | 0) >> 2] | 0 | 0]($1_1, $4_1, $3_1) | 0) { - return 1 | 0 - } - $0_1 = 0; - label$25 : while (1) { - if (($0_1 | 0) == ($5_1 | 0)) { - return 0 | 0 - } - $0_1 = $0_1 + 1 | 0; - if (!(FUNCTION_TABLE[HEAP32[($7_1 + 16 | 0) >> 2] | 0 | 0]($1_1, $2_1) | 0)) { - continue label$25 - } - break label$25; - }; - return ($0_1 - 1 | 0) >>> 0 < $5_1 >>> 0 | 0; - } - return FUNCTION_TABLE[HEAP32[((HEAP32[($1_1 + 24 | 0) >> 2] | 0) + 12 | 0) >> 2] | 0 | 0](HEAP32[($1_1 + 20 | 0) >> 2] | 0, $4_1, $3_1) | 0 | 0; - } - return FUNCTION_TABLE[HEAP32[((HEAP32[($1_1 + 24 | 0) >> 2] | 0) + 12 | 0) >> 2] | 0 | 0](HEAP32[($1_1 + 20 | 0) >> 2] | 0, $4_1, $3_1) | 0 | 0; - } - - function $25($0_1, $1_1) { - $0_1 = $0_1 | 0; - $1_1 = $1_1 | 0; - return FUNCTION_TABLE[HEAP32[((HEAP32[($0_1 + 4 | 0) >> 2] | 0) + 12 | 0) >> 2] | 0 | 0](HEAP32[$0_1 >> 2] | 0, $1_1) | 0 | 0; - } - - function $26($0_1, $1_1, $2_1) { - $0_1 = $0_1 | 0; - $1_1 = $1_1 | 0; - $2_1 = $2_1 | 0; - var $3_1 = 0, $4_1 = 0, $5_1 = 0, $6_1 = 0, $7_1 = 0, $9_1 = 0, $8_1 = 0, $10_1 = 0, $11_1 = 0, $12_1 = 0, $140 = 0, $13_1 = 0, $69 = 0, $14_1 = 0; - $13_1 = $1_1 - 1 | 0; - $10_1 = HEAP32[($0_1 + 4 | 0) >> 2] | 0; - $11_1 = HEAP32[$0_1 >> 2] | 0; - $12_1 = HEAP32[($0_1 + 8 | 0) >> 2] | 0; - label$1 : { - label$2 : while (1) { - if ($6_1) { - break label$1 - } - label$3 : { - label$4 : { - if ($2_1 >>> 0 < $4_1 >>> 0) { - break label$4 - } - label$5 : while (1) { - $6_1 = $1_1 + $4_1 | 0; - label$6 : { - label$7 : { - label$8 : { - $7_1 = $2_1 - $4_1 | 0; - if ($7_1 >>> 0 <= 7 >>> 0) { - if (($2_1 | 0) != ($4_1 | 0)) { - break label$8 - } - $4_1 = $2_1; - break label$4; - } - label$10 : { - $5_1 = ($6_1 + 3 | 0) & -4 | 0; - $3_1 = $5_1 - $6_1 | 0; - if ($3_1) { - $0_1 = 0; - label$12 : while (1) { - if ((HEAPU8[($0_1 + $6_1 | 0) >> 0] | 0 | 0) == (10 | 0)) { - break label$6 - } - $0_1 = $0_1 + 1 | 0; - if (($3_1 | 0) != ($0_1 | 0)) { - continue label$12 - } - break label$12; - }; - $0_1 = $7_1 - 8 | 0; - if ($3_1 >>> 0 <= $0_1 >>> 0) { - break label$10 - } - break label$7; - } - $0_1 = $7_1 - 8 | 0; - } - label$13 : while (1) { - $9_1 = HEAP32[$5_1 >> 2] | 0; - $69 = 16843008 - ($9_1 ^ 168430090 | 0) | 0 | $9_1 | 0; - $9_1 = HEAP32[($5_1 + 4 | 0) >> 2] | 0; - if ((($69 & (16843008 - ($9_1 ^ 168430090 | 0) | 0 | $9_1 | 0) | 0) & -2139062144 | 0 | 0) != (-2139062144 | 0)) { - break label$7 - } - $5_1 = $5_1 + 8 | 0; - $3_1 = $3_1 + 8 | 0; - if ($3_1 >>> 0 <= $0_1 >>> 0) { - continue label$13 - } - break label$13; - }; - break label$7; - } - $0_1 = 0; - label$14 : while (1) { - if ((HEAPU8[($0_1 + $6_1 | 0) >> 0] | 0 | 0) == (10 | 0)) { - break label$6 - } - $0_1 = $0_1 + 1 | 0; - if (($7_1 | 0) != ($0_1 | 0)) { - continue label$14 - } - break label$14; - }; - $4_1 = $2_1; - break label$4; - } - if (($3_1 | 0) == ($7_1 | 0)) { - $4_1 = $2_1; - break label$4; - } - $5_1 = $3_1 + $6_1 | 0; - $7_1 = ($2_1 - $3_1 | 0) - $4_1 | 0; - $0_1 = 0; - label$16 : { - label$17 : while (1) { - if ((HEAPU8[($0_1 + $5_1 | 0) >> 0] | 0 | 0) == (10 | 0)) { - break label$16 - } - $0_1 = $0_1 + 1 | 0; - if (($7_1 | 0) != ($0_1 | 0)) { - continue label$17 - } - break label$17; - }; - $4_1 = $2_1; - break label$4; - } - $0_1 = $0_1 + $3_1 | 0; - } - $3_1 = $0_1 + $4_1 | 0; - $4_1 = $3_1 + 1 | 0; - label$18 : { - if ($2_1 >>> 0 <= $3_1 >>> 0) { - break label$18 - } - if ((HEAPU8[($0_1 + $6_1 | 0) >> 0] | 0 | 0) != (10 | 0)) { - break label$18 - } - $6_1 = 0; - $3_1 = $4_1; - $140 = $3_1; - break label$3; - } - if ($2_1 >>> 0 >= $4_1 >>> 0) { - continue label$5 - } - break label$5; - }; - } - if (($2_1 | 0) == ($8_1 | 0)) { - break label$1 - } - $6_1 = 1; - $3_1 = $8_1; - $140 = $2_1; - } - $0_1 = $140; - label$19 : { - if (HEAPU8[$12_1 >> 0] | 0) { - if (FUNCTION_TABLE[HEAP32[($10_1 + 12 | 0) >> 2] | 0 | 0]($11_1, 1048816, 4) | 0) { - break label$19 - } - } - $5_1 = 0; - if (($0_1 | 0) != ($8_1 | 0)) { - $5_1 = (HEAPU8[($0_1 + $13_1 | 0) >> 0] | 0 | 0) == (10 | 0) - } - $0_1 = $0_1 - $8_1 | 0; - $7_1 = $1_1 + $8_1 | 0; - HEAP8[$12_1 >> 0] = $5_1; - $8_1 = $3_1; - if (!(FUNCTION_TABLE[HEAP32[($10_1 + 12 | 0) >> 2] | 0 | 0]($11_1, $7_1, $0_1) | 0)) { - continue label$2 - } - } - break label$2; - }; - $14_1 = 1; - } - return $14_1 | 0; - } - - function $27($0_1, $1_1) { - $0_1 = $0_1 | 0; - $1_1 = $1_1 | 0; - var $2_1 = 0, $3_1 = 0; - $2_1 = HEAP32[($0_1 + 4 | 0) >> 2] | 0; - $3_1 = HEAP32[$0_1 >> 2] | 0; - label$1 : { - $0_1 = HEAP32[($0_1 + 8 | 0) >> 2] | 0; - if (!(HEAPU8[$0_1 >> 0] | 0)) { - break label$1 - } - if (!(FUNCTION_TABLE[HEAP32[($2_1 + 12 | 0) >> 2] | 0 | 0]($3_1, 1048816, 4) | 0)) { - break label$1 - } - return 1 | 0; - } - HEAP8[$0_1 >> 0] = ($1_1 | 0) == (10 | 0); - return FUNCTION_TABLE[HEAP32[($2_1 + 16 | 0) >> 2] | 0 | 0]($3_1, $1_1) | 0 | 0; - } - - function $28($0_1, $1_1) { - $0_1 = $0_1 | 0; - $1_1 = $1_1 | 0; - return $13($0_1 | 0, 1048792 | 0, $1_1 | 0) | 0 | 0; - } - - function $29($0_1, $1_1) { - $0_1 = $0_1 | 0; - $1_1 = $1_1 | 0; - var $2_1 = 0, $3_1 = 0, $4_1 = 0; - $3_1 = HEAP32[($1_1 + 8 | 0) >> 2] | 0; - label$1 : { - label$2 : { - label$3 : { - $2_1 = HEAP32[$1_1 >> 2] | 0; - if (!$2_1) { - $4_1 = 1; - if ($3_1) { - break label$3 - } - $2_1 = 0; - $1_1 = 0; - break label$1; - } - $2_1 = (HEAP32[($1_1 + 4 | 0) >> 2] | 0) - $2_1 | 0; - if ($3_1) { - break label$2 - } - $4_1 = 1; - $1_1 = $2_1; - break label$1; - } - $2_1 = (HEAP32[($1_1 + 12 | 0) >> 2] | 0) - $3_1 | 0; - $1_1 = $2_1; - break label$1; - } - $1_1 = ((HEAP32[($1_1 + 12 | 0) >> 2] | 0) - $3_1 | 0) + $2_1 | 0; - $4_1 = $1_1 >>> 0 >= $2_1 >>> 0; - $2_1 = $1_1 >>> 0 < $2_1 >>> 0 ? -1 : $1_1; - } - HEAP32[($0_1 + 8 | 0) >> 2] = $1_1; - HEAP32[($0_1 + 4 | 0) >> 2] = $4_1; - HEAP32[$0_1 >> 2] = $2_1; - } - - function $30($0_1, $1_1) { - $0_1 = $0_1 | 0; - $1_1 = $1_1 | 0; - var $2_1 = 0, $3_1 = 0, $4_1 = 0; - $2_1 = global$0 - 16 | 0; - global$0 = $2_1; - label$1 : { - if (($1_1 | 0) < (0 | 0)) { - break label$1 - } - label$2 : { - if (!$1_1) { - $1_1 = 0; - $3_1 = 1; - break label$2; - } - $4_1 = 1; - $31($2_1 + 8 | 0 | 0, 1 | 0, $1_1 | 0); - $3_1 = HEAP32[($2_1 + 8 | 0) >> 2] | 0; - if (!$3_1) { - break label$1 - } - } - HEAP32[($0_1 + 4 | 0) >> 2] = $3_1; - HEAP32[$0_1 >> 2] = $1_1; - global$0 = $2_1 + 16 | 0; - return; - } - $0($4_1 | 0); - wasm2js_trap(); - } - - function $31($0_1, $1_1, $2_1) { - $0_1 = $0_1 | 0; - $1_1 = $1_1 | 0; - $2_1 = $2_1 | 0; - if ($2_1) { - $1_1 = $34($2_1 | 0) | 0 - } - HEAP32[($0_1 + 4 | 0) >> 2] = $2_1; - HEAP32[$0_1 >> 2] = $1_1; - } - - function $32($0_1, $1_1) { - $0_1 = $0_1 | 0; - $1_1 = $1_1 | 0; - var $2_1 = 0, $3_1 = 0; - $2_1 = global$0 - 16 | 0; - global$0 = $2_1; - label$1 : { - $3_1 = HEAP32[($0_1 + 8 | 0) >> 2] | 0; - if (((HEAP32[$0_1 >> 2] | 0) - $3_1 | 0) >>> 0 >= $1_1 >>> 0) { - break label$1 - } - $33($2_1 + 8 | 0 | 0, $0_1 | 0, $3_1 | 0, $1_1 | 0, 1 | 0, 1 | 0); - $0_1 = HEAP32[($2_1 + 8 | 0) >> 2] | 0; - if (($0_1 | 0) == (-2147483647 | 0)) { - break label$1 - } - HEAP32[($2_1 + 12 | 0) >> 2] | 0; - $0($0_1 | 0); - wasm2js_trap(); - } - global$0 = $2_1 + 16 | 0; - } - - function $33($0_1, $1_1, $2_1, $3_1, $4_1, $5_1) { - $0_1 = $0_1 | 0; - $1_1 = $1_1 | 0; - $2_1 = $2_1 | 0; - $3_1 = $3_1 | 0; - $4_1 = $4_1 | 0; - $5_1 = $5_1 | 0; - var $6_1 = 0, i64toi32_i32$0 = 0, $7_1 = 0, i64toi32_i32$1 = 0, $8_1 = 0, $9_1 = 0, i64toi32_i32$4 = 0, $10_1 = 0, $95 = 0, i64toi32_i32$3 = 0, $23_1 = 0, $72 = 0, $28$hi = 0, $49$hi = 0, $11_1 = 0, $11$hi = 0, i64toi32_i32$2 = 0, $60 = 0; - $6_1 = global$0 - 32 | 0; - global$0 = $6_1; - label$1 : { - $3_1 = $2_1 + $3_1 | 0; - if ($2_1 >>> 0 > $3_1 >>> 0) { - $2_1 = 0; - break label$1; - } - $2_1 = 0; - i64toi32_i32$0 = 0; - $28$hi = i64toi32_i32$0; - $7_1 = ($5_1 | 0) == (1 | 0) ? 8 : 4; - $8_1 = HEAP32[$1_1 >> 2] | 0; - $9_1 = $8_1 << 1 | 0; - $3_1 = $3_1 >>> 0 < $9_1 >>> 0 ? $9_1 : $3_1; - $9_1 = $3_1 >>> 0 < $7_1 >>> 0 ? $7_1 : $3_1; - i64toi32_i32$0 = 0; - $49$hi = i64toi32_i32$0; - i64toi32_i32$0 = $28$hi; - i64toi32_i32$1 = $49$hi; - i64toi32_i32$1 = __wasm_i64_mul((($4_1 + $5_1 | 0) - 1 | 0) & (0 - $4_1 | 0) | 0 | 0, i64toi32_i32$0 | 0, $9_1 | 0, i64toi32_i32$1 | 0) | 0; - i64toi32_i32$0 = i64toi32_i32$HIGH_BITS; - $11_1 = i64toi32_i32$1; - $11$hi = i64toi32_i32$0; - i64toi32_i32$2 = i64toi32_i32$1; - i64toi32_i32$1 = 0; - i64toi32_i32$3 = 32; - i64toi32_i32$4 = i64toi32_i32$3 & 31 | 0; - if (32 >>> 0 <= (i64toi32_i32$3 & 63 | 0) >>> 0) { - i64toi32_i32$1 = 0; - $23_1 = i64toi32_i32$0 >>> i64toi32_i32$4 | 0; - } else { - i64toi32_i32$1 = i64toi32_i32$0 >>> i64toi32_i32$4 | 0; - $23_1 = (((1 << i64toi32_i32$4 | 0) - 1 | 0) & i64toi32_i32$0 | 0) << (32 - i64toi32_i32$4 | 0) | 0 | (i64toi32_i32$2 >>> i64toi32_i32$4 | 0) | 0; - } - if ($23_1) { - break label$1 - } - i64toi32_i32$1 = $11$hi; - $7_1 = $11_1; - if ($7_1 >>> 0 > (-2147483648 - $4_1 | 0) >>> 0) { - break label$1 - } - $60 = $6_1; - if ($8_1) { - HEAP32[($6_1 + 28 | 0) >> 2] = Math_imul($5_1, $8_1); - HEAP32[($6_1 + 20 | 0) >> 2] = HEAP32[($1_1 + 4 | 0) >> 2] | 0; - $72 = $4_1; - } else { - $72 = 0 - } - HEAP32[($60 + 24 | 0) >> 2] = $72; - $8_1 = $6_1 + 8 | 0; - $2_1 = global$0 - 16 | 0; - global$0 = $2_1; - label$5 : { - $5_1 = $6_1 + 20 | 0; - if (HEAP32[($5_1 + 4 | 0) >> 2] | 0) { - $10_1 = HEAP32[($5_1 + 8 | 0) >> 2] | 0; - if (!$10_1) { - $31($2_1 + 8 | 0 | 0, $4_1 | 0, $7_1 | 0); - $5_1 = HEAP32[($2_1 + 8 | 0) >> 2] | 0; - $95 = HEAP32[($2_1 + 12 | 0) >> 2] | 0; - break label$5; - } - $5_1 = $5(HEAP32[$5_1 >> 2] | 0 | 0, $10_1 | 0, $7_1 | 0) | 0; - $95 = $7_1; - break label$5; - } - $31($2_1 | 0, $4_1 | 0, $7_1 | 0); - $5_1 = HEAP32[$2_1 >> 2] | 0; - $95 = HEAP32[($2_1 + 4 | 0) >> 2] | 0; - } - $10_1 = $95; - HEAP32[($8_1 + 4 | 0) >> 2] = $5_1 ? $5_1 : $4_1; - HEAP32[$8_1 >> 2] = !$5_1; - HEAP32[($8_1 + 8 | 0) >> 2] = $5_1 ? $10_1 : $7_1; - global$0 = $2_1 + 16 | 0; - if (!(HEAP32[($6_1 + 8 | 0) >> 2] | 0)) { - $2_1 = HEAP32[($6_1 + 12 | 0) >> 2] | 0; - HEAP32[$1_1 >> 2] = $9_1; - HEAP32[($1_1 + 4 | 0) >> 2] = $2_1; - $2_1 = -2147483647; - break label$1; - } - $3_1 = HEAP32[($6_1 + 16 | 0) >> 2] | 0; - $2_1 = HEAP32[($6_1 + 12 | 0) >> 2] | 0; - } - HEAP32[($0_1 + 4 | 0) >> 2] = $3_1; - HEAP32[$0_1 >> 2] = $2_1; - global$0 = $6_1 + 32 | 0; - } - - function $34($0_1) { - $0_1 = $0_1 | 0; - HEAPU8[1049704 >> 0] | 0; - return $6($0_1 | 0) | 0 | 0; - } - - function $35($0_1, $1_1) { - $0_1 = $0_1 | 0; - $1_1 = $1_1 | 0; - var $2_1 = 0, $3_1 = 0, $4_1 = 0, i64toi32_i32$0 = 0, i64toi32_i32$1 = 0, $6_1 = 0, $9_1 = 0, $5_1 = 0, $7_1 = 0, $8_1 = 0, $10_1 = 0, $73 = 0, $76 = 0; - $2_1 = global$0 + -64 | 0; - global$0 = $2_1; - $3_1 = HEAP32[($0_1 + 4 | 0) >> 2] | 0; - $4_1 = HEAP32[$0_1 >> 2] | 0; - $0_1 = FUNCTION_TABLE[HEAP32[((HEAP32[($1_1 + 24 | 0) >> 2] | 0) + 12 | 0) >> 2] | 0 | 0](HEAP32[($1_1 + 20 | 0) >> 2] | 0, 1048772, 1) | 0; - label$1 : while (1) { - $6_1 = $8_1; - label$2 : { - label$3 : { - if ($3_1) { - $8_1 = 1; - $10_1 = $0_1 & 1 | 0; - $0_1 = 1; - if ($10_1) { - break label$2 - } - $9_1 = HEAP32[($1_1 + 28 | 0) >> 2] | 0; - if (!($9_1 & 4 | 0)) { - if (!($6_1 & 1 | 0)) { - break label$3 - } - if (!(FUNCTION_TABLE[HEAP32[((HEAP32[($1_1 + 24 | 0) >> 2] | 0) + 12 | 0) >> 2] | 0 | 0](HEAP32[($1_1 + 20 | 0) >> 2] | 0, 1048820, 2) | 0)) { - break label$3 - } - break label$2; - } - $5_1 = HEAP32[($1_1 + 24 | 0) >> 2] | 0; - $7_1 = HEAP32[($1_1 + 20 | 0) >> 2] | 0; - if (!($6_1 & 1 | 0)) { - if (FUNCTION_TABLE[HEAP32[($5_1 + 12 | 0) >> 2] | 0 | 0]($7_1, 1048824, 1) | 0) { - break label$2 - } - } - HEAP8[($2_1 + 27 | 0) >> 0] = 1; - HEAP32[($2_1 + 16 | 0) >> 2] = $5_1; - HEAP32[($2_1 + 12 | 0) >> 2] = $7_1; - HEAP32[($2_1 + 56 | 0) >> 2] = $9_1; - HEAP32[($2_1 + 52 | 0) >> 2] = 1048792; - HEAP8[($2_1 + 60 | 0) >> 0] = HEAPU8[($1_1 + 32 | 0) >> 0] | 0; - HEAP32[($2_1 + 44 | 0) >> 2] = HEAP32[($1_1 + 16 | 0) >> 2] | 0; - i64toi32_i32$0 = HEAP32[($1_1 + 8 | 0) >> 2] | 0; - i64toi32_i32$1 = HEAP32[($1_1 + 12 | 0) >> 2] | 0; - $73 = i64toi32_i32$0; - i64toi32_i32$0 = $2_1; - HEAP32[($2_1 + 36 | 0) >> 2] = $73; - HEAP32[($2_1 + 40 | 0) >> 2] = i64toi32_i32$1; - i64toi32_i32$1 = HEAP32[$1_1 >> 2] | 0; - i64toi32_i32$0 = HEAP32[($1_1 + 4 | 0) >> 2] | 0; - $76 = i64toi32_i32$1; - i64toi32_i32$1 = $2_1; - HEAP32[($2_1 + 28 | 0) >> 2] = $76; - HEAP32[($2_1 + 32 | 0) >> 2] = i64toi32_i32$0; - HEAP32[($2_1 + 20 | 0) >> 2] = $2_1 + 27 | 0; - HEAP32[($2_1 + 48 | 0) >> 2] = $2_1 + 12 | 0; - if (!($36($4_1 | 0, $2_1 + 28 | 0 | 0) | 0)) { - $0_1 = FUNCTION_TABLE[HEAP32[((HEAP32[($2_1 + 52 | 0) >> 2] | 0) + 12 | 0) >> 2] | 0 | 0](HEAP32[($2_1 + 48 | 0) >> 2] | 0, 1048822, 2) | 0; - break label$2; - } - break label$2; - } - $3_1 = 1; - if (!($0_1 & 1 | 0)) { - $3_1 = FUNCTION_TABLE[HEAP32[((HEAP32[($1_1 + 24 | 0) >> 2] | 0) + 12 | 0) >> 2] | 0 | 0](HEAP32[($1_1 + 20 | 0) >> 2] | 0, 1048825, 1) | 0 - } - global$0 = $2_1 - -64 | 0; - return $3_1 | 0; - } - $0_1 = $36($4_1 | 0, $1_1 | 0) | 0; - } - $4_1 = $4_1 + 1 | 0; - $3_1 = $3_1 - 1 | 0; - continue label$1; - }; - } - - function $36($0_1, $1_1) { - $0_1 = $0_1 | 0; - $1_1 = $1_1 | 0; - var $2_1 = 0, $3_1 = 0, $5_1 = 0, $6_1 = 0, $4_1 = 0, $22_1 = 0, i64toi32_i32$1 = 0; - $4_1 = global$0 - 128 | 0; - global$0 = $4_1; - label$1 : { - label$2 : { - label$3 : { - $2_1 = HEAP32[($1_1 + 28 | 0) >> 2] | 0; - if (!($2_1 & 16 | 0)) { - if ($2_1 & 32 | 0) { - break label$3 - } - i64toi32_i32$1 = 0; - $22_1 = $20(HEAPU8[$0_1 >> 0] | 0 | 0, i64toi32_i32$1 | 0, $1_1 | 0) | 0; - break label$1; - } - $0_1 = HEAPU8[$0_1 >> 0] | 0; - $2_1 = 127; - label$5 : while (1) { - $3_1 = $2_1; - $5_1 = $4_1 + $2_1 | 0; - $2_1 = $0_1 & 15 | 0; - HEAP8[$5_1 >> 0] = $2_1 >>> 0 < 10 >>> 0 ? $2_1 | 48 | 0 : $2_1 + 87 | 0; - $2_1 = $3_1 - 1 | 0; - $6_1 = $0_1 & 255 | 0; - $0_1 = $6_1 >>> 4 | 0; - if ($6_1 >>> 0 >= 16 >>> 0) { - continue label$5 - } - break label$7; - }; - break label$2; - } - $0_1 = HEAPU8[$0_1 >> 0] | 0; - $2_1 = 127; - label$6 : while (1) { - $3_1 = $2_1; - $5_1 = $4_1 + $2_1 | 0; - $2_1 = $0_1 & 15 | 0; - HEAP8[$5_1 >> 0] = $2_1 >>> 0 < 10 >>> 0 ? $2_1 | 48 | 0 : $2_1 + 55 | 0; - $2_1 = $3_1 - 1 | 0; - $6_1 = $0_1 & 255 | 0; - $0_1 = $6_1 >>> 4 | 0; - if ($6_1 >>> 0 >= 16 >>> 0) { - continue label$6 - } - break label$6; - }; - if ($3_1 >>> 0 >= 129 >>> 0) { - $18($3_1 | 0); - wasm2js_trap(); - } - $22_1 = $21($1_1 | 0, 1048864 | 0, 2 | 0, $5_1 | 0, 128 - $3_1 | 0 | 0) | 0; - break label$1; - } - if ($3_1 >>> 0 >= 129 >>> 0) { - $18($3_1 | 0); - wasm2js_trap(); - } - $22_1 = $21($1_1 | 0, 1048864 | 0, 2 | 0, $5_1 | 0, 128 - $3_1 | 0 | 0) | 0; - } - global$0 = $4_1 + 128 | 0; - return $22_1 | 0; - } - - function $37($0_1, $1_1, $2_1) { - $0_1 = $0_1 | 0; - $1_1 = $1_1 | 0; - $2_1 = $2_1 | 0; - if ($0_1) { - $9($1_1 | 0, Math_imul($0_1, $2_1) | 0) - } - } - - function $38($0_1, $1_1) { - $0_1 = $0_1 | 0; - $1_1 = $1_1 | 0; - var $2_1 = 0; - $2_1 = $34($0_1 + 20 | 0 | 0) | 0; - HEAP32[($2_1 + 16 | 0) >> 2] = $0_1; - HEAP32[($2_1 + 12 | 0) >> 2] = $1_1; - HEAP32[($2_1 + 4 | 0) >> 2] = 0; - HEAP32[$2_1 >> 2] = $2_1; - return $2_1 | 0; - } - - function $39($0_1, $1_1, $2_1) { - $0_1 = $0_1 | 0; - $1_1 = $1_1 | 0; - $2_1 = $2_1 | 0; - var $8_1 = 0; - $0_1 = $38($2_1 | 0, $0_1 | 0) | 0; - $8_1 = $1_1; - $1_1 = HEAP32[($0_1 + 16 | 0) >> 2] | 0; - $57($0_1 + 20 | 0 | 0, $8_1 | 0, ($1_1 >>> 0 < $2_1 >>> 0 ? $1_1 : $2_1) | 0) | 0; - return $0_1 | 0; - } - - function $40($0_1) { - $0_1 = $0_1 | 0; - var $2_1 = 0, $1_1 = 0, $3_1 = 0, $4_1 = 0, $5_1 = 0, $6_1 = 0, $7_1 = 0, $8_1 = 0, $9_1 = 0, $10_1 = 0, $67 = 0, $11_1 = 0, $12_1 = 0, $123 = 0, $204 = 0; - label$1 : { - label$2 : { - label$3 : { - label$4 : { - label$5 : { - $2_1 = HEAP32[($0_1 + 4 | 0) >> 2] | 0; - switch ($2_1 | 0) { - case 1: - break label$3; - case 0: - break label$5; - default: - break label$4; - }; - break label$3; - } - $3_1 = $0_1 + 20 | 0; - $10_1 = HEAP32[1049700 >> 2] | 0; - $4_1 = $10_1 << 2 | 0; - $11_1 = (HEAP32[($0_1 + 16 | 0) >> 2] | 0) + 20 | 0; - $2_1 = HEAP32[1049696 >> 2] | 0; - $1_1 = $2_1; - label$6 : while (1) { - if (!$4_1) { - break label$1 - } - if ((HEAP32[$1_1 >> 2] | 0 | 0) == ($3_1 | 0)) { - break label$2 - } - $4_1 = $4_1 - 4 | 0; - $6_1 = $6_1 + 1 | 0; - $1_1 = $1_1 + 4 | 0; - continue label$6; - }; - } - HEAP32[($0_1 + 4 | 0) >> 2] = $2_1 - 1 | 0; - } - $9($0_1 | 0, 20 | 0); - return; - } - label$7 : { - label$8 : { - label$9 : { - $7_1 = ($10_1 + ($6_1 ^ -1 | 0) | 0) << 2 | 0; - $2_1 = $2_1 + ($6_1 << 2 | 0) | 0; - $1_1 = $2_1 + 4 | 0; - if ($7_1 >>> 0 > ($2_1 - $1_1 | 0) >>> 0) { - $8_1 = $1_1 + $7_1 | 0; - $3_1 = $2_1 + $7_1 | 0; - $67 = $2_1; - if ($7_1 >>> 0 < 16 >>> 0) { - break label$8 - } - $5_1 = $3_1 & -4 | 0; - $6_1 = $3_1 & 3 | 0; - $12_1 = 0 - $6_1 | 0; - if ($6_1) { - $4_1 = $8_1 - 1 | 0; - label$12 : while (1) { - $3_1 = $3_1 - 1 | 0; - HEAP8[$3_1 >> 0] = HEAPU8[$4_1 >> 0] | 0; - $4_1 = $4_1 - 1 | 0; - if ($3_1 >>> 0 > $5_1 >>> 0) { - continue label$12 - } - break label$12; - }; - } - $7_1 = $7_1 - $6_1 | 0; - $9_1 = $7_1 & -4 | 0; - $3_1 = $5_1 - $9_1 | 0; - $8_1 = $12_1 + $8_1 | 0; - if ($8_1 & 3 | 0) { - if (($9_1 | 0) <= (0 | 0)) { - break label$9 - } - $2_1 = $8_1 << 3 | 0; - $6_1 = $2_1 & 24 | 0; - $4_1 = $8_1 & -4 | 0; - $1_1 = $4_1 - 4 | 0; - $2_1 = (0 - $2_1 | 0) & 24 | 0; - $4_1 = HEAP32[$4_1 >> 2] | 0; - label$14 : while (1) { - $5_1 = $5_1 - 4 | 0; - $123 = $4_1 << $2_1 | 0; - $4_1 = HEAP32[$1_1 >> 2] | 0; - HEAP32[$5_1 >> 2] = $123 | ($4_1 >>> $6_1 | 0) | 0; - $1_1 = $1_1 - 4 | 0; - if ($3_1 >>> 0 < $5_1 >>> 0) { - continue label$14 - } - break label$14; - }; - break label$9; - } - if (($9_1 | 0) <= (0 | 0)) { - break label$9 - } - $1_1 = ($1_1 + $7_1 | 0) - 4 | 0; - label$15 : while (1) { - $5_1 = $5_1 - 4 | 0; - HEAP32[$5_1 >> 2] = HEAP32[$1_1 >> 2] | 0; - $1_1 = $1_1 - 4 | 0; - if ($3_1 >>> 0 < $5_1 >>> 0) { - continue label$15 - } - break label$15; - }; - break label$9; - } - label$16 : { - if ($7_1 >>> 0 < 16 >>> 0) { - $3_1 = $2_1; - break label$16; - } - $6_1 = (0 - $2_1 | 0) & 3 | 0; - $5_1 = $2_1 + $6_1 | 0; - if ($6_1) { - $3_1 = $2_1; - $4_1 = $1_1; - label$19 : while (1) { - HEAP8[$3_1 >> 0] = HEAPU8[$4_1 >> 0] | 0; - $4_1 = $4_1 + 1 | 0; - $3_1 = $3_1 + 1 | 0; - if ($3_1 >>> 0 < $5_1 >>> 0) { - continue label$19 - } - break label$19; - }; - } - $8_1 = $7_1 - $6_1 | 0; - $9_1 = $8_1 & -4 | 0; - $3_1 = $5_1 + $9_1 | 0; - label$20 : { - $2_1 = $1_1 + $6_1 | 0; - if ($2_1 & 3 | 0) { - if (($9_1 | 0) <= (0 | 0)) { - break label$20 - } - $6_1 = $2_1 << 3 | 0; - $7_1 = $6_1 & 24 | 0; - $4_1 = $2_1 & -4 | 0; - $1_1 = $4_1 + 4 | 0; - $6_1 = (0 - $6_1 | 0) & 24 | 0; - $4_1 = HEAP32[$4_1 >> 2] | 0; - label$22 : while (1) { - $204 = $4_1 >>> $7_1 | 0; - $4_1 = HEAP32[$1_1 >> 2] | 0; - HEAP32[$5_1 >> 2] = $204 | ($4_1 << $6_1 | 0) | 0; - $1_1 = $1_1 + 4 | 0; - $5_1 = $5_1 + 4 | 0; - if ($5_1 >>> 0 < $3_1 >>> 0) { - continue label$22 - } - break label$22; - }; - break label$20; - } - if (($9_1 | 0) <= (0 | 0)) { - break label$20 - } - $1_1 = $2_1; - label$23 : while (1) { - HEAP32[$5_1 >> 2] = HEAP32[$1_1 >> 2] | 0; - $1_1 = $1_1 + 4 | 0; - $5_1 = $5_1 + 4 | 0; - if ($5_1 >>> 0 < $3_1 >>> 0) { - continue label$23 - } - break label$23; - }; - } - $7_1 = $8_1 & 3 | 0; - $1_1 = $2_1 + $9_1 | 0; - } - if (!$7_1) { - break label$7 - } - $2_1 = $3_1 + $7_1 | 0; - label$24 : while (1) { - HEAP8[$3_1 >> 0] = HEAPU8[$1_1 >> 0] | 0; - $1_1 = $1_1 + 1 | 0; - $3_1 = $3_1 + 1 | 0; - if ($3_1 >>> 0 < $2_1 >>> 0) { - continue label$24 - } - break label$24; - }; - break label$7; - } - $2_1 = $7_1 & 3 | 0; - if (!$2_1) { - break label$7 - } - $8_1 = $8_1 - $9_1 | 0; - $67 = $3_1 - $2_1 | 0; - } - $2_1 = $67; - $1_1 = $8_1 - 1 | 0; - label$25 : while (1) { - $3_1 = $3_1 - 1 | 0; - HEAP8[$3_1 >> 0] = HEAPU8[$1_1 >> 0] | 0; - $1_1 = $1_1 - 1 | 0; - if ($2_1 >>> 0 < $3_1 >>> 0) { - continue label$25 - } - break label$25; - }; - } - HEAP32[1049700 >> 2] = $10_1 - 1 | 0; - } - $9($0_1 | 0, $11_1 | 0); - } - - function $41($0_1, $1_1) { - $0_1 = $0_1 | 0; - $1_1 = $1_1 | 0; - var i64toi32_i32$1 = 0, i64toi32_i32$2 = 0, i64toi32_i32$0 = 0, $2_1 = 0, i64toi32_i32$3 = 0, $3_1 = 0, $27_1 = 0; - $2_1 = $1_1 - 20 | 0; - HEAP32[($2_1 + 4 | 0) >> 2] = (HEAP32[($2_1 + 4 | 0) >> 2] | 0) + 1 | 0; - $3_1 = HEAP32[($2_1 + 16 | 0) >> 2] | 0; - if ($3_1 >>> 0 <= 3 >>> 0) { - $0_1 = global$0 - 48 | 0; - global$0 = $0_1; - HEAP32[$0_1 >> 2] = 4; - HEAP32[($0_1 + 4 | 0) >> 2] = $3_1; - HEAP32[($0_1 + 12 | 0) >> 2] = 2; - HEAP32[($0_1 + 8 | 0) >> 2] = 1049152; - i64toi32_i32$1 = $0_1; - i64toi32_i32$0 = 0; - HEAP32[($0_1 + 20 | 0) >> 2] = 2; - HEAP32[($0_1 + 24 | 0) >> 2] = i64toi32_i32$0; - i64toi32_i32$0 = 0; - i64toi32_i32$2 = $0_1 + 4 | 0; - i64toi32_i32$1 = 1; - i64toi32_i32$3 = 0; - i64toi32_i32$1 = i64toi32_i32$0 | i64toi32_i32$1 | 0; - $27_1 = i64toi32_i32$2 | i64toi32_i32$3 | 0; - i64toi32_i32$2 = $0_1; - HEAP32[($0_1 + 40 | 0) >> 2] = $27_1; - HEAP32[($0_1 + 44 | 0) >> 2] = i64toi32_i32$1; - i64toi32_i32$1 = 0; - i64toi32_i32$0 = $0_1; - i64toi32_i32$2 = 1; - i64toi32_i32$3 = 0; - i64toi32_i32$2 = i64toi32_i32$1 | i64toi32_i32$2 | 0; - i64toi32_i32$0 = $0_1; - HEAP32[($0_1 + 32 | 0) >> 2] = $0_1 | i64toi32_i32$3 | 0; - HEAP32[($0_1 + 36 | 0) >> 2] = i64toi32_i32$2; - HEAP32[($0_1 + 16 | 0) >> 2] = $0_1 + 32 | 0; - $2($0_1 + 8 | 0 | 0, 1049412 | 0); - wasm2js_trap(); - } - $1_1 = (HEAPU8[$1_1 >> 0] | 0 | ((HEAPU8[($1_1 + 1 | 0) >> 0] | 0) << 8 | 0) | 0 | ((HEAPU8[($1_1 + 2 | 0) >> 0] | 0) << 16 | 0 | ((HEAPU8[($1_1 + 3 | 0) >> 0] | 0) << 24 | 0) | 0) | 0) - 20 | 0; - HEAP32[($1_1 + 4 | 0) >> 2] = (HEAP32[($1_1 + 4 | 0) >> 2] | 0) + 1 | 0; - HEAP32[($0_1 + 4 | 0) >> 2] = $1_1; - HEAP32[$0_1 >> 2] = $2_1; - } - - function $42($0_1, $1_1) { - $0_1 = $0_1 | 0; - $1_1 = $1_1 | 0; - var $2_1 = 0; - $2_1 = HEAP32[($0_1 + 4 | 0) >> 2] | 0; - if ($2_1 >>> 0 >= 2 >>> 0) { - HEAP32[($0_1 + 4 | 0) >> 2] = $2_1 - 1 | 0 - } - $0_1 = HEAP32[($1_1 + 4 | 0) >> 2] | 0; - if ($0_1 >>> 0 >= 2 >>> 0) { - HEAP32[($1_1 + 4 | 0) >> 2] = $0_1 - 1 | 0 - } - } - - function $43($0_1, $1_1) { - $0_1 = $0_1 | 0; - $1_1 = $1_1 | 0; - var $2_1 = 0, $3_1 = 0, $4_1 = 0, $5_1 = 0, $6_1 = 0, $7_1 = 0, i64toi32_i32$1 = 0, $11_1 = 0, $12_1 = 0, $152 = 0, $8_1 = 0; - $2_1 = global$0 - 96 | 0; - global$0 = $2_1; - label$1 : { - if ($1_1 >>> 0 >= 16 >>> 0) { - $4_1 = $23($0_1 | 0, $1_1 | 0) | 0; - break label$1; - } - if (!$1_1) { - break label$1 - } - $5_1 = $1_1 & 3 | 0; - if ($1_1 >>> 0 >= 4 >>> 0) { - $3_1 = $0_1; - $7_1 = $1_1 & 12 | 0; - $6_1 = $7_1; - label$4 : while (1) { - $4_1 = ((($4_1 + ((HEAP8[$3_1 >> 0] | 0 | 0) > (-65 | 0)) | 0) + ((HEAP8[($3_1 + 1 | 0) >> 0] | 0 | 0) > (-65 | 0)) | 0) + ((HEAP8[($3_1 + 2 | 0) >> 0] | 0 | 0) > (-65 | 0)) | 0) + ((HEAP8[($3_1 + 3 | 0) >> 0] | 0 | 0) > (-65 | 0)) | 0; - $3_1 = $3_1 + 4 | 0; - $6_1 = $6_1 - 4 | 0; - if ($6_1) { - continue label$4 - } - break label$4; - }; - } - if (!$5_1) { - break label$1 - } - $3_1 = $0_1 + $7_1 | 0; - label$5 : while (1) { - $4_1 = $4_1 + ((HEAP8[$3_1 >> 0] | 0 | 0) > (-65 | 0)) | 0; - $3_1 = $3_1 + 1 | 0; - $5_1 = $5_1 - 1 | 0; - if ($5_1) { - continue label$5 - } - break label$5; - }; - } - $5_1 = $2_1 + 48 | 0; - HEAP32[($2_1 + 32 | 0) >> 2] = $5_1; - HEAP16[($2_1 + 46 | 0) >> 1] = $4_1; - HEAP32[($2_1 + 36 | 0) >> 2] = $0_1; - HEAP32[($2_1 + 40 | 0) >> 2] = $0_1 + $1_1 | 0; - HEAP32[($2_1 + 28 | 0) >> 2] = $2_1 + 46 | 0; - $4_1 = $2_1 + 28 | 0; - $29($2_1 + 60 | 0 | 0, $4_1 | 0); - label$6 : { - if ((HEAP32[($2_1 + 64 | 0) >> 2] | 0 | 0) == (1 | 0)) { - $30($2_1 + 16 | 0 | 0, HEAP32[($2_1 + 68 | 0) >> 2] | 0 | 0); - $3_1 = 0; - HEAP32[($2_1 + 56 | 0) >> 2] = 0; - i64toi32_i32$1 = HEAP32[($2_1 + 20 | 0) >> 2] | 0; - HEAP32[($2_1 + 48 | 0) >> 2] = HEAP32[($2_1 + 16 | 0) >> 2] | 0; - HEAP32[($2_1 + 52 | 0) >> 2] = i64toi32_i32$1; - $29($2_1 + 72 | 0 | 0, $4_1 | 0); - if ((HEAP32[($2_1 + 76 | 0) >> 2] | 0 | 0) == (1 | 0)) { - $32($5_1 | 0, HEAP32[($2_1 + 80 | 0) >> 2] | 0 | 0); - $5_1 = HEAP32[($2_1 + 52 | 0) >> 2] | 0; - $6_1 = HEAP32[($2_1 + 56 | 0) >> 2] | 0; - $4_1 = $5_1 + $6_1 | 0; - label$9 : while (1) { - HEAP8[($3_1 + $4_1 | 0) >> 0] = HEAPU8[(($2_1 + 46 | 0) + $3_1 | 0) >> 0] | 0; - $3_1 = $3_1 + 1 | 0; - if (($3_1 | 0) != (2 | 0)) { - continue label$9 - } - break label$9; - }; - if ($1_1) { - $7_1 = $3_1 + $4_1 | 0; - $4_1 = 0; - label$11 : while (1) { - HEAP8[($4_1 + $7_1 | 0) >> 0] = HEAPU8[($0_1 + $4_1 | 0) >> 0] | 0; - $4_1 = $4_1 + 1 | 0; - if (($1_1 | 0) != ($4_1 | 0)) { - continue label$11 - } - break label$11; - }; - $152 = ($3_1 + $6_1 | 0) + $4_1 | 0; - } else { - $152 = $3_1 + $6_1 | 0 - } - $0_1 = $152; - $7_1 = HEAP32[($2_1 + 48 | 0) >> 2] | 0; - $6_1 = $39(1 | 0, $5_1 | 0, $0_1 | 0) | 0; - HEAP32[($2_1 + 36 | 0) >> 2] = $0_1; - $0_1 = $6_1 + 20 | 0; - HEAP32[($2_1 + 32 | 0) >> 2] = $0_1; - HEAP32[($2_1 + 28 | 0) >> 2] = $0_1; - $30($2_1 + 8 | 0 | 0, 12 | 0); - $1_1 = HEAP32[($2_1 + 12 | 0) >> 2] | 0; - HEAP32[($2_1 + 76 | 0) >> 2] = $1_1; - HEAP32[($2_1 + 72 | 0) >> 2] = HEAP32[($2_1 + 8 | 0) >> 2] | 0; - $4_1 = 0; - $3_1 = 0; - label$13 : while (1) { - HEAP32[($2_1 + 80 | 0) >> 2] = $4_1; - if (($3_1 | 0) == (12 | 0)) { - break label$6 - } - $32($2_1 + 72 | 0 | 0, 4 | 0); - $1_1 = HEAP32[($2_1 + 76 | 0) >> 2] | 0; - $0_1 = HEAP32[($2_1 + 80 | 0) >> 2] | 0; - $11_1 = $1_1 + $0_1 | 0; - $12_1 = HEAP32[(($2_1 + 28 | 0) + $3_1 | 0) >> 2] | 0; - HEAP8[$11_1 >> 0] = $12_1; - HEAP8[($11_1 + 1 | 0) >> 0] = $12_1 >>> 8 | 0; - HEAP8[($11_1 + 2 | 0) >> 0] = $12_1 >>> 16 | 0; - HEAP8[($11_1 + 3 | 0) >> 0] = $12_1 >>> 24 | 0; - $3_1 = $3_1 + 4 | 0; - $4_1 = $0_1 + 4 | 0; - continue label$13; - }; - } - HEAP32[($2_1 + 88 | 0) >> 2] = 0; - HEAP32[($2_1 + 76 | 0) >> 2] = 1; - HEAP32[($2_1 + 72 | 0) >> 2] = 1049188; - i64toi32_i32$1 = 0; - HEAP32[($2_1 + 80 | 0) >> 2] = 4; - HEAP32[($2_1 + 84 | 0) >> 2] = i64toi32_i32$1; - $2($2_1 + 72 | 0 | 0, 1049384 | 0); - wasm2js_trap(); - } - HEAP32[($2_1 + 88 | 0) >> 2] = 0; - HEAP32[($2_1 + 76 | 0) >> 2] = 1; - HEAP32[($2_1 + 72 | 0) >> 2] = 1049188; - i64toi32_i32$1 = 0; - HEAP32[($2_1 + 80 | 0) >> 2] = 4; - HEAP32[($2_1 + 84 | 0) >> 2] = i64toi32_i32$1; - $2($2_1 + 72 | 0 | 0, 1049292 | 0); - wasm2js_trap(); - } - $8_1 = HEAP32[($2_1 + 72 | 0) >> 2] | 0; - $0_1 = $39(2 | 0, $1_1 | 0, $4_1 | 0) | 0; - $37($8_1 | 0, $1_1 | 0, 1 | 0); - $37($7_1 | 0, $5_1 | 0, 1 | 0); - fimport$0($0_1 + 20 | 0 | 0); - $40($0_1 | 0); - $40($6_1 | 0); - global$0 = $2_1 + 96 | 0; - } - - function $44($0_1) { - $0_1 = $0_1 | 0; - var $1_1 = 0, $3_1 = 0, $2_1 = 0; - $1_1 = global$0 + -64 | 0; - global$0 = $1_1; - $41($1_1 | 0, $0_1 | 0); - $2_1 = HEAP32[$1_1 >> 2] | 0; - $0_1 = HEAP32[($1_1 + 4 | 0) >> 2] | 0; - HEAP32[($1_1 + 28 | 0) >> 2] = 1; - HEAP32[($1_1 + 24 | 0) >> 2] = 1049440; - HEAP32[($1_1 + 36 | 0) >> 2] = 1; - HEAP32[($1_1 + 52 | 0) >> 2] = 4; - HEAP32[($1_1 + 56 | 0) >> 2] = $0_1 + 20 | 0; - HEAP32[($1_1 + 60 | 0) >> 2] = HEAP32[($0_1 + 16 | 0) >> 2] | 0; - HEAP32[($1_1 + 40 | 0) >> 2] = 0; - HEAP32[($1_1 + 32 | 0) >> 2] = $1_1 + 48 | 0; - HEAP32[($1_1 + 48 | 0) >> 2] = $1_1 + 56 | 0; - $45($1_1 + 12 | 0 | 0, $1_1 + 24 | 0 | 0); - $3_1 = HEAP32[($1_1 + 16 | 0) >> 2] | 0; - $43($3_1 | 0, HEAP32[($1_1 + 20 | 0) >> 2] | 0 | 0); - $37(HEAP32[($1_1 + 12 | 0) >> 2] | 0 | 0, $3_1 | 0, 1 | 0); - $3_1 = HEAP32[($0_1 + 4 | 0) >> 2] | 0; - if ($3_1 >>> 0 >= 2 >>> 0) { - HEAP32[($0_1 + 4 | 0) >> 2] = $3_1 - 1 | 0 - } - $0_1 = HEAP32[($2_1 + 4 | 0) >> 2] | 0; - if ($0_1 >>> 0 >= 2 >>> 0) { - HEAP32[($2_1 + 4 | 0) >> 2] = $0_1 - 1 | 0 - } - global$0 = $1_1 - -64 | 0; - return $2_1 + 20 | 0 | 0; - } - - function $45($0_1, $1_1) { - $0_1 = $0_1 | 0; - $1_1 = $1_1 | 0; - var $2_1 = 0, $4_1 = 0, $3_1 = 0, $5_1 = 0, i64toi32_i32$0 = 0, i64toi32_i32$1 = 0, i64toi32_i32$2 = 0, $6_1 = 0, $7_1 = 0, $8_1 = 0, $9_1 = 0, i64toi32_i32$3 = 0, $21_1 = 0, $122 = 0, $146 = 0, $151 = 0; - $4_1 = global$0 - 32 | 0; - global$0 = $4_1; - $8_1 = HEAP32[($1_1 + 12 | 0) >> 2] | 0; - $6_1 = HEAP32[$1_1 >> 2] | 0; - label$1 : { - label$2 : { - label$3 : { - label$4 : { - label$5 : { - label$6 : { - label$7 : { - label$8 : { - label$9 : { - label$10 : { - label$11 : { - label$12 : { - label$13 : { - $5_1 = HEAP32[($1_1 + 4 | 0) >> 2] | 0; - switch ($5_1 | 0) { - case 1: - break label$11; - case 0: - break label$13; - default: - break label$12; - }; - } - if ($8_1) { - break label$7 - } - $21_1 = 1; - break label$10; - } - $7_1 = $5_1 & 3 | 0; - label$14 : { - if ($5_1 >>> 0 < 4 >>> 0) { - $5_1 = 0; - break label$14; - } - $2_1 = $6_1 + 28 | 0; - $5_1 = $5_1 & -4 | 0; - $9_1 = $5_1; - label$16 : while (1) { - $3_1 = (HEAP32[$2_1 >> 2] | 0) + ((HEAP32[($2_1 - 8 | 0) >> 2] | 0) + ((HEAP32[($2_1 - 16 | 0) >> 2] | 0) + ((HEAP32[($2_1 - 24 | 0) >> 2] | 0) + $3_1 | 0) | 0) | 0) | 0; - $2_1 = $2_1 + 32 | 0; - $9_1 = $9_1 - 4 | 0; - if ($9_1) { - continue label$16 - } - break label$16; - }; - } - if (!$7_1) { - break label$8 - } - break label$9; - } - if ($8_1) { - $7_1 = $5_1 & 3 | 0; - $5_1 = 0; - break label$9; - } - $2_1 = HEAP32[($6_1 + 4 | 0) >> 2] | 0; - $21_1 = HEAP32[$6_1 >> 2] | 0; - } - $1_1 = $21_1; - $30($4_1 + 8 | 0 | 0, $2_1 | 0); - $3_1 = HEAP32[($4_1 + 8 | 0) >> 2] | 0; - $1_1 = $57(HEAP32[($4_1 + 12 | 0) >> 2] | 0 | 0, $1_1 | 0, $2_1 | 0) | 0; - HEAP32[($0_1 + 8 | 0) >> 2] = $2_1; - HEAP32[($0_1 + 4 | 0) >> 2] = $1_1; - HEAP32[$0_1 >> 2] = $3_1; - break label$4; - } - $2_1 = (($5_1 << 3 | 0) + $6_1 | 0) + 4 | 0; - label$18 : while (1) { - $3_1 = (HEAP32[$2_1 >> 2] | 0) + $3_1 | 0; - $2_1 = $2_1 + 8 | 0; - $7_1 = $7_1 - 1 | 0; - if ($7_1) { - continue label$18 - } - break label$18; - }; - } - if ($8_1) { - if (($3_1 | 0) < (0 | 0)) { - break label$7 - } - if (!(HEAP32[($6_1 + 4 | 0) >> 2] | 0) & $3_1 >>> 0 < 16 >>> 0 | 0) { - break label$7 - } - $3_1 = $3_1 << 1 | 0; - } - if (($3_1 | 0) < (0 | 0)) { - break label$3 - } - if ($3_1) { - break label$6 - } - } - $2_1 = 1; - $3_1 = 0; - break label$5; - } - HEAPU8[1049704 >> 0] | 0; - $2_1 = $6($3_1 | 0) | 0; - if (!$2_1) { - break label$2 - } - } - HEAP32[($4_1 + 24 | 0) >> 2] = 0; - HEAP32[($4_1 + 20 | 0) >> 2] = $2_1; - HEAP32[($4_1 + 16 | 0) >> 2] = $3_1; - if ($13($4_1 + 16 | 0 | 0, 1048576 | 0, $1_1 | 0) | 0) { - break label$1 - } - i64toi32_i32$2 = $4_1; - i64toi32_i32$0 = HEAP32[($4_1 + 16 | 0) >> 2] | 0; - i64toi32_i32$1 = HEAP32[($4_1 + 20 | 0) >> 2] | 0; - $122 = i64toi32_i32$0; - i64toi32_i32$0 = $0_1; - HEAP32[$0_1 >> 2] = $122; - HEAP32[($0_1 + 4 | 0) >> 2] = i64toi32_i32$1; - HEAP32[($0_1 + 8 | 0) >> 2] = HEAP32[($4_1 + 24 | 0) >> 2] | 0; - } - global$0 = $4_1 + 32 | 0; - return; - } - $1(); - } - wasm2js_trap(); - } - $0_1 = global$0 + -64 | 0; - global$0 = $0_1; - HEAP32[($0_1 + 12 | 0) >> 2] = 86; - HEAP32[($0_1 + 8 | 0) >> 2] = 1048652; - HEAP32[($0_1 + 20 | 0) >> 2] = 1048636; - HEAP32[($0_1 + 16 | 0) >> 2] = $4_1 + 31 | 0; - HEAP32[($0_1 + 28 | 0) >> 2] = 2; - HEAP32[($0_1 + 24 | 0) >> 2] = 1048776; - i64toi32_i32$0 = $0_1; - i64toi32_i32$1 = 0; - HEAP32[($0_1 + 36 | 0) >> 2] = 2; - HEAP32[($0_1 + 40 | 0) >> 2] = i64toi32_i32$1; - i64toi32_i32$1 = 0; - i64toi32_i32$2 = $0_1 + 16 | 0; - i64toi32_i32$0 = 2; - i64toi32_i32$3 = 0; - i64toi32_i32$0 = i64toi32_i32$1 | i64toi32_i32$0 | 0; - $146 = i64toi32_i32$2 | i64toi32_i32$3 | 0; - i64toi32_i32$2 = $0_1; - HEAP32[($0_1 + 56 | 0) >> 2] = $146; - HEAP32[($0_1 + 60 | 0) >> 2] = i64toi32_i32$0; - i64toi32_i32$0 = 0; - i64toi32_i32$1 = $0_1 + 8 | 0; - i64toi32_i32$2 = 3; - i64toi32_i32$3 = 0; - i64toi32_i32$2 = i64toi32_i32$0 | i64toi32_i32$2 | 0; - $151 = i64toi32_i32$1 | i64toi32_i32$3 | 0; - i64toi32_i32$1 = $0_1; - HEAP32[($0_1 + 48 | 0) >> 2] = $151; - HEAP32[($0_1 + 52 | 0) >> 2] = i64toi32_i32$2; - HEAP32[($0_1 + 32 | 0) >> 2] = $0_1 + 48 | 0; - $2($0_1 + 24 | 0 | 0, 1048756 | 0); - wasm2js_trap(); - } - - function $46($0_1) { - $0_1 = $0_1 | 0; - $58($0_1 | 0, 1049468 | 0); - } - - function $47($0_1) { - $0_1 = $0_1 | 0; - $58($0_1 | 0, 1049488 | 0); - } - - function $48($0_1, $1_1) { - $0_1 = $0_1 | 0; - $1_1 = $1_1 | 0; - $0_1 = ($38($0_1 | 0, $1_1 | 0) | 0) + 20 | 0; - $49(1049692 | 0, $0_1 | 0); - return $0_1 | 0; - } - - function $49($0_1, $1_1) { - $0_1 = $0_1 | 0; - $1_1 = $1_1 | 0; - var $3_1 = 0, $2_1 = 0, $4_1 = 0; - $4_1 = HEAP32[($0_1 + 8 | 0) >> 2] | 0; - $3_1 = HEAP32[$0_1 >> 2] | 0; - if (($4_1 | 0) == ($3_1 | 0)) { - $2_1 = global$0 - 16 | 0; - global$0 = $2_1; - $33($2_1 + 8 | 0 | 0, $0_1 | 0, $3_1 | 0, 1 | 0, 4 | 0, 4 | 0); - $3_1 = HEAP32[($2_1 + 8 | 0) >> 2] | 0; - if (($3_1 | 0) != (-2147483647 | 0)) { - HEAP32[($2_1 + 12 | 0) >> 2] | 0; - $0($3_1 | 0); - wasm2js_trap(); - } - global$0 = $2_1 + 16 | 0; - } - HEAP32[($0_1 + 8 | 0) >> 2] = $4_1 + 1 | 0; - HEAP32[((HEAP32[($0_1 + 4 | 0) >> 2] | 0) + ($4_1 << 2 | 0) | 0) >> 2] = $1_1; - } - - function $50($0_1) { - $0_1 = $0_1 | 0; - var $1_1 = 0; - $1_1 = $0_1 - 16 | 0; - HEAP32[$1_1 >> 2] = (HEAP32[$1_1 >> 2] | 0) + 1 | 0; - return $0_1 | 0; - } - - function $51($0_1) { - $0_1 = $0_1 | 0; - var $1_1 = 0, $2_1 = 0; - $1_1 = global$0 - 48 | 0; - global$0 = $1_1; - $0_1 = $0_1 - 20 | 0; - $2_1 = HEAP32[($0_1 + 4 | 0) >> 2] | 0; - if ($2_1 >>> 0 >= 2 >>> 0) { - HEAP32[($0_1 + 4 | 0) >> 2] = $2_1 - 1 | 0 - } - HEAP32[($1_1 + 16 | 0) >> 2] = 1; - HEAP32[($1_1 + 12 | 0) >> 2] = 1049508; - HEAP32[($1_1 + 24 | 0) >> 2] = 1; - HEAP32[($1_1 + 28 | 0) >> 2] = 0; - HEAP32[($1_1 + 40 | 0) >> 2] = 1; - HEAP32[($1_1 + 44 | 0) >> 2] = HEAP32[1049700 >> 2] | 0; - HEAP32[($1_1 + 20 | 0) >> 2] = $1_1 + 36 | 0; - HEAP32[($1_1 + 36 | 0) >> 2] = $1_1 + 44 | 0; - $45($1_1 | 0, $1_1 + 12 | 0 | 0); - $0_1 = HEAP32[($1_1 + 4 | 0) >> 2] | 0; - $43($0_1 | 0, HEAP32[($1_1 + 8 | 0) >> 2] | 0 | 0); - $37(HEAP32[$1_1 >> 2] | 0 | 0, $0_1 | 0, 1 | 0); - global$0 = $1_1 + 48 | 0; - } - - function $52() { - var $0_1 = 0, i64toi32_i32$0 = 0, $1_1 = 0, $2_1 = 0, $3_1 = 0, i64toi32_i32$1 = 0, $34_1 = 0; - $0_1 = global$0 - 16 | 0; - global$0 = $0_1; - i64toi32_i32$1 = $0_1; - i64toi32_i32$0 = 4; - HEAP32[($0_1 + 4 | 0) >> 2] = 0; - HEAP32[($0_1 + 8 | 0) >> 2] = i64toi32_i32$0; - HEAP32[($0_1 + 12 | 0) >> 2] = 0; - $1_1 = (HEAP32[1049700 >> 2] | 0) << 2 | 0; - $2_1 = HEAP32[1049696 >> 2] | 0; - label$1 : while (1) { - if ($1_1) { - label$3 : { - $3_1 = (HEAP32[$2_1 >> 2] | 0) - 20 | 0; - if (!(HEAP32[($3_1 + 4 | 0) >> 2] | 0)) { - $9($3_1 | 0, 20 | 0); - break label$3; - } - $49($0_1 + 4 | 0 | 0, $3_1 + 20 | 0 | 0); - } - $2_1 = $2_1 + 4 | 0; - $1_1 = $1_1 - 4 | 0; - continue label$1; - } - break label$1; - }; - $37(HEAP32[1049692 >> 2] | 0 | 0, HEAP32[1049696 >> 2] | 0 | 0, 4 | 0); - HEAP32[1049700 >> 2] = HEAP32[($0_1 + 12 | 0) >> 2] | 0; - i64toi32_i32$0 = HEAP32[($0_1 + 4 | 0) >> 2] | 0; - i64toi32_i32$1 = HEAP32[($0_1 + 8 | 0) >> 2] | 0; - $34_1 = i64toi32_i32$0; - i64toi32_i32$0 = 1049692; - HEAP32[i64toi32_i32$0 >> 2] = $34_1; - HEAP32[(i64toi32_i32$0 + 4 | 0) >> 2] = i64toi32_i32$1; - global$0 = $0_1 + 16 | 0; - } - - function $53($0_1, $1_1) { - $0_1 = $0_1 | 0; - $1_1 = $1_1 | 0; - HEAP32[$0_1 >> 2] = 0; - } - - function $54($0_1, $1_1) { - $0_1 = $0_1 | 0; - $1_1 = $1_1 | 0; - var $2_1 = 0, $3_1 = 0, $4_1 = 0, $5_1 = 0; - $2_1 = 31; - HEAP32[($0_1 + 16 | 0) >> 2] = 0; - HEAP32[($0_1 + 20 | 0) >> 2] = 0; - if ($1_1 >>> 0 <= 16777215 >>> 0) { - $3_1 = Math_clz32($1_1 >>> 8 | 0); - $2_1 = ((($1_1 >>> (6 - $3_1 | 0) | 0) & 1 | 0) - ($3_1 << 1 | 0) | 0) + 62 | 0; - } - HEAP32[($0_1 + 28 | 0) >> 2] = $2_1; - $4_1 = ($2_1 << 2 | 0) + 1049716 | 0; - $3_1 = 1 << $2_1 | 0; - if (!($3_1 & (HEAP32[1050128 >> 2] | 0) | 0)) { - HEAP32[$4_1 >> 2] = $0_1; - HEAP32[($0_1 + 24 | 0) >> 2] = $4_1; - HEAP32[($0_1 + 12 | 0) >> 2] = $0_1; - HEAP32[($0_1 + 8 | 0) >> 2] = $0_1; - HEAP32[1050128 >> 2] = HEAP32[1050128 >> 2] | 0 | $3_1 | 0; - return; - } - label$3 : { - label$4 : { - $3_1 = HEAP32[$4_1 >> 2] | 0; - if (($1_1 | 0) == ((HEAP32[($3_1 + 4 | 0) >> 2] | 0) & -8 | 0 | 0)) { - $2_1 = $3_1; - break label$4; - } - $5_1 = $1_1 << (($2_1 | 0) != (31 | 0) ? 25 - ($2_1 >>> 1 | 0) | 0 : 0) | 0; - label$6 : while (1) { - $4_1 = ($3_1 + (($5_1 >>> 29 | 0) & 4 | 0) | 0) + 16 | 0; - $2_1 = HEAP32[$4_1 >> 2] | 0; - if (!$2_1) { - break label$3 - } - $5_1 = $5_1 << 1 | 0; - $3_1 = $2_1; - if (((HEAP32[($2_1 + 4 | 0) >> 2] | 0) & -8 | 0 | 0) != ($1_1 | 0)) { - continue label$6 - } - break label$6; - }; - } - $1_1 = HEAP32[($2_1 + 8 | 0) >> 2] | 0; - HEAP32[($1_1 + 12 | 0) >> 2] = $0_1; - HEAP32[($2_1 + 8 | 0) >> 2] = $0_1; - HEAP32[($0_1 + 24 | 0) >> 2] = 0; - HEAP32[($0_1 + 12 | 0) >> 2] = $2_1; - HEAP32[($0_1 + 8 | 0) >> 2] = $1_1; - return; - } - HEAP32[$4_1 >> 2] = $0_1; - HEAP32[($0_1 + 24 | 0) >> 2] = $3_1; - HEAP32[($0_1 + 12 | 0) >> 2] = $0_1; - HEAP32[($0_1 + 8 | 0) >> 2] = $0_1; - } - - function $55($0_1, $1_1, $2_1) { - $0_1 = $0_1 | 0; - $1_1 = $1_1 | 0; - $2_1 = $2_1 | 0; - var $3_1 = 0, $4_1 = 0; - $3_1 = global$0 - 16 | 0; - global$0 = $3_1; - $4_1 = HEAP32[1049712 >> 2] | 0; - HEAP32[1049712 >> 2] = $4_1 + 1 | 0; - label$1 : { - if (($4_1 | 0) < (0 | 0)) { - break label$1 - } - label$2 : { - if (!(HEAPU8[1050172 >> 0] | 0)) { - HEAP32[1050168 >> 2] = (HEAP32[1050168 >> 2] | 0) + 1 | 0; - if ((HEAP32[1049708 >> 2] | 0 | 0) >= (0 | 0)) { - break label$2 - } - break label$1; - } - FUNCTION_TABLE[$1_1 | 0]($3_1 + 8 | 0, $0_1); - wasm2js_trap(); - } - HEAP8[1050172 >> 0] = 0; - if (!$2_1) { - break label$1 - } - wasm2js_trap(); - } - wasm2js_trap(); - } - - function $56($0_1, $1_1) { - $0_1 = $0_1 | 0; - $1_1 = $1_1 | 0; - var i64toi32_i32$0 = 0, i64toi32_i32$2 = 0, i64toi32_i32$1 = 0, $4_1 = 0; - i64toi32_i32$2 = $1_1; - i64toi32_i32$0 = HEAP32[i64toi32_i32$2 >> 2] | 0; - i64toi32_i32$1 = HEAP32[(i64toi32_i32$2 + 4 | 0) >> 2] | 0; - $4_1 = i64toi32_i32$0; - i64toi32_i32$0 = $0_1; - HEAP32[i64toi32_i32$0 >> 2] = $4_1; - HEAP32[(i64toi32_i32$0 + 4 | 0) >> 2] = i64toi32_i32$1; - } - - function $57($0_1, $1_1, $2_1) { - $0_1 = $0_1 | 0; - $1_1 = $1_1 | 0; - $2_1 = $2_1 | 0; - var $3_1 = 0, $4_1 = 0, $5_1 = 0, $6_1 = 0, $7_1 = 0, $8_1 = 0, $9_1 = 0, $63 = 0; - label$1 : { - if ($2_1 >>> 0 < 16 >>> 0) { - $3_1 = $0_1; - break label$1; - } - $4_1 = (0 - $0_1 | 0) & 3 | 0; - $5_1 = $0_1 + $4_1 | 0; - if ($4_1) { - $3_1 = $0_1; - $6_1 = $1_1; - label$4 : while (1) { - HEAP8[$3_1 >> 0] = HEAPU8[$6_1 >> 0] | 0; - $6_1 = $6_1 + 1 | 0; - $3_1 = $3_1 + 1 | 0; - if ($3_1 >>> 0 < $5_1 >>> 0) { - continue label$4 - } - break label$4; - }; - } - $8_1 = $2_1 - $4_1 | 0; - $7_1 = $8_1 & -4 | 0; - $3_1 = $5_1 + $7_1 | 0; - label$5 : { - $4_1 = $1_1 + $4_1 | 0; - if ($4_1 & 3 | 0) { - if (($7_1 | 0) <= (0 | 0)) { - break label$5 - } - $2_1 = $4_1 << 3 | 0; - $9_1 = $2_1 & 24 | 0; - $6_1 = $4_1 & -4 | 0; - $1_1 = $6_1 + 4 | 0; - $2_1 = (0 - $2_1 | 0) & 24 | 0; - $6_1 = HEAP32[$6_1 >> 2] | 0; - label$7 : while (1) { - $63 = $6_1 >>> $9_1 | 0; - $6_1 = HEAP32[$1_1 >> 2] | 0; - HEAP32[$5_1 >> 2] = $63 | ($6_1 << $2_1 | 0) | 0; - $1_1 = $1_1 + 4 | 0; - $5_1 = $5_1 + 4 | 0; - if ($5_1 >>> 0 < $3_1 >>> 0) { - continue label$7 - } - break label$7; - }; - break label$5; - } - if (($7_1 | 0) <= (0 | 0)) { - break label$5 - } - $1_1 = $4_1; - label$8 : while (1) { - HEAP32[$5_1 >> 2] = HEAP32[$1_1 >> 2] | 0; - $1_1 = $1_1 + 4 | 0; - $5_1 = $5_1 + 4 | 0; - if ($5_1 >>> 0 < $3_1 >>> 0) { - continue label$8 - } - break label$8; - }; - } - $2_1 = $8_1 & 3 | 0; - $1_1 = $4_1 + $7_1 | 0; - } - if ($2_1) { - $2_1 = $2_1 + $3_1 | 0; - label$10 : while (1) { - HEAP8[$3_1 >> 0] = HEAPU8[$1_1 >> 0] | 0; - $1_1 = $1_1 + 1 | 0; - $3_1 = $3_1 + 1 | 0; - if ($3_1 >>> 0 < $2_1 >>> 0) { - continue label$10 - } - break label$10; - }; - } - return $0_1 | 0; - } - - function $58($0_1, $1_1) { - $0_1 = $0_1 | 0; - $1_1 = $1_1 | 0; - var $2_1 = 0, $4_1 = 0, $5_1 = 0; - $2_1 = global$0 + -64 | 0; - global$0 = $2_1; - $41($2_1 | 0, $0_1 | 0); - $5_1 = HEAP32[$2_1 >> 2] | 0; - $0_1 = HEAP32[($2_1 + 4 | 0) >> 2] | 0; - HEAP32[($2_1 + 28 | 0) >> 2] = 1; - HEAP32[($2_1 + 24 | 0) >> 2] = $1_1; - HEAP32[($2_1 + 36 | 0) >> 2] = 1; - HEAP32[($2_1 + 52 | 0) >> 2] = 4; - HEAP32[($2_1 + 56 | 0) >> 2] = $0_1 + 20 | 0; - HEAP32[($2_1 + 60 | 0) >> 2] = HEAP32[($0_1 + 16 | 0) >> 2] | 0; - HEAP32[($2_1 + 40 | 0) >> 2] = 0; - HEAP32[($2_1 + 32 | 0) >> 2] = $2_1 + 48 | 0; - HEAP32[($2_1 + 48 | 0) >> 2] = $2_1 + 56 | 0; - $45($2_1 + 12 | 0 | 0, $2_1 + 24 | 0 | 0); - $4_1 = HEAP32[($2_1 + 16 | 0) >> 2] | 0; - $43($4_1 | 0, HEAP32[($2_1 + 20 | 0) >> 2] | 0 | 0); - $37(HEAP32[($2_1 + 12 | 0) >> 2] | 0 | 0, $4_1 | 0, 1 | 0); - $42($5_1 | 0, $0_1 | 0); - global$0 = $2_1 - -64 | 0; - } - - function _ZN17compiler_builtins3int3mul3Mul3mul17h070e9a1c69faec5bE(var$0, var$0$hi, var$1, var$1$hi) { - var$0 = var$0 | 0; - var$0$hi = var$0$hi | 0; - var$1 = var$1 | 0; - var$1$hi = var$1$hi | 0; - var i64toi32_i32$4 = 0, i64toi32_i32$0 = 0, i64toi32_i32$1 = 0, var$2 = 0, i64toi32_i32$2 = 0, i64toi32_i32$3 = 0, var$3 = 0, var$4 = 0, var$5 = 0, $21_1 = 0, $22_1 = 0, var$6 = 0, $24_1 = 0, $17_1 = 0, $18_1 = 0, $23_1 = 0, $29_1 = 0, $45_1 = 0, $56$hi = 0, $62$hi = 0; - i64toi32_i32$0 = var$1$hi; - var$2 = var$1; - var$4 = var$2 >>> 16 | 0; - i64toi32_i32$0 = var$0$hi; - var$3 = var$0; - var$5 = var$3 >>> 16 | 0; - $17_1 = Math_imul(var$4, var$5); - $18_1 = var$2; - i64toi32_i32$2 = var$3; - i64toi32_i32$1 = 0; - i64toi32_i32$3 = 32; - i64toi32_i32$4 = i64toi32_i32$3 & 31 | 0; - if (32 >>> 0 <= (i64toi32_i32$3 & 63 | 0) >>> 0) { - i64toi32_i32$1 = 0; - $21_1 = i64toi32_i32$0 >>> i64toi32_i32$4 | 0; - } else { - i64toi32_i32$1 = i64toi32_i32$0 >>> i64toi32_i32$4 | 0; - $21_1 = (((1 << i64toi32_i32$4 | 0) - 1 | 0) & i64toi32_i32$0 | 0) << (32 - i64toi32_i32$4 | 0) | 0 | (i64toi32_i32$2 >>> i64toi32_i32$4 | 0) | 0; - } - $23_1 = $17_1 + Math_imul($18_1, $21_1) | 0; - i64toi32_i32$1 = var$1$hi; - i64toi32_i32$0 = var$1; - i64toi32_i32$2 = 0; - i64toi32_i32$3 = 32; - i64toi32_i32$4 = i64toi32_i32$3 & 31 | 0; - if (32 >>> 0 <= (i64toi32_i32$3 & 63 | 0) >>> 0) { - i64toi32_i32$2 = 0; - $22_1 = i64toi32_i32$1 >>> i64toi32_i32$4 | 0; - } else { - i64toi32_i32$2 = i64toi32_i32$1 >>> i64toi32_i32$4 | 0; - $22_1 = (((1 << i64toi32_i32$4 | 0) - 1 | 0) & i64toi32_i32$1 | 0) << (32 - i64toi32_i32$4 | 0) | 0 | (i64toi32_i32$0 >>> i64toi32_i32$4 | 0) | 0; - } - $29_1 = $23_1 + Math_imul($22_1, var$3) | 0; - var$2 = var$2 & 65535 | 0; - var$3 = var$3 & 65535 | 0; - var$6 = Math_imul(var$2, var$3); - var$2 = (var$6 >>> 16 | 0) + Math_imul(var$2, var$5) | 0; - $45_1 = $29_1 + (var$2 >>> 16 | 0) | 0; - var$2 = (var$2 & 65535 | 0) + Math_imul(var$4, var$3) | 0; - i64toi32_i32$2 = 0; - i64toi32_i32$1 = $45_1 + (var$2 >>> 16 | 0) | 0; - i64toi32_i32$0 = 0; - i64toi32_i32$3 = 32; - i64toi32_i32$4 = i64toi32_i32$3 & 31 | 0; - if (32 >>> 0 <= (i64toi32_i32$3 & 63 | 0) >>> 0) { - i64toi32_i32$0 = i64toi32_i32$1 << i64toi32_i32$4 | 0; - $24_1 = 0; - } else { - i64toi32_i32$0 = ((1 << i64toi32_i32$4 | 0) - 1 | 0) & (i64toi32_i32$1 >>> (32 - i64toi32_i32$4 | 0) | 0) | 0 | (i64toi32_i32$2 << i64toi32_i32$4 | 0) | 0; - $24_1 = i64toi32_i32$1 << i64toi32_i32$4 | 0; - } - $56$hi = i64toi32_i32$0; - i64toi32_i32$0 = 0; - $62$hi = i64toi32_i32$0; - i64toi32_i32$0 = $56$hi; - i64toi32_i32$2 = $24_1; - i64toi32_i32$1 = $62$hi; - i64toi32_i32$3 = var$2 << 16 | 0 | (var$6 & 65535 | 0) | 0; - i64toi32_i32$1 = i64toi32_i32$0 | i64toi32_i32$1 | 0; - i64toi32_i32$2 = i64toi32_i32$2 | i64toi32_i32$3 | 0; - i64toi32_i32$HIGH_BITS = i64toi32_i32$1; - return i64toi32_i32$2 | 0; - } - - function _ZN17compiler_builtins3int4udiv10divmod_u6417h6026910b5ed08e40E(var$0, var$0$hi, var$1, var$1$hi) { - var$0 = var$0 | 0; - var$0$hi = var$0$hi | 0; - var$1 = var$1 | 0; - var$1$hi = var$1$hi | 0; - var i64toi32_i32$2 = 0, i64toi32_i32$3 = 0, i64toi32_i32$4 = 0, i64toi32_i32$1 = 0, i64toi32_i32$0 = 0, i64toi32_i32$5 = 0, var$2 = 0, var$3 = 0, var$4 = 0, var$5 = 0, var$5$hi = 0, var$6 = 0, var$6$hi = 0, i64toi32_i32$6 = 0, $37_1 = 0, $38_1 = 0, $39_1 = 0, $40_1 = 0, $41_1 = 0, $42_1 = 0, $43_1 = 0, $44_1 = 0, var$8$hi = 0, $45_1 = 0, $46_1 = 0, $47_1 = 0, $48_1 = 0, var$7$hi = 0, $49_1 = 0, $63$hi = 0, $65 = 0, $65$hi = 0, $120$hi = 0, $129$hi = 0, $134$hi = 0, var$8 = 0, $140 = 0, $140$hi = 0, $142$hi = 0, $144 = 0, $144$hi = 0, $151 = 0, $151$hi = 0, $154$hi = 0, var$7 = 0, $165$hi = 0; - label$1 : { - label$2 : { - label$3 : { - label$4 : { - label$5 : { - label$6 : { - label$7 : { - label$8 : { - label$9 : { - label$10 : { - label$11 : { - i64toi32_i32$0 = var$0$hi; - i64toi32_i32$2 = var$0; - i64toi32_i32$1 = 0; - i64toi32_i32$3 = 32; - i64toi32_i32$4 = i64toi32_i32$3 & 31 | 0; - if (32 >>> 0 <= (i64toi32_i32$3 & 63 | 0) >>> 0) { - i64toi32_i32$1 = 0; - $37_1 = i64toi32_i32$0 >>> i64toi32_i32$4 | 0; - } else { - i64toi32_i32$1 = i64toi32_i32$0 >>> i64toi32_i32$4 | 0; - $37_1 = (((1 << i64toi32_i32$4 | 0) - 1 | 0) & i64toi32_i32$0 | 0) << (32 - i64toi32_i32$4 | 0) | 0 | (i64toi32_i32$2 >>> i64toi32_i32$4 | 0) | 0; - } - var$2 = $37_1; - if (var$2) { - i64toi32_i32$1 = var$1$hi; - var$3 = var$1; - if (!var$3) { - break label$11 - } - i64toi32_i32$0 = var$3; - i64toi32_i32$2 = 0; - i64toi32_i32$3 = 32; - i64toi32_i32$4 = i64toi32_i32$3 & 31 | 0; - if (32 >>> 0 <= (i64toi32_i32$3 & 63 | 0) >>> 0) { - i64toi32_i32$2 = 0; - $38_1 = i64toi32_i32$1 >>> i64toi32_i32$4 | 0; - } else { - i64toi32_i32$2 = i64toi32_i32$1 >>> i64toi32_i32$4 | 0; - $38_1 = (((1 << i64toi32_i32$4 | 0) - 1 | 0) & i64toi32_i32$1 | 0) << (32 - i64toi32_i32$4 | 0) | 0 | (i64toi32_i32$0 >>> i64toi32_i32$4 | 0) | 0; - } - var$4 = $38_1; - if (!var$4) { - break label$9 - } - var$2 = Math_clz32(var$4) - Math_clz32(var$2) | 0; - if (var$2 >>> 0 <= 31 >>> 0) { - break label$8 - } - break label$2; - } - i64toi32_i32$2 = var$1$hi; - i64toi32_i32$1 = var$1; - i64toi32_i32$0 = 1; - i64toi32_i32$3 = 0; - if (i64toi32_i32$2 >>> 0 > i64toi32_i32$0 >>> 0 | ((i64toi32_i32$2 | 0) == (i64toi32_i32$0 | 0) & i64toi32_i32$1 >>> 0 >= i64toi32_i32$3 >>> 0 | 0) | 0) { - break label$2 - } - i64toi32_i32$1 = var$0$hi; - var$2 = var$0; - i64toi32_i32$1 = i64toi32_i32$2; - i64toi32_i32$1 = i64toi32_i32$2; - var$3 = var$1; - var$2 = (var$2 >>> 0) / (var$3 >>> 0) | 0; - i64toi32_i32$1 = 0; - __wasm_intrinsics_temp_i64 = var$0 - Math_imul(var$2, var$3) | 0; - __wasm_intrinsics_temp_i64$hi = i64toi32_i32$1; - i64toi32_i32$1 = 0; - i64toi32_i32$2 = var$2; - i64toi32_i32$HIGH_BITS = i64toi32_i32$1; - return i64toi32_i32$2 | 0; - } - i64toi32_i32$2 = var$1$hi; - i64toi32_i32$3 = var$1; - i64toi32_i32$1 = 0; - i64toi32_i32$0 = 32; - i64toi32_i32$4 = i64toi32_i32$0 & 31 | 0; - if (32 >>> 0 <= (i64toi32_i32$0 & 63 | 0) >>> 0) { - i64toi32_i32$1 = 0; - $39_1 = i64toi32_i32$2 >>> i64toi32_i32$4 | 0; - } else { - i64toi32_i32$1 = i64toi32_i32$2 >>> i64toi32_i32$4 | 0; - $39_1 = (((1 << i64toi32_i32$4 | 0) - 1 | 0) & i64toi32_i32$2 | 0) << (32 - i64toi32_i32$4 | 0) | 0 | (i64toi32_i32$3 >>> i64toi32_i32$4 | 0) | 0; - } - var$3 = $39_1; - i64toi32_i32$1 = var$0$hi; - if (!var$0) { - break label$7 - } - if (!var$3) { - break label$6 - } - var$4 = var$3 + -1 | 0; - if (var$4 & var$3 | 0) { - break label$6 - } - i64toi32_i32$1 = 0; - i64toi32_i32$2 = var$4 & var$2 | 0; - i64toi32_i32$3 = 0; - i64toi32_i32$0 = 32; - i64toi32_i32$4 = i64toi32_i32$0 & 31 | 0; - if (32 >>> 0 <= (i64toi32_i32$0 & 63 | 0) >>> 0) { - i64toi32_i32$3 = i64toi32_i32$2 << i64toi32_i32$4 | 0; - $40_1 = 0; - } else { - i64toi32_i32$3 = ((1 << i64toi32_i32$4 | 0) - 1 | 0) & (i64toi32_i32$2 >>> (32 - i64toi32_i32$4 | 0) | 0) | 0 | (i64toi32_i32$1 << i64toi32_i32$4 | 0) | 0; - $40_1 = i64toi32_i32$2 << i64toi32_i32$4 | 0; - } - $63$hi = i64toi32_i32$3; - i64toi32_i32$3 = var$0$hi; - i64toi32_i32$1 = var$0; - i64toi32_i32$2 = 0; - i64toi32_i32$0 = -1; - i64toi32_i32$2 = i64toi32_i32$3 & i64toi32_i32$2 | 0; - $65 = i64toi32_i32$1 & i64toi32_i32$0 | 0; - $65$hi = i64toi32_i32$2; - i64toi32_i32$2 = $63$hi; - i64toi32_i32$3 = $40_1; - i64toi32_i32$1 = $65$hi; - i64toi32_i32$0 = $65; - i64toi32_i32$1 = i64toi32_i32$2 | i64toi32_i32$1 | 0; - __wasm_intrinsics_temp_i64 = i64toi32_i32$3 | i64toi32_i32$0 | 0; - __wasm_intrinsics_temp_i64$hi = i64toi32_i32$1; - i64toi32_i32$1 = 0; - i64toi32_i32$3 = var$2 >>> ((__wasm_ctz_i32(var$3 | 0) | 0) & 31 | 0) | 0; - i64toi32_i32$HIGH_BITS = i64toi32_i32$1; - return i64toi32_i32$3 | 0; - } - } - var$4 = var$3 + -1 | 0; - if (!(var$4 & var$3 | 0)) { - break label$5 - } - var$2 = (Math_clz32(var$3) + 33 | 0) - Math_clz32(var$2) | 0; - var$3 = 0 - var$2 | 0; - break label$3; - } - var$3 = 63 - var$2 | 0; - var$2 = var$2 + 1 | 0; - break label$3; - } - var$4 = (var$2 >>> 0) / (var$3 >>> 0) | 0; - i64toi32_i32$3 = 0; - i64toi32_i32$2 = var$2 - Math_imul(var$4, var$3) | 0; - i64toi32_i32$1 = 0; - i64toi32_i32$0 = 32; - i64toi32_i32$4 = i64toi32_i32$0 & 31 | 0; - if (32 >>> 0 <= (i64toi32_i32$0 & 63 | 0) >>> 0) { - i64toi32_i32$1 = i64toi32_i32$2 << i64toi32_i32$4 | 0; - $41_1 = 0; - } else { - i64toi32_i32$1 = ((1 << i64toi32_i32$4 | 0) - 1 | 0) & (i64toi32_i32$2 >>> (32 - i64toi32_i32$4 | 0) | 0) | 0 | (i64toi32_i32$3 << i64toi32_i32$4 | 0) | 0; - $41_1 = i64toi32_i32$2 << i64toi32_i32$4 | 0; - } - __wasm_intrinsics_temp_i64 = $41_1; - __wasm_intrinsics_temp_i64$hi = i64toi32_i32$1; - i64toi32_i32$1 = 0; - i64toi32_i32$2 = var$4; - i64toi32_i32$HIGH_BITS = i64toi32_i32$1; - return i64toi32_i32$2 | 0; - } - var$2 = Math_clz32(var$3) - Math_clz32(var$2) | 0; - if (var$2 >>> 0 < 31 >>> 0) { - break label$4 - } - break label$2; - } - i64toi32_i32$2 = var$0$hi; - i64toi32_i32$2 = 0; - __wasm_intrinsics_temp_i64 = var$4 & var$0 | 0; - __wasm_intrinsics_temp_i64$hi = i64toi32_i32$2; - if ((var$3 | 0) == (1 | 0)) { - break label$1 - } - i64toi32_i32$2 = var$0$hi; - i64toi32_i32$2 = 0; - $120$hi = i64toi32_i32$2; - i64toi32_i32$2 = var$0$hi; - i64toi32_i32$3 = var$0; - i64toi32_i32$1 = $120$hi; - i64toi32_i32$0 = __wasm_ctz_i32(var$3 | 0) | 0; - i64toi32_i32$4 = i64toi32_i32$0 & 31 | 0; - if (32 >>> 0 <= (i64toi32_i32$0 & 63 | 0) >>> 0) { - i64toi32_i32$1 = 0; - $42_1 = i64toi32_i32$2 >>> i64toi32_i32$4 | 0; - } else { - i64toi32_i32$1 = i64toi32_i32$2 >>> i64toi32_i32$4 | 0; - $42_1 = (((1 << i64toi32_i32$4 | 0) - 1 | 0) & i64toi32_i32$2 | 0) << (32 - i64toi32_i32$4 | 0) | 0 | (i64toi32_i32$3 >>> i64toi32_i32$4 | 0) | 0; - } - i64toi32_i32$3 = $42_1; - i64toi32_i32$HIGH_BITS = i64toi32_i32$1; - return i64toi32_i32$3 | 0; - } - var$3 = 63 - var$2 | 0; - var$2 = var$2 + 1 | 0; - } - i64toi32_i32$3 = var$0$hi; - i64toi32_i32$3 = 0; - $129$hi = i64toi32_i32$3; - i64toi32_i32$3 = var$0$hi; - i64toi32_i32$2 = var$0; - i64toi32_i32$1 = $129$hi; - i64toi32_i32$0 = var$2 & 63 | 0; - i64toi32_i32$4 = i64toi32_i32$0 & 31 | 0; - if (32 >>> 0 <= (i64toi32_i32$0 & 63 | 0) >>> 0) { - i64toi32_i32$1 = 0; - $43_1 = i64toi32_i32$3 >>> i64toi32_i32$4 | 0; - } else { - i64toi32_i32$1 = i64toi32_i32$3 >>> i64toi32_i32$4 | 0; - $43_1 = (((1 << i64toi32_i32$4 | 0) - 1 | 0) & i64toi32_i32$3 | 0) << (32 - i64toi32_i32$4 | 0) | 0 | (i64toi32_i32$2 >>> i64toi32_i32$4 | 0) | 0; - } - var$5 = $43_1; - var$5$hi = i64toi32_i32$1; - i64toi32_i32$1 = var$0$hi; - i64toi32_i32$1 = 0; - $134$hi = i64toi32_i32$1; - i64toi32_i32$1 = var$0$hi; - i64toi32_i32$3 = var$0; - i64toi32_i32$2 = $134$hi; - i64toi32_i32$0 = var$3 & 63 | 0; - i64toi32_i32$4 = i64toi32_i32$0 & 31 | 0; - if (32 >>> 0 <= (i64toi32_i32$0 & 63 | 0) >>> 0) { - i64toi32_i32$2 = i64toi32_i32$3 << i64toi32_i32$4 | 0; - $44_1 = 0; - } else { - i64toi32_i32$2 = ((1 << i64toi32_i32$4 | 0) - 1 | 0) & (i64toi32_i32$3 >>> (32 - i64toi32_i32$4 | 0) | 0) | 0 | (i64toi32_i32$1 << i64toi32_i32$4 | 0) | 0; - $44_1 = i64toi32_i32$3 << i64toi32_i32$4 | 0; - } - var$0 = $44_1; - var$0$hi = i64toi32_i32$2; - label$13 : { - if (var$2) { - i64toi32_i32$2 = var$1$hi; - i64toi32_i32$1 = var$1; - i64toi32_i32$3 = -1; - i64toi32_i32$0 = -1; - i64toi32_i32$4 = i64toi32_i32$1 + i64toi32_i32$0 | 0; - i64toi32_i32$5 = i64toi32_i32$2 + i64toi32_i32$3 | 0; - if (i64toi32_i32$4 >>> 0 < i64toi32_i32$0 >>> 0) { - i64toi32_i32$5 = i64toi32_i32$5 + 1 | 0 - } - var$8 = i64toi32_i32$4; - var$8$hi = i64toi32_i32$5; - label$15 : while (1) { - i64toi32_i32$5 = var$5$hi; - i64toi32_i32$2 = var$5; - i64toi32_i32$1 = 0; - i64toi32_i32$0 = 1; - i64toi32_i32$3 = i64toi32_i32$0 & 31 | 0; - if (32 >>> 0 <= (i64toi32_i32$0 & 63 | 0) >>> 0) { - i64toi32_i32$1 = i64toi32_i32$2 << i64toi32_i32$3 | 0; - $45_1 = 0; - } else { - i64toi32_i32$1 = ((1 << i64toi32_i32$3 | 0) - 1 | 0) & (i64toi32_i32$2 >>> (32 - i64toi32_i32$3 | 0) | 0) | 0 | (i64toi32_i32$5 << i64toi32_i32$3 | 0) | 0; - $45_1 = i64toi32_i32$2 << i64toi32_i32$3 | 0; - } - $140 = $45_1; - $140$hi = i64toi32_i32$1; - i64toi32_i32$1 = var$0$hi; - i64toi32_i32$5 = var$0; - i64toi32_i32$2 = 0; - i64toi32_i32$0 = 63; - i64toi32_i32$3 = i64toi32_i32$0 & 31 | 0; - if (32 >>> 0 <= (i64toi32_i32$0 & 63 | 0) >>> 0) { - i64toi32_i32$2 = 0; - $46_1 = i64toi32_i32$1 >>> i64toi32_i32$3 | 0; - } else { - i64toi32_i32$2 = i64toi32_i32$1 >>> i64toi32_i32$3 | 0; - $46_1 = (((1 << i64toi32_i32$3 | 0) - 1 | 0) & i64toi32_i32$1 | 0) << (32 - i64toi32_i32$3 | 0) | 0 | (i64toi32_i32$5 >>> i64toi32_i32$3 | 0) | 0; - } - $142$hi = i64toi32_i32$2; - i64toi32_i32$2 = $140$hi; - i64toi32_i32$1 = $140; - i64toi32_i32$5 = $142$hi; - i64toi32_i32$0 = $46_1; - i64toi32_i32$5 = i64toi32_i32$2 | i64toi32_i32$5 | 0; - var$5 = i64toi32_i32$1 | i64toi32_i32$0 | 0; - var$5$hi = i64toi32_i32$5; - $144 = var$5; - $144$hi = i64toi32_i32$5; - i64toi32_i32$5 = var$8$hi; - i64toi32_i32$5 = var$5$hi; - i64toi32_i32$5 = var$8$hi; - i64toi32_i32$2 = var$8; - i64toi32_i32$1 = var$5$hi; - i64toi32_i32$0 = var$5; - i64toi32_i32$3 = i64toi32_i32$2 - i64toi32_i32$0 | 0; - i64toi32_i32$6 = i64toi32_i32$2 >>> 0 < i64toi32_i32$0 >>> 0; - i64toi32_i32$4 = i64toi32_i32$6 + i64toi32_i32$1 | 0; - i64toi32_i32$4 = i64toi32_i32$5 - i64toi32_i32$4 | 0; - i64toi32_i32$5 = i64toi32_i32$3; - i64toi32_i32$2 = 0; - i64toi32_i32$0 = 63; - i64toi32_i32$1 = i64toi32_i32$0 & 31 | 0; - if (32 >>> 0 <= (i64toi32_i32$0 & 63 | 0) >>> 0) { - i64toi32_i32$2 = i64toi32_i32$4 >> 31 | 0; - $47_1 = i64toi32_i32$4 >> i64toi32_i32$1 | 0; - } else { - i64toi32_i32$2 = i64toi32_i32$4 >> i64toi32_i32$1 | 0; - $47_1 = (((1 << i64toi32_i32$1 | 0) - 1 | 0) & i64toi32_i32$4 | 0) << (32 - i64toi32_i32$1 | 0) | 0 | (i64toi32_i32$5 >>> i64toi32_i32$1 | 0) | 0; - } - var$6 = $47_1; - var$6$hi = i64toi32_i32$2; - i64toi32_i32$2 = var$1$hi; - i64toi32_i32$2 = var$6$hi; - i64toi32_i32$4 = var$6; - i64toi32_i32$5 = var$1$hi; - i64toi32_i32$0 = var$1; - i64toi32_i32$5 = i64toi32_i32$2 & i64toi32_i32$5 | 0; - $151 = i64toi32_i32$4 & i64toi32_i32$0 | 0; - $151$hi = i64toi32_i32$5; - i64toi32_i32$5 = $144$hi; - i64toi32_i32$2 = $144; - i64toi32_i32$4 = $151$hi; - i64toi32_i32$0 = $151; - i64toi32_i32$1 = i64toi32_i32$2 - i64toi32_i32$0 | 0; - i64toi32_i32$6 = i64toi32_i32$2 >>> 0 < i64toi32_i32$0 >>> 0; - i64toi32_i32$3 = i64toi32_i32$6 + i64toi32_i32$4 | 0; - i64toi32_i32$3 = i64toi32_i32$5 - i64toi32_i32$3 | 0; - var$5 = i64toi32_i32$1; - var$5$hi = i64toi32_i32$3; - i64toi32_i32$3 = var$0$hi; - i64toi32_i32$5 = var$0; - i64toi32_i32$2 = 0; - i64toi32_i32$0 = 1; - i64toi32_i32$4 = i64toi32_i32$0 & 31 | 0; - if (32 >>> 0 <= (i64toi32_i32$0 & 63 | 0) >>> 0) { - i64toi32_i32$2 = i64toi32_i32$5 << i64toi32_i32$4 | 0; - $48_1 = 0; - } else { - i64toi32_i32$2 = ((1 << i64toi32_i32$4 | 0) - 1 | 0) & (i64toi32_i32$5 >>> (32 - i64toi32_i32$4 | 0) | 0) | 0 | (i64toi32_i32$3 << i64toi32_i32$4 | 0) | 0; - $48_1 = i64toi32_i32$5 << i64toi32_i32$4 | 0; - } - $154$hi = i64toi32_i32$2; - i64toi32_i32$2 = var$7$hi; - i64toi32_i32$2 = $154$hi; - i64toi32_i32$3 = $48_1; - i64toi32_i32$5 = var$7$hi; - i64toi32_i32$0 = var$7; - i64toi32_i32$5 = i64toi32_i32$2 | i64toi32_i32$5 | 0; - var$0 = i64toi32_i32$3 | i64toi32_i32$0 | 0; - var$0$hi = i64toi32_i32$5; - i64toi32_i32$5 = var$6$hi; - i64toi32_i32$2 = var$6; - i64toi32_i32$3 = 0; - i64toi32_i32$0 = 1; - i64toi32_i32$3 = i64toi32_i32$5 & i64toi32_i32$3 | 0; - var$6 = i64toi32_i32$2 & i64toi32_i32$0 | 0; - var$6$hi = i64toi32_i32$3; - var$7 = var$6; - var$7$hi = i64toi32_i32$3; - var$2 = var$2 + -1 | 0; - if (var$2) { - continue label$15 - } - break label$15; - }; - break label$13; - } - } - i64toi32_i32$3 = var$5$hi; - __wasm_intrinsics_temp_i64 = var$5; - __wasm_intrinsics_temp_i64$hi = i64toi32_i32$3; - i64toi32_i32$3 = var$0$hi; - i64toi32_i32$5 = var$0; - i64toi32_i32$2 = 0; - i64toi32_i32$0 = 1; - i64toi32_i32$4 = i64toi32_i32$0 & 31 | 0; - if (32 >>> 0 <= (i64toi32_i32$0 & 63 | 0) >>> 0) { - i64toi32_i32$2 = i64toi32_i32$5 << i64toi32_i32$4 | 0; - $49_1 = 0; - } else { - i64toi32_i32$2 = ((1 << i64toi32_i32$4 | 0) - 1 | 0) & (i64toi32_i32$5 >>> (32 - i64toi32_i32$4 | 0) | 0) | 0 | (i64toi32_i32$3 << i64toi32_i32$4 | 0) | 0; - $49_1 = i64toi32_i32$5 << i64toi32_i32$4 | 0; - } - $165$hi = i64toi32_i32$2; - i64toi32_i32$2 = var$6$hi; - i64toi32_i32$2 = $165$hi; - i64toi32_i32$3 = $49_1; - i64toi32_i32$5 = var$6$hi; - i64toi32_i32$0 = var$6; - i64toi32_i32$5 = i64toi32_i32$2 | i64toi32_i32$5 | 0; - i64toi32_i32$3 = i64toi32_i32$3 | i64toi32_i32$0 | 0; - i64toi32_i32$HIGH_BITS = i64toi32_i32$5; - return i64toi32_i32$3 | 0; - } - i64toi32_i32$3 = var$0$hi; - __wasm_intrinsics_temp_i64 = var$0; - __wasm_intrinsics_temp_i64$hi = i64toi32_i32$3; - i64toi32_i32$3 = 0; - var$0 = 0; - var$0$hi = i64toi32_i32$3; - } - i64toi32_i32$3 = var$0$hi; - i64toi32_i32$5 = var$0; - i64toi32_i32$HIGH_BITS = i64toi32_i32$3; - return i64toi32_i32$5 | 0; - } - - function __wasm_i64_mul(var$0, var$0$hi, var$1, var$1$hi) { - var$0 = var$0 | 0; - var$0$hi = var$0$hi | 0; - var$1 = var$1 | 0; - var$1$hi = var$1$hi | 0; - var i64toi32_i32$0 = 0, i64toi32_i32$1 = 0; - i64toi32_i32$0 = var$0$hi; - i64toi32_i32$0 = var$1$hi; - i64toi32_i32$0 = var$0$hi; - i64toi32_i32$1 = var$1$hi; - i64toi32_i32$1 = _ZN17compiler_builtins3int3mul3Mul3mul17h070e9a1c69faec5bE(var$0 | 0, i64toi32_i32$0 | 0, var$1 | 0, i64toi32_i32$1 | 0) | 0; - i64toi32_i32$0 = i64toi32_i32$HIGH_BITS; - i64toi32_i32$HIGH_BITS = i64toi32_i32$0; - return i64toi32_i32$1 | 0; - } - - function __wasm_i64_udiv(var$0, var$0$hi, var$1, var$1$hi) { - var$0 = var$0 | 0; - var$0$hi = var$0$hi | 0; - var$1 = var$1 | 0; - var$1$hi = var$1$hi | 0; - var i64toi32_i32$0 = 0, i64toi32_i32$1 = 0; - i64toi32_i32$0 = var$0$hi; - i64toi32_i32$0 = var$1$hi; - i64toi32_i32$0 = var$0$hi; - i64toi32_i32$1 = var$1$hi; - i64toi32_i32$1 = _ZN17compiler_builtins3int4udiv10divmod_u6417h6026910b5ed08e40E(var$0 | 0, i64toi32_i32$0 | 0, var$1 | 0, i64toi32_i32$1 | 0) | 0; - i64toi32_i32$0 = i64toi32_i32$HIGH_BITS; - i64toi32_i32$HIGH_BITS = i64toi32_i32$0; - return i64toi32_i32$1 | 0; - } - - function __wasm_ctz_i32(var$0) { - var$0 = var$0 | 0; - if (var$0) { - return 31 - Math_clz32((var$0 + -1 | 0) ^ var$0 | 0) | 0 | 0 - } - return 32 | 0; - } - - bufferView = HEAPU8; - initActiveSegments(imports); - var FUNCTION_TABLE = [null, $19, $25, $24, $35, $53, $56, $8, $10, $11, $12, $7, $26, $27, $28]; - function __wasm_memory_size() { - return buffer.byteLength / 65536 | 0; - } - - function __wasm_memory_grow(pagesToAdd) { - pagesToAdd = pagesToAdd | 0; - var oldPages = __wasm_memory_size() | 0; - var newPages = oldPages + pagesToAdd | 0; - if ((oldPages < newPages) && (newPages < 65536)) { - var newBuffer = new ArrayBuffer(Math_imul(newPages, 65536)); - var newHEAP8 = new Int8Array(newBuffer); - newHEAP8.set(HEAP8); - HEAP8 = new Int8Array(newBuffer); - HEAP16 = new Int16Array(newBuffer); - HEAP32 = new Int32Array(newBuffer); - HEAPU8 = new Uint8Array(newBuffer); - HEAPU16 = new Uint16Array(newBuffer); - HEAPU32 = new Uint32Array(newBuffer); - HEAPF32 = new Float32Array(newBuffer); - HEAPF64 = new Float64Array(newBuffer); - buffer = newBuffer; - bufferView = HEAPU8; - } - return oldPages; - } - - return { - "memory": Object.create(Object.prototype, { - "grow": { - "value": __wasm_memory_grow - }, - "buffer": { - "get": function () { - return buffer; - } - - } - }), - "execute": $44, - "setEnvironment": $46, - "onDeploy": $47, - "__new": $48, - "__pin": $50, - "__unpin": $51, - "__collect": $52, - "__data_end": { - get value() { - return global$1; - }, - set value(_global$1) { - global$1 = _global$1; - } - }, - "__heap_base": { - get value() { - return global$2; - }, - set value(_global$2) { - global$2 = _global$2; - } - } - }; -} - -var retasmFunc = asmFunc({ - "env": env, -}); -export var memory = retasmFunc.memory; -export var execute = retasmFunc.execute; -export var setEnvironment = retasmFunc.setEnvironment; -export var onDeploy = retasmFunc.onDeploy; -export var __new = retasmFunc.__new; -export var __pin = retasmFunc.__pin; -export var __unpin = retasmFunc.__unpin; -export var __collect = retasmFunc.__collect; -export var __data_end = retasmFunc.__data_end; -export var __heap_base = retasmFunc.__heap_base; diff --git a/example/.cargo/config.toml b/example/.cargo/config.toml new file mode 100644 index 0000000..435ed75 --- /dev/null +++ b/example/.cargo/config.toml @@ -0,0 +1,2 @@ +[build] +target = "wasm32-unknown-unknown" \ No newline at end of file diff --git a/example/Cargo.toml b/example/Cargo.toml index ab3831f..b3b1ed0 100644 --- a/example/Cargo.toml +++ b/example/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "example" -version = "0.1.0" -edition = "2021" +version = { workspace = true } +edition = { workspace = true } [lib] crate-type = ["cdylib"] @@ -14,8 +14,8 @@ panic = "abort" # Avoids including panic runtime support strip = true [dependencies] -rust_runtime = {path=".."} -hex = "0.4.3" -lol_alloc = "0.4.1" +lol_alloc = { workspace = true } +rust_runtime = { workspace = true } +sha2-const = {workspace = true } -[features] \ No newline at end of file +[features] diff --git a/example/src/contract.rs b/example/src/contract.rs new file mode 100644 index 0000000..2ab0532 --- /dev/null +++ b/example/src/contract.rs @@ -0,0 +1,168 @@ +use rust_runtime::{ + blockchain::AddressHash, + contract::op_20::Pointer, + ethnum::u256, + math::abi::encode_selector_const, + storage::{ + multi_address_map::MultiAddressMemoryMap, + stored::{StoredTrait, StoredU256, StoredU8}, + stored_map::StoredMap, + StorageValue, + }, + types::{CallData, Selector}, + ContractTrait, OP20Trait, +}; + +const SELECTOR_AIRDROP: Selector = encode_selector_const("airdrop"); +const SELECTOR_AIRDROP_WITH_AMOUNT: Selector = encode_selector_const("airdropWithAmount"); +const SELECTOR_MINT: Selector = encode_selector_const("mint"); + +pub struct Contract { + environment: Option<&'static rust_runtime::blockchain::Environment>, + params: rust_runtime::contract::op_20::OP20Params, + balance_of_map: StoredMap, + allowance_map: MultiAddressMemoryMap, + total_supply: StoredU256, +} +impl Contract { + pub const fn new() -> Self { + Self { + environment: None, + params: rust_runtime::contract::op_20::OP20Params { + max_supply: StoredU256::new_const( + Pointer::MaxSupply.u16(), + u256::new(100000000000000000000000000), + ), + decimals: StoredU8::new_const(Pointer::Decimals.u16(), 18), + name: "MyToken", + symbol: "TOKEN", + }, + balance_of_map: StoredMap::new(Pointer::BalanceOfMap.u16()), + allowance_map: MultiAddressMemoryMap::new( + Pointer::AllowanceMap.u16(), + StorageValue::ZERO, + ), + total_supply: StoredU256::new_const(Pointer::TotalSupply.u16(), u256::ZERO), + } + } +} + +impl Contract { + fn execute( + &mut self, + selector: Selector, + call_data: CallData, + ) -> Result { + match selector { + SELECTOR_MINT => self.mint(call_data), + SELECTOR_AIRDROP => self.airdrop(call_data), + SELECTOR_AIRDROP_WITH_AMOUNT => self.airdrop_with_amount(call_data), + _ => OP20Trait::execute_base(self, selector, call_data), + } + } + + fn mint( + &mut self, + mut call_data: CallData, + ) -> Result { + self.only_deployer(&self.environment().sender)?; + + let mut response = crate::WaBuffer::new(1, 1)?; + let mut cursor = response.cursor(); + let address = call_data.read_address()?; + let amount = call_data.read_u256_be()?; + cursor.write_bool(self.mint_base(&address, amount, false)?)?; + + return Ok(response); + } + + fn airdrop( + &mut self, + mut call_data: CallData, + ) -> Result { + self.only_deployer(&self.environment().sender)?; + let drops = call_data.read_address_value_map()?; + for (address, amount) in drops.iter() { + self.mint_base(address, amount.clone(), false)?; + } + + let mut response = crate::WaBuffer::new(1, 1)?; + let mut cursor = response.cursor(); + cursor.write_bool(true)?; + + Ok(response) + } + + fn optimized_mint( + &mut self, + address: AddressHash, + amount: u256, + ) -> Result<(), rust_runtime::error::Error> { + self.balance_of_map.set(&address, amount); + let value = self.total_supply.value() + amount; + self.total_supply.set_no_commit(value); + + Self::create_mint_event(address, amount)?; + + Ok(()) + } + + fn airdrop_with_amount( + &mut self, + mut call_data: CallData, + ) -> Result { + self.only_deployer(&self.environment().sender)?; + let amount = call_data.read_u256_be()?; + let amount_of_addresses: u32 = call_data.read_u32_le()?; + + for _ in 0..amount_of_addresses { + let address = call_data.read_address()?; + self.optimized_mint(address, amount)?; + } + + self.total_supply.commit(); + + let mut response = crate::WaBuffer::new(1, 1)?; + let mut cursor = response.cursor(); + cursor.write_bool(true)?; + Ok(response) + } +} + +impl rust_runtime::contract::op_20::OP20Trait for Contract { + fn params(&mut self) -> &mut rust_runtime::OP20Params { + &mut self.params + } + fn total_supply(&mut self) -> &mut StoredU256 { + &mut self.total_supply + } + + fn allowance_map(&mut self) -> &mut MultiAddressMemoryMap { + &mut self.allowance_map + } + + fn balance_of_map(&mut self) -> &mut StoredMap { + &mut self.balance_of_map + } +} + +impl rust_runtime::contract::ContractTrait for Contract { + fn set_environment(&mut self, environment: &'static rust_runtime::blockchain::Environment) { + self.environment = Some(environment); + } + + fn environment(&self) -> &'static rust_runtime::blockchain::Environment { + self.environment.unwrap() + } + + fn execute( + &mut self, + mut call_data: CallData, + ) -> Result { + let selector = call_data.read_selector()?; + + Contract::execute(self, selector, call_data) + } + + fn on_deploy(&mut self, _call_data: CallData) {} +} diff --git a/example/src/lib.rs b/example/src/lib.rs index 309d6c4..d175ddf 100644 --- a/example/src/lib.rs +++ b/example/src/lib.rs @@ -1,5 +1,12 @@ #![no_std] -use rust_runtime; +extern crate alloc; + +#[allow(unused_imports)] +use rust_runtime::prelude::{ContractTrait, WaBuffer, WaPtr}; +pub mod contract; + +#[allow(dead_code, static_mut_refs)] +static mut CONTRACT: contract::Contract = contract::Contract::new(); #[cfg(target_arch = "wasm32")] use lol_alloc::LeakingPageAllocator; @@ -7,3 +14,32 @@ use lol_alloc::LeakingPageAllocator; #[cfg(target_arch = "wasm32")] #[global_allocator] static ALLOCATOR: LeakingPageAllocator = LeakingPageAllocator; + +#[cfg(target_arch = "wasm32")] +#[allow(static_mut_refs)] +#[export_name = "execute"] +pub unsafe fn execute(ptr: WaPtr) -> WaPtr { + match CONTRACT.execute(WaBuffer::from_raw(ptr).cursor()) { + Ok(buffer) => buffer.ptr(), + Err(err) => { + rust_runtime::log(err.as_str()); + panic!("Error occured") + } + } +} + +#[cfg(target_arch = "wasm32")] +#[export_name = "onDeploy"] +#[allow(static_mut_refs)] +pub unsafe fn on_deploy(ptr: WaPtr) { + CONTRACT.on_deploy(WaBuffer::from_raw(ptr).cursor()); +} + +#[cfg(target_arch = "wasm32")] +#[export_name = "setEnvironment"] +#[allow(static_mut_refs)] +pub unsafe fn set_environment(ptr: WaPtr) { + let buffer = WaBuffer::from_raw(ptr); + let environment: &mut rust_runtime::blockchain::Environment = buffer.into_type(); + CONTRACT.set_environment(environment); +} diff --git a/rust-toolchain b/rust-toolchain index bf867e0..c3889eb 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1,4 @@ -nightly +[toolchain] +channel = "nightly" +components = [ "rustfmt", "clippy" ] +targets = [ "wasm32-unknown-unknown" ] diff --git a/src/blockchain/address.rs b/src/blockchain/address.rs index f05455f..0927eb0 100644 --- a/src/blockchain/address.rs +++ b/src/blockchain/address.rs @@ -1,11 +1,33 @@ -pub struct Address { + +use crate::storage::StorageKey; + +#[derive(Clone, Copy, Eq, PartialEq)] +pub struct AddressHash { pub bytes: [u8; crate::constant::ADDRESS_BYTE_LENGTH], } -impl crate::utils::ToHex for Address { - fn get_bytes<'a>(&'a self) -> &'a [u8] { +impl From for StorageKey { + fn from(val: AddressHash) -> Self { + val.bytes + } +} + +impl crate::utils::ToHex for AddressHash { + fn get_bytes(&self) -> &[u8] { self.bytes.as_ref() } } -impl Address {} +impl AddressHash { + pub const DEAD: AddressHash = AddressHash { + bytes: [ + 40, 74, 228, 172, 219, 50, 169, 155, 163, 235, 250, 102, 169, 29, 219, 65, 167, 183, + 161, 210, 254, 244, 21, 57, 153, 34, 205, 138, 4, 72, 92, 2, + ], + }; + pub fn new(bytes: &[u8]) -> Self { + Self { + bytes: bytes.try_into().unwrap(), + } + } +} diff --git a/src/blockchain/block.rs b/src/blockchain/block.rs new file mode 100644 index 0000000..3d457bd --- /dev/null +++ b/src/blockchain/block.rs @@ -0,0 +1,9 @@ +pub struct BlockHash { + pub bytes: [u8; crate::constant::BLOCK_HASH_LENGTH], +} + +impl crate::utils::ToHex for BlockHash { + fn get_bytes(&self) -> &[u8] { + self.bytes.as_ref() + } +} diff --git a/src/blockchain/environment.rs b/src/blockchain/environment.rs index a7cd3ae..804614d 100644 --- a/src/blockchain/environment.rs +++ b/src/blockchain/environment.rs @@ -1,87 +1,63 @@ -use alloc::{format, string::ToString}; - -use crate::utils::ToHex; +use super::AddressHash; pub struct Environment { - pub sender: super::Address, - pub origin: super::Address, - pub transaction: [u8; crate::constant::TRANSACTION_HASH_LENGHT], - pub block_hash: [u8; crate::constant::BLOCK_HASH_LENGHT], - pub owner: super::Address, - pub address: super::Address, + pub sender: super::AddressHash, + pub origin: super::AddressHash, + pub transaction_hash: super::TransactionHash, + pub block_hash: super::BlockHash, + pub deployer: super::AddressHash, + pub address: super::AddressHash, pub timestamp: u64, pub safe_rnd: u64, } -impl ToString for Environment { - fn to_string(&self) -> alloc::string::String { - format!("Environment\n sender: {}, origin: {}, transaction: {:?}, block_hash: {:?}, owner: {}, address: {}, timestamp: {}, safe_rnd: {}", self.sender.to_hex(), self.origin.to_hex(), self.transaction, self.block_hash, self.owner.to_hex(), self.address.to_hex(), self.timestamp, self.safe_rnd) +impl Environment { + #[allow(clippy::too_many_arguments)] + pub fn new( + sender: AddressHash, + origin: AddressHash, + transaction_hash: super::TransactionHash, + block_hash: super::BlockHash, + deployer: AddressHash, + address: AddressHash, + timestamp: u64, + safe_rnd: u64, + ) -> Self { + Self { + sender, + origin, + transaction_hash, + block_hash, + deployer, + address, + timestamp, + safe_rnd, + } } } -#[cfg(test)] -mod tests { - use super::*; +#[allow(dead_code)] +#[cfg(not(target_arch = "wasm32"))] +mod display { + use crate::utils::{to_hex, ToHex}; + use core::fmt::Display; + + impl Display for super::Environment { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + use alloc::string::ToString; - #[test] - fn test_environment_decoding() { - let buffer = crate::mem::WaBuffer::from_bytes(&[ - 68, 102, 250, 135, 110, 248, 85, 140, 109, 85, 18, 71, 53, 174, 144, 79, 221, 222, 214, - 225, 179, 36, 87, 124, 87, 68, 62, 237, 41, 255, 124, 217, 68, 102, 250, 135, 110, 248, - 85, 140, 109, 85, 18, 71, 53, 174, 144, 79, 221, 222, 214, 225, 179, 36, 87, 124, 87, - 68, 62, 237, 41, 255, 124, 217, 71, 126, 176, 13, 215, 90, 186, 198, 64, 192, 122, 134, - 241, 188, 208, 24, 18, 40, 247, 207, 24, 222, 218, 124, 183, 138, 219, 244, 109, 179, - 19, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 68, 102, 250, 135, 110, 248, 85, 140, 109, 85, 18, 71, 53, 174, 144, - 79, 221, 222, 214, 225, 179, 36, 87, 124, 87, 68, 62, 237, 41, 255, 124, 217, 160, 10, - 9, 97, 12, 133, 130, 89, 89, 178, 82, 39, 219, 188, 247, 242, 177, 44, 196, 106, 249, - 60, 52, 210, 109, 42, 21, 191, 62, 6, 187, 249, 212, 188, 107, 254, 146, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - ]); - let environment = unsafe { buffer.into_type::().unwrap() }; - assert_eq!( - environment.sender.bytes, - [ - 68, 102, 250, 135, 110, 248, 85, 140, 109, 85, 18, 71, 53, 174, 144, 79, 221, 222, - 214, 225, 179, 36, 87, 124, 87, 68, 62, 237, 41, 255, 124, 217 - ] - ); - assert_eq!( - environment.origin.bytes, - [ - 68, 102, 250, 135, 110, 248, 85, 140, 109, 85, 18, 71, 53, 174, 144, 79, 221, 222, - 214, 225, 179, 36, 87, 124, 87, 68, 62, 237, 41, 255, 124, 217 - ] - ); - assert_eq!( - environment.transaction, - [ - 71, 126, 176, 13, 215, 90, 186, 198, 64, 192, 122, 134, 241, 188, 208, 24, 18, 40, - 247, 207, 24, 222, 218, 124, 183, 138, 219, 244, 109, 179, 19, 37 - ] - ); - assert_eq!( - environment.block_hash, - [ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1 - ] - ); - assert_eq!( - environment.owner.bytes, - [ - 68, 102, 250, 135, 110, 248, 85, 140, 109, 85, 18, 71, 53, 174, 144, 79, 221, 222, - 214, 225, 179, 36, 87, 124, 87, 68, 62, 237, 41, 255, 124, 217 - ] - ); - assert_eq!( - environment.address.bytes, - [ - 160, 10, 9, 97, 12, 133, 130, 89, 89, 178, 82, 39, 219, 188, 247, 242, 177, 44, - 196, 106, 249, 60, 52, 210, 109, 42, 21, 191, 62, 6, 187, 249 - ] - ); - assert_eq!(environment.timestamp, 1730845326548); - assert_eq!(environment.safe_rnd, 0); + f.debug_struct("Environment") + .field("sender", &self.sender.to_hex()) + .field("origin", &self.origin.to_hex()) + .field("transaction", &to_hex(&self.transaction_hash.bytes)) + .field("block_hash", &to_hex(&self.block_hash.bytes)) + .field("deployer", &self.deployer.to_hex()) + .field("address", &self.address.to_hex()) + .field("timestamp", &self.timestamp.to_string()) + .field("safe_rnd", &self.safe_rnd.to_string()) + .finish() + } } } + +impl Environment {} diff --git a/src/blockchain/mod.rs b/src/blockchain/mod.rs index 6379381..5b8825e 100644 --- a/src/blockchain/mod.rs +++ b/src/blockchain/mod.rs @@ -1,7 +1,9 @@ pub mod address; +pub mod block; pub mod environment; pub mod transaction; -pub use address::Address; +pub use address::AddressHash; +pub use block::BlockHash; pub use environment::Environment; -pub use transaction::Transaction; +pub use transaction::{Transaction, TransactionHash}; diff --git a/src/blockchain/transaction.rs b/src/blockchain/transaction.rs index 3e7b39c..38b4534 100644 --- a/src/blockchain/transaction.rs +++ b/src/blockchain/transaction.rs @@ -1,5 +1,26 @@ +pub struct TransactionHash { + pub bytes: [u8; crate::constant::TRANSACTION_HASH_LENGTH], +} +impl crate::utils::ToHex for TransactionHash { + fn get_bytes(&self) -> &[u8] { + self.bytes.as_ref() + } +} + pub struct Transaction { - pub sender: super::Address, - pub origin: super::Address, - pub hash: [u8; 32], + pub sender: super::AddressHash, + pub origin: super::AddressHash, + pub hash: TransactionHash, +} + +pub struct Output { + pub index: u8, + pub script_pub_key: [u8; 32], + pub value: u64, +} + +pub struct Input { + pub tx_id: [u8; 32], + pub output_index: u8, + pub script_sig: u8, } diff --git a/src/constant.rs b/src/constant.rs index 21d0fe5..ae30e64 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -1,3 +1,6 @@ -pub const ADDRESS_BYTE_LENGTH: usize = 32; -pub const TRANSACTION_HASH_LENGHT: usize = 32; -pub const BLOCK_HASH_LENGHT: usize = 32; +pub const HASH_SIZE: usize = 32; +pub const ADDRESS_BYTE_LENGTH: usize = HASH_SIZE; +pub const TRANSACTION_HASH_LENGTH: usize = HASH_SIZE; +pub const BLOCK_HASH_LENGTH: usize = HASH_SIZE; +pub const STORE_KEY_SIZE: usize = HASH_SIZE; +pub const STORE_VALUE_SIZE: usize = HASH_SIZE; diff --git a/src/contract/mod.rs b/src/contract/mod.rs index 8229185..f71d11e 100644 --- a/src/contract/mod.rs +++ b/src/contract/mod.rs @@ -1 +1,35 @@ +use crate::{blockchain::AddressHash, mem::WaBuffer, types::CallData}; + pub mod op_20; + +pub trait ContractTrait { + fn set_environment(&mut self, environment: &'static crate::blockchain::Environment); + + fn environment(&self) -> &'static crate::blockchain::Environment; + + fn is_self(&self, address: &AddressHash) -> bool { + address.eq(&self.environment().address) + } + + fn only_deployer(&self, caller: &AddressHash) -> Result<(), crate::error::Error> { + if self.environment().deployer.ne(caller) { + Err(crate::error::Error::OnlyOwner) + } else { + Ok(()) + } + } + + fn emit(event: &impl crate::event::EventTrait) -> Result<(), crate::error::Error> { + crate::env::emit(event.buffer()); + Ok(()) + } + + fn on_deploy(&mut self, _call_data: CallData) { + crate::log("On Deploy is not implemented"); + } + + fn execute(&mut self, _call_data: CallData) -> Result { + crate::log("Execute is not implemented"); + unimplemented!("Execute needs to be implemented"); + } +} diff --git a/src/contract/op_20.rs b/src/contract/op_20.rs index 127aaa5..0dd1535 100644 --- a/src/contract/op_20.rs +++ b/src/contract/op_20.rs @@ -1,3 +1,426 @@ -pub struct OP20Params {} +use ethnum::u256; -pub trait OP20Trait {} +use crate::{ + blockchain::AddressHash, + constant::ADDRESS_BYTE_LENGTH, + math::abi::encode_selector_const, + storage::{ + multi_address_map::MultiAddressMemoryMap, + stored::{StoredTrait, StoredU256, StoredU8}, + stored_map::StoredMap, + }, + types::{CallData, Selector}, + WaBuffer, +}; + +pub struct OP20Params { + pub max_supply: StoredU256, + pub decimals: StoredU8, + pub name: &'static str, + pub symbol: &'static str, +} + +#[repr(u16)] +pub enum Pointer { + MaxSupply = 1, + Decimals, + Name, + Symbol, + TotalSupply, + AllowanceMap, + BalanceOfMap, +} + +impl Pointer { + pub const fn u16(self) -> u16 { + self as u16 + } +} + +pub const SELECTOR_OWNER: Selector = encode_selector_const("owner"); +pub const SELECTOR_DECIMALS: Selector = encode_selector_const("decimals"); +pub const SELECTOR_NAME: Selector = encode_selector_const("name"); +pub const SELECTOR_SYMBOL: Selector = encode_selector_const("symbol"); +pub const SELECTOR_TOTAL_SUPPLY: Selector = encode_selector_const("totalSupply"); +pub const SELECTOR_MAXIMUM_SUPPLY: Selector = encode_selector_const("maximumSupply"); +pub const SELECTOR_ALLOWANCE: Selector = encode_selector_const("allowance"); +pub const SELECTOR_APPROVE: Selector = encode_selector_const("approve"); +pub const SELECTOR_BALANCE_OF: Selector = encode_selector_const("balanceOf"); +pub const SELECTOR_BURN: Selector = encode_selector_const("burn"); +pub const SELECTOR_TRANSFER: Selector = encode_selector_const("transfer"); +pub const SELECTOR_TRANSFER_FROM: Selector = encode_selector_const("transferFrom"); + +pub trait OP20Trait: super::ContractTrait { + fn execute_base( + &mut self, + selector: Selector, + call_data: crate::types::CallData, + ) -> Result { + match selector { + SELECTOR_OWNER => { + let mut buffer = WaBuffer::new(ADDRESS_BYTE_LENGTH, 2)?; + let mut cursor = buffer.cursor(); + cursor.write_address(&self.environment().deployer)?; + Ok(buffer) + } + SELECTOR_DECIMALS => { + let mut buffer = WaBuffer::new(1, 2)?; + let mut cursor = buffer.cursor(); + cursor.write_u8(self.decimals())?; + Ok(buffer) + } + SELECTOR_NAME => { + let name = self.name(); + let mut buffer = WaBuffer::new(name.len() + 2, 1)?; + let mut cursor = buffer.cursor(); + cursor.write_string_with_len(&name)?; + Ok(buffer) + } + SELECTOR_SYMBOL => { + let symbol = self.symbol(); + let mut buffer = WaBuffer::new(symbol.len() + 2, 1)?; + let mut cursor = buffer.cursor(); + cursor.write_string_with_len(&symbol)?; + Ok(buffer) + } + SELECTOR_TOTAL_SUPPLY => { + let mut buffer = WaBuffer::new(32, 1)?; + let mut cursor = buffer.cursor(); + cursor.write_u256_be(&self.total_supply().value())?; + Ok(buffer) + } + SELECTOR_MAXIMUM_SUPPLY => { + let mut buffer = WaBuffer::new(32, 1)?; + let mut cursor = buffer.cursor(); + cursor.write_u256_be(&self.max_supply())?; + Ok(buffer) + } + SELECTOR_ALLOWANCE => self.allowance(call_data), + SELECTOR_APPROVE => self.approve(call_data), + SELECTOR_BALANCE_OF => self.balance_of(call_data), + SELECTOR_BURN => self.burn(call_data), + SELECTOR_TRANSFER => self.transfer(call_data), + SELECTOR_TRANSFER_FROM => self.transfer_from(call_data), + _ => Err(crate::error::Error::UnknownSelector), + } + } + fn execute( + &mut self, + selector: Selector, + call_data: crate::types::CallData, + ) -> Result { + self.execute_base(selector, call_data) + } + + fn params(&mut self) -> &mut OP20Params; + fn total_supply(&mut self) -> &mut StoredU256; + + fn max_supply(&mut self) -> u256 { + self.params().max_supply.value() + } + fn decimals(&mut self) -> u8 { + self.params().decimals.value() + } + + fn name(&mut self) -> &'static str { + self.params().name + } + fn symbol(&mut self) -> &'static str { + self.params().symbol + } + + fn allowance_map(&mut self) -> &mut MultiAddressMemoryMap; + fn balance_of_map(&mut self) -> &mut StoredMap; + + fn allowance_base(&mut self, owner: &AddressHash, spender: &AddressHash) -> u256 { + let mut sender_map = self.allowance_map().get(owner); + sender_map.get(&spender.bytes).u256() + } + + fn allowance( + &mut self, + mut call_data: CallData, + ) -> Result { + let mut response = crate::WaBuffer::new(32, 1)?; + let mut cursor = response.cursor(); + let address_owner = call_data.read_address()?; + let address_spender = call_data.read_address()?; + let allowance = self.allowance_base(&address_owner, &address_spender); + + cursor.write_u256_be(&allowance)?; + Ok(response) + } + + fn approve_base( + &mut self, + owner: &AddressHash, + spender: &AddressHash, + value: u256, + ) -> Result { + if AddressHash::DEAD.eq(owner) { + return Err(crate::error::Error::DeadAddress); + } + + if AddressHash::DEAD.eq(spender) { + return Err(crate::error::Error::DeadAddress); + } + + let mut sender_map = self.allowance_map().get(owner); + sender_map.set(&spender.bytes, value.into()); + + Self::create_approve_event(*owner, *spender, value)?; + + Ok(true) + } + + fn approve(&mut self, mut call_data: CallData) -> Result { + let owner = self.environment().sender; + let spender = call_data.read_address()?; + let amount = call_data.read_u256_be()?; + + let mut response = crate::WaBuffer::new(32, 1)?; + let mut cursor = response.cursor(); + cursor.write_bool(self.approve_base(&owner, &spender, amount)?)?; + + Ok(response) + } + + fn balance_of_base(&mut self, address: &AddressHash) -> u256 { + self.balance_of_map().get(address, u256::ZERO).into() + } + + fn balance_of( + &mut self, + mut call_data: crate::types::CallData, + ) -> Result { + let mut response = WaBuffer::new(32, 1)?; + let mut cursor = response.cursor(); + let address = call_data.read_address()?; + let balance = self.balance_of_base(&address); + cursor.write_u256_be(&balance)?; + Ok(response) + } + + fn burn_base(&mut self, value: u256, only_deployer: bool) -> Result { + if value.eq(&u256::ZERO) { + return Err(crate::error::Error::NoTokens); + } + + if only_deployer { + self.only_deployer(&self.environment().sender)?; + } + + let total_supply = self.total_supply().value(); + if total_supply < value { + return Err(crate::error::Error::InsufficientTotalSupply); + } + + let sender = self.environment().sender; + if !self.balance_of_map().contains_key(&sender) { + return Err(crate::error::Error::NoBalance); + } + + let balance: u256 = self.balance_of_map().get(&sender, u256::ZERO).u256(); + if balance < value { + return Err(crate::error::Error::InsufficientBalance); + } + + let new_balance = balance - value; + self.balance_of_map().set(&sender, new_balance); + + Self::create_burn_event(self.total_supply().set(total_supply - value))?; + + Ok(true) + } + + fn burn( + &mut self, + mut call_data: crate::types::CallData, + ) -> Result { + let mut response = WaBuffer::new(1, 1)?; + let mut cursor = response.cursor(); + let amount = call_data.read_u256_be()?; + + cursor.write_bool(self.burn_base(amount, true)?)?; + Ok(response) + } + + fn mint_base( + &mut self, + to: &AddressHash, + value: u256, + only_deployer: bool, + ) -> Result { + if only_deployer { + self.only_deployer(&self.environment().sender)?; + } + + if !self.balance_of_map().contains_key(to) { + self.balance_of_map().set(to, value); + } else { + let to_balance = self.balance_of_map().get(to, u256::ZERO).u256(); + self.balance_of_map().set(to, to_balance + value); + } + + let old = self.total_supply().value(); + let new = old + value; + + if new > self.max_supply() { + return Err(crate::error::Error::MaxSupplyReached); + } + self.total_supply().set(new); + + Self::create_mint_event(*to, value)?; + + Ok(true) + } + + fn transfer_base( + &mut self, + to: &AddressHash, + value: u256, + ) -> Result { + let sender = self.environment().sender; + if self.is_self(&sender) { + return Err(crate::error::Error::CanNotTransferFromSelfAccount); + } + + if value == u256::ZERO { + return Err(crate::error::Error::CannotTransferZeroTokens); + } + + let balance = self.balance_of_map().get(&sender, u256::ZERO).u256(); + + if balance < value { + return Err(crate::error::Error::InsufficientBalance); + } + let new_balance = balance - value; + self.balance_of_map().set(&sender, new_balance); + + let balance = self.balance_of_map().get(to, u256::ZERO).u256(); + let new_balance = balance + value; + self.balance_of_map().set(to, new_balance); + + Self::create_transfer_event(sender, *to, value)?; + Ok(true) + } + + fn transfer( + &mut self, + mut call_data: crate::types::CallData, + ) -> Result { + let mut response = WaBuffer::new(1, 1)?; + let mut cursor = response.cursor(); + let address = call_data.read_address()?; + let amount = call_data.read_u256_be()?; + let result = self.transfer_base(&address, amount)?; + + cursor.write_bool(result)?; + Ok(response) + } + + fn spend_allowance( + &mut self, + deployer: &AddressHash, + spender: &AddressHash, + value: u256, + ) -> Result<(), crate::error::Error> { + let mut deployer_allowance_map = self.allowance_map().get(deployer); + let allowed: u256 = deployer_allowance_map.get(&spender.bytes).u256(); + + if allowed < value { + return Err(crate::error::Error::InsufficientAllowance); + } + + let new_allowance = allowed - value; + deployer_allowance_map.set(&spender.bytes, new_allowance.into()); + self.allowance_map().set(*deployer, deployer_allowance_map); + Ok(()) + } + + fn transfer_from_unsafe( + &mut self, + from: &AddressHash, + to: &AddressHash, + value: u256, + ) -> Result { + let balance: u256 = self.balance_of_map().get(from, u256::ZERO).u256(); + if balance < value { + return Err(crate::error::Error::InsufficientBalance); + } + + let new_balance = balance - value; + self.balance_of_map().set(from, new_balance); + + if !self.balance_of_map().contains_key(to) { + self.balance_of_map().set(to, value); + } else { + let to_balance: u256 = self.balance_of_map().get(to, u256::ZERO).u256(); + let new_to_balance = to_balance + value; + self.balance_of_map().set(to, new_to_balance); + } + + Self::create_transfer_event(*from, *to, value)?; + + Ok(true) + } + + fn transfer_from_base( + &mut self, + from: &AddressHash, + to: &AddressHash, + value: u256, + ) -> Result { + if AddressHash::DEAD.eq(from) || AddressHash::DEAD.eq(to) { + return Err(crate::error::Error::DeadAddress); + } + + self.spend_allowance(from, &self.environment().sender, value)?; + self.transfer_from_unsafe(from, to, value)?; + Ok(true) + } + + fn transfer_from( + &mut self, + mut call_data: crate::types::CallData, + ) -> Result { + let mut response = WaBuffer::new(1, 1)?; + let mut cursor = response.cursor(); + + let address_from = call_data.read_address()?; + let address_to = call_data.read_address()?; + let amount = call_data.read_u256_be()?; + cursor.write_bool(self.transfer_from_base(&address_from, &address_to, amount)?)?; + + Ok(response) + } + + fn create_burn_event(value: u256) -> Result<(), crate::error::Error> { + let burn_event = crate::event::Event::burn(value)?; + + Self::emit(&burn_event) + } + + fn create_approve_event( + deployer: AddressHash, + spender: AddressHash, + value: u256, + ) -> Result<(), crate::error::Error> { + let approve_event = crate::event::Event::approve(deployer, spender, value)?; + Self::emit(&approve_event) + } + + fn create_mint_event(deployer: AddressHash, amount: u256) -> Result<(), crate::error::Error> { + let mint_event = crate::event::Event::mint(deployer, amount)?; + Self::emit(&mint_event) + } + + fn create_transfer_event( + from: AddressHash, + to: AddressHash, + amount: u256, + ) -> Result<(), crate::error::Error> { + let transfer_event = crate::event::Event::transfer(from, to, amount)?; + Self::emit(&transfer_event) + } +} diff --git a/src/cursor/mod.rs b/src/cursor/mod.rs new file mode 100644 index 0000000..01edca8 --- /dev/null +++ b/src/cursor/mod.rs @@ -0,0 +1,68 @@ +use crate::WaBuffer; + +pub mod reader; +pub mod writer; + +pub struct Cursor { + inner: &'static mut [u8], + reader: usize, + writer: usize, +} + +impl Cursor { + pub fn from_slice(inner: &'static mut [u8]) -> Cursor { + Cursor { + reader: 0, + writer: 0, + inner, + } + } + + pub fn into_inner(self) -> &'static [u8] { + self.inner + } + + pub fn read_pos(&self) -> usize { + self.reader + } + + pub fn write_pos(&self) -> usize { + self.writer + } + + pub fn reset(&mut self) { + self.reader = 0; + self.writer = 0; + } + + pub fn get_buffer(&self) -> Result { + WaBuffer::from_bytes(self.inner) + } +} + +#[cfg(test)] +mod tests { + use ethnum::u256; + + #[test] + fn test_reader() -> Result<(), crate::error::Error> { + let mem = alloc::boxed::Box::new([0; 256]); + let mut cursor = super::Cursor::from_slice(alloc::boxed::Box::leak(mem)); + + cursor.write_u8(1)?; + cursor.write_u16_le(&2)?; + cursor.write_u32_le(&3)?; + cursor.write_u64_le(&4)?; + cursor.write_u128_le(&5)?; + cursor.write_u256_be(&u256::new(6))?; + + assert_eq!(cursor.read_u8()?, 1); + assert_eq!(cursor.read_u16_le()?, 2); + assert_eq!(cursor.read_u32_le()?, 3); + assert_eq!(cursor.read_u64_le()?, 4); + assert_eq!(cursor.read_u128_le()?, 5); + assert_eq!(cursor.read_u256_be()?, u256::new(6)); + + Ok(()) + } +} diff --git a/src/cursor/reader.rs b/src/cursor/reader.rs new file mode 100644 index 0000000..954b18b --- /dev/null +++ b/src/cursor/reader.rs @@ -0,0 +1,130 @@ +use crate::{blockchain::AddressHash, storage::map::Map, types::Selector}; +use ethnum::u256; + +impl super::Cursor { + pub fn read_u32_le_unchecked(&mut self) -> u32 { + self.reader += 4; + u32::from_le_bytes(self.inner[self.reader - 4..self.reader].try_into().unwrap()) + } + + pub fn read_u8(&mut self) -> Result { + if self.reader < self.inner.len() { + let result = self.inner[self.reader]; + self.reader += 1; + Ok(result) + } else { + Err(crate::error::Error::NoMoreData) + } + } + + pub fn read_u16_le(&mut self) -> Result { + if self.reader + 2 <= self.inner.len() { + let result = + u16::from_le_bytes(self.inner[self.reader..self.reader + 2].try_into().unwrap()); + self.reader += 2; + Ok(result) + } else { + Err(crate::error::Error::NoMoreData) + } + } + + pub fn read_u32_le(&mut self) -> Result { + if self.reader + 4 <= self.inner.len() { + let result = + u32::from_le_bytes(self.inner[self.reader..self.reader + 4].try_into().unwrap()); + self.reader += 4; + Ok(result) + } else { + Err(crate::error::Error::NoMoreData) + } + } + + pub fn read_u64_le(&mut self) -> Result { + if self.reader + 8 <= self.inner.len() { + let result = + u64::from_le_bytes(self.inner[self.reader..self.reader + 8].try_into().unwrap()); + self.reader += 8; + Ok(result) + } else { + Err(crate::error::Error::NoMoreData) + } + } + + pub fn read_u128_le(&mut self) -> Result { + if self.reader + 16 <= self.inner.len() { + let result = u128::from_le_bytes( + self.inner[self.reader..self.reader + 16] + .try_into() + .unwrap(), + ); + self.reader += 16; + Ok(result) + } else { + Err(crate::error::Error::NoMoreData) + } + } + + pub fn read_u256_be(&mut self) -> Result { + if self.reader + 32 <= self.inner.len() { + let result = u256::from_be_bytes( + self.inner[self.reader..self.reader + 32] + .try_into() + .unwrap(), + ); + self.reader += 32; + Ok(result) + } else { + Err(crate::error::Error::NoMoreData) + } + } + + pub fn read_u256_le(&mut self) -> Result { + if self.reader + 32 <= self.inner.len() { + let result = u256::from_le_bytes( + self.inner[self.reader..self.reader + 32] + .try_into() + .unwrap(), + ); + self.reader += 32; + Ok(result) + } else { + Err(crate::error::Error::NoMoreData) + } + } + + pub fn read_bool(&mut self) -> Result { + Ok((self.read_u8()?) != 0) + } + + pub fn read_selector(&mut self) -> Result { + self.read_u32_le() + } + + pub fn read_bytes(&mut self, size: usize) -> Result<&[u8], crate::error::Error> { + if self.reader + size <= self.inner.len() { + let result = &self.inner[self.reader..self.reader + size]; + self.reader += size; + Ok(result) + } else { + Err(crate::error::Error::NoMoreData) + } + } + + pub fn read_address(&mut self) -> Result { + Ok(AddressHash::new( + self.read_bytes(crate::constant::ADDRESS_BYTE_LENGTH)?, + )) + } + + pub fn read_address_value_map( + &mut self, + ) -> Result, crate::error::Error> { + let len = self.read_u16_le()?; + let mut result = Map::new(); + + for _ in 0..len { + result.insert(self.read_address()?, self.read_u256_be()?); + } + Ok(result) + } +} diff --git a/src/cursor/writer.rs b/src/cursor/writer.rs new file mode 100644 index 0000000..ccbabb7 --- /dev/null +++ b/src/cursor/writer.rs @@ -0,0 +1,128 @@ +use ethnum::u256; + +use crate::{blockchain::AddressHash, constant::ADDRESS_BYTE_LENGTH, types::Selector}; + +impl super::Cursor { + pub fn write_u8(&mut self, val: u8) -> Result<(), crate::error::Error> { + if self.writer < self.inner.len() { + self.inner[self.writer] = val; + self.writer += 1; + Ok(()) + } else { + Err(crate::error::Error::BufferIsFull) + } + } + + pub fn write_u16_le(&mut self, val: &u16) -> Result<(), crate::error::Error> { + if self.writer + 2 <= self.inner.len() { + self.inner[self.writer..self.writer + 2].copy_from_slice(&val.to_le_bytes()); + self.writer += 2; + Ok(()) + } else { + Err(crate::error::Error::BufferIsFull) + } + } + + pub fn write_u32_le(&mut self, val: &u32) -> Result<(), crate::error::Error> { + if self.writer + 4 <= self.inner.len() { + self.inner[self.writer..self.writer + 4].copy_from_slice(&val.to_le_bytes()); + self.writer += 4; + Ok(()) + } else { + Err(crate::error::Error::BufferIsFull) + } + } + + pub fn write_u64_le(&mut self, val: &u64) -> Result<(), crate::error::Error> { + if self.writer + 8 <= self.inner.len() { + self.inner[self.writer..self.writer + 8].copy_from_slice(&val.to_le_bytes()); + self.writer += 8; + Ok(()) + } else { + Err(crate::error::Error::BufferIsFull) + } + } + + pub fn write_u128_le(&mut self, val: &u128) -> Result<(), crate::error::Error> { + if self.writer + 16 <= self.inner.len() { + self.inner[self.writer..self.writer + 16].copy_from_slice(&val.to_le_bytes()); + self.writer += 16; + Ok(()) + } else { + Err(crate::error::Error::BufferIsFull) + } + } + + pub fn write_u256_le(&mut self, val: &u256) -> Result<(), crate::error::Error> { + if self.writer + 32 <= self.inner.len() { + self.inner[self.writer..self.writer + 32].copy_from_slice(&val.to_le_bytes()); + self.writer += 32; + Ok(()) + } else { + Err(crate::error::Error::BufferIsFull) + } + } + + pub fn write_u256_be(&mut self, val: &u256) -> Result<(), crate::error::Error> { + if self.writer + 32 <= self.inner.len() { + self.inner[self.writer..self.writer + 32].copy_from_slice(&val.to_be_bytes()); + self.writer += 32; + Ok(()) + } else { + Err(crate::error::Error::BufferIsFull) + } + } + + pub fn write_bool(&mut self, val: bool) -> Result<(), crate::error::Error> { + self.write_u8(val.into()) + } + + pub fn write_selector(&mut self, selector: &Selector) -> Result<(), crate::error::Error> { + self.write_u32_le(selector) + } + + pub fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), crate::error::Error> { + if self.writer + bytes.len() <= self.inner.len() { + self.inner[self.writer..self.writer + bytes.len()].copy_from_slice(bytes); + self.writer += bytes.len(); + Ok(()) + } else { + Err(crate::error::Error::BufferIsFull) + } + } + + pub fn write_bytes_with_len(&mut self, bytes: &[u8]) -> Result<(), crate::error::Error> { + if self.writer + bytes.len() + 4 <= self.inner.len() { + self.write_u32_le(&(bytes.len() as u32))?; + self.write_bytes(bytes) + } else { + Err(crate::error::Error::BufferIsFull) + } + } + + pub fn write_string(&mut self, string: &str) -> Result<(), crate::error::Error> { + if self.writer + string.len() <= self.inner.len() { + self.write_bytes(string.as_bytes()) + } else { + Err(crate::error::Error::BufferIsFull) + } + } + + pub fn write_string_with_len(&mut self, string: &str) -> Result<(), crate::error::Error> { + let bytes = string.as_bytes(); + if self.writer + bytes.len() + 2 <= self.inner.len() { + self.write_u16_le(&(bytes.len() as u16))?; + self.write_bytes(bytes) + } else { + Err(crate::error::Error::BufferIsFull) + } + } + + pub fn write_address(&mut self, address: &AddressHash) -> Result<(), crate::error::Error> { + if self.writer + ADDRESS_BYTE_LENGTH <= self.inner.len() { + self.write_bytes(&address.bytes) + } else { + Err(crate::error::Error::BufferIsFull) + } + } +} diff --git a/src/env/address.rs b/src/env/address.rs new file mode 100644 index 0000000..c0614e5 --- /dev/null +++ b/src/env/address.rs @@ -0,0 +1,12 @@ +#[cfg(target_arch = "wasm32")] +pub fn validate_bitcoin_address(address: &str) -> Result { + let mut buffer = crate::WaBuffer::new(address.len(), 1)?; + let mut cursor = buffer.cursor(); + cursor.write_string(address)?; + + unsafe { + crate::WaBuffer::from_raw(super::global::validateBitcoinAddress(buffer.ptr())) + .cursor() + .read_bool() + } +} diff --git a/src/env/global.rs b/src/env/global.rs index 67d8d09..cb0d3dc 100644 --- a/src/env/global.rs +++ b/src/env/global.rs @@ -1,12 +1,37 @@ -pub struct Block {} +use crate::mem::WaPtr; -pub struct Transaction {} +#[cfg(target_arch = "wasm32")] +#[link(wasm_import_module = "env")] +extern "C" { + #[allow(dead_code)] + pub fn load(ptr: WaPtr) -> WaPtr; + #[allow(dead_code)] + pub fn store(ptr: WaPtr) -> WaPtr; -pub struct Contract {} -pub struct BlockChainEnvironment { - pub block: Block, - pub transaction: Transaction, - pub contract: Contract, -} + #[allow(dead_code)] + pub fn nextPointerGreaterThan(ptr: WaPtr) -> WaPtr; + + #[allow(dead_code)] + pub fn deploy(ptr: WaPtr) -> WaPtr; + #[allow(dead_code)] + pub fn deployFromAddress(ptr: WaPtr) -> WaPtr; -pub static mut ENVIRONMENT: Option = None; + #[allow(dead_code)] + pub fn call(ptr: WaPtr) -> WaPtr; + #[allow(dead_code)] + pub fn log(ptr: WaPtr); + #[allow(dead_code)] + pub fn emit(ptr: WaPtr); + #[allow(dead_code)] + pub fn encodeAddress(ptr: WaPtr) -> WaPtr; + #[allow(dead_code)] + pub fn validateBitcoinAddress(ptr: WaPtr) -> WaPtr; + #[allow(dead_code)] + pub fn sha256(ptr: WaPtr) -> WaPtr; + #[allow(dead_code)] + pub fn ripemd160(ptr: WaPtr) -> WaPtr; + #[allow(dead_code)] + pub fn inputs() -> WaPtr; + #[allow(dead_code)] + pub fn outputs() -> WaPtr; +} diff --git a/src/env/mod.rs b/src/env/mod.rs index cdcd83a..6dc33e8 100644 --- a/src/env/mod.rs +++ b/src/env/mod.rs @@ -1 +1,32 @@ -pub mod global; +use crate::mem::WaBuffer; +#[allow(unused_imports)] +use core::str::FromStr; + +mod address; +mod global; +mod sha; +mod store; + +pub use address::*; +pub use sha::*; +pub use store::*; + +#[cfg(target_arch = "wasm32")] +pub fn log(text: &str) { + unsafe { + if let Ok(string) = WaBuffer::from_str(text) { + global::log(string.ptr()); + } + } +} + +#[cfg(not(target_arch = "wasm32"))] +pub fn log(text: &str) {} + +#[cfg(target_arch = "wasm32")] +pub fn emit(buffer: WaBuffer) { + unsafe { global::emit(buffer.ptr()) } +} + +#[cfg(not(target_arch = "wasm32"))] +pub fn emit(buffer: WaBuffer) {} diff --git a/src/env/sha.rs b/src/env/sha.rs new file mode 100644 index 0000000..e63307b --- /dev/null +++ b/src/env/sha.rs @@ -0,0 +1,55 @@ +#[allow(unused_imports)] +use crate::WaBuffer; + +#[cfg(target_arch = "wasm32")] +pub fn sha256(bytes: &[u8]) -> Result<&'static [u8], crate::error::Error> { + unsafe { + Ok(WaBuffer::from_raw(super::global::sha256(WaBuffer::from_bytes(bytes)?.ptr())).data()) + } +} + +#[cfg(not(target_arch = "wasm32"))] +pub fn sha256(bytes: &[u8]) -> Result<&'static [u8], crate::error::Error> { + let sha = alloc::boxed::Box::new(sha2_const::Sha256::new().update(bytes).finalize()); + Ok(alloc::boxed::Box::leak(sha)) +} + +#[cfg(target_arch = "wasm32")] +pub fn sha256_double(bytes: &[u8]) -> Result<&'static [u8], crate::error::Error> { + unsafe { + let first = super::global::sha256(WaBuffer::from_bytes(bytes)?.ptr()); + let second = super::global::sha256(first); + Ok(WaBuffer::from_raw(second).data()) + } +} +#[cfg(not(target_arch = "wasm32"))] +pub fn sha256_double(bytes: &[u8]) -> Result<&'static [u8], crate::error::Error> { + let first = sha2_const::Sha256::new().update(bytes).finalize(); + let second = sha2_const::Sha256::new().update(&first).finalize(); + Ok(alloc::boxed::Box::leak(alloc::boxed::Box::new(second))) +} + +#[cfg(test)] +mod tests { + #[test] + fn test_sha_256() { + let text = "Hello world"; + assert_eq!( + crate::utils::to_hex(super::sha256(text.as_bytes()).unwrap()), + alloc::string::String::from( + "0x64ec88ca00b268e5ba1a35678a1b5316d212f4f366b2477232534a8aeca37f3c" + ) + ); + } + + #[test] + fn test_sha_256_double() { + let text = "Hello world"; + assert_eq!( + crate::utils::to_hex(super::sha256_double(text.as_bytes()).unwrap()), + alloc::string::String::from( + "0xf6dc724d119649460e47ce719139e521e082be8a9755c5bece181de046ee65fe" + ) + ); + } +} diff --git a/src/env/store.rs b/src/env/store.rs new file mode 100644 index 0000000..0e01ca6 --- /dev/null +++ b/src/env/store.rs @@ -0,0 +1,82 @@ +#[allow(unused_imports)] +use crate::{ + storage::{map::Map, StorageKey, StorageValue}, + WaBuffer, +}; + +#[allow(dead_code)] +#[cfg(not(target_arch = "wasm32"))] +static mut STORAGE: Map = Map::new(); + +#[cfg(target_arch = "wasm32")] +pub fn pointer_store(key: &StorageKey, value: &StorageValue) -> Result { + let mut buffer = WaBuffer::new(64, 1)?; + let mut cursor = buffer.cursor(); + + cursor.write_bytes(key)?; + cursor.write_bytes(value.bytes())?; + + unsafe { + WaBuffer::from_raw(super::global::store(buffer.ptr())) + .cursor() + .read_bool() + } +} + +/** + * For unit test only + */ +#[cfg(not(target_arch = "wasm32"))] +pub fn pointer_store(key: &StorageKey, value: &StorageValue) -> Result { + unsafe { STORAGE.insert(*key, *value) }; + Ok(true) +} + +#[cfg(target_arch = "wasm32")] +pub fn pointer_load(key: &StorageKey) -> Result { + let mut buffer = WaBuffer::new(32, 1)?; + let mut cursor = buffer.cursor(); + + cursor.write_bytes(key)?; + unsafe { + let value: StorageValue = WaBuffer::from_raw(super::global::load(buffer.ptr())) + .data() + .into(); + Ok(value) + } +} +#[cfg(not(target_arch = "wasm32"))] +#[allow(static_mut_refs)] +pub fn pointer_load(key: &StorageKey) -> Result { + unsafe { Ok(*STORAGE.get(key).unwrap_or(&StorageValue::ZERO)) } +} + +#[cfg(not(target_arch = "wasm32"))] +#[allow(static_mut_refs)] +pub fn pointer_storage_reset() { + unsafe { + STORAGE.clear(); + } +} + +/* +pub fn pointer_next_greater_than( + target_pointer: &StorageKey, + value_at_least: &StorageValue, + lte: bool, +) -> Result { + let mut buffer = WaBuffer::new(64, 1)?; + let mut cursor = buffer.cursor(); + cursor.write_bytes(target_pointer)?; + cursor.write_bytes(value_at_least.bytes())?; + cursor.write_bool(lte)?; + + unsafe { + Ok( + WaBuffer::from_raw(super::global::nextPointerGreaterThan(buffer.ptr())) + .data() + .into(), + ) + } +} + */ diff --git a/src/error.rs b/src/error.rs new file mode 100644 index 0000000..afa130c --- /dev/null +++ b/src/error.rs @@ -0,0 +1,51 @@ +use core::fmt::Debug; + +pub enum Error { + NoMoreData, + BufferIsFull, + UnknownSelector, + DuplicateKey, + DeadAddress, + InsufficientTotalSupply, + NoBalance, + InsufficientBalance, + MaxSupplyReached, + CanNotTransferFromSelfAccount, + CannotTransferZeroTokens, + OnlyOwner, + NoTokens, + InsufficientAllowance, + + Test, + + Extra(&'static str), +} + +impl Error { + pub fn as_str(&self) -> &'static str { + match self { + Self::NoMoreData => "No more data", + Self::BufferIsFull => "Buffer is full", + Self::UnknownSelector => "Unknown selector", + Self::DuplicateKey => "Duplicate key", + Self::DeadAddress => "Dead address", + Self::InsufficientTotalSupply => "InsufficientTotalSupply", + Self::NoBalance => "No balance", + Self::InsufficientBalance => "Insufficient balance", + Self::MaxSupplyReached => "Max supply reached", + Self::CanNotTransferFromSelfAccount => "CanNotTransferFromSelfAccount", + Self::CannotTransferZeroTokens => "CannotTransferZeroTokens", + Self::OnlyOwner => "OnlyOwner", + Self::NoTokens => "NoTokens", + Self::InsufficientAllowance => "InsufficientAllowance", + Self::Test => "Test", + Self::Extra(err) => err, + } + } +} + +impl Debug for Error { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct(&self.as_str()).finish() + } +} diff --git a/src/event/mod.rs b/src/event/mod.rs new file mode 100644 index 0000000..ddfa569 --- /dev/null +++ b/src/event/mod.rs @@ -0,0 +1,125 @@ +use crate::{blockchain::AddressHash, constant::ADDRESS_BYTE_LENGTH, WaBuffer}; +use ethnum::u256; + +pub trait EventTrait { + fn buffer(&self) -> WaBuffer; +} + +pub struct Event { + buffer: WaBuffer, +} + +impl Event { + pub fn approve( + owner: AddressHash, + spender: AddressHash, + value: u256, + ) -> Result { + let event_type = "Approve"; + let byte_size = ADDRESS_BYTE_LENGTH * 2 + 32; + let mut buffer = WaBuffer::new(event_type.len() + 6 + byte_size, 1)?; + let mut cursor = buffer.cursor(); + + cursor.write_string_with_len(event_type)?; + cursor.write_u32_le(&(byte_size as u32))?; + cursor.write_address(&owner)?; + cursor.write_address(&spender)?; + cursor.write_u256_be(&value)?; + + Ok(Event { buffer }) + } + + pub fn burn(amount: u256) -> Result { + let event_type = "Burn"; + let byte_size = 32; + let mut buffer = WaBuffer::new(event_type.len() + 6 + byte_size, 1)?; + let mut cursor = buffer.cursor(); + + cursor.write_string_with_len(event_type)?; + cursor.write_u32_le(&(byte_size as u32))?; + cursor.write_u256_be(&amount)?; + + Ok(Event { buffer }) + } + + pub fn claim(amount: u256) -> Result { + let event_type = "Claim"; + let byte_size = 32; + let mut buffer = WaBuffer::new(event_type.len() + 6 + byte_size, 1)?; + let mut cursor = buffer.cursor(); + + cursor.write_string_with_len(event_type)?; + cursor.write_u32_le(&(byte_size as u32))?; + cursor.write_u256_be(&amount)?; + + Ok(Event { buffer }) + } + + pub fn mint(address: AddressHash, amount: u256) -> Result { + let event_type = "Mint"; + let byte_size = 32 + ADDRESS_BYTE_LENGTH; + let mut buffer = WaBuffer::new(event_type.len() + 6 + byte_size, 1)?; + let mut cursor = buffer.cursor(); + + cursor.write_string_with_len(event_type)?; + cursor.write_u32_le(&(byte_size as u32))?; + cursor.write_address(&address)?; + cursor.write_u256_be(&amount)?; + + Ok(Event { buffer }) + } + + pub fn stake(amount: u256) -> Result { + let event_type = "Stake"; + let byte_size = 32; + let mut buffer = WaBuffer::new(event_type.len() + 6 + byte_size, 1)?; + let mut cursor = buffer.cursor(); + + cursor.write_string_with_len(event_type)?; + cursor.write_u32_le(&(byte_size as u32))?; + cursor.write_u256_be(&amount)?; + + Ok(Event { buffer }) + } + + pub fn unstake(amount: u256) -> Result { + let event_type = "Unstake"; + let byte_size = 32; + let mut buffer = WaBuffer::new(event_type.len() + 6 + byte_size, 1)?; + let mut cursor = buffer.cursor(); + + cursor.write_string_with_len(event_type)?; + cursor.write_u32_le(&(byte_size as u32))?; + cursor.write_u256_be(&amount)?; + + Ok(Event { buffer }) + } + + pub fn transfer( + addr_from: AddressHash, + addr_to: AddressHash, + amount: u256, + ) -> Result { + let event_type = "Transfer"; + + let byte_size = ADDRESS_BYTE_LENGTH * 2 + 32; + let mut buffer = WaBuffer::new(event_type.len() + 6 + byte_size, 1)?; + let mut cursor = buffer.cursor(); + + cursor.write_string_with_len(event_type)?; + + cursor.write_u32_le(&(byte_size as u32))?; + + cursor.write_address(&addr_from)?; + cursor.write_address(&addr_to)?; + cursor.write_u256_be(&amount)?; + + Ok(Event { buffer }) + } +} + +impl EventTrait for Event { + fn buffer(&self) -> WaBuffer { + self.buffer.clone() + } +} diff --git a/src/lib.rs b/src/lib.rs index c41ef55..2b8f01b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,20 +1,32 @@ #![no_std] -use alloc::{format, string::ToString}; -use blockchain::transaction; -use mem::{WaBuffer, WaCell, WaPtr}; -use utils::ToHex; +#![feature(const_for)] +#![feature(const_trait_impl)] extern crate alloc; -#![no_std] -extern crate alloc; - -pub mod allocator; +pub mod blockchain; pub mod constant; pub mod contract; +pub mod cursor; pub mod env; -pub mod mem; +pub mod error; +pub mod event; +pub mod math; +mod mem; +pub mod prelude; +pub mod storage; +pub mod types; pub mod utils; +pub use crate::mem::WaBuffer; +pub use env::*; +pub use ethnum; +pub use utils::*; + +pub use contract::{ + op_20::{OP20Params, OP20Trait}, + ContractTrait, +}; + #[cfg(not(test))] #[cfg(not(feature = "std"))] #[cfg(target_arch = "wasm32")] @@ -22,64 +34,3 @@ pub mod utils; fn panic(_panic: &core::panic::PanicInfo<'_>) -> ! { core::arch::wasm32::unreachable() } - -#[link(wasm_import_module = "env")] -extern "C" { - pub fn log(buffer: WaPtr); -} - -pub fn log_str(text: &str) { - unsafe { - let string = WaBuffer::from_str(text); - log(string.ptr()); - } -} - -#[no_mangle] -pub fn execute(ptr: WaPtr) -> WaPtr { - let buffer = WaBuffer::from_raw(ptr); - log_str(&alloc::format!("Execute: {:?}", buffer.data())); - buffer.to_raw() -} - -#[no_mangle] -#[export_name = "setEnvironment"] -pub fn set_environment(ptr: WaPtr) { - let buffer = WaBuffer::from_raw(ptr); - log_str(&alloc::format!("Set environment: {:?}", buffer.data())); - unsafe { - let environment: &mut crate::blockchain::Environment = buffer.into_type().unwrap(); - - log_str(&environment.to_string()); - } -} - -#[no_mangle] -#[export_name = "onDeploy"] -pub fn on_deploy(ptr: WaPtr) { - let buffer = WaBuffer::from_raw(ptr); - //log_str(&format!("On deploy: {:?}", buffer.data())); -} - -#[no_mangle] -#[export_name = "__new"] -pub fn new(size: usize, id: u32) -> WaPtr { - log_str(&format!("__new: {} {}", size, id)); - WaCell::new(size, id).to_raw() -} - -#[no_mangle] -#[export_name = "__pin"] -pub fn pin(ptr: WaPtr) -> WaPtr { - //let cell = WaCell::from_raw(ptr); - //log_str(&format!("Pin: {}, {:?}", ptr, cell.data())); - //WaCell::from_raw(ptr).to_raw() - ptr -} - -#[no_mangle] -#[export_name = "__unpin"] -pub fn unpin(ptr: WaPtr) { - //let cell = WaCell::from_raw(ptr); - //log_str(&format!("Unpin: {}, {:?}", ptr, cell.data())); -} diff --git a/src/math/abi.rs b/src/math/abi.rs index e69de29..16f42dc 100644 --- a/src/math/abi.rs +++ b/src/math/abi.rs @@ -0,0 +1,63 @@ +use crate::{sha256, storage::StorageKey}; +/** + * Encode selector in static build time + */ +pub const fn encode_selector_const(selector: &str) -> crate::types::Selector { + let bytes = sha2_const::Sha256::new() + .update(selector.as_bytes()) + .finalize(); + + ((bytes[3] as u32) << 24) + | ((bytes[2] as u32) << 16) + | ((bytes[1] as u32) << 8) + | (bytes[0] as u32) +} + +/** + * Encode selector in the runtime + */ +pub fn encode_selector(selector: &str) -> crate::types::Selector { + super::bytes::bytes4( + crate::env::sha256(selector.as_bytes()) + .unwrap() + .try_into() + .unwrap(), + ) +} + +pub const fn encode_pointer_const(unique_identifier: u16) -> StorageKey { + let mut key = [0; crate::constant::STORE_KEY_SIZE]; + key[0] = (unique_identifier & 0xff) as u8; + key[1] = ((unique_identifier >> 8) & 0xff) as u8; + key +} + +pub fn encode_pointer(unique_identifier: u16, typed: &[u8]) -> StorageKey { + let hash = if typed.len() != 32 { + sha256(typed).unwrap() + } else { + typed + }; + + let mut final_pointer: [u8; 32] = [0; 32]; + final_pointer[0] = (unique_identifier & 0xff) as u8; + final_pointer[1] = ((unique_identifier >> 8) & 0xff) as u8; + + /* + for i in 0..30 { + // drop the last two bytes + final_pointer[i + 2] = hash[i]; + } + */ + final_pointer[2..32].copy_from_slice(&hash[..30]); + + final_pointer +} + +#[cfg(test)] +mod tests { + #[test] + fn test_encode_selector() { + let selector = "Abi"; + } +} diff --git a/src/math/bytes.rs b/src/math/bytes.rs index e69de29..ee94e56 100644 --- a/src/math/bytes.rs +++ b/src/math/bytes.rs @@ -0,0 +1,13 @@ +use ethnum::u256; + +pub const fn bytes4(bytes: [u8; 4]) -> u32 { + u32::from_le_bytes(bytes) +} + +pub const fn bytes8(bytes: [u8; 8]) -> u64 { + u64::from_le_bytes(bytes) +} + +pub fn bytes32(bytes: [u8; 32]) -> u256 { + u256::from_le_bytes(bytes) +} diff --git a/src/math/mod.rs b/src/math/mod.rs index e69de29..e13f9ed 100644 --- a/src/math/mod.rs +++ b/src/math/mod.rs @@ -0,0 +1,2 @@ +pub mod abi; +pub mod bytes; diff --git a/src/mem.rs b/src/mem.rs index d926aca..299c28a 100644 --- a/src/mem.rs +++ b/src/mem.rs @@ -1,46 +1,18 @@ -use core::slice; +use alloc::alloc::{alloc, Layout}; +use alloc::slice; +use core::ptr::NonNull; +use core::str::FromStr; -use alloc::boxed::Box; -use alloc::vec::Vec; -use core::mem; -use alloc::alloc::{alloc, Layout, dealloc}; -use alloc::{format}; // Import format and String from alloc +use crate::cursor::Cursor; // Import format and String from alloc extern crate alloc; pub type WaPtr = u32; -static mut MEMORY: Vec = Vec::new(); - -pub struct Cursor<'a> { - inner: &'a [u8], - pos: usize, -} - -impl<'a> Cursor<'a> { - pub const fn new(inner: &[u8]) -> Cursor { - Cursor { pos: 0, inner } - } - - pub fn into_inner(self) -> &'a [u8] { - self.inner - } - - pub const fn position(&self) -> usize { - self.pos - } - - pub fn read_u32(&mut self) -> u32 { - let result = u32::from_le_bytes(self.inner[self.pos..self.pos + 4].try_into().unwrap()); - self.pos += 4; - result - } -} - pub struct WaCell { - pub mm_info: usize, - pub gc_info1: usize, - pub gc_info2: usize, + pub mm_info: u64, + pub gc_info1: u64, + pub gc_info2: u64, pub rt_id: u32, pub rt_size: u32, } @@ -55,113 +27,85 @@ impl WaCell { const fn layout(size: usize) -> Layout { unsafe { Layout::from_size_align_unchecked(size + WaCell::usize(), 1) } } - pub fn new<'a>(size: usize, id: u32) -> &'a mut WaCell { + pub fn new(size: usize, id: u32) -> &'static mut WaCell { unsafe { let layout = WaCell::layout(size); let ptr = alloc(layout); - let mut cell = Box::::from_raw(ptr.cast()); + let cell = NonNull::::new_unchecked(ptr.cast()).as_mut(); + cell.gc_info1 = 0; - cell.mm_info = ptr as usize; + cell.mm_info = ptr as u64; cell.rt_id = id; cell.rt_size = size as u32; cell } } - pub fn new_data(id: u32, data: &[u8]) -> Box { - let mut cell = WaCell::new(data.len(), id); + pub fn new_data(id: u32, data: &[u8]) -> &'static mut WaCell { + let cell = WaCell::new(data.len(), id); cell.data_mut().copy_from_slice(data); // Use `copy_from_slice` instead of `write` cell } - pub fn from_raw<'a>(ptr: WaPtr) -> &'a mut WaCell { + pub fn from_raw(ptr: WaPtr) -> &'static mut WaCell { unsafe { NonNull::::new_unchecked((ptr - WaCell::size()) as *mut WaCell).as_mut() } } - pub fn drop(mut self: Box) { - if self.gc_info1 == 0 { - let layout = WaCell::layout(self.rt_size as usize); - unsafe { - let ptr = self.ptr(); - if let Some(index) = MEMORY.iter().position(|cell_ptr| *cell_ptr == ptr) { - MEMORY.remove(index); - } - dealloc(Box::into_raw(self) as *mut u8, layout); - } - } else { - self.dec(); - } - } - - pub fn from_raw(ptr: WaPtr) -> Box { - unsafe { Box::from_raw((ptr - WaCell::size()) as *mut u8 as *mut WaCell) } - } - - pub fn to_raw(self: Box) -> WaPtr { - (Box::into_raw(self) as *const u8).wrapping_add(WaCell::usize()) as WaPtr - } - - pub fn inc(&mut self) { - self.gc_info1 += 1; - } - - pub fn dec(&mut self) { - if self.gc_info1 > 1 { - self.gc_info1 -= 1; - } - } - #[inline] pub fn ptr(&self) -> WaPtr { (self as *const Self as *const u8 as WaPtr) + WaCell::size() } - pub fn data<'a>(&self) -> &'a [u8] { + pub fn data(&self) -> &'static [u8] { unsafe { slice::from_raw_parts(self.ptr() as *const u8, self.rt_size as usize) } } - pub fn data_mut(&mut self) -> &mut [u8] { + pub fn data_mut(&mut self) -> &'static mut [u8] { unsafe { slice::from_raw_parts_mut(self.ptr() as *mut u8, self.rt_size as usize) } } - pub fn cursor(&mut self) -> Cursor { - Cursor::new(self.data_mut()) + pub fn cursor(&mut self) -> super::cursor::Cursor { + super::cursor::Cursor::from_slice(self.data_mut()) } } -pub struct WaBuffer<'a> { - buffer: &'a mut WaCell, - pointer: &'a mut WaCell, +pub struct WaBuffer { + buffer: &'static mut WaCell, + pointer: &'static mut WaCell, } -impl<'a> WaBuffer<'a> { - pub fn from_str(s: &str) -> WaBuffer<'a> { - let len = (s.chars().count()) as u16; - let str_data = len - .to_le_bytes() - .iter() - .chain(s.as_bytes()) - .cloned() - .collect::>(); - WaBuffer::from_bytes(&str_data) +impl Clone for WaBuffer { + fn clone(&self) -> Self { + WaBuffer { + buffer: WaCell::from_raw(self.buffer.ptr()), + pointer: WaCell::from_raw(self.pointer.ptr()), + } } - pub fn from_bytes(bytes: &[u8]) -> WaBuffer<'a> { +} + +impl WaBuffer { + pub fn new(size: usize, id: u32) -> Result { + let buffer = WaCell::new(size, 1); + let pointer = WaCell::new(12, id); + let mut cursor = pointer.cursor(); + cursor.write_u32_le(&buffer.ptr())?; + cursor.write_u32_le(&buffer.ptr())?; + cursor.write_u32_le(&(size as u32))?; + Ok(WaBuffer { pointer, buffer }) + } + pub fn from_bytes(bytes: &[u8]) -> Result { let buffer = WaCell::new_data(1, bytes); - let pointer = WaCell::new_data( - 2, - &[ - buffer.ptr().to_le_bytes(), - buffer.ptr().to_le_bytes(), - (bytes.len() as u32).to_le_bytes(), - ] - .concat(), - ); - WaBuffer { pointer, buffer } + let pointer = WaCell::new(12, 2); + let mut cursor = pointer.cursor(); + cursor.write_u32_le(&buffer.ptr())?; + cursor.write_u32_le(&buffer.ptr())?; + cursor.write_u32_le(&(bytes.len() as u32))?; + Ok(WaBuffer { pointer, buffer }) } - pub fn from_raw(ptr: WaPtr) -> WaBuffer<'a> { + pub fn from_raw(ptr: WaPtr) -> WaBuffer { let pointer = WaCell::from_raw(ptr); let mut cursor = pointer.cursor(); - let buffer_ptr = cursor.read_u32(); + let buffer_ptr = cursor.read_u32_le_unchecked(); let buffer = WaCell::from_raw(buffer_ptr); WaBuffer { pointer, buffer } } @@ -170,123 +114,52 @@ impl<'a> WaBuffer<'a> { self.pointer.ptr() } - pub fn data(&self) -> &[u8] { + pub fn data(&self) -> &'static [u8] { self.buffer.data() } - pub fn to_raw(self) -> WaPtr { - self.pointer.to_raw() + pub fn cursor(&mut self) -> Cursor { + Cursor::from_slice(self.buffer.data_mut()) } - pub unsafe fn into_type(&self) -> Result<&'a mut T, alloc::string::String> { - /* - super::log_str(&alloc::format!("Data: {:?}", self.cell.data())); - super::log_str(&self.buffer.ptr().to_string()); - super::log_str(&alloc::format!("Data: {:?}", self.buffer.data())); - */ + /// # Safety + /// + /// Cast memory to given Type. + /// It is very unsafe and works only on WASM32 arch due to memory align and type sizes + #[cfg(target_arch = "wasm32")] + pub unsafe fn into_type(&self) -> &'static mut T { if core::mem::size_of::() <= self.buffer.rt_size as usize { - #[cfg(feature = "std")] - println!("Casting memory"); - - fn drop(self) { - self.cell.drop(); - self.buffer.drop(); + NonNull::new_unchecked(self.buffer.ptr() as *mut T).as_mut() + } else { + panic!("Cannot map larger objects"); + } } } -#[link(wasm_import_module = "env")] -extern "C" { - pub fn log(buffer: WaPtr); -} - -pub fn log_str(text: &str) { - unsafe { - let string = WaString::new(text); - log(string.ptr()); - string.drop(); +impl FromStr for WaBuffer { + type Err = crate::error::Error; + fn from_str(s: &str) -> Result { + let bytes = s.as_bytes(); + let len = bytes.len() as u16; + let str_data = len + .to_le_bytes() + .iter() + .chain(bytes) + .cloned() + .collect::>(); + WaBuffer::from_bytes(&str_data) } } -#[no_mangle] -pub fn execute(ptr: WaPtr) -> WaPtr { - let buffer = WaArray::from_raw(ptr); - log_str(&alloc::format!("Execute: {:?}", buffer.data())); - buffer.to_raw() -} - -#[no_mangle] -#[export_name = "setEnvironment"] -pub fn set_environment(ptr: WaPtr) { - let buffer = WaArray::from_raw(ptr); - log_str(&alloc::format!("Set environment: {:?}", buffer.data())); - buffer.leak(); -} - -#[no_mangle] -#[export_name = "onDeploy"] -pub fn on_deploy(ptr: WaPtr) { - let buffer = WaArray::from_raw(ptr); - log_str(&format!("On deploy: {:?}", buffer.data())); - buffer.leak(); -} - -#[no_mangle] #[export_name = "__new"] pub fn new(size: usize, id: u32) -> WaPtr { - unsafe { - let cell = WaCell::new(size, id); - let ptr = cell.to_raw(); - MEMORY.push(ptr); - ptr - } + WaCell::new(size, id).ptr() } -#[no_mangle] #[export_name = "__pin"] pub fn pin(ptr: WaPtr) -> WaPtr { - let mut cell = WaCell::from_raw(ptr); - cell.inc(); - cell.to_raw() + ptr } -#[no_mangle] #[export_name = "__unpin"] -pub fn unpin(ptr: WaPtr) { - unsafe { - let mut cell = WaCell::from_raw(ptr); - cell.dec(); - cell.to_raw(); - log_str(&alloc::format!("Mem size: {}", MEMORY.len())); - } -} - -/** - * Remove unused allocations - */ -#[no_mangle] -#[export_name = "__collect"] -pub fn collect() { - unsafe { - let mut new = Vec::new(); - for ptr in MEMORY.iter() { - let cell = WaCell::from_raw(*ptr); - if cell.gc_info1 > 0 { - new.push(cell.to_raw()); - } - } - MEMORY.clear(); // Clear the old memory - MEMORY.extend(new); // Update with the new elements - } -} - -/* -pub fn alloc_box_buffer(len: usize) -> Box<[u8]> { - if len == 0 { - return >::default(); - } - let layout = Layout::array::(len).unwrap(); - let ptr = unsafe { alloc::alloc::alloc(layout) }; - let slice_ptr = core::ptr::slice_from_raw_parts_mut(ptr, len); - unsafe { Box::from_raw(slice_ptr) } -} - */ +pub fn unpin(_ptr: WaPtr) {} diff --git a/src/prelude.rs b/src/prelude.rs new file mode 100644 index 0000000..01cd494 --- /dev/null +++ b/src/prelude.rs @@ -0,0 +1,4 @@ +pub use crate::cursor::Cursor; +pub use crate::ethnum; +pub use crate::mem::{WaBuffer, WaCell, WaPtr}; +pub use crate::ContractTrait; diff --git a/src/storage/array_merger.rs b/src/storage/array_merger.rs new file mode 100644 index 0000000..6b449c5 --- /dev/null +++ b/src/storage/array_merger.rs @@ -0,0 +1,41 @@ +use alloc::vec::Vec; + +use crate::{math::abi::encode_pointer, storage::StorageKey}; + +use super::{GlobalStore, StorageValue}; + +#[derive(Clone, Eq, PartialEq)] +pub struct ArrayMerger { + parent_key: Vec, + pointer: u16, + default_value: StorageValue, +} + +impl ArrayMerger { + pub fn new(parent_key: Vec, pointer: u16, default_value: StorageValue) -> Self { + Self { + parent_key, + pointer, + default_value, + } + } + pub fn get(&mut self, key: &[u8]) -> StorageValue { + let key = self.get_key_hash(key); + GlobalStore::get(&key, self.default_value) + } + + pub fn set(&mut self, key: &[u8], value: StorageValue) { + let key = self.get_key_hash(key); + GlobalStore::set(key, value); + } + + pub fn contains_key(&self, key: &[u8]) -> bool { + let key = self.get_key_hash(key); + GlobalStore::has_key(&key) + } + + fn get_key_hash(&self, key: &[u8]) -> StorageKey { + let merged: Vec = self.parent_key.iter().chain(key.iter()).cloned().collect(); + encode_pointer(self.pointer, &merged) + } +} diff --git a/src/storage/key.rs b/src/storage/key.rs new file mode 100644 index 0000000..a641867 --- /dev/null +++ b/src/storage/key.rs @@ -0,0 +1 @@ +pub type StorageKey = [u8; crate::constant::STORE_KEY_SIZE]; diff --git a/src/storage/map.rs b/src/storage/map.rs new file mode 100644 index 0000000..5c71ca0 --- /dev/null +++ b/src/storage/map.rs @@ -0,0 +1,136 @@ +//! Simplified version Map +//! + +/// Map structure +pub struct Map +where + Key: Sized + Eq, + Value: Sized + Clone + Eq, +{ + items: alloc::vec::Vec<(Key, Value)>, +} +// Implement default trait +impl Default for Map { + fn default() -> Self { + Self::new() + } +} + +impl Map { + pub const fn new() -> Self { + Self { + items: alloc::vec::Vec::new(), + } + } + + pub fn new_with_capacity(capacity: usize) -> Self { + Self { + items: alloc::vec::Vec::with_capacity(capacity), + } + } + + pub fn clear(&mut self) { + self.items.clear(); + } + + /// Doesn not check for duplicities. + /// Faster, but can make map unstable + pub fn push(&mut self, key: Key, value: Value) { + self.items.push((key, value)); + } + + /// Insert element and check for duplicities + pub fn insert(&mut self, key: Key, value: Value) -> Option { + if let Some((_, val)) = self.items.iter_mut().find(|(key, _)| key.eq(key)) { + let result = val.clone(); + *val = value; + Some(result) + } else { + self.push(key, value); + None + } + } + + pub fn pop(&mut self) -> Option<(Key, Value)> { + self.items.pop() + } + + pub fn contains_key(&self, key: &Key) -> bool { + self.items.iter().any(|(k, _)| k.eq(key)) + } + + pub fn contains_value(&self, value: &Value) -> bool { + self.items.iter().any(|(_, v)| v.eq(value)) + } + + pub fn get(&self, key: &Key) -> Option<&Value> { + self.items.iter().find(|(k, _)| k.eq(key)).map(|(_, v)| v) + } + + pub fn get_mut(&mut self, key: &Key) -> Option<&mut Value> { + self.items + .iter_mut() + .find(|(k, _)| k.eq(key)) + .map(|(_, v)| v) + } + + pub fn iter(&self) -> impl Iterator { + self.items.iter() + } + + pub fn iter_mut(&mut self) -> impl Iterator { + self.items.iter_mut() + } + + pub fn iter_keys(&self) -> impl Iterator { + self.items.iter().map(|i| &i.0) + } + + pub fn iter_keys_mut(&mut self) -> impl Iterator { + self.items.iter_mut().map(|i| &mut i.0) + } + + pub fn iter_values(&self) -> impl Iterator { + self.items.iter().map(|i| &i.1) + } + + pub fn iter_values_mut(&mut self) -> impl Iterator { + self.items.iter_mut().map(|(_, v)| v) + } + + pub fn remove(&mut self, key: &Key) -> Option { + if let Some(index) = self.items.iter().position(|(k, _)| k.eq(key)) { + Some(self.items.remove(index).1) + } else { + None + } + } +} + +impl core::ops::Index<&Key> for Map { + type Output = Value; + + fn index(&self, index: &Key) -> &Value { + self.get(index).unwrap() + } +} + +impl core::ops::Index for Map { + type Output = Value; + + fn index(&self, index: Key) -> &Value { + self.get(&index).unwrap() + } +} + +impl core::ops::IndexMut<&Key> for Map { + fn index_mut(&mut self, index: &Key) -> &mut Self::Output { + self.get_mut(index).unwrap() + } +} + +impl core::ops::IndexMut for Map { + fn index_mut(&mut self, index: Key) -> &mut Self::Output { + self.get_mut(&index).unwrap() + } +} diff --git a/src/storage/mod.rs b/src/storage/mod.rs new file mode 100644 index 0000000..5fbea4e --- /dev/null +++ b/src/storage/mod.rs @@ -0,0 +1,65 @@ +use map::Map; + +pub mod array_merger; +pub mod key; +pub mod map; +pub mod multi_address_map; +pub mod stored; +pub mod stored_map; +pub mod stored_string; +pub mod value; + +pub use key::StorageKey; +pub use value::StorageValue; + +#[allow(static_mut_refs)] +static mut GLOBAL_STORE: Map = Map::new(); + +pub struct GlobalStore {} + +impl GlobalStore { + pub fn get(key: &StorageKey, default_value: StorageValue) -> StorageValue { + if Self::has_key(key) { + #[allow(static_mut_refs)] + unsafe { + if let Some(value) = GLOBAL_STORE.get(key) { + *value + } else { + if let Ok(result) = crate::env::pointer_load(key) { + GLOBAL_STORE.insert(key.clone(), result); + result + } else { + default_value + } + } + } + } else { + default_value + } + } + + pub fn set(key: StorageKey, value: StorageValue) { + assert!(crate::env::pointer_store(&key, &value).unwrap()); + + #[allow(static_mut_refs)] + unsafe { + GLOBAL_STORE.insert(key, value); + } + } + + pub fn has_key(key: &StorageKey) -> bool { + #[allow(static_mut_refs)] + unsafe { + if GLOBAL_STORE.contains_key(key) { + return true; + }; + + if let Ok(result) = crate::env::pointer_load(key) { + GLOBAL_STORE.insert(*key, result); + return !result.zero(); + } + } + + false + } +} diff --git a/src/storage/multi_address_map.rs b/src/storage/multi_address_map.rs new file mode 100644 index 0000000..2c942ad --- /dev/null +++ b/src/storage/multi_address_map.rs @@ -0,0 +1,46 @@ +use crate::blockchain::AddressHash; + +use super::{array_merger::ArrayMerger, map::Map, StorageValue}; + +pub struct MultiAddressMemoryMap { + pointer: u16, + default_value: StorageValue, + pub map: Map, +} + +impl MultiAddressMemoryMap { + pub const fn new(pointer: u16, default_value: StorageValue) -> Self { + Self { + pointer, + default_value, + map: Map::new(), + } + } + + pub fn clear(&mut self) { + self.map.clear(); + } + + pub fn get(&mut self, key: &AddressHash) -> ArrayMerger { + self.create_key_merger(key); + self.map.get(key).unwrap().clone() + } + + pub fn set(&mut self, key: AddressHash, value: ArrayMerger) { + self.create_key_merger(&key); + self.map.insert(key, value); + } + + pub fn contains_key(&self, key: &AddressHash) -> bool { + self.map.contains_key(key) + } + + fn create_key_merger(&mut self, key: &AddressHash) { + if !self.map.contains_key(key) { + self.map.push( + *key, + ArrayMerger::new(key.bytes.to_vec(), self.pointer, self.default_value), + ); + } + } +} diff --git a/src/storage/stored.rs b/src/storage/stored.rs new file mode 100644 index 0000000..62616e0 --- /dev/null +++ b/src/storage/stored.rs @@ -0,0 +1,167 @@ +use ethnum::u256; + +use super::{GlobalStore, StorageKey, StorageValue}; +use crate::{blockchain::AddressHash, math::abi::encode_pointer}; +use core::convert::Into; + +pub trait StoredTrait +where + D: Into, +{ + fn value(&mut self) -> T; + fn refresh(&mut self) -> T; + fn set(&mut self, value: T) -> T; + fn set_no_commit(&mut self, value: T) -> T; + fn commit(&mut self); +} + +pub struct Stored +where + T: Into + Copy + Eq, + StorageValue: Into, + D: Into + Clone, +{ + pointer: StorageKey, + default_value: D, + value: Option, +} + +impl StoredTrait for Stored +where + T: Into + Copy + Eq, + StorageValue: Into, + D: Into + Clone, +{ + fn value(&mut self) -> T { + if let Some(value) = &self.value { + *value + } else { + self.value = Some( + GlobalStore::get( + &self.pointer, + Into::::into(self.default_value.clone().into()), + ) + .into(), + ); + self.value.as_ref().unwrap().clone() + } + } + + fn set(&mut self, value: T) -> T { + if Some(value) != self.value { + GlobalStore::set(self.pointer, value.into()); + self.value = Some(value); + value + } else { + value + } + } + + fn refresh(&mut self) -> T { + let value = GlobalStore::get( + &self.pointer, + Into::::into(self.default_value.clone().into()), + ); + self.value = Some(value.clone().into()); + self.value.unwrap() + } + + fn set_no_commit(&mut self, value: T) -> T { + self.value = Some(value); + value + } + + fn commit(&mut self) { + if let Some(value) = self.value { + GlobalStore::set(self.pointer, value.into()); + } + } +} + +impl Stored +where + T: Into + Copy + Eq, + StorageValue: Into, + D: Into + Clone, +{ + pub const fn new_const(pointer: u16, default_value: D) -> Self { + Self { + pointer: crate::math::abi::encode_pointer_const(pointer), + default_value, + value: None, + } + } + + pub fn new(pointer: u16, sub_pointer: &StorageKey, default_value: D) -> Self { + Self { + pointer: encode_pointer(pointer, sub_pointer), + default_value, + value: None, + } + } +} + +pub type StoredBool = Stored; +pub type StoredU8 = Stored; +pub type StoredU16 = Stored; +pub type StoredU32 = Stored; +pub type StoredU64 = Stored; +pub type StoredU128 = Stored; +pub type StoredU256 = Stored; +pub type StoredAddress = Stored; + +#[cfg(test)] +mod tests { + + use ethnum::u256; + + use super::StoredTrait; + #[test] + fn test_bool() { + let mut stored_bool = super::StoredBool::new_const(0, false); + stored_bool.set(true); + assert_eq!(stored_bool.refresh(), true) + } + + #[test] + fn test_u8() { + let mut stored_u8 = super::StoredU8::new_const(0, 0); + stored_u8.set(1); + assert_eq!(stored_u8.refresh(), 1) + } + + #[test] + fn test_u16() { + let mut stored_u16 = super::StoredU16::new_const(0, 0); + stored_u16.set(123); + assert_eq!(stored_u16.refresh(), 123) + } + + #[test] + fn test_u32() { + let mut stored_u32 = super::StoredU32::new_const(0, 0); + stored_u32.set(123); + assert_eq!(stored_u32.refresh(), 123) + } + + #[test] + fn test_u64() { + let mut stored_u64 = super::StoredU64::new_const(0, 0); + stored_u64.set(123); + assert_eq!(stored_u64.refresh(), 123) + } + + #[test] + fn test_u128() { + let mut stored_u128 = super::StoredU128::new_const(0, 0); + stored_u128.set(123); + assert_eq!(stored_u128.refresh(), 123) + } + + #[test] + fn test_u256() { + let mut stored_u256 = super::StoredU256::new_const(0, u256::new(0)); + stored_u256.set(u256::new(123)); + assert_eq!(stored_u256.refresh(), u256::new(123)) + } +} diff --git a/src/storage/stored_map.rs b/src/storage/stored_map.rs new file mode 100644 index 0000000..9dc8c23 --- /dev/null +++ b/src/storage/stored_map.rs @@ -0,0 +1,53 @@ +use core::marker::PhantomData; +use ethnum::u256; + +use crate::{blockchain::AddressHash, math::abi::encode_pointer}; + +use super::{GlobalStore, StorageKey, StorageValue}; + +pub struct StoredMap +where + K: Into, + V: Into, +{ + pointer: u16, + k: PhantomData, + v: PhantomData, +} + +impl StoredMap +where + K: Into + Copy, + V: Into + Clone, +{ + pub const fn new(pointer: u16) -> Self { + Self { + pointer, + k: PhantomData, + v: PhantomData, + } + } + + pub fn set(&self, key: &K, value: V) { + let key: StorageKey = (*key).into(); + let key_hash = encode_pointer(self.pointer, &key); + let value = Into::::into(value); + GlobalStore::set(key_hash, value); + } + + pub fn get(&self, key: &K, default_value: V) -> StorageValue { + let key: StorageKey = (*key).into(); + let key_hash = encode_pointer(self.pointer, &key); + let value = GlobalStore::get(&key_hash, default_value.into()); + value + } + + pub fn contains_key(&self, key: &K) -> bool { + let key: StorageKey = (*key).into(); + let key_hash = encode_pointer(self.pointer, &key); + let has = GlobalStore::has_key(&key_hash); + has + } +} + +pub type StoredAddresValueMap = StoredMap; diff --git a/src/storage/stored_string.rs b/src/storage/stored_string.rs new file mode 100644 index 0000000..8bf9f64 --- /dev/null +++ b/src/storage/stored_string.rs @@ -0,0 +1,127 @@ +use alloc::string::String; + +use crate::{constant::STORE_VALUE_SIZE, storage::StorageValue}; + +use super::{stored::StoredTrait, GlobalStore}; + +pub struct StoredString { + pointer: u16, + default_value: &'static str, + value: Option, +} + +impl StoredString { + pub const fn new_const(pointer: u16, default_value: &'static str) -> Self { + Self { + pointer, + default_value, + value: None, + } + } + + pub fn new(pointer: u16, default_value: &'static str) -> Self { + Self { + pointer, + default_value, + value: None, + } + } + + fn save(&mut self, value: String) -> String { + let bytes = value.as_bytes(); + let mut remaining = bytes.len(); + let mut offset = [0u8; crate::constant::STORE_VALUE_SIZE]; + assert!(remaining < 2048); + + let mut data = [0u8; crate::constant::STORE_VALUE_SIZE]; + let mut length = remaining.min(STORE_VALUE_SIZE - 4); + data[0..4].copy_from_slice(&(remaining as u32).to_le_bytes()); + data[4..4 + remaining.min(28)].copy_from_slice(&bytes[0..length]); + let key = crate::math::abi::encode_pointer(self.pointer, &offset); + remaining -= length; + GlobalStore::set(key, data.into()); + + while remaining > 0 { + length = remaining.min(crate::constant::STORE_VALUE_SIZE); + let start = value.len() - remaining; + data[0..length].copy_from_slice(&bytes[start..start + length]); + if length < crate::constant::STORE_VALUE_SIZE { + data[length..crate::constant::STORE_VALUE_SIZE].copy_from_slice( + &[0u8; crate::constant::STORE_VALUE_SIZE] + [0..crate::constant::STORE_VALUE_SIZE - length], + ); + } + offset[crate::constant::STORE_KEY_SIZE - 1] += 1; + remaining -= length; + + let key = crate::math::abi::encode_pointer(self.pointer, &offset); + GlobalStore::set(key, data.into()); + } + self.value = Some(value.clone()); + value + } + + fn load(&mut self) -> String { + let mut offset = [0u8; crate::constant::STORE_VALUE_SIZE]; + let header = GlobalStore::get( + &crate::math::abi::encode_pointer(self.pointer, &offset), + StorageValue::ZERO, + ); + let bytes = header.bytes(); + let len = u32::from_le_bytes(bytes[0..4].try_into().unwrap()) as usize; + let mut length = len.min(crate::constant::STORE_VALUE_SIZE); + let mut value: alloc::vec::Vec = alloc::vec::Vec::with_capacity(len); + let mut remaining = len - length; + for &byte in bytes.iter().skip(4).take(length) { + value.push(byte); + } + + while remaining > 0 { + offset[crate::constant::STORE_KEY_SIZE - 1] += 1; + let key = crate::math::abi::encode_pointer(self.pointer, &offset); + let tmp = GlobalStore::get(&key, StorageValue::ZERO); + let bytes = tmp.bytes(); + length = remaining.min(crate::constant::STORE_VALUE_SIZE); + for &byte in bytes.iter().take(length) { + value.push(byte); + } + remaining -= length; + } + if let Ok(value) = String::from_utf8(value) { + self.value = Some(value.clone()); + value + // Unexpected state + } else { + self.default_value.into() + } + } +} + +impl StoredTrait for StoredString { + fn set(&mut self, value: String) -> String { + self.save(value) + } + + fn value(&mut self) -> String { + if let Some(value) = &self.value { + value.clone() + } else { + self.load() + } + } + + fn set_no_commit(&mut self, value: String) -> String { + self.value = Some(value.clone()); + value + } + + fn commit(&mut self) { + if let Some(value) = &self.value { + self.save(value.clone()); + } + } + + fn refresh(&mut self) -> String { + self.load() + } +} diff --git a/src/storage/value.rs b/src/storage/value.rs new file mode 100644 index 0000000..2c9e093 --- /dev/null +++ b/src/storage/value.rs @@ -0,0 +1,161 @@ +use ethnum::u256; + +#[derive(Copy, Clone, Eq, PartialEq)] +pub struct StorageValue { + inner: [u8; crate::constant::STORE_VALUE_SIZE], +} + +impl StorageValue { + pub const ZERO: StorageValue = StorageValue { + inner: [0; crate::constant::STORE_VALUE_SIZE], + }; + + pub fn from_bytes(bytes: [u8; crate::constant::STORE_VALUE_SIZE]) -> Self { + Self { inner: bytes } + } + pub fn value(&self) -> [u8; crate::constant::STORE_VALUE_SIZE] { + self.inner + } + + pub fn bytes(&self) -> &[u8] { + &self.inner + } + + pub fn bool(&self) -> bool { + self.inner.iter().any(|v| 0.le(v)) + } + + pub fn zero(&self) -> bool { + self.inner.iter().all(|v| 0.eq(v)) + } + + pub fn u8(&self) -> u8 { + self.inner[31] + } + + pub fn u16(&self) -> u16 { + u16::from_be_bytes(self.inner[30..32].try_into().unwrap()) + } + + pub fn u32(&self) -> u32 { + u32::from_be_bytes(self.inner[28..32].try_into().unwrap()) + } + + pub fn u64(&self) -> u64 { + u64::from_be_bytes(self.inner[24..32].try_into().unwrap()) + } + + pub fn u128(&self) -> u128 { + u128::from_be_bytes(self.inner[16..32].try_into().unwrap()) + } + + pub fn u256(&self) -> u256 { + u256::from_be_bytes(self.inner) + } +} + +impl From<[u8; crate::constant::STORE_VALUE_SIZE]> for StorageValue { + fn from(value: [u8; crate::constant::STORE_VALUE_SIZE]) -> Self { + StorageValue { inner: value } + } +} + +impl From<&[u8; crate::constant::STORE_VALUE_SIZE]> for StorageValue { + fn from(value: &[u8; crate::constant::STORE_VALUE_SIZE]) -> Self { + StorageValue { inner: *value } + } +} + +impl From<&[u8]> for StorageValue { + fn from(value: &[u8]) -> Self { + let mut inner = [0u8; crate::constant::STORE_VALUE_SIZE]; + let length = value.len().min(crate::constant::STORE_VALUE_SIZE); + + inner[32 - length..32].copy_from_slice(&value[0..length]); + StorageValue { inner } + } +} + +impl From for StorageValue { + fn from(value: u8) -> Self { + From::<&[u8]>::from(&value.to_be_bytes()) + } +} + +impl From for StorageValue { + fn from(value: u16) -> Self { + From::<&[u8]>::from(&value.to_be_bytes()) + } +} + +impl From for StorageValue { + fn from(value: u32) -> Self { + From::<&[u8]>::from(&value.to_be_bytes()) + } +} + +impl From for StorageValue { + fn from(value: u64) -> Self { + From::<&[u8]>::from(&value.to_be_bytes()) + } +} + +impl From for StorageValue { + fn from(value: u128) -> Self { + From::<&[u8]>::from(&value.to_be_bytes()) + } +} + +impl From for StorageValue { + fn from(value: u256) -> Self { + Self::from(value.to_be_bytes()) + } +} + +impl From for StorageValue { + fn from(value: bool) -> Self { + From::::from(value.into()) + } +} + +impl From for u8 { + fn from(val: StorageValue) -> Self { + val.u8() + } +} + +impl From for u16 { + fn from(val: StorageValue) -> Self { + val.u16() + } +} + +impl From for u32 { + fn from(val: StorageValue) -> Self { + val.u32() + } +} + +impl From for u64 { + fn from(val: StorageValue) -> Self { + val.u64() + } +} + +impl From for u128 { + fn from(val: StorageValue) -> Self { + val.u128() + } +} + +impl From for u256 { + fn from(val: StorageValue) -> Self { + val.u256() + } +} + +impl From for bool { + fn from(val: StorageValue) -> Self { + val.bool() + } +} diff --git a/src/types.rs b/src/types.rs new file mode 100644 index 0000000..1852183 --- /dev/null +++ b/src/types.rs @@ -0,0 +1,2 @@ +pub type Selector = u32; +pub type CallData = crate::cursor::Cursor; diff --git a/src/utils.rs b/src/utils.rs index 8b507ce..26880bb 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,18 +1,27 @@ const BASE64_TABLE: [char; 16] = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', ]; + +pub fn to_hex(bytes: &[u8]) -> alloc::string::String { + let mut string = alloc::string::String::with_capacity(bytes.len() * 2 + 3); + string.push_str("0x"); + + for byte in bytes.iter() { + string.push(BASE64_TABLE[(*byte >> 4) as usize]); + string.push(BASE64_TABLE[(*byte & 0xf) as usize]); + } + string +} pub trait ToHex { - fn get_bytes<'a>(&'a self) -> &'a [u8]; - fn to_hex<'a>(&'a self) -> alloc::string::String { - let bytes = self.get_bytes(); - let mut string = alloc::string::String::with_capacity(bytes.len() * 2 + 3); - string.push_str("0x"); + fn get_bytes(&self) -> &[u8]; + fn to_hex(&self) -> alloc::string::String { + to_hex(self.get_bytes()) + } +} - for byte in bytes.iter() { - string.push(BASE64_TABLE[(*byte >> 4) as usize]); - string.push(BASE64_TABLE[(*byte & 0xf) as usize]); - } - string +impl ToHex for &[u8] { + fn get_bytes(&self) -> &[u8] { + self } } @@ -22,14 +31,22 @@ mod tests { pub struct TestHex(alloc::vec::Vec); impl ToHex for TestHex { - fn get_bytes<'a>(&'a self) -> &'a [u8] { + fn get_bytes(&self) -> &[u8] { &self.0 } } #[test] - fn it_works() { + fn test_to_hex() { let v = TestHex(alloc::vec![0xda, 0x02, 0xa1, 0x1f]); assert_eq!(v.to_hex(), alloc::string::String::from("0xda02a11f")); + assert_eq!( + to_hex(&255u8.to_be_bytes()), + alloc::string::String::from("0xff") + ); + assert_eq!( + to_hex(&255u64.to_be_bytes()), + alloc::string::String::from("0x00000000000000ff") + ); } } From d765c3b5d96f4d4a6386e0b590b57cd31bf257cb Mon Sep 17 00:00:00 2001 From: Miksa Date: Thu, 19 Dec 2024 02:01:43 +0100 Subject: [PATCH 06/23] WIP - direct test for contract --- Cargo.lock | 18 ++++++++++- Cargo.toml | 1 + example/src/contract.rs | 69 +++++++++++++++++++++++++++++++++++++++++ src/cursor/reader.rs | 15 +++++++++ src/lib.rs | 2 ++ src/mem.rs | 28 ++++++++++++++++- 6 files changed, 131 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9393fe1..4171126 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "autocfg" @@ -23,6 +23,21 @@ dependencies = [ "sha2-const", ] +[[package]] +name = "libc" +version = "0.2.168" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d" + +[[package]] +name = "libc-print" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a660208db49e35faf57b37484350f1a61072f2a5becf0592af6015d9ddd4b0" +dependencies = [ + "libc", +] + [[package]] name = "lock_api" version = "0.4.12" @@ -47,6 +62,7 @@ name = "rust_runtime" version = "0.1.0" dependencies = [ "ethnum", + "libc-print", "sha2-const", ] diff --git a/Cargo.toml b/Cargo.toml index 5e2aebc..6e41083 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,7 @@ members = ["example"] # This crate is much larger than expected. Avoid using it unless absolutely necessary. ethnum = { workspace = true } sha2-const = {workspace = true } +libc-print = {version = "0.1.22", optional=true} [features] std = [] diff --git a/example/src/contract.rs b/example/src/contract.rs index 2ab0532..bd4279d 100644 --- a/example/src/contract.rs +++ b/example/src/contract.rs @@ -166,3 +166,72 @@ impl rust_runtime::contract::ContractTrait for Contract { fn on_deploy(&mut self, _call_data: CallData) {} } + +#[cfg(test)] +mod tests { + use rust_runtime::{ + blockchain::{AddressHash, TransactionHash}, + ethnum::u256, + WaBuffer, + }; + + use crate::contract::SELECTOR_MINT; + + #[test] + fn test_contract_name() { + let mut contract = super::Contract::new(); + + let mut buffer = WaBuffer::new(0, 1).unwrap(); + let mut result = contract + .execute( + rust_runtime::contract::op_20::SELECTOR_NAME, + buffer.cursor(), + ) + .unwrap(); + + let mut cursor = result.cursor(); + assert_eq!(contract.params.name, cursor.read_string_with_len().unwrap()); + } + + #[test] + fn test_contract_total_supply() { + let mut contract = super::Contract::new(); + let address = AddressHash::new(&[ + 223, 139, 191, 239, 93, 189, 81, 15, 99, 20, 253, 253, 223, 251, 207, 31, 133, 139, + 175, 201, 19, 59, 128, 1, 13, 88, 160, 143, 140, 87, 84, 92, + ]); + let environment = alloc::boxed::Box::new(rust_runtime::blockchain::Environment { + address: address.clone(), + block_hash: rust_runtime::blockchain::BlockHash { + bytes: address.bytes.clone(), + }, + sender: address.clone(), + deployer: address.clone(), + origin: address.clone(), + transaction_hash: TransactionHash { + bytes: address.bytes.clone(), + }, + timestamp: 0, + safe_rnd: 0, + }); + contract.environment = Some(alloc::boxed::Box::leak(environment)); + let amount = u256::new(10000000); + + let mut buffer = WaBuffer::new(64, 1).unwrap(); + let mut cursor = buffer.cursor(); + cursor.write_address(&address).unwrap(); + cursor.write_u256_be(&amount).unwrap(); + contract.execute(SELECTOR_MINT, cursor).unwrap(); + + let mut buffer = WaBuffer::new(0, 1).unwrap(); + let mut result = contract + .execute( + rust_runtime::contract::op_20::SELECTOR_TOTAL_SUPPLY, + buffer.cursor(), + ) + .unwrap(); + + let mut cursor = result.cursor(); + assert_eq!(cursor.read_u256_be().unwrap(), amount); + } +} diff --git a/src/cursor/reader.rs b/src/cursor/reader.rs index 954b18b..23f4e6d 100644 --- a/src/cursor/reader.rs +++ b/src/cursor/reader.rs @@ -1,3 +1,5 @@ +use core::str; + use crate::{blockchain::AddressHash, storage::map::Map, types::Selector}; use ethnum::u256; @@ -127,4 +129,17 @@ impl super::Cursor { } Ok(result) } + + pub fn read_string_with_len(&mut self) -> Result<&str, crate::error::Error> { + let len = self.read_u16_le()?; + + let pos = self.reader; + self.reader += len as usize; + unsafe { + Ok(str::from_raw_parts( + self.inner.as_ptr().add(pos as usize), + len as usize, + )) + } + } } diff --git a/src/lib.rs b/src/lib.rs index 2b8f01b..7b0d7b1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,8 @@ #![no_std] #![feature(const_for)] #![feature(const_trait_impl)] +#![feature(stmt_expr_attributes)] +#![feature(str_from_raw_parts)] extern crate alloc; pub mod blockchain; diff --git a/src/mem.rs b/src/mem.rs index 299c28a..a4161ae 100644 --- a/src/mem.rs +++ b/src/mem.rs @@ -3,6 +3,9 @@ use alloc::slice; use core::ptr::NonNull; use core::str::FromStr; +#[cfg(feature = "std")] +use libc_print::std_name::println; + use crate::cursor::Cursor; // Import format and String from alloc extern crate alloc; @@ -15,6 +18,8 @@ pub struct WaCell { pub gc_info2: u64, pub rt_id: u32, pub rt_size: u32, + #[cfg(not(target_arch = "wasm32"))] + pub data: &'static mut [u8], } impl WaCell { @@ -31,12 +36,18 @@ impl WaCell { unsafe { let layout = WaCell::layout(size); let ptr = alloc(layout); + let cell = NonNull::::new_unchecked(ptr.cast()).as_mut(); cell.gc_info1 = 0; cell.mm_info = ptr as u64; cell.rt_id = id; cell.rt_size = size as u32; + #[cfg(not(target_arch = "wasm32"))] + { + let data = alloc(Layout::from_size_align_unchecked(size, 1)); + cell.data = core::slice::from_raw_parts_mut(data, size); + } cell } } @@ -56,14 +67,29 @@ impl WaCell { (self as *const Self as *const u8 as WaPtr) + WaCell::size() } + #[cfg(target_arch = "wasm32")] + pub fn data(&self) -> &'static [u8] { + #[cfg(target_arch = "wasm32")] + unsafe { + slice::from_raw_parts(self.ptr() as *const u8, self.rt_size as usize) + } + } + + #[cfg(not(target_arch = "wasm32"))] pub fn data(&self) -> &'static [u8] { - unsafe { slice::from_raw_parts(self.ptr() as *const u8, self.rt_size as usize) } + unsafe { slice::from_raw_parts(self.data.as_ptr(), self.rt_size as usize) } } + #[cfg(target_arch = "wasm32")] pub fn data_mut(&mut self) -> &'static mut [u8] { unsafe { slice::from_raw_parts_mut(self.ptr() as *mut u8, self.rt_size as usize) } } + #[cfg(not(target_arch = "wasm32"))] + pub fn data_mut(&mut self) -> &'static mut [u8] { + unsafe { slice::from_raw_parts_mut(self.data.as_mut_ptr(), self.rt_size as usize) } + } + pub fn cursor(&mut self) -> super::cursor::Cursor { super::cursor::Cursor::from_slice(self.data_mut()) } From 3e47dcd72ae769ed4444d4378ce98c9dab7fec90 Mon Sep 17 00:00:00 2001 From: Miksa Date: Thu, 19 Dec 2024 02:41:31 +0100 Subject: [PATCH 07/23] WIP - add random generated environment --- Cargo.lock | 125 ++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + example/src/contract.rs | 43 +++++--------- src/lib.rs | 2 + src/tests/mod.rs | 79 +++++++++++++++++++++++++ 5 files changed, 221 insertions(+), 29 deletions(-) create mode 100644 src/tests/mod.rs diff --git a/Cargo.lock b/Cargo.lock index 4171126..56d6121 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,6 +8,18 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + [[package]] name = "ethnum" version = "1.5.0" @@ -23,6 +35,17 @@ dependencies = [ "sha2-const", ] +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + [[package]] name = "libc" version = "0.2.168" @@ -57,12 +80,70 @@ dependencies = [ "spin", ] +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro2" +version = "1.0.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + [[package]] name = "rust_runtime" version = "0.1.0" dependencies = [ "ethnum", "libc-print", + "rand", "sha2-const", ] @@ -86,3 +167,47 @@ checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" dependencies = [ "lock_api", ] + +[[package]] +name = "syn" +version = "2.0.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/Cargo.toml b/Cargo.toml index 6e41083..ff7bb19 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,6 +25,7 @@ members = ["example"] ethnum = { workspace = true } sha2-const = {workspace = true } libc-print = {version = "0.1.22", optional=true} +rand = {version = "0.8.5"} [features] std = [] diff --git a/example/src/contract.rs b/example/src/contract.rs index bd4279d..677d80d 100644 --- a/example/src/contract.rs +++ b/example/src/contract.rs @@ -171,7 +171,9 @@ impl rust_runtime::contract::ContractTrait for Contract { mod tests { use rust_runtime::{ blockchain::{AddressHash, TransactionHash}, + contract::op_20::SELECTOR_BALANCE_OF, ethnum::u256, + tests::{execute, execute_address, execute_address_amount, random_environment}, WaBuffer, }; @@ -196,42 +198,25 @@ mod tests { #[test] fn test_contract_total_supply() { let mut contract = super::Contract::new(); - let address = AddressHash::new(&[ - 223, 139, 191, 239, 93, 189, 81, 15, 99, 20, 253, 253, 223, 251, 207, 31, 133, 139, - 175, 201, 19, 59, 128, 1, 13, 88, 160, 143, 140, 87, 84, 92, - ]); + let address = rust_runtime::tests::random_address(); + let environment = alloc::boxed::Box::new(rust_runtime::blockchain::Environment { - address: address.clone(), - block_hash: rust_runtime::blockchain::BlockHash { - bytes: address.bytes.clone(), - }, - sender: address.clone(), deployer: address.clone(), - origin: address.clone(), - transaction_hash: TransactionHash { - bytes: address.bytes.clone(), - }, - timestamp: 0, - safe_rnd: 0, + sender: address.clone(), + ..random_environment() }); + contract.environment = Some(alloc::boxed::Box::leak(environment)); let amount = u256::new(10000000); - let mut buffer = WaBuffer::new(64, 1).unwrap(); - let mut cursor = buffer.cursor(); - cursor.write_address(&address).unwrap(); - cursor.write_u256_be(&amount).unwrap(); - contract.execute(SELECTOR_MINT, cursor).unwrap(); - - let mut buffer = WaBuffer::new(0, 1).unwrap(); - let mut result = contract - .execute( - rust_runtime::contract::op_20::SELECTOR_TOTAL_SUPPLY, - buffer.cursor(), - ) - .unwrap(); + execute_address_amount(&mut contract, SELECTOR_MINT, &address, amount); + let mut cursor = execute( + &mut contract, + rust_runtime::contract::op_20::SELECTOR_TOTAL_SUPPLY, + ); + assert_eq!(cursor.read_u256_be().unwrap(), amount); - let mut cursor = result.cursor(); + let mut cursor = execute_address(&mut contract, SELECTOR_BALANCE_OF, &address); assert_eq!(cursor.read_u256_be().unwrap(), amount); } } diff --git a/src/lib.rs b/src/lib.rs index 7b0d7b1..190099c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -19,6 +19,8 @@ pub mod storage; pub mod types; pub mod utils; +pub mod tests; + pub use crate::mem::WaBuffer; pub use env::*; pub use ethnum; diff --git a/src/tests/mod.rs b/src/tests/mod.rs new file mode 100644 index 0000000..b216e14 --- /dev/null +++ b/src/tests/mod.rs @@ -0,0 +1,79 @@ +use ethnum::u256; + +use crate::{ + blockchain::{AddressHash, BlockHash, Environment, TransactionHash}, + cursor::Cursor, +}; + +pub fn random_bytes() -> [u8; 32] { + let mut result = [0u8; 32]; + result.iter_mut().for_each(|b| *b = rand::random::()); + result +} + +pub fn random_address() -> AddressHash { + AddressHash { + bytes: random_bytes(), + } +} + +pub fn random_transaction() -> TransactionHash { + TransactionHash { + bytes: random_bytes(), + } +} + +pub fn random_block() -> BlockHash { + BlockHash { + bytes: random_bytes(), + } +} + +pub fn random_environment() -> Environment { + Environment { + address: random_address(), + block_hash: random_block(), + deployer: random_address(), + sender: random_address(), + origin: random_address(), + transaction_hash: random_transaction(), + timestamp: 0, + safe_rnd: rand::random(), + } +} + +pub fn execute( + contract: &mut impl crate::ContractTrait, + selector: crate::types::Selector, +) -> Cursor { + let mut buffer = crate::WaBuffer::new(32, 1).unwrap(); + let mut cursor = buffer.cursor(); + cursor.write_u32_le(&selector).unwrap(); + contract.execute(cursor).unwrap().cursor() +} + +pub fn execute_address( + contract: &mut impl crate::ContractTrait, + selector: crate::types::Selector, + address: &AddressHash, +) -> Cursor { + let mut buffer = crate::WaBuffer::new(64, 1).unwrap(); + let mut cursor = buffer.cursor(); + cursor.write_u32_le(&selector).unwrap(); + cursor.write_address(&address).unwrap(); + contract.execute(cursor).unwrap().cursor() +} + +pub fn execute_address_amount( + contract: &mut impl crate::ContractTrait, + selector: crate::types::Selector, + address: &AddressHash, + amount: u256, +) -> Cursor { + let mut buffer = crate::WaBuffer::new(96, 1).unwrap(); + let mut cursor = buffer.cursor(); + cursor.write_u32_le(&selector).unwrap(); + cursor.write_address(&address).unwrap(); + cursor.write_u256_be(&amount).unwrap(); + contract.execute(cursor).unwrap().cursor() +} From 0a821747a88f9f7bc4f877b4ddebf0feed9610c5 Mon Sep 17 00:00:00 2001 From: Miksa Date: Thu, 19 Dec 2024 02:53:37 +0100 Subject: [PATCH 08/23] Fix build --- Cargo.toml | 2 ++ example/src/contract.rs | 14 ++------------ src/tests/mod.rs | 18 +++++++++++++++++- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ff7bb19..6fa3b2e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,6 +25,8 @@ members = ["example"] ethnum = { workspace = true } sha2-const = {workspace = true } libc-print = {version = "0.1.22", optional=true} + +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] rand = {version = "0.8.5"} [features] diff --git a/example/src/contract.rs b/example/src/contract.rs index 677d80d..5e75ffd 100644 --- a/example/src/contract.rs +++ b/example/src/contract.rs @@ -170,11 +170,9 @@ impl rust_runtime::contract::ContractTrait for Contract { #[cfg(test)] mod tests { use rust_runtime::{ - blockchain::{AddressHash, TransactionHash}, - contract::op_20::SELECTOR_BALANCE_OF, + contract::op_20::{SELECTOR_BALANCE_OF, SELECTOR_NAME}, ethnum::u256, tests::{execute, execute_address, execute_address_amount, random_environment}, - WaBuffer, }; use crate::contract::SELECTOR_MINT; @@ -183,15 +181,7 @@ mod tests { fn test_contract_name() { let mut contract = super::Contract::new(); - let mut buffer = WaBuffer::new(0, 1).unwrap(); - let mut result = contract - .execute( - rust_runtime::contract::op_20::SELECTOR_NAME, - buffer.cursor(), - ) - .unwrap(); - - let mut cursor = result.cursor(); + let mut cursor = execute(&mut contract, SELECTOR_NAME); assert_eq!(contract.params.name, cursor.read_string_with_len().unwrap()); } diff --git a/src/tests/mod.rs b/src/tests/mod.rs index b216e14..8ea7fce 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -5,12 +5,28 @@ use crate::{ cursor::Cursor, }; +#[cfg(not(target_arch = "wasm32"))] pub fn random_bytes() -> [u8; 32] { let mut result = [0u8; 32]; result.iter_mut().for_each(|b| *b = rand::random::()); result } +#[cfg(target_arch = "wasm32")] +pub fn random_bytes() -> [u8; 32] { + [0; 32] +} + +#[cfg(not(target_arch = "wasm32"))] +pub fn random_u64() -> u64 { + rand::random() +} + +#[cfg(target_arch = "wasm32")] +pub fn random_u64() -> u64 { + 0 +} + pub fn random_address() -> AddressHash { AddressHash { bytes: random_bytes(), @@ -38,7 +54,7 @@ pub fn random_environment() -> Environment { origin: random_address(), transaction_hash: random_transaction(), timestamp: 0, - safe_rnd: rand::random(), + safe_rnd: random_u64(), } } From 87f4c3d943001d65bc020c44b01fbfb5616cd331 Mon Sep 17 00:00:00 2001 From: Miksa Date: Thu, 19 Dec 2024 12:42:57 +0100 Subject: [PATCH 09/23] WIP - small changes --- Cargo.toml | 2 +- example/src/contract.rs | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6fa3b2e..ce2f0d2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,10 +24,10 @@ members = ["example"] # This crate is much larger than expected. Avoid using it unless absolutely necessary. ethnum = { workspace = true } sha2-const = {workspace = true } -libc-print = {version = "0.1.22", optional=true} [target.'cfg(not(target_arch = "wasm32"))'.dependencies] rand = {version = "0.8.5"} +libc-print = {version = "0.1.22"} [features] std = [] diff --git a/example/src/contract.rs b/example/src/contract.rs index 5e75ffd..d586441 100644 --- a/example/src/contract.rs +++ b/example/src/contract.rs @@ -173,6 +173,7 @@ mod tests { contract::op_20::{SELECTOR_BALANCE_OF, SELECTOR_NAME}, ethnum::u256, tests::{execute, execute_address, execute_address_amount, random_environment}, + ContractTrait, }; use crate::contract::SELECTOR_MINT; @@ -200,13 +201,15 @@ mod tests { let amount = u256::new(10000000); execute_address_amount(&mut contract, SELECTOR_MINT, &address, amount); + execute_address_amount(&mut contract, SELECTOR_MINT, &address, amount); + let mut cursor = execute( &mut contract, rust_runtime::contract::op_20::SELECTOR_TOTAL_SUPPLY, ); - assert_eq!(cursor.read_u256_be().unwrap(), amount); + assert_eq!(cursor.read_u256_be().unwrap(), 2 * amount); let mut cursor = execute_address(&mut contract, SELECTOR_BALANCE_OF, &address); - assert_eq!(cursor.read_u256_be().unwrap(), amount); + assert_eq!(cursor.read_u256_be().unwrap(), 2 * amount); } } From 8d656e95cc021f32fb2d3b4049f6eb0d8d184137 Mon Sep 17 00:00:00 2001 From: Predmet <175954199+impredmet@users.noreply.github.com> Date: Tue, 11 Feb 2025 20:52:05 +0400 Subject: [PATCH 10/23] Add once_cell and spin dependencies; refactor global storage for thread safety --- Cargo.lock | 8 +++++ Cargo.toml | 8 +++-- example/src/contract.rs | 68 +++++++++++++++++++++++++++++++++-------- src/env/global.rs | 2 -- src/env/mod.rs | 5 ++- src/env/store.rs | 49 +++++++++-------------------- src/math/abi.rs | 2 ++ src/storage/mod.rs | 60 ++++++++++++++++++------------------ 8 files changed, 116 insertions(+), 86 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 56d6121..ede1f9a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -80,6 +80,12 @@ dependencies = [ "spin", ] +[[package]] +name = "once_cell" +version = "1.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" + [[package]] name = "ppv-lite86" version = "0.2.20" @@ -143,8 +149,10 @@ version = "0.1.0" dependencies = [ "ethnum", "libc-print", + "once_cell", "rand", "sha2-const", + "spin", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index ce2f0d2..4371126 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,11 +23,13 @@ members = ["example"] [dependencies] # This crate is much larger than expected. Avoid using it unless absolutely necessary. ethnum = { workspace = true } -sha2-const = {workspace = true } +once_cell = "1.20.3" +sha2-const = { workspace = true } +spin = "0.9.8" [target.'cfg(not(target_arch = "wasm32"))'.dependencies] -rand = {version = "0.8.5"} -libc-print = {version = "0.1.22"} +rand = { version = "0.8.5" } +libc-print = { version = "0.1.22" } [features] std = [] diff --git a/example/src/contract.rs b/example/src/contract.rs index d586441..3880249 100644 --- a/example/src/contract.rs +++ b/example/src/contract.rs @@ -133,6 +133,7 @@ impl rust_runtime::contract::op_20::OP20Trait for Contract { fn params(&mut self) -> &mut rust_runtime::OP20Params { &mut self.params } + fn total_supply(&mut self) -> &mut StoredU256 { &mut self.total_supply } @@ -167,19 +168,21 @@ impl rust_runtime::contract::ContractTrait for Contract { fn on_deploy(&mut self, _call_data: CallData) {} } +// To run the tests, run `cargo test -p example` in the root of the workspace #[cfg(test)] mod tests { + use crate::contract::SELECTOR_MINT; use rust_runtime::{ - contract::op_20::{SELECTOR_BALANCE_OF, SELECTOR_NAME}, + contract::op_20::{SELECTOR_BALANCE_OF, SELECTOR_NAME, SELECTOR_TOTAL_SUPPLY}, ethnum::u256, + pointer_storage_reset, tests::{execute, execute_address, execute_address_amount, random_environment}, - ContractTrait, }; - use crate::contract::SELECTOR_MINT; - #[test] fn test_contract_name() { + pointer_storage_reset(); + let mut contract = super::Contract::new(); let mut cursor = execute(&mut contract, SELECTOR_NAME); @@ -187,8 +190,11 @@ mod tests { } #[test] - fn test_contract_total_supply() { + fn test_contract_mint() { + pointer_storage_reset(); + let mut contract = super::Contract::new(); + let address = rust_runtime::tests::random_address(); let environment = alloc::boxed::Box::new(rust_runtime::blockchain::Environment { @@ -200,16 +206,52 @@ mod tests { contract.environment = Some(alloc::boxed::Box::leak(environment)); let amount = u256::new(10000000); - execute_address_amount(&mut contract, SELECTOR_MINT, &address, amount); - execute_address_amount(&mut contract, SELECTOR_MINT, &address, amount); + let mut cursor = execute_address(&mut contract, SELECTOR_BALANCE_OF, &address); + assert_eq!(cursor.read_u256_be().unwrap(), 0); + + for _ in 0..3 { + execute_address_amount(&mut contract, SELECTOR_MINT, &address, amount); + } - let mut cursor = execute( - &mut contract, - rust_runtime::contract::op_20::SELECTOR_TOTAL_SUPPLY, - ); - assert_eq!(cursor.read_u256_be().unwrap(), 2 * amount); + let mut cursor = execute_address(&mut contract, SELECTOR_BALANCE_OF, &address); + assert_eq!(cursor.read_u256_be().unwrap(), 3 * amount); + + execute_address_amount(&mut contract, SELECTOR_MINT, &address, amount); // mint more let mut cursor = execute_address(&mut contract, SELECTOR_BALANCE_OF, &address); - assert_eq!(cursor.read_u256_be().unwrap(), 2 * amount); + assert_eq!(cursor.read_u256_be().unwrap(), 4 * amount); + } + + #[test] + fn test_contract_total_supply() { + pointer_storage_reset(); + + let mut contract = super::Contract::new(); + + let address = rust_runtime::tests::random_address(); + + let environment = alloc::boxed::Box::new(rust_runtime::blockchain::Environment { + deployer: address.clone(), + sender: address.clone(), + ..random_environment() + }); + + contract.environment = Some(alloc::boxed::Box::leak(environment)); + let amount = u256::new(10000000); + + let mut cursor = execute(&mut contract, SELECTOR_TOTAL_SUPPLY); + assert_eq!(cursor.read_u256_be().unwrap(), 0); + + for _ in 0..3 { + execute_address_amount(&mut contract, SELECTOR_MINT, &address, amount); + } + + let mut cursor = execute(&mut contract, SELECTOR_TOTAL_SUPPLY); + assert_eq!(cursor.read_u256_be().unwrap(), 3 * amount); + + execute_address_amount(&mut contract, SELECTOR_MINT, &address, amount); // mint more + + let mut cursor = execute(&mut contract, SELECTOR_TOTAL_SUPPLY); + assert_eq!(cursor.read_u256_be().unwrap(), 4 * amount); } } diff --git a/src/env/global.rs b/src/env/global.rs index cb0d3dc..819e49f 100644 --- a/src/env/global.rs +++ b/src/env/global.rs @@ -1,5 +1,3 @@ -use crate::mem::WaPtr; - #[cfg(target_arch = "wasm32")] #[link(wasm_import_module = "env")] extern "C" { diff --git a/src/env/mod.rs b/src/env/mod.rs index 6dc33e8..8b7ca98 100644 --- a/src/env/mod.rs +++ b/src/env/mod.rs @@ -7,7 +7,6 @@ mod global; mod sha; mod store; -pub use address::*; pub use sha::*; pub use store::*; @@ -21,7 +20,7 @@ pub fn log(text: &str) { } #[cfg(not(target_arch = "wasm32"))] -pub fn log(text: &str) {} +pub fn log(_text: &str) {} #[cfg(target_arch = "wasm32")] pub fn emit(buffer: WaBuffer) { @@ -29,4 +28,4 @@ pub fn emit(buffer: WaBuffer) { } #[cfg(not(target_arch = "wasm32"))] -pub fn emit(buffer: WaBuffer) {} +pub fn emit(_buffer: WaBuffer) {} diff --git a/src/env/store.rs b/src/env/store.rs index 0e01ca6..49b3de7 100644 --- a/src/env/store.rs +++ b/src/env/store.rs @@ -3,10 +3,13 @@ use crate::{ storage::{map::Map, StorageKey, StorageValue}, WaBuffer, }; +use once_cell::sync::Lazy; +use spin::Mutex; -#[allow(dead_code)] +/// For test purposes only: This global storage is used to mock the VM’s load/store behavior. +/// (In production the runtime uses GlobalStore instead.) #[cfg(not(target_arch = "wasm32"))] -static mut STORAGE: Map = Map::new(); +static STORAGE: Lazy>> = Lazy::new(|| Mutex::new(Map::new())); #[cfg(target_arch = "wasm32")] pub fn pointer_store(key: &StorageKey, value: &StorageValue) -> Result { @@ -23,12 +26,11 @@ pub fn pointer_store(key: &StorageKey, value: &StorageValue) -> Result Result { - unsafe { STORAGE.insert(*key, *value) }; + let mut storage = STORAGE.lock(); + storage.insert(*key, *value); Ok(true) } @@ -45,38 +47,17 @@ pub fn pointer_load(key: &StorageKey) -> Result Result { - unsafe { Ok(*STORAGE.get(key).unwrap_or(&StorageValue::ZERO)) } + let storage = STORAGE.lock(); + Ok(*storage.get(key).unwrap_or(&StorageValue::ZERO)) } +/// For unit tests only: Clear the mocked storage. #[cfg(not(target_arch = "wasm32"))] -#[allow(static_mut_refs)] pub fn pointer_storage_reset() { - unsafe { - STORAGE.clear(); - } -} - -/* -pub fn pointer_next_greater_than( - target_pointer: &StorageKey, - value_at_least: &StorageValue, - lte: bool, -) -> Result { - let mut buffer = WaBuffer::new(64, 1)?; - let mut cursor = buffer.cursor(); - cursor.write_bytes(target_pointer)?; - cursor.write_bytes(value_at_least.bytes())?; - cursor.write_bool(lte)?; - - unsafe { - Ok( - WaBuffer::from_raw(super::global::nextPointerGreaterThan(buffer.ptr())) - .data() - .into(), - ) - } + let mut storage = STORAGE.lock(); + storage.clear(); } - */ diff --git a/src/math/abi.rs b/src/math/abi.rs index 16f42dc..ba51f34 100644 --- a/src/math/abi.rs +++ b/src/math/abi.rs @@ -54,6 +54,7 @@ pub fn encode_pointer(unique_identifier: u16, typed: &[u8]) -> StorageKey { final_pointer } +/* #[cfg(test)] mod tests { #[test] @@ -61,3 +62,4 @@ mod tests { let selector = "Abi"; } } +*/ diff --git a/src/storage/mod.rs b/src/storage/mod.rs index 5fbea4e..e23d73d 100644 --- a/src/storage/mod.rs +++ b/src/storage/mod.rs @@ -1,4 +1,6 @@ -use map::Map; +use crate::storage::map::Map; +use once_cell::sync::Lazy; +use spin::Mutex; pub mod array_merger; pub mod key; @@ -12,54 +14,50 @@ pub mod value; pub use key::StorageKey; pub use value::StorageValue; -#[allow(static_mut_refs)] -static mut GLOBAL_STORE: Map = Map::new(); +static GLOBAL_STORE: Lazy>> = + Lazy::new(|| Mutex::new(Map::new())); pub struct GlobalStore {} impl GlobalStore { pub fn get(key: &StorageKey, default_value: StorageValue) -> StorageValue { - if Self::has_key(key) { - #[allow(static_mut_refs)] - unsafe { - if let Some(value) = GLOBAL_STORE.get(key) { - *value - } else { - if let Ok(result) = crate::env::pointer_load(key) { - GLOBAL_STORE.insert(key.clone(), result); - result - } else { + let mut store = GLOBAL_STORE.lock(); + if store.contains_key(key) { + *store.get(key).unwrap() + } else { + match crate::env::pointer_load(key) { + Ok(result) => { + if result == StorageValue::ZERO && default_value != StorageValue::ZERO { + store.insert(key.clone(), default_value); default_value + } else { + store.insert(key.clone(), result); + result } } + Err(_) => default_value, } - } else { - default_value } } pub fn set(key: StorageKey, value: StorageValue) { assert!(crate::env::pointer_store(&key, &value).unwrap()); - - #[allow(static_mut_refs)] - unsafe { - GLOBAL_STORE.insert(key, value); - } + let mut store = GLOBAL_STORE.lock(); + store.insert(key, value); } pub fn has_key(key: &StorageKey) -> bool { - #[allow(static_mut_refs)] - unsafe { - if GLOBAL_STORE.contains_key(key) { - return true; - }; - - if let Ok(result) = crate::env::pointer_load(key) { - GLOBAL_STORE.insert(*key, result); - return !result.zero(); + let mut store = GLOBAL_STORE.lock(); + if store.contains_key(key) { + true + } else { + match crate::env::pointer_load(key) { + Ok(result) => { + store.insert(key.clone(), result); + !result.zero() + } + Err(_) => false, } } - - false } } From 5d71427549e128953b85c4b969266519c2761902 Mon Sep 17 00:00:00 2001 From: Miksa Date: Wed, 12 Feb 2025 12:27:20 +0100 Subject: [PATCH 11/23] Fix problem with mutexes --- Cargo.lock | 7 --- Cargo.toml | 3 +- example/src/contract.rs | 96 ++++++++++++++++++++--------------------- src/env/global.rs | 3 ++ src/env/store.rs | 21 +++++++-- src/storage/mod.rs | 3 +- 6 files changed, 71 insertions(+), 62 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ede1f9a..11cf4d3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -80,12 +80,6 @@ dependencies = [ "spin", ] -[[package]] -name = "once_cell" -version = "1.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" - [[package]] name = "ppv-lite86" version = "0.2.20" @@ -149,7 +143,6 @@ version = "0.1.0" dependencies = [ "ethnum", "libc-print", - "once_cell", "rand", "sha2-const", "spin", diff --git a/Cargo.toml b/Cargo.toml index 4371126..67de62c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,9 +23,8 @@ members = ["example"] [dependencies] # This crate is much larger than expected. Avoid using it unless absolutely necessary. ethnum = { workspace = true } -once_cell = "1.20.3" sha2-const = { workspace = true } -spin = "0.9.8" +spin = { version = "0.9.8", features=["mutex", "lazy"]} [target.'cfg(not(target_arch = "wasm32"))'.dependencies] rand = { version = "0.8.5" } diff --git a/example/src/contract.rs b/example/src/contract.rs index 3880249..56aebc4 100644 --- a/example/src/contract.rs +++ b/example/src/contract.rs @@ -175,83 +175,83 @@ mod tests { use rust_runtime::{ contract::op_20::{SELECTOR_BALANCE_OF, SELECTOR_NAME, SELECTOR_TOTAL_SUPPLY}, ethnum::u256, - pointer_storage_reset, + pointer_storage, tests::{execute, execute_address, execute_address_amount, random_environment}, }; #[test] fn test_contract_name() { - pointer_storage_reset(); + pointer_storage(None, || { + let mut contract = super::Contract::new(); - let mut contract = super::Contract::new(); - - let mut cursor = execute(&mut contract, SELECTOR_NAME); - assert_eq!(contract.params.name, cursor.read_string_with_len().unwrap()); + let mut cursor = execute(&mut contract, SELECTOR_NAME); + assert_eq!(contract.params.name, cursor.read_string_with_len().unwrap()); + }); } #[test] fn test_contract_mint() { - pointer_storage_reset(); + pointer_storage(None, || { + let mut contract = super::Contract::new(); - let mut contract = super::Contract::new(); + let address = rust_runtime::tests::random_address(); - let address = rust_runtime::tests::random_address(); + let environment = alloc::boxed::Box::new(rust_runtime::blockchain::Environment { + deployer: address.clone(), + sender: address.clone(), + ..random_environment() + }); - let environment = alloc::boxed::Box::new(rust_runtime::blockchain::Environment { - deployer: address.clone(), - sender: address.clone(), - ..random_environment() - }); + contract.environment = Some(alloc::boxed::Box::leak(environment)); + let amount = u256::new(10000000); - contract.environment = Some(alloc::boxed::Box::leak(environment)); - let amount = u256::new(10000000); + let mut cursor = execute_address(&mut contract, SELECTOR_BALANCE_OF, &address); + assert_eq!(cursor.read_u256_be().unwrap(), 0); - let mut cursor = execute_address(&mut contract, SELECTOR_BALANCE_OF, &address); - assert_eq!(cursor.read_u256_be().unwrap(), 0); - - for _ in 0..3 { - execute_address_amount(&mut contract, SELECTOR_MINT, &address, amount); - } + for _ in 0..3 { + execute_address_amount(&mut contract, SELECTOR_MINT, &address, amount); + } - let mut cursor = execute_address(&mut contract, SELECTOR_BALANCE_OF, &address); - assert_eq!(cursor.read_u256_be().unwrap(), 3 * amount); + let mut cursor = execute_address(&mut contract, SELECTOR_BALANCE_OF, &address); + assert_eq!(cursor.read_u256_be().unwrap(), 3 * amount); - execute_address_amount(&mut contract, SELECTOR_MINT, &address, amount); // mint more + execute_address_amount(&mut contract, SELECTOR_MINT, &address, amount); // mint more - let mut cursor = execute_address(&mut contract, SELECTOR_BALANCE_OF, &address); - assert_eq!(cursor.read_u256_be().unwrap(), 4 * amount); + let mut cursor = execute_address(&mut contract, SELECTOR_BALANCE_OF, &address); + assert_eq!(cursor.read_u256_be().unwrap(), 4 * amount); + }); } #[test] fn test_contract_total_supply() { - pointer_storage_reset(); + pointer_storage(None, || { + let mut contract = super::Contract::new(); - let mut contract = super::Contract::new(); + let address = rust_runtime::tests::random_address(); - let address = rust_runtime::tests::random_address(); + let environment = alloc::boxed::Box::new(rust_runtime::blockchain::Environment { + deployer: address.clone(), + sender: address.clone(), + ..random_environment() + }); - let environment = alloc::boxed::Box::new(rust_runtime::blockchain::Environment { - deployer: address.clone(), - sender: address.clone(), - ..random_environment() - }); + contract.environment = Some(alloc::boxed::Box::leak(environment)); + let amount = u256::new(10000000); - contract.environment = Some(alloc::boxed::Box::leak(environment)); - let amount = u256::new(10000000); + let mut cursor = execute(&mut contract, SELECTOR_TOTAL_SUPPLY); + assert_eq!(cursor.read_u256_be().unwrap(), 0); - let mut cursor = execute(&mut contract, SELECTOR_TOTAL_SUPPLY); - assert_eq!(cursor.read_u256_be().unwrap(), 0); + for _ in 0..3 { + execute_address_amount(&mut contract, SELECTOR_MINT, &address, amount); + } - for _ in 0..3 { - execute_address_amount(&mut contract, SELECTOR_MINT, &address, amount); - } + let mut cursor = execute(&mut contract, SELECTOR_TOTAL_SUPPLY); + assert_eq!(cursor.read_u256_be().unwrap(), 3 * amount); - let mut cursor = execute(&mut contract, SELECTOR_TOTAL_SUPPLY); - assert_eq!(cursor.read_u256_be().unwrap(), 3 * amount); + execute_address_amount(&mut contract, SELECTOR_MINT, &address, amount); // mint more - execute_address_amount(&mut contract, SELECTOR_MINT, &address, amount); // mint more - - let mut cursor = execute(&mut contract, SELECTOR_TOTAL_SUPPLY); - assert_eq!(cursor.read_u256_be().unwrap(), 4 * amount); + let mut cursor = execute(&mut contract, SELECTOR_TOTAL_SUPPLY); + assert_eq!(cursor.read_u256_be().unwrap(), 4 * amount); + }); } } diff --git a/src/env/global.rs b/src/env/global.rs index 819e49f..480f931 100644 --- a/src/env/global.rs +++ b/src/env/global.rs @@ -1,3 +1,6 @@ +#[cfg(target_arch = "wasm32")] +use crate::mem::WaPtr; + #[cfg(target_arch = "wasm32")] #[link(wasm_import_module = "env")] extern "C" { diff --git a/src/env/store.rs b/src/env/store.rs index 49b3de7..d96d29b 100644 --- a/src/env/store.rs +++ b/src/env/store.rs @@ -3,14 +3,18 @@ use crate::{ storage::{map::Map, StorageKey, StorageValue}, WaBuffer, }; -use once_cell::sync::Lazy; -use spin::Mutex; + +#[allow(unused_imports)] +use spin::{Lazy, Mutex, RwLock}; /// For test purposes only: This global storage is used to mock the VM’s load/store behavior. /// (In production the runtime uses GlobalStore instead.) #[cfg(not(target_arch = "wasm32"))] static STORAGE: Lazy>> = Lazy::new(|| Mutex::new(Map::new())); +#[cfg(not(target_arch = "wasm32"))] +static STORAGE_GUARD: Lazy> = Lazy::new(|| Mutex::new(false)); + #[cfg(target_arch = "wasm32")] pub fn pointer_store(key: &StorageKey, value: &StorageValue) -> Result { let mut buffer = WaBuffer::new(64, 1)?; @@ -57,7 +61,18 @@ pub fn pointer_load(key: &StorageKey) -> Result>, callback: impl FnOnce()) { + let lock = STORAGE_GUARD.lock(); + + if let Some(data) = data { + let mut storage = STORAGE.lock(); + + for (key, value) in data.iter() { + storage.insert(key.clone(), value.clone()); + } + } + + callback(); let mut storage = STORAGE.lock(); storage.clear(); } diff --git a/src/storage/mod.rs b/src/storage/mod.rs index e23d73d..96b9ae6 100644 --- a/src/storage/mod.rs +++ b/src/storage/mod.rs @@ -1,6 +1,5 @@ use crate::storage::map::Map; -use once_cell::sync::Lazy; -use spin::Mutex; +use spin::{Lazy, Mutex}; pub mod array_merger; pub mod key; From 316473ee58fb922ce2c16099f5d263516097a099 Mon Sep 17 00:00:00 2001 From: Miksa Date: Wed, 12 Feb 2025 16:01:16 +0100 Subject: [PATCH 12/23] Fix STORAGE_GUARD mutex --- example/src/contract.rs | 16 ++++++---------- src/blockchain/environment.rs | 5 +++++ src/env/store.rs | 6 +++++- src/tests/mod.rs | 10 ---------- 4 files changed, 16 insertions(+), 21 deletions(-) diff --git a/example/src/contract.rs b/example/src/contract.rs index 56aebc4..997e1e2 100644 --- a/example/src/contract.rs +++ b/example/src/contract.rs @@ -183,7 +183,6 @@ mod tests { fn test_contract_name() { pointer_storage(None, || { let mut contract = super::Contract::new(); - let mut cursor = execute(&mut contract, SELECTOR_NAME); assert_eq!(contract.params.name, cursor.read_string_with_len().unwrap()); }); @@ -195,14 +194,12 @@ mod tests { let mut contract = super::Contract::new(); let address = rust_runtime::tests::random_address(); - - let environment = alloc::boxed::Box::new(rust_runtime::blockchain::Environment { + contract.environment = rust_runtime::blockchain::Environment { deployer: address.clone(), sender: address.clone(), ..random_environment() - }); - - contract.environment = Some(alloc::boxed::Box::leak(environment)); + } + .leak(); let amount = u256::new(10000000); let mut cursor = execute_address(&mut contract, SELECTOR_BALANCE_OF, &address); @@ -229,13 +226,12 @@ mod tests { let address = rust_runtime::tests::random_address(); - let environment = alloc::boxed::Box::new(rust_runtime::blockchain::Environment { + contract.environment = rust_runtime::blockchain::Environment { deployer: address.clone(), sender: address.clone(), ..random_environment() - }); - - contract.environment = Some(alloc::boxed::Box::leak(environment)); + } + .leak(); let amount = u256::new(10000000); let mut cursor = execute(&mut contract, SELECTOR_TOTAL_SUPPLY); diff --git a/src/blockchain/environment.rs b/src/blockchain/environment.rs index 804614d..da8636f 100644 --- a/src/blockchain/environment.rs +++ b/src/blockchain/environment.rs @@ -34,6 +34,11 @@ impl Environment { safe_rnd, } } + + pub fn leak(self) -> Option<&'static Environment> { + let leak: &'static Environment = alloc::boxed::Box::leak(alloc::boxed::Box::new(self)); + Some(leak) + } } #[allow(dead_code)] diff --git a/src/env/store.rs b/src/env/store.rs index d96d29b..38622de 100644 --- a/src/env/store.rs +++ b/src/env/store.rs @@ -5,7 +5,8 @@ use crate::{ }; #[allow(unused_imports)] -use spin::{Lazy, Mutex, RwLock}; +#[cfg(not(target_arch = "wasm32"))] +use spin::{Lazy, Mutex}; /// For test purposes only: This global storage is used to mock the VM’s load/store behavior. /// (In production the runtime uses GlobalStore instead.) @@ -75,4 +76,7 @@ pub fn pointer_storage(data: Option>, callback: im callback(); let mut storage = STORAGE.lock(); storage.clear(); + + // Variable must by used!!! + drop(lock); } diff --git a/src/tests/mod.rs b/src/tests/mod.rs index 8ea7fce..876636a 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -12,21 +12,11 @@ pub fn random_bytes() -> [u8; 32] { result } -#[cfg(target_arch = "wasm32")] -pub fn random_bytes() -> [u8; 32] { - [0; 32] -} - #[cfg(not(target_arch = "wasm32"))] pub fn random_u64() -> u64 { rand::random() } -#[cfg(target_arch = "wasm32")] -pub fn random_u64() -> u64 { - 0 -} - pub fn random_address() -> AddressHash { AddressHash { bytes: random_bytes(), From 29b8b7c2d0e18e5ee08991434939d83ce6fab941 Mon Sep 17 00:00:00 2001 From: Miksa Date: Fri, 21 Feb 2025 13:43:35 +0100 Subject: [PATCH 13/23] WIP - new version of env --- Cargo.lock | 61 ++++++++++++++++++ Cargo.toml | 1 + example/src/contract.rs | 105 ++++++++++++++++--------------- example/src/lib.rs | 2 +- src/blockchain/address.rs | 3 +- src/blockchain/transaction.rs | 4 ++ src/contract/mod.rs | 12 ++-- src/contract/op_20.rs | 100 ++++++++++++++++++++---------- src/env/address.rs | 3 + src/env/global.rs | 33 ++++++++++ src/env/{sha.rs => hash.rs} | 32 ++++++++++ src/env/mod.rs | 99 ++++++++++++++++++++++++----- src/env/test.rs | 113 ++++++++++++++++++++++++++++++++++ src/event/mod.rs | 5 +- src/math/abi.rs | 19 +----- src/storage/array_merger.rs | 20 +++--- src/storage/mod.rs | 2 + src/storage/stored.rs | 39 ++++++------ src/storage/stored_map.rs | 16 ++--- src/storage/stored_string.rs | 32 +++++----- 20 files changed, 522 insertions(+), 179 deletions(-) rename src/env/{sha.rs => hash.rs} (66%) create mode 100644 src/env/test.rs diff --git a/Cargo.lock b/Cargo.lock index 11cf4d3..f297326 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,6 +8,15 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + [[package]] name = "byteorder" version = "1.5.0" @@ -20,6 +29,26 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + [[package]] name = "ethnum" version = "1.5.0" @@ -35,6 +64,16 @@ dependencies = [ "sha2-const", ] +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + [[package]] name = "getrandom" version = "0.2.15" @@ -137,6 +176,15 @@ dependencies = [ "getrandom", ] +[[package]] +name = "ripemd" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" +dependencies = [ + "digest", +] + [[package]] name = "rust_runtime" version = "0.1.0" @@ -144,6 +192,7 @@ dependencies = [ "ethnum", "libc-print", "rand", + "ripemd", "sha2-const", "spin", ] @@ -180,12 +229,24 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "typenum" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" + [[package]] name = "unicode-ident" version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" diff --git a/Cargo.toml b/Cargo.toml index 67de62c..fdf26ba 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,6 +29,7 @@ spin = { version = "0.9.8", features=["mutex", "lazy"]} [target.'cfg(not(target_arch = "wasm32"))'.dependencies] rand = { version = "0.8.5" } libc-print = { version = "0.1.22" } +ripemd = "0.1.3" [features] std = [] diff --git a/example/src/contract.rs b/example/src/contract.rs index 997e1e2..d98a6bb 100644 --- a/example/src/contract.rs +++ b/example/src/contract.rs @@ -10,22 +10,23 @@ use rust_runtime::{ StorageValue, }, types::{CallData, Selector}, - ContractTrait, OP20Trait, + ContractTrait, EnvMethods, OP20Trait, }; const SELECTOR_AIRDROP: Selector = encode_selector_const("airdrop"); const SELECTOR_AIRDROP_WITH_AMOUNT: Selector = encode_selector_const("airdropWithAmount"); const SELECTOR_MINT: Selector = encode_selector_const("mint"); -pub struct Contract { - environment: Option<&'static rust_runtime::blockchain::Environment>, +pub struct Contract<'a> { + environment: Option<&'a rust_runtime::blockchain::Environment>, params: rust_runtime::contract::op_20::OP20Params, balance_of_map: StoredMap, allowance_map: MultiAddressMemoryMap, total_supply: StoredU256, + methods: &'a impl EnvMethods, } -impl Contract { - pub const fn new() -> Self { +impl<'a> Contract<'a> { + pub const fn new(methods: &'a impl EnvMethods) -> Self { Self { environment: None, params: rust_runtime::contract::op_20::OP20Params { @@ -43,6 +44,7 @@ impl Contract { StorageValue::ZERO, ), total_supply: StoredU256::new_const(Pointer::TotalSupply.u16(), u256::ZERO), + methods, } } } @@ -181,73 +183,70 @@ mod tests { #[test] fn test_contract_name() { - pointer_storage(None, || { - let mut contract = super::Contract::new(); - let mut cursor = execute(&mut contract, SELECTOR_NAME); - assert_eq!(contract.params.name, cursor.read_string_with_len().unwrap()); - }); + let local_methods = rust_runtime::env::LocalMethods::new(); + let mut contract = super::Contract::new(&local_methods); + let mut cursor = execute(&mut contract, SELECTOR_NAME); + assert_eq!(contract.params.name, cursor.read_string_with_len().unwrap()); } #[test] fn test_contract_mint() { - pointer_storage(None, || { - let mut contract = super::Contract::new(); - - let address = rust_runtime::tests::random_address(); - contract.environment = rust_runtime::blockchain::Environment { - deployer: address.clone(), - sender: address.clone(), - ..random_environment() - } - .leak(); - let amount = u256::new(10000000); + let local_methods = rust_runtime::env::LocalMethods::new(); + let mut contract = super::Contract::new(&local_methods); + + let address = rust_runtime::tests::random_address(); + contract.environment = rust_runtime::blockchain::Environment { + deployer: address.clone(), + sender: address.clone(), + ..random_environment() + } + .leak(); + let amount = u256::new(10000000); - let mut cursor = execute_address(&mut contract, SELECTOR_BALANCE_OF, &address); - assert_eq!(cursor.read_u256_be().unwrap(), 0); + let mut cursor = execute_address(&mut contract, SELECTOR_BALANCE_OF, &address); + assert_eq!(cursor.read_u256_be().unwrap(), 0); - for _ in 0..3 { - execute_address_amount(&mut contract, SELECTOR_MINT, &address, amount); - } + for _ in 0..3 { + execute_address_amount(&mut contract, SELECTOR_MINT, &address, amount); + } - let mut cursor = execute_address(&mut contract, SELECTOR_BALANCE_OF, &address); - assert_eq!(cursor.read_u256_be().unwrap(), 3 * amount); + let mut cursor = execute_address(&mut contract, SELECTOR_BALANCE_OF, &address); + assert_eq!(cursor.read_u256_be().unwrap(), 3 * amount); - execute_address_amount(&mut contract, SELECTOR_MINT, &address, amount); // mint more + execute_address_amount(&mut contract, SELECTOR_MINT, &address, amount); // mint more - let mut cursor = execute_address(&mut contract, SELECTOR_BALANCE_OF, &address); - assert_eq!(cursor.read_u256_be().unwrap(), 4 * amount); - }); + let mut cursor = execute_address(&mut contract, SELECTOR_BALANCE_OF, &address); + assert_eq!(cursor.read_u256_be().unwrap(), 4 * amount); } #[test] fn test_contract_total_supply() { - pointer_storage(None, || { - let mut contract = super::Contract::new(); + let local_methods = rust_runtime::env::LocalMethods::new(); + let mut contract = super::Contract::new(&local_methods); - let address = rust_runtime::tests::random_address(); + let address = rust_runtime::tests::random_address(); - contract.environment = rust_runtime::blockchain::Environment { - deployer: address.clone(), - sender: address.clone(), - ..random_environment() - } - .leak(); - let amount = u256::new(10000000); + contract.environment = rust_runtime::blockchain::Environment { + deployer: address.clone(), + sender: address.clone(), + ..random_environment() + } + .leak(); + let amount = u256::new(10000000); - let mut cursor = execute(&mut contract, SELECTOR_TOTAL_SUPPLY); - assert_eq!(cursor.read_u256_be().unwrap(), 0); + let mut cursor = execute(&mut contract, SELECTOR_TOTAL_SUPPLY); + assert_eq!(cursor.read_u256_be().unwrap(), 0); - for _ in 0..3 { - execute_address_amount(&mut contract, SELECTOR_MINT, &address, amount); - } + for _ in 0..3 { + execute_address_amount(&mut contract, SELECTOR_MINT, &address, amount); + } - let mut cursor = execute(&mut contract, SELECTOR_TOTAL_SUPPLY); - assert_eq!(cursor.read_u256_be().unwrap(), 3 * amount); + let mut cursor = execute(&mut contract, SELECTOR_TOTAL_SUPPLY); + assert_eq!(cursor.read_u256_be().unwrap(), 3 * amount); - execute_address_amount(&mut contract, SELECTOR_MINT, &address, amount); // mint more + execute_address_amount(&mut contract, SELECTOR_MINT, &address, amount); // mint more - let mut cursor = execute(&mut contract, SELECTOR_TOTAL_SUPPLY); - assert_eq!(cursor.read_u256_be().unwrap(), 4 * amount); - }); + let mut cursor = execute(&mut contract, SELECTOR_TOTAL_SUPPLY); + assert_eq!(cursor.read_u256_be().unwrap(), 4 * amount); } } diff --git a/example/src/lib.rs b/example/src/lib.rs index d175ddf..a8953bd 100644 --- a/example/src/lib.rs +++ b/example/src/lib.rs @@ -6,7 +6,7 @@ use rust_runtime::prelude::{ContractTrait, WaBuffer, WaPtr}; pub mod contract; #[allow(dead_code, static_mut_refs)] -static mut CONTRACT: contract::Contract = contract::Contract::new(); +static mut CONTRACT: contract::Contract = contract::Contract::new(rust_runtime::GLOBAL_METHODS); #[cfg(target_arch = "wasm32")] use lol_alloc::LeakingPageAllocator; diff --git a/src/blockchain/address.rs b/src/blockchain/address.rs index 0927eb0..2bd8566 100644 --- a/src/blockchain/address.rs +++ b/src/blockchain/address.rs @@ -1,7 +1,6 @@ - use crate::storage::StorageKey; -#[derive(Clone, Copy, Eq, PartialEq)] +#[derive(Clone, Copy, Eq, PartialEq, Debug)] pub struct AddressHash { pub bytes: [u8; crate::constant::ADDRESS_BYTE_LENGTH], } diff --git a/src/blockchain/transaction.rs b/src/blockchain/transaction.rs index 38b4534..255cb05 100644 --- a/src/blockchain/transaction.rs +++ b/src/blockchain/transaction.rs @@ -1,3 +1,4 @@ +#[derive(Clone, Debug)] pub struct TransactionHash { pub bytes: [u8; crate::constant::TRANSACTION_HASH_LENGTH], } @@ -7,18 +8,21 @@ impl crate::utils::ToHex for TransactionHash { } } +#[derive(Clone, Debug)] pub struct Transaction { pub sender: super::AddressHash, pub origin: super::AddressHash, pub hash: TransactionHash, } +#[derive(Clone, Debug)] pub struct Output { pub index: u8, pub script_pub_key: [u8; 32], pub value: u64, } +#[derive(Clone, Debug)] pub struct Input { pub tx_id: [u8; 32], pub output_index: u8, diff --git a/src/contract/mod.rs b/src/contract/mod.rs index f71d11e..4d35f84 100644 --- a/src/contract/mod.rs +++ b/src/contract/mod.rs @@ -1,4 +1,4 @@ -use crate::{blockchain::AddressHash, mem::WaBuffer, types::CallData}; +use crate::{blockchain::AddressHash, mem::WaBuffer, types::CallData, Context}; pub mod op_20; @@ -7,6 +7,8 @@ pub trait ContractTrait { fn environment(&self) -> &'static crate::blockchain::Environment; + fn context(&self) -> &mut impl crate::env::Context; + fn is_self(&self, address: &AddressHash) -> bool { address.eq(&self.environment().address) } @@ -19,17 +21,17 @@ pub trait ContractTrait { } } - fn emit(event: &impl crate::event::EventTrait) -> Result<(), crate::error::Error> { - crate::env::emit(event.buffer()); + fn emit(&mut self, event: &impl crate::event::EventTrait) -> Result<(), crate::error::Error> { + self.context().emit(event); Ok(()) } fn on_deploy(&mut self, _call_data: CallData) { - crate::log("On Deploy is not implemented"); + self.context().log("On Deploy is not implemented"); } fn execute(&mut self, _call_data: CallData) -> Result { - crate::log("Execute is not implemented"); + self.context().log("Execute is not implemented"); unimplemented!("Execute needs to be implemented"); } } diff --git a/src/contract/op_20.rs b/src/contract/op_20.rs index 0dd1535..5a79a00 100644 --- a/src/contract/op_20.rs +++ b/src/contract/op_20.rs @@ -3,6 +3,7 @@ use ethnum::u256; use crate::{ blockchain::AddressHash, constant::ADDRESS_BYTE_LENGTH, + env::Context, math::abi::encode_selector_const, storage::{ multi_address_map::MultiAddressMemoryMap, @@ -134,7 +135,7 @@ pub trait OP20Trait: super::ContractTrait { fn allowance_base(&mut self, owner: &AddressHash, spender: &AddressHash) -> u256 { let mut sender_map = self.allowance_map().get(owner); - sender_map.get(&spender.bytes).u256() + sender_map.get(self.context(), &spender.bytes).u256() } fn allowance( @@ -166,9 +167,9 @@ pub trait OP20Trait: super::ContractTrait { } let mut sender_map = self.allowance_map().get(owner); - sender_map.set(&spender.bytes, value.into()); + sender_map.set(self.context(), &spender.bytes, value.into()); - Self::create_approve_event(*owner, *spender, value)?; + self.create_approve_event(*owner, *spender, value)?; Ok(true) } @@ -186,7 +187,9 @@ pub trait OP20Trait: super::ContractTrait { } fn balance_of_base(&mut self, address: &AddressHash) -> u256 { - self.balance_of_map().get(address, u256::ZERO).into() + self.balance_of_map() + .get(self.context(), address, u256::ZERO) + .into() } fn balance_of( @@ -216,19 +219,24 @@ pub trait OP20Trait: super::ContractTrait { } let sender = self.environment().sender; - if !self.balance_of_map().contains_key(&sender) { + if !self.balance_of_map().contains_key(self.context(), &sender) { return Err(crate::error::Error::NoBalance); } - let balance: u256 = self.balance_of_map().get(&sender, u256::ZERO).u256(); + let balance: u256 = self + .balance_of_map() + .get(self.context(), &sender, u256::ZERO) + .u256(); if balance < value { return Err(crate::error::Error::InsufficientBalance); } let new_balance = balance - value; - self.balance_of_map().set(&sender, new_balance); + self.balance_of_map() + .set(self.context(), &sender, new_balance); + let value = self.total_supply().set(total_supply - value); - Self::create_burn_event(self.total_supply().set(total_supply - value))?; + self.create_burn_event(value)?; Ok(true) } @@ -255,11 +263,15 @@ pub trait OP20Trait: super::ContractTrait { self.only_deployer(&self.environment().sender)?; } - if !self.balance_of_map().contains_key(to) { - self.balance_of_map().set(to, value); + if !self.balance_of_map().contains_key(self.context(), to) { + self.balance_of_map().set(self.context(), to, value); } else { - let to_balance = self.balance_of_map().get(to, u256::ZERO).u256(); - self.balance_of_map().set(to, to_balance + value); + let to_balance = self + .balance_of_map() + .get(self.context(), to, u256::ZERO) + .u256(); + self.balance_of_map() + .set(self.context(), to, to_balance + value); } let old = self.total_supply().value(); @@ -270,7 +282,7 @@ pub trait OP20Trait: super::ContractTrait { } self.total_supply().set(new); - Self::create_mint_event(*to, value)?; + self.create_mint_event(*to, value)?; Ok(true) } @@ -289,19 +301,26 @@ pub trait OP20Trait: super::ContractTrait { return Err(crate::error::Error::CannotTransferZeroTokens); } - let balance = self.balance_of_map().get(&sender, u256::ZERO).u256(); + let balance = self + .balance_of_map() + .get(self.context(), &sender, u256::ZERO) + .u256(); if balance < value { return Err(crate::error::Error::InsufficientBalance); } let new_balance = balance - value; - self.balance_of_map().set(&sender, new_balance); + self.balance_of_map() + .set(self.context(), &sender, new_balance); - let balance = self.balance_of_map().get(to, u256::ZERO).u256(); + let balance = self + .balance_of_map() + .get(self.context(), to, u256::ZERO) + .u256(); let new_balance = balance + value; - self.balance_of_map().set(to, new_balance); + self.balance_of_map().set(self.context(), to, new_balance); - Self::create_transfer_event(sender, *to, value)?; + self.create_transfer_event(sender, *to, value)?; Ok(true) } @@ -326,14 +345,16 @@ pub trait OP20Trait: super::ContractTrait { value: u256, ) -> Result<(), crate::error::Error> { let mut deployer_allowance_map = self.allowance_map().get(deployer); - let allowed: u256 = deployer_allowance_map.get(&spender.bytes).u256(); + let allowed: u256 = deployer_allowance_map + .get(self.context(), &spender.bytes) + .u256(); if allowed < value { return Err(crate::error::Error::InsufficientAllowance); } let new_allowance = allowed - value; - deployer_allowance_map.set(&spender.bytes, new_allowance.into()); + deployer_allowance_map.set(self.context(), &spender.bytes, new_allowance.into()); self.allowance_map().set(*deployer, deployer_allowance_map); Ok(()) } @@ -344,23 +365,30 @@ pub trait OP20Trait: super::ContractTrait { to: &AddressHash, value: u256, ) -> Result { - let balance: u256 = self.balance_of_map().get(from, u256::ZERO).u256(); + let balance: u256 = self + .balance_of_map() + .get(self.context(), from, u256::ZERO) + .u256(); if balance < value { return Err(crate::error::Error::InsufficientBalance); } let new_balance = balance - value; - self.balance_of_map().set(from, new_balance); + self.balance_of_map().set(self.context(), from, new_balance); - if !self.balance_of_map().contains_key(to) { - self.balance_of_map().set(to, value); + if !self.balance_of_map().contains_key(self.context(), to) { + self.balance_of_map().set(self.context(), to, value); } else { - let to_balance: u256 = self.balance_of_map().get(to, u256::ZERO).u256(); + let to_balance: u256 = self + .balance_of_map() + .get(self.context(), to, u256::ZERO) + .u256(); let new_to_balance = to_balance + value; - self.balance_of_map().set(to, new_to_balance); + self.balance_of_map() + .set(self.context(), to, new_to_balance); } - Self::create_transfer_event(*from, *to, value)?; + self.create_transfer_event(*from, *to, value)?; Ok(true) } @@ -395,32 +423,38 @@ pub trait OP20Trait: super::ContractTrait { Ok(response) } - fn create_burn_event(value: u256) -> Result<(), crate::error::Error> { + fn create_burn_event(&mut self, value: u256) -> Result<(), crate::error::Error> { let burn_event = crate::event::Event::burn(value)?; - Self::emit(&burn_event) + Ok(self.context().emit(&burn_event)) } fn create_approve_event( + &self, deployer: AddressHash, spender: AddressHash, value: u256, ) -> Result<(), crate::error::Error> { let approve_event = crate::event::Event::approve(deployer, spender, value)?; - Self::emit(&approve_event) + Ok(self.context().emit(&approve_event)) } - fn create_mint_event(deployer: AddressHash, amount: u256) -> Result<(), crate::error::Error> { + fn create_mint_event( + &mut self, + deployer: AddressHash, + amount: u256, + ) -> Result<(), crate::error::Error> { let mint_event = crate::event::Event::mint(deployer, amount)?; - Self::emit(&mint_event) + Ok(self.context().emit(&mint_event)) } fn create_transfer_event( + &mut self, from: AddressHash, to: AddressHash, amount: u256, ) -> Result<(), crate::error::Error> { let transfer_event = crate::event::Event::transfer(from, to, amount)?; - Self::emit(&transfer_event) + Ok(self.context().emit(&transfer_event)) } } diff --git a/src/env/address.rs b/src/env/address.rs index c0614e5..0d458f8 100644 --- a/src/env/address.rs +++ b/src/env/address.rs @@ -10,3 +10,6 @@ pub fn validate_bitcoin_address(address: &str) -> Result Result {} diff --git a/src/env/global.rs b/src/env/global.rs index 480f931..c366157 100644 --- a/src/env/global.rs +++ b/src/env/global.rs @@ -1,5 +1,6 @@ #[cfg(target_arch = "wasm32")] use crate::mem::WaPtr; +use crate::storage::map::Map; #[cfg(target_arch = "wasm32")] #[link(wasm_import_module = "env")] @@ -28,6 +29,8 @@ extern "C" { #[allow(dead_code)] pub fn validateBitcoinAddress(ptr: WaPtr) -> WaPtr; #[allow(dead_code)] + pub fn verifySchnorrSignature(ptr: WaPtr) -> WaPtr; + #[allow(dead_code)] pub fn sha256(ptr: WaPtr) -> WaPtr; #[allow(dead_code)] pub fn ripemd160(ptr: WaPtr) -> WaPtr; @@ -36,3 +39,33 @@ extern "C" { #[allow(dead_code)] pub fn outputs() -> WaPtr; } + +#[cfg(target_arch = "wasm32")] +pub struct GlobalMethods { + store: Map, +} + +#[cfg(target_arch = "wasm32")] +impl GlobalMethods { + pub const fn new() { + Self { store: Map::new() } + } +} + +#[cfg(target_arch = "wasm32")] +impl super::EnvMethods for GlobalMethods { + fn log(&self, text: &str) { + unsafe { + if let Ok(string) = WaBuffer::from_str(text) { + log(string.ptr()); + } + } + } + + fn emit(buffer: crate::WaBuffer) { + unsafe { emit(buffer.ptr()) } + } +} + +#[cfg(target_arch = "wasm32")] +pub static GLOBAL_METHODS: GlobalMethods = GlobalMethods::new(); diff --git a/src/env/sha.rs b/src/env/hash.rs similarity index 66% rename from src/env/sha.rs rename to src/env/hash.rs index e63307b..e229ce6 100644 --- a/src/env/sha.rs +++ b/src/env/hash.rs @@ -1,6 +1,9 @@ #[allow(unused_imports)] use crate::WaBuffer; +#[allow(unused_imports)] +use ripemd::{Digest, Ripemd160}; + #[cfg(target_arch = "wasm32")] pub fn sha256(bytes: &[u8]) -> Result<&'static [u8], crate::error::Error> { unsafe { @@ -29,6 +32,26 @@ pub fn sha256_double(bytes: &[u8]) -> Result<&'static [u8], crate::error::Error> Ok(alloc::boxed::Box::leak(alloc::boxed::Box::new(second))) } +#[cfg(target_arch = "wasm32")] +pub fn rimemd160(bytes: &[u8]) -> Result<&'static [u8], crate::error::Error> { + unsafe { + Ok(WaBuffer::from_raw(super::global::rimemd160(WaBuffer::from_bytes(bytes)?.ptr())).data()) + } +} + +#[cfg(not(target_arch = "wasm32"))] +pub fn rimemd160(data: &[u8]) -> Result<&'static [u8], crate::error::Error> { + use ripemd::digest::crypto_common::KeyInit; + + let mut hasher = ripemd::Ripemd160::new(); + hasher.update(data); + let hash = hasher.finalize(); + + Ok(alloc::boxed::Box::leak(alloc::boxed::Box::new( + hash.to_vec(), + ))) +} + #[cfg(test)] mod tests { #[test] @@ -52,4 +75,13 @@ mod tests { ) ); } + + #[test] + fn test_ripemd160() { + let text = "Hello world"; + assert_eq!( + crate::utils::to_hex(super::rimemd160(text.as_bytes()).unwrap()), + alloc::string::String::from("0xdbea7bd24eef40a2e79387542e36dd408b77b21a") + ); + } } diff --git a/src/env/mod.rs b/src/env/mod.rs index 8b7ca98..cdb6069 100644 --- a/src/env/mod.rs +++ b/src/env/mod.rs @@ -1,31 +1,102 @@ -use crate::mem::WaBuffer; +use crate::{ + event, + mem::WaBuffer, + storage::{StorageKey, StorageValue}, +}; #[allow(unused_imports)] use core::str::FromStr; -mod address; mod global; -mod sha; -mod store; +mod test; +pub use test::TestContext; -pub use sha::*; -pub use store::*; +#[cfg(target_arch = "wasm32")] +pub use global::GLOBAL_METHODS; #[cfg(target_arch = "wasm32")] -pub fn log(text: &str) { +pub fn sha256(bytes: &[u8]) -> &'static [u8] { unsafe { - if let Ok(string) = WaBuffer::from_str(text) { - global::log(string.ptr()); - } + WaBuffer::from_raw(super::global::sha256( + WaBuffer::from_bytes(bytes).unwrap().ptr(), + )) + .data() } } #[cfg(not(target_arch = "wasm32"))] -pub fn log(_text: &str) {} +pub fn sha256(bytes: &[u8]) -> &'static [u8] { + let sha = alloc::boxed::Box::new(sha2_const::Sha256::new().update(bytes).finalize()); + alloc::boxed::Box::leak(sha) +} #[cfg(target_arch = "wasm32")] -pub fn emit(buffer: WaBuffer) { - unsafe { global::emit(buffer.ptr()) } +pub fn rimemd160(bytes: &[u8]) -> &'static [u8] { + unsafe { + WaBuffer::from_raw(super::global::rimemd160( + WaBuffer::from_bytes(bytes).unwrap().ptr(), + )) + .data() + } } #[cfg(not(target_arch = "wasm32"))] -pub fn emit(_buffer: WaBuffer) {} +pub fn rimemd160(data: &[u8]) -> &'static [u8] { + use ripemd::{Digest, Ripemd160}; + + let mut hasher = ripemd::Ripemd160::new(); + hasher.update(data); + let hash = hasher.finalize(); + + alloc::boxed::Box::leak(alloc::boxed::Box::new(hash.to_vec())) +} + +pub trait Context<'a> { + fn log(&self, text: &str); + fn emit(&mut self, event: &impl crate::event::EventTrait); + fn call(&self, buffer: WaBuffer) -> WaBuffer; + + fn deploy(&self, buffer: WaBuffer) -> WaBuffer; + fn deploy_from_address(&self, buffer: WaBuffer) -> WaBuffer; + + fn load(&mut self, pointer: &StorageKey, default: StorageValue) -> StorageValue; + fn store(&mut self, pointer: StorageKey, value: StorageValue); + fn exists(&mut self, pointer: &StorageKey) -> bool; + fn next_pointer_greater_than(&self, pointer: StorageKey) -> StorageKey; + + fn encode_address(&self, address: &str) -> &'a [u8]; + fn validate_bitcoin_address(&self, address: &str) -> bool; + fn verify_schnorr_signature(&self, data: &[u8]) -> bool; + fn sha256(&self, data: &[u8]) -> &'a [u8] { + sha256(data) + } + fn sha256_double(&self, data: &[u8]) -> &'a [u8]; + fn rimemd160(&self, data: &[u8]) -> &'a [u8] { + rimemd160(data) + } + + fn iter_inputs(&self) -> impl Iterator; + fn iter_outputs(&self) -> impl Iterator; +} + +#[cfg(test)] +mod tests { + #[test] + fn test_sha_256() { + let text = "Hello world"; + assert_eq!( + crate::utils::to_hex(super::sha256(text.as_bytes())), + alloc::string::String::from( + "0x64ec88ca00b268e5ba1a35678a1b5316d212f4f366b2477232534a8aeca37f3c" + ) + ); + } + + #[test] + fn test_ripemd160() { + let text = "Hello world"; + assert_eq!( + crate::utils::to_hex(super::rimemd160(text.as_bytes())), + alloc::string::String::from("0xdbea7bd24eef40a2e79387542e36dd408b77b21a") + ); + } +} diff --git a/src/env/test.rs b/src/env/test.rs new file mode 100644 index 0000000..ca2b30a --- /dev/null +++ b/src/env/test.rs @@ -0,0 +1,113 @@ +use libc_print::libc_println; + +use crate::{ + storage::map::Map, + storage::{StorageKey, StorageValue}, + WaBuffer, +}; + +pub enum Network { + Mainnet, + Testnet, + Preview, +} + +pub struct TestContext { + pub newtork: Network, + pub events: alloc::vec::Vec, + pub global_store: Map, + pub cache_store: Map, + pub inputs: alloc::vec::Vec, + pub outputs: alloc::vec::Vec, +} + +impl<'a> super::Context<'a> for TestContext { + fn emit(&mut self, event: &impl crate::event::EventTrait) { + let event = crate::event::Event::new(event.buffer()); + self.events.push(event); + } + + fn log(&self, text: &str) { + libc_println!("{}", text); + } + + fn call(&self, buffer: crate::WaBuffer) -> WaBuffer { + buffer + } + + fn deploy(&self, buffer: WaBuffer) -> WaBuffer { + buffer + } + + fn deploy_from_address(&self, buffer: WaBuffer) -> WaBuffer { + buffer + } + + fn encode_address(&self, address: &str) -> &'static [u8] { + b"abc" + } + + fn validate_bitcoin_address(&self, address: &str) -> bool { + true + } + + fn verify_schnorr_signature(&self, data: &[u8]) -> bool { + true + } + + fn load( + &mut self, + pointer: &crate::storage::StorageKey, + default_value: crate::storage::StorageValue, + ) -> crate::storage::StorageValue { + if self.cache_store.contains_key(&pointer) { + *self.cache_store.get(&pointer).unwrap() + } else { + match self.global_store.get(&pointer) { + Some(result) => { + if StorageValue::ZERO.eq(result) && default_value != StorageValue::ZERO { + self.cache_store.insert(pointer, default_value); + default_value + } else { + self.cache_store.insert(pointer, *result); + *result + } + } + None => default_value, + } + } + } + + fn store(&mut self, pointer: crate::storage::StorageKey, value: crate::storage::StorageValue) {} + + fn exists(&mut self, pointer: &StorageKey) -> bool { + false + } + + fn next_pointer_greater_than( + &self, + pointer: crate::storage::StorageKey, + ) -> crate::storage::StorageKey { + [0; 32].into() + } + + fn sha256(&self, data: &[u8]) -> &'static [u8] { + b"ab" + } + + fn sha256_double(&self, data: &[u8]) -> &'static [u8] { + b"ab2" + } + + fn rimemd160(&self, data: &[u8]) -> &'static [u8] { + b"ab3" + } + + fn iter_inputs(&self) -> impl Iterator { + self.inputs.iter() + } + + fn iter_outputs(&self) -> impl Iterator { + self.outputs.iter() + } +} diff --git a/src/event/mod.rs b/src/event/mod.rs index ddfa569..41110ad 100644 --- a/src/event/mod.rs +++ b/src/event/mod.rs @@ -6,10 +6,13 @@ pub trait EventTrait { } pub struct Event { - buffer: WaBuffer, + pub buffer: WaBuffer, } impl Event { + pub fn new(buffer: WaBuffer) -> Event { + Self { buffer } + } pub fn approve( owner: AddressHash, spender: AddressHash, diff --git a/src/math/abi.rs b/src/math/abi.rs index ba51f34..6485968 100644 --- a/src/math/abi.rs +++ b/src/math/abi.rs @@ -17,12 +17,7 @@ pub const fn encode_selector_const(selector: &str) -> crate::types::Selector { * Encode selector in the runtime */ pub fn encode_selector(selector: &str) -> crate::types::Selector { - super::bytes::bytes4( - crate::env::sha256(selector.as_bytes()) - .unwrap() - .try_into() - .unwrap(), - ) + super::bytes::bytes4(crate::env::sha256(selector.as_bytes()).try_into().unwrap()) } pub const fn encode_pointer_const(unique_identifier: u16) -> StorageKey { @@ -34,7 +29,7 @@ pub const fn encode_pointer_const(unique_identifier: u16) -> StorageKey { pub fn encode_pointer(unique_identifier: u16, typed: &[u8]) -> StorageKey { let hash = if typed.len() != 32 { - sha256(typed).unwrap() + sha256(typed) } else { typed }; @@ -53,13 +48,3 @@ pub fn encode_pointer(unique_identifier: u16, typed: &[u8]) -> StorageKey { final_pointer } - -/* -#[cfg(test)] -mod tests { - #[test] - fn test_encode_selector() { - let selector = "Abi"; - } -} -*/ diff --git a/src/storage/array_merger.rs b/src/storage/array_merger.rs index 6b449c5..f3ddc29 100644 --- a/src/storage/array_merger.rs +++ b/src/storage/array_merger.rs @@ -1,8 +1,8 @@ use alloc::vec::Vec; -use crate::{math::abi::encode_pointer, storage::StorageKey}; +use crate::{math::abi::encode_pointer, storage::StorageKey, Context}; -use super::{GlobalStore, StorageValue}; +use super::StorageValue; #[derive(Clone, Eq, PartialEq)] pub struct ArrayMerger { @@ -19,19 +19,19 @@ impl ArrayMerger { default_value, } } - pub fn get(&mut self, key: &[u8]) -> StorageValue { - let key = self.get_key_hash(key); - GlobalStore::get(&key, self.default_value) + pub fn get<'a>(&mut self, context: &mut impl Context<'a>, key: &[u8]) -> StorageValue { + let pointer = self.get_key_hash(key); + context.load(&pointer, self.default_value) } - pub fn set(&mut self, key: &[u8], value: StorageValue) { - let key = self.get_key_hash(key); - GlobalStore::set(key, value); + pub fn set<'a>(&mut self, context: &mut impl Context<'a>, key: &[u8], value: StorageValue) { + let pointer = self.get_key_hash(key); + context.store(pointer, value); } - pub fn contains_key(&self, key: &[u8]) -> bool { + pub fn contains_key<'a>(&self, context: &mut impl Context<'a>, key: &[u8]) -> bool { let key = self.get_key_hash(key); - GlobalStore::has_key(&key) + context.exists(&key) } fn get_key_hash(&self, key: &[u8]) -> StorageKey { diff --git a/src/storage/mod.rs b/src/storage/mod.rs index 96b9ae6..e605104 100644 --- a/src/storage/mod.rs +++ b/src/storage/mod.rs @@ -13,6 +13,7 @@ pub mod value; pub use key::StorageKey; pub use value::StorageValue; +/* static GLOBAL_STORE: Lazy>> = Lazy::new(|| Mutex::new(Map::new())); @@ -60,3 +61,4 @@ impl GlobalStore { } } } + */ diff --git a/src/storage/stored.rs b/src/storage/stored.rs index 62616e0..10fe103 100644 --- a/src/storage/stored.rs +++ b/src/storage/stored.rs @@ -1,18 +1,18 @@ use ethnum::u256; -use super::{GlobalStore, StorageKey, StorageValue}; -use crate::{blockchain::AddressHash, math::abi::encode_pointer}; +use super::{StorageKey, StorageValue}; +use crate::{blockchain::AddressHash, math::abi::encode_pointer, Context}; use core::convert::Into; pub trait StoredTrait where D: Into, { - fn value(&mut self) -> T; - fn refresh(&mut self) -> T; - fn set(&mut self, value: T) -> T; - fn set_no_commit(&mut self, value: T) -> T; - fn commit(&mut self); + fn value(&mut self, context: &mut impl Context) -> T; + fn refresh(&mut self, context: &mut impl Context) -> T; + fn set(&mut self, context: &mut impl Context, value: T) -> T; + fn set_no_commit(&mut self, context: &mut impl Context, value: T) -> T; + fn commit(&mut self, context: &mut impl Context); } pub struct Stored @@ -32,24 +32,25 @@ where StorageValue: Into, D: Into + Clone, { - fn value(&mut self) -> T { + fn value(&mut self, context: &mut impl Context) -> T { if let Some(value) = &self.value { *value } else { self.value = Some( - GlobalStore::get( - &self.pointer, - Into::::into(self.default_value.clone().into()), - ) - .into(), + context + .load( + &self.pointer, + Into::::into(self.default_value.clone().into()), + ) + .into(), ); self.value.as_ref().unwrap().clone() } } - fn set(&mut self, value: T) -> T { + fn set(&mut self, context: &mut impl Context, value: T) -> T { if Some(value) != self.value { - GlobalStore::set(self.pointer, value.into()); + context.store(self.pointer, value.into()); self.value = Some(value); value } else { @@ -57,8 +58,8 @@ where } } - fn refresh(&mut self) -> T { - let value = GlobalStore::get( + fn refresh(&mut self, context: &mut impl Context) -> T { + let value = context.load( &self.pointer, Into::::into(self.default_value.clone().into()), ); @@ -71,9 +72,9 @@ where value } - fn commit(&mut self) { + fn commit(&mut self, context: &mut impl Context) { if let Some(value) = self.value { - GlobalStore::set(self.pointer, value.into()); + context.store(self.pointer, value.into()); } } } diff --git a/src/storage/stored_map.rs b/src/storage/stored_map.rs index 9dc8c23..a0da99e 100644 --- a/src/storage/stored_map.rs +++ b/src/storage/stored_map.rs @@ -1,9 +1,9 @@ use core::marker::PhantomData; use ethnum::u256; -use crate::{blockchain::AddressHash, math::abi::encode_pointer}; +use crate::{blockchain::AddressHash, math::abi::encode_pointer, Context}; -use super::{GlobalStore, StorageKey, StorageValue}; +use super::{StorageKey, StorageValue}; pub struct StoredMap where @@ -28,24 +28,24 @@ where } } - pub fn set(&self, key: &K, value: V) { + pub fn set(&self, context: &mut impl Context, key: &K, value: V) { let key: StorageKey = (*key).into(); let key_hash = encode_pointer(self.pointer, &key); let value = Into::::into(value); - GlobalStore::set(key_hash, value); + context.store(key_hash, value); } - pub fn get(&self, key: &K, default_value: V) -> StorageValue { + pub fn get(&self, context: &mut impl Context, key: &K, default_value: V) -> StorageValue { let key: StorageKey = (*key).into(); let key_hash = encode_pointer(self.pointer, &key); - let value = GlobalStore::get(&key_hash, default_value.into()); + let value = context.load(&key_hash, default_value.into()); value } - pub fn contains_key(&self, key: &K) -> bool { + pub fn contains_key(&self, context: &mut impl Context, key: &K) -> bool { let key: StorageKey = (*key).into(); let key_hash = encode_pointer(self.pointer, &key); - let has = GlobalStore::has_key(&key_hash); + let has = context.exists(&key_hash); has } } diff --git a/src/storage/stored_string.rs b/src/storage/stored_string.rs index 8bf9f64..3266c76 100644 --- a/src/storage/stored_string.rs +++ b/src/storage/stored_string.rs @@ -1,8 +1,8 @@ use alloc::string::String; -use crate::{constant::STORE_VALUE_SIZE, storage::StorageValue}; +use crate::{constant::STORE_VALUE_SIZE, storage::StorageValue, Context}; -use super::{stored::StoredTrait, GlobalStore}; +use super::stored::StoredTrait; pub struct StoredString { pointer: u16, @@ -27,7 +27,7 @@ impl StoredString { } } - fn save(&mut self, value: String) -> String { + fn save(&mut self, context: &mut impl Context, value: String) -> String { let bytes = value.as_bytes(); let mut remaining = bytes.len(); let mut offset = [0u8; crate::constant::STORE_VALUE_SIZE]; @@ -39,7 +39,7 @@ impl StoredString { data[4..4 + remaining.min(28)].copy_from_slice(&bytes[0..length]); let key = crate::math::abi::encode_pointer(self.pointer, &offset); remaining -= length; - GlobalStore::set(key, data.into()); + context.store(key, data.into()); while remaining > 0 { length = remaining.min(crate::constant::STORE_VALUE_SIZE); @@ -55,15 +55,15 @@ impl StoredString { remaining -= length; let key = crate::math::abi::encode_pointer(self.pointer, &offset); - GlobalStore::set(key, data.into()); + context.store(key, data.into()); } self.value = Some(value.clone()); value } - fn load(&mut self) -> String { + fn load(&mut self, context: &mut impl Context) -> String { let mut offset = [0u8; crate::constant::STORE_VALUE_SIZE]; - let header = GlobalStore::get( + let header = context.load( &crate::math::abi::encode_pointer(self.pointer, &offset), StorageValue::ZERO, ); @@ -79,7 +79,7 @@ impl StoredString { while remaining > 0 { offset[crate::constant::STORE_KEY_SIZE - 1] += 1; let key = crate::math::abi::encode_pointer(self.pointer, &offset); - let tmp = GlobalStore::get(&key, StorageValue::ZERO); + let tmp = context.load(&key, StorageValue::ZERO); let bytes = tmp.bytes(); length = remaining.min(crate::constant::STORE_VALUE_SIZE); for &byte in bytes.iter().take(length) { @@ -98,15 +98,15 @@ impl StoredString { } impl StoredTrait for StoredString { - fn set(&mut self, value: String) -> String { - self.save(value) + fn set(&mut self, context: &mut impl Context, value: String) -> String { + self.save(context, value) } - fn value(&mut self) -> String { + fn value(&mut self, context: &mut impl Context) -> String { if let Some(value) = &self.value { value.clone() } else { - self.load() + self.load(context) } } @@ -115,13 +115,13 @@ impl StoredTrait for StoredString { value } - fn commit(&mut self) { + fn commit(&mut self, context: &mut impl Context) { if let Some(value) = &self.value { - self.save(value.clone()); + self.save(context, value.clone()); } } - fn refresh(&mut self) -> String { - self.load() + fn refresh(&mut self, context: &mut impl Context) -> String { + self.load(context) } } From 985aa0e31c25922d752477f3fc21fceeaea8d5bf Mon Sep 17 00:00:00 2001 From: Miksa Date: Fri, 21 Feb 2025 14:07:51 +0100 Subject: [PATCH 14/23] WIP - problem with muttable borrows --- src/contract/op_20.rs | 16 +++++---- src/env/mod.rs | 2 +- src/env/test.rs | 24 +++++++++++-- src/storage/stored.rs | 67 +++++++++++++++++++++++------------- src/storage/stored_map.rs | 11 ++++-- src/storage/stored_string.rs | 12 +++---- 6 files changed, 89 insertions(+), 43 deletions(-) diff --git a/src/contract/op_20.rs b/src/contract/op_20.rs index 5a79a00..387c67b 100644 --- a/src/contract/op_20.rs +++ b/src/contract/op_20.rs @@ -87,7 +87,7 @@ pub trait OP20Trait: super::ContractTrait { SELECTOR_TOTAL_SUPPLY => { let mut buffer = WaBuffer::new(32, 1)?; let mut cursor = buffer.cursor(); - cursor.write_u256_be(&self.total_supply().value())?; + cursor.write_u256_be(&self.total_supply().value(self.context()))?; Ok(buffer) } SELECTOR_MAXIMUM_SUPPLY => { @@ -117,10 +117,10 @@ pub trait OP20Trait: super::ContractTrait { fn total_supply(&mut self) -> &mut StoredU256; fn max_supply(&mut self) -> u256 { - self.params().max_supply.value() + self.params().max_supply.value(self.context()) } fn decimals(&mut self) -> u8 { - self.params().decimals.value() + self.params().decimals.value(self.context()) } fn name(&mut self) -> &'static str { @@ -213,7 +213,7 @@ pub trait OP20Trait: super::ContractTrait { self.only_deployer(&self.environment().sender)?; } - let total_supply = self.total_supply().value(); + let total_supply = self.total_supply().value(self.context()); if total_supply < value { return Err(crate::error::Error::InsufficientTotalSupply); } @@ -234,7 +234,9 @@ pub trait OP20Trait: super::ContractTrait { let new_balance = balance - value; self.balance_of_map() .set(self.context(), &sender, new_balance); - let value = self.total_supply().set(total_supply - value); + let value = self + .total_supply() + .set(self.context(), total_supply - value); self.create_burn_event(value)?; @@ -274,13 +276,13 @@ pub trait OP20Trait: super::ContractTrait { .set(self.context(), to, to_balance + value); } - let old = self.total_supply().value(); + let old = self.total_supply().value(self.context()); let new = old + value; if new > self.max_supply() { return Err(crate::error::Error::MaxSupplyReached); } - self.total_supply().set(new); + self.total_supply().set(self.context(), new); self.create_mint_event(*to, value)?; diff --git a/src/env/mod.rs b/src/env/mod.rs index cdb6069..3745ef0 100644 --- a/src/env/mod.rs +++ b/src/env/mod.rs @@ -8,7 +8,7 @@ use core::str::FromStr; mod global; mod test; -pub use test::TestContext; +pub use test::{Network, TestContext}; #[cfg(target_arch = "wasm32")] pub use global::GLOBAL_METHODS; diff --git a/src/env/test.rs b/src/env/test.rs index ca2b30a..2f52e09 100644 --- a/src/env/test.rs +++ b/src/env/test.rs @@ -13,7 +13,7 @@ pub enum Network { } pub struct TestContext { - pub newtork: Network, + pub network: Network, pub events: alloc::vec::Vec, pub global_store: Map, pub cache_store: Map, @@ -21,6 +21,24 @@ pub struct TestContext { pub outputs: alloc::vec::Vec, } +impl TestContext { + pub fn new( + network: Network, + global_store: Map, + inputs: alloc::vec::Vec, + outputs: alloc::vec::Vec, + ) -> Self { + Self { + network, + events: alloc::vec::Vec::new(), + global_store, + cache_store: Map::new(), + inputs, + outputs, + } + } +} + impl<'a> super::Context<'a> for TestContext { fn emit(&mut self, event: &impl crate::event::EventTrait) { let event = crate::event::Event::new(event.buffer()); @@ -66,10 +84,10 @@ impl<'a> super::Context<'a> for TestContext { match self.global_store.get(&pointer) { Some(result) => { if StorageValue::ZERO.eq(result) && default_value != StorageValue::ZERO { - self.cache_store.insert(pointer, default_value); + self.cache_store.insert(*pointer, default_value); default_value } else { - self.cache_store.insert(pointer, *result); + self.cache_store.insert(*pointer, *result); *result } } diff --git a/src/storage/stored.rs b/src/storage/stored.rs index 10fe103..63936f7 100644 --- a/src/storage/stored.rs +++ b/src/storage/stored.rs @@ -8,11 +8,11 @@ pub trait StoredTrait where D: Into, { - fn value(&mut self, context: &mut impl Context) -> T; - fn refresh(&mut self, context: &mut impl Context) -> T; - fn set(&mut self, context: &mut impl Context, value: T) -> T; - fn set_no_commit(&mut self, context: &mut impl Context, value: T) -> T; - fn commit(&mut self, context: &mut impl Context); + fn value<'a>(&mut self, context: &mut impl Context<'a>) -> T; + fn refresh<'a>(&mut self, context: &mut impl Context<'a>) -> T; + fn set<'a>(&mut self, context: &mut impl Context<'a>, value: T) -> T; + fn set_no_commit(&mut self, value: T) -> T; + fn commit<'a>(&mut self, context: &mut impl Context<'a>); } pub struct Stored @@ -32,7 +32,7 @@ where StorageValue: Into, D: Into + Clone, { - fn value(&mut self, context: &mut impl Context) -> T { + fn value<'a>(&mut self, context: &mut impl Context<'a>) -> T { if let Some(value) = &self.value { *value } else { @@ -48,7 +48,7 @@ where } } - fn set(&mut self, context: &mut impl Context, value: T) -> T { + fn set<'a>(&mut self, context: &mut impl Context<'a>, value: T) -> T { if Some(value) != self.value { context.store(self.pointer, value.into()); self.value = Some(value); @@ -58,7 +58,7 @@ where } } - fn refresh(&mut self, context: &mut impl Context) -> T { + fn refresh<'a>(&mut self, context: &mut impl Context<'a>) -> T { let value = context.load( &self.pointer, Into::::into(self.default_value.clone().into()), @@ -72,7 +72,7 @@ where value } - fn commit(&mut self, context: &mut impl Context) { + fn commit<'a>(&mut self, context: &mut impl Context<'a>) { if let Some(value) = self.value { context.store(self.pointer, value.into()); } @@ -114,55 +114,76 @@ pub type StoredAddress = Stored; #[cfg(test)] mod tests { + use alloc::vec::Vec; use ethnum::u256; + use crate::storage::Map; + use crate::TestContext; + use super::StoredTrait; + + fn context() -> TestContext { + TestContext::new( + crate::env::Network::Testnet, + Map::new(), + Vec::new(), + Vec::new(), + ) + } + #[test] fn test_bool() { let mut stored_bool = super::StoredBool::new_const(0, false); - stored_bool.set(true); - assert_eq!(stored_bool.refresh(), true) + let mut context = context(); + stored_bool.set(&mut context, true); + assert_eq!(stored_bool.refresh(&mut context), true) } #[test] fn test_u8() { + let mut context = context(); let mut stored_u8 = super::StoredU8::new_const(0, 0); - stored_u8.set(1); - assert_eq!(stored_u8.refresh(), 1) + stored_u8.set(&mut context, 1); + assert_eq!(stored_u8.refresh(&mut context), 1) } #[test] fn test_u16() { + let mut context = context(); let mut stored_u16 = super::StoredU16::new_const(0, 0); - stored_u16.set(123); - assert_eq!(stored_u16.refresh(), 123) + stored_u16.set(&mut context, 123); + assert_eq!(stored_u16.refresh(&mut context), 123) } #[test] fn test_u32() { + let mut context = context(); let mut stored_u32 = super::StoredU32::new_const(0, 0); - stored_u32.set(123); - assert_eq!(stored_u32.refresh(), 123) + stored_u32.set(&mut context, 123); + assert_eq!(stored_u32.refresh(&mut context), 123) } #[test] fn test_u64() { + let mut context = context(); let mut stored_u64 = super::StoredU64::new_const(0, 0); - stored_u64.set(123); - assert_eq!(stored_u64.refresh(), 123) + stored_u64.set(&mut context, 123); + assert_eq!(stored_u64.refresh(&mut context), 123) } #[test] fn test_u128() { + let mut context = context(); let mut stored_u128 = super::StoredU128::new_const(0, 0); - stored_u128.set(123); - assert_eq!(stored_u128.refresh(), 123) + stored_u128.set(&mut context, 123); + assert_eq!(stored_u128.refresh(&mut context), 123) } #[test] fn test_u256() { + let mut context = context(); let mut stored_u256 = super::StoredU256::new_const(0, u256::new(0)); - stored_u256.set(u256::new(123)); - assert_eq!(stored_u256.refresh(), u256::new(123)) + stored_u256.set(&mut context, u256::new(123)); + assert_eq!(stored_u256.refresh(&mut context), u256::new(123)) } } diff --git a/src/storage/stored_map.rs b/src/storage/stored_map.rs index a0da99e..ac40703 100644 --- a/src/storage/stored_map.rs +++ b/src/storage/stored_map.rs @@ -28,21 +28,26 @@ where } } - pub fn set(&self, context: &mut impl Context, key: &K, value: V) { + pub fn set<'a>(&self, context: &mut impl Context<'a>, key: &K, value: V) { let key: StorageKey = (*key).into(); let key_hash = encode_pointer(self.pointer, &key); let value = Into::::into(value); context.store(key_hash, value); } - pub fn get(&self, context: &mut impl Context, key: &K, default_value: V) -> StorageValue { + pub fn get<'a>( + &self, + context: &mut impl Context<'a>, + key: &K, + default_value: V, + ) -> StorageValue { let key: StorageKey = (*key).into(); let key_hash = encode_pointer(self.pointer, &key); let value = context.load(&key_hash, default_value.into()); value } - pub fn contains_key(&self, context: &mut impl Context, key: &K) -> bool { + pub fn contains_key<'a>(&self, context: &mut impl Context<'a>, key: &K) -> bool { let key: StorageKey = (*key).into(); let key_hash = encode_pointer(self.pointer, &key); let has = context.exists(&key_hash); diff --git a/src/storage/stored_string.rs b/src/storage/stored_string.rs index 3266c76..5203bbf 100644 --- a/src/storage/stored_string.rs +++ b/src/storage/stored_string.rs @@ -27,7 +27,7 @@ impl StoredString { } } - fn save(&mut self, context: &mut impl Context, value: String) -> String { + fn save<'a>(&mut self, context: &mut impl Context<'a>, value: String) -> String { let bytes = value.as_bytes(); let mut remaining = bytes.len(); let mut offset = [0u8; crate::constant::STORE_VALUE_SIZE]; @@ -61,7 +61,7 @@ impl StoredString { value } - fn load(&mut self, context: &mut impl Context) -> String { + fn load<'a>(&mut self, context: &mut impl Context<'a>) -> String { let mut offset = [0u8; crate::constant::STORE_VALUE_SIZE]; let header = context.load( &crate::math::abi::encode_pointer(self.pointer, &offset), @@ -98,11 +98,11 @@ impl StoredString { } impl StoredTrait for StoredString { - fn set(&mut self, context: &mut impl Context, value: String) -> String { + fn set<'a>(&mut self, context: &mut impl Context<'a>, value: String) -> String { self.save(context, value) } - fn value(&mut self, context: &mut impl Context) -> String { + fn value<'a>(&mut self, context: &mut impl Context<'a>) -> String { if let Some(value) = &self.value { value.clone() } else { @@ -115,13 +115,13 @@ impl StoredTrait for StoredString { value } - fn commit(&mut self, context: &mut impl Context) { + fn commit<'a>(&mut self, context: &mut impl Context<'a>) { if let Some(value) = &self.value { self.save(context, value.clone()); } } - fn refresh(&mut self, context: &mut impl Context) -> String { + fn refresh<'a>(&mut self, context: &mut impl Context<'a>) -> String { self.load(context) } } From c7a6044bb007fc3ef95e808d3e04d6deb115e7bd Mon Sep 17 00:00:00 2001 From: Miksa Date: Sun, 23 Feb 2025 19:40:15 +0100 Subject: [PATCH 15/23] Fighitng with mutable borrow --- src/contract/mod.rs | 2 +- src/env/mod.rs | 8 ++++---- src/env/test.rs | 10 ++++++---- src/storage/stored.rs | 2 +- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/contract/mod.rs b/src/contract/mod.rs index 4d35f84..d16b5b1 100644 --- a/src/contract/mod.rs +++ b/src/contract/mod.rs @@ -7,7 +7,7 @@ pub trait ContractTrait { fn environment(&self) -> &'static crate::blockchain::Environment; - fn context(&self) -> &mut impl crate::env::Context; + fn context<'b>(&mut self) -> &'b impl crate::env::Context; fn is_self(&self, address: &AddressHash) -> bool { address.eq(&self.environment().address) diff --git a/src/env/mod.rs b/src/env/mod.rs index 3745ef0..d00d8ba 100644 --- a/src/env/mod.rs +++ b/src/env/mod.rs @@ -52,15 +52,15 @@ pub fn rimemd160(data: &[u8]) -> &'static [u8] { pub trait Context<'a> { fn log(&self, text: &str); - fn emit(&mut self, event: &impl crate::event::EventTrait); + fn emit(&self, event: &impl crate::event::EventTrait); fn call(&self, buffer: WaBuffer) -> WaBuffer; fn deploy(&self, buffer: WaBuffer) -> WaBuffer; fn deploy_from_address(&self, buffer: WaBuffer) -> WaBuffer; - fn load(&mut self, pointer: &StorageKey, default: StorageValue) -> StorageValue; - fn store(&mut self, pointer: StorageKey, value: StorageValue); - fn exists(&mut self, pointer: &StorageKey) -> bool; + fn load(&self, pointer: &StorageKey, default: StorageValue) -> StorageValue; + fn store(&self, pointer: StorageKey, value: StorageValue); + fn exists(&self, pointer: &StorageKey) -> bool; fn next_pointer_greater_than(&self, pointer: StorageKey) -> StorageKey; fn encode_address(&self, address: &str) -> &'a [u8]; diff --git a/src/env/test.rs b/src/env/test.rs index 2f52e09..c19e9ab 100644 --- a/src/env/test.rs +++ b/src/env/test.rs @@ -1,3 +1,5 @@ +use core::ptr::NonNull; + use libc_print::libc_println; use crate::{ @@ -14,9 +16,9 @@ pub enum Network { pub struct TestContext { pub network: Network, - pub events: alloc::vec::Vec, - pub global_store: Map, - pub cache_store: Map, + pub events: NonNull>, + pub global_store: NonNull>, + pub cache_store: NonNull>, pub inputs: alloc::vec::Vec, pub outputs: alloc::vec::Vec, } @@ -30,7 +32,7 @@ impl TestContext { ) -> Self { Self { network, - events: alloc::vec::Vec::new(), + events: NonNull::new(alloc::vec::Vec::new()).unwrap(), global_store, cache_store: Map::new(), inputs, diff --git a/src/storage/stored.rs b/src/storage/stored.rs index 63936f7..017ce76 100644 --- a/src/storage/stored.rs +++ b/src/storage/stored.rs @@ -58,7 +58,7 @@ where } } - fn refresh<'a>(&mut self, context: &mut impl Context<'a>) -> T { + fn refresh<'a>(&mut self, context: &impl Context<'a>) -> T { let value = context.load( &self.pointer, Into::::into(self.default_value.clone().into()), From 1bffea58e803a79274d99b4029406d65030e86d1 Mon Sep 17 00:00:00 2001 From: Miksa Date: Mon, 24 Feb 2025 12:50:21 +0100 Subject: [PATCH 16/23] Add reasonable context --- example/src/contract.rs | 24 ++++-- src/contract/mod.rs | 76 +++++++++++++++--- src/contract/op_20.rs | 98 +++++++++--------------- src/env/mod.rs | 44 ++++++++--- src/env/test.rs | 71 ++++++++--------- src/storage/array_merger.rs | 41 ++++++++-- src/storage/multi_address_map.rs | 20 ++++- src/storage/stored.rs | 127 ++++++++++++++++++------------- src/storage/stored_map.rs | 33 ++++---- src/storage/stored_string.rs | 51 ++++++++----- src/tests/mod.rs | 6 +- 11 files changed, 365 insertions(+), 226 deletions(-) diff --git a/example/src/contract.rs b/example/src/contract.rs index d98a6bb..80c0ef9 100644 --- a/example/src/contract.rs +++ b/example/src/contract.rs @@ -1,3 +1,5 @@ +use core::cell::RefCell; + use rust_runtime::{ blockchain::AddressHash, contract::op_20::Pointer, @@ -10,7 +12,7 @@ use rust_runtime::{ StorageValue, }, types::{CallData, Selector}, - ContractTrait, EnvMethods, OP20Trait, + Context, ContractTrait, EnvMethods, OP20Trait, }; const SELECTOR_AIRDROP: Selector = encode_selector_const("airdrop"); @@ -23,28 +25,30 @@ pub struct Contract<'a> { balance_of_map: StoredMap, allowance_map: MultiAddressMemoryMap, total_supply: StoredU256, - methods: &'a impl EnvMethods, + context: Rc>, } impl<'a> Contract<'a> { - pub const fn new(methods: &'a impl EnvMethods) -> Self { + pub const fn new(context: Rc>) -> Self { Self { environment: None, params: rust_runtime::contract::op_20::OP20Params { max_supply: StoredU256::new_const( + context, Pointer::MaxSupply.u16(), u256::new(100000000000000000000000000), ), - decimals: StoredU8::new_const(Pointer::Decimals.u16(), 18), + decimals: StoredU8::new_const(context, Pointer::Decimals.u16(), 18), name: "MyToken", symbol: "TOKEN", }, - balance_of_map: StoredMap::new(Pointer::BalanceOfMap.u16()), + balance_of_map: StoredMap::new(context, Pointer::BalanceOfMap.u16()), allowance_map: MultiAddressMemoryMap::new( + context, Pointer::AllowanceMap.u16(), StorageValue::ZERO, ), - total_supply: StoredU256::new_const(Pointer::TotalSupply.u16(), u256::ZERO), - methods, + total_supply: StoredU256::new_const(context, Pointer::TotalSupply.u16(), u256::ZERO), + context, } } } @@ -104,7 +108,7 @@ impl Contract { let value = self.total_supply.value() + amount; self.total_supply.set_no_commit(value); - Self::create_mint_event(address, amount)?; + self.create_mint_event(address, amount)?; Ok(()) } @@ -158,6 +162,10 @@ impl rust_runtime::contract::ContractTrait for Contract { self.environment.unwrap() } + fn context(&self) -> alloc::rc::Rc> { + self.context + } + fn execute( &mut self, mut call_data: CallData, diff --git a/src/contract/mod.rs b/src/contract/mod.rs index d16b5b1..43d220a 100644 --- a/src/contract/mod.rs +++ b/src/contract/mod.rs @@ -1,13 +1,22 @@ -use crate::{blockchain::AddressHash, mem::WaBuffer, types::CallData, Context}; +use alloc::rc::Rc; +use alloc::vec::Vec; +use core::cell::RefCell; +use crate::{ + blockchain::AddressHash, + mem::WaBuffer, + storage::{StorageKey, StorageValue}, + types::CallData, + Context, +}; pub mod op_20; -pub trait ContractTrait { +pub trait ContractTrait<'a> { fn set_environment(&mut self, environment: &'static crate::blockchain::Environment); fn environment(&self) -> &'static crate::blockchain::Environment; - fn context<'b>(&mut self) -> &'b impl crate::env::Context; + fn context(&self) -> Rc>; fn is_self(&self, address: &AddressHash) -> bool { address.eq(&self.environment().address) @@ -21,17 +30,64 @@ pub trait ContractTrait { } } - fn emit(&mut self, event: &impl crate::event::EventTrait) -> Result<(), crate::error::Error> { - self.context().emit(event); - Ok(()) - } - fn on_deploy(&mut self, _call_data: CallData) { - self.context().log("On Deploy is not implemented"); + self.context().borrow().log("On Deploy is not implemented"); } fn execute(&mut self, _call_data: CallData) -> Result { - self.context().log("Execute is not implemented"); + self.context().borrow().log("Execute is not implemented"); unimplemented!("Execute needs to be implemented"); } + + fn log(&self, text: &str) { + self.context().borrow().log(text); + } + fn emit(&self, event: &dyn crate::event::EventTrait) { + self.context().borrow_mut().emit(event); + } + fn call(&self, buffer: WaBuffer) -> WaBuffer { + self.context().borrow().call(buffer) + } + + fn load(&self, pointer: &StorageKey) -> Option { + self.context().borrow_mut().load(pointer) + } + fn store(&self, pointer: StorageKey, value: StorageValue) { + self.context().borrow_mut().store(pointer, value) + } + fn exists(&self, pointer: &StorageKey) -> bool { + self.context().borrow_mut().exists(pointer) + } + fn next_pointer_greater_than(&self, pointer: StorageKey) -> StorageKey { + self.context() + .as_ref() + .borrow() + .next_pointer_greater_than(pointer) + } + + fn encode_address(&self, address: &str) -> &'static [u8] { + self.context().borrow().encode_address(address) + } + fn validate_bitcoin_address(&self, address: &str) -> bool { + self.context().borrow().validate_bitcoin_address(address) + } + fn verify_schnorr_signature(&self, data: &[u8]) -> bool { + self.context().borrow().verify_schnorr_signature(data) + } + fn sha256(&self, data: &[u8]) -> &'static [u8] { + self.context().borrow().sha256(data) + } + fn sha256_double(&self, data: &[u8]) -> &'static [u8] { + self.context().borrow().sha256_double(data) + } + fn rimemd160(&self, data: &[u8]) -> &'static [u8] { + self.context().borrow().rimemd160(data) + } + + fn inputs(&self) -> Vec { + self.context().borrow_mut().inputs() + } + fn outputs(&self) -> Vec { + self.context().borrow_mut().outputs() + } } diff --git a/src/contract/op_20.rs b/src/contract/op_20.rs index 387c67b..ff31620 100644 --- a/src/contract/op_20.rs +++ b/src/contract/op_20.rs @@ -51,7 +51,7 @@ pub const SELECTOR_BURN: Selector = encode_selector_const("burn"); pub const SELECTOR_TRANSFER: Selector = encode_selector_const("transfer"); pub const SELECTOR_TRANSFER_FROM: Selector = encode_selector_const("transferFrom"); -pub trait OP20Trait: super::ContractTrait { +pub trait OP20Trait<'a>: super::ContractTrait<'a> { fn execute_base( &mut self, selector: Selector, @@ -87,7 +87,7 @@ pub trait OP20Trait: super::ContractTrait { SELECTOR_TOTAL_SUPPLY => { let mut buffer = WaBuffer::new(32, 1)?; let mut cursor = buffer.cursor(); - cursor.write_u256_be(&self.total_supply().value(self.context()))?; + cursor.write_u256_be(&self.total_supply().value())?; Ok(buffer) } SELECTOR_MAXIMUM_SUPPLY => { @@ -117,10 +117,10 @@ pub trait OP20Trait: super::ContractTrait { fn total_supply(&mut self) -> &mut StoredU256; fn max_supply(&mut self) -> u256 { - self.params().max_supply.value(self.context()) + self.params().max_supply.value() } fn decimals(&mut self) -> u8 { - self.params().decimals.value(self.context()) + self.params().decimals.value() } fn name(&mut self) -> &'static str { @@ -135,7 +135,7 @@ pub trait OP20Trait: super::ContractTrait { fn allowance_base(&mut self, owner: &AddressHash, spender: &AddressHash) -> u256 { let mut sender_map = self.allowance_map().get(owner); - sender_map.get(self.context(), &spender.bytes).u256() + sender_map.get(&spender.bytes).u256() } fn allowance( @@ -167,7 +167,7 @@ pub trait OP20Trait: super::ContractTrait { } let mut sender_map = self.allowance_map().get(owner); - sender_map.set(self.context(), &spender.bytes, value.into()); + sender_map.set(&spender.bytes, value.into()); self.create_approve_event(*owner, *spender, value)?; @@ -187,9 +187,7 @@ pub trait OP20Trait: super::ContractTrait { } fn balance_of_base(&mut self, address: &AddressHash) -> u256 { - self.balance_of_map() - .get(self.context(), address, u256::ZERO) - .into() + self.balance_of_map().get(address, u256::ZERO).into() } fn balance_of( @@ -213,30 +211,24 @@ pub trait OP20Trait: super::ContractTrait { self.only_deployer(&self.environment().sender)?; } - let total_supply = self.total_supply().value(self.context()); + let total_supply = self.total_supply().value(); if total_supply < value { return Err(crate::error::Error::InsufficientTotalSupply); } let sender = self.environment().sender; - if !self.balance_of_map().contains_key(self.context(), &sender) { + if !self.balance_of_map().contains_key(&sender) { return Err(crate::error::Error::NoBalance); } - let balance: u256 = self - .balance_of_map() - .get(self.context(), &sender, u256::ZERO) - .u256(); + let balance: u256 = self.balance_of_map().get(&sender, u256::ZERO); if balance < value { return Err(crate::error::Error::InsufficientBalance); } let new_balance = balance - value; - self.balance_of_map() - .set(self.context(), &sender, new_balance); - let value = self - .total_supply() - .set(self.context(), total_supply - value); + self.balance_of_map().set(&sender, new_balance); + let value = self.total_supply().set(total_supply - value); self.create_burn_event(value)?; @@ -265,24 +257,20 @@ pub trait OP20Trait: super::ContractTrait { self.only_deployer(&self.environment().sender)?; } - if !self.balance_of_map().contains_key(self.context(), to) { - self.balance_of_map().set(self.context(), to, value); + if !self.balance_of_map().contains_key(to) { + self.balance_of_map().set(to, value); } else { - let to_balance = self - .balance_of_map() - .get(self.context(), to, u256::ZERO) - .u256(); - self.balance_of_map() - .set(self.context(), to, to_balance + value); + let to_balance = self.balance_of_map().get(to, u256::ZERO); + self.balance_of_map().set(to, to_balance + value); } - let old = self.total_supply().value(self.context()); + let old = self.total_supply().value(); let new = old + value; if new > self.max_supply() { return Err(crate::error::Error::MaxSupplyReached); } - self.total_supply().set(self.context(), new); + self.total_supply().set(new); self.create_mint_event(*to, value)?; @@ -303,24 +291,17 @@ pub trait OP20Trait: super::ContractTrait { return Err(crate::error::Error::CannotTransferZeroTokens); } - let balance = self - .balance_of_map() - .get(self.context(), &sender, u256::ZERO) - .u256(); + let balance = self.balance_of_map().get(&sender, u256::ZERO); if balance < value { return Err(crate::error::Error::InsufficientBalance); } let new_balance = balance - value; - self.balance_of_map() - .set(self.context(), &sender, new_balance); + self.balance_of_map().set(&sender, new_balance); - let balance = self - .balance_of_map() - .get(self.context(), to, u256::ZERO) - .u256(); + let balance = self.balance_of_map().get(to, u256::ZERO); let new_balance = balance + value; - self.balance_of_map().set(self.context(), to, new_balance); + self.balance_of_map().set(to, new_balance); self.create_transfer_event(sender, *to, value)?; Ok(true) @@ -347,16 +328,14 @@ pub trait OP20Trait: super::ContractTrait { value: u256, ) -> Result<(), crate::error::Error> { let mut deployer_allowance_map = self.allowance_map().get(deployer); - let allowed: u256 = deployer_allowance_map - .get(self.context(), &spender.bytes) - .u256(); + let allowed: u256 = deployer_allowance_map.get(&spender.bytes).u256(); if allowed < value { return Err(crate::error::Error::InsufficientAllowance); } let new_allowance = allowed - value; - deployer_allowance_map.set(self.context(), &spender.bytes, new_allowance.into()); + deployer_allowance_map.set(&spender.bytes, new_allowance.into()); self.allowance_map().set(*deployer, deployer_allowance_map); Ok(()) } @@ -367,27 +346,22 @@ pub trait OP20Trait: super::ContractTrait { to: &AddressHash, value: u256, ) -> Result { - let balance: u256 = self - .balance_of_map() - .get(self.context(), from, u256::ZERO) - .u256(); + let context = self.context().clone(); + + let balance: u256 = self.balance_of_map().get(from, u256::ZERO); if balance < value { return Err(crate::error::Error::InsufficientBalance); } let new_balance = balance - value; - self.balance_of_map().set(self.context(), from, new_balance); + self.balance_of_map().set(from, new_balance); - if !self.balance_of_map().contains_key(self.context(), to) { - self.balance_of_map().set(self.context(), to, value); + if !self.balance_of_map().contains_key(to) { + self.balance_of_map().set(to, value); } else { - let to_balance: u256 = self - .balance_of_map() - .get(self.context(), to, u256::ZERO) - .u256(); + let to_balance: u256 = self.balance_of_map().get(to, u256::ZERO); let new_to_balance = to_balance + value; - self.balance_of_map() - .set(self.context(), to, new_to_balance); + self.balance_of_map().set(to, new_to_balance); } self.create_transfer_event(*from, *to, value)?; @@ -428,7 +402,7 @@ pub trait OP20Trait: super::ContractTrait { fn create_burn_event(&mut self, value: u256) -> Result<(), crate::error::Error> { let burn_event = crate::event::Event::burn(value)?; - Ok(self.context().emit(&burn_event)) + Ok(self.context().borrow_mut().emit(&burn_event)) } fn create_approve_event( @@ -438,7 +412,7 @@ pub trait OP20Trait: super::ContractTrait { value: u256, ) -> Result<(), crate::error::Error> { let approve_event = crate::event::Event::approve(deployer, spender, value)?; - Ok(self.context().emit(&approve_event)) + Ok(self.context().borrow_mut().emit(&approve_event)) } fn create_mint_event( @@ -447,7 +421,7 @@ pub trait OP20Trait: super::ContractTrait { amount: u256, ) -> Result<(), crate::error::Error> { let mint_event = crate::event::Event::mint(deployer, amount)?; - Ok(self.context().emit(&mint_event)) + Ok(self.context().borrow_mut().emit(&mint_event)) } fn create_transfer_event( @@ -457,6 +431,6 @@ pub trait OP20Trait: super::ContractTrait { amount: u256, ) -> Result<(), crate::error::Error> { let transfer_event = crate::event::Event::transfer(from, to, amount)?; - Ok(self.context().emit(&transfer_event)) + Ok(self.context().borrow_mut().emit(&transfer_event)) } } diff --git a/src/env/mod.rs b/src/env/mod.rs index d00d8ba..d1b6fc6 100644 --- a/src/env/mod.rs +++ b/src/env/mod.rs @@ -3,9 +3,9 @@ use crate::{ mem::WaBuffer, storage::{StorageKey, StorageValue}, }; +use alloc::vec::Vec; #[allow(unused_imports)] use core::str::FromStr; - mod global; mod test; pub use test::{Network, TestContext}; @@ -50,32 +50,56 @@ pub fn rimemd160(data: &[u8]) -> &'static [u8] { alloc::boxed::Box::leak(alloc::boxed::Box::new(hash.to_vec())) } -pub trait Context<'a> { +pub struct WrappedMut { + inner: T, +} + +impl WrappedMut { + pub const fn new(t: T) -> WrappedMut { + Self { inner: t } + } + + pub fn as_ref(&self) -> &T { + &self.inner + } + + pub fn as_mut(&self) -> &mut T { + unsafe { + if let Some(val) = ((&self.inner) as *const T as *mut T).as_mut() { + return val; + } else { + panic!("Unexpected null"); + } + } + } +} + +pub trait Context { fn log(&self, text: &str); - fn emit(&self, event: &impl crate::event::EventTrait); + fn emit(&self, event: &dyn crate::event::EventTrait); fn call(&self, buffer: WaBuffer) -> WaBuffer; fn deploy(&self, buffer: WaBuffer) -> WaBuffer; fn deploy_from_address(&self, buffer: WaBuffer) -> WaBuffer; - fn load(&self, pointer: &StorageKey, default: StorageValue) -> StorageValue; + fn load(&self, pointer: &StorageKey) -> Option; fn store(&self, pointer: StorageKey, value: StorageValue); fn exists(&self, pointer: &StorageKey) -> bool; fn next_pointer_greater_than(&self, pointer: StorageKey) -> StorageKey; - fn encode_address(&self, address: &str) -> &'a [u8]; + fn encode_address(&self, address: &str) -> &'static [u8]; fn validate_bitcoin_address(&self, address: &str) -> bool; fn verify_schnorr_signature(&self, data: &[u8]) -> bool; - fn sha256(&self, data: &[u8]) -> &'a [u8] { + fn sha256(&self, data: &[u8]) -> &'static [u8] { sha256(data) } - fn sha256_double(&self, data: &[u8]) -> &'a [u8]; - fn rimemd160(&self, data: &[u8]) -> &'a [u8] { + fn sha256_double(&self, data: &[u8]) -> &'static [u8]; + fn rimemd160(&self, data: &[u8]) -> &'static [u8] { rimemd160(data) } - fn iter_inputs(&self) -> impl Iterator; - fn iter_outputs(&self) -> impl Iterator; + fn inputs(&self) -> Vec; + fn outputs(&self) -> Vec; } #[cfg(test)] diff --git a/src/env/test.rs b/src/env/test.rs index c19e9ab..88da496 100644 --- a/src/env/test.rs +++ b/src/env/test.rs @@ -1,8 +1,9 @@ -use core::ptr::NonNull; - +use alloc::vec::Vec; +use core::cell::RefCell; use libc_print::libc_println; use crate::{ + env::WrappedMut, storage::map::Map, storage::{StorageKey, StorageValue}, WaBuffer, @@ -16,9 +17,9 @@ pub enum Network { pub struct TestContext { pub network: Network, - pub events: NonNull>, - pub global_store: NonNull>, - pub cache_store: NonNull>, + pub events: RefCell>, + pub global_store: RefCell>, + pub cache_store: RefCell>, pub inputs: alloc::vec::Vec, pub outputs: alloc::vec::Vec, } @@ -32,19 +33,21 @@ impl TestContext { ) -> Self { Self { network, - events: NonNull::new(alloc::vec::Vec::new()).unwrap(), - global_store, - cache_store: Map::new(), + events: RefCell::new(alloc::vec::Vec::new()), + global_store: RefCell::new(global_store), + cache_store: RefCell::new(Map::new()), inputs, outputs, } } } -impl<'a> super::Context<'a> for TestContext { - fn emit(&mut self, event: &impl crate::event::EventTrait) { +impl super::Context for TestContext { + fn emit(&self, event: &dyn crate::event::EventTrait) { let event = crate::event::Event::new(event.buffer()); - self.events.push(event); + unsafe { + self.events.borrow_mut().push(event); + } } fn log(&self, text: &str) { @@ -75,32 +78,30 @@ impl<'a> super::Context<'a> for TestContext { true } - fn load( - &mut self, - pointer: &crate::storage::StorageKey, - default_value: crate::storage::StorageValue, - ) -> crate::storage::StorageValue { - if self.cache_store.contains_key(&pointer) { - *self.cache_store.get(&pointer).unwrap() + fn load(&self, pointer: &crate::storage::StorageKey) -> Option { + if let Some(value) = if let Some(value) = self.cache_store.borrow().get(&pointer) { + Some(*value) } else { - match self.global_store.get(&pointer) { - Some(result) => { - if StorageValue::ZERO.eq(result) && default_value != StorageValue::ZERO { - self.cache_store.insert(*pointer, default_value); - default_value - } else { - self.cache_store.insert(*pointer, *result); - *result - } - } - None => default_value, + if let Some(value) = self.global_store.borrow().get(&pointer) { + self.cache_store.borrow_mut().insert(*pointer, *value); + Some(*value) + } else { + None } + } { + if StorageValue::ZERO.eq(&value) { + None + } else { + Some(value) + } + } else { + None } } - fn store(&mut self, pointer: crate::storage::StorageKey, value: crate::storage::StorageValue) {} + fn store(&self, pointer: crate::storage::StorageKey, value: crate::storage::StorageValue) {} - fn exists(&mut self, pointer: &StorageKey) -> bool { + fn exists(&self, pointer: &StorageKey) -> bool { false } @@ -123,11 +124,11 @@ impl<'a> super::Context<'a> for TestContext { b"ab3" } - fn iter_inputs(&self) -> impl Iterator { - self.inputs.iter() + fn inputs(&self) -> Vec { + self.inputs.clone() } - fn iter_outputs(&self) -> impl Iterator { - self.outputs.iter() + fn outputs(&self) -> Vec { + self.outputs.clone() } } diff --git a/src/storage/array_merger.rs b/src/storage/array_merger.rs index f3ddc29..a9c3d8f 100644 --- a/src/storage/array_merger.rs +++ b/src/storage/array_merger.rs @@ -1,37 +1,50 @@ +use core::cell::RefCell; + use alloc::vec::Vec; use crate::{math::abi::encode_pointer, storage::StorageKey, Context}; use super::StorageValue; +use alloc::rc::Rc; -#[derive(Clone, Eq, PartialEq)] +#[derive(Clone)] pub struct ArrayMerger { + context: Rc>, parent_key: Vec, pointer: u16, default_value: StorageValue, } impl ArrayMerger { - pub fn new(parent_key: Vec, pointer: u16, default_value: StorageValue) -> Self { + pub fn new( + context: Rc>, + parent_key: Vec, + pointer: u16, + default_value: StorageValue, + ) -> Self { Self { + context, parent_key, pointer, default_value, } } - pub fn get<'a>(&mut self, context: &mut impl Context<'a>, key: &[u8]) -> StorageValue { + pub fn get<'a>(&mut self, key: &[u8]) -> StorageValue { let pointer = self.get_key_hash(key); - context.load(&pointer, self.default_value) + self.context + .borrow_mut() + .load(&pointer) + .unwrap_or(self.default_value.clone()) } - pub fn set<'a>(&mut self, context: &mut impl Context<'a>, key: &[u8], value: StorageValue) { + pub fn set<'a>(&mut self, key: &[u8], value: StorageValue) { let pointer = self.get_key_hash(key); - context.store(pointer, value); + self.context.borrow_mut().store(pointer, value); } - pub fn contains_key<'a>(&self, context: &mut impl Context<'a>, key: &[u8]) -> bool { + pub fn contains_key<'a>(&self, key: &[u8]) -> bool { let key = self.get_key_hash(key); - context.exists(&key) + self.context.borrow_mut().exists(&key) } fn get_key_hash(&self, key: &[u8]) -> StorageKey { @@ -39,3 +52,15 @@ impl ArrayMerger { encode_pointer(self.pointer, &merged) } } + +impl PartialEq for ArrayMerger { + fn eq(&self, other: &Self) -> bool { + self.parent_key.eq(&other.parent_key) && self.pointer.eq(&other.pointer) + } + + fn ne(&self, other: &Self) -> bool { + self.parent_key.ne(&other.parent_key) && self.pointer.ne(&other.pointer) + } +} + +impl Eq for ArrayMerger {} diff --git a/src/storage/multi_address_map.rs b/src/storage/multi_address_map.rs index 2c942ad..d3627ee 100644 --- a/src/storage/multi_address_map.rs +++ b/src/storage/multi_address_map.rs @@ -1,16 +1,25 @@ -use crate::blockchain::AddressHash; +use alloc::rc::Rc; +use core::cell::RefCell; + +use crate::{blockchain::AddressHash, Context}; use super::{array_merger::ArrayMerger, map::Map, StorageValue}; pub struct MultiAddressMemoryMap { + context: Rc>, pointer: u16, default_value: StorageValue, pub map: Map, } impl MultiAddressMemoryMap { - pub const fn new(pointer: u16, default_value: StorageValue) -> Self { + pub const fn new( + context: Rc>, + pointer: u16, + default_value: StorageValue, + ) -> Self { Self { + context, pointer, default_value, map: Map::new(), @@ -39,7 +48,12 @@ impl MultiAddressMemoryMap { if !self.map.contains_key(key) { self.map.push( *key, - ArrayMerger::new(key.bytes.to_vec(), self.pointer, self.default_value), + ArrayMerger::new( + self.context.clone(), + key.bytes.to_vec(), + self.pointer, + self.default_value, + ), ); } } diff --git a/src/storage/stored.rs b/src/storage/stored.rs index 017ce76..32347b6 100644 --- a/src/storage/stored.rs +++ b/src/storage/stored.rs @@ -1,18 +1,19 @@ use ethnum::u256; -use super::{StorageKey, StorageValue}; +use super::{Map, StorageKey, StorageValue}; use crate::{blockchain::AddressHash, math::abi::encode_pointer, Context}; -use core::convert::Into; +use alloc::rc::Rc; +use core::{cell::RefCell, convert::Into}; pub trait StoredTrait where D: Into, { - fn value<'a>(&mut self, context: &mut impl Context<'a>) -> T; - fn refresh<'a>(&mut self, context: &mut impl Context<'a>) -> T; - fn set<'a>(&mut self, context: &mut impl Context<'a>, value: T) -> T; + fn value<'a>(&mut self) -> T; + fn refresh<'a>(&mut self) -> T; + fn set<'a>(&mut self, value: T) -> T; fn set_no_commit(&mut self, value: T) -> T; - fn commit<'a>(&mut self, context: &mut impl Context<'a>); + fn commit<'a>(&mut self); } pub struct Stored @@ -21,6 +22,7 @@ where StorageValue: Into, D: Into + Clone, { + context: Rc>, pointer: StorageKey, default_value: D, value: Option, @@ -32,25 +34,25 @@ where StorageValue: Into, D: Into + Clone, { - fn value<'a>(&mut self, context: &mut impl Context<'a>) -> T { + fn value(&mut self) -> T { if let Some(value) = &self.value { *value } else { - self.value = Some( - context - .load( - &self.pointer, - Into::::into(self.default_value.clone().into()), - ) - .into(), - ); - self.value.as_ref().unwrap().clone() + let value: T = self + .context + .borrow_mut() + .load(&self.pointer) + .map(|value| value.into()) + .unwrap_or(self.default_value.clone().into()); + + self.value = Some(value.clone()); + value } } - fn set<'a>(&mut self, context: &mut impl Context<'a>, value: T) -> T { + fn set(&mut self, value: T) -> T { if Some(value) != self.value { - context.store(self.pointer, value.into()); + self.context.borrow_mut().store(self.pointer, value.into()); self.value = Some(value); value } else { @@ -58,13 +60,15 @@ where } } - fn refresh<'a>(&mut self, context: &impl Context<'a>) -> T { - let value = context.load( - &self.pointer, - Into::::into(self.default_value.clone().into()), - ); - self.value = Some(value.clone().into()); - self.value.unwrap() + fn refresh(&mut self) -> T { + let value: T = self + .context + .borrow_mut() + .load(&self.pointer) + .map(|value| value.into()) + .unwrap_or(self.default_value.clone().into()); + self.value = Some(value.clone()); + value } fn set_no_commit(&mut self, value: T) -> T { @@ -72,9 +76,9 @@ where value } - fn commit<'a>(&mut self, context: &mut impl Context<'a>) { + fn commit(&mut self) { if let Some(value) = self.value { - context.store(self.pointer, value.into()); + self.context.borrow_mut().store(self.pointer, value.into()); } } } @@ -85,16 +89,27 @@ where StorageValue: Into, D: Into + Clone, { - pub const fn new_const(pointer: u16, default_value: D) -> Self { + pub const fn new_const( + context: Rc>, + pointer: u16, + default_value: D, + ) -> Self { Self { + context, pointer: crate::math::abi::encode_pointer_const(pointer), default_value, value: None, } } - pub fn new(pointer: u16, sub_pointer: &StorageKey, default_value: D) -> Self { + pub fn new( + context: Rc>, + pointer: u16, + sub_pointer: &StorageKey, + default_value: D, + ) -> Self { Self { + context, pointer: encode_pointer(pointer, sub_pointer), default_value, value: None, @@ -114,76 +129,80 @@ pub type StoredAddress = Stored; #[cfg(test)] mod tests { + use core::cell::RefCell; + + use alloc::rc::Rc; use alloc::vec::Vec; use ethnum::u256; use crate::storage::Map; + use crate::Context; use crate::TestContext; use super::StoredTrait; - fn context() -> TestContext { - TestContext::new( + fn context() -> Rc> { + Rc::new(RefCell::new(TestContext::new( crate::env::Network::Testnet, Map::new(), Vec::new(), Vec::new(), - ) + ))) } #[test] fn test_bool() { - let mut stored_bool = super::StoredBool::new_const(0, false); + let mut stored_bool = super::StoredBool::new_const(context(), 0, false); let mut context = context(); - stored_bool.set(&mut context, true); - assert_eq!(stored_bool.refresh(&mut context), true) + stored_bool.set(true); + assert_eq!(stored_bool.refresh(), true) } #[test] fn test_u8() { let mut context = context(); - let mut stored_u8 = super::StoredU8::new_const(0, 0); - stored_u8.set(&mut context, 1); - assert_eq!(stored_u8.refresh(&mut context), 1) + let mut stored_u8 = super::StoredU8::new_const(context, 0, 0); + stored_u8.set(1); + assert_eq!(stored_u8.refresh(), 1) } #[test] fn test_u16() { - let mut context = context(); - let mut stored_u16 = super::StoredU16::new_const(0, 0); - stored_u16.set(&mut context, 123); - assert_eq!(stored_u16.refresh(&mut context), 123) + let context = context(); + let mut stored_u16 = super::StoredU16::new_const(context, 0, 0); + stored_u16.set(123); + assert_eq!(stored_u16.refresh(), 123) } #[test] fn test_u32() { let mut context = context(); - let mut stored_u32 = super::StoredU32::new_const(0, 0); - stored_u32.set(&mut context, 123); - assert_eq!(stored_u32.refresh(&mut context), 123) + let mut stored_u32 = super::StoredU32::new_const(context, 0, 0); + stored_u32.set(123); + assert_eq!(stored_u32.refresh(), 123) } #[test] fn test_u64() { let mut context = context(); - let mut stored_u64 = super::StoredU64::new_const(0, 0); - stored_u64.set(&mut context, 123); - assert_eq!(stored_u64.refresh(&mut context), 123) + let mut stored_u64 = super::StoredU64::new_const(context, 0, 0); + stored_u64.set(123); + assert_eq!(stored_u64.refresh(), 123) } #[test] fn test_u128() { let mut context = context(); - let mut stored_u128 = super::StoredU128::new_const(0, 0); - stored_u128.set(&mut context, 123); - assert_eq!(stored_u128.refresh(&mut context), 123) + let mut stored_u128 = super::StoredU128::new_const(context, 0, 0); + stored_u128.set(123); + assert_eq!(stored_u128.refresh(), 123) } #[test] fn test_u256() { let mut context = context(); - let mut stored_u256 = super::StoredU256::new_const(0, u256::new(0)); - stored_u256.set(&mut context, u256::new(123)); - assert_eq!(stored_u256.refresh(&mut context), u256::new(123)) + let mut stored_u256 = super::StoredU256::new_const(context, 0, u256::new(0)); + stored_u256.set(u256::new(123)); + assert_eq!(stored_u256.refresh(), u256::new(123)) } } diff --git a/src/storage/stored_map.rs b/src/storage/stored_map.rs index ac40703..6094ef8 100644 --- a/src/storage/stored_map.rs +++ b/src/storage/stored_map.rs @@ -1,15 +1,18 @@ -use core::marker::PhantomData; +use core::{cell::RefCell, marker::PhantomData}; use ethnum::u256; use crate::{blockchain::AddressHash, math::abi::encode_pointer, Context}; use super::{StorageKey, StorageValue}; +use alloc::rc::Rc; pub struct StoredMap where K: Into, V: Into, { + context: Rc>, + default: V, pointer: u16, k: PhantomData, v: PhantomData, @@ -18,39 +21,39 @@ where impl StoredMap where K: Into + Copy, - V: Into + Clone, + V: Into + From + Clone, { - pub const fn new(pointer: u16) -> Self { + pub const fn new(context: Rc>, pointer: u16, default: V) -> Self { Self { + context, + default, pointer, k: PhantomData, v: PhantomData, } } - pub fn set<'a>(&self, context: &mut impl Context<'a>, key: &K, value: V) { + pub fn set(&self, key: &K, value: V) { let key: StorageKey = (*key).into(); let key_hash = encode_pointer(self.pointer, &key); let value = Into::::into(value); - context.store(key_hash, value); + self.context.borrow_mut().store(key_hash, value); } - pub fn get<'a>( - &self, - context: &mut impl Context<'a>, - key: &K, - default_value: V, - ) -> StorageValue { + pub fn get(&self, key: &K, default_value: V) -> V { let key: StorageKey = (*key).into(); let key_hash = encode_pointer(self.pointer, &key); - let value = context.load(&key_hash, default_value.into()); - value + self.context + .borrow_mut() + .load(&key_hash) + .map(|value| V::from(value)) + .unwrap_or_else(|| default_value) } - pub fn contains_key<'a>(&self, context: &mut impl Context<'a>, key: &K) -> bool { + pub fn contains_key(&self, key: &K) -> bool { let key: StorageKey = (*key).into(); let key_hash = encode_pointer(self.pointer, &key); - let has = context.exists(&key_hash); + let has = self.context.borrow_mut().exists(&key_hash); has } } diff --git a/src/storage/stored_string.rs b/src/storage/stored_string.rs index 5203bbf..4d5bdd1 100644 --- a/src/storage/stored_string.rs +++ b/src/storage/stored_string.rs @@ -1,37 +1,51 @@ -use alloc::string::String; +use core::cell::RefCell; use crate::{constant::STORE_VALUE_SIZE, storage::StorageValue, Context}; +use alloc::rc::Rc; +use alloc::string::String; use super::stored::StoredTrait; pub struct StoredString { + context: Rc>, pointer: u16, default_value: &'static str, value: Option, } impl StoredString { - pub const fn new_const(pointer: u16, default_value: &'static str) -> Self { + pub const fn new_const( + context: Rc>, + pointer: u16, + default_value: &'static str, + ) -> Self { Self { + context, pointer, default_value, value: None, } } - pub fn new(pointer: u16, default_value: &'static str) -> Self { + pub fn new( + context: Rc>, + pointer: u16, + default_value: &'static str, + ) -> Self { Self { + context, pointer, default_value, value: None, } } - fn save<'a>(&mut self, context: &mut impl Context<'a>, value: String) -> String { + fn save<'a>(&mut self, value: String) -> String { let bytes = value.as_bytes(); let mut remaining = bytes.len(); let mut offset = [0u8; crate::constant::STORE_VALUE_SIZE]; assert!(remaining < 2048); + let mut context = self.context.borrow_mut(); let mut data = [0u8; crate::constant::STORE_VALUE_SIZE]; let mut length = remaining.min(STORE_VALUE_SIZE - 4); @@ -61,12 +75,13 @@ impl StoredString { value } - fn load<'a>(&mut self, context: &mut impl Context<'a>) -> String { + fn load<'a>(&mut self) -> String { let mut offset = [0u8; crate::constant::STORE_VALUE_SIZE]; - let header = context.load( - &crate::math::abi::encode_pointer(self.pointer, &offset), - StorageValue::ZERO, - ); + let mut context = self.context.borrow_mut(); + + let header = context + .load(&crate::math::abi::encode_pointer(self.pointer, &offset)) + .unwrap_or(StorageValue::ZERO); let bytes = header.bytes(); let len = u32::from_le_bytes(bytes[0..4].try_into().unwrap()) as usize; let mut length = len.min(crate::constant::STORE_VALUE_SIZE); @@ -79,7 +94,7 @@ impl StoredString { while remaining > 0 { offset[crate::constant::STORE_KEY_SIZE - 1] += 1; let key = crate::math::abi::encode_pointer(self.pointer, &offset); - let tmp = context.load(&key, StorageValue::ZERO); + let tmp = context.load(&key).unwrap_or(StorageValue::ZERO); let bytes = tmp.bytes(); length = remaining.min(crate::constant::STORE_VALUE_SIZE); for &byte in bytes.iter().take(length) { @@ -98,15 +113,15 @@ impl StoredString { } impl StoredTrait for StoredString { - fn set<'a>(&mut self, context: &mut impl Context<'a>, value: String) -> String { - self.save(context, value) + fn set(&mut self, value: String) -> String { + self.save(value) } - fn value<'a>(&mut self, context: &mut impl Context<'a>) -> String { + fn value(&mut self) -> String { if let Some(value) = &self.value { value.clone() } else { - self.load(context) + self.load() } } @@ -115,13 +130,13 @@ impl StoredTrait for StoredString { value } - fn commit<'a>(&mut self, context: &mut impl Context<'a>) { + fn commit(&mut self) { if let Some(value) = &self.value { - self.save(context, value.clone()); + self.save(value.clone()); } } - fn refresh<'a>(&mut self, context: &mut impl Context<'a>) -> String { - self.load(context) + fn refresh(&mut self) -> String { + self.load() } } diff --git a/src/tests/mod.rs b/src/tests/mod.rs index 876636a..0f497fb 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -49,7 +49,7 @@ pub fn random_environment() -> Environment { } pub fn execute( - contract: &mut impl crate::ContractTrait, + contract: &mut dyn crate::ContractTrait, selector: crate::types::Selector, ) -> Cursor { let mut buffer = crate::WaBuffer::new(32, 1).unwrap(); @@ -59,7 +59,7 @@ pub fn execute( } pub fn execute_address( - contract: &mut impl crate::ContractTrait, + contract: &mut dyn crate::ContractTrait, selector: crate::types::Selector, address: &AddressHash, ) -> Cursor { @@ -71,7 +71,7 @@ pub fn execute_address( } pub fn execute_address_amount( - contract: &mut impl crate::ContractTrait, + contract: &mut dyn crate::ContractTrait, selector: crate::types::Selector, address: &AddressHash, amount: u256, From cde283e483ae66163c9d152fcf12771d78ca6e95 Mon Sep 17 00:00:00 2001 From: Miksa Date: Mon, 24 Feb 2025 13:48:07 +0100 Subject: [PATCH 17/23] All test are passing --- example/src/contract.rs | 64 +++++++++++++++++++++++++++-------------- example/src/lib.rs | 5 +++- src/contract/mod.rs | 4 +-- src/env/global.rs | 6 ++-- src/env/test.rs | 24 ++++++++++++++-- 5 files changed, 73 insertions(+), 30 deletions(-) diff --git a/example/src/contract.rs b/example/src/contract.rs index 80c0ef9..af874a1 100644 --- a/example/src/contract.rs +++ b/example/src/contract.rs @@ -1,5 +1,5 @@ +use alloc::rc::Rc; use core::cell::RefCell; - use rust_runtime::{ blockchain::AddressHash, contract::op_20::Pointer, @@ -12,7 +12,7 @@ use rust_runtime::{ StorageValue, }, types::{CallData, Selector}, - Context, ContractTrait, EnvMethods, OP20Trait, + Context, ContractTrait, OP20Trait, }; const SELECTOR_AIRDROP: Selector = encode_selector_const("airdrop"); @@ -28,32 +28,40 @@ pub struct Contract<'a> { context: Rc>, } impl<'a> Contract<'a> { - pub const fn new(context: Rc>) -> Self { + pub fn new(context: Rc>) -> Self { Self { environment: None, params: rust_runtime::contract::op_20::OP20Params { max_supply: StoredU256::new_const( - context, + context.clone(), Pointer::MaxSupply.u16(), u256::new(100000000000000000000000000), ), - decimals: StoredU8::new_const(context, Pointer::Decimals.u16(), 18), + decimals: StoredU8::new_const(context.clone(), Pointer::Decimals.u16(), 18), name: "MyToken", symbol: "TOKEN", }, - balance_of_map: StoredMap::new(context, Pointer::BalanceOfMap.u16()), + balance_of_map: StoredMap::new( + context.clone(), + Pointer::BalanceOfMap.u16(), + u256::ZERO, + ), allowance_map: MultiAddressMemoryMap::new( - context, + context.clone(), Pointer::AllowanceMap.u16(), StorageValue::ZERO, ), - total_supply: StoredU256::new_const(context, Pointer::TotalSupply.u16(), u256::ZERO), + total_supply: StoredU256::new_const( + context.clone(), + Pointer::TotalSupply.u16(), + u256::ZERO, + ), context, } } } -impl Contract { +impl<'a> Contract<'a> { fn execute( &mut self, selector: Selector, @@ -135,7 +143,7 @@ impl Contract { } } -impl rust_runtime::contract::op_20::OP20Trait for Contract { +impl<'a> rust_runtime::contract::op_20::OP20Trait<'a> for Contract<'a> { fn params(&mut self) -> &mut rust_runtime::OP20Params { &mut self.params } @@ -153,17 +161,17 @@ impl rust_runtime::contract::op_20::OP20Trait for Contract { } } -impl rust_runtime::contract::ContractTrait for Contract { - fn set_environment(&mut self, environment: &'static rust_runtime::blockchain::Environment) { +impl<'a> rust_runtime::contract::ContractTrait<'a> for Contract<'a> { + fn set_environment(&mut self, environment: &'a rust_runtime::blockchain::Environment) { self.environment = Some(environment); } - fn environment(&self) -> &'static rust_runtime::blockchain::Environment { + fn environment(&self) -> &'a rust_runtime::blockchain::Environment { self.environment.unwrap() } - fn context(&self) -> alloc::rc::Rc> { - self.context + fn context(&self) -> Rc> { + self.context.clone() } fn execute( @@ -181,26 +189,38 @@ impl rust_runtime::contract::ContractTrait for Contract { // To run the tests, run `cargo test -p example` in the root of the workspace #[cfg(test)] mod tests { + use core::{cell::RefCell, task::Context}; + use crate::contract::SELECTOR_MINT; + use alloc::{rc::Rc, vec::Vec}; use rust_runtime::{ contract::op_20::{SELECTOR_BALANCE_OF, SELECTOR_NAME, SELECTOR_TOTAL_SUPPLY}, ethnum::u256, - pointer_storage, + storage::map::Map, tests::{execute, execute_address, execute_address_amount, random_environment}, }; + fn context() -> Rc> { + Rc::new(RefCell::new(rust_runtime::env::TestContext::new( + rust_runtime::Network::Mainnet, + Map::new(), + Vec::new(), + Vec::new(), + ))) + } + #[test] fn test_contract_name() { - let local_methods = rust_runtime::env::LocalMethods::new(); - let mut contract = super::Contract::new(&local_methods); + let context = context(); + let mut contract = super::Contract::new(context); let mut cursor = execute(&mut contract, SELECTOR_NAME); assert_eq!(contract.params.name, cursor.read_string_with_len().unwrap()); } #[test] fn test_contract_mint() { - let local_methods = rust_runtime::env::LocalMethods::new(); - let mut contract = super::Contract::new(&local_methods); + let context = context(); + let mut contract = super::Contract::new(context); let address = rust_runtime::tests::random_address(); contract.environment = rust_runtime::blockchain::Environment { @@ -229,8 +249,8 @@ mod tests { #[test] fn test_contract_total_supply() { - let local_methods = rust_runtime::env::LocalMethods::new(); - let mut contract = super::Contract::new(&local_methods); + let context = context(); + let mut contract = super::Contract::new(context); let address = rust_runtime::tests::random_address(); diff --git a/example/src/lib.rs b/example/src/lib.rs index a8953bd..701e3d3 100644 --- a/example/src/lib.rs +++ b/example/src/lib.rs @@ -5,8 +5,11 @@ extern crate alloc; use rust_runtime::prelude::{ContractTrait, WaBuffer, WaPtr}; pub mod contract; +/* #[allow(dead_code, static_mut_refs)] -static mut CONTRACT: contract::Contract = contract::Contract::new(rust_runtime::GLOBAL_METHODS); +#[cfg(target_arch = "wasm32")] +static mut CONTRACT: contract::Contract = contract::Contract::new(rust_runtime::env::); + */ #[cfg(target_arch = "wasm32")] use lol_alloc::LeakingPageAllocator; diff --git a/src/contract/mod.rs b/src/contract/mod.rs index 43d220a..ca85f52 100644 --- a/src/contract/mod.rs +++ b/src/contract/mod.rs @@ -12,9 +12,9 @@ use crate::{ pub mod op_20; pub trait ContractTrait<'a> { - fn set_environment(&mut self, environment: &'static crate::blockchain::Environment); + fn set_environment(&mut self, environment: &'a crate::blockchain::Environment); - fn environment(&self) -> &'static crate::blockchain::Environment; + fn environment(&self) -> &'a crate::blockchain::Environment; fn context(&self) -> Rc>; diff --git a/src/env/global.rs b/src/env/global.rs index c366157..a12f89d 100644 --- a/src/env/global.rs +++ b/src/env/global.rs @@ -41,19 +41,19 @@ extern "C" { } #[cfg(target_arch = "wasm32")] -pub struct GlobalMethods { +pub struct GlobalContext { store: Map, } #[cfg(target_arch = "wasm32")] -impl GlobalMethods { +impl GlobalContext { pub const fn new() { Self { store: Map::new() } } } #[cfg(target_arch = "wasm32")] -impl super::EnvMethods for GlobalMethods { +impl super::Context for GlobalContext { fn log(&self, text: &str) { unsafe { if let Ok(string) = WaBuffer::from_str(text) { diff --git a/src/env/test.rs b/src/env/test.rs index 88da496..f19a7a0 100644 --- a/src/env/test.rs +++ b/src/env/test.rs @@ -99,10 +99,30 @@ impl super::Context for TestContext { } } - fn store(&self, pointer: crate::storage::StorageKey, value: crate::storage::StorageValue) {} + fn store(&self, pointer: crate::storage::StorageKey, value: crate::storage::StorageValue) { + if if let Some(old) = self.cache_store.borrow().get(&pointer) { + value.ne(old) + } else { + true + } { + self.cache_store + .borrow_mut() + .insert(pointer.clone(), value.clone()); + self.global_store.borrow_mut().insert(pointer, value); + } + } fn exists(&self, pointer: &StorageKey) -> bool { - false + if self.cache_store.borrow().contains_key(pointer) { + true + } else { + if let Some(value) = self.global_store.borrow().get(pointer) { + self.cache_store.borrow_mut().insert(*pointer, *value); + true + } else { + false + } + } } fn next_pointer_greater_than( From e3322d9bdd408bb261cc9037770786c825987eb0 Mon Sep 17 00:00:00 2001 From: Miksa Date: Mon, 24 Feb 2025 15:53:33 +0100 Subject: [PATCH 18/23] Working build --- Cargo.lock | 1 + example/Cargo.toml | 1 + example/src/lib.rs | 27 +++++++---- src/contract/mod.rs | 4 +- src/contract/op_20.rs | 18 ++++--- src/cursor/reader.rs | 2 +- src/env/global.rs | 96 ++++++++++++++++++++++++++++++++----- src/env/mod.rs | 45 ++++++++--------- src/env/test.rs | 86 +++++++++++---------------------- src/error.rs | 2 +- src/storage/array_merger.rs | 2 +- src/storage/mod.rs | 2 - src/storage/stored.rs | 8 ++-- src/tests/mod.rs | 24 +++++++++- 14 files changed, 197 insertions(+), 121 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f297326..91aa6a0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -62,6 +62,7 @@ dependencies = [ "lol_alloc", "rust_runtime", "sha2-const", + "spin", ] [[package]] diff --git a/example/Cargo.toml b/example/Cargo.toml index b3b1ed0..819612b 100644 --- a/example/Cargo.toml +++ b/example/Cargo.toml @@ -17,5 +17,6 @@ strip = true lol_alloc = { workspace = true } rust_runtime = { workspace = true } sha2-const = {workspace = true } +spin = { version = "0.9.8", features=["mutex", "lazy"]} [features] diff --git a/example/src/lib.rs b/example/src/lib.rs index 701e3d3..f51c893 100644 --- a/example/src/lib.rs +++ b/example/src/lib.rs @@ -1,15 +1,19 @@ #![no_std] extern crate alloc; +use alloc::rc::Rc; +use core::cell::RefCell; + #[allow(unused_imports)] use rust_runtime::prelude::{ContractTrait, WaBuffer, WaPtr}; pub mod contract; -/* -#[allow(dead_code, static_mut_refs)] #[cfg(target_arch = "wasm32")] -static mut CONTRACT: contract::Contract = contract::Contract::new(rust_runtime::env::); - */ +static mut CONTRACT: spin::Lazy> = spin::Lazy::new(|| { + RefCell::new(contract::Contract::new(Rc::new(RefCell::new( + rust_runtime::env::global::GlobalContext::new(), + )))) +}); #[cfg(target_arch = "wasm32")] use lol_alloc::LeakingPageAllocator; @@ -22,10 +26,15 @@ static ALLOCATOR: LeakingPageAllocator = LeakingPageAllocator; #[allow(static_mut_refs)] #[export_name = "execute"] pub unsafe fn execute(ptr: WaPtr) -> WaPtr { - match CONTRACT.execute(WaBuffer::from_raw(ptr).cursor()) { + use spin::lazy::Lazy; + + match CONTRACT + .borrow_mut() + .execute(WaBuffer::from_raw(ptr).cursor()) + { Ok(buffer) => buffer.ptr(), Err(err) => { - rust_runtime::log(err.as_str()); + CONTRACT.borrow_mut().log(err.as_str()); panic!("Error occured") } } @@ -35,7 +44,9 @@ pub unsafe fn execute(ptr: WaPtr) -> WaPtr { #[export_name = "onDeploy"] #[allow(static_mut_refs)] pub unsafe fn on_deploy(ptr: WaPtr) { - CONTRACT.on_deploy(WaBuffer::from_raw(ptr).cursor()); + CONTRACT + .borrow_mut() + .on_deploy(WaBuffer::from_raw(ptr).cursor()); } #[cfg(target_arch = "wasm32")] @@ -44,5 +55,5 @@ pub unsafe fn on_deploy(ptr: WaPtr) { pub unsafe fn set_environment(ptr: WaPtr) { let buffer = WaBuffer::from_raw(ptr); let environment: &mut rust_runtime::blockchain::Environment = buffer.into_type(); - CONTRACT.set_environment(environment); + CONTRACT.borrow_mut().set_environment(environment); } diff --git a/src/contract/mod.rs b/src/contract/mod.rs index ca85f52..5c51770 100644 --- a/src/contract/mod.rs +++ b/src/contract/mod.rs @@ -80,8 +80,8 @@ pub trait ContractTrait<'a> { fn sha256_double(&self, data: &[u8]) -> &'static [u8] { self.context().borrow().sha256_double(data) } - fn rimemd160(&self, data: &[u8]) -> &'static [u8] { - self.context().borrow().rimemd160(data) + fn ripemd160(&self, data: &[u8]) -> &'static [u8] { + self.context().borrow().ripemd160(data) } fn inputs(&self) -> Vec { diff --git a/src/contract/op_20.rs b/src/contract/op_20.rs index ff31620..466539d 100644 --- a/src/contract/op_20.rs +++ b/src/contract/op_20.rs @@ -74,14 +74,14 @@ pub trait OP20Trait<'a>: super::ContractTrait<'a> { let name = self.name(); let mut buffer = WaBuffer::new(name.len() + 2, 1)?; let mut cursor = buffer.cursor(); - cursor.write_string_with_len(&name)?; + cursor.write_string_with_len(name)?; Ok(buffer) } SELECTOR_SYMBOL => { let symbol = self.symbol(); let mut buffer = WaBuffer::new(symbol.len() + 2, 1)?; let mut cursor = buffer.cursor(); - cursor.write_string_with_len(&symbol)?; + cursor.write_string_with_len(symbol)?; Ok(buffer) } SELECTOR_TOTAL_SUPPLY => { @@ -187,7 +187,7 @@ pub trait OP20Trait<'a>: super::ContractTrait<'a> { } fn balance_of_base(&mut self, address: &AddressHash) -> u256 { - self.balance_of_map().get(address, u256::ZERO).into() + self.balance_of_map().get(address, u256::ZERO) } fn balance_of( @@ -402,7 +402,8 @@ pub trait OP20Trait<'a>: super::ContractTrait<'a> { fn create_burn_event(&mut self, value: u256) -> Result<(), crate::error::Error> { let burn_event = crate::event::Event::burn(value)?; - Ok(self.context().borrow_mut().emit(&burn_event)) + self.context().borrow_mut().emit(&burn_event); + Ok(()) } fn create_approve_event( @@ -412,7 +413,8 @@ pub trait OP20Trait<'a>: super::ContractTrait<'a> { value: u256, ) -> Result<(), crate::error::Error> { let approve_event = crate::event::Event::approve(deployer, spender, value)?; - Ok(self.context().borrow_mut().emit(&approve_event)) + self.context().borrow_mut().emit(&approve_event); + Ok(()) } fn create_mint_event( @@ -421,7 +423,8 @@ pub trait OP20Trait<'a>: super::ContractTrait<'a> { amount: u256, ) -> Result<(), crate::error::Error> { let mint_event = crate::event::Event::mint(deployer, amount)?; - Ok(self.context().borrow_mut().emit(&mint_event)) + self.context().borrow_mut().emit(&mint_event); + Ok(()) } fn create_transfer_event( @@ -431,6 +434,7 @@ pub trait OP20Trait<'a>: super::ContractTrait<'a> { amount: u256, ) -> Result<(), crate::error::Error> { let transfer_event = crate::event::Event::transfer(from, to, amount)?; - Ok(self.context().borrow_mut().emit(&transfer_event)) + self.context().borrow_mut().emit(&transfer_event); + Ok(()) } } diff --git a/src/cursor/reader.rs b/src/cursor/reader.rs index 23f4e6d..ee1fc9e 100644 --- a/src/cursor/reader.rs +++ b/src/cursor/reader.rs @@ -137,7 +137,7 @@ impl super::Cursor { self.reader += len as usize; unsafe { Ok(str::from_raw_parts( - self.inner.as_ptr().add(pos as usize), + self.inner.as_ptr().add(pos), len as usize, )) } diff --git a/src/env/global.rs b/src/env/global.rs index a12f89d..e7fd215 100644 --- a/src/env/global.rs +++ b/src/env/global.rs @@ -1,8 +1,11 @@ -#[cfg(target_arch = "wasm32")] use crate::mem::WaPtr; -use crate::storage::map::Map; +use crate::{ + storage::{key::StorageKey, map::Map, value::StorageValue}, + WaBuffer, +}; +use core::str::FromStr; -#[cfg(target_arch = "wasm32")] +//#[cfg(target_arch = "wasm32")] #[link(wasm_import_module = "env")] extern "C" { #[allow(dead_code)] @@ -40,19 +43,19 @@ extern "C" { pub fn outputs() -> WaPtr; } -#[cfg(target_arch = "wasm32")] +//#[cfg(target_arch = "wasm32")] pub struct GlobalContext { store: Map, } -#[cfg(target_arch = "wasm32")] +//#[cfg(target_arch = "wasm32")] impl GlobalContext { - pub const fn new() { + pub const fn new() -> Self { Self { store: Map::new() } } } -#[cfg(target_arch = "wasm32")] +//#[cfg(target_arch = "wasm32")] impl super::Context for GlobalContext { fn log(&self, text: &str) { unsafe { @@ -62,10 +65,79 @@ impl super::Context for GlobalContext { } } - fn emit(buffer: crate::WaBuffer) { - unsafe { emit(buffer.ptr()) } + fn emit(&mut self, event: &dyn crate::event::EventTrait) { + unsafe { + emit(event.buffer().ptr()); + } + } + + fn call(&self, buffer: WaBuffer) -> WaBuffer { + unsafe { WaBuffer::from_raw(call(buffer.ptr())) } + } + + fn encode_address(&self, address: &str) -> &'static [u8] { + b"abcd" + } + + fn deploy(&self, buffer: WaBuffer) -> WaBuffer { + unsafe { WaBuffer::from_raw(deploy(buffer.ptr())) } + } + + fn deploy_from_address(&self, buffer: WaBuffer) -> WaBuffer { + unsafe { WaBuffer::from_raw(deployFromAddress(buffer.ptr())) } + } + + fn validate_bitcoin_address(&self, address: &str) -> bool { + false + } + + fn verify_schnorr_signature(&self, data: &[u8]) -> bool { + false + } + + fn load(&mut self, pointer: &StorageKey) -> Option { + unsafe { + let mut buffer = WaBuffer::from_raw(load(WaBuffer::from_bytes(pointer).unwrap().ptr())); + let value: StorageValue = buffer.cursor().read_u256_be().unwrap().into(); + if value.eq(&StorageValue::ZERO) { + None + } else { + self.store.insert(*pointer, value.clone()); + Some(value) + } + } } -} -#[cfg(target_arch = "wasm32")] -pub static GLOBAL_METHODS: GlobalMethods = GlobalMethods::new(); + fn exists(&mut self, pointer: &StorageKey) -> bool { + if self.store.contains_key(pointer) { + true + } else { + self.load(pointer).is_some() + } + } + + fn store(&mut self, pointer: StorageKey, value: StorageValue) { + unsafe { + if if let Some(old) = self.store.get(&pointer) { + value.ne(old) + } else { + false + } { + self.store.insert(pointer, value); + store(WaBuffer::from_bytes(value.bytes()).unwrap().ptr()); + } + } + } + + fn next_pointer_greater_than(&self, pointer: StorageKey) -> StorageKey { + [0; 32] + } + + fn inputs(&self) -> alloc::vec::Vec { + alloc::vec::Vec::new() + } + + fn outputs(&self) -> alloc::vec::Vec { + alloc::vec::Vec::new() + } +} diff --git a/src/env/mod.rs b/src/env/mod.rs index d1b6fc6..3b79a69 100644 --- a/src/env/mod.rs +++ b/src/env/mod.rs @@ -1,26 +1,21 @@ use crate::{ - event, mem::WaBuffer, storage::{StorageKey, StorageValue}, }; use alloc::vec::Vec; #[allow(unused_imports)] use core::str::FromStr; -mod global; +pub mod global; + +#[cfg(not(target_arch = "wasm32"))] mod test; -pub use test::{Network, TestContext}; -#[cfg(target_arch = "wasm32")] -pub use global::GLOBAL_METHODS; +#[cfg(not(target_arch = "wasm32"))] +pub use test::{Network, TestContext}; #[cfg(target_arch = "wasm32")] pub fn sha256(bytes: &[u8]) -> &'static [u8] { - unsafe { - WaBuffer::from_raw(super::global::sha256( - WaBuffer::from_bytes(bytes).unwrap().ptr(), - )) - .data() - } + unsafe { WaBuffer::from_raw(global::sha256(WaBuffer::from_bytes(bytes).unwrap().ptr())).data() } } #[cfg(not(target_arch = "wasm32"))] @@ -30,9 +25,9 @@ pub fn sha256(bytes: &[u8]) -> &'static [u8] { } #[cfg(target_arch = "wasm32")] -pub fn rimemd160(bytes: &[u8]) -> &'static [u8] { +pub fn ripemd160(bytes: &[u8]) -> &'static [u8] { unsafe { - WaBuffer::from_raw(super::global::rimemd160( + WaBuffer::from_raw(global::ripemd160( WaBuffer::from_bytes(bytes).unwrap().ptr(), )) .data() @@ -40,8 +35,8 @@ pub fn rimemd160(bytes: &[u8]) -> &'static [u8] { } #[cfg(not(target_arch = "wasm32"))] -pub fn rimemd160(data: &[u8]) -> &'static [u8] { - use ripemd::{Digest, Ripemd160}; +pub fn ripemd160(data: &[u8]) -> &'static [u8] { + use ripemd::Digest; let mut hasher = ripemd::Ripemd160::new(); hasher.update(data); @@ -66,7 +61,7 @@ impl WrappedMut { pub fn as_mut(&self) -> &mut T { unsafe { if let Some(val) = ((&self.inner) as *const T as *mut T).as_mut() { - return val; + val } else { panic!("Unexpected null"); } @@ -76,15 +71,15 @@ impl WrappedMut { pub trait Context { fn log(&self, text: &str); - fn emit(&self, event: &dyn crate::event::EventTrait); + fn emit(&mut self, event: &dyn crate::event::EventTrait); fn call(&self, buffer: WaBuffer) -> WaBuffer; fn deploy(&self, buffer: WaBuffer) -> WaBuffer; fn deploy_from_address(&self, buffer: WaBuffer) -> WaBuffer; - fn load(&self, pointer: &StorageKey) -> Option; - fn store(&self, pointer: StorageKey, value: StorageValue); - fn exists(&self, pointer: &StorageKey) -> bool; + fn load(&mut self, pointer: &StorageKey) -> Option; + fn store(&mut self, pointer: StorageKey, value: StorageValue); + fn exists(&mut self, pointer: &StorageKey) -> bool; fn next_pointer_greater_than(&self, pointer: StorageKey) -> StorageKey; fn encode_address(&self, address: &str) -> &'static [u8]; @@ -93,9 +88,11 @@ pub trait Context { fn sha256(&self, data: &[u8]) -> &'static [u8] { sha256(data) } - fn sha256_double(&self, data: &[u8]) -> &'static [u8]; - fn rimemd160(&self, data: &[u8]) -> &'static [u8] { - rimemd160(data) + fn sha256_double(&self, data: &[u8]) -> &'static [u8] { + self.sha256(self.sha256(data)) + } + fn ripemd160(&self, data: &[u8]) -> &'static [u8] { + ripemd160(data) } fn inputs(&self) -> Vec; @@ -119,7 +116,7 @@ mod tests { fn test_ripemd160() { let text = "Hello world"; assert_eq!( - crate::utils::to_hex(super::rimemd160(text.as_bytes())), + crate::utils::to_hex(super::ripemd160(text.as_bytes())), alloc::string::String::from("0xdbea7bd24eef40a2e79387542e36dd408b77b21a") ); } diff --git a/src/env/test.rs b/src/env/test.rs index f19a7a0..f8a146c 100644 --- a/src/env/test.rs +++ b/src/env/test.rs @@ -1,9 +1,7 @@ use alloc::vec::Vec; use core::cell::RefCell; -use libc_print::libc_println; use crate::{ - env::WrappedMut, storage::map::Map, storage::{StorageKey, StorageValue}, WaBuffer, @@ -17,9 +15,9 @@ pub enum Network { pub struct TestContext { pub network: Network, - pub events: RefCell>, - pub global_store: RefCell>, - pub cache_store: RefCell>, + pub events: alloc::vec::Vec, + pub global_store: Map, + pub cache_store: Map, pub inputs: alloc::vec::Vec, pub outputs: alloc::vec::Vec, } @@ -33,9 +31,9 @@ impl TestContext { ) -> Self { Self { network, - events: RefCell::new(alloc::vec::Vec::new()), - global_store: RefCell::new(global_store), - cache_store: RefCell::new(Map::new()), + events: alloc::vec::Vec::new(), + global_store: global_store, + cache_store: Map::new(), inputs, outputs, } @@ -43,16 +41,12 @@ impl TestContext { } impl super::Context for TestContext { - fn emit(&self, event: &dyn crate::event::EventTrait) { + fn emit(&mut self, event: &dyn crate::event::EventTrait) { let event = crate::event::Event::new(event.buffer()); - unsafe { - self.events.borrow_mut().push(event); - } + self.events.push(event); } - fn log(&self, text: &str) { - libc_println!("{}", text); - } + fn log(&self, text: &str) {} fn call(&self, buffer: crate::WaBuffer) -> WaBuffer { buffer @@ -78,50 +72,40 @@ impl super::Context for TestContext { true } - fn load(&self, pointer: &crate::storage::StorageKey) -> Option { - if let Some(value) = if let Some(value) = self.cache_store.borrow().get(&pointer) { + fn load( + &mut self, + pointer: &crate::storage::StorageKey, + ) -> Option { + if let Some(value) = self.cache_store.get(pointer) { + Some(*value) + } else if let Some(value) = self.global_store.get(pointer) { + self.cache_store.insert(*pointer, *value); Some(*value) - } else { - if let Some(value) = self.global_store.borrow().get(&pointer) { - self.cache_store.borrow_mut().insert(*pointer, *value); - Some(*value) - } else { - None - } - } { - if StorageValue::ZERO.eq(&value) { - None - } else { - Some(value) - } } else { None } + .filter(|&value| !StorageValue::ZERO.eq(&value)) } - fn store(&self, pointer: crate::storage::StorageKey, value: crate::storage::StorageValue) { - if if let Some(old) = self.cache_store.borrow().get(&pointer) { + fn store(&mut self, pointer: crate::storage::StorageKey, value: crate::storage::StorageValue) { + if if let Some(old) = self.cache_store.get(&pointer) { value.ne(old) } else { true } { - self.cache_store - .borrow_mut() - .insert(pointer.clone(), value.clone()); - self.global_store.borrow_mut().insert(pointer, value); + self.cache_store.insert(pointer, value); + self.global_store.insert(pointer, value); } } - fn exists(&self, pointer: &StorageKey) -> bool { - if self.cache_store.borrow().contains_key(pointer) { + fn exists(&mut self, pointer: &StorageKey) -> bool { + if self.cache_store.contains_key(pointer) { + true + } else if let Some(value) = self.global_store.get(pointer) { + self.cache_store.insert(*pointer, *value); true } else { - if let Some(value) = self.global_store.borrow().get(pointer) { - self.cache_store.borrow_mut().insert(*pointer, *value); - true - } else { - false - } + false } } @@ -129,19 +113,7 @@ impl super::Context for TestContext { &self, pointer: crate::storage::StorageKey, ) -> crate::storage::StorageKey { - [0; 32].into() - } - - fn sha256(&self, data: &[u8]) -> &'static [u8] { - b"ab" - } - - fn sha256_double(&self, data: &[u8]) -> &'static [u8] { - b"ab2" - } - - fn rimemd160(&self, data: &[u8]) -> &'static [u8] { - b"ab3" + [0; 32] } fn inputs(&self) -> Vec { diff --git a/src/error.rs b/src/error.rs index afa130c..bf32443 100644 --- a/src/error.rs +++ b/src/error.rs @@ -46,6 +46,6 @@ impl Error { impl Debug for Error { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.debug_struct(&self.as_str()).finish() + f.debug_struct(self.as_str()).finish() } } diff --git a/src/storage/array_merger.rs b/src/storage/array_merger.rs index a9c3d8f..ee385a4 100644 --- a/src/storage/array_merger.rs +++ b/src/storage/array_merger.rs @@ -34,7 +34,7 @@ impl ArrayMerger { self.context .borrow_mut() .load(&pointer) - .unwrap_or(self.default_value.clone()) + .unwrap_or(self.default_value) } pub fn set<'a>(&mut self, key: &[u8], value: StorageValue) { diff --git a/src/storage/mod.rs b/src/storage/mod.rs index e605104..0363b56 100644 --- a/src/storage/mod.rs +++ b/src/storage/mod.rs @@ -1,5 +1,3 @@ -use crate::storage::map::Map; -use spin::{Lazy, Mutex}; pub mod array_merger; pub mod key; diff --git a/src/storage/stored.rs b/src/storage/stored.rs index 32347b6..c399fba 100644 --- a/src/storage/stored.rs +++ b/src/storage/stored.rs @@ -1,6 +1,6 @@ use ethnum::u256; -use super::{Map, StorageKey, StorageValue}; +use super::{StorageKey, StorageValue}; use crate::{blockchain::AddressHash, math::abi::encode_pointer, Context}; use alloc::rc::Rc; use core::{cell::RefCell, convert::Into}; @@ -45,7 +45,7 @@ where .map(|value| value.into()) .unwrap_or(self.default_value.clone().into()); - self.value = Some(value.clone()); + self.value = Some(value); value } } @@ -67,7 +67,7 @@ where .load(&self.pointer) .map(|value| value.into()) .unwrap_or(self.default_value.clone().into()); - self.value = Some(value.clone()); + self.value = Some(value); value } @@ -135,7 +135,7 @@ mod tests { use alloc::vec::Vec; use ethnum::u256; - use crate::storage::Map; + use crate::storage::map::Map; use crate::Context; use crate::TestContext; diff --git a/src/tests/mod.rs b/src/tests/mod.rs index 0f497fb..62a7ae1 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -12,11 +12,31 @@ pub fn random_bytes() -> [u8; 32] { result } +#[cfg(target_arch = "wasm32")] +pub fn random_bytes() -> [u8; 32] { + static mut value: u8 = 9; + let mut result = [0u8; 32]; + result.iter_mut().for_each(|b| unsafe { + value += 13; + *b = value; + }); + result +} + #[cfg(not(target_arch = "wasm32"))] pub fn random_u64() -> u64 { rand::random() } +#[cfg(target_arch = "wasm32")] +pub fn random_u64() -> u64 { + unsafe { + static mut value: u64 = 9; + value += 19; + value + } +} + pub fn random_address() -> AddressHash { AddressHash { bytes: random_bytes(), @@ -66,7 +86,7 @@ pub fn execute_address( let mut buffer = crate::WaBuffer::new(64, 1).unwrap(); let mut cursor = buffer.cursor(); cursor.write_u32_le(&selector).unwrap(); - cursor.write_address(&address).unwrap(); + cursor.write_address(address).unwrap(); contract.execute(cursor).unwrap().cursor() } @@ -79,7 +99,7 @@ pub fn execute_address_amount( let mut buffer = crate::WaBuffer::new(96, 1).unwrap(); let mut cursor = buffer.cursor(); cursor.write_u32_le(&selector).unwrap(); - cursor.write_address(&address).unwrap(); + cursor.write_address(address).unwrap(); cursor.write_u256_be(&amount).unwrap(); contract.execute(cursor).unwrap().cursor() } From 972f33d0409bf2889f92e35c74a4e8e8bcae453e Mon Sep 17 00:00:00 2001 From: Miksa Date: Mon, 24 Feb 2025 16:13:40 +0100 Subject: [PATCH 19/23] Cleaned code --- example/src/contract.rs | 2 +- example/src/lib.rs | 3 +++ rust.wasm | Bin 19101 -> 37688 bytes src/contract/mod.rs | 2 +- src/contract/op_20.rs | 17 +++++++---------- src/env/global.rs | 9 +++++---- src/env/test.rs | 12 ++++++------ src/storage/stored.rs | 19 ++++++------------- src/storage/stored_map.rs | 6 +++--- 9 files changed, 32 insertions(+), 38 deletions(-) diff --git a/example/src/contract.rs b/example/src/contract.rs index af874a1..77ca163 100644 --- a/example/src/contract.rs +++ b/example/src/contract.rs @@ -189,7 +189,7 @@ impl<'a> rust_runtime::contract::ContractTrait<'a> for Contract<'a> { // To run the tests, run `cargo test -p example` in the root of the workspace #[cfg(test)] mod tests { - use core::{cell::RefCell, task::Context}; + use core::cell::RefCell; use crate::contract::SELECTOR_MINT; use alloc::{rc::Rc, vec::Vec}; diff --git a/example/src/lib.rs b/example/src/lib.rs index f51c893..896e83b 100644 --- a/example/src/lib.rs +++ b/example/src/lib.rs @@ -1,7 +1,10 @@ #![no_std] extern crate alloc; +#[allow(unused_imports)] use alloc::rc::Rc; + +#[allow(unused_imports)] use core::cell::RefCell; #[allow(unused_imports)] diff --git a/rust.wasm b/rust.wasm index d7f81190c75301030d71de5c440341fda27e58be..e20e0c37a188a6b0bb9df54cfb2e6544abcd67f5 100644 GIT binary patch literal 37688 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 literal 19101 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 diff --git a/src/contract/mod.rs b/src/contract/mod.rs index 5c51770..624f66f 100644 --- a/src/contract/mod.rs +++ b/src/contract/mod.rs @@ -16,7 +16,7 @@ pub trait ContractTrait<'a> { fn environment(&self) -> &'a crate::blockchain::Environment; - fn context(&self) -> Rc>; + fn context(&self) -> Rc>; fn is_self(&self, address: &AddressHash) -> bool { address.eq(&self.environment().address) diff --git a/src/contract/op_20.rs b/src/contract/op_20.rs index 466539d..9ef96ba 100644 --- a/src/contract/op_20.rs +++ b/src/contract/op_20.rs @@ -3,7 +3,6 @@ use ethnum::u256; use crate::{ blockchain::AddressHash, constant::ADDRESS_BYTE_LENGTH, - env::Context, math::abi::encode_selector_const, storage::{ multi_address_map::MultiAddressMemoryMap, @@ -187,7 +186,7 @@ pub trait OP20Trait<'a>: super::ContractTrait<'a> { } fn balance_of_base(&mut self, address: &AddressHash) -> u256 { - self.balance_of_map().get(address, u256::ZERO) + self.balance_of_map().get(address) } fn balance_of( @@ -221,7 +220,7 @@ pub trait OP20Trait<'a>: super::ContractTrait<'a> { return Err(crate::error::Error::NoBalance); } - let balance: u256 = self.balance_of_map().get(&sender, u256::ZERO); + let balance: u256 = self.balance_of_map().get(&sender); if balance < value { return Err(crate::error::Error::InsufficientBalance); } @@ -260,7 +259,7 @@ pub trait OP20Trait<'a>: super::ContractTrait<'a> { if !self.balance_of_map().contains_key(to) { self.balance_of_map().set(to, value); } else { - let to_balance = self.balance_of_map().get(to, u256::ZERO); + let to_balance = self.balance_of_map().get(to); self.balance_of_map().set(to, to_balance + value); } @@ -291,7 +290,7 @@ pub trait OP20Trait<'a>: super::ContractTrait<'a> { return Err(crate::error::Error::CannotTransferZeroTokens); } - let balance = self.balance_of_map().get(&sender, u256::ZERO); + let balance = self.balance_of_map().get(&sender); if balance < value { return Err(crate::error::Error::InsufficientBalance); @@ -299,7 +298,7 @@ pub trait OP20Trait<'a>: super::ContractTrait<'a> { let new_balance = balance - value; self.balance_of_map().set(&sender, new_balance); - let balance = self.balance_of_map().get(to, u256::ZERO); + let balance = self.balance_of_map().get(to); let new_balance = balance + value; self.balance_of_map().set(to, new_balance); @@ -346,9 +345,7 @@ pub trait OP20Trait<'a>: super::ContractTrait<'a> { to: &AddressHash, value: u256, ) -> Result { - let context = self.context().clone(); - - let balance: u256 = self.balance_of_map().get(from, u256::ZERO); + let balance: u256 = self.balance_of_map().get(from); if balance < value { return Err(crate::error::Error::InsufficientBalance); } @@ -359,7 +356,7 @@ pub trait OP20Trait<'a>: super::ContractTrait<'a> { if !self.balance_of_map().contains_key(to) { self.balance_of_map().set(to, value); } else { - let to_balance: u256 = self.balance_of_map().get(to, u256::ZERO); + let to_balance: u256 = self.balance_of_map().get(to); let new_to_balance = to_balance + value; self.balance_of_map().set(to, new_to_balance); } diff --git a/src/env/global.rs b/src/env/global.rs index e7fd215..aadb28c 100644 --- a/src/env/global.rs +++ b/src/env/global.rs @@ -4,6 +4,7 @@ use crate::{ WaBuffer, }; use core::str::FromStr; +use ethnum::u256; //#[cfg(target_arch = "wasm32")] #[link(wasm_import_module = "env")] @@ -75,7 +76,7 @@ impl super::Context for GlobalContext { unsafe { WaBuffer::from_raw(call(buffer.ptr())) } } - fn encode_address(&self, address: &str) -> &'static [u8] { + fn encode_address(&self, _address: &str) -> &'static [u8] { b"abcd" } @@ -87,11 +88,11 @@ impl super::Context for GlobalContext { unsafe { WaBuffer::from_raw(deployFromAddress(buffer.ptr())) } } - fn validate_bitcoin_address(&self, address: &str) -> bool { + fn validate_bitcoin_address(&self, _address: &str) -> bool { false } - fn verify_schnorr_signature(&self, data: &[u8]) -> bool { + fn verify_schnorr_signature(&self, _data: &[u8]) -> bool { false } @@ -130,7 +131,7 @@ impl super::Context for GlobalContext { } fn next_pointer_greater_than(&self, pointer: StorageKey) -> StorageKey { - [0; 32] + (u256::from_le_bytes(pointer) + 1).to_le_bytes() } fn inputs(&self) -> alloc::vec::Vec { diff --git a/src/env/test.rs b/src/env/test.rs index f8a146c..bb4bb93 100644 --- a/src/env/test.rs +++ b/src/env/test.rs @@ -1,5 +1,5 @@ use alloc::vec::Vec; -use core::cell::RefCell; +use ethnum::u256; use crate::{ storage::map::Map, @@ -46,7 +46,7 @@ impl super::Context for TestContext { self.events.push(event); } - fn log(&self, text: &str) {} + fn log(&self, _text: &str) {} fn call(&self, buffer: crate::WaBuffer) -> WaBuffer { buffer @@ -60,15 +60,15 @@ impl super::Context for TestContext { buffer } - fn encode_address(&self, address: &str) -> &'static [u8] { + fn encode_address(&self, _address: &str) -> &'static [u8] { b"abc" } - fn validate_bitcoin_address(&self, address: &str) -> bool { + fn validate_bitcoin_address(&self, _address: &str) -> bool { true } - fn verify_schnorr_signature(&self, data: &[u8]) -> bool { + fn verify_schnorr_signature(&self, _data: &[u8]) -> bool { true } @@ -113,7 +113,7 @@ impl super::Context for TestContext { &self, pointer: crate::storage::StorageKey, ) -> crate::storage::StorageKey { - [0; 32] + (u256::from_be_bytes(pointer) + 1).to_le_bytes() } fn inputs(&self) -> Vec { diff --git a/src/storage/stored.rs b/src/storage/stored.rs index c399fba..9545917 100644 --- a/src/storage/stored.rs +++ b/src/storage/stored.rs @@ -153,55 +153,48 @@ mod tests { #[test] fn test_bool() { let mut stored_bool = super::StoredBool::new_const(context(), 0, false); - let mut context = context(); stored_bool.set(true); assert_eq!(stored_bool.refresh(), true) } #[test] fn test_u8() { - let mut context = context(); - let mut stored_u8 = super::StoredU8::new_const(context, 0, 0); + let mut stored_u8 = super::StoredU8::new_const(context(), 0, 0); stored_u8.set(1); assert_eq!(stored_u8.refresh(), 1) } #[test] fn test_u16() { - let context = context(); - let mut stored_u16 = super::StoredU16::new_const(context, 0, 0); + let mut stored_u16 = super::StoredU16::new_const(context(), 0, 0); stored_u16.set(123); assert_eq!(stored_u16.refresh(), 123) } #[test] fn test_u32() { - let mut context = context(); - let mut stored_u32 = super::StoredU32::new_const(context, 0, 0); + let mut stored_u32 = super::StoredU32::new_const(context(), 0, 0); stored_u32.set(123); assert_eq!(stored_u32.refresh(), 123) } #[test] fn test_u64() { - let mut context = context(); - let mut stored_u64 = super::StoredU64::new_const(context, 0, 0); + let mut stored_u64 = super::StoredU64::new_const(context(), 0, 0); stored_u64.set(123); assert_eq!(stored_u64.refresh(), 123) } #[test] fn test_u128() { - let mut context = context(); - let mut stored_u128 = super::StoredU128::new_const(context, 0, 0); + let mut stored_u128 = super::StoredU128::new_const(context(), 0, 0); stored_u128.set(123); assert_eq!(stored_u128.refresh(), 123) } #[test] fn test_u256() { - let mut context = context(); - let mut stored_u256 = super::StoredU256::new_const(context, 0, u256::new(0)); + let mut stored_u256 = super::StoredU256::new_const(context(), 0, u256::new(0)); stored_u256.set(u256::new(123)); assert_eq!(stored_u256.refresh(), u256::new(123)) } diff --git a/src/storage/stored_map.rs b/src/storage/stored_map.rs index 6094ef8..b909c9f 100644 --- a/src/storage/stored_map.rs +++ b/src/storage/stored_map.rs @@ -9,7 +9,7 @@ use alloc::rc::Rc; pub struct StoredMap where K: Into, - V: Into, + V: Into + Clone, { context: Rc>, default: V, @@ -40,14 +40,14 @@ where self.context.borrow_mut().store(key_hash, value); } - pub fn get(&self, key: &K, default_value: V) -> V { + pub fn get(&self, key: &K) -> V { let key: StorageKey = (*key).into(); let key_hash = encode_pointer(self.pointer, &key); self.context .borrow_mut() .load(&key_hash) .map(|value| V::from(value)) - .unwrap_or_else(|| default_value) + .unwrap_or(self.default.clone()) } pub fn contains_key(&self, key: &K) -> bool { From aa90b66ed1afeff3fd65afc5c44ebb035e95b6e9 Mon Sep 17 00:00:00 2001 From: Miksa Date: Wed, 5 Mar 2025 14:54:29 +0100 Subject: [PATCH 20/23] Chained call for TestContext --- example/src/contract.rs | 97 +++++++++++------- example/src/lib.rs | 49 ++------- rust.wasm | Bin 37688 -> 37374 bytes src/blockchain/address.rs | 12 ++- src/blockchain/block.rs | 1 + src/blockchain/environment.rs | 1 + src/contract/mod.rs | 26 +++-- src/contract/op_20.rs | 86 ++++++++-------- src/cursor/mod.rs | 36 ++++++- src/env/global.rs | 180 ++++++++++++++++++++++------------ src/env/mod.rs | 102 +++++++++---------- src/env/test.rs | 98 +++++++++++++----- src/event/mod.rs | 76 +++++++++----- src/lib.rs | 67 ++++++++++++- src/math/abi.rs | 13 ++- src/mem.rs | 26 ++--- src/prelude.rs | 1 - src/storage/key.rs | 20 +++- src/storage/map.rs | 1 + src/storage/stored.rs | 4 +- src/storage/stored_map.rs | 6 +- src/storage/value.rs | 11 +++ src/tests/mod.rs | 15 ++- 23 files changed, 596 insertions(+), 332 deletions(-) diff --git a/example/src/contract.rs b/example/src/contract.rs index 77ca163..c1586b3 100644 --- a/example/src/contract.rs +++ b/example/src/contract.rs @@ -19,15 +19,15 @@ const SELECTOR_AIRDROP: Selector = encode_selector_const("airdrop"); const SELECTOR_AIRDROP_WITH_AMOUNT: Selector = encode_selector_const("airdropWithAmount"); const SELECTOR_MINT: Selector = encode_selector_const("mint"); -pub struct Contract<'a> { - environment: Option<&'a rust_runtime::blockchain::Environment>, +pub struct Contract { + environment: Option<&'static rust_runtime::blockchain::Environment>, params: rust_runtime::contract::op_20::OP20Params, balance_of_map: StoredMap, allowance_map: MultiAddressMemoryMap, total_supply: StoredU256, context: Rc>, } -impl<'a> Contract<'a> { +impl Contract { pub fn new(context: Rc>) -> Self { Self { environment: None, @@ -61,12 +61,12 @@ impl<'a> Contract<'a> { } } -impl<'a> Contract<'a> { +impl Contract { fn execute( &mut self, selector: Selector, call_data: CallData, - ) -> Result { + ) -> Result { match selector { SELECTOR_MINT => self.mint(call_data), SELECTOR_AIRDROP => self.airdrop(call_data), @@ -78,33 +78,31 @@ impl<'a> Contract<'a> { fn mint( &mut self, mut call_data: CallData, - ) -> Result { + ) -> Result { self.only_deployer(&self.environment().sender)?; - let mut response = crate::WaBuffer::new(1, 1)?; - let mut cursor = response.cursor(); + let mut cursor = rust_runtime::cursor::Cursor::new(1); let address = call_data.read_address()?; let amount = call_data.read_u256_be()?; cursor.write_bool(self.mint_base(&address, amount, false)?)?; - return Ok(response); + return Ok(cursor); } fn airdrop( &mut self, mut call_data: CallData, - ) -> Result { + ) -> Result { self.only_deployer(&self.environment().sender)?; let drops = call_data.read_address_value_map()?; for (address, amount) in drops.iter() { self.mint_base(address, amount.clone(), false)?; } - let mut response = crate::WaBuffer::new(1, 1)?; - let mut cursor = response.cursor(); + let mut cursor = rust_runtime::cursor::Cursor::new(1); cursor.write_bool(true)?; - Ok(response) + Ok(cursor) } fn optimized_mint( @@ -124,7 +122,7 @@ impl<'a> Contract<'a> { fn airdrop_with_amount( &mut self, mut call_data: CallData, - ) -> Result { + ) -> Result { self.only_deployer(&self.environment().sender)?; let amount = call_data.read_u256_be()?; let amount_of_addresses: u32 = call_data.read_u32_le()?; @@ -136,14 +134,13 @@ impl<'a> Contract<'a> { self.total_supply.commit(); - let mut response = crate::WaBuffer::new(1, 1)?; - let mut cursor = response.cursor(); + let mut cursor = rust_runtime::cursor::Cursor::new(1); cursor.write_bool(true)?; - Ok(response) + Ok(cursor) } } -impl<'a> rust_runtime::contract::op_20::OP20Trait<'a> for Contract<'a> { +impl rust_runtime::contract::op_20::OP20Trait for Contract { fn params(&mut self) -> &mut rust_runtime::OP20Params { &mut self.params } @@ -161,12 +158,12 @@ impl<'a> rust_runtime::contract::op_20::OP20Trait<'a> for Contract<'a> { } } -impl<'a> rust_runtime::contract::ContractTrait<'a> for Contract<'a> { - fn set_environment(&mut self, environment: &'a rust_runtime::blockchain::Environment) { +impl rust_runtime::contract::ContractTrait for Contract { + fn set_environment(&mut self, environment: &'static rust_runtime::blockchain::Environment) { self.environment = Some(environment); } - fn environment(&self) -> &'a rust_runtime::blockchain::Environment { + fn environment(&self) -> &'static rust_runtime::blockchain::Environment { self.environment.unwrap() } @@ -177,7 +174,7 @@ impl<'a> rust_runtime::contract::ContractTrait<'a> for Contract<'a> { fn execute( &mut self, mut call_data: CallData, - ) -> Result { + ) -> Result { let selector = call_data.read_selector()?; Contract::execute(self, selector, call_data) @@ -194,10 +191,15 @@ mod tests { use crate::contract::SELECTOR_MINT; use alloc::{rc::Rc, vec::Vec}; use rust_runtime::{ - contract::op_20::{SELECTOR_BALANCE_OF, SELECTOR_NAME, SELECTOR_TOTAL_SUPPLY}, + contract::{ + self, + op_20::{SELECTOR_BALANCE_OF, SELECTOR_NAME, SELECTOR_TOTAL_SUPPLY}, + }, + cursor::{self, Cursor}, ethnum::u256, storage::map::Map, tests::{execute, execute_address, execute_address_amount, random_environment}, + Context, }; fn context() -> Rc> { @@ -206,6 +208,7 @@ mod tests { Map::new(), Vec::new(), Vec::new(), + None, ))) } @@ -219,32 +222,52 @@ mod tests { #[test] fn test_contract_mint() { - let context = context(); - let mut contract = super::Contract::new(context); + let router = Rc::new(RefCell::new(rust_runtime::env::TestRouter::new())); + let context = rust_runtime::env::TestContext::new( + rust_runtime::Network::Mainnet, + Map::new(), + Vec::new(), + Vec::new(), + Some(router.clone()), + ); let address = rust_runtime::tests::random_address(); - contract.environment = rust_runtime::blockchain::Environment { + let environment = rust_runtime::blockchain::Environment { deployer: address.clone(), sender: address.clone(), ..random_environment() - } - .leak(); + }; + + let mut contract = + alloc::boxed::Box::new(super::Contract::new(Rc::new(RefCell::new(context.clone())))); + + contract.environment = environment.clone().leak(); + router.borrow_mut().push(address.clone(), contract); + let amount = u256::new(10000000); - let mut cursor = execute_address(&mut contract, SELECTOR_BALANCE_OF, &address); + let mut cursor = Cursor::new(4 + 32); + cursor.write_selector(&SELECTOR_BALANCE_OF).unwrap(); + cursor.write_address(&address).unwrap(); + let mut cursor = router.borrow().call(address.clone(), cursor); assert_eq!(cursor.read_u256_be().unwrap(), 0); - for _ in 0..3 { - execute_address_amount(&mut contract, SELECTOR_MINT, &address, amount); - } + for i in 0..3 { + let mut cursor = rust_runtime::cursor::Cursor::new(4 + 32 + 32); + cursor.write_selector(&SELECTOR_MINT).unwrap(); + cursor.write_address(&address).unwrap(); + cursor.write_u256_be(&amount).unwrap(); - let mut cursor = execute_address(&mut contract, SELECTOR_BALANCE_OF, &address); - assert_eq!(cursor.read_u256_be().unwrap(), 3 * amount); + let mut cursor = router.borrow().call(address.clone(), cursor); + assert_eq!(cursor.read_bool().unwrap(), true); - execute_address_amount(&mut contract, SELECTOR_MINT, &address, amount); // mint more + let mut cursor = Cursor::new(36); + cursor.write_selector(&SELECTOR_BALANCE_OF).unwrap(); + cursor.write_address(&address).unwrap(); + let mut cursor = router.borrow().call(address.clone(), cursor); - let mut cursor = execute_address(&mut contract, SELECTOR_BALANCE_OF, &address); - assert_eq!(cursor.read_u256_be().unwrap(), 4 * amount); + assert_eq!(cursor.read_u256_be().unwrap(), (i + 1) * amount); + } } #[test] diff --git a/example/src/lib.rs b/example/src/lib.rs index 896e83b..dfe0109 100644 --- a/example/src/lib.rs +++ b/example/src/lib.rs @@ -8,16 +8,9 @@ use alloc::rc::Rc; use core::cell::RefCell; #[allow(unused_imports)] -use rust_runtime::prelude::{ContractTrait, WaBuffer, WaPtr}; +use rust_runtime::prelude::ContractTrait; pub mod contract; -#[cfg(target_arch = "wasm32")] -static mut CONTRACT: spin::Lazy> = spin::Lazy::new(|| { - RefCell::new(contract::Contract::new(Rc::new(RefCell::new( - rust_runtime::env::global::GlobalContext::new(), - )))) -}); - #[cfg(target_arch = "wasm32")] use lol_alloc::LeakingPageAllocator; @@ -26,37 +19,11 @@ use lol_alloc::LeakingPageAllocator; static ALLOCATOR: LeakingPageAllocator = LeakingPageAllocator; #[cfg(target_arch = "wasm32")] -#[allow(static_mut_refs)] -#[export_name = "execute"] -pub unsafe fn execute(ptr: WaPtr) -> WaPtr { - use spin::lazy::Lazy; - - match CONTRACT - .borrow_mut() - .execute(WaBuffer::from_raw(ptr).cursor()) - { - Ok(buffer) => buffer.ptr(), - Err(err) => { - CONTRACT.borrow_mut().log(err.as_str()); - panic!("Error occured") - } - } -} - -#[cfg(target_arch = "wasm32")] -#[export_name = "onDeploy"] -#[allow(static_mut_refs)] -pub unsafe fn on_deploy(ptr: WaPtr) { - CONTRACT - .borrow_mut() - .on_deploy(WaBuffer::from_raw(ptr).cursor()); -} - -#[cfg(target_arch = "wasm32")] -#[export_name = "setEnvironment"] -#[allow(static_mut_refs)] -pub unsafe fn set_environment(ptr: WaPtr) { - let buffer = WaBuffer::from_raw(ptr); - let environment: &mut rust_runtime::blockchain::Environment = buffer.into_type(); - CONTRACT.borrow_mut().set_environment(environment); +#[export_name = "start"] +pub unsafe fn start() { + use rust_runtime::env::global::GlobalContext; + let context = Rc::new(RefCell::new(GlobalContext::new())); + rust_runtime::CONTRACT = Some(Rc::new(RefCell::new(crate::contract::Contract::new( + context, + )))); } diff --git a/rust.wasm b/rust.wasm index e20e0c37a188a6b0bb9df54cfb2e6544abcd67f5..9ba50a57e47b7375e87dc9edcfdc020e068d4477 100644 GIT binary patch delta 6861 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 E1K?5ZCIA2c delta 7076 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 diff --git a/src/blockchain/address.rs b/src/blockchain/address.rs index 2bd8566..42887e6 100644 --- a/src/blockchain/address.rs +++ b/src/blockchain/address.rs @@ -1,4 +1,4 @@ -use crate::storage::StorageKey; +use crate::{storage::StorageKey, WaPtr}; #[derive(Clone, Copy, Eq, PartialEq, Debug)] pub struct AddressHash { @@ -7,7 +7,7 @@ pub struct AddressHash { impl From for StorageKey { fn from(val: AddressHash) -> Self { - val.bytes + StorageKey::new(val.bytes) } } @@ -24,9 +24,17 @@ impl AddressHash { 161, 210, 254, 244, 21, 57, 153, 34, 205, 138, 4, 72, 92, 2, ], }; + pub const fn new_from_bytes(bytes: [u8; crate::constant::ADDRESS_BYTE_LENGTH]) -> Self { + Self { bytes } + } + pub fn new(bytes: &[u8]) -> Self { Self { bytes: bytes.try_into().unwrap(), } } + + pub fn ptr(&self) -> WaPtr { + WaPtr::from(&self.bytes) + } } diff --git a/src/blockchain/block.rs b/src/blockchain/block.rs index 3d457bd..8b5a8d6 100644 --- a/src/blockchain/block.rs +++ b/src/blockchain/block.rs @@ -1,3 +1,4 @@ +#[derive(Clone)] pub struct BlockHash { pub bytes: [u8; crate::constant::BLOCK_HASH_LENGTH], } diff --git a/src/blockchain/environment.rs b/src/blockchain/environment.rs index da8636f..da11453 100644 --- a/src/blockchain/environment.rs +++ b/src/blockchain/environment.rs @@ -1,5 +1,6 @@ use super::AddressHash; +#[derive(Clone)] pub struct Environment { pub sender: super::AddressHash, pub origin: super::AddressHash, diff --git a/src/contract/mod.rs b/src/contract/mod.rs index 624f66f..68a1a89 100644 --- a/src/contract/mod.rs +++ b/src/contract/mod.rs @@ -4,17 +4,17 @@ use core::cell::RefCell; use crate::{ blockchain::AddressHash, - mem::WaBuffer, + cursor::Cursor, storage::{StorageKey, StorageValue}, types::CallData, Context, }; pub mod op_20; -pub trait ContractTrait<'a> { - fn set_environment(&mut self, environment: &'a crate::blockchain::Environment); +pub trait ContractTrait { + fn set_environment(&mut self, environment: &'static crate::blockchain::Environment); - fn environment(&self) -> &'a crate::blockchain::Environment; + fn environment(&self) -> &'static crate::blockchain::Environment; fn context(&self) -> Rc>; @@ -34,7 +34,7 @@ pub trait ContractTrait<'a> { self.context().borrow().log("On Deploy is not implemented"); } - fn execute(&mut self, _call_data: CallData) -> Result { + fn execute(&mut self, _call_data: CallData) -> Result { self.context().borrow().log("Execute is not implemented"); unimplemented!("Execute needs to be implemented"); } @@ -45,8 +45,12 @@ pub trait ContractTrait<'a> { fn emit(&self, event: &dyn crate::event::EventTrait) { self.context().borrow_mut().emit(event); } - fn call(&self, buffer: WaBuffer) -> WaBuffer { - self.context().borrow().call(buffer) + fn call( + &self, + address: &crate::blockchain::AddressHash, + data: crate::cursor::Cursor, + ) -> Cursor { + self.context().borrow().call(address, data) } fn load(&self, pointer: &StorageKey) -> Option { @@ -58,12 +62,14 @@ pub trait ContractTrait<'a> { fn exists(&self, pointer: &StorageKey) -> bool { self.context().borrow_mut().exists(pointer) } + /* fn next_pointer_greater_than(&self, pointer: StorageKey) -> StorageKey { self.context() .as_ref() .borrow() .next_pointer_greater_than(pointer) } + */ fn encode_address(&self, address: &str) -> &'static [u8] { self.context().borrow().encode_address(address) @@ -74,13 +80,13 @@ pub trait ContractTrait<'a> { fn verify_schnorr_signature(&self, data: &[u8]) -> bool { self.context().borrow().verify_schnorr_signature(data) } - fn sha256(&self, data: &[u8]) -> &'static [u8] { + fn sha256(&self, data: &[u8]) -> [u8; 32] { self.context().borrow().sha256(data) } - fn sha256_double(&self, data: &[u8]) -> &'static [u8] { + fn sha256_double(&self, data: &[u8]) -> [u8; 32] { self.context().borrow().sha256_double(data) } - fn ripemd160(&self, data: &[u8]) -> &'static [u8] { + fn ripemd160(&self, data: &[u8]) -> [u8; 20] { self.context().borrow().ripemd160(data) } diff --git a/src/contract/op_20.rs b/src/contract/op_20.rs index 9ef96ba..e96d659 100644 --- a/src/contract/op_20.rs +++ b/src/contract/op_20.rs @@ -3,6 +3,7 @@ use ethnum::u256; use crate::{ blockchain::AddressHash, constant::ADDRESS_BYTE_LENGTH, + cursor::Cursor, math::abi::encode_selector_const, storage::{ multi_address_map::MultiAddressMemoryMap, @@ -10,7 +11,6 @@ use crate::{ stored_map::StoredMap, }, types::{CallData, Selector}, - WaBuffer, }; pub struct OP20Params { @@ -50,50 +50,45 @@ pub const SELECTOR_BURN: Selector = encode_selector_const("burn"); pub const SELECTOR_TRANSFER: Selector = encode_selector_const("transfer"); pub const SELECTOR_TRANSFER_FROM: Selector = encode_selector_const("transferFrom"); -pub trait OP20Trait<'a>: super::ContractTrait<'a> { +pub trait OP20Trait: super::ContractTrait { fn execute_base( &mut self, selector: Selector, - call_data: crate::types::CallData, - ) -> Result { + call_data: CallData, + ) -> Result { match selector { SELECTOR_OWNER => { - let mut buffer = WaBuffer::new(ADDRESS_BYTE_LENGTH, 2)?; - let mut cursor = buffer.cursor(); + let mut cursor = Cursor::new(ADDRESS_BYTE_LENGTH); cursor.write_address(&self.environment().deployer)?; - Ok(buffer) + Ok(cursor) } SELECTOR_DECIMALS => { - let mut buffer = WaBuffer::new(1, 2)?; - let mut cursor = buffer.cursor(); + let mut cursor = Cursor::new(1); cursor.write_u8(self.decimals())?; - Ok(buffer) + Ok(cursor) } SELECTOR_NAME => { let name = self.name(); - let mut buffer = WaBuffer::new(name.len() + 2, 1)?; - let mut cursor = buffer.cursor(); + let mut cursor = Cursor::new(name.len() + 2); cursor.write_string_with_len(name)?; - Ok(buffer) + Ok(cursor) } SELECTOR_SYMBOL => { let symbol = self.symbol(); - let mut buffer = WaBuffer::new(symbol.len() + 2, 1)?; - let mut cursor = buffer.cursor(); + + let mut cursor = Cursor::new(symbol.len() + 2); cursor.write_string_with_len(symbol)?; - Ok(buffer) + Ok(cursor) } SELECTOR_TOTAL_SUPPLY => { - let mut buffer = WaBuffer::new(32, 1)?; - let mut cursor = buffer.cursor(); + let mut cursor = Cursor::new(32); cursor.write_u256_be(&self.total_supply().value())?; - Ok(buffer) + Ok(cursor) } SELECTOR_MAXIMUM_SUPPLY => { - let mut buffer = WaBuffer::new(32, 1)?; - let mut cursor = buffer.cursor(); + let mut cursor = Cursor::new(32); cursor.write_u256_be(&self.max_supply())?; - Ok(buffer) + Ok(cursor) } SELECTOR_ALLOWANCE => self.allowance(call_data), SELECTOR_APPROVE => self.approve(call_data), @@ -108,7 +103,7 @@ pub trait OP20Trait<'a>: super::ContractTrait<'a> { &mut self, selector: Selector, call_data: crate::types::CallData, - ) -> Result { + ) -> Result { self.execute_base(selector, call_data) } @@ -140,15 +135,14 @@ pub trait OP20Trait<'a>: super::ContractTrait<'a> { fn allowance( &mut self, mut call_data: CallData, - ) -> Result { - let mut response = crate::WaBuffer::new(32, 1)?; - let mut cursor = response.cursor(); + ) -> Result { + let mut cursor = Cursor::new(32); let address_owner = call_data.read_address()?; let address_spender = call_data.read_address()?; let allowance = self.allowance_base(&address_owner, &address_spender); cursor.write_u256_be(&allowance)?; - Ok(response) + Ok(cursor) } fn approve_base( @@ -173,16 +167,18 @@ pub trait OP20Trait<'a>: super::ContractTrait<'a> { Ok(true) } - fn approve(&mut self, mut call_data: CallData) -> Result { + fn approve( + &mut self, + mut call_data: CallData, + ) -> Result { let owner = self.environment().sender; let spender = call_data.read_address()?; let amount = call_data.read_u256_be()?; - let mut response = crate::WaBuffer::new(32, 1)?; - let mut cursor = response.cursor(); + let mut cursor = Cursor::new(32); cursor.write_bool(self.approve_base(&owner, &spender, amount)?)?; - Ok(response) + Ok(cursor) } fn balance_of_base(&mut self, address: &AddressHash) -> u256 { @@ -192,13 +188,12 @@ pub trait OP20Trait<'a>: super::ContractTrait<'a> { fn balance_of( &mut self, mut call_data: crate::types::CallData, - ) -> Result { - let mut response = WaBuffer::new(32, 1)?; - let mut cursor = response.cursor(); + ) -> Result { + let mut cursor = Cursor::new(32); let address = call_data.read_address()?; let balance = self.balance_of_base(&address); cursor.write_u256_be(&balance)?; - Ok(response) + Ok(cursor) } fn burn_base(&mut self, value: u256, only_deployer: bool) -> Result { @@ -237,13 +232,12 @@ pub trait OP20Trait<'a>: super::ContractTrait<'a> { fn burn( &mut self, mut call_data: crate::types::CallData, - ) -> Result { - let mut response = WaBuffer::new(1, 1)?; - let mut cursor = response.cursor(); + ) -> Result { + let mut cursor = Cursor::new(1); let amount = call_data.read_u256_be()?; cursor.write_bool(self.burn_base(amount, true)?)?; - Ok(response) + Ok(cursor) } fn mint_base( @@ -309,15 +303,14 @@ pub trait OP20Trait<'a>: super::ContractTrait<'a> { fn transfer( &mut self, mut call_data: crate::types::CallData, - ) -> Result { - let mut response = WaBuffer::new(1, 1)?; - let mut cursor = response.cursor(); + ) -> Result { + let mut cursor = Cursor::new(1); let address = call_data.read_address()?; let amount = call_data.read_u256_be()?; let result = self.transfer_base(&address, amount)?; cursor.write_bool(result)?; - Ok(response) + Ok(cursor) } fn spend_allowance( @@ -384,16 +377,15 @@ pub trait OP20Trait<'a>: super::ContractTrait<'a> { fn transfer_from( &mut self, mut call_data: crate::types::CallData, - ) -> Result { - let mut response = WaBuffer::new(1, 1)?; - let mut cursor = response.cursor(); + ) -> Result { + let mut cursor = Cursor::new(1); let address_from = call_data.read_address()?; let address_to = call_data.read_address()?; let amount = call_data.read_u256_be()?; cursor.write_bool(self.transfer_from_base(&address_from, &address_to, amount)?)?; - Ok(response) + Ok(cursor) } fn create_burn_event(&mut self, value: u256) -> Result<(), crate::error::Error> { diff --git a/src/cursor/mod.rs b/src/cursor/mod.rs index 01edca8..107a76c 100644 --- a/src/cursor/mod.rs +++ b/src/cursor/mod.rs @@ -1,4 +1,8 @@ -use crate::WaBuffer; +use core::alloc::Layout; + +use ::alloc::alloc::alloc; + +use crate::WaPtr; pub mod reader; pub mod writer; @@ -9,7 +13,33 @@ pub struct Cursor { writer: usize, } +impl Clone for Cursor { + fn clone(&self) -> Self { + Cursor::from_ptr(self.ptr(), self.inner.len()) + } +} + impl Cursor { + pub fn new(size: usize) -> Cursor { + unsafe { + let layout = Layout::from_size_align_unchecked(size, 1); + Cursor { + inner: core::slice::from_raw_parts_mut(alloc(layout), size), + reader: 0, + writer: 0, + } + } + } + + pub fn from_ptr(ptr: WaPtr, size: usize) -> Cursor { + unsafe { + Cursor { + inner: core::slice::from_raw_parts_mut(ptr.0 as *mut u8, size), + reader: 0, + writer: 0, + } + } + } pub fn from_slice(inner: &'static mut [u8]) -> Cursor { Cursor { reader: 0, @@ -35,8 +65,8 @@ impl Cursor { self.writer = 0; } - pub fn get_buffer(&self) -> Result { - WaBuffer::from_bytes(self.inner) + pub fn ptr(&self) -> WaPtr { + WaPtr((self.inner.as_ptr()) as u32) } } diff --git a/src/env/global.rs b/src/env/global.rs index aadb28c..ec905dd 100644 --- a/src/env/global.rs +++ b/src/env/global.rs @@ -1,91 +1,126 @@ -use crate::mem::WaPtr; +use alloc::vec::Vec; + use crate::{ - storage::{key::StorageKey, map::Map, value::StorageValue}, - WaBuffer, + blockchain::{transaction::Input, AddressHash}, + cursor::Cursor, + storage::{ + key::{self, StorageKey}, + map::Map, + value::{self, StorageValue}, + }, + WaPtr, }; -use core::str::FromStr; use ethnum::u256; -//#[cfg(target_arch = "wasm32")] #[link(wasm_import_module = "env")] extern "C" { - #[allow(dead_code)] - pub fn load(ptr: WaPtr) -> WaPtr; - #[allow(dead_code)] - pub fn store(ptr: WaPtr) -> WaPtr; - - #[allow(dead_code)] - pub fn nextPointerGreaterThan(ptr: WaPtr) -> WaPtr; - - #[allow(dead_code)] - pub fn deploy(ptr: WaPtr) -> WaPtr; - #[allow(dead_code)] - pub fn deployFromAddress(ptr: WaPtr) -> WaPtr; - - #[allow(dead_code)] - pub fn call(ptr: WaPtr) -> WaPtr; - #[allow(dead_code)] - pub fn log(ptr: WaPtr); - #[allow(dead_code)] - pub fn emit(ptr: WaPtr); - #[allow(dead_code)] - pub fn encodeAddress(ptr: WaPtr) -> WaPtr; - #[allow(dead_code)] - pub fn validateBitcoinAddress(ptr: WaPtr) -> WaPtr; - #[allow(dead_code)] - pub fn verifySchnorrSignature(ptr: WaPtr) -> WaPtr; - #[allow(dead_code)] - pub fn sha256(ptr: WaPtr) -> WaPtr; - #[allow(dead_code)] - pub fn ripemd160(ptr: WaPtr) -> WaPtr; - #[allow(dead_code)] - pub fn inputs() -> WaPtr; - #[allow(dead_code)] - pub fn outputs() -> WaPtr; + pub fn revert(data: u32, length: u32); + + #[link_name = "getCalldata"] + pub fn get_call_data(offset: u32, length: u32, result: WaPtr); + + pub fn load(key: u32, result: u32); + + pub fn store(key: u32, value: u32); + + #[link_name = "deployFromAddress"] + pub fn deploy_from_address(origin_address: u32, salt: u32, result_address: u32) -> u32; + + pub fn call(address: u32, call_data: u32, call_data_length: u32, resultLength: u32); + + #[link_name = "callResult"] + pub fn call_result(offset: u32, length: u32, result: u32); + + pub fn emit(data: u32, data_length: u32); + #[link_name = "encodeAddress"] + pub fn encode_address(data: u32) -> u32; + + #[link_name = "validateBitcoinAddress"] + pub fn validate_bitcoin_address(addres: u32, address_length: u32) -> u32; + + #[link_name = "verifySchnorrSignature"] + pub fn verify_schnorr_signature(public_key: u32, signature: u32, message: u32) -> u32; + + pub fn sha256(data: u32, data_legth: u32, result: u32); + + pub fn ripemd160(data: u32, data_length: u32, result: u32); + + #[link_name = "inputsSize"] + pub fn inputs_size() -> u32; + + pub fn inputs(buffer: u32); + + #[link_name = "outputsSize"] + pub fn outputs_size() -> u32; + + pub fn outputs(buffer: u32); +} + +#[link(wasm_import_module = "debug")] +extern "C" { + pub fn log(ptr: u32); } //#[cfg(target_arch = "wasm32")] pub struct GlobalContext { store: Map, + inputs: Option>, + outputs: Option>, } //#[cfg(target_arch = "wasm32")] impl GlobalContext { pub const fn new() -> Self { - Self { store: Map::new() } + Self { + store: Map::new(), + inputs: None, + outputs: None, + } } } //#[cfg(target_arch = "wasm32")] impl super::Context for GlobalContext { + fn get_call_data(&self, size: usize) -> Cursor { + let cursor = crate::cursor::Cursor::new(size); + unsafe { + get_call_data(0, size as u32, cursor.ptr()); + } + cursor + } + fn log(&self, text: &str) { unsafe { - if let Ok(string) = WaBuffer::from_str(text) { - log(string.ptr()); - } + let bytes = text + .as_bytes() + .iter() + .chain(b"\0".iter()) + .cloned() + .collect::>(); + log(bytes.as_ptr() as u32); } } fn emit(&mut self, event: &dyn crate::event::EventTrait) { unsafe { - emit(event.buffer().ptr()); + emit(event.ptr(), event.buffer().len() as u32); } } - fn call(&self, buffer: WaBuffer) -> WaBuffer { - unsafe { WaBuffer::from_raw(call(buffer.ptr())) } + fn call(&self, address: &crate::blockchain::AddressHash, data: Cursor) -> Cursor { + data } fn encode_address(&self, _address: &str) -> &'static [u8] { b"abcd" } - fn deploy(&self, buffer: WaBuffer) -> WaBuffer { - unsafe { WaBuffer::from_raw(deploy(buffer.ptr())) } - } - - fn deploy_from_address(&self, buffer: WaBuffer) -> WaBuffer { - unsafe { WaBuffer::from_raw(deployFromAddress(buffer.ptr())) } + fn deploy_from_address( + &self, + from_address: &AddressHash, + salt: [u8; 32], + ) -> Result { + Ok(*from_address) } fn validate_bitcoin_address(&self, _address: &str) -> bool { @@ -98,8 +133,9 @@ impl super::Context for GlobalContext { fn load(&mut self, pointer: &StorageKey) -> Option { unsafe { - let mut buffer = WaBuffer::from_raw(load(WaBuffer::from_bytes(pointer).unwrap().ptr())); - let value: StorageValue = buffer.cursor().read_u256_be().unwrap().into(); + let mut value = StorageValue::from_bytes([0; 32]); + load(pointer.ptr().0, value.ptr().0); + if value.eq(&StorageValue::ZERO) { None } else { @@ -125,20 +161,44 @@ impl super::Context for GlobalContext { false } { self.store.insert(pointer, value); - store(WaBuffer::from_bytes(value.bytes()).unwrap().ptr()); + store(pointer.ptr().0, value.ptr().0) } } } - fn next_pointer_greater_than(&self, pointer: StorageKey) -> StorageKey { - (u256::from_le_bytes(pointer) + 1).to_le_bytes() + fn inputs(&mut self) -> alloc::vec::Vec { + if let Some(inputs) = &self.inputs { + inputs.clone() + } else { + Vec::new() + } } - fn inputs(&self) -> alloc::vec::Vec { - alloc::vec::Vec::new() + /* + fn iter_inputs(&mut self) -> impl Iterator { + if self.inputs.is_none() { + self.inputs = Some(Vec::new()); + } + + self.inputs.as_ref().unwrap().iter() } + */ + + fn outputs(&mut self) -> alloc::vec::Vec { + if let Some(outputs) = &self.outputs { + outputs.clone() + } else { + Vec::new() + } + } + + /* + fn iter_outputs(&mut self) -> impl Iterator { + if self.outputs.is_none() { + self.outputs = Some(Vec::new()); + } - fn outputs(&self) -> alloc::vec::Vec { - alloc::vec::Vec::new() + self.outputs.as_ref().unwrap().iter() } + */ } diff --git a/src/env/mod.rs b/src/env/mod.rs index 3b79a69..5ea860d 100644 --- a/src/env/mod.rs +++ b/src/env/mod.rs @@ -1,8 +1,8 @@ use crate::{ - mem::WaBuffer, + cursor::Cursor, storage::{StorageKey, StorageValue}, }; -use alloc::vec::Vec; +use alloc::{collections::binary_heap::Iter, vec::Vec}; #[allow(unused_imports)] use core::str::FromStr; pub mod global; @@ -11,92 +11,92 @@ pub mod global; mod test; #[cfg(not(target_arch = "wasm32"))] -pub use test::{Network, TestContext}; +pub use test::{Network, TestContext, TestRouter}; #[cfg(target_arch = "wasm32")] -pub fn sha256(bytes: &[u8]) -> &'static [u8] { - unsafe { WaBuffer::from_raw(global::sha256(WaBuffer::from_bytes(bytes).unwrap().ptr())).data() } +pub fn sha256(bytes: &[u8]) -> [u8; 32] { + use crate::math::bytes; + + unsafe { + //WaBuffer::from_raw(global::sha256(WaBuffer::from_bytes(bytes).unwrap().ptr())).data() + let len = bytes.len() as u32; + let result = [0u8; 32]; + global::sha256( + bytes.as_ptr() as *const u8 as u32, + (&len) as *const _ as *const u8 as u32, + result.as_ptr() as *const u8 as u32, + ); + result + } } #[cfg(not(target_arch = "wasm32"))] -pub fn sha256(bytes: &[u8]) -> &'static [u8] { - let sha = alloc::boxed::Box::new(sha2_const::Sha256::new().update(bytes).finalize()); - alloc::boxed::Box::leak(sha) +pub fn sha256(bytes: &[u8]) -> [u8; 32] { + let sha = sha2_const::Sha256::new().update(bytes).finalize(); + sha } #[cfg(target_arch = "wasm32")] -pub fn ripemd160(bytes: &[u8]) -> &'static [u8] { +pub fn ripemd160(bytes: &[u8]) -> [u8; 20] { + use crate::{math::bytes, WaPtr}; + + let len = bytes.len() as u32; + let result = [0u8; 20]; + unsafe { - WaBuffer::from_raw(global::ripemd160( - WaBuffer::from_bytes(bytes).unwrap().ptr(), - )) - .data() + global::ripemd160( + WaPtr::from(bytes).0, + WaPtr::from(&len).0, + WaPtr::from(&result[0..20]).0, + ); + result } } #[cfg(not(target_arch = "wasm32"))] -pub fn ripemd160(data: &[u8]) -> &'static [u8] { +pub fn ripemd160(data: &[u8]) -> [u8; 20] { use ripemd::Digest; let mut hasher = ripemd::Ripemd160::new(); hasher.update(data); let hash = hasher.finalize(); - alloc::boxed::Box::leak(alloc::boxed::Box::new(hash.to_vec())) -} - -pub struct WrappedMut { - inner: T, -} - -impl WrappedMut { - pub const fn new(t: T) -> WrappedMut { - Self { inner: t } - } - - pub fn as_ref(&self) -> &T { - &self.inner - } - - pub fn as_mut(&self) -> &mut T { - unsafe { - if let Some(val) = ((&self.inner) as *const T as *mut T).as_mut() { - val - } else { - panic!("Unexpected null"); - } - } - } + hash[0..20].try_into().unwrap() } pub trait Context { + fn get_call_data(&self, size: usize) -> Cursor; fn log(&self, text: &str); fn emit(&mut self, event: &dyn crate::event::EventTrait); - fn call(&self, buffer: WaBuffer) -> WaBuffer; + fn call(&self, address: &crate::blockchain::AddressHash, data: Cursor) -> Cursor; - fn deploy(&self, buffer: WaBuffer) -> WaBuffer; - fn deploy_from_address(&self, buffer: WaBuffer) -> WaBuffer; + fn deploy_from_address( + &self, + from_address: &crate::blockchain::AddressHash, + salt: [u8; 32], + ) -> Result; fn load(&mut self, pointer: &StorageKey) -> Option; fn store(&mut self, pointer: StorageKey, value: StorageValue); fn exists(&mut self, pointer: &StorageKey) -> bool; - fn next_pointer_greater_than(&self, pointer: StorageKey) -> StorageKey; fn encode_address(&self, address: &str) -> &'static [u8]; fn validate_bitcoin_address(&self, address: &str) -> bool; fn verify_schnorr_signature(&self, data: &[u8]) -> bool; - fn sha256(&self, data: &[u8]) -> &'static [u8] { + fn sha256(&self, data: &[u8]) -> [u8; 32] { sha256(data) } - fn sha256_double(&self, data: &[u8]) -> &'static [u8] { - self.sha256(self.sha256(data)) + fn sha256_double(&self, data: &[u8]) -> [u8; 32] { + self.sha256(&self.sha256(data)) } - fn ripemd160(&self, data: &[u8]) -> &'static [u8] { + fn ripemd160(&self, data: &[u8]) -> [u8; 20] { ripemd160(data) } - fn inputs(&self) -> Vec; - fn outputs(&self) -> Vec; + fn inputs(&mut self) -> Vec; + //fn iter_inputs(&mut self) -> impl Iterator; + fn outputs(&mut self) -> Vec; + //fn iter_outputs(&mut self) -> impl Iterator; } #[cfg(test)] @@ -105,7 +105,7 @@ mod tests { fn test_sha_256() { let text = "Hello world"; assert_eq!( - crate::utils::to_hex(super::sha256(text.as_bytes())), + crate::utils::to_hex(&super::sha256(text.as_bytes())), alloc::string::String::from( "0x64ec88ca00b268e5ba1a35678a1b5316d212f4f366b2477232534a8aeca37f3c" ) @@ -116,7 +116,7 @@ mod tests { fn test_ripemd160() { let text = "Hello world"; assert_eq!( - crate::utils::to_hex(super::ripemd160(text.as_bytes())), + crate::utils::to_hex(&super::ripemd160(text.as_bytes())), alloc::string::String::from("0xdbea7bd24eef40a2e79387542e36dd408b77b21a") ); } diff --git a/src/env/test.rs b/src/env/test.rs index bb4bb93..6faedec 100644 --- a/src/env/test.rs +++ b/src/env/test.rs @@ -1,25 +1,60 @@ +use core::cell::RefCell; +extern crate std; use alloc::vec::Vec; -use ethnum::u256; +use alloc::{boxed::Box, rc::Rc}; +use crate::contract; use crate::{ - storage::map::Map, - storage::{StorageKey, StorageValue}, - WaBuffer, + blockchain::{address, AddressHash}, + cursor::Cursor, + storage::{map::Map, StorageKey, StorageValue}, + ContractTrait, }; +#[derive(Clone)] pub enum Network { Mainnet, Testnet, Preview, } +pub struct TestRouter { + contracts: Vec<(AddressHash, *mut dyn ContractTrait)>, +} +impl TestRouter { + pub fn new() -> Self { + Self { + contracts: Vec::new(), + } + } + + pub fn push(&mut self, address: AddressHash, contract: Box) { + let contract = Box::into_raw(contract); + self.contracts.push((address, contract)); + } + pub fn call(&self, address: AddressHash, call_data: Cursor) -> Cursor { + if let Some((_, contract_ptr)) = self.contracts.iter().find(|(addr, _)| address.eq(addr)) { + unsafe { + let mut contract: Box = Box::from_raw(*contract_ptr); + let result = contract.execute(call_data).unwrap(); + Box::leak(contract); + result + } + } else { + panic!("Contract is not present") + } + } +} + +#[derive(Clone)] pub struct TestContext { pub network: Network, pub events: alloc::vec::Vec, pub global_store: Map, pub cache_store: Map, - pub inputs: alloc::vec::Vec, - pub outputs: alloc::vec::Vec, + pub inputs: Vec, + pub outputs: Vec, + pub router: Option>>, } impl TestContext { @@ -28,6 +63,7 @@ impl TestContext { global_store: Map, inputs: alloc::vec::Vec, outputs: alloc::vec::Vec, + router: Option>>, ) -> Self { Self { network, @@ -36,11 +72,16 @@ impl TestContext { cache_store: Map::new(), inputs, outputs, + router, } } } impl super::Context for TestContext { + // Just mock, data are passed from different entry point + fn get_call_data(&self, size: usize) -> Cursor { + Cursor::new(size) + } fn emit(&mut self, event: &dyn crate::event::EventTrait) { let event = crate::event::Event::new(event.buffer()); self.events.push(event); @@ -48,16 +89,24 @@ impl super::Context for TestContext { fn log(&self, _text: &str) {} - fn call(&self, buffer: crate::WaBuffer) -> WaBuffer { - buffer - } - - fn deploy(&self, buffer: WaBuffer) -> WaBuffer { - buffer + fn call( + &self, + address: &crate::blockchain::AddressHash, + call_data: crate::cursor::Cursor, + ) -> Cursor { + if let Some(router) = &self.router { + router.borrow().call(address.clone(), call_data) + } else { + panic!("There is no router associated with a contract") + } } - fn deploy_from_address(&self, buffer: WaBuffer) -> WaBuffer { - buffer + fn deploy_from_address( + &self, + from_address: &crate::blockchain::AddressHash, + salt: [u8; 32], + ) -> Result { + Ok(*from_address) } fn encode_address(&self, _address: &str) -> &'static [u8] { @@ -109,18 +158,23 @@ impl super::Context for TestContext { } } - fn next_pointer_greater_than( - &self, - pointer: crate::storage::StorageKey, - ) -> crate::storage::StorageKey { - (u256::from_be_bytes(pointer) + 1).to_le_bytes() + fn inputs(&mut self) -> Vec { + self.inputs.clone() } - fn inputs(&self) -> Vec { - self.inputs.clone() + /* + fn iter_inputs(&mut self) -> impl Iterator { + self.inputs.iter() } + */ - fn outputs(&self) -> Vec { + fn outputs(&mut self) -> Vec { self.outputs.clone() } + + /* + fn iter_outputs(&mut self) -> impl Iterator { + self.outputs.iter() + } + */ } diff --git a/src/event/mod.rs b/src/event/mod.rs index 41110ad..6283b98 100644 --- a/src/event/mod.rs +++ b/src/event/mod.rs @@ -1,18 +1,22 @@ -use crate::{blockchain::AddressHash, constant::ADDRESS_BYTE_LENGTH, WaBuffer}; +use crate::cursor::Cursor; +use crate::{blockchain::AddressHash, constant::ADDRESS_BYTE_LENGTH}; use ethnum::u256; pub trait EventTrait { - fn buffer(&self) -> WaBuffer; + fn buffer(&self) -> &'static [u8]; + fn ptr(&self) -> u32; } +#[derive(Clone)] pub struct Event { - pub buffer: WaBuffer, + pub buffer: &'static [u8], } impl Event { - pub fn new(buffer: WaBuffer) -> Event { + pub fn new(buffer: &'static [u8]) -> Event { Self { buffer } } + pub fn approve( owner: AddressHash, spender: AddressHash, @@ -20,8 +24,8 @@ impl Event { ) -> Result { let event_type = "Approve"; let byte_size = ADDRESS_BYTE_LENGTH * 2 + 32; - let mut buffer = WaBuffer::new(event_type.len() + 6 + byte_size, 1)?; - let mut cursor = buffer.cursor(); + //let mut buffer = crate::mem::WaBuffer::new(event_type.len() + 6 + byte_size, 1)?; + let mut cursor = Cursor::new(event_type.len() + 6 + byte_size); cursor.write_string_with_len(event_type)?; cursor.write_u32_le(&(byte_size as u32))?; @@ -29,73 +33,85 @@ impl Event { cursor.write_address(&spender)?; cursor.write_u256_be(&value)?; - Ok(Event { buffer }) + Ok(Event { + buffer: cursor.into_inner(), + }) } pub fn burn(amount: u256) -> Result { let event_type = "Burn"; let byte_size = 32; - let mut buffer = WaBuffer::new(event_type.len() + 6 + byte_size, 1)?; - let mut cursor = buffer.cursor(); + //let mut buffer = WaBuffer::new(event_type.len() + 6 + byte_size, 1)?; + let mut cursor = Cursor::new(event_type.len() + 6 + byte_size); cursor.write_string_with_len(event_type)?; cursor.write_u32_le(&(byte_size as u32))?; cursor.write_u256_be(&amount)?; - Ok(Event { buffer }) + Ok(Event { + buffer: cursor.into_inner(), + }) } pub fn claim(amount: u256) -> Result { let event_type = "Claim"; let byte_size = 32; - let mut buffer = WaBuffer::new(event_type.len() + 6 + byte_size, 1)?; - let mut cursor = buffer.cursor(); + //let mut buffer = WaBuffer::new(event_type.len() + 6 + byte_size, 1)?; + let mut cursor = Cursor::new(event_type.len() + 6 + byte_size); cursor.write_string_with_len(event_type)?; cursor.write_u32_le(&(byte_size as u32))?; cursor.write_u256_be(&amount)?; - Ok(Event { buffer }) + Ok(Event { + buffer: cursor.into_inner(), + }) } pub fn mint(address: AddressHash, amount: u256) -> Result { let event_type = "Mint"; let byte_size = 32 + ADDRESS_BYTE_LENGTH; - let mut buffer = WaBuffer::new(event_type.len() + 6 + byte_size, 1)?; - let mut cursor = buffer.cursor(); + //let mut buffer = WaBuffer::new(event_type.len() + 6 + byte_size, 1)?; + let mut cursor = Cursor::new(event_type.len() + 6 + byte_size); cursor.write_string_with_len(event_type)?; cursor.write_u32_le(&(byte_size as u32))?; cursor.write_address(&address)?; cursor.write_u256_be(&amount)?; - Ok(Event { buffer }) + Ok(Event { + buffer: cursor.into_inner(), + }) } pub fn stake(amount: u256) -> Result { let event_type = "Stake"; let byte_size = 32; - let mut buffer = WaBuffer::new(event_type.len() + 6 + byte_size, 1)?; - let mut cursor = buffer.cursor(); + // let mut buffer = WaBuffer::new(event_type.len() + 6 + byte_size, 1)?; + let mut cursor = Cursor::new(event_type.len() + 6 + byte_size); cursor.write_string_with_len(event_type)?; cursor.write_u32_le(&(byte_size as u32))?; cursor.write_u256_be(&amount)?; - Ok(Event { buffer }) + Ok(Event { + buffer: cursor.into_inner(), + }) } pub fn unstake(amount: u256) -> Result { let event_type = "Unstake"; let byte_size = 32; - let mut buffer = WaBuffer::new(event_type.len() + 6 + byte_size, 1)?; - let mut cursor = buffer.cursor(); + //let mut buffer = WaBuffer::new(event_type.len() + 6 + byte_size, 1)?; + let mut cursor = Cursor::new(event_type.len() + 6 + byte_size); cursor.write_string_with_len(event_type)?; cursor.write_u32_le(&(byte_size as u32))?; cursor.write_u256_be(&amount)?; - Ok(Event { buffer }) + Ok(Event { + buffer: cursor.into_inner(), + }) } pub fn transfer( @@ -106,8 +122,8 @@ impl Event { let event_type = "Transfer"; let byte_size = ADDRESS_BYTE_LENGTH * 2 + 32; - let mut buffer = WaBuffer::new(event_type.len() + 6 + byte_size, 1)?; - let mut cursor = buffer.cursor(); + //let mut buffer = WaBuffer::new(event_type.len() + 6 + byte_size, 1)?; + let mut cursor = Cursor::new(event_type.len() + 6 + byte_size); cursor.write_string_with_len(event_type)?; @@ -117,12 +133,18 @@ impl Event { cursor.write_address(&addr_to)?; cursor.write_u256_be(&amount)?; - Ok(Event { buffer }) + Ok(Event { + buffer: cursor.into_inner(), + }) } } impl EventTrait for Event { - fn buffer(&self) -> WaBuffer { - self.buffer.clone() + fn buffer(&self) -> &'static [u8] { + self.buffer + } + + fn ptr(&self) -> u32 { + (self.buffer.as_ptr() as u32) } } diff --git a/src/lib.rs b/src/lib.rs index 190099c..6fbdcc5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,17 +13,20 @@ pub mod env; pub mod error; pub mod event; pub mod math; -mod mem; pub mod prelude; pub mod storage; pub mod types; pub mod utils; +//pub mod mem; pub mod tests; -pub use crate::mem::WaBuffer; +use core::cell::RefCell; + +use alloc::rc::Rc; pub use env::*; pub use ethnum; +//pub use mem::WaBuffer; pub use utils::*; pub use contract::{ @@ -31,6 +34,28 @@ pub use contract::{ ContractTrait, }; +pub static mut CONTRACT: Option>> = None; + +pub struct WaPtr(u32); + +impl From<&u32> for WaPtr { + fn from(value: &u32) -> Self { + Self(value as *const _ as *mut u8 as u32) + } +} + +impl From<&[u8]> for WaPtr { + fn from(value: &[u8]) -> Self { + Self(value as *const _ as *mut u8 as u32) + } +} + +impl From<&[u8; 32]> for WaPtr { + fn from(value: &[u8; 32]) -> Self { + Self(value as *const _ as *mut u8 as u32) + } +} + #[cfg(not(test))] #[cfg(not(feature = "std"))] #[cfg(target_arch = "wasm32")] @@ -38,3 +63,41 @@ pub use contract::{ fn panic(_panic: &core::panic::PanicInfo<'_>) -> ! { core::arch::wasm32::unreachable() } + +//#[cfg(target_arch = "wasm32")] +#[allow(static_mut_refs)] +#[export_name = "execute"] +pub unsafe fn execute(length: u32) -> WaPtr { + if let Some(contract) = &mut CONTRACT { + let mut contract = contract.borrow_mut(); + + let call_data = contract + .context() + .borrow_mut() + .get_call_data(length as usize); + + contract.execute(call_data).unwrap().ptr() + } else { + panic!("Contract is not set") + } +} + +#[cfg(target_arch = "wasm32")] +#[export_name = "onDeploy"] +#[allow(static_mut_refs)] +pub unsafe fn on_deploy(ptr: WaPtr) { + // problematic input!!! +} + +#[cfg(target_arch = "wasm32")] +#[export_name = "setEnvironment"] +#[allow(static_mut_refs)] +pub unsafe fn set_environment(ptr: u32) { + use blockchain::Environment; + + let environment = core::ptr::NonNull::new_unchecked(ptr as *mut Environment).as_mut(); + if let Some(contract) = &mut CONTRACT { + let mut contract = contract.borrow_mut(); + contract.set_environment(environment); + } +} diff --git a/src/math/abi.rs b/src/math/abi.rs index 6485968..8bbb08d 100644 --- a/src/math/abi.rs +++ b/src/math/abi.rs @@ -17,21 +17,26 @@ pub const fn encode_selector_const(selector: &str) -> crate::types::Selector { * Encode selector in the runtime */ pub fn encode_selector(selector: &str) -> crate::types::Selector { - super::bytes::bytes4(crate::env::sha256(selector.as_bytes()).try_into().unwrap()) + super::bytes::bytes4( + crate::env::sha256(selector.as_bytes())[0..4] + .try_into() + .unwrap(), + ) } pub const fn encode_pointer_const(unique_identifier: u16) -> StorageKey { let mut key = [0; crate::constant::STORE_KEY_SIZE]; key[0] = (unique_identifier & 0xff) as u8; key[1] = ((unique_identifier >> 8) & 0xff) as u8; - key + + StorageKey::new(key) } pub fn encode_pointer(unique_identifier: u16, typed: &[u8]) -> StorageKey { let hash = if typed.len() != 32 { sha256(typed) } else { - typed + typed.try_into().unwrap() }; let mut final_pointer: [u8; 32] = [0; 32]; @@ -46,5 +51,5 @@ pub fn encode_pointer(unique_identifier: u16, typed: &[u8]) -> StorageKey { */ final_pointer[2..32].copy_from_slice(&hash[..30]); - final_pointer + StorageKey::new(final_pointer) } diff --git a/src/mem.rs b/src/mem.rs index a4161ae..f8dab39 100644 --- a/src/mem.rs +++ b/src/mem.rs @@ -7,10 +7,10 @@ use core::str::FromStr; use libc_print::std_name::println; use crate::cursor::Cursor; // Import format and String from alloc - +use crate::WaPtr; extern crate alloc; -pub type WaPtr = u32; +//pub type WaPtr = u32; pub struct WaCell { pub mm_info: u64, @@ -23,8 +23,8 @@ pub struct WaCell { } impl WaCell { - const fn size() -> WaPtr { - size_of::() as WaPtr + const fn size() -> u32 { + size_of::() as u32 } const fn usize() -> usize { size_of::() @@ -59,12 +59,14 @@ impl WaCell { } pub fn from_raw(ptr: WaPtr) -> &'static mut WaCell { - unsafe { NonNull::::new_unchecked((ptr - WaCell::size()) as *mut WaCell).as_mut() } + unsafe { + NonNull::::new_unchecked((ptr.0 - WaCell::size()) as *mut WaCell).as_mut() + } } #[inline] pub fn ptr(&self) -> WaPtr { - (self as *const Self as *const u8 as WaPtr) + WaCell::size() + WaPtr((self as *const Self as *const u8 as u32) + WaCell::size()) } #[cfg(target_arch = "wasm32")] @@ -114,8 +116,9 @@ impl WaBuffer { let buffer = WaCell::new(size, 1); let pointer = WaCell::new(12, id); let mut cursor = pointer.cursor(); - cursor.write_u32_le(&buffer.ptr())?; - cursor.write_u32_le(&buffer.ptr())?; + + cursor.write_u32_le(&buffer.ptr().0)?; + cursor.write_u32_le(&buffer.ptr().0)?; cursor.write_u32_le(&(size as u32))?; Ok(WaBuffer { pointer, buffer }) } @@ -123,8 +126,9 @@ impl WaBuffer { let buffer = WaCell::new_data(1, bytes); let pointer = WaCell::new(12, 2); let mut cursor = pointer.cursor(); - cursor.write_u32_le(&buffer.ptr())?; - cursor.write_u32_le(&buffer.ptr())?; + + cursor.write_u32_le(&buffer.ptr().0)?; + cursor.write_u32_le(&buffer.ptr().0)?; cursor.write_u32_le(&(bytes.len() as u32))?; Ok(WaBuffer { pointer, buffer }) } @@ -132,7 +136,7 @@ impl WaBuffer { let pointer = WaCell::from_raw(ptr); let mut cursor = pointer.cursor(); let buffer_ptr = cursor.read_u32_le_unchecked(); - let buffer = WaCell::from_raw(buffer_ptr); + let buffer = WaCell::from_raw(WaPtr(buffer_ptr)); WaBuffer { pointer, buffer } } diff --git a/src/prelude.rs b/src/prelude.rs index 01cd494..b4a8400 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -1,4 +1,3 @@ pub use crate::cursor::Cursor; pub use crate::ethnum; -pub use crate::mem::{WaBuffer, WaCell, WaPtr}; pub use crate::ContractTrait; diff --git a/src/storage/key.rs b/src/storage/key.rs index a641867..e13f460 100644 --- a/src/storage/key.rs +++ b/src/storage/key.rs @@ -1 +1,19 @@ -pub type StorageKey = [u8; crate::constant::STORE_KEY_SIZE]; +use crate::WaPtr; + +#[derive(Clone, Copy, Eq, PartialEq)] +pub struct StorageKey { + pub bytes: [u8; crate::constant::STORE_KEY_SIZE], +} + +impl StorageKey { + pub const fn new(bytes: [u8; crate::constant::STORE_KEY_SIZE]) -> Self { + Self { bytes } + } + pub fn mut_ptr(&mut self) -> WaPtr { + WaPtr(self.bytes.as_mut_ptr() as *mut u8 as u32) + } + + pub fn ptr(&self) -> WaPtr { + WaPtr(self.bytes.as_ptr() as *const u8 as u32) + } +} diff --git a/src/storage/map.rs b/src/storage/map.rs index 5c71ca0..405abcf 100644 --- a/src/storage/map.rs +++ b/src/storage/map.rs @@ -2,6 +2,7 @@ //! /// Map structure +#[derive(Clone)] pub struct Map where Key: Sized + Eq, diff --git a/src/storage/stored.rs b/src/storage/stored.rs index 9545917..aca3dbc 100644 --- a/src/storage/stored.rs +++ b/src/storage/stored.rs @@ -110,7 +110,7 @@ where ) -> Self { Self { context, - pointer: encode_pointer(pointer, sub_pointer), + pointer: encode_pointer(pointer, &sub_pointer.bytes), default_value, value: None, } @@ -135,6 +135,7 @@ mod tests { use alloc::vec::Vec; use ethnum::u256; + use crate::cursor::Cursor; use crate::storage::map::Map; use crate::Context; use crate::TestContext; @@ -147,6 +148,7 @@ mod tests { Map::new(), Vec::new(), Vec::new(), + None, ))) } diff --git a/src/storage/stored_map.rs b/src/storage/stored_map.rs index b909c9f..f762ad2 100644 --- a/src/storage/stored_map.rs +++ b/src/storage/stored_map.rs @@ -35,14 +35,14 @@ where pub fn set(&self, key: &K, value: V) { let key: StorageKey = (*key).into(); - let key_hash = encode_pointer(self.pointer, &key); + let key_hash = encode_pointer(self.pointer, &key.bytes); let value = Into::::into(value); self.context.borrow_mut().store(key_hash, value); } pub fn get(&self, key: &K) -> V { let key: StorageKey = (*key).into(); - let key_hash = encode_pointer(self.pointer, &key); + let key_hash = encode_pointer(self.pointer, &key.bytes); self.context .borrow_mut() .load(&key_hash) @@ -52,7 +52,7 @@ where pub fn contains_key(&self, key: &K) -> bool { let key: StorageKey = (*key).into(); - let key_hash = encode_pointer(self.pointer, &key); + let key_hash = encode_pointer(self.pointer, &key.bytes); let has = self.context.borrow_mut().exists(&key_hash); has } diff --git a/src/storage/value.rs b/src/storage/value.rs index 2c9e093..43dcc82 100644 --- a/src/storage/value.rs +++ b/src/storage/value.rs @@ -1,5 +1,7 @@ use ethnum::u256; +use crate::WaPtr; + #[derive(Copy, Clone, Eq, PartialEq)] pub struct StorageValue { inner: [u8; crate::constant::STORE_VALUE_SIZE], @@ -10,9 +12,18 @@ impl StorageValue { inner: [0; crate::constant::STORE_VALUE_SIZE], }; + pub fn mut_ptr(&mut self) -> WaPtr { + WaPtr(self.inner.as_mut_ptr() as *mut u8 as u32) + } + + pub fn ptr(&self) -> WaPtr { + WaPtr(self.inner.as_ptr() as *const u8 as u32) + } + pub fn from_bytes(bytes: [u8; crate::constant::STORE_VALUE_SIZE]) -> Self { Self { inner: bytes } } + pub fn value(&self) -> [u8; crate::constant::STORE_VALUE_SIZE] { self.inner } diff --git a/src/tests/mod.rs b/src/tests/mod.rs index 62a7ae1..270e733 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -72,10 +72,9 @@ pub fn execute( contract: &mut dyn crate::ContractTrait, selector: crate::types::Selector, ) -> Cursor { - let mut buffer = crate::WaBuffer::new(32, 1).unwrap(); - let mut cursor = buffer.cursor(); + let mut cursor = Cursor::new(32); cursor.write_u32_le(&selector).unwrap(); - contract.execute(cursor).unwrap().cursor() + contract.execute(cursor).unwrap() } pub fn execute_address( @@ -83,11 +82,10 @@ pub fn execute_address( selector: crate::types::Selector, address: &AddressHash, ) -> Cursor { - let mut buffer = crate::WaBuffer::new(64, 1).unwrap(); - let mut cursor = buffer.cursor(); + let mut cursor = Cursor::new(64); cursor.write_u32_le(&selector).unwrap(); cursor.write_address(address).unwrap(); - contract.execute(cursor).unwrap().cursor() + contract.execute(cursor).unwrap() } pub fn execute_address_amount( @@ -96,10 +94,9 @@ pub fn execute_address_amount( address: &AddressHash, amount: u256, ) -> Cursor { - let mut buffer = crate::WaBuffer::new(96, 1).unwrap(); - let mut cursor = buffer.cursor(); + let mut cursor = Cursor::new(96); cursor.write_u32_le(&selector).unwrap(); cursor.write_address(address).unwrap(); cursor.write_u256_be(&amount).unwrap(); - contract.execute(cursor).unwrap().cursor() + contract.execute(cursor).unwrap() } From e6531bd1597a559aa9cbc2105de65b551a500a3a Mon Sep 17 00:00:00 2001 From: Miksa Date: Mon, 10 Mar 2025 13:00:30 +0100 Subject: [PATCH 21/23] WIP changes --- Cargo.lock | 134 ++++++++++++++++++- Cargo.toml | 3 +- example/Cargo.toml | 2 +- example/src/contract.rs | 83 +++++------- example/src/lib.rs | 8 +- src/blockchain/address.rs | 3 + src/blockchain/block.rs | 5 + src/blockchain/environment.rs | 76 +++++------ src/blockchain/mod.rs | 2 +- src/blockchain/transaction.rs | 5 + src/constant.rs | 2 + src/contract/mod.rs | 56 ++++---- src/contract/op_20.rs | 26 ++-- src/env/global.rs | 133 ++++++++++++------- src/env/mod.rs | 18 +-- src/env/test.rs | 215 ++++++++++++++++++++++++------- src/event/mod.rs | 2 +- src/lib.rs | 29 ++--- src/storage/array_merger.rs | 13 +- src/storage/mod.rs | 51 -------- src/storage/multi_address_map.rs | 8 +- src/storage/stored.rs | 26 +--- src/storage/stored_map.rs | 9 +- src/tests/mod.rs | 36 +----- 24 files changed, 554 insertions(+), 391 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 91aa6a0..7cb2787 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,12 +2,82 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + [[package]] name = "autocfg" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +[[package]] +name = "base58ck" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c8d66485a3a2ea485c1913c4572ce0256067a5377ac8c75c4960e1cda98605f" +dependencies = [ + "bitcoin-internals", + "bitcoin_hashes", +] + +[[package]] +name = "bech32" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d965446196e3b7decd44aa7ee49e31d630118f90ef12f97900f262eb915c951d" + +[[package]] +name = "bitcoin" +version = "0.32.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6bc65742dea50536e35ad42492b234c27904a27f0abdcbce605015cb4ea026" +dependencies = [ + "base58ck", + "bech32", + "bitcoin-internals", + "bitcoin-io", + "bitcoin-units", + "bitcoin_hashes", + "hex-conservative", + "hex_lit", + "secp256k1 0.29.1", +] + +[[package]] +name = "bitcoin-internals" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30bdbe14aa07b06e6cfeffc529a1f099e5fbe249524f8125358604df99a4bed2" + +[[package]] +name = "bitcoin-io" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b47c4ab7a93edb0c7198c5535ed9b52b63095f4e9b45279c6736cec4b856baf" + +[[package]] +name = "bitcoin-units" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5285c8bcaa25876d07f37e3d30c303f2609179716e11d688f51e8f1fe70063e2" +dependencies = [ + "bitcoin-internals", +] + +[[package]] +name = "bitcoin_hashes" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb18c03d0db0247e147a21a6faafd5a7eb851c743db062de72018b6b7e8e4d16" +dependencies = [ + "bitcoin-io", + "hex-conservative", +] + [[package]] name = "block-buffer" version = "0.10.4" @@ -23,6 +93,15 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +[[package]] +name = "cc" +version = "1.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c" +dependencies = [ + "shlex", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -62,7 +141,6 @@ dependencies = [ "lol_alloc", "rust_runtime", "sha2-const", - "spin", ] [[package]] @@ -86,6 +164,21 @@ dependencies = [ "wasi", ] +[[package]] +name = "hex-conservative" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5313b072ce3c597065a808dbf612c4c8e8590bdbf8b579508bf7a762c5eae6cd" +dependencies = [ + "arrayvec", +] + +[[package]] +name = "hex_lit" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3011d1213f159867b13cfd6ac92d2cd5f1345762c63be3554e84092d85a50bbd" + [[package]] name = "libc" version = "0.2.168" @@ -190,12 +283,13 @@ dependencies = [ name = "rust_runtime" version = "0.1.0" dependencies = [ + "bitcoin", "ethnum", "libc-print", "rand", "ripemd", + "secp256k1 0.30.0", "sha2-const", - "spin", ] [[package]] @@ -204,12 +298,48 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "secp256k1" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9465315bc9d4566e1724f0fffcbcc446268cb522e60f9a27bcded6b19c108113" +dependencies = [ + "bitcoin_hashes", + "secp256k1-sys", +] + +[[package]] +name = "secp256k1" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b50c5943d326858130af85e049f2661ba3c78b26589b8ab98e65e80ae44a1252" +dependencies = [ + "bitcoin_hashes", + "rand", + "secp256k1-sys", +] + +[[package]] +name = "secp256k1-sys" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4387882333d3aa8cb20530a17c69a3752e97837832f34f6dccc760e715001d9" +dependencies = [ + "cc", +] + [[package]] name = "sha2-const" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5edcd790916d95ff81bdc1505b09c74d30d47a755929cc8c71c59cbbfa99f91b" +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "spin" version = "0.9.8" diff --git a/Cargo.toml b/Cargo.toml index fdf26ba..b416f12 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,12 +24,13 @@ members = ["example"] # This crate is much larger than expected. Avoid using it unless absolutely necessary. ethnum = { workspace = true } sha2-const = { workspace = true } -spin = { version = "0.9.8", features=["mutex", "lazy"]} [target.'cfg(not(target_arch = "wasm32"))'.dependencies] rand = { version = "0.8.5" } libc-print = { version = "0.1.22" } ripemd = "0.1.3" +bitcoin = "0.32.5" +secp256k1 = { version = "0.30.0", features = ["std"] } [features] std = [] diff --git a/example/Cargo.toml b/example/Cargo.toml index 819612b..9fd7511 100644 --- a/example/Cargo.toml +++ b/example/Cargo.toml @@ -17,6 +17,6 @@ strip = true lol_alloc = { workspace = true } rust_runtime = { workspace = true } sha2-const = {workspace = true } -spin = { version = "0.9.8", features=["mutex", "lazy"]} + [features] diff --git a/example/src/contract.rs b/example/src/contract.rs index c1586b3..fa5bdc8 100644 --- a/example/src/contract.rs +++ b/example/src/contract.rs @@ -1,7 +1,7 @@ use alloc::rc::Rc; use core::cell::RefCell; use rust_runtime::{ - blockchain::AddressHash, + blockchain::{AddressHash, Environment}, contract::op_20::Pointer, ethnum::u256, math::abi::encode_selector_const, @@ -20,15 +20,15 @@ const SELECTOR_AIRDROP_WITH_AMOUNT: Selector = encode_selector_const("airdropWit const SELECTOR_MINT: Selector = encode_selector_const("mint"); pub struct Contract { - environment: Option<&'static rust_runtime::blockchain::Environment>, + environment: Option, params: rust_runtime::contract::op_20::OP20Params, balance_of_map: StoredMap, allowance_map: MultiAddressMemoryMap, total_supply: StoredU256, - context: Rc>, + context: Rc, } impl Contract { - pub fn new(context: Rc>) -> Self { + pub fn new(context: Rc) -> Self { Self { environment: None, params: rust_runtime::contract::op_20::OP20Params { @@ -79,7 +79,8 @@ impl Contract { &mut self, mut call_data: CallData, ) -> Result { - self.only_deployer(&self.environment().sender)?; + let sender = self.environment().caller; + self.only_deployer(&sender)?; let mut cursor = rust_runtime::cursor::Cursor::new(1); let address = call_data.read_address()?; @@ -93,7 +94,8 @@ impl Contract { &mut self, mut call_data: CallData, ) -> Result { - self.only_deployer(&self.environment().sender)?; + let sender = self.environment().caller; + self.only_deployer(&sender)?; let drops = call_data.read_address_value_map()?; for (address, amount) in drops.iter() { self.mint_base(address, amount.clone(), false)?; @@ -123,7 +125,8 @@ impl Contract { &mut self, mut call_data: CallData, ) -> Result { - self.only_deployer(&self.environment().sender)?; + let sender = self.environment().caller; + self.only_deployer(&sender)?; let amount = call_data.read_u256_be()?; let amount_of_addresses: u32 = call_data.read_u32_le()?; @@ -159,15 +162,14 @@ impl rust_runtime::contract::op_20::OP20Trait for Contract { } impl rust_runtime::contract::ContractTrait for Contract { - fn set_environment(&mut self, environment: &'static rust_runtime::blockchain::Environment) { - self.environment = Some(environment); - } - - fn environment(&self) -> &'static rust_runtime::blockchain::Environment { - self.environment.unwrap() + fn environment(&mut self) -> &Environment { + if self.environment.is_none() { + self.environment = Some(self.context().environment()); + } + self.environment.as_ref().unwrap() } - fn context(&self) -> Rc> { + fn context(&self) -> Rc { self.context.clone() } @@ -189,27 +191,16 @@ mod tests { use core::cell::RefCell; use crate::contract::SELECTOR_MINT; - use alloc::{rc::Rc, vec::Vec}; + use alloc::rc::Rc; use rust_runtime::{ - contract::{ - self, - op_20::{SELECTOR_BALANCE_OF, SELECTOR_NAME, SELECTOR_TOTAL_SUPPLY}, - }, - cursor::{self, Cursor}, + contract::op_20::{SELECTOR_BALANCE_OF, SELECTOR_NAME, SELECTOR_TOTAL_SUPPLY}, + cursor::Cursor, ethnum::u256, - storage::map::Map, - tests::{execute, execute_address, execute_address_amount, random_environment}, - Context, + tests::{execute, execute_address, execute_address_amount}, }; - fn context() -> Rc> { - Rc::new(RefCell::new(rust_runtime::env::TestContext::new( - rust_runtime::Network::Mainnet, - Map::new(), - Vec::new(), - Vec::new(), - None, - ))) + fn context() -> Rc { + Rc::new(rust_runtime::env::TestContext::default()) } #[test] @@ -223,25 +214,18 @@ mod tests { #[test] fn test_contract_mint() { let router = Rc::new(RefCell::new(rust_runtime::env::TestRouter::new())); - let context = rust_runtime::env::TestContext::new( - rust_runtime::Network::Mainnet, - Map::new(), - Vec::new(), - Vec::new(), - Some(router.clone()), - ); + let context = rust_runtime::env::TestContext::default(); let address = rust_runtime::tests::random_address(); let environment = rust_runtime::blockchain::Environment { - deployer: address.clone(), - sender: address.clone(), - ..random_environment() + contract_deployer: address.clone(), + caller: address.clone(), + ..Default::default() }; - let mut contract = - alloc::boxed::Box::new(super::Contract::new(Rc::new(RefCell::new(context.clone())))); + let mut contract = alloc::boxed::Box::new(super::Contract::new(Rc::new(context.clone()))); - contract.environment = environment.clone().leak(); + contract.environment = Some(environment.clone()); router.borrow_mut().push(address.clone(), contract); let amount = u256::new(10000000); @@ -277,12 +261,11 @@ mod tests { let address = rust_runtime::tests::random_address(); - contract.environment = rust_runtime::blockchain::Environment { - deployer: address.clone(), - sender: address.clone(), - ..random_environment() - } - .leak(); + contract.environment = Some(rust_runtime::blockchain::Environment { + contract_deployer: address.clone(), + caller: address.clone(), + ..Default::default() + }); let amount = u256::new(10000000); let mut cursor = execute(&mut contract, SELECTOR_TOTAL_SUPPLY); diff --git a/example/src/lib.rs b/example/src/lib.rs index dfe0109..2234dc9 100644 --- a/example/src/lib.rs +++ b/example/src/lib.rs @@ -8,7 +8,6 @@ use alloc::rc::Rc; use core::cell::RefCell; #[allow(unused_imports)] -use rust_runtime::prelude::ContractTrait; pub mod contract; #[cfg(target_arch = "wasm32")] @@ -21,8 +20,13 @@ static ALLOCATOR: LeakingPageAllocator = LeakingPageAllocator; #[cfg(target_arch = "wasm32")] #[export_name = "start"] pub unsafe fn start() { + return; + use rust_runtime::env::global::GlobalContext; - let context = Rc::new(RefCell::new(GlobalContext::new())); + use rust_runtime::Context; + let context = Rc::new(GlobalContext::new()); + + context.log("Hello world"); rust_runtime::CONTRACT = Some(Rc::new(RefCell::new(crate::contract::Contract::new( context, )))); diff --git a/src/blockchain/address.rs b/src/blockchain/address.rs index 42887e6..371477b 100644 --- a/src/blockchain/address.rs +++ b/src/blockchain/address.rs @@ -24,6 +24,9 @@ impl AddressHash { 161, 210, 254, 244, 21, 57, 153, 34, 205, 138, 4, 72, 92, 2, ], }; + pub const EMPTY: AddressHash = AddressHash { + bytes: [0; crate::constant::ADDRESS_BYTE_LENGTH], + }; pub const fn new_from_bytes(bytes: [u8; crate::constant::ADDRESS_BYTE_LENGTH]) -> Self { Self { bytes } } diff --git a/src/blockchain/block.rs b/src/blockchain/block.rs index 8b5a8d6..f2ad663 100644 --- a/src/blockchain/block.rs +++ b/src/blockchain/block.rs @@ -2,6 +2,11 @@ pub struct BlockHash { pub bytes: [u8; crate::constant::BLOCK_HASH_LENGTH], } +impl BlockHash { + pub const EMPTY: BlockHash = BlockHash { + bytes: [0; crate::constant::BLOCK_HASH_LENGTH], + }; +} impl crate::utils::ToHex for BlockHash { fn get_bytes(&self) -> &[u8] { diff --git a/src/blockchain/environment.rs b/src/blockchain/environment.rs index da11453..0294de8 100644 --- a/src/blockchain/environment.rs +++ b/src/blockchain/environment.rs @@ -1,44 +1,23 @@ +use crate::WaPtr; + use super::AddressHash; #[derive(Clone)] pub struct Environment { - pub sender: super::AddressHash, - pub origin: super::AddressHash, - pub transaction_hash: super::TransactionHash, pub block_hash: super::BlockHash, - pub deployer: super::AddressHash, - pub address: super::AddressHash, - pub timestamp: u64, - pub safe_rnd: u64, + pub block_number: u64, + pub block_median_time: u64, + pub transaction_hash: super::TransactionHash, + + pub contract_address: super::AddressHash, + pub contract_deployer: super::AddressHash, + pub caller: super::AddressHash, + pub origin: super::AddressHash, } impl Environment { - #[allow(clippy::too_many_arguments)] - pub fn new( - sender: AddressHash, - origin: AddressHash, - transaction_hash: super::TransactionHash, - block_hash: super::BlockHash, - deployer: AddressHash, - address: AddressHash, - timestamp: u64, - safe_rnd: u64, - ) -> Self { - Self { - sender, - origin, - transaction_hash, - block_hash, - deployer, - address, - timestamp, - safe_rnd, - } - } - - pub fn leak(self) -> Option<&'static Environment> { - let leak: &'static Environment = alloc::boxed::Box::leak(alloc::boxed::Box::new(self)); - Some(leak) + pub fn ptr(&self) -> WaPtr { + WaPtr(self as *const Environment as u32) } } @@ -53,17 +32,32 @@ mod display { use alloc::string::ToString; f.debug_struct("Environment") - .field("sender", &self.sender.to_hex()) + .field("block_hash", &self.block_hash.to_hex()) + .field("block_number", &self.block_number) + .field("block_median_time", &self.block_median_time) + .field("transaction_hash", &self.transaction_hash.to_hex()) + .field("contract_address", &self.contract_address.to_hex()) + .field("contract_deployer", &self.contract_deployer.to_hex()) + .field("caller", &self.caller.to_hex()) .field("origin", &self.origin.to_hex()) - .field("transaction", &to_hex(&self.transaction_hash.bytes)) - .field("block_hash", &to_hex(&self.block_hash.bytes)) - .field("deployer", &self.deployer.to_hex()) - .field("address", &self.address.to_hex()) - .field("timestamp", &self.timestamp.to_string()) - .field("safe_rnd", &self.safe_rnd.to_string()) .finish() } } } -impl Environment {} +#[allow(dead_code)] +#[cfg(not(target_arch = "wasm32"))] +impl Default for Environment { + fn default() -> Self { + Environment { + block_hash: crate::tests::random_block(), + block_number: crate::tests::random_u64(), + block_median_time: crate::tests::random_u64(), + transaction_hash: crate::tests::random_transaction(), + contract_address: crate::tests::random_address(), + contract_deployer: crate::tests::random_address(), + caller: crate::tests::random_address(), + origin: crate::tests::random_address(), + } + } +} diff --git a/src/blockchain/mod.rs b/src/blockchain/mod.rs index 5b8825e..c045bb6 100644 --- a/src/blockchain/mod.rs +++ b/src/blockchain/mod.rs @@ -6,4 +6,4 @@ pub mod transaction; pub use address::AddressHash; pub use block::BlockHash; pub use environment::Environment; -pub use transaction::{Transaction, TransactionHash}; +pub use transaction::{Input, Output, Transaction, TransactionHash}; diff --git a/src/blockchain/transaction.rs b/src/blockchain/transaction.rs index 255cb05..7624d11 100644 --- a/src/blockchain/transaction.rs +++ b/src/blockchain/transaction.rs @@ -2,6 +2,11 @@ pub struct TransactionHash { pub bytes: [u8; crate::constant::TRANSACTION_HASH_LENGTH], } +impl TransactionHash { + pub const EMPTY: TransactionHash = TransactionHash { + bytes: [0; crate::constant::TRANSACTION_HASH_LENGTH], + }; +} impl crate::utils::ToHex for TransactionHash { fn get_bytes(&self) -> &[u8] { self.bytes.as_ref() diff --git a/src/constant.rs b/src/constant.rs index ae30e64..dec6e0d 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -4,3 +4,5 @@ pub const TRANSACTION_HASH_LENGTH: usize = HASH_SIZE; pub const BLOCK_HASH_LENGTH: usize = HASH_SIZE; pub const STORE_KEY_SIZE: usize = HASH_SIZE; pub const STORE_VALUE_SIZE: usize = HASH_SIZE; + +pub const ENVIRONMENT_SIZE: usize = 208; diff --git a/src/contract/mod.rs b/src/contract/mod.rs index 68a1a89..d5c46d3 100644 --- a/src/contract/mod.rs +++ b/src/contract/mod.rs @@ -3,7 +3,7 @@ use alloc::vec::Vec; use core::cell::RefCell; use crate::{ - blockchain::AddressHash, + blockchain::{AddressHash, Environment}, cursor::Cursor, storage::{StorageKey, StorageValue}, types::CallData, @@ -12,18 +12,16 @@ use crate::{ pub mod op_20; pub trait ContractTrait { - fn set_environment(&mut self, environment: &'static crate::blockchain::Environment); + fn context(&self) -> Rc; - fn environment(&self) -> &'static crate::blockchain::Environment; + fn environment(&mut self) -> &Environment; - fn context(&self) -> Rc>; - - fn is_self(&self, address: &AddressHash) -> bool { - address.eq(&self.environment().address) + fn is_self(&mut self, address: &AddressHash) -> bool { + address.eq(&self.environment().contract_address) } - fn only_deployer(&self, caller: &AddressHash) -> Result<(), crate::error::Error> { - if self.environment().deployer.ne(caller) { + fn only_deployer(&mut self, caller: &AddressHash) -> Result<(), crate::error::Error> { + if self.environment().contract_deployer.ne(caller) { Err(crate::error::Error::OnlyOwner) } else { Ok(()) @@ -31,69 +29,61 @@ pub trait ContractTrait { } fn on_deploy(&mut self, _call_data: CallData) { - self.context().borrow().log("On Deploy is not implemented"); + self.context().log("On Deploy is not implemented"); } fn execute(&mut self, _call_data: CallData) -> Result { - self.context().borrow().log("Execute is not implemented"); + self.context().log("Execute is not implemented"); unimplemented!("Execute needs to be implemented"); } fn log(&self, text: &str) { - self.context().borrow().log(text); + self.context().log(text); } fn emit(&self, event: &dyn crate::event::EventTrait) { - self.context().borrow_mut().emit(event); + self.context().emit(event); } fn call( &self, address: &crate::blockchain::AddressHash, data: crate::cursor::Cursor, ) -> Cursor { - self.context().borrow().call(address, data) + self.context().call(address, data) } fn load(&self, pointer: &StorageKey) -> Option { - self.context().borrow_mut().load(pointer) + self.context().load(pointer) } fn store(&self, pointer: StorageKey, value: StorageValue) { - self.context().borrow_mut().store(pointer, value) + self.context().store(pointer, value) } fn exists(&self, pointer: &StorageKey) -> bool { - self.context().borrow_mut().exists(pointer) - } - /* - fn next_pointer_greater_than(&self, pointer: StorageKey) -> StorageKey { - self.context() - .as_ref() - .borrow() - .next_pointer_greater_than(pointer) + self.context().exists(pointer) } - */ fn encode_address(&self, address: &str) -> &'static [u8] { - self.context().borrow().encode_address(address) + self.context().encode_address(address) } fn validate_bitcoin_address(&self, address: &str) -> bool { - self.context().borrow().validate_bitcoin_address(address) + self.context().validate_bitcoin_address(address) } fn verify_schnorr_signature(&self, data: &[u8]) -> bool { - self.context().borrow().verify_schnorr_signature(data) + self.context().verify_schnorr_signature(data) } fn sha256(&self, data: &[u8]) -> [u8; 32] { - self.context().borrow().sha256(data) + self.context().sha256(data) } fn sha256_double(&self, data: &[u8]) -> [u8; 32] { - self.context().borrow().sha256_double(data) + self.context().sha256_double(data) } fn ripemd160(&self, data: &[u8]) -> [u8; 20] { - self.context().borrow().ripemd160(data) + self.context().ripemd160(data) } fn inputs(&self) -> Vec { - self.context().borrow_mut().inputs() + self.context().inputs() } fn outputs(&self) -> Vec { - self.context().borrow_mut().outputs() + self.context().outputs() } } diff --git a/src/contract/op_20.rs b/src/contract/op_20.rs index e96d659..32c0265 100644 --- a/src/contract/op_20.rs +++ b/src/contract/op_20.rs @@ -59,7 +59,7 @@ pub trait OP20Trait: super::ContractTrait { match selector { SELECTOR_OWNER => { let mut cursor = Cursor::new(ADDRESS_BYTE_LENGTH); - cursor.write_address(&self.environment().deployer)?; + cursor.write_address(&self.environment().contract_deployer)?; Ok(cursor) } SELECTOR_DECIMALS => { @@ -171,7 +171,7 @@ pub trait OP20Trait: super::ContractTrait { &mut self, mut call_data: CallData, ) -> Result { - let owner = self.environment().sender; + let owner = self.environment().caller; let spender = call_data.read_address()?; let amount = call_data.read_u256_be()?; @@ -197,12 +197,14 @@ pub trait OP20Trait: super::ContractTrait { } fn burn_base(&mut self, value: u256, only_deployer: bool) -> Result { + let sender = self.environment().caller; + if value.eq(&u256::ZERO) { return Err(crate::error::Error::NoTokens); } if only_deployer { - self.only_deployer(&self.environment().sender)?; + self.only_deployer(&sender)?; } let total_supply = self.total_supply().value(); @@ -210,7 +212,6 @@ pub trait OP20Trait: super::ContractTrait { return Err(crate::error::Error::InsufficientTotalSupply); } - let sender = self.environment().sender; if !self.balance_of_map().contains_key(&sender) { return Err(crate::error::Error::NoBalance); } @@ -247,7 +248,8 @@ pub trait OP20Trait: super::ContractTrait { only_deployer: bool, ) -> Result { if only_deployer { - self.only_deployer(&self.environment().sender)?; + let sender = self.environment().caller.clone(); + self.only_deployer(&sender)?; } if !self.balance_of_map().contains_key(to) { @@ -275,7 +277,7 @@ pub trait OP20Trait: super::ContractTrait { to: &AddressHash, value: u256, ) -> Result { - let sender = self.environment().sender; + let sender = self.environment().caller; if self.is_self(&sender) { return Err(crate::error::Error::CanNotTransferFromSelfAccount); } @@ -369,7 +371,9 @@ pub trait OP20Trait: super::ContractTrait { return Err(crate::error::Error::DeadAddress); } - self.spend_allowance(from, &self.environment().sender, value)?; + let sender = self.environment().caller; + + self.spend_allowance(from, &sender, value)?; self.transfer_from_unsafe(from, to, value)?; Ok(true) } @@ -391,7 +395,7 @@ pub trait OP20Trait: super::ContractTrait { fn create_burn_event(&mut self, value: u256) -> Result<(), crate::error::Error> { let burn_event = crate::event::Event::burn(value)?; - self.context().borrow_mut().emit(&burn_event); + self.emit(&burn_event); Ok(()) } @@ -402,7 +406,7 @@ pub trait OP20Trait: super::ContractTrait { value: u256, ) -> Result<(), crate::error::Error> { let approve_event = crate::event::Event::approve(deployer, spender, value)?; - self.context().borrow_mut().emit(&approve_event); + self.emit(&approve_event); Ok(()) } @@ -412,7 +416,7 @@ pub trait OP20Trait: super::ContractTrait { amount: u256, ) -> Result<(), crate::error::Error> { let mint_event = crate::event::Event::mint(deployer, amount)?; - self.context().borrow_mut().emit(&mint_event); + self.emit(&mint_event); Ok(()) } @@ -423,7 +427,7 @@ pub trait OP20Trait: super::ContractTrait { amount: u256, ) -> Result<(), crate::error::Error> { let transfer_event = crate::event::Event::transfer(from, to, amount)?; - self.context().borrow_mut().emit(&transfer_event); + self.emit(&transfer_event); Ok(()) } } diff --git a/src/env/global.rs b/src/env/global.rs index ec905dd..355ae8a 100644 --- a/src/env/global.rs +++ b/src/env/global.rs @@ -1,8 +1,8 @@ -use alloc::vec::Vec; - use crate::{ - blockchain::{transaction::Input, AddressHash}, - cursor::Cursor, + blockchain::{ + environment, transaction::Input, AddressHash, BlockHash, Environment, TransactionHash, + }, + cursor::{self, Cursor}, storage::{ key::{self, StorageKey}, map::Map, @@ -10,18 +10,23 @@ use crate::{ }, WaPtr, }; +use alloc::vec::Vec; +use core::cell::RefCell; use ethnum::u256; #[link(wasm_import_module = "env")] extern "C" { pub fn revert(data: u32, length: u32); - #[link_name = "getCalldata"] + #[link_name = "calldata"] pub fn get_call_data(offset: u32, length: u32, result: WaPtr); - pub fn load(key: u32, result: u32); + #[link_name = "environment"] + pub fn get_environment(offset: u32, length: u32, result: WaPtr); + + pub fn load(key: WaPtr, result: WaPtr); - pub fn store(key: u32, value: u32); + pub fn store(key: WaPtr, value: WaPtr); #[link_name = "deployFromAddress"] pub fn deploy_from_address(origin_address: u32, salt: u32, result_address: u32) -> u32; @@ -48,40 +53,36 @@ extern "C" { #[link_name = "inputsSize"] pub fn inputs_size() -> u32; - pub fn inputs(buffer: u32); + pub fn inputs(buffer: WaPtr); #[link_name = "outputsSize"] pub fn outputs_size() -> u32; - pub fn outputs(buffer: u32); + pub fn outputs(buffer: WaPtr); } #[link(wasm_import_module = "debug")] extern "C" { - pub fn log(ptr: u32); + pub fn log(ptr: u32, len: u32); } //#[cfg(target_arch = "wasm32")] pub struct GlobalContext { - store: Map, - inputs: Option>, - outputs: Option>, + store: RefCell>, } //#[cfg(target_arch = "wasm32")] impl GlobalContext { pub const fn new() -> Self { Self { - store: Map::new(), - inputs: None, - outputs: None, + store: RefCell::new(Map::new()), } } } //#[cfg(target_arch = "wasm32")] impl super::Context for GlobalContext { - fn get_call_data(&self, size: usize) -> Cursor { + fn call_data(&self, size: usize) -> Cursor { let cursor = crate::cursor::Cursor::new(size); unsafe { get_call_data(0, size as u32, cursor.ptr()); @@ -89,19 +90,45 @@ impl super::Context for GlobalContext { cursor } + fn environment(&self) -> Environment { + unsafe { + let mut cursor = Cursor::new(crate::constant::ENVIRONMENT_SIZE); + get_environment(0, crate::constant::ENVIRONMENT_SIZE as u32, cursor.ptr()); + + Environment { + block_hash: BlockHash { + bytes: cursor + .read_bytes(crate::constant::BLOCK_HASH_LENGTH) + .unwrap() + .try_into() + .unwrap(), + }, + block_number: cursor.read_u64_le().unwrap(), + block_median_time: cursor.read_u64_le().unwrap(), + transaction_hash: TransactionHash { + bytes: cursor + .read_bytes(crate::constant::TRANSACTION_HASH_LENGTH) + .unwrap() + .try_into() + .unwrap(), + }, + contract_address: cursor.read_address().unwrap(), + contract_deployer: cursor.read_address().unwrap(), + caller: cursor.read_address().unwrap(), + origin: cursor.read_address().unwrap(), + } + } + } + fn log(&self, text: &str) { unsafe { - let bytes = text - .as_bytes() - .iter() - .chain(b"\0".iter()) - .cloned() - .collect::>(); - log(bytes.as_ptr() as u32); + let mut cursor = Cursor::new(text.as_bytes().len() + 3); + cursor.write_string_with_len(text).unwrap(); + log(cursor.ptr().0, cursor.write_pos() as u32); } } - fn emit(&mut self, event: &dyn crate::event::EventTrait) { + fn emit(&self, event: &dyn crate::event::EventTrait) { unsafe { emit(event.ptr(), event.buffer().len() as u32); } @@ -131,47 +158,53 @@ impl super::Context for GlobalContext { false } - fn load(&mut self, pointer: &StorageKey) -> Option { + fn load(&self, pointer: &StorageKey) -> Option { unsafe { - let mut value = StorageValue::from_bytes([0; 32]); - load(pointer.ptr().0, value.ptr().0); - - if value.eq(&StorageValue::ZERO) { - None + let value = StorageValue::from_bytes([0; 32]); + if let Some(value) = self.store.borrow().get(pointer) { + Some(value.clone()) } else { - self.store.insert(*pointer, value.clone()); - Some(value) + load(pointer.ptr(), value.ptr()); + + if value.eq(&StorageValue::ZERO) { + None + } else { + self.store.borrow_mut().insert(*pointer, value.clone()); + Some(value) + } } } } - fn exists(&mut self, pointer: &StorageKey) -> bool { - if self.store.contains_key(pointer) { + fn exists(&self, pointer: &StorageKey) -> bool { + if self.store.borrow().contains_key(pointer) { true } else { self.load(pointer).is_some() } } - fn store(&mut self, pointer: StorageKey, value: StorageValue) { + fn store(&self, pointer: StorageKey, value: StorageValue) { unsafe { - if if let Some(old) = self.store.get(&pointer) { + if if let Some(old) = self.store.borrow().get(&pointer) { value.ne(old) } else { false } { - self.store.insert(pointer, value); - store(pointer.ptr().0, value.ptr().0) + self.store.borrow_mut().insert(pointer, value); + store(pointer.ptr(), value.ptr()) } } } - fn inputs(&mut self) -> alloc::vec::Vec { - if let Some(inputs) = &self.inputs { - inputs.clone() - } else { - Vec::new() + fn inputs(&self) -> alloc::vec::Vec { + unsafe { + let size = inputs_size(); + let buffer = Cursor::new(size as usize); + inputs(buffer.ptr()); } + + alloc::vec::Vec::new() } /* @@ -184,12 +217,14 @@ impl super::Context for GlobalContext { } */ - fn outputs(&mut self) -> alloc::vec::Vec { - if let Some(outputs) = &self.outputs { - outputs.clone() - } else { - Vec::new() + fn outputs(&self) -> alloc::vec::Vec { + unsafe { + let size = outputs_size(); + let buffer = Cursor::new(size as usize); + outputs(buffer.ptr()); } + + alloc::vec::Vec::new() } /* diff --git a/src/env/mod.rs b/src/env/mod.rs index 5ea860d..d8e6f18 100644 --- a/src/env/mod.rs +++ b/src/env/mod.rs @@ -1,4 +1,5 @@ use crate::{ + blockchain::Environment, cursor::Cursor, storage::{StorageKey, StorageValue}, }; @@ -11,7 +12,7 @@ pub mod global; mod test; #[cfg(not(target_arch = "wasm32"))] -pub use test::{Network, TestContext, TestRouter}; +pub use test::{TestContext, TestRouter}; #[cfg(target_arch = "wasm32")] pub fn sha256(bytes: &[u8]) -> [u8; 32] { @@ -65,9 +66,10 @@ pub fn ripemd160(data: &[u8]) -> [u8; 20] { } pub trait Context { - fn get_call_data(&self, size: usize) -> Cursor; + fn call_data(&self, size: usize) -> Cursor; + fn environment(&self) -> Environment; fn log(&self, text: &str); - fn emit(&mut self, event: &dyn crate::event::EventTrait); + fn emit(&self, event: &dyn crate::event::EventTrait); fn call(&self, address: &crate::blockchain::AddressHash, data: Cursor) -> Cursor; fn deploy_from_address( @@ -76,9 +78,9 @@ pub trait Context { salt: [u8; 32], ) -> Result; - fn load(&mut self, pointer: &StorageKey) -> Option; - fn store(&mut self, pointer: StorageKey, value: StorageValue); - fn exists(&mut self, pointer: &StorageKey) -> bool; + fn load(&self, pointer: &StorageKey) -> Option; + fn store(&self, pointer: StorageKey, value: StorageValue); + fn exists(&self, pointer: &StorageKey) -> bool; fn encode_address(&self, address: &str) -> &'static [u8]; fn validate_bitcoin_address(&self, address: &str) -> bool; @@ -93,9 +95,9 @@ pub trait Context { ripemd160(data) } - fn inputs(&mut self) -> Vec; + fn inputs(&self) -> Vec; //fn iter_inputs(&mut self) -> impl Iterator; - fn outputs(&mut self) -> Vec; + fn outputs(&self) -> Vec; //fn iter_outputs(&mut self) -> impl Iterator; } diff --git a/src/env/test.rs b/src/env/test.rs index 6faedec..79f6cb3 100644 --- a/src/env/test.rs +++ b/src/env/test.rs @@ -2,21 +2,17 @@ use core::cell::RefCell; extern crate std; use alloc::vec::Vec; use alloc::{boxed::Box, rc::Rc}; +use bitcoin::{Address, Network}; +use core::str::FromStr; -use crate::contract; +use crate::blockchain::Environment; use crate::{ - blockchain::{address, AddressHash}, + blockchain::AddressHash, cursor::Cursor, storage::{map::Map, StorageKey, StorageValue}, ContractTrait, }; -#[derive(Clone)] -pub enum Network { - Mainnet, - Testnet, - Preview, -} pub struct TestRouter { contracts: Vec<(AddressHash, *mut dyn ContractTrait)>, } @@ -49,42 +45,41 @@ impl TestRouter { #[derive(Clone)] pub struct TestContext { pub network: Network, - pub events: alloc::vec::Vec, - pub global_store: Map, - pub cache_store: Map, + pub environment: Environment, + pub events: RefCell>, + pub global_store: RefCell>, + pub cache_store: RefCell>, pub inputs: Vec, pub outputs: Vec, pub router: Option>>, } -impl TestContext { - pub fn new( - network: Network, - global_store: Map, - inputs: alloc::vec::Vec, - outputs: alloc::vec::Vec, - router: Option>>, - ) -> Self { +impl Default for TestContext { + fn default() -> Self { Self { - network, - events: alloc::vec::Vec::new(), - global_store: global_store, - cache_store: Map::new(), - inputs, - outputs, - router, + network: bitcoin::Network::Bitcoin, + environment: Environment::default(), + events: RefCell::new(Vec::new()), + global_store: RefCell::new(Map::new()), + cache_store: RefCell::new(Map::new()), + inputs: Vec::new(), + outputs: Vec::new(), + router: None, } } } impl super::Context for TestContext { // Just mock, data are passed from different entry point - fn get_call_data(&self, size: usize) -> Cursor { + fn call_data(&self, size: usize) -> Cursor { Cursor::new(size) } - fn emit(&mut self, event: &dyn crate::event::EventTrait) { + fn environment(&self) -> Environment { + self.environment.clone() + } + fn emit(&self, event: &dyn crate::event::EventTrait) { let event = crate::event::Event::new(event.buffer()); - self.events.push(event); + self.events.borrow_mut().push(event); } fn log(&self, _text: &str) {} @@ -113,22 +108,33 @@ impl super::Context for TestContext { b"abc" } - fn validate_bitcoin_address(&self, _address: &str) -> bool { - true + fn validate_bitcoin_address(&self, address: &str) -> bool { + match Address::from_str(address) { + Ok(addr) => { + if addr.is_valid_for_network(self.network) { + true + } else { + false + } + } + Err(e) => false, + } } fn verify_schnorr_signature(&self, _data: &[u8]) -> bool { - true + let SECP: secp256k1::Secp256k1 = secp256k1::Secp256k1::new(); + + let xonly_public_key = secp256k1::XOnlyPublicKey::from_byte_array(&[0u8; 32]).unwrap(); + let signature = secp256k1::schnorr::Signature::from_byte_array([0u8; 64]); + let result = SECP.verify_schnorr(&signature, &[0u8; 32], &xonly_public_key); + result.is_ok() } - fn load( - &mut self, - pointer: &crate::storage::StorageKey, - ) -> Option { - if let Some(value) = self.cache_store.get(pointer) { + fn load(&self, pointer: &crate::storage::StorageKey) -> Option { + if let Some(value) = self.cache_store.borrow().get(pointer) { Some(*value) - } else if let Some(value) = self.global_store.get(pointer) { - self.cache_store.insert(*pointer, *value); + } else if let Some(value) = self.global_store.borrow().get(pointer) { + self.cache_store.borrow_mut().insert(*pointer, *value); Some(*value) } else { None @@ -136,29 +142,29 @@ impl super::Context for TestContext { .filter(|&value| !StorageValue::ZERO.eq(&value)) } - fn store(&mut self, pointer: crate::storage::StorageKey, value: crate::storage::StorageValue) { - if if let Some(old) = self.cache_store.get(&pointer) { + fn store(&self, pointer: crate::storage::StorageKey, value: crate::storage::StorageValue) { + if if let Some(old) = self.cache_store.borrow().get(&pointer) { value.ne(old) } else { true } { - self.cache_store.insert(pointer, value); - self.global_store.insert(pointer, value); + self.cache_store.borrow_mut().insert(pointer, value); + self.global_store.borrow_mut().insert(pointer, value); } } - fn exists(&mut self, pointer: &StorageKey) -> bool { - if self.cache_store.contains_key(pointer) { + fn exists(&self, pointer: &StorageKey) -> bool { + if self.cache_store.borrow().contains_key(pointer) { true - } else if let Some(value) = self.global_store.get(pointer) { - self.cache_store.insert(*pointer, *value); + } else if let Some(value) = self.global_store.borrow().get(pointer) { + self.cache_store.borrow_mut().insert(*pointer, *value); true } else { false } } - fn inputs(&mut self) -> Vec { + fn inputs(&self) -> Vec { self.inputs.clone() } @@ -168,7 +174,7 @@ impl super::Context for TestContext { } */ - fn outputs(&mut self) -> Vec { + fn outputs(&self) -> Vec { self.outputs.clone() } @@ -178,3 +184,114 @@ impl super::Context for TestContext { } */ } + +#[cfg(test)] +mod tests { + use crate::Context; + + use super::TestContext; + + #[test] + fn test_validate_mainnet_address() { + let context = TestContext::default(); + assert_eq!( + true, + context.validate_bitcoin_address("bc1qnghhhgvz5cn8n6x2fy06yzvkuermcm5ljn06gw") + ); + } + + #[test] + fn test_validate_testnet_address() { + let context = TestContext { + network: bitcoin::Network::Testnet, + ..Default::default() + }; + assert_eq!( + true, + context.validate_bitcoin_address("mym4vP87LdQp9YzRbggpS46fYiQFfR52Nq") + ); + } + + #[test] + fn test_validate_p2sh_mainnet_address() { + let context = TestContext { + network: bitcoin::Network::Bitcoin, + ..Default::default() + }; + assert_eq!( + true, + context.validate_bitcoin_address("3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy") + ); + } + + #[test] + fn test_invalid_address_format() { + let context = TestContext { + network: bitcoin::Network::Bitcoin, + ..Default::default() + }; + assert_eq!(false, context.validate_bitcoin_address("invalid_address")); + } + + #[test] + fn test_address_valid_but_wrong_network() { + let context = TestContext { + network: bitcoin::Network::Bitcoin, + ..Default::default() + }; + assert_eq!( + false, + context.validate_bitcoin_address("mym4vP87LdQp9YzRbggpS46fYiQFfR52Nq") + ); + } + + #[test] + fn test_valid_regtest_address() { + let context = TestContext { + network: bitcoin::Network::Regtest, + ..Default::default() + }; + assert_eq!( + true, + context.validate_bitcoin_address( + "bcrt1pe0slk2klsxckhf90hvu8g0688rxt9qts6thuxk3u4ymxeejw53gs0xjlhn" + ) + ); + } + + #[test] + fn test_valid_regtest_address_segwit() { + let context = TestContext { + network: bitcoin::Network::Regtest, + ..Default::default() + }; + assert_eq!( + true, + context.validate_bitcoin_address("bcrt1qfqsr3m7vjxheghcvw4ks0fryqxfq8qzjf8fxes") + ); + } + + #[test] + fn test_valid_regtest_address_legacy() { + let context = TestContext { + network: bitcoin::Network::Regtest, + ..Default::default() + }; + assert_eq!( + true, + context.validate_bitcoin_address("mn6KYibk94NhScakhgVPQdGE1bnscugRDG") + ); + } + + #[test] + fn test_valid_regtest_address_p2sh() { + let context = TestContext { + network: bitcoin::Network::Regtest, + ..Default::default() + }; + assert_eq!( + true, + context.validate_bitcoin_address("2MyLLEUGJSusHvPDNHTwYnG9FAJcrQ3VPZY") + ); + } +} diff --git a/src/event/mod.rs b/src/event/mod.rs index 6283b98..b2fcd8d 100644 --- a/src/event/mod.rs +++ b/src/event/mod.rs @@ -145,6 +145,6 @@ impl EventTrait for Event { } fn ptr(&self) -> u32 { - (self.buffer.as_ptr() as u32) + self.buffer.as_ptr() as u32 } } diff --git a/src/lib.rs b/src/lib.rs index 6fbdcc5..f59daf7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -26,7 +26,9 @@ use core::cell::RefCell; use alloc::rc::Rc; pub use env::*; pub use ethnum; -//pub use mem::WaBuffer; + +#[cfg(not(target_arch = "wasm32"))] +pub use bitcoin; pub use utils::*; pub use contract::{ @@ -36,6 +38,7 @@ pub use contract::{ pub static mut CONTRACT: Option>> = None; +#[repr(transparent)] pub struct WaPtr(u32); impl From<&u32> for WaPtr { @@ -64,21 +67,20 @@ fn panic(_panic: &core::panic::PanicInfo<'_>) -> ! { core::arch::wasm32::unreachable() } -//#[cfg(target_arch = "wasm32")] +#[cfg(target_arch = "wasm32")] #[allow(static_mut_refs)] #[export_name = "execute"] pub unsafe fn execute(length: u32) -> WaPtr { if let Some(contract) = &mut CONTRACT { let mut contract = contract.borrow_mut(); - let call_data = contract - .context() - .borrow_mut() - .get_call_data(length as usize); + contract.context().log("Log message"); + + let call_data = contract.context().call_data(length as usize); contract.execute(call_data).unwrap().ptr() } else { - panic!("Contract is not set") + return WaPtr(20); } } @@ -88,16 +90,3 @@ pub unsafe fn execute(length: u32) -> WaPtr { pub unsafe fn on_deploy(ptr: WaPtr) { // problematic input!!! } - -#[cfg(target_arch = "wasm32")] -#[export_name = "setEnvironment"] -#[allow(static_mut_refs)] -pub unsafe fn set_environment(ptr: u32) { - use blockchain::Environment; - - let environment = core::ptr::NonNull::new_unchecked(ptr as *mut Environment).as_mut(); - if let Some(contract) = &mut CONTRACT { - let mut contract = contract.borrow_mut(); - contract.set_environment(environment); - } -} diff --git a/src/storage/array_merger.rs b/src/storage/array_merger.rs index ee385a4..1c35ff9 100644 --- a/src/storage/array_merger.rs +++ b/src/storage/array_merger.rs @@ -9,7 +9,7 @@ use alloc::rc::Rc; #[derive(Clone)] pub struct ArrayMerger { - context: Rc>, + context: Rc, parent_key: Vec, pointer: u16, default_value: StorageValue, @@ -17,7 +17,7 @@ pub struct ArrayMerger { impl ArrayMerger { pub fn new( - context: Rc>, + context: Rc, parent_key: Vec, pointer: u16, default_value: StorageValue, @@ -31,20 +31,17 @@ impl ArrayMerger { } pub fn get<'a>(&mut self, key: &[u8]) -> StorageValue { let pointer = self.get_key_hash(key); - self.context - .borrow_mut() - .load(&pointer) - .unwrap_or(self.default_value) + self.context.load(&pointer).unwrap_or(self.default_value) } pub fn set<'a>(&mut self, key: &[u8], value: StorageValue) { let pointer = self.get_key_hash(key); - self.context.borrow_mut().store(pointer, value); + self.context.store(pointer, value); } pub fn contains_key<'a>(&self, key: &[u8]) -> bool { let key = self.get_key_hash(key); - self.context.borrow_mut().exists(&key) + self.context.exists(&key) } fn get_key_hash(&self, key: &[u8]) -> StorageKey { diff --git a/src/storage/mod.rs b/src/storage/mod.rs index 0363b56..645a913 100644 --- a/src/storage/mod.rs +++ b/src/storage/mod.rs @@ -1,4 +1,3 @@ - pub mod array_merger; pub mod key; pub mod map; @@ -10,53 +9,3 @@ pub mod value; pub use key::StorageKey; pub use value::StorageValue; - -/* -static GLOBAL_STORE: Lazy>> = - Lazy::new(|| Mutex::new(Map::new())); - -pub struct GlobalStore {} - -impl GlobalStore { - pub fn get(key: &StorageKey, default_value: StorageValue) -> StorageValue { - let mut store = GLOBAL_STORE.lock(); - if store.contains_key(key) { - *store.get(key).unwrap() - } else { - match crate::env::pointer_load(key) { - Ok(result) => { - if result == StorageValue::ZERO && default_value != StorageValue::ZERO { - store.insert(key.clone(), default_value); - default_value - } else { - store.insert(key.clone(), result); - result - } - } - Err(_) => default_value, - } - } - } - - pub fn set(key: StorageKey, value: StorageValue) { - assert!(crate::env::pointer_store(&key, &value).unwrap()); - let mut store = GLOBAL_STORE.lock(); - store.insert(key, value); - } - - pub fn has_key(key: &StorageKey) -> bool { - let mut store = GLOBAL_STORE.lock(); - if store.contains_key(key) { - true - } else { - match crate::env::pointer_load(key) { - Ok(result) => { - store.insert(key.clone(), result); - !result.zero() - } - Err(_) => false, - } - } - } -} - */ diff --git a/src/storage/multi_address_map.rs b/src/storage/multi_address_map.rs index d3627ee..b521556 100644 --- a/src/storage/multi_address_map.rs +++ b/src/storage/multi_address_map.rs @@ -6,18 +6,14 @@ use crate::{blockchain::AddressHash, Context}; use super::{array_merger::ArrayMerger, map::Map, StorageValue}; pub struct MultiAddressMemoryMap { - context: Rc>, + context: Rc, pointer: u16, default_value: StorageValue, pub map: Map, } impl MultiAddressMemoryMap { - pub const fn new( - context: Rc>, - pointer: u16, - default_value: StorageValue, - ) -> Self { + pub const fn new(context: Rc, pointer: u16, default_value: StorageValue) -> Self { Self { context, pointer, diff --git a/src/storage/stored.rs b/src/storage/stored.rs index aca3dbc..7a9b0fb 100644 --- a/src/storage/stored.rs +++ b/src/storage/stored.rs @@ -22,7 +22,7 @@ where StorageValue: Into, D: Into + Clone, { - context: Rc>, + context: Rc, pointer: StorageKey, default_value: D, value: Option, @@ -40,7 +40,6 @@ where } else { let value: T = self .context - .borrow_mut() .load(&self.pointer) .map(|value| value.into()) .unwrap_or(self.default_value.clone().into()); @@ -52,7 +51,7 @@ where fn set(&mut self, value: T) -> T { if Some(value) != self.value { - self.context.borrow_mut().store(self.pointer, value.into()); + self.context.store(self.pointer, value.into()); self.value = Some(value); value } else { @@ -63,7 +62,6 @@ where fn refresh(&mut self) -> T { let value: T = self .context - .borrow_mut() .load(&self.pointer) .map(|value| value.into()) .unwrap_or(self.default_value.clone().into()); @@ -78,7 +76,7 @@ where fn commit(&mut self) { if let Some(value) = self.value { - self.context.borrow_mut().store(self.pointer, value.into()); + self.context.store(self.pointer, value.into()); } } } @@ -89,11 +87,7 @@ where StorageValue: Into, D: Into + Clone, { - pub const fn new_const( - context: Rc>, - pointer: u16, - default_value: D, - ) -> Self { + pub const fn new_const(context: Rc, pointer: u16, default_value: D) -> Self { Self { context, pointer: crate::math::abi::encode_pointer_const(pointer), @@ -103,7 +97,7 @@ where } pub fn new( - context: Rc>, + context: Rc, pointer: u16, sub_pointer: &StorageKey, default_value: D, @@ -142,14 +136,8 @@ mod tests { use super::StoredTrait; - fn context() -> Rc> { - Rc::new(RefCell::new(TestContext::new( - crate::env::Network::Testnet, - Map::new(), - Vec::new(), - Vec::new(), - None, - ))) + fn context() -> Rc { + Rc::new(TestContext::default()) } #[test] diff --git a/src/storage/stored_map.rs b/src/storage/stored_map.rs index f762ad2..269a6ac 100644 --- a/src/storage/stored_map.rs +++ b/src/storage/stored_map.rs @@ -11,7 +11,7 @@ where K: Into, V: Into + Clone, { - context: Rc>, + context: Rc, default: V, pointer: u16, k: PhantomData, @@ -23,7 +23,7 @@ where K: Into + Copy, V: Into + From + Clone, { - pub const fn new(context: Rc>, pointer: u16, default: V) -> Self { + pub const fn new(context: Rc, pointer: u16, default: V) -> Self { Self { context, default, @@ -37,14 +37,13 @@ where let key: StorageKey = (*key).into(); let key_hash = encode_pointer(self.pointer, &key.bytes); let value = Into::::into(value); - self.context.borrow_mut().store(key_hash, value); + self.context.store(key_hash, value); } pub fn get(&self, key: &K) -> V { let key: StorageKey = (*key).into(); let key_hash = encode_pointer(self.pointer, &key.bytes); self.context - .borrow_mut() .load(&key_hash) .map(|value| V::from(value)) .unwrap_or(self.default.clone()) @@ -53,7 +52,7 @@ where pub fn contains_key(&self, key: &K) -> bool { let key: StorageKey = (*key).into(); let key_hash = encode_pointer(self.pointer, &key.bytes); - let has = self.context.borrow_mut().exists(&key_hash); + let has = self.context.exists(&key_hash); has } } diff --git a/src/tests/mod.rs b/src/tests/mod.rs index 270e733..0048d6d 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -12,62 +12,32 @@ pub fn random_bytes() -> [u8; 32] { result } -#[cfg(target_arch = "wasm32")] -pub fn random_bytes() -> [u8; 32] { - static mut value: u8 = 9; - let mut result = [0u8; 32]; - result.iter_mut().for_each(|b| unsafe { - value += 13; - *b = value; - }); - result -} - #[cfg(not(target_arch = "wasm32"))] pub fn random_u64() -> u64 { rand::random() } -#[cfg(target_arch = "wasm32")] -pub fn random_u64() -> u64 { - unsafe { - static mut value: u64 = 9; - value += 19; - value - } -} - +#[cfg(not(target_arch = "wasm32"))] pub fn random_address() -> AddressHash { AddressHash { bytes: random_bytes(), } } +#[cfg(not(target_arch = "wasm32"))] pub fn random_transaction() -> TransactionHash { TransactionHash { bytes: random_bytes(), } } +#[cfg(not(target_arch = "wasm32"))] pub fn random_block() -> BlockHash { BlockHash { bytes: random_bytes(), } } -pub fn random_environment() -> Environment { - Environment { - address: random_address(), - block_hash: random_block(), - deployer: random_address(), - sender: random_address(), - origin: random_address(), - transaction_hash: random_transaction(), - timestamp: 0, - safe_rnd: random_u64(), - } -} - pub fn execute( contract: &mut dyn crate::ContractTrait, selector: crate::types::Selector, From 12ad07533309e0694b703d598ab51fba1dbffc42 Mon Sep 17 00:00:00 2001 From: Miksa Date: Fri, 14 Mar 2025 15:47:57 +0100 Subject: [PATCH 22/23] WIP: adding tests --- example/src/contract.rs | 148 +++++++------ example/src/lib.rs | 3 - src/blockchain/address.rs | 56 ++--- src/blockchain/block.rs | 27 ++- src/blockchain/environment.rs | 7 +- src/blockchain/transaction.rs | 27 ++- src/constant.rs | 20 +- src/contract/mod.rs | 42 +++- src/contract/op_20.rs | 346 ++++++++++++++++++++++--------- src/cursor/mod.rs | 24 ++- src/cursor/reader.rs | 85 +++++--- src/cursor/writer.rs | 58 +++--- src/env/global.rs | 111 +++++----- src/env/mod.rs | 11 +- src/env/test.rs | 90 +++++--- src/error.rs | 8 + src/event/mod.rs | 28 +-- src/lib.rs | 41 +++- src/math/abi.rs | 2 +- src/storage/array_merger.rs | 57 ++++- src/storage/key.rs | 4 +- src/storage/multi_address_map.rs | 41 +++- src/storage/stored.rs | 11 +- src/storage/stored_map.rs | 22 ++ src/storage/stored_string.rs | 36 ++-- src/storage/value.rs | 32 +-- src/tests/mod.rs | 24 +-- src/utils.rs | 31 ++- 28 files changed, 910 insertions(+), 482 deletions(-) diff --git a/example/src/contract.rs b/example/src/contract.rs index fa5bdc8..ec10809 100644 --- a/example/src/contract.rs +++ b/example/src/contract.rs @@ -1,27 +1,30 @@ use alloc::rc::Rc; -use core::cell::RefCell; +use core::{cell::RefCell, ops::Add}; use rust_runtime::{ blockchain::{AddressHash, Environment}, contract::op_20::Pointer, ethnum::u256, math::abi::encode_selector_const, storage::{ + map::Map, multi_address_map::MultiAddressMemoryMap, stored::{StoredTrait, StoredU256, StoredU8}, - stored_map::StoredMap, + stored_map::{StoredAddresValueMap, StoredMap}, StorageValue, }, types::{CallData, Selector}, Context, ContractTrait, OP20Trait, }; -const SELECTOR_AIRDROP: Selector = encode_selector_const("airdrop"); -const SELECTOR_AIRDROP_WITH_AMOUNT: Selector = encode_selector_const("airdropWithAmount"); -const SELECTOR_MINT: Selector = encode_selector_const("mint"); +const SELECTOR_AIRDROP: Selector = encode_selector_const("airdrop(address)"); +const SELECTOR_AIRDROP_WITH_AMOUNT: Selector = + encode_selector_const("airdropWithAmount(address, address[]"); +const SELECTOR_MINT: Selector = encode_selector_const("mint(address,uint256)"); pub struct Contract { environment: Option, params: rust_runtime::contract::op_20::OP20Params, + nonce_map: StoredMap, balance_of_map: StoredMap, allowance_map: MultiAddressMemoryMap, total_supply: StoredU256, @@ -41,6 +44,7 @@ impl Contract { name: "MyToken", symbol: "TOKEN", }, + nonce_map: StoredMap::new(context.clone(), Pointer::NonceMap.u16(), u256::ZERO), balance_of_map: StoredMap::new( context.clone(), Pointer::BalanceOfMap.u16(), @@ -65,11 +69,20 @@ impl Contract { fn execute( &mut self, selector: Selector, - call_data: CallData, + mut call_data: CallData, ) -> Result { match selector { - SELECTOR_MINT => self.mint(call_data), - SELECTOR_AIRDROP => self.airdrop(call_data), + SELECTOR_MINT => { + let address = call_data.read_address()?; + let amount = call_data.read_u256(true)?; + + self.mint(address, amount) + } + SELECTOR_AIRDROP => { + let drops = call_data.read_address_value_map()?; + + self.airdrop(drops) + } SELECTOR_AIRDROP_WITH_AMOUNT => self.airdrop_with_amount(call_data), _ => OP20Trait::execute_base(self, selector, call_data), } @@ -77,26 +90,26 @@ impl Contract { fn mint( &mut self, - mut call_data: CallData, + address: AddressHash, + amount: u256, ) -> Result { - let sender = self.environment().caller; - self.only_deployer(&sender)?; + let caller = self.environment().caller; + self.only_deployer(&caller)?; - let mut cursor = rust_runtime::cursor::Cursor::new(1); - let address = call_data.read_address()?; - let amount = call_data.read_u256_be()?; - cursor.write_bool(self.mint_base(&address, amount, false)?)?; + let mut result = rust_runtime::cursor::Cursor::new(1); + + result.write_bool(self.mint_base(&address, amount, false)?)?; - return Ok(cursor); + return Ok(result); } fn airdrop( &mut self, - mut call_data: CallData, + drops: Map, ) -> Result { let sender = self.environment().caller; self.only_deployer(&sender)?; - let drops = call_data.read_address_value_map()?; + for (address, amount) in drops.iter() { self.mint_base(address, amount.clone(), false)?; } @@ -127,8 +140,8 @@ impl Contract { ) -> Result { let sender = self.environment().caller; self.only_deployer(&sender)?; - let amount = call_data.read_u256_be()?; - let amount_of_addresses: u32 = call_data.read_u32_le()?; + let amount = call_data.read_u256(true)?; + let amount_of_addresses: u32 = call_data.read_u32(true)?; for _ in 0..amount_of_addresses { let address = call_data.read_address()?; @@ -159,6 +172,10 @@ impl rust_runtime::contract::op_20::OP20Trait for Contract { fn balance_of_map(&mut self) -> &mut StoredMap { &mut self.balance_of_map } + + fn nonce_map(&mut self) -> &mut StoredMap { + &mut self.nonce_map + } } impl rust_runtime::contract::ContractTrait for Contract { @@ -193,10 +210,14 @@ mod tests { use crate::contract::SELECTOR_MINT; use alloc::rc::Rc; use rust_runtime::{ - contract::op_20::{SELECTOR_BALANCE_OF, SELECTOR_NAME, SELECTOR_TOTAL_SUPPLY}, + contract::op_20::{ + SELECTOR_BALANCE_OF, SELECTOR_NAME, SELECTOR_SYMBOL, SELECTOR_TOTAL_SUPPLY, + }, cursor::Cursor, ethnum::u256, + global::call, tests::{execute, execute_address, execute_address_amount}, + OP20Trait, }; fn context() -> Rc { @@ -207,51 +228,58 @@ mod tests { fn test_contract_name() { let context = context(); let mut contract = super::Contract::new(context); - let mut cursor = execute(&mut contract, SELECTOR_NAME); - assert_eq!(contract.params.name, cursor.read_string_with_len().unwrap()); + let mut result = contract.execute(SELECTOR_NAME, Cursor::new(0)).unwrap(); + assert_eq!(contract.params.name, result.read_string_with_len().unwrap()); + } + + #[test] + fn test_contract_symbol() { + let context = context(); + let mut contract = super::Contract::new(context); + let mut result = contract.execute(SELECTOR_SYMBOL, Cursor::new(0)).unwrap(); + assert_eq!( + contract.params.symbol, + result.read_string_with_len().unwrap() + ); } #[test] fn test_contract_mint() { let router = Rc::new(RefCell::new(rust_runtime::env::TestRouter::new())); - let context = rust_runtime::env::TestContext::default(); + let contract_address = rust_runtime::tests::random_address(); let address = rust_runtime::tests::random_address(); + let amount = u256::new(10000000); let environment = rust_runtime::blockchain::Environment { contract_deployer: address.clone(), + contract_address, caller: address.clone(), ..Default::default() }; + let context = rust_runtime::env::TestContext { + environment, + ..Default::default() + }; - let mut contract = alloc::boxed::Box::new(super::Contract::new(Rc::new(context.clone()))); - - contract.environment = Some(environment.clone()); - router.borrow_mut().push(address.clone(), contract); - - let amount = u256::new(10000000); - - let mut cursor = Cursor::new(4 + 32); - cursor.write_selector(&SELECTOR_BALANCE_OF).unwrap(); - cursor.write_address(&address).unwrap(); - let mut cursor = router.borrow().call(address.clone(), cursor); - assert_eq!(cursor.read_u256_be().unwrap(), 0); + router.borrow_mut().push( + contract_address, + alloc::boxed::Box::new(super::Contract::new(Rc::new(context.clone()))), + ); - for i in 0..3 { - let mut cursor = rust_runtime::cursor::Cursor::new(4 + 32 + 32); - cursor.write_selector(&SELECTOR_MINT).unwrap(); - cursor.write_address(&address).unwrap(); - cursor.write_u256_be(&amount).unwrap(); + let mut call_data = Cursor::new(68); + call_data.write_selector(&SELECTOR_MINT).unwrap(); + call_data.write_address(&address).unwrap(); + call_data.write_u256(&amount, true).unwrap(); - let mut cursor = router.borrow().call(address.clone(), cursor); - assert_eq!(cursor.read_bool().unwrap(), true); + let mut result = router.borrow().call(contract_address, call_data); + assert_eq!(result.read_bool().unwrap(), true); - let mut cursor = Cursor::new(36); - cursor.write_selector(&SELECTOR_BALANCE_OF).unwrap(); - cursor.write_address(&address).unwrap(); - let mut cursor = router.borrow().call(address.clone(), cursor); + let mut call_data = Cursor::new(36); + call_data.write_selector(&SELECTOR_BALANCE_OF).unwrap(); + call_data.write_address(&address).unwrap(); - assert_eq!(cursor.read_u256_be().unwrap(), (i + 1) * amount); - } + let mut result = router.borrow_mut().call(contract_address, call_data); + assert_eq!(result.read_u256(true).unwrap(), amount); } #[test] @@ -268,19 +296,17 @@ mod tests { }); let amount = u256::new(10000000); - let mut cursor = execute(&mut contract, SELECTOR_TOTAL_SUPPLY); - assert_eq!(cursor.read_u256_be().unwrap(), 0); - - for _ in 0..3 { - execute_address_amount(&mut contract, SELECTOR_MINT, &address, amount); - } - - let mut cursor = execute(&mut contract, SELECTOR_TOTAL_SUPPLY); - assert_eq!(cursor.read_u256_be().unwrap(), 3 * amount); + let mut result = contract + .execute(SELECTOR_TOTAL_SUPPLY, Cursor::new(0)) + .unwrap(); + assert_eq!(result.read_u256(true).unwrap(), 0); - execute_address_amount(&mut contract, SELECTOR_MINT, &address, amount); // mint more + let mut result = contract.mint(address.clone(), amount).unwrap(); + assert_eq!(result.read_bool().unwrap(), true); - let mut cursor = execute(&mut contract, SELECTOR_TOTAL_SUPPLY); - assert_eq!(cursor.read_u256_be().unwrap(), 4 * amount); + let mut result = contract + .execute(SELECTOR_TOTAL_SUPPLY, Cursor::new(0)) + .unwrap(); + assert_eq!(result.read_u256(true).unwrap(), amount); } } diff --git a/example/src/lib.rs b/example/src/lib.rs index 2234dc9..cc78906 100644 --- a/example/src/lib.rs +++ b/example/src/lib.rs @@ -20,13 +20,10 @@ static ALLOCATOR: LeakingPageAllocator = LeakingPageAllocator; #[cfg(target_arch = "wasm32")] #[export_name = "start"] pub unsafe fn start() { - return; - use rust_runtime::env::global::GlobalContext; use rust_runtime::Context; let context = Rc::new(GlobalContext::new()); - context.log("Hello world"); rust_runtime::CONTRACT = Some(Rc::new(RefCell::new(crate::contract::Contract::new( context, )))); diff --git a/src/blockchain/address.rs b/src/blockchain/address.rs index 371477b..908d978 100644 --- a/src/blockchain/address.rs +++ b/src/blockchain/address.rs @@ -1,43 +1,47 @@ -use crate::{storage::StorageKey, WaPtr}; +use crate::{storage::StorageKey, AsBytes, FromBytes, ToHex, WaPtr}; #[derive(Clone, Copy, Eq, PartialEq, Debug)] -pub struct AddressHash { - pub bytes: [u8; crate::constant::ADDRESS_BYTE_LENGTH], +#[repr(transparent)] +pub struct AddressHash(pub [u8; crate::constant::ADDRESS_BYTE_LENGTH]); + +impl AsBytes for AddressHash { + fn as_bytes(&self) -> &[u8] { + &self.0 + } } -impl From for StorageKey { - fn from(val: AddressHash) -> Self { - StorageKey::new(val.bytes) +impl AsBytes for &AddressHash { + fn as_bytes(&self) -> &[u8] { + &self.0 } } -impl crate::utils::ToHex for AddressHash { - fn get_bytes(&self) -> &[u8] { - self.bytes.as_ref() +impl FromBytes for AddressHash { + fn from_bytes(bytes: &[u8]) -> Self { + Self(bytes.try_into().unwrap()) } } -impl AddressHash { - pub const DEAD: AddressHash = AddressHash { - bytes: [ - 40, 74, 228, 172, 219, 50, 169, 155, 163, 235, 250, 102, 169, 29, 219, 65, 167, 183, - 161, 210, 254, 244, 21, 57, 153, 34, 205, 138, 4, 72, 92, 2, - ], - }; - pub const EMPTY: AddressHash = AddressHash { - bytes: [0; crate::constant::ADDRESS_BYTE_LENGTH], - }; - pub const fn new_from_bytes(bytes: [u8; crate::constant::ADDRESS_BYTE_LENGTH]) -> Self { - Self { bytes } +impl ToHex for AddressHash {} +impl ToHex for &AddressHash {} + +impl From for StorageKey { + fn from(val: AddressHash) -> Self { + StorageKey::new(val.0) } +} - pub fn new(bytes: &[u8]) -> Self { - Self { - bytes: bytes.try_into().unwrap(), - } +impl AddressHash { + pub const DEAD: AddressHash = AddressHash([ + 40, 74, 228, 172, 219, 50, 169, 155, 163, 235, 250, 102, 169, 29, 219, 65, 167, 183, 161, + 210, 254, 244, 21, 57, 153, 34, 205, 138, 4, 72, 92, 2, + ]); + pub const EMPTY: AddressHash = AddressHash([0; crate::constant::ADDRESS_BYTE_LENGTH]); + pub const fn new(bytes: [u8; crate::constant::ADDRESS_BYTE_LENGTH]) -> Self { + Self(bytes) } pub fn ptr(&self) -> WaPtr { - WaPtr::from(&self.bytes) + WaPtr::from(&self.0) } } diff --git a/src/blockchain/block.rs b/src/blockchain/block.rs index f2ad663..227c63c 100644 --- a/src/blockchain/block.rs +++ b/src/blockchain/block.rs @@ -1,15 +1,22 @@ -#[derive(Clone)] -pub struct BlockHash { - pub bytes: [u8; crate::constant::BLOCK_HASH_LENGTH], -} +use crate::{AsBytes, FromBytes, ToHex}; + +#[derive(Clone, Copy)] +#[repr(transparent)] +pub struct BlockHash([u8; crate::constant::BLOCK_HASH_BYTE_LENGTH]); impl BlockHash { - pub const EMPTY: BlockHash = BlockHash { - bytes: [0; crate::constant::BLOCK_HASH_LENGTH], - }; + pub const EMPTY: BlockHash = BlockHash([0; crate::constant::BLOCK_HASH_BYTE_LENGTH]); +} + +impl AsBytes for BlockHash { + fn as_bytes(&self) -> &[u8] { + &self.0 + } } -impl crate::utils::ToHex for BlockHash { - fn get_bytes(&self) -> &[u8] { - self.bytes.as_ref() +impl FromBytes for BlockHash { + fn from_bytes(bytes: &[u8]) -> Self { + Self(bytes.try_into().unwrap()) } } + +impl ToHex for BlockHash {} diff --git a/src/blockchain/environment.rs b/src/blockchain/environment.rs index 0294de8..8c4e4ac 100644 --- a/src/blockchain/environment.rs +++ b/src/blockchain/environment.rs @@ -1,8 +1,9 @@ use crate::WaPtr; use super::AddressHash; +use crate::{AsBytes, ToHex}; -#[derive(Clone)] +#[derive(Clone, Copy)] pub struct Environment { pub block_hash: super::BlockHash, pub block_number: u64, @@ -24,13 +25,11 @@ impl Environment { #[allow(dead_code)] #[cfg(not(target_arch = "wasm32"))] mod display { - use crate::utils::{to_hex, ToHex}; + use crate::utils::ToHex; use core::fmt::Display; impl Display for super::Environment { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - use alloc::string::ToString; - f.debug_struct("Environment") .field("block_hash", &self.block_hash.to_hex()) .field("block_number", &self.block_number) diff --git a/src/blockchain/transaction.rs b/src/blockchain/transaction.rs index 7624d11..7b4f480 100644 --- a/src/blockchain/transaction.rs +++ b/src/blockchain/transaction.rs @@ -1,17 +1,24 @@ -#[derive(Clone, Debug)] -pub struct TransactionHash { - pub bytes: [u8; crate::constant::TRANSACTION_HASH_LENGTH], -} +use crate::{AsBytes, FromBytes, ToHex}; + +#[derive(Clone, Copy, Debug)] +#[repr(transparent)] +pub struct TransactionHash([u8; crate::constant::TRANSACTION_HASH_BYTE_LENGTH]); impl TransactionHash { - pub const EMPTY: TransactionHash = TransactionHash { - bytes: [0; crate::constant::TRANSACTION_HASH_LENGTH], - }; + pub const EMPTY: TransactionHash = + TransactionHash([0; crate::constant::TRANSACTION_HASH_BYTE_LENGTH]); } -impl crate::utils::ToHex for TransactionHash { - fn get_bytes(&self) -> &[u8] { - self.bytes.as_ref() +impl AsBytes for TransactionHash { + fn as_bytes(&self) -> &[u8] { + &self.0 + } +} + +impl FromBytes for TransactionHash { + fn from_bytes(bytes: &[u8]) -> Self { + Self(bytes.try_into().unwrap()) } } +impl ToHex for TransactionHash {} #[derive(Clone, Debug)] pub struct Transaction { diff --git a/src/constant.rs b/src/constant.rs index dec6e0d..9ab33c2 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -1,8 +1,12 @@ -pub const HASH_SIZE: usize = 32; -pub const ADDRESS_BYTE_LENGTH: usize = HASH_SIZE; -pub const TRANSACTION_HASH_LENGTH: usize = HASH_SIZE; -pub const BLOCK_HASH_LENGTH: usize = HASH_SIZE; -pub const STORE_KEY_SIZE: usize = HASH_SIZE; -pub const STORE_VALUE_SIZE: usize = HASH_SIZE; - -pub const ENVIRONMENT_SIZE: usize = 208; +pub const HASH_BYTE_LENGTH: usize = 32; +pub const U256_BYTE_LENGTH: usize = 32; +pub const U64_BYTE_LENGTH: usize = 8; +pub const BOOLEAN_BYTE_LENGTH: usize = 1; +pub const ADDRESS_BYTE_LENGTH: usize = HASH_BYTE_LENGTH; +pub const TRANSACTION_HASH_BYTE_LENGTH: usize = HASH_BYTE_LENGTH; +pub const BLOCK_HASH_BYTE_LENGTH: usize = HASH_BYTE_LENGTH; +pub const STORE_KEY_BYTE_LENGTH: usize = HASH_BYTE_LENGTH; +pub const STORE_VALUE_BYTE_LENGTH: usize = U256_BYTE_LENGTH; +pub const ENVIRONMENT_BYTE_LENGTH: usize = 208; +pub const SCHNORR_SIGNATURE_BYTE_LENGTH: usize = 64; +pub const SCHNORR_MESSAGE_BYTE_LENGTH: usize = 32; diff --git a/src/contract/mod.rs b/src/contract/mod.rs index d5c46d3..3f3edcf 100644 --- a/src/contract/mod.rs +++ b/src/contract/mod.rs @@ -1,6 +1,6 @@ use alloc::rc::Rc; use alloc::vec::Vec; -use core::cell::RefCell; +use core::{cell::RefCell, ptr::hash}; use crate::{ blockchain::{AddressHash, Environment}, @@ -16,10 +16,12 @@ pub trait ContractTrait { fn environment(&mut self) -> &Environment; + #[inline] fn is_self(&mut self, address: &AddressHash) -> bool { address.eq(&self.environment().contract_address) } + #[inline] fn only_deployer(&mut self, caller: &AddressHash) -> Result<(), crate::error::Error> { if self.environment().contract_deployer.ne(caller) { Err(crate::error::Error::OnlyOwner) @@ -28,21 +30,28 @@ pub trait ContractTrait { } } + #[inline] fn on_deploy(&mut self, _call_data: CallData) { self.context().log("On Deploy is not implemented"); } + #[inline] fn execute(&mut self, _call_data: CallData) -> Result { self.context().log("Execute is not implemented"); unimplemented!("Execute needs to be implemented"); } + #[inline] fn log(&self, text: &str) { self.context().log(text); } + + #[inline] fn emit(&self, event: &dyn crate::event::EventTrait) { self.context().emit(event); } + + #[inline] fn call( &self, address: &crate::blockchain::AddressHash, @@ -51,38 +60,63 @@ pub trait ContractTrait { self.context().call(address, data) } + #[inline] fn load(&self, pointer: &StorageKey) -> Option { self.context().load(pointer) } + + #[inline] fn store(&self, pointer: StorageKey, value: StorageValue) { self.context().store(pointer, value) } + + #[inline] fn exists(&self, pointer: &StorageKey) -> bool { self.context().exists(pointer) } + #[inline] fn encode_address(&self, address: &str) -> &'static [u8] { self.context().encode_address(address) } - fn validate_bitcoin_address(&self, address: &str) -> bool { + + #[inline] + fn validate_bitcoin_address(&self, address: &str) -> Result { self.context().validate_bitcoin_address(address) } - fn verify_schnorr_signature(&self, data: &[u8]) -> bool { - self.context().verify_schnorr_signature(data) + + #[inline] + fn verify_schnorr_signature( + &self, + address: &AddressHash, + signature: &[u8], + message: &[u8], + ) -> Result { + self.context() + .verify_schnorr_signature(address, signature, message) } + + #[inline] fn sha256(&self, data: &[u8]) -> [u8; 32] { self.context().sha256(data) } + + #[inline] fn sha256_double(&self, data: &[u8]) -> [u8; 32] { self.context().sha256_double(data) } + + #[inline] fn ripemd160(&self, data: &[u8]) -> [u8; 20] { self.context().ripemd160(data) } + #[inline] fn inputs(&self) -> Vec { self.context().inputs() } + + #[inline] fn outputs(&self) -> Vec { self.context().outputs() } diff --git a/src/contract/op_20.rs b/src/contract/op_20.rs index 32c0265..f6cd751 100644 --- a/src/contract/op_20.rs +++ b/src/contract/op_20.rs @@ -1,9 +1,13 @@ +use core::ops::Add; + +use alloc::format; use ethnum::u256; use crate::{ blockchain::AddressHash, - constant::ADDRESS_BYTE_LENGTH, - cursor::Cursor, + constant::{ADDRESS_BYTE_LENGTH, BOOLEAN_BYTE_LENGTH, U256_BYTE_LENGTH}, + cursor::{self, Cursor}, + error::Error, math::abi::encode_selector_const, storage::{ multi_address_map::MultiAddressMemoryMap, @@ -11,6 +15,7 @@ use crate::{ stored_map::StoredMap, }, types::{CallData, Selector}, + AsBytes, ToHex, }; pub struct OP20Params { @@ -22,10 +27,10 @@ pub struct OP20Params { #[repr(u16)] pub enum Pointer { - MaxSupply = 1, + NonceMap = 1, + MaxSupply, Decimals, - Name, - Symbol, + String, TotalSupply, AllowanceMap, BalanceOfMap, @@ -38,25 +43,35 @@ impl Pointer { } pub const SELECTOR_OWNER: Selector = encode_selector_const("owner"); +pub const SELECTOR_DEPLOYER: Selector = encode_selector_const("deployer"); pub const SELECTOR_DECIMALS: Selector = encode_selector_const("decimals"); pub const SELECTOR_NAME: Selector = encode_selector_const("name"); pub const SELECTOR_SYMBOL: Selector = encode_selector_const("symbol"); pub const SELECTOR_TOTAL_SUPPLY: Selector = encode_selector_const("totalSupply"); pub const SELECTOR_MAXIMUM_SUPPLY: Selector = encode_selector_const("maximumSupply"); pub const SELECTOR_ALLOWANCE: Selector = encode_selector_const("allowance"); -pub const SELECTOR_APPROVE: Selector = encode_selector_const("approve"); -pub const SELECTOR_BALANCE_OF: Selector = encode_selector_const("balanceOf"); -pub const SELECTOR_BURN: Selector = encode_selector_const("burn"); -pub const SELECTOR_TRANSFER: Selector = encode_selector_const("transfer"); -pub const SELECTOR_TRANSFER_FROM: Selector = encode_selector_const("transferFrom"); +pub const SELECTOR_APPROVE: Selector = encode_selector_const("approve(address,uint256)"); +pub const SELECTOR_APPROVE_FROM: Selector = + encode_selector_const("approveFrom(address,uint256,uint256,bytes)"); +pub const SELECTOR_BALANCE_OF: Selector = encode_selector_const("balanceOf(address)"); +pub const SELECTOR_BURN: Selector = encode_selector_const("burn(uint256)"); +pub const SELECTOR_TRANSFER: Selector = encode_selector_const("transfer(address,uint256)"); +pub const SELECTOR_TRANSFER_FROM: Selector = + encode_selector_const("transferFrom(address,address,uint256)"); +pub const SELECTOR_NONCE_OF: Selector = encode_selector_const("nonceOf(address)"); pub trait OP20Trait: super::ContractTrait { fn execute_base( &mut self, selector: Selector, - call_data: CallData, + mut call_data: CallData, ) -> Result { match selector { + SELECTOR_DEPLOYER => { + let mut cursor = Cursor::new(ADDRESS_BYTE_LENGTH); + cursor.write_address(&self.environment().contract_deployer)?; + Ok(cursor) + } SELECTOR_OWNER => { let mut cursor = Cursor::new(ADDRESS_BYTE_LENGTH); cursor.write_address(&self.environment().contract_deployer)?; @@ -82,20 +97,66 @@ pub trait OP20Trait: super::ContractTrait { } SELECTOR_TOTAL_SUPPLY => { let mut cursor = Cursor::new(32); - cursor.write_u256_be(&self.total_supply().value())?; + cursor.write_u256(&self.total_supply().value(), true)?; Ok(cursor) } SELECTOR_MAXIMUM_SUPPLY => { let mut cursor = Cursor::new(32); - cursor.write_u256_be(&self.max_supply())?; + cursor.write_u256(&self.max_supply(), true)?; Ok(cursor) } - SELECTOR_ALLOWANCE => self.allowance(call_data), - SELECTOR_APPROVE => self.approve(call_data), - SELECTOR_BALANCE_OF => self.balance_of(call_data), - SELECTOR_BURN => self.burn(call_data), - SELECTOR_TRANSFER => self.transfer(call_data), - SELECTOR_TRANSFER_FROM => self.transfer_from(call_data), + SELECTOR_ALLOWANCE => { + let address_owner = call_data.read_address()?; + let address_spender = call_data.read_address()?; + + self.allowance(&address_owner, &address_spender) + } + SELECTOR_APPROVE => { + let owner = self.environment().caller; + let spender = call_data.read_address()?; + let value = call_data.read_u256(true)?; + + self.approve(owner, spender, value) + } + SELECTOR_APPROVE_FROM => { + let owner = self.environment().origin; + let spender = call_data.read_address()?; + let value = call_data.read_u256(true)?; + let nonce = call_data.read_u256(true)?; + let signature = call_data.read_bytes_with_length(true)?; + + self.approve_from(owner, spender, value, nonce, signature) + } + SELECTOR_NONCE_OF => { + let owner = call_data.read_address()?; + self.nonce_of(owner) + } + SELECTOR_BALANCE_OF => { + let address = call_data.read_address()?; + + self.balance_of(address) + } + + SELECTOR_BURN => { + let amount = call_data.read_u256(true)?; + + self.burn(amount) + } + + SELECTOR_TRANSFER => { + let address = call_data.read_address()?; + let amount = call_data.read_u256(true)?; + self.transfer(address, amount) + } + + SELECTOR_TRANSFER_FROM => { + let address_from = call_data.read_address()?; + let address_to = call_data.read_address()?; + let amount = call_data.read_u256(true)?; + + self.transfer_from(address_from, address_to, amount) + } + _ => Err(crate::error::Error::UnknownSelector), } } @@ -126,30 +187,73 @@ pub trait OP20Trait: super::ContractTrait { fn allowance_map(&mut self) -> &mut MultiAddressMemoryMap; fn balance_of_map(&mut self) -> &mut StoredMap; + fn nonce_map(&mut self) -> &mut StoredMap; + #[inline] fn allowance_base(&mut self, owner: &AddressHash, spender: &AddressHash) -> u256 { let mut sender_map = self.allowance_map().get(owner); - sender_map.get(&spender.bytes).u256() + sender_map.get(&spender).u256() } + #[inline] fn allowance( &mut self, - mut call_data: CallData, + owner: &AddressHash, + spender: &AddressHash, ) -> Result { let mut cursor = Cursor::new(32); - let address_owner = call_data.read_address()?; - let address_spender = call_data.read_address()?; - let allowance = self.allowance_base(&address_owner, &address_spender); - - cursor.write_u256_be(&allowance)?; + let allowance = self.allowance_base(&owner, &spender); + cursor.write_u256(&allowance, true)?; Ok(cursor) } + #[inline] fn approve_base( + &mut self, + owner: AddressHash, + spender: AddressHash, + amount: u256, + ) -> Result { + if AddressHash::DEAD.eq(&owner) { + return Err(crate::error::Error::Revert( + "Address con not be dead address", + )); + } + + if AddressHash::DEAD.eq(&spender) { + return Err(crate::error::Error::Revert( + "Address con not be dead address", + )); + } + + self.allowance_map() + .get(&owner) + .set(&spender, amount.into()); + + self.create_approve_event(owner, spender, amount)?; + Ok(true) + } + + #[inline] + fn approve( + &mut self, + owner: AddressHash, + spender: AddressHash, + amount: u256, + ) -> Result { + let mut cursor = Cursor::new(BOOLEAN_BYTE_LENGTH); + cursor.write_bool(self.approve_base(owner, spender, amount)?)?; + Ok(cursor) + } + + #[inline] + fn approve_from_base( &mut self, owner: &AddressHash, spender: &AddressHash, - value: u256, + value: &u256, + nonce: &u256, + signature: &[u8], ) -> Result { if AddressHash::DEAD.eq(owner) { return Err(crate::error::Error::DeadAddress); @@ -159,70 +263,115 @@ pub trait OP20Trait: super::ContractTrait { return Err(crate::error::Error::DeadAddress); } + let stored_nonce = self.nonce_map().get(owner); + if stored_nonce.eq(nonce) { + return Err(crate::error::Error::Revert( + "Invalid nonce (possible replay or out-of-sync)", + )); + } + + let mut data = Cursor::new(ADDRESS_BYTE_LENGTH * 2 + 2 * U256_BYTE_LENGTH); + data.write_address(owner)?; + data.write_address(spender)?; + data.write_u256(&value, true)?; + data.write_u256(&nonce, true)?; + + let hash = self.context().sha256(data.into_inner()); + if !self + .context() + .verify_schnorr_signature(owner, signature, &hash)? + { + return Err(crate::error::Error::Revert( + "ApproveFrom: Invalid signature", + )); + } + let mut sender_map = self.allowance_map().get(owner); - sender_map.set(&spender.bytes, value.into()); + sender_map.set(&spender, (*value).into()); - self.create_approve_event(*owner, *spender, value)?; + self.create_approve_event(*owner, *spender, *value)?; Ok(true) } - fn approve( + #[inline] + fn approve_from( &mut self, - mut call_data: CallData, - ) -> Result { - let owner = self.environment().caller; - let spender = call_data.read_address()?; - let amount = call_data.read_u256_be()?; + owner: AddressHash, + spender: AddressHash, + value: u256, + nonce: u256, + signature: &[u8], + ) -> Result { + if owner == spender { + return Err(Error::Revert( + "Direct owner approval detected. Use approve function instead of approveFrom.", + )); + } - let mut cursor = Cursor::new(32); - cursor.write_bool(self.approve_base(&owner, &spender, amount)?)?; + if signature.len() != 64 { + return Err(Error::Revert("Invalid signature length")); + } - Ok(cursor) + let mut response = Cursor::new(BOOLEAN_BYTE_LENGTH); + response + .write_bool(self.approve_from_base(&owner, &spender, &value, &nonce, signature)?)?; + Ok(response) } + #[inline] + fn nonce_of(&mut self, owner: AddressHash) -> Result { + let nonce = self.nonce_map().get(&owner); + let mut response = Cursor::new(U256_BYTE_LENGTH); + response.write_u256(&nonce, true)?; + Ok(response) + } + + #[inline] fn balance_of_base(&mut self, address: &AddressHash) -> u256 { self.balance_of_map().get(address) } + #[inline] fn balance_of( &mut self, - mut call_data: crate::types::CallData, + address: AddressHash, ) -> Result { - let mut cursor = Cursor::new(32); - let address = call_data.read_address()?; + let mut result = Cursor::new(U256_BYTE_LENGTH); + let balance = self.balance_of_base(&address); - cursor.write_u256_be(&balance)?; - Ok(cursor) + + result.write_u256(&balance, true)?; + Ok(result) } + #[inline] fn burn_base(&mut self, value: u256, only_deployer: bool) -> Result { - let sender = self.environment().caller; - if value.eq(&u256::ZERO) { return Err(crate::error::Error::NoTokens); } + let caller = self.environment().caller; if only_deployer { - self.only_deployer(&sender)?; + self.only_deployer(&caller)?; } let total_supply = self.total_supply().value(); if total_supply < value { - return Err(crate::error::Error::InsufficientTotalSupply); + return Err(Error::Revert("Insufficient total supply.")); } - if !self.balance_of_map().contains_key(&sender) { - return Err(crate::error::Error::NoBalance); + if !self.balance_of_map().contains_key(&caller) { + return Err(crate::error::Error::Revert("No balance")); } - let balance: u256 = self.balance_of_map().get(&sender); + let balance: u256 = self.balance_of_map().get(&caller); if balance < value { - return Err(crate::error::Error::InsufficientBalance); + return Err(Error::Revert("Insufficient balance")); } let new_balance = balance - value; - self.balance_of_map().set(&sender, new_balance); + self.balance_of_map().set(&caller, new_balance); let value = self.total_supply().set(total_supply - value); self.create_burn_event(value)?; @@ -230,26 +379,24 @@ pub trait OP20Trait: super::ContractTrait { Ok(true) } - fn burn( - &mut self, - mut call_data: crate::types::CallData, - ) -> Result { - let mut cursor = Cursor::new(1); - let amount = call_data.read_u256_be()?; + #[inline] + fn burn(&mut self, amount: u256) -> Result { + let mut response = Cursor::new(1); - cursor.write_bool(self.burn_base(amount, true)?)?; - Ok(cursor) + response.write_bool(self.burn_base(amount, true)?)?; + Ok(response) } + #[inline] fn mint_base( &mut self, to: &AddressHash, value: u256, only_deployer: bool, - ) -> Result { + ) -> Result { if only_deployer { - let sender = self.environment().caller.clone(); - self.only_deployer(&sender)?; + let caller = self.environment().caller; + self.only_deployer(&caller)?; } if !self.balance_of_map().contains_key(to) { @@ -263,77 +410,79 @@ pub trait OP20Trait: super::ContractTrait { let new = old + value; if new > self.max_supply() { - return Err(crate::error::Error::MaxSupplyReached); + return Err(Error::Revert("Max supply reached")); } self.total_supply().set(new); - self.create_mint_event(*to, value)?; - + self.context() + .log(&format!("Minted! {}: {}", to.to_hex(), value)); Ok(true) } + #[inline] fn transfer_base( &mut self, to: &AddressHash, - value: u256, + value: &u256, ) -> Result { - let sender = self.environment().caller; - if self.is_self(&sender) { - return Err(crate::error::Error::CanNotTransferFromSelfAccount); + let caller = self.environment().caller; + if self.is_self(&caller) { + return Err(Error::Revert("Can not transfer from self account")); } - if value == u256::ZERO { - return Err(crate::error::Error::CannotTransferZeroTokens); + if u256::ZERO.eq(value) { + return Err(Error::Revert("Cannot transfer 0 tokens")); } - let balance = self.balance_of_map().get(&sender); + let balance = self.balance_of_map().get(&caller); - if balance < value { - return Err(crate::error::Error::InsufficientBalance); + if balance.lt(value) { + return Err(Error::Revert("Insufficient balance")); } let new_balance = balance - value; - self.balance_of_map().set(&sender, new_balance); + self.balance_of_map().set(&caller, new_balance); let balance = self.balance_of_map().get(to); let new_balance = balance + value; self.balance_of_map().set(to, new_balance); - self.create_transfer_event(sender, *to, value)?; + self.create_transfer_event(caller, *to, *value)?; Ok(true) } + #[inline] fn transfer( &mut self, - mut call_data: crate::types::CallData, + address: AddressHash, + amount: u256, ) -> Result { - let mut cursor = Cursor::new(1); - let address = call_data.read_address()?; - let amount = call_data.read_u256_be()?; - let result = self.transfer_base(&address, amount)?; + let mut result = Cursor::new(1); - cursor.write_bool(result)?; - Ok(cursor) + result.write_bool(self.transfer_base(&address, &amount)?)?; + Ok(result) } + #[inline] fn spend_allowance( &mut self, - deployer: &AddressHash, + owner: &AddressHash, spender: &AddressHash, value: u256, ) -> Result<(), crate::error::Error> { - let mut deployer_allowance_map = self.allowance_map().get(deployer); - let allowed: u256 = deployer_allowance_map.get(&spender.bytes).u256(); + let mut owner_allowance_map = self.allowance_map().get(owner); + let allowed: u256 = owner_allowance_map.get(&spender).u256(); if allowed < value { return Err(crate::error::Error::InsufficientAllowance); } let new_allowance = allowed - value; - deployer_allowance_map.set(&spender.bytes, new_allowance.into()); - self.allowance_map().set(*deployer, deployer_allowance_map); + owner_allowance_map.set(&spender, new_allowance.into()); + self.allowance_map().set(*owner, owner_allowance_map); Ok(()) } + #[inline] fn transfer_from_unsafe( &mut self, from: &AddressHash, @@ -361,6 +510,7 @@ pub trait OP20Trait: super::ContractTrait { Ok(true) } + #[inline] fn transfer_from_base( &mut self, from: &AddressHash, @@ -378,23 +528,21 @@ pub trait OP20Trait: super::ContractTrait { Ok(true) } + #[inline] fn transfer_from( &mut self, - mut call_data: crate::types::CallData, + address_from: AddressHash, + address_to: AddressHash, + amount: u256, ) -> Result { - let mut cursor = Cursor::new(1); - - let address_from = call_data.read_address()?; - let address_to = call_data.read_address()?; - let amount = call_data.read_u256_be()?; - cursor.write_bool(self.transfer_from_base(&address_from, &address_to, amount)?)?; - - Ok(cursor) + let mut result = Cursor::new(BOOLEAN_BYTE_LENGTH); + result.write_bool(self.transfer_from_base(&address_from, &address_to, amount)?)?; + Ok(result) } + #[inline] fn create_burn_event(&mut self, value: u256) -> Result<(), crate::error::Error> { let burn_event = crate::event::Event::burn(value)?; - self.emit(&burn_event); Ok(()) } diff --git a/src/cursor/mod.rs b/src/cursor/mod.rs index 107a76c..64c49aa 100644 --- a/src/cursor/mod.rs +++ b/src/cursor/mod.rs @@ -68,6 +68,10 @@ impl Cursor { pub fn ptr(&self) -> WaPtr { WaPtr((self.inner.as_ptr()) as u32) } + + pub fn size(&self) -> usize { + self.inner.len() + } } #[cfg(test)] @@ -80,18 +84,18 @@ mod tests { let mut cursor = super::Cursor::from_slice(alloc::boxed::Box::leak(mem)); cursor.write_u8(1)?; - cursor.write_u16_le(&2)?; - cursor.write_u32_le(&3)?; - cursor.write_u64_le(&4)?; - cursor.write_u128_le(&5)?; - cursor.write_u256_be(&u256::new(6))?; + cursor.write_u16(&2, true)?; + cursor.write_u32(&3, true)?; + cursor.write_u64(&4, true)?; + cursor.write_u128(&5, true)?; + cursor.write_u256(&u256::new(6), true)?; assert_eq!(cursor.read_u8()?, 1); - assert_eq!(cursor.read_u16_le()?, 2); - assert_eq!(cursor.read_u32_le()?, 3); - assert_eq!(cursor.read_u64_le()?, 4); - assert_eq!(cursor.read_u128_le()?, 5); - assert_eq!(cursor.read_u256_be()?, u256::new(6)); + assert_eq!(cursor.read_u16(true)?, 2); + assert_eq!(cursor.read_u32(true)?, 3); + assert_eq!(cursor.read_u64(true)?, 4); + assert_eq!(cursor.read_u128(true)?, 5); + assert_eq!(cursor.read_u256(true)?, u256::new(6)); Ok(()) } diff --git a/src/cursor/reader.rs b/src/cursor/reader.rs index ee1fc9e..53b6c99 100644 --- a/src/cursor/reader.rs +++ b/src/cursor/reader.rs @@ -1,12 +1,12 @@ use core::str; -use crate::{blockchain::AddressHash, storage::map::Map, types::Selector}; +use crate::{blockchain::AddressHash, storage::map::Map, types::Selector, FromBytes}; use ethnum::u256; impl super::Cursor { - pub fn read_u32_le_unchecked(&mut self) -> u32 { + pub fn read_u32_be_unchecked(&mut self) -> u32 { self.reader += 4; - u32::from_le_bytes(self.inner[self.reader - 4..self.reader].try_into().unwrap()) + u32::from_be_bytes(self.inner[self.reader - 4..self.reader].try_into().unwrap()) } pub fn read_u8(&mut self) -> Result { @@ -19,10 +19,13 @@ impl super::Cursor { } } - pub fn read_u16_le(&mut self) -> Result { + pub fn read_u16(&mut self, be: bool) -> Result { if self.reader + 2 <= self.inner.len() { - let result = - u16::from_le_bytes(self.inner[self.reader..self.reader + 2].try_into().unwrap()); + let result = if be { + u16::from_be_bytes(self.inner[self.reader..self.reader + 2].try_into().unwrap()) + } else { + u16::from_le_bytes(self.inner[self.reader..self.reader + 2].try_into().unwrap()) + }; self.reader += 2; Ok(result) } else { @@ -30,10 +33,13 @@ impl super::Cursor { } } - pub fn read_u32_le(&mut self) -> Result { + pub fn read_u32(&mut self, be: bool) -> Result { if self.reader + 4 <= self.inner.len() { - let result = - u32::from_le_bytes(self.inner[self.reader..self.reader + 4].try_into().unwrap()); + let result = if be { + u32::from_be_bytes(self.inner[self.reader..self.reader + 4].try_into().unwrap()) + } else { + u32::from_le_bytes(self.inner[self.reader..self.reader + 4].try_into().unwrap()) + }; self.reader += 4; Ok(result) } else { @@ -41,10 +47,10 @@ impl super::Cursor { } } - pub fn read_u64_le(&mut self) -> Result { + pub fn read_u64(&mut self, be: bool) -> Result { if self.reader + 8 <= self.inner.len() { let result = - u64::from_le_bytes(self.inner[self.reader..self.reader + 8].try_into().unwrap()); + u64::from_be_bytes(self.inner[self.reader..self.reader + 8].try_into().unwrap()); self.reader += 8; Ok(result) } else { @@ -52,13 +58,21 @@ impl super::Cursor { } } - pub fn read_u128_le(&mut self) -> Result { + pub fn read_u128(&mut self, be: bool) -> Result { if self.reader + 16 <= self.inner.len() { - let result = u128::from_le_bytes( - self.inner[self.reader..self.reader + 16] - .try_into() - .unwrap(), - ); + let result = if be { + u128::from_be_bytes( + self.inner[self.reader..self.reader + 16] + .try_into() + .unwrap(), + ) + } else { + u128::from_le_bytes( + self.inner[self.reader..self.reader + 16] + .try_into() + .unwrap(), + ) + }; self.reader += 16; Ok(result) } else { @@ -66,13 +80,21 @@ impl super::Cursor { } } - pub fn read_u256_be(&mut self) -> Result { + pub fn read_u256(&mut self, be: bool) -> Result { if self.reader + 32 <= self.inner.len() { - let result = u256::from_be_bytes( - self.inner[self.reader..self.reader + 32] - .try_into() - .unwrap(), - ); + let result = if be { + u256::from_be_bytes( + self.inner[self.reader..self.reader + 32] + .try_into() + .unwrap(), + ) + } else { + u256::from_le_bytes( + self.inner[self.reader..self.reader + 32] + .try_into() + .unwrap(), + ) + }; self.reader += 32; Ok(result) } else { @@ -80,6 +102,7 @@ impl super::Cursor { } } + /* pub fn read_u256_le(&mut self) -> Result { if self.reader + 32 <= self.inner.len() { let result = u256::from_le_bytes( @@ -93,13 +116,14 @@ impl super::Cursor { Err(crate::error::Error::NoMoreData) } } + */ pub fn read_bool(&mut self) -> Result { Ok((self.read_u8()?) != 0) } pub fn read_selector(&mut self) -> Result { - self.read_u32_le() + self.read_u32(false) } pub fn read_bytes(&mut self, size: usize) -> Result<&[u8], crate::error::Error> { @@ -112,8 +136,13 @@ impl super::Cursor { } } + pub fn read_bytes_with_length(&mut self, be: bool) -> Result<&[u8], crate::error::Error> { + let length = self.read_u32(be)?; + return self.read_bytes(length as usize); + } + pub fn read_address(&mut self) -> Result { - Ok(AddressHash::new( + Ok(AddressHash::from_bytes( self.read_bytes(crate::constant::ADDRESS_BYTE_LENGTH)?, )) } @@ -121,17 +150,17 @@ impl super::Cursor { pub fn read_address_value_map( &mut self, ) -> Result, crate::error::Error> { - let len = self.read_u16_le()?; + let len = self.read_u16(true)?; let mut result = Map::new(); for _ in 0..len { - result.insert(self.read_address()?, self.read_u256_be()?); + result.insert(self.read_address()?, self.read_u256(true)?); } Ok(result) } pub fn read_string_with_len(&mut self) -> Result<&str, crate::error::Error> { - let len = self.read_u16_le()?; + let len = self.read_u16(true)?; let pos = self.reader; self.reader += len as usize; diff --git a/src/cursor/writer.rs b/src/cursor/writer.rs index ccbabb7..4ae318e 100644 --- a/src/cursor/writer.rs +++ b/src/cursor/writer.rs @@ -13,9 +13,13 @@ impl super::Cursor { } } - pub fn write_u16_le(&mut self, val: &u16) -> Result<(), crate::error::Error> { + pub fn write_u16(&mut self, val: &u16, be: bool) -> Result<(), crate::error::Error> { if self.writer + 2 <= self.inner.len() { - self.inner[self.writer..self.writer + 2].copy_from_slice(&val.to_le_bytes()); + self.inner[self.writer..self.writer + 2].copy_from_slice(&if be { + val.to_be_bytes() + } else { + val.to_le_bytes() + }); self.writer += 2; Ok(()) } else { @@ -23,9 +27,13 @@ impl super::Cursor { } } - pub fn write_u32_le(&mut self, val: &u32) -> Result<(), crate::error::Error> { + pub fn write_u32(&mut self, val: &u32, be: bool) -> Result<(), crate::error::Error> { if self.writer + 4 <= self.inner.len() { - self.inner[self.writer..self.writer + 4].copy_from_slice(&val.to_le_bytes()); + self.inner[self.writer..self.writer + 4].copy_from_slice(&if be { + val.to_be_bytes() + } else { + val.to_le_bytes() + }); self.writer += 4; Ok(()) } else { @@ -33,9 +41,13 @@ impl super::Cursor { } } - pub fn write_u64_le(&mut self, val: &u64) -> Result<(), crate::error::Error> { + pub fn write_u64(&mut self, val: &u64, be: bool) -> Result<(), crate::error::Error> { if self.writer + 8 <= self.inner.len() { - self.inner[self.writer..self.writer + 8].copy_from_slice(&val.to_le_bytes()); + self.inner[self.writer..self.writer + 8].copy_from_slice(&if be { + val.to_be_bytes() + } else { + val.to_le_bytes() + }); self.writer += 8; Ok(()) } else { @@ -43,9 +55,13 @@ impl super::Cursor { } } - pub fn write_u128_le(&mut self, val: &u128) -> Result<(), crate::error::Error> { + pub fn write_u128(&mut self, val: &u128, be: bool) -> Result<(), crate::error::Error> { if self.writer + 16 <= self.inner.len() { - self.inner[self.writer..self.writer + 16].copy_from_slice(&val.to_le_bytes()); + self.inner[self.writer..self.writer + 16].copy_from_slice(&if be { + val.to_be_bytes() + } else { + val.to_le_bytes() + }); self.writer += 16; Ok(()) } else { @@ -53,19 +69,13 @@ impl super::Cursor { } } - pub fn write_u256_le(&mut self, val: &u256) -> Result<(), crate::error::Error> { + pub fn write_u256(&mut self, val: &u256, be: bool) -> Result<(), crate::error::Error> { if self.writer + 32 <= self.inner.len() { - self.inner[self.writer..self.writer + 32].copy_from_slice(&val.to_le_bytes()); - self.writer += 32; - Ok(()) - } else { - Err(crate::error::Error::BufferIsFull) - } - } - - pub fn write_u256_be(&mut self, val: &u256) -> Result<(), crate::error::Error> { - if self.writer + 32 <= self.inner.len() { - self.inner[self.writer..self.writer + 32].copy_from_slice(&val.to_be_bytes()); + self.inner[self.writer..self.writer + 32].copy_from_slice(&if be { + val.to_be_bytes() + } else { + val.to_le_bytes() + }); self.writer += 32; Ok(()) } else { @@ -78,7 +88,7 @@ impl super::Cursor { } pub fn write_selector(&mut self, selector: &Selector) -> Result<(), crate::error::Error> { - self.write_u32_le(selector) + self.write_u32(selector, false) } pub fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), crate::error::Error> { @@ -93,7 +103,7 @@ impl super::Cursor { pub fn write_bytes_with_len(&mut self, bytes: &[u8]) -> Result<(), crate::error::Error> { if self.writer + bytes.len() + 4 <= self.inner.len() { - self.write_u32_le(&(bytes.len() as u32))?; + self.write_u32(&(bytes.len() as u32), true)?; self.write_bytes(bytes) } else { Err(crate::error::Error::BufferIsFull) @@ -111,7 +121,7 @@ impl super::Cursor { pub fn write_string_with_len(&mut self, string: &str) -> Result<(), crate::error::Error> { let bytes = string.as_bytes(); if self.writer + bytes.len() + 2 <= self.inner.len() { - self.write_u16_le(&(bytes.len() as u16))?; + self.write_u16(&(bytes.len() as u16), true)?; self.write_bytes(bytes) } else { Err(crate::error::Error::BufferIsFull) @@ -120,7 +130,7 @@ impl super::Cursor { pub fn write_address(&mut self, address: &AddressHash) -> Result<(), crate::error::Error> { if self.writer + ADDRESS_BYTE_LENGTH <= self.inner.len() { - self.write_bytes(&address.bytes) + self.write_bytes(&address.0) } else { Err(crate::error::Error::BufferIsFull) } diff --git a/src/env/global.rs b/src/env/global.rs index 355ae8a..190bb00 100644 --- a/src/env/global.rs +++ b/src/env/global.rs @@ -1,23 +1,23 @@ +use alloc::format; + use crate::{ blockchain::{ - environment, transaction::Input, AddressHash, BlockHash, Environment, TransactionHash, - }, - cursor::{self, Cursor}, - storage::{ - key::{self, StorageKey}, - map::Map, - value::{self, StorageValue}, + transaction::{Input, Output}, + AddressHash, BlockHash, Environment, TransactionHash, }, - WaPtr, + cursor::Cursor, + storage::{key::StorageKey, map::Map, value::StorageValue}, + FromBytes, WaPtr, }; -use alloc::vec::Vec; + use core::cell::RefCell; -use ethnum::u256; #[link(wasm_import_module = "env")] extern "C" { pub fn revert(data: u32, length: u32); + pub fn exit(status: u32, data: WaPtr, length: u32); + #[link_name = "calldata"] pub fn get_call_data(offset: u32, length: u32, result: WaPtr); @@ -37,6 +37,7 @@ extern "C" { pub fn call_result(offset: u32, length: u32, result: u32); pub fn emit(data: u32, data_length: u32); + #[link_name = "encodeAddress"] pub fn encode_address(data: u32) -> u32; @@ -92,26 +93,27 @@ impl super::Context for GlobalContext { fn environment(&self) -> Environment { unsafe { - let mut cursor = Cursor::new(crate::constant::ENVIRONMENT_SIZE); - get_environment(0, crate::constant::ENVIRONMENT_SIZE as u32, cursor.ptr()); + let mut cursor = Cursor::new(crate::constant::ENVIRONMENT_BYTE_LENGTH); + get_environment( + 0, + crate::constant::ENVIRONMENT_BYTE_LENGTH as u32, + cursor.ptr(), + ); Environment { - block_hash: BlockHash { - bytes: cursor - .read_bytes(crate::constant::BLOCK_HASH_LENGTH) - .unwrap() - .try_into() + block_hash: BlockHash::from_bytes( + cursor + .read_bytes(crate::constant::BLOCK_HASH_BYTE_LENGTH) .unwrap(), - }, - block_number: cursor.read_u64_le().unwrap(), - block_median_time: cursor.read_u64_le().unwrap(), - transaction_hash: TransactionHash { - bytes: cursor - .read_bytes(crate::constant::TRANSACTION_HASH_LENGTH) - .unwrap() - .try_into() + ), + block_number: cursor.read_u64(true).unwrap(), + block_median_time: cursor.read_u64(true).unwrap(), + transaction_hash: TransactionHash::from_bytes( + cursor + .read_bytes(crate::constant::TRANSACTION_HASH_BYTE_LENGTH) .unwrap(), - }, + ), + contract_address: cursor.read_address().unwrap(), contract_deployer: cursor.read_address().unwrap(), caller: cursor.read_address().unwrap(), @@ -130,7 +132,14 @@ impl super::Context for GlobalContext { fn emit(&self, event: &dyn crate::event::EventTrait) { unsafe { - emit(event.ptr(), event.buffer().len() as u32); + let buffer = event.buffer(); + self.log(&format!( + "Emit size: {:?} {} {}", + buffer, + buffer.len(), + buffer.as_ptr() as u32 + )); + emit(buffer.as_ptr() as u32, buffer.len() as u32); } } @@ -150,12 +159,28 @@ impl super::Context for GlobalContext { Ok(*from_address) } - fn validate_bitcoin_address(&self, _address: &str) -> bool { - false + fn validate_bitcoin_address(&self, address: &str) -> Result { + unsafe { + Ok(validate_bitcoin_address( + address.as_bytes().as_ptr() as u32, + address.as_bytes().len() as u32, + ) != 0) + } } - fn verify_schnorr_signature(&self, _data: &[u8]) -> bool { - false + fn verify_schnorr_signature( + &self, + address: &AddressHash, + signature: &[u8], + hash: &[u8], + ) -> Result { + unsafe { + Ok(verify_schnorr_signature( + address.ptr().0, + signature.as_ptr() as u32, + hash.as_ptr() as u32, + ) != 0) + } } fn load(&self, pointer: &StorageKey) -> Option { @@ -197,7 +222,7 @@ impl super::Context for GlobalContext { } } - fn inputs(&self) -> alloc::vec::Vec { + fn inputs(&self) -> alloc::vec::Vec { unsafe { let size = inputs_size(); let buffer = Cursor::new(size as usize); @@ -207,17 +232,7 @@ impl super::Context for GlobalContext { alloc::vec::Vec::new() } - /* - fn iter_inputs(&mut self) -> impl Iterator { - if self.inputs.is_none() { - self.inputs = Some(Vec::new()); - } - - self.inputs.as_ref().unwrap().iter() - } - */ - - fn outputs(&self) -> alloc::vec::Vec { + fn outputs(&self) -> alloc::vec::Vec { unsafe { let size = outputs_size(); let buffer = Cursor::new(size as usize); @@ -226,14 +241,4 @@ impl super::Context for GlobalContext { alloc::vec::Vec::new() } - - /* - fn iter_outputs(&mut self) -> impl Iterator { - if self.outputs.is_none() { - self.outputs = Some(Vec::new()); - } - - self.outputs.as_ref().unwrap().iter() - } - */ } diff --git a/src/env/mod.rs b/src/env/mod.rs index d8e6f18..81f8454 100644 --- a/src/env/mod.rs +++ b/src/env/mod.rs @@ -1,5 +1,5 @@ use crate::{ - blockchain::Environment, + blockchain::{AddressHash, Environment}, cursor::Cursor, storage::{StorageKey, StorageValue}, }; @@ -83,8 +83,13 @@ pub trait Context { fn exists(&self, pointer: &StorageKey) -> bool; fn encode_address(&self, address: &str) -> &'static [u8]; - fn validate_bitcoin_address(&self, address: &str) -> bool; - fn verify_schnorr_signature(&self, data: &[u8]) -> bool; + fn validate_bitcoin_address(&self, address: &str) -> Result; + fn verify_schnorr_signature( + &self, + address: &AddressHash, + signature: &[u8], + hash: &[u8], + ) -> Result; fn sha256(&self, data: &[u8]) -> [u8; 32] { sha256(data) } diff --git a/src/env/test.rs b/src/env/test.rs index 79f6cb3..74af08b 100644 --- a/src/env/test.rs +++ b/src/env/test.rs @@ -108,26 +108,35 @@ impl super::Context for TestContext { b"abc" } - fn validate_bitcoin_address(&self, address: &str) -> bool { + fn validate_bitcoin_address(&self, address: &str) -> Result { match Address::from_str(address) { Ok(addr) => { if addr.is_valid_for_network(self.network) { - true + Ok(true) } else { - false + Ok(false) } } - Err(e) => false, + Err(e) => Ok(false), } } - fn verify_schnorr_signature(&self, _data: &[u8]) -> bool { - let SECP: secp256k1::Secp256k1 = secp256k1::Secp256k1::new(); - - let xonly_public_key = secp256k1::XOnlyPublicKey::from_byte_array(&[0u8; 32]).unwrap(); - let signature = secp256k1::schnorr::Signature::from_byte_array([0u8; 64]); - let result = SECP.verify_schnorr(&signature, &[0u8; 32], &xonly_public_key); - result.is_ok() + fn verify_schnorr_signature( + &self, + address: &AddressHash, + signature: &[u8], + hash: &[u8], + ) -> Result { + let secp: secp256k1::Secp256k1 = secp256k1::Secp256k1::new(); + + let xonly_public_key = secp256k1::XOnlyPublicKey::from_byte_array(&address.0).unwrap(); + let signature = secp256k1::schnorr::Signature::from_byte_array( + signature + .try_into() + .map_err(|_| crate::error::Error::ConvertError)?, + ); + let result = secp.verify_schnorr(&signature, &hash, &xonly_public_key); + Ok(result.is_ok()) } fn load(&self, pointer: &crate::storage::StorageKey) -> Option { @@ -168,21 +177,9 @@ impl super::Context for TestContext { self.inputs.clone() } - /* - fn iter_inputs(&mut self) -> impl Iterator { - self.inputs.iter() - } - */ - fn outputs(&self) -> Vec { self.outputs.clone() } - - /* - fn iter_outputs(&mut self) -> impl Iterator { - self.outputs.iter() - } - */ } #[cfg(test)] @@ -190,13 +187,16 @@ mod tests { use crate::Context; use super::TestContext; + use crate::tests::random_address; #[test] fn test_validate_mainnet_address() { let context = TestContext::default(); assert_eq!( true, - context.validate_bitcoin_address("bc1qnghhhgvz5cn8n6x2fy06yzvkuermcm5ljn06gw") + context + .validate_bitcoin_address("bc1qnghhhgvz5cn8n6x2fy06yzvkuermcm5ljn06gw") + .unwrap() ); } @@ -208,7 +208,9 @@ mod tests { }; assert_eq!( true, - context.validate_bitcoin_address("mym4vP87LdQp9YzRbggpS46fYiQFfR52Nq") + context + .validate_bitcoin_address("mym4vP87LdQp9YzRbggpS46fYiQFfR52Nq") + .unwrap() ); } @@ -220,7 +222,9 @@ mod tests { }; assert_eq!( true, - context.validate_bitcoin_address("3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy") + context + .validate_bitcoin_address("3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy") + .unwrap() ); } @@ -230,7 +234,10 @@ mod tests { network: bitcoin::Network::Bitcoin, ..Default::default() }; - assert_eq!(false, context.validate_bitcoin_address("invalid_address")); + assert_eq!( + false, + context.validate_bitcoin_address("invalid_address").unwrap() + ); } #[test] @@ -241,7 +248,9 @@ mod tests { }; assert_eq!( false, - context.validate_bitcoin_address("mym4vP87LdQp9YzRbggpS46fYiQFfR52Nq") + context + .validate_bitcoin_address("mym4vP87LdQp9YzRbggpS46fYiQFfR52Nq") + .unwrap() ); } @@ -253,9 +262,11 @@ mod tests { }; assert_eq!( true, - context.validate_bitcoin_address( - "bcrt1pe0slk2klsxckhf90hvu8g0688rxt9qts6thuxk3u4ymxeejw53gs0xjlhn" - ) + context + .validate_bitcoin_address( + "bcrt1pe0slk2klsxckhf90hvu8g0688rxt9qts6thuxk3u4ymxeejw53gs0xjlhn" + ) + .unwrap() ); } @@ -267,7 +278,9 @@ mod tests { }; assert_eq!( true, - context.validate_bitcoin_address("bcrt1qfqsr3m7vjxheghcvw4ks0fryqxfq8qzjf8fxes") + context + .validate_bitcoin_address("bcrt1qfqsr3m7vjxheghcvw4ks0fryqxfq8qzjf8fxes") + .unwrap() ); } @@ -279,7 +292,9 @@ mod tests { }; assert_eq!( true, - context.validate_bitcoin_address("mn6KYibk94NhScakhgVPQdGE1bnscugRDG") + context + .validate_bitcoin_address("mn6KYibk94NhScakhgVPQdGE1bnscugRDG") + .unwrap() ); } @@ -291,7 +306,14 @@ mod tests { }; assert_eq!( true, - context.validate_bitcoin_address("2MyLLEUGJSusHvPDNHTwYnG9FAJcrQ3VPZY") + context + .validate_bitcoin_address("2MyLLEUGJSusHvPDNHTwYnG9FAJcrQ3VPZY") + .unwrap() ); } + + #[test] + fn test_valid_schnnor_signature() { + assert_eq!(true, true) + } } diff --git a/src/error.rs b/src/error.rs index bf32443..b00d374 100644 --- a/src/error.rs +++ b/src/error.rs @@ -15,9 +15,12 @@ pub enum Error { OnlyOwner, NoTokens, InsufficientAllowance, + ConvertError, + ParseError, Test, + Revert(&'static str), Extra(&'static str), } @@ -38,7 +41,12 @@ impl Error { Self::OnlyOwner => "OnlyOwner", Self::NoTokens => "NoTokens", Self::InsufficientAllowance => "InsufficientAllowance", + Self::ConvertError => "Convert error", + Self::ParseError => "ParseError", + Self::Test => "Test", + + Self::Revert(err) => err, Self::Extra(err) => err, } } diff --git a/src/event/mod.rs b/src/event/mod.rs index b2fcd8d..2253d31 100644 --- a/src/event/mod.rs +++ b/src/event/mod.rs @@ -28,10 +28,10 @@ impl Event { let mut cursor = Cursor::new(event_type.len() + 6 + byte_size); cursor.write_string_with_len(event_type)?; - cursor.write_u32_le(&(byte_size as u32))?; + cursor.write_u32(&(byte_size as u32), true)?; cursor.write_address(&owner)?; cursor.write_address(&spender)?; - cursor.write_u256_be(&value)?; + cursor.write_u256(&value, true)?; Ok(Event { buffer: cursor.into_inner(), @@ -45,8 +45,8 @@ impl Event { let mut cursor = Cursor::new(event_type.len() + 6 + byte_size); cursor.write_string_with_len(event_type)?; - cursor.write_u32_le(&(byte_size as u32))?; - cursor.write_u256_be(&amount)?; + cursor.write_u32(&(byte_size as u32), true)?; + cursor.write_u256(&amount, true)?; Ok(Event { buffer: cursor.into_inner(), @@ -60,8 +60,8 @@ impl Event { let mut cursor = Cursor::new(event_type.len() + 6 + byte_size); cursor.write_string_with_len(event_type)?; - cursor.write_u32_le(&(byte_size as u32))?; - cursor.write_u256_be(&amount)?; + cursor.write_u32(&(byte_size as u32), true)?; + cursor.write_u256(&amount, true)?; Ok(Event { buffer: cursor.into_inner(), @@ -75,9 +75,9 @@ impl Event { let mut cursor = Cursor::new(event_type.len() + 6 + byte_size); cursor.write_string_with_len(event_type)?; - cursor.write_u32_le(&(byte_size as u32))?; + cursor.write_u32(&(byte_size as u32), true)?; cursor.write_address(&address)?; - cursor.write_u256_be(&amount)?; + cursor.write_u256(&amount, true)?; Ok(Event { buffer: cursor.into_inner(), @@ -91,8 +91,8 @@ impl Event { let mut cursor = Cursor::new(event_type.len() + 6 + byte_size); cursor.write_string_with_len(event_type)?; - cursor.write_u32_le(&(byte_size as u32))?; - cursor.write_u256_be(&amount)?; + cursor.write_u32(&(byte_size as u32), true)?; + cursor.write_u256(&amount, true)?; Ok(Event { buffer: cursor.into_inner(), @@ -106,8 +106,8 @@ impl Event { let mut cursor = Cursor::new(event_type.len() + 6 + byte_size); cursor.write_string_with_len(event_type)?; - cursor.write_u32_le(&(byte_size as u32))?; - cursor.write_u256_be(&amount)?; + cursor.write_u32(&(byte_size as u32), true)?; + cursor.write_u256(&amount, true)?; Ok(Event { buffer: cursor.into_inner(), @@ -127,11 +127,11 @@ impl Event { cursor.write_string_with_len(event_type)?; - cursor.write_u32_le(&(byte_size as u32))?; + cursor.write_u32(&(byte_size as u32), true)?; cursor.write_address(&addr_from)?; cursor.write_address(&addr_to)?; - cursor.write_u256_be(&amount)?; + cursor.write_u256(&amount, true)?; Ok(Event { buffer: cursor.into_inner(), diff --git a/src/lib.rs b/src/lib.rs index f59daf7..e934749 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -67,26 +67,51 @@ fn panic(_panic: &core::panic::PanicInfo<'_>) -> ! { core::arch::wasm32::unreachable() } -#[cfg(target_arch = "wasm32")] +//#[cfg(target_arch = "wasm32")] #[allow(static_mut_refs)] #[export_name = "execute"] -pub unsafe fn execute(length: u32) -> WaPtr { +pub unsafe fn execute(length: u32) -> u32 { if let Some(contract) = &mut CONTRACT { let mut contract = contract.borrow_mut(); - contract.context().log("Log message"); - let call_data = contract.context().call_data(length as usize); - contract.execute(call_data).unwrap().ptr() + match contract.execute(call_data) { + Ok(result) => { + env::global::exit(0, result.ptr(), result.size() as u32); + 0 + } + Err(err) => { + let log_text = alloc::format!("Contract failed with a error: {}", err.as_str()); + env::global::log( + log_text.as_bytes().as_ptr() as u32, + log_text.as_bytes().len() as u32, + ); + 1 + } + } } else { - return WaPtr(20); + let log_text: &str = "Contract is empty"; + env::global::log( + log_text.as_bytes().as_ptr() as u32, + log_text.as_bytes().len() as u32, + ); + 1 } } #[cfg(target_arch = "wasm32")] #[export_name = "onDeploy"] #[allow(static_mut_refs)] -pub unsafe fn on_deploy(ptr: WaPtr) { - // problematic input!!! +pub unsafe fn on_deploy(length: u32) -> u32 { + if let Some(contract) = &mut CONTRACT { + let mut contract = contract.borrow_mut(); + + let call_data = contract.context().call_data(length as usize); + let result = contract.on_deploy(call_data); + + 0 + } else { + 1 + } } diff --git a/src/math/abi.rs b/src/math/abi.rs index 8bbb08d..360cab4 100644 --- a/src/math/abi.rs +++ b/src/math/abi.rs @@ -25,7 +25,7 @@ pub fn encode_selector(selector: &str) -> crate::types::Selector { } pub const fn encode_pointer_const(unique_identifier: u16) -> StorageKey { - let mut key = [0; crate::constant::STORE_KEY_SIZE]; + let mut key = [0; crate::constant::STORE_KEY_BYTE_LENGTH]; key[0] = (unique_identifier & 0xff) as u8; key[1] = ((unique_identifier >> 8) & 0xff) as u8; diff --git a/src/storage/array_merger.rs b/src/storage/array_merger.rs index 1c35ff9..946afa6 100644 --- a/src/storage/array_merger.rs +++ b/src/storage/array_merger.rs @@ -1,8 +1,6 @@ -use core::cell::RefCell; - use alloc::vec::Vec; -use crate::{math::abi::encode_pointer, storage::StorageKey, Context}; +use crate::{math::abi::encode_pointer, storage::StorageKey, AsBytes, Context}; use super::StorageValue; use alloc::rc::Rc; @@ -29,23 +27,40 @@ impl ArrayMerger { default_value, } } - pub fn get<'a>(&mut self, key: &[u8]) -> StorageValue { + pub fn get(&mut self, key: &T) -> StorageValue + where + T: AsBytes, + { let pointer = self.get_key_hash(key); self.context.load(&pointer).unwrap_or(self.default_value) } - pub fn set<'a>(&mut self, key: &[u8], value: StorageValue) { + pub fn set(&mut self, key: &T, value: StorageValue) + where + T: AsBytes, + { let pointer = self.get_key_hash(key); self.context.store(pointer, value); } - pub fn contains_key<'a>(&self, key: &[u8]) -> bool { + pub fn contains_key(&self, key: &T) -> bool + where + T: AsBytes, + { let key = self.get_key_hash(key); self.context.exists(&key) } - fn get_key_hash(&self, key: &[u8]) -> StorageKey { - let merged: Vec = self.parent_key.iter().chain(key.iter()).cloned().collect(); + fn get_key_hash(&self, key: &T) -> StorageKey + where + T: AsBytes, + { + let merged: Vec = self + .parent_key + .iter() + .chain(key.as_bytes().iter()) + .cloned() + .collect(); encode_pointer(self.pointer, &merged) } } @@ -61,3 +76,29 @@ impl PartialEq for ArrayMerger { } impl Eq for ArrayMerger {} + +#[cfg(test)] +mod tests { + use crate::{storage::StorageValue, AsBytes}; + + use super::ArrayMerger; + + #[test] + pub fn test1() { + let context = alloc::rc::Rc::new(crate::env::TestContext::default()); + let address1 = crate::tests::random_address(); + let address2 = crate::tests::random_address(); + let mut am1 = ArrayMerger::new(context.clone(), address1.0.to_vec(), 0, StorageValue::ZERO); + + let check_value = [1; 32]; + + let value = am1.get(&address2); + assert_eq!(value.as_bytes(), StorageValue::ZERO.as_bytes()); + + am1.set(&address2.as_bytes(), StorageValue::from_bytes(check_value)); + + let mut am2 = ArrayMerger::new(context.clone(), address1.0.to_vec(), 0, StorageValue::ZERO); + let value = am2.get(&address2); + assert_eq!(value.as_bytes(), &check_value); + } +} diff --git a/src/storage/key.rs b/src/storage/key.rs index e13f460..4bf77a0 100644 --- a/src/storage/key.rs +++ b/src/storage/key.rs @@ -2,11 +2,11 @@ use crate::WaPtr; #[derive(Clone, Copy, Eq, PartialEq)] pub struct StorageKey { - pub bytes: [u8; crate::constant::STORE_KEY_SIZE], + pub bytes: [u8; crate::constant::STORE_KEY_BYTE_LENGTH], } impl StorageKey { - pub const fn new(bytes: [u8; crate::constant::STORE_KEY_SIZE]) -> Self { + pub const fn new(bytes: [u8; crate::constant::STORE_KEY_BYTE_LENGTH]) -> Self { Self { bytes } } pub fn mut_ptr(&mut self) -> WaPtr { diff --git a/src/storage/multi_address_map.rs b/src/storage/multi_address_map.rs index b521556..eaed231 100644 --- a/src/storage/multi_address_map.rs +++ b/src/storage/multi_address_map.rs @@ -1,7 +1,6 @@ -use alloc::rc::Rc; -use core::cell::RefCell; +use alloc::{rc::Rc, vec::Vec}; -use crate::{blockchain::AddressHash, Context}; +use crate::{blockchain::AddressHash, AsBytes, Context}; use super::{array_merger::ArrayMerger, map::Map, StorageValue}; @@ -26,9 +25,9 @@ impl MultiAddressMemoryMap { self.map.clear(); } - pub fn get(&mut self, key: &AddressHash) -> ArrayMerger { - self.create_key_merger(key); - self.map.get(key).unwrap().clone() + pub fn get(&mut self, address: &AddressHash) -> ArrayMerger { + self.create_key_merger(address); + self.map.get(address).unwrap().clone() } pub fn set(&mut self, key: AddressHash, value: ArrayMerger) { @@ -46,7 +45,7 @@ impl MultiAddressMemoryMap { *key, ArrayMerger::new( self.context.clone(), - key.bytes.to_vec(), + key.as_bytes().to_vec(), self.pointer, self.default_value, ), @@ -54,3 +53,31 @@ impl MultiAddressMemoryMap { } } } + +#[cfg(test)] +mod tests { + use super::MultiAddressMemoryMap; + use crate::{storage::StorageValue, tests::random_address, AsBytes, TestContext}; + use alloc::rc::Rc; + + #[test] + fn test1() { + let context = Rc::new(TestContext::default()); + let address1 = random_address(); + let address2 = random_address(); + let one = [1; 32]; + let mut mamm1 = MultiAddressMemoryMap::new(context.clone(), 0, StorageValue::ZERO); + let mut merger1 = mamm1.get(&address1); + assert_eq!( + merger1.get(&address2).as_bytes(), + StorageValue::ZERO.as_bytes() + ); + + merger1.set(&address2, StorageValue::from_bytes(one)); + assert_eq!(merger1.get(&address2).as_bytes(), &one); + + let mut mamm2 = MultiAddressMemoryMap::new(context.clone(), 0, StorageValue::ZERO); + let mut merger2 = mamm2.get(&address1); + assert_eq!(merger2.get(&address2).as_bytes(), &one); + } +} diff --git a/src/storage/stored.rs b/src/storage/stored.rs index 7a9b0fb..2ddf953 100644 --- a/src/storage/stored.rs +++ b/src/storage/stored.rs @@ -122,17 +122,10 @@ pub type StoredAddress = Stored; #[cfg(test)] mod tests { - - use core::cell::RefCell; - - use alloc::rc::Rc; - use alloc::vec::Vec; - use ethnum::u256; - - use crate::cursor::Cursor; - use crate::storage::map::Map; use crate::Context; use crate::TestContext; + use alloc::rc::Rc; + use ethnum::u256; use super::StoredTrait; diff --git a/src/storage/stored_map.rs b/src/storage/stored_map.rs index 269a6ac..caf41de 100644 --- a/src/storage/stored_map.rs +++ b/src/storage/stored_map.rs @@ -58,3 +58,25 @@ where } pub type StoredAddresValueMap = StoredMap; + +#[cfg(test)] +mod tests { + use alloc::rc::Rc; + + use crate::{ + blockchain::AddressHash, storage::StorageValue, tests::random_address, AsBytes, TestContext, + }; + + use super::StoredMap; + + #[test] + fn test1() { + let context = Rc::new(TestContext::default()); + let one = [1; 32]; + let address1 = random_address(); + let sm: StoredMap = + StoredMap::new(context.clone(), 0, StorageValue::ZERO); + sm.set(&address1, StorageValue::from_bytes(one)); + assert_eq!(sm.get(&address1).as_bytes(), &one); + } +} diff --git a/src/storage/stored_string.rs b/src/storage/stored_string.rs index 4d5bdd1..ca38160 100644 --- a/src/storage/stored_string.rs +++ b/src/storage/stored_string.rs @@ -1,6 +1,6 @@ use core::cell::RefCell; -use crate::{constant::STORE_VALUE_SIZE, storage::StorageValue, Context}; +use crate::{constant::STORE_VALUE_BYTE_LENGTH, storage::StorageValue, AsBytes, Context}; use alloc::rc::Rc; use alloc::string::String; @@ -43,12 +43,12 @@ impl StoredString { fn save<'a>(&mut self, value: String) -> String { let bytes = value.as_bytes(); let mut remaining = bytes.len(); - let mut offset = [0u8; crate::constant::STORE_VALUE_SIZE]; + let mut offset = [0u8; crate::constant::STORE_VALUE_BYTE_LENGTH]; assert!(remaining < 2048); - let mut context = self.context.borrow_mut(); + let context = self.context.borrow(); - let mut data = [0u8; crate::constant::STORE_VALUE_SIZE]; - let mut length = remaining.min(STORE_VALUE_SIZE - 4); + let mut data = [0u8; crate::constant::STORE_VALUE_BYTE_LENGTH]; + let mut length = remaining.min(STORE_VALUE_BYTE_LENGTH - 4); data[0..4].copy_from_slice(&(remaining as u32).to_le_bytes()); data[4..4 + remaining.min(28)].copy_from_slice(&bytes[0..length]); let key = crate::math::abi::encode_pointer(self.pointer, &offset); @@ -56,16 +56,16 @@ impl StoredString { context.store(key, data.into()); while remaining > 0 { - length = remaining.min(crate::constant::STORE_VALUE_SIZE); + length = remaining.min(crate::constant::STORE_VALUE_BYTE_LENGTH); let start = value.len() - remaining; data[0..length].copy_from_slice(&bytes[start..start + length]); - if length < crate::constant::STORE_VALUE_SIZE { - data[length..crate::constant::STORE_VALUE_SIZE].copy_from_slice( - &[0u8; crate::constant::STORE_VALUE_SIZE] - [0..crate::constant::STORE_VALUE_SIZE - length], + if length < crate::constant::STORE_VALUE_BYTE_LENGTH { + data[length..crate::constant::STORE_VALUE_BYTE_LENGTH].copy_from_slice( + &[0u8; crate::constant::STORE_VALUE_BYTE_LENGTH] + [0..crate::constant::STORE_VALUE_BYTE_LENGTH - length], ); } - offset[crate::constant::STORE_KEY_SIZE - 1] += 1; + offset[crate::constant::STORE_KEY_BYTE_LENGTH - 1] += 1; remaining -= length; let key = crate::math::abi::encode_pointer(self.pointer, &offset); @@ -76,15 +76,15 @@ impl StoredString { } fn load<'a>(&mut self) -> String { - let mut offset = [0u8; crate::constant::STORE_VALUE_SIZE]; - let mut context = self.context.borrow_mut(); + let mut offset = [0u8; crate::constant::STORE_VALUE_BYTE_LENGTH]; + let context = self.context.borrow_mut(); let header = context .load(&crate::math::abi::encode_pointer(self.pointer, &offset)) .unwrap_or(StorageValue::ZERO); - let bytes = header.bytes(); + let bytes = header.as_bytes(); let len = u32::from_le_bytes(bytes[0..4].try_into().unwrap()) as usize; - let mut length = len.min(crate::constant::STORE_VALUE_SIZE); + let mut length = len.min(crate::constant::STORE_VALUE_BYTE_LENGTH); let mut value: alloc::vec::Vec = alloc::vec::Vec::with_capacity(len); let mut remaining = len - length; for &byte in bytes.iter().skip(4).take(length) { @@ -92,11 +92,11 @@ impl StoredString { } while remaining > 0 { - offset[crate::constant::STORE_KEY_SIZE - 1] += 1; + offset[crate::constant::STORE_VALUE_BYTE_LENGTH - 1] += 1; let key = crate::math::abi::encode_pointer(self.pointer, &offset); let tmp = context.load(&key).unwrap_or(StorageValue::ZERO); - let bytes = tmp.bytes(); - length = remaining.min(crate::constant::STORE_VALUE_SIZE); + let bytes = tmp.as_bytes(); + length = remaining.min(crate::constant::STORE_VALUE_BYTE_LENGTH); for &byte in bytes.iter().take(length) { value.push(byte); } diff --git a/src/storage/value.rs b/src/storage/value.rs index 43dcc82..39a20a4 100644 --- a/src/storage/value.rs +++ b/src/storage/value.rs @@ -1,15 +1,15 @@ use ethnum::u256; -use crate::WaPtr; +use crate::{AsBytes, WaPtr}; #[derive(Copy, Clone, Eq, PartialEq)] pub struct StorageValue { - inner: [u8; crate::constant::STORE_VALUE_SIZE], + inner: [u8; crate::constant::STORE_VALUE_BYTE_LENGTH], } impl StorageValue { pub const ZERO: StorageValue = StorageValue { - inner: [0; crate::constant::STORE_VALUE_SIZE], + inner: [0; crate::constant::STORE_VALUE_BYTE_LENGTH], }; pub fn mut_ptr(&mut self) -> WaPtr { @@ -20,18 +20,14 @@ impl StorageValue { WaPtr(self.inner.as_ptr() as *const u8 as u32) } - pub fn from_bytes(bytes: [u8; crate::constant::STORE_VALUE_SIZE]) -> Self { + pub fn from_bytes(bytes: [u8; crate::constant::STORE_VALUE_BYTE_LENGTH]) -> Self { Self { inner: bytes } } - pub fn value(&self) -> [u8; crate::constant::STORE_VALUE_SIZE] { + pub fn value(&self) -> [u8; crate::constant::STORE_VALUE_BYTE_LENGTH] { self.inner } - pub fn bytes(&self) -> &[u8] { - &self.inner - } - pub fn bool(&self) -> bool { self.inner.iter().any(|v| 0.le(v)) } @@ -65,22 +61,28 @@ impl StorageValue { } } -impl From<[u8; crate::constant::STORE_VALUE_SIZE]> for StorageValue { - fn from(value: [u8; crate::constant::STORE_VALUE_SIZE]) -> Self { +impl AsBytes for StorageValue { + fn as_bytes(&self) -> &[u8] { + &self.inner + } +} + +impl From<[u8; crate::constant::STORE_VALUE_BYTE_LENGTH]> for StorageValue { + fn from(value: [u8; crate::constant::STORE_VALUE_BYTE_LENGTH]) -> Self { StorageValue { inner: value } } } -impl From<&[u8; crate::constant::STORE_VALUE_SIZE]> for StorageValue { - fn from(value: &[u8; crate::constant::STORE_VALUE_SIZE]) -> Self { +impl From<&[u8; crate::constant::STORE_VALUE_BYTE_LENGTH]> for StorageValue { + fn from(value: &[u8; crate::constant::STORE_VALUE_BYTE_LENGTH]) -> Self { StorageValue { inner: *value } } } impl From<&[u8]> for StorageValue { fn from(value: &[u8]) -> Self { - let mut inner = [0u8; crate::constant::STORE_VALUE_SIZE]; - let length = value.len().min(crate::constant::STORE_VALUE_SIZE); + let mut inner = [0u8; crate::constant::STORE_VALUE_BYTE_LENGTH]; + let length = value.len().min(crate::constant::STORE_VALUE_BYTE_LENGTH); inner[32 - length..32].copy_from_slice(&value[0..length]); StorageValue { inner } diff --git a/src/tests/mod.rs b/src/tests/mod.rs index 0048d6d..c8fd253 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -19,23 +19,21 @@ pub fn random_u64() -> u64 { #[cfg(not(target_arch = "wasm32"))] pub fn random_address() -> AddressHash { - AddressHash { - bytes: random_bytes(), - } + AddressHash(random_bytes()) } #[cfg(not(target_arch = "wasm32"))] pub fn random_transaction() -> TransactionHash { - TransactionHash { - bytes: random_bytes(), - } + use crate::FromBytes; + + TransactionHash::from_bytes(&random_bytes()) } #[cfg(not(target_arch = "wasm32"))] pub fn random_block() -> BlockHash { - BlockHash { - bytes: random_bytes(), - } + use crate::FromBytes; + + BlockHash::from_bytes(&random_bytes()) } pub fn execute( @@ -43,7 +41,7 @@ pub fn execute( selector: crate::types::Selector, ) -> Cursor { let mut cursor = Cursor::new(32); - cursor.write_u32_le(&selector).unwrap(); + cursor.write_u32(&selector, true).unwrap(); contract.execute(cursor).unwrap() } @@ -53,7 +51,7 @@ pub fn execute_address( address: &AddressHash, ) -> Cursor { let mut cursor = Cursor::new(64); - cursor.write_u32_le(&selector).unwrap(); + cursor.write_u32(&selector, true).unwrap(); cursor.write_address(address).unwrap(); contract.execute(cursor).unwrap() } @@ -65,8 +63,8 @@ pub fn execute_address_amount( amount: u256, ) -> Cursor { let mut cursor = Cursor::new(96); - cursor.write_u32_le(&selector).unwrap(); + cursor.write_u32(&selector, true).unwrap(); cursor.write_address(address).unwrap(); - cursor.write_u256_be(&amount).unwrap(); + cursor.write_u256(&amount, true).unwrap(); contract.execute(cursor).unwrap() } diff --git a/src/utils.rs b/src/utils.rs index 26880bb..ab2b917 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,3 +1,17 @@ +pub trait AsBytes { + fn as_bytes(&self) -> &[u8]; +} + +pub trait FromBytes { + fn from_bytes(bytes: &[u8]) -> Self; +} + +impl AsBytes for &[u8] { + fn as_bytes(&self) -> &[u8] { + self + } +} + const BASE64_TABLE: [char; 16] = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', ]; @@ -12,30 +26,27 @@ pub fn to_hex(bytes: &[u8]) -> alloc::string::String { } string } -pub trait ToHex { - fn get_bytes(&self) -> &[u8]; +pub trait ToHex: AsBytes { fn to_hex(&self) -> alloc::string::String { - to_hex(self.get_bytes()) + to_hex(self.as_bytes()) } } -impl ToHex for &[u8] { - fn get_bytes(&self) -> &[u8] { - self - } -} +impl ToHex for &[u8] {} #[cfg(test)] mod tests { use super::*; pub struct TestHex(alloc::vec::Vec); - impl ToHex for TestHex { - fn get_bytes(&self) -> &[u8] { + impl AsBytes for TestHex { + fn as_bytes(&self) -> &[u8] { &self.0 } } + impl ToHex for TestHex {} + #[test] fn test_to_hex() { let v = TestHex(alloc::vec![0xda, 0x02, 0xa1, 0x1f]); From d8cafa1fda0520e3f5aa82c6d664a990ec324ffc Mon Sep 17 00:00:00 2001 From: Miksa Date: Sat, 15 Mar 2025 23:15:44 +0100 Subject: [PATCH 23/23] WIP - working gas tests --- Cargo.toml | 2 +- rust.wasm | Bin 37374 -> 56689 bytes src/constant.rs | 1 + src/env/global.rs | 29 ++++++----- src/env/store.rs | 82 ------------------------------- src/env/test.rs | 54 ++++++++++++++++++-- src/error.rs | 2 + src/lib.rs | 34 +++++++++---- src/storage/array_merger.rs | 4 +- src/storage/key.rs | 25 +++++++--- src/storage/multi_address_map.rs | 2 +- src/storage/stored.rs | 2 +- src/storage/stored_map.rs | 12 ++--- src/storage/value.rs | 63 +++++++++++++----------- 14 files changed, 154 insertions(+), 158 deletions(-) delete mode 100644 src/env/store.rs diff --git a/Cargo.toml b/Cargo.toml index b416f12..b8b8dce 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,7 +30,7 @@ rand = { version = "0.8.5" } libc-print = { version = "0.1.22" } ripemd = "0.1.3" bitcoin = "0.32.5" -secp256k1 = { version = "0.30.0", features = ["std"] } +secp256k1 = { version = "0.30.0", features = ["rand", "hashes", "std"] } [features] std = [] diff --git a/rust.wasm b/rust.wasm index 9ba50a57e47b7375e87dc9edcfdc020e068d4477..9bcbf12d6202ff76d8d0f4b4bb4c4f08935f938f 100644 GIT binary patch literal 56689 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 NGgtK<7Mqx|{J)NGM2G+Y diff --git a/src/constant.rs b/src/constant.rs index 9ab33c2..580286e 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -10,3 +10,4 @@ pub const STORE_VALUE_BYTE_LENGTH: usize = U256_BYTE_LENGTH; pub const ENVIRONMENT_BYTE_LENGTH: usize = 208; pub const SCHNORR_SIGNATURE_BYTE_LENGTH: usize = 64; pub const SCHNORR_MESSAGE_BYTE_LENGTH: usize = 32; +pub const DEBUG: bool = true; diff --git a/src/env/global.rs b/src/env/global.rs index 190bb00..adac8b2 100644 --- a/src/env/global.rs +++ b/src/env/global.rs @@ -185,36 +185,31 @@ impl super::Context for GlobalContext { fn load(&self, pointer: &StorageKey) -> Option { unsafe { - let value = StorageValue::from_bytes([0; 32]); - if let Some(value) = self.store.borrow().get(pointer) { - Some(value.clone()) + let value = StorageValue::ZERO; + + let result = self.store.borrow().get(pointer).cloned(); + + if let Some(value) = result { + Some(value) } else { load(pointer.ptr(), value.ptr()); if value.eq(&StorageValue::ZERO) { None } else { - self.store.borrow_mut().insert(*pointer, value.clone()); + self.store.borrow_mut().insert(*pointer, value); Some(value) } } } } - fn exists(&self, pointer: &StorageKey) -> bool { - if self.store.borrow().contains_key(pointer) { - true - } else { - self.load(pointer).is_some() - } - } - fn store(&self, pointer: StorageKey, value: StorageValue) { unsafe { if if let Some(old) = self.store.borrow().get(&pointer) { value.ne(old) } else { - false + true } { self.store.borrow_mut().insert(pointer, value); store(pointer.ptr(), value.ptr()) @@ -222,6 +217,14 @@ impl super::Context for GlobalContext { } } + fn exists(&self, pointer: &StorageKey) -> bool { + if self.store.borrow().contains_key(pointer) { + true + } else { + self.load(pointer).is_some() + } + } + fn inputs(&self) -> alloc::vec::Vec { unsafe { let size = inputs_size(); diff --git a/src/env/store.rs b/src/env/store.rs deleted file mode 100644 index 38622de..0000000 --- a/src/env/store.rs +++ /dev/null @@ -1,82 +0,0 @@ -#[allow(unused_imports)] -use crate::{ - storage::{map::Map, StorageKey, StorageValue}, - WaBuffer, -}; - -#[allow(unused_imports)] -#[cfg(not(target_arch = "wasm32"))] -use spin::{Lazy, Mutex}; - -/// For test purposes only: This global storage is used to mock the VM’s load/store behavior. -/// (In production the runtime uses GlobalStore instead.) -#[cfg(not(target_arch = "wasm32"))] -static STORAGE: Lazy>> = Lazy::new(|| Mutex::new(Map::new())); - -#[cfg(not(target_arch = "wasm32"))] -static STORAGE_GUARD: Lazy> = Lazy::new(|| Mutex::new(false)); - -#[cfg(target_arch = "wasm32")] -pub fn pointer_store(key: &StorageKey, value: &StorageValue) -> Result { - let mut buffer = WaBuffer::new(64, 1)?; - let mut cursor = buffer.cursor(); - - cursor.write_bytes(key)?; - cursor.write_bytes(value.bytes())?; - - unsafe { - WaBuffer::from_raw(super::global::store(buffer.ptr())) - .cursor() - .read_bool() - } -} - -/// For unit tests only: Write the key/value pair to our mocked storage. -#[cfg(not(target_arch = "wasm32"))] -pub fn pointer_store(key: &StorageKey, value: &StorageValue) -> Result { - let mut storage = STORAGE.lock(); - storage.insert(*key, *value); - Ok(true) -} - -#[cfg(target_arch = "wasm32")] -pub fn pointer_load(key: &StorageKey) -> Result { - let mut buffer = WaBuffer::new(32, 1)?; - let mut cursor = buffer.cursor(); - - cursor.write_bytes(key)?; - unsafe { - let value: StorageValue = WaBuffer::from_raw(super::global::load(buffer.ptr())) - .data() - .into(); - Ok(value) - } -} - -/// For unit tests only: Read the value from our mocked storage. -#[cfg(not(target_arch = "wasm32"))] -pub fn pointer_load(key: &StorageKey) -> Result { - let storage = STORAGE.lock(); - Ok(*storage.get(key).unwrap_or(&StorageValue::ZERO)) -} - -/// For unit tests only: Clear the mocked storage. -#[cfg(not(target_arch = "wasm32"))] -pub fn pointer_storage(data: Option>, callback: impl FnOnce()) { - let lock = STORAGE_GUARD.lock(); - - if let Some(data) = data { - let mut storage = STORAGE.lock(); - - for (key, value) in data.iter() { - storage.insert(key.clone(), value.clone()); - } - } - - callback(); - let mut storage = STORAGE.lock(); - storage.clear(); - - // Variable must by used!!! - drop(lock); -} diff --git a/src/env/test.rs b/src/env/test.rs index 74af08b..7273b38 100644 --- a/src/env/test.rs +++ b/src/env/test.rs @@ -117,7 +117,7 @@ impl super::Context for TestContext { Ok(false) } } - Err(e) => Ok(false), + Err(_) => Err(crate::error::Error::NoValidAddress), } } @@ -184,10 +184,8 @@ impl super::Context for TestContext { #[cfg(test)] mod tests { - use crate::Context; - use super::TestContext; - use crate::tests::random_address; + use crate::Context; #[test] fn test_validate_mainnet_address() { @@ -314,6 +312,52 @@ mod tests { #[test] fn test_valid_schnnor_signature() { - assert_eq!(true, true) + use secp256k1::hashes::{sha256, Hash}; + use secp256k1::rand::rngs::OsRng; + let context = TestContext::default(); + + let secp: secp256k1::Secp256k1 = secp256k1::Secp256k1::new(); + let (secret_key, public_key) = secp256k1::Secp256k1::new().generate_keypair(&mut OsRng); + let keypair = secp256k1::Keypair::from_secret_key(&secp, &secret_key); + let msg = sha256::Hash::hash("Hello World!".as_bytes()); + + // With random data + let signature = secp.sign_schnorr_with_rng(msg.as_byte_array(), &keypair, &mut OsRng); + assert!(secp + .verify_schnorr(&signature, msg.as_byte_array(), &public_key.into()) + .is_ok()); + assert!(context + .verify_schnorr_signature( + &crate::blockchain::AddressHash(public_key.x_only_public_key().0.serialize()), + signature.as_byte_array(), + msg.as_byte_array() + ) + .is_ok()); + + // NO random data + let signature = secp.sign_schnorr_no_aux_rand(msg.as_byte_array(), &keypair); + assert!(secp + .verify_schnorr(&signature, msg.as_byte_array(), &public_key.into()) + .is_ok()); + assert!(context + .verify_schnorr_signature( + &crate::blockchain::AddressHash(public_key.x_only_public_key().0.serialize()), + signature.as_byte_array(), + msg.as_byte_array() + ) + .is_ok()); + + // Custom random data + let signature = secp.sign_schnorr_with_aux_rand(msg.as_byte_array(), &keypair, &[1; 32]); + assert!(secp + .verify_schnorr(&signature, msg.as_byte_array(), &public_key.into()) + .is_ok()); + assert!(context + .verify_schnorr_signature( + &crate::blockchain::AddressHash(public_key.x_only_public_key().0.serialize()), + signature.as_byte_array(), + msg.as_byte_array() + ) + .is_ok()); } } diff --git a/src/error.rs b/src/error.rs index b00d374..1394173 100644 --- a/src/error.rs +++ b/src/error.rs @@ -17,6 +17,7 @@ pub enum Error { InsufficientAllowance, ConvertError, ParseError, + NoValidAddress, Test, @@ -43,6 +44,7 @@ impl Error { Self::InsufficientAllowance => "InsufficientAllowance", Self::ConvertError => "Convert error", Self::ParseError => "ParseError", + Self::NoValidAddress => "NoValidAddress", Self::Test => "Test", diff --git a/src/lib.rs b/src/lib.rs index e934749..001eba8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -27,6 +27,7 @@ use alloc::rc::Rc; pub use env::*; pub use ethnum; +pub use crate::constant::DEBUG; #[cfg(not(target_arch = "wasm32"))] pub use bitcoin; pub use utils::*; @@ -59,6 +60,13 @@ impl From<&[u8; 32]> for WaPtr { } } +fn log(text: &str) { + unsafe { + let bytes = text.as_bytes(); + env::global::log(bytes.as_ptr() as u32, bytes.len() as u32) + }; +} + #[cfg(not(test))] #[cfg(not(feature = "std"))] #[cfg(target_arch = "wasm32")] @@ -78,24 +86,30 @@ pub unsafe fn execute(length: u32) -> u32 { match contract.execute(call_data) { Ok(result) => { + if DEBUG { + log(&alloc::format!( + "Result of contract: {:?}", + result.clone().into_inner() + )); + } + env::global::exit(0, result.ptr(), result.size() as u32); 0 } Err(err) => { - let log_text = alloc::format!("Contract failed with a error: {}", err.as_str()); - env::global::log( - log_text.as_bytes().as_ptr() as u32, - log_text.as_bytes().len() as u32, - ); + if DEBUG { + log(&alloc::format!( + "Contract failed with a error: {}", + err.as_str() + )); + } 1 } } } else { - let log_text: &str = "Contract is empty"; - env::global::log( - log_text.as_bytes().as_ptr() as u32, - log_text.as_bytes().len() as u32, - ); + if DEBUG { + log("Contract is empty"); + } 1 } } diff --git a/src/storage/array_merger.rs b/src/storage/array_merger.rs index 946afa6..062b84e 100644 --- a/src/storage/array_merger.rs +++ b/src/storage/array_merger.rs @@ -79,7 +79,7 @@ impl Eq for ArrayMerger {} #[cfg(test)] mod tests { - use crate::{storage::StorageValue, AsBytes}; + use crate::{storage::StorageValue, AsBytes, FromBytes}; use super::ArrayMerger; @@ -95,7 +95,7 @@ mod tests { let value = am1.get(&address2); assert_eq!(value.as_bytes(), StorageValue::ZERO.as_bytes()); - am1.set(&address2.as_bytes(), StorageValue::from_bytes(check_value)); + am1.set(&address2.as_bytes(), StorageValue::new(check_value)); let mut am2 = ArrayMerger::new(context.clone(), address1.0.to_vec(), 0, StorageValue::ZERO); let value = am2.get(&address2); diff --git a/src/storage/key.rs b/src/storage/key.rs index 4bf77a0..34f706a 100644 --- a/src/storage/key.rs +++ b/src/storage/key.rs @@ -1,19 +1,30 @@ -use crate::WaPtr; +use crate::{AsBytes, FromBytes, WaPtr}; #[derive(Clone, Copy, Eq, PartialEq)] -pub struct StorageKey { - pub bytes: [u8; crate::constant::STORE_KEY_BYTE_LENGTH], -} +#[repr(transparent)] +pub struct StorageKey(pub [u8; crate::constant::STORE_KEY_BYTE_LENGTH]); impl StorageKey { pub const fn new(bytes: [u8; crate::constant::STORE_KEY_BYTE_LENGTH]) -> Self { - Self { bytes } + Self(bytes) } pub fn mut_ptr(&mut self) -> WaPtr { - WaPtr(self.bytes.as_mut_ptr() as *mut u8 as u32) + WaPtr(self.0.as_mut_ptr() as *mut u8 as u32) } pub fn ptr(&self) -> WaPtr { - WaPtr(self.bytes.as_ptr() as *const u8 as u32) + WaPtr(self.0.as_ptr() as *const u8 as u32) + } +} + +impl AsBytes for StorageKey { + fn as_bytes(&self) -> &[u8] { + &self.0 + } +} + +impl FromBytes for StorageKey { + fn from_bytes(bytes: &[u8]) -> Self { + Self(bytes.try_into().unwrap()) } } diff --git a/src/storage/multi_address_map.rs b/src/storage/multi_address_map.rs index eaed231..0feb73d 100644 --- a/src/storage/multi_address_map.rs +++ b/src/storage/multi_address_map.rs @@ -73,7 +73,7 @@ mod tests { StorageValue::ZERO.as_bytes() ); - merger1.set(&address2, StorageValue::from_bytes(one)); + merger1.set(&address2, StorageValue::new(one)); assert_eq!(merger1.get(&address2).as_bytes(), &one); let mut mamm2 = MultiAddressMemoryMap::new(context.clone(), 0, StorageValue::ZERO); diff --git a/src/storage/stored.rs b/src/storage/stored.rs index 2ddf953..53b463b 100644 --- a/src/storage/stored.rs +++ b/src/storage/stored.rs @@ -104,7 +104,7 @@ where ) -> Self { Self { context, - pointer: encode_pointer(pointer, &sub_pointer.bytes), + pointer: encode_pointer(pointer, &sub_pointer.0), default_value, value: None, } diff --git a/src/storage/stored_map.rs b/src/storage/stored_map.rs index caf41de..365f943 100644 --- a/src/storage/stored_map.rs +++ b/src/storage/stored_map.rs @@ -1,7 +1,7 @@ -use core::{cell::RefCell, marker::PhantomData}; +use core::marker::PhantomData; use ethnum::u256; -use crate::{blockchain::AddressHash, math::abi::encode_pointer, Context}; +use crate::{blockchain::AddressHash, math::abi::encode_pointer, AsBytes, Context}; use super::{StorageKey, StorageValue}; use alloc::rc::Rc; @@ -35,14 +35,14 @@ where pub fn set(&self, key: &K, value: V) { let key: StorageKey = (*key).into(); - let key_hash = encode_pointer(self.pointer, &key.bytes); + let key_hash = encode_pointer(self.pointer, &key.0); let value = Into::::into(value); self.context.store(key_hash, value); } pub fn get(&self, key: &K) -> V { let key: StorageKey = (*key).into(); - let key_hash = encode_pointer(self.pointer, &key.bytes); + let key_hash = encode_pointer(self.pointer, &key.0); self.context .load(&key_hash) .map(|value| V::from(value)) @@ -51,7 +51,7 @@ where pub fn contains_key(&self, key: &K) -> bool { let key: StorageKey = (*key).into(); - let key_hash = encode_pointer(self.pointer, &key.bytes); + let key_hash = encode_pointer(self.pointer, key.as_bytes()); let has = self.context.exists(&key_hash); has } @@ -76,7 +76,7 @@ mod tests { let address1 = random_address(); let sm: StoredMap = StoredMap::new(context.clone(), 0, StorageValue::ZERO); - sm.set(&address1, StorageValue::from_bytes(one)); + sm.set(&address1, StorageValue::new(one)); assert_eq!(sm.get(&address1).as_bytes(), &one); } } diff --git a/src/storage/value.rs b/src/storage/value.rs index 39a20a4..ddbc49c 100644 --- a/src/storage/value.rs +++ b/src/storage/value.rs @@ -1,91 +1,94 @@ use ethnum::u256; -use crate::{AsBytes, WaPtr}; +use crate::{AsBytes, FromBytes, WaPtr}; #[derive(Copy, Clone, Eq, PartialEq)] -pub struct StorageValue { - inner: [u8; crate::constant::STORE_VALUE_BYTE_LENGTH], -} +#[repr(transparent)] +pub struct StorageValue(pub [u8; crate::constant::STORE_VALUE_BYTE_LENGTH]); impl StorageValue { - pub const ZERO: StorageValue = StorageValue { - inner: [0; crate::constant::STORE_VALUE_BYTE_LENGTH], - }; + pub const ZERO: StorageValue = StorageValue([0; crate::constant::STORE_VALUE_BYTE_LENGTH]); - pub fn mut_ptr(&mut self) -> WaPtr { - WaPtr(self.inner.as_mut_ptr() as *mut u8 as u32) + pub fn new(bytes: [u8; crate::constant::STORE_VALUE_BYTE_LENGTH]) -> Self { + Self(bytes) } - pub fn ptr(&self) -> WaPtr { - WaPtr(self.inner.as_ptr() as *const u8 as u32) + pub fn mut_ptr(&mut self) -> WaPtr { + WaPtr(self.0.as_mut_ptr() as *mut u8 as u32) } - pub fn from_bytes(bytes: [u8; crate::constant::STORE_VALUE_BYTE_LENGTH]) -> Self { - Self { inner: bytes } + pub fn ptr(&self) -> WaPtr { + WaPtr(self.0.as_ptr() as *const u8 as u32) } pub fn value(&self) -> [u8; crate::constant::STORE_VALUE_BYTE_LENGTH] { - self.inner + self.0 } pub fn bool(&self) -> bool { - self.inner.iter().any(|v| 0.le(v)) + self.0.iter().any(|v| 0.le(v)) } pub fn zero(&self) -> bool { - self.inner.iter().all(|v| 0.eq(v)) + self.0.iter().all(|v| 0.eq(v)) } pub fn u8(&self) -> u8 { - self.inner[31] + self.0[31] } pub fn u16(&self) -> u16 { - u16::from_be_bytes(self.inner[30..32].try_into().unwrap()) + u16::from_be_bytes(self.0[30..32].try_into().unwrap()) } pub fn u32(&self) -> u32 { - u32::from_be_bytes(self.inner[28..32].try_into().unwrap()) + u32::from_be_bytes(self.0[28..32].try_into().unwrap()) } pub fn u64(&self) -> u64 { - u64::from_be_bytes(self.inner[24..32].try_into().unwrap()) + u64::from_be_bytes(self.0[24..32].try_into().unwrap()) } pub fn u128(&self) -> u128 { - u128::from_be_bytes(self.inner[16..32].try_into().unwrap()) + u128::from_be_bytes(self.0[16..32].try_into().unwrap()) } pub fn u256(&self) -> u256 { - u256::from_be_bytes(self.inner) + u256::from_be_bytes(self.0) } } impl AsBytes for StorageValue { fn as_bytes(&self) -> &[u8] { - &self.inner + &self.0 + } +} + +impl FromBytes for StorageValue { + fn from_bytes(bytes: &[u8]) -> Self { + let mut inner = [0u8; crate::constant::STORE_VALUE_BYTE_LENGTH]; + let length = bytes.len().min(crate::constant::STORE_VALUE_BYTE_LENGTH); + + inner[32 - length..32].copy_from_slice(&bytes[0..length]); + StorageValue(inner) } } impl From<[u8; crate::constant::STORE_VALUE_BYTE_LENGTH]> for StorageValue { fn from(value: [u8; crate::constant::STORE_VALUE_BYTE_LENGTH]) -> Self { - StorageValue { inner: value } + StorageValue(value) } } impl From<&[u8; crate::constant::STORE_VALUE_BYTE_LENGTH]> for StorageValue { fn from(value: &[u8; crate::constant::STORE_VALUE_BYTE_LENGTH]) -> Self { - StorageValue { inner: *value } + StorageValue(*value) } } impl From<&[u8]> for StorageValue { fn from(value: &[u8]) -> Self { - let mut inner = [0u8; crate::constant::STORE_VALUE_BYTE_LENGTH]; - let length = value.len().min(crate::constant::STORE_VALUE_BYTE_LENGTH); - - inner[32 - length..32].copy_from_slice(&value[0..length]); - StorageValue { inner } + StorageValue::from_bytes(value) } }