diff --git a/Makefile b/Makefile index ff5be07e8f3586871fe705ee0c5506e603813caf..c45f7b3764954fd1d8936d62cf6af4ca6211696b 100644 --- a/Makefile +++ b/Makefile @@ -12,8 +12,12 @@ build-wasm: win-exe-icon: windres -o main_rc_windows.syso main.rc -arduino: +arduino-run: + go run main.go -target=arduino arduino.wa + +arduino-build: go run main.go build -target=arduino arduino.wa wat2wasm a.out.wat -o a.out.wasm + xxd -i a.out.wasm > app.wasm.h clean: diff --git a/arduino.wa b/arduino.wa index c2440ee76ec1685b52315138fd9dd79b22715501..4e42b07cd825cb7501a6739735454ecf925bb8bd 100644 --- a/arduino.wa +++ b/arduino.wa @@ -6,7 +6,7 @@ var LED = arduino.GetPinLED() fn init() { arduino.PinMode(LED, 1) - arduino.Println("Wa is running 😎") + arduino.Println("Wa/Arduino is running 😎") } fn main() { diff --git a/internal/app/apputil/wabt_wat2wasm.go b/internal/app/apputil/wabt_wat2wasm.go index f0606000b4644f27c51629a79da4ca58d939c22c..bd0d60712179894a19f060f6950363a681fcb151 100644 --- a/internal/app/apputil/wabt_wat2wasm.go +++ b/internal/app/apputil/wabt_wat2wasm.go @@ -41,8 +41,24 @@ func RunWasm(cfg *config.Config, filename string) (stdoutStderr []byte, err erro r := wazero.NewRuntime(ctx) defer r.Close(ctx) - if _, err = waruntime.WalangInstantiate(ctx, r); err != nil { - return nil, err + switch cfg.WaOS { + case config.WaOS_Arduino: + if _, err = waruntime.ArduinoInstantiate(ctx, r); err != nil { + return nil, err + } + case config.WaOS_Chrome: + if _, err = waruntime.ChromeInstantiate(ctx, r); err != nil { + return nil, err + } + + case config.WaOS_Walang: + if _, err = waruntime.WalangInstantiate(ctx, r); err != nil { + return nil, err + } + case config.WaOS_Wasi: + if _, err = waruntime.WasiInstantiate(ctx, r); err != nil { + return nil, err + } } _, err = r.InstantiateModuleFromBinary(ctx, wasmBytes) diff --git a/internal/app/waruntime/arduino.go b/internal/app/waruntime/arduino.go index b9d51495f47dbe4f7dee43a81533dc0d8a53ecb3..9c10d3f418fbd4c6b505bbf86a04477fcb810a9c 100644 --- a/internal/app/waruntime/arduino.go +++ b/internal/app/waruntime/arduino.go @@ -4,12 +4,62 @@ package waruntime import ( "context" + "fmt" + "time" "github.com/tetratelabs/wazero" "github.com/tetratelabs/wazero/api" "github.com/wa-lang/wa/internal/config" ) -func ArduinoInstantiate(ctx context.Context, rt wazero.Runtime) (api.Module, error) { - return rt.NewHostModuleBuilder(config.WaOS_Arduino).Instantiate(ctx, rt) +func ArduinoInstantiate(ctx context.Context, rt wazero.Runtime) (api.Closer, error) { + startTime := time.Now() + return rt.NewHostModuleBuilder(config.WaOS_Arduino). + NewFunctionBuilder(). + WithFunc(func(ctx context.Context, m api.Module) int32 { + t := time.Now().Sub(startTime).Milliseconds() + fmt.Printf("arduino.millis(): %v\n", t) + return int32(t) + }). + WithParameterNames(). + Export("millis"). + NewFunctionBuilder(). + WithFunc(func(ctx context.Context, ms uint32) { + fmt.Printf("arduino.delay(%d)...\n", ms) + time.Sleep(time.Millisecond * time.Duration(ms)) + }). + WithParameterNames("ms"). + Export("delay"). + NewFunctionBuilder(). + WithFunc(func(ctx context.Context, pin, mode int32) { + if mode == 0 { + fmt.Printf("arduino.pinMode(%d, %s)\n", pin, "LOW") + } else { + fmt.Printf("arduino.pinMode(%d, %s)\n", pin, "HIGH") + } + }). + WithParameterNames("pin", "mode"). + Export("pinMode"). + NewFunctionBuilder(). + WithFunc(func(ctx context.Context, pin, value int32) { + fmt.Printf("arduino.digitalWrite(%d, %d)\n", pin, value) + }). + WithParameterNames("pin", "value"). + Export("digitalWrite"). + NewFunctionBuilder(). + WithFunc(func(ctx context.Context) int32 { + const pin = 13 + fmt.Printf("arduino.getPinLED(): %v\n", pin) + return pin + }). + WithParameterNames(). + Export("getPinLED"). + NewFunctionBuilder(). + WithFunc(func(ctx context.Context, m api.Module, ptr, len uint32) { + bytes, _ := m.Memory().Read(ctx, ptr, len) + fmt.Printf("arduino.print(%q)\n", string(bytes)) + }). + WithParameterNames("ptr", "len"). + Export("print"). + Instantiate(ctx, rt) } diff --git a/internal/app/waruntime/chrome.go b/internal/app/waruntime/chrome.go index 465e66928e6f2d9ee8ccf277d5d0d435bebc0aaa..09a77e0ce9a07ad280b57612122be36fc5fb1a8d 100644 --- a/internal/app/waruntime/chrome.go +++ b/internal/app/waruntime/chrome.go @@ -10,6 +10,6 @@ import ( "github.com/wa-lang/wa/internal/config" ) -func ChromeInstantiate(ctx context.Context, rt wazero.Runtime) (api.Module, error) { +func ChromeInstantiate(ctx context.Context, rt wazero.Runtime) (api.Closer, error) { return rt.NewHostModuleBuilder(config.WaOS_Chrome).Instantiate(ctx, rt) } diff --git a/internal/app/waruntime/walang.go b/internal/app/waruntime/walang.go index 1c363afdb7b4ba7e89c4e5ec3e666c30aec973eb..9f90e750448b0d954c9fed60c9f4f63acfacf106 100644 --- a/internal/app/waruntime/walang.go +++ b/internal/app/waruntime/walang.go @@ -12,7 +12,7 @@ import ( const envWalang = "wa_js_env" -func WalangInstantiate(ctx context.Context, rt wazero.Runtime) (api.Module, error) { +func WalangInstantiate(ctx context.Context, rt wazero.Runtime) (api.Closer, error) { return rt.NewHostModuleBuilder(envWalang). NewFunctionBuilder(). WithFunc(func(ctx context.Context, m api.Module, pos, len uint32) { diff --git a/internal/app/waruntime/wasi.go b/internal/app/waruntime/wasi.go index f555e7629f11df339ee86d8eda509f485b00a57b..68c21e2247b46d3d9e31d584816d9188f32939df 100644 --- a/internal/app/waruntime/wasi.go +++ b/internal/app/waruntime/wasi.go @@ -6,9 +6,10 @@ import ( "context" "github.com/tetratelabs/wazero" + "github.com/tetratelabs/wazero/api" "github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1" ) -func WasiInstantiate(ctx context.Context, rt wazero.Runtime) { - wasi_snapshot_preview1.MustInstantiate(ctx, rt) +func WasiInstantiate(ctx context.Context, rt wazero.Runtime) (api.Closer, error) { + return wasi_snapshot_preview1.Instantiate(ctx, rt) } diff --git a/internal/waroot/_waroot/src/runtime/runtime_arduino.wa b/internal/waroot/_waroot/src/runtime/runtime_arduino.wa index 8237592466bfa9112eeaaba2c1b3bcee391531c2..e799a244f2729bd8d2ba46d7075874fc8641a186 100644 --- a/internal/waroot/_waroot/src/runtime/runtime_arduino.wa +++ b/internal/waroot/_waroot/src/runtime/runtime_arduino.wa @@ -1,5 +1,7 @@ # η‰ˆζƒ @2022 凹语言 δ½œθ€…γ€‚δΏη•™ζ‰€ζœ‰ζƒεˆ©γ€‚ +import "syscall/arduino" + var WAOS = "arduino" #wa:linkname $runtime.waPrintI32 @@ -9,4 +11,6 @@ fn waPrintI32(i: i32) {} fn waPrintRune(ch: i32) {} #wa:linkname $runtime.waPuts -fn waPuts(ptr: i32, len: i32) {} +fn waPuts(ptr: i32, len: i32) { + arduino.PrintRawString(ptr, len) +} diff --git a/internal/waroot/_waroot/src/syscall/arduino/arduino.wa b/internal/waroot/_waroot/src/syscall/arduino/arduino.wa index e53e160766cf653403ab868e65dfb2509951b7f7..ae6e542ed09c62a874c4c763b7d2a289559f55a4 100644 --- a/internal/waroot/_waroot/src/syscall/arduino/arduino.wa +++ b/internal/waroot/_waroot/src/syscall/arduino/arduino.wa @@ -10,49 +10,27 @@ var ( ) #wa:import arduino millis -#wa:linkname $waMillis fn Millis() => i32 #wa:import arduino delay -#wa:linkname $waDelay fn Delay(ms: i32) #wa:import arduino pinMode -#wa:linkname $waPinMode fn PinMode(pin, mode: i32) #wa:import arduino digitalWrite -#wa:linkname $waDigitalWrite fn DigitalWrite(pin, value: i32) #wa:import arduino getPinLED -#wa:linkname $waGetPinLED fn GetPinLED() => i32 #wa:import arduino print -#wa:linkname $waPrint -fn Print(s: string) +fn PrintRawString(ptr: i32, len: i32) -#wa:import arduino getGreeting -#wa:linkname $waGetGreeting -fn _getGreeting(buf: *byte, maxlen: i32) - -fn Println(s: string) { - Print(s) - Print("\n") -} - -#wa:linkname $waPrintI32 -fn waPrintI32(i: i32) { - # TODO +fn Print(s: string) { + print(s) } -#wa:linkname $waPrintRune -fn waPrintRune(ch: i32) { - # TODO -} - -#wa:linkname $waPuts -fn waPuts(ptr: i32, len: i32) { - # TODO +fn Println(s: string) { + println(s) }