Cesium
Cesium copied to clipboard
Struct layout calculation
To statically determine struct layout (for 32b, 64b and wide architecture sets), we'll need to calculate struct layout.
I am planning to make structures have Pack = 4 / 8 and LayoutKind.Explicit for these architectures.
See the documentation on pack.
Look for number 355 in the code when implementing this.
Hey, This looks interesting, and I want to contribute to this. Can you give me some more details regarding this issue so that I can start working on it asap?
Sure thing. This is a good task for new contributors, because it doesn't require deep knowledge of the existing code.
Here's a more detailed explanation.
We support several CPU architectures (or "architecture sets" as we call them right now): 64-bit, 32-bit, and dynamic. (Let's not talk about wide right now since it is not yet implemented, and dynamic is out of scope of this task anyway.)
Each bitness requires separate layout of nearly every C structure, because on different architectures, the pointer size are different.
.NET documentation outlines some basic layout rules, but I'm not sure if this is the full rule set, and even if it is, the wording is very suboptimal, so if you have some domain knowledge in C structure layout, that would be ideal (if not, then you could still try to read the documentation and test on some examples, that would be fine as well).
I want Cesium to support different struct layouts for different architectures, which mean:
- Set
Pack = 4orPack = 8inStructType.csbased on the target architecture set (already done). - Set an equivalent of
[StructLayout(LayoutKind.Explicit)]for all Cesium-generated structure types (seeStructType.cs:33)[^1]. - For every struct field, calculate the field layout and generate an equivalent of
[FieldOffset(x)]in the byte code for said field[^1]. - Taking into account these field layots, Cesium should properly calculate static type size as well (see
StructType.cs:80–84) – type size is used to allocate arrays of structures. - Ideally, this should be covered by the unit tests:
- check type sizes for Cesium structs and equivalent C# structs[^2],
- check field offsets for different struct fields and compare them[^3].
I don't require a contributor to implement everything at once; you can start in small steps and ask for help if/when you feel you need that.
[^1]: I don't know if an setting StructLayout and FieldOffset is straightforward in Mono.Cecil: certain C# attributes may be directly mapped to type metadata flags. This is left for the implementor to research.
[^2]: I've just found that that sizeof(T) works in C#, so that should be easy.
[^3]: To get a field offset in C#, you may compare a struct pointer with a field pointer, something like this:
```csharp
unsafe struct Foo
{
public int* Padding;
public long Field;
}
// …
var x = new Foo();
var structPtr = (byte*)&x;
var fieldPtr = (byte*)&x.Field;
var offset = fieldPtr - structPtr;
```