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 (
@@ -239,6 +256,18 @@ export async function componentize(opts,
239256 wevalBin = await getWeval ( ) ;
240257 }
241258
259+ // Set the min stack size, if one was provided
260+ if ( opts . aotMinStackSizeBytes ) {
261+ if ( ! isNumeric ( opts . aotMinStackSizeBytes ) ) {
262+ throw new TypeError (
263+ `aotMinStackSizeBytes must be a numeric value, received [${ opts . aotMinStackSizeBytes } ] (type ${ typeof opts . aotMinStackSizeBytes } )` ,
264+ ) ;
265+ }
266+ env . RUST_MIN_STACK = opts . aotMinStackSizeBytes ;
267+ } else {
268+ env . RUST_MIN_STACK = defaultMinStackSize ( ) ;
269+ }
270+
242271 wizerProcess = spawnSync (
243272 wevalBin ,
244273 [
@@ -312,7 +341,7 @@ export async function componentize(opts,
312341 async function initWasm ( bin ) {
313342 const eep = ( name ) => ( ) => {
314343 throw new Error (
315- `Internal error: unexpected call to "${ name } " during Wasm verification`
344+ `Internal error: unexpected call to "${ name } " during Wasm verification` ,
316345 ) ;
317346 } ;
318347
@@ -332,7 +361,7 @@ export async function componentize(opts,
332361 const bufPtr = mem . getUint32 ( iovs + i * 8 , true ) ;
333362 const bufLen = mem . getUint32 ( iovs + 4 + i * 8 , true ) ;
334363 stderr += new TextDecoder ( ) . decode (
335- new Uint8Array ( exports . memory . buffer , bufPtr , bufLen )
364+ new Uint8Array ( exports . memory . buffer , bufPtr , bufLen ) ,
336365 ) ;
337366 written += bufLen ;
338367 }
@@ -390,7 +419,7 @@ export async function componentize(opts,
390419 features ,
391420 witWorld ,
392421 maybeWindowsPath ( witPath ) ,
393- worldName
422+ worldName ,
394423 ) ;
395424
396425 if ( debugBindings ) {
@@ -403,12 +432,12 @@ export async function componentize(opts,
403432 Object . entries ( {
404433 wasi_snapshot_preview1 : await readFile ( preview2Adapter ) ,
405434 } ) ,
406- false
435+ false ,
407436 ) ,
408437 Object . entries ( {
409438 language : [ [ 'JavaScript' , '' ] ] ,
410439 'processed-by' : [ [ 'ComponentizeJS' , version ] ] ,
411- } )
440+ } ) ,
412441 ) ;
413442
414443 // convert CABI import conventions to ESM import conventions
@@ -421,3 +450,14 @@ export async function componentize(opts,
421450 imports,
422451 } ;
423452}
453+
454+ /**
455+ * Calculate the min stack size depending on free memory
456+ *
457+ * @param {number } freeMemoryBytes - Amount of free memory in the system, in bytes (if not provided, os.freemem() is used)
458+ * @returns {number } The minimum stack size that should be used as a default.
459+ */
460+ function defaultMinStackSize ( freeMemoryBytes ) {
461+ freeMemoryBytes = freeMemoryBytes ?? freemem ( ) ;
462+ return Math . max ( 8 * 1024 * 1024 , Math . floor ( freeMemoryBytes * 0.1 ) ) ;
463+ }
0 commit comments