Skip to content

Commit 531d7f3

Browse files
committed
GLFW with wrappers compiles now
1 parent eaa4286 commit 531d7f3

File tree

15 files changed

+2137
-317
lines changed

15 files changed

+2137
-317
lines changed

sources/Core/Pointers/Any.cs

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
using System.Runtime.CompilerServices;
2+
using System.Runtime.InteropServices;
3+
4+
namespace Silk.NET.Core;
5+
6+
/// <summary>
7+
/// Represents an untyped constant pointer.
8+
/// </summary>
9+
public unsafe ref struct Any
10+
{
11+
/// <summary>
12+
/// The underlying reference.
13+
/// </summary>
14+
public readonly ref byte Ref;
15+
16+
/// <summary>
17+
/// Creates a pointer with the given underlying ref.
18+
/// </summary>
19+
/// <param name="ref">The underlying ref.</param>
20+
public Any(ref byte @ref) => Ref = ref @ref;
21+
22+
/// <summary>
23+
/// Creates an untyped pointer from a typed reference.
24+
/// </summary>
25+
/// <param name="ref">The </param>
26+
/// <typeparam name="T"></typeparam>
27+
/// <returns></returns>
28+
public static Any Create<T>(ref T @ref) => new(ref Unsafe.As<T, byte>(ref @ref));
29+
30+
/// <summary>
31+
/// Gets the underlying reference.
32+
/// </summary>
33+
/// <returns>The underlying reference.</returns>
34+
/// <remarks>
35+
/// This function allows a <see cref="Any"/> to be used in a <c>fixed</c> statement.
36+
/// </remarks>
37+
public ref byte GetPinnableReference() => ref Ref;
38+
39+
/// <summary>
40+
/// Creates a span with the given length from this pointer.
41+
/// </summary>
42+
/// <param name="len">The span length.</param>
43+
/// <returns>The span.</returns>
44+
public ReadOnlySpan<T> AsSpan<T>(int len) =>
45+
MemoryMarshal.CreateReadOnlySpan(ref Unsafe.As<byte, T>(ref Ref), len);
46+
47+
// TODO strings?
48+
49+
/// <summary>
50+
/// Creates a <see cref="Any"/> from an array.
51+
/// </summary>
52+
/// <param name="array"></param>
53+
/// <returns>The pointer.</returns>
54+
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
55+
public static implicit operator Any(Array array) => new(ref MemoryMarshal.GetArrayDataReference(array));
56+
57+
// TODO spans?
58+
59+
/// <summary>
60+
/// Creates a <see cref="Any"/> from a raw pointer.
61+
/// </summary>
62+
/// <param name="raw">The raw pointer.</param>
63+
/// <returns>The pointer.</returns>
64+
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
65+
public static implicit operator Any(void* raw) => new(ref *(byte*)raw);
66+
67+
/// <summary>
68+
/// Creates a null <see cref="Any"/>.
69+
/// </summary>
70+
/// <param name="_"><see cref="DSL.nullptr"/></param>
71+
/// <returns>A null pointer.</returns>
72+
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
73+
public static implicit operator Any(NullPtr _) => new(ref Unsafe.NullRef<byte>());
74+
75+
/// <summary>
76+
/// Unsafely gets the pointer to the underlying reference of this <see cref="Any"/>.
77+
/// </summary>
78+
/// <param name="ptr">The pointer.</param>
79+
/// <returns>The raw pointer.</returns>
80+
/// <remarks>
81+
/// This is unsafe if the reference is a managed reference. You should prefer pinning using <c>fixed</c> instead.
82+
/// </remarks>
83+
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
84+
public static explicit operator void*(Any ptr) => Unsafe.AsPointer(ref ptr.Ref);
85+
86+
// TODO strings?
87+
88+
/// <inheritdoc />
89+
public override bool Equals(object? obj) => false;
90+
91+
/// <summary>
92+
/// Determines whether the given pointer points to the same location as this pointer.
93+
/// </summary>
94+
/// <param name="other">The other pointer.</param>
95+
/// <returns>Whether the pointers are equal.</returns>
96+
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
97+
public bool Equals(Any other) => Unsafe.AreSame(ref Ref, ref other.Ref);
98+
99+
/// <inheritdoc />
100+
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
101+
public override int GetHashCode() => HashCode.Combine((nint)Unsafe.AsPointer(ref Ref));
102+
103+
/// <summary>
104+
/// Determines whether the given pointers point to the same location.
105+
/// </summary>
106+
/// <param name="left">The first pointer.</param>
107+
/// <param name="right">The second pointer.</param>
108+
/// <returns>Whether the pointers are equal.</returns>
109+
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
110+
public static bool operator ==(Any left, Any right) => left.Equals(right);
111+
112+
/// <summary>
113+
/// Determines whether the given pointers point do not to the same location.
114+
/// </summary>
115+
/// <param name="left">The first pointer.</param>
116+
/// <param name="right">The second pointer.</param>
117+
/// <returns>Whether the pointers are not equal.</returns>
118+
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
119+
public static bool operator !=(Any left, Any right) => !left.Equals(right);
120+
121+
/// <summary>
122+
/// Determines whether the given pointer is not null.
123+
/// </summary>
124+
/// <param name="left">The pointer.</param>
125+
/// <param name="_"><see cref="DSL.nullptr"/></param>
126+
/// <returns>Whether the pointer is not null.</returns>
127+
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
128+
public static bool operator !=(Any left, NullPtr _) => !(left == _);
129+
130+
/// <summary>
131+
/// Determines whether the given pointer is null.
132+
/// </summary>
133+
/// <param name="left">The pointer.</param>
134+
/// <param name="_"><see cref="DSL.nullptr"/></param>
135+
/// <returns>Whether the pointer is null.</returns>
136+
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
137+
public static bool operator ==(Any left, NullPtr _) => Unsafe.IsNullRef(ref left.Ref);
138+
}

sources/Core/Pointers/Any2D.cs

Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
using System.Diagnostics.CodeAnalysis;
2+
using System.Runtime.CompilerServices;
3+
using System.Runtime.InteropServices;
4+
using InlineIL;
5+
6+
namespace Silk.NET.Core;
7+
8+
/// <summary>
9+
/// Represents an untyped constant pointer.
10+
/// </summary>
11+
public readonly unsafe ref struct Any2D
12+
{
13+
#pragma warning disable CS0649
14+
private readonly ref byte InteriorRef;
15+
#pragma warning restore CS0649
16+
17+
/// <summary>
18+
/// Creates a <see cref="Any"/> pointing at the given <see cref="ConstPtr{T}"/>.
19+
/// </summary>
20+
/// <param name="ref">The reference to the pointee <see cref="ConstPtr{T}"/>.</param>
21+
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
22+
public Any2D(ref Any @ref)
23+
{
24+
IL.Emit.Ldarg_0();
25+
IL.Emit.Ldarg_1();
26+
IL.Emit.Stfld(FieldRef.Field(TypeRef.Type(typeof(Any2D)), nameof(InteriorRef)));
27+
IL.Emit.Ret();
28+
throw IL.Unreachable();
29+
}
30+
31+
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
32+
private Any2D(ref byte interior) => InteriorRef = ref interior;
33+
34+
/// <summary>
35+
/// The underlying reference.
36+
/// </summary>
37+
public ref Any Ref
38+
{
39+
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
40+
get
41+
{
42+
// Would use the delegate* trick but this isn't optimised in JIT yet or necessarily safe
43+
IL.Emit.Ldarg_0();
44+
IL.Emit.Ldfld(FieldRef.Field(TypeRef.Type(typeof(Any2D)),
45+
nameof(InteriorRef)));
46+
IL.Emit.Ret();
47+
throw IL.Unreachable();
48+
}
49+
}
50+
51+
/// <summary>
52+
/// Gets the item at the given offset from this pointer.
53+
/// </summary>
54+
/// <param name="index">The index.</param>
55+
public ref Any this[nuint index]
56+
{
57+
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
58+
get
59+
{
60+
IL.Emit.Ldarg_0();
61+
IL.Emit.Ldfld(FieldRef.Field(TypeRef.Type(typeof(Any2D)),
62+
nameof(InteriorRef)));
63+
IL.Emit.Ldarg_1();
64+
IL.Emit.Sizeof<nuint>();
65+
IL.Emit.Mul();
66+
IL.Emit.Add();
67+
IL.Emit.Ret();
68+
throw IL.Unreachable();
69+
}
70+
}
71+
72+
// TODO strings?
73+
74+
/// <summary>
75+
/// Gets the underlying reference.
76+
/// </summary>
77+
/// <returns>The underlying reference.</returns>
78+
/// <remarks>
79+
/// This function allows a <see cref="ConstPtr{T}"/> to be used in a <c>fixed</c> statement.
80+
/// </remarks>
81+
public ref void* GetPinnableReference()
82+
{
83+
IL.Emit.Ldarg_0();
84+
IL.Emit.Ldfld(FieldRef.Field(TypeRef.Type(typeof(Any2D)),
85+
nameof(InteriorRef)));
86+
IL.Emit.Ret();
87+
throw IL.Unreachable();
88+
}
89+
90+
/// <summary>
91+
/// Creates a <see cref="Any2D"/> from a raw pointer.
92+
/// </summary>
93+
/// <param name="raw">The raw pointer.</param>
94+
/// <returns>The pointer.</returns>
95+
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
96+
public static implicit operator Any2D(void** raw)
97+
{
98+
IL.DeclareLocals(new LocalVar("ret", TypeRef.Type(typeof(Any2D))));
99+
IL.Emit.Ldloca_S("ret");
100+
IL.Emit.Initobj(TypeRef.Type(typeof(Any2D)));
101+
IL.Emit.Ldloca_S("ret");
102+
IL.Emit.Ldarg_0();
103+
IL.Emit.Stfld(
104+
FieldRef.Field(TypeRef.Type(typeof(Any2D)), nameof(InteriorRef)));
105+
IL.Emit.Ldloc_S("ret");
106+
IL.Emit.Ret();
107+
throw IL.Unreachable();
108+
}
109+
110+
// TODO arrays?
111+
112+
// TODO strings?
113+
114+
/// <summary>
115+
/// Creates a <see cref="Any2D"/> from an array of pointers.
116+
/// </summary>
117+
/// <param name="array">The array.</param>
118+
/// <returns>The pointer.</returns>
119+
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
120+
[SuppressMessage("ReSharper", "EntityNameCapturedOnly.Local")]
121+
public static implicit operator Any2D(void*[] array)
122+
{
123+
IL.Emit.Ldarg_0();
124+
IL.Emit.Ldc_I4_0();
125+
IL.Emit.Ldelema(TypeRef.Type(typeof(void).MakePointerType()));
126+
IL.Emit.Newobj(MethodRef.Constructor(TypeRef.Type(typeof(Any2D)),
127+
TypeRef.Type(typeof(Any).MakeByRefType())));
128+
IL.Emit.Ret();
129+
throw IL.Unreachable();
130+
}
131+
132+
/// <summary>
133+
/// Creates a null <see cref="Any2D"/>.
134+
/// </summary>
135+
/// <param name="_"><see cref="DSL.nullptr"/></param>
136+
/// <returns>A null pointer.</returns>
137+
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
138+
public static implicit operator Any2D(NullPtr _)
139+
{
140+
IL.DeclareLocals(new LocalVar("ret", TypeRef.Type(typeof(Any2D))));
141+
IL.Emit.Ldloca_S("ret");
142+
IL.Emit.Initobj(TypeRef.Type(typeof(Any2D)));
143+
IL.Emit.Ldloca_S("ret");
144+
IL.Emit.Ldc_I4_0();
145+
IL.Emit.Conv_U();
146+
IL.Emit.Stfld(
147+
FieldRef.Field(TypeRef.Type(typeof(Any2D)), nameof(InteriorRef)));
148+
IL.Emit.Ldloc_S("ret");
149+
IL.Emit.Ret();
150+
throw IL.Unreachable();
151+
}
152+
153+
/// <summary>
154+
/// Unsafely gets a raw pointer from a <see cref="Any2D"/>.
155+
/// </summary>
156+
/// <param name="ptr">The <see cref="Any2D"/>.</param>
157+
/// <returns>The raw pointer.</returns>
158+
/// <remarks>
159+
/// This is unsafe if the reference is a managed reference. You should prefer pinning using <c>fixed</c> instead.
160+
/// </remarks>
161+
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
162+
public static explicit operator void**(Any2D ptr)
163+
{
164+
IL.Emit.Ldarg_0();
165+
IL.Emit.Ldfld(
166+
FieldRef.Field(TypeRef.Type(typeof(Any2D)), nameof(InteriorRef)));
167+
IL.Emit.Ret();
168+
throw IL.Unreachable();
169+
}
170+
171+
/// <inheritdoc />
172+
public override bool Equals(object? obj) => false;
173+
174+
/// <summary>
175+
/// Determines whether the given pointer points to the same location as this pointer.
176+
/// </summary>
177+
/// <param name="other">The other pointer.</param>
178+
/// <returns>Whether the pointers are equal.</returns>
179+
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
180+
public bool Equals(Any2D other) =>
181+
Unsafe.AreSame(ref Unsafe.AsRef(in InteriorRef), ref Unsafe.AsRef(in other.InteriorRef));
182+
183+
/// <inheritdoc />
184+
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
185+
public override int GetHashCode() => HashCode.Combine((nint)Unsafe.AsPointer(ref Unsafe.AsRef(in InteriorRef)));
186+
187+
/// <summary>
188+
/// Determines whether the given pointers point to the same location.
189+
/// </summary>
190+
/// <param name="left">The first pointer.</param>
191+
/// <param name="right">The second pointer.</param>
192+
/// <returns>Whether the pointers are equal.</returns>
193+
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
194+
public static bool operator ==(Any2D left, Any2D right) => left.Equals(right);
195+
196+
/// <summary>
197+
/// Determines whether the given pointers point do not to the same location.
198+
/// </summary>
199+
/// <param name="left">The first pointer.</param>
200+
/// <param name="right">The second pointer.</param>
201+
/// <returns>Whether the pointers are not equal.</returns>
202+
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
203+
public static bool operator !=(Any2D left, Any2D right) => !left.Equals(right);
204+
205+
/// <summary>
206+
/// Determines whether the given pointer is not null.
207+
/// </summary>
208+
/// <param name="left">The pointer.</param>
209+
/// <param name="_"><see cref="DSL.nullptr"/></param>
210+
/// <returns>Whether the pointer is not null.</returns>
211+
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
212+
public static bool operator !=(Any2D left, NullPtr _) => !(left == _);
213+
214+
/// <summary>
215+
/// Determines whether the given pointer is null.
216+
/// </summary>
217+
/// <param name="left">The pointer.</param>
218+
/// <param name="_"><see cref="DSL.nullptr"/></param>
219+
/// <returns>Whether the pointer is null.</returns>
220+
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
221+
public static bool operator ==(Any2D left, NullPtr _) =>
222+
Unsafe.IsNullRef(ref Unsafe.AsRef(in left.InteriorRef));
223+
}

0 commit comments

Comments
 (0)