Rantanen / intercom

Object based cross-language FFI for Rust
MIT License
63 stars 7 forks source link

Implement support for context parameters such as TypeSystem #84

Open Rantanen opened 5 years ago

Rantanen commented 5 years ago

There should be no technical reason to have 1:1 mapping between Rust and COM parameters. We are already coming up with COM OUT values based on Rust return types.

We could further skip some of the Rust method parameters on the COM level and fill these in by Intercom.

The primary (and for now only) use case for this would be the type system argument. Being able to tell what type system is being used to invoke a function has immediate use case in writing unit tests for Intercom itself. But it would also be required if someone wants to write methods by managing interface pointers, etc. themselves.

The big open question here is what kind of marker we'll want for such parameters. Below are some options in terms of the intercom::TypeSystem enum.

/// Assume certain types are always contextual types.
fn foo( &self, ts : intercom::TypeSystem );

/// Require an attribute on the parameter.
fn foo( &self, #[intercom::context] ts : intercom::TypeSystem );

/// Use a generic type instead.
fn foo( &self, ts : intercom::CallContext<intercom::TypeSystem> );

Personally I'm in favor of the first one. Intercom needs to be aware of these types anyway and as such we can be certain that these types are not COM-compatible (no #[repr(C)]).

The one dirty aspect with this is that when Rust wants to call such COM methods, there's no clean way to communicate to the caller that these things are not needed...

Although things like ts should probably affect the preference of which TS to use in case the ComItf we are using to call these methods happens to have both Automation and Raw interfaces available. Though is it an error if the asked interface is not available? There's no real TypeSystem::Any variant and we don't want one for output purposes.

Rantanen commented 4 years ago

Now that we've stripped a lot of the type handling into ExternType, I feel like having special handling for getting the context in the parameters would be a slight step backwards.

My current preference would be a thread local stack that receives the most current context when Intercom receives a call. I don't think the overhead should be too much, if we use the unsafe get...unguarded methods to access the stack RefCell (We'll just need to hide the TLS in a mod of its own so we can be failry certain it's used only in a safe manner after that).

Furthermore we might implement a fn-level #[uses_call_context]-attribute that would be required for that push/pop to happen so it wouldn't cause overhead on methods that don't need it.