peachsim 0.1.2224 → 0.1.2228

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 (171) hide show
  1. package/cli/bridge-flow-runner.ts +56 -3
  2. package/cli/commands/control.ts +27 -1
  3. package/cli/commands/flow.ts +26 -0
  4. package/cli/commands/package.ts +9 -2
  5. package/cli/drivers/playwright.ts +1 -0
  6. package/cli/drivers/types.ts +3 -0
  7. package/cli/internal-child.ts +4 -2
  8. package/dist-lib/agent-daemon-client.cjs +1 -1
  9. package/dist-lib/agent-events.cjs +1 -1
  10. package/dist-lib/attached-projects.cjs +1 -1
  11. package/dist-lib/auth/shared-session.cjs +1 -1
  12. package/dist-lib/backend-origin.cjs +1 -1
  13. package/dist-lib/beta.cjs +1 -1
  14. package/dist-lib/beta.mjs +1 -1
  15. package/dist-lib/bridge-constants.cjs +1 -1
  16. package/dist-lib/bridge-contract-input.cjs +1 -1
  17. package/dist-lib/bridge-contract-input.mjs +1 -1
  18. package/dist-lib/bridge-contract.cjs +1 -1
  19. package/dist-lib/bridge-contract.mjs +1 -1
  20. package/dist-lib/bundle-channel.cjs +931 -455
  21. package/dist-lib/capture-contract.cjs +1 -1
  22. package/dist-lib/capture-contract.mjs +1 -1
  23. package/dist-lib/cloud-contract.cjs +1 -1
  24. package/dist-lib/cloud-contract.mjs +1 -1
  25. package/dist-lib/cloud-test-args.cjs +1 -1
  26. package/dist-lib/cloud-test-args.mjs +1 -1
  27. package/dist-lib/cloud.cjs +1 -1
  28. package/dist-lib/cloud.mjs +1 -1
  29. package/dist-lib/config.cjs +1 -1
  30. package/dist-lib/config.mjs +1 -1
  31. package/dist-lib/detox/index.cjs +2 -2
  32. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  33. package/dist-lib/expo-swift-bundle.cjs +867 -391
  34. package/dist-lib/expo-swift-metadata.cjs +1 -1
  35. package/dist-lib/expo-swift-metadata.mjs +1 -1
  36. package/dist-lib/home-paths.cjs +1 -1
  37. package/dist-lib/host/bridge-host.cjs +926 -450
  38. package/dist-lib/host/fetch-proxy-handler.cjs +55 -12
  39. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  40. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  41. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  42. package/dist-lib/host/websocket-proxy.cjs +1 -1
  43. package/dist-lib/index.cjs +60 -16
  44. package/dist-lib/jump-to-source-babel.cjs +1 -1
  45. package/dist-lib/jump-to-source-native.cjs +1 -1
  46. package/dist-lib/kotlin-host.cjs +1 -1
  47. package/dist-lib/menu.cjs +1 -1
  48. package/dist-lib/menu.mjs +1 -1
  49. package/dist-lib/metro-fingerprint-registry.cjs +1 -1
  50. package/dist-lib/metro-fingerprint-registry.mjs +1 -1
  51. package/dist-lib/metro-production-bundle.cjs +11 -4
  52. package/dist-lib/metro-production-bundle.mjs +10 -4
  53. package/dist-lib/metro.cjs +60 -16
  54. package/dist-lib/native-app-identity-project.cjs +53 -9
  55. package/dist-lib/native-app-identity-project.mjs +84 -37
  56. package/dist-lib/native-app-identity.cjs +1 -1
  57. package/dist-lib/native-app-identity.mjs +1 -1
  58. package/dist-lib/native-firebase-metadata.cjs +1 -1
  59. package/dist-lib/native-firebase-metadata.mjs +1 -1
  60. package/dist-lib/pdfium-raster.cjs +1 -1
  61. package/dist-lib/pdfium-raster.mjs +1 -1
  62. package/dist-lib/plist.cjs +1 -1
  63. package/dist-lib/plist.mjs +1 -1
  64. package/dist-lib/profiles.cjs +1 -1
  65. package/dist-lib/public-brand.cjs +1 -1
  66. package/dist-lib/public-origins-lib-esm.json +26 -24
  67. package/dist-lib/public-origins-lib.json +66 -54
  68. package/dist-lib/react-native-host-modules.cjs +1 -1
  69. package/dist-lib/react-native-host-modules.mjs +1 -1
  70. package/dist-lib/reap-browser.cjs +1 -1
  71. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  72. package/dist-lib/sdk.cjs +1 -1
  73. package/dist-lib/sdk.mjs +1 -1
  74. package/dist-lib/skills.cjs +1049 -512
  75. package/dist-lib/swift-compile.cjs +557 -121
  76. package/dist-lib/swift-compile.mjs +693 -258
  77. package/dist-lib/swift-package.cjs +1 -1
  78. package/dist-lib/swift-package.mjs +1 -1
  79. package/dist-lib/swift-submit.cjs +1 -1
  80. package/dist-lib/swift-submit.mjs +1 -1
  81. package/dist-lib/swift-toolchain.cjs +38 -2
  82. package/dist-lib/swift.cjs +1 -1
  83. package/dist-lib/vite-swift.cjs +1726 -1209
  84. package/dist-lib/vite.cjs +55 -12
  85. package/dist-lib/worklet-executable.cjs +1 -1
  86. package/dist-lib/worklet-executable.mjs +1 -1
  87. package/dist-types/packages/peach-engine/src/bundle-parse-receipt.d.ts +17 -0
  88. package/dist-types/packages/peach-engine/src/engine/canvaskit-api.d.ts +2 -1
  89. package/dist-types/packages/peach-engine/src/engine/font-config.d.ts +2 -2
  90. package/dist-types/packages/peach-engine/src/engine/native-layout.d.ts +1 -0
  91. package/dist-types/packages/peach-engine/src/engine/native-paragraph.d.ts +4 -0
  92. package/dist-types/packages/peach-engine/src/engine/node.d.ts +2 -0
  93. package/dist-types/packages/peach-engine/src/engine/scene-table.d.ts +1 -1
  94. package/dist-types/packages/peach-engine/src/engine/types.d.ts +7 -0
  95. package/dist-types/packages/peach-engine/src/engine/yoga-layout.d.ts +2 -0
  96. package/dist-types/packages/peach-engine/src/metro-fingerprint.d.ts +3 -2
  97. package/dist-types/packages/peach-engine/src/preview/preview-room-contract.d.ts +6 -0
  98. package/dist-types/packages/peach-engine/src/render-worker/compositor-protocol.d.ts +1 -0
  99. package/dist-types/packages/peach-engine/src/render-worker/protocol.d.ts +15 -3
  100. package/dist-types/packages/peach-engine/src/rolldown-bundle-inventory.d.ts +0 -5
  101. package/dist-types/packages/peach-kit/src/capabilities.d.ts +2 -0
  102. package/dist-types/packages/peach-kit/src/internal.d.ts +1 -1
  103. package/dist-types/packages/peach-kit/src/ios-tint.d.ts +2 -0
  104. package/kotlin/sdk.tar.gz +0 -0
  105. package/package.json +1 -1
  106. package/runtime-companion.json +1 -1
  107. package/sdk/ios/System/Library/Frameworks/CoreFoundation.framework/Headers/CFCGTypes.h +0 -6
  108. package/sdk/ios/System/Library/Frameworks/Foundation.framework/Headers/NSCharacterSet.h +1 -1
  109. package/sdk/ios/System/Library/Frameworks/Foundation.framework/Headers/NSURL.h +1 -1
  110. package/sdk/ios/System/Library/Frameworks/UIKit.framework/Headers/UIControl.h +0 -26
  111. package/sdk/ios/System/Library/Frameworks/UIKitTypes.framework/Headers/UIKitTypes.h +27 -0
  112. package/sdk/ios/usr/include/AvailabilityInternal.h +2 -2
  113. package/sdk/ios/usr/include/ObjectiveC.apinotes +380 -7
  114. package/sdk/ios/usr/include/peach/pthread.h +1 -7
  115. package/sdk/ios/wasm/include/TargetConditionals.h +2 -3
  116. package/sdk/ios/wasm/include/__struct_timeval.h +15 -0
  117. package/sdk/ios/wasm/include/__typedef_suseconds_t.h +9 -0
  118. package/sdk/ios/wasm/include/limits.h +1 -1
  119. package/sdk/ios/wasm/include/machine/_types.h +1 -1
  120. package/sdk/ios/wasm/include/machine/limits.h +1 -1
  121. package/sdk/ios/wasm/include/machine/param.h +2 -2
  122. package/sdk/ios/wasm/include/math.h +13 -0
  123. package/sdk/ios/wasm/include/pthread.h +1 -13
  124. package/sdk/ios/wasm/include/sys/resource.h +3 -0
  125. package/sdk/ios/wasm/include/sys/socket.h +0 -10
  126. package/sdk/ios/wasm/include/sys/stat.h +5 -2
  127. package/sdk/ios/wasm/include/sys/time.h +16 -3
  128. package/sdk/ios/wasm/include/sys/types.h +4 -1
  129. package/sdk/ios/wasm/include/time.h +2 -0
  130. package/sdk/ios/wasm/storage-include/TargetConditionals.h +2 -3
  131. package/sdk/native-hashes.json +14 -14
  132. package/src/metro-production-bundle.ts +15 -2
  133. package/src/native-slices.ts +3 -2
  134. package/src/native-static-libraries.ts +23 -23
  135. package/src/native-swift-slices.ts +2 -2
  136. package/src/nitro-adapter.lock.json +288 -288
  137. package/src/nitro-compiler-digest.ts +0 -1
  138. package/src/nitro-dependencies.ts +8 -9
  139. package/src/nitro-superset.lock.json +4 -4
  140. package/src/react-native-core-build.ts +2 -2
  141. package/src/swift-compile.ts +209 -47
  142. package/src/swift-compiler-digest.ts +2 -0
  143. package/src/swift-cxx-standin.ts +1 -1
  144. package/src/swift-darwin-records.ts +4 -4
  145. package/src/swift-distribution-contract.ts +2 -2
  146. package/src/swift-distribution.lock.json +13 -12
  147. package/src/swift-guest-compile.ts +6 -5
  148. package/src/swift-guest-image-ledger.ts +5 -5
  149. package/src/swift-guest-link.ts +1 -1
  150. package/src/swift-guest-linked-spans.ts +7 -4
  151. package/src/swift-guest-manifest.ts +2 -2
  152. package/src/swift-guest-source-inputs.ts +16 -5
  153. package/src/swift-host.ts +10 -5
  154. package/src/swift-icu.ts +1 -1
  155. package/src/swift-objc-compile.ts +9 -4
  156. package/src/swift-objc-standin.ts +1 -4
  157. package/src/swift-package-manifest.ts +5 -1
  158. package/src/swift-packages.ts +2 -2
  159. package/src/swift-shared-sdk.ts +1 -1
  160. package/src/swift-standin-emit.ts +3 -16
  161. package/src/swift-standins.ts +119 -87
  162. package/src/swift-toolchain.ts +37 -1
  163. package/src/swift-uniform-type-constants.ts +1 -1
  164. package/src/swift-wasm-prune.ts +17 -12
  165. package/src/swiftGuestImageContract.ts +4 -4
  166. package/src/swiftNativePinContract.ts +1 -1
  167. package/src/swiftRuntimeProductContract.ts +1 -1
  168. package/src/turbo-runtime.lock.json +28 -28
  169. package/src/wasm-narrow-boundary.ts +296 -0
  170. package/src/wasm-optimize.ts +59 -14
  171. package/src/xcode-project.ts +6 -4
@@ -50,6 +50,42 @@ export interface SwiftHostCompilerPin {
50
50
  // advance. an installed CLI adds the compiler its runtime pins
51
51
  // (registerSwiftHostCompiler).
52
52
  const compilerArchives: Record<string, SwiftHostCompilerPin> = {
53
+ 'swift-6.4.0-RELEASE-custom-fb42d2535739dfd2': {
54
+ identity: 'fb42d2535739dfd2',
55
+ archive: 'tar.zst',
56
+ hosts: {
57
+ 'darwin-arm64': {
58
+ checksum: '5e417d415ca74a435755e298a1d2d19ec47637fd03479de7a7d958eb382941f1',
59
+ manifest: 'eb5a0356aebabe89c7b2780f8809e13d6e2ad6f342fed87cf99f9a5834344363',
60
+ },
61
+ 'linux-arm64': {
62
+ checksum: '8ac7ad97f3d68bf485423001d1ce3cd92a8d4625313c47c8071867a9aeed3af9',
63
+ manifest: '6126266dd65b43c43d719e4dc4d33c4ea6a3267f99f34e3638637439a995af2e',
64
+ },
65
+ 'linux-x64': {
66
+ checksum: '7d76463079619ba822123d250601bd35f6744ed5f8054a657ce472ce4dac76c8',
67
+ manifest: 'f1a6c0c61d15eddb2ecfa4c3a72a5154621881ac2f0c413162ff1d0f4343bd0e',
68
+ },
69
+ },
70
+ },
71
+ 'swift-6.4.0-RELEASE-custom-44ecd25f163bb359': {
72
+ identity: '44ecd25f163bb359',
73
+ archive: 'tar.zst',
74
+ hosts: {
75
+ 'darwin-arm64': {
76
+ checksum: 'd06dda4435f99d8376179cc7a3804907aa7305513135ece6288fd8e6d4695ae6',
77
+ manifest: 'bc0d8b955f923f096dda2aa8bbb1d56176a73f3d4a4df4cc9a1f59d31417061a',
78
+ },
79
+ 'linux-x64': {
80
+ checksum: 'f95b56440693c5de7995f10ea14c57fc7e659a161018a17f17a74b61a98e88a4',
81
+ manifest: 'c18a60b14d5c89a8b2e1dbb2b4b52342c5fb92c7f3069fdc55c985bce61683a7',
82
+ },
83
+ 'linux-arm64': {
84
+ checksum: 'afb74ae60df2b5bd7792bfbcf29bcea03675a5c814b758dd6cb91a760c220cd2',
85
+ manifest: 'ac037f6b0fdc4a6ae582eebc22bcf811fa2becdc30d083057137fc857f3c456a',
86
+ },
87
+ },
88
+ },
53
89
  'swift-6.4.0-RELEASE-custom-11345d60dca47496': {
54
90
  identity: '11345d60dca47496',
55
91
  archive: 'tar.zst',
@@ -827,7 +863,7 @@ function validateSwiftSdkIdentity(sdk: SwiftWasmSdk): void {
827
863
  function swiftSdkBundle(swift: string, id: string, options: string[]): string {
828
864
  const configuration = execFileSync(
829
865
  swift,
830
- ['sdk', 'configure', ...options, '--show-configuration', id, 'wasm32-unknown-wasip1'],
866
+ ['sdk', 'configure', ...options, '--show-configuration', id, 'wasm64-unknown-wasip1'],
831
867
  { encoding: 'utf8', env: swiftEnvironment(), stdio: ['ignore', 'pipe', 'pipe'] },
832
868
  )
833
869
  const sysroot = /^sdkRootPath: (.+)$/m.exec(configuration)?.[1]?.trim()
@@ -17,7 +17,7 @@ export function compileUniformTypeConstants(args: {
17
17
  execFileSync(
18
18
  path.join(args.bin, 'clang'),
19
19
  [
20
- '--target=wasm32-unknown-wasip1',
20
+ '--target=wasm64-unknown-wasip1',
21
21
  `--sysroot=${args.sysroot}`,
22
22
  '-Oz',
23
23
  '-g0',
@@ -67,7 +67,10 @@ function encodeULEB(val: number): number[] {
67
67
  return out
68
68
  }
69
69
 
70
- const HAS_ADDEND = new Set([3, 4, 5, 8, 9, 11, 13, 14, 15, 16, 21, 22, 23, 24, 25])
70
+ // llvm's relocTypeHasAddend: memory addresses, function and section offsets.
71
+ const HAS_ADDEND = new Set([3, 4, 5, 8, 9, 11, 14, 15, 16, 17, 21, 22, 23, 25])
72
+ // the 64-bit address, table index and function offset relocations patch eight bytes.
73
+ const WIDE_DATA_RELOCS = new Set([16, 19, 22])
71
74
 
72
75
  const ROOT_SEG_PREFIXES = [
73
76
  '.init_array',
@@ -1254,7 +1257,7 @@ export function pruneSwiftWasmLink(
1254
1257
  } else if (
1255
1258
  !inStartLib &&
1256
1259
  t.endsWith('.a') &&
1257
- !t.endsWith('libclang_rt.builtins-wasm32.a') &&
1260
+ !t.endsWith('libclang_rt.builtins-wasm64.a') &&
1258
1261
  fs.existsSync(t)
1259
1262
  ) {
1260
1263
  const members = readArMembers(new Uint8Array(fs.readFileSync(t)))
@@ -1841,7 +1844,12 @@ export function pruneSwiftWasmLink(
1841
1844
  }
1842
1845
 
1843
1846
  const keptDataRelocBytes: Uint8Array[] = []
1844
- const zeroDataRelocOffsets: number[] = []
1847
+ const zeroDataRelocs: { ro: number; width: number }[] = []
1848
+ const zeroDataReloc = (r: { ro: number; rawBytes: Uint8Array }) =>
1849
+ zeroDataRelocs.push({
1850
+ ro: r.ro,
1851
+ width: WIDE_DATA_RELOCS.has(r.rawBytes[0]!) ? 8 : 4,
1852
+ })
1845
1853
  const usedSyms = new Set<number>()
1846
1854
  // a type index relocation carries a type index, not a symbol index
1847
1855
  for (const r of keptCodeRelocs) if (r.rawBytes[0] !== 6) usedSyms.add(r.rs)
@@ -1854,7 +1862,7 @@ export function pruneSwiftWasmLink(
1854
1862
  keptDataRelocBytes.push(r.rawBytes)
1855
1863
  usedSyms.add(r.rs)
1856
1864
  } else if (sName === '__objc_classes') {
1857
- zeroDataRelocOffsets.push(r.ro)
1865
+ zeroDataReloc(r)
1858
1866
  } else {
1859
1867
  const repl = firstLiveInSpecialSeg.get(r.segIdx)!
1860
1868
  const roBytes = encodeULEB(r.ro)
@@ -1867,13 +1875,13 @@ export function pruneSwiftWasmLink(
1867
1875
  } else if (r.ownerSymIdx !== -1) {
1868
1876
  if (dLive.has(r.ownerSymIdx)) {
1869
1877
  if (obj.isDist && dropsReflection(obj, obj.symNames[r.rs])) {
1870
- zeroDataRelocOffsets.push(r.ro)
1878
+ zeroDataReloc(r)
1871
1879
  } else {
1872
1880
  keptDataRelocBytes.push(r.rawBytes)
1873
1881
  usedSyms.add(r.rs)
1874
1882
  }
1875
1883
  } else if (sName === '__objc_class_refs') {
1876
- zeroDataRelocOffsets.push(r.ro)
1884
+ zeroDataReloc(r)
1877
1885
  }
1878
1886
  } else if (sLive[r.segIdx] === 1) {
1879
1887
  if (
@@ -1881,7 +1889,7 @@ export function pruneSwiftWasmLink(
1881
1889
  obj.symNames[r.rs]?.startsWith('l__swift5_reflection_descriptor') &&
1882
1890
  dropsReflection(obj, obj.symNames[r.rs])
1883
1891
  ) {
1884
- zeroDataRelocOffsets.push(r.ro)
1892
+ zeroDataReloc(r)
1885
1893
  } else {
1886
1894
  keptDataRelocBytes.push(r.rawBytes)
1887
1895
  usedSyms.add(r.rs)
@@ -2096,11 +2104,8 @@ export function pruneSwiftWasmLink(
2096
2104
  outChunks.push(buf.subarray(secStart, end))
2097
2105
  }
2098
2106
  } else {
2099
- if (id === 11 && zeroDataRelocOffsets.length > 0) {
2100
- for (const ro of zeroDataRelocOffsets) {
2101
- buf.fill(0, p + ro, p + ro + 4)
2102
- }
2103
- }
2107
+ if (id === 11)
2108
+ for (const { ro, width } of zeroDataRelocs) buf.fill(0, p + ro, p + ro + width)
2104
2109
  outChunks.push(buf.subarray(secStart, end))
2105
2110
  }
2106
2111
  pos = end
@@ -24,8 +24,8 @@ export interface SwiftGuestImageManifest {
24
24
  installName: string
25
25
  fileType: 'executable' | 'dylib'
26
26
  target: {
27
- triple: 'wasm32-unknown-wasip1'
28
- pointerWidth: 32
27
+ triple: 'wasm64-unknown-wasip1'
28
+ pointerWidth: 64
29
29
  byteOrder: 'little'
30
30
  cpuType: -1
31
31
  cpuSubtype: 0
@@ -66,8 +66,8 @@ export function isSwiftGuestImageManifest(
66
66
  !text(value.installName) ||
67
67
  (value.fileType !== 'executable' && value.fileType !== 'dylib') ||
68
68
  !isRecord(value.target) ||
69
- value.target.triple !== 'wasm32-unknown-wasip1' ||
70
- value.target.pointerWidth !== 32 ||
69
+ value.target.triple !== 'wasm64-unknown-wasip1' ||
70
+ value.target.pointerWidth !== 64 ||
71
71
  value.target.byteOrder !== 'little' ||
72
72
  value.target.cpuType !== -1 ||
73
73
  value.target.cpuSubtype !== 0 ||
@@ -16,7 +16,7 @@ import {
16
16
  import type { SwiftHostCompilerPin } from './swift-toolchain'
17
17
 
18
18
  export const SWIFT_NATIVE_PIN_PATH = 'node/swift-native.json'
19
- export const SWIFT_NATIVE_PIN_SCHEMA = 2
19
+ export const SWIFT_NATIVE_PIN_SCHEMA = 3
20
20
 
21
21
  export interface SwiftNativePin {
22
22
  schema: typeof SWIFT_NATIVE_PIN_SCHEMA
@@ -46,7 +46,7 @@ export const swiftSdkProductSchema = v.pipe(
46
46
  v.object({
47
47
  id: v.string(),
48
48
  installName: v.string(),
49
- target: v.literal('wasm32-unknown-wasip1'),
49
+ target: v.literal('wasm64-unknown-wasip1'),
50
50
  linkNames: v.array(v.string()),
51
51
  // absent records declare no framework namespace, even when a library name matches.
52
52
  frameworkAliases: v.optional(
@@ -1,90 +1,90 @@
1
1
  {
2
2
  "schema": 2,
3
3
  "platform": "ios",
4
- "target": "wasm32-unknown-wasip1",
5
- "recipe": "704fe0a2e79278bce00a7af1b1dc1846943873c3f54942a174833a515d222b79",
4
+ "target": "wasm64-unknown-wasip1",
5
+ "recipe": "34baf639742120cf206d06dd95e4da3444d9f9f377b8db6eafe78417840d79d7",
6
6
  "adapter": {
7
- "sha256": "0d31912293226deb3354b3b32f2944e9c61c68590e3020d8b5af0c12a6677893"
7
+ "sha256": "2ba7674c823a6adf902af9ccdd489cfe47d68e9788a7214fe8b83c784fc3fa98"
8
8
  },
9
- "compiler": "swift-6.4.0-RELEASE-custom-11345d60dca47496",
9
+ "compiler": "swift-6.4.0-RELEASE-custom-fb42d2535739dfd2",
10
10
  "sdk": {
11
- "id": "swift-6.4.0-RELEASE_wasm-peach-19471d4b",
12
- "checksum": "764c16e7e34156bf90d6c3372a2b77b98b9d8c3470235520d0f9619f90f33456"
11
+ "id": "swift-6.4.0-RELEASE_wasm-peach-b577231e",
12
+ "checksum": "9a8f0c694ada318ede49413cd72395e34a7fbb1b9a227b31eff8b05371ffb9aa"
13
13
  },
14
14
  "framework": {
15
- "distribution": "e7ae8fdb51086f73",
16
- "wireAbi": "246b8412514b644113e6a26252c8ebd6de49ab4156ac5f5c98bb9e4c2ff2568b"
15
+ "distribution": "c7825880e72c77d4",
16
+ "wireAbi": "38eed69f6b7391584112981b7892914e7033d7e0c17c2e8d4a4448030618bd2b"
17
17
  },
18
18
  "archives": [
19
19
  {
20
20
  "headers": {
21
21
  "reactNativeJsi": "0f8c2defbca69a27a848a81ae72363073bf9602fd316e57a75811be1a0528358"
22
22
  },
23
- "sha256": "e48499ac95604409b5da4b0f113e8ec3d3e7de9bd170f2f401513c4a45c234dc",
24
- "size": 25392
23
+ "sha256": "675b1c6d919198a3329fa48d9ad74c05c093201fc4abe246436f7f8e1d47887f",
24
+ "size": 26175
25
25
  },
26
26
  {
27
27
  "headers": {
28
28
  "reactNativeJsi": "21a624ea24fd17d56bf26832d496fc1177067f89640414c20e6486c7984dfb0a"
29
29
  },
30
- "sha256": "bf331e9b3d141240d9fda77dc67e1d4b584513bdc455b0c37ae6aeb1a89038ed",
31
- "size": 26137
30
+ "sha256": "fb2a2b16ef4963022676c04a8acc23a10a3c7de9b1fb2760743a299eb5fb6cda",
31
+ "size": 26914
32
32
  },
33
33
  {
34
34
  "headers": {
35
35
  "reactNativeJsi": "324aefd8591d9ce688bce7589c4c2b516cd33ecb95d35c47239a87a8fcf6a8da"
36
36
  },
37
- "sha256": "181c4fef940e164d52f0e8a6284990cfa23a19c42afb445f6945cd959f708bf9",
38
- "size": 25392
37
+ "sha256": "3b5f5db71ed80b6c5563332e81edd9d9a7d626740471892e3a3aecf34946df8d",
38
+ "size": 26167
39
39
  },
40
40
  {
41
41
  "headers": {
42
42
  "reactNativeJsi": "33596664ee7d7a6623f0796a6feb429543316c3a41b211150acda6e1d835286c"
43
43
  },
44
- "sha256": "44ac75e98b6badd32e32556bfd04beab8728bbce58cf32f31528a7e17b6b3665",
45
- "size": 25166
44
+ "sha256": "7577e8dc552780eed3ee136fb7a77e19345199c4d87420b21a444adf647bf2ec",
45
+ "size": 25957
46
46
  },
47
47
  {
48
48
  "headers": {
49
49
  "reactNativeJsi": "66b2cd5a38511195207f6c8a76aba735f9b9cc66a52a0d00780ffe5d331623f7"
50
50
  },
51
- "sha256": "dab069c53f92c911f1f84c7c037077c6e73df2fbd1673cb9dbbff0c6014fb9ac",
52
- "size": 25398
51
+ "sha256": "1ccfb1335ba66d6f53d27a5a1ee9c223b7d05a9c0abb6eb7dccdc6124245e470",
52
+ "size": 26172
53
53
  },
54
54
  {
55
55
  "headers": {
56
56
  "reactNativeJsi": "96db4e758dd53e9320cef7cad485e00aa06e7a982cefd920f17007de8a5bd9f9"
57
57
  },
58
- "sha256": "6612544a0287c8cc231436ad31e9a45f4d824fbbc5e7da7460ac11728568c353",
59
- "size": 26139
58
+ "sha256": "15e27e276e9add8769400c323ea880867ebbefd3efb823b203b2eaae0be23fa4",
59
+ "size": 26913
60
60
  },
61
61
  {
62
62
  "headers": {
63
63
  "reactNativeJsi": "aeab590ddd1218df963462242d3954ce467b0fa88f70e91429e4ffc74d230893"
64
64
  },
65
- "sha256": "c73fb45ff0e2037bf21c6a0e019e80c645ff141e80052b750c7d14570a4f7e72",
66
- "size": 26138
65
+ "sha256": "f0243c32cdbe887ce7672e2abf3338dccbd76c43dfeb8686b7269f0d3272fb88",
66
+ "size": 26914
67
67
  },
68
68
  {
69
69
  "headers": {
70
70
  "reactNativeJsi": "b5fb260522384dd7ab07d740cdc534b529922446fcec798341c7817d9eaa49f4"
71
71
  },
72
- "sha256": "997372e6c03141640cfc3aab115b8afe9b04f6f6e806721f14f4fc0dc871d271",
73
- "size": 25267
72
+ "sha256": "b107936623043c5cbf4353acbbfadb6426750138304befd9e0fa768d6e256e49",
73
+ "size": 26046
74
74
  },
75
75
  {
76
76
  "headers": {
77
77
  "reactNativeJsi": "c6b391a1e870ccf7cdd534be63582862840f8245b99ebd253317deece1e6ffd5"
78
78
  },
79
- "sha256": "60f8e1e7da90a20ee5b112b950e264f93329014bfabdcbcd5aa1281945f2725b",
80
- "size": 26143
79
+ "sha256": "3c56322e46544e260cbbc6f90720cb2bdfd5373e744801e55b778113d99e8799",
80
+ "size": 26912
81
81
  },
82
82
  {
83
83
  "headers": {
84
84
  "reactNativeJsi": "c8270f1315745ecc204c4209a4f50f58ff6f14b4a385ad6820a69800270b53c6"
85
85
  },
86
- "sha256": "47269b8662bf147cbf9ccc011de79f0faffc30aa6b09344ad4f95dbdfae656c9",
87
- "size": 25105
86
+ "sha256": "e96bfa3c28e45bd3d4d64a059449d1960e7136a966d746662834ff3aa2d1ce6b",
87
+ "size": 25921
88
88
  }
89
89
  ]
90
90
  }
@@ -0,0 +1,296 @@
1
+ // narrows the host boundary of a linked wasm64 module to 32 bits, so host
2
+ // javascript keeps Number pointers once the memory is lowered. scalar i64 host
3
+ // imports retain their existing BigInt ABI; wasi pointers are already 32-bit
4
+ // in libc. the module's wide imports and exports get private
5
+ // names here, and wasm-merge fuses them with the thunk module that converts.
6
+
7
+ const I64 = 0x7e
8
+ const VALUE_TYPES = new Map([
9
+ [0x7f, 'i32'],
10
+ [I64, 'i64'],
11
+ [0x7d, 'f32'],
12
+ [0x7c, 'f64'],
13
+ [0x7b, 'v128'],
14
+ [0x70, 'funcref'],
15
+ [0x6f, 'externref'],
16
+ ])
17
+ const GUEST = 'guest'
18
+ const BOUNDARY = 'boundary'
19
+ const WIDE = '$wide.'
20
+ const NARROW = '$narrow.'
21
+
22
+ type FunctionType = { parameters: number[]; results: number[] }
23
+
24
+ function encodeNumber(value: number): number[] {
25
+ const bytes: number[] = []
26
+ for (let rest = value; ; ) {
27
+ const byte = rest % 128
28
+ rest = Math.floor(rest / 128)
29
+ if (rest === 0) return [...bytes, byte]
30
+ bytes.push(byte | 128)
31
+ }
32
+ }
33
+
34
+ function encodeName(name: string): number[] {
35
+ const bytes = [...Buffer.from(name)]
36
+ return [...encodeNumber(bytes.length), ...bytes]
37
+ }
38
+
39
+ function reader(bytes: Uint8Array, start: number, end: number) {
40
+ let at = start
41
+ const number = () => {
42
+ let value = 0
43
+ for (let shift = 0; ; shift += 7) {
44
+ if (at >= end || shift > 63) throw new Error('invalid wasm integer')
45
+ const byte = bytes[at++]!
46
+ value += (byte & 127) * 2 ** shift
47
+ if (!(byte & 128)) return value
48
+ }
49
+ }
50
+ return {
51
+ number,
52
+ byte: () => {
53
+ if (at >= end) throw new Error('truncated wasm section')
54
+ return bytes[at++]!
55
+ },
56
+ name: () => {
57
+ const length = number()
58
+ at += length
59
+ if (at > end) throw new Error('truncated wasm name')
60
+ return Buffer.from(bytes.subarray(at - length, at)).toString()
61
+ },
62
+ position: () => at,
63
+ done: () => at === end,
64
+ }
65
+ }
66
+
67
+ function sections(bytes: Uint8Array): { id: number; start: number; end: number }[] {
68
+ if (Buffer.from(bytes.subarray(0, 8)).toString('hex') !== '0061736d01000000')
69
+ throw new Error('not a wasm module')
70
+ const found: { id: number; start: number; end: number }[] = []
71
+ for (let at = 8; at < bytes.length; ) {
72
+ const header = reader(bytes, at, bytes.length)
73
+ const id = header.byte()
74
+ const size = header.number()
75
+ const start = header.position()
76
+ found.push({ id, start, end: start + size })
77
+ at = start + size
78
+ }
79
+ return found
80
+ }
81
+
82
+ // replaces whole sections and keeps every other byte.
83
+ function withSections(
84
+ bytes: Uint8Array,
85
+ layout: readonly { id: number; start: number; end: number }[],
86
+ replacements: ReadonlyMap<number, number[]>,
87
+ ): Buffer {
88
+ const parts: Uint8Array[] = [bytes.subarray(0, 8)]
89
+ let at = 8
90
+ for (const section of layout) {
91
+ const body = replacements.get(section.id)
92
+ parts.push(
93
+ body
94
+ ? Uint8Array.from([section.id, ...encodeNumber(body.length), ...body])
95
+ : bytes.subarray(at, section.end),
96
+ )
97
+ at = section.end
98
+ }
99
+ return Buffer.concat(parts)
100
+ }
101
+
102
+ const quoted = (name: string) =>
103
+ `"${[...Buffer.from(name)].map((byte) => `\\${byte.toString(16).padStart(2, '0')}`).join('')}"`
104
+
105
+ const signature = (types: readonly number[], keyword: string, narrow: boolean) =>
106
+ types.length === 0
107
+ ? ''
108
+ : ` (${keyword} ${types
109
+ .map((type) => {
110
+ const name = VALUE_TYPES.get(narrow && type === I64 ? 0x7f : type)
111
+ if (!name) throw new Error(`unsupported wasm boundary type ${type}`)
112
+ return name
113
+ })
114
+ .join(' ')})`
115
+
116
+ const wide = (type: FunctionType) =>
117
+ type.parameters.includes(I64) || type.results.includes(I64)
118
+
119
+ /**
120
+ * the module with its wide imports and exports renamed for the merge, and the
121
+ * thunk module's text; undefined when the boundary is already narrow.
122
+ */
123
+ export function narrowWasmBoundary(
124
+ bytes: Uint8Array,
125
+ ): { module: Buffer; thunks: string } | undefined {
126
+ const layout = sections(bytes)
127
+ const section = (id: number) => {
128
+ const found = layout.find((entry) => entry.id === id)
129
+ return found && reader(bytes, found.start, found.end)
130
+ }
131
+
132
+ const types: FunctionType[] = []
133
+ const typeSection = section(1)
134
+ if (typeSection) {
135
+ for (let count = typeSection.number(); count > 0; count--) {
136
+ if (typeSection.byte() !== 0x60) throw new Error('unsupported wasm type')
137
+ const values = () =>
138
+ Array.from({ length: typeSection.number() }, () => typeSection.byte())
139
+ types.push({ parameters: values(), results: values() })
140
+ }
141
+ }
142
+ const typeAt = (index: number) => {
143
+ const type = types[index]
144
+ if (!type) throw new Error('invalid wasm type index')
145
+ return type
146
+ }
147
+
148
+ const thunks: string[] = []
149
+ const functionTypes: FunctionType[] = []
150
+ const importBody: number[] = []
151
+ const importSection = section(2)
152
+ if (importSection) {
153
+ const count = importSection.number()
154
+ importBody.push(...encodeNumber(count))
155
+ for (let index = 0; index < count; index++) {
156
+ const module = importSection.name()
157
+ const name = importSection.name()
158
+ const start = importSection.position()
159
+ const kind = importSection.byte()
160
+ const limits = () => {
161
+ const flags = importSection.number()
162
+ importSection.number()
163
+ if (flags & 1) importSection.number()
164
+ }
165
+ let type: FunctionType | undefined
166
+ if (kind === 0) {
167
+ type = typeAt(importSection.number())
168
+ functionTypes.push(type)
169
+ } else if (kind === 1) {
170
+ importSection.byte()
171
+ limits()
172
+ } else if (kind === 2) limits()
173
+ else if (kind === 3) {
174
+ importSection.byte()
175
+ importSection.byte()
176
+ } else if (kind === 4) {
177
+ importSection.byte()
178
+ importSection.number()
179
+ } else throw new Error('unsupported wasm import')
180
+ const scalar64 = (parameter: number | null) =>
181
+ (module === 'wasi_snapshot_preview1' &&
182
+ (!name.startsWith('peach_') ||
183
+ (name === 'peach_fs_path_birthtime_set' && parameter === 2))) ||
184
+ (module === 'peach' && name === 'hw_memsize' && parameter === null) ||
185
+ (module === 'peach_notify' && name === 'set' && parameter === 1)
186
+ const parameters = type?.parameters.map((value, index) =>
187
+ value === I64 && !scalar64(index) ? 0x7f : value,
188
+ )
189
+ const results = type?.results.map((value) =>
190
+ value === I64 && !scalar64(null) ? 0x7f : value,
191
+ )
192
+ if (
193
+ type &&
194
+ parameters &&
195
+ results &&
196
+ (parameters.some((value, index) => value !== type.parameters[index]) ||
197
+ results.some((value, index) => value !== type.results[index]))
198
+ ) {
199
+ if (type.results.length > 1)
200
+ throw new Error(`import ${module}.${name} returns several values`)
201
+ const id = thunks.length
202
+ const call = `(call $host${id}${type.parameters
203
+ .map((value, at) =>
204
+ value !== parameters[at]
205
+ ? ` (i32.wrap_i64 (local.get ${at}))`
206
+ : ` (local.get ${at})`,
207
+ )
208
+ .join('')})`
209
+ thunks.push(
210
+ `(import ${quoted(module)} ${quoted(name)} (func $host${id}${signature(parameters, 'param', false)}${signature(results, 'result', false)}))`,
211
+ `(func (export "${NARROW}${id}")${signature(type.parameters, 'param', false)}${signature(type.results, 'result', false)} ${type.results[0] !== results[0] ? `(i64.extend_i32_u ${call})` : call})`,
212
+ )
213
+ importBody.push(...encodeName(BOUNDARY), ...encodeName(`${NARROW}${id}`))
214
+ } else importBody.push(...encodeName(module), ...encodeName(name))
215
+ importBody.push(...bytes.subarray(start, importSection.position()))
216
+ }
217
+ if (!importSection.done()) throw new Error('invalid wasm imports')
218
+ }
219
+
220
+ const functionSection = section(3)
221
+ if (functionSection)
222
+ for (let count = functionSection.number(); count > 0; count--)
223
+ functionTypes.push(typeAt(functionSection.number()))
224
+
225
+ const exportBody: number[] = []
226
+ const exportSection = section(7)
227
+ if (exportSection) {
228
+ const count = exportSection.number()
229
+ exportBody.push(...encodeNumber(count))
230
+ for (let index = 0; index < count; index++) {
231
+ const name = exportSection.name()
232
+ const kind = exportSection.byte()
233
+ const target = exportSection.number()
234
+ const type = kind === 0 ? functionTypes[target] : undefined
235
+ if (kind === 0 && !type) throw new Error('invalid wasm export')
236
+ if (type && wide(type)) {
237
+ if (type.results.length > 1)
238
+ throw new Error(`export ${name} returns several values`)
239
+ const id = thunks.length
240
+ const call = `(call $guest${id}${type.parameters
241
+ .map((value, at) =>
242
+ value === I64
243
+ ? ` (i64.extend_i32_u (local.get ${at}))`
244
+ : ` (local.get ${at})`,
245
+ )
246
+ .join('')})`
247
+ thunks.push(
248
+ `(import "${GUEST}" "${WIDE}${id}" (func $guest${id}${signature(type.parameters, 'param', false)}${signature(type.results, 'result', false)}))`,
249
+ `(func (export ${quoted(name)})${signature(type.parameters, 'param', true)}${signature(type.results, 'result', true)} ${type.results[0] === I64 ? `(i32.wrap_i64 ${call})` : call})`,
250
+ )
251
+ exportBody.push(...encodeName(`${WIDE}${id}`))
252
+ } else exportBody.push(...encodeName(name))
253
+ exportBody.push(kind, ...encodeNumber(target))
254
+ }
255
+ if (!exportSection.done()) throw new Error('invalid wasm exports')
256
+ }
257
+
258
+ if (thunks.length === 0) return undefined
259
+ // imports precede definitions in the text format.
260
+ const imports = thunks.filter((line) => line.startsWith('(import'))
261
+ const functions = thunks.filter((line) => !line.startsWith('(import'))
262
+ return {
263
+ module: withSections(
264
+ bytes,
265
+ layout,
266
+ new Map([
267
+ [2, importBody],
268
+ [7, exportBody],
269
+ ]),
270
+ ),
271
+ thunks: `(module\n${[...imports, ...functions].join('\n')}\n)\n`,
272
+ }
273
+ }
274
+
275
+ export const NARROW_MERGE_NAMES = { guest: GUEST, boundary: BOUNDARY }
276
+
277
+ /** drops the private names the merge left exported. */
278
+ export function dropBoundaryExports(bytes: Uint8Array): Buffer {
279
+ const layout = sections(bytes)
280
+ const found = layout.find((entry) => entry.id === 7)
281
+ if (!found) throw new Error('merged module has no exports')
282
+ const exportSection = reader(bytes, found.start, found.end)
283
+ const kept: number[][] = []
284
+ for (let count = exportSection.number(); count > 0; count--) {
285
+ const name = exportSection.name()
286
+ const kind = exportSection.byte()
287
+ const target = exportSection.number()
288
+ if (!name.startsWith(WIDE) && !name.startsWith(NARROW))
289
+ kept.push([...encodeName(name), kind, ...encodeNumber(target)])
290
+ }
291
+ return withSections(
292
+ bytes,
293
+ layout,
294
+ new Map([[7, [...encodeNumber(kept.length), ...kept.flat()]]]),
295
+ )
296
+ }