Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/toyobayashi/wasm-util
https://github.com/toyobayashi/wasm-util
Last synced: 12 days ago
JSON representation
- Host: GitHub
- URL: https://github.com/toyobayashi/wasm-util
- Owner: toyobayashi
- Created: 2022-10-19T15:55:36.000Z (about 2 years ago)
- Default Branch: main
- Last Pushed: 2024-05-07T03:21:10.000Z (6 months ago)
- Last Synced: 2024-10-11T20:58:33.212Z (27 days ago)
- Language: TypeScript
- Size: 187 KB
- Stars: 28
- Watchers: 2
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# @tybys/wasm-util
WebAssembly related utils for browser environment
**The output code is ES2019**
## Features
All example code below need to be bundled by ES module bundlers like `webpack` / `rollup`, or specify import map in browser native ES module runtime.
### WASI polyfill for browser
The API is similar to the `require('wasi').WASI` in Node.js.
You can use `memfs-browser` to provide filesystem capability.
- Example: [https://github.com/toyobayashi/wasi-wabt](https://github.com/toyobayashi/wasi-wabt)
- Demo: [https://toyobayashi.github.io/wasi-wabt/](https://toyobayashi.github.io/wasi-wabt/)```js
import { load, WASI } from '@tybys/wasm-util'
import { Volume, createFsFromVolume } from 'memfs-browser'const fs = createFsFromVolume(Volume.fromJSON({
'/home/wasi': null
}))const wasi = new WASI({
args: ['chrome', 'file.wasm'],
env: {
NODE_ENV: 'development',
WASI_SDK_PATH: '/opt/wasi-sdk'
},
preopens: {
'/': '/'
},
fs,// redirect stdout / stderr
// print (text) { console.log(text) },
// printErr (text) { console.error(text) }
})const imports = {
wasi_snapshot_preview1: wasi.wasiImport
}const { module, instance } = await load('/path/to/file.wasm', imports)
wasi.start(instance)
// wasi.initialize(instance)
```Implemented syscalls: [wasi_snapshot_preview1](#wasi_snapshot_preview1)
### `load` / `loadSync`
`loadSync` has 4KB wasm size limit in browser.
```js
// bundler
import { load, loadSync } from '@tybys/wasm-util'const imports = { /* ... */ }
// using path
const { module, instance } = await load('/path/to/file.wasm', imports)
const { module, instance } = loadSync('/path/to/file.wasm', imports)// using URL
const { module, instance } = await load(new URL('./file.wasm', import.meta.url), imports)
const { module, instance } = loadSync(new URL('./file.wasm', import.meta.url), imports)// using Uint8Array
const buffer = new Uint8Array([
0x00, 0x61, 0x73, 0x6d,
0x01, 0x00, 0x00, 0x00
])
const { module, instance } = await load(buffer, imports)
const { module, instance } = loadSync(buffer, imports)// auto asyncify
const {
module,
instance: asyncifiedInstance
} = await load(buffer, imports, { /* asyncify options */})
asyncifiedInstance.exports.fn() // => return Promise
```### Extend Memory instance
```js
import { Memory, extendMemory } from '@tybys/wasm-util'const memory = new WebAssembly.Memory({ initial: 256 })
// const memory = instance.exports.memoryextendMemory(memory)
console.log(memory instanceof Memory)
console.log(memory instanceof WebAssembly.Memory)
// expose memory view getters like Emscripten
const { HEAPU8, HEAPU32, view } = memory
```### Asyncify wrap
Build the C code using `clang`, `wasm-ld` and `wasm-opt`
```c
void async_sleep(int ms);int main() {
async_sleep(200);
return 0;
}
``````js
import { Asyncify } from '@tybys/wasm-util'const asyncify = new Asyncify()
const imports = {
env: {
async_sleep: asyncify.wrapImportFunction(function (ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms)
})
})
}
}// async_sleep(200)
const bytes = await (await fetch('/asyncfied_by_wasm-opt.wasm')).arrayBuffer()
const { instance } = await WebAssembly.instantiate(bytes, imports)
const asyncifiedInstance = asyncify.init(instance.exports.memory, instance, {
wrapExports: ['_start']
})const p = asyncifedInstance._start()
console.log(typeof p.then === 'function')
const now = Date.now()
await p
console.log(Date.now() - now >= 200)
```### wasi_snapshot_preview1
- [x] args_get
- [x] args_sizes_get
- [x] environ_get
- [x] environ_sizes_get
- [x] clock_res_get
- [x] clock_time_get
- [ ] ~~fd_advise~~
- [x] fd_allocate
- [x] fd_close
- [x] fd_datasync
- [x] fd_fdstat_get
- [ ] ~~fd_fdstat_set_flags~~
- [x] fd_fdstat_set_rights
- [x] fd_filestat_get
- [x] fd_filestat_set_size
- [x] fd_filestat_set_times
- [x] fd_pread
- [x] fd_prestat_get
- [x] fd_prestat_dir_name
- [x] fd_pwrite
- [x] fd_read
- [x] fd_readdir
- [x] fd_renumber
- [x] fd_seek
- [x] fd_sync
- [x] fd_tell
- [x] fd_write
- [x] path_create_directory
- [x] path_filestat_get
- [x] path_filestat_set_times
- [x] path_link
- [x] path_open
- [x] path_readlink
- [x] path_remove_directory
- [x] path_rename
- [x] path_symlink
- [x] path_unlink_file
- [x] poll_oneoff (timer only)
- [x] proc_exit
- [ ] ~~proc_raise~~
- [x] sched_yield
- [x] random_get
- [ ] ~~sock_recv~~
- [ ] ~~sock_send~~
- [ ] ~~sock_shutdown~~