summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2022-06-01 16:12:18 -0700
committerGitHub <noreply@github.com>2022-06-01 16:12:18 -0700
commitfc00dcc64c337a8128fbf2b5fbdb40bb0aaa861b (patch)
tree0daaeba892f71afa945a1df27e328a2a3efc8071
parent8470e7d780e6cf6171f47638e54bd5a019d8e055 (diff)
downloadbinaryen-fc00dcc64c337a8128fbf2b5fbdb40bb0aaa861b.tar.gz
binaryen-fc00dcc64c337a8128fbf2b5fbdb40bb0aaa861b.tar.bz2
binaryen-fc00dcc64c337a8128fbf2b5fbdb40bb0aaa861b.zip
Fuzzer: Add support for creating structs and arrays in makeConst (#4707)
#4659 adds a testcase with an import of (ref $struct). This could cause an error in the fuzzer, since it wants to remove imports (because the various fuzzers cannot pass in custom imports - they want to just run the wasm). When it tries to remove that import it tries to create a constant for a struct reference, and fails. To fix that, add enough support to create structs and arrays at least in the simple case where all their fields are defaultable.
-rw-r--r--src/tools/fuzzing/fuzzing.cpp28
1 files changed, 20 insertions, 8 deletions
diff --git a/src/tools/fuzzing/fuzzing.cpp b/src/tools/fuzzing/fuzzing.cpp
index fe091c91f..e5afbf559 100644
--- a/src/tools/fuzzing/fuzzing.cpp
+++ b/src/tools/fuzzing/fuzzing.cpp
@@ -2017,23 +2017,35 @@ Expression* TranslateToFuzzReader::makeConstCompoundRef(Type type) {
assert(wasm.features.hasReferenceTypes());
if (heapType.isSignature()) {
return makeRefFuncConst(type);
- } else {
- // TODO: Handle nontrivial array and struct types.
}
+
// We weren't able to directly materialize a non-null constant. Try again to
// create a null.
if (type.isNullable()) {
return builder.makeRefNull(type);
}
+
// We have to produce a non-null value. Possibly create a null and cast it
// to non-null even though that will trap at runtime. We must have a
- // function context because the cast is not allowed in globals.
- if (!funcContext) {
- std::cerr << type << "\n";
+ // function context for this because the cast is not allowed in globals.
+ if (funcContext) {
+ return builder.makeRefAs(RefAsNonNull,
+ builder.makeRefNull(Type(heapType, Nullable)));
+ }
+
+ // Otherwise, we are not in a function context. This can happen if we need
+ // to make a constant for the initializer of a global, for example. We've
+ // already handled simple cases of this above, for basic heap types, so what
+ // we have left here are user-defined heap types like structs.
+ // TODO: support non-defaultable fields. for now, just use default values.
+ if (type.isStruct()) {
+ return builder.makeStructNew(type.getHeapType(),
+ std::vector<Expression*>{});
+ } else if (type.isArray()) {
+ return builder.makeArrayNew(type.getHeapType(), makeConst(Type::i32));
+ } else {
+ WASM_UNREACHABLE("bad user-defined ref type");
}
- assert(funcContext);
- return builder.makeRefAs(RefAsNonNull,
- builder.makeRefNull(Type(heapType, Nullable)));
}
Expression* TranslateToFuzzReader::buildUnary(const UnaryArgs& args) {