Commit da70d7aa authored by mtrofin's avatar mtrofin Committed by Commit bot

Steps towards removing the dependency on ModuleEnv from the compiler.

This CL simplifies the relation between the wasm graph builder, the
wasm decoder, and the wasm module they work on.

BUG=

Review-Url: https://codereview.chromium.org/2612643002
Cr-Commit-Position: refs/heads/master@{#42056}
parent 9a4f899d
......@@ -341,10 +341,12 @@ class WasmTrapHelper : public ZoneObject {
};
WasmGraphBuilder::WasmGraphBuilder(
Zone* zone, JSGraph* jsgraph, wasm::FunctionSig* sig,
wasm::ModuleEnv* module_env, Zone* zone, JSGraph* jsgraph,
wasm::FunctionSig* sig,
compiler::SourcePositionTable* source_position_table)
: zone_(zone),
jsgraph_(jsgraph),
module_(module_env),
function_tables_(zone),
function_table_sizes_(zone),
cur_buffer_(def_buffer_),
......@@ -3342,10 +3344,9 @@ Handle<Code> CompileJSToWasmWrapper(Isolate* isolate,
Node* effect = nullptr;
wasm::ModuleEnv module_env(module, nullptr);
WasmGraphBuilder builder(&zone, &jsgraph, func->sig);
WasmGraphBuilder builder(&module_env, &zone, &jsgraph, func->sig);
builder.set_control_ptr(&control);
builder.set_effect_ptr(&effect);
builder.set_module(&module_env);
builder.BuildJSToWasmWrapper(wasm_code, func->sig);
//----------------------------------------------------------------------------
......@@ -3422,7 +3423,8 @@ Handle<Code> CompileWasmToJSWrapper(Isolate* isolate, Handle<JSReceiver> target,
origin == wasm::kAsmJsOrigin ? new (&zone) SourcePositionTable(&graph)
: nullptr;
WasmGraphBuilder builder(&zone, &jsgraph, sig, source_position_table);
WasmGraphBuilder builder(nullptr, &zone, &jsgraph, sig,
source_position_table);
builder.set_control_ptr(&control);
builder.set_effect_ptr(&effect);
builder.BuildWasmToJSWrapper(target, sig);
......@@ -3500,10 +3502,10 @@ SourcePositionTable* WasmCompilationUnit::BuildGraphForWasmFunction(
MachineOperatorBuilder* machine = jsgraph_->machine();
SourcePositionTable* source_position_table =
new (jsgraph_->zone()) SourcePositionTable(graph);
WasmGraphBuilder builder(jsgraph_->zone(), jsgraph_, function_->sig,
source_position_table);
WasmGraphBuilder builder(module_env_, jsgraph_->zone(), jsgraph_,
function_->sig, source_position_table);
const byte* module_start = module_env_->module_bytes.start();
wasm::FunctionBody body = {module_env_, function_->sig, module_start,
wasm::FunctionBody body = {function_->sig, module_start,
module_start + function_->code_start_offset,
module_start + function_->code_end_offset};
graph_construction_result_ =
......@@ -3531,7 +3533,8 @@ SourcePositionTable* WasmCompilationUnit::BuildGraphForWasmFunction(
if (index >= FLAG_trace_wasm_ast_start && index < FLAG_trace_wasm_ast_end) {
OFStream os(stdout);
PrintWasmCode(isolate_->allocator(), body, os, nullptr);
PrintWasmCode(isolate_->allocator(), body, module_env_->module, os,
nullptr);
}
if (index >= FLAG_trace_wasm_text_start && index < FLAG_trace_wasm_text_end) {
OFStream os(stdout);
......
......@@ -109,7 +109,7 @@ typedef ZoneVector<Node*> NodeVector;
class WasmGraphBuilder {
public:
WasmGraphBuilder(
Zone* z, JSGraph* g, wasm::FunctionSig* sig,
wasm::ModuleEnv* module_env, Zone* z, JSGraph* g, wasm::FunctionSig* sig,
compiler::SourcePositionTable* source_position_table = nullptr);
Node** Buffer(size_t count) {
......@@ -206,8 +206,6 @@ class WasmGraphBuilder {
Node* Control() { return *control_; }
Node* Effect() { return *effect_; }
void set_module(wasm::ModuleEnv* module) { this->module_ = module; }
void set_control_ptr(Node** control) { this->control_ = control; }
void set_effect_ptr(Node** effect) { this->effect_ = effect; }
......@@ -229,6 +227,8 @@ class WasmGraphBuilder {
bool has_simd() const { return has_simd_; }
wasm::ModuleEnv* module_env() const { return module_; }
private:
static const int kDefaultBufferSize = 16;
friend class WasmTrapHelper;
......
......@@ -31,13 +31,13 @@ namespace wasm {
#define TRACE(...)
#endif
#define CHECK_PROTOTYPE_OPCODE(flag) \
if (module_ && module_->module->origin == kAsmJsOrigin) { \
error("Opcode not supported for asmjs modules"); \
} \
if (!FLAG_##flag) { \
error("Invalid opcode (enable with --" #flag ")"); \
break; \
#define CHECK_PROTOTYPE_OPCODE(flag) \
if (module_ != nullptr && module_->origin == kAsmJsOrigin) { \
error("Opcode not supported for asmjs modules"); \
} \
if (!FLAG_##flag) { \
error("Invalid opcode (enable with --" #flag ")"); \
break; \
}
// TODO(titzer): this is only for intermediate migration.
#define IMPLICIT_FUNCTION_END 1
......@@ -164,14 +164,14 @@ struct LaneOperand {
// lengths, etc.
class WasmDecoder : public Decoder {
public:
WasmDecoder(ModuleEnv* module, FunctionSig* sig, const byte* start,
WasmDecoder(const WasmModule* module, FunctionSig* sig, const byte* start,
const byte* end)
: Decoder(start, end),
module_(module),
sig_(sig),
total_locals_(0),
local_types_(nullptr) {}
ModuleEnv* module_;
const WasmModule* module_;
FunctionSig* sig_;
size_t total_locals_;
ZoneVector<ValueType>* local_types_;
......@@ -190,9 +190,8 @@ class WasmDecoder : public Decoder {
}
inline bool Validate(const byte* pc, GlobalIndexOperand& operand) {
ModuleEnv* m = module_;
if (m && m->module && operand.index < m->module->globals.size()) {
operand.global = &m->module->globals[operand.index];
if (module_ != nullptr && operand.index < module_->globals.size()) {
operand.global = &module_->globals[operand.index];
operand.type = operand.global->type;
return true;
}
......@@ -201,9 +200,8 @@ class WasmDecoder : public Decoder {
}
inline bool Complete(const byte* pc, CallFunctionOperand& operand) {
ModuleEnv* m = module_;
if (m && m->module && operand.index < m->module->functions.size()) {
operand.sig = m->module->functions[operand.index].sig;
if (module_ != nullptr && operand.index < module_->functions.size()) {
operand.sig = module_->functions[operand.index].sig;
return true;
}
return false;
......@@ -218,17 +216,15 @@ class WasmDecoder : public Decoder {
}
inline bool Complete(const byte* pc, CallIndirectOperand& operand) {
ModuleEnv* m = module_;
if (m && m->module && operand.index < m->module->signatures.size()) {
operand.sig = m->module->signatures[operand.index];
if (module_ != nullptr && operand.index < module_->signatures.size()) {
operand.sig = module_->signatures[operand.index];
return true;
}
return false;
}
inline bool Validate(const byte* pc, CallIndirectOperand& operand) {
uint32_t table_index = 0;
if (!module_->IsValidTable(table_index)) {
if (module_ == nullptr || module_->function_tables.empty()) {
error("function table has to exist to execute call_indirect");
return false;
}
......@@ -363,22 +359,22 @@ class WasmDecoder : public Decoder {
static const int32_t kNullCatch = -1;
// The full WASM decoder for bytecode. Both verifies bytecode and generates
// a TurboFan IR graph.
// The full WASM decoder for bytecode. Verifies bytecode and, optionally,
// generates a TurboFan IR graph.
class WasmFullDecoder : public WasmDecoder {
public:
WasmFullDecoder(Zone* zone, const FunctionBody& body)
: WasmFullDecoder(zone, nullptr, nullptr, body) {}
WasmFullDecoder(Zone* zone, const wasm::WasmModule* module,
const FunctionBody& body)
: WasmFullDecoder(zone, module, nullptr, body) {}
WasmFullDecoder(Zone* zone, TFBuilder* builder, const FunctionBody& body)
: WasmDecoder(body.module, body.sig, body.start, body.end),
zone_(zone),
builder_(builder),
base_(body.base),
local_type_vec_(zone),
stack_(zone),
control_(zone),
last_end_found_(false),
current_catch_(kNullCatch) {
local_types_ = &local_type_vec_;
}
: WasmFullDecoder(zone, builder->module_env() == nullptr
? nullptr
: builder->module_env()->module,
builder, body) {}
bool Decode() {
if (FLAG_wasm_code_fuzzer_gen_test) {
......@@ -492,6 +488,20 @@ class WasmFullDecoder : public WasmDecoder {
}
private:
WasmFullDecoder(Zone* zone, const wasm::WasmModule* module,
TFBuilder* builder, const FunctionBody& body)
: WasmDecoder(module, body.sig, body.start, body.end),
zone_(zone),
builder_(builder),
base_(body.base),
local_type_vec_(zone),
stack_(zone),
control_(zone),
last_end_found_(false),
current_catch_(kNullCatch) {
local_types_ = &local_type_vec_;
}
static const size_t kErrorMsgSize = 128;
Zone* zone_;
......@@ -536,7 +546,6 @@ class WasmFullDecoder : public WasmDecoder {
ssa_env->locals[index++] = node;
}
}
builder_->set_module(module_);
}
ssa_env->control = start;
ssa_env->effect = start;
......@@ -1118,7 +1127,8 @@ class WasmFullDecoder : public WasmDecoder {
break;
case kExprGrowMemory: {
MemoryIndexOperand operand(this, pc_);
if (module_->module->origin != kAsmJsOrigin) {
DCHECK_NOT_NULL(module_);
if (module_->origin != kAsmJsOrigin) {
Value val = Pop(0, kWasmI32);
Push(kWasmI32, BUILD(GrowMemory, val.node));
} else {
......@@ -1168,7 +1178,7 @@ class WasmFullDecoder : public WasmDecoder {
break;
}
case kAtomicPrefix: {
if (!module_ || module_->module->origin != kAsmJsOrigin) {
if (module_ == nullptr || module_->origin != kAsmJsOrigin) {
error("Atomics are allowed only in AsmJs modules");
break;
}
......@@ -1187,7 +1197,7 @@ class WasmFullDecoder : public WasmDecoder {
}
default: {
// Deal with special asmjs opcodes.
if (module_ && module_->module->origin == kAsmJsOrigin) {
if (module_ != nullptr && module_->origin == kAsmJsOrigin) {
sig = WasmOpcodes::AsmjsSignature(opcode);
if (sig) {
BuildSimpleOperator(opcode, sig);
......@@ -1893,8 +1903,8 @@ bool DecodeLocalDecls(BodyLocalDecls& decls, const byte* start,
const byte* end) {
AccountingAllocator allocator;
Zone tmp(&allocator, ZONE_NAME);
FunctionBody body = {nullptr, nullptr, nullptr, start, end};
WasmFullDecoder decoder(&tmp, nullptr, body);
FunctionBody body = {nullptr, nullptr, start, end};
WasmFullDecoder decoder(&tmp, body);
return decoder.DecodeLocalDecls(decls);
}
......@@ -1910,9 +1920,10 @@ BytecodeIterator::BytecodeIterator(const byte* start, const byte* end,
}
DecodeResult VerifyWasmCode(AccountingAllocator* allocator,
const wasm::WasmModule* module,
FunctionBody& body) {
Zone zone(allocator, ZONE_NAME);
WasmFullDecoder decoder(&zone, nullptr, body);
WasmFullDecoder decoder(&zone, module, body);
decoder.Decode();
return decoder.toResult<DecodeStruct*>(nullptr);
}
......@@ -1933,14 +1944,15 @@ unsigned OpcodeLength(const byte* pc, const byte* end) {
void PrintWasmCodeForDebugging(const byte* start, const byte* end) {
AccountingAllocator allocator;
OFStream os(stdout);
PrintWasmCode(&allocator, FunctionBodyForTesting(start, end), os, nullptr);
PrintWasmCode(&allocator, FunctionBodyForTesting(start, end), nullptr, os,
nullptr);
}
bool PrintWasmCode(AccountingAllocator* allocator, const FunctionBody& body,
std::ostream& os,
const wasm::WasmModule* module, std::ostream& os,
std::vector<std::tuple<uint32_t, int, int>>* offset_table) {
Zone zone(allocator, ZONE_NAME);
WasmFullDecoder decoder(&zone, nullptr, body);
WasmFullDecoder decoder(&zone, module, body);
int line_nr = 0;
// Print the function signature.
......@@ -2058,8 +2070,8 @@ bool PrintWasmCode(AccountingAllocator* allocator, const FunctionBody& body,
BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals,
const byte* start, const byte* end) {
FunctionBody body = {nullptr, nullptr, nullptr, start, end};
WasmFullDecoder decoder(zone, nullptr, body);
FunctionBody body = {nullptr, nullptr, start, end};
WasmFullDecoder decoder(zone, body);
return decoder.AnalyzeLoopAssignmentForTesting(start, num_locals);
}
......
......@@ -308,11 +308,10 @@ struct MemoryAccessOperand {
};
typedef compiler::WasmGraphBuilder TFBuilder;
struct ModuleEnv; // forward declaration of module interface.
struct WasmModule; // forward declaration of module interface.
// All of the various data structures necessary to decode a function body.
struct FunctionBody {
ModuleEnv* module; // module environment
FunctionSig* sig; // function signature
const byte* base; // base of the module bytes, for error reporting
const byte* start; // start of the function body
......@@ -321,7 +320,7 @@ struct FunctionBody {
static inline FunctionBody FunctionBodyForTesting(const byte* start,
const byte* end) {
return {nullptr, nullptr, start, start, end};
return {nullptr, start, start, end};
}
struct DecodeStruct {
......@@ -333,28 +332,28 @@ inline std::ostream& operator<<(std::ostream& os, const DecodeStruct& tree) {
}
V8_EXPORT_PRIVATE DecodeResult VerifyWasmCode(AccountingAllocator* allocator,
const wasm::WasmModule* module,
FunctionBody& body);
DecodeResult BuildTFGraph(AccountingAllocator* allocator, TFBuilder* builder,
FunctionBody& body);
bool PrintWasmCode(AccountingAllocator* allocator, const FunctionBody& body,
std::ostream& os,
const wasm::WasmModule* module, std::ostream& os,
std::vector<std::tuple<uint32_t, int, int>>* offset_table);
// A simplified form of AST printing, e.g. from a debugger.
void PrintWasmCodeForDebugging(const byte* start, const byte* end);
inline DecodeResult VerifyWasmCode(AccountingAllocator* allocator,
ModuleEnv* module, FunctionSig* sig,
const WasmModule* module, FunctionSig* sig,
const byte* start, const byte* end) {
FunctionBody body = {module, sig, nullptr, start, end};
return VerifyWasmCode(allocator, body);
FunctionBody body = {sig, nullptr, start, end};
return VerifyWasmCode(allocator, module, body);
}
inline DecodeResult BuildTFGraph(AccountingAllocator* allocator,
TFBuilder* builder, ModuleEnv* module,
FunctionSig* sig, const byte* start,
const byte* end) {
FunctionBody body = {module, sig, nullptr, start, end};
TFBuilder* builder, FunctionSig* sig,
const byte* start, const byte* end) {
FunctionBody body = {sig, nullptr, start, end};
return BuildTFGraph(allocator, builder, body);
}
......
......@@ -763,10 +763,12 @@ class ModuleDecoder : public Decoder {
os << "Verifying WASM function " << WasmFunctionName(function, menv)
<< std::endl;
}
FunctionBody body = {menv, function->sig, start_,
FunctionBody body = {function->sig, start_,
start_ + function->code_start_offset,
start_ + function->code_end_offset};
DecodeResult result = VerifyWasmCode(module_zone->allocator(), body);
DecodeResult result =
VerifyWasmCode(module_zone->allocator(),
menv == nullptr ? nullptr : menv->module, body);
if (result.failed()) {
// Wrap the error message from the function decoder.
std::ostringstream str;
......
......@@ -335,15 +335,15 @@ inline void TestBuildingGraph(Zone* zone, JSGraph* jsgraph, ModuleEnv* module,
FunctionSig* sig,
SourcePositionTable* source_position_table,
const byte* start, const byte* end) {
compiler::WasmGraphBuilder builder(zone, jsgraph, sig, source_position_table);
compiler::WasmGraphBuilder builder(module, zone, jsgraph, sig,
source_position_table);
DecodeResult result =
BuildTFGraph(zone->allocator(), &builder, module, sig, start, end);
BuildTFGraph(zone->allocator(), &builder, sig, start, end);
if (result.failed()) {
if (!FLAG_trace_wasm_decoder) {
// Retry the compilation with the tracing flag on, to help in debugging.
FLAG_trace_wasm_decoder = true;
result =
BuildTFGraph(zone->allocator(), &builder, module, sig, start, end);
result = BuildTFGraph(zone->allocator(), &builder, sig, start, end);
}
ptrdiff_t pc = result.error_pc - result.start;
......
......@@ -110,8 +110,9 @@ class FunctionBodyDecoderTest : public TestWithZone {
const byte* end) {
local_decls.Prepend(zone(), &start, &end);
// Verify the code.
DecodeResult result =
VerifyWasmCode(zone()->allocator(), module, sig, start, end);
DecodeResult result = VerifyWasmCode(
zone()->allocator(), module == nullptr ? nullptr : module->module, sig,
start, end);
if (result.error_code != expected) {
ptrdiff_t pc = result.error_pc - result.start;
......
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