Skip to content

[RFC] Simplify block creation pattern #4543

@rolfbjarne

Description

@rolfbjarne

The current pattern generated by the generator (and which we copy around liberally), goes something like this:

unsafe {
	BlockLiteral *block_ptr_handler;
	BlockLiteral block_handler;
	block_handler = new BlockLiteral ();
	block_ptr_handler = &block_handler;
	block_handler.SetupBlockUnsafe (blockCallback, userCallback);

	NativePInvoke ((void*) block_ptr_handler);
	block_ptr_handler->CleanupBlock ();
}

I think we can make it possible to simplify this a lot, so that we get down to:

using (var block = new BlockLiteral (blockCallback, userCallback, false))
    NativePInvoke (ref block);

This requires:

  • Make BlockLiteral implement IDisposable (and call CleanupBlock in Dispose).
  • Add a BlockLiteral constructor that takes the corresponding delegates.
  • Add support to the linker/optimizer for the new BlockLiteral constructor.
  • Change P/Invokes to take ref BlockLiteral instead of void * or IntPtr (this only works if the block isn't nullable).

Advantages

  • Much smaller & simpler C# code.
  • We won't leak the block if the P/Invoke (or any code after setting up the block) throws an exception.

Disadvantages

  • I think we'd end up creating more compiled (both IL and native), because of the additional exception handling by the using statement. This would need to be confirmed by testing though.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementThe issue or pull request is an enhancementiOSIssues affecting iOSmacOSIssues affecting macOSrequest-for-commentsThe issue is a suggested idea seeking feedback

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions