diff options
author | Alon Zakai <azakai@google.com> | 2022-06-01 16:12:18 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-06-01 16:12:18 -0700 |
commit | fc00dcc64c337a8128fbf2b5fbdb40bb0aaa861b (patch) | |
tree | 0daaeba892f71afa945a1df27e328a2a3efc8071 | |
parent | 8470e7d780e6cf6171f47638e54bd5a019d8e055 (diff) | |
download | binaryen-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.cpp | 28 |
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) { |