Commit d7e34a5
committed
feat: add opt-in "swift" identity mode with Swift-owned strong cache
Introduces a third value for @js(identityMode:): .swift, alongside the
existing .none (default) and .pointer (weak JS-side cache shipped in main).
With .swift mode, Swift owns the wrapper lifetime via per-class tables:
var _<Class>_identityTable: [UnsafeMutableRawPointer: Int32] // ptr → id
var _<Class>_idToPointer: [Int32: UnsafeMutableRawPointer] // id → ptr
var _<Class>_wrapperRefs: [Int32] // id → JS ref
var _<Class>_freeIds: [Int32]
var _<Class>_nextId: Int32
On return, Swift looks up the pointer; on miss it retains, allocates an id,
and pushes (id, freshBit) on the existing i32 stack. JS pops the pair, and
either returns cache[id] (hit) or builds a wrapper and calls back via
bjs_<Class>_register_wrapper to install the retained JS ref. Release is
driven by an explicit bjs_<Class>_release_wrapper(id) export.
The miss-heavy regression of .pointer mode (FinalizationRegistry.register +
new WeakRef + Map.set account for 88% of miss cost per Phase 0 profiling)
is addressed: .swift mode keeps no WeakRef, no FinalizationRegistry, no
per-miss Map.set — just a dense array indexed by Swift-assigned id.
Per-class opt-in via @js(identityMode: .swift); project-wide default via
"identityMode": "swift" in bridge-js.config.json. A JSIdentityMode enum
replaces the legacy identityMode: Bool macro parameter; true/false literals
are still accepted at parse time for backward compatibility.
Changes:
- New JSIdentityMode enum + macro parameter migration (Bool → enum)
- Skeleton.identityMode: Bool? → String?, with per-class and config-default
resolution threaded through ExportSwift and BridgeJSLink
- New Wasm intrinsic _swift_js_release_ref
- ExportSwift emits per-class tables + register/release thunks +
bridgeJSStackPush override for array-element returns
- BridgeJSLink emits a standalone SwiftIdentityHeapObject template
(no SwiftHeapObject inheritance, no FinalizationRegistry, no WeakRef)
with a use-after-release guard on every instance member
- New BridgeJSSwiftIdentityTests target for config-default opt-in E2E
coverage; extends BridgeJSIdentityTests with per-class opt-in scenarios
- *SwiftIdentity benchmark variants + three-mode harness in identity-benchmarks.js
- DocC article Identity-Modes-For-Exported-Classes.md; cross-references
from Exporting-Swift-Class.md, Exporting-Swift-to-JavaScript.md,
BridgeJS-Configuration.md1 parent 34c5d0d commit d7e34a5
39 files changed
Lines changed: 5852 additions & 82 deletions
File tree
- Benchmarks
- Sources
- Generated
- JavaScript
- lib
- Plugins/BridgeJS
- Sources
- BridgeJSCore
- BridgeJSLink
- BridgeJSSkeleton
- Tests/BridgeJSToolTests
- Inputs/MacroSwift
- __Snapshots__
- BridgeJSCodegenTests
- BridgeJSLinkTests
- Sources/JavaScriptKit
- Documentation.docc/Articles/BridgeJS
- Exporting-Swift
- Tests
- BridgeJSIdentityTests
- Generated
- JavaScript
- JavaScript
- BridgeJSSwiftIdentityTests
- Generated
- JavaScript
- JavaScript
- Utilities
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
15 | | - | |
| 15 | + | |
16 | 16 | | |
17 | 17 | | |
18 | 18 | | |
19 | 19 | | |
20 | 20 | | |
21 | | - | |
| 21 | + | |
22 | 22 | | |
23 | 23 | | |
24 | 24 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
305 | 305 | | |
306 | 306 | | |
307 | 307 | | |
308 | | - | |
309 | | - | |
| 308 | + | |
| 309 | + | |
310 | 310 | | |
311 | 311 | | |
312 | | - | |
| 312 | + | |
313 | 313 | | |
314 | 314 | | |
315 | 315 | | |
| |||
326 | 326 | | |
327 | 327 | | |
328 | 328 | | |
329 | | - | |
| 329 | + | |
330 | 330 | | |
331 | 331 | | |
332 | 332 | | |
| |||
345 | 345 | | |
346 | 346 | | |
347 | 347 | | |
348 | | - | |
| 348 | + | |
349 | 349 | | |
350 | 350 | | |
351 | 351 | | |
| |||
360 | 360 | | |
361 | 361 | | |
362 | 362 | | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
363 | 418 | | |
364 | 419 | | |
365 | 420 | | |
| |||
0 commit comments