1

emscripten uses the LLVM compiler. emscripten official documentation

Environmental requirements

  • Python 2.7.12+, 3 will also work.
  • mime-type The media type, application/wasm, can be verified by the http header.

Install

# 下载 emsdk 仓库
git clone https://github.com/emscripten-core/emsdk.git && cd emsdk

# 下载并安装 sdk
./emsdk install latest

# 激活最新 sdk
./emsdk activate latest

# 激活终端环境变量
source ./emsdk_env.sh

can also be added to environment variables

# emsdk
export PATH=$PATH:$YOUR_DIR/emsdk
export PATH=$PATH:$YOUR_DIR/emsdk/node/14.18.2_64bit/bin
export PATH=$PATH:$YOUR_DIR/emsdk/upstream/emscripten

verify

emsdk list

A simple wasm program

calculate_prime.c

#ifdef __EMSCRIPTEN__
    #include <emscripten.h>
#endif
#include <stdlib.h>
#include <stdio.h>

int IsPrime(int value) {
  int i;
  for (i = 2; i < value; i++) {
    if (value % i == 0) {
      return 0;
    }
  }
  return 1;
}
int main(int argc, char **argv) {
  int start = 0;
  int end = 100;

  printf("prime number between %d and %d\n", start, end);

  for (int i = start; i < end; i++) {
    if (IsPrime(i)) {
      printf("%d is prime\n", i);
    }
  }
  return 0;
}

</div>
</div>

Compile see the result

emcc calculate_prime.c -o html_template.html

form three files

html_template.html
html_template.js
html_template.wasm

html mainly contains references and instantiations of wasm . Run through web API and emsdk through the tools provided by js .

Of course, only js file can be generated.

emcc calculate_prime.c -o js_plumbing.js

makefile

js_plumbing.js
js_plumbing.wasm

The generated wasm file is a binary file, we can read it by converting wasm to wat .

# https://github.com/webassembly/wabt
wasm2wat js_plumbing.wasm -o js_plumbing.wat

Open it and you will see a code snippet like this. ( how to read wasm? )

(module
  (type (;0;) (func (param i32 i32 i32) (result i32)))
  (type (;1;) (func (param i32) (result i32)))
  (type (;2;) (func (result i32)))
  (type (;3;) (func (param i32)))

wasm interacts with javascript

side_module.c

int Increment(int x) {
  return x + 1;
}

compile

emcc side_module.c -s SIDE_MODULE=2 -O1 -s EXPORTED_FUNCTIONS=\["_Increment"\] -o side_module.wasm
  • -s SIDE_MODULE=2 : Compile the code as a submodule and emcc will not include the standard library of C in the generated module
  • Optimization flag -O1 , default -O0 . -O0 kept extraneous functions; -O1 did tree sharking ; -O2 compressed and tree sharking
  • -s EXPORTED_FUNCTIONS=['_Increment'] specifies Increment as an export function, and needs to add _ in front, allowing multiple.
  • *.wasm suffix means that only webAssembly file is generated.

index.js to load wasm

const wasmBinaryFile = 'side_module.wasm'

/**
 * WebAssembly.Memory
 * 包含内存、表、全局变量、函数引用等
 */
const env = {
    '__table_base': 0,
    'memory': new WebAssembly.Memory({ initial: 256, maximum: 256 }),
    '__memory_base': 1024,
};

WebAssembly.instantiateStreaming(
    fetch(wasmBinaryFile),
    {env},
).then(result => {
    const increment = result.instance.exports.Increment;
    
    console.log('get wasm export function:', increment);
    increment && console.log(increment(17).toString())
})

donggg
203 声望584 粉丝

> github