Commit d7ee8124 authored by ahaas's avatar ahaas Committed by Commit bot

[wasm] Implement GrowMemory in the wasm interpreter

R=titzer@chromium.org

Review-Url: https://codereview.chromium.org/2341653002
Cr-Commit-Position: refs/heads/master@{#39406}
parent 19522d8e
......@@ -654,6 +654,45 @@ static inline int64_t ExecuteI64ReinterpretF64(double a, TrapReason* trap) {
return bit_cast<int64_t>(a);
}
static inline int32_t ExecuteGrowMemory(uint32_t delta_pages,
WasmModuleInstance* instance) {
// TODO(ahaas): Move memory allocation to wasm-module.cc for better
// encapsulation.
uint32_t old_size = instance->mem_size;
uint32_t new_size;
byte* new_mem_start;
if (instance->mem_size == 0) {
if (delta_pages > wasm::WasmModule::kMaxMemPages) {
return -1;
}
// TODO(gdeepti): Fix bounds check to take into account size of memtype.
new_size = delta_pages * wasm::WasmModule::kPageSize;
new_mem_start = static_cast<byte*>(calloc(new_size, sizeof(byte)));
if (!new_mem_start) {
return -1;
}
} else {
DCHECK_NOT_NULL(instance->mem_start);
new_size = old_size + delta_pages * wasm::WasmModule::kPageSize;
if (new_size >
wasm::WasmModule::kMaxMemPages * wasm::WasmModule::kPageSize) {
return -1;
}
new_mem_start = static_cast<byte*>(realloc(instance->mem_start, new_size));
if (!new_mem_start) {
return -1;
}
// Zero initializing uninitialized memory from realloc
memset(new_mem_start + old_size, 0, new_size - old_size);
}
instance->mem_start = new_mem_start;
instance->mem_size = new_size;
// realloc
// update mem_start
// update mem_size
return static_cast<int32_t>(old_size / WasmModule::kPageSize);
}
enum InternalOpcode {
#define DECL_INTERNAL_ENUM(name, value) kInternal##name = value,
FOREACH_INTERNAL_OPCODE(DECL_INTERNAL_ENUM)
......@@ -1546,7 +1585,11 @@ class ThreadImpl : public WasmInterpreter::Thread {
ASMJS_STORE_CASE(F32AsmjsStoreMem, float, float);
ASMJS_STORE_CASE(F64AsmjsStoreMem, double, double);
#undef ASMJS_STORE_CASE
case kExprGrowMemory: {
uint32_t delta_pages = Pop().to<uint32_t>();
Push(pc, WasmVal(ExecuteGrowMemory(delta_pages, instance())));
break;
}
case kExprMemorySize: {
Push(pc, WasmVal(static_cast<uint32_t>(instance()->mem_size)));
break;
......
......@@ -286,6 +286,26 @@ TEST(Breakpoint_I32And_disable) {
}
}
TEST(GrowMemory) {
TestingModule module(kExecuteInterpreted);
WasmRunner<int32_t> r(&module, MachineType::Uint32());
module.AddMemory(WasmModule::kPageSize);
BUILD(r, WASM_GROW_MEMORY(WASM_GET_LOCAL(0)));
CHECK_EQ(1, r.Call(1));
}
TEST(GrowMemoryPreservesData) {
int32_t index = 16;
int32_t value = 2335;
TestingModule module(kExecuteInterpreted);
WasmRunner<int32_t> r(&module, MachineType::Uint32());
module.AddMemory(WasmModule::kPageSize);
BUILD(r, WASM_BLOCK(WASM_STORE_MEM(MachineType::Int32(), WASM_I32V(index),
WASM_I32V(value)),
WASM_GROW_MEMORY(WASM_GET_LOCAL(0)),
WASM_LOAD_MEM(MachineType::Int32(), WASM_I32V(index))));
CHECK_EQ(value, r.Call(1));
}
} // namespace wasm
} // namespace internal
} // namespace v8
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