summaryrefslogtreecommitdiff
path: root/src/ir/module-utils.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/ir/module-utils.h')
-rw-r--r--src/ir/module-utils.h71
1 files changed, 70 insertions, 1 deletions
diff --git a/src/ir/module-utils.h b/src/ir/module-utils.h
index 66d3a1015..259ec9fea 100644
--- a/src/ir/module-utils.h
+++ b/src/ir/module-utils.h
@@ -17,6 +17,7 @@
#ifndef wasm_ir_module_h
#define wasm_ir_module_h
+#include "wasm-binary.h"
#include "wasm.h"
#include "ir/find_all.h"
#include "ir/manipulation.h"
@@ -68,6 +69,75 @@ struct BinaryIndexes {
}
};
+// Read the features section into the out param, if it is present. If it is not
+// present, return false
+inline bool readFeaturesSection(const Module& module, FeatureSet& features) try {
+ features = FeatureSet::MVP;
+
+ const UserSection* section = nullptr;
+ for (auto &s : module.userSections) {
+ if (s.name == BinaryConsts::UserSections::TargetFeatures) {
+ section = &s;
+ break;
+ }
+ }
+
+ if (!section) {
+ return false;
+ }
+
+ // read target features section
+ size_t index = 0;
+ auto next_byte = [&]() {
+ return section->data.at(index++);
+ };
+
+ size_t num_feats = U32LEB().read(next_byte).value;
+ for (size_t i = 0; i < num_feats; ++i) {
+ uint8_t prefix = section->data.at(index++);
+ if (prefix != '=' && prefix != '+' && prefix != '-') {
+ // unrecognized prefix, silently fail
+ features = FeatureSet::MVP;
+ return false;
+ }
+
+ size_t len = U32LEB().read(next_byte).value;
+ if (index + len > section->data.size()) {
+ // ill-formed string, silently fail
+ features = FeatureSet::MVP;
+ return false;
+ }
+ std::string name(&section->data[index], len);
+ index += len;
+
+ if (prefix == '-') {
+ continue;
+ }
+
+ if (name == BinaryConsts::UserSections::AtomicsFeature) {
+ features.setAtomics();
+ } else if (name == BinaryConsts::UserSections::BulkMemoryFeature) {
+ features.setBulkMemory();
+ } else if (name == BinaryConsts::UserSections::ExceptionHandlingFeature) {
+ WASM_UNREACHABLE(); // TODO: exception handling
+ } else if (name == BinaryConsts::UserSections::TruncSatFeature) {
+ features.setTruncSat();
+ } else if (name == BinaryConsts::UserSections::SignExtFeature) {
+ features.setSignExt();
+ } else if (name == BinaryConsts::UserSections::SIMD128Feature) {
+ features.setSIMD();
+ }
+ }
+
+ return true;
+
+// silently fail to read features. Maybe this should warn?
+} catch (std::out_of_range& e) {
+ features = FeatureSet::MVP;
+ return false;
+}
+
+
inline Function* copyFunction(Function* func, Module& out) {
auto* ret = new Function();
ret->name = func->name;
@@ -254,4 +324,3 @@ inline void iterDefinedFunctions(Module& wasm, T visitor) {
} // namespace wasm
#endif // wasm_ir_module_h
-