@@ -51,6 +51,17 @@ const DEFAULT_AOT_CACHE = fileURLToPath(
51
51
new URL ( `../lib/starlingmonkey_ics.wevalcache` , import . meta. url ) ,
52
52
) ;
53
53
54
+ /** Default settings for debug options */
55
+ const DEFAULT_DEBUG_SETTINGS = {
56
+ bindings : false ,
57
+ bindingsDir : null ,
58
+
59
+ binary : false ,
60
+ binaryPath : null ,
61
+
62
+ wizerLogging : false ,
63
+ } ;
64
+
54
65
function maybeWindowsPath ( path ) {
55
66
if ( ! path ) return path ;
56
67
if ( ! IS_WINDOWS ) return resolve ( path ) ;
@@ -96,13 +107,21 @@ export async function componentize(
96
107
worldName,
97
108
disableFeatures = [ ] ,
98
109
enableFeatures = [ ] ,
110
+
111
+ debug = { ...DEFAULT_DEBUG_SETTINGS } ,
99
112
debugBuild = false ,
100
- runtimeArgs,
101
113
debugBindings = false ,
102
114
enableWizerLogging = false ,
115
+
116
+ runtimeArgs,
117
+
103
118
aotCache = DEFAULT_AOT_CACHE ,
104
119
} = opts ;
105
120
121
+ debugBindings = debugBindings || debug ?. bindings ;
122
+ debugBuild = debugBuild || debug ?. build ;
123
+ enableWizerLogging = enableWizerLogging || debug ?. enableWizerLogging ;
124
+
106
125
// Determine the path to the StarlingMonkey binary
107
126
const engine = getEnginePath ( opts ) ;
108
127
@@ -121,27 +140,52 @@ export async function componentize(
121
140
await writeFile ( join ( sourcesDir , 'initializer.js' ) , jsBindings ) ;
122
141
123
142
if ( debugBindings ) {
124
- console . log ( '--- JS Bindings ---' ) ;
125
- console . log (
126
- jsBindings
127
- . split ( '\n' )
128
- . map ( ( ln , idx ) => `${ ( idx + 1 ) . toString ( ) . padStart ( 4 , ' ' ) } | ${ ln } ` )
129
- . join ( '\n' ) ,
130
- ) ;
131
- console . log ( '--- JS Imports ---' ) ;
132
- console . log ( imports ) ;
133
- console . log ( '--- JS Exports ---' ) ;
134
- console . log ( exports ) ;
143
+ // If a bindings output directory was specified, output generated bindings to files
144
+ if ( debug ?. bindingsDir ) {
145
+ console . error ( `outputting debug files to [${ debug ?. bindingsDir } ]...\n` ) ;
146
+ // Ensure the debug bindings dir exists, and is a directory
147
+ if ( ! ( await stat ( debug ?. bindingsDir ) . then ( ( s ) => s . isDirectory ( ) ) ) ) {
148
+ throw new Error (
149
+ `Missing/invalid debug bindings directory [${ debug ?. bindingsDir } ]` ,
150
+ ) ;
151
+ }
152
+ // Write debug to bindings debug directory
153
+ await Promise . all ( [
154
+ writeFile ( join ( debug ?. bindingsDir , 'source.debug.js' ) , jsSource ) ,
155
+ writeFile ( join ( debug ?. bindingsDir , 'bindings.debug.js' ) , jsBindings ) ,
156
+ writeFile (
157
+ join ( debug ?. bindingsDir , 'imports.debug.json' ) ,
158
+ JSON . stringify ( imports , null , 2 ) ,
159
+ ) ,
160
+ writeFile (
161
+ join ( debug ?. bindingsDir , 'exports.debug.json' ) ,
162
+ JSON . stringify ( exports , null , 2 ) ,
163
+ ) ,
164
+ ] ) ;
165
+ } else {
166
+ // If a bindings output directory was not specified, output to stdout
167
+ console . error ( '--- JS Bindings ---' ) ;
168
+ console . error (
169
+ jsBindings
170
+ . split ( '\n' )
171
+ . map ( ( ln , idx ) => `${ ( idx + 1 ) . toString ( ) . padStart ( 4 , ' ' ) } | ${ ln } ` )
172
+ . join ( '\n' ) ,
173
+ ) ;
174
+ console . error ( '--- JS Imports ---' ) ;
175
+ console . error ( imports ) ;
176
+ console . error ( '--- JS Exports ---' ) ;
177
+ console . error ( exports ) ;
178
+ }
135
179
}
136
180
137
181
if ( ! useOriginalSourceFile ) {
138
182
if ( debugBindings ) {
139
- console . log ( `> Writing JS source to ${ tmpDir } /sources` ) ;
183
+ console . error ( `> Writing JS source to ${ tmpDir } /sources` ) ;
140
184
}
141
185
await writeFile ( sourcePath , jsSource ) ;
142
186
}
143
187
144
- // we never disable a feature that is already in the target world usage
188
+ // We never disable a feature that is already in the target world usage
145
189
const features = [ ] ;
146
190
if ( ! disableFeatures . includes ( 'stdio' ) ) {
147
191
features . push ( 'stdio' ) ;
@@ -185,8 +229,8 @@ export async function componentize(
185
229
env [ 'IMPORT_CNT' ] = imports . length ;
186
230
187
231
if ( debugBindings ) {
188
- console . log ( '--- Wizer Env ---' ) ;
189
- console . log ( env ) ;
232
+ console . error ( '--- Wizer Env ---' ) ;
233
+ console . error ( env ) ;
190
234
}
191
235
192
236
let initializerPath = join ( sourcesDir , 'initializer.js' ) ;
@@ -208,17 +252,18 @@ export async function componentize(
208
252
sourcePath = sourcePath . slice ( workspacePrefix . length + 1 ) ;
209
253
}
210
254
}
255
+
211
256
let args = `--initializer-script-path ${ initializerPath } --strip-path-prefix ${ workspacePrefix } / ${ sourcePath } ` ;
212
257
runtimeArgs = runtimeArgs ? `${ runtimeArgs } ${ args } ` : args ;
258
+
213
259
let preopens = [ `--dir ${ sourcesDir } ` ] ;
214
260
if ( opts . enableAot ) {
215
261
preopens . push ( `--dir ${ workspacePrefix } ` ) ;
216
262
} else {
217
263
preopens . push ( `--mapdir /::${ workspacePrefix } ` ) ;
218
264
}
219
265
220
- let wizerProcess ;
221
-
266
+ let postProcess ;
222
267
if ( opts . enableAot ) {
223
268
// Determine the weval bin path, possibly using a pre-downloaded version
224
269
let wevalBin ;
@@ -240,7 +285,7 @@ export async function componentize(
240
285
env . RUST_MIN_STACK = defaultMinStackSize ( ) ;
241
286
}
242
287
243
- wizerProcess = spawnSync (
288
+ postProcess = spawnSync (
244
289
wevalBin ,
245
290
[
246
291
'weval' ,
@@ -261,7 +306,7 @@ export async function componentize(
261
306
} ,
262
307
) ;
263
308
} else {
264
- wizerProcess = spawnSync (
309
+ postProcess = spawnSync (
265
310
wizer ,
266
311
[
267
312
'--allow-wasi' ,
@@ -283,11 +328,12 @@ export async function componentize(
283
328
) ;
284
329
}
285
330
286
- if ( wizerProcess . status !== 0 ) {
287
- let wizerErr = parseWizerStderr ( wizerProcess . stderr ) ;
331
+ // If the wizer (or weval) process failed, parse the output and display to the user
332
+ if ( postProcess . status !== 0 ) {
333
+ let wizerErr = parseWizerStderr ( postProcess . stderr ) ;
288
334
let err = `Failed to initialize component:\n${ wizerErr } ` ;
289
335
if ( debugBindings ) {
290
- err += `\n\nBinary and sources available for debugging at ${ tmpDir } \n` ;
336
+ err += `\n\nBinary and sources available for debugging at ${ workDir } \n` ;
291
337
} else {
292
338
await rm ( workDir , { recursive : true } ) ;
293
339
}
@@ -312,7 +358,7 @@ export async function componentize(
312
358
/// Process output of check init, throwing if necessary
313
359
handleCheckInitOutput ( check_init ( ) , initializerPath , workDir , getStderr ) ;
314
360
315
- // after wizening, stub out the wasi imports depending on what features are enabled
361
+ // After wizening, stub out the wasi imports depending on what features are enabled
316
362
const finalBin = stubWasi (
317
363
bin ,
318
364
features ,
@@ -339,14 +385,26 @@ export async function componentize(
339
385
} ) ,
340
386
) ;
341
387
342
- // convert CABI import conventions to ESM import conventions
388
+ // Convert CABI import conventions to ESM import conventions
343
389
imports = imports . map ( ( [ specifier , impt ] ) =>
344
390
specifier === '$root' ? [ impt , 'default' ] : [ specifier , impt ] ,
345
391
) ;
346
392
393
+ // Build debug object to return
394
+ let debugOutput ;
395
+ if ( debugBindings ) {
396
+ debugOutput . bindings = debug . bindings ;
397
+ debugOutput . workDir = workDir ;
398
+ }
399
+ if ( debug ?. binary ) {
400
+ debugOutput . binary = debug . binary ;
401
+ debugOutput . binaryPath = debug . binaryPath ;
402
+ }
403
+
347
404
return {
348
405
component,
349
406
imports,
407
+ debug : debugOutput ,
350
408
} ;
351
409
}
352
410
0 commit comments