diff --git a/ChangeLog b/ChangeLog
index 4c7e3ac..708f5bc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,51 @@
+Wed Mar 1 12:01:19 2009 Brent Roman <brent@mbari.org>
+
+ * eval.c: fixed missed volatile qualifiers
+
+ * version.h: bumped date, MBARI version 8A --> 8B
+
+Wed Feb 27 12:01:19 2009 Brent Roman <brent@mbari.org>
+
+ * rubysig.c: added support for __anyPowerPC__
+
+ * version.h: bumped date
+
+Wed Feb 25 12:01:19 2009 Brent Roman <brent@mbari.org>
+
+ * gc.c: default GC.limit=2e6*sizeof(VALUE)
+
+ * eval.c: added RB_GC_GUARDs to eval_slit() & more volatile tweaks
+
+ * re.c: removed unneeded volatile qualifier & copy in rb_regcomp()
+
+ * version.h: bumped date, MBARI version 7A --> 8A
+
+Tue Feb 24 00:01:19 2009 Brent Roman <brent@mbari.org>
+
+ * cofigure.in: added --enable-mbari-api and --with-wipe-sites
+
+ * signal.c: removed CHECK_INTS after kill
+
+ * test/ruby/suicide.rb: add tiny delay to let signal propogate
+
+ * gc.c: save regs properly on main stack before marking it!
+
+ * eval.c: numerous corrections in use of volatile variables w/setjmp()
+
+ * version.h: bumped date, MBARI version 7+ --> 7A
+
+Fri Feb 13 00:01:19 2009 Brent Roman <brent@mbari.org>
+
+ * signal.c: CHECK_INTS after kill in case of suicide
+
+ * version.h: bumped date
+
+Tue Feb 10 00:01:19 2009 Brent Roman <brent@mbari.org>
+
+ * gc.c: don't redundantly mark stack before base of current thread
+
+ * version.h: bumped date
+
Mon Feb 09 00:01:19 2009 Brent Roman <brent@mbari.org>
* rubysig.h: default values for STACK_WIPE_SITES if x86_64
diff --git a/configure.in b/configure.in
index fe63c0c..885bfc0 100644
--- a/configure.in
+++ b/configure.in
@@ -151,6 +151,24 @@ AC_ARG_ENABLE(frame-address,
if test $frame_address = yes; then
AC_DEFINE(USE_BUILTIN_FRAME_ADDRESS)
fi
+AC_ARG_ENABLE(mbari-api,
+ [ --enable-mbari-api enable API changes from the MBARI patches. ],
+ [mbari_api=$enableval])
+if test "$mbari_api" = yes; then
+ AC_DEFINE(MBARI_API)
+fi
+AC_ARG_WITH(wipe-sites,
+[ --with-wipe-sites=MASK override default STACK_WIPES_SITES mask in rubysig.h],
+[wipe_sites=$withval])
+if test "$wipe_sites" != ""; then
+ case $wipe_sites in
+ none|no) wipe_sites=0x0;;
+ yes) wipe_sites=;;
+ esac
+ if test -n "$wipe_sites"; then
+ AC_DEFINE_UNQUOTED(STACK_WIPE_SITES,$wipe_sites)
+ fi
+fi
AC_ARG_PROGRAM
@@ -1783,7 +1801,7 @@ AC_DEFINE_UNQUOTED(RUBY_SITE_ARCHLIB, "${RUBY_SITE_LIB_PATH2}/${sitearch}")
AC_DEFINE_UNQUOTED(RUBY_VENDOR_ARCHLIB, "${RUBY_VENDOR_LIB_PATH2}/${sitearch}")
AC_ARG_WITH(search-path,
- [ --with-search-path=DIR specify the additional search path],
+ [ --with-search-path= DIR specify the additional search path],
[search_path=$withval])
if test "$search_path" != ""; then
AC_DEFINE_UNQUOTED(RUBY_SEARCH_PATH,"$search_path")
diff --git a/eval.c b/eval.c
index e9ce2b7..a73bd2b 100644
--- a/eval.c
+++ b/eval.c
@@ -221,7 +221,7 @@ static VALUE proc_invoke _((VALUE,VALUE,VALUE,VALUE));
static VALUE rb_f_binding _((VALUE));
NOINLINE(static void rb_f_END _((void)));
static VALUE rb_f_block_given_p _((void));
-static VALUE block_pass _((VALUE,NODE*));
+static VALUE block_pass _((volatile VALUE, NODE *volatile));
VALUE rb_cMethod;
static VALUE method_call _((int, VALUE*, VALUE));
@@ -243,6 +243,30 @@ static int scope_vmode;
VALUE (*ruby_sandbox_save)_((rb_thread_t));
VALUE (*ruby_sandbox_restore)_((rb_thread_t));
NODE* ruby_current_node;
+
+#if 0
+#define SET_CURRENT_SOURCE() (ruby_sourcefile = ruby_current_node->nd_file, \
+ ruby_sourceline = nd_line(ruby_current_node))
+#else
+#define SET_CURRENT_SOURCE() ((void)0)
+#endif
+
+void
+ruby_set_current_source()
+{
+ if (ruby_current_node) {
+ ruby_sourcefile = ruby_current_node->nd_file;
+ ruby_sourceline = nd_line(ruby_current_node);
+ }
+}
+
+#ifdef MBARI_API
+#define SET_METHOD_SOURCE() ruby_set_current_source()
+#else
+#define SET_METHOD_SOURCE() (void)0
+#endif
+
+
int ruby_safe_level = 0;
/* safe-level:
0 - strings from streams/environment/ARGV are tainted (default)
@@ -726,7 +750,7 @@ rb_attr(klass, id, read, write, ex)
if (!name) {
rb_raise(rb_eArgError, "argument needs to be symbol or string");
}
- ruby_set_current_source(); /* for Method#__line__ */
+ SET_METHOD_SOURCE();
len = strlen(name)+2;
buf = ALLOCA_N(char,len);
snprintf(buf, len, "@%s", name);
@@ -965,7 +989,7 @@ rb_svar(cnt)
ID id;
if (!ruby_scope->local_tbl) return NULL;
- if (cnt >= ruby_scope->local_tbl[0]) return NULL;
+ if ((ID)cnt >= ruby_scope->local_tbl[0]) return NULL;
id = ruby_scope->local_tbl[cnt+1];
while (vars) {
if (vars->id == id) return &vars->val;
@@ -1123,10 +1147,11 @@ static void scope_dup _((struct SCOPE *));
} while (0)
static VALUE rb_eval _((VALUE,NODE*));
-static VALUE eval _((VALUE,VALUE,VALUE,const char*,int));
+static VALUE eval _((VALUE,VALUE,volatile VALUE,const char* volatile,int));
static NODE *compile _((VALUE, const char*, int));
-static VALUE rb_yield_0 _((VALUE, VALUE, VALUE, int, int));
+static VALUE rb_yield_0
+ _((volatile VALUE, volatile VALUE, VALUE, int, volatile int));
#if STACK_WIPE_SITES & 0x20
#define wipeBeforeYield() rb_gc_wipe_stack()
@@ -1142,7 +1167,7 @@ static VALUE rb_yield_0 _((VALUE, VALUE, VALUE, int, int));
#define YIELD_FUNC_LAMBDA 3
static VALUE rb_call _((VALUE,VALUE,ID,int,const VALUE*,int,VALUE));
-static VALUE module_setup _((VALUE,NODE*));
+static VALUE module_setup _((VALUE,NODE *volatile));
static VALUE massign _((VALUE,NODE*,VALUE,int));
static void assign _((VALUE,NODE*,VALUE,int));
@@ -1174,22 +1199,6 @@ static VALUE trace_func = 0;
static int tracing = 0;
static void call_trace_func _((rb_event_t,NODE*,VALUE,ID,VALUE));
-#if 0
-#define SET_CURRENT_SOURCE() (ruby_sourcefile = ruby_current_node->nd_file, \
- ruby_sourceline = nd_line(ruby_current_node))
-#else
-#define SET_CURRENT_SOURCE() ((void)0)
-#endif
-
-void
-ruby_set_current_source()
-{
- if (ruby_current_node) {
- ruby_sourcefile = ruby_current_node->nd_file;
- ruby_sourceline = nd_line(ruby_current_node);
- }
-}
-
static void
#ifdef HAVE_STDARG_PROTOTYPES
warn_printf(const char *fmt, ...)
@@ -1251,15 +1260,15 @@ set_backtrace(info, bt)
static void
error_print()
{
- VALUE errat = Qnil; /* OK */
+ VALUE errat;
volatile VALUE eclass, e;
- const char *einfo;
+ const char * einfo;
long elen;
if (NIL_P(ruby_errinfo)) return;
PUSH_TAG(PROT_NONE);
- errat = EXEC_TAG() == 0 ? get_backtrace(ruby_errinfo) : Qnil;
+ errat = EXEC_TAG() ? Qnil : get_backtrace(ruby_errinfo);
if (EXEC_TAG()) goto error;
if (NIL_P(errat)){
ruby_set_current_source();
@@ -1442,7 +1451,7 @@ ruby_init()
}
static VALUE
-eval_node(self, node)
+eval_tree(self, node)
VALUE self;
NODE *node;
{
@@ -1591,12 +1600,13 @@ ruby_finalize()
}
int
-ruby_cleanup(ex)
- int ex;
+ruby_cleanup(exArg)
+ int exArg;
{
int state;
volatile VALUE errs[2];
- int nerr;
+ unsigned nerr;
+ volatile int ex = exArg;
errs[1] = ruby_errinfo;
ruby_safe_level = 0;
@@ -1659,7 +1669,7 @@ ruby_exec_internal()
/* default visibility is private at toplevel */
SCOPE_SET(SCOPE_PRIVATE);
if ((state = EXEC_TAG()) == 0) {
- eval_node(ruby_top_self, ruby_eval_tree);
+ eval_tree(ruby_top_self, ruby_eval_tree);
}
POP_ITER();
POP_TAG();
@@ -1867,8 +1877,8 @@ rb_eval_cmd(cmd, arg, level)
int level;
{
int state;
- VALUE val = Qnil; /* OK */
- struct SCOPE *saved_scope;
+ VALUE val;
+ struct SCOPE * volatile saved_scope;
volatile int safe = ruby_safe_level;
if (OBJ_TAINTED(cmd)) {
@@ -1899,9 +1909,7 @@ rb_eval_cmd(cmd, arg, level)
ruby_safe_level = level;
PUSH_TAG(PROT_NONE);
- if ((state = EXEC_TAG()) == 0) {
- val = eval(ruby_top_self, cmd, Qnil, 0, 0);
- }
+ val = (state = EXEC_TAG()) ? Qnil : eval(ruby_top_self, cmd, Qnil, 0, 0);
if (ruby_scope->flags & SCOPE_DONT_RECYCLE)
scope_dup(saved_scope);
ruby_scope = saved_scope;
@@ -1940,8 +1948,12 @@ ev_const_defined(cref, id, self)
return rb_const_defined(cref->nd_clss, id);
}
-NOINLINE(static VALUE
-ev_const_get(cref, id, self))
+NOINLINE(static VALUE ev_const_get _((NODE *cref, ID id, VALUE self)));
+NOINLINE(static void eval_cvar_set _((NODE *node, VALUE result, int warn)));
+NOINLINE(static void eval_cdecl _((VALUE self, NODE *node, VALUE value)));
+
+static VALUE
+ev_const_get(cref, id, self)
NODE *cref;
ID id;
VALUE self;
@@ -2268,8 +2280,8 @@ rb_copy_node_scope(node, rval)
NODE *rval;
{
NODE *copy;
-
- ruby_set_current_source(); /* for Method#__line__ */
+
+ SET_METHOD_SOURCE();
copy=NEW_NODE(NODE_SCOPE,0,rval,node->nd_next);
if (node->nd_tbl) {
@@ -2377,10 +2389,10 @@ arg_defined(self, node, buf, type)
static const char*
is_defined(self, node, buf)
VALUE self;
- NODE *node; /* OK */
+ NODE *node;
char *buf;
{
- VALUE val; /* OK */
+ VALUE val;
int state;
again:
@@ -2725,14 +2737,15 @@ call_trace_func(event, node, self, id, klass)
NODE *node;
VALUE self;
ID id;
- VALUE klass; /* OK */
+ VALUE klass;
{
- int state, raised;
+ int state;
+ volatile int raised;
struct FRAME *prev;
- NODE *node_save;
+ NODE * volatile node_save;
VALUE srcfile;
const char *event_name;
- rb_thread_t th = curr_thread;
+ volatile rb_thread_t th = curr_thread;
if (!trace_func) return;
if (tracing) return;
@@ -2941,11 +2954,11 @@ class_prefix(self, cpath)
NORETURN(static void return_jump _((VALUE)));
NORETURN(static void break_jump _((VALUE)));
NORETURN(static void next_jump _((VALUE)));
-NORETURN(static void unknown_node _((NODE * volatile)));
+NORETURN(static void unknown_node _((NODE *)));
static void
unknown_node(node)
- NODE *volatile node;
+ NODE *node;
{
ruby_current_node = 0;
if (node->flags == 0) {
@@ -2959,23 +2972,26 @@ unknown_node(node)
}
}
-
/*
- functions factored out of rb_eval() to reduce its stack frame size
-*/
-NOINLINE(static VALUE eval_match2(self, node))
- VALUE self;
- NODE *node;
+ * functions factored out of rb_eval() to reduce its stack frame size
+ */
+#define eval_node_0(n,retType, self, node) \
+NOINLINE(static retType TOKEN_PASTE(eval_,n) _((self, node)));\
+static retType TOKEN_PASTE(eval_,n)(self, node)
+
+#define eval_node(n,retType) \
+ eval_node_0(n,retType, VALUE self, NODE *node)
+#define eval_node_volatile(n,retType) \
+ eval_node_0(n,retType, volatile VALUE self, NODE * volatile node)
+
+eval_node(match2, VALUE)
{
VALUE l = rb_eval(self,node->nd_recv);
VALUE r = rb_eval(self,node->nd_value);
return rb_reg_match(l, r);
}
-NOINLINE(static VALUE
-eval_match3(self, node))
- VALUE self;
- NODE *node;
+eval_node(match3, VALUE)
{
VALUE r = rb_eval(self,node->nd_recv);
VALUE l = rb_eval(self,node->nd_value);
@@ -2983,16 +2999,14 @@ eval_match3(self, node))
}
-NOINLINE(static void
-eval_opt_n(self, node))
- VALUE self;
- NODE *node;
+eval_node_volatile(opt_n, void)
{
int state;
PUSH_TAG(PROT_LOOP);
switch (state = EXEC_TAG()) {
+ case TAG_NEXT:
+ state = 0;
case 0:
- opt_n_next:
while (!NIL_P(rb_gets())) {
opt_n_redo:
rb_eval(self, node->nd_body);
@@ -3002,9 +3016,7 @@ eval_opt_n(self, node))
case TAG_REDO:
state = 0;
goto opt_n_redo;
- case TAG_NEXT:
- state = 0;
- goto opt_n_next;
+
case TAG_BREAK:
state = 0;
default:
@@ -3015,10 +3027,7 @@ eval_opt_n(self, node))
}
-NOINLINE(static NODE *
-eval_when(self, node))
- VALUE self;
- NODE *node;
+eval_node(when, NODE*)
{
do {
NODE *tag = node->nd_head;
@@ -3045,10 +3054,7 @@ eval_when(self, node))
}
-NOINLINE (static NODE *
-eval_case(self, node))
- VALUE self;
- NODE *node;
+eval_node(case, NODE*)
{
VALUE val = rb_eval(self, node->nd_head);
node = node->nd_body;
@@ -3083,27 +3089,26 @@ eval_case(self, node))
}
-NOINLINE (static VALUE
-eval_while(self, node))
- VALUE self;
- NODE *node;
+eval_node_volatile(while, VALUE)
{
int state;
- volatile VALUE result = Qnil;
+ VALUE result;
PUSH_TAG(PROT_LOOP);
switch (state = EXEC_TAG()) {
case 0:
- if (node->nd_state && !RTEST(rb_eval(self, node->nd_cond)))
- goto while_out;
- do {
- while_redo:
+ if (!(node->nd_state) || RTEST(rb_eval(self, node->nd_cond))) {
+ do {
+ while_redo:
#if STACK_WIPE_SITES & 0x10
- rb_gc_wipe_stack();
+ rb_gc_wipe_stack();
#endif
- rb_eval(self, node->nd_body);
- while_next:
- ;
- } while (RTEST(rb_eval(self, node->nd_cond)));
+ rb_eval(self, node->nd_body);
+ while_next:
+ ;
+ } while (RTEST(rb_eval(self, node->nd_cond)));
+ } /* fall thru */
+ default:
+ result=Qnil;
break;
case TAG_REDO:
@@ -3117,38 +3122,33 @@ eval_while(self, node))
state = 0;
result = prot_tag->retval;
}
- /* fall through */
- default:
- break;
}
-while_out:
POP_TAG();
if (state) JUMP_TAG(state);
return result;
}
-NOINLINE (static VALUE
-eval_until(self, node))
- VALUE self;
- NODE *node;
+eval_node_volatile(until, VALUE)
{
int state;
- volatile VALUE result = Qnil;
+ VALUE result;
PUSH_TAG(PROT_LOOP);
switch (state = EXEC_TAG()) {
case 0:
- if (node->nd_state && RTEST(rb_eval(self, node->nd_cond)))
- goto until_out;
- do {
- until_redo:
-#if STACK_WIPE_SITES & 0x10
- rb_gc_wipe_stack();
-#endif
- rb_eval(self, node->nd_body);
- until_next:
- ;
- } while (!RTEST(rb_eval(self, node->nd_cond)));
+ if (!(node->nd_state) || !RTEST(rb_eval(self, node->nd_cond))) {
+ do {
+ until_redo:
+ #if STACK_WIPE_SITES & 0x10
+ rb_gc_wipe_stack();
+ #endif
+ rb_eval(self, node->nd_body);
+ until_next:
+ ;
+ } while (!RTEST(rb_eval(self, node->nd_cond)));
+ } /* fall thru */
+ default:
+ result=Qnil;
break;
case TAG_REDO:
@@ -3162,24 +3162,17 @@ eval_until(self, node))
state = 0;
result = prot_tag->retval;
}
- /* fall through */
- default:
- break;
}
- until_out:
POP_TAG();
if (state) JUMP_TAG(state);
return result;
}
-NOINLINE (static VALUE
-eval_iter(self, node))
- VALUE self;
- NODE *node;
+eval_node_volatile(iter, VALUE)
{
int state;
- volatile VALUE result = Qnil;
+ VALUE result;
PUSH_TAG(PROT_LOOP);
PUSH_BLOCK(node->nd_var, node->nd_body);
@@ -3194,15 +3187,13 @@ eval_iter(self, node))
result = rb_eval(self, node->nd_iter);
}
else {
- VALUE recv;
-
_block.flags &= ~BLOCK_D_SCOPE;
BEGIN_CALLARGS;
- recv = rb_eval(self, node->nd_iter);
+ result = rb_eval(self, node->nd_iter);
END_CALLARGS;
- ruby_current_node = node;
+ ruby_current_node = (NODE *)node;
SET_CURRENT_SOURCE();
- result = rb_call(CLASS_OF(recv),recv,each,0,0,0,self);
+ result = rb_call(CLASS_OF(result),result,each,0,0,0,self);
}
POP_ITER();
break;
@@ -3220,15 +3211,12 @@ eval_iter(self, node))
}
-NOINLINE (static VALUE
-eval_rescue(self, node))
- VALUE self;
- NODE *node;
+eval_node_volatile(rescue, VALUE)
{
volatile VALUE e_info = ruby_errinfo;
volatile int rescuing = 0;
int state;
- volatile VALUE result = Qnil;
+ VALUE result;
PUSH_TAG(PROT_NONE);
if ((state = EXEC_TAG()) == 0) {
@@ -3238,6 +3226,7 @@ eval_rescue(self, node))
else if (rescuing) {
if (rescuing < 0) {
/* in rescue argument, just reraise */
+ result = Qnil;
}
else if (state == TAG_RETRY) {
rescuing = state = 0;
@@ -3279,13 +3268,10 @@ eval_rescue(self, node))
}
-NOINLINE (static VALUE
-eval_ensure(self, node))
- VALUE self;
- NODE *node;
+eval_node_volatile(ensure, VALUE)
{
int state;
- volatile VALUE result = Qnil;
+ VALUE result;
PUSH_TAG(PROT_NONE);
if ((state = EXEC_TAG()) == 0) {
@@ -3305,10 +3291,7 @@ eval_ensure(self, node))
}
-NOINLINE (static VALUE
-eval_dot(self, node))
- VALUE self;
- NODE *node;
+eval_node(dot, VALUE)
{
VALUE beg = rb_eval(self, node->nd_beg);
VALUE end = rb_eval(self, node->nd_end);
@@ -3316,10 +3299,7 @@ eval_dot(self, node))
}
-NOINLINE (static VALUE
-eval_flip2(self, node))
- VALUE self;
- NODE *node;
+eval_node(flip2, VALUE)
{
VALUE *flip = rb_svar(node->nd_cnt);
if (!flip) rb_bug("unexpected local variable");
@@ -3334,10 +3314,7 @@ eval_flip2(self, node))
}
-NOINLINE (static VALUE
-eval_flip3(self, node))
- VALUE self;
- NODE *node;
+eval_node(flip3, VALUE)
{
VALUE *flip = rb_svar(node->nd_cnt);
if (!flip) rb_bug("unexpected local variable");
@@ -3349,10 +3326,7 @@ eval_flip3(self, node))
}
-NOINLINE (static VALUE
-eval_attrasgn(self, node))
- VALUE self;
- NODE *node;
+eval_node(attrasgn, VALUE)
{
VALUE recv;
int argc; VALUE *argv; /* used in SETUP_ARGS */
@@ -3378,10 +3352,7 @@ eval_attrasgn(self, node))
}
-NOINLINE (static VALUE
-eval_call(self, node))
- VALUE self;
- NODE *node;
+eval_node(call, VALUE)
{
VALUE recv;
int argc; VALUE *argv; /* used in SETUP_ARGS */
@@ -3398,10 +3369,7 @@ eval_call(self, node))
}
-NOINLINE (static VALUE
-eval_fcall(self, node))
- VALUE self;
- NODE *node;
+eval_node(fcall, VALUE)
{
int argc; VALUE *argv; /* used in SETUP_ARGS */
TMP_PROTECT;
@@ -3415,10 +3383,8 @@ eval_fcall(self, node))
return rb_call(CLASS_OF(self),self,node->nd_mid,argc,argv,1,self);
}
-NOINLINE (static VALUE
-eval_super(self, node))
- VALUE self;
- NODE *node;
+
+eval_node(super, VALUE)
{
int argc; VALUE *argv; /* used in SETUP_ARGS */
TMP_PROTECT;
@@ -3463,15 +3429,12 @@ eval_super(self, node))
}
-NOINLINE (static VALUE
-eval_scope(self, node))
- VALUE self;
- NODE *node;
+eval_node_volatile(scope, VALUE)
{
int state;
- volatile VALUE result = Qnil;
+ VALUE result;
struct FRAME frame;
- NODE *saved_cref = 0;
+ NODE * volatile saved_cref = 0;
frame = *ruby_frame;
frame.tmp = ruby_frame;
@@ -3506,10 +3469,7 @@ eval_scope(self, node))
return result;
}
-NOINLINE (static VALUE
-eval_op_asgn1(self, node))
- VALUE self;
- NODE *node;
+eval_node(op_asgn1, VALUE)
{
int argc; VALUE *argv; /* used in SETUP_ARGS */
VALUE recv, val, tmp;
@@ -3539,10 +3499,7 @@ eval_op_asgn1(self, node))
}
-NOINLINE (static VALUE
-eval_op_asgn2(self, node))
- VALUE self;
- NODE *node;
+eval_node(op_asgn2, VALUE)
{
ID id = node->nd_next->nd_vid;
VALUE recv, val, tmp;
@@ -3568,10 +3525,7 @@ eval_op_asgn2(self, node))
}
-NOINLINE (static VALUE
-eval_hash(self, node))
- VALUE self;
- NODE *node;
+eval_node(hash, VALUE)
{
NODE *list;
VALUE hash = rb_hash_new();
@@ -3591,10 +3545,7 @@ eval_hash(self, node))
}
-NOINLINE (static VALUE
-eval_array(self, node))
- VALUE self;
- NODE *node;
+eval_node(array, VALUE)
{
VALUE ary;
long i;
@@ -3609,10 +3560,7 @@ eval_array(self, node))
}
-NOINLINE (static VALUE
-eval_slit(self, node))
- VALUE self;
- NODE *node;
+eval_node(slit, VALUE)
{
VALUE str, str2;
NODE *list = node->nd_next;
@@ -3635,12 +3583,15 @@ eval_slit(self, node))
}
switch (nd_type(node)) {
case NODE_DREGX:
- return rb_reg_new(RSTRING(str)->ptr, RSTRING(str)->len,
+ str2 = rb_reg_new(RSTRING(str)->ptr, RSTRING(str)->len,
node->nd_cflag);
+ RB_GC_GUARD(str); /* ensure str is not GC'd in rb_reg_new */
+ return str2;
case NODE_DREGX_ONCE: /* regexp expand once */
str2 = rb_reg_new(RSTRING(str)->ptr, RSTRING(str)->len,
node->nd_cflag);
nd_set_type(node, NODE_LIT);
+ RB_GC_GUARD(str); /* ensure str is not GC'd in rb_reg_new */
return node->nd_lit = str2;
case NODE_LIT:
/* other thread may replace NODE_DREGX_ONCE to NODE_LIT */
@@ -3654,10 +3605,7 @@ eval_slit(self, node))
}
-NOINLINE (static void
-eval_defn(self, node))
- VALUE self;
- NODE *node;
+eval_node(defn, void)
{
NODE *body, *defn;
VALUE origin = 0;
@@ -3703,10 +3651,7 @@ eval_defn(self, node))
}
-NOINLINE (static void
-eval_defs(self, node))
- VALUE self;
- NODE *node;
+eval_node(defs, void)
{
VALUE recv = rb_eval(self, node->nd_recv);
VALUE klass;
@@ -3740,10 +3685,7 @@ eval_defs(self, node))
}
-NOINLINE (static VALUE
-eval_class(self, node))
- VALUE self;
- NODE *node;
+eval_node(class, VALUE)
{
VALUE super, klass, tmp, cbase;
ID cname;
@@ -3799,10 +3741,7 @@ eval_class(self, node))
}
-NOINLINE (static VALUE
-eval_module(self, node))
- VALUE self;
- NODE *node;
+eval_node(module, VALUE)
{
VALUE module, cbase;
ID cname;
@@ -3836,10 +3775,7 @@ eval_module(self, node))
}
-NOINLINE (static VALUE
-eval_sclass(self, node))
- VALUE self;
- NODE *node;
+eval_node(sclass, VALUE)
{
VALUE klass, result;
@@ -3861,10 +3797,7 @@ eval_sclass(self, node))
}
-NOINLINE (static VALUE
-eval_defined(self, node))
- VALUE self;
- NODE *node;
+eval_node(defined, VALUE)
{
char buf[20];
const char *desc = is_defined(self, node->nd_head, buf);
@@ -3872,17 +3805,18 @@ eval_defined(self, node))
}
-NOINLINE (static void
-eval_cvar_set(result, node, bool))
- VALUE result, bool;
+static void
+eval_cvar_set(node, result, warn)
NODE *node;
+ VALUE result;
+ int warn;
{
- rb_cvar_set(cvar_cbase(), node->nd_vid, result, bool);
+ rb_cvar_set(cvar_cbase(), node->nd_vid, result, warn);
}
-NOINLINE (static void
-eval_cdecl(self, node, result))
+static void
+eval_cdecl(self, node, result)
VALUE self, result;
NODE *node;
{
@@ -3897,7 +3831,7 @@ eval_cdecl(self, node, result))
static VALUE
rb_eval(self, node)
VALUE self;
- NODE *node;
+ NODE * node;
{
VALUE result;
@@ -3906,8 +3840,6 @@ again:
result = Qnil;
if (node) {
ruby_current_node = node;
- SET_CURRENT_SOURCE();
-
switch (nd_type(node)) {
case NODE_BLOCK:
while (node->nd_next) {
@@ -4187,12 +4119,12 @@ again:
rb_raise(rb_eTypeError, "no class/module to define class variable");
}
result = rb_eval(self, node->nd_value);
- eval_cvar_set(result, node, Qtrue);
+ eval_cvar_set(node, result, Qtrue);
break;
case NODE_CVASGN:
result = rb_eval(self, node->nd_value);
- eval_cvar_set(result, node, Qfalse);
+ eval_cvar_set(node, result, Qfalse);
break;
case NODE_LVAR:
@@ -4378,12 +4310,12 @@ again:
static VALUE
module_setup(module, n)
VALUE module;
- NODE *n;
+ NODE * volatile n;
{
- NODE * volatile node = n->nd_body;
+ NODE *node = n->nd_body;
int state;
struct FRAME frame;
- VALUE result = Qnil; /* OK */
+ VALUE result;
TMP_PROTECT;
frame = *ruby_frame;
@@ -4774,16 +4706,16 @@ rb_iter_break()
break_jump(Qnil);
}
-NORETURN(static void rb_longjmp _((int, VALUE)));
+NORETURN(static void rb_longjmp _((volatile int, volatile VALUE)));
static VALUE make_backtrace _((void));
static void
rb_longjmp(tag, mesg)
- int tag;
- VALUE mesg;
+ volatile int tag;
+ volatile VALUE mesg;
{
VALUE at;
- rb_thread_t th = curr_thread;
+ volatile rb_thread_t th = curr_thread;
if (rb_thread_set_raised(th)) {
ruby_errinfo = exception_error;
@@ -4914,14 +4846,12 @@ rb_make_exception(argc, argv)
int argc;
VALUE *argv;
{
- VALUE mesg;
+ VALUE mesg = Qnil;
ID exception;
int n;
- mesg = Qnil;
switch (argc) {
case 0:
- mesg = Qnil;
break;
case 1:
if (NIL_P(argv[0])) break;
@@ -5140,19 +5070,21 @@ rb_need_block()
static VALUE
rb_yield_0(val, self, klass, flags, avalue)
- VALUE val, self, klass; /* OK */
- int flags, avalue;
+ volatile VALUE val, self;
+ VALUE klass;
+ int flags;
+ volatile int avalue;
{
- NODE *node, *var;
+ NODE *var, *volatile node;
volatile VALUE result = Qnil;
volatile VALUE old_cref;
volatile VALUE old_wrapper;
struct BLOCK * volatile block;
struct SCOPE * volatile old_scope;
- int old_vmode;
+ volatile int old_vmode;
struct FRAME frame;
NODE *cnode = ruby_current_node;
- int lambda = flags & YIELD_LAMBDA_CALL;
+ volatile int lambda = flags & YIELD_LAMBDA_CALL;
int state;
rb_need_block();
@@ -5262,56 +5194,49 @@ rb_yield_0(val, self, klass, flags, avalue)
PUSH_ITER(block->iter);
PUSH_TAG(lambda ? PROT_NONE : PROT_YIELD);
- if ((state = EXEC_TAG()) == 0) {
- redo:
+ switch (state = EXEC_TAG()) {
+ case TAG_REDO:
+ state = 0;
+ CHECK_INTS;
+ case 0:
if (nd_type(node) == NODE_CFUNC || nd_type(node) == NODE_IFUNC) {
- switch (node->nd_state) {
- case YIELD_FUNC_LAMBDA:
- if (!avalue) {
- val = rb_ary_new3(1, val);
- }
- break;
- case YIELD_FUNC_AVALUE:
- if (!avalue) {
- val = svalue_to_avalue(val);
- }
- break;
- default:
- if (avalue) {
- val = avalue_to_svalue(val);
- }
- if (val == Qundef && node->nd_state != YIELD_FUNC_SVALUE)
- val = Qnil;
+ switch (node->nd_state) {
+ case YIELD_FUNC_LAMBDA:
+ if (!avalue) {
+ val = rb_ary_new3(1, val);
+ }
+ break;
+ case YIELD_FUNC_AVALUE:
+ if (!avalue) {
+ val = svalue_to_avalue(val);
+ }
+ break;
+ default:
+ if (avalue) {
+ val = avalue_to_svalue(val);
+ }
+ if (val == Qundef && node->nd_state != YIELD_FUNC_SVALUE)
+ val = Qnil;
}
result = (*node->nd_cfnc)(val, node->nd_tval, self);
- }
- else {
+ }else
result = rb_eval(self, node);
- }
- }
- else {
- switch (state) {
- case TAG_REDO:
- state = 0;
- CHECK_INTS;
- goto redo;
- case TAG_NEXT:
- if (!lambda) {
- state = 0;
- result = prot_tag->retval;
- }
- break;
- case TAG_BREAK:
- if (TAG_DST()) {
- result = prot_tag->retval;
- }
- else {
- lambda = Qtrue; /* just pass TAG_BREAK */
- }
- break;
- default:
- break;
- }
+ break;
+ case TAG_NEXT:
+ if (!lambda) {
+ state = 0;
+ result = prot_tag->retval;
+ }
+ break;
+ case TAG_BREAK:
+ if (TAG_DST()) {
+ result = prot_tag->retval;
+ }
+ else {
+ lambda = Qtrue; /* just pass TAG_BREAK */
+ }
+ default:
+ break;
}
POP_TAG();
POP_ITER();
@@ -5597,11 +5522,12 @@ assign(self, lhs, val, pcall)
VALUE
rb_iterate(it_proc, data1, bl_proc, data2)
- VALUE (*it_proc) _((VALUE)), (*bl_proc)(ANYARGS);
- VALUE data1, data2;
+ VALUE (* volatile it_proc) _((VALUE)), (*bl_proc)(ANYARGS);
+ volatile VALUE data1;
+ VALUE data2;
{
int state;
- volatile VALUE retval = Qnil;
+ VALUE retval;
NODE *node = NEW_IFUNC(bl_proc, data2);
VALUE self = ruby_top_self;
@@ -5625,12 +5551,7 @@ rb_iterate(it_proc, data1, bl_proc, data2)
POP_BLOCK();
POP_TAG();
- switch (state) {
- case 0:
- break;
- default:
- JUMP_TAG(state);
- }
+ if (state) JUMP_TAG(state);
return retval;
}
@@ -5662,16 +5583,17 @@ handle_rescue(self, node)
VALUE
#ifdef HAVE_STDARG_PROTOTYPES
-rb_rescue2(VALUE (*b_proc)(ANYARGS), VALUE data1, VALUE (*r_proc)(ANYARGS), VALUE data2, ...)
+rb_rescue2(VALUE (* volatile b_proc)(ANYARGS), volatile VALUE data1,
+ VALUE (* volatile r_proc)(ANYARGS), volatile VALUE data2, ...)
#else
rb_rescue2(b_proc, data1, r_proc, data2, va_alist)
- VALUE (*b_proc)(ANYARGS), (*r_proc)(ANYARGS);
- VALUE data1, data2;
+ VALUE (* volatile b_proc)(ANYARGS), (* volatile r_proc)(ANYARGS);
+ volatile VALUE data1, data2;
va_dcl
#endif
{
int state;
- volatile VALUE result;
+ VALUE result;
volatile VALUE e_info = ruby_errinfo;
volatile int handle = Qfalse;
VALUE eclass;
@@ -5730,9 +5652,9 @@ VALUE
rb_protect(proc, data, state)
VALUE (*proc) _((VALUE));
VALUE data;
- int *state;
+ int * volatile state;
{
- VALUE result = Qnil; /* OK */
+ VALUE result;
int status;
PUSH_TAG(PROT_NONE);
@@ -5745,22 +5667,18 @@ rb_protect(proc, data, state)
if (state) {
*state = status;
}
- if (status != 0) {
- return Qnil;
- }
-
- return result;
+ return status ? Qnil : result;
}
VALUE
rb_ensure(b_proc, data1, e_proc, data2)
VALUE (*b_proc)();
VALUE data1;
- VALUE (*e_proc)();
- VALUE data2;
+ VALUE (* volatile e_proc)();
+ volatile VALUE data2;
{
int state;
- volatile VALUE result = Qnil;
+ VALUE result;
VALUE retval;
PUSH_TAG(PROT_NONE);
@@ -5768,7 +5686,7 @@ rb_ensure(b_proc, data1, e_proc, data2)
result = (*b_proc)(data1);
}
POP_TAG();
- retval = prot_tag ? prot_tag->retval : Qnil; /* save retval */
+ if (prot_tag) retval = prot_tag->retval; /* save retval */
if (!thread_no_ensure()) {
(*e_proc)(data2);
}
@@ -5782,7 +5700,7 @@ rb_with_disable_interrupt(proc, data)
VALUE (*proc)();
VALUE data;
{
- VALUE result = Qnil; /* OK */
+ VALUE result;
int status;
DEFER_INTS;
@@ -6034,16 +5952,16 @@ call_cfunc(func, recv, len, argc, argv)
static VALUE
rb_call0(klass, recv, id, oid, argc, argv, body, flags)
- VALUE klass, recv;
- ID id;
+ volatile VALUE klass, recv;
+ volatile ID id;
ID oid;
- int argc; /* OK */
- VALUE *argv; /* OK */
- NODE * volatile body;
+ int argc;
+ VALUE *argv;
+ NODE *body;
int flags;
{
NODE *b2; /* OK */
- volatile VALUE result = Qnil;
+ VALUE result;
int itr;
static int tick;
TMP_PROTECT;
@@ -6150,9 +6068,10 @@ rb_call0(klass, recv, id, oid, argc, argv, body, flags)
Data_Get_Struct(body->nd_cval, struct BLOCK, data);
EXEC_EVENT_HOOK(RUBY_EVENT_CALL, data->body, recv, id, klass);
}
- result = proc_invoke(body->nd_cval, rb_ary_new4(argc, argv), recv, klass);
+ result = proc_invoke(body->nd_cval, rb_ary_new4(argc,argv), recv,klass);
if (event_hooks) {
- EXEC_EVENT_HOOK(RUBY_EVENT_RETURN, ruby_current_node, recv, id, klass);
+ EXEC_EVENT_HOOK(RUBY_EVENT_RETURN,
+ ruby_current_node, recv, id, klass);
}
break;
@@ -6160,7 +6079,7 @@ rb_call0(klass, recv, id, oid, argc, argv, body, flags)
{
int state;
VALUE *local_vars; /* OK */
- NODE *saved_cref = 0;
+ NODE * volatile saved_cref = 0;
PUSH_SCOPE();
if (body->nd_rval) {
@@ -6206,8 +6125,9 @@ rb_call0(klass, recv, id, oid, argc, argv, body, flags)
i = node->nd_cnt;
if (i > argc) {
- rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)",
- argc, i);
+ rb_raise(rb_eArgError,
+ "wrong number of arguments (%d for %d)",
+ argc, i);
}
if (!node->nd_rest) {
NODE *optnode = node->nd_opt;
@@ -6275,7 +6195,8 @@ rb_call0(klass, recv, id, oid, argc, argv, body, flags)
}
POP_TAG();
if (event_hooks) {
- EXEC_EVENT_HOOK(RUBY_EVENT_RETURN, ruby_current_node, recv, id, klass);
+ EXEC_EVENT_HOOK(RUBY_EVENT_RETURN, ruby_current_node,
+ recv, id, klass);
}
POP_VARS();
POP_CLASS();
@@ -6303,7 +6224,6 @@ rb_call0(klass, recv, id, oid, argc, argv, body, flags)
default:
unknown_node(body);
- break;
}
POP_FRAME();
POP_ITER();
@@ -6471,7 +6391,7 @@ rb_funcall_rescue(recv, mid, n, va_alist)
va_dcl
#endif
{
- VALUE result = Qnil; /* OK */
+ VALUE result;
int status;
va_list ar;
@@ -6687,12 +6607,13 @@ compile(src, file, line)
static VALUE
eval(self, src, scope, file, line)
- VALUE self, src, scope;
- const char *file;
+ VALUE self, src;
+ volatile VALUE scope;
+ const char * volatile file;
int line;
{
struct BLOCK *data = NULL;
- volatile VALUE result = Qnil;
+ VALUE result;
struct SCOPE * volatile old_scope;
struct BLOCK * volatile old_block;
struct RVarmap * volatile old_dyna_vars;
@@ -6700,7 +6621,7 @@ eval(self, src, scope, file, line)
int volatile old_vmode;
volatile VALUE old_wrapper;
struct FRAME frame;
- NODE *nodesave = ruby_current_node;
+ NODE * volatile nodesave = ruby_current_node;
volatile int iter = ruby_frame->iter;
volatile int safe = ruby_safe_level;
int state;
@@ -6765,7 +6686,7 @@ eval(self, src, scope, file, line)
compile_error(0);
}
if (!NIL_P(result)) ruby_errinfo = result;
- result = eval_node(self, node);
+ result = eval_tree(self, node);
}
POP_TAG();
POP_CLASS();
@@ -6891,12 +6812,13 @@ rb_f_eval(argc, argv, self)
static VALUE
exec_under(func, under, cbase, args)
VALUE (*func)();
- VALUE under, cbase;
+ VALUE under;
+ volatile VALUE cbase;
void *args;
{
- VALUE val = Qnil; /* OK */
+ VALUE val;
int state;
- int mode;
+ volatile int mode;
struct FRAME *f = ruby_frame;
PUSH_CLASS(under);
@@ -7182,9 +7104,9 @@ rb_load(fname, wrap)
volatile int prohibit_int = rb_prohibit_interrupt;
volatile ID last_func;
volatile VALUE wrapper = ruby_wrapper;
- volatile VALUE self = ruby_top_self;
+ VALUE self = ruby_top_self;
NODE *volatile last_node;
- NODE *saved_cref = ruby_cref;
+ NODE *volatile saved_cref = ruby_cref;
if (wrap && ruby_safe_level >= 4) {
StringValue(fname);
@@ -7233,7 +7155,7 @@ rb_load(fname, wrap)
ruby_current_node = 0;
if (state == 0) {
NODE *node;
- volatile int critical;
+ int critical;
DEFER_INTS;
ruby_in_eval++;
@@ -7245,7 +7167,7 @@ rb_load(fname, wrap)
rb_thread_critical = critical;
ALLOW_INTS;
if (ruby_nerrs == 0) {
- eval_node(self, node);
+ eval_tree(self, node);
}
}
ruby_frame->last_func = last_func;
@@ -7278,7 +7200,7 @@ void
rb_load_protect(fname, wrap, state)
VALUE fname;
int wrap;
- int *state;
+ int * volatile state;
{
int status;
@@ -7567,7 +7489,7 @@ rb_require_safe(fname, safe)
VALUE fname;
int safe;
{
- VALUE result = Qnil;
+ VALUE result;
volatile VALUE errinfo = ruby_errinfo;
int state;
struct {
@@ -7618,7 +7540,8 @@ rb_require_safe(fname, safe)
rb_provide_feature(feature);
result = Qtrue;
}
- }
+ }else
+ result = Qnil;
}
POP_TAG();
ruby_current_node = saved.node;
@@ -8286,7 +8209,7 @@ rb_f_at_exit()
void
rb_exec_end_proc()
{
- struct end_proc_data *link, *tmp;
+ struct end_proc_data *tmp, *volatile link;
int status;
volatile int safe = ruby_safe_level;
@@ -9009,8 +8932,9 @@ proc_invoke(proc, args, self, klass)
int state;
volatile int safe = ruby_safe_level;
volatile VALUE old_wrapper = ruby_wrapper;
- volatile int pcall, avalue = Qtrue;
- volatile VALUE tmp = args;
+ volatile int pcall;
+ int avalue = Qtrue;
+ VALUE tmp = args;
VALUE bvar = Qnil;
if (rb_block_given_p() && ruby_frame->last_func) {
@@ -9316,15 +9240,15 @@ proc_binding(proc)
static VALUE
block_pass(self, node)
- VALUE self;
- NODE *node;
+ volatile VALUE self;
+ NODE *volatile node;
{
- VALUE proc = rb_eval(self, node->nd_body); /* OK */
+ volatile VALUE proc = rb_eval(self, node->nd_body);
VALUE b;
struct BLOCK * volatile old_block;
struct BLOCK _block;
struct BLOCK *data;
- volatile VALUE result = Qnil;
+ VALUE result;
int state;
volatile int orphan;
volatile int safe = ruby_safe_level;
@@ -9371,20 +9295,24 @@ block_pass(self, node)
PUSH_TAG(PROT_LOOP);
state = EXEC_TAG();
- if (state == 0) {
- retry:
+ switch (state) {
+ case TAG_RETRY:
+ state = 0;
+ case 0:
proc_set_safe_level(proc);
if (safe > ruby_safe_level)
ruby_safe_level = safe;
result = rb_eval(self, node->nd_iter);
- }
- else if (state == TAG_BREAK && TAG_DST()) {
- result = prot_tag->retval;
- state = 0;
- }
- else if (state == TAG_RETRY) {
- state = 0;
- goto retry;
+ break;
+ case TAG_BREAK:
+ result = Qnil;
+ if (TAG_DST()) {
+ result = prot_tag->retval;
+ state = 0;
+ }
+ break;
+ default:
+ result = Qnil;
}
POP_TAG();
POP_ITER();
@@ -9401,7 +9329,6 @@ block_pass(self, node)
default:
JUMP_TAG(state);
}
-
return result;
}
@@ -9735,7 +9662,7 @@ method_call(argc, argv, method)
VALUE *argv;
VALUE method;
{
- VALUE result = Qnil; /* OK */
+ VALUE result;
struct METHOD *data;
int safe;
@@ -10030,12 +9957,9 @@ static VALUE
bmcall(args, method)
VALUE args, method;
{
- volatile VALUE a;
- VALUE ret;
-
- a = svalue_to_avalue(args);
- ret = method_call(RARRAY(a)->len, RARRAY(a)->ptr, method);
- a = Qnil; /* prevent tail call */
+ VALUE a = svalue_to_avalue(args);
+ VALUE ret = method_call(RARRAY(a)->len, RARRAY(a)->ptr, method);
+ RB_GC_GUARD(a); /* ensure a is not GC'd during method_call */
return ret;
}
@@ -10151,7 +10075,7 @@ rb_mod_define_method(argc, argv, mod)
else {
rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", argc);
}
- ruby_set_current_source(); /* for Method#__line__ */
+ SET_METHOD_SOURCE();
if (RDATA(body)->dmark == (RUBY_DATA_FUNC)bm_mark) {
node = NEW_DMETHOD(method_unbind(body));
}
@@ -10184,12 +10108,16 @@ rb_mod_define_method(argc, argv, mod)
}
+#ifdef MBARI_API
/*
* call-seq:
* meth.__file__ => String
*
* returns the filename containing this method's definition
+ *
* raises ArgumentError if method has no associated ruby source code
+ *
+ * <i>Only available when MBARI_API extentions are enabled at build time</i>
*/
static VALUE
@@ -10212,7 +10140,10 @@ method_source_file_name(VALUE method)
* meth.__line__ => Fixnum
*
* returns the starting line number of this method
+ *
* raises ArgumentError if method has no associated ruby source code
+ *
+ * <i>Only available when MBARI_API extentions are enabled at build time</i>
*/
static VALUE
@@ -10231,13 +10162,15 @@ method_source_line(VALUE method)
}
-
/*
* call-seq:
* prc.__file__ => String
*
* returns the filename where this proc is defined
+ *
* raises ArgumentError if proc has no associated ruby source
+ *
+ * <i>Only available when MBARI_API extentions are enabled at build time</i>
*/
static VALUE
@@ -10259,7 +10192,10 @@ proc_source_file_name(VALUE block)
* prc.__line__ => Fixnum
*
* returns the starting line number of this proc
+ *
* raises ArgumentError if proc has no associated ruby source code
+ *
+ * <i>Only available when MBARI_API extentions are enabled at build time</i>
*/
static VALUE
@@ -10274,6 +10210,8 @@ proc_source_line(VALUE block)
rb_raise(rb_eArgError, "native Proc");
}
+#endif /* MBARI_API */
+
/*
* <code>Proc</code> objects are blocks of code that have been bound to
@@ -10326,8 +10264,6 @@ Init_Proc()
rb_define_method(rb_cProc, "to_s", proc_to_s, 0);
rb_define_method(rb_cProc, "to_proc", proc_to_self, 0);
rb_define_method(rb_cProc, "binding", proc_binding, 0);
- rb_define_method(rb_cProc, "__file__", proc_source_file_name, 0);
- rb_define_method(rb_cProc, "__line__", proc_source_line, 0);
rb_define_global_function("proc", proc_lambda, 0);
rb_define_global_function("lambda", proc_lambda, 0);
@@ -10348,8 +10284,6 @@ Init_Proc()
rb_define_method(rb_cMethod, "owner", method_owner, 0);
rb_define_method(rb_cMethod, "unbind", method_unbind, 0);
rb_define_method(rb_mKernel, "method", rb_obj_method, 1);
- rb_define_method(rb_cMethod, "__file__", method_source_file_name, 0);
- rb_define_method(rb_cMethod, "__line__", method_source_line, 0);
rb_cUnboundMethod = rb_define_class("UnboundMethod", rb_cObject);
rb_undef_alloc_func(rb_cUnboundMethod);
@@ -10362,9 +10296,16 @@ Init_Proc()
rb_define_method(rb_cUnboundMethod, "name", method_name, 0);
rb_define_method(rb_cUnboundMethod, "owner", method_owner, 0);
rb_define_method(rb_cUnboundMethod, "bind", umethod_bind, 1);
+ rb_define_method(rb_cModule, "instance_method", rb_mod_method, 1);
+
+#ifdef MBARI_API
rb_define_method(rb_cUnboundMethod, "__file__", method_source_file_name, 0);
rb_define_method(rb_cUnboundMethod, "__line__", method_source_line, 0);
- rb_define_method(rb_cModule, "instance_method", rb_mod_method, 1);
+ rb_define_method(rb_cProc, "__file__", proc_source_file_name, 0);
+ rb_define_method(rb_cProc, "__line__", proc_source_line, 0);
+ rb_define_method(rb_cMethod, "__file__", method_source_file_name, 0);
+ rb_define_method(rb_cMethod, "__line__", method_source_line, 0);
+#endif
}
/*
@@ -10910,7 +10851,7 @@ static void
rb_thread_save_context(th)
rb_thread_t th;
{
- int len;
+ size_t len;
static VALUE tval;
len = ruby_stack_length(th->stk_start,&th->stk_pos);
@@ -11112,7 +11053,6 @@ rb_thread_restore_context(th, exit)
#if HAVE_ALLOCA /* use alloca to grow stack in O(1) time */
VALUE v;
- volatile VALUE *space;
if (!th->stk_ptr) rb_bug("unsaved context");
# if !STACK_GROW_DIRECTION /* unknown at compile time */
@@ -11120,13 +11060,15 @@ rb_thread_restore_context(th, exit)
# endif
# if STACK_GROW_DIRECTION <= 0
pos -= th->stk_len;
- if (&v > pos) space=ALLOCA_N(VALUE, &v-pos);
+ if (&v > pos)
+ (volatile void *)ALLOCA_N(VALUE, &v-pos);
# endif
# if !STACK_GROW_DIRECTION
}else
# endif
#if STACK_GROW_DIRECTION >= 0 /* stack grows upward */
- if (&v < pos + th->stk_len) space=ALLOCA_N(VALUE, pos+th->stk_len - &v);
+ if (&v < pos + th->stk_len)
+ (volatile void *)ALLOCA_N(VALUE, pos+th->stk_len - &v);
# endif
#else /* recursive O(n/1024) if extending stack > 1024 VALUEs */
@@ -11737,8 +11679,6 @@ rb_thread_select(max, read, write, except, timeout)
return curr_thread->select_value;
}
-static int rb_thread_join _((rb_thread_t, double));
-
static int
rb_thread_join(th, limit)
rb_thread_t th;
@@ -13450,7 +13390,7 @@ static VALUE
rb_callcc(self)
VALUE self;
{
- rb_thread_t th = prep4callcc();
+ volatile rb_thread_t th = prep4callcc();
return THREAD_SAVE_CONTEXT(th) ?
th->result
:
@@ -13505,18 +13445,21 @@ rb_cont_call(argc, argv, cont)
}
+#ifdef MBARI_API
/*
* call-seq:
* cont.thread
*
* Returns the thread on which this continuation can be called
- * (or nil if that thread has died)
+ * or nil if that thread has died
*
* t = Thread.new {callcc{|c| $x=c}; sleep 5}
* sleep 1
* $x.thread #=> t
* sleep 10
* $x.thread #=> nil
+ *
+ * <i>Only available when MBARI_API extentions are enabled at build time</i>
*/
static VALUE
rb_cont_thread(cont)
@@ -13526,6 +13469,7 @@ rb_cont_thread(cont)
cc_purge(th);
return th->thread;
}
+#endif
struct thgroup {
@@ -13784,21 +13728,20 @@ rb_exec_recursive(func, obj, arg)
VALUE obj;
VALUE arg;
{
- VALUE hash = rb_thread_local_aref(rb_thread_current(), recursive_key);
- VALUE objid = rb_obj_id(obj);
+ volatile VALUE hash =
+ rb_thread_local_aref(rb_thread_current(), recursive_key);
+ volatile VALUE objid = rb_obj_id(obj);
if (recursive_check(hash, objid)) {
return (*func) (obj, arg, Qtrue);
}
else {
- VALUE result = Qundef;
+ VALUE result;
int state;
hash = recursive_push(hash, objid);
PUSH_TAG(PROT_NONE);
- if ((state = EXEC_TAG()) == 0) {
- result = (*func) (obj, arg, Qfalse);
- }
+ result = (state = EXEC_TAG()) ? Qundef : (*func) (obj, arg, Qfalse);
POP_TAG();
recursive_pop(hash, objid);
if (state)
@@ -13881,7 +13824,9 @@ Init_Thread()
rb_undef_method(CLASS_OF(rb_cCont), "new");
rb_define_method(rb_cCont, "call", rb_cont_call, -1);
rb_define_method(rb_cCont, "[]", rb_cont_call, -1);
+#ifdef MBARI_API
rb_define_method(rb_cCont, "thread", rb_cont_thread, 0);
+#endif
rb_define_global_function("callcc", rb_callcc, 0);
rb_global_variable(&cont_protect);
@@ -13933,10 +13878,11 @@ Init_Thread()
static VALUE
rb_f_catch(dmy, tag)
- VALUE dmy, tag;
+ VALUE dmy;
+ volatile VALUE tag;
{
int state;
- VALUE val = Qnil; /* OK */
+ VALUE val;
tag = ID2SYM(rb_to_id(tag));
PUSH_TAG(tag);
diff --git a/gc.c b/gc.c
index 3314171..167dfcd 100644
--- a/gc.c
+++ b/gc.c
@@ -43,7 +43,7 @@ int _setjmp(), _longjmp();
#if defined(MSDOS) || defined(__human68k__)
#define GC_MALLOC_LIMIT 200000
#else
-#define GC_MALLOC_LIMIT 8000000
+#define GC_MALLOC_LIMIT (2000000*sizeof(VALUE))
#endif
#endif
@@ -60,6 +60,7 @@ static VALUE *stack_limit, *gc_stack_limit;
static size_t malloc_increase = 0;
static size_t malloc_limit = GC_MALLOC_LIMIT;
+#ifdef MBARI_API
/*
* call-seq:
* GC.limit => increase limit in bytes
@@ -67,6 +68,7 @@ static size_t malloc_limit = GC_MALLOC_LIMIT;
* Get the # of bytes that may be allocated before triggering
* a mark and sweep by the garbarge collector to reclaim unused storage.
*
+ * <i>Only available when MBARI_API extentions are enabled at build time</i>
*/
static VALUE gc_getlimit(VALUE mod)
{
@@ -84,12 +86,14 @@ static VALUE gc_getlimit(VALUE mod)
* GC.limit=5000000 #=> 5000000
* GC.limit #=> 5000000
* GC.limit=-50 #=> 5000000
- * GC.limit=0 #=> 0
+ * GC.limit=0 #=> 0 #functionally equivalent to GC.stress=true
*
+ * <i>Only available when MBARI_API extentions are enabled at build time</i>
*/
static VALUE gc_setlimit(VALUE mod, VALUE newLimit)
{
long limit = NUM2LONG(newLimit);
+ rb_secure(2);
if (limit < 0) return gc_getlimit(mod);
malloc_limit = limit;
return newLimit;
@@ -98,12 +102,13 @@ static VALUE gc_setlimit(VALUE mod, VALUE newLimit)
/*
* call-seq:
- * GC.increase
+ * GC.growth
*
* Get # of bytes that have been allocated since the last mark & sweep
*
+ * <i>Only available when MBARI_API extentions are enabled at build time</i>
*/
-static VALUE gc_increase(VALUE mod)
+static VALUE gc_growth(VALUE mod)
{
return ULONG2NUM(malloc_increase);
}
@@ -115,6 +120,7 @@ static VALUE gc_increase(VALUE mod)
*
* Purge ghost references from recently freed stack space
*
+ * <i>Only available when MBARI_API extentions are enabled at build time</i>
*/
static VALUE gc_exorcise(VALUE mod)
{
@@ -122,6 +128,55 @@ static VALUE gc_exorcise(VALUE mod)
return Qnil;
}
+#else /* no api changes */
+
+static size_t unstressed_malloc_limit = GC_MALLOC_LIMIT;
+
+/*
+ * call-seq:
+ * GC.stress => true or false
+ *
+ * returns current status of GC stress mode.
+ *
+ * <i>Only available when MBARI_API extentions are disabled at build time</i>
+ */
+
+static VALUE
+gc_stress_get(self)
+ VALUE self;
+{
+ return malloc_limit ? Qfalse : Qtrue;
+}
+
+/*
+ * call-seq:
+ * GC.stress = bool => bool
+ *
+ * updates GC stress mode.
+ *
+ * When GC.stress = true, GC is invoked for all GC opportunity:
+ * all memory and object allocation.
+ *
+ * Since it makes Ruby very slow, it is only for debugging.
+ *
+ * <i>Only available when MBARI_API extentions are enabled at build time</i>
+ */
+
+static VALUE
+gc_stress_set(self, bool)
+ VALUE self, bool;
+{
+ rb_secure(2);
+ if (!RTEST(bool))
+ malloc_limit = unstressed_malloc_limit;
+ else if (malloc_limit > 0) {
+ unstressed_malloc_limit = malloc_limit;
+ malloc_limit = 0;
+ }
+ return bool;
+}
+
+#endif /* MBARI_API */
static void run_final();
static VALUE nomem_error;
@@ -512,6 +567,7 @@ static unsigned int STACK_LEVEL_MAX = 655300;
#ifndef nativeAllocA
/* portable way to return an approximate stack pointer */
+NOINLINE(VALUE *__sp(void));
VALUE *__sp(void) {
VALUE tos;
return &tos;
@@ -548,7 +604,7 @@ stack_grow_direction(addr)
# define STACK_UPPER(a, b) (rb_gc_stack_grow_direction > 0 ? a : b)
#endif
-int
+size_t
ruby_stack_length(start, base)
VALUE *start, **base;
{
@@ -733,7 +789,7 @@ mark_locations_array(x, n)
}
}
-void inline
+inline void
rb_gc_mark_locations(start, end)
VALUE *start, *end;
{
@@ -1103,7 +1159,7 @@ gc_sweep()
RVALUE *p, *pend, *final_list;
int freed = 0;
int i;
- unsigned long free_min = 0;
+ long free_min = 0;
for (i = 0; i < heaps_used; i++) {
free_min += heaps[i].limit;
@@ -1376,7 +1432,6 @@ garbage_collect_0(VALUE *top_frame)
{
struct gc_list *list;
struct FRAME * frame;
- jmp_buf save_regs_gc_mark;
SET_STACK_END;
#ifdef HAVE_NATIVETHREAD
@@ -1415,19 +1470,15 @@ garbage_collect_0(VALUE *top_frame)
mark_tbl(finalizer_table);
}
- FLUSH_REGISTER_WINDOWS;
- /* This assumes that all registers are saved into the jmp_buf (and stack) */
- rb_setjmp(save_regs_gc_mark);
- mark_locations_array((VALUE*)save_regs_gc_mark, sizeof(save_regs_gc_mark) / sizeof(VALUE *));
#if STACK_GROW_DIRECTION < 0
- rb_gc_mark_locations(top_frame, rb_gc_stack_start);
+ rb_gc_mark_locations(top_frame, rb_curr_thread->stk_start);
#elif STACK_GROW_DIRECTION > 0
- rb_gc_mark_locations(rb_gc_stack_start, top_frame + 1);
+ rb_gc_mark_locations(rb_curr_thread->stk_start, top_frame + 1);
#else
if (rb_gc_stack_grow_direction < 0)
- rb_gc_mark_locations(top_frame, rb_gc_stack_start);
+ rb_gc_mark_locations(top_frame, rb_curr_thread->stk_start);
else
- rb_gc_mark_locations(rb_gc_stack_start, top_frame + 1);
+ rb_gc_mark_locations(rb_curr_thread->stk_start, top_frame + 1);
#endif
#ifdef __ia64
/* mark backing store (flushed register window on the stack) */
@@ -1436,7 +1487,7 @@ garbage_collect_0(VALUE *top_frame)
#endif
#if defined(__human68k__) || defined(__mc68000__)
rb_gc_mark_locations((VALUE*)((char*)STACK_END + 2),
- (VALUE*)((char*)rb_gc_stack_start + 2));
+ (VALUE*)((char*)rb_curr_thread->stk_start + 2));
#endif
rb_gc_mark_threads();
@@ -1473,13 +1524,17 @@ garbage_collect_0(VALUE *top_frame)
static void
garbage_collect()
{
+ jmp_buf save_regs_gc_mark;
VALUE *top = __sp();
+ FLUSH_REGISTER_WINDOWS;
+ /* This assumes that all registers are saved into the jmp_buf (and stack) */
+ rb_setjmp(save_regs_gc_mark);
+
#if STACK_WIPE_SITES & 0x400
# ifdef nativeAllocA
if (__stack_past (top, stack_limit)) {
/* allocate a large frame to ensure app stack cannot grow into GC stack */
- volatile char *spacer =
- nativeAllocA(__stack_depth((void*)stack_limit,(void*)top));
+ (volatile void*) nativeAllocA(__stack_depth((void*)stack_limit,(void*)top));
}
garbage_collect_0(top);
# else /* no native alloca() available */
@@ -2123,10 +2178,15 @@ Init_GC()
rb_define_singleton_method(rb_mGC, "start", rb_gc_start, 0);
rb_define_singleton_method(rb_mGC, "enable", rb_gc_enable, 0);
rb_define_singleton_method(rb_mGC, "disable", rb_gc_disable, 0);
+#ifdef MBARI_API
rb_define_singleton_method(rb_mGC, "limit", gc_getlimit, 0);
rb_define_singleton_method(rb_mGC, "limit=", gc_setlimit, 1);
- rb_define_singleton_method(rb_mGC, "increase", gc_increase, 0);
+ rb_define_singleton_method(rb_mGC, "growth", gc_growth, 0);
rb_define_singleton_method(rb_mGC, "exorcise", gc_exorcise, 0);
+#else
+ rb_define_singleton_method(rb_mGC, "stress", gc_stress_get, 0);
+ rb_define_singleton_method(rb_mGC, "stress=", gc_stress_set, 1);
+#endif
rb_define_method(rb_mGC, "garbage_collect", rb_gc_start, 0);
rb_mObSpace = rb_define_module("ObjectSpace");
diff --git a/intern.h b/intern.h
index e434bc5..ee9185e 100644
--- a/intern.h
+++ b/intern.h
@@ -251,7 +251,7 @@ VALUE rb_file_directory_p _((VALUE,VALUE));
/* gc.c */
NORETURN(void rb_memerror __((void)));
int ruby_stack_check _((void));
-int ruby_stack_length _((VALUE *,VALUE**));
+size_t ruby_stack_length _((VALUE *,VALUE**));
int rb_during_gc _((void));
char *rb_source_filename _((const char*));
void rb_gc_mark_locations _((VALUE*, VALUE*));
diff --git a/node.h b/node.h
index e79f526..3295cf7 100644
--- a/node.h
+++ b/node.h
@@ -409,13 +409,11 @@ struct rb_thread {
VALUE result;
- long stk_len, stk_max;
+ size_t stk_len, stk_max;
VALUE *stk_ptr, *stk_pos, *stk_start;
#ifdef __ia64
- long bstr_len;
- long bstr_max;
- VALUE *bstr_ptr;
- VALUE *bstr_pos;
+ size_t bstr_len, bstr_max;
+ VALUE *bstr_ptr, *bstr_pos;
#endif
struct FRAME *frame;
diff --git a/re.c b/re.c
index a0ac6a8..85d013c 100644
--- a/re.c
+++ b/re.c
@@ -1468,18 +1468,18 @@ VALUE
rb_reg_regcomp(str)
VALUE str;
{
- volatile VALUE save_str = str;
- if (reg_cache && RREGEXP(reg_cache)->len == RSTRING(str)->len
- && case_cache == ruby_ignorecase
- && kcode_cache == reg_kcode
- && memcmp(RREGEXP(reg_cache)->str, RSTRING(str)->ptr, RSTRING(str)->len) == 0)
- return reg_cache;
-
- case_cache = ruby_ignorecase;
- kcode_cache = reg_kcode;
- reg_cache = rb_reg_new(RSTRING(str)->ptr, RSTRING(str)->len, ruby_ignorecase);
- RB_GC_GUARD(save_str);
+ if (reg_cache && RREGEXP(reg_cache)->len == RSTRING(str)->len
+ && case_cache == ruby_ignorecase
+ && kcode_cache == reg_kcode
+ && memcmp(RREGEXP(reg_cache)->str, RSTRING(str)->ptr,
+ RSTRING(str)->len) == 0)
return reg_cache;
+
+ case_cache = ruby_ignorecase;
+ kcode_cache = reg_kcode;
+ reg_cache = rb_reg_new(RSTRING(str)->ptr, RSTRING(str)->len, ruby_ignorecase);
+ RB_GC_GUARD(str);
+ return reg_cache;
}
static int
diff --git a/rubysig.h b/rubysig.h
index 8a11cf4..fae0869 100644
--- a/rubysig.h
+++ b/rubysig.h
@@ -15,6 +15,11 @@
#include <errno.h>
+#if defined __ppc__ || defined __powerpc__ || \
+ defined __ppc64__ || defined __powerpc64__
+#define __anyPowerPC__ 1 /* for compatibility with older gcc versions */
+#endif
+
/* STACK_WIPE_SITES determines where attempts are made to exorcise
"ghost object refereces" from the stack and how the stack is cleared:
@@ -65,7 +70,7 @@
#ifndef STACK_WIPE_SITES
# ifdef __x86_64__ /* deal with "red zone" by not inlining stack clearing */
# define STACK_WIPE_SITES 0x6770
-# elif defined __ppc__ || defined __ppc64__ /* On any PowerPC, deal with... */
+# elif defined __anyPowerPC__ /* On any PowerPC, deal with... */
# define STACK_WIPE_SITES 0x7764 /* red zone & alloc(0) doesn't return sp */
# else
# define STACK_WIPE_SITES 0x8770 /*normal case, use 0x4770 if problems arise*/
@@ -211,11 +216,12 @@ static inline VALUE *__sp(void) \
VALUE *sp; asm(asmb); \
return sp; \
}
-# if defined __ppc__ || defined __ppc64__
+# ifdef __anyPowerPC__
__defspfn("addi %0, r1, 0": "=r"(sp))
# elif defined __i386__
__defspfn("movl %%esp, %0": "=r"(sp))
# elif defined __x86_64__
+#warn ===> x86_64 inline assembler is known to crash -- change STACK_WIPE_SITES
__defspfn("movq %%rsp, %0": "=r"(sp))
# elif __arm__
__defspfn("mov %0, sp": "=r"(sp))
diff --git a/test/ruby/suicide.rb b/test/ruby/suicide.rb
index 2687ed0..c7a0a67 100644
--- a/test/ruby/suicide.rb
+++ b/test/ruby/suicide.rb
@@ -1,2 +1,4 @@
STDERR.reopen(STDOUT)
-at_exit{Process.kill(:INT, $$)}
+at_exit{Process.kill(:INT, $$); sleep 0}
+# brent@mbari.org says
+# sleep 0 avoids race between process termination and signal reception
diff --git a/version.h b/version.h
index c608764..b336dd7 100644
--- a/version.h
+++ b/version.h
@@ -1,15 +1,15 @@
#define RUBY_VERSION "1.8.7"
-#define RUBY_RELEASE_DATE "2009-2-9"
+#define RUBY_RELEASE_DATE "2009-3-1"
#define RUBY_VERSION_CODE 187
-#define RUBY_RELEASE_CODE 20090209
+#define RUBY_RELEASE_CODE 20090301
#define RUBY_PATCHLEVEL 72
#define RUBY_VERSION_MAJOR 1
#define RUBY_VERSION_MINOR 8
#define RUBY_VERSION_TEENY 7
#define RUBY_RELEASE_YEAR 2009
-#define RUBY_RELEASE_MONTH 2
-#define RUBY_RELEASE_DAY 9
+#define RUBY_RELEASE_MONTH 3
+#define RUBY_RELEASE_DAY 1
#ifdef RUBY_EXTERN
RUBY_EXTERN const char ruby_version[];
@@ -28,7 +28,14 @@ RUBY_EXTERN const char *ruby_copyright;
#include "rubysig.h"
#define string_arg(s) #s
-#define MBARI_RELEASE(wipe_sites) "MBARI 7/" string_arg(wipe_sites)
+
+#ifdef MBARI_API
+#define _mbari_rev_ "MBARI"
+#else
+#define _mbari_rev_ "mbari"
+#endif
+
+#define MBARI_RELEASE(wipe_sites) _mbari_rev_ " 8B/" string_arg(wipe_sites)
#define RUBY_RELEASE_STR MBARI_RELEASE(STACK_WIPE_SITES) " on patchlevel"
#define RUBY_RELEASE_NUM RUBY_PATCHLEVEL
--- mbari8A/configure 2008-08-10 17:39:51.000000000 -0700
+++ matzruby/configure 2009-02-25 21:16:28.000000000 -0800
@@ -1347,6 +1347,7 @@
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
--enable-frame-address use GCC __builtin_frame_address().
+ --enable-mbari-api enable API changes from the MBARI patches.
--disable-largefile omit support for large files
--enable-pthread use pthread library.
--disable-fastthread do not use the fastthread mutex
@@ -1359,6 +1360,7 @@
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
--without-gcc never use gcc
+ --with-wipe-sites=MASK override default STACK_WIPES_SITES mask in rubysig.h
--with-winsock2 link winsock2 (MinGW only)
--with-libc_r link libc_r if possible (FreeBSD only)
--with-setjmp-type select setjmp type
@@ -1367,7 +1369,7 @@
--with-static-linked-ext link external modules statically
--with-sitedir=DIR site libraries in DIR [LIBDIR/ruby/site_ruby]
--with-vendordir=DIR vendor libraries in DIR [LIBDIR/ruby/vendor_ruby]
- --with-search-path=DIR specify the additional search path
+ --with-search-path= DIR specify the additional search path
--with-mantype=TYPE specify man page type; TYPE is one of man and doc
Some influential environment variables:
@@ -2042,6 +2044,35 @@
_ACEOF
fi
+# Check whether --enable-mbari-api was given.
+if test "${enable_mbari_api+set}" = set; then
+ enableval=$enable_mbari_api; mbari_api=$enableval
+fi
+
+if test "$mbari_api" = yes; then
+ cat >>confdefs.h <<\_ACEOF
+#define MBARI_API 1
+_ACEOF
+
+fi
+
+# Check whether --with-wipe-sites was given.
+if test "${with_wipe_sites+set}" = set; then
+ withval=$with_wipe_sites; wipe_sites=$withval
+fi
+
+if test "$wipe_sites" != ""; then
+ case $wipe_sites in
+ none|no) wipe_sites=0x0;;
+ yes) wipe_sites=;;
+ esac
+ if test -n "$wipe_sites"; then
+ cat >>confdefs.h <<_ACEOF
+#define STACK_WIPE_SITES $wipe_sites
+_ACEOF
+
+ fi
+fi
test "$program_prefix" != NONE &&
program_transform_name="s&^&$program_prefix&;$program_transform_name"