[webkit-changes] [WebKit/WebKit] a6c381: Introduce lazyInitialize and use it in Document
Ryosuke Niwa
noreply at github.com
Wed Nov 13 15:25:20 PST 2024
Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: a6c381f8c36872e7e6267099a8a53d1bf713796d
https://github.com/WebKit/WebKit/commit/a6c381f8c36872e7e6267099a8a53d1bf713796d
Author: Ryosuke Niwa <rniwa at webkit.org>
Date: 2024-11-13 (Wed, 13 Nov 2024)
Changed paths:
M Source/WTF/wtf/RefPtr.h
M Source/WTF/wtf/StdLibExtras.h
M Source/WebCore/dom/Document.cpp
M Source/WebCore/dom/Document.h
Log Message:
-----------
Introduce lazyInitialize and use it in Document
https://bugs.webkit.org/show_bug.cgi?id=283038
Reviewed by Geoffrey Garen and Chris Dumez.
In WebKit, it’s fairly common to write a member variable as `RefPtr` or `std::unique_ptr` that later
gets lazily initialized to some value but never unset or assigned of a different value after that. e.g.
```
class Foo {
Bar& bar() {
if (!m_bar)
m_bar = Bar::create();
return *m_bar;
}
Ref<Bar> protectedBar() { return bar(); }
RefPtr<Bar> m_bar;
}
```
Assuming there is no other code modifying m_bar, `foo->bar()->method()` is always safe to call
even if method wasn’t a trivial function. Right now, static analyzer doesn’t recognize this pattern
so we’d be forced to write code like this: `foo->protectedBar()->method()` where `protectedBar` is
a wrapper function which returns `Ref<Bar>`.
This PR introduces a new convention for this pattern. Namely, we would use `const Ref` or
`const UniqueRef` for when the value is initialized inside the constructor, and `const RefPtr` or
`const unique_ptr` in the case it is lazily initialized. The lazy initialization is done via newly
introduced `lazyInitialize`, which takes `const RefPtr` or `const unique_ptr` and a R-value.
e.g.
```
class Foo {
Bar& bar() {
if (!m_bar)
lazyInitialize(m_bar, Bar::create());
return *m_bar;
}
const RefPtr<Bar> m_bar;
}
```
`lazyInitialize` release asserts that the pointer value isn't set and `const_cast` the pointer type
to set the value. It is a programming error to invoke `lazyInitialize` more than once on a given
instance variable in an object.
* Source/WTF/wtf/RefPtr.h:
(WTF::lazyInitialize):
* Source/WTF/wtf/StdLibExtras.h:
(WTF::lazyInitialize):
* Source/WebCore/dom/Document.cpp:
(WebCore::Document::ensureQuirks):
(WebCore::Document::ensureExtensionStyleSheets):
(WebCore::Document::ensureMarkers):
(WebCore::Document::ensureVisitedLinkState):
(WebCore::Document::ensureFullscreenManager):
(WebCore::Document::fontLoader):
(WebCore::Document::ensureFontLoader):
(WebCore::Document::ensureFontSelector):
(WebCore::Document::ensureUndoManager):
(WebCore::Document::ensureEditor):
(WebCore::Document::ensureReportingScope):
(WebCore::Document::ensureScriptRunner):
(WebCore::Document::ensureTemplateDocument):
(WebCore::Document::ensureIntersectionObserverData):
(WebCore::Document::ensureTimelinesController):
(WebCore::Document::ensurePaintWorklet):
(WebCore::Document::ensureResizeObserverForContainIntrinsicSize):
* Source/WebCore/dom/Document.h:
Canonical link: https://commits.webkit.org/286566@main
To unsubscribe from these emails, change your notification settings at https://github.com/WebKit/WebKit/settings/notifications
More information about the webkit-changes
mailing list