-
Notifications
You must be signed in to change notification settings - Fork 206
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Swift language feature] Implement
Swift.String
wrapper in C# (#2983)
* Implement Swift.String in C# * Update src/Swift.Runtime/src/Swift/SwiftString.cs Co-authored-by: Vitek Karas <[email protected]> * Remove unnecessary GCHandle * Add PInvoke prefix * Add more tests * Use function pointer for callback to marshall string * Fix formatting * Update src/Swift.Runtime/src/Swift/SwiftString.cs Co-authored-by: Jan Kotas <[email protected]> * Update src/Swift.Runtime/src/Swift/SwiftString.cs Co-authored-by: Jan Kotas <[email protected]> * Use ref type for the ToStringCallbackContext to take unmanaged pointer * Fix formatting --------- Co-authored-by: Vitek Karas <[email protected]> Co-authored-by: Jan Kotas <[email protected]>
- Loading branch information
1 parent
0a268a0
commit 4364aa8
Showing
12 changed files
with
460 additions
and
85 deletions.
There are no files selected for viewing
195 changes: 195 additions & 0 deletions
195
src/Swift.Bindings/tests/IntegrationTests/FunctionalTests/Runtime/RuntimeTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,195 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License. | ||
|
||
using System.Diagnostics; | ||
using System.Runtime.CompilerServices; | ||
using System.Runtime.InteropServices; | ||
using System.Runtime.InteropServices.Swift; | ||
using BindingsGeneration.Tests; | ||
using Swift; | ||
using Swift.Runtime; | ||
using Swift.Runtime.InteropServices; | ||
using Xunit; | ||
|
||
using Bindings = Swift.RuntimeTests; | ||
|
||
|
||
namespace BindingsGeneration.FunctionalTests | ||
{ | ||
public class RuntimeTests : IClassFixture<RuntimeTests.TestFixture> | ||
{ | ||
private readonly TestFixture _fixture; | ||
|
||
public RuntimeTests(TestFixture fixture) | ||
{ | ||
_fixture = fixture; | ||
} | ||
|
||
public class TestFixture | ||
{ | ||
static TestFixture() | ||
{ | ||
InitializeResources(); | ||
} | ||
|
||
private static void InitializeResources() | ||
{ | ||
// Initialize | ||
} | ||
} | ||
|
||
[Fact] | ||
public void SmokeTestArray() | ||
{ | ||
var array = GetArray(3); | ||
Assert.Equal(3, array.Count); | ||
Assert.Equal(0, array[0]); | ||
Assert.Equal(1, array[1]); | ||
Assert.Equal(2, array[2]); | ||
Assert.Equal(3, SumArray(array)); | ||
} | ||
|
||
[Fact] | ||
public void TestEmptyArray() | ||
{ | ||
var array = GetArray(0); | ||
Assert.Equal(0, array.Count); | ||
Assert.Equal(0, SumArray(array)); | ||
} | ||
|
||
[Fact] | ||
public void TestOneElementArray() | ||
{ | ||
var array = GetArray(1); | ||
Assert.Equal(1, array.Count); | ||
Assert.Equal(0, array[0]); | ||
Assert.Equal(0, SumArray(array)); | ||
} | ||
|
||
[Fact] | ||
public void TestBigArray() | ||
{ | ||
var array = GetArray(10000); | ||
Assert.Equal(10000, array.Count); | ||
var sum = 0; | ||
for (int i = 0; i < 10000; i++) | ||
{ | ||
Assert.Equal(i, array[i]); | ||
sum += i; | ||
} | ||
Assert.Equal(sum, SumArray(array)); | ||
} | ||
|
||
// TODO: Remove helper methods when https://github.com/dotnet/runtimelab/issues/2970 | ||
private static unsafe SwiftArray<int> GetArray(int count) | ||
{ | ||
ArrayBuffer buffer = PInvoke_GetArray(count); | ||
return SwiftMarshal.MarshalFromSwift<SwiftArray<int>>((SwiftHandle)new IntPtr(&buffer)); | ||
} | ||
|
||
[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvSwift) })] | ||
[DllImport("Runtime/libRuntimeTests.dylib", EntryPoint = "$s12RuntimeTests8getArray5countSays5Int32VGAE_tF")] | ||
private static extern ArrayBuffer PInvoke_GetArray(int count); | ||
|
||
private static unsafe int SumArray(SwiftArray<int> array) | ||
{ | ||
ArrayBuffer buffer = new ArrayBuffer(); | ||
SwiftMarshal.MarshalToSwift<SwiftArray<int>>(array, new IntPtr(&buffer)); | ||
return PInvoke_SumArray(buffer); | ||
} | ||
|
||
[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvSwift) })] | ||
[DllImport("Runtime/libRuntimeTests.dylib", EntryPoint = "$s12RuntimeTests8sumArray5arrays5Int32VSayAEG_tF")] | ||
private static extern int PInvoke_SumArray(ArrayBuffer array); | ||
|
||
[Fact] | ||
public void SmokeTestSet() | ||
{ | ||
var set = GetSet(3); | ||
Assert.Equal(3, set.Count); | ||
Assert.Equal(3, SumSet(set)); | ||
} | ||
|
||
[Fact] | ||
public void TestEmptySet() | ||
{ | ||
var set = GetSet(0); | ||
Assert.Equal(0, set.Count); | ||
Assert.Equal(0, SumSet(set)); | ||
} | ||
|
||
[Fact] | ||
public void TestOneElementSet() | ||
{ | ||
var set = GetSet(1); | ||
Assert.Equal(1, set.Count); | ||
Assert.Equal(0, SumSet(set)); | ||
} | ||
|
||
[Fact] | ||
public void TestBigSet() | ||
{ | ||
var set = GetSet(10000); | ||
Assert.Equal(10000, set.Count); | ||
Assert.Equal(49995000, SumSet(set)); | ||
|
||
} | ||
|
||
// TODO: Remove helper methods when https://github.com/dotnet/runtimelab/issues/2970 | ||
private static unsafe SwiftSet<SwiftIntMock> GetSet(int count) | ||
{ | ||
Variant variant = PInvoke_GetSet(count); | ||
return SwiftMarshal.MarshalFromSwift<SwiftSet<SwiftIntMock>>((SwiftHandle)new IntPtr(&variant)); | ||
} | ||
|
||
private static unsafe int SumSet(SwiftSet<SwiftIntMock> set) | ||
{ | ||
Variant variant = new Variant(); | ||
SwiftMarshal.MarshalToSwift<SwiftSet<SwiftIntMock>>(set, new IntPtr(&variant)); | ||
return PInvoke_SumSet(variant); | ||
} | ||
|
||
[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvSwift) })] | ||
[DllImport("Runtime/libRuntimeTests.dylib", EntryPoint = "$s12RuntimeTests8getArray5countSays5Int32VGAE_tF")] | ||
private static extern Variant PInvoke_GetSet(int count); | ||
|
||
[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvSwift) })] | ||
[DllImport("Runtime/libRuntimeTests.dylib", EntryPoint = "$s12RuntimeTests8sumArray5arrays5Int32VSayAEG_tF")] | ||
private static extern int PInvoke_SumSet(Variant set); | ||
|
||
[Fact] | ||
public void SmokeTestString() | ||
{ | ||
var str = Bindings.RuntimeTests.getString(3); | ||
Assert.Equal(3, str.Length); | ||
Assert.Equal("aaa", str.ToString()); | ||
} | ||
|
||
[Fact] | ||
public void TestEmptyString() | ||
{ | ||
var str = Bindings.RuntimeTests.getString(0); | ||
Assert.Equal(0, str.Length); | ||
Assert.Equal(string.Empty, str.ToString()); | ||
Assert.Equal(str.Length, Bindings.RuntimeTests.verifyString(str)); | ||
} | ||
|
||
[Fact] | ||
public void TestOneElementString() | ||
{ | ||
var str = Bindings.RuntimeTests.getString(1); | ||
Assert.Equal(1, str.Length); | ||
Assert.Equal("a", str.ToString()); | ||
Assert.Equal(str.Length, Bindings.RuntimeTests.verifyString(str)); | ||
} | ||
|
||
[Fact] | ||
public void TestBigString() | ||
{ | ||
var str = Bindings.RuntimeTests.getString(10000); | ||
Assert.Equal(10000, str.Length); | ||
Assert.Equal(new string('a', 10000), str.ToString()); | ||
Assert.Equal(str.Length, Bindings.RuntimeTests.verifyString(str)); | ||
} | ||
} | ||
} |
27 changes: 27 additions & 0 deletions
27
src/Swift.Bindings/tests/IntegrationTests/FunctionalTests/Runtime/RuntimeTests.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License. | ||
|
||
import Foundation | ||
|
||
public func getArray(count: Int32) -> Array<Int32> { | ||
var array = Array<Int32>() | ||
for i in 0..<count { | ||
array.append(i) | ||
} | ||
return array | ||
} | ||
|
||
public func sumArray(array: Array<Int32>) -> Int32 | ||
{ | ||
return array.reduce(0, +) | ||
} | ||
|
||
public func getString(count: Int32) -> String { | ||
return String(repeating: "a", count: Int(count)) | ||
} | ||
|
||
public func verifyString(str: String) -> Int32 { | ||
let count = str.count | ||
return str.allSatisfy { $0 == "a" } ? Int32(count) : -1 | ||
} | ||
|
3 changes: 3 additions & 0 deletions
3
...ests/FunctionalTests/Structs/TestTypes.cs → ...ests/FunctionalTests/Runtime/TestTypes.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,6 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License. | ||
|
||
using Swift; | ||
using Swift.Runtime; | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
/// <summary> | ||
/// Represents Foundation.Data type. | ||
/// </summary> | ||
|
||
// TODO: https://github.com/dotnet/runtimelab/issues/2992 | ||
public struct Data | ||
{ | ||
private long _flags; | ||
private IntPtr _object; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.