Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions Plugins/BridgeJS/Sources/BridgeJSCore/ClosureCodegen.swift
Original file line number Diff line number Diff line change
Expand Up @@ -123,23 +123,23 @@ public struct ClosureCodegen {

for (index, paramType) in signature.parameters.enumerated() {
let paramName = "param\(index)"
let liftInfo = try paramType.liftParameterInfo()
let liftParams = try paramType.liftParameterInfo()

for (argName, wasmType) in liftInfo.parameters {
for (argName, wasmType) in liftParams {
let fullName =
liftInfo.parameters.count > 1 ? "\(paramName)\(argName.capitalizedFirstLetter)" : paramName
liftParams.count > 1 ? "\(paramName)\(argName.capitalizedFirstLetter)" : paramName
abiParams.append((fullName, wasmType))
}

let argNames = liftInfo.parameters.map { (argName, _) in
liftInfo.parameters.count > 1 ? "\(paramName)\(argName.capitalizedFirstLetter)" : paramName
let argNames = liftParams.map { (argName, _) in
liftParams.count > 1 ? "\(paramName)\(argName.capitalizedFirstLetter)" : paramName
}
liftedParams.append("\(paramType.swiftType).bridgeJSLiftParameter(\(argNames.joined(separator: ", ")))")
}

let closureCallExpr = ExprSyntax("closure(\(raw: liftedParams.joined(separator: ", ")))")

let abiReturnWasmType = try signature.returnType.loweringReturnInfo().returnType
let abiReturnWasmType = try signature.returnType.loweringReturnInfo()

// Build signature using SwiftSignatureBuilder
let funcSignature = SwiftSignatureBuilder.buildABIFunctionSignature(
Expand Down
409 changes: 123 additions & 286 deletions Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift

Large diffs are not rendered by default.

134 changes: 21 additions & 113 deletions Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift
Original file line number Diff line number Diff line change
Expand Up @@ -695,143 +695,51 @@ enum SwiftCodePattern {
extension BridgeType {
struct LoweringParameterInfo {
let loweredParameters: [(name: String, type: WasmCoreType)]

static let bool = LoweringParameterInfo(loweredParameters: [("value", .i32)])
static let int = LoweringParameterInfo(loweredParameters: [("value", .i32)])
static let float = LoweringParameterInfo(loweredParameters: [("value", .f32)])
static let double = LoweringParameterInfo(loweredParameters: [("value", .f64)])
static let string = LoweringParameterInfo(loweredParameters: [("value", .i32)])
static let jsObject = LoweringParameterInfo(loweredParameters: [("value", .i32)])
static let jsValue = LoweringParameterInfo(loweredParameters: [
("kind", .i32),
("payload1", .i32),
("payload2", .f64),
])
static let void = LoweringParameterInfo(loweredParameters: [])
}

func loweringParameterInfo(context: BridgeContext = .importTS) throws -> LoweringParameterInfo {
switch self {
case .bool: return .bool
case .int, .uint: return .int
case .float: return .float
case .double: return .double
case .string: return .string
case .jsObject: return .jsObject
case .jsValue: return .jsValue
case .void: return .void
case .closure:
// Swift closure is passed to JS as a JS function reference.
return LoweringParameterInfo(loweredParameters: [("funcRef", .i32)])
case .unsafePointer:
return LoweringParameterInfo(loweredParameters: [("pointer", .pointer)])
case .swiftHeapObject:
return LoweringParameterInfo(loweredParameters: [("pointer", .pointer)])
case .swiftProtocol:
throw BridgeJSCoreError("swiftProtocol is not supported in imported signatures")
case .caseEnum:
switch context {
case .importTS:
throw BridgeJSCoreError("Enum types are not yet supported in TypeScript imports")
case .exportSwift:
return LoweringParameterInfo(loweredParameters: [("value", .i32)])
}
case .rawValueEnum(_, let rawType):
let wasmType = rawType.wasmCoreType ?? .i32
return LoweringParameterInfo(loweredParameters: [("value", wasmType)])
case .associatedValueEnum:
switch context {
case .importTS:
throw BridgeJSCoreError("Enum types are not yet supported in TypeScript imports")
case .exportSwift:
return LoweringParameterInfo(loweredParameters: [("caseId", .i32)])
}
case .swiftStruct:
switch context {
case .importTS:
// Swift structs are bridged as JS objects (object IDs) in imported signatures.
return LoweringParameterInfo(loweredParameters: [("objectId", .i32)])
case .exportSwift:
return LoweringParameterInfo(loweredParameters: [])
}
case .namespaceEnum:
throw BridgeJSCoreError("Namespace enums cannot be used as parameters")
case .nullable(let wrappedType, _):
let wrappedInfo = try wrappedType.loweringParameterInfo(context: context)
var params = [("isSome", WasmCoreType.i32)]
params.append(contentsOf: wrappedInfo.loweredParameters)
return LoweringParameterInfo(loweredParameters: params)
case .array, .dictionary:
return LoweringParameterInfo(loweredParameters: [])
case .namespaceEnum:
throw BridgeJSCoreError("Namespace enums cannot be used as parameters")
case .swiftProtocol:
throw BridgeJSCoreError("swiftProtocol is not supported in imported signatures")
case .caseEnum, .associatedValueEnum:
if context == .importTS {
throw BridgeJSCoreError("Enum types are not yet supported in TypeScript imports")
}
fallthrough
default:
return LoweringParameterInfo(loweredParameters: descriptor.importParams)
}
}

struct LiftingReturnInfo {
let valueToLift: WasmCoreType?

static let bool = LiftingReturnInfo(valueToLift: .i32)
static let int = LiftingReturnInfo(valueToLift: .i32)
static let float = LiftingReturnInfo(valueToLift: .f32)
static let double = LiftingReturnInfo(valueToLift: .f64)
static let string = LiftingReturnInfo(valueToLift: .i32)
static let jsObject = LiftingReturnInfo(valueToLift: .i32)
static let jsValue = LiftingReturnInfo(valueToLift: nil)
static let void = LiftingReturnInfo(valueToLift: nil)
}

func liftingReturnInfo(
context: BridgeContext = .importTS
) throws -> LiftingReturnInfo {
switch self {
case .bool: return .bool
case .int, .uint: return .int
case .float: return .float
case .double: return .double
case .string: return .string
case .jsObject: return .jsObject
case .jsValue: return .jsValue
case .void: return .void
case .closure:
// JS returns a callback ID for closures, which Swift lifts to a typed closure.
return LiftingReturnInfo(valueToLift: .i32)
case .unsafePointer:
return LiftingReturnInfo(valueToLift: .pointer)
case .swiftHeapObject:
return LiftingReturnInfo(valueToLift: .pointer)
case .nullable(let wrappedType, _):
let wrappedInfo = try wrappedType.liftingReturnInfo(context: context)
return LiftingReturnInfo(valueToLift: wrappedInfo.valueToLift)
case .namespaceEnum:
throw BridgeJSCoreError("Namespace enums cannot be used as return values")
case .swiftProtocol:
throw BridgeJSCoreError("swiftProtocol is not supported in imported signatures")
case .caseEnum:
switch context {
case .importTS:
throw BridgeJSCoreError("Enum types are not yet supported in TypeScript imports")
case .exportSwift:
return LiftingReturnInfo(valueToLift: .i32)
}
case .rawValueEnum(_, let rawType):
let wasmType = rawType.wasmCoreType ?? .i32
return LiftingReturnInfo(valueToLift: wasmType)
case .associatedValueEnum:
switch context {
case .importTS:
case .caseEnum, .associatedValueEnum:
if context == .importTS {
throw BridgeJSCoreError("Enum types are not yet supported in TypeScript imports")
case .exportSwift:
return LiftingReturnInfo(valueToLift: .i32)
}
case .swiftStruct:
switch context {
case .importTS:
// Swift structs are bridged as JS objects (object IDs) in imported signatures.
return LiftingReturnInfo(valueToLift: .i32)
case .exportSwift:
return LiftingReturnInfo(valueToLift: nil)
}
case .namespaceEnum:
throw BridgeJSCoreError("Namespace enums cannot be used as return values")
case .nullable(let wrappedType, _):
let wrappedInfo = try wrappedType.liftingReturnInfo(context: context)
return LiftingReturnInfo(valueToLift: wrappedInfo.valueToLift)
case .array, .dictionary:
return LiftingReturnInfo(valueToLift: nil)
fallthrough
default:
return LiftingReturnInfo(valueToLift: descriptor.importReturnType)
}
}
}
Expand Down
14 changes: 3 additions & 11 deletions Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1534,16 +1534,8 @@ public struct BridgeJSLink {
let enumValuesName = enumDefinition.valuesName

switch enumDefinition.enumType {
case .simple:
let fragment = IntrinsicJSFragment.simpleEnumHelper(enumDefinition: enumDefinition)
_ = try fragment.printCode([enumValuesName], context)
jsTopLevelLines.append(contentsOf: printer.lines)
case .rawValue:
guard enumDefinition.rawType != nil else {
throw BridgeJSLinkError(message: "Raw value enum \(enumDefinition.name) is missing rawType")
}

let fragment = IntrinsicJSFragment.rawValueEnumHelper(enumDefinition: enumDefinition)
case .simple, .rawValue:
let fragment = IntrinsicJSFragment.caseEnumHelper(enumDefinition: enumDefinition)
_ = try fragment.printCode([enumValuesName], context)
jsTopLevelLines.append(contentsOf: printer.lines)
case .associatedValue:
Expand Down Expand Up @@ -2172,7 +2164,7 @@ extension BridgeJSLink {
printer.write("} catch (error) {")
printer.indent {
printer.write("setException(error);")
if let abiReturnType = returnType.abiReturnType {
if !returnType.isOptional, let abiReturnType = returnType.descriptor.wasmReturnType {
printer.write("return \(abiReturnType.placeholderValue)")
}
}
Expand Down
Loading