summaryrefslogtreecommitdiff
path: root/src/wasm
diff options
context:
space:
mode:
Diffstat (limited to 'src/wasm')
-rw-r--r--src/wasm/wasm-binary.cpp4
-rw-r--r--src/wasm/wasm-validator.cpp29
-rw-r--r--src/wasm/wasm.cpp1
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