exp: client host and demo app using wasm/wasmtime
diff --git a/apps/client/hello/main.go b/apps/client/hello/main.go
new file mode 100644
index 0000000..21cb8dd
--- /dev/null
+++ b/apps/client/hello/main.go
@@ -0,0 +1,97 @@
+package main
+
+import (
+ "fmt"
+ "os"
+ "syscall"
+ "unsafe"
+
+ "github.com/ahmetalpbalkan/go-cursor"
+ "github.com/bytecodealliance/wasmtime-go"
+)
+
+type WindowSize struct {
+ Row uint16
+ Col uint16
+ Xpixel uint16
+ Ypixel uint16
+}
+
+func check(err error) {
+ if err != nil {
+ panic(err)
+ }
+}
+
+func main() {
+ store := wasmtime.NewStore(wasmtime.NewEngine())
+ linker := wasmtime.NewLinker(store.Engine)
+ err := linker.DefineWasi()
+ check(err)
+ wasiConfig := wasmtime.NewWasiConfig()
+ store.SetWasi(wasiConfig)
+ err = linker.FuncNew(
+ "env",
+ "hello",
+ wasmtime.NewFuncType(
+ []*wasmtime.ValType{wasmtime.NewValType(wasmtime.KindI32)},
+ []*wasmtime.ValType{}),
+ func(c *wasmtime.Caller, args []wasmtime.Val) ([]wasmtime.Val, *wasmtime.Trap) {
+ if len(args) != 1 {
+ check(fmt.Errorf("%+v", args))
+ }
+ id := args[0].I32()
+ fmt.Printf("Hello %d\n", id)
+ return []wasmtime.Val{}, nil
+ })
+ check(err)
+ err = linker.FuncWrap("env", "cursorHide", func() {
+ fmt.Print(cursor.Hide())
+ })
+ check(err)
+ err = linker.FuncWrap("env", "cursorShow", func() {
+ fmt.Print(cursor.Show())
+ })
+ check(err)
+ err = linker.FuncWrap("env", "cursorSet", func(x, y int32) {
+ fmt.Print(cursor.MoveTo(int(x), int(y)))
+ })
+ check(err)
+ err = linker.FuncWrap("env", "clearScreen", func() {
+ fmt.Print(cursor.ClearEntireScreen())
+ })
+ check(err)
+ err = linker.FuncWrap("env", "flush", func() {
+ // fmt.Print(cursor.Flush())
+ })
+ check(err)
+ err = linker.FuncWrap("env", "draw", func(x, y int32) {
+ fmt.Printf("\x1b7\x1b[%d;%df%s\x1b8", x, y, ".")
+ })
+ check(err)
+ err = linker.FuncWrap("env", "getSize", func() (int32, int32, int32, int32) {
+ var ws WindowSize
+ retCode, _, errno := syscall.Syscall(syscall.SYS_IOCTL,
+ uintptr(syscall.Stdin),
+ uintptr(syscall.TIOCGWINSZ),
+ uintptr(unsafe.Pointer(&ws)))
+ if int(retCode) == -1 {
+ panic(errno)
+ }
+ return int32(ws.Row), int32(ws.Col), int32(ws.Xpixel), int32(ws.Ypixel)
+ })
+ check(err)
+
+ wasm, err := os.ReadFile("call_host/target/wasm32-wasi/debug/call_host.wasm")
+ check(err)
+ module, err := wasmtime.NewModule(store.Engine, wasm)
+ check(err)
+ instance, err := linker.Instantiate(store, module)
+ check(err)
+ run := instance.GetFunc(store, "run")
+ if run == nil {
+ panic("not a function")
+ }
+ _, err = run.Call(store)
+ check(err)
+}