diff options
author | Abbas Mashayekh <martianboy2005@gmail.com> | 2021-03-24 21:43:45 +0430 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-24 10:13:45 -0700 |
commit | ffac06650507ac413d60d72aadc1e33fb1f91ccf (patch) | |
tree | f581d02da66df8db2a775fc731d39baf15d96c82 /src/wasm/wasm-validator.cpp | |
parent | 683c31381f5798016f683a6b42e2a8fad0f871cb (diff) | |
download | binaryen-ffac06650507ac413d60d72aadc1e33fb1f91ccf.tar.gz binaryen-ffac06650507ac413d60d72aadc1e33fb1f91ccf.tar.bz2 binaryen-ffac06650507ac413d60d72aadc1e33fb1f91ccf.zip |
[RT] Support expressions in element segments (#3666)
This PR adds support for `ref.null t` as a valid element segment
item. The abbreviated format of `(elem ... func $f $g...)` is kept in
both printing and binary emitting if all items are `ref.func`s. Public
APIs aren't updated in this PR.
Diffstat (limited to 'src/wasm/wasm-validator.cpp')
-rw-r--r-- | src/wasm/wasm-validator.cpp | 44 |
1 files changed, 37 insertions, 7 deletions
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index 71ecf208e..52ba36872 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -1960,7 +1960,10 @@ void FunctionValidator::visitMemoryGrow(MemoryGrow* curr) { } void FunctionValidator::visitRefNull(RefNull* curr) { - shouldBeTrue(getModule()->features.hasReferenceTypes(), + // If we are not in a function, this is a global location like a table. We + // allow RefNull there as we represent tables that way regardless of what + // features are enabled. + shouldBeTrue(!getFunction() || getModule()->features.hasReferenceTypes(), curr, "ref.null requires reference-types to be enabled"); shouldBeTrue( @@ -1978,7 +1981,10 @@ void FunctionValidator::visitRefIs(RefIs* curr) { } void FunctionValidator::visitRefFunc(RefFunc* curr) { - shouldBeTrue(getModule()->features.hasReferenceTypes(), + // If we are not in a function, this is a global location like a table. We + // allow RefFunc there as we represent tables that way regardless of what + // features are enabled. + shouldBeTrue(!getFunction() || getModule()->features.hasReferenceTypes(), curr, "ref.func requires reference-types to be enabled"); if (!info.validateGlobally) { @@ -2799,11 +2805,29 @@ static void validateMemory(Module& module, ValidationInfo& info) { } static void validateTables(Module& module, ValidationInfo& info) { + FunctionValidator validator(module, &info); + if (!module.features.hasReferenceTypes()) { info.shouldBeTrue(module.tables.size() <= 1, "table", "Only 1 table definition allowed in MVP (requires " "--enable-reference-types)"); + if (!module.tables.empty()) { + auto& table = module.tables.front(); + for (auto& segment : module.elementSegments) { + info.shouldBeTrue(segment->table == table->name, + "elem", + "all element segments should refer to a single table " + "in MVP."); + for (auto* expr : segment->data) { + info.shouldBeTrue( + expr->is<RefFunc>(), + expr, + "all table elements must be non-null funcrefs in MVP."); + validator.validate(expr); + } + } + } } for (auto& segment : module.elementSegments) { @@ -2820,11 +2844,17 @@ static void validateTables(Module& module, ValidationInfo& info) { table->initial * Table::kPageSize), segment->offset, "table segment offset should be reasonable"); - FunctionValidator(module, &info).validate(segment->offset); - } - for (auto name : segment->data) { - info.shouldBeTrue( - module.getFunctionOrNull(name), name, "segment name should be valid"); + validator.validate(segment->offset); + } + // Avoid double checking items + if (module.features.hasReferenceTypes()) { + for (auto* expr : segment->data) { + info.shouldBeTrue( + expr->is<RefFunc>() || expr->is<RefNull>(), + expr, + "element segment items must be either ref.func or ref.null func."); + validator.validate(expr); + } } } } |