Skip to content

Commit 00fa856

Browse files
committed
Generate StackAllocations automatically.
1 parent e9edf8c commit 00fa856

9 files changed

+395
-24
lines changed

BTDB.SourceGenerator.Sample/Examples.cs

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
Creator = &Create1,
3030
AdderKeyValue = &Add1
3131
});
32+
ReflectionMetadata.RegisterStackAllocator(typeof((int, string)), &AllocateValueType);
3233
}
3334

3435
MyCtx myCtx = default;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//HintName: StackAllocationRegistrations.g.cs
2+
// <auto-generated/>
3+
#nullable enable
4+
#pragma warning disable CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type
5+
using System;
6+
using System.Runtime.CompilerServices;
7+
[CompilerGenerated]
8+
static file class StackAllocationRegistrations
9+
{
10+
[ModuleInitializer]
11+
internal static unsafe void Register4BTDB()
12+
{
13+
BTDB.Serialization.ReflectionMetadata.RegisterStackAllocator(typeof(int), &Allocate1);
14+
static void Allocate1(ref byte ctx, ref nint ptr, delegate*<ref byte, void> chain)
15+
{
16+
int value;
17+
ptr = (nint)(&value);
18+
chain(ref ctx);
19+
ptr = 0;
20+
}
21+
}
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//HintName: StackAllocationRegistrations.g.cs
2+
// <auto-generated/>
3+
#nullable enable
4+
#pragma warning disable CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type
5+
using System;
6+
using System.Runtime.CompilerServices;
7+
[CompilerGenerated]
8+
static file class StackAllocationRegistrations
9+
{
10+
[ModuleInitializer]
11+
internal static unsafe void Register4BTDB()
12+
{
13+
BTDB.Serialization.ReflectionMetadata.RegisterStackAllocator(typeof(int), &Allocate1);
14+
static void Allocate1(ref byte ctx, ref nint ptr, delegate*<ref byte, void> chain)
15+
{
16+
int value;
17+
ptr = (nint)(&value);
18+
chain(ref ctx);
19+
ptr = 0;
20+
}
21+
}
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//HintName: StackAllocationRegistrations.g.cs
2+
// <auto-generated/>
3+
#nullable enable
4+
#pragma warning disable CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type
5+
using System;
6+
using System.Runtime.CompilerServices;
7+
[CompilerGenerated]
8+
static file class StackAllocationRegistrations
9+
{
10+
[ModuleInitializer]
11+
internal static unsafe void Register4BTDB()
12+
{
13+
BTDB.Serialization.ReflectionMetadata.RegisterStackAllocator(typeof(int), &Allocate1);
14+
static void Allocate1(ref byte ctx, ref nint ptr, delegate*<ref byte, void> chain)
15+
{
16+
int value;
17+
ptr = (nint)(&value);
18+
chain(ref ctx);
19+
ptr = 0;
20+
}
21+
}
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
//HintName: CollectionRegistrations.g.cs
2+
// <auto-generated/>
3+
#nullable enable
4+
using System;
5+
using System.Runtime.CompilerServices;
6+
[CompilerGenerated]
7+
static file class CollectionRegistrations
8+
{
9+
[ModuleInitializer]
10+
internal static void Register4BTDB()
11+
{
12+
BTDB.Serialization.ReflectionMetadata.RegisterCollection(new()
13+
{
14+
Type = typeof(global::System.Collections.Generic.IDictionary<int, (string, string)>),
15+
ElementKeyType = typeof(int),
16+
ElementValueType = typeof((string, string)),
17+
Creator = &Create1,
18+
AdderKeyValue = &Add1
19+
});
20+
21+
static object Create1(uint capacity)
22+
{
23+
return new global::System.Collections.Generic.Dictionary<int, (string, string)>((int)capacity);
24+
}
25+
26+
static void Add1(object c, ref byte key, ref byte value)
27+
{
28+
Unsafe.As<global::System.Collections.Generic.Dictionary<int, (string, string)>>(c).Add(Unsafe.As<byte, int>(ref key), Unsafe.As<byte, (string, string)>(ref value));
29+
}
30+
31+
BTDB.Serialization.ReflectionMetadata.RegisterCollection(new()
32+
{
33+
Type = typeof(global::System.Collections.Generic.ISet<(string, int)>),
34+
ElementKeyType = typeof((string, int)),
35+
Creator = &Create2,
36+
Adder = &Add2
37+
});
38+
39+
static object Create2(uint capacity)
40+
{
41+
return new global::System.Collections.Generic.HashSet<(string, int)>((int)capacity);
42+
}
43+
44+
static void Add2(object c, ref byte value)
45+
{
46+
Unsafe.As<global::System.Collections.Generic.HashSet<(string, int)>>(c).Add(Unsafe.As<byte, (string, int)>(ref value));
47+
}
48+
}
49+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//HintName: StackAllocationRegistrations.g.cs
2+
// <auto-generated/>
3+
#nullable enable
4+
#pragma warning disable CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type
5+
using System;
6+
using System.Runtime.CompilerServices;
7+
[CompilerGenerated]
8+
static file class StackAllocationRegistrations
9+
{
10+
[ModuleInitializer]
11+
internal static unsafe void Register4BTDB()
12+
{
13+
BTDB.Serialization.ReflectionMetadata.RegisterStackAllocator(typeof(int), &Allocate1);
14+
static void Allocate1(ref byte ctx, ref nint ptr, delegate*<ref byte, void> chain)
15+
{
16+
int value;
17+
ptr = (nint)(&value);
18+
chain(ref ctx);
19+
ptr = 0;
20+
}
21+
22+
BTDB.Serialization.ReflectionMetadata.RegisterStackAllocator(typeof((string, string)), &Allocate2);
23+
static void Allocate2(ref byte ctx, ref nint ptr, delegate*<ref byte, void> chain)
24+
{
25+
(string, string) value;
26+
ptr = (nint)(&value);
27+
chain(ref ctx);
28+
ptr = 0;
29+
}
30+
31+
BTDB.Serialization.ReflectionMetadata.RegisterStackAllocator(typeof((string, int)), &Allocate3);
32+
static void Allocate3(ref byte ctx, ref nint ptr, delegate*<ref byte, void> chain)
33+
{
34+
(string, int) value;
35+
ptr = (nint)(&value);
36+
chain(ref ctx);
37+
ptr = 0;
38+
}
39+
}
40+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
//HintName: TestNamespace.Person.g.cs
2+
// <auto-generated/>
3+
#pragma warning disable 612,618
4+
using System;
5+
using System.Runtime.CompilerServices;
6+
7+
namespace TestNamespace;
8+
9+
[CompilerGenerated]
10+
static file class PersonRegistration
11+
{
12+
[UnsafeAccessor(UnsafeAccessorKind.Constructor)]
13+
extern static global::TestNamespace.Person Creator();
14+
[UnsafeAccessor(UnsafeAccessorKind.Field, Name = "<Name>k__BackingField")]
15+
extern static ref string Field1(global::TestNamespace.Person @this);
16+
[UnsafeAccessor(UnsafeAccessorKind.Field, Name = "<Id2Names>k__BackingField")]
17+
extern static ref global::System.Collections.Generic.IDictionary<int, (string, string)> Field2(global::TestNamespace.Person @this);
18+
[UnsafeAccessor(UnsafeAccessorKind.Field, Name = "<NameSet2>k__BackingField")]
19+
extern static ref global::System.Collections.Generic.ISet<(string, int)> Field3(global::TestNamespace.Person @this);
20+
[ModuleInitializer]
21+
internal static unsafe void Register4BTDB()
22+
{
23+
global::BTDB.IOC.IContainer.RegisterFactory(typeof(global::TestNamespace.Person), (container, ctx) =>
24+
{
25+
return (container2, ctx2) =>
26+
{
27+
var res = new global::TestNamespace.Person();
28+
return res;
29+
};
30+
});
31+
var metadata = new global::BTDB.Serialization.ClassMetadata();
32+
metadata.Name = "Person";
33+
metadata.Type = typeof(global::TestNamespace.Person);
34+
metadata.Namespace = "TestNamespace";
35+
metadata.Implements = [];
36+
metadata.Creator = &Creator;
37+
var dummy = Unsafe.As<global::TestNamespace.Person>(metadata);
38+
metadata.Fields = new[]
39+
{
40+
new global::BTDB.Serialization.FieldMetadata
41+
{
42+
Name = "Name",
43+
Type = typeof(string),
44+
ByteOffset = global::BTDB.Serialization.RawData.CalcOffset(dummy, ref Field1(dummy)),
45+
},
46+
new global::BTDB.Serialization.FieldMetadata
47+
{
48+
Name = "Id2Names",
49+
Type = typeof(global::System.Collections.Generic.IDictionary<int, (string, string)>),
50+
ByteOffset = global::BTDB.Serialization.RawData.CalcOffset(dummy, ref Field2(dummy)),
51+
},
52+
new global::BTDB.Serialization.FieldMetadata
53+
{
54+
Name = "NameSet2",
55+
Type = typeof(global::System.Collections.Generic.ISet<(string, int)>),
56+
ByteOffset = global::BTDB.Serialization.RawData.CalcOffset(dummy, ref Field3(dummy)),
57+
},
58+
};
59+
global::BTDB.Serialization.ReflectionMetadata.Register(metadata);
60+
}
61+
}

BTDB.SourceGenerator.Test/MetadataTests.cs

+18
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,24 @@ public class Person
9696
""");
9797
}
9898

99+
[Fact]
100+
public Task VerifyStructFromCollections()
101+
{
102+
// language=cs
103+
return VerifySourceGenerator("""
104+
using System.Collections.Generic;
105+
namespace TestNamespace;
106+
107+
[BTDB.Generate]
108+
public class Person
109+
{
110+
public string Name { get; set; } = "";
111+
public IDictionary<int,(string, string)> Id2Names { get; set; }
112+
public ISet<(string, int)> NameSet2 { get; set; }
113+
}
114+
""");
115+
}
116+
99117
[Fact]
100118
public Task VerifyImplementsInterface()
101119
{

0 commit comments

Comments
 (0)