[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