WEBVTT

00:00.000 --> 00:15.720
Okay, good to see y'all, my name is Andy Wingo, and this is a talk about a new head of time

00:15.720 --> 00:21.000
compiler for WebAssembly, it's called Wastrel, it's WebAssembly without rentime, and once

00:21.000 --> 00:28.320
you start the talk with a little demo, let's see, it's my terminal, it's where they've

00:28.320 --> 00:34.920
mostly, I don't actually use a terminal inside e-max, I don't use many tools, because

00:34.920 --> 00:41.760
I'm not very smart basically, so we have, I'm in my Wastrel directory, I have to run

00:41.760 --> 00:47.160
inside a little environment, okay, Wastrel, I want to run a little WebAssembly file, and

00:47.160 --> 00:58.280
I don't know if people are aware, but WebAssembly is a list, and it has this set

00:58.280 --> 01:04.880
textual format, which is one-to-one correspondence with a binary, so you can write it

01:04.880 --> 01:10.400
as text directly, and this is called Wat format, or the assembly text format, so I opened

01:10.400 --> 01:14.400
up the Wat, obviously, I don't have my e-max very well configured either, still in the

01:14.400 --> 01:19.080
fundamental mode, I have to go in schema, though, because Wat has parentheses, and I don't

01:19.080 --> 01:23.880
know how to write things with parentheses without par edit and all these niceties, so writing

01:23.920 --> 01:31.560
a WebAssembly module, you start with a module, usually, it's actually optional, but it

01:31.560 --> 01:39.240
expands out to module, and we're going to do a hello-fuzz them here, so a funk hello, we're

01:39.240 --> 01:45.640
going to take no parameters, so you can put no parameters or not if you leave it out, it's

01:45.640 --> 01:52.320
not a problem, no results, okay, we're going to do a hello world here, let me just say

01:52.320 --> 01:57.480
call, and we're going to need to call some sort of procedure that outputs things onto the

01:57.480 --> 02:02.400
screen, and as you might know, WebAssembly doesn't have any capabilities in and of itself,

02:02.400 --> 02:07.040
you have to provide it with capabilities, including the capability to output to the screen,

02:07.040 --> 02:16.040
so we have to import, define a function, and say it's, well, call it pk, actually, it's

02:16.040 --> 02:22.280
kind of a nice name, and we're going to import it from, I don't know, some debug library,

02:22.520 --> 02:29.720
we're going to call it debug stir, and it's going to take as a parameter, and this is the

02:29.720 --> 02:37.720
problem with WebAssembly, it's like WebAssembly 1.0, you have N32 and 64, float 32, float 64, and how

02:37.720 --> 02:42.680
are you going to get a string into that, and this is the new thing in WebAssembly now, is that we

02:42.680 --> 02:49.240
have structured data, which is managed by WebAssembly itself, we almost had a good thing, in

02:49.240 --> 02:55.880
the sense that we almost had the ability to have a string data type in WebAssembly itself,

02:55.880 --> 03:03.800
and we didn't, we haven't managed to get it in yet, but we still have it in the tool chain

03:03.800 --> 03:08.160
that, that WebAssembly uses, this actually lowers down to an array of bytes at some point,

03:08.160 --> 03:13.080
so, has a parameter of a restring and no results, so we're going to import it from some

03:13.160 --> 03:24.360
standard library, so we're going to call pk on string.const, hello fuzz them, new line, all right,

03:24.360 --> 03:30.520
and we're going to start this WebAssembly module with the hello function. Now, if I didn't

03:30.520 --> 03:37.400
fuck up here, then I should be able to run this, let's see, last row, what is this, hello something,

03:38.040 --> 03:47.560
hello fuzz them, dot wet, does that fuck up? Ah, yes, there's one thing,

03:49.240 --> 04:00.200
expose the, talk about this in just a minute, hello fuzz them, oh thank you, y'all are so nice,

04:01.400 --> 04:05.560
that's not a little demo, so I'm going to get back to what the demo is, but I have to start with

04:05.560 --> 04:09.960
some story time, right, so let's go on on this side with me, I'm a long time commentator of the

04:09.960 --> 04:17.000
Gauss game invitation, Gauss uses the boom demo's Weiser Collector, the BDWGC, it's very reliable,

04:17.000 --> 04:23.320
we've had almost no problems with it over the 20 years, I think, that we've been using it, but it

04:23.320 --> 04:29.720
has some limitations, it's performance is not that great when you have multiple mutator threads,

04:29.720 --> 04:35.160
it has a relatively inflexible memory usage profile, you can't really get some very

04:35.160 --> 04:41.000
tight heaps with it, it can't move objects, it can't compact the heap, and there are new things,

04:41.000 --> 04:47.240
and I say new, but I realize that actually the new thing that I saw that I heard of at one point

04:47.240 --> 04:54.040
in was inspired to work on GCs was this design called Inix, it's a design for a garbage collector,

04:54.040 --> 05:00.040
and I'm like, it's a new design, it's 18 years old people, the time pass is really, really fast,

05:00.040 --> 05:06.200
but some of the work, precisely that we build on in this garbage collection work was

05:06.200 --> 05:09.000
happening a bit later, it's a kind of family of papers, but that one was the first one,

05:10.520 --> 05:13.960
so I always wanted to write a garbage collector, and that's probably actually,

05:15.080 --> 05:19.640
it's not one of these three bullet points here, but the problem with Gauss using the

05:19.640 --> 05:26.760
boom collector is that I didn't write it, which is not a good reason, but I've always wanted to

05:26.760 --> 05:32.840
work on a GC, and so I wrote a collection library built around this Inix inspired collector,

05:33.720 --> 05:39.240
and this collection library is called Wipit, Wipit is a embedable GC library, it's designed not

05:39.240 --> 05:46.200
to link to, but rather to include into your project's source tree, it's mainly designed for a

05:46.200 --> 05:51.800
project written in C, for a number of reasons we can talk about, now there's no dependencies,

05:51.800 --> 05:57.560
whatsoever, and the way it works is customizable, it compile time, you choose the collector,

05:57.560 --> 06:02.440
you choose the object representation, you specify how you trace your objects, you specify how you

06:02.440 --> 06:07.480
get your, how you identify the set of roots from which you need to start tracing, and that's

06:07.480 --> 06:12.280
such, it also contains a collector of collectors, collection of collectors, so I have another little

06:12.360 --> 06:20.120
demo here, so this is one of these commands that's kind of like the get sort of interface,

06:22.120 --> 06:28.920
and I have only really two options, I two sub commands right now, I have the run in the compile

06:28.920 --> 06:36.360
commands, so we're going to do a compile. Wastoral compile, and I can specify a GC with which to compile,

06:37.320 --> 06:43.400
oh man, it's kind of wrapping around my screen here, but I need an E equals here, GC equals help,

06:44.200 --> 06:53.240
help us them. Watt, let's compile it to hello, fuzz them, and I don't know, but,

06:53.240 --> 06:58.920
I specify in GC equals help is going to get me this list of available GC augmentations here,

06:58.920 --> 07:04.920
which you can choose, when you compile your, your Wastoral module, actually not all of these are

07:05.000 --> 07:10.760
appropriate for, for this, we'll get into this in just a minute, but I'm going to choose, for example,

07:12.360 --> 07:23.800
BDW, for example, so hello fuzz them, BDW, um, that work, okay, maybe I'll choose another one,

07:24.440 --> 07:31.480
MMC, which is another one of the main collectors in Wastoral, okay,

07:31.880 --> 07:46.600
hello fuzz them, star, all right, so we got the BDW one, compile the 70 kilobytes, and MMC, BDW is

07:47.800 --> 07:54.440
whip it's collector, but implementing whip it's API is the bomb library, so we're dynamically

07:54.440 --> 08:02.200
leaking to the bomb collector, for this one, we can run both of them, hello fuzz them, BDW, and C, okay,

08:02.200 --> 08:08.760
great, let's strip them both to get an idea of the size of them, so hello, I think about a

08:08.760 --> 08:18.440
father it puts in debugging symbols in BDW and C, let's look again, get an idea of what the size

08:18.440 --> 08:23.400
of these things are, so this is about the minimum you can get to with a with a Wastoral binary,

08:24.120 --> 08:32.200
the BDW one's 27 kilobytes, and it links out to the libgc, oh you can see, LDD on your hello fuzz them,

08:33.240 --> 08:37.560
BDW, and because I'm on geeks you can't really see anything, but the important thing is this,

08:38.600 --> 08:46.200
libgc here, so this one's looking to the libgc, and the other one is not, right, it links to

08:46.360 --> 08:52.520
what is this, LD Linux, libgc itself, that you see support library, libm, and I don't know what

08:52.520 --> 08:58.680
Linux video is, we'll see, right, so that's an example of choosing the different collectors,

08:59.960 --> 09:06.200
in whip it, there are three main collectors, right, three main collector variants and main,

09:06.200 --> 09:10.360
my quality collectors, because I've tried many things, but these are the ones that they're actually

09:10.360 --> 09:15.320
good, first one is a parallel copying collector, so semi-space collector, but it's heap is organized

09:15.320 --> 09:21.800
in a block structured way to allow for parallel both mutator and collector threads, it's a very

09:21.800 --> 09:27.080
good collector, but it requires a memory, and it requires the ability to precisely enumerate all of the

09:27.080 --> 09:32.840
edges in your heap graph, so that when collection time comes it can relocate them from from space

09:32.840 --> 09:37.720
to tree space, so it rewrites all the references at every collection, it's much faster than you

09:37.720 --> 09:43.560
would think though, the other one is the in-ex inspired collector, the MMC, and they're a mostly

09:43.560 --> 09:48.600
marking collector, because it mostly marks objects in place, but sometimes can compact them,

09:48.600 --> 09:53.080
and talk about these in some previous files and talks, I'm not going to go too deep onto them,

09:53.080 --> 09:58.440
and the other one is using the bone collector behind, and so I showed an example of using

09:58.440 --> 10:06.760
MMC and using BDW in this case, and the whole pitch here now is that this is what I would like to

10:06.760 --> 10:11.320
believe, and I haven't fully proven this, I'm not going to show a bunch of graphs today, but the

10:11.320 --> 10:17.400
pitch of this collector is that MMC collector improves on BDW, and that allows you to access

10:17.400 --> 10:22.040
tighter heaps, it scales better for multiple user threads, and it can compact the heap, so you

10:22.040 --> 10:28.360
never have that worry that's like, why is my memory like this, what's the reason, and BDW is not

10:28.360 --> 10:33.240
really something you can introspect and find that out, and whip it was developed with the support

10:33.240 --> 10:37.640
of NONET, thank you very much, and also with the Guardian, I have a bit of paper on this, oops,

10:38.600 --> 10:41.560
so if you, I'll share the side link later, but if you search for like,

10:42.600 --> 10:48.120
a whip it isn't in the name, this is going to be hard to search for, anyway, so whip it was made

10:49.400 --> 10:56.760
forgot, right? I designed it in some of the ways so that I could replace the use of the bone

10:56.760 --> 11:04.600
collector in-gile with whip it, and I, last year, from the period of about April to August,

11:05.240 --> 11:13.000
I actually did this, I replaced the bone collector with whip it first, with whip it, but using

11:13.000 --> 11:23.480
BDW, and then whip it, but using MMC, the MX-DRIVed collector, but in a fully conservative mode,

11:24.040 --> 11:30.760
so not precisely enumerating edges on the heap, and then moving to a mode where it scans the stack

11:30.760 --> 11:36.840
and static data, conservatively, but heap edges are precisely enumerated, which allows it to

11:37.400 --> 11:42.760
actually improve on performance, and this took about 300, 350 commits or so, not sure how many of

11:42.760 --> 11:49.240
those are merge commits, because I was merging in whip it periodically on this, and I need to,

11:50.040 --> 11:55.240
I got it to the point where it's pretty good, and I still need to do some evaluations on it,

11:55.560 --> 12:00.920
but I need to do some incremental merging of this work, now that we are on code bird,

12:00.920 --> 12:07.320
and can do like merge requests and proper code review and such, for a push for a gal fore, so

12:07.320 --> 12:11.800
I'd love to talk about this in the next couple of days of the geek states, if anyone's going to

12:11.800 --> 12:18.440
be there, or afterwards, whatever. Right, right, right, but this is like Alice's restaurant,

12:18.440 --> 12:24.760
and so this is a talk about Wastrel, right? Not a talk about whip it. Wastrel is a funny thing,

12:24.920 --> 12:30.200
it's a web assembly to see compiler, right? So you didn't actually see the see compiler

12:31.320 --> 12:36.680
being invoked when I, when I invoked Wastrel before, but it just takes care of that itself.

12:37.560 --> 12:45.560
It's a Wastem to see compiler, but which embeds the whip it collector for managed data types.

12:46.520 --> 12:48.520
Wastem to see compiler with whip it, okay.

12:54.920 --> 13:00.440
I don't believe it was narcissism that I started all of these projects with a W. It really,

13:02.680 --> 13:07.560
Wastem, I didn't name that, whip it was named because it was a work in progress,

13:08.280 --> 13:13.480
garbage collector, and Wastrel because Wastem things are often named starting with the W.

13:14.280 --> 13:20.440
It's what I'm telling you today. So Wastrel is not, it's not like the first,

13:20.440 --> 13:24.040
and I'm sure it's not going to be the only compiler that's like a Wastem to see compiler,

13:24.920 --> 13:28.040
there's a number of them out there, originally there was Wastem to see,

13:28.760 --> 13:35.720
and then there's an update version of this called W2C2, improves on a number of ways.

13:37.880 --> 13:47.960
Our differentiator for the Wastrel project is that we aim to do Gc, so I'm doing whip it,

13:47.960 --> 13:53.640
and it's built in Gile on top of the WebAssembly libraries that were made as part of the

13:53.640 --> 13:59.960
hoop compiler. So all of that Wasm work allowed us, well, allow me to make the first version

13:59.960 --> 14:05.560
of Wastrel in a couple of days, right. The first version of Wastrel that couldn't do anything, of course,

14:05.560 --> 14:11.320
because Wastrel is essentially a baseline compiler in structure, and I've written baseline

14:11.400 --> 14:17.640
compilers before, and I've written things based on the who-wastem libraries, the process,

14:17.640 --> 14:22.600
Wastem modules, but actually getting it to do something, took a little bit longer,

14:22.600 --> 14:25.560
in the sense of wiring it up to other capabilities. A little bit more in that minute.

14:26.280 --> 14:31.960
How does it perform? It's, it's great, right? No, no, no, I mean,

14:35.560 --> 14:40.520
say you can probably, I haven't done a full battery of tests, but say you can pass something like

14:40.680 --> 14:48.840
core mark, right? You compile it native, and then you compile it by a Wastrel or, or Wasm time,

14:48.840 --> 14:55.320
or Wtc2. Wastrel is like a few percent off native, like maybe three, four,

14:56.840 --> 15:04.120
and Wtc2s about there, and Wasm times significantly below that in my tests anyway. So like it,

15:04.200 --> 15:12.120
it is a state-of-the-art compiler in that sense. It, and it doesn't, on the features of Wasm,

15:12.120 --> 15:19.560
for example, memory isolation, and it does so, because it, a lot of the more complicated Wasm

15:19.560 --> 15:23.480
run times allow you to instantiate modules at runtime, but because this is a fully ahead of time

15:23.480 --> 15:28.440
compiler, we can fully allocate everything statically, we can fully allocate all of the memory statically,

15:29.000 --> 15:34.920
and, and, and thus at runtime reserve, a gigabyte map regions for the memory, for example,

15:34.920 --> 15:39.640
so you don't have to do any runtime checks that, that your pointers are in balance, for example.

15:40.920 --> 15:44.760
Yeah, hey, I'm sure a lot of people have worked in C here.

15:46.440 --> 15:53.320
My, my approach to C is, is much, much different than when I learned it poorly 20 years ago.

15:53.320 --> 15:57.960
So I, I just wanted to have a little slide here about if you're working with C, this is what I've

15:58.920 --> 16:05.240
found to work for me in recent projects. So I, I think you want to heavily lean in,

16:06.440 --> 16:12.920
trust the optimizer, for example. Like sometimes we are when writing C or when generating C,

16:13.640 --> 16:18.120
we try to smash everything together, right, because you're like, okay, we're just going to

16:18.120 --> 16:22.120
inline everything in, in, in an expression, because that, that way the compiler is going to do things,

16:22.120 --> 16:28.760
good things about it. We can actually use abstractions in, in terms of static inline always inline

16:28.760 --> 16:34.360
functions, and it, and it, and it works great. It burn away completely a compile time. And, and as such,

16:34.360 --> 16:40.600
you can have extractions without runtime overhead, and, and, and, and, and, and avoid a lot of, like,

16:40.600 --> 16:45.800
the pathological, um, undefined behavior stuff in, and C, for example, about, uh, casts,

16:46.600 --> 16:50.840
completely remove casts from your program, uh, both implicit and implicit, always go through

16:50.920 --> 16:56.040
static inline functions to do so, just to make everything, um, explicit. If you need to read

16:56.040 --> 17:00.680
from memory, you can always mem copy, uh, even if it's four bytes, in the case of web assembly,

17:00.680 --> 17:04.440
and the compiler will rewrite that to a four byte load if it can, but that, that follows, like,

17:04.440 --> 17:11.160
the C memory model. Um, and absolutely avoid, um, like, using any kind of integer data type to represent

17:11.160 --> 17:15.640
anything of semantic value, like, always wrap that in a struct of one value, and it will get

17:15.640 --> 17:19.640
compiled just as well. But that just means, like, you've given a name to what that is, and it won't

17:19.720 --> 17:25.400
get confused with any other U.N. pointer, or, or, or, enter, whatever that, that is, uh, that might

17:25.400 --> 17:30.440
implicitly convert to that value. And, and the goal is, like, so Wasm as a type system is a strongly

17:30.440 --> 17:35.960
typed, and, and, and the type system, like, is the reification of a proof that when run at runtime,

17:35.960 --> 17:40.840
it's not going to do a number of things. And, and if we manage to translate the types from Wasm

17:40.840 --> 17:46.360
into the types and C, then I've also translated that proof, right, like, because I've eliminated

17:46.440 --> 17:52.600
a number of sources of, of errors that GCC can actually, uh, check that, that my compilation is,

17:53.720 --> 17:58.920
preserve these properties for me in a bit. Of course, you know, you also want, like, sanitizers

17:58.920 --> 18:03.160
and things like this, but, but you can lean into, and, and the C type system a bit better than,

18:03.160 --> 18:06.920
at least, at least what I was used to doing, you know, 20 years ago with a bunch of castes and stuff.

18:07.960 --> 18:13.640
Um, right, so the question is, what do we do about a standard library? Uh, with, with C programs,

18:13.720 --> 18:20.440
there's a C standard tool chain called the Wasm SDK. Uh, it's a version of clang plus, uh, a C library,

18:20.440 --> 18:26.040
and you just compile like clang with target Wasm 32. Uh, Wasm 32 wasn't p1, for example.

18:26.040 --> 18:31.960
And, and that runs great in, in Wasm, I can run LVM, for example, uh, with, with Wasm,

18:31.960 --> 18:37.160
takes forever to compile. This is, this is another issue, but, um, uh, but it was really excruciating

18:37.160 --> 18:44.520
implement, um, because, uh, the Wasm interface is essentially what you're given is the, the reified

18:44.520 --> 18:50.760
artifacts of, of an API, API lowering in terms of N32s and floats and stuff. You don't actually

18:50.760 --> 18:56.200
have pointers or meaning when, when you're, when you're implementing Wasm unless you, unless you

18:56.200 --> 19:01.400
implement other tools. So, I, I kind of running in circles here, but that was very, very annoying

19:02.360 --> 19:07.720
The one, the one thing I would note that was that, uh, Wasm can expose a file system interface,

19:07.720 --> 19:14.040
and, uh, I, I do so with Linux namespaces, so it only runs on Linux. Okay, better force.

19:14.600 --> 19:21.560
Uh, if you need access to file system. Okay, get back to GC. Uh, Wasm 1.0 was number of instructions

19:21.560 --> 19:28.520
that can operate on an array of bytes. We're up to 3.0, anomaly, now, which is linear memory,

19:28.520 --> 19:35.160
but also exceptions, manage memory data types. And so, uh, here's, here's, for example, a

19:35.160 --> 19:42.520
definition of a pair type, right, in WebAssembly. Uh, well, I can't actually highlight it. There, uh,

19:43.800 --> 19:49.480
I have a, a cursor. So I have a, a pair type. It's a structured data type, a product type,

19:49.480 --> 19:57.240
and it contains two fields. I didn't give them names here. Um, X is in the type hierarchy of WebAssembly,

19:57.320 --> 20:02.120
values that can be prepared, that can be compared by identity. You can, you can, you can apply

20:02.120 --> 20:08.680
ref X on them. Um, so it's like, it's a pair of any values, essentially. And to const, to make a pair,

20:09.400 --> 20:16.280
I write a function that takes as a parameter A and B, my X refs, and then I return a pair, and I, I,

20:16.280 --> 20:22.040
I return it by, it being the last value in the, in the function, and I just call structure new pair,

20:22.040 --> 20:27.560
and I, and I give it the operands as organs. It's, um, it's a higher level assembly, and it's an

20:27.560 --> 20:34.680
interesting target for for compilers, because you can run this on the web. You can run it on cloud environments,

20:34.680 --> 20:39.640
and you can run it with last row now. Uh, we have, uh, in addition to structs, there are also arrays.

20:40.360 --> 20:48.280
Subtyping is a whole thing, um, recursive types, immediate, uh, casts, and, and it needs stuff.

20:48.360 --> 20:54.120
So it was, it was, um, took me longer than expected to add, uh, Gc to last row, because of subtyping,

20:55.000 --> 21:02.200
because you have, like, um, well, in wasm, you have typing judgments that are formally verified,

21:02.200 --> 21:09.480
and to translate those, like subtyping into C, uh, was, was very annoying. Um, but, uh,

21:09.480 --> 21:15.640
it managed to work, and so Gc can check our work. So here's an example, right? In, in wasm, Gc,

21:15.720 --> 21:22.200
you have three top types. So three type trees, sort of, or lattices, right? Uh, there's any, and

21:22.200 --> 21:30.760
external, and funk. And they are, um, yeah, they're, uh, external, and any can be interconverted,

21:30.760 --> 21:37.240
but funk cannot, and this is based on, uh, reasons of how things are represented in, um, in, in

21:37.240 --> 21:45.240
web browsers. And so under any, you have x, and then under x, you have i31, which is, uh, 31 bit

21:45.320 --> 21:52.040
immediate. You have strokes and arrays, right? And, and we represent them as, you know, uh, C

21:52.040 --> 21:58.600
strokes, which include the parent just, uh, directly like that. Um, and functions, they include just

21:58.600 --> 22:03.320
the function pointer as a value, and I hear I have to use a voice star for reasons. And, and functions

22:03.320 --> 22:07.320
are the, are the pointer type that actually bears the type in the, in the reference itself. But for

22:07.320 --> 22:12.440
objects, their type is in this, uh, tag word initially, and then so you have an object representation

22:12.520 --> 22:18.520
hierarchy as well. Like you have any object, and instructs are any object, and arrays are any object,

22:18.520 --> 22:23.800
but also with a length field. And so, that was a header that's like the sort of base types,

22:23.800 --> 22:29.960
and then last rolled generates a number of, uh, implementations for these types. Uh, uh, this,

22:29.960 --> 22:34.760
there's some, um, routines on the, on the base type. So you have, you have noble types, and non-noble

22:34.760 --> 22:38.920
types, and you can check if something's immediate, and then you can, you can get an object reference

22:38.920 --> 22:44.120
out of a, uh, of an any rough. I'm going a little fast here, because we got, you know, a couple

22:44.120 --> 22:48.520
minutes. So let's step through some, some generated see here. Here we have two types. One is a,

22:48.520 --> 22:54.760
uh, as type 0 is a struct, it has an i31, i32 field. And then we have type 1, which derives from type 0,

22:55.320 --> 23:01.480
which has the same i31, i32, this is supposed to be i32, excuse me. But additionally has a,

23:01.480 --> 23:05.960
uh, a ref to type 1, so there are a cursive type. And so that reason we've, we've wrapped it in

23:06.040 --> 23:13.080
rec here. Uh, what is this generate? We generate, uh, some, the ref types for which we can refer

23:13.080 --> 23:19.320
to these values. So type 1 ref, derives from struct graph. Uh, type 0 ref, derives from struct

23:19.320 --> 23:25.160
graph, type 1 ref, should derive from type 0 ref. You know, excuse me here. Um, and, and the representations

23:25.160 --> 23:30.760
of the actual objects, uh, type 0, directly from struct, type 1, this should be directly from 0, excuse me.

23:31.480 --> 23:35.960
Um, and then we can have our type predicate. Because we're at a header time compiler,

23:35.960 --> 23:42.680
we can allocate type tags continuously, uh, via depth or search, so that a type test can include

23:42.680 --> 23:48.200
subtypes. Like I just have, uh, what are two comparisons in, uh, in the source code, but which

23:48.200 --> 23:54.680
compiles that one comparison, um, here. Because the range of types has a continuous range of, of, of,

23:54.760 --> 24:02.200
tags, um, having sorted the tag values according to the type tree. Um, and then you can, when you

24:02.200 --> 24:08.280
create one of these values, you can pack it into a ref with loads of, of, of, of braces, you know,

24:08.280 --> 24:14.520
so, as you can tell, web assembly is definitely a list here. Um, and, and here's the, the one,

24:15.560 --> 24:20.920
instance of, of, of, of, of, of whip it code here. You pass a mutator around because we're,

24:21.000 --> 24:26.680
static the allocating just one thread currently. This is a global variable. Um, you allocate the size of type

24:26.680 --> 24:32.280
one, we're telling it's a tag allocation, initialized tag word, initialized field 0 in the parent,

24:32.280 --> 24:38.440
because that's how the types work, and then we're, we return the pack value. Okay. Um, right,

24:39.240 --> 24:45.400
one, uh, so we have a currently to get capabilities, uh, we look at the set of imports and provide

24:45.400 --> 24:50.280
imports that we know by name. So for example, debugster is something that who uses, for example,

24:51.240 --> 24:56.280
in, in, in, in, in, in, Wazun couple of hoot artifacts. I implement that, and that's what allows us to

24:56.280 --> 25:00.120
know how the world. Um, I'm going to look, you know, soon to building out the hoot standard

25:00.120 --> 25:04.360
lived, including big norms and other things. And, and Wastrel skin, Wastrel can also, in many

25:04.360 --> 25:09.000
other extensions. So for example, the string wrap support that we saw is actually, uh, an artifact

25:09.000 --> 25:13.640
of the tool chain, not of the, an imitation, but like, because it, because it's built on the, on the

25:13.640 --> 25:18.600
hoot, Wazun lives, we can compile the, the text format to the Wazun format on the fly. And from,

25:18.760 --> 25:23.000
from this code, we can still access the Wazun capability. But it's, it's not really because Wazun

25:23.000 --> 25:27.720
often assumes, uh, that you're passing parameters through linear memory and doing so, uh, via,

25:27.720 --> 25:32.520
via Wazun Gc isn't so nice. The status is that it's, it's somewhat demoware right now, right?

25:32.520 --> 25:37.480
I just got it working, right? Um, but it's up on Wastrel. We have never issues for things that are

25:37.480 --> 25:41.960
still dimmed. We're going to be rolling this out over the next month or two. Um, and next up,

25:42.840 --> 25:49.080
other, uh, language runtimes. There's Kotlin, Skala, OCaml, happy to have been any, uh, any of the

25:49.080 --> 25:53.480
facilities that these run times need, uh, from web browsers. So we get native compiles for them as

25:53.480 --> 25:58.200
well. With hoot, uh, since we can compile a guy, essentially, to web assembly, we now have a web

25:58.200 --> 26:04.280
assembly to native, uh, target as well. Interesting. Uh, benchmarking some more Wazun features.

26:05.000 --> 26:10.840
Um, as you saw, I had to expose the root directory, uh, when I ran things, because the Gc

26:10.920 --> 26:15.160
wants to read proxail from app, and as I need to fix, uh, the file system sandbox,

26:15.160 --> 26:20.040
with regards that you see, some bugs, more Wazun standards, stack switching, which is essentially

26:20.040 --> 26:25.320
fibers and drilling conditions, drilling situations, in the Wazun standard, and to be active,

26:25.320 --> 26:30.200
which is meant in helping evolve Wazun standards. So, and if you're writing a new language,

26:30.200 --> 26:34.760
consider, generally, Wazun Gc, because it's a growing ecosystem. There's not so many things right

26:34.760 --> 26:39.480
now. You'll be the center of attention. If you are targeting Wazun Gc already, then let's talk

26:39.480 --> 26:43.160
about implementing your standard library. And if you are implementing a language runtime,

26:43.160 --> 26:46.760
and you need a garbage collector, let's talk to you. So, thank you for a much, uh, I can take

26:46.760 --> 27:01.080
a question so we can ask you a question. Sure, and note. Sure, and note.

27:01.480 --> 27:12.120
Yeah. Yeah. Good question. The question is, uh, just compile and you see how you

27:12.120 --> 27:18.200
have your head. Uh, on one side note, um, on the other side, uh, some things are unavailable to us.

27:18.200 --> 27:23.160
For example, uh, implementing exceptions, you would like to have a side table mapping program

27:23.160 --> 27:28.920
counter to ranges of of exceptions, and I'm not going to be able to do that, right? Uh,

27:29.240 --> 27:37.480
or because I am not using handles in all of my GC objects, like here, for example,

27:38.520 --> 27:44.600
if, if I had a moving GC, this should be a handle. This type 1ref should be a, uh, should be a

27:44.600 --> 27:49.960
relocatable pointer, because it's present before I allocate a value. And when I allocate,

27:49.960 --> 27:56.600
that can cause collection, invalidating that value. Uh, I could do that, but it's, it's, um,

27:56.600 --> 28:02.760
it's so gnarly to do handles, and I, I don't want to, but it's also a limitation of C, and

28:02.760 --> 28:08.280
that it doesn't really facilitate me, uh, ensuring that each pointer is relocatable, um, in the right

28:08.280 --> 28:14.360
way. So, so the answers have been ambiguous there. It's an okay strategy, I think, but it is not

28:15.160 --> 28:17.960
globally optimum. There are other options.

