Chromium Code Reviews| Index: src/wasm/wasm-js.cc |
| diff --git a/src/wasm/wasm-js.cc b/src/wasm/wasm-js.cc |
| index 4190562694fb55643390db70f7ef551f727bd5d9..dc43e990d013115ce38f0c6f972db94c2b9df934 100644 |
| --- a/src/wasm/wasm-js.cc |
| +++ b/src/wasm/wasm-js.cc |
| @@ -29,6 +29,13 @@ using v8::internal::wasm::ErrorThrower; |
| namespace v8 { |
| namespace { |
| +i::Handle<i::String> v8_str(i::Isolate* isolate, const char* str) { |
| + return isolate->factory()->NewStringFromAsciiChecked(str); |
| +} |
| +Local<String> v8_str(Isolate* isolate, const char* str) { |
| + return Utils::ToLocal(v8_str(reinterpret_cast<i::Isolate*>(isolate), str)); |
| +} |
| + |
| struct RawBuffer { |
| const byte* start; |
| const byte* end; |
| @@ -78,7 +85,7 @@ void VerifyModule(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| ErrorThrower thrower(isolate, "Wasm.verifyModule()"); |
| if (args.Length() < 1) { |
| - thrower.Error("Argument 0 must be a buffer source"); |
| + thrower.TypeError("Argument 0 must be a buffer source"); |
| return; |
| } |
| RawBuffer buffer = GetRawBufferSource(args[0], &thrower); |
| @@ -102,7 +109,7 @@ void VerifyFunction(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| ErrorThrower thrower(isolate, "Wasm.verifyFunction()"); |
| if (args.Length() < 1) { |
| - thrower.Error("Argument 0 must be a buffer source"); |
| + thrower.TypeError("Argument 0 must be a buffer source"); |
| return; |
| } |
| RawBuffer buffer = GetRawBufferSource(args[0], &thrower); |
| @@ -167,7 +174,7 @@ void InstantiateModule(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| ErrorThrower thrower(isolate, "Wasm.instantiateModule()"); |
| if (args.Length() < 1) { |
| - thrower.Error("Argument 0 must be a buffer source"); |
| + thrower.TypeError("Argument 0 must be a buffer source"); |
| return; |
| } |
| RawBuffer buffer = GetRawBufferSource(args[0], &thrower); |
| @@ -191,6 +198,19 @@ static i::MaybeHandle<i::JSObject> CreateModuleObject( |
| i::wasm::ModuleOrigin::kWasmOrigin); |
| } |
| +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); |
| + if (has_brand.IsNothing()) return false; |
| + if (has_brand.ToChecked()) return true; |
| + } |
| + v8::Local<v8::Value> e = v8::Exception::TypeError(v8_str(isolate, msg)); |
| + isolate->ThrowException(e); |
| + return false; |
| +} |
| + |
| void WebAssemblyCompile(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| v8::Isolate* isolate = args.GetIsolate(); |
| HandleScope scope(isolate); |
| @@ -198,7 +218,7 @@ void WebAssemblyCompile(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| "WebAssembly.compile()"); |
| if (args.Length() < 1) { |
| - thrower.Error("Argument 0 must be a buffer source"); |
| + thrower.TypeError("Argument 0 must be a buffer source"); |
| return; |
| } |
| i::MaybeHandle<i::JSObject> module_obj = |
| @@ -223,7 +243,7 @@ void WebAssemblyModule(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| "WebAssembly.Module()"); |
| if (args.Length() < 1) { |
| - thrower.Error("Argument 0 must be a buffer source"); |
| + thrower.TypeError("Argument 0 must be a buffer source"); |
| return; |
| } |
| i::MaybeHandle<i::JSObject> module_obj = |
| @@ -242,18 +262,15 @@ void WebAssemblyInstance(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| ErrorThrower thrower(i_isolate, "WebAssembly.Instance()"); |
| if (args.Length() < 1) { |
| - thrower.Error( |
| - "Argument 0 must be provided, and must be a WebAssembly.Module object"); |
| + thrower.TypeError("Argument 0 must be a WebAssembly.Module"); |
| return; |
| } |
| Local<Context> context = isolate->GetCurrentContext(); |
| i::Handle<i::Context> i_context = Utils::OpenHandle(*context); |
| - i::Handle<i::Symbol> module_sym(i_context->wasm_module_sym()); |
| - i::MaybeHandle<i::Object> source = |
| - i::Object::GetProperty(Utils::OpenHandle(*args[0]), module_sym); |
| - if (source.is_null() || source.ToHandleChecked()->IsUndefined(i_isolate)) { |
| - thrower.Error("Argument 0 must be a WebAssembly.Module"); |
| + if (!BrandCheck(isolate, Utils::OpenHandle(*args[0]), |
| + i::Handle<i::Symbol>(i_context->wasm_module_sym()), |
| + "Argument 0 must be a WebAssembly.Module")) { |
| return; |
| } |
| @@ -263,7 +280,7 @@ void WebAssemblyInstance(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| i::Handle<i::JSObject>::cast(v8::Utils::OpenHandle(*obj)); |
| if (module_obj->GetInternalFieldCount() < 1 || |
| !module_obj->GetInternalField(0)->IsFixedArray()) { |
| - thrower.Error("Argument 0 is an invalid WebAssembly.Module"); |
| + thrower.TypeError("Argument 0 is an invalid WebAssembly.Module"); |
| return; |
| } |
| @@ -288,6 +305,214 @@ void WebAssemblyInstance(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); |
| return_value.Set(Utils::ToLocal(instance.ToHandleChecked())); |
| } |
| + |
| +void WebAssemblyTable(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| + v8::Isolate* isolate = args.GetIsolate(); |
| + HandleScope scope(isolate); |
| + ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate), |
| + "WebAssembly.Module()"); |
| + if (args.Length() < 1 || !args[0]->IsObject()) { |
| + thrower.TypeError("Argument 0 must be a table descriptor"); |
| + return; |
| + } |
| + Local<Context> context = isolate->GetCurrentContext(); |
| + Local<v8::Object> descriptor = args[0]->ToObject(context).ToLocalChecked(); |
| + // The descriptor's 'element'. |
| + { |
| + v8::MaybeLocal<v8::Value> maybe = |
| + descriptor->Get(context, v8_str(isolate, "element")); |
| + v8::Local<v8::Value> value; |
| + if (!maybe.ToLocal(&value)) return; |
| + v8::Local<v8::String> string; |
| + if (!value->ToString(context).ToLocal(&string)) return; |
| + bool equal; |
| + if (!string->Equals(context, v8_str(isolate, "anyfunc")).To(&equal)) return; |
| + if (!equal) { |
| + thrower.TypeError("Descriptor property 'element' must be 'anyfunc'"); |
| + return; |
| + } |
| + } |
| + // The descriptor's 'initial'. |
| + int initial; |
| + { |
| + v8::MaybeLocal<v8::Value> maybe = |
| + descriptor->Get(context, v8_str(isolate, "initial")); |
| + v8::Local<v8::Value> value; |
| + if (!maybe.ToLocal(&value)) return; |
| + int64_t number; |
|
titzer
2016/09/20 12:37:21
Can we factor out a helper routine for setting a n
ahaas
2016/09/21 09:38:11
Done.
|
| + if (!value->IntegerValue(context).To(&number)) return; |
| + if (number < 0) { |
| + thrower.RangeError("Descriptor property 'initial' must not be negative"); |
| + return; |
| + } |
| + initial = static_cast<int>(number); |
| + if (initial != number) { |
| + thrower.RangeError("Descriptor property 'initial' too large"); |
| + return; |
| + } |
| + } |
| + // The descriptor's 'maximum'. |
| + Maybe<int> maximum = Nothing<int>(); |
| + { |
| + v8::MaybeLocal<v8::Value> maybe = |
| + descriptor->Get(context, v8_str(isolate, "maximum")); |
| + v8::Local<v8::Value> value; |
| + if (maybe.ToLocal(&value) && !value->IsUndefined()) { |
| + int64_t number; |
| + if (!value->IntegerValue(context).To(&number)) return; |
| + if (number < 0) { |
| + thrower.RangeError( |
| + "Descriptor property 'maximum' must not be negative"); |
| + return; |
| + } |
| + int num = static_cast<int>(number); |
| + if (num != number) { |
| + thrower.RangeError("Descriptor property 'maximum' too large"); |
| + return; |
| + } |
| + if (num < initial) { |
| + thrower.RangeError( |
| + "Descriptor property 'maximum' must not be smaller than 'initial'"); |
| + return; |
| + } |
| + maximum = Just(num); |
| + } |
| + } |
| + i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); |
| + i::Handle<i::JSFunction> table_cons( |
| + i_isolate->native_context()->wasm_table_constructor()); |
| + i::Handle<i::JSObject> table_obj = |
| + i_isolate->factory()->NewJSObject(table_cons); |
| + i::Handle<i::FixedArray> fixed_array = |
| + i_isolate->factory()->NewFixedArray(initial); |
| + i::Object* null = i_isolate->heap()->null_value(); |
| + for (int i = 0; i < initial; ++i) fixed_array->set(i, null); |
| + table_obj->SetInternalField(0, *fixed_array); |
| + table_obj->SetInternalField( |
| + 1, maximum.IsNothing() |
| + ? static_cast<i::Object*>(i_isolate->heap()->undefined_value()) |
| + : static_cast<i::Object*>(i::Smi::FromInt(maximum.ToChecked()))); |
| + 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(); |
| + v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); |
| + return_value.Set(Utils::ToLocal(table_obj)); |
| +} |
| +void WebAssemblyMemory(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| + v8::Isolate* isolate = args.GetIsolate(); |
| + HandleScope scope(isolate); |
| + ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate), |
| + "WebAssembly.Module()"); |
| + if (args.Length() < 1 || !args[0]->IsObject()) { |
| + thrower.TypeError("Argument 0 must be a table descriptor"); |
| + return; |
| + } |
| + Local<Context> context = isolate->GetCurrentContext(); |
| + Local<v8::Object> descriptor = args[0]->ToObject(context).ToLocalChecked(); |
| + // The descriptor's 'initial'. |
| + int initial; |
| + { |
| + v8::MaybeLocal<v8::Value> maybe = |
| + descriptor->Get(context, v8_str(isolate, "initial")); |
| + v8::Local<v8::Value> value; |
| + if (!maybe.ToLocal(&value)) return; |
| + int64_t number; |
| + if (!value->IntegerValue(context).To(&number)) return; |
| + if (number < 0) { |
| + thrower.RangeError("Descriptor property 'inital' must not be negative"); |
| + return; |
| + } |
| + initial = static_cast<int>(number); |
| + if (initial != number || initial > 65536) { |
| + thrower.RangeError( |
| + "Descriptor property 'initial' " |
| + "must not be larger than 65536 (4GiB)"); |
| + return; |
| + } |
| + } |
| + // The descriptor's 'maximum'. |
| + Maybe<int> maximum = Nothing<int>(); |
| + { |
| + v8::MaybeLocal<v8::Value> maybe = |
| + descriptor->Get(context, v8_str(isolate, "maximum")); |
| + v8::Local<v8::Value> value; |
| + if (maybe.ToLocal(&value) && !value->IsUndefined()) { |
| + int64_t number; |
| + if (!value->IntegerValue(context).To(&number)) return; |
| + if (number < 0) { |
| + thrower.RangeError( |
| + "Descriptor property 'maximum' must not be negative"); |
| + return; |
| + } |
| + int num = static_cast<int>(number); |
| + if (num != number || initial > 65536) { |
| + thrower.RangeError( |
| + "Descriptor property 'maximum' must not be larger than 65536 " |
| + "(4GiB)"); |
| + return; |
| + } |
| + if (num < initial) { |
| + thrower.RangeError( |
| + "Descriptor property 'maximum' must not be smaller than 'initial'"); |
| + return; |
| + } |
| + maximum = Just(num); |
| + } |
| + } |
| + i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); |
| + i::Handle<i::JSFunction> memory_cons( |
| + i_isolate->native_context()->wasm_memory_constructor()); |
| + i::Handle<i::JSObject> memory_obj = |
| + i_isolate->factory()->NewJSObject(memory_cons); |
| + i::Handle<i::JSArrayBuffer> buffer = |
| + i_isolate->factory()->NewJSArrayBuffer(i::SharedFlag::kNotShared); |
| + size_t size = static_cast<size_t>(i::wasm::WasmModule::kPageSize) * |
| + static_cast<size_t>(initial); |
| + i::JSArrayBuffer::SetupAllocatingData(buffer, i_isolate, size); |
| + memory_obj->SetInternalField(0, *buffer); |
| + memory_obj->SetInternalField( |
| + 1, maximum.IsNothing() |
| + ? static_cast<i::Object*>(i_isolate->heap()->undefined_value()) |
| + : static_cast<i::Object*>(i::Smi::FromInt(maximum.ToChecked()))); |
| + 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(); |
| + v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); |
| + return_value.Set(Utils::ToLocal(memory_obj)); |
| +} |
| +void WebAssemblyTableGetLength( |
| + const v8::FunctionCallbackInfo<v8::Value>& args) { |
| + // TODO(rossberg) |
| +} |
| +void WebAssemblyTableGrow(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| + // TODO(rossberg) |
| +} |
| +void WebAssemblyTableGet(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| + // TODO(rossberg) |
| +} |
| +void WebAssemblyTableSet(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| + // TODO(rossberg) |
| +} |
| +void WebAssemblyMemoryGrow(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| + // TODO(rossberg) |
| +} |
| +void WebAssemblyMemoryGetBuffer( |
| + const v8::FunctionCallbackInfo<v8::Value>& args) { |
| + v8::Isolate* isolate = args.GetIsolate(); |
| + Local<Context> context = isolate->GetCurrentContext(); |
| + i::Handle<i::Context> i_context = Utils::OpenHandle(*context); |
| + if (!BrandCheck(isolate, Utils::OpenHandle(*args.This()), |
| + i::Handle<i::Symbol>(i_context->wasm_memory_sym()), |
| + "Receiver is not a WebAssembly.Memory")) { |
| + 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> buffer(receiver->GetInternalField(0), i_isolate); |
| + DCHECK(buffer->IsJSArrayBuffer()); |
| + v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); |
| + return_value.Set(Utils::ToLocal(buffer)); |
| +} |
| } // namespace |
| // TODO(titzer): we use the API to create the function template because the |
| @@ -300,12 +525,9 @@ static i::Handle<i::FunctionTemplateInfo> NewTemplate(i::Isolate* i_isolate, |
| } |
| namespace internal { |
| -static Handle<String> v8_str(Isolate* isolate, const char* str) { |
| - return isolate->factory()->NewStringFromAsciiChecked(str); |
| -} |
| -static Handle<JSFunction> InstallFunc(Isolate* isolate, Handle<JSObject> object, |
| - const char* str, FunctionCallback func) { |
| +Handle<JSFunction> InstallFunc(Isolate* isolate, Handle<JSObject> object, |
| + const char* str, FunctionCallback func) { |
| Handle<String> name = v8_str(isolate, str); |
| Handle<FunctionTemplateInfo> temp = NewTemplate(isolate, func); |
| Handle<JSFunction> function = |
| @@ -316,44 +538,98 @@ static Handle<JSFunction> InstallFunc(Isolate* isolate, Handle<JSObject> object, |
| return function; |
| } |
| +Handle<JSFunction> InstallGetter(Isolate* isolate, Handle<JSObject> object, |
| + const char* str, FunctionCallback func) { |
| + Handle<String> name = v8_str(isolate, str); |
| + Handle<FunctionTemplateInfo> temp = NewTemplate(isolate, func); |
| + Handle<JSFunction> function = |
| + ApiNatives::InstantiateFunction(temp).ToHandleChecked(); |
| + v8::PropertyAttribute attributes = |
| + static_cast<v8::PropertyAttribute>(v8::DontDelete | v8::ReadOnly); |
| + Utils::ToLocal(object)->SetAccessorProperty(Utils::ToLocal(name), |
| + Utils::ToLocal(function), |
| + Local<Function>(), attributes); |
| + return function; |
| +} |
| + |
| void WasmJs::InstallWasmModuleSymbolIfNeeded(Isolate* isolate, |
| Handle<JSGlobalObject> global, |
| Handle<Context> context) { |
| if (!context->get(Context::WASM_MODULE_SYM_INDEX)->IsSymbol() || |
| !context->get(Context::WASM_INSTANCE_SYM_INDEX)->IsSymbol()) { |
| - Factory* factory = isolate->factory(); |
| - // Create private symbols. |
| - Handle<Symbol> module_sym = factory->NewPrivateSymbol(); |
| - Handle<Symbol> instance_sym = factory->NewPrivateSymbol(); |
| - context->set_wasm_module_sym(*module_sym); |
| - context->set_wasm_instance_sym(*instance_sym); |
| - |
| - // Bind the WebAssembly object. |
| - Handle<String> name = v8_str(isolate, "WebAssembly"); |
| - Handle<JSFunction> cons = factory->NewFunction(name); |
| - JSFunction::SetInstancePrototype( |
| - cons, Handle<Object>(context->initial_object_prototype(), isolate)); |
| - cons->shared()->set_instance_class_name(*name); |
| - Handle<JSObject> wasm_object = factory->NewJSObject(cons, TENURED); |
| - PropertyAttributes attributes = static_cast<PropertyAttributes>(DONT_ENUM); |
| - JSObject::AddProperty(global, name, wasm_object, attributes); |
| - |
| - // Install static methods on WebAssembly object. |
| - InstallFunc(isolate, wasm_object, "compile", WebAssemblyCompile); |
| - Handle<JSFunction> module_constructor = |
| - InstallFunc(isolate, wasm_object, "Module", WebAssemblyModule); |
| - Handle<JSFunction> instance_constructor = |
| - InstallFunc(isolate, wasm_object, "Instance", WebAssemblyInstance); |
| - i::Handle<i::Map> map = isolate->factory()->NewMap( |
| - i::JS_OBJECT_TYPE, i::JSObject::kHeaderSize + i::kPointerSize); |
| - module_constructor->set_prototype_or_initial_map(*map); |
| - map->SetConstructor(*module_constructor); |
| - |
| - context->set_wasm_module_constructor(*module_constructor); |
| - context->set_wasm_instance_constructor(*instance_constructor); |
| + InstallWasmMapsIfNeeded(isolate, isolate->native_context()); |
| + InstallWasmConstructors(isolate, isolate->global_object(), |
| + isolate->native_context()); |
| } |
| } |
| +void WasmJs::InstallWasmConstructors(Isolate* isolate, |
| + Handle<JSGlobalObject> global, |
| + Handle<Context> context) { |
| + Factory* factory = isolate->factory(); |
| + // Create private symbols. |
| + Handle<Symbol> module_sym = factory->NewPrivateSymbol(); |
| + Handle<Symbol> instance_sym = factory->NewPrivateSymbol(); |
| + Handle<Symbol> table_sym = factory->NewPrivateSymbol(); |
| + Handle<Symbol> memory_sym = factory->NewPrivateSymbol(); |
| + context->set_wasm_module_sym(*module_sym); |
| + context->set_wasm_instance_sym(*instance_sym); |
| + context->set_wasm_table_sym(*table_sym); |
| + context->set_wasm_memory_sym(*memory_sym); |
| + // Bind the WebAssembly object. |
| + Handle<String> name = v8_str(isolate, "WebAssembly"); |
| + Handle<JSFunction> cons = factory->NewFunction(name); |
| + JSFunction::SetInstancePrototype( |
| + cons, Handle<Object>(context->initial_object_prototype(), isolate)); |
| + cons->shared()->set_instance_class_name(*name); |
| + Handle<JSObject> wasm_object = factory->NewJSObject(cons, TENURED); |
| + PropertyAttributes attributes = static_cast<PropertyAttributes>(DONT_ENUM); |
| + JSObject::AddProperty(global, name, wasm_object, attributes); |
| + // Install static methods on WebAssembly object. |
| + InstallFunc(isolate, wasm_object, "compile", WebAssemblyCompile); |
| + Handle<JSFunction> module_constructor = |
|
titzer
2016/09/20 12:37:21
It's tough to see what's going in here exactly, bu
ahaas
2016/09/21 09:38:11
I restructured code now, but I don't think that it
titzer
2016/09/21 09:47:44
Ok, we can always take another crack at it later.
|
| + InstallFunc(isolate, wasm_object, "Module", WebAssemblyModule); |
| + Handle<JSFunction> instance_constructor = |
| + InstallFunc(isolate, wasm_object, "Instance", WebAssemblyInstance); |
| + Handle<JSFunction> table_constructor = |
| + InstallFunc(isolate, wasm_object, "Table", WebAssemblyTable); |
| + Handle<JSFunction> memory_constructor = |
| + InstallFunc(isolate, wasm_object, "Memory", WebAssemblyMemory); |
| + context->set_wasm_module_constructor(*module_constructor); |
| + context->set_wasm_instance_constructor(*instance_constructor); |
| + context->set_wasm_table_constructor(*table_constructor); |
| + context->set_wasm_memory_constructor(*memory_constructor); |
| + // Set up prototypes and instance maps. |
| + 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); |
| + JSFunction::SetInitialMap(module_constructor, map, module_proto); |
| + Handle<JSObject> table_proto = |
| + factory->NewJSObject(table_constructor, TENURED); |
| + map = isolate->factory()->NewMap( |
| + i::JS_OBJECT_TYPE, i::JSObject::kHeaderSize + 2 * i::kPointerSize); |
| + JSFunction::SetInitialMap(table_constructor, map, table_proto); |
| + Handle<JSObject> memory_proto = |
| + factory->NewJSObject(memory_constructor, TENURED); |
| + map = isolate->factory()->NewMap( |
| + i::JS_OBJECT_TYPE, i::JSObject::kHeaderSize + 2 * i::kPointerSize); |
| + JSFunction::SetInitialMap(memory_constructor, map, memory_proto); |
| + // Add prototype properties. |
| + JSObject::AddProperty(module_proto, isolate->factory()->constructor_string(), |
| + module_constructor, DONT_ENUM); |
| + JSObject::AddProperty(table_proto, isolate->factory()->constructor_string(), |
| + table_constructor, DONT_ENUM); |
| + InstallGetter(isolate, table_proto, "length", WebAssemblyTableGetLength); |
| + InstallFunc(isolate, table_proto, "grow", WebAssemblyTableGrow); |
| + InstallFunc(isolate, table_proto, "get", WebAssemblyTableGet); |
| + InstallFunc(isolate, table_proto, "set", WebAssemblyTableSet); |
| + JSObject::AddProperty(memory_proto, isolate->factory()->constructor_string(), |
| + memory_constructor, DONT_ENUM); |
| + InstallFunc(isolate, memory_proto, "grow", WebAssemblyMemoryGrow); |
| + InstallGetter(isolate, memory_proto, "buffer", WebAssemblyMemoryGetBuffer); |
| +} |
| + |
| void WasmJs::Install(Isolate* isolate, Handle<JSGlobalObject> global) { |
| if (!FLAG_expose_wasm && !FLAG_validate_asm) { |
| return; |
| @@ -363,7 +639,7 @@ void WasmJs::Install(Isolate* isolate, Handle<JSGlobalObject> global) { |
| // Setup wasm function map. |
| Handle<Context> context(global->native_context(), isolate); |
| - InstallWasmFunctionMapIfNeeded(isolate, context); |
| + InstallWasmMapsIfNeeded(isolate, context); |
| if (!FLAG_expose_wasm) { |
| return; |
| @@ -396,11 +672,11 @@ void WasmJs::Install(Isolate* isolate, Handle<JSGlobalObject> global) { |
| JSObject::AddProperty(wasm_object, name, value, attributes); |
| } |
| } |
| - InstallWasmModuleSymbolIfNeeded(isolate, global, context); |
| + InstallWasmConstructors(isolate, global, context); |
| } |
| -void WasmJs::InstallWasmFunctionMapIfNeeded(Isolate* isolate, |
| - Handle<Context> context) { |
| +void WasmJs::InstallWasmMapsIfNeeded(Isolate* isolate, |
| + Handle<Context> context) { |
| if (!context->get(Context::WASM_FUNCTION_MAP_INDEX)->IsMap()) { |
| // TODO(titzer): Move this to bootstrapper.cc?? |
| // TODO(titzer): Also make one for strict mode functions? |