Commit 1e1f72f3 authored by titzer's avatar titzer Committed by Commit bot

[wasm] Factor out WasmModuleInstance from ModuleEnv.

R=ahaas@chromium.org,bradnelson@chromium.org
BUG=

Review URL: https://codereview.chromium.org/1637923002

Cr-Commit-Position: refs/heads/master@{#33541}
parent 49fda47c
......@@ -197,7 +197,7 @@ class WasmTrapHelper : public ZoneObject {
*effect_ptr = effects_[reason] =
graph()->NewNode(common()->EffectPhi(1), *effect_ptr, *control_ptr);
if (module && !module->context.is_null()) {
if (module && !module->instance->context.is_null()) {
// Use the module context to call the runtime to throw an exception.
Runtime::FunctionId f = Runtime::kThrow;
const Runtime::Function* fun = Runtime::FunctionForId(f);
......@@ -210,7 +210,7 @@ class WasmTrapHelper : public ZoneObject {
jsgraph()->ExternalConstant(
ExternalReference(f, jsgraph()->isolate())), // ref
jsgraph()->Int32Constant(fun->nargs), // arity
jsgraph()->Constant(module->context), // context
jsgraph()->Constant(module->instance->context), // context
*effect_ptr,
*control_ptr};
......@@ -1701,18 +1701,23 @@ void WasmGraphBuilder::BuildWasmToJSWrapper(Handle<JSFunction> function,
Node* WasmGraphBuilder::MemBuffer(uint32_t offset) {
DCHECK(module_ && module_->instance);
if (offset == 0) {
if (!mem_buffer_)
mem_buffer_ = jsgraph()->IntPtrConstant(module_->mem_start);
if (!mem_buffer_) {
mem_buffer_ = jsgraph()->IntPtrConstant(
reinterpret_cast<uintptr_t>(module_->instance->mem_start));
}
return mem_buffer_;
} else {
return jsgraph()->IntPtrConstant(module_->mem_start + offset);
return jsgraph()->IntPtrConstant(
reinterpret_cast<uintptr_t>(module_->instance->mem_start + offset));
}
}
Node* WasmGraphBuilder::MemSize(uint32_t offset) {
int32_t size = static_cast<int>(module_->mem_end - module_->mem_start);
DCHECK(module_ && module_->instance);
uint32_t size = static_cast<uint32_t>(module_->instance->mem_size);
if (offset == 0) {
if (!mem_size_) mem_size_ = jsgraph()->Int32Constant(size);
return mem_size_;
......@@ -1723,18 +1728,21 @@ Node* WasmGraphBuilder::MemSize(uint32_t offset) {
Node* WasmGraphBuilder::FunctionTable() {
DCHECK(module_ && module_->instance &&
!module_->instance->function_table.is_null());
if (!function_table_) {
DCHECK(!module_->function_table.is_null());
function_table_ = jsgraph()->Constant(module_->function_table);
function_table_ = jsgraph()->Constant(module_->instance->function_table);
}
return function_table_;
}
Node* WasmGraphBuilder::LoadGlobal(uint32_t index) {
DCHECK(module_ && module_->instance && module_->instance->globals_start);
MachineType mem_type = module_->GetGlobalType(index);
Node* addr = jsgraph()->IntPtrConstant(
module_->globals_area + module_->module->globals->at(index).offset);
reinterpret_cast<uintptr_t>(module_->instance->globals_start +
module_->module->globals->at(index).offset));
const Operator* op = jsgraph()->machine()->Load(mem_type);
Node* node = graph()->NewNode(op, addr, jsgraph()->Int32Constant(0), *effect_,
*control_);
......@@ -1744,9 +1752,11 @@ Node* WasmGraphBuilder::LoadGlobal(uint32_t index) {
Node* WasmGraphBuilder::StoreGlobal(uint32_t index, Node* val) {
DCHECK(module_ && module_->instance && module_->instance->globals_start);
MachineType mem_type = module_->GetGlobalType(index);
Node* addr = jsgraph()->IntPtrConstant(
module_->globals_area + module_->module->globals->at(index).offset);
reinterpret_cast<uintptr_t>(module_->instance->globals_start +
module_->module->globals->at(index).offset));
const Operator* op = jsgraph()->machine()->Store(
StoreRepresentation(mem_type.representation(), kNoWriteBarrier));
Node* node = graph()->NewNode(op, addr, jsgraph()->Int32Constant(0), val,
......@@ -1759,12 +1769,11 @@ Node* WasmGraphBuilder::StoreGlobal(uint32_t index, Node* val) {
void WasmGraphBuilder::BoundsCheckMem(MachineType memtype, Node* index,
uint32_t offset) {
// TODO(turbofan): fold bounds checks for constant indexes.
CHECK_GE(module_->mem_end, module_->mem_start);
ptrdiff_t size = module_->mem_end - module_->mem_start;
DCHECK(module_ && module_->instance);
size_t size = module_->instance->mem_size;
byte memsize = wasm::WasmOpcodes::MemSize(memtype);
Node* cond;
if (static_cast<ptrdiff_t>(offset) >= size ||
static_cast<ptrdiff_t>(offset + memsize) > size) {
if (offset >= size || (static_cast<uint64_t>(offset) + memsize) > size) {
// The access will always throw.
cond = jsgraph()->Int32Constant(0);
} else {
......
......@@ -102,10 +102,7 @@ class ModuleDecoder : public Decoder {
// Set up module environment for verification.
ModuleEnv menv;
menv.module = module;
menv.globals_area = 0;
menv.mem_start = 0;
menv.mem_end = 0;
menv.function_code = nullptr;
menv.instance = nullptr;
menv.asm_js = asm_js_;
// Decode functions.
for (uint32_t i = 0; i < functions_count; i++) {
......
This diff is collapsed.
......@@ -121,22 +121,41 @@ struct WasmModule {
Handle<JSArrayBuffer> memory);
};
// An instantiated WASM module, including memory, function table, etc.
struct WasmModuleInstance {
WasmModule* module; // static representation of the module.
// -- Heap allocated --------------------------------------------------------
Handle<JSObject> js_object; // JavaScript module object.
Handle<Context> context; // JavaScript native context.
Handle<JSArrayBuffer> mem_buffer; // Handle to array buffer of memory.
Handle<JSArrayBuffer> globals_buffer; // Handle to array buffer of globals.
Handle<FixedArray> function_table; // indirect function table.
std::vector<Handle<Code>>* function_code; // code objects for each function.
// -- raw memory ------------------------------------------------------------
byte* mem_start; // start of linear memory.
size_t mem_size; // size of the linear memory.
// -- raw globals -----------------------------------------------------------
byte* globals_start; // start of the globals area.
size_t globals_size; // size of the globals area.
explicit WasmModuleInstance(WasmModule* m)
: module(m),
function_code(nullptr),
mem_start(nullptr),
mem_size(0),
globals_start(nullptr),
globals_size(0) {}
};
// forward declaration.
class WasmLinker;
// Interface provided to the decoder/graph builder which contains only
// minimal information about the globals, functions, and function tables.
struct ModuleEnv {
uintptr_t globals_area; // address of the globals area.
uintptr_t mem_start; // address of the start of linear memory.
uintptr_t mem_end; // address of the end of linear memory.
WasmModule* module;
WasmModuleInstance* instance;
WasmLinker* linker;
std::vector<Handle<Code>>* function_code;
Handle<FixedArray> function_table;
Handle<JSArrayBuffer> memory;
Handle<Context> context;
bool asm_js; // true if the module originated from asm.js.
bool IsValidGlobal(uint32_t index) {
......
......@@ -56,7 +56,7 @@ uint32_t AddJsFunction(TestingModule* module, FunctionSig* sig,
uint32_t index = static_cast<uint32_t>(module->module->functions->size() - 1);
Isolate* isolate = CcTest::InitIsolateOnce();
Handle<Code> code = CompileWasmToJSWrapper(isolate, module, jsfunc, index);
module->function_code->at(index) = code;
module->instance->function_code->at(index) = code;
return index;
}
......@@ -84,7 +84,7 @@ Handle<JSFunction> WrapCode(ModuleEnv* module, uint32_t index) {
// Wrap the code so it can be called as a JS function.
Handle<String> name = isolate->factory()->NewStringFromStaticChars("main");
Handle<JSObject> module_object = Handle<JSObject>(0, isolate);
Handle<Code> code = module->function_code->at(index);
Handle<Code> code = module->instance->function_code->at(index);
WasmJs::InstallWasmFunctionMap(isolate, isolate->native_context());
return compiler::CompileJSToWasmWrapper(isolate, module, name, code,
module_object, index);
......
......@@ -60,37 +60,37 @@ inline void init_env(FunctionEnv* env, FunctionSig* sig) {
const uint32_t kMaxGlobalsSize = 128;
// A helper for module environments that adds the ability to allocate memory
// and global variables.
// and global variables. Contains a built-in {WasmModuleInstance}.
class TestingModule : public ModuleEnv {
public:
TestingModule() : mem_size(0), global_offset(0) {
globals_area = 0;
mem_start = 0;
mem_end = 0;
TestingModule() : instance_(nullptr), global_offset(0) {
instance = &instance_;
instance->globals_start = global_data;
instance->globals_size = kMaxGlobalsSize;
instance->mem_start = nullptr;
instance->mem_size = 0;
instance->function_code = nullptr;
module = nullptr;
linker = nullptr;
function_code = nullptr;
asm_js = false;
memset(global_data, 0, sizeof(global_data));
}
~TestingModule() {
if (mem_start) {
free(raw_mem_start<byte>());
if (instance->mem_start) {
free(instance->mem_start);
}
if (function_code) delete function_code;
if (instance->function_code) delete instance->function_code;
if (module) delete module;
}
byte* AddMemory(size_t size) {
CHECK_EQ(0, mem_start);
CHECK_EQ(0, mem_size);
mem_start = reinterpret_cast<uintptr_t>(malloc(size));
CHECK(mem_start);
byte* raw = raw_mem_start<byte>();
memset(raw, 0, size);
mem_end = mem_start + size;
mem_size = size;
CHECK_NULL(instance->mem_start);
CHECK_EQ(0, instance->mem_size);
instance->mem_start = reinterpret_cast<byte*>(malloc(size));
CHECK(instance->mem_start);
memset(instance->mem_start, 0, size);
instance->mem_size = size;
return raw_mem_start<byte>();
}
......@@ -103,7 +103,7 @@ class TestingModule : public ModuleEnv {
template <typename T>
T* AddGlobal(MachineType mem_type) {
WasmGlobal* global = AddGlobal(mem_type);
return reinterpret_cast<T*>(globals_area + global->offset);
return reinterpret_cast<T*>(instance->globals_start + global->offset);
}
byte AddSignature(FunctionSig* sig) {
......@@ -119,33 +119,33 @@ class TestingModule : public ModuleEnv {
template <typename T>
T* raw_mem_start() {
DCHECK(mem_start);
return reinterpret_cast<T*>(mem_start);
DCHECK(instance->mem_start);
return reinterpret_cast<T*>(instance->mem_start);
}
template <typename T>
T* raw_mem_end() {
DCHECK(mem_end);
return reinterpret_cast<T*>(mem_end);
DCHECK(instance->mem_start);
return reinterpret_cast<T*>(instance->mem_start + instance->mem_size);
}
template <typename T>
T raw_mem_at(int i) {
DCHECK(mem_start);
return reinterpret_cast<T*>(mem_start)[i];
DCHECK(instance->mem_start);
return reinterpret_cast<T*>(instance->mem_start)[i];
}
template <typename T>
T raw_val_at(int i) {
T val;
memcpy(&val, reinterpret_cast<void*>(mem_start + i), sizeof(T));
memcpy(&val, reinterpret_cast<void*>(instance->mem_start + i), sizeof(T));
return val;
}
// Zero-initialize the memory.
void BlankMemory() {
byte* raw = raw_mem_start<byte>();
memset(raw, 0, mem_size);
memset(raw, 0, instance->mem_size);
}
// Pseudo-randomly intialize the memory.
......@@ -161,10 +161,10 @@ class TestingModule : public ModuleEnv {
AllocModule();
if (module->functions == nullptr) {
module->functions = new std::vector<WasmFunction>();
function_code = new std::vector<Handle<Code>>();
instance->function_code = new std::vector<Handle<Code>>();
}
module->functions->push_back({sig, 0, 0, 0, 0, 0, 0, 0, false, false});
function_code->push_back(code);
instance->function_code->push_back(code);
return &module->functions->back();
}
......@@ -173,7 +173,7 @@ class TestingModule : public ModuleEnv {
Isolate* isolate = module->shared_isolate;
Handle<FixedArray> fixed =
isolate->factory()->NewFixedArray(2 * table_size);
function_table = fixed;
instance->function_table = fixed;
module->function_table = new std::vector<uint16_t>();
for (int i = 0; i < table_size; i++) {
module->function_table->push_back(functions[i]);
......@@ -181,26 +181,26 @@ class TestingModule : public ModuleEnv {
}
void PopulateIndirectFunctionTable() {
if (function_table.is_null()) return;
if (instance->function_table.is_null()) return;
int table_size = static_cast<int>(module->function_table->size());
for (int i = 0; i < table_size; i++) {
int function_index = module->function_table->at(i);
WasmFunction* function = &module->functions->at(function_index);
function_table->set(i, Smi::FromInt(function->sig_index));
function_table->set(i + table_size, *function_code->at(function_index));
instance->function_table->set(i, Smi::FromInt(function->sig_index));
instance->function_table->set(
i + table_size, *instance->function_code->at(function_index));
}
}
private:
size_t mem_size;
WasmModuleInstance instance_;
uint32_t global_offset;
byte global_data[kMaxGlobalsSize];
byte global_data[kMaxGlobalsSize]; // preallocated global data.
WasmGlobal* AddGlobal(MachineType mem_type) {
AllocModule();
if (globals_area == 0) {
globals_area = reinterpret_cast<uintptr_t>(global_data);
if (!module->globals) {
module->globals = new std::vector<WasmGlobal>();
}
byte size = WasmOpcodes::MemSize(mem_type);
......
......@@ -1204,11 +1204,9 @@ namespace {
class TestModuleEnv : public ModuleEnv {
public:
TestModuleEnv() {
mem_start = 0;
mem_end = 0;
instance = nullptr;
module = &mod;
linker = nullptr;
function_code = nullptr;
mod.globals = new std::vector<WasmGlobal>;
mod.signatures = new std::vector<FunctionSig*>;
mod.functions = new std::vector<WasmFunction>;
......
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