update speaker notes
This commit is contained in:
@@ -7,7 +7,6 @@ paginate: true
|
||||
footer: <span> <img src="images/qb-logo-mark.png" width="60"/> Sept 2026 </span>
|
||||
html: "true"
|
||||
---
|
||||
<!-- all slideshow styling in one place -->
|
||||
<style>
|
||||
/* font setup */
|
||||
section {
|
||||
@@ -44,6 +43,13 @@ html: "true"
|
||||
|
||||
### Ed Guloien
|
||||
|
||||
<!--
|
||||
Have you ever wanted to add your own crate
|
||||
Or write your own Web API to your favourite browser?
|
||||
My name is Ed Guloien and today
|
||||
I'm going to tell you how.
|
||||
-->
|
||||
|
||||
<!-- disable page numbering on title page -->
|
||||
<!-- _paginate: false -->
|
||||
|
||||
@@ -85,12 +91,26 @@ html: "true"
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--
|
||||
I'm a Senior Software Developer,
|
||||
Formerly working on the Web Platform Networking team at Mozilla.
|
||||
Currently writing rust full time Quantum Bridge working on Distributed Symmetric Key Exchange.
|
||||
-->
|
||||
|
||||
---
|
||||
## Interop 2025
|
||||
|
||||

|
||||

|
||||
|
||||
<!--
|
||||
There is an initiative to improve web compatibility by improving Web API implementations
|
||||
across the major browsers.
|
||||
It's called Interop and it happens every year.
|
||||
And a hundred years ago, for Interop 2025,
|
||||
I implemented the URLPattern Web API.
|
||||
-->
|
||||
|
||||
---
|
||||
## URLPattern Web API
|
||||
|
||||
@@ -106,6 +126,11 @@ pattern.test("https://example.com/books/123");
|
||||
pattern.exec("https://example.com/books/123").pathname.groups
|
||||
```
|
||||
|
||||
<!--
|
||||
URLPattern is basically pattern matching for URLs and their components.
|
||||
We can construct a pattern object and match strings against it.
|
||||
-->
|
||||
|
||||
---
|
||||
## Denoland & Firefox
|
||||
|
||||
@@ -113,16 +138,42 @@ pattern.exec("https://example.com/books/123").pathname.groups
|
||||
|
||||

|
||||
|
||||
<!--
|
||||
Luckily for us there is an existing open source implementation by Denoland, written in rust.
|
||||
So all we 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.
|
||||
We need URLPattern everywhere:
|
||||
* for each web content process
|
||||
* and for Compression Dictionaries in the main process.
|
||||
So we add it to libXUL, a common library within Firefox.
|
||||
-->
|
||||
-------
|
||||
## Web API Call Flow
|
||||
|
||||

|
||||
|
||||
<!--
|
||||
We fork Denoland's crate by vetting, vendoring and telling the build system to compile it.
|
||||
This works just ffine.
|
||||
|
||||
But Firefox's Browser Engine is mostly C++ and we're missing a call path.
|
||||
* So we generate JS_callable C++ bindings from a webIDL file
|
||||
* Implement a DOM wrapper that will forward the calls to our gloue crate
|
||||
* And Tell the build system about our FFI glue crate
|
||||
* It uses cbindgen to generate headers for C++ compilation against rust
|
||||
* And include a C++ convenience wrapper and make our rust call the crate
|
||||
-->
|
||||
-----
|
||||
## Urlpattern Crate API
|
||||
|
||||

|
||||
|
||||
<!--
|
||||
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
|
||||
|
||||
@@ -133,6 +184,11 @@ let results = quirks::process_match(pattern, input);
|
||||
// call it a day
|
||||
```
|
||||
|
||||
<!--
|
||||
Easy Peazy, right?
|
||||
well,
|
||||
not so fast.
|
||||
-->
|
||||
-----
|
||||
## Reality Sets In (Memory Concerns)
|
||||
|
||||
@@ -154,11 +210,32 @@ glue::process_match(..., res: *mut MatchResults, other: MaybeString)
|
||||
glue::doing_thing(..., res: &mut ThinVec<>);
|
||||
```
|
||||
|
||||
<!--
|
||||
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 to hide those details.
|
||||
* This leads to all sorts of unsafe pointer voodoo
|
||||
|
||||
Similarly, to represent options we use pointers, or write wrapper bindings to hide the gory details.
|
||||
But sometimes we get lucky and find a specialized FFI type that can handle the ownership model difference between C++ and Rust
|
||||
-->
|
||||
|
||||
----
|
||||
## Pattern Re-use; Marshaling
|
||||
|
||||

|
||||
|
||||
<!--
|
||||
We get that working and quickly notice that
|
||||
Pattern construction is the most expensive part of using URLPattern.
|
||||
So 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,
|
||||
* and write the additional marshaling to do it.
|
||||
|
||||
With that done, when the user requests a match: we pass the pattern along to the crate.
|
||||
To avoid memory leaks, when the DOM binding goes out of scope the pattern is destroyed by it's rust creator.
|
||||
-->
|
||||
------
|
||||
## 99.8%
|
||||
|
||||
@@ -166,13 +243,43 @@ glue::doing_thing(..., res: &mut ThinVec<>);
|
||||
regex::Regex != EcmaScript Regex
|
||||
```
|
||||
|
||||
<!--
|
||||
If you get this far
|
||||
You're pretty much there, with decent performance.
|
||||
|
||||
But if you want the whole banana, 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 in SpiderMonkey, the Javascript engine
|
||||
-->
|
||||
----
|
||||
## Spidermonkey Challenges (many)
|
||||
|
||||

|
||||
|
||||
<!--
|
||||
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 through all the marshaling.
|
||||
* It uses Garbage Collection.
|
||||
* Calling JS can be interrupted to prioritize other JS.
|
||||
|
||||
So we cast some spells:
|
||||
* we spin up a JS context,
|
||||
* we prevent Spidermonkey from interrupting execution,
|
||||
* we root the objects to a context that is safe from GC
|
||||
* AND convert between UTF-8 and 16 as needed.
|
||||
-->
|
||||
-----
|
||||
## And if you do all that...
|
||||
|
||||
...
|
||||
|
||||
-------
|
||||
## Phew!
|
||||
|
||||
|
||||
@@ -187,3 +294,8 @@ regex::Regex != EcmaScript Regex
|
||||
- https://searchfox.org/firefox-main
|
||||
- https://github.com/denoland/rust-urlpattern
|
||||
- See also: https://manuelbucher.com/blog/rust-gecko/
|
||||
|
||||
<!--
|
||||
You're done.
|
||||
Now you can add your own crates and Web API's to your favourite open source browser.
|
||||
-->
|
||||
Reference in New Issue
Block a user