Commit f79eee1f authored by Rakhim Khismet's avatar Rakhim Khismet Committed by V8 LUCI CQ

[fuzzer] Make GetValueType method to generate user-defined reftypes.

We add additional num_types and liftoff parameters
for GetValueType to be able to generate user-def reftypes.
num_types is the number of types in the program and
liftoff checks if we could add reftypes or not.
The additional method (NumTypes) was added to WasmModuleBuilder and
additional field (liftoff) to WasmGenerator constructor.

Bug: v8:11954
Change-Id: I4904a41043264c65d5cba5b22129184d6a486bfe
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3041426
Commit-Queue: Rakhim Khismet <khismet@google.com>
Reviewed-by: 's avatarManos Koukoutos <manoskouk@chromium.org>
Reviewed-by: 's avatarThibaud Michaud <thibaudm@chromium.org>
Cr-Commit-Position: refs/heads/master@{#75840}
parent 67960ba1
......@@ -295,6 +295,8 @@ class V8_EXPORT_PRIVATE WasmModuleBuilder : public ZoneObject {
int NumExceptions() { return static_cast<int>(exceptions_.size()); }
int NumTypes() { return static_cast<int>(types_.size()); }
FunctionSig* GetExceptionType(int index) {
return types_[exceptions_[index]].sig;
}
......
......@@ -89,7 +89,8 @@ class DataRange {
}
};
ValueType GetValueType(DataRange* data) {
ValueType GetValueType(uint32_t num_types, DataRange* data,
bool liftoff_as_reference) {
constexpr ValueType types[] = {
kWasmI32, kWasmI64,
kWasmF32, kWasmF64,
......@@ -97,6 +98,13 @@ ValueType GetValueType(DataRange* data) {
kWasmFuncRef, kWasmEqRef,
kWasmAnyRef, ValueType::Ref(HeapType(HeapType::kData), kNullable)};
if (liftoff_as_reference) {
uint32_t id = data->get<uint8_t>() % (arraysize(types) + num_types);
if (id >= arraysize(types)) {
return ValueType::Ref(id - arraysize(types), kNullable);
}
return types[id];
}
return types[data->get<uint8_t>() % arraysize(types)];
}
......@@ -484,7 +492,9 @@ class WasmGenerator {
}
void drop(DataRange* data) {
Generate(GetValueType(data), data);
Generate(GetValueType(builder_->builder()->NumTypes(), data,
liftoff_as_reference_),
data);
builder_->Emit(kExprDrop);
}
......@@ -780,11 +790,13 @@ class WasmGenerator {
public:
WasmGenerator(WasmFunctionBuilder* fn, const std::vector<uint32_t>& functions,
const std::vector<ValueType>& globals,
const std::vector<uint8_t>& mutable_globals, DataRange* data)
const std::vector<uint8_t>& mutable_globals, DataRange* data,
bool liftoff_as_reference)
: builder_(fn),
functions_(functions),
globals_(globals),
mutable_globals_(mutable_globals) {
mutable_globals_(mutable_globals),
liftoff_as_reference_(liftoff_as_reference) {
FunctionSig* sig = fn->signature();
blocks_.emplace_back();
for (size_t i = 0; i < sig->return_count(); ++i) {
......@@ -794,7 +806,8 @@ class WasmGenerator {
constexpr uint32_t kMaxLocals = 32;
locals_.resize(data->get<uint8_t>() % kMaxLocals);
for (ValueType& local : locals_) {
local = GetValueType(data);
local = GetValueType(builder_->builder()->NumTypes(), data,
liftoff_as_reference_);
fn->AddLocal(local);
}
}
......@@ -832,7 +845,7 @@ class WasmGenerator {
std::vector<int> try_blocks_;
std::vector<int> catch_blocks_;
bool has_simd_;
bool liftoff_as_reference_;
static constexpr uint32_t kMaxRecursionDepth = 64;
bool recursion_limit_reached() {
......@@ -1561,7 +1574,8 @@ std::vector<ValueType> WasmGenerator::GenerateTypes(DataRange* data) {
std::vector<ValueType> types;
int num_params = int{data->get<uint8_t>()} % (kMaxParameters + 1);
for (int i = 0; i < num_params; ++i) {
types.push_back(GetValueType(data));
types.push_back(GetValueType(builder_->builder()->NumTypes(), data,
liftoff_as_reference_));
}
return types;
}
......@@ -1615,7 +1629,8 @@ void WasmGenerator::ConsumeAndGenerate(
enum SigKind { kFunctionSig, kExceptionSig };
FunctionSig* GenerateSig(Zone* zone, DataRange* data, SigKind sig_kind) {
FunctionSig* GenerateSig(Zone* zone, DataRange* data, SigKind sig_kind,
uint32_t num_types, bool liftoff_as_reference) {
// Generate enough parameters to spill some to the stack.
int num_params = int{data->get<uint8_t>()} % (kMaxParameters + 1);
int num_returns = sig_kind == kFunctionSig
......@@ -1623,8 +1638,12 @@ FunctionSig* GenerateSig(Zone* zone, DataRange* data, SigKind sig_kind) {
: 0;
FunctionSig::Builder builder(zone, num_returns, num_params);
for (int i = 0; i < num_returns; ++i) builder.AddReturn(GetValueType(data));
for (int i = 0; i < num_params; ++i) builder.AddParam(GetValueType(data));
for (int i = 0; i < num_returns; ++i) {
builder.AddReturn(GetValueType(num_types, data, liftoff_as_reference));
}
for (int i = 0; i < num_params; ++i) {
builder.AddParam(GetValueType(num_types, data, liftoff_as_reference));
}
return builder.Build();
}
......@@ -1646,7 +1665,8 @@ class WasmCompileFuzzer : public WasmExecutionFuzzer {
int num_functions = 1 + (range.get<uint8_t>() % kMaxFunctions);
for (int i = 1; i < num_functions; ++i) {
FunctionSig* sig = GenerateSig(zone, &range, kFunctionSig);
FunctionSig* sig = GenerateSig(zone, &range, kFunctionSig,
builder.NumTypes(), liftoff_as_reference);
uint32_t signature_index = builder.AddSignature(sig);
function_signatures.push_back(signature_index);
}
......@@ -1659,12 +1679,33 @@ class WasmCompileFuzzer : public WasmExecutionFuzzer {
int num_exceptions = 1 + (range.get<uint8_t>() % kMaxExceptions);
for (int i = 0; i < num_exceptions; ++i) {
FunctionSig* sig = GenerateSig(zone, &range, kExceptionSig);
FunctionSig* sig = GenerateSig(zone, &range, kExceptionSig,
builder.NumTypes(), liftoff_as_reference);
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(&range);
ValueType type =
GetValueType(builder.NumTypes(), &range, liftoff_as_reference);
// 1/8 of globals are immutable.
const bool mutability = (range.get<uint8_t>() % 8) != 0;
builder.AddGlobal(type, mutability, WasmInitExpr());
......@@ -1680,7 +1721,7 @@ class WasmCompileFuzzer : public WasmExecutionFuzzer {
WasmFunctionBuilder* f = builder.AddFunction(sig);
WasmGenerator gen(f, function_signatures, globals, mutable_globals,
&function_range);
&function_range, liftoff_as_reference);
base::Vector<const ValueType> return_types(sig->returns().begin(),
sig->return_count());
gen.Generate(return_types, &function_range);
......@@ -1693,24 +1734,6 @@ class WasmCompileFuzzer : public WasmExecutionFuzzer {
for (int i = 0; i < num_functions; ++i) {
builder.SetIndirectFunction(i, i);
}
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);
}
builder.SetMaxMemorySize(32);
// We enable shared memory to be able to test atomics.
builder.SetHasSharedMemory();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment