diff options
-rw-r--r-- | src/wasm-features.h | 70 | ||||
-rw-r--r-- | src/wasm-type.h | 3 | ||||
-rw-r--r-- | src/wasm.h | 44 | ||||
-rw-r--r-- | src/wasm/wasm-type.cpp | 8 | ||||
-rw-r--r-- | src/wasm/wasm-validator.cpp | 5 |
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) { |