Skip to main content

A stack-based virtual machine for learning about WebAssembly

Project description

WasmVM.py

A stack-based virtual machine for learning about WebAssembly

This is a simple stack-based virtual machine that can execute a small set of instructions. It is intended to be the starting point for learning more deeply how WebAssembly works. Right now, like WebAssembly, it only supports 32- and 64-bit integers and floats for operations.

Using

Basic usage

  1. Open the Python REPL by running python3 in your terminal.
  2. Install the package wasmvm by running pip install wasmvm.
  3. Import the StackVM class and instructions.
    from wasmvm import StackVM, Add, Sub, Push, i32
    
  4. Create an instance of the StackVM class.
    vm = StackVM()
    # Optionally, you can specify the number of pages of memory
    # you want your VM to start with, and the maximum number it
    # may have: StackVM(1, 10)
    
  5. Add instructions to your virtual machine.
    vm.instructions = [Push(i32(2)), Push(i32(3)), Add("i32")]
    
  6. Execute the instructions.
    vm.run()
    
  7. Inspect the stack after your instructions have been executed:
    vm.inspect()
    # [5]
    

Running the API

  1. Create a Python virtual environment, e.g. python3 -m venv venv.
  2. Activate the virtual environment, e.g. source .venv/bin/activate.
  3. Install the dependencies, e.g. pip install -r requirements.txt.
  4. Install the API dependency: pip install "fastapi[standard]"
  5. Start the API: fastapi dev main.py
  6. Navigate to http://127.0.0.1:8000/docs to use the OpenAPI documentation.

Working with the frontend

In the directory /static, there resides a simple frontend that can be used to interact with the API. To start the frontend, you need to first install the necessary tools:

# install bun for macos
brew install oven-sh/bun/bun
bun upgrade

From here, you'll next install the dependencies:

cd static
bun install

Finally, you can start the frontend:

bun run dev

To build the frontend for production, you can run:

bun run build

Hooking in observers

Since this is a learning tool, it can be useful to see what your machine is doing while it's operating. Since this is intended to be an extensible tool, you can add different types of observers suited to your execution environment.

For example, you can add a simple observer that prints the stack at each step by running (this one is included in the virtual_machine module):

from virtual_machine import StackVM
from lib import Add, Sub, Push
from shared import VMState

def print_state(state: VMState) -> None:
    print(f"Stack: {state.stack} || Program Counter: {state.pc}")

vm = StackVM()
vm.add_observer(print_state)

Then, when your virtual machine runs, you'll see the stack printed after each instruction has been executed.

Wait, what's a stack-based virtual machine?

In short, a stack-based virtual machine is a computer that uses a stack to store data and execute instructions ("stack" like pancakes). Operations are performed by pushing values onto the stack and then popping them off to be used as arguments to instructions. The program counter (PC) keeps track of where the virtual machine is in the program, and the stack is used to store intermediate values.

Stack-based virtual machines are found in the wild in many places, such as the Java Virtual Machine (JVM), the .NET Common Language Runtime (CLR), and (of course) the WebAssembly virtual machine that's in your browser (unless you're using Lynx).

Instruction set

  • Add
  • Sub
  • Mul
  • Div
  • Eq
  • Eqz
  • Lt
  • Le coming soon
  • Gt
  • Ge coming soon

Building

source venv/bin/activate
python -m pip install -r requirements.txt
# Install dev version locally
python -m pip install -e .
# Build wheel
python -m build
# Upload wheel to testpypi
python -m twine upload --verbose --repository testpypi dist/*

Resources

There are many resources available to learn more about WebAssembly and how it works. Here's what I've been using:

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

wasmvm-0.1.0.tar.gz (6.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

WasmVM-0.1.0-py3-none-any.whl (7.3 kB view details)

Uploaded Python 3

File details

Details for the file wasmvm-0.1.0.tar.gz.

File metadata

  • Download URL: wasmvm-0.1.0.tar.gz
  • Upload date:
  • Size: 6.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.12.7

File hashes

Hashes for wasmvm-0.1.0.tar.gz
Algorithm Hash digest
SHA256 2d97f88590d5a558bf9f5acd491d4b804133a38cd77b0889c6e02b9c4215d4a5
MD5 0113005ba5c4728ccf44f8ed3cedb72b
BLAKE2b-256 0c82b6ae480d300bf46f1888f39d2ee791a40be500207edbdbfb3f9e2a93fc86

See more details on using hashes here.

File details

Details for the file WasmVM-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: WasmVM-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 7.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.12.7

File hashes

Hashes for WasmVM-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 19bd1130f4f6649d68dfe868344cad6f5721697fc8135840357a6e9dc19a649e
MD5 59eeb1b3f1d127c588b03b03456fd48c
BLAKE2b-256 91b2d798c9f63876e2551b62afdd5cb39b9ddfe15b16ab29c3b3503a206e628e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page