@bytecodealliance/jco 1.13.3 → 1.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,7 @@
1
1
  /* global Buffer */
2
2
 
3
- import { platform } from 'node:process';
4
3
  import { extname, basename, resolve } from 'node:path';
5
4
 
6
- import c from 'chalk-template';
7
5
  import { minify } from 'terser';
8
6
  import { fileURLToPath } from 'url';
9
7
 
@@ -16,15 +14,17 @@ import {
16
14
  setShowSpinner,
17
15
  getShowSpinner,
18
16
  writeFiles,
17
+ styleText,
19
18
  ASYNC_WASI_IMPORTS,
20
19
  ASYNC_WASI_EXPORTS,
20
+ DEFAULT_ASYNC_MODE,
21
21
  } from '../common.js';
22
22
  import { $init as wasmToolsInit, tools } from '../../obj/wasm-tools.js';
23
23
  const { componentEmbed, componentNew } = tools;
24
24
 
25
25
  import ora from '#ora';
26
26
 
27
- const isWindows = platform === 'win32';
27
+ import { isWindows } from '../common.js';
28
28
 
29
29
  // These re-exports exist to avoid breaking backwards compatibility
30
30
  export { types, guestTypes, typesComponent } from './types.js';
@@ -122,6 +122,7 @@ async function wasm2Js(source) {
122
122
  * multiMemory?: bool,
123
123
  * experimentalIdlImports?: bool,
124
124
  * optArgs?: string[],
125
+ * wasmOptBin?: string[],
125
126
  * }} opts
126
127
  * @returns {Promise<{ files: { [filename: string]: Uint8Array }, imports: string[], exports: [string, 'function' | 'instance'][] }>}
127
128
  */
@@ -168,22 +169,36 @@ export async function transpileComponent(component, opts = {}) {
168
169
  instantiation = { tag: 'async' };
169
170
  }
170
171
 
171
- const asyncMode =
172
- !opts.asyncMode || opts.asyncMode === 'sync'
173
- ? null
174
- : {
175
- tag: opts.asyncMode,
176
- val: {
177
- imports: opts.asyncImports || [],
178
- exports: opts.asyncExports || [],
179
- },
180
- };
172
+ // Get the configured async mode then transform it into what the types component expects
173
+ // Build list of async imports/exports
174
+ let asyncImports = new Set([...(opts.asyncImports ?? [])]);
175
+ let asyncExports = new Set([...(opts.asyncExports ?? [])]);
176
+ let asyncMode = opts.asyncMode ?? DEFAULT_ASYNC_MODE;
177
+ if (asyncMode === 'sync' && asyncExports.size > 0) {
178
+ throw new Error(
179
+ 'async exports cannot be specified in sync mode (consider removing --async-mode=jspi)'
180
+ );
181
+ }
182
+ let asyncModeObj;
183
+ if (asyncMode === 'sync') {
184
+ asyncModeObj = null;
185
+ } else if (asyncMode === 'jspi') {
186
+ asyncModeObj = {
187
+ tag: 'jspi',
188
+ val: {
189
+ imports: [...asyncImports],
190
+ exports: [...asyncExports],
191
+ },
192
+ };
193
+ } else {
194
+ throw new Error(`invalid/unrecognized async mode [${asyncMode}]`);
195
+ }
181
196
 
182
197
  let { files, imports, exports } = generate(component, {
183
198
  name: opts.name ?? 'component',
184
199
  map: Object.entries(opts.map ?? {}),
185
200
  instantiation,
186
- asyncMode,
201
+ asyncMode: asyncModeObj,
187
202
  importBindings: opts.importBindings
188
203
  ? { tag: opts.importBindings }
189
204
  : null,
@@ -276,7 +291,7 @@ export async function transpileComponent(component, opts = {}) {
276
291
  // Configure the spinner.
277
292
  let completed = 0;
278
293
  const spinnerText = () =>
279
- c`{cyan ${completed} / ${wasmFiles.length}} Running Binaryen wasm2js on Wasm core modules (this takes a while)...\n`;
294
+ `${styleText("cyan", `${completed} / ${wasmFiles.length}`)} Running Binaryen wasm2js on Wasm core modules (this takes a while)...\n`;
280
295
  if (showSpinner) {
281
296
  spinner = ora({
282
297
  color: 'cyan',
@@ -302,16 +317,16 @@ export async function transpileComponent(component, opts = {}) {
302
317
  .map(
303
318
  (asm, nth) => `function asm${nth}(imports) {
304
319
  ${
305
- // strip and replace the asm instantiation wrapper
306
- asm
307
- .replace(/import \* as [^ ]+ from '[^']*';/g, '')
308
- .replace('function asmFunc(imports) {', '')
309
- .replace(/export var ([^ ]+) = ([^. ]+)\.([^ ]+);/g, '')
310
- .replace(/var retasmFunc = [\s\S]*$/, '')
311
- .replace(/var memasmFunc = new ArrayBuffer\(0\);/g, '')
312
- .replace('memory.grow = __wasm_memory_grow;', '')
313
- .trim()
314
- }`
320
+ // strip and replace the asm instantiation wrapper
321
+ asm
322
+ .replace(/import \* as [^ ]+ from '[^']*';/g, '')
323
+ .replace('function asmFunc(imports) {', '')
324
+ .replace(/export var ([^ ]+) = ([^. ]+)\.([^ ]+);/g, '')
325
+ .replace(/var retasmFunc = [\s\S]*$/, '')
326
+ .replace(/var memasmFunc = new ArrayBuffer\(0\);/g, '')
327
+ .replace('memory.grow = __wasm_memory_grow;', '')
328
+ .trim()
329
+ }`
315
330
  )
316
331
  .join(',\n');
317
332
 
@@ -352,14 +367,14 @@ ${
352
367
  // Exporting `$init` must come first to not break the transpiling tests.
353
368
  opts.tlaCompat ? ' $init,\n' : ''
354
369
  }${exports
355
- .map(([name]) => {
356
- if (name === asmMangle(name)) {
357
- return ` ${name},`;
358
- } else {
359
- return ` ${asmMangle(name)} as '${name}',`;
360
- }
361
- })
362
- .join('\n')}
370
+ .map(([name]) => {
371
+ if (name === asmMangle(name)) {
372
+ return ` ${name},`;
373
+ } else {
374
+ return ` ${asmMangle(name)} as '${name}',`;
375
+ }
376
+ })
377
+ .join('\n')}
363
378
  }`;
364
379
  }
365
380
 
@@ -368,35 +383,35 @@ ${
368
383
  .map(([name]) => `_${asmMangle(name)}`)
369
384
  .join(', ')};
370
385
  ${exports
371
- .map(([name, ty]) => {
372
- if (ty === 'function') {
373
- return `\nfunction ${asmMangle(name)} () {
386
+ .map(([name, ty]) => {
387
+ if (ty === 'function') {
388
+ return `\nfunction ${asmMangle(name)} () {
374
389
  return _${asmMangle(name)}.apply(this, arguments);
375
390
  }`;
376
- } else {
377
- return `\nlet ${asmMangle(name)};`;
378
- }
379
- })
380
- .join('\n')}`;
391
+ } else {
392
+ return `\nlet ${asmMangle(name)};`;
393
+ }
394
+ })
395
+ .join('\n')}`;
381
396
 
382
397
  autoInstantiate = `${async_}function $init() {
383
398
  ( {
384
399
  ${exports
385
- .map(([name, ty]) => {
386
- if (ty === 'function') {
387
- return ` '${name}': _${asmMangle(name)},`;
388
- } else if (asmMangle(name) === name) {
389
- return ` ${name},`;
390
- } else {
391
- return ` '${name}': ${asmMangle(name)},`;
392
- }
393
- })
394
- .join('\n')}
400
+ .map(([name, ty]) => {
401
+ if (ty === 'function') {
402
+ return ` '${name}': _${asmMangle(name)},`;
403
+ } else if (asmMangle(name) === name) {
404
+ return ` ${name},`;
405
+ } else {
406
+ return ` '${name}': ${asmMangle(name)},`;
407
+ }
408
+ })
409
+ .join('\n')}
395
410
  } = ${await_}instantiate(
396
411
  {
397
412
  ${imports
398
- .map((import_file, nth) => ` '${import_file}': import${nth},`)
399
- .join('\n')}
413
+ .map((import_file, nth) => ` '${import_file}': import${nth},`)
414
+ .join('\n')}
400
415
  }
401
416
  ) )
402
417
  }
@@ -465,6 +480,41 @@ function asmMangle(name) {
465
480
 
466
481
  // Names must start with a character, $ or _
467
482
  switch (name[0]) {
483
+ case '0':
484
+ case '1':
485
+ case '2':
486
+ case '3':
487
+ case '4':
488
+ case '5':
489
+ case '6':
490
+ case '7':
491
+ case '8':
492
+ case '9': {
493
+ name = '$' + name;
494
+ i = 2;
495
+ // fallthrough
496
+ }
497
+ case '$':
498
+ case '_': {
499
+ mightBeKeyword = false;
500
+ break;
501
+ }
502
+ default: {
503
+ let chNum = name.charCodeAt(0);
504
+ if (
505
+ !(chNum >= 97 && chNum <= 122) &&
506
+ !(chNum >= 65 && chNum <= 90)
507
+ ) {
508
+ name = '$' + name.substr(1);
509
+ mightBeKeyword = false;
510
+ }
511
+ }
512
+ }
513
+
514
+ // Names must contain only characters, digits, $ or _
515
+ let len = name.length;
516
+ for (; i < len; ++i) {
517
+ switch (name[i]) {
468
518
  case '0':
469
519
  case '1':
470
520
  case '2':
@@ -474,194 +524,159 @@ function asmMangle(name) {
474
524
  case '6':
475
525
  case '7':
476
526
  case '8':
477
- case '9': {
478
- name = '$' + name;
479
- i = 2;
480
- // fallthrough
481
- }
527
+ case '9':
482
528
  case '$':
483
529
  case '_': {
484
530
  mightBeKeyword = false;
485
531
  break;
486
532
  }
487
533
  default: {
488
- let chNum = name.charCodeAt(0);
534
+ let chNum = name.charCodeAt(i);
489
535
  if (
490
536
  !(chNum >= 97 && chNum <= 122) &&
491
- !(chNum >= 65 && chNum <= 90)
537
+ !(chNum >= 65 && chNum <= 90)
492
538
  ) {
493
- name = '$' + name.substr(1);
539
+ name = name.substr(0, i) + '_' + name.substr(i + 1);
494
540
  mightBeKeyword = false;
495
541
  }
496
542
  }
497
- }
498
-
499
- // Names must contain only characters, digits, $ or _
500
- let len = name.length;
501
- for (; i < len; ++i) {
502
- switch (name[i]) {
503
- case '0':
504
- case '1':
505
- case '2':
506
- case '3':
507
- case '4':
508
- case '5':
509
- case '6':
510
- case '7':
511
- case '8':
512
- case '9':
513
- case '$':
514
- case '_': {
515
- mightBeKeyword = false;
516
- break;
517
- }
518
- default: {
519
- let chNum = name.charCodeAt(i);
520
- if (
521
- !(chNum >= 97 && chNum <= 122) &&
522
- !(chNum >= 65 && chNum <= 90)
523
- ) {
524
- name = name.substr(0, i) + '_' + name.substr(i + 1);
525
- mightBeKeyword = false;
526
- }
527
- }
528
543
  }
529
544
  }
530
545
 
531
546
  // Names must not collide with keywords
532
547
  if (mightBeKeyword && len >= 2 && len <= 10) {
533
548
  switch (name[0]) {
534
- case 'a': {
535
- if (name == 'arguments') {
536
- return name + '_';
537
- }
538
- break;
549
+ case 'a': {
550
+ if (name == 'arguments') {
551
+ return name + '_';
539
552
  }
540
- case 'b': {
541
- if (name == 'break') {
542
- return name + '_';
543
- }
544
- break;
553
+ break;
554
+ }
555
+ case 'b': {
556
+ if (name == 'break') {
557
+ return name + '_';
545
558
  }
546
- case 'c': {
547
- if (
548
- name == 'case' ||
559
+ break;
560
+ }
561
+ case 'c': {
562
+ if (
563
+ name == 'case' ||
549
564
  name == 'continue' ||
550
565
  name == 'catch' ||
551
566
  name == 'const' ||
552
567
  name == 'class'
553
- ) {
554
- return name + '_';
555
- }
556
- break;
568
+ ) {
569
+ return name + '_';
557
570
  }
558
- case 'd': {
559
- if (name == 'do' || name == 'default' || name == 'debugger') {
560
- return name + '_';
561
- }
562
- break;
571
+ break;
572
+ }
573
+ case 'd': {
574
+ if (name == 'do' || name == 'default' || name == 'debugger') {
575
+ return name + '_';
563
576
  }
564
- case 'e': {
565
- if (
566
- name == 'else' ||
577
+ break;
578
+ }
579
+ case 'e': {
580
+ if (
581
+ name == 'else' ||
567
582
  name == 'enum' ||
568
583
  name == 'eval' || // to be sure
569
584
  name == 'export' ||
570
585
  name == 'extends'
571
- ) {
572
- return name + '_';
573
- }
574
- break;
586
+ ) {
587
+ return name + '_';
575
588
  }
576
- case 'f': {
577
- if (
578
- name == 'for' ||
589
+ break;
590
+ }
591
+ case 'f': {
592
+ if (
593
+ name == 'for' ||
579
594
  name == 'false' ||
580
595
  name == 'finally' ||
581
596
  name == 'function'
582
- ) {
583
- return name + '_';
584
- }
585
- break;
597
+ ) {
598
+ return name + '_';
586
599
  }
587
- case 'i': {
588
- if (
589
- name == 'if' ||
600
+ break;
601
+ }
602
+ case 'i': {
603
+ if (
604
+ name == 'if' ||
590
605
  name == 'in' ||
591
606
  name == 'import' ||
592
607
  name == 'interface' ||
593
608
  name == 'implements' ||
594
609
  name == 'instanceof'
595
- ) {
596
- return name + '_';
597
- }
598
- break;
610
+ ) {
611
+ return name + '_';
599
612
  }
600
- case 'l': {
601
- if (name == 'let') {
602
- return name + '_';
603
- }
604
- break;
613
+ break;
614
+ }
615
+ case 'l': {
616
+ if (name == 'let') {
617
+ return name + '_';
605
618
  }
606
- case 'n': {
607
- if (name == 'new' || name == 'null') {
608
- return name + '_';
609
- }
610
- break;
619
+ break;
620
+ }
621
+ case 'n': {
622
+ if (name == 'new' || name == 'null') {
623
+ return name + '_';
611
624
  }
612
- case 'p': {
613
- if (
614
- name == 'public' ||
625
+ break;
626
+ }
627
+ case 'p': {
628
+ if (
629
+ name == 'public' ||
615
630
  name == 'package' ||
616
631
  name == 'private' ||
617
632
  name == 'protected'
618
- ) {
619
- return name + '_';
620
- }
621
- break;
633
+ ) {
634
+ return name + '_';
622
635
  }
623
- case 'r': {
624
- if (name == 'return') {
625
- return name + '_';
626
- }
627
- break;
636
+ break;
637
+ }
638
+ case 'r': {
639
+ if (name == 'return') {
640
+ return name + '_';
628
641
  }
629
- case 's': {
630
- if (name == 'super' || name == 'static' || name == 'switch') {
631
- return name + '_';
632
- }
633
- break;
642
+ break;
643
+ }
644
+ case 's': {
645
+ if (name == 'super' || name == 'static' || name == 'switch') {
646
+ return name + '_';
634
647
  }
635
- case 't': {
636
- if (
637
- name == 'try' ||
648
+ break;
649
+ }
650
+ case 't': {
651
+ if (
652
+ name == 'try' ||
638
653
  name == 'this' ||
639
654
  name == 'true' ||
640
655
  name == 'throw' ||
641
656
  name == 'typeof'
642
- ) {
643
- return name + '_';
644
- }
645
- break;
657
+ ) {
658
+ return name + '_';
646
659
  }
647
- case 'v': {
648
- if (name == 'var' || name == 'void') {
649
- return name + '_';
650
- }
651
- break;
660
+ break;
661
+ }
662
+ case 'v': {
663
+ if (name == 'var' || name == 'void') {
664
+ return name + '_';
652
665
  }
653
- case 'w': {
654
- if (name == 'with' || name == 'while') {
655
- return name + '_';
656
- }
657
- break;
666
+ break;
667
+ }
668
+ case 'w': {
669
+ if (name == 'with' || name == 'while') {
670
+ return name + '_';
658
671
  }
659
- case 'y': {
660
- if (name == 'yield') {
661
- return name + '_';
662
- }
663
- break;
672
+ break;
673
+ }
674
+ case 'y': {
675
+ if (name == 'yield') {
676
+ return name + '_';
664
677
  }
678
+ break;
679
+ }
665
680
  }
666
681
  }
667
682
  return name;