Commit 2392fd87 authored by Michael Starzinger's avatar Michael Starzinger Committed by Commit Bot

[wasm] Avoid internal implicit receivers for API functions.

This assigns dummy instance templates to all WebAssembly API functions
used as constructors. It hence avoids implicit receivers from having the
internal instance types. These objects would never be fully initialized
and causes heap iterations to stumble over these objects.

R=clemensh@chromium.org
BUG=v8:8003

Change-Id: I3c81d8dc3ae4a38e650b390a04170585cb31ec77
Reviewed-on: https://chromium-review.googlesource.com/1170685Reviewed-by: 's avatarClemens Hammacher <clemensh@chromium.org>
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55037}
parent f4ca3fc5
......@@ -223,10 +223,12 @@ void HeapObject::HeapObjectVerify(Isolate* isolate) {
case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
case WASM_GLOBAL_TYPE:
case WASM_MEMORY_TYPE:
case WASM_MODULE_TYPE:
case WASM_TABLE_TYPE:
JSObject::cast(this)->JSObjectVerify(isolate);
break;
case WASM_MODULE_TYPE:
WasmModuleObject::cast(this)->WasmModuleObjectVerify(isolate);
break;
case WASM_INSTANCE_TYPE:
WasmInstanceObject::cast(this)->WasmInstanceObjectVerify(isolate);
break;
......@@ -1678,7 +1680,9 @@ void WasmExportedFunctionData::WasmExportedFunctionDataVerify(
void WasmModuleObject::WasmModuleObjectVerify(Isolate* isolate) {
CHECK(IsWasmModuleObject());
VerifyObjectField(isolate, kNativeModuleOffset);
CHECK(managed_native_module()->IsForeign());
VerifyObjectField(isolate, kExportWrappersOffset);
CHECK(export_wrappers()->IsFixedArray());
VerifyObjectField(isolate, kScriptOffset);
VerifyObjectField(isolate, kAsmJsOffsetTableOffset);
VerifyObjectField(isolate, kBreakPointInfosOffset);
......
......@@ -1296,19 +1296,26 @@ void WebAssemblyGlobalSetValue(
// TODO(titzer): we use the API to create the function template because the
// internal guts are too ugly to replicate here.
static i::Handle<i::FunctionTemplateInfo> NewTemplate(i::Isolate* i_isolate,
FunctionCallback func) {
static i::Handle<i::FunctionTemplateInfo> NewFunctionTemplate(
i::Isolate* i_isolate, FunctionCallback func) {
Isolate* isolate = reinterpret_cast<Isolate*>(i_isolate);
Local<FunctionTemplate> templ = FunctionTemplate::New(isolate, func);
templ->ReadOnlyPrototype();
return v8::Utils::OpenHandle(*templ);
}
static i::Handle<i::ObjectTemplateInfo> NewObjectTemplate(
i::Isolate* i_isolate) {
Isolate* isolate = reinterpret_cast<Isolate*>(i_isolate);
Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
return v8::Utils::OpenHandle(*templ);
}
namespace internal {
Handle<JSFunction> CreateFunc(Isolate* isolate, Handle<String> name,
FunctionCallback func) {
Handle<FunctionTemplateInfo> temp = NewTemplate(isolate, func);
Handle<FunctionTemplateInfo> temp = NewFunctionTemplate(isolate, func);
Handle<JSFunction> function =
ApiNatives::InstantiateFunction(temp, name).ToHandleChecked();
DCHECK(function->shared()->HasSharedName());
......@@ -1367,6 +1374,15 @@ void InstallGetterSetter(Isolate* isolate, Handle<JSObject> object,
Utils::ToLocal(setter_func), attributes);
}
// Assigns a dummy instance template to the given constructor function. Used to
// make sure the implicit receivers for the constructors in this file have an
// instance type different from the internal one, they allocate the resulting
// object explicitly and ignore implicit receiver.
void SetDummyInstanceTemplate(Isolate* isolate, Handle<JSFunction> fun) {
Handle<ObjectTemplateInfo> instance_template = NewObjectTemplate(isolate);
fun->shared()->get_api_func_data()->set_instance_template(*instance_template);
}
void WasmJs::Install(Isolate* isolate, bool exposed_on_global_object) {
Handle<JSGlobalObject> global = isolate->global_object();
Handle<Context> context(global->native_context(), isolate);
......@@ -1412,6 +1428,7 @@ void WasmJs::Install(Isolate* isolate, bool exposed_on_global_object) {
Handle<JSFunction> module_constructor =
InstallFunc(isolate, webassembly, "Module", WebAssemblyModule, 1);
context->set_wasm_module_constructor(*module_constructor);
SetDummyInstanceTemplate(isolate, module_constructor);
JSFunction::EnsureHasInitialMap(module_constructor);
Handle<JSObject> module_proto(
JSObject::cast(module_constructor->instance_prototype()), isolate);
......@@ -1431,6 +1448,7 @@ void WasmJs::Install(Isolate* isolate, bool exposed_on_global_object) {
Handle<JSFunction> instance_constructor =
InstallFunc(isolate, webassembly, "Instance", WebAssemblyInstance, 1);
context->set_wasm_instance_constructor(*instance_constructor);
SetDummyInstanceTemplate(isolate, instance_constructor);
JSFunction::EnsureHasInitialMap(instance_constructor);
Handle<JSObject> instance_proto(
JSObject::cast(instance_constructor->instance_prototype()), isolate);
......@@ -1447,6 +1465,7 @@ void WasmJs::Install(Isolate* isolate, bool exposed_on_global_object) {
Handle<JSFunction> table_constructor =
InstallFunc(isolate, webassembly, "Table", WebAssemblyTable, 1);
context->set_wasm_table_constructor(*table_constructor);
SetDummyInstanceTemplate(isolate, table_constructor);
JSFunction::EnsureHasInitialMap(table_constructor);
Handle<JSObject> table_proto(
JSObject::cast(table_constructor->instance_prototype()), isolate);
......@@ -1464,6 +1483,7 @@ void WasmJs::Install(Isolate* isolate, bool exposed_on_global_object) {
Handle<JSFunction> memory_constructor =
InstallFunc(isolate, webassembly, "Memory", WebAssemblyMemory, 1);
context->set_wasm_memory_constructor(*memory_constructor);
SetDummyInstanceTemplate(isolate, memory_constructor);
JSFunction::EnsureHasInitialMap(memory_constructor);
Handle<JSObject> memory_proto(
JSObject::cast(memory_constructor->instance_prototype()), isolate);
......@@ -1481,6 +1501,7 @@ void WasmJs::Install(Isolate* isolate, bool exposed_on_global_object) {
Handle<JSFunction> global_constructor =
InstallFunc(isolate, webassembly, "Global", WebAssemblyGlobal, 1);
context->set_wasm_global_constructor(*global_constructor);
SetDummyInstanceTemplate(isolate, global_constructor);
JSFunction::EnsureHasInitialMap(global_constructor);
Handle<JSObject> global_proto(
JSObject::cast(global_constructor->instance_prototype()), isolate);
......
......@@ -212,15 +212,6 @@ Handle<WasmModuleObject> WasmModuleObject::New(
static_cast<int>(native_module->module()->num_exported_functions);
Handle<FixedArray> export_wrappers =
isolate->factory()->NewFixedArray(export_wrapper_size, TENURED);
Handle<WasmModuleObject> module_object = Handle<WasmModuleObject>::cast(
isolate->factory()->NewJSObject(isolate->wasm_module_constructor()));
module_object->set_export_wrappers(*export_wrappers);
if (script->type() == Script::TYPE_WASM) {
script->set_wasm_module_object(*module_object);
}
module_object->set_script(*script);
module_object->set_weak_instance_list(
ReadOnlyRoots(isolate).empty_weak_array_list());
// Use the given shared {NativeModule}, but increase its reference count by
// allocating a new {Managed<T>} that the {WasmModuleObject} references.
......@@ -232,6 +223,16 @@ Handle<WasmModuleObject> WasmModuleObject::New(
Handle<Managed<wasm::NativeModule>> managed_native_module =
Managed<wasm::NativeModule>::FromSharedPtr(isolate, memory_estimate,
std::move(native_module));
Handle<WasmModuleObject> module_object = Handle<WasmModuleObject>::cast(
isolate->factory()->NewJSObject(isolate->wasm_module_constructor()));
module_object->set_export_wrappers(*export_wrappers);
if (script->type() == Script::TYPE_WASM) {
script->set_wasm_module_object(*module_object);
}
module_object->set_script(*script);
module_object->set_weak_instance_list(
ReadOnlyRoots(isolate).empty_weak_array_list());
module_object->set_managed_native_module(*managed_native_module);
return 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