BetterC + Windows + setjmp longjmp

Diederik de Groot ddegroot at talon.nl
Wed Sep 19 11:06:23 UTC 2018


On Tuesday, 18 September 2018 at 19:45:18 UTC, SrMordred wrote:
> On Tuesday, 18 September 2018 at 03:09:18 UTC, Mike Parker 
> wrote:
>> On Tuesday, 18 September 2018 at 00:24:23 UTC, SrMordred wrote:
>>
>>> Yes, i'm using signal(SIGSEGV, sigfn_t func), it catches 
>>> correctly, but end the execution after.
>>>
>>> I find the alternatives of setjmp/longjmp and sigaction, but 
>>> none are avaliable on windows afaik.
>>
>> setjmp/longjmp are available on windows (image loaders using 
>> libpng, lua, quake3, and lots of old C code make use of them):
>>
>> https://msdn.microsoft.com/en-us/library/xe7acxfb.aspx?f=255&MSPPError=-2147217396
>> https://msdn.microsoft.com/en-us/library/3ye15wsy.aspx
>>
>> You can declare the functions in your own code and they should 
>> link just fine. It would be helpful if you also submit a PR to 
>> add them to DRuntime for Windows.
>>
>> As for sigaction, a quick search suggests it isn't available 
>> (and it doesn't show up in MSDN):
>>
>> https://stackoverflow.com/questions/32389905/sigaction-and-porting-linux-code-to-windows
>
> I think this may be going beyond my knowledge ;/
>
> (Trying to follow setjmp.h, don´t have experience doing this)
>
> enum _SIGSET_NWORDS = (1024 / (8 * (ulong.sizeof)));
> struct __sigset_t
> {
>     ulong[_SIGSET_NWORDS] __val;
> }
>
> struct __jmp_buf_tag
> {
>     long[8] __jmpbuf;
>     int __mask_was_saved;
>     __sigset_t __saved_mask;
> };
>
> alias __jmp_buf_tag[1] jmp_buf;
>
> extern (C) @nogc nothrow  int setjmp(ref jmp_buf) ;
> extern (C) @nogc nothrow void longjmp(ref jmp_buf, int);

I think your definition should look more like this:
Notes:
- modulename using druntime path.
- Not 100% sure about all the sizes (lifted from winsdk10).
    - long/c_long
    - JBLEN or JBLEN+1
- Compatible with MARS setjmp.h x86 sizes
------
module core.sys.windows.setjmp;

extern (C):
@system:
nothrow:
@nogc:

private import core.sys.windows.config;
import core.stdc.signal;

version ( Windows ):
version( X86 )
{
     enum _JBLEN 16
     struct _jmp_buf { int[_JBLEN + 1] _ssjb; }
}
else version( X86_64)
{
     enum _JBLEN 16
     struct {
         long[2] part;   // c_long ?
     } float128;
     struct _jmp_buf { float128[_JBLEN] _sjb;
}
else version (AArch64)
{
     enum _JBLEN 28
     struct _jmp_buf { int[_JBLEN] _sjb; }
}
/*
else version (IA64)
{
     enum _JBLEN 33
     struct {
         long _high;
         long _low;
     } float128;
     struct _jmp_buf { float128[_JBLEN] _sjb;
}
*/
else
     static assert(0, "Not implemented for platforms other than 
X86, yet");

alias _jmp_buf[_JBLEN] jmp_buf;

int  setjmp(ref jmp_buf);
void longjmp(ref jmp_buf, int);
--------
Only the exact size of the jmp_buf is important (not the details 
about the content). We only call a function with it, we never 
look inside.



More information about the Digitalmars-d-learn mailing list