summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/wasm-features.h70
-rw-r--r--src/wasm-type.h3
-rw-r--r--src/wasm.h44
-rw-r--r--src/wasm/wasm-type.cpp8
-rw-r--r--src/wasm/wasm-validator.cpp5
5 files changed, 87 insertions, 43 deletions
diff --git a/src/wasm-features.h b/src/wasm-features.h
new file mode 100644
index 000000000..4dd806e28
--- /dev/null
+++ b/src/wasm-features.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2019 WebAssembly Community Group participants
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef wasm_features_h
+#define wasm_features_h
+
+#include <stdint.h>
+
+struct FeatureSet {
+ enum Feature : uint32_t {
+ MVP = 0,
+ Atomics = 1 << 0,
+ MutableGlobals = 1 << 1,
+ TruncSat = 1 << 2,
+ SIMD = 1 << 3,
+ BulkMemory = 1 << 4,
+ SignExt = 1 << 5,
+ All = Atomics | MutableGlobals | TruncSat | SIMD | BulkMemory | SignExt
+ };
+
+ FeatureSet() : features(MVP) {}
+ FeatureSet(uint32_t features) : features(features) {}
+
+ bool isMVP() const { return features == MVP; }
+ bool has(Feature f) { return (features & f) == f; }
+ bool hasAtomics() const { return features & Atomics; }
+ bool hasMutableGlobals() const { return features & MutableGlobals; }
+ bool hasTruncSat() const { return features & TruncSat; }
+ bool hasSIMD() const { return features & SIMD; }
+ bool hasBulkMemory() const { return features & BulkMemory; }
+ bool hasSignExt() const { return features & SignExt; }
+ bool hasAll() const { return features & All; }
+
+ void makeMVP() { features = MVP; }
+ void set(Feature f, bool v = true) { features = v ? (features | f) : (features & ~f); }
+ void setAtomics(bool v = true) { set(Atomics, v); }
+ void setMutableGlobals(bool v = true) { set(MutableGlobals, v); }
+ void setTruncSat(bool v = true) { set(TruncSat, v); }
+ void setSIMD(bool v = true) { set(SIMD, v); }
+ void setBulkMemory(bool v = true) { set(BulkMemory, v); }
+ void setSignExt(bool v = true) { set(SignExt, v); }
+ void setAll(bool v = true) { features = v ? All : MVP; }
+
+ bool operator<=(const FeatureSet& other) {
+ return !(features & ~other.features);
+ }
+
+ FeatureSet& operator|=(const FeatureSet& other) {
+ features |= other.features;
+ return *this;
+ }
+
+private:
+ uint32_t features;
+};
+
+#endif // wasm_features_h
diff --git a/src/wasm-type.h b/src/wasm-type.h
index 0b99fa53a..60253f6ab 100644
--- a/src/wasm-type.h
+++ b/src/wasm-type.h
@@ -17,6 +17,8 @@
#ifndef wasm_wasm_type_h
#define wasm_wasm_type_h
+#include "wasm-features.h"
+
namespace wasm {
enum Type {
@@ -33,6 +35,7 @@ enum Type {
const char* printType(Type type);
unsigned getTypeSize(Type type);
+FeatureSet getFeatures(Type type);
Type getType(unsigned size, bool float_);
Type getReachableType(Type a, Type b);
bool isConcreteType(Type type);
diff --git a/src/wasm.h b/src/wasm.h
index 258ed0f35..ab9d7c816 100644
--- a/src/wasm.h
+++ b/src/wasm.h
@@ -35,52 +35,10 @@
#include "mixed_arena.h"
#include "support/name.h"
#include "wasm-type.h"
+#include "wasm-features.h"
namespace wasm {
-struct FeatureSet {
- enum Feature : uint32_t {
- MVP = 0,
- Atomics = 1 << 0,
- MutableGlobals = 1 << 1,
- TruncSat = 1 << 2,
- SIMD = 1 << 3,
- BulkMemory = 1 << 4,
- SignExt = 1 << 5,
- All = Atomics | MutableGlobals | TruncSat | SIMD | BulkMemory | SignExt
- };
-
- FeatureSet() : features(MVP) {}
- FeatureSet(uint32_t features) : features(features) {}
-
- bool isMVP() const { return features == MVP; }
- bool has(Feature f) const { return (features & f) == f; }
- bool hasAtomics() const { return features & Atomics; }
- bool hasMutableGlobals() const { return features & MutableGlobals; }
- bool hasTruncSat() const { return features & TruncSat; }
- bool hasSIMD() const { return features & SIMD; }
- bool hasBulkMemory() const { return features & BulkMemory; }
- bool hasSignExt() const { return features & SignExt; }
- bool hasAll() const { return features & All; }
-
- void makeMVP() { features = MVP; }
- void set(Feature f, bool v = true) { features = v ? (features | f) : (features & ~f); }
- void setAtomics(bool v = true) { set(Atomics, v); }
- void setMutableGlobals(bool v = true) { set(MutableGlobals, v); }
- void setTruncSat(bool v = true) { set(TruncSat, v); }
- void setSIMD(bool v = true) { set(SIMD, v); }
- void setBulkMemory(bool v = true) { set(BulkMemory, v); }
- void setSignExt(bool v = true) { set(SignExt, v); }
- void setAll(bool v = true) { features = v ? All : MVP; }
-
- bool operator<=(const FeatureSet& other) {
- return !(features & ~other.features);
- }
-
-private:
- uint32_t features;
-};
-
// An index in a wasm module
typedef uint32_t Index;
diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp
index f9371ffab..fc393ed98 100644
--- a/src/wasm/wasm-type.cpp
+++ b/src/wasm/wasm-type.cpp
@@ -15,6 +15,7 @@
*/
#include "wasm-type.h"
+#include "wasm-features.h"
#include <cstdlib>
#include "compiler-support.h"
@@ -47,6 +48,13 @@ unsigned getTypeSize(Type type) {
WASM_UNREACHABLE();
}
+FeatureSet getFeatures(Type type) {
+ if (type == v128) {
+ return FeatureSet::SIMD;
+ }
+ return FeatureSet();
+}
+
Type getType(unsigned size, bool float_) {
if (size < 4) return Type::i32;
if (size == 4) return float_ ? Type::f32 : Type::i32;
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp
index 84a0efbff..91e7e7398 100644
--- a/src/wasm/wasm-validator.cpp
+++ b/src/wasm/wasm-validator.cpp
@@ -1081,12 +1081,17 @@ void FunctionValidator::visitHost(Host* curr) {
}
void FunctionValidator::visitFunction(Function* curr) {
+ FeatureSet typeFeatures = getFeatures(curr->result);
for (auto type : curr->params) {
+ typeFeatures |= getFeatures(type);
shouldBeTrue(isConcreteType(type), curr, "params must be concretely typed");
}
for (auto type : curr->vars) {
+ typeFeatures |= getFeatures(type);
shouldBeTrue(isConcreteType(type), curr, "vars must be concretely typed");
}
+ shouldBeTrue(typeFeatures <= info.features, curr,
+ "all used types should be allowed");
// if function has no result, it is ignored
// if body is unreachable, it might be e.g. a return
if (curr->body->type != unreachable) {