-
Notifications
You must be signed in to change notification settings - Fork 38
[jextract] Improve Cdecl lowering #238
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@@ -103,38 +76,30 @@ enum ConversionStep: Equatable { | |||
|
|||
/// Convert the conversion step into an expression with the given | |||
/// value as the placeholder value in the expression. | |||
func asExprSyntax(isSelf: Bool, placeholder: String) -> ExprSyntax { | |||
func asExprSyntax(placeholder: String, bodyItems: inout [CodeBlockItemSyntax]) -> ExprSyntax? { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using bodyItems
, ConversionStep
can now introduce side effects, for example it can store the inner step into a variable, then return the DeclReferenceExprSyntax
to it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks fantastic, thank you!
/// providing all of the mappings between the parameter and result types | ||
/// of the original function and its `@_cdecl` counterpart. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Total nit, but there's no parameter or result type for a variable, just the type itself.
if let generics = node.genericParameterClause { | ||
throw SwiftFunctionTranslationError.generic(generics) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for making it defensive like this
hasGetter = true | ||
case .keyword(.set), .keyword(._modify), .keyword(.unsafeMutableAddress): | ||
hasSetter = true | ||
default: // Ignore willSet/didSet and unknown accessors. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
willSet/didSet imply that we have both getter and setter, don't they?
switch (hasGetter, hasSetter) { | ||
case (true, true): return [.get, .set] | ||
case (true, false): return [.get] | ||
case (false, true): return [.set] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Technically, this case is unreachable in well-formed code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ohh, I didn't know setter only variables are prohibited in Swift 😅
expectedCDecl: """ | ||
@_cdecl("c_takeString") | ||
public func c_takeString(_ str: UnsafePointer<Int8>) { | ||
takeString(str: String(cString: str)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very useful, thank you!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great! Lgtm
* Newly introduce `lowerResult()` (splitted from `lowerParameter()` because result lowering can be differnt from parameter lowering. * Remove `ConversionStep.init(cdeclToSwift:)/.init(swiftToCdecl:)`. Instead embed the logic in `lowerParameter()`/`lowerResult()` so that we can implement type lowering and the actual conversion at the same place. * Support 'String', 'Void' and '() -> Void) types * Implement getter / setter lowering * Fix conversion for tuple returns (see: `lowerTupleReturns()` test) * Reference types are now returned indirectly, as the logic are being unifed. Thanks to this we don't need manual `retain()` before returning instances, which wasn't implemented correctly.
01b8081
to
bcd5e0e
Compare
Part of #236 with some test cases.
Cdecl lowering improvements without integrating into the actual workflow.
lowerResult()
(splitted fromlowerParameter()
because result lowering can be differnt from parameter lowering.ConversionStep.init(cdeclToSwift:)/.init(swiftToCdecl:)
. Instead embed the logic inlowerParameter()
/lowerResult()
so that we can implement type lowering and the actual conversion at the same place.lowerTupleReturns()
test)retain()
before returning instances, which wasn't implemented correctly.