summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--eval.c56
2 files changed, 65 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 2ebab00ca3..8072844853 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+Mon Aug 19 09:36:00 2002 Nobuyoshi Nakada <nobu.nokada@softhome.net>
+
+ * 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.
+
Fri Aug 16 15:58:16 2002 WATANABE Hirofumi <eban@ruby-lang.org>
* io.c (NOFILE): define NOFILE as 64 if not defined.
diff --git a/eval.c b/eval.c
index ee19b03c2b..7a32be4574 100644
--- a/eval.c
+++ b/eval.c
@@ -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;