Commit df834f3f authored by titzer's avatar titzer Committed by Commit bot

[wasm] Split the compilation and instantiation API into sync and async methods.

This makes it easier to implement asynchronous compilation by hiding all the implementation details of both synchronous and asynchronous compilation within wasm-module.cc, whereas before the code in wasm-js.cc actually implemented asynchronous compilation in terms of synchronous.

BUG=

Review-Url: https://codereview.chromium.org/2695813005
Cr-Commit-Position: refs/heads/master@{#43310}
parent db624fc4
...@@ -7599,11 +7599,8 @@ MaybeLocal<WasmCompiledModule> WasmCompiledModule::Compile(Isolate* isolate, ...@@ -7599,11 +7599,8 @@ MaybeLocal<WasmCompiledModule> WasmCompiledModule::Compile(Isolate* isolate,
size_t length) { size_t length) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
i::wasm::ErrorThrower thrower(i_isolate, "WasmCompiledModule::Deserialize()"); i::wasm::ErrorThrower thrower(i_isolate, "WasmCompiledModule::Deserialize()");
i::MaybeHandle<i::JSObject> maybe_compiled = i::MaybeHandle<i::JSObject> maybe_compiled = i::wasm::SyncCompile(
i::wasm::CreateModuleObjectFromBytes( i_isolate, &thrower, i::wasm::ModuleWireBytes(start, start + length));
i_isolate, start, start + length, &thrower,
i::wasm::ModuleOrigin::kWasmOrigin, i::Handle<i::Script>::null(),
i::Vector<const uint8_t>::empty());
if (maybe_compiled.is_null()) return MaybeLocal<WasmCompiledModule>(); if (maybe_compiled.is_null()) return MaybeLocal<WasmCompiledModule>();
return Local<WasmCompiledModule>::Cast( return Local<WasmCompiledModule>::Cast(
Utils::ToLocal(maybe_compiled.ToHandleChecked())); Utils::ToLocal(maybe_compiled.ToHandleChecked()));
......
...@@ -110,7 +110,8 @@ class RegisteredExtension { ...@@ -110,7 +110,8 @@ class RegisteredExtension {
V(Proxy, JSProxy) \ V(Proxy, JSProxy) \
V(NativeWeakMap, JSWeakMap) \ V(NativeWeakMap, JSWeakMap) \
V(debug::GeneratorObject, JSGeneratorObject) \ V(debug::GeneratorObject, JSGeneratorObject) \
V(debug::Script, Script) V(debug::Script, Script) \
V(Promise, JSPromise)
class Utils { class Utils {
public: public:
......
...@@ -188,9 +188,10 @@ MaybeHandle<FixedArray> AsmJs::CompileAsmViaWasm(CompilationInfo* info) { ...@@ -188,9 +188,10 @@ MaybeHandle<FixedArray> AsmJs::CompileAsmViaWasm(CompilationInfo* info) {
base::ElapsedTimer compile_timer; base::ElapsedTimer compile_timer;
compile_timer.Start(); compile_timer.Start();
MaybeHandle<JSObject> compiled = wasm::CreateModuleObjectFromBytes( MaybeHandle<JSObject> compiled = SyncCompileTranslatedAsmJs(
info->isolate(), module->begin(), module->end(), &thrower, info->isolate(), &thrower,
internal::wasm::kAsmJsOrigin, info->script(), asm_offsets_vec); wasm::ModuleWireBytes(module->begin(), module->end()), info->script(),
asm_offsets_vec);
DCHECK(!compiled.is_null()); DCHECK(!compiled.is_null());
double compile_time = compile_timer.Elapsed().InMillisecondsF(); double compile_time = compile_timer.Elapsed().InMillisecondsF();
DCHECK_GE(module->end(), module->begin()); DCHECK_GE(module->end(), module->begin());
...@@ -276,8 +277,7 @@ MaybeHandle<Object> AsmJs::InstantiateAsmWasm(i::Isolate* isolate, ...@@ -276,8 +277,7 @@ MaybeHandle<Object> AsmJs::InstantiateAsmWasm(i::Isolate* isolate,
} }
i::MaybeHandle<i::Object> maybe_module_object = i::MaybeHandle<i::Object> maybe_module_object =
i::wasm::WasmModule::Instantiate(isolate, &thrower, module, ffi_object, i::wasm::SyncInstantiate(isolate, &thrower, module, ffi_object, memory);
memory);
if (maybe_module_object.is_null()) { if (maybe_module_object.is_null()) {
return MaybeHandle<Object>(); return MaybeHandle<Object>();
} }
......
...@@ -1624,10 +1624,8 @@ MaybeHandle<JSObject> ValueDeserializer::ReadWasmModule() { ...@@ -1624,10 +1624,8 @@ MaybeHandle<JSObject> ValueDeserializer::ReadWasmModule() {
MaybeHandle<JSObject> result; MaybeHandle<JSObject> result;
{ {
wasm::ErrorThrower thrower(isolate_, "ValueDeserializer::ReadWasmModule"); wasm::ErrorThrower thrower(isolate_, "ValueDeserializer::ReadWasmModule");
result = wasm::CreateModuleObjectFromBytes( result = wasm::SyncCompile(isolate_, &thrower,
isolate_, wire_bytes.begin(), wire_bytes.end(), &thrower, wasm::ModuleWireBytes(wire_bytes));
wasm::ModuleOrigin::kWasmOrigin, Handle<Script>::null(),
Vector<const byte>::empty());
} }
RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate_, JSObject); RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate_, JSObject);
return result; return result;
......
...@@ -31,6 +31,20 @@ using v8::internal::wasm::ErrorThrower; ...@@ -31,6 +31,20 @@ using v8::internal::wasm::ErrorThrower;
namespace v8 { namespace v8 {
namespace { 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) { i::Handle<i::String> v8_str(i::Isolate* isolate, const char* str) {
return isolate->factory()->NewStringFromAsciiChecked(str); return isolate->factory()->NewStringFromAsciiChecked(str);
} }
...@@ -38,17 +52,37 @@ Local<String> v8_str(Isolate* isolate, const char* 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)); return Utils::ToLocal(v8_str(reinterpret_cast<i::Isolate*>(isolate), str));
} }
struct RawBuffer { i::MaybeHandle<i::WasmModuleObject> GetFirstArgumentAsModule(
const byte* start; const v8::FunctionCallbackInfo<v8::Value>& args, ErrorThrower* thrower) {
const byte* end; v8::Isolate* isolate = args.GetIsolate();
size_t size() { return static_cast<size_t>(end - start); } 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* start = nullptr;
const byte* end = nullptr; const byte* end = nullptr;
v8::Local<v8::Value> source = args[0];
if (source->IsArrayBuffer()) { if (source->IsArrayBuffer()) {
// A raw array buffer was passed. // A raw array buffer was passed.
Local<ArrayBuffer> buffer = Local<ArrayBuffer>::Cast(source); Local<ArrayBuffer> buffer = Local<ArrayBuffer>::Cast(source);
...@@ -74,58 +108,29 @@ RawBuffer GetRawBufferSource( ...@@ -74,58 +108,29 @@ RawBuffer GetRawBufferSource(
if (start == nullptr || end == start) { if (start == nullptr || end == start) {
thrower->CompileError("BufferSource argument is empty"); 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( i::MaybeHandle<i::JSReceiver> GetSecondArgumentAsImports(
v8::Isolate* isolate, const v8::Local<v8::Value> source, const v8::FunctionCallbackInfo<v8::Value>& args, ErrorThrower* thrower) {
ErrorThrower* thrower) { if (args.Length() < 2) return {};
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); if (args[1]->IsUndefined()) return {};
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();
}
static bool BrandCheck(ErrorThrower* thrower, i::Handle<i::Object> value, if (!args[1]->IsObject()) {
i::Handle<i::Symbol> sym, const char* msg) { thrower->TypeError("Argument 1 must be an object");
return HasBrand(value, sym) ? true : (thrower->TypeError("%s", msg), false); 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) { void WebAssemblyCompile(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Isolate* isolate = args.GetIsolate(); v8::Isolate* isolate = args.GetIsolate();
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
HandleScope scope(isolate); HandleScope scope(isolate);
ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate), ErrorThrower thrower(i_isolate, "WebAssembly.compile()");
"WebAssembly.compile()");
Local<Context> context = isolate->GetCurrentContext(); Local<Context> context = isolate->GetCurrentContext();
v8::Local<v8::Promise::Resolver> resolver; v8::Local<v8::Promise::Resolver> resolver;
...@@ -133,34 +138,28 @@ void WebAssemblyCompile(const v8::FunctionCallbackInfo<v8::Value>& args) { ...@@ -133,34 +138,28 @@ void WebAssemblyCompile(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
return_value.Set(resolver->GetPromise()); return_value.Set(resolver->GetPromise());
if (args.Length() < 1) { auto bytes = GetFirstArgumentAsBytes(args, &thrower);
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);
if (thrower.error()) { if (thrower.error()) {
resolver->Reject(context, Utils::ToLocal(thrower.Reify())); resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
} else { return;
resolver->Resolve(context, Utils::ToLocal(module_obj.ToHandleChecked()));
} }
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) { void WebAssemblyValidate(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Isolate* isolate = args.GetIsolate(); v8::Isolate* isolate = args.GetIsolate();
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
HandleScope scope(isolate); HandleScope scope(isolate);
ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate), ErrorThrower thrower(i_isolate, "WebAssembly.validate()");
"WebAssembly.validate()");
if (args.Length() < 1) { auto bytes = GetFirstArgumentAsBytes(args, &thrower);
thrower.TypeError("Argument 0 must be a buffer source");
return;
}
v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); 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)); return_value.Set(v8::True(isolate));
} else { } else {
if (thrower.wasm_error()) thrower.Reify(); // Clear error. if (thrower.wasm_error()) thrower.Reify(); // Clear error.
...@@ -168,84 +167,25 @@ void WebAssemblyValidate(const v8::FunctionCallbackInfo<v8::Value>& args) { ...@@ -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) { void WebAssemblyModule(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Isolate* isolate = args.GetIsolate(); v8::Isolate* isolate = args.GetIsolate();
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
HandleScope scope(isolate); HandleScope scope(isolate);
ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate), ErrorThrower thrower(i_isolate, "WebAssembly.Module()");
"WebAssembly.Module()");
if (args.Length() < 1) { auto bytes = GetFirstArgumentAsBytes(args, &thrower);
thrower.TypeError("Argument 0 must be a buffer source"); if (thrower.error()) return;
return;
}
i::MaybeHandle<i::JSObject> module_obj = i::MaybeHandle<i::Object> module_obj =
CreateModuleObject(isolate, args[0], &thrower); i::wasm::SyncCompile(i_isolate, &thrower, bytes);
if (module_obj.is_null()) return; if (module_obj.is_null()) return;
v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
return_value.Set(Utils::ToLocal(module_obj.ToHandleChecked())); return_value.Set(Utils::ToLocal(module_obj.ToHandleChecked()));
} }
MaybeLocal<Value> InstantiateModuleImpl( // WebAssembly.Module.imports(module) -> Array<Import>
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
void WebAssemblyModuleImports(const v8::FunctionCallbackInfo<v8::Value>& args) { void WebAssemblyModuleImports(const v8::FunctionCallbackInfo<v8::Value>& args) {
HandleScope scope(args.GetIsolate()); HandleScope scope(args.GetIsolate());
v8::Isolate* isolate = args.GetIsolate(); v8::Isolate* isolate = args.GetIsolate();
...@@ -253,14 +193,12 @@ void WebAssemblyModuleImports(const v8::FunctionCallbackInfo<v8::Value>& args) { ...@@ -253,14 +193,12 @@ void WebAssemblyModuleImports(const v8::FunctionCallbackInfo<v8::Value>& args) {
ErrorThrower thrower(i_isolate, "WebAssembly.Module.imports()"); ErrorThrower thrower(i_isolate, "WebAssembly.Module.imports()");
auto maybe_module = GetFirstArgumentAsModule(args, &thrower); auto maybe_module = GetFirstArgumentAsModule(args, &thrower);
if (thrower.error()) return;
if (!maybe_module.is_null()) { auto imports = i::wasm::GetImports(i_isolate, maybe_module.ToHandleChecked());
auto imports = args.GetReturnValue().Set(Utils::ToLocal(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) { void WebAssemblyModuleExports(const v8::FunctionCallbackInfo<v8::Value>& args) {
HandleScope scope(args.GetIsolate()); HandleScope scope(args.GetIsolate());
v8::Isolate* isolate = args.GetIsolate(); v8::Isolate* isolate = args.GetIsolate();
...@@ -268,14 +206,12 @@ void WebAssemblyModuleExports(const v8::FunctionCallbackInfo<v8::Value>& args) { ...@@ -268,14 +206,12 @@ void WebAssemblyModuleExports(const v8::FunctionCallbackInfo<v8::Value>& args) {
ErrorThrower thrower(i_isolate, "WebAssembly.Module.exports()"); ErrorThrower thrower(i_isolate, "WebAssembly.Module.exports()");
auto maybe_module = GetFirstArgumentAsModule(args, &thrower); auto maybe_module = GetFirstArgumentAsModule(args, &thrower);
if (thrower.error()) return;
if (!maybe_module.is_null()) { auto exports = i::wasm::GetExports(i_isolate, maybe_module.ToHandleChecked());
auto exports = args.GetReturnValue().Set(Utils::ToLocal(exports));
i::wasm::GetExports(i_isolate, maybe_module.ToHandleChecked());
args.GetReturnValue().Set(Utils::ToLocal(exports));
}
} }
// WebAssembly.Module.customSections(module, name) -> Array<Section>
void WebAssemblyModuleCustomSections( void WebAssemblyModuleCustomSections(
const v8::FunctionCallbackInfo<v8::Value>& args) { const v8::FunctionCallbackInfo<v8::Value>& args) {
HandleScope scope(args.GetIsolate()); HandleScope scope(args.GetIsolate());
...@@ -284,6 +220,7 @@ void WebAssemblyModuleCustomSections( ...@@ -284,6 +220,7 @@ void WebAssemblyModuleCustomSections(
ErrorThrower thrower(i_isolate, "WebAssembly.Module.customSections()"); 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) { if (args.Length() < 2) {
thrower.TypeError("Argument 1 must be a string"); thrower.TypeError("Argument 1 must be a string");
...@@ -296,16 +233,14 @@ void WebAssemblyModuleCustomSections( ...@@ -296,16 +233,14 @@ void WebAssemblyModuleCustomSections(
return; return;
} }
if (!maybe_module.is_null()) { auto custom_sections =
auto custom_sections = i::wasm::GetCustomSections(i_isolate, maybe_module.ToHandleChecked(),
i::wasm::GetCustomSections(i_isolate, maybe_module.ToHandleChecked(), i::Handle<i::String>::cast(name), &thrower);
i::Handle<i::String>::cast(name), &thrower); if (thrower.error()) return;
if (!thrower.error()) { args.GetReturnValue().Set(Utils::ToLocal(custom_sections));
args.GetReturnValue().Set(Utils::ToLocal(custom_sections));
}
}
} }
// new WebAssembly.Instance(module, imports) -> WebAssembly.Instance
void WebAssemblyInstance(const v8::FunctionCallbackInfo<v8::Value>& args) { void WebAssemblyInstance(const v8::FunctionCallbackInfo<v8::Value>& args) {
HandleScope scope(args.GetIsolate()); HandleScope scope(args.GetIsolate());
v8::Isolate* isolate = args.GetIsolate(); v8::Isolate* isolate = args.GetIsolate();
...@@ -313,19 +248,21 @@ void WebAssemblyInstance(const v8::FunctionCallbackInfo<v8::Value>& args) { ...@@ -313,19 +248,21 @@ void WebAssemblyInstance(const v8::FunctionCallbackInfo<v8::Value>& args) {
ErrorThrower thrower(i_isolate, "WebAssembly.Instance()"); ErrorThrower thrower(i_isolate, "WebAssembly.Instance()");
auto maybe_module = GetFirstArgumentAsModule(args, &thrower); auto maybe_module = GetFirstArgumentAsModule(args, &thrower);
if (thrower.error()) return;
if (!maybe_module.is_null()) { auto maybe_imports = GetSecondArgumentAsImports(args, &thrower);
MaybeLocal<Value> instance = InstantiateModuleImpl( if (thrower.error()) return;
i_isolate, maybe_module.ToHandleChecked(), args, &thrower);
if (instance.IsEmpty()) { i::MaybeHandle<i::Object> instance_object = i::wasm::SyncInstantiate(
DCHECK(thrower.error()); i_isolate, &thrower, maybe_module.ToHandleChecked(), maybe_imports,
return; i::MaybeHandle<i::JSArrayBuffer>());
} if (instance_object.is_null()) return;
args.GetReturnValue().Set(instance.ToLocalChecked()); 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) { void WebAssemblyInstantiate(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Isolate* isolate = args.GetIsolate(); v8::Isolate* isolate = args.GetIsolate();
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
...@@ -356,50 +293,28 @@ void WebAssemblyInstantiate(const v8::FunctionCallbackInfo<v8::Value>& args) { ...@@ -356,50 +293,28 @@ void WebAssemblyInstantiate(const v8::FunctionCallbackInfo<v8::Value>& args) {
resolver->Reject(context, Utils::ToLocal(thrower.Reify())); resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
return; return;
} }
bool want_pair =
!HasBrand(first_arg, i::Handle<i::Symbol>(i_context->wasm_module_sym())); auto maybe_imports = GetSecondArgumentAsImports(args, &thrower);
i::Handle<i::WasmModuleObject> module_obj; if (thrower.error()) {
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());
resolver->Reject(context, Utils::ToLocal(thrower.Reify())); 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 { } else {
DCHECK(!thrower.error()); // WebAssembly.instantiate(bytes, imports) -> {module, instance}
Local<Value> retval; auto bytes = GetFirstArgumentAsBytes(args, &thrower);
if (want_pair) { if (thrower.error()) {
i::Handle<i::JSFunction> object_function = i::Handle<i::JSFunction>( resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
i_isolate->native_context()->object_function(), i_isolate); return;
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()); i::wasm::AsyncCompileAndInstantiate(i_isolate, promise, bytes,
resolver->Resolve(context, retval); maybe_imports);
} }
} }
...@@ -430,11 +345,12 @@ bool GetIntegerProperty(v8::Isolate* isolate, ErrorThrower* thrower, ...@@ -430,11 +345,12 @@ bool GetIntegerProperty(v8::Isolate* isolate, ErrorThrower* thrower,
return false; return false;
} }
// new WebAssembly.Table(args) -> WebAssembly.Table
void WebAssemblyTable(const v8::FunctionCallbackInfo<v8::Value>& args) { void WebAssemblyTable(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Isolate* isolate = args.GetIsolate(); v8::Isolate* isolate = args.GetIsolate();
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
HandleScope scope(isolate); HandleScope scope(isolate);
ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate), ErrorThrower thrower(i_isolate, "WebAssembly.Module()");
"WebAssembly.Module()");
if (args.Length() < 1 || !args[0]->IsObject()) { if (args.Length() < 1 || !args[0]->IsObject()) {
thrower.TypeError("Argument 0 must be a table descriptor"); thrower.TypeError("Argument 0 must be a table descriptor");
return; return;
...@@ -476,7 +392,6 @@ void WebAssemblyTable(const v8::FunctionCallbackInfo<v8::Value>& args) { ...@@ -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::FixedArray> fixed_array;
i::Handle<i::JSObject> table_obj = i::Handle<i::JSObject> table_obj =
i::WasmTableObject::New(i_isolate, initial, maximum, &fixed_array); i::WasmTableObject::New(i_isolate, initial, maximum, &fixed_array);
...@@ -486,9 +401,9 @@ void WebAssemblyTable(const v8::FunctionCallbackInfo<v8::Value>& args) { ...@@ -486,9 +401,9 @@ void WebAssemblyTable(const v8::FunctionCallbackInfo<v8::Value>& args) {
void WebAssemblyMemory(const v8::FunctionCallbackInfo<v8::Value>& args) { void WebAssemblyMemory(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Isolate* isolate = args.GetIsolate(); v8::Isolate* isolate = args.GetIsolate();
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
HandleScope scope(isolate); HandleScope scope(isolate);
ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate), ErrorThrower thrower(i_isolate, "WebAssembly.Memory()");
"WebAssembly.Memory()");
if (args.Length() < 1 || !args[0]->IsObject()) { if (args.Length() < 1 || !args[0]->IsObject()) {
thrower.TypeError("Argument 0 must be a memory descriptor"); thrower.TypeError("Argument 0 must be a memory descriptor");
return; return;
...@@ -514,7 +429,6 @@ void WebAssemblyMemory(const v8::FunctionCallbackInfo<v8::Value>& args) { ...@@ -514,7 +429,6 @@ void WebAssemblyMemory(const v8::FunctionCallbackInfo<v8::Value>& args) {
return; return;
} }
} }
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
size_t size = static_cast<size_t>(i::wasm::WasmModule::kPageSize) * size_t size = static_cast<size_t>(i::wasm::WasmModule::kPageSize) *
static_cast<size_t>(initial); static_cast<size_t>(initial);
i::Handle<i::JSArrayBuffer> buffer = i::Handle<i::JSArrayBuffer> buffer =
...@@ -531,12 +445,13 @@ void WebAssemblyMemory(const v8::FunctionCallbackInfo<v8::Value>& args) { ...@@ -531,12 +445,13 @@ void WebAssemblyMemory(const v8::FunctionCallbackInfo<v8::Value>& args) {
void WebAssemblyTableGetLength( void WebAssemblyTableGetLength(
const v8::FunctionCallbackInfo<v8::Value>& args) { const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Isolate* isolate = args.GetIsolate(); v8::Isolate* isolate = args.GetIsolate();
ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate), i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
"WebAssembly.Table.length()"); HandleScope scope(isolate);
ErrorThrower thrower(i_isolate, "WebAssembly.Table.length()");
Local<Context> context = isolate->GetCurrentContext(); Local<Context> context = isolate->GetCurrentContext();
i::Handle<i::Context> i_context = Utils::OpenHandle(*context); i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
if (!BrandCheck(&thrower, Utils::OpenHandle(*args.This()), if (!BrandCheck(Utils::OpenHandle(*args.This()),
i::Handle<i::Symbol>(i_context->wasm_table_sym()), i::Handle<i::Symbol>(i_context->wasm_table_sym()), &thrower,
"Receiver is not a WebAssembly.Table")) { "Receiver is not a WebAssembly.Table")) {
return; return;
} }
...@@ -546,19 +461,20 @@ void WebAssemblyTableGetLength( ...@@ -546,19 +461,20 @@ void WebAssemblyTableGetLength(
v8::Number::New(isolate, receiver->current_length())); v8::Number::New(isolate, receiver->current_length()));
} }
// WebAssembly.Table.grow(num) -> num
void WebAssemblyTableGrow(const v8::FunctionCallbackInfo<v8::Value>& args) { void WebAssemblyTableGrow(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Isolate* isolate = args.GetIsolate(); v8::Isolate* isolate = args.GetIsolate();
ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate), i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
"WebAssembly.Table.grow()"); HandleScope scope(isolate);
ErrorThrower thrower(i_isolate, "WebAssembly.Table.grow()");
Local<Context> context = isolate->GetCurrentContext(); Local<Context> context = isolate->GetCurrentContext();
i::Handle<i::Context> i_context = Utils::OpenHandle(*context); i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
if (!BrandCheck(&thrower, Utils::OpenHandle(*args.This()), if (!BrandCheck(Utils::OpenHandle(*args.This()),
i::Handle<i::Symbol>(i_context->wasm_table_sym()), i::Handle<i::Symbol>(i_context->wasm_table_sym()), &thrower,
"Receiver is not a WebAssembly.Table")) { "Receiver is not a WebAssembly.Table")) {
return; return;
} }
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
auto receiver = auto receiver =
i::Handle<i::WasmTableObject>::cast(Utils::OpenHandle(*args.This())); i::Handle<i::WasmTableObject>::cast(Utils::OpenHandle(*args.This()));
i::Handle<i::FixedArray> old_array(receiver->functions(), i_isolate); i::Handle<i::FixedArray> old_array(receiver->functions(), i_isolate);
...@@ -599,14 +515,16 @@ void WebAssemblyTableGrow(const v8::FunctionCallbackInfo<v8::Value>& args) { ...@@ -599,14 +515,16 @@ void WebAssemblyTableGrow(const v8::FunctionCallbackInfo<v8::Value>& args) {
return_value.Set(old_size); return_value.Set(old_size);
} }
// WebAssembly.Table.get(num) -> JSFunction
void WebAssemblyTableGet(const v8::FunctionCallbackInfo<v8::Value>& args) { void WebAssemblyTableGet(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Isolate* isolate = args.GetIsolate(); v8::Isolate* isolate = args.GetIsolate();
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
HandleScope scope(isolate);
ErrorThrower thrower(i_isolate, "WebAssembly.Table.get()"); ErrorThrower thrower(i_isolate, "WebAssembly.Table.get()");
Local<Context> context = isolate->GetCurrentContext(); Local<Context> context = isolate->GetCurrentContext();
i::Handle<i::Context> i_context = Utils::OpenHandle(*context); i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
if (!BrandCheck(&thrower, Utils::OpenHandle(*args.This()), if (!BrandCheck(Utils::OpenHandle(*args.This()),
i::Handle<i::Symbol>(i_context->wasm_table_sym()), i::Handle<i::Symbol>(i_context->wasm_table_sym()), &thrower,
"Receiver is not a WebAssembly.Table")) { "Receiver is not a WebAssembly.Table")) {
return; return;
} }
...@@ -626,14 +544,16 @@ void WebAssemblyTableGet(const v8::FunctionCallbackInfo<v8::Value>& args) { ...@@ -626,14 +544,16 @@ void WebAssemblyTableGet(const v8::FunctionCallbackInfo<v8::Value>& args) {
return_value.Set(Utils::ToLocal(value)); return_value.Set(Utils::ToLocal(value));
} }
// WebAssembly.Table.set(num, JSFunction)
void WebAssemblyTableSet(const v8::FunctionCallbackInfo<v8::Value>& args) { void WebAssemblyTableSet(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Isolate* isolate = args.GetIsolate(); v8::Isolate* isolate = args.GetIsolate();
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
HandleScope scope(isolate);
ErrorThrower thrower(i_isolate, "WebAssembly.Table.set()"); ErrorThrower thrower(i_isolate, "WebAssembly.Table.set()");
Local<Context> context = isolate->GetCurrentContext(); Local<Context> context = isolate->GetCurrentContext();
i::Handle<i::Context> i_context = Utils::OpenHandle(*context); i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
if (!BrandCheck(&thrower, Utils::OpenHandle(*args.This()), if (!BrandCheck(Utils::OpenHandle(*args.This()),
i::Handle<i::Symbol>(i_context->wasm_table_sym()), i::Handle<i::Symbol>(i_context->wasm_table_sym()), &thrower,
"Receiver is not a WebAssembly.Table")) { "Receiver is not a WebAssembly.Table")) {
return; return;
} }
...@@ -673,14 +593,16 @@ void WebAssemblyTableSet(const v8::FunctionCallbackInfo<v8::Value>& args) { ...@@ -673,14 +593,16 @@ void WebAssemblyTableSet(const v8::FunctionCallbackInfo<v8::Value>& args) {
i::Handle<i::FixedArray>::cast(array)->set(i, *value); i::Handle<i::FixedArray>::cast(array)->set(i, *value);
} }
// WebAssembly.Memory.grow(num) -> num
void WebAssemblyMemoryGrow(const v8::FunctionCallbackInfo<v8::Value>& args) { void WebAssemblyMemoryGrow(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Isolate* isolate = args.GetIsolate(); v8::Isolate* isolate = args.GetIsolate();
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
HandleScope scope(isolate);
ErrorThrower thrower(i_isolate, "WebAssembly.Memory.grow()"); ErrorThrower thrower(i_isolate, "WebAssembly.Memory.grow()");
Local<Context> context = isolate->GetCurrentContext(); Local<Context> context = isolate->GetCurrentContext();
i::Handle<i::Context> i_context = Utils::OpenHandle(*context); i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
if (!BrandCheck(&thrower, Utils::OpenHandle(*args.This()), if (!BrandCheck(Utils::OpenHandle(*args.This()),
i::Handle<i::Symbol>(i_context->wasm_memory_sym()), i::Handle<i::Symbol>(i_context->wasm_memory_sym()), &thrower,
"Receiver is not a WebAssembly.Memory")) { "Receiver is not a WebAssembly.Memory")) {
return; return;
} }
...@@ -715,15 +637,17 @@ void WebAssemblyMemoryGrow(const v8::FunctionCallbackInfo<v8::Value>& args) { ...@@ -715,15 +637,17 @@ void WebAssemblyMemoryGrow(const v8::FunctionCallbackInfo<v8::Value>& args) {
return_value.Set(ret); return_value.Set(ret);
} }
// WebAssembly.Memory.buffer -> ArrayBuffer
void WebAssemblyMemoryGetBuffer( void WebAssemblyMemoryGetBuffer(
const v8::FunctionCallbackInfo<v8::Value>& args) { const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Isolate* isolate = args.GetIsolate(); v8::Isolate* isolate = args.GetIsolate();
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
HandleScope scope(isolate);
ErrorThrower thrower(i_isolate, "WebAssembly.Memory.buffer"); ErrorThrower thrower(i_isolate, "WebAssembly.Memory.buffer");
Local<Context> context = isolate->GetCurrentContext(); Local<Context> context = isolate->GetCurrentContext();
i::Handle<i::Context> i_context = Utils::OpenHandle(*context); i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
if (!BrandCheck(&thrower, Utils::OpenHandle(*args.This()), if (!BrandCheck(Utils::OpenHandle(*args.This()),
i::Handle<i::Symbol>(i_context->wasm_memory_sym()), i::Handle<i::Symbol>(i_context->wasm_memory_sym()), &thrower,
"Receiver is not a WebAssembly.Memory")) { "Receiver is not a WebAssembly.Memory")) {
return; return;
} }
......
...@@ -898,23 +898,23 @@ int wasm::GetFunctionCodeOffset(Handle<WasmCompiledModule> compiled_module, ...@@ -898,23 +898,23 @@ int wasm::GetFunctionCodeOffset(Handle<WasmCompiledModule> compiled_module,
WasmModule::WasmModule(Zone* owned) WasmModule::WasmModule(Zone* owned)
: owned_zone(owned), pending_tasks(new base::Semaphore(0)) {} : owned_zone(owned), pending_tasks(new base::Semaphore(0)) {}
MaybeHandle<WasmCompiledModule> WasmModule::CompileFunctions( MaybeHandle<WasmModuleObject> CompileToModuleObject(
Isolate* isolate, Handle<WasmModuleWrapper> module_wrapper, Isolate* isolate, WasmModule* m, ErrorThrower* thrower,
ErrorThrower* thrower, const ModuleWireBytes& wire_bytes, const ModuleWireBytes& wire_bytes, Handle<Script> asm_js_script,
Handle<Script> asm_js_script, Vector<const byte> asm_js_offset_table_bytes) {
Vector<const byte> asm_js_offset_table_bytes) const {
Factory* factory = isolate->factory(); Factory* factory = isolate->factory();
MaybeHandle<WasmModuleObject> nothing;
MaybeHandle<WasmCompiledModule> nothing; // The {module_wrapper} will take ownership of the {WasmModule} object,
// and it will be destroyed when the GC reclaims the wrapper object.
WasmInstance temp_instance(this); Handle<WasmModuleWrapper> module_wrapper = WasmModuleWrapper::New(isolate, m);
WasmInstance temp_instance(m);
temp_instance.context = isolate->native_context(); temp_instance.context = isolate->native_context();
temp_instance.mem_size = WasmModule::kPageSize * min_mem_pages; temp_instance.mem_size = WasmModule::kPageSize * m->min_mem_pages;
temp_instance.mem_start = nullptr; temp_instance.mem_start = nullptr;
temp_instance.globals_start = nullptr; temp_instance.globals_start = nullptr;
// Initialize the indirect tables with placeholders. // Initialize the indirect tables with placeholders.
int function_table_count = static_cast<int>(function_tables.size()); int function_table_count = static_cast<int>(m->function_tables.size());
Handle<FixedArray> function_tables = Handle<FixedArray> function_tables =
factory->NewFixedArray(function_table_count, TENURED); factory->NewFixedArray(function_table_count, TENURED);
Handle<FixedArray> signature_tables = Handle<FixedArray> signature_tables =
...@@ -929,25 +929,25 @@ MaybeHandle<WasmCompiledModule> WasmModule::CompileFunctions( ...@@ -929,25 +929,25 @@ MaybeHandle<WasmCompiledModule> WasmModule::CompileFunctions(
HistogramTimerScope wasm_compile_module_time_scope( HistogramTimerScope wasm_compile_module_time_scope(
isolate->counters()->wasm_compile_module_time()); isolate->counters()->wasm_compile_module_time());
ModuleBytesEnv module_env(this, &temp_instance, wire_bytes); ModuleBytesEnv module_env(m, &temp_instance, wire_bytes);
// The {code_table} array contains import wrappers and functions (which // The {code_table} array contains import wrappers and functions (which
// are both included in {functions.size()}, and export wrappers. // are both included in {functions.size()}, and export wrappers.
int code_table_size = int code_table_size =
static_cast<int>(functions.size() + num_exported_functions); static_cast<int>(m->functions.size() + m->num_exported_functions);
Handle<FixedArray> code_table = Handle<FixedArray> code_table =
factory->NewFixedArray(static_cast<int>(code_table_size), TENURED); factory->NewFixedArray(static_cast<int>(code_table_size), TENURED);
// Initialize the code table with the illegal builtin. All call sites will be // Initialize the code table with the illegal builtin. All call sites will be
// patched at instantiation. // patched at instantiation.
Handle<Code> illegal_builtin = isolate->builtins()->Illegal(); Handle<Code> illegal_builtin = isolate->builtins()->Illegal();
for (uint32_t i = 0; i < functions.size(); ++i) { for (uint32_t i = 0; i < m->functions.size(); ++i) {
code_table->set(static_cast<int>(i), *illegal_builtin); code_table->set(static_cast<int>(i), *illegal_builtin);
temp_instance.function_code[i] = illegal_builtin; temp_instance.function_code[i] = illegal_builtin;
} }
isolate->counters()->wasm_functions_per_module()->AddSample( isolate->counters()->wasm_functions_per_module()->AddSample(
static_cast<int>(functions.size())); static_cast<int>(m->functions.size()));
if (!FLAG_trace_wasm_decoder && FLAG_wasm_num_compilation_tasks != 0) { if (!FLAG_trace_wasm_decoder && FLAG_wasm_num_compilation_tasks != 0) {
// Avoid a race condition by collecting results into a second vector. // Avoid a race condition by collecting results into a second vector.
std::vector<Handle<Code>> results(temp_instance.function_code); std::vector<Handle<Code>> results(temp_instance.function_code);
...@@ -1002,39 +1002,40 @@ MaybeHandle<WasmCompiledModule> WasmModule::CompileFunctions( ...@@ -1002,39 +1002,40 @@ MaybeHandle<WasmCompiledModule> WasmModule::CompileFunctions(
// and information needed at instantiation time. This object needs to be // and information needed at instantiation time. This object needs to be
// serializable. Instantiation may occur off a deserialized version of this // serializable. Instantiation may occur off a deserialized version of this
// object. // object.
Handle<WasmCompiledModule> ret = WasmCompiledModule::New(isolate, shared); Handle<WasmCompiledModule> compiled_module =
ret->set_num_imported_functions(num_imported_functions); WasmCompiledModule::New(isolate, shared);
ret->set_code_table(code_table); compiled_module->set_num_imported_functions(m->num_imported_functions);
ret->set_min_mem_pages(min_mem_pages); compiled_module->set_code_table(code_table);
ret->set_max_mem_pages(max_mem_pages); compiled_module->set_min_mem_pages(m->min_mem_pages);
compiled_module->set_max_mem_pages(m->max_mem_pages);
if (function_table_count > 0) { if (function_table_count > 0) {
ret->set_function_tables(function_tables); compiled_module->set_function_tables(function_tables);
ret->set_signature_tables(signature_tables); compiled_module->set_signature_tables(signature_tables);
ret->set_empty_function_tables(function_tables); compiled_module->set_empty_function_tables(function_tables);
} }
// If we created a wasm script, finish it now and make it public to the // If we created a wasm script, finish it now and make it public to the
// debugger. // debugger.
if (asm_js_script.is_null()) { if (asm_js_script.is_null()) {
script->set_wasm_compiled_module(*ret); script->set_wasm_compiled_module(*compiled_module);
isolate->debug()->OnAfterCompile(script); isolate->debug()->OnAfterCompile(script);
} }
// Compile JS->WASM wrappers for exported functions. // Compile JS->WASM wrappers for exported functions.
int func_index = 0; int func_index = 0;
for (auto exp : export_table) { for (auto exp : m->export_table) {
if (exp.kind != kExternalFunction) continue; if (exp.kind != kExternalFunction) continue;
Handle<Code> wasm_code = Handle<Code> wasm_code =
code_table->GetValueChecked<Code>(isolate, exp.index); code_table->GetValueChecked<Code>(isolate, exp.index);
Handle<Code> wrapper_code = Handle<Code> wrapper_code =
compiler::CompileJSToWasmWrapper(isolate, this, wasm_code, exp.index); compiler::CompileJSToWasmWrapper(isolate, m, wasm_code, exp.index);
int export_index = static_cast<int>(functions.size() + func_index); int export_index = static_cast<int>(m->functions.size() + func_index);
code_table->set(export_index, *wrapper_code); code_table->set(export_index, *wrapper_code);
RecordStats(isolate, *wrapper_code); RecordStats(isolate, *wrapper_code);
func_index++; func_index++;
} }
return ret; return WasmModuleObject::New(isolate, compiled_module);
} }
static WasmFunction* GetWasmFunctionForImportWrapper(Isolate* isolate, static WasmFunction* GetWasmFunctionForImportWrapper(Isolate* isolate,
...@@ -1139,17 +1140,20 @@ void wasm::UpdateDispatchTables(Isolate* isolate, ...@@ -1139,17 +1140,20 @@ void wasm::UpdateDispatchTables(Isolate* isolate,
// A helper class to simplify instantiating a module from a compiled module. // A helper class to simplify instantiating a module from a compiled module.
// It closes over the {Isolate}, the {ErrorThrower}, the {WasmCompiledModule}, // It closes over the {Isolate}, the {ErrorThrower}, the {WasmCompiledModule},
// etc. // etc.
class WasmInstanceBuilder { class InstantiationHelper {
public: public:
WasmInstanceBuilder(Isolate* isolate, ErrorThrower* thrower, InstantiationHelper(Isolate* isolate, ErrorThrower* thrower,
Handle<WasmModuleObject> module_object, Handle<WasmModuleObject> module_object,
Handle<JSReceiver> ffi, Handle<JSArrayBuffer> memory) MaybeHandle<JSReceiver> ffi,
MaybeHandle<JSArrayBuffer> memory)
: isolate_(isolate), : isolate_(isolate),
module_(module_object->compiled_module()->module()), module_(module_object->compiled_module()->module()),
thrower_(thrower), thrower_(thrower),
module_object_(module_object), module_object_(module_object),
ffi_(ffi), ffi_(ffi.is_null() ? Handle<JSReceiver>::null()
memory_(memory) {} : ffi.ToHandleChecked()),
memory_(memory.is_null() ? Handle<JSArrayBuffer>::null()
: memory.ToHandleChecked()) {}
// Build an instance, in all of its glory. // Build an instance, in all of its glory.
MaybeHandle<WasmInstanceObject> Build() { MaybeHandle<WasmInstanceObject> Build() {
...@@ -1526,8 +1530,8 @@ class WasmInstanceBuilder { ...@@ -1526,8 +1530,8 @@ class WasmInstanceBuilder {
WasmModule* const module_; WasmModule* const module_;
ErrorThrower* thrower_; ErrorThrower* thrower_;
Handle<WasmModuleObject> module_object_; Handle<WasmModuleObject> module_object_;
Handle<JSReceiver> ffi_; Handle<JSReceiver> ffi_; // TODO(titzer): Use MaybeHandle
Handle<JSArrayBuffer> memory_; Handle<JSArrayBuffer> memory_; // TODO(titzer): Use MaybeHandle
Handle<JSArrayBuffer> globals_; Handle<JSArrayBuffer> globals_;
Handle<WasmCompiledModule> compiled_module_; Handle<WasmCompiledModule> compiled_module_;
std::vector<TableInstance> table_instances_; std::vector<TableInstance> table_instances_;
...@@ -2243,16 +2247,6 @@ class WasmInstanceBuilder { ...@@ -2243,16 +2247,6 @@ class WasmInstanceBuilder {
} }
}; };
// Instantiates a WASM module, creating a WebAssembly.Instance from a
// WebAssembly.Module.
MaybeHandle<WasmInstanceObject> WasmModule::Instantiate(
Isolate* isolate, ErrorThrower* thrower,
Handle<WasmModuleObject> wasm_module, Handle<JSReceiver> ffi,
Handle<JSArrayBuffer> memory) {
WasmInstanceBuilder builder(isolate, thrower, wasm_module, ffi, memory);
return builder.Build();
}
bool wasm::IsWasmInstance(Object* object) { bool wasm::IsWasmInstance(Object* object) {
return WasmInstanceObject::IsWasmInstanceObject(object); return WasmInstanceObject::IsWasmInstanceObject(object);
} }
...@@ -2268,57 +2262,6 @@ bool wasm::IsWasmCodegenAllowed(Isolate* isolate, Handle<Context> context) { ...@@ -2268,57 +2262,6 @@ bool wasm::IsWasmCodegenAllowed(Isolate* isolate, Handle<Context> context) {
isolate->allow_code_gen_callback()(v8::Utils::ToLocal(context)); isolate->allow_code_gen_callback()(v8::Utils::ToLocal(context));
} }
// TODO(clemensh): origin can be inferred from asm_js_script; remove it.
MaybeHandle<WasmModuleObject> wasm::CreateModuleObjectFromBytes(
Isolate* isolate, const byte* start, const byte* end, ErrorThrower* thrower,
ModuleOrigin origin, Handle<Script> asm_js_script,
Vector<const byte> asm_js_offset_table_bytes) {
MaybeHandle<WasmModuleObject> nothing;
if (origin != kAsmJsOrigin &&
!IsWasmCodegenAllowed(isolate, isolate->native_context())) {
thrower->CompileError("Wasm code generation disallowed in this context");
return nothing;
}
ModuleResult result = DecodeWasmModule(isolate, start, end, false, origin);
if (result.failed()) {
if (result.val) delete result.val;
thrower->CompileFailed("Wasm decoding failed", result);
return nothing;
}
// The {module_wrapper} will take ownership of the {WasmModule} object,
// and it will be destroyed when the GC reclaims the wrapper object.
Handle<WasmModuleWrapper> module_wrapper =
WasmModuleWrapper::New(isolate, const_cast<WasmModule*>(result.val));
// Compile the functions of the module, producing a compiled module.
MaybeHandle<WasmCompiledModule> maybe_compiled_module =
result.val->CompileFunctions(isolate, module_wrapper, thrower,
ModuleWireBytes(start, end), asm_js_script,
asm_js_offset_table_bytes);
if (maybe_compiled_module.is_null()) return nothing;
Handle<WasmCompiledModule> compiled_module =
maybe_compiled_module.ToHandleChecked();
return WasmModuleObject::New(isolate, compiled_module);
}
bool wasm::ValidateModuleBytes(Isolate* isolate, const byte* start,
const byte* end, ErrorThrower* thrower,
ModuleOrigin origin) {
ModuleResult result = DecodeWasmModule(isolate, start, end, true, origin);
if (result.val) {
delete result.val;
} else {
DCHECK(!result.ok());
}
return result.ok();
}
MaybeHandle<JSArrayBuffer> wasm::GetInstanceMemory( MaybeHandle<JSArrayBuffer> wasm::GetInstanceMemory(
Isolate* isolate, Handle<WasmInstanceObject> object) { Isolate* isolate, Handle<WasmInstanceObject> object) {
auto instance = Handle<WasmInstanceObject>::cast(object); auto instance = Handle<WasmInstanceObject>::cast(object);
...@@ -2825,3 +2768,143 @@ Handle<JSArray> wasm::GetCustomSections(Isolate* isolate, ...@@ -2825,3 +2768,143 @@ Handle<JSArray> wasm::GetCustomSections(Isolate* isolate,
return array_object; return array_object;
} }
bool wasm::SyncValidate(Isolate* isolate, ErrorThrower* thrower,
const ModuleWireBytes& bytes) {
if (bytes.start() == nullptr || bytes.length() == 0) return false;
ModuleResult result =
DecodeWasmModule(isolate, bytes.start(), bytes.end(), true, kWasmOrigin);
if (result.val) delete result.val;
return result.ok();
}
MaybeHandle<WasmModuleObject> wasm::SyncCompileTranslatedAsmJs(
Isolate* isolate, ErrorThrower* thrower, const ModuleWireBytes& bytes,
Handle<Script> asm_js_script,
Vector<const byte> asm_js_offset_table_bytes) {
MaybeHandle<WasmModuleObject> nothing;
ModuleResult result = DecodeWasmModule(isolate, bytes.start(), bytes.end(),
false, kAsmJsOrigin);
if (result.failed()) {
// TODO(titzer): use Result<std::unique_ptr<const WasmModule*>>?
if (result.val) delete result.val;
thrower->CompileFailed("Wasm decoding failed", result);
return nothing;
}
return CompileToModuleObject(isolate, const_cast<WasmModule*>(result.val),
thrower, bytes, asm_js_script,
asm_js_offset_table_bytes);
}
MaybeHandle<WasmModuleObject> wasm::SyncCompile(Isolate* isolate,
ErrorThrower* thrower,
const ModuleWireBytes& bytes) {
MaybeHandle<WasmModuleObject> nothing;
if (!IsWasmCodegenAllowed(isolate, isolate->native_context())) {
thrower->CompileError("Wasm code generation disallowed in this context");
return nothing;
}
ModuleResult result =
DecodeWasmModule(isolate, bytes.start(), bytes.end(), false, kWasmOrigin);
if (result.failed()) {
if (result.val) delete result.val;
thrower->CompileFailed("Wasm decoding failed", result);
return nothing;
}
return CompileToModuleObject(isolate, const_cast<WasmModule*>(result.val),
thrower, bytes, Handle<Script>(),
Vector<const byte>());
}
MaybeHandle<WasmInstanceObject> wasm::SyncInstantiate(
Isolate* isolate, ErrorThrower* thrower,
Handle<WasmModuleObject> module_object, MaybeHandle<JSReceiver> imports,
MaybeHandle<JSArrayBuffer> memory) {
InstantiationHelper helper(isolate, thrower, module_object, imports, memory);
return helper.Build();
}
void RejectPromise(Isolate* isolate, ErrorThrower* thrower,
Handle<JSPromise> promise) {
v8::Local<v8::Promise::Resolver> resolver =
v8::Utils::PromiseToLocal(promise).As<v8::Promise::Resolver>();
Handle<Context> context(isolate->context(), isolate);
resolver->Reject(v8::Utils::ToLocal(context),
v8::Utils::ToLocal(thrower->Reify()));
}
void ResolvePromise(Isolate* isolate, Handle<JSPromise> promise,
Handle<Object> result) {
v8::Local<v8::Promise::Resolver> resolver =
v8::Utils::PromiseToLocal(promise).As<v8::Promise::Resolver>();
Handle<Context> context(isolate->context(), isolate);
resolver->Resolve(v8::Utils::ToLocal(context), v8::Utils::ToLocal(result));
}
void wasm::AsyncCompile(Isolate* isolate, Handle<JSPromise> promise,
const ModuleWireBytes& bytes) {
ErrorThrower thrower(isolate, nullptr);
MaybeHandle<WasmModuleObject> module_object =
SyncCompile(isolate, &thrower, bytes);
if (thrower.error()) {
RejectPromise(isolate, &thrower, promise);
return;
}
ResolvePromise(isolate, promise, module_object.ToHandleChecked());
}
void wasm::AsyncInstantiate(Isolate* isolate, Handle<JSPromise> promise,
Handle<WasmModuleObject> module_object,
MaybeHandle<JSReceiver> imports) {
ErrorThrower thrower(isolate, nullptr);
MaybeHandle<WasmInstanceObject> instance_object = SyncInstantiate(
isolate, &thrower, module_object, imports, Handle<JSArrayBuffer>::null());
if (thrower.error()) {
RejectPromise(isolate, &thrower, promise);
return;
}
ResolvePromise(isolate, promise, instance_object.ToHandleChecked());
}
void wasm::AsyncCompileAndInstantiate(Isolate* isolate,
Handle<JSPromise> promise,
const ModuleWireBytes& bytes,
MaybeHandle<JSReceiver> imports) {
ErrorThrower thrower(isolate, nullptr);
// Compile the module.
MaybeHandle<WasmModuleObject> module_object =
SyncCompile(isolate, &thrower, bytes);
if (thrower.error()) {
RejectPromise(isolate, &thrower, promise);
return;
}
Handle<WasmModuleObject> module = module_object.ToHandleChecked();
// Instantiate the module.
MaybeHandle<WasmInstanceObject> instance_object = SyncInstantiate(
isolate, &thrower, module, imports, Handle<JSArrayBuffer>::null());
if (thrower.error()) {
RejectPromise(isolate, &thrower, promise);
return;
}
Handle<JSFunction> object_function =
Handle<JSFunction>(isolate->native_context()->object_function(), isolate);
Handle<JSObject> ret =
isolate->factory()->NewJSObject(object_function, TENURED);
Handle<String> module_property_name =
isolate->factory()->InternalizeUtf8String("module");
Handle<String> instance_property_name =
isolate->factory()->InternalizeUtf8String("instance");
JSObject::AddProperty(ret, module_property_name, module, NONE);
JSObject::AddProperty(ret, instance_property_name,
instance_object.ToHandleChecked(), NONE);
ResolvePromise(isolate, promise, ret);
}
...@@ -28,7 +28,6 @@ class WasmMemoryObject; ...@@ -28,7 +28,6 @@ class WasmMemoryObject;
namespace compiler { namespace compiler {
class CallDescriptor; class CallDescriptor;
class WasmCompilationUnit;
} }
namespace wasm { namespace wasm {
...@@ -217,18 +216,6 @@ struct V8_EXPORT_PRIVATE WasmModule { ...@@ -217,18 +216,6 @@ struct V8_EXPORT_PRIVATE WasmModule {
~WasmModule() { ~WasmModule() {
if (owned_zone) delete owned_zone; if (owned_zone) delete owned_zone;
} }
// Creates a new instantiation of the module in the given isolate.
static MaybeHandle<WasmInstanceObject> Instantiate(
Isolate* isolate, ErrorThrower* thrower,
Handle<WasmModuleObject> wasm_module, Handle<JSReceiver> ffi,
Handle<JSArrayBuffer> memory = Handle<JSArrayBuffer>::null());
MaybeHandle<WasmCompiledModule> CompileFunctions(
Isolate* isolate, Handle<Managed<WasmModule>> module_wrapper,
ErrorThrower* thrower, const ModuleWireBytes& wire_bytes,
Handle<Script> asm_js_script,
Vector<const byte> asm_js_offset_table_bytes) const;
}; };
typedef Managed<WasmModule> WasmModuleWrapper; typedef Managed<WasmModule> WasmModuleWrapper;
...@@ -359,6 +346,7 @@ struct V8_EXPORT_PRIVATE ModuleEnv { ...@@ -359,6 +346,7 @@ struct V8_EXPORT_PRIVATE ModuleEnv {
return instance->function_code[index]; return instance->function_code[index];
} }
// TODO(titzer): move these into src/compiler/wasm-compiler.cc
static compiler::CallDescriptor* GetWasmCallDescriptor(Zone* zone, static compiler::CallDescriptor* GetWasmCallDescriptor(Zone* zone,
FunctionSig* sig); FunctionSig* sig);
static compiler::CallDescriptor* GetI32WasmCallDescriptor( static compiler::CallDescriptor* GetI32WasmCallDescriptor(
...@@ -425,11 +413,6 @@ V8_EXPORT_PRIVATE Handle<JSArray> GetCustomSections( ...@@ -425,11 +413,6 @@ V8_EXPORT_PRIVATE Handle<JSArray> GetCustomSections(
Isolate* isolate, Handle<WasmModuleObject> module, Handle<String> name, Isolate* isolate, Handle<WasmModuleObject> module, Handle<String> name,
ErrorThrower* thrower); ErrorThrower* thrower);
V8_EXPORT_PRIVATE bool ValidateModuleBytes(Isolate* isolate, const byte* start,
const byte* end,
ErrorThrower* thrower,
ModuleOrigin origin);
// Get the offset of the code of a function within a module. // Get the offset of the code of a function within a module.
int GetFunctionCodeOffset(Handle<WasmCompiledModule> compiled_module, int GetFunctionCodeOffset(Handle<WasmCompiledModule> compiled_module,
int func_index); int func_index);
...@@ -464,15 +447,43 @@ void UpdateDispatchTables(Isolate* isolate, Handle<FixedArray> dispatch_tables, ...@@ -464,15 +447,43 @@ void UpdateDispatchTables(Isolate* isolate, Handle<FixedArray> dispatch_tables,
void GrowDispatchTables(Isolate* isolate, Handle<FixedArray> dispatch_tables, void GrowDispatchTables(Isolate* isolate, Handle<FixedArray> dispatch_tables,
uint32_t old_size, uint32_t count); uint32_t old_size, uint32_t count);
namespace testing { //============================================================================
//== Compilation and instantiation ===========================================
//============================================================================
V8_EXPORT_PRIVATE bool SyncValidate(Isolate* isolate, ErrorThrower* thrower,
const ModuleWireBytes& bytes);
V8_EXPORT_PRIVATE MaybeHandle<WasmModuleObject> SyncCompileTranslatedAsmJs(
Isolate* isolate, ErrorThrower* thrower, const ModuleWireBytes& bytes,
Handle<Script> asm_js_script, Vector<const byte> asm_js_offset_table_bytes);
V8_EXPORT_PRIVATE MaybeHandle<WasmModuleObject> SyncCompile(
Isolate* isolate, ErrorThrower* thrower, const ModuleWireBytes& bytes);
V8_EXPORT_PRIVATE MaybeHandle<WasmInstanceObject> SyncInstantiate(
Isolate* isolate, ErrorThrower* thrower,
Handle<WasmModuleObject> module_object, MaybeHandle<JSReceiver> imports,
MaybeHandle<JSArrayBuffer> memory);
V8_EXPORT_PRIVATE void AsyncCompile(Isolate* isolate, Handle<JSPromise> promise,
const ModuleWireBytes& bytes);
V8_EXPORT_PRIVATE void AsyncInstantiate(Isolate* isolate,
Handle<JSPromise> promise,
Handle<WasmModuleObject> module_object,
MaybeHandle<JSReceiver> imports);
V8_EXPORT_PRIVATE void AsyncCompileAndInstantiate(
Isolate* isolate, Handle<JSPromise> promise, const ModuleWireBytes& bytes,
MaybeHandle<JSReceiver> imports);
namespace testing {
void ValidateInstancesChain(Isolate* isolate, void ValidateInstancesChain(Isolate* isolate,
Handle<WasmModuleObject> module_obj, Handle<WasmModuleObject> module_obj,
int instance_count); int instance_count);
void ValidateModuleState(Isolate* isolate, Handle<WasmModuleObject> module_obj); void ValidateModuleState(Isolate* isolate, Handle<WasmModuleObject> module_obj);
void ValidateOrphanedInstance(Isolate* isolate, void ValidateOrphanedInstance(Isolate* isolate,
Handle<WasmInstanceObject> instance); Handle<WasmInstanceObject> instance);
} // namespace testing } // namespace testing
} // namespace wasm } // namespace wasm
} // namespace internal } // namespace internal
......
...@@ -271,9 +271,9 @@ class WasmSerializationTest { ...@@ -271,9 +271,9 @@ class WasmSerializationTest {
0); 0);
} }
Handle<JSObject> instance = Handle<JSObject> instance =
WasmModule::Instantiate(current_isolate(), &thrower, module_object, SyncInstantiate(current_isolate(), &thrower, module_object,
Handle<JSReceiver>::null(), Handle<JSReceiver>::null(),
Handle<JSArrayBuffer>::null()) MaybeHandle<JSArrayBuffer>())
.ToHandleChecked(); .ToHandleChecked();
Handle<Object> params[1] = { Handle<Object> params[1] = {
Handle<Object>(Smi::FromInt(41), current_isolate())}; Handle<Object>(Smi::FromInt(41), current_isolate())};
...@@ -318,19 +318,13 @@ class WasmSerializationTest { ...@@ -318,19 +318,13 @@ class WasmSerializationTest {
HandleScope scope(serialization_isolate); HandleScope scope(serialization_isolate);
testing::SetupIsolateForWasmModule(serialization_isolate); testing::SetupIsolateForWasmModule(serialization_isolate);
ModuleResult decoding_result = MaybeHandle<WasmModuleObject> module_object =
DecodeWasmModule(serialization_isolate, buffer.begin(), buffer.end(), SyncCompile(serialization_isolate, &thrower,
false, kWasmOrigin); ModuleWireBytes(buffer.begin(), buffer.end()));
CHECK(!decoding_result.failed());
Handle<WasmModuleWrapper> module_wrapper = WasmModuleWrapper::New( MaybeHandle<WasmCompiledModule> compiled_module(
serialization_isolate, const_cast<WasmModule*>(decoding_result.val)); module_object.ToHandleChecked()->compiled_module(),
serialization_isolate);
MaybeHandle<WasmCompiledModule> compiled_module =
decoding_result.val->CompileFunctions(
serialization_isolate, module_wrapper, &thrower,
ModuleWireBytes(buffer.begin(), buffer.end()),
Handle<Script>::null(), Vector<const byte>::empty());
CHECK(!compiled_module.is_null()); CHECK(!compiled_module.is_null());
Handle<JSObject> module_obj = WasmModuleObject::New( Handle<JSObject> module_obj = WasmModuleObject::New(
serialization_isolate, compiled_module.ToHandleChecked()); serialization_isolate, compiled_module.ToHandleChecked());
...@@ -437,10 +431,8 @@ TEST(BlockWasmCodeGen) { ...@@ -437,10 +431,8 @@ TEST(BlockWasmCodeGen) {
CcTest::isolate()->SetAllowCodeGenerationFromStringsCallback(False); CcTest::isolate()->SetAllowCodeGenerationFromStringsCallback(False);
ErrorThrower thrower(isolate, "block codegen"); ErrorThrower thrower(isolate, "block codegen");
MaybeHandle<WasmModuleObject> ret = wasm::CreateModuleObjectFromBytes( MaybeHandle<WasmModuleObject> ret = wasm::SyncCompile(
isolate, buffer.begin(), buffer.end(), &thrower, isolate, &thrower, ModuleWireBytes(buffer.begin(), buffer.end()));
wasm::ModuleOrigin::kWasmOrigin, Handle<v8::internal::Script>::null(),
Vector<const byte>::empty());
CcTest::isolate()->SetAllowCodeGenerationFromStringsCallback(nullptr); CcTest::isolate()->SetAllowCodeGenerationFromStringsCallback(nullptr);
CHECK(ret.is_null()); CHECK(ret.is_null());
CHECK(thrower.error()); CHECK(thrower.error());
......
...@@ -59,17 +59,15 @@ const Handle<WasmInstanceObject> InstantiateModuleForTesting( ...@@ -59,17 +59,15 @@ const Handle<WasmInstanceObject> InstantiateModuleForTesting(
// Although we decoded the module for some pre-validation, run the bytes // Although we decoded the module for some pre-validation, run the bytes
// again through the normal pipeline. // again through the normal pipeline.
// TODO(wasm): Use {module} instead of decoding the module bytes again. // TODO(wasm): Use {module} instead of decoding the module bytes again.
MaybeHandle<WasmModuleObject> module_object = CreateModuleObjectFromBytes( MaybeHandle<WasmModuleObject> module_object =
isolate, wire_bytes.start(), wire_bytes.end(), thrower, SyncCompile(isolate, thrower, wire_bytes);
ModuleOrigin::kWasmOrigin, Handle<Script>::null(),
Vector<const byte>::empty());
if (module_object.is_null()) { if (module_object.is_null()) {
thrower->CompileError("Module pre-validation failed."); thrower->CompileError("Module pre-validation failed.");
return Handle<WasmInstanceObject>::null(); return Handle<WasmInstanceObject>::null();
} }
MaybeHandle<WasmInstanceObject> maybe_instance = MaybeHandle<WasmInstanceObject> maybe_instance =
WasmModule::Instantiate(isolate, thrower, module_object.ToHandleChecked(), SyncInstantiate(isolate, thrower, module_object.ToHandleChecked(),
Handle<JSReceiver>::null()); Handle<JSReceiver>::null(), MaybeHandle<JSArrayBuffer>());
Handle<WasmInstanceObject> instance; Handle<WasmInstanceObject> instance;
if (!maybe_instance.ToHandle(&instance)) { if (!maybe_instance.ToHandle(&instance)) {
return Handle<WasmInstanceObject>::null(); return Handle<WasmInstanceObject>::null();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment