Skip to content
This repository was archived by the owner on Dec 12, 2024. It is now read-only.

Commit bc5af77

Browse files
Merge pull request #443 from xamarin/marshal-protocol
Runtime marshaling of protocols
2 parents a5cad25 + 4d5a01e commit bc5af77

File tree

2 files changed

+102
-1
lines changed

2 files changed

+102
-1
lines changed

SwiftRuntimeLibrary/SwiftMarshal/StructMarshal.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -667,6 +667,9 @@ public IntPtr ToSwift (Type t, object o, IntPtr swiftDestinationMemory)
667667
return swiftDestinationMemory;
668668
}
669669
#endif
670+
if (IsSwiftProtocol (t)) {
671+
return MarshalProtocolToSwift (t, o, swiftDestinationMemory);
672+
}
670673

671674
if (IsSwiftError (t)) {
672675
return MarshalSwiftErrorToSwift ((SwiftError)o, swiftDestinationMemory);
@@ -1083,6 +1086,12 @@ SwiftClosureRepresentation BuildClosureRepresentation (Delegate del, Type [] arg
10831086
}
10841087
}
10851088

1089+
public IntPtr MarshalProtocolToSwift (Type t, object implementsProtocol, IntPtr swiftDestinationMemory)
1090+
{
1091+
var container = SwiftObjectRegistry.Registry.ExistentialContainerForProtocols (implementsProtocol, t);
1092+
return container.CopyTo (swiftDestinationMemory);
1093+
}
1094+
10861095

10871096
public IntPtr MarshalTupleToSwift (Type t, object tuple, IntPtr swiftDestinationMemory)
10881097
{
@@ -1522,7 +1531,9 @@ public void ReleaseSwiftPointer (Type type, IntPtr value)
15221531
return;
15231532
}
15241533
#endif
1525-
1534+
if (IsSwiftProtocol (type)) {
1535+
return;
1536+
}
15261537
throw new SwiftRuntimeException ($"Don't know how to release a swift pointer to {type}.");
15271538
}
15281539

tests/tom-swifty-test/SwiftReflector/NewClassCompilerTests.cs

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1533,6 +1533,96 @@ public func tryMeHere (a:DisposeMeThanks ) -> Int {
15331533

15341534
TestRunning.TestAndExecute (swiftCode, callingCode, "SwiftObject handle is IntPtr.Zero, likely because it was disposed.\n");
15351535
}
1536+
1537+
[Test]
1538+
public void SandwichTest ()
1539+
{
1540+
var swiftCode = @"
1541+
public protocol Filling {
1542+
var stuff: String { get }
1543+
}
1544+
1545+
public protocol Bread {
1546+
var name: String { get }
1547+
var sliced: Bool { get }
1548+
}
1549+
1550+
public struct Rye : Bread {
1551+
public init () { }
1552+
public var name:String {
1553+
get { return ""rye"" }
1554+
}
1555+
public var sliced:Bool {
1556+
get { return true }
1557+
}
1558+
}
1559+
1560+
public struct Ham : Filling {
1561+
public init () { }
1562+
public var stuff: String {
1563+
get { return ""ham"" }
1564+
}
1565+
}
1566+
1567+
public enum LettuceKind {
1568+
case IceBerg, Romaine, Bib
1569+
}
1570+
1571+
public struct Lettuce : Filling {
1572+
private var kind: LettuceKind
1573+
public init (of: LettuceKind) {
1574+
kind = of
1575+
}
1576+
public var stuff: String {
1577+
get {
1578+
return ""\(kindToString ()) lettuce""
1579+
}
1580+
}
1581+
1582+
private func kindToString () -> String {
1583+
switch kind {
1584+
case .IceBerg: return ""iceberg""
1585+
case .Romaine: return ""romaine""
1586+
case .Bib: return ""bib""
1587+
}
1588+
}
1589+
}
1590+
1591+
public func printSandwich (of: Bread, with: Filling) {
1592+
print (""\(with.stuff) on \(of.name)"")
1593+
}
1594+
";
1595+
1596+
var printer = CSFunctionCall.ConsoleWriteLine (CSConstant.Val ("hi"));
1597+
var callingCode = CSCodeBlock.Create (printer);
1598+
1599+
TestRunning.TestAndExecute (swiftCode, callingCode, "hi\n");
1600+
}
1601+
1602+
[Test]
1603+
public void MakeProto ()
1604+
{
1605+
var swiftCode = @"
1606+
public protocol Silly {
1607+
func beSilly ()
1608+
}
1609+
";
1610+
var impl = new CSClass (CSVisibility.Public, "Goof");
1611+
impl.Inheritance.Add (new CSIdentifier ("ISilly"));
1612+
var goofPrinter = CSFunctionCall.ConsoleWriteLine (CSConstant.Val ("here"));
1613+
var method = new CSMethod (CSVisibility.Public, CSMethodKind.None, CSSimpleType.Void, new CSIdentifier ("BeSilly"),
1614+
new CSParameterList (), CSCodeBlock.Create (goofPrinter));
1615+
impl.Methods.Add (method);
1616+
1617+
var arrId = new CSIdentifier ("arr");
1618+
var arrDecl = CSVariableDeclaration.VarLine (arrId, new CSFunctionCall ("SwiftArray<ISilly>", true));
1619+
var add = CSFunctionCall.FunctionCallLine ("arr.Add", false, new CSFunctionCall (impl.Name.Name, true));
1620+
var printer = CSFunctionCall.ConsoleWriteLine (CSConstant.Val ("here"));
1621+
1622+
var callingCode = CSCodeBlock.Create (arrDecl, add, printer);
1623+
1624+
TestRunning.TestAndExecute (swiftCode, callingCode, "here\n", otherClass: impl);
1625+
}
15361626
}
15371627
}
15381628

0 commit comments

Comments
 (0)