diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2002-08-19 00:37:16 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2002-08-19 00:37:16 +0000 |
commit | 11e7d457d6b86f5ca53440c7caadf679f4abff34 (patch) | |
tree | b328848b2192d29018190e64f0deffd81c794b8b /eval.c | |
parent | 4f60a534cd006a72f4b4b0cdf7b1f4cc205a81bd (diff) |
* eval.c (rb_thread_save_context, rb_thread_restore_context):
save/restore SEH chain on MS-Windows at thread switch.
[ruby-win32:273]
* eval.c (win32_get_exception_frame, win32_set_exception_frame):
added.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2716 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'eval.c')
-rw-r--r-- | eval.c | 56 |
1 files changed, 56 insertions, 0 deletions
@@ -7221,6 +7221,53 @@ Init_Proc() rb_define_method(rb_cModule, "instance_method", rb_mod_method, 1); } +/* Windows SEH refers data on the stack. */ +#ifdef _WIN32 +# if !(defined _M_IX86 || defined __i386__) +# error unsupported processor +# endif +static inline DWORD +win32_get_exception_list() +{ + DWORD p; +# if defined _MSC_VER +# ifdef _M_IX86 + __asm mov eax, fs:[0]; + __asm mov p, eax; +# endif +# elif defined __GNUC__ +# ifdef __i386__ + __asm__("movl %%fs:0,%0" : "=r"(p)); +# endif +# elif defined __BORLANDC__ + __emit__(0x64, 0xA1, 0, 0, 0, 0); /* mov eax, fs:[0] */ + p = _EAX; +# else +# error unsupported compiler +# endif + return p; +} + +static inline void +win32_set_exception_list() + DWORD p; +{ +# if defined _MSC_VER +# ifdef _M_IX86 + __asm mov eax, p; + __asm mov fs:[0], eax; +# endif +# elif defined __GNUC__ +# ifdef __i386__ + __asm__("movl %0,%%fs:0" :: "r"(p)); +# endif +# elif defined __BORLANDC__ + _EAX = p; + __emit__(0x64, 0xA3, 0, 0, 0, 0); /* mov fs:[0], eax */ +# endif +} +#endif + static VALUE rb_eThreadError; int rb_thread_pending = 0; @@ -7250,6 +7297,9 @@ enum thread_status { struct thread { struct thread *next, *prev; jmp_buf context; +#ifdef _WIN32 + DWORD win32_exception_list; +#endif VALUE result; @@ -7501,6 +7551,9 @@ rb_thread_save_context(th) th->stk_len = len; FLUSH_REGISTER_WINDOWS; MEMCPY(th->stk_ptr, th->stk_pos, VALUE, th->stk_len); +#ifdef _WIN32 + th->win32_exception_list = win32_get_exception_list(); +#endif th->frame = ruby_frame; th->scope = ruby_scope; @@ -7614,6 +7667,9 @@ rb_thread_restore_context(th, exit) ruby_current_node = th->node; +#ifdef _WIN32 + win32_set_exception_list(th->win32_exception_list); +#endif tmp = th; ex = exit; FLUSH_REGISTER_WINDOWS; |