summaryrefslogtreecommitdiff
path: root/src/wasm/wasm-binary.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/wasm/wasm-binary.cpp')
-rw-r--r--src/wasm/wasm-binary.cpp98
1 files changed, 58 insertions, 40 deletions
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index 31fe1bc6e..581dbd6a2 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -1319,6 +1319,14 @@ void WasmBinaryWriter::writeField(const Field& field) {
// reader
+WasmBinaryBuilder::WasmBinaryBuilder(Module& wasm,
+ FeatureSet features,
+ const std::vector<char>& input)
+ : wasm(wasm), allocator(wasm.allocator), input(input), sourceMap(nullptr),
+ nextDebugLocation(0, {0, 0, 0}), debugLocation() {
+ wasm.features = features;
+}
+
bool WasmBinaryBuilder::hasDWARFSections() {
assert(pos == 0);
getInt32(); // magic
@@ -3186,22 +3194,21 @@ void WasmBinaryBuilder::readNames(size_t payloadLen) {
void WasmBinaryBuilder::readFeatures(size_t payloadLen) {
wasm.hasFeaturesSection = true;
- wasm.features = FeatureSet::MVP;
auto sectionPos = pos;
size_t numFeatures = getU32LEB();
for (size_t i = 0; i < numFeatures; ++i) {
uint8_t prefix = getInt8();
- if (prefix != BinaryConsts::FeatureUsed) {
- if (prefix == BinaryConsts::FeatureRequired) {
- std::cerr
- << "warning: required features in feature section are ignored";
- } else if (prefix == BinaryConsts::FeatureDisallowed) {
- std::cerr
- << "warning: disallowed features in feature section are ignored";
- } else {
- throwError("Unrecognized feature policy prefix");
- }
+
+ bool disallowed = prefix == BinaryConsts::FeatureDisallowed;
+ bool required = prefix == BinaryConsts::FeatureRequired;
+ bool used = prefix == BinaryConsts::FeatureUsed;
+
+ if (!disallowed && !required && !used) {
+ throwError("Unrecognized feature policy prefix");
+ }
+ if (required) {
+ std::cerr << "warning: required features in feature section are ignored";
}
Name name = getInlineString();
@@ -3209,35 +3216,46 @@ void WasmBinaryBuilder::readFeatures(size_t payloadLen) {
throwError("ill-formed string extends beyond section");
}
- if (prefix != BinaryConsts::FeatureDisallowed) {
- if (name == BinaryConsts::UserSections::AtomicsFeature) {
- wasm.features.setAtomics();
- } else if (name == BinaryConsts::UserSections::BulkMemoryFeature) {
- wasm.features.setBulkMemory();
- } else if (name == BinaryConsts::UserSections::ExceptionHandlingFeature) {
- wasm.features.setExceptionHandling();
- } else if (name == BinaryConsts::UserSections::MutableGlobalsFeature) {
- wasm.features.setMutableGlobals();
- } else if (name == BinaryConsts::UserSections::TruncSatFeature) {
- wasm.features.setTruncSat();
- } else if (name == BinaryConsts::UserSections::SignExtFeature) {
- wasm.features.setSignExt();
- } else if (name == BinaryConsts::UserSections::SIMD128Feature) {
- wasm.features.setSIMD();
- } else if (name == BinaryConsts::UserSections::TailCallFeature) {
- wasm.features.setTailCall();
- } else if (name == BinaryConsts::UserSections::ReferenceTypesFeature) {
- wasm.features.setReferenceTypes();
- } else if (name == BinaryConsts::UserSections::MultivalueFeature) {
- wasm.features.setMultivalue();
- } else if (name == BinaryConsts::UserSections::GCFeature) {
- wasm.features.setGC();
- } else if (name == BinaryConsts::UserSections::Memory64Feature) {
- wasm.features.setMemory64();
- } else if (name ==
- BinaryConsts::UserSections::TypedFunctionReferencesFeature) {
- wasm.features.setTypedFunctionReferences();
- }
+ FeatureSet feature;
+ if (name == BinaryConsts::UserSections::AtomicsFeature) {
+ feature = FeatureSet::Atomics;
+ } else if (name == BinaryConsts::UserSections::BulkMemoryFeature) {
+ feature = FeatureSet::BulkMemory;
+ } else if (name == BinaryConsts::UserSections::ExceptionHandlingFeature) {
+ feature = FeatureSet::ExceptionHandling;
+ } else if (name == BinaryConsts::UserSections::MutableGlobalsFeature) {
+ feature = FeatureSet::MutableGlobals;
+ } else if (name == BinaryConsts::UserSections::TruncSatFeature) {
+ feature = FeatureSet::TruncSat;
+ } else if (name == BinaryConsts::UserSections::SignExtFeature) {
+ feature = FeatureSet::SignExt;
+ } else if (name == BinaryConsts::UserSections::SIMD128Feature) {
+ feature = FeatureSet::SIMD;
+ } else if (name == BinaryConsts::UserSections::TailCallFeature) {
+ feature = FeatureSet::TailCall;
+ } else if (name == BinaryConsts::UserSections::ReferenceTypesFeature) {
+ feature = FeatureSet::ReferenceTypes;
+ } else if (name == BinaryConsts::UserSections::MultivalueFeature) {
+ feature = FeatureSet::Multivalue;
+ } else if (name == BinaryConsts::UserSections::GCFeature) {
+ feature = FeatureSet::GC;
+ } else if (name == BinaryConsts::UserSections::Memory64Feature) {
+ feature = FeatureSet::Memory64;
+ } else if (name ==
+ BinaryConsts::UserSections::TypedFunctionReferencesFeature) {
+ feature = FeatureSet::TypedFunctionReferences;
+ } else {
+ // Silently ignore unknown features (this may be and old binaryen running
+ // on a new wasm).
+ }
+
+ if (disallowed && wasm.features.has(feature)) {
+ std::cerr
+ << "warning: feature " << feature.toString()
+ << " was enabled by the user, but disallowed in the features section.";
+ }
+ if (required || used) {
+ wasm.features.enable(feature);
}
}
if (pos != sectionPos + payloadLen) {