diff options
-rw-r--r-- | src/tools/wasm-fuzz-types.cpp | 4 | ||||
-rw-r--r-- | src/wasm-type-printing.h | 16 | ||||
-rw-r--r-- | test/example/type-builder-nominal.cpp | 67 | ||||
-rw-r--r-- | test/gtest/type-builder.cpp | 47 |
4 files changed, 96 insertions, 38 deletions
diff --git a/src/tools/wasm-fuzz-types.cpp b/src/tools/wasm-fuzz-types.cpp index 4fba27753..d2540636f 100644 --- a/src/tools/wasm-fuzz-types.cpp +++ b/src/tools/wasm-fuzz-types.cpp @@ -95,8 +95,8 @@ void Fuzzer::printTypes() { TypeNames getNames(HeapType type) { Fatal() << "trying to print unknown heap type"; } - }; - IndexedTypeNameGenerator<FatalTypeNameGenerator> print(types); + } fatalGenerator; + IndexedTypeNameGenerator<FatalTypeNameGenerator> print(types, fatalGenerator); std::unordered_map<HeapType, size_t> seen; std::optional<RecGroup> currRecGroup; auto inRecGroup = [&]() { return currRecGroup && currRecGroup->size() > 1; }; diff --git a/src/wasm-type-printing.h b/src/wasm-type-printing.h index fcf05db17..685d488fd 100644 --- a/src/wasm-type-printing.h +++ b/src/wasm-type-printing.h @@ -67,13 +67,23 @@ struct DefaultTypeNameGenerator template<typename FallbackGenerator = DefaultTypeNameGenerator> struct IndexedTypeNameGenerator : TypeNameGeneratorBase<IndexedTypeNameGenerator<FallbackGenerator>> { - FallbackGenerator fallback; + DefaultTypeNameGenerator defaultGenerator; + FallbackGenerator& fallback; std::unordered_map<HeapType, TypeNames> names; - template<typename T> IndexedTypeNameGenerator(T& types) { + + template<typename T> + IndexedTypeNameGenerator(T& types, + FallbackGenerator& fallback, + const std::string& prefix = "") + : fallback(fallback) { for (size_t i = 0; i < types.size(); ++i) { - names.insert({types[i], {std::to_string(i), {}}}); + names.insert({types[i], {prefix + std::to_string(i), {}}}); } } + template<typename T> + IndexedTypeNameGenerator(T& types, const std::string& prefix = "") + : IndexedTypeNameGenerator(types, defaultGenerator, prefix) {} + TypeNames getNames(HeapType type) { if (auto it = names.find(type); it != names.end()) { return it->second; diff --git a/test/example/type-builder-nominal.cpp b/test/example/type-builder-nominal.cpp index f83648b74..5bfefadc3 100644 --- a/test/example/type-builder-nominal.cpp +++ b/test/example/type-builder-nominal.cpp @@ -30,31 +30,35 @@ void test_builder() { Struct struct_({Field(refNullArray, Immutable), Field(rttArray, Mutable)}); Array array(Field(refNullExt, Mutable)); - IndexedTypeNameGenerator print(builder); - - std::cout << "Before setting heap types:\n"; - std::cout << "$sig => " << print(builder[0]) << "\n"; - std::cout << "$struct => " << print(builder[1]) << "\n"; - std::cout << "$array => " << print(builder[2]) << "\n"; - std::cout << "(ref $sig) => " << print(refSig) << "\n"; - std::cout << "(ref $struct) => " << print(refStruct) << "\n"; - std::cout << "(ref $array) => " << print(refArray) << "\n"; - std::cout << "(ref null $array) => " << print(refNullArray) << "\n"; - std::cout << "(rtt 0 $array) => " << print(rttArray) << "\n\n"; + { + IndexedTypeNameGenerator print(builder); + std::cout << "Before setting heap types:\n"; + std::cout << "$sig => " << print(builder[0]) << "\n"; + std::cout << "$struct => " << print(builder[1]) << "\n"; + std::cout << "$array => " << print(builder[2]) << "\n"; + std::cout << "(ref $sig) => " << print(refSig) << "\n"; + std::cout << "(ref $struct) => " << print(refStruct) << "\n"; + std::cout << "(ref $array) => " << print(refArray) << "\n"; + std::cout << "(ref null $array) => " << print(refNullArray) << "\n"; + std::cout << "(rtt 0 $array) => " << print(rttArray) << "\n\n"; + } builder[0] = sig; builder[1] = struct_; builder[2] = array; - std::cout << "After setting heap types:\n"; - std::cout << "$sig => " << print(builder[0]) << "\n"; - std::cout << "$struct => " << print(builder[1]) << "\n"; - std::cout << "$array => " << print(builder[2]) << "\n"; - std::cout << "(ref $sig) => " << print(refSig) << "\n"; - std::cout << "(ref $struct) => " << print(refStruct) << "\n"; - std::cout << "(ref $array) => " << print(refArray) << "\n"; - std::cout << "(ref null $array) => " << print(refNullArray) << "\n"; - std::cout << "(rtt 0 $array) => " << print(rttArray) << "\n\n"; + { + IndexedTypeNameGenerator print(builder); + std::cout << "After setting heap types:\n"; + std::cout << "$sig => " << print(builder[0]) << "\n"; + std::cout << "$struct => " << print(builder[1]) << "\n"; + std::cout << "$array => " << print(builder[2]) << "\n"; + std::cout << "(ref $sig) => " << print(refSig) << "\n"; + std::cout << "(ref $struct) => " << print(refStruct) << "\n"; + std::cout << "(ref $array) => " << print(refArray) << "\n"; + std::cout << "(ref null $array) => " << print(refNullArray) << "\n"; + std::cout << "(rtt 0 $array) => " << print(rttArray) << "\n\n"; + } std::vector<HeapType> built = *builder.build(); @@ -64,17 +68,18 @@ void test_builder() { Type newRefNullArray = Type(built[2], Nullable); Type newRttArray = Type(Rtt(0, built[2])); - print = IndexedTypeNameGenerator(built); - - std::cout << "After building types:\n"; - std::cout << "$sig => " << print(built[0]) << "\n"; - std::cout << "$struct => " << print(built[1]) << "\n"; - std::cout << "$array => " << print(built[2]) << "\n"; - std::cout << "(ref $sig) => " << print(newRefSig) << "\n"; - std::cout << "(ref $struct) => " << print(newRefStruct) << "\n"; - std::cout << "(ref $array) => " << print(newRefArray) << "\n"; - std::cout << "(ref null $array) => " << print(newRefNullArray) << "\n"; - std::cout << "(rtt 0 $array) => " << print(newRttArray) << "\n\n"; + { + IndexedTypeNameGenerator print(built); + std::cout << "After building types:\n"; + std::cout << "$sig => " << print(built[0]) << "\n"; + std::cout << "$struct => " << print(built[1]) << "\n"; + std::cout << "$array => " << print(built[2]) << "\n"; + std::cout << "(ref $sig) => " << print(newRefSig) << "\n"; + std::cout << "(ref $struct) => " << print(newRefStruct) << "\n"; + std::cout << "(ref $array) => " << print(newRefArray) << "\n"; + std::cout << "(ref null $array) => " << print(newRefNullArray) << "\n"; + std::cout << "(rtt 0 $array) => " << print(newRttArray) << "\n\n"; + } } // Check that the builder works when there are duplicate definitions diff --git a/test/gtest/type-builder.cpp b/test/gtest/type-builder.cpp index 4ae9e0e63..99bec48bf 100644 --- a/test/gtest/type-builder.cpp +++ b/test/gtest/type-builder.cpp @@ -1,5 +1,6 @@ -#include <gtest/gtest.h> -#include <wasm-type.h> +#include "wasm-type-printing.h" +#include "wasm-type.h" +#include "gtest/gtest.h" using namespace wasm; @@ -101,6 +102,48 @@ TEST_F(TypeTest, TypeIterator) { EXPECT_EQ(reverse, tuple.rend()); } +TEST_F(TypeTest, IndexedTypePrinter) { + TypeBuilder builder(4); + + Type refStructA = builder.getTempRefType(builder[0], Nullable); + Type refStructB = builder.getTempRefType(builder[1], Nullable); + Type refArrayA = builder.getTempRefType(builder[2], Nullable); + Type refArrayB = builder.getTempRefType(builder[3], Nullable); + builder[0] = Struct({Field(refArrayB, Immutable)}); + builder[1] = Struct({Field(refStructA, Immutable)}); + builder[2] = Array(Field(refStructB, Immutable)); + builder[3] = Array(Field(refArrayA, Immutable)); + + auto result = builder.build(); + ASSERT_TRUE(result); + auto built = *result; + + std::vector<HeapType> structs{built[0], built[1]}; + std::vector<HeapType> arrays{built[2], built[3]}; + + // Check that IndexedTypePrinters configured with fallbacks work correctly. + using ArrayPrinter = IndexedTypeNameGenerator<DefaultTypeNameGenerator>; + ArrayPrinter printArrays(arrays, "array"); + using StructPrinter = IndexedTypeNameGenerator<ArrayPrinter>; + StructPrinter print(structs, printArrays, "struct"); + + std::stringstream stream; + stream << print(built[0]); + EXPECT_EQ(stream.str(), "(struct (field (ref null $array1)))"); + + stream.str(""); + stream << print(built[1]); + EXPECT_EQ(stream.str(), "(struct (field (ref null $struct0)))"); + + stream.str(""); + stream << print(built[2]); + EXPECT_EQ(stream.str(), "(array (ref null $struct1))"); + + stream.str(""); + stream << print(built[3]); + EXPECT_EQ(stream.str(), "(array (ref null $array0))"); +} + TEST_F(EquirecursiveTest, Basics) { // (type $sig (func (param (ref $struct)) (result (ref $array) i32))) // (type $struct (struct (field (ref null $array) (mut rtt 0 $array)))) |