Skip to content

Commit 1d1cd67

Browse files
committed
Made copy by value only work for Kythera-specific code
1 parent a9518ce commit 1d1cd67

File tree

4 files changed

+36
-77
lines changed

4 files changed

+36
-77
lines changed

src/Generator/Generators/CSharp/CSharpMarshal.cs

Lines changed: 36 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -768,41 +768,54 @@ private void MarshalRefClass(Class @class)
768768
{
769769
if (Context.Parameter.IsIndirect)
770770
{
771-
Method cctor = @class.HasNonTrivialCopyConstructor ? @class.Methods.First(c => c.IsCopyConstructor) : null;
772-
if (cctor != null && cctor.IsGenerated)
771+
// Kythera-specific classes.
772+
if (@class.Namespace.Name == "Kyt")
773773
{
774-
Context.Before.WriteLine($"if (ReferenceEquals({Context.Parameter.Name}, null))");
775-
Context.Before.WriteLineIndent(
776-
$@"throw new global::System.ArgumentNullException(""{
777-
Context.Parameter.Name}"", ""Cannot be null because it is passed by value."");");
774+
Method cctor = @class.HasNonTrivialCopyConstructor ? @class.Methods.First(c => c.IsCopyConstructor) : null;
775+
if (cctor != null && cctor.IsGenerated)
776+
{
777+
Context.Before.WriteLine($"if (ReferenceEquals({Context.Parameter.Name}, null))");
778+
Context.Before.WriteLineIndent(
779+
$@"throw new global::System.ArgumentNullException(""{
780+
Context.Parameter.Name}"", ""Cannot be null because it is passed by value."");");
778781

779-
var nativeClass = typePrinter.PrintNative(@class);
782+
var nativeClass = typePrinter.PrintNative(@class);
780783

781-
var cctorName = CSharpSources.GetFunctionNativeIdentifier(Context.Context, cctor);
784+
var cctorName = CSharpSources.GetFunctionNativeIdentifier(Context.Context, cctor);
782785

783-
var defaultValue = "";
784-
var TypePrinter = new CSharpTypePrinter(Context.Context);
785-
var ExpressionPrinter = new CSharpExpressionPrinter(TypePrinter);
786-
if (cctor.Parameters.Count > 1)
787-
defaultValue = $", {ExpressionPrinter.VisitParameter(cctor.Parameters.Last())}";
786+
var defaultValue = "";
787+
var TypePrinter = new CSharpTypePrinter(Context.Context);
788+
var ExpressionPrinter = new CSharpExpressionPrinter(TypePrinter);
789+
if (cctor.Parameters.Count > 1)
790+
defaultValue = $", {ExpressionPrinter.VisitParameter(cctor.Parameters.Last())}";
788791

789-
Context.Before.WriteLine($"byte* __{Context.Parameter.Name}Memory = stackalloc byte[sizeof({nativeClass})];");
790-
Context.Before.WriteLine($"__IntPtr __{Context.Parameter.Name}Ptr = (__IntPtr)__{Context.Parameter.Name}Memory;");
791-
Context.Before.WriteLine($"{nativeClass}.{cctorName}(__{Context.Parameter.Name}Ptr, {Context.Parameter.Name}.__Instance{defaultValue});");
792-
Context.Return.Write($"__{Context.Parameter.Name}Ptr");
792+
Context.Before.WriteLine($"byte* __{Context.Parameter.Name}Memory = stackalloc byte[sizeof({nativeClass})];");
793+
Context.Before.WriteLine($"__IntPtr __{Context.Parameter.Name}Ptr = (__IntPtr)__{Context.Parameter.Name}Memory;");
794+
Context.Before.WriteLine($"{nativeClass}.{cctorName}(__{Context.Parameter.Name}Ptr, {Context.Parameter.Name}.__Instance{defaultValue});");
795+
Context.Return.Write($"__{Context.Parameter.Name}Ptr");
793796

794-
if (Context.Context.ParserOptions.IsItaniumLikeAbi && @class.HasNonTrivialDestructor)
795-
{
796-
Method dtor = @class.Destructors.FirstOrDefault();
797-
if (dtor != null)
797+
if (Context.Context.ParserOptions.IsItaniumLikeAbi && @class.HasNonTrivialDestructor)
798798
{
799-
// todo: virtual destructors?
800-
Context.Cleanup.WriteLine($"{nativeClass}.dtor(__{Context.Parameter.Name}Ptr);");
799+
Method dtor = @class.Destructors.FirstOrDefault();
800+
if (dtor != null)
801+
{
802+
// todo: virtual destructors?
803+
Context.Cleanup.WriteLine($"{nativeClass}.dtor(__{Context.Parameter.Name}Ptr);");
804+
}
801805
}
802806
}
807+
else
808+
{
809+
Context.Return.Write(paramInstance);
810+
}
803811
}
812+
// Non-Kythera classes.
804813
else
805814
{
815+
Context.Before.WriteLine($"if (ReferenceEquals({Context.Parameter.Name}, null))");
816+
Context.Before.WriteLineIndent(
817+
$@"throw new global::System.ArgumentNullException(""{
818+
Context.Parameter.Name}"", ""Cannot be null because it is passed by value."");");
806819
Context.Return.Write(paramInstance);
807820
}
808821
}

tests/dotnet/CSharp/CSharp.Tests.cs

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1995,19 +1995,4 @@ public void TestPointerToClass()
19951995
Assert.IsTrue(CSharp.CSharp.PointerToClass.IsDefaultInstance);
19961996
Assert.IsTrue(CSharp.CSharp.PointerToClass.IsValid);
19971997
}
1998-
1999-
[Test]
2000-
public void TestCallByValueCopyConstructor()
2001-
{
2002-
using (var s = new CallByValueCopyConstructor())
2003-
{
2004-
s.A = 500;
2005-
CSharp.CSharp.CallByValueCopyConstructorFunction(s);
2006-
Assert.That(s.A, Is.EqualTo(500));
2007-
}
2008-
2009-
Assert.That(CallByValueCopyConstructor.ConstructorCalls, Is.EqualTo(1));
2010-
Assert.That(CallByValueCopyConstructor.CopyConstructorCalls, Is.EqualTo(1));
2011-
Assert.That(CallByValueCopyConstructor.DestructorCalls, Is.EqualTo(2));
2012-
}
20131998
}

tests/dotnet/CSharp/CSharp.cpp

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1791,29 +1791,3 @@ bool PointerTester::IsValid()
17911791
}
17921792

17931793
PointerTester* PointerToClass = &internalPointerTesterInstance;
1794-
1795-
int CallByValueCopyConstructor::constructorCalls = 0;
1796-
int CallByValueCopyConstructor::destructorCalls = 0;
1797-
int CallByValueCopyConstructor::copyConstructorCalls = 0;
1798-
1799-
CallByValueCopyConstructor::CallByValueCopyConstructor()
1800-
{
1801-
a = 0;
1802-
constructorCalls++;
1803-
}
1804-
1805-
CallByValueCopyConstructor::CallByValueCopyConstructor(const CallByValueCopyConstructor& other)
1806-
{
1807-
a = other.a;
1808-
copyConstructorCalls++;
1809-
}
1810-
1811-
CallByValueCopyConstructor::~CallByValueCopyConstructor()
1812-
{
1813-
destructorCalls++;
1814-
}
1815-
1816-
void CallByValueCopyConstructorFunction(CallByValueCopyConstructor s)
1817-
{
1818-
s.a = 99999;
1819-
}

tests/dotnet/CSharp/CSharp.h

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1603,16 +1603,3 @@ class DLL_API PointerTester
16031603
};
16041604

16051605
DLL_API extern PointerTester* PointerToClass;
1606-
1607-
struct DLL_API CallByValueCopyConstructor {
1608-
int a;
1609-
static int constructorCalls;
1610-
static int destructorCalls;
1611-
static int copyConstructorCalls;
1612-
1613-
CallByValueCopyConstructor();
1614-
~CallByValueCopyConstructor();
1615-
CallByValueCopyConstructor(const CallByValueCopyConstructor& other);
1616-
};
1617-
1618-
DLL_API void CallByValueCopyConstructorFunction(CallByValueCopyConstructor s);

0 commit comments

Comments
 (0)