Skip to content

Commit ab9e3f7

Browse files
authored
Expose features option in C API binary reading (#6380)
This allows reading a module that requires a particular feature set. The old API assumed only MVP features.
1 parent 920cbc3 commit ab9e3f7

File tree

4 files changed

+41
-4
lines changed

4 files changed

+41
-4
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ Current Trunk
1818
- (If new wat parser is enabled) Source map comments on `else` branches must
1919
now be placed above the instruction inside the `else` branch rather than on
2020
the `else` branch itself.
21+
- Add a new `BinaryenModuleReadWithFeatures` function to the C API that allows
22+
to configure which features to enable in the parser.
2123

2224
v117
2325
----

src/binaryen-c.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5851,14 +5851,15 @@ char* BinaryenModuleAllocateAndWriteStackIR(BinaryenModuleRef module,
58515851
return output;
58525852
}
58535853

5854-
BinaryenModuleRef BinaryenModuleRead(char* input, size_t inputSize) {
5854+
BinaryenModuleRef BinaryenModuleReadWithFeatures(char* input,
5855+
size_t inputSize,
5856+
BinaryenFeatures features) {
58555857
auto* wasm = new Module;
58565858
std::vector<char> buffer(false);
58575859
buffer.resize(inputSize);
58585860
std::copy_n(input, inputSize, buffer.begin());
58595861
try {
5860-
// TODO: allow providing features in the C API
5861-
WasmBinaryReader parser(*wasm, FeatureSet::MVP, buffer);
5862+
WasmBinaryReader parser(*wasm, features, buffer);
58625863
parser.read();
58635864
} catch (ParseException& p) {
58645865
p.dump(std::cerr);
@@ -5867,6 +5868,10 @@ BinaryenModuleRef BinaryenModuleRead(char* input, size_t inputSize) {
58675868
return wasm;
58685869
}
58695870

5871+
BinaryenModuleRef BinaryenModuleRead(char* input, size_t inputSize) {
5872+
return BinaryenModuleReadWithFeatures(input, inputSize, BinaryenFeatureMVP());
5873+
}
5874+
58705875
void BinaryenModuleInterpret(BinaryenModuleRef module) {
58715876
ShellExternalInterface interface;
58725877
ModuleRunner instance(*(Module*)module, &interface, {});

src/binaryen-c.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3175,10 +3175,14 @@ BINARYEN_API char* BinaryenModuleAllocateAndWriteText(BinaryenModuleRef module);
31753175
BINARYEN_API char*
31763176
BinaryenModuleAllocateAndWriteStackIR(BinaryenModuleRef module, bool optimize);
31773177

3178-
// Deserialize a module from binary form.
3178+
// Deserialize a module from binary form, assuming the MVP feature set.
31793179
BINARYEN_API BinaryenModuleRef BinaryenModuleRead(char* input,
31803180
size_t inputSize);
31813181

3182+
// Deserialize a module from binary form, enabling the given feature set.
3183+
BINARYEN_API BinaryenModuleRef BinaryenModuleReadWithFeatures(
3184+
char* input, size_t inputSize, BinaryenFeatures featureSet);
3185+
31823186
// Execute a module in the Binaryen interpreter. This will create an instance of
31833187
// the module, run it in the interpreter - which means running the start method
31843188
// - and then destroying the instance.

test/example/c-api-kitchen-sink.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,32 @@ void test_features() {
401401
printf("BinaryenFeatureAll: %d\n", BinaryenFeatureAll());
402402
}
403403

404+
void test_read_with_feature() {
405+
BinaryenModuleRef module = BinaryenModuleCreate();
406+
// Having multiple tables makes this module inherently not MVP compatible
407+
// and requires the externref feature enabled to parse successfully.
408+
BinaryenAddTable(module, "tab", 0, 100, BinaryenTypeFuncref());
409+
BinaryenAddTable(module, "tab2", 0, 100, BinaryenTypeFuncref());
410+
411+
BinaryenFeatures features =
412+
BinaryenFeatureMVP() | BinaryenFeatureReferenceTypes();
413+
BinaryenModuleSetFeatures(module, features);
414+
415+
size_t bufferSize = 1024;
416+
char* buffer = malloc(bufferSize);
417+
size_t written = BinaryenModuleWrite(module, buffer, bufferSize);
418+
BinaryenModuleDispose(module);
419+
420+
// See we can read the bytes and get a valid module from there.
421+
BinaryenModuleRef readModule =
422+
BinaryenModuleReadWithFeatures(buffer, written, features);
423+
int valid = BinaryenModuleValidate(readModule);
424+
assert(valid);
425+
BinaryenModuleDispose(readModule);
426+
427+
free(buffer);
428+
}
429+
404430
void test_core() {
405431

406432
// Module creation

0 commit comments

Comments
 (0)