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
@@ -6,6 +6,7 @@ import {
6
6
  } from 'node:child_process'
7
7
  import { createHash, randomUUID } from 'node:crypto'
8
8
  import {
9
+ chmodSync,
9
10
  copyFileSync,
10
11
  cpSync,
11
12
  existsSync,
@@ -48,6 +49,7 @@ import {
48
49
  } from './swift-distribution-contract'
49
50
  import { foundationCategoryObjects } from './swift-foundation'
50
51
  import { compileGuestLink } from './swift-guest-compile'
52
+ import { CLANG_TARGET_MODULE_WRAPPER } from './swift-guest-source-inputs'
51
53
  import {
52
54
  brotliCompressQ11,
53
55
  brotliCompressQ4,
@@ -140,7 +142,7 @@ import {
140
142
  SWIFT_FRAMEWORK_PRODUCT_FILE,
141
143
  swiftFrameworkProductSchema,
142
144
  } from './swiftRuntimeProductContract'
143
- import { KEEP_WASM_NAMES, optimizeWasm, WASM_OPTIMIZE_IDENTITY } from './wasm-optimize'
145
+ import { KEEP_WASM_NAMES, lowerWasm, WASM_LOWER_IDENTITY } from './wasm-optimize'
144
146
  import { writeBuildFile } from './write-build-file'
145
147
  import { writeXcodeHeaderSearch } from './xcode-header-search'
146
148
  import type { SwiftImageUpload } from './swift-submit'
@@ -263,7 +265,7 @@ async function runCompiler(
263
265
  }
264
266
  }
265
267
 
266
- export const WASM_TRIPLE = 'wasm32-unknown-wasip1'
268
+ export const WASM_TRIPLE = 'wasm64-unknown-wasip1'
267
269
 
268
270
  // swiftpm's step counter, echoed while a build runs; its diagnostics print
269
271
  // once, with the failure.
@@ -933,7 +935,7 @@ const kleeneOr = (
933
935
  : undefined
934
936
 
935
937
  // a compilation condition as the wasm compile sees it after the source
936
- // rewrite below: `os(iOS)` and `os(WASI)` hold, other platforms do not,
938
+ // rewrite below: `os(iOS)` holds, other platforms (WASI too) do not,
937
939
  // `canImport` holds for an available module. what the scan cannot know
938
940
  // (custom flags, swift versions, features) is undefined, three-valued
939
941
  // through `!`, `&&` and `||`.
@@ -956,10 +958,11 @@ function swiftCondition(
956
958
  const call = /^(\w+)\s*\(\s*([^,()]*?)\s*(?:,[^()]*)?\)$/.exec(token ?? '')
957
959
  if (!call) return undefined
958
960
  const [, name, argument] = call
959
- if (name === 'os') return argument === 'iOS' || argument === 'WASI'
960
- if (name === 'canImport') return available?.has(argument!)
961
+ if (name === 'os') return argument === 'iOS'
962
+ if (name === 'canImport')
963
+ return argument !== 'FoundationNetworking' && available?.has(argument!)
961
964
  if (name === 'targetEnvironment') return argument === 'simulator'
962
- if (name === 'arch') return argument === 'wasm32'
965
+ if (name === 'arch') return argument === 'wasm64'
963
966
  return undefined
964
967
  }
965
968
  const both = (): boolean | undefined => {
@@ -1103,7 +1106,7 @@ export function swiftSdkPaths(
1103
1106
  ...options,
1104
1107
  '--show-configuration',
1105
1108
  sdk,
1106
- 'wasm32-unknown-wasip1',
1109
+ 'wasm64-unknown-wasip1',
1107
1110
  ],
1108
1111
  { encoding: 'utf8', env: swiftEnvironment(), stdio: ['ignore', 'pipe', 'pipe'] },
1109
1112
  )
@@ -1636,6 +1639,19 @@ export const FOUNDATION_IMPLICIT_MODULES = [
1636
1639
  'PeachFoundationCombine',
1637
1640
  'Darwin',
1638
1641
  ]
1642
+ // darwin's Foundation is one module, so `@preconcurrency import Foundation`
1643
+ // (or of UIKit or SwiftUI, which re-export it) relaxes Sendable checking for
1644
+ // everything it exports. Peach splits that surface across ObjectiveC and the
1645
+ // implicit modules, and swift credits a type's import attributes to a direct
1646
+ // import of its own module before the first re-exporting import, which is
1647
+ // always an implicit one. naming each split module under the same attribute
1648
+ // gives the darwin result; the guard keeps host-built macro sources intact.
1649
+ const PRECONCURRENCY_FOUNDATION_IMPORT =
1650
+ /^[ \t]*@preconcurrency[ \t]+(?:(?:public|package|internal|fileprivate|private)[ \t]+)?import[ \t]+(?:Foundation|UIKit|SwiftUI)[ \t]*(?:\/\/.*)?$/m
1651
+ export function withPreconcurrencyFoundationModules(source: string): string {
1652
+ if (!PRECONCURRENCY_FOUNDATION_IMPORT.test(source)) return source
1653
+ return `${source}${source.endsWith('\n') ? '' : '\n'}#if canImport(PeachObjC)\n${['ObjectiveC', ...FOUNDATION_IMPLICIT_MODULES].map((module) => `@preconcurrency import ${module}\n`).join('')}#endif\n`
1654
+ }
1639
1655
  const FOUNDATION_IMPLICIT_FLAGS = FOUNDATION_IMPLICIT_MODULES.map(
1640
1656
  (module) => `, "-Xfrontend", "-import-module", "-Xfrontend", "${module}"`,
1641
1657
  ).join('')
@@ -1689,7 +1705,8 @@ export function swiftArtifactHash(
1689
1705
  if (input.oneModule) hash.update('one-module\n')
1690
1706
  if (KEEP_WASM_NAMES) hash.update('names\n')
1691
1707
  hash.update(swiftModuleDigest(moduleRoot))
1692
- if (input.optimize) hash.update(`optimize\n${WASM_OPTIMIZE_IDENTITY}\n`)
1708
+ hash.update(`lower\n${WASM_LOWER_IDENTITY}\n`)
1709
+ if (input.optimize) hash.update('optimize\n')
1693
1710
  for (const file of Object.keys(input.files).sort()) {
1694
1711
  hash.update(createHash('sha256').update(file).digest())
1695
1712
  hash.update(createHash('sha256').update(input.files[file]).digest())
@@ -1855,6 +1872,10 @@ function toolsetOrdersLibcxxBeforeDarwinOverlay(options: readonly string[]): boo
1855
1872
  return libcxx >= 0 && overlay > libcxx
1856
1873
  }
1857
1874
 
1875
+ // the iOS minimum swiftpm gives a package that declares no iOS platform
1876
+ // (swift-package-manager PackageModel Platform.iOS oldestSupportedVersion).
1877
+ const SWIFTPM_DEFAULT_IOS_DEPLOYMENT_TARGET = '12.0'
1878
+
1858
1879
  export function emitSwiftPackageManifest(args: {
1859
1880
  /** the build root holding the linker each executable links with. */
1860
1881
  root: string
@@ -2230,7 +2251,8 @@ export function emitSwiftPackageManifest(args: {
2230
2251
  ? `, "-emit-objc-header-path", ${JSON.stringify(path.join(args.headerDirectory, `${target.name}-Swift${args.nativeHeaderDeclarations?.[target.name] ? '.original' : ''}.h`))}`
2231
2252
  : ''
2232
2253
  const clangMode = target.cxxInterop ? '' : ', "-Xcc", "-fno-cxx-modules"'
2233
- const swiftSettings = `swiftSettings: [.swiftLanguageMode(.v${target.languageMode}),${isolation}${interoperability}${defines}${features}${upcoming} .unsafeFlags(${swiftFlagArray(`["-Osize", "-Xfrontend", "-enable-cross-import-overlays"${overlayFlags}${FOUNDATION_IMPLICIT_FLAGS}${oneModule ? ONE_IMPLICIT_FLAGS : ''}${imports}${nativeImportFlags}${objcFlags}${header}${clangMode}${upstream}]`)})]`
2254
+ const deployment = `, "-Xfrontend", "-peach-ios-deployment-target", "-Xfrontend", ${JSON.stringify(target.iosDeploymentTarget ?? SWIFTPM_DEFAULT_IOS_DEPLOYMENT_TARGET)}`
2255
+ const swiftSettings = `swiftSettings: [.swiftLanguageMode(.v${target.languageMode}),${isolation}${interoperability}${defines}${features}${upcoming} .unsafeFlags(${swiftFlagArray(`["-Osize", "-Xfrontend", "-enable-cross-import-overlays"${overlayFlags}${FOUNDATION_IMPLICIT_FLAGS}${oneModule ? ONE_IMPLICIT_FLAGS : ''}${imports}${nativeImportFlags}${objcFlags}${header}${clangMode}${deployment}${upstream}]`)})]`
2234
2256
  const deps = [
2235
2257
  ...new Set([
2236
2258
  ...(target.dependencies ?? []).flatMap((dependency) =>
@@ -2500,12 +2522,16 @@ export function syncSwiftTree(base: string, files: Map<string, string | Buffer>)
2500
2522
  // every iOS branch of the app would compile out. peach is the iOS simulator,
2501
2523
  // so `targetEnvironment(simulator)` holds too. a condition line names iOS
2502
2524
  // as `true` padded to the same length, so diagnostics keep their columns;
2503
- // os(WASI) still holds for code written for wasm. only `#if` and `#elseif`
2504
- // lines that begin in code change: a line inside a string literal or a block
2505
- // comment is content. the artifact hash stays over the original text.
2525
+ // `os(WASI)` is `false` the same way, as on iOS, so a package takes the
2526
+ // branch its iOS app runs. only `#if` and `#elseif` lines that begin in code
2527
+ // change: a line inside a string literal or a block comment is content. the
2528
+ // artifact hash stays over the original text.
2506
2529
  // objective-c syntax is compiled unchanged by the native importer.
2507
2530
  const DIRECTIVE = /^[ \t]*#(?:if|elseif)\b/
2508
2531
  const OS_IOS = /\b(?:os\(\s*iOS\s*\)|targetEnvironment\(\s*simulator\s*\))/g
2532
+ // iOS has no FoundationNetworking module; Peach's is imported implicitly
2533
+ // and gated packages must take their Apple branch
2534
+ const NOT_ON_IOS = /\b(?:os\(\s*WASI\s*\)|canImport\(\s*FoundationNetworking\s*\))/g
2509
2535
  // uikit makes app and scene delegates from their class through the objc
2510
2536
  // runtime; here their protocols require init(), which a non-final class
2511
2537
  // meets only with a required one. a class declaring one of them that is
@@ -2532,19 +2558,17 @@ function compiledSwiftSources(
2532
2558
  )
2533
2559
  })
2534
2560
  const manifest = /(?:^|\/)Package(?:@swift-[\d.]+)?\.swift$/.test(file)
2535
- return [
2536
- file,
2537
- manifest && (!owner || /^Package(?:@swift-[\d.]+)?\.swift$/.test(file))
2538
- ? source
2539
- : swiftSourceAsIOS(
2540
- source,
2541
- overlayFrameworks,
2542
- owner?.defines?.includes(SWIFT_XCODE_BUILD_CONDITION) &&
2543
- !owner.defines.includes('SWIFT_PACKAGE')
2544
- ? false
2545
- : undefined,
2546
- ),
2547
- ]
2561
+ if (manifest && (!owner || /^Package(?:@swift-[\d.]+)?\.swift$/.test(file)))
2562
+ return [file, source]
2563
+ const ios = swiftSourceAsIOS(
2564
+ source,
2565
+ overlayFrameworks,
2566
+ owner?.defines?.includes(SWIFT_XCODE_BUILD_CONDITION) &&
2567
+ !owner.defines.includes('SWIFT_PACKAGE')
2568
+ ? false
2569
+ : undefined,
2570
+ )
2571
+ return [file, withPreconcurrencyFoundationModules(ios)]
2548
2572
  }),
2549
2573
  )
2550
2574
  }
@@ -3251,21 +3275,26 @@ export function foundationOwnerOf(name: string): string | undefined {
3251
3275
  return undefined
3252
3276
  }
3253
3277
 
3254
- export function swiftSourceAsIOS(
3278
+ // dependency sources take the same platform branches as app sources
3279
+ function swiftPackageSourceAsIOS(source: string): string {
3280
+ return swiftConditionsAsIOS(source, swiftCodeScan(source).lineStarts)
3281
+ }
3282
+
3283
+ function swiftConditionsAsIOS(
3255
3284
  source: string,
3256
- overlayFrameworks: () => ReadonlySet<string>,
3285
+ lineStarts: ReadonlySet<number>,
3257
3286
  swiftPackage?: boolean,
3258
3287
  ): string {
3259
- const { lineStarts, tokens } = swiftCodeScan(source)
3260
3288
  let offset = 0
3261
- // equal width, so every token offset still holds
3262
- const conditioned = source
3289
+ return source
3263
3290
  .split('\n')
3264
3291
  .map((line) => {
3265
3292
  const start = offset
3266
3293
  offset += line.length + 1
3267
3294
  if (!lineStarts.has(start) || !DIRECTIVE.test(line)) return line
3268
- const platform = line.replace(OS_IOS, (match) => 'true'.padEnd(match.length))
3295
+ const platform = line
3296
+ .replace(OS_IOS, (match) => 'true'.padEnd(match.length))
3297
+ .replace(NOT_ON_IOS, (match) => 'false'.padEnd(match.length))
3269
3298
  // SwiftPM is the backend for Xcode targets, whose original conditions
3270
3299
  // do not include its automatically injected SWIFT_PACKAGE definition.
3271
3300
  return swiftPackage === false
@@ -3273,6 +3302,16 @@ export function swiftSourceAsIOS(
3273
3302
  : platform
3274
3303
  })
3275
3304
  .join('\n')
3305
+ }
3306
+
3307
+ export function swiftSourceAsIOS(
3308
+ source: string,
3309
+ overlayFrameworks: () => ReadonlySet<string>,
3310
+ swiftPackage?: boolean,
3311
+ ): string {
3312
+ const { lineStarts, tokens } = swiftCodeScan(source)
3313
+ // equal width, so every token offset still holds
3314
+ const conditioned = swiftConditionsAsIOS(source, lineStarts, swiftPackage)
3276
3315
  let out = ''
3277
3316
  let copied = 0
3278
3317
  const sceneLifecycleBodies = new Set<number>()
@@ -3859,7 +3898,7 @@ function stripCCode(source: string): string {
3859
3898
  return code
3860
3899
  }
3861
3900
 
3862
- // whether the unit's code under wasm32 takes its own return address, which
3901
+ // whether the unit's wasm code takes its own return address, which
3863
3902
  // the WebAssembly backend rejects ("hasn't implemented __builtin_return_address"):
3864
3903
  // native machine code the target has no lowering for, like assembly. branches
3865
3904
  // the native architecture macros guard are not wasm code.
@@ -3867,7 +3906,7 @@ const wasmMacroEnvironment: SwiftCMacroEnvironment = {
3867
3906
  ...emptyMacroEnvironment,
3868
3907
  defines: new Map([
3869
3908
  ['__wasm__', '1'],
3870
- ['__wasm32__', '1'],
3909
+ ['__wasm64__', '1'],
3871
3910
  ['__wasi__', '1'],
3872
3911
  ]),
3873
3912
  }
@@ -5883,8 +5922,17 @@ export function writeSwiftProject(
5883
5922
  }) + moduleFiles,
5884
5923
  )
5885
5924
  }
5886
- for (const [file, bytes] of Object.entries(input.packageFiles ?? {}))
5887
- files.set(path.join(layout.root, file), Buffer.from(bytes, 'base64'))
5925
+ for (const [file, bytes] of Object.entries(input.packageFiles ?? {})) {
5926
+ const contents = Buffer.from(bytes, 'base64')
5927
+ files.set(
5928
+ path.join(layout.root, file),
5929
+ file.endsWith('.swift') && !/(?:^|\/)Package(?:@swift-[\d.]+)?\.swift$/.test(file)
5930
+ ? withPreconcurrencyFoundationModules(
5931
+ swiftPackageSourceAsIOS(contents.toString('utf8')),
5932
+ )
5933
+ : contents,
5934
+ )
5935
+ }
5888
5936
  for (const [file, bytes] of Object.entries(input.projectFiles ?? {})) {
5889
5937
  const destination = path.join(layout.root, file)
5890
5938
  if (files.has(destination)) continue
@@ -5904,15 +5952,43 @@ export function writeSwiftProject(
5904
5952
  ]
5905
5953
  : []),
5906
5954
  ]
5955
+ // swiftpm compiles a package's C and Objective-C targets with -fmodules
5956
+ // and -fmodule-name=<target> only on darwin triples, so `@import UIKit`
5957
+ // in an iOS package compiles natively and fails on wasm. the toolset
5958
+ // passes -fmodules; this names the target from the <target>.build
5959
+ // directory swiftpm writes its objects to, so a target's own headers stay
5960
+ // textual as on darwin.
5961
+ const clangWrapper = path.join(layout.root, CLANG_TARGET_MODULE_WRAPPER)
5962
+ files.set(
5963
+ clangWrapper,
5964
+ [
5965
+ '#!/bin/sh',
5966
+ 'name=',
5967
+ 'prev=',
5968
+ 'for arg in "$@"; do',
5969
+ ' if [ "$prev" = -o ]; then name=${arg%/*}; name=${name##*/}; fi',
5970
+ ' prev=$arg',
5971
+ 'done',
5972
+ 'case $name in',
5973
+ ` *.build) exec '${path.join(nativeToolchain(), 'clang')}' "-fmodule-name=\${name%.build}" "$@" ;;`,
5974
+ ` *) exec '${path.join(nativeToolchain(), 'clang')}' "$@" ;;`,
5975
+ 'esac',
5976
+ '',
5977
+ ].join('\n'),
5978
+ )
5907
5979
  files.set(
5908
5980
  path.join(layout.root, '.peach-target-toolset.json'),
5909
5981
  JSON.stringify({
5910
5982
  schemaVersion: '1.0',
5983
+ cCompiler: {
5984
+ extraCLIOptions: [
5985
+ ...nativeToolsetFlags,
5986
+ '-fmodules',
5987
+ `-fmodules-cache-path=${path.join(layout.root, '.build', 'ModuleCache')}`,
5988
+ ],
5989
+ },
5911
5990
  ...(nativeToolsetFlags.length > 0
5912
- ? {
5913
- cCompiler: { extraCLIOptions: nativeToolsetFlags },
5914
- cxxCompiler: { extraCLIOptions: nativeToolsetFlags },
5915
- }
5991
+ ? { cxxCompiler: { extraCLIOptions: nativeToolsetFlags } }
5916
5992
  : {}),
5917
5993
  swiftCompiler: {
5918
5994
  extraCLIOptions: [
@@ -6004,6 +6080,8 @@ export function writeSwiftProject(
6004
6080
  '// dependency targets emit their native compatibility headers.\n',
6005
6081
  )
6006
6082
  syncSwiftTree(layout.root, files)
6083
+ const clangWrapper = path.join(layout.root, CLANG_TARGET_MODULE_WRAPPER)
6084
+ if (files.has(clangWrapper)) chmodSync(clangWrapper, 0o755)
6007
6085
  // header-consuming units have moved downstream. only the emitted target
6008
6086
  // graph describes which producer builds already emit another header.
6009
6087
  const dependencies = new Map(
@@ -6619,6 +6697,9 @@ async function buildFrameworkProducts(
6619
6697
  'release',
6620
6698
  '-Xswiftc',
6621
6699
  '-Osize',
6700
+ // the release link strips all debug info, so none is generated
6701
+ '-Xswiftc',
6702
+ '-gnone',
6622
6703
  '-Xswiftc',
6623
6704
  '-num-threads',
6624
6705
  '-Xswiftc',
@@ -7262,14 +7343,18 @@ function compileSwiftProjectOnce(
7262
7343
  const projectProcess = options.project
7263
7344
  ? prepareSwiftProjectProcess(root, options.project)
7264
7345
  : undefined
7346
+ // the native build system takes its C compiler from CC, never a toolset
7347
+ const compiler: Record<string, string> = preparation.targetToolset
7348
+ ? { CC: path.join(root, CLANG_TARGET_MODULE_WRAPPER) }
7349
+ : {}
7265
7350
  const appOptions = projectProcess
7266
7351
  ? {
7267
7352
  ...buildOptions,
7268
7353
  uid: projectProcess.uid,
7269
7354
  gid: projectProcess.gid,
7270
- confined: projectProcess.env,
7355
+ confined: { ...projectProcess.env, ...compiler },
7271
7356
  }
7272
- : buildOptions
7357
+ : { ...buildOptions, env: { ...buildOptions.env, ...compiler } }
7273
7358
  const unprepared = preparation.targetFailures.map(
7274
7359
  (failure) => `error: target ${failure}`,
7275
7360
  )
@@ -7306,6 +7391,9 @@ function compileSwiftProjectOnce(
7306
7391
  : []),
7307
7392
  '-c',
7308
7393
  'release',
7394
+ // the link strips debug info, so none is generated (as for the framework)
7395
+ '-Xswiftc',
7396
+ '-gnone',
7309
7397
  '-Xswiftc',
7310
7398
  '-num-threads',
7311
7399
  '-Xswiftc',
@@ -7522,16 +7610,15 @@ function compileSwiftProjectOnce(
7522
7610
  output,
7523
7611
  optimized,
7524
7612
  })
7525
- else if (input.optimize) await optimizeWasm(output, optimized)
7526
- const executable = input.optimize ? optimized : output
7613
+ else await lowerWasm(output, optimized, { optimize: input.optimize === true })
7527
7614
  await runCompiler(
7528
7615
  path.join(options.toolchainBin, 'llvm-objcopy'),
7529
- ['--remove-section=.swift1_autolink_entries', executable],
7616
+ ['--remove-section=.swift1_autolink_entries', optimized],
7530
7617
  buildOptions,
7531
7618
  )
7532
7619
  const artifact = {
7533
7620
  hash,
7534
- bytes: readFileSync(executable),
7621
+ bytes: readFileSync(optimized),
7535
7622
  icu: await icu,
7536
7623
  }
7537
7624
  if (artifact.bytes.length <= 8)
@@ -21,6 +21,8 @@ export const SWIFT_DIGEST_SOURCES = [
21
21
  'process-table.ts',
22
22
  'swift-link-roots.ts',
23
23
  'swift-wasm-prune.ts',
24
+ 'wasm-optimize.ts',
25
+ 'wasm-narrow-boundary.ts',
24
26
  'swift-guest-image-ledger.ts',
25
27
  'swift-guest-archive.ts',
26
28
  'swift-guest-link-plan.ts',
@@ -120,7 +120,7 @@ export async function emitCxxStandin(input: CxxInputs): Promise<{
120
120
  )
121
121
  const flags = [
122
122
  '-target',
123
- 'wasm32-unknown-wasip1',
123
+ 'wasm64-unknown-wasip1',
124
124
  '--sysroot',
125
125
  input.sysroot,
126
126
  ...WASI_EMULATION_FLAGS,
@@ -1,6 +1,6 @@
1
1
  // the darwin record providers (packages/sootsim-swift/Sources/DarwinRecords)
2
- // compiled for wasm32. they answer darwin's calls over the installed libc, so
3
- // they compile in its view, with the records' shared sdk tree. the wasm sdk
2
+ // compiled for wasm64. they answer darwin's calls over the installed libc,
3
+ // sysctl uses the client records; libc adapters retain the installed view. the sdk
4
4
  // ships them as libDarwinRecords.a for its own clients; a distribution and a
5
5
  // source checkout compile them from the same source as their Darwin module and
6
6
  // link them ahead of that archive (specs/peach/swift/darwin-libc-providers.md).
@@ -51,7 +51,7 @@ export function compileDarwinRecords(args: {
51
51
  execFileSync(
52
52
  path.join(args.bin, 'clang'),
53
53
  [
54
- '--target=wasm32-unknown-wasip1',
54
+ '--target=wasm64-unknown-wasip1',
55
55
  `--sysroot=${args.sysroot}`,
56
56
  '-Oz',
57
57
  '-g0',
@@ -64,7 +64,7 @@ export function compileDarwinRecords(args: {
64
64
  `-ffile-prefix-map=${records}${path.sep}=DarwinRecords/`,
65
65
  // apple's headers select on the ios identity original units compile
66
66
  // with, and TargetConditionals.h refuses a compiler without it
67
- ...(file.endsWith('.m')
67
+ ...(file === 'sysctl.c' || file.endsWith('.m')
68
68
  ? objcSdkIntakeFlags(args.darwin, args.bin, args.minimum)
69
69
  : [
70
70
  ...swiftObjCPlatformFlags(args.bin, args.minimum),
@@ -26,7 +26,7 @@ export function swiftDistributionHost(
26
26
  return SWIFT_DISTRIBUTION_HOSTS.find((candidate) => candidate === host) ?? null
27
27
  }
28
28
 
29
- /** the host-independent half: wasm32 modules and their objects. */
29
+ /** the host-independent half: wasm64 modules and their objects. */
30
30
  export interface SwiftDistributionWasm extends SwiftWasmSdk {
31
31
  /** the digest of the module sources it was built from (swiftModuleDigest). */
32
32
  id: string
@@ -34,7 +34,7 @@ export interface SwiftDistributionWasm extends SwiftWasmSdk {
34
34
  release: string
35
35
  /** the importable Swift modules under modules/. */
36
36
  modules: string[]
37
- /** the modules' wasm32 objects, relative to the root, in link order. */
37
+ /** the modules' wasm64 objects, relative to the root, in link order. */
38
38
  objects: string[]
39
39
  /** linker flags the objects autolink. */
40
40
  link: string[]
@@ -1,10 +1,10 @@
1
1
  {
2
- "id": "e7ae8fdb51086f73",
3
- "release": "swift-6.4.0-RELEASE-custom-11345d60dca47496",
4
- "wasmSdkId": "swift-6.4.0-RELEASE_wasm-peach-19471d4b",
5
- "wasmSdkUrl": "https://r2.sootsim.com/swift-wasm-sdk/swift-6.4.0-RELEASE_wasm-peach-19471d4b.artifactbundle.tar.gz",
6
- "wasmSdkChecksum": "764c16e7e34156bf90d6c3372a2b77b98b9d8c3470235520d0f9619f90f33456",
7
- "source": "dbcdd2998c7a523cb5136f3731f6850cfe0bd154",
2
+ "id": "c7825880e72c77d4",
3
+ "release": "swift-6.4.0-RELEASE-custom-fb42d2535739dfd2",
4
+ "wasmSdkId": "swift-6.4.0-RELEASE_wasm-peach-b577231e",
5
+ "wasmSdkUrl": "https://r2.sootsim.com/swift-wasm-sdk/swift-6.4.0-RELEASE_wasm-peach-b577231e.artifactbundle.tar.gz",
6
+ "wasmSdkChecksum": "9a8f0c694ada318ede49413cd72395e34a7fbb1b9a227b31eff8b05371ffb9aa",
7
+ "source": "071342e8371d62d839b1acf0b4462235ed263eae",
8
8
  "targets": [
9
9
  "ImagePlayground",
10
10
  "QuickLookThumbnailing",
@@ -216,6 +216,7 @@
216
216
  "deviceModel": ["string"],
217
217
  "systemName": ["string"],
218
218
  "systemVersion": ["string"],
219
+ "gameCenterPlayerIDs": ["array"],
219
220
  "screenMetrics": ["array"],
220
221
  "reservedRegions": ["array"],
221
222
  "colorScheme": ["string:light", "string:dark"],
@@ -244,16 +245,16 @@
244
245
  },
245
246
  "hosts": {
246
247
  "darwin-arm64": {
247
- "sha256": "8680805789e5212d83e374bea9e4af3e3c7a86011e8ebf4921e76a8eba092761",
248
- "size": 103496854
248
+ "sha256": "f932303a90b0119e4500f2569ed6b6c519430d7fddad998d8555d92493d0f30a",
249
+ "size": 104821966
249
250
  },
250
251
  "linux-x64": {
251
- "sha256": "9d82820dfdbc857d5127c489b9c704c9e9336fe8b010256cd5b1d24ba956f454",
252
- "size": 106214710
252
+ "sha256": "aed1395ab7cc4c464b2e32fa21096b85f343a9001cdb72e714444f54a5b6f91a",
253
+ "size": 107541215
253
254
  },
254
255
  "linux-arm64": {
255
- "sha256": "a8e5084e14867ca9245428e51cb9435bc5b34505914fa5855950951d01b6b990",
256
- "size": 105708986
256
+ "sha256": "c45ecac4feab55969b26bbf910258f49c1301552e9c523dd76a14dc7b221266e",
257
+ "size": 107034390
257
258
  }
258
259
  }
259
260
  }
@@ -32,7 +32,7 @@ import {
32
32
  planGuestSourceLink,
33
33
  } from './swift-guest-source-plan'
34
34
  import { frameworkRuntimeProductId } from './swift-runtime-products'
35
- import { optimizeWasm } from './wasm-optimize'
35
+ import { lowerWasm } from './wasm-optimize'
36
36
  import type { SwiftSourceLinkGraph } from './swiftContract'
37
37
  import type { SwiftGuestImageManifest } from './swiftGuestImageContract'
38
38
 
@@ -84,7 +84,7 @@ export async function compileGuestLink(options: {
84
84
  }
85
85
  const buildVersion = imageBuildVersion(entry.buildVersion)
86
86
  const clangOptions = [
87
- '--target=wasm32-unknown-wasip1',
87
+ '--target=wasm64-unknown-wasip1',
88
88
  `--sysroot=${options.sysroot}`,
89
89
  `-I${path.join(options.moduleRoot, 'include')}`,
90
90
  ]
@@ -437,9 +437,10 @@ export async function compileGuestLink(options: {
437
437
  },
438
438
  })
439
439
  if (!reserved || !projectionObject) throw new Error('guest projection was not reserved')
440
- await optimizeWasm(options.output, options.optimized, [
441
- 'duplicate-function-elimination',
442
- ])
440
+ await lowerWasm(options.output, options.optimized, {
441
+ optimize: true,
442
+ skipPasses: ['duplicate-function-elimination'],
443
+ })
443
444
  const map = readFileSync(result.mapPath, 'utf8')
444
445
  // no linked code reads the image records, so the link dropped them and
445
446
  // there is nothing to fill.
@@ -59,7 +59,7 @@ function readNumber(bytes: Uint8Array, position: number): [number, number] {
59
59
  let value = 0
60
60
  let shift = 0
61
61
  for (;;) {
62
- if (position >= bytes.length || shift > 28) throw new Error('invalid wasm integer')
62
+ if (position >= bytes.length || shift > 63) throw new Error('invalid wasm integer')
63
63
  const byte = bytes[position++]!
64
64
  value += (byte & 127) * 2 ** shift
65
65
  if (!(byte & 128)) return [value, position]
@@ -195,12 +195,12 @@ function rewriteObject(
195
195
  if (referenceType !== 0x70 && referenceType !== 0x6f)
196
196
  throw new Error('unsupported table type')
197
197
  const flags = number()
198
- if (flags & ~3) throw new Error('unsupported table limits')
198
+ if (flags & ~7) throw new Error('unsupported table limits')
199
199
  number()
200
200
  if (flags & 1) number()
201
201
  } else if (kind === 2) {
202
202
  const flags = number()
203
- if (flags & ~3) throw new Error('unsupported memory limits')
203
+ if (flags & ~7) throw new Error('unsupported memory limits')
204
204
  number()
205
205
  if (flags & 1) number()
206
206
  } else if (kind === 3) offset += 2
@@ -215,7 +215,7 @@ function rewriteObject(
215
215
  if (module === 'env' && names.has(name)) usedSymbols.add(name)
216
216
  if (isDlsym || isDlerror) {
217
217
  const type = types[functionType]
218
- const expected = isDlsym ? '127,127:127' : ':127'
218
+ const expected = isDlsym ? '126,126:126' : ':126'
219
219
  if (
220
220
  !type ||
221
221
  `${type.parameters.join(',')}:${type.results.join(',')}` !== expected
@@ -598,7 +598,7 @@ export function createGuestImageLedger(input: GuestImageLedgerInput): GuestImage
598
598
  })
599
599
  .join('')
600
600
  const ir = [
601
- 'target triple = "wasm32-unknown-wasip1"',
601
+ 'target triple = "wasm64-unknown-wasip1"',
602
602
  `@.names = private constant [${nameSize} x i8] c"${nameContents}"`,
603
603
  ]
604
604
  for (const definition of exported.values()) {
@@ -504,7 +504,7 @@ export function linkGuestImages(
504
504
  fs.writeFileSync(irPath, ledger.llvmIR)
505
505
  execFileSync(
506
506
  clang,
507
- ['--target=wasm32-unknown-wasip1', '-c', irPath, '-o', ledgerObject],
507
+ ['--target=wasm64-unknown-wasip1', '-c', irPath, '-o', ledgerObject],
508
508
  { stdio: 'pipe' },
509
509
  )
510
510
  linkedOwners.set(ledgerObject, options.ledgerDataImage)
@@ -29,6 +29,9 @@ function number(bytes: Uint8Array, start: number): [number, number] {
29
29
  }
30
30
  }
31
31
 
32
+ // the linked module places segments with i64.const and the lowered one with i32.const.
33
+ const constant = (opcode: number | undefined) => opcode === 0x41 || opcode === 0x42
34
+
32
35
  function signedAddress(bytes: Uint8Array, start: number): [number, number] {
33
36
  const [value, end] = number(bytes, start)
34
37
  const bits = (end - start) * 7
@@ -84,7 +87,7 @@ function layout(bytes: Uint8Array): WasmLayout {
84
87
  }
85
88
  const limits = () => {
86
89
  const flags = read()
87
- if (flags & ~3) throw new Error('unsupported wasm limits')
90
+ if (flags & ~7) throw new Error('unsupported wasm limits')
88
91
  const minimum = read()
89
92
  if (flags & 1) read()
90
93
  return minimum
@@ -123,7 +126,7 @@ function layout(bytes: Uint8Array): WasmLayout {
123
126
  if (read() !== 1 || memoryPages !== undefined)
124
127
  throw new Error('unsupported wasm memories')
125
128
  const flags = read()
126
- if (flags & ~3) throw new Error('unsupported wasm memory limits')
129
+ if (flags & ~7) throw new Error('unsupported wasm memory limits')
127
130
  memoryPages = read()
128
131
  if (flags & 1) read()
129
132
  if (pos !== memory[1]) throw new Error('invalid wasm memory section')
@@ -160,7 +163,7 @@ function layout(bytes: Uint8Array): WasmLayout {
160
163
  if (flags !== 0 && flags !== 2)
161
164
  throw new Error(`unsupported wasm element segment ${flags}`)
162
165
  if (flags === 2 && read() !== 0) throw new Error('unsupported wasm table index')
163
- if (bytes[pos++] !== 0x41) throw new Error('nonconstant wasm table offset')
166
+ if (!constant(bytes[pos++])) throw new Error('nonconstant wasm table offset')
164
167
  let base: number
165
168
  ;[base, pos] = signedAddress(bytes, pos)
166
169
  if (bytes[pos++] !== 0x0b) throw new Error('invalid wasm table offset')
@@ -191,7 +194,7 @@ function layout(bytes: Uint8Array): WasmLayout {
191
194
  if (flags !== 0 && flags !== 2)
192
195
  throw new Error(`unsupported wasm data segment ${flags}`)
193
196
  if (flags === 2 && read() !== 0) throw new Error('unsupported wasm memory index')
194
- if (bytes[pos++] !== 0x41) throw new Error('nonconstant wasm data offset')
197
+ if (!constant(bytes[pos++])) throw new Error('nonconstant wasm data offset')
195
198
  let address: number
196
199
  ;[address, pos] = signedAddress(bytes, pos)
197
200
  if (bytes[pos++] !== 0x0b) throw new Error('invalid wasm data offset')
@@ -90,8 +90,8 @@ export function createGuestImageManifest(
90
90
  image: GuestManifestImage,
91
91
  ): SwiftGuestImageManifest {
92
92
  const target = {
93
- triple: 'wasm32-unknown-wasip1',
94
- pointerWidth: 32,
93
+ triple: 'wasm64-unknown-wasip1',
94
+ pointerWidth: 64,
95
95
  byteOrder: 'little',
96
96
  cpuType: -1,
97
97
  cpuSubtype: 0,