Skip to content

Commit

Permalink
Generate StackAllocations automatically.
Browse files Browse the repository at this point in the history
  • Loading branch information
Bobris committed Apr 28, 2024
1 parent e9edf8c commit 00fa856
Show file tree
Hide file tree
Showing 9 changed files with 395 additions and 24 deletions.
1 change: 1 addition & 0 deletions BTDB.SourceGenerator.Sample/Examples.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
Creator = &Create1,
AdderKeyValue = &Add1
});
ReflectionMetadata.RegisterStackAllocator(typeof((int, string)), &AllocateValueType);
}

MyCtx myCtx = default;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//HintName: StackAllocationRegistrations.g.cs
// <auto-generated/>
#nullable enable
#pragma warning disable CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type
using System;
using System.Runtime.CompilerServices;
[CompilerGenerated]
static file class StackAllocationRegistrations
{
[ModuleInitializer]
internal static unsafe void Register4BTDB()
{
BTDB.Serialization.ReflectionMetadata.RegisterStackAllocator(typeof(int), &Allocate1);
static void Allocate1(ref byte ctx, ref nint ptr, delegate*<ref byte, void> chain)
{
int value;
ptr = (nint)(&value);
chain(ref ctx);
ptr = 0;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//HintName: StackAllocationRegistrations.g.cs
// <auto-generated/>
#nullable enable
#pragma warning disable CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type
using System;
using System.Runtime.CompilerServices;
[CompilerGenerated]
static file class StackAllocationRegistrations
{
[ModuleInitializer]
internal static unsafe void Register4BTDB()
{
BTDB.Serialization.ReflectionMetadata.RegisterStackAllocator(typeof(int), &Allocate1);
static void Allocate1(ref byte ctx, ref nint ptr, delegate*<ref byte, void> chain)
{
int value;
ptr = (nint)(&value);
chain(ref ctx);
ptr = 0;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//HintName: StackAllocationRegistrations.g.cs
// <auto-generated/>
#nullable enable
#pragma warning disable CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type
using System;
using System.Runtime.CompilerServices;
[CompilerGenerated]
static file class StackAllocationRegistrations
{
[ModuleInitializer]
internal static unsafe void Register4BTDB()
{
BTDB.Serialization.ReflectionMetadata.RegisterStackAllocator(typeof(int), &Allocate1);
static void Allocate1(ref byte ctx, ref nint ptr, delegate*<ref byte, void> chain)
{
int value;
ptr = (nint)(&value);
chain(ref ctx);
ptr = 0;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
//HintName: CollectionRegistrations.g.cs
// <auto-generated/>
#nullable enable
using System;
using System.Runtime.CompilerServices;
[CompilerGenerated]
static file class CollectionRegistrations
{
[ModuleInitializer]
internal static void Register4BTDB()
{
BTDB.Serialization.ReflectionMetadata.RegisterCollection(new()
{
Type = typeof(global::System.Collections.Generic.IDictionary<int, (string, string)>),
ElementKeyType = typeof(int),
ElementValueType = typeof((string, string)),
Creator = &Create1,
AdderKeyValue = &Add1
});

static object Create1(uint capacity)
{
return new global::System.Collections.Generic.Dictionary<int, (string, string)>((int)capacity);
}

static void Add1(object c, ref byte key, ref byte value)
{
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));
}

BTDB.Serialization.ReflectionMetadata.RegisterCollection(new()
{
Type = typeof(global::System.Collections.Generic.ISet<(string, int)>),
ElementKeyType = typeof((string, int)),
Creator = &Create2,
Adder = &Add2
});

static object Create2(uint capacity)
{
return new global::System.Collections.Generic.HashSet<(string, int)>((int)capacity);
}

static void Add2(object c, ref byte value)
{
Unsafe.As<global::System.Collections.Generic.HashSet<(string, int)>>(c).Add(Unsafe.As<byte, (string, int)>(ref value));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//HintName: StackAllocationRegistrations.g.cs
// <auto-generated/>
#nullable enable
#pragma warning disable CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type
using System;
using System.Runtime.CompilerServices;
[CompilerGenerated]
static file class StackAllocationRegistrations
{
[ModuleInitializer]
internal static unsafe void Register4BTDB()
{
BTDB.Serialization.ReflectionMetadata.RegisterStackAllocator(typeof(int), &Allocate1);
static void Allocate1(ref byte ctx, ref nint ptr, delegate*<ref byte, void> chain)
{
int value;
ptr = (nint)(&value);
chain(ref ctx);
ptr = 0;
}

BTDB.Serialization.ReflectionMetadata.RegisterStackAllocator(typeof((string, string)), &Allocate2);
static void Allocate2(ref byte ctx, ref nint ptr, delegate*<ref byte, void> chain)
{
(string, string) value;
ptr = (nint)(&value);
chain(ref ctx);
ptr = 0;
}

BTDB.Serialization.ReflectionMetadata.RegisterStackAllocator(typeof((string, int)), &Allocate3);
static void Allocate3(ref byte ctx, ref nint ptr, delegate*<ref byte, void> chain)
{
(string, int) value;
ptr = (nint)(&value);
chain(ref ctx);
ptr = 0;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
//HintName: TestNamespace.Person.g.cs
// <auto-generated/>
#pragma warning disable 612,618
using System;
using System.Runtime.CompilerServices;

namespace TestNamespace;

[CompilerGenerated]
static file class PersonRegistration
{
[UnsafeAccessor(UnsafeAccessorKind.Constructor)]
extern static global::TestNamespace.Person Creator();
[UnsafeAccessor(UnsafeAccessorKind.Field, Name = "<Name>k__BackingField")]
extern static ref string Field1(global::TestNamespace.Person @this);
[UnsafeAccessor(UnsafeAccessorKind.Field, Name = "<Id2Names>k__BackingField")]
extern static ref global::System.Collections.Generic.IDictionary<int, (string, string)> Field2(global::TestNamespace.Person @this);
[UnsafeAccessor(UnsafeAccessorKind.Field, Name = "<NameSet2>k__BackingField")]
extern static ref global::System.Collections.Generic.ISet<(string, int)> Field3(global::TestNamespace.Person @this);
[ModuleInitializer]
internal static unsafe void Register4BTDB()
{
global::BTDB.IOC.IContainer.RegisterFactory(typeof(global::TestNamespace.Person), (container, ctx) =>
{
return (container2, ctx2) =>
{
var res = new global::TestNamespace.Person();
return res;
};
});
var metadata = new global::BTDB.Serialization.ClassMetadata();
metadata.Name = "Person";
metadata.Type = typeof(global::TestNamespace.Person);
metadata.Namespace = "TestNamespace";
metadata.Implements = [];
metadata.Creator = &Creator;
var dummy = Unsafe.As<global::TestNamespace.Person>(metadata);
metadata.Fields = new[]
{
new global::BTDB.Serialization.FieldMetadata
{
Name = "Name",
Type = typeof(string),
ByteOffset = global::BTDB.Serialization.RawData.CalcOffset(dummy, ref Field1(dummy)),
},
new global::BTDB.Serialization.FieldMetadata
{
Name = "Id2Names",
Type = typeof(global::System.Collections.Generic.IDictionary<int, (string, string)>),
ByteOffset = global::BTDB.Serialization.RawData.CalcOffset(dummy, ref Field2(dummy)),
},
new global::BTDB.Serialization.FieldMetadata
{
Name = "NameSet2",
Type = typeof(global::System.Collections.Generic.ISet<(string, int)>),
ByteOffset = global::BTDB.Serialization.RawData.CalcOffset(dummy, ref Field3(dummy)),
},
};
global::BTDB.Serialization.ReflectionMetadata.Register(metadata);
}
}
18 changes: 18 additions & 0 deletions BTDB.SourceGenerator.Test/MetadataTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,24 @@ public class Person
""");
}

[Fact]
public Task VerifyStructFromCollections()
{
// language=cs
return VerifySourceGenerator("""
using System.Collections.Generic;
namespace TestNamespace;

[BTDB.Generate]
public class Person
{
public string Name { get; set; } = "";
public IDictionary<int,(string, string)> Id2Names { get; set; }
public ISet<(string, int)> NameSet2 { get; set; }
}
""");
}

[Fact]
public Task VerifyImplementsInterface()
{
Expand Down

0 comments on commit 00fa856

Please sign in to comment.