feat: init
This commit is contained in:
193
node_modules/@tybys/wasm-util/README.md
generated
vendored
Normal file
193
node_modules/@tybys/wasm-util/README.md
generated
vendored
Normal file
@@ -0,0 +1,193 @@
|
||||
# @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.memory
|
||||
|
||||
extendMemory(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~~
|
||||
Reference in New Issue
Block a user