Commit b46cc820 authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[wasm] compile fuzzer: Also generate loops

Beside blocks, do also generate loops.
Also, generalize generation of breaks such that they can happen
anywhere, even outside of a block or loop.

R=eholk@chromium.org

Change-Id: Ib2f8c75913e97f331ec105fd87fc882bc5c04864
Reviewed-on: https://chromium-review.googlesource.com/771610Reviewed-by: 's avatarEric Holk <eholk@chromium.org>
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#49392}
parent 6af79fd8
...@@ -19,7 +19,7 @@ const uint32_t kWasmMagic = 0x6d736100; ...@@ -19,7 +19,7 @@ const uint32_t kWasmMagic = 0x6d736100;
const uint32_t kWasmVersion = 0x01; const uint32_t kWasmVersion = 0x01;
// Binary encoding of local types. // Binary encoding of local types.
enum ValueTypeCode { enum ValueTypeCode : uint8_t {
kLocalVoid = 0x40, kLocalVoid = 0x40,
kLocalI32 = 0x7f, kLocalI32 = 0x7f,
kLocalI64 = 0x7e, kLocalI64 = 0x7e,
......
...@@ -81,30 +81,48 @@ class WasmGenerator { ...@@ -81,30 +81,48 @@ class WasmGenerator {
builder_->Emit(Op); builder_->Emit(Op);
} }
class BlockScope {
public:
BlockScope(WasmGenerator* gen, WasmOpcode block_type, ValueType result_type,
ValueType br_type)
: gen_(gen) {
gen->blocks_.push_back(br_type);
gen->builder_->EmitWithU8(block_type,
WasmOpcodes::ValueTypeCodeFor(result_type));
}
~BlockScope() {
gen_->builder_->Emit(kExprEnd);
gen_->blocks_.pop_back();
}
private:
WasmGenerator* const gen_;
};
template <ValueType T> template <ValueType T>
void block(DataRange data) { void block(DataRange data) {
blocks_.push_back(T); BlockScope block_scope(this, kExprBlock, T, T);
builder_->EmitWithU8(
kExprBlock, static_cast<uint8_t>(WasmOpcodes::ValueTypeCodeFor(T)));
Generate<T>(data); Generate<T>(data);
builder_->Emit(kExprEnd);
blocks_.pop_back();
} }
template <ValueType T> template <ValueType T>
void block_br(DataRange data) { void loop(DataRange data) {
blocks_.push_back(T); // When breaking to a loop header, don't provide any input value (hence
builder_->EmitWithU8( // kWasmStmt).
kExprBlock, static_cast<uint8_t>(WasmOpcodes::ValueTypeCodeFor(T))); BlockScope block_scope(this, kExprLoop, T, kWasmStmt);
Generate<T>(data);
}
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]; const ValueType break_type = blocks_[target_block];
Generate(break_type, data); Generate(break_type, data);
builder_->EmitWithI32V( builder_->EmitWithI32V(
kExprBr, static_cast<uint32_t>(blocks_.size()) - 1 - target_block); kExprBr, static_cast<uint32_t>(blocks_.size()) - 1 - target_block);
builder_->Emit(kExprEnd);
blocks_.pop_back();
} }
// TODO(eholk): make this function constexpr once gcc supports it // TODO(eholk): make this function constexpr once gcc supports it
...@@ -191,7 +209,10 @@ class WasmGenerator { ...@@ -191,7 +209,10 @@ class WasmGenerator {
}; };
public: public:
explicit WasmGenerator(WasmFunctionBuilder* fn) : builder_(fn) {} explicit WasmGenerator(WasmFunctionBuilder* fn) : builder_(fn) {
DCHECK_EQ(1, fn->signature()->return_count());
blocks_.push_back(fn->signature()->GetReturn(0));
}
void Generate(ValueType type, DataRange data); void Generate(ValueType type, DataRange data);
...@@ -224,7 +245,8 @@ void WasmGenerator::Generate<kWasmStmt>(DataRange data) { ...@@ -224,7 +245,8 @@ void WasmGenerator::Generate<kWasmStmt>(DataRange data) {
constexpr generate_fn alternates[] = { constexpr generate_fn alternates[] = {
&WasmGenerator::block<kWasmStmt>, &WasmGenerator::block<kWasmStmt>,
&WasmGenerator::block_br<kWasmStmt>, &WasmGenerator::loop<kWasmStmt>,
&WasmGenerator::br,
&WasmGenerator::memop<kExprI32StoreMem, kWasmI32>, &WasmGenerator::memop<kExprI32StoreMem, kWasmI32>,
&WasmGenerator::memop<kExprI32StoreMem8, kWasmI32>, &WasmGenerator::memop<kExprI32StoreMem8, kWasmI32>,
...@@ -307,7 +329,7 @@ void WasmGenerator::Generate<kWasmI32>(DataRange data) { ...@@ -307,7 +329,7 @@ void WasmGenerator::Generate<kWasmI32>(DataRange data) {
&WasmGenerator::op<kExprI32ReinterpretF32, kWasmF32>, &WasmGenerator::op<kExprI32ReinterpretF32, kWasmF32>,
&WasmGenerator::block<kWasmI32>, &WasmGenerator::block<kWasmI32>,
&WasmGenerator::block_br<kWasmI32>, &WasmGenerator::loop<kWasmI32>,
&WasmGenerator::memop<kExprI32LoadMem>, &WasmGenerator::memop<kExprI32LoadMem>,
&WasmGenerator::memop<kExprI32LoadMem8S>, &WasmGenerator::memop<kExprI32LoadMem8S>,
...@@ -355,7 +377,7 @@ void WasmGenerator::Generate<kWasmI64>(DataRange data) { ...@@ -355,7 +377,7 @@ void WasmGenerator::Generate<kWasmI64>(DataRange data) {
&WasmGenerator::op<kExprI64Popcnt, kWasmI64>, &WasmGenerator::op<kExprI64Popcnt, kWasmI64>,
&WasmGenerator::block<kWasmI64>, &WasmGenerator::block<kWasmI64>,
&WasmGenerator::block_br<kWasmI64>, &WasmGenerator::loop<kWasmI64>,
&WasmGenerator::memop<kExprI64LoadMem>, &WasmGenerator::memop<kExprI64LoadMem>,
&WasmGenerator::memop<kExprI64LoadMem8S>, &WasmGenerator::memop<kExprI64LoadMem8S>,
...@@ -384,7 +406,7 @@ void WasmGenerator::Generate<kWasmF32>(DataRange data) { ...@@ -384,7 +406,7 @@ void WasmGenerator::Generate<kWasmF32>(DataRange data) {
&WasmGenerator::op<kExprF32Mul, kWasmF32, kWasmF32>, &WasmGenerator::op<kExprF32Mul, kWasmF32, kWasmF32>,
&WasmGenerator::block<kWasmF32>, &WasmGenerator::block<kWasmF32>,
&WasmGenerator::block_br<kWasmF32>, &WasmGenerator::loop<kWasmF32>,
&WasmGenerator::memop<kExprF32LoadMem>}; &WasmGenerator::memop<kExprF32LoadMem>};
...@@ -407,7 +429,7 @@ void WasmGenerator::Generate<kWasmF64>(DataRange data) { ...@@ -407,7 +429,7 @@ void WasmGenerator::Generate<kWasmF64>(DataRange data) {
&WasmGenerator::op<kExprF64Mul, kWasmF64, kWasmF64>, &WasmGenerator::op<kExprF64Mul, kWasmF64, kWasmF64>,
&WasmGenerator::block<kWasmF64>, &WasmGenerator::block<kWasmF64>,
&WasmGenerator::block_br<kWasmF64>, &WasmGenerator::loop<kWasmF64>,
&WasmGenerator::memop<kExprF64LoadMem>}; &WasmGenerator::memop<kExprF64LoadMem>};
...@@ -452,8 +474,7 @@ class WasmCompileFuzzer : public WasmExecutionFuzzer { ...@@ -452,8 +474,7 @@ class WasmCompileFuzzer : public WasmExecutionFuzzer {
WasmGenerator gen(f); WasmGenerator gen(f);
gen.Generate<kWasmI32>(DataRange(data, static_cast<uint32_t>(size))); gen.Generate<kWasmI32>(DataRange(data, static_cast<uint32_t>(size)));
uint8_t end_opcode = kExprEnd; f->Emit(kExprEnd);
f->EmitCode(&end_opcode, 1);
builder.AddExport(CStrVector("main"), f); builder.AddExport(CStrVector("main"), f);
builder.SetMaxMemorySize(32); builder.SetMaxMemorySize(32);
......
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