Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

rrampage/wart

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

275 Commits

Repository files navigation

A simple WASM interpreter in multiple languages

Inspired by David Beazley's mindblowing talk on live-coding a WASM interpreter

wasp - Java WASM interpreter

  • Runs Doom!
doom-wasm.mp4
  • Runs Linux (very slowly!!) by running a RISC-V emulator compiled to WASM
    • java --enable-preview -cp path_to_jar.jar rrampage.wasp.examples.RiscVEmulator

Currently implemented

Machine

  • Stack push/pop works for i32, i64, f32 and f64
  • Uses Java 21 pattern matching and records to implement instructions
  • Arithmetic and comparison ops implemented
  • Load/store with alignment and offset support
  • Unary ops like popcnt, ceil, floor, trunc implemented
  • Functions
    • call and call_indirect
    • Labels set/reset during/after function call
  • Bitshift ops
  • Blocks, loops and conditionals
  • Sign extension operations
  • Non-trapping Float to Int conversions
  • Start
  • Exports
  • Invoke exported functions

WAT Parser

  • Instructions
  • Imports
  • Types
  • Functions
  • Block comments

WASM parser

  • Magic bytes and version check
  • Implement LEB128 decode
  • Read section metadata
  • Read sections
    • Type
    • Import
    • Export
    • Start
    • Function
    • Table
    • Memory
    • Code
    • Data
    • Data count
    • Element
    • Global
  • Module instantiation
    • Memory
    • Imports
    • Globals
    • Exports
    • Data Segments

Interop

  • Import Java functions in WASM using MethodHandle for typesafe invoking

More Demos!

image

image

  • Renders olive.c examples

image

  • Game of Life pulsar

image

TODO

Machine

  • Multi-valued Block types
  • 128 bit vector (v128) data type and instructions
  • external reference types
  • GC ??
  • Stack frames

WAT Parser

  • Exports
  • Memory
  • Tables
  • Start

WASM parser

  • Implement LEB128 encode
  • Read sections
    • Custom
  • Module instantiation
    • Element Segments

Interop

  • Use exported functions from Java
  • Create support infrastructure to pass multiple imports
    • We do not have to pass imports while parsing. We can create stubbed-out functions using the type signature
    • Later, when instantiating machine, we can replace these stubbed functions with method handles from a HashMap<String, MethodHandle>
  • Limits must have meaningful bounds
  • Block types must be expressed in one of 2 forms both of which are converted to function types
    • typeidx: types[typeidx] must be defined
    • valtype : [] -> [valtype]
  • Table type limits for reftype must be valid within the range 2^32 -1
  • Memory type limits must be valid within the range 2^16
  • External types : the corresponding function / table / memory / global types must be valid
  • Import subtyping: When instantiating a module, external values must be provided whose types are matched against the respective external types classifying each import.
    • Limits: External limits(min1, max1) matches limits(min2. max2) iff min1 >= min2 AND (max2 is empty OR (max1 and max2 are non-empty AND max1 <= max2))
    • Function types: External functype1 and functype2 are the same
    • Tables: External reftype table1(limits1, reftype1) matches table2(limits2, reftype2) iff limits1 matches limits2 AND reftype1 and reftype2 are the same
    • Memories: External memory1(limits1) matches memory2(limits2) iff limits1 matches limits2
    • Globals: External global1(globaltype1) matches global2(globaltype2) iff globaltype1 and globaltype2 are the same
  • Instructions
  • Modules

wag - Golang WASM interpreter

cd wag
go mod tidy
go test -v

Currently implemented

  • Works with i32
  • Support for load/store
  • Support for arithmetic
  • Support for simple functions

TODO:

  • Branching
  • Blocks
  • Support i64, f32, f64
  • Imports
  • Run on simple wasm files

References

WASM opcode references:

Tools:

  • Convert wasm to wat : wasm-tools print my_file.wasm > my_file.wat
  • Generate valid WASM files: head -c 1000 /dev/urandom | wasm-tools smith -o test.wasm
  • Generate valid WAT files: head -c 1000 /dev/urandom | wasm-tools smith | wasm-tools print > test.wat
  • Convert wat to wasm : wat2wasm my_file.wat will create my_file.wasm
  • Analyze wasm file: wasm-objdump -x my_file.wasm.
    • -x shows section details
    • -d shows disassembly of all function bodies
    • -s shows section contents

Standard coreutils / binutils

  • Read wasm file as hex:
    • xxd -u -g 1 my_file.wasm or hexdump -C my_file.wasm

About

A simple Web Assembly Interpreter

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

AltStyle によって変換されたページ (->オリジナル) /