[Go] WASM ๋น๋ํ๊ธฐ
go๋ wasm์ ๊ทธ๋ญ์ ๋ญ ์ง์ํ๋ ํธ์ด๋ค.
์ฑ๋ฅ์ด ํน์ถ๋๊ฑฐ๋ ์ง์ ์์ค์ด ์์ฒญ ์ข์๊ฑด ์๋๋ฐ, ๋ธ๋ผ์ฐ์ ์์ ๊ตฌํํ๊ธฐ ๋๊ฐํ ๊ฒ๋ค์ ๋ํํ ๋ ๊ฐ๋์ ์ธ๋งํ ๊ฒ์ด๋ค.
์ธ๋ถ ์ข ์์ฑ์ด ๋ฐ๋ก ํ์ํ์ง ์๋ค.
js ๋ณธ๋ ๊ฐ์ ธ์ค๊ธฐ
wasm์ ํ๊ณ์, ๋
๋ฆฝ์ ์ผ๋ก๋ ์ฌ์ฉ์ด ๋ถ๊ฐ๋ฅํ๊ณ js๋ฅผ ๊ฑฐ์ณ์๋ง ์ฌ์ฉ์ด ๊ฐ๋ฅํ๋ค.
์๋์ ๊ฐ์ ํน์ํ ๊ฒฝ๋ก์ ์ค๋น๋์ด์๋ wasm ๋ณธ๋ ์ฝ๋๊ฐ ์๋ค. ๊ทธ๊ฑธ ๋ณต์ฌํด์ ๊ฐ์ ธ์จ๋ค.
cp $(go env GOROOT)/misc/wasm/wasm_exec.js .
๋ด์ฉ์ ์ด๋ฐ๋ฐ, ๊ตณ์ด ๋ณผ ํ์๋ ์๋ค. ๊ณ ์น ์ผ๋ ์๊ณ
Go ์ฝ๋ ์์ฑํ๊ธฐ
์ด์ wasm์ ์์ฑํ ์ฝ๋๋ฅผ ์์ฑํด๋ณด๊ฒ ๋ค.
๊ฐ๋จํ๊ฒ ๋ง์
ํจ์๋ง ํ๋ ์ถ๊ฐํด์ ๋๋ ค๋ณด๋ ค ํ๋ค.
์ฐ์ syscall/js๋ผ๋ ๊ธฐ๋ณธ ํจํค์ง๋ฅผ importํ๋ค.
์ด๊ฑด ํน์ ํ๊ฒ์์๋ง ์ฌ์ฉํ ์ ์๋ ํน์ ํจํค์ง๋ค. ๋นจ๊ฐ์ค์ ๊ทธ๋์ ๋จ๋๊ฑฐ๋ค.
๊ทธ๋ฆฌ๊ณ js์์ ์ฌ์ฉํ ๋ง์ ํจ์๋ฅผ ํ๋ ๋ง๋ค์ด์คฌ๋ค.
js์ ๋ด๋ณด๋ผ ํจ์๋ค์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ด๋ฌํ ํจ์ ์๊ทธ๋์ฒ๋ฅผ ๊ฐ์ ธ์ผ ํ๋ค.
์ฒซ๋ฒ์งธ ์ธ์๋ ํจ์ ์์ฒด์ this ์ปจํ
์คํธ๊ณ , ๋๋จธ์ง๊ฐ ๋งค๊ฐ๋ณ์๋ค.
์ฌ๊ธฐ์๋ Int๋ก ๋ณํํ๋ค์์ ๋ง์
์ ์ํํ๊ณ , ๋ฐํํด์ฃผ๋๋ก ํ๋ค.
๊ทธ๋ฆฌ๊ณ ์ ํจ์๋ฅผ ๋ช ์์ ์ผ๋ก js ์ ์ญ ์ํ์ ์ถ๊ฐํด์ค์ผ ํ๋ค.

main ํจ์๋ง ์ถ๊ฐํด์ฃผ๋ฉด ๋์ด๋ค.
์ฌ๊ธฐ์ ์ด๊ธฐํ ๊ด๋ จ ๋ก์ง๋ค์ ํ ๋นํ ์๋ ์๊ณ , ํจ์ ๋ฑ๋ก๋ ์ฌ๊ธฐ์ ํ๋ค.
๊ทธ๋ฆฌ๊ณ ์ด main ํจ์๋ ์ข
๋ฃ๋์ง ์์์ผ ํ๊ธฐ ๋๋ฌธ์ ์ฑ๋๋ก ๋ธ๋ฝ์ ๊ฑธ์ด์ค๋ค.
main์ด ๋๋๋ฉด ์ฌ๊ธฐ์ ๊ตฌํํ ํจ์๋ฅผ ์ฌ์ฉํ ์๊ฐ ์๋๋ผ. IPC ์คํ์ผ์ธ๊ฑฐ๊ฐ๋ค.
์ ์ฒด ์ฝ๋๋ค.
// main.go
package main
import (
"log"
"syscall/js"
)
//export add
func add(this js.Value, args []js.Value) any {
result := args[0].Int() + args[1].Int()
return js.ValueOf(result)
}
func registerCallbacks() {
js.Global().Set("add", js.FuncOf(add))
}
func main() {
waiter := make(chan struct{}, 0)
println("Hello, WASM!")
log.Println("WASM Go Initialized")
registerCallbacks()
<-waiter
}html๊ณผ ์ฌ์ฉํด๋ณด๊ธฐ
์ฐ์ wasm ๋น๋๋ฅผ ํ๋ค.
์ด๋ฐ์์ผ๋ก ์ต์
์ ์ฃผ๋ฉด ๋๋ค.
GOOS=js GOARCH=wasm go build -o static/main.wasm cmd/main.go
๊ฒฐ๊ณผ๋ฌผ๋ค์ ํ๊ณณ์ ๋ชฐ์๋ฃ๊ณ

๊ฐ๋จํ ์ ์ ์๋ฒ ํ๋ ๋ง๋ค๊ณ
const express = require("express");
const path = require("path");
const app = express();
const port = 8000;
const root = path.join(__dirname, "static");
app.get("*", (req, res) => {
const filePath = path.join(root, req.url);
res.sendFile(filePath, (err) => {
if (err) {
res.status(404).send("Not Found");
}
});
});
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}/`);
});
๋ธ๋ผ์ฐ์ ์ฝ๋๋ ์ด๋ ์งฐ๋ค.
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Go+Wasm</title>
<script src="wasm_exec.js"></script>
<script>
const go = new Go();
WebAssembly.instantiateStreaming(fetch("main.wasm"), go.importObject)
.then((wasmModule) => {
// ์น ์ด์
๋ธ๋ฆฌ ๋ก๋ฉ
go.run(wasmModule.instance);
// ์น ์ด์
๋ธ๋ฆฌ์์ ์ ๊ณตํ๋ add ํจ์ ํธ์ถ
console.log(wasmModule.instance.exports);
});
</script>
</head>
<body></body>
</html>
js ๋ณธ๋ importํ ๋ค์์ ์ ๋ฐ ์์ผ๋ก ์ด๊ธฐํ๋ฅผ ํด์ฃผ๋ฉด ๋๋ค.
๊ทธ๋ฆฌ๊ณ ์คํํด๋ณด๋ฉด

์ด๋ฐ์์ผ๋ก ๊ฐ๋ค์ธ ์ ์์ ๊ฒ์ด๋ค.
