Skip to content
Merged
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
22 changes: 11 additions & 11 deletions Benchmarks/Sources/Generated/BridgeJS.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,20 +64,20 @@ extension APIResult: _BridgedSwiftAssociatedValueEnum {
@_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() {
switch self {
case .success(let param0):
_swift_js_push_tag(Int32(0))
param0.bridgeJSLowerStackReturn()
_swift_js_push_tag(Int32(0))
case .failure(let param0):
_swift_js_push_tag(Int32(1))
param0.bridgeJSLowerStackReturn()
_swift_js_push_tag(Int32(1))
case .flag(let param0):
_swift_js_push_tag(Int32(2))
param0.bridgeJSLowerStackReturn()
_swift_js_push_tag(Int32(2))
case .rate(let param0):
_swift_js_push_tag(Int32(3))
param0.bridgeJSLowerStackReturn()
_swift_js_push_tag(Int32(3))
case .precise(let param0):
_swift_js_push_tag(Int32(4))
param0.bridgeJSLowerStackReturn()
_swift_js_push_tag(Int32(4))
case .info:
_swift_js_push_tag(Int32(5))
}
Expand Down Expand Up @@ -161,29 +161,28 @@ extension ComplexResult: _BridgedSwiftAssociatedValueEnum {
@_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() {
switch self {
case .success(let param0):
_swift_js_push_tag(Int32(0))
param0.bridgeJSLowerStackReturn()
_swift_js_push_tag(Int32(0))
case .error(let param0, let param1):
_swift_js_push_tag(Int32(1))
param0.bridgeJSLowerStackReturn()
param1.bridgeJSLowerStackReturn()
_swift_js_push_tag(Int32(1))
case .location(let param0, let param1, let param2):
_swift_js_push_tag(Int32(2))
param0.bridgeJSLowerStackReturn()
param1.bridgeJSLowerStackReturn()
param2.bridgeJSLowerStackReturn()
_swift_js_push_tag(Int32(2))
case .status(let param0, let param1, let param2):
_swift_js_push_tag(Int32(3))
param0.bridgeJSLowerStackReturn()
param1.bridgeJSLowerStackReturn()
param2.bridgeJSLowerStackReturn()
_swift_js_push_tag(Int32(3))
case .coordinates(let param0, let param1, let param2):
_swift_js_push_tag(Int32(4))
param0.bridgeJSLowerStackReturn()
param1.bridgeJSLowerStackReturn()
param2.bridgeJSLowerStackReturn()
_swift_js_push_tag(Int32(4))
case .comprehensive(let param0, let param1, let param2, let param3, let param4, let param5, let param6, let param7, let param8):
_swift_js_push_tag(Int32(5))
param0.bridgeJSLowerStackReturn()
param1.bridgeJSLowerStackReturn()
param2.bridgeJSLowerStackReturn()
Expand All @@ -193,6 +192,7 @@ extension ComplexResult: _BridgedSwiftAssociatedValueEnum {
param6.bridgeJSLowerStackReturn()
param7.bridgeJSLowerStackReturn()
param8.bridgeJSLowerStackReturn()
_swift_js_push_tag(Int32(5))
case .info:
_swift_js_push_tag(Int32(6))
}
Expand Down
4 changes: 3 additions & 1 deletion Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1221,9 +1221,11 @@ struct EnumCodegen {
.map { index, associatedValue in "let \(associatedValue.label ?? "param\(index)")" }
.joined(separator: ", ")
cases.append("case .\(enumCase.name)(\(pattern)):")
cases.append("_swift_js_push_tag(Int32(\(caseIndex)))")
let payloadCode = generatePayloadPushingCode(associatedValues: enumCase.associatedValues)
cases.append(contentsOf: payloadCode)
// Push tag AFTER payloads so it's popped first (LIFO) by the JS lift function.
// This ensures nested enum tags don't overwrite the outer tag.
cases.append("_swift_js_push_tag(Int32(\(caseIndex)))")
}
}
return cases
Expand Down
10 changes: 6 additions & 4 deletions Plugins/BridgeJS/Sources/BridgeJSCore/SwiftToSkeleton.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1428,26 +1428,28 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor {
for enumCase in exportedEnum.cases {
for associatedValue in enumCase.associatedValues {
switch associatedValue.type {
case .string, .int, .float, .double, .bool:
case .string, .int, .float, .double, .bool, .caseEnum, .rawValueEnum,
.swiftStruct, .swiftHeapObject, .jsObject, .associatedValueEnum, .array:
break
case .nullable(let wrappedType, _):
switch wrappedType {
case .string, .int, .float, .double, .bool:
case .string, .int, .float, .double, .bool, .caseEnum, .rawValueEnum,
.swiftStruct, .swiftHeapObject, .jsObject, .associatedValueEnum, .array:
break
default:
diagnose(
node: node,
message: "Unsupported associated value type: \(associatedValue.type.swiftType)",
hint:
"Only primitive types and optional primitives (String?, Int?, Float?, Double?, Bool?) are supported in associated-value enums"
"Only primitive types, enums, structs, classes, JSObject, arrays, and their optionals are supported in associated-value enums"
)
}
default:
diagnose(
node: node,
message: "Unsupported associated value type: \(associatedValue.type.swiftType)",
hint:
"Only primitive types and optional primitives (String?, Int?, Float?, Double?, Bool?) are supported in associated-value enums"
"Only primitive types, enums, structs, classes, JSObject, arrays, and their optionals are supported in associated-value enums"
)
}
}
Expand Down
29 changes: 20 additions & 9 deletions Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ public struct BridgeJSLink {
"let \(JSGlueVariableScope.reservedStorageToReturnOptionalFloat);",
"let \(JSGlueVariableScope.reservedStorageToReturnOptionalDouble);",
"let \(JSGlueVariableScope.reservedStorageToReturnOptionalHeapObject);",
"let \(JSGlueVariableScope.reservedTmpRetTag);",
"let \(JSGlueVariableScope.reservedTmpRetTag) = [];",
"let \(JSGlueVariableScope.reservedTmpRetStrings) = [];",
"let \(JSGlueVariableScope.reservedTmpRetInts) = [];",
"let \(JSGlueVariableScope.reservedTmpRetF32s) = [];",
Expand Down Expand Up @@ -388,7 +388,7 @@ public struct BridgeJSLink {
printer.write("}")
printer.write("bjs[\"swift_js_push_tag\"] = function(tag) {")
printer.indent {
printer.write("\(JSGlueVariableScope.reservedTmpRetTag) = tag;")
printer.write("\(JSGlueVariableScope.reservedTmpRetTag).push(tag);")
}
printer.write("}")
printer.write("bjs[\"swift_js_push_i32\"] = function(v) {")
Expand Down Expand Up @@ -1059,6 +1059,18 @@ public struct BridgeJSLink {
_ = fragment.printCode([structDef.name], structScope, structPrinter, structCleanup)
bodyPrinter.write(lines: structPrinter.lines)
}

let allAssocEnums = exportedSkeletons.flatMap {
$0.enums.filter { $0.enumType == .associatedValue }
}
for enumDef in allAssocEnums {
let enumPrinter = CodeFragmentPrinter()
let enumScope = JSGlueVariableScope()
let enumCleanup = CodeFragmentPrinter()
let fragment = IntrinsicJSFragment.associatedValueEnumHelperFactory(enumDefinition: enumDef)
_ = fragment.printCode([enumDef.valuesName], enumScope, enumPrinter, enumCleanup)
bodyPrinter.write(lines: enumPrinter.lines)
}
bodyPrinter.nextLine()
bodyPrinter.write(contentsOf: generateAddImports(needsImportsObject: data.needsImportsObject))

Expand Down Expand Up @@ -1094,8 +1106,6 @@ public struct BridgeJSLink {
"\(JSGlueVariableScope.reservedMemory) = \(JSGlueVariableScope.reservedInstance).exports.memory;",
])
printer.nextLine()
// Enum helpers section
printer.write(contentsOf: enumHelperAssignments())
// Error handling
printer.write("\(JSGlueVariableScope.reservedSetException) = (error) => {")
printer.indent {
Expand All @@ -1109,18 +1119,19 @@ public struct BridgeJSLink {
}

// createExports method
try printer.indent {
printer.indent {
printer.write(lines: [
"/** @param {WebAssembly.Instance} instance */",
"createExports: (instance) => {",
])
try printer.indent {
printer.indent {
printer.write("const js = \(JSGlueVariableScope.reservedSwift).memory.heap;")

printer.write(lines: data.classLines)

// Struct helpers must be initialized AFTER classes are defined (to allow _exports access)
// Struct and enum helpers must be initialized AFTER classes are defined (to allow _exports access)
printer.write(contentsOf: structHelperAssignments())
printer.write(contentsOf: enumHelperAssignments())
let namespaceInitCode = namespaceBuilder.buildNamespaceInitialization(
exportedSkeletons: exportedSkeletons
)
Expand Down Expand Up @@ -1151,7 +1162,7 @@ public struct BridgeJSLink {
for skeleton in skeletons.compactMap(\.exported) {
for enumDef in skeleton.enums where enumDef.enumType == .associatedValue {
printer.write(
"const \(enumDef.name)Helpers = __bjs_create\(enumDef.valuesName)Helpers()(\(JSGlueVariableScope.reservedTmpParamInts), \(JSGlueVariableScope.reservedTmpParamF32s), \(JSGlueVariableScope.reservedTmpParamF64s), \(JSGlueVariableScope.reservedTextEncoder), \(JSGlueVariableScope.reservedSwift));"
"const \(enumDef.name)Helpers = __bjs_create\(enumDef.valuesName)Helpers()(\(JSGlueVariableScope.reservedTmpParamInts), \(JSGlueVariableScope.reservedTmpParamF32s), \(JSGlueVariableScope.reservedTmpParamF64s), \(JSGlueVariableScope.reservedTmpParamPointers), \(JSGlueVariableScope.reservedTmpRetPointers), \(JSGlueVariableScope.reservedTextEncoder), \(JSGlueVariableScope.reservedSwift), \(JSGlueVariableScope.reservedStructHelpers), \(JSGlueVariableScope.reservedEnumHelpers));"
)
printer.write("\(JSGlueVariableScope.reservedEnumHelpers).\(enumDef.name) = \(enumDef.name)Helpers;")
printer.nextLine()
Expand Down Expand Up @@ -1616,7 +1627,7 @@ public struct BridgeJSLink {
_ = fragment.printCode([enumValuesName], scope, printer, cleanup)
jsTopLevelLines.append(contentsOf: printer.lines)
case .associatedValue:
let fragment = IntrinsicJSFragment.associatedValueEnumHelper(enumDefinition: enumDefinition)
let fragment = IntrinsicJSFragment.associatedValueEnumValues(enumDefinition: enumDefinition)
_ = fragment.printCode([enumValuesName], scope, printer, cleanup)
jsTopLevelLines.append(contentsOf: printer.lines)
case .namespace:
Expand Down
Loading