diff options
Diffstat (limited to 'src/wasm/wasm-binary.cpp')
-rw-r--r-- | src/wasm/wasm-binary.cpp | 98 |
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) { |