Commit 6572b562 authored by clemensh's avatar clemensh Committed by Commit bot

[wasm] Remove raw byte pointers from WasmModule

These byte pointers (module_start and module_end) were only valid
during decoding. During instantiation or execution, they can get
invalidated by garbage collection.
This CL removes them from the WasmModule struct, and introduces a new
ModuleStorage struct as interface to the wasm wire bytes.
Since the storage is often needed together with the ModuleEnv, a new
ModuleStorageEnv struct holds both a ModuleEnv and a ModuleStorage.
The pointers in the ModuleStorage should never escape the live range of
this struct, as they might point into a SeqOneByteString or ArrayBuffer.
Therefore, the WasmInterpreter needs to create its own copy of the
whole module.
Runtime functions that previously used the raw pointers in WasmModule
(leading to memory errors) now have to use the SeqOneByteString in the
WasmCompiledModule.

R=titzer@chromium.org
BUG=chromium:669518

Review-Url: https://codereview.chromium.org/2540133002
Cr-Commit-Position: refs/heads/master@{#41388}
parent 6d90507a
...@@ -3152,9 +3152,10 @@ static void RecordFunctionCompilation(CodeEventListener::LogEventsAndTags tag, ...@@ -3152,9 +3152,10 @@ static void RecordFunctionCompilation(CodeEventListener::LogEventsAndTags tag,
*script_str, 0, 0)); *script_str, 0, 0));
} }
Handle<Code> CompileJSToWasmWrapper(Isolate* isolate, wasm::ModuleEnv* module, Handle<Code> CompileJSToWasmWrapper(Isolate* isolate,
const wasm::WasmModule* module,
Handle<Code> wasm_code, uint32_t index) { Handle<Code> wasm_code, uint32_t index) {
const wasm::WasmFunction* func = &module->module->functions[index]; const wasm::WasmFunction* func = &module->functions[index];
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// Create the Graph // Create the Graph
...@@ -3168,10 +3169,11 @@ Handle<Code> CompileJSToWasmWrapper(Isolate* isolate, wasm::ModuleEnv* module, ...@@ -3168,10 +3169,11 @@ Handle<Code> CompileJSToWasmWrapper(Isolate* isolate, wasm::ModuleEnv* module,
Node* control = nullptr; Node* control = nullptr;
Node* effect = nullptr; Node* effect = nullptr;
wasm::ModuleEnv module_env(module, nullptr);
WasmGraphBuilder builder(&zone, &jsgraph, func->sig); WasmGraphBuilder builder(&zone, &jsgraph, func->sig);
builder.set_control_ptr(&control); builder.set_control_ptr(&control);
builder.set_effect_ptr(&effect); builder.set_effect_ptr(&effect);
builder.set_module(module); builder.set_module(&module_env);
builder.BuildJSToWasmWrapper(wasm_code, func->sig); builder.BuildJSToWasmWrapper(wasm_code, func->sig);
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
...@@ -3184,8 +3186,8 @@ Handle<Code> CompileJSToWasmWrapper(Isolate* isolate, wasm::ModuleEnv* module, ...@@ -3184,8 +3186,8 @@ Handle<Code> CompileJSToWasmWrapper(Isolate* isolate, wasm::ModuleEnv* module,
} }
// Schedule and compile to machine code. // Schedule and compile to machine code.
int params = int params = static_cast<int>(
static_cast<int>(module->GetFunctionSignature(index)->parameter_count()); module_env.GetFunctionSignature(index)->parameter_count());
CallDescriptor* incoming = Linkage::GetJSCallDescriptor( CallDescriptor* incoming = Linkage::GetJSCallDescriptor(
&zone, false, params + 1, CallDescriptor::kNoFlags); &zone, false, params + 1, CallDescriptor::kNoFlags);
Code::Flags flags = Code::ComputeFlags(Code::JS_TO_WASM_FUNCTION); Code::Flags flags = Code::ComputeFlags(Code::JS_TO_WASM_FUNCTION);
...@@ -3218,10 +3220,11 @@ Handle<Code> CompileJSToWasmWrapper(Isolate* isolate, wasm::ModuleEnv* module, ...@@ -3218,10 +3220,11 @@ Handle<Code> CompileJSToWasmWrapper(Isolate* isolate, wasm::ModuleEnv* module,
} }
if (isolate->logger()->is_logging_code_events() || isolate->is_profiling()) { if (isolate->logger()->is_logging_code_events() || isolate->is_profiling()) {
RecordFunctionCompilation( char func_name[32];
CodeEventListener::FUNCTION_TAG, isolate, code, "js-to-wasm", index, SNPrintF(ArrayVector(func_name), "js-to-wasm#%d", func->func_index);
wasm::WasmName("export"), RecordFunctionCompilation(CodeEventListener::FUNCTION_TAG, isolate, code,
module->module->GetName(func->name_offset, func->name_length)); "js-to-wasm", index, wasm::WasmName("export"),
CStrVector(func_name));
} }
return code; return code;
} }
...@@ -3321,10 +3324,10 @@ SourcePositionTable* WasmCompilationUnit::BuildGraphForWasmFunction( ...@@ -3321,10 +3324,10 @@ SourcePositionTable* WasmCompilationUnit::BuildGraphForWasmFunction(
new (jsgraph_->zone()) SourcePositionTable(graph); new (jsgraph_->zone()) SourcePositionTable(graph);
WasmGraphBuilder builder(jsgraph_->zone(), jsgraph_, function_->sig, WasmGraphBuilder builder(jsgraph_->zone(), jsgraph_, function_->sig,
source_position_table); source_position_table);
wasm::FunctionBody body = { const byte* module_start = module_env_->module_bytes.start();
module_env_, function_->sig, module_env_->module->module_start, wasm::FunctionBody body = {module_env_, function_->sig, module_start,
module_env_->module->module_start + function_->code_start_offset, module_start + function_->code_start_offset,
module_env_->module->module_start + function_->code_end_offset}; module_start + function_->code_end_offset};
graph_construction_result_ = graph_construction_result_ =
wasm::BuildTFGraph(isolate_->allocator(), &builder, body); wasm::BuildTFGraph(isolate_->allocator(), &builder, body);
...@@ -3354,7 +3357,8 @@ SourcePositionTable* WasmCompilationUnit::BuildGraphForWasmFunction( ...@@ -3354,7 +3357,8 @@ SourcePositionTable* WasmCompilationUnit::BuildGraphForWasmFunction(
} }
if (index >= FLAG_trace_wasm_text_start && index < FLAG_trace_wasm_text_end) { if (index >= FLAG_trace_wasm_text_start && index < FLAG_trace_wasm_text_end) {
OFStream os(stdout); OFStream os(stdout);
PrintWasmText(module_env_->module, function_->func_index, os, nullptr); PrintWasmText(module_env_->module, *module_env_, function_->func_index, os,
nullptr);
} }
if (FLAG_trace_wasm_decode_time) { if (FLAG_trace_wasm_decode_time) {
*decode_ms = decode_timer.Elapsed().InMillisecondsF(); *decode_ms = decode_timer.Elapsed().InMillisecondsF();
...@@ -3364,13 +3368,13 @@ SourcePositionTable* WasmCompilationUnit::BuildGraphForWasmFunction( ...@@ -3364,13 +3368,13 @@ SourcePositionTable* WasmCompilationUnit::BuildGraphForWasmFunction(
WasmCompilationUnit::WasmCompilationUnit(wasm::ErrorThrower* thrower, WasmCompilationUnit::WasmCompilationUnit(wasm::ErrorThrower* thrower,
Isolate* isolate, Isolate* isolate,
wasm::ModuleEnv* module_env, wasm::ModuleBytesEnv* module_env,
const wasm::WasmFunction* function, const wasm::WasmFunction* function,
uint32_t index) uint32_t index)
: thrower_(thrower), : thrower_(thrower),
isolate_(isolate), isolate_(isolate),
module_env_(module_env), module_env_(module_env),
function_(function), function_(&module_env->module->functions[index]),
graph_zone_(new Zone(isolate->allocator(), ZONE_NAME)), graph_zone_(new Zone(isolate->allocator(), ZONE_NAME)),
jsgraph_(new (graph_zone()) JSGraph( jsgraph_(new (graph_zone()) JSGraph(
isolate, new (graph_zone()) Graph(graph_zone()), isolate, new (graph_zone()) Graph(graph_zone()),
...@@ -3380,9 +3384,7 @@ WasmCompilationUnit::WasmCompilationUnit(wasm::ErrorThrower* thrower, ...@@ -3380,9 +3384,7 @@ WasmCompilationUnit::WasmCompilationUnit(wasm::ErrorThrower* thrower,
InstructionSelector::SupportedMachineOperatorFlags(), InstructionSelector::SupportedMachineOperatorFlags(),
InstructionSelector::AlignmentRequirements()))), InstructionSelector::AlignmentRequirements()))),
compilation_zone_(isolate->allocator(), ZONE_NAME), compilation_zone_(isolate->allocator(), ZONE_NAME),
info_(function->name_length != 0 info_(function->name_length != 0 ? module_env->GetNameOrNull(function)
? module_env->module->GetNameOrNull(function->name_offset,
function->name_length)
: ArrayVector("wasm"), : ArrayVector("wasm"),
isolate, &compilation_zone_, isolate, &compilation_zone_,
Code::ComputeFlags(Code::WASM_FUNCTION)), Code::ComputeFlags(Code::WASM_FUNCTION)),
...@@ -3453,8 +3455,7 @@ Handle<Code> WasmCompilationUnit::FinishCompilation() { ...@@ -3453,8 +3455,7 @@ Handle<Code> WasmCompilationUnit::FinishCompilation() {
if (graph_construction_result_.failed()) { if (graph_construction_result_.failed()) {
// Add the function as another context for the exception // Add the function as another context for the exception
ScopedVector<char> buffer(128); ScopedVector<char> buffer(128);
wasm::WasmName name = module_env_->module->GetName( wasm::WasmName name = module_env_->GetName(function_);
function_->name_offset, function_->name_length);
SNPrintF(buffer, "Compiling WASM function #%d:%.*s failed:", SNPrintF(buffer, "Compiling WASM function #%d:%.*s failed:",
function_->func_index, name.length(), name.start()); function_->func_index, name.length(), name.start());
thrower_->CompileFailed(buffer.start(), graph_construction_result_); thrower_->CompileFailed(buffer.start(), graph_construction_result_);
...@@ -3474,11 +3475,10 @@ Handle<Code> WasmCompilationUnit::FinishCompilation() { ...@@ -3474,11 +3475,10 @@ Handle<Code> WasmCompilationUnit::FinishCompilation() {
if (isolate_->logger()->is_logging_code_events() || if (isolate_->logger()->is_logging_code_events() ||
isolate_->is_profiling()) { isolate_->is_profiling()) {
RecordFunctionCompilation( RecordFunctionCompilation(CodeEventListener::FUNCTION_TAG, isolate_, code,
CodeEventListener::FUNCTION_TAG, isolate_, code, "WASM_function", "WASM_function", function_->func_index,
function_->func_index, wasm::WasmName("module"), wasm::WasmName("module"),
module_env_->module->GetName(function_->name_offset, module_env_->GetName(function_));
function_->name_length));
} }
if (FLAG_trace_wasm_decode_time) { if (FLAG_trace_wasm_decode_time) {
......
...@@ -29,8 +29,10 @@ class SourcePositionTable; ...@@ -29,8 +29,10 @@ class SourcePositionTable;
namespace wasm { namespace wasm {
// Forward declarations for some WASM data structures. // Forward declarations for some WASM data structures.
struct ModuleBytesEnv;
struct ModuleEnv; struct ModuleEnv;
struct WasmFunction; struct WasmFunction;
struct WasmModule;
class ErrorThrower; class ErrorThrower;
struct DecodeStruct; struct DecodeStruct;
...@@ -43,7 +45,7 @@ namespace compiler { ...@@ -43,7 +45,7 @@ namespace compiler {
class WasmCompilationUnit final { class WasmCompilationUnit final {
public: public:
WasmCompilationUnit(wasm::ErrorThrower* thrower, Isolate* isolate, WasmCompilationUnit(wasm::ErrorThrower* thrower, Isolate* isolate,
wasm::ModuleEnv* module_env, wasm::ModuleBytesEnv* module_env,
const wasm::WasmFunction* function, uint32_t index); const wasm::WasmFunction* function, uint32_t index);
Zone* graph_zone() { return graph_zone_.get(); } Zone* graph_zone() { return graph_zone_.get(); }
...@@ -54,7 +56,7 @@ class WasmCompilationUnit final { ...@@ -54,7 +56,7 @@ class WasmCompilationUnit final {
static Handle<Code> CompileWasmFunction(wasm::ErrorThrower* thrower, static Handle<Code> CompileWasmFunction(wasm::ErrorThrower* thrower,
Isolate* isolate, Isolate* isolate,
wasm::ModuleEnv* module_env, wasm::ModuleBytesEnv* module_env,
const wasm::WasmFunction* function) { const wasm::WasmFunction* function) {
WasmCompilationUnit unit(thrower, isolate, module_env, function, 0); WasmCompilationUnit unit(thrower, isolate, module_env, function, 0);
unit.ExecuteCompilation(); unit.ExecuteCompilation();
...@@ -66,7 +68,7 @@ class WasmCompilationUnit final { ...@@ -66,7 +68,7 @@ class WasmCompilationUnit final {
wasm::ErrorThrower* thrower_; wasm::ErrorThrower* thrower_;
Isolate* isolate_; Isolate* isolate_;
wasm::ModuleEnv* module_env_; wasm::ModuleBytesEnv* module_env_;
const wasm::WasmFunction* function_; const wasm::WasmFunction* function_;
// The graph zone is deallocated at the end of ExecuteCompilation. // The graph zone is deallocated at the end of ExecuteCompilation.
std::unique_ptr<Zone> graph_zone_; std::unique_ptr<Zone> graph_zone_;
...@@ -88,7 +90,8 @@ Handle<Code> CompileWasmToJSWrapper(Isolate* isolate, Handle<JSReceiver> target, ...@@ -88,7 +90,8 @@ Handle<Code> CompileWasmToJSWrapper(Isolate* isolate, Handle<JSReceiver> target,
MaybeHandle<String> import_name); MaybeHandle<String> import_name);
// Wraps a given wasm code object, producing a code object. // Wraps a given wasm code object, producing a code object.
Handle<Code> CompileJSToWasmWrapper(Isolate* isolate, wasm::ModuleEnv* module, Handle<Code> CompileJSToWasmWrapper(Isolate* isolate,
const wasm::WasmModule* module,
Handle<Code> wasm_code, uint32_t index); Handle<Code> wasm_code, uint32_t index);
// Abstracts details of building TurboFan graph nodes for WASM to separate // Abstracts details of building TurboFan graph nodes for WASM to separate
......
...@@ -33,7 +33,7 @@ class Vector { ...@@ -33,7 +33,7 @@ class Vector {
// Returns a vector using the same backing storage as this one, // Returns a vector using the same backing storage as this one,
// spanning from and including 'from', to but not including 'to'. // spanning from and including 'from', to but not including 'to'.
Vector<T> SubVector(int from, int to) { Vector<T> SubVector(int from, int to) const {
DCHECK(0 <= from); DCHECK(0 <= from);
SLOW_DCHECK(from < to); SLOW_DCHECK(from < to);
SLOW_DCHECK(static_cast<unsigned>(to) <= static_cast<unsigned>(length_)); SLOW_DCHECK(static_cast<unsigned>(to) <= static_cast<unsigned>(length_));
......
...@@ -32,7 +32,7 @@ namespace wasm { ...@@ -32,7 +32,7 @@ namespace wasm {
#endif #endif
#define CHECK_PROTOTYPE_OPCODE(flag) \ #define CHECK_PROTOTYPE_OPCODE(flag) \
if (module_ && module_->origin == kAsmJsOrigin) { \ if (module_ && module_->module->origin == kAsmJsOrigin) { \
error("Opcode not supported for asmjs modules"); \ error("Opcode not supported for asmjs modules"); \
} \ } \
if (!FLAG_##flag) { \ if (!FLAG_##flag) { \
...@@ -1118,7 +1118,7 @@ class WasmFullDecoder : public WasmDecoder { ...@@ -1118,7 +1118,7 @@ class WasmFullDecoder : public WasmDecoder {
break; break;
case kExprGrowMemory: { case kExprGrowMemory: {
MemoryIndexOperand operand(this, pc_); MemoryIndexOperand operand(this, pc_);
if (module_->origin != kAsmJsOrigin) { if (module_->module->origin != kAsmJsOrigin) {
Value val = Pop(0, kAstI32); Value val = Pop(0, kAstI32);
Push(kAstI32, BUILD(GrowMemory, val.node)); Push(kAstI32, BUILD(GrowMemory, val.node));
} else { } else {
...@@ -1168,7 +1168,7 @@ class WasmFullDecoder : public WasmDecoder { ...@@ -1168,7 +1168,7 @@ class WasmFullDecoder : public WasmDecoder {
break; break;
} }
case kAtomicPrefix: { case kAtomicPrefix: {
if (!module_ || module_->origin != kAsmJsOrigin) { if (!module_ || module_->module->origin != kAsmJsOrigin) {
error("Atomics are allowed only in AsmJs modules"); error("Atomics are allowed only in AsmJs modules");
break; break;
} }
...@@ -1187,7 +1187,7 @@ class WasmFullDecoder : public WasmDecoder { ...@@ -1187,7 +1187,7 @@ class WasmFullDecoder : public WasmDecoder {
} }
default: { default: {
// Deal with special asmjs opcodes. // Deal with special asmjs opcodes.
if (module_ && module_->origin == kAsmJsOrigin) { if (module_ && module_->module->origin == kAsmJsOrigin) {
sig = WasmOpcodes::AsmjsSignature(opcode); sig = WasmOpcodes::AsmjsSignature(opcode);
if (sig) { if (sig) {
BuildSimpleOperator(opcode, sig); BuildSimpleOperator(opcode, sig);
......
...@@ -189,7 +189,7 @@ class ModuleDecoder : public Decoder { ...@@ -189,7 +189,7 @@ class ModuleDecoder : public Decoder {
pc_ = limit_; // On error, terminate section decoding loop. pc_ = limit_; // On error, terminate section decoding loop.
} }
static void DumpModule(WasmModule* module, const ModuleResult& result) { void DumpModule(const ModuleResult& result) {
std::string path; std::string path;
if (FLAG_dump_wasm_module_path) { if (FLAG_dump_wasm_module_path) {
path = FLAG_dump_wasm_module_path; path = FLAG_dump_wasm_module_path;
...@@ -199,7 +199,7 @@ class ModuleDecoder : public Decoder { ...@@ -199,7 +199,7 @@ class ModuleDecoder : public Decoder {
} }
} }
// File are named `HASH.{ok,failed}.wasm`. // File are named `HASH.{ok,failed}.wasm`.
size_t hash = base::hash_range(module->module_start, module->module_end); size_t hash = base::hash_range(start_, limit_);
char buf[32] = {'\0'}; char buf[32] = {'\0'};
#if V8_OS_WIN && _MSC_VER < 1900 #if V8_OS_WIN && _MSC_VER < 1900
#define snprintf sprintf_s #define snprintf sprintf_s
...@@ -208,17 +208,15 @@ class ModuleDecoder : public Decoder { ...@@ -208,17 +208,15 @@ class ModuleDecoder : public Decoder {
result.ok() ? "ok" : "failed"); result.ok() ? "ok" : "failed");
std::string name(buf); std::string name(buf);
if (FILE* wasm_file = base::OS::FOpen((path + name).c_str(), "wb")) { if (FILE* wasm_file = base::OS::FOpen((path + name).c_str(), "wb")) {
fwrite(module->module_start, module->module_end - module->module_start, 1, fwrite(start_, limit_ - start_, 1, wasm_file);
wasm_file);
fclose(wasm_file); fclose(wasm_file);
} }
} }
// Decodes an entire module. // Decodes an entire module.
ModuleResult DecodeModule(WasmModule* module, bool verify_functions = true) { ModuleResult DecodeModule(bool verify_functions = true) {
pc_ = start_; pc_ = start_;
module->module_start = start_; WasmModule* module = new WasmModule(module_zone);
module->module_end = limit_;
module->min_mem_pages = 0; module->min_mem_pages = 0;
module->max_mem_pages = 0; module->max_mem_pages = 0;
module->mem_export = false; module->mem_export = false;
...@@ -587,10 +585,8 @@ class ModuleDecoder : public Decoder { ...@@ -587,10 +585,8 @@ class ModuleDecoder : public Decoder {
function->code_start_offset = pc_offset(); function->code_start_offset = pc_offset();
function->code_end_offset = pc_offset() + size; function->code_end_offset = pc_offset() + size;
if (verify_functions) { if (verify_functions) {
ModuleEnv module_env; ModuleBytesEnv module_env(module, nullptr,
module_env.module = module; ModuleWireBytes(start_, limit_));
module_env.origin = module->origin;
VerifyFunctionBody(i + module->num_imported_functions, &module_env, VerifyFunctionBody(i + module->num_imported_functions, &module_env,
function); function);
} }
...@@ -656,7 +652,7 @@ class ModuleDecoder : public Decoder { ...@@ -656,7 +652,7 @@ class ModuleDecoder : public Decoder {
if (verify_functions && result.ok()) { if (verify_functions && result.ok()) {
result.MoveFrom(result_); // Copy error code and location. result.MoveFrom(result_); // Copy error code and location.
} }
if (FLAG_dump_wasm_module) DumpModule(module, result); if (FLAG_dump_wasm_module) DumpModule(result);
return result; return result;
} }
...@@ -667,7 +663,7 @@ class ModuleDecoder : public Decoder { ...@@ -667,7 +663,7 @@ class ModuleDecoder : public Decoder {
} }
// Decodes a single anonymous function starting at {start_}. // Decodes a single anonymous function starting at {start_}.
FunctionResult DecodeSingleFunction(ModuleEnv* module_env, FunctionResult DecodeSingleFunction(ModuleBytesEnv* module_env,
WasmFunction* function) { WasmFunction* function) {
pc_ = start_; pc_ = start_;
function->sig = consume_sig(); // read signature function->sig = consume_sig(); // read signature
...@@ -779,7 +775,7 @@ class ModuleDecoder : public Decoder { ...@@ -779,7 +775,7 @@ class ModuleDecoder : public Decoder {
} }
// Verifies the body (code) of a given function. // Verifies the body (code) of a given function.
void VerifyFunctionBody(uint32_t func_num, ModuleEnv* menv, void VerifyFunctionBody(uint32_t func_num, ModuleBytesEnv* menv,
WasmFunction* function) { WasmFunction* function) {
if (FLAG_trace_wasm_decoder || FLAG_trace_wasm_decode_time) { if (FLAG_trace_wasm_decoder || FLAG_trace_wasm_decode_time) {
OFStream os(stdout); OFStream os(stdout);
...@@ -1120,9 +1116,8 @@ ModuleResult DecodeWasmModule(Isolate* isolate, const byte* module_start, ...@@ -1120,9 +1116,8 @@ ModuleResult DecodeWasmModule(Isolate* isolate, const byte* module_start,
// Signatures are stored in zone memory, which have the same lifetime // Signatures are stored in zone memory, which have the same lifetime
// as the {module}. // as the {module}.
Zone* zone = new Zone(isolate->allocator(), ZONE_NAME); Zone* zone = new Zone(isolate->allocator(), ZONE_NAME);
WasmModule* module = new WasmModule(zone, module_start);
ModuleDecoder decoder(zone, module_start, module_end, origin); ModuleDecoder decoder(zone, module_start, module_end, origin);
ModuleResult result = decoder.DecodeModule(module, verify_functions); ModuleResult result = decoder.DecodeModule(verify_functions);
// TODO(bradnelson): Improve histogram handling of size_t. // TODO(bradnelson): Improve histogram handling of size_t.
// TODO(titzer): this isn't accurate, since it doesn't count the data // TODO(titzer): this isn't accurate, since it doesn't count the data
// allocated on the C++ heap. // allocated on the C++ heap.
...@@ -1146,7 +1141,7 @@ WasmInitExpr DecodeWasmInitExprForTesting(const byte* start, const byte* end) { ...@@ -1146,7 +1141,7 @@ WasmInitExpr DecodeWasmInitExprForTesting(const byte* start, const byte* end) {
} }
FunctionResult DecodeWasmFunction(Isolate* isolate, Zone* zone, FunctionResult DecodeWasmFunction(Isolate* isolate, Zone* zone,
ModuleEnv* module_env, ModuleBytesEnv* module_env,
const byte* function_start, const byte* function_start,
const byte* function_end) { const byte* function_end) {
HistogramTimerScope wasm_decode_function_time_scope( HistogramTimerScope wasm_decode_function_time_scope(
......
...@@ -37,7 +37,8 @@ V8_EXPORT_PRIVATE FunctionSig* DecodeWasmSignatureForTesting(Zone* zone, ...@@ -37,7 +37,8 @@ V8_EXPORT_PRIVATE FunctionSig* DecodeWasmSignatureForTesting(Zone* zone,
// Decodes the bytes of a WASM function between // Decodes the bytes of a WASM function between
// {function_start} and {function_end}. // {function_start} and {function_end}.
V8_EXPORT_PRIVATE FunctionResult DecodeWasmFunction(Isolate* isolate, V8_EXPORT_PRIVATE FunctionResult DecodeWasmFunction(Isolate* isolate,
Zone* zone, ModuleEnv* env, Zone* zone,
ModuleBytesEnv* env,
const byte* function_start, const byte* function_start,
const byte* function_end); const byte* function_end);
......
...@@ -721,8 +721,8 @@ class ControlTransfers : public ZoneObject { ...@@ -721,8 +721,8 @@ class ControlTransfers : public ZoneObject {
public: public:
ControlTransferMap map_; ControlTransferMap map_;
ControlTransfers(Zone* zone, ModuleEnv* env, AstLocalDecls* locals, ControlTransfers(Zone* zone, AstLocalDecls* locals, const byte* start,
const byte* start, const byte* end) const byte* end)
: map_(zone) { : map_(zone) {
// Represents a control flow label. // Represents a control flow label.
struct CLabel : public ZoneObject { struct CLabel : public ZoneObject {
...@@ -890,14 +890,13 @@ class CodeMap { ...@@ -890,14 +890,13 @@ class CodeMap {
const WasmModule* module_; const WasmModule* module_;
ZoneVector<InterpreterCode> interpreter_code_; ZoneVector<InterpreterCode> interpreter_code_;
CodeMap(const WasmModule* module, Zone* zone) CodeMap(const WasmModule* module, const uint8_t* module_start, Zone* zone)
: zone_(zone), module_(module), interpreter_code_(zone) { : zone_(zone), module_(module), interpreter_code_(zone) {
if (module == nullptr) return; if (module == nullptr) return;
for (size_t i = 0; i < module->functions.size(); ++i) { for (size_t i = 0; i < module->functions.size(); ++i) {
const WasmFunction* function = &module->functions[i]; const WasmFunction* function = &module->functions[i];
const byte* code_start = const byte* code_start = module_start + function->code_start_offset;
module->module_start + function->code_start_offset; const byte* code_end = module_start + function->code_end_offset;
const byte* code_end = module->module_start + function->code_end_offset;
AddFunction(function, code_start, code_end); AddFunction(function, code_start, code_end);
} }
} }
...@@ -930,9 +929,8 @@ class CodeMap { ...@@ -930,9 +929,8 @@ class CodeMap {
if (code->targets == nullptr && code->start) { if (code->targets == nullptr && code->start) {
// Compute the control targets map and the local declarations. // Compute the control targets map and the local declarations.
CHECK(DecodeLocalDecls(code->locals, code->start, code->end)); CHECK(DecodeLocalDecls(code->locals, code->start, code->end));
ModuleEnv env = {module_, nullptr, kWasmOrigin};
code->targets = new (zone_) ControlTransfers( code->targets = new (zone_) ControlTransfers(
zone_, &env, &code->locals, code->orig_start, code->orig_end); zone_, &code->locals, code->orig_start, code->orig_end);
} }
return code; return code;
} }
...@@ -1760,14 +1758,19 @@ class ThreadImpl : public WasmInterpreter::Thread { ...@@ -1760,14 +1758,19 @@ class ThreadImpl : public WasmInterpreter::Thread {
class WasmInterpreterInternals : public ZoneObject { class WasmInterpreterInternals : public ZoneObject {
public: public:
WasmInstance* instance_; WasmInstance* instance_;
// Create a copy of the module bytes for the interpreter, since the passed
// pointer might be invalidated after constructing the interpreter.
const ZoneVector<uint8_t> module_bytes_;
CodeMap codemap_; CodeMap codemap_;
ZoneVector<ThreadImpl*> threads_; ZoneVector<ThreadImpl*> threads_;
WasmInterpreterInternals(Zone* zone, WasmInstance* instance) WasmInterpreterInternals(Zone* zone, const ModuleBytesEnv& env)
: instance_(instance), : instance_(env.instance),
codemap_(instance_ ? instance_->module : nullptr, zone), module_bytes_(env.module_bytes.start(), env.module_bytes.end(), zone),
codemap_(env.instance ? env.instance->module : nullptr,
module_bytes_.data(), zone),
threads_(zone) { threads_(zone) {
threads_.push_back(new ThreadImpl(zone, &codemap_, instance)); threads_.push_back(new ThreadImpl(zone, &codemap_, env.instance));
} }
void Delete() { void Delete() {
...@@ -1780,10 +1783,10 @@ class WasmInterpreterInternals : public ZoneObject { ...@@ -1780,10 +1783,10 @@ class WasmInterpreterInternals : public ZoneObject {
//============================================================================ //============================================================================
// Implementation of the public interface of the interpreter. // Implementation of the public interface of the interpreter.
//============================================================================ //============================================================================
WasmInterpreter::WasmInterpreter(WasmInstance* instance, WasmInterpreter::WasmInterpreter(const ModuleBytesEnv& env,
AccountingAllocator* allocator) AccountingAllocator* allocator)
: zone_(allocator, ZONE_NAME), : zone_(allocator, ZONE_NAME),
internals_(new (&zone_) WasmInterpreterInternals(&zone_, instance)) {} internals_(new (&zone_) WasmInterpreterInternals(&zone_, env)) {}
WasmInterpreter::~WasmInterpreter() { internals_->Delete(); } WasmInterpreter::~WasmInterpreter() { internals_->Delete(); }
...@@ -1885,7 +1888,7 @@ bool WasmInterpreter::SetFunctionCodeForTesting(const WasmFunction* function, ...@@ -1885,7 +1888,7 @@ bool WasmInterpreter::SetFunctionCodeForTesting(const WasmFunction* function,
ControlTransferMap WasmInterpreter::ComputeControlTransfersForTesting( ControlTransferMap WasmInterpreter::ComputeControlTransfersForTesting(
Zone* zone, const byte* start, const byte* end) { Zone* zone, const byte* start, const byte* end) {
ControlTransfers targets(zone, nullptr, nullptr, start, end); ControlTransfers targets(zone, nullptr, start, end);
return targets.map_; return targets.map_;
} }
......
...@@ -17,8 +17,8 @@ namespace internal { ...@@ -17,8 +17,8 @@ namespace internal {
namespace wasm { namespace wasm {
// forward declarations. // forward declarations.
struct ModuleBytesEnv;
struct WasmFunction; struct WasmFunction;
struct WasmInstance;
class WasmInterpreterInternals; class WasmInterpreterInternals;
typedef size_t pc_t; typedef size_t pc_t;
...@@ -135,7 +135,7 @@ class V8_EXPORT_PRIVATE WasmInterpreter { ...@@ -135,7 +135,7 @@ class V8_EXPORT_PRIVATE WasmInterpreter {
bool GetBreakpoint(const WasmFunction* function, int pc); bool GetBreakpoint(const WasmFunction* function, int pc);
}; };
WasmInterpreter(WasmInstance* instance, AccountingAllocator* allocator); WasmInterpreter(const ModuleBytesEnv& env, AccountingAllocator* allocator);
~WasmInterpreter(); ~WasmInterpreter();
//========================================================================== //==========================================================================
......
This diff is collapsed.
...@@ -177,6 +177,7 @@ struct WasmExport { ...@@ -177,6 +177,7 @@ struct WasmExport {
}; };
enum ModuleOrigin { kWasmOrigin, kAsmJsOrigin }; enum ModuleOrigin { kWasmOrigin, kAsmJsOrigin };
struct ModuleWireBytes;
// Static representation of a module. // Static representation of a module.
struct V8_EXPORT_PRIVATE WasmModule { struct V8_EXPORT_PRIVATE WasmModule {
...@@ -187,8 +188,6 @@ struct V8_EXPORT_PRIVATE WasmModule { ...@@ -187,8 +188,6 @@ struct V8_EXPORT_PRIVATE WasmModule {
static const size_t kV8MaxTableSize = 16 * 1024 * 1024; static const size_t kV8MaxTableSize = 16 * 1024 * 1024;
Zone* owned_zone; Zone* owned_zone;
const byte* module_start = nullptr; // starting address for the module bytes
const byte* module_end = nullptr; // end address for the module bytes
uint32_t min_mem_pages = 0; // minimum size of the memory in 64k pages uint32_t min_mem_pages = 0; // minimum size of the memory in 64k pages
uint32_t max_mem_pages = 0; // maximum size of the memory in 64k pages uint32_t max_mem_pages = 0; // maximum size of the memory in 64k pages
bool has_memory = false; // true if the memory was defined or imported bool has_memory = false; // true if the memory was defined or imported
...@@ -220,46 +219,12 @@ struct V8_EXPORT_PRIVATE WasmModule { ...@@ -220,46 +219,12 @@ struct V8_EXPORT_PRIVATE WasmModule {
// switch to libc-2.21 or higher. // switch to libc-2.21 or higher.
std::unique_ptr<base::Semaphore> pending_tasks; std::unique_ptr<base::Semaphore> pending_tasks;
WasmModule() : WasmModule(nullptr, nullptr) {} WasmModule() : WasmModule(nullptr) {}
WasmModule(Zone* owned_zone, const byte* module_start); WasmModule(Zone* owned_zone);
~WasmModule() { ~WasmModule() {
if (owned_zone) delete owned_zone; if (owned_zone) delete owned_zone;
} }
// Get a string stored in the module bytes representing a name.
WasmName GetName(uint32_t offset, uint32_t length) const {
if (length == 0) return {"<?>", 3}; // no name.
CHECK(BoundsCheck(offset, offset + length));
DCHECK_GE(static_cast<int>(length), 0);
return {reinterpret_cast<const char*>(module_start + offset),
static_cast<int>(length)};
}
// Get a string stored in the module bytes representing a function name.
WasmName GetName(WasmFunction* function) const {
return GetName(function->name_offset, function->name_length);
}
// Get a string stored in the module bytes representing a name.
WasmName GetNameOrNull(uint32_t offset, uint32_t length) const {
if (offset == 0 && length == 0) return {NULL, 0}; // no name.
CHECK(BoundsCheck(offset, offset + length));
DCHECK_GE(static_cast<int>(length), 0);
return {reinterpret_cast<const char*>(module_start + offset),
static_cast<int>(length)};
}
// Get a string stored in the module bytes representing a function name.
WasmName GetNameOrNull(const WasmFunction* function) const {
return GetNameOrNull(function->name_offset, function->name_length);
}
// Checks the given offset range is contained within the module bytes.
bool BoundsCheck(uint32_t start, uint32_t end) const {
size_t size = module_end - module_start;
return start <= size && end <= size;
}
// Creates a new instantiation of the module in the given isolate. // Creates a new instantiation of the module in the given isolate.
static MaybeHandle<WasmInstanceObject> Instantiate( static MaybeHandle<WasmInstanceObject> Instantiate(
Isolate* isolate, ErrorThrower* thrower, Handle<JSObject> wasm_module, Isolate* isolate, ErrorThrower* thrower, Handle<JSObject> wasm_module,
...@@ -267,7 +232,7 @@ struct V8_EXPORT_PRIVATE WasmModule { ...@@ -267,7 +232,7 @@ struct V8_EXPORT_PRIVATE WasmModule {
MaybeHandle<WasmCompiledModule> CompileFunctions( MaybeHandle<WasmCompiledModule> CompileFunctions(
Isolate* isolate, Handle<Managed<WasmModule>> module_wrapper, Isolate* isolate, Handle<Managed<WasmModule>> module_wrapper,
ErrorThrower* thrower) const; ErrorThrower* thrower, const ModuleWireBytes& wire_bytes) const;
}; };
typedef Managed<WasmModule> WasmModuleWrapper; typedef Managed<WasmModule> WasmModuleWrapper;
...@@ -294,12 +259,63 @@ struct WasmInstance { ...@@ -294,12 +259,63 @@ struct WasmInstance {
function_code(m->functions.size()) {} function_code(m->functions.size()) {}
}; };
// Interface to the storage (wire bytes) of a wasm module.
// It is illegal for anyone receiving a ModuleWireBytes to store pointers based
// on module_bytes, as this storage is only guaranteed to be alive as long as
// this struct is alive.
struct V8_EXPORT_PRIVATE ModuleWireBytes {
ModuleWireBytes(Vector<const byte> module_bytes)
: module_bytes(module_bytes) {}
ModuleWireBytes(const byte* start, const byte* end)
: module_bytes(start, static_cast<int>(end - start)) {
DCHECK_GE(kMaxInt, end - start);
}
const Vector<const byte> module_bytes;
// Get a string stored in the module bytes representing a name.
WasmName GetName(uint32_t offset, uint32_t length) const {
if (length == 0) return {"<?>", 3}; // no name.
CHECK(BoundsCheck(offset, length));
DCHECK_GE(static_cast<int>(length), 0);
return Vector<const char>::cast(
module_bytes.SubVector(offset, offset + length));
}
// Get a string stored in the module bytes representing a function name.
WasmName GetName(const WasmFunction* function) const {
return GetName(function->name_offset, function->name_length);
}
// Get a string stored in the module bytes representing a name.
WasmName GetNameOrNull(uint32_t offset, uint32_t length) const {
if (offset == 0 && length == 0) return {NULL, 0}; // no name.
CHECK(BoundsCheck(offset, length));
DCHECK_GE(static_cast<int>(length), 0);
return Vector<const char>::cast(
module_bytes.SubVector(offset, offset + length));
}
// Get a string stored in the module bytes representing a function name.
WasmName GetNameOrNull(const WasmFunction* function) const {
return GetNameOrNull(function->name_offset, function->name_length);
}
// Checks the given offset range is contained within the module bytes.
bool BoundsCheck(uint32_t offset, uint32_t length) const {
uint32_t size = static_cast<uint32_t>(module_bytes.length());
return offset <= size && length <= size - offset;
}
};
// Interface provided to the decoder/graph builder which contains only // Interface provided to the decoder/graph builder which contains only
// minimal information about the globals, functions, and function tables. // minimal information about the globals, functions, and function tables.
struct V8_EXPORT_PRIVATE ModuleEnv { struct V8_EXPORT_PRIVATE ModuleEnv {
ModuleEnv(const WasmModule* module, WasmInstance* instance)
: module(module), instance(instance) {}
const WasmModule* module; const WasmModule* module;
WasmInstance* instance; WasmInstance* instance;
ModuleOrigin origin;
bool IsValidGlobal(uint32_t index) const { bool IsValidGlobal(uint32_t index) const {
return module && index < module->globals.size(); return module && index < module->globals.size();
...@@ -330,7 +346,7 @@ struct V8_EXPORT_PRIVATE ModuleEnv { ...@@ -330,7 +346,7 @@ struct V8_EXPORT_PRIVATE ModuleEnv {
return &module->function_tables[index]; return &module->function_tables[index];
} }
bool asm_js() { return origin == kAsmJsOrigin; } bool asm_js() { return module->origin == kAsmJsOrigin; }
Handle<Code> GetFunctionCode(uint32_t index) { Handle<Code> GetFunctionCode(uint32_t index) {
DCHECK_NOT_NULL(instance); DCHECK_NOT_NULL(instance);
...@@ -345,12 +361,23 @@ struct V8_EXPORT_PRIVATE ModuleEnv { ...@@ -345,12 +361,23 @@ struct V8_EXPORT_PRIVATE ModuleEnv {
Zone* zone, compiler::CallDescriptor* descriptor); Zone* zone, compiler::CallDescriptor* descriptor);
}; };
// A ModuleEnv together with ModuleWireBytes.
struct ModuleBytesEnv : public ModuleEnv, public ModuleWireBytes {
ModuleBytesEnv(const WasmModule* module, WasmInstance* instance,
Vector<const byte> module_bytes)
: ModuleEnv(module, instance), ModuleWireBytes(module_bytes) {}
ModuleBytesEnv(const WasmModule* module, WasmInstance* instance,
const ModuleWireBytes& wire_bytes)
: ModuleEnv(module, instance), ModuleWireBytes(wire_bytes) {}
};
// A helper for printing out the names of functions. // A helper for printing out the names of functions.
struct WasmFunctionName { struct WasmFunctionName {
WasmFunctionName(const WasmFunction* function, ModuleBytesEnv* module_env)
: function_(function), name_(module_env->GetNameOrNull(function)) {}
const WasmFunction* function_; const WasmFunction* function_;
const WasmModule* module_; WasmName name_;
WasmFunctionName(const WasmFunction* function, const ModuleEnv* menv)
: function_(function), module_(menv ? menv->module : nullptr) {}
}; };
std::ostream& operator<<(std::ostream& os, const WasmModule& module); std::ostream& operator<<(std::ostream& os, const WasmModule& module);
......
...@@ -128,7 +128,8 @@ bool IsValidFunctionName(const Vector<const char> &name) { ...@@ -128,7 +128,8 @@ bool IsValidFunctionName(const Vector<const char> &name) {
} // namespace } // namespace
void wasm::PrintWasmText( void wasm::PrintWasmText(
const WasmModule *module, uint32_t func_index, std::ostream &os, const WasmModule *module, const ModuleWireBytes &wire_bytes,
uint32_t func_index, std::ostream &os,
std::vector<std::tuple<uint32_t, int, int>> *offset_table) { std::vector<std::tuple<uint32_t, int, int>> *offset_table) {
DCHECK_NOT_NULL(module); DCHECK_NOT_NULL(module);
DCHECK_GT(module->functions.size(), func_index); DCHECK_GT(module->functions.size(), func_index);
...@@ -141,9 +142,7 @@ void wasm::PrintWasmText( ...@@ -141,9 +142,7 @@ void wasm::PrintWasmText(
// Print the function signature. // Print the function signature.
os << "func"; os << "func";
Vector<const char> fun_name( WasmName fun_name = wire_bytes.GetNameOrNull(fun);
reinterpret_cast<const char *>(module->module_start + fun->name_offset),
fun->name_length);
if (IsValidFunctionName(fun_name)) { if (IsValidFunctionName(fun_name)) {
os << " $"; os << " $";
os.write(fun_name.start(), fun_name.length()); os.write(fun_name.start(), fun_name.length());
...@@ -167,10 +166,10 @@ void wasm::PrintWasmText( ...@@ -167,10 +166,10 @@ void wasm::PrintWasmText(
// Print the local declarations. // Print the local declarations.
AstLocalDecls decls(&zone); AstLocalDecls decls(&zone);
const byte *code_start = module->module_start + fun->code_start_offset; Vector<const byte> func_bytes = wire_bytes.module_bytes.SubVector(
const byte *code_end = module->module_start + fun->code_end_offset; fun->code_start_offset, fun->code_end_offset);
BytecodeIterator i(code_start, code_end, &decls); BytecodeIterator i(func_bytes.begin(), func_bytes.end(), &decls);
DCHECK_LT(code_start, i.pc()); DCHECK_LT(func_bytes.begin(), i.pc());
if (!decls.local_types.empty()) { if (!decls.local_types.empty()) {
os << "(local"; os << "(local";
for (auto p : decls.local_types) { for (auto p : decls.local_types) {
......
...@@ -17,12 +17,13 @@ namespace wasm { ...@@ -17,12 +17,13 @@ namespace wasm {
// Forward declaration. // Forward declaration.
struct WasmModule; struct WasmModule;
struct ModuleWireBytes;
// Generate disassembly according to official text format. // Generate disassembly according to official text format.
// Output disassembly to the given output stream, and optionally return an // Output disassembly to the given output stream, and optionally return an
// offset table of <byte offset, line, column> via the given pointer. // offset table of <byte offset, line, column> via the given pointer.
void PrintWasmText(const WasmModule *module, uint32_t func_index, void PrintWasmText(const WasmModule *module, const ModuleWireBytes &wire_bytes,
std::ostream &os, uint32_t func_index, std::ostream &os,
std::vector<std::tuple<uint32_t, int, int>> *offset_table); std::vector<std::tuple<uint32_t, int, int>> *offset_table);
} // namespace wasm } // namespace wasm
......
...@@ -36,6 +36,13 @@ class ZoneVector : public std::vector<T, zone_allocator<T>> { ...@@ -36,6 +36,13 @@ class ZoneVector : public std::vector<T, zone_allocator<T>> {
// having the value {def}. // having the value {def}.
ZoneVector(size_t size, T def, Zone* zone) ZoneVector(size_t size, T def, Zone* zone)
: std::vector<T, zone_allocator<T>>(size, def, zone_allocator<T>(zone)) {} : std::vector<T, zone_allocator<T>>(size, def, zone_allocator<T>(zone)) {}
// Constructs a new vector and fills it with the contents of the range
// [first, last).
template <class InputIt>
ZoneVector(InputIt first, InputIt last, Zone* zone)
: std::vector<T, zone_allocator<T>>(first, last,
zone_allocator<T>(zone)) {}
}; };
// A wrapper subclass std::deque to make it easy to construct one // A wrapper subclass std::deque to make it easy to construct one
......
...@@ -39,7 +39,7 @@ uint32_t GetMatchingRelocInfoCount(Handle<Code> code, RelocInfo::Mode rmode) { ...@@ -39,7 +39,7 @@ uint32_t GetMatchingRelocInfoCount(Handle<Code> code, RelocInfo::Mode rmode) {
WASM_EXEC_TEST(Int32AsmjsDivS) { WASM_EXEC_TEST(Int32AsmjsDivS) {
TestingModule module(execution_mode); TestingModule module(execution_mode);
module.origin = kAsmJsOrigin; module.ChangeOriginToAsmjs();
WasmRunner<int32_t> r(&module, MachineType::Int32(), MachineType::Int32()); WasmRunner<int32_t> r(&module, MachineType::Int32(), MachineType::Int32());
BUILD(r, WASM_BINOP(kExprI32AsmjsDivS, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); BUILD(r, WASM_BINOP(kExprI32AsmjsDivS, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
const int32_t kMin = std::numeric_limits<int32_t>::min(); const int32_t kMin = std::numeric_limits<int32_t>::min();
...@@ -52,7 +52,7 @@ WASM_EXEC_TEST(Int32AsmjsDivS) { ...@@ -52,7 +52,7 @@ WASM_EXEC_TEST(Int32AsmjsDivS) {
WASM_EXEC_TEST(Int32AsmjsRemS) { WASM_EXEC_TEST(Int32AsmjsRemS) {
TestingModule module(execution_mode); TestingModule module(execution_mode);
module.origin = kAsmJsOrigin; module.ChangeOriginToAsmjs();
WasmRunner<int32_t> r(&module, MachineType::Int32(), MachineType::Int32()); WasmRunner<int32_t> r(&module, MachineType::Int32(), MachineType::Int32());
BUILD(r, WASM_BINOP(kExprI32AsmjsRemS, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); BUILD(r, WASM_BINOP(kExprI32AsmjsRemS, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
const int32_t kMin = std::numeric_limits<int32_t>::min(); const int32_t kMin = std::numeric_limits<int32_t>::min();
...@@ -65,7 +65,7 @@ WASM_EXEC_TEST(Int32AsmjsRemS) { ...@@ -65,7 +65,7 @@ WASM_EXEC_TEST(Int32AsmjsRemS) {
WASM_EXEC_TEST(Int32AsmjsDivU) { WASM_EXEC_TEST(Int32AsmjsDivU) {
TestingModule module(execution_mode); TestingModule module(execution_mode);
module.origin = kAsmJsOrigin; module.ChangeOriginToAsmjs();
WasmRunner<int32_t> r(&module, MachineType::Int32(), MachineType::Int32()); WasmRunner<int32_t> r(&module, MachineType::Int32(), MachineType::Int32());
BUILD(r, WASM_BINOP(kExprI32AsmjsDivU, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); BUILD(r, WASM_BINOP(kExprI32AsmjsDivU, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
const int32_t kMin = std::numeric_limits<int32_t>::min(); const int32_t kMin = std::numeric_limits<int32_t>::min();
...@@ -78,7 +78,7 @@ WASM_EXEC_TEST(Int32AsmjsDivU) { ...@@ -78,7 +78,7 @@ WASM_EXEC_TEST(Int32AsmjsDivU) {
WASM_EXEC_TEST(Int32AsmjsRemU) { WASM_EXEC_TEST(Int32AsmjsRemU) {
TestingModule module(execution_mode); TestingModule module(execution_mode);
module.origin = kAsmJsOrigin; module.ChangeOriginToAsmjs();
WasmRunner<int32_t> r(&module, MachineType::Int32(), MachineType::Int32()); WasmRunner<int32_t> r(&module, MachineType::Int32(), MachineType::Int32());
BUILD(r, WASM_BINOP(kExprI32AsmjsRemU, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); BUILD(r, WASM_BINOP(kExprI32AsmjsRemU, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
const int32_t kMin = std::numeric_limits<int32_t>::min(); const int32_t kMin = std::numeric_limits<int32_t>::min();
...@@ -91,7 +91,7 @@ WASM_EXEC_TEST(Int32AsmjsRemU) { ...@@ -91,7 +91,7 @@ WASM_EXEC_TEST(Int32AsmjsRemU) {
WASM_EXEC_TEST(I32AsmjsSConvertF32) { WASM_EXEC_TEST(I32AsmjsSConvertF32) {
TestingModule module(execution_mode); TestingModule module(execution_mode);
module.origin = kAsmJsOrigin; module.ChangeOriginToAsmjs();
WasmRunner<int32_t> r(&module, MachineType::Float32()); WasmRunner<int32_t> r(&module, MachineType::Float32());
BUILD(r, WASM_UNOP(kExprI32AsmjsSConvertF32, WASM_GET_LOCAL(0))); BUILD(r, WASM_UNOP(kExprI32AsmjsSConvertF32, WASM_GET_LOCAL(0)));
...@@ -103,7 +103,7 @@ WASM_EXEC_TEST(I32AsmjsSConvertF32) { ...@@ -103,7 +103,7 @@ WASM_EXEC_TEST(I32AsmjsSConvertF32) {
WASM_EXEC_TEST(I32AsmjsSConvertF64) { WASM_EXEC_TEST(I32AsmjsSConvertF64) {
TestingModule module(execution_mode); TestingModule module(execution_mode);
module.origin = kAsmJsOrigin; module.ChangeOriginToAsmjs();
WasmRunner<int32_t> r(&module, MachineType::Float64()); WasmRunner<int32_t> r(&module, MachineType::Float64());
BUILD(r, WASM_UNOP(kExprI32AsmjsSConvertF64, WASM_GET_LOCAL(0))); BUILD(r, WASM_UNOP(kExprI32AsmjsSConvertF64, WASM_GET_LOCAL(0)));
...@@ -115,7 +115,7 @@ WASM_EXEC_TEST(I32AsmjsSConvertF64) { ...@@ -115,7 +115,7 @@ WASM_EXEC_TEST(I32AsmjsSConvertF64) {
WASM_EXEC_TEST(I32AsmjsUConvertF32) { WASM_EXEC_TEST(I32AsmjsUConvertF32) {
TestingModule module(execution_mode); TestingModule module(execution_mode);
module.origin = kAsmJsOrigin; module.ChangeOriginToAsmjs();
WasmRunner<uint32_t> r(&module, MachineType::Float32()); WasmRunner<uint32_t> r(&module, MachineType::Float32());
BUILD(r, WASM_UNOP(kExprI32AsmjsUConvertF32, WASM_GET_LOCAL(0))); BUILD(r, WASM_UNOP(kExprI32AsmjsUConvertF32, WASM_GET_LOCAL(0)));
...@@ -127,7 +127,7 @@ WASM_EXEC_TEST(I32AsmjsUConvertF32) { ...@@ -127,7 +127,7 @@ WASM_EXEC_TEST(I32AsmjsUConvertF32) {
WASM_EXEC_TEST(I32AsmjsUConvertF64) { WASM_EXEC_TEST(I32AsmjsUConvertF64) {
TestingModule module(execution_mode); TestingModule module(execution_mode);
module.origin = kAsmJsOrigin; module.ChangeOriginToAsmjs();
WasmRunner<uint32_t> r(&module, MachineType::Float64()); WasmRunner<uint32_t> r(&module, MachineType::Float64());
BUILD(r, WASM_UNOP(kExprI32AsmjsUConvertF64, WASM_GET_LOCAL(0))); BUILD(r, WASM_UNOP(kExprI32AsmjsUConvertF64, WASM_GET_LOCAL(0)));
...@@ -139,7 +139,7 @@ WASM_EXEC_TEST(I32AsmjsUConvertF64) { ...@@ -139,7 +139,7 @@ WASM_EXEC_TEST(I32AsmjsUConvertF64) {
WASM_EXEC_TEST(LoadMemI32_oob_asm) { WASM_EXEC_TEST(LoadMemI32_oob_asm) {
TestingModule module(execution_mode); TestingModule module(execution_mode);
module.origin = kAsmJsOrigin; module.ChangeOriginToAsmjs();
int32_t* memory = module.AddMemoryElems<int32_t>(8); int32_t* memory = module.AddMemoryElems<int32_t>(8);
WasmRunner<int32_t> r(&module, MachineType::Uint32()); WasmRunner<int32_t> r(&module, MachineType::Uint32());
module.RandomizeMemory(1112); module.RandomizeMemory(1112);
...@@ -160,7 +160,7 @@ WASM_EXEC_TEST(LoadMemI32_oob_asm) { ...@@ -160,7 +160,7 @@ WASM_EXEC_TEST(LoadMemI32_oob_asm) {
WASM_EXEC_TEST(LoadMemF32_oob_asm) { WASM_EXEC_TEST(LoadMemF32_oob_asm) {
TestingModule module(execution_mode); TestingModule module(execution_mode);
module.origin = kAsmJsOrigin; module.ChangeOriginToAsmjs();
float* memory = module.AddMemoryElems<float>(8); float* memory = module.AddMemoryElems<float>(8);
WasmRunner<float> r(&module, MachineType::Uint32()); WasmRunner<float> r(&module, MachineType::Uint32());
module.RandomizeMemory(1112); module.RandomizeMemory(1112);
...@@ -181,7 +181,7 @@ WASM_EXEC_TEST(LoadMemF32_oob_asm) { ...@@ -181,7 +181,7 @@ WASM_EXEC_TEST(LoadMemF32_oob_asm) {
WASM_EXEC_TEST(LoadMemF64_oob_asm) { WASM_EXEC_TEST(LoadMemF64_oob_asm) {
TestingModule module(execution_mode); TestingModule module(execution_mode);
module.origin = kAsmJsOrigin; module.ChangeOriginToAsmjs();
double* memory = module.AddMemoryElems<double>(8); double* memory = module.AddMemoryElems<double>(8);
WasmRunner<double> r(&module, MachineType::Uint32()); WasmRunner<double> r(&module, MachineType::Uint32());
module.RandomizeMemory(1112); module.RandomizeMemory(1112);
...@@ -204,7 +204,7 @@ WASM_EXEC_TEST(LoadMemF64_oob_asm) { ...@@ -204,7 +204,7 @@ WASM_EXEC_TEST(LoadMemF64_oob_asm) {
WASM_EXEC_TEST(StoreMemI32_oob_asm) { WASM_EXEC_TEST(StoreMemI32_oob_asm) {
TestingModule module(execution_mode); TestingModule module(execution_mode);
module.origin = kAsmJsOrigin; module.ChangeOriginToAsmjs();
int32_t* memory = module.AddMemoryElems<int32_t>(8); int32_t* memory = module.AddMemoryElems<int32_t>(8);
WasmRunner<int32_t> r(&module, MachineType::Uint32(), MachineType::Uint32()); WasmRunner<int32_t> r(&module, MachineType::Uint32(), MachineType::Uint32());
module.RandomizeMemory(1112); module.RandomizeMemory(1112);
...@@ -240,7 +240,7 @@ WASM_EXEC_TEST(StoreMemI32_oob_asm) { ...@@ -240,7 +240,7 @@ WASM_EXEC_TEST(StoreMemI32_oob_asm) {
#define INT_LOAD_TEST(OP_TYPE) \ #define INT_LOAD_TEST(OP_TYPE) \
TEST(RunWasm_AsmCheckedRelocInfo##OP_TYPE) { \ TEST(RunWasm_AsmCheckedRelocInfo##OP_TYPE) { \
TestingModule module(kExecuteCompiled); \ TestingModule module(kExecuteCompiled); \
module.origin = kAsmJsOrigin; \ module.ChangeOriginToAsmjs(); \
WasmRunner<int32_t> r(&module, MachineType::Uint32()); \ WasmRunner<int32_t> r(&module, MachineType::Uint32()); \
BUILD(r, WASM_UNOP(OP_TYPE, WASM_GET_LOCAL(0))); \ BUILD(r, WASM_UNOP(OP_TYPE, WASM_GET_LOCAL(0))); \
CHECK_EQ(1u, GetMatchingRelocInfoCount(module.instance->function_code[0], \ CHECK_EQ(1u, GetMatchingRelocInfoCount(module.instance->function_code[0], \
...@@ -255,7 +255,7 @@ FOREACH_INT_CHECKED_LOAD_OP(INT_LOAD_TEST) ...@@ -255,7 +255,7 @@ FOREACH_INT_CHECKED_LOAD_OP(INT_LOAD_TEST)
#define INT_STORE_TEST(OP_TYPE) \ #define INT_STORE_TEST(OP_TYPE) \
TEST(RunWasm_AsmCheckedRelocInfo##OP_TYPE) { \ TEST(RunWasm_AsmCheckedRelocInfo##OP_TYPE) { \
TestingModule module(kExecuteCompiled); \ TestingModule module(kExecuteCompiled); \
module.origin = kAsmJsOrigin; \ module.ChangeOriginToAsmjs(); \
WasmRunner<int32_t> r(&module, MachineType::Uint32(), \ WasmRunner<int32_t> r(&module, MachineType::Uint32(), \
MachineType::Uint32()); \ MachineType::Uint32()); \
BUILD(r, WASM_BINOP(OP_TYPE, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); \ BUILD(r, WASM_BINOP(OP_TYPE, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); \
...@@ -270,7 +270,7 @@ FOREACH_INT_CHECKED_STORE_OP(INT_STORE_TEST) ...@@ -270,7 +270,7 @@ FOREACH_INT_CHECKED_STORE_OP(INT_STORE_TEST)
TEST(RunWasm_AsmCheckedLoadFloat32RelocInfo) { TEST(RunWasm_AsmCheckedLoadFloat32RelocInfo) {
TestingModule module(kExecuteCompiled); TestingModule module(kExecuteCompiled);
module.origin = kAsmJsOrigin; module.ChangeOriginToAsmjs();
WasmRunner<float> r(&module, MachineType::Uint32()); WasmRunner<float> r(&module, MachineType::Uint32());
BUILD(r, WASM_UNOP(kExprF32AsmjsLoadMem, WASM_GET_LOCAL(0))); BUILD(r, WASM_UNOP(kExprF32AsmjsLoadMem, WASM_GET_LOCAL(0)));
...@@ -283,7 +283,7 @@ TEST(RunWasm_AsmCheckedLoadFloat32RelocInfo) { ...@@ -283,7 +283,7 @@ TEST(RunWasm_AsmCheckedLoadFloat32RelocInfo) {
TEST(RunWasm_AsmCheckedStoreFloat32RelocInfo) { TEST(RunWasm_AsmCheckedStoreFloat32RelocInfo) {
TestingModule module(kExecuteCompiled); TestingModule module(kExecuteCompiled);
module.origin = kAsmJsOrigin; module.ChangeOriginToAsmjs();
WasmRunner<float> r(&module, MachineType::Uint32(), MachineType::Float32()); WasmRunner<float> r(&module, MachineType::Uint32(), MachineType::Float32());
BUILD(r, WASM_BINOP(kExprF32AsmjsStoreMem, WASM_GET_LOCAL(0), BUILD(r, WASM_BINOP(kExprF32AsmjsStoreMem, WASM_GET_LOCAL(0),
WASM_GET_LOCAL(1))); WASM_GET_LOCAL(1)));
...@@ -297,7 +297,7 @@ TEST(RunWasm_AsmCheckedStoreFloat32RelocInfo) { ...@@ -297,7 +297,7 @@ TEST(RunWasm_AsmCheckedStoreFloat32RelocInfo) {
TEST(RunWasm_AsmCheckedLoadFloat64RelocInfo) { TEST(RunWasm_AsmCheckedLoadFloat64RelocInfo) {
TestingModule module(kExecuteCompiled); TestingModule module(kExecuteCompiled);
module.origin = kAsmJsOrigin; module.ChangeOriginToAsmjs();
WasmRunner<double> r(&module, MachineType::Uint32()); WasmRunner<double> r(&module, MachineType::Uint32());
BUILD(r, WASM_UNOP(kExprF64AsmjsLoadMem, WASM_GET_LOCAL(0))); BUILD(r, WASM_UNOP(kExprF64AsmjsLoadMem, WASM_GET_LOCAL(0)));
...@@ -310,7 +310,7 @@ TEST(RunWasm_AsmCheckedLoadFloat64RelocInfo) { ...@@ -310,7 +310,7 @@ TEST(RunWasm_AsmCheckedLoadFloat64RelocInfo) {
TEST(RunWasm_AsmCheckedStoreFloat64RelocInfo) { TEST(RunWasm_AsmCheckedStoreFloat64RelocInfo) {
TestingModule module(kExecuteCompiled); TestingModule module(kExecuteCompiled);
module.origin = kAsmJsOrigin; module.ChangeOriginToAsmjs();
WasmRunner<double> r(&module, MachineType::Uint32(), MachineType::Float64()); WasmRunner<double> r(&module, MachineType::Uint32(), MachineType::Float64());
BUILD(r, WASM_BINOP(kExprF64AsmjsStoreMem, WASM_GET_LOCAL(0), BUILD(r, WASM_BINOP(kExprF64AsmjsStoreMem, WASM_GET_LOCAL(0),
WASM_GET_LOCAL(1))); WASM_GET_LOCAL(1)));
......
...@@ -315,8 +315,9 @@ class WasmSerializationTest { ...@@ -315,8 +315,9 @@ class WasmSerializationTest {
serialization_isolate, const_cast<WasmModule*>(decoding_result.val)); serialization_isolate, const_cast<WasmModule*>(decoding_result.val));
MaybeHandle<WasmCompiledModule> compiled_module = MaybeHandle<WasmCompiledModule> compiled_module =
decoding_result.val->CompileFunctions(serialization_isolate, decoding_result.val->CompileFunctions(
module_wrapper, &thrower); serialization_isolate, module_wrapper, &thrower,
ModuleWireBytes(buffer.begin(), buffer.end()));
CHECK(!compiled_module.is_null()); CHECK(!compiled_module.is_null());
Handle<JSObject> module_obj = WasmModuleObject::New( Handle<JSObject> module_obj = WasmModuleObject::New(
serialization_isolate, compiled_module.ToHandleChecked()); serialization_isolate, compiled_module.ToHandleChecked());
......
...@@ -72,21 +72,22 @@ const uint32_t kMaxGlobalsSize = 128; ...@@ -72,21 +72,22 @@ const uint32_t kMaxGlobalsSize = 128;
class TestingModule : public ModuleEnv { class TestingModule : public ModuleEnv {
public: public:
explicit TestingModule(WasmExecutionMode mode = kExecuteCompiled) explicit TestingModule(WasmExecutionMode mode = kExecuteCompiled)
: execution_mode_(mode), : ModuleEnv(&module_, &instance_),
execution_mode_(mode),
instance_(&module_), instance_(&module_),
isolate_(CcTest::InitIsolateOnce()), isolate_(CcTest::InitIsolateOnce()),
global_offset(0), global_offset(0),
interpreter_(mode == kExecuteInterpreted interpreter_(mode == kExecuteInterpreted
? new WasmInterpreter(&instance_, &allocator_) ? new WasmInterpreter(
ModuleBytesEnv(&module_, &instance_,
Vector<const byte>::empty()),
&allocator_)
: nullptr) { : nullptr) {
module = &module_;
instance = &instance_;
instance->module = &module_; instance->module = &module_;
instance->globals_start = global_data; instance->globals_start = global_data;
module_.globals_size = kMaxGlobalsSize; module_.globals_size = kMaxGlobalsSize;
instance->mem_start = nullptr; instance->mem_start = nullptr;
instance->mem_size = 0; instance->mem_size = 0;
origin = kWasmOrigin;
memset(global_data, 0, sizeof(global_data)); memset(global_data, 0, sizeof(global_data));
} }
...@@ -97,7 +98,7 @@ class TestingModule : public ModuleEnv { ...@@ -97,7 +98,7 @@ class TestingModule : public ModuleEnv {
if (interpreter_) delete interpreter_; if (interpreter_) delete interpreter_;
} }
void ChangeOriginToAsmjs() { origin = kAsmJsOrigin; } void ChangeOriginToAsmjs() { module_.origin = kAsmJsOrigin; }
byte* AddMemory(uint32_t size) { byte* AddMemory(uint32_t size) {
CHECK_NULL(instance->mem_start); CHECK_NULL(instance->mem_start);
...@@ -212,7 +213,7 @@ class TestingModule : public ModuleEnv { ...@@ -212,7 +213,7 @@ class TestingModule : public ModuleEnv {
Handle<Code> code = instance->function_code[index]; Handle<Code> code = instance->function_code[index];
WasmJs::InstallWasmMapsIfNeeded(isolate_, isolate_->native_context()); WasmJs::InstallWasmMapsIfNeeded(isolate_, isolate_->native_context());
Handle<Code> ret_code = Handle<Code> ret_code =
compiler::CompileJSToWasmWrapper(isolate_, this, code, index); compiler::CompileJSToWasmWrapper(isolate_, &module_, code, index);
Handle<JSFunction> ret = WasmExportedFunction::New( Handle<JSFunction> ret = WasmExportedFunction::New(
isolate_, instance_obj, name, ret_code, isolate_, instance_obj, name, ret_code,
static_cast<int>(this->module->functions[index].sig->parameter_count()), static_cast<int>(this->module->functions[index].sig->parameter_count()),
...@@ -481,7 +482,8 @@ class WasmFunctionCompiler : public HandleAndZoneScope, ...@@ -481,7 +482,8 @@ class WasmFunctionCompiler : public HandleAndZoneScope,
function_->func_index = 0; function_->func_index = 0;
function_->sig_index = 0; function_->sig_index = 0;
if (mode == kExecuteInterpreted) { if (mode == kExecuteInterpreted) {
interpreter_ = new WasmInterpreter(nullptr, zone()->allocator()); ModuleBytesEnv empty_env(nullptr, nullptr, Vector<const byte>::empty());
interpreter_ = new WasmInterpreter(empty_env, zone()->allocator());
int index = interpreter_->AddFunctionForTesting(function_); int index = interpreter_->AddFunctionForTesting(function_);
CHECK_EQ(0, index); CHECK_EQ(0, index);
} }
......
...@@ -46,9 +46,9 @@ const WasmModule* DecodeWasmModuleForTesting( ...@@ -46,9 +46,9 @@ const WasmModule* DecodeWasmModuleForTesting(
} }
const Handle<WasmInstanceObject> InstantiateModuleForTesting( const Handle<WasmInstanceObject> InstantiateModuleForTesting(
Isolate* isolate, ErrorThrower* thrower, const WasmModule* module) { Isolate* isolate, ErrorThrower* thrower, const WasmModule* module,
CHECK(module != nullptr); const ModuleWireBytes& wire_bytes) {
DCHECK_NOT_NULL(module);
if (module->import_table.size() > 0) { if (module->import_table.size() > 0) {
thrower->CompileError("Not supported: module has imports."); thrower->CompileError("Not supported: module has imports.");
} }
...@@ -59,8 +59,9 @@ const Handle<WasmInstanceObject> InstantiateModuleForTesting( ...@@ -59,8 +59,9 @@ const Handle<WasmInstanceObject> InstantiateModuleForTesting(
// again through the normal pipeline. // again through the normal pipeline.
// TODO(wasm): Use {module} instead of decoding the module bytes again. // TODO(wasm): Use {module} instead of decoding the module bytes again.
MaybeHandle<WasmModuleObject> module_object = CreateModuleObjectFromBytes( MaybeHandle<WasmModuleObject> module_object = CreateModuleObjectFromBytes(
isolate, module->module_start, module->module_end, thrower, isolate, wire_bytes.module_bytes.start(), wire_bytes.module_bytes.end(),
ModuleOrigin::kWasmOrigin, Handle<Script>::null(), nullptr, nullptr); thrower, ModuleOrigin::kWasmOrigin, Handle<Script>::null(), nullptr,
nullptr);
if (module_object.is_null()) { if (module_object.is_null()) {
thrower->CompileError("Module pre-validation failed."); thrower->CompileError("Module pre-validation failed.");
return Handle<WasmInstanceObject>::null(); return Handle<WasmInstanceObject>::null();
...@@ -85,7 +86,8 @@ const Handle<WasmInstanceObject> CompileInstantiateWasmModuleForTesting( ...@@ -85,7 +86,8 @@ const Handle<WasmInstanceObject> CompileInstantiateWasmModuleForTesting(
thrower->CompileError("Wasm module decoding failed"); thrower->CompileError("Wasm module decoding failed");
return Handle<WasmInstanceObject>::null(); return Handle<WasmInstanceObject>::null();
} }
return InstantiateModuleForTesting(isolate, thrower, module.get()); return InstantiateModuleForTesting(isolate, thrower, module.get(),
ModuleWireBytes(module_start, module_end));
} }
int32_t RunWasmModuleForTesting(Isolate* isolate, Handle<JSObject> instance, int32_t RunWasmModuleForTesting(Isolate* isolate, Handle<JSObject> instance,
...@@ -110,10 +112,11 @@ int32_t CompileAndRunWasmModule(Isolate* isolate, const byte* module_start, ...@@ -110,10 +112,11 @@ int32_t CompileAndRunWasmModule(Isolate* isolate, const byte* module_start,
} }
int32_t InterpretWasmModule(Isolate* isolate, ErrorThrower* thrower, int32_t InterpretWasmModule(Isolate* isolate, ErrorThrower* thrower,
const WasmModule* module, int function_index, const WasmModule* module,
WasmVal* args, bool* possible_nondeterminism) { const ModuleWireBytes& wire_bytes,
CHECK(module != nullptr); int function_index, WasmVal* args,
bool* possible_nondeterminism) {
DCHECK_NOT_NULL(module);
Zone zone(isolate->allocator(), ZONE_NAME); Zone zone(isolate->allocator(), ZONE_NAME);
v8::internal::HandleScope scope(isolate); v8::internal::HandleScope scope(isolate);
...@@ -136,7 +139,8 @@ int32_t InterpretWasmModule(Isolate* isolate, ErrorThrower* thrower, ...@@ -136,7 +139,8 @@ int32_t InterpretWasmModule(Isolate* isolate, ErrorThrower* thrower,
static_cast<byte*>(calloc(GetMinModuleMemSize(module), 1)); static_cast<byte*>(calloc(GetMinModuleMemSize(module), 1));
instance.globals_start = nullptr; instance.globals_start = nullptr;
WasmInterpreter interpreter(&instance, isolate->allocator()); ModuleBytesEnv env(module, &instance, wire_bytes);
WasmInterpreter interpreter(env, isolate->allocator());
WasmInterpreter::Thread* thread = interpreter.GetThread(0); WasmInterpreter::Thread* thread = interpreter.GetThread(0);
thread->Reset(); thread->Reset();
......
...@@ -26,7 +26,8 @@ const WasmModule* DecodeWasmModuleForTesting( ...@@ -26,7 +26,8 @@ const WasmModule* DecodeWasmModuleForTesting(
// Instantiates a module without any imports and exports. // Instantiates a module without any imports and exports.
const Handle<WasmInstanceObject> InstantiateModuleForTesting( const Handle<WasmInstanceObject> InstantiateModuleForTesting(
Isolate* isolate, ErrorThrower* thrower, const WasmModule* module); Isolate* isolate, ErrorThrower* thrower, const WasmModule* module,
const ModuleWireBytes& wire_bytes);
int32_t CallWasmFunctionForTesting(Isolate* isolate, Handle<JSObject> instance, int32_t CallWasmFunctionForTesting(Isolate* isolate, Handle<JSObject> instance,
ErrorThrower* thrower, const char* name, ErrorThrower* thrower, const char* name,
...@@ -42,8 +43,10 @@ int32_t CompileAndRunWasmModule(Isolate* isolate, const byte* module_start, ...@@ -42,8 +43,10 @@ int32_t CompileAndRunWasmModule(Isolate* isolate, const byte* module_start,
// {function_index}. The return type of the function has to be int32. The module // {function_index}. The return type of the function has to be int32. The module
// should not have any imports or exports // should not have any imports or exports
int32_t InterpretWasmModule(Isolate* isolate, ErrorThrower* thrower, int32_t InterpretWasmModule(Isolate* isolate, ErrorThrower* thrower,
const WasmModule* module, int function_index, const WasmModule* module,
WasmVal* args, bool* may_produced_nan); const ModuleWireBytes& wire_bytes,
int function_index, WasmVal* args,
bool* may_produced_nan);
// Compiles WasmModule bytes and return an instance of the compiled module. // Compiles WasmModule bytes and return an instance of the compiled module.
const Handle<WasmInstanceObject> CompileInstantiateWasmModuleForTesting( const Handle<WasmInstanceObject> CompileInstantiateWasmModuleForTesting(
......
...@@ -141,18 +141,19 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { ...@@ -141,18 +141,19 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
if (module == nullptr) { if (module == nullptr) {
return 0; return 0;
} }
ModuleWireBytes wire_bytes(buffer.begin(), buffer.end());
int32_t result_interpreted; int32_t result_interpreted;
bool possible_nondeterminism = false; bool possible_nondeterminism = false;
{ {
result_interpreted = testing::InterpretWasmModule( result_interpreted = testing::InterpretWasmModule(
i_isolate, &interpreter_thrower, module.get(), 0, interpreter_args, i_isolate, &interpreter_thrower, module.get(), wire_bytes, 0,
&possible_nondeterminism); interpreter_args, &possible_nondeterminism);
} }
ErrorThrower compiler_thrower(i_isolate, "Compiler"); ErrorThrower compiler_thrower(i_isolate, "Compiler");
v8::internal::Handle<v8::internal::JSObject> instance = v8::internal::Handle<v8::internal::JSObject> instance =
testing::InstantiateModuleForTesting(i_isolate, &compiler_thrower, testing::InstantiateModuleForTesting(i_isolate, &compiler_thrower,
module.get()); module.get(), wire_bytes);
if (!interpreter_thrower.error()) { if (!interpreter_thrower.error()) {
CHECK(!instance.is_null()); CHECK(!instance.is_null());
......
...@@ -104,19 +104,20 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { ...@@ -104,19 +104,20 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
os << "})();" << std::endl; os << "})();" << std::endl;
} }
ModuleWireBytes wire_bytes(buffer.begin(), buffer.end());
int32_t result_interpreted; int32_t result_interpreted;
bool possible_nondeterminism = false; bool possible_nondeterminism = false;
{ {
WasmVal args[] = {WasmVal(1), WasmVal(2), WasmVal(3)}; WasmVal args[] = {WasmVal(1), WasmVal(2), WasmVal(3)};
result_interpreted = testing::InterpretWasmModule( result_interpreted = testing::InterpretWasmModule(
i_isolate, &interpreter_thrower, module.get(), 0, args, i_isolate, &interpreter_thrower, module.get(), wire_bytes, 0, args,
&possible_nondeterminism); &possible_nondeterminism);
} }
ErrorThrower compiler_thrower(i_isolate, "Compiler"); ErrorThrower compiler_thrower(i_isolate, "Compiler");
v8::internal::Handle<v8::internal::JSObject> instance = v8::internal::Handle<v8::internal::JSObject> instance =
testing::InstantiateModuleForTesting(i_isolate, &compiler_thrower, testing::InstantiateModuleForTesting(i_isolate, &compiler_thrower,
module.get()); module.get(), wire_bytes);
// Restore the flag. // Restore the flag.
v8::internal::FLAG_wasm_code_fuzzer_gen_test = generate_test; v8::internal::FLAG_wasm_code_fuzzer_gen_test = generate_test;
if (!interpreter_thrower.error()) { if (!interpreter_thrower.error()) {
......
...@@ -1279,9 +1279,9 @@ namespace { ...@@ -1279,9 +1279,9 @@ namespace {
// globals. // globals.
class TestModuleEnv : public ModuleEnv { class TestModuleEnv : public ModuleEnv {
public: public:
TestModuleEnv() { explicit TestModuleEnv(ModuleOrigin origin = kWasmOrigin)
instance = nullptr; : ModuleEnv(&mod, nullptr) {
module = &mod; mod.origin = origin;
} }
byte AddGlobal(LocalType type, bool mutability = true) { byte AddGlobal(LocalType type, bool mutability = true) {
mod.globals.push_back({type, mutability, WasmInitExpr(), 0, false, false}); mod.globals.push_back({type, mutability, WasmInitExpr(), 0, false, false});
...@@ -1654,7 +1654,6 @@ TEST_F(AstDecoderTest, AllSetGlobalCombinations) { ...@@ -1654,7 +1654,6 @@ TEST_F(AstDecoderTest, AllSetGlobalCombinations) {
TEST_F(AstDecoderTest, WasmGrowMemory) { TEST_F(AstDecoderTest, WasmGrowMemory) {
TestModuleEnv module_env; TestModuleEnv module_env;
module = &module_env; module = &module_env;
module->origin = kWasmOrigin;
byte code[] = {WASM_GET_LOCAL(0), kExprGrowMemory, 0}; byte code[] = {WASM_GET_LOCAL(0), kExprGrowMemory, 0};
EXPECT_VERIFIES_C(i_i, code); EXPECT_VERIFIES_C(i_i, code);
...@@ -1662,9 +1661,8 @@ TEST_F(AstDecoderTest, WasmGrowMemory) { ...@@ -1662,9 +1661,8 @@ TEST_F(AstDecoderTest, WasmGrowMemory) {
} }
TEST_F(AstDecoderTest, AsmJsGrowMemory) { TEST_F(AstDecoderTest, AsmJsGrowMemory) {
TestModuleEnv module_env; TestModuleEnv module_env(kAsmJsOrigin);
module = &module_env; module = &module_env;
module->origin = kAsmJsOrigin;
byte code[] = {WASM_GET_LOCAL(0), kExprGrowMemory, 0}; byte code[] = {WASM_GET_LOCAL(0), kExprGrowMemory, 0};
EXPECT_FAILURE_C(i_i, code); EXPECT_FAILURE_C(i_i, code);
...@@ -1694,9 +1692,8 @@ TEST_F(AstDecoderTest, AsmJsBinOpsCheckOrigin) { ...@@ -1694,9 +1692,8 @@ TEST_F(AstDecoderTest, AsmJsBinOpsCheckOrigin) {
}; };
{ {
TestModuleEnv module_env; TestModuleEnv module_env(kAsmJsOrigin);
module = &module_env; module = &module_env;
module->origin = kAsmJsOrigin;
for (size_t i = 0; i < arraysize(AsmJsBinOps); i++) { for (size_t i = 0; i < arraysize(AsmJsBinOps); i++) {
TestBinop(AsmJsBinOps[i].op, AsmJsBinOps[i].sig); TestBinop(AsmJsBinOps[i].op, AsmJsBinOps[i].sig);
} }
...@@ -1705,7 +1702,6 @@ TEST_F(AstDecoderTest, AsmJsBinOpsCheckOrigin) { ...@@ -1705,7 +1702,6 @@ TEST_F(AstDecoderTest, AsmJsBinOpsCheckOrigin) {
{ {
TestModuleEnv module_env; TestModuleEnv module_env;
module = &module_env; module = &module_env;
module->origin = kWasmOrigin;
for (size_t i = 0; i < arraysize(AsmJsBinOps); i++) { for (size_t i = 0; i < arraysize(AsmJsBinOps); i++) {
byte code[] = { byte code[] = {
WASM_BINOP(AsmJsBinOps[i].op, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))}; WASM_BINOP(AsmJsBinOps[i].op, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))};
...@@ -1742,9 +1738,8 @@ TEST_F(AstDecoderTest, AsmJsUnOpsCheckOrigin) { ...@@ -1742,9 +1738,8 @@ TEST_F(AstDecoderTest, AsmJsUnOpsCheckOrigin) {
{kExprI32AsmjsSConvertF64, sigs.i_d()}, {kExprI32AsmjsSConvertF64, sigs.i_d()},
{kExprI32AsmjsUConvertF64, sigs.i_d()}}; {kExprI32AsmjsUConvertF64, sigs.i_d()}};
{ {
TestModuleEnv module_env; TestModuleEnv module_env(kAsmJsOrigin);
module = &module_env; module = &module_env;
module->origin = kAsmJsOrigin;
for (size_t i = 0; i < arraysize(AsmJsUnOps); i++) { for (size_t i = 0; i < arraysize(AsmJsUnOps); i++) {
TestUnop(AsmJsUnOps[i].op, AsmJsUnOps[i].sig); TestUnop(AsmJsUnOps[i].op, AsmJsUnOps[i].sig);
} }
...@@ -1753,7 +1748,6 @@ TEST_F(AstDecoderTest, AsmJsUnOpsCheckOrigin) { ...@@ -1753,7 +1748,6 @@ TEST_F(AstDecoderTest, AsmJsUnOpsCheckOrigin) {
{ {
TestModuleEnv module_env; TestModuleEnv module_env;
module = &module_env; module = &module_env;
module->origin = kWasmOrigin;
for (size_t i = 0; i < arraysize(AsmJsUnOps); i++) { for (size_t i = 0; i < arraysize(AsmJsUnOps); i++) {
byte code[] = {WASM_UNOP(AsmJsUnOps[i].op, WASM_GET_LOCAL(0))}; byte code[] = {WASM_UNOP(AsmJsUnOps[i].op, WASM_GET_LOCAL(0))};
EXPECT_FAILURE_SC(AsmJsUnOps[i].sig, code); EXPECT_FAILURE_SC(AsmJsUnOps[i].sig, code);
......
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