Index: src/wasm/wasm-interpreter.cc |
diff --git a/src/wasm/wasm-interpreter.cc b/src/wasm/wasm-interpreter.cc |
index 17ca6111e3a5e947570491f32a4102a5d7383440..94b385033d5110f94692c7fde2978eb63ed93f43 100644 |
--- a/src/wasm/wasm-interpreter.cc |
+++ b/src/wasm/wasm-interpreter.cc |
@@ -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; |