From 93bd746d77c319796898592b2fd4b8aef7a6a7ce Mon Sep 17 00:00:00 2001 From: Alan Orwick Date: Mon, 2 Oct 2023 11:59:40 -0500 Subject: [PATCH] Add testing for Wasm implementation --- core/vm/logger_test.go | 71 + core/vm/wasm_contracts/get_address/build.sh | 2 + .../wasm_contracts/get_address/get_address.go | 82 + .../get_address/get_address.wasm | Bin 0 -> 7403 bytes .../wasm_contracts/get_block_number/build.sh | 2 + .../get_block_number/get_block_number.go | 33 + .../get_block_number/get_block_number.wasm | Bin 0 -> 7098 bytes core/vm/wasm_contracts/get_caller/build.sh | 2 + .../wasm_contracts/get_caller/get_caller.go | 81 + .../wasm_contracts/get_caller/get_caller.wasm | Bin 0 -> 7401 bytes .../wasm_contracts/get_caller/get_caller.wat | 2807 +++++++++++++++++ core/vm/wasm_contracts/hello/build.sh | 2 + core/vm/wasm_contracts/hello/hello.go | 47 + core/vm/wasm_contracts/hello/hello.wasm | Bin 0 -> 6335 bytes core/vm/wasm_contracts/use_gas/build.sh | 2 + core/vm/wasm_contracts/use_gas/use_gas.go | 14 + core/vm/wasm_contracts/use_gas/use_gas.wasm | Bin 0 -> 6064 bytes core/vm/wasm_interpreter_test.go | 163 + 18 files changed, 3308 insertions(+) create mode 100644 core/vm/logger_test.go create mode 100755 core/vm/wasm_contracts/get_address/build.sh create mode 100644 core/vm/wasm_contracts/get_address/get_address.go create mode 100755 core/vm/wasm_contracts/get_address/get_address.wasm create mode 100755 core/vm/wasm_contracts/get_block_number/build.sh create mode 100644 core/vm/wasm_contracts/get_block_number/get_block_number.go create mode 100755 core/vm/wasm_contracts/get_block_number/get_block_number.wasm create mode 100755 core/vm/wasm_contracts/get_caller/build.sh create mode 100644 core/vm/wasm_contracts/get_caller/get_caller.go create mode 100755 core/vm/wasm_contracts/get_caller/get_caller.wasm create mode 100644 core/vm/wasm_contracts/get_caller/get_caller.wat create mode 100755 core/vm/wasm_contracts/hello/build.sh create mode 100644 core/vm/wasm_contracts/hello/hello.go create mode 100755 core/vm/wasm_contracts/hello/hello.wasm create mode 100755 core/vm/wasm_contracts/use_gas/build.sh create mode 100644 core/vm/wasm_contracts/use_gas/use_gas.go create mode 100755 core/vm/wasm_contracts/use_gas/use_gas.wasm create mode 100644 core/vm/wasm_interpreter_test.go diff --git a/core/vm/logger_test.go b/core/vm/logger_test.go new file mode 100644 index 0000000000..ab2ad7d23b --- /dev/null +++ b/core/vm/logger_test.go @@ -0,0 +1,71 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package vm + +import ( + "math/big" + + "github.com/dominant-strategies/go-quai/common" + "github.com/dominant-strategies/go-quai/core/state" +) + +type dummyContractRef struct { + calledForEach bool +} + +func (dummyContractRef) Address() common.Address { return common.Address{} } +func (dummyContractRef) Value() *big.Int { return new(big.Int) } +func (dummyContractRef) SetCode(common.Hash, []byte) {} +func (d *dummyContractRef) ForEachStorage(callback func(key, value common.Hash) bool) { + d.calledForEach = true +} +func (d *dummyContractRef) SubBalance(amount *big.Int) {} +func (d *dummyContractRef) AddBalance(amount *big.Int) {} +func (d *dummyContractRef) SetBalance(*big.Int) {} +func (d *dummyContractRef) SetNonce(uint64) {} +func (d *dummyContractRef) Balance() *big.Int { return new(big.Int) } + +type dummyStatedb struct { + state.StateDB +} + +func (*dummyStatedb) GetRefund() uint64 { return 1337 } + +// func TestStoreCapture(t *testing.T) { +// var ( +// env = NewEVM(BlockContext{}, TxContext{}, &dummyStatedb{}, params.TestChainConfig, Config{}) +// logger = NewStructLogger(nil) +// contract = NewContract(&dummyContractRef{}, &dummyContractRef{}, new(big.Int), 0) +// scope = &ScopeContext{ +// Memory: NewMemory(), +// Stack: newstack(), +// Contract: contract, +// } +// ) +// scope.Stack.push(uint256.NewInt(1)) +// scope.Stack.push(new(uint256.Int)) +// var index common.Hash +// logger.CaptureState(env, 0, SSTORE, 0, 0, scope, nil, 0, nil) +// if len(logger.storage[contract.Address()]) == 0 { +// t.Fatalf("expected exactly 1 changed value on address %x, got %d", contract.Address(), +// len(logger.storage[contract.Address()])) +// } +// exp := common.BigToHash(big.NewInt(1)) +// if logger.storage[contract.Address()][index] != exp { +// t.Errorf("expected %x, got %x", exp, logger.storage[contract.Address()][index]) +// } +// } diff --git a/core/vm/wasm_contracts/get_address/build.sh b/core/vm/wasm_contracts/get_address/build.sh new file mode 100755 index 0000000000..732ba6c708 --- /dev/null +++ b/core/vm/wasm_contracts/get_address/build.sh @@ -0,0 +1,2 @@ +#!/bin/bash +tinygo build -o get_address.wasm -scheduler=none --no-debug -target wasi ./get_address.go \ No newline at end of file diff --git a/core/vm/wasm_contracts/get_address/get_address.go b/core/vm/wasm_contracts/get_address/get_address.go new file mode 100644 index 0000000000..5b1665fdec --- /dev/null +++ b/core/vm/wasm_contracts/get_address/get_address.go @@ -0,0 +1,82 @@ +package main + +// import "unsafe" + +// // main is required for TinyGo to compile to Wasm. +// func main() {} + +// //export run +// //go:linkname run +// func run() { +// var address [8]uint32 +// rawAddress := uintptr(unsafe.Pointer(&address[0])) +// int32Address := (*int32)(unsafe.Pointer(rawAddress)) +// getAddress(int32Address) +// } + +// //export getAddress +// //go:linkname getAddress +// func getAddress(resultOffset int32) + +/* +#include + +extern void getAddress(uint32_t *offset); +extern void storageStore(uint32_t *keyOffset, uint32_t *valueOffset); +*/ +import ( + "reflect" + "strconv" + "unsafe" +) + +func main() {} + +//export hostLogString +//go:linkname hostLogString +func hostLogString(offset uint32, byteCount uint32) + +//export run +//go:linkname run +func run() { + var address string + rawAddress := uintptr(unsafe.Pointer(&address)) + + int32RawAddress := int32(int64(rawAddress)) + + getAddress(int32RawAddress) + + addressString := ptrToString(uint32(rawAddress), 42) + + hostLogString(strToPtr(addressString)) + hostLogString(strToPtr("pointer " + strconv.Itoa(int(int32RawAddress)))) + hostLogString(strToPtr("Hello from wasm")) + +} + +//export getAddress +//go:linkname getAddress +func getAddress(resultOffset int32) + + +// ptrToString returns a string from WebAssembly compatible numeric types +// representing its pointer and length. +func ptrToString(ptr uint32, size uint32) string { + // Get a slice view of the underlying bytes in the stream. We use SliceHeader, not StringHeader + // as it allows us to fix the capacity to what was allocated. + return *(*string)(unsafe.Pointer(&reflect.SliceHeader{ + Data: uintptr(ptr), + Len: uintptr(size), // Tinygo requires these as uintptrs even if they are int fields. + Cap: uintptr(size), // ^^ See https://github.com/tinygo-org/tinygo/issues/1284 + })) +} + + +// strToPtr returns a pointer and size pair for the given string in a way +// compatible with WebAssembly numeric types. +func strToPtr(s string) (uint32, uint32) { + buf := []byte(s) + ptr := &buf[0] + unsafePtr := uintptr(unsafe.Pointer(ptr)) + return uint32(unsafePtr), uint32(len(buf)) +} \ No newline at end of file diff --git a/core/vm/wasm_contracts/get_address/get_address.wasm b/core/vm/wasm_contracts/get_address/get_address.wasm new file mode 100755 index 0000000000000000000000000000000000000000..4d328be009f900cadc6bc4a3726ce461a8663720 GIT binary patch literal 7403 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 + +extern void getAddress(uint32_t *offset); +extern void storageStore(uint32_t *keyOffset, uint32_t *valueOffset); +*/ +import ( + "reflect" + "strconv" + "unsafe" +) + +func main() {} + +//export hostLogString +//go:linkname hostLogString +func hostLogString(offset uint32, byteCount uint32) + +//export run +//go:linkname run +func run() { + var address string + rawAddress := uintptr(unsafe.Pointer(&address)) + + int32RawAddress := int32(int64(rawAddress)) + + getCaller(int32RawAddress) + + addressString := ptrToString(uint32(rawAddress), 42) + + hostLogString(strToPtr(addressString)) + hostLogString(strToPtr("pointer " + strconv.Itoa(int(int32RawAddress)))) + hostLogString(strToPtr("Hello from wasm")) +} + +//export getCaller +//go:linkname getCaller +func getCaller(resultOffset int32) + + +// ptrToString returns a string from WebAssembly compatible numeric types +// representing its pointer and length. +func ptrToString(ptr uint32, size uint32) string { + // Get a slice view of the underlying bytes in the stream. We use SliceHeader, not StringHeader + // as it allows us to fix the capacity to what was allocated. + return *(*string)(unsafe.Pointer(&reflect.SliceHeader{ + Data: uintptr(ptr), + Len: uintptr(size), // Tinygo requires these as uintptrs even if they are int fields. + Cap: uintptr(size), // ^^ See https://github.com/tinygo-org/tinygo/issues/1284 + })) +} + + +// strToPtr returns a pointer and size pair for the given string in a way +// compatible with WebAssembly numeric types. +func strToPtr(s string) (uint32, uint32) { + buf := []byte(s) + ptr := &buf[0] + unsafePtr := uintptr(unsafe.Pointer(ptr)) + return uint32(unsafePtr), uint32(len(buf)) +} \ No newline at end of file diff --git a/core/vm/wasm_contracts/get_caller/get_caller.wasm b/core/vm/wasm_contracts/get_caller/get_caller.wasm new file mode 100755 index 0000000000000000000000000000000000000000..910efe4fdd81e2740137042d959c4fe4d96ce217 GIT binary patch literal 7401 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 literal 0 HcmV?d00001 diff --git a/core/vm/wasm_contracts/get_caller/get_caller.wat b/core/vm/wasm_contracts/get_caller/get_caller.wat new file mode 100644 index 0000000000..011af97ee4 --- /dev/null +++ b/core/vm/wasm_contracts/get_caller/get_caller.wat @@ -0,0 +1,2807 @@ +(module + (type (;0;) (func (param i32 i32 i32 i32) (result i32))) + (type (;1;) (func (param i32))) + (type (;2;) (func (param i32 i32))) + (type (;3;) (func)) + (type (;4;) (func (param i32) (result i32))) + (type (;5;) (func (param i32 i32) (result i32))) + (type (;6;) (func (result i32))) + (type (;7;) (func (param i32 i32 i32 i32))) + (type (;8;) (func (param i32 i32 i32))) + (import "wasi_snapshot_preview1" "fd_write" (func (;0;) (type 0))) + (import "env" "getCaller" (func (;1;) (type 1))) + (import "env" "hostLogString" (func (;2;) (type 2))) + (func (;3;) (type 0) (param i32 i32 i32 i32) (result i32) + (local i32 i32) + i32.const 0 + local.set 3 + block (result i32) ;; label = @1 + loop ;; label = @2 + local.get 2 + local.get 2 + local.get 3 + i32.eq + br_if 1 (;@1;) + drop + local.get 1 + local.get 3 + i32.add + local.set 4 + local.get 0 + local.get 3 + i32.add + local.get 3 + i32.const 1 + i32.add + local.set 3 + i32.load8_u + local.get 4 + i32.load8_u + i32.eq + br_if 0 (;@2;) + end + local.get 3 + i32.const 1 + i32.sub + end + local.get 2 + i32.ge_u) + (func (;4;) (type 0) (param i32 i32 i32 i32) (result i32) + local.get 1 + i32.const -962287725 + i32.mul + local.get 2 + i32.xor + i32.const -1130422988 + i32.xor + local.set 2 + loop ;; label = @1 + local.get 1 + i32.const 4 + i32.lt_s + i32.eqz + if ;; label = @2 + local.get 0 + i32.load align=1 + local.get 2 + i32.add + i32.const -962287725 + i32.mul + local.tee 2 + i32.const 16 + i32.shr_u + local.get 2 + i32.xor + local.set 2 + local.get 1 + i32.const 4 + i32.sub + local.set 1 + local.get 0 + i32.const 4 + i32.add + local.set 0 + br 1 (;@1;) + end + end + block ;; label = @1 + block ;; label = @2 + block ;; label = @3 + block ;; label = @4 + local.get 1 + i32.const 1 + i32.sub + br_table 2 (;@2;) 1 (;@3;) 0 (;@4;) 3 (;@1;) + end + local.get 0 + i32.load8_u offset=2 + i32.const 16 + i32.shl + local.get 2 + i32.add + local.set 2 + end + local.get 0 + i32.load8_u offset=1 + i32.const 8 + i32.shl + local.get 2 + i32.add + local.set 2 + end + local.get 2 + local.get 0 + i32.load8_u + i32.add + i32.const -962287725 + i32.mul + local.tee 0 + i32.const 24 + i32.shr_u + local.get 0 + i32.xor + local.set 2 + end + local.get 2) + (func (;5;) (type 3) + i32.const 65905 + i32.const 18 + call 6 + unreachable) + (func (;6;) (type 2) (param i32 i32) + i32.const 65860 + i32.const 22 + call 8 + local.get 0 + local.get 1 + call 8 + i32.const 10 + call 9 + unreachable) + (func (;7;) (type 3) + i32.const 65923 + i32.const 18 + call 6 + unreachable) + (func (;8;) (type 2) (param i32 i32) + local.get 1 + i32.const 0 + local.get 1 + i32.const 0 + i32.gt_s + select + local.set 1 + loop ;; label = @1 + local.get 1 + if ;; label = @2 + local.get 0 + i32.load8_u + call 9 + local.get 1 + i32.const 1 + i32.sub + local.set 1 + local.get 0 + i32.const 1 + i32.add + local.set 0 + br 1 (;@1;) + end + end) + (func (;9;) (type 1) (param i32) + (local i32 i32) + i32.const 66012 + i32.load + local.tee 1 + i32.const 119 + i32.le_u + if ;; label = @1 + i32.const 66012 + local.get 1 + i32.const 1 + i32.add + local.tee 2 + i32.store + local.get 1 + i32.const 66016 + i32.add + local.get 0 + i32.store8 + local.get 0 + i32.const 255 + i32.and + i32.const 10 + i32.ne + local.get 1 + i32.const 119 + i32.ne + i32.and + i32.eqz + if ;; label = @2 + i32.const 65964 + local.get 2 + i32.store + i32.const 1 + i32.const 65960 + i32.const 1 + i32.const 66184 + call 0 + drop + i32.const 66012 + i32.const 0 + i32.store + end + return + end + call 5 + unreachable) + (func (;10;) (type 4) (param i32) (result i32) + (local i32 i32 i32 i32 i32 i32 i32) + local.get 0 + i32.eqz + if ;; label = @1 + i32.const 66176 + return + end + i32.const 66152 + i32.const 66152 + i64.load + local.get 0 + i64.extend_i32_u + i64.add + i64.store + i32.const 66160 + i32.const 66160 + i64.load + i64.const 1 + i64.add + i64.store + local.get 0 + i32.const 15 + i32.add + i32.const 4 + i32.shr_u + local.set 5 + i32.const 66140 + i32.load + local.tee 4 + local.set 3 + loop ;; label = @1 + block ;; label = @2 + block ;; label = @3 + block ;; label = @4 + block ;; label = @5 + local.get 3 + local.get 4 + i32.ne + if ;; label = @6 + local.get 2 + local.set 1 + br 1 (;@5;) + end + i32.const 1 + local.set 1 + block ;; label = @6 + block ;; label = @7 + local.get 2 + i32.const 255 + i32.and + br_table 2 (;@5;) 0 (;@7;) 1 (;@6;) + end + i32.const 66180 + i32.load + drop + global.get 0 + i32.const 65536 + call 11 + i32.const 65536 + i32.const 66480 + call 11 + loop ;; label = @7 + i32.const 66177 + i32.load8_u + i32.eqz + if ;; label = @8 + i32.const 0 + local.set 2 + i32.const 0 + local.set 4 + i32.const 0 + local.set 1 + loop ;; label = @9 + block ;; label = @10 + block ;; label = @11 + i32.const 66144 + i32.load + local.get 1 + i32.gt_u + if ;; label = @12 + block ;; label = @13 + block ;; label = @14 + block ;; label = @15 + block ;; label = @16 + local.get 1 + call 12 + i32.const 255 + i32.and + br_table 3 (;@13;) 0 (;@16;) 1 (;@15;) 2 (;@14;) 6 (;@10;) + end + local.get 1 + call 13 + i32.const 66168 + i32.const 66168 + i64.load + i64.const 1 + i64.add + i64.store + br 4 (;@11;) + end + local.get 4 + i32.const 1 + i32.and + i32.const 0 + local.set 4 + i32.eqz + br_if 4 (;@10;) + local.get 1 + call 13 + br 3 (;@11;) + end + i32.const 0 + local.set 4 + i32.const 66136 + i32.load + local.get 1 + i32.const 2 + i32.shr_u + i32.add + local.tee 6 + local.get 6 + i32.load8_u + i32.const 2 + local.get 1 + i32.const 1 + i32.shl + i32.const 6 + i32.and + i32.shl + i32.const -1 + i32.xor + i32.and + i32.store8 + br 3 (;@10;) + end + local.get 2 + i32.const 16 + i32.add + local.set 2 + br 2 (;@10;) + end + i32.const 2 + local.set 1 + local.get 2 + i32.const 66136 + i32.load + i32.const 66480 + i32.sub + i32.const 3 + i32.div_u + i32.ge_u + br_if 6 (;@5;) + call 14 + drop + br 6 (;@5;) + end + local.get 2 + i32.const 16 + i32.add + local.set 2 + i32.const 1 + local.set 4 + end + local.get 1 + i32.const 1 + i32.add + local.set 1 + br 0 (;@9;) + end + unreachable + end + i32.const 0 + local.set 1 + i32.const 66177 + i32.const 0 + i32.store8 + i32.const 66144 + i32.load + local.set 2 + loop ;; label = @8 + local.get 1 + local.get 2 + i32.ge_u + br_if 1 (;@7;) + local.get 1 + call 12 + i32.const 255 + i32.and + i32.const 3 + i32.eq + if ;; label = @9 + local.get 1 + call 15 + i32.const 66144 + i32.load + local.set 2 + end + local.get 1 + i32.const 1 + i32.add + local.set 1 + br 0 (;@8;) + end + unreachable + end + unreachable + end + local.get 2 + local.set 1 + call 14 + i32.const 1 + i32.and + i32.eqz + br_if 1 (;@4;) + end + i32.const 66144 + i32.load + local.get 3 + i32.eq + if ;; label = @5 + i32.const 0 + local.set 3 + br 2 (;@3;) + end + local.get 3 + call 12 + i32.const 255 + i32.and + if ;; label = @5 + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 2 (;@3;) + end + local.get 3 + i32.const 1 + i32.add + local.set 2 + local.get 5 + local.get 7 + i32.const 1 + i32.add + local.tee 7 + i32.ne + if ;; label = @5 + local.get 2 + local.set 3 + br 3 (;@2;) + end + i32.const 66140 + local.get 2 + i32.store + local.get 2 + local.get 5 + i32.sub + local.tee 2 + i32.const 1 + call 16 + local.get 3 + local.get 5 + i32.sub + i32.const 2 + i32.add + local.set 1 + loop ;; label = @5 + i32.const 66140 + i32.load + local.get 1 + i32.ne + if ;; label = @6 + local.get 1 + i32.const 2 + call 16 + local.get 1 + i32.const 1 + i32.add + local.set 1 + br 1 (;@5;) + end + end + local.get 2 + i32.const 4 + i32.shl + i32.const 66480 + i32.add + local.tee 2 + i32.const 0 + local.get 0 + memory.fill + local.get 2 + return + end + i32.const 65840 + i32.const 13 + call 6 + unreachable + end + i32.const 0 + local.set 7 + end + i32.const 66140 + i32.load + local.set 4 + local.get 1 + local.set 2 + br 0 (;@1;) + end + unreachable) + (func (;11;) (type 2) (param i32 i32) + (local i32) + loop ;; label = @1 + local.get 0 + local.get 1 + i32.ge_u + i32.eqz + if ;; label = @2 + block ;; label = @3 + local.get 0 + i32.load + local.tee 2 + i32.const 66480 + i32.lt_u + br_if 0 (;@3;) + local.get 2 + i32.const 66136 + i32.load + i32.ge_u + br_if 0 (;@3;) + local.get 2 + i32.const 66480 + i32.sub + i32.const 4 + i32.shr_u + local.tee 2 + call 12 + i32.const 255 + i32.and + i32.eqz + br_if 0 (;@3;) + local.get 2 + call 19 + local.tee 2 + call 12 + i32.const 255 + i32.and + i32.const 3 + i32.eq + br_if 0 (;@3;) + local.get 2 + call 15 + end + local.get 0 + i32.const 4 + i32.add + local.set 0 + br 1 (;@1;) + end + end) + (func (;12;) (type 4) (param i32) (result i32) + i32.const 66136 + i32.load + local.get 0 + i32.const 2 + i32.shr_u + i32.add + i32.load8_u + local.get 0 + i32.const 1 + i32.shl + i32.const 6 + i32.and + i32.shr_u + i32.const 3 + i32.and) + (func (;13;) (type 1) (param i32) + (local i32) + i32.const 66136 + i32.load + local.get 0 + i32.const 2 + i32.shr_u + i32.add + local.tee 1 + local.get 1 + i32.load8_u + i32.const 3 + local.get 0 + i32.const 1 + i32.shl + i32.const 6 + i32.and + i32.shl + i32.const -1 + i32.xor + i32.and + i32.store8) + (func (;14;) (type 6) (result i32) + (local i32 i32 i32) + memory.size + memory.grow + i32.const -1 + i32.ne + local.tee 1 + if ;; label = @1 + memory.size + local.set 0 + i32.const 66008 + i32.load + local.set 2 + i32.const 66008 + local.get 0 + i32.const 16 + i32.shl + i32.store + i32.const 66136 + i32.load + local.set 0 + call 18 + i32.const 66136 + i32.load + local.get 0 + local.get 2 + local.get 0 + i32.sub + memory.copy + end + local.get 1) + (func (;15;) (type 1) (param i32) + (local i32 i32 i32 i32 i32 i32 i32 i32) + global.get 0 + i32.const -64 + i32.add + local.tee 4 + global.set 0 + local.get 4 + i32.const 4 + i32.add + i32.const 0 + i32.const 60 + memory.fill + local.get 4 + local.get 0 + i32.store + local.get 0 + i32.const 3 + call 16 + i32.const 1 + local.set 1 + block ;; label = @1 + loop ;; label = @2 + local.get 1 + i32.const 0 + i32.gt_s + if ;; label = @3 + local.get 1 + i32.const 1 + i32.sub + local.tee 1 + i32.const 15 + i32.gt_u + br_if 2 (;@1;) + local.get 4 + local.get 1 + i32.const 2 + i32.shl + i32.add + i32.load + local.tee 3 + i32.const 4 + i32.shl + local.set 0 + block ;; label = @4 + block ;; label = @5 + local.get 3 + call 12 + i32.const 255 + i32.and + i32.const 1 + i32.sub + br_table 0 (;@5;) 1 (;@4;) 0 (;@5;) 1 (;@4;) + end + local.get 3 + i32.const 1 + i32.add + local.set 3 + end + local.get 0 + i32.const 66480 + i32.add + local.set 6 + local.get 3 + i32.const 4 + i32.shl + local.tee 5 + local.get 0 + i32.sub + local.set 2 + local.get 5 + i32.const 66480 + i32.add + local.set 5 + i32.const 66136 + i32.load + local.set 7 + loop ;; label = @4 + block ;; label = @5 + local.get 2 + local.set 0 + local.get 5 + local.get 7 + i32.ge_u + br_if 0 (;@5;) + local.get 0 + i32.const 16 + i32.add + local.set 2 + local.get 5 + i32.const 16 + i32.add + local.set 5 + local.get 3 + call 12 + local.get 3 + i32.const 1 + i32.add + local.set 3 + i32.const 255 + i32.and + i32.const 2 + i32.eq + br_if 1 (;@4;) + end + end + loop ;; label = @4 + local.get 0 + i32.eqz + br_if 2 (;@2;) + block ;; label = @5 + local.get 6 + i32.load + local.tee 2 + i32.const 66480 + i32.lt_u + br_if 0 (;@5;) + local.get 2 + i32.const 66136 + i32.load + i32.ge_u + br_if 0 (;@5;) + local.get 2 + i32.const 66480 + i32.sub + i32.const 4 + i32.shr_u + local.tee 2 + call 12 + i32.const 255 + i32.and + i32.eqz + br_if 0 (;@5;) + local.get 2 + call 19 + local.tee 2 + call 12 + i32.const 255 + i32.and + i32.const 3 + i32.eq + br_if 0 (;@5;) + local.get 2 + i32.const 3 + call 16 + local.get 1 + i32.const 16 + i32.eq + if ;; label = @6 + i32.const 66177 + i32.const 1 + i32.store8 + i32.const 16 + local.set 1 + br 1 (;@5;) + end + local.get 1 + i32.const 15 + i32.gt_u + br_if 4 (;@1;) + local.get 4 + local.get 1 + i32.const 2 + i32.shl + i32.add + local.get 2 + i32.store + local.get 1 + i32.const 1 + i32.add + local.set 1 + end + local.get 0 + i32.const 4 + i32.sub + local.set 0 + local.get 6 + i32.const 4 + i32.add + local.set 6 + br 0 (;@4;) + end + unreachable + end + end + local.get 4 + i32.const -64 + i32.sub + global.set 0 + return + end + call 5 + unreachable) + (func (;16;) (type 2) (param i32 i32) + (local i32) + i32.const 66136 + i32.load + local.get 0 + i32.const 2 + i32.shr_u + i32.add + local.tee 2 + local.get 2 + i32.load8_u + local.get 1 + local.get 0 + i32.const 1 + i32.shl + i32.const 6 + i32.and + i32.shl + i32.or + i32.store8) + (func (;17;) (type 3) + i32.const 65882 + i32.const 23 + call 6 + unreachable) + (func (;18;) (type 3) + (local i32) + i32.const 66136 + i32.const 66008 + i32.load + local.tee 0 + local.get 0 + i32.const 66416 + i32.sub + i32.const 65 + i32.div_u + i32.sub + local.tee 0 + i32.store + i32.const 66144 + local.get 0 + i32.const 66480 + i32.sub + i32.const 4 + i32.shr_u + i32.store) + (func (;19;) (type 4) (param i32) (result i32) + (local i32) + loop ;; label = @1 + local.get 0 + call 12 + local.get 0 + i32.const 1 + i32.sub + local.set 0 + i32.const 255 + i32.and + i32.const 2 + i32.eq + br_if 0 (;@1;) + end + local.get 0 + i32.const 1 + i32.add) + (func (;20;) (type 4) (param i32) (result i32) + (local i32 i32 i32) + global.get 0 + i32.const 32 + i32.sub + local.tee 1 + global.set 0 + local.get 1 + i32.const 2 + i32.store offset=20 + i32.const 66180 + i32.load + local.set 3 + i32.const 66180 + local.get 1 + i32.const 16 + i32.add + i32.store + local.get 1 + local.get 3 + i32.store offset=16 + block ;; label = @1 + local.get 0 + if ;; label = @2 + local.get 0 + i32.const 0 + i32.lt_s + br_if 1 (;@1;) + local.get 1 + local.get 0 + call 10 + local.tee 2 + i32.store offset=24 + local.get 1 + local.get 2 + i32.store offset=28 + local.get 1 + local.get 0 + i32.store offset=8 + local.get 1 + local.get 0 + i32.store offset=4 + local.get 1 + local.get 2 + i32.store + local.get 1 + local.get 2 + i32.store offset=12 + local.get 1 + i32.const 12 + i32.add + local.get 1 + call 21 + end + i32.const 66180 + local.get 3 + i32.store + local.get 1 + i32.const 32 + i32.add + global.set 0 + local.get 2 + return + end + call 7 + unreachable) + (func (;21;) (type 2) (param i32 i32) + i32.const 65968 + local.get 0 + local.get 1 + local.get 0 + i32.const 65980 + i32.load + i32.const 65972 + i32.load + local.get 0 + call 4 + call 30) + (func (;22;) (type 1) (param i32) + (local i32) + global.get 0 + i32.const 16 + i32.sub + local.tee 1 + global.set 0 + block ;; label = @1 + local.get 0 + if ;; label = @2 + local.get 1 + local.get 0 + i32.store offset=12 + local.get 1 + i32.const 12 + i32.add + local.get 1 + call 23 + i32.const 1 + i32.and + i32.eqz + br_if 1 (;@1;) + local.get 1 + local.get 0 + i32.store + local.get 1 + call 24 + end + local.get 1 + i32.const 16 + i32.add + global.set 0 + return + end + i32.const 65800 + call 25 + unreachable) + (func (;23;) (type 5) (param i32 i32) (result i32) + i32.const 65968 + local.get 0 + local.get 1 + local.get 0 + i32.const 65980 + i32.load + i32.const 65972 + i32.load + local.get 0 + call 4 + call 29) + (func (;24;) (type 1) (param i32) + (local i32 i32 i32 i32 i32 i32 i32 i32 i32) + global.get 0 + i32.const 32 + i32.sub + local.tee 1 + global.set 0 + local.get 1 + i32.const 24 + i32.add + i64.const 0 + i64.store + local.get 1 + i64.const 0 + i64.store offset=16 + local.get 1 + i32.const 6 + i32.store offset=4 + i32.const 66180 + i32.load + local.set 6 + i32.const 66180 + local.get 1 + i32.store + local.get 1 + local.get 6 + i32.store + local.get 0 + i32.const 65980 + i32.load + local.tee 3 + i32.const 65972 + i32.load + i32.const 0 + call 4 + local.set 2 + local.get 1 + i32.const 65968 + i32.load + local.tee 4 + i32.store offset=8 + local.get 2 + i32.const 24 + i32.shr_u + local.tee 5 + i32.const 1 + local.get 5 + select + local.set 7 + local.get 4 + local.get 3 + i32.const 65984 + i32.load + i32.add + i32.const 3 + i32.shl + i32.const 12 + i32.add + local.get 2 + i32.const -1 + i32.const -1 + i32.const 65988 + i32.load8_u + local.tee 3 + i32.shl + i32.const -1 + i32.xor + local.get 3 + i32.const 31 + i32.gt_u + select + i32.and + i32.mul + i32.add + local.set 2 + block ;; label = @1 + loop ;; label = @2 + local.get 1 + local.get 2 + i32.store offset=12 + local.get 1 + local.get 2 + i32.store offset=16 + local.get 2 + i32.eqz + br_if 1 (;@1;) + i32.const 0 + local.set 3 + block ;; label = @3 + loop ;; label = @4 + local.get 3 + i32.const 8 + i32.ne + if ;; label = @5 + block ;; label = @6 + local.get 2 + local.get 3 + i32.add + local.tee 8 + i32.load8_u + local.get 7 + i32.ne + br_if 0 (;@6;) + i32.const 65980 + i32.load + local.set 4 + local.get 1 + i32.const 65992 + i32.load + local.tee 9 + i32.store offset=20 + local.get 1 + i32.const 65996 + i32.load + local.tee 5 + i32.store offset=24 + local.get 5 + i32.eqz + br_if 3 (;@3;) + local.get 0 + local.get 3 + local.get 4 + i32.mul + local.get 2 + i32.add + i32.const 12 + i32.add + local.get 4 + local.get 9 + local.get 5 + call_indirect (type 0) + i32.const 1 + i32.and + i32.eqz + br_if 0 (;@6;) + local.get 8 + i32.const 0 + i32.store8 + i32.const 65976 + i32.const 65976 + i32.load + i32.const 1 + i32.sub + i32.store + br 5 (;@1;) + end + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@4;) + end + end + local.get 1 + local.get 2 + i32.load offset=8 + local.tee 2 + i32.store offset=28 + br 1 (;@2;) + end + end + call 17 + unreachable + end + i32.const 66180 + local.get 6 + i32.store + local.get 1 + i32.const 32 + i32.add + global.set 0) + (func (;25;) (type 1) (param i32) + i32.const 65853 + i32.const 7 + call 8 + local.get 0 + i32.load + local.get 0 + i32.load offset=4 + call 8 + i32.const 10 + call 9 + unreachable) + (func (;26;) (type 5) (param i32 i32) (result i32) + (local i32 i32) + global.get 0 + i32.const 16 + i32.sub + local.tee 2 + global.set 0 + i32.const 66180 + i32.load + local.set 3 + i32.const 66180 + local.get 2 + i32.store + local.get 0 + local.get 1 + i32.mul + call 20 + i32.const 66180 + local.get 3 + i32.store + local.get 2 + i32.const 16 + i32.add + global.set 0) + (func (;27;) (type 5) (param i32 i32) (result i32) + (local i32 i32 i32 i32) + global.get 0 + i32.const 32 + i32.sub + local.tee 2 + global.set 0 + local.get 2 + i32.const 2 + i32.store offset=20 + i32.const 66180 + i32.load + local.set 4 + i32.const 66180 + local.get 2 + i32.const 16 + i32.add + i32.store + local.get 2 + local.get 4 + i32.store offset=16 + block ;; label = @1 + block ;; label = @2 + block ;; label = @3 + local.get 1 + i32.eqz + if ;; label = @4 + local.get 0 + call 22 + br 1 (;@3;) + end + local.get 1 + i32.const 0 + i32.lt_s + br_if 1 (;@2;) + local.get 2 + local.get 1 + call 10 + local.tee 3 + i32.store offset=24 + local.get 2 + local.get 3 + i32.store offset=28 + local.get 0 + if ;; label = @4 + local.get 2 + local.get 0 + i32.store offset=12 + local.get 2 + i32.const 12 + i32.add + local.get 2 + call 23 + i32.const 1 + i32.and + i32.eqz + br_if 3 (;@1;) + local.get 3 + local.get 2 + i32.load + local.get 2 + i32.load offset=4 + local.tee 5 + local.get 1 + local.get 1 + local.get 5 + i32.gt_u + select + memory.copy + local.get 2 + local.get 0 + i32.store + local.get 2 + call 24 + end + local.get 2 + local.get 1 + i32.store offset=8 + local.get 2 + local.get 1 + i32.store offset=4 + local.get 2 + local.get 3 + i32.store + local.get 2 + local.get 3 + i32.store offset=12 + local.get 2 + i32.const 12 + i32.add + local.get 2 + call 21 + end + i32.const 66180 + local.get 4 + i32.store + local.get 2 + i32.const 32 + i32.add + global.set 0 + local.get 3 + return + end + call 7 + unreachable + end + i32.const 65832 + call 25 + unreachable) + (func (;28;) (type 3) + (local i32 i32) + i32.const 66008 + memory.size + i32.const 16 + i32.shl + local.tee 0 + i32.store + call 18 + i32.const 66136 + i32.load + local.tee 1 + i32.const 0 + local.get 0 + local.get 1 + i32.sub + memory.fill + i32.const 66008 + memory.size + i32.const 16 + i32.shl + i32.store) + (func (;29;) (type 0) (param i32 i32 i32 i32) (result i32) + (local i32 i32 i32 i32 i32 i32 i32 i32) + global.get 0 + i32.const 48 + i32.sub + local.tee 4 + global.set 0 + local.get 4 + i32.const 40 + i32.add + i32.const 0 + i32.store + local.get 4 + i64.const 0 + i64.store offset=32 + local.get 4 + i32.const 7 + i32.store offset=12 + i32.const 66180 + i32.load + local.set 7 + i32.const 66180 + local.get 4 + i32.const 8 + i32.add + i32.store + local.get 4 + local.get 7 + i32.store offset=8 + local.get 4 + local.get 0 + i32.load + local.tee 5 + i32.store offset=16 + local.get 5 + local.get 0 + i32.load offset=16 + local.get 0 + i32.load offset=12 + i32.add + i32.const 3 + i32.shl + i32.const 12 + i32.add + i32.const -1 + i32.const -1 + local.get 0 + i32.load8_u offset=20 + local.tee 6 + i32.shl + i32.const -1 + i32.xor + local.get 6 + i32.const 31 + i32.gt_u + select + local.get 3 + i32.and + i32.mul + i32.add + local.set 5 + local.get 3 + i32.const 24 + i32.shr_u + local.tee 3 + i32.const 1 + local.get 3 + select + local.set 9 + block ;; label = @1 + block ;; label = @2 + loop ;; label = @3 + block ;; label = @4 + local.get 4 + local.get 5 + i32.store offset=24 + local.get 4 + local.get 5 + i32.store offset=28 + local.get 4 + local.get 5 + i32.store offset=20 + local.get 5 + i32.eqz + br_if 0 (;@4;) + i32.const 0 + local.set 3 + loop ;; label = @5 + local.get 3 + i32.const 8 + i32.ne + if ;; label = @6 + block ;; label = @7 + local.get 3 + local.get 5 + i32.add + i32.load8_u + local.get 9 + i32.ne + br_if 0 (;@7;) + local.get 0 + i32.load offset=12 + local.set 6 + local.get 0 + i32.load offset=16 + local.set 10 + local.get 4 + local.get 0 + i32.load offset=24 + local.tee 11 + i32.store offset=32 + local.get 4 + local.get 0 + i32.load offset=28 + local.tee 8 + i32.store offset=36 + local.get 8 + i32.eqz + br_if 5 (;@2;) + local.get 1 + local.get 3 + local.get 6 + i32.mul + local.get 5 + i32.add + i32.const 12 + i32.add + local.get 6 + local.get 11 + local.get 8 + call_indirect (type 0) + i32.const 1 + i32.and + i32.eqz + br_if 0 (;@7;) + local.get 2 + local.get 3 + local.get 10 + i32.mul + local.get 6 + i32.const 3 + i32.shl + i32.add + local.get 5 + i32.add + i32.const 12 + i32.add + local.get 0 + i32.load offset=16 + memory.copy + br 6 (;@1;) + end + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@5;) + end + end + local.get 4 + local.get 5 + i32.load offset=8 + local.tee 5 + i32.store offset=40 + br 1 (;@3;) + end + end + local.get 2 + i32.const 0 + local.get 0 + i32.load offset=16 + memory.fill + br 1 (;@1;) + end + call 17 + unreachable + end + i32.const 66180 + local.get 7 + i32.store + local.get 4 + i32.const 48 + i32.add + global.set 0 + local.get 5 + i32.const 0 + i32.ne) + (func (;30;) (type 7) (param i32 i32 i32 i32) + (local i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32) + global.get 0 + i32.const 256 + i32.sub + local.tee 4 + global.set 0 + local.get 4 + i32.const 50 + i32.store offset=52 + local.get 4 + i32.const 56 + i32.add + i32.const 0 + i32.const 200 + memory.fill + local.get 4 + i32.const 66180 + i32.load + local.tee 14 + i32.store offset=48 + i32.const 66180 + local.get 4 + i32.const 48 + i32.add + i32.store + block ;; label = @1 + block ;; label = @2 + local.get 0 + i32.eqz + br_if 0 (;@2;) + block ;; label = @3 + local.get 0 + i32.load8_u offset=20 + local.tee 6 + i32.const 29 + i32.gt_u + br_if 0 (;@3;) + local.get 0 + i32.load offset=8 + i32.const 6 + local.get 6 + i32.shl + i32.le_u + br_if 0 (;@3;) + local.get 4 + i64.const 0 + i64.store offset=24 + local.get 4 + local.get 0 + i32.load offset=36 + local.tee 3 + i32.store offset=72 + local.get 4 + local.get 0 + i32.load offset=32 + local.tee 5 + i32.store offset=68 + local.get 4 + local.get 0 + i32.load offset=28 + local.tee 7 + i32.store offset=64 + local.get 4 + local.get 0 + i32.load offset=24 + local.tee 8 + i32.store offset=60 + local.get 4 + local.get 0 + i32.load + i32.store offset=56 + local.get 4 + local.get 3 + i32.store offset=44 + local.get 4 + local.get 5 + i32.store offset=40 + local.get 4 + local.get 7 + i32.store offset=36 + local.get 4 + local.get 8 + i32.store offset=32 + local.get 4 + local.get 0 + i32.load offset=16 + i32.store offset=24 + local.get 4 + local.get 0 + i32.load offset=12 + i32.store offset=20 + i32.const 65956 + i32.const 65956 + i32.load + local.tee 3 + i32.const 7 + i32.shl + local.get 3 + i32.xor + local.tee 3 + i32.const 1 + i32.shr_u + local.get 3 + i32.xor + local.tee 3 + i32.const 9 + i32.shl + local.get 3 + i32.xor + local.tee 3 + i32.store + local.get 4 + i32.const 0 + i32.store offset=16 + local.get 4 + local.get 3 + i32.store offset=12 + local.get 4 + local.get 6 + i32.const 1 + i32.add + local.tee 3 + i32.store8 offset=28 + local.get 4 + local.get 0 + i32.load offset=16 + local.get 0 + i32.load offset=12 + i32.add + i32.const 3 + i32.shl + i32.const 12 + i32.add + local.get 3 + i32.shl + call 10 + local.tee 3 + i32.store offset=8 + local.get 4 + local.get 3 + i32.store offset=76 + local.get 4 + local.get 0 + i32.load offset=12 + call 10 + local.tee 8 + i32.store offset=80 + local.get 4 + local.get 0 + i32.load offset=16 + call 10 + local.tee 11 + i32.store offset=84 + i32.const 0 + local.set 7 + i32.const 0 + local.set 3 + i32.const 0 + local.set 5 + i32.const 0 + local.set 6 + loop ;; label = @4 + local.get 4 + local.get 5 + i32.store offset=88 + local.get 5 + i32.eqz + if ;; label = @5 + local.get 4 + local.get 0 + i32.load + local.tee 5 + i32.store offset=92 + i32.const 1 + local.get 0 + i32.load8_u offset=20 + local.tee 9 + i32.shl + i32.const 0 + local.get 9 + i32.const 31 + i32.le_u + select + local.set 12 + end + local.get 4 + local.get 5 + i32.store offset=108 + local.get 4 + local.get 5 + i32.store offset=124 + block ;; label = @5 + loop ;; label = @6 + local.get 4 + local.get 3 + i32.store offset=96 + local.get 6 + i32.const 255 + i32.and + i32.const 8 + i32.ge_u + if ;; label = @7 + local.get 3 + i32.eqz + br_if 5 (;@2;) + local.get 4 + local.get 3 + i32.load offset=8 + local.tee 3 + i32.store offset=100 + i32.const 0 + local.set 6 + end + local.get 4 + local.get 3 + i32.store offset=104 + local.get 3 + i32.eqz + if ;; label = @7 + local.get 7 + local.get 12 + i32.ge_u + br_if 2 (;@5;) + local.get 5 + local.get 0 + i32.load offset=16 + local.get 0 + i32.load offset=12 + i32.add + i32.const 3 + i32.shl + i32.const 12 + i32.add + local.get 7 + i32.mul + i32.add + local.set 3 + local.get 7 + i32.const 1 + i32.add + local.set 7 + end + local.get 4 + local.get 3 + i32.store offset=116 + local.get 4 + local.get 3 + i32.store offset=120 + local.get 4 + local.get 3 + i32.store offset=112 + local.get 3 + i32.eqz + br_if 4 (;@2;) + local.get 3 + local.get 6 + i32.const 255 + i32.and + local.tee 10 + i32.add + i32.load8_u + i32.eqz + if ;; label = @7 + local.get 6 + i32.const 1 + i32.add + local.set 6 + br 1 (;@6;) + end + local.get 8 + local.get 0 + i32.load offset=12 + local.tee 9 + local.get 10 + i32.mul + local.get 3 + i32.add + i32.const 12 + i32.add + local.get 9 + memory.copy + local.get 4 + local.get 0 + i32.load + local.tee 13 + i32.store offset=128 + block ;; label = @7 + local.get 5 + local.get 13 + i32.eq + if ;; label = @8 + local.get 11 + local.get 10 + local.get 0 + i32.load offset=16 + local.tee 10 + i32.mul + local.get 9 + i32.const 3 + i32.shl + i32.add + local.get 3 + i32.add + i32.const 12 + i32.add + local.get 10 + memory.copy + local.get 6 + i32.const 1 + i32.add + local.set 6 + br 1 (;@7;) + end + local.get 4 + local.get 0 + i32.load offset=32 + local.tee 13 + i32.store offset=132 + local.get 4 + local.get 0 + i32.load offset=36 + local.tee 10 + i32.store offset=136 + local.get 10 + i32.eqz + br_if 5 (;@2;) + local.get 6 + i32.const 1 + i32.add + local.set 6 + local.get 0 + local.get 8 + local.get 11 + local.get 8 + local.get 9 + local.get 0 + i32.load offset=4 + local.get 13 + local.get 10 + call_indirect (type 0) + call 29 + i32.const 1 + i32.and + i32.eqz + br_if 1 (;@6;) + end + end + local.get 4 + local.get 4 + i32.load offset=40 + local.tee 10 + i32.store offset=140 + local.get 4 + local.get 4 + i32.load offset=44 + local.tee 9 + i32.store offset=144 + local.get 9 + i32.eqz + br_if 3 (;@2;) + local.get 4 + i32.const 8 + i32.add + local.get 8 + local.get 11 + local.get 8 + local.get 4 + i32.load offset=20 + local.get 4 + i32.load offset=12 + local.get 10 + local.get 9 + call_indirect (type 0) + call 30 + br 1 (;@4;) + end + end + local.get 0 + local.get 4 + i32.load offset=8 + local.tee 3 + i32.store + local.get 0 + local.get 4 + i64.load offset=12 align=4 + i64.store offset=4 align=4 + local.get 0 + local.get 4 + i64.load offset=20 align=4 + i64.store offset=12 align=4 + local.get 0 + local.get 4 + i32.load8_u offset=28 + i32.store8 offset=20 + local.get 0 + local.get 4 + i32.load offset=32 + local.tee 5 + i32.store offset=24 + local.get 0 + local.get 4 + i32.load offset=36 + local.tee 7 + i32.store offset=28 + local.get 0 + local.get 4 + i32.load offset=40 + local.tee 6 + i32.store offset=32 + local.get 0 + local.get 4 + i32.load offset=44 + local.tee 8 + i32.store offset=36 + local.get 4 + local.get 3 + i32.store offset=148 + local.get 4 + local.get 5 + i32.store offset=152 + local.get 4 + local.get 7 + i32.store offset=156 + local.get 4 + local.get 6 + i32.store offset=160 + local.get 4 + local.get 8 + i32.store offset=164 + local.get 4 + local.get 0 + i32.load offset=32 + local.tee 5 + i32.store offset=168 + local.get 4 + local.get 0 + i32.load offset=36 + local.tee 3 + i32.store offset=172 + local.get 3 + i32.eqz + br_if 1 (;@2;) + local.get 1 + local.get 0 + i32.load offset=12 + local.get 0 + i32.load offset=4 + local.get 5 + local.get 3 + call_indirect (type 0) + local.set 3 + local.get 0 + i32.load8_u offset=20 + local.set 6 + end + local.get 4 + local.get 0 + i32.load + local.tee 5 + i32.store offset=176 + local.get 5 + local.get 0 + i32.load offset=16 + local.get 0 + i32.load offset=12 + i32.add + i32.const 3 + i32.shl + i32.const 12 + i32.add + i32.const -1 + i32.const -1 + local.get 6 + i32.const 255 + i32.and + local.tee 7 + i32.shl + i32.const -1 + i32.xor + local.get 7 + i32.const 31 + i32.gt_u + select + local.get 3 + i32.and + i32.mul + i32.add + local.set 7 + local.get 3 + i32.const 24 + i32.shr_u + local.tee 3 + i32.const 1 + local.get 3 + select + local.set 9 + i32.const 0 + local.set 3 + i32.const 0 + local.set 6 + i32.const 0 + local.set 11 + i32.const 0 + local.set 8 + loop ;; label = @3 + block ;; label = @4 + local.get 4 + local.get 7 + local.tee 5 + i32.store offset=212 + local.get 4 + local.get 5 + i32.store offset=216 + local.get 4 + local.get 5 + i32.store offset=196 + local.get 4 + local.get 3 + i32.store offset=192 + local.get 4 + local.get 6 + i32.store offset=188 + local.get 4 + local.get 11 + i32.store offset=184 + local.get 4 + local.get 8 + i32.store offset=180 + local.get 5 + i32.eqz + br_if 0 (;@4;) + i32.const 0 + local.set 3 + loop ;; label = @5 + block ;; label = @6 + local.get 4 + local.get 11 + i32.store offset=204 + local.get 4 + local.get 6 + i32.store offset=208 + local.get 4 + local.get 8 + i32.store offset=200 + local.get 3 + i32.const 8 + i32.eq + br_if 0 (;@6;) + local.get 4 + local.get 8 + local.get 3 + local.get 5 + i32.add + local.tee 7 + local.get 7 + i32.load8_u + local.get 6 + i32.or + local.tee 12 + select + local.tee 8 + i32.store offset=220 + local.get 4 + local.get 6 + local.get 0 + i32.load offset=12 + local.tee 10 + local.get 3 + i32.mul + local.get 5 + i32.add + i32.const 12 + i32.add + local.tee 13 + local.get 12 + select + local.tee 6 + i32.store offset=228 + local.get 4 + local.get 11 + local.get 0 + i32.load offset=16 + local.get 3 + i32.mul + local.get 10 + i32.const 3 + i32.shl + i32.add + local.get 5 + i32.add + i32.const 12 + i32.add + local.tee 15 + local.get 12 + select + local.tee 11 + i32.store offset=224 + block ;; label = @7 + local.get 7 + i32.load8_u + local.get 9 + i32.ne + br_if 0 (;@7;) + local.get 4 + local.get 0 + i32.load offset=24 + local.tee 12 + i32.store offset=232 + local.get 4 + local.get 0 + i32.load offset=28 + local.tee 7 + i32.store offset=236 + local.get 7 + i32.eqz + br_if 5 (;@2;) + local.get 1 + local.get 13 + local.get 10 + local.get 12 + local.get 7 + call_indirect (type 0) + i32.const 1 + i32.and + i32.eqz + br_if 0 (;@7;) + local.get 15 + local.get 2 + local.get 0 + i32.load offset=16 + memory.copy + br 6 (;@1;) + end + local.get 3 + i32.const 1 + i32.add + local.set 3 + br 1 (;@5;) + end + end + local.get 4 + local.get 5 + i32.load offset=8 + local.tee 7 + i32.store offset=240 + local.get 5 + local.set 3 + br 1 (;@3;) + end + end + local.get 6 + i32.eqz + if ;; label = @3 + local.get 0 + i32.load offset=16 + local.get 0 + i32.load offset=12 + i32.add + i32.const 3 + i32.shl + i32.const 12 + i32.add + call 10 + local.set 5 + local.get 0 + local.get 0 + i32.load offset=8 + i32.const 1 + i32.add + i32.store offset=8 + local.get 4 + local.get 5 + i32.store offset=248 + local.get 4 + local.get 5 + i32.store offset=252 + local.get 4 + local.get 5 + i32.store offset=244 + local.get 5 + i32.const 12 + i32.add + local.tee 7 + local.get 1 + local.get 0 + i32.load offset=12 + local.tee 1 + memory.copy + local.get 7 + local.get 1 + i32.const 3 + i32.shl + i32.add + local.get 2 + local.get 0 + i32.load offset=16 + memory.copy + local.get 5 + local.get 9 + i32.store8 + local.get 3 + i32.eqz + br_if 1 (;@2;) + local.get 3 + local.get 5 + i32.store offset=8 + br 2 (;@1;) + end + local.get 0 + local.get 0 + i32.load offset=8 + i32.const 1 + i32.add + i32.store offset=8 + local.get 6 + local.get 1 + local.get 0 + i32.load offset=12 + memory.copy + local.get 11 + local.get 2 + local.get 0 + i32.load offset=16 + memory.copy + local.get 8 + i32.eqz + br_if 0 (;@2;) + local.get 8 + local.get 9 + i32.store8 + br 1 (;@1;) + end + call 17 + unreachable + end + i32.const 66180 + local.get 14 + i32.store + local.get 4 + i32.const 256 + i32.add + global.set 0) + (func (;31;) (type 3) + (local i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i64) + global.get 0 + i32.const 112 + i32.sub + local.tee 0 + global.set 0 + local.get 0 + i32.const 18 + i32.store offset=36 + local.get 0 + i32.const 56 + i32.add + i32.const 0 + i32.const 56 + memory.fill + local.get 0 + i32.const 66180 + i32.load + local.tee 8 + i32.store offset=32 + i32.const 66180 + local.get 0 + i32.const 32 + i32.add + i32.store + local.get 0 + i32.const 8 + call 10 + local.tee 3 + i32.store offset=48 + local.get 0 + local.get 3 + i32.store offset=52 + local.get 0 + local.get 3 + i32.store offset=44 + local.get 0 + local.get 3 + i32.store offset=40 + local.get 3 + call 1 + local.get 0 + i32.const 24 + i32.add + local.get 3 + i32.const 42 + call 32 + local.get 0 + i32.load offset=24 + local.get 0 + i32.load offset=28 + call 2 + block ;; label = @1 + block ;; label = @2 + local.get 3 + i32.const 99 + i32.le_u + if ;; label = @3 + local.get 3 + i32.const 65536 + i32.add + local.get 3 + i32.const 1 + i32.shl + i32.const 65572 + i32.add + local.get 3 + i32.const 10 + i32.lt_u + local.tee 2 + select + local.set 1 + i32.const 1 + i32.const 2 + local.get 2 + select + local.set 3 + br 1 (;@2;) + end + i32.const 65 + local.set 2 + local.get 0 + i32.const 65 + call 10 + local.tee 6 + i32.store offset=56 + local.get 3 + local.get 3 + i32.const 31 + i32.shr_s + local.tee 1 + i32.xor + local.get 1 + i32.sub + i64.extend_i32_u + local.set 12 + local.get 6 + i32.const 2 + i32.sub + local.set 7 + loop ;; label = @3 + local.get 12 + i64.const 1000000000 + i64.ge_u + if ;; label = @4 + local.get 2 + local.get 7 + i32.add + local.set 5 + local.get 12 + local.get 12 + i64.const 1000000000 + i64.div_u + local.tee 12 + i64.const 3294967296 + i64.mul + i64.add + i32.wrap_i64 + local.set 4 + i32.const 0 + local.set 1 + loop ;; label = @5 + local.get 1 + i32.const -8 + i32.ne + if ;; label = @6 + local.get 1 + local.get 2 + i32.add + local.tee 9 + i32.const 1 + i32.sub + i32.const 64 + i32.gt_u + br_if 5 (;@1;) + local.get 1 + local.get 5 + i32.add + local.tee 10 + i32.const 1 + i32.add + local.get 4 + local.get 4 + i32.const 100 + i32.div_u + local.tee 4 + i32.const -100 + i32.mul + i32.add + i32.const 1 + i32.shl + local.tee 11 + i32.const 1 + i32.or + i32.const 65572 + i32.add + i32.load8_u + i32.store8 + local.get 9 + i32.const 2 + i32.sub + i32.const 64 + i32.gt_u + br_if 5 (;@1;) + local.get 10 + local.get 11 + i32.const 65572 + i32.add + i32.load8_u + i32.store8 + local.get 1 + i32.const 2 + i32.sub + local.set 1 + br 1 (;@5;) + end + end + local.get 4 + i32.const 1 + i32.shl + i32.const 1 + i32.or + local.tee 4 + i32.const 199 + i32.gt_u + br_if 3 (;@1;) + local.get 1 + local.get 2 + i32.add + i32.const 1 + i32.sub + local.tee 2 + i32.const 64 + i32.gt_u + br_if 3 (;@1;) + local.get 1 + local.get 5 + i32.add + i32.const 1 + i32.add + local.get 4 + i32.const 65572 + i32.add + i32.load8_u + i32.store8 + br 1 (;@3;) + end + end + local.get 12 + i32.wrap_i64 + local.set 1 + loop ;; label = @3 + local.get 1 + i32.const 100 + i32.ge_u + if ;; label = @4 + local.get 2 + i32.const 1 + i32.sub + i32.const 64 + i32.gt_u + br_if 3 (;@1;) + local.get 2 + local.get 6 + i32.add + local.tee 4 + i32.const 1 + i32.sub + local.get 1 + local.get 1 + i32.const 100 + i32.div_u + local.tee 1 + i32.const -100 + i32.mul + i32.add + i32.const 1 + i32.shl + local.tee 5 + i32.const 1 + i32.or + i32.const 65572 + i32.add + i32.load8_u + i32.store8 + local.get 2 + i32.const 2 + i32.sub + local.tee 2 + i32.const 64 + i32.gt_u + br_if 3 (;@1;) + local.get 4 + i32.const 2 + i32.sub + local.get 5 + i32.const 65572 + i32.add + i32.load8_u + i32.store8 + br 1 (;@3;) + end + end + local.get 2 + i32.const 1 + i32.sub + local.tee 4 + i32.const 64 + i32.gt_u + br_if 1 (;@1;) + local.get 2 + local.get 6 + i32.add + local.tee 5 + i32.const 1 + i32.sub + local.get 1 + i32.const 1 + i32.shl + local.tee 7 + i32.const 1 + i32.or + i32.const 65572 + i32.add + i32.load8_u + i32.store8 + local.get 1 + i32.const 10 + i32.ge_u + if ;; label = @3 + local.get 2 + i32.const 2 + i32.sub + local.tee 4 + i32.const 64 + i32.gt_u + br_if 2 (;@1;) + local.get 5 + i32.const 2 + i32.sub + local.get 7 + i32.const 65572 + i32.add + i32.load8_u + i32.store8 + end + local.get 3 + i32.const 0 + i32.lt_s + if ;; label = @3 + local.get 4 + i32.const 1 + i32.sub + local.tee 4 + i32.const 64 + i32.gt_u + br_if 2 (;@1;) + local.get 4 + local.get 6 + i32.add + i32.const 45 + i32.store8 + end + local.get 0 + i32.const 65 + local.get 4 + i32.sub + local.tee 3 + call 10 + local.tee 1 + i32.store offset=68 + local.get 0 + local.get 1 + i32.store offset=72 + local.get 0 + local.get 1 + i32.store offset=64 + local.get 0 + local.get 1 + i32.store offset=60 + local.get 1 + local.get 4 + local.get 6 + i32.add + local.get 3 + memory.copy + end + local.get 0 + local.get 1 + i32.store offset=92 + local.get 0 + local.get 1 + i32.store offset=96 + local.get 0 + local.get 1 + i32.store offset=84 + local.get 0 + local.get 1 + i32.store offset=80 + local.get 0 + local.get 1 + i32.store offset=76 + local.get 3 + i32.const 8 + i32.add + local.tee 4 + call 10 + local.tee 2 + i64.const 2338042707301724016 + i64.store align=1 + local.get 0 + local.get 2 + i32.store offset=104 + local.get 0 + local.get 2 + i32.store offset=108 + local.get 0 + local.get 2 + i32.store offset=100 + local.get 0 + local.get 2 + i32.store offset=88 + local.get 2 + i32.const 8 + i32.add + local.get 1 + local.get 3 + memory.copy + local.get 0 + i32.const 16 + i32.add + local.get 2 + local.get 4 + call 32 + local.get 0 + i32.load offset=16 + local.get 0 + i32.load offset=20 + call 2 + local.get 0 + i32.const 8 + i32.add + i32.const 65941 + i32.const 15 + call 32 + local.get 0 + i32.load offset=8 + local.get 0 + i32.load offset=12 + call 2 + i32.const 66180 + local.get 8 + i32.store + local.get 0 + i32.const 112 + i32.add + global.set 0 + return + end + call 5 + unreachable) + (func (;32;) (type 8) (param i32 i32 i32) + (local i32 i32 i32 i32) + global.get 0 + i32.const 32 + i32.sub + local.tee 3 + global.set 0 + local.get 3 + i32.const 16 + i32.add + local.tee 6 + i64.const 0 + i64.store + local.get 3 + i32.const 24 + i32.add + local.tee 4 + i32.const 0 + i32.store + local.get 3 + i64.const 0 + i64.store offset=8 + local.get 3 + i32.const 5 + i32.store offset=4 + i32.const 66180 + i32.load + local.set 5 + i32.const 66180 + local.get 3 + i32.store + local.get 3 + local.get 5 + i32.store + local.get 4 + local.get 2 + call 10 + local.tee 4 + i32.store + local.get 6 + local.get 4 + i32.store + local.get 3 + local.get 4 + i32.store offset=20 + local.get 3 + local.get 4 + i32.store offset=12 + local.get 3 + local.get 4 + i32.store offset=8 + local.get 4 + local.get 1 + local.get 2 + memory.copy + local.get 2 + if ;; label = @1 + i32.const 66180 + local.get 5 + i32.store + local.get 0 + local.get 2 + i32.store offset=4 + local.get 0 + local.get 4 + i32.store + local.get 3 + i32.const 32 + i32.add + global.set 0 + return + end + call 5 + unreachable) + (table (;0;) 3 3 funcref) + (memory (;0;) 2) + (global (;0;) (mut i32) (i32.const 65536)) + (export "memory" (memory 0)) + (export "malloc" (func 20)) + (export "free" (func 22)) + (export "calloc" (func 26)) + (export "realloc" (func 27)) + (export "_start" (func 28)) + (export "run" (func 31)) + (elem (;0;) (i32.const 1) func 3 4) + (data (;0;) (i32.const 65536) "0123456789abcdefghijklmnopqrstuvwxyz00010203040506070809101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899free: invalid pointer\00\00\00\00\00\00\00\ec\00\01\00\15\00\00\00realloc: invalid pointer\10\01\01\00\18\00\00\00out of memorypanic: panic: runtime error: nil pointer dereferenceindex out of rangeslice out of rangeHello from wasm") + (data (;1;) (i32.const 65956) "\c1\82\01\00\e0\01\01\00\00\00\00\00\8c\02\01\00\c1\82\01\00\00\00\00\00\04\00\00\00\0c\00\00\00\01\00\00\00\00\00\00\00\01\00\00\00\00\00\00\00\02")) diff --git a/core/vm/wasm_contracts/hello/build.sh b/core/vm/wasm_contracts/hello/build.sh new file mode 100755 index 0000000000..fd049c302a --- /dev/null +++ b/core/vm/wasm_contracts/hello/build.sh @@ -0,0 +1,2 @@ +#!/bin/bash +tinygo build -o hello.wasm -scheduler=none --no-debug -target wasi ./hello.go \ No newline at end of file diff --git a/core/vm/wasm_contracts/hello/hello.go b/core/vm/wasm_contracts/hello/hello.go new file mode 100644 index 0000000000..ee1170e806 --- /dev/null +++ b/core/vm/wasm_contracts/hello/hello.go @@ -0,0 +1,47 @@ +package main + +import ( + "unsafe" +) + +// main is required for TinyGo to compile to Wasm. +func main() {} + +//export run +//go:linkname run +func run() { + add(1, 2) +} + +//export hostLogString +//go:linkname hostLogString +func hostLogString(offset uint32, byteCount uint32) + +//export hostLogUint32 +//go:linkname hostLogUint32 +func hostLogUint32(value uint32) + +//export add +func add(x uint32, y uint32) uint32 { + // 🖐 a wasm module cannot print something + //fmt.Println(x,y) + res := x + y + + hostLogUint32(res) + + // //offset, byteCount := strToPtr("from wasm: " + strconv.FormatUint(uint64(res), 10)) + offset, byteCount := strToPtr("👋 Hello from wasm") + + hostLogString(offset, byteCount) + + return res +} + +// strToPtr returns a pointer and size pair for the given string in a way +// compatible with WebAssembly numeric types. +func strToPtr(s string) (uint32, uint32) { + buf := []byte(s) + ptr := &buf[0] + unsafePtr := uintptr(unsafe.Pointer(ptr)) + return uint32(unsafePtr), uint32(len(buf)) +} \ No newline at end of file diff --git a/core/vm/wasm_contracts/hello/hello.wasm b/core/vm/wasm_contracts/hello/hello.wasm new file mode 100755 index 0000000000000000000000000000000000000000..106e097c46b8e8588ba05e135d0649bac1448dcc GIT binary patch literal 6335 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 kb}Q*doel^&xz