Index: src/wasm/wasm-js.cc |
diff --git a/src/wasm/wasm-js.cc b/src/wasm/wasm-js.cc |
index b18524bdf65be30d1b492e328a90f0c9bbbd4b04..3c3b3dac8d910ec27ddff7b5872c0d7bee52ade9 100644 |
--- a/src/wasm/wasm-js.cc |
+++ b/src/wasm/wasm-js.cc |
@@ -27,11 +27,20 @@ using v8::internal::wasm::ErrorThrower; |
namespace v8 { |
-static const int kWasmMemoryBufferFieldIndex = 0; |
-static const int kWasmMemoryMaximumFieldIndex = 1; |
static const int kWasmTableArrayFieldIndex = 0; |
static const int kWasmTableMaximumFieldIndex = 1; |
+enum WasmMemoryObjectData { |
+ kWasmMemoryBuffer, |
+ kWasmMemoryMaximum, |
+ kWasmMemoryInstanceObject |
+}; |
+ |
+enum WasmInternalFieldCountData { |
+ kWasmTableInternalFieldCount = 2, |
+ kWasmMemoryInternalFieldCount |
+}; |
+ |
namespace { |
i::Handle<i::String> v8_str(i::Isolate* isolate, const char* str) { |
return isolate->factory()->NewStringFromAsciiChecked(str); |
@@ -636,11 +645,42 @@ void WebAssemblyMemoryGrow(const v8::FunctionCallbackInfo<v8::Value>& args) { |
"Receiver is not a WebAssembly.Memory")) { |
return; |
} |
+ if (args.Length() < 1) { |
+ v8::Local<v8::Value> e = v8::Exception::TypeError( |
+ v8_str(isolate, "Argument 0 required, must be numeric value of pages")); |
+ isolate->ThrowException(e); |
+ return; |
+ } |
- // TODO(rossberg): grow memory. |
- v8::Local<v8::Value> e = |
- v8::Exception::TypeError(v8_str(isolate, "Memory#grow unimplemented")); |
- isolate->ThrowException(e); |
+ uint32_t delta = args[0]->Uint32Value(context).FromJust(); |
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); |
+ i::Handle<i::JSObject> receiver = |
+ i::Handle<i::JSObject>::cast(Utils::OpenHandle(*args.This())); |
+ i::Handle<i::Object> instance_object( |
+ receiver->GetInternalField(kWasmMemoryInstanceObject), i_isolate); |
+ i::Handle<i::JSObject> instance( |
+ i::Handle<i::JSObject>::cast(instance_object)); |
+ |
+ // TODO(gdeepti) Implement growing memory when shared by different |
+ // instances. |
+ int32_t ret = internal::wasm::GrowInstanceMemory(i_isolate, instance, delta); |
+ if (ret == -1) { |
+ v8::Local<v8::Value> e = v8::Exception::Error( |
+ v8_str(isolate, "Unable to grow instance memory.")); |
+ isolate->ThrowException(e); |
+ return; |
+ } |
+ i::MaybeHandle<i::JSArrayBuffer> buffer = |
+ internal::wasm::GetInstanceMemory(i_isolate, instance); |
+ if (buffer.is_null()) { |
+ v8::Local<v8::Value> e = v8::Exception::Error( |
+ v8_str(isolate, "WebAssembly.Memory buffer object not set.")); |
+ isolate->ThrowException(e); |
+ return; |
+ } |
+ receiver->SetInternalField(kWasmMemoryBuffer, *buffer.ToHandleChecked()); |
+ v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); |
+ return_value.Set(ret); |
} |
void WebAssemblyMemoryGetBuffer( |
@@ -656,8 +696,8 @@ void WebAssemblyMemoryGetBuffer( |
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); |
i::Handle<i::JSObject> receiver = |
i::Handle<i::JSObject>::cast(Utils::OpenHandle(*args.This())); |
- i::Handle<i::Object> buffer( |
- receiver->GetInternalField(kWasmMemoryBufferFieldIndex), i_isolate); |
+ i::Handle<i::Object> buffer(receiver->GetInternalField(kWasmMemoryBuffer), |
+ i_isolate); |
DCHECK(buffer->IsJSArrayBuffer()); |
v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); |
return_value.Set(Utils::ToLocal(buffer)); |
@@ -671,9 +711,9 @@ i::Handle<i::JSObject> i::WasmJs::CreateWasmMemoryObject( |
i_isolate->native_context()->wasm_memory_constructor()); |
i::Handle<i::JSObject> memory_obj = |
i_isolate->factory()->NewJSObject(memory_ctor); |
- memory_obj->SetInternalField(kWasmMemoryBufferFieldIndex, *buffer); |
+ memory_obj->SetInternalField(kWasmMemoryBuffer, *buffer); |
memory_obj->SetInternalField( |
- kWasmMemoryMaximumFieldIndex, |
+ kWasmMemoryMaximum, |
has_maximum |
? static_cast<i::Object*>(i::Smi::FromInt(maximum)) |
: static_cast<i::Object*>(i_isolate->heap()->undefined_value())); |
@@ -788,7 +828,8 @@ void WasmJs::InstallWasmConstructors(Isolate* isolate, |
Handle<JSObject> table_proto = |
factory->NewJSObject(table_constructor, TENURED); |
map = isolate->factory()->NewMap( |
- i::JS_OBJECT_TYPE, i::JSObject::kHeaderSize + 2 * i::kPointerSize); |
+ i::JS_OBJECT_TYPE, i::JSObject::kHeaderSize + |
+ kWasmTableInternalFieldCount * i::kPointerSize); |
JSFunction::SetInitialMap(table_constructor, map, table_proto); |
JSObject::AddProperty(table_proto, isolate->factory()->constructor_string(), |
table_constructor, DONT_ENUM); |
@@ -804,7 +845,8 @@ void WasmJs::InstallWasmConstructors(Isolate* isolate, |
Handle<JSObject> memory_proto = |
factory->NewJSObject(memory_constructor, TENURED); |
map = isolate->factory()->NewMap( |
- i::JS_OBJECT_TYPE, i::JSObject::kHeaderSize + 2 * i::kPointerSize); |
+ i::JS_OBJECT_TYPE, i::JSObject::kHeaderSize + |
+ kWasmMemoryInternalFieldCount * i::kPointerSize); |
JSFunction::SetInitialMap(memory_constructor, map, memory_proto); |
JSObject::AddProperty(memory_proto, isolate->factory()->constructor_string(), |
memory_constructor, DONT_ENUM); |
@@ -912,9 +954,30 @@ Handle<JSArrayBuffer> WasmJs::GetWasmMemoryArrayBuffer(Isolate* isolate, |
Handle<Object> value) { |
DCHECK(IsWasmMemoryObject(isolate, value)); |
Handle<Object> buf( |
- JSObject::cast(*value)->GetInternalField(kWasmMemoryBufferFieldIndex), |
- isolate); |
+ JSObject::cast(*value)->GetInternalField(kWasmMemoryBuffer), isolate); |
return Handle<JSArrayBuffer>::cast(buf); |
} |
+ |
+uint32_t WasmJs::GetWasmMemoryMaximumSize(Isolate* isolate, |
+ Handle<Object> value) { |
+ DCHECK(IsWasmMemoryObject(isolate, value)); |
+ Object* max_mem = |
+ JSObject::cast(*value)->GetInternalField(kWasmMemoryMaximum); |
+ if (max_mem->IsUndefined(isolate)) return wasm::WasmModule::kMaxMemPages; |
+ uint32_t max_pages = Smi::cast(max_mem)->value(); |
+ return max_pages; |
+} |
+ |
+void WasmJs::SetWasmMemoryInstance(Isolate* isolate, |
+ Handle<Object> memory_object, |
+ Handle<JSObject> instance) { |
+ if (!memory_object->IsUndefined(isolate)) { |
+ DCHECK(IsWasmMemoryObject(isolate, memory_object)); |
+ // TODO(gdeepti): This should be a weak list of instance objects |
+ // for instances that share memory. |
+ JSObject::cast(*memory_object) |
+ ->SetInternalField(kWasmMemoryInstanceObject, *instance); |
+ } |
+} |
} // namespace internal |
} // namespace v8 |