summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas Lively <7121787+tlively@users.noreply.github.com>2019-03-18 20:38:07 -0700
committerGitHub <noreply@github.com>2019-03-18 20:38:07 -0700
commitdd3873375ca7375b79105742b30fa03f9f8a0c24 (patch)
treef07e51c24c124cc0981d1d87214aad200e67f1a8 /src
parenta2dd7c4feae3c4da3a1f8de90171795d12eb8879 (diff)
downloadbinaryen-dd3873375ca7375b79105742b30fa03f9f8a0c24.tar.gz
binaryen-dd3873375ca7375b79105742b30fa03f9f8a0c24.tar.bz2
binaryen-dd3873375ca7375b79105742b30fa03f9f8a0c24.zip
Validate that types match features (#1949)
Refactors features into a new wasm-features.h file and updates the validator to check that all types are allowed. Currently this is only relevant for the v128 SIMD type, but new types will be added in the future. The test for this change is in #1948.
Diffstat (limited to 'src')
-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) {