hello world in wat

This commit is contained in:
2025-11-14 14:37:36 +00:00
parent 1d9a6903b8
commit 9fb976703d
5 changed files with 184 additions and 1 deletions

102
pkg/wasm/README.md Normal file
View File

@@ -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.

18
pkg/wasm/hello.js Normal file
View File

@@ -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();
})();

10
pkg/wasm/index.html Normal file
View File

@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello, World! in WebAssembly</title>
</head>
<body>
<script src="hello.js" type="module"></script>
</body>
</html>

48
pkg/wasm/server.go Normal file
View File

@@ -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)
}
}