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; |
} |