dotnet / runtimelab

This repo is for experimentation and exploring new ideas that may or may not make it into the main dotnet/runtime repo.
MIT License
1.36k stars 188 forks source link

[Discussion] Generate C# bindings for Foundation framework #2584

Open kotlarmilos opened 1 month ago

kotlarmilos commented 1 month ago

Objective

Our goal is to generate Foundation APIs bindings that can be consumed by other frameworks like CryptoKit and SwiftUI. This issue analyzes the implementation of the Foundation framework which should help us identify requirements for the projection tooling and runtime.

Numbers, data, and basic values

Primitive Swift types along with unsafe pointers are projected into C# types as outlined in this table.

The Foundation.Data is a frozen struct utilized within the CryptoKit framework and serves as a byte buffer in memory. This struct should be mapped to a C# struct that contains a sequence of 16-byte primitives. The representation depends on the length of the byte buffer. For buffers with a length of up to 15 bytes, the data is stored directly within the struct, with the last byte allocated for its length. If the buffer exceeds the struct’s capacity but is still small enough to fit a storage pointer + range in two words, it is represented by a slice: Range<HalfInt> and a storage: __DataStorage. If the buffer range is too large to fit in a single word, t is represented by a slice: RangeReference and storage: __DataStorage.

The Swift implementation of data representation is as follows:

internal enum _Representation : Sendable {
        case empty
        case inline(InlineData)
        case slice(InlineSlice)
        case large(LargeSlice)
}

In C#, enums can't hold values in addition to cases, and thus are projected as structs. Type Foundation.Data is heavily used across the frameworks, and can be projected as a blob of 16 bytes. This can be implemented as C# struct of fixed array of bytes:

[StructLayout(LayoutKind.Sequential, Size = 16)]
public unsafe struct Data {
    public fixed byte bytes[16];
}

Strings and text

TBD

Collections: Array, dictionary, and set

TBD

Tasks

List of tasks to support identified bindings: