From b46cc820bad1c89a82ff3d4e99412756a449a205 Mon Sep 17 00:00:00 2001 From: Clemens Hammacher Date: Wed, 15 Nov 2017 12:51:15 +0100 Subject: [PATCH] [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/771610 Reviewed-by: Eric Holk Commit-Queue: Clemens Hammacher Cr-Commit-Position: refs/heads/master@{#49392} --- src/wasm/wasm-opcodes.h | 2 +- test/fuzzer/wasm-compile.cc | 59 +++++++++++++++++++++++++------------ 2 files changed, 41 insertions(+), 20 deletions(-) diff --git a/src/wasm/wasm-opcodes.h b/src/wasm/wasm-opcodes.h index 0fb874974b..e8cb348b53 100644 --- a/src/wasm/wasm-opcodes.h +++ b/src/wasm/wasm-opcodes.h @@ -19,7 +19,7 @@ const uint32_t kWasmMagic = 0x6d736100; const uint32_t kWasmVersion = 0x01; // Binary encoding of local types. -enum ValueTypeCode { +enum ValueTypeCode : uint8_t { kLocalVoid = 0x40, kLocalI32 = 0x7f, kLocalI64 = 0x7e, diff --git a/test/fuzzer/wasm-compile.cc b/test/fuzzer/wasm-compile.cc index 64517bd87b..ded3a101f2 100644 --- a/test/fuzzer/wasm-compile.cc +++ b/test/fuzzer/wasm-compile.cc @@ -81,30 +81,48 @@ class WasmGenerator { 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 void block(DataRange data) { - blocks_.push_back(T); - builder_->EmitWithU8( - kExprBlock, static_cast(WasmOpcodes::ValueTypeCodeFor(T))); + BlockScope block_scope(this, kExprBlock, T, T); Generate(data); - builder_->Emit(kExprEnd); - blocks_.pop_back(); } template - void block_br(DataRange data) { - blocks_.push_back(T); - builder_->EmitWithU8( - kExprBlock, static_cast(WasmOpcodes::ValueTypeCodeFor(T))); + 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); + Generate(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() % blocks_.size(); const ValueType break_type = blocks_[target_block]; Generate(break_type, data); builder_->EmitWithI32V( kExprBr, static_cast(blocks_.size()) - 1 - target_block); - builder_->Emit(kExprEnd); - blocks_.pop_back(); } // TODO(eholk): make this function constexpr once gcc supports it @@ -191,7 +209,10 @@ class WasmGenerator { }; 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); @@ -224,7 +245,8 @@ void WasmGenerator::Generate(DataRange data) { constexpr generate_fn alternates[] = { &WasmGenerator::block, - &WasmGenerator::block_br, + &WasmGenerator::loop, + &WasmGenerator::br, &WasmGenerator::memop, &WasmGenerator::memop, @@ -307,7 +329,7 @@ void WasmGenerator::Generate(DataRange data) { &WasmGenerator::op, &WasmGenerator::block, - &WasmGenerator::block_br, + &WasmGenerator::loop, &WasmGenerator::memop, &WasmGenerator::memop, @@ -355,7 +377,7 @@ void WasmGenerator::Generate(DataRange data) { &WasmGenerator::op, &WasmGenerator::block, - &WasmGenerator::block_br, + &WasmGenerator::loop, &WasmGenerator::memop, &WasmGenerator::memop, @@ -384,7 +406,7 @@ void WasmGenerator::Generate(DataRange data) { &WasmGenerator::op, &WasmGenerator::block, - &WasmGenerator::block_br, + &WasmGenerator::loop, &WasmGenerator::memop}; @@ -407,7 +429,7 @@ void WasmGenerator::Generate(DataRange data) { &WasmGenerator::op, &WasmGenerator::block, - &WasmGenerator::block_br, + &WasmGenerator::loop, &WasmGenerator::memop}; @@ -452,8 +474,7 @@ class WasmCompileFuzzer : public WasmExecutionFuzzer { WasmGenerator gen(f); gen.Generate(DataRange(data, static_cast(size))); - uint8_t end_opcode = kExprEnd; - f->EmitCode(&end_opcode, 1); + f->Emit(kExprEnd); builder.AddExport(CStrVector("main"), f); builder.SetMaxMemorySize(32);