Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
77 changes: 39 additions & 38 deletions Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift
Original file line number Diff line number Diff line change
Expand Up @@ -261,19 +261,19 @@ public struct BridgeJSLink {
]
}

private func generateAddImports(needsImportsObject: Bool) -> CodeFragmentPrinter {
private func generateAddImports(needsImportsObject: Bool) throws -> CodeFragmentPrinter {
let printer = CodeFragmentPrinter()
let allStructs = skeletons.compactMap { $0.exported?.structs }.flatMap { $0 }
printer.write("return {")
printer.indent {
try printer.indent {
printer.write(lines: [
"/**",
" * @param {WebAssembly.Imports} importObject",
" */",
"addImports: (importObject, importsContext) => {",
])

printer.indent {
try printer.indent {
printer.write(lines: [
"bjs = {};",
"importObject[\"bjs\"] = bjs;",
Expand Down Expand Up @@ -687,20 +687,21 @@ public struct BridgeJSLink {

for signature in closureSignatures.sorted(by: { $0.mangleName < $1.mangleName }) {
let invokeFuncName = "invoke_js_callback_\(moduleName)_\(signature.mangleName)"
printer.write(
lines: generateInvokeFunction(
signature: signature,
functionName: invokeFuncName
)
let invokeLines = try generateInvokeFunction(
signature: signature,
functionName: invokeFuncName
)
printer.write(lines: invokeLines)

let lowerFuncName = "lower_closure_\(moduleName)_\(signature.mangleName)"
let makeFuncName = "make_swift_closure_\(moduleName)_\(signature.mangleName)"
printer.write("bjs[\"\(makeFuncName)\"] = function(boxPtr, file, line) {")
printer.indent {
printer.write(
lines: generateLowerClosureFunction(signature: signature, functionName: lowerFuncName)
try printer.indent {
let lowerLines = try generateLowerClosureFunction(
signature: signature,
functionName: lowerFuncName
)
printer.write(lines: lowerLines)
printer.write(
"return \(JSGlueVariableScope.reservedMakeSwiftClosure)(boxPtr, file, line, \(lowerFuncName));"
)
Expand Down Expand Up @@ -788,7 +789,7 @@ public struct BridgeJSLink {
private func generateInvokeFunction(
signature: ClosureSignature,
functionName: String
) -> [String] {
) throws -> [String] {
let printer = CodeFragmentPrinter()
let scope = JSGlueVariableScope(intrinsicRegistry: intrinsicRegistry)
let cleanupCode = CodeFragmentPrinter()
Expand All @@ -806,20 +807,20 @@ public struct BridgeJSLink {

printer.nextLine()
printer.write("bjs[\"\(functionName)\"] = function(\(invokeParams.joined(separator: ", "))) {")
printer.indent {
try printer.indent {
printer.write("try {")
printer.indent {
try printer.indent {
printer.write("const callback = \(JSGlueVariableScope.reservedSwift).memory.getObject(callbackId);")

for (index, paramType) in signature.parameters.enumerated() {
let fragment = try! IntrinsicJSFragment.closureLiftParameter(type: paramType)
let fragment = try IntrinsicJSFragment.closureLiftParameter(type: paramType)
let args: [String]
if case .nullable = paramType {
args = ["param\(index)IsSome", "param\(index)Value", "param\(index)"]
} else {
args = ["param\(index)Id", "param\(index)"]
}
_ = fragment.printCode(args, scope, printer, cleanupCode)
_ = try fragment.printCode(args, scope, printer, cleanupCode)
}

let callbackParams = signature.parameters.indices.map { "param\($0)" }.joined(separator: ", ")
Expand All @@ -837,14 +838,14 @@ public struct BridgeJSLink {
break
}

let returnFragment = try! IntrinsicJSFragment.closureLowerReturn(type: signature.returnType)
_ = returnFragment.printCode(["result"], scope, printer, cleanupCode)
let returnFragment = try IntrinsicJSFragment.closureLowerReturn(type: signature.returnType)
_ = try returnFragment.printCode(["result"], scope, printer, cleanupCode)
}
printer.write("} catch (error) {")
printer.indent {
try printer.indent {
printer.write("\(JSGlueVariableScope.reservedSetException)?.(error);")
let errorFragment = IntrinsicJSFragment.closureErrorReturn(type: signature.returnType)
_ = errorFragment.printCode([], scope, printer, cleanupCode)
_ = try errorFragment.printCode([], scope, printer, cleanupCode)
}
printer.write("}")
}
Expand All @@ -857,21 +858,21 @@ public struct BridgeJSLink {
private func generateLowerClosureFunction(
signature: ClosureSignature,
functionName: String
) -> [String] {
) throws -> [String] {
let printer = CodeFragmentPrinter()
let scope = JSGlueVariableScope(intrinsicRegistry: intrinsicRegistry)
let cleanupCode = CodeFragmentPrinter()

printer.write(
"const \(functionName) = function(\(signature.parameters.indices.map { "param\($0)" }.joined(separator: ", "))) {"
)
printer.indent {
try printer.indent {
var invokeArgs: [String] = ["boxPtr"]

for (index, paramType) in signature.parameters.enumerated() {
let paramName = "param\(index)"
let fragment = try! IntrinsicJSFragment.lowerParameter(type: paramType)
let lowered = fragment.printCode([paramName], scope, printer, cleanupCode)
let fragment = try IntrinsicJSFragment.lowerParameter(type: paramType)
let lowered = try fragment.printCode([paramName], scope, printer, cleanupCode)
invokeArgs.append(contentsOf: lowered)
}

Expand All @@ -894,8 +895,8 @@ public struct BridgeJSLink {
}
printer.write("}")

let returnFragment = try! IntrinsicJSFragment.closureLiftReturn(type: signature.returnType)
_ = returnFragment.printCode([invokeResultName], scope, printer, cleanupCode)
let returnFragment = try IntrinsicJSFragment.closureLiftReturn(type: signature.returnType)
_ = try returnFragment.printCode([invokeResultName], scope, printer, cleanupCode)
}
printer.write("};")

Expand Down Expand Up @@ -1073,7 +1074,7 @@ public struct BridgeJSLink {
// Main function declaration
printer.write("export async function createInstantiator(options, \(JSGlueVariableScope.reservedSwift)) {")

printer.indent {
try printer.indent {
printer.write(lines: generateVariableDeclarations())

let bodyPrinter = CodeFragmentPrinter()
Expand All @@ -1083,7 +1084,7 @@ public struct BridgeJSLink {
let structScope = JSGlueVariableScope(intrinsicRegistry: intrinsicRegistry)
let structCleanup = CodeFragmentPrinter()
let fragment = IntrinsicJSFragment.structHelper(structDefinition: structDef, allStructs: allStructs)
_ = fragment.printCode([structDef.name], structScope, structPrinter, structCleanup)
_ = try fragment.printCode([structDef.name], structScope, structPrinter, structCleanup)
bodyPrinter.write(lines: structPrinter.lines)
}

Expand All @@ -1095,11 +1096,11 @@ public struct BridgeJSLink {
let enumScope = JSGlueVariableScope(intrinsicRegistry: intrinsicRegistry)
let enumCleanup = CodeFragmentPrinter()
let fragment = IntrinsicJSFragment.associatedValueEnumHelperFactory(enumDefinition: enumDef)
_ = fragment.printCode([enumDef.valuesName], enumScope, enumPrinter, enumCleanup)
_ = try fragment.printCode([enumDef.valuesName], enumScope, enumPrinter, enumCleanup)
bodyPrinter.write(lines: enumPrinter.lines)
}
bodyPrinter.nextLine()
bodyPrinter.write(contentsOf: generateAddImports(needsImportsObject: data.needsImportsObject))
bodyPrinter.write(contentsOf: try generateAddImports(needsImportsObject: data.needsImportsObject))

if !intrinsicRegistry.isEmpty {
printer.write(lines: intrinsicRegistry.emitLines())
Expand Down Expand Up @@ -1356,7 +1357,7 @@ public struct BridgeJSLink {
loweringFragment.parameters.count == 1,
"Lowering fragment should have exactly one parameter to lower"
)
let loweredValues = loweringFragment.printCode([param.name], scope, body, cleanupCode)
let loweredValues = try loweringFragment.printCode([param.name], scope, body, cleanupCode)
parameterForwardings.append(contentsOf: loweredValues)
}

Expand Down Expand Up @@ -1388,7 +1389,7 @@ public struct BridgeJSLink {
body.write("const \(returnVariable) = \(call);")
fragmentArguments = [returnVariable]
}
let liftedValues = liftingFragment.printCode(fragmentArguments, scope, body, cleanupCode)
let liftedValues = try liftingFragment.printCode(fragmentArguments, scope, body, cleanupCode)
assert(liftedValues.count <= 1, "Lifting fragment should produce at most one value")
return liftedValues.first
}
Expand Down Expand Up @@ -1646,19 +1647,19 @@ public struct BridgeJSLink {
switch enumDefinition.enumType {
case .simple:
let fragment = IntrinsicJSFragment.simpleEnumHelper(enumDefinition: enumDefinition)
_ = fragment.printCode([enumValuesName], scope, printer, cleanup)
_ = try fragment.printCode([enumValuesName], scope, printer, cleanup)
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)
_ = fragment.printCode([enumValuesName], scope, printer, cleanup)
_ = try fragment.printCode([enumValuesName], scope, printer, cleanup)
jsTopLevelLines.append(contentsOf: printer.lines)
case .associatedValue:
let fragment = IntrinsicJSFragment.associatedValueEnumValues(enumDefinition: enumDefinition)
_ = fragment.printCode([enumValuesName], scope, printer, cleanup)
_ = try fragment.printCode([enumValuesName], scope, printer, cleanup)
jsTopLevelLines.append(contentsOf: printer.lines)
case .namespace:
break
Expand Down Expand Up @@ -2252,7 +2253,7 @@ extension BridgeJSLink {
valuesToLift = liftingFragment.parameters.map { scope.variable(param.name + $0.capitalizedFirstLetter) }
parameterNames.append(contentsOf: valuesToLift)
}
let liftedValues = liftingFragment.printCode(valuesToLift, scope, body, cleanupCode)
let liftedValues = try liftingFragment.printCode(valuesToLift, scope, body, cleanupCode)
assert(liftedValues.count == 1, "Lifting fragment should produce exactly one value")
parameterForwardings.append(contentsOf: liftedValues)
}
Expand Down Expand Up @@ -2362,7 +2363,7 @@ extension BridgeJSLink {
)

let fragment = try IntrinsicJSFragment.protocolPropertyOptionalToSideChannel(wrappedType: wrappedType)
_ = fragment.printCode([resultVar], scope, body, cleanupCode)
_ = try fragment.printCode([resultVar], scope, body, cleanupCode)

return nil // Side-channel types return nil (no direct return value)
}
Expand Down Expand Up @@ -2415,7 +2416,7 @@ extension BridgeJSLink {
loweringFragment: IntrinsicJSFragment
) throws -> String? {
assert(loweringFragment.parameters.count <= 1, "Lowering fragment should have at most one parameter")
let loweredValues = loweringFragment.printCode(returnExpr.map { [$0] } ?? [], scope, body, cleanupCode)
let loweredValues = try loweringFragment.printCode(returnExpr.map { [$0] } ?? [], scope, body, cleanupCode)
assert(loweredValues.count <= 1, "Lowering fragment should produce at most one value")
return loweredValues.first
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ final class JSIntrinsicRegistry {
entries.isEmpty
}

func register(name: String, build: (CodeFragmentPrinter) -> Void) {
func register(name: String, build: (CodeFragmentPrinter) throws -> Void) rethrows {
guard entries[name] == nil else { return }
let printer = CodeFragmentPrinter()
build(printer)
try build(printer)
entries[name] = printer.lines
}

Expand Down
Loading
Loading