summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog13
-rw-r--r--configure.in48
-rw-r--r--eval_intern.h10
-rw-r--r--gc.c16
-rw-r--r--vm_core.h2
5 files changed, 72 insertions, 17 deletions
diff --git a/ChangeLog b/ChangeLog
index 026d65a66b..e788d81a6b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+Tue Apr 1 02:58:39 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * configure.in (RUBY_SETJMP, RUBY_LONGJMP, RUBY_JMP_BUF): prefers
+ __builtin_setjmp, _setjmp over setjmp and sigsetjmp.
+ [ruby-core:16023], [ruby-core:16086]
+
+ * configure.in (--with-setjmp-type): new option to override the
+ default rule in the above.
+
+ * eval_intern.h (ruby_setjmp, ruby_longjmp), gc.c (rb_setjmp),
+ vm_core.h (rb_jmpbuf_t): use RUBY_SETJMP, RUBY_LONGJMP and
+ RUBY_JMP_BUF.
+
Tue Apr 1 01:55:52 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
* lib/resolv.rb (Resolv::Config.default_config_hash): requires
diff --git a/configure.in b/configure.in
index f2884a0b33..8d10a7b3b8 100644
--- a/configure.in
+++ b/configure.in
@@ -709,6 +709,54 @@ AC_CHECK_FUNCS(fmod killpg wait4 waitpid fork spawnv syscall chroot fsync getcwd
setuid setgid daemon select_large_fdset setenv unsetenv\
mktime timegm clock_gettime gettimeofday\
pread sendfile)
+
+AC_CACHE_CHECK(for __builtin_setjmp, ac_cv_func___builtin_setjmp,
+[AC_TRY_LINK([@%:@include <setjmp.h>
+ jmp_buf jb; void t() {__builtin_longjmp(jb, 1);}],
+ [__builtin_setjmp(jb);],
+ [ac_cv_func___builtin_setjmp=yes],
+ [ac_cv_func___builtin_setjmp=no])
+])
+
+AC_MSG_CHECKING(for setjmp type)
+AC_ARG_WITH(setjmp-type,
+ [ --with-setjmp-type select setjmp type], [
+ case $withval in
+ __builtin_setjmp) setjmp_prefix=__builtin_;;
+ _setjmp) setjmp_prefix=_;;
+ sigsetjmp) setjmp_prefix=sig;;
+ setjmp) setjmp_prefix=;;
+ '') unset setjmp_prefix;;
+ *) AC_MSG_ERROR(invalid setjmp type: $withval);;
+ esac], [unset setjmp_prefix])
+if test ${setjmp_prefix+set}; then
+ if test "${setjmp_prefix}" && eval test '$ac_cv_'${setjmp_prefix}setjmp = no; then
+ AC_MSG_ERROR(${setjmp_prefix}setjmp is not available)
+ fi
+elif test "$ac_cv_func___builtin_setjmp" = yes; then
+ setjmp_prefix=__builtin_
+elif test "$ac_cv_func__setjmp" = yes; then
+ setjmp_prefix=_
+elif test "$ac_cv_func_sigsetjmp" = yes; then
+ case $target_os in
+ solaris*|cygwin*)
+ setjmp_prefix=;;
+ *)
+ setjmp_prefix=sig;;
+ esac
+else
+ setjmp_prefix=
+fi
+if test $setjmp_prefix = sig; then
+ setjmp_sigmask=yes
+else
+ unset setjmp_sigmask
+fi
+AC_MSG_RESULT(${setjmp_prefix}setjmp)
+AC_DEFINE_UNQUOTED([RUBY_SETJMP(env)], [${setjmp_prefix}setjmp(env${setjmp_sigmask+,0})])
+AC_DEFINE_UNQUOTED([RUBY_LONGJMP(env,val)], [${setjmp_prefix}longjmp(env,val)])
+AC_DEFINE_UNQUOTED(RUBY_JMP_BUF, ${setjmp_sigmask+${setjmp_prefix}}jmp_buf)
+
AC_ARG_ENABLE(setreuid,
[ --enable-setreuid use setreuid()/setregid() according to need even if obsolete.],
[use_setreuid=$enableval])
diff --git a/eval_intern.h b/eval_intern.h
index 52d2969844..8296ee0f51 100644
--- a/eval_intern.h
+++ b/eval_intern.h
@@ -81,12 +81,10 @@ char *strrchr(const char *, const char);
#include "vmsruby_private.h"
#endif
-#if !defined(setjmp) && defined(HAVE__SETJMP) && !defined(sigsetjmp) && !defined(HAVE_SIGSETJMP)
-#define ruby_setjmp(env) _setjmp(env)
-#define ruby_longjmp(env,val) _longjmp(env,val)
-#else
-#define ruby_setjmp(env) setjmp(env)
-#define ruby_longjmp(env,val) longjmp(env,val)
+#define ruby_setjmp(env) RUBY_SETJMP(env)
+#define ruby_longjmp(env,val) RUBY_LONGJMP(env,val)
+#ifdef __CYGWIN__
+int _setjmp(), _longjmp();
#endif
#include <sys/types.h>
diff --git a/gc.c b/gc.c
index f54048718f..e090b0db49 100644
--- a/gc.c
+++ b/gc.c
@@ -52,9 +52,8 @@
int rb_io_fptr_finalize(struct rb_io_t*);
-#if !defined(setjmp) && defined(HAVE__SETJMP) && !defined(sigsetjmp) && !defined(HAVE_SIGSETJMP)
-#define setjmp(env) _setjmp(env)
-#endif
+#define rb_setjmp(env) RUBY_SETJMP(env)
+#define rb_jmp_buf rb_jmpbuf_t
/* Make alloca work the best possible way. */
#ifdef __GNUC__
@@ -1427,6 +1426,8 @@ obj_free(VALUE obj)
#ifdef __GNUC__
#if defined(__human68k__) || defined(DJGPP)
+#undef rb_setjmp
+#undef rb_jmp_buf
#if defined(__human68k__)
typedef unsigned long rb_jmp_buf[8];
__asm__ (".even\n\
@@ -1435,9 +1436,6 @@ _rb_setjmp:\n\
movem.l d3-d7/a3-a5,(a0)\n\
moveq.l #0,d0\n\
rts");
-#ifdef setjmp
-#undef setjmp
-#endif
#else
#if defined(DJGPP)
typedef unsigned long rb_jmp_buf[6];
@@ -1458,8 +1456,6 @@ _rb_setjmp:\n\
#endif
#endif
int rb_setjmp (rb_jmp_buf);
-#define jmp_buf rb_jmp_buf
-#define setjmp rb_setjmp
#endif /* __human68k__ or DJGPP */
#endif /* __GNUC__ */
@@ -1470,7 +1466,7 @@ void rb_vm_mark(void *ptr);
static void
mark_current_machine_context(rb_thread_t *th)
{
- jmp_buf save_regs_gc_mark;
+ rb_jmp_buf save_regs_gc_mark;
VALUE *stack_start, *stack_end;
SET_STACK_END;
@@ -1493,7 +1489,7 @@ mark_current_machine_context(rb_thread_t *th)
FLUSH_REGISTER_WINDOWS;
/* This assumes that all registers are saved into the jmp_buf (and stack) */
- setjmp(save_regs_gc_mark);
+ rb_setjmp(save_regs_gc_mark);
mark_locations_array((VALUE*)save_regs_gc_mark,
sizeof(save_regs_gc_mark) / sizeof(VALUE));
diff --git a/vm_core.h b/vm_core.h
index 551e87a48a..540175cba5 100644
--- a/vm_core.h
+++ b/vm_core.h
@@ -346,7 +346,7 @@ enum rb_thread_status {
THREAD_KILLED,
};
-typedef jmp_buf rb_jmpbuf_t;
+typedef RUBY_JMP_BUF rb_jmpbuf_t;
struct rb_vm_tag {
rb_jmpbuf_t buf;