Generate WebAssembly Modules with Python

This article explains how to use Python code to generate a functioning WebAssembly (Wasm) module. It covers the core concepts of WebAssembly generation from Python, provides a complete and runnable Python script that compiles WebAssembly Text Format (WAT) into a binary .wasm file, and demonstrates how to execute the resulting module.


Can Python Generate Wasm Modules?

Yes, Python can be used to generate functioning WebAssembly modules. While Python itself is an interpreted language, developers can utilize Python libraries to compile WebAssembly Text Format (WAT) or lower-level representations directly into .wasm binary files.

One of the most effective tools for this task is PPCI (Python Compiler Infrastructure), a compiler written entirely in Python. PPCI includes support for WebAssembly, allowing you to assemble WAT code into a valid Wasm binary directly from a Python script.


Step-by-Step Guide to Generating Wasm with Python

To generate a Wasm module, you need to write WebAssembly instructions (usually in text format) and use Python to compile and save them as a binary file.

1. Install the Required Library

First, install the Python Compiler Infrastructure (ppci) package using pip:

pip install ppci

2. Python Code to Generate the Wasm File

The following Python script defines a simple addition function in WebAssembly Text format, compiles it into binary WebAssembly, and writes it to a file named add.wasm.

from ppci.api import wat2wasm

# Define the WebAssembly Text (WAT) code
wat_code = """
(module
  (func $add (param $lhs i32) (param $rhs i32) (result i32)
    local.get $lhs
    local.get $rhs
    i32.add)
  (export "add" (func $add))
)
"""

def generate_wasm():
    try:
        # Compile WAT string to binary WASM bytes
        wasm_bytes = wat2wasm(wat_code)
        
        # Save the binary bytes to a file
        with open("add.wasm", "wb") as f:
            f.write(wasm_bytes)
        
        print("Success: 'add.wasm' module generated successfully!")
    except Exception as e:
        print(f"Error generating WASM module: {e}")

if __name__ == "__main__":
    generate_wasm()

Running the Generated Wasm Module

Once Python has generated the add.wasm file, you can run it in any Wasm runtime, such as a web browser or a Node.js environment.

Executing in JavaScript

You can load and run your Python-generated Wasm module in a browser or Node.js using the following JavaScript code:

const fs = require('fs');

// Load the generated WASM binary
const wasmBuffer = fs.readFileSync('add.wasm');

WebAssembly.instantiate(wasmBuffer).then(wasmModule => {
    // Access the exported 'add' function
    const add = wasmModule.instance.exports.add;
    
    // Execute the function
    const result = add(10, 15);
    console.log(`Result of 10 + 15: ${result}`); // Outputs: 25
});

Alternative Approaches

If you want to compile standard Python code into WebAssembly rather than writing WAT code, you can use these alternative toolchains: