├── .gitignore
├── package.json
├── packages
├── asm-webpack
│ ├── index.html
│ ├── package.json
│ ├── src
│ │ └── index.js
│ └── wasm
│ │ ├── fibonacci.js
│ │ ├── fibonacci.wasm
│ │ └── fibonacci.wast
├── clang-array
│ ├── .gitignore
│ ├── build.sh
│ ├── index.html
│ ├── readme.md
│ └── src
│ │ └── print_array.c
├── clang-simd
│ ├── .gitignore
│ ├── build.sh
│ ├── index.html
│ ├── lib.js
│ ├── no-simd.html
│ ├── readme.md
│ ├── simd.html
│ └── src
│ │ ├── multiply_arrays.c
│ │ └── multiply_arrays_simd.c
├── clang-thread
│ ├── .gitignore
│ ├── build.sh
│ ├── index.html
│ ├── readme.md
│ └── src
│ │ └── test.c
├── clang
│ ├── index.html
│ ├── package.json
│ ├── readme.md
│ ├── wasm-loader.js
│ └── wasm
│ │ ├── helloworld-dylib.c
│ │ ├── helloworld-dylib.wasm
│ │ ├── helloworld-std.c
│ │ ├── helloworld-std.js
│ │ └── helloworld-std.wasm
├── go
│ ├── Makefile
│ ├── index.html
│ ├── readme.md
│ ├── server
│ ├── src
│ │ ├── main.go
│ │ └── server.go
│ ├── wasm
│ │ └── main.wasm
│ └── wasm_exec.js
├── rust-parcel
│ ├── index.html
│ ├── package.json
│ ├── readme.md
│ ├── src
│ │ └── index.js
│ └── wasm
│ │ ├── add.rs
│ │ └── square.wasm
├── rust-thread
│ ├── .gitignore
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── build.sh
│ ├── index.html
│ ├── readme.md
│ ├── src
│ │ ├── lib.rs
│ │ └── thread.rs
│ └── worker.js
├── rust-wasi-node
│ ├── .gitignore
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── readme.md
│ ├── runtime
│ │ └── index.mjs
│ └── src
│ │ └── lib.rs
├── rust-wasm-bindgen
│ ├── .gitignore
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── index.html
│ ├── package.json
│ ├── readme.md
│ ├── src
│ │ └── index.js
│ ├── wasm
│ │ └── alert.rs
│ └── webpack.config.js
├── rust-wasm-pack
│ ├── .gitignore
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── build.sh
│ ├── index.html
│ ├── readme.md
│ └── src
│ │ └── lib.rs
├── rust-webgl
│ ├── .babelrc
│ ├── .gitignore
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── README.md
│ ├── index.html
│ ├── package.json
│ └── src
│ │ ├── main.rs
│ │ └── webgl.rs
├── rust
│ ├── index.html
│ ├── package.json
│ ├── readme.md
│ ├── wasm-loader.js
│ └── wasm
│ │ ├── math.rs
│ │ └── math.wasm
└── ts-assembly-script
│ ├── index.html
│ ├── package.json
│ ├── readme.md
│ ├── tsconfig.json
│ ├── wasm-loader.js
│ └── wasm
│ ├── fibonacci.ts
│ ├── fibonacci.wasm
│ └── fibonacci.wasm.map
└── readme.md
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
3 | yarn.lock
4 | .cache
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "hello-world-wasm",
3 | "version": "0.0.0",
4 | "license": "MIT",
5 | "devDependencies": {
6 | "http-server": "^0.11.1",
7 | "webpack": "^4.6.0",
8 | "webpack-cli": "^2.0.14"
9 | },
10 | "dependencies": {
11 | "next": "^12.0.2",
12 | "react": "^17.0.2",
13 | "react-dom": "^17.0.2"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/packages/asm-webpack/index.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/asm-webpack/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "asm",
3 | "version": "0.0.0",
4 | "scripts": {
5 | "start": "../node_modules/.bin/serve .",
6 | "build:webpack": "../node_modules/.bin/webpack --mode=development --output-public-path=/dist/",
7 | "build:wasm": "asm2wasm ./wasm/fibonacci.js | grep -v '(import \"env\"' > ./wasm/fibonacci.wast && wat2wasm ./wasm/fibonacci.wast -o ./wasm/fibonacci.wasm",
8 | "build": "npm run build:wasm && npm run build:webpack"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/packages/asm-webpack/src/index.js:
--------------------------------------------------------------------------------
1 | import('../wasm/fibonacci.wasm').then(m => {
2 | document.write(m.fibonacci(5))
3 | })
--------------------------------------------------------------------------------
/packages/asm-webpack/wasm/fibonacci.js:
--------------------------------------------------------------------------------
1 | function () {
2 | "use asm";
3 |
4 | function fibonacci (n) {
5 | n = n | 0;
6 | if (n < 2) {
7 | return 1
8 | }
9 | return (fibonacci(n - 2) | 0) + (fibonacci(n - 1) | 0) | 0
10 | }
11 |
12 | return {
13 | fibonacci: fibonacci,
14 | }
15 | }
--------------------------------------------------------------------------------
/packages/asm-webpack/wasm/fibonacci.wasm:
--------------------------------------------------------------------------------
1 | asm `
fibonacci
2 | AH@A Ak Ak j
--------------------------------------------------------------------------------
/packages/asm-webpack/wasm/fibonacci.wast:
--------------------------------------------------------------------------------
1 | (module
2 | (export "fibonacci" (func $fibonacci))
3 | (func $fibonacci (; 0 ;) (param $n i32) (result i32)
4 | (if
5 | (i32.lt_s
6 | (get_local $n)
7 | (i32.const 2)
8 | )
9 | (return
10 | (i32.const 1)
11 | )
12 | )
13 | (return
14 | (i32.add
15 | (call $fibonacci
16 | (i32.sub
17 | (get_local $n)
18 | (i32.const 2)
19 | )
20 | )
21 | (call $fibonacci
22 | (i32.sub
23 | (get_local $n)
24 | (i32.const 1)
25 | )
26 | )
27 | )
28 | )
29 | )
30 | )
31 |
--------------------------------------------------------------------------------
/packages/clang-array/.gitignore:
--------------------------------------------------------------------------------
1 | *.js
2 | *.wasm
--------------------------------------------------------------------------------
/packages/clang-array/build.sh:
--------------------------------------------------------------------------------
1 | emcc ./src/print_array.c -o print_array.js -O2 -s WASM=1 -s NO_EXIT_RUNTIME=1 -s EXTRA_EXPORTED_RUNTIME_METHODS='["cwrap"]' -s ALLOW_MEMORY_GROWTH=1 -s ERROR_ON_UNDEFINED_SYMBOLS=0
--------------------------------------------------------------------------------
/packages/clang-array/index.html:
--------------------------------------------------------------------------------
1 |
2 |
39 |
--------------------------------------------------------------------------------
/packages/clang-array/readme.md:
--------------------------------------------------------------------------------
1 | # Array manging example with Clang
2 |
3 | ## Build
4 |
5 | ```
6 | sh ./build.sh
7 | ```
8 |
9 | ## Run
10 |
11 | ```
12 | python3 -m http.server
13 | ```
14 |
15 | # License
16 |
17 | MIT @ Jimmy Moon
--------------------------------------------------------------------------------
/packages/clang-array/src/print_array.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | EM_JS(void, iprint, (int n), {
4 | console.log(n);
5 | });
6 |
7 | EM_JS(void, fprint, (float n), {
8 | console.log(n);
9 | });
10 |
11 | EM_JS(void, dprint, (double n), {
12 | console.log(n);
13 | });
14 |
15 | EMSCRIPTEN_KEEPALIVE
16 | void print_iarray(int* in, int size) {
17 | for (int i = 0; i < size; i++) {
18 | iprint(in[i]);
19 | }
20 | }
21 |
22 | EMSCRIPTEN_KEEPALIVE
23 | void print_farray(float* in, int size) {
24 | for (int i = 0; i < size; i++) {
25 | fprint(in[i]);
26 | }
27 | }
28 |
29 | EMSCRIPTEN_KEEPALIVE
30 | void print_darray(double* in, int size) {
31 | for (int i = 0; i < size; i++) {
32 | dprint(in[i]);
33 | }
34 | }
--------------------------------------------------------------------------------
/packages/clang-simd/.gitignore:
--------------------------------------------------------------------------------
1 | *.js
2 | !lib.js
3 | *.wasm
--------------------------------------------------------------------------------
/packages/clang-simd/build.sh:
--------------------------------------------------------------------------------
1 | emcc ./src/multiply_arrays_simd.c -o multiply_arrays_simd.js -O2 -s WASM=1 -s NO_EXIT_RUNTIME=1 -s EXTRA_EXPORTED_RUNTIME_METHODS='["ccall"]' -s ALLOW_MEMORY_GROWTH=1 -s ERROR_ON_UNDEFINED_SYMBOLS=0 -msimd128
2 | emcc ./src/multiply_arrays.c -o multiply_arrays.js -O2 -s WASM=1 -s NO_EXIT_RUNTIME=1 -s EXTRA_EXPORTED_RUNTIME_METHODS='["ccall"]' -s ALLOW_MEMORY_GROWTH=1 -s ERROR_ON_UNDEFINED_SYMBOLS=0
--------------------------------------------------------------------------------
/packages/clang-simd/index.html:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/packages/clang-simd/lib.js:
--------------------------------------------------------------------------------
1 | function TypedArrayToHeap(arr) {
2 | const { name, BYTES_PER_ELEMENT } = arr.constructor;
3 | const prefix = name.charAt(0).replace(/I|B/, '');
4 | const heap = Module[`HEAP${prefix}${BYTES_PER_ELEMENT << 3}`];
5 |
6 | if (!heap) {
7 | throw new Error(`Unknow typed array ${heap}`);
8 | }
9 |
10 | const ptr = Module._malloc(arr.length * BYTES_PER_ELEMENT);
11 | heap.set(arr, ptr / BYTES_PER_ELEMENT);
12 |
13 | return ptr;
14 | }
15 |
16 | function runWasm(func, onload) {
17 | var script = document.createElement('script');
18 | script.onload = onload;
19 | script.src = func + '.js';
20 | document.body.appendChild(script);
21 | }
22 |
23 | function multiply(func, array, arr1, arr2, arr3) {
24 | const size = array.length;
25 | const time = [0, 0];
26 |
27 | time[0] = performance.now();
28 |
29 | Module.ccall(
30 | func,
31 | null,
32 | ['number', 'number', 'number', 'number'],
33 | [arr1, arr2, arr3, size]
34 | );
35 |
36 | time[1] = performance.now();
37 |
38 | return time[1] - time[0];
39 | }
40 |
41 | function setRunResult(func, result) {
42 | const e = document.querySelector('#result');
43 | e.setAttribute('style', 'white-space: pre;');
44 | e.textContent += `${func}: ${result}\r\n`;
45 | }
46 |
47 | function getInt32Value(arr, index = 0) {
48 | const startPtr = arr / Int32Array.BYTES_PER_ELEMENT;
49 | return arr + index;
50 | }
51 |
52 | function subInt32Array(arr, begin = 0, end = undefined) {
53 | const startPtr = arr / Int32Array.BYTES_PER_ELEMENT;
54 | return new Int32Array(HEAP32.subarray(startPtr + begin, startPtr + (end ? end : arr.length)));
55 | }
56 |
--------------------------------------------------------------------------------
/packages/clang-simd/no-simd.html:
--------------------------------------------------------------------------------
1 |
2 | Multiply without SIMD
3 |
4 |
5 |
19 |
20 |
--------------------------------------------------------------------------------
/packages/clang-simd/readme.md:
--------------------------------------------------------------------------------
1 | # SIMD example with Clang
2 |
3 | > Working SIMD example from https://v8.dev/features/simd
4 |
5 | ## Build
6 |
7 | ```
8 | sh ./build.sh
9 | ```
10 |
11 | ## Run
12 |
13 | ```
14 | python3 -m http.server
15 | ```
16 |
17 | # License
18 |
19 | MIT @ Jimmy Moon
--------------------------------------------------------------------------------
/packages/clang-simd/simd.html:
--------------------------------------------------------------------------------
1 |
2 | Multiply with SIMD
3 |
4 |
5 |
22 |
23 |
--------------------------------------------------------------------------------
/packages/clang-simd/src/multiply_arrays.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | EMSCRIPTEN_KEEPALIVE
4 | void multiply_arrays(int* out, int* in_a, int* in_b, int size) {
5 | for (int i = 0; i < size; i++) {
6 | out[i] = in_a[i] * in_b[i];
7 | }
8 | }
--------------------------------------------------------------------------------
/packages/clang-simd/src/multiply_arrays_simd.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | EMSCRIPTEN_KEEPALIVE
5 | void multiply_arrays_simd(int* out, int* in_a, int* in_b, int size) {
6 | for (int i = 0; i < size; i++) {
7 | out[i] = in_a[i] * in_b[i];
8 | }
9 | }
10 |
11 | EMSCRIPTEN_KEEPALIVE
12 | void multiply_arrays_simd_intrinsics(int* out, int* in_a, int* in_b, int size) {
13 | for (int i = 0; i < size; i += 4) {
14 | v128_t a = wasm_v128_load(&in_a[i]);
15 | v128_t b = wasm_v128_load(&in_b[i]);
16 | v128_t prod = wasm_i32x4_mul(a, b);
17 | wasm_v128_store(&out[i], prod);
18 | }
19 | }
--------------------------------------------------------------------------------
/packages/clang-thread/.gitignore:
--------------------------------------------------------------------------------
1 | pkg
--------------------------------------------------------------------------------
/packages/clang-thread/build.sh:
--------------------------------------------------------------------------------
1 | mkdir -p pkg
2 | emcc -O2 -s -pthread -s PTHREAD_POOL_SIZE=4 ./src/test.c -o ./pkg/test.js
3 | python3 -m http.server
--------------------------------------------------------------------------------
/packages/clang-thread/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Threads test
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/packages/clang-thread/readme.md:
--------------------------------------------------------------------------------
1 | # Web Assembly Thread
2 |
3 | > Working sample for [WebAssembly Threads ready to try in Chrome 70](https://developers.google.com/web/updates/2018/10/wasm-threads)
4 |
5 | # Prerequisites
6 |
7 | - HTTP server which can serve some of static files like html, js. You might need to install `http-server` on your system, or just use your own simple http server to do
8 | - emscripten SDK, 1.38.11 or later. Please make sure `emcc` is being in your PATH
9 |
10 | # How to run
11 |
12 | ```
13 | yarn build && yarn start
14 | ```
15 |
16 |
--------------------------------------------------------------------------------
/packages/clang-thread/src/test.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | // Calculate fibonacci numbers shared function
5 | int fibonacci(int iterations) {
6 | int val = 1;
7 | int last = 0;
8 |
9 | if (iterations == 0) {
10 | return 0;
11 | }
12 | for (int i = 1; i < iterations; i++) {
13 | int seq;
14 |
15 | seq = val + last;
16 | last = val;
17 | val = seq;
18 | }
19 | return val;
20 | }
21 | // Start function for the background thread
22 | void *bg_func(void *arg) {
23 | int *iter = (void *)arg;
24 |
25 | *iter = fibonacci(*iter);
26 | return arg;
27 | }
28 | // Foreground thread and main entry point
29 | int main(int argc, char *argv[]) {
30 | int fg_val = 54;
31 | int bg_val = 42;
32 | pthread_t bg_thread;
33 |
34 | // Create the background thread
35 | if (pthread_create(&bg_thread, NULL, bg_func, &bg_val)) {
36 | perror("Thread create failed");
37 | return 1;
38 | }
39 | // Calculate on the foreground thread
40 | fg_val = fibonacci(fg_val);
41 | // Wait for background thread to finish
42 | if (pthread_join(bg_thread, NULL)) {
43 | perror("Thread join failed");
44 | return 2;
45 | }
46 | // Show the result from background and foreground threads
47 | printf("Fib(42) is %d, Fib(6 * 9) is %d\n", bg_val, fg_val);
48 |
49 | return 0;
50 | }
--------------------------------------------------------------------------------
/packages/clang/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/packages/clang/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "clang",
3 | "version": "0.0.0",
4 | "scripts": {
5 | "start": "../node_modules/.bin/serve .",
6 | "build:dylib": "emcc ./wasm/helloworld-dylib.c -Os -s WASM=1 -s SIDE_MODULE=1 -o ./wasm/helloworld-dylib.wasm",
7 | "build:std": "emcc ./wasm/helloworld-std.c -Os -s WASM=1 -s ONLY_MY_CODE=1 -o ./wasm/helloworld-std.js",
8 | "build": "npm run build:dylib && npm run build:std"
9 | },
10 | "devDependencies": {
11 | "serve": "^6.5.5"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/packages/clang/readme.md:
--------------------------------------------------------------------------------
1 | # EMSCRIPTEN SDK ONLY
2 |
3 | ```
4 | yarn intall
5 |
6 | yarn build
7 |
8 | yarn start
9 | ```
--------------------------------------------------------------------------------
/packages/clang/wasm-loader.js:
--------------------------------------------------------------------------------
1 | function setEnvironment({env = {}}) {
2 | if (!env.memory) {
3 | env.memory = new WebAssembly.Memory({
4 | initial: 256,
5 | maximum: 256
6 | })
7 | }
8 |
9 | if (!env.table) {
10 | env.table = new WebAssembly.Table({
11 | initial: 0,
12 | maximum: 0,
13 | element: 'anyfunc'
14 | })
15 | }
16 |
17 | return {
18 | ...{
19 | tableBase: 0,
20 | memoryBase: 0,
21 | STACKTOP: 0,
22 | STACK_MAX: env.memory.buffer.byteLength,
23 | abortStackOverflow() {},
24 | abort() {}
25 | },
26 | ...env
27 | }
28 | }
29 |
30 | async function wasmInstantiate(req, importObject = {}) {
31 | const bytes = await window.fetch(req).then(x => x.arrayBuffer())
32 |
33 | importObject = {
34 | global: {},
35 | ...importObject,
36 | env: setEnvironment(importObject)
37 | }
38 |
39 | return {
40 | ...await WebAssembly.instantiate(bytes, importObject),
41 | ...importObject
42 | }
43 | }
--------------------------------------------------------------------------------
/packages/clang/wasm/helloworld-dylib.c:
--------------------------------------------------------------------------------
1 | #define HELLO_WORLD "Hello World!"
2 |
3 | const char* str() {
4 | return HELLO_WORLD;
5 | }
6 |
7 | unsigned int len() {
8 | unsigned int len = 0;
9 |
10 | for (const char* p = HELLO_WORLD; *p != '\0'; p++) {
11 | len++;
12 | }
13 |
14 | return len;
15 | }
--------------------------------------------------------------------------------
/packages/clang/wasm/helloworld-dylib.wasm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ragingwind/wasm-helloworld/3b49e9f944cfb94191dd6312517b96c444544080/packages/clang/wasm/helloworld-dylib.wasm
--------------------------------------------------------------------------------
/packages/clang/wasm/helloworld-std.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | EMSCRIPTEN_KEEPALIVE
4 | const char* HELLO_WORLD = "Hello World!";
5 |
6 | EMSCRIPTEN_KEEPALIVE
7 | const char* str() {
8 | return HELLO_WORLD;
9 | }
10 |
11 | EMSCRIPTEN_KEEPALIVE
12 | unsigned int len() {
13 | unsigned int len = 0;
14 |
15 | for (const char* p = HELLO_WORLD; *p != '\0'; p++) {
16 | len++;
17 | }
18 |
19 | return len;
20 | }
--------------------------------------------------------------------------------
/packages/clang/wasm/helloworld-std.js:
--------------------------------------------------------------------------------
1 | // The Module object: Our interface to the outside world. We import
2 | // and export values on it. There are various ways Module can be used:
3 | // 1. Not defined. We create it here
4 | // 2. A function parameter, function(Module) { ..generated code.. }
5 | // 3. pre-run appended it, var Module = {}; ..generated code..
6 | // 4. External script tag defines var Module.
7 | // We need to check if Module already exists (e.g. case 3 above).
8 | // Substitution will be replaced with actual code on later stage of the build,
9 | // this way Closure Compiler will not mangle it (e.g. case 4. above).
10 | // Note that if you want to run closure, and also to use Module
11 | // after the generated code, you will need to define var Module = {};
12 | // before the code. Then that object will be used in the code, and you
13 | // can continue to use Module afterwards as well.
14 | var Module = typeof Module !== 'undefined' ? Module : {};
15 |
16 | // --pre-jses are emitted after the Module integration code, so that they can
17 | // refer to Module (if they choose; they can also define Module)
18 | // {{PRE_JSES}}
19 |
20 | // Sometimes an existing Module object exists with properties
21 | // meant to overwrite the default module functionality. Here
22 | // we collect those properties and reapply _after_ we configure
23 | // the current environment's defaults to avoid having to be so
24 | // defensive during initialization.
25 | var moduleOverrides = {};
26 | var key;
27 | for (key in Module) {
28 | if (Module.hasOwnProperty(key)) {
29 | moduleOverrides[key] = Module[key];
30 | }
31 | }
32 |
33 | Module['arguments'] = [];
34 | Module['thisProgram'] = './this.program';
35 | Module['quit'] = function(status, toThrow) {
36 | throw toThrow;
37 | };
38 | Module['preRun'] = [];
39 | Module['postRun'] = [];
40 |
41 | // The environment setup code below is customized to use Module.
42 | // *** Environment setup code ***
43 | var ENVIRONMENT_IS_WEB = false;
44 | var ENVIRONMENT_IS_WORKER = false;
45 | var ENVIRONMENT_IS_NODE = false;
46 | var ENVIRONMENT_IS_SHELL = false;
47 |
48 | // Three configurations we can be running in:
49 | // 1) We could be the application main() thread running in the main JS UI thread. (ENVIRONMENT_IS_WORKER == false and ENVIRONMENT_IS_PTHREAD == false)
50 | // 2) We could be the application main() thread proxied to worker. (with Emscripten -s PROXY_TO_WORKER=1) (ENVIRONMENT_IS_WORKER == true, ENVIRONMENT_IS_PTHREAD == false)
51 | // 3) We could be an application pthread running in a worker. (ENVIRONMENT_IS_WORKER == true and ENVIRONMENT_IS_PTHREAD == true)
52 |
53 | if (Module['ENVIRONMENT']) {
54 | if (Module['ENVIRONMENT'] === 'WEB') {
55 | ENVIRONMENT_IS_WEB = true;
56 | } else if (Module['ENVIRONMENT'] === 'WORKER') {
57 | ENVIRONMENT_IS_WORKER = true;
58 | } else if (Module['ENVIRONMENT'] === 'NODE') {
59 | ENVIRONMENT_IS_NODE = true;
60 | } else if (Module['ENVIRONMENT'] === 'SHELL') {
61 | ENVIRONMENT_IS_SHELL = true;
62 | } else {
63 | throw new Error('Module[\'ENVIRONMENT\'] value is not valid. must be one of: WEB|WORKER|NODE|SHELL.');
64 | }
65 | } else {
66 | ENVIRONMENT_IS_WEB = typeof window === 'object';
67 | ENVIRONMENT_IS_WORKER = typeof importScripts === 'function';
68 | ENVIRONMENT_IS_NODE = typeof process === 'object' && typeof require === 'function' && !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_WORKER;
69 | ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER;
70 | }
71 |
72 |
73 | if (ENVIRONMENT_IS_NODE) {
74 | // Expose functionality in the same simple way that the shells work
75 | // Note that we pollute the global namespace here, otherwise we break in node
76 | var nodeFS;
77 | var nodePath;
78 |
79 | Module['read'] = function shell_read(filename, binary) {
80 | var ret;
81 | if (!nodeFS) nodeFS = require('fs');
82 | if (!nodePath) nodePath = require('path');
83 | filename = nodePath['normalize'](filename);
84 | ret = nodeFS['readFileSync'](filename);
85 | return binary ? ret : ret.toString();
86 | };
87 |
88 | Module['readBinary'] = function readBinary(filename) {
89 | var ret = Module['read'](filename, true);
90 | if (!ret.buffer) {
91 | ret = new Uint8Array(ret);
92 | }
93 | assert(ret.buffer);
94 | return ret;
95 | };
96 |
97 | if (process['argv'].length > 1) {
98 | Module['thisProgram'] = process['argv'][1].replace(/\\/g, '/');
99 | }
100 |
101 | Module['arguments'] = process['argv'].slice(2);
102 |
103 | if (typeof module !== 'undefined') {
104 | module['exports'] = Module;
105 | }
106 |
107 | process['on']('uncaughtException', function(ex) {
108 | // suppress ExitStatus exceptions from showing an error
109 | if (!(ex instanceof ExitStatus)) {
110 | throw ex;
111 | }
112 | });
113 | // Currently node will swallow unhandled rejections, but this behavior is
114 | // deprecated, and in the future it will exit with error status.
115 | process['on']('unhandledRejection', function(reason, p) {
116 | process['exit'](1);
117 | });
118 |
119 | Module['inspect'] = function () { return '[Emscripten Module object]'; };
120 | }
121 | else if (ENVIRONMENT_IS_SHELL) {
122 | if (typeof read != 'undefined') {
123 | Module['read'] = function shell_read(f) {
124 | return read(f);
125 | };
126 | }
127 |
128 | Module['readBinary'] = function readBinary(f) {
129 | var data;
130 | if (typeof readbuffer === 'function') {
131 | return new Uint8Array(readbuffer(f));
132 | }
133 | data = read(f, 'binary');
134 | assert(typeof data === 'object');
135 | return data;
136 | };
137 |
138 | if (typeof scriptArgs != 'undefined') {
139 | Module['arguments'] = scriptArgs;
140 | } else if (typeof arguments != 'undefined') {
141 | Module['arguments'] = arguments;
142 | }
143 |
144 | if (typeof quit === 'function') {
145 | Module['quit'] = function(status, toThrow) {
146 | quit(status);
147 | }
148 | }
149 | }
150 | else if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
151 | Module['read'] = function shell_read(url) {
152 | var xhr = new XMLHttpRequest();
153 | xhr.open('GET', url, false);
154 | xhr.send(null);
155 | return xhr.responseText;
156 | };
157 |
158 | if (ENVIRONMENT_IS_WORKER) {
159 | Module['readBinary'] = function readBinary(url) {
160 | var xhr = new XMLHttpRequest();
161 | xhr.open('GET', url, false);
162 | xhr.responseType = 'arraybuffer';
163 | xhr.send(null);
164 | return new Uint8Array(xhr.response);
165 | };
166 | }
167 |
168 | Module['readAsync'] = function readAsync(url, onload, onerror) {
169 | var xhr = new XMLHttpRequest();
170 | xhr.open('GET', url, true);
171 | xhr.responseType = 'arraybuffer';
172 | xhr.onload = function xhr_onload() {
173 | if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) { // file URLs can return 0
174 | onload(xhr.response);
175 | return;
176 | }
177 | onerror();
178 | };
179 | xhr.onerror = onerror;
180 | xhr.send(null);
181 | };
182 |
183 | Module['setWindowTitle'] = function(title) { document.title = title };
184 | }
185 |
186 | // console.log is checked first, as 'print' on the web will open a print dialogue
187 | // printErr is preferable to console.warn (works better in shells)
188 | // bind(console) is necessary to fix IE/Edge closed dev tools panel behavior.
189 | Module['print'] = typeof console !== 'undefined' ? console.log.bind(console) : (typeof print !== 'undefined' ? print : null);
190 | Module['printErr'] = typeof printErr !== 'undefined' ? printErr : ((typeof console !== 'undefined' && console.warn.bind(console)) || Module['print']);
191 |
192 | // *** Environment setup code ***
193 |
194 | // Closure helpers
195 | Module.print = Module['print'];
196 | Module.printErr = Module['printErr'];
197 |
198 | // Merge back in the overrides
199 | for (key in moduleOverrides) {
200 | if (moduleOverrides.hasOwnProperty(key)) {
201 | Module[key] = moduleOverrides[key];
202 | }
203 | }
204 | // Free the object hierarchy contained in the overrides, this lets the GC
205 | // reclaim data used e.g. in memoryInitializerRequest, which is a large typed array.
206 | moduleOverrides = undefined;
207 |
208 |
209 |
210 | // {{PREAMBLE_ADDITIONS}}
211 |
212 | var STACK_ALIGN = 16;
213 |
214 |
215 | function staticAlloc(size) {
216 | assert(!staticSealed);
217 | var ret = STATICTOP;
218 | STATICTOP = (STATICTOP + size + 15) & -16;
219 | return ret;
220 | }
221 |
222 | function dynamicAlloc(size) {
223 | assert(DYNAMICTOP_PTR);
224 | var ret = HEAP32[DYNAMICTOP_PTR>>2];
225 | var end = (ret + size + 15) & -16;
226 | HEAP32[DYNAMICTOP_PTR>>2] = end;
227 | if (end >= TOTAL_MEMORY) {
228 | var success = enlargeMemory();
229 | if (!success) {
230 | HEAP32[DYNAMICTOP_PTR>>2] = ret;
231 | return 0;
232 | }
233 | }
234 | return ret;
235 | }
236 |
237 | function alignMemory(size, factor) {
238 | if (!factor) factor = STACK_ALIGN; // stack alignment (16-byte) by default
239 | var ret = size = Math.ceil(size / factor) * factor;
240 | return ret;
241 | }
242 |
243 | function getNativeTypeSize(type) {
244 | switch (type) {
245 | case 'i1': case 'i8': return 1;
246 | case 'i16': return 2;
247 | case 'i32': return 4;
248 | case 'i64': return 8;
249 | case 'float': return 4;
250 | case 'double': return 8;
251 | default: {
252 | if (type[type.length-1] === '*') {
253 | return 4; // A pointer
254 | } else if (type[0] === 'i') {
255 | var bits = parseInt(type.substr(1));
256 | assert(bits % 8 === 0);
257 | return bits / 8;
258 | } else {
259 | return 0;
260 | }
261 | }
262 | }
263 | }
264 |
265 | function warnOnce(text) {
266 | if (!warnOnce.shown) warnOnce.shown = {};
267 | if (!warnOnce.shown[text]) {
268 | warnOnce.shown[text] = 1;
269 | Module.printErr(text);
270 | }
271 | }
272 |
273 |
274 |
275 | var jsCallStartIndex = 1;
276 | var functionPointers = new Array(0);
277 |
278 | // 'sig' parameter is only used on LLVM wasm backend
279 | function addFunction(func, sig) {
280 | var base = 0;
281 | for (var i = base; i < base + 0; i++) {
282 | if (!functionPointers[i]) {
283 | functionPointers[i] = func;
284 | return jsCallStartIndex + i;
285 | }
286 | }
287 | throw 'Finished up all reserved function pointers. Use a higher value for RESERVED_FUNCTION_POINTERS.';
288 | }
289 |
290 | function removeFunction(index) {
291 | functionPointers[index-jsCallStartIndex] = null;
292 | }
293 |
294 | var funcWrappers = {};
295 |
296 | function getFuncWrapper(func, sig) {
297 | if (!func) return; // on null pointer, return undefined
298 | assert(sig);
299 | if (!funcWrappers[sig]) {
300 | funcWrappers[sig] = {};
301 | }
302 | var sigCache = funcWrappers[sig];
303 | if (!sigCache[func]) {
304 | // optimize away arguments usage in common cases
305 | if (sig.length === 1) {
306 | sigCache[func] = function dynCall_wrapper() {
307 | return dynCall(sig, func);
308 | };
309 | } else if (sig.length === 2) {
310 | sigCache[func] = function dynCall_wrapper(arg) {
311 | return dynCall(sig, func, [arg]);
312 | };
313 | } else {
314 | // general case
315 | sigCache[func] = function dynCall_wrapper() {
316 | return dynCall(sig, func, Array.prototype.slice.call(arguments));
317 | };
318 | }
319 | }
320 | return sigCache[func];
321 | }
322 |
323 |
324 | function makeBigInt(low, high, unsigned) {
325 | return unsigned ? ((+((low>>>0)))+((+((high>>>0)))*4294967296.0)) : ((+((low>>>0)))+((+((high|0)))*4294967296.0));
326 | }
327 |
328 | function dynCall(sig, ptr, args) {
329 | if (args && args.length) {
330 | return Module['dynCall_' + sig].apply(null, [ptr].concat(args));
331 | } else {
332 | return Module['dynCall_' + sig].call(null, ptr);
333 | }
334 | }
335 |
336 |
337 |
338 | var Runtime = {
339 | // FIXME backwards compatibility layer for ports. Support some Runtime.*
340 | // for now, fix it there, then remove it from here. That way we
341 | // can minimize any period of breakage.
342 | dynCall: dynCall, // for SDL2 port
343 | };
344 |
345 | // The address globals begin at. Very low in memory, for code size and optimization opportunities.
346 | // Above 0 is static memory, starting with globals.
347 | // Then the stack.
348 | // Then 'dynamic' memory for sbrk.
349 | var GLOBAL_BASE = 1024;
350 |
351 |
352 |
353 | // === Preamble library stuff ===
354 |
355 | // Documentation for the public APIs defined in this file must be updated in:
356 | // site/source/docs/api_reference/preamble.js.rst
357 | // A prebuilt local version of the documentation is available at:
358 | // site/build/text/docs/api_reference/preamble.js.txt
359 | // You can also build docs locally as HTML or other formats in site/
360 | // An online HTML version (which may be of a different version of Emscripten)
361 | // is up at http://kripken.github.io/emscripten-site/docs/api_reference/preamble.js.html
362 |
363 |
364 |
365 | //========================================
366 | // Runtime essentials
367 | //========================================
368 |
369 | var ABORT = 0; // whether we are quitting the application. no code should run after this. set in exit() and abort()
370 | var EXITSTATUS = 0;
371 |
372 | /** @type {function(*, string=)} */
373 | function assert(condition, text) {
374 | if (!condition) {
375 | abort('Assertion failed: ' + text);
376 | }
377 | }
378 |
379 | var globalScope = this;
380 |
381 | // Returns the C function with a specified identifier (for C++, you need to do manual name mangling)
382 | function getCFunc(ident) {
383 | var func = Module['_' + ident]; // closure exported function
384 | assert(func, 'Cannot call unknown function ' + ident + ', make sure it is exported');
385 | return func;
386 | }
387 |
388 | var JSfuncs = {
389 | // Helpers for cwrap -- it can't refer to Runtime directly because it might
390 | // be renamed by closure, instead it calls JSfuncs['stackSave'].body to find
391 | // out what the minified function name is.
392 | 'stackSave': function() {
393 | stackSave()
394 | },
395 | 'stackRestore': function() {
396 | stackRestore()
397 | },
398 | // type conversion from js to c
399 | 'arrayToC' : function(arr) {
400 | var ret = stackAlloc(arr.length);
401 | writeArrayToMemory(arr, ret);
402 | return ret;
403 | },
404 | 'stringToC' : function(str) {
405 | var ret = 0;
406 | if (str !== null && str !== undefined && str !== 0) { // null string
407 | // at most 4 bytes per UTF-8 code point, +1 for the trailing '\0'
408 | var len = (str.length << 2) + 1;
409 | ret = stackAlloc(len);
410 | stringToUTF8(str, ret, len);
411 | }
412 | return ret;
413 | }
414 | };
415 |
416 | // For fast lookup of conversion functions
417 | var toC = {
418 | 'string': JSfuncs['stringToC'], 'array': JSfuncs['arrayToC']
419 | };
420 |
421 | // C calling interface.
422 | function ccall (ident, returnType, argTypes, args, opts) {
423 | var func = getCFunc(ident);
424 | var cArgs = [];
425 | var stack = 0;
426 | if (args) {
427 | for (var i = 0; i < args.length; i++) {
428 | var converter = toC[argTypes[i]];
429 | if (converter) {
430 | if (stack === 0) stack = stackSave();
431 | cArgs[i] = converter(args[i]);
432 | } else {
433 | cArgs[i] = args[i];
434 | }
435 | }
436 | }
437 | var ret = func.apply(null, cArgs);
438 | if (returnType === 'string') ret = Pointer_stringify(ret);
439 | else if (returnType === 'boolean') ret = Boolean(ret);
440 | if (stack !== 0) {
441 | stackRestore(stack);
442 | }
443 | return ret;
444 | }
445 |
446 | function cwrap (ident, returnType, argTypes) {
447 | argTypes = argTypes || [];
448 | var cfunc = getCFunc(ident);
449 | // When the function takes numbers and returns a number, we can just return
450 | // the original function
451 | var numericArgs = argTypes.every(function(type){ return type === 'number'});
452 | var numericRet = returnType !== 'string';
453 | if (numericRet && numericArgs) {
454 | return cfunc;
455 | }
456 | return function() {
457 | return ccall(ident, returnType, argTypes, arguments);
458 | }
459 | }
460 |
461 | /** @type {function(number, number, string, boolean=)} */
462 | function setValue(ptr, value, type, noSafe) {
463 | type = type || 'i8';
464 | if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit
465 | switch(type) {
466 | case 'i1': HEAP8[((ptr)>>0)]=value; break;
467 | case 'i8': HEAP8[((ptr)>>0)]=value; break;
468 | case 'i16': HEAP16[((ptr)>>1)]=value; break;
469 | case 'i32': HEAP32[((ptr)>>2)]=value; break;
470 | case 'i64': (tempI64 = [value>>>0,(tempDouble=value,(+(Math_abs(tempDouble))) >= 1.0 ? (tempDouble > 0.0 ? ((Math_min((+(Math_floor((tempDouble)/4294967296.0))), 4294967295.0))|0)>>>0 : (~~((+(Math_ceil((tempDouble - +(((~~(tempDouble)))>>>0))/4294967296.0)))))>>>0) : 0)],HEAP32[((ptr)>>2)]=tempI64[0],HEAP32[(((ptr)+(4))>>2)]=tempI64[1]); break;
471 | case 'float': HEAPF32[((ptr)>>2)]=value; break;
472 | case 'double': HEAPF64[((ptr)>>3)]=value; break;
473 | default: abort('invalid type for setValue: ' + type);
474 | }
475 | }
476 |
477 | /** @type {function(number, string, boolean=)} */
478 | function getValue(ptr, type, noSafe) {
479 | type = type || 'i8';
480 | if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit
481 | switch(type) {
482 | case 'i1': return HEAP8[((ptr)>>0)];
483 | case 'i8': return HEAP8[((ptr)>>0)];
484 | case 'i16': return HEAP16[((ptr)>>1)];
485 | case 'i32': return HEAP32[((ptr)>>2)];
486 | case 'i64': return HEAP32[((ptr)>>2)];
487 | case 'float': return HEAPF32[((ptr)>>2)];
488 | case 'double': return HEAPF64[((ptr)>>3)];
489 | default: abort('invalid type for getValue: ' + type);
490 | }
491 | return null;
492 | }
493 |
494 | var ALLOC_NORMAL = 0; // Tries to use _malloc()
495 | var ALLOC_STACK = 1; // Lives for the duration of the current function call
496 | var ALLOC_STATIC = 2; // Cannot be freed
497 | var ALLOC_DYNAMIC = 3; // Cannot be freed except through sbrk
498 | var ALLOC_NONE = 4; // Do not allocate
499 |
500 | // allocate(): This is for internal use. You can use it yourself as well, but the interface
501 | // is a little tricky (see docs right below). The reason is that it is optimized
502 | // for multiple syntaxes to save space in generated code. So you should
503 | // normally not use allocate(), and instead allocate memory using _malloc(),
504 | // initialize it with setValue(), and so forth.
505 | // @slab: An array of data, or a number. If a number, then the size of the block to allocate,
506 | // in *bytes* (note that this is sometimes confusing: the next parameter does not
507 | // affect this!)
508 | // @types: Either an array of types, one for each byte (or 0 if no type at that position),
509 | // or a single type which is used for the entire block. This only matters if there
510 | // is initial data - if @slab is a number, then this does not matter at all and is
511 | // ignored.
512 | // @allocator: How to allocate memory, see ALLOC_*
513 | /** @type {function((TypedArray|Array|number), string, number, number=)} */
514 | function allocate(slab, types, allocator, ptr) {
515 | var zeroinit, size;
516 | if (typeof slab === 'number') {
517 | zeroinit = true;
518 | size = slab;
519 | } else {
520 | zeroinit = false;
521 | size = slab.length;
522 | }
523 |
524 | var singleType = typeof types === 'string' ? types : null;
525 |
526 | var ret;
527 | if (allocator == ALLOC_NONE) {
528 | ret = ptr;
529 | } else {
530 | ret = [typeof _malloc === 'function' ? _malloc : staticAlloc, stackAlloc, staticAlloc, dynamicAlloc][allocator === undefined ? ALLOC_STATIC : allocator](Math.max(size, singleType ? 1 : types.length));
531 | }
532 |
533 | if (zeroinit) {
534 | var stop;
535 | ptr = ret;
536 | assert((ret & 3) == 0);
537 | stop = ret + (size & ~3);
538 | for (; ptr < stop; ptr += 4) {
539 | HEAP32[((ptr)>>2)]=0;
540 | }
541 | stop = ret + size;
542 | while (ptr < stop) {
543 | HEAP8[((ptr++)>>0)]=0;
544 | }
545 | return ret;
546 | }
547 |
548 | if (singleType === 'i8') {
549 | if (slab.subarray || slab.slice) {
550 | HEAPU8.set(/** @type {!Uint8Array} */ (slab), ret);
551 | } else {
552 | HEAPU8.set(new Uint8Array(slab), ret);
553 | }
554 | return ret;
555 | }
556 |
557 | var i = 0, type, typeSize, previousType;
558 | while (i < size) {
559 | var curr = slab[i];
560 |
561 | type = singleType || types[i];
562 | if (type === 0) {
563 | i++;
564 | continue;
565 | }
566 |
567 | if (type == 'i64') type = 'i32'; // special case: we have one i32 here, and one i32 later
568 |
569 | setValue(ret+i, curr, type);
570 |
571 | // no need to look up size unless type changes, so cache it
572 | if (previousType !== type) {
573 | typeSize = getNativeTypeSize(type);
574 | previousType = type;
575 | }
576 | i += typeSize;
577 | }
578 |
579 | return ret;
580 | }
581 |
582 | // Allocate memory during any stage of startup - static memory early on, dynamic memory later, malloc when ready
583 | function getMemory(size) {
584 | if (!staticSealed) return staticAlloc(size);
585 | if (!runtimeInitialized) return dynamicAlloc(size);
586 | return _malloc(size);
587 | }
588 |
589 | /** @type {function(number, number=)} */
590 | function Pointer_stringify(ptr, length) {
591 | if (length === 0 || !ptr) return '';
592 | // TODO: use TextDecoder
593 | // Find the length, and check for UTF while doing so
594 | var hasUtf = 0;
595 | var t;
596 | var i = 0;
597 | while (1) {
598 | t = HEAPU8[(((ptr)+(i))>>0)];
599 | hasUtf |= t;
600 | if (t == 0 && !length) break;
601 | i++;
602 | if (length && i == length) break;
603 | }
604 | if (!length) length = i;
605 |
606 | var ret = '';
607 |
608 | if (hasUtf < 128) {
609 | var MAX_CHUNK = 1024; // split up into chunks, because .apply on a huge string can overflow the stack
610 | var curr;
611 | while (length > 0) {
612 | curr = String.fromCharCode.apply(String, HEAPU8.subarray(ptr, ptr + Math.min(length, MAX_CHUNK)));
613 | ret = ret ? ret + curr : curr;
614 | ptr += MAX_CHUNK;
615 | length -= MAX_CHUNK;
616 | }
617 | return ret;
618 | }
619 | return UTF8ToString(ptr);
620 | }
621 |
622 | // Given a pointer 'ptr' to a null-terminated ASCII-encoded string in the emscripten HEAP, returns
623 | // a copy of that string as a Javascript String object.
624 |
625 | function AsciiToString(ptr) {
626 | var str = '';
627 | while (1) {
628 | var ch = HEAP8[((ptr++)>>0)];
629 | if (!ch) return str;
630 | str += String.fromCharCode(ch);
631 | }
632 | }
633 |
634 | // Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
635 | // null-terminated and encoded in ASCII form. The copy will require at most str.length+1 bytes of space in the HEAP.
636 |
637 | function stringToAscii(str, outPtr) {
638 | return writeAsciiToMemory(str, outPtr, false);
639 | }
640 |
641 | // Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the given array that contains uint8 values, returns
642 | // a copy of that string as a Javascript String object.
643 |
644 | var UTF8Decoder = typeof TextDecoder !== 'undefined' ? new TextDecoder('utf8') : undefined;
645 | function UTF8ArrayToString(u8Array, idx) {
646 | var endPtr = idx;
647 | // TextDecoder needs to know the byte length in advance, it doesn't stop on null terminator by itself.
648 | // Also, use the length info to avoid running tiny strings through TextDecoder, since .subarray() allocates garbage.
649 | while (u8Array[endPtr]) ++endPtr;
650 |
651 | if (endPtr - idx > 16 && u8Array.subarray && UTF8Decoder) {
652 | return UTF8Decoder.decode(u8Array.subarray(idx, endPtr));
653 | } else {
654 | var u0, u1, u2, u3, u4, u5;
655 |
656 | var str = '';
657 | while (1) {
658 | // For UTF8 byte structure, see http://en.wikipedia.org/wiki/UTF-8#Description and https://www.ietf.org/rfc/rfc2279.txt and https://tools.ietf.org/html/rfc3629
659 | u0 = u8Array[idx++];
660 | if (!u0) return str;
661 | if (!(u0 & 0x80)) { str += String.fromCharCode(u0); continue; }
662 | u1 = u8Array[idx++] & 63;
663 | if ((u0 & 0xE0) == 0xC0) { str += String.fromCharCode(((u0 & 31) << 6) | u1); continue; }
664 | u2 = u8Array[idx++] & 63;
665 | if ((u0 & 0xF0) == 0xE0) {
666 | u0 = ((u0 & 15) << 12) | (u1 << 6) | u2;
667 | } else {
668 | u3 = u8Array[idx++] & 63;
669 | if ((u0 & 0xF8) == 0xF0) {
670 | u0 = ((u0 & 7) << 18) | (u1 << 12) | (u2 << 6) | u3;
671 | } else {
672 | u4 = u8Array[idx++] & 63;
673 | if ((u0 & 0xFC) == 0xF8) {
674 | u0 = ((u0 & 3) << 24) | (u1 << 18) | (u2 << 12) | (u3 << 6) | u4;
675 | } else {
676 | u5 = u8Array[idx++] & 63;
677 | u0 = ((u0 & 1) << 30) | (u1 << 24) | (u2 << 18) | (u3 << 12) | (u4 << 6) | u5;
678 | }
679 | }
680 | }
681 | if (u0 < 0x10000) {
682 | str += String.fromCharCode(u0);
683 | } else {
684 | var ch = u0 - 0x10000;
685 | str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF));
686 | }
687 | }
688 | }
689 | }
690 |
691 | // Given a pointer 'ptr' to a null-terminated UTF8-encoded string in the emscripten HEAP, returns
692 | // a copy of that string as a Javascript String object.
693 |
694 | function UTF8ToString(ptr) {
695 | return UTF8ArrayToString(HEAPU8,ptr);
696 | }
697 |
698 | // Copies the given Javascript String object 'str' to the given byte array at address 'outIdx',
699 | // encoded in UTF8 form and null-terminated. The copy will require at most str.length*4+1 bytes of space in the HEAP.
700 | // Use the function lengthBytesUTF8 to compute the exact number of bytes (excluding null terminator) that this function will write.
701 | // Parameters:
702 | // str: the Javascript string to copy.
703 | // outU8Array: the array to copy to. Each index in this array is assumed to be one 8-byte element.
704 | // outIdx: The starting offset in the array to begin the copying.
705 | // maxBytesToWrite: The maximum number of bytes this function can write to the array. This count should include the null
706 | // terminator, i.e. if maxBytesToWrite=1, only the null terminator will be written and nothing else.
707 | // maxBytesToWrite=0 does not write any bytes to the output, not even the null terminator.
708 | // Returns the number of bytes written, EXCLUDING the null terminator.
709 |
710 | function stringToUTF8Array(str, outU8Array, outIdx, maxBytesToWrite) {
711 | if (!(maxBytesToWrite > 0)) // Parameter maxBytesToWrite is not optional. Negative values, 0, null, undefined and false each don't write out any bytes.
712 | return 0;
713 |
714 | var startIdx = outIdx;
715 | var endIdx = outIdx + maxBytesToWrite - 1; // -1 for string null terminator.
716 | for (var i = 0; i < str.length; ++i) {
717 | // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! So decode UTF16->UTF32->UTF8.
718 | // See http://unicode.org/faq/utf_bom.html#utf16-3
719 | // For UTF8 byte structure, see http://en.wikipedia.org/wiki/UTF-8#Description and https://www.ietf.org/rfc/rfc2279.txt and https://tools.ietf.org/html/rfc3629
720 | var u = str.charCodeAt(i); // possibly a lead surrogate
721 | if (u >= 0xD800 && u <= 0xDFFF) u = 0x10000 + ((u & 0x3FF) << 10) | (str.charCodeAt(++i) & 0x3FF);
722 | if (u <= 0x7F) {
723 | if (outIdx >= endIdx) break;
724 | outU8Array[outIdx++] = u;
725 | } else if (u <= 0x7FF) {
726 | if (outIdx + 1 >= endIdx) break;
727 | outU8Array[outIdx++] = 0xC0 | (u >> 6);
728 | outU8Array[outIdx++] = 0x80 | (u & 63);
729 | } else if (u <= 0xFFFF) {
730 | if (outIdx + 2 >= endIdx) break;
731 | outU8Array[outIdx++] = 0xE0 | (u >> 12);
732 | outU8Array[outIdx++] = 0x80 | ((u >> 6) & 63);
733 | outU8Array[outIdx++] = 0x80 | (u & 63);
734 | } else if (u <= 0x1FFFFF) {
735 | if (outIdx + 3 >= endIdx) break;
736 | outU8Array[outIdx++] = 0xF0 | (u >> 18);
737 | outU8Array[outIdx++] = 0x80 | ((u >> 12) & 63);
738 | outU8Array[outIdx++] = 0x80 | ((u >> 6) & 63);
739 | outU8Array[outIdx++] = 0x80 | (u & 63);
740 | } else if (u <= 0x3FFFFFF) {
741 | if (outIdx + 4 >= endIdx) break;
742 | outU8Array[outIdx++] = 0xF8 | (u >> 24);
743 | outU8Array[outIdx++] = 0x80 | ((u >> 18) & 63);
744 | outU8Array[outIdx++] = 0x80 | ((u >> 12) & 63);
745 | outU8Array[outIdx++] = 0x80 | ((u >> 6) & 63);
746 | outU8Array[outIdx++] = 0x80 | (u & 63);
747 | } else {
748 | if (outIdx + 5 >= endIdx) break;
749 | outU8Array[outIdx++] = 0xFC | (u >> 30);
750 | outU8Array[outIdx++] = 0x80 | ((u >> 24) & 63);
751 | outU8Array[outIdx++] = 0x80 | ((u >> 18) & 63);
752 | outU8Array[outIdx++] = 0x80 | ((u >> 12) & 63);
753 | outU8Array[outIdx++] = 0x80 | ((u >> 6) & 63);
754 | outU8Array[outIdx++] = 0x80 | (u & 63);
755 | }
756 | }
757 | // Null-terminate the pointer to the buffer.
758 | outU8Array[outIdx] = 0;
759 | return outIdx - startIdx;
760 | }
761 |
762 | // Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
763 | // null-terminated and encoded in UTF8 form. The copy will require at most str.length*4+1 bytes of space in the HEAP.
764 | // Use the function lengthBytesUTF8 to compute the exact number of bytes (excluding null terminator) that this function will write.
765 | // Returns the number of bytes written, EXCLUDING the null terminator.
766 |
767 | function stringToUTF8(str, outPtr, maxBytesToWrite) {
768 | return stringToUTF8Array(str, HEAPU8,outPtr, maxBytesToWrite);
769 | }
770 |
771 | // Returns the number of bytes the given Javascript string takes if encoded as a UTF8 byte array, EXCLUDING the null terminator byte.
772 |
773 | function lengthBytesUTF8(str) {
774 | var len = 0;
775 | for (var i = 0; i < str.length; ++i) {
776 | // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! So decode UTF16->UTF32->UTF8.
777 | // See http://unicode.org/faq/utf_bom.html#utf16-3
778 | var u = str.charCodeAt(i); // possibly a lead surrogate
779 | if (u >= 0xD800 && u <= 0xDFFF) u = 0x10000 + ((u & 0x3FF) << 10) | (str.charCodeAt(++i) & 0x3FF);
780 | if (u <= 0x7F) {
781 | ++len;
782 | } else if (u <= 0x7FF) {
783 | len += 2;
784 | } else if (u <= 0xFFFF) {
785 | len += 3;
786 | } else if (u <= 0x1FFFFF) {
787 | len += 4;
788 | } else if (u <= 0x3FFFFFF) {
789 | len += 5;
790 | } else {
791 | len += 6;
792 | }
793 | }
794 | return len;
795 | }
796 |
797 | // Given a pointer 'ptr' to a null-terminated UTF16LE-encoded string in the emscripten HEAP, returns
798 | // a copy of that string as a Javascript String object.
799 |
800 | var UTF16Decoder = typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-16le') : undefined;
801 | function UTF16ToString(ptr) {
802 | var endPtr = ptr;
803 | // TextDecoder needs to know the byte length in advance, it doesn't stop on null terminator by itself.
804 | // Also, use the length info to avoid running tiny strings through TextDecoder, since .subarray() allocates garbage.
805 | var idx = endPtr >> 1;
806 | while (HEAP16[idx]) ++idx;
807 | endPtr = idx << 1;
808 |
809 | if (endPtr - ptr > 32 && UTF16Decoder) {
810 | return UTF16Decoder.decode(HEAPU8.subarray(ptr, endPtr));
811 | } else {
812 | var i = 0;
813 |
814 | var str = '';
815 | while (1) {
816 | var codeUnit = HEAP16[(((ptr)+(i*2))>>1)];
817 | if (codeUnit == 0) return str;
818 | ++i;
819 | // fromCharCode constructs a character from a UTF-16 code unit, so we can pass the UTF16 string right through.
820 | str += String.fromCharCode(codeUnit);
821 | }
822 | }
823 | }
824 |
825 | // Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
826 | // null-terminated and encoded in UTF16 form. The copy will require at most str.length*4+2 bytes of space in the HEAP.
827 | // Use the function lengthBytesUTF16() to compute the exact number of bytes (excluding null terminator) that this function will write.
828 | // Parameters:
829 | // str: the Javascript string to copy.
830 | // outPtr: Byte address in Emscripten HEAP where to write the string to.
831 | // maxBytesToWrite: The maximum number of bytes this function can write to the array. This count should include the null
832 | // terminator, i.e. if maxBytesToWrite=2, only the null terminator will be written and nothing else.
833 | // maxBytesToWrite<2 does not write any bytes to the output, not even the null terminator.
834 | // Returns the number of bytes written, EXCLUDING the null terminator.
835 |
836 | function stringToUTF16(str, outPtr, maxBytesToWrite) {
837 | // Backwards compatibility: if max bytes is not specified, assume unsafe unbounded write is allowed.
838 | if (maxBytesToWrite === undefined) {
839 | maxBytesToWrite = 0x7FFFFFFF;
840 | }
841 | if (maxBytesToWrite < 2) return 0;
842 | maxBytesToWrite -= 2; // Null terminator.
843 | var startPtr = outPtr;
844 | var numCharsToWrite = (maxBytesToWrite < str.length*2) ? (maxBytesToWrite / 2) : str.length;
845 | for (var i = 0; i < numCharsToWrite; ++i) {
846 | // charCodeAt returns a UTF-16 encoded code unit, so it can be directly written to the HEAP.
847 | var codeUnit = str.charCodeAt(i); // possibly a lead surrogate
848 | HEAP16[((outPtr)>>1)]=codeUnit;
849 | outPtr += 2;
850 | }
851 | // Null-terminate the pointer to the HEAP.
852 | HEAP16[((outPtr)>>1)]=0;
853 | return outPtr - startPtr;
854 | }
855 |
856 | // Returns the number of bytes the given Javascript string takes if encoded as a UTF16 byte array, EXCLUDING the null terminator byte.
857 |
858 | function lengthBytesUTF16(str) {
859 | return str.length*2;
860 | }
861 |
862 | function UTF32ToString(ptr) {
863 | var i = 0;
864 |
865 | var str = '';
866 | while (1) {
867 | var utf32 = HEAP32[(((ptr)+(i*4))>>2)];
868 | if (utf32 == 0)
869 | return str;
870 | ++i;
871 | // Gotcha: fromCharCode constructs a character from a UTF-16 encoded code (pair), not from a Unicode code point! So encode the code point to UTF-16 for constructing.
872 | // See http://unicode.org/faq/utf_bom.html#utf16-3
873 | if (utf32 >= 0x10000) {
874 | var ch = utf32 - 0x10000;
875 | str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF));
876 | } else {
877 | str += String.fromCharCode(utf32);
878 | }
879 | }
880 | }
881 |
882 | // Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
883 | // null-terminated and encoded in UTF32 form. The copy will require at most str.length*4+4 bytes of space in the HEAP.
884 | // Use the function lengthBytesUTF32() to compute the exact number of bytes (excluding null terminator) that this function will write.
885 | // Parameters:
886 | // str: the Javascript string to copy.
887 | // outPtr: Byte address in Emscripten HEAP where to write the string to.
888 | // maxBytesToWrite: The maximum number of bytes this function can write to the array. This count should include the null
889 | // terminator, i.e. if maxBytesToWrite=4, only the null terminator will be written and nothing else.
890 | // maxBytesToWrite<4 does not write any bytes to the output, not even the null terminator.
891 | // Returns the number of bytes written, EXCLUDING the null terminator.
892 |
893 | function stringToUTF32(str, outPtr, maxBytesToWrite) {
894 | // Backwards compatibility: if max bytes is not specified, assume unsafe unbounded write is allowed.
895 | if (maxBytesToWrite === undefined) {
896 | maxBytesToWrite = 0x7FFFFFFF;
897 | }
898 | if (maxBytesToWrite < 4) return 0;
899 | var startPtr = outPtr;
900 | var endPtr = startPtr + maxBytesToWrite - 4;
901 | for (var i = 0; i < str.length; ++i) {
902 | // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! We must decode the string to UTF-32 to the heap.
903 | // See http://unicode.org/faq/utf_bom.html#utf16-3
904 | var codeUnit = str.charCodeAt(i); // possibly a lead surrogate
905 | if (codeUnit >= 0xD800 && codeUnit <= 0xDFFF) {
906 | var trailSurrogate = str.charCodeAt(++i);
907 | codeUnit = 0x10000 + ((codeUnit & 0x3FF) << 10) | (trailSurrogate & 0x3FF);
908 | }
909 | HEAP32[((outPtr)>>2)]=codeUnit;
910 | outPtr += 4;
911 | if (outPtr + 4 > endPtr) break;
912 | }
913 | // Null-terminate the pointer to the HEAP.
914 | HEAP32[((outPtr)>>2)]=0;
915 | return outPtr - startPtr;
916 | }
917 |
918 | // Returns the number of bytes the given Javascript string takes if encoded as a UTF16 byte array, EXCLUDING the null terminator byte.
919 |
920 | function lengthBytesUTF32(str) {
921 | var len = 0;
922 | for (var i = 0; i < str.length; ++i) {
923 | // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! We must decode the string to UTF-32 to the heap.
924 | // See http://unicode.org/faq/utf_bom.html#utf16-3
925 | var codeUnit = str.charCodeAt(i);
926 | if (codeUnit >= 0xD800 && codeUnit <= 0xDFFF) ++i; // possibly a lead surrogate, so skip over the tail surrogate.
927 | len += 4;
928 | }
929 |
930 | return len;
931 | }
932 |
933 | // Allocate heap space for a JS string, and write it there.
934 | // It is the responsibility of the caller to free() that memory.
935 | function allocateUTF8(str) {
936 | var size = lengthBytesUTF8(str) + 1;
937 | var ret = _malloc(size);
938 | if (ret) stringToUTF8Array(str, HEAP8, ret, size);
939 | return ret;
940 | }
941 |
942 | // Allocate stack space for a JS string, and write it there.
943 | function allocateUTF8OnStack(str) {
944 | var size = lengthBytesUTF8(str) + 1;
945 | var ret = stackAlloc(size);
946 | stringToUTF8Array(str, HEAP8, ret, size);
947 | return ret;
948 | }
949 |
950 | function demangle(func) {
951 | return func;
952 | }
953 |
954 | function demangleAll(text) {
955 | var regex =
956 | /__Z[\w\d_]+/g;
957 | return text.replace(regex,
958 | function(x) {
959 | var y = demangle(x);
960 | return x === y ? x : (x + ' [' + y + ']');
961 | });
962 | }
963 |
964 | function jsStackTrace() {
965 | var err = new Error();
966 | if (!err.stack) {
967 | // IE10+ special cases: It does have callstack info, but it is only populated if an Error object is thrown,
968 | // so try that as a special-case.
969 | try {
970 | throw new Error(0);
971 | } catch(e) {
972 | err = e;
973 | }
974 | if (!err.stack) {
975 | return '(no stack trace available)';
976 | }
977 | }
978 | return err.stack.toString();
979 | }
980 |
981 | function stackTrace() {
982 | var js = jsStackTrace();
983 | if (Module['extraStackTrace']) js += '\n' + Module['extraStackTrace']();
984 | return demangleAll(js);
985 | }
986 |
987 | // Memory management
988 |
989 | var PAGE_SIZE = 16384;
990 | var WASM_PAGE_SIZE = 65536;
991 | var ASMJS_PAGE_SIZE = 16777216;
992 | var MIN_TOTAL_MEMORY = 16777216;
993 |
994 | function alignUp(x, multiple) {
995 | if (x % multiple > 0) {
996 | x += multiple - (x % multiple);
997 | }
998 | return x;
999 | }
1000 |
1001 | var HEAP,
1002 | /** @type {ArrayBuffer} */
1003 | buffer,
1004 | /** @type {Int8Array} */
1005 | HEAP8,
1006 | /** @type {Uint8Array} */
1007 | HEAPU8,
1008 | /** @type {Int16Array} */
1009 | HEAP16,
1010 | /** @type {Uint16Array} */
1011 | HEAPU16,
1012 | /** @type {Int32Array} */
1013 | HEAP32,
1014 | /** @type {Uint32Array} */
1015 | HEAPU32,
1016 | /** @type {Float32Array} */
1017 | HEAPF32,
1018 | /** @type {Float64Array} */
1019 | HEAPF64;
1020 |
1021 | function updateGlobalBuffer(buf) {
1022 | Module['buffer'] = buffer = buf;
1023 | }
1024 |
1025 | function updateGlobalBufferViews() {
1026 | Module['HEAP8'] = HEAP8 = new Int8Array(buffer);
1027 | Module['HEAP16'] = HEAP16 = new Int16Array(buffer);
1028 | Module['HEAP32'] = HEAP32 = new Int32Array(buffer);
1029 | Module['HEAPU8'] = HEAPU8 = new Uint8Array(buffer);
1030 | Module['HEAPU16'] = HEAPU16 = new Uint16Array(buffer);
1031 | Module['HEAPU32'] = HEAPU32 = new Uint32Array(buffer);
1032 | Module['HEAPF32'] = HEAPF32 = new Float32Array(buffer);
1033 | Module['HEAPF64'] = HEAPF64 = new Float64Array(buffer);
1034 | }
1035 |
1036 | var STATIC_BASE, STATICTOP, staticSealed; // static area
1037 | var STACK_BASE, STACKTOP, STACK_MAX; // stack area
1038 | var DYNAMIC_BASE, DYNAMICTOP_PTR; // dynamic area handled by sbrk
1039 |
1040 | STATIC_BASE = STATICTOP = STACK_BASE = STACKTOP = STACK_MAX = DYNAMIC_BASE = DYNAMICTOP_PTR = 0;
1041 | staticSealed = false;
1042 |
1043 |
1044 |
1045 | function abortOnCannotGrowMemory() {
1046 | abort('Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value ' + TOTAL_MEMORY + ', (2) compile with -s ALLOW_MEMORY_GROWTH=1 which allows increasing the size at runtime, or (3) if you want malloc to return NULL (0) instead of this abort, compile with -s ABORTING_MALLOC=0 ');
1047 | }
1048 |
1049 |
1050 | function enlargeMemory() {
1051 | abortOnCannotGrowMemory();
1052 | }
1053 |
1054 |
1055 | var TOTAL_STACK = Module['TOTAL_STACK'] || 5242880;
1056 | var TOTAL_MEMORY = Module['TOTAL_MEMORY'] || 16777216;
1057 | if (TOTAL_MEMORY < TOTAL_STACK) Module.printErr('TOTAL_MEMORY should be larger than TOTAL_STACK, was ' + TOTAL_MEMORY + '! (TOTAL_STACK=' + TOTAL_STACK + ')');
1058 |
1059 | // Initialize the runtime's memory
1060 |
1061 |
1062 |
1063 | // Use a provided buffer, if there is one, or else allocate a new one
1064 | if (Module['buffer']) {
1065 | buffer = Module['buffer'];
1066 | } else {
1067 | // Use a WebAssembly memory where available
1068 | if (typeof WebAssembly === 'object' && typeof WebAssembly.Memory === 'function') {
1069 | Module['wasmMemory'] = new WebAssembly.Memory({ 'initial': TOTAL_MEMORY / WASM_PAGE_SIZE, 'maximum': TOTAL_MEMORY / WASM_PAGE_SIZE });
1070 | buffer = Module['wasmMemory'].buffer;
1071 | } else
1072 | {
1073 | buffer = new ArrayBuffer(TOTAL_MEMORY);
1074 | }
1075 | Module['buffer'] = buffer;
1076 | }
1077 | updateGlobalBufferViews();
1078 |
1079 |
1080 | function getTotalMemory() {
1081 | return TOTAL_MEMORY;
1082 | }
1083 |
1084 | // Endianness check (note: assumes compiler arch was little-endian)
1085 | HEAP32[0] = 0x63736d65; /* 'emsc' */
1086 | HEAP16[1] = 0x6373;
1087 | if (HEAPU8[2] !== 0x73 || HEAPU8[3] !== 0x63) throw 'Runtime error: expected the system to be little-endian!';
1088 |
1089 | function callRuntimeCallbacks(callbacks) {
1090 | while(callbacks.length > 0) {
1091 | var callback = callbacks.shift();
1092 | if (typeof callback == 'function') {
1093 | callback();
1094 | continue;
1095 | }
1096 | var func = callback.func;
1097 | if (typeof func === 'number') {
1098 | if (callback.arg === undefined) {
1099 | Module['dynCall_v'](func);
1100 | } else {
1101 | Module['dynCall_vi'](func, callback.arg);
1102 | }
1103 | } else {
1104 | func(callback.arg === undefined ? null : callback.arg);
1105 | }
1106 | }
1107 | }
1108 |
1109 | var __ATPRERUN__ = []; // functions called before the runtime is initialized
1110 | var __ATINIT__ = []; // functions called during startup
1111 | var __ATMAIN__ = []; // functions called when main() is to be run
1112 | var __ATEXIT__ = []; // functions called during shutdown
1113 | var __ATPOSTRUN__ = []; // functions called after the runtime has exited
1114 |
1115 | var runtimeInitialized = false;
1116 | var runtimeExited = false;
1117 |
1118 |
1119 | function preRun() {
1120 | // compatibility - merge in anything from Module['preRun'] at this time
1121 | if (Module['preRun']) {
1122 | if (typeof Module['preRun'] == 'function') Module['preRun'] = [Module['preRun']];
1123 | while (Module['preRun'].length) {
1124 | addOnPreRun(Module['preRun'].shift());
1125 | }
1126 | }
1127 | callRuntimeCallbacks(__ATPRERUN__);
1128 | }
1129 |
1130 | function ensureInitRuntime() {
1131 | if (runtimeInitialized) return;
1132 | runtimeInitialized = true;
1133 | callRuntimeCallbacks(__ATINIT__);
1134 | }
1135 |
1136 | function preMain() {
1137 | callRuntimeCallbacks(__ATMAIN__);
1138 | }
1139 |
1140 | function exitRuntime() {
1141 | callRuntimeCallbacks(__ATEXIT__);
1142 | runtimeExited = true;
1143 | }
1144 |
1145 | function postRun() {
1146 | // compatibility - merge in anything from Module['postRun'] at this time
1147 | if (Module['postRun']) {
1148 | if (typeof Module['postRun'] == 'function') Module['postRun'] = [Module['postRun']];
1149 | while (Module['postRun'].length) {
1150 | addOnPostRun(Module['postRun'].shift());
1151 | }
1152 | }
1153 | callRuntimeCallbacks(__ATPOSTRUN__);
1154 | }
1155 |
1156 | function addOnPreRun(cb) {
1157 | __ATPRERUN__.unshift(cb);
1158 | }
1159 |
1160 | function addOnInit(cb) {
1161 | __ATINIT__.unshift(cb);
1162 | }
1163 |
1164 | function addOnPreMain(cb) {
1165 | __ATMAIN__.unshift(cb);
1166 | }
1167 |
1168 | function addOnExit(cb) {
1169 | __ATEXIT__.unshift(cb);
1170 | }
1171 |
1172 | function addOnPostRun(cb) {
1173 | __ATPOSTRUN__.unshift(cb);
1174 | }
1175 |
1176 | // Deprecated: This function should not be called because it is unsafe and does not provide
1177 | // a maximum length limit of how many bytes it is allowed to write. Prefer calling the
1178 | // function stringToUTF8Array() instead, which takes in a maximum length that can be used
1179 | // to be secure from out of bounds writes.
1180 | /** @deprecated */
1181 | function writeStringToMemory(string, buffer, dontAddNull) {
1182 | warnOnce('writeStringToMemory is deprecated and should not be called! Use stringToUTF8() instead!');
1183 |
1184 | var /** @type {number} */ lastChar, /** @type {number} */ end;
1185 | if (dontAddNull) {
1186 | // stringToUTF8Array always appends null. If we don't want to do that, remember the
1187 | // character that existed at the location where the null will be placed, and restore
1188 | // that after the write (below).
1189 | end = buffer + lengthBytesUTF8(string);
1190 | lastChar = HEAP8[end];
1191 | }
1192 | stringToUTF8(string, buffer, Infinity);
1193 | if (dontAddNull) HEAP8[end] = lastChar; // Restore the value under the null character.
1194 | }
1195 |
1196 | function writeArrayToMemory(array, buffer) {
1197 | HEAP8.set(array, buffer);
1198 | }
1199 |
1200 | function writeAsciiToMemory(str, buffer, dontAddNull) {
1201 | for (var i = 0; i < str.length; ++i) {
1202 | HEAP8[((buffer++)>>0)]=str.charCodeAt(i);
1203 | }
1204 | // Null-terminate the pointer to the HEAP.
1205 | if (!dontAddNull) HEAP8[((buffer)>>0)]=0;
1206 | }
1207 |
1208 | function unSign(value, bits, ignore) {
1209 | if (value >= 0) {
1210 | return value;
1211 | }
1212 | return bits <= 32 ? 2*Math.abs(1 << (bits-1)) + value // Need some trickery, since if bits == 32, we are right at the limit of the bits JS uses in bitshifts
1213 | : Math.pow(2, bits) + value;
1214 | }
1215 | function reSign(value, bits, ignore) {
1216 | if (value <= 0) {
1217 | return value;
1218 | }
1219 | var half = bits <= 32 ? Math.abs(1 << (bits-1)) // abs is needed if bits == 32
1220 | : Math.pow(2, bits-1);
1221 | if (value >= half && (bits <= 32 || value > half)) { // for huge values, we can hit the precision limit and always get true here. so don't do that
1222 | // but, in general there is no perfect solution here. With 64-bit ints, we get rounding and errors
1223 | // TODO: In i64 mode 1, resign the two parts separately and safely
1224 | value = -2*half + value; // Cannot bitshift half, as it may be at the limit of the bits JS uses in bitshifts
1225 | }
1226 | return value;
1227 | }
1228 |
1229 |
1230 | var Math_abs = Math.abs;
1231 | var Math_cos = Math.cos;
1232 | var Math_sin = Math.sin;
1233 | var Math_tan = Math.tan;
1234 | var Math_acos = Math.acos;
1235 | var Math_asin = Math.asin;
1236 | var Math_atan = Math.atan;
1237 | var Math_atan2 = Math.atan2;
1238 | var Math_exp = Math.exp;
1239 | var Math_log = Math.log;
1240 | var Math_sqrt = Math.sqrt;
1241 | var Math_ceil = Math.ceil;
1242 | var Math_floor = Math.floor;
1243 | var Math_pow = Math.pow;
1244 | var Math_imul = Math.imul;
1245 | var Math_fround = Math.fround;
1246 | var Math_round = Math.round;
1247 | var Math_min = Math.min;
1248 | var Math_max = Math.max;
1249 | var Math_clz32 = Math.clz32;
1250 | var Math_trunc = Math.trunc;
1251 |
1252 | // A counter of dependencies for calling run(). If we need to
1253 | // do asynchronous work before running, increment this and
1254 | // decrement it. Incrementing must happen in a place like
1255 | // PRE_RUN_ADDITIONS (used by emcc to add file preloading).
1256 | // Note that you can add dependencies in preRun, even though
1257 | // it happens right before run - run will be postponed until
1258 | // the dependencies are met.
1259 | var runDependencies = 0;
1260 | var runDependencyWatcher = null;
1261 | var dependenciesFulfilled = null; // overridden to take different actions when all run dependencies are fulfilled
1262 |
1263 | function getUniqueRunDependency(id) {
1264 | return id;
1265 | }
1266 |
1267 | function addRunDependency(id) {
1268 | runDependencies++;
1269 | if (Module['monitorRunDependencies']) {
1270 | Module['monitorRunDependencies'](runDependencies);
1271 | }
1272 | }
1273 |
1274 | function removeRunDependency(id) {
1275 | runDependencies--;
1276 | if (Module['monitorRunDependencies']) {
1277 | Module['monitorRunDependencies'](runDependencies);
1278 | }
1279 | if (runDependencies == 0) {
1280 | if (runDependencyWatcher !== null) {
1281 | clearInterval(runDependencyWatcher);
1282 | runDependencyWatcher = null;
1283 | }
1284 | if (dependenciesFulfilled) {
1285 | var callback = dependenciesFulfilled;
1286 | dependenciesFulfilled = null;
1287 | callback(); // can add another dependenciesFulfilled
1288 | }
1289 | }
1290 | }
1291 |
1292 | Module["preloadedImages"] = {}; // maps url to image data
1293 | Module["preloadedAudios"] = {}; // maps url to audio data
1294 |
1295 |
1296 |
1297 | var memoryInitializer = null;
1298 |
1299 |
1300 |
1301 |
1302 |
1303 |
1304 | // Prefix of data URIs emitted by SINGLE_FILE and related options.
1305 | var dataURIPrefix = 'data:application/octet-stream;base64,';
1306 |
1307 | // Indicates whether filename is a base64 data URI.
1308 | function isDataURI(filename) {
1309 | return String.prototype.startsWith ?
1310 | filename.startsWith(dataURIPrefix) :
1311 | filename.indexOf(dataURIPrefix) === 0;
1312 | }
1313 |
1314 |
1315 |
1316 |
1317 | function integrateWasmJS() {
1318 | // wasm.js has several methods for creating the compiled code module here:
1319 | // * 'native-wasm' : use native WebAssembly support in the browser
1320 | // * 'interpret-s-expr': load s-expression code from a .wast and interpret
1321 | // * 'interpret-binary': load binary wasm and interpret
1322 | // * 'interpret-asm2wasm': load asm.js code, translate to wasm, and interpret
1323 | // * 'asmjs': no wasm, just load the asm.js code and use that (good for testing)
1324 | // The method is set at compile time (BINARYEN_METHOD)
1325 | // The method can be a comma-separated list, in which case, we will try the
1326 | // options one by one. Some of them can fail gracefully, and then we can try
1327 | // the next.
1328 |
1329 | // inputs
1330 |
1331 | var method = 'native-wasm';
1332 |
1333 | var wasmTextFile = 'helloworld-std.wast';
1334 | var wasmBinaryFile = 'helloworld-std.wasm';
1335 | var asmjsCodeFile = 'helloworld-std.temp.asm.js';
1336 |
1337 | if (typeof Module['locateFile'] === 'function') {
1338 | if (!isDataURI(wasmTextFile)) {
1339 | wasmTextFile = Module['locateFile'](wasmTextFile);
1340 | }
1341 | if (!isDataURI(wasmBinaryFile)) {
1342 | wasmBinaryFile = Module['locateFile'](wasmBinaryFile);
1343 | }
1344 | if (!isDataURI(asmjsCodeFile)) {
1345 | asmjsCodeFile = Module['locateFile'](asmjsCodeFile);
1346 | }
1347 | }
1348 |
1349 | // utilities
1350 |
1351 | var wasmPageSize = 64*1024;
1352 |
1353 | var info = {
1354 | 'global': null,
1355 | 'env': null,
1356 | 'asm2wasm': { // special asm2wasm imports
1357 | "f64-rem": function(x, y) {
1358 | return x % y;
1359 | },
1360 | "debugger": function() {
1361 | debugger;
1362 | }
1363 | },
1364 | 'parent': Module // Module inside wasm-js.cpp refers to wasm-js.cpp; this allows access to the outside program.
1365 | };
1366 |
1367 | var exports = null;
1368 |
1369 |
1370 | function mergeMemory(newBuffer) {
1371 | // The wasm instance creates its memory. But static init code might have written to
1372 | // buffer already, including the mem init file, and we must copy it over in a proper merge.
1373 | // TODO: avoid this copy, by avoiding such static init writes
1374 | // TODO: in shorter term, just copy up to the last static init write
1375 | var oldBuffer = Module['buffer'];
1376 | if (newBuffer.byteLength < oldBuffer.byteLength) {
1377 | Module['printErr']('the new buffer in mergeMemory is smaller than the previous one. in native wasm, we should grow memory here');
1378 | }
1379 | var oldView = new Int8Array(oldBuffer);
1380 | var newView = new Int8Array(newBuffer);
1381 |
1382 |
1383 | newView.set(oldView);
1384 | updateGlobalBuffer(newBuffer);
1385 | updateGlobalBufferViews();
1386 | }
1387 |
1388 | function fixImports(imports) {
1389 | return imports;
1390 | }
1391 |
1392 | function getBinary() {
1393 | try {
1394 | if (Module['wasmBinary']) {
1395 | return new Uint8Array(Module['wasmBinary']);
1396 | }
1397 | if (Module['readBinary']) {
1398 | return Module['readBinary'](wasmBinaryFile);
1399 | } else {
1400 | throw "on the web, we need the wasm binary to be preloaded and set on Module['wasmBinary']. emcc.py will do that for you when generating HTML (but not JS)";
1401 | }
1402 | }
1403 | catch (err) {
1404 | abort(err);
1405 | }
1406 | }
1407 |
1408 | function getBinaryPromise() {
1409 | // if we don't have the binary yet, and have the Fetch api, use that
1410 | // in some environments, like Electron's render process, Fetch api may be present, but have a different context than expected, let's only use it on the Web
1411 | if (!Module['wasmBinary'] && (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) && typeof fetch === 'function') {
1412 | return fetch(wasmBinaryFile, { credentials: 'same-origin' }).then(function(response) {
1413 | if (!response['ok']) {
1414 | throw "failed to load wasm binary file at '" + wasmBinaryFile + "'";
1415 | }
1416 | return response['arrayBuffer']();
1417 | }).catch(function () {
1418 | return getBinary();
1419 | });
1420 | }
1421 | // Otherwise, getBinary should be able to get it synchronously
1422 | return new Promise(function(resolve, reject) {
1423 | resolve(getBinary());
1424 | });
1425 | }
1426 |
1427 | // do-method functions
1428 |
1429 |
1430 | function doNativeWasm(global, env, providedBuffer) {
1431 | if (typeof WebAssembly !== 'object') {
1432 | Module['printErr']('no native wasm support detected');
1433 | return false;
1434 | }
1435 | // prepare memory import
1436 | if (!(Module['wasmMemory'] instanceof WebAssembly.Memory)) {
1437 | Module['printErr']('no native wasm Memory in use');
1438 | return false;
1439 | }
1440 | env['memory'] = Module['wasmMemory'];
1441 | // Load the wasm module and create an instance of using native support in the JS engine.
1442 | info['global'] = {
1443 | 'NaN': NaN,
1444 | 'Infinity': Infinity
1445 | };
1446 | info['global.Math'] = Math;
1447 | info['env'] = env;
1448 | // handle a generated wasm instance, receiving its exports and
1449 | // performing other necessary setup
1450 | function receiveInstance(instance, module) {
1451 | exports = instance.exports;
1452 | if (exports.memory) mergeMemory(exports.memory);
1453 | Module['asm'] = exports;
1454 | Module["usingWasm"] = true;
1455 | removeRunDependency('wasm-instantiate');
1456 | }
1457 | addRunDependency('wasm-instantiate');
1458 |
1459 | // User shell pages can write their own Module.instantiateWasm = function(imports, successCallback) callback
1460 | // to manually instantiate the Wasm module themselves. This allows pages to run the instantiation parallel
1461 | // to any other async startup actions they are performing.
1462 | if (Module['instantiateWasm']) {
1463 | try {
1464 | return Module['instantiateWasm'](info, receiveInstance);
1465 | } catch(e) {
1466 | Module['printErr']('Module.instantiateWasm callback failed with error: ' + e);
1467 | return false;
1468 | }
1469 | }
1470 |
1471 | function receiveInstantiatedSource(output) {
1472 | // 'output' is a WebAssemblyInstantiatedSource object which has both the module and instance.
1473 | // receiveInstance() will swap in the exports (to Module.asm) so they can be called
1474 | receiveInstance(output['instance'], output['module']);
1475 | }
1476 | function instantiateArrayBuffer(receiver) {
1477 | getBinaryPromise().then(function(binary) {
1478 | return WebAssembly.instantiate(binary, info);
1479 | }).then(receiver).catch(function(reason) {
1480 | Module['printErr']('failed to asynchronously prepare wasm: ' + reason);
1481 | abort(reason);
1482 | });
1483 | }
1484 | // Prefer streaming instantiation if available.
1485 | if (!Module['wasmBinary'] &&
1486 | typeof WebAssembly.instantiateStreaming === 'function' &&
1487 | !isDataURI(wasmBinaryFile) &&
1488 | typeof fetch === 'function') {
1489 | WebAssembly.instantiateStreaming(fetch(wasmBinaryFile, { credentials: 'same-origin' }), info)
1490 | .then(receiveInstantiatedSource)
1491 | .catch(function(reason) {
1492 | // We expect the most common failure cause to be a bad MIME type for the binary,
1493 | // in which case falling back to ArrayBuffer instantiation should work.
1494 | Module['printErr']('wasm streaming compile failed: ' + reason);
1495 | Module['printErr']('falling back to ArrayBuffer instantiation');
1496 | instantiateArrayBuffer(receiveInstantiatedSource);
1497 | });
1498 | } else {
1499 | instantiateArrayBuffer(receiveInstantiatedSource);
1500 | }
1501 | return {}; // no exports yet; we'll fill them in later
1502 | }
1503 |
1504 |
1505 | // We may have a preloaded value in Module.asm, save it
1506 | Module['asmPreload'] = Module['asm'];
1507 |
1508 | // Memory growth integration code
1509 |
1510 | var asmjsReallocBuffer = Module['reallocBuffer'];
1511 |
1512 | var wasmReallocBuffer = function(size) {
1513 | var PAGE_MULTIPLE = Module["usingWasm"] ? WASM_PAGE_SIZE : ASMJS_PAGE_SIZE; // In wasm, heap size must be a multiple of 64KB. In asm.js, they need to be multiples of 16MB.
1514 | size = alignUp(size, PAGE_MULTIPLE); // round up to wasm page size
1515 | var old = Module['buffer'];
1516 | var oldSize = old.byteLength;
1517 | if (Module["usingWasm"]) {
1518 | // native wasm support
1519 | try {
1520 | var result = Module['wasmMemory'].grow((size - oldSize) / wasmPageSize); // .grow() takes a delta compared to the previous size
1521 | if (result !== (-1 | 0)) {
1522 | // success in native wasm memory growth, get the buffer from the memory
1523 | return Module['buffer'] = Module['wasmMemory'].buffer;
1524 | } else {
1525 | return null;
1526 | }
1527 | } catch(e) {
1528 | return null;
1529 | }
1530 | }
1531 | };
1532 |
1533 | Module['reallocBuffer'] = function(size) {
1534 | if (finalMethod === 'asmjs') {
1535 | return asmjsReallocBuffer(size);
1536 | } else {
1537 | return wasmReallocBuffer(size);
1538 | }
1539 | };
1540 |
1541 | // we may try more than one; this is the final one, that worked and we are using
1542 | var finalMethod = '';
1543 |
1544 | // Provide an "asm.js function" for the application, called to "link" the asm.js module. We instantiate
1545 | // the wasm module at that time, and it receives imports and provides exports and so forth, the app
1546 | // doesn't need to care that it is wasm or olyfilled wasm or asm.js.
1547 |
1548 | Module['asm'] = function(global, env, providedBuffer) {
1549 | env = fixImports(env);
1550 |
1551 | // import table
1552 | if (!env['table']) {
1553 | var TABLE_SIZE = Module['wasmTableSize'];
1554 | if (TABLE_SIZE === undefined) TABLE_SIZE = 1024; // works in binaryen interpreter at least
1555 | var MAX_TABLE_SIZE = Module['wasmMaxTableSize'];
1556 | if (typeof WebAssembly === 'object' && typeof WebAssembly.Table === 'function') {
1557 | if (MAX_TABLE_SIZE !== undefined) {
1558 | env['table'] = new WebAssembly.Table({ 'initial': TABLE_SIZE, 'maximum': MAX_TABLE_SIZE, 'element': 'anyfunc' });
1559 | } else {
1560 | env['table'] = new WebAssembly.Table({ 'initial': TABLE_SIZE, element: 'anyfunc' });
1561 | }
1562 | } else {
1563 | env['table'] = new Array(TABLE_SIZE); // works in binaryen interpreter at least
1564 | }
1565 | Module['wasmTable'] = env['table'];
1566 | }
1567 |
1568 | if (!env['memoryBase']) {
1569 | env['memoryBase'] = Module['STATIC_BASE']; // tell the memory segments where to place themselves
1570 | }
1571 | if (!env['tableBase']) {
1572 | env['tableBase'] = 0; // table starts at 0 by default, in dynamic linking this will change
1573 | }
1574 |
1575 | // try the methods. each should return the exports if it succeeded
1576 |
1577 | var exports;
1578 | exports = doNativeWasm(global, env, providedBuffer);
1579 |
1580 | if (!exports) abort('no binaryen method succeeded. consider enabling more options, like interpreting, if you want that: https://github.com/kripken/emscripten/wiki/WebAssembly#binaryen-methods');
1581 |
1582 |
1583 | return exports;
1584 | };
1585 |
1586 | var methodHandler = Module['asm']; // note our method handler, as we may modify Module['asm'] later
1587 | }
1588 |
1589 | integrateWasmJS();
1590 |
1591 | // === Body ===
1592 |
1593 | var ASM_CONSTS = [];
1594 |
1595 |
1596 |
1597 |
1598 |
1599 | STATIC_BASE = GLOBAL_BASE;
1600 |
1601 | STATICTOP = STATIC_BASE + 1056;
1602 | /* global initializers */ __ATINIT__.push();
1603 |
1604 |
1605 |
1606 |
1607 |
1608 |
1609 |
1610 | var STATIC_BUMP = 1056;
1611 | Module["STATIC_BASE"] = STATIC_BASE;
1612 | Module["STATIC_BUMP"] = STATIC_BUMP;
1613 |
1614 | /* no memory initializer */
1615 | var tempDoublePtr = STATICTOP; STATICTOP += 16;
1616 |
1617 | function copyTempFloat(ptr) { // functions, because inlining this code increases code size too much
1618 |
1619 | HEAP8[tempDoublePtr] = HEAP8[ptr];
1620 |
1621 | HEAP8[tempDoublePtr+1] = HEAP8[ptr+1];
1622 |
1623 | HEAP8[tempDoublePtr+2] = HEAP8[ptr+2];
1624 |
1625 | HEAP8[tempDoublePtr+3] = HEAP8[ptr+3];
1626 |
1627 | }
1628 |
1629 | function copyTempDouble(ptr) {
1630 |
1631 | HEAP8[tempDoublePtr] = HEAP8[ptr];
1632 |
1633 | HEAP8[tempDoublePtr+1] = HEAP8[ptr+1];
1634 |
1635 | HEAP8[tempDoublePtr+2] = HEAP8[ptr+2];
1636 |
1637 | HEAP8[tempDoublePtr+3] = HEAP8[ptr+3];
1638 |
1639 | HEAP8[tempDoublePtr+4] = HEAP8[ptr+4];
1640 |
1641 | HEAP8[tempDoublePtr+5] = HEAP8[ptr+5];
1642 |
1643 | HEAP8[tempDoublePtr+6] = HEAP8[ptr+6];
1644 |
1645 | HEAP8[tempDoublePtr+7] = HEAP8[ptr+7];
1646 |
1647 | }
1648 |
1649 | // {{PRE_LIBRARY}}
1650 |
1651 | DYNAMICTOP_PTR = staticAlloc(4);
1652 |
1653 | STACK_BASE = STACKTOP = alignMemory(STATICTOP);
1654 |
1655 | STACK_MAX = STACK_BASE + TOTAL_STACK;
1656 |
1657 | DYNAMIC_BASE = alignMemory(STACK_MAX);
1658 |
1659 | HEAP32[DYNAMICTOP_PTR>>2] = DYNAMIC_BASE;
1660 |
1661 | staticSealed = true; // seal the static portion of memory
1662 |
1663 | var ASSERTIONS = false;
1664 |
1665 | /** @type {function(string, boolean=, number=)} */
1666 | function intArrayFromString(stringy, dontAddNull, length) {
1667 | var len = length > 0 ? length : lengthBytesUTF8(stringy)+1;
1668 | var u8array = new Array(len);
1669 | var numBytesWritten = stringToUTF8Array(stringy, u8array, 0, u8array.length);
1670 | if (dontAddNull) u8array.length = numBytesWritten;
1671 | return u8array;
1672 | }
1673 |
1674 | function intArrayToString(array) {
1675 | var ret = [];
1676 | for (var i = 0; i < array.length; i++) {
1677 | var chr = array[i];
1678 | if (chr > 0xFF) {
1679 | if (ASSERTIONS) {
1680 | assert(false, 'Character code ' + chr + ' (' + String.fromCharCode(chr) + ') at offset ' + i + ' not in 0x00-0xFF.');
1681 | }
1682 | chr &= 0xFF;
1683 | }
1684 | ret.push(String.fromCharCode(chr));
1685 | }
1686 | return ret.join('');
1687 | }
1688 |
1689 |
1690 |
1691 | Module['wasmTableSize'] = 0;
1692 |
1693 | Module['wasmMaxTableSize'] = 0;
1694 |
1695 | Module.asmGlobalArg = {};
1696 |
1697 | Module.asmLibraryArg = { "abort": abort, "assert": assert, "enlargeMemory": enlargeMemory, "getTotalMemory": getTotalMemory, "abortOnCannotGrowMemory": abortOnCannotGrowMemory, "DYNAMICTOP_PTR": DYNAMICTOP_PTR, "tempDoublePtr": tempDoublePtr, "ABORT": ABORT, "STACKTOP": STACKTOP, "STACK_MAX": STACK_MAX };
1698 | // EMSCRIPTEN_START_ASM
1699 | var asm =Module["asm"]// EMSCRIPTEN_END_ASM
1700 | (Module.asmGlobalArg, Module.asmLibraryArg, buffer);
1701 |
1702 | Module["asm"] = asm;
1703 | var _len = Module["_len"] = function() { return Module["asm"]["_len"].apply(null, arguments) };
1704 | var _str = Module["_str"] = function() { return Module["asm"]["_str"].apply(null, arguments) };
1705 | ;
1706 |
1707 |
1708 |
1709 | // === Auto-generated postamble setup entry stuff ===
1710 |
1711 | Module['asm'] = asm;
1712 |
1713 |
1714 |
1715 |
1716 |
1717 |
1718 |
1719 |
1720 |
1721 |
1722 |
1723 |
1724 |
1725 |
1726 |
1727 |
1728 |
1729 |
1730 |
1731 |
1732 |
1733 |
1734 |
1735 |
1736 |
1737 |
1738 |
1739 |
1740 |
1741 |
1742 |
1743 |
1744 |
1745 |
1746 |
1747 |
1748 |
1749 |
1750 |
1751 |
1752 |
1753 |
1754 |
1755 |
1756 |
1757 |
1758 |
1759 |
1760 |
1761 |
1762 |
1763 |
1764 |
1765 |
1766 |
1767 |
1768 |
1769 |
1770 |
1771 |
1772 |
1773 |
1774 |
1775 |
1776 |
1777 |
1778 |
1779 |
1780 |
1781 |
1782 |
1783 |
1784 | /**
1785 | * @constructor
1786 | * @extends {Error}
1787 | * @this {ExitStatus}
1788 | */
1789 | function ExitStatus(status) {
1790 | this.name = "ExitStatus";
1791 | this.message = "Program terminated with exit(" + status + ")";
1792 | this.status = status;
1793 | };
1794 | ExitStatus.prototype = new Error();
1795 | ExitStatus.prototype.constructor = ExitStatus;
1796 |
1797 | var initialStackTop;
1798 | var calledMain = false;
1799 |
1800 | dependenciesFulfilled = function runCaller() {
1801 | // If run has never been called, and we should call run (INVOKE_RUN is true, and Module.noInitialRun is not false)
1802 | if (!Module['calledRun']) run();
1803 | if (!Module['calledRun']) dependenciesFulfilled = runCaller; // try this again later, after new deps are fulfilled
1804 | }
1805 |
1806 |
1807 |
1808 |
1809 |
1810 | /** @type {function(Array=)} */
1811 | function run(args) {
1812 | args = args || Module['arguments'];
1813 |
1814 | if (runDependencies > 0) {
1815 | return;
1816 | }
1817 |
1818 |
1819 | preRun();
1820 |
1821 | if (runDependencies > 0) return; // a preRun added a dependency, run will be called later
1822 | if (Module['calledRun']) return; // run may have just been called through dependencies being fulfilled just in this very frame
1823 |
1824 | function doRun() {
1825 | if (Module['calledRun']) return; // run may have just been called while the async setStatus time below was happening
1826 | Module['calledRun'] = true;
1827 |
1828 | if (ABORT) return;
1829 |
1830 | ensureInitRuntime();
1831 |
1832 | preMain();
1833 |
1834 | if (Module['onRuntimeInitialized']) Module['onRuntimeInitialized']();
1835 |
1836 |
1837 | postRun();
1838 | }
1839 |
1840 | if (Module['setStatus']) {
1841 | Module['setStatus']('Running...');
1842 | setTimeout(function() {
1843 | setTimeout(function() {
1844 | Module['setStatus']('');
1845 | }, 1);
1846 | doRun();
1847 | }, 1);
1848 | } else {
1849 | doRun();
1850 | }
1851 | }
1852 | Module['run'] = run;
1853 |
1854 |
1855 | function exit(status, implicit) {
1856 |
1857 | // if this is just main exit-ing implicitly, and the status is 0, then we
1858 | // don't need to do anything here and can just leave. if the status is
1859 | // non-zero, though, then we need to report it.
1860 | // (we may have warned about this earlier, if a situation justifies doing so)
1861 | if (implicit && Module['noExitRuntime'] && status === 0) {
1862 | return;
1863 | }
1864 |
1865 | if (Module['noExitRuntime']) {
1866 | } else {
1867 |
1868 | ABORT = true;
1869 | EXITSTATUS = status;
1870 | STACKTOP = initialStackTop;
1871 |
1872 | exitRuntime();
1873 |
1874 | if (Module['onExit']) Module['onExit'](status);
1875 | }
1876 |
1877 | if (ENVIRONMENT_IS_NODE) {
1878 | process['exit'](status);
1879 | }
1880 | Module['quit'](status, new ExitStatus(status));
1881 | }
1882 | Module['exit'] = exit;
1883 |
1884 | var abortDecorators = [];
1885 |
1886 | function abort(what) {
1887 | if (Module['onAbort']) {
1888 | Module['onAbort'](what);
1889 | }
1890 |
1891 | if (what !== undefined) {
1892 | Module.print(what);
1893 | Module.printErr(what);
1894 | what = JSON.stringify(what)
1895 | } else {
1896 | what = '';
1897 | }
1898 |
1899 | ABORT = true;
1900 | EXITSTATUS = 1;
1901 |
1902 | throw 'abort(' + what + '). Build with -s ASSERTIONS=1 for more info.';
1903 | }
1904 | Module['abort'] = abort;
1905 |
1906 | // {{PRE_RUN_ADDITIONS}}
1907 |
1908 | if (Module['preInit']) {
1909 | if (typeof Module['preInit'] == 'function') Module['preInit'] = [Module['preInit']];
1910 | while (Module['preInit'].length > 0) {
1911 | Module['preInit'].pop()();
1912 | }
1913 | }
1914 |
1915 |
1916 | Module["noExitRuntime"] = true;
1917 |
1918 | run();
1919 |
1920 | // {{POST_RUN_ADDITIONS}}
1921 |
1922 |
1923 |
1924 |
1925 |
1926 | // {{MODULE_ADDITIONS}}
1927 |
1928 |
1929 |
1930 |
--------------------------------------------------------------------------------
/packages/clang/wasm/helloworld-std.wasm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ragingwind/wasm-helloworld/3b49e9f944cfb94191dd6312517b96c444544080/packages/clang/wasm/helloworld-std.wasm
--------------------------------------------------------------------------------
/packages/go/Makefile:
--------------------------------------------------------------------------------
1 | build:
2 | GOARCH=wasm GOOS=js ${GOROOT}/bin/go build -o ./wasm/main.wasm ./src/main.go
3 |
4 | build-server:
5 | go build -o ./server ./src/server.go
6 |
7 | run:
8 | ./server ${PORT}
--------------------------------------------------------------------------------
/packages/go/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/packages/go/readme.md:
--------------------------------------------------------------------------------
1 | # Install
2 |
3 | - Go lang with vesion [over 1.11](https://golang.org/dl/)
4 |
5 | # Usage
6 |
7 | ```
8 | # build with your go bin, make sure that your go must support web assembly
9 | GOROOT=~/Go/release/go1.11beta1/ make build
10 |
11 | # run and visit https://localhost:8080
12 | make PORT=8080 run
13 |
14 | # build server as you want
15 | make build-server
16 | ```
--------------------------------------------------------------------------------
/packages/go/server:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ragingwind/wasm-helloworld/3b49e9f944cfb94191dd6312517b96c444544080/packages/go/server
--------------------------------------------------------------------------------
/packages/go/src/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "syscall/js"
5 | )
6 |
7 | func main() {
8 | output := js.Global().Get("document").Call("querySelector", "#output")
9 | output.Set("textContent", Add(10, 90))
10 | }
11 |
12 | func Add(a, b int) int {
13 | return a + b
14 | }
15 |
--------------------------------------------------------------------------------
/packages/go/src/server.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "log"
6 | "net/http"
7 | "os"
8 | )
9 |
10 | func wasmHandler(w http.ResponseWriter, r *http.Request) {
11 | w.Header().Set("Content-Type", "application/wasm")
12 | http.ServeFile(w, r, "./wasm/main.wasm")
13 | }
14 |
15 | func main() {
16 | var port string
17 | if len(os.Args) > 1 {
18 | port = os.Args[1]
19 | } else {
20 | port = "8080"
21 | }
22 |
23 | mux := http.NewServeMux()
24 | mux.Handle("/", http.FileServer(http.Dir(".")))
25 | mux.HandleFunc("/main.wasm", wasmHandler)
26 | log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), mux))
27 | }
28 |
--------------------------------------------------------------------------------
/packages/go/wasm/main.wasm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ragingwind/wasm-helloworld/3b49e9f944cfb94191dd6312517b96c444544080/packages/go/wasm/main.wasm
--------------------------------------------------------------------------------
/packages/go/wasm_exec.js:
--------------------------------------------------------------------------------
1 | // Copyright 2018 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 | // https://raw.githubusercontent.com/golang/go/master/misc/wasm/wasm_exec.js
5 |
6 | (() => {
7 | // Map web browser API and Node.js API to a single common API (preferring web standards over Node.js API).
8 | const isNodeJS = typeof process !== "undefined";
9 | if (isNodeJS) {
10 | global.require = require;
11 | global.fs = require("fs");
12 |
13 | const nodeCrypto = require("crypto");
14 | global.crypto = {
15 | getRandomValues(b) {
16 | nodeCrypto.randomFillSync(b);
17 | },
18 | };
19 |
20 | global.performance = {
21 | now() {
22 | const [sec, nsec] = process.hrtime();
23 | return sec * 1000 + nsec / 1000000;
24 | },
25 | };
26 |
27 | const util = require("util");
28 | global.TextEncoder = util.TextEncoder;
29 | global.TextDecoder = util.TextDecoder;
30 | } else {
31 | window.global = window;
32 |
33 | let outputBuf = "";
34 | global.fs = {
35 | constants: { O_WRONLY: -1, O_RDWR: -1, O_CREAT: -1, O_TRUNC: -1, O_APPEND: -1, O_EXCL: -1, O_NONBLOCK: -1, O_SYNC: -1 }, // unused
36 | writeSync(fd, buf) {
37 | outputBuf += decoder.decode(buf);
38 | const nl = outputBuf.lastIndexOf("\n");
39 | if (nl != -1) {
40 | console.log(outputBuf.substr(0, nl));
41 | outputBuf = outputBuf.substr(nl + 1);
42 | }
43 | return buf.length;
44 | },
45 | openSync(path, flags, mode) {
46 | const err = new Error("not implemented");
47 | err.code = "ENOSYS";
48 | throw err;
49 | },
50 | };
51 | }
52 |
53 | const encoder = new TextEncoder("utf-8");
54 | const decoder = new TextDecoder("utf-8");
55 |
56 | global.Go = class {
57 | constructor() {
58 | this.argv = ["js"];
59 | this.env = {};
60 | this.exit = (code) => {
61 | if (code !== 0) {
62 | console.warn("exit code:", code);
63 | }
64 | };
65 | this._callbackTimeouts = new Map();
66 | this._nextCallbackTimeoutID = 1;
67 |
68 | const mem = () => {
69 | // The buffer may change when requesting more memory.
70 | return new DataView(this._inst.exports.mem.buffer);
71 | }
72 |
73 | const setInt64 = (addr, v) => {
74 | mem().setUint32(addr + 0, v, true);
75 | mem().setUint32(addr + 4, Math.floor(v / 4294967296), true);
76 | }
77 |
78 | const getInt64 = (addr) => {
79 | const low = mem().getUint32(addr + 0, true);
80 | const high = mem().getInt32(addr + 4, true);
81 | return low + high * 4294967296;
82 | }
83 |
84 | const loadValue = (addr) => {
85 | const f = mem().getFloat64(addr, true);
86 | if (!isNaN(f)) {
87 | return f;
88 | }
89 |
90 | const id = mem().getUint32(addr, true);
91 | return this._values[id];
92 | }
93 |
94 | const storeValue = (addr, v) => {
95 | if (typeof v === "number") {
96 | if (isNaN(v)) {
97 | mem().setUint32(addr + 4, 0x7FF80000, true); // NaN
98 | mem().setUint32(addr, 0, true);
99 | return;
100 | }
101 | mem().setFloat64(addr, v, true);
102 | return;
103 | }
104 |
105 | mem().setUint32(addr + 4, 0x7FF80000, true); // NaN
106 |
107 | switch (v) {
108 | case undefined:
109 | mem().setUint32(addr, 1, true);
110 | return;
111 | case null:
112 | mem().setUint32(addr, 2, true);
113 | return;
114 | case true:
115 | mem().setUint32(addr, 3, true);
116 | return;
117 | case false:
118 | mem().setUint32(addr, 4, true);
119 | return;
120 | }
121 |
122 | if (typeof v === "string") {
123 | let ref = this._stringRefs.get(v);
124 | if (ref === undefined) {
125 | ref = this._values.length;
126 | this._values.push(v);
127 | this._stringRefs.set(v, ref);
128 | }
129 | mem().setUint32(addr, ref, true);
130 | return;
131 | }
132 |
133 | if (typeof v === "symbol") {
134 | let ref = this._symbolRefs.get(v);
135 | if (ref === undefined) {
136 | ref = this._values.length;
137 | this._values.push(v);
138 | this._symbolRefs.set(v, ref);
139 | }
140 | mem().setUint32(addr, ref, true);
141 | return;
142 | }
143 |
144 | let ref = v[this._refProp];
145 | if (ref === undefined || this._values[ref] !== v) {
146 | ref = this._values.length;
147 | this._values.push(v);
148 | v[this._refProp] = ref;
149 | }
150 | mem().setUint32(addr, ref, true);
151 | }
152 |
153 | const loadSlice = (addr) => {
154 | const array = getInt64(addr + 0);
155 | const len = getInt64(addr + 8);
156 | return new Uint8Array(this._inst.exports.mem.buffer, array, len);
157 | }
158 |
159 | const loadSliceOfValues = (addr) => {
160 | const array = getInt64(addr + 0);
161 | const len = getInt64(addr + 8);
162 | const a = new Array(len);
163 | for (let i = 0; i < len; i++) {
164 | a[i] = loadValue(array + i * 8);
165 | }
166 | return a;
167 | }
168 |
169 | const loadString = (addr) => {
170 | const saddr = getInt64(addr + 0);
171 | const len = getInt64(addr + 8);
172 | return decoder.decode(new DataView(this._inst.exports.mem.buffer, saddr, len));
173 | }
174 |
175 | const timeOrigin = Date.now() - performance.now();
176 | this.importObject = {
177 | go: {
178 | // func wasmExit(code int32)
179 | "runtime.wasmExit": (sp) => {
180 | this.exited = true;
181 | this.exit(mem().getInt32(sp + 8, true));
182 | },
183 |
184 | // func wasmWrite(fd uintptr, p unsafe.Pointer, n int32)
185 | "runtime.wasmWrite": (sp) => {
186 | const fd = getInt64(sp + 8);
187 | const p = getInt64(sp + 16);
188 | const n = mem().getInt32(sp + 24, true);
189 | fs.writeSync(fd, new Uint8Array(this._inst.exports.mem.buffer, p, n));
190 | },
191 |
192 | // func nanotime() int64
193 | "runtime.nanotime": (sp) => {
194 | setInt64(sp + 8, (timeOrigin + performance.now()) * 1000000);
195 | },
196 |
197 | // func walltime() (sec int64, nsec int32)
198 | "runtime.walltime": (sp) => {
199 | const msec = (new Date).getTime();
200 | setInt64(sp + 8, msec / 1000);
201 | mem().setInt32(sp + 16, (msec % 1000) * 1000000, true);
202 | },
203 |
204 | // func scheduleCallback(delay int64) int32
205 | "runtime.scheduleCallback": (sp) => {
206 | const id = this._nextCallbackTimeoutID;
207 | this._nextCallbackTimeoutID++;
208 | this._callbackTimeouts.set(id, setTimeout(
209 | () => { this._resolveCallbackPromise(); },
210 | getInt64(sp + 8) + 1, // setTimeout has been seen to fire up to 1 millisecond early
211 | ));
212 | mem().setInt32(sp + 16, id, true);
213 | },
214 |
215 | // func clearScheduledCallback(id int32)
216 | "runtime.clearScheduledCallback": (sp) => {
217 | const id = mem().getInt32(sp + 8, true);
218 | clearTimeout(this._callbackTimeouts.get(id));
219 | this._callbackTimeouts.delete(id);
220 | },
221 |
222 | // func getRandomData(r []byte)
223 | "runtime.getRandomData": (sp) => {
224 | crypto.getRandomValues(loadSlice(sp + 8));
225 | },
226 |
227 | // func stringVal(value string) ref
228 | "syscall/js.stringVal": (sp) => {
229 | storeValue(sp + 24, loadString(sp + 8));
230 | },
231 |
232 | // func valueGet(v ref, p string) ref
233 | "syscall/js.valueGet": (sp) => {
234 | storeValue(sp + 32, Reflect.get(loadValue(sp + 8), loadString(sp + 16)));
235 | },
236 |
237 | // func valueSet(v ref, p string, x ref)
238 | "syscall/js.valueSet": (sp) => {
239 | Reflect.set(loadValue(sp + 8), loadString(sp + 16), loadValue(sp + 32));
240 | },
241 |
242 | // func valueIndex(v ref, i int) ref
243 | "syscall/js.valueIndex": (sp) => {
244 | storeValue(sp + 24, Reflect.get(loadValue(sp + 8), getInt64(sp + 16)));
245 | },
246 |
247 | // valueSetIndex(v ref, i int, x ref)
248 | "syscall/js.valueSetIndex": (sp) => {
249 | Reflect.set(loadValue(sp + 8), getInt64(sp + 16), loadValue(sp + 24));
250 | },
251 |
252 | // func valueCall(v ref, m string, args []ref) (ref, bool)
253 | "syscall/js.valueCall": (sp) => {
254 | try {
255 | const v = loadValue(sp + 8);
256 | const m = Reflect.get(v, loadString(sp + 16));
257 | const args = loadSliceOfValues(sp + 32);
258 | storeValue(sp + 56, Reflect.apply(m, v, args));
259 | mem().setUint8(sp + 64, 1);
260 | } catch (err) {
261 | storeValue(sp + 56, err);
262 | mem().setUint8(sp + 64, 0);
263 | }
264 | },
265 |
266 | // func valueInvoke(v ref, args []ref) (ref, bool)
267 | "syscall/js.valueInvoke": (sp) => {
268 | try {
269 | const v = loadValue(sp + 8);
270 | const args = loadSliceOfValues(sp + 16);
271 | storeValue(sp + 40, Reflect.apply(v, undefined, args));
272 | mem().setUint8(sp + 48, 1);
273 | } catch (err) {
274 | storeValue(sp + 40, err);
275 | mem().setUint8(sp + 48, 0);
276 | }
277 | },
278 |
279 | // func valueNew(v ref, args []ref) (ref, bool)
280 | "syscall/js.valueNew": (sp) => {
281 | try {
282 | const v = loadValue(sp + 8);
283 | const args = loadSliceOfValues(sp + 16);
284 | storeValue(sp + 40, Reflect.construct(v, args));
285 | mem().setUint8(sp + 48, 1);
286 | } catch (err) {
287 | storeValue(sp + 40, err);
288 | mem().setUint8(sp + 48, 0);
289 | }
290 | },
291 |
292 | // func valueLength(v ref) int
293 | "syscall/js.valueLength": (sp) => {
294 | setInt64(sp + 16, parseInt(loadValue(sp + 8).length));
295 | },
296 |
297 | // valuePrepareString(v ref) (ref, int)
298 | "syscall/js.valuePrepareString": (sp) => {
299 | const str = encoder.encode(String(loadValue(sp + 8)));
300 | storeValue(sp + 16, str);
301 | setInt64(sp + 24, str.length);
302 | },
303 |
304 | // valueLoadString(v ref, b []byte)
305 | "syscall/js.valueLoadString": (sp) => {
306 | const str = loadValue(sp + 8);
307 | loadSlice(sp + 16).set(str);
308 | },
309 |
310 | // func valueInstanceOf(v ref, t ref) bool
311 | "syscall/js.valueInstanceOf": (sp) => {
312 | mem().setUint8(sp + 24, loadValue(sp + 8) instanceof loadValue(sp + 16));
313 | },
314 |
315 | "debug": (value) => {
316 | console.log(value);
317 | },
318 | }
319 | };
320 | }
321 |
322 | async run(instance) {
323 | this._inst = instance;
324 | this._values = [ // TODO: garbage collection
325 | NaN,
326 | undefined,
327 | null,
328 | true,
329 | false,
330 | global,
331 | this._inst.exports.mem,
332 | () => { // resolveCallbackPromise
333 | if (this.exited) {
334 | throw new Error("bad callback: Go program has already exited");
335 | }
336 | setTimeout(this._resolveCallbackPromise, 0); // make sure it is asynchronous
337 | },
338 | ];
339 | this._stringRefs = new Map();
340 | this._symbolRefs = new Map();
341 | this._refProp = Symbol();
342 | this.exited = false;
343 |
344 | const mem = new DataView(this._inst.exports.mem.buffer)
345 |
346 | // Pass command line arguments and environment variables to WebAssembly by writing them to the linear memory.
347 | let offset = 4096;
348 |
349 | const strPtr = (str) => {
350 | let ptr = offset;
351 | new Uint8Array(mem.buffer, offset, str.length + 1).set(encoder.encode(str + "\0"));
352 | offset += str.length + (8 - (str.length % 8));
353 | return ptr;
354 | };
355 |
356 | const argc = this.argv.length;
357 |
358 | const argvPtrs = [];
359 | this.argv.forEach((arg) => {
360 | argvPtrs.push(strPtr(arg));
361 | });
362 |
363 | const keys = Object.keys(this.env).sort();
364 | argvPtrs.push(keys.length);
365 | keys.forEach((key) => {
366 | argvPtrs.push(strPtr(`${key}=${this.env[key]}`));
367 | });
368 |
369 | const argv = offset;
370 | argvPtrs.forEach((ptr) => {
371 | mem.setUint32(offset, ptr, true);
372 | mem.setUint32(offset + 4, 0, true);
373 | offset += 8;
374 | });
375 |
376 | while (true) {
377 | const callbackPromise = new Promise((resolve) => {
378 | this._resolveCallbackPromise = resolve;
379 | });
380 | this._inst.exports.run(argc, argv);
381 | if (this.exited) {
382 | break;
383 | }
384 | await callbackPromise;
385 | }
386 | }
387 | }
388 |
389 | if (isNodeJS) {
390 | if (process.argv.length < 3) {
391 | process.stderr.write("usage: go_js_wasm_exec [wasm binary] [arguments]\n");
392 | process.exit(1);
393 | }
394 |
395 | const go = new Go();
396 | go.argv = process.argv.slice(2);
397 | go.env = process.env;
398 | go.exit = process.exit;
399 | WebAssembly.instantiate(fs.readFileSync(process.argv[2]), go.importObject).then((result) => {
400 | process.on("exit", () => { // Node.js exits if no callback is pending
401 | if (!go.exited) {
402 | console.error("error: all goroutines asleep and no JavaScript callback pending - deadlock!");
403 | process.exit(1);
404 | }
405 | });
406 | return go.run(result.instance);
407 | }).catch((err) => {
408 | console.error(err);
409 | go.exited = true;
410 | process.exit(1);
411 | });
412 | }
413 | })();
--------------------------------------------------------------------------------
/packages/rust-parcel/index.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/rust-parcel/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "clang",
3 | "version": "0.0.0",
4 | "scripts": {
5 | "start": "parcel index.html --open -p 8080",
6 | "build": "parcel build src/index.js --out-dir ./dist"
7 | },
8 | "devDependencies": {
9 | "parcel-bundler": "^1.7.1"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/packages/rust-parcel/readme.md:
--------------------------------------------------------------------------------
1 | # Rust with parcel packager
2 |
3 | > Parcel packager allows us to import rust source code directly in source files.
4 |
5 | ## Uses
6 |
7 | ```sh
8 | # Install deps
9 | yarn install
10 |
11 | # Build or
12 | yarn build
13 |
14 | # Start dev server
15 | yarn start
16 | ```
17 |
18 | # License
19 |
20 | MIT @ CODEBUSKING
--------------------------------------------------------------------------------
/packages/rust-parcel/src/index.js:
--------------------------------------------------------------------------------
1 | import('../wasm/add.rs').then(({add}) => {
2 | document.body.innerHTML += `add(2, 3) = ${add(2, 3)}
`
3 | })
4 |
5 | import('../wasm/square.wasm').then(({square}) => {
6 | document.body.innerHTML += `square(10) = ${square(10)}
`
7 | })
--------------------------------------------------------------------------------
/packages/rust-parcel/wasm/add.rs:
--------------------------------------------------------------------------------
1 | pub fn main() {}
2 |
3 | #[no_mangle]
4 | pub extern fn add(a: i32, b: i32) -> i32 {
5 | return a + b
6 | }
--------------------------------------------------------------------------------
/packages/rust-parcel/wasm/square.wasm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ragingwind/wasm-helloworld/3b49e9f944cfb94191dd6312517b96c444544080/packages/rust-parcel/wasm/square.wasm
--------------------------------------------------------------------------------
/packages/rust-thread/.gitignore:
--------------------------------------------------------------------------------
1 | pkg
2 | target
--------------------------------------------------------------------------------
/packages/rust-thread/Cargo.lock:
--------------------------------------------------------------------------------
1 | # This file is automatically @generated by Cargo.
2 | # It is not intended for manual editing.
3 | [[package]]
4 | name = "anyhow"
5 | version = "1.0.22"
6 | source = "registry+https://github.com/rust-lang/crates.io-index"
7 |
8 | [[package]]
9 | name = "bumpalo"
10 | version = "2.6.0"
11 | source = "registry+https://github.com/rust-lang/crates.io-index"
12 |
13 | [[package]]
14 | name = "cfg-if"
15 | version = "0.1.10"
16 | source = "registry+https://github.com/rust-lang/crates.io-index"
17 |
18 | [[package]]
19 | name = "heck"
20 | version = "0.3.1"
21 | source = "registry+https://github.com/rust-lang/crates.io-index"
22 | dependencies = [
23 | "unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
24 | ]
25 |
26 | [[package]]
27 | name = "itoa"
28 | version = "0.4.4"
29 | source = "registry+https://github.com/rust-lang/crates.io-index"
30 |
31 | [[package]]
32 | name = "js-sys"
33 | version = "0.3.31"
34 | source = "registry+https://github.com/rust-lang/crates.io-index"
35 | dependencies = [
36 | "wasm-bindgen 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
37 | ]
38 |
39 | [[package]]
40 | name = "lazy_static"
41 | version = "1.4.0"
42 | source = "registry+https://github.com/rust-lang/crates.io-index"
43 |
44 | [[package]]
45 | name = "log"
46 | version = "0.4.8"
47 | source = "registry+https://github.com/rust-lang/crates.io-index"
48 | dependencies = [
49 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
50 | ]
51 |
52 | [[package]]
53 | name = "memchr"
54 | version = "2.2.1"
55 | source = "registry+https://github.com/rust-lang/crates.io-index"
56 |
57 | [[package]]
58 | name = "nom"
59 | version = "4.2.3"
60 | source = "registry+https://github.com/rust-lang/crates.io-index"
61 | dependencies = [
62 | "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
63 | "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
64 | ]
65 |
66 | [[package]]
67 | name = "proc-macro2"
68 | version = "1.0.6"
69 | source = "registry+https://github.com/rust-lang/crates.io-index"
70 | dependencies = [
71 | "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
72 | ]
73 |
74 | [[package]]
75 | name = "quote"
76 | version = "1.0.2"
77 | source = "registry+https://github.com/rust-lang/crates.io-index"
78 | dependencies = [
79 | "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
80 | ]
81 |
82 | [[package]]
83 | name = "rust-thread"
84 | version = "0.1.0"
85 | dependencies = [
86 | "js-sys 0.3.31 (registry+https://github.com/rust-lang/crates.io-index)",
87 | "wasm-bindgen 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
88 | "wasm-bindgen-futures 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
89 | "web-sys 0.3.31 (registry+https://github.com/rust-lang/crates.io-index)",
90 | ]
91 |
92 | [[package]]
93 | name = "ryu"
94 | version = "1.0.2"
95 | source = "registry+https://github.com/rust-lang/crates.io-index"
96 |
97 | [[package]]
98 | name = "serde"
99 | version = "1.0.102"
100 | source = "registry+https://github.com/rust-lang/crates.io-index"
101 |
102 | [[package]]
103 | name = "serde_json"
104 | version = "1.0.41"
105 | source = "registry+https://github.com/rust-lang/crates.io-index"
106 | dependencies = [
107 | "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
108 | "ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
109 | "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
110 | ]
111 |
112 | [[package]]
113 | name = "sourcefile"
114 | version = "0.1.4"
115 | source = "registry+https://github.com/rust-lang/crates.io-index"
116 |
117 | [[package]]
118 | name = "syn"
119 | version = "1.0.8"
120 | source = "registry+https://github.com/rust-lang/crates.io-index"
121 | dependencies = [
122 | "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
123 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
124 | "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
125 | ]
126 |
127 | [[package]]
128 | name = "unicode-segmentation"
129 | version = "1.6.0"
130 | source = "registry+https://github.com/rust-lang/crates.io-index"
131 |
132 | [[package]]
133 | name = "unicode-xid"
134 | version = "0.2.0"
135 | source = "registry+https://github.com/rust-lang/crates.io-index"
136 |
137 | [[package]]
138 | name = "version_check"
139 | version = "0.1.5"
140 | source = "registry+https://github.com/rust-lang/crates.io-index"
141 |
142 | [[package]]
143 | name = "wasm-bindgen"
144 | version = "0.2.54"
145 | source = "registry+https://github.com/rust-lang/crates.io-index"
146 | dependencies = [
147 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
148 | "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
149 | "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
150 | "wasm-bindgen-macro 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
151 | ]
152 |
153 | [[package]]
154 | name = "wasm-bindgen-backend"
155 | version = "0.2.54"
156 | source = "registry+https://github.com/rust-lang/crates.io-index"
157 | dependencies = [
158 | "bumpalo 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
159 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
160 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
161 | "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
162 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
163 | "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
164 | "wasm-bindgen-shared 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
165 | ]
166 |
167 | [[package]]
168 | name = "wasm-bindgen-futures"
169 | version = "0.4.4"
170 | source = "registry+https://github.com/rust-lang/crates.io-index"
171 | dependencies = [
172 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
173 | "js-sys 0.3.31 (registry+https://github.com/rust-lang/crates.io-index)",
174 | "wasm-bindgen 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
175 | "web-sys 0.3.31 (registry+https://github.com/rust-lang/crates.io-index)",
176 | ]
177 |
178 | [[package]]
179 | name = "wasm-bindgen-macro"
180 | version = "0.2.54"
181 | source = "registry+https://github.com/rust-lang/crates.io-index"
182 | dependencies = [
183 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
184 | "wasm-bindgen-macro-support 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
185 | ]
186 |
187 | [[package]]
188 | name = "wasm-bindgen-macro-support"
189 | version = "0.2.54"
190 | source = "registry+https://github.com/rust-lang/crates.io-index"
191 | dependencies = [
192 | "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
193 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
194 | "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
195 | "wasm-bindgen-backend 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
196 | "wasm-bindgen-shared 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
197 | ]
198 |
199 | [[package]]
200 | name = "wasm-bindgen-shared"
201 | version = "0.2.54"
202 | source = "registry+https://github.com/rust-lang/crates.io-index"
203 |
204 | [[package]]
205 | name = "wasm-bindgen-webidl"
206 | version = "0.2.54"
207 | source = "registry+https://github.com/rust-lang/crates.io-index"
208 | dependencies = [
209 | "anyhow 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
210 | "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
211 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
212 | "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
213 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
214 | "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
215 | "wasm-bindgen-backend 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
216 | "weedle 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
217 | ]
218 |
219 | [[package]]
220 | name = "web-sys"
221 | version = "0.3.31"
222 | source = "registry+https://github.com/rust-lang/crates.io-index"
223 | dependencies = [
224 | "anyhow 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
225 | "js-sys 0.3.31 (registry+https://github.com/rust-lang/crates.io-index)",
226 | "sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
227 | "wasm-bindgen 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
228 | "wasm-bindgen-webidl 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
229 | ]
230 |
231 | [[package]]
232 | name = "weedle"
233 | version = "0.10.0"
234 | source = "registry+https://github.com/rust-lang/crates.io-index"
235 | dependencies = [
236 | "nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
237 | ]
238 |
239 | [metadata]
240 | "checksum anyhow 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)" = "e19f23ab207147bbdbcdfa7f7e4ca5e84963d79bae3937074682177ab9150968"
241 | "checksum bumpalo 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ad807f2fc2bf185eeb98ff3a901bd46dc5ad58163d0fa4577ba0d25674d71708"
242 | "checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
243 | "checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
244 | "checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f"
245 | "checksum js-sys 0.3.31 (registry+https://github.com/rust-lang/crates.io-index)" = "d8657b7ca06a6044ece477f6900bf7670f8b5fd0cce177a1d7094eef51e0adf4"
246 | "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
247 | "checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
248 | "checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
249 | "checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6"
250 | "checksum proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9c9e470a8dc4aeae2dee2f335e8f533e2d4b347e1434e5671afc49b054592f27"
251 | "checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
252 | "checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8"
253 | "checksum serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4b39bd9b0b087684013a792c59e3e07a46a01d2322518d8a1104641a0b1be0"
254 | "checksum serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)" = "2f72eb2a68a7dc3f9a691bfda9305a1c017a6215e5a4545c258500d2099a37c2"
255 | "checksum sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4bf77cb82ba8453b42b6ae1d692e4cdc92f9a47beaf89a847c8be83f4e328ad3"
256 | "checksum syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "661641ea2aa15845cddeb97dad000d22070bb5c1fb456b96c1cba883ec691e92"
257 | "checksum unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0"
258 | "checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
259 | "checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
260 | "checksum wasm-bindgen 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)" = "c4568ae1b4e07ca907b1a4de41174eaa3e5be4066c024475586b7842725f69a9"
261 | "checksum wasm-bindgen-backend 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5a00cfdce37367770062065fd3abb9278cbae86a0d918cacd0978a7acd51b481"
262 | "checksum wasm-bindgen-futures 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "07573324d8331357b833487c57f7b8d45924a69d5e2c44b4420558b310b86943"
263 | "checksum wasm-bindgen-macro 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)" = "7c568f4d3cf6d7c1d72b165daf778fb0d6e09a24f96ac14fc8c4f66a96e86b72"
264 | "checksum wasm-bindgen-macro-support 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)" = "430d12539ae324d16097b399e9d07a6d5ce0173b2a61a2d02346ca7c198daffe"
265 | "checksum wasm-bindgen-shared 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)" = "8ae7167f0bbffd7fac2b12da0fa1f834c1d84671a1ae3c93ac8bde2e97179c39"
266 | "checksum wasm-bindgen-webidl 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)" = "3021567c515a746a64ad0b269d120d46e687c0c95702a4750623db935ae6b5e7"
267 | "checksum web-sys 0.3.31 (registry+https://github.com/rust-lang/crates.io-index)" = "ce8e893e021539beb87de8f06e77bdb390a3ab0db4cfeb569c4e377b55ed20de"
268 | "checksum weedle 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3bb43f70885151e629e2a19ce9e50bd730fd436cfd4b666894c9ce4de9141164"
269 |
--------------------------------------------------------------------------------
/packages/rust-thread/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "rust-thread"
3 | version = "0.1.0"
4 | authors = ["Jimmy Moon "]
5 | edition = "2018"
6 |
7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8 |
9 | [lib]
10 | crate-type = ["cdylib"]
11 |
12 | [dependencies]
13 | js-sys = "0.3.31"
14 | wasm-bindgen = { version = "0.2.54", features = ['serde-serialize'] }
15 | wasm-bindgen-futures = "0.4.4"
16 |
17 | [dependencies.web-sys]
18 | version = "0.3.23"
19 | features = [
20 | 'CanvasRenderingContext2d',
21 | 'ErrorEvent',
22 | 'Event',
23 | 'ImageData',
24 | 'Navigator',
25 | 'Window',
26 | 'Worker',
27 | 'WorkerOptions',
28 | 'DedicatedWorkerGlobalScope',
29 | 'MessageEvent',
30 | ]
--------------------------------------------------------------------------------
/packages/rust-thread/build.sh:
--------------------------------------------------------------------------------
1 | mkdir -p pkg
2 | PATH=$PATH:$(dirname $(find $(rustc --print sysroot) -name 'rust-lld')) \
3 | RUSTFLAGS='-C target-feature=+atomics,+bulk-memory' rustup run nightly wasm-pack build -t no-modules -- -Z build-std
4 |
5 | python3 -m http.server
--------------------------------------------------------------------------------
/packages/rust-thread/index.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/packages/rust-thread/readme.md:
--------------------------------------------------------------------------------
1 | # rust-thread example
2 |
3 | > Build thread with Rust and wasm-bindgen, custom worker.js. It's kind of snippets from origin source, [raytrace-paraller](https://github.com/rustwasm/wasm-bindgen/tree/master/examples/raytrace-parallel) to understand how thread works in Rust. It would be updated to more practical example.
4 |
5 | # How to run
6 |
7 | ```sh
8 | # build
9 | ./build.sh
10 | ```
11 |
12 | # License
13 |
14 | MIT @ Jimmy Moon
--------------------------------------------------------------------------------
/packages/rust-thread/src/lib.rs:
--------------------------------------------------------------------------------
1 | #![cfg_attr(not(target_arch = "wasm32"), allow(dead_code))]
2 |
3 | use wasm_bindgen::prelude::*;
4 |
5 | mod thread;
6 |
7 | macro_rules! console_log {
8 | ($($t:tt)*) => (crate::log(&format_args!($($t)*).to_string()))
9 | }
10 |
11 | #[wasm_bindgen]
12 | extern "C" {
13 | #[wasm_bindgen(js_namespace = console)]
14 | fn log(s: &str);
15 | #[wasm_bindgen(js_namespace = console, js_name = log)]
16 | fn logv(x: &JsValue);
17 | }
18 |
19 | #[wasm_bindgen]
20 | pub fn start() -> Result<(), JsValue> {
21 | let thread = thread::WorkerThread::new("./worker.js", "worker1")?;
22 | thread.run(move || {
23 | console_log!("run in wasm");
24 | })?;
25 |
26 | Ok(())
27 | }
--------------------------------------------------------------------------------
/packages/rust-thread/src/thread.rs:
--------------------------------------------------------------------------------
1 | use std::rc::Rc;
2 | use wasm_bindgen::prelude::*;
3 | use web_sys::{Worker, WorkerOptions};
4 |
5 | pub struct WorkerThread {
6 | worker: Rc
7 | }
8 |
9 | pub struct Work {
10 | pub func: Box,
11 | }
12 |
13 | impl WorkerThread {
14 | pub fn new(script: &str, name: &str) -> Result {
15 | let mut options = WorkerOptions::new();
16 | options.name(String::from(name).as_str());
17 |
18 | let worker = Worker::new_with_options(script, &options)?;
19 | let thread = WorkerThread {
20 | worker: Rc::new(worker)
21 | };
22 |
23 | let wasm = js_sys::Array::new();
24 | wasm.push(&wasm_bindgen::module());
25 | wasm.push(&wasm_bindgen::memory());
26 | thread.post_message("init", &wasm)?;
27 |
28 | Ok(thread)
29 | }
30 |
31 | pub fn post_message(&self, command: &str, payload: &JsValue) -> Result<(), JsValue> {
32 | let commands = js_sys::Array::new();
33 | commands.push(&JsValue::from_str(command));
34 | commands.push(payload);
35 | self.worker.post_message(&commands)?;
36 | Ok(())
37 | }
38 |
39 | pub fn run(&self, f: impl FnOnce() + Send + 'static) -> Result<(), JsValue> {
40 | let work = Box::new(Work { func: Box::new(f) });
41 | let ptr = Box::into_raw(work);
42 |
43 | match self.post_message("work", &JsValue::from(ptr as u32)) {
44 | Ok(()) => Ok(()),
45 | Err(e) => {
46 | unsafe {
47 | drop(Box::from_raw(ptr));
48 | }
49 | Err(e)
50 | }
51 | }
52 | }
53 | }
54 |
55 | #[wasm_bindgen]
56 | pub fn thread_execute(ptr: u32) -> Result<(), JsValue> {
57 | let ptr = unsafe { Box::from_raw(ptr as *mut Work) };
58 | (ptr.func)();
59 | Ok(())
60 | }
--------------------------------------------------------------------------------
/packages/rust-thread/worker.js:
--------------------------------------------------------------------------------
1 | importScripts("./pkg/rust_thread.js");
2 |
3 | console.log('worker: worker started', self.name);
4 |
5 | self.onmessage = async ({data}) => {
6 | console.log('message from wasm', data);
7 | try {
8 | switch (data[0]) {
9 | case 'init':
10 | await wasm_bindgen(...data[1]);
11 | break;
12 | case 'work':
13 | wasm_bindgen.thread_execute(data[1]);
14 | break;
15 | }
16 | } catch (e) {
17 | console.error(e);
18 | }
19 | }
--------------------------------------------------------------------------------
/packages/rust-wasi-node/.gitignore:
--------------------------------------------------------------------------------
1 | *.txt
2 | target
--------------------------------------------------------------------------------
/packages/rust-wasi-node/Cargo.lock:
--------------------------------------------------------------------------------
1 | # This file is automatically @generated by Cargo.
2 | # It is not intended for manual editing.
3 | [[package]]
4 | name = "rust-wasi-node"
5 | version = "0.1.0"
6 |
--------------------------------------------------------------------------------
/packages/rust-wasi-node/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "rust-wasi-node"
3 | version = "0.1.0"
4 | authors = ["Jimmy Moon "]
5 | edition = "2018"
6 |
7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8 |
9 | [dependencies]
10 |
11 | [lib]
12 | crate-type = ['cdylib']
--------------------------------------------------------------------------------
/packages/rust-wasi-node/readme.md:
--------------------------------------------------------------------------------
1 | # rust-wasi-node example
2 |
3 | > The demo shows how WASI work with Node.js
4 |
5 | # How to make
6 |
7 | ## Install cargo-wasi
8 |
9 | ```
10 | cargo install cargo-wasi
11 | ```
12 |
13 | ## Create a project as lib
14 |
15 | ```
16 | cargo new rust-wasi-node --lib
17 | ```
18 |
19 | ## Update Cargo.toml for lib project
20 |
21 | add `[lib]` section below
22 |
23 | ```
24 | [lib]
25 | crate-type = ['cdylib']
26 | ```
27 |
28 | ## Implement `src/lib.rs`
29 |
30 | Write(Copy) code with below into `src/lib.rs`
31 |
32 | ```
33 | use std::io::prelude::*;
34 | use std::fs;
35 |
36 | // export name with no mangling
37 | #[no_mangle]
38 | pub extern "C" fn print_hello() {
39 | // use system stdio
40 | println!("Hello, world!");
41 |
42 | // use system file io
43 | let mut file = fs::File::create("/host/helloworld.txt").unwrap();
44 |
45 | // write the text to the file we created
46 | write!(file, "Hello world!\n").unwrap();
47 | }
48 | ```
49 |
50 | ## Build
51 |
52 | Run commands below
53 |
54 | ```
55 | rustup target add wasm32-wasi
56 | cargo build --target wasm32-wasi
57 | ```
58 |
59 | ## Run with wasmtime
60 |
61 | Pass `/host` path to map host device location to virtual filesystem. To current directory(.) on the host filesystem will be mapped to `/host` virtual filesystem. For example:
62 |
63 | ```
64 | --mapdir /host::.
65 | ```
66 |
67 | Run wasmtime with using commadn below
68 |
69 | ```
70 | wasmtime --mapdir /host::. --invoke print_hello target/wasm32-wasi/debug/rust_wasi_node.wasm
71 | cat ./helloworld.txt
72 | ```
73 |
74 | ## Run on Node.js
75 |
76 | Create a file to `runtime/index.mjs`
77 |
78 | ```
79 | mkdir -p runtime
80 | touch runtime/index.mjs
81 | ```
82 |
83 | Write this code to `runtime/index.mjs`:
84 |
85 | ```
86 | 'use strict';
87 |
88 | import fs from 'fs';
89 | import path from 'path';
90 | import { fileURLToPath } from 'url';
91 | import { WASI } from 'wasi';
92 |
93 | const __dirname = path.dirname(fileURLToPath(import.meta.url));
94 |
95 | const wasi = new WASI({
96 | // Same as --mapdir of wasmtime, map virtual filesystem to host filesystem
97 | preopens: {
98 | '/host': process.cwd(),
99 | },
100 | });
101 |
102 | // pass import Object to WASM to use host APIs
103 | const importObject = { wasi_snapshot_preview1: wasi.wasiImport };
104 |
105 | // Load, and compile, and instantiate WASM
106 | const wasm = await WebAssembly.compile(fs.readFileSync(path.resolve(__dirname, '../target/wasm32-wasi/debug/rust_wasi_node.wasm')));
107 | const instance = await WebAssembly.instantiate(wasm, importObject);
108 |
109 | // WASI try to initialize WASM instanced
110 | wasi.initialize(instance);
111 |
112 | // Run WASM function
113 | instance.exports.print_hello();
114 | ```
115 |
116 | Before running, please make sure that the version of Node.js. It have to be over 16
117 |
118 | ```
119 | node -v
120 | ```
121 |
122 | And then run with experimental flag
123 |
124 | ```
125 | node --experimental-wasi-unstable-preview1 ./runtime/index.mjs
126 | cat ./helloworld.txt
127 | ```
128 |
129 | # Reference
130 |
131 | - https://github.com/bytecodealliance/wasmtime/blob/main/docs/wasm-rust.md#writing-libraries
132 | - https://github.com/bytecodealliance/wasmtime/blob/main/docs/wasm-rust.md#webassembly-interface-types
133 | - https://wasmbyexample.dev/examples/wasi-hello-world/wasi-hello-world.rust.en-us.html
134 | - https://nodejs.org/api/wasi.html
--------------------------------------------------------------------------------
/packages/rust-wasi-node/runtime/index.mjs:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import fs from 'fs';
4 | import path from 'path';
5 | import { fileURLToPath } from 'url';
6 | import { WASI } from 'wasi';
7 |
8 | const __dirname = path.dirname(fileURLToPath(import.meta.url));
9 |
10 | const wasi = new WASI({
11 | // Same as --mapdir of wasmtime, map virtual filesystem to host filesystem
12 | preopens: {
13 | '/host': process.cwd(),
14 | },
15 | });
16 |
17 | // pass import Object to WASM to use host APIs
18 | const importObject = { wasi_snapshot_preview1: wasi.wasiImport };
19 |
20 | // Load, and compile, and instantiate WASM
21 | const wasm = await WebAssembly.compile(fs.readFileSync(path.resolve(__dirname, '../target/wasm32-wasi/debug/rust_wasi_node.wasm')));
22 | const instance = await WebAssembly.instantiate(wasm, importObject);
23 |
24 | // WASI try to initialize WASM instanced
25 | wasi.initialize(instance);
26 |
27 | // Run WASM function
28 | instance.exports.print_hello();
--------------------------------------------------------------------------------
/packages/rust-wasi-node/src/lib.rs:
--------------------------------------------------------------------------------
1 | use std::io::prelude::*;
2 | use std::fs;
3 |
4 | #[no_mangle]
5 | pub extern "C" fn print_hello() {
6 | println!("Hello, world!");
7 | let mut file = fs::File::create("host/helloworld.txt").unwrap();
8 |
9 | // Write the text to the file we created
10 | write!(file, "Hello world!\n").unwrap();
11 | }
12 |
--------------------------------------------------------------------------------
/packages/rust-wasm-bindgen/.gitignore:
--------------------------------------------------------------------------------
1 | dist
2 | node_modules
3 | .cache
4 | .vscode
5 |
6 | /src/alert*.*
7 | /target
8 | **/*.rs.bk
9 |
--------------------------------------------------------------------------------
/packages/rust-wasm-bindgen/Cargo.lock:
--------------------------------------------------------------------------------
1 | [[package]]
2 | name = "alert"
3 | version = "0.1.0"
4 | dependencies = [
5 | "wasm-bindgen 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
6 | ]
7 |
8 | [[package]]
9 | name = "dtoa"
10 | version = "0.4.3"
11 | source = "registry+https://github.com/rust-lang/crates.io-index"
12 |
13 | [[package]]
14 | name = "itoa"
15 | version = "0.4.2"
16 | source = "registry+https://github.com/rust-lang/crates.io-index"
17 |
18 | [[package]]
19 | name = "proc-macro2"
20 | version = "0.4.6"
21 | source = "registry+https://github.com/rust-lang/crates.io-index"
22 | dependencies = [
23 | "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
24 | ]
25 |
26 | [[package]]
27 | name = "quote"
28 | version = "0.6.3"
29 | source = "registry+https://github.com/rust-lang/crates.io-index"
30 | dependencies = [
31 | "proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
32 | ]
33 |
34 | [[package]]
35 | name = "serde"
36 | version = "1.0.70"
37 | source = "registry+https://github.com/rust-lang/crates.io-index"
38 |
39 | [[package]]
40 | name = "serde_derive"
41 | version = "1.0.70"
42 | source = "registry+https://github.com/rust-lang/crates.io-index"
43 | dependencies = [
44 | "proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
45 | "quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
46 | "syn 0.14.4 (registry+https://github.com/rust-lang/crates.io-index)",
47 | ]
48 |
49 | [[package]]
50 | name = "serde_json"
51 | version = "1.0.22"
52 | source = "registry+https://github.com/rust-lang/crates.io-index"
53 | dependencies = [
54 | "dtoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
55 | "itoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
56 | "serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
57 | ]
58 |
59 | [[package]]
60 | name = "syn"
61 | version = "0.14.4"
62 | source = "registry+https://github.com/rust-lang/crates.io-index"
63 | dependencies = [
64 | "proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
65 | "quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
66 | "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
67 | ]
68 |
69 | [[package]]
70 | name = "unicode-xid"
71 | version = "0.1.0"
72 | source = "registry+https://github.com/rust-lang/crates.io-index"
73 |
74 | [[package]]
75 | name = "wasm-bindgen"
76 | version = "0.2.11"
77 | source = "registry+https://github.com/rust-lang/crates.io-index"
78 | dependencies = [
79 | "wasm-bindgen-macro 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
80 | ]
81 |
82 | [[package]]
83 | name = "wasm-bindgen-backend"
84 | version = "0.2.11"
85 | source = "registry+https://github.com/rust-lang/crates.io-index"
86 | dependencies = [
87 | "proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
88 | "quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
89 | "serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
90 | "syn 0.14.4 (registry+https://github.com/rust-lang/crates.io-index)",
91 | "wasm-bindgen-shared 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
92 | ]
93 |
94 | [[package]]
95 | name = "wasm-bindgen-macro"
96 | version = "0.2.11"
97 | source = "registry+https://github.com/rust-lang/crates.io-index"
98 | dependencies = [
99 | "proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
100 | "quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
101 | "syn 0.14.4 (registry+https://github.com/rust-lang/crates.io-index)",
102 | "wasm-bindgen-backend 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
103 | ]
104 |
105 | [[package]]
106 | name = "wasm-bindgen-shared"
107 | version = "0.2.11"
108 | source = "registry+https://github.com/rust-lang/crates.io-index"
109 | dependencies = [
110 | "serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
111 | "serde_derive 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
112 | ]
113 |
114 | [metadata]
115 | "checksum dtoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6d301140eb411af13d3115f9a562c85cc6b541ade9dfa314132244aaee7489dd"
116 | "checksum itoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5adb58558dcd1d786b5f0bd15f3226ee23486e24b7b58304b60f64dc68e62606"
117 | "checksum proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "effdb53b25cdad54f8f48843d67398f7ef2e14f12c1b4cb4effc549a6462a4d6"
118 | "checksum quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e44651a0dc4cdd99f71c83b561e221f714912d11af1a4dff0631f923d53af035"
119 | "checksum serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)" = "0c3adf19c07af6d186d91dae8927b83b0553d07ca56cbf7f2f32560455c91920"
120 | "checksum serde_derive 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)" = "3525a779832b08693031b8ecfb0de81cd71cfd3812088fafe9a7496789572124"
121 | "checksum serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)" = "84b8035cabe9b35878adec8ac5fe03d5f6bc97ff6edd7ccb96b44c1276ba390e"
122 | "checksum syn 0.14.4 (registry+https://github.com/rust-lang/crates.io-index)" = "2beff8ebc3658f07512a413866875adddd20f4fd47b2a4e6c9da65cd281baaea"
123 | "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
124 | "checksum wasm-bindgen 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "e38789b21dd56c9b172efb263d635ba5203d4f6c65a7010a26fba1aaa8c55bda"
125 | "checksum wasm-bindgen-backend 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "3360d814e6dfc2d1de99d20e224310cb2a640e5749133d7e7e6be2f8d401378a"
126 | "checksum wasm-bindgen-macro 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "00cae1d10619d295b817c40cb5bb2fa7969d5abf39c74ceac4dd7e8b285376f0"
127 | "checksum wasm-bindgen-shared 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "12fc3992a9356fb2eec8133e6336996cea864ebfe21660793ecd4a9d522b2985"
128 |
--------------------------------------------------------------------------------
/packages/rust-wasm-bindgen/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "alert"
3 | version = "0.1.0"
4 | authors = ["Jimmy Moon "]
5 |
6 | [lib]
7 | crate-type = ["cdylib"]
8 | path="./wasm/alert.rs"
9 |
10 | [dependencies]
11 | wasm-bindgen = "0.2.11"
12 |
--------------------------------------------------------------------------------
/packages/rust-wasm-bindgen/index.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/rust-wasm-bindgen/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rust-wasm-bindgen",
3 | "version": "0.0.0",
4 | "scripts": {
5 | "cargo": "cargo +nightly build --target wasm32-unknown-unknown && wasm-bindgen target/wasm32-unknown-unknown/debug/alert.wasm --out-dir ./src",
6 | "clean": "rm -rf ./dist .cache ./target",
7 | "build": "webpack ./src/index.js -o dist/index.js",
8 | "start": "webpack-dev-server"
9 | },
10 | "devDependencies": {
11 | "webpack": "^4.16.0",
12 | "webpack-cli": "^3.0.8",
13 | "webpack-dev-server": "^3.1.4"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/packages/rust-wasm-bindgen/readme.md:
--------------------------------------------------------------------------------
1 | # Rust with wasm-bindgen
2 |
3 | > This sample has been wrote following by [Basic Usage](https://github.com/rustwasm/wasm-bindgen/blob/master/guide/src/basic-usage.md) with wasm-bindgen. Webpack will served files because of a [lack of features in parcel](https://github.com/rustwasm/wasm-bindgen/issues/182)
4 |
5 | ## Changes
6 |
7 | - Using `import()` for asynchrounos loading
8 | - Using npm script instead of `build.sh`
9 | - Custom path with Cargo
10 |
11 | ## Uses
12 |
13 | ```sh
14 | # Install deps
15 | yarn install
16 |
17 | # Build wasm source first. Generated files will be placed at 'src'
18 | yarn cargo
19 |
20 | # Start dev server of webpack than go to the local server
21 | yarn start
22 | ```
23 |
24 | # License
25 |
26 | MIT @ CODEBUSKING
--------------------------------------------------------------------------------
/packages/rust-wasm-bindgen/src/index.js:
--------------------------------------------------------------------------------
1 | import('./alert').then(m => {
2 | m.greet("World!");
3 | })
--------------------------------------------------------------------------------
/packages/rust-wasm-bindgen/wasm/alert.rs:
--------------------------------------------------------------------------------
1 | #![feature(proc_macro, wasm_custom_section, wasm_import_module)]
2 |
3 | extern crate wasm_bindgen;
4 | use wasm_bindgen::prelude::*;
5 |
6 | #[wasm_bindgen]
7 | extern {
8 | fn alert(s: &str);
9 | }
10 |
11 | #[wasm_bindgen]
12 | pub fn greet(name: &str) {
13 | alert(&format!("Hello, {}!", name));
14 | }
--------------------------------------------------------------------------------
/packages/rust-wasm-bindgen/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 |
3 | module.exports = {
4 | entry: './src/index.js',
5 | output: {
6 | path: path.resolve(__dirname, 'dist'),
7 | filename: 'index.js',
8 | publicPath: 'src'
9 | },
10 | mode: 'development'
11 | };
--------------------------------------------------------------------------------
/packages/rust-wasm-pack/.gitignore:
--------------------------------------------------------------------------------
1 | pkg
2 | target
--------------------------------------------------------------------------------
/packages/rust-wasm-pack/Cargo.lock:
--------------------------------------------------------------------------------
1 | # This file is automatically @generated by Cargo.
2 | # It is not intended for manual editing.
3 | [[package]]
4 | name = "bumpalo"
5 | version = "2.6.0"
6 | source = "registry+https://github.com/rust-lang/crates.io-index"
7 |
8 | [[package]]
9 | name = "cfg-if"
10 | version = "0.1.10"
11 | source = "registry+https://github.com/rust-lang/crates.io-index"
12 |
13 | [[package]]
14 | name = "lazy_static"
15 | version = "1.4.0"
16 | source = "registry+https://github.com/rust-lang/crates.io-index"
17 |
18 | [[package]]
19 | name = "log"
20 | version = "0.4.8"
21 | source = "registry+https://github.com/rust-lang/crates.io-index"
22 | dependencies = [
23 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
24 | ]
25 |
26 | [[package]]
27 | name = "proc-macro2"
28 | version = "1.0.6"
29 | source = "registry+https://github.com/rust-lang/crates.io-index"
30 | dependencies = [
31 | "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
32 | ]
33 |
34 | [[package]]
35 | name = "quote"
36 | version = "1.0.2"
37 | source = "registry+https://github.com/rust-lang/crates.io-index"
38 | dependencies = [
39 | "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
40 | ]
41 |
42 | [[package]]
43 | name = "square"
44 | version = "0.1.0"
45 | dependencies = [
46 | "wasm-bindgen 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
47 | ]
48 |
49 | [[package]]
50 | name = "syn"
51 | version = "1.0.8"
52 | source = "registry+https://github.com/rust-lang/crates.io-index"
53 | dependencies = [
54 | "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
55 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
56 | "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
57 | ]
58 |
59 | [[package]]
60 | name = "unicode-xid"
61 | version = "0.2.0"
62 | source = "registry+https://github.com/rust-lang/crates.io-index"
63 |
64 | [[package]]
65 | name = "wasm-bindgen"
66 | version = "0.2.54"
67 | source = "registry+https://github.com/rust-lang/crates.io-index"
68 | dependencies = [
69 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
70 | "wasm-bindgen-macro 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
71 | ]
72 |
73 | [[package]]
74 | name = "wasm-bindgen-backend"
75 | version = "0.2.54"
76 | source = "registry+https://github.com/rust-lang/crates.io-index"
77 | dependencies = [
78 | "bumpalo 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
79 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
80 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
81 | "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
82 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
83 | "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
84 | "wasm-bindgen-shared 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
85 | ]
86 |
87 | [[package]]
88 | name = "wasm-bindgen-macro"
89 | version = "0.2.54"
90 | source = "registry+https://github.com/rust-lang/crates.io-index"
91 | dependencies = [
92 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
93 | "wasm-bindgen-macro-support 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
94 | ]
95 |
96 | [[package]]
97 | name = "wasm-bindgen-macro-support"
98 | version = "0.2.54"
99 | source = "registry+https://github.com/rust-lang/crates.io-index"
100 | dependencies = [
101 | "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
102 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
103 | "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
104 | "wasm-bindgen-backend 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
105 | "wasm-bindgen-shared 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
106 | ]
107 |
108 | [[package]]
109 | name = "wasm-bindgen-shared"
110 | version = "0.2.54"
111 | source = "registry+https://github.com/rust-lang/crates.io-index"
112 |
113 | [metadata]
114 | "checksum bumpalo 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ad807f2fc2bf185eeb98ff3a901bd46dc5ad58163d0fa4577ba0d25674d71708"
115 | "checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
116 | "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
117 | "checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
118 | "checksum proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9c9e470a8dc4aeae2dee2f335e8f533e2d4b347e1434e5671afc49b054592f27"
119 | "checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
120 | "checksum syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "661641ea2aa15845cddeb97dad000d22070bb5c1fb456b96c1cba883ec691e92"
121 | "checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
122 | "checksum wasm-bindgen 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)" = "c4568ae1b4e07ca907b1a4de41174eaa3e5be4066c024475586b7842725f69a9"
123 | "checksum wasm-bindgen-backend 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5a00cfdce37367770062065fd3abb9278cbae86a0d918cacd0978a7acd51b481"
124 | "checksum wasm-bindgen-macro 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)" = "7c568f4d3cf6d7c1d72b165daf778fb0d6e09a24f96ac14fc8c4f66a96e86b72"
125 | "checksum wasm-bindgen-macro-support 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)" = "430d12539ae324d16097b399e9d07a6d5ce0173b2a61a2d02346ca7c198daffe"
126 | "checksum wasm-bindgen-shared 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)" = "8ae7167f0bbffd7fac2b12da0fa1f834c1d84671a1ae3c93ac8bde2e97179c39"
127 |
--------------------------------------------------------------------------------
/packages/rust-wasm-pack/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "square"
3 | version = "0.1.0"
4 | authors = ["Jimmy Moon "]
5 | edition = "2018"
6 |
7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8 |
9 | [lib]
10 | crate-type = ["cdylib"]
11 |
12 | [dependencies]
13 | wasm-bindgen = "0.2"
14 |
--------------------------------------------------------------------------------
/packages/rust-wasm-pack/build.sh:
--------------------------------------------------------------------------------
1 | mkdir -p pkg
2 | rustc --target wasm32-unknown-unknown -O ./src/lib.rs -o ./pkg/square.wasm
3 |
--------------------------------------------------------------------------------
/packages/rust-wasm-pack/index.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/rust-wasm-pack/readme.md:
--------------------------------------------------------------------------------
1 | # rust-wasm-pack example
2 |
3 | > Build wasm by [wasm-pack](https://github.com/rustwasm/wasm-pack)
4 |
5 | # How to run
6 |
7 | ```sh
8 | # build
9 | wasm-pack build
10 |
11 | # run webserver by command-based
12 | serve .
13 | ```
14 |
15 | # License
16 |
17 | MIT @ Jimmy Moon
--------------------------------------------------------------------------------
/packages/rust-wasm-pack/src/lib.rs:
--------------------------------------------------------------------------------
1 | pub fn main() {}
2 |
3 | #[no_mangle]
4 | pub extern fn square (x: u32) -> u32 {
5 | x * x
6 | }
--------------------------------------------------------------------------------
/packages/rust-webgl/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": [
3 | "transform-object-rest-spread",
4 | ["transform-runtime", {
5 | "polyfill": false,
6 | "regenerator": true
7 | }]
8 | ]
9 | }
--------------------------------------------------------------------------------
/packages/rust-webgl/.gitignore:
--------------------------------------------------------------------------------
1 | dist
2 | node_modules
3 | .cache
4 | .vscode
5 |
6 | /target
7 | **/*.rs.bk
8 |
9 | /target
10 | **/*.rs.bk
11 |
12 | /target
13 | **/*.rs.bk
14 |
15 | /target
16 | **/*.rs.bk
17 |
18 | /target
19 | **/*.rs.bk
20 |
--------------------------------------------------------------------------------
/packages/rust-webgl/Cargo.lock:
--------------------------------------------------------------------------------
1 | [[package]]
2 | name = "bitflags"
3 | version = "1.0.3"
4 | source = "registry+https://github.com/rust-lang/crates.io-index"
5 |
6 | [[package]]
7 | name = "cfg-if"
8 | version = "0.1.4"
9 | source = "registry+https://github.com/rust-lang/crates.io-index"
10 |
11 | [[package]]
12 | name = "gl_generator"
13 | version = "0.9.0"
14 | source = "registry+https://github.com/rust-lang/crates.io-index"
15 | dependencies = [
16 | "khronos_api 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
17 | "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
18 | "xml-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
19 | ]
20 |
21 | [[package]]
22 | name = "gleam"
23 | version = "0.5.1"
24 | source = "registry+https://github.com/rust-lang/crates.io-index"
25 | dependencies = [
26 | "gl_generator 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
27 | ]
28 |
29 | [[package]]
30 | name = "khronos_api"
31 | version = "2.2.0"
32 | source = "registry+https://github.com/rust-lang/crates.io-index"
33 |
34 | [[package]]
35 | name = "log"
36 | version = "0.4.3"
37 | source = "registry+https://github.com/rust-lang/crates.io-index"
38 | dependencies = [
39 | "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
40 | ]
41 |
42 | [[package]]
43 | name = "triangle"
44 | version = "0.1.0"
45 | dependencies = [
46 | "gleam 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
47 | ]
48 |
49 | [[package]]
50 | name = "xml-rs"
51 | version = "0.7.0"
52 | source = "registry+https://github.com/rust-lang/crates.io-index"
53 | dependencies = [
54 | "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
55 | ]
56 |
57 | [metadata]
58 | "checksum bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c54bb8f454c567f21197eefcdbf5679d0bd99f2ddbe52e84c77061952e6789"
59 | "checksum cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "efe5c877e17a9c717a0bf3613b2709f723202c4e4675cc8f12926ded29bcb17e"
60 | "checksum gl_generator 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a795170cbd85b5a7baa58d6d7525cae6a03e486859860c220f7ebbbdd379d0a"
61 | "checksum gleam 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "12b793fcf40a23dd372f184c228ab3eb96f88c50bb4fba8319c483aa025a4e45"
62 | "checksum khronos_api 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "037ab472c33f67b5fbd3e9163a2645319e5356fcd355efa6d4eb7fff4bbcb554"
63 | "checksum log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "61bd98ae7f7b754bc53dca7d44b604f733c6bba044ea6f41bc8d89272d8161d2"
64 | "checksum xml-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c1cb601d29fe2c2ac60a2b2e5e293994d87a1f6fa9687a31a15270f909be9c2"
65 |
--------------------------------------------------------------------------------
/packages/rust-webgl/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "triangle"
3 | version = "0.1.0"
4 | authors = ["Jimmy Moon "]
5 |
6 | [dependencies]
7 | gleam = "0.5.1"
--------------------------------------------------------------------------------
/packages/rust-webgl/README.md:
--------------------------------------------------------------------------------
1 | # Usage
2 |
3 | ```sh
4 | # install deps (rust/cargo must be installed before build)
5 | yarn install
6 |
7 | # build rs to wasm with rust
8 | yarn build
9 |
10 | # serve and go to the server, http://localhost:8080
11 | yarn start
12 | ```
13 |
14 | # References
15 |
16 | - [WebGL context](https://goo.gl/NgRnm6)
17 | - [gleam - Rust](https://goo.gl/UXRADj)
18 | - [likr/rust-webgl2-example](https://goo.gl/YBj58c)
19 |
--------------------------------------------------------------------------------
/packages/rust-webgl/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | TRIAGNLES - WEBGL
7 |
8 |
9 |
10 |
11 |
20 |
21 |
--------------------------------------------------------------------------------
/packages/rust-webgl/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rust-webgl",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "author": "Jimmy Moon ",
6 | "license": "MIT",
7 | "scripts": {
8 | "start": "parcel index.html --open -p 8080",
9 | "build": "parcel build index.html --out-dir ./dist && npm run cargo",
10 | "cargo": "cargo build --release --target=wasm32-unknown-emscripten && cp target/wasm32-unknown-emscripten/release/*.js ./dist && cp target/wasm32-unknown-emscripten/release/*.wasm ./dist"
11 | },
12 | "devDependencies": {
13 | "babel-plugin-transform-object-rest-spread": "^6.26.0",
14 | "babel-plugin-transform-runtime": "^6.23.0",
15 | "parcel-bundler": "^1.9.4"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/packages/rust-webgl/src/main.rs:
--------------------------------------------------------------------------------
1 | use std::rc::Rc;
2 |
3 | extern crate gleam;
4 | use gleam::gl;
5 | use gleam::gl::{GLenum};
6 |
7 | mod webgl;
8 | use webgl::{
9 | emscripten_GetProcAddress, emscripten_get_element_css_size,
10 | emscripten_webgl_create_context, emscripten_webgl_init_context_attributes,
11 | emscripten_webgl_make_context_current, EmscriptenWebGLContextAttributes,
12 | };
13 |
14 | const VERTICES: [f32; 6] = [
15 | 0.0, 0.5,
16 | 0.5, -0.5,
17 | -0.5, -0.5,
18 | ];
19 |
20 | const INDICES: [u16; 3] = [0, 1, 2];
21 |
22 | const VERT_CODE: &[&[u8]] = &[b"
23 | attribute vec3 coordinates;
24 | void main(void) {
25 | gl_Position = vec4(coordinates, 1.0);
26 | }"
27 | ];
28 |
29 | const FRAG_CODE: &[&[u8]] = &[b"
30 | void main(void) {
31 | gl_FragColor = vec4(1.0, 1.0, 1.0, 1);
32 | }"
33 | ];
34 |
35 | fn get_canvas_size() -> (u32, u32) {
36 | unsafe {
37 | let mut width = std::mem::uninitialized();
38 | let mut height = std::mem::uninitialized();
39 | emscripten_get_element_css_size(std::ptr::null(), &mut width, &mut height);
40 | (width as u32, height as u32)
41 | }
42 | }
43 |
44 | fn init_webgl() -> Rc {
45 | unsafe {
46 | let mut attributes: EmscriptenWebGLContextAttributes = std::mem::uninitialized();
47 | emscripten_webgl_init_context_attributes(&mut attributes);
48 | attributes.majorVersion = 2;
49 |
50 | let handle = emscripten_webgl_create_context(std::ptr::null(), &attributes);
51 | emscripten_webgl_make_context_current(handle);
52 |
53 | return gl::GlesFns::load_with(|addr| {
54 | let addr = std::ffi::CString::new(addr).unwrap();
55 | emscripten_GetProcAddress(addr.into_raw() as *const _) as *const _
56 | });
57 | }
58 | }
59 |
60 | fn create_buffer(gl: &Rc, vertices: Vec, indices: Vec) {
61 | let buffers = gl.gen_buffers(2);
62 | let vertex_buffer = buffers[0];
63 |
64 | gl.bind_buffer(gl::ARRAY_BUFFER, vertex_buffer);
65 | gl.buffer_data_untyped(
66 | gl::ARRAY_BUFFER,
67 | 4 * vertices.len() as isize,
68 | vertices.as_ptr() as *const _,
69 | gl::STATIC_DRAW,
70 | );
71 |
72 | let element_buffer = buffers[1];
73 | gl.bind_buffer(gl::ELEMENT_ARRAY_BUFFER, element_buffer);
74 | gl.buffer_data_untyped(
75 | gl::ELEMENT_ARRAY_BUFFER,
76 | 2 * indices.len() as isize,
77 | indices.as_ptr() as *const _,
78 | gl::STATIC_DRAW,
79 | );
80 | }
81 |
82 | fn create_shader(gl: &Rc, shader_type: GLenum, code: &[&[u8]]) -> u32 {
83 | let shader = gl.create_shader(shader_type);
84 | gl.shader_source(shader, code);
85 | gl.compile_shader(shader);
86 |
87 | let mut compiled = [0];
88 | unsafe {
89 | gl.get_shader_iv(shader, gl::COMPILE_STATUS, &mut compiled);
90 | }
91 |
92 | if compiled[0] == 0 {
93 | gl.delete_shader(shader);
94 | }
95 |
96 | return shader;
97 | }
98 |
99 | fn create_shaders(gl: &Rc, vert_code: &[&[u8]], frag_code: &[&[u8]]) {
100 | let vert_shader = create_shader(gl, gl::VERTEX_SHADER, vert_code);
101 | let frag_shader = create_shader(gl, gl::FRAGMENT_SHADER, frag_code);
102 | let program = gl.create_program();
103 |
104 | gl.attach_shader(program, vert_shader);
105 | gl.attach_shader(program, frag_shader);
106 | gl.link_program(program);
107 | gl.use_program(program);
108 |
109 | let coordinate_var = gl.get_attrib_location(program, "coordinates") as u32;
110 | gl.enable_vertex_attrib_array(coordinate_var);
111 | gl.vertex_attrib_pointer(coordinate_var, 2, gl::FLOAT, false, 0, 0);
112 | }
113 |
114 | fn draw(gl: &Rc) {
115 | let (width, height) = get_canvas_size();
116 | gl.viewport(0, 0, width as i32, height as i32);
117 | gl.clear_color(0.0, 0.0, 0.0, 1.0);
118 | gl.clear(gl::COLOR_BUFFER_BIT);
119 | gl.draw_elements(gl::TRIANGLES, 3, gl::UNSIGNED_SHORT, 0);
120 | }
121 |
122 | pub fn main() {
123 | let gl = init_webgl();
124 | create_buffer(&gl, VERTICES.to_vec(), INDICES.to_vec());
125 | create_shaders(&gl, VERT_CODE, FRAG_CODE);
126 | draw(&gl);
127 | }
128 |
--------------------------------------------------------------------------------
/packages/rust-webgl/src/webgl.rs:
--------------------------------------------------------------------------------
1 | #![allow(non_camel_case_types)]
2 | #![allow(non_snake_case)]
3 |
4 | pub type EMSCRIPTEN_WEBGL_CONTEXT_HANDLE = ::std::os::raw::c_int;
5 |
6 | #[repr(C)]
7 | #[derive(Debug, Copy)]
8 | pub struct EmscriptenWebGLContextAttributes {
9 | pub alpha: ::std::os::raw::c_int,
10 | pub depth: ::std::os::raw::c_int,
11 | pub stencil: ::std::os::raw::c_int,
12 | pub antialias: ::std::os::raw::c_int,
13 | pub premultipliedAlpha: ::std::os::raw::c_int,
14 | pub preserveDrawingBuffer: ::std::os::raw::c_int,
15 | pub preferLowPowerToHighPerformance: ::std::os::raw::c_int,
16 | pub failIfMajorPerformanceCaveat: ::std::os::raw::c_int,
17 | pub majorVersion: ::std::os::raw::c_int,
18 | pub minorVersion: ::std::os::raw::c_int,
19 | pub enableExtensionsByDefault: ::std::os::raw::c_int,
20 | pub explicitSwapControl: ::std::os::raw::c_int,
21 | }
22 |
23 | impl Clone for EmscriptenWebGLContextAttributes {
24 | fn clone(&self) -> Self {
25 | *self
26 | }
27 | }
28 |
29 | extern "C" {
30 | pub fn emscripten_GetProcAddress(
31 | name: *const ::std::os::raw::c_char,
32 | ) -> *const ::std::os::raw::c_void;
33 |
34 | pub fn emscripten_webgl_init_context_attributes(
35 | attributes: *mut EmscriptenWebGLContextAttributes,
36 | );
37 |
38 | pub fn emscripten_webgl_create_context(
39 | target: *const ::std::os::raw::c_char,
40 | attributes: *const EmscriptenWebGLContextAttributes,
41 | ) -> EMSCRIPTEN_WEBGL_CONTEXT_HANDLE;
42 |
43 | pub fn emscripten_webgl_make_context_current(
44 | context: EMSCRIPTEN_WEBGL_CONTEXT_HANDLE,
45 | ) -> ::std::os::raw::c_int;
46 |
47 | pub fn emscripten_get_element_css_size(
48 | target: *const ::std::os::raw::c_char,
49 | width: *mut f64,
50 | height: *mut f64,
51 | ) -> ::std::os::raw::c_int;
52 | }
53 |
--------------------------------------------------------------------------------
/packages/rust/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/packages/rust/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "clang",
3 | "version": "0.0.0",
4 | "scripts": {
5 | "start": "../node_modules/.bin/serve .",
6 | "build:wasm": "rustc --target wasm32-unknown-unknown -O ./wasm/math.rs -o ./wasm/math.wasm",
7 | "build": "npm run build:wasm"
8 | }
9 | }
--------------------------------------------------------------------------------
/packages/rust/readme.md:
--------------------------------------------------------------------------------
1 | # add target
2 |
3 | ```
4 | rustup update
5 | rustup target add wasm32-unknown-unknown
6 | ```
7 |
8 | # License
9 |
10 | MIT @ CODEBUSKING
--------------------------------------------------------------------------------
/packages/rust/wasm-loader.js:
--------------------------------------------------------------------------------
1 | function setEnvironment({env = {}}) {
2 | if (!env.memory) {
3 | env.memory = new WebAssembly.Memory({
4 | initial: 256,
5 | maximum: 256
6 | })
7 | }
8 |
9 | if (!env.table) {
10 | env.table = new WebAssembly.Table({
11 | initial: 0,
12 | maximum: 0,
13 | element: 'anyfunc'
14 | })
15 | }
16 |
17 | return {
18 | ...{
19 | tableBase: 0,
20 | memoryBase: 0,
21 | STACKTOP: 0,
22 | STACK_MAX: env.memory.buffer.byteLength,
23 | abortStackOverflow() {},
24 | abort() {}
25 | },
26 | ...env
27 | }
28 | }
29 |
30 | async function wasmInstantiate(req, importObject = {}) {
31 | const bytes = await window.fetch(req).then(x => x.arrayBuffer())
32 |
33 | importObject = {
34 | global: {},
35 | ...importObject,
36 | env: setEnvironment(importObject)
37 | }
38 |
39 | return {
40 | ...await WebAssembly.instantiate(bytes, importObject),
41 | ...importObject
42 | }
43 | }
--------------------------------------------------------------------------------
/packages/rust/wasm/math.rs:
--------------------------------------------------------------------------------
1 | pub fn main() {}
2 |
3 | #[no_mangle]
4 | pub extern fn square (x: u32) -> u32 {
5 | x * x
6 | }
--------------------------------------------------------------------------------
/packages/rust/wasm/math.wasm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ragingwind/wasm-helloworld/3b49e9f944cfb94191dd6312517b96c444544080/packages/rust/wasm/math.wasm
--------------------------------------------------------------------------------
/packages/ts-assembly-script/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/packages/ts-assembly-script/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "clang",
3 | "version": "0.0.0",
4 | "scripts": {
5 | "start": "../node_modules/.bin/serve .",
6 | "build:wasm": " asc ./wasm/fibonacci.ts -o ./wasm/fibonacci.wasm --optimize --validate --sourceMap",
7 | "build": "npm run build:wasm"
8 | },
9 | "devDependencies": {
10 | "assemblyscript": "AssemblyScript/assemblyscript"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/packages/ts-assembly-script/readme.md:
--------------------------------------------------------------------------------
1 | # Hello World for WASM with AssemblyScript
2 |
3 | - [More types](https://github.com/AssemblyScript/assemblyscript/wiki/Types)
--------------------------------------------------------------------------------
/packages/ts-assembly-script/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../node_modules/assemblyscript/std/assembly.json",
3 | "include": [
4 | "./**/*.ts"
5 | ]
6 | }
--------------------------------------------------------------------------------
/packages/ts-assembly-script/wasm-loader.js:
--------------------------------------------------------------------------------
1 | function setEnvironment({env = {}}) {
2 | if (!env.memory) {
3 | env.memory = new WebAssembly.Memory({
4 | initial: 256,
5 | maximum: 256
6 | })
7 | }
8 |
9 | if (!env.table) {
10 | env.table = new WebAssembly.Table({
11 | initial: 0,
12 | maximum: 0,
13 | element: 'anyfunc'
14 | })
15 | }
16 |
17 | return {
18 | ...{
19 | tableBase: 0,
20 | memoryBase: 0,
21 | STACKTOP: 0,
22 | STACK_MAX: env.memory.buffer.byteLength,
23 | abortStackOverflow() {},
24 | abort() {}
25 | },
26 | ...env
27 | }
28 | }
29 |
30 | async function wasmInstantiate(req, importObject = {}) {
31 | const bytes = await window.fetch(req).then(x => x.arrayBuffer())
32 |
33 | importObject = {
34 | global: {},
35 | ...importObject,
36 | env: setEnvironment(importObject)
37 | }
38 |
39 | return {
40 | ...await WebAssembly.instantiate(bytes, importObject),
41 | ...importObject
42 | }
43 | }
--------------------------------------------------------------------------------
/packages/ts-assembly-script/wasm/fibonacci.ts:
--------------------------------------------------------------------------------
1 | export function fibonacci (n: i32): i32 {
2 | n = n | 0;
3 | if (n < 2) {
4 | return 1
5 | }
6 | return (fibonacci(n - 2) | 0) + (fibonacci(n - 1) | 0) | 0
7 | }
--------------------------------------------------------------------------------
/packages/ts-assembly-script/wasm/fibonacci.wasm:
--------------------------------------------------------------------------------
1 | asm ` fibonacci memory
2 | AH@A Ak Ak j "name wasm/fibonacci/fibonacci $sourceMappingURLfibonacci.wasm.map
--------------------------------------------------------------------------------
/packages/ts-assembly-script/wasm/fibonacci.wasm.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["wasm/fibonacci.ts"],"names":[],"mappings":"8DAEE,AAAI,AADA,EACI,SAGD,AAAC,AAAU,EAAI,KAAW,AAAU,EAAI","sourceRoot":"assemblyscript:///","sourceContents":["export function fibonacci (n: i32): i32 {\n n = n | 0;\n if (n < 2) {\n return 1\n }\n return (fibonacci(n - 2) | 0) + (fibonacci(n - 1) | 0) | 0\n}"]}
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # Hello World for WebAssembly
2 |
3 | > The first step for beginners about WASM, WebAssembly
4 |
5 | # Prerequisites
6 |
7 | WebAssembly is required bunch of preperations for compiling native soruce codes. While you use emscripten directly install on your system, Surmma at Google Chrome Team suggests [the alternative way](https://developers.google.com/web/updates/2018/03/emscripting-a-c-library) with docker.
8 |
9 | ## Build Environment with Docker
10 |
11 | ## Build Environment with Emscripten Toolchain
12 |
13 | - Setup git, CMake, gcc and python on your system
14 | - Install [Emscripten toolchain](http://webassembly.org/getting-started/developers-guide/) and [The WebAssembly Binary Toolkit](https://github.com/WebAssembly/wabt)
15 | - Install compilers for Go, Rust and C/C++
16 |
17 | # Installation Dependencies
18 |
19 | Each demo has own npm dependencies or own environment to build and start application. In case of Node.js environment, for getting convenience of installation, you should install dependencies with `yarn install --modules-folder=../node_modules`
20 |
21 | # Demos
22 |
23 | ## C/C++ Languages
24 | - clang: Emscripten and WASM APIs, Basic sample, show two of types compiling, static and dynamic
25 | - clang-thread: Show how to use c with thread. Implementation of official sample from Google\
26 | - clang-array: Show how to manage numberic array
27 | - clang-simd: Show how WASM is working with SIMD
28 |
29 | ## Rust Languages
30 | - rust: Rust Language with Emscripten and WASM APIs
31 | - rust-parcel: Rust Language with parcel bundler
32 | - rust-thread
33 | - rust-wasm-bindgen: Rust Language with wasm-bindgen
34 | - rust-wasm-pack
35 | - rust-webgl
36 | - rust-wasi-node: WASI demo with Rust and Node.js
37 |
38 | ## Typescript
39 | - ts-assembly-script: Typescript(AssemblyScript) with WASM APIs
40 |
41 | ## Golang
42 | - go: Go with WASM
43 |
44 | ## asm.js
45 | - asm-webpack: asm.js with WABT and webpack 4
46 |
47 | # License
48 |
49 | MIT @ Jimmy Moon
50 |
--------------------------------------------------------------------------------