@agoric/xsnap 0.14.3-u14.0 → 0.14.3-u16.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.
Files changed (137) hide show
  1. package/README.md +3 -3
  2. package/api.js +4 -2
  3. package/build.env +1 -1
  4. package/moddable/modules/data/base64/base64.js +28 -0
  5. package/moddable/modules/data/base64/manifest.json +11 -0
  6. package/moddable/modules/data/base64/modBase64.c +188 -0
  7. package/moddable/modules/data/binaryMessage/BinaryMessage.js +106 -0
  8. package/moddable/modules/data/crc/crc.c +205 -0
  9. package/moddable/modules/data/crc/crc.js +36 -0
  10. package/moddable/modules/data/crc/manifest.json +8 -0
  11. package/moddable/modules/data/hex/hex.js +28 -0
  12. package/moddable/modules/data/hex/manifest.json +11 -0
  13. package/moddable/modules/data/hex/modHex.c +139 -0
  14. package/moddable/modules/data/logical/logical.js +32 -0
  15. package/moddable/modules/data/logical/modLogical.c +98 -0
  16. package/moddable/modules/data/qrcode/manifest.json +9 -0
  17. package/moddable/modules/data/qrcode/qrcode.c +93 -0
  18. package/moddable/modules/data/qrcode/qrcode.js +23 -0
  19. package/moddable/modules/data/qrcode/qrcodegen.c +1025 -0
  20. package/moddable/modules/data/qrcode/qrcodegen.h +267 -0
  21. package/moddable/modules/data/text/decoder/manifest.json +8 -0
  22. package/moddable/modules/data/text/decoder/textdecoder.c +480 -0
  23. package/moddable/modules/data/text/decoder/textdecoder.js +27 -0
  24. package/moddable/modules/data/text/encoder/manifest.json +8 -0
  25. package/moddable/modules/data/text/encoder/textencoder.c +232 -0
  26. package/moddable/modules/data/text/encoder/textencoder.js +24 -0
  27. package/moddable/modules/data/tinyint/tinyint.c +150 -0
  28. package/moddable/modules/data/tinyint/tinyint.js +53 -0
  29. package/moddable/modules/data/url/manifest.json +17 -0
  30. package/moddable/modules/data/url/url.c +1959 -0
  31. package/moddable/modules/data/url/url.js +210 -0
  32. package/moddable/modules/data/wavreader/manifest.json +8 -0
  33. package/moddable/modules/data/wavreader/wavreader.js +128 -0
  34. package/moddable/modules/data/zlib/deflate.c +161 -0
  35. package/moddable/modules/data/zlib/deflate.js +63 -0
  36. package/moddable/modules/data/zlib/inflate.c +145 -0
  37. package/moddable/modules/data/zlib/inflate.js +66 -0
  38. package/moddable/modules/data/zlib/manifest_deflate.json +9 -0
  39. package/moddable/modules/data/zlib/manifest_inflate.json +9 -0
  40. package/moddable/modules/data/zlib/miniz.c +4924 -0
  41. package/moddable/xs/includes/xs.d.ts +73 -0
  42. package/moddable/xs/includes/xs.h +1533 -0
  43. package/moddable/xs/includes/xsmc.h +206 -0
  44. package/moddable/xs/makefiles/lin/makefile +33 -0
  45. package/moddable/xs/makefiles/lin/xsc.mk +118 -0
  46. package/moddable/xs/makefiles/lin/xsid.mk +90 -0
  47. package/moddable/xs/makefiles/lin/xsl.mk +168 -0
  48. package/moddable/xs/makefiles/lin/xst.mk +201 -0
  49. package/moddable/xs/makefiles/mac/makefile +33 -0
  50. package/moddable/xs/makefiles/mac/xsc.mk +130 -0
  51. package/moddable/xs/makefiles/mac/xsid.mk +102 -0
  52. package/moddable/xs/makefiles/mac/xsl.mk +177 -0
  53. package/moddable/xs/makefiles/mac/xst.mk +203 -0
  54. package/moddable/xs/makefiles/mac/xst_no_asan.txt +52 -0
  55. package/moddable/xs/makefiles/win/build.bat +26 -0
  56. package/moddable/xs/makefiles/win/xsc.mak +142 -0
  57. package/moddable/xs/makefiles/win/xsid.mak +113 -0
  58. package/moddable/xs/makefiles/win/xsl.mak +186 -0
  59. package/moddable/xs/makefiles/win/xst.mak +195 -0
  60. package/moddable/xs/platforms/lin_xs.h +99 -0
  61. package/moddable/xs/platforms/mac_xs.h +97 -0
  62. package/moddable/xs/platforms/wasm_xs.h +79 -0
  63. package/moddable/xs/platforms/win_xs.h +104 -0
  64. package/moddable/xs/platforms/xsHost.h +63 -0
  65. package/moddable/xs/platforms/xsPlatform.h +618 -0
  66. package/moddable/xs/sources/xsAPI.c +2555 -0
  67. package/moddable/xs/sources/xsAll.c +294 -0
  68. package/moddable/xs/sources/xsAll.h +2741 -0
  69. package/moddable/xs/sources/xsArguments.c +222 -0
  70. package/moddable/xs/sources/xsArray.c +2657 -0
  71. package/moddable/xs/sources/xsAtomics.c +844 -0
  72. package/moddable/xs/sources/xsBigInt.c +1859 -0
  73. package/moddable/xs/sources/xsBoolean.c +109 -0
  74. package/moddable/xs/sources/xsCode.c +4493 -0
  75. package/moddable/xs/sources/xsCommon.c +1710 -0
  76. package/moddable/xs/sources/xsCommon.h +1142 -0
  77. package/moddable/xs/sources/xsDataView.c +2890 -0
  78. package/moddable/xs/sources/xsDate.c +1541 -0
  79. package/moddable/xs/sources/xsDebug.c +2710 -0
  80. package/moddable/xs/sources/xsDefaults.c +134 -0
  81. package/moddable/xs/sources/xsError.c +353 -0
  82. package/moddable/xs/sources/xsFunction.c +776 -0
  83. package/moddable/xs/sources/xsGenerator.c +865 -0
  84. package/moddable/xs/sources/xsGlobal.c +839 -0
  85. package/moddable/xs/sources/xsJSON.c +1091 -0
  86. package/moddable/xs/sources/xsLexical.c +1969 -0
  87. package/moddable/xs/sources/xsLockdown.c +933 -0
  88. package/moddable/xs/sources/xsMapSet.c +1649 -0
  89. package/moddable/xs/sources/xsMarshall.c +1020 -0
  90. package/moddable/xs/sources/xsMath.c +624 -0
  91. package/moddable/xs/sources/xsMemory.c +1941 -0
  92. package/moddable/xs/sources/xsModule.c +3101 -0
  93. package/moddable/xs/sources/xsNumber.c +560 -0
  94. package/moddable/xs/sources/xsObject.c +1102 -0
  95. package/moddable/xs/sources/xsPlatforms.c +480 -0
  96. package/moddable/xs/sources/xsProfile.c +577 -0
  97. package/moddable/xs/sources/xsPromise.c +1199 -0
  98. package/moddable/xs/sources/xsProperty.c +636 -0
  99. package/moddable/xs/sources/xsProxy.c +1014 -0
  100. package/moddable/xs/sources/xsRegExp.c +1168 -0
  101. package/moddable/xs/sources/xsRun.c +4889 -0
  102. package/moddable/xs/sources/xsScope.c +1293 -0
  103. package/moddable/xs/sources/xsScript.c +288 -0
  104. package/moddable/xs/sources/xsScript.h +1186 -0
  105. package/moddable/xs/sources/xsSnapshot.c +2161 -0
  106. package/moddable/xs/sources/xsSnapshot.h +51 -0
  107. package/moddable/xs/sources/xsSourceMap.c +218 -0
  108. package/moddable/xs/sources/xsString.c +3332 -0
  109. package/moddable/xs/sources/xsSymbol.c +503 -0
  110. package/moddable/xs/sources/xsSyntaxical.c +4193 -0
  111. package/moddable/xs/sources/xsTree.c +1893 -0
  112. package/moddable/xs/sources/xsType.c +1488 -0
  113. package/moddable/xs/sources/xsdtoa.c +6672 -0
  114. package/moddable/xs/sources/xsmc.c +340 -0
  115. package/moddable/xs/sources/xsre.c +7578 -0
  116. package/package.json +37 -20
  117. package/scripts/get_xsnap_version.sh +14 -0
  118. package/scripts/test-package.sh +21 -0
  119. package/src/avaAssertXS.js +6 -2
  120. package/src/avaHandler.cjs +2 -5
  121. package/src/avaXS.js +7 -8
  122. package/src/build.js +161 -28
  123. package/src/replay.js +0 -3
  124. package/src/xsnap.js +105 -91
  125. package/src/xsrepl.js +2 -3
  126. package/xsnap-native/xsnap/makefiles/lin/makefile +10 -0
  127. package/xsnap-native/xsnap/makefiles/lin/xsnap-worker.mk +156 -0
  128. package/xsnap-native/xsnap/makefiles/lin/xsnap.mk +144 -0
  129. package/xsnap-native/xsnap/makefiles/mac/makefile +10 -0
  130. package/xsnap-native/xsnap/makefiles/mac/xsnap-worker.mk +165 -0
  131. package/xsnap-native/xsnap/makefiles/mac/xsnap.mk +153 -0
  132. package/xsnap-native/xsnap/sources/xsnap-worker.c +1008 -0
  133. package/xsnap-native/xsnap/sources/xsnap.c +717 -0
  134. package/xsnap-native/xsnap/sources/xsnap.h +142 -0
  135. package/xsnap-native/xsnap/sources/xsnapPlatform.c +1501 -0
  136. package/xsnap-native/xsnap/sources/xsnapPlatform.h +105 -0
  137. package/CHANGELOG.md +0 -654
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agoric/xsnap",
3
- "version": "0.14.3-u14.0",
3
+ "version": "0.14.3-u16.0",
4
4
  "description": "Snapshotting VM worker based on Moddable's XS Javascript engine",
5
5
  "author": "Agoric",
6
6
  "license": "Apache-2.0",
@@ -13,53 +13,70 @@
13
13
  "scripts": {
14
14
  "repl": "node src/xsrepl.js",
15
15
  "build:bin": "if test -d ./test; then node src/build.js; else yarn build:from-env; fi",
16
- "build:env": "test -d ./test && node src/build.js --show-env > build.env",
16
+ "build:env": "node src/build.js --show-env > build.env",
17
17
  "build:from-env": "{ cat build.env; echo node src/build.js; } | xargs env",
18
18
  "build": "yarn build:bin && yarn build:env",
19
- "postinstall": "yarn build:from-env",
19
+ "check-version": "xsnap_version=$(./scripts/get_xsnap_version.sh); if test \"${npm_package_version}\" != \"${xsnap_version}\"; then echo \"xsnap version mismatch; expected '${npm_package_version}', got '${xsnap_version}'\"; exit 1; fi",
20
+ "postinstall": "npm run build:from-env",
20
21
  "clean": "rm -rf xsnap-native/xsnap/build",
21
22
  "lint": "run-s --continue-on-error lint:*",
22
23
  "lint:js": "eslint 'src/**/*.js' 'test/**/*.js' api.js",
23
- "lint:types": "tsc -p jsconfig.json",
24
+ "lint:types": "tsc",
24
25
  "lint-fix": "eslint --fix 'src/**/*.js' 'test/**/*.js' api.js",
25
26
  "test": "ava",
26
27
  "test:c8": "c8 $C8_OPTIONS ava --config=ava-nesm.config.js",
27
28
  "test:xs": "exit 0"
28
29
  },
29
30
  "dependencies": {
30
- "@agoric/assert": "^0.6.1-u11wf.0",
31
- "@agoric/internal": "^0.4.0-u14.0",
32
- "@agoric/xsnap-lockdown": "^0.14.1-u13.0",
33
- "@endo/bundle-source": "2.5.2-upstream-rollup",
34
- "@endo/eventual-send": "0.17.2",
35
- "@endo/init": "0.5.56",
36
- "@endo/netstring": "0.3.26",
37
- "@endo/promise-kit": "0.2.56",
38
- "@endo/stream": "0.3.25",
39
- "@endo/stream-node": "0.2.26",
31
+ "@agoric/assert": "^0.6.1-u16.0",
32
+ "@agoric/internal": "^0.4.0-u16.0",
33
+ "@agoric/xsnap-lockdown": "^0.14.1-u16.0",
34
+ "@endo/bundle-source": "^3.2.3",
35
+ "@endo/eventual-send": "^1.2.2",
36
+ "@endo/init": "^1.1.2",
37
+ "@endo/netstring": "^1.0.7",
38
+ "@endo/promise-kit": "^1.1.2",
39
+ "@endo/stream": "^1.2.2",
40
+ "@endo/stream-node": "^1.1.2",
40
41
  "glob": "^7.1.6",
41
42
  "tmp": "^0.2.1"
42
43
  },
43
44
  "devDependencies": {
44
- "@endo/base64": "0.2.31",
45
- "ava": "^5.2.0",
46
- "c8": "^7.13.0"
45
+ "@endo/base64": "^1.0.5",
46
+ "@endo/nat": "^5.0.7",
47
+ "@types/glob": "^8.1.0",
48
+ "ava": "^5.3.0",
49
+ "c8": "^9.1.0"
47
50
  },
48
51
  "files": [
49
52
  "LICENSE*",
50
53
  "api.js",
51
54
  "build.env",
52
- "src"
55
+ "moddable/modules/data",
56
+ "moddable/xs/includes",
57
+ "moddable/xs/makefiles",
58
+ "moddable/xs/platforms/*.h",
59
+ "moddable/xs/sources",
60
+ "scripts",
61
+ "src",
62
+ "xsnap-native/xsnap/makefiles",
63
+ "xsnap-native/xsnap/sources"
53
64
  ],
54
65
  "publishConfig": {
55
66
  "access": "public"
56
67
  },
57
68
  "ava": {
58
69
  "files": [
59
- "test/**/test-*.js"
70
+ "test/**/*.test.*"
71
+ ],
72
+ "require": [
73
+ "@endo/init/debug.js"
60
74
  ],
61
75
  "timeout": "2m",
62
76
  "workerThreads": false
63
77
  },
64
- "gitHead": "b3a6f3374cb3bddab39fc6d6f426429cae6c29c6"
78
+ "typeCoverage": {
79
+ "atLeast": 93.95
80
+ },
81
+ "gitHead": "bbdf652c3f413381cb352a8a360db1063974fafd"
65
82
  }
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env bash
2
+
3
+ set -ueo pipefail
4
+
5
+ # the xsnap binary lives in a platform-specific directory
6
+ unameOut="$(uname -s)"
7
+ case "${unameOut}" in
8
+ Linux*) platform=lin ;;
9
+ Darwin*) platform=mac ;;
10
+ *) platform=win ;;
11
+ esac
12
+
13
+ # extract the xsnap package version from the long version printed by xsnap-worker
14
+ "./xsnap-native/xsnap/build/bin/${platform}/release/xsnap-worker" -v | sed -e 's/^xsnap \([^ ]*\) (XS [^)]*)$/\1/g'
@@ -0,0 +1,21 @@
1
+ #!/bin/bash
2
+ # Verifies that files in package.json covers everything xsnap needs to compile
3
+ # from sources out of an npm package.
4
+ set -xueo pipefail
5
+
6
+ TEMP=$(mktemp -d)
7
+ # function cleanup() {
8
+ # rm -rf "$TEMP"
9
+ # }
10
+ # trap cleanup EXIT
11
+
12
+ yarn pack -f "$TEMP/package.tar"
13
+ (
14
+ cd "$TEMP"
15
+ tar xvf package.tar
16
+ cd package
17
+ time yarn
18
+ time yarn
19
+ time yarn
20
+ time yarn
21
+ )
@@ -1,5 +1,4 @@
1
1
  /* global globalThis */
2
- /* eslint-disable no-await-in-loop, @jessie.js/no-nested-await -- test code */
3
2
  /** global print */
4
3
 
5
4
  const { assign, freeze, keys } = Object;
@@ -67,7 +66,7 @@ function deepDifference(x, y) {
67
66
  * @param {(msg: TapMessage) => void} send
68
67
  *
69
68
  * @typedef { ReturnType<typeof tapFormat> } TapFormat
70
- * @typedef {import('./avaXS').TapMessage} TapMessage
69
+ * @import {TapMessage} from './avaXS.js'
71
70
  */
72
71
  function tapFormat(send) {
73
72
  return freeze({
@@ -229,6 +228,8 @@ function makeTester(htest, out) {
229
228
  fail(message) {
230
229
  assert(false, message);
231
230
  },
231
+ // Not the SES or @endo/errors `assert`
232
+ // See https://github.com/Agoric/agoric-sdk/issues/9515
232
233
  assert,
233
234
  truthy,
234
235
  /**
@@ -300,6 +301,7 @@ function makeTester(htest, out) {
300
301
  expectation,
301
302
  message = `should reject like ${expectation}`,
302
303
  ) {
304
+ await null;
303
305
  try {
304
306
  await (typeof thrower === 'function' ? thrower() : thrower);
305
307
  assert(false, message);
@@ -310,6 +312,7 @@ function makeTester(htest, out) {
310
312
  },
311
313
  /** @type {(thrower: () => Promise<unknown>, message?: string) => Promise<void> } */
312
314
  async notThrowsAsync(nonThrower, message) {
315
+ await null;
313
316
  try {
314
317
  await (typeof nonThrower === 'function' ? nonThrower() : nonThrower);
315
318
  } catch (ex) {
@@ -335,6 +338,7 @@ const test = (label, run, htestOpt) => {
335
338
  htest.queue(label, async () => {
336
339
  const out = tapFormat(htest.send);
337
340
  const t = makeTester(htest, out);
341
+ await null;
338
342
  try {
339
343
  // out.diagnostic('start', label);
340
344
  await run(t);
@@ -12,7 +12,6 @@ HandledPromise is defined by eventual send shim.
12
12
  /// <reference types="ses" />
13
13
  /// <reference types="@endo/eventual-send" />
14
14
 
15
- // @ts-expect-error cannot redeclare encoder
16
15
  const encoder = new TextEncoder();
17
16
  const decoder = new TextDecoder();
18
17
 
@@ -20,7 +19,7 @@ const decoder = new TextDecoder();
20
19
  * @param {{ testNames: string[]} |
21
20
  * { bundleSource: [string, ...unknown[]] } |
22
21
  * TapMessage | Summary } item
23
- * @typedef {import('./avaXS').Summary} Summary
22
+ * @import {Summary} from './avaXS'
24
23
  */
25
24
  function send(item) {
26
25
  const msg = encoder.encode(JSON.stringify(item)).buffer;
@@ -33,7 +32,6 @@ function send(item) {
33
32
  */
34
33
  const bundleSource = async (startFilename, ...args) => {
35
34
  const msg = await send({ bundleSource: [startFilename, ...args] });
36
- // @ts-expect-error send() returns void
37
35
  return JSON.parse(decoder.decode(msg));
38
36
  };
39
37
 
@@ -79,7 +77,7 @@ function handler(rawMessage) {
79
77
  const { source } = msg;
80
78
  const virtualObjectGlobals =
81
79
  // @ts-expect-error
82
- // eslint-disable-next-line no-undef
80
+
83
81
  typeof VatData !== 'undefined' ? { VatData } : {};
84
82
  const c = new Compartment({
85
83
  require: testRequire,
@@ -87,7 +85,6 @@ function handler(rawMessage) {
87
85
  __filename,
88
86
  console,
89
87
  assert,
90
- // @ts-expect-error
91
88
  HandledPromise,
92
89
  URL: class URLStub {
93
90
  constructor(url, base) {
package/src/avaXS.js CHANGED
@@ -2,11 +2,10 @@
2
2
 
3
3
  Usage:
4
4
 
5
- node avaXS.js [--debug] test-*.js
5
+ node avaXS.js [--debug] *.test.js
6
6
 
7
7
  */
8
8
 
9
- /* eslint-disable no-await-in-loop, @jessie.js/no-nested-await -- test code */
10
9
  import '@endo/init';
11
10
 
12
11
  import fs from 'fs';
@@ -69,8 +68,6 @@ function isMatch(specimen, pattern) {
69
68
  *
70
69
  * It also calls back if a test calls `bundleSource`.
71
70
  *
72
- * @typedef {{ moduleFormat: string, source: string }} Bundle
73
- *
74
71
  * And finally it reports back a summary of assertion results.
75
72
  *
76
73
  * @typedef {{
@@ -84,7 +81,7 @@ function isMatch(specimen, pattern) {
84
81
  * @param {{ verbose?: boolean, titleMatch?: string }} options
85
82
  * @param {{
86
83
  * spawnXSnap: (opts: object) => XSnap,
87
- * bundleSource: (...args: [string, ...unknown[]]) => Promise<Bundle>,
84
+ * bundleSource: import('@endo/bundle-source').BundleSource,
88
85
  * resolve: ResolveFn,
89
86
  * dirname: typeof import('path').dirname,
90
87
  * basename: typeof import('path').basename,
@@ -93,7 +90,7 @@ function isMatch(specimen, pattern) {
93
90
  *
94
91
  * @typedef {{ total: number, pass: number, fail: { filename: string, name: string }[] }} TestResults
95
92
  * @typedef { 'ok' | 'not ok' | 'SKIP' } Status
96
- * @typedef {ReturnType<typeof import('./xsnap').xsnap>} XSnap
93
+ * @typedef {ReturnType<typeof import('./xsnap.js').xsnap>} XSnap
97
94
  */
98
95
  async function runTestScript(
99
96
  filename,
@@ -120,7 +117,7 @@ async function runTestScript(
120
117
  /**
121
118
  * See also send() in avaHandler.cjs
122
119
  *
123
- * @type { TapMessage | { testNames: string[] } | { bundleSource: [string, ...unknown[]] } | Summary }
120
+ * @type { TapMessage | { testNames: string[] } | { bundleSource: Parameters<import('@endo/bundle-source').BundleSource> } | Summary }
124
121
  */
125
122
  const msg = JSON.parse(decoder.decode(message));
126
123
  // console.log(input, msg, qty, byStatus);
@@ -129,6 +126,7 @@ async function runTestScript(
129
126
  testNames = msg.testNames;
130
127
  }
131
128
 
129
+ await null;
132
130
  if ('bundleSource' in msg) {
133
131
  const [startFilename, ...rest] = msg.bundleSource;
134
132
  // see also makeBundleResolve() below
@@ -244,6 +242,7 @@ async function avaConfig(args, options, { glob, readFile }) {
244
242
  let debug = false;
245
243
  let verbose = false;
246
244
  let titleMatch;
245
+ await null;
247
246
  while (args.length > 0) {
248
247
  const arg = args.shift();
249
248
  assert.typeof(arg, 'string');
@@ -301,7 +300,7 @@ async function avaConfig(args, options, { glob, readFile }) {
301
300
  /**
302
301
  * @param {string[]} args - CLI args (excluding node interpreter, script name)
303
302
  * @param {{
304
- * bundleSource: typeof import('@endo/bundle-source').default,
303
+ * bundleSource: import('@endo/bundle-source').BundleSource,
305
304
  * spawn: typeof import('child_process')['spawn'],
306
305
  * osType: typeof import('os')['type'],
307
306
  * readFile: typeof import('fs')['promises']['readFile'],
package/src/build.js CHANGED
@@ -1,6 +1,5 @@
1
1
  #!/usr/bin/env node
2
2
  /* global process */
3
- /* eslint-disable @jessie.js/no-nested-await -- test/build code */
4
3
  import * as childProcessTop from 'child_process';
5
4
  import fsTop from 'fs';
6
5
  import osTop from 'os';
@@ -140,7 +139,7 @@ const makeSubmodule = (path, repoUrl, { git }) => {
140
139
  };
141
140
 
142
141
  /**
143
- * @param {string[]} args
142
+ * @param {boolean} showEnv
144
143
  * @param {{
145
144
  * env: Record<string, string | undefined>,
146
145
  * stdout: typeof process.stdout,
@@ -150,12 +149,9 @@ const makeSubmodule = (path, repoUrl, { git }) => {
150
149
  * rmdirSync: typeof import('fs').rmdirSync,
151
150
  * readFile: typeof import('fs').promises.readFile,
152
151
  * },
153
- * os: {
154
- * type: typeof import('os').type,
155
- * }
156
152
  * }} io
157
153
  */
158
- async function main(args, { env, stdout, spawn, fs, os }) {
154
+ const updateSubmodules = async (showEnv, { env, stdout, spawn, fs }) => {
159
155
  const git = makeCLI('git', { spawn });
160
156
 
161
157
  // When changing/adding entries here, make sure to search the whole project
@@ -176,13 +172,13 @@ async function main(args, { env, stdout, spawn, fs, os }) {
176
172
  },
177
173
  ];
178
174
 
179
- if (args.includes('--show-env')) {
175
+ await null;
176
+ if (showEnv) {
180
177
  for (const submodule of submodules) {
181
178
  const { path, envPrefix, commitHash } = submodule;
182
179
  if (!commitHash) {
183
180
  // We need to glean the commitHash and url from Git.
184
181
  const sm = makeSubmodule(path, '?', { git });
185
- // eslint-disable-next-line no-await-in-loop
186
182
  const [[{ hash }], url] = await Promise.all([
187
183
  sm.status(),
188
184
  sm.config('url'),
@@ -208,20 +204,50 @@ async function main(args, { env, stdout, spawn, fs, os }) {
208
204
  // ignore
209
205
  }
210
206
  if (!fs.existsSync(submodule.path)) {
211
- // eslint-disable-next-line no-await-in-loop
212
207
  await submodule.clone();
213
208
  }
214
- // eslint-disable-next-line no-await-in-loop
215
209
  await submodule.checkout(commitHash);
216
210
  } else {
217
- // eslint-disable-next-line no-await-in-loop
218
211
  await submodule.init();
219
212
  }
220
213
  }
214
+ };
221
215
 
216
+ /**
217
+ * @param {{
218
+ * spawn: typeof import('child_process').spawn,
219
+ * fs: {
220
+ * existsSync: typeof import('fs').existsSync,
221
+ * rmdirSync: typeof import('fs').rmdirSync,
222
+ * readFile: typeof import('fs').promises.readFile,
223
+ * writeFile: typeof import('fs').promises.writeFile,
224
+ * },
225
+ * os: {
226
+ * type: typeof import('os').type,
227
+ * }
228
+ * }} io
229
+ * @param {object} [options]
230
+ * @param {boolean} [options.forceBuild]
231
+ */
232
+ const makeXsnap = async ({ spawn, fs, os }, { forceBuild = false } = {}) => {
222
233
  const pjson = await fs.readFile(asset('../package.json'), 'utf-8');
223
234
  const pkg = JSON.parse(pjson);
224
235
 
236
+ const configEnvs = [
237
+ `XSNAP_VERSION=${pkg.version}`,
238
+ `CC=cc "-D__has_builtin(x)=1"`,
239
+ ];
240
+
241
+ const configEnvFile = asset('../build.config.env');
242
+ const existingConfigEnvs = fs.existsSync(configEnvFile)
243
+ ? await fs.readFile(configEnvFile, 'utf-8')
244
+ : '';
245
+
246
+ const expectedConfigEnvs = configEnvs.concat('').join('\n');
247
+ if (forceBuild || existingConfigEnvs.trim() !== expectedConfigEnvs.trim()) {
248
+ await fs.writeFile(configEnvFile, expectedConfigEnvs);
249
+ }
250
+
225
251
  const platform = ModdableSDK.platforms[os.type()];
226
252
  if (!platform) {
227
253
  throw Error(`Unsupported OS found: ${os.type()}`);
@@ -229,13 +255,14 @@ async function main(args, { env, stdout, spawn, fs, os }) {
229
255
 
230
256
  const make = makeCLI(platform.make || 'make', { spawn });
231
257
  for (const goal of ModdableSDK.buildGoals) {
232
- // eslint-disable-next-line no-await-in-loop
233
258
  await make.run(
234
259
  [
235
260
  `MODDABLE=${ModdableSDK.MODDABLE}`,
236
261
  `GOAL=${goal}`,
237
- `XSNAP_VERSION=${pkg.version}`,
238
- `CC=cc "-D__has_builtin(x)=1"`,
262
+ // Any other configuration variables that affect the build output
263
+ // should be placed in `configEnvs` to force a rebuild if they change
264
+ ...configEnvs,
265
+ `EXTRA_DEPS=${configEnvFile}`,
239
266
  '-f',
240
267
  'xsnap-worker.mk',
241
268
  ],
@@ -244,21 +271,127 @@ async function main(args, { env, stdout, spawn, fs, os }) {
244
271
  },
245
272
  );
246
273
  }
274
+ };
275
+
276
+ /**
277
+ * @param {string[]} args
278
+ * @param {{
279
+ * env: Record<string, string | undefined>,
280
+ * stdout: typeof process.stdout,
281
+ * spawn: typeof import('child_process').spawn,
282
+ * fs: {
283
+ * existsSync: typeof import('fs').existsSync,
284
+ * rmdirSync: typeof import('fs').rmdirSync,
285
+ * readFile: typeof import('fs').promises.readFile,
286
+ * writeFile: typeof import('fs').promises.writeFile,
287
+ * },
288
+ * os: {
289
+ * type: typeof import('os').type,
290
+ * }
291
+ * }} io
292
+ */
293
+ async function main(args, { env, stdout, spawn, fs, os }) {
294
+ // I solemnly swear I will do no synchronous work followed by a variable
295
+ // number turns of the event loop.
296
+ await null;
297
+
298
+ const osType = os.type();
299
+ const platform = {
300
+ Linux: 'lin',
301
+ Darwin: 'mac',
302
+ // Windows_NT: 'win', // One can dream.
303
+ }[osType];
304
+ if (platform === undefined) {
305
+ throw Error(`xsnap does not support platform ${osType}`);
306
+ }
307
+
308
+ // If this is a working copy of xsnap in a checkout of agoric-sdk, we need to
309
+ // either clone or update submodules.
310
+ // Otherwise, we are running from an extracted npm tarball and we should not
311
+ // attempt to update Git submodules and should make the binary from the
312
+ // published source.
313
+ //
314
+ // These steps will avoid rebuilding native xsnap in the common case for end
315
+ // users.
316
+ //
317
+ // || | X || git
318
+ // || X | X || make
319
+ // || ---- | ---- || ----
320
+ // | bin | src | .git || pack | work ||
321
+ // | --- | --- | ---- || ---- | ---- ||
322
+ // | | | || | X ||
323
+ // | | | X || | ||
324
+ // | | X | || X | ||
325
+ // | | X | X || | X ||
326
+ // | X | | || | ||
327
+ // | X | | X || | ||
328
+ // | X | X | || X | ||
329
+ // | X | X | X || | X ||
330
+ //
331
+ // We build both release and debug, so checking for one should suffice.
332
+ // XXX This will need to account for the .exe extension if we recover support
333
+ // for Windows.
334
+ const hasBin = fs.existsSync(
335
+ asset(`../xsnap-native/xsnap/build/bin/${platform}/release/xsnap-worker`),
336
+ );
337
+ let hasSource = fs.existsSync(asset('../moddable/xs/includes/xs.h'));
338
+ const hasGit = fs.existsSync(asset('../moddable/.git'));
339
+ const isWorkingCopy = hasGit || (!hasSource && !hasBin);
340
+ const showEnv = args.includes('--show-env');
341
+
342
+ if (isWorkingCopy || showEnv) {
343
+ if (showEnv && !isWorkingCopy) {
344
+ throw new Error('XSnap requires a working copy and git to --show-env');
345
+ }
346
+ await updateSubmodules(showEnv, { env, stdout, spawn, fs });
347
+ hasSource = true;
348
+ }
349
+
350
+ if (!showEnv) {
351
+ if (hasSource) {
352
+ // Force a rebuild if for some reason the binary is out of date
353
+ // Since the make checks may not always detect that situation
354
+ let forceBuild = !hasBin;
355
+ if (hasBin) {
356
+ const npm = makeCLI('npm', { spawn });
357
+ await npm
358
+ .run(['run', '-s', 'check-version'], { cwd: asset('..') })
359
+ .catch(() => {
360
+ forceBuild = true;
361
+ });
362
+ }
363
+ await makeXsnap({ spawn, fs, os }, { forceBuild });
364
+ } else if (!hasBin) {
365
+ throw new Error(
366
+ 'XSnap has neither sources nor a pre-built binary. Docker? .dockerignore? npm files?',
367
+ );
368
+ }
369
+ }
247
370
  }
248
371
 
249
- main(process.argv.slice(2), {
250
- env: { ...process.env },
251
- stdout: process.stdout,
252
- spawn: childProcessTop.spawn,
253
- fs: {
254
- readFile: fsTop.promises.readFile,
255
- existsSync: fsTop.existsSync,
256
- rmdirSync: fsTop.rmdirSync,
372
+ const run = () =>
373
+ main(process.argv.slice(2), {
374
+ env: { ...process.env },
375
+ stdout: process.stdout,
376
+ spawn: childProcessTop.spawn,
377
+ fs: {
378
+ readFile: fsTop.promises.readFile,
379
+ writeFile: fsTop.promises.writeFile,
380
+ existsSync: fsTop.existsSync,
381
+ rmdirSync: fsTop.rmdirSync,
382
+ },
383
+ os: {
384
+ type: osTop.type,
385
+ },
386
+ });
387
+
388
+ process.exitCode = 1;
389
+ run().then(
390
+ () => {
391
+ process.exitCode = 0;
257
392
  },
258
- os: {
259
- type: osTop.type,
393
+ err => {
394
+ console.error('Failed with', err);
395
+ process.exit(process.exitCode || 1);
260
396
  },
261
- }).catch(e => {
262
- console.error(e);
263
- process.exit(1);
264
- });
397
+ );
package/src/replay.js CHANGED
@@ -227,14 +227,12 @@ export async function replayXSnap(
227
227
  const seq = parseInt(digits, 10);
228
228
  console.log(folder, seq, kind);
229
229
  if (running && !['command', 'reply'].includes(kind)) {
230
- // eslint-disable-next-line @jessie.js/no-nested-await
231
230
  await running;
232
231
  running = undefined;
233
232
  }
234
233
  const file = rd.file(step);
235
234
  switch (kind) {
236
235
  case 'isReady':
237
- // eslint-disable-next-line @jessie.js/no-nested-await
238
236
  await it.isReady();
239
237
  break;
240
238
  case 'evaluate':
@@ -254,7 +252,6 @@ export async function replayXSnap(
254
252
  console.log(folder, step, 'ignoring remaining steps from', folder);
255
253
  return;
256
254
  } else {
257
- // eslint-disable-next-line @jessie.js/no-nested-await
258
255
  await (async () => {
259
256
  const snapshotPath = file.getText();
260
257
  const snapFile = await opts.fs.open(snapshotPath, 'w');