| Index: src/wasm/wasm-js.cc
|
| diff --git a/src/wasm/wasm-js.cc b/src/wasm/wasm-js.cc
|
| index 4b2b897d82734112bac66f8d8d0532d3e4412d41..36ffed223da101b0ba8cd44bc8b63c1f837f69ea 100644
|
| --- a/src/wasm/wasm-js.cc
|
| +++ b/src/wasm/wasm-js.cc
|
| @@ -29,6 +29,7 @@ namespace v8 {
|
|
|
| static const int kWasmTableArrayFieldIndex = 0;
|
| static const int kWasmTableMaximumFieldIndex = 1;
|
| +static const int kWasmTableDispatchTablesFieldIndex = 2;
|
|
|
| enum WasmMemoryObjectData {
|
| kWasmMemoryBuffer,
|
| @@ -37,8 +38,8 @@ enum WasmMemoryObjectData {
|
| };
|
|
|
| enum WasmInternalFieldCountData {
|
| - kWasmTableInternalFieldCount = 2,
|
| - kWasmMemoryInternalFieldCount
|
| + kWasmTableInternalFieldCount = 3,
|
| + kWasmMemoryInternalFieldCount = 3
|
| };
|
|
|
| namespace {
|
| @@ -518,9 +519,19 @@ void WebAssemblyTableSet(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| return;
|
| }
|
|
|
| - i::Handle<i::FixedArray>::cast(array)->set(i, *value);
|
| + i::Handle<i::FixedArray> dispatch_tables(
|
| + i::FixedArray::cast(
|
| + receiver->GetInternalField(kWasmTableDispatchTablesFieldIndex)),
|
| + i_isolate);
|
| + if (value->IsNull(i_isolate)) {
|
| + i::wasm::UpdateDispatchTables(i_isolate, dispatch_tables, i,
|
| + i::Handle<i::JSFunction>::null());
|
| + } else {
|
| + i::wasm::UpdateDispatchTables(i_isolate, dispatch_tables, i,
|
| + i::Handle<i::JSFunction>::cast(value));
|
| + }
|
|
|
| - // TODO(titzer): update relevant instances.
|
| + i::Handle<i::FixedArray>::cast(array)->set(i, *value);
|
| }
|
|
|
| void WebAssemblyMemoryGrow(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| @@ -612,26 +623,60 @@ i::Handle<i::JSObject> i::WasmJs::CreateWasmMemoryObject(
|
|
|
| i::Handle<i::JSObject> i::WasmJs::CreateWasmTableObject(
|
| i::Isolate* i_isolate, uint32_t initial, bool has_maximum, uint32_t maximum,
|
| - i::Handle<i::FixedArray>* array) {
|
| + i::Handle<i::FixedArray>* js_functions) {
|
| i::Handle<i::JSFunction> table_ctor(
|
| i_isolate->native_context()->wasm_table_constructor());
|
| i::Handle<i::JSObject> table_obj =
|
| i_isolate->factory()->NewJSObject(table_ctor);
|
| - *array = i_isolate->factory()->NewFixedArray(initial);
|
| + *js_functions = i_isolate->factory()->NewFixedArray(initial);
|
| i::Object* null = i_isolate->heap()->null_value();
|
| // TODO(titzer): consider moving FixedArray to size_t.
|
| - for (int i = 0; i < static_cast<int>(initial); ++i) (*array)->set(i, null);
|
| - table_obj->SetInternalField(kWasmTableArrayFieldIndex, *(*array));
|
| + for (int i = 0; i < static_cast<int>(initial); ++i) {
|
| + (*js_functions)->set(i, null);
|
| + }
|
| + table_obj->SetInternalField(kWasmTableArrayFieldIndex, *(*js_functions));
|
| table_obj->SetInternalField(
|
| kWasmTableMaximumFieldIndex,
|
| has_maximum
|
| ? static_cast<i::Object*>(i::Smi::FromInt(maximum))
|
| : static_cast<i::Object*>(i_isolate->heap()->undefined_value()));
|
| + Handle<FixedArray> dispatch_tables = i_isolate->factory()->NewFixedArray(0);
|
| + table_obj->SetInternalField(kWasmTableDispatchTablesFieldIndex,
|
| + *dispatch_tables);
|
| i::Handle<i::Symbol> table_sym(i_isolate->native_context()->wasm_table_sym());
|
| i::Object::SetProperty(table_obj, table_sym, table_obj, i::STRICT).Check();
|
| return table_obj;
|
| }
|
|
|
| +i::Handle<i::FixedArray> i::WasmJs::AddWasmTableDispatchTable(
|
| + i::Isolate* i_isolate, i::Handle<i::JSObject> table_obj,
|
| + i::Handle<i::JSObject> instance, int table_index,
|
| + i::Handle<i::FixedArray> dispatch_table) {
|
| + DCHECK(IsWasmTableObject(i_isolate, table_obj));
|
| + i::Handle<i::FixedArray> dispatch_tables(
|
| + i::FixedArray::cast(
|
| + table_obj->GetInternalField(kWasmTableDispatchTablesFieldIndex)),
|
| + i_isolate);
|
| + DCHECK_EQ(0, dispatch_tables->length() % 3);
|
| +
|
| + if (instance.is_null()) return dispatch_tables;
|
| + // TODO(titzer): use weak cells here to avoid leaking instances.
|
| +
|
| + // Grow the dispatch table and add a new pair at the end.
|
| + i::Handle<i::FixedArray> new_dispatch_tables =
|
| + i_isolate->factory()->CopyFixedArrayAndGrow(dispatch_tables, 3);
|
| +
|
| + new_dispatch_tables->set(dispatch_tables->length() + 0, *instance);
|
| + new_dispatch_tables->set(dispatch_tables->length() + 1,
|
| + Smi::FromInt(table_index));
|
| + new_dispatch_tables->set(dispatch_tables->length() + 2, *dispatch_table);
|
| +
|
| + table_obj->SetInternalField(kWasmTableDispatchTablesFieldIndex,
|
| + *new_dispatch_tables);
|
| +
|
| + return new_dispatch_tables;
|
| +}
|
| +
|
| // TODO(titzer): we use the API to create the function template because the
|
| // internal guts are too ugly to replicate here.
|
| static i::Handle<i::FunctionTemplateInfo> NewTemplate(i::Isolate* i_isolate,
|
| @@ -817,17 +862,35 @@ void WasmJs::InstallWasmMapsIfNeeded(Isolate* isolate,
|
| }
|
| }
|
|
|
| -bool WasmJs::IsWasmMemoryObject(Isolate* isolate, Handle<Object> value) {
|
| +static bool HasBrand(i::Handle<i::Object> value, i::Handle<i::Symbol> symbol) {
|
| if (value->IsJSObject()) {
|
| i::Handle<i::JSObject> object = i::Handle<i::JSObject>::cast(value);
|
| - i::Handle<i::Symbol> sym(isolate->context()->wasm_memory_sym(), isolate);
|
| - Maybe<bool> has_brand = i::JSObject::HasOwnProperty(object, sym);
|
| + Maybe<bool> has_brand = i::JSObject::HasOwnProperty(object, symbol);
|
| if (has_brand.IsNothing()) return false;
|
| if (has_brand.ToChecked()) return true;
|
| }
|
| return false;
|
| }
|
|
|
| +bool WasmJs::IsWasmMemoryObject(Isolate* isolate, Handle<Object> value) {
|
| + i::Handle<i::Symbol> symbol(isolate->context()->wasm_memory_sym(), isolate);
|
| + return HasBrand(value, symbol);
|
| +}
|
| +
|
| +bool WasmJs::IsWasmTableObject(Isolate* isolate, Handle<Object> value) {
|
| + i::Handle<i::Symbol> symbol(isolate->context()->wasm_table_sym(), isolate);
|
| + return HasBrand(value, symbol);
|
| +}
|
| +
|
| +Handle<FixedArray> WasmJs::GetWasmTableFunctions(Isolate* isolate,
|
| + Handle<JSObject> value) {
|
| + DCHECK(IsWasmTableObject(isolate, value));
|
| + Handle<Object> arr(
|
| + JSObject::cast(*value)->GetInternalField(kWasmTableArrayFieldIndex),
|
| + isolate);
|
| + return Handle<FixedArray>::cast(arr);
|
| +}
|
| +
|
| Handle<JSArrayBuffer> WasmJs::GetWasmMemoryArrayBuffer(Isolate* isolate,
|
| Handle<Object> value) {
|
| DCHECK(IsWasmMemoryObject(isolate, value));
|
| @@ -847,7 +910,7 @@ uint32_t WasmJs::GetWasmMemoryMaximumSize(Isolate* isolate,
|
| DCHECK(IsWasmMemoryObject(isolate, value));
|
| Object* max_mem =
|
| JSObject::cast(*value)->GetInternalField(kWasmMemoryMaximum);
|
| - if (max_mem->IsUndefined(isolate)) return wasm::WasmModule::kMaxMemPages;
|
| + if (max_mem->IsUndefined(isolate)) return wasm::WasmModule::kV8MaxPages;
|
| uint32_t max_pages = Smi::cast(max_mem)->value();
|
| return max_pages;
|
| }
|
|
|