summaryrefslogtreecommitdiff
path: root/deps/v8/src/wasm/wasm-js.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/wasm/wasm-js.cc')
-rw-r--r--deps/v8/src/wasm/wasm-js.cc475
1 files changed, 150 insertions, 325 deletions
diff --git a/deps/v8/src/wasm/wasm-js.cc b/deps/v8/src/wasm/wasm-js.cc
index b426d5bf3d..281c4e82e6 100644
--- a/deps/v8/src/wasm/wasm-js.cc
+++ b/deps/v8/src/wasm/wasm-js.cc
@@ -13,6 +13,7 @@
#include "src/factory.h"
#include "src/handles.h"
#include "src/isolate.h"
+#include "src/objects-inl.h"
#include "src/objects.h"
#include "src/parsing/parse-info.h"
@@ -35,6 +36,20 @@ namespace {
"Wasm compilation exceeds internal limits in this context for the provided " \
"arguments"
+// 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);
}
@@ -42,11 +57,26 @@ 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));
+}
bool IsCompilationAllowed(i::Isolate* isolate, ErrorThrower* thrower,
v8::Local<v8::Value> source, bool is_async) {
@@ -142,99 +172,12 @@ i::MaybeHandle<i::JSReceiver> GetSecondArgumentAsImports(
return i::Handle<i::JSReceiver>::cast(v8::Utils::OpenHandle(*obj));
}
-RawBuffer GetRawBufferSource(
- v8::Local<v8::Value> source, ErrorThrower* thrower) {
- const byte* start = nullptr;
- const byte* end = nullptr;
-
- if (source->IsArrayBuffer()) {
- // A raw array buffer was passed.
- Local<ArrayBuffer> buffer = Local<ArrayBuffer>::Cast(source);
- ArrayBuffer::Contents contents = buffer->GetContents();
-
- start = reinterpret_cast<const byte*>(contents.Data());
- end = start + contents.ByteLength();
-
- } else if (source->IsTypedArray()) {
- // A TypedArray was passed.
- Local<TypedArray> array = Local<TypedArray>::Cast(source);
- Local<ArrayBuffer> buffer = array->Buffer();
-
- ArrayBuffer::Contents contents = buffer->GetContents();
-
- start =
- reinterpret_cast<const byte*>(contents.Data()) + array->ByteOffset();
- end = start + array->ByteLength();
-
- } else {
- thrower->TypeError("Argument 0 must be a buffer source");
- }
- if (start == nullptr || end == start) {
- thrower->CompileError("BufferSource argument is empty");
- }
- return {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 BrandCheck(Isolate* isolate, 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);
- if (has_brand.IsNothing()) return false;
- return has_brand.ToChecked();
-}
-
-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);
- 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;
-}
-
+// 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;
@@ -242,40 +185,29 @@ 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;
- }
auto bytes = GetFirstArgumentAsBytes(args, &thrower);
- USE(bytes);
if (!IsCompilationAllowed(i_isolate, &thrower, args[0], true)) {
resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
return;
}
- i::MaybeHandle<i::JSObject> module_obj =
- CreateModuleObject(isolate, args[0], &thrower);
-
- if (thrower.error()) {
- resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
- } else {
- resolver->Resolve(context, Utils::ToLocal(module_obj.ToHandleChecked()));
- }
+ DCHECK(!thrower.error());
+ 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.
@@ -283,128 +215,61 @@ 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);
- USE(bytes);
if (!IsCompilationAllowed(i_isolate, &thrower, args[0], false)) return;
- i::MaybeHandle<i::JSObject> module_obj =
- CreateModuleObject(isolate, args[0], &thrower);
+ DCHECK(!thrower.error());
+ 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(isolate, 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();
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
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));
- }
+ auto maybe_module = GetFirstArgumentAsModule(args, &thrower);
+ 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();
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
-
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));
- }
+ auto maybe_module = GetFirstArgumentAsModule(args, &thrower);
+ 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());
v8::Isolate* isolate = args.GetIsolate();
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
-
ErrorThrower thrower(i_isolate, "WebAssembly.Module.customSections()");
- auto maybe_module = GetFirstArgumentAsModule(args, thrower);
+ auto maybe_module = GetFirstArgumentAsModule(args, &thrower);
+ if (thrower.error()) return;
if (args.Length() < 2) {
thrower.TypeError("Argument 1 must be a string");
@@ -417,25 +282,23 @@ 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();
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
-
ErrorThrower thrower(i_isolate, "WebAssembly.Instance()");
- auto maybe_module = GetFirstArgumentAsModule(args, thrower);
+ auto maybe_module = GetFirstArgumentAsModule(args, &thrower);
if (thrower.error()) return;
+
auto maybe_imports = GetSecondArgumentAsImports(args, &thrower);
if (!IsInstantiationAllowed(i_isolate, &thrower, args[0], maybe_imports,
false)) {
@@ -443,23 +306,22 @@ void WebAssemblyInstance(const v8::FunctionCallbackInfo<v8::Value>& args) {
}
DCHECK(!thrower.error());
- if (!maybe_module.is_null()) {
- MaybeLocal<Value> instance = InstantiateModuleImpl(
- i_isolate, maybe_module.ToHandleChecked(), args, &thrower);
- 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);
+ ErrorThrower thrower(i_isolate, "WebAssembly.instantiate()");
HandleScope scope(isolate);
- ErrorThrower thrower(i_isolate, "WebAssembly.instantiate()");
Local<Context> context = isolate->GetCurrentContext();
i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
@@ -485,8 +347,6 @@ void WebAssemblyInstantiate(const v8::FunctionCallbackInfo<v8::Value>& args) {
return;
}
- bool want_pair = !BrandCheck(
- isolate, first_arg, i::Handle<i::Symbol>(i_context->wasm_module_sym()));
auto maybe_imports = GetSecondArgumentAsImports(args, &thrower);
if (thrower.error()) {
resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
@@ -497,48 +357,21 @@ void WebAssemblyInstantiate(const v8::FunctionCallbackInfo<v8::Value>& args) {
resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
return;
}
- 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());
+ 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 {
+ // WebAssembly.instantiate(bytes, imports) -> {module, instance}
+ auto bytes = GetFirstArgumentAsBytes(args, &thrower);
+ if (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());
- resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
- } 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();
- }
- DCHECK(!retval.IsEmpty());
- resolver->Resolve(context, retval);
+ i::wasm::AsyncCompileAndInstantiate(i_isolate, promise, bytes,
+ maybe_imports);
}
}
@@ -569,11 +402,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;
@@ -599,7 +433,7 @@ void WebAssemblyTable(const v8::FunctionCallbackInfo<v8::Value>& args) {
int initial = 0;
if (!GetIntegerProperty(isolate, &thrower, context, descriptor,
v8_str(isolate, "initial"), &initial, 0,
- i::wasm::kV8MaxWasmTableSize)) {
+ i::FLAG_wasm_max_table_size)) {
return;
}
// The descriptor's 'maximum'.
@@ -615,7 +449,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);
@@ -625,9 +458,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;
@@ -638,7 +471,7 @@ void WebAssemblyMemory(const v8::FunctionCallbackInfo<v8::Value>& args) {
int initial = 0;
if (!GetIntegerProperty(isolate, &thrower, context, descriptor,
v8_str(isolate, "initial"), &initial, 0,
- i::wasm::kV8MaxWasmMemoryPages)) {
+ i::FLAG_wasm_max_mem_pages)) {
return;
}
// The descriptor's 'maximum'.
@@ -653,7 +486,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 =
@@ -670,10 +502,13 @@ void WebAssemblyMemory(const v8::FunctionCallbackInfo<v8::Value>& args) {
void WebAssemblyTableGetLength(
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.length()");
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_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;
}
@@ -683,17 +518,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();
+ 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(isolate, 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);
@@ -706,15 +544,13 @@ void WebAssemblyTableGrow(const v8::FunctionCallbackInfo<v8::Value>& args) {
int64_t max_size64 = receiver->maximum_length();
if (max_size64 < 0 ||
- max_size64 > static_cast<int64_t>(i::wasm::kV8MaxWasmTableSize)) {
- max_size64 = i::wasm::kV8MaxWasmTableSize;
+ max_size64 > static_cast<int64_t>(i::FLAG_wasm_max_table_size)) {
+ max_size64 = i::FLAG_wasm_max_table_size;
}
if (new_size64 < old_size || new_size64 > max_size64) {
- v8::Local<v8::Value> e = v8::Exception::RangeError(
- v8_str(isolate, new_size64 < old_size ? "trying to shrink table"
- : "maximum table size exceeded"));
- isolate->ThrowException(e);
+ thrower.RangeError(new_size64 < old_size ? "trying to shrink table"
+ : "maximum table size exceeded");
return;
}
@@ -736,17 +572,20 @@ 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(isolate, 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> array(receiver->functions(), i_isolate);
@@ -754,9 +593,7 @@ void WebAssemblyTableGet(const v8::FunctionCallbackInfo<v8::Value>& args) {
if (args.Length() > 0 && !args[0]->Int32Value(context).To(&i)) return;
v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
if (i < 0 || i >= array->length()) {
- v8::Local<v8::Value> e =
- v8::Exception::RangeError(v8_str(isolate, "index out of bounds"));
- isolate->ThrowException(e);
+ thrower.RangeError("index out of bounds");
return;
}
@@ -764,20 +601,21 @@ 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(isolate, 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;
}
if (args.Length() < 2) {
- v8::Local<v8::Value> e = v8::Exception::TypeError(
- v8_str(isolate, "Argument 1 must be null or a function"));
- isolate->ThrowException(e);
+ thrower.TypeError("Argument 1 must be null or a function");
return;
}
i::Handle<i::Object> value = Utils::OpenHandle(*args[1]);
@@ -785,9 +623,7 @@ void WebAssemblyTableSet(const v8::FunctionCallbackInfo<v8::Value>& args) {
(!value->IsJSFunction() ||
i::Handle<i::JSFunction>::cast(value)->code()->kind() !=
i::Code::JS_TO_WASM_FUNCTION)) {
- v8::Local<v8::Value> e = v8::Exception::TypeError(
- v8_str(isolate, "Argument 1 must be null or a WebAssembly function"));
- isolate->ThrowException(e);
+ thrower.TypeError("Argument 1 must be null or a WebAssembly function");
return;
}
@@ -797,9 +633,7 @@ void WebAssemblyTableSet(const v8::FunctionCallbackInfo<v8::Value>& args) {
int i;
if (!args[0]->Int32Value(context).To(&i)) return;
if (i < 0 || i >= array->length()) {
- v8::Local<v8::Value> e =
- v8::Exception::RangeError(v8_str(isolate, "index out of bounds"));
- isolate->ThrowException(e);
+ thrower.RangeError("index out of bounds");
return;
}
@@ -816,64 +650,65 @@ 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(isolate, 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;
}
int64_t delta_size = 0;
if (args.Length() < 1 || !args[0]->IntegerValue(context).To(&delta_size)) {
- v8::Local<v8::Value> e = v8::Exception::TypeError(
- v8_str(isolate, "Argument 0 required, must be numeric value of pages"));
- isolate->ThrowException(e);
+ thrower.TypeError("Argument 0 required, must be numeric value of pages");
return;
}
i::Handle<i::WasmMemoryObject> receiver =
i::Handle<i::WasmMemoryObject>::cast(Utils::OpenHandle(*args.This()));
int64_t max_size64 = receiver->maximum_pages();
if (max_size64 < 0 ||
- max_size64 > static_cast<int64_t>(i::wasm::kV8MaxWasmTableSize)) {
- max_size64 = i::wasm::kV8MaxWasmMemoryPages;
+ max_size64 > static_cast<int64_t>(i::FLAG_wasm_max_mem_pages)) {
+ max_size64 = i::FLAG_wasm_max_mem_pages;
}
i::Handle<i::JSArrayBuffer> old_buffer(receiver->buffer());
uint32_t old_size =
old_buffer->byte_length()->Number() / i::wasm::kSpecMaxWasmMemoryPages;
int64_t new_size64 = old_size + delta_size;
if (delta_size < 0 || max_size64 < new_size64 || new_size64 < old_size) {
- v8::Local<v8::Value> e = v8::Exception::RangeError(v8_str(
- isolate, new_size64 < old_size ? "trying to shrink memory"
- : "maximum memory size exceeded"));
- isolate->ThrowException(e);
+ thrower.RangeError(new_size64 < old_size ? "trying to shrink memory"
+ : "maximum memory size exceeded");
return;
}
- i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
int32_t ret = i::wasm::GrowWebAssemblyMemory(
i_isolate, receiver, static_cast<uint32_t>(delta_size));
if (ret == -1) {
- v8::Local<v8::Value> e = v8::Exception::RangeError(
- v8_str(isolate, "Unable to grow instance memory."));
- isolate->ThrowException(e);
+ thrower.RangeError("Unable to grow instance memory.");
return;
}
+ i::wasm::DetachWebAssemblyMemoryBuffer(i_isolate, old_buffer);
v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
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(isolate, 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;
}
- i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
i::Handle<i::WasmMemoryObject> receiver =
i::Handle<i::WasmMemoryObject>::cast(Utils::OpenHandle(*args.This()));
i::Handle<i::Object> buffer(receiver->buffer(), i_isolate);
@@ -1078,16 +913,6 @@ void WasmJs::Install(Isolate* isolate) {
runtime_error, attributes);
}
-static bool HasBrand(i::Handle<i::Object> value, i::Handle<i::Symbol> symbol) {
- if (value->IsJSObject()) {
- i::Handle<i::JSObject> object = i::Handle<i::JSObject>::cast(value);
- Maybe<bool> has_brand = i::JSObject::HasOwnProperty(object, symbol);
- if (has_brand.IsNothing()) return false;
- if (has_brand.ToChecked()) return true;
- }
- return false;
-}
-
bool WasmJs::IsWasmMemoryObject(Isolate* isolate, Handle<Object> value) {
i::Handle<i::Symbol> symbol(isolate->context()->wasm_memory_sym(), isolate);
return HasBrand(value, symbol);