| giolekva | 0990ccf | 2022-05-13 16:12:38 +0400 | [diff] [blame^] | 1 | package main |
| 2 | |
| 3 | import ( |
| 4 | "fmt" |
| 5 | "os" |
| 6 | "syscall" |
| 7 | "unsafe" |
| 8 | |
| 9 | "github.com/ahmetalpbalkan/go-cursor" |
| 10 | "github.com/bytecodealliance/wasmtime-go" |
| 11 | ) |
| 12 | |
| 13 | type WindowSize struct { |
| 14 | Row uint16 |
| 15 | Col uint16 |
| 16 | Xpixel uint16 |
| 17 | Ypixel uint16 |
| 18 | } |
| 19 | |
| 20 | func check(err error) { |
| 21 | if err != nil { |
| 22 | panic(err) |
| 23 | } |
| 24 | } |
| 25 | |
| 26 | func main() { |
| 27 | store := wasmtime.NewStore(wasmtime.NewEngine()) |
| 28 | linker := wasmtime.NewLinker(store.Engine) |
| 29 | err := linker.DefineWasi() |
| 30 | check(err) |
| 31 | wasiConfig := wasmtime.NewWasiConfig() |
| 32 | store.SetWasi(wasiConfig) |
| 33 | err = linker.FuncNew( |
| 34 | "env", |
| 35 | "hello", |
| 36 | wasmtime.NewFuncType( |
| 37 | []*wasmtime.ValType{wasmtime.NewValType(wasmtime.KindI32)}, |
| 38 | []*wasmtime.ValType{}), |
| 39 | func(c *wasmtime.Caller, args []wasmtime.Val) ([]wasmtime.Val, *wasmtime.Trap) { |
| 40 | if len(args) != 1 { |
| 41 | check(fmt.Errorf("%+v", args)) |
| 42 | } |
| 43 | id := args[0].I32() |
| 44 | fmt.Printf("Hello %d\n", id) |
| 45 | return []wasmtime.Val{}, nil |
| 46 | }) |
| 47 | check(err) |
| 48 | err = linker.FuncWrap("env", "cursorHide", func() { |
| 49 | fmt.Print(cursor.Hide()) |
| 50 | }) |
| 51 | check(err) |
| 52 | err = linker.FuncWrap("env", "cursorShow", func() { |
| 53 | fmt.Print(cursor.Show()) |
| 54 | }) |
| 55 | check(err) |
| 56 | err = linker.FuncWrap("env", "cursorSet", func(x, y int32) { |
| 57 | fmt.Print(cursor.MoveTo(int(x), int(y))) |
| 58 | }) |
| 59 | check(err) |
| 60 | err = linker.FuncWrap("env", "clearScreen", func() { |
| 61 | fmt.Print(cursor.ClearEntireScreen()) |
| 62 | }) |
| 63 | check(err) |
| 64 | err = linker.FuncWrap("env", "flush", func() { |
| 65 | // fmt.Print(cursor.Flush()) |
| 66 | }) |
| 67 | check(err) |
| 68 | err = linker.FuncWrap("env", "draw", func(x, y int32) { |
| 69 | fmt.Printf("\x1b7\x1b[%d;%df%s\x1b8", x, y, ".") |
| 70 | }) |
| 71 | check(err) |
| 72 | err = linker.FuncWrap("env", "getSize", func() (int32, int32, int32, int32) { |
| 73 | var ws WindowSize |
| 74 | retCode, _, errno := syscall.Syscall(syscall.SYS_IOCTL, |
| 75 | uintptr(syscall.Stdin), |
| 76 | uintptr(syscall.TIOCGWINSZ), |
| 77 | uintptr(unsafe.Pointer(&ws))) |
| 78 | if int(retCode) == -1 { |
| 79 | panic(errno) |
| 80 | } |
| 81 | return int32(ws.Row), int32(ws.Col), int32(ws.Xpixel), int32(ws.Ypixel) |
| 82 | }) |
| 83 | check(err) |
| 84 | |
| 85 | wasm, err := os.ReadFile("call_host/target/wasm32-wasi/debug/call_host.wasm") |
| 86 | check(err) |
| 87 | module, err := wasmtime.NewModule(store.Engine, wasm) |
| 88 | check(err) |
| 89 | instance, err := linker.Instantiate(store, module) |
| 90 | check(err) |
| 91 | run := instance.GetFunc(store, "run") |
| 92 | if run == nil { |
| 93 | panic("not a function") |
| 94 | } |
| 95 | _, err = run.Call(store) |
| 96 | check(err) |
| 97 | } |