[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}
This commit is contained in:
titzer 2016-01-27 03:04:02 -08:00 committed by Commit bot
parent 49fda47c5f
commit 1e1f72f3a6
7 changed files with 202 additions and 152 deletions

View File

@ -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 {

View File

@ -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++) {

View File

@ -183,25 +183,81 @@ Handle<FixedArray> BuildFunctionTable(Isolate* isolate, WasmModule* module) {
return fixed;
}
Handle<JSArrayBuffer> NewArrayBuffer(Isolate* isolate, int size,
Handle<JSArrayBuffer> NewArrayBuffer(Isolate* isolate, size_t size,
byte** backing_store) {
void* memory = isolate->array_buffer_allocator()->Allocate(size);
if (!memory) return Handle<JSArrayBuffer>::null();
if (size > (1 << WasmModule::kMaxMemSize)) {
// TODO(titzer): lift restriction on maximum memory allocated here.
*backing_store = nullptr;
return Handle<JSArrayBuffer>::null();
}
void* memory =
isolate->array_buffer_allocator()->Allocate(static_cast<int>(size));
if (!memory) {
*backing_store = nullptr;
return Handle<JSArrayBuffer>::null();
}
*backing_store = reinterpret_cast<byte*>(memory);
#if DEBUG
// Double check the API allocator actually zero-initialized the memory.
for (int i = 0; i < size; i++) {
DCHECK_EQ(0, (*backing_store)[i]);
byte* bytes = reinterpret_cast<byte*>(*backing_store);
for (size_t i = 0; i < size; i++) {
DCHECK_EQ(0, bytes[i]);
}
#endif
Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer();
JSArrayBuffer::Setup(buffer, isolate, false, memory, size);
JSArrayBuffer::Setup(buffer, isolate, false, memory, static_cast<int>(size));
buffer->set_is_neuterable(false);
return buffer;
}
// Set the memory for a module instance to be the {memory} array buffer.
void SetMemory(WasmModuleInstance* instance, Handle<JSArrayBuffer> memory) {
memory->set_is_neuterable(false);
instance->mem_start = reinterpret_cast<byte*>(memory->backing_store());
instance->mem_size = memory->byte_length()->Number();
instance->mem_buffer = memory;
}
// Allocate memory for a module instance as a new JSArrayBuffer.
bool AllocateMemory(ErrorThrower* thrower, Isolate* isolate,
WasmModuleInstance* instance) {
DCHECK(instance->module);
DCHECK(instance->mem_buffer.is_null());
if (instance->module->min_mem_size_log2 > WasmModule::kMaxMemSize) {
thrower->Error("Out of memory: wasm memory too large");
return false;
}
instance->mem_size = static_cast<size_t>(1)
<< instance->module->min_mem_size_log2;
instance->mem_buffer =
NewArrayBuffer(isolate, instance->mem_size, &instance->mem_start);
if (!instance->mem_start) {
thrower->Error("Out of memory: wasm memory");
instance->mem_size = 0;
return false;
}
return true;
}
bool AllocateGlobals(ErrorThrower* thrower, Isolate* isolate,
WasmModuleInstance* instance) {
instance->globals_size = AllocateGlobalsOffsets(instance->module->globals);
if (instance->globals_size > 0) {
instance->globals_buffer = NewArrayBuffer(isolate, instance->globals_size,
&instance->globals_start);
if (!instance->globals_start) {
// Not enough space for backing store of globals.
thrower->Error("Out of memory: wasm globals");
return false;
}
}
return true;
}
} // namespace
@ -232,90 +288,63 @@ MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate,
Handle<JSArrayBuffer> memory) {
this->shared_isolate = isolate; // TODO(titzer): have a real shared isolate.
ErrorThrower thrower(isolate, "WasmModule::Instantiate()");
Factory* factory = isolate->factory();
// Memory is bigger than maximum supported size.
if (memory.is_null() && min_mem_size_log2 > kMaxMemSize) {
thrower.Error("Out of memory: wasm memory too large");
return MaybeHandle<JSObject>();
}
//-------------------------------------------------------------------------
// Allocate the instance and its JS counterpart.
//-------------------------------------------------------------------------
Handle<Map> map = factory->NewMap(
JS_OBJECT_TYPE,
JSObject::kHeaderSize + kWasmModuleInternalFieldCount * kPointerSize);
//-------------------------------------------------------------------------
// Allocate the module object.
//-------------------------------------------------------------------------
Handle<JSObject> module = factory->NewJSObjectFromMap(map, TENURED);
WasmModuleInstance instance(this);
instance.context = isolate->native_context();
instance.js_object = factory->NewJSObjectFromMap(map, TENURED);
Handle<FixedArray> code_table =
factory->NewFixedArray(static_cast<int>(functions->size()), TENURED);
instance.js_object->SetInternalField(kWasmModuleCodeTable, *code_table);
//-------------------------------------------------------------------------
// Allocate the linear memory.
// Allocate and initialize the linear memory.
//-------------------------------------------------------------------------
uint32_t mem_size = 1 << min_mem_size_log2;
byte* mem_addr = nullptr;
Handle<JSArrayBuffer> mem_buffer;
if (!memory.is_null()) {
memory->set_is_neuterable(false);
mem_addr = reinterpret_cast<byte*>(memory->backing_store());
mem_size = memory->byte_length()->Number();
mem_buffer = memory;
} else {
mem_buffer = NewArrayBuffer(isolate, mem_size, &mem_addr);
if (!mem_addr) {
// Not enough space for backing store of memory
thrower.Error("Out of memory: wasm memory");
if (memory.is_null()) {
if (!AllocateMemory(&thrower, isolate, &instance)) {
return MaybeHandle<JSObject>();
}
} else {
SetMemory(&instance, memory);
}
// Load initialized data segments.
LoadDataSegments(this, mem_addr, mem_size);
module->SetInternalField(kWasmMemArrayBuffer, *mem_buffer);
instance.js_object->SetInternalField(kWasmMemArrayBuffer,
*instance.mem_buffer);
LoadDataSegments(this, instance.mem_start, instance.mem_size);
if (mem_export) {
// Export the memory as a named property.
Handle<String> name = factory->InternalizeUtf8String("memory");
JSObject::AddProperty(module, name, mem_buffer, READ_ONLY);
JSObject::AddProperty(instance.js_object, name, instance.mem_buffer,
READ_ONLY);
}
//-------------------------------------------------------------------------
// Allocate the globals area if necessary.
//-------------------------------------------------------------------------
size_t globals_size = AllocateGlobalsOffsets(globals);
byte* globals_addr = nullptr;
if (globals_size > 0) {
Handle<JSArrayBuffer> globals_buffer =
NewArrayBuffer(isolate, mem_size, &globals_addr);
if (!globals_addr) {
// Not enough space for backing store of globals.
thrower.Error("Out of memory: wasm globals");
return MaybeHandle<JSObject>();
}
module->SetInternalField(kWasmGlobalsArrayBuffer, *globals_buffer);
} else {
module->SetInternalField(kWasmGlobalsArrayBuffer, Smi::FromInt(0));
if (!AllocateGlobals(&thrower, isolate, &instance)) {
return MaybeHandle<JSObject>();
}
if (!instance.globals_buffer.is_null()) {
instance.js_object->SetInternalField(kWasmGlobalsArrayBuffer,
*instance.globals_buffer);
}
//-------------------------------------------------------------------------
// Compile all functions in the module.
//-------------------------------------------------------------------------
instance.function_table = BuildFunctionTable(isolate, this);
int index = 0;
WasmLinker linker(isolate, functions->size());
ModuleEnv module_env;
module_env.module = this;
module_env.mem_start = reinterpret_cast<uintptr_t>(mem_addr);
module_env.mem_end = reinterpret_cast<uintptr_t>(mem_addr) + mem_size;
module_env.globals_area = reinterpret_cast<uintptr_t>(globals_addr);
module_env.instance = &instance;
module_env.linker = &linker;
module_env.function_code = nullptr;
module_env.function_table = BuildFunctionTable(isolate, this);
module_env.memory = memory;
module_env.context = isolate->native_context();
module_env.asm_js = false;
// First pass: compile each function and initialize the code table.
@ -358,8 +387,8 @@ MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate,
return MaybeHandle<JSObject>();
}
if (func.exported) {
function = compiler::CompileJSToWasmWrapper(isolate, &module_env, name,
code, module, index);
function = compiler::CompileJSToWasmWrapper(
isolate, &module_env, name, code, instance.js_object, index);
}
}
if (!code.is_null()) {
@ -369,24 +398,25 @@ MaybeHandle<JSObject> WasmModule::Instantiate(Isolate* isolate,
}
if (func.exported) {
// Exported functions are installed as read-only properties on the module.
JSObject::AddProperty(module, name, function, READ_ONLY);
JSObject::AddProperty(instance.js_object, name, function, READ_ONLY);
}
index++;
}
// Second pass: patch all direct call sites.
linker.Link(module_env.function_table, this->function_table);
module->SetInternalField(kWasmModuleFunctionTable, Smi::FromInt(0));
module->SetInternalField(kWasmModuleCodeTable, *code_table);
return module;
linker.Link(instance.function_table, this->function_table);
instance.js_object->SetInternalField(kWasmModuleFunctionTable,
Smi::FromInt(0));
return instance.js_object;
}
Handle<Code> ModuleEnv::GetFunctionCode(uint32_t index) {
DCHECK(IsValidFunction(index));
if (linker) return linker->GetFunctionCode(index);
if (function_code) return function_code->at(index);
if (instance && instance->function_code) {
return instance->function_code->at(index);
}
return Handle<Code>::null();
}
@ -426,33 +456,30 @@ int32_t CompileAndRunWasmModule(Isolate* isolate, const byte* module_start,
int32_t CompileAndRunWasmModule(Isolate* isolate, WasmModule* module) {
ErrorThrower thrower(isolate, "CompileAndRunWasmModule");
WasmModuleInstance instance(module);
// Allocate temporary linear memory and globals.
size_t mem_size = 1 << module->min_mem_size_log2;
size_t globals_size = AllocateGlobalsOffsets(module->globals);
// Allocate and initialize the linear memory.
if (!AllocateMemory(&thrower, isolate, &instance)) {
return -1;
}
LoadDataSegments(module, instance.mem_start, instance.mem_size);
base::SmartArrayPointer<byte> mem_addr(new byte[mem_size]);
base::SmartArrayPointer<byte> globals_addr(new byte[globals_size]);
// Allocate the globals area if necessary.
if (!AllocateGlobals(&thrower, isolate, &instance)) {
return -1;
}
memset(mem_addr.get(), 0, mem_size);
memset(globals_addr.get(), 0, globals_size);
// Build the function table.
instance.function_table = BuildFunctionTable(isolate, module);
// Create module environment.
WasmLinker linker(isolate, module->functions->size());
ModuleEnv module_env;
module_env.module = module;
module_env.mem_start = reinterpret_cast<uintptr_t>(mem_addr.get());
module_env.mem_end = reinterpret_cast<uintptr_t>(mem_addr.get()) + mem_size;
module_env.globals_area = reinterpret_cast<uintptr_t>(globals_addr.get());
module_env.instance = &instance;
module_env.linker = &linker;
module_env.function_code = nullptr;
module_env.function_table = BuildFunctionTable(isolate, module);
module_env.asm_js = false;
// Load data segments.
// TODO(titzer): throw instead of crashing if segments don't fit in memory?
LoadDataSegments(module, mem_addr.get(), mem_size);
// Compile all functions.
Handle<Code> main_code = Handle<Code>::null(); // record last code.
int index = 0;
@ -479,7 +506,7 @@ int32_t CompileAndRunWasmModule(Isolate* isolate, WasmModule* module) {
return -1;
}
linker.Link(module_env.function_table, module->function_table);
linker.Link(instance.function_table, instance.module->function_table);
// Wrap the main code so it can be called as a JS function.
Handle<String> name = isolate->factory()->NewStringFromStaticChars("main");

View File

@ -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) {

View File

@ -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);

View File

@ -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);

View File

@ -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>;