├── .github └── workflows │ └── test.yml ├── .gitignore ├── LICENSE ├── README.md ├── game-of-life ├── README.md ├── asconfig.json ├── assembly │ ├── config.ts │ ├── index.ts │ └── tsconfig.json ├── build │ ├── .gitignore │ └── release.wasm ├── index.html ├── package.json └── preview.jpg ├── i64 ├── README.md ├── asconfig.json ├── assembly │ ├── i64.ts │ └── tsconfig.json ├── build │ └── .gitignore ├── index.d.ts ├── index.js ├── package.json └── tests │ └── index.js ├── interference ├── README.md ├── assembly │ ├── index.ts │ └── tsconfig.json ├── build │ ├── .gitignore │ └── optimized.wasm ├── index.html ├── package.json └── preview.jpg ├── libm ├── README.md ├── assembly │ ├── libm.ts │ ├── libmf.ts │ └── tsconfig.json ├── build │ └── .gitignore ├── index.d.ts ├── index.js ├── package.json └── tests │ └── index.js ├── loader ├── README.md ├── assembly │ ├── index.ts │ ├── myConsole.ts │ └── tsconfig.json ├── build │ ├── .gitignore │ └── optimized.wasm ├── index.js ├── package.json ├── preview.jpg └── tests │ └── index.js ├── mandelbrot ├── README.md ├── asconfig.json ├── assembly │ ├── index.ts │ └── tsconfig.json ├── build │ ├── .gitignore │ └── release.wasm ├── index.html ├── index.js ├── package.json └── preview.jpg ├── n-body ├── README.md ├── asconfig.json ├── assembly │ ├── index.js │ ├── index.ts │ └── tsconfig.json ├── build │ ├── .gitignore │ └── as_nbody.wasm ├── index.html ├── package.json ├── preview.jpg ├── rust │ ├── .cargo │ │ └── config │ ├── .gitignore │ ├── Cargo.lock │ ├── Cargo.toml │ ├── README.md │ ├── index.js │ └── src │ │ └── lib.rs ├── scripts │ └── postprocess.js └── tests │ └── index.js ├── parse ├── README.md ├── assembly │ ├── index.ts │ ├── options.ts │ └── tsconfig.json ├── build │ ├── .gitignore │ └── index.wat ├── index.d.ts ├── index.js ├── index.js.map ├── package.json ├── src │ ├── common.ts │ ├── index.ts │ └── tsconfig.json ├── tests │ ├── index.ts │ └── libm.wasm └── webpack.config.js ├── sdk ├── README.md ├── index.html ├── package.json └── preview.jpg └── transform ├── README.md ├── assembly └── index.ts ├── mytransform.mjs └── package.json /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | 2 | name: Test 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | schedule: 9 | - cron: '30 0 * * *' 10 | jobs: 11 | game-of-life: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v1 15 | - uses: dcodeIO/setup-node-nvm@master 16 | with: 17 | node-version: current 18 | - name: Test 19 | run: | 20 | cd game-of-life 21 | npm install 22 | npm run asbuild 23 | i64: 24 | runs-on: ubuntu-latest 25 | steps: 26 | - uses: actions/checkout@v1 27 | - uses: dcodeIO/setup-node-nvm@master 28 | with: 29 | node-version: current 30 | - name: Test 31 | run: | 32 | cd i64 33 | npm install 34 | npm run asbuild 35 | npm test 36 | interference: 37 | runs-on: ubuntu-latest 38 | steps: 39 | - uses: actions/checkout@v1 40 | - uses: dcodeIO/setup-node-nvm@master 41 | with: 42 | node-version: current 43 | - name: Test 44 | run: | 45 | cd interference 46 | npm install 47 | npm run asbuild 48 | libm: 49 | runs-on: ubuntu-latest 50 | steps: 51 | - uses: actions/checkout@v1 52 | - uses: dcodeIO/setup-node-nvm@master 53 | with: 54 | node-version: current 55 | - name: Test 56 | run: | 57 | cd libm 58 | npm install 59 | npm run asbuild 60 | npm test 61 | loader: 62 | runs-on: ubuntu-latest 63 | steps: 64 | - uses: actions/checkout@v1 65 | - uses: dcodeIO/setup-node-nvm@master 66 | with: 67 | node-version: current 68 | - name: Test 69 | run: | 70 | cd loader 71 | npm install 72 | npm run asbuild 73 | npm test 74 | mandelbrot: 75 | runs-on: ubuntu-latest 76 | steps: 77 | - uses: actions/checkout@v1 78 | - uses: dcodeIO/setup-node-nvm@master 79 | with: 80 | node-version: current 81 | - name: Test 82 | run: | 83 | cd mandelbrot 84 | npm install 85 | npm run asbuild 86 | n-body: 87 | runs-on: ubuntu-latest 88 | steps: 89 | - uses: actions/checkout@v1 90 | - uses: dcodeIO/setup-node-nvm@master 91 | with: 92 | node-version: current 93 | - name: Test 94 | run: | 95 | cd n-body 96 | npm install 97 | npm run asbuild 98 | # npm test 99 | transform: 100 | runs-on: ubuntu-latest 101 | steps: 102 | - uses: actions/checkout@v1 103 | - uses: dcodeIO/setup-node-nvm@master 104 | with: 105 | node-version: current 106 | - name: Test 107 | run: | 108 | cd transform 109 | npm install 110 | npm test 111 | parse: 112 | runs-on: ubuntu-latest 113 | steps: 114 | - uses: actions/checkout@v1 115 | - uses: dcodeIO/setup-node-nvm@master 116 | with: 117 | node-version: current 118 | - name: Test 119 | run: | 120 | cd parse 121 | npm install 122 | npm run build 123 | npm test 124 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | package-lock.json 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 The AssemblyScript Project 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![](https://avatars1.githubusercontent.com/u/28916798?s=64) AssemblyScript Examples 2 | ======================= 3 | 4 | [![Actions Status](https://github.com/AssemblyScript/examples/workflows/Test/badge.svg?branch=main)](https://github.com/AssemblyScript/examples/actions) 5 | 6 | ## Instructions 7 | 8 | This repository contains one example per directory. All examples can be obtained by cloning the repository: 9 | 10 | ``` 11 | $> git clone https://github.com/AssemblyScript/examples.git 12 | $> cd examples 13 | ``` 14 | 15 | Afterwards, select the example you'd like to run and follow the instructions in its README file. 16 | 17 | ## Low-level perspective 18 | 19 | The following examples make use of AssemblyScript's low-level capabilities, i.e. to essentially write WebAssembly with a nicer syntax. 20 | 21 | * [Conway's Game Of Life](./game-of-life) ([demo](https://assemblyscript.github.io/examples/game-of-life/))
22 | An implementation of the game of life with slight modifications. Updates an image buffer in memory, that is then presented on a canvas. 23 | 24 | 25 | 26 | * [Mandelbrot Set](./mandelbrot) ([demo](https://assemblyscript.github.io/examples/mandelbrot/))
27 | Computes 2048 offsets of a color gradient in memory, line by line, and presents the set using the gradient's actual colors, as computed on the JavaScript side, on a canvas. 28 | 29 | 30 | 31 | * [Interference effect](./interference) ([demo](https://assemblyscript.github.io/examples/interference/))
32 | Colin Eberhardt's and Ben Smith's WebAssembly interference effect, if it was written in AssemblyScript. 33 | 34 | 35 | 36 | ## High-level perspective 37 | 38 | These examples cover slightly higher level aspects, like working with managed objects or interfacing with them. 39 | 40 | * [N-body system](./n-body) ([demo](https://assemblyscript.github.io/examples/n-body/))
41 | This is actually a benchmark - visualizing it just so happened. 42 | 43 | 44 | 45 | * [Loader](./loader)
46 | Utilizes the [loader](https://docs.assemblyscript.org/basics/loader) to perform various common tasks on the WebAssembly/JavaScript boundary, like passing along strings and arrays between both worlds. 47 | 48 | 49 | 50 | ## Libraries 51 | 52 | Various WebAssembly or AssemblyScript features as a library. 53 | 54 | * [i64](./i64)
55 | Exposes WebAssembly's i64 operations to JavaScript using 32-bit integers (low and high bits). 56 | 57 | * [libm](./libm)
58 | Exposes AssemblyScript's math routines for double and single precision as a library. 59 | 60 | ## Features 61 | 62 | General examples showing how to utilize specific AssemblyScript features. 63 | 64 | * [Browser SDK](./sdk) ([demo](https://assemblyscript.github.io/examples/sdk/))
65 | Shows how to use the browser SDK to run the AssemblyScript compiler in the browser. 66 | 67 | 68 | 69 | * [Compiler transforms](./transform)
70 | An example of using compiler transforms to hook into the compilation process. 71 | 72 | ## Additional resources 73 | 74 | * [Wasm By Example](https://wasmbyexample.dev/all-examples-list.html)
75 | A concise, hands-on introduction to WebAssembly using code snippets and annotated example programs. If you "learn best by doing", or just need a good starting point for a concept, this is the place for you. 76 | 77 | * [Built with AssemblyScript](https://www.assemblyscript.org/built-with-assemblyscript.html)
78 | A list of more sophisticated open source projects using AssemblyScript. 79 | -------------------------------------------------------------------------------- /game-of-life/README.md: -------------------------------------------------------------------------------- 1 | Conway's Game of Life 2 | ===================== 3 | 4 | An [AssemblyScript](http://assemblyscript.org) example. Continuously updates the cellular automaton and visualizes its state on a canvas. Compiles to ~940 bytes of optimized WASM. 5 | 6 | Instructions 7 | ------------ 8 | 9 | First, install the development dependencies: 10 | 11 | ``` 12 | $> npm install 13 | ``` 14 | 15 | Now, to build [assembly/index.ts](./assembly/index.ts) to an untouched and an optimized `.wasm` including their respective `.wat` representations, run: 16 | 17 | ``` 18 | $> npm run asbuild 19 | ``` 20 | 21 | Afterwards, run 22 | 23 | ``` 24 | $> npm start 25 | ``` 26 | 27 | to start a local server. 28 | -------------------------------------------------------------------------------- /game-of-life/asconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "options": { 3 | "runtime": "stub", 4 | "use": "Math=JSMath", 5 | "importMemory": true, 6 | "sourceMap": true, 7 | "measure": true 8 | }, 9 | "targets": { 10 | "debug": { 11 | "outFile": "build/debug.wasm", 12 | "textFile": "build/debug.wat", 13 | "debug": true 14 | }, 15 | "release": { 16 | "outFile": "build/release.wasm", 17 | "textFile": "build/release.wat", 18 | "optimizeLevel": 3, 19 | "shrinkLevel": 0, 20 | "noAssert": true 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /game-of-life/assembly/config.ts: -------------------------------------------------------------------------------- 1 | // On the WASM side, 32-bit color values are modified in ABGR order (alpha, blue, green, red) 2 | // because WASM is little endian. This results in RGBA in memory, which is exactly what the image 3 | // buffer, composed of 8-bit components, expects on the JS side. 4 | export declare const BGR_ALIVE: u32; 5 | export declare const BGR_DEAD: u32; 6 | export declare const BIT_ROT: u32; 7 | -------------------------------------------------------------------------------- /game-of-life/assembly/index.ts: -------------------------------------------------------------------------------- 1 | // see: https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life 2 | 3 | // Configuration imported from JS 4 | import { BGR_ALIVE, BGR_DEAD, BIT_ROT } from "./config"; 5 | 6 | var width: i32, height: i32, offset: i32; 7 | 8 | /** Gets an input pixel in the range [0, s]. */ 9 | // @ts-ignore: decorator 10 | @inline 11 | function get(x: u32, y: u32): u32 { 12 | return load((y * width + x) << 2); 13 | } 14 | 15 | /** Sets an output pixel in the range [s, 2*s]. */ 16 | // @ts-ignore: decorator 17 | @inline 18 | function set(x: u32, y: u32, v: u32): void { 19 | store((offset + y * width + x) << 2, v); 20 | } 21 | 22 | /** Sets an output pixel in the range [s, 2*s] while fading it out. */ 23 | // @ts-ignore: decorator 24 | @inline 25 | function rot(x: u32, y: u32, v: u32): void { 26 | var alpha = max((v >> 24) - BIT_ROT, 0); 27 | set(x, y, (alpha << 24) | (v & 0x00ffffff)); 28 | } 29 | 30 | /** Initializes width and height. Called once from JS. */ 31 | export function init(w: i32, h: i32): void { 32 | width = w; 33 | height = h; 34 | offset = w * h; 35 | 36 | // Start by filling output with random live cells. 37 | for (let y = 0; y < h; ++y) { 38 | for (let x = 0; x < w; ++x) { 39 | let c = Math.random() > 0.1 40 | ? BGR_DEAD & 0x00ffffff 41 | : BGR_ALIVE | 0xff000000; 42 | set(x, y, c); 43 | } 44 | } 45 | } 46 | 47 | /** Performs one step. Called about 30 times a second from JS. */ 48 | export function step(): void { 49 | var w = width, 50 | h = height; 51 | 52 | var hm1 = h - 1, // h - 1 53 | wm1 = w - 1; // w - 1 54 | 55 | // The universe of the Game of Life is an infinite two-dimensional orthogonal grid of square 56 | // "cells", each of which is in one of two possible states, alive or dead. 57 | for (let y = 0; y < h; ++y) { 58 | let ym1 = y == 0 ? hm1 : y - 1, 59 | yp1 = y == hm1 ? 0 : y + 1; 60 | for (let x = 0; x < w; ++x) { 61 | let xm1 = x == 0 ? wm1 : x - 1, 62 | xp1 = x == wm1 ? 0 : x + 1; 63 | 64 | // Every cell interacts with its eight neighbours, which are the cells that are horizontally, 65 | // vertically, or diagonally adjacent. Least significant bit indicates alive or dead. 66 | let aliveNeighbors = ( 67 | (get(xm1, ym1) & 1) + (get(x, ym1) & 1) + (get(xp1, ym1) & 1) + 68 | (get(xm1, y ) & 1) + (get(xp1, y ) & 1) + 69 | (get(xm1, yp1) & 1) + (get(x, yp1) & 1) + (get(xp1, yp1) & 1) 70 | ); 71 | 72 | let self = get(x, y); 73 | if (self & 1) { 74 | // A live cell with 2 or 3 live neighbors rots on to the next generation. 75 | if ((aliveNeighbors & 0b1110) == 0b0010) rot(x, y, self); 76 | // A live cell with fewer than 2 or more than 3 live neighbors dies. 77 | else set(x, y, BGR_DEAD | 0xff000000); 78 | } else { 79 | // A dead cell with exactly 3 live neighbors becomes a live cell. 80 | if (aliveNeighbors == 3) set(x, y, BGR_ALIVE | 0xff000000); 81 | // A dead cell with fewer or more than 3 live neighbors just rots. 82 | else rot(x, y, self); 83 | } 84 | } 85 | } 86 | } 87 | 88 | /** Fills the row and column indicated by `x` and `y` with random live cells. */ 89 | export function fill(x: u32, y: u32, p: f64): void { 90 | for (let ix = 0; ix < width; ++ix) { 91 | if (Math.random() < p) set(ix, y, BGR_ALIVE | 0xff000000); 92 | } 93 | for (let iy = 0; iy < height; ++iy) { 94 | if (Math.random() < p) set(x, iy, BGR_ALIVE | 0xff000000); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /game-of-life/assembly/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../node_modules/assemblyscript/std/assembly.json", 3 | "include": [ 4 | "./**/*.ts" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /game-of-life/build/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | !release.wasm 4 | -------------------------------------------------------------------------------- /game-of-life/build/release.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AssemblyScript/examples/8b23ca8fa2f27cf9a39e5dfe4989d9eeba87d48f/game-of-life/build/release.wasm -------------------------------------------------------------------------------- /game-of-life/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Conway's Game of Life - AssemblyScript 7 | 8 | 17 | 18 | 19 |

20 | Conway's Game of Life in 21 | AssemblyScript 22 | ( source ) 23 |

24 | 25 |
Might be blurry because MS Edge does not support 'image-rendering: crisp-edges' (yet) :-(
26 | 145 | 146 | 147 | -------------------------------------------------------------------------------- /game-of-life/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@assemblyscript/game-of-life-example", 3 | "version": "1.0.0", 4 | "license": "Apache-2.0", 5 | "private": true, 6 | "scripts": { 7 | "asbuild:debug": "asc assembly/index.ts --target debug", 8 | "asbuild:release": "asc assembly/index.ts --target release", 9 | "asbuild": "npm run asbuild:debug && npm run asbuild:release", 10 | "start": "npx serve" 11 | }, 12 | "devDependencies": { 13 | "assemblyscript": "latest" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /game-of-life/preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AssemblyScript/examples/8b23ca8fa2f27cf9a39e5dfe4989d9eeba87d48f/game-of-life/preview.jpg -------------------------------------------------------------------------------- /i64/README.md: -------------------------------------------------------------------------------- 1 | i64 2 | === 3 | 4 | An [AssemblyScript](http://assemblyscript.org) example. Exposes WebAssembly's i64 operations to JavaScript using 32-bit integers (low and high bits). 5 | 6 | Usage 7 | ----- 8 | 9 | ```ts 10 | import * as i64 from "path/to/i64"; 11 | 12 | i64.div(10, 0, 2, 0); 13 | 14 | console.log("result: lo=" + i64.getLo() + ", hi=" + i64.getHi()); 15 | ``` 16 | 17 | API 18 | --- 19 | 20 | **Note** that `u32` is just an alias of `number` in JavaScript with values in 32-bit integer range. 21 | 22 | * **getLo**(): `u32`
23 | Gets the low 32 bits of the computed 64-bit value. 24 | 25 | * **getHi**(): `u32`
26 | Gets the high 32 bits of the computed 64-bit value. 27 | 28 | * **clz**(loLeft: `u32`, hiLeft: `u32`): `void`
29 | Performs the sign-agnostic count leading zero bits operation. All zero bits are considered leading if the value is zero. 30 | 31 | * **ctz**(loLeft: `u32`, hiLeft: `u32`): `void`
32 | Performs the sign-agnostic count tailing zero bits operation. All zero bits are considered trailing if the value is zero. 33 | 34 | * **popcnt**(loLeft: `u32`, hiLeft: `u32`): `void`
35 | Performs the sign-agnostic count number of one bits operation. 36 | 37 | * **eqz**(loLeft: `u32`, hiLeft: `u32`): `void`
38 | Performs the sign-agnostic equals-zero operation. 39 | 40 | * **add**(loLeft: `u32`, hiLeft: `u32`, loRight: `u32`, hiRight: `u32`): `void`
41 | Performs the sign-agnostic addition operation. 42 | 43 | * **sub**(loLeft: `u32`, hiLeft: `u32`, loRight: `u32`, hiRight: `u32`): `void`
44 | Performs the sign-agnostic subtraction operation. 45 | 46 | * **mul**(loLeft: `u32`, hiLeft: `u32`, loRight: `u32`, hiRight: `u32`): `void`
47 | Performs the sign-agnostic multiplication operation. 48 | 49 | * **div_s**(loLeft: `u32`, hiLeft: `u32`, loRight: `u32`, hiRight: `u32`): `void`
50 | Performs the signed division operation. 51 | 52 | * **div_u**(loLeft: `u32`, hiLeft: `u32`, loRight: `u32`, hiRight: `u32`): `void`
53 | Performs the unsigned division operation. 54 | 55 | * **rem_s**(loLeft: `u32`, hiLeft: `u32`, loRight: `u32`, hiRight: `u32`): `void`
56 | Performs the signed remainder operation. 57 | 58 | * **rem_u**(loLeft: `u32`, hiLeft: `u32`, loRight: `u32`, hiRight: `u32`): `void`
59 | Performs the unsigned remainder operation. 60 | 61 | * **and**(loLeft: `u32`, hiLeft: `u32`, loRight: `u32`, hiRight: `u32`): `void`
62 | Performs the sign-agnostic bitwise and operation. 63 | 64 | * **or**(loLeft: `u32`, hiLeft: `u32`, loRight: `u32`, hiRight: `u32`): `void`
65 | Performs the sign-agnostic bitwise or operation. 66 | 67 | * **xor**(loLeft: `u32`, hiLeft: `u32`, loRight: `u32`, hiRight: `u32`): `void`
68 | Performs the sign-agnostic bitwise xor operation. 69 | 70 | * **shl**(loLeft: `u32`, hiLeft: `u32`, loRight: `u32`, hiRight: `u32`): `void`
71 | Performs the sign-agnostic bitwise shift left operation. 72 | 73 | * **shr_s**(loLeft: `u32`, hiLeft: `u32`, loRight: `u32`, hiRight: `u32`): `void`
74 | Performs the signed bitwise shift right operation. 75 | 76 | * **shr_u**(loLeft: `u32`, hiLeft: `u32`, loRight: `u32`, hiRight: `u32`): `void`
77 | Performs the unsigned bitwise shift right operation. 78 | 79 | * **rotl**(loLeft: `u32`, hiLeft: `u32`, loRight: `u32`, hiRight: `u32`): `void`
80 | Performs the sign-agnostic rotate left operation. 81 | 82 | * **rotr**(loLeft: `u32`, hiLeft: `u32`, loRight: `u32`, hiRight: `u32`): `void`
83 | Performs the sign-agnostic rotate right operation. 84 | 85 | * **eq**(loLeft: `u32`, hiLeft: `u32`, loRight: `u32`, hiRight: `u32`): `void`
86 | Performs the sign-agnostic compare equal operation. 87 | 88 | * **ne**(loLeft: `u32`, hiLeft: `u32`, loRight: `u32`, hiRight: `u32`): `void`
89 | Performs the sign-agnostic compare unequal operation. 90 | 91 | * **lt_s**(loLeft: `u32`, hiLeft: `u32`, loRight: `u32`, hiRight: `u32`): `void`
92 | Performs the signed less than operation. 93 | 94 | * **lt_u**(loLeft: `u32`, hiLeft: `u32`, loRight: `u32`, hiRight: `u32`): `void`
95 | Performs the unsigned less than operation. 96 | 97 | * **le_s**(loLeft: `u32`, hiLeft: `u32`, loRight: `u32`, hiRight: `u32`): `void`
98 | Performs the signed less than or equal operation. 99 | 100 | * **le_u**(loLeft: `u32`, hiLeft: `u32`, loRight: `u32`, hiRight: `u32`): `void`
101 | Performs the unsigned less than or equal operation. 102 | 103 | * **gt_s**(loLeft: `u32`, hiLeft: `u32`, loRight: `u32`, hiRight: `u32`): `void`
104 | Performs the signed greater than operation. 105 | 106 | * **gt_u**(loLeft: `u32`, hiLeft: `u32`, loRight: `u32`, hiRight: `u32`): `void`
107 | Performs the unsigned greater than operation. 108 | 109 | * **ge_s**(loLeft: `u32`, hiLeft: `u32`, loRight: `u32`, hiRight: `u32`): `void`
110 | Performs the signed greater than or equal operation. 111 | 112 | * **ge_u**(loLeft: `u32`, hiLeft: `u32`, loRight: `u32`, hiRight: `u32`): `void`
113 | Performs the unsigned greater than or equal operation. 114 | 115 | Building 116 | -------- 117 | 118 | To build [assembly/i64.ts](./assembly/i64.ts) to an untouched and an optimized `.wasm` including their respective `.wat` representations, run: 119 | 120 | ``` 121 | $> npm run asbuild 122 | ``` 123 | 124 | Afterwards, to run the included [test](./tests/index.js): 125 | 126 | ``` 127 | $> npm test 128 | ``` 129 | -------------------------------------------------------------------------------- /i64/asconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "entries": [ 3 | "./assembly/i64.ts" 4 | ], 5 | "options": { 6 | "runtime": "stub", 7 | "sourceMap": true, 8 | "measure": true 9 | }, 10 | "targets": { 11 | "debug": { 12 | "outFile": "build/debug.wasm", 13 | "textFile": "build/debug.wat", 14 | "debug": true 15 | }, 16 | "release": { 17 | "outFile": "build/release.wasm", 18 | "textFile": "build/release.wat", 19 | "optimizeLevel": 3, 20 | "shrinkLevel": 0, 21 | "noAssert": true 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /i64/assembly/i64.ts: -------------------------------------------------------------------------------- 1 | import { 2 | clz as builtin_clz, 3 | ctz as builtin_ctz, 4 | popcnt as builtin_popcnt, 5 | rotl as builtin_rotl, 6 | rotr as builtin_rotr, 7 | } from "builtins"; 8 | 9 | let 10 | lo: u32, 11 | hi: u32; 12 | 13 | export function getLo(): u32 { 14 | return lo; 15 | } 16 | 17 | export function getHi(): u32 { 18 | return hi; 19 | } 20 | 21 | export function clz(loLeft: u32, hiLeft: u32): void { 22 | var ret = builtin_clz(loLeft | hiLeft << 32); 23 | lo = ret; 24 | hi = 0; 25 | } 26 | 27 | export function ctz(loLeft: u32, hiLeft: u32): void { 28 | var ret = builtin_ctz(loLeft | hiLeft << 32); 29 | lo = ret; 30 | hi = 0; 31 | } 32 | 33 | export function popcnt(loLeft: u32, hiLeft: u32): void { 34 | var ret = builtin_popcnt(loLeft | hiLeft << 32); 35 | lo = ret; 36 | hi = 0; 37 | } 38 | 39 | export function eqz(loLeft: u32, hiLeft: u32): void { 40 | var ret = !(loLeft | hiLeft << 32); 41 | lo = u32(ret); 42 | hi = 0; 43 | } 44 | 45 | export function add(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void { 46 | var ret = (loLeft | hiLeft << 32) + (loRight | hiRight << 32); 47 | lo = ret; 48 | hi = u32(ret >> 32); 49 | } 50 | 51 | export function sub(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void { 52 | var ret = (loLeft | hiLeft << 32) - (loRight | hiRight << 32); 53 | lo = ret; 54 | hi = u32(ret >> 32); 55 | } 56 | 57 | export function mul(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void { 58 | var ret = (loLeft | hiLeft << 32) * (loRight | hiRight << 32); 59 | lo = ret; 60 | hi = u32(ret >> 32); 61 | } 62 | 63 | export function div_s(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void { 64 | var ret = u64(i64(loLeft | hiLeft << 32) / i64(loRight | hiRight << 32)); 65 | lo = ret; 66 | hi = u32(ret >> 32); 67 | } 68 | 69 | export function div_u(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void { 70 | var ret = (loLeft | hiLeft << 32) / (loRight | hiRight << 32); 71 | lo = ret; 72 | hi = u32(ret >> 32); 73 | } 74 | 75 | export function rem_s(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void { 76 | var ret = u64(i64(loLeft | hiLeft << 32) % i64(loRight | hiRight << 32)); 77 | lo = ret; 78 | hi = u32(ret >> 32); 79 | } 80 | 81 | export function rem_u(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void { 82 | var ret = (loLeft | hiLeft << 32) % (loRight | hiRight << 32); 83 | lo = ret; 84 | hi = u32(ret >>> 32); 85 | } 86 | 87 | export function and(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void { 88 | var ret = (loLeft | hiLeft << 32) & (loRight | hiRight << 32); 89 | lo = ret; 90 | hi = u32(ret >>> 32); 91 | } 92 | 93 | export function or(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void { 94 | var ret = (loLeft | hiLeft << 32) | (loRight | hiRight << 32); 95 | lo = ret; 96 | hi = u32(ret >>> 32); 97 | } 98 | 99 | export function xor(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void { 100 | var ret = (loLeft | hiLeft << 32) ^ (loRight | hiRight << 32); 101 | lo = ret; 102 | hi = u32(ret >>> 32); 103 | } 104 | 105 | export function shl(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void { 106 | var ret = (loLeft | hiLeft << 32) << (loRight | hiRight << 32); 107 | lo = ret; 108 | hi = u32(ret >>> 32); 109 | } 110 | 111 | export function shr_s(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void { 112 | var ret = u64(i64(loLeft | hiLeft << 32) >> i64(loRight | hiRight << 32)); 113 | lo = ret; 114 | hi = u32(ret >>> 32); 115 | } 116 | 117 | export function shr_u(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void { 118 | var ret = (loLeft | hiLeft << 32) >> (loRight | hiRight << 32); 119 | lo = ret; 120 | hi = u32(ret >>> 32); 121 | } 122 | 123 | export function rotl(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void { 124 | var ret = builtin_rotl(loLeft | hiLeft << 32, loRight | hiRight << 32); 125 | lo = ret; 126 | hi = u32(ret >>> 32); 127 | } 128 | 129 | export function rotr(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void { 130 | var ret = builtin_rotr(loLeft | hiLeft << 32, loRight | hiRight << 32); 131 | lo = ret; 132 | hi = u32(ret >>> 32); 133 | } 134 | 135 | export function eq(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void { 136 | var ret = (loLeft | hiLeft << 32) == (loRight | hiRight << 32); 137 | lo = u32(ret); 138 | hi = 0; 139 | } 140 | 141 | export function ne(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void { 142 | var ret = (loLeft | hiLeft << 32) != (loRight | hiRight << 32); 143 | lo = u32(ret); 144 | hi = 0; 145 | } 146 | 147 | export function lt_s(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void { 148 | var ret = i64(loLeft | hiLeft << 32) < i64(loRight | hiRight << 32); 149 | lo = u32(ret); 150 | hi = 0; 151 | } 152 | 153 | export function lt_u(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void { 154 | var ret = (loLeft | hiLeft << 32) < (loRight | hiRight << 32); 155 | lo = u32(ret); 156 | hi = 0; 157 | } 158 | 159 | export function le_s(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void { 160 | var ret = i64(loLeft | hiLeft << 32) <= i64(loRight | hiRight << 32); 161 | lo = u32(ret); 162 | hi = 0; 163 | } 164 | 165 | export function le_u(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void { 166 | var ret = (loLeft | hiLeft << 32) <= (loRight | hiRight << 32); 167 | lo = u32(ret); 168 | hi = 0; 169 | } 170 | 171 | export function gt_s(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void { 172 | var ret = (loLeft | hiLeft << 32) > (loRight | hiRight << 32); 173 | lo = u32(ret); 174 | hi = 0; 175 | } 176 | 177 | export function gt_u(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void { 178 | var ret = (loLeft | hiLeft << 32) > (loRight | hiRight << 32); 179 | lo = u32(ret); 180 | hi = 0; 181 | } 182 | 183 | export function ge_s(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void { 184 | var ret = i64(loLeft | hiLeft << 32) >= i64(loRight | hiRight << 32); 185 | lo = u32(ret); 186 | hi = 0; 187 | } 188 | 189 | export function ge_u(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void { 190 | var ret = (loLeft | hiLeft << 32) >= (loRight | hiRight << 32); 191 | lo = u32(ret); 192 | hi = 0; 193 | } 194 | -------------------------------------------------------------------------------- /i64/assembly/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../node_modules/assemblyscript/std/assembly.json", 3 | "include": [ 4 | "./**/*.ts" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /i64/build/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /i64/index.d.ts: -------------------------------------------------------------------------------- 1 | type u32 = number; 2 | /** Gets the low 32 bits of the computed 64-bit value. */ 3 | export function getLo(): u32; 4 | /** Gets the high 32 bits of the computed 64-bit value. */ 5 | export function getHi(): u32; 6 | /** Performs the sign-agnostic count leading zero bits operation. All zero bits are considered leading if the value is zero. */ 7 | export function clz(loLeft: u32, hiLeft: u32): void; 8 | /** Performs the sign-agnostic count tailing zero bits operation. All zero bits are considered trailing if the value is zero. */ 9 | export function ctz(loLeft: u32, hiLeft: u32): void; 10 | /** Performs the sign-agnostic count number of one bits operation. */ 11 | export function popcnt(loLeft: u32, hiLeft: u32): void; 12 | /** Performs the sign-agnostic equals-zero operation. */ 13 | export function eqz(loLeft: u32, hiLeft: u32): void; 14 | /** Performs the sign-agnostic addition operation. */ 15 | export function add(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void; 16 | /** Performs the sign-agnostic subtraction operation. */ 17 | export function sub(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void; 18 | /** Performs the sign-agnostic multiplication operation. */ 19 | export function mul(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void; 20 | /** Performs the signed division operation. */ 21 | export function div_s(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void; 22 | /** Performs the unsigned division operation. */ 23 | export function div_u(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void; 24 | /** Performs the signed remainder operation. */ 25 | export function rem_s(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void; 26 | /** Performs the unsigned remainder operation. */ 27 | export function rem_u(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void; 28 | /** Performs the sign-agnostic bitwise and operation. */ 29 | export function and(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void; 30 | /** Performs the sign-agnostic bitwise or operation. */ 31 | export function or(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void; 32 | /** Performs the sign-agnostic bitwise xor operation. */ 33 | export function xor(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void; 34 | /** Performs the sign-agnostic bitwise shift left operation. */ 35 | export function shl(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void; 36 | /** Performs the signed bitwise shift right operation. */ 37 | export function shr_s(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void; 38 | /** Performs the unsigned bitwise shift right operation. */ 39 | export function shr_u(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void; 40 | /** Performs the sign-agnostic rotate left operation. */ 41 | export function rotl(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void; 42 | /** Performs the sign-agnostic rotate right operation. */ 43 | export function rotr(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void; 44 | /** Performs the sign-agnostic compare equal operation. */ 45 | export function eq(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void; 46 | /** Performs the sign-agnostic compare unequal operation. */ 47 | export function ne(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void; 48 | /** Performs the signed less than operation. */ 49 | export function lt_s(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void; 50 | /** Performs the unsigned less than operation. */ 51 | export function lt_u(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void; 52 | /** Performs the signed less than or equal operation. */ 53 | export function le_s(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void; 54 | /** Performs the unsigned less than or equal operation. */ 55 | export function le_u(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void; 56 | /** Performs the signed greater than operation.*/ 57 | export function gt_s(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void; 58 | /** Performs the unsigned greater than operation.*/ 59 | export function gt_u(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void; 60 | /** Performs the signed greater than or equal operation. */ 61 | export function ge_s(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void; 62 | /** Performs the unsigned greater than or equal operation. */ 63 | export function ge_u(loLeft: u32, hiLeft: u32, loRight: u32, hiRight: u32): void; 64 | -------------------------------------------------------------------------------- /i64/index.js: -------------------------------------------------------------------------------- 1 | var fs = require("fs"); 2 | 3 | // Instantiate the module 4 | var mod = new WebAssembly.Module(fs.readFileSync(__dirname + "/build/release.wasm")); 5 | var ins = new WebAssembly.Instance(mod, { /* no imports */ }); 6 | 7 | // Export its exports 8 | module.exports = ins.exports; 9 | -------------------------------------------------------------------------------- /i64/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@assemblyscript/i64-example", 3 | "version": "1.0.0", 4 | "license": "Apache-2.0", 5 | "main": "index.js", 6 | "types": "index.d.ts", 7 | "scripts": { 8 | "asbuild:debug": "asc --target debug", 9 | "asbuild:release": "asc --target release", 10 | "asbuild": "npm run asbuild:debug && npm run asbuild:release", 11 | "test": "node tests" 12 | }, 13 | "files": [ 14 | "assembly/", 15 | "build/release.wasm", 16 | "build/release.wasm.map", 17 | "index.d.ts", 18 | "index.js", 19 | "README.md" 20 | ], 21 | "devDependencies": { 22 | "assemblyscript": "latest" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /i64/tests/index.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | 3 | function assertUnary(op, loLeft, hiLeft, loResult, hiResult) { 4 | op(loLeft, hiLeft); 5 | assert.strictEqual(i64.getLo(), loResult); 6 | assert.strictEqual(i64.getHi(), hiResult); 7 | } 8 | 9 | function assertBinary(op, loLeft, hiLeft, loRight, hiRight, loResult, hiResult) { 10 | op(loLeft, hiLeft, loLeft, loRight); 11 | assert.strictEqual(i64.getLo(), loResult); 12 | assert.strictEqual(i64.getHi(), hiResult); 13 | } 14 | 15 | var i64 = require(".."); 16 | 17 | assertUnary(i64.clz, 1, 0, 63, 0); 18 | assertUnary(i64.clz, 0, 1, 31, 0); 19 | assertUnary(i64.clz, 1, 1, 31, 0); 20 | assertUnary(i64.clz, 0, 0, 64, 0); 21 | 22 | assertUnary(i64.ctz, 0, 0x80000000, 63, 0); 23 | assertUnary(i64.ctz, 0x80000000, 0x80000000, 31, 0); 24 | assertUnary(i64.ctz, 0, 1, 32, 0); 25 | assertUnary(i64.ctz, 1, 0, 0, 0); 26 | assertUnary(i64.ctz, 0, 0, 64, 0); 27 | 28 | assertUnary(i64.popcnt, 0x55555555, 0x55555555, 32, 0); 29 | assertUnary(i64.popcnt, -1, -1, 64, 0); 30 | assertUnary(i64.popcnt, 0, 0, 0, 0); 31 | assertUnary(i64.popcnt, 0x55, 0, 4, 0); 32 | assertUnary(i64.popcnt, 0, 0x55, 4, 0); 33 | assertUnary(i64.popcnt, 0x55, 0x55, 8, 0); 34 | 35 | assertUnary(i64.eqz, 0, 0, 1, 0); 36 | assertUnary(i64.eqz, 0, 1, 0, 0); 37 | assertUnary(i64.eqz, 1, 0, 0, 0); 38 | assertUnary(i64.eqz, 1, 1, 0, 0); 39 | 40 | // TODO... 41 | 42 | console.log("ok"); 43 | -------------------------------------------------------------------------------- /interference/README.md: -------------------------------------------------------------------------------- 1 | Interference effect 2 | =================== 3 | 4 | An [AssemblyScript](http://assemblyscript.org) example. Colin Eberhardt's and Ben Smith's [WebAssembly interference effect](https://github.com/ColinEberhardt/wasm-interference), if it was written in AssemblyScript and utilizing 32-bit floating point math. 5 | 6 | Instructions 7 | ------------ 8 | 9 | First, install the development dependencies: 10 | 11 | ``` 12 | $> npm install 13 | ``` 14 | 15 | Now, to build [assembly/index.ts](./assembly/index.ts) to an untouched and an optimized `.wasm` including their respective `.wat` representations, run: 16 | 17 | ``` 18 | $> npm run asbuild 19 | ``` 20 | 21 | Afterwards, run 22 | 23 | ``` 24 | $> npm start 25 | ``` 26 | 27 | to start a local server. 28 | -------------------------------------------------------------------------------- /interference/assembly/index.ts: -------------------------------------------------------------------------------- 1 | var width = 320; 2 | var height = 200; 3 | 4 | export const offset = __heap_base; 5 | 6 | function set(x: i32, y: i32, v: f32): void { 7 | var vi = v; 8 | store(offset + ((width * y + x) << 2), ~vi << 24 | vi << 8); 9 | } 10 | 11 | function distance(x1: i32, y1: i32, x2: f32, y2: f32): f32 { 12 | var dx = x1 - x2; 13 | var dy = y1 - y2; 14 | return Mathf.sqrt(dx * dx + dy * dy); 15 | } 16 | 17 | export function update(tick: f32): void { 18 | var w = width; 19 | var h = height; 20 | var hw = w * 0.5, 21 | hh = h * 0.5; 22 | var cx1 = (Mathf.sin(tick * 2) + Mathf.sin(tick )) * hw * 0.3 + hw, 23 | cy1 = (Mathf.cos(tick) ) * hh * 0.3 + hh, 24 | cx2 = (Mathf.sin(tick * 4) + Mathf.sin(tick + 1.2)) * hw * 0.3 + hw, 25 | cy2 = (Mathf.sin(tick * 3) + Mathf.cos(tick + 0.1)) * hh * 0.3 + hh; 26 | var res = 48 / Mathf.max(w, h); 27 | var y = 0; 28 | do { 29 | let x = 0; 30 | do { 31 | set(x, y, Mathf.abs( 32 | Mathf.sin(distance(x, y, cx1, cy1) * res) + 33 | Mathf.sin(distance(x, y, cx2, cy2) * res) 34 | ) * 120); 35 | } while (++x != width) 36 | } while (++y != height) 37 | } 38 | 39 | export function resize(w: i32, h: i32): void { 40 | width = w; height = h; 41 | var needed = ((offset + (w * h * sizeof() + 0xffff)) & ~0xffff) >>> 16; 42 | var actual = memory.size(); 43 | if (needed > actual) memory.grow(needed - actual); 44 | } 45 | -------------------------------------------------------------------------------- /interference/assembly/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../node_modules/assemblyscript/std/assembly.json", 3 | "include": [ 4 | "./**/*.ts" 5 | ] 6 | } -------------------------------------------------------------------------------- /interference/build/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | !optimized.wasm 4 | -------------------------------------------------------------------------------- /interference/build/optimized.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AssemblyScript/examples/8b23ca8fa2f27cf9a39e5dfe4989d9eeba87d48f/interference/build/optimized.wasm -------------------------------------------------------------------------------- /interference/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Interference effect - AssemblyScript 7 | 8 | 16 | 17 | 18 |

19 | Interference effect in AssemblyScript ( source ) 20 |

21 | 22 | 23 | 24 | 53 | 54 | 57 |
58 |

EPILEPSY WARNING

59 |

A very small percentage of individuals may experience epileptic seizures when exposed to certain light patterns or flashing lights. Exposure to certain patterns or backgrounds on a computer screen may induce an epileptic seizure in these individuals. Certain conditions may induce previously undetected epileptic symptoms even in persons who have no history of prior seizures or epilepsy.

60 |

If you experience any of the following symptoms while viewing - dizziness, altered vision, eye or muscle twitches, loss of awareness, disorientation, any involuntary movement, or convulsions - IMMEDIATELY discontinue use and consult your physician.

61 |

(click to continue)

62 |
63 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /interference/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@assemblyscript/interference-example", 3 | "version": "1.0.0", 4 | "license": "Apache-2.0", 5 | "private": true, 6 | "scripts": { 7 | "asbuild:untouched": "asc assembly/index.ts -b build/untouched.wasm -t build/untouched.wat --sourceMap --runtime stub --debug", 8 | "asbuild:optimized": "asc assembly/index.ts -b build/optimized.wasm -t build/optimized.wat --sourceMap --runtime stub --optimize", 9 | "asbuild": "npm run asbuild:untouched && npm run asbuild:optimized", 10 | "start": "npx serve" 11 | }, 12 | "devDependencies": { 13 | "assemblyscript": "latest" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /interference/preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AssemblyScript/examples/8b23ca8fa2f27cf9a39e5dfe4989d9eeba87d48f/interference/preview.jpg -------------------------------------------------------------------------------- /libm/README.md: -------------------------------------------------------------------------------- 1 | libm 2 | ==== 3 | 4 | An [AssemblyScript](http://assemblyscript.org) example. Exposes AssemblyScript's math routines for double and single precision as a library. 5 | 6 | ```ts 7 | const libm = require("path/to/libm"); 8 | const libmf = libm.libmf; 9 | ... 10 | ``` 11 | 12 | Both `libm` and `libmf` have the same general interface as JavaScript's `Math`, with `libmf` doing single precision math. 13 | 14 | Instructions 15 | ------------ 16 | 17 | First, install the development dependencies: 18 | 19 | ``` 20 | $> npm install 21 | ``` 22 | 23 | Now, to build [assembly/libm.ts](./assembly/libm.ts) to `build/libm.wasm` respectively [assembly/libmf.ts](./assembly/libmf.ts) to `build/libmf.wasm`, run: 24 | 25 | ``` 26 | $> npm run asbuild 27 | ``` 28 | 29 | Afterwards, run 30 | 31 | ``` 32 | $> npm test 33 | ``` 34 | 35 | to verify that it works. 36 | -------------------------------------------------------------------------------- /libm/assembly/libm.ts: -------------------------------------------------------------------------------- 1 | export const E = Math.E; 2 | export const LN10 = Math.LN10; 3 | export const LN2 = Math.LN2; 4 | export const LOG10E = Math.LOG10E; 5 | export const LOG2E = Math.LOG2E; 6 | export const PI = Math.PI; 7 | export const SQRT1_2 = Math.SQRT1_2; 8 | export const SQRT2 = Math.SQRT2; 9 | 10 | export function abs(x: f64): f64 { 11 | return Math.abs(x); 12 | } 13 | 14 | export function acos(x: f64): f64 { 15 | return Math.acos(x); 16 | } 17 | 18 | export function acosh(x: f64): f64 { 19 | return Math.acosh(x); 20 | } 21 | 22 | export function asin(x: f64): f64 { 23 | return Math.asin(x); 24 | } 25 | 26 | export function asinh(x: f64): f64 { 27 | return Math.asinh(x); 28 | } 29 | 30 | export function atan(x: f64): f64 { 31 | return Math.atan(x); 32 | } 33 | 34 | export function atanh(x: f64): f64 { 35 | return Math.atanh(x); 36 | } 37 | 38 | export function atan2(y: f64, x: f64): f64 { 39 | return Math.atan2(y, x); 40 | } 41 | 42 | export function cbrt(x: f64): f64 { 43 | return Math.cbrt(x); 44 | } 45 | 46 | export function ceil(x: f64): f64 { 47 | return Math.ceil(x); 48 | } 49 | 50 | export function clz32(x: f64): f64 { 51 | return Math.clz32(x); 52 | } 53 | 54 | export function cos(x: f64): f64 { 55 | return Math.cos(x); 56 | } 57 | 58 | export function cosh(x: f64): f64 { 59 | return Math.cosh(x); 60 | } 61 | 62 | export function exp(x: f64): f64 { 63 | return Math.exp(x); 64 | } 65 | 66 | export function expm1(x: f64): f64 { 67 | return Math.expm1(x); 68 | } 69 | 70 | export function floor(x: f64): f64 { 71 | return Math.floor(x); 72 | } 73 | 74 | export function fround(x: f64): f64 { 75 | return Math.fround(x); 76 | } 77 | 78 | export function hypot(a: f64, b: f64): f64 { 79 | return Math.hypot(a, b); 80 | } 81 | 82 | export function imul(a: f64, b: f64): f64 { 83 | return Math.imul(a, b); 84 | } 85 | 86 | export function log(x: f64): f64 { 87 | return Math.log(x); 88 | } 89 | 90 | export function log10(x: f64): f64 { 91 | return Math.log10(x); 92 | } 93 | 94 | export function log1p(x: f64): f64 { 95 | return Math.log1p(x); 96 | } 97 | 98 | export function log2(x: f64): f64 { 99 | return Math.log2(x); 100 | } 101 | 102 | export function max(a: f64, b: f64): f64 { 103 | return Math.max(a, b); 104 | } 105 | 106 | export function min(a: f64, b: f64): f64 { 107 | return Math.min(a, b); 108 | } 109 | 110 | export function pow(x: f64, y: f64): f64 { 111 | return Math.pow(x, y); 112 | } 113 | 114 | export function round(x: f64): f64 { 115 | return Math.round(x); 116 | } 117 | 118 | export function sign(x: f64): f64 { 119 | return Math.sign(x); 120 | } 121 | 122 | export function sin(x: f64): f64 { 123 | return Math.sin(x); 124 | } 125 | 126 | export function sinh(x: f64): f64 { 127 | return Math.sinh(x); 128 | } 129 | 130 | export function sqrt(x: f64): f64 { 131 | return Math.sqrt(x); 132 | } 133 | 134 | export function tan(x: f64): f64 { 135 | return Math.tan(x); 136 | } 137 | 138 | export function tanh(x: f64): f64 { 139 | return Math.tanh(x); 140 | } 141 | 142 | export function trunc(x: f64): f64 { 143 | return Math.trunc(x); 144 | } 145 | -------------------------------------------------------------------------------- /libm/assembly/libmf.ts: -------------------------------------------------------------------------------- 1 | export const E = Mathf.E; 2 | export const LN10 = Mathf.LN10; 3 | export const LN2 = Mathf.LN2; 4 | export const LOG10E = Mathf.LOG10E; 5 | export const LOG2E = Mathf.LOG2E; 6 | export const PI = Mathf.PI; 7 | export const SQRT1_2 = Mathf.SQRT1_2; 8 | export const SQRT2 = Mathf.SQRT2; 9 | 10 | export function abs(x: f32): f32 { 11 | return Mathf.abs(x); 12 | } 13 | 14 | export function acos(x: f32): f32 { 15 | return Mathf.acos(x); 16 | } 17 | 18 | export function acosh(x: f32): f32 { 19 | return Mathf.acosh(x); 20 | } 21 | 22 | export function asin(x: f32): f32 { 23 | return Mathf.asin(x); 24 | } 25 | 26 | export function asinh(x: f32): f32 { 27 | return Mathf.asinh(x); 28 | } 29 | 30 | export function atan(x: f32): f32 { 31 | return Mathf.atan(x); 32 | } 33 | 34 | export function atanh(x: f32): f32 { 35 | return Mathf.atanh(x); 36 | } 37 | 38 | export function atan2(y: f32, x: f32): f32 { 39 | return Mathf.atan2(y, x); 40 | } 41 | 42 | export function cbrt(x: f32): f32 { 43 | return Mathf.cbrt(x); 44 | } 45 | 46 | export function ceil(x: f32): f32 { 47 | return Mathf.ceil(x); 48 | } 49 | 50 | export function clz32(x: f32): f32 { 51 | return Mathf.clz32(x); 52 | } 53 | 54 | export function cos(x: f32): f32 { 55 | return Mathf.cos(x); 56 | } 57 | 58 | export function cosh(x: f32): f32 { 59 | return Mathf.cosh(x); 60 | } 61 | 62 | export function exp(x: f32): f32 { 63 | return Mathf.exp(x); 64 | } 65 | 66 | export function expm1(x: f32): f32 { 67 | return Mathf.expm1(x); 68 | } 69 | 70 | export function floor(x: f32): f32 { 71 | return Mathf.floor(x); 72 | } 73 | 74 | export function fround(x: f32): f32 { 75 | return Mathf.fround(x); 76 | } 77 | 78 | export function hypot(a: f32, b: f32): f32 { 79 | return Mathf.hypot(a, b); 80 | } 81 | 82 | export function imul(a: f32, b: f32): f32 { 83 | return Mathf.imul(a, b); 84 | } 85 | 86 | export function log(x: f32): f32 { 87 | return Mathf.log(x); 88 | } 89 | 90 | export function log10(x: f32): f32 { 91 | return Mathf.log10(x); 92 | } 93 | 94 | export function log1p(x: f32): f32 { 95 | return Mathf.log1p(x); 96 | } 97 | 98 | export function log2(x: f32): f32 { 99 | return Mathf.log2(x); 100 | } 101 | 102 | export function max(a: f32, b: f32): f32 { 103 | return Mathf.max(a, b); 104 | } 105 | 106 | export function min(a: f32, b: f32): f32 { 107 | return Mathf.min(a, b); 108 | } 109 | 110 | export function pow(x: f32, y: f32): f32 { 111 | return Mathf.pow(x, y); 112 | } 113 | 114 | export function round(x: f32): f32 { 115 | return Mathf.round(x); 116 | } 117 | 118 | export function sign(x: f32): f32 { 119 | return Mathf.sign(x); 120 | } 121 | 122 | export function sin(x: f32): f32 { 123 | return Mathf.sin(x); 124 | } 125 | 126 | export function sinh(x: f32): f32 { 127 | return Mathf.sinh(x); 128 | } 129 | 130 | export function sqrt(x: f32): f32 { 131 | return Mathf.sqrt(x); 132 | } 133 | 134 | export function tan(x: f32): f32 { 135 | return Mathf.tan(x); 136 | } 137 | 138 | export function tanh(x: f32): f32 { 139 | return Mathf.tanh(x); 140 | } 141 | 142 | export function trunc(x: f32): f32 { 143 | return Mathf.trunc(x); 144 | } 145 | -------------------------------------------------------------------------------- /libm/assembly/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../node_modules/assemblyscript/std/assembly.json", 3 | "include": [ 4 | "./**/*.ts" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /libm/build/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /libm/index.d.ts: -------------------------------------------------------------------------------- 1 | declare const libm: typeof Math & { libm: typeof Math, libmf: typeof Math }; 2 | export = libm; 3 | -------------------------------------------------------------------------------- /libm/index.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const libm = new WebAssembly.Instance(new WebAssembly.Module(fs.readFileSync("./build/libm.wasm")), { Math }).exports; 3 | const libmf = new WebAssembly.Instance(new WebAssembly.Module(fs.readFileSync("./build/libmf.wasm")), {}).exports; 4 | module.exports = Object.create(libm, { 5 | libm: { value: libm, enumerable: true }, 6 | libmf: { value: libmf, enumerable: true } 7 | }); 8 | -------------------------------------------------------------------------------- /libm/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@assemblyscript/libm-example", 3 | "version": "1.0.0", 4 | "license": "Apache-2.0", 5 | "private": true, 6 | "main": "index.js", 7 | "types": "index.d.ts", 8 | "scripts": { 9 | "asbuild": "npm run asbuild:libm && npm run asbuild:libmf", 10 | "asbuild:libm": "asc assembly/libm.ts -O3 -o build/libm.wasm -t build/libm.wat --runtime stub", 11 | "asbuild:libmf": "asc assembly/libmf.ts -O3 -o build/libmf.wasm -t build/libmf.wat --runtime stub", 12 | "test": "node tests" 13 | }, 14 | "files": [ 15 | "package.json", 16 | "index.d.ts", 17 | "index.js", 18 | "build/*.wasm", 19 | "README.md" 20 | ], 21 | "devDependencies": { 22 | "assemblyscript": "latest" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /libm/tests/index.js: -------------------------------------------------------------------------------- 1 | const { libm, libmf } = require(".."); 2 | 3 | console.log("=== libm ==="); 4 | console.log(libm); 5 | 6 | console.log("=== libmf ==="); 7 | console.log(libmf); 8 | -------------------------------------------------------------------------------- /loader/README.md: -------------------------------------------------------------------------------- 1 | Loader Example 2 | ============== 3 | 4 | An [AssemblyScript](http://assemblyscript.org) example. Utilizes the [loader](https://docs.assemblyscript.org/basics/loader) to perform various common tasks on the WebAssembly/JavaScript boundary, like passing along strings and arrays. 5 | 6 | Instructions 7 | ------------ 8 | 9 | Install the dependencies, build the WebAssembly module and verify that everything works: 10 | 11 | ``` 12 | $> npm install 13 | $> npm run asbuild 14 | $> npm test 15 | ``` 16 | 17 | The example consists of several files showing the different perspectives, in recommended reading order: 18 | 19 | * [assembly/index.ts](./assembly/index.ts)
20 | The AssemblyScript sources we are going to compile to a WebAssembly module. 21 | Contains the implementations we are going to call from JavaScript. 22 | 23 | * [tests/index.js](./tests/index.js)
24 | A test loading our WebAssembly node module that will utilize the loader to 25 | pass strings and arrays between WebAssembly and JavaScript. 26 | 27 | * [index.js](./index.js)
28 | Instantiates the WebAssembly module and exposes it as a node module. Also 29 | provides the imported functions used in Example 3. 30 | 31 | * [assembly/myConsole.ts](./assembly/myConsole.ts)
32 | The import declarations of our custom console API used in Example 3. 33 | 34 | To rerun the tests: 35 | 36 | ``` 37 | $> npm test 38 | ``` 39 | -------------------------------------------------------------------------------- /loader/assembly/index.ts: -------------------------------------------------------------------------------- 1 | // Example 1: Passing a string from WebAssembly to JavaScript. 2 | 3 | // Under the hood, the following yields a WebAssembly function export returning 4 | // the pointer to a string within the module's memory. To obtain its contents, 5 | // we are going to read it from memory on the JavaScript side. 6 | 7 | // see: tests/index.js "Test for Example 1" 8 | 9 | export function getHello(): string { 10 | return "Hello world (I am a WebAssembly string)"; 11 | } 12 | 13 | // Example 2: Passing a string from JavaScript to WebAssembly. 14 | 15 | // Similarly, we'll call the following function with a pointer to a string in 16 | // the module's memory from JavaScript. To do so, the string will first be 17 | // allocated on the JavaScript side, while holding on to a reference to it. 18 | 19 | // see: tests/index.js "Test for Example 2" 20 | 21 | export function sayHello(s: string): void { 22 | console.log(" " + s); // see Example 3 23 | } 24 | 25 | // Example 3: Calling a JavaScript import with a WebAssembly string. 26 | 27 | // see: assembly/myConsole.ts 28 | 29 | import * as console from "./myConsole"; 30 | 31 | // Example 4: Passing an array from WebAssembly to JavaScript. 32 | 33 | // Analogous to the examples above working with strings, the following function 34 | // will return a pointer to an array within the module's memory. We can either 35 | // get a live view on it to modify, or obtain a copy. 36 | 37 | // see: tests/index.js "Test for Example 4" 38 | 39 | export function getMyArray(size: i32): Int32Array { 40 | var arr = new Int32Array(size); 41 | for (let i = 0; i < size; ++i) { 42 | arr[i] = i; 43 | } 44 | return arr; 45 | } 46 | 47 | // Example 5: Passing an array from JavaScript to WebAssembly. 48 | 49 | // Likewise, we can also allocate an array on the JavaScript side and pass its 50 | // pointer to WebAssembly, then doing something with it. 51 | 52 | // see: tests/index.js "Test for Example 5" 53 | 54 | export function computeSum(a: Int32Array): i32 { 55 | console.time("sum"); // see Example 3 56 | var sum = 0; 57 | for (let i = 0, k = a.length; i < k; ++i) { 58 | sum += a[i]; 59 | } 60 | console.timeEnd("sum"); // see Example 3 61 | return sum; 62 | } 63 | 64 | // See the comments in test/index.js "Test for Example 5" for why this is 65 | // necessary, and how to perform an Int32Array allocation using its runtime id. 66 | export const Int32Array_ID = idof(); 67 | 68 | // Example 6: WebAssembly arrays of WebAssembly strings. 69 | 70 | // Let's get a little more serious with a combined example. We'd like to pass an 71 | // array of strings from JavaScript to WebAssembly, create a new array with all 72 | // strings converted to upper case, return it to JavaScript and print its contents. 73 | 74 | // see: tests/index.js "Test for Example 6" 75 | 76 | export function capitalize(a: string[]): string[] { 77 | var length = a.length; 78 | var b = new Array(length); 79 | for (let i = 0; i < length; ++i) { 80 | b[i] = a[i].toUpperCase(); 81 | } 82 | return b; 83 | } 84 | 85 | export const ArrayOfStrings_ID = idof(); 86 | 87 | // Example 7: Using custom classes. 88 | 89 | // The loader also understands exports of entire classes, and with the knowledge 90 | // obtained in the previous examples it becomes possible to interface with a 91 | // more complex program like the following in a nearly natural way. 92 | 93 | // see: tests/index.js "Test for Example 7" 94 | 95 | export namespace Game { 96 | export class Player { 97 | name: string; 98 | position: Position | null; 99 | constructor(name: string) { 100 | this.name = name; 101 | this.position = new Position(); 102 | } 103 | move(x: i32, y: i32): void { 104 | var position = assert(this.position); 105 | position.x += x; 106 | position.y += y; 107 | } 108 | kill(): void { 109 | this.position = null; 110 | } 111 | toString(): string { 112 | var position = this.position; 113 | if (position) { 114 | return this.name + " @ " + position.toString(); 115 | } else { 116 | return this.name + " @ AWAITING ASSIGNMENT"; 117 | } 118 | } 119 | } 120 | export class Position { 121 | x: i32 = 0; 122 | y: i32 = 0; 123 | toString(): string { 124 | return this.x.toString() + "/" + this.y.toString(); 125 | } 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /loader/assembly/myConsole.ts: -------------------------------------------------------------------------------- 1 | // Example 3: Calling JavaScript imports with WebAssembly strings. 2 | 3 | // Let's declare a `myConsole` import, with member functions we can call with 4 | // WebAssembly strings. Our imports, defined in the top-level index.js, will 5 | // translate the calls to JavaScript's console API using the loader. 6 | 7 | export declare function log(s: string): void; 8 | export declare function time(s: string): void; 9 | export declare function timeEnd(s: string): void; 10 | -------------------------------------------------------------------------------- /loader/assembly/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../node_modules/assemblyscript/std/assembly.json", 3 | "include": [ 4 | "./**/*.ts" 5 | ] 6 | } -------------------------------------------------------------------------------- /loader/build/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | !optimized.wasm 4 | -------------------------------------------------------------------------------- /loader/build/optimized.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AssemblyScript/examples/8b23ca8fa2f27cf9a39e5dfe4989d9eeba87d48f/loader/build/optimized.wasm -------------------------------------------------------------------------------- /loader/index.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const loader = require("@assemblyscript/loader"); 3 | const wasmModule = loader.instantiateSync(fs.readFileSync(__dirname + "/build/optimized.wasm"), 4 | 5 | // These are the JavaScript imports to our WebAssembly module, translating 6 | // from WebAssembly strings, received as a pointer into the module's memory, 7 | // to JavaScript's console API as JavaScript strings. 8 | { 9 | // Example 3: Calling JavaScript imports with WebAssembly strings. 10 | myConsole: { 11 | log(messagePtr) { // Called as `console.log` in assembly/index.ts 12 | console.log(wasmModule.exports.__getString(messagePtr)); 13 | }, 14 | time(labelPtr) { // Called as `console.time` in assembly/index.ts 15 | console.time(wasmModule.exports.__getString(labelPtr)); 16 | }, 17 | timeEnd(labelPtr) { // Called as `console.timeEnd` in assembly/index.ts 18 | console.timeEnd(wasmModule.exports.__getString(labelPtr)); 19 | } 20 | } 21 | } 22 | ); 23 | module.exports = wasmModule.exports; 24 | -------------------------------------------------------------------------------- /loader/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@assemblyscript/loader-example", 3 | "version": "1.0.0", 4 | "license": "Apache-2.0", 5 | "private": true, 6 | "scripts": { 7 | "asbuild:untouched": "asc assembly/index.ts -b build/untouched.wasm -t build/untouched.wat --exportRuntime --sourceMap --debug", 8 | "asbuild:optimized": "asc assembly/index.ts -b build/optimized.wasm -t build/optimized.wat --exportRuntime --sourceMap --optimize", 9 | "asbuild": "npm run asbuild:untouched && npm run asbuild:optimized", 10 | "test": "node tests" 11 | }, 12 | "dependencies": { 13 | "@assemblyscript/loader": "latest" 14 | }, 15 | "devDependencies": { 16 | "assemblyscript": "latest" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /loader/preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AssemblyScript/examples/8b23ca8fa2f27cf9a39e5dfe4989d9eeba87d48f/loader/preview.jpg -------------------------------------------------------------------------------- /loader/tests/index.js: -------------------------------------------------------------------------------- 1 | // Load the node module exporting our WebAssembly module 2 | const myModule = require("../index"); 3 | 4 | // Obtain the runtime helpers for 5 | const { 6 | // memory management 7 | __newString, __newArray, 8 | // garbage collection 9 | __pin, __unpin, 10 | // and interop 11 | __getString, __getArray, __getArrayView 12 | } = myModule; 13 | 14 | // Test for Example 1: Passing a string from WebAssembly to JavaScript. 15 | { 16 | console.log("Example 1:"); 17 | 18 | // Obtain a pointer to our string in the module's memory. 19 | const ptr = __pin(myModule.getHello()); 20 | 21 | // Print its contents 22 | console.log(" " + __getString(ptr)); 23 | 24 | __unpin(ptr); // it is ok if the string becomes garbage collected now 25 | } 26 | 27 | // Test for Example 2: Passing a string from JavaScript to WebAssembly. 28 | { 29 | console.log("Example 2:"); 30 | 31 | // Allocate a string in the module's memory and pin it externally 32 | const ptr = __pin(__newString("Hello world (I am a JavaScript string)")); 33 | 34 | // Pass it to our WebAssembly export, which is going to print it using our custom console 35 | myModule.sayHello(ptr); 36 | 37 | __unpin(ptr); // it is ok if the string becomes garbage collected now 38 | } 39 | 40 | // Test for Example 4: Passing an array from WebAssembly to JavaScript. 41 | { 42 | console.log("Example 4:"); 43 | 44 | // Obtain a pointer to our array in the module's memory. 45 | const ptr = __pin(myModule.getMyArray(10)); 46 | 47 | // Obtain a live view on it 48 | const view = __getArrayView(ptr); 49 | console.log(" " + view + " (view)"); 50 | 51 | // Obtain a copy of it (modifying the live view does not modify the copy) 52 | const copy = __getArray(ptr); 53 | console.log(" " + copy + " (copy)"); 54 | 55 | __unpin(ptr); // it is ok if the array becomes garbage collected now 56 | } 57 | 58 | // Test for Example 5: Passing an array from JavaScript to WebAssembly. 59 | { 60 | console.log("Example 5:"); 61 | 62 | // Allocate a new array in WebAssembly memory and get a view on it. Note that 63 | // we have to specify the runtime id of the array type we want to allocate, so 64 | // we export its id (`idof`) from the module to do so. 65 | const ptr = __pin(__newArray(myModule.Int32Array_ID, [ 1, 2, 3 ])); 66 | const view = __getArrayView(ptr); 67 | const copy = __getArray(ptr); 68 | 69 | // Compute its sum 70 | console.log(" Sum of " + view + " is " + myModule.computeSum(ptr)); 71 | 72 | // Modify the first element in place, and compute the new sum 73 | view[0] = 42; 74 | console.log(" Sum of " + view + " is " + myModule.computeSum(ptr)); 75 | 76 | // The initial copy remains unchanged and is not linked to `ptr` 77 | console.log(" Unmodified copy: " + copy); 78 | 79 | __unpin(ptr); // it is ok if the array becomes garbage collected now 80 | } 81 | 82 | // Test for Example 6: WebAssembly arrays of WebAssembly strings. 83 | { 84 | console.log("Example 6:"); 85 | 86 | // Allocate a new array, but this time its elements are pointers to strings. 87 | const elemPtrs = [ "hello", "world" ].map(v => __pin(__newString(v))); 88 | const inPtr = __pin(__newArray(myModule.ArrayOfStrings_ID, elemPtrs)); 89 | 90 | // The array keeps its values alive from now on 91 | elemPtrs.forEach(__unpin); 92 | 93 | // Provide our array of lowercase strings to WebAssembly, and obtain the new 94 | // array of uppercase strings before printing it. 95 | const outPtr = __pin(myModule.capitalize(inPtr)); 96 | console.log(" Uppercased: " + __getArray(outPtr).map(__getString)); 97 | 98 | __unpin(inPtr); // it is ok if the arrays becomes garbage collected now 99 | __unpin(outPtr); 100 | 101 | // Note that Example 6 is not an especially efficient use case and one would 102 | // typically rather avoid the overhead and do this in JavaScript directly. 103 | } 104 | 105 | // Test for Example 7: Using custom classes. 106 | { 107 | console.log("Example 7:"); 108 | 109 | // Create a new player. Note that the loader makes a nice object structure 110 | // of our exports, here a class `Player` within the `Game` namespace. So 111 | // let's call the `Player` constructor: 112 | let player; 113 | { 114 | const namePtr = __pin(__newString("Gordon Freeman")); 115 | player = new myModule.Game.Player(namePtr); 116 | __pin(player); 117 | __unpin(namePtr); 118 | // Pro tip: Pinning is optional in this exact case 119 | } 120 | 121 | // Let's see how our player looks now by calling toString 122 | { 123 | const strPtr = __pin(player.toString()); 124 | console.log(" Player (new): " + __getString(strPtr)); 125 | __unpin(strPtr); 126 | // Pro tip: Pinning is optional in this exact case 127 | } 128 | 129 | // Move them and log again 130 | { 131 | player.move(10, 20); 132 | const strPtr = __pin(player.toString()); 133 | console.log(" Player (moved): " + __getString(strPtr)); 134 | __unpin(strPtr); 135 | // Pro tip: Pinning is optional in this exact case 136 | } 137 | 138 | // Obtaining just the position. Note that we can `wrap` any pointer with 139 | // the matching class within the object structure made by the loader, and 140 | // that a position's x and y properties are just basic values, not objects, 141 | // so tracking references does not apply to them. 142 | { 143 | const positionPtr = __pin(player.position); 144 | const position = myModule.Game.Position.wrap(positionPtr); 145 | console.log(" Position (wrapped): " + position.x + "/" + position.y); 146 | 147 | position.x -= 100; 148 | position.y += 200; 149 | 150 | const strPtr = __pin(position.toString()); 151 | console.log(" Position (moved): " + __getString(strPtr)); 152 | __unpin(strPtr); 153 | 154 | __unpin(positionPtr); 155 | } 156 | 157 | // Finish 'em 158 | { 159 | player.kill(); 160 | const strPtr = __pin(player.toString()); 161 | console.log(" Player (finished): " + __getString(strPtr)); 162 | __unpin(strPtr); 163 | // Pro tip: Pinning is optional in this exact case 164 | } 165 | 166 | __unpin(player); // a tidy house, a tidy mind. 167 | } 168 | 169 | // Interested in all the details? https://docs.assemblyscript.org/details :) 170 | -------------------------------------------------------------------------------- /mandelbrot/README.md: -------------------------------------------------------------------------------- 1 | Mandelbrot Set 2 | ============== 3 | 4 | An [AssemblyScript](http://assemblyscript.org) example. Renders the Mandelbrot set to a canvas. Compiles to ~590 bytes of optimized WASM. 5 | 6 | Instructions 7 | ------------ 8 | 9 | First, install the development dependencies: 10 | 11 | ``` 12 | $> npm install 13 | ``` 14 | 15 | Now, to build [assembly/index.ts](./assembly/index.ts) to an untouched and an optimized `.wasm` including their respective `.wat` representations, run: 16 | 17 | ``` 18 | $> npm run asbuild 19 | ``` 20 | 21 | Afterwards, run 22 | 23 | ``` 24 | $> npm start 25 | ``` 26 | 27 | to start a local server. 28 | -------------------------------------------------------------------------------- /mandelbrot/asconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "options": { 3 | "runtime": "stub", 4 | "use": "Math=JSMath", 5 | "importMemory": true, 6 | "sourceMap": true, 7 | "measure": true 8 | }, 9 | "targets": { 10 | "debug": { 11 | "outFile": "build/debug.wasm", 12 | "textFile": "build/debug.wat", 13 | "debug": true 14 | }, 15 | "release": { 16 | "outFile": "build/release.wasm", 17 | "textFile": "build/release.wat", 18 | "optimizeLevel": 3, 19 | "shrinkLevel": 0, 20 | "noAssert": true 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /mandelbrot/assembly/index.ts: -------------------------------------------------------------------------------- 1 | // see: https://en.wikipedia.org/wiki/Mandelbrot_set 2 | 3 | /** Number of discrete color values on the JS side. */ 4 | const NUM_COLORS = 2048; 5 | 6 | /** Computes a single line in the rectangle `width` x `height`. */ 7 | export function computeLine(y: u32, width: u32, height: u32, limit: u32): void { 8 | var translateX = width * (1.0 / 1.6); 9 | var translateY = height * (1.0 / 2.0); 10 | var scale = 10.0 / min(3 * width, 4 * height); 11 | var imaginary = (y - translateY) * scale; 12 | var realOffset = translateX * scale; 13 | var stride = (y * width) << 1; 14 | var invLimit = 1.0 / limit; 15 | 16 | var minIterations = min(8, limit); 17 | 18 | for (let x: u32 = 0; x < width; ++x) { 19 | let real = x * scale - realOffset; 20 | 21 | // Iterate until either the escape radius or iteration limit is exceeded 22 | let ix = 0.0, iy = 0.0, ixSq: f64, iySq: f64; 23 | let iteration: u32 = 0; 24 | while ((ixSq = ix * ix) + (iySq = iy * iy) <= 4.0) { 25 | iy = 2.0 * ix * iy + imaginary; 26 | ix = ixSq - iySq + real; 27 | if (iteration >= limit) break; 28 | ++iteration; 29 | } 30 | 31 | // Do a few extra iterations for quick escapes to reduce error margin 32 | while (iteration < minIterations) { 33 | let ixNew = ix * ix - iy * iy + real; 34 | iy = 2.0 * ix * iy + imaginary; 35 | ix = ixNew; 36 | ++iteration; 37 | } 38 | 39 | // Iteration count is a discrete value in the range [0, limit] here, but we'd like it to be 40 | // normalized in the range [0, 2047] so it maps to the gradient computed in JS. 41 | // see also: http://linas.org/art-gallery/escape/escape.html 42 | let col = NUM_COLORS - 1; 43 | let sqd = ix * ix + iy * iy; 44 | if (sqd > 1.0) { 45 | let frac = Math.log2(0.5 * Math.log(sqd)); 46 | col = ((NUM_COLORS - 1) * clamp((iteration + 1 - frac) * invLimit, 0.0, 1.0)); 47 | } 48 | store(stride + (x << 1), col); 49 | } 50 | } 51 | 52 | /** Clamps a value between the given minimum and maximum. */ 53 | @inline 54 | function clamp(value: T, minValue: T, maxValue: T): T { 55 | return min(max(value, minValue), maxValue); 56 | } 57 | -------------------------------------------------------------------------------- /mandelbrot/assembly/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../node_modules/assemblyscript/std/assembly.json", 3 | "include": [ 4 | "./**/*.ts" 5 | ] 6 | } -------------------------------------------------------------------------------- /mandelbrot/build/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | !release.wasm 4 | -------------------------------------------------------------------------------- /mandelbrot/build/release.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AssemblyScript/examples/8b23ca8fa2f27cf9a39e5dfe4989d9eeba87d48f/mandelbrot/build/release.wasm -------------------------------------------------------------------------------- /mandelbrot/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Mandelbrot set - AssemblyScript 7 | 8 | 16 | 17 | 18 |

19 | Mandelbrot set in 20 | AssemblyScript 21 | ( source ) 22 |

23 | 24 | 137 | 138 | 139 | -------------------------------------------------------------------------------- /mandelbrot/index.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const compiled = new WebAssembly.Module(fs.readFileSync(__dirname + "/build/release.wasm")); 3 | const imports = { 4 | env: { 5 | "Math.log": Math.log, 6 | "Math.log2": Math.log2, 7 | } 8 | }; 9 | Object.defineProperty(module, "exports", { 10 | get: () => new WebAssembly.Instance(compiled, imports).exports 11 | }); 12 | -------------------------------------------------------------------------------- /mandelbrot/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@assemblyscript/mandelbrot-example", 3 | "version": "1.0.0", 4 | "license": "Apache-2.0", 5 | "private": true, 6 | "scripts": { 7 | "asbuild:debug": "asc assembly/index.ts --target debug", 8 | "asbuild:release": "asc assembly/index.ts --target release", 9 | "asbuild": "npm run asbuild:debug && npm run asbuild:release", 10 | "start": "npx serve" 11 | }, 12 | "devDependencies": { 13 | "assemblyscript": "latest" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /mandelbrot/preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AssemblyScript/examples/8b23ca8fa2f27cf9a39e5dfe4989d9eeba87d48f/mandelbrot/preview.jpg -------------------------------------------------------------------------------- /n-body/README.md: -------------------------------------------------------------------------------- 1 | N-body system 2 | ============= 3 | 4 | An [AssemblyScript](http://assemblyscript.org) example. This is actually a benchmark - visualizing it just so happened. 5 | 6 | Instructions 7 | ------------ 8 | 9 | First, install the development dependencies: 10 | 11 | ``` 12 | $> npm install 13 | ``` 14 | 15 | Now, to build [assembly/index.ts](./assembly/index.ts) to an untouched and an optimized `.wasm` including their respective `.wat` representations, run: 16 | 17 | ``` 18 | $> npm run asbuild 19 | ``` 20 | 21 | Afterwards, run 22 | 23 | ``` 24 | $> npm start 25 | ``` 26 | 27 | to start a local server. 28 | 29 | To run the benchmark: 30 | 31 | ```bash 32 | $> npm test [steps=1000000] 33 | ``` 34 | 35 | Benchmark 36 | 37 | ========= 38 | 39 | ***Environment:*** 40 | 41 | - MacBook Pro (15-inch, 2019) 42 | - macOS 12.5.0 43 | - node.js v18.7.0 44 | - rustc 1.64.0-nightly (0f4bcadb4 2022-07-30) 45 | 46 | ***Results:*** 47 | 48 | | Target | Time, ***ms*** | Size, ***KB*** | 49 | |-------------------------|-----------------|----------------| 50 | | **AssemblyScript WASM** | **1606** | **1.8** | 51 | | JavaScript | 11640 | 5* | 52 | | Rust WASM | 1611 | 2 | 53 | 54 | ___* unminified___ 55 | -------------------------------------------------------------------------------- /n-body/asconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "options": { 3 | "runtime": "stub", 4 | "initialMemory": 17, 5 | "sourceMap": true 6 | }, 7 | "targets": { 8 | "wasm": { 9 | "outFile": "build/as_nbody.wasm", 10 | "textFile": "build/as_nbody.wat", 11 | "optimizeLevel": 3, 12 | "shrinkLevel": 0, 13 | "converge": true, 14 | "noAssert": true 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /n-body/assembly/index.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const path = require("path"); 3 | 4 | const compiled = new WebAssembly.Module( 5 | fs.readFileSync(path.resolve(__dirname, "..", "build", "as_nbody.wasm")) 6 | ); 7 | 8 | const imports = { 9 | env: { 10 | abort: (_, line, column) => { 11 | throw Error("abort called at " + line + ":" + column); 12 | } 13 | } 14 | }; 15 | 16 | Object.defineProperty(module, "exports", { 17 | get: () => new WebAssembly.Instance(compiled, imports).exports 18 | }); 19 | -------------------------------------------------------------------------------- /n-body/assembly/index.ts: -------------------------------------------------------------------------------- 1 | // From The Computer Language Benchmarks Game 2 | // http://benchmarksgame.alioth.debian.org 3 | 4 | type float = f64; // interchangeable f32/f64 for testing 5 | 6 | const SOLAR_MASS = (4.0 * Math.PI * Math.PI); 7 | const DAYS_PER_YEAR: float = 365.24; 8 | 9 | class Body { 10 | 11 | constructor( 12 | public x: float, 13 | public y: float, 14 | public z: float, 15 | public vx: float, 16 | public vy: float, 17 | public vz: float, 18 | public mass: float 19 | ) {} 20 | 21 | offsetMomentum(px: float, py: float, pz: float): this { 22 | this.vx = -px / SOLAR_MASS; 23 | this.vy = -py / SOLAR_MASS; 24 | this.vz = -pz / SOLAR_MASS; 25 | return this; 26 | } 27 | } 28 | 29 | function Sun(): Body { 30 | return new Body( 31 | 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, SOLAR_MASS 32 | ); 33 | } 34 | 35 | function Jupiter(): Body { 36 | return new Body( 37 | 4.84143144246472090e+00, 38 | -1.16032004402742839e+00, 39 | -1.03622044471123109e-01, 40 | 1.66007664274403694e-03 * DAYS_PER_YEAR, 41 | 7.69901118419740425e-03 * DAYS_PER_YEAR, 42 | -6.90460016972063023e-05 * DAYS_PER_YEAR, 43 | 9.54791938424326609e-04 * SOLAR_MASS 44 | ); 45 | } 46 | 47 | function Saturn(): Body { 48 | return new Body( 49 | 8.34336671824457987e+00, 50 | 4.12479856412430479e+00, 51 | -4.03523417114321381e-01, 52 | -2.76742510726862411e-03 * DAYS_PER_YEAR, 53 | 4.99852801234917238e-03 * DAYS_PER_YEAR, 54 | 2.30417297573763929e-05 * DAYS_PER_YEAR, 55 | 2.85885980666130812e-04 * SOLAR_MASS 56 | ); 57 | } 58 | 59 | function Uranus(): Body { 60 | return new Body( 61 | 1.28943695621391310e+01, 62 | -1.51111514016986312e+01, 63 | -2.23307578892655734e-01, 64 | 2.96460137564761618e-03 * DAYS_PER_YEAR, 65 | 2.37847173959480950e-03 * DAYS_PER_YEAR, 66 | -2.96589568540237556e-05 * DAYS_PER_YEAR, 67 | 4.36624404335156298e-05 * SOLAR_MASS 68 | ); 69 | } 70 | 71 | function Neptune(): Body { 72 | return new Body( 73 | 1.53796971148509165e+01, 74 | -2.59193146099879641e+01, 75 | 1.79258772950371181e-01, 76 | 2.68067772490389322e-03 * DAYS_PER_YEAR, 77 | 1.62824170038242295e-03 * DAYS_PER_YEAR, 78 | -9.51592254519715870e-05 * DAYS_PER_YEAR, 79 | 5.15138902046611451e-05 * SOLAR_MASS 80 | ); 81 | } 82 | 83 | class NBodySystem { 84 | 85 | constructor(public bodies: StaticArray) { 86 | var px: float = 0.0; 87 | var py: float = 0.0; 88 | var pz: float = 0.0; 89 | var size = bodies.length; 90 | for (let i = 0; i < size; ++i) { 91 | let b = unchecked(bodies[i]); 92 | let m = b.mass; 93 | px += b.vx * m; 94 | py += b.vy * m; 95 | pz += b.vz * m; 96 | } 97 | unchecked(bodies[0]).offsetMomentum(px, py, pz); 98 | } 99 | 100 | advance(dt: float): void { 101 | var bodies = this.bodies; 102 | var size: u32 = bodies.length; 103 | // var buffer = changetype(bodies.buffer_); 104 | 105 | for (let i: u32 = 0; i < size; ++i) { 106 | let bodyi = unchecked(bodies[i]); 107 | // let bodyi = load(buffer + i * sizeof(), 8); 108 | 109 | let ix = bodyi.x; 110 | let iy = bodyi.y; 111 | let iz = bodyi.z; 112 | 113 | let bivx = bodyi.vx; 114 | let bivy = bodyi.vy; 115 | let bivz = bodyi.vz; 116 | 117 | let bodyim = bodyi.mass; 118 | for (let j: u32 = i + 1; j < size; ++j) { 119 | let bodyj = unchecked(bodies[j]); 120 | // let bodyj = load(buffer + j * sizeof(), 8); 121 | 122 | let dx = ix - bodyj.x; 123 | let dy = iy - bodyj.y; 124 | let dz = iz - bodyj.z; 125 | 126 | let distanceSq = dx * dx + dy * dy + dz * dz; 127 | let distance = Math.sqrt(distanceSq); 128 | let mag = dt / (distanceSq * distance); 129 | 130 | let bim = bodyim * mag; 131 | let bjm = bodyj.mass * mag; 132 | 133 | bivx -= dx * bjm; 134 | bivy -= dy * bjm; 135 | bivz -= dz * bjm; 136 | 137 | bodyj.vx += dx * bim; 138 | bodyj.vy += dy * bim; 139 | bodyj.vz += dz * bim; 140 | } 141 | 142 | bodyi.vx = bivx; 143 | bodyi.vy = bivy; 144 | bodyi.vz = bivz; 145 | 146 | bodyi.x += dt * bivx; 147 | bodyi.y += dt * bivy; 148 | bodyi.z += dt * bivz; 149 | } 150 | } 151 | 152 | energy(): float { 153 | var e: float = 0.0; 154 | var bodies = this.bodies; 155 | 156 | for (let i: u32 = 0, size: u32 = bodies.length; i < size; ++i) { 157 | let bodyi = unchecked(bodies[i]); 158 | 159 | let ix = bodyi.x; 160 | let iy = bodyi.y; 161 | let iz = bodyi.z; 162 | 163 | let vx = bodyi.vx; 164 | let vy = bodyi.vy; 165 | let vz = bodyi.vz; 166 | 167 | let bim = bodyi.mass; 168 | 169 | e += 0.5 * bim * (vx * vx + vy * vy + vz * vz); 170 | 171 | for (let j: u32 = i + 1; j < size; ++j) { 172 | let bodyj = unchecked(bodies[j]); 173 | let dx = ix - bodyj.x; 174 | let dy = iy - bodyj.y; 175 | let dz = iz - bodyj.z; 176 | let distance = Math.sqrt(dx * dx + dy * dy + dz * dz); 177 | e -= bim * bodyj.mass / distance; 178 | } 179 | } 180 | return e; 181 | } 182 | } 183 | 184 | var system: NBodySystem; 185 | 186 | export function init(): void { 187 | system = new NBodySystem([ 188 | Sun(), 189 | Jupiter(), 190 | Saturn(), 191 | Uranus(), 192 | Neptune() 193 | ]); 194 | } 195 | 196 | export function step(): float { 197 | system.advance(0.01); 198 | return system.energy(); 199 | } 200 | 201 | export function bench(steps: u32): void { 202 | for (let i: u32 = 0; i < steps; ++i) system.advance(0.01); 203 | } 204 | 205 | export function getBody(index: i32): Body | null { 206 | var bodies = system.bodies; 207 | return index < bodies.length ? unchecked(bodies[index]) : null; 208 | } 209 | -------------------------------------------------------------------------------- /n-body/assembly/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../node_modules/assemblyscript/std/assembly.json", 3 | "include": [ 4 | "./**/*.ts" 5 | ] 6 | } -------------------------------------------------------------------------------- /n-body/build/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | !as_nbody.wasm 4 | -------------------------------------------------------------------------------- /n-body/build/as_nbody.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AssemblyScript/examples/8b23ca8fa2f27cf9a39e5dfe4989d9eeba87d48f/n-body/build/as_nbody.wasm -------------------------------------------------------------------------------- /n-body/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | N-body system - AssemblyScript 7 | 8 | 16 | 17 | 18 |

19 | N-body system in 20 | AssemblyScript 21 | ( source ) 22 |

23 | 24 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /n-body/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@assemblyscript/n-body-example", 3 | "version": "1.0.0", 4 | "license": "Apache-2.0", 5 | "private": true, 6 | "scripts": { 7 | "asbuild:wasm": "asc assembly/index.ts --target wasm", 8 | "asbuild": "npm run asbuild:wasm", 9 | "tsbuild": "tsc -p assembly -t esnext -m commonjs --outDir build && node scripts/postprocess", 10 | "rsbuild": "cd rust && RUSTFLAGS='-C link-arg=-s' cargo +nightly build --release", 11 | "build": "npm run asbuild && npm run tsbuild && npm run rsbuild", 12 | "start": "npx serve", 13 | "test": "node --nowasm-bounds-checks --nowasm-stack-checks --noliftoff --expose-gc tests" 14 | }, 15 | "devDependencies": { 16 | "assemblyscript": "latest", 17 | "typescript": "^4.7.4" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /n-body/preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AssemblyScript/examples/8b23ca8fa2f27cf9a39e5dfe4989d9eeba87d48f/n-body/preview.jpg -------------------------------------------------------------------------------- /n-body/rust/.cargo/config: -------------------------------------------------------------------------------- 1 | [build] 2 | jobs = 1 3 | target = "wasm32-unknown-unknown" 4 | target-dir = "../build" 5 | -------------------------------------------------------------------------------- /n-body/rust/.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | -------------------------------------------------------------------------------- /n-body/rust/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "rust_nbody" 5 | version = "0.1.0" 6 | 7 | -------------------------------------------------------------------------------- /n-body/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rust_nbody" 3 | version = "0.1.0" 4 | authors = ["MaxGraey "] 5 | 6 | [lib] 7 | path = "src/lib.rs" 8 | crate-type = ["cdylib"] 9 | 10 | [profile.dev] 11 | panic = "abort" 12 | 13 | [profile.release] 14 | panic = "abort" 15 | lto = true 16 | opt-level = 3 17 | -------------------------------------------------------------------------------- /n-body/rust/README.md: -------------------------------------------------------------------------------- 1 | ### Build 2 | ```bash 3 | npm run rsbuild 4 | ``` 5 | or 6 | ```bash 7 | RUSTFLAGS='-C link-arg=-s' cargo +nightly build --release 8 | ``` 9 | 10 | ***wasm-gc is deprecated. But the same strip effect we could get with RUSTFLAGS='-C link-arg=-s'*** 11 | -------------------------------------------------------------------------------- /n-body/rust/index.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const path = require("path"); 3 | 4 | const compiled = new WebAssembly.Module( 5 | fs.readFileSync(path.resolve( 6 | __dirname, 7 | "..", 8 | "build", 9 | "wasm32-unknown-unknown", 10 | "release", 11 | "rust_nbody.wasm" 12 | ) 13 | )); 14 | 15 | const imports = { 16 | env: { 17 | memory: new WebAssembly.Memory({ initial: 17 }), 18 | abort: (_filename, line, column) => { 19 | throw Error("abort called at " + line + ":" + column); 20 | } 21 | } 22 | }; 23 | 24 | Object.defineProperty(module, "exports", { 25 | get: () => new WebAssembly.Instance(compiled, imports).exports 26 | }); 27 | -------------------------------------------------------------------------------- /n-body/rust/src/lib.rs: -------------------------------------------------------------------------------- 1 | // Code adopted from https://benchmarksgame-team.pages.debian.net/benchmarksgame/program/nbody-rust-1.html 2 | 3 | #![feature(core_intrinsics)] 4 | #![no_std] 5 | 6 | use core::intrinsics; 7 | use core::panic::PanicInfo; 8 | 9 | #[panic_handler] 10 | pub fn panic(_info: &PanicInfo) -> ! { 11 | loop {} 12 | } 13 | 14 | #[inline(always)] 15 | fn sqrt(x: f64) -> f64 { 16 | unsafe { intrinsics::sqrtf64(x) } 17 | } 18 | 19 | const PI: f64 = 3.141592653589793; 20 | const SOLAR_MASS: f64 = 4.0 * PI * PI; 21 | const YEAR: f64 = 365.24; 22 | const N_BODIES: usize = 5; 23 | 24 | static mut BODIES: [Planet; N_BODIES] = [ 25 | // Sun 26 | Planet { 27 | x: 0.0, 28 | y: 0.0, 29 | z: 0.0, 30 | vx: 0.0, 31 | vy: 0.0, 32 | vz: 0.0, 33 | mass: SOLAR_MASS, 34 | }, 35 | // Jupiter 36 | Planet { 37 | x: 4.84143144246472090e+00, 38 | y: -1.16032004402742839e+00, 39 | z: -1.03622044471123109e-01, 40 | vx: 1.66007664274403694e-03 * YEAR, 41 | vy: 7.69901118419740425e-03 * YEAR, 42 | vz: -6.90460016972063023e-05 * YEAR, 43 | mass: 9.54791938424326609e-04 * SOLAR_MASS, 44 | }, 45 | // Saturn 46 | Planet { 47 | x: 8.34336671824457987e+00, 48 | y: 4.12479856412430479e+00, 49 | z: -4.03523417114321381e-01, 50 | vx: -2.76742510726862411e-03 * YEAR, 51 | vy: 4.99852801234917238e-03 * YEAR, 52 | vz: 2.30417297573763929e-05 * YEAR, 53 | mass: 2.85885980666130812e-04 * SOLAR_MASS, 54 | }, 55 | // Uranus 56 | Planet { 57 | x: 1.28943695621391310e+01, 58 | y: -1.51111514016986312e+01, 59 | z: -2.23307578892655734e-01, 60 | vx: 2.96460137564761618e-03 * YEAR, 61 | vy: 2.37847173959480950e-03 * YEAR, 62 | vz: -2.96589568540237556e-05 * YEAR, 63 | mass: 4.36624404335156298e-05 * SOLAR_MASS, 64 | }, 65 | // Neptune 66 | Planet { 67 | x: 1.53796971148509165e+01, 68 | y: -2.59193146099879641e+01, 69 | z: 1.79258772950371181e-01, 70 | vx: 2.68067772490389322e-03 * YEAR, 71 | vy: 1.62824170038242295e-03 * YEAR, 72 | vz: -9.51592254519715870e-05 * YEAR, 73 | mass: 5.15138902046611451e-05 * SOLAR_MASS, 74 | }, 75 | ]; 76 | 77 | #[derive(Clone, Copy)] 78 | struct Planet { 79 | x: f64, 80 | y: f64, 81 | z: f64, 82 | vx: f64, 83 | vy: f64, 84 | vz: f64, 85 | mass: f64, 86 | } 87 | 88 | fn advance(bodies: &mut [Planet; N_BODIES], dt: f64) { 89 | let mut b_slice: &mut [_] = bodies; 90 | loop { 91 | let bi = match shift_mut_ref(&mut b_slice) { 92 | Some(bi) => bi, 93 | None => break, 94 | }; 95 | 96 | for bj in b_slice.iter_mut() { 97 | let dx = bi.x - bj.x; 98 | let dy = bi.y - bj.y; 99 | let dz = bi.z - bj.z; 100 | 101 | let d2 = dx * dx + dy * dy + dz * dz; 102 | let mag = dt / (d2 * sqrt(d2)); 103 | 104 | let massj_mag = bj.mass * mag; 105 | bi.vx -= dx * massj_mag; 106 | bi.vy -= dy * massj_mag; 107 | bi.vz -= dz * massj_mag; 108 | 109 | let massi_mag = bi.mass * mag; 110 | bj.vx += dx * massi_mag; 111 | bj.vy += dy * massi_mag; 112 | bj.vz += dz * massi_mag; 113 | } 114 | bi.x += dt * bi.vx; 115 | bi.y += dt * bi.vy; 116 | bi.z += dt * bi.vz; 117 | } 118 | } 119 | 120 | fn energy(bodies: &[Planet; N_BODIES]) -> f64 { 121 | let mut e = 0.0; 122 | let mut bodies = bodies.iter(); 123 | 124 | loop { 125 | let bi = match bodies.next() { 126 | Some(bi) => bi, 127 | None => break, 128 | }; 129 | 130 | e += (bi.vx * bi.vx + bi.vy * bi.vy + bi.vz * bi.vz) * bi.mass / 2.0; 131 | for bj in bodies.clone() { 132 | let dx = bi.x - bj.x; 133 | let dy = bi.y - bj.y; 134 | let dz = bi.z - bj.z; 135 | let dist = sqrt(dx * dx + dy * dy + dz * dz); 136 | e -= bi.mass * bj.mass / dist; 137 | } 138 | } 139 | e 140 | } 141 | 142 | fn offset_momentum(bodies: &mut [Planet; N_BODIES]) { 143 | let mut px = 0.0; 144 | let mut py = 0.0; 145 | let mut pz = 0.0; 146 | for bi in bodies.iter() { 147 | px += bi.vx * bi.mass; 148 | py += bi.vy * bi.mass; 149 | pz += bi.vz * bi.mass; 150 | } 151 | let sun = &mut bodies[0]; 152 | sun.vx = -px / SOLAR_MASS; 153 | sun.vy = -py / SOLAR_MASS; 154 | sun.vz = -pz / SOLAR_MASS; 155 | } 156 | 157 | #[no_mangle] 158 | pub unsafe extern fn init() { 159 | offset_momentum(&mut BODIES); 160 | } 161 | 162 | #[no_mangle] 163 | pub unsafe extern fn step() -> f64 { 164 | advance(&mut BODIES, 0.01); 165 | energy(&BODIES) 166 | } 167 | 168 | #[no_mangle] 169 | pub unsafe extern fn bench(steps: i32) { 170 | for _ in 0..steps { 171 | advance(&mut BODIES, 0.01); 172 | } 173 | } 174 | 175 | /// Pop a mutable reference off the head of a slice, mutating the slice to no 176 | /// longer contain the mutable reference. 177 | fn shift_mut_ref<'a, T>(r: &mut &'a mut [T]) -> Option<&'a mut T> { 178 | if r.len() == 0 { 179 | return None; 180 | } 181 | let tmp = core::mem::replace(r, &mut []); 182 | let (h, t) = tmp.split_at_mut(1); 183 | *r = t; 184 | Some(&mut h[0]) 185 | } 186 | -------------------------------------------------------------------------------- /n-body/scripts/postprocess.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const path = require("path"); 3 | 4 | const filename = path.join(__dirname, "..", "build" , "index.js"); 5 | const source = fs.readFileSync(filename, { encoding: "utf8" }); 6 | 7 | function removeUnchecked(str) { 8 | return str 9 | .replace(/unchecked\((.*?)\)/g, (_, _1) => _1) 10 | .replace(/unchecked\((.*?)\)/g, (_, _1) => _1); 11 | } 12 | 13 | fs.writeFileSync(filename, removeUnchecked(source)); 14 | -------------------------------------------------------------------------------- /n-body/tests/index.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | 3 | // Load AssemblyScript version 4 | const nbodyAS = require("../assembly/index.js"); 5 | // Load Rust/wasm version 6 | let nbodyRS; 7 | try { nbodyRS = require("../rust/index.js"); } catch (e) {} 8 | 9 | // Load JS version 10 | const nbodyJS = require("../build/index.js"); 11 | 12 | function gcCollect() { 13 | if (global.gc) { 14 | global.gc(); 15 | global.gc(); 16 | } 17 | } 18 | 19 | function sleep(delay) { 20 | var start = Date.now(); 21 | while (Date.now() < start + delay); 22 | } 23 | 24 | function test(nbody, steps) { 25 | nbody.init(); 26 | var start = process.hrtime(); 27 | nbody.bench(steps); 28 | let t = process.hrtime(start); 29 | gcCollect(); 30 | return t; 31 | } 32 | 33 | const steps = process.argv.length > 2 34 | ? parseInt(process.argv[2], 10) 35 | : 20000000; 36 | 37 | function bench(name, fn) { 38 | console.log(`Performing ${steps} steps (${name}) ...`); 39 | const time = test(fn, steps); 40 | console.log(`Took ${(time[0] * 1e3 + time[1] / 1e6).toFixed(0)} ms`); 41 | } 42 | 43 | console.log("\nCOLD SERIES:\n"); 44 | 45 | bench("AssemblyScript WASM", nbodyAS); 46 | bench("JS", nbodyJS); 47 | if (nbodyRS) { 48 | bench("Rust WASM", nbodyRS); 49 | } 50 | 51 | console.log("\nWARMED UP SERIES:\n"); 52 | sleep(1000); 53 | 54 | bench("AssemblyScript WASM", nbodyAS); 55 | bench("JS", nbodyJS); 56 | if (nbodyRS) { 57 | bench("Rust WASM", nbodyRS); 58 | } 59 | -------------------------------------------------------------------------------- /parse/README.md: -------------------------------------------------------------------------------- 1 | WebAssembly Parser 2 | ================== 3 | 4 | An [AssemblyScript](http://assemblyscript.org) example. A WebAssembly binary parser in WebAssembly. Small, fast, with TypeScript support. 5 | 6 | API 7 | --- 8 | 9 | * **parse**(binary: `Uint8Array`, options?: `ParseOptions`): `void`
10 | Parses the contents of a WebAssembly binary according to the specified options. 11 | 12 | * **ParseOptions**
13 | Options specified to the parser. The `onSection` callback determines the sections being evaluated in detail. 14 | 15 | * **onSection**?(id: `SectionId`, payloadOff: `number`, payloadLen: `number`, nameOff: `number`, nameLen: `number`): `boolean`
16 | Called with each section in the binary. Returning `true` evaluates the section. 17 | 18 | * **onType**?(index: `number`, form: `number`): `void`
19 | Called with each function type if the type section is evaluated. 20 | 21 | * **onTypeParam**?(index: `number`, paramIndex: `number`, paramType: `Type`): `void`
22 | Called with each function parameter if the type section is evaluated. 23 | 24 | * **onTypeReturn**?(index: `number`, returnIndex: `number`, returnType: `Type`): `void`
25 | Called with each function return type if the type section is evaluated. 26 | 27 | * **onImport**?(index: `number`, kind: `ExternalKind`, moduleOff: `number`, moduleLen: `number`, fieldOff: `number`, fieldLen: `number`): `void`
28 | Called with each import if the import section is evaluated. 29 | 30 | * **onFunctionImport**?(index: `number`, type: `number`): `void`
31 | Called with each function import if the import section is evaluated. 32 | 33 | * **onTableImport**?(index: `number`, type: `Type`, initial: `number`, maximum: `number`, flags: `number`): `void`
34 | Called with each table import if the import section is evaluated. 35 | 36 | * **onMemoryImport**?(index: `number`, initial: `number`, maximum: `number`, flags: `number`): `void`
37 | Called with each memory import if the import section is evaluated. 38 | 39 | * **onGlobalImport**?(index: `number`, type: `Type`, mutability: `number`): `void`
40 | Called with each global import if the import section is evaluated. 41 | 42 | * **onMemory**?(index: `number`, initial: `number`, maximum: `number`, flags: `number`): `void`
43 | Called with each memory if the memory section is evaluated. 44 | 45 | * **onFunction**?(index: `number`, typeIndex: `number`): `void`
46 | Called with each function if the function section is evaluated. 47 | 48 | * **onGlobal**?(index: `number`, type: `Type`, mutability: `number`): `void`
49 | Called with each global if the global section is evaluated. 50 | 51 | * **onStart**?(index: `number`): `void`
52 | Called with the start function index if the start section is evaluated. 53 | 54 | * **onExport**?(index: `number`, kind: `ExternalKind`, kindIndex: `number`, nameOff: `number`, nameLen: `number`): `void`
55 | Called with each export if the export section is evaluated. 56 | 57 | * **onSourceMappingURL**?(offset: `number`, length: `number`): `void`
58 | Called with the source map URL if the 'sourceMappingURL' section is evaluated. 59 | 60 | * **onModuleName**?(offset: `number`, length: `number`): `void`
61 | Called with the module name if present and the 'name' section is evaluated. 62 | 63 | * **onFunctionName**?(index: `number`, offset: `number`, length: `number`): `void`
64 | Called with each function name if present and the 'name' section is evaluated. 65 | 66 | * **onLocalName**?(funcIndex: `number`, index: `number`, offset: `number`, length: `number`): `void`
67 | Called with each local name if present and the 'name' section is evaluated. 68 | 69 | * **Type**
70 | A value or element type, depending on context. 71 | 72 | | Name | Value 73 | |---------|------- 74 | | i32 | 0x7f 75 | | i64 | 0x7e 76 | | f32 | 0x7d 77 | | f64 | 0x7c 78 | | anyfunc | 0x70 79 | | func | 0x60 80 | | none | 0x40 81 | 82 | * **SectionId**
83 | Numerical id of the current section. 84 | 85 | | Name | Value 86 | |----------|------- 87 | | Custom | 0 88 | | Type | 1 89 | | Import | 2 90 | | Function | 3 91 | | Table | 4 92 | | Memory | 5 93 | | Global | 6 94 | | Export | 7 95 | | Start | 8 96 | | Element | 9 97 | | Code | 10 98 | | Data | 11 99 | 100 | * **ExternalKind**
101 | Kind of an export or import. 102 | 103 | | Name | Value 104 | |----------|------- 105 | | Function | 0 106 | | Table | 1 107 | | Memory | 2 108 | | Global | 3 109 | -------------------------------------------------------------------------------- /parse/assembly/index.ts: -------------------------------------------------------------------------------- 1 | /** A WebAssembly module that parses WebAssembly modules. */ 2 | 3 | // Common constants shared between AssemblyScript and TypeScript 4 | import { 5 | SectionId, 6 | ExternalKind, 7 | NameType, 8 | MAX_PAGES, 9 | MAX_ELEMS, 10 | Opcode 11 | } from "../src/common"; 12 | 13 | import * as opt from "./options"; 14 | 15 | /** Current offset in memory. */ 16 | var off: u32 = 0; 17 | 18 | /** Reads an unsigned integer from memory. */ 19 | function readUint(): u32 { 20 | var pos = off; 21 | var val = load(pos); 22 | off = pos + sizeof(); 23 | return val; 24 | } 25 | 26 | /** Reads an unsigned 64-bit integer from memory. */ 27 | function readUint64(): u64 { 28 | var pos = off; 29 | var val = load(pos); 30 | off = pos + 8; 31 | return val; 32 | } 33 | 34 | /** Reads a LEB128-encoded unsigned integer from memory. */ 35 | function readVaruint(size: u32): u32 { 36 | var val: u32 = 0; 37 | var shl: u32 = 0; 38 | var byt: u32; 39 | var pos = off; 40 | do { 41 | byt = load(pos++); 42 | val |= (byt & 0x7F) << shl; 43 | if (!(byt & 0x80)) break; 44 | shl += 7; 45 | } while (true); 46 | off = pos; 47 | return val; 48 | } 49 | 50 | /** Reads a LEB128-encoded signed integer from memory. */ 51 | function readVarint(size: u32): i32 { 52 | var val: u32 = 0; 53 | var shl: u32 = 0; 54 | var byt: u32; 55 | var pos = off; 56 | do { 57 | byt = load(pos++); 58 | val |= (byt & 0x7F) << shl; 59 | shl += 7; 60 | } while (byt & 0x80); 61 | off = pos; 62 | return select(val | (~0 << shl), val, shl < size && (byt & 0x40) != 0); 63 | } 64 | 65 | /** Reads a LEB128-encoded signed 64-bit integer from memory. */ 66 | function readVarint64(): i64 { 67 | var val: u64 = 0; 68 | var shl: u64 = 0; 69 | var byt: u64; 70 | var pos = off; 71 | do { 72 | byt = load(pos++); 73 | val |= (byt & 0x7F) << shl; 74 | shl += 7; 75 | } while (byt & 0x80); 76 | off = pos; 77 | return select(val | (~0 << shl), val, shl < 64 && (byt & 0x40) != 0); 78 | } 79 | 80 | function skipInitExpr(): void { 81 | var op = readUint(); 82 | switch (op) { 83 | case Opcode.i32_const: { 84 | readVarint(32); 85 | break; 86 | } 87 | case Opcode.i64_const: { 88 | readVarint64(); 89 | break; 90 | } 91 | case Opcode.f32_const: { 92 | readUint(); 93 | break; 94 | } 95 | case Opcode.f64_const: { 96 | readUint64(); 97 | break; 98 | } 99 | case Opcode.get_global: { 100 | readVaruint(32); 101 | break; 102 | } 103 | default: unreachable(); // MVP 104 | } 105 | if (readUint() != Opcode.end) unreachable(); 106 | } 107 | 108 | /** Starts parsing the module that has been placed in memory. */ 109 | export function parse(begin: u32, end: u32): void { 110 | off = begin; 111 | var magic = readUint(); 112 | if (magic != 0x6D736100) unreachable(); 113 | var version = readUint(); 114 | if (version != 1) unreachable(); 115 | var fun_space_index: u32 = 0; 116 | var glo_space_index: u32 = 0; 117 | var mem_space_index: u32 = 0; 118 | var tbl_space_index: u32 = 0; 119 | while (off < end) { 120 | // let section_off = off; 121 | let id = readVaruint(7); 122 | let payload_len = readVaruint(32); 123 | let name_off = 0; 124 | let name_len = 0; 125 | if (!id) { 126 | let before = off; 127 | name_len = readVaruint(32); 128 | name_off = off; 129 | off += name_len; 130 | payload_len -= off - before; 131 | } else if (id > SectionId.Data) unreachable(); 132 | let payload_off = off; 133 | if (opt.onSection( 134 | id, 135 | payload_off, 136 | payload_len, 137 | name_off, 138 | name_len 139 | )) { 140 | switch (id) { 141 | case SectionId.Type: { 142 | let count = readVaruint(32); 143 | for (let index: u32 = 0; index < count; ++index) { 144 | let form = readVarint(7) & 0x7f; 145 | opt.onType( 146 | index, 147 | form 148 | ); 149 | let paramCount = readVaruint(32); 150 | for (let paramIndex: u32 = 0; paramIndex < paramCount; ++paramIndex) { 151 | let paramType = readVarint(7) & 0x7f; 152 | opt.onTypeParam( 153 | index, 154 | paramIndex, 155 | paramType 156 | ); 157 | } 158 | let returnCount = readVaruint(1); // MVP 159 | for (let returnIndex: u32 = 0; returnIndex < returnCount; ++returnIndex) { 160 | let returnType = readVarint(7) & 0x7f; 161 | opt.onTypeReturn( 162 | index, 163 | returnIndex, 164 | returnType 165 | ); 166 | } 167 | } 168 | break; 169 | } 170 | case SectionId.Import: { 171 | let count = readVaruint(32); 172 | for (let index: u32 = 0; index < count; ++index) { 173 | let module_len = readVaruint(32); 174 | let module_off = off; 175 | off += module_len; 176 | let field_len = readVaruint(32); 177 | let field_off = off; 178 | off += field_len; 179 | let kind = readUint(); 180 | opt.onImport( 181 | index, 182 | kind, 183 | module_off, 184 | module_len, 185 | field_off, 186 | field_len 187 | ); 188 | switch (kind) { 189 | case ExternalKind.Function: { 190 | let type = readVaruint(32); 191 | opt.onFunctionImport( 192 | fun_space_index++, 193 | type 194 | ); 195 | break; 196 | } 197 | case ExternalKind.Table: { 198 | let type = readVarint(7) & 0x7f; 199 | let flags = readVaruint(1); 200 | let initial = readVaruint(32); 201 | let maximum = flags & 1 ? readVaruint(32) : MAX_ELEMS; 202 | opt.onTableImport( 203 | tbl_space_index++, 204 | type, 205 | initial, 206 | maximum, 207 | flags 208 | ); 209 | break; 210 | } 211 | case ExternalKind.Memory: { 212 | let flags = readVaruint(1); 213 | let initial = readVaruint(32); 214 | let maximum = flags & 1 ? readVaruint(32) : MAX_PAGES; 215 | opt.onMemoryImport( 216 | mem_space_index++, 217 | initial, 218 | maximum, 219 | flags 220 | ); 221 | break; 222 | } 223 | case ExternalKind.Global: { 224 | let type = readVarint(7) & 0x7f; 225 | let mutability = readVaruint(1); 226 | opt.onGlobalImport( 227 | glo_space_index++, 228 | type, 229 | mutability 230 | ); 231 | break; 232 | } 233 | default: unreachable(); 234 | } 235 | } 236 | break; 237 | } 238 | case SectionId.Function: { 239 | let count = readVaruint(32); 240 | for (let i: u32 = 0; i < count; ++i) { 241 | let typeIndex = readVaruint(32); 242 | opt.onFunction( 243 | fun_space_index++, 244 | typeIndex 245 | ); 246 | } 247 | break; 248 | } 249 | case SectionId.Table: { 250 | let count = readVaruint(32); 251 | for (let index: u32 = 0; index < count; ++index) { 252 | let type = readVaruint(7) & 0x7f; 253 | let flags = readVaruint(1); 254 | let initial = readVaruint(32); 255 | let maximum = flags & 1 ? readVaruint(32) : MAX_ELEMS; 256 | opt.onTable( 257 | tbl_space_index++, 258 | type, 259 | initial, 260 | maximum, 261 | flags 262 | ); 263 | } 264 | break; 265 | } 266 | case SectionId.Memory: { 267 | let count = readVaruint(32); 268 | for (let index: u32 = 0; index < count; ++index) { 269 | let flags = readVaruint(1); 270 | let initial = readVaruint(32); 271 | let maximum = flags & 1 ? readVaruint(32) : MAX_PAGES; 272 | opt.onMemory( 273 | mem_space_index++, 274 | initial, 275 | maximum, 276 | flags 277 | ); 278 | } 279 | break; 280 | } 281 | case SectionId.Global: { 282 | let count = readVaruint(32); 283 | for (let i: u32 = 0; i < count; ++i) { 284 | let type = readVarint(7) & 0x7f; 285 | let mutability = readVaruint(1); 286 | skipInitExpr(); 287 | opt.onGlobal( 288 | glo_space_index++, 289 | type, 290 | mutability 291 | ); 292 | } 293 | break; 294 | } 295 | case SectionId.Export: { 296 | let count = readVaruint(32); 297 | for (let index: u32 = 0; index < count; ++index) { 298 | let field_len = readVaruint(32); 299 | let field_off = off; 300 | off += field_len; 301 | let kind = readUint(); 302 | let kind_index = readVaruint(32); 303 | opt.onExport( 304 | index, 305 | kind, 306 | kind_index, 307 | field_off, 308 | field_len 309 | ); 310 | } 311 | break; 312 | } 313 | case SectionId.Start: { 314 | let index = readVaruint(32); 315 | opt.onStart( 316 | index 317 | ); 318 | break; 319 | } 320 | case SectionId.Custom: { 321 | if ( 322 | name_len == 4 && 323 | load(name_off) == 0x656D616E // "name" 324 | ) { 325 | let name_type = readVaruint(7); 326 | let name_payload_len = readVaruint(32); 327 | let name_payload_off = off; 328 | switch (name_type) { 329 | case NameType.Module: { 330 | let module_name_len = readVaruint(32); 331 | let module_name_off = off; 332 | opt.onModuleName( 333 | module_name_off, 334 | module_name_len 335 | ); 336 | break; 337 | } 338 | case NameType.Function: { 339 | let count = readVaruint(32); 340 | for (let i: u32 = 0; i < count; ++i) { 341 | let fn_index = readVaruint(32); 342 | let fn_name_len = readVaruint(32); 343 | let fn_name_off = off; 344 | off += fn_name_len; 345 | opt.onFunctionName( 346 | fn_index, 347 | fn_name_off, 348 | fn_name_len 349 | ); 350 | } 351 | break; 352 | } 353 | case NameType.Local: { 354 | let count = readVaruint(32); 355 | for (let i: u32 = 0; i < count; ++i) { 356 | let fn_index = readVaruint(32); 357 | let lc_count = readVaruint(32); 358 | for (let j: u32 = 0; j < lc_count; ++j) { 359 | let lc_index = readVaruint(32); 360 | let lc_name_len = readVaruint(32); 361 | let lc_name_off = off; 362 | off += lc_name_len; 363 | opt.onLocalName( 364 | fn_index, 365 | lc_index, 366 | lc_name_off, 367 | lc_name_len 368 | ); 369 | } 370 | } 371 | break; 372 | } 373 | default: unreachable(); 374 | } 375 | off = name_payload_off + name_payload_len; // ignore errors 376 | break; 377 | } else if ( 378 | name_len == 16 && 379 | load(name_off ) == 0x614D656372756F73 && // "sourceMa" 380 | load(name_off + 8) == 0x4C5255676E697070 // "ppingURL" 381 | ) { 382 | let url_len = readVaruint(32); 383 | let url_off = off; 384 | off += url_len; 385 | opt.onSourceMappingURL( 386 | url_off, 387 | url_len 388 | ); 389 | } 390 | off = payload_off + payload_len; // ignore errors 391 | break; 392 | } 393 | case SectionId.Element: 394 | case SectionId.Code: 395 | case SectionId.Data: { // skip 396 | off += payload_len; 397 | break; 398 | } 399 | default: unreachable(); 400 | } 401 | } else { // skip 402 | off += payload_len; 403 | } 404 | } 405 | if (off != end) unreachable(); 406 | } 407 | -------------------------------------------------------------------------------- /parse/assembly/options.ts: -------------------------------------------------------------------------------- 1 | // Imported callbacks 2 | export declare function onSection(id: u32, offset: u32, length: u32, nameOffset: u32, nameLength: u32): bool; 3 | export declare function onType(index: u32, form: u32): void; 4 | export declare function onTypeParam(index: u32, paramIndex: u32, paramType: u32): void; 5 | export declare function onTypeReturn(index: u32, returnIndex: u32, returnType: u32): void; 6 | export declare function onImport(index: u32, kind: u32, moduleOff: u32, moduleLen: u32, fieldOff: u32, fieldLen: u32): void; 7 | export declare function onFunctionImport(index: u32, type: u32): void; 8 | export declare function onTableImport(index: u32, type: u32, initial: u32, maximum: u32, flags: u32): void; 9 | export declare function onMemoryImport(index: u32, initial: u32, maximum: u32, flags: u32): void; 10 | export declare function onGlobalImport(index: u32, type: u32, mutability: u32): void; 11 | export declare function onMemory(index: u32, initial: u32, maximum: u32, flags: u32): void; 12 | export declare function onFunction(index: u32, typeIndex: u32): void; 13 | export declare function onTable(index: u32, type: u32, initial: u32, maximum: u32, flags: u32): void; 14 | export declare function onGlobal(index: u32, type: u32, mutability: u32): void; 15 | export declare function onExport(index: u32, kind: u32, kindIndex: u32, nameOffset: u32, nameLength: u32): void; 16 | export declare function onStart(index: u32): void; 17 | export declare function onSourceMappingURL(offset: u32, length: u32): void; 18 | export declare function onModuleName(offset: u32, length: u32): void; 19 | export declare function onFunctionName(index: u32, offset: u32, length: u32): void; 20 | export declare function onLocalName(funcIndex: u32, index: u32, offset: u32, length: u32): void; 21 | -------------------------------------------------------------------------------- /parse/assembly/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../node_modules/assemblyscript/std/assembly.json", 3 | "include": [ 4 | "./**/*.ts" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /parse/build/.gitignore: -------------------------------------------------------------------------------- 1 | *.wasm 2 | *.wasm.map 3 | -------------------------------------------------------------------------------- /parse/index.d.ts: -------------------------------------------------------------------------------- 1 | export * from "./src"; 2 | -------------------------------------------------------------------------------- /parse/index.js: -------------------------------------------------------------------------------- 1 | !function(A,I){"object"==typeof exports&&"object"==typeof module?module.exports=I():"function"==typeof define&&define.amd?define([],I):"object"==typeof exports?exports.asparse=I():A.asparse=I()}("undefined"!=typeof self?self:this,(function(){return(()=>{"use strict";var A={200:(A,I)=>{var C,Q,E,B,g;I.__esModule=!0,I.Opcode=I.MAX_ELEMS=I.MAX_PAGES=I.NameType=I.ExternalKind=I.SectionId=I.Type=void 0,(g=I.Type||(I.Type={}))[g.i32=127]="i32",g[g.i64=126]="i64",g[g.f32=125]="f32",g[g.f64=124]="f64",g[g.anyfunc=112]="anyfunc",g[g.func=96]="func",g[g.none=64]="none",(B=I.SectionId||(I.SectionId={}))[B.Custom=0]="Custom",B[B.Type=1]="Type",B[B.Import=2]="Import",B[B.Function=3]="Function",B[B.Table=4]="Table",B[B.Memory=5]="Memory",B[B.Global=6]="Global",B[B.Export=7]="Export",B[B.Start=8]="Start",B[B.Element=9]="Element",B[B.Code=10]="Code",B[B.Data=11]="Data",(E=I.ExternalKind||(I.ExternalKind={}))[E.Function=0]="Function",E[E.Table=1]="Table",E[E.Memory=2]="Memory",E[E.Global=3]="Global",(Q=I.NameType||(I.NameType={}))[Q.Module=0]="Module",Q[Q.Function=1]="Function",Q[Q.Local=2]="Local",I.MAX_PAGES=65535,I.MAX_ELEMS=4294967295,(C=I.Opcode||(I.Opcode={}))[C.end=11]="end",C[C.get_global=35]="get_global",C[C.i32_const=65]="i32_const",C[C.i64_const=66]="i64_const",C[C.f32_const=67]="f32_const",C[C.f64_const=68]="f64_const"}},I={};function C(Q){var E=I[Q];if(void 0!==E)return E.exports;var B=I[Q]={exports:{}};return A[Q](B,B.exports,C),B.exports}var Q={};return(()=>{var A=Q;A.__esModule=!0,A.parse=A.ExternalKind=A.SectionId=A.Type=void 0;var I=C(200);A.Type=I.Type,A.SectionId=I.SectionId,A.ExternalKind=I.ExternalKind;var E=null;A.parse=function A(I,C){C||(C={}),E||(E=new WebAssembly.Module(function(A){var I=A.length;if(I){for(var C=0,Q=I;--Q%4>1&&61===A.charCodeAt(Q);)++C;I=Math.ceil(3*I)/4-C}for(var E=new Uint8Array(I),g=0,i=0,h=0,o=0,n=A.length;o1)break;if(void 0===(c=B[c]))throw Error();switch(g){case 0:h=c,g=1;break;case 1:E[i++]=h<<2|(48&c)>>4,h=c,g=2;break;case 2:E[i++]=(15&h)<<4|(60&c)>>2,h=c,g=3;break;case 3:E[i++]=(3&h)<<6|c,g=0}}if(1===g)throw Error();return E}("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")));var Q=I.length,g=(Q+65535&-65536)>>16,i=new WebAssembly.Memory({initial:g}),h=new Uint8Array(i.buffer);h.set(I),A.readString=function(A,I){return function(A,I,C){if(C-I<1)return"";for(var Q=null,E=[],B=0,g=0;I191&&g<224?E[B++]=(31&g)<<6|63&A[I++]:g>239&&g<365?(g=((7&g)<<18|(63&A[I++])<<12|(63&A[I++])<<6|63&A[I++])-65536,E[B++]=55296+(g>>10),E[B++]=56320+(1023&g)):E[B++]=(15&g)<<12|(63&A[I++])<<6|63&A[I++],B>8191&&((Q||(Q=[])).push(String.fromCharCode.apply(String,E)),B=0);return Q?(B&&Q.push(String.fromCharCode.apply(String,E.slice(0,B))),Q.join("")):String.fromCharCode.apply(String,E.slice(0,B))}(h,A,A+I)};var o={env:{memory:i},options:{}};["onSection","onType","onTypeParam","onTypeReturn","onImport","onFunctionImport","onTableImport","onMemoryImport","onGlobalImport","onMemory","onFunction","onTable","onGlobal","onExport","onStart","onSourceMappingURL","onModuleName","onFunctionName","onLocalName"].forEach((function(A){return o.options[A]=C[A]||function(){}})),new WebAssembly.Instance(E,o).exports.parse(0,Q)};for(var B=new Array(123),g=0;g<64;)B[g<26?g+65:g<52?g+71:g<62?g-4:g-59|43]=g++})(),Q})()})); 2 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /parse/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","mappings":"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","sources":["webpack://asparse/webpack/universalModuleDefinition","webpack://asparse/./src/common.ts","webpack://asparse/webpack/bootstrap","webpack://asparse/./src/index.ts"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"asparse\"] = factory();\n\telse\n\t\troot[\"asparse\"] = factory();\n})(typeof self !== 'undefined' ? self : this, function() {\nreturn ","\"use strict\";\r\n/** Common constants shared between AssemblyScript and TypeScript. */\r\nexports.__esModule = true;\r\nexports.Opcode = exports.MAX_ELEMS = exports.MAX_PAGES = exports.NameType = exports.ExternalKind = exports.SectionId = exports.Type = void 0;\r\n/** WebAssembly types. */\r\nvar Type;\r\n(function (Type) {\r\n Type[Type[\"i32\"] = 127] = \"i32\";\r\n Type[Type[\"i64\"] = 126] = \"i64\";\r\n Type[Type[\"f32\"] = 125] = \"f32\";\r\n Type[Type[\"f64\"] = 124] = \"f64\";\r\n Type[Type[\"anyfunc\"] = 112] = \"anyfunc\";\r\n Type[Type[\"func\"] = 96] = \"func\";\r\n Type[Type[\"none\"] = 64] = \"none\";\r\n})(Type = exports.Type || (exports.Type = {}));\r\n/** WebAssembly section ids. */\r\nvar SectionId;\r\n(function (SectionId) {\r\n SectionId[SectionId[\"Custom\"] = 0] = \"Custom\";\r\n SectionId[SectionId[\"Type\"] = 1] = \"Type\";\r\n SectionId[SectionId[\"Import\"] = 2] = \"Import\";\r\n SectionId[SectionId[\"Function\"] = 3] = \"Function\";\r\n SectionId[SectionId[\"Table\"] = 4] = \"Table\";\r\n SectionId[SectionId[\"Memory\"] = 5] = \"Memory\";\r\n SectionId[SectionId[\"Global\"] = 6] = \"Global\";\r\n SectionId[SectionId[\"Export\"] = 7] = \"Export\";\r\n SectionId[SectionId[\"Start\"] = 8] = \"Start\";\r\n SectionId[SectionId[\"Element\"] = 9] = \"Element\";\r\n SectionId[SectionId[\"Code\"] = 10] = \"Code\";\r\n SectionId[SectionId[\"Data\"] = 11] = \"Data\";\r\n})(SectionId = exports.SectionId || (exports.SectionId = {}));\r\n/** WebAssembly external kinds. */\r\nvar ExternalKind;\r\n(function (ExternalKind) {\r\n ExternalKind[ExternalKind[\"Function\"] = 0] = \"Function\";\r\n ExternalKind[ExternalKind[\"Table\"] = 1] = \"Table\";\r\n ExternalKind[ExternalKind[\"Memory\"] = 2] = \"Memory\";\r\n ExternalKind[ExternalKind[\"Global\"] = 3] = \"Global\";\r\n})(ExternalKind = exports.ExternalKind || (exports.ExternalKind = {}));\r\n/** Name section types. */\r\nvar NameType;\r\n(function (NameType) {\r\n NameType[NameType[\"Module\"] = 0] = \"Module\";\r\n NameType[NameType[\"Function\"] = 1] = \"Function\";\r\n NameType[NameType[\"Local\"] = 2] = \"Local\";\r\n})(NameType = exports.NameType || (exports.NameType = {}));\r\n/** Maximum number of memory pages. */\r\nexports.MAX_PAGES = 0xffff;\r\n/** Maximum number of table elements. */\r\nexports.MAX_ELEMS = 0xffffffff;\r\n/** WebAssembly opcodes. */\r\nvar Opcode;\r\n(function (Opcode) {\r\n // unreachable = 0x00,\r\n // nop = 0x01,\r\n // block = 0x02,\r\n // loop = 0x03,\r\n // if_ = 0x04,\r\n // else_ = 0x05,\r\n Opcode[Opcode[\"end\"] = 11] = \"end\";\r\n // br = 0x0c,\r\n // br_if = 0x0d,\r\n // br_table = 0x0e,\r\n // return_ = 0x0f,\r\n // call = 0x10,\r\n // call_indirect = 0x11,\r\n // drop = 0x1a,\r\n // select = 0x1b,\r\n // get_local = 0x20,\r\n // set_local = 0x21,\r\n // tee_local = 0x22,\r\n Opcode[Opcode[\"get_global\"] = 35] = \"get_global\";\r\n // set_global = 0x24,\r\n // i32_load = 0x28,\r\n // i64_load = 0x29,\r\n // f32_load = 0x2a,\r\n // f64_load = 0x2b,\r\n // i32_load8_s = 0x2c,\r\n // i32_load8_u = 0x2d,\r\n // i32_load16_s = 0x2e,\r\n // i32_load16_u = 0x2f,\r\n // i64_load8_s = 0x30,\r\n // i64_load8_u = 0x31,\r\n // i64_load16_s = 0x32,\r\n // i64_load16_u = 0x33,\r\n // i64_load32_s = 0x34,\r\n // i64_load32_u = 0x35,\r\n // i32_store = 0x36,\r\n // i64_store = 0x37,\r\n // f32_store = 0x38,\r\n // f64_store = 0x39,\r\n // i32_store8 = 0x3a,\r\n // i32_store16 = 0x3b,\r\n // i64_store8 = 0x3c,\r\n // i64_store16 = 0x3d,\r\n // i64_store32 = 0x3e,\r\n // current_memory = 0x3f,\r\n // grow_memory = 0x40,\r\n Opcode[Opcode[\"i32_const\"] = 65] = \"i32_const\";\r\n Opcode[Opcode[\"i64_const\"] = 66] = \"i64_const\";\r\n Opcode[Opcode[\"f32_const\"] = 67] = \"f32_const\";\r\n Opcode[Opcode[\"f64_const\"] = 68] = \"f64_const\";\r\n // i32_eqz = 0x45,\r\n // i32_eq = 0x46,\r\n // i32_ne = 0x47,\r\n // i32_lt_s = 0x48,\r\n // i32_lt_u = 0x49,\r\n // i32_gt_s = 0x4a,\r\n // i32_gt_u = 0x4b,\r\n // i32_le_s = 0x4c,\r\n // i32_le_u = 0x4d,\r\n // i32_ge_s = 0x4e,\r\n // i32_ge_u = 0x4f,\r\n // i64_eqz = 0x50,\r\n // i64_eq = 0x51,\r\n // i64_ne = 0x52,\r\n // i64_lt_s = 0x53,\r\n // i64_lt_u = 0x54,\r\n // i64_gt_s = 0x55,\r\n // i64_gt_u = 0x56,\r\n // i64_le_s = 0x57,\r\n // i64_le_u = 0x58,\r\n // i64_ge_s = 0x59,\r\n // i64_ge_u = 0x5a,\r\n // f32_eq = 0x5b,\r\n // f32_ne = 0x5c,\r\n // f32_lt = 0x5d,\r\n // f32_gt = 0x5e,\r\n // f32_le = 0x5f,\r\n // f32_ge = 0x60,\r\n // f64_eq = 0x61,\r\n // f64_ne = 0x62,\r\n // f64_lt = 0x63,\r\n // f64_gt = 0x64,\r\n // f64_le = 0x65,\r\n // f64_ge = 0x66,\r\n // i32_clz = 0x67,\r\n // i32_ctz = 0x68,\r\n // i32_popcnt = 0x69,\r\n // i32_add = 0x6a,\r\n // i32_sub = 0x6b,\r\n // i32_mul = 0x6c,\r\n // i32_div_s = 0x6d,\r\n // i32_div_u = 0x6e,\r\n // i32_rem_s = 0x6f,\r\n // i32_rem_u = 0x70,\r\n // i32_and = 0x71,\r\n // i32_or = 0x72,\r\n // i32_xor = 0x73,\r\n // i32_shl = 0x74,\r\n // i32_shr_s = 0x75,\r\n // i32_shr_u = 0x76,\r\n // i32_rotl = 0x77,\r\n // i32_rotr = 0x78,\r\n // i64_clz = 0x79,\r\n // i64_ctz = 0x7a,\r\n // i64_popcnt = 0x7b,\r\n // i64_add = 0x7c,\r\n // i64_sub = 0x7d,\r\n // i64_mul = 0x7e,\r\n // i64_div_s = 0x7f,\r\n // i64_div_u = 0x80,\r\n // i64_rem_s = 0x81,\r\n // i64_rem_u = 0x82,\r\n // i64_and = 0x83,\r\n // i64_or = 0x84,\r\n // i64_xor = 0x85,\r\n // i64_shl = 0x86,\r\n // i64_shr_s = 0x87,\r\n // i64_shr_u = 0x88,\r\n // i64_rotl = 0x89,\r\n // i64_rotr = 0x8a,\r\n // f32_abs = 0x8b,\r\n // f32_neg = 0x8c,\r\n // f32_ceil = 0x8d,\r\n // f32_floor = 0x8e,\r\n // f32_trunc = 0x8f,\r\n // f32_nearest = 0x90,\r\n // f32_sqrt = 0x91,\r\n // f32_add = 0x92,\r\n // f32_sub = 0x93,\r\n // f32_mul = 0x94,\r\n // f32_div = 0x95,\r\n // f32_min = 0x96,\r\n // f32_max = 0x97,\r\n // f32_copysign = 0x98,\r\n // f64_abs = 0x99,\r\n // f64_neg = 0x9a,\r\n // f64_ceil = 0x9b,\r\n // f64_floor = 0x9c,\r\n // f64_trunc = 0x9d,\r\n // f64_nearest = 0x9e,\r\n // f64_sqrt = 0x9f,\r\n // f64_add = 0xa0,\r\n // f64_sub = 0xa1,\r\n // f64_mul = 0xa2,\r\n // f64_div = 0xa3,\r\n // f64_min = 0xa4,\r\n // f64_max = 0xa5,\r\n // f64_copysign = 0xa6,\r\n // i32_wrap_i64 = 0xa7,\r\n // i32_trunc_s_f32 = 0xa8,\r\n // i32_trunc_u_f32 = 0xa9,\r\n // i32_trunc_s_f64 = 0xaa,\r\n // i32_trunc_u_f64 = 0xab,\r\n // i64_extend_s_i32 = 0xac,\r\n // i64_extend_u_i32 = 0xad,\r\n // i64_trunc_s_f32 = 0xae,\r\n // i64_trunc_u_f32 = 0xaf,\r\n // i64_trunc_s_f64 = 0xb0,\r\n // i64_trunc_u_f64 = 0xb1,\r\n // f32_convert_s_i32 = 0xb2,\r\n // f32_convert_u_i32 = 0xb3,\r\n // f32_convert_s_i64 = 0xb4,\r\n // f32_convert_u_i64 = 0xb5,\r\n // f32_demote_f64 = 0xb6,\r\n // f64_convert_s_i32 = 0xb7,\r\n // f64_convert_u_i32 = 0xb8,\r\n // f64_convert_s_i64 = 0xb9,\r\n // f64_convert_u_i64 = 0xba,\r\n // f64_promote_f32 = 0xbb,\r\n // i32_reinterpret_f32 = 0xbc,\r\n // i64_reinterpret_f64 = 0xbd,\r\n // f32_reinterpret_i32 = 0xbe,\r\n // f64_reinterpret_i64 = 0xbf\r\n})(Opcode = exports.Opcode || (exports.Opcode = {}));\r\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","\"use strict\";\r\nexports.__esModule = true;\r\nexports.parse = exports.ExternalKind = exports.SectionId = exports.Type = void 0;\r\nvar common_1 = require(\"./common\");\r\nexports.Type = common_1.Type;\r\nexports.SectionId = common_1.SectionId;\r\nexports.ExternalKind = common_1.ExternalKind;\r\n/** Cached compiled parser. */\r\nvar compiled = null;\r\nif (typeof WASM_DATA !== \"string\") {\r\n // eslint-disable-next-line @typescript-eslint/no-var-requires\r\n WASM_DATA = require(\"fs\").readFileSync(__dirname + \"/../build/index.wasm\", \"base64\");\r\n}\r\n/** Parses the contents of a WebAssembly binary according to the specified options. */\r\nfunction parse(binary, options) {\r\n if (!options)\r\n options = {};\r\n // compile the parser if not yet compiled\r\n if (!compiled)\r\n compiled = new WebAssembly.Module(base64_decode(WASM_DATA));\r\n // use the binary as the parser's memory\r\n var nBytes = binary.length;\r\n var nPages = ((nBytes + 0xffff) & ~0xffff) >> 16;\r\n var memory = new WebAssembly.Memory({ initial: nPages });\r\n var buffer = new Uint8Array(memory.buffer);\r\n buffer.set(binary);\r\n // provide a way to read strings from memory\r\n parse.readString = function (offset, length) { return utf8_read(buffer, offset, offset + length); };\r\n // instantiate the parser and return its exports\r\n var imports = {\r\n env: {\r\n memory: memory\r\n },\r\n options: {}\r\n };\r\n [\"onSection\",\r\n \"onType\",\r\n \"onTypeParam\",\r\n \"onTypeReturn\",\r\n \"onImport\",\r\n \"onFunctionImport\",\r\n \"onTableImport\",\r\n \"onMemoryImport\",\r\n \"onGlobalImport\",\r\n \"onMemory\",\r\n \"onFunction\",\r\n \"onTable\",\r\n \"onGlobal\",\r\n \"onExport\",\r\n \"onStart\",\r\n \"onSourceMappingURL\",\r\n \"onModuleName\",\r\n \"onFunctionName\",\r\n \"onLocalName\"\r\n ].forEach(function (name) { return imports.options[name] = options[name] || function () { }; });\r\n var instance = new WebAssembly.Instance(compiled, imports);\r\n instance.exports.parse(0, nBytes); // ?\r\n}\r\nexports.parse = parse;\r\n// see: https://github.com/dcodeIO/protobuf.js/tree/master/lib/utf8\r\nfunction utf8_read(buffer, start, end) {\r\n var len = end - start;\r\n if (len < 1)\r\n return \"\";\r\n var parts = null, chunk = [];\r\n var i = 0, t = 0; // char offset and temporary\r\n while (start < end) {\r\n t = buffer[start++];\r\n if (t < 128) {\r\n chunk[i++] = t;\r\n }\r\n else if (t > 191 && t < 224) {\r\n chunk[i++] = (t & 31) << 6 | buffer[start++] & 63;\r\n }\r\n else if (t > 239 && t < 365) {\r\n t = ((t & 7) << 18 | (buffer[start++] & 63) << 12 | (buffer[start++] & 63) << 6 | buffer[start++] & 63) - 0x10000;\r\n chunk[i++] = 0xD800 + (t >> 10);\r\n chunk[i++] = 0xDC00 + (t & 1023);\r\n }\r\n else {\r\n chunk[i++] = (t & 15) << 12 | (buffer[start++] & 63) << 6 | buffer[start++] & 63;\r\n }\r\n if (i > 8191) {\r\n (parts || (parts = [])).push(String.fromCharCode.apply(String, chunk));\r\n i = 0;\r\n }\r\n }\r\n if (parts) {\r\n if (i)\r\n parts.push(String.fromCharCode.apply(String, chunk.slice(0, i)));\r\n return parts.join(\"\");\r\n }\r\n return String.fromCharCode.apply(String, chunk.slice(0, i));\r\n}\r\n// see: https://github.com/dcodeIO/protobuf.js/tree/master/lib/base64\r\nfunction base64_decode(string) {\r\n var length = string.length;\r\n if (length) {\r\n var n = 0, p = length;\r\n while (--p % 4 > 1 && string.charCodeAt(p) === 61)\r\n ++n;\r\n length = Math.ceil(length * 3) / 4 - n;\r\n }\r\n var buffer = new Uint8Array(length);\r\n var j = 0, o = 0, t = 0;\r\n for (var i = 0, k = string.length; i < k;) {\r\n var c = string.charCodeAt(i++);\r\n if (c === 61 && j > 1)\r\n break;\r\n if ((c = s64[c]) === undefined)\r\n throw Error();\r\n switch (j) {\r\n case 0: {\r\n t = c;\r\n j = 1;\r\n break;\r\n }\r\n case 1: {\r\n buffer[o++] = t << 2 | (c & 48) >> 4;\r\n t = c;\r\n j = 2;\r\n break;\r\n }\r\n case 2: {\r\n buffer[o++] = (t & 15) << 4 | (c & 60) >> 2;\r\n t = c;\r\n j = 3;\r\n break;\r\n }\r\n case 3: {\r\n buffer[o++] = (t & 3) << 6 | c;\r\n j = 0;\r\n break;\r\n }\r\n }\r\n }\r\n if (j === 1)\r\n throw Error();\r\n return buffer;\r\n}\r\nvar s64 = new Array(123);\r\nfor (var i = 0; i < 64;)\r\n s64[i < 26 ? i + 65 : i < 52 ? i + 71 : i < 62 ? i - 4 : i - 59 | 43] = i++;\r\n"],"names":["root","factory","exports","module","define","amd","self","this","Opcode","NameType","ExternalKind","SectionId","Type","__esModule","MAX_ELEMS","MAX_PAGES","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","__webpack_modules__","parse","common_1","compiled","binary","options","WebAssembly","Module","string","length","n","p","charCodeAt","Math","ceil","buffer","Uint8Array","j","o","t","i","k","c","s64","Error","base64_decode","nBytes","nPages","memory","Memory","initial","set","readString","offset","start","end","parts","chunk","push","String","fromCharCode","apply","slice","join","utf8_read","imports","env","forEach","name","Instance","Array"],"sourceRoot":""} -------------------------------------------------------------------------------- /parse/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@assemblyscript/parse-example", 3 | "version": "1.0.0", 4 | "license": "Apache-2.0", 5 | "private": true, 6 | "main": "index.js", 7 | "types": "index.d.ts", 8 | "scripts": { 9 | "asbuild": "asc assembly/index.ts -O3 -o build/index.wasm -t build/index.wat --importMemory --runtime stub --sourceMap", 10 | "build": "npm run asbuild && webpack --mode production", 11 | "test": "ts-node tests/" 12 | }, 13 | "devDependencies": { 14 | "assemblyscript": "latest", 15 | "ts-loader": "^5.2.1", 16 | "ts-node": "^6.2.0", 17 | "typescript": "^4.5.2", 18 | "webpack": "^5.64.4", 19 | "webpack-cli": "^4.9.1" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /parse/src/common.ts: -------------------------------------------------------------------------------- 1 | /** Common constants shared between AssemblyScript and TypeScript. */ 2 | 3 | /** WebAssembly types. */ 4 | export enum Type { 5 | i32 = 0x7f, 6 | i64 = 0x7e, 7 | f32 = 0x7d, 8 | f64 = 0x7c, 9 | anyfunc = 0x70, 10 | func = 0x60, 11 | none = 0x40 12 | } 13 | 14 | /** WebAssembly section ids. */ 15 | export enum SectionId { 16 | Custom = 0, 17 | Type = 1, 18 | Import = 2, 19 | Function = 3, 20 | Table = 4, 21 | Memory = 5, 22 | Global = 6, 23 | Export = 7, 24 | Start = 8, 25 | Element = 9, 26 | Code = 10, 27 | Data = 11 28 | } 29 | 30 | /** WebAssembly external kinds. */ 31 | export enum ExternalKind { 32 | Function = 0, 33 | Table = 1, 34 | Memory = 2, 35 | Global = 3 36 | } 37 | 38 | /** Name section types. */ 39 | export enum NameType { 40 | Module = 0, 41 | Function = 1, 42 | Local = 2 43 | } 44 | 45 | /** Maximum number of memory pages. */ 46 | export const MAX_PAGES = 0xffff; 47 | 48 | /** Maximum number of table elements. */ 49 | export const MAX_ELEMS = 0xffffffff; 50 | 51 | /** WebAssembly opcodes. */ 52 | export enum Opcode { // just a few of these are actually used 53 | // unreachable = 0x00, 54 | // nop = 0x01, 55 | // block = 0x02, 56 | // loop = 0x03, 57 | // if_ = 0x04, 58 | // else_ = 0x05, 59 | end = 0x0b, 60 | // br = 0x0c, 61 | // br_if = 0x0d, 62 | // br_table = 0x0e, 63 | // return_ = 0x0f, 64 | // call = 0x10, 65 | // call_indirect = 0x11, 66 | // drop = 0x1a, 67 | // select = 0x1b, 68 | // get_local = 0x20, 69 | // set_local = 0x21, 70 | // tee_local = 0x22, 71 | get_global = 0x23, 72 | // set_global = 0x24, 73 | // i32_load = 0x28, 74 | // i64_load = 0x29, 75 | // f32_load = 0x2a, 76 | // f64_load = 0x2b, 77 | // i32_load8_s = 0x2c, 78 | // i32_load8_u = 0x2d, 79 | // i32_load16_s = 0x2e, 80 | // i32_load16_u = 0x2f, 81 | // i64_load8_s = 0x30, 82 | // i64_load8_u = 0x31, 83 | // i64_load16_s = 0x32, 84 | // i64_load16_u = 0x33, 85 | // i64_load32_s = 0x34, 86 | // i64_load32_u = 0x35, 87 | // i32_store = 0x36, 88 | // i64_store = 0x37, 89 | // f32_store = 0x38, 90 | // f64_store = 0x39, 91 | // i32_store8 = 0x3a, 92 | // i32_store16 = 0x3b, 93 | // i64_store8 = 0x3c, 94 | // i64_store16 = 0x3d, 95 | // i64_store32 = 0x3e, 96 | // current_memory = 0x3f, 97 | // grow_memory = 0x40, 98 | i32_const = 0x41, 99 | i64_const = 0x42, 100 | f32_const = 0x43, 101 | f64_const = 0x44 102 | // i32_eqz = 0x45, 103 | // i32_eq = 0x46, 104 | // i32_ne = 0x47, 105 | // i32_lt_s = 0x48, 106 | // i32_lt_u = 0x49, 107 | // i32_gt_s = 0x4a, 108 | // i32_gt_u = 0x4b, 109 | // i32_le_s = 0x4c, 110 | // i32_le_u = 0x4d, 111 | // i32_ge_s = 0x4e, 112 | // i32_ge_u = 0x4f, 113 | // i64_eqz = 0x50, 114 | // i64_eq = 0x51, 115 | // i64_ne = 0x52, 116 | // i64_lt_s = 0x53, 117 | // i64_lt_u = 0x54, 118 | // i64_gt_s = 0x55, 119 | // i64_gt_u = 0x56, 120 | // i64_le_s = 0x57, 121 | // i64_le_u = 0x58, 122 | // i64_ge_s = 0x59, 123 | // i64_ge_u = 0x5a, 124 | // f32_eq = 0x5b, 125 | // f32_ne = 0x5c, 126 | // f32_lt = 0x5d, 127 | // f32_gt = 0x5e, 128 | // f32_le = 0x5f, 129 | // f32_ge = 0x60, 130 | // f64_eq = 0x61, 131 | // f64_ne = 0x62, 132 | // f64_lt = 0x63, 133 | // f64_gt = 0x64, 134 | // f64_le = 0x65, 135 | // f64_ge = 0x66, 136 | // i32_clz = 0x67, 137 | // i32_ctz = 0x68, 138 | // i32_popcnt = 0x69, 139 | // i32_add = 0x6a, 140 | // i32_sub = 0x6b, 141 | // i32_mul = 0x6c, 142 | // i32_div_s = 0x6d, 143 | // i32_div_u = 0x6e, 144 | // i32_rem_s = 0x6f, 145 | // i32_rem_u = 0x70, 146 | // i32_and = 0x71, 147 | // i32_or = 0x72, 148 | // i32_xor = 0x73, 149 | // i32_shl = 0x74, 150 | // i32_shr_s = 0x75, 151 | // i32_shr_u = 0x76, 152 | // i32_rotl = 0x77, 153 | // i32_rotr = 0x78, 154 | // i64_clz = 0x79, 155 | // i64_ctz = 0x7a, 156 | // i64_popcnt = 0x7b, 157 | // i64_add = 0x7c, 158 | // i64_sub = 0x7d, 159 | // i64_mul = 0x7e, 160 | // i64_div_s = 0x7f, 161 | // i64_div_u = 0x80, 162 | // i64_rem_s = 0x81, 163 | // i64_rem_u = 0x82, 164 | // i64_and = 0x83, 165 | // i64_or = 0x84, 166 | // i64_xor = 0x85, 167 | // i64_shl = 0x86, 168 | // i64_shr_s = 0x87, 169 | // i64_shr_u = 0x88, 170 | // i64_rotl = 0x89, 171 | // i64_rotr = 0x8a, 172 | // f32_abs = 0x8b, 173 | // f32_neg = 0x8c, 174 | // f32_ceil = 0x8d, 175 | // f32_floor = 0x8e, 176 | // f32_trunc = 0x8f, 177 | // f32_nearest = 0x90, 178 | // f32_sqrt = 0x91, 179 | // f32_add = 0x92, 180 | // f32_sub = 0x93, 181 | // f32_mul = 0x94, 182 | // f32_div = 0x95, 183 | // f32_min = 0x96, 184 | // f32_max = 0x97, 185 | // f32_copysign = 0x98, 186 | // f64_abs = 0x99, 187 | // f64_neg = 0x9a, 188 | // f64_ceil = 0x9b, 189 | // f64_floor = 0x9c, 190 | // f64_trunc = 0x9d, 191 | // f64_nearest = 0x9e, 192 | // f64_sqrt = 0x9f, 193 | // f64_add = 0xa0, 194 | // f64_sub = 0xa1, 195 | // f64_mul = 0xa2, 196 | // f64_div = 0xa3, 197 | // f64_min = 0xa4, 198 | // f64_max = 0xa5, 199 | // f64_copysign = 0xa6, 200 | // i32_wrap_i64 = 0xa7, 201 | // i32_trunc_s_f32 = 0xa8, 202 | // i32_trunc_u_f32 = 0xa9, 203 | // i32_trunc_s_f64 = 0xaa, 204 | // i32_trunc_u_f64 = 0xab, 205 | // i64_extend_s_i32 = 0xac, 206 | // i64_extend_u_i32 = 0xad, 207 | // i64_trunc_s_f32 = 0xae, 208 | // i64_trunc_u_f32 = 0xaf, 209 | // i64_trunc_s_f64 = 0xb0, 210 | // i64_trunc_u_f64 = 0xb1, 211 | // f32_convert_s_i32 = 0xb2, 212 | // f32_convert_u_i32 = 0xb3, 213 | // f32_convert_s_i64 = 0xb4, 214 | // f32_convert_u_i64 = 0xb5, 215 | // f32_demote_f64 = 0xb6, 216 | // f64_convert_s_i32 = 0xb7, 217 | // f64_convert_u_i32 = 0xb8, 218 | // f64_convert_s_i64 = 0xb9, 219 | // f64_convert_u_i64 = 0xba, 220 | // f64_promote_f32 = 0xbb, 221 | // i32_reinterpret_f32 = 0xbc, 222 | // i64_reinterpret_f64 = 0xbd, 223 | // f32_reinterpret_i32 = 0xbe, 224 | // f64_reinterpret_i64 = 0xbf 225 | } 226 | -------------------------------------------------------------------------------- /parse/src/index.ts: -------------------------------------------------------------------------------- 1 | import { Type, SectionId, ExternalKind } from "./common"; 2 | export { Type, SectionId, ExternalKind }; 3 | 4 | /** Cached compiled parser. */ 5 | var compiled: WebAssembly.Module | null = null; 6 | 7 | declare var WASM_DATA: string; // injected by webpack 8 | if (typeof WASM_DATA !== "string") { 9 | // eslint-disable-next-line @typescript-eslint/no-var-requires 10 | WASM_DATA = require("fs").readFileSync(__dirname + "/../build/index.wasm", "base64"); 11 | } 12 | 13 | /** Options specified to the parser. The `onSection` callback determines the sections being evaluated in detail. */ 14 | export interface ParseOptions { 15 | /** Called with each section in the binary. Returning `true` evaluates the section. */ 16 | onSection?(id: SectionId, payloadOff: number, payloadLen: number, nameOff: number, nameLen: number): boolean; 17 | /** Called with each function type if the type section is evaluated. */ 18 | onType?(index: number, form: number): void; 19 | /** Called with each function parameter if the type section is evaluated. */ 20 | onTypeParam?(index: number, paramIndex: number, paramType: Type): void; 21 | /** Called with each function return type if the type section is evaluated. */ 22 | onTypeReturn?(index: number, returnIndex: number, returnType: Type): void; 23 | /** Called with each import if the import section is evaluated. */ 24 | onImport?(index: number, kind: ExternalKind, moduleOff: number, moduleLen: number, fieldOff: number, fieldLen: number): void; 25 | /** Called with each function import if the import section is evaluated. */ 26 | onFunctionImport?(index: number, type: number): void; 27 | /** Called with each table import if the import section is evaluated. */ 28 | onTableImport?(index: number, type: Type, initial: number, maximum: number, flags: number): void; 29 | /** Called with each memory import if the import section is evaluated. */ 30 | onMemoryImport?(index: number, initial: number, maximum: number, flags: number): void; 31 | /** Called with each global import if the import section is evaluated. */ 32 | onGlobalImport?(index: number, type: Type, mutability: number): void; 33 | /** Called with each memory if the memory section is evaluated.*/ 34 | onMemory?(index: number, initial: number, maximum: number, flags: number): void; 35 | /** Called with each function if the function section is evaluated. */ 36 | onFunction?(index: number, typeIndex: number): void; 37 | /** Called with each table if the table section is evaluated.*/ 38 | onTable?(index: number, type: Type, initial: number, maximum: number, flags: number): void; 39 | /** Called with each global if the global section is evaluated. */ 40 | onGlobal?(index: number, type: Type, mutability: number): void; 41 | /** Called with the start function index if the start section is evaluated. */ 42 | onStart?(index: number): void; 43 | /** Called with each export if the export section is evaluated. */ 44 | onExport?(index: number, kind: ExternalKind, kindIndex: number, nameOff: number, nameLen: number): void; 45 | /** Called with the source map URL if the 'sourceMappingURL' section is evaluated. */ 46 | onSourceMappingURL?(offset: number, length: number): void; 47 | /** Called with the module name if present and the 'name' section is evaluated. */ 48 | onModuleName?(offset: number, length: number): void; 49 | /** Called with each function name if present and the 'name' section is evaluated. */ 50 | onFunctionName?(index: number, offset: number, length: number): void; 51 | /** Called with each local name if present and the 'name' section is evaluated. */ 52 | onLocalName?(funcIndex: number, index: number, offset: number, length: number): void; 53 | } 54 | 55 | /** Parses the contents of a WebAssembly binary according to the specified options. */ 56 | export function parse(binary: Uint8Array, options?: ParseOptions): void { 57 | if (!options) options = {}; 58 | 59 | // compile the parser if not yet compiled 60 | if (!compiled) compiled = new WebAssembly.Module(base64_decode(WASM_DATA)); 61 | 62 | // use the binary as the parser's memory 63 | var nBytes = binary.length; 64 | var nPages = ((nBytes + 0xffff) & ~0xffff) >> 16; 65 | var memory = new WebAssembly.Memory({ initial: nPages }); 66 | var buffer = new Uint8Array(memory.buffer); 67 | buffer.set(binary); 68 | 69 | // provide a way to read strings from memory 70 | parse.readString = (offset: number, length: number): string => utf8_read(buffer, offset, offset + length); 71 | 72 | // instantiate the parser and return its exports 73 | var imports = { 74 | env: { 75 | memory 76 | }, 77 | options: {} 78 | }; 79 | [ "onSection", 80 | "onType", 81 | "onTypeParam", 82 | "onTypeReturn", 83 | "onImport", 84 | "onFunctionImport", 85 | "onTableImport", 86 | "onMemoryImport", 87 | "onGlobalImport", 88 | "onMemory", 89 | "onFunction", 90 | "onTable", 91 | "onGlobal", 92 | "onExport", 93 | "onStart", 94 | "onSourceMappingURL", 95 | "onModuleName", 96 | "onFunctionName", 97 | "onLocalName" 98 | ].forEach((name: string) => imports.options[name] = options[name] || function() { /* nop */ }); 99 | var instance = new WebAssembly.Instance(compiled, imports); 100 | (instance.exports).parse(0, nBytes); // ? 101 | } 102 | 103 | export declare namespace parse { 104 | /** Utility function for reading an UTF8 encoded string from memory while parsing. */ 105 | function readString(offset: number, length: number): string; 106 | } 107 | 108 | // see: https://github.com/dcodeIO/protobuf.js/tree/master/lib/utf8 109 | function utf8_read(buffer: Uint8Array, start: number, end: number): string { 110 | var len = end - start; 111 | if (len < 1) return ""; 112 | var parts: string[] | null = null, chunk: number[] = []; 113 | var i = 0, t = 0; // char offset and temporary 114 | while (start < end) { 115 | t = buffer[start++]; 116 | if (t < 128) { 117 | chunk[i++] = t; 118 | } else if (t > 191 && t < 224) { 119 | chunk[i++] = (t & 31) << 6 | buffer[start++] & 63; 120 | } else if (t > 239 && t < 365) { 121 | t = ((t & 7) << 18 | (buffer[start++] & 63) << 12 | (buffer[start++] & 63) << 6 | buffer[start++] & 63) - 0x10000; 122 | chunk[i++] = 0xD800 + (t >> 10); 123 | chunk[i++] = 0xDC00 + (t & 1023); 124 | } else { 125 | chunk[i++] = (t & 15) << 12 | (buffer[start++] & 63) << 6 | buffer[start++] & 63; 126 | } 127 | if (i > 8191) { 128 | (parts || (parts = [])).push(String.fromCharCode(...chunk)); 129 | i = 0; 130 | } 131 | } 132 | if (parts) { 133 | if (i) parts.push(String.fromCharCode(...chunk.slice(0, i))); 134 | return parts.join(""); 135 | } 136 | return String.fromCharCode(...chunk.slice(0, i)); 137 | } 138 | 139 | // see: https://github.com/dcodeIO/protobuf.js/tree/master/lib/base64 140 | function base64_decode(string: string): Uint8Array { 141 | var length = string.length; 142 | if (length) { 143 | let n = 0, p = length; 144 | while (--p % 4 > 1 && string.charCodeAt(p) === 61) ++n; 145 | length = Math.ceil(length * 3) / 4 - n; 146 | } 147 | var buffer = new Uint8Array(length); 148 | var j = 0, o = 0, t = 0; 149 | for (let i = 0, k = string.length; i < k;) { 150 | let c = string.charCodeAt(i++); 151 | if (c === 61 && j > 1) break; 152 | if ((c = s64[c]) === undefined) throw Error(); 153 | switch (j) { 154 | case 0: { t = c; j = 1; break; } 155 | case 1: { buffer[o++] = t << 2 | (c & 48) >> 4; t = c; j = 2; break; } 156 | case 2: { buffer[o++] = (t & 15) << 4 | (c & 60) >> 2; t = c; j = 3; break; } 157 | case 3: { buffer[o++] = (t & 3) << 6 | c; j = 0; break; } 158 | } 159 | } 160 | if (j === 1) throw Error(); 161 | return buffer; 162 | } 163 | 164 | var s64 = new Array(123); 165 | for (let i = 0; i < 64;) s64[i < 26 ? i + 65 : i < 52 ? i + 71 : i < 62 ? i - 4 : i - 59 | 43] = i++; 166 | -------------------------------------------------------------------------------- /parse/src/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs" 4 | }, 5 | "include": [ 6 | "./**/*.ts" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /parse/tests/index.ts: -------------------------------------------------------------------------------- 1 | import * as fs from "fs"; 2 | import { 3 | Type, 4 | SectionId, 5 | ExternalKind, 6 | parse 7 | } from ".."; 8 | 9 | function onSection(id: SectionId, offset: number, length: number, nameOffset: number, nameLength: number): boolean { 10 | var name = id == 0 ? "'" + parse.readString(nameOffset, nameLength) + "'" : SectionId[id]; 11 | console.log(name + " section at " + offset + ".." + (offset + length)); 12 | return true; 13 | } 14 | 15 | function onType(index: number, form: Type): void { 16 | console.log("- FunctionType[" + index + "]: " + Type[form]); 17 | } 18 | 19 | function onTypeParam(index: number, paramIndex: number, paramType: Type): void { 20 | console.log(" > param[" + paramIndex + "] -> " + Type[paramType]); 21 | } 22 | 23 | function onTypeReturn(index: number, returnIndex: number, returnType: Type): void { 24 | console.log(" > return[" + returnIndex + "] -> " + Type[returnType]); 25 | } 26 | 27 | function onImport(index: number, kind: ExternalKind, moduleOff: number, moduleLen: number, fieldOff: number, fieldLen: number): void { 28 | var moduleName = parse.readString(moduleOff, moduleLen); 29 | var fieldName = parse.readString(fieldOff, fieldLen); 30 | console.log("- Import[" + index + "]: '" + moduleName + "." + fieldName + "'"); 31 | } 32 | 33 | function onFunctionImport(funIndex: number, type: number): void { 34 | console.log(" - Function[" + funIndex + "] -> FunctionType[" + type + "]"); 35 | } 36 | 37 | function onTableImport(tblIndex: number, type: Type, initial: number, maximum: number, flags: number): void { 38 | console.log(" - Table[" + tblIndex + "] -> " + Type[type] + ": initial=" + initial + ", maximum=" + maximum); 39 | } 40 | 41 | function onMemoryImport(memIndex: number, initial: number, maximum: number, flags: number): void { 42 | console.log(" - Memory[" + memIndex + "]: initial=" + initial + ", maximum=" + maximum); 43 | } 44 | 45 | function onGlobalImport(gloIndex: number, type: Type, mutability: number): void { 46 | console.log(" - Global[" + gloIndex + "]: " + (mutability & 1 ? "mutable " : "const ") + Type[type]); 47 | } 48 | 49 | function onMemory(memIndex: number, initial: number, maximum: number, flags: number): void { 50 | console.log("- Memory[" + memIndex + "]: initial=" + initial + ", maximum=" + maximum); 51 | } 52 | 53 | function onFunction(funIndex: number, typeIndex: number): void { 54 | console.log("- Function[" + funIndex + "] -> FunctionType[" + typeIndex + "]"); 55 | } 56 | 57 | function onTable(tblIndex: number, type: number, initial: number, maximum: number, flags: number): void { 58 | console.log("- Table[" + tblIndex + "] -> " + Type[type] + ": initial=" + initial + ", maximum=" + (maximum >>> 0)); 59 | } 60 | 61 | function onGlobal(gloIndex: number, type: Type, mutability: number): void { 62 | console.log("- Global[" + gloIndex + "]: " + (mutability & 1 ? "mutable " : "const ") + Type[type]); 63 | } 64 | 65 | function onStart(index: number): void { 66 | console.log("- Start: Function[" + index + "]"); 67 | } 68 | 69 | function onExport(index: number, kind: ExternalKind, kindIndex: number, fieldOffset: number, fieldLength: number): void { 70 | var field = parse.readString(fieldOffset, fieldLength); 71 | console.log("- Export[" + index + "], '" + field + "' -> " + ExternalKind[kind] + "[" + kindIndex + "]"); 72 | } 73 | 74 | function onSourceMappingURL(offset: number, length: number): void { 75 | var url = parse.readString(offset, length); 76 | console.log("- sourceMap: " + url); 77 | } 78 | 79 | function onModuleName(offset: number, length: number): void { 80 | var name = parse.readString(offset, length); 81 | console.log("- moduleName: " + name); 82 | } 83 | 84 | function onFunctionName(index: number, offset: number, length: number): void { 85 | var name = parse.readString(offset, length); 86 | console.log(" - Function[" + index + "] name: " + name); 87 | } 88 | 89 | function onLocalName(funcIndex: number, index: number, offset: number, length: number): void { 90 | var name = parse.readString(offset, length); 91 | console.log(" - Function[" + funcIndex + "].local[" + index + "] name: " + name); 92 | } 93 | 94 | [ "../build/index.wasm", 95 | "libm.wasm" 96 | ].forEach((filename: string): void => { 97 | const binary: Uint8Array = fs.readFileSync(__dirname + "/" + filename); 98 | console.log("Testing '" + filename + "' ..."); 99 | parse(binary, { 100 | onSection, 101 | onType, 102 | onTypeParam, 103 | onTypeReturn, 104 | onImport, 105 | onFunctionImport, 106 | onTableImport, 107 | onMemoryImport, 108 | onGlobalImport, 109 | onMemory, 110 | onFunction, 111 | onTable, 112 | onGlobal, 113 | onStart, 114 | onExport, 115 | onSourceMappingURL, 116 | onModuleName, 117 | onFunctionName, 118 | onLocalName 119 | }); 120 | console.log(); 121 | }); 122 | -------------------------------------------------------------------------------- /parse/tests/libm.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AssemblyScript/examples/8b23ca8fa2f27cf9a39e5dfe4989d9eeba87d48f/parse/tests/libm.wasm -------------------------------------------------------------------------------- /parse/webpack.config.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const webpack = require("webpack"); 3 | 4 | const wasmData = fs.readFileSync(__dirname + "/build/index.wasm"); 5 | 6 | module.exports = { 7 | entry: [ "./src/index.ts" ], 8 | module: { 9 | rules: [ 10 | { 11 | test: /\.ts$/, 12 | use: "ts-loader", 13 | exclude: /node_modules/ 14 | } 15 | ] 16 | }, 17 | resolve: { 18 | extensions: [ ".ts", ".js" ] 19 | }, 20 | output: { 21 | filename: "index.js", 22 | path: __dirname, 23 | library: "asparse", 24 | libraryTarget: "umd", 25 | globalObject: "typeof self !== 'undefined' ? self : this" 26 | }, 27 | plugins: [ 28 | new webpack.DefinePlugin({ 29 | WASM_DATA: JSON.stringify(wasmData.toString("base64")) 30 | }) 31 | ], 32 | devtool: "source-map" 33 | }; 34 | -------------------------------------------------------------------------------- /sdk/README.md: -------------------------------------------------------------------------------- 1 | Browser SDK 2 | =========== 3 | 4 | An [AssemblyScript](http://assemblyscript.org) example using the [AssemblyScript browser SDK](https://github.com/AssemblyScript/assemblyscript/tree/master/lib/sdk). 5 | 6 | Instructions 7 | ------------ 8 | 9 | Open [index.html](./index.html) in a browser and see the console. View the source to learn how it works. 10 | -------------------------------------------------------------------------------- /sdk/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | AssemblyScript SDK Example 6 | 7 | 8 | 9 | 66 |

See the browser console!

67 | 68 | 69 | -------------------------------------------------------------------------------- /sdk/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@assemblyscript/sdk-example", 3 | "version": "1.0.0", 4 | "license": "Apache-2.0", 5 | "private": true, 6 | "scripts": { 7 | "start": "npx serve" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /sdk/preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AssemblyScript/examples/8b23ca8fa2f27cf9a39e5dfe4989d9eeba87d48f/sdk/preview.jpg -------------------------------------------------------------------------------- /transform/README.md: -------------------------------------------------------------------------------- 1 | Compiler transforms 2 | =================== 3 | 4 | An [AssemblyScript](http://assemblyscript.org) example of using compiler transforms to hook into the compilation process. 5 | 6 | Instructions 7 | ------------ 8 | 9 | * [JavaScript transform](./mytransform.js)
10 | An ES6 JavaScript transform. Recommended. 11 | 12 | See [package.json](./package.json) on how to utilize the transforms with `asc`. 13 | You may also run 14 | 15 | ``` 16 | $> npm install 17 | $> npm test 18 | ``` 19 | 20 | to verify that it works. 21 | -------------------------------------------------------------------------------- /transform/assembly/index.ts: -------------------------------------------------------------------------------- 1 | // empty 2 | -------------------------------------------------------------------------------- /transform/mytransform.mjs: -------------------------------------------------------------------------------- 1 | import * as assemblyscript from "assemblyscript"; 2 | import { Transform } from "assemblyscript/transform"; 3 | import binaryen from "binaryen"; 4 | 5 | class MyTransform extends Transform { 6 | afterParse(parser) { 7 | this.log("[mytransform.js] afterParse called, baseDir = " + this.baseDir); 8 | var sources = this.program.sources; 9 | sources.forEach((source) => 10 | this.log(" " + source.internalPath + " [" + assemblyscript.SourceKind[source.sourceKind] + "]") 11 | ); 12 | } 13 | afterInitialize(program) { 14 | this.log("[mytransform.js] afterInitialize called"); 15 | var elements = program.elementsByName; 16 | elements.forEach((element) => 17 | this.log(" " + element.internalName + " [" + assemblyscript.ElementKind[element.kind] + "]") 18 | ); 19 | } 20 | afterCompile(asModule) { 21 | this.log("[mytransform.js] afterCompile called"); 22 | var module = binaryen.wrapModule(asModule.ref); 23 | this.log(module.emitBinary()); 24 | } 25 | } 26 | 27 | export default MyTransform; 28 | -------------------------------------------------------------------------------- /transform/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@assemblyscript/transform-example", 3 | "version": "1.0.0", 4 | "license": "Apache-2.0", 5 | "private": true, 6 | "scripts": { 7 | "test": "asc assembly/index.ts --runtime stub --transform ./mytransform.mjs" 8 | }, 9 | "devDependencies": { 10 | "assemblyscript": "latest" 11 | } 12 | } 13 | --------------------------------------------------------------------------------