Okay, so while we're getting these slides up, I'm going to go ahead and introduce our next
speaker for you.
I'd like to introduce David Thompson.
He's a CTO at Spitley Institute, a co-maintainer of Gail Hoot, and a long-time contributor
to Ganyu Geeks.
He's going to be talking to us about a proposal to rearchitect web browsers as minimal
awesome run times.
Where functionality is provided by safe modular extensions to reduce centralization.
So as we get these slides up here, let's go ahead and give them a warm-out of
applause.
Everyone.
On mute.
And then we're still here and stay on this side of the board.
Okay, do you want to add it?
Cool.
It goes forward and goes back.
Okay, I don't get a mirror there.
Okay.
Yeah, that's fine.
I'll just be looking over my shoulder.
Did everybody hear me?
Come with you?
Okay, cool.
Well, hi, ready?
I'm Dave.
Just Kevin said in the CTO, the Spitley Institute, the Spitley Institute is
we work on the next generation of decentralized internet technology for the social web.
And specifically, I want to talk about one of our projects called Hoot.
And it's why I'm here to talk to you about WebAssembly today.
I'm a user and implementer of the WebAssembly specification through the Hoot project.
Who does a scheme to WebAssembly compiler?
At Sprite Lee, we do a lot of our research and development in the scheme programming language.
And Hoot is a way to deliver it to anyone that has a web browser to actually try out
our prototypes and demos.
Hoot's not only compiler for an obscure list programming language.
It's also a complete standalone WebAssembly tool chain, including things like a WebAssembly
interpreter.
So, in addition to running things in the browser, we can actually run things in our
own interpreter for testing purposes.
So, that's kind of my background.
And in WebAssembly, I've been doing this working with WebAssembly for two to three years
at this point.
I'm going to talk to you about the state of WebAssembly.
And this is more of a, this is a vision talk.
I normally give talks about kind of concrete things that I've been working on.
This is more of a vision.
It's not my vision.
It's one that I've read about online that I find compelling.
I'm going to be maybe not discussing all of the political things that are going to make
what I'm about to show you, a very difficult thing to achieve, but just an idea I find
very compelling.
And basically, I think the WebAs grown too big to implement, to implement a new browser,
to say, peel any market share away from something like Chrome is mostly impossible.
If you're not Google or funded by Google, you know, good luck implementing it off of the
web standards to make a browser that people can actually use.
People are trying, but it's certainly an uphill battle.
So what if we subdivide the problem?
What might a more modular browser look like?
What if a web browser was little more than a WebAssembly runtime?
What if we shrunk the core of the web browser down to, mostly that, gives you a window
in a runtime and maybe some way to access the OS facilities that the WebAssembly can access.
So how do we get from where we are now to there?
One, I don't totally know, but I'm going to present a vision.
So today, we have, like, most browsers have like a high trust, monolithic core, typically
written in C++, with JavaScript as the user space, and now there's a web assembly runtime
kind of sitting on the side, but it's still driven from JavaScript as like the host of those
things.
The vision is a minimal core with the necessary OS access, and then just a web assembly
user space.
So what if JavaScript wasn't even something you assumed as a core part of your web browser?
What if it was just web assembly?
One of the things that I like that this would enable is having what it call a polyglot environment.
You know, instead of traditionally, we just had JavaScript on the client-side web.
And so if you wanted to do no matter what you wanted to do, you had to use JavaScript
and often people are compiling other languages to JavaScript.
Now with WebAssembly, we have a feasible way to use different languages for the tasks that
they're most appropriate for.
WebAssembly's found a lot of success in using, say, Rust or C++ to make a WebAssembly module
that does a lot of number crunching, let's say, that we offload some of the work from JavaScript
over to WebAssembly for that purpose, but still JavaScript's kind of our main language
we're using, but we could take this further and we could utilize all sorts of different languages
and different programming paradigms for the things that they're best suited for.
So this is kind of looking to use having a big toolbox that we can use to build our applications
out of.
So again, this idea is not mine.
I've read about it for some time.
This is a blog post by Joey Hess.
He knows a long time deviant developer, author of GetAnnex General Haskell Wizard, someone
who's code I often can't understand, but I think he's a really brilliant person.
This would be easy to read if I had my laptop the mirror here, but you know, so throw out
all the web standards, make a browser that just runs Wasm Blobs and give them the surface
to you.
Sort of like the way Wayland does.
It has tabs in a Throbber and URLs, but no HTML and no JavaScript, no CSS.
Just HTTP of Wasm Blobs and Joey asserts, this is where the web browser is going eventually
anyway.
So I don't we try to build a future where we go there, but users retain some agency over
their web browsing and this is not.
It goes there anyway to Wasm Blobs but retains all of the large corporate control that
we currently see with the web browser.
So I found this really compelling and then as I got into WebAssembly work, I found it more
and more compelling.
Alright, WebAssembly, what is it anyway?
So show of hands who's familiar with WebAssembly already.
Okay, that's a good number of people who's worked with WebAssembly directly at any point.
Okay, that's fewer people.
Okay, so just for those that are kind of know but once more information, WebAssembly is a portable stack-based virtual machine.
It's purposes to be a lower level, compilation target than JavaScript, but still being a higher level
at a higher abstraction level than your average assembly language.
So there are features of WebAssembly that you wouldn't find in like your X86 or risk-5, et cetera.
Assembly languages, one of which being garbage collection primitives which I'll get to you.
And so it's everything in WebAssembly, it's statically typed on like JavaScript.
Like JavaScript, control flow is structured, which is unlike most assembly languages that have some kind of go to
things to jump to various labels in the code.
So it's quite different and it has this import export system for composition.
So modules are usually small self-contained things and you can compose many modules together to form your overall application.
So yeah, it's designed to be a good target for compilation.
The idea is to be faster than JavaScript and have good boot time as well.
So who's heard of ASM.js? It's a precursor to WebAssembly.
It was basically using a subset of JavaScript that was started by Mozilla using a subset of JavaScript that was amenable to good jit compilation.
And all sorts of interesting demos were done with that, including a form of the Unreal Engine and getting that running in web browsers.
Very cool at the time, but WebAssembly came out of this to like, okay, let's do this but for real.
Let's have a real format for this.
So this is what WebAssembly looks like.
This is a full module in the WebAssembly text format.
It looks like a weird list if you're used to at all the list programming language,
got all these parentheses, everything's in prefix notation.
This module is very simple. It has an exported function called factorial.
And what you see here is just an iterative factorial algorithm.
But note that there's things like loop constructs.
If these things you can have nested instructions and stuff like that.
So different than most assembly languages in that regard.
So yeah, so here's a sketch of a modular web browser.
What if nearly everything was an extension?
I'm an EMAX user and an EMAX nearly everything's an extension and the core is relatively small.
What would the EMAX browsers look like?
It can't even be a thing.
There's so many web standards out there.
If browsers weren't concerned with having to implement all of them,
we could actually have implementations of web standards as web assembly modules.
And so that we could actually have,
we could ship browsers where the implementations could be swapped out as long as they respect compliant.
Maybe you could leave them out entirely.
There could be competition amongst an implementation of individual web standards
as opposed to just having essentially chromium and web kit.
And we got a gecko and stuff over there,
unfortunately, seeming to start to fade into relevance.
So one thing that's compelling to me about this approach would be
the idea of shipping to the web is good.
It's good to have a native app too.
It's good to have the same code in both places.
And so electron is kind of appealing,
but you're shipping all of chromium or something like to people.
And it's just like this giant blob and it does not make me feel good.
It does not spark joy at all.
But if I could tailor what I shipped down to just the things I need for my specific application,
I'd feel a lot better about shipping something like that.
The surface area for problems and just total binary size feels a lot more reasonable.
In that case.
And major browsers could look more like a Linux desktop does.
It's a curated collections of software packages.
What if browsers could be more curated collections of these modules?
But decoupling all this stuff means coordination.
We need modules to interoperate.
They need to share references to objects with each other.
How can modules know when another module is done using our reference?
Is anyone familiar with the WebAssembly component model?
WebAssembly system interface, OK?
Just a few people.
Well, this is a proposal out there for this Wassey thing.
It introduces the component model for collaboration amongst WebAssembly modules.
Unfortunately, in my opinion, it takes a very shared nothing or baro checking approach to collaboration,
where you can send something to another module,
but it's only for the duration of a single call and then you kind of like unbarrow it.
At the end, there's no real idea of sharing things for long term
and then collecting them when the objects are used in that other module.
And Wassey's really focused on non-web use cases anyway,
so I think Wassey is an interesting thing,
but I think it's completely the wrong direction for the Web.
So I think the solution really is to embrace garbage collection,
which is I know sometimes a contentious subject,
but I'm a big proponent of garbage collection.
WebAssembly 1.0 had a linear memory, only model.
You're talking about offsets, pointers, offsets into memory.
WebAssembly 3.0 added these GC managed reference types,
which means that we can do heap allocation.
So there's a struct.new instruction,
and this is what allocating a pair looks like in our scheme implementation.
And this is a pair that has two, you see,
this is Reft.I-31s there.
Those are representation of some immediate values,
in which case those magic numbers are the constant for true and the constant for false.
So this is just a pair of both Boolean values.
So these are heap allocated, they're opaque.
In the sense that you can't just get an offset into that memory there
and then go read off somewhere that you shouldn't be.
So we have some, there's security properties of heap references.
So we have this reference type hierarchy here.
This is what the reference type system looks like in WebAssembly.
You have all your things like structs and arrays for composite types.
And then way over on the other side here, we have this external reference type.
And that's good for sharing references from JavaScript,
or any other WebAssembly module.
So you can get external values, say like a DOM node or something like that,
and you can operate them, interoperate with them through WebAssembly.
So there's a whole rich type system here.
If there's any GC skeptics in the room,
if you're using Rust or something to compile into WebAssembly,
you could use what, why isn't GC as well.
It's not all or nothing kind of thing.
It would be feasible to say, have all your viral checking stuff
that you might prefer inside of your Rust module,
and then have GC between modules for that kind of collaboration that you need.
So it's another issue.
D-coupling means distributing trust.
WebAs is a very secure environment,
and so that high trust C++ core is a, you know,
something that's not changed with any, any speed, you know,
in the previous talk,
something about how careful the browser vendors are about about making changes.
So I'm proposing decoupling these things.
That requires even more security.
So we need a way to, for modules to collaborate safely.
How are we going to do that?
And the solution is capability security.
So sure of hand.
So it was sort of capability security in the room.
Okay.
It's a little less than half.
That's actually better than I expected.
Very cool.
The motto we like to use as rightly is,
if you don't have it, you can't use it.
By holding a reference to something,
you have the authority to send a message to that thing.
That's the essential idea of a capability.
If you're used to passing arguments to functions,
congrats.
You basically understand capabilities at this point.
Okay.
How many programmers in the room would say,
if you're familiar with the concept of lexical scope,
make that your security model and you have capabilities.
Importantly, it means no ambient authority.
And what does ambient authority?
Here's an example just using JavaScript of a contrived thing
that gets the value of something of an element and then focuses it.
The first one uses ambient global state by looking up an element by its ID.
And so the document is this magic global thing that you just assume
every function can access.
And then you can just look up things by identifier.
So this is what you would call ambient global state in a program.
And so that's not a capability approach.
A capability approach is explicit reference passing,
where you would actually get the element as an argument
and by holding a reference to it, you can then send messages.
So that's very simplistic example.
This is not a new idea.
This is a paper at MIT from 1996,
a security kernel based in the way of the calculus by Jonathan Reath.
I highly recommend highly recommended reading, really cool.
But just to show you this is an idea that's decades old.
Capability security also has the benefit of having a good user experience.
There's this paper I would recommend reading as well called not one click for security.
And I'll say, by using a browser today,
you're actually already used to certain capability paradigms.
The file picker, when you want to upload a file,
and give access to a file to a website,
is a capability pattern called a power box.
By clicking the upload file, you open the file picker.
The web page does not have access to your whole file system.
You instead consent to picking a very particular file
and granting it access.
So web browsers already have some of these really nice UX properties already.
And so I think we should take this further.
So yes, so reason I bring up capabilities is because web assembly
is a capability system.
And there's both compile time capabilities and run time capabilities.
Bison binders have no privileges by default.
They can't do anything besides they get into an infinite loop
and make your laptop hot.
They can't do IO.
They can't make network requests, et cetera.
It's all outside world interaction.
Any IO that a module can do has to be explicitly passed in
by its host, the instantiator of the module.
Which means you can't just import something from the web.
The web assembly module can't do that.
So this is a capability security, like a central core principle.
And web assembly modules may also export things
that then can be imported into other web assembly modules.
So with an import export system,
and no way to reach out beyond what you're given,
web assembly makes for a secure runtime.
And then all these heat-allocated references that I was talking about,
and talking about those are runtime capabilities.
So those are you can get access to references at runtime
and then operate on those objects and pass them around.
So this is just an example of importing.
Let's see, I'm just trying to see how I'm doing the time.
I'm doing okay.
So this is from our Hoot project, actually.
Like a snippet from it.
This is calling into JavaScript's big-int implementation
to allocate big-ints.
This is what the web assembly decoration looks like.
It's basically a function that doesn't have a body.
We just say there's a hole that's got this signature,
and I need the host to put something in there,
so that this module can work.
And here's an implementation of it from the web assembly side,
where we boot the module and then we pass in the import.
And in this case, it's using the big-int class to actually allocate the big-int.
But the important thing is that the instantiator is in control.
If a module asks for something,
that asks for something with a certain signature,
is up to the host to say what that is.
And the host could just pass in something that didn't do
what the module hopes it would do in the first place.
So if there was a dangerous feature or something that you didn't trust
about the thing you're trying to run,
well, okay, it wants an import.
Imagine this was like some kind of HTTP request.
You could just say, no, I'm just going to return
some garbage or spoof something or whatever.
So it's really the instantiator is who is in control,
which means we have the ability to run entrusted code,
which is kind of nice.
But let it end about to wrap up.
Another article that I found really compelling
was by Ian Hixie Hixon,
towards a modern web stack.
And Hixie has been advocating for kind of the same thing
that Joey Hess was advocating for,
of kind of reducing the stack.
More to being like, okay, you have a canvas
and you can draw on it somehow.
And this article has made people concerned
that the whole idea of web documents
and all the stuff that we get with the document object model
and all the accessibility features that are built into the document
model.
Like, are you proposing to throw all of that out
and just have a canvas and you just write pixels?
And I'm speaking for myself here.
And I think if we can figure out the right approach
to modularity, I don't think it has to be a dichotomy.
I don't think it has to be one of the other.
I think for the document web is great,
but also it's not sufficient for certain types of applications.
Can we find a way to have both of these things work?
So I don't, I'm not advocating for a choice
between one or the other.
I would like both.
So Wasm is room to grow.
What's out there with WasmGC right now is
it's minimal viable product.
It works.
I use it daily.
It's nice.
But there's a number of things that should be improved.
I gave a talk yesterday talking about these things more
in depth, but stack switching, multi-biter A access,
reference type strings for whatever reasons strings
are not as easy to work with.
I think what I'm talking about is you might expect.
There are many things that we can improve to make Wasm
like a suitable substrate for the kind of thing that I'm talking about.
But I think the core stuff is there.
The core security properties are there,
and I think we have a good base to build on.
So yeah, in summary, we have a near monopoly for browser engines.
I think it's quite unhealthy.
We need to break it up somehow, at least I hope we could.
I think Wasm is the suitable thing to use for this.
It's a really great technology, and I think also it's very accessible.
The standard is very easy to read,
and it's actually implementable without too much engineering effort.
Like you could do it as a free time project.
You could do it with minimal resources.
It's pretty cool.
We should push Wasm to its limit for this purpose.
See what we can get out of it.
And just in general, let's take back the web for regular people,
and to give users more agency over their computing.
So people are concerned about web assembly being like,
well, with JavaScript, I can read the source code,
right? I can look at the inspector and see the source.
It's not really true because most websites are delivering stuff
that's been run through a compiler to chain,
and minified.
You're already looking at things that aren't real source code anyway.
So the web has already gone in this direction of shipping you blogs.
And if we're going to do this, what we need is to give people agency.
If they're to have control over their computing in the long term.
So that's what I would like.
I don't exactly know how to get there,
but I've hope I've planted a seed of interest
in exploring this direction.
So I just encourage more thought and effort put into here.
So that's all.
Again, I work for a small nonprofit.
We do a lot with a little.
And if you like the work we do,
please visit SpritLetAinstitute.
So I should donate.
We really need your support.
We're a 501c3 nonprofit in the United States.
If you happen to be in the United States,
it means your donations tax deductible.
And yeah, otherwise, just check out our blog.
We have interesting things there.
So I hope this was of interest.
Thank you.
Questions.
Thank you.
All right, I can already see a hand.
All right.
We're going to do questions now.
We've got about six minutes.
Oh, I don't know what I'm saying.
Okay, great.
I forgot to start my talk once again.
So I didn't know.
Yeah, I apologize.
The apologies to anyone that came on.
I came in at groom on time or anyone watching this stream.
I did start your talk a couple minutes early.
So my apologies.
But anyone watching this stream can actually rewind it.
Watch the recording.
So I, I think the case is really convincing for this from the bottom up.
Like, you know, everyone below the like web dev that never got further than learning
of the JavaScript frameworks could be pretty convinced by this.
But I'm kind of like trying to imagine on the in the other direction from like the dumbest possible web dev.
How painful is it to have to do like your example of having to do capability like not having any global functions unless you're using the module that gives you global functions.
And and I was thinking like you talked about garbage collection capabilities, but just even.
I'm thinking there's like a whole school of thought that web 1.0 and web 2.0 were like basically enabled by the weird janky session abstraction that like made it so that you had to learn much less.
Programming to be able to make a web app that was state full and like how, how would we do just as a.
Random example.
I'm going to move in the possible question answer, but like how would you give that equivalence like what would have to be in place.
Which modules would have to already be written for someone to have.
Old school session variables and JavaScript and have it all run in this.
That's a great question.
Well, I would I would hope that by by doing something like this, we don't like throw away any of that old stuff because the web has to continue to be backwards compatible.
I would hope that like yeah, that old session based thing would still work and you would have hopefully that the API layer just you yourself the API layer to do that.
But you're I think you're getting at like you're talking about capabilities and it's it's slightly it's a it's.
In some ways a familiar way to program but also different because we're all we're used to some.
Being able to just like request like we talked to rest APIs and things like resource based things things with names, file names like non globally unique names.
I should say and that is not fully answered question like the world has not come to view capabilities as the way to go.
But I think the research is encouraging around things like this not one click for security paper around so there's there's the developer experience part and making things good for the developer and then there's the user experience part of like when you.
When you have capabilities as like what your systems built on how to how to users interact with them you're asking more about the developer experience.
And I think what we try to do it sprightly we try to like really emphasize that it looks like regular programming like I think.
The conceptual leap is not as big as people might think but there's still some education and.
I'm still looking for ways to like how do I how do I make this leap intuitive to people and I don't fully have an answer for you.
Does that answer your question in any form.
Okay.
Cool that was a great question thank you.
Awesome we should talk after.
We have time for one more question.
I'm going to go ahead and head over now and then we'll do change over.
If you do have a question for free to talk to Dave afterwards.
My main question would be that browsers are currently written in C++ for a great reason of performance and like.
WebAssembly like kindness puts a like branch in the works because it occurs like several times overhead in relation to the actual native implementation.
So if we were to like actually make layout in the engine and webAssembly like all of that graphics abstraction and webAssembly wouldn't that be just horribly slow.
That's a great question.
I think I could have a one word answer with yes but it's like yes but.
What I think you know I'm talking about like a vision here I think we need to like if this were to be pursued.
We'd have to find out like where where do we make the trade off where we where we maybe sacrifice a little bit of.
Performance for flexibility and for modularity and where where do we say that's not tenable and what do we keep in the core.
To you know there are certain things that just need to be faster than the R.
So you make a good point so I think I'm not saying get rid of all of the C++ essentially like if you maybe there are certain things that we have to keep there for practical reasons.
But we can modularize more a lot more than what we have now.
At the same time I think webAssembly can also kind of come up in its ability.
To express more performance programs and to be more efficiently compiled.
So for example webAssembly right now you're kind of strictly talking like single threaded programs there's there's a proposal for threads out there.
So for example like you're not going to have like a you can't write a really good garbage collector and webAssembly right now because it's not going to perform well because good garbage collectors want to use all of your CPUs for so it can be allocating across many threads and collecting and things like that so.
So there's room for webAssembly to level up and then there's also a matter of like we have to make practical tradeoffs of like what what what's worth it like what's worth having the modularity what's not right now does that.
Can answer question it's nebulous, but yeah sure.
Are you like later like yeah we get to that clear you sound unconvinced that's okay.
Thank you everybody.