| Index: src/wasm/wasm-js.cc
|
| diff --git a/src/wasm/wasm-js.cc b/src/wasm/wasm-js.cc
|
| index 60f33f9e4c6b7c4220addb4e02b98ce11e27b10d..0e030a28c467ef6e00af8c7b7f4fad90b48ccf21 100644
|
| --- a/src/wasm/wasm-js.cc
|
| +++ b/src/wasm/wasm-js.cc
|
| @@ -19,6 +19,7 @@
|
| #include "src/wasm/module-decoder.h"
|
| #include "src/wasm/wasm-js.h"
|
| #include "src/wasm/wasm-module.h"
|
| +#include "src/wasm/wasm-objects.h"
|
| #include "src/wasm/wasm-result.h"
|
|
|
| typedef uint8_t byte;
|
| @@ -27,21 +28,12 @@ using v8::internal::wasm::ErrorThrower;
|
|
|
| namespace v8 {
|
|
|
| -static const int kWasmTableArrayFieldIndex = 0;
|
| -static const int kWasmTableMaximumFieldIndex = 1;
|
| -static const int kWasmTableDispatchTablesFieldIndex = 2;
|
| -
|
| enum WasmMemoryObjectData {
|
| kWasmMemoryBuffer,
|
| kWasmMemoryMaximum,
|
| kWasmMemoryInstanceObject
|
| };
|
|
|
| -enum WasmInternalFieldCountData {
|
| - kWasmTableInternalFieldCount = 3,
|
| - kWasmMemoryInternalFieldCount = 3
|
| -};
|
| -
|
| namespace {
|
| i::Handle<i::String> v8_str(i::Isolate* isolate, const char* str) {
|
| return isolate->factory()->NewStringFromAsciiChecked(str);
|
| @@ -93,14 +85,14 @@ RawBuffer GetRawBufferSource(
|
| return {start, end};
|
| }
|
|
|
| -static i::MaybeHandle<i::JSObject> CreateModuleObject(
|
| +static i::MaybeHandle<i::WasmModuleObject> CreateModuleObject(
|
| v8::Isolate* isolate, const v8::Local<v8::Value> source,
|
| ErrorThrower* thrower) {
|
| i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
| i::MaybeHandle<i::JSObject> nothing;
|
|
|
| RawBuffer buffer = GetRawBufferSource(source, thrower);
|
| - if (buffer.start == nullptr) return i::MaybeHandle<i::JSObject>();
|
| + if (buffer.start == nullptr) return i::MaybeHandle<i::WasmModuleObject>();
|
|
|
| DCHECK(source->IsArrayBuffer() || source->IsTypedArray());
|
| return i::wasm::CreateModuleObjectFromBytes(
|
| @@ -123,8 +115,8 @@ static bool ValidateModule(v8::Isolate* isolate,
|
| i::wasm::ModuleOrigin::kWasmOrigin);
|
| }
|
|
|
| -bool BrandCheck(Isolate* isolate, i::Handle<i::Object> value,
|
| - i::Handle<i::Symbol> sym, const char* msg) {
|
| +static bool BrandCheck(Isolate* isolate, i::Handle<i::Object> value,
|
| + i::Handle<i::Symbol> sym, const char* msg) {
|
| if (value->IsJSObject()) {
|
| i::Handle<i::JSObject> object = i::Handle<i::JSObject>::cast(value);
|
| Maybe<bool> has_brand = i::JSObject::HasOwnProperty(object, sym);
|
| @@ -233,7 +225,9 @@ void WebAssemblyInstance(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| Local<Object> obj = Local<Object>::Cast(args[2]);
|
| i::Handle<i::Object> mem_obj = v8::Utils::OpenHandle(*obj);
|
| if (i::WasmJs::IsWasmMemoryObject(i_isolate, mem_obj)) {
|
| - memory = i::WasmJs::GetWasmMemoryArrayBuffer(i_isolate, mem_obj);
|
| + memory = i::Handle<i::JSArrayBuffer>(
|
| + i::Handle<i::WasmMemoryObject>::cast(mem_obj)->get_buffer(),
|
| + i_isolate);
|
| } else {
|
| thrower.TypeError("Argument 2 must be a WebAssembly.Memory");
|
| }
|
| @@ -325,12 +319,14 @@ void WebAssemblyTable(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| &maximum, initial, max_table_size)) {
|
| return;
|
| }
|
| + } else {
|
| + maximum = static_cast<int>(i::wasm::WasmModule::kV8MaxTableSize);
|
| }
|
|
|
| i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
| i::Handle<i::FixedArray> fixed_array;
|
| - i::Handle<i::JSObject> table_obj = i::WasmJs::CreateWasmTableObject(
|
| - i_isolate, initial, has_maximum.FromJust(), maximum, &fixed_array);
|
| + i::Handle<i::JSObject> table_obj =
|
| + i::WasmTableObject::New(i_isolate, initial, maximum, &fixed_array);
|
| v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
|
| return_value.Set(Utils::ToLocal(table_obj));
|
| }
|
| @@ -374,10 +370,9 @@ void WebAssemblyMemory(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| static_cast<size_t>(initial);
|
| i::JSArrayBuffer::SetupAllocatingData(buffer, i_isolate, size);
|
|
|
| - i::Handle<i::JSObject> memory_obj = i::WasmJs::CreateWasmMemoryObject(
|
| - i_isolate, buffer, has_maximum.FromJust(), maximum);
|
| - v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
|
| - return_value.Set(Utils::ToLocal(memory_obj));
|
| + i::Handle<i::JSObject> memory_obj = i::WasmMemoryObject::New(
|
| + i_isolate, buffer, has_maximum.FromJust() ? maximum : -1);
|
| + args.GetReturnValue().Set(Utils::ToLocal(memory_obj));
|
| }
|
|
|
| void WebAssemblyTableGetLength(
|
| @@ -390,14 +385,10 @@ void WebAssemblyTableGetLength(
|
| "Receiver is not a WebAssembly.Table")) {
|
| return;
|
| }
|
| - 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> array(
|
| - receiver->GetInternalField(kWasmTableArrayFieldIndex), i_isolate);
|
| - int length = i::Handle<i::FixedArray>::cast(array)->length();
|
| - v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
|
| - return_value.Set(v8::Number::New(isolate, length));
|
| + auto receiver =
|
| + i::Handle<i::WasmTableObject>::cast(Utils::OpenHandle(*args.This()));
|
| + args.GetReturnValue().Set(
|
| + v8::Number::New(isolate, receiver->current_length()));
|
| }
|
|
|
| void WebAssemblyTableGrow(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| @@ -411,12 +402,9 @@ void WebAssemblyTableGrow(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| }
|
|
|
| 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::FixedArray> old_array(
|
| - i::FixedArray::cast(
|
| - receiver->GetInternalField(kWasmTableArrayFieldIndex)),
|
| - i_isolate);
|
| + auto receiver =
|
| + i::Handle<i::WasmTableObject>::cast(Utils::OpenHandle(*args.This()));
|
| + i::Handle<i::FixedArray> old_array(receiver->get_functions(), i_isolate);
|
| int old_size = old_array->length();
|
| int64_t new_size64 = 0;
|
| if (args.Length() > 0 && !args[0]->IntegerValue(context).To(&new_size64)) {
|
| @@ -424,11 +412,7 @@ void WebAssemblyTableGrow(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| }
|
| new_size64 += old_size;
|
|
|
| - i::Handle<i::Object> max_val(
|
| - receiver->GetInternalField(kWasmTableMaximumFieldIndex), i_isolate);
|
| - int max_size =
|
| - max_val->IsSmi() ? i::Smi::cast(*max_val)->value() : max_table_size;
|
| - if (new_size64 < old_size || new_size64 > max_size) {
|
| + if (new_size64 < old_size || new_size64 > receiver->maximum_length()) {
|
| v8::Local<v8::Value> e = v8::Exception::RangeError(
|
| v8_str(isolate, new_size64 < old_size ? "trying to shrink table"
|
| : "maximum table size exceeded"));
|
| @@ -443,7 +427,7 @@ void WebAssemblyTableGrow(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| for (int i = 0; i < old_size; ++i) new_array->set(i, old_array->get(i));
|
| i::Object* null = i_isolate->heap()->null_value();
|
| for (int i = old_size; i < new_size; ++i) new_array->set(i, null);
|
| - receiver->SetInternalField(kWasmTableArrayFieldIndex, *new_array);
|
| + receiver->set_functions(*new_array);
|
| }
|
|
|
| // TODO(titzer): update relevant instances.
|
| @@ -460,22 +444,20 @@ void WebAssemblyTableGet(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| }
|
|
|
| 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> array(
|
| - receiver->GetInternalField(kWasmTableArrayFieldIndex), i_isolate);
|
| + auto receiver =
|
| + i::Handle<i::WasmTableObject>::cast(Utils::OpenHandle(*args.This()));
|
| + i::Handle<i::FixedArray> array(receiver->get_functions(), i_isolate);
|
| int i = 0;
|
| if (args.Length() > 0 && !args[0]->Int32Value(context).To(&i)) return;
|
| v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
|
| - if (i < 0 || i >= i::Handle<i::FixedArray>::cast(array)->length()) {
|
| + if (i < 0 || i >= array->length()) {
|
| v8::Local<v8::Value> e =
|
| v8::Exception::RangeError(v8_str(isolate, "index out of bounds"));
|
| isolate->ThrowException(e);
|
| return;
|
| }
|
|
|
| - i::Handle<i::Object> value(i::Handle<i::FixedArray>::cast(array)->get(i),
|
| - i_isolate);
|
| + i::Handle<i::Object> value(array->get(i), i_isolate);
|
| return_value.Set(Utils::ToLocal(value));
|
| }
|
|
|
| @@ -506,23 +488,20 @@ void WebAssemblyTableSet(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| return;
|
| }
|
|
|
| - i::Handle<i::JSObject> receiver =
|
| - i::Handle<i::JSObject>::cast(Utils::OpenHandle(*args.This()));
|
| - i::Handle<i::Object> array(
|
| - receiver->GetInternalField(kWasmTableArrayFieldIndex), i_isolate);
|
| + auto receiver =
|
| + i::Handle<i::WasmTableObject>::cast(Utils::OpenHandle(*args.This()));
|
| + i::Handle<i::FixedArray> array(receiver->get_functions(), i_isolate);
|
| int i;
|
| if (!args[0]->Int32Value(context).To(&i)) return;
|
| - if (i < 0 || i >= i::Handle<i::FixedArray>::cast(array)->length()) {
|
| + if (i < 0 || i >= array->length()) {
|
| v8::Local<v8::Value> e =
|
| v8::Exception::RangeError(v8_str(isolate, "index out of bounds"));
|
| isolate->ThrowException(e);
|
| return;
|
| }
|
|
|
| - i::Handle<i::FixedArray> dispatch_tables(
|
| - i::FixedArray::cast(
|
| - receiver->GetInternalField(kWasmTableDispatchTablesFieldIndex)),
|
| - i_isolate);
|
| + i::Handle<i::FixedArray> dispatch_tables(receiver->get_dispatch_tables(),
|
| + i_isolate);
|
| if (value->IsNull(i_isolate)) {
|
| i::wasm::UpdateDispatchTables(i_isolate, dispatch_tables, i,
|
| i::Handle<i::JSFunction>::null());
|
| @@ -602,81 +581,6 @@ void WebAssemblyMemoryGetBuffer(
|
| }
|
| } // namespace
|
|
|
| -i::Handle<i::JSObject> i::WasmJs::CreateWasmMemoryObject(
|
| - i::Isolate* i_isolate, i::Handle<i::JSArrayBuffer> buffer, bool has_maximum,
|
| - int maximum) {
|
| - i::Handle<i::JSFunction> memory_ctor(
|
| - i_isolate->native_context()->wasm_memory_constructor());
|
| - i::Handle<i::JSObject> memory_obj =
|
| - i_isolate->factory()->NewJSObject(memory_ctor);
|
| - memory_obj->SetInternalField(kWasmMemoryBuffer, *buffer);
|
| - memory_obj->SetInternalField(
|
| - kWasmMemoryMaximum,
|
| - has_maximum
|
| - ? static_cast<i::Object*>(i::Smi::FromInt(maximum))
|
| - : static_cast<i::Object*>(i_isolate->heap()->undefined_value()));
|
| - i::Handle<i::Symbol> memory_sym(
|
| - i_isolate->native_context()->wasm_memory_sym());
|
| - i::Object::SetProperty(memory_obj, memory_sym, memory_obj, i::STRICT).Check();
|
| - return memory_obj;
|
| -}
|
| -
|
| -i::Handle<i::JSObject> i::WasmJs::CreateWasmTableObject(
|
| - i::Isolate* i_isolate, uint32_t initial, bool has_maximum, uint32_t maximum,
|
| - 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);
|
| - *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) {
|
| - (*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,
|
| @@ -765,7 +669,8 @@ void WasmJs::InstallWasmConstructors(Isolate* isolate,
|
| Handle<JSObject> module_proto =
|
| factory->NewJSObject(module_constructor, TENURED);
|
| i::Handle<i::Map> map = isolate->factory()->NewMap(
|
| - i::JS_OBJECT_TYPE, i::JSObject::kHeaderSize + i::kPointerSize);
|
| + i::JS_OBJECT_TYPE, i::JSObject::kHeaderSize +
|
| + WasmModuleObject::kFieldCount * i::kPointerSize);
|
| JSFunction::SetInitialMap(module_constructor, map, module_proto);
|
| JSObject::AddProperty(module_proto, isolate->factory()->constructor_string(),
|
| module_constructor, DONT_ENUM);
|
| @@ -783,7 +688,7 @@ void WasmJs::InstallWasmConstructors(Isolate* isolate,
|
| factory->NewJSObject(table_constructor, TENURED);
|
| map = isolate->factory()->NewMap(
|
| i::JS_OBJECT_TYPE, i::JSObject::kHeaderSize +
|
| - kWasmTableInternalFieldCount * i::kPointerSize);
|
| + WasmTableObject::kFieldCount * i::kPointerSize);
|
| JSFunction::SetInitialMap(table_constructor, map, table_proto);
|
| JSObject::AddProperty(table_proto, isolate->factory()->constructor_string(),
|
| table_constructor, DONT_ENUM);
|
| @@ -800,7 +705,7 @@ void WasmJs::InstallWasmConstructors(Isolate* isolate,
|
| factory->NewJSObject(memory_constructor, TENURED);
|
| map = isolate->factory()->NewMap(
|
| i::JS_OBJECT_TYPE, i::JSObject::kHeaderSize +
|
| - kWasmMemoryInternalFieldCount * i::kPointerSize);
|
| + WasmMemoryObject::kFieldCount * i::kPointerSize);
|
| JSFunction::SetInitialMap(memory_constructor, map, memory_proto);
|
| JSObject::AddProperty(memory_proto, isolate->factory()->constructor_string(),
|
| memory_constructor, DONT_ENUM);
|
| @@ -881,50 +786,5 @@ 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));
|
| - Handle<Object> buf(
|
| - JSObject::cast(*value)->GetInternalField(kWasmMemoryBuffer), isolate);
|
| - return Handle<JSArrayBuffer>::cast(buf);
|
| -}
|
| -
|
| -void WasmJs::SetWasmMemoryArrayBuffer(Isolate* isolate, Handle<Object> value,
|
| - Handle<JSArrayBuffer> buffer) {
|
| - DCHECK(IsWasmMemoryObject(isolate, value));
|
| - JSObject::cast(*value)->SetInternalField(kWasmMemoryBuffer, *buffer);
|
| -}
|
| -
|
| -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 0;
|
| - 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
|
|
|