[fuzzer][wasm] Add support for reftypes in test generator
We add support for struct and arraytypes in wasm-fuzzer-common. Also, we add addStruct and addArray while generating tests. Other OptRef types like eqref/anyref have been supported. Adding struct and arraytypes in wasm-compile has been placed at the beginning in order to generate them in addSignature. Bug: v8:11954 Change-Id: Ibe468dd4df70ad40367196c88353b28b7654f086 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3074463 Reviewed-by: Thibaud Michaud <thibaudm@chromium.org> Reviewed-by: Manos Koukoutos <manoskouk@chromium.org> Commit-Queue: Rakhim Khismet <khismet@google.com> Cr-Commit-Position: refs/heads/master@{#76137}
This commit is contained in:
parent
9b19cc5ca2
commit
7810ce0468
@ -1703,6 +1703,28 @@ class WasmCompileFuzzer : public WasmExecutionFuzzer {
|
||||
|
||||
DataRange range(data);
|
||||
std::vector<uint32_t> function_signatures;
|
||||
|
||||
// Add struct and array types first so that we get a chance to generate
|
||||
// these types in function signatures
|
||||
if (liftoff_as_reference) {
|
||||
uint32_t count = 4;
|
||||
StructType::Builder struct_builder(zone, count);
|
||||
struct_builder.AddField(kWasmI32, false);
|
||||
struct_builder.AddField(kWasmI64, false);
|
||||
struct_builder.AddField(kWasmF32, false);
|
||||
struct_builder.AddField(kWasmF64, false);
|
||||
StructType* struct_fuz = struct_builder.Build();
|
||||
builder.AddStructType(struct_fuz);
|
||||
ArrayType* array_fuzI32 = zone->New<ArrayType>(kWasmI32, true);
|
||||
ArrayType* array_fuzI64 = zone->New<ArrayType>(kWasmI64, true);
|
||||
ArrayType* array_fuzF32 = zone->New<ArrayType>(kWasmF32, true);
|
||||
ArrayType* array_fuzF64 = zone->New<ArrayType>(kWasmF64, true);
|
||||
builder.AddArrayType(array_fuzI32);
|
||||
builder.AddArrayType(array_fuzI64);
|
||||
builder.AddArrayType(array_fuzF32);
|
||||
builder.AddArrayType(array_fuzF64);
|
||||
}
|
||||
|
||||
function_signatures.push_back(builder.AddSignature(sigs.i_iii()));
|
||||
|
||||
static_assert(kMaxFunctions >= 1, "need min. 1 function");
|
||||
@ -1728,25 +1750,6 @@ class WasmCompileFuzzer : public WasmExecutionFuzzer {
|
||||
builder.AddException(sig);
|
||||
}
|
||||
|
||||
if (liftoff_as_reference) {
|
||||
uint32_t count = 4;
|
||||
StructType::Builder struct_builder(zone, count);
|
||||
struct_builder.AddField(kWasmI32, false);
|
||||
struct_builder.AddField(kWasmI64, false);
|
||||
struct_builder.AddField(kWasmF32, false);
|
||||
struct_builder.AddField(kWasmF64, false);
|
||||
StructType* struct_fuz = struct_builder.Build();
|
||||
builder.AddStructType(struct_fuz);
|
||||
ArrayType* array_fuzI32 = zone->New<ArrayType>(kWasmI32, true);
|
||||
ArrayType* array_fuzI64 = zone->New<ArrayType>(kWasmI64, true);
|
||||
ArrayType* array_fuzF32 = zone->New<ArrayType>(kWasmF32, true);
|
||||
ArrayType* array_fuzF64 = zone->New<ArrayType>(kWasmF64, true);
|
||||
builder.AddArrayType(array_fuzI32);
|
||||
builder.AddArrayType(array_fuzI64);
|
||||
builder.AddArrayType(array_fuzF32);
|
||||
builder.AddArrayType(array_fuzF64);
|
||||
}
|
||||
|
||||
for (int i = 0; i < num_globals; ++i) {
|
||||
ValueType type =
|
||||
GetValueType(builder.NumTypes(), &range, liftoff_as_reference);
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "src/objects/objects-inl.h"
|
||||
#include "src/utils/ostreams.h"
|
||||
#include "src/wasm/baseline/liftoff-compiler.h"
|
||||
#include "src/wasm/function-body-decoder-impl.h"
|
||||
#include "src/wasm/module-instantiate.h"
|
||||
#include "src/wasm/wasm-engine.h"
|
||||
#include "src/wasm/wasm-feature-flags.h"
|
||||
@ -198,7 +199,7 @@ PrintSig PrintParameters(const FunctionSig* sig) {
|
||||
PrintSig PrintReturns(const FunctionSig* sig) {
|
||||
return {sig->return_count(), [=](size_t i) { return sig->GetReturn(i); }};
|
||||
}
|
||||
const char* ValueTypeToConstantName(ValueType type) {
|
||||
std::string ValueTypeToConstantName(ValueType type) {
|
||||
switch (type.kind()) {
|
||||
case kI32:
|
||||
return "kWasmI32";
|
||||
@ -216,17 +217,44 @@ const char* ValueTypeToConstantName(ValueType type) {
|
||||
return "kWasmExternRef";
|
||||
case HeapType::kFunc:
|
||||
return "kWasmFuncRef";
|
||||
case HeapType::kEq:
|
||||
return "kWasmEqRef";
|
||||
case HeapType::kAny:
|
||||
return "kWasmAnyRef";
|
||||
case HeapType::kData:
|
||||
return "wasmOptRefType(kWasmDataRef)";
|
||||
case HeapType::kI31:
|
||||
return "wasmOptRefType(kWasmI31Ref)";
|
||||
case HeapType::kBottom:
|
||||
default:
|
||||
// TODO(7748): Implement these if fuzzing for them is enabled.
|
||||
UNREACHABLE();
|
||||
return "wasmOptRefType(" + std::to_string(type.ref_index()) + ")";
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
std::string HeapTypeToConstantName(HeapType heap_type) {
|
||||
switch (heap_type.representation()) {
|
||||
case HeapType::kFunc:
|
||||
return "kWasmFuncRef";
|
||||
case HeapType::kExtern:
|
||||
return "kWasmExternRef";
|
||||
case HeapType::kEq:
|
||||
return "kWasmEqRef";
|
||||
case HeapType::kI31:
|
||||
return "kWasmI31Ref";
|
||||
case HeapType::kData:
|
||||
return "kWasmDataRef";
|
||||
case HeapType::kAny:
|
||||
return "kWasmAnyRef";
|
||||
case HeapType::kBottom:
|
||||
UNREACHABLE();
|
||||
default:
|
||||
return std::to_string(heap_type.ref_index());
|
||||
}
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const PrintSig& print) {
|
||||
os << "[";
|
||||
for (size_t i = 0; i < print.num; ++i) {
|
||||
@ -292,10 +320,28 @@ void AppendInitExpr(std::ostream& os, ModuleWireBytes wire_bytes,
|
||||
os << "F64Const(" << bit_cast<double>(result);
|
||||
break;
|
||||
}
|
||||
case kSimdPrefix: {
|
||||
DCHECK_LE(2 + kSimd128Size, expr.length());
|
||||
DCHECK_EQ(static_cast<WasmOpcode>(pc[1]), kExprS128Const & 0xff);
|
||||
os << "S128Const([";
|
||||
for (int i = 0; i < kSimd128Size; i++) {
|
||||
os << int(decoder.read_u8<Decoder::kNoValidation>(pc + 2 + i));
|
||||
if (i + 1 < kSimd128Size) os << ", ";
|
||||
}
|
||||
os << "]";
|
||||
break;
|
||||
}
|
||||
case kExprRefFunc:
|
||||
os << "RefFunc("
|
||||
<< decoder.read_u32v<Decoder::kNoValidation>(pc + 1, &length);
|
||||
break;
|
||||
case kExprRefNull: {
|
||||
HeapType heap_type =
|
||||
value_type_reader::read_heap_type<Decoder::kNoValidation>(
|
||||
&decoder, pc + 1, &length, nullptr, WasmFeatures::All());
|
||||
os << "RefNull(" << HeapTypeToConstantName(heap_type);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
@ -334,7 +380,7 @@ void GenerateTestCase(Isolate* isolate, ModuleWireBytes wire_bytes,
|
||||
"can be\n"
|
||||
"// found in the LICENSE file.\n"
|
||||
"\n"
|
||||
"// Flags: --wasm-staging\n"
|
||||
"// Flags: --wasm-staging --experimental-wasm-gc\n"
|
||||
"\n"
|
||||
"load('test/mjsunit/wasm/wasm-module-builder.js');\n"
|
||||
"\n"
|
||||
@ -361,16 +407,38 @@ void GenerateTestCase(Isolate* isolate, ModuleWireBytes wire_bytes,
|
||||
os << ");\n";
|
||||
}
|
||||
|
||||
// TODO(7748): Support array/struct types.
|
||||
#if DEBUG
|
||||
for (uint8_t kind : module->type_kinds) {
|
||||
DCHECK_EQ(kWasmFunctionTypeCode, kind);
|
||||
DCHECK(kWasmArrayTypeCode == kind || kWasmStructTypeCode == kind ||
|
||||
kWasmFunctionTypeCode == kind);
|
||||
}
|
||||
#endif
|
||||
for (TypeDefinition type : module->types) {
|
||||
const FunctionSig* sig = type.function_sig;
|
||||
os << "builder.addType(makeSig(" << PrintParameters(sig) << ", "
|
||||
<< PrintReturns(sig) << "));\n";
|
||||
|
||||
for (int i = 0; i < static_cast<int>(module->types.size()); i++) {
|
||||
if (module->has_struct(i)) {
|
||||
const StructType* struct_type = module->types[i].struct_type;
|
||||
os << "builder.addStruct([";
|
||||
int field_count = struct_type->field_count();
|
||||
for (int index = 0; index < field_count; index++) {
|
||||
os << "makeField(" << ValueTypeToConstantName(struct_type->field(index))
|
||||
<< ", " << (struct_type->mutability(index) ? "true" : "false")
|
||||
<< ")";
|
||||
if (index + 1 < field_count)
|
||||
os << ", ";
|
||||
else
|
||||
os << "]);\n";
|
||||
}
|
||||
} else if (module->has_array(i)) {
|
||||
const ArrayType* array_type = module->types[i].array_type;
|
||||
os << "builder.addArray("
|
||||
<< ValueTypeToConstantName(array_type->element_type()) << ","
|
||||
<< (array_type->mutability() ? "true" : "false") << ");\n";
|
||||
} else {
|
||||
DCHECK(module->has_signature(i));
|
||||
const FunctionSig* sig = module->types[i].function_sig;
|
||||
os << "builder.addType(makeSig(" << PrintParameters(sig) << ", "
|
||||
<< PrintReturns(sig) << "));\n";
|
||||
}
|
||||
}
|
||||
|
||||
Zone tmp_zone(isolate->allocator(), ZONE_NAME);
|
||||
|
Loading…
Reference in New Issue
Block a user