Index: src/objects.cc |
diff --git a/src/objects.cc b/src/objects.cc |
index 828fcd896a0607ecd52aacfa7f9a0e49080c15bd..3c83fbcb6b93dd6e6e721bc3e9a12fab25bb8030 100644 |
--- a/src/objects.cc |
+++ b/src/objects.cc |
@@ -1356,12 +1356,31 @@ MaybeHandle<Object> Object::GetPropertyWithAccessor(LookupIterator* it) { |
return handle(*result, isolate); |
} |
- // Regular accessor. |
Handle<Object> getter(AccessorPair::cast(*structure)->getter(), isolate); |
if (getter->IsFunctionTemplateInfo()) { |
- return Builtins::InvokeApiFunction( |
- isolate, false, Handle<FunctionTemplateInfo>::cast(getter), receiver, 0, |
- nullptr, isolate->factory()->undefined_value()); |
+ Handle<FunctionTemplateInfo> fti = |
+ Handle<FunctionTemplateInfo>::cast(getter); |
+ |
+ // Check if the accessor is backed by a private property (surrogate |
+ // accessor). |
+ if (!fti->cache_property()->IsTheHole(isolate)) { |
+ Handle<Name> name = handle(Name::cast(fti->cache_property()), isolate); |
+ |
+ LookupIterator cache_it = LookupIterator::PropertyOrElement( |
+ isolate, it->GetStoreTarget(), name); |
+ |
+ // The hidden property must be set before it's accessed. |
+ // This will catch setting the hidden property on the wrong object in most |
+ // cases. |
+ CHECK_EQ(LookupIterator::DATA, cache_it.state()); |
+ return Object::GetProperty(&cache_it); |
+ } |
+ |
+ // Regular accessor. |
+ return Builtins::InvokeApiFunction(isolate, false, fti, receiver, 0, |
+ nullptr, |
+ isolate->factory()->undefined_value()); |
+ |
} else if (getter->IsCallable()) { |
// TODO(rossberg): nicer would be to cast to some JSCallable here... |
return Object::GetPropertyWithDefinedGetter( |
@@ -19900,5 +19919,19 @@ bool Module::Instantiate(Handle<Module> module, v8::Local<v8::Context> context, |
return true; |
} |
+MaybeHandle<Name> FunctionTemplateInfo::TryGetCachePropertyName( |
+ Isolate* isolate, Handle<Object> getter) { |
+ if (getter->IsFunctionTemplateInfo()) { |
+ Handle<FunctionTemplateInfo> fti = |
+ Handle<FunctionTemplateInfo>::cast(getter); |
+ // Check if the accessor is backed by a private property (cached accessor). |
+ if (!fti->cache_property()->IsTheHole(isolate)) { |
+ Handle<Name> name = handle(Name::cast(fti->cache_property())); |
+ return MaybeHandle<Name>(name); |
+ } |
+ } |
+ return MaybeHandle<Name>(); |
+} |
+ |
} // namespace internal |
} // namespace v8 |