WebAssembly - WASM: A Beginner's Guide

Hello there, future coding superstar! I'm thrilled to be your guide on this exciting journey into the world of WebAssembly, or WASM for short. Don't worry if you've never written a line of code before – we're going to start from the very beginning and work our way up together. So, grab a cup of your favorite beverage, get comfortable, and let's dive in!

WebAssembly - WASM

What is WebAssembly?

WebAssembly is like a secret language that web browsers understand. It's designed to make web applications run faster and more efficiently. Imagine you're trying to play a complex video game on a website. Without WebAssembly, it might be slow and clunky. But with WebAssembly, it can run smoothly, almost as if you were playing it on a gaming console!

A Brief History

WebAssembly was born out of a desire to make web applications more powerful. It was first announced in 2015, and by 2017, it was supported by all major web browsers. That's pretty fast in the tech world – kind of like how quickly your favorite social media app updates with new features!

The Stack Machine Model

Now, let's talk about something that sounds a bit technical but is actually quite simple when you break it down: the Stack Machine Model. This is the heart of how WebAssembly works.

What is a Stack?

Think of a stack like a pile of plates. You can only add or remove plates from the top of the pile. In computer terms, we call adding to the stack "pushing" and removing from the stack "popping".

How WebAssembly Uses the Stack

WebAssembly uses this stack idea to perform operations. It's like a very efficient chef in a kitchen, always knowing exactly which ingredient (or number, in our case) to use next.

Let's look at a simple example:

(module
  (func $add (param $a i32) (param $b i32) (result i32)
    local.get $a
    local.get $b
    i32.add)
  (export "add" (func $add))
)

Don't panic! I know this looks like alien language right now, but let's break it down:

  1. (module): This is like saying "Here's a new recipe book".
  2. (func $add ...): We're defining a new function (or recipe) called "add".
  3. (param $a i32) (param $b i32): Our function takes two ingredients (parameters), both 32-bit integers.
  4. (result i32): The result will also be a 32-bit integer.
  5. local.get $a: Put the first number on top of our stack of plates.
  6. local.get $b: Put the second number on top.
  7. i32.add: Add the top two numbers and replace them with the result.

So, if we called this function with 5 and 3, our stack would look like this:

  1. Start with an empty stack: []
  2. After local.get $a: [5]
  3. After local.get $b: [5, 3]
  4. After i32.add: [8]

And voila! We've added two numbers using WebAssembly's stack machine model.

Why Use WebAssembly?

You might be wondering, "This seems complicated. Why not just use JavaScript?" Great question! WebAssembly has some super powers that make it special:

  1. Speed: WebAssembly can run much faster than JavaScript for certain tasks.
  2. Efficiency: It uses less memory and processing power.
  3. Language Flexibility: You can write code in languages like C++ or Rust and convert it to WebAssembly.

Imagine you're building a sandcastle. JavaScript is like using your hands – it's flexible and easy to start with. WebAssembly is like having a set of specialized tools – it might take a bit more setup, but you can build much more complex and sturdy castles!

Your First WebAssembly Program

Let's write a simple program that adds two numbers. We'll use a language called WAT (WebAssembly Text Format) which is a human-readable version of WebAssembly.

(module
  (func $add (param $left i32) (param $right i32) (result i32)
    local.get $left
    local.get $right
    i32.add)
  (export "add" (func $add))
)

This might look familiar – it's very similar to our earlier example! Here's what it does:

  1. Defines a module (our program).
  2. Creates a function called $add that takes two 32-bit integers and returns one.
  3. Gets the first number ($left) and puts it on the stack.
  4. Gets the second number ($right) and puts it on top of the first.
  5. Adds the two numbers on the stack.
  6. Exports the function so we can use it from JavaScript.

To use this in a web page, we need a bit of JavaScript:

fetch('add.wasm')
  .then(response => response.arrayBuffer())
  .then(bytes => WebAssembly.instantiate(bytes))
  .then(results => {
    const add = results.instance.exports.add;
    console.log(add(5, 3));  // Outputs: 8
  });

This code loads our WebAssembly module, creates an instance of it, and then calls our add function with the numbers 5 and 3.

Conclusion

Congratulations! You've just taken your first steps into the world of WebAssembly. We've covered what WebAssembly is, how it uses a stack machine model, and even written our first WebAssembly program.

Remember, learning to code is like learning a new language or instrument – it takes practice and patience. Don't be discouraged if everything doesn't click right away. Keep experimenting, keep learning, and before you know it, you'll be building amazing things with WebAssembly!

In our next lesson, we'll dive deeper into more complex WebAssembly concepts and start building some really cool projects. Until then, happy coding!

WebAssembly Methods Description
local.get Retrieves a local variable or parameter
local.set Sets the value of a local variable
i32.add Adds two 32-bit integers
i32.sub Subtracts two 32-bit integers
i32.mul Multiplies two 32-bit integers
i32.div_s Signed division of two 32-bit integers
i32.rem_s Signed remainder of two 32-bit integers
i32.and Bitwise AND of two 32-bit integers
i32.or Bitwise OR of two 32-bit integers
i32.xor Bitwise XOR of two 32-bit integers
i32.shl Left shift of a 32-bit integer
i32.shr_s Signed right shift of a 32-bit integer
i32.eq Equality comparison of two 32-bit integers
i32.ne Inequality comparison of two 32-bit integers
i32.lt_s Signed less than comparison of two 32-bit integers

Credits: Image by storyset