summaryrefslogtreecommitdiff
path: root/src/tools/fuzzing/fuzzing.cpp
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2022-05-06 11:43:41 -0700
committerGitHub <noreply@github.com>2022-05-06 11:43:41 -0700
commit5d43429f3c12cf7c2c43eb11d4e9b6b1816ed0ee (patch)
treee5e7e80e8a8363aa4d006176ee697191fa66b1ca /src/tools/fuzzing/fuzzing.cpp
parentc6531f935d9e925e6ecb30c53fadcf2d6fc380cf (diff)
downloadbinaryen-5d43429f3c12cf7c2c43eb11d4e9b6b1816ed0ee.tar.gz
binaryen-5d43429f3c12cf7c2c43eb11d4e9b6b1816ed0ee.tar.bz2
binaryen-5d43429f3c12cf7c2c43eb11d4e9b6b1816ed0ee.zip
[Fuzzer] Fix another reference types vs gc types issue (#4647)
Diff without whitespace is smaller. We can't emit HeapType::data without GC. Fixing that by switching to func, another problem was uncovered: makeRefFuncConst had a TODO to handle the case where we need a function to refer to but have created none yet. In fact that TODO was done at the end of the function. Fix up the logic in between to actually get there.
Diffstat (limited to 'src/tools/fuzzing/fuzzing.cpp')
-rw-r--r--src/tools/fuzzing/fuzzing.cpp73
1 files changed, 37 insertions, 36 deletions
diff --git a/src/tools/fuzzing/fuzzing.cpp b/src/tools/fuzzing/fuzzing.cpp
index 36dc5dcb1..a5f00d8ef 100644
--- a/src/tools/fuzzing/fuzzing.cpp
+++ b/src/tools/fuzzing/fuzzing.cpp
@@ -1856,50 +1856,50 @@ Literal TranslateToFuzzReader::makeLiteral(Type type) {
}
Expression* TranslateToFuzzReader::makeRefFuncConst(Type type) {
- // ref.as_non_null is allowed in globals and we don't yet support func.ref in
- // globals because we create globals before we create functions. As a result,
- // we can only create non-nullable function references if we are in a function
- // context for now.
- // TODO: Generate trivial functions to support ref.func in globals.
- assert(type.isNullable() || funcContext);
- if (!funcContext || (type.isNullable() && oneIn(8))) {
- return builder.makeRefNull(type);
- }
-
auto heapType = type.getHeapType();
if (heapType == HeapType::func) {
// First set to target to the last created function, and try to select
// among other existing function if possible.
- Function* target = funcContext->func;
- if (!wasm.functions.empty() && !oneIn(wasm.functions.size())) {
+ Function* target = funcContext ? funcContext->func : nullptr;
+ // If there is no last function, and we have others, pick between them. Also
+ // pick between them with some random probability even if there is a last
+ // function.
+ if (!target || (!wasm.functions.empty() && !oneIn(wasm.functions.size()))) {
target = pick(wasm.functions).get();
}
- return builder.makeRefFunc(target->name, target->type);
- } else {
- // TODO: randomize the order
- for (auto& func : wasm.functions) {
- if (Type::isSubType(type, Type(func->type, NonNullable))) {
- return builder.makeRefFunc(func->name, func->type);
- }
+ if (target) {
+ return builder.makeRefFunc(target->name, target->type);
}
- // We don't have a matching function, so create a null with high probability
- // if the type is nullable or otherwise create and cast a null with low
- // probability.
- if ((type.isNullable() && !oneIn(8)) || oneIn(8)) {
- Expression* ret = builder.makeRefNull(Type(heapType, Nullable));
- if (!type.isNullable()) {
- ret = builder.makeRefAs(RefAsNonNull, ret);
- }
- return ret;
+ }
+ if (heapType == HeapType::func) {
+ // From here on we need a specific signature type, as we want to create a
+ // RefFunc or even a Function out of it. Pick an arbitrary one if we only
+ // had generic 'func' here.
+ heapType = Signature(Type::none, Type::none);
+ }
+ // TODO: randomize the order
+ for (auto& func : wasm.functions) {
+ if (Type::isSubType(type, Type(func->type, NonNullable))) {
+ return builder.makeRefFunc(func->name, func->type);
}
- // As a final option, create a new function with the correct signature.
- auto* func = wasm.addFunction(
- builder.makeFunction(Names::getValidFunctionName(wasm, "ref_func_target"),
- heapType,
- {},
- builder.makeUnreachable()));
- return builder.makeRefFunc(func->name, heapType);
}
+ // We don't have a matching function, so create a null with high probability
+ // if the type is nullable or otherwise create and cast a null with low
+ // probability.
+ if ((type.isNullable() && !oneIn(8)) || oneIn(8)) {
+ Expression* ret = builder.makeRefNull(Type(heapType, Nullable));
+ if (!type.isNullable()) {
+ ret = builder.makeRefAs(RefAsNonNull, ret);
+ }
+ return ret;
+ }
+ // As a final option, create a new function with the correct signature.
+ auto* func = wasm.addFunction(
+ builder.makeFunction(Names::getValidFunctionName(wasm, "ref_func_target"),
+ heapType,
+ {},
+ builder.makeUnreachable()));
+ return builder.makeRefFunc(func->name, heapType);
}
Expression* TranslateToFuzzReader::makeConst(Type type) {
@@ -1926,7 +1926,7 @@ Expression* TranslateToFuzzReader::makeConst(Type type) {
HeapType::i31,
HeapType::data));
} else {
- subtype = HeapType::data;
+ subtype = HeapType::func;
}
return makeConst(Type(subtype, nullability));
}
@@ -1950,6 +1950,7 @@ Expression* TranslateToFuzzReader::makeConst(Type type) {
return builder.makeRefNull(type);
}
case HeapType::data:
+ assert(wasm.features.hasReferenceTypes() && wasm.features.hasGC());
// TODO: Construct nontrivial types. For now just create a hard coded
// struct or array.
if (oneIn(2)) {