WASM_C_DEMO

simple flow

flowchart LR

CODE(CODE) --> FILE(.wasm) --> TARGET(WASM RUNTIME)
Loading

emscripten

https://github.com/emscripten-core/emscripten

LLVM-to-JS compiler.

traits

  • wasm이 로드되면 Module가 전역 객체로 브라우저 내에 생성됨. 뭐 잘 이해 안가면 출력해서 확인해보자.
  • export된 함수들은 브라우저 내에서 _를 접두사로 붙여서 호출해야 함.

some cmd

# gen wasm, js
emcc lib/demo.c -s WASM=1 -o public/demo.js

# gen html, wasm, js
emcc lib/demo.c -s WASM=1 -o public/demo.html

# only generate .wasm
emcc lib/demo.c -s WASM=1 -o public/demo.wasm

# optimize level 2 compile. (-O2)
emcc lib/demo.c -s WASM=1 -O2 -o public/demo.js

# --post-js, --pre-js
emcc lib/demo.c -s WASM=1 --post-js public/post.js --pre-js public/pre.js -o public/demo.js

# EXPORTED_FUNCTIONS
emcc lib/demo.c -s WASM=1 -s EXPORTED_FUNCTIONS="['_getNum', '_main']"  --post-js public/post.js --pre-js public/pre.js -o public/demo.js

# EXPORTED_RUNTIME_METHODS
emcc lib/demo.c -s WASM=1 -s EXPORTED_FUNCTIONS="['_getNum', '_main', '_getDoubleNum', '_greet']" -s EXPORTED_RUNTIME_METHODS='["cwrap", "ccall"]' --post-js public/post.js --pre-js public/pre.js -o public/demo.js

# TOTAL_MEMORY=64MB
emcc lib/demo.c -s WASM=1 -s EXPORTED_FUNCTIONS="['_getNum', '_main', '_getDoubleNum', '_greet']" -s EXPORTED_RUNTIME_METHODS='["cwrap", "ccall"]' -s TOTAL_MEMORY=64MB  --post-js public/post.js --pre-js public/pre.js -o public/demo.js

mem view

TOTAL_MEMORY로 특정 용량을 설정한 후 wasm을 빌드해서 module을 까보면 각 메모리를 단위별로 끊어볼 수 있어 비트 연산이 편함.

  • HEAP8, HEAP16, HEAP32
  • HEAPF32, HEAPF64
  • HEAPU8, HEAPU16, HEAPU32

preamble.js

https://emscripten.org/docs/api_reference/preamble.js.html

C 코드와의 연결을 위한 js 헬퍼 함수들. emcc로 컴파일 시 자동으로 추가된다. (버전 따라 동작이 좀 다른 듯)

ccall, cwrap이 대표적이며, 그 외의 다양한 helper 함수들이 존재한다.

ccall(ident, returnType, argTypes, args, opts)

ccall('getNum')
ccall('greet', 'string')
ccall('getDoubleNum', 'number', ['number'], [12])
ccall('greet', 'string', ['string'], ['darren'])

emscripten.h

https://emscripten.org/docs/api_reference/emscripten.h.html

etc

browser WASM API 를 통해서 js 함수를 wasm에서 가져다 사용하는 방법이 있지만, emcc에서는 해당 방식이 WASM의 본 의도와 맞지 않다고 생각. (emscripten.h를 통해서 사용하는 것이 더 좋다고 여기는 듯)