@agoric/xsnap 0.14.3-other-dev-8f8782b.0 → 0.14.3-other-dev-3eb1a1d.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 (138) 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 +40 -23
  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 +13 -11
  122. package/src/build.js +164 -30
  123. package/src/replay.js +12 -8
  124. package/src/xsnap.js +131 -115
  125. package/src/xsrepl.js +8 -9
  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 +1024 -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 -622
  138. package/src/defer.js +0 -31
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@agoric/xsnap",
3
- "version": "0.14.3-other-dev-8f8782b.0+8f8782b",
4
- "description": "Description forthcoming.",
3
+ "version": "0.14.3-other-dev-3eb1a1d.0+3eb1a1d",
4
+ "description": "Snapshotting VM worker based on Moddable's XS Javascript engine",
5
5
  "author": "Agoric",
6
6
  "license": "Apache-2.0",
7
7
  "type": "module",
@@ -12,54 +12,71 @@
12
12
  },
13
13
  "scripts": {
14
14
  "repl": "node src/xsrepl.js",
15
- "build:bin": "if git status >/dev/null 2>&1; then node src/build.js; else yarn build:from-env; fi",
16
- "build:env": "if git status >/dev/null 2>&1; then node src/build.js --show-env > build.env; fi",
15
+ "build:bin": "if test -d ./test; then node src/build.js; else yarn build:from-env; fi",
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
- "test:c8": "c8 $C8_OPTIONS ava --config=ava-nesm.config.js",
27
+ "test:c8": "c8 --all $C8_OPTIONS ava",
27
28
  "test:xs": "exit 0"
28
29
  },
29
30
  "dependencies": {
30
- "@agoric/assert": "0.6.1-other-dev-8f8782b.0+8f8782b",
31
- "@agoric/internal": "0.3.3-other-dev-8f8782b.0+8f8782b",
32
- "@agoric/xsnap-lockdown": "0.14.1-other-dev-8f8782b.0+8f8782b",
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/internal": "0.3.3-other-dev-3eb1a1d.0+3eb1a1d",
32
+ "@agoric/xsnap-lockdown": "0.14.1-other-dev-3eb1a1d.0+3eb1a1d",
33
+ "@endo/bundle-source": "^3.5.0",
34
+ "@endo/errors": "^1.2.8",
35
+ "@endo/eventual-send": "^1.2.8",
36
+ "@endo/init": "^1.1.7",
37
+ "@endo/netstring": "^1.0.13",
38
+ "@endo/promise-kit": "^1.1.8",
39
+ "@endo/stream": "^1.2.8",
40
+ "@endo/stream-node": "^1.1.8",
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.9",
46
+ "@endo/nat": "^5.0.13",
47
+ "@types/glob": "^8.1.0",
48
+ "ava": "^5.3.0",
49
+ "c8": "^10.1.2"
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": "8f8782bc52393e9d4fc82523ecf31cab429b11b3"
78
+ "typeCoverage": {
79
+ "atLeast": 93.51
80
+ },
81
+ "gitHead": "3eb1a1d2d75b2b4a94807cd3bf759bc9fc531f05"
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,17 +2,17 @@
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';
12
+ import { fileURLToPath } from 'url';
13
13
  import { tmpName } from 'tmp';
14
14
 
15
- import { assert, q, Fail } from '@agoric/assert';
15
+ import { assert, q, Fail } from '@endo/errors';
16
16
  import { getDebugLockdownBundle } from '@agoric/xsnap-lockdown';
17
17
  import { xsnap } from './xsnap.js';
18
18
 
@@ -22,7 +22,7 @@ const avaHandler = `./avaHandler.cjs`;
22
22
 
23
23
  /** @type { (ref: string, readFile: typeof import('fs').promises.readFile ) => Promise<string> } */
24
24
  const asset = (ref, readFile) =>
25
- readFile(new URL(ref, import.meta.url).pathname, 'utf8');
25
+ readFile(fileURLToPath(new URL(ref, import.meta.url)), 'utf8');
26
26
 
27
27
  /**
28
28
  * When we bundle test scripts, we leave these externals
@@ -69,8 +69,6 @@ function isMatch(specimen, pattern) {
69
69
  *
70
70
  * It also calls back if a test calls `bundleSource`.
71
71
  *
72
- * @typedef {{ moduleFormat: string, source: string }} Bundle
73
- *
74
72
  * And finally it reports back a summary of assertion results.
75
73
  *
76
74
  * @typedef {{
@@ -84,7 +82,7 @@ function isMatch(specimen, pattern) {
84
82
  * @param {{ verbose?: boolean, titleMatch?: string }} options
85
83
  * @param {{
86
84
  * spawnXSnap: (opts: object) => XSnap,
87
- * bundleSource: (...args: [string, ...unknown[]]) => Promise<Bundle>,
85
+ * bundleSource: import('@endo/bundle-source').BundleSource,
88
86
  * resolve: ResolveFn,
89
87
  * dirname: typeof import('path').dirname,
90
88
  * basename: typeof import('path').basename,
@@ -93,7 +91,7 @@ function isMatch(specimen, pattern) {
93
91
  *
94
92
  * @typedef {{ total: number, pass: number, fail: { filename: string, name: string }[] }} TestResults
95
93
  * @typedef { 'ok' | 'not ok' | 'SKIP' } Status
96
- * @typedef {ReturnType<typeof import('./xsnap').xsnap>} XSnap
94
+ * @typedef {ReturnType<typeof import('./xsnap.js').xsnap>} XSnap
97
95
  */
98
96
  async function runTestScript(
99
97
  filename,
@@ -120,7 +118,7 @@ async function runTestScript(
120
118
  /**
121
119
  * See also send() in avaHandler.cjs
122
120
  *
123
- * @type { TapMessage | { testNames: string[] } | { bundleSource: [string, ...unknown[]] } | Summary }
121
+ * @type { TapMessage | { testNames: string[] } | { bundleSource: Parameters<import('@endo/bundle-source').BundleSource> } | Summary }
124
122
  */
125
123
  const msg = JSON.parse(decoder.decode(message));
126
124
  // console.log(input, msg, qty, byStatus);
@@ -129,6 +127,7 @@ async function runTestScript(
129
127
  testNames = msg.testNames;
130
128
  }
131
129
 
130
+ await null;
132
131
  if ('bundleSource' in msg) {
133
132
  const [startFilename, ...rest] = msg.bundleSource;
134
133
  // see also makeBundleResolve() below
@@ -244,6 +243,7 @@ async function avaConfig(args, options, { glob, readFile }) {
244
243
  let debug = false;
245
244
  let verbose = false;
246
245
  let titleMatch;
246
+ await null;
247
247
  while (args.length > 0) {
248
248
  const arg = args.shift();
249
249
  assert.typeof(arg, 'string');
@@ -301,7 +301,7 @@ async function avaConfig(args, options, { glob, readFile }) {
301
301
  /**
302
302
  * @param {string[]} args - CLI args (excluding node interpreter, script name)
303
303
  * @param {{
304
- * bundleSource: typeof import('@endo/bundle-source').default,
304
+ * bundleSource: import('@endo/bundle-source').BundleSource,
305
305
  * spawn: typeof import('child_process')['spawn'],
306
306
  * osType: typeof import('os')['type'],
307
307
  * readFile: typeof import('fs')['promises']['readFile'],
@@ -385,7 +385,9 @@ export async function main(
385
385
 
386
386
  stats.total += results.total;
387
387
  stats.pass += results.pass;
388
- results.fail.forEach(info => stats.fail.push(info));
388
+ for (const info of results.fail) {
389
+ stats.fail.push(info);
390
+ }
389
391
  }
390
392
 
391
393
  console.log(stats.pass, 'tests passed');
package/src/build.js CHANGED
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env node
2
- /* global process */
3
- /* eslint-disable @jessie.js/no-nested-await -- test/build code */
2
+ /* eslint-env node */
4
3
  import * as childProcessTop from 'child_process';
4
+ import { fileURLToPath } from 'url';
5
5
  import fsTop from 'fs';
6
6
  import osTop from 'os';
7
7
 
8
8
  const { freeze } = Object;
9
9
 
10
10
  /** @param {string} path */
11
- const asset = path => new URL(path, import.meta.url).pathname;
11
+ const asset = path => fileURLToPath(new URL(path, import.meta.url));
12
12
 
13
13
  const ModdableSDK = {
14
14
  MODDABLE: asset('../moddable'),
@@ -140,7 +140,7 @@ const makeSubmodule = (path, repoUrl, { git }) => {
140
140
  };
141
141
 
142
142
  /**
143
- * @param {string[]} args
143
+ * @param {boolean} showEnv
144
144
  * @param {{
145
145
  * env: Record<string, string | undefined>,
146
146
  * stdout: typeof process.stdout,
@@ -150,12 +150,9 @@ const makeSubmodule = (path, repoUrl, { git }) => {
150
150
  * rmdirSync: typeof import('fs').rmdirSync,
151
151
  * readFile: typeof import('fs').promises.readFile,
152
152
  * },
153
- * os: {
154
- * type: typeof import('os').type,
155
- * }
156
153
  * }} io
157
154
  */
158
- async function main(args, { env, stdout, spawn, fs, os }) {
155
+ const updateSubmodules = async (showEnv, { env, stdout, spawn, fs }) => {
159
156
  const git = makeCLI('git', { spawn });
160
157
 
161
158
  // When changing/adding entries here, make sure to search the whole project
@@ -176,13 +173,13 @@ async function main(args, { env, stdout, spawn, fs, os }) {
176
173
  },
177
174
  ];
178
175
 
179
- if (args.includes('--show-env')) {
176
+ await null;
177
+ if (showEnv) {
180
178
  for (const submodule of submodules) {
181
179
  const { path, envPrefix, commitHash } = submodule;
182
180
  if (!commitHash) {
183
181
  // We need to glean the commitHash and url from Git.
184
182
  const sm = makeSubmodule(path, '?', { git });
185
- // eslint-disable-next-line no-await-in-loop
186
183
  const [[{ hash }], url] = await Promise.all([
187
184
  sm.status(),
188
185
  sm.config('url'),
@@ -208,20 +205,50 @@ async function main(args, { env, stdout, spawn, fs, os }) {
208
205
  // ignore
209
206
  }
210
207
  if (!fs.existsSync(submodule.path)) {
211
- // eslint-disable-next-line no-await-in-loop
212
208
  await submodule.clone();
213
209
  }
214
- // eslint-disable-next-line no-await-in-loop
215
210
  await submodule.checkout(commitHash);
216
211
  } else {
217
- // eslint-disable-next-line no-await-in-loop
218
212
  await submodule.init();
219
213
  }
220
214
  }
215
+ };
221
216
 
217
+ /**
218
+ * @param {{
219
+ * spawn: typeof import('child_process').spawn,
220
+ * fs: {
221
+ * existsSync: typeof import('fs').existsSync,
222
+ * rmdirSync: typeof import('fs').rmdirSync,
223
+ * readFile: typeof import('fs').promises.readFile,
224
+ * writeFile: typeof import('fs').promises.writeFile,
225
+ * },
226
+ * os: {
227
+ * type: typeof import('os').type,
228
+ * }
229
+ * }} io
230
+ * @param {object} [options]
231
+ * @param {boolean} [options.forceBuild]
232
+ */
233
+ const makeXsnap = async ({ spawn, fs, os }, { forceBuild = false } = {}) => {
222
234
  const pjson = await fs.readFile(asset('../package.json'), 'utf-8');
223
235
  const pkg = JSON.parse(pjson);
224
236
 
237
+ const configEnvs = [
238
+ `XSNAP_VERSION=${pkg.version}`,
239
+ `CC=cc "-D__has_builtin(x)=1"`,
240
+ ];
241
+
242
+ const configEnvFile = asset('../build.config.env');
243
+ const existingConfigEnvs = fs.existsSync(configEnvFile)
244
+ ? await fs.readFile(configEnvFile, 'utf-8')
245
+ : '';
246
+
247
+ const expectedConfigEnvs = configEnvs.concat('').join('\n');
248
+ if (forceBuild || existingConfigEnvs.trim() !== expectedConfigEnvs.trim()) {
249
+ await fs.writeFile(configEnvFile, expectedConfigEnvs);
250
+ }
251
+
225
252
  const platform = ModdableSDK.platforms[os.type()];
226
253
  if (!platform) {
227
254
  throw Error(`Unsupported OS found: ${os.type()}`);
@@ -229,13 +256,14 @@ async function main(args, { env, stdout, spawn, fs, os }) {
229
256
 
230
257
  const make = makeCLI(platform.make || 'make', { spawn });
231
258
  for (const goal of ModdableSDK.buildGoals) {
232
- // eslint-disable-next-line no-await-in-loop
233
259
  await make.run(
234
260
  [
235
261
  `MODDABLE=${ModdableSDK.MODDABLE}`,
236
262
  `GOAL=${goal}`,
237
- `XSNAP_VERSION=${pkg.version}`,
238
- `CC=cc "-D__has_builtin(x)=1"`,
263
+ // Any other configuration variables that affect the build output
264
+ // should be placed in `configEnvs` to force a rebuild if they change
265
+ ...configEnvs,
266
+ `EXTRA_DEPS=${configEnvFile}`,
239
267
  '-f',
240
268
  'xsnap-worker.mk',
241
269
  ],
@@ -244,21 +272,127 @@ async function main(args, { env, stdout, spawn, fs, os }) {
244
272
  },
245
273
  );
246
274
  }
275
+ };
276
+
277
+ /**
278
+ * @param {string[]} args
279
+ * @param {{
280
+ * env: Record<string, string | undefined>,
281
+ * stdout: typeof process.stdout,
282
+ * spawn: typeof import('child_process').spawn,
283
+ * fs: {
284
+ * existsSync: typeof import('fs').existsSync,
285
+ * rmdirSync: typeof import('fs').rmdirSync,
286
+ * readFile: typeof import('fs').promises.readFile,
287
+ * writeFile: typeof import('fs').promises.writeFile,
288
+ * },
289
+ * os: {
290
+ * type: typeof import('os').type,
291
+ * }
292
+ * }} io
293
+ */
294
+ async function main(args, { env, stdout, spawn, fs, os }) {
295
+ // I solemnly swear I will do no synchronous work followed by a variable
296
+ // number turns of the event loop.
297
+ await null;
298
+
299
+ const osType = os.type();
300
+ const platform = {
301
+ Linux: 'lin',
302
+ Darwin: 'mac',
303
+ // Windows_NT: 'win', // One can dream.
304
+ }[osType];
305
+ if (platform === undefined) {
306
+ throw Error(`xsnap does not support platform ${osType}`);
307
+ }
308
+
309
+ // If this is a working copy of xsnap in a checkout of agoric-sdk, we need to
310
+ // either clone or update submodules.
311
+ // Otherwise, we are running from an extracted npm tarball and we should not
312
+ // attempt to update Git submodules and should make the binary from the
313
+ // published source.
314
+ //
315
+ // These steps will avoid rebuilding native xsnap in the common case for end
316
+ // users.
317
+ //
318
+ // || | X || git
319
+ // || X | X || make
320
+ // || ---- | ---- || ----
321
+ // | bin | src | .git || pack | work ||
322
+ // | --- | --- | ---- || ---- | ---- ||
323
+ // | | | || | X ||
324
+ // | | | X || | ||
325
+ // | | X | || X | ||
326
+ // | | X | X || | X ||
327
+ // | X | | || | ||
328
+ // | X | | X || | ||
329
+ // | X | X | || X | ||
330
+ // | X | X | X || | X ||
331
+ //
332
+ // We build both release and debug, so checking for one should suffice.
333
+ // XXX This will need to account for the .exe extension if we recover support
334
+ // for Windows.
335
+ const hasBin = fs.existsSync(
336
+ asset(`../xsnap-native/xsnap/build/bin/${platform}/release/xsnap-worker`),
337
+ );
338
+ let hasSource = fs.existsSync(asset('../moddable/xs/includes/xs.h'));
339
+ const hasGit = fs.existsSync(asset('../moddable/.git'));
340
+ const isWorkingCopy = hasGit || (!hasSource && !hasBin);
341
+ const showEnv = args.includes('--show-env');
342
+
343
+ if (isWorkingCopy || showEnv) {
344
+ if (showEnv && !isWorkingCopy) {
345
+ throw Error('XSnap requires a working copy and git to --show-env');
346
+ }
347
+ await updateSubmodules(showEnv, { env, stdout, spawn, fs });
348
+ hasSource = true;
349
+ }
350
+
351
+ if (!showEnv) {
352
+ if (hasSource) {
353
+ // Force a rebuild if for some reason the binary is out of date
354
+ // Since the make checks may not always detect that situation
355
+ let forceBuild = !hasBin;
356
+ if (hasBin) {
357
+ const npm = makeCLI('npm', { spawn });
358
+ await npm
359
+ .run(['run', '-s', 'check-version'], { cwd: asset('..') })
360
+ .catch(() => {
361
+ forceBuild = true;
362
+ });
363
+ }
364
+ await makeXsnap({ spawn, fs, os }, { forceBuild });
365
+ } else if (!hasBin) {
366
+ throw Error(
367
+ 'XSnap has neither sources nor a pre-built binary. Docker? .dockerignore? npm files?',
368
+ );
369
+ }
370
+ }
247
371
  }
248
372
 
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,
373
+ const run = () =>
374
+ main(process.argv.slice(2), {
375
+ env: { ...process.env },
376
+ stdout: process.stdout,
377
+ spawn: childProcessTop.spawn,
378
+ fs: {
379
+ readFile: fsTop.promises.readFile,
380
+ writeFile: fsTop.promises.writeFile,
381
+ existsSync: fsTop.existsSync,
382
+ rmdirSync: fsTop.rmdirSync,
383
+ },
384
+ os: {
385
+ type: osTop.type,
386
+ },
387
+ });
388
+
389
+ process.exitCode = 1;
390
+ run().then(
391
+ () => {
392
+ process.exitCode = 0;
257
393
  },
258
- os: {
259
- type: osTop.type,
394
+ err => {
395
+ console.error('Failed with', err);
396
+ process.exit(process.exitCode || 1);
260
397
  },
261
- }).catch(e => {
262
- console.error(e);
263
- process.exit(1);
264
- });
398
+ );
package/src/replay.js CHANGED
@@ -13,6 +13,7 @@ import osPowers from 'os';
13
13
  import fsPowers from 'fs';
14
14
  import { Readable } from 'stream';
15
15
  import { tmpName as tmpNamePower } from 'tmp';
16
+ import { fileURLToPath } from 'url';
16
17
  import { makeQueue } from '@endo/stream';
17
18
  import { xsnap, DEFAULT_CRANK_METERING_LIMIT } from './xsnap.js';
18
19
 
@@ -38,7 +39,9 @@ function makeSyncStorage(path, { writeFileSync }) {
38
39
  file: fn => {
39
40
  /** @param {Uint8Array} data */
40
41
  const put = data =>
41
- writeFileSync(new URL(fn, base).pathname, data, { flag: 'wx' });
42
+ writeFileSync(fileURLToPath(new URL(fn, base)), data, {
43
+ flag: 'wx',
44
+ });
42
45
 
43
46
  return freeze({
44
47
  put,
@@ -60,14 +63,18 @@ function makeSyncAccess(path, { readdirSync, readFileSync }) {
60
63
  const base = new URL(path, 'file://');
61
64
  /** @param {string} fn */
62
65
  const file = fn => {
63
- const fullname = new URL(fn, base).pathname;
66
+ const fullname = fileURLToPath(new URL(fn, base));
64
67
 
65
68
  return freeze({
66
69
  getData: () => readFileSync(fullname),
67
70
  getText: () => readFileSync(fullname, 'utf-8'),
68
71
  });
69
72
  };
70
- return freeze({ path, file, readdir: () => readdirSync(base.pathname) });
73
+ return freeze({
74
+ path,
75
+ file,
76
+ readdir: () => readdirSync(fileURLToPath(base)),
77
+ });
71
78
  }
72
79
 
73
80
  /**
@@ -227,14 +234,12 @@ export async function replayXSnap(
227
234
  const seq = parseInt(digits, 10);
228
235
  console.log(folder, seq, kind);
229
236
  if (running && !['command', 'reply'].includes(kind)) {
230
- // eslint-disable-next-line @jessie.js/no-nested-await
231
237
  await running;
232
238
  running = undefined;
233
239
  }
234
240
  const file = rd.file(step);
235
241
  switch (kind) {
236
242
  case 'isReady':
237
- // eslint-disable-next-line @jessie.js/no-nested-await
238
243
  await it.isReady();
239
244
  break;
240
245
  case 'evaluate':
@@ -254,7 +259,6 @@ export async function replayXSnap(
254
259
  console.log(folder, step, 'ignoring remaining steps from', folder);
255
260
  return;
256
261
  } else {
257
- // eslint-disable-next-line @jessie.js/no-nested-await
258
262
  await (async () => {
259
263
  const snapshotPath = file.getText();
260
264
  const snapFile = await opts.fs.open(snapshotPath, 'w');
@@ -322,8 +326,8 @@ export async function main(
322
326
  await replayXSnap(options, folders, { readdirSync, readFileSync });
323
327
  }
324
328
 
325
- /* global process */
326
- if (process.argv[1] === new URL(import.meta.url).pathname) {
329
+ /* eslint-env node */
330
+ if (process.argv[1] === fileURLToPath(new URL(import.meta.url))) {
327
331
  main([...process.argv.slice(2)], {
328
332
  spawn: childProcessPowers.spawn,
329
333
  fs: { ...fsPowers, ...fsPowers.promises },