Biohazrd icon indicating copy to clipboard operation
Biohazrd copied to clipboard

Meta: Proper and friendly constructor/destructor support

Open PathogenDavid opened this issue 2 years ago • 0 comments

Up until now I've mostly ignored object construction/destruction because most libraries we've used with Biohazrd thus far have primarily had object lifetimes managed by the target library. (IE: Things are allocated and deallocated exclusively in native code.)

This isn't sustainable long-term, as many libraries (and even some aspects of libraries we already wrap) expect you to manage object lifetimes yourself.

At a high level, we need to support the following:

  • [ ] Create an analyzer to error when calling new() or using default(T) when it would bypass the constructor. (These should be separate diagnostics.)
    • [ ] We should also detect situations where no constructor is called at all and all fields are manually populated. IE: SharpLab.
    • [ ] https://github.com/MochiLibraries/Biohazrd/issues/231
  • [x] Allow allocating C++ objects on the managed stack. (Just works™)
  • [ ] Allow destroying C++ objects on the managed stack. (Currently broken)
    • [ ] Microsoft broken by bug: https://github.com/MochiLibraries/Biohazrd/issues/243
    • [ ] Itanium needs to expose complete object destructor: https://github.com/MochiLibraries/Biohazrd/issues/210
  • [ ] Allow allocating C++ objects on the native heap.
    • At a glance it looks like Microsoft and Itanium both implement this by calling operator new to allocate memory and then separately call the constructor.
  • [ ] Allow deallocating C++ objects on the native heap.
    • On Microsoft this is basically calling the destructor with an implicit shouldDelete parameter set to 1. (See https://github.com/MochiLibraries/Biohazrd/issues/243)
    • On Itanium there is a separate deleting destructor which is called instead.
  • [ ] Allow allocating C++ objects extended in C# on some heap.
    • Right now the Mochi.PhysX snippets have a Pinned<T> helper which basically lets you do this on the managed heap. Unfortunately .NET limitations mean T cannot contain managed references. (You can only really pin managed objects via an interior pointer and can't allocate them on the pinned heap.)
  • [ ] Allow deallocating C++ objects extended in C# from some heap.
    • Most notably this needs to support calling the base destructor.

It would also be nice if we could find a way to properly manage the above situations using IDisposable. It's tricky in C# since we don't intrinsically know how the object was allocated like we do in C++. Dispose()/using makes sense for stack-allocated objects, but less so for heap-allocated ones. We don't want to accidentally mislead people into thinking they can/should call Dispose() on heap-allocated objects and cause the destructor to be called without actually freeing memory. (Although if we don't permit allocating on the native heap -- IE: Only allow something like Pinned<T> this becomes a non-issue I think?)

Since C++ objects expect automatic destructor calls for stack-allocated objects, it might also be helpful to implement an analyzer to tell people to use using for objects allocated on the stack from C#. It's pretty easy to accidentally miss this when porting code from C++ since it's implicit there.

Additionally we need to investigate how virtual destructors affect any or all of the above.


The follow issues relate to this effort:

  • [ ] https://github.com/MochiLibraries/Biohazrd/issues/14
  • [ ] https://github.com/MochiLibraries/Biohazrd/issues/160
  • [ ] https://github.com/MochiLibraries/Biohazrd/issues/161
  • [ ] https://github.com/MochiLibraries/Biohazrd/issues/162
  • [ ] https://github.com/MochiLibraries/Biohazrd/issues/159
  • [ ] https://github.com/MochiLibraries/Biohazrd/issues/210
  • [ ] https://github.com/MochiLibraries/Biohazrd/issues/231
  • [ ] https://github.com/MochiLibraries/Biohazrd/issues/243

See also https://github.com/MochiLibraries/Biohazrd/issues/163

PathogenDavid avatar May 06 '22 13:05 PathogenDavid