Patching WebAssembly Binary with C++

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
okay our real life looks like we're live hello everyone and welcome to yet another uh get ready so let's make a little bit of an announcement and officially start the Stream so uh a red circle right so live on Twitch and what are we doing on twitch.television what exactly are we doing on twitch.television today we are hacking webassembly in C plus that's what we're doing today so I'm going to give the link to uh that which channel where we're doing all that which which is slash so I think and I'm gonna ping uh everyone who's interested in being pinked and there we go we officially started this stream so today we're gonna be doing a very interesting thing right so some time ago I actually started developing like a game in Jaime uh Jai is a Jonathan Blow programming language um so I started to develop this game as sort of like an exercise as a you know an excuse to learn this language and uh recently we did a very cool thing we ported that game to webassembly and the cool thing about that fact is that that Jai does not support webassembly in the first place right so we ported um a language that doesn't support webassembly so the thing it does support it does support the LED VM intermediate presentation so it can speed out uh intermediate representation of the um of the application is compiling so then you can do whatever you want with that intermediate representation and we basically translated that to webassembly and you can play this game without having the job compiler in here so J break uh so there you go so this is how the game looks like right and you can play it without in any recompilation or anything like that so I'm gonna give the link uh in the chat and I'm also gonna put that in the description for anyone who's watching on YouTube If I Ever Gonna upload this thing on YouTube so let me open the description so the description currently this was some stuff that I probably not gonna upload so let me maybe actually overwrite this entire stuff so references uh references and in here I'm gonna give the um [Music] deployed game right deploy it in and also I'm going to give the source code of the game so for anyone who's interested you can find a source code in here I'm going to copy paste that in the chat and I'm going to also put that in the description uh so source code of the game right there you go so but the problem is um the we sort of hacked our way through uh webassembly compilation right so basically Hector right now unfortunately um and that also created an interesting bug that we effectively ignored just to get things done as quickly as possible right so we managed to compile GI code to webassembly but that code didn't really work correctly and what we do we simply ignore that so but today I wanted to get back to that book and actually fix it and while I was researching how to fix that bug I went to a pretty cool rabbit hole that I would like to share with all of you so we're gonna go down that rabbit hole together because it's rather interesting and not particularly intuitive and also the same time super cool uh right and it's it's related to C plus plus I promise we're not going to do C plus plus right away but it is related to C plus plus uh okay let's take a look at the bug uh so I'm gonna start team nukes and I'm gonna go to the source code of jai right so the bug is the uh these structure literals don't work right so the structures don't work if we go to jailbreak and open the game and let's pick the the player right so do we have a random player uh okay so we don't have a separate function for that but we have a big function render that renders everything let's try to find where we render the player um I'm not really the player but the bar right so I think this is the place where we do that yeah so if we are in a place State we simply this doesn't look this is a projectile here is the bar okay so the bar color we can strike the barcode a color at run time right so if I construct the bar color at compile time this is not going to work and you can do that using the structure literals right so let me actually put the structure list in here and if I try to recompile the center I think right so by the way off screen I I did a pretty cool thing uh essentially now the entire compilation of the game is done in Jai without any shell scripts uh right I don't know if I actually said that on the on the stream but essentially now uh there is a function build wasn't platform that basically builds everything right and it goes to a function uh that like calls the external things in here right so you don't even need to have a shell script so you can use J as the cross-platform shell uh which is rather cool so because this is one of the problems that I have with like C and C plus plus you you can't just have uh like an easy cross platform shell right so we can have a cross-platform build system but build system tend to get over complicated and quite often I just want to have a simple build system and it's usually the shell and shell is not cross-platform unfortunately right so in here you can use the language as the shell and and that is very very convenient so we have a lot of subscriptions actually thank you so much everyone who subscribed I really appreciate it I don't get any money from that but I really appreciate you throwing money at uh Amazon anyway the your tour thank you so much for twitch Prime senior Whopper pants thank you thank you thank you and share with some tofu uh thank you so much for four months of uh of the subscription um all right so and let's actually try to recompile this into anything I think I'm gonna do uh Opitz Jai Linux and I'm gonna do first giant all right so and another interesting thing now what I did is when I detect an an assembly right what I detected when I detect an assembly I removed the entire body of the function and this is something that you can actually do enjoy right you can detect a certain construction during the compilation and do something with that for example remove it right so since we can't compile uh assembly inline assembly blocks into webassembly we have nothing to do with them we can only remove them so essentially you have to write a code that doesn't use such functions right um so yeah and the compiler also I made the compiler to sort of warn you uh if you're like if the assembly code is detected so don't use that specific function it will be also kind of cool to maybe uh I don't know throw some sort of a compilation error if you're trying to use that function from your code or something like that but we'll see so it's it's not particularly obvious how to do that um so we have some some errors which are kind of weird uh oh yeah I know what what's up with that error so this is like a fresh installation installation of Jane so I'll probably have to go somewhere here yeah so I have to add system in here okay let's forget about listening one more time uh let's recompile this one more time and maybe it will finally work so it takes so much time it's because it is like spitting out the intermediate representation it's usually pretty slow process for whatever reason uh there we go so also let me start the server so I can serve the web assembly actually the server 6969 I should have actually done that in an in an asynchronous way um all right and there you go so I already tested this into I think no I didn't test this Center I think uh actually yeah there we go so here's the problem as you can see uh there's no bar there is no bar and this is because right this is because I used the structure liberals if I construct uh structures at compile time they don't work if I construct them at runtime they do work and that's the bug that we have in here right that's the bug that we have on here um so we'll have to wait a little bit right the uh you know the build of the inside I think is kind of slow because it involves like other things except J right external tools and stuff like that right and if I refresh as you can see it works so using structure literals simply does not work and that is very very interesting all right so one of the hints that were given to me about why this doesn't work um done by one lives left I don't know if he's watching this right now but yeah uh he's another another better tester of this language he said that the structure literals are located in a data section right so basically they are constructed at compile time and they are saved into the data section and uh then they're referred to you know in in the data section so but here's the thing the way we hacked together webassembly is by simply converting right simply converting the webassembly code to what what is the textual representation of webassembly and back to wasm several times which effectively apparently removed the data section so essentially we're compiling Jai and removing the data section right and that's why anything that involves the data section simply does not work in the in the final application that we compiled does that make sense right and the question is why do we do that in the first place okay if we don't do that right so here 's what we're doing so we're just compiling the the file in here right so we just compile it let's see if it's going to compile or not also let me actually not compile any native platforms all right so we're only going to focus on bottom right so we're only focusing on Watson um so it should work right so we're just compiling the the final thing but the problem will start to appear when we'll try to link that object file print okay so as you can see we're taking the intermediate representation and we are turning it into a file so that went great that went okay and now what we can try to do we can try to link that file into the final executable so let's let's give it a try um so I don't see if I can just quickly uncomment something I think I can uncomment something like this all right so let me copy paste it in here uh right so and so I'm using the fixed oh let's not use fixed store I'm going to just use the regular or right so let's try to link that as well [Music] so let's wait a little bit and here is the problem so uh it says while trying to link this thing it says invalid data symbol offset uh type table offset is this but segment size is this right so and essentially we have a data symbol right a data symbol type table which has the size of this thing but the start of that thing is located beyond the size beyond the size that is allocated for that segment see this is rather strange right so essentially what that means the compiler generated uh some data that is smaller than the pointer it tries to point to right it generated some array of some size and then said okay so the these symbol stats at that thing that is over that data and I was thinking like why the would compiler generate something like that why the hell would it even generate anything like that and here is this the thing and then the very interesting thing occurred to me um so let's actually go to the standard Library uh GI modules I think maybe pre-load uh or maybe Kampala I don't remember um I think it's it's better done by looking at the compiler right so let's take a look at the build options of the compiler right um I remember there was something like machine or maybe oh okay so there you go so there is an option called machine type right and the only thing you can put in here is x8664 right it supports only 64. and the comment clearly says we only support 64-bit x86 at the moment so this isn't very useful yet uh so and if we take a closer look at how we're trying to compile foreign oh boy essentially the compiler is compiling everything using 64-bit pointers right it's a 64. it thinks that it's compiling for 64-bit machine but then we're saying okay the target is wasn't 32. and here is an interesting thing about wasn't 32 wasn't 32 supports 64-bit arithmetics and stuff like that but that it doesn't support a 64-bit memory addressing right so for that specifically there is wasn't 64. right so but the problem with wasm64 is that it's experimental right so a lot of JavaScript runtimes simply do not support that but we can try to compile uh our thing with wasn't 64 and see if it will work or not right so let's actually see if it will work I'm going to try to recompile this into I think um I wish it was a little bit faster but it is what it is it's not about Jai right it's about external tools that we call to so J itself is actually very fast and as you can see it compiled perfectly so this is something that was discussed in the uh GI Discord server for quite some time people were thinking how can I compile it to webassembly because every time I try to compile to webassembly I get that passkey uh type table offset problem this is how you solve that you use 64-bit assembly to compile your jab application that's how we do that but here's the problem okay so if I try to now run this thing right and the cool thing about just using 64-bit is that you don't have to do any of those stupid hacks of like converting back and forth to remove the data section you just don't have to do any of that right you just like compiled as usual right so and if I try to reload this entire thing uh so what's gonna happen uh oh yeah yeah so I'm using the old version so let me actually go and remove the fixed so this is the 64-bit version and if I try to do that it says invalid memory limits flag 0 4 enable via experimental was a memory 64. so here's the interesting thing this is the flag there is no such flag for chromium so this is a message this is a message from the compiler right so you need to enable that in on the level of the compiler maybe there is a way to set that flag somewhere in the settings but this thing is experimental uh wasm64 is an experimental thing and it's not that easily supported on all of the browsers right so you can probably enable that in node.js right so just by providing that flag but in the browser you can't expect the user to just have this enabled somehow right so we have essentially one option right so we just wait until this becomes like you know the stable feature of webassembly and all the uh all of the browsers support that or we can do something more interesting right if we can try to do something more interesting [Music] is there a way to convert from wasm 64 to wasn't 32 maybe this is a good question you're you're actually looking in a very very right direction very right direction so there is a degree of rightness right so um essentially uh let me see what we can do uh after all of that so here we have um main.twasm let's try to convert that main.wasm to what and see what we can do with that so I'm literally gonna do uh wasn't to what uh main wasn't right main wasn't and I'm converting that to what and as you can see uh wasn't even wasn't to what does not allow you to do that right so it doesn't like allow memory 64 by default if I remember correctly what you have to do you have to use some flag to enable that oh there we go so you have to do enable memory 64. uh all right let me see so we have to do enable memory memory 64 right and let's see so the essence of memory 64 is essentially the memory declaration right so in wasm32 memory declaration doesn't have this type in here right it simply doesn't have this type it just like doesn't have anything in here but memory 64 does have that and what it means it means that every time you try to do any memory operation like a store or load if it accepts 64-bit pointer instead of a 32. okay so can we just say just use this thing then right so just use the 32-bit memory uh and let's try to convert it back to towards them right to what to wasn't um we don't have to enable anything and I'm gonna just literally try to compile that and we're getting very interesting things we're getting validation errors right so this is not a valid wasn't anymore because for instance you have a store instruction right so store instruction and um it accepts now since the memory is indexed with 32-bit integers it accepts 32-bit integer for for the pointer and some value I64 in this case it just saves I like I-64 but instead it got I-64 so just because we said okay use 32 bits to index the memory it doesn't mean that the code does not assume that everything is 64 bits right the code the entire code itself still expects the pointers to beam 64 bits right so no matter how you you know change the the definitions and stuff like that the entire code is still hardwired to work with 64 bit integers and this is like a interesting problem that we have to solve my idea is the following so only load in store operations create the problem only load and store I have the following idea what if we patch the webassembly code essentially write some sort of a program that searches for all of the store and load instructions right and then right before store and load we're gonna insert another instruction that simply truncates the pointer to 32 bits right essentially we allow the code to think that it works with 64-bit integers but right when you're about to read or write into the memory we convert them to 32-bit integers right and I know for sure that the the program is not going to use more than four gigabytes of memory so I know that it's not going to create the problem right so we're sort of like emulating 64 bits you know what I mean um so that's basically the idea I want to write a program that takes 64 wasn't 64 and turns it into wasn't 32 allowing the the logic of the program to think that it's still in 64 bits right it's emulating with 64 bits right so it should be relatively easy because you just need to find all of the like load and store instructions and just like convert points right before them and that will trick the entire thinking into into working and if we manage to pull that off um that will be actually kind of cool foreign [Music] or maybe we can change the entire instruction itself which is which is also pretty cool so uh let's actually start working on this internet I think let's see if this entire ID is going to work in the first place right so let's actually see what we can do about that uh let me maybe go to prop and I'm gonna create um how I'm gonna say that so essentially I'm going to write a simple C program right I'm going to compile it to uh wasm64 right I'm going to compile to what I'm 64 and then uh I'm gonna try to manually change those things to like you know to 60 to 32-bit right reads and writes and see if it actually solves the problem if it actually ports 64 bits to 32 bits right because doing that with the jailbreak executable is kind of like uh kind of tedious because it has like as far as I know it's like it has like 4 000 like read and write instructions so it's like you know too much okay uh let me see [Music] um test 64 to 32 idea uh let's actually put it this way it wasn't 64 to 32. test 2016. uh and let me let me see foreign so let's create a simple program right so let's actually create a simple problem that we're going to compile to webassembly so what we're gonna do uh we need some memory right we need some memory that we're going to address so this is going to be uh let's have a bunch of messages right so we're gonna have uh phones char and we're going to put some messages in here all right so here's the messages Hello World um and then this is going to be full bar uh and then maybe test test test whatever right so we just need to have some messages uh and we need some function that will maybe do something with this messages maybe iterate them or something like that iterate messages um right so I also need to know how many messages I have in here and I want to be able to easily add this messages so I'm gonna just have a constant uh right so Define messages count all right so we're going to take the size of this array so messages and I'm going to divide it by the size of a single element of that array and this is how we're going to compute the the amount of messages that we have in here everything thank you so much for one month of or for four months actually of tier one subscription the twitch Prime subscription thank you thank you thank you so let's actually iterate through this entire thing uh I'm going to write in here messages count uh and what we want to do we want to print those messages somehow right so let's actually do print message right messages uh I so and since we're compiled to webassembly this function is probably going to be implemented in webassembly right so let's actually put it this way uh fonts Char message all right so this is going to be an external function so it's going to be as simple as that um so let me let me see if I can easily compile this entire thing so I'm going to build this stage uh and Bin sh set XE and let's compile that to wasm32 so this is going to be clang Target wasn't 32. output is going to be made that wasn't main.c do we need anything else in here uh I'm not really sure maybe maybe that is actually it maybe that is actually it so so I'm gonna do it like that and I'm gonna just actually do that oh yeah we I have to disable the standard Library so I'm going going to take the flags from my existing project right there right so jailbreak uh so no standard Library something something um so in here we basically do a separate compilation right so we first compile this thing and only then we're linking it okay we can do the same thing it wasn't LD M wasn't 32 We're not gonna have any entry point everything is going to be exported right and if something is not provided we're gonna I'll just allow that it's gonna be provided like from the outside and the output is going to be minor plasm because of that maybe this thing is not particularly needed but maybe I'm just going to call it o right so it's kind of weird that flying allows the object files but wasn't still called o which I mean probably makes sense I don't know and uh so what do we do in here we just do it like that so let me try to run this into everything and yeah there we go so I have a wasm file maybe on top of that I'm gonna instantly also convert that to what just for for the debug purposes right so this thing wasn't main.wot right so and if I try to to run this into anything I think as you can see it seems to be working and this is the assembly it didn't really generate that much assembly right so it's pretty it's very straightforward so I want to set up some uh you know website that basically loads it into into the browser so we can test all of that I'm going to copy paste that stuff from from the jailbreak right so this is going to jailbreak uh index where is my index HTML so I'm gonna take that and also gonna take that and I'm gonna copy paste all of that in here so let me see uh we don't really need a canvas right so we're only going to print to the standard output and what we're gonna do in here what we're gonna do in here I don't really remember if I actually showed that uh on the stream but they create a pretty cool function called make environment right so the thing about this wasm module is that it expects you to implement a lot of external functions right and the amount and the specific set of such function always changes depending on like maybe the compiler version and stuff like that so I created a function that creates a proxy that basically allows the module to use whatever function with whatever name it wants and if it's try to use the function that is not available when it tries to call to that function it will just print an error not implemented of given the argument so we can instantly see what function you can Implement right so that way you can say okay the environment is going to be make environment and here are my functions right if it tries to go to any call to any other functions it will actually call them but if it tries to call to non-existing function it will actually log that it's trying to use an existing function so we can implement it later in here right so you don't have to know what function the web assembly module wants up front right you don't have to know that you can just Implement them as the webassembly tries to call them it's more Dynamic and that way if the compiler changes something in its internal implementation and it requires different set of functions this code still works to some extent okay so in that case I'm not going to just like put anything in here right for now and uh let me let me see so we are fetching main that wasn't Ruffalo 38 thank you so much for uh the wishbone submission thank you thank you thank you really appreciate that okay so in here we are searching for a particular function right so the function we're searching for I suppose iterate messages okay uh iterate messages where is the load.gs um I wonder if like so this thing iterate messages oh yeah it doesn't require the uh the dollar right so here it requires the dollar but I suppose it's something uh very much web assembly specific so I don't really care so let me remove some of that stuff uh iterate messages and we're searching for iterate messages and let me simply call this function right it's frequencies okay so I think let me start the server let's python3 HTTP server uh 6969 and there we go so if I try to reverse this entire thing I cannot read the property get context of null okay so I still have all the code in here that is really not needed uh yeah there we go Okay cool so as you can see it tried to print a message and it was not implemented right so when it gave us three different pointers right which is rather interesting so they're not they're actually decreasing which is rather interesting right so they're actually decreasing so what we need to do we need to implement print message so let's quickly do that uh print message print message and here we accept message pointer right so this is a message pointer and we have to do something with that let's do message pointer and message PTR let me see yeah there we go so my Sprint so the thing we need to do we need to actually grab the um the message out of the memory right so what I want to do I need to have an access to the webassembly module so that means I need to have it somewhere here so this Mark is no and as soon as we load the webassembly module right I think I'm going to call w0 or something I'm going to reassign it to a global variable right so as soon as we load this it's part of the global variable and all the parts of the code can use that quite easily so what we want to do in here we want to take a look at uh instance instance exports and I think memory is located within the experts right so memory isn't here right so here is the memory and within the memory we have the buffer right so we have the buffer and as you can see here is the buffer uh maybe I'm going to save that buffer somewhere in here right so this is the bottom and what I'm gonna do I think I'm going to create uint8 array so it essentially creates a view on that specific buffer right and if I remember correctly you can specify sort of like a slice of borders for the buffer so I can say okay start the buffer from that specific pointer so this is where the messages start right so we can also provide this second uh argument in here which is either the size or the last point I don't remember I think I think I need to look it up right so it's actually Google that thank you [Music] so let me let me see let me see uh so what's the what's the other what's the other argument of u8 array uh it's length Okay so this is actually convenient right so you can provide the length but the problem is it's a C string in in a C string we don't know the length we have to calculate it right so essentially the C string is like ends with zero and that's how we know the at the end of it uh so and this is something that will help to calculate so let me actually put this stuff in here and let me run this entire stuff and see if we actually get some stuff okay as you can see we can clearly see some messages some messages in the memory we just cannot pinpoint their exact length right so because we need to calculate it so let's actually create a function that computes the length of uh of this thing so maybe it's gonna straight up accept the U in eight array because why function c as to order then and we're going to take the message right so the length initial is going to be zero and while message length is not equal to zero we're simply going to increment that thing right and then we're going to return the length so which is rather cool right because it allows us to do the following thing we can do something like message length where I just construct that and I take the length of that thing so then later I can construct another view with the length Okay that's a pretty cool way of doing that right so and we can take a look at the message itself right so here I can even save it like that so this is the actual message uh okay I could probably do it like this is it going to work yeah so here are the three messages right so this is actually three messages so the only thing we need to do we need to convert it to the text right so as far as I know there's a text decoder uh decoder it would be better to actually save it some way here uh text decoder uh text decoder text decoder right and let's go back uh text decoder I think it's just decode right so you just do message decode and that should be fine all right so I'm gonna put it like this and if I do that there we go about that how about that which will inspect that to happen so and this is literally the messages that we are trying to print from C right so essentially we got three pointers and we just extracted that step from from the points so uh we have a working example uh web assembly wasn't 32 examples specifically right so and one of the things I probably want to do I want to compile the same example to Wasim 64 right so that's another thing I want to do more than six to four so in here I want to kind of preserve this like 32 bits because I think it's kind of useful uh let's actually do the following thing I'm gonna compile it to main32 right so this is the main 32 and this is the main 32 main 32 and this is the main 32 right and essentially I'm going to copy paste this entire stuff and just replace 32 with 64. boom okay that's cool so in here I'm going to mark all of these things and I probably go ah I'm gonna remove them right so we'll remove them and I'm running build sh one more time and okay so maybe for that thing I'll have to implement enable memory 64 right and there we go so we have two sort of variants like a 32-bit variant and 64-bit variant right and here we can actually switch between them I suppose right so this is 32. it works 64. um doesn't work so in browser specifically doesn't work okay so what I want to do I want to just take this thing and try to patch this thing manually and see if that entire idea that we have even works right so I'm gonna copy paste that to main six to four two usually you know usually people do like what to wasn't they say two um like a two like a number right but in this case it's just like it's already a number so 64 to 32. no I know that I think it's a pretty cool name 64-32 right so the maybe this is going to be the name of the conversion tool right so this is going to be uh so the tool that converts 64-bit was into 32 1 is going to be called wasn't 64 to 32. what's funny is that it's five numbers but they're really easy to remember right you convert in 64 to 2 to 2 to 32 right so it's that's that's the name of the tool yeah 64 to 32 yeah so let's call it like this I think I think I like that I think it's pretty cool uh so let me now go and replace this thing in here since this thing is so small it's like 123 lines of code uh it is super easy to just hack it manually right so we'll give it a try I'm gonna do uh wasm to what uh actually what to awesome right so what two wasn't main 64 to 32 and let's see what we have right so this is essentially what we do right so it accepts uh i32 but we got a 64 so here as you can see this parameter is probably 64 but I don't remember how to convert the um 64 bit to 32. I don't remember how to do that wasn't convert integer instruction [Music] okay um conversion so not equals arithmetic conversion okay so convert I64 to 32 this is precise what we want how do I do that show me an example uh i32 rub I64 okay uh let me let me see so let me go back in here so if I put i32 RUP I-64 is it going to work I think it worked so this is load in case of a load we just have to do it like that i32 wrap I64 maybe I'm going to actually put it in the clipboard uh all right and just do it like that so this is yet another load uh huh get another load this is yet another load uh-huh so those are actually easy so I'm just thinking how we're going to be implementing that so what should we need what we need to do we just need to find the loads and right before the loads put this single instruction so with the stores it is a little bit more complicated right with the stores it's a bit more complicated because so let me let me actually recommend it out uh let's support the comments so I can oh yeah so how do you how do you comment uh let me remove that okay so with the Stars it's a little bit complicated because the pointer that we have to convert is the first argument so there is an argument in front of it so that means we need to be able to swap the elements somehow then convert them right so then convert them and then Swap this thing back but as far as I know the webassembly does not support the swap operation so what we'll have to do we'll have to find where the first argument actually starts and it could be like a complicated expression and as far as I know these both of these two values may be returned by a single expression in case of the multi-valued return right because the functions in webassembly uh can can return several values and I think it's an extension but I don't think it's a unstable extension I think it's a pretty stable extent extension by that point so like finding where to put that conversion thing for the store is actually not that trivial right so we'll have to think how to do that spring so it is not particularly trivial okay the same story in here right so it's just i32 uh rub I64 and we have data so if I remember correctly data accepts a pointer within the memory where to place that chunk of data right so it essentially you allocate data in here and then you say okay but starting from here just hard code this data into the memory just just place it there and since it refers to the memory it also refers by either 32-bit pointer or 64 since it's a wasn't 64 it puts 64 in here so it's suppose what we need to do here is just replace this with that right and compiled them right and now we have a thing right wasn't what's interesting is that it's a bit is it bigger than 32 it's actually smaller this is weird so it is smaller than actual wasn't 32 right so if you want to save on memory compile this thing to 64 beat and then convert it to 32. I I wonder why the is this like that but but anyway so let's actually do this thing 64-32 and let me see if it works oh this is actually very cool can I convert the big hint Okay so 34. here is an interesting thing I think this is a reason why memory 64 right wasn't 64 is an experimental feature right 64-bit integers are not representable by JavaScript numbers they're not right because as far as I know JavaScript numbers are floating points right so they're actually using nand boxing to uh uh you know to implement like different types of object to distinguish between them dynamically which means that they have 48 bits for an integer to represent so anything bigger than that is considered an unsafe number right and to circumvent that they came up with a thing called Big int which is actually long arithmetics so and that creates a friction on a border between JavaScript and webassembly because webassembly supports 64 bits easily but JavaScript doesn't so every time webassembly returns 64-bit integer it is actually interpreted as big hint including pointers so now whatever point is we receive in here their big end pointers so I suppose the reason why this extension is still unstable is because of that friction between JavaScript and webassembly on on the on the border of 64-bit integers uh we're leaving in 2022 by the way this is a year 2022 we can't migrate to 64 bits till because of some stupid toy scripting language thank you very much anyway so uh we know that it's not gonna it's it's not bigger than 48 bits right we know that it's not so the thing we can do we can straight up just convert this big into a number right so we can just treat it as a number uh there we go written in a week by one person in all fairness In fairness like modern JavaScript is actually you know it's more than one week of work uh uh all right so let me let me see okay and it works this is actually SAS right we got an executable that that is smaller than the native 32-bit executable and it works somehow so but the answer is yes so this approach actually works so essentially to take 64-bit program and it wasn't programmed and convert to set you two you have to change the memory I suppose also change the data if you have any data go through all of the reads and writes or loads and stores and convert the pointer that accept they accept to 32 bits like basically like wrap it around right uh but here's the problem like store instructions actually button right so the store instructions actually bottom because as you can see okay we can probably create a function that accepts I64 and i32 right and that way we can basically access the the previous argument regardless of how it was calculated again so this argument can be calculated like in many ways right it could be an expression so I cannot just take the previous instruction because the argument might be computed some way here but through the stack operations it just like remains here right so this is a huge problem right if it was in front of the store that would have been way easier because I could have just like insert the converter instruction and that is it but now I have to find the previous argument and the distance between the store instruction in the previous argument can be huge right it could be like 10 instruction can be 20 instruction I don't know right it depends on how the compatible decides to generate the ship so what I'm thinking is that we can create we can do a function call right just call to I don't know um store convert store wrap right and this function accepts I-64 and i32 and then within that function we already just like take the previous argument quite easily because everything is collapsed so to speak and then return everything but the problem is here we have to generate such function for each type of a value right if the store accepts 64-bit value if it wants to store 64-bit value into the memory we'll have to have a separate function for that so we have to do store um I don't know i32 store I64 store I8 and what not maybe F 32 f64 we have to generate like this kind of function for each of this value and I don't think it's a problem right because we're going to be doing that automatically right um we're gonna do that automatically we can just write the code that injects all of the that generates all of the functions and injects them into the wasm so we can call them right I don't think it's that big of a problem you know what I mean uh so let's actually give it a try let's see if we can create such function um so let's create funk [Music] oh yeah I remember that so you actually have to in like in wasn't binary format you have to first declare the type of the function and only then you can use that type in the function even though the text format allows you to provide the signature in here I think in the binary format it still expected to be here but I don't quite remember for sure so I might be wrong with that don't quote me with that right so let's actually create a type uh right so this is going to be top type number two and this is going to be a function that accepts the two parameters 64-bit pointer and 32 uh bit value all right and I suppose it returns uh both 32 right so let's carry the function which is store wrap 32 maybe I set it so right so and the title of this thing is going to be termed so in here um I don't remember so let's actually try to compile this sentence I can see how it's going to complain so expected i32 if I remember correctly the parameters are considered the local value so we can do something like local get zero right I don't even have to do it like that uh yeah it does work so in local get one there we go and I can put I3 to wrap I64 in here there we go so yeah essentially we just need to uh yeah we just need to create such function for each and individual value type that we want to store right and every time we store something all right we can just call to this function in here and it works and in here it works as well so we can do something like that right so but again we'll have to generate that for all of the types right we'll have to generate that for I64 for F32 and so on and so forth right but since we're going to be doing that programmatically it's not a problem uh so it is not a problem whatsoever okay so this is basically the plan so this is mechanically what we need to do right so this is a very small executable but we need to do that on a bigger scale on a way bigger scale so the question is how we're going to be doing all that right how we're going to be doing all of that uh well we could write wasn't pass ourselves we can do that on a level of the text but use like doing that on the level of the text is not really robust I would like to actually parse webassembly like properly analyze it and modify it patch it and then save it back right so we can try to do that from scratch which is kind of tedious but we can take an already existing code that can parse and generate wasn't right and in fact we've been using such code since the start of the Stream the we have two utilities wasn't two what and what two wasn't first one is capable of parsing binary wasn't and the second one is capable of generating binary wasn't so why can't we take the source code of these two things and just hack it and Implement utility and new utility that does whatever we try to do in here you know what I mean so both of these utilities they come from a tool set or a tool set called wabbit so it's a the webassembly binary toolkit and it's written in C plus plus so uh my idea is to basically take these two tools and create a new one a combined one that reads the you know webassembly binary patches it and saves it back basically converting 64-bit wasn't to 32. so yeah we can finally we can finally start the main topic of today's stream like I spent one hour uh explaining the justification of what I'm about to do uh all right so yeah let's actually download the source code of this entire thing and uh let's try to hack it so I'm gonna do that like I did I literally just did one hour intro this is one hour intern okay uh let me go somewhere here do I already have a one bit okay so we don't have about it uh I'm pretty sure I'll have to do a recursive like every time I'm cloning one of those goddamn projects I have to do recursive do I have to do recursive yeah I have to do recursive because all of them use uh sub modules your purse uh okay yeah all right [Music] okay so I hope it's not going to take too much hmm Google tests test Suites wasm C API um was he was he uh all right so it uses c-make so let's actually try to build usually with cmake uh you have to do build right and then cmake dot dot let's see if we can build that okay and uh go apply names dot CC binaries.cc binary reader maybe this is something that will binary reader IR intermediate representation very interesting so we're getting very interesting things so maybe a while it is compiling I don't know for how long it's going to go um but I really want to make a small break and maybe make a cup of tea and after after the break we're gonna try to hack this thing and see how it goes all right all right so we finally uh build it so let's give it a try let's see what we can do we have any of this okay so here are the executables right so what wasm what was them and wasn't to what here they are and I wonder like where do they even start right so maybe they have like um you know the um you know the entry point somewhere maybe the file that contains the entry point is literally called wasn't uh to watch so I think this is how we do that it wasn't too uh what apparently it is not uh so but maybe I'm actually don't know okay find type file name wasm maybe yeah wasn't to what and let's do something like this just in case it has any prefixes oh okay oh there is even like a folder for for tools is is that the things we have okay so this is the folders where there are entry points for all of the tools in here right so welcome to what uh wasn't would you dump what was them and stuff like that and I suppose they just share this code right so there's um what writer which is kind of useful right so is there the here is the binary reader so we can do this kind of stuff so that's pretty cool okay so I'm curious about like the first thing I want to do I want to be able to read the the binary format right so that's the first thing so because of that I'm interested in how wasn't what works right so here it is uh let me find the entry point okay so entry point there is some stuff in here what to try um I wonder what the is this um Define uh okay so it's it's for exceptions with exceptions so there is a parameter that allows you to enable exceptions and in that case there is a global try catch that catches everything well not everything but it catches the bad airlock uh what a useful macro okay we're off to a good start uh so I already like that um okay so we're initializing stgio I have no idea what the this is uh okay and it's only for msvc and on msvc is just like does something with stdio so much useful code so far I really like that okay so okay here we read the file right read the provided file so parse options parse options actually rather interesting so they have their own option passer which we're probably going to use so and it's based on lambdas would you look at that so you provide the name of the parameter the description and the Lambda that is going to be triggered when you encounter such things so you can set up your Global variables and whatnot so that's pretty cool uh oh right all right all right so in amazing Georgia thank you so much for which Prime thank you thank you thank you Ruffalo 32 38 thank you so much everything a the Euro tour if I didn't mention anyone at like someone um and yeah someone please please forgive me so um okay so here we have some parameters and yeah this is actually pretty straightforce all right so now we read the file and if we succeed we set up read binary options like there's quite a few options in here and then we read binary IR right we read binary IR uh where do we read that where do we read that I'm not really sure uh I guess we're reading that into modules so and what is a module class module is that a class oh yeah okay so the problem with C plus plus by the way is that you have a type and you don't even know what it is is that a class is that a structure which is literally pretty much the same thing except you know visibility stuff or is that enumeration uh I don't really know so the decision of actually making the definitions of the type and just start like literally the same the name and then colon colon is actually quite genius because you can find that type regardless of what it is whether it's a structure enumeration or anything they all start with the name colon colon right so and then only the structure in um or something else right so this is actually quite convenient in case of like C and C plus plus it's not particularly convenient right because different kinds of types are declared slightly differently um so and uh I support this module so class class module uh class module and I'm not sure if that's the module uh is that a structure so okay there is a struct module and it's conveniently located in intermediate representation file I suppose I really like that so this is a structure so I have an access to all of this right so I haven't so there is a function read binary IR which just gives you a bunch of vectors which are tags functions globals inputs memory right so we we just have to call that we just have to look into the memories and just set something there and I'm pretty sure memory contains like the type that it can be indexed by you know what I mean so class memory uh okay so that means it's a structure memory there we go and it has a name Memory can have a name and it has something called limits page limits so maybe the type is located in those limits right class limits or struct limits and it's defined in a different file it's a the princess in is another Castle right uh so class limits uh structure limits there we go it's it's located in common.h so there's a bunch of Constructors here and uh is 64 right so you just like put a Boolean in here so it's not even a type it's literally a Boolean that controls whether the memory is 64 bits or 32 bits okay I'm back so it's pretty cool I really like this C plus plus this is like a uh C plus plus zero three good old C plus plus zero three uh uh is that like an immigration class I think it is immigration class um anyway so yeah we just need to read this I think uh and then like patch it and we're good to go I think so uh what we're gonna do I really want to create like a separate new tool right so like create another file in here uh so let's actually create something like wasn't 64 to 32 cc and uh I didn't even know what I'm gonna do here so it's a higher stream uh main uh we definitely need so the problem here is that CC does not in like set up my simple C mode so maybe I'll have to do something about that but maybe later so character something like this and uh let's do the following thing STD C out uh hello world hello world STD candle and I suppose we'll have to modify C make list txt so wasn't let's actually find ad executable right so I remember cmake a little bit right so I did a lot of C plus plus commercially and I of course used cmake so I do remember that to declare and executively how to use add executable direct if I do remember that uh okay so I suppose there are some functions that okay it's a wabbit executable so the the talk the um the boilerplate of defining executable entity and the function wallet executable so let's take a look at this function and okay so there you go so here are all of the build Tools in here so that means I can literally just copy paste this code right just call this wasm 64-32 there we go 64-32 and let's see if I can rebuild this into anything I think all right all right all right you know what's cool about uh cmake is that the empty bill that doesn't do anything takes uh one and a half of a second on my machine this build literally doesn't do anything the only thing it does it checks whether it's already built the thing that it needs to build and then it moves on to another thing so and that takes 1.3 seconds a very cool build system I'm I'm really happy okay so do I have wasn't 64 there you go so I have a wasm 64-32 it's not cool Isn't that cool I think it's pretty cool all right still faster than Rusty I agree with him um okay so I have a two new lines in here by the way so this is the first new line this is the second new line when you don't have enough new lines by the way hello hello hmm okay so I usually when I'm going to someone else code base I'm trying to mimic whatever they're doing right so I suppose I I have to do that I'm not really happy about this thing but since this is not my code base right so this is how I supposed to do that and it's supposed to have the program main right it needs to be separated and there should be a global you know switch case or something like that sure I'm totally fine with that and uh I suppose we need to initialize the stdio just in case somebody will try to compile that with msvc and we also need to parse the options right we need to parse the options I'm not really sure what kind of options I care about uh but yeah maybe I'm gonna accept the file path the input file path because why not uh right so and I'm gonna X I'm gonna do option parser so in here we do wasm64-32 and we here we have a description all right and description is this uh static thing again right so this static thinking and this is a lot right so read a file in the webassembly binary format okay convert [Music] um was m64 to wasn't 32 by tricking tricking loads and stores into hmm by let's let's not say tricking by converting uh all pointers for loads and stores all pointers accordingly follow the Stars this doesn't explain anything actually this is the worst description I've ever written but I cannot come up with a bad description and I'm really sorry so once I'm 64-32 uh okay let's actually say test 32 oh uh actually 64. 32 wasn't so that means we'll have to support at least such flag which is okay which is fine uh no like again you don't even have to know how to program as you can see you can just copy paste the code right just copy paste the code and that's gonna be fine so we have a verbose flag I'm not really sure if I care about that right now so the output flag the output flag seems to be rather convenient so maybe this is something that I'm gonna add in here all right so I don't even understand what the I'm doing and my my formatting tool is broken is it because of this is that because of this fancy string thingy right so this is a roll string from C plus plus 69 for 20. I don't remember when like what kind of features the latest C plus plus introduce but I think that's that's actually the reason okay it is okay this thing breaks my formatter for matter how do you pronounce that I didn't speak English I'm sorry I'm really sorry for my pronunciation because I don't speak this language like at all uh I had to learn this language anyway so like who needs this fancy Rose drinks roll Gadget strings you know what I'm talking about when you have just like a good old like multi-line strings you can do like that and it works it worked 20 years ago it works today why kids these days always need to invent new useless speeches when the old ones still work you know what I mean like I mean we can do like that anyway um so and it works let's go back it wasn't to what so what else do we need in here that's a good question so for the experts I don't know what the hell is that uh file name oh okay so look look they have separation for options and for the arguments and this is something that we need here as well right so we also need the the input file input file argument and then we're gonna we have to say parse this uh okay so let's see if this entire stuff compiles right so it probably doesn't as usual ah welcome to C plus plus okay option part oh you we we have to import some stuff of course wasn't to what uh so what do we have to import here I'm gonna import everything right I don't really know what is needed in here so I'm gonna just like literally import everything who cares um okay welcome to C plus plus cool option passer is that because oh wait wait a second why ah sure of course almost worked okay so there's no such thing as as out file so s out oh okay so they're basically like a couple of global variables that we can simply copy paste on that you see programming is easy you just copy paste since super easy um yeah people like study programming for like three or six years um you know in universities and stuff like that it's it's easy you just take the text and you copy paste text so there is no return statement in here so we'll probably have to return the stage and uh yes we used to use okay why are you freaking this one okay so we can actually do something in here so inputs right and we can provide the input as in file and if I remember correctly we're also going to have the output output out file there we go so let me see so if I try to run volume 64-32 expected file name argument right so we provide this thing input but output is not provided how do you provide the default value for this thing right so the output was never specified unless I do something like this right so but if I have a default stuff how do I set the default stuff uh s out file oh okay wait a second so it's done at run time right it is done at runtime I think they're not different time or maybe at runtime yeah so you convert the backslash to slash or something or something no it's not that how it is oh okay so I brain farted a little bit so if it's not empty all right so where um oh I see so we just okay so it outputs the file write it outputs to file but if no output file is provided it just prints it prints it to standard output so this is basically how how is that okay sure okay that's fine uh cool so we copy pasted a bunch of things so let's actually start reading the the thing let's actually start reading um what do we need to do in here we need to allocate the vector right so we interlocate the vector for the data right so we're reading that into a vector of bytes right it's the vector uint 8 and this is a file data right then we read file I have no idea what it does but it apparently judging by the name I think it it reads the file so as in file C Str and then file data right it Returns the result and the result is this thing okay result results and it succeeds but can we do an opposite like not succeed is there something like failed because I want to do an opposite thing uh Define is that defined or is that maybe it's actually Boolean it should return yeah okay it Returns the Boolean and okay so there is a failed and it's actually as easy as just like comparing it to okay or error why do I need that anyway um okay so if failed I want to just like print something you know what I mean um error could not read file and we can provide the the file that we couldn't read foreign and then I can return with on zero exit code right so then it will return in here and return everything so yeah so after that we can print something for instance a red file data size if I remember correctly in stld the size of the vector is size bytes right and here we might as well put something like this so red this amount of bytes okay so let's actually copy paste the the tool the the another tool but the the executable that we're going to be converting you know what I mean uh right so I'm going to do probe test wasn't 64-32 idea let's take uh this thing right and like literally copy paste it in here so main um main 64 right so main 64 wasn't okay and we we need to recompile it first of course right so it's our compound first foreign [Music] [Music] should have actually like didn't should have not recompiled it and just followed all the errors but whatever um okay so we're at 724 bytes is that true it's 724 bytes we managed to write seven uh read 724 bytes so what's gonna be the next thing uh as some three thank you so much for 500 beats thank you thank you thank you I really appreciate that okay um after we're read everything we need to basically create binary options um so we need errors modules and stuff like that okay so let me just copy paste this thing right so because apparently this is the main important thing right you construct an options and then you just provide options in here everything else is just like Global parameters that controlled by the flags if I understand correctly so let me try to compile this thing and this C if it's gonna work right s features s features is what let me see s features so this is a global think right so this is a group oh this is a very interesting so add options I want to I want to take a look at that add options as features and options um foreign do we have oh we even have just features in here add options it accepts the pasta so it probably sort of like enriches the pass with additional flags that enable or disable uh features of X macros oh this is actually pretty cool oh yeah okay that's pretty cool so there is a centralized place where you have all of the features and they are using X macros to generate like additional code to uh set features to enable disable and stuff like that do you guys know what is the X macros in CC plus X macros right it's sort of like a pattern pattern right that allows you to do this kind of stuff uh right so you have a list of variables that call to macro X right but the they don't Define X they just go to that X and this is basically means that whatever is going to be substituted by X dependent on the context right it's dependent on the context so first thing you do you define that X you define the context then you expand this list this list will use this additional macros and then you undefine that right and that way depending on the context you can change to what this macro is expanded right and this is a good example for instance I have a list of features right so here is the list of features then I want to generate a class that for each feature um creates four methods and that's exactly what they Define in the context so this is actually pretty cool like I haven't seen the X macros in a while for quite some time so this is very convenient um so I've seen them a lot a lot of times but did you know they're called X macros yeah they're called X macros it's completely arbitrary names the name which makes it actually kind of bad right because like there's no reason why it is called X so it's kind of difficult to remember in my opinion right but I don't know if there is a better name for this kind of like pattern but yeah [Music] seven so you don't need this kind of stuff in jail for instance because in Jai you can literally just generate the code you can inject in the compiler event Loop and just on specific events just literally add new code at compile time like you can you don't have to use it you don't need any of this mm-hmm all right so and in case of jai you would probably just have a structure that defines all of the features and you would generate additional code around that structure right so at compile time you would just find the structure definition and iterate through all the fields and for each field you will just generate additional code like whatever the code you need right so you wouldn't have to do any of this stuff uh so yeah let me let me see [Music] um it's exactly how John is Implement itself yeah I've seen that stream all right so all right so what I was talking about so features is just like but do I really want to enable features uh through Flags I don't really want to do that because there's specific features that I want to always enable right so features features I wanna always enable so how how do you do that features I want to always enable memory 64. I wonder if I can do that feature death memory 64. okay so there we go uh so wasn't 64 enabled uh memory 64. right so I always want to just like do that um I don't really care about everything else so s log stream so there's there's too much bureaucracy why there's so much bureaucracy in here I hate it thank you we just thank you so much for tier one uh so yeah 222 wasn't to what and where is that stuff okay so on top of that I also need errors and module and this is where we're going to be reading all of that uh stop on the first error sure I can enable that as well uh what else do we need in here so I have to go through the compilation errors and stuff okay so s log so it's that thing and okay huh we can enable that why not I didn't see anything wrong with that I I suppose eventually I'm gonna copy paste the whole thing so and this is the purpose right is the verbose and for the verbose we also have S verbose in here uh-huh and do we need anything else okay so as read debug names so is it always true okay let's read the Box names you know what I think I'm gonna just like put this things as Global stuff but I'm not gonna bother hooking them up to anything all right does it hook up yes red yeah they're hooked up and we're going to hook them up into the flags because they're going to be couldn't be bothered couldn't be couldn't couldn't be bothered okay so generate names uh so this this one is not used then okay I suppose we did it right if a result failed uh failed result STD out error could not um bars binary to Binary data from file s in file new line I mean exit actually not exit but return one and after that we may want to try to print whatever we read right so it's actually go to here tracked module right where is the module and let's get all of these things yeah okay some Mojo um size out okay wasm64 and we're gonna provide Main 64.1 does it look like a truth we have three functions is that true why do we have three of them because I remember I defined one um iterate maybe another one is an import we can always do the following thing we can do wasn't wasn't too what and we have to enable the memory 64. memory 64. and what kind of functions do we have so wasn't called Constructors I have no idea what it is but maybe that's the third one so here's the constructors here iterate messages and I suppose another one is the import okay so that's why we have three of them so yeah we managed to parse the binary data how about it isn't it cool so let me pause the binary data ciao we just parse the web assembly behind the date we were called to the other code right so the code we didn't write but okay that's what I'm looking for people don't pogging like nothing happened um sometimes I'm starting to feel like I'm gonna invent like a cure for cancer in the Stream and nobody's gonna notice anything you're missing the content chat what the you're missing the sweet juicy content all right so what we need to do in here we need to iterate through all of the functions first of all first of all we need to set the memory to to 32. no we need to validate assembly I think I think read binary doesn't really validate it right so if I go to wasn't 2 do we have a validate assembly now we do have it's even called validating here as well okay so all right validated assembly validate is just like even we provide the the features as well in here okay I'm pretty sure I can just like do it like that I have no idea what this generate names do we really need to generate names I don't think we need the general names that all right so uh let me let me put it in here so this is validates this is the features and we're validating this step and if failed result write a fail result mm-hmm um okay validation failed okay and we can put nothing in here I don't know can I get the exact precise error message in here uh right now what I'm gonna do I'm gonna just build first and then run this entiretek [Music] so features conflicting declaration ah okay can you just call this oh man this sucks I probably can do something like this and then we can do something like there we go more than 64. okay so everything is okay it seems to be it seems to be that everything is okay uh cool no you know what like I don't really have to do it like that can I just like inline this so I don't have to have this ugly look I'm pretty sure I can I can have like that yeah there we go because it's like ah civil Sports developers I swear to God anyway so what I want to do I want to find the memory all right so the problem here is that you can have several memories you have to have several memories but the good good news are that multiple memories multi memories is an extension and not multi-membrane it's an extension right it's an extension uh that is set to false though right okay we're gonna do the following thing I'm going to do the following thing I'm gonna explicitly explicitly disable multi-membering right so I don't really want to support multiple memories right now it's an extension so nobody cares so we're not going to have multiple memory I suppose this uh class means like you can pass this class to places where appropriate and if something is trying to use the feature that is disabled is going to throw an error right for example I suppose the validation is not going to allow multiple memories if the features are disabled or something like that so this is actually a pretty cool way of doing that I really like that hmm purple code number one okay so validate Mojo so I suppose you may not have a memory declaration at all so we're gonna do the following thing if module is it called Memories it's called Memories size is greater than zero we're going to do module memories zero and I'm going to go into struct memories memory I'll have to take the page limits right taking the page needs and then if I remember it's located in common okay is 64 false there we go you know what why do we even care why can't I just do the following thing for auto memory module memories um memory page limits is 64 volts and it doesn't really matter if it's like supports multiple memories it doesn't support it's just gonna work anyway like why can't we just do that so okay and now that should break the executable so if we try to validate this thing second time uh right it should fail because we're gonna have a lot of loads and stores that operate with 64-bit integers but memories are indexed only with 32 because we we said so right so let's actually check if it's gonna you know throw them all right let me see okay so it doesn't even compile um so I suppose this is because of that right so it's a pointer out of the referencing in 2022 where where is out of the referencing second connotation failed uh I wonder if I can make this thing to print this stuff to standard error do you know what I mean so validation validation hmm how do you print the errors though so let me see [Music] so they don't print anything oh is that how we do that I think this is how we do that so we pass yeah this is actually quite cool so we have errors we pass them everywhere so they're basically accumulated and then once we're done right once we're done we sort of like printing them to file uh but which file that's a good question um so let me see Oh by default it's a standard error okay so that makes sense sure I'm fine with that um okay we can put this stuff like everywhere like every time there is an error we just do maybe I didn't even have to well it would be nice to know like what stage it failed on right so I think that's that's useful I think it is in fact useful okay so let's try to recompile that um okay okay look at that look at that so this is precisely what I was talking about right loads and stores and loads and stores and um but on top of that we can try to find all of the worlds right we can try to find those and everything okay so but to do that we need to iterate through all of the functions okay so Auto Funk uh so let's actually not do the second validation for now all right so it's going to be zero and we're gonna just exit with this thing Funk module uh struct module uh-huh where is the function so it's a funks so this is Funks and what do we have in funks funk so what's interesting we have we have a name for instance we have declaration local types bindings expressions expression list okay so I think expressionist is the thing that we care about but for now I want to focus on namesake can we extract the names of all functions right something like STD out um Funk name and just tested your handle right let's see [Music] okay there here are the functions so print message wasn't call Constructor situate messages and so on and so forth right so we got the message it's cool the next thing we need to do we need to probably iterate through their bodies I presume the bodies are located in expressions and which is an expression list okay so let's find what is next okay intrusive list intrusive list is that a c plus blasting embedded template Library is that a like a homemade holy it is a homemade thing they implemented as a STL container okay this uses a similar interface as STD list but is missing the following features uh ad extract functions that remove an element from a list return only supports move only operations no allocator support no initializer is very intrusive list asserts instead of exceptions some why why I'm not gonna question that but yeah anyway so um okay expressionist is an intrusive list of expressions and what is an expression expression is a class all right which is which inherits intrusive list base uh so where this thing is located what is intrusive was based is located in here and it's a friend with intrusive list which means um intrusive list can modify its private things and it has next and previews oh it's literally a linked list and intrusive list base is the node for this thing and expression is a node for Linked list it is not copyable or anything okay so that's that's fine uh we have different types of expressions and that is about it which means that this class is supposed to be a base for other okay okay so there is a oh all right there is a hierarchy of different Expressions oh oh we we're okay we're going that route then okay I haven't seen this style for quite some time already oh my God I'm I'm having a PTSD right now holy um I I thought I'm gonna never gonna see this style of software development ever again in my entire life but here it is again okay uh I mean it's not that bad okay yeah uh it's just like it's a hierarchy it's a hierarchy nothing particularly special everything's fine um okay what kind of Expressions do we have there I'm actually curious uh expression mixing memory binary oh this is actually pretty cool ref type op code CMD look at that select expression so that's pretty cool if expression look at that so it has two branches right true and false and this one is a block another one is expressionist what's the difference between block and expressions extract block uh and it also has expressionist okay so this is basically a tree with linked list where each node could be either an element or linked list essentially [Music] um so okay which makes sense right so because we need to represent this thing so let me just do this stuff I probably have to go to build right so we need to represent this kind of thing right this kind of thing how can you represent that you basically have a linked list which is a node in a tree right so each thing is a separate node and then we have a block right which itself spawns another linked list and yes so that's how we represent the city I think the vision is like on which instructions we can branch instructions we can branch so that's a good question [Music] so let's create a function patch Funk and here we're going to accept the function that we need to patch right so I might as well even do something like unimplemented right patch funk [Music] and then we'll do patch Funk funk if I remember correctly it's just a pointer so here I could have just done it like that [Music] um so where is the class um is it classic is it distract and remember all of them are Pointers so that means it's safe to just iterate it like that [Music] so my only concern is that like we can just iterate through the Expressions right I can always just do something like this four uh alt expression um Funk experts all right so and what kind of expressions are we looking for right class expert right so we have to do expression type okay so expert type and expert type is what okay so here our Express like different types Atomic load do I have to handle Atomic load I don't know we'll see so there is just a load uh load Splat load zero so I'm not sure so there's also a store sure these things are important for us I think I'm gonna only care about store and load for now so here I can just switch so case expression type store um implemented patch store and in here we're going to have a separate thing which is a patch load and default we're gonna just basically do this entire thing right so this is very cool but uh what if I have if right so there is if something like maybe block right so block okay so there is a block expression base or something like that um impression type look so how do we do that expression type block okay if there is a case of expression type block right so I'm just looking for like the ways how people handle that right so here's expression we they take a look at the type and if there is a block uh okay so they do something with that oh there is a special function that can cast the expressions where is it okay there is a cast.h oh okay so this is gonna be so there's a function special function that allows you to cast these expression hierarchies and stuff like that so oh my God I'm I'm starting to think maybe I should have actually written like a shell script that you know just patches the text representation but I mean it adds a lot of moving parts right so in some particular first platform so much useless code anyway I'm just fine uh okay so this is a block expression so what is a block expression [Music] let me let me find that in IR block expression so there's a block oh okay so block expression is a Alias for Block expression base which is parameterized by a template okay so there are two oh okay okay so it's just like for the code three usage right and essentially what I have to do right essentially what I have to do I think is when I encounter something like case expression type uh block for instance right I have to do something recursive to do something recursive you know what I mean you know what I mean just do something recursive um so that means we need to have something like patch expert list right so expert list is that a pointer by the way expert at least no it is not so I have to do it like that expert person all right and I probably want to move this entire stuff in here right so this is just that and then I do a patch X for list all right expert list uh Funk experts and I can say that this thing is implemented anyway so that means when I encounter a block what I have to do I have to cast cast this thing to block expert expert all right and then take um block expert base block struct block okay block experts patch expertise oh okay cool something like that but the question is like how many of those things I have right I have to do that on block um I had to do that on Loop like how many of those do I have that's the real question um so I suppose we can see how um how this usually iterated right so if I take a look at wasm wasn't to what right so at the end of all of the transformation what do we do is we write what so there is a function that takes a module and writes the module into the file so let's actually find the function write what uh write what write what where is it located okay it's located somewhere in here and let's see how it is done so there's a what writer of course there is a special class that does that for you so it's a module context okay so what do we call in here write module right Mojo So what we're doing here so with your iterate through the module field okay so right funk I think right Funk is something interesting so what are we doing here um right bindings param begin funk so where do we do right folded expressionist get expression type get expression everything push expression the flush the are you doing expression tree stack okay I see what they're trying to do yeah so because you have to pretty printer you know what I'm not sure if it's a good idea I want to take a look at the wasm what to wasn't right so because this is a very complicated so we have to Traverse that in a very specific way to achieve a specific result because it's a text representation so it's not going to be straightforward recursive traversal so I didn't think it's a good idea to look in here so we need to do instead is uh what towards them all right so and how do we do that right buffer right binary module I think so here we accept the module and that's basically it so let me let me try to find that emacs shut the happy mix okay so what do we have in here okay so binary of course this is a binary writer um so and we have a right module right so how do we do right mode um so I'm looking for a function so when we do function experts oh man okay right expertise so this so this is probably what I care about because that is kind of resembles what I'm trying to do okay so this is actually literally what I'm doing this is literally what I'm doing okay so there's a block yes that's probably what I need uh there is if Loop okay so I I feel like I have to go through this interaction oh there is also try oh boy um yeah we have to we'll have to do something about that okay so I'm already streaming for two hours goddamn so uh let's make a small break I need to make a cup of tea and after I make a cup of tea we're going to continue doing this thing so I just need to you know go through all of the expression types and just find the ones that look like a block and iterate just just do recursive column then that's it I don't really need to do anything else to be fair right so yeah I think the easiest way would be to just like do that mainly I suppose right so type expert huh expert type yeah there we go so just like go through all of the 6 60 almost 69 almost 69 things and look for the one that looks like a block all right so something like if Loop um try for instance I'm pretty sure it's a block throw hmm yeah all right let's break all right so let's continue uh what I need to do what I need to do so handling loads is probably the easiest thing to do right so if we encounter load we just have to put the conversion instruction right in front of this thing so the question is can intrusive list does the intrusive list allow to insert things it does very cool so I presume there's no documentation on how this thing works insert right where does it insert things exactly I don't want to understand this thing so I suppose if the interface is similar to STD list right so that means the STDs documentation should be useful for this specific container um just a second all right so hopefully you can hear me relatively well okay uh so insert insert insert insert okay where is an insert insert the element a specified location insert the value before position this is actually perfect is it oh it also accepts the nodes as a unique point that is rather interesting can I just look for inserts how do you use them um well [Music] oh okay so this is a test for intrusive list um so they have a make unique thing to make unique function which has a dedicated file called make unique.h okay this is named make unique instead of make unique because make unique has the potential of conflicting with STD make unique ah they spend so much time documenting this I'm relocating the whole file it's like a the law of triviality right so it's a disproportional attention to a very trivial thing okay cool um so I'm sorry it's just it's pretty funny there is like a huge problem in software development where people really allocate you like really disproportional attention to very trivial things right and like like actual substantial things usually don't have enough attention right like why did you spend writing like like really I I don't know so anyway sorry um so we're inserting by an iterator so that means we have to it like iterate this into anything by incerators so we have to be something like eater uh experts begin if I remember correctly right so this is my C plus zero three reflexes uh all right I can't even call it yeah boy it not equal x first and oh man I feel like I'm in high school yes again this is the I've been writing in high school what the this brings back so much so many memories like nobody writes plus like that anymore you guys remember do we have any Boomers who remember how to write such code and what this means hmm all right anyway so in here we'll probably have to do something like this uh let's actually try to compile this and test it Boomer exactly so let's see welcome to C plus plus so experts so since this is a pointer we have to do it like that uh the next error thank you very much the next error um as a request for a member and which of the point um what I could not converge store to type error oh okay so there was there was an error here somewhere or would even uh an implements it wasn't in store from expression type to type error so something some error has happened there and this is so weird and it doesn't really tell me exactly what the is going on but okay sure uh is that because I have to do I feel like I have to do something like this man I'm I feel really really bad so the expression is let me let me let me actually go to this entire thing expression list is a bunch of Expressions right in an expression class we have a type an expression type does it have a store does have a store so it should just work it should just work so but the wow I didn't see any problems I don't understand is that because of the unimplemented because I just don't have it anywhere I can I can define it message you could have just explained to me a little bit like more you know properly what do you mean that would be actually kind of cool so can we do something like a file but then this then line um implemented I might as well do something on this and then message something like this then exit one so that's the only thing I want to do right now and let me try to compile this into anything uh-huh okay so that was the reason okay cause do we have a cast thank you so much for such a beautiful error message I really appreciate it so expression so there is just this oh and this is interesting so I have to take the point to get again to actually properly okay let's see what's going on here what else do we have in here um so expression [Music] cannot convert expression to expressionist so we have to take the point of that thing okay I see oh boy um so in the year we also have to take that by a point so okay so compiled cool uh patch okay it even tell me that uh we have not implemented this thing that's pretty cool so for now I think I'm gonna just like not do anything um all right I'm gonna come in there so the only thing I care about is load probably load so what we're going to be doing with loads right so I have expressions and since this is a linked list all right since this is a linked list inserting into this thing should not invalidate any of the iterators so that should be fine right and what we have to do in here we have to do make uh unique all right and what kind of expression do we put in there that's a very good question so um do we have something like rub so the operation oh I see something ooh so opcode okay that's cool uh so this is the instruction that I have to insert in here but how can you construct such instruction so oh convert so there is a convert expression then okay of code expression and there is a okay so that's cool concept code expression you can okay you can construct an opcode and we know up op code it's a i32 rap i64. yes um so convert so that means I should be able to do something like convert expression top code i32 wrap I-64 and is that what I can do in here I think I feel like that's what it can do in here and that should be either actually [Music] okay he did something I'm not sure what exactly it did but anyway so we patched the memory we patched the functions but then we need to validate it afterwards right so the second validation is important the second validation is extremely important okay oh it patched it patched all the modes would you look at the that's actually very cool wait a second so uh if I commented out all right I recommend that here is a bunch of floats there was like four loads right and then we patch them out so the only thing we need to do now all right is to patch stores and also patch the data right but that's a completely separate story all right so stores is rather interesting because for the stores we'll need to implement um we'll need to implement some stuff um we'll need to implement functions that convert do the conversion so here is we do memory patch function and let's do the following stuff first first of all we need to create the type right so we need to create a type uh let me see so this is the IR h so class module um is it is that a struct module or uh-huh can I just like I pen I can append fields certain fields and I can have a type module field what is that and you can have a type entry and what is a type entry type entry um oh it's another hierarchy holy okay function type and have a function function signature function function symmetry and class um request Funk signature it's actually a little bit called and okay so there's the param types result types and so on and so forth okay [Music] in almost three hours okay [Music] I need to go again to module type module field and type module field [Music] I suppose we can just construct type module field [Music] Funk type make unique type module Fields right so let me try to recompile this into I think okay so it seems to be working and then within this stuff within this stuff IR this is like unnecessarily complicated I'm not gonna lie type entry and type entry is more of an abstract thing and more of a specific thing is a funk type right so this is more of a like um type field right so this is a type field but I don't know if I can just specify the type so I have to construct them separately um okay so if you feel like I do have to construct it separately okay so then I have a Funk type which is a make unique Funk type let's see I swear to God like why people write code like this uh Funk type so and in here we have to access this signature Funk type signature right and what do we have in that specific signature we have params param types and result types for Ram types and result types that's what we have in there right so then for the param types this is the type of vector right so this is the type vector and what is a type Vector I'm pretty sure it's an alias for some sort of a vector using yeah I was right it is this that so it means I can just push back and I have to push something like type and how can I construct a type I can just provide the type and enumeration so it's essentially type type what kind of enumerations do we have in there okay so we accept I64 so this is the parameter uh this is the first perimeter and then we accept i32 so we're going to generate the thing for Value City right and then we're going to return 32 32 two times so we constructed the signature for the function type and then we have to set um type I already forgot um type module field so this is the type to font type I wonder if I can actually do something like this right and then type field type Kennedy stuff like that I wonder see the are you sure about that oh okay so because we lost the time yeah I see we have to do it like that because it is more abstract it's just the type uh so we're losing the specifics that's why I had to do it like that okay so what we have in here cannot bind our value oh do I have to move it inside do I have to move it inside yeah okay okay so essentially when I try to assign I actually make a copy but I think the copy Constructor for the funk type is deleted or something um so type entry yeah just allow a copy and assign so copy and assign is disallowed so C plus plus is such a good compiler that it cannot just tell you that copying an assignment is not allowed it literally you have no ability to say that to you instead it can say some gibberish about L value and R value um right so but what it means is that you have to move that value welcome to C plus plus by the way dude [Music] um so yeah anyway after that after that we can do module and I think module had like a thing to to do that um oh you can literally append the field um all right so it's a type module field all right appended field side field all right can you do that I should be able to do that okay so we didn't like that okay probably the same situation we want to move that inside probably want to move that inside okay so that seems to be working so this is just a type right but for that type we also need to generate a function that uses that type right that's what we need to do so let's define a funk field right so there is a type field there must be a func field right so Funk module field and it has a function which is not a pointer by the way which is good so make unique Punk module field right in Funk field uh we're accessing the funk what do we have in funk what are we having funk okay we have a name do we care about the name I don't think we care about the name so whatever um function declaration I think we do care about function declaration we care about Expressions right so expressions and function declaration and then think I care about anything else uh function declaration so has a function type blue well probably is probably true function signature oh so you can have like a type in place I'm not sure what that means but can I just like do a very dumb thing not really dumb thing but uh signature right and just like use that signature so I don't have to define the type of this stuff can you do it like that will be actually kind of progress wouldn't be okay so we have that um so it has a phonic type and Funk type so it probably you have to say that to true and then you can refer to type VAR that you're defined in here but I'm not sure what is VAR struct VAR VAR I don't know what it is but maybe I didn't even need any of this stuff maybe I can just do it you know the only way you can check that is by like literally appending that thing there right so module append field STD Moon Funk field all right let's see if it's gonna do anything foreign type store type is matching implicit return it means that it it try to validate the function and function didn't return anything it's it's the same error as we had when we manually modified the what file it's complaining about that function holy alright so that means we can start doing expressions and for the Expressions we can probably just push back a bunch of stuff right so can we have like a uh local we can have a local guest local get expression right and this is a bar expression and a VAR expression okay so that means we can do something like make unique um local get expression and we have to provide the bar and I have no idea what the is for um it's it's an index what the is index is that a struck where the is index I'm sorry for swearing a lot today I'm programming C plus plus oh okay it's just a number oh it's a it's an operand like you can get zero and get one okay I see so that means I should be able to literally do something like this so that should now get the parameter of the function so it will complain that it has one number there we go it has one number but doesn't have the second one so the next thing we need to do we need to convert that stuff to 32 bits and we already know how to do that we already done that before all right so that's the instruction we want to insert in here right so that's the instruction we want to insert in here come on you can do that yes i32 so it actually converted that okay so I can program in webassembly from C plus so what I need to do now I need to take the the second one okay that's cool okay so it validated the function that I generated from scratch and actually didn't need uh any of this stuff I didn't need any time so this is actually working in uh so let me let me see let's do the following thing uh generate store wrap for type right so and I'm gonna move literally everything there uh-huh so and essentially we're going to accept the type right we're going to accept the type uh here we might as well accept the module and the type so we're generating this thing for this specific type and we're converting 64-bit pointer to 32-bit one so yeah I don't really know how to refer to these functions yet but we'll see so and essentially I should be able to um just generate store wrap for type so here is the module and the type is type i32 then I can generate it for 64 and so on and so forth so for this kind of things we can generate different things all right all right so that's cool so already generated two functions okay so there's some problems in here but code generation yes exactly we're doing code generation local variable is out of range [Music] foreign function but what are you talking about it was fine it was fine before so what's wrong hmm I don't get it function type variable function type wait what what what changed excuse me was it important so let's actually go back [Music] was this thing important [Music] This Is Us okay if I remove this thing foreign I think it still needs the type so I can do that but um oh I suppose it just looks up that type yeah okay you can't use this type if it was never declared or something maybe that's the problem here okay that's a really weird way of doing that but fine so generate rap store for type module module type type okay sure [Music] um so I'm gonna accept that and then let's put this thing like that so this is the type let's type um okay for a second I thought it's going to review literally everything okay so and now generate a wrapped store for type module type type is digital I-64 um so I always write action okay so let's find all of these stores now and perform the corresponding calls but that's a problem uh so let me see how can we perform the calls all right so expression type call that means there is a call expression call expression is a variable expression and a variable expression except some sort of index and a presume the index is basically the index of the function okay so that makes sense probably now if I remember the webassembly format correctly right I kind of roughly remember and remember that when you want to call a function you refer to the function by the index in the array of functions right by the web assembly format so that's what they remember so we suppose we can get the index by like Yeah by looking at the size of the functions right if you take a look at this thing straight module right so here are the functions you can take the length of that thing so funks size and we can just do it as an index Funk Index right we can try to return this thing index all right so okay and we can return that index in here um so index store i32 and then here we can have store I-64 so for now what I think I'm gonna do all right I'm going to accept store 532 right I'm gonna just like you know pass them there let's see how it goes okay cool so was it complaining about this is weird what the wait a second type mismatch really can I am I going crazy did they up the generation generate rap type mm-hmm you know what maybe instead of Declaration I have to do something else ah so Funk declaration so maybe I shouldn't leave the signature along all right that's what it feels like and just do as a function type I'm going to set it to true and then I'm gonna set the type variable part I'm going to set it to the type so out of funk type index and this is essentially module types size like so funk [Music] type index uh-huh so let's give it a try I'll probably have to wrap it in a bar expected I-64 but God foreign it says that um so what's up with this mm-hmm so let me let me see [Music] type of sign oh they were just taking an array mm-hmm and then just append okay it's a binary reader oh set function declaration so signature index set Funk there where where is it why is it in a different file is it in a different file okay well that's literally what it does it just sets that thing and that is it so we didn't think it's that big of a problem okay [Music] so making so type module fields foreign why it didn't work Maybe maybe this is not what I think it is maybe this is not who they think it is right so [Music] um [Music] thank you so let me let me only start with one hmm oh wait so this is not what I think okay okay that makes sense I think all right um now we can just put something in there just like zero um okay so it caused not by the generated code okay so I spent so much time trying to understand like what oh this is because oh my God I'm I'm so tired already okay I just copy pasted the code because I wanted like a placeholder all right so for which I'm Gonna Change to call expression I forgot about that and okay I see I'm just already tired like the the stream took uh too too much science right so that's that's literally the reason why it is like that okay uh uh so now let me see um but basically I discovered that you don't need to Define types like that or maybe I don't know we'll see let's see so and here what I want you to do I want to do a call right so this is my RH call expression right so this is a cool expression this is it has to be a VAR uh right and I can just do store i32 let's store i32 um all right so what do we have in here unused but where is the actual error could you please give me the actual error oh boy okay so required from here oh you have the VAR so maybe I should always rub them in VAR um type mismatch in initializer expression yes I think we solved all of the problems initial I think initialize expression is the data right so just a second yeah just a second um wasn't to what main 64. we have to enable them memory 64. uh memory 64. it's this yeah yeah it's this thing remember we we did the data and we also have to do this kind of stuff oh boy um okay I guess that's the only thing we need to do but I don't know uh how to do that module data I think it's a data segment yeah it's probably the data segment so struct data segment and what do we have in here oh wait really so this could be index well it is an expression because I-64 const is like an operand it's it's an instruction so you can you can have in here oh so but can you have like an arbitration here so that's a good question so what kind of stuff can you can you have so apparently this is a const expression right can you have ancient in there um all right can you really have anything there maybe maybe not you know what I'm actually gonna hardcore that because I didn't think you can have anything in there right patch expert what we're not gonna patch expert list what I need to do is um what is it called initializer expression okay patch we need experts but to do that we need to go through all of the data settings our data IR struct module date segments okay latest segments and then data experts uh-huh here we'll have to accept batch X for least come on yeah so that's what we need to do so in here I suppose we can just do outer expert experts and we can switch upon this stuff case um expression expression type expression type what is that const right I'm pretty sure it's const expression type const and there we go expression type const and if it is expression type const we have to modify that so it's a const expression so it has the internal const and it has an internal type set u32 what is from it's so weird from accept the type and data does some insertions sets the type and sets the data so to change the cons to u32 I literally have to do something like set this is so such a weird code why okay I'm sure uh I mean I don't care that's if that's your thing um so we have to do cast um what was that const expression right Advanced expression so pointer to the expression we cast that then we take the const right then we set u32 but to do that we have to get uh the center I think oh boy uh all right so essentially I can do something like autocons expert right almost expert const I can take this thing and then you can set this thing if we encounter anything else this is a straight up and ritual uh right so essentially it should break on anything that is not promised right so literally headquarter it should be fine I suppose um so do we call that anywhere go then anywhere okay we don't have though we take a bad point right let's do the Boomer style uh out uh begin and typical experts and foreign okay unreachable and implemented people [Music] um okay [Music] daily second doesn't have a are you serious it's called offset sure it just validated the second part we successfully patched that ship we actually did we successfully patched that all right so but we need to save that binary thing so uh we need to open what to wasn't so how do we do that memory stream right binary so we have to create some sort of a stream and it's a log stream yes logo stream all right and it's set well this sucks um yes wait what create this to the error yes look string [Music] so the only thing we need to do we need to save that somewhere ah it's needed for the login in case something something bad happens or whatnot okay whatever so I'm just gonna go and just do that so we validated the second thing um then if it failed all right oh default output name this is actually cool foreign could not generate binary data for the patched module all right something like this and then we're gonna do format write the file errors location type binary and then return one so then let me let me see if it's going to compile it's probably never been compounded so it needs some that's right binary options okay uh not sure if I care about these things so can I just like construct that stuff and never said anything so s right binary option relocatable write all five bytes debug names no I really don't care about it stuff um oh and it's okay [Music] binary yeah inches get I think it's from unique points I don't think we need to get the next one module pointer yes okay it's successfully generated something if I understand correctly um then we're saving it to a file and then we're saving that so we have to do something like that then we're writing that to trim output buffer okay so that should be fine but I don't think it's gonna work default output name I feel like default output name depends on what kind of thing you're doing so it must be the function that is yeah okay okay it was an extension um so let's put this thing somewhere here string view by the way huh strip extension and what kind of extension do we add so what we're gonna put in here I'm gonna put 64 to 32 wasn't all right get the base in him please name uh file names you're freaking serious wait did they modify okay I'm gonna need it should have actually put it in here foreign buffer file where is it located oh wait it's a are you serious you can just you can just do it like that why you need this functional dumb module dumb it's like additional nobody cares about okay so this is what we can do the buffer is oh really stream output buffer oh yeah so write a file file name and the file name is s out file okay police work already yes 64.2 yes we've got it we've got this uh let me take a look at the what uh wasn't to what the main 64 64 232 and what do we have in here so memory is well it doesn't have any type that means it's actually 32. the data 32 uh do we have additional functions so this is the function parameters okay we have an empty function well empty function I suppose it's the like in meat or something [Music] so environment print message do we import anything so the export it feels like some of the exported functions were like lost oh no okay so they're action okay so here by the way the function that we generated so the uh the rubbers right so and we can generate flag for any typing yeah so that's pretty cool I want to take this module now and I want to put it into the test test wasn't uh all right I'm gonna copy paste it in here and in load JS this one is 64.64. um search it too 64-32 and do we have this stuff okay so apparently I have okay it seems to be working does it yeah so there we go we're loading that module and it is work so we managed to write a tool that converts a 64-bit wasn't to search it a bit so let's actually try to apply it to jai uh and see in on in which places is going to break [Applause] okay so it's party um 64-32 and I'm gonna just try to do that okay so it fails in some of these places okay type mismatch okay so could you please stop it it didn't stop uh okay oh yeah okay I I know what it is I know what it is because we don't use store 64. we don't use store 64. mm-hmm so we need to pass it in there we're going to have many of them so we'll have to pass them like always you know I have an idea what if we create a structure store right in here we're going to have different things like I set it to I-64 and then if we add more we're going to be adding more there so store store [Music] um okay and then here I think it makes sense to actually return a variable VAR iety okay so when we patch function we have to do store wasn't 64. okay so store has to be defined let's define somewhere up here mm-hmm so we'll have to pass those things into um okay attach funk alright cool so essentially here when I do the store I need to know what kind of store do I have do I have that information in the store expression what is this load store expression I need a store expression oh okay so it's a Memory load expression hmm a little store expression and we only have opcode which is I guess enough right so do we have up code you would have that we have different op codes so i32 store yeah for Isa to the store yeah that's pretty cool so we can do it like that so we can just switch um but that will also require converting to Auto store expression right cost store expression um it can take that switch store expression popcodes and here we have different op codes um now this is actually pretty cool because now if I have something unsupported I can print what exactly I can support or code is32 store all right so and that's what I do and then for the default I can always say something like STD Alt can I can actually say that um can for the op code can I so the op code is defined also a name but can I have an access to that to that name uh op code okay so there's a up code This is complicated okay okay I can have a name which is nice so this is op code but this is a time also type um get code it's a enumeration as well and does it have a conversion to enumeration yeah it does have it okay this is perfect so that means I can do stuff like that and then um unsupported store uh store instruction and we can do something like uh store expression fault codes get name all right and then I can exit with one Okay so that's pretty cool now let me go to jailbreak and I'm gonna try to do that and support it store instruction I64 so what that means that means I can now do the following thing [Music] um I-64 964. so let's rebuild this thing and now let's do that one more time I set it to store eight this one is interesting what that means that means that it accepts with 32-bit value but stores only one byte out of it right so because in webassembly there is no I8 i16 there's only i32 and i-64. and therefore you can only store one byte by having 32-bit an integer right so that means if we encounter i32 store 8 we have to redirect that into I think to uh i32 store right so that's basically what we'll have to do okay so can I just ate eight I think I think you can oh this is not particular permanent you know what I want to do I want to copy paste that main uh here so it's a little bit easier for me to to work with it because I want to be able to work with it in a single place uh main.wasm I'm gonna quickly paste it in here and let's just do make and then wasm64-32 main.wasm and let's see how it's going to go so basically I'm going to rebuild it and then modify it so that's what I want to do okay so the same for 16 as you can see right okay so that's cool um next one so I wonder how many of them do we have I wonder how many of them do we have 32 so we're getting to the territory of things that we don't support yet so this one's going to be F32 all right and here generate have 32 F32 all right so and if we encounter op code is up code F32 store so we call to F32 um f64 okay makes sense mm-hmm I don't think we will need anything else I think there's only like i32 I64 F32 and f64 all right so that's the only four things that we need to generate in here uh I'm so tired okay uh 64. 64. uh-huh foreign it's done and it even type checked I was expecting that not everything is going to be type checked because like you need we didn't handle all of the blocks right we only handled like loops it like I mean there is a good chance that this worked because we do like a double validation this is okay so let me see um do I break I'm gonna just copy paste this thing back all right I'm gonna go to load.js uh 64 to 32 right so this is what we're gonna try to do in here so I think I'm gonna remove that okay so there's nothing in here and let me put buy something okay so it's it's complaining about big ins it's a very good sign this is a very good sign because it's trying to work with 64-bit integers uh so this is a very good sign uh what do we have in here it's it's 46. oh this is a good point so it means it wants null as a big integer this is a very good sign okay wait wait a second did you notice that this thing started to work it didn't work before um yeah it didn't work before and you know why it didn't work before because it was using the structured literals it works this works so this idea works so the program compiled for 64 bits and we tricked it into working in 32 bits this is so cool this utility by the way 64-32 could be very useful for for somebody else right and imagine that you have like a 64-bit program that is actually hardcoded to be 64-bit but you want to run it on 32 bits this could be useful I mean until memory 64 extension becomes like a standard this is a very useful tool I think I want to actually turn it into Standalone thing that other people can use right this this thing is obviously not finished right so you you need to like add more types in here maybe like double check some stuff but overall this could be a very useful tool um and as far as I know I think wobbit is a library isn't it yeah it is a library I saw I can probably you like write this tool outside of the uh wipe it source code tree you know what I mean furthermore Jai can interrupt with um with C code so I can even integrate this specific code into the build of the game right the process of patching wasn't could be part of the build quite easily because the Jai can make a call to this code right so we can do something like that but that requires like additional stuff so there's a lot of things in here that you can wow right it just it just works now right and probably all of the bugs associated with like incorrect pointer arithmetic is actually fixed um this is so cool the the code base of wabbit is actually kind of there so it says like a it feels really strange because it's a mix of like old school C programmer right so you you clearly can feel like an old school C programmer vibe in here when you just have this like functions like a procedural functions that you call then when you deep uh like a dig down into what these functions actually do you see the classical uh CS course op course yeah a classical CS course and then you can see some crazy C plus plus developer like implementing their own STL so it this code base like feels like a mix of like these different styles like uh old-school see stuff the op with all of these hierarchies and stuff like that and the crazy STL thing created by Russian developer under mushrooms or something like that yeah um did you guys know that the creator of STL was actually had like uh food poisoning when we when he came up with STL or something like that do you guys know that it sounds different right so and he was in the hospital when he came up with the STL idea so he had some sort of like a food poisoning uh [Music] uh I didn't remember but this is like the history behind it so yeah yeah all right anyway that's pretty cool so I finally picked that book so the structure literals actually worked work and I can I can sleep in peace so and I think the outcome of today's stream is actually very useful so all of that artifacts can be turned into something something useful for the community all right does anyone have any questions [Music] I have any questions I guess not all right that's it for today thanks everyone who's watching right now I really appreciate it I have a good one and I see you uh on the next stream I love you [Music]
Info
Channel: Tsoding Daily
Views: 36,162
Rating: undefined out of 5
Keywords:
Id: tfME9wwdgGw
Channel Id: undefined
Length: 196min 26sec (11786 seconds)
Published: Tue Aug 23 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.