diff options
author | Alon Zakai <alonzakai@gmail.com> | 2019-04-16 14:38:03 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-04-16 14:38:03 -0700 |
commit | 698fddca4e598cb4f72fe61557c9f91ed879a289 (patch) | |
tree | bb27155812d1e8ddb37c3d01724c0d54b15c3a37 | |
parent | a8fde2fa899cfbca9069f0796fce284ab7a6ffc4 (diff) | |
download | binaryen-698fddca4e598cb4f72fe61557c9f91ed879a289.tar.gz binaryen-698fddca4e598cb4f72fe61557c9f91ed879a289.tar.bz2 binaryen-698fddca4e598cb4f72fe61557c9f91ed879a289.zip |
Improve instrumentation passes (#2012)
* Make the memory instrumentation pass log both pointers and values.
* Use "env" as the import module - simpler to support and get working.
-rw-r--r-- | src/passes/InstrumentLocals.cpp | 2 | ||||
-rw-r--r-- | src/passes/InstrumentMemory.cpp | 143 | ||||
-rw-r--r-- | test/passes/instrument-locals.txt | 16 | ||||
-rw-r--r-- | test/passes/instrument-memory.txt | 602 |
4 files changed, 477 insertions, 286 deletions
diff --git a/src/passes/InstrumentLocals.cpp b/src/passes/InstrumentLocals.cpp index a1835eb64..6b44af0ad 100644 --- a/src/passes/InstrumentLocals.cpp +++ b/src/passes/InstrumentLocals.cpp @@ -129,7 +129,7 @@ private: void addImport(Module* wasm, Name name, std::string sig) { auto import = new Function; import->name = name; - import->module = INSTRUMENT; + import->module = ENV; import->base = name; auto* functionType = ensureFunctionType(sig, wasm); import->type = functionType->name; diff --git a/src/passes/InstrumentMemory.cpp b/src/passes/InstrumentMemory.cpp index 17b5850f4..a929478df 100644 --- a/src/passes/InstrumentMemory.cpp +++ b/src/passes/InstrumentMemory.cpp @@ -18,27 +18,21 @@ // Instruments the build with code to intercept all memory reads and writes. // This can be useful in building tools that analyze memory access behaviour. // -// The instrumentation is performed by calling an FFI with an ID for each -// memory access site. Load / store IDs share the same index space. The -// instrumentation wraps the evaluation of the address operand, therefore -// it executes before the load / store is executed. Note that Instrumentation -// code must return tha address argument. -// -// Loads: load(id, bytes, offset, address) => address -// // Before: // (i32.load8_s align=1 offset=2 (i32.const 3)) // // After: -// (i32.load8_s align=1 offset=2 -// (call $load -// (i32.const n) // ID -// (i32.const 1) // bytes -// (i32.const 2) // offset -// (i32.const 3) // address +// (call $load_val_i32 +// (i32.const n) // ID +// (i32.load8_s align=1 offset=2 +// (call $load_ptr +// (i32.const n) // ID +// (i32.const 1) // bytes +// (i32.const 2) // offset +// (i32.const 3) // address +// ) // ) // ) -// // Stores: store(id, bytes, offset, address) => address // // Before: @@ -46,13 +40,16 @@ // // After: // (i32.store16 align=1 offset=2 -// (call $store +// (call $store_ptr // (i32.const n) // ID // (i32.const 1) // bytes // (i32.const 2) // offset // (i32.const 3) // address // ) -// (i32.const 4) +// (call $store_val_i32 +// (i32.const n) // ID +// (i32.const 4) +// ) // ) #include <wasm.h> @@ -65,57 +62,101 @@ namespace wasm { -Name load("load"); -Name store("store"); +static Name load_ptr("load_ptr"), + load_val_i32("load_val_i32"), + load_val_i64("load_val_i64"), + load_val_f32("load_val_f32"), + load_val_f64("load_val_f64"), + store_ptr("store_ptr"), + store_val_i32("store_val_i32"), + store_val_i64("store_val_i64"), + store_val_f32("store_val_f32"), + store_val_f64("store_val_f64"); + // TODO: Add support for atomicRMW/cmpxchg struct InstrumentMemory : public WalkerPass<PostWalker<InstrumentMemory>> { void visitLoad(Load* curr) { - makeLoadCall(curr); - } - void visitStore(Store* curr) { - makeStoreCall(curr); - } - void addImport(Module *curr, Name name, std::string sig) { - auto import = new Function; - import->name = name; - import->module = INSTRUMENT; - import->base = name; - auto* functionType = ensureFunctionType(sig, curr); - import->type = functionType->name; - FunctionTypeUtils::fillFunction(import, functionType); - curr->addFunction(import); - } - - void visitModule(Module *curr) { - addImport(curr, load, "iiiii"); - addImport(curr, store, "iiiii"); - } - -private: - std::atomic<Index> id; - Expression* makeLoadCall(Load* curr) { + id++; Builder builder(*getModule()); - curr->ptr = builder.makeCall(load, - { builder.makeConst(Literal(int32_t(id.fetch_add(1)))), + curr->ptr = builder.makeCall(load_ptr, + { + builder.makeConst(Literal(int32_t(id))), builder.makeConst(Literal(int32_t(curr->bytes))), builder.makeConst(Literal(int32_t(curr->offset.addr))), - curr->ptr}, + curr->ptr + }, i32 ); - return curr; + Name target; + switch (curr->type) { + case i32: target = load_val_i32; break; + case i64: target = load_val_i64; break; + case f32: target = load_val_f32; break; + case f64: target = load_val_f64; break; + default: return; // TODO: other types, unreachable, etc. + } + replaceCurrent(builder.makeCall(target, + { + builder.makeConst(Literal(int32_t(id))), + curr + }, + curr->type + )); } - Expression* makeStoreCall(Store* curr) { + void visitStore(Store* curr) { + id++; Builder builder(*getModule()); - curr->ptr = builder.makeCall(store, - { builder.makeConst(Literal(int32_t(id.fetch_add(1)))), + curr->ptr = builder.makeCall(store_ptr, + { builder.makeConst(Literal(int32_t(id))), builder.makeConst(Literal(int32_t(curr->bytes))), builder.makeConst(Literal(int32_t(curr->offset.addr))), curr->ptr }, i32 ); - return curr; + Name target; + switch (curr->value->type) { + case i32: target = store_val_i32; break; + case i64: target = store_val_i64; break; + case f32: target = store_val_f32; break; + case f64: target = store_val_f64; break; + default: return; // TODO: other types, unreachable, etc. + } + curr->value = builder.makeCall(target, + { + builder.makeConst(Literal(int32_t(id))), + curr->value + }, + curr->value->type + ); + } + + void visitModule(Module *curr) { + addImport(curr, load_ptr, "iiiii"); + addImport(curr, load_val_i32, "iii"); + addImport(curr, load_val_i64, "jij"); + addImport(curr, load_val_f32, "fif"); + addImport(curr, load_val_f64, "did"); + addImport(curr, store_ptr, "iiiii"); + addImport(curr, store_val_i32, "iii"); + addImport(curr, store_val_i64, "jij"); + addImport(curr, store_val_f32, "fif"); + addImport(curr, store_val_f64, "did"); + } + +private: + Index id; + + void addImport(Module *curr, Name name, std::string sig) { + auto import = new Function; + import->name = name; + import->module = ENV; + import->base = name; + auto* functionType = ensureFunctionType(sig, curr); + import->type = functionType->name; + FunctionTypeUtils::fillFunction(import, functionType); + curr->addFunction(import); } }; diff --git a/test/passes/instrument-locals.txt b/test/passes/instrument-locals.txt index 24cbdf44e..2637a69aa 100644 --- a/test/passes/instrument-locals.txt +++ b/test/passes/instrument-locals.txt @@ -4,14 +4,14 @@ (type $FUNCSIG$jiij (func (param i32 i32 i64) (result i64))) (type $FUNCSIG$fiif (func (param i32 i32 f32) (result f32))) (type $FUNCSIG$diid (func (param i32 i32 f64) (result f64))) - (import "instrument" "get_i32" (func $get_i32 (param i32 i32 i32) (result i32))) - (import "instrument" "get_i64" (func $get_i64 (param i32 i32 i64) (result i64))) - (import "instrument" "get_f32" (func $get_f32 (param i32 i32 f32) (result f32))) - (import "instrument" "get_f64" (func $get_f64 (param i32 i32 f64) (result f64))) - (import "instrument" "set_i32" (func $set_i32 (param i32 i32 i32) (result i32))) - (import "instrument" "set_i64" (func $set_i64 (param i32 i32 i64) (result i64))) - (import "instrument" "set_f32" (func $set_f32 (param i32 i32 f32) (result f32))) - (import "instrument" "set_f64" (func $set_f64 (param i32 i32 f64) (result f64))) + (import "env" "get_i32" (func $get_i32 (param i32 i32 i32) (result i32))) + (import "env" "get_i64" (func $get_i64 (param i32 i32 i64) (result i64))) + (import "env" "get_f32" (func $get_f32 (param i32 i32 f32) (result f32))) + (import "env" "get_f64" (func $get_f64 (param i32 i32 f64) (result f64))) + (import "env" "set_i32" (func $set_i32 (param i32 i32 i32) (result i32))) + (import "env" "set_i64" (func $set_i64 (param i32 i32 i64) (result i64))) + (import "env" "set_f32" (func $set_f32 (param i32 i32 f32) (result f32))) + (import "env" "set_f64" (func $set_f64 (param i32 i32 f64) (result f64))) (func $A (; 8 ;) (type $0) (local $x i32) (local $y i64) diff --git a/test/passes/instrument-memory.txt b/test/passes/instrument-memory.txt index fc5221c3e..1bcc9ea01 100644 --- a/test/passes/instrument-memory.txt +++ b/test/passes/instrument-memory.txt @@ -1,453 +1,603 @@ (module (type $1 (func)) (type $FUNCSIG$iiiii (func (param i32 i32 i32 i32) (result i32))) - (import "instrument" "load" (func $load (param i32 i32 i32 i32) (result i32))) - (import "instrument" "store" (func $store (param i32 i32 i32 i32) (result i32))) + (type $FUNCSIG$iii (func (param i32 i32) (result i32))) + (type $FUNCSIG$jij (func (param i32 i64) (result i64))) + (type $FUNCSIG$fif (func (param i32 f32) (result f32))) + (type $FUNCSIG$did (func (param i32 f64) (result f64))) + (import "env" "load_ptr" (func $load_ptr (param i32 i32 i32 i32) (result i32))) + (import "env" "load_val_i32" (func $load_val_i32 (param i32 i32) (result i32))) + (import "env" "load_val_i64" (func $load_val_i64 (param i32 i64) (result i64))) + (import "env" "load_val_f32" (func $load_val_f32 (param i32 f32) (result f32))) + (import "env" "load_val_f64" (func $load_val_f64 (param i32 f64) (result f64))) + (import "env" "store_ptr" (func $store_ptr (param i32 i32 i32 i32) (result i32))) + (import "env" "store_val_i32" (func $store_val_i32 (param i32 i32) (result i32))) + (import "env" "store_val_i64" (func $store_val_i64 (param i32 i64) (result i64))) + (import "env" "store_val_f32" (func $store_val_f32 (param i32 f32) (result f32))) + (import "env" "store_val_f64" (func $store_val_f64 (param i32 f64) (result f64))) (memory $0 256 256) - (func $A (; 2 ;) (type $1) + (func $A (; 10 ;) (type $1) (drop - (i32.load8_s - (call $load - (i32.const 0) - (i32.const 1) - (i32.const 0) - (i32.const 0) + (call $load_val_i32 + (i32.const 1) + (i32.load8_s + (call $load_ptr + (i32.const 1) + (i32.const 1) + (i32.const 0) + (i32.const 0) + ) ) ) ) (drop - (i32.load8_u - (call $load - (i32.const 1) - (i32.const 1) - (i32.const 0) - (i32.const 0) + (call $load_val_i32 + (i32.const 2) + (i32.load8_u + (call $load_ptr + (i32.const 2) + (i32.const 1) + (i32.const 0) + (i32.const 0) + ) ) ) ) (drop - (i32.load16_s - (call $load - (i32.const 2) - (i32.const 2) - (i32.const 0) - (i32.const 0) + (call $load_val_i32 + (i32.const 3) + (i32.load16_s + (call $load_ptr + (i32.const 3) + (i32.const 2) + (i32.const 0) + (i32.const 0) + ) ) ) ) (drop - (i32.load16_u - (call $load - (i32.const 3) - (i32.const 2) - (i32.const 0) - (i32.const 0) + (call $load_val_i32 + (i32.const 4) + (i32.load16_u + (call $load_ptr + (i32.const 4) + (i32.const 2) + (i32.const 0) + (i32.const 0) + ) ) ) ) (drop - (i32.load - (call $load - (i32.const 4) - (i32.const 4) - (i32.const 0) - (i32.const 0) + (call $load_val_i32 + (i32.const 5) + (i32.load + (call $load_ptr + (i32.const 5) + (i32.const 4) + (i32.const 0) + (i32.const 0) + ) ) ) ) (drop - (i64.load8_s - (call $load - (i32.const 5) - (i32.const 1) - (i32.const 0) - (i32.const 0) + (call $load_val_i64 + (i32.const 6) + (i64.load8_s + (call $load_ptr + (i32.const 6) + (i32.const 1) + (i32.const 0) + (i32.const 0) + ) ) ) ) (drop - (i64.load8_u - (call $load - (i32.const 6) - (i32.const 1) - (i32.const 0) - (i32.const 0) + (call $load_val_i64 + (i32.const 7) + (i64.load8_u + (call $load_ptr + (i32.const 7) + (i32.const 1) + (i32.const 0) + (i32.const 0) + ) ) ) ) (drop - (i64.load16_s - (call $load - (i32.const 7) - (i32.const 2) - (i32.const 0) - (i32.const 0) + (call $load_val_i64 + (i32.const 8) + (i64.load16_s + (call $load_ptr + (i32.const 8) + (i32.const 2) + (i32.const 0) + (i32.const 0) + ) ) ) ) (drop - (i64.load16_u - (call $load - (i32.const 8) - (i32.const 2) - (i32.const 0) - (i32.const 0) + (call $load_val_i64 + (i32.const 9) + (i64.load16_u + (call $load_ptr + (i32.const 9) + (i32.const 2) + (i32.const 0) + (i32.const 0) + ) ) ) ) (drop - (i64.load32_s - (call $load - (i32.const 9) - (i32.const 4) - (i32.const 0) - (i32.const 0) + (call $load_val_i64 + (i32.const 10) + (i64.load32_s + (call $load_ptr + (i32.const 10) + (i32.const 4) + (i32.const 0) + (i32.const 0) + ) ) ) ) (drop - (i64.load32_u - (call $load - (i32.const 10) - (i32.const 4) - (i32.const 0) - (i32.const 0) + (call $load_val_i64 + (i32.const 11) + (i64.load32_u + (call $load_ptr + (i32.const 11) + (i32.const 4) + (i32.const 0) + (i32.const 0) + ) ) ) ) (drop - (i64.load - (call $load - (i32.const 11) - (i32.const 8) - (i32.const 0) - (i32.const 0) + (call $load_val_i64 + (i32.const 12) + (i64.load + (call $load_ptr + (i32.const 12) + (i32.const 8) + (i32.const 0) + (i32.const 0) + ) ) ) ) (drop - (f32.load - (call $load - (i32.const 12) - (i32.const 4) - (i32.const 0) - (i32.const 0) + (call $load_val_f32 + (i32.const 13) + (f32.load + (call $load_ptr + (i32.const 13) + (i32.const 4) + (i32.const 0) + (i32.const 0) + ) ) ) ) (drop - (f64.load - (call $load - (i32.const 13) - (i32.const 8) - (i32.const 0) - (i32.const 0) + (call $load_val_f64 + (i32.const 14) + (f64.load + (call $load_ptr + (i32.const 14) + (i32.const 8) + (i32.const 0) + (i32.const 0) + ) ) ) ) (drop - (i32.load8_s offset=1 - (call $load - (i32.const 14) - (i32.const 1) - (i32.const 1) - (i32.const 0) + (call $load_val_i32 + (i32.const 15) + (i32.load8_s offset=1 + (call $load_ptr + (i32.const 15) + (i32.const 1) + (i32.const 1) + (i32.const 0) + ) ) ) ) (drop - (i32.load8_u offset=2 - (call $load - (i32.const 15) - (i32.const 1) - (i32.const 2) - (i32.const 0) + (call $load_val_i32 + (i32.const 16) + (i32.load8_u offset=2 + (call $load_ptr + (i32.const 16) + (i32.const 1) + (i32.const 2) + (i32.const 0) + ) ) ) ) (drop - (i32.load16_s offset=3 align=1 - (call $load - (i32.const 16) - (i32.const 2) - (i32.const 3) - (i32.const 0) + (call $load_val_i32 + (i32.const 17) + (i32.load16_s offset=3 align=1 + (call $load_ptr + (i32.const 17) + (i32.const 2) + (i32.const 3) + (i32.const 0) + ) ) ) ) (drop - (i32.load16_u offset=4 align=1 - (call $load - (i32.const 17) - (i32.const 2) - (i32.const 4) - (i32.const 0) + (call $load_val_i32 + (i32.const 18) + (i32.load16_u offset=4 align=1 + (call $load_ptr + (i32.const 18) + (i32.const 2) + (i32.const 4) + (i32.const 0) + ) ) ) ) (drop - (i32.load offset=5 align=2 - (call $load - (i32.const 18) - (i32.const 4) - (i32.const 5) - (i32.const 0) + (call $load_val_i32 + (i32.const 19) + (i32.load offset=5 align=2 + (call $load_ptr + (i32.const 19) + (i32.const 4) + (i32.const 5) + (i32.const 0) + ) ) ) ) (drop - (i64.load8_s offset=6 - (call $load - (i32.const 19) - (i32.const 1) - (i32.const 6) - (i32.const 0) + (call $load_val_i64 + (i32.const 20) + (i64.load8_s offset=6 + (call $load_ptr + (i32.const 20) + (i32.const 1) + (i32.const 6) + (i32.const 0) + ) ) ) ) (drop - (i64.load8_u offset=7 - (call $load - (i32.const 20) - (i32.const 1) - (i32.const 7) - (i32.const 0) + (call $load_val_i64 + (i32.const 21) + (i64.load8_u offset=7 + (call $load_ptr + (i32.const 21) + (i32.const 1) + (i32.const 7) + (i32.const 0) + ) ) ) ) (drop - (i64.load16_s offset=8 align=1 - (call $load - (i32.const 21) - (i32.const 2) - (i32.const 8) - (i32.const 0) + (call $load_val_i64 + (i32.const 22) + (i64.load16_s offset=8 align=1 + (call $load_ptr + (i32.const 22) + (i32.const 2) + (i32.const 8) + (i32.const 0) + ) ) ) ) (drop - (i64.load16_u offset=9 align=1 - (call $load - (i32.const 22) - (i32.const 2) - (i32.const 9) - (i32.const 0) + (call $load_val_i64 + (i32.const 23) + (i64.load16_u offset=9 align=1 + (call $load_ptr + (i32.const 23) + (i32.const 2) + (i32.const 9) + (i32.const 0) + ) ) ) ) (drop - (i64.load32_s offset=10 align=2 - (call $load - (i32.const 23) - (i32.const 4) - (i32.const 10) - (i32.const 0) + (call $load_val_i64 + (i32.const 24) + (i64.load32_s offset=10 align=2 + (call $load_ptr + (i32.const 24) + (i32.const 4) + (i32.const 10) + (i32.const 0) + ) ) ) ) (drop - (i64.load32_u offset=11 align=2 - (call $load - (i32.const 24) - (i32.const 4) - (i32.const 11) - (i32.const 0) + (call $load_val_i64 + (i32.const 25) + (i64.load32_u offset=11 align=2 + (call $load_ptr + (i32.const 25) + (i32.const 4) + (i32.const 11) + (i32.const 0) + ) ) ) ) (drop - (i64.load offset=12 align=2 - (call $load - (i32.const 25) - (i32.const 8) - (i32.const 12) - (i32.const 0) + (call $load_val_i64 + (i32.const 26) + (i64.load offset=12 align=2 + (call $load_ptr + (i32.const 26) + (i32.const 8) + (i32.const 12) + (i32.const 0) + ) ) ) ) (drop - (f32.load offset=13 align=2 - (call $load - (i32.const 26) - (i32.const 4) - (i32.const 13) - (i32.const 0) + (call $load_val_f32 + (i32.const 27) + (f32.load offset=13 align=2 + (call $load_ptr + (i32.const 27) + (i32.const 4) + (i32.const 13) + (i32.const 0) + ) ) ) ) (drop - (f64.load offset=14 align=2 - (call $load - (i32.const 27) - (i32.const 8) - (i32.const 14) - (i32.const 0) + (call $load_val_f64 + (i32.const 28) + (f64.load offset=14 align=2 + (call $load_ptr + (i32.const 28) + (i32.const 8) + (i32.const 14) + (i32.const 0) + ) ) ) ) ) - (func $B (; 3 ;) (type $1) + (func $B (; 11 ;) (type $1) (i32.store8 - (call $store - (i32.const 28) + (call $store_ptr + (i32.const 29) (i32.const 1) (i32.const 0) (i32.const 0) ) - (i32.const 1) + (call $store_val_i32 + (i32.const 29) + (i32.const 1) + ) ) (i32.store16 - (call $store - (i32.const 29) + (call $store_ptr + (i32.const 30) (i32.const 2) (i32.const 0) (i32.const 0) ) - (i32.const 2) + (call $store_val_i32 + (i32.const 30) + (i32.const 2) + ) ) (i32.store - (call $store - (i32.const 30) + (call $store_ptr + (i32.const 31) (i32.const 4) (i32.const 0) (i32.const 0) ) - (i32.const 3) + (call $store_val_i32 + (i32.const 31) + (i32.const 3) + ) ) (i64.store8 - (call $store - (i32.const 31) + (call $store_ptr + (i32.const 32) (i32.const 1) (i32.const 0) (i32.const 0) ) - (i64.const 4) + (call $store_val_i64 + (i32.const 32) + (i64.const 4) + ) ) (i64.store16 - (call $store - (i32.const 32) + (call $store_ptr + (i32.const 33) (i32.const 2) (i32.const 0) (i32.const 0) ) - (i64.const 5) + (call $store_val_i64 + (i32.const 33) + (i64.const 5) + ) ) (i64.store32 - (call $store - (i32.const 33) + (call $store_ptr + (i32.const 34) (i32.const 4) (i32.const 0) (i32.const 0) ) - (i64.const 6) + (call $store_val_i64 + (i32.const 34) + (i64.const 6) + ) ) (i64.store - (call $store - (i32.const 34) + (call $store_ptr + (i32.const 35) (i32.const 8) (i32.const 0) (i32.const 0) ) - (i64.const 7) + (call $store_val_i64 + (i32.const 35) + (i64.const 7) + ) ) (f32.store - (call $store - (i32.const 35) + (call $store_ptr + (i32.const 36) (i32.const 4) (i32.const 0) (i32.const 0) ) - (f32.const 8) + (call $store_val_f32 + (i32.const 36) + (f32.const 8) + ) ) (f64.store - (call $store - (i32.const 36) + (call $store_ptr + (i32.const 37) (i32.const 8) (i32.const 0) (i32.const 0) ) - (f64.const 9) + (call $store_val_f64 + (i32.const 37) + (f64.const 9) + ) ) (i32.store8 offset=1 - (call $store - (i32.const 37) + (call $store_ptr + (i32.const 38) (i32.const 1) (i32.const 1) (i32.const 0) ) - (i32.const 1) + (call $store_val_i32 + (i32.const 38) + (i32.const 1) + ) ) (i32.store16 offset=2 align=1 - (call $store - (i32.const 38) + (call $store_ptr + (i32.const 39) (i32.const 2) (i32.const 2) (i32.const 0) ) - (i32.const 2) + (call $store_val_i32 + (i32.const 39) + (i32.const 2) + ) ) (i32.store offset=3 align=2 - (call $store - (i32.const 39) + (call $store_ptr + (i32.const 40) (i32.const 4) (i32.const 3) (i32.const 0) ) - (i32.const 3) + (call $store_val_i32 + (i32.const 40) + (i32.const 3) + ) ) (i64.store8 offset=4 - (call $store - (i32.const 40) + (call $store_ptr + (i32.const 41) (i32.const 1) (i32.const 4) (i32.const 0) ) - (i64.const 4) + (call $store_val_i64 + (i32.const 41) + (i64.const 4) + ) ) (i64.store16 offset=5 - (call $store - (i32.const 41) + (call $store_ptr + (i32.const 42) (i32.const 2) (i32.const 5) (i32.const 0) ) - (i64.const 5) + (call $store_val_i64 + (i32.const 42) + (i64.const 5) + ) ) (i64.store32 offset=6 align=2 - (call $store - (i32.const 42) + (call $store_ptr + (i32.const 43) (i32.const 4) (i32.const 6) (i32.const 0) ) - (i64.const 6) + (call $store_val_i64 + (i32.const 43) + (i64.const 6) + ) ) (i64.store offset=7 align=2 - (call $store - (i32.const 43) + (call $store_ptr + (i32.const 44) (i32.const 8) (i32.const 7) (i32.const 0) ) - (i64.const 7) + (call $store_val_i64 + (i32.const 44) + (i64.const 7) + ) ) (f32.store offset=8 align=2 - (call $store - (i32.const 44) + (call $store_ptr + (i32.const 45) (i32.const 4) (i32.const 8) (i32.const 0) ) - (f32.const 8) + (call $store_val_f32 + (i32.const 45) + (f32.const 8) + ) ) (f64.store offset=9 align=2 - (call $store - (i32.const 45) + (call $store_ptr + (i32.const 46) (i32.const 8) (i32.const 9) (i32.const 0) ) - (f64.const 9) + (call $store_val_f64 + (i32.const 46) + (f64.const 9) + ) ) ) ) |