diff options
Diffstat (limited to 'src/wasm/wasm-validator.cpp')
-rw-r--r-- | src/wasm/wasm-validator.cpp | 68 |
1 files changed, 65 insertions, 3 deletions
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index 484376358..1db8ed7c0 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -319,6 +319,8 @@ public: void visitThrow(Throw* curr); void visitRethrow(Rethrow* curr); void visitBrOnExn(BrOnExn* curr); + void visitTupleMake(TupleMake* curr); + void visitTupleExtract(TupleExtract* curr); void visitFunction(Function* curr); // helpers @@ -386,6 +388,11 @@ void FunctionValidator::noteLabelName(Name name) { } void FunctionValidator::visitBlock(Block* curr) { + if (!getModule()->features.hasMultivalue()) { + shouldBeTrue(!curr->type.isMulti(), + curr, + "Multivalue block type (multivalue is not enabled)"); + } // if we are break'ed to, then the value must be right for us if (curr->name.is()) { noteLabelName(curr->name); @@ -1744,6 +1751,14 @@ void FunctionValidator::visitSelect(Select* curr) { curr->condition->type == Type::i32, curr, "select condition must be valid"); + if (curr->ifTrue->type != Type::unreachable) { + shouldBeTrue( + curr->ifTrue->type.isSingle(), curr, "select value may not be a tuple"); + } + if (curr->ifFalse->type != Type::unreachable) { + shouldBeTrue( + curr->ifFalse->type.isSingle(), curr, "select value may not be a tuple"); + } if (curr->type != Type::unreachable) { shouldBeTrue(Type::isSubType(curr->ifTrue->type, curr->type), curr, @@ -1887,10 +1902,46 @@ void FunctionValidator::visitBrOnExn(BrOnExn* curr) { } } +void FunctionValidator::visitTupleMake(TupleMake* curr) { + std::vector<Type> types; + for (auto* op : curr->operands) { + if (op->type == Type::unreachable) { + shouldBeTrue( + curr->type == Type::unreachable, + curr, + "If tuple.make has an unreachable operand, it must be unreachable"); + return; + } + types.push_back(op->type); + } + shouldBeTrue(Type(types) == curr->type, + curr, + "Type of tuple.make does not match types of its operands"); +} + +void FunctionValidator::visitTupleExtract(TupleExtract* curr) { + if (curr->tuple->type == Type::unreachable) { + shouldBeTrue( + curr->type == Type::unreachable, + curr, + "If tuple.extract has an unreachable operand, it must be unreachable"); + } else { + shouldBeTrue(curr->index < curr->tuple->type.size(), + curr, + "tuple.extract index out of bounds"); + shouldBeTrue( + curr->type == curr->tuple->type.expand()[curr->index], + curr, + "tuple.extract type does not match the type of the extracted element"); + } +} + void FunctionValidator::visitFunction(Function* curr) { - shouldBeTrue(!curr->sig.results.isMulti(), - curr->body, - "Multivalue functions not allowed yet"); + if (curr->sig.results.isMulti()) { + shouldBeTrue(getModule()->features.hasMultivalue(), + curr->body, + "Multivalue function results (multivalue is not enabled)"); + } FeatureSet features; for (auto type : curr->sig.params.expand()) { features |= type.getFeatures(); @@ -2053,6 +2104,12 @@ static void validateBinaryenIR(Module& wasm, ValidationInfo& info) { static void validateImports(Module& module, ValidationInfo& info) { ModuleUtils::iterImportedFunctions(module, [&](Function* curr) { + if (curr->sig.results.isMulti()) { + info.shouldBeTrue(module.features.hasMultivalue(), + curr->name, + "Imported multivalue function " + "(multivalue is not enabled)"); + } if (info.validateWeb) { for (Type param : curr->sig.params.expand()) { info.shouldBeUnequal(param, @@ -2252,6 +2309,11 @@ static void validateEvents(Module& module, ValidationInfo& info) { Type(Type::none), curr->name, "Event type's result type should be none"); + if (curr->sig.params.isMulti()) { + info.shouldBeTrue(module.features.hasMultivalue(), + curr->name, + "Multivalue event type (multivalue is not enabled)"); + } for (auto type : curr->sig.params.expand()) { info.shouldBeTrue(type.isConcrete(), curr->name, |