Index: src/wasm/wasm-module.cc |
diff --git a/src/wasm/wasm-module.cc b/src/wasm/wasm-module.cc |
index 5f7174acebac77a6c4662b9134c628c85e28618a..10c03a84ee5eabb97ffa57b87a9e53876bef4ae8 100644 |
--- a/src/wasm/wasm-module.cc |
+++ b/src/wasm/wasm-module.cc |
@@ -102,6 +102,12 @@ enum WasmIndirectFunctionTableData { |
kWasmIndirectFunctionTableDataSize // Sentinel value. |
}; |
+enum WasmMemoryObjectData { |
titzer
2016/10/11 08:30:06
I am wondering if it is possible to hide these in
gdeepti
2016/10/16 15:39:58
Done.
|
+ kWasmMemoryBuffer, |
+ kWasmMaxMemory, |
+ kWasmInstanceObject |
+}; |
+ |
byte* raw_buffer_ptr(MaybeHandle<JSArrayBuffer> buffer, int offset) { |
return static_cast<byte*>(buffer.ToHandleChecked()->backing_store()) + offset; |
} |
@@ -1449,6 +1455,14 @@ class WasmInstanceBuilder { |
} |
DCHECK(wasm::IsWasmObject(*instance)); |
+ // TODO(gdeepti): This should be a weak list of instance objects |
+ // for instances that share memory. |
+ Handle<Object> memory_object(instance->GetInternalField(kWasmMemObject), |
+ isolate_); |
+ if (!memory_object->IsUndefined(isolate_)) { |
+ JSObject::cast(*memory_object) |
+ ->SetInternalField(kWasmInstanceObject, *instance); |
+ } |
TRACE("Finishing instance %d\n", compiled_module_->instance_id()); |
TRACE_CHAIN(WasmCompiledModule::cast(module_object_->GetInternalField(0))); |
@@ -2181,11 +2195,26 @@ int32_t GetInstanceMemorySize(Isolate* isolate, Handle<JSObject> instance) { |
} |
} |
+uint32_t GetMaxInstanceMemorySize(Isolate* isolate, Handle<JSObject> instance) { |
+ uint32_t max_pages = WasmModule::kMaxMemPages; |
+ Handle<Object> memory_object(instance->GetInternalField(kWasmMemObject), |
+ isolate); |
+ if (memory_object->IsUndefined(isolate)) return max_pages; |
+ Object* max_mem = |
+ JSObject::cast(*memory_object)->GetInternalField(kWasmMaxMemory); |
+ if (max_mem->IsUndefined(isolate)) return max_pages; |
+ max_pages = Smi::cast(max_mem)->value(); |
+ DCHECK(max_pages <= WasmModule::kMaxMemPages); |
+ return max_pages; |
+} |
+ |
int32_t GrowInstanceMemory(Isolate* isolate, Handle<JSObject> instance, |
uint32_t pages) { |
- if (pages == 0) { |
- return GetInstanceMemorySize(isolate, instance); |
- } |
+ if (!IsWasmObject(*instance)) return -1; |
+ if (pages == 0) return GetInstanceMemorySize(isolate, instance); |
+ uint32_t max_pages = GetMaxInstanceMemorySize(isolate, instance); |
+ if (WasmModule::kMaxMemPages < max_pages) return -1; |
+ |
Address old_mem_start = nullptr; |
uint32_t old_size = 0, new_size = 0; |
@@ -2197,8 +2226,7 @@ int32_t GrowInstanceMemory(Isolate* isolate, Handle<JSObject> instance, |
// Allocate new array buffer of given size. |
// TODO(gdeepti): Fix bounds check to take into account size of memtype. |
new_size = pages * WasmModule::kPageSize; |
- // The code generated in the wasm compiler guarantees this precondition. |
- DCHECK(pages <= WasmModule::kMaxMemPages); |
+ if (max_pages < pages) return -1; |
} else { |
old_mem_start = static_cast<Address>(old_buffer->backing_store()); |
old_size = old_buffer->byte_length()->Number(); |
@@ -2211,8 +2239,7 @@ int32_t GrowInstanceMemory(Isolate* isolate, Handle<JSObject> instance, |
new_size = old_size + pages * WasmModule::kPageSize; |
} |
- if (new_size <= old_size || |
- WasmModule::kMaxMemPages * WasmModule::kPageSize <= new_size) { |
+ if (new_size <= old_size || max_pages * WasmModule::kPageSize < new_size) { |
return -1; |
} |
Handle<JSArrayBuffer> buffer = NewArrayBuffer(isolate, new_size); |