peachsim 0.1.2223 → 0.1.2225

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 (152) hide show
  1. package/cli/internal-child.ts +4 -2
  2. package/dist-lib/agent-daemon-client.cjs +1 -1
  3. package/dist-lib/agent-events.cjs +1 -1
  4. package/dist-lib/attached-projects.cjs +1 -1
  5. package/dist-lib/auth/shared-session.cjs +1 -1
  6. package/dist-lib/backend-origin.cjs +1 -1
  7. package/dist-lib/beta.cjs +1 -1
  8. package/dist-lib/beta.mjs +1 -1
  9. package/dist-lib/bridge-constants.cjs +1 -1
  10. package/dist-lib/bridge-contract-input.cjs +1 -1
  11. package/dist-lib/bridge-contract-input.mjs +1 -1
  12. package/dist-lib/bridge-contract.cjs +1 -1
  13. package/dist-lib/bridge-contract.mjs +1 -1
  14. package/dist-lib/bundle-channel.cjs +875 -468
  15. package/dist-lib/capture-contract.cjs +1 -1
  16. package/dist-lib/capture-contract.mjs +1 -1
  17. package/dist-lib/cloud-contract.cjs +1 -1
  18. package/dist-lib/cloud-contract.mjs +1 -1
  19. package/dist-lib/cloud-test-args.cjs +1 -1
  20. package/dist-lib/cloud-test-args.mjs +1 -1
  21. package/dist-lib/cloud.cjs +1 -1
  22. package/dist-lib/cloud.mjs +1 -1
  23. package/dist-lib/config.cjs +1 -1
  24. package/dist-lib/config.mjs +1 -1
  25. package/dist-lib/detox/index.cjs +2 -2
  26. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  27. package/dist-lib/expo-swift-bundle.cjs +811 -404
  28. package/dist-lib/expo-swift-metadata.cjs +1 -1
  29. package/dist-lib/expo-swift-metadata.mjs +1 -1
  30. package/dist-lib/home-paths.cjs +1 -1
  31. package/dist-lib/host/bridge-host.cjs +870 -463
  32. package/dist-lib/host/fetch-proxy-handler.cjs +55 -12
  33. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  34. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  35. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  36. package/dist-lib/host/websocket-proxy.cjs +1 -1
  37. package/dist-lib/index.cjs +60 -16
  38. package/dist-lib/jump-to-source-babel.cjs +1 -1
  39. package/dist-lib/jump-to-source-native.cjs +1 -1
  40. package/dist-lib/kotlin-host.cjs +1 -1
  41. package/dist-lib/menu.cjs +1 -1
  42. package/dist-lib/menu.mjs +1 -1
  43. package/dist-lib/metro-fingerprint-registry.cjs +1 -1
  44. package/dist-lib/metro-fingerprint-registry.mjs +1 -1
  45. package/dist-lib/metro-production-bundle.cjs +1 -1
  46. package/dist-lib/metro-production-bundle.mjs +1 -1
  47. package/dist-lib/metro.cjs +60 -16
  48. package/dist-lib/native-app-identity-project.cjs +53 -9
  49. package/dist-lib/native-app-identity-project.mjs +84 -37
  50. package/dist-lib/native-app-identity.cjs +1 -1
  51. package/dist-lib/native-app-identity.mjs +1 -1
  52. package/dist-lib/native-firebase-metadata.cjs +1 -1
  53. package/dist-lib/native-firebase-metadata.mjs +1 -1
  54. package/dist-lib/pdfium-raster.cjs +1 -1
  55. package/dist-lib/pdfium-raster.mjs +1 -1
  56. package/dist-lib/plist.cjs +1 -1
  57. package/dist-lib/plist.mjs +1 -1
  58. package/dist-lib/profiles.cjs +1 -1
  59. package/dist-lib/public-brand.cjs +1 -1
  60. package/dist-lib/public-origins-lib-esm.json +26 -24
  61. package/dist-lib/public-origins-lib.json +65 -54
  62. package/dist-lib/react-native-host-modules.cjs +1 -1
  63. package/dist-lib/react-native-host-modules.mjs +1 -1
  64. package/dist-lib/reap-browser.cjs +1 -1
  65. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  66. package/dist-lib/sdk.cjs +1 -1
  67. package/dist-lib/sdk.mjs +1 -1
  68. package/dist-lib/skills.cjs +919 -511
  69. package/dist-lib/swift-compile.cjs +491 -119
  70. package/dist-lib/swift-compile.mjs +629 -257
  71. package/dist-lib/swift-package.cjs +1 -1
  72. package/dist-lib/swift-package.mjs +1 -1
  73. package/dist-lib/swift-submit.cjs +1 -1
  74. package/dist-lib/swift-submit.mjs +1 -1
  75. package/dist-lib/swift-toolchain.cjs +38 -2
  76. package/dist-lib/swift.cjs +1 -1
  77. package/dist-lib/vite-swift.cjs +1665 -1217
  78. package/dist-lib/vite.cjs +55 -12
  79. package/dist-lib/worklet-executable.cjs +1 -1
  80. package/dist-lib/worklet-executable.mjs +1 -1
  81. package/dist-types/packages/peach-engine/src/engine/glass-material.d.ts +4 -0
  82. package/dist-types/packages/peach-engine/src/engine/liquid-glass.d.ts +3 -6
  83. package/dist-types/packages/peach-engine/src/engine/scene-table.d.ts +1 -1
  84. package/dist-types/packages/peach-engine/src/engine/types.d.ts +1 -0
  85. package/dist-types/packages/peach-engine/src/preview/preview-room-contract.d.ts +6 -0
  86. package/dist-types/packages/peach-engine/src/render-worker/protocol.d.ts +12 -0
  87. package/kotlin/sdk.tar.gz +0 -0
  88. package/package.json +1 -1
  89. package/runtime-companion.json +1 -1
  90. package/sdk/ios/System/Library/Frameworks/CoreFoundation.framework/Headers/CFCGTypes.h +0 -6
  91. package/sdk/ios/System/Library/Frameworks/Foundation.framework/Headers/NSCharacterSet.h +1 -1
  92. package/sdk/ios/System/Library/Frameworks/Foundation.framework/Headers/NSURL.h +1 -1
  93. package/sdk/ios/usr/include/AvailabilityInternal.h +2 -2
  94. package/sdk/ios/usr/include/peach/pthread.h +1 -7
  95. package/sdk/ios/wasm/include/TargetConditionals.h +2 -3
  96. package/sdk/ios/wasm/include/__struct_timeval.h +15 -0
  97. package/sdk/ios/wasm/include/__typedef_suseconds_t.h +9 -0
  98. package/sdk/ios/wasm/include/limits.h +1 -1
  99. package/sdk/ios/wasm/include/machine/_types.h +1 -1
  100. package/sdk/ios/wasm/include/machine/limits.h +1 -1
  101. package/sdk/ios/wasm/include/machine/param.h +2 -2
  102. package/sdk/ios/wasm/include/math.h +13 -0
  103. package/sdk/ios/wasm/include/pthread.h +1 -13
  104. package/sdk/ios/wasm/include/sys/resource.h +3 -0
  105. package/sdk/ios/wasm/include/sys/socket.h +0 -10
  106. package/sdk/ios/wasm/include/sys/stat.h +5 -2
  107. package/sdk/ios/wasm/include/sys/time.h +16 -3
  108. package/sdk/ios/wasm/include/sys/types.h +4 -1
  109. package/sdk/ios/wasm/include/time.h +2 -0
  110. package/sdk/ios/wasm/storage-include/TargetConditionals.h +2 -3
  111. package/sdk/native-hashes.json +14 -14
  112. package/src/conformance-comparison-contract.ts +9 -9
  113. package/src/native-slices.ts +3 -2
  114. package/src/native-static-libraries.ts +23 -23
  115. package/src/native-swift-slices.ts +2 -2
  116. package/src/nitro-adapter.lock.json +288 -288
  117. package/src/nitro-compiler-digest.ts +0 -1
  118. package/src/nitro-dependencies.ts +8 -9
  119. package/src/nitro-superset.lock.json +4 -4
  120. package/src/react-native-core-build.ts +2 -2
  121. package/src/swift-compile.ts +132 -45
  122. package/src/swift-compiler-digest.ts +2 -0
  123. package/src/swift-cxx-standin.ts +1 -1
  124. package/src/swift-darwin-records.ts +4 -4
  125. package/src/swift-distribution-contract.ts +2 -2
  126. package/src/swift-distribution.lock.json +13 -12
  127. package/src/swift-guest-compile.ts +6 -5
  128. package/src/swift-guest-image-ledger.ts +5 -5
  129. package/src/swift-guest-link.ts +1 -1
  130. package/src/swift-guest-linked-spans.ts +7 -4
  131. package/src/swift-guest-manifest.ts +2 -2
  132. package/src/swift-guest-source-inputs.ts +16 -5
  133. package/src/swift-host.ts +33 -31
  134. package/src/swift-icu.ts +1 -1
  135. package/src/swift-objc-compile.ts +9 -4
  136. package/src/swift-objc-standin.ts +1 -4
  137. package/src/swift-package-manifest.ts +5 -1
  138. package/src/swift-packages.ts +2 -2
  139. package/src/swift-shared-sdk.ts +1 -1
  140. package/src/swift-standin-emit.ts +2 -16
  141. package/src/swift-standins.ts +111 -87
  142. package/src/swift-toolchain.ts +37 -1
  143. package/src/swift-uniform-type-constants.ts +1 -1
  144. package/src/swift-wasm-prune.ts +17 -12
  145. package/src/swiftGuestImageContract.ts +4 -4
  146. package/src/swiftNativePinContract.ts +1 -1
  147. package/src/swiftRuntimeProductContract.ts +1 -1
  148. package/src/turbo-runtime.lock.json +28 -28
  149. package/src/vite-plugin.ts +6 -1
  150. package/src/wasm-narrow-boundary.ts +296 -0
  151. package/src/wasm-optimize.ts +59 -14
  152. package/src/xcode-project.ts +6 -4
@@ -1,6 +1,6 @@
1
1
  import { execFileSync } from 'node:child_process'
2
2
  import { createHash } from 'node:crypto'
3
- import { readFileSync, realpathSync, writeFileSync } from 'node:fs'
3
+ import { mkdirSync, readFileSync, realpathSync, writeFileSync } from 'node:fs'
4
4
  import path from 'node:path'
5
5
  import { libraryArchiveTarget, type GuestSourceArtifact } from './swift-guest-source-plan'
6
6
  import { frameworkRuntimeProductId } from './swift-runtime-products'
@@ -42,6 +42,10 @@ export function clangIrLinkOptions(ir: string): string[] {
42
42
  return result
43
43
  }
44
44
 
45
+ // the C compiler a package build runs: the toolchain clang, named for the
46
+ // target whose <target>.build directory receives the object
47
+ export const CLANG_TARGET_MODULE_WRAPPER = '.peach-clang'
48
+
45
49
  /** Replay only selected source-owned Clang commands to retain their IR link options. */
46
50
  export function sourceGuestClangLinkOptions(options: {
47
51
  buildDirectory: string
@@ -97,15 +101,22 @@ export function sourceGuestClangLinkOptions(options: {
97
101
  throw new Error(`unsupported source object producer ${file}`)
98
102
  continue
99
103
  }
104
+ const compiler = command.args[0] ? realpathSync(command.args[0]) : ''
100
105
  if (
101
106
  command.tool !== 'clang' ||
102
- !command.args.length ||
103
- realpathSync(command.args[0]!) !==
104
- realpathSync(path.join(options.toolchainBin, 'clang'))
107
+ (compiler !== realpathSync(path.join(options.toolchainBin, 'clang')) &&
108
+ compiler !==
109
+ realpathSync(path.join(options.buildDirectory, CLANG_TARGET_MODULE_WRAPPER)))
105
110
  )
106
111
  throw new Error(`unsupported source object producer ${file}`)
107
112
  const args = command.args.slice(1).filter((arg) => arg !== '-c')
108
- const output = path.join(options.directory, `clang-link-${index}.ll`)
113
+ // the replay keeps the object's <target>.build directory name
114
+ const outputDirectory = path.join(
115
+ options.directory,
116
+ path.basename(path.dirname(file)),
117
+ )
118
+ mkdirSync(outputDirectory, { recursive: true })
119
+ const output = path.join(outputDirectory, `clang-link-${index}.ll`)
109
120
  for (const flag of ['-o', '-MF']) {
110
121
  const index = args.lastIndexOf(flag)
111
122
  if (index < 0 || index + 1 >= args.length)
package/src/swift-host.ts CHANGED
@@ -1171,16 +1171,21 @@ async function buildXcodeLayout(root: string): Promise<XcodeLayout | null> {
1171
1171
  )
1172
1172
  .map((feature) => feature.name),
1173
1173
  // the flat build gives every module one package; swiftpm names each
1174
- // module for its own package, which `@retroactive` and `package` read
1175
- swiftFlags: ['-package-name', swiftPackageIdentity(target.packageDir)].concat(
1176
- target.packageSwiftFlags
1174
+ // module for its own package, which `@retroactive` and `package` read.
1175
+ // xcode and swiftpm build a debug package testable, so sources may
1176
+ // `@testable import` it
1177
+ swiftFlags: [
1178
+ '-package-name',
1179
+ swiftPackageIdentity(target.packageDir),
1180
+ ...(packageConfiguration === 'debug' ? ['-enable-testing'] : []),
1181
+ ...target.packageSwiftFlags
1177
1182
  .filter(
1178
1183
  (setting) =>
1179
1184
  setting.configuration === null ||
1180
1185
  setting.configuration === packageConfiguration,
1181
1186
  )
1182
1187
  .flatMap((setting) => setting.flags),
1183
- ),
1188
+ ],
1184
1189
  linkedLibraries: target.packageLibraries
1185
1190
  .filter(
1186
1191
  (library) =>
@@ -1666,7 +1671,7 @@ function xcodeManifest(layout: XcodeLayout): string {
1666
1671
  return [
1667
1672
  '// swift-tools-version: 6.2',
1668
1673
  'import PackageDescription',
1669
- `let package = Package(name: "app", ${layout.app.iosDeploymentTarget ? `platforms: [.iOS(${JSON.stringify(layout.app.iosDeploymentTarget)})], ` : ''}dependencies: [${[...nativePaths].map(([name, directory]) => `.package(name: ${JSON.stringify(name)}, path: ${JSON.stringify(directory)})`).join(', ')}], targets: [`,
1674
+ `let package = Package(name: "app", platforms: [.iOS(${JSON.stringify(layout.app.iosDeploymentTarget)})], dependencies: [${[...nativePaths].map(([name, directory]) => `.package(name: ${JSON.stringify(name)}, path: ${JSON.stringify(directory)})`).join(', ')}], targets: [`,
1670
1675
  ` .executableTarget(name: "${layout.app.moduleName}", dependencies: [${[...appProducts, ...layout.targets.map((target) => JSON.stringify(target.name)), ...sdkProducts].join(', ')}], path: "${XCODE_APP_DIR}", ${appSettings}),`,
1671
1676
  ...layout.targets.map((target) =>
1672
1677
  target.systemLibrary
@@ -2812,6 +2817,28 @@ export function compileInput(
2812
2817
  )
2813
2818
  }
2814
2819
 
2820
+ export function swiftBuildRoot(packagePath: string, moduleRoot: string): string {
2821
+ if (process.env.CONTRAST_SWIFT_BUILD_ROOT) return process.env.CONTRAST_SWIFT_BUILD_ROOT
2822
+ const resolvedPath = path.resolve(packagePath)
2823
+ const parts = resolvedPath.split(path.sep)
2824
+ const scopedAt = Math.max(
2825
+ parts.lastIndexOf('peach-expo-swift'),
2826
+ parts.lastIndexOf('peach-nitro-swift'),
2827
+ )
2828
+ const buildKeyPath =
2829
+ scopedAt >= 0 && parts.length >= scopedAt + 3
2830
+ ? parts.slice(0, scopedAt + 2).join(path.sep)
2831
+ : (sourceEntries().get(resolvedPath) ?? resolvedPath)
2832
+ return path.join(
2833
+ swiftCacheDir(),
2834
+ 'swift-builds',
2835
+ createHash('sha256')
2836
+ .update(`${moduleRoot}\0${buildKeyPath}`)
2837
+ .digest('hex')
2838
+ .slice(0, 16),
2839
+ )
2840
+ }
2841
+
2815
2842
  // the compile input of an installed workspace with the binary frameworks its
2816
2843
  // pods and project vendor, read from one layout.
2817
2844
  export function installedWorkspaceInput(
@@ -2922,32 +2949,7 @@ async function compile(
2922
2949
  // building each other's sources. each app and module checkout still gets
2923
2950
  // its own root, so they do not queue and the same app keeps its
2924
2951
  // incremental build across restarts.
2925
- buildRoot: (() => {
2926
- if (process.env.CONTRAST_SWIFT_BUILD_ROOT)
2927
- return process.env.CONTRAST_SWIFT_BUILD_ROOT
2928
- const resolvedPath = path.resolve(packagePath)
2929
- // units of one app or nitro module share a root so the module cache stays
2930
- // warm across server restarts: peach-expo-swift/<app>/<scope>/<package>
2931
- // and peach-nitro-swift/<module>/<scope> share <app> or <module>.
2932
- // servers on one app or module queue on the root lock.
2933
- const parts = resolvedPath.split(path.sep)
2934
- const scopedAt = Math.max(
2935
- parts.lastIndexOf('peach-expo-swift'),
2936
- parts.lastIndexOf('peach-nitro-swift'),
2937
- )
2938
- const buildKeyPath =
2939
- scopedAt >= 0 && parts.length >= scopedAt + 3
2940
- ? parts.slice(0, scopedAt + 2).join(path.sep)
2941
- : (sourceEntries().get(resolvedPath) ?? resolvedPath)
2942
- return path.join(
2943
- swiftCacheDir(),
2944
- 'swift-builds',
2945
- createHash('sha256')
2946
- .update(`${moduleRoot}\0${buildKeyPath}`)
2947
- .digest('hex')
2948
- .slice(0, 16),
2949
- )
2950
- })(),
2952
+ buildRoot: swiftBuildRoot(packagePath, moduleRoot),
2951
2953
  moduleRoot,
2952
2954
  ...toolchain,
2953
2955
  signal,
package/src/swift-icu.ts CHANGED
@@ -141,7 +141,7 @@ async function load(toolchainBin: string, sdk: string): Promise<Buffer> {
141
141
  ...swiftSdkOptions(),
142
142
  '--show-configuration',
143
143
  sdk,
144
- 'wasm32-unknown-wasip1',
144
+ 'wasm64-unknown-wasip1',
145
145
  ],
146
146
  { env: swiftEnvironment() },
147
147
  )
@@ -5,7 +5,7 @@ import path from 'node:path'
5
5
  import { mapLimit } from '../../../src/helpers/mapLimit.ts'
6
6
  import { cacheDir } from './home-paths'
7
7
  import { isRecord } from './is-record'
8
- import { DOUBLE_CONVERSION_WASM32_BACKPORT } from './nitro-dependencies'
8
+ import { DOUBLE_CONVERSION_WASM64_BACKPORT } from './nitro-dependencies'
9
9
  import {
10
10
  swiftBuildJobs,
11
11
  swiftSdkPaths,
@@ -320,7 +320,7 @@ function* xcodeObjCInputSteps(
320
320
  )
321
321
  // the pod's own double-conversion utils.h takes the approved backport by
322
322
  // its exact original bytes; the file on disk stays unchanged.
323
- const backport = DOUBLE_CONVERSION_WASM32_BACKPORT
323
+ const backport = DOUBLE_CONVERSION_WASM64_BACKPORT
324
324
  if (
325
325
  path.basename(file) !== 'utils.h' ||
326
326
  createHash('sha256').update(bytes).digest('hex') !== backport.originalSha256
@@ -713,6 +713,11 @@ function* xcodeObjCInputSteps(
713
713
  }
714
714
  for (const reference of references) {
715
715
  if (++workCount % 64 === 0) yield
716
+ if (
717
+ path.isAbsolute(reference.name) &&
718
+ /\.sdk\/(?:System|Developer)\/Library\/Frameworks\//.test(reference.name)
719
+ )
720
+ continue
716
721
  // only the first quoted lookup depends on the including file. after a
717
722
  // local miss, every includer shares the target's ordered search paths.
718
723
  if (reference.quoted && !reference.next) {
@@ -1120,7 +1125,7 @@ export function prepareXcodeSwiftProducts(
1120
1125
  ? ['-merge-modules', '-emit-module']
1121
1126
  : ['-emit-object', '-whole-module-optimization', '-parse-as-library']),
1122
1127
  '-target',
1123
- 'wasm32-unknown-wasip1',
1128
+ 'wasm64-unknown-wasip1',
1124
1129
  '-sdk',
1125
1130
  sdk.sysroot,
1126
1131
  '-resource-dir',
@@ -1547,7 +1552,7 @@ export async function prepareXcodeObjCImplementations(
1547
1552
  (!cxx ||
1548
1553
  flags.lastIndexOf('-fno-cxx-modules') <= flags.lastIndexOf('-fcxx-modules'))
1549
1554
  const args = [
1550
- '--target=wasm32-unknown-wasip1',
1555
+ '--target=wasm64-unknown-wasip1',
1551
1556
  `--sysroot=${sdk.sysroot}`,
1552
1557
  '-fwasm-exceptions',
1553
1558
  '-fexceptions',
@@ -303,14 +303,11 @@ export function objcSdkIntakeFlags(
303
303
  return [
304
304
  ...swiftObjCPlatformFlags(toolchainBin, minimum),
305
305
  // AvailabilityInternal.h derives these through __is_target_os(ios), which
306
- // is false for wasm32. the maximum is the sdk the headers come from, as
306
+ // is false for wasm64. the maximum is the sdk the headers come from, as
307
307
  // xcode defines it, so `#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_26_0`
308
308
  // sources see the members the sdk declares instead of a 17.0 default.
309
309
  `-D__IPHONE_OS_VERSION_MIN_REQUIRED=${minimum}`,
310
310
  `-D__IPHONE_OS_VERSION_MAX_ALLOWED=__IPHONE_${NATIVE_GRAPH_SDK_VERSION.replace('.', '_')}`,
311
- // apple's build setting for a 32-bit target to keep NSInteger and
312
- // NSUInteger long, the nominal types they have on arm64.
313
- '-DNS_BUILD_32_LIKE_64=1',
314
311
  // the installed libc's default feature set otherwise defines
315
312
  // _XOPEN_SOURCE, which darwin's sys/cdefs.h turns into a strict posix
316
313
  // level; iOS compiles at darwin's full level with neither defined.
@@ -513,7 +513,11 @@ export function swiftPackageManifest(
513
513
  ? '5'
514
514
  : (string(record(raw.toolsVersion)._version) ?? 'unknown')
515
515
  let mainActorIsolation = false
516
- const defines: SwiftManifestSetting[] = []
516
+ // swiftpm defines each enabled trait as a condition in every swift target
517
+ const defines: SwiftManifestSetting[] = [...traits].map((name) => ({
518
+ name,
519
+ configuration: null,
520
+ }))
517
521
  const libraries: SwiftManifestSetting[] = []
518
522
  const frameworks: SwiftManifestSetting[] = []
519
523
  const experimentalFeatures: SwiftManifestSetting[] = []
@@ -116,7 +116,7 @@ export interface SwiftPackageBinary {
116
116
  reached: boolean
117
117
  /** a source Objective-C target: public headers relative to dir. */
118
118
  publicHeaders?: string
119
- /** sources, relative to the package, with no wasm32 lowering that keep a
119
+ /** sources, relative to the package, with no wasm lowering that keep a
120
120
  * source target from compiling; its public headers stand in for it. */
121
121
  unloweredSources?: string[]
122
122
  /** dependency module public headers, relative to dir. */
@@ -693,7 +693,7 @@ export function resolveSwiftPackages(options: {
693
693
  : target.type !== 'regular' && target.type !== 'system'
694
694
  ? `${name} is a ${target.type} target`
695
695
  : unlowerable.length > 0
696
- ? `${name} has native sources with no wasm32 lowering: ${unlowerable.map((file) => path.relative(pkg.manifest.dir, file)).join(', ')}${gap ? `; ${gap}` : ''}`
696
+ ? `${name} has native sources with no wasm lowering: ${unlowerable.map((file) => path.relative(pkg.manifest.dir, file)).join(', ')}${gap ? `; ${gap}` : ''}`
697
697
  : null
698
698
  // every dependency resolves, so a failing one never hides the rest
699
699
  // of the closure from the compile or from the report
@@ -277,7 +277,7 @@ export function swiftSharedSdkViewOptions(
277
277
  ...swiftSdkOptions(),
278
278
  '--show-configuration',
279
279
  sdk,
280
- 'wasm32-unknown-wasip1',
280
+ 'wasm64-unknown-wasip1',
281
281
  ],
282
282
  { encoding: 'utf8', env: swiftEnvironment(), stdio: ['ignore', 'pipe', 'pipe'] },
283
283
  )
@@ -1703,8 +1703,7 @@ export function emitSwiftStandin(
1703
1703
  synthesizedEquality(member, list))
1704
1704
  )
1705
1705
  continue
1706
- const header = values.get(member.identifier.precise)
1707
- const value = header === undefined ? undefined : atWidth(header, raw)
1706
+ const value = values.get(member.identifier.precise)
1708
1707
  if (value !== undefined && member.kind.identifier === 'swift.type.property') {
1709
1708
  emit(
1710
1709
  `${inner}public static let ${tick(leaf(member))} = ${shape.name}(rawValue: ${value})`,
@@ -1763,8 +1762,7 @@ export function emitSwiftStandin(
1763
1762
  )
1764
1763
  const seenValues = new Map<string, string>()
1765
1764
  for (const member of cases) {
1766
- const header = values.get(member.identifier.precise)
1767
- const value = header === undefined ? undefined : atWidth(header, raw)
1765
+ const value = values.get(member.identifier.precise)
1768
1766
  // objective-c aliases a value under a second name; swift spells
1769
1767
  // the alias as a static member of the first case.
1770
1768
  if (value !== undefined && seenValues.has(value)) {
@@ -1976,18 +1974,6 @@ export function emitSwiftStandin(
1976
1974
  }
1977
1975
  return null
1978
1976
  }
1979
- // header values are clang's for 64-bit iOS. NSUIntegerMax, NSIntegerMax
1980
- // and NSIntegerMin are the platform-width type's own extremes, which on
1981
- // wasm32 are the 32-bit ones.
1982
- const atWidth = (value: string, raw: string | null) =>
1983
- (raw === 'UInt' || raw === 'Swift.UInt') && value === '18446744073709551615'
1984
- ? '4294967295'
1985
- : (raw === 'Int' || raw === 'Swift.Int') && value === '9223372036854775807'
1986
- ? '2147483647'
1987
- : (raw === 'Int' || raw === 'Swift.Int') && value === '-9223372036854775808'
1988
- ? '-2147483648'
1989
- : value
1990
-
1991
1977
  const emitGlobal = scoped((symbol: GraphSymbol) => {
1992
1978
  const path = pathOf(symbol)
1993
1979
  const kind = symbol.kind.identifier
@@ -13,12 +13,14 @@ import { execFileSync, spawn, spawnSync } from 'node:child_process'
13
13
  import { createHash } from 'node:crypto'
14
14
  import fs from 'node:fs'
15
15
  import path from 'node:path'
16
+ import { PEACH_FORKED_SCRIPT_ENV } from './forked-script-contract'
16
17
  import { cacheDir as peachCacheDir } from './home-paths'
17
18
  import { isRecord } from './is-record'
18
19
  import { fetchNativeEntry, nativeEntryKey } from './native-prebuilt'
19
20
  import { nativeSliceEntry, NATIVE_SLICE_RECIPES } from './native-slices'
20
21
  import { nativeStaticLibrary, nativeStaticLibraryRecipe } from './native-static-libraries'
21
22
  import { nativeSwiftSlice } from './native-swift-slices'
23
+ import { tryAcquireNumberedLock } from './numbered-lock'
22
24
  import { outputLockStdio } from './output-lock-stdio'
23
25
  import {
24
26
  FOUNDATION_IMPLICIT_MODULES,
@@ -35,6 +37,7 @@ import {
35
37
  swiftSdkPaths,
36
38
  } from './swift-compile'
37
39
  import { emitCxxStandin } from './swift-cxx-standin'
40
+ import { swiftModuleToolchain } from './swift-distribution'
38
41
  import {
39
42
  iosSdkId,
40
43
  WASI_EMULATION,
@@ -74,7 +77,7 @@ import {
74
77
  } from './swift-toolchain'
75
78
  import { simulatorNativeLibrary } from './swift-xcframework'
76
79
 
77
- const TRIPLE = 'wasm32-unknown-wasip1'
80
+ const TRIPLE = 'wasm64-unknown-wasip1'
78
81
  // every stand-in artifact and temporary workspace belongs to peach.
79
82
  const cacheDir = path.join(peachCacheDir(), 'swift-standins')
80
83
  export interface SwiftStandin {
@@ -2175,7 +2178,7 @@ async function cxxStandin(
2175
2178
  }
2176
2179
  }
2177
2180
 
2178
- export const RUST_TARGET = 'wasm32-wasip1'
2181
+ export const RUST_TARGET = 'wasm64-wasip1'
2179
2182
  // directories a crate search never enters: build output and installed deps
2180
2183
  const UNSEARCHED = new Set([
2181
2184
  'node_modules',
@@ -2233,9 +2236,7 @@ export function crateFor(root: string, name: string): string | null {
2233
2236
  */
2234
2237
  export const RUST_TOOLCHAIN = '1.94.0'
2235
2238
 
2236
- // the directories a crate's build reads: the workspace that owns its Cargo.lock
2237
- // plus every path dependency that lies outside it.
2238
- function crateSourceRoots(manifest: string): string[] {
2239
+ function crateWorkspace(manifest: string): string {
2239
2240
  let workspace = path.dirname(manifest)
2240
2241
  while (!fs.existsSync(path.join(workspace, 'Cargo.lock'))) {
2241
2242
  const parent = path.dirname(workspace)
@@ -2243,7 +2244,15 @@ function crateSourceRoots(manifest: string): string[] {
2243
2244
  throw new Error(`${manifest} has no Cargo.lock; the build runs --locked`)
2244
2245
  workspace = parent
2245
2246
  }
2246
- const roots = [workspace]
2247
+ return workspace
2248
+ }
2249
+
2250
+ function crateSourceRoots(manifest: string, searchRoot: string): string[] {
2251
+ const workspace = crateWorkspace(manifest)
2252
+ const root = path.resolve(searchRoot)
2253
+ const roots = path.relative(root, workspace).startsWith('..')
2254
+ ? [root, workspace]
2255
+ : [root]
2247
2256
  const inside = (dir: string) =>
2248
2257
  roots.some((root) => !path.relative(root, dir).startsWith('..'))
2249
2258
  const manifests = (dir: string): string[] =>
@@ -2269,7 +2278,7 @@ function crateSourceRoots(manifest: string): string[] {
2269
2278
 
2270
2279
  // a digest of every file under the roots a crate builds from, build output and
2271
2280
  // installed dependencies aside.
2272
- function crateSourceDigest(manifest: string): string {
2281
+ function crateSourceDigest(manifest: string, searchRoot: string): string {
2273
2282
  const hash = createHash('sha256')
2274
2283
  const walk = (dir: string, root: string) => {
2275
2284
  for (const entry of fs
@@ -2285,7 +2294,7 @@ function crateSourceDigest(manifest: string): string {
2285
2294
  }
2286
2295
  }
2287
2296
  }
2288
- for (const root of crateSourceRoots(manifest)) {
2297
+ for (const root of crateSourceRoots(manifest, searchRoot)) {
2289
2298
  hash.update(`root\0`)
2290
2299
  walk(root, root)
2291
2300
  }
@@ -2293,14 +2302,20 @@ function crateSourceDigest(manifest: string): string {
2293
2302
  }
2294
2303
 
2295
2304
  /** the registry entry a crate's static library lives under. */
2296
- export function rustCrateEntry(manifest: string, library: string) {
2305
+ export function rustCrateEntry(
2306
+ manifest: string,
2307
+ library: string,
2308
+ moduleRoot: string,
2309
+ searchRoot: string,
2310
+ ) {
2297
2311
  const inputs = {
2298
2312
  crate: library,
2299
- source: crateSourceDigest(manifest),
2313
+ source: crateSourceDigest(manifest, searchRoot),
2300
2314
  target: RUST_TARGET,
2301
- build: 'release locked',
2315
+ build: 'release locked panic=abort',
2316
+ compiler: swiftModuleToolchain(moduleRoot).release,
2317
+ sdk: swiftModuleSdk(moduleRoot).wasmSdkChecksum,
2302
2318
  rust: RUST_TOOLCHAIN,
2303
- rustflags: process.env.RUSTFLAGS ?? '',
2304
2319
  }
2305
2320
  return { name: library, inputs, key: nativeEntryKey(inputs) }
2306
2321
  }
@@ -2308,7 +2323,7 @@ export function rustCrateEntry(manifest: string, library: string) {
2308
2323
  /**
2309
2324
  * the WebAssembly static library a c stand-in links in place of its traps,
2310
2325
  * or null when it has none. a build the developer supplies in the
2311
- * xcframework (`wasm32-wasip1/lib<name>.a`) wins; otherwise the crate under
2326
+ * xcframework (`wasm64-wasip1/lib<name>.a`) wins; otherwise the crate under
2312
2327
  * `searchRoot` that builds the slice's library comes from the registry when
2313
2328
  * it holds that crate's source and toolchain, else compiles with the
2314
2329
  * developer's cargo with the registry's pinned toolchain. peach ships no rust compiler.
@@ -2353,10 +2368,11 @@ export function standinLibrary(
2353
2368
  }
2354
2369
  const manifest = crateFor(searchRoot, path.basename(library, '.a').replace(/^lib/, ''))
2355
2370
  if (!manifest) return null
2356
- const entry = rustCrateEntry(manifest, library)
2371
+ if (!toolchain) throw new Error('Rust native libraries need the Swift SDK')
2372
+ const entry = rustCrateEntry(manifest, library, toolchain.moduleRoot, searchRoot)
2357
2373
  const prebuilt = fetchNativeEntry('rust', entry.name, entry.key)
2358
2374
  if (prebuilt) return path.join(prebuilt, library)
2359
- return buildRustCrate(manifest, library, searchRoot)
2375
+ return buildRustCrate(manifest, library, searchRoot, toolchain.moduleRoot, entry)
2360
2376
  }
2361
2377
 
2362
2378
  /** compiles a crate with the same rust standard library as registry archives. */
@@ -2364,87 +2380,95 @@ export function buildRustCrate(
2364
2380
  manifest: string,
2365
2381
  library: string,
2366
2382
  searchRoot: string,
2383
+ moduleRoot: string,
2384
+ entry = rustCrateEntry(manifest, library, moduleRoot, searchRoot),
2367
2385
  ): string {
2368
- const crate = path.relative(searchRoot, path.dirname(manifest))
2369
- // rustup installs the pinned toolchain and its wasm target, and is a no-op
2370
- // when both are present. a cargo without rustup has to carry them itself.
2371
- const rustup = spawnSync(
2372
- // runner-toolchain-platform: darwin
2373
- 'rustup',
2374
- [
2375
- 'toolchain',
2376
- 'install',
2377
- RUST_TOOLCHAIN,
2378
- '--profile',
2379
- 'minimal',
2380
- '--target',
2381
- RUST_TARGET,
2382
- '--no-self-update',
2383
- ],
2384
- { encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] },
2385
- )
2386
- if (!rustup.error && rustup.status !== 0)
2387
- throw new Error(
2388
- `rustup could not install Rust ${RUST_TOOLCHAIN} with ${RUST_TARGET} for ${crate}: ${failure(rustup)}`,
2386
+ const compiler = swiftModuleToolchain(moduleRoot)
2387
+ const sdk = swiftModuleSdk(moduleRoot)
2388
+ const sdkRoot = path.dirname(swiftSdkPaths(moduleRoot, compiler.toolchainBin).sysroot)
2389
+ const runner = path.join(sdkRoot, 'rust/scripts/build-rust-wasm64.mjs')
2390
+ const work = path.join(cacheDir, 'rust', entry.key)
2391
+ const release = tryAcquireNumberedLock(work + '.lock', manifest)
2392
+ if (!release) throw new Error('Rust native build already running: ' + manifest)
2393
+ try {
2394
+ const roots = crateSourceRoots(manifest, searchRoot)
2395
+ let common = roots[0]!
2396
+ while (
2397
+ roots.some((root) => {
2398
+ const relative = path.relative(common, root)
2399
+ return relative === '..' || relative.startsWith('..' + path.sep)
2400
+ })
2389
2401
  )
2390
- const result = spawnSync(
2391
- // runner-toolchain-platform: darwin
2392
- 'cargo',
2393
- [
2394
- 'build',
2395
- '--release',
2396
- '--locked',
2397
- '--target',
2398
- RUST_TARGET,
2399
- '--message-format=json-render-diagnostics',
2400
- '--manifest-path',
2401
- manifest,
2402
- '--target-dir',
2403
- path.join(cacheDir, 'cargo', key(manifest)),
2404
- ],
2405
- {
2406
- encoding: 'utf8',
2407
- env: {
2408
- ...process.env,
2409
- RUSTUP_TOOLCHAIN: RUST_TOOLCHAIN,
2410
- CARGO_HOME: path.join(cacheDir, 'cargo-home'),
2411
- },
2412
- maxBuffer: 256 * 1024 * 1024,
2413
- stdio: ['ignore', 'pipe', 'pipe'],
2414
- },
2415
- )
2416
- if (result.error)
2417
- throw new Error(
2418
- `${crate} is a rust crate and cargo is not installed; install rust (https://rustup.rs), then run again`,
2402
+ common = path.dirname(common)
2403
+ const source = path.join(work, 'source')
2404
+ fs.rmSync(source, { recursive: true, force: true })
2405
+ for (const root of roots)
2406
+ fs.cpSync(root, path.join(source, path.relative(common, root)), {
2407
+ recursive: true,
2408
+ filter: (file) => !UNSEARCHED.has(path.basename(file)),
2409
+ })
2410
+ const privateManifest = path.join(source, path.relative(common, manifest))
2411
+ const lock = path.join(
2412
+ source,
2413
+ path.relative(common, crateWorkspace(manifest)),
2414
+ 'Cargo.lock',
2419
2415
  )
2420
- if (result.status !== 0) {
2421
- if (
2422
- /target may not be installed|can't find crate for `(core|std)`/.test(result.stderr)
2416
+ const result = spawnSync(
2417
+ process.execPath,
2418
+ [
2419
+ runner,
2420
+ '--bin',
2421
+ compiler.toolchainBin,
2422
+ '--sdk',
2423
+ sdkRoot,
2424
+ '--sdk-checksum',
2425
+ sdk.wasmSdkChecksum,
2426
+ '--work',
2427
+ path.join(work, 'toolchain'),
2428
+ '--manifest',
2429
+ privateManifest,
2430
+ '--lock',
2431
+ lock,
2432
+ '--panic',
2433
+ 'abort',
2434
+ '--cargo-arg=--locked',
2435
+ '--cargo-arg=--jobs',
2436
+ '--cargo-arg=' + (process.env.TM_EXEC_CPU_CORES ?? '1'),
2437
+ ],
2438
+ {
2439
+ encoding: 'utf8',
2440
+ env: { ...swiftEnvironment(), [PEACH_FORKED_SCRIPT_ENV]: '1' },
2441
+ maxBuffer: 256 * 1024 * 1024,
2442
+ stdio: ['ignore', 'pipe', 'pipe'],
2443
+ },
2423
2444
  )
2445
+ if (result.error) throw result.error
2446
+ if (result.status !== 0)
2424
2447
  throw new Error(
2425
- `${crate} builds for ${RUST_TARGET}, which Rust ${RUST_TOOLCHAIN} lacks; run \`rustup target add --toolchain ${RUST_TOOLCHAIN} ${RUST_TARGET}\`, then run again`,
2448
+ `Rust wasm64 could not build ${path.relative(searchRoot, manifest)}: ${failure(result)}`,
2449
+ )
2450
+ for (const line of result.stdout.split('\n')) {
2451
+ if (!line.startsWith('{')) continue
2452
+ const message: unknown = JSON.parse(line)
2453
+ if (
2454
+ !message ||
2455
+ typeof message !== 'object' ||
2456
+ !('filenames' in message) ||
2457
+ !Array.isArray(message.filenames)
2426
2458
  )
2459
+ continue
2460
+ const archive = message.filenames.find(
2461
+ (file): file is string =>
2462
+ typeof file === 'string' && path.basename(file) === library,
2463
+ )
2464
+ if (archive) return archive
2465
+ }
2427
2466
  throw new Error(
2428
- `cargo could not build ${crate} for ${RUST_TARGET}: ${failure(result)}`,
2467
+ `cargo built ${manifest} for ${RUST_TARGET} but reported no ${library}`,
2429
2468
  )
2469
+ } finally {
2470
+ release()
2430
2471
  }
2431
- for (const line of result.stdout.split('\n')) {
2432
- if (!line.startsWith('{')) continue
2433
- const message: unknown = JSON.parse(line)
2434
- if (
2435
- !message ||
2436
- typeof message !== 'object' ||
2437
- !('filenames' in message) ||
2438
- !Array.isArray(message.filenames)
2439
- )
2440
- continue
2441
- const archive = message.filenames.find(
2442
- (file): file is string =>
2443
- typeof file === 'string' && path.basename(file) === library,
2444
- )
2445
- if (archive) return archive
2446
- }
2447
- throw new Error(`cargo built ${crate} for ${RUST_TARGET} but reported no ${library}`)
2448
2472
  }
2449
2473
 
2450
2474
  // source preflight admits the complete closure once, including ignored local
@@ -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',