From 2bf247b653980a755210288b332c7a5774751c34 Mon Sep 17 00:00:00 2001 From: Ed Guloien Date: Mon, 24 Aug 2026 17:35:44 -0400 Subject: [PATCH] added speaker notes --- speaker-notes.md | 101 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 speaker-notes.md diff --git a/speaker-notes.md b/speaker-notes.md new file mode 100644 index 0000000..321a310 --- /dev/null +++ b/speaker-notes.md @@ -0,0 +1,101 @@ +--------- + +(Title page) +Have you ever wanted to add your own crate to your favourite open source browser? +Or write your own Web API to your own custom browser fork? +My name is Ed Guloien and today I'm going to tell you how and what to watch out for. + +(about://ed-guloien) +I'm a Senior Software Developer, +Formerly working on the Web Platform Networking team at Mozilla. +Currently at Quantum Bridge working on Distributed Symmetric Key Exchange +Interested in privacy, security and systems programming + +(Interop 2025) +For the unfamiliar there is an initiative to improve web compatibility +by improving pre-selected Web API implementations across all browsers. +It's called Interop. +And a hundred years ago, for Interop 2025, I implemented the URLPattern Web API. + +(URLPattern Web API) +URLPattern is basically pattern matching supporting ECMAScript Regex +for URLs and their components. +From Web JavaScript we construct a pattern and match strings against it. + +(Denoland crate and Firefox) +Luckily for me there is an existing open source implementation by Denoland, written in rust. +So all I have to do is figure out how to incorporate it into Firefox. +This is Firefox's Fission Architecture, +it isolates web content from other web content, roughly by origin. +And we have the main process handling orchestration and networking. +We need URLPattern everywhere: +* for each content process +* and for Compression Dictionaries in the main process. +So we add it to the very common libXUL library within Firefox. + +(WebAPI call flow to crate) +We fork Denoland's crate by vetting and vendoring it in to libXUL, inside gkrust. +And that compiles just fine. +But Firefox's Browser Engine, Gecko, is mostly C++. +* So we tell the build system about our FFI glue crate +* We use cbindgen to generate the headers required for compiling C++ against rust. +* Then generate JS-callable-C++-bindings from a webIDL file +* And implement the DOM wrapper that forwards the call to our glue crate. + +(UrlPattern crate API) +Then we call the crate from our rust glue. +The crate API exposes a trait called RegExp and a few functions to go with it. +We simply implement trait, and call the functions to create patterns and match against them. + +(Glue Crate) +Easy Peazy, +well, +not so fast. + +(Reality Sets In) +Non-POD objects need to be passed-by-reference across the FFI. +* And since our common C ABI doesn't have references, cbindgen degrades our references to raw pointers. +* And if the object exposes internal types unknown to the other side you need an opaque pointer (a void pointer) to hide those details. +* This leads to unsafe, pointer casts, dereferences, return parameters and so on. +Similarly we use pointers to represent options, or write wrapper bindings to hide the gory details. +But sometimes we are lucky and can use specialized FFI types to that can handle the ownership model difference between C++ and Rust + +(Pattern re-use) +Pattern construction is the most expensive part of using URLPattern. +We cannot feasibly do it on every match. +* So to save some cycles we pass the pattern object to the closest persistent object, +* all the way back in the generated DOM bindings, +* subjecting our pattern object to further marshaling across the ownership models. +But with that done, when the user requests a match or closes the page, +we pass the pattern to the rust crate for use or deletion. + +(99.8%) +If you can get past all that, +You're pretty much there, with decent performance. +But if you want to go all the way you have to know +* that rust::regex is not EcmaRegex compliant +* and the urlpattern crate uses rust::regex by default. +Luckily for us, we're in Firefox, +we already HAVE an EcmaRegex implementation living in the SpiderMonkey Javascript engine + +(Spidermonkey Challenges) +But it comes at the cost of toil. +We write similar FFI going the back to C++ to access SpiderMonkey. +But this API was not designed for C++ use. +* It requires JS context, which we lost touch with through the marshaling. +* It has a completely different memory model using Garbage Collection. +* A typical Web JS runtime can be interrupted to prioritize other JS. +* AND it uses UTF-16 by default, unlike Rust's UTF-8. +So we cast some spells: +* we spin up a JS context, +* we prevent Spidermonkey from interrupting it's execution, +* we root the objects to a context that will prevent the GC from marking them for deletion +* AND convert between UTF-8 and 16 as needed. +And if you do all that... + +(Phew!) +Phew! All done. +Now you can add your own crates and WebAPI's +to an open source browser. + +(references) \ No newline at end of file