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

[fuzzer] Add ref.func and ref.is_null to fuzzer

We add ref.func and ref.is_null to the fuzzed module.
ref.is_null returns i32, so it is added to i32 generator.
ref.func is added to GenerateOptRef.
GetRefType function is added to generate reftypes.

Bug: v8:11954
Change-Id: Ia1add950bed573a02b6bec1cba401273d401919e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3106925
Commit-Queue: Rakhim Khismet <khismet@google.com>
Reviewed-by: 's avatarManos Koukoutos <manoskouk@chromium.org>
Cr-Commit-Position: refs/heads/main@{#76431}
parent 7b072d5b
...@@ -207,6 +207,7 @@ class V8_EXPORT_PRIVATE WasmFunctionBuilder : public ZoneObject { ...@@ -207,6 +207,7 @@ class V8_EXPORT_PRIVATE WasmFunctionBuilder : public ZoneObject {
WasmModuleBuilder* builder() const { return builder_; } WasmModuleBuilder* builder() const { return builder_; }
uint32_t func_index() { return func_index_; } uint32_t func_index() { return func_index_; }
uint32_t sig_index() { return signature_index_; }
inline FunctionSig* signature(); inline FunctionSig* signature();
private: private:
...@@ -296,6 +297,7 @@ class V8_EXPORT_PRIVATE WasmModuleBuilder : public ZoneObject { ...@@ -296,6 +297,7 @@ class V8_EXPORT_PRIVATE WasmModuleBuilder : public ZoneObject {
DCHECK(types_[index].kind == Type::kFunctionSig); DCHECK(types_[index].kind == Type::kFunctionSig);
return types_[index].sig; return types_[index].sig;
} }
bool IsStructType(uint32_t index) { bool IsStructType(uint32_t index) {
return types_[index].kind == Type::kStructType; return types_[index].kind == Type::kStructType;
} }
...@@ -308,10 +310,13 @@ class V8_EXPORT_PRIVATE WasmModuleBuilder : public ZoneObject { ...@@ -308,10 +310,13 @@ class V8_EXPORT_PRIVATE WasmModuleBuilder : public ZoneObject {
} }
ArrayType* GetArrayType(uint32_t index) { return types_[index].array_type; } ArrayType* GetArrayType(uint32_t index) { return types_[index].array_type; }
WasmFunctionBuilder* GetFunction(uint32_t index) { return functions_[index]; }
int NumExceptions() { return static_cast<int>(exceptions_.size()); } int NumExceptions() { return static_cast<int>(exceptions_.size()); }
int NumTypes() { return static_cast<int>(types_.size()); } int NumTypes() { return static_cast<int>(types_.size()); }
int NumFunctions() { return static_cast<int>(functions_.size()); }
FunctionSig* GetExceptionType(int index) { FunctionSig* GetExceptionType(int index) {
return types_[exceptions_[index]].sig; return types_[exceptions_[index]].sig;
} }
......
...@@ -110,6 +110,22 @@ ValueType GetValueType(uint32_t num_types, DataRange* data, ...@@ -110,6 +110,22 @@ ValueType GetValueType(uint32_t num_types, DataRange* data,
return types[data->get<uint8_t>() % arraysize(types)]; return types[data->get<uint8_t>() % arraysize(types)];
} }
ValueType GetRefType(uint32_t num_types, DataRange* data,
bool liftoff_as_reference) {
constexpr ValueType types[] = {
kWasmExternRef, 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)];
}
class WasmGenerator { class WasmGenerator {
template <WasmOpcode Op, ValueKind... Args> template <WasmOpcode Op, ValueKind... Args>
void op(DataRange* data) { void op(DataRange* data) {
...@@ -791,6 +807,18 @@ class WasmGenerator { ...@@ -791,6 +807,18 @@ class WasmGenerator {
builder_->EmitU32V(index); builder_->EmitU32V(index);
} }
return; return;
} else {
DCHECK(builder_->builder()->IsSignature(index));
int func_size = builder_->builder()->NumFunctions();
for (int i = 0; i < func_size; i++) {
WasmFunctionBuilder* func = builder_->builder()->GetFunction(i);
// TODO(11954): Choose a random function from among those matching the
// signature (consider function subtyping?).
if (func->sig_index() == index) {
builder_->EmitWithU32V(kExprRefFunc, func->func_index());
return;
}
}
} }
} }
ref_null(type, data); ref_null(type, data);
...@@ -839,6 +867,14 @@ class WasmGenerator { ...@@ -839,6 +867,14 @@ class WasmGenerator {
} }
} }
template <ValueKind wanted_kind>
void ref_is_null(DataRange* data) {
ValueType val = GetRefType(builder_->builder()->NumTypes(), data,
liftoff_as_reference_);
GenerateOptRef(val.heap_type(), data);
builder_->EmitU32V(kExprRefIsNull);
}
using GenerateFn = void (WasmGenerator::*const)(DataRange*); using GenerateFn = void (WasmGenerator::*const)(DataRange*);
using GenerateFnWithHeap = void (WasmGenerator::*const)(HeapType, DataRange*); using GenerateFnWithHeap = void (WasmGenerator::*const)(HeapType, DataRange*);
...@@ -1155,7 +1191,9 @@ void WasmGenerator::Generate<kI32>(DataRange* data) { ...@@ -1155,7 +1191,9 @@ void WasmGenerator::Generate<kI32>(DataRange* data) {
&WasmGenerator::call_indirect<kI32>, &WasmGenerator::call_indirect<kI32>,
&WasmGenerator::try_block<kI32>, &WasmGenerator::try_block<kI32>,
&WasmGenerator::struct_get<kI32>}; &WasmGenerator::struct_get<kI32>,
&WasmGenerator::ref_is_null<kI32>};
GenerateOneOf(alternatives, data); GenerateOneOf(alternatives, data);
} }
...@@ -1872,12 +1910,10 @@ class WasmCompileFuzzer : public WasmExecutionFuzzer { ...@@ -1872,12 +1910,10 @@ class WasmCompileFuzzer : public WasmExecutionFuzzer {
globals.push_back(type); globals.push_back(type);
if (mutability) mutable_globals.push_back(static_cast<uint8_t>(i)); if (mutability) mutable_globals.push_back(static_cast<uint8_t>(i));
} }
for (int i = 0; i < num_functions; ++i) { for (int i = 0; i < num_functions; ++i) {
DataRange function_range = range.split(); DataRange function_range = range.split();
FunctionSig* sig = builder.GetSignature(function_signatures[i]); FunctionSig* sig = builder.GetSignature(function_signatures[i]);
WasmFunctionBuilder* f = builder.AddFunction(sig); WasmFunctionBuilder* f = builder.AddFunction(sig);
WasmGenerator gen(f, function_signatures, globals, mutable_globals, WasmGenerator gen(f, function_signatures, globals, mutable_globals,
num_structs, num_arrays, &function_range, num_structs, num_arrays, &function_range,
liftoff_as_reference); liftoff_as_reference);
......
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