From 9fb976703d283466a763f18ff7427b59947be91d Mon Sep 17 00:00:00 2001 From: mleku Date: Fri, 14 Nov 2025 14:37:36 +0000 Subject: [PATCH] hello world in wat --- .claude/settings.local.json | 7 ++- pkg/wasm/README.md | 102 ++++++++++++++++++++++++++++++++++++ pkg/wasm/hello.js | 18 +++++++ pkg/wasm/index.html | 10 ++++ pkg/wasm/server.go | 48 +++++++++++++++++ 5 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 pkg/wasm/README.md create mode 100644 pkg/wasm/hello.js create mode 100644 pkg/wasm/index.html create mode 100644 pkg/wasm/server.go diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 2c6ad60..d23d1df 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -48,7 +48,12 @@ "Bash(./test-policy.sh:*)", "Bash(docker rm:*)", "Bash(./scripts/docker-policy/test-policy.sh:*)", - "Bash(./policytest:*)" + "Bash(./policytest:*)", + "WebSearch", + "WebFetch(domain:blog.scottlogic.com)", + "WebFetch(domain:eli.thegreenplace.net)", + "WebFetch(domain:learn-wasm.dev)", + "Bash(curl:*)" ], "deny": [], "ask": [] diff --git a/pkg/wasm/README.md b/pkg/wasm/README.md new file mode 100644 index 0000000..4154758 --- /dev/null +++ b/pkg/wasm/README.md @@ -0,0 +1,102 @@ +# WebAssembly Test Server + +Simple Go web server for serving WebAssembly files with correct MIME types. + +## Quick Start + +```bash +# Build and run the server +go run server.go + +# Or with custom port +go run server.go -port 3000 + +# Or serve from a different directory +go run server.go -dir /path/to/wasm/files +``` + +## Build and Install + +```bash +# Build binary +go build -o wasm-server server.go + +# Run +./wasm-server + +# Install to PATH +go install +``` + +## Usage + +Once the server is running, open your browser to: +- http://localhost:8080/ + +The server will serve: +- `index.html` - Main HTML page +- `hello.js` - JavaScript loader for WASM +- `hello.wasm` - WebAssembly binary module +- `hello.wat` - WebAssembly text format (for reference) + +## Files + +- **server.go** - Go web server with WASM MIME type support +- **index.html** - HTML page that loads the WASM module +- **hello.js** - JavaScript glue code to instantiate and run WASM +- **hello.wasm** - Compiled WebAssembly binary +- **hello.wat** - WebAssembly text format source + +## Building WASM Files + +### From WAT (WebAssembly Text Format) + +```bash +# Install wabt tools +sudo apt install wabt + +# Compile WAT to WASM +wat2wasm hello.wat -o hello.wasm + +# Disassemble WASM back to WAT +wasm2wat hello.wasm -o hello.wat +``` + +### From Go (using TinyGo) + +```bash +# Install TinyGo +wget https://github.com/tinygo-org/tinygo/releases/download/v0.31.0/tinygo_0.31.0_amd64.deb +sudo dpkg -i tinygo_0.31.0_amd64.deb + +# Create Go program +cat > main.go << 'EOF' +package main + +import "fmt" + +func main() { + fmt.Println("Hello from Go WASM!") +} +EOF + +# Compile to WASM +tinygo build -o main.wasm -target=wasm main.go + +# Get the WASM runtime helper +cp $(tinygo env TINYGOROOT)/targets/wasm_exec.js . +``` + +## Browser Console + +Open your browser's developer console (F12) to see the output from the WASM module. + +The `hello.wasm` module should print "Hello, World!" to the console. + +## CORS Headers + +The server includes CORS headers to allow: +- Cross-origin requests during development +- Loading WASM modules from different origins + +This is useful when developing and testing WASM modules. diff --git a/pkg/wasm/hello.js b/pkg/wasm/hello.js new file mode 100644 index 0000000..0a34482 --- /dev/null +++ b/pkg/wasm/hello.js @@ -0,0 +1,18 @@ +const memory = new WebAssembly.Memory({ initial: 1 }); + +const log = (offset, length) => { + const bytes = new Uint8Array(memory.buffer, offset, length); + const string = new TextDecoder('utf8').decode(bytes); + + console.log(string); +}; + +(async () => { + const response = await fetch('./hello.wasm'); + const bytes = await response.arrayBuffer(); + const { instance } = await WebAssembly.instantiate(bytes, { + env: { log, memory } + }); + + instance.exports.hello(); +})(); diff --git a/pkg/wasm/index.html b/pkg/wasm/index.html new file mode 100644 index 0000000..3b93a9f --- /dev/null +++ b/pkg/wasm/index.html @@ -0,0 +1,10 @@ + + + + + Hello, World! in WebAssembly + + + + + diff --git a/pkg/wasm/server.go b/pkg/wasm/server.go new file mode 100644 index 0000000..dfa6446 --- /dev/null +++ b/pkg/wasm/server.go @@ -0,0 +1,48 @@ +package main + +import ( + "flag" + "fmt" + "log" + "net/http" + "path/filepath" +) + +func main() { + port := flag.Int("port", 8080, "Port to serve on") + dir := flag.String("dir", ".", "Directory to serve files from") + flag.Parse() + + // Create file server + fs := http.FileServer(http.Dir(*dir)) + + // Wrap with MIME type handler for WASM files + http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + // Set correct MIME type for WebAssembly files + if filepath.Ext(r.URL.Path) == ".wasm" { + w.Header().Set("Content-Type", "application/wasm") + } + + // Set CORS headers to allow cross-origin requests (useful for development) + w.Header().Set("Access-Control-Allow-Origin", "*") + w.Header().Set("Access-Control-Allow-Methods", "GET, OPTIONS") + w.Header().Set("Access-Control-Allow-Headers", "Content-Type") + + // Handle OPTIONS preflight requests + if r.Method == "OPTIONS" { + w.WriteHeader(http.StatusOK) + return + } + + fs.ServeHTTP(w, r) + }) + + addr := fmt.Sprintf(":%d", *port) + log.Printf("Starting WASM server on http://localhost%s", addr) + log.Printf("Serving files from: %s", *dir) + log.Printf("\nOpen http://localhost%s/ in your browser", addr) + + if err := http.ListenAndServe(addr, nil); err != nil { + log.Fatal(err) + } +}