Browse Source

Add a mechanism to selectively initialize allocated unmanaged memory in the default constructor.

* feature: Add a mechanism to selectively initialize unmanaged memory in the default constructor. (C# Only at this point).

* Use the global:: prefix when calling InitBlock
pull/1612/head
Joe Hull 4 years ago committed by GitHub
parent
commit
748b7b5d03
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      src/Generator/Generators/CSharp/CSharpSources.cs
  2. 12
      src/Generator/Options.cs
  3. 3
      tests/CSharp/CSharp.Gen.cs
  4. 13
      tests/CSharp/CSharp.Tests.cs
  5. 8
      tests/CSharp/CSharp.h

3
src/Generator/Generators/CSharp/CSharpSources.cs

@ -2942,6 +2942,9 @@ internal static{(@new ? " new" : string.Empty)} {printedClass} __GetInstance({Ty @@ -2942,6 +2942,9 @@ internal static{(@new ? " new" : string.Empty)} {printedClass} __GetInstance({Ty
}
else
{
if (method.IsDefaultConstructor && Context.Options.ZeroAllocatedMemory(@class))
WriteLine($"global::System.Runtime.CompilerServices.Unsafe.InitBlock((void*){Helpers.InstanceIdentifier}, 0, (uint)sizeof({@internal}));");
if (!method.IsDefaultConstructor || @class.HasNonTrivialDefaultConstructor)
GenerateInternalFunctionCall(method);
}

12
src/Generator/Options.cs

@ -119,6 +119,18 @@ namespace CppSharp @@ -119,6 +119,18 @@ namespace CppSharp
/// </summary>
public bool GenerateFinalizers;
/// <summary>
/// If <see cref="ZeroAllocatedMemory"/> returns <c>true</c> for a given <see cref="Class"/>,
/// unmanaged memory allocated in the class' default constructor will be initialized with
/// zeros. The default implementation always returns <c>false</c>. Currently, C# only.
/// </summary>
/// <remarks>
/// If this option returns <c>true</c>, you must take a reference to the nuget package
/// System.Runtime.CompilerServices.Unsafe in the project(s) containing the generated file(s) to
/// resolve the Unsafe.InitBlock method.
/// </remarks>
public Func<Class, bool> ZeroAllocatedMemory = (@class) => false;
public string IncludePrefix;
public Func<TranslationUnit, string> GenerateName;

3
tests/CSharp/CSharp.Gen.cs

@ -65,6 +65,9 @@ namespace CppSharp.Tests @@ -65,6 +65,9 @@ namespace CppSharp.Tests
Name = "MacroTest",
Namespace = ctx.TranslationUnits.First(u => u.IsValid && !u.IsSystemHeader)
};
// Preserve the original semantics except for our one test class.
driver.Options.ZeroAllocatedMemory = (@class) => @class.Name == "ClassZeroAllocatedMemoryTest";
}
public override void Postprocess(Driver driver, ASTContext ctx)

13
tests/CSharp/CSharp.Tests.cs

@ -708,6 +708,19 @@ public unsafe class CSharpTests @@ -708,6 +708,19 @@ public unsafe class CSharpTests
Assert.That(CSharp.HasFreeConstant.AnotherUnit.STD_STRING_CONSTANT, Is.EqualTo("test"));
}
[Test]
public void TestZeroAllocatedMemoryOption()
{
// We've arranged in the generator for the ZeroAllocatedMemory option to return true for this one
// class.
var test = new ClassZeroAllocatedMemoryTest();
Assert.That(test.P1, Is.EqualTo(0));
Assert.That(test.p2.P2p1, Is.EqualTo(0));
Assert.That(test.p2.P2p2, Is.EqualTo(0));
Assert.That(test.P3, Is.EqualTo(false));
Assert.That(test.P4, Is.EqualTo('\0'));
}
[Test]
public void TestAlignment()
{

8
tests/CSharp/CSharp.h

@ -1487,6 +1487,14 @@ struct TestVariableWithoutType @@ -1487,6 +1487,14 @@ struct TestVariableWithoutType
static constexpr auto variable = create(n...);
};
struct DLL_API ClassZeroAllocatedMemoryTest
{
int p1;
struct { int p2p1; int p2p2; } p2;
bool p3;
char p4;
};
struct DLL_API ConversionFunctions
{
ConversionFunctions();

Loading…
Cancel
Save