On 5/26/2017 2:31 PM, Steven Schveighoffer wrote:
"The destructor for Throwable will, if the refcount is 1, call _d_delThrowable(e.next), i.e. on the head of the chained list of exceptions."

How does this work if the throwable is being destroyed by the GC? In this case, e.next may be a dangling pointer.

The GC calls a finalizer which calls _d_delThrowable on the e.next value.

"it will call the new function _d_newThrowable() which will allocate E and intialize it for refcounting."

Where is it allocated?

My implementation uses malloc().

If on the GC heap,

It isn't.

how can it be @nogc?

And that's how it can be @nogc.

If not, then how does it interact with GC pointers?

The refcount of 0 means it is GC allocated.

e.g. the e.next pointer may point to a GC-allocated exception, how to stop the GC from collecting it early?

The usual way - register the roots with the GC. Take a look at the PRs for this, they do that.

Part of this may mean clarifying what @nogc actually means. Does it mean no interaction with the GC system, or does it mean "cannot run a collection cycle"?

@nogc means no GC allocations occur in the @nogc code, the same as usual, no more, no less.

"In catch blocks, e is regarded as scope so that it cannot escape the catch 
block."

If e is scope, then the destructor is called. However, since e is a reference type, the data it points at isn't really stack allocated, and the scope-ness ends at the reference, no? So what if you have something like this?

void *foo;

try
{
   func();
}
catch(MyException e)
{
    foo = e.voidptr; // get pointer to some member
}

Should foo be allowed to capture pieces of e? How does the compiler stop that if not?

That's what DIP 1000 addresses. DIP 1008 relies on DIP 1000.

What expectations can e assume in terms of its members that are references? Can it assume that it is in charge of the management of that memory if it's ref counted, or does it need to assume GC usage for those items?

See DIP 1000.

Reply via email to