diff options
-rw-r--r-- | src/wasm-type-printing.h | 28 | ||||
-rw-r--r-- | src/wasm/wasm-type.cpp | 6 | ||||
-rw-r--r-- | test/example/type-builder-nominal.txt | 100 | ||||
-rw-r--r-- | test/example/type-builder.txt | 68 | ||||
-rw-r--r-- | test/example/typeinfo.txt | 4 | ||||
-rw-r--r-- | test/gtest/type-builder.cpp | 46 |
6 files changed, 161 insertions, 91 deletions
diff --git a/src/wasm-type-printing.h b/src/wasm-type-printing.h index 685d488fd..3a8740350 100644 --- a/src/wasm-type-printing.h +++ b/src/wasm-type-printing.h @@ -24,6 +24,7 @@ #include "support/name.h" #include "support/utilities.h" #include "wasm-type.h" +#include "wasm.h" namespace wasm { @@ -93,6 +94,33 @@ struct IndexedTypeNameGenerator } }; +// Prints heap types stored in a module, falling back to the given +// FallbackGenerator if the module does not have a name for type type. +template<typename FallbackGenerator = DefaultTypeNameGenerator> +struct ModuleTypeNameGenerator + : TypeNameGeneratorBase<ModuleTypeNameGenerator<FallbackGenerator>> { + const Module& wasm; + DefaultTypeNameGenerator defaultGenerator; + FallbackGenerator& fallback; + + ModuleTypeNameGenerator(const Module& wasm, FallbackGenerator& fallback) + : wasm(wasm), fallback(fallback) {} + + // TODO: Use C++20 `requires` to clean this up. + template<class T = FallbackGenerator> + ModuleTypeNameGenerator( + const Module& wasm, + std::enable_if_t<std::is_same_v<T, DefaultTypeNameGenerator>>* = nullptr) + : ModuleTypeNameGenerator(wasm, defaultGenerator) {} + + TypeNames getNames(HeapType type) { + if (auto it = wasm.typeNames.find(type); it != wasm.typeNames.end()) { + return it->second; + } + return fallback.getNames(type); + } +}; + } // namespace wasm #endif // wasm_wasm_type_printing_h diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp index 64fd07759..e5493c8d1 100644 --- a/src/wasm/wasm-type.cpp +++ b/src/wasm/wasm-type.cpp @@ -1867,6 +1867,10 @@ std::ostream& TypePrinter::print(HeapType type) { } } + os << "(type "; + printHeapTypeName(type); + os << " "; + if (isTemp(type)) { os << "(; temp ;) "; } @@ -1885,7 +1889,7 @@ std::ostream& TypePrinter::print(HeapType type) { } else { WASM_UNREACHABLE("unexpected type"); } - return os; + return os << ")"; } std::ostream& TypePrinter::print(const Tuple& tuple) { diff --git a/test/example/type-builder-nominal.txt b/test/example/type-builder-nominal.txt index b542f212c..4da8857f2 100644 --- a/test/example/type-builder-nominal.txt +++ b/test/example/type-builder-nominal.txt @@ -1,24 +1,24 @@ ;; Test TypeBuilder Before setting heap types: -$sig => (; temp ;) (func) -$struct => (; temp ;) (func) -$array => (; temp ;) (func) +$sig => (type $0 (; temp ;) (func)) +$struct => (type $1 (; temp ;) (func)) +$array => (type $2 (; temp ;) (func)) (ref $sig) => (; temp ;) (ref $0) (ref $struct) => (; temp ;) (ref $1) (ref $array) => (; temp ;) (ref $2) (ref null $array) => (; temp ;) (ref null $2) After setting heap types: -$sig => (; temp ;) (func (param (; temp ;) (ref $1)) (result (; temp ;) (ref $2) i32)) -$struct => (; temp ;) (struct (field (; temp ;) (ref null $2))) -$array => (; temp ;) (array (mut anyref)) +$sig => (type $0 (; temp ;) (func (param (; temp ;) (ref $1)) (result (; temp ;) (ref $2) i32))) +$struct => (type $1 (; temp ;) (struct (field (; temp ;) (ref null $2)))) +$array => (type $2 (; temp ;) (array (mut anyref))) (ref $sig) => (; temp ;) (ref $0) (ref $struct) => (; temp ;) (ref $1) (ref $array) => (; temp ;) (ref $2) (ref null $array) => (; temp ;) (ref null $2) After building types: -$sig => (func (param (ref $1)) (result (ref $2) i32)) -$struct => (struct (field (ref null $2))) -$array => (array (mut anyref)) +$sig => (type $0 (func (param (ref $1)) (result (ref $2) i32))) +$struct => (type $1 (struct (field (ref null $2)))) +$array => (type $2 (array (mut anyref))) (ref $sig) => (ref $0) (ref $struct) => (ref $1) (ref $array) => (ref $2) @@ -27,49 +27,49 @@ $array => (array (mut anyref)) ;; Test basic ;; Test canonical signatures ;; Test recursive types -(func (result (ref null $0))) +(type $0 (func (result (ref null $0)))) -(func (result (ref null $1))) -(func (result (ref null $0))) +(type $0 (func (result (ref null $1)))) +(type $1 (func (result (ref null $0)))) -(func (result (ref null $1))) -(func (result (ref null $2))) -(func (result (ref null $3))) -(func (result (ref null $4))) -(func (result (ref null $0))) +(type $0 (func (result (ref null $1)))) +(type $1 (func (result (ref null $2)))) +(type $2 (func (result (ref null $3)))) +(type $3 (func (result (ref null $4)))) +(type $4 (func (result (ref null $0)))) -(func (result (ref null $0) (ref null $2))) -(func (result (ref null $1) (ref null $3))) -(func) -(func) -(func (result (ref null $0))) -(func (result (ref null $1))) +(type $0 (func (result (ref null $0) (ref null $2)))) +(type $1 (func (result (ref null $1) (ref null $3)))) +(type $2 (func)) +(type $3 (func)) +(type $4 (func (result (ref null $0)))) +(type $5 (func (result (ref null $1)))) -(func (result (ref null $0))) -(func (result (ref null $0))) +(type $0 (func (result (ref null $0)))) +(type $1 (func (result (ref null $0)))) ;; Test subtyping ;; Test TypeBuilder Before setting heap types: -$sig => (; temp ;) (func) -$struct => (; temp ;) (func) -$array => (; temp ;) (func) +$sig => (type $0 (; temp ;) (func)) +$struct => (type $1 (; temp ;) (func)) +$array => (type $2 (; temp ;) (func)) (ref $sig) => (; temp ;) (ref $0) (ref $struct) => (; temp ;) (ref $1) (ref $array) => (; temp ;) (ref $2) (ref null $array) => (; temp ;) (ref null $2) After setting heap types: -$sig => (; temp ;) (func (param (; temp ;) (ref $1)) (result (; temp ;) (ref $2) i32)) -$struct => (; temp ;) (struct (field (; temp ;) (ref null $2))) -$array => (; temp ;) (array (mut anyref)) +$sig => (type $0 (; temp ;) (func (param (; temp ;) (ref $1)) (result (; temp ;) (ref $2) i32))) +$struct => (type $1 (; temp ;) (struct (field (; temp ;) (ref null $2)))) +$array => (type $2 (; temp ;) (array (mut anyref))) (ref $sig) => (; temp ;) (ref $0) (ref $struct) => (; temp ;) (ref $1) (ref $array) => (; temp ;) (ref $2) (ref null $array) => (; temp ;) (ref null $2) After building types: -$sig => (func (param (ref $1)) (result (ref $2) i32)) -$struct => (struct (field (ref null $2))) -$array => (array (mut anyref)) +$sig => (type $0 (func (param (ref $1)) (result (ref $2) i32))) +$struct => (type $1 (struct (field (ref null $2)))) +$array => (type $2 (array (mut anyref))) (ref $sig) => (ref $0) (ref $struct) => (ref $1) (ref $array) => (ref $2) @@ -78,25 +78,25 @@ $array => (array (mut anyref)) ;; Test basic ;; Test canonical signatures ;; Test recursive types -(func (result (ref null $0))) +(type $0 (func (result (ref null $0)))) -(func (result (ref null $1))) -(func (result (ref null $0))) +(type $0 (func (result (ref null $1)))) +(type $1 (func (result (ref null $0)))) -(func (result (ref null $1))) -(func (result (ref null $2))) -(func (result (ref null $3))) -(func (result (ref null $4))) -(func (result (ref null $0))) +(type $0 (func (result (ref null $1)))) +(type $1 (func (result (ref null $2)))) +(type $2 (func (result (ref null $3)))) +(type $3 (func (result (ref null $4)))) +(type $4 (func (result (ref null $0)))) -(func (result (ref null $0) (ref null $2))) -(func (result (ref null $1) (ref null $3))) -(func) -(func) -(func (result (ref null $0))) -(func (result (ref null $1))) +(type $0 (func (result (ref null $0) (ref null $2)))) +(type $1 (func (result (ref null $1) (ref null $3)))) +(type $2 (func)) +(type $3 (func)) +(type $4 (func (result (ref null $0)))) +(type $5 (func (result (ref null $1)))) -(func (result (ref null $0))) -(func (result (ref null $0))) +(type $0 (func (result (ref null $0)))) +(type $1 (func (result (ref null $0)))) ;; Test subtyping diff --git a/test/example/type-builder.txt b/test/example/type-builder.txt index 6d584e7be..b0cff3cc0 100644 --- a/test/example/type-builder.txt +++ b/test/example/type-builder.txt @@ -1,54 +1,54 @@ ;; Test canonicalization ;; Test basic ;; Test recursive types -(func (result (ref null $0))) +(type $0 (func (result (ref null $0)))) -(func (result (ref null $1))) -(func (result (ref null $0))) +(type $0 (func (result (ref null $1)))) +(type $1 (func (result (ref null $0)))) -(func (result (ref null $1))) -(func (result (ref null $2))) -(func (result (ref null $3))) -(func (result (ref null $4))) -(func (result (ref null $0))) +(type $0 (func (result (ref null $1)))) +(type $1 (func (result (ref null $2)))) +(type $2 (func (result (ref null $3)))) +(type $3 (func (result (ref null $4)))) +(type $4 (func (result (ref null $0)))) -(func) -(func) -(func (result (ref null $0) (ref null $2))) -(func (result (ref null $0) (ref null $3))) -(func (result (ref null $2))) -(func (result (ref null $3))) +(type $0 (func)) +(type $0 (func)) +(type $2 (func (result (ref null $0) (ref null $2)))) +(type $3 (func (result (ref null $0) (ref null $3)))) +(type $4 (func (result (ref null $2)))) +(type $5 (func (result (ref null $3)))) -(func (result (ref null $0))) -(func (result (ref null $0))) +(type $0 (func (result (ref null $0)))) +(type $1 (func (result (ref null $0)))) any -(func (param anyref) (result (ref null $1))) +(type $1 (func (param anyref) (result (ref null $1)))) ;; Test canonicalization ;; Test basic ;; Test recursive types -(func (result (ref null $0))) +(type $0 (func (result (ref null $0)))) -(func (result (ref null $1))) -(func (result (ref null $0))) +(type $0 (func (result (ref null $1)))) +(type $1 (func (result (ref null $0)))) -(func (result (ref null $1))) -(func (result (ref null $2))) -(func (result (ref null $3))) -(func (result (ref null $4))) -(func (result (ref null $0))) +(type $0 (func (result (ref null $1)))) +(type $1 (func (result (ref null $2)))) +(type $2 (func (result (ref null $3)))) +(type $3 (func (result (ref null $4)))) +(type $4 (func (result (ref null $0)))) -(func) -(func) -(func (result (ref null $0) (ref null $2))) -(func (result (ref null $0) (ref null $3))) -(func (result (ref null $2))) -(func (result (ref null $3))) +(type $0 (func)) +(type $0 (func)) +(type $2 (func (result (ref null $0) (ref null $2)))) +(type $3 (func (result (ref null $0) (ref null $3)))) +(type $4 (func (result (ref null $2)))) +(type $5 (func (result (ref null $3)))) -(func (result (ref null $0))) -(func (result (ref null $0))) +(type $0 (func (result (ref null $0)))) +(type $1 (func (result (ref null $0)))) any -(func (param anyref) (result (ref null $1))) +(type $1 (func (param anyref) (result (ref null $1)))) diff --git a/test/example/typeinfo.txt b/test/example/typeinfo.txt index 7015e6cfc..a20fc2bfa 100644 --- a/test/example/typeinfo.txt +++ b/test/example/typeinfo.txt @@ -12,8 +12,8 @@ i31 i31ref (ref i31) (func) -(struct) -(array i32) +(type $struct.0 (struct)) +(type $array.0 (array i32)) ;; Signature (func) diff --git a/test/gtest/type-builder.cpp b/test/gtest/type-builder.cpp index d26b8bb97..af6613bd2 100644 --- a/test/gtest/type-builder.cpp +++ b/test/gtest/type-builder.cpp @@ -103,19 +103,57 @@ TEST_F(TypeTest, IndexedTypePrinter) { std::stringstream stream; stream << print(built[0]); - EXPECT_EQ(stream.str(), "(struct (field (ref null $array1)))"); + EXPECT_EQ(stream.str(), + "(type $struct0 (struct (field (ref null $array1))))"); stream.str(""); stream << print(built[1]); - EXPECT_EQ(stream.str(), "(struct (field (ref null $struct0)))"); + EXPECT_EQ(stream.str(), + "(type $struct1 (struct (field (ref null $struct0))))"); stream.str(""); stream << print(built[2]); - EXPECT_EQ(stream.str(), "(array (ref null $struct1))"); + EXPECT_EQ(stream.str(), "(type $array0 (array (ref null $struct1)))"); stream.str(""); stream << print(built[3]); - EXPECT_EQ(stream.str(), "(array (ref null $array0))"); + EXPECT_EQ(stream.str(), "(type $array1 (array (ref null $array0)))"); +} + +TEST_F(TypeTest, ModuleTypePrinter) { + TypeBuilder builder(2); + builder.createRecGroup(0, 2); + builder[0] = Struct({Field(Type::i32, Immutable)}); + builder[1] = Struct({Field(Type::i32, Immutable)}); + + auto result = builder.build(); + ASSERT_TRUE(result); + auto built = *result; + + Module module; + module.typeNames[built[0]] = {"A", {}}; + + ModuleTypeNameGenerator printDefault(module); + + std::stringstream stream; + stream << printDefault(built[0]); + EXPECT_EQ(stream.str(), "(type $A (struct (field i32)))"); + + stream.str(""); + stream << printDefault(built[1]); + EXPECT_EQ(stream.str(), "(type $struct.0 (struct (field i32)))"); + + using IndexedFallback = IndexedTypeNameGenerator<DefaultTypeNameGenerator>; + IndexedTypeNameGenerator fallback(built); + ModuleTypeNameGenerator<IndexedFallback> printIndexed(module, fallback); + + stream.str(""); + stream << printIndexed(built[0]); + EXPECT_EQ(stream.str(), "(type $A (struct (field i32)))"); + + stream.str(""); + stream << printIndexed(built[1]); + EXPECT_EQ(stream.str(), "(type $1 (struct (field i32)))"); } TEST_F(IsorecursiveTest, Basics) { |