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