Commit 406b99c4 authored by Thibaud Michaud's avatar Thibaud Michaud Committed by Commit Bot

[wasm] Add indirect calls to compile fuzzer

Setup the function table exactly like the module's function table, so
that we can share most of the call generation logic.

R=clemensb@chromium.org

Bug: v8:10751
Change-Id: Ie74150af8cf79d00adcc59d6880d2ed3e7cf78f1
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2323353
Commit-Queue: Thibaud Michaud <thibaudm@chromium.org>
Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#69111}
parent e6414f6e
...@@ -429,9 +429,16 @@ class WasmGenerator { ...@@ -429,9 +429,16 @@ class WasmGenerator {
builder_->Emit(kExprDrop); builder_->Emit(kExprDrop);
} }
enum CallDirect : bool { kCallDirect = true, kCallIndirect = false };
template <ValueType::Kind wanted_type> template <ValueType::Kind wanted_type>
void call(DataRange* data) { void call(DataRange* data) {
call(data, ValueType::Primitive(wanted_type)); call(data, ValueType::Primitive(wanted_type), kCallDirect);
}
template <ValueType::Kind wanted_type>
void call_indirect(DataRange* data) {
call(data, ValueType::Primitive(wanted_type), kCallIndirect);
} }
void Convert(ValueType src, ValueType dst) { void Convert(ValueType src, ValueType dst) {
...@@ -473,10 +480,11 @@ class WasmGenerator { ...@@ -473,10 +480,11 @@ class WasmGenerator {
} }
} }
void call(DataRange* data, ValueType wanted_type) { void call(DataRange* data, ValueType wanted_type, CallDirect call_direct) {
uint8_t random_byte = data->get<uint8_t>(); uint8_t random_byte = data->get<uint8_t>();
int func_index = random_byte % functions_.size(); int func_index = random_byte % functions_.size();
FunctionSig* sig = functions_[func_index]; uint32_t sig_index = functions_[func_index];
FunctionSig* sig = builder_->builder()->GetSignature(sig_index);
// Generate arguments. // Generate arguments.
for (size_t i = 0; i < sig->parameter_count(); ++i) { for (size_t i = 0; i < sig->parameter_count(); ++i) {
Generate(sig->GetParam(i), data); Generate(sig->GetParam(i), data);
...@@ -489,10 +497,22 @@ class WasmGenerator { ...@@ -489,10 +497,22 @@ class WasmGenerator {
std::equal(sig->returns().begin(), sig->returns().end(), std::equal(sig->returns().begin(), sig->returns().end(),
builder_->signature()->returns().begin(), builder_->signature()->returns().begin(),
builder_->signature()->returns().end())) { builder_->signature()->returns().end())) {
builder_->EmitWithU32V(kExprReturnCall, func_index); if (call_direct) {
builder_->EmitWithU32V(kExprReturnCall, func_index);
} else {
builder_->EmitI32Const(func_index);
builder_->EmitWithU32V(kExprReturnCallIndirect, sig_index);
builder_->EmitByte(0); // Table index.
}
return; return;
} else { } else {
builder_->EmitWithU32V(kExprCallFunction, func_index); if (call_direct) {
builder_->EmitWithU32V(kExprCallFunction, func_index);
} else {
builder_->EmitI32Const(func_index);
builder_->EmitWithU32V(kExprCallIndirect, sig_index);
builder_->EmitByte(0); // Table index.
}
} }
if (sig->return_count() == 0 && wanted_type != kWasmStmt) { if (sig->return_count() == 0 && wanted_type != kWasmStmt) {
// The call did not generate a value. Thus just generate it here. // The call did not generate a value. Thus just generate it here.
...@@ -659,8 +679,7 @@ class WasmGenerator { ...@@ -659,8 +679,7 @@ class WasmGenerator {
}; };
public: public:
WasmGenerator(WasmFunctionBuilder* fn, WasmGenerator(WasmFunctionBuilder* fn, const std::vector<uint32_t>& functions,
const std::vector<FunctionSig*>& functions,
const std::vector<ValueType>& globals, const std::vector<ValueType>& globals,
const std::vector<uint8_t>& mutable_globals, DataRange* data) const std::vector<uint8_t>& mutable_globals, DataRange* data)
: builder_(fn), : builder_(fn),
...@@ -703,7 +722,7 @@ class WasmGenerator { ...@@ -703,7 +722,7 @@ class WasmGenerator {
private: private:
WasmFunctionBuilder* builder_; WasmFunctionBuilder* builder_;
std::vector<std::vector<ValueType>> blocks_; std::vector<std::vector<ValueType>> blocks_;
const std::vector<FunctionSig*>& functions_; const std::vector<uint32_t>& functions_;
std::vector<ValueType> locals_; std::vector<ValueType> locals_;
std::vector<ValueType> globals_; std::vector<ValueType> globals_;
std::vector<uint8_t> mutable_globals_; // indexes into {globals_}. std::vector<uint8_t> mutable_globals_; // indexes into {globals_}.
...@@ -767,6 +786,7 @@ void WasmGenerator::Generate<ValueType::kStmt>(DataRange* data) { ...@@ -767,6 +786,7 @@ void WasmGenerator::Generate<ValueType::kStmt>(DataRange* data) {
&WasmGenerator::drop, &WasmGenerator::drop,
&WasmGenerator::call<ValueType::kStmt>, &WasmGenerator::call<ValueType::kStmt>,
&WasmGenerator::call_indirect<ValueType::kStmt>,
&WasmGenerator::set_local, &WasmGenerator::set_local,
&WasmGenerator::set_global}; &WasmGenerator::set_global};
...@@ -939,7 +959,8 @@ void WasmGenerator::Generate<ValueType::kI32>(DataRange* data) { ...@@ -939,7 +959,8 @@ void WasmGenerator::Generate<ValueType::kI32>(DataRange* data) {
ValueType::kI32>, ValueType::kI32>,
&WasmGenerator::select_with_type<ValueType::kI32>, &WasmGenerator::select_with_type<ValueType::kI32>,
&WasmGenerator::call<ValueType::kI32>}; &WasmGenerator::call<ValueType::kI32>,
&WasmGenerator::call_indirect<ValueType::kI32>};
GenerateOneOf(alternatives, data); GenerateOneOf(alternatives, data);
} }
...@@ -1080,7 +1101,8 @@ void WasmGenerator::Generate<ValueType::kI64>(DataRange* data) { ...@@ -1080,7 +1101,8 @@ void WasmGenerator::Generate<ValueType::kI64>(DataRange* data) {
ValueType::kI32>, ValueType::kI32>,
&WasmGenerator::select_with_type<ValueType::kI64>, &WasmGenerator::select_with_type<ValueType::kI64>,
&WasmGenerator::call<ValueType::kI64>}; &WasmGenerator::call<ValueType::kI64>,
&WasmGenerator::call_indirect<ValueType::kI64>};
GenerateOneOf(alternatives, data); GenerateOneOf(alternatives, data);
} }
...@@ -1137,7 +1159,8 @@ void WasmGenerator::Generate<ValueType::kF32>(DataRange* data) { ...@@ -1137,7 +1159,8 @@ void WasmGenerator::Generate<ValueType::kF32>(DataRange* data) {
ValueType::kI32>, ValueType::kI32>,
&WasmGenerator::select_with_type<ValueType::kF32>, &WasmGenerator::select_with_type<ValueType::kF32>,
&WasmGenerator::call<ValueType::kF32>}; &WasmGenerator::call<ValueType::kF32>,
&WasmGenerator::call_indirect<ValueType::kF32>};
GenerateOneOf(alternatives, data); GenerateOneOf(alternatives, data);
} }
...@@ -1194,7 +1217,8 @@ void WasmGenerator::Generate<ValueType::kF64>(DataRange* data) { ...@@ -1194,7 +1217,8 @@ void WasmGenerator::Generate<ValueType::kF64>(DataRange* data) {
ValueType::kI32>, ValueType::kI32>,
&WasmGenerator::select_with_type<ValueType::kF64>, &WasmGenerator::select_with_type<ValueType::kF64>,
&WasmGenerator::call<ValueType::kF64>}; &WasmGenerator::call<ValueType::kF64>,
&WasmGenerator::call_indirect<ValueType::kF64>};
GenerateOneOf(alternatives, data); GenerateOneOf(alternatives, data);
} }
...@@ -1633,14 +1657,16 @@ class WasmCompileFuzzer : public WasmExecutionFuzzer { ...@@ -1633,14 +1657,16 @@ class WasmCompileFuzzer : public WasmExecutionFuzzer {
WasmModuleBuilder builder(zone); WasmModuleBuilder builder(zone);
DataRange range(data); DataRange range(data);
std::vector<FunctionSig*> function_signatures; std::vector<uint32_t> function_signatures;
function_signatures.push_back(sigs.i_iii()); function_signatures.push_back(builder.AddSignature(sigs.i_iii()));
static_assert(kMaxFunctions >= 1, "need min. 1 function"); static_assert(kMaxFunctions >= 1, "need min. 1 function");
int num_functions = 1 + (range.get<uint8_t>() % kMaxFunctions); int num_functions = 1 + (range.get<uint8_t>() % kMaxFunctions);
for (int i = 1; i < num_functions; ++i) { for (int i = 1; i < num_functions; ++i) {
function_signatures.push_back(GenerateSig(zone, &range)); FunctionSig* sig = GenerateSig(zone, &range);
uint32_t signature_index = builder.AddSignature(sig);
function_signatures.push_back(signature_index);
} }
int num_globals = range.get<uint8_t>() % (kMaxGlobals + 1); int num_globals = range.get<uint8_t>() % (kMaxGlobals + 1);
...@@ -1662,7 +1688,7 @@ class WasmCompileFuzzer : public WasmExecutionFuzzer { ...@@ -1662,7 +1688,7 @@ class WasmCompileFuzzer : public WasmExecutionFuzzer {
DataRange function_range = DataRange function_range =
i == num_functions - 1 ? std::move(range) : range.split(); i == num_functions - 1 ? std::move(range) : range.split();
FunctionSig* sig = 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,
...@@ -1675,6 +1701,11 @@ class WasmCompileFuzzer : public WasmExecutionFuzzer { ...@@ -1675,6 +1701,11 @@ class WasmCompileFuzzer : public WasmExecutionFuzzer {
if (i == 0) builder.AddExport(CStrVector("main"), f); if (i == 0) builder.AddExport(CStrVector("main"), f);
} }
builder.AllocateIndirectFunctions(num_functions);
for (int i = 0; i < num_functions; ++i) {
builder.SetIndirectFunction(i, i);
}
builder.SetMaxMemorySize(32); builder.SetMaxMemorySize(32);
// We enable shared memory to be able to test atomics. // We enable shared memory to be able to test atomics.
builder.SetHasSharedMemory(); 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