์ด๋ค ๊ฒฝ์ฐ๋ฅผ ๋ง๋ฉ๋๋ค.
ํ๋๋ ์ ์ฐฉ์ ์ฝ๋๊ฐ ํ์ํฉ๋๋ค.
int addThree(uint8_t *buf, int len) {
uint8_t *item;
uint8_t *end = buf + len;
for (item = buf; item<end; item++) {
*item += 3;
}
return 0;
}
๊ทธ๋ฌ๋ ๊ฐ๋จํ ๋ฐฉ๋ฒ์ผ๋ก .wasm ํ์ผ๋ง ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค.
int adder (int a, int b) {
return a + b;
}
๊ทธ๋์, ๊ธ๋ฃจ ์ฝ๋๋ ๋ฌด์์ํฉ๋๊น? ๋ฌธ์๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค.
๋ฌด์จ ๊ธ๋ฃจ ์ฝ๋? ์ผ๋ถ Wasm ํํ ๋ฆฌ์ผ์์ ๋ ๊ฐ์ง ๊ธฐ๋ฅ( addThree()
๋ฐ adder()
)์ ๋ณต์ฌํ ๊ฒ ๊ฐ์ต๋๋ค. ๊ทธ๊ฒ๋ค์ ์ค์ ๋ก ๋ง์ ์ผ์ ํ์ง ์๋ ๋จ์ํ ์์ ํจ์๋ก ๋ณด์ด๋ฉฐ, ๋จ์ํ Wasm ํํ ๋ฆฌ์ผ์ ๋ณด์ฌ์ฃผ๊ธฐ๋ง ํ๋ฉด ๋ฉ๋๋ค. ์ด๋ฌํ ํจ์ ์ค ์ด๋ ๊ฒ๋ ๋ณต์กํ ์๋ช
์ ๊ฐ๊ณ ์์ง ์์ผ๋ฉฐ ๊ธ๋ฃจ ์ฝ๋ ์์ด ํธ์ถํ ์ ์์ด์ผ ํฉ๋๋ค.
ํ์ง๋ง, ๊ทธ๊ฒ์ ๋ด ์์ ์ด ์๋๋๋ค. ์ผ๋ถ ๋ฌธ์์์ ๋ค์๊ณผ ๊ฐ์ด ์ค๋ช ํฉ๋๋ค.
์ฅ๊ธฐ์ ์ผ๋ก ์ ํ์ด ์ง์ ๋ ๊ฐ์ฒด์ GC๊ฐ ์๋ wasm์ด ๋์์ด ๋ ์ ์์ต๋๋ค. ๊ทธ๊ฒ ์ฌ๊ธฐ์ ๋งํ๋ ๊ฑด๊ฐ์?
๊ทธ๋ ์ง ์์ผ๋ฉด ๋จ๊ธฐ ๋๋ ์ค๊ธฐ์ ์ผ๋ก ๊ทธ ๊ธ๋ฃจ ์ฝ๋๋ฅผ ์ด๋ป๊ฒ ์ ๊ฑฐํ ์ ์๋์ง ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. C/C++๋ฅผ JS์ฒ๋ผ ๋ณด์ด๊ฒ ๋ง๋๋ ์์ ํ์ฑํ๋ ค๋ฉด ๋ง์ ์์ ์ด ํ์ํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ๊ธ๋ฃจ ์ฝ๋์๋ C ๋ฌธ์์ด์ JS ๋ฌธ์์ด๋ก ๋๋ ๊ทธ ๋ฐ๋๋ก ๋ณํํ๋ ๋ฉ์๋๊ฐ ํฌํจ๋์ด์ผ ํฉ๋๋ค. C++ ์์ค์์ JS์์ C++ ํด๋์ค ํ์ฅ์ ์ง์ํ๊ณ JS์์ ๊ฐ์ ๋ฉ์๋๋ฅผ ๊ตฌํํ๋ ค๋ฉด ์๋นํ ํด์ปค๊ฐ ํ์ํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ผ๋ฐ์ ์ผ๋ก JS๋ฅผ ํตํด wasm์์ ์น API์ ์ก์ธ์คํ๋ ค๋ฉด ๋ง์ ์ ์ฐฉ์ ๊ฐ ํ์ํฉ๋๋ค.
๋ค๋ฅธ ์ฌ๋:
Emscripten์ ์ ๊ณต๋ ํ ํ๋ฆฟ์ ์ด๋ฏธ ํฌํจ๋์ด ์๋ ๋ฉ๋ชจ๋ฆฌ ํ ๋น, ๋ฉ๋ชจ๋ฆฌ ๋์ ๋ฐ ๊ธฐํ ์ฌ๋ฌ ๋ฌธ์ ๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํด ๋ค์ํ JavaScript "์ ์ฐฉ์ " ์ฝ๋๊ฐ ํ์ํฉ๋๋ค. ์ง์ ์์ฑํ๋ ๊ฒ๋ณด๋ค ์ฌ์ฉํ๋ ๊ฒ์ด ๋ ์ฝ์ต๋๋ค.
๊ฐ๋จํ C/C++ ์ฝ๋๋ฅผ ๋ง๋๋ฉด wasm์ ์ปดํ์ผํ๊ณ export.xxxFn()
์ฌ์ฉํ์ฌ ์ฝ๊ฒ ์ฌ์ฉํ ์ ์์ต๋๋ค.
int adder (int a, int b) {
return a + b;
}
๋ฒํผ๋ฅผ ์ฌ์ฉํ๋ ์ฝ๋๋ฅผ ์ฌ์ฉํ ๋ ๊ธ๋ฃจ ์ฝ๋๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ์ ํธํฉ๋๋ค.
# C/C++
int addThree(uint8_t *buf, int len) {
uint8_t *item;
uint8_t *end = buf + len;
for (item = buf; item<end; item++) {
*item += 3;
}
return 0;
}
# deal with buffer in JS
...
let dataHeap = new Uint8Array(Module.HEAPU8.buffer, dataPtr, nDataBytes);
dataHeap.set(new Uint8Array(buffer_pcm.buffer));
...
๋ฐ๋ผ์ Buffer๋ฅผ WASM์ผ๋ก ์ ์กํ ๋ ๋ฉ๋ชจ๋ฆฌ ํ ๋น, ๋ฉ๋ชจ๋ฆฌ ๋์ ๋ฐ ๊ธฐํ ์ฌ๋ฌ ๋ฌธ์ ๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํด ๊ธ๋ฃจ ์ฝ๋๊ฐ ํ์ํ๋ค๋ ๊ฒฐ๋ก ์ ๋ด๋ฆด ์ ์์ต๋๊น?
์์ ์ฃผ์์ ์ค๋ช ๋ ๊ธ๋ฃจ ์ฝ๋๋ Emscripten์ด ์์ฑํ๋ JavaScript ๋ก๋์ ๋๋ค. ์ฃผ์์ด ๋งํ๋ ๊ฒ๊ณผ ์ ํํ ์ผ์นํฉ๋๋ค. JS์ C++ ๋ฐ์ดํฐ ํํ(์: ๋ฌธ์์ด) ์ฌ์ด, ๊ทธ๋ฆฌ๊ณ ์๋ก ๋ค๋ฅธ ๊ฐ์ฒด ํํ(์ฆ, C++ ๊ฐ์ฒด์ ๋ํ JS ํ๋ก์ ๊ฐ์ฒด ์์ฑ) ๊ฐ์ ๋ณํํฉ๋๋ค. ๋ํ ํ์ํ ํ์ํ๋ ๋ฐฐ์ด์ ๋ง๋ญ๋๋ค.
์๋ค์ํผ, ์์ ๋ก ์ฌ์ฉํ ๋ ํจ์์ ๊ฐ์ ๊ฐ๋จํ ๊ฒฝ์ฐ์๋ Emscripten ๋ก๋๋ฅผ ์๋ตํ ์ ์์ต๋๋ค. ๋ ๋ค ๋ณต์กํ ๊ธ๋ฃจ ์ฝ๋๊ฐ ํ์ํ์ง ์์ต๋๋ค. ๊ฐ๊ฐ์ Wasm ํ์ผ์ ๋ก๋ํ๊ธฐ ์ํด JS ํ์ผ๋ง ์์ผ๋ฉด ๋ฉ๋๋ค(๋ ๋ฒ์งธ ์์์ addThree์ wasm ํ์ผ์ Uint8Array๋ ์์ฑํด์ผ ํจ).
๋ง์ง๋ง์ผ๋ก, ๋ฉ๋ชจ๋ฆฌ ํ ๋น์ musl์ malloc ๋ณต์ฌ๋ณธ์ ํฌํจํด์ผ ํ๋ Wasm ์ฝ๋์ ์ํด ์ฒ๋ฆฌ๋ฉ๋๋ค. ๋ฉ๋ชจ๋ฆฌ ๋์๋ ์์ ์ ๋ง์น ํ C/C++ ์ฝ๋์์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํด์ ํจ์ผ๋ก์จ ํ์ค ๋ฐฉ์์ผ๋ก ํผํ ์ ์์ต๋๋ค. ์ฌ๊ธฐ์ Wasm์ด ์๊ตฌํ๋ ํน๋ณํ ๊ฒ์ ์์ต๋๋ค.
๊ถ๊ทน์ ์ผ๋ก ์ฝ๋๊ฐ ๋ง๋๋ ๊ฒฝ๊ณ ๊ฐ ํธ์ถ(JS์์ C++๋ก, C++์์ JS๋ก)์ ๊ธฐ๋ฐ์ผ๋ก ์ค์ ๋ก ์ฌ์ฉํ ๊ธ๋ฃจ ์ฝ๋๋ง ์์ผ๋ฉด ๋ฉ๋๋ค.
์ด ๋ฌธ์ ๋ ๋ซ์ ์ ์์ต๋๋ค. WebAssembly ๋์์ธ ์์ฒด์ ๋ฒ๊ทธ๋ผ๊ธฐ๋ณด๋ค๋ Emscripten์ ๋ํ ์ง๋ฌธ์ ๋๋ค.
๋งค์ฐ ๊ฐ์ฌํฉ๋๋ค
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
์์ ์ฃผ์์ ์ค๋ช ๋ ๊ธ๋ฃจ ์ฝ๋๋ Emscripten์ด ์์ฑํ๋ JavaScript ๋ก๋์ ๋๋ค. ์ฃผ์์ด ๋งํ๋ ๊ฒ๊ณผ ์ ํํ ์ผ์นํฉ๋๋ค. JS์ C++ ๋ฐ์ดํฐ ํํ(์: ๋ฌธ์์ด) ์ฌ์ด, ๊ทธ๋ฆฌ๊ณ ์๋ก ๋ค๋ฅธ ๊ฐ์ฒด ํํ(์ฆ, C++ ๊ฐ์ฒด์ ๋ํ JS ํ๋ก์ ๊ฐ์ฒด ์์ฑ) ๊ฐ์ ๋ณํํฉ๋๋ค. ๋ํ ํ์ํ ํ์ํ๋ ๋ฐฐ์ด์ ๋ง๋ญ๋๋ค.
์๋ค์ํผ, ์์ ๋ก ์ฌ์ฉํ ๋ ํจ์์ ๊ฐ์ ๊ฐ๋จํ ๊ฒฝ์ฐ์๋ Emscripten ๋ก๋๋ฅผ ์๋ตํ ์ ์์ต๋๋ค. ๋ ๋ค ๋ณต์กํ ๊ธ๋ฃจ ์ฝ๋๊ฐ ํ์ํ์ง ์์ต๋๋ค. ๊ฐ๊ฐ์ Wasm ํ์ผ์ ๋ก๋ํ๊ธฐ ์ํด JS ํ์ผ๋ง ์์ผ๋ฉด ๋ฉ๋๋ค(๋ ๋ฒ์งธ ์์์ addThree์ wasm ํ์ผ์ Uint8Array๋ ์์ฑํด์ผ ํจ).
๋ง์ง๋ง์ผ๋ก, ๋ฉ๋ชจ๋ฆฌ ํ ๋น์ musl์ malloc ๋ณต์ฌ๋ณธ์ ํฌํจํด์ผ ํ๋ Wasm ์ฝ๋์ ์ํด ์ฒ๋ฆฌ๋ฉ๋๋ค. ๋ฉ๋ชจ๋ฆฌ ๋์๋ ์์ ์ ๋ง์น ํ C/C++ ์ฝ๋์์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํด์ ํจ์ผ๋ก์จ ํ์ค ๋ฐฉ์์ผ๋ก ํผํ ์ ์์ต๋๋ค. ์ฌ๊ธฐ์ Wasm์ด ์๊ตฌํ๋ ํน๋ณํ ๊ฒ์ ์์ต๋๋ค.
๊ถ๊ทน์ ์ผ๋ก ์ฝ๋๊ฐ ๋ง๋๋ ๊ฒฝ๊ณ ๊ฐ ํธ์ถ(JS์์ C++๋ก, C++์์ JS๋ก)์ ๊ธฐ๋ฐ์ผ๋ก ์ค์ ๋ก ์ฌ์ฉํ ๊ธ๋ฃจ ์ฝ๋๋ง ์์ผ๋ฉด ๋ฉ๋๋ค.
์ด ๋ฌธ์ ๋ ๋ซ์ ์ ์์ต๋๋ค. WebAssembly ๋์์ธ ์์ฒด์ ๋ฒ๊ทธ๋ผ๊ธฐ๋ณด๋ค๋ Emscripten์ ๋ํ ์ง๋ฌธ์ ๋๋ค.