Commit e4d7995c authored by Ben L. Titzer's avatar Ben L. Titzer Committed by Commit Bot

[wasm] Move SyncCompile* and AsyncCompile* methods to WasmEngine

This is a further step to separate the implementation of the JavaScript
API from the internals of the WASM implementation. Now, wasm-js.cc
only needs to interact with the WASM engine and is (almost) independent
of module-decoder.h and module-compiler.h.

Also, move SyncCompileAndInstantiate() into wasm-module-runner.cc.

Bug: v8:7316

R=clemensh@chromium.org, mstarzinger@chromium.org

Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng
Change-Id: I7765af54ac16f53a5ff88c17a22c5d36bacaf926
Reviewed-on: https://chromium-review.googlesource.com/870871
Commit-Queue: Ben Titzer <titzer@chromium.org>
Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Reviewed-by: 's avatarClemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#50679}
parent cf500ac1
......@@ -7606,8 +7606,9 @@ MaybeLocal<WasmCompiledModule> WasmCompiledModule::Compile(Isolate* isolate,
if (!i::wasm::IsWasmCodegenAllowed(i_isolate, i_isolate->native_context())) {
return MaybeLocal<WasmCompiledModule>();
}
i::MaybeHandle<i::JSObject> maybe_compiled = i::wasm::SyncCompile(
i_isolate, &thrower, i::wasm::ModuleWireBytes(start, start + length));
i::MaybeHandle<i::JSObject> maybe_compiled =
i_isolate->wasm_engine()->SyncCompile(
i_isolate, &thrower, i::wasm::ModuleWireBytes(start, start + length));
if (maybe_compiled.is_null()) return MaybeLocal<WasmCompiledModule>();
return Local<WasmCompiledModule>::Cast(
Utils::ToLocal(maybe_compiled.ToHandleChecked()));
......@@ -7666,10 +7667,10 @@ void WasmModuleObjectBuilderStreaming::Finish() {
}
// AsyncCompile makes its own copy of the wire bytes. This inefficiency
// will be resolved when we move to true streaming compilation.
i::wasm::AsyncCompile(reinterpret_cast<i::Isolate*>(isolate_),
Utils::OpenHandle(*promise_.Get(isolate_)),
{wire_bytes.get(), wire_bytes.get() + total_size_},
false);
auto i_isolate = reinterpret_cast<i::Isolate*>(isolate_);
i_isolate->wasm_engine()->AsyncCompile(
i_isolate, Utils::OpenHandle(*promise_.Get(isolate_)),
{wire_bytes.get(), wire_bytes.get() + total_size_}, false);
}
void WasmModuleObjectBuilderStreaming::Abort(Local<Value> exception) {
......
......@@ -21,8 +21,7 @@
#include "src/parsing/scanner-character-streams.h"
#include "src/parsing/scanner.h"
#include "src/wasm/module-compiler.h"
#include "src/wasm/module-decoder.h"
#include "src/wasm/wasm-engine.h"
#include "src/wasm/wasm-js.h"
#include "src/wasm/wasm-module-builder.h"
#include "src/wasm/wasm-objects-inl.h"
......@@ -284,11 +283,12 @@ CompilationJob::Status AsmJsCompilationJob::FinalizeJobImpl(Isolate* isolate) {
wasm::ErrorThrower thrower(isolate, "AsmJs::Compile");
Handle<WasmModuleObject> compiled =
SyncCompileTranslatedAsmJs(
isolate, &thrower,
wasm::ModuleWireBytes(module_->begin(), module_->end()),
parse_info()->script(),
Vector<const byte>(asm_offsets_->begin(), asm_offsets_->size()))
isolate->wasm_engine()
->SyncCompileTranslatedAsmJs(
isolate, &thrower,
wasm::ModuleWireBytes(module_->begin(), module_->end()),
parse_info()->script(),
Vector<const byte>(asm_offsets_->begin(), asm_offsets_->size()))
.ToHandleChecked();
DCHECK(!thrower.error());
compile_time_ = compile_timer.Elapsed().InMillisecondsF();
......@@ -389,7 +389,8 @@ MaybeHandle<Object> AsmJs::InstantiateAsmWasm(Isolate* isolate,
wasm::ErrorThrower thrower(isolate, "AsmJs::Instantiate");
MaybeHandle<Object> maybe_module_object =
wasm::SyncInstantiate(isolate, &thrower, module, foreign, memory);
isolate->wasm_engine()->SyncInstantiate(isolate, &thrower, module,
foreign, memory);
if (maybe_module_object.is_null()) {
// An exception caused by the module start function will be set as pending
// and bypass the {ErrorThrower}, this happens in case of a stack overflow.
......
......@@ -18,7 +18,7 @@
#include "src/objects.h"
#include "src/snapshot/code-serializer.h"
#include "src/transitions.h"
#include "src/wasm/module-compiler.h"
#include "src/wasm/wasm-engine.h"
#include "src/wasm/wasm-objects-inl.h"
#include "src/wasm/wasm-result.h"
#include "src/wasm/wasm-serialization.h"
......@@ -1714,8 +1714,8 @@ MaybeHandle<JSObject> ValueDeserializer::ReadWasmModule() {
}
if (result.is_null()) {
wasm::ErrorThrower thrower(isolate_, "ValueDeserializer::ReadWasmModule");
result = wasm::SyncCompile(isolate_, &thrower,
wasm::ModuleWireBytes(wire_bytes));
result = isolate_->wasm_engine()->SyncCompile(
isolate_, &thrower, wasm::ModuleWireBytes(wire_bytes));
}
RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate_, JSObject);
uint32_t id = next_id_++;
......
......@@ -4,6 +4,7 @@
#include "src/wasm/compilation-manager.h"
#include "src/base/template-utils.h"
#include "src/wasm/module-compiler.h"
#include "src/objects-inl.h"
......
......@@ -9,12 +9,13 @@
#include "src/handles.h"
#include "src/isolate.h"
#include "src/wasm/module-compiler.h"
namespace v8 {
namespace internal {
namespace wasm {
class AsyncCompileJob;
// The CompilationManager manages a list of active WebAssembly compile jobs. The
// manager owns the memory of the compile jobs and can trigger the abortion of
// compile jobs. If the isolate tears down, the CompilationManager makes sure
......
......@@ -207,18 +207,12 @@ class ModuleCompiler {
compiler::ModuleEnv* module_env,
ErrorThrower* thrower);
static MaybeHandle<WasmModuleObject> CompileToModuleObject(
Isolate* isolate, ErrorThrower* thrower,
std::unique_ptr<WasmModule> module, const ModuleWireBytes& wire_bytes,
Handle<Script> asm_js_script,
Vector<const byte> asm_js_offset_table_bytes);
private:
MaybeHandle<WasmModuleObject> CompileToModuleObjectInternal(
ErrorThrower* thrower, std::unique_ptr<WasmModule> module,
const ModuleWireBytes& wire_bytes, Handle<Script> asm_js_script,
Vector<const byte> asm_js_offset_table_bytes);
private:
Isolate* isolate_;
WasmModule* module_;
const std::shared_ptr<Counters> async_counters_;
......@@ -533,42 +527,7 @@ class SetOfNativeModuleModificationScopes final {
} // namespace
MaybeHandle<WasmModuleObject> SyncCompileTranslatedAsmJs(
Isolate* isolate, ErrorThrower* thrower, const ModuleWireBytes& bytes,
Handle<Script> asm_js_script,
Vector<const byte> asm_js_offset_table_bytes) {
ModuleResult result = SyncDecodeWasmModule(isolate, bytes.start(),
bytes.end(), false, kAsmJsOrigin);
if (result.failed()) {
thrower->CompileFailed("Wasm decoding failed", result);
return {};
}
// Transfer ownership of the WasmModule to the {WasmModuleWrapper} generated
// in {CompileToModuleObject}.
return ModuleCompiler::CompileToModuleObject(
isolate, thrower, std::move(result.val), bytes, asm_js_script,
asm_js_offset_table_bytes);
}
MaybeHandle<WasmModuleObject> SyncCompile(Isolate* isolate,
ErrorThrower* thrower,
const ModuleWireBytes& bytes) {
ModuleResult result = SyncDecodeWasmModule(isolate, bytes.start(),
bytes.end(), false, kWasmOrigin);
if (result.failed()) {
thrower->CompileFailed("Wasm decoding failed", result);
return {};
}
// Transfer ownership of the WasmModule to the {WasmModuleWrapper} generated
// in {CompileToModuleObject}.
return ModuleCompiler::CompileToModuleObject(
isolate, thrower, std::move(result.val), bytes, Handle<Script>(),
Vector<const byte>());
}
MaybeHandle<WasmInstanceObject> SyncInstantiate(
MaybeHandle<WasmInstanceObject> InstantiateToInstanceObject(
Isolate* isolate, ErrorThrower* thrower,
Handle<WasmModuleObject> module_object, MaybeHandle<JSReceiver> imports,
MaybeHandle<JSArrayBuffer> memory) {
......@@ -577,17 +536,6 @@ MaybeHandle<WasmInstanceObject> SyncInstantiate(
return builder.Build();
}
MaybeHandle<WasmInstanceObject> SyncCompileAndInstantiate(
Isolate* isolate, ErrorThrower* thrower, const ModuleWireBytes& bytes,
MaybeHandle<JSReceiver> imports, MaybeHandle<JSArrayBuffer> memory) {
MaybeHandle<WasmModuleObject> module = SyncCompile(isolate, thrower, bytes);
DCHECK_EQ(thrower->error(), module.is_null());
if (module.is_null()) return {};
return SyncInstantiate(isolate, thrower, module.ToHandleChecked(), imports,
memory);
}
void RejectPromise(Isolate* isolate, Handle<Context> context,
ErrorThrower& thrower, Handle<JSPromise> promise) {
Local<Promise::Resolver> resolver =
......@@ -606,65 +554,6 @@ void ResolvePromise(Isolate* isolate, Handle<Context> context,
CHECK_IMPLIES(!maybe.FromMaybe(false), isolate->has_scheduled_exception());
}
void 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, handle(isolate->context()), thrower, promise);
return;
}
ResolvePromise(isolate, handle(isolate->context()), promise,
instance_object.ToHandleChecked());
}
void AsyncCompile(Isolate* isolate, Handle<JSPromise> promise,
const ModuleWireBytes& bytes, bool is_shared) {
if (!FLAG_wasm_async_compilation) {
// Asynchronous compilation disabled; fall back on synchronous compilation.
ErrorThrower thrower(isolate, "WasmCompile");
MaybeHandle<WasmModuleObject> module_object;
if (is_shared) {
// Make a copy of the wire bytes to avoid concurrent modification.
std::unique_ptr<uint8_t[]> copy(new uint8_t[bytes.length()]);
memcpy(copy.get(), bytes.start(), bytes.length());
i::wasm::ModuleWireBytes bytes_copy(copy.get(),
copy.get() + bytes.length());
module_object = SyncCompile(isolate, &thrower, bytes_copy);
} else {
// The wire bytes are not shared, OK to use them directly.
module_object = SyncCompile(isolate, &thrower, bytes);
}
if (thrower.error()) {
RejectPromise(isolate, handle(isolate->context()), thrower, promise);
return;
}
Handle<WasmModuleObject> module = module_object.ToHandleChecked();
ResolvePromise(isolate, handle(isolate->context()), promise, module);
return;
}
if (FLAG_wasm_test_streaming) {
std::shared_ptr<StreamingDecoder> streaming_decoder =
isolate->wasm_engine()
->compilation_manager()
->StartStreamingCompilation(isolate, handle(isolate->context()),
promise);
streaming_decoder->OnBytesReceived(bytes.module_bytes());
streaming_decoder->Finish();
return;
}
// Make a copy of the wire bytes in case the user program changes them
// during asynchronous compilation.
std::unique_ptr<byte[]> copy(new byte[bytes.length()]);
memcpy(copy.get(), bytes.start(), bytes.length());
isolate->wasm_engine()->compilation_manager()->StartAsyncCompileJob(
isolate, std::move(copy), bytes.length(), handle(isolate->context()),
promise);
}
Handle<Code> CompileLazyOnGCHeap(Isolate* isolate) {
HistogramTimerScope lazy_time_scope(
isolate->counters()->wasm_lazy_compilation_time());
......@@ -1678,8 +1567,7 @@ void ModuleCompiler::ValidateSequentially(const ModuleWireBytes& wire_bytes,
}
}
// static
MaybeHandle<WasmModuleObject> ModuleCompiler::CompileToModuleObject(
MaybeHandle<WasmModuleObject> CompileToModuleObject(
Isolate* isolate, ErrorThrower* thrower, std::unique_ptr<WasmModule> module,
const ModuleWireBytes& wire_bytes, Handle<Script> asm_js_script,
Vector<const byte> asm_js_offset_table_bytes) {
......
......@@ -23,34 +23,20 @@ namespace wasm {
class ModuleCompiler;
class WasmCode;
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);
MaybeHandle<WasmModuleObject> CompileToModuleObject(
Isolate* isolate, ErrorThrower* thrower, std::unique_ptr<WasmModule> module,
const ModuleWireBytes& wire_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(
MaybeHandle<WasmInstanceObject> InstantiateToInstanceObject(
Isolate* isolate, ErrorThrower* thrower,
Handle<WasmModuleObject> module_object, MaybeHandle<JSReceiver> imports,
MaybeHandle<JSArrayBuffer> memory);
V8_EXPORT_PRIVATE MaybeHandle<WasmInstanceObject> SyncCompileAndInstantiate(
Isolate* isolate, ErrorThrower* thrower, const ModuleWireBytes& bytes,
MaybeHandle<JSReceiver> imports, MaybeHandle<JSArrayBuffer> memory);
V8_EXPORT_PRIVATE void AsyncCompile(Isolate* isolate, Handle<JSPromise> promise,
const ModuleWireBytes& bytes,
bool is_shared);
V8_EXPORT_PRIVATE void AsyncInstantiate(Isolate* isolate,
Handle<JSPromise> promise,
Handle<WasmModuleObject> module_object,
MaybeHandle<JSReceiver> imports);
V8_EXPORT_PRIVATE void CompileJsToWasmWrappers(
Isolate* isolate, Handle<WasmCompiledModule> compiled_module,
Counters* counters);
V8_EXPORT_PRIVATE
void CompileJsToWasmWrappers(Isolate* isolate,
Handle<WasmCompiledModule> compiled_module,
Counters* counters);
V8_EXPORT_PRIVATE Handle<Script> CreateWasmScript(
Isolate* isolate, const ModuleWireBytes& wire_bytes);
......
......@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "src/wasm/wasm-engine.h"
#include "src/api.h"
#include "src/objects-inl.h"
#include "src/wasm/module-compiler.h"
......@@ -18,6 +19,123 @@ bool WasmEngine::SyncValidate(Isolate* isolate, const ModuleWireBytes& bytes) {
return result.ok();
}
MaybeHandle<WasmModuleObject> WasmEngine::SyncCompileTranslatedAsmJs(
Isolate* isolate, ErrorThrower* thrower, const ModuleWireBytes& bytes,
Handle<Script> asm_js_script,
Vector<const byte> asm_js_offset_table_bytes) {
ModuleResult result = SyncDecodeWasmModule(isolate, bytes.start(),
bytes.end(), false, kAsmJsOrigin);
CHECK(!result.failed());
// Transfer ownership of the WasmModule to the {WasmModuleWrapper} generated
// in {CompileToModuleObject}.
return CompileToModuleObject(isolate, thrower, std::move(result.val), bytes,
asm_js_script, asm_js_offset_table_bytes);
}
MaybeHandle<WasmModuleObject> WasmEngine::SyncCompile(
Isolate* isolate, ErrorThrower* thrower, const ModuleWireBytes& bytes) {
ModuleResult result = SyncDecodeWasmModule(isolate, bytes.start(),
bytes.end(), false, kWasmOrigin);
if (result.failed()) {
thrower->CompileFailed("Wasm decoding failed", result);
return {};
}
// Transfer ownership of the WasmModule to the {WasmModuleWrapper} generated
// in {CompileToModuleObject}.
return CompileToModuleObject(isolate, thrower, std::move(result.val), bytes,
Handle<Script>(), Vector<const byte>());
}
MaybeHandle<WasmInstanceObject> WasmEngine::SyncInstantiate(
Isolate* isolate, ErrorThrower* thrower,
Handle<WasmModuleObject> module_object, MaybeHandle<JSReceiver> imports,
MaybeHandle<JSArrayBuffer> memory) {
return InstantiateToInstanceObject(isolate, thrower, module_object, imports,
memory);
}
namespace {
// TODO(titzer): these utilities are duplicated in module-compiler.cc
void RejectPromise(Isolate* isolate, Handle<Context> context,
ErrorThrower& thrower, Handle<JSPromise> promise) {
Local<Promise::Resolver> resolver =
Utils::PromiseToLocal(promise).As<Promise::Resolver>();
auto maybe = resolver->Reject(Utils::ToLocal(context),
Utils::ToLocal(thrower.Reify()));
CHECK_IMPLIES(!maybe.FromMaybe(false), isolate->has_scheduled_exception());
}
void ResolvePromise(Isolate* isolate, Handle<Context> context,
Handle<JSPromise> promise, Handle<Object> result) {
Local<Promise::Resolver> resolver =
Utils::PromiseToLocal(promise).As<Promise::Resolver>();
auto maybe =
resolver->Resolve(Utils::ToLocal(context), Utils::ToLocal(result));
CHECK_IMPLIES(!maybe.FromMaybe(false), isolate->has_scheduled_exception());
}
} // namespace
void WasmEngine::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, handle(isolate->context()), thrower, promise);
return;
}
ResolvePromise(isolate, handle(isolate->context()), promise,
instance_object.ToHandleChecked());
}
void WasmEngine::AsyncCompile(Isolate* isolate, Handle<JSPromise> promise,
const ModuleWireBytes& bytes, bool is_shared) {
if (!FLAG_wasm_async_compilation) {
// Asynchronous compilation disabled; fall back on synchronous compilation.
ErrorThrower thrower(isolate, "WasmCompile");
MaybeHandle<WasmModuleObject> module_object;
if (is_shared) {
// Make a copy of the wire bytes to avoid concurrent modification.
std::unique_ptr<uint8_t[]> copy(new uint8_t[bytes.length()]);
memcpy(copy.get(), bytes.start(), bytes.length());
i::wasm::ModuleWireBytes bytes_copy(copy.get(),
copy.get() + bytes.length());
module_object = SyncCompile(isolate, &thrower, bytes_copy);
} else {
// The wire bytes are not shared, OK to use them directly.
module_object = SyncCompile(isolate, &thrower, bytes);
}
if (thrower.error()) {
RejectPromise(isolate, handle(isolate->context()), thrower, promise);
return;
}
Handle<WasmModuleObject> module = module_object.ToHandleChecked();
ResolvePromise(isolate, handle(isolate->context()), promise, module);
return;
}
if (FLAG_wasm_test_streaming) {
std::shared_ptr<StreamingDecoder> streaming_decoder =
isolate->wasm_engine()
->compilation_manager()
->StartStreamingCompilation(isolate, handle(isolate->context()),
promise);
streaming_decoder->OnBytesReceived(bytes.module_bytes());
streaming_decoder->Finish();
return;
}
// Make a copy of the wire bytes in case the user program changes them
// during asynchronous compilation.
std::unique_ptr<byte[]> copy(new byte[bytes.length()]);
memcpy(copy.get(), bytes.start(), bytes.length());
isolate->wasm_engine()->compilation_manager()->StartAsyncCompileJob(
isolate, std::move(copy), bytes.length(), handle(isolate->context()),
promise);
}
} // namespace wasm
} // namespace internal
} // namespace v8
......@@ -14,8 +14,14 @@
namespace v8 {
namespace internal {
class WasmModuleObject;
class WasmInstanceObject;
namespace wasm {
class ErrorThrower;
struct ModuleWireBytes;
// The central data structure that represents an engine instance capable of
// loading, instantiating, and executing WASM code.
class V8_EXPORT_PRIVATE WasmEngine {
......@@ -23,8 +29,44 @@ class V8_EXPORT_PRIVATE WasmEngine {
explicit WasmEngine(std::unique_ptr<WasmCodeManager> code_manager)
: code_manager_(std::move(code_manager)) {}
// Synchronously validates the given bytes that represent an encoded WASM
// module.
bool SyncValidate(Isolate* isolate, const ModuleWireBytes& bytes);
// Synchronously compiles the given bytes that represent a translated
// asm.js module.
MaybeHandle<WasmModuleObject> SyncCompileTranslatedAsmJs(
Isolate* isolate, ErrorThrower* thrower, const ModuleWireBytes& bytes,
Handle<Script> asm_js_script,
Vector<const byte> asm_js_offset_table_bytes);
// Synchronously compiles the given bytes that represent an encoded WASM
// module.
MaybeHandle<WasmModuleObject> SyncCompile(Isolate* isolate,
ErrorThrower* thrower,
const ModuleWireBytes& bytes);
// Synchronously instantiate the given WASM module with the given imports.
// If the module represents an asm.js module, then the supplied {memory}
// should be used as the memory of the instance.
MaybeHandle<WasmInstanceObject> SyncInstantiate(
Isolate* isolate, ErrorThrower* thrower,
Handle<WasmModuleObject> module_object, MaybeHandle<JSReceiver> imports,
MaybeHandle<JSArrayBuffer> memory);
// Begin an asynchronous compilation of the given bytes that represent an
// encoded WASM module, placing the result in the supplied {promise}.
// The {is_shared} flag indicates if the bytes backing the module could
// be shared across threads, i.e. could be concurrently modified.
void AsyncCompile(Isolate* isolate, Handle<JSPromise> promise,
const ModuleWireBytes& bytes, bool is_shared);
// Begin an asynchronous instantiation of the given WASM module, placing the
// result in the supplied {promise}.
void AsyncInstantiate(Isolate* isolate, Handle<JSPromise> promise,
Handle<WasmModuleObject> module_object,
MaybeHandle<JSReceiver> imports);
CompilationManager* compilation_manager() { return &compilation_manager_; }
WasmCodeManager* code_manager() const { return code_manager_.get(); }
......
......@@ -16,7 +16,6 @@
#include "src/objects.h"
#include "src/parsing/parse-info.h"
#include "src/trap-handler/trap-handler.h"
#include "src/wasm/module-compiler.h"
#include "src/wasm/wasm-api.h"
#include "src/wasm/wasm-engine.h"
#include "src/wasm/wasm-limits.h"
......@@ -165,7 +164,7 @@ void WebAssemblyCompile(const v8::FunctionCallbackInfo<v8::Value>& args) {
}
i::Handle<i::JSPromise> promise = Utils::OpenHandle(*resolver->GetPromise());
// Asynchronous compilation handles copying wire bytes if necessary.
i::wasm::AsyncCompile(i_isolate, promise, bytes, is_shared);
i_isolate->wasm_engine()->AsyncCompile(i_isolate, promise, bytes, is_shared);
}
// WebAssembly.validate(bytes) -> bool
......@@ -233,10 +232,12 @@ void WebAssemblyModule(const v8::FunctionCallbackInfo<v8::Value>& args) {
memcpy(copy.get(), bytes.start(), bytes.length());
i::wasm::ModuleWireBytes bytes_copy(copy.get(),
copy.get() + bytes.length());
module_obj = i::wasm::SyncCompile(i_isolate, &thrower, bytes_copy);
module_obj =
i_isolate->wasm_engine()->SyncCompile(i_isolate, &thrower, bytes_copy);
} else {
// The wire bytes are not shared, OK to use them directly.
module_obj = i::wasm::SyncCompile(i_isolate, &thrower, bytes);
module_obj =
i_isolate->wasm_engine()->SyncCompile(i_isolate, &thrower, bytes);
}
if (module_obj.is_null()) return;
......@@ -312,9 +313,9 @@ MaybeLocal<Value> WebAssemblyInstantiateImpl(Isolate* isolate,
i::Handle<i::WasmModuleObject> module_obj =
i::Handle<i::WasmModuleObject>::cast(
Utils::OpenHandle(Object::Cast(*module)));
instance_object =
i::wasm::SyncInstantiate(i_isolate, &thrower, module_obj, maybe_imports,
i::MaybeHandle<i::JSArrayBuffer>());
instance_object = i_isolate->wasm_engine()->SyncInstantiate(
i_isolate, &thrower, module_obj, maybe_imports,
i::MaybeHandle<i::JSArrayBuffer>());
}
DCHECK_EQ(instance_object.is_null(), i_isolate->has_scheduled_exception());
......
......@@ -18,7 +18,6 @@
#include "src/trap-handler/trap-handler.h"
#include "src/v8.h"
#include "src/wasm/compilation-manager.h"
#include "src/wasm/module-compiler.h"
#include "src/wasm/module-decoder.h"
#include "src/wasm/wasm-code-manager.h"
#include "src/wasm/wasm-code-specialization.h"
......
......@@ -1005,6 +1005,7 @@ void WasmSharedModuleData::PrepareForLazyCompilation(
Handle<WasmSharedModuleData> shared) {
if (shared->has_lazy_compilation_orchestrator()) return;
Isolate* isolate = shared->GetIsolate();
// TODO(titzer): remove dependency on module-compiler.h
auto orch_handle =
Managed<wasm::LazyCompilationOrchestrator>::Allocate(isolate);
shared->set_lazy_compilation_orchestrator(*orch_handle);
......
......@@ -9,8 +9,8 @@
#include "src/objects-inl.h"
#include "src/snapshot/code-serializer.h"
#include "src/version.h"
#include "src/wasm/module-compiler.h"
#include "src/wasm/module-decoder.h"
#include "src/wasm/wasm-engine.h"
#include "src/wasm/wasm-memory.h"
#include "src/wasm/wasm-module-builder.h"
#include "src/wasm/wasm-module.h"
......@@ -27,6 +27,8 @@ namespace v8 {
namespace internal {
namespace wasm {
using testing::CompileAndInstantiateForTesting;
namespace {
void Cleanup(Isolate* isolate = nullptr) {
// By sending a low memory notifications, we will try hard to collect all
......@@ -283,9 +285,11 @@ class WasmSerializationTest {
0);
}
Handle<WasmInstanceObject> instance =
SyncInstantiate(current_isolate(), &thrower, module_object,
Handle<JSReceiver>::null(),
MaybeHandle<JSArrayBuffer>())
current_isolate()
->wasm_engine()
->SyncInstantiate(current_isolate(), &thrower, module_object,
Handle<JSReceiver>::null(),
MaybeHandle<JSArrayBuffer>())
.ToHandleChecked();
Handle<Object> params[1] = {
Handle<Object>(Smi::FromInt(41), current_isolate())};
......@@ -330,8 +334,9 @@ class WasmSerializationTest {
testing::SetupIsolateForWasmModule(serialization_isolate);
MaybeHandle<WasmModuleObject> module_object =
SyncCompile(serialization_isolate, &thrower,
ModuleWireBytes(buffer.begin(), buffer.end()));
serialization_isolate->wasm_engine()->SyncCompile(
serialization_isolate, &thrower,
ModuleWireBytes(buffer.begin(), buffer.end()));
MaybeHandle<WasmCompiledModule> compiled_module(
module_object.ToHandleChecked()->compiled_module(),
......@@ -531,8 +536,10 @@ TEST(TransferrableWasmModules) {
HandleScope scope(from_isolate);
testing::SetupIsolateForWasmModule(from_isolate);
MaybeHandle<WasmModuleObject> module_object = SyncCompile(
from_isolate, &thrower, ModuleWireBytes(buffer.begin(), buffer.end()));
MaybeHandle<WasmModuleObject> module_object =
from_isolate->wasm_engine()->SyncCompile(
from_isolate, &thrower,
ModuleWireBytes(buffer.begin(), buffer.end()));
v8::Local<v8::WasmCompiledModule> v8_module =
v8::Local<v8::WasmCompiledModule>::Cast(v8::Utils::ToLocal(
Handle<JSObject>::cast(module_object.ToHandleChecked())));
......@@ -685,9 +692,8 @@ TEST(TestInterruptLoop) {
testing::SetupIsolateForWasmModule(isolate);
ErrorThrower thrower(isolate, "Test");
const Handle<WasmInstanceObject> instance =
SyncCompileAndInstantiate(isolate, &thrower,
ModuleWireBytes(buffer.begin(), buffer.end()),
{}, {})
CompileAndInstantiateForTesting(
isolate, &thrower, ModuleWireBytes(buffer.begin(), buffer.end()))
.ToHandleChecked();
Handle<JSArrayBuffer> memory(instance->memory_object()->array_buffer(),
......@@ -768,9 +774,8 @@ TEST(Run_WasmModule_GrowMemOobFixedIndex) {
ErrorThrower thrower(isolate, "Test");
Handle<WasmInstanceObject> instance =
SyncCompileAndInstantiate(isolate, &thrower,
ModuleWireBytes(buffer.begin(), buffer.end()),
{}, {})
CompileAndInstantiateForTesting(
isolate, &thrower, ModuleWireBytes(buffer.begin(), buffer.end()))
.ToHandleChecked();
// Initial memory size is 16 pages, should trap till index > MemSize on
......@@ -816,9 +821,8 @@ TEST(Run_WasmModule_GrowMemOobVariableIndex) {
ErrorThrower thrower(isolate, "Test");
Handle<WasmInstanceObject> instance =
SyncCompileAndInstantiate(isolate, &thrower,
ModuleWireBytes(buffer.begin(), buffer.end()),
{}, {})
CompileAndInstantiateForTesting(
isolate, &thrower, ModuleWireBytes(buffer.begin(), buffer.end()))
.ToHandleChecked();
// Initial memory size is 16 pages, should trap till index > MemSize on
......@@ -945,9 +949,8 @@ TEST(InitDataAtTheUpperLimit) {
'c' // data bytes
};
SyncCompileAndInstantiate(isolate, &thrower,
ModuleWireBytes(data, data + arraysize(data)), {},
{});
CompileAndInstantiateForTesting(
isolate, &thrower, ModuleWireBytes(data, data + arraysize(data)));
if (thrower.error()) {
thrower.Reify()->Print();
FATAL("compile or instantiate error");
......@@ -982,9 +985,8 @@ TEST(EmptyMemoryNonEmptyDataSegment) {
'c' // data bytes
};
SyncCompileAndInstantiate(isolate, &thrower,
ModuleWireBytes(data, data + arraysize(data)), {},
{});
CompileAndInstantiateForTesting(
isolate, &thrower, ModuleWireBytes(data, data + arraysize(data)));
// It should not be possible to instantiate this module.
CHECK(thrower.error());
}
......@@ -1016,9 +1018,8 @@ TEST(EmptyMemoryEmptyDataSegment) {
U32V_1(0), // source size
};
SyncCompileAndInstantiate(isolate, &thrower,
ModuleWireBytes(data, data + arraysize(data)), {},
{});
CompileAndInstantiateForTesting(
isolate, &thrower, ModuleWireBytes(data, data + arraysize(data)));
// It should be possible to instantiate this module.
CHECK(!thrower.error());
}
......@@ -1050,9 +1051,8 @@ TEST(MemoryWithOOBEmptyDataSegment) {
U32V_1(0), // source size
};
SyncCompileAndInstantiate(isolate, &thrower,
ModuleWireBytes(data, data + arraysize(data)), {},
{});
CompileAndInstantiateForTesting(
isolate, &thrower, ModuleWireBytes(data, data + arraysize(data)));
// It should not be possible to instantiate this module.
CHECK(thrower.error());
}
......@@ -1104,9 +1104,8 @@ TEST(Run_WasmModule_Buffer_Externalized_GrowMem) {
testing::SetupIsolateForWasmModule(isolate);
ErrorThrower thrower(isolate, "Test");
const Handle<WasmInstanceObject> instance =
SyncCompileAndInstantiate(isolate, &thrower,
ModuleWireBytes(buffer.begin(), buffer.end()),
{}, {})
CompileAndInstantiateForTesting(
isolate, &thrower, ModuleWireBytes(buffer.begin(), buffer.end()))
.ToHandleChecked();
Handle<WasmMemoryObject> memory_object(instance->memory_object(), isolate);
......@@ -1198,8 +1197,9 @@ TEST(AtomicOpDisassembly) {
testing::SetupIsolateForWasmModule(isolate);
ErrorThrower thrower(isolate, "Test");
MaybeHandle<WasmModuleObject> module_object = SyncCompile(
isolate, &thrower, ModuleWireBytes(buffer.begin(), buffer.end()));
MaybeHandle<WasmModuleObject> module_object =
isolate->wasm_engine()->SyncCompile(
isolate, &thrower, ModuleWireBytes(buffer.begin(), buffer.end()));
Handle<WasmCompiledModule> compiled_module(
module_object.ToHandleChecked()->compiled_module(), isolate);
......
......@@ -9,8 +9,8 @@
#include "src/objects-inl.h"
#include "src/objects.h"
#include "src/property-descriptor.h"
#include "src/wasm/module-compiler.h"
#include "src/wasm/module-decoder.h"
#include "src/wasm/wasm-engine.h"
#include "src/wasm/wasm-interpreter.h"
#include "src/wasm/wasm-js.h"
#include "src/wasm/wasm-module.h"
......@@ -26,6 +26,17 @@ uint32_t GetInitialMemSize(const WasmModule* module) {
return kWasmPageSize * module->initial_pages;
}
MaybeHandle<WasmInstanceObject> CompileAndInstantiateForTesting(
Isolate* isolate, ErrorThrower* thrower, const ModuleWireBytes& bytes) {
MaybeHandle<WasmModuleObject> module =
isolate->wasm_engine()->SyncCompile(isolate, thrower, bytes);
DCHECK_EQ(thrower->error(), module.is_null());
if (module.is_null()) return {};
return isolate->wasm_engine()->SyncInstantiate(
isolate, thrower, module.ToHandleChecked(), {}, {});
}
std::unique_ptr<WasmModule> DecodeWasmModuleForTesting(
Isolate* isolate, ErrorThrower* thrower, const byte* module_start,
const byte* module_end, ModuleOrigin origin, bool verify_functions) {
......@@ -117,8 +128,8 @@ int32_t CompileAndRunWasmModule(Isolate* isolate, const byte* module_start,
const byte* module_end) {
HandleScope scope(isolate);
ErrorThrower thrower(isolate, "CompileAndRunWasmModule");
MaybeHandle<WasmInstanceObject> instance = SyncCompileAndInstantiate(
isolate, &thrower, ModuleWireBytes(module_start, module_end), {}, {});
MaybeHandle<WasmInstanceObject> instance = CompileAndInstantiateForTesting(
isolate, &thrower, ModuleWireBytes(module_start, module_end));
if (instance.is_null()) {
return -1;
}
......@@ -130,15 +141,17 @@ int32_t CompileAndRunAsmWasmModule(Isolate* isolate, const byte* module_start,
const byte* module_end) {
HandleScope scope(isolate);
ErrorThrower thrower(isolate, "CompileAndRunAsmWasmModule");
MaybeHandle<WasmModuleObject> module = wasm::SyncCompileTranslatedAsmJs(
isolate, &thrower, ModuleWireBytes(module_start, module_end),
Handle<Script>::null(), Vector<const byte>());
MaybeHandle<WasmModuleObject> module =
isolate->wasm_engine()->SyncCompileTranslatedAsmJs(
isolate, &thrower, ModuleWireBytes(module_start, module_end),
Handle<Script>::null(), Vector<const byte>());
DCHECK_EQ(thrower.error(), module.is_null());
if (module.is_null()) return -1;
MaybeHandle<WasmInstanceObject> instance = wasm::SyncInstantiate(
isolate, &thrower, module.ToHandleChecked(), Handle<JSReceiver>::null(),
Handle<JSArrayBuffer>::null());
MaybeHandle<WasmInstanceObject> instance =
isolate->wasm_engine()->SyncInstantiate(
isolate, &thrower, module.ToHandleChecked(),
Handle<JSReceiver>::null(), Handle<JSArrayBuffer>::null());
DCHECK_EQ(thrower.error(), instance.is_null());
if (instance.is_null()) return -1;
......
......@@ -54,6 +54,10 @@ bool InterpretWasmModuleForTesting(Isolate* isolate,
int32_t CompileAndRunWasmModule(Isolate* isolate, const byte* module_start,
const byte* module_end);
// Decode, compile, and instantiate the given module with no imports.
MaybeHandle<WasmInstanceObject> CompileAndInstantiateForTesting(
Isolate* isolate, ErrorThrower* thrower, const ModuleWireBytes& bytes);
// Interprets the given module, starting at the function specified by
// {function_index}. The return type of the function has to be int32. The module
// should not have any imports or exports
......
......@@ -13,8 +13,8 @@
#include "src/isolate.h"
#include "src/objects-inl.h"
#include "src/objects.h"
#include "src/wasm/module-compiler.h"
#include "src/wasm/wasm-api.h"
#include "src/wasm/wasm-engine.h"
#include "src/wasm/wasm-module.h"
#include "test/common/wasm/flag-utils.h"
#include "test/common/wasm/wasm-module-runner.h"
......@@ -93,8 +93,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
Promise::Resolver::New(support->GetContext()));
Local<Promise> promise = resolver->GetPromise();
AsyncCompile(i_isolate, Utils::OpenHandle(*promise),
ModuleWireBytes(data, data + size), false);
i_isolate->wasm_engine()->AsyncCompile(i_isolate, Utils::OpenHandle(*promise),
ModuleWireBytes(data, data + size),
false);
ASSIGN(Function, instantiate_impl,
Function::New(support->GetContext(), &InstantiateCallback,
......
......@@ -7,7 +7,6 @@
#include "include/v8.h"
#include "src/isolate.h"
#include "src/objects-inl.h"
#include "src/wasm/module-compiler.h"
#include "src/wasm/wasm-api.h"
#include "src/wasm/wasm-engine.h"
#include "src/wasm/wasm-module-builder.h"
......@@ -71,9 +70,10 @@ void InterpretAndExecuteModule(i::Isolate* isolate,
ScheduledErrorThrower thrower(isolate, "WebAssembly Instantiation");
// Try to instantiate and interpret the module_object.
MaybeHandle<WasmInstanceObject> maybe_instance =
SyncInstantiate(isolate, &thrower, module_object,
Handle<JSReceiver>::null(), // imports
MaybeHandle<JSArrayBuffer>()); // memory
isolate->wasm_engine()->SyncInstantiate(
isolate, &thrower, module_object,
Handle<JSReceiver>::null(), // imports
MaybeHandle<JSArrayBuffer>()); // memory
Handle<WasmInstanceObject> instance;
if (!maybe_instance.ToHandle(&instance)) return;
if (!testing::InterpretWasmModuleForTesting(isolate, instance, "main", 0,
......@@ -82,9 +82,10 @@ void InterpretAndExecuteModule(i::Isolate* isolate,
}
// Instantiate and execute the module_object.
maybe_instance = SyncInstantiate(isolate, &thrower, module_object,
Handle<JSReceiver>::null(), // imports
MaybeHandle<JSArrayBuffer>()); // memory
maybe_instance = isolate->wasm_engine()->SyncInstantiate(
isolate, &thrower, module_object,
Handle<JSReceiver>::null(), // imports
MaybeHandle<JSArrayBuffer>()); // memory
if (!maybe_instance.ToHandle(&instance)) return;
testing::RunWasmModuleForTesting(isolate, instance, 0, nullptr);
......@@ -241,7 +242,8 @@ int WasmExecutionFuzzer::FuzzWasmModule(const uint8_t* data, size_t size,
MaybeHandle<WasmModuleObject> compiled_module;
{
FlagScope<bool> no_liftoff(&FLAG_liftoff, false);
compiled_module = SyncCompile(i_isolate, &interpreter_thrower, wire_bytes);
compiled_module = i_isolate->wasm_engine()->SyncCompile(
i_isolate, &interpreter_thrower, wire_bytes);
}
bool compiles = !compiled_module.is_null();
......@@ -260,9 +262,10 @@ int WasmExecutionFuzzer::FuzzWasmModule(const uint8_t* data, size_t size,
int32_t result_interpreter;
bool possible_nondeterminism = false;
{
MaybeHandle<WasmInstanceObject> interpreter_instance = SyncInstantiate(
i_isolate, &interpreter_thrower, compiled_module.ToHandleChecked(),
MaybeHandle<JSReceiver>(), MaybeHandle<JSArrayBuffer>());
MaybeHandle<WasmInstanceObject> interpreter_instance =
i_isolate->wasm_engine()->SyncInstantiate(
i_isolate, &interpreter_thrower, compiled_module.ToHandleChecked(),
MaybeHandle<JSReceiver>(), MaybeHandle<JSArrayBuffer>());
// Ignore instantiation failure.
if (interpreter_thrower.error()) {
......@@ -286,9 +289,10 @@ int WasmExecutionFuzzer::FuzzWasmModule(const uint8_t* data, size_t size,
int32_t result_turbofan;
{
ErrorThrower compiler_thrower(i_isolate, "Turbofan");
MaybeHandle<WasmInstanceObject> compiled_instance = SyncInstantiate(
i_isolate, &compiler_thrower, compiled_module.ToHandleChecked(),
MaybeHandle<JSReceiver>(), MaybeHandle<JSArrayBuffer>());
MaybeHandle<WasmInstanceObject> compiled_instance =
i_isolate->wasm_engine()->SyncInstantiate(
i_isolate, &compiler_thrower, compiled_module.ToHandleChecked(),
MaybeHandle<JSReceiver>(), MaybeHandle<JSArrayBuffer>());
DCHECK(!compiler_thrower.error());
result_turbofan = testing::CallWasmFunctionForTesting(
......@@ -315,9 +319,8 @@ int WasmExecutionFuzzer::FuzzWasmModule(const uint8_t* data, size_t size,
ErrorThrower compiler_thrower(i_isolate, "Liftoff");
// Re-compile with Liftoff.
MaybeHandle<WasmInstanceObject> compiled_instance =
SyncCompileAndInstantiate(i_isolate, &compiler_thrower, wire_bytes,
MaybeHandle<JSReceiver>(),
MaybeHandle<JSArrayBuffer>());
testing::CompileAndInstantiateForTesting(i_isolate, &compiler_thrower,
wire_bytes);
DCHECK(!compiler_thrower.error());
result_liftoff = testing::CallWasmFunctionForTesting(
i_isolate, compiled_instance.ToHandleChecked(), &compiler_thrower,
......
......@@ -12,7 +12,7 @@
#include "src/isolate.h"
#include "src/objects-inl.h"
#include "src/objects.h"
#include "src/wasm/module-compiler.h"
#include "src/wasm/wasm-engine.h"
#include "src/wasm/wasm-module.h"
#include "test/common/wasm/flag-utils.h"
#include "test/common/wasm/wasm-module-runner.h"
......@@ -42,8 +42,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
i::HandleScope scope(i_isolate);
i::wasm::ErrorThrower thrower(i_isolate, "wasm fuzzer");
i::MaybeHandle<i::WasmModuleObject> maybe_object = SyncCompile(
i_isolate, &thrower, i::wasm::ModuleWireBytes(data, data + size));
i::MaybeHandle<i::WasmModuleObject> maybe_object =
i_isolate->wasm_engine()->SyncCompile(
i_isolate, &thrower, i::wasm::ModuleWireBytes(data, data + size));
i::Handle<i::WasmModuleObject> module_object;
if (maybe_object.ToHandle(&module_object)) {
i::wasm::fuzzer::InterpretAndExecuteModule(i_isolate, module_object);
......
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