@@ -348,6 +348,45 @@ struct CdeclLowering {
348348 case . composite :
349349 throw LoweringError . unhandledType ( type )
350350
351+ case . array ( let wrapped ) where wrapped == knownTypes . uint8 :
352+ // Lower an array as 'address' raw pointer and 'count' integer
353+ let cdeclParameters = [
354+ SwiftParameter (
355+ convention : . byValue ,
356+ parameterName : " \( parameterName ) _pointer " ,
357+ type : knownTypes . unsafeRawPointer
358+ ) ,
359+ SwiftParameter (
360+ convention : . byValue ,
361+ parameterName : " \( parameterName ) _count " ,
362+ type : knownTypes . int
363+ ) ,
364+ ]
365+
366+ let bufferPointerInit = ConversionStep . initialize (
367+ knownTypes . unsafeRawBufferPointer ,
368+ arguments : [
369+ LabeledArgument (
370+ label : " start " ,
371+ argument : . explodedComponent ( . placeholder , component : " pointer " )
372+ ) ,
373+ LabeledArgument (
374+ label : " count " ,
375+ argument : . explodedComponent ( . placeholder , component : " count " )
376+ ) ,
377+ ]
378+ )
379+
380+ let arrayInit = ConversionStep . initialize (
381+ type ,
382+ arguments : [ LabeledArgument ( argument : bufferPointerInit ) ]
383+ )
384+
385+ return LoweredParameter (
386+ cdeclParameters : cdeclParameters ,
387+ conversion : arrayInit
388+ )
389+
351390 case . array :
352391 throw LoweringError . unhandledType ( type )
353392 }
@@ -525,6 +564,24 @@ struct CdeclLowering {
525564 }
526565 }
527566
567+ /// Create "out" parameter names when we're returning an array-like result.
568+ fileprivate func makeBufferIndirectReturnParameters ( _ outParameterName : String , isMutable : Bool ) -> [ SwiftParameter ] {
569+ [
570+ SwiftParameter (
571+ convention : . byValue ,
572+ parameterName : " \( outParameterName ) _pointer " ,
573+ type : knownTypes . unsafeMutablePointer (
574+ . optional ( isMutable ? knownTypes . unsafeMutableRawPointer : knownTypes . unsafeRawPointer )
575+ )
576+ ) ,
577+ SwiftParameter (
578+ convention : . byValue ,
579+ parameterName : " \( outParameterName ) _count " ,
580+ type : knownTypes . unsafeMutablePointer ( knownTypes . int )
581+ ) ,
582+ ]
583+ }
584+
528585 /// Lower a Swift result type to cdecl out parameters and return type.
529586 ///
530587 /// - Parameters:
@@ -580,20 +637,7 @@ struct CdeclLowering {
580637 let isMutable = knownType == . unsafeMutableRawBufferPointer
581638 return LoweredResult (
582639 cdeclResultType : . void ,
583- cdeclOutParameters : [
584- SwiftParameter (
585- convention : . byValue ,
586- parameterName : " \( outParameterName ) _pointer " ,
587- type : knownTypes . unsafeMutablePointer (
588- . optional ( isMutable ? knownTypes . unsafeMutableRawPointer : knownTypes . unsafeRawPointer )
589- )
590- ) ,
591- SwiftParameter (
592- convention : . byValue ,
593- parameterName : " \( outParameterName ) _count " ,
594- type : knownTypes . unsafeMutablePointer ( knownTypes . int )
595- ) ,
596- ] ,
640+ cdeclOutParameters : makeBufferIndirectReturnParameters ( outParameterName , isMutable : isMutable ) ,
597641 conversion : . aggregate ( [
598642 . populatePointer (
599643 name : " \( outParameterName ) _pointer " ,
@@ -672,6 +716,37 @@ struct CdeclLowering {
672716 cdeclOutParameters : parameters ,
673717 conversion : . tupleExplode ( conversions , name : outParameterName )
674718 )
719+
720+ case . array ( let wrapped ) where wrapped == knownTypes . uint8 :
721+ let resultName = " _result "
722+
723+ return LoweredResult (
724+ cdeclResultType : . void , // we call into the _result_initialize instead
725+ cdeclOutParameters : [
726+ SwiftParameter (
727+ convention : . byValue ,
728+ parameterName : " \( outParameterName ) _initialize " ,
729+ type : knownTypes . functionInitializeByteBuffer
730+ )
731+ ] ,
732+ conversion : . aggregate ( [
733+ . method ( base : resultName , methodName : " withUnsafeBufferPointer " , arguments : [
734+ . init ( argument :
735+ . closureLowering (
736+ parameters : [ . placeholder ] ,
737+ result : . method (
738+ base : " \( outParameterName ) _initialize " ,
739+ methodName : nil , // just `(...)` apply the closure
740+ arguments : [
741+ . init ( label : nil , argument : . member ( . constant ( " _0 " ) , member : " baseAddress! " ) ) ,
742+ . init ( label : nil , argument : . member ( . constant ( " _0 " ) , member : " count " ) ) ,
743+ ]
744+ )
745+ )
746+ )
747+ ] )
748+ ] , name : resultName )
749+ )
675750
676751 case . genericParameter , . function , . optional , . existential , . opaque , . composite , . array :
677752 throw LoweringError . unhandledType ( type )
0 commit comments