Skip to content

Conversation

@krodak
Copy link
Member

@krodak krodak commented Nov 5, 2025

Overview

This PR implements typed closure support in BridgeJS, enabling Swift functions to accept closures as parameters and return closures as values with full type safety.

Example

Swift:

@JS class TextProcessor {
    @JS init(transform: @escaping (String) -> String)
    @JS func processWithPerson(_ person: Person, formatter: (Person) -> String) -> String
    @JS func makePersonCreator(defaultName: String) -> (String) -> Person
}

JavaScript:

const processor = new exports.TextProcessor((text) => text.toUpperCase());

const person = new exports.Person("Alice");
const result = processor.processWithPerson(person, (p) => `${p.name}: ${p.greet()}`);

const creator = processor.makePersonCreator("Default");
const p1 = creator("Bob");

TypeScript:

export interface TextProcessor extends SwiftHeapObject {
    processWithPerson(person: Person, formatter: (arg0: Person) => string): string;
    makePersonCreator(defaultName: string): (arg0: string) => Person;
}

Technical Changes

  • Extended type system to support BridgeType.closure(ClosureSignature)
  • Updated Swift parser to detect closure parameters in function declarations
  • Generate Swift helper enums (_BJS_Closure_*) for each unique closure signature
  • Generate JavaScript callback registry and invoke functions, needed to expose _exports and _bjs to support that
  • Map closure signatures to TypeScript function types
  • Automatic memory management in both directions, needed to add bridgeJSLowerParameterWithRetain to support optional SwiftHeapObject

Supported Features

  • ✅ Closure parameters with any supported type
  • ✅ Closure return values
  • @escaping closures
  • ✅ Optional closures and optional parameters/returns
  • ✅ All existing BridgeJS types (primitives, String, enums, Swift classes)
  • ❌ Closure-typed properties (parameters/returns only)
  • ❌ Async/throwing closures

Testing

Added comprehensive snapshot and runtime tests for closure parameters, returns, optionals, and Swift heap objects in closures.

Documentation

Extended current documentation with new Exporting-Swift-Closure.md

@krodak krodak self-assigned this Nov 5, 2025
@krodak krodak added this to WasmKit Nov 5, 2025
@krodak krodak force-pushed the feat/closure-support branch from bbfaa31 to 3d17fda Compare November 5, 2025 14:05
@krodak krodak removed this from WasmKit Nov 5, 2025
@krodak krodak closed this Nov 6, 2025
@krodak krodak reopened this Nov 6, 2025
@krodak krodak force-pushed the feat/closure-support branch from 3298e26 to b9827cb Compare November 14, 2025 13:06
@krodak krodak force-pushed the feat/closure-support branch from b9827cb to d628d2d Compare November 14, 2025 13:17
@krodak krodak enabled auto-merge November 14, 2025 13:47
Copy link
Member

@kateinoigakukun kateinoigakukun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! 🚢

@krodak krodak merged commit 38b0c63 into swiftwasm:main Nov 14, 2025
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants