
Lesson Description
The "WASM Exercise" Lesson is part of the full, Write a Compiler That Understands Types course featured in this preview video. Here's what you'd learn in this lesson:
Richard explains the process of incorporating WebAssembly operations for addition and multiplication. He emphasizes the importance of setting the opCode variable correctly and understanding the order of operations due to Web Assembly's stack machine nature.
Transcript from the "WASM Exercise" Lesson
[00:00:00]
>> Richard Feldman: All right, cool. Let's go through, well, get into the last exercise. So as before, we once again have our index.js that is, once again, the thing that we're gonna run. And unlike the other sections, we're all done with typecheck.js that's still there, it's doing its job, whether someone's using it.
[00:00:19]
But now we have our new thing of wasm.js which is what we're actually gonna have our little section to mess around in. So let's cd into part 7 and run this, and there we go. We're getting a whole bunch of WebAssembly errors that are not working out right now.
[00:00:35]
Even for our test titled simple numeric edition, we're even blowing up on simple numeric addition. Can you imagine it? As you may recall, we have done quite a lot with binary operators, the two that we support being plus and times. So right here, basically what we wanna do is we want to use Webassembly's magical numbers to tell Webassembly, hey Webassembly, it's multiplication time, or hey Webassembly, it is addition time.
[00:00:59]
All we have to do, essentially, is to just go look for the global OP constant, which is short for operator. So that is back up at the top of the file somewhere, there it is. That was it, yeah. So as you can see, there's a whole bunch of different operations that WebAssembly supports.
[00:01:18]
Let me get back there. So we got BLOCK, LOOP, IF, ELSE, END, blah, blah, blah, on, and on, and on. And then in here we have a whole bunch of F64 specific, F64 being our number type operations, such as add, subtract, multiply. So of course we are interested in these two out of all of them.
[00:01:38]
I definitely recommend referencing the constant. You could just put the hard-coded number in there, but nobody's gonna ever remember what that's all about. So I would definitely recommend not doing that if you could avoid it. But yeah, so basically what we wanna do is in both cases, we want to set this variable called opCode because what we end up returning is concatBytes.
[00:01:57]
Again, concatBytes being essentially the same thing as concatString, except that we're concatenating bytes instead of a string like we were at the very beginning with the formatter. So what we're gonna do here is essentially say, okay, I'm going to concat left, which is basically where we have sort of recursively gone down this path as usual doing a visit type thing where we're just going down and building up bytes, bytes, bytes, bytes.
[00:02:21]
We say, okay, take all the stuff that we had on the left, and then we take all the stuff on the right, and then that goes right after that. So you can imagine this big, long chunk of bytes and this big, long chunk of bytes, and then after that we put the actual opCode that we want to apply to those.
[00:02:35]
Now, the reason they're in this order is, again, going back to the WebAssembly, is a stack machine thing. So what WebAssembly wants you to do is, essentially, when it sees this opCode, it says, aha, I see you want me to do this operation. You'd better have put the two parameters to that on the stack already.
[00:02:49]
You better have put that one here and that one here, because that's where I'm expecting them to be. I expect them to be right in front of the operation. Whereas, of course, if we were writing this in JavaScript, we would put it in the middle. So we'd go like, put the opCode, whether it's plus, or minus, or times, or whatever, in the middle, and then we put the other operand on the other side, but WebAssembly doesn't want it in that order.
[00:03:09]
Now, that's a pretty minor little swap around, but you can kind of see, if you squint, we're doing the same stuff that we would do in a formatter, just at a slightly different order and with slightly different constants. So this is our one thing. It's a little light one to end on.
[00:03:24]
Get a little WebAssembly in the mix and let's just take five minutes and work through it.
>> Richard Feldman: Great, all right, let's go through the final set of solutions. It's a pretty simple one this time. So basically, we're doing a switch on node.operator. If we wanted to add support for more in the future, of course we could, but for right now, we've just got plus and times.
[00:03:49]
So the cases here are pretty straightforward, it's just like, OP.F64_ADD, F64_MUL. If you wanted to know the full range of things that WebAssembly supports, this is where you'd sort of just go to documentation. You can just find a long lists of here they are, here's what the magic numbers are that correspond to these, but pretty straightforward.
[00:04:06]
At this point, just put it in there, assign it to that thing, and we are good. One other note on this is that at this point, we've already sort of generated the thing that's going to be the first operand and the thing that's going to be the second operand.
[00:04:24]
If it is conceivable that not in the case of plus and times obviously, but you might actually need to potentially generate these in a different order depending on if you have operator specific things that you need to do with these things. In this case, that doesn't come up, but just like with everything else that we've talked, Cogen is something where sometimes you have a nice neat pattern like this, and then other times it's sort of like, yeah, in this situation it's fine.
[00:04:47]
But then as soon as I introduce a raise, wait a minute, now there's an edge case, and stuff like that. So all these things that we're looking at here, this is kind of the simplified version of it. It's like not necessarily as simple as you can get. I try to kinda strike a balance with like interesting type system and code gen features, and whatnot with, something that's so easily digestible.
[00:05:06]
But when you think about what's the difference between this code right here and a big production gigantic million line of code compiler? A lot of it just has to do with, there's just way more edge cases around little stuff like this. But if you kinda blur the lines a little bit, you can be like, okay, I can still see the same basic fundamentals around this.
[00:05:25]
They just have a lot more conditionals in between in a lot of cases. So alright, so now we've got our opcodes in there, and hey, look at that simple numeric addition in WebAssembly. It's a beautiful thing. Any questions on WebAssembly before we go to our final little wrap up, summarize everything that we learned section?
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops