[wasm] Remove non-const reference args from fuzzers
R=ahaas@chromium.org Bug: v8:9429, v8:9396 Change-Id: Ie6119ff58fdf48612d81fe0616986a4da95135d2 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1690836 Reviewed-by: Andreas Haas <ahaas@chromium.org> Commit-Queue: Clemens Hammacher <clemensh@chromium.org> Cr-Commit-Position: refs/heads/master@{#62569}
This commit is contained in:
parent
edd383fbcd
commit
4c9d52e1c8
@ -85,33 +85,31 @@ MachineType RandomType(InputProvider* input) {
|
||||
|
||||
int index(MachineType type) { return static_cast<int>(type.representation()); }
|
||||
|
||||
Node* Constant(RawMachineAssembler& m, // NOLINT(runtime/references)
|
||||
MachineType type, int value) {
|
||||
Node* Constant(RawMachineAssembler* m, MachineType type, int value) {
|
||||
switch (type.representation()) {
|
||||
case MachineRepresentation::kWord32:
|
||||
return m.Int32Constant(static_cast<int32_t>(value));
|
||||
return m->Int32Constant(static_cast<int32_t>(value));
|
||||
case MachineRepresentation::kWord64:
|
||||
return m.Int64Constant(static_cast<int64_t>(value));
|
||||
return m->Int64Constant(static_cast<int64_t>(value));
|
||||
case MachineRepresentation::kFloat32:
|
||||
return m.Float32Constant(static_cast<float>(value));
|
||||
return m->Float32Constant(static_cast<float>(value));
|
||||
case MachineRepresentation::kFloat64:
|
||||
return m.Float64Constant(static_cast<double>(value));
|
||||
return m->Float64Constant(static_cast<double>(value));
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
Node* ToInt32(RawMachineAssembler& m, // NOLINT(runtime/references)
|
||||
MachineType type, Node* a) {
|
||||
Node* ToInt32(RawMachineAssembler* m, MachineType type, Node* a) {
|
||||
switch (type.representation()) {
|
||||
case MachineRepresentation::kWord32:
|
||||
return a;
|
||||
case MachineRepresentation::kWord64:
|
||||
return m.TruncateInt64ToInt32(a);
|
||||
return m->TruncateInt64ToInt32(a);
|
||||
case MachineRepresentation::kFloat32:
|
||||
return m.TruncateFloat32ToInt32(a);
|
||||
return m->TruncateFloat32ToInt32(a);
|
||||
case MachineRepresentation::kFloat64:
|
||||
return m.RoundFloat64ToInt32(a);
|
||||
return m->RoundFloat64ToInt32(a);
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
@ -224,7 +222,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||
MachineType type = desc->GetReturnType(i);
|
||||
// Find a random same-type parameter to return. Use a constant if none.
|
||||
if (counts[index(type)] == 0) {
|
||||
returns[i] = Constant(callee, type, 42);
|
||||
returns[i] = Constant(&callee, type, 42);
|
||||
outputs[i] = 42;
|
||||
} else {
|
||||
int n = input.NextInt32(counts[index(type)]);
|
||||
@ -266,18 +264,18 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||
// WasmContext dummy.
|
||||
params[1] = caller.PointerConstant(nullptr);
|
||||
for (size_t i = 0; i < param_count; ++i) {
|
||||
params[i + 2] = Constant(caller, desc->GetParameterType(i + 1), inputs[i]);
|
||||
params[i + 2] = Constant(&caller, desc->GetParameterType(i + 1), inputs[i]);
|
||||
}
|
||||
Node* call = caller.AddNode(caller.common()->Call(desc),
|
||||
static_cast<int>(param_count + 2), params.get());
|
||||
Node* ret = Constant(caller, MachineType::Int32(), 0);
|
||||
Node* ret = Constant(&caller, MachineType::Int32(), 0);
|
||||
for (size_t i = 0; i < desc->ReturnCount(); ++i) {
|
||||
// Skip roughly one third of the outputs.
|
||||
if (input.NextInt8(3) == 0) continue;
|
||||
Node* ret_i = (desc->ReturnCount() == 1)
|
||||
? call
|
||||
: caller.AddNode(caller.common()->Projection(i), call);
|
||||
ret = caller.Int32Add(ret, ToInt32(caller, desc->GetReturnType(i), ret_i));
|
||||
ret = caller.Int32Add(ret, ToInt32(&caller, desc->GetReturnType(i), ret_i));
|
||||
expect += outputs[i];
|
||||
}
|
||||
caller.Return(ret);
|
||||
|
@ -21,9 +21,9 @@ namespace fuzzer {
|
||||
class WasmCodeFuzzer : public WasmExecutionFuzzer {
|
||||
bool GenerateModule(
|
||||
Isolate* isolate, Zone* zone, Vector<const uint8_t> data,
|
||||
ZoneBuffer& buffer, int32_t& num_args,
|
||||
std::unique_ptr<WasmValue[]>& interpreter_args,
|
||||
std::unique_ptr<Handle<Object>[]>& compiler_args) override {
|
||||
ZoneBuffer* buffer, int32_t* num_args,
|
||||
std::unique_ptr<WasmValue[]>* interpreter_args,
|
||||
std::unique_ptr<Handle<Object>[]>* compiler_args) override {
|
||||
TestSignatures sigs;
|
||||
WasmModuleBuilder builder(zone);
|
||||
WasmFunctionBuilder* f = builder.AddFunction(sigs.i_iii());
|
||||
@ -33,14 +33,15 @@ class WasmCodeFuzzer : public WasmExecutionFuzzer {
|
||||
builder.AddExport(CStrVector("main"), f);
|
||||
|
||||
builder.SetMaxMemorySize(32);
|
||||
builder.WriteTo(&buffer);
|
||||
num_args = 3;
|
||||
interpreter_args.reset(
|
||||
builder.WriteTo(buffer);
|
||||
*num_args = 3;
|
||||
interpreter_args->reset(
|
||||
new WasmValue[3]{WasmValue(1), WasmValue(2), WasmValue(3)});
|
||||
|
||||
compiler_args.reset(new Handle<Object>[3]{
|
||||
handle(Smi::FromInt(1), isolate), handle(Smi::FromInt(2), isolate),
|
||||
handle(Smi::FromInt(3), isolate)});
|
||||
compiler_args->reset(new Handle<Object>[3] {
|
||||
handle(Smi::FromInt(1), isolate), handle(Smi::FromInt(2), isolate),
|
||||
handle(Smi::FromInt(3), isolate)
|
||||
});
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
@ -78,8 +78,8 @@ class DataRange {
|
||||
DISALLOW_COPY_AND_ASSIGN(DataRange);
|
||||
};
|
||||
|
||||
ValueType GetValueType(DataRange& data) { // NOLINT(runtime/references)
|
||||
switch (data.get<uint8_t>() % 4) {
|
||||
ValueType GetValueType(DataRange* data) {
|
||||
switch (data->get<uint8_t>() % 4) {
|
||||
case 0:
|
||||
return kWasmI32;
|
||||
case 1:
|
||||
@ -94,7 +94,7 @@ ValueType GetValueType(DataRange& data) { // NOLINT(runtime/references)
|
||||
|
||||
class WasmGenerator {
|
||||
template <WasmOpcode Op, ValueType... Args>
|
||||
void op(DataRange& data) { // NOLINT(runtime/references)
|
||||
void op(DataRange* data) {
|
||||
Generate<Args...>(data);
|
||||
builder_->Emit(Op);
|
||||
}
|
||||
@ -119,13 +119,13 @@ class WasmGenerator {
|
||||
};
|
||||
|
||||
template <ValueType T>
|
||||
void block(DataRange& data) { // NOLINT(runtime/references)
|
||||
void block(DataRange* data) {
|
||||
BlockScope block_scope(this, kExprBlock, T, T);
|
||||
Generate<T>(data);
|
||||
}
|
||||
|
||||
template <ValueType T>
|
||||
void loop(DataRange& data) { // NOLINT(runtime/references)
|
||||
void loop(DataRange* data) {
|
||||
// When breaking to a loop header, don't provide any input value (hence
|
||||
// kWasmStmt).
|
||||
BlockScope block_scope(this, kExprLoop, T, kWasmStmt);
|
||||
@ -135,7 +135,7 @@ class WasmGenerator {
|
||||
enum IfType { kIf, kIfElse };
|
||||
|
||||
template <ValueType T, IfType type>
|
||||
void if_(DataRange& data) { // NOLINT(runtime/references)
|
||||
void if_(DataRange* data) {
|
||||
static_assert(T == kWasmStmt || type == kIfElse,
|
||||
"if without else cannot produce a value");
|
||||
Generate<kWasmI32>(data);
|
||||
@ -147,10 +147,10 @@ class WasmGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
void br(DataRange& data) { // NOLINT(runtime/references)
|
||||
void br(DataRange* data) {
|
||||
// There is always at least the block representing the function body.
|
||||
DCHECK(!blocks_.empty());
|
||||
const uint32_t target_block = data.get<uint32_t>() % blocks_.size();
|
||||
const uint32_t target_block = data->get<uint32_t>() % blocks_.size();
|
||||
const ValueType break_type = blocks_[target_block];
|
||||
|
||||
Generate(break_type, data);
|
||||
@ -159,10 +159,10 @@ class WasmGenerator {
|
||||
}
|
||||
|
||||
template <ValueType wanted_type>
|
||||
void br_if(DataRange& data) { // NOLINT(runtime/references)
|
||||
void br_if(DataRange* data) {
|
||||
// There is always at least the block representing the function body.
|
||||
DCHECK(!blocks_.empty());
|
||||
const uint32_t target_block = data.get<uint32_t>() % blocks_.size();
|
||||
const uint32_t target_block = data->get<uint32_t>() % blocks_.size();
|
||||
const ValueType break_type = blocks_[target_block];
|
||||
|
||||
Generate(break_type, data);
|
||||
@ -208,9 +208,9 @@ class WasmGenerator {
|
||||
}
|
||||
|
||||
template <WasmOpcode memory_op, ValueType... arg_types>
|
||||
void memop(DataRange& data) { // NOLINT(runtime/references)
|
||||
const uint8_t align = data.get<uint8_t>() % (max_alignment(memory_op) + 1);
|
||||
const uint32_t offset = data.get<uint32_t>();
|
||||
void memop(DataRange* data) {
|
||||
const uint8_t align = data->get<uint8_t>() % (max_alignment(memory_op) + 1);
|
||||
const uint32_t offset = data->get<uint32_t>();
|
||||
|
||||
// Generate the index and the arguments, if any.
|
||||
Generate<kWasmI32, arg_types...>(data);
|
||||
@ -220,13 +220,13 @@ class WasmGenerator {
|
||||
builder_->EmitU32V(offset);
|
||||
}
|
||||
|
||||
void drop(DataRange& data) { // NOLINT(runtime/references)
|
||||
void drop(DataRange* data) {
|
||||
Generate(GetValueType(data), data);
|
||||
builder_->Emit(kExprDrop);
|
||||
}
|
||||
|
||||
template <ValueType wanted_type>
|
||||
void call(DataRange& data) { // NOLINT(runtime/references)
|
||||
void call(DataRange* data) {
|
||||
call(data, wanted_type);
|
||||
}
|
||||
|
||||
@ -258,8 +258,7 @@ class WasmGenerator {
|
||||
builder_->Emit(kConvertOpcodes[arr_idx]);
|
||||
}
|
||||
|
||||
void ConvertOrGenerate(ValueType src, ValueType dst,
|
||||
DataRange& data) { // NOLINT(runtime/references)
|
||||
void ConvertOrGenerate(ValueType src, ValueType dst, DataRange* data) {
|
||||
if (src == dst) return;
|
||||
if (src == kWasmStmt && dst != kWasmStmt) {
|
||||
Generate(dst, data);
|
||||
@ -270,9 +269,8 @@ class WasmGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
void call(DataRange& data, // NOLINT(runtime/references)
|
||||
ValueType wanted_type) {
|
||||
int func_index = data.get<uint8_t>() % functions_.size();
|
||||
void call(DataRange* data, ValueType wanted_type) {
|
||||
int func_index = data->get<uint8_t>() % functions_.size();
|
||||
FunctionSig* sig = functions_[func_index];
|
||||
// Generate arguments.
|
||||
for (size_t i = 0; i < sig->parameter_count(); ++i) {
|
||||
@ -303,20 +301,19 @@ class WasmGenerator {
|
||||
bool is_valid() const { return type != kWasmStmt; }
|
||||
};
|
||||
|
||||
Var GetRandomLocal(DataRange& data) { // NOLINT(runtime/references)
|
||||
Var GetRandomLocal(DataRange* data) {
|
||||
uint32_t num_params =
|
||||
static_cast<uint32_t>(builder_->signature()->parameter_count());
|
||||
uint32_t num_locals = static_cast<uint32_t>(locals_.size());
|
||||
if (num_params + num_locals == 0) return {};
|
||||
uint32_t index = data.get<uint8_t>() % (num_params + num_locals);
|
||||
uint32_t index = data->get<uint8_t>() % (num_params + num_locals);
|
||||
ValueType type = index < num_params ? builder_->signature()->GetParam(index)
|
||||
: locals_[index - num_params];
|
||||
return {index, type};
|
||||
}
|
||||
|
||||
template <ValueType wanted_type>
|
||||
void local_op(DataRange& data, // NOLINT(runtime/references)
|
||||
WasmOpcode opcode) {
|
||||
void local_op(DataRange* data, WasmOpcode opcode) {
|
||||
Var local = GetRandomLocal(data);
|
||||
// If there are no locals and no parameters, just generate any value (if a
|
||||
// value is needed), or do nothing.
|
||||
@ -333,46 +330,43 @@ class WasmGenerator {
|
||||
}
|
||||
|
||||
template <ValueType wanted_type>
|
||||
void get_local(DataRange& data) { // NOLINT(runtime/references)
|
||||
void get_local(DataRange* data) {
|
||||
static_assert(wanted_type != kWasmStmt, "illegal type");
|
||||
local_op<wanted_type>(data, kExprGetLocal);
|
||||
}
|
||||
|
||||
void set_local(DataRange& data) { // NOLINT(runtime/references)
|
||||
local_op<kWasmStmt>(data, kExprSetLocal);
|
||||
}
|
||||
void set_local(DataRange* data) { local_op<kWasmStmt>(data, kExprSetLocal); }
|
||||
|
||||
template <ValueType wanted_type>
|
||||
void tee_local(DataRange& data) { // NOLINT(runtime/references)
|
||||
void tee_local(DataRange* data) {
|
||||
local_op<wanted_type>(data, kExprTeeLocal);
|
||||
}
|
||||
|
||||
template <size_t num_bytes>
|
||||
void i32_const(DataRange& data) { // NOLINT(runtime/references)
|
||||
builder_->EmitI32Const(data.get<int32_t, num_bytes>());
|
||||
void i32_const(DataRange* data) {
|
||||
builder_->EmitI32Const(data->get<int32_t, num_bytes>());
|
||||
}
|
||||
|
||||
template <size_t num_bytes>
|
||||
void i64_const(DataRange& data) { // NOLINT(runtime/references)
|
||||
builder_->EmitI64Const(data.get<int64_t, num_bytes>());
|
||||
void i64_const(DataRange* data) {
|
||||
builder_->EmitI64Const(data->get<int64_t, num_bytes>());
|
||||
}
|
||||
|
||||
Var GetRandomGlobal(DataRange& data, // NOLINT(runtime/references)
|
||||
bool ensure_mutable) {
|
||||
Var GetRandomGlobal(DataRange* data, bool ensure_mutable) {
|
||||
uint32_t index;
|
||||
if (ensure_mutable) {
|
||||
if (mutable_globals_.empty()) return {};
|
||||
index = mutable_globals_[data.get<uint8_t>() % mutable_globals_.size()];
|
||||
index = mutable_globals_[data->get<uint8_t>() % mutable_globals_.size()];
|
||||
} else {
|
||||
if (globals_.empty()) return {};
|
||||
index = data.get<uint8_t>() % globals_.size();
|
||||
index = data->get<uint8_t>() % globals_.size();
|
||||
}
|
||||
ValueType type = globals_[index];
|
||||
return {index, type};
|
||||
}
|
||||
|
||||
template <ValueType wanted_type>
|
||||
void global_op(DataRange& data) { // NOLINT(runtime/references)
|
||||
void global_op(DataRange* data) {
|
||||
constexpr bool is_set = wanted_type == kWasmStmt;
|
||||
Var global = GetRandomGlobal(data, is_set);
|
||||
// If there are no globals, just generate any value (if a value is needed),
|
||||
@ -391,13 +385,13 @@ class WasmGenerator {
|
||||
}
|
||||
|
||||
template <ValueType wanted_type>
|
||||
void get_global(DataRange& data) { // NOLINT(runtime/references)
|
||||
void get_global(DataRange* data) {
|
||||
static_assert(wanted_type != kWasmStmt, "illegal type");
|
||||
global_op<wanted_type>(data);
|
||||
}
|
||||
|
||||
template <ValueType select_type>
|
||||
void select_with_type(DataRange& data) { // NOLINT(runtime/references)
|
||||
void select_with_type(DataRange* data) {
|
||||
static_assert(select_type != kWasmStmt, "illegal type for select");
|
||||
Generate<select_type, select_type, kWasmI32>(data);
|
||||
// num_types is always 1.
|
||||
@ -406,29 +400,26 @@ class WasmGenerator {
|
||||
ValueTypes::ValueTypeCodeFor(select_type));
|
||||
}
|
||||
|
||||
void set_global(DataRange& data) { // NOLINT(runtime/references)
|
||||
global_op<kWasmStmt>(data);
|
||||
}
|
||||
void set_global(DataRange* data) { global_op<kWasmStmt>(data); }
|
||||
|
||||
template <ValueType... Types>
|
||||
void sequence(DataRange& data) { // NOLINT(runtime/references)
|
||||
void sequence(DataRange* data) {
|
||||
Generate<Types...>(data);
|
||||
}
|
||||
|
||||
void current_memory(DataRange& data) { // NOLINT(runtime/references)
|
||||
void current_memory(DataRange* data) {
|
||||
builder_->EmitWithU8(kExprMemorySize, 0);
|
||||
}
|
||||
|
||||
void grow_memory(DataRange& data); // NOLINT(runtime/references)
|
||||
void grow_memory(DataRange* data);
|
||||
|
||||
using generate_fn = void (WasmGenerator::*const)(DataRange&);
|
||||
using generate_fn = void (WasmGenerator::*const)(DataRange*);
|
||||
|
||||
template <size_t N>
|
||||
void GenerateOneOf(generate_fn (&alternates)[N],
|
||||
DataRange& data) { // NOLINT(runtime/references)
|
||||
void GenerateOneOf(generate_fn (&alternates)[N], DataRange* data) {
|
||||
static_assert(N < std::numeric_limits<uint8_t>::max(),
|
||||
"Too many alternates. Replace with a bigger type if needed.");
|
||||
const auto which = data.get<uint8_t>();
|
||||
const auto which = data->get<uint8_t>();
|
||||
|
||||
generate_fn alternate = alternates[which % N];
|
||||
(this->*alternate)(data);
|
||||
@ -450,8 +441,7 @@ class WasmGenerator {
|
||||
WasmGenerator(WasmFunctionBuilder* fn,
|
||||
const std::vector<FunctionSig*>& functions,
|
||||
const std::vector<ValueType>& globals,
|
||||
const std::vector<uint8_t>& mutable_globals,
|
||||
DataRange& data) // NOLINT(runtime/references)
|
||||
const std::vector<uint8_t>& mutable_globals, DataRange* data)
|
||||
: builder_(fn),
|
||||
functions_(functions),
|
||||
globals_(globals),
|
||||
@ -461,23 +451,23 @@ class WasmGenerator {
|
||||
blocks_.push_back(sig->return_count() == 0 ? kWasmStmt : sig->GetReturn(0));
|
||||
|
||||
constexpr uint32_t kMaxLocals = 32;
|
||||
locals_.resize(data.get<uint8_t>() % kMaxLocals);
|
||||
locals_.resize(data->get<uint8_t>() % kMaxLocals);
|
||||
for (ValueType& local : locals_) {
|
||||
local = GetValueType(data);
|
||||
fn->AddLocal(local);
|
||||
}
|
||||
}
|
||||
|
||||
void Generate(ValueType type, DataRange& data); // NOLINT(runtime/references)
|
||||
void Generate(ValueType type, DataRange* data);
|
||||
|
||||
template <ValueType T>
|
||||
void Generate(DataRange& data); // NOLINT(runtime/references)
|
||||
void Generate(DataRange* data);
|
||||
|
||||
template <ValueType T1, ValueType T2, ValueType... Ts>
|
||||
void Generate(DataRange& data) { // NOLINT(runtime/references)
|
||||
void Generate(DataRange* data) {
|
||||
// TODO(clemensh): Implement a more even split.
|
||||
auto first_data = data.split();
|
||||
Generate<T1>(first_data);
|
||||
auto first_data = data->split();
|
||||
Generate<T1>(&first_data);
|
||||
Generate<T2, Ts...>(data);
|
||||
}
|
||||
|
||||
@ -498,10 +488,9 @@ class WasmGenerator {
|
||||
};
|
||||
|
||||
template <>
|
||||
void WasmGenerator::Generate<kWasmStmt>(
|
||||
DataRange& data) { // NOLINT(runtime/references)
|
||||
void WasmGenerator::Generate<kWasmStmt>(DataRange* data) {
|
||||
GeneratorRecursionScope rec_scope(this);
|
||||
if (recursion_limit_reached() || data.size() == 0) return;
|
||||
if (recursion_limit_reached() || data->size() == 0) return;
|
||||
|
||||
constexpr generate_fn alternates[] = {
|
||||
&WasmGenerator::sequence<kWasmStmt, kWasmStmt>,
|
||||
@ -536,11 +525,10 @@ void WasmGenerator::Generate<kWasmStmt>(
|
||||
}
|
||||
|
||||
template <>
|
||||
void WasmGenerator::Generate<kWasmI32>(
|
||||
DataRange& data) { // NOLINT(runtime/references)
|
||||
void WasmGenerator::Generate<kWasmI32>(DataRange* data) {
|
||||
GeneratorRecursionScope rec_scope(this);
|
||||
if (recursion_limit_reached() || data.size() <= 1) {
|
||||
builder_->EmitI32Const(data.get<uint32_t>());
|
||||
if (recursion_limit_reached() || data->size() <= 1) {
|
||||
builder_->EmitI32Const(data->get<uint32_t>());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -635,11 +623,10 @@ void WasmGenerator::Generate<kWasmI32>(
|
||||
}
|
||||
|
||||
template <>
|
||||
void WasmGenerator::Generate<kWasmI64>(
|
||||
DataRange& data) { // NOLINT(runtime/references)
|
||||
void WasmGenerator::Generate<kWasmI64>(DataRange* data) {
|
||||
GeneratorRecursionScope rec_scope(this);
|
||||
if (recursion_limit_reached() || data.size() <= 1) {
|
||||
builder_->EmitI64Const(data.get<int64_t>());
|
||||
if (recursion_limit_reached() || data->size() <= 1) {
|
||||
builder_->EmitI64Const(data->get<int64_t>());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -704,11 +691,10 @@ void WasmGenerator::Generate<kWasmI64>(
|
||||
}
|
||||
|
||||
template <>
|
||||
void WasmGenerator::Generate<kWasmF32>(
|
||||
DataRange& data) { // NOLINT(runtime/references)
|
||||
void WasmGenerator::Generate<kWasmF32>(DataRange* data) {
|
||||
GeneratorRecursionScope rec_scope(this);
|
||||
if (recursion_limit_reached() || data.size() <= sizeof(float)) {
|
||||
builder_->EmitF32Const(data.get<float>());
|
||||
if (recursion_limit_reached() || data->size() <= sizeof(float)) {
|
||||
builder_->EmitF32Const(data->get<float>());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -740,11 +726,10 @@ void WasmGenerator::Generate<kWasmF32>(
|
||||
}
|
||||
|
||||
template <>
|
||||
void WasmGenerator::Generate<kWasmF64>(
|
||||
DataRange& data) { // NOLINT(runtime/references)
|
||||
void WasmGenerator::Generate<kWasmF64>(DataRange* data) {
|
||||
GeneratorRecursionScope rec_scope(this);
|
||||
if (recursion_limit_reached() || data.size() <= sizeof(double)) {
|
||||
builder_->EmitF64Const(data.get<double>());
|
||||
if (recursion_limit_reached() || data->size() <= sizeof(double)) {
|
||||
builder_->EmitF64Const(data->get<double>());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -775,12 +760,12 @@ void WasmGenerator::Generate<kWasmF64>(
|
||||
GenerateOneOf(alternates, data);
|
||||
}
|
||||
|
||||
void WasmGenerator::grow_memory(DataRange& data) {
|
||||
void WasmGenerator::grow_memory(DataRange* data) {
|
||||
Generate<kWasmI32>(data);
|
||||
builder_->EmitWithU8(kExprMemoryGrow, 0);
|
||||
}
|
||||
|
||||
void WasmGenerator::Generate(ValueType type, DataRange& data) {
|
||||
void WasmGenerator::Generate(ValueType type, DataRange* data) {
|
||||
switch (type) {
|
||||
case kWasmStmt:
|
||||
return Generate<kWasmStmt>(data);
|
||||
@ -797,12 +782,11 @@ void WasmGenerator::Generate(ValueType type, DataRange& data) {
|
||||
}
|
||||
}
|
||||
|
||||
FunctionSig* GenerateSig(Zone* zone,
|
||||
DataRange& data) { // NOLINT(runtime/references)
|
||||
FunctionSig* GenerateSig(Zone* zone, DataRange* data) {
|
||||
// Generate enough parameters to spill some to the stack.
|
||||
constexpr int kMaxParameters = 15;
|
||||
int num_params = int{data.get<uint8_t>()} % (kMaxParameters + 1);
|
||||
bool has_return = data.get<bool>();
|
||||
int num_params = int{data->get<uint8_t>()} % (kMaxParameters + 1);
|
||||
bool has_return = data->get<bool>();
|
||||
|
||||
FunctionSig::Builder builder(zone, has_return ? 1 : 0, num_params);
|
||||
if (has_return) builder.AddReturn(GetValueType(data));
|
||||
@ -815,9 +799,9 @@ FunctionSig* GenerateSig(Zone* zone,
|
||||
class WasmCompileFuzzer : public WasmExecutionFuzzer {
|
||||
bool GenerateModule(
|
||||
Isolate* isolate, Zone* zone, Vector<const uint8_t> data,
|
||||
ZoneBuffer& buffer, int32_t& num_args,
|
||||
std::unique_ptr<WasmValue[]>& interpreter_args,
|
||||
std::unique_ptr<Handle<Object>[]>& compiler_args) override {
|
||||
ZoneBuffer* buffer, int32_t* num_args,
|
||||
std::unique_ptr<WasmValue[]>* interpreter_args,
|
||||
std::unique_ptr<Handle<Object>[]>* compiler_args) override {
|
||||
TestSignatures sigs;
|
||||
|
||||
WasmModuleBuilder builder(zone);
|
||||
@ -830,7 +814,7 @@ class WasmCompileFuzzer : public WasmExecutionFuzzer {
|
||||
int num_functions = 1 + (range.get<uint8_t>() % kMaxFunctions);
|
||||
|
||||
for (int i = 1; i < num_functions; ++i) {
|
||||
function_signatures.push_back(GenerateSig(zone, range));
|
||||
function_signatures.push_back(GenerateSig(zone, &range));
|
||||
}
|
||||
|
||||
int num_globals = range.get<uint8_t>() % (kMaxGlobals + 1);
|
||||
@ -840,7 +824,7 @@ class WasmCompileFuzzer : public WasmExecutionFuzzer {
|
||||
mutable_globals.reserve(num_globals);
|
||||
|
||||
for (int i = 0; i < num_globals; ++i) {
|
||||
ValueType type = GetValueType(range);
|
||||
ValueType type = GetValueType(&range);
|
||||
const bool exported = range.get<bool>();
|
||||
// 1/8 of globals are immutable.
|
||||
const bool mutability = (range.get<uint8_t>() % 8) != 0;
|
||||
@ -857,25 +841,26 @@ class WasmCompileFuzzer : public WasmExecutionFuzzer {
|
||||
WasmFunctionBuilder* f = builder.AddFunction(sig);
|
||||
|
||||
WasmGenerator gen(f, function_signatures, globals, mutable_globals,
|
||||
function_range);
|
||||
&function_range);
|
||||
ValueType return_type =
|
||||
sig->return_count() == 0 ? kWasmStmt : sig->GetReturn(0);
|
||||
gen.Generate(return_type, function_range);
|
||||
gen.Generate(return_type, &function_range);
|
||||
|
||||
f->Emit(kExprEnd);
|
||||
if (i == 0) builder.AddExport(CStrVector("main"), f);
|
||||
}
|
||||
|
||||
builder.SetMaxMemorySize(32);
|
||||
builder.WriteTo(&buffer);
|
||||
builder.WriteTo(buffer);
|
||||
|
||||
num_args = 3;
|
||||
interpreter_args.reset(
|
||||
*num_args = 3;
|
||||
interpreter_args->reset(
|
||||
new WasmValue[3]{WasmValue(1), WasmValue(2), WasmValue(3)});
|
||||
|
||||
compiler_args.reset(new Handle<Object>[3]{
|
||||
handle(Smi::FromInt(1), isolate), handle(Smi::FromInt(2), isolate),
|
||||
handle(Smi::FromInt(3), isolate)});
|
||||
compiler_args->reset(new Handle<Object>[3] {
|
||||
handle(Smi::FromInt(1), isolate), handle(Smi::FromInt(2), isolate),
|
||||
handle(Smi::FromInt(3), isolate)
|
||||
});
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
@ -278,8 +278,8 @@ void WasmExecutionFuzzer::FuzzWasmModule(Vector<const uint8_t> data,
|
||||
// compiled with Turbofan and which one with Liftoff.
|
||||
uint8_t tier_mask = data.empty() ? 0 : data[0];
|
||||
if (!data.empty()) data += 1;
|
||||
if (!GenerateModule(i_isolate, &zone, data, buffer, num_args,
|
||||
interpreter_args, compiler_args)) {
|
||||
if (!GenerateModule(i_isolate, &zone, data, &buffer, &num_args,
|
||||
&interpreter_args, &compiler_args)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -37,12 +37,9 @@ class WasmExecutionFuzzer {
|
||||
protected:
|
||||
virtual bool GenerateModule(
|
||||
Isolate* isolate, Zone* zone, Vector<const uint8_t> data,
|
||||
ZoneBuffer& buffer, // NOLINT(runtime/references)
|
||||
int32_t& num_args, // NOLINT(runtime/references)
|
||||
std::unique_ptr<WasmValue[]>&
|
||||
interpreter_args, // NOLINT(runtime/references)
|
||||
std::unique_ptr<Handle<Object>[]>&
|
||||
compiler_args) = 0; // NOLINT(runtime/references)
|
||||
ZoneBuffer* buffer, int32_t* num_args,
|
||||
std::unique_ptr<WasmValue[]>* interpreter_args,
|
||||
std::unique_ptr<Handle<Object>[]>* compiler_args) = 0;
|
||||
};
|
||||
|
||||
} // namespace fuzzer
|
||||
|
Loading…
Reference in New Issue
Block a user