diff options
Diffstat (limited to 'src/wasm')
-rw-r--r-- | src/wasm/wasm-binary.cpp | 3 | ||||
-rw-r--r-- | src/wasm/wasm-s-parser.cpp | 19 | ||||
-rw-r--r-- | src/wasm/wasm-type.cpp | 50 | ||||
-rw-r--r-- | src/wasm/wasm-validator.cpp | 4 |
4 files changed, 46 insertions, 30 deletions
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index f3160c461..bcf7c15fe 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -1416,7 +1416,8 @@ Type WasmBinaryBuilder::getType(int initial) { // FIXME: for now, force all inputs to be nullable return Type(getHeapType(), Nullable); case BinaryConsts::EncodedType::i31ref: - return Type::i31ref; + // FIXME: for now, force all inputs to be nullable + return Type(HeapType::BasicHeapType::i31, Nullable); case BinaryConsts::EncodedType::rtt_n: { auto depth = getU32LEB(); auto heapType = getHeapType(); diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index 20ab4f3d2..d76a3c49a 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -22,6 +22,7 @@ #include "ir/branch-utils.h" #include "shared-constants.h" +#include "support/string.h" #include "wasm-binary.h" #include "wasm-builder.h" @@ -867,7 +868,8 @@ Type SExpressionWasmBuilder::stringToType(const char* str, return Type::eqref; } if (strncmp(str, "i31ref", 6) == 0 && (prefix || str[6] == 0)) { - return Type::i31ref; + // FIXME: for now, force all inputs to be nullable + return Type(HeapType::BasicHeapType::i31, Nullable); } if (allowError) { return Type::none; @@ -2802,12 +2804,17 @@ HeapType SExpressionWasmBuilder::parseHeapType(Element& s) { } return types[it->second]; } else { - // index - size_t offset = atoi(s.str().c_str()); - if (offset >= types.size()) { - throw ParseException("unknown indexed function type", s.line, s.col); + // It may be a numerical index, or it may be a built-in type name like + // "i31". + auto* str = s.str().c_str(); + if (String::isNumber(str)) { + size_t offset = atoi(str); + if (offset >= types.size()) { + throw ParseException("unknown indexed function type", s.line, s.col); + } + return types[offset]; } - return types[offset]; + return stringToHeapType(str, /* prefix = */ false); } } // It's a list. diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp index 2eef7eb3d..31290c745 100644 --- a/src/wasm/wasm-type.cpp +++ b/src/wasm/wasm-type.cpp @@ -481,18 +481,29 @@ Type Type::reinterpret() const { FeatureSet Type::getFeatures() const { auto getSingleFeatures = [](Type t) -> FeatureSet { if (t.isRef()) { - if (t != Type::funcref && t.isFunction()) { - // Strictly speaking, typed function references require the typed - // function references feature, however, we use these types internally - // regardless of the presence of features (in particular, since during - // load of the wasm we don't know the features yet, so we apply the more - // refined types). - return FeatureSet::ReferenceTypes; - } + // A reference type implies we need that feature. Some also require more, + // such as GC or exceptions. auto heapType = t.getHeapType(); if (heapType.isStruct() || heapType.isArray()) { return FeatureSet::ReferenceTypes | FeatureSet::GC; } + if (heapType.isBasic()) { + switch (heapType.getBasic()) { + case HeapType::BasicHeapType::exn: + return FeatureSet::ReferenceTypes | FeatureSet::ExceptionHandling; + case HeapType::BasicHeapType::any: + case HeapType::BasicHeapType::eq: + case HeapType::BasicHeapType::i31: + return FeatureSet::ReferenceTypes | FeatureSet::GC; + default: {} + } + } + // Note: Technically typed function references also require the typed + // function references feature, however, we use these types internally + // regardless of the presence of features (in particular, since during + // load of the wasm we don't know the features yet, so we apply the more + // refined types), so we don't add that in any case here. + return FeatureSet::ReferenceTypes; } else if (t.isRtt()) { return FeatureSet::ReferenceTypes | FeatureSet::GC; } @@ -500,15 +511,6 @@ FeatureSet Type::getFeatures() const { switch (t.getBasic()) { case Type::v128: return FeatureSet::SIMD; - case Type::funcref: - case Type::externref: - return FeatureSet::ReferenceTypes; - case Type::exnref: - return FeatureSet::ReferenceTypes | FeatureSet::ExceptionHandling; - case Type::anyref: - case Type::eqref: - case Type::i31ref: - return FeatureSet::ReferenceTypes | FeatureSet::GC; default: return FeatureSet::MVP; } @@ -594,17 +596,21 @@ bool Type::isSubType(Type left, Type right) { return true; } // Various things are subtypes of eqref. - if ((left == Type::i31ref || left.getHeapType().isArray() || - left.getHeapType().isStruct()) && - right == Type::eqref) { + auto leftHeap = left.getHeapType(); + auto rightHeap = right.getHeapType(); + if ((leftHeap == HeapType::i31 || leftHeap.isArray() || + leftHeap.isStruct()) && + rightHeap == HeapType::eq && + (!left.isNullable() || right.isNullable())) { return true; } // All typed function signatures are subtypes of funcref. - if (left.getHeapType().isSignature() && right == Type::funcref) { + if (leftHeap.isSignature() && rightHeap == HeapType::func && + (!left.isNullable() || right.isNullable())) { return true; } // A non-nullable type is a supertype of a nullable one - if (left.getHeapType() == right.getHeapType() && !left.isNullable()) { + if (leftHeap == rightHeap && !left.isNullable()) { // The only difference is the nullability. assert(right.isNullable()); return true; diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index a45be1fd3..06f77b093 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -2191,9 +2191,11 @@ void FunctionValidator::visitI31Get(I31Get* curr) { shouldBeTrue(getModule()->features.hasGC(), curr, "i31.get_s/u requires gc to be enabled"); + // FIXME: use i31ref here, which is non-nullable, when we support non- + // nullability. shouldBeSubTypeOrFirstIsUnreachable( curr->i31->type, - Type::i31ref, + Type(HeapType::i31, Nullable), curr->i31, "i31.get_s/u's argument should be i31ref"); } |