diff options
-rw-r--r-- | src/binaryen-c.cpp | 21 | ||||
-rw-r--r-- | src/binaryen-c.h | 7 | ||||
-rw-r--r-- | test/example/c-api-kitchen-sink.c | 30 | ||||
-rw-r--r-- | test/example/c-api-kitchen-sink.txt | 11 |
4 files changed, 69 insertions, 0 deletions
diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp index a876c998b..d46125bb3 100644 --- a/src/binaryen-c.cpp +++ b/src/binaryen-c.cpp @@ -21,6 +21,7 @@ #include "binaryen-c.h" #include "pass.h" #include "wasm.h" +#include "wasm-binary.h" #include "wasm-builder.h" #include "wasm-printing.h" #include "wasm-validator.h" @@ -398,6 +399,26 @@ void BinaryenModuleOptimize(BinaryenModuleRef module) { passRunner.run(); } +size_t BinaryenModuleWrite(BinaryenModuleRef module, char* output, size_t outputSize) { + Module* wasm = (Module*)module; + BufferWithRandomAccess buffer(false); + WasmBinaryWriter writer(wasm, buffer, false); + writer.write(); + size_t bytes = std::min(buffer.size(), outputSize); + std::copy_n(buffer.begin(), bytes, output); + return bytes; +} + +BinaryenModuleRef BinaryenModuleRead(char* input, size_t inputSize) { + auto* wasm = new Module; + std::vector<char> buffer(false); + buffer.resize(inputSize); + std::copy_n(input, inputSize, buffer.begin()); + WasmBinaryBuilder parser(*wasm, buffer, false); + parser.read(); + return wasm; +} + // // ========== CFG / Relooper ========== // diff --git a/src/binaryen-c.h b/src/binaryen-c.h index 9319de209..da445dfb2 100644 --- a/src/binaryen-c.h +++ b/src/binaryen-c.h @@ -273,6 +273,13 @@ int BinaryenModuleValidate(BinaryenModuleRef module); // Run the standard optimization passes on the module. void BinaryenModuleOptimize(BinaryenModuleRef module); +// Serialize a module into binary form. +// @return how many bytes were written. This will be less than or equal to bufferSize +size_t BinaryenModuleWrite(BinaryenModuleRef module, char* output, size_t outputSize); + +// Deserialize a module from binary form. +BinaryenModuleRef BinaryenModuleRead(char* input, size_t inputSize); + // // ========== CFG / Relooper ========== // diff --git a/test/example/c-api-kitchen-sink.c b/test/example/c-api-kitchen-sink.c index ee32725c1..4a63e931d 100644 --- a/test/example/c-api-kitchen-sink.c +++ b/test/example/c-api-kitchen-sink.c @@ -377,8 +377,38 @@ void test_relooper() { BinaryenModuleDispose(module); } +void test_binaries() { + char buffer[1024]; + size_t size; + + { // create a module and write it to binary + BinaryenModuleRef module = BinaryenModuleCreate(); + BinaryenType params[2] = { BinaryenInt32(), BinaryenInt32() }; + BinaryenFunctionTypeRef iii = BinaryenAddFunctionType(module, "iii", BinaryenInt32(), params, 2); + BinaryenExpressionRef x = BinaryenGetLocal(module, 0, BinaryenInt32()), + y = BinaryenGetLocal(module, 1, BinaryenInt32()); + BinaryenExpressionRef add = BinaryenBinary(module, BinaryenAdd(), x, y); + BinaryenFunctionRef adder = BinaryenAddFunction(module, "adder", iii, NULL, 0, add); + size = BinaryenModuleWrite(module, buffer, 1024); // write out the module + BinaryenModuleDispose(module); + } + + assert(size > 0); + assert(size < 512); // this is a tiny module + + // read the module from the binary + BinaryenModuleRef module = BinaryenModuleRead(buffer, size); + + // validate, print, and free + assert(BinaryenModuleValidate(module)); + printf("module loaded from binary form:\n"); + BinaryenModulePrint(module); + BinaryenModuleDispose(module); +} + int main() { test_core(); test_relooper(); + test_binaries(); } diff --git a/test/example/c-api-kitchen-sink.txt b/test/example/c-api-kitchen-sink.txt index 226e937ce..cb037d80c 100644 --- a/test/example/c-api-kitchen-sink.txt +++ b/test/example/c-api-kitchen-sink.txt @@ -761,3 +761,14 @@ optimized: (i32.const 6) ) ) +module loaded from binary form: +(module + (memory 0) + (type $0 (func (param i32 i32) (result i32))) + (func $adder (type $0) (param $var$0 i32) (param $var$1 i32) (result i32) + (i32.add + (get_local $var$0) + (get_local $var$1) + ) + ) +) |