WebAssembly - Convert WAT to WASM

Hello, aspiring programmers! Today, we're going to embark on an exciting journey into the world of WebAssembly, specifically focusing on converting WebAssembly Text (WAT) to WebAssembly binary (WASM). Don't worry if these terms sound alien to you – we'll break everything down step by step. By the end of this tutorial, you'll be converting WAT to WASM like a pro!

WebAssembly - Convert WAT to WASM

What is WebAssembly?

Before we dive into the conversion process, let's take a moment to understand what WebAssembly is. Imagine you're building a sandcastle. WebAssembly is like having a magical bucket that can create perfect sand structures instantly, making your beach creations faster and more impressive.

In the world of web development, WebAssembly is a low-level language that allows code written in languages like C++ or Rust to run in web browsers at near-native speed. It's designed to work alongside JavaScript, enhancing the performance of web applications.

WAT vs WASM: The Basics

Now, let's talk about WAT and WASM. Think of WAT as the blueprint for your sandcastle, written in a language humans can read. WASM, on the other hand, is like the final sandcastle – it's the form that computers understand and can execute quickly.

  • WAT (WebAssembly Text Format): Human-readable, similar to assembly language
  • WASM (WebAssembly Binary Format): Machine-readable, compact binary format

WAT to WASM Conversion: The Process

Converting WAT to WASM is like translating our sandcastle blueprint into actual sand structures. Let's go through this process step by step.

Step 1: Write Your WAT Code

First, we need to create our WAT code. Here's 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))
)

This WAT code defines a module with a function that adds two 32-bit integers. Don't worry if you don't understand every detail – we'll break it down:

  1. (module ...): This wraps our entire WAT code.
  2. (func $add ...): Defines a function named "add".
  3. (param $a i32) (param $b i32): Specifies two 32-bit integer parameters.
  4. (result i32): Indicates that the function returns a 32-bit integer.
  5. local.get $a and local.get $b: Retrieves the function parameters.
  6. i32.add: Adds the two numbers.
  7. (export "add" (func $add)): Makes the function accessible from outside the module.

Step 2: Save Your WAT File

Save this code in a file with a .wat extension, for example, add.wat.

Step 3: Use a WAT to WASM Converter

Now comes the magic part – converting WAT to WASM. We'll use a tool called wat2wasm, which is part of the WebAssembly Binary Toolkit (WABT).

Here's how you can use it:

  1. Install WABT (if you haven't already):

    • On macOS: brew install wabt
    • On Ubuntu: sudo apt-get install wabt
    • For other systems, check the WABT GitHub repository
  2. Open your terminal and navigate to the directory containing your WAT file.

  3. Run the following command:

wat2wasm add.wat -o add.wasm

This command tells wat2wasm to convert our add.wat file into a WASM file named add.wasm.

Step 4: Verify Your WASM File

Congratulations! You've just created your first WASM file. But how do we know it worked? Let's use another WABT tool called wasm2wat to convert our WASM back to WAT and see if it matches our original code:

wasm2wat add.wasm -o add_verified.wat

Now, open add_verified.wat in a text editor. It should look very similar to our original WAT code, though it might have some minor formatting differences.

Using Your WASM File

Now that we have our WASM file, how do we use it in a web application? Here's a simple HTML and JavaScript example:

<!DOCTYPE html>
<html>
<head>
    <title>WebAssembly Add Function</title>
</head>
<body>
    <h1>WebAssembly Add Function</h1>
    <p>Result: <span id="result"></span></p>
    <script>
        (async () => {
            const response = await fetch('add.wasm');
            const bytes = await response.arrayBuffer();
            const { instance } = await WebAssembly.instantiate(bytes);
            const result = instance.exports.add(5, 3);
            document.getElementById('result').textContent = result;
        })();
    </script>
</body>
</html>

This HTML file loads our WASM module and calls our add function with the arguments 5 and 3. The result (8) is then displayed on the page.

Conclusion

And there you have it! We've journeyed from writing WAT code to converting it to WASM and finally using it in a web page. Remember, this is just the tip of the iceberg. WebAssembly opens up a world of possibilities for high-performance web applications.

As you continue your programming adventure, keep experimenting with different WAT functions and exploring the capabilities of WebAssembly. Who knows? You might just create the next breakthrough web application that changes the world!

Happy coding, future WebAssembly wizards!

Credits: Image by storyset