# Anatomy of Web Browsers ###### tags: `GUI` `Operating System` `Computer Networking` `Computer Graphics` `API` `App` `Protocol` `Software` `Hardware` `Cross Platform` `System Design` `Web Technology` `Browser Engine` `Rendering Engine` `JavaScript Engine` `Chromium` `Webkit` `Blink` `JavaScript` `CSS` `Parser` In this note, we discuss 2 topics of the modern web browsers: 1. the modern browser architectures. 2. the browser engine (rendering engine + JavaScript engine) of the render process in the multi-process browser architecture. **Intro:** - [Multi-Processes in Browsers: Chrome, Internet Explorer, Firefox and WebKit - Softpedia](https://news.softpedia.com/news/Multi-Processes-in-Browsers-Chrome-Internet-Explorer-Firefox-and-WebKit-140535.shtml) - [Multi-process Architecture - Chromium Docs](https://www.chromium.org/developers/design-documents/multi-process-architecture/) - [Chromium 架构简介 - 力战者 - 掘金](https://juejin.cn/post/7148427252487684110) - [Inside look at modern web browser - Chrome for Developer](https://developer.chrome.com/blog/inside-browser-part1) **Resources:** - [How Blink works - haraken - Chromium Docs](https://docs.google.com/document/d/1aitSOucL0VHZa9Z2vbRJSyAIsAz24kX8LFByQ5xQnUg) - [[Book] High Performance Browser Networking (O'Reilly) - Grigorik, Ilya](https://hpbn.co/) - [[Series] Webkit - sauphy - CSDN](https://blog.csdn.net/sauphy/category_3275265.html) ## Overview ### Chromium Multi-Process Architecture *Works along with a decoupled event-driven IPC system.* :::info :+1: :+1: Walkthrough: [[Slides] Android Chromium Rendering Pipeline - Hyungwook Lee](https://www.slideshare.net/slideshow/android-chromium-rendering-pipeline/46149418). ::: > (reversed bottom-up) multi-process architecture: > ![Chromium Architecture](https://hackmd.io/_uploads/HyiHOGWl-e.png =650x) > > (Source: [Explore the Magic Behind Google Chrome - Medium](https://zicodeng.medium.com/explore-the-magic-behind-google-chrome-c3563dbd2739)) > ![image](https://hackmd.io/_uploads/BJL8gQbxWl.png =650x) > > (Source: [Multi-process Architecture - Chromium Docs](https://www.chromium.org/developers/design-documents/multi-process-architecture/)) - **Browser Process:** system's core. > **`Render...Host` represents the broker instance for proxying messages between Browser Process (`Render...Host`) & Renderer Process (`Render...`).** - **UI (main) thread:** manage & dispatch system's resources ---- *UI, input events, networks, filesystems, ...* - **`RenderProcessHost`(s):** represent the broker of ++Render Process' main thread's `RenderProcess`++. :::info **`RenderProcessHost` vs. `RenderViewHost`(s)** *Render Process broker vs. per Renderer Instance broker* It may queue & pipe view-specific messages then forward particular messages to the corresponding view's/frame's host. For example, `SetCursor` message from WebKit: ```sh! RenderProcessHost::OnMessageReceived -> RenderViewHost::OnMessageReceived -> RenderWidgetHost::OnMsgSetCursorImpl (not navigation-specific) ``` [How Chromium Displays Web Pages - Chromium Docs](https://www.chromium.org/developers/design-documents/displaying-a-web-page-in-chrome/#life-of-a-mouse-click-message) ::: :::warning **Same Site Isolation** Each render process should stick with only one site origin (`SiteInstance`). ::: - **`WebContents`(es):** the instance that represents all things about a web page rendering into a view. > **`WebContents` exposes a ++web page instance (render view)++ that can be interacted with.** > ![image](https://hackmd.io/_uploads/rkgCtoUiA.png =450x) - **`RenderViewHost`**/**`RenderFrameHost`/`RenderWidgetHost`**: represent ++Render Process' render thread's each "RenderView"++. > **`RenderWidgetHost` is implemented in different GUI platforms such as `RenderWidgetHostView[Aura|Gtk|Mac|Win]`.** :::warning **`WebContents` ---- Browser (Upper Layers) vs. `//content/` (Core Module)** By using `WebContents`, browser can interact with each renderer-related components (defined under `//contents/`): - **tab-helper:** browser-maintained additional useful data (`WebContentsUserData`) ---- favicon, infobar, ... - **browser-side renderer broker:** ++Browser Process' UI thread's `Render...Host`++. - **actual renderer:** ++Render Process' render thread's resources++. ```sh! Browser -WebContent instance-> Render View Host <-IPC system communication-> Render View -bindings & callbacks-> Browser Engine (rendering engine + js engine) ``` > `WebContents` usage example: > ```C++= > std::unique_ptr<content::WebContents> web_contents { > // like a make_unique(...) wrapper -> content::WebContents* > content::WebContents::Create( > // constructor's parameters > content::WebContents::CreateParams(browser_context)) > }; > > // call WebContents' virtual methods. > gfx::NativeView view = web_contents->GetNativeView(); > ``` > For more `WebContents` usages, see: > - interaction: [//chrome/browser/ui/browser.cc](https://chromium.googlesource.com/chromium/src/+/main/chrome/browser/ui/browser.cc) > - interface: [//content/public/browser/web_contents.h](https://chromium.googlesource.com/chromium/src/+/main/content/public/browser/web_contents.h) ::: :::info **`//content/...` vs. `//<other-platform>/...`** *Decouple the functionalities & features of same layers but of different service scopes & logics.* > "first-class tab" design philosophy: [content, not chrome - Chromium Blog](https://blog.chromium.org/2008/10/content-not-chrome.html). ![image](https://hackmd.io/_uploads/SJnL1XWebg.png =650x) [//content/ - Chromium Source](https://chromium.googlesource.com/chromium/src/+/HEAD/content/README.md) - `//content/`: "core" code for implementing the web platform functionalities. Also, `//content/` provides generic extension points for hooking other platform's functions. > E.g., navigation, load URL, set zoom, reload, open devtools, ... - `//components/`: shared system services or common code logic for platforms. > E.g., embedder on `//chrome/` & `//android_webview/`, cross-platform chrome services on `//chrome/` & `//ios/chrome/`, ... [//components/ - Chromium Source](https://chromium.googlesource.com/chromium/src/+/HEAD/components/README.md) - `//chrome/`: web browser app functions. > E.g., extensions, autofill, spelling, ... - `//android_webview/`: integration into Android platform. - `//chromecast/`, `//headless/`, `//ios/chrome/`, ... ::: :::warning **`content` Layer for Different Application Architectures** ![image](https://hackmd.io/_uploads/S1x2cM-e-e.png =650x) In **chrome** architecture (multi-process): ![image](https://hackmd.io/_uploads/rk49tfbxWl.png =650x) In **webview** architecture (single-process): ![image](https://hackmd.io/_uploads/SkdxKMZgZx.png =650x) In **iframe** architecture (multi-process): ![image](https://hackmd.io/_uploads/r1fPQQbxWg.png =650x) > See: [Out-of-Process iframes (OOPIFs) - Chromium Docs](https://www.chromium.org/developers/design-documents/oop-iframes/). ::: - **IO thread/threadpool:** for traffic control. - manage network resources & proxy requests. - **`ResourceDispatcherHost`:** represents *Render Process' IO thread*. - **`ChannelProxy`**/**`Mojo`**: event-driven IPC system & individual channels (via UDS, pipe, shm, ...) with filtering (routing) & sending resources handles from consumers to producers, & vice versa. ```md! Browser Process' UI Thread <-IPC system-> Render Process' Main Thread ``` - **`ResourceMessageFilter`:** routes networking-specific messages to the `ResourceDispatcherHost`. > This happens on `ResourceMessageFilter::OnMessageReceived`. :::warning **[Scalability] Fullstack IPC Call Rules vs. Pub/Sub Event System** *Event centralized dispatchers, not intertwined routing rules ---- enable focusing on self business only.* > Historical IPC messages definition: [//chrome/common/render_messages.h](https://chromium.googlesource.com/chromium/src/+/cc44547a90acfb170c5a52be637009c6940745ca/chrome/common/render_messages.h). 1. **renderer:** use `RenderViewObserver` to recv (filter) / send IPC messages. > See: [//content/public/renderer/render_frame_observer.h](https://chromium.googlesource.com/chromium/src/+/main/content/public/renderer/render_frame_observer.h). :::info **[Modulization] Renderer's Extra Features** *Feature Callback Hooks vs. Virtual Interface Calls* Instead of making all extra features be implemented inside the core interface (e.g., `WebContents`, `WebViewClient`) as callbacks, create new specialized virtual interface such that: 1. renderer core (& out-bound IPC messages to the platform-specific API, ...) makes use of it. 2. each platform implements it. > For example: [//third_party/blink/public/web/web_autofill_client.h](https://chromium.googlesource.com/chromium/src/+/main/third_party/blink/public/web/web_autofill_client.h). ::: 2. **browser:** 1. **UI thread:** use `WebContentsObserver` to recv (filter) / send IPC messages. > See: [//content/public/browser/web_contents_observer.h](https://chromium.googlesource.com/chromium/src/+/main/content/public/browser/web_contents_observer.h). 2. **other threads:** (extendedly) use `BrowserMessageFilter` to recv (filter) / send IPC messages. 3. BrowserMessageFilter > Thus, IPC messages are handled in a decoupled way. [How to Add New Features (without bloating RenderView/RenderViewHost/WebContents) - Chromium Docs](https://www.chromium.org/developers/design-documents/multi-process-architecture/how-to-add-new-features/) ::: - ~~**Network thread:** for dedicated networking control, storages, & resources cache.~~ - ~~**GPU thread:** for dedicated graphics work.~~ :::warning **Using Layers (Shared Libraries) or Processes or Threads (IPCs)?** Depends on policies of: - resources isolation (relies on OS-level? constrained environment?) - virtualization (containerized partition) - concurrency/parellelism (responsiveness, computation offload) - reliability (vulnarable?) > For example: for better resources isolation, separate GPU thread from UI thread, network thread from IO thread, ... by using OS's (light-weight) process virtualization. More: - [Process Model and Site Isolation - Chromium Docs](https://chromium.googlesource.com/chromium/src/+/main/docs/process_model_and_site_isolation.md): real-world browser's separate process model & connection design principle. - [The Rule Of 2 - Chromium Docs](https://chromium.googlesource.com/chromium/src/+/master/docs/security/rule-of-2.md): system design among "processing untrust inputs" vs. "unsafe program" vs. "resources isolation". ::: - **Render Process(es):** instance & context for rendering each web page (with virtualization) ---- *html, DOM tree, layout tree, js runtime, gl context, ...* > On Webkit, it is called ++WebContent Process(es)++. - **Main thread:** - **`RenderProcess`:** the proxy agent between `RenderProcessHost` & *render thread*'s components. - **Render (main) thread:** - **`RenderView`**/**`RenderFrame`(s)**: represent the *document* (e.g., *tabs*, *web pages*, or *iframes*) for: 1. rendering the view. 2. handling input events. 3. ++handling navigation.++ > **Basically, `RenderView` represent a ++window++ / ++view++ UI instance of a "web page".** :::info **Newer Architecture:** *Frame-based* not *view-based* rendering targets. ::: - **`RenderWidget`(s):** the base class of the `RenderView`. 1. rendering the view. 2. handling input events. > **Fundamentally, `RenderWidget` maps to the WebKit's `WebCore::Widget` with WebKit glue layer (or Blink's `WebWidget`).** :::warning **Non-Navigatable UI View** `RenderWidget` has no ability for navigation, so it is suitable for a non-web-page UI. > E.g., selection boxes implemented by a native window. > ![image](https://hackmd.io/_uploads/ByzoX8nl-l.png =450x) ::: - **`ResourceDispatcher`(s):** resources request broker. > Requests from *Blink*'s `ResourceFetcher` to *Browser Process*'s *UI (or IO) thread*'s `ResourceDispatcherHost`. - ~~**Compositor thread & Raster thread:** (deligated from rendering engine) for more responsive UI.~~ > See: [Compositor Thread Architecture - Chromium Docs](https://www.chromium.org/developers/design-documents/compositor-thread-architecture/). - ~~**Worker thread(s):** (deligated from JS engine) JS Service Workers.~~ :::info **[Reference] Using Service Workers as Network Proxy Agents** *Webkit Implementation* The `Service Worker` can essentially act as proxy servers that sit between web applications, the browser, & the network. The `Service Worker` may load data from cache or request new resources from the network, allowing it to perform effective *offline experiences*, *intercept network requests*, *push notification*, and take actions on different network conditions. > **For example:** When a navigation happens, `Browser Process`'s `Network Thread` checks the domain against *registered service worker scopes*, if a `Service Worker` is registered for that URL, the `Browser Process`'s `UI Thread` finds that exact `Renderer Process` & execute the corresponding `Service Worker` code. > > ![image](https://hackmd.io/_uploads/rkXTlgEs0.png =300x) ::: - (**IO thread(s):** (deligated from `ResourceDispatcher`) listen and wait for the resources.) ### WebKit2 Multi-Process Architecture *WebKit’s Secure Multi-Process Architecture* > multi-process architecture: > ![image](https://hackmd.io/_uploads/rkgs8PiYJl.png =650x) > ![image](https://hackmd.io/_uploads/ryeKdnr1ke.png =650x) > ![image](https://hackmd.io/_uploads/HymileVj0.png =650x) :::warning **Porting - Platform-Specific Implementations** WebKit has been ported to various platforms and operating systems. The platform-specific code for each port is maintained by different teams that collaborate on the cross-platform code. [What Are WebKit Ports? - Webkit Docs](https://docs.webkit.org/Ports/Introduction.html) > There are no cross-platform releases of WebKit (i.e. each WebKit port is responsible for creating their own separate releases). > - Apple: `macOS`, `iOS`. > - Linux: `QtWebkit`, `WebKitGTK+`, `WPE WebKit`. > - Microsoft: `Windows`. > - Sony: `PlayStation`. > - JavaScriptCore without the rest of WebKit: `JSCOnly`. ::: #### JavaScriptCore (JSC) - JavaScript Engine A JavaScript engine that implements ECMAScript as in ECMA-262 specs. [JavaScriptCore - Webkit Docs](https://docs.webkit.org/Deep%20Dive/JSC/JavaScriptCore.html) - **JavaScript Parser, JSON Parser** - **Byte Compiler:** Uses internal bytecode format. - **Assembler:** Uses code patching at runtime (writable code memory required). - **Interpreter:** Runs the generated bytecode in C++. - **Baseline JIT:** The 1st JIT compiler tier serves as the profiler as well as a significant speed up from the interpreter. - **DFG JIT:** Data Flow Graph JIT compiler uses the data flow analysis to generate optimized machine code. - **FTL JIT:** The fastest tier of JSC uses `B3 JIT Compiler`. JavaScriptCode also implements JavaScriptCore API for macOS and iOS applications. - **Regex Engine:** With JIT Support. - **Garbage Collector:** Mark-&-sweep. - **Runtime:** Management of all the JS global objects (e.g., *Date*, *String*, *Number*) - **Debugger Profiler** #### WebCore - Rendering Engine Implements most of the Web APIs (e.g., *HTML standard*) and their behaviors, such as *network access*, *parsing*, *rendering*, *layout*, *painting*, *DOM*, *binding*, *multimedia*, etc. - [[Slides] Life of a Pixel - Steve Kobes - Chromium Docs](https://docs.google.com/presentation/d/1boPxbgNrTU0ddsc144rcXayGA_WF53k96imRH8Mp34Y) - [[Series] WebCore Rendering - Webkit Blog](https://webkit.org/blog/114/webcore-rendering-i-the-basics/) :::warning **Web Page Rendering in a Browser High-Level Perspective** The following concepts are mainly explored from a rendering engine perspective -- a high-level graphics rendering framework used in browser technologies. :arrow_right: If you're interested in diving deeper into the underlying infrastructure, such as JavaScript engines, runtimes, or graphics rendering in GUI systems, check out: - [我所不知道的 JavaScript - shibarashinu](https://hackmd.io/@shibarashinu/BkAHFociR) - [GUI Systems on Linux - shibarashinu](https://hackmd.io/@shibarashinu/S1C42Zh50) ::: ## Rendering Engine *Like Webkit or Blink.* - **Resource Loaders** - **Document Parsers (`XMLDocumentParser` / `HTMLDocumentParser`):** ![image](https://hackmd.io/_uploads/rJFf-xNsC.png =500x) - **DOM Tree (`HTMLTreeBuilder`):** > DOM Node Objects *(Non-Primitives)* in Browser's JavaScript Runtime: > ![0](https://hackmd.io/_uploads/HJ7xMvoYyl.jpg) > > (Source: [Understanding the JavaScript Runtime Environment and DOM Nodes - Vahid Dejwakh](https://vahid.blog/post/2021-03-21-understanding-the-javascript-runtime-environment-and-dom-nodes/)) ![image](https://hackmd.io/_uploads/SydQ-xEjR.png =500x) ![image](https://hackmd.io/_uploads/ryN4-xEoC.png =500x) - **Document (`XMLDocument` / `HTMLDocument` / `SVGDocument` / `MathMLDocument`):** The root `Node` of the DOM tree. - **Node (*Component*):** Provides basic DOM props & methods (e.g., `nodeType`, `nodeName`, `appendChild()`, `removeChild()`). - **Element (*Composite*):** All `<tags />` that occur in the *document* source turn into Element nodes. - **Text (*Leaf*):** All text enclosed by `<tag>...</tag>` turns into Text nodes. - **CSS:** Parser, Selectors, Animations, JIT compiler, ... ![image](https://hackmd.io/_uploads/HymSbgVjC.png =500x) - **Rendering Pipeline:** All of the children of Render Tree are `RenderObject` that can be obtained using the `renderer()` method on `Node` of DOM tree. [RenderingNG - Chris Harrelson - Chrome for Developers](https://developer.chrome.com/docs/chromium/renderingng) ![image](https://hackmd.io/_uploads/Bk0HbeVsA.png) 1. **Style Calculation:** ![image](https://hackmd.io/_uploads/S1VPblEiR.png =500x) > Render Tree (DOM Tree x CSSOM Tree): > ![image](https://hackmd.io/_uploads/Bk0zBvstJe.png) 2. **Layout (& Reflow):** Turns `inline`, `block`, `table`, `float`, `flex`, `grid` to actual layout data. - *DOM Tree* with `RenderObject` -> *Layout Tree* with `LayoutObject` ![image](https://hackmd.io/_uploads/B1-dZe4s0.png =500x) ![image](https://hackmd.io/_uploads/Bkvt-g4iC.png =500x) ![image](https://hackmd.io/_uploads/rkXqbg4oC.png =500x) - (Input) *Layout Tree* with `LayoutObject` -- update --> (Result) *Fragment Tree* with `Computed Layout Data` :::info For example: **DOM:** ```html= <div style="max-width: 100px"> <div style="float: left; padding: 1ex">F</div> <br>The <b>quick brown</b> fox <div style="margin: -60px 0 0 80px">jumps</div> </div> ``` **Layout Tree:** ```js= LayoutBlockFLow {DIV} LayoutBlockFlow (anonymous) LayoutBlockFlow (floating) LayoutText "F" LayoutBR LayoutText "The" LayoutInline {B} LayoutText "quick brown" LayoutBlockFlow {DIV} LayoutText "fox" LayoutBlockFLow {DIV} LayoutText "jumps" ``` **Fragment Tree (Layout Result):** ```js= Box (block-flow) at 0,0 100x12 Box (block-flow children-inline) at 0,0 100x54 LineBox at 24.9,0 0x18 Box (floating block-flow children-inline) at 0,0 24.9x34 LineBox at 8,8 8.9x18 Text 'F' at 8,8 8.9x17 Text '\n' at 24.9,0 0x17 LineBox at 24.9,18 67.1x18 Text 'The ' at 24.9,18 28.9x17 Text 'quick' at 53.8,18 38.25x17 // Note: Here we get a line-break due to the overflow LineBox at 0,36 69.5x18 Text 'brown' at 0,36 44.2x17 Text ' fox' at 44.2,36 25.3x17 Box (block-flow children-inline) at 80,-6 20x18 LineBox at 0,0 39.125x18 Text 'jumps' at 0,0 39.125x17 ``` ::: 3. **Paint (& Repaint):** Renders data onto each frame buffer in the order of `z-index`. ![image](https://hackmd.io/_uploads/S1OiblVo0.png =500x) :::info **Example 1:** 1 *IMG* with 1 `DisplayItem` with 1 `draw()` operation. ![image](https://hackmd.io/_uploads/B1KPHD8s0.png =500x) **Example 2:** 1 *DIV* with 3 `DisplayItems` with 4 `draw()` operations. ![image](https://hackmd.io/_uploads/SynZYNUo0.png =500x) ::: :::warning **Note:** When doing the `drawText()` opration, a blob structure is used to store *keyCode* & *offset* of each glyph. ![image](https://hackmd.io/_uploads/SklFcV8iA.png =500x) ::: 4. **Rasterization:** *Vectors / Data* -> *Pixels* ![image](https://hackmd.io/_uploads/rJZhbeEoR.png =500x) ![image](https://hackmd.io/_uploads/SkAxcvIi0.png =500x) ![image](https://hackmd.io/_uploads/ry1OJuUjC.png =500x) :::info **Raster Tasks (in Sandboxed ++Rendering Process++):** Need interface for inderectly accessing the underlying graphics library & the GPU. > The compositor is implemented on top of the GL ES 2.0 client library which proxies the graphics calls over the *IPC* channel to the ++GPU process++ and rasters directly into the window’s backbuffer. ![image](https://hackmd.io/_uploads/rk4RzO8jC.png =500x) **GL Function Pointers in GPU Process:** Linked dynamically to the system's shared *OpenGL library*, or *ANGLE library*. ![image](https://hackmd.io/_uploads/S1wRIOUjA.png =500x) ::: 5. **Composite:** Combines all layers to one screen by GPU. - [How cc Works - Chromium Docs](https://chromium.googlesource.com/chromium/src.git/+/HEAD/docs/how_cc_works.md) - [GPU Accelerated Compositing in Chrome - Chromium Docs](https://www.chromium.org/developers/design-documents/gpu-accelerated-compositing-in-chrome/) - **Bindings Generator:** Binds *JavaScript* -> *Browser's underlying native functions*, enhancing cross-compatibility & consistency. [Design of V8 bindings - Chromium Docs](https://chromium.googlesource.com/chromium/src/+/master/third_party/blink/renderer/bindings/core/v8/V8BindingDesign.md) ![image](https://hackmd.io/_uploads/HJ4T-e4sC.png =500x) > `V8 wrapper` -- *strong reference* --> Native C++ `DOM Tree` ; > Native C++ `DOM Tree` -- *weak reference* --> `V8 wrapper(s)`. - **API Specs:** The `web IDL` files describing the exposing APIs that *JavaScript* can fully make use of the *browser* (e.g., V8, ObjC, Graphics, GUIs, Hardwares). - [Web IDL Standard - WHATWG](https://webidl.spec.whatwg.org/) - [一文读懂web标准的基石:web IDL - 水鱼兄 - CSDN](https://blog.csdn.net/weixin_44384265/article/details/127238837) :::warning **IDL Systems** Metaprogramming for bindings of *marshalling* & *unmarshalling* data between two entities. - **In-Process:** web IDL `*.idl` (JS engine <-> browser engine). > Actual bridge code may implement as ++shared library++. - **IPC:** Mojo `*.mojom` (renderer process <-> browser process). > Actual bridge code may implement on ++UDS (UNIX domain socket)++. - **RPC:** gRPC's protobuf `*.proto` (between microservices). > Actual bridge code may implement on ++HTTP2++. - **Portable Objects:** Java's protobuf `.proto` (Java objects <-[ProtoStream](https://docs.redhat.com/en/documentation/red_hat_data_grid/8.5/html/cache_encoding_and_marshalling/marshalling_user_types)-> binaries). > *ProtoStream* is of marshalling layer only, the applications are decoupled from it. ::: - **Binding & Integration:** generate the target code to implement the interface layer in the *browser engine* via `web IDL` files. For example, a simple `add` function in a `IDL` file exposed to JS runtime: - adder.idl ```idl= /* can be accessed via global window object */ [ Exposed=Window ] interface Adder : Calculator { [CallWith=Adder] constructor(); [Affects=Nothing] double add(double a, double b); }; ``` My `add` header & implementation: - adder.h ```c++= #progma once #include <stdio.h> #include "platform/bindings/ScriptWrappable.h" #include "platform/bindings/TraceWrapperMember.h" #include "platform/bindings/TraceWrapperV8Reference.h" class Calculator : public ScriptWrappable { DEFINE_WRAPPERTYPEINFO(); public: Calculator() = default; } class adder : public Calculator { DEFINE_WRAPPERTYPEINFO(); public: double add(double a, double b); }; ``` - adder.cc ```c++= #include "adder.h" double Adder::add(double a, double b) { return a + b; } ``` [third_party/blink/renderer/core/dom - chromium](https://chromium.googlesource.com/chromium/src/+/refs/heads/main/third_party/blink/renderer/core/dom/document.idl) Then, with browser engine's binding system (glue code generator): 1. The glue code compiled (e.g., in a shared library form). ```! IdlCompiler: idl_filename -"IdlReader"-> IdlDefinitions -"CodeGeneratorV8"-> header_text, cpp_text ``` ```! "IdlReader": idl_filename -"BlinkIDLLexer"->(internally)-"BlinkIDLParser"-> IDLNode -"idl_definitions_builder"-> IdlDefinitions ``` ```! "CodeGeneratorV8": IdlDefinitions -(extract member)-> IdlInterface -v8_*.py -> dict -"jinja2"-> header_text, cpp_text ``` [third_party/blink/renderer/bindings/IDLCompiler.md - chromium](https://chromium.googlesource.com/chromium/src/+/HEAD/third_party/blink/renderer/bindings/IDLCompiler.md) 2. The runtime system can load them at the start up / dynamically linking, & exposed to JS (e.g. `window.Adder := V8Adder`). 3. On JS function call (e.g., `new Adder().add(1, 2)`), engine routes it to JS engine's wrapper, marshals data, then calls C++ actual implmentation. ```! JavaScript -> V8 stub -> C++ impl -> return ``` [Wrapper Tracing Reference - chromium](https://chromium.googlesource.com/chromium/src/+/66.0.3359.158/third_party/WebKit/Source/platform/bindings/TraceWrapperReference.md) :::warning **IDL System Limitation** 1. Dynamic, implicit JS language characteristics can't directly be applied & used in C++. These only exist in JS execution context. 2. Although C++ supports template-boilerplate programming, specific type functions of templates are bundled into shared libraries only if they are explicitly used / instantiated. > Typically these are narrowed down to C++ primitives & container-defined data types. :::info **Use C++ Templates for Shared Libraries** A template declaration in the header: ```c++= template<typename T> T add(T a, T b) { return a + b; } ``` - Explicit template instantiation: ```c++= // declare once template int add<int>(int, int); template double add<double>(double, double); ``` - Or with multiple `extern` & once instantiation: ```c++= // multiple declarations scattered out there extern template int add<int>(int, int); // only declare once in somewhere template int add<int>(int, int); ``` ::: 3. To make all IDL-related components can access essential data types or functions, make those accessible in the header. > Implement globally once, or with `extern`, as the above shown. For example: - [third_party/blink/renderer/platform/wtf/vector.h - chromium](https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/platform/wtf/vector.h;l=1124) ```c++= template <typename T, wtf_size_t InlineCapacity, typename Allocator> template <typename U> void Vector<T, InlineCapacity, Allocator>::insert(wtf_size_t position, const U* data, wtf_size_t data_size) { DCHECK(Allocator::IsAllocationAllowed()); CHECK_LE(position, size()); wtf_size_t new_size = size_ + data_size; if (new_size > capacity()) { data = ExpandCapacity(new_size, data); DCHECK(this->data()); } CHECK_GE(new_size, size_); MARKING_AWARE_ANNOTATE_CHANGE_SIZE(Allocator, this->data(), capacity(), size_, new_size); T* spot = this->data() + position; TypeOperations::MoveOverlapping(spot, DataEnd(), spot + data_size, VectorOperationOrigin::kRegularModification); TypeOperations::UninitializedCopy( data, &data[data_size], spot, VectorOperationOrigin::kRegularModification); size_ = new_size; } ``` ```c++= template <typename T, wtf_size_t InlineCapacity, typename Allocator> inline auto Vector<T, InlineCapacity, Allocator>::erase(iterator position) -> iterator { wtf_size_t index = static_cast<wtf_size_t>(position - begin()); EraseAt(index); return begin() + index; } template <typename T, wtf_size_t InlineCapacity, typename Allocator> inline void Vector<T, InlineCapacity, Allocator>::EraseAt(wtf_size_t position, wtf_size_t length) { SECURITY_DCHECK(position <= size()); if (!length) return; CHECK_LE(position + length, size()); T* begin_spot = data() + position; T* end_spot = begin_spot + length; TypeOperations::Destruct(begin_spot, end_spot); TypeOperations::MoveOverlapping(end_spot, DataEnd(), begin_spot, VectorOperationOrigin::kRegularModification); ClearUnusedSlots(DataEnd() - length, DataEnd()); MARKING_AWARE_ANNOTATE_CHANGE_SIZE(Allocator, data(), capacity(), size_, size_ - length); size_ -= length; } ``` ```c++= template <typename T, wtf_size_t InlineCapacity, typename Allocator> inline void Vector<T, InlineCapacity, Allocator>::Reverse() { for (wtf_size_t i = 0; i < size_ / 2; ++i) std::swap(at(i), at(size_ - 1 - i)); } template <typename T, wtf_size_t InlineCapacity, typename Allocator> inline void swap(Vector<T, InlineCapacity, Allocator>& a, Vector<T, InlineCapacity, Allocator>& b) { a.Swap(b); } ::: For example: :::info **[Map-like browser APIs - MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map#map-like_browser_apis)** Browser `Map-Like Objects` are ++Web API++ interfaces that behave in many ways like a `Map`. For example: `AudioParamMap`, `RTCStatsReport`, `EventCounts`, `KeyboardLayoutMap`, `MIDIInputMap`, `MIDIOutputMap` > `Map-Like Objects` & `Map` share many properties & methods to access an object as an ordered map, ==the key difference is `Map-Like Objects` only allow specific predefined types for the *keys* and *values* of each entry==. The allowed types & specs are defined in the `web IDL` file: ```javascript= /* * For example, RTCStatsReport is a Map-Like Object that * must use "strings" for keys & "objects" for values. */ interface RTCStatsReport { readonly maplike<DOMString, object>; }; ``` ::: - **Web Standards:** [[Intro] The web and web standards - MDN Web Docs](https://developer.mozilla.org/en-US/docs/Learn/Getting_started_with_the_web/The_web_and_web_standards) - **HTML5:** `<section>`, `<article>`, `<header>`, `<footer>`, `<canvas>`, `<audio>`, `<video>` [HTML Standard - WHATWG](https://html.spec.whatwg.org/multipage/) - **DOM:** `addEventListener`, `ChildNode`, `TreeWalker`, ... [DOM Standard - WHATWG](https://dom.spec.whatwg.org/) - **CSS3:** `flex`, `grid`, new effects, new selectors, ... - **JS:** - Language Support: ECMAScript 2015+ - Web APIs: WebGL, Web Workers, Web Storage, Notification, ... > More: > - [ECMAScript® 2025 Language Specification - Ecma TC39](https://tc39.es/ecma262/) > - [JavaScript reference - MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference) > - [Web APIs - MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API) - **WebAssembly (WASM)** - **Platform Integration:** [[Slides] WebKitGtk+ Project - Joone Hur](https://www.slideshare.net/slideshow/webkitgtk-project/11327512) - **Cairo/Skia:** 2D Rendering - **Pango:** Fonts - **GTK+:** Themes & Widgets - **Soup:** Networking - **GStreamer:** HTML5 video - **Others:** PyGtk+, HTTP/3, WebGPU, ... - **GPU Acceleration:** ![image](https://hackmd.io/_uploads/rJi1MgEoA.png =500x) - **Layer Compositing (New RenderLayer):** Activated & Implemented the following effects in `RenderLayer`. [CSS GPU Animation: Doing It Right - Sergey Chikuyonok - Smashing Magazine](https://www.smashingmagazine.com/2016/12/gpu-animation-doing-it-right/) > **Note:** Rendering pipeline is platform dependent. - CSS props/JS animate: `transform`, `opacity`, `filter`, `animation`, `will-change`, `position: fixed` - DOM elements with GPU acceleration: `<video>`, `<canvas>`, `<iframe>` - **Image Rasterization:** Using GPU operations for image decoding & raster onto a bitmap as a `Texture`. - **WebGL:** Managed access to OpenGL ES APIs from JavaScript. - **WebInspector** - [about:debugging - Firefox Docs](https://firefox-source-docs.mozilla.org/devtools-user/about_colon_debugging/index.html) - [Remote Debugging Protocol - Firefox Docs](https://firefox-source-docs.mozilla.org/devtools/backend/protocol.html)