Website Structure

This commit is contained in:
supalerk-ar66 2026-01-13 10:46:40 +07:00
parent 62812f2090
commit 71f0676a62
22365 changed files with 4265753 additions and 791 deletions

View 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~~

View file

@ -0,0 +1,11 @@
// This file is read by tools that parse documentation comments conforming to the TSDoc standard.
// It should be published with your NPM package. It should not be tracked by Git.
{
"tsdocVersion": "0.12",
"toolPackages": [
{
"packageName": "@microsoft/api-extractor",
"packageVersion": "7.34.4"
}
]
}

View file

@ -0,0 +1,423 @@
/**
* @packageDocumentation
*/
/** @public */
export declare class Asyncify {
private value;
private exports;
private dataPtr;
init<T extends WebAssembly.Exports, U extends Array<Exclude<keyof T, AsyncifyExportName>>>(memory: WebAssembly.Memory, instance: {
readonly exports: T;
}, options: AsyncifyOptions): {
readonly exports: AsyncifyExports<T, U>;
};
private assertState;
wrapImportFunction<T extends Function>(f: T): T;
wrapImports<T extends WebAssembly.Imports>(imports: T): T;
wrapExportFunction<T extends Function>(f: T): AsyncifyExportFunction<T>;
wrapExports<T extends WebAssembly.Exports>(exports: T): AsyncifyExports<T, void>;
wrapExports<T extends WebAssembly.Exports, U extends Array<Exclude<keyof T, AsyncifyExportName>>>(exports: T, needWrap: U): AsyncifyExports<T, U>;
}
/** @public */
export declare type AsyncifyExportFunction<T> = T extends Callable ? (...args: Parameters<T>) => Promise<ReturnType<T>> : T;
/** @public */
export declare type AsyncifyExportName = 'asyncify_get_state' | 'asyncify_start_unwind' | 'asyncify_stop_unwind' | 'asyncify_start_rewind' | 'asyncify_stop_rewind';
/** @public */
export declare type AsyncifyExports<T, U> = T extends Record<string, any> ? {
[P in keyof T]: T[P] extends Callable ? U extends Array<Exclude<keyof T, AsyncifyExportName>> ? P extends U[number] ? AsyncifyExportFunction<T[P]> : T[P] : AsyncifyExportFunction<T[P]> : T[P];
} : T;
/** @public */
export declare function asyncifyLoad(asyncify: AsyncifyOptions, urlOrBuffer: string | URL | BufferSource | WebAssembly.Module, imports?: WebAssembly.Imports): Promise<WebAssembly.WebAssemblyInstantiatedSource>;
/** @public */
export declare function asyncifyLoadSync(asyncify: AsyncifyOptions, buffer: BufferSource | WebAssembly.Module, imports?: WebAssembly.Imports): WebAssembly.WebAssemblyInstantiatedSource;
/** @public */
export declare interface AsyncifyOptions {
wasm64?: boolean;
tryAllocate?: boolean | {
size?: number;
name?: string;
};
wrapExports?: string[];
}
/** @public */
export declare interface AsyncWASIOptions extends WASIOptions {
fs: {
promises: IFsPromises;
};
asyncify?: Asyncify;
}
/** @public */
export declare interface BaseEncodingOptions {
encoding?: BufferEncoding_2;
}
/** @public */
export declare interface BigIntStats extends StatsBase<bigint> {
}
/** @public */
declare type BufferEncoding_2 = 'ascii' | 'utf8' | 'utf-8' | 'utf16le' | 'ucs2' | 'ucs-2' | 'base64' | 'base64url' | 'latin1' | 'binary' | 'hex';
export { BufferEncoding_2 as BufferEncoding }
/** @public */
export declare type BufferEncodingOption = 'buffer' | {
encoding: 'buffer';
};
/** @public */
export declare type Callable = (...args: any[]) => any;
/** @public */
export declare function createAsyncWASI(options?: AsyncWASIOptions): Promise<WASI>;
/** @public */
export declare function extendMemory(memory: WebAssembly.Memory): Memory;
/** @public */
export declare interface FileHandle {
readonly fd: number;
datasync(): Promise<void>;
sync(): Promise<void>;
read<TBuffer extends Uint8Array>(buffer: TBuffer, offset?: number, length?: number, position?: number): Promise<{
bytesRead: number;
buffer: TBuffer;
}>;
stat(opts?: StatOptions & {
bigint?: false;
}): Promise<Stats>;
stat(opts: StatOptions & {
bigint: true;
}): Promise<BigIntStats>;
stat(opts?: StatOptions): Promise<Stats | BigIntStats>;
truncate(len?: number): Promise<void>;
utimes(atime: string | number | Date, mtime: string | number | Date): Promise<void>;
write<TBuffer extends Uint8Array>(buffer: TBuffer, offset?: number, length?: number, position?: number): Promise<{
bytesWritten: number;
buffer: TBuffer;
}>;
write(data: string | Uint8Array, position?: number, encoding?: BufferEncoding_2): Promise<{
bytesWritten: number;
buffer: string;
}>;
close(): Promise<void>;
}
/** @public */
export declare interface FinalizeBindingsOptions {
memory?: WebAssembly.Memory;
}
/** @public */
export declare interface IDirent {
isFile(): boolean;
isDirectory(): boolean;
isBlockDevice(): boolean;
isCharacterDevice(): boolean;
isSymbolicLink(): boolean;
isFIFO(): boolean;
isSocket(): boolean;
name: string;
}
/** @public */
export declare interface IFs {
fstatSync(fd: number, options?: StatOptions & {
bigint?: false;
}): Stats;
fstatSync(fd: number, options: StatOptions & {
bigint: true;
}): BigIntStats;
fstatSync(fd: number, options?: StatOptions): Stats | BigIntStats;
statSync(path: PathLike, options?: StatOptions & {
bigint?: false;
}): Stats;
statSync(path: PathLike, options: StatOptions & {
bigint: true;
}): BigIntStats;
statSync(path: PathLike, options?: StatOptions): Stats | BigIntStats;
lstatSync(path: PathLike, options?: StatOptions & {
bigint?: false;
}): Stats;
lstatSync(path: PathLike, options: StatOptions & {
bigint: true;
}): BigIntStats;
lstatSync(path: PathLike, options?: StatOptions): Stats | BigIntStats;
utimesSync(path: PathLike, atime: string | number | Date, mtime: string | number | Date): void;
openSync(path: PathLike, flags: OpenMode, mode?: Mode): number;
readSync(fd: number, buffer: ArrayBufferView, offset: number, length: number, position: number | null): number;
readSync(fd: number, buffer: ArrayBufferView, opts?: ReadSyncOptions): number;
writeSync(fd: number, buffer: ArrayBufferView, offset?: number, length?: number, position?: number): number;
writeSync(fd: number, string: string, position?: number, encoding?: BufferEncoding_2): number;
closeSync(fd: number): void;
readlinkSync(path: PathLike, options?: BaseEncodingOptions | BufferEncoding_2): string;
readlinkSync(path: PathLike, options: BufferEncodingOption): Uint8Array;
readlinkSync(path: PathLike, options?: BaseEncodingOptions | string): string | Uint8Array;
realpathSync(path: PathLike, options?: BaseEncodingOptions | BufferEncoding_2): string;
realpathSync(path: PathLike, options: BufferEncodingOption): Uint8Array;
realpathSync(path: PathLike, options?: BaseEncodingOptions | string): string | Uint8Array;
truncateSync(path: PathLike, len?: number): void;
ftruncateSync(fd: number, len?: number): void;
fdatasyncSync(fd: number): void;
futimesSync(fd: number, atime: string | number | Date, mtime: string | number | Date): void;
readdirSync(path: PathLike, options?: {
encoding: BufferEncoding_2 | null;
withFileTypes?: false;
} | BufferEncoding_2): string[];
readdirSync(path: PathLike, options: {
encoding: 'buffer';
withFileTypes?: false;
} | 'buffer'): Uint8Array[];
readdirSync(path: PathLike, options?: BaseEncodingOptions & {
withFileTypes?: false;
} | BufferEncoding_2): string[] | Uint8Array[];
readdirSync(path: PathLike, options: BaseEncodingOptions & {
withFileTypes: true;
}): IDirent[];
fsyncSync(fd: number): void;
mkdirSync(path: PathLike, options: MakeDirectoryOptions & {
recursive: true;
}): string | undefined;
mkdirSync(path: PathLike, options?: Mode | (MakeDirectoryOptions & {
recursive?: false;
})): void;
mkdirSync(path: PathLike, options?: Mode | MakeDirectoryOptions): string | undefined;
rmdirSync(path: PathLike, options?: RmDirOptions): void;
linkSync(existingPath: PathLike, newPath: PathLike): void;
unlinkSync(path: PathLike): void;
renameSync(oldPath: PathLike, newPath: PathLike): void;
symlinkSync(target: PathLike, path: PathLike, type?: 'dir' | 'file' | 'junction'): void;
}
/** @public */
export declare interface IFsPromises {
stat(path: PathLike, options?: StatOptions & {
bigint?: false;
}): Promise<Stats>;
stat(path: PathLike, options: StatOptions & {
bigint: true;
}): Promise<BigIntStats>;
stat(path: PathLike, options?: StatOptions): Promise<Stats | BigIntStats>;
lstat(path: PathLike, options?: StatOptions & {
bigint?: false;
}): Promise<Stats>;
lstat(path: PathLike, options: StatOptions & {
bigint: true;
}): Promise<BigIntStats>;
lstat(path: PathLike, options?: StatOptions): Promise<Stats | BigIntStats>;
utimes(path: PathLike, atime: string | number | Date, mtime: string | number | Date): Promise<void>;
open(path: PathLike, flags: OpenMode, mode?: Mode): Promise<FileHandle>;
read<TBuffer extends Uint8Array>(handle: FileHandle, buffer: TBuffer, offset?: number, length?: number, position?: number): Promise<{
bytesRead: number;
buffer: TBuffer;
}>;
write<TBuffer extends Uint8Array>(handle: FileHandle, buffer: TBuffer, offset?: number, length?: number, position?: number): Promise<{
bytesWritten: number;
buffer: TBuffer;
}>;
readlink(path: PathLike, options?: BaseEncodingOptions | BufferEncoding_2): Promise<string>;
readlink(path: PathLike, options: BufferEncodingOption): Promise<Uint8Array>;
readlink(path: PathLike, options?: BaseEncodingOptions | string): Promise<string | Uint8Array>;
realpath(path: PathLike, options?: BaseEncodingOptions | BufferEncoding_2): Promise<string>;
realpath(path: PathLike, options: BufferEncodingOption): Promise<Uint8Array>;
realpath(path: PathLike, options?: BaseEncodingOptions | string): Promise<string | Uint8Array>;
truncate(path: PathLike, len?: number): Promise<void>;
ftruncate(handle: FileHandle, len?: number): Promise<void>;
fdatasync(handle: FileHandle): Promise<void>;
futimes(handle: FileHandle, atime: string | number | Date, mtime: string | number | Date): Promise<void>;
readdir(path: PathLike, options?: {
encoding: BufferEncoding_2 | null;
withFileTypes?: false;
} | BufferEncoding_2): Promise<string[]>;
readdir(path: PathLike, options: {
encoding: 'buffer';
withFileTypes?: false;
} | 'buffer'): Promise<Uint8Array[]>;
readdir(path: PathLike, options?: BaseEncodingOptions & {
withFileTypes?: false;
} | BufferEncoding_2): Promise<string[] | Uint8Array[]>;
readdir(path: PathLike, options: BaseEncodingOptions & {
withFileTypes: true;
}): Promise<IDirent[]>;
fsync(handle: FileHandle): Promise<void>;
mkdir(path: PathLike, options: MakeDirectoryOptions & {
recursive: true;
}): Promise<string | undefined>;
mkdir(path: PathLike, options?: Mode | (MakeDirectoryOptions & {
recursive?: false;
})): Promise<void>;
mkdir(path: PathLike, options?: Mode | MakeDirectoryOptions): Promise<string | undefined>;
rmdir(path: PathLike, options?: RmDirOptions): Promise<void>;
link(existingPath: PathLike, newPath: PathLike): Promise<void>;
unlink(path: PathLike): Promise<void>;
rename(oldPath: PathLike, newPath: PathLike): Promise<void>;
symlink(target: PathLike, path: PathLike, type?: 'dir' | 'file' | 'junction'): Promise<void>;
}
declare const kBindingName: unique symbol;
declare const kExitCode: unique symbol;
declare const kInstance: unique symbol;
declare const kSetMemory: unique symbol;
declare const kStarted: unique symbol;
/** @public */
export declare function load(wasmInput: string | URL | BufferSource | WebAssembly.Module, imports?: WebAssembly.Imports): Promise<WebAssembly.WebAssemblyInstantiatedSource>;
/** @public */
export declare function loadSync(wasmInput: BufferSource | WebAssembly.Module, imports?: WebAssembly.Imports): WebAssembly.WebAssemblyInstantiatedSource;
/** @public */
export declare interface MakeDirectoryOptions {
recursive?: boolean;
mode?: Mode;
}
/** @public */
export declare class Memory extends WebAssemblyMemory {
constructor(descriptor: WebAssembly.MemoryDescriptor);
get HEAP8(): Int8Array;
get HEAPU8(): Uint8Array;
get HEAP16(): Int16Array;
get HEAPU16(): Uint16Array;
get HEAP32(): Int32Array;
get HEAPU32(): Uint32Array;
get HEAP64(): BigInt64Array;
get HEAPU64(): BigUint64Array;
get HEAPF32(): Float32Array;
get HEAPF64(): Float64Array;
get view(): DataView;
}
/** @public */
export declare type Mode = number | string;
/** @public */
export declare type OpenMode = number | string;
/** @public */
export declare type PathLike = string | Uint8Array | URL;
/** @public */
export declare type PromisifyExports<T, U> = T extends Record<string, any> ? {
[P in keyof T]: T[P] extends Callable ? U extends Array<keyof T> ? P extends U[number] ? AsyncifyExportFunction<T[P]> : T[P] : AsyncifyExportFunction<T[P]> : T[P];
} : T;
/** @public */
export declare interface ReadSyncOptions {
offset?: number;
length?: number;
position?: number;
}
/** @public */
export declare interface RmDirOptions {
maxRetries?: number;
recursive?: boolean;
retryDelay?: number;
}
/** @public */
export declare interface StatOptions {
bigint?: boolean;
}
/** @public */
export declare interface Stats extends StatsBase<number> {
}
/** @public */
export declare interface StatsBase<T> {
isFile(): boolean;
isDirectory(): boolean;
isBlockDevice(): boolean;
isCharacterDevice(): boolean;
isSymbolicLink(): boolean;
isFIFO(): boolean;
isSocket(): boolean;
dev: T;
ino: T;
mode: T;
nlink: T;
uid: T;
gid: T;
rdev: T;
size: T;
blksize: T;
blocks: T;
atimeMs: T;
mtimeMs: T;
ctimeMs: T;
birthtimeMs: T;
atime: Date;
mtime: Date;
ctime: Date;
birthtime: Date;
}
/** @public */
export declare interface SyncWASIOptions extends WASIOptions {
fs?: IFs;
}
/** @public */
export declare class WASI {
private [kSetMemory];
private [kStarted];
private [kExitCode];
private [kInstance];
private [kBindingName];
readonly wasiImport: Record<string, any>;
constructor(options?: SyncWASIOptions);
finalizeBindings(instance: WebAssembly.Instance, { memory }?: FinalizeBindingsOptions): void;
start(instance: WebAssembly.Instance): number | undefined | Promise<number> | Promise<undefined>;
initialize(instance: WebAssembly.Instance): void | Promise<void>;
getImportObject(): Record<string, Record<string, any>>;
}
/** @public */
export declare interface WASIOptions {
version?: 'unstable' | 'preview1';
args?: string[] | undefined;
env?: Record<string, string> | undefined;
preopens?: Record<string, string> | undefined;
/**
* @defaultValue `false`
*/
returnOnExit?: boolean | undefined;
print?: (str: string) => void;
printErr?: (str: string) => void;
}
/** @public */
export declare const WebAssemblyMemory: {
new (descriptor: WebAssembly.MemoryDescriptor): WebAssembly.Memory;
prototype: WebAssembly.Memory;
};
/** @public */
export declare function wrapAsyncExport<T extends Function = any>(f: Function): T;
/** @public */
export declare function wrapAsyncImport<T extends (...args: any[]) => any>(f: T, parameterType: WebAssembly.ValueType[], returnType: WebAssembly.ValueType[]): (...args: [object, ...Parameters<T>]) => ReturnType<T>;
/** @public */
export declare function wrapExports<T extends WebAssembly.Exports>(exports: T): PromisifyExports<T, void>;
/** @public */
export declare function wrapExports<T extends WebAssembly.Exports, U extends Array<keyof T>>(exports: T, needWrap: U): PromisifyExports<T, U>;
export { }
export as namespace wasmUtil;

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,158 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Asyncify = void 0;
const webassembly_1 = require("./webassembly");
const util_1 = require("./wasi/util");
const ignoreNames = [
'asyncify_get_state',
'asyncify_start_rewind',
'asyncify_start_unwind',
'asyncify_stop_rewind',
'asyncify_stop_unwind'
];
// const wrappedExports = new WeakMap<WebAssembly.Exports, WebAssembly.Exports>()
var AsyncifyState;
(function (AsyncifyState) {
AsyncifyState[AsyncifyState["NONE"] = 0] = "NONE";
AsyncifyState[AsyncifyState["UNWINDING"] = 1] = "UNWINDING";
AsyncifyState[AsyncifyState["REWINDING"] = 2] = "REWINDING";
})(AsyncifyState || (AsyncifyState = {}));
function tryAllocate(instance, wasm64, size, mallocName) {
if (typeof instance.exports[mallocName] !== 'function' || size <= 0) {
return {
wasm64,
dataPtr: 16,
start: wasm64 ? 32 : 24,
end: 1024
};
}
const malloc = instance.exports[mallocName];
const dataPtr = wasm64 ? Number(malloc(BigInt(16) + BigInt(size))) : malloc(8 + size);
if (dataPtr === 0) {
throw new Error('Allocate asyncify data failed');
}
return wasm64
? { wasm64, dataPtr, start: dataPtr + 16, end: dataPtr + 16 + size }
: { wasm64, dataPtr, start: dataPtr + 8, end: dataPtr + 8 + size };
}
/** @public */
class Asyncify {
constructor() {
this.value = undefined;
this.exports = undefined;
this.dataPtr = 0;
}
init(memory, instance, options) {
var _a, _b;
if (this.exports) {
throw new Error('Asyncify has been initialized');
}
if (!(memory instanceof webassembly_1._WebAssembly.Memory)) {
throw new TypeError('Require WebAssembly.Memory object');
}
const exports = instance.exports;
for (let i = 0; i < ignoreNames.length; ++i) {
if (typeof exports[ignoreNames[i]] !== 'function') {
throw new TypeError('Invalid asyncify wasm');
}
}
let address;
const wasm64 = Boolean(options.wasm64);
if (!options.tryAllocate) {
address = {
wasm64,
dataPtr: 16,
start: wasm64 ? 32 : 24,
end: 1024
};
}
else {
if (options.tryAllocate === true) {
address = tryAllocate(instance, wasm64, 4096, 'malloc');
}
else {
address = tryAllocate(instance, wasm64, (_a = options.tryAllocate.size) !== null && _a !== void 0 ? _a : 4096, (_b = options.tryAllocate.name) !== null && _b !== void 0 ? _b : 'malloc');
}
}
this.dataPtr = address.dataPtr;
if (wasm64) {
new BigInt64Array(memory.buffer, this.dataPtr).set([BigInt(address.start), BigInt(address.end)]);
}
else {
new Int32Array(memory.buffer, this.dataPtr).set([address.start, address.end]);
}
this.exports = this.wrapExports(exports, options.wrapExports);
const asyncifiedInstance = Object.create(webassembly_1._WebAssembly.Instance.prototype);
Object.defineProperty(asyncifiedInstance, 'exports', { value: this.exports });
// Object.setPrototypeOf(instance, Instance.prototype)
return asyncifiedInstance;
}
assertState() {
if (this.exports.asyncify_get_state() !== AsyncifyState.NONE) {
throw new Error('Asyncify state error');
}
}
wrapImportFunction(f) {
// eslint-disable-next-line @typescript-eslint/no-this-alias
const _this = this;
return (function () {
// eslint-disable-next-line no-unreachable-loop
while (_this.exports.asyncify_get_state() === AsyncifyState.REWINDING) {
_this.exports.asyncify_stop_rewind();
return _this.value;
}
_this.assertState();
const v = f.apply(this, arguments);
if (!(0, util_1.isPromiseLike)(v))
return v;
_this.exports.asyncify_start_unwind(_this.dataPtr);
_this.value = v;
});
}
wrapImports(imports) {
const importObject = {};
Object.keys(imports).forEach(k => {
const mod = imports[k];
const newModule = {};
Object.keys(mod).forEach(name => {
const importValue = mod[name];
if (typeof importValue === 'function') {
newModule[name] = this.wrapImportFunction(importValue);
}
else {
newModule[name] = importValue;
}
});
importObject[k] = newModule;
});
return importObject;
}
wrapExportFunction(f) {
// eslint-disable-next-line @typescript-eslint/no-this-alias
const _this = this;
return (async function () {
_this.assertState();
let ret = f.apply(this, arguments);
while (_this.exports.asyncify_get_state() === AsyncifyState.UNWINDING) {
_this.exports.asyncify_stop_unwind();
_this.value = await _this.value;
_this.assertState();
_this.exports.asyncify_start_rewind(_this.dataPtr);
ret = f.call(this);
}
_this.assertState();
return ret;
});
}
wrapExports(exports, needWrap) {
return (0, util_1.wrapInstanceExports)(exports, (exportValue, name) => {
let ignore = ignoreNames.indexOf(name) !== -1 || typeof exportValue !== 'function';
if (Array.isArray(needWrap)) {
ignore = ignore || (needWrap.indexOf(name) === -1);
}
return ignore ? exportValue : this.wrapExportFunction(exportValue);
});
}
}
exports.Asyncify = Asyncify;
//# sourceMappingURL=asyncify.js.map

View file

@ -0,0 +1,13 @@
"use strict";
/**
* @packageDocumentation
*/
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
tslib_1.__exportStar(require("./asyncify"), exports);
tslib_1.__exportStar(require("./load"), exports);
tslib_1.__exportStar(require("./wasi/index"), exports);
tslib_1.__exportStar(require("./memory"), exports);
tslib_1.__exportStar(require("./jspi"), exports);
tslib_1.__exportStar(require("./wasi/fs"), exports);
//# sourceMappingURL=index.js.map

View file

@ -0,0 +1,46 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.wrapExports = exports.wrapAsyncExport = exports.wrapAsyncImport = void 0;
const util_1 = require("./wasi/util");
const webassembly_1 = require("./webassembly");
function checkWebAssemblyFunction() {
const WebAssemblyFunction = webassembly_1._WebAssembly.Function;
if (typeof WebAssemblyFunction !== 'function') {
throw new Error('WebAssembly.Function is not supported in this environment.' +
' If you are using V8 based browser like Chrome, try to specify' +
' --js-flags="--wasm-staging --experimental-wasm-stack-switching"');
}
return WebAssemblyFunction;
}
/** @public */
function wrapAsyncImport(f, parameterType, returnType) {
const WebAssemblyFunction = checkWebAssemblyFunction();
if (typeof f !== 'function') {
throw new TypeError('Function required');
}
const parameters = parameterType.slice(0);
parameters.unshift('externref');
return new WebAssemblyFunction({ parameters, results: returnType }, f, { suspending: 'first' });
}
exports.wrapAsyncImport = wrapAsyncImport;
/** @public */
function wrapAsyncExport(f) {
const WebAssemblyFunction = checkWebAssemblyFunction();
if (typeof f !== 'function') {
throw new TypeError('Function required');
}
return new WebAssemblyFunction({ parameters: [...WebAssemblyFunction.type(f).parameters.slice(1)], results: ['externref'] }, f, { promising: 'first' });
}
exports.wrapAsyncExport = wrapAsyncExport;
/** @public */
function wrapExports(exports, needWrap) {
return (0, util_1.wrapInstanceExports)(exports, (exportValue, name) => {
let ignore = typeof exportValue !== 'function';
if (Array.isArray(needWrap)) {
ignore = ignore || (needWrap.indexOf(name) === -1);
}
return ignore ? exportValue : wrapAsyncExport(exportValue);
});
}
exports.wrapExports = wrapExports;
//# sourceMappingURL=jspi.js.map

View file

@ -0,0 +1,97 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.asyncifyLoadSync = exports.loadSync = exports.asyncifyLoad = exports.load = void 0;
const webassembly_1 = require("./webassembly");
const asyncify_1 = require("./asyncify");
function validateImports(imports) {
if (imports && typeof imports !== 'object') {
throw new TypeError('imports must be an object or undefined');
}
}
function fetchWasm(urlOrBuffer, imports) {
if (typeof wx !== 'undefined' && typeof __wxConfig !== 'undefined') {
return webassembly_1._WebAssembly.instantiate(urlOrBuffer, imports);
}
return fetch(urlOrBuffer)
.then(response => response.arrayBuffer())
.then(buffer => webassembly_1._WebAssembly.instantiate(buffer, imports));
}
/** @public */
function load(wasmInput, imports) {
validateImports(imports);
imports = imports !== null && imports !== void 0 ? imports : {};
let source;
if (wasmInput instanceof ArrayBuffer || ArrayBuffer.isView(wasmInput)) {
return webassembly_1._WebAssembly.instantiate(wasmInput, imports);
}
if (wasmInput instanceof webassembly_1._WebAssembly.Module) {
return webassembly_1._WebAssembly.instantiate(wasmInput, imports).then((instance) => {
return { instance, module: wasmInput };
});
}
if (typeof wasmInput !== 'string' && !(wasmInput instanceof URL)) {
throw new TypeError('Invalid source');
}
if (typeof webassembly_1._WebAssembly.instantiateStreaming === 'function') {
let responsePromise;
try {
responsePromise = fetch(wasmInput);
source = webassembly_1._WebAssembly.instantiateStreaming(responsePromise, imports).catch(() => {
return fetchWasm(wasmInput, imports);
});
}
catch (_) {
source = fetchWasm(wasmInput, imports);
}
}
else {
source = fetchWasm(wasmInput, imports);
}
return source;
}
exports.load = load;
/** @public */
function asyncifyLoad(asyncify, urlOrBuffer, imports) {
validateImports(imports);
imports = imports !== null && imports !== void 0 ? imports : {};
const asyncifyHelper = new asyncify_1.Asyncify();
imports = asyncifyHelper.wrapImports(imports);
return load(urlOrBuffer, imports).then(source => {
var _a;
const memory = source.instance.exports.memory || ((_a = imports.env) === null || _a === void 0 ? void 0 : _a.memory);
return { module: source.module, instance: asyncifyHelper.init(memory, source.instance, asyncify) };
});
}
exports.asyncifyLoad = asyncifyLoad;
/** @public */
function loadSync(wasmInput, imports) {
validateImports(imports);
imports = imports !== null && imports !== void 0 ? imports : {};
let module;
if ((wasmInput instanceof ArrayBuffer) || ArrayBuffer.isView(wasmInput)) {
module = new webassembly_1._WebAssembly.Module(wasmInput);
}
else if (wasmInput instanceof WebAssembly.Module) {
module = wasmInput;
}
else {
throw new TypeError('Invalid source');
}
const instance = new webassembly_1._WebAssembly.Instance(module, imports);
const source = { instance, module };
return source;
}
exports.loadSync = loadSync;
/** @public */
function asyncifyLoadSync(asyncify, buffer, imports) {
var _a;
validateImports(imports);
imports = imports !== null && imports !== void 0 ? imports : {};
const asyncifyHelper = new asyncify_1.Asyncify();
imports = asyncifyHelper.wrapImports(imports);
const source = loadSync(buffer, imports);
const memory = source.instance.exports.memory || ((_a = imports.env) === null || _a === void 0 ? void 0 : _a.memory);
return { module: source.module, instance: asyncifyHelper.init(memory, source.instance, asyncify) };
}
exports.asyncifyLoadSync = asyncifyLoadSync;
//# sourceMappingURL=load.js.map

View file

@ -0,0 +1,35 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.extendMemory = exports.Memory = exports.WebAssemblyMemory = void 0;
/* eslint-disable spaced-comment */
const webassembly_1 = require("./webassembly");
/** @public */
exports.WebAssemblyMemory = (function () { return webassembly_1._WebAssembly.Memory; })();
/** @public */
class Memory extends exports.WebAssemblyMemory {
// eslint-disable-next-line @typescript-eslint/no-useless-constructor
constructor(descriptor) {
super(descriptor);
}
get HEAP8() { return new Int8Array(super.buffer); }
get HEAPU8() { return new Uint8Array(super.buffer); }
get HEAP16() { return new Int16Array(super.buffer); }
get HEAPU16() { return new Uint16Array(super.buffer); }
get HEAP32() { return new Int32Array(super.buffer); }
get HEAPU32() { return new Uint32Array(super.buffer); }
get HEAP64() { return new BigInt64Array(super.buffer); }
get HEAPU64() { return new BigUint64Array(super.buffer); }
get HEAPF32() { return new Float32Array(super.buffer); }
get HEAPF64() { return new Float64Array(super.buffer); }
get view() { return new DataView(super.buffer); }
}
exports.Memory = Memory;
/** @public */
function extendMemory(memory) {
if (Object.getPrototypeOf(memory) === webassembly_1._WebAssembly.Memory.prototype) {
Object.setPrototypeOf(memory, Memory.prototype);
}
return memory;
}
exports.extendMemory = extendMemory;
//# sourceMappingURL=memory.js.map

View file

@ -0,0 +1,103 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WasiError = exports.strerror = void 0;
const types_1 = require("./types");
function strerror(errno) {
switch (errno) {
case types_1.WasiErrno.ESUCCESS: return 'Success';
case types_1.WasiErrno.E2BIG: return 'Argument list too long';
case types_1.WasiErrno.EACCES: return 'Permission denied';
case types_1.WasiErrno.EADDRINUSE: return 'Address in use';
case types_1.WasiErrno.EADDRNOTAVAIL: return 'Address not available';
case types_1.WasiErrno.EAFNOSUPPORT: return 'Address family not supported by protocol';
case types_1.WasiErrno.EAGAIN: return 'Resource temporarily unavailable';
case types_1.WasiErrno.EALREADY: return 'Operation already in progress';
case types_1.WasiErrno.EBADF: return 'Bad file descriptor';
case types_1.WasiErrno.EBADMSG: return 'Bad message';
case types_1.WasiErrno.EBUSY: return 'Resource busy';
case types_1.WasiErrno.ECANCELED: return 'Operation canceled';
case types_1.WasiErrno.ECHILD: return 'No child process';
case types_1.WasiErrno.ECONNABORTED: return 'Connection aborted';
case types_1.WasiErrno.ECONNREFUSED: return 'Connection refused';
case types_1.WasiErrno.ECONNRESET: return 'Connection reset by peer';
case types_1.WasiErrno.EDEADLK: return 'Resource deadlock would occur';
case types_1.WasiErrno.EDESTADDRREQ: return 'Destination address required';
case types_1.WasiErrno.EDOM: return 'Domain error';
case types_1.WasiErrno.EDQUOT: return 'Quota exceeded';
case types_1.WasiErrno.EEXIST: return 'File exists';
case types_1.WasiErrno.EFAULT: return 'Bad address';
case types_1.WasiErrno.EFBIG: return 'File too large';
case types_1.WasiErrno.EHOSTUNREACH: return 'Host is unreachable';
case types_1.WasiErrno.EIDRM: return 'Identifier removed';
case types_1.WasiErrno.EILSEQ: return 'Illegal byte sequence';
case types_1.WasiErrno.EINPROGRESS: return 'Operation in progress';
case types_1.WasiErrno.EINTR: return 'Interrupted system call';
case types_1.WasiErrno.EINVAL: return 'Invalid argument';
case types_1.WasiErrno.EIO: return 'I/O error';
case types_1.WasiErrno.EISCONN: return 'Socket is connected';
case types_1.WasiErrno.EISDIR: return 'Is a directory';
case types_1.WasiErrno.ELOOP: return 'Symbolic link loop';
case types_1.WasiErrno.EMFILE: return 'No file descriptors available';
case types_1.WasiErrno.EMLINK: return 'Too many links';
case types_1.WasiErrno.EMSGSIZE: return 'Message too large';
case types_1.WasiErrno.EMULTIHOP: return 'Multihop attempted';
case types_1.WasiErrno.ENAMETOOLONG: return 'Filename too long';
case types_1.WasiErrno.ENETDOWN: return 'Network is down';
case types_1.WasiErrno.ENETRESET: return 'Connection reset by network';
case types_1.WasiErrno.ENETUNREACH: return 'Network unreachable';
case types_1.WasiErrno.ENFILE: return 'Too many files open in system';
case types_1.WasiErrno.ENOBUFS: return 'No buffer space available';
case types_1.WasiErrno.ENODEV: return 'No such device';
case types_1.WasiErrno.ENOENT: return 'No such file or directory';
case types_1.WasiErrno.ENOEXEC: return 'Exec format error';
case types_1.WasiErrno.ENOLCK: return 'No locks available';
case types_1.WasiErrno.ENOLINK: return 'Link has been severed';
case types_1.WasiErrno.ENOMEM: return 'Out of memory';
case types_1.WasiErrno.ENOMSG: return 'No message of the desired type';
case types_1.WasiErrno.ENOPROTOOPT: return 'Protocol not available';
case types_1.WasiErrno.ENOSPC: return 'No space left on device';
case types_1.WasiErrno.ENOSYS: return 'Function not implemented';
case types_1.WasiErrno.ENOTCONN: return 'Socket not connected';
case types_1.WasiErrno.ENOTDIR: return 'Not a directory';
case types_1.WasiErrno.ENOTEMPTY: return 'Directory not empty';
case types_1.WasiErrno.ENOTRECOVERABLE: return 'State not recoverable';
case types_1.WasiErrno.ENOTSOCK: return 'Not a socket';
case types_1.WasiErrno.ENOTSUP: return 'Not supported';
case types_1.WasiErrno.ENOTTY: return 'Not a tty';
case types_1.WasiErrno.ENXIO: return 'No such device or address';
case types_1.WasiErrno.EOVERFLOW: return 'Value too large for data type';
case types_1.WasiErrno.EOWNERDEAD: return 'Previous owner died';
case types_1.WasiErrno.EPERM: return 'Operation not permitted';
case types_1.WasiErrno.EPIPE: return 'Broken pipe';
case types_1.WasiErrno.EPROTO: return 'Protocol error';
case types_1.WasiErrno.EPROTONOSUPPORT: return 'Protocol not supported';
case types_1.WasiErrno.EPROTOTYPE: return 'Protocol wrong type for socket';
case types_1.WasiErrno.ERANGE: return 'Result not representable';
case types_1.WasiErrno.EROFS: return 'Read-only file system';
case types_1.WasiErrno.ESPIPE: return 'Invalid seek';
case types_1.WasiErrno.ESRCH: return 'No such process';
case types_1.WasiErrno.ESTALE: return 'Stale file handle';
case types_1.WasiErrno.ETIMEDOUT: return 'Operation timed out';
case types_1.WasiErrno.ETXTBSY: return 'Text file busy';
case types_1.WasiErrno.EXDEV: return 'Cross-device link';
case types_1.WasiErrno.ENOTCAPABLE: return 'Capabilities insufficient';
default: return 'Unknown error';
}
}
exports.strerror = strerror;
class WasiError extends Error {
constructor(message, errno) {
super(message);
this.errno = errno;
}
getErrorMessage() {
return strerror(this.errno);
}
}
exports.WasiError = WasiError;
Object.defineProperty(WasiError.prototype, 'name', {
configurable: true,
writable: true,
value: 'WasiError'
});
//# sourceMappingURL=error.js.map

View file

@ -0,0 +1,268 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AsyncTable = exports.SyncTable = exports.FileDescriptorTable = exports.toFileStat = exports.toFileType = exports.StandardOutput = exports.FileDescriptor = exports.concatBuffer = void 0;
const types_1 = require("./types");
const rights_1 = require("./rights");
const error_1 = require("./error");
function concatBuffer(buffers, size) {
let total = 0;
if (typeof size === 'number' && size >= 0) {
total = size;
}
else {
for (let i = 0; i < buffers.length; i++) {
const buffer = buffers[i];
total += buffer.length;
}
}
let pos = 0;
const ret = new Uint8Array(total);
for (let i = 0; i < buffers.length; i++) {
const buffer = buffers[i];
ret.set(buffer, pos);
pos += buffer.length;
}
return ret;
}
exports.concatBuffer = concatBuffer;
class FileDescriptor {
constructor(id, fd, path, realPath, type, rightsBase, rightsInheriting, preopen) {
this.id = id;
this.fd = fd;
this.path = path;
this.realPath = realPath;
this.type = type;
this.rightsBase = rightsBase;
this.rightsInheriting = rightsInheriting;
this.preopen = preopen;
this.pos = BigInt(0);
this.size = BigInt(0);
}
seek(offset, whence) {
if (whence === types_1.WasiWhence.SET) {
this.pos = BigInt(offset);
}
else if (whence === types_1.WasiWhence.CUR) {
this.pos += BigInt(offset);
}
else if (whence === types_1.WasiWhence.END) {
this.pos = BigInt(this.size) - BigInt(offset);
}
else {
throw new error_1.WasiError('Unknown whence', types_1.WasiErrno.EIO);
}
return this.pos;
}
}
exports.FileDescriptor = FileDescriptor;
class StandardOutput extends FileDescriptor {
constructor(log, id, fd, path, realPath, type, rightsBase, rightsInheriting, preopen) {
super(id, fd, path, realPath, type, rightsBase, rightsInheriting, preopen);
this._log = log;
this._buf = null;
}
write(buffer) {
const originalBuffer = buffer;
if (this._buf) {
buffer = concatBuffer([this._buf, buffer]);
this._buf = null;
}
if (buffer.indexOf(10) === -1) {
this._buf = buffer;
return originalBuffer.byteLength;
}
let written = 0;
let lastBegin = 0;
let index;
while ((index = buffer.indexOf(10, written)) !== -1) {
const str = new TextDecoder().decode(buffer.subarray(lastBegin, index));
this._log(str);
written += index - lastBegin + 1;
lastBegin = index + 1;
}
if (written < buffer.length) {
this._buf = buffer.slice(written);
}
return originalBuffer.byteLength;
}
}
exports.StandardOutput = StandardOutput;
function toFileType(stat) {
if (stat.isBlockDevice())
return types_1.WasiFileType.BLOCK_DEVICE;
if (stat.isCharacterDevice())
return types_1.WasiFileType.CHARACTER_DEVICE;
if (stat.isDirectory())
return types_1.WasiFileType.DIRECTORY;
if (stat.isSocket())
return types_1.WasiFileType.SOCKET_STREAM;
if (stat.isFile())
return types_1.WasiFileType.REGULAR_FILE;
if (stat.isSymbolicLink())
return types_1.WasiFileType.SYMBOLIC_LINK;
return types_1.WasiFileType.UNKNOWN;
}
exports.toFileType = toFileType;
function toFileStat(view, buf, stat) {
view.setBigUint64(buf, stat.dev, true);
view.setBigUint64(buf + 8, stat.ino, true);
view.setBigUint64(buf + 16, BigInt(toFileType(stat)), true);
view.setBigUint64(buf + 24, stat.nlink, true);
view.setBigUint64(buf + 32, stat.size, true);
view.setBigUint64(buf + 40, stat.atimeMs * BigInt(1000000), true);
view.setBigUint64(buf + 48, stat.mtimeMs * BigInt(1000000), true);
view.setBigUint64(buf + 56, stat.ctimeMs * BigInt(1000000), true);
}
exports.toFileStat = toFileStat;
class FileDescriptorTable {
constructor(options) {
this.used = 0;
this.size = options.size;
this.fds = Array(options.size);
this.stdio = [options.in, options.out, options.err];
this.print = options.print;
this.printErr = options.printErr;
this.insertStdio(options.in, 0, '<stdin>');
this.insertStdio(options.out, 1, '<stdout>');
this.insertStdio(options.err, 2, '<stderr>');
}
insertStdio(fd, expected, name) {
const type = types_1.WasiFileType.CHARACTER_DEVICE;
const { base, inheriting } = (0, rights_1.getRights)(this.stdio, fd, types_1.FileControlFlag.O_RDWR, type);
const wrap = this.insert(fd, name, name, type, base, inheriting, 0);
if (wrap.id !== expected) {
throw new error_1.WasiError(`id: ${wrap.id} !== expected: ${expected}`, types_1.WasiErrno.EBADF);
}
return wrap;
}
insert(fd, mappedPath, realPath, type, rightsBase, rightsInheriting, preopen) {
var _a, _b;
let index = -1;
if (this.used >= this.size) {
const newSize = this.size * 2;
this.fds.length = newSize;
index = this.size;
this.size = newSize;
}
else {
for (let i = 0; i < this.size; ++i) {
if (this.fds[i] == null) {
index = i;
break;
}
}
}
let entry;
if (mappedPath === '<stdout>') {
entry = new StandardOutput((_a = this.print) !== null && _a !== void 0 ? _a : console.log, index, fd, mappedPath, realPath, type, rightsBase, rightsInheriting, preopen);
}
else if (mappedPath === '<stderr>') {
entry = new StandardOutput((_b = this.printErr) !== null && _b !== void 0 ? _b : console.error, index, fd, mappedPath, realPath, type, rightsBase, rightsInheriting, preopen);
}
else {
entry = new FileDescriptor(index, fd, mappedPath, realPath, type, rightsBase, rightsInheriting, preopen);
}
this.fds[index] = entry;
this.used++;
return entry;
}
get(id, base, inheriting) {
if (id >= this.size) {
throw new error_1.WasiError('Invalid fd', types_1.WasiErrno.EBADF);
}
const entry = this.fds[id];
if (!entry || entry.id !== id) {
throw new error_1.WasiError('Bad file descriptor', types_1.WasiErrno.EBADF);
}
/* Validate that the fd has the necessary rights. */
if ((~entry.rightsBase & base) !== BigInt(0) || (~entry.rightsInheriting & inheriting) !== BigInt(0)) {
throw new error_1.WasiError('Capabilities insufficient', types_1.WasiErrno.ENOTCAPABLE);
}
return entry;
}
remove(id) {
if (id >= this.size) {
throw new error_1.WasiError('Invalid fd', types_1.WasiErrno.EBADF);
}
const entry = this.fds[id];
if (!entry || entry.id !== id) {
throw new error_1.WasiError('Bad file descriptor', types_1.WasiErrno.EBADF);
}
this.fds[id] = undefined;
this.used--;
}
}
exports.FileDescriptorTable = FileDescriptorTable;
class SyncTable extends FileDescriptorTable {
constructor(options) {
super(options);
this.fs = options.fs;
}
getFileTypeByFd(fd) {
const stats = this.fs.fstatSync(fd, { bigint: true });
return toFileType(stats);
}
insertPreopen(fd, mappedPath, realPath) {
const type = this.getFileTypeByFd(fd);
if (type !== types_1.WasiFileType.DIRECTORY) {
throw new error_1.WasiError(`Preopen not dir: ["${mappedPath}", "${realPath}"]`, types_1.WasiErrno.ENOTDIR);
}
const result = (0, rights_1.getRights)(this.stdio, fd, 0, type);
return this.insert(fd, mappedPath, realPath, type, result.base, result.inheriting, 1);
}
renumber(dst, src) {
if (dst === src)
return;
if (dst >= this.size || src >= this.size) {
throw new error_1.WasiError('Invalid fd', types_1.WasiErrno.EBADF);
}
const dstEntry = this.fds[dst];
const srcEntry = this.fds[src];
if (!dstEntry || !srcEntry || dstEntry.id !== dst || srcEntry.id !== src) {
throw new error_1.WasiError('Invalid fd', types_1.WasiErrno.EBADF);
}
this.fs.closeSync(dstEntry.fd);
this.fds[dst] = this.fds[src];
this.fds[dst].id = dst;
this.fds[src] = undefined;
this.used--;
}
}
exports.SyncTable = SyncTable;
class AsyncTable extends FileDescriptorTable {
// eslint-disable-next-line @typescript-eslint/no-useless-constructor
constructor(options) {
super(options);
}
async getFileTypeByFd(fd) {
const stats = await fd.stat({ bigint: true });
return toFileType(stats);
}
async insertPreopen(fd, mappedPath, realPath) {
const type = await this.getFileTypeByFd(fd);
if (type !== types_1.WasiFileType.DIRECTORY) {
throw new error_1.WasiError(`Preopen not dir: ["${mappedPath}", "${realPath}"]`, types_1.WasiErrno.ENOTDIR);
}
const result = (0, rights_1.getRights)(this.stdio, fd.fd, 0, type);
return this.insert(fd, mappedPath, realPath, type, result.base, result.inheriting, 1);
}
async renumber(dst, src) {
if (dst === src)
return;
if (dst >= this.size || src >= this.size) {
throw new error_1.WasiError('Invalid fd', types_1.WasiErrno.EBADF);
}
const dstEntry = this.fds[dst];
const srcEntry = this.fds[src];
if (!dstEntry || !srcEntry || dstEntry.id !== dst || srcEntry.id !== src) {
throw new error_1.WasiError('Invalid fd', types_1.WasiErrno.EBADF);
}
await dstEntry.fd.close();
this.fds[dst] = this.fds[src];
this.fds[dst].id = dst;
this.fds[src] = undefined;
this.used--;
}
}
exports.AsyncTable = AsyncTable;
//# sourceMappingURL=fd.js.map

View file

@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=fs.js.map

View file

@ -0,0 +1,192 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createAsyncWASI = exports.WASI = void 0;
const preview1_1 = require("./preview1");
const util_1 = require("./util");
// eslint-disable-next-line spaced-comment
const kEmptyObject = /*#__PURE__*/ Object.freeze(/*#__PURE__*/ Object.create(null));
const kExitCode = Symbol('kExitCode');
const kSetMemory = Symbol('kSetMemory');
const kStarted = Symbol('kStarted');
const kInstance = Symbol('kInstance');
const kBindingName = Symbol('kBindingName');
function validateOptions(options) {
var _a;
(0, util_1.validateObject)(options, 'options');
let _WASI;
if (options.version !== undefined) {
(0, util_1.validateString)(options.version, 'options.version');
switch (options.version) {
case 'unstable':
_WASI = preview1_1.WASI;
this[kBindingName] = 'wasi_unstable';
break;
case 'preview1':
_WASI = preview1_1.WASI;
this[kBindingName] = 'wasi_snapshot_preview1';
break;
default:
throw new TypeError(`unsupported WASI version "${options.version}"`);
}
}
else {
_WASI = preview1_1.WASI;
this[kBindingName] = 'wasi_snapshot_preview1';
}
if (options.args !== undefined) {
(0, util_1.validateArray)(options.args, 'options.args');
}
const args = ((_a = options.args) !== null && _a !== void 0 ? _a : []).map(String);
const env = [];
if (options.env !== undefined) {
(0, util_1.validateObject)(options.env, 'options.env');
Object.entries(options.env).forEach(({ 0: key, 1: value }) => {
if (value !== undefined) {
env.push(`${key}=${value}`);
}
});
}
const preopens = [];
if (options.preopens !== undefined) {
(0, util_1.validateObject)(options.preopens, 'options.preopens');
Object.entries(options.preopens).forEach(({ 0: key, 1: value }) => preopens.push({ mappedPath: String(key), realPath: String(value) }));
}
if (preopens.length > 0) {
if (options.fs === undefined) {
throw new Error('filesystem is disabled, can not preopen directory');
}
try {
(0, util_1.validateObject)(options.fs, 'options.fs');
}
catch (_) {
throw new TypeError('Node.js fs like implementation is not provided');
}
}
// if (options.filesystem !== undefined) {
// validateObject(options.filesystem, 'options.filesystem')
// validateString(options.filesystem.type, 'options.filesystem.type')
// if (options.filesystem.type !== 'memfs' && options.filesystem.type !== 'file-system-access-api') {
// throw new Error(`Filesystem type ${(options.filesystem as any).type as string} is not supported, only "memfs" and "file-system-access-api" is supported currently`)
// }
// try {
// validateObject(options.filesystem.fs, 'options.filesystem.fs')
// } catch (_) {
// throw new Error('Node.js fs like implementation is not provided')
// }
// }
if (options.print !== undefined)
(0, util_1.validateFunction)(options.print, 'options.print');
if (options.printErr !== undefined)
(0, util_1.validateFunction)(options.printErr, 'options.printErr');
if (options.returnOnExit !== undefined) {
(0, util_1.validateBoolean)(options.returnOnExit, 'options.returnOnExit');
}
// const { stdin = 0, stdout = 1, stderr = 2 } = options
// validateInt32(stdin, 'options.stdin', 0)
// validateInt32(stdout, 'options.stdout', 0)
// validateInt32(stderr, 'options.stderr', 0)
// const stdio = [stdin, stdout, stderr] as const
const stdio = [0, 1, 2];
return {
args,
env,
preopens,
stdio,
_WASI
};
}
function initWASI(setMemory, wrap) {
this[kSetMemory] = setMemory;
this.wasiImport = wrap;
this[kStarted] = false;
this[kExitCode] = 0;
this[kInstance] = undefined;
}
/** @public */
class WASI {
constructor(options = kEmptyObject) {
const { args, env, preopens, stdio, _WASI } = validateOptions.call(this, options);
const wrap = _WASI.createSync(args, env, preopens, stdio, options.fs, options.print, options.printErr);
const setMemory = wrap._setMemory;
delete wrap._setMemory;
initWASI.call(this, setMemory, wrap);
if (options.returnOnExit) {
wrap.proc_exit = wasiReturnOnProcExit.bind(this);
}
}
finalizeBindings(instance, _a) {
var _b;
var { memory = (_b = instance === null || instance === void 0 ? void 0 : instance.exports) === null || _b === void 0 ? void 0 : _b.memory } = _a === void 0 ? {} : _a;
if (this[kStarted]) {
throw new Error('WASI instance has already started');
}
(0, util_1.validateObject)(instance, 'instance');
(0, util_1.validateObject)(instance.exports, 'instance.exports');
this[kSetMemory](memory);
this[kInstance] = instance;
this[kStarted] = true;
}
// Must not export _initialize, must export _start
start(instance) {
this.finalizeBindings(instance);
const { _start, _initialize } = this[kInstance].exports;
(0, util_1.validateFunction)(_start, 'instance.exports._start');
(0, util_1.validateUndefined)(_initialize, 'instance.exports._initialize');
let ret;
try {
ret = _start();
}
catch (err) {
if (err !== kExitCode) {
throw err;
}
}
if (ret instanceof Promise) {
return ret.then(() => this[kExitCode], (err) => {
if (err !== kExitCode) {
throw err;
}
return this[kExitCode];
});
}
return this[kExitCode];
}
// Must not export _start, may optionally export _initialize
initialize(instance) {
this.finalizeBindings(instance);
const { _start, _initialize } = this[kInstance].exports;
(0, util_1.validateUndefined)(_start, 'instance.exports._start');
if (_initialize !== undefined) {
(0, util_1.validateFunction)(_initialize, 'instance.exports._initialize');
return _initialize();
}
}
getImportObject() {
return { [this[kBindingName]]: this.wasiImport };
}
}
exports.WASI = WASI;
function wasiReturnOnProcExit(rval) {
this[kExitCode] = rval;
// eslint-disable-next-line @typescript-eslint/no-throw-literal
throw kExitCode;
}
/** @public */
async function createAsyncWASI(options = kEmptyObject) {
const _this = Object.create(WASI.prototype);
const { args, env, preopens, stdio, _WASI } = validateOptions.call(_this, options);
if (options.asyncify !== undefined) {
(0, util_1.validateObject)(options.asyncify, 'options.asyncify');
(0, util_1.validateFunction)(options.asyncify.wrapImportFunction, 'options.asyncify.wrapImportFunction');
}
const wrap = await _WASI.createAsync(args, env, preopens, stdio, options.fs, options.print, options.printErr, options.asyncify);
const setMemory = wrap._setMemory;
delete wrap._setMemory;
initWASI.call(_this, setMemory, wrap);
if (options.returnOnExit) {
wrap.proc_exit = wasiReturnOnProcExit.bind(_this);
}
return _this;
}
exports.createAsyncWASI = createAsyncWASI;
//# sourceMappingURL=index.js.map

View file

@ -0,0 +1,174 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.relative = exports.resolve = void 0;
const util_1 = require("./util");
const CHAR_DOT = 46; /* . */
const CHAR_FORWARD_SLASH = 47; /* / */
function isPosixPathSeparator(code) {
return code === CHAR_FORWARD_SLASH;
}
function normalizeString(path, allowAboveRoot, separator, isPathSeparator) {
let res = '';
let lastSegmentLength = 0;
let lastSlash = -1;
let dots = 0;
let code = 0;
for (let i = 0; i <= path.length; ++i) {
if (i < path.length) {
code = path.charCodeAt(i);
}
else if (isPathSeparator(code)) {
break;
}
else {
code = CHAR_FORWARD_SLASH;
}
if (isPathSeparator(code)) {
if (lastSlash === i - 1 || dots === 1) {
// NOOP
}
else if (dots === 2) {
if (res.length < 2 || lastSegmentLength !== 2 ||
res.charCodeAt(res.length - 1) !== CHAR_DOT ||
res.charCodeAt(res.length - 2) !== CHAR_DOT) {
if (res.length > 2) {
const lastSlashIndex = res.indexOf(separator);
if (lastSlashIndex === -1) {
res = '';
lastSegmentLength = 0;
}
else {
res = res.slice(0, lastSlashIndex);
lastSegmentLength =
res.length - 1 - res.indexOf(separator);
}
lastSlash = i;
dots = 0;
continue;
}
else if (res.length !== 0) {
res = '';
lastSegmentLength = 0;
lastSlash = i;
dots = 0;
continue;
}
}
if (allowAboveRoot) {
res += res.length > 0 ? `${separator}..` : '..';
lastSegmentLength = 2;
}
}
else {
if (res.length > 0) {
res += `${separator}${path.slice(lastSlash + 1, i)}`;
}
else {
res = path.slice(lastSlash + 1, i);
}
lastSegmentLength = i - lastSlash - 1;
}
lastSlash = i;
dots = 0;
}
else if (code === CHAR_DOT && dots !== -1) {
++dots;
}
else {
dots = -1;
}
}
return res;
}
function resolve(...args) {
let resolvedPath = '';
let resolvedAbsolute = false;
for (let i = args.length - 1; i >= -1 && !resolvedAbsolute; i--) {
const path = i >= 0 ? args[i] : '/';
(0, util_1.validateString)(path, 'path');
// Skip empty entries
if (path.length === 0) {
continue;
}
resolvedPath = `${path}/${resolvedPath}`;
resolvedAbsolute = path.charCodeAt(0) === CHAR_FORWARD_SLASH;
}
// At this point the path should be resolved to a full absolute path, but
// handle relative paths to be safe (might happen when process.cwd() fails)
// Normalize the path
resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute, '/', isPosixPathSeparator);
if (resolvedAbsolute) {
return `/${resolvedPath}`;
}
return resolvedPath.length > 0 ? resolvedPath : '.';
}
exports.resolve = resolve;
function relative(from, to) {
(0, util_1.validateString)(from, 'from');
(0, util_1.validateString)(to, 'to');
if (from === to)
return '';
// Trim leading forward slashes.
from = resolve(from);
to = resolve(to);
if (from === to)
return '';
const fromStart = 1;
const fromEnd = from.length;
const fromLen = fromEnd - fromStart;
const toStart = 1;
const toLen = to.length - toStart;
// Compare paths to find the longest common path from root
const length = (fromLen < toLen ? fromLen : toLen);
let lastCommonSep = -1;
let i = 0;
for (; i < length; i++) {
const fromCode = from.charCodeAt(fromStart + i);
if (fromCode !== to.charCodeAt(toStart + i)) {
break;
}
else if (fromCode === CHAR_FORWARD_SLASH) {
lastCommonSep = i;
}
}
if (i === length) {
if (toLen > length) {
if (to.charCodeAt(toStart + i) === CHAR_FORWARD_SLASH) {
// We get here if `from` is the exact base path for `to`.
// For example: from='/foo/bar'; to='/foo/bar/baz'
return to.slice(toStart + i + 1);
}
if (i === 0) {
// We get here if `from` is the root
// For example: from='/'; to='/foo'
return to.slice(toStart + i);
}
}
else if (fromLen > length) {
if (from.charCodeAt(fromStart + i) === CHAR_FORWARD_SLASH) {
// We get here if `to` is the exact base path for `from`.
// For example: from='/foo/bar/baz'; to='/foo/bar'
lastCommonSep = i;
}
else if (i === 0) {
// We get here if `to` is the root.
// For example: from='/foo/bar'; to='/'
lastCommonSep = 0;
}
}
}
let out = '';
// Generate the relative path based on the path difference between `to`
// and `from`.
for (i = fromStart + lastCommonSep + 1; i <= fromEnd; ++i) {
if (i === fromEnd ||
from.charCodeAt(i) === CHAR_FORWARD_SLASH) {
out += out.length === 0 ? '..' : '/..';
}
}
// Lastly, append the rest of the destination (`to`) path that comes after
// the common path parts.
return `${out}${to.slice(toStart + lastCommonSep)}`;
}
exports.relative = relative;
//# sourceMappingURL=path.js.map

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,141 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getRights = exports.TTY_INHERITING = exports.TTY_BASE = exports.SOCKET_INHERITING = exports.SOCKET_BASE = exports.DIRECTORY_INHERITING = exports.DIRECTORY_BASE = exports.REGULAR_FILE_INHERITING = exports.REGULAR_FILE_BASE = exports.CHARACTER_DEVICE_INHERITING = exports.CHARACTER_DEVICE_BASE = exports.BLOCK_DEVICE_INHERITING = exports.BLOCK_DEVICE_BASE = exports.RIGHTS_ALL = void 0;
/* eslint-disable spaced-comment */
const error_1 = require("./error");
const types_1 = require("./types");
exports.RIGHTS_ALL = types_1.WasiRights.FD_DATASYNC |
types_1.WasiRights.FD_READ |
types_1.WasiRights.FD_SEEK |
types_1.WasiRights.FD_FDSTAT_SET_FLAGS |
types_1.WasiRights.FD_SYNC |
types_1.WasiRights.FD_TELL |
types_1.WasiRights.FD_WRITE |
types_1.WasiRights.FD_ADVISE |
types_1.WasiRights.FD_ALLOCATE |
types_1.WasiRights.PATH_CREATE_DIRECTORY |
types_1.WasiRights.PATH_CREATE_FILE |
types_1.WasiRights.PATH_LINK_SOURCE |
types_1.WasiRights.PATH_LINK_TARGET |
types_1.WasiRights.PATH_OPEN |
types_1.WasiRights.FD_READDIR |
types_1.WasiRights.PATH_READLINK |
types_1.WasiRights.PATH_RENAME_SOURCE |
types_1.WasiRights.PATH_RENAME_TARGET |
types_1.WasiRights.PATH_FILESTAT_GET |
types_1.WasiRights.PATH_FILESTAT_SET_SIZE |
types_1.WasiRights.PATH_FILESTAT_SET_TIMES |
types_1.WasiRights.FD_FILESTAT_GET |
types_1.WasiRights.FD_FILESTAT_SET_TIMES |
types_1.WasiRights.FD_FILESTAT_SET_SIZE |
types_1.WasiRights.PATH_SYMLINK |
types_1.WasiRights.PATH_UNLINK_FILE |
types_1.WasiRights.PATH_REMOVE_DIRECTORY |
types_1.WasiRights.POLL_FD_READWRITE |
types_1.WasiRights.SOCK_SHUTDOWN |
types_1.WasiRights.SOCK_ACCEPT;
exports.BLOCK_DEVICE_BASE = exports.RIGHTS_ALL;
exports.BLOCK_DEVICE_INHERITING = exports.RIGHTS_ALL;
exports.CHARACTER_DEVICE_BASE = exports.RIGHTS_ALL;
exports.CHARACTER_DEVICE_INHERITING = exports.RIGHTS_ALL;
exports.REGULAR_FILE_BASE = types_1.WasiRights.FD_DATASYNC |
types_1.WasiRights.FD_READ |
types_1.WasiRights.FD_SEEK |
types_1.WasiRights.FD_FDSTAT_SET_FLAGS |
types_1.WasiRights.FD_SYNC |
types_1.WasiRights.FD_TELL |
types_1.WasiRights.FD_WRITE |
types_1.WasiRights.FD_ADVISE |
types_1.WasiRights.FD_ALLOCATE |
types_1.WasiRights.FD_FILESTAT_GET |
types_1.WasiRights.FD_FILESTAT_SET_SIZE |
types_1.WasiRights.FD_FILESTAT_SET_TIMES |
types_1.WasiRights.POLL_FD_READWRITE;
exports.REGULAR_FILE_INHERITING = BigInt(0);
exports.DIRECTORY_BASE = types_1.WasiRights.FD_FDSTAT_SET_FLAGS |
types_1.WasiRights.FD_SYNC |
types_1.WasiRights.FD_ADVISE |
types_1.WasiRights.PATH_CREATE_DIRECTORY |
types_1.WasiRights.PATH_CREATE_FILE |
types_1.WasiRights.PATH_LINK_SOURCE |
types_1.WasiRights.PATH_LINK_TARGET |
types_1.WasiRights.PATH_OPEN |
types_1.WasiRights.FD_READDIR |
types_1.WasiRights.PATH_READLINK |
types_1.WasiRights.PATH_RENAME_SOURCE |
types_1.WasiRights.PATH_RENAME_TARGET |
types_1.WasiRights.PATH_FILESTAT_GET |
types_1.WasiRights.PATH_FILESTAT_SET_SIZE |
types_1.WasiRights.PATH_FILESTAT_SET_TIMES |
types_1.WasiRights.FD_FILESTAT_GET |
types_1.WasiRights.FD_FILESTAT_SET_TIMES |
types_1.WasiRights.PATH_SYMLINK |
types_1.WasiRights.PATH_UNLINK_FILE |
types_1.WasiRights.PATH_REMOVE_DIRECTORY |
types_1.WasiRights.POLL_FD_READWRITE;
exports.DIRECTORY_INHERITING = exports.DIRECTORY_BASE | exports.REGULAR_FILE_BASE;
exports.SOCKET_BASE = (types_1.WasiRights.FD_READ |
types_1.WasiRights.FD_FDSTAT_SET_FLAGS |
types_1.WasiRights.FD_WRITE |
types_1.WasiRights.FD_FILESTAT_GET |
types_1.WasiRights.POLL_FD_READWRITE |
types_1.WasiRights.SOCK_SHUTDOWN);
exports.SOCKET_INHERITING = exports.RIGHTS_ALL;
exports.TTY_BASE = types_1.WasiRights.FD_READ |
types_1.WasiRights.FD_FDSTAT_SET_FLAGS |
types_1.WasiRights.FD_WRITE |
types_1.WasiRights.FD_FILESTAT_GET |
types_1.WasiRights.POLL_FD_READWRITE;
exports.TTY_INHERITING = BigInt(0);
function getRights(stdio, fd, flags, type) {
const ret = {
base: BigInt(0),
inheriting: BigInt(0)
};
if (type === types_1.WasiFileType.UNKNOWN) {
throw new error_1.WasiError('Unknown file type', types_1.WasiErrno.EINVAL);
}
switch (type) {
case types_1.WasiFileType.REGULAR_FILE:
ret.base = exports.REGULAR_FILE_BASE;
ret.inheriting = exports.REGULAR_FILE_INHERITING;
break;
case types_1.WasiFileType.DIRECTORY:
ret.base = exports.DIRECTORY_BASE;
ret.inheriting = exports.DIRECTORY_INHERITING;
break;
case types_1.WasiFileType.SOCKET_STREAM:
case types_1.WasiFileType.SOCKET_DGRAM:
ret.base = exports.SOCKET_BASE;
ret.inheriting = exports.SOCKET_INHERITING;
break;
case types_1.WasiFileType.CHARACTER_DEVICE:
if (stdio.indexOf(fd) !== -1) {
ret.base = exports.TTY_BASE;
ret.inheriting = exports.TTY_INHERITING;
}
else {
ret.base = exports.CHARACTER_DEVICE_BASE;
ret.inheriting = exports.CHARACTER_DEVICE_INHERITING;
}
break;
case types_1.WasiFileType.BLOCK_DEVICE:
ret.base = exports.BLOCK_DEVICE_BASE;
ret.inheriting = exports.BLOCK_DEVICE_INHERITING;
break;
default:
ret.base = BigInt(0);
ret.inheriting = BigInt(0);
}
/* Disable read/write bits depending on access mode. */
const read_or_write_only = flags & (0 | 1 | 2);
if (read_or_write_only === 0) {
ret.base &= ~types_1.WasiRights.FD_WRITE;
}
else if (read_or_write_only === 1) {
ret.base &= ~types_1.WasiRights.FD_READ;
}
return ret;
}
exports.getRights = getRights;
//# sourceMappingURL=rights.js.map

View file

@ -0,0 +1,220 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WasiSubclockflags = exports.WasiEventType = exports.WasiFstFlag = exports.WasiClockid = exports.WasiFdFlag = exports.WasiFileControlFlag = exports.FileControlFlag = exports.WasiWhence = exports.WasiRights = exports.WasiFileType = exports.WasiErrno = void 0;
/* eslint-disable spaced-comment */
var WasiErrno;
(function (WasiErrno) {
WasiErrno[WasiErrno["ESUCCESS"] = 0] = "ESUCCESS";
WasiErrno[WasiErrno["E2BIG"] = 1] = "E2BIG";
WasiErrno[WasiErrno["EACCES"] = 2] = "EACCES";
WasiErrno[WasiErrno["EADDRINUSE"] = 3] = "EADDRINUSE";
WasiErrno[WasiErrno["EADDRNOTAVAIL"] = 4] = "EADDRNOTAVAIL";
WasiErrno[WasiErrno["EAFNOSUPPORT"] = 5] = "EAFNOSUPPORT";
WasiErrno[WasiErrno["EAGAIN"] = 6] = "EAGAIN";
WasiErrno[WasiErrno["EALREADY"] = 7] = "EALREADY";
WasiErrno[WasiErrno["EBADF"] = 8] = "EBADF";
WasiErrno[WasiErrno["EBADMSG"] = 9] = "EBADMSG";
WasiErrno[WasiErrno["EBUSY"] = 10] = "EBUSY";
WasiErrno[WasiErrno["ECANCELED"] = 11] = "ECANCELED";
WasiErrno[WasiErrno["ECHILD"] = 12] = "ECHILD";
WasiErrno[WasiErrno["ECONNABORTED"] = 13] = "ECONNABORTED";
WasiErrno[WasiErrno["ECONNREFUSED"] = 14] = "ECONNREFUSED";
WasiErrno[WasiErrno["ECONNRESET"] = 15] = "ECONNRESET";
WasiErrno[WasiErrno["EDEADLK"] = 16] = "EDEADLK";
WasiErrno[WasiErrno["EDESTADDRREQ"] = 17] = "EDESTADDRREQ";
WasiErrno[WasiErrno["EDOM"] = 18] = "EDOM";
WasiErrno[WasiErrno["EDQUOT"] = 19] = "EDQUOT";
WasiErrno[WasiErrno["EEXIST"] = 20] = "EEXIST";
WasiErrno[WasiErrno["EFAULT"] = 21] = "EFAULT";
WasiErrno[WasiErrno["EFBIG"] = 22] = "EFBIG";
WasiErrno[WasiErrno["EHOSTUNREACH"] = 23] = "EHOSTUNREACH";
WasiErrno[WasiErrno["EIDRM"] = 24] = "EIDRM";
WasiErrno[WasiErrno["EILSEQ"] = 25] = "EILSEQ";
WasiErrno[WasiErrno["EINPROGRESS"] = 26] = "EINPROGRESS";
WasiErrno[WasiErrno["EINTR"] = 27] = "EINTR";
WasiErrno[WasiErrno["EINVAL"] = 28] = "EINVAL";
WasiErrno[WasiErrno["EIO"] = 29] = "EIO";
WasiErrno[WasiErrno["EISCONN"] = 30] = "EISCONN";
WasiErrno[WasiErrno["EISDIR"] = 31] = "EISDIR";
WasiErrno[WasiErrno["ELOOP"] = 32] = "ELOOP";
WasiErrno[WasiErrno["EMFILE"] = 33] = "EMFILE";
WasiErrno[WasiErrno["EMLINK"] = 34] = "EMLINK";
WasiErrno[WasiErrno["EMSGSIZE"] = 35] = "EMSGSIZE";
WasiErrno[WasiErrno["EMULTIHOP"] = 36] = "EMULTIHOP";
WasiErrno[WasiErrno["ENAMETOOLONG"] = 37] = "ENAMETOOLONG";
WasiErrno[WasiErrno["ENETDOWN"] = 38] = "ENETDOWN";
WasiErrno[WasiErrno["ENETRESET"] = 39] = "ENETRESET";
WasiErrno[WasiErrno["ENETUNREACH"] = 40] = "ENETUNREACH";
WasiErrno[WasiErrno["ENFILE"] = 41] = "ENFILE";
WasiErrno[WasiErrno["ENOBUFS"] = 42] = "ENOBUFS";
WasiErrno[WasiErrno["ENODEV"] = 43] = "ENODEV";
WasiErrno[WasiErrno["ENOENT"] = 44] = "ENOENT";
WasiErrno[WasiErrno["ENOEXEC"] = 45] = "ENOEXEC";
WasiErrno[WasiErrno["ENOLCK"] = 46] = "ENOLCK";
WasiErrno[WasiErrno["ENOLINK"] = 47] = "ENOLINK";
WasiErrno[WasiErrno["ENOMEM"] = 48] = "ENOMEM";
WasiErrno[WasiErrno["ENOMSG"] = 49] = "ENOMSG";
WasiErrno[WasiErrno["ENOPROTOOPT"] = 50] = "ENOPROTOOPT";
WasiErrno[WasiErrno["ENOSPC"] = 51] = "ENOSPC";
WasiErrno[WasiErrno["ENOSYS"] = 52] = "ENOSYS";
WasiErrno[WasiErrno["ENOTCONN"] = 53] = "ENOTCONN";
WasiErrno[WasiErrno["ENOTDIR"] = 54] = "ENOTDIR";
WasiErrno[WasiErrno["ENOTEMPTY"] = 55] = "ENOTEMPTY";
WasiErrno[WasiErrno["ENOTRECOVERABLE"] = 56] = "ENOTRECOVERABLE";
WasiErrno[WasiErrno["ENOTSOCK"] = 57] = "ENOTSOCK";
WasiErrno[WasiErrno["ENOTSUP"] = 58] = "ENOTSUP";
WasiErrno[WasiErrno["ENOTTY"] = 59] = "ENOTTY";
WasiErrno[WasiErrno["ENXIO"] = 60] = "ENXIO";
WasiErrno[WasiErrno["EOVERFLOW"] = 61] = "EOVERFLOW";
WasiErrno[WasiErrno["EOWNERDEAD"] = 62] = "EOWNERDEAD";
WasiErrno[WasiErrno["EPERM"] = 63] = "EPERM";
WasiErrno[WasiErrno["EPIPE"] = 64] = "EPIPE";
WasiErrno[WasiErrno["EPROTO"] = 65] = "EPROTO";
WasiErrno[WasiErrno["EPROTONOSUPPORT"] = 66] = "EPROTONOSUPPORT";
WasiErrno[WasiErrno["EPROTOTYPE"] = 67] = "EPROTOTYPE";
WasiErrno[WasiErrno["ERANGE"] = 68] = "ERANGE";
WasiErrno[WasiErrno["EROFS"] = 69] = "EROFS";
WasiErrno[WasiErrno["ESPIPE"] = 70] = "ESPIPE";
WasiErrno[WasiErrno["ESRCH"] = 71] = "ESRCH";
WasiErrno[WasiErrno["ESTALE"] = 72] = "ESTALE";
WasiErrno[WasiErrno["ETIMEDOUT"] = 73] = "ETIMEDOUT";
WasiErrno[WasiErrno["ETXTBSY"] = 74] = "ETXTBSY";
WasiErrno[WasiErrno["EXDEV"] = 75] = "EXDEV";
WasiErrno[WasiErrno["ENOTCAPABLE"] = 76] = "ENOTCAPABLE";
})(WasiErrno = exports.WasiErrno || (exports.WasiErrno = {}));
var WasiFileType;
(function (WasiFileType) {
WasiFileType[WasiFileType["UNKNOWN"] = 0] = "UNKNOWN";
WasiFileType[WasiFileType["BLOCK_DEVICE"] = 1] = "BLOCK_DEVICE";
WasiFileType[WasiFileType["CHARACTER_DEVICE"] = 2] = "CHARACTER_DEVICE";
WasiFileType[WasiFileType["DIRECTORY"] = 3] = "DIRECTORY";
WasiFileType[WasiFileType["REGULAR_FILE"] = 4] = "REGULAR_FILE";
WasiFileType[WasiFileType["SOCKET_DGRAM"] = 5] = "SOCKET_DGRAM";
WasiFileType[WasiFileType["SOCKET_STREAM"] = 6] = "SOCKET_STREAM";
WasiFileType[WasiFileType["SYMBOLIC_LINK"] = 7] = "SYMBOLIC_LINK";
})(WasiFileType = exports.WasiFileType || (exports.WasiFileType = {}));
const FD_DATASYNC = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(0));
const FD_READ = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(1));
const FD_SEEK = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(2));
const FD_FDSTAT_SET_FLAGS = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(3));
const FD_SYNC = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(4));
const FD_TELL = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(5));
const FD_WRITE = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(6));
const FD_ADVISE = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(7));
const FD_ALLOCATE = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(8));
const PATH_CREATE_DIRECTORY = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(9));
const PATH_CREATE_FILE = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(10));
const PATH_LINK_SOURCE = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(11));
const PATH_LINK_TARGET = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(12));
const PATH_OPEN = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(13));
const FD_READDIR = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(14));
const PATH_READLINK = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(15));
const PATH_RENAME_SOURCE = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(16));
const PATH_RENAME_TARGET = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(17));
const PATH_FILESTAT_GET = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(18));
const PATH_FILESTAT_SET_SIZE = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(19));
const PATH_FILESTAT_SET_TIMES = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(20));
const FD_FILESTAT_GET = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(21));
const FD_FILESTAT_SET_SIZE = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(22));
const FD_FILESTAT_SET_TIMES = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(23));
const PATH_SYMLINK = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(24));
const PATH_REMOVE_DIRECTORY = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(25));
const PATH_UNLINK_FILE = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(26));
const POLL_FD_READWRITE = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(27));
const SOCK_SHUTDOWN = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(28));
const SOCK_ACCEPT = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(29));
exports.WasiRights = {
FD_DATASYNC,
FD_READ,
FD_SEEK,
FD_FDSTAT_SET_FLAGS,
FD_SYNC,
FD_TELL,
FD_WRITE,
FD_ADVISE,
FD_ALLOCATE,
PATH_CREATE_DIRECTORY,
PATH_CREATE_FILE,
PATH_LINK_SOURCE,
PATH_LINK_TARGET,
PATH_OPEN,
FD_READDIR,
PATH_READLINK,
PATH_RENAME_SOURCE,
PATH_RENAME_TARGET,
PATH_FILESTAT_GET,
PATH_FILESTAT_SET_SIZE,
PATH_FILESTAT_SET_TIMES,
FD_FILESTAT_GET,
FD_FILESTAT_SET_SIZE,
FD_FILESTAT_SET_TIMES,
PATH_SYMLINK,
PATH_REMOVE_DIRECTORY,
PATH_UNLINK_FILE,
POLL_FD_READWRITE,
SOCK_SHUTDOWN,
SOCK_ACCEPT
};
var WasiWhence;
(function (WasiWhence) {
WasiWhence[WasiWhence["SET"] = 0] = "SET";
WasiWhence[WasiWhence["CUR"] = 1] = "CUR";
WasiWhence[WasiWhence["END"] = 2] = "END";
})(WasiWhence = exports.WasiWhence || (exports.WasiWhence = {}));
var FileControlFlag;
(function (FileControlFlag) {
FileControlFlag[FileControlFlag["O_RDONLY"] = 0] = "O_RDONLY";
FileControlFlag[FileControlFlag["O_WRONLY"] = 1] = "O_WRONLY";
FileControlFlag[FileControlFlag["O_RDWR"] = 2] = "O_RDWR";
FileControlFlag[FileControlFlag["O_CREAT"] = 64] = "O_CREAT";
FileControlFlag[FileControlFlag["O_EXCL"] = 128] = "O_EXCL";
FileControlFlag[FileControlFlag["O_NOCTTY"] = 256] = "O_NOCTTY";
FileControlFlag[FileControlFlag["O_TRUNC"] = 512] = "O_TRUNC";
FileControlFlag[FileControlFlag["O_APPEND"] = 1024] = "O_APPEND";
FileControlFlag[FileControlFlag["O_DIRECTORY"] = 65536] = "O_DIRECTORY";
FileControlFlag[FileControlFlag["O_NOATIME"] = 262144] = "O_NOATIME";
FileControlFlag[FileControlFlag["O_NOFOLLOW"] = 131072] = "O_NOFOLLOW";
FileControlFlag[FileControlFlag["O_SYNC"] = 1052672] = "O_SYNC";
FileControlFlag[FileControlFlag["O_DIRECT"] = 16384] = "O_DIRECT";
FileControlFlag[FileControlFlag["O_NONBLOCK"] = 2048] = "O_NONBLOCK";
})(FileControlFlag = exports.FileControlFlag || (exports.FileControlFlag = {}));
var WasiFileControlFlag;
(function (WasiFileControlFlag) {
WasiFileControlFlag[WasiFileControlFlag["O_CREAT"] = 1] = "O_CREAT";
WasiFileControlFlag[WasiFileControlFlag["O_DIRECTORY"] = 2] = "O_DIRECTORY";
WasiFileControlFlag[WasiFileControlFlag["O_EXCL"] = 4] = "O_EXCL";
WasiFileControlFlag[WasiFileControlFlag["O_TRUNC"] = 8] = "O_TRUNC";
})(WasiFileControlFlag = exports.WasiFileControlFlag || (exports.WasiFileControlFlag = {}));
var WasiFdFlag;
(function (WasiFdFlag) {
WasiFdFlag[WasiFdFlag["APPEND"] = 1] = "APPEND";
WasiFdFlag[WasiFdFlag["DSYNC"] = 2] = "DSYNC";
WasiFdFlag[WasiFdFlag["NONBLOCK"] = 4] = "NONBLOCK";
WasiFdFlag[WasiFdFlag["RSYNC"] = 8] = "RSYNC";
WasiFdFlag[WasiFdFlag["SYNC"] = 16] = "SYNC";
})(WasiFdFlag = exports.WasiFdFlag || (exports.WasiFdFlag = {}));
var WasiClockid;
(function (WasiClockid) {
WasiClockid[WasiClockid["REALTIME"] = 0] = "REALTIME";
WasiClockid[WasiClockid["MONOTONIC"] = 1] = "MONOTONIC";
WasiClockid[WasiClockid["PROCESS_CPUTIME_ID"] = 2] = "PROCESS_CPUTIME_ID";
WasiClockid[WasiClockid["THREAD_CPUTIME_ID"] = 3] = "THREAD_CPUTIME_ID";
})(WasiClockid = exports.WasiClockid || (exports.WasiClockid = {}));
var WasiFstFlag;
(function (WasiFstFlag) {
WasiFstFlag[WasiFstFlag["SET_ATIM"] = 1] = "SET_ATIM";
WasiFstFlag[WasiFstFlag["SET_ATIM_NOW"] = 2] = "SET_ATIM_NOW";
WasiFstFlag[WasiFstFlag["SET_MTIM"] = 4] = "SET_MTIM";
WasiFstFlag[WasiFstFlag["SET_MTIM_NOW"] = 8] = "SET_MTIM_NOW";
})(WasiFstFlag = exports.WasiFstFlag || (exports.WasiFstFlag = {}));
var WasiEventType;
(function (WasiEventType) {
WasiEventType[WasiEventType["CLOCK"] = 0] = "CLOCK";
WasiEventType[WasiEventType["FD_READ"] = 1] = "FD_READ";
WasiEventType[WasiEventType["FD_WRITE"] = 2] = "FD_WRITE";
})(WasiEventType = exports.WasiEventType || (exports.WasiEventType = {}));
var WasiSubclockflags;
(function (WasiSubclockflags) {
WasiSubclockflags[WasiSubclockflags["ABSTIME"] = 1] = "ABSTIME";
})(WasiSubclockflags = exports.WasiSubclockflags || (exports.WasiSubclockflags = {}));
//# sourceMappingURL=types.js.map

View file

@ -0,0 +1,128 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.unsharedSlice = exports.sleepBreakIf = exports.postMsg = exports.isMainThread = exports.wrapInstanceExports = exports.isPromiseLike = exports.validateInt32 = exports.validateUndefined = exports.validateFunction = exports.validateString = exports.validateBoolean = exports.validateArray = exports.validateObject = void 0;
/* eslint-disable spaced-comment */
function validateObject(value, name) {
if (value === null || typeof value !== 'object') {
throw new TypeError(`${name} must be an object. Received ${value === null ? 'null' : typeof value}`);
}
}
exports.validateObject = validateObject;
function validateArray(value, name) {
if (!Array.isArray(value)) {
throw new TypeError(`${name} must be an array. Received ${value === null ? 'null' : typeof value}`);
}
}
exports.validateArray = validateArray;
function validateBoolean(value, name) {
if (typeof value !== 'boolean') {
throw new TypeError(`${name} must be a boolean. Received ${value === null ? 'null' : typeof value}`);
}
}
exports.validateBoolean = validateBoolean;
function validateString(value, name) {
if (typeof value !== 'string') {
throw new TypeError(`${name} must be a string. Received ${value === null ? 'null' : typeof value}`);
}
}
exports.validateString = validateString;
function validateFunction(value, name) {
if (typeof value !== 'function') {
throw new TypeError(`${name} must be a function. Received ${value === null ? 'null' : typeof value}`);
}
}
exports.validateFunction = validateFunction;
function validateUndefined(value, name) {
if (value !== undefined) {
throw new TypeError(`${name} must be undefined. Received ${value === null ? 'null' : typeof value}`);
}
}
exports.validateUndefined = validateUndefined;
function validateInt32(value, name, min = -2147483648, max = 2147483647) {
if (typeof value !== 'number') {
throw new TypeError(`${name} must be a number. Received ${value === null ? 'null' : typeof value}`);
}
if (!Number.isInteger(value)) {
throw new RangeError(`${name} must be a integer.`);
}
if (value < min || value > max) {
throw new RangeError(`${name} must be >= ${min} && <= ${max}. Received ${value}`);
}
}
exports.validateInt32 = validateInt32;
function isPromiseLike(obj) {
return !!(obj && (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function');
}
exports.isPromiseLike = isPromiseLike;
function wrapInstanceExports(exports, mapFn) {
const newExports = Object.create(null);
Object.keys(exports).forEach(name => {
const exportValue = exports[name];
Object.defineProperty(newExports, name, {
enumerable: true,
value: mapFn(exportValue, name)
});
});
return newExports;
}
exports.wrapInstanceExports = wrapInstanceExports;
const _require = /*#__PURE__*/ (function () {
let nativeRequire;
if (typeof __webpack_public_path__ !== 'undefined') {
nativeRequire = (function () {
return typeof __non_webpack_require__ !== 'undefined' ? __non_webpack_require__ : undefined;
})();
}
else {
nativeRequire = (function () {
return typeof __webpack_public_path__ !== 'undefined' ? (typeof __non_webpack_require__ !== 'undefined' ? __non_webpack_require__ : undefined) : (typeof require !== 'undefined' ? require : undefined);
})();
}
return nativeRequire;
})();
exports.isMainThread = (function () {
let worker_threads;
try {
worker_threads = _require('worker_threads');
}
catch (_) { }
if (!worker_threads) {
return typeof importScripts === 'undefined';
}
return worker_threads.isMainThread;
})();
exports.postMsg = exports.isMainThread
? () => { }
: /*#__PURE__*/ (function () {
let worker_threads;
try {
worker_threads = _require('worker_threads');
}
catch (_) { }
if (!worker_threads) {
return postMessage;
}
return function postMessage(data) {
worker_threads.parentPort.postMessage({ data });
};
})();
function sleepBreakIf(delay, breakIf) {
const start = Date.now();
const end = start + delay;
let ret = false;
while (Date.now() < end) {
if (breakIf()) {
ret = true;
break;
}
}
return ret;
}
exports.sleepBreakIf = sleepBreakIf;
function unsharedSlice(view, start, end) {
return ((typeof SharedArrayBuffer === 'function' && view.buffer instanceof SharedArrayBuffer) || (Object.prototype.toString.call(view.buffer.constructor) === '[object SharedArrayBuffer]'))
? view.slice(start, end)
: view.subarray(start, end);
}
exports.unsharedSlice = unsharedSlice;
//# sourceMappingURL=util.js.map

View file

@ -0,0 +1,13 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports._WebAssembly = void 0;
const _WebAssembly = typeof WebAssembly !== 'undefined'
? WebAssembly
: typeof WXWebAssembly !== 'undefined'
? WXWebAssembly
: undefined;
exports._WebAssembly = _WebAssembly;
if (!_WebAssembly) {
throw new Error('WebAssembly is not supported in this environment');
}
//# sourceMappingURL=webassembly.js.map

View file

@ -0,0 +1,153 @@
import { _WebAssembly } from "./webassembly.mjs";
import { isPromiseLike, wrapInstanceExports } from "./wasi/util.mjs";
const ignoreNames = [
'asyncify_get_state',
'asyncify_start_rewind',
'asyncify_start_unwind',
'asyncify_stop_rewind',
'asyncify_stop_unwind'
];
// const wrappedExports = new WeakMap<WebAssembly.Exports, WebAssembly.Exports>()
var AsyncifyState;
(function (AsyncifyState) {
AsyncifyState[AsyncifyState["NONE"] = 0] = "NONE";
AsyncifyState[AsyncifyState["UNWINDING"] = 1] = "UNWINDING";
AsyncifyState[AsyncifyState["REWINDING"] = 2] = "REWINDING";
})(AsyncifyState || (AsyncifyState = {}));
function tryAllocate(instance, wasm64, size, mallocName) {
if (typeof instance.exports[mallocName] !== 'function' || size <= 0) {
return {
wasm64,
dataPtr: 16,
start: wasm64 ? 32 : 24,
end: 1024
};
}
const malloc = instance.exports[mallocName];
const dataPtr = wasm64 ? Number(malloc(BigInt(16) + BigInt(size))) : malloc(8 + size);
if (dataPtr === 0) {
throw new Error('Allocate asyncify data failed');
}
return wasm64
? { wasm64, dataPtr, start: dataPtr + 16, end: dataPtr + 16 + size }
: { wasm64, dataPtr, start: dataPtr + 8, end: dataPtr + 8 + size };
}
/** @public */
export class Asyncify {
constructor() {
this.value = undefined;
this.exports = undefined;
this.dataPtr = 0;
}
init(memory, instance, options) {
var _a, _b;
if (this.exports) {
throw new Error('Asyncify has been initialized');
}
if (!(memory instanceof _WebAssembly.Memory)) {
throw new TypeError('Require WebAssembly.Memory object');
}
const exports = instance.exports;
for (let i = 0; i < ignoreNames.length; ++i) {
if (typeof exports[ignoreNames[i]] !== 'function') {
throw new TypeError('Invalid asyncify wasm');
}
}
let address;
const wasm64 = Boolean(options.wasm64);
if (!options.tryAllocate) {
address = {
wasm64,
dataPtr: 16,
start: wasm64 ? 32 : 24,
end: 1024
};
}
else {
if (options.tryAllocate === true) {
address = tryAllocate(instance, wasm64, 4096, 'malloc');
}
else {
address = tryAllocate(instance, wasm64, (_a = options.tryAllocate.size) !== null && _a !== void 0 ? _a : 4096, (_b = options.tryAllocate.name) !== null && _b !== void 0 ? _b : 'malloc');
}
}
this.dataPtr = address.dataPtr;
if (wasm64) {
new BigInt64Array(memory.buffer, this.dataPtr).set([BigInt(address.start), BigInt(address.end)]);
}
else {
new Int32Array(memory.buffer, this.dataPtr).set([address.start, address.end]);
}
this.exports = this.wrapExports(exports, options.wrapExports);
const asyncifiedInstance = Object.create(_WebAssembly.Instance.prototype);
Object.defineProperty(asyncifiedInstance, 'exports', { value: this.exports });
// Object.setPrototypeOf(instance, Instance.prototype)
return asyncifiedInstance;
}
assertState() {
if (this.exports.asyncify_get_state() !== AsyncifyState.NONE) {
throw new Error('Asyncify state error');
}
}
wrapImportFunction(f) {
// eslint-disable-next-line @typescript-eslint/no-this-alias
const _this = this;
return (function () {
// eslint-disable-next-line no-unreachable-loop
while (_this.exports.asyncify_get_state() === AsyncifyState.REWINDING) {
_this.exports.asyncify_stop_rewind();
return _this.value;
}
_this.assertState();
const v = f.apply(this, arguments);
if (!isPromiseLike(v))
return v;
_this.exports.asyncify_start_unwind(_this.dataPtr);
_this.value = v;
});
}
wrapImports(imports) {
const importObject = {};
Object.keys(imports).forEach(k => {
const mod = imports[k];
const newModule = {};
Object.keys(mod).forEach(name => {
const importValue = mod[name];
if (typeof importValue === 'function') {
newModule[name] = this.wrapImportFunction(importValue);
}
else {
newModule[name] = importValue;
}
});
importObject[k] = newModule;
});
return importObject;
}
wrapExportFunction(f) {
// eslint-disable-next-line @typescript-eslint/no-this-alias
const _this = this;
return (async function () {
_this.assertState();
let ret = f.apply(this, arguments);
while (_this.exports.asyncify_get_state() === AsyncifyState.UNWINDING) {
_this.exports.asyncify_stop_unwind();
_this.value = await _this.value;
_this.assertState();
_this.exports.asyncify_start_rewind(_this.dataPtr);
ret = f.call(this);
}
_this.assertState();
return ret;
});
}
wrapExports(exports, needWrap) {
return wrapInstanceExports(exports, (exportValue, name) => {
let ignore = ignoreNames.indexOf(name) !== -1 || typeof exportValue !== 'function';
if (Array.isArray(needWrap)) {
ignore = ignore || (needWrap.indexOf(name) === -1);
}
return ignore ? exportValue : this.wrapExportFunction(exportValue);
});
}
}

View file

@ -0,0 +1,9 @@
/**
* @packageDocumentation
*/
export * from "./asyncify.mjs";
export * from "./load.mjs";
export * from "./wasi/index.mjs";
export * from "./memory.mjs";
export * from "./jspi.mjs";
export * from "./wasi/fs.mjs";

View file

@ -0,0 +1,39 @@
import { wrapInstanceExports } from "./wasi/util.mjs";
import { _WebAssembly } from "./webassembly.mjs";
function checkWebAssemblyFunction() {
const WebAssemblyFunction = _WebAssembly.Function;
if (typeof WebAssemblyFunction !== 'function') {
throw new Error('WebAssembly.Function is not supported in this environment.' +
' If you are using V8 based browser like Chrome, try to specify' +
' --js-flags="--wasm-staging --experimental-wasm-stack-switching"');
}
return WebAssemblyFunction;
}
/** @public */
export function wrapAsyncImport(f, parameterType, returnType) {
const WebAssemblyFunction = checkWebAssemblyFunction();
if (typeof f !== 'function') {
throw new TypeError('Function required');
}
const parameters = parameterType.slice(0);
parameters.unshift('externref');
return new WebAssemblyFunction({ parameters, results: returnType }, f, { suspending: 'first' });
}
/** @public */
export function wrapAsyncExport(f) {
const WebAssemblyFunction = checkWebAssemblyFunction();
if (typeof f !== 'function') {
throw new TypeError('Function required');
}
return new WebAssemblyFunction({ parameters: [...WebAssemblyFunction.type(f).parameters.slice(1)], results: ['externref'] }, f, { promising: 'first' });
}
/** @public */
export function wrapExports(exports, needWrap) {
return wrapInstanceExports(exports, (exportValue, name) => {
let ignore = typeof exportValue !== 'function';
if (Array.isArray(needWrap)) {
ignore = ignore || (needWrap.indexOf(name) === -1);
}
return ignore ? exportValue : wrapAsyncExport(exportValue);
});
}

View file

@ -0,0 +1,89 @@
import { _WebAssembly } from "./webassembly.mjs";
import { Asyncify } from "./asyncify.mjs";
function validateImports(imports) {
if (imports && typeof imports !== 'object') {
throw new TypeError('imports must be an object or undefined');
}
}
function fetchWasm(urlOrBuffer, imports) {
if (typeof wx !== 'undefined' && typeof __wxConfig !== 'undefined') {
return _WebAssembly.instantiate(urlOrBuffer, imports);
}
return fetch(urlOrBuffer)
.then(response => response.arrayBuffer())
.then(buffer => _WebAssembly.instantiate(buffer, imports));
}
/** @public */
export function load(wasmInput, imports) {
validateImports(imports);
imports = imports !== null && imports !== void 0 ? imports : {};
let source;
if (wasmInput instanceof ArrayBuffer || ArrayBuffer.isView(wasmInput)) {
return _WebAssembly.instantiate(wasmInput, imports);
}
if (wasmInput instanceof _WebAssembly.Module) {
return _WebAssembly.instantiate(wasmInput, imports).then((instance) => {
return { instance, module: wasmInput };
});
}
if (typeof wasmInput !== 'string' && !(wasmInput instanceof URL)) {
throw new TypeError('Invalid source');
}
if (typeof _WebAssembly.instantiateStreaming === 'function') {
let responsePromise;
try {
responsePromise = fetch(wasmInput);
source = _WebAssembly.instantiateStreaming(responsePromise, imports).catch(() => {
return fetchWasm(wasmInput, imports);
});
}
catch (_) {
source = fetchWasm(wasmInput, imports);
}
}
else {
source = fetchWasm(wasmInput, imports);
}
return source;
}
/** @public */
export function asyncifyLoad(asyncify, urlOrBuffer, imports) {
validateImports(imports);
imports = imports !== null && imports !== void 0 ? imports : {};
const asyncifyHelper = new Asyncify();
imports = asyncifyHelper.wrapImports(imports);
return load(urlOrBuffer, imports).then(source => {
var _a;
const memory = source.instance.exports.memory || ((_a = imports.env) === null || _a === void 0 ? void 0 : _a.memory);
return { module: source.module, instance: asyncifyHelper.init(memory, source.instance, asyncify) };
});
}
/** @public */
export function loadSync(wasmInput, imports) {
validateImports(imports);
imports = imports !== null && imports !== void 0 ? imports : {};
let module;
if ((wasmInput instanceof ArrayBuffer) || ArrayBuffer.isView(wasmInput)) {
module = new _WebAssembly.Module(wasmInput);
}
else if (wasmInput instanceof WebAssembly.Module) {
module = wasmInput;
}
else {
throw new TypeError('Invalid source');
}
const instance = new _WebAssembly.Instance(module, imports);
const source = { instance, module };
return source;
}
/** @public */
export function asyncifyLoadSync(asyncify, buffer, imports) {
var _a;
validateImports(imports);
imports = imports !== null && imports !== void 0 ? imports : {};
const asyncifyHelper = new Asyncify();
imports = asyncifyHelper.wrapImports(imports);
const source = loadSync(buffer, imports);
const memory = source.instance.exports.memory || ((_a = imports.env) === null || _a === void 0 ? void 0 : _a.memory);
return { module: source.module, instance: asyncifyHelper.init(memory, source.instance, asyncify) };
}

View file

@ -0,0 +1,28 @@
import { _WebAssembly } from "./webassembly.mjs";
/** @public */
export const WebAssemblyMemory = /*#__PURE__*/ (function () { return _WebAssembly.Memory; })();
/** @public */
export class Memory extends WebAssemblyMemory {
// eslint-disable-next-line @typescript-eslint/no-useless-constructor
constructor(descriptor) {
super(descriptor);
}
get HEAP8() { return new Int8Array(super.buffer); }
get HEAPU8() { return new Uint8Array(super.buffer); }
get HEAP16() { return new Int16Array(super.buffer); }
get HEAPU16() { return new Uint16Array(super.buffer); }
get HEAP32() { return new Int32Array(super.buffer); }
get HEAPU32() { return new Uint32Array(super.buffer); }
get HEAP64() { return new BigInt64Array(super.buffer); }
get HEAPU64() { return new BigUint64Array(super.buffer); }
get HEAPF32() { return new Float32Array(super.buffer); }
get HEAPF64() { return new Float64Array(super.buffer); }
get view() { return new DataView(super.buffer); }
}
/** @public */
export function extendMemory(memory) {
if (Object.getPrototypeOf(memory) === _WebAssembly.Memory.prototype) {
Object.setPrototypeOf(memory, Memory.prototype);
}
return memory;
}

View file

@ -0,0 +1,97 @@
import { WasiErrno } from "./types.mjs";
export function strerror(errno) {
switch (errno) {
case WasiErrno.ESUCCESS: return 'Success';
case WasiErrno.E2BIG: return 'Argument list too long';
case WasiErrno.EACCES: return 'Permission denied';
case WasiErrno.EADDRINUSE: return 'Address in use';
case WasiErrno.EADDRNOTAVAIL: return 'Address not available';
case WasiErrno.EAFNOSUPPORT: return 'Address family not supported by protocol';
case WasiErrno.EAGAIN: return 'Resource temporarily unavailable';
case WasiErrno.EALREADY: return 'Operation already in progress';
case WasiErrno.EBADF: return 'Bad file descriptor';
case WasiErrno.EBADMSG: return 'Bad message';
case WasiErrno.EBUSY: return 'Resource busy';
case WasiErrno.ECANCELED: return 'Operation canceled';
case WasiErrno.ECHILD: return 'No child process';
case WasiErrno.ECONNABORTED: return 'Connection aborted';
case WasiErrno.ECONNREFUSED: return 'Connection refused';
case WasiErrno.ECONNRESET: return 'Connection reset by peer';
case WasiErrno.EDEADLK: return 'Resource deadlock would occur';
case WasiErrno.EDESTADDRREQ: return 'Destination address required';
case WasiErrno.EDOM: return 'Domain error';
case WasiErrno.EDQUOT: return 'Quota exceeded';
case WasiErrno.EEXIST: return 'File exists';
case WasiErrno.EFAULT: return 'Bad address';
case WasiErrno.EFBIG: return 'File too large';
case WasiErrno.EHOSTUNREACH: return 'Host is unreachable';
case WasiErrno.EIDRM: return 'Identifier removed';
case WasiErrno.EILSEQ: return 'Illegal byte sequence';
case WasiErrno.EINPROGRESS: return 'Operation in progress';
case WasiErrno.EINTR: return 'Interrupted system call';
case WasiErrno.EINVAL: return 'Invalid argument';
case WasiErrno.EIO: return 'I/O error';
case WasiErrno.EISCONN: return 'Socket is connected';
case WasiErrno.EISDIR: return 'Is a directory';
case WasiErrno.ELOOP: return 'Symbolic link loop';
case WasiErrno.EMFILE: return 'No file descriptors available';
case WasiErrno.EMLINK: return 'Too many links';
case WasiErrno.EMSGSIZE: return 'Message too large';
case WasiErrno.EMULTIHOP: return 'Multihop attempted';
case WasiErrno.ENAMETOOLONG: return 'Filename too long';
case WasiErrno.ENETDOWN: return 'Network is down';
case WasiErrno.ENETRESET: return 'Connection reset by network';
case WasiErrno.ENETUNREACH: return 'Network unreachable';
case WasiErrno.ENFILE: return 'Too many files open in system';
case WasiErrno.ENOBUFS: return 'No buffer space available';
case WasiErrno.ENODEV: return 'No such device';
case WasiErrno.ENOENT: return 'No such file or directory';
case WasiErrno.ENOEXEC: return 'Exec format error';
case WasiErrno.ENOLCK: return 'No locks available';
case WasiErrno.ENOLINK: return 'Link has been severed';
case WasiErrno.ENOMEM: return 'Out of memory';
case WasiErrno.ENOMSG: return 'No message of the desired type';
case WasiErrno.ENOPROTOOPT: return 'Protocol not available';
case WasiErrno.ENOSPC: return 'No space left on device';
case WasiErrno.ENOSYS: return 'Function not implemented';
case WasiErrno.ENOTCONN: return 'Socket not connected';
case WasiErrno.ENOTDIR: return 'Not a directory';
case WasiErrno.ENOTEMPTY: return 'Directory not empty';
case WasiErrno.ENOTRECOVERABLE: return 'State not recoverable';
case WasiErrno.ENOTSOCK: return 'Not a socket';
case WasiErrno.ENOTSUP: return 'Not supported';
case WasiErrno.ENOTTY: return 'Not a tty';
case WasiErrno.ENXIO: return 'No such device or address';
case WasiErrno.EOVERFLOW: return 'Value too large for data type';
case WasiErrno.EOWNERDEAD: return 'Previous owner died';
case WasiErrno.EPERM: return 'Operation not permitted';
case WasiErrno.EPIPE: return 'Broken pipe';
case WasiErrno.EPROTO: return 'Protocol error';
case WasiErrno.EPROTONOSUPPORT: return 'Protocol not supported';
case WasiErrno.EPROTOTYPE: return 'Protocol wrong type for socket';
case WasiErrno.ERANGE: return 'Result not representable';
case WasiErrno.EROFS: return 'Read-only file system';
case WasiErrno.ESPIPE: return 'Invalid seek';
case WasiErrno.ESRCH: return 'No such process';
case WasiErrno.ESTALE: return 'Stale file handle';
case WasiErrno.ETIMEDOUT: return 'Operation timed out';
case WasiErrno.ETXTBSY: return 'Text file busy';
case WasiErrno.EXDEV: return 'Cross-device link';
case WasiErrno.ENOTCAPABLE: return 'Capabilities insufficient';
default: return 'Unknown error';
}
}
export class WasiError extends Error {
constructor(message, errno) {
super(message);
this.errno = errno;
}
getErrorMessage() {
return strerror(this.errno);
}
}
Object.defineProperty(WasiError.prototype, 'name', {
configurable: true,
writable: true,
value: 'WasiError'
});

View file

@ -0,0 +1,256 @@
import { WasiErrno, FileControlFlag, WasiFileType, WasiWhence } from "./types.mjs";
import { getRights } from "./rights.mjs";
import { WasiError } from "./error.mjs";
export function concatBuffer(buffers, size) {
let total = 0;
if (typeof size === 'number' && size >= 0) {
total = size;
}
else {
for (let i = 0; i < buffers.length; i++) {
const buffer = buffers[i];
total += buffer.length;
}
}
let pos = 0;
const ret = new Uint8Array(total);
for (let i = 0; i < buffers.length; i++) {
const buffer = buffers[i];
ret.set(buffer, pos);
pos += buffer.length;
}
return ret;
}
export class FileDescriptor {
constructor(id, fd, path, realPath, type, rightsBase, rightsInheriting, preopen) {
this.id = id;
this.fd = fd;
this.path = path;
this.realPath = realPath;
this.type = type;
this.rightsBase = rightsBase;
this.rightsInheriting = rightsInheriting;
this.preopen = preopen;
this.pos = BigInt(0);
this.size = BigInt(0);
}
seek(offset, whence) {
if (whence === WasiWhence.SET) {
this.pos = BigInt(offset);
}
else if (whence === WasiWhence.CUR) {
this.pos += BigInt(offset);
}
else if (whence === WasiWhence.END) {
this.pos = BigInt(this.size) - BigInt(offset);
}
else {
throw new WasiError('Unknown whence', WasiErrno.EIO);
}
return this.pos;
}
}
export class StandardOutput extends FileDescriptor {
constructor(log, id, fd, path, realPath, type, rightsBase, rightsInheriting, preopen) {
super(id, fd, path, realPath, type, rightsBase, rightsInheriting, preopen);
this._log = log;
this._buf = null;
}
write(buffer) {
const originalBuffer = buffer;
if (this._buf) {
buffer = concatBuffer([this._buf, buffer]);
this._buf = null;
}
if (buffer.indexOf(10) === -1) {
this._buf = buffer;
return originalBuffer.byteLength;
}
let written = 0;
let lastBegin = 0;
let index;
while ((index = buffer.indexOf(10, written)) !== -1) {
const str = new TextDecoder().decode(buffer.subarray(lastBegin, index));
this._log(str);
written += index - lastBegin + 1;
lastBegin = index + 1;
}
if (written < buffer.length) {
this._buf = buffer.slice(written);
}
return originalBuffer.byteLength;
}
}
export function toFileType(stat) {
if (stat.isBlockDevice())
return WasiFileType.BLOCK_DEVICE;
if (stat.isCharacterDevice())
return WasiFileType.CHARACTER_DEVICE;
if (stat.isDirectory())
return WasiFileType.DIRECTORY;
if (stat.isSocket())
return WasiFileType.SOCKET_STREAM;
if (stat.isFile())
return WasiFileType.REGULAR_FILE;
if (stat.isSymbolicLink())
return WasiFileType.SYMBOLIC_LINK;
return WasiFileType.UNKNOWN;
}
export function toFileStat(view, buf, stat) {
view.setBigUint64(buf, stat.dev, true);
view.setBigUint64(buf + 8, stat.ino, true);
view.setBigUint64(buf + 16, BigInt(toFileType(stat)), true);
view.setBigUint64(buf + 24, stat.nlink, true);
view.setBigUint64(buf + 32, stat.size, true);
view.setBigUint64(buf + 40, stat.atimeMs * BigInt(1000000), true);
view.setBigUint64(buf + 48, stat.mtimeMs * BigInt(1000000), true);
view.setBigUint64(buf + 56, stat.ctimeMs * BigInt(1000000), true);
}
export class FileDescriptorTable {
constructor(options) {
this.used = 0;
this.size = options.size;
this.fds = Array(options.size);
this.stdio = [options.in, options.out, options.err];
this.print = options.print;
this.printErr = options.printErr;
this.insertStdio(options.in, 0, '<stdin>');
this.insertStdio(options.out, 1, '<stdout>');
this.insertStdio(options.err, 2, '<stderr>');
}
insertStdio(fd, expected, name) {
const type = WasiFileType.CHARACTER_DEVICE;
const { base, inheriting } = getRights(this.stdio, fd, FileControlFlag.O_RDWR, type);
const wrap = this.insert(fd, name, name, type, base, inheriting, 0);
if (wrap.id !== expected) {
throw new WasiError(`id: ${wrap.id} !== expected: ${expected}`, WasiErrno.EBADF);
}
return wrap;
}
insert(fd, mappedPath, realPath, type, rightsBase, rightsInheriting, preopen) {
var _a, _b;
let index = -1;
if (this.used >= this.size) {
const newSize = this.size * 2;
this.fds.length = newSize;
index = this.size;
this.size = newSize;
}
else {
for (let i = 0; i < this.size; ++i) {
if (this.fds[i] == null) {
index = i;
break;
}
}
}
let entry;
if (mappedPath === '<stdout>') {
entry = new StandardOutput((_a = this.print) !== null && _a !== void 0 ? _a : console.log, index, fd, mappedPath, realPath, type, rightsBase, rightsInheriting, preopen);
}
else if (mappedPath === '<stderr>') {
entry = new StandardOutput((_b = this.printErr) !== null && _b !== void 0 ? _b : console.error, index, fd, mappedPath, realPath, type, rightsBase, rightsInheriting, preopen);
}
else {
entry = new FileDescriptor(index, fd, mappedPath, realPath, type, rightsBase, rightsInheriting, preopen);
}
this.fds[index] = entry;
this.used++;
return entry;
}
get(id, base, inheriting) {
if (id >= this.size) {
throw new WasiError('Invalid fd', WasiErrno.EBADF);
}
const entry = this.fds[id];
if (!entry || entry.id !== id) {
throw new WasiError('Bad file descriptor', WasiErrno.EBADF);
}
/* Validate that the fd has the necessary rights. */
if ((~entry.rightsBase & base) !== BigInt(0) || (~entry.rightsInheriting & inheriting) !== BigInt(0)) {
throw new WasiError('Capabilities insufficient', WasiErrno.ENOTCAPABLE);
}
return entry;
}
remove(id) {
if (id >= this.size) {
throw new WasiError('Invalid fd', WasiErrno.EBADF);
}
const entry = this.fds[id];
if (!entry || entry.id !== id) {
throw new WasiError('Bad file descriptor', WasiErrno.EBADF);
}
this.fds[id] = undefined;
this.used--;
}
}
export class SyncTable extends FileDescriptorTable {
constructor(options) {
super(options);
this.fs = options.fs;
}
getFileTypeByFd(fd) {
const stats = this.fs.fstatSync(fd, { bigint: true });
return toFileType(stats);
}
insertPreopen(fd, mappedPath, realPath) {
const type = this.getFileTypeByFd(fd);
if (type !== WasiFileType.DIRECTORY) {
throw new WasiError(`Preopen not dir: ["${mappedPath}", "${realPath}"]`, WasiErrno.ENOTDIR);
}
const result = getRights(this.stdio, fd, 0, type);
return this.insert(fd, mappedPath, realPath, type, result.base, result.inheriting, 1);
}
renumber(dst, src) {
if (dst === src)
return;
if (dst >= this.size || src >= this.size) {
throw new WasiError('Invalid fd', WasiErrno.EBADF);
}
const dstEntry = this.fds[dst];
const srcEntry = this.fds[src];
if (!dstEntry || !srcEntry || dstEntry.id !== dst || srcEntry.id !== src) {
throw new WasiError('Invalid fd', WasiErrno.EBADF);
}
this.fs.closeSync(dstEntry.fd);
this.fds[dst] = this.fds[src];
this.fds[dst].id = dst;
this.fds[src] = undefined;
this.used--;
}
}
export class AsyncTable extends FileDescriptorTable {
// eslint-disable-next-line @typescript-eslint/no-useless-constructor
constructor(options) {
super(options);
}
async getFileTypeByFd(fd) {
const stats = await fd.stat({ bigint: true });
return toFileType(stats);
}
async insertPreopen(fd, mappedPath, realPath) {
const type = await this.getFileTypeByFd(fd);
if (type !== WasiFileType.DIRECTORY) {
throw new WasiError(`Preopen not dir: ["${mappedPath}", "${realPath}"]`, WasiErrno.ENOTDIR);
}
const result = getRights(this.stdio, fd.fd, 0, type);
return this.insert(fd, mappedPath, realPath, type, result.base, result.inheriting, 1);
}
async renumber(dst, src) {
if (dst === src)
return;
if (dst >= this.size || src >= this.size) {
throw new WasiError('Invalid fd', WasiErrno.EBADF);
}
const dstEntry = this.fds[dst];
const srcEntry = this.fds[src];
if (!dstEntry || !srcEntry || dstEntry.id !== dst || srcEntry.id !== src) {
throw new WasiError('Invalid fd', WasiErrno.EBADF);
}
await dstEntry.fd.close();
this.fds[dst] = this.fds[src];
this.fds[dst].id = dst;
this.fds[src] = undefined;
this.used--;
}
}

View file

@ -0,0 +1 @@
export {};

View file

@ -0,0 +1,186 @@
import { WASI as WASIPreview1 } from "./preview1.mjs";
import { validateObject, validateArray, validateBoolean, validateFunction, validateUndefined, validateString } from "./util.mjs";
// eslint-disable-next-line spaced-comment
const kEmptyObject = /*#__PURE__*/ Object.freeze(/*#__PURE__*/ Object.create(null));
const kExitCode = Symbol('kExitCode');
const kSetMemory = Symbol('kSetMemory');
const kStarted = Symbol('kStarted');
const kInstance = Symbol('kInstance');
const kBindingName = Symbol('kBindingName');
function validateOptions(options) {
var _a;
validateObject(options, 'options');
let _WASI;
if (options.version !== undefined) {
validateString(options.version, 'options.version');
switch (options.version) {
case 'unstable':
_WASI = WASIPreview1;
this[kBindingName] = 'wasi_unstable';
break;
case 'preview1':
_WASI = WASIPreview1;
this[kBindingName] = 'wasi_snapshot_preview1';
break;
default:
throw new TypeError(`unsupported WASI version "${options.version}"`);
}
}
else {
_WASI = WASIPreview1;
this[kBindingName] = 'wasi_snapshot_preview1';
}
if (options.args !== undefined) {
validateArray(options.args, 'options.args');
}
const args = ((_a = options.args) !== null && _a !== void 0 ? _a : []).map(String);
const env = [];
if (options.env !== undefined) {
validateObject(options.env, 'options.env');
Object.entries(options.env).forEach(({ 0: key, 1: value }) => {
if (value !== undefined) {
env.push(`${key}=${value}`);
}
});
}
const preopens = [];
if (options.preopens !== undefined) {
validateObject(options.preopens, 'options.preopens');
Object.entries(options.preopens).forEach(({ 0: key, 1: value }) => preopens.push({ mappedPath: String(key), realPath: String(value) }));
}
if (preopens.length > 0) {
if (options.fs === undefined) {
throw new Error('filesystem is disabled, can not preopen directory');
}
try {
validateObject(options.fs, 'options.fs');
}
catch (_) {
throw new TypeError('Node.js fs like implementation is not provided');
}
}
// if (options.filesystem !== undefined) {
// validateObject(options.filesystem, 'options.filesystem')
// validateString(options.filesystem.type, 'options.filesystem.type')
// if (options.filesystem.type !== 'memfs' && options.filesystem.type !== 'file-system-access-api') {
// throw new Error(`Filesystem type ${(options.filesystem as any).type as string} is not supported, only "memfs" and "file-system-access-api" is supported currently`)
// }
// try {
// validateObject(options.filesystem.fs, 'options.filesystem.fs')
// } catch (_) {
// throw new Error('Node.js fs like implementation is not provided')
// }
// }
if (options.print !== undefined)
validateFunction(options.print, 'options.print');
if (options.printErr !== undefined)
validateFunction(options.printErr, 'options.printErr');
if (options.returnOnExit !== undefined) {
validateBoolean(options.returnOnExit, 'options.returnOnExit');
}
// const { stdin = 0, stdout = 1, stderr = 2 } = options
// validateInt32(stdin, 'options.stdin', 0)
// validateInt32(stdout, 'options.stdout', 0)
// validateInt32(stderr, 'options.stderr', 0)
// const stdio = [stdin, stdout, stderr] as const
const stdio = [0, 1, 2];
return {
args,
env,
preopens,
stdio,
_WASI
};
}
function initWASI(setMemory, wrap) {
this[kSetMemory] = setMemory;
this.wasiImport = wrap;
this[kStarted] = false;
this[kExitCode] = 0;
this[kInstance] = undefined;
}
/** @public */
export class WASI {
constructor(options = kEmptyObject) {
const { args, env, preopens, stdio, _WASI } = validateOptions.call(this, options);
const wrap = _WASI.createSync(args, env, preopens, stdio, options.fs, options.print, options.printErr);
const setMemory = wrap._setMemory;
delete wrap._setMemory;
initWASI.call(this, setMemory, wrap);
if (options.returnOnExit) {
wrap.proc_exit = wasiReturnOnProcExit.bind(this);
}
}
finalizeBindings(instance, _a) {
var _b;
var { memory = (_b = instance === null || instance === void 0 ? void 0 : instance.exports) === null || _b === void 0 ? void 0 : _b.memory } = _a === void 0 ? {} : _a;
if (this[kStarted]) {
throw new Error('WASI instance has already started');
}
validateObject(instance, 'instance');
validateObject(instance.exports, 'instance.exports');
this[kSetMemory](memory);
this[kInstance] = instance;
this[kStarted] = true;
}
// Must not export _initialize, must export _start
start(instance) {
this.finalizeBindings(instance);
const { _start, _initialize } = this[kInstance].exports;
validateFunction(_start, 'instance.exports._start');
validateUndefined(_initialize, 'instance.exports._initialize');
let ret;
try {
ret = _start();
}
catch (err) {
if (err !== kExitCode) {
throw err;
}
}
if (ret instanceof Promise) {
return ret.then(() => this[kExitCode], (err) => {
if (err !== kExitCode) {
throw err;
}
return this[kExitCode];
});
}
return this[kExitCode];
}
// Must not export _start, may optionally export _initialize
initialize(instance) {
this.finalizeBindings(instance);
const { _start, _initialize } = this[kInstance].exports;
validateUndefined(_start, 'instance.exports._start');
if (_initialize !== undefined) {
validateFunction(_initialize, 'instance.exports._initialize');
return _initialize();
}
}
getImportObject() {
return { [this[kBindingName]]: this.wasiImport };
}
}
function wasiReturnOnProcExit(rval) {
this[kExitCode] = rval;
// eslint-disable-next-line @typescript-eslint/no-throw-literal
throw kExitCode;
}
/** @public */
export async function createAsyncWASI(options = kEmptyObject) {
const _this = Object.create(WASI.prototype);
const { args, env, preopens, stdio, _WASI } = validateOptions.call(_this, options);
if (options.asyncify !== undefined) {
validateObject(options.asyncify, 'options.asyncify');
validateFunction(options.asyncify.wrapImportFunction, 'options.asyncify.wrapImportFunction');
}
const wrap = await _WASI.createAsync(args, env, preopens, stdio, options.fs, options.print, options.printErr, options.asyncify);
const setMemory = wrap._setMemory;
delete wrap._setMemory;
initWASI.call(_this, setMemory, wrap);
if (options.returnOnExit) {
wrap.proc_exit = wasiReturnOnProcExit.bind(_this);
}
return _this;
}

View file

@ -0,0 +1,168 @@
import { validateString } from "./util.mjs";
const CHAR_DOT = 46; /* . */
const CHAR_FORWARD_SLASH = 47; /* / */
function isPosixPathSeparator(code) {
return code === CHAR_FORWARD_SLASH;
}
function normalizeString(path, allowAboveRoot, separator, isPathSeparator) {
let res = '';
let lastSegmentLength = 0;
let lastSlash = -1;
let dots = 0;
let code = 0;
for (let i = 0; i <= path.length; ++i) {
if (i < path.length) {
code = path.charCodeAt(i);
}
else if (isPathSeparator(code)) {
break;
}
else {
code = CHAR_FORWARD_SLASH;
}
if (isPathSeparator(code)) {
if (lastSlash === i - 1 || dots === 1) {
// NOOP
}
else if (dots === 2) {
if (res.length < 2 || lastSegmentLength !== 2 ||
res.charCodeAt(res.length - 1) !== CHAR_DOT ||
res.charCodeAt(res.length - 2) !== CHAR_DOT) {
if (res.length > 2) {
const lastSlashIndex = res.indexOf(separator);
if (lastSlashIndex === -1) {
res = '';
lastSegmentLength = 0;
}
else {
res = res.slice(0, lastSlashIndex);
lastSegmentLength =
res.length - 1 - res.indexOf(separator);
}
lastSlash = i;
dots = 0;
continue;
}
else if (res.length !== 0) {
res = '';
lastSegmentLength = 0;
lastSlash = i;
dots = 0;
continue;
}
}
if (allowAboveRoot) {
res += res.length > 0 ? `${separator}..` : '..';
lastSegmentLength = 2;
}
}
else {
if (res.length > 0) {
res += `${separator}${path.slice(lastSlash + 1, i)}`;
}
else {
res = path.slice(lastSlash + 1, i);
}
lastSegmentLength = i - lastSlash - 1;
}
lastSlash = i;
dots = 0;
}
else if (code === CHAR_DOT && dots !== -1) {
++dots;
}
else {
dots = -1;
}
}
return res;
}
export function resolve(...args) {
let resolvedPath = '';
let resolvedAbsolute = false;
for (let i = args.length - 1; i >= -1 && !resolvedAbsolute; i--) {
const path = i >= 0 ? args[i] : '/';
validateString(path, 'path');
// Skip empty entries
if (path.length === 0) {
continue;
}
resolvedPath = `${path}/${resolvedPath}`;
resolvedAbsolute = path.charCodeAt(0) === CHAR_FORWARD_SLASH;
}
// At this point the path should be resolved to a full absolute path, but
// handle relative paths to be safe (might happen when process.cwd() fails)
// Normalize the path
resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute, '/', isPosixPathSeparator);
if (resolvedAbsolute) {
return `/${resolvedPath}`;
}
return resolvedPath.length > 0 ? resolvedPath : '.';
}
export function relative(from, to) {
validateString(from, 'from');
validateString(to, 'to');
if (from === to)
return '';
// Trim leading forward slashes.
from = resolve(from);
to = resolve(to);
if (from === to)
return '';
const fromStart = 1;
const fromEnd = from.length;
const fromLen = fromEnd - fromStart;
const toStart = 1;
const toLen = to.length - toStart;
// Compare paths to find the longest common path from root
const length = (fromLen < toLen ? fromLen : toLen);
let lastCommonSep = -1;
let i = 0;
for (; i < length; i++) {
const fromCode = from.charCodeAt(fromStart + i);
if (fromCode !== to.charCodeAt(toStart + i)) {
break;
}
else if (fromCode === CHAR_FORWARD_SLASH) {
lastCommonSep = i;
}
}
if (i === length) {
if (toLen > length) {
if (to.charCodeAt(toStart + i) === CHAR_FORWARD_SLASH) {
// We get here if `from` is the exact base path for `to`.
// For example: from='/foo/bar'; to='/foo/bar/baz'
return to.slice(toStart + i + 1);
}
if (i === 0) {
// We get here if `from` is the root
// For example: from='/'; to='/foo'
return to.slice(toStart + i);
}
}
else if (fromLen > length) {
if (from.charCodeAt(fromStart + i) === CHAR_FORWARD_SLASH) {
// We get here if `to` is the exact base path for `from`.
// For example: from='/foo/bar/baz'; to='/foo/bar'
lastCommonSep = i;
}
else if (i === 0) {
// We get here if `to` is the root.
// For example: from='/foo/bar'; to='/'
lastCommonSep = 0;
}
}
}
let out = '';
// Generate the relative path based on the path difference between `to`
// and `from`.
for (i = fromStart + lastCommonSep + 1; i <= fromEnd; ++i) {
if (i === fromEnd ||
from.charCodeAt(i) === CHAR_FORWARD_SLASH) {
out += out.length === 0 ? '..' : '/..';
}
}
// Lastly, append the rest of the destination (`to`) path that comes after
// the common path parts.
return `${out}${to.slice(toStart + lastCommonSep)}`;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,135 @@
import { WasiError } from "./error.mjs";
import { WasiErrno, WasiRights, WasiFileType } from "./types.mjs";
export const RIGHTS_ALL = WasiRights.FD_DATASYNC |
WasiRights.FD_READ |
WasiRights.FD_SEEK |
WasiRights.FD_FDSTAT_SET_FLAGS |
WasiRights.FD_SYNC |
WasiRights.FD_TELL |
WasiRights.FD_WRITE |
WasiRights.FD_ADVISE |
WasiRights.FD_ALLOCATE |
WasiRights.PATH_CREATE_DIRECTORY |
WasiRights.PATH_CREATE_FILE |
WasiRights.PATH_LINK_SOURCE |
WasiRights.PATH_LINK_TARGET |
WasiRights.PATH_OPEN |
WasiRights.FD_READDIR |
WasiRights.PATH_READLINK |
WasiRights.PATH_RENAME_SOURCE |
WasiRights.PATH_RENAME_TARGET |
WasiRights.PATH_FILESTAT_GET |
WasiRights.PATH_FILESTAT_SET_SIZE |
WasiRights.PATH_FILESTAT_SET_TIMES |
WasiRights.FD_FILESTAT_GET |
WasiRights.FD_FILESTAT_SET_TIMES |
WasiRights.FD_FILESTAT_SET_SIZE |
WasiRights.PATH_SYMLINK |
WasiRights.PATH_UNLINK_FILE |
WasiRights.PATH_REMOVE_DIRECTORY |
WasiRights.POLL_FD_READWRITE |
WasiRights.SOCK_SHUTDOWN |
WasiRights.SOCK_ACCEPT;
export const BLOCK_DEVICE_BASE = RIGHTS_ALL;
export const BLOCK_DEVICE_INHERITING = RIGHTS_ALL;
export const CHARACTER_DEVICE_BASE = RIGHTS_ALL;
export const CHARACTER_DEVICE_INHERITING = RIGHTS_ALL;
export const REGULAR_FILE_BASE = WasiRights.FD_DATASYNC |
WasiRights.FD_READ |
WasiRights.FD_SEEK |
WasiRights.FD_FDSTAT_SET_FLAGS |
WasiRights.FD_SYNC |
WasiRights.FD_TELL |
WasiRights.FD_WRITE |
WasiRights.FD_ADVISE |
WasiRights.FD_ALLOCATE |
WasiRights.FD_FILESTAT_GET |
WasiRights.FD_FILESTAT_SET_SIZE |
WasiRights.FD_FILESTAT_SET_TIMES |
WasiRights.POLL_FD_READWRITE;
export const REGULAR_FILE_INHERITING = /*#__PURE__*/ BigInt(0);
export const DIRECTORY_BASE = WasiRights.FD_FDSTAT_SET_FLAGS |
WasiRights.FD_SYNC |
WasiRights.FD_ADVISE |
WasiRights.PATH_CREATE_DIRECTORY |
WasiRights.PATH_CREATE_FILE |
WasiRights.PATH_LINK_SOURCE |
WasiRights.PATH_LINK_TARGET |
WasiRights.PATH_OPEN |
WasiRights.FD_READDIR |
WasiRights.PATH_READLINK |
WasiRights.PATH_RENAME_SOURCE |
WasiRights.PATH_RENAME_TARGET |
WasiRights.PATH_FILESTAT_GET |
WasiRights.PATH_FILESTAT_SET_SIZE |
WasiRights.PATH_FILESTAT_SET_TIMES |
WasiRights.FD_FILESTAT_GET |
WasiRights.FD_FILESTAT_SET_TIMES |
WasiRights.PATH_SYMLINK |
WasiRights.PATH_UNLINK_FILE |
WasiRights.PATH_REMOVE_DIRECTORY |
WasiRights.POLL_FD_READWRITE;
export const DIRECTORY_INHERITING = DIRECTORY_BASE | REGULAR_FILE_BASE;
export const SOCKET_BASE = (WasiRights.FD_READ |
WasiRights.FD_FDSTAT_SET_FLAGS |
WasiRights.FD_WRITE |
WasiRights.FD_FILESTAT_GET |
WasiRights.POLL_FD_READWRITE |
WasiRights.SOCK_SHUTDOWN);
export const SOCKET_INHERITING = RIGHTS_ALL;
export const TTY_BASE = WasiRights.FD_READ |
WasiRights.FD_FDSTAT_SET_FLAGS |
WasiRights.FD_WRITE |
WasiRights.FD_FILESTAT_GET |
WasiRights.POLL_FD_READWRITE;
export const TTY_INHERITING = /*#__PURE__*/ BigInt(0);
export function getRights(stdio, fd, flags, type) {
const ret = {
base: BigInt(0),
inheriting: BigInt(0)
};
if (type === WasiFileType.UNKNOWN) {
throw new WasiError('Unknown file type', WasiErrno.EINVAL);
}
switch (type) {
case WasiFileType.REGULAR_FILE:
ret.base = REGULAR_FILE_BASE;
ret.inheriting = REGULAR_FILE_INHERITING;
break;
case WasiFileType.DIRECTORY:
ret.base = DIRECTORY_BASE;
ret.inheriting = DIRECTORY_INHERITING;
break;
case WasiFileType.SOCKET_STREAM:
case WasiFileType.SOCKET_DGRAM:
ret.base = SOCKET_BASE;
ret.inheriting = SOCKET_INHERITING;
break;
case WasiFileType.CHARACTER_DEVICE:
if (stdio.indexOf(fd) !== -1) {
ret.base = TTY_BASE;
ret.inheriting = TTY_INHERITING;
}
else {
ret.base = CHARACTER_DEVICE_BASE;
ret.inheriting = CHARACTER_DEVICE_INHERITING;
}
break;
case WasiFileType.BLOCK_DEVICE:
ret.base = BLOCK_DEVICE_BASE;
ret.inheriting = BLOCK_DEVICE_INHERITING;
break;
default:
ret.base = BigInt(0);
ret.inheriting = BigInt(0);
}
/* Disable read/write bits depending on access mode. */
const read_or_write_only = flags & (0 | 1 | 2);
if (read_or_write_only === 0) {
ret.base &= ~WasiRights.FD_WRITE;
}
else if (read_or_write_only === 1) {
ret.base &= ~WasiRights.FD_READ;
}
return ret;
}

View file

@ -0,0 +1,216 @@
/* eslint-disable spaced-comment */
export var WasiErrno;
(function (WasiErrno) {
WasiErrno[WasiErrno["ESUCCESS"] = 0] = "ESUCCESS";
WasiErrno[WasiErrno["E2BIG"] = 1] = "E2BIG";
WasiErrno[WasiErrno["EACCES"] = 2] = "EACCES";
WasiErrno[WasiErrno["EADDRINUSE"] = 3] = "EADDRINUSE";
WasiErrno[WasiErrno["EADDRNOTAVAIL"] = 4] = "EADDRNOTAVAIL";
WasiErrno[WasiErrno["EAFNOSUPPORT"] = 5] = "EAFNOSUPPORT";
WasiErrno[WasiErrno["EAGAIN"] = 6] = "EAGAIN";
WasiErrno[WasiErrno["EALREADY"] = 7] = "EALREADY";
WasiErrno[WasiErrno["EBADF"] = 8] = "EBADF";
WasiErrno[WasiErrno["EBADMSG"] = 9] = "EBADMSG";
WasiErrno[WasiErrno["EBUSY"] = 10] = "EBUSY";
WasiErrno[WasiErrno["ECANCELED"] = 11] = "ECANCELED";
WasiErrno[WasiErrno["ECHILD"] = 12] = "ECHILD";
WasiErrno[WasiErrno["ECONNABORTED"] = 13] = "ECONNABORTED";
WasiErrno[WasiErrno["ECONNREFUSED"] = 14] = "ECONNREFUSED";
WasiErrno[WasiErrno["ECONNRESET"] = 15] = "ECONNRESET";
WasiErrno[WasiErrno["EDEADLK"] = 16] = "EDEADLK";
WasiErrno[WasiErrno["EDESTADDRREQ"] = 17] = "EDESTADDRREQ";
WasiErrno[WasiErrno["EDOM"] = 18] = "EDOM";
WasiErrno[WasiErrno["EDQUOT"] = 19] = "EDQUOT";
WasiErrno[WasiErrno["EEXIST"] = 20] = "EEXIST";
WasiErrno[WasiErrno["EFAULT"] = 21] = "EFAULT";
WasiErrno[WasiErrno["EFBIG"] = 22] = "EFBIG";
WasiErrno[WasiErrno["EHOSTUNREACH"] = 23] = "EHOSTUNREACH";
WasiErrno[WasiErrno["EIDRM"] = 24] = "EIDRM";
WasiErrno[WasiErrno["EILSEQ"] = 25] = "EILSEQ";
WasiErrno[WasiErrno["EINPROGRESS"] = 26] = "EINPROGRESS";
WasiErrno[WasiErrno["EINTR"] = 27] = "EINTR";
WasiErrno[WasiErrno["EINVAL"] = 28] = "EINVAL";
WasiErrno[WasiErrno["EIO"] = 29] = "EIO";
WasiErrno[WasiErrno["EISCONN"] = 30] = "EISCONN";
WasiErrno[WasiErrno["EISDIR"] = 31] = "EISDIR";
WasiErrno[WasiErrno["ELOOP"] = 32] = "ELOOP";
WasiErrno[WasiErrno["EMFILE"] = 33] = "EMFILE";
WasiErrno[WasiErrno["EMLINK"] = 34] = "EMLINK";
WasiErrno[WasiErrno["EMSGSIZE"] = 35] = "EMSGSIZE";
WasiErrno[WasiErrno["EMULTIHOP"] = 36] = "EMULTIHOP";
WasiErrno[WasiErrno["ENAMETOOLONG"] = 37] = "ENAMETOOLONG";
WasiErrno[WasiErrno["ENETDOWN"] = 38] = "ENETDOWN";
WasiErrno[WasiErrno["ENETRESET"] = 39] = "ENETRESET";
WasiErrno[WasiErrno["ENETUNREACH"] = 40] = "ENETUNREACH";
WasiErrno[WasiErrno["ENFILE"] = 41] = "ENFILE";
WasiErrno[WasiErrno["ENOBUFS"] = 42] = "ENOBUFS";
WasiErrno[WasiErrno["ENODEV"] = 43] = "ENODEV";
WasiErrno[WasiErrno["ENOENT"] = 44] = "ENOENT";
WasiErrno[WasiErrno["ENOEXEC"] = 45] = "ENOEXEC";
WasiErrno[WasiErrno["ENOLCK"] = 46] = "ENOLCK";
WasiErrno[WasiErrno["ENOLINK"] = 47] = "ENOLINK";
WasiErrno[WasiErrno["ENOMEM"] = 48] = "ENOMEM";
WasiErrno[WasiErrno["ENOMSG"] = 49] = "ENOMSG";
WasiErrno[WasiErrno["ENOPROTOOPT"] = 50] = "ENOPROTOOPT";
WasiErrno[WasiErrno["ENOSPC"] = 51] = "ENOSPC";
WasiErrno[WasiErrno["ENOSYS"] = 52] = "ENOSYS";
WasiErrno[WasiErrno["ENOTCONN"] = 53] = "ENOTCONN";
WasiErrno[WasiErrno["ENOTDIR"] = 54] = "ENOTDIR";
WasiErrno[WasiErrno["ENOTEMPTY"] = 55] = "ENOTEMPTY";
WasiErrno[WasiErrno["ENOTRECOVERABLE"] = 56] = "ENOTRECOVERABLE";
WasiErrno[WasiErrno["ENOTSOCK"] = 57] = "ENOTSOCK";
WasiErrno[WasiErrno["ENOTSUP"] = 58] = "ENOTSUP";
WasiErrno[WasiErrno["ENOTTY"] = 59] = "ENOTTY";
WasiErrno[WasiErrno["ENXIO"] = 60] = "ENXIO";
WasiErrno[WasiErrno["EOVERFLOW"] = 61] = "EOVERFLOW";
WasiErrno[WasiErrno["EOWNERDEAD"] = 62] = "EOWNERDEAD";
WasiErrno[WasiErrno["EPERM"] = 63] = "EPERM";
WasiErrno[WasiErrno["EPIPE"] = 64] = "EPIPE";
WasiErrno[WasiErrno["EPROTO"] = 65] = "EPROTO";
WasiErrno[WasiErrno["EPROTONOSUPPORT"] = 66] = "EPROTONOSUPPORT";
WasiErrno[WasiErrno["EPROTOTYPE"] = 67] = "EPROTOTYPE";
WasiErrno[WasiErrno["ERANGE"] = 68] = "ERANGE";
WasiErrno[WasiErrno["EROFS"] = 69] = "EROFS";
WasiErrno[WasiErrno["ESPIPE"] = 70] = "ESPIPE";
WasiErrno[WasiErrno["ESRCH"] = 71] = "ESRCH";
WasiErrno[WasiErrno["ESTALE"] = 72] = "ESTALE";
WasiErrno[WasiErrno["ETIMEDOUT"] = 73] = "ETIMEDOUT";
WasiErrno[WasiErrno["ETXTBSY"] = 74] = "ETXTBSY";
WasiErrno[WasiErrno["EXDEV"] = 75] = "EXDEV";
WasiErrno[WasiErrno["ENOTCAPABLE"] = 76] = "ENOTCAPABLE";
})(WasiErrno || (WasiErrno = {}));
export var WasiFileType;
(function (WasiFileType) {
WasiFileType[WasiFileType["UNKNOWN"] = 0] = "UNKNOWN";
WasiFileType[WasiFileType["BLOCK_DEVICE"] = 1] = "BLOCK_DEVICE";
WasiFileType[WasiFileType["CHARACTER_DEVICE"] = 2] = "CHARACTER_DEVICE";
WasiFileType[WasiFileType["DIRECTORY"] = 3] = "DIRECTORY";
WasiFileType[WasiFileType["REGULAR_FILE"] = 4] = "REGULAR_FILE";
WasiFileType[WasiFileType["SOCKET_DGRAM"] = 5] = "SOCKET_DGRAM";
WasiFileType[WasiFileType["SOCKET_STREAM"] = 6] = "SOCKET_STREAM";
WasiFileType[WasiFileType["SYMBOLIC_LINK"] = 7] = "SYMBOLIC_LINK";
})(WasiFileType || (WasiFileType = {}));
const FD_DATASYNC = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(0));
const FD_READ = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(1));
const FD_SEEK = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(2));
const FD_FDSTAT_SET_FLAGS = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(3));
const FD_SYNC = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(4));
const FD_TELL = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(5));
const FD_WRITE = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(6));
const FD_ADVISE = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(7));
const FD_ALLOCATE = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(8));
const PATH_CREATE_DIRECTORY = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(9));
const PATH_CREATE_FILE = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(10));
const PATH_LINK_SOURCE = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(11));
const PATH_LINK_TARGET = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(12));
const PATH_OPEN = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(13));
const FD_READDIR = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(14));
const PATH_READLINK = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(15));
const PATH_RENAME_SOURCE = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(16));
const PATH_RENAME_TARGET = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(17));
const PATH_FILESTAT_GET = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(18));
const PATH_FILESTAT_SET_SIZE = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(19));
const PATH_FILESTAT_SET_TIMES = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(20));
const FD_FILESTAT_GET = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(21));
const FD_FILESTAT_SET_SIZE = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(22));
const FD_FILESTAT_SET_TIMES = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(23));
const PATH_SYMLINK = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(24));
const PATH_REMOVE_DIRECTORY = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(25));
const PATH_UNLINK_FILE = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(26));
const POLL_FD_READWRITE = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(27));
const SOCK_SHUTDOWN = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(28));
const SOCK_ACCEPT = ( /*#__PURE__*/BigInt(1) << /*#__PURE__*/ BigInt(29));
export const WasiRights = {
FD_DATASYNC,
FD_READ,
FD_SEEK,
FD_FDSTAT_SET_FLAGS,
FD_SYNC,
FD_TELL,
FD_WRITE,
FD_ADVISE,
FD_ALLOCATE,
PATH_CREATE_DIRECTORY,
PATH_CREATE_FILE,
PATH_LINK_SOURCE,
PATH_LINK_TARGET,
PATH_OPEN,
FD_READDIR,
PATH_READLINK,
PATH_RENAME_SOURCE,
PATH_RENAME_TARGET,
PATH_FILESTAT_GET,
PATH_FILESTAT_SET_SIZE,
PATH_FILESTAT_SET_TIMES,
FD_FILESTAT_GET,
FD_FILESTAT_SET_SIZE,
FD_FILESTAT_SET_TIMES,
PATH_SYMLINK,
PATH_REMOVE_DIRECTORY,
PATH_UNLINK_FILE,
POLL_FD_READWRITE,
SOCK_SHUTDOWN,
SOCK_ACCEPT
};
export var WasiWhence;
(function (WasiWhence) {
WasiWhence[WasiWhence["SET"] = 0] = "SET";
WasiWhence[WasiWhence["CUR"] = 1] = "CUR";
WasiWhence[WasiWhence["END"] = 2] = "END";
})(WasiWhence || (WasiWhence = {}));
export var FileControlFlag;
(function (FileControlFlag) {
FileControlFlag[FileControlFlag["O_RDONLY"] = 0] = "O_RDONLY";
FileControlFlag[FileControlFlag["O_WRONLY"] = 1] = "O_WRONLY";
FileControlFlag[FileControlFlag["O_RDWR"] = 2] = "O_RDWR";
FileControlFlag[FileControlFlag["O_CREAT"] = 64] = "O_CREAT";
FileControlFlag[FileControlFlag["O_EXCL"] = 128] = "O_EXCL";
FileControlFlag[FileControlFlag["O_NOCTTY"] = 256] = "O_NOCTTY";
FileControlFlag[FileControlFlag["O_TRUNC"] = 512] = "O_TRUNC";
FileControlFlag[FileControlFlag["O_APPEND"] = 1024] = "O_APPEND";
FileControlFlag[FileControlFlag["O_DIRECTORY"] = 65536] = "O_DIRECTORY";
FileControlFlag[FileControlFlag["O_NOATIME"] = 262144] = "O_NOATIME";
FileControlFlag[FileControlFlag["O_NOFOLLOW"] = 131072] = "O_NOFOLLOW";
FileControlFlag[FileControlFlag["O_SYNC"] = 1052672] = "O_SYNC";
FileControlFlag[FileControlFlag["O_DIRECT"] = 16384] = "O_DIRECT";
FileControlFlag[FileControlFlag["O_NONBLOCK"] = 2048] = "O_NONBLOCK";
})(FileControlFlag || (FileControlFlag = {}));
export var WasiFileControlFlag;
(function (WasiFileControlFlag) {
WasiFileControlFlag[WasiFileControlFlag["O_CREAT"] = 1] = "O_CREAT";
WasiFileControlFlag[WasiFileControlFlag["O_DIRECTORY"] = 2] = "O_DIRECTORY";
WasiFileControlFlag[WasiFileControlFlag["O_EXCL"] = 4] = "O_EXCL";
WasiFileControlFlag[WasiFileControlFlag["O_TRUNC"] = 8] = "O_TRUNC";
})(WasiFileControlFlag || (WasiFileControlFlag = {}));
export var WasiFdFlag;
(function (WasiFdFlag) {
WasiFdFlag[WasiFdFlag["APPEND"] = 1] = "APPEND";
WasiFdFlag[WasiFdFlag["DSYNC"] = 2] = "DSYNC";
WasiFdFlag[WasiFdFlag["NONBLOCK"] = 4] = "NONBLOCK";
WasiFdFlag[WasiFdFlag["RSYNC"] = 8] = "RSYNC";
WasiFdFlag[WasiFdFlag["SYNC"] = 16] = "SYNC";
})(WasiFdFlag || (WasiFdFlag = {}));
export var WasiClockid;
(function (WasiClockid) {
WasiClockid[WasiClockid["REALTIME"] = 0] = "REALTIME";
WasiClockid[WasiClockid["MONOTONIC"] = 1] = "MONOTONIC";
WasiClockid[WasiClockid["PROCESS_CPUTIME_ID"] = 2] = "PROCESS_CPUTIME_ID";
WasiClockid[WasiClockid["THREAD_CPUTIME_ID"] = 3] = "THREAD_CPUTIME_ID";
})(WasiClockid || (WasiClockid = {}));
export var WasiFstFlag;
(function (WasiFstFlag) {
WasiFstFlag[WasiFstFlag["SET_ATIM"] = 1] = "SET_ATIM";
WasiFstFlag[WasiFstFlag["SET_ATIM_NOW"] = 2] = "SET_ATIM_NOW";
WasiFstFlag[WasiFstFlag["SET_MTIM"] = 4] = "SET_MTIM";
WasiFstFlag[WasiFstFlag["SET_MTIM_NOW"] = 8] = "SET_MTIM_NOW";
})(WasiFstFlag || (WasiFstFlag = {}));
export var WasiEventType;
(function (WasiEventType) {
WasiEventType[WasiEventType["CLOCK"] = 0] = "CLOCK";
WasiEventType[WasiEventType["FD_READ"] = 1] = "FD_READ";
WasiEventType[WasiEventType["FD_WRITE"] = 2] = "FD_WRITE";
})(WasiEventType || (WasiEventType = {}));
export var WasiSubclockflags;
(function (WasiSubclockflags) {
WasiSubclockflags[WasiSubclockflags["ABSTIME"] = 1] = "ABSTIME";
})(WasiSubclockflags || (WasiSubclockflags = {}));

View file

@ -0,0 +1,113 @@
/* eslint-disable spaced-comment */
export function validateObject(value, name) {
if (value === null || typeof value !== 'object') {
throw new TypeError(`${name} must be an object. Received ${value === null ? 'null' : typeof value}`);
}
}
export function validateArray(value, name) {
if (!Array.isArray(value)) {
throw new TypeError(`${name} must be an array. Received ${value === null ? 'null' : typeof value}`);
}
}
export function validateBoolean(value, name) {
if (typeof value !== 'boolean') {
throw new TypeError(`${name} must be a boolean. Received ${value === null ? 'null' : typeof value}`);
}
}
export function validateString(value, name) {
if (typeof value !== 'string') {
throw new TypeError(`${name} must be a string. Received ${value === null ? 'null' : typeof value}`);
}
}
export function validateFunction(value, name) {
if (typeof value !== 'function') {
throw new TypeError(`${name} must be a function. Received ${value === null ? 'null' : typeof value}`);
}
}
export function validateUndefined(value, name) {
if (value !== undefined) {
throw new TypeError(`${name} must be undefined. Received ${value === null ? 'null' : typeof value}`);
}
}
export function validateInt32(value, name, min = -2147483648, max = 2147483647) {
if (typeof value !== 'number') {
throw new TypeError(`${name} must be a number. Received ${value === null ? 'null' : typeof value}`);
}
if (!Number.isInteger(value)) {
throw new RangeError(`${name} must be a integer.`);
}
if (value < min || value > max) {
throw new RangeError(`${name} must be >= ${min} && <= ${max}. Received ${value}`);
}
}
export function isPromiseLike(obj) {
return !!(obj && (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function');
}
export function wrapInstanceExports(exports, mapFn) {
const newExports = Object.create(null);
Object.keys(exports).forEach(name => {
const exportValue = exports[name];
Object.defineProperty(newExports, name, {
enumerable: true,
value: mapFn(exportValue, name)
});
});
return newExports;
}
const _require = /*#__PURE__*/ (function () {
let nativeRequire;
if (typeof __webpack_public_path__ !== 'undefined') {
nativeRequire = (function () {
return typeof __non_webpack_require__ !== 'undefined' ? __non_webpack_require__ : undefined;
})();
}
else {
nativeRequire = (function () {
return typeof __webpack_public_path__ !== 'undefined' ? (typeof __non_webpack_require__ !== 'undefined' ? __non_webpack_require__ : undefined) : (typeof require !== 'undefined' ? require : undefined);
})();
}
return nativeRequire;
})();
export const isMainThread = /*#__PURE__*/ (function () {
let worker_threads;
try {
worker_threads = _require('worker_threads');
}
catch (_) { }
if (!worker_threads) {
return typeof importScripts === 'undefined';
}
return worker_threads.isMainThread;
})();
export const postMsg = isMainThread
? () => { }
: /*#__PURE__*/ (function () {
let worker_threads;
try {
worker_threads = _require('worker_threads');
}
catch (_) { }
if (!worker_threads) {
return postMessage;
}
return function postMessage(data) {
worker_threads.parentPort.postMessage({ data });
};
})();
export function sleepBreakIf(delay, breakIf) {
const start = Date.now();
const end = start + delay;
let ret = false;
while (Date.now() < end) {
if (breakIf()) {
ret = true;
break;
}
}
return ret;
}
export function unsharedSlice(view, start, end) {
return ((typeof SharedArrayBuffer === 'function' && view.buffer instanceof SharedArrayBuffer) || (Object.prototype.toString.call(view.buffer.constructor) === '[object SharedArrayBuffer]'))
? view.slice(start, end)
: view.subarray(start, end);
}

View file

@ -0,0 +1,9 @@
const _WebAssembly = typeof WebAssembly !== 'undefined'
? WebAssembly
: typeof WXWebAssembly !== 'undefined'
? WXWebAssembly
: undefined;
if (!_WebAssembly) {
throw new Error('WebAssembly is not supported in this environment');
}
export { _WebAssembly };

View file

@ -0,0 +1,58 @@
{
"name": "@tybys/wasm-util",
"version": "0.10.1",
"description": "WASI polyfill for browser and some wasm util",
"main": "./lib/cjs/index.js",
"module": "./dist/wasm-util.esm-bundler.js",
"types": "./dist/wasm-util.d.ts",
"exports": {
".": {
"module": "./dist/wasm-util.esm-bundler.js",
"import": "./lib/mjs/index.mjs",
"require": "./lib/cjs/index.js",
"types": "./dist/wasm-util.d.ts"
}
},
"scripts": {
"build": "tsgo build",
"watch": "tsgo watch",
"test": "jest",
"lint": "eslint ./src/**/*.{ts,js} --fix",
"prepare": "npm run build"
},
"publishConfig": {
"access": "public"
},
"keywords": [
"wasm",
"webassembly",
"wasi",
"polyfill"
],
"repository": {
"type": "git",
"url": "https://github.com/toyobayashi/wasm-util.git"
},
"author": "toyobayashi",
"license": "MIT",
"dependencies": {
"tslib": "^2.4.0"
},
"devDependencies": {
"@tybys/ts-transform-module-specifier": "^0.0.2",
"@tybys/ts-transform-pure-class": "^0.1.1",
"@tybys/tsgo": "^1.1.0",
"@types/node": "^14.14.31",
"@typescript-eslint/eslint-plugin": "^5.40.1",
"@typescript-eslint/parser": "^5.40.1",
"eslint": "^8.25.0",
"eslint-config-standard-with-typescript": "^23.0.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-n": "^15.3.0",
"eslint-plugin-promise": "^6.1.0",
"memfs-browser": "^3.4.13000",
"mocha": "^10.1.0",
"ts-node": "^10.9.1",
"typescript": "~4.8.3"
}
}