forked from UbiquityDotNET/Llvm.NET
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLLVMMCJITMemoryManagerRef.g.cs
More file actions
113 lines (100 loc) · 5.65 KB
/
Copy pathLLVMMCJITMemoryManagerRef.g.cs
File metadata and controls
113 lines (100 loc) · 5.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// ------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool. [LlvmBindingsGenerator]
// Tool Version: 20.1.9-epsilon.0.0.ci.618434732.ZZZ
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
// ------------------------------------------------------------------------------
#nullable enable
using System;
using System.CodeDom.Compiler;
using System.Runtime.InteropServices.Marshalling;
namespace Ubiquity.NET.Llvm.Interop
{
/// <summary>Simple type safe handle to wrap an opaque pointer for interop with "C" API exported from LibLLVM</summary>
/// <remarks>
/// <para>This is not, nor can it ever be a `ref struct` as such things are not usable in an array. Many LLVM APIs
/// deal with arrays of handles which requires heap allocated location of the handle value not allowed by `ref struct`.
/// This is an important performance distinction as an array of handles, once pinned, is castable to a pointer to the
/// underlying native form. The structs are bit compatible with the underlying form. They are essentially a managed code
/// variant on a type alias. They provide type specific insurance for an opaque native pointer.</para>
/// <note type="important">
/// This is a "Disposable" struct to provide a standard mechanism for releasing the handle
/// AND to allow for performance in marshalling arrays of handles. (It's just an
/// <see cref="nint"/> under the hood.) This removes the need to perform any sort of marshaling
/// conversions whenever passed to a native API, and for EVERY entry in an array instead of just
/// fixing the array and passing a pointer. There are a LOT of APIs that take an array of handles
/// and this allows use with them in a significantly more performant fashion. Copying this struct,
/// which happens a LOT under the hood, will simply copy the underlying <see cref="nint"/> but NOT
/// it's disposed state. Consumers should use care in ONLY making a single call to Dispose().
/// Due to this trade-off it is an inherently dangerous structure and requires care to ensure the
/// correct usage.
/// </note>
/// </remarks>
[GeneratedCode("LlvmBindingsGenerator","20.1.9-epsilon.0.0.ci.618434732.ZZZ")]
[NativeMarshalling(typeof(WrappedHandleMarshaller<LLVMMCJITMemoryManagerRef>))]
public readonly record struct LLVMMCJITMemoryManagerRef
: IWrappedHandle<LLVMMCJITMemoryManagerRef>
, IFormattable
, IDisposable
{
/// <summary>Gets a value indicating if this handle is a <see langword="null"/> value</summary>
public bool IsNull => Handle == nint.Zero;
/// <summary>Gets the handle as an <see cref="nint"/> suitable for passing to native code</summary>
/// <returns>The handle as an <see cref="nint"/></returns>
public nint DangerousGetHandle() => Handle;
/// <inheritdoc/>
public override string ToString( )
{
return Handle.ToString();
}
/// <inheritdoc/>
public string ToString( string? format, IFormatProvider? formatProvider )
{
return Handle.ToString(format, formatProvider);
}
/// <summary>Interface defined factory for an instance of <see cref="LLVMMCJITMemoryManagerRef"/></summary>
/// <param name="abiValue">Native ABI value of the handle</param>
/// <returns>Type specific wrapper around the native ABI handle</returns>
public static LLVMMCJITMemoryManagerRef FromABI(nint abiValue) => new(abiValue);
/// <summary>Gets the handle as an <see cref="nint"/> suitable for passing to native code</summary>
/// <param name="value">Handle to convert</param>
/// <returns>The handle as an <see cref="nint"/></returns>
public static implicit operator nint(LLVMMCJITMemoryManagerRef value) => value.Handle;
#if DEBUG
/// <summary>Gets creation stack - Debugging aid</summary>
public string? CreationStack { get; }
#endif
/// <remarks>
/// <em><b>This is NOT an idempotent call.</b></em> Additionally, since this is a struct it does NOT
/// guarantee that all copies are invalidated. This is merely a means of standardizing on the release
/// to a single API signature and pattern. It is just an equivalent to calling the native release API
/// for the handle. Callers should take care to ensure that this is called only once for any particular
/// value and that such a value is not used after it is destroyed.
/// </remarks>
public void Dispose( )
{
ObjectDisposedException.ThrowIf(Handle == nint.Zero, this);
LLVMDisposeMCJITMemoryManager( Handle );
// Native ABI declaration without ANY marshaling, AOT compatible
[DllImport( NativeMethods.LibraryName )]
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
static unsafe extern void LLVMDisposeMCJITMemoryManager( nint p );
}
internal LLVMMCJITMemoryManagerRef( nint p )
{
Handle = p;
#if DEBUG
// In a debug build capture the stack for creation of this instance
// that way it is still available if there is an access violation
// in the dispose. Usually such a thing indicates the source did NOT
// properly apply a using. So it is VERY helpful in debugging of finalizer
// failures to locate the source.
CreationStack = Environment.StackTrace;
#endif
}
private readonly nint Handle;
}
}