Skip to content

Commit f012b0c

Browse files
authored
Remove extraneous IDisposable types for global handles (#38)
converted global handles for MemoryBuffer and DIBuilder and GenericValue to use LlvmObject to remove need for IDisposable
1 parent e457f03 commit f012b0c

File tree

7 files changed

+80
-105
lines changed

7 files changed

+80
-105
lines changed

src/Llvm.NET/BitcodeModule.cs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -798,12 +798,10 @@ public BitcodeModule Clone( Context targetContext )
798798
return Clone( );
799799
}
800800

801-
using( var buffer = WriteToBuffer( ) )
802-
{
803-
var retVal = LoadFrom( buffer, targetContext );
804-
Debug.Assert( retVal.Context == targetContext, "Expected to get a module bound to the specified context" );
805-
return retVal;
806-
}
801+
var buffer = WriteToBuffer( );
802+
var retVal = LoadFrom( buffer, targetContext );
803+
Debug.Assert( retVal.Context == targetContext, "Expected to get a module bound to the specified context" );
804+
return retVal;
807805
}
808806

809807
/// <inheritdoc/>
@@ -828,10 +826,8 @@ public static BitcodeModule LoadFrom( string path, Context context )
828826
throw new FileNotFoundException( "Specified bit-code file does not exist", path );
829827
}
830828

831-
using( var buffer = new MemoryBuffer( path ) )
832-
{
833-
return LoadFrom( buffer, context );
834-
}
829+
var buffer = new MemoryBuffer( path );
830+
return LoadFrom( buffer, context );
835831
}
836832

837833
/// <summary>Load bit code from a memory buffer</summary>

src/Llvm.NET/DebugInfo/DebugInfoBuilder.cs

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@
1919

2020
namespace Llvm.NET.DebugInfo
2121
{
22-
// TODO: Remove IDisposable once LLVMDIBuilderRef is based on LlvmObject
23-
2422
/// <summary>DebugInfoBuilder is a factory class for creating DebugInformation for an LLVM
2523
/// <see cref="BitcodeModule"/></summary>
2624
/// <remarks>
@@ -31,7 +29,6 @@ namespace Llvm.NET.DebugInfo
3129
/// </remarks>
3230
/// <seealso href="xref:llvm_sourceleveldebugging">LLVM Source Level Debugging</seealso>
3331
public sealed class DebugInfoBuilder
34-
: IDisposable
3532
{
3633
/// <summary>Gets the module that owns this builder</summary>
3734
public BitcodeModule OwningModule { get; }
@@ -1305,16 +1302,6 @@ public DICompositeType CreateReplaceableCompositeType( Tag tag
13051302
return MDNode.FromHandle<DICompositeType>( handle );
13061303
}
13071304

1308-
/// <inheritdoc/>
1309-
public void Dispose( )
1310-
{
1311-
if( BuilderHandle == default )
1312-
{
1313-
LLVMDIBuilderDestroy( BuilderHandle );
1314-
BuilderHandle = default;
1315-
}
1316-
}
1317-
13181305
internal DebugInfoBuilder( BitcodeModule owningModule )
13191306
: this( owningModule, true )
13201307
{
@@ -1326,10 +1313,7 @@ internal DebugInfoBuilder( BitcodeModule owningModule )
13261313
// allowUnresolved == false
13271314
private DebugInfoBuilder( BitcodeModule owningModule, bool allowUnresolved )
13281315
{
1329-
if( owningModule == null )
1330-
{
1331-
throw new ArgumentNullException( nameof( owningModule ) );
1332-
}
1316+
owningModule.ValidateNotNull( nameof( owningModule ) );
13331317

13341318
BuilderHandle = LLVMNewDIBuilder( owningModule.ModuleHandle, allowUnresolved );
13351319
OwningModule = owningModule;
@@ -1348,9 +1332,6 @@ private static bool LocationDescribes( DILocation location, Function function )
13481332
[DllImport( LibraryPath, CallingConvention = System.Runtime.InteropServices.CallingConvention.Cdecl, BestFitMapping = false, ThrowOnUnmappableChar = true )]
13491333
private static extern LLVMDIBuilderRef LLVMNewDIBuilder( LLVMModuleRef @m, [MarshalAs( UnmanagedType.Bool )]bool allowUnresolved );
13501334

1351-
[DllImport( LibraryPath, CallingConvention = System.Runtime.InteropServices.CallingConvention.Cdecl, BestFitMapping = false, ThrowOnUnmappableChar = true )]
1352-
private static extern void LLVMDIBuilderDestroy( LLVMDIBuilderRef @d );
1353-
13541335
[DllImport( LibraryPath, CallingConvention = System.Runtime.InteropServices.CallingConvention.Cdecl, BestFitMapping = false, ThrowOnUnmappableChar = true )]
13551336
private static extern void LLVMDIBuilderFinalize( LLVMDIBuilderRef @d );
13561337

src/Llvm.NET/JIT/GenericValue.cs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ namespace Llvm.NET.JIT
1313
{
1414
/// <summary>LLVM JIT discriminated union for a generic primitive value</summary>
1515
public sealed class GenericValue
16-
: IDisposable
1716
{
1817
/// <summary>Initializes a new instance of the <see cref="GenericValue"/> class with an integer value</summary>
1918
/// <param name="t">LLVM type describing the integer bit width</param>
@@ -63,12 +62,6 @@ public GenericValue( ITypeRef t, double value )
6362
/// <returns>Floating point value</returns>
6463
public double ToDouble( Context ctx ) => LLVMGenericValueToFloat( ctx.DoubleType.GetTypeRef( ), Handle );
6564

66-
/// <inheritdoc/>
67-
public void Dispose( )
68-
{
69-
Handle.Dispose( );
70-
}
71-
7265
private readonly LLVMGenericValueRef Handle;
7366
}
7467
}

src/Llvm.NET/MemoryBuffer.cs

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ namespace Llvm.NET
1515
{
1616
/// <summary>LLVM MemoryBuffer</summary>
1717
public sealed class MemoryBuffer
18-
: IDisposable
1918
{
2019
/// <summary>Initializes a new instance of the <see cref="MemoryBuffer"/> class from a file</summary>
2120
/// <param name="path">Path of the file to load</param>
@@ -43,16 +42,6 @@ public int Size
4342
}
4443
}
4544

46-
/// <inheritdoc/>
47-
public void Dispose( )
48-
{
49-
if( BufferHandle == default )
50-
{
51-
LLVMDisposeMemoryBuffer( BufferHandle );
52-
BufferHandle_ = default;
53-
}
54-
}
55-
5645
/// <summary>Gets an array of bytes from the buffer</summary>
5746
/// <returns>Array of bytes copied from the buffer</returns>
5847
public byte[] ToArray()
@@ -72,6 +61,7 @@ internal MemoryBuffer( LLVMMemoryBufferRef bufferHandle )
7261

7362
internal LLVMMemoryBufferRef BufferHandle => BufferHandle_;
7463

64+
// TODO: Consider some form of WriteOnce<T> to enforce semantics and not rely on a coment
7565
// keep as a private field so this is usable as an out parameter in constructor
7666
// do not write to it directly, treat it as readonly.
7767
[SuppressMessage( "StyleCop.CSharp.NamingRules"
@@ -80,5 +70,33 @@ internal MemoryBuffer( LLVMMemoryBufferRef bufferHandle )
8070
)
8171
]
8272
private LLVMMemoryBufferRef BufferHandle_;
73+
74+
[DllImport( LibraryPath, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ThrowOnUnmappableChar = true, BestFitMapping = false )]
75+
private static extern LLVMStatus LLVMCreateMemoryBufferWithContentsOfFile( [MarshalAs( UnmanagedType.LPStr )] string @Path
76+
, out LLVMMemoryBufferRef @OutMemBuf
77+
, [MarshalAs( UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof( StringMarshaler ), MarshalCookie = "DisposeMessage" )]out string @OutMessage
78+
);
79+
80+
[DllImport( LibraryPath, CallingConvention = CallingConvention.Cdecl )]
81+
private static extern LLVMStatus LLVMCreateMemoryBufferWithSTDIN( out LLVMMemoryBufferRef @OutMemBuf, out IntPtr @OutMessage );
82+
83+
[DllImport( LibraryPath, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ThrowOnUnmappableChar = true, BestFitMapping = false )]
84+
private static extern LLVMMemoryBufferRef LLVMCreateMemoryBufferWithMemoryRange( [ MarshalAs( UnmanagedType.LPStr )] string @InputData
85+
, size_t @InputDataLength
86+
, [MarshalAs( UnmanagedType.LPStr )] string @BufferName
87+
, [MarshalAs( UnmanagedType.Bool )]bool @RequiresNullTerminator
88+
);
89+
90+
[DllImport( LibraryPath, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ThrowOnUnmappableChar = true, BestFitMapping = false )]
91+
private static extern LLVMMemoryBufferRef LLVMCreateMemoryBufferWithMemoryRangeCopy( [MarshalAs( UnmanagedType.LPStr )] string @InputData
92+
, size_t @InputDataLength
93+
, [MarshalAs( UnmanagedType.LPStr )] string @BufferName
94+
);
95+
96+
[DllImport( LibraryPath, CallingConvention = CallingConvention.Cdecl )]
97+
private static extern IntPtr LLVMGetBufferStart( LLVMMemoryBufferRef @MemBuf );
98+
99+
[DllImport( LibraryPath, CallingConvention = CallingConvention.Cdecl )]
100+
private static extern size_t LLVMGetBufferSize( LLVMMemoryBufferRef @MemBuf );
83101
}
84102
}

src/Llvm.NET/Native/Generated.cs

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2311,29 +2311,6 @@ internal static partial class NativeMethods
23112311
internal static extern LLVMValueRef LLVMBuildAtomicCmpXchg( LLVMBuilderRef @B, LLVMValueRef @Ptr, LLVMValueRef @Cmp, LLVMValueRef @New, LLVMAtomicOrdering @SuccessOrdering, LLVMAtomicOrdering @FailureOrdering, [MarshalAs( UnmanagedType.Bool )]bool @SingleThread );
23122312
#endregion
23132313

2314-
#region Memory Buffer
2315-
[DllImport( LibraryPath, EntryPoint = "LLVMCreateMemoryBufferWithContentsOfFile", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ThrowOnUnmappableChar = true, BestFitMapping = false )]
2316-
internal static extern LLVMStatus LLVMCreateMemoryBufferWithContentsOfFile( [MarshalAs( UnmanagedType.LPStr )] string @Path, out LLVMMemoryBufferRef @OutMemBuf, [MarshalAs( UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof( StringMarshaler ), MarshalCookie = "DisposeMessage" )]out string @OutMessage );
2317-
2318-
[DllImport( LibraryPath, EntryPoint = "LLVMCreateMemoryBufferWithSTDIN", CallingConvention = CallingConvention.Cdecl )]
2319-
internal static extern LLVMStatus LLVMCreateMemoryBufferWithSTDIN( out LLVMMemoryBufferRef @OutMemBuf, out IntPtr @OutMessage );
2320-
2321-
[DllImport( LibraryPath, EntryPoint = "LLVMCreateMemoryBufferWithMemoryRange", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ThrowOnUnmappableChar = true, BestFitMapping = false )]
2322-
internal static extern LLVMMemoryBufferRef LLVMCreateMemoryBufferWithMemoryRange( [MarshalAs( UnmanagedType.LPStr )] string @InputData, size_t @InputDataLength, [MarshalAs( UnmanagedType.LPStr )] string @BufferName, [MarshalAs( UnmanagedType.Bool )]bool @RequiresNullTerminator );
2323-
2324-
[DllImport( LibraryPath, EntryPoint = "LLVMCreateMemoryBufferWithMemoryRangeCopy", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ThrowOnUnmappableChar = true, BestFitMapping = false )]
2325-
internal static extern LLVMMemoryBufferRef LLVMCreateMemoryBufferWithMemoryRangeCopy( [MarshalAs( UnmanagedType.LPStr )] string @InputData, size_t @InputDataLength, [MarshalAs( UnmanagedType.LPStr )] string @BufferName );
2326-
2327-
[DllImport( LibraryPath, EntryPoint = "LLVMGetBufferStart", CallingConvention = CallingConvention.Cdecl )]
2328-
internal static extern IntPtr LLVMGetBufferStart( LLVMMemoryBufferRef @MemBuf );
2329-
2330-
[DllImport( LibraryPath, EntryPoint = "LLVMGetBufferSize", CallingConvention = CallingConvention.Cdecl )]
2331-
internal static extern size_t LLVMGetBufferSize( LLVMMemoryBufferRef @MemBuf );
2332-
2333-
[DllImport( LibraryPath, EntryPoint = "LLVMDisposeMemoryBuffer", CallingConvention = CallingConvention.Cdecl )]
2334-
internal static extern void LLVMDisposeMemoryBuffer( LLVMMemoryBufferRef @MemBuf );
2335-
#endregion
2336-
23372314
#region Pass Manager
23382315
[DllImport( LibraryPath, EntryPoint = "LLVMGetGlobalPassRegistry", CallingConvention = CallingConvention.Cdecl )]
23392316
internal static extern LLVMPassRegistryRef LLVMGetGlobalPassRegistry( );

src/Llvm.NET/Native/Handles/LLVMDIBuilderRef.cs

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,35 @@
33
// </copyright>
44

55
using System;
6-
using System.Collections.Generic;
6+
using System.Runtime.InteropServices;
7+
using System.Security;
8+
9+
using static Llvm.NET.Native.NativeMethods;
710

811
namespace Llvm.NET.Native
912
{
10-
// TODO: Convert to using LlvmObject so that DebugInfoBuilder doesn't need to be disposable
11-
internal struct LLVMDIBuilderRef
12-
: IEquatable<LLVMDIBuilderRef>
13+
[SecurityCritical]
14+
internal class LLVMDIBuilderRef
15+
: LlvmObjectRef
1316
{
14-
public override int GetHashCode( ) => Handle.GetHashCode( );
15-
16-
public override bool Equals( object obj ) => !( obj is null ) && ( obj is LLVMDIBuilderRef r ) && r.Handle == Handle;
17-
18-
public bool Equals( LLVMDIBuilderRef other ) => Handle == other.Handle;
19-
20-
public static bool operator ==( LLVMDIBuilderRef lhs, LLVMDIBuilderRef rhs )
21-
=> EqualityComparer<LLVMDIBuilderRef>.Default.Equals( lhs, rhs );
17+
public LLVMDIBuilderRef( IntPtr handle, bool owner)
18+
: base( owner )
19+
{
20+
SetHandle( handle );
21+
}
2222

23-
public static bool operator !=( LLVMDIBuilderRef lhs, LLVMDIBuilderRef rhs ) => !( lhs == rhs );
23+
protected override bool ReleaseHandle( )
24+
{
25+
LLVMDIBuilderDestroy( handle );
26+
return true;
27+
}
2428

25-
internal LLVMDIBuilderRef( IntPtr pointer )
29+
private LLVMDIBuilderRef()
30+
: base( true )
2631
{
27-
Handle = pointer;
2832
}
2933

30-
private readonly IntPtr Handle;
34+
[DllImport( LibraryPath, CallingConvention = CallingConvention.Cdecl )]
35+
private static extern void LLVMDIBuilderDestroy( IntPtr d );
3136
}
3237
}
Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,38 @@
1-
// <copyright file="Generated.cs" company=".NET Foundation">
1+
// <copyright file="LLVMMemoryBufferRef.cs" company=".NET Foundation">
22
// Copyright (c) .NET Foundation. All rights reserved.
33
// </copyright>
44

55
using System;
6-
using System.Collections.Generic;
6+
using System.Runtime.InteropServices;
7+
using System.Security;
8+
9+
using static Llvm.NET.Native.NativeMethods;
710

811
namespace Llvm.NET.Native
912
{
10-
// TODO: replace with LlvmObject impl so that MemoryBuffer can remove the IDisposable interface and function like any other
11-
// garbage collected type in .NET
12-
internal struct LLVMMemoryBufferRef
13-
: IEquatable<LLVMMemoryBufferRef>
13+
[SecurityCritical]
14+
internal class LLVMMemoryBufferRef
15+
: LlvmObjectRef
1416
{
15-
public override int GetHashCode( ) => Handle.GetHashCode( );
16-
17-
public override bool Equals( object obj ) => !( obj is null ) && ( obj is LLVMMemoryBufferRef r ) && r.Handle == Handle;
18-
19-
public bool Equals( LLVMMemoryBufferRef other ) => Handle == other.Handle;
20-
21-
public static bool operator ==( LLVMMemoryBufferRef lhs, LLVMMemoryBufferRef rhs )
22-
=> EqualityComparer<LLVMMemoryBufferRef>.Default.Equals( lhs, rhs );
17+
public LLVMMemoryBufferRef( IntPtr handle, bool owner )
18+
: base( owner )
19+
{
20+
SetHandle( handle );
21+
}
2322

24-
public static bool operator !=( LLVMMemoryBufferRef lhs, LLVMMemoryBufferRef rhs ) => !( lhs == rhs );
23+
[SecurityCritical]
24+
protected override bool ReleaseHandle( )
25+
{
26+
LLVMDisposeMemoryBuffer( handle );
27+
return true;
28+
}
2529

26-
internal LLVMMemoryBufferRef( IntPtr pointer )
30+
private LLVMMemoryBufferRef( )
31+
: base( true )
2732
{
28-
Handle = pointer;
2933
}
3034

31-
private readonly IntPtr Handle;
35+
[DllImport( LibraryPath, CallingConvention = CallingConvention.Cdecl )]
36+
private static extern void LLVMDisposeMemoryBuffer( IntPtr handle );
3237
}
3338
}

0 commit comments

Comments
 (0)