From 7e99ae19bb8eff10d517b8677163610df829350f Mon Sep 17 00:00:00 2001 From: Walter Bright Date: Wed, 30 Dec 2015 03:48:56 -0800 Subject: [PATCH] Dwarf EH: add _d_eh_swapContextDwarf --- src/core/thread.d | 48 +++++++++++++++++++++++++++++++++++++++++++++-- src/rt/dwarfeh.d | 15 +++++++++++++++ 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/src/core/thread.d b/src/core/thread.d index d596862b72d..c55540412e6 100644 --- a/src/core/thread.d +++ b/src/core/thread.d @@ -118,6 +118,50 @@ private * is switched in for the first time. */ extern(C) void* _d_eh_swapContext(void* newContext) nothrow; + + version (DigitalMars) + { + version (Windows) + alias _d_eh_swapContext swapContext; + else + { + extern(C) void* _d_eh_swapContextDwarf(void* newContext) nothrow; + + void* swapContext(void* newContext) nothrow + { + /* Detect at runtime which scheme is being used. + * Eventually, determine it statically. + */ + static int which = 0; + final switch (which) + { + case 0: + { + assert(newContext == null); + auto p = _d_eh_swapContext(newContext); + auto pdwarf = _d_eh_swapContextDwarf(newContext); + if (p) + { + which = 1; + return p; + } + else if (pdwarf) + { + which = 2; + return pdwarf; + } + return null; + } + case 1: + return _d_eh_swapContext(newContext); + case 2: + return _d_eh_swapContextDwarf(newContext); + } + } + } + } + else + alias _d_eh_swapContext swapContext; } @@ -1461,7 +1505,7 @@ private: } body { - m_curr.ehContext = _d_eh_swapContext(c.ehContext); + m_curr.ehContext = swapContext(c.ehContext); c.within = m_curr; m_curr = c; } @@ -1476,7 +1520,7 @@ private: { Context* c = m_curr; m_curr = c.within; - c.ehContext = _d_eh_swapContext(m_curr.ehContext); + c.ehContext = swapContext(m_curr.ehContext); c.within = null; } diff --git a/src/rt/dwarfeh.d b/src/rt/dwarfeh.d index c9b63275cac..c348fd56e13 100644 --- a/src/rt/dwarfeh.d +++ b/src/rt/dwarfeh.d @@ -150,6 +150,21 @@ extern(C) Throwable __dmd_begin_catch(_Unwind_Exception* exceptionObject) return o; } +/**************************************** + * Called when fibers switch contexts. + * Params: + * newContext = stack to switch to + * Returns: + * previous value of stack + */ +extern(C) void* _d_eh_swapContextDwarf(void* newContext) nothrow +{ + auto old = ExceptionHeader.stack; + ExceptionHeader.stack = cast(ExceptionHeader*)newContext; + return old; +} + + /********************* * Called by D code to throw an exception via * ---