diff options
Diffstat (limited to 'src/wasm')
-rw-r--r-- | src/wasm/wasm-binary.cpp | 4 | ||||
-rw-r--r-- | src/wasm/wasm-validator.cpp | 29 | ||||
-rw-r--r-- | src/wasm/wasm.cpp | 1 |
3 files changed, 25 insertions, 9 deletions
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 1ddb009cf..f43346fdb 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -1084,6 +1084,8 @@ void WasmBinaryWriter::writeFeaturesSection() { return BinaryConsts::UserSections::TypedFunctionReferencesFeature; case FeatureSet::RelaxedSIMD: return BinaryConsts::UserSections::RelaxedSIMDFeature; + case FeatureSet::ExtendedConst: + return BinaryConsts::UserSections::ExtendedConstFeature; default: WASM_UNREACHABLE("unexpected feature flag"); } @@ -3350,6 +3352,8 @@ void WasmBinaryBuilder::readFeatures(size_t payloadLen) { feature = FeatureSet::TypedFunctionReferences; } else if (name == BinaryConsts::UserSections::RelaxedSIMDFeature) { feature = FeatureSet::RelaxedSIMD; + } else if (name == BinaryConsts::UserSections::ExtendedConstFeature) { + feature = FeatureSet::ExtendedConst; } else { // Silently ignore unknown features (this may be and old binaryen running // on a new wasm). diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index 65fcc7a9d..86fc4811b 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -2767,13 +2767,21 @@ void FunctionValidator::visitFunction(Function* curr) { } } -static bool checkSegmentOffset(Expression* curr, Address add, Address max) { - if (curr->is<GlobalGet>()) { - return true; +static bool checkSegmentOffset(Expression* curr, + Address add, + Address max, + FeatureSet features) { + if (!Properties::isValidInConstantExpression(curr, features)) { + return false; } auto* c = curr->dynCast<Const>(); if (!c) { - return false; + // Unless the instruction is actually a const instruction, we don't + // currently try to evaluate it. + // TODO: Attempt to evaluate other expressions that might also be const + // such as `global.get` or more complex instruction sequences involving + // add/sub/mul/etc. + return true; } uint64_t raw = c->value.getInteger(); if (raw > std::numeric_limits<Address::address32_t>::max()) { @@ -2999,9 +3007,10 @@ static void validateGlobals(Module& module, ValidationInfo& info) { info.shouldBeTrue( curr->init != nullptr, curr->name, "global init must be non-null"); assert(curr->init); - info.shouldBeTrue(GlobalUtils::canInitializeGlobal(curr->init), - curr->name, - "global init must be valid"); + info.shouldBeTrue( + GlobalUtils::canInitializeGlobal(curr->init, module.features), + curr->name, + "global init must be valid"); if (!info.shouldBeSubType(curr->init->type, curr->type, @@ -3066,7 +3075,8 @@ static void validateMemory(Module& module, ValidationInfo& info) { } info.shouldBeTrue(checkSegmentOffset(segment.offset, segment.data.size(), - curr.initial * Memory::kPageSize), + curr.initial * Memory::kPageSize, + module.features), segment.offset, "memory segment offset should be reasonable"); if (segment.offset->is<Const>()) { @@ -3171,7 +3181,8 @@ static void validateTables(Module& module, ValidationInfo& info) { "element segment offset should be i32"); info.shouldBeTrue(checkSegmentOffset(segment->offset, segment->data.size(), - table->initial * Table::kPageSize), + table->initial * Table::kPageSize, + module.features), segment->offset, "table segment offset should be reasonable"); if (module.features.hasTypedFunctionReferences()) { diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index aac8b44fe..ca9691346 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -49,6 +49,7 @@ const char* GCFeature = "gc"; const char* Memory64Feature = "memory64"; const char* TypedFunctionReferencesFeature = "typed-function-references"; const char* RelaxedSIMDFeature = "relaxed-simd"; +const char* ExtendedConstFeature = "extended-const"; } // namespace UserSections } // namespace BinaryConsts |