Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update design docs to reflect our new marshaller design from partner feedback #71017

Merged
merged 5 commits into from
Jun 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions docs/design/libraries/LibraryImportGenerator/Compatibility.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@

Documentation on compatibility guidance and the current state. The version headings act as a rolling delta between the previous version.

## Version 2

The focus of version 2 is to support all repos that make up the .NET Product, including ASP.NET Core and Windows Forms, as well as all packages in dotnet/runtime.

### User defined type marshalling

Support for user-defined type marshalling in the source-generated marshalling is described in [UserTypeMarshallingV2.md](UserTypeMarshallingV2.md). This support replaces the designs specified in [StructMarshalling.md](StructMarshalling.md) and [SpanMarshallers.md](SpanMarshallers.md).


## Version 1

The focus of version 1 is to support `NetCoreApp`. This implies that anything not needed by `NetCoreApp` is subject to change.
Expand Down
12 changes: 10 additions & 2 deletions docs/design/libraries/LibraryImportGenerator/Pipeline.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,17 @@ The stub code generator itself will handle some initial setup and variable decla
1. `Pin`: data pinning in preparation for calling the generated P/Invoke
- Call `Generate` on the marshalling generator for every parameter
- Ignore any statements that are not `fixed` statements
1. `PinnedMarshal`: conversion of managed to native data
- Call `Generate` on the marshalling generator for every parameter
1. `Invoke`: call to the generated P/Invoke
- Call `AsArgument` on the marshalling generator for every parameter
- Create invocation statement that calls the generated P/Invoke
1. `KeepAlive`: keep alive any objects who's native representation won't keep them alive across the call.
1. `NotifyForSuccessfulInvoke`: Notify a marshaller that all stages through the "Invoke" stage were successful.
- Used to keep alive any objects who's native representation won't keep them alive across the call.
- Call `Generate` on the marshalling generator for every parameter.
1. `UnmarshalCapture`: capture any native out parameters to avoid memory leaks if exceptions are thrown during `Unmarshal`.
- If the method has a non-void return, call `Generate` on the marshalling generator for the return
- Call `Generate` on the marshalling generator for every parameter
1. `Unmarshal`: conversion of native to managed data
- If the method has a non-void return, call `Generate` on the marshalling generator for the return
- Call `Generate` on the marshalling generator for every parameter
Expand All @@ -97,9 +103,11 @@ try
<< Marshal >>
<< Pin >> (fixed)
{
<< Pinned Marshal >>
<< Invoke >>
}
<< Keep Alive >>
<< Notify For Successful Invoke >>
<< Unmarshal Capture >>
<< Unmarshal >>
}
finally
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

As part of the exit criteria for the LibraryImportGenerator experiment, we have decided to introduce support for marshalling `System.Span<T>` and `System.ReadOnlySpan<T>` into the LibraryImportGenerator-generated stubs. This document describes design decisions made during the implementation of these marshallers.

> NOTE: These design docs are kept for historical purposes. The designs in this file are superseded by the designs in [UserTypeMarshallingV2.md](UserTypeMarshallingV2.md).

## Design 1: "Intrinsic" support for `(ReadOnly)Span<T>`

In this design, the default support for `(ReadOnly)Span<T>` is emitted into the marshalling stub directly and builds on the pattern we enabled for arrays.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ As part of the new source-generated direction for .NET Interop, we are looking a

These types pose an interesting problem for a number of reasons listed below. With a few constraints, I believe we can create a system that will enable users to use their own user-defined types and pass them by-value to native code.

> NOTE: These design docs are kept for historical purposes. The designs in this file are superseded by the designs in [UserTypeMarshallingV2.md](UserTypeMarshallingV2.md).

## Problems

- What types require marshalling and what types can be passed as-is to native code?
Expand Down Expand Up @@ -139,7 +141,7 @@ When these `CallerAllocatedBuffer` feature flag is present, the source generator

Type authors can pass down the `buffer` pointer to native code by using the `TwoStageMarshalling` feature to provide a `ToNativeValue` method that returns a pointer to the first element, generally through code using `MemoryMarshal.GetReference()` and `Unsafe.AsPointer`. The `buffer` span must be pinned to be used safely. The `buffer` span can be pinned by defining a `GetPinnableReference()` method on the native type that returns a reference to the first element of the span.

### Determining if a type is doesn't need marshalling
### Determining if a type doesn't need marshalling

For this design, we need to decide how to determine a type doesn't need to be marshalled and already has a representation we can pass directly to native code - that is, we need a definition for "does not require marshalling". We have two designs that we have experimented with below, and we have decided to go with design 2.

Expand Down
Loading