xamarin / binding-tools-for-swift

MIT License
157 stars 21 forks source link

Add gchandle to all receivers #832

Closed stephen-hawley closed 6 months ago

stephen-hawley commented 6 months ago

In the last PR, I added a GCHandle to all the vtable representations (both C# and Swift).

This PR builds on that and adds the GCHandle to be the first argument for all of the receivers.

I'm not really happy with this because the code in MarshalEngineCSafeSwiftToCSharp was full of magic numbers in the marshaling code. The problem is that the meaning of the index depends HEAVILY on the context in which they're used so making variables to represent them makes things worse IMHO (in terms of complication), but better in terms of future usage. Since in future usage, a lot (if not all) of this code is going to go away due to runtime support for the same actions, I'm not too too concerned of leaving it how it is.

When you call a receiver (this is the C# function that gets called from Swift in order to implement a virtual or protocol method), you will have the following arguments:

GCHandle [ReturnPointer] InstancePointer [args]

The Return pointer is there if the return type can't be marshaled directly or when the implementation may throw. If it can throw, then the return type is a Medusa tuple which contains a bool to indicate whether or not the exception was thrown, a pointer to space for the return value (if there was no exception), and a pointer to the exception if the exception was thrown.