[bootstrapper] copy accessors in deserialized global into global object created using global proxy template

Originally, the accessors wont be copied into global object from
deserialized global. And the accessors in serialized global object
will be lost. Fix to copy accessors in deserialized global
into global object when recreating new global object using passed
global proxy template.
Tests credited to xiangyangemail@gmail.com https://chromium-review.googlesource.com/c/v8/v8/+/3405405

Bug: v8:12564
Change-Id: Iefb3a6dbfa5445b227d87c26eb423cf1b924dbb4
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3459937
Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/main@{#79087}
This commit is contained in:
jameslahm 2022-02-14 16:58:10 +08:00 committed by V8 LUCI CQ
parent 9eb7568b5f
commit 05c199ce70
2 changed files with 44 additions and 4 deletions

View File

@ -6011,8 +6011,15 @@ void Genesis::TransferNamedProperties(Handle<JSObject> from,
Handle<Object> value(cell->value(), isolate());
if (value->IsTheHole(isolate())) continue;
PropertyDetails details = cell->property_details();
if (details.kind() != PropertyKind::kData) continue;
JSObject::AddProperty(isolate(), to, key, value, details.attributes());
if (details.kind() == PropertyKind::kData) {
JSObject::AddProperty(isolate(), to, key, value, details.attributes());
} else {
DCHECK_EQ(PropertyKind::kAccessor, details.kind());
DCHECK(!to->HasFastProperties());
PropertyDetails d(PropertyKind::kAccessor, details.attributes(),
PropertyCellType::kMutable);
JSObject::SetNormalizedProperty(to, key, value, d);
}
}
} else if (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) {
@ -6186,8 +6193,8 @@ Genesis::Genesis(
// If no global proxy template was passed in, simply use the global in the
// snapshot. If a global proxy template was passed in it's used to recreate
// the global object and its protype chain, and the data properties from the
// deserialized global are copied onto it.
// the global object and its prototype chain, and the data and the accessor
// properties from the deserialized global are copied onto it.
if (context_snapshot_index == 0 && !global_proxy_template.IsEmpty()) {
Handle<JSGlobalObject> global_object =
CreateNewGlobals(global_proxy_template, global_proxy);

View File

@ -3835,6 +3835,39 @@ UNINITIALIZED_TEST(SnapshotAccessorDescriptors) {
delete[] data1.data;
}
UNINITIALIZED_TEST(SnapshotObjectDefinePropertyWhenNewGlobalTemplate) {
const char* source1 =
"Object.defineProperty(this, 'property1', {\n"
" value: 42,\n"
" writable: false\n"
"});\n"
"var bValue = 38;\n"
"Object.defineProperty(this, 'property2', {\n"
" get() { return bValue; },\n"
" set(newValue) { bValue = newValue; }\n"
"});";
v8::StartupData data1 = CreateSnapshotDataBlob(source1);
v8::Isolate::CreateParams params1;
params1.snapshot_blob = &data1;
params1.array_buffer_allocator = CcTest::array_buffer_allocator();
v8::Isolate* isolate1 = v8::Isolate::New(params1);
{
v8::Isolate::Scope i_scope(isolate1);
v8::HandleScope h_scope(isolate1);
v8::Local<v8::ObjectTemplate> global_template =
v8::ObjectTemplate::New(isolate1);
v8::Local<v8::Context> context =
v8::Context::New(isolate1, nullptr, global_template);
v8::Context::Scope c_scope(context);
ExpectInt32("this.property1", 42);
ExpectInt32("this.property2", 38);
}
isolate1->Dispose();
delete[] data1.data;
}
UNINITIALIZED_TEST(SnapshotCreatorIncludeGlobalProxy) {
DisableAlwaysOpt();
DisableEmbeddedBlobRefcounting();