Commit 5f8a6ec4 authored by mtrofin's avatar mtrofin Committed by Commit bot

[wasm] consolidate wasm and asm.js module compilation sequence

This unblocks avoiding the separate code template.
In the upcoming CL doing away with code templates, We need to track instances
through the module object, which needs to be separate from the compiled module
data, which is then shared with the first instance.

This CL ensures we have the object available in the asm.js scenario, too.

Note that this CL also unifies the error messaging when module
decoding fails.

BUG=v8:5316

Review-Url: https://codereview.chromium.org/2299873002
Cr-Commit-Position: refs/heads/master@{#39097}
parent f93ee70c
......@@ -7040,8 +7040,9 @@ MaybeLocal<WasmCompiledModule> WasmCompiledModule::Deserialize(
if (!maybe_compiled_part.ToHandle(&compiled_part)) {
return MaybeLocal<WasmCompiledModule>();
}
return Local<WasmCompiledModule>::Cast(Utils::ToLocal(
i::wasm::CreateCompiledModuleObject(i_isolate, compiled_part)));
return Local<WasmCompiledModule>::Cast(
Utils::ToLocal(i::wasm::CreateCompiledModuleObject(
i_isolate, compiled_part, i::wasm::ModuleOrigin::kWasmOrigin)));
}
// static
......
......@@ -30,29 +30,6 @@ namespace v8 {
namespace internal {
namespace {
i::MaybeHandle<i::FixedArray> CompileModule(
i::Isolate* isolate, const byte* start, const byte* end,
ErrorThrower* thrower,
internal::wasm::ModuleOrigin origin = i::wasm::kWasmOrigin) {
// Decode but avoid a redundant pass over function bodies for verification.
// Verification will happen during compilation.
i::Zone zone(isolate->allocator());
internal::wasm::ModuleResult result = internal::wasm::DecodeWasmModule(
isolate, &zone, start, end, false, origin);
i::MaybeHandle<i::FixedArray> compiled_module;
if (result.failed() && origin == internal::wasm::kAsmJsOrigin) {
thrower->Error("Asm.js converted module failed to decode");
} else if (result.failed()) {
thrower->Failed("", result);
} else {
compiled_module = result.val->CompileFunctions(isolate, thrower);
}
if (result.val) delete result.val;
return compiled_module;
}
Handle<i::Object> StdlibMathMember(i::Isolate* isolate,
Handle<JSReceiver> stdlib,
Handle<Name> name) {
......@@ -187,9 +164,9 @@ MaybeHandle<FixedArray> AsmJs::ConvertAsmToWasm(ParseInfo* info) {
i::Handle<i::FixedArray> foreign_globals;
auto module = builder.Run(&foreign_globals);
i::MaybeHandle<i::FixedArray> compiled =
CompileModule(info->isolate(), module->begin(), module->end(), &thrower,
internal::wasm::kAsmJsOrigin);
i::MaybeHandle<i::JSObject> compiled = wasm::CreateModuleObjectFromBytes(
info->isolate(), module->begin(), module->end(), &thrower,
internal::wasm::kAsmJsOrigin);
DCHECK(!compiled.is_null());
wasm::AsmTyper::StdlibSet uses = typer.StdlibUses();
......@@ -223,7 +200,9 @@ MaybeHandle<Object> AsmJs::InstantiateAsmWasm(i::Isolate* isolate,
Handle<FixedArray> wasm_data,
Handle<JSArrayBuffer> memory,
Handle<JSReceiver> foreign) {
i::Handle<i::FixedArray> compiled(i::FixedArray::cast(wasm_data->get(0)));
i::Handle<i::JSObject> module(i::JSObject::cast(wasm_data->get(0)));
i::Handle<i::FixedArray> compiled(
i::FixedArray::cast(module->GetInternalField(0)));
i::Handle<i::FixedArray> foreign_globals(
i::FixedArray::cast(wasm_data->get(1)));
......
......@@ -769,7 +769,8 @@ RUNTIME_FUNCTION(Runtime_DeserializeWasmModule) {
if (!maybe_compiled_module.ToHandle(&compiled_module)) {
return isolate->heap()->undefined_value();
}
return *wasm::CreateCompiledModuleObject(isolate, compiled_module);
return *wasm::CreateCompiledModuleObject(isolate, compiled_module,
wasm::ModuleOrigin::kWasmOrigin);
}
} // namespace internal
......
......@@ -195,20 +195,9 @@ static i::MaybeHandle<i::JSObject> CreateModuleObject(
if (buffer.start == nullptr) return i::MaybeHandle<i::JSObject>();
DCHECK(source->IsArrayBuffer() || source->IsTypedArray());
i::Zone zone(i_isolate->allocator());
i::wasm::ModuleResult result = i::wasm::DecodeWasmModule(
i_isolate, &zone, buffer.start, buffer.end, false, i::wasm::kWasmOrigin);
std::unique_ptr<const i::wasm::WasmModule> decoded_module(result.val);
if (result.failed()) {
thrower->Failed("", result);
return nothing;
}
i::MaybeHandle<i::FixedArray> compiled_module =
decoded_module->CompileFunctions(i_isolate, thrower);
if (compiled_module.is_null()) return nothing;
return i::wasm::CreateCompiledModuleObject(i_isolate,
compiled_module.ToHandleChecked());
return i::wasm::CreateModuleObjectFromBytes(
i_isolate, buffer.start, buffer.end, thrower,
i::wasm::ModuleOrigin::kWasmOrigin);
}
void WebAssemblyCompile(const v8::FunctionCallbackInfo<v8::Value>& args) {
......
......@@ -1629,17 +1629,50 @@ int GetNumberOfFunctions(JSObject* wasm) {
return ByteArray::cast(func_names_obj)->get_int(0);
}
Handle<JSObject> CreateCompiledModuleObject(
Isolate* isolate, Handle<FixedArray> compiled_module) {
Handle<JSFunction> module_cons(
isolate->native_context()->wasm_module_constructor());
Handle<JSObject> module_obj = isolate->factory()->NewJSObject(module_cons);
Handle<JSObject> CreateCompiledModuleObject(Isolate* isolate,
Handle<FixedArray> compiled_module,
ModuleOrigin origin) {
Handle<JSObject> module_obj;
if (origin == ModuleOrigin::kWasmOrigin) {
Handle<JSFunction> module_cons(
isolate->native_context()->wasm_module_constructor());
module_obj = isolate->factory()->NewJSObject(module_cons);
} else {
DCHECK(origin == ModuleOrigin::kAsmJsOrigin);
Handle<Map> map = isolate->factory()->NewMap(
JS_OBJECT_TYPE, JSObject::kHeaderSize + kPointerSize);
module_obj = isolate->factory()->NewJSObjectFromMap(map, TENURED);
}
module_obj->SetInternalField(0, *compiled_module);
Handle<Symbol> module_sym(isolate->native_context()->wasm_module_sym());
Object::SetProperty(module_obj, module_sym, module_obj, STRICT).Check();
if (origin == ModuleOrigin::kWasmOrigin) {
Handle<Symbol> module_sym(isolate->native_context()->wasm_module_sym());
Object::SetProperty(module_obj, module_sym, module_obj, STRICT).Check();
}
return module_obj;
}
MaybeHandle<JSObject> CreateModuleObjectFromBytes(Isolate* isolate,
const byte* start,
const byte* end,
ErrorThrower* thrower,
ModuleOrigin origin) {
MaybeHandle<JSObject> nothing;
Zone zone(isolate->allocator());
ModuleResult result =
DecodeWasmModule(isolate, &zone, start, end, false, origin);
std::unique_ptr<const WasmModule> decoded_module(result.val);
if (result.failed()) {
thrower->Failed("Wasm decoding failed", result);
return nothing;
}
MaybeHandle<FixedArray> compiled_module =
decoded_module->CompileFunctions(isolate, thrower);
if (compiled_module.is_null()) return nothing;
return CreateCompiledModuleObject(isolate, compiled_module.ToHandleChecked(),
origin);
}
namespace testing {
int32_t CompileAndRunWasmModule(Isolate* isolate, const byte* module_start,
......
......@@ -399,7 +399,14 @@ void PopulateFunctionTable(Handle<FixedArray> table, uint32_t table_size,
const std::vector<Handle<Code>>* code_table);
Handle<JSObject> CreateCompiledModuleObject(Isolate* isolate,
Handle<FixedArray> compiled_module);
Handle<FixedArray> compiled_module,
ModuleOrigin origin);
MaybeHandle<JSObject> CreateModuleObjectFromBytes(Isolate* isolate,
const byte* start,
const byte* end,
ErrorThrower* thrower,
ModuleOrigin origin);
// Assumed to be called with a code object associated to a wasm module instance.
// Intended to be called from runtime functions.
......
......@@ -215,8 +215,8 @@ TEST(Run_WasmModule_Serialization) {
MaybeHandle<FixedArray> compiled_module =
module->CompileFunctions(isolate, &thrower);
CHECK(!compiled_module.is_null());
Handle<JSObject> module_obj =
CreateCompiledModuleObject(isolate, compiled_module.ToHandleChecked());
Handle<JSObject> module_obj = CreateCompiledModuleObject(
isolate, compiled_module.ToHandleChecked(), ModuleOrigin::kWasmOrigin);
v8::Local<v8::Object> v8_module_obj = v8::Utils::ToLocal(module_obj);
CHECK(v8_module_obj->IsWebAssemblyCompiledModule());
......
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