Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@tybys/wasm-util

Package Overview
Dependencies
Maintainers
1
Versions
15
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@tybys/wasm-util

WASI polyfill for browser and some wasm util

  • 0.4.0
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
1.7M
increased by3.16%
Maintainers
1
Weekly downloads
 
Created
Source

@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
  • Demo: https://toyobayashi.github.io/wasi-wabt/
import { load, WASI } from '@tybys/wasm-util'
import { Volumn, createFsFromVolume } from 'memfs-browser'

const fs = createFsFromVolume(Volume.from({
  '/home/wasi': null
}))

const wasi = new WASI({
  args: ['chrome', 'file.wasm'],
  env: {
    NODE_ENV: 'development',
    WASI_SDK_PATH: '/opt/wasi-sdk'
  },
  preopens: {
    '/': '/'
  },
  filesystem: { type: 'memfs', 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

load / loadSync

loadSync has 4KB wasm size limit in browser.

// 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

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

void async_sleep(int ms);

int main() {
  async_sleep(200);
  return 0;
}
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

  • args_get
  • args_sizes_get
  • environ_get
  • environ_sizes_get
  • clock_res_get
  • clock_time_get
  • fd_advise
  • fd_allocate
  • fd_close
  • fd_datasync
  • fd_fdstat_get
  • fd_fdstat_set_flags
  • fd_fdstat_set_rights
  • fd_filestat_get
  • fd_filestat_set_size
  • fd_filestat_set_times
  • fd_pread
  • fd_prestat_get
  • fd_prestat_dir_name
  • fd_pwrite
  • fd_read
  • fd_readdir
  • fd_renumber
  • fd_seek
  • fd_sync
  • fd_tell
  • fd_write
  • path_create_directory
  • path_filestat_get
  • path_filestat_set_times
  • path_link
  • path_open
  • path_readlink
  • path_remove_directory
  • path_rename
  • path_symlink
  • path_unlink_file
  • poll_oneoff
  • proc_exit
  • proc_raise
  • sched_yield
  • random_get
  • sock_recv
  • sock_send
  • sock_shutdown

Keywords

FAQs

Package last updated on 14 Nov 2022

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc