From fc00dcc64c337a8128fbf2b5fbdb40bb0aaa861b Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Wed, 1 Jun 2022 16:12:18 -0700 Subject: 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. --- src/tools/fuzzing/fuzzing.cpp | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) (limited to 'src/tools/fuzzing/fuzzing.cpp') 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{}); + } 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) { -- cgit v1.2.3