summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Lively <tlively@google.com>2023-01-18 13:31:26 -0600
committerGitHub <noreply@github.com>2023-01-18 11:31:26 -0800
commit82bd2c4e5717cbe19a1a6c34cfdd5116b13a68dc (patch)
treec801db56ab7288144c0fd288cb57dec0023a9569
parentab5b3e455770fec0e9ac78e566b48ec5a873a7ca (diff)
downloadbinaryen-82bd2c4e5717cbe19a1a6c34cfdd5116b13a68dc.tar.gz
binaryen-82bd2c4e5717cbe19a1a6c34cfdd5116b13a68dc.tar.bz2
binaryen-82bd2c4e5717cbe19a1a6c34cfdd5116b13a68dc.zip
Add a TypeNameGenerator that uses names from a Module (#5437)
If the module does not have a name for a particular type, the new utility falls back to use a different user-configurable type name generator, just like the existing IndexedTypeNameGenerator does. Also change how heap types are printed by this printing machinery (which is currently only used for debugging) so that their names are printed in addition to their contents. This makes the printer much more useful for debugging.
-rw-r--r--src/wasm-type-printing.h28
-rw-r--r--src/wasm/wasm-type.cpp6
-rw-r--r--test/example/type-builder-nominal.txt100
-rw-r--r--test/example/type-builder.txt68
-rw-r--r--test/example/typeinfo.txt4
-rw-r--r--test/gtest/type-builder.cpp46
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) {