1+ import { freemem } from "node:os" ;
12import wizer from '@bytecodealliance/wizer' ;
23import getWeval from '@bytecodealliance/weval' ;
34import {
@@ -18,7 +19,7 @@ import {
1819import { fileURLToPath } from 'node:url' ;
1920import { cwd , stdout , platform } from 'node:process' ;
2021export const { version } = JSON . parse (
21- await readFile ( new URL ( '../package.json' , import . meta. url ) , 'utf8' )
22+ await readFile ( new URL ( '../package.json' , import . meta. url ) , 'utf8' ) ,
2223) ;
2324const isWindows = platform === 'win32' ;
2425
@@ -56,6 +57,24 @@ function parseWizerStderr(stderr) {
5657 return `${ output . substring ( 0 , causeStart ) } ${ output . substring ( causeEnd ) } ` . trim ( ) ;
5758}
5859
60+ /**
61+ * Check whether a value is numeric (including BigInt)
62+ *
63+ * @param {any } n
64+ * @returns {boolean } whether the value is numeric
65+ */
66+ function isNumeric ( n ) {
67+ switch ( typeof n ) {
68+ case 'bigint' :
69+ case 'number' :
70+ return true ;
71+ case 'object' :
72+ return n . constructor == BigInt || n . constructor == Number ;
73+ default :
74+ return false ;
75+ }
76+ }
77+
5978export async function componentize ( opts ,
6079 _deprecatedWitWorldOrOpts = undefined ,
6180 _deprecatedOpts = undefined ) {
@@ -106,7 +125,7 @@ export async function componentize(opts,
106125 debugBindings = false ,
107126 enableWizerLogging = false ,
108127 aotCache = fileURLToPath (
109- new URL ( `../lib/starlingmonkey_ics.wevalcache` , import . meta. url )
128+ new URL ( `../lib/starlingmonkey_ics.wevalcache` , import . meta. url ) ,
110129 ) ,
111130 } = opts ;
112131
@@ -116,11 +135,9 @@ export async function componentize(opts,
116135 new URL (
117136 opts . enableAot
118137 ? `../lib/starlingmonkey_embedding_weval.wasm`
119- : `../lib/starlingmonkey_embedding${
120- debugBuild ? '.debug' : ''
121- } .wasm`,
122- import . meta. url
123- )
138+ : `../lib/starlingmonkey_embedding${ debugBuild ? '.debug' : '' } .wasm` ,
139+ import . meta. url ,
140+ ) ,
124141 ) ;
125142
126143 let { wasm, jsBindings, exports, imports } = spliceBindings (
@@ -245,6 +262,18 @@ export async function componentize(opts,
245262 wevalBin = await getWeval ( ) ;
246263 }
247264
265+ // Set the min stack size, if one was provided
266+ if ( opts . aotMinStackSizeBytes ) {
267+ if ( ! isNumeric ( opts . aotMinStackSizeBytes ) ) {
268+ throw new TypeError (
269+ `aotMinStackSizeBytes must be a numeric value, received [${ opts . aotMinStackSizeBytes } ] (type ${ typeof opts . aotMinStackSizeBytes } )` ,
270+ ) ;
271+ }
272+ env . RUST_MIN_STACK = opts . aotMinStackSizeBytes ;
273+ } else {
274+ env . RUST_MIN_STACK = defaultMinStackSize ( ) ;
275+ }
276+
248277 wizerProcess = spawnSync (
249278 wevalBin ,
250279 [
@@ -318,7 +347,7 @@ export async function componentize(opts,
318347 async function initWasm ( bin ) {
319348 const eep = ( name ) => ( ) => {
320349 throw new Error (
321- `Internal error: unexpected call to "${ name } " during Wasm verification`
350+ `Internal error: unexpected call to "${ name } " during Wasm verification` ,
322351 ) ;
323352 } ;
324353
@@ -338,7 +367,7 @@ export async function componentize(opts,
338367 const bufPtr = mem . getUint32 ( iovs + i * 8 , true ) ;
339368 const bufLen = mem . getUint32 ( iovs + 4 + i * 8 , true ) ;
340369 stderr += new TextDecoder ( ) . decode (
341- new Uint8Array ( exports . memory . buffer , bufPtr , bufLen )
370+ new Uint8Array ( exports . memory . buffer , bufPtr , bufLen ) ,
342371 ) ;
343372 written += bufLen ;
344373 }
@@ -396,7 +425,7 @@ export async function componentize(opts,
396425 features ,
397426 witWorld ,
398427 maybeWindowsPath ( witPath ) ,
399- worldName
428+ worldName ,
400429 ) ;
401430
402431 if ( debugBindings ) {
@@ -409,12 +438,12 @@ export async function componentize(opts,
409438 Object . entries ( {
410439 wasi_snapshot_preview1 : await readFile ( preview2Adapter ) ,
411440 } ) ,
412- false
441+ false ,
413442 ) ,
414443 Object . entries ( {
415444 language : [ [ 'JavaScript' , '' ] ] ,
416445 'processed-by' : [ [ 'ComponentizeJS' , version ] ] ,
417- } )
446+ } ) ,
418447 ) ;
419448
420449 // convert CABI import conventions to ESM import conventions
@@ -427,3 +456,14 @@ export async function componentize(opts,
427456 imports,
428457 } ;
429458}
459+
460+ /**
461+ * Calculate the min stack size depending on free memory
462+ *
463+ * @param {number } freeMemoryBytes - Amount of free memory in the system, in bytes (if not provided, os.freemem() is used)
464+ * @returns {number } The minimum stack size that should be used as a default.
465+ */
466+ function defaultMinStackSize ( freeMemoryBytes ) {
467+ freeMemoryBytes = freeMemoryBytes ?? freemem ( ) ;
468+ return Math . max ( 8 * 1024 * 1024 , Math . floor ( freeMemoryBytes * 0.1 ) ) ;
469+ }
0 commit comments