1- import { WASI as _WASI } from './preview1'
1+ import { WASI as WASIPreview1 } from './preview1'
22import type { Preopen } from './preview1'
33import type { exitcode } from './types'
44
77 validateArray ,
88 validateBoolean ,
99 validateFunction ,
10- validateUndefined
10+ validateUndefined ,
11+ validateString
1112} from './util'
1213import type { IFs , IFsPromises } from './fs'
1314import type { Asyncify } from '../asyncify'
@@ -18,6 +19,7 @@ const kExitCode = Symbol('kExitCode')
1819const kSetMemory = Symbol ( 'kSetMemory' )
1920const kStarted = Symbol ( 'kStarted' )
2021const kInstance = Symbol ( 'kInstance' )
22+ const kBindingName = Symbol ( 'kBindingName' )
2123
2224function setupInstance ( self : WASI , instance : WebAssembly . Instance ) : void {
2325 validateObject ( instance , 'instance' )
@@ -29,6 +31,7 @@ function setupInstance (self: WASI, instance: WebAssembly.Instance): void {
2931
3032/** @public */
3133export interface WASIOptions {
34+ version ?: 'unstable' | 'preview1'
3235 args ?: string [ ] | undefined
3336 env ?: Record < string , string > | undefined
3437 preopens ?: Record < string , string > | undefined
@@ -68,17 +71,35 @@ export interface AsyncWASIOptions extends WASIOptions {
6871 asyncify ?: Asyncify
6972}
7073
71- // /** @public */
72- // export type WasiSnapshotPreview1 = Omit<_WASI, '_setMemory'>
73-
74- function validateOptions ( options : WASIOptions & { fs ?: IFs | { promises : IFsPromises } } ) : {
74+ function validateOptions ( this : WASI , options : WASIOptions & { fs ?: IFs | { promises : IFsPromises } } ) : {
7575 args : string [ ]
7676 env : string [ ]
7777 preopens : Preopen [ ]
7878 stdio : readonly [ 0 , 1 , 2 ]
79+ _WASI : any
7980} {
8081 validateObject ( options , 'options' )
8182
83+ let _WASI : any
84+ if ( options . version !== undefined ) {
85+ validateString ( options . version , 'options.version' )
86+ switch ( options . version ) {
87+ case 'unstable' :
88+ _WASI = WASIPreview1
89+ this [ kBindingName ] = 'wasi_unstable'
90+ break
91+ case 'preview1' :
92+ _WASI = WASIPreview1
93+ this [ kBindingName ] = 'wasi_snapshot_preview1'
94+ break
95+ default :
96+ throw new TypeError ( `unsupported WASI version "${ options . version as string } "` )
97+ }
98+ } else {
99+ _WASI = WASIPreview1
100+ this [ kBindingName ] = 'wasi_snapshot_preview1'
101+ }
102+
82103 if ( options . args !== undefined ) {
83104 validateArray ( options . args , 'options.args' )
84105 }
@@ -145,11 +166,12 @@ function validateOptions (options: WASIOptions & { fs?: IFs | { promises: IFsPro
145166 args,
146167 env,
147168 preopens,
148- stdio
169+ stdio,
170+ _WASI
149171 }
150172}
151173
152- function initWASI ( this : WASI , setMemory : ( m : WebAssembly . Memory ) => void , wrap : _WASI ) : void {
174+ function initWASI ( this : WASI , setMemory : ( m : WebAssembly . Memory ) => void , wrap : any ) : void {
153175 this [ kSetMemory ] = setMemory ;
154176 ( this as any ) . wasiImport = wrap
155177 this [ kStarted ] = false
@@ -189,57 +211,18 @@ export class WASI {
189211 private [ kStarted ] ! : boolean
190212 private [ kExitCode ] ! : number
191213 private [ kInstance ] : WebAssembly . Instance | undefined
214+ private [ kBindingName ] ! : string
192215
193216 public readonly wasiImport ! : Record < string , any >
194217
195- static createSync ( options : SyncWASIOptions = kEmptyObject ) : WASI {
196- return new WASI ( options )
197- }
198-
199- static async createAsync ( options : AsyncWASIOptions = kEmptyObject ) : Promise < WASI > {
200- const {
201- args,
202- env,
203- preopens,
204- stdio
205- } = validateOptions ( options )
206-
207- if ( options . asyncify !== undefined ) {
208- validateObject ( options . asyncify , 'options.asyncify' )
209- validateFunction ( options . asyncify . wrapImportFunction , 'options.asyncify.wrapImportFunction' )
210- }
211-
212- const wrap = await _WASI . createAsync (
213- args ,
214- env ,
215- preopens ,
216- stdio ,
217- options . fs ,
218- options . print ,
219- options . printErr ,
220- options . asyncify
221- )
222-
223- const setMemory = wrap . _setMemory !
224- delete wrap . _setMemory
225- const _this = Object . create ( WASI . prototype )
226- initWASI . call ( _this ,
227- setMemory ,
228- wrap
229- )
230-
231- if ( options . returnOnExit ) { wrap . proc_exit = wasiReturnOnProcExit . bind ( _this ) }
232-
233- return _this
234- }
235-
236218 public constructor ( options : SyncWASIOptions = kEmptyObject ) {
237219 const {
238220 args,
239221 env,
240222 preopens,
241- stdio
242- } = validateOptions ( options )
223+ stdio,
224+ _WASI
225+ } = validateOptions . call ( this , options )
243226
244227 const wrap = _WASI . createSync (
245228 args ,
@@ -311,10 +294,53 @@ export class WASI {
311294 return ( _initialize as ( ) => any ) ( )
312295 }
313296 }
297+
298+ getImportObject ( ) : Record < string , Record < string , any > > {
299+ return { [ this [ kBindingName ] ] : this . wasiImport }
300+ }
314301}
315302
316303function wasiReturnOnProcExit ( this : WASI , rval : exitcode ) : exitcode {
317304 this [ kExitCode ] = rval
318305 // eslint-disable-next-line @typescript-eslint/no-throw-literal
319306 throw kExitCode
320307}
308+
309+ /** @public */
310+ export async function createAsyncWASI ( options : AsyncWASIOptions = kEmptyObject ) : Promise < WASI > {
311+ const _this = Object . create ( WASI . prototype )
312+ const {
313+ args,
314+ env,
315+ preopens,
316+ stdio,
317+ _WASI
318+ } = validateOptions . call ( _this , options )
319+
320+ if ( options . asyncify !== undefined ) {
321+ validateObject ( options . asyncify , 'options.asyncify' )
322+ validateFunction ( options . asyncify . wrapImportFunction , 'options.asyncify.wrapImportFunction' )
323+ }
324+
325+ const wrap = await _WASI . createAsync (
326+ args ,
327+ env ,
328+ preopens ,
329+ stdio ,
330+ options . fs ,
331+ options . print ,
332+ options . printErr ,
333+ options . asyncify
334+ )
335+
336+ const setMemory = wrap . _setMemory !
337+ delete wrap . _setMemory
338+ initWASI . call ( _this ,
339+ setMemory ,
340+ wrap
341+ )
342+
343+ if ( options . returnOnExit ) { wrap . proc_exit = wasiReturnOnProcExit . bind ( _this ) }
344+
345+ return _this
346+ }
0 commit comments