| Index: src/wasm/wasm-js.cc
|
| diff --git a/src/wasm/wasm-js.cc b/src/wasm/wasm-js.cc
|
| index baec27d3cc5661af4d47b0a9bfc8d71c332c63ef..91d6c8a51c74d93443c808972aabc134ef58c4b3 100644
|
| --- a/src/wasm/wasm-js.cc
|
| +++ b/src/wasm/wasm-js.cc
|
| @@ -31,6 +31,20 @@ using v8::internal::wasm::ErrorThrower;
|
| namespace v8 {
|
|
|
| namespace {
|
| +// TODO(wasm): move brand check to the respective types, and don't throw
|
| +// in it, rather, use a provided ErrorThrower, or let caller handle it.
|
| +static bool HasBrand(i::Handle<i::Object> value, i::Handle<i::Symbol> sym) {
|
| + if (!value->IsJSObject()) return false;
|
| + i::Handle<i::JSObject> object = i::Handle<i::JSObject>::cast(value);
|
| + Maybe<bool> has_brand = i::JSObject::HasOwnProperty(object, sym);
|
| + return has_brand.FromMaybe(false);
|
| +}
|
| +
|
| +static bool BrandCheck(i::Handle<i::Object> value, i::Handle<i::Symbol> sym,
|
| + ErrorThrower* thrower, const char* msg) {
|
| + return HasBrand(value, sym) ? true : (thrower->TypeError("%s", msg), false);
|
| +}
|
| +
|
| i::Handle<i::String> v8_str(i::Isolate* isolate, const char* str) {
|
| return isolate->factory()->NewStringFromAsciiChecked(str);
|
| }
|
| @@ -38,17 +52,37 @@ 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;
|
| - size_t size() { return static_cast<size_t>(end - start); }
|
| -};
|
| +i::MaybeHandle<i::WasmModuleObject> GetFirstArgumentAsModule(
|
| + const v8::FunctionCallbackInfo<v8::Value>& args, ErrorThrower* thrower) {
|
| + v8::Isolate* isolate = args.GetIsolate();
|
| + if (args.Length() < 1) {
|
| + thrower->TypeError("Argument 0 must be a WebAssembly.Module");
|
| + return {};
|
| + }
|
| +
|
| + Local<Context> context = isolate->GetCurrentContext();
|
| + i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
|
| + if (!BrandCheck(Utils::OpenHandle(*args[0]),
|
| + i::handle(i_context->wasm_module_sym()), thrower,
|
| + "Argument 0 must be a WebAssembly.Module")) {
|
| + return {};
|
| + }
|
| +
|
| + Local<Object> module_obj = Local<Object>::Cast(args[0]);
|
| + return i::Handle<i::WasmModuleObject>::cast(
|
| + v8::Utils::OpenHandle(*module_obj));
|
| +}
|
| +
|
| +i::wasm::ModuleWireBytes GetFirstArgumentAsBytes(
|
| + const v8::FunctionCallbackInfo<v8::Value>& args, ErrorThrower* thrower) {
|
| + if (args.Length() < 1) {
|
| + thrower->TypeError("Argument 0 must be a buffer source");
|
| + return i::wasm::ModuleWireBytes(nullptr, nullptr);
|
| + }
|
|
|
| -RawBuffer GetRawBufferSource(
|
| - v8::Local<v8::Value> source, ErrorThrower* thrower) {
|
| const byte* start = nullptr;
|
| const byte* end = nullptr;
|
| -
|
| + v8::Local<v8::Value> source = args[0];
|
| if (source->IsArrayBuffer()) {
|
| // A raw array buffer was passed.
|
| Local<ArrayBuffer> buffer = Local<ArrayBuffer>::Cast(source);
|
| @@ -74,58 +108,29 @@ RawBuffer GetRawBufferSource(
|
| if (start == nullptr || end == start) {
|
| thrower->CompileError("BufferSource argument is empty");
|
| }
|
| - return {start, end};
|
| + // TODO(titzer): use the handle as well?
|
| + return i::wasm::ModuleWireBytes(start, end);
|
| }
|
|
|
| -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::WasmModuleObject>();
|
| -
|
| - DCHECK(source->IsArrayBuffer() || source->IsTypedArray());
|
| - return i::wasm::CreateModuleObjectFromBytes(
|
| - i_isolate, buffer.start, buffer.end, thrower, i::wasm::kWasmOrigin,
|
| - i::Handle<i::Script>::null(), i::Vector<const byte>::empty());
|
| -}
|
| -
|
| -static bool ValidateModule(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 false;
|
| -
|
| - DCHECK(source->IsArrayBuffer() || source->IsTypedArray());
|
| - return i::wasm::ValidateModuleBytes(i_isolate, buffer.start, buffer.end,
|
| - thrower,
|
| - i::wasm::ModuleOrigin::kWasmOrigin);
|
| -}
|
| -
|
| -// TODO(wasm): move brand check to the respective types, and don't throw
|
| -// in it, rather, use a provided ErrorThrower, or let caller handle it.
|
| -static bool HasBrand(i::Handle<i::Object> value, i::Handle<i::Symbol> sym) {
|
| - if (!value->IsJSObject()) return false;
|
| - i::Handle<i::JSObject> object = i::Handle<i::JSObject>::cast(value);
|
| - Maybe<bool> has_brand = i::JSObject::HasOwnProperty(object, sym);
|
| - return !has_brand.IsNothing() && has_brand.ToChecked();
|
| -}
|
| +i::MaybeHandle<i::JSReceiver> GetSecondArgumentAsImports(
|
| + const v8::FunctionCallbackInfo<v8::Value>& args, ErrorThrower* thrower) {
|
| + if (args.Length() < 2) return {};
|
| + if (args[1]->IsUndefined()) return {};
|
|
|
| -static bool BrandCheck(ErrorThrower* thrower, i::Handle<i::Object> value,
|
| - i::Handle<i::Symbol> sym, const char* msg) {
|
| - return HasBrand(value, sym) ? true : (thrower->TypeError("%s", msg), false);
|
| + if (!args[1]->IsObject()) {
|
| + thrower->TypeError("Argument 1 must be an object");
|
| + return {};
|
| + }
|
| + Local<Object> obj = Local<Object>::Cast(args[1]);
|
| + return i::Handle<i::JSReceiver>::cast(v8::Utils::OpenHandle(*obj));
|
| }
|
|
|
| +// WebAssembly.compile(bytes) -> Promise
|
| void WebAssemblyCompile(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| v8::Isolate* isolate = args.GetIsolate();
|
| + i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
| HandleScope scope(isolate);
|
| - ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate),
|
| - "WebAssembly.compile()");
|
| + ErrorThrower thrower(i_isolate, "WebAssembly.compile()");
|
|
|
| Local<Context> context = isolate->GetCurrentContext();
|
| v8::Local<v8::Promise::Resolver> resolver;
|
| @@ -133,34 +138,28 @@ void WebAssemblyCompile(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
|
| return_value.Set(resolver->GetPromise());
|
|
|
| - if (args.Length() < 1) {
|
| - thrower.TypeError("Argument 0 must be a buffer source");
|
| - resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
|
| - return;
|
| - }
|
| - i::MaybeHandle<i::JSObject> module_obj =
|
| - CreateModuleObject(isolate, args[0], &thrower);
|
| -
|
| + auto bytes = GetFirstArgumentAsBytes(args, &thrower);
|
| if (thrower.error()) {
|
| resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
|
| - } else {
|
| - resolver->Resolve(context, Utils::ToLocal(module_obj.ToHandleChecked()));
|
| + return;
|
| }
|
| + i::Handle<i::JSPromise> promise = Utils::OpenHandle(*resolver->GetPromise());
|
| + i::wasm::AsyncCompile(i_isolate, promise, bytes);
|
| }
|
|
|
| +// WebAssembly.validate(bytes) -> bool
|
| void WebAssemblyValidate(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| v8::Isolate* isolate = args.GetIsolate();
|
| + i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
| HandleScope scope(isolate);
|
| - ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate),
|
| - "WebAssembly.validate()");
|
| + ErrorThrower thrower(i_isolate, "WebAssembly.validate()");
|
|
|
| - if (args.Length() < 1) {
|
| - thrower.TypeError("Argument 0 must be a buffer source");
|
| - return;
|
| - }
|
| + auto bytes = GetFirstArgumentAsBytes(args, &thrower);
|
|
|
| v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
|
| - if (ValidateModule(isolate, args[0], &thrower)) {
|
| + if (!thrower.error() &&
|
| + i::wasm::SyncValidate(reinterpret_cast<i::Isolate*>(isolate), &thrower,
|
| + bytes)) {
|
| return_value.Set(v8::True(isolate));
|
| } else {
|
| if (thrower.wasm_error()) thrower.Reify(); // Clear error.
|
| @@ -168,84 +167,25 @@ void WebAssemblyValidate(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| }
|
| }
|
|
|
| +// new WebAssembly.Module(bytes) -> WebAssembly.Module
|
| void WebAssemblyModule(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| v8::Isolate* isolate = args.GetIsolate();
|
| + i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
| HandleScope scope(isolate);
|
| - ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate),
|
| - "WebAssembly.Module()");
|
| + ErrorThrower thrower(i_isolate, "WebAssembly.Module()");
|
|
|
| - if (args.Length() < 1) {
|
| - thrower.TypeError("Argument 0 must be a buffer source");
|
| - return;
|
| - }
|
| + auto bytes = GetFirstArgumentAsBytes(args, &thrower);
|
| + if (thrower.error()) return;
|
|
|
| - i::MaybeHandle<i::JSObject> module_obj =
|
| - CreateModuleObject(isolate, args[0], &thrower);
|
| + i::MaybeHandle<i::Object> module_obj =
|
| + i::wasm::SyncCompile(i_isolate, &thrower, bytes);
|
| if (module_obj.is_null()) return;
|
|
|
| v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
|
| return_value.Set(Utils::ToLocal(module_obj.ToHandleChecked()));
|
| }
|
|
|
| -MaybeLocal<Value> InstantiateModuleImpl(
|
| - i::Isolate* i_isolate, i::Handle<i::WasmModuleObject> i_module_obj,
|
| - const v8::FunctionCallbackInfo<v8::Value>& args, ErrorThrower* thrower) {
|
| - // It so happens that in both the WebAssembly.instantiate, as well as
|
| - // WebAssembly.Instance ctor, the positions of the ffi object and memory
|
| - // are the same. If that changes later, we refactor the consts into
|
| - // parameters.
|
| - static const int kFfiOffset = 1;
|
| -
|
| - MaybeLocal<Value> nothing;
|
| - i::Handle<i::JSReceiver> ffi = i::Handle<i::JSObject>::null();
|
| - // This is a first - level validation of the argument. If present, we only
|
| - // check its type. {Instantiate} will further check that if the module
|
| - // has imports, the argument must be present, as well as piecemeal
|
| - // import satisfaction.
|
| - if (args.Length() > kFfiOffset && !args[kFfiOffset]->IsUndefined()) {
|
| - if (!args[kFfiOffset]->IsObject()) {
|
| - thrower->TypeError("Argument %d must be an object", kFfiOffset);
|
| - return nothing;
|
| - }
|
| - Local<Object> obj = Local<Object>::Cast(args[kFfiOffset]);
|
| - ffi = i::Handle<i::JSReceiver>::cast(v8::Utils::OpenHandle(*obj));
|
| - }
|
| -
|
| - i::MaybeHandle<i::JSObject> instance =
|
| - i::wasm::WasmModule::Instantiate(i_isolate, thrower, i_module_obj, ffi);
|
| - if (instance.is_null()) {
|
| - if (!thrower->error())
|
| - thrower->RuntimeError("Could not instantiate module");
|
| - return nothing;
|
| - }
|
| - DCHECK(!i_isolate->has_pending_exception());
|
| - return Utils::ToLocal(instance.ToHandleChecked());
|
| -}
|
| -
|
| -namespace {
|
| -i::MaybeHandle<i::WasmModuleObject> GetFirstArgumentAsModule(
|
| - const v8::FunctionCallbackInfo<v8::Value>& args, ErrorThrower* thrower) {
|
| - v8::Isolate* isolate = args.GetIsolate();
|
| - i::MaybeHandle<i::WasmModuleObject> nothing;
|
| - if (args.Length() < 1) {
|
| - thrower->TypeError("Argument 0 must be a WebAssembly.Module");
|
| - return nothing;
|
| - }
|
| -
|
| - Local<Context> context = isolate->GetCurrentContext();
|
| - i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
|
| - if (!BrandCheck(thrower, Utils::OpenHandle(*args[0]),
|
| - i::Handle<i::Symbol>(i_context->wasm_module_sym()),
|
| - "Argument 0 must be a WebAssembly.Module")) {
|
| - return nothing;
|
| - }
|
| -
|
| - Local<Object> module_obj = Local<Object>::Cast(args[0]);
|
| - return i::Handle<i::WasmModuleObject>::cast(
|
| - v8::Utils::OpenHandle(*module_obj));
|
| -}
|
| -} // namespace
|
| -
|
| +// WebAssembly.Module.imports(module) -> Array<Import>
|
| void WebAssemblyModuleImports(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| HandleScope scope(args.GetIsolate());
|
| v8::Isolate* isolate = args.GetIsolate();
|
| @@ -253,14 +193,12 @@ void WebAssemblyModuleImports(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| ErrorThrower thrower(i_isolate, "WebAssembly.Module.imports()");
|
|
|
| auto maybe_module = GetFirstArgumentAsModule(args, &thrower);
|
| -
|
| - if (!maybe_module.is_null()) {
|
| - auto imports =
|
| - i::wasm::GetImports(i_isolate, maybe_module.ToHandleChecked());
|
| - args.GetReturnValue().Set(Utils::ToLocal(imports));
|
| - }
|
| + if (thrower.error()) return;
|
| + auto imports = i::wasm::GetImports(i_isolate, maybe_module.ToHandleChecked());
|
| + args.GetReturnValue().Set(Utils::ToLocal(imports));
|
| }
|
|
|
| +// WebAssembly.Module.exports(module) -> Array<Export>
|
| void WebAssemblyModuleExports(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| HandleScope scope(args.GetIsolate());
|
| v8::Isolate* isolate = args.GetIsolate();
|
| @@ -268,14 +206,12 @@ void WebAssemblyModuleExports(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| ErrorThrower thrower(i_isolate, "WebAssembly.Module.exports()");
|
|
|
| auto maybe_module = GetFirstArgumentAsModule(args, &thrower);
|
| -
|
| - if (!maybe_module.is_null()) {
|
| - auto exports =
|
| - i::wasm::GetExports(i_isolate, maybe_module.ToHandleChecked());
|
| - args.GetReturnValue().Set(Utils::ToLocal(exports));
|
| - }
|
| + if (thrower.error()) return;
|
| + auto exports = i::wasm::GetExports(i_isolate, maybe_module.ToHandleChecked());
|
| + args.GetReturnValue().Set(Utils::ToLocal(exports));
|
| }
|
|
|
| +// WebAssembly.Module.customSections(module, name) -> Array<Section>
|
| void WebAssemblyModuleCustomSections(
|
| const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| HandleScope scope(args.GetIsolate());
|
| @@ -284,6 +220,7 @@ void WebAssemblyModuleCustomSections(
|
| ErrorThrower thrower(i_isolate, "WebAssembly.Module.customSections()");
|
|
|
| auto maybe_module = GetFirstArgumentAsModule(args, &thrower);
|
| + if (thrower.error()) return;
|
|
|
| if (args.Length() < 2) {
|
| thrower.TypeError("Argument 1 must be a string");
|
| @@ -296,16 +233,14 @@ void WebAssemblyModuleCustomSections(
|
| return;
|
| }
|
|
|
| - if (!maybe_module.is_null()) {
|
| - auto custom_sections =
|
| - i::wasm::GetCustomSections(i_isolate, maybe_module.ToHandleChecked(),
|
| - i::Handle<i::String>::cast(name), &thrower);
|
| - if (!thrower.error()) {
|
| - args.GetReturnValue().Set(Utils::ToLocal(custom_sections));
|
| - }
|
| - }
|
| + auto custom_sections =
|
| + i::wasm::GetCustomSections(i_isolate, maybe_module.ToHandleChecked(),
|
| + i::Handle<i::String>::cast(name), &thrower);
|
| + if (thrower.error()) return;
|
| + args.GetReturnValue().Set(Utils::ToLocal(custom_sections));
|
| }
|
|
|
| +// new WebAssembly.Instance(module, imports) -> WebAssembly.Instance
|
| void WebAssemblyInstance(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| HandleScope scope(args.GetIsolate());
|
| v8::Isolate* isolate = args.GetIsolate();
|
| @@ -313,19 +248,21 @@ void WebAssemblyInstance(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| ErrorThrower thrower(i_isolate, "WebAssembly.Instance()");
|
|
|
| auto maybe_module = GetFirstArgumentAsModule(args, &thrower);
|
| + if (thrower.error()) return;
|
|
|
| - if (!maybe_module.is_null()) {
|
| - MaybeLocal<Value> instance = InstantiateModuleImpl(
|
| - i_isolate, maybe_module.ToHandleChecked(), args, &thrower);
|
| + auto maybe_imports = GetSecondArgumentAsImports(args, &thrower);
|
| + if (thrower.error()) return;
|
|
|
| - if (instance.IsEmpty()) {
|
| - DCHECK(thrower.error());
|
| - return;
|
| - }
|
| - args.GetReturnValue().Set(instance.ToLocalChecked());
|
| - }
|
| + i::MaybeHandle<i::Object> instance_object = i::wasm::SyncInstantiate(
|
| + i_isolate, &thrower, maybe_module.ToHandleChecked(), maybe_imports,
|
| + i::MaybeHandle<i::JSArrayBuffer>());
|
| + if (instance_object.is_null()) return;
|
| + args.GetReturnValue().Set(Utils::ToLocal(instance_object.ToHandleChecked()));
|
| }
|
|
|
| +// WebAssembly.instantiate(module, imports) -> WebAssembly.Instance
|
| +// WebAssembly.instantiate(bytes, imports) ->
|
| +// {module: WebAssembly.Module, instance: WebAssembly.Instance}
|
| void WebAssemblyInstantiate(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| v8::Isolate* isolate = args.GetIsolate();
|
| i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
| @@ -356,50 +293,28 @@ void WebAssemblyInstantiate(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
|
| return;
|
| }
|
| - bool want_pair =
|
| - !HasBrand(first_arg, i::Handle<i::Symbol>(i_context->wasm_module_sym()));
|
| - i::Handle<i::WasmModuleObject> module_obj;
|
| - if (want_pair) {
|
| - i::MaybeHandle<i::WasmModuleObject> maybe_module_obj =
|
| - CreateModuleObject(isolate, args[0], &thrower);
|
| - if (!maybe_module_obj.ToHandle(&module_obj)) {
|
| - DCHECK(thrower.error());
|
| - resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
|
| - return;
|
| - }
|
| - } else {
|
| - module_obj = i::Handle<i::WasmModuleObject>::cast(first_arg);
|
| - }
|
| - DCHECK(!module_obj.is_null());
|
| - MaybeLocal<Value> instance =
|
| - InstantiateModuleImpl(i_isolate, module_obj, args, &thrower);
|
| - if (instance.IsEmpty()) {
|
| - DCHECK(thrower.error());
|
| +
|
| + auto maybe_imports = GetSecondArgumentAsImports(args, &thrower);
|
| + if (thrower.error()) {
|
| resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
|
| + return;
|
| + }
|
| + i::Handle<i::JSPromise> promise = Utils::OpenHandle(*resolver->GetPromise());
|
| +
|
| + if (HasBrand(first_arg, i::Handle<i::Symbol>(i_context->wasm_module_sym()))) {
|
| + // WebAssembly.instantiate(module, imports) -> WebAssembly.Instance
|
| + auto module_object = GetFirstArgumentAsModule(args, &thrower);
|
| + i::wasm::AsyncInstantiate(i_isolate, promise,
|
| + module_object.ToHandleChecked(), maybe_imports);
|
| } else {
|
| - DCHECK(!thrower.error());
|
| - Local<Value> retval;
|
| - if (want_pair) {
|
| - i::Handle<i::JSFunction> object_function = i::Handle<i::JSFunction>(
|
| - i_isolate->native_context()->object_function(), i_isolate);
|
| -
|
| - i::Handle<i::JSObject> i_retval =
|
| - i_isolate->factory()->NewJSObject(object_function, i::TENURED);
|
| - i::Handle<i::String> module_property_name =
|
| - i_isolate->factory()->InternalizeUtf8String("module");
|
| - i::Handle<i::String> instance_property_name =
|
| - i_isolate->factory()->InternalizeUtf8String("instance");
|
| - i::JSObject::AddProperty(i_retval, module_property_name, module_obj,
|
| - i::NONE);
|
| - i::JSObject::AddProperty(i_retval, instance_property_name,
|
| - Utils::OpenHandle(*instance.ToLocalChecked()),
|
| - i::NONE);
|
| - retval = Utils::ToLocal(i_retval);
|
| - } else {
|
| - retval = instance.ToLocalChecked();
|
| + // WebAssembly.instantiate(bytes, imports) -> {module, instance}
|
| + auto bytes = GetFirstArgumentAsBytes(args, &thrower);
|
| + if (thrower.error()) {
|
| + resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
|
| + return;
|
| }
|
| - DCHECK(!retval.IsEmpty());
|
| - resolver->Resolve(context, retval);
|
| + i::wasm::AsyncCompileAndInstantiate(i_isolate, promise, bytes,
|
| + maybe_imports);
|
| }
|
| }
|
|
|
| @@ -430,11 +345,12 @@ bool GetIntegerProperty(v8::Isolate* isolate, ErrorThrower* thrower,
|
| return false;
|
| }
|
|
|
| +// new WebAssembly.Table(args) -> WebAssembly.Table
|
| void WebAssemblyTable(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| v8::Isolate* isolate = args.GetIsolate();
|
| + i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
| HandleScope scope(isolate);
|
| - ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate),
|
| - "WebAssembly.Module()");
|
| + ErrorThrower thrower(i_isolate, "WebAssembly.Module()");
|
| if (args.Length() < 1 || !args[0]->IsObject()) {
|
| thrower.TypeError("Argument 0 must be a table descriptor");
|
| return;
|
| @@ -476,7 +392,6 @@ void WebAssemblyTable(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| }
|
| }
|
|
|
| - i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
| i::Handle<i::FixedArray> fixed_array;
|
| i::Handle<i::JSObject> table_obj =
|
| i::WasmTableObject::New(i_isolate, initial, maximum, &fixed_array);
|
| @@ -486,9 +401,9 @@ void WebAssemblyTable(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
|
|
| void WebAssemblyMemory(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| v8::Isolate* isolate = args.GetIsolate();
|
| + i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
| HandleScope scope(isolate);
|
| - ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate),
|
| - "WebAssembly.Memory()");
|
| + ErrorThrower thrower(i_isolate, "WebAssembly.Memory()");
|
| if (args.Length() < 1 || !args[0]->IsObject()) {
|
| thrower.TypeError("Argument 0 must be a memory descriptor");
|
| return;
|
| @@ -514,7 +429,6 @@ void WebAssemblyMemory(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| return;
|
| }
|
| }
|
| - i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
| size_t size = static_cast<size_t>(i::wasm::WasmModule::kPageSize) *
|
| static_cast<size_t>(initial);
|
| i::Handle<i::JSArrayBuffer> buffer =
|
| @@ -531,12 +445,13 @@ void WebAssemblyMemory(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| void WebAssemblyTableGetLength(
|
| const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| v8::Isolate* isolate = args.GetIsolate();
|
| - ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate),
|
| - "WebAssembly.Table.length()");
|
| + i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
| + HandleScope scope(isolate);
|
| + ErrorThrower thrower(i_isolate, "WebAssembly.Table.length()");
|
| Local<Context> context = isolate->GetCurrentContext();
|
| i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
|
| - if (!BrandCheck(&thrower, Utils::OpenHandle(*args.This()),
|
| - i::Handle<i::Symbol>(i_context->wasm_table_sym()),
|
| + if (!BrandCheck(Utils::OpenHandle(*args.This()),
|
| + i::Handle<i::Symbol>(i_context->wasm_table_sym()), &thrower,
|
| "Receiver is not a WebAssembly.Table")) {
|
| return;
|
| }
|
| @@ -546,19 +461,20 @@ void WebAssemblyTableGetLength(
|
| v8::Number::New(isolate, receiver->current_length()));
|
| }
|
|
|
| +// WebAssembly.Table.grow(num) -> num
|
| void WebAssemblyTableGrow(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| v8::Isolate* isolate = args.GetIsolate();
|
| - ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate),
|
| - "WebAssembly.Table.grow()");
|
| + i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
| + HandleScope scope(isolate);
|
| + ErrorThrower thrower(i_isolate, "WebAssembly.Table.grow()");
|
| Local<Context> context = isolate->GetCurrentContext();
|
| i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
|
| - if (!BrandCheck(&thrower, Utils::OpenHandle(*args.This()),
|
| - i::Handle<i::Symbol>(i_context->wasm_table_sym()),
|
| + if (!BrandCheck(Utils::OpenHandle(*args.This()),
|
| + i::Handle<i::Symbol>(i_context->wasm_table_sym()), &thrower,
|
| "Receiver is not a WebAssembly.Table")) {
|
| return;
|
| }
|
|
|
| - i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
| auto receiver =
|
| i::Handle<i::WasmTableObject>::cast(Utils::OpenHandle(*args.This()));
|
| i::Handle<i::FixedArray> old_array(receiver->functions(), i_isolate);
|
| @@ -599,14 +515,16 @@ void WebAssemblyTableGrow(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| return_value.Set(old_size);
|
| }
|
|
|
| +// WebAssembly.Table.get(num) -> JSFunction
|
| void WebAssemblyTableGet(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| v8::Isolate* isolate = args.GetIsolate();
|
| i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
| + HandleScope scope(isolate);
|
| ErrorThrower thrower(i_isolate, "WebAssembly.Table.get()");
|
| Local<Context> context = isolate->GetCurrentContext();
|
| i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
|
| - if (!BrandCheck(&thrower, Utils::OpenHandle(*args.This()),
|
| - i::Handle<i::Symbol>(i_context->wasm_table_sym()),
|
| + if (!BrandCheck(Utils::OpenHandle(*args.This()),
|
| + i::Handle<i::Symbol>(i_context->wasm_table_sym()), &thrower,
|
| "Receiver is not a WebAssembly.Table")) {
|
| return;
|
| }
|
| @@ -626,14 +544,16 @@ void WebAssemblyTableGet(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| return_value.Set(Utils::ToLocal(value));
|
| }
|
|
|
| +// WebAssembly.Table.set(num, JSFunction)
|
| void WebAssemblyTableSet(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| v8::Isolate* isolate = args.GetIsolate();
|
| i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
| + HandleScope scope(isolate);
|
| ErrorThrower thrower(i_isolate, "WebAssembly.Table.set()");
|
| Local<Context> context = isolate->GetCurrentContext();
|
| i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
|
| - if (!BrandCheck(&thrower, Utils::OpenHandle(*args.This()),
|
| - i::Handle<i::Symbol>(i_context->wasm_table_sym()),
|
| + if (!BrandCheck(Utils::OpenHandle(*args.This()),
|
| + i::Handle<i::Symbol>(i_context->wasm_table_sym()), &thrower,
|
| "Receiver is not a WebAssembly.Table")) {
|
| return;
|
| }
|
| @@ -673,14 +593,16 @@ void WebAssemblyTableSet(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| i::Handle<i::FixedArray>::cast(array)->set(i, *value);
|
| }
|
|
|
| +// WebAssembly.Memory.grow(num) -> num
|
| void WebAssemblyMemoryGrow(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| v8::Isolate* isolate = args.GetIsolate();
|
| i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
| + HandleScope scope(isolate);
|
| ErrorThrower thrower(i_isolate, "WebAssembly.Memory.grow()");
|
| Local<Context> context = isolate->GetCurrentContext();
|
| i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
|
| - if (!BrandCheck(&thrower, Utils::OpenHandle(*args.This()),
|
| - i::Handle<i::Symbol>(i_context->wasm_memory_sym()),
|
| + if (!BrandCheck(Utils::OpenHandle(*args.This()),
|
| + i::Handle<i::Symbol>(i_context->wasm_memory_sym()), &thrower,
|
| "Receiver is not a WebAssembly.Memory")) {
|
| return;
|
| }
|
| @@ -715,15 +637,17 @@ void WebAssemblyMemoryGrow(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| return_value.Set(ret);
|
| }
|
|
|
| +// WebAssembly.Memory.buffer -> ArrayBuffer
|
| void WebAssemblyMemoryGetBuffer(
|
| const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| v8::Isolate* isolate = args.GetIsolate();
|
| i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
| + HandleScope scope(isolate);
|
| ErrorThrower thrower(i_isolate, "WebAssembly.Memory.buffer");
|
| Local<Context> context = isolate->GetCurrentContext();
|
| i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
|
| - if (!BrandCheck(&thrower, Utils::OpenHandle(*args.This()),
|
| - i::Handle<i::Symbol>(i_context->wasm_memory_sym()),
|
| + if (!BrandCheck(Utils::OpenHandle(*args.This()),
|
| + i::Handle<i::Symbol>(i_context->wasm_memory_sym()), &thrower,
|
| "Receiver is not a WebAssembly.Memory")) {
|
| return;
|
| }
|
|
|