@@ -328,76 +328,8 @@ export async function componentize(
328328
329329 await tmpdirRemovePromise ;
330330
331- async function initWasm ( bin ) {
332- const eep = ( name ) => ( ) => {
333- throw new Error (
334- `Internal error: unexpected call to "${ name } " during Wasm verification` ,
335- ) ;
336- } ;
337-
338- let stderr = '' ;
339- const wasmModule = await WebAssembly . compile ( bin ) ;
340-
341- const mockImports = {
342- // "wasi-logging2": {
343- // log: eep("log"),
344- // },
345- wasi_snapshot_preview1 : {
346- fd_write : function ( fd , iovs , iovs_len , nwritten ) {
347- if ( fd !== 2 ) return 0 ;
348- const mem = new DataView ( exports . memory . buffer ) ;
349- let written = 0 ;
350- for ( let i = 0 ; i < iovs_len ; i ++ ) {
351- const bufPtr = mem . getUint32 ( iovs + i * 8 , true ) ;
352- const bufLen = mem . getUint32 ( iovs + 4 + i * 8 , true ) ;
353- stderr += new TextDecoder ( ) . decode (
354- new Uint8Array ( exports . memory . buffer , bufPtr , bufLen ) ,
355- ) ;
356- written += bufLen ;
357- }
358- mem . setUint32 ( nwritten , written , true ) ;
359- return 1 ;
360- } ,
361- } ,
362- } ;
363-
364- for ( const { module, name } of WebAssembly . Module . imports ( wasmModule ) ) {
365- mockImports [ module ] = mockImports [ module ] || { } ;
366- if ( ! mockImports [ module ] [ name ] ) mockImports [ module ] [ name ] = eep ( name ) ;
367- }
368-
369- const { exports } = await WebAssembly . instantiate ( wasmModule , mockImports ) ;
370- return {
371- exports,
372- getStderr ( ) {
373- return stderr ;
374- } ,
375- } ;
376- }
377-
378- const status = check_init ( ) ;
379- let err = null ;
380- switch ( status ) {
381- case CHECK_INIT_RETURN_OK :
382- break ;
383- case CHECK_INIT_RETURN_FN_LIST :
384- err = `Unable to extract expected exports list` ;
385- break ;
386- case CHECK_INIT_RETURN_TYPE_PARSE :
387- err = `Unable to parse the core ABI export types` ;
388- break ;
389- default :
390- err = `Unknown error during initialization: ${ status } ` ;
391- }
392-
393- if ( err ) {
394- let msg = err ;
395- const stderr = getStderr ( ) ;
396- if ( stderr ) {
397- msg += `\n${ stripLinesPrefixes ( stderr , [ new RegExp ( `${ initializerPath } [:\\d]* ?` ) ] , tmpDir ) } ` ;
398- }
399- throw new Error ( msg ) ;
400- }
331+ /// Process output of check init, throwing if necessary
332+ handleCheckInitOutput ( check_init ( ) , initializerPath , workDir , getStderr ) ;
401333
402334 // after wizening, stub out the wasi imports depending on what features are enabled
403335 const finalBin = stubWasi (
@@ -498,3 +430,130 @@ function isNumeric(n) {
498430 }
499431}
500432
433+ /**
434+ * Initialize a WebAssembly binary, given the
435+ *
436+ * @param {Buffer } bin - WebAssembly binary bytes
437+ * @throws If a binary is invalid
438+ */
439+ async function initWasm ( bin ) {
440+ const eep = ( name ) => ( ) => {
441+ throw new Error (
442+ `Internal error: unexpected call to "${ name } " during Wasm verification` ,
443+ ) ;
444+ } ;
445+
446+ let stderr = '' ;
447+ const wasmModule = await WebAssembly . compile ( bin ) ;
448+
449+ const mockImports = {
450+ // "wasi-logging2": {
451+ // log: eep("log"),
452+ // },
453+ wasi_snapshot_preview1 : {
454+ fd_write : function ( fd , iovs , iovs_len , nwritten ) {
455+ if ( fd !== 2 ) return 0 ;
456+ const mem = new DataView ( exports . memory . buffer ) ;
457+ let written = 0 ;
458+ for ( let i = 0 ; i < iovs_len ; i ++ ) {
459+ const bufPtr = mem . getUint32 ( iovs + i * 8 , true ) ;
460+ const bufLen = mem . getUint32 ( iovs + 4 + i * 8 , true ) ;
461+ stderr += new TextDecoder ( ) . decode (
462+ new Uint8Array ( exports . memory . buffer , bufPtr , bufLen ) ,
463+ ) ;
464+ written += bufLen ;
465+ }
466+ mem . setUint32 ( nwritten , written , true ) ;
467+ return 1 ;
468+ } ,
469+ } ,
470+ } ;
471+
472+ for ( const { module, name } of WebAssembly . Module . imports ( wasmModule ) ) {
473+ mockImports [ module ] = mockImports [ module ] || { } ;
474+ if ( ! mockImports [ module ] [ name ] ) mockImports [ module ] [ name ] = eep ( name ) ;
475+ }
476+
477+ const { exports } = await WebAssembly . instantiate ( wasmModule , mockImports ) ;
478+ return {
479+ exports,
480+ getStderr ( ) {
481+ return stderr ;
482+ } ,
483+ } ;
484+ }
485+
486+ /**
487+ * Handle the output of `check_init()`
488+ *
489+ * @param {number } status - output of check_init
490+ * @param {string } initializerPath
491+ * @param {string } workDir
492+ * @param {() => string } getStderr - A function that resolves to the stderr output of check init
493+ */
494+ async function handleCheckInitOutput (
495+ status ,
496+ initializerPath ,
497+ workDir ,
498+ getStderr ,
499+ ) {
500+ let err = null ;
501+ switch ( status ) {
502+ case CHECK_INIT_RETURN_OK :
503+ break ;
504+ case CHECK_INIT_RETURN_FN_LIST :
505+ err = `Unable to extract expected exports list` ;
506+ break ;
507+ case CHECK_INIT_RETURN_TYPE_PARSE :
508+ err = `Unable to parse the core ABI export types` ;
509+ break ;
510+ default :
511+ err = `Unknown error during initialization: ${ status } ` ;
512+ }
513+
514+ if ( err ) {
515+ let msg = err ;
516+ const stderr = getStderr ( ) ;
517+ if ( stderr ) {
518+ msg += `\n${ stripLinesPrefixes ( stderr , [ new RegExp ( `${ initializerPath } [:\\d]* ?` ) ] , workDir ) } ` ;
519+ }
520+ throw new Error ( msg ) ;
521+ }
522+
523+ // after wizening, stub out the wasi imports depending on what features are enabled
524+ const finalBin = stubWasi (
525+ bin ,
526+ features ,
527+ witWorld ,
528+ maybeWindowsPath ( witPath ) ,
529+ worldName ,
530+ ) ;
531+
532+ if ( debugBindings ) {
533+ await writeFile ( 'binary.wasm' , finalBin ) ;
534+ }
535+
536+ const component = await metadataAdd (
537+ await componentNew (
538+ finalBin ,
539+ Object . entries ( {
540+ wasi_snapshot_preview1 : await readFile ( preview2Adapter ) ,
541+ } ) ,
542+ false ,
543+ ) ,
544+ Object . entries ( {
545+ language : [ [ 'JavaScript' , '' ] ] ,
546+ 'processed-by' : [ [ 'ComponentizeJS' , version ] ] ,
547+ } ) ,
548+ ) ;
549+
550+ // convert CABI import conventions to ESM import conventions
551+ imports = imports . map ( ( [ specifier , impt ] ) =>
552+ specifier === '$root' ? [ impt , 'default' ] : [ specifier , impt ] ,
553+ ) ;
554+
555+ return {
556+ component,
557+ imports,
558+ } ;
559+ }
0 commit comments