diff options
-rw-r--r-- | CHANGELOG.md | 2 | ||||
-rw-r--r-- | src/binaryen-c.cpp | 11 | ||||
-rw-r--r-- | src/binaryen-c.h | 6 | ||||
-rw-r--r-- | test/example/c-api-kitchen-sink.c | 26 |
4 files changed, 41 insertions, 4 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index fc03cf492..b42efef38 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,8 @@ Current Trunk - (If new wat parser is enabled) Source map comments on `else` branches must now be placed above the instruction inside the `else` branch rather than on the `else` branch itself. + - Add a new `BinaryenModuleReadWithFeatures` function to the C API that allows + to configure which features to enable in the parser. v117 ---- diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp index f9a778a68..29e0597d7 100644 --- a/src/binaryen-c.cpp +++ b/src/binaryen-c.cpp @@ -5851,14 +5851,15 @@ char* BinaryenModuleAllocateAndWriteStackIR(BinaryenModuleRef module, return output; } -BinaryenModuleRef BinaryenModuleRead(char* input, size_t inputSize) { +BinaryenModuleRef BinaryenModuleReadWithFeatures(char* input, + size_t inputSize, + BinaryenFeatures features) { auto* wasm = new Module; std::vector<char> buffer(false); buffer.resize(inputSize); std::copy_n(input, inputSize, buffer.begin()); try { - // TODO: allow providing features in the C API - WasmBinaryReader parser(*wasm, FeatureSet::MVP, buffer); + WasmBinaryReader parser(*wasm, features, buffer); parser.read(); } catch (ParseException& p) { p.dump(std::cerr); @@ -5867,6 +5868,10 @@ BinaryenModuleRef BinaryenModuleRead(char* input, size_t inputSize) { return wasm; } +BinaryenModuleRef BinaryenModuleRead(char* input, size_t inputSize) { + return BinaryenModuleReadWithFeatures(input, inputSize, BinaryenFeatureMVP()); +} + void BinaryenModuleInterpret(BinaryenModuleRef module) { ShellExternalInterface interface; ModuleRunner instance(*(Module*)module, &interface, {}); diff --git a/src/binaryen-c.h b/src/binaryen-c.h index 4ead70ea4..42bd45915 100644 --- a/src/binaryen-c.h +++ b/src/binaryen-c.h @@ -3175,10 +3175,14 @@ BINARYEN_API char* BinaryenModuleAllocateAndWriteText(BinaryenModuleRef module); BINARYEN_API char* BinaryenModuleAllocateAndWriteStackIR(BinaryenModuleRef module, bool optimize); -// Deserialize a module from binary form. +// Deserialize a module from binary form, assuming the MVP feature set. BINARYEN_API BinaryenModuleRef BinaryenModuleRead(char* input, size_t inputSize); +// Deserialize a module from binary form, enabling the given feature set. +BINARYEN_API BinaryenModuleRef BinaryenModuleReadWithFeatures( + char* input, size_t inputSize, BinaryenFeatures featureSet); + // Execute a module in the Binaryen interpreter. This will create an instance of // the module, run it in the interpreter - which means running the start method // - and then destroying the instance. diff --git a/test/example/c-api-kitchen-sink.c b/test/example/c-api-kitchen-sink.c index bf80833a0..e5b614bec 100644 --- a/test/example/c-api-kitchen-sink.c +++ b/test/example/c-api-kitchen-sink.c @@ -401,6 +401,32 @@ void test_features() { printf("BinaryenFeatureAll: %d\n", BinaryenFeatureAll()); } +void test_read_with_feature() { + BinaryenModuleRef module = BinaryenModuleCreate(); + // Having multiple tables makes this module inherently not MVP compatible + // and requires the externref feature enabled to parse successfully. + BinaryenAddTable(module, "tab", 0, 100, BinaryenTypeFuncref()); + BinaryenAddTable(module, "tab2", 0, 100, BinaryenTypeFuncref()); + + BinaryenFeatures features = + BinaryenFeatureMVP() | BinaryenFeatureReferenceTypes(); + BinaryenModuleSetFeatures(module, features); + + size_t bufferSize = 1024; + char* buffer = malloc(bufferSize); + size_t written = BinaryenModuleWrite(module, buffer, bufferSize); + BinaryenModuleDispose(module); + + // See we can read the bytes and get a valid module from there. + BinaryenModuleRef readModule = + BinaryenModuleReadWithFeatures(buffer, written, features); + int valid = BinaryenModuleValidate(readModule); + assert(valid); + BinaryenModuleDispose(readModule); + + free(buffer); +} + void test_core() { // Module creation |