peachsim 0.1.2208 → 0.1.2210

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 (139) hide show
  1. package/dist-lib/agent-daemon-client.cjs +1 -1
  2. package/dist-lib/agent-events.cjs +1 -1
  3. package/dist-lib/attached-projects.cjs +1 -1
  4. package/dist-lib/auth/shared-session.cjs +1 -1
  5. package/dist-lib/backend-origin.cjs +1 -1
  6. package/dist-lib/beta.cjs +1 -1
  7. package/dist-lib/beta.mjs +1 -1
  8. package/dist-lib/bridge-constants.cjs +1 -1
  9. package/dist-lib/bridge-contract-input.cjs +1 -1
  10. package/dist-lib/bridge-contract-input.mjs +1 -1
  11. package/dist-lib/bridge-contract.cjs +1 -1
  12. package/dist-lib/bridge-contract.mjs +1 -1
  13. package/dist-lib/bundle-channel.cjs +712 -66
  14. package/dist-lib/capture-contract.cjs +1 -1
  15. package/dist-lib/capture-contract.mjs +1 -1
  16. package/dist-lib/cloud-contract.cjs +1 -1
  17. package/dist-lib/cloud-contract.mjs +1 -1
  18. package/dist-lib/cloud-test-args.cjs +1 -1
  19. package/dist-lib/cloud-test-args.mjs +1 -1
  20. package/dist-lib/cloud.cjs +1 -1
  21. package/dist-lib/cloud.mjs +1 -1
  22. package/dist-lib/config.cjs +1 -1
  23. package/dist-lib/config.mjs +1 -1
  24. package/dist-lib/detox/index.cjs +2 -2
  25. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  26. package/dist-lib/expo-swift-bundle.cjs +700 -60
  27. package/dist-lib/expo-swift-metadata.cjs +1 -1
  28. package/dist-lib/expo-swift-metadata.mjs +1 -1
  29. package/dist-lib/home-paths.cjs +1 -1
  30. package/dist-lib/host/bridge-host.cjs +712 -66
  31. package/dist-lib/host/fetch-proxy-handler.cjs +17 -4
  32. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  33. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  34. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  35. package/dist-lib/host/websocket-proxy.cjs +1 -1
  36. package/dist-lib/index.cjs +17 -4
  37. package/dist-lib/jump-to-source-babel.cjs +1 -1
  38. package/dist-lib/jump-to-source-native.cjs +1 -1
  39. package/dist-lib/kotlin-host.cjs +7 -1
  40. package/dist-lib/menu.cjs +1 -1
  41. package/dist-lib/menu.mjs +1 -1
  42. package/dist-lib/metro-fingerprint-registry.cjs +1 -1
  43. package/dist-lib/metro-fingerprint-registry.mjs +1 -1
  44. package/dist-lib/metro-production-bundle.cjs +1 -1
  45. package/dist-lib/metro-production-bundle.mjs +1 -1
  46. package/dist-lib/metro.cjs +17 -4
  47. package/dist-lib/native-app-identity-project.cjs +15 -2
  48. package/dist-lib/native-app-identity-project.mjs +15 -2
  49. package/dist-lib/native-app-identity.cjs +1 -1
  50. package/dist-lib/native-app-identity.mjs +1 -1
  51. package/dist-lib/native-firebase-metadata.cjs +1 -1
  52. package/dist-lib/native-firebase-metadata.mjs +1 -1
  53. package/dist-lib/pdfium-raster.cjs +1 -1
  54. package/dist-lib/pdfium-raster.mjs +1 -1
  55. package/dist-lib/plist.cjs +1 -1
  56. package/dist-lib/plist.mjs +1 -1
  57. package/dist-lib/profiles.cjs +1 -1
  58. package/dist-lib/public-brand.cjs +1 -1
  59. package/dist-lib/public-origins-lib-esm.json +24 -24
  60. package/dist-lib/public-origins-lib.json +69 -53
  61. package/dist-lib/react-native-host-modules.cjs +1 -1
  62. package/dist-lib/react-native-host-modules.mjs +1 -1
  63. package/dist-lib/reap-browser.cjs +1 -1
  64. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  65. package/dist-lib/sdk.cjs +1 -1
  66. package/dist-lib/sdk.mjs +1 -1
  67. package/dist-lib/skills.cjs +5679 -358
  68. package/dist-lib/swift-compile.cjs +154 -16
  69. package/dist-lib/swift-compile.mjs +153 -16
  70. package/dist-lib/swift-package.cjs +1 -1
  71. package/dist-lib/swift-package.mjs +1 -1
  72. package/dist-lib/swift-submit.cjs +1 -1
  73. package/dist-lib/swift-submit.mjs +1 -1
  74. package/dist-lib/swift-toolchain.cjs +1 -1
  75. package/dist-lib/swift.cjs +1 -1
  76. package/dist-lib/vite-swift.cjs +600 -55
  77. package/dist-lib/vite.cjs +17 -4
  78. package/dist-lib/worklet-executable.cjs +1 -1
  79. package/dist-lib/worklet-executable.mjs +1 -1
  80. package/dist-types/packages/peach-engine/src/engine/animated.d.ts +2 -1
  81. package/dist-types/packages/peach-engine/src/engine/animation-graph.d.ts +1 -0
  82. package/dist-types/packages/peach-engine/src/engine/liquid-glass.d.ts +6 -0
  83. package/dist-types/packages/peach-engine/src/engine/node.d.ts +1 -0
  84. package/dist-types/packages/peach-engine/src/engine/types.d.ts +1 -0
  85. package/dist-types/packages/peach-engine/src/render-worker/canvaskit-webgpu.d.ts +8 -0
  86. package/dist-types/packages/peach-engine/src/render-worker/compositor-gpu.d.ts +3 -0
  87. package/dist-types/packages/peach-engine/src/render-worker/compositor-protocol.d.ts +14 -0
  88. package/dist-types/packages/peach-engine/src/render-worker/compositor-runtime/render-tree.d.ts +18 -0
  89. package/kotlin/sdk.tar.gz +0 -0
  90. package/package.json +1 -1
  91. package/runtime-companion.json +1 -1
  92. package/sdk/ios/System/Library/Frameworks/Foundation.framework/Headers/NSCompoundPredicate.h +1 -1
  93. package/sdk/ios/System/Library/Frameworks/Foundation.framework/Headers/NSExpression.h +1 -1
  94. package/sdk/ios/System/Library/Frameworks/Foundation.framework/Headers/NSISO8601DateFormatter.h +1 -1
  95. package/sdk/ios/System/Library/Frameworks/Foundation.framework/Headers/NSMeasurementFormatter.h +1 -1
  96. package/sdk/ios/System/Library/Frameworks/Intents.framework/Headers/INObjectCollection.h +27 -0
  97. package/sdk/ios/System/Library/Frameworks/Intents.framework/Headers/INObjectSection.h +24 -0
  98. package/sdk/ios/System/Library/Frameworks/Intents.framework/Headers/Intents.h +9 -0
  99. package/sdk/ios/System/Library/Frameworks/Intents.framework/Modules/module.modulemap +5 -0
  100. package/sdk/ios/System/Library/Frameworks/QuartzCore.framework/Headers/CoreAnimation.h +2 -0
  101. package/sdk/ios/System/Library/Frameworks/UIKit.framework/Headers/UIFeedbackGenerator.h +1 -1
  102. package/sdk/ios/System/Library/Frameworks/UIKit.framework/Headers/UIImpactFeedbackGenerator.h +1 -1
  103. package/sdk/ios/System/Library/Frameworks/UIKit.framework/Headers/UIKit.apinotes +21 -0
  104. package/sdk/ios/System/Library/Frameworks/UIKit.framework/Headers/UINibLoading.h +1 -1
  105. package/sdk/ios/System/Library/Frameworks/UIKit.framework/Headers/UINotificationFeedbackGenerator.h +1 -1
  106. package/sdk/ios/System/Library/Frameworks/UIKit.framework/Headers/UISelectionFeedbackGenerator.h +1 -1
  107. package/sdk/ios/usr/include/ObjectiveC.apinotes +7 -0
  108. package/sdk/ios/usr/lib/swift/Combine.swiftmodule/arm64-apple-ios-simulator.swiftinterface +18 -0
  109. package/sdk/ios/usr/lib/swift/Foundation.swiftmodule/arm64-apple-ios-simulator.swiftinterface +1 -0
  110. package/sdk/ios/usr/lib/swift/SwiftUI.swiftmodule/arm64-apple-ios-simulator.swiftinterface +19 -0
  111. package/sdk/ios/usr/lib/swift/SwiftUICore.swiftmodule/arm64-apple-ios-simulator.swiftinterface +4 -0
  112. package/sdk/ios/usr/lib/swift/UIKit.swiftmodule/arm64-apple-ios-simulator.swiftinterface +4 -0
  113. package/sdk/ios/wasm/include/pthread.h +1 -0
  114. package/sdk/ios/wasm/include/signal.h +2 -2
  115. package/sdk/native-hashes.json +3 -3
  116. package/src/android-theme.ts +136 -2
  117. package/src/expo-swift-host.ts +90 -1
  118. package/src/generated/android-framework-text.json +4566 -0
  119. package/src/generated/android-framework-themes.json +11 -0
  120. package/src/kotlin-app.ts +24 -4
  121. package/src/kotlin-host.ts +9 -0
  122. package/src/native-static-libraries.ts +7 -0
  123. package/src/nitro-adapter.lock.json +246 -246
  124. package/src/nitro-superset.lock.json +4 -4
  125. package/src/swift-compile.ts +168 -12
  126. package/src/swift-distribution.lock.json +8 -8
  127. package/src/swift-host.ts +22 -3
  128. package/src/swift-objc-compile.ts +1 -1
  129. package/src/swift-objc-import.ts +32 -2
  130. package/src/swift-objc-standin.ts +10 -3
  131. package/src/swift-packages.ts +53 -28
  132. package/src/swift-pdf-raster.ts +60 -4
  133. package/src/swift-shared-sdk.ts +2 -1
  134. package/src/swift-shipped-archives.json +44 -0
  135. package/src/swift-shipped-binaries.ts +12 -0
  136. package/src/swift-standin-builtin-behavior.ts +248 -0
  137. package/src/swift-standin-emit.ts +11 -3
  138. package/src/swift-standins.ts +92 -13
  139. package/src/turbo-runtime.lock.json +17 -17
@@ -62,6 +62,7 @@ import {
62
62
  SWIFT_OBJC_INTEROP_FLAGS,
63
63
  swiftClangImporterFlags,
64
64
  swiftObjCModuleMap,
65
+ swiftSubmoduleImports,
65
66
  } from './swift-objc-import'
66
67
  import { swiftObjCRuntimeFlags } from './swift-objc-runtime'
67
68
  import { iosDeploymentMinimum, objcSdkIntakeFlags } from './swift-objc-standin'
@@ -1373,6 +1374,104 @@ export function swiftSystemLibraryExclusions(
1373
1374
  )
1374
1375
  }
1375
1376
 
1377
+ // EXUpdates publicly imports these C targets. The distribution links their
1378
+ // objects and ships no clang module, so a later `import EXUpdates` fails
1379
+ // with missing required modules EXStructuredHeaders and EXUpdatesBSPatch.
1380
+ // Headers match packages/sootsim-swift/Sources for those targets.
1381
+ const DISTRIBUTION_CLANG_MODULES: {
1382
+ name: string
1383
+ header: string
1384
+ source: string
1385
+ }[] = [
1386
+ {
1387
+ name: 'EXStructuredHeaders',
1388
+ header: 'EXStructuredHeaders/EXStructuredHeadersParser.h',
1389
+ source: `// Copyright © 2021 650 Industries. All rights reserved.
1390
+
1391
+ #import <Foundation/Foundation.h>
1392
+
1393
+ NS_ASSUME_NONNULL_BEGIN
1394
+
1395
+ typedef NS_ENUM(NSInteger, EXStructuredHeadersParserFieldType) {
1396
+ EXStructuredHeadersParserFieldTypeDictionary,
1397
+ EXStructuredHeadersParserFieldTypeList,
1398
+ EXStructuredHeadersParserFieldTypeItem
1399
+ };
1400
+
1401
+ @interface EXStructuredHeadersParser : NSObject
1402
+
1403
+ - (instancetype)initWithRawInput:(NSString *)raw
1404
+ fieldType:(EXStructuredHeadersParserFieldType)fieldType;
1405
+
1406
+ - (instancetype)initWithRawInput:(NSString *)raw
1407
+ fieldType:(EXStructuredHeadersParserFieldType)fieldType
1408
+ ignoringParameters:(BOOL)shouldIgnoreParameters;
1409
+
1410
+ - (nullable id)parseStructuredFieldsWithError:(NSError ** _Nullable)error;
1411
+
1412
+ @end
1413
+
1414
+ NS_ASSUME_NONNULL_END
1415
+ `,
1416
+ },
1417
+ {
1418
+ name: 'EXUpdatesBSPatch',
1419
+ header: 'EXUpdatesBSPatch.h',
1420
+ source: `// Copyright 2015-present 650 Industries. All rights reserved.
1421
+
1422
+ #pragma once
1423
+
1424
+ #import <Foundation/Foundation.h>
1425
+
1426
+ int EXUpdatesApplyBSDiffPatch(const char * _Nonnull oldFilePath,
1427
+ const char * _Nonnull newFilePath,
1428
+ const char * _Nonnull patchFilePath);
1429
+ `,
1430
+ },
1431
+ ]
1432
+
1433
+ function distributionClangModulePresent(modules: string, name: string): boolean {
1434
+ return (
1435
+ existsSync(path.join(modules, `${name}.swiftmodule`)) ||
1436
+ existsSync(path.join(modules, name, 'module.modulemap'))
1437
+ )
1438
+ }
1439
+
1440
+ /** module map for distribution C targets the archive omitted, or null when
1441
+ * the archive already provides them. */
1442
+ function distributionClangModuleMap(root: string, modules: string): string | null {
1443
+ const missing = DISTRIBUTION_CLANG_MODULES.filter(
1444
+ (mod) => !distributionClangModulePresent(modules, mod.name),
1445
+ )
1446
+ if (missing.length === 0) return null
1447
+ const key = createHash('sha256')
1448
+ .update(modules)
1449
+ .update(missing.map((mod) => `${mod.name}\0${mod.source}`).join('\0'))
1450
+ .digest('hex')
1451
+ .slice(0, 16)
1452
+ const directory = path.join(root, `.peach-clang-modules-${key}`)
1453
+ const mapPath = path.join(directory, 'module.modulemap')
1454
+ if (!existsSync(mapPath)) {
1455
+ mkdirSync(directory, { recursive: true })
1456
+ const parts: string[] = []
1457
+ for (const mod of missing) {
1458
+ const destination = path.join(directory, mod.header)
1459
+ mkdirSync(path.dirname(destination), { recursive: true })
1460
+ writeFileSync(destination, mod.source)
1461
+ parts.push(
1462
+ `module ${mod.name} {\n requires objc\n header "${mod.header}"\n export *\n}\n`,
1463
+ )
1464
+ }
1465
+ writeFileSync(mapPath, parts.join('\n'))
1466
+ }
1467
+ return mapPath
1468
+ }
1469
+
1470
+ function distributionClangModuleOptions(root: string, modules: string): string[] {
1471
+ const map = distributionClangModuleMap(root, modules)
1472
+ return map === null ? [] : ['-Xcc', `-fmodule-map-file=${map}`]
1473
+ }
1474
+
1376
1475
  /** prebuilt modules without interfaces owned by the compiling source graph. */
1377
1476
  function providedModulesPath(
1378
1477
  root: string,
@@ -2038,7 +2137,9 @@ export function emitSwiftPackageManifest(args: {
2038
2137
  path.join(moduleRoot, 'modules'),
2039
2138
  args.moduleExcludes,
2040
2139
  ),
2041
- )}`
2140
+ )}${distributionClangModuleOptions(args.root, path.join(moduleRoot, 'modules'))
2141
+ .map((flag) => `, ${JSON.stringify(flag)}`)
2142
+ .join('')}`
2042
2143
  : prebuilt
2043
2144
  ? `, "-Isystem", ${JSON.stringify(providedModulesPath(args.root, prebuilt.modules, args.moduleExcludes))}${prebuilt.moduleMaps
2044
2145
  .map((map) => `, "-Xcc", ${JSON.stringify(`-fmodule-map-file=${map}`)}`)
@@ -2351,6 +2452,9 @@ export function syncSwiftTree(base: string, files: Map<string, string | Buffer>)
2351
2452
  dir === base &&
2352
2453
  (entry.name === '.build' ||
2353
2454
  entry.name.startsWith('.peach-modules-') ||
2455
+ // distribution clang maps are written beside the project and named
2456
+ // from the compiler flags, so a sync must not remove them.
2457
+ entry.name.startsWith('.peach-clang-modules-') ||
2354
2458
  entry.name === SWIFT_LINK_STAMP)
2355
2459
  )
2356
2460
  continue
@@ -3729,6 +3833,25 @@ function stripCCode(source: string): string {
3729
3833
  return code
3730
3834
  }
3731
3835
 
3836
+ // whether the unit's code under wasm32 takes its own return address, which
3837
+ // the WebAssembly backend rejects ("hasn't implemented __builtin_return_address"):
3838
+ // native machine code the target has no lowering for, like assembly. branches
3839
+ // the native architecture macros guard are not wasm code.
3840
+ const wasmMacroEnvironment: SwiftCMacroEnvironment = {
3841
+ ...emptyMacroEnvironment,
3842
+ defines: new Map([
3843
+ ['__wasm__', '1'],
3844
+ ['__wasm32__', '1'],
3845
+ ['__wasi__', '1'],
3846
+ ]),
3847
+ }
3848
+ export function swiftCTakesReturnAddress(source: string): boolean {
3849
+ if (!source.includes('__builtin_return_address')) return false
3850
+ return /\b__builtin_return_address\s*\(/.test(
3851
+ cActiveCode(stripCCode(source), wasmMacroEnvironment),
3852
+ )
3853
+ }
3854
+
3732
3855
  // every name the given sources define. order and conditions are not
3733
3856
  // evaluated: a name defined anywhere makes its guards undecided.
3734
3857
  export function swiftCDefinedNames(sources: Iterable<string>): Set<string> {
@@ -4257,6 +4380,11 @@ export function writeSwiftProject(
4257
4380
  clangImportedModules.add(name)
4258
4381
  }
4259
4382
  }
4383
+ const submoduleImports = swiftSubmoduleImports(
4384
+ Object.entries(input.files).flatMap(([file, contents]) =>
4385
+ file.endsWith('.swift') ? [contents] : [],
4386
+ ),
4387
+ )
4260
4388
  const headerDirectory = path.join(layout.root, '.build', 'peach-cxx-headers')
4261
4389
  const flattenedHeaders = new Set<string>()
4262
4390
  // product header aliases belong to this input. keep emitted Swift headers,
@@ -4803,6 +4931,7 @@ export function writeSwiftProject(
4803
4931
  swiftObjCModuleMap(
4804
4932
  swiftTargetModuleName(target.name),
4805
4933
  roots.map((file) => path.join(layout.root, file)),
4934
+ submoduleImports.get(swiftTargetModuleName(target.name)),
4806
4935
  ))
4807
4936
  if (moduleContents === undefined)
4808
4937
  throw new Error('missing original module map ' + modulemap)
@@ -5192,26 +5321,38 @@ export function writeSwiftProject(
5192
5321
  modulemap,
5193
5322
  originalMap
5194
5323
  ? `extern module ${moduleName} ${JSON.stringify(path.join(layout.root, originalMap))}\nmodule ${moduleName}.Swift {\n header ${JSON.stringify(path.join(headerDirectory, name + '-Swift.h'))}\n requires objc\n}\n`
5195
- : swiftObjCModuleMap(moduleName, [
5196
- ...(
5197
- input.nativeTargets?.find((target) => target.name === name)
5198
- ?.publicHeaders ?? []
5199
- ).map((header) => path.join(layout.root, header)),
5200
- path.join(headerDirectory, name + '-Swift.h'),
5201
- ]),
5324
+ : swiftObjCModuleMap(
5325
+ moduleName,
5326
+ [
5327
+ ...(
5328
+ input.nativeTargets?.find((target) => target.name === name)
5329
+ ?.publicHeaders ?? []
5330
+ ).map((header) => path.join(layout.root, header)),
5331
+ path.join(headerDirectory, name + '-Swift.h'),
5332
+ ],
5333
+ submoduleImports.get(moduleName),
5334
+ ),
5202
5335
  )
5203
5336
  nativeHeaderFlags.push('-fmodule-map-file=' + modulemap)
5204
5337
  }
5205
5338
  // swiftpm plans a build root's build once and reuses the plan until a
5206
5339
  // manifest changes, so a file added to the module would never compile
5207
5340
  // there (RAN: a broken new UIKitCore file built "complete" in 0.1s). the
5208
- // module's file list and package flags replan when either changes.
5341
+ // module's file list, the package flags, and the app package's swift
5342
+ // names replan when any changes. names only, so an edit of a file already
5343
+ // in the plan still incremental-compiles.
5209
5344
  const modulePlan = createHash('sha256').update(
5210
5345
  swiftModuleInputFiles(moduleRoot).join('\n'),
5211
5346
  )
5212
5347
  if (!distribution) {
5213
5348
  modulePlan.update(readFileSync(path.join(moduleRoot, 'Package.swift')))
5214
5349
  }
5350
+ modulePlan.update(
5351
+ Object.keys(input.files)
5352
+ .filter((file) => file.endsWith('.swift'))
5353
+ .sort()
5354
+ .join('\n'),
5355
+ )
5215
5356
  const resourcePlan = createHash('sha256')
5216
5357
  .update(
5217
5358
  JSON.stringify(
@@ -5744,6 +5885,12 @@ export function writeSwiftProject(
5744
5885
  : prebuilt
5745
5886
  ? providedModulesPath(layout.root, prebuilt.modules, moduleExcludes)
5746
5887
  : path.join(layout.root, '.build', WASM_TRIPLE, 'release', 'Modules'),
5888
+ ...(distribution
5889
+ ? distributionClangModuleOptions(
5890
+ layout.root,
5891
+ path.join(moduleRoot, 'modules'),
5892
+ )
5893
+ : []),
5747
5894
  ...(prebuilt?.moduleMaps.flatMap((map) => [
5748
5895
  '-Xcc',
5749
5896
  `-fmodule-map-file=${map}`,
@@ -6471,8 +6618,15 @@ async function buildFrameworkProducts(
6471
6618
  const linked = frameworkLinkClosure(scratch, linkedTargets.targets)
6472
6619
  const objects = linked.objects
6473
6620
  if (linked.modules.has('UniformTypeIdentifiers')) {
6474
- const object = path.join(scratch, 'UniformTypeIdentifiers-NativeConstants.o')
6475
- if (!existsSync(object)) {
6621
+ const constantsDir = path.join(scratch, 'uniform-type-constants')
6622
+ const constantsStamp = path.join(constantsDir, '.complete')
6623
+ const object = path.join(constantsDir, 'UniformTypeIdentifiers-NativeConstants.o')
6624
+ if (
6625
+ !existsSync(constantsStamp) ||
6626
+ readFileSync(constantsStamp, 'utf8') !== args.frameworkKey
6627
+ ) {
6628
+ rmSync(constantsDir, { recursive: true, force: true })
6629
+ mkdirSync(constantsDir)
6476
6630
  const sdkPaths = swiftSdkPaths(args.moduleRoot, args.toolchainBin)
6477
6631
  compileUniformTypeConstants({
6478
6632
  bin: args.toolchainBin,
@@ -6480,8 +6634,9 @@ async function buildFrameworkProducts(
6480
6634
  darwin: sdkPaths.darwin,
6481
6635
  packageRoot: args.moduleRoot,
6482
6636
  minimum: darwinRecordsMinimum(),
6483
- out: scratch,
6637
+ out: constantsDir,
6484
6638
  })
6639
+ writeFileSync(constantsStamp, args.frameworkKey)
6485
6640
  }
6486
6641
  objects.push(object)
6487
6642
  linked.owners.set(object, 'UniformTypeIdentifiers')
@@ -6886,6 +7041,7 @@ function compileSwiftProjectOnce(
6886
7041
  if (
6887
7042
  !options.intermediates &&
6888
7043
  process.platform === 'darwin' &&
7044
+ !options.intermediates &&
6889
7045
  process.env.TM_SESSION &&
6890
7046
  !windowAdmission() &&
6891
7047
  process.env.CI !== 'true' &&
@@ -1,10 +1,10 @@
1
1
  {
2
- "id": "87fc4d2ff9d5d588",
2
+ "id": "e7ae8fdb51086f73",
3
3
  "release": "swift-6.4.0-RELEASE-custom-11345d60dca47496",
4
4
  "wasmSdkId": "swift-6.4.0-RELEASE_wasm-peach-19471d4b",
5
5
  "wasmSdkUrl": "https://r2.sootsim.com/swift-wasm-sdk/swift-6.4.0-RELEASE_wasm-peach-19471d4b.artifactbundle.tar.gz",
6
6
  "wasmSdkChecksum": "764c16e7e34156bf90d6c3372a2b77b98b9d8c3470235520d0f9619f90f33456",
7
- "source": "08519cc5f11db43a2f85f28c47ec6c8930843f93",
7
+ "source": "dbcdd2998c7a523cb5136f3731f6850cfe0bd154",
8
8
  "targets": [
9
9
  "ImagePlayground",
10
10
  "QuickLookThumbnailing",
@@ -244,16 +244,16 @@
244
244
  },
245
245
  "hosts": {
246
246
  "darwin-arm64": {
247
- "sha256": "7444ad87688bb551601a49fee6b48d15978fcd877982a25a944280f553f439b5",
248
- "size": 103297800
247
+ "sha256": "8680805789e5212d83e374bea9e4af3e3c7a86011e8ebf4921e76a8eba092761",
248
+ "size": 103496854
249
249
  },
250
250
  "linux-x64": {
251
- "sha256": "03edd8359c024c592bb53b8917d9efc59f9b76871966b41189838deb2b9c27f2",
252
- "size": 106017072
251
+ "sha256": "9d82820dfdbc857d5127c489b9c704c9e9336fe8b010256cd5b1d24ba956f454",
252
+ "size": 106214710
253
253
  },
254
254
  "linux-arm64": {
255
- "sha256": "00a89f46a581f73ea6b0343f21fa330bbe1ae444a1d29ad7251e87a86e4bc91b",
256
- "size": 105508093
255
+ "sha256": "a8e5084e14867ca9245428e51cb9435bc5b34505914fa5855950951d01b6b990",
256
+ "size": 105708986
257
257
  }
258
258
  }
259
259
  }
package/src/swift-host.ts CHANGED
@@ -83,7 +83,8 @@ import {
83
83
  type SwiftPackageGap,
84
84
  type SwiftPackages,
85
85
  } from './swift-packages'
86
- import { rasterizePdfFile } from './swift-pdf-raster'
86
+ import { rasterizePdfFile, rasterizeSvgFile } from './swift-pdf-raster'
87
+ import { shippedBinaryDiffers } from './swift-shipped-binaries'
87
88
  import {
88
89
  packageInputPath,
89
90
  readPackageFile as readSwiftSourceFile,
@@ -596,7 +597,7 @@ async function swiftPackages(
596
597
  // compiling, or a placeholder package's swift target: each stands in from
597
598
  // its public surface.
598
599
  const standinArtifact = (binary: SwiftPackageBinary) =>
599
- binary.publicHeaders === undefined || binary.assemblySources !== undefined
600
+ binary.publicHeaders === undefined || binary.unloweredSources !== undefined
600
601
  const artifacts = reached.filter(standinArtifact)
601
602
  if (entry.moduleRoot && entry.provided && artifacts.length > 0) {
602
603
  const resolved = swiftModuleToolchain(entry.moduleRoot)
@@ -618,10 +619,16 @@ async function swiftPackages(
618
619
  const cxxArtifacts = reached.filter(standinArtifact)
619
620
  const generation = standinGenerationInputs(cxxArtifacts, toolchain, entry.behavior)
620
621
  if (cached.standinKey !== generation) {
622
+ // an archive other than the one peach ships a module for stands in itself
623
+ const replaced = new Set(
624
+ cxxArtifacts
625
+ .filter((binary) => shippedBinaryDiffers(binary.target, binary.checksum))
626
+ .map((binary) => binary.target),
627
+ )
621
628
  const built = await swiftStandins(
622
629
  cxxArtifacts,
623
630
  toolchain,
624
- entry.provided,
631
+ new Set([...entry.provided].filter((name) => !replaced.has(name))),
625
632
  entry.behavior,
626
633
  )
627
634
  cached.packages = await resolveSwiftPackagesAsync({
@@ -637,6 +644,9 @@ async function swiftPackages(
637
644
  .map((binary) => binary.target)
638
645
  .filter((target) => !built.gaps.has(target)),
639
646
  ]),
647
+ standinTargets: new Set(
648
+ [...replaced].filter((target) => !built.gaps.has(target)),
649
+ ),
640
650
  binaryGaps: built.gaps,
641
651
  owners,
642
652
  })
@@ -1941,6 +1951,15 @@ export function buildSwiftResourceTable(
1941
1951
  throw new Error('swift image pack exceeds the compile service caps')
1942
1952
  }
1943
1953
  bytes = readPackageFile(project.packagePath, disk, limits.imageBytes)
1954
+ const svg =
1955
+ ext === '.svg'
1956
+ ? rasterizeSvgFile(disk, createHash('sha256').update(bytes).digest('hex'))
1957
+ : null
1958
+ if (svg) {
1959
+ bytes = svg.bytes
1960
+ ext = '.png'
1961
+ uploadName = `${path.posix.basename(file, path.posix.extname(file))}.png`
1962
+ }
1944
1963
  }
1945
1964
  if (imageBytes + bytes.length > limits.imageTotalBytes) {
1946
1965
  throw new Error('swift image pack exceeds the compile service caps')
@@ -432,7 +432,7 @@ function* xcodeObjCInputSteps(
432
432
  if (
433
433
  !binary.reached ||
434
434
  binary.publicHeaders === undefined ||
435
- binary.assemblySources !== undefined
435
+ binary.unloweredSources !== undefined
436
436
  )
437
437
  continue
438
438
  const manifest = swiftPackageManifest(binary.dir)
@@ -24,12 +24,42 @@ export function swiftClangImporterFlags(flags: readonly string[]): string[] {
24
24
  )
25
25
  }
26
26
 
27
+ // swift names a header's submodule as `import Module.Header`, which xcode
28
+ // infers for every header of a framework. a header an app source imports that
29
+ // way becomes its own submodule, visible with the module; the rest stay in it.
30
+ const SWIFT_SUBMODULE_IMPORT =
31
+ /^[ \t]*(?:@\w+(?:\([^)]*\))?[ \t]+)*import[ \t]+([A-Za-z_]\w*)\.([A-Za-z_]\w*)[ \t]*(?:\/\/.*)?$/gm
32
+
33
+ export function swiftSubmoduleImports(
34
+ sources: Iterable<string>,
35
+ ): Map<string, Set<string>> {
36
+ const imports = new Map<string, Set<string>>()
37
+ for (const source of sources)
38
+ for (const [, module, submodule] of source.matchAll(SWIFT_SUBMODULE_IMPORT)) {
39
+ const names = imports.get(module!) ?? new Set<string>()
40
+ names.add(submodule!)
41
+ imports.set(module!, names)
42
+ }
43
+ return imports
44
+ }
45
+
27
46
  // swiftpm synthesizes a module map for public headers when the package provides
28
47
  // none. original xcode and package module maps retain their own contents.
29
- export function swiftObjCModuleMap(module: string, headers: readonly string[]): string {
48
+ export function swiftObjCModuleMap(
49
+ module: string,
50
+ headers: readonly string[],
51
+ submodules: ReadonlySet<string> = new Set(),
52
+ ): string {
53
+ const header = (file: string) => `header ${JSON.stringify(file)}`
54
+ const stem = (file: string) =>
55
+ file.slice(file.lastIndexOf('/') + 1).replace(/\.[^.]*$/, '')
30
56
  return [
31
57
  `module ${module} {`,
32
- ...headers.map((header) => ` header ${JSON.stringify(header)}`),
58
+ ...headers.map((file) =>
59
+ submodules.has(stem(file))
60
+ ? ` module ${stem(file)} { ${header(file)} export * }`
61
+ : ` ${header(file)}`,
62
+ ),
33
63
  ' export *',
34
64
  '}',
35
65
  '',
@@ -348,7 +348,7 @@ export function iosDeploymentMinimum(version: string | null): number | undefined
348
348
  const headerFiles = (dir: string): string[] =>
349
349
  fs
350
350
  .readdirSync(dir, { recursive: true, encoding: 'utf8' })
351
- .filter((file) => file.endsWith('.h'))
351
+ .filter((file) => file.endsWith('.h') || file.endsWith('.hh'))
352
352
  .sort()
353
353
 
354
354
  /**
@@ -571,11 +571,18 @@ export function objcView(
571
571
  recursive: true,
572
572
  })
573
573
  // the swift overlay owns what the generated -Swift.h header re-imports
574
- // under swift_name, so a mixed framework's intake map drops that submodule
574
+ // under swift_name, so a mixed framework's intake map drops that submodule.
575
+ // an enum the objective-c headers only forward-declare is completed by that
576
+ // header, and without it every member naming the enum leaves the import.
575
577
  const modulemap = fs.readFileSync(surface.modulemap, 'utf8')
578
+ const forwardEnum = [...originals.values()].some((text) =>
579
+ /typedef\s+NS_(?:CLOSED_)?(?:ENUM|OPTIONS)\s*\(\s*\w+\s*,\s*\w+\s*\)\s*;/.test(
580
+ text,
581
+ ),
582
+ )
576
583
  fs.writeFileSync(
577
584
  path.join(frameworks, `${surface.module}.framework`, 'Modules', 'module.modulemap'),
578
- surface.interface
585
+ surface.interface && !forwardEnum
579
586
  ? modulemap.replace(
580
587
  new RegExp(`\\n\\s*module\\s+${surface.module}\\.Swift\\s*\\{[^}]*\\}`),
581
588
  '',
@@ -19,6 +19,7 @@ import { cacheDir } from './home-paths'
19
19
  import { requireNativeGit } from './native-git'
20
20
  import { tryAcquireNumberedLock } from './numbered-lock'
21
21
  import { preparedSwiftCheckouts, preparedSwiftPin } from './prepared-xcode-phases'
22
+ import { swiftCTakesReturnAddress } from './swift-compile'
22
23
  import {
23
24
  isSwiftNativeTranslationUnit,
24
25
  swiftImplicitResourcePaths,
@@ -36,6 +37,7 @@ import {
36
37
  type SwiftManifestTarget,
37
38
  type SwiftPackageManifest,
38
39
  } from './swift-package-manifest'
40
+ import { shippedBinaryDiffers } from './swift-shipped-binaries'
39
41
  import type { SwiftSourceLinkGraph } from './swiftContract'
40
42
 
41
43
  // which machine a package target is built for
@@ -114,9 +116,9 @@ export interface SwiftPackageBinary {
114
116
  reached: boolean
115
117
  /** a source Objective-C target: public headers relative to dir. */
116
118
  publicHeaders?: string
117
- /** assembly sources, relative to the package, that keep a source target from
118
- * compiling; its public headers stand in for it. */
119
- assemblySources?: string[]
119
+ /** sources, relative to the package, with no wasm32 lowering that keep a
120
+ * source target from compiling; its public headers stand in for it. */
121
+ unloweredSources?: string[]
120
122
  /** dependency module public headers, relative to dir. */
121
123
  headerDependencies?: { module: string; path: string }[]
122
124
  /** xcode modules whose linked package products reach this clang target. */
@@ -159,29 +161,42 @@ export function remoteSwiftCheckouts(root: string): string {
159
161
  // assembly requires its own target lowering; objective-c keeps its original bodies.
160
162
  const UNSUPPORTED_NATIVE = /\.(s|S)$/
161
163
 
162
- // a clang source target whose sources include assembly cannot lower to wasm,
163
- // unless upstream declares wasi-conditioned c settings for it: that is the
164
- // package's own supported portable path (boringssl's guarded assembly with
165
- // OPENSSL_NO_ASM), which compiles with those flags exactly as swiftpm builds
166
- // it. without that signal the target keeps the refusal below. when a refused
167
- // target also ships public headers, those headers stand in for it and every
168
- // declaration they spell traps by name. this is the assembly rule above,
169
- // widened only where the target has a header surface to stand in from.
170
- function assemblySources(
164
+ // a clang source target whose sources include assembly, or take their own
165
+ // return address, cannot lower to wasm, unless upstream declares
166
+ // wasi-conditioned c settings for it: that is the package's own supported
167
+ // portable path (boringssl's guarded assembly with OPENSSL_NO_ASM), which
168
+ // compiles with those flags exactly as swiftpm builds it. without that signal
169
+ // the target keeps the refusal below. when a refused target also ships public
170
+ // headers, those headers stand in for it and every declaration they spell
171
+ // traps by name. this is the assembly rule above, widened only where the
172
+ // target has a header surface to stand in from.
173
+ function unlowerableSources(
174
+ files: readonly string[],
175
+ target: SwiftManifestTarget,
176
+ ): string[] {
177
+ if (target.declaresWasiNativeSettings) return []
178
+ return [
179
+ ...files.filter((file) => UNSUPPORTED_NATIVE.test(file)),
180
+ ...files
181
+ .filter(isSwiftNativeTranslationUnit)
182
+ .filter((file) => swiftCTakesReturnAddress(fs.readFileSync(file, 'utf8'))),
183
+ ]
184
+ }
185
+
186
+ function unloweredSources(
171
187
  files: readonly string[],
172
188
  target: SwiftManifestTarget,
173
189
  ): string[] | null {
174
190
  if (target.type !== 'regular') return null
175
- if (target.declaresWasiNativeSettings) return null
176
- const assembly = files.filter((file) => UNSUPPORTED_NATIVE.test(file))
177
- if (assembly.length === 0) return null
178
191
  if (!files.some(isSwiftNativeTranslationUnit)) return null
192
+ const unlowered = unlowerableSources(files, target)
193
+ if (unlowered.length === 0) return null
179
194
  const headers = path.resolve(target.dir, target.publicHeadersPath)
180
195
  if (
181
196
  !files.some((file) => file.startsWith(`${headers}${path.sep}`) && file.endsWith('.h'))
182
197
  )
183
198
  return null
184
- return assembly
199
+ return unlowered
185
200
  }
186
201
 
187
202
  const BINARY = 'is a binary framework'
@@ -514,6 +529,8 @@ export function resolveSwiftPackages(options: {
514
529
  /** local package directories the workspace or a project references. */
515
530
  localDirs: readonly string[]
516
531
  provided: ReadonlySet<string> | null
532
+ /** binary targets whose stand-in is built; one pinning another archive than peach's shipped module compiles through it. */
533
+ standinTargets?: ReadonlySet<string>
517
534
  /** why a binary target has no stand-in, added to its reason. */
518
535
  binaryGaps?: ReadonlyMap<string, string>
519
536
  /**
@@ -657,9 +674,7 @@ export function resolveSwiftPackages(options: {
657
674
  ? swiftTargetFiles(pkg.manifest, target)
658
675
  : []
659
676
  const gap = options.binaryGaps?.get(name)
660
- const assembly = target.declaresWasiNativeSettings
661
- ? []
662
- : files.filter((file) => UNSUPPORTED_NATIVE.test(file))
677
+ const unlowerable = unlowerableSources(files, target)
663
678
  const placeholder = placeholderPackage(pkg)
664
679
  const ownReason =
665
680
  target.type === 'binary'
@@ -668,8 +683,8 @@ export function resolveSwiftPackages(options: {
668
683
  ? `${name} stands in as a placeholder (${placeholder}), and ${gap}`
669
684
  : target.type !== 'regular' && target.type !== 'system'
670
685
  ? `${name} is a ${target.type} target`
671
- : assembly.length > 0
672
- ? `${name} is an assembly target with no wasm32 lowering: ${assembly.map((file) => path.relative(pkg.manifest.dir, file)).join(', ')}${gap ? `; ${gap}` : ''}`
686
+ : unlowerable.length > 0
687
+ ? `${name} has native sources with no wasm32 lowering: ${unlowerable.map((file) => path.relative(pkg.manifest.dir, file)).join(', ')}${gap ? `; ${gap}` : ''}`
673
688
  : null
674
689
  // every dependency resolves, so a failing one never hides the rest
675
690
  // of the closure from the compile or from the report
@@ -778,9 +793,8 @@ export function resolveSwiftPackages(options: {
778
793
  )
779
794
  )
780
795
  return false
781
- // an assembly target stands in from its public headers, so a stand-in
782
- // peach built for it stays provided instead of compiling its sources
783
- if (providedTargets.has(name) && assemblySources(files, target)) return false
796
+ // a target whose headers stand in for its unlowered sources stays with the stand-in
797
+ if (unloweredSources(files, target)) return false
784
798
  claimed.add(key)
785
799
  providedTargets.delete(name)
786
800
  for (const dependency of target.dependencies) {
@@ -794,6 +808,17 @@ export function resolveSwiftPackages(options: {
794
808
  }
795
809
  const claimProduct = (pkg: LoadedPackage, product: string): void => {
796
810
  const roots = pkg.manifest.products.get(product)?.targets ?? []
811
+ for (const root of roots) {
812
+ const target = pkg.manifest.targets.get(root)
813
+ if (
814
+ target?.type === 'binary' &&
815
+ !options.standinTargets?.has(root) &&
816
+ shippedBinaryDiffers(root, target.checksum)
817
+ ) {
818
+ providedTargets.delete(root)
819
+ providedProducts.delete(product)
820
+ }
821
+ }
797
822
  if (roots.map((name) => claimTarget(pkg, name)).some(Boolean))
798
823
  providedProducts.delete(product)
799
824
  }
@@ -840,7 +865,7 @@ export function resolveSwiftPackages(options: {
840
865
  : []
841
866
  const objc =
842
867
  target.type === 'regular' && files.some((file) => /\.(m|mm)$/.test(file))
843
- const assembly = assemblySources(files, target)
868
+ const unlowered = unloweredSources(files, target)
844
869
  const gap = placeholderPackage(pkg)
845
870
  const sources = files.filter((file) => file.endsWith('.swift'))
846
871
  // swiftpm's release settings, as xcode builds a package for any
@@ -873,7 +898,7 @@ export function resolveSwiftPackages(options: {
873
898
  ],
874
899
  },
875
900
  })
876
- else if (target.type === 'binary' || objc || assembly)
901
+ else if (target.type === 'binary' || objc || unlowered)
877
902
  result.binaries.push({
878
903
  target: name,
879
904
  source: pkg.source,
@@ -889,9 +914,9 @@ export function resolveSwiftPackages(options: {
889
914
  path.join(target.dir, target.publicHeadersPath),
890
915
  ),
891
916
  }),
892
- ...(assembly
917
+ ...(unlowered
893
918
  ? {
894
- assemblySources: assembly.map((file) =>
919
+ unloweredSources: unlowered.map((file) =>
895
920
  path.relative(pkg.manifest.dir, file),
896
921
  ),
897
922
  }