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 0000000000..4d328be009
Binary files /dev/null and b/core/vm/wasm_contracts/get_address/get_address.wasm differ
diff --git a/core/vm/wasm_contracts/get_block_number/build.sh b/core/vm/wasm_contracts/get_block_number/build.sh
new file mode 100755
index 0000000000..6c5e124512
--- /dev/null
+++ b/core/vm/wasm_contracts/get_block_number/build.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+tinygo build -o get_block_number.wasm -scheduler=none --no-debug -target wasi ./get_block_number.go
\ No newline at end of file
diff --git a/core/vm/wasm_contracts/get_block_number/get_block_number.go b/core/vm/wasm_contracts/get_block_number/get_block_number.go
new file mode 100644
index 0000000000..29ea665658
--- /dev/null
+++ b/core/vm/wasm_contracts/get_block_number/get_block_number.go
@@ -0,0 +1,33 @@
+package main
+
+import (
+ "strconv"
+ "unsafe"
+)
+
+// main is required for TinyGo to compile to Wasm.
+func main() {}
+
+//export hostLogString
+//go:linkname hostLogString
+func hostLogString(offset uint32, byteCount uint32)
+
+//export run
+//go:linkname run
+func run() {
+ number := getBlockNumber()
+ hostLogString(strToPtr(strconv.Itoa(int(number))))
+}
+
+//export getBlockNumber
+//go:linkname getBlockNumber
+func getBlockNumber() int64
+
+// 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_block_number/get_block_number.wasm b/core/vm/wasm_contracts/get_block_number/get_block_number.wasm
new file mode 100755
index 0000000000..f34371bed5
Binary files /dev/null and b/core/vm/wasm_contracts/get_block_number/get_block_number.wasm differ
diff --git a/core/vm/wasm_contracts/get_caller/build.sh b/core/vm/wasm_contracts/get_caller/build.sh
new file mode 100755
index 0000000000..96993d1c5a
--- /dev/null
+++ b/core/vm/wasm_contracts/get_caller/build.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+tinygo build -o get_caller.wasm -scheduler=none --no-debug -target wasi ./get_caller.go
\ No newline at end of file
diff --git a/core/vm/wasm_contracts/get_caller/get_caller.go b/core/vm/wasm_contracts/get_caller/get_caller.go
new file mode 100644
index 0000000000..9432f88cb2
--- /dev/null
+++ b/core/vm/wasm_contracts/get_caller/get_caller.go
@@ -0,0 +1,81 @@
+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))
+
+ 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 0000000000..910efe4fdd
Binary files /dev/null and b/core/vm/wasm_contracts/get_caller/get_caller.wasm differ
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 0000000000..106e097c46
Binary files /dev/null and b/core/vm/wasm_contracts/hello/hello.wasm differ
diff --git a/core/vm/wasm_contracts/use_gas/build.sh b/core/vm/wasm_contracts/use_gas/build.sh
new file mode 100755
index 0000000000..9be68b58f8
--- /dev/null
+++ b/core/vm/wasm_contracts/use_gas/build.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+tinygo build -o use_gas.wasm -scheduler=none --no-debug -target wasi ./use_gas.go
\ No newline at end of file
diff --git a/core/vm/wasm_contracts/use_gas/use_gas.go b/core/vm/wasm_contracts/use_gas/use_gas.go
new file mode 100644
index 0000000000..022820efd4
--- /dev/null
+++ b/core/vm/wasm_contracts/use_gas/use_gas.go
@@ -0,0 +1,14 @@
+package main
+
+// main is required for TinyGo to compile to Wasm.
+func main() {}
+
+//export run
+//go:linkname run
+func run() {
+ useGas(1000)
+}
+
+//export useGas
+//go:linkname useGas
+func useGas(amount int64)
diff --git a/core/vm/wasm_contracts/use_gas/use_gas.wasm b/core/vm/wasm_contracts/use_gas/use_gas.wasm
new file mode 100755
index 0000000000..a364e3a9bc
Binary files /dev/null and b/core/vm/wasm_contracts/use_gas/use_gas.wasm differ
diff --git a/core/vm/wasm_interpreter_test.go b/core/vm/wasm_interpreter_test.go
new file mode 100644
index 0000000000..3c274d277f
--- /dev/null
+++ b/core/vm/wasm_interpreter_test.go
@@ -0,0 +1,163 @@
+package vm
+
+import (
+ "fmt"
+ "io/ioutil"
+ "math/big"
+ "os"
+ "testing"
+
+ "github.com/dominant-strategies/go-quai/common"
+ "github.com/dominant-strategies/go-quai/crypto"
+ "github.com/dominant-strategies/go-quai/params"
+)
+
+func TestHelloContract(t *testing.T) {
+ var (
+ env = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{})
+ wasmInterpreter = NewWASMInterpreter(env, env.Config)
+ )
+
+ wasmBytes, err := ioutil.ReadFile("wasm_contracts/hello/hello.wasm")
+ if err != nil {
+ fmt.Fprintln(os.Stderr, "Error reading wasm file:", err)
+ os.Exit(1)
+ }
+
+ // Track time taken and memory usage
+ // defer trackTime(time.Now(), "wasm")
+
+ // Initialise a new contract and set the code that is to be used by the EVM.
+ // The contract is a scoped environment for this execution context only.
+ contract := NewContract(&dummyContractRef{}, &dummyContractRef{}, new(big.Int), 2000)
+ contract.SetCodeOptionalHash(nil, &codeAndHash{
+ code: wasmBytes,
+ })
+
+ _, err2 := wasmInterpreter.Run(contract, nil, false)
+ if err2 != nil {
+ t.Errorf("error: %v", err)
+ }
+}
+
+func TestUseGasContract(t *testing.T) {
+ var (
+ env = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{})
+ wasmInterpreter = NewWASMInterpreter(env, env.Config)
+ )
+
+ wasmBytes, err := ioutil.ReadFile("wasm_contracts/use_gas/use_gas.wasm")
+ if err != nil {
+ fmt.Fprintln(os.Stderr, "Error reading wasm file:", err)
+ os.Exit(1)
+ }
+
+ // Track time taken and memory usage
+ // defer trackTime(time.Now(), "wasm")
+
+ // Initialise a new contract and set the code that is to be used by the EVM.
+ // The contract is a scoped environment for this execution context only.
+ contract := NewContract(&dummyContractRef{}, &dummyContractRef{}, new(big.Int), 2000)
+ contract.SetCodeOptionalHash(nil, &codeAndHash{
+ code: wasmBytes,
+ })
+
+ _, err2 := wasmInterpreter.Run(contract, nil, false)
+ if err2 != nil {
+ t.Errorf("error: %v", err)
+ }
+}
+
+func TestGetAddressContract(t *testing.T) {
+ var (
+ env = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{})
+ wasmInterpreter = NewWASMInterpreter(env, env.Config)
+ )
+
+ wasmBytes, err := ioutil.ReadFile("wasm_contracts/get_address/get_address.wasm")
+ if err != nil {
+ fmt.Fprintln(os.Stderr, "Error reading wasm file:", err)
+ os.Exit(1)
+ }
+
+ // Track time taken and memory usage
+ // defer trackTime(time.Now(), "wasm")
+
+ // Initialise a new contract and set the code that is to be used by the EVM.
+ // The contract is a scoped environment for this execution context only.
+ contract := NewContract(&dummyContractRef{}, &dummyContractRef{}, new(big.Int), 2000)
+ contract.SetCodeOptionalHash(&common.ZeroAddr, &codeAndHash{
+ code: wasmBytes,
+ hash: crypto.Keccak256Hash(wasmBytes),
+ })
+
+ _, err2 := wasmInterpreter.Run(contract, nil, false)
+ if err2 != nil {
+ t.Errorf("error: %v", err)
+ }
+}
+
+func TestGetBlockNumber(t *testing.T) {
+ context := BlockContext{
+ BlockNumber: big.NewInt(100),
+ }
+
+ var (
+ env = NewEVM(context, TxContext{}, nil, params.TestChainConfig, Config{})
+ wasmInterpreter = NewWASMInterpreter(env, env.Config)
+ )
+
+ wasmBytes, err := ioutil.ReadFile("wasm_contracts/get_block_number/get_block_number.wasm")
+ if err != nil {
+ fmt.Fprintln(os.Stderr, "Error reading wasm file:", err)
+ os.Exit(1)
+ }
+
+ // Track time taken and memory usage
+ // defer trackTime(time.Now(), "wasm")
+
+ // Initialise a new contract and set the code that is to be used by the EVM.
+ // The contract is a scoped environment for this execution context only.
+ contract := NewContract(&dummyContractRef{}, &dummyContractRef{}, new(big.Int), 2000)
+ contract.SetCodeOptionalHash(&common.ZeroAddr, &codeAndHash{
+ code: wasmBytes,
+ hash: crypto.Keccak256Hash(wasmBytes),
+ })
+
+ _, err2 := wasmInterpreter.Run(contract, nil, false)
+ if err2 != nil {
+ t.Errorf("error: %v", err)
+ }
+}
+
+func TestGetCallerContract(t *testing.T) {
+ var (
+ env = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{})
+ wasmInterpreter = NewWASMInterpreter(env, env.Config)
+ )
+
+ wasmBytes, err := ioutil.ReadFile("wasm_contracts/get_caller/get_caller.wasm")
+ if err != nil {
+ fmt.Fprintln(os.Stderr, "Error reading wasm file:", err)
+ os.Exit(1)
+ }
+
+ // Track time taken and memory usage
+ // defer trackTime(time.Now(), "wasm")
+
+ // Initialise a new contract and set the code that is to be used by the EVM.
+ // The contract is a scoped environment for this execution context only.
+ contract := NewContract(&dummyContractRef{}, &dummyContractRef{}, new(big.Int), 2000)
+ contract.SetCodeOptionalHash(&common.ZeroAddr, &codeAndHash{
+ code: wasmBytes,
+ hash: crypto.Keccak256Hash(wasmBytes),
+ })
+
+ hexString := "0x1234567898765432123412345678987654321234"
+ contract.CallerAddress = common.HexToAddress(hexString)
+
+ _, err2 := wasmInterpreter.Run(contract, nil, false)
+ if err2 != nil {
+ t.Errorf("error: %v", err)
+ }
+}