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