whoami7 - Manager
:
/
proc
/
self
/
root
/
usr
/
local
/
rvm
/
patches
/
ruby
/
1.8.7
/
p72
/
Upload File:
files >> //proc/self/root/usr/local/rvm/patches/ruby/1.8.7/p72/mbari-4.patch
diff -rux '*.o' ruby-1.8.7-p72/ChangeLog ruby-1.8.7-mbari/ChangeLog --- ruby-1.8.7-p72/ChangeLog 2008-12-16 00:47:25.000000000 -0800 +++ ruby-1.8.7-mbari/ChangeLog 2008-12-16 23:06:21.000000000 -0800 @@ -1,3 +1,11 @@ +Tue Dec 15 9:15:36 2008 Brent Roman <brent@mbari.org> + + * eval.c: factored rb_eval() into many separate non-inlined + functions to reduce the size of its stack frame when + compiled with gcc. + Factored callcc into 2 functions. + + Tue Dec 13 6:10:36 2008 Brent Roman <brent@mbari.org> * eval.c: update stack extent just before and after every setjmp diff -rux '*.o' ruby-1.8.7-p72/eval.c ruby-1.8.7-mbari/eval.c --- ruby-1.8.7-p72/eval.c 2008-12-16 00:47:25.000000000 -0800 +++ ruby-1.8.7-mbari/eval.c 2008-12-16 23:28:08.000000000 -0800 @@ -3,7 +3,7 @@ eval.c - $Author: brent $ - $Date: 2008/12/14 07:23:06 $ + $Date: 2008/12/17 07:28:08 $ created at: Thu Jun 10 14:22:17 JST 1993 Copyright (C) 1993-2003 Yukihiro Matsumoto @@ -219,7 +219,7 @@ VALUE rb_cBinding; static VALUE proc_invoke _((VALUE,VALUE,VALUE,VALUE)); static VALUE rb_f_binding _((VALUE)); -static void rb_f_END _((void)); +NOINLINE(static void rb_f_END _((void))); static VALUE rb_f_block_given_p _((void)); static VALUE block_pass _((VALUE,NODE*)); @@ -1240,12 +1240,7 @@ if (NIL_P(ruby_errinfo)) return; PUSH_TAG(PROT_NONE); - if (EXEC_TAG() == 0) { - errat = get_backtrace(ruby_errinfo); - } - else { - errat = Qnil; - } + errat = EXEC_TAG() == 0 ? get_backtrace(ruby_errinfo) : Qnil; if (EXEC_TAG()) goto error; if (NIL_P(errat)){ ruby_set_current_source(); @@ -1926,8 +1921,8 @@ return rb_const_defined(cref->nd_clss, id); } -static VALUE -ev_const_get(cref, id, self) +NOINLINE(static VALUE +ev_const_get(cref, id, self)) NODE *cref; ID id; VALUE self; @@ -2942,40 +2937,960 @@ } } -static VALUE -rb_eval(self, n) - VALUE self; - NODE *n; + +/* + functions factored out of rb_eval() to reduce its stack frame size +*/ +NOINLINE(static VALUE eval_match2(self, node)) + VALUE self; + NODE *node; +{ + 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; +{ + VALUE r = rb_eval(self,node->nd_recv); + VALUE l = rb_eval(self,node->nd_value); + return TYPE(l) == T_STRING ? rb_reg_match(r, l) : rb_funcall(l, match, 1, r); +} + + +NOINLINE(static void +eval_opt_n(self, node)) + VALUE self; + NODE *node; +{ + int state; + PUSH_TAG(PROT_LOOP); + switch (state = EXEC_TAG()) { + case 0: + opt_n_next: + while (!NIL_P(rb_gets())) { + opt_n_redo: + rb_eval(self, node->nd_body); + } + break; + + case TAG_REDO: + state = 0; + goto opt_n_redo; + case TAG_NEXT: + state = 0; + goto opt_n_next; + case TAG_BREAK: + state = 0; + default: + break; + } + POP_TAG(); + if (state) JUMP_TAG(state); +} + + +NOINLINE(static NODE * +eval_when(self, node)) + VALUE self; + NODE *node; +{ + do { + NODE *tag = node->nd_head; + while (tag) { + EXEC_EVENT_HOOK(RUBY_EVENT_LINE, tag, self, + ruby_frame->last_func, + ruby_frame->last_class); + if (tag->nd_head && nd_type(tag->nd_head) == NODE_WHEN) { + VALUE v = rb_eval(self, tag->nd_head->nd_head); + long i; + + if (TYPE(v) != T_ARRAY) v = rb_ary_to_ary(v); + for (i=0; i<RARRAY(v)->len; i++) { + if (RTEST(RARRAY(v)->ptr[i])) return node->nd_body; + } + tag = tag->nd_next; + continue; + } + if (RTEST(rb_eval(self, tag->nd_head))) return node->nd_body; + tag = tag->nd_next; + } + } while ((node = node->nd_next) && nd_type(node) == NODE_WHEN); + return node; +} + + +NOINLINE (static NODE * +eval_case(self, node)) + VALUE self; + NODE *node; +{ + VALUE val = rb_eval(self, node->nd_head); + node = node->nd_body; + while (node) { + NODE *tag; + + if (nd_type(node) != NODE_WHEN) break; + tag = node->nd_head; + while (tag) { + EXEC_EVENT_HOOK(RUBY_EVENT_LINE, tag, self, + ruby_frame->last_func, + ruby_frame->last_class); + if (tag->nd_head && nd_type(tag->nd_head) == NODE_WHEN) { + VALUE v = rb_eval(self, tag->nd_head->nd_head); + long i; + + if (TYPE(v) != T_ARRAY) v = rb_ary_to_ary(v); + for (i=0; i<RARRAY(v)->len; i++) { + if (RTEST(rb_funcall2(RARRAY(v)->ptr[i], eqq, 1, &val))) + return node->nd_body; + } + tag = tag->nd_next; + continue; + } + if (RTEST(rb_funcall2(rb_eval(self, tag->nd_head), eqq, 1, &val))) + return node->nd_body; + tag = tag->nd_next; + } + node = node->nd_next; + } + return node; +} + + +NOINLINE (static VALUE +eval_while(self, node)) + VALUE self; + NODE *node; +{ + int state; + volatile VALUE result = Qnil; + 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: + rb_eval(self, node->nd_body); + while_next: + ; + } while (RTEST(rb_eval(self, node->nd_cond))); + break; + + case TAG_REDO: + state = 0; + goto while_redo; + case TAG_NEXT: + state = 0; + goto while_next; + case TAG_BREAK: + if (TAG_DST()) { + 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; +{ + int state; + volatile VALUE result = Qnil; + 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: + rb_eval(self, node->nd_body); + until_next: + ; + } while (!RTEST(rb_eval(self, node->nd_cond))); + break; + + case TAG_REDO: + state = 0; + goto until_redo; + case TAG_NEXT: + state = 0; + goto until_next; + case TAG_BREAK: + if (TAG_DST()) { + 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; +{ + int state; + volatile VALUE result = Qnil; + + PUSH_TAG(PROT_LOOP); + PUSH_BLOCK(node->nd_var, node->nd_body); + + state = EXEC_TAG(); + switch (state) { + case TAG_RETRY: + state = 0; /* fall thru to case 0 */ + case 0: + PUSH_ITER(ITER_PRE); + if (nd_type(node) == NODE_ITER) { + result = rb_eval(self, node->nd_iter); + } + else { + VALUE recv; + + _block.flags &= ~BLOCK_D_SCOPE; + BEGIN_CALLARGS; + recv = rb_eval(self, node->nd_iter); + END_CALLARGS; + ruby_current_node = node; + SET_CURRENT_SOURCE(); + result = rb_call(CLASS_OF(recv),recv,each,0,0,0,self); + } + POP_ITER(); + break; + + case TAG_BREAK: + if (TAG_DST()) { + result = prot_tag->retval; + state = 0; + } + } + POP_BLOCK(); + POP_TAG(); + if (state) JUMP_TAG(state); + return result; +} + + +NOINLINE (static VALUE +eval_rescue(self, node)) + VALUE self; + NODE *node; { - NODE * volatile contnode = 0; - NODE * volatile node = n; + volatile VALUE e_info = ruby_errinfo; + volatile int rescuing = 0; int state; volatile VALUE result = Qnil; - st_data_t data; -#define RETURN(v) do { \ - result = (v); \ - goto finish; \ -} while (0) + PUSH_TAG(PROT_NONE); + if ((state = EXEC_TAG()) == 0) { + retry_entry: + result = rb_eval(self, node->nd_head); + } + else if (rescuing) { + if (rescuing < 0) { + /* in rescue argument, just reraise */ + } + else if (state == TAG_RETRY) { + rescuing = state = 0; + ruby_errinfo = e_info; + goto retry_entry; + } + else if (state != TAG_RAISE) { + result = prot_tag->retval; + } + } + else if (state == TAG_RAISE) { + NODE *resq = node->nd_resq; - again: - if (!node) RETURN(Qnil); + rescuing = -1; + while (resq) { + ruby_current_node = resq; + if (handle_rescue(self, resq)) { + state = 0; + rescuing = 1; + result = rb_eval(self, resq->nd_body); + break; + } + resq = resq->nd_head; /* next rescue */ + } + } + else { + result = prot_tag->retval; + } + POP_TAG(); + if (state != TAG_RAISE) ruby_errinfo = e_info; + if (state) { + JUMP_TAG(state); + } + /* no exception raised */ + if (!rescuing && node->nd_else) { /* else clause given */ + result = Qundef; /* caller must eval this! */ + } + return result; +} + +NOINLINE (static VALUE +eval_ensure(self, node)) + VALUE self; + NODE *node; +{ + int state; + volatile VALUE result = Qnil; + + PUSH_TAG(PROT_NONE); + if ((state = EXEC_TAG()) == 0) { + result = rb_eval(self, node->nd_head); + } + POP_TAG(); + if (node->nd_ensr && !thread_no_ensure()) { + VALUE retval = prot_tag->retval; /* save retval */ + VALUE errinfo = ruby_errinfo; + + rb_eval(self, node->nd_ensr); + return_value(retval); + ruby_errinfo = errinfo; + } + if (state) JUMP_TAG(state); + return result; +} + + +NOINLINE (static VALUE +eval_dot(self, node)) + VALUE self; + NODE *node; +{ + VALUE beg = rb_eval(self, node->nd_beg); + VALUE end = rb_eval(self, node->nd_end); + return rb_range_new(beg, end, nd_type(node) == NODE_DOT3); +} + + +NOINLINE (static VALUE +eval_flip2(self, node)) + VALUE self; + NODE *node; +{ + VALUE *flip = rb_svar(node->nd_cnt); + if (!flip) rb_bug("unexpected local variable"); + if (!RTEST(*flip)) { + if (!RTEST(rb_eval(self, node->nd_beg))) + return Qfalse; + *flip = RTEST(rb_eval(self, node->nd_end))?Qfalse:Qtrue; + } + else if (RTEST(rb_eval(self, node->nd_end))) + *flip = Qfalse; + return Qtrue; +} + + +NOINLINE (static VALUE +eval_flip3(self, node)) + VALUE self; + NODE *node; +{ + VALUE *flip = rb_svar(node->nd_cnt); + if (!flip) rb_bug("unexpected local variable"); + if (!RTEST(*flip)) + return *flip = (RTEST(rb_eval(self, node->nd_beg)) ? Qtrue : Qfalse); + if (RTEST(rb_eval(self, node->nd_end))) + *flip = Qfalse; + return Qtrue; +} + + +NOINLINE (static VALUE +eval_attrasgn(self, node)) + VALUE self; + NODE *node; +{ + VALUE recv; + int argc; VALUE *argv; /* used in SETUP_ARGS */ + int scope; + TMP_PROTECT; + + BEGIN_CALLARGS; + if (node->nd_recv == (NODE *)1) { + recv = self; + scope = 1; + } + else { + recv = rb_eval(self, node->nd_recv); + scope = 0; + } + SETUP_ARGS(node->nd_args); + END_CALLARGS; + + ruby_current_node = node; + SET_CURRENT_SOURCE(); + rb_call(CLASS_OF(recv),recv,node->nd_mid,argc,argv,scope,self); + return argv[argc-1]; +} + + +NOINLINE (static VALUE +eval_call(self, node)) + VALUE self; + NODE *node; +{ + VALUE recv; + int argc; VALUE *argv; /* used in SETUP_ARGS */ + TMP_PROTECT; + + BEGIN_CALLARGS; + recv = rb_eval(self, node->nd_recv); + SETUP_ARGS(node->nd_args); + END_CALLARGS; + + ruby_current_node = node; + SET_CURRENT_SOURCE(); + return rb_call(CLASS_OF(recv),recv,node->nd_mid,argc,argv,0,self); +} + + +NOINLINE (static VALUE +eval_fcall(self, node)) + VALUE self; + NODE *node; +{ + int argc; VALUE *argv; /* used in SETUP_ARGS */ + TMP_PROTECT; + + BEGIN_CALLARGS; + SETUP_ARGS(node->nd_args); + END_CALLARGS; + + ruby_current_node = node; + SET_CURRENT_SOURCE(); + 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; +{ + int argc; VALUE *argv; /* used in SETUP_ARGS */ + TMP_PROTECT; + + if (ruby_frame->last_class == 0) { + if (ruby_frame->last_func) { + rb_name_error(ruby_frame->last_func, + "superclass method `%s' disabled", + rb_id2name(ruby_frame->orig_func)); + } + else { + rb_raise(rb_eNoMethodError, "super called outside of method"); + } + } + if (nd_type(node) == NODE_ZSUPER) { + argc = ruby_frame->argc; + if (argc && DMETHOD_P()) { + if (TYPE(RBASIC(ruby_scope)->klass) != T_ARRAY || + RARRAY(RBASIC(ruby_scope)->klass)->len != argc) { + rb_raise(rb_eRuntimeError, + "super: specify arguments explicitly"); + } + argv = RARRAY(RBASIC(ruby_scope)->klass)->ptr; + } + else if (!ruby_scope->local_vars) { + argc = 0; + argv = 0; + } + else { + argv = ruby_scope->local_vars + 2; + } + } + else { + BEGIN_CALLARGS; + SETUP_ARGS(node->nd_args); + END_CALLARGS; + ruby_current_node = node; + } + + SET_CURRENT_SOURCE(); + return rb_call_super(argc, argv); +} + + +NOINLINE (static VALUE +eval_scope(self, node)) + VALUE self; + NODE *node; +{ + int state; + volatile VALUE result = Qnil; + struct FRAME frame; + NODE *saved_cref = 0; + + frame = *ruby_frame; + frame.tmp = ruby_frame; + ruby_frame = &frame; + + PUSH_SCOPE(); + PUSH_TAG(PROT_NONE); + if (node->nd_rval) { + saved_cref = ruby_cref; + ruby_cref = (NODE*)node->nd_rval; + } + if (node->nd_tbl) { + VALUE *vars = ALLOCA_N(VALUE, node->nd_tbl[0]+1); + *vars++ = (VALUE)node; + ruby_scope->local_vars = vars; + rb_mem_clear(ruby_scope->local_vars, node->nd_tbl[0]); + ruby_scope->local_tbl = node->nd_tbl; + } + else { + ruby_scope->local_vars = 0; + ruby_scope->local_tbl = 0; + } + if ((state = EXEC_TAG()) == 0) { + result = rb_eval(self, node->nd_next); + } + POP_TAG(); + POP_SCOPE(); + ruby_frame = frame.tmp; + if (saved_cref) + ruby_cref = saved_cref; + if (state) JUMP_TAG(state); + return result; +} + +NOINLINE (static VALUE +eval_op_asgn1(self, node)) + VALUE self; + NODE *node; +{ + int argc; VALUE *argv; /* used in SETUP_ARGS */ + VALUE recv, val, tmp; + NODE *rval; + TMP_PROTECT; + + recv = rb_eval(self, node->nd_recv); + rval = node->nd_args->nd_head; + SETUP_ARGS0(node->nd_args->nd_body, 1); + val = rb_funcall3(recv, aref, argc, argv); + switch (node->nd_mid) { + case 0: /* OR */ + if (RTEST(val)) return val; + val = rb_eval(self, rval); + break; + case 1: /* AND */ + if (!RTEST(val)) return val; + val = rb_eval(self, rval); + break; + default: + tmp = rb_eval(self, rval); + val = rb_funcall3(val, node->nd_mid, 1, &tmp); + } + argv[argc] = val; + rb_funcall2(recv, aset, argc+1, argv); + return val; +} + + +NOINLINE (static VALUE +eval_op_asgn2(self, node)) + VALUE self; + NODE *node; +{ + ID id = node->nd_next->nd_vid; + VALUE recv, val, tmp; + + recv = rb_eval(self, node->nd_recv); + val = rb_funcall3(recv, id, 0, 0); + switch (node->nd_next->nd_mid) { + case 0: /* OR */ + if (RTEST(val)) return val; + val = rb_eval(self, node->nd_value); + break; + case 1: /* AND */ + if (!RTEST(val)) return val; + val = rb_eval(self, node->nd_value); + break; + default: + tmp = rb_eval(self, node->nd_value); + val = rb_funcall3(val, node->nd_next->nd_mid, 1, &tmp); + } + + rb_funcall2(recv, node->nd_next->nd_aid, 1, &val); + return val; +} + + +NOINLINE (static VALUE +eval_hash(self, node)) + VALUE self; + NODE *node; +{ + NODE *list; + VALUE hash = rb_hash_new(); + VALUE key, val; + + list = node->nd_head; + while (list) { + key = rb_eval(self, list->nd_head); + list = list->nd_next; + if (list == 0) + rb_bug("odd number list for Hash"); + val = rb_eval(self, list->nd_head); + list = list->nd_next; + rb_hash_aset(hash, key, val); + } + return hash; +} + + +NOINLINE (static VALUE +eval_array(self, node)) + VALUE self; + NODE *node; +{ + VALUE ary; + long i; + + i = node->nd_alen; + ary = rb_ary_new2(i); + for (i=0;node;node=node->nd_next) { + RARRAY(ary)->ptr[i++] = rb_eval(self, node->nd_head); + RARRAY(ary)->len = i; + } + return ary; +} + + +NOINLINE (static VALUE +eval_slit(self, node)) + VALUE self; + NODE *node; +{ + VALUE str, str2; + NODE *list = node->nd_next; + + str = rb_str_new3(node->nd_lit); + while (list) { + if (list->nd_head) { + switch (nd_type(list->nd_head)) { + case NODE_STR: + str2 = list->nd_head->nd_lit; + break; + default: + str2 = rb_eval(self, list->nd_head); + break; + } + rb_str_append(str, str2); + OBJ_INFECT(str, str2); + } + list = list->nd_next; + } + switch (nd_type(node)) { + case NODE_DREGX: + return rb_reg_new(RSTRING(str)->ptr, RSTRING(str)->len, + node->nd_cflag); + 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); + return node->nd_lit = str2; + case NODE_LIT: + /* other thread may replace NODE_DREGX_ONCE to NODE_LIT */ + return Qundef; + case NODE_DXSTR: + return rb_funcall(self, '`', 1, str); + case NODE_DSYM: + return rb_str_intern(str); + } + return str; +} + + +NOINLINE (static void +eval_defn(self, node)) + VALUE self; + NODE *node; +{ + NODE *body, *defn; + VALUE origin = 0; + int noex; + + if (NIL_P(ruby_class)) { + rb_raise(rb_eTypeError, "no class/module to add method"); + } + if (ruby_class == rb_cObject && node->nd_mid == init) { + rb_warn("redefining Object#initialize may cause infinite loop"); + } + if (node->nd_mid == __id__ || node->nd_mid == __send__) { + rb_warn("redefining `%s' may cause serious problem", + rb_id2name(node->nd_mid)); + } + rb_frozen_class_p(ruby_class); + body = search_method(ruby_class, node->nd_mid, &origin); + if (body){ + if (RTEST(ruby_verbose) && ruby_class == origin && body->nd_cnt == 0 && body->nd_body) { + rb_warning("method redefined; discarding old %s", rb_id2name(node->nd_mid)); + } + } + + if (SCOPE_TEST(SCOPE_PRIVATE) || node->nd_mid == init) { + noex = NOEX_PRIVATE; + } + else if (SCOPE_TEST(SCOPE_PROTECTED)) { + noex = NOEX_PROTECTED; + } + else { + noex = NOEX_PUBLIC; + } + if (body && origin == ruby_class && body->nd_body == 0) { + noex |= NOEX_NOSUPER; + } + + defn = rb_copy_node_scope(node->nd_defn, ruby_cref); + rb_add_method(ruby_class, node->nd_mid, defn, noex); + if (scope_vmode == SCOPE_MODFUNC) { + rb_add_method(rb_singleton_class(ruby_class), + node->nd_mid, defn, NOEX_PUBLIC); + } +} + + +NOINLINE (static void +eval_defs(self, node)) + VALUE self; + NODE *node; +{ + VALUE recv = rb_eval(self, node->nd_recv); + VALUE klass; + NODE *body = 0, *defn; + st_data_t data; + + if (ruby_safe_level >= 4 && !OBJ_TAINTED(recv)) { + rb_raise(rb_eSecurityError, "Insecure: can't define singleton method"); + } + if (FIXNUM_P(recv) || SYMBOL_P(recv)) { + rb_raise(rb_eTypeError, + "can't define singleton method \"%s\" for %s", + rb_id2name(node->nd_mid), + rb_obj_classname(recv)); + } + + if (OBJ_FROZEN(recv)) rb_error_frozen("object"); + klass = rb_singleton_class(recv); + if (st_lookup(RCLASS(klass)->m_tbl, node->nd_mid, &data)) { + body = (NODE *)data; + if (ruby_safe_level >= 4) { + rb_raise(rb_eSecurityError, "redefining method prohibited"); + } + if (RTEST(ruby_verbose)) { + rb_warning("redefine %s", rb_id2name(node->nd_mid)); + } + } + defn = rb_copy_node_scope(node->nd_defn, ruby_cref); + rb_add_method(klass, node->nd_mid, defn, + NOEX_PUBLIC|(body?body->nd_noex&NOEX_UNDEF:0)); +} + + +NOINLINE (static VALUE +eval_class(self, node)) + VALUE self; + NODE *node; +{ + VALUE super, klass, tmp, cbase; + ID cname; + int gen = Qfalse; + + cbase = class_prefix(self, node->nd_cpath); + cname = node->nd_cpath->nd_mid; + + if (NIL_P(ruby_cbase)) { + rb_raise(rb_eTypeError, "no outer class/module"); + } + if (node->nd_super) { + super = rb_eval(self, node->nd_super); + rb_check_inheritable(super); + } + else { + super = 0; + } + + if (rb_const_defined_at(cbase, cname)) { + klass = rb_const_get_at(cbase, cname); + if (TYPE(klass) != T_CLASS) { + rb_raise(rb_eTypeError, "%s is not a class", + rb_id2name(cname)); + } + if (super) { + tmp = rb_class_real(RCLASS(klass)->super); + if (tmp != super) { + rb_raise(rb_eTypeError, "superclass mismatch for class %s", + rb_id2name(cname)); + } + super = 0; + } + if (ruby_safe_level >= 4) { + rb_raise(rb_eSecurityError, "extending class prohibited"); + } + } + else { + if (!super) super = rb_cObject; + klass = rb_define_class_id(cname, super); + rb_set_class_path(klass, cbase, rb_id2name(cname)); + rb_const_set(cbase, cname, klass); + gen = Qtrue; + } + if (ruby_wrapper) { + rb_extend_object(klass, ruby_wrapper); + rb_include_module(klass, ruby_wrapper); + } + if (super && gen) { + rb_class_inherited(super, klass); + } + return module_setup(klass, node); +} + + +NOINLINE (static VALUE +eval_module(self, node)) + VALUE self; + NODE *node; +{ + VALUE module, cbase; + ID cname; + + if (NIL_P(ruby_cbase)) { + rb_raise(rb_eTypeError, "no outer class/module"); + } + cbase = class_prefix(self, node->nd_cpath); + cname = node->nd_cpath->nd_mid; + if (rb_const_defined_at(cbase, cname)) { + module = rb_const_get_at(cbase, cname); + if (TYPE(module) != T_MODULE) { + rb_raise(rb_eTypeError, "%s is not a module", + rb_id2name(cname)); + } + if (ruby_safe_level >= 4) { + rb_raise(rb_eSecurityError, "extending module prohibited"); + } + } + else { + module = rb_define_module_id(cname); + rb_set_class_path(module, cbase, rb_id2name(cname)); + rb_const_set(cbase, cname, module); + } + if (ruby_wrapper) { + rb_extend_object(module, ruby_wrapper); + rb_include_module(module, ruby_wrapper); + } + + return module_setup(module, node); +} + + +NOINLINE (static VALUE +eval_sclass(self, node)) + VALUE self; + NODE *node; +{ + VALUE klass, result; + + result = rb_eval(self, node->nd_recv); + if (FIXNUM_P(result) || SYMBOL_P(result)) { + rb_raise(rb_eTypeError, "no virtual class for %s", + rb_obj_classname(result)); + } + if (ruby_safe_level >= 4 && !OBJ_TAINTED(result)) + rb_raise(rb_eSecurityError, "Insecure: can't extend object"); + klass = rb_singleton_class(result); + + if (ruby_wrapper) { + rb_extend_object(klass, ruby_wrapper); + rb_include_module(klass, ruby_wrapper); + } + + return module_setup(klass, node); +} + + +NOINLINE (static VALUE +eval_defined(self, node)) + VALUE self; + NODE *node; +{ + char buf[20]; + const char *desc = is_defined(self, node->nd_head, buf); + return desc ? rb_str_new2(desc) : Qnil; +} + + +NOINLINE (static void +eval_cvar_set(result, node, bool)) + VALUE result, bool; + NODE *node; +{ + rb_cvar_set(cvar_cbase(), node->nd_vid, result, bool); +} + + +NOINLINE (static void +eval_cdecl(self, node, result)) + VALUE self, result; + NODE *node; +{ + if (node->nd_vid == 0) + rb_const_set(class_prefix(self, node->nd_else), + node->nd_else->nd_mid, result); + else + rb_const_set(ruby_cbase, node->nd_vid, result); +} + + +static VALUE +rb_eval(self, node) + VALUE self; + NODE *node; +{ + VALUE result; + +again: + CHECK_INTS; + result = Qnil; + if (node) { ruby_current_node = node; + switch (nd_type(node)) { case NODE_BLOCK: - if (contnode) { - result = rb_eval(self, node); - break; + while (node->nd_next) { + rb_eval(self, node->nd_head); + node = node->nd_next; } - contnode = node->nd_next; node = node->nd_head; goto again; case NODE_POSTEXE: rb_f_END(); nd_set_type(node, NODE_NIL); /* exec just once */ - result = Qnil; break; /* begin .. end without clauses */ @@ -2990,65 +3905,33 @@ /* nodes for speed-up(literal match) */ case NODE_MATCH2: - { - VALUE l = rb_eval(self,node->nd_recv); - VALUE r = rb_eval(self,node->nd_value); - result = rb_reg_match(l, r); - } + result = eval_match2(self, node); break; /* nodes for speed-up(literal match) */ case NODE_MATCH3: - { - VALUE r = rb_eval(self,node->nd_recv); - VALUE l = rb_eval(self,node->nd_value); - if (TYPE(l) == T_STRING) { - result = rb_reg_match(r, l); - } - else { - result = rb_funcall(l, match, 1, r); - } - } + result = eval_match3(self,node); break; /* node for speed-up(top-level loop for -n/-p) */ case NODE_OPT_N: - PUSH_TAG(PROT_LOOP); - switch (state = EXEC_TAG()) { - case 0: - opt_n_next: - while (!NIL_P(rb_gets())) { - opt_n_redo: - rb_eval(self, node->nd_body); - } - break; - - case TAG_REDO: - state = 0; - goto opt_n_redo; - case TAG_NEXT: - state = 0; - goto opt_n_next; - case TAG_BREAK: - state = 0; - default: - break; - } - POP_TAG(); - if (state) JUMP_TAG(state); - RETURN(Qnil); + eval_opt_n(self, node); + break; case NODE_SELF: - RETURN(self); + result = self; + break; case NODE_NIL: - RETURN(Qnil); + break; case NODE_TRUE: - RETURN(Qtrue); + result = Qtrue; + break; case NODE_FALSE: - RETURN(Qfalse); + result = Qfalse; + break; case NODE_IF: if (RTEST(rb_eval(self, node->nd_cond))) { @@ -3066,150 +3949,20 @@ goto again; case NODE_WHEN: - while (node) { - NODE *tag; - - if (nd_type(node) != NODE_WHEN) goto again; - tag = node->nd_head; - while (tag) { - EXEC_EVENT_HOOK(RUBY_EVENT_LINE, tag, self, - ruby_frame->last_func, - ruby_frame->last_class); - if (tag->nd_head && nd_type(tag->nd_head) == NODE_WHEN) { - VALUE v = rb_eval(self, tag->nd_head->nd_head); - long i; - - if (TYPE(v) != T_ARRAY) v = rb_ary_to_ary(v); - for (i=0; i<RARRAY(v)->len; i++) { - if (RTEST(RARRAY(v)->ptr[i])) { - node = node->nd_body; - goto again; - } - } - tag = tag->nd_next; - continue; - } - if (RTEST(rb_eval(self, tag->nd_head))) { - node = node->nd_body; - goto again; - } - tag = tag->nd_next; - } - node = node->nd_next; - } - RETURN(Qnil); + if (node = eval_when(self, node)) goto again; + break; case NODE_CASE: - { - VALUE val; - - val = rb_eval(self, node->nd_head); - node = node->nd_body; - while (node) { - NODE *tag; - - if (nd_type(node) != NODE_WHEN) { - goto again; - } - tag = node->nd_head; - while (tag) { - EXEC_EVENT_HOOK(RUBY_EVENT_LINE, tag, self, - ruby_frame->last_func, - ruby_frame->last_class); - if (tag->nd_head && nd_type(tag->nd_head) == NODE_WHEN) { - VALUE v = rb_eval(self, tag->nd_head->nd_head); - long i; - - if (TYPE(v) != T_ARRAY) v = rb_ary_to_ary(v); - for (i=0; i<RARRAY(v)->len; i++) { - if (RTEST(rb_funcall2(RARRAY(v)->ptr[i], eqq, 1, &val))){ - node = node->nd_body; - goto again; - } - } - tag = tag->nd_next; - continue; - } - if (RTEST(rb_funcall2(rb_eval(self, tag->nd_head), eqq, 1, &val))) { - node = node->nd_body; - goto again; - } - tag = tag->nd_next; - } - node = node->nd_next; - } - } - RETURN(Qnil); + if (node = eval_case(self, node)) goto again; + break; case NODE_WHILE: - PUSH_TAG(PROT_LOOP); - result = Qnil; - switch (state = EXEC_TAG()) { - case 0: - if (node->nd_state && !RTEST(rb_eval(self, node->nd_cond))) - goto while_out; - do { - while_redo: - rb_eval(self, node->nd_body); - while_next: - ; - } while (RTEST(rb_eval(self, node->nd_cond))); - break; - - case TAG_REDO: - state = 0; - goto while_redo; - case TAG_NEXT: - state = 0; - goto while_next; - case TAG_BREAK: - if (TAG_DST()) { - state = 0; - result = prot_tag->retval; - } - /* fall through */ - default: - break; - } - while_out: - POP_TAG(); - if (state) JUMP_TAG(state); - RETURN(result); + result = eval_while(self,node); + break; case NODE_UNTIL: - PUSH_TAG(PROT_LOOP); - result = Qnil; - switch (state = EXEC_TAG()) { - case 0: - if (node->nd_state && RTEST(rb_eval(self, node->nd_cond))) - goto until_out; - do { - until_redo: - rb_eval(self, node->nd_body); - until_next: - ; - } while (!RTEST(rb_eval(self, node->nd_cond))); - break; - - case TAG_REDO: - state = 0; - goto until_redo; - case TAG_NEXT: - state = 0; - goto until_next; - case TAG_BREAK: - if (TAG_DST()) { - state = 0; - result = prot_tag->retval; - } - /* fall through */ - default: - break; - } - until_out: - POP_TAG(); - if (state) JUMP_TAG(state); - RETURN(result); + result = eval_until(self,node); + break; case NODE_BLOCK_PASS: result = block_pass(self, node); @@ -3217,47 +3970,7 @@ case NODE_ITER: case NODE_FOR: - { - PUSH_TAG(PROT_LOOP); - PUSH_BLOCK(node->nd_var, node->nd_body); - - state = EXEC_TAG(); - if (state == 0) { - iter_retry: - PUSH_ITER(ITER_PRE); - if (nd_type(node) == NODE_ITER) { - result = rb_eval(self, node->nd_iter); - } - else { - VALUE recv; - - _block.flags &= ~BLOCK_D_SCOPE; - BEGIN_CALLARGS; - recv = rb_eval(self, node->nd_iter); - END_CALLARGS; - ruby_current_node = node; - SET_CURRENT_SOURCE(); - result = rb_call(CLASS_OF(recv),recv,each,0,0,0,self); - } - POP_ITER(); - } - else if (state == TAG_BREAK && TAG_DST()) { - result = prot_tag->retval; - state = 0; - } - else if (state == TAG_RETRY) { - state = 0; - goto iter_retry; - } - POP_BLOCK(); - POP_TAG(); - switch (state) { - case 0: - break; - default: - JUMP_TAG(state); - } - } + result = eval_iter(self, node); break; case NODE_BREAK: @@ -3265,17 +3978,14 @@ break; case NODE_NEXT: - CHECK_INTS; next_jump(rb_eval(self, node->nd_stts)); break; case NODE_REDO: - CHECK_INTS; JUMP_TAG(TAG_REDO); break; case NODE_RETRY: - CHECK_INTS; JUMP_TAG(TAG_RETRY); break; @@ -3305,73 +4015,15 @@ break; case NODE_RESCUE: - { - volatile VALUE e_info = ruby_errinfo; - volatile int rescuing = 0; - - PUSH_TAG(PROT_NONE); - if ((state = EXEC_TAG()) == 0) { - retry_entry: - result = rb_eval(self, node->nd_head); - } - else if (rescuing) { - if (rescuing < 0) { - /* in rescue argument, just reraise */ - } - else if (state == TAG_RETRY) { - rescuing = state = 0; - ruby_errinfo = e_info; - goto retry_entry; - } - else if (state != TAG_RAISE) { - result = prot_tag->retval; - } - } - else if (state == TAG_RAISE) { - NODE *resq = node->nd_resq; - - rescuing = -1; - while (resq) { - ruby_current_node = resq; - if (handle_rescue(self, resq)) { - state = 0; - rescuing = 1; - result = rb_eval(self, resq->nd_body); - break; - } - resq = resq->nd_head; /* next rescue */ - } - } - else { - result = prot_tag->retval; - } - POP_TAG(); - if (state != TAG_RAISE) ruby_errinfo = e_info; - if (state) { - JUMP_TAG(state); - } - /* no exception raised */ - if (!rescuing && (node = node->nd_else)) { /* else clause given */ - goto again; - } - } + result = eval_rescue(self,node); + if (result == Qundef) { /* handle else clause w/o recursion */ + node = node->nd_else; + goto again; + } break; case NODE_ENSURE: - PUSH_TAG(PROT_NONE); - if ((state = EXEC_TAG()) == 0) { - result = rb_eval(self, node->nd_head); - } - POP_TAG(); - if (node->nd_ensr && !thread_no_ensure()) { - VALUE retval = prot_tag->retval; /* save retval */ - VALUE errinfo = ruby_errinfo; - - rb_eval(self, node->nd_ensr); - return_value(retval); - ruby_errinfo = errinfo; - } - if (state) JUMP_TAG(state); + result = eval_ensure(self,node); break; case NODE_AND: @@ -3387,56 +4039,20 @@ goto again; case NODE_NOT: - if (RTEST(rb_eval(self, node->nd_body))) result = Qfalse; - else result = Qtrue; + result = RTEST(rb_eval(self, node->nd_body)) ? Qfalse : Qtrue; break; case NODE_DOT2: case NODE_DOT3: - { - VALUE beg = rb_eval(self, node->nd_beg); - VALUE end = rb_eval(self, node->nd_end); - result = rb_range_new(beg, end, nd_type(node) == NODE_DOT3); - } - break; + result = eval_dot(self,node); + break; case NODE_FLIP2: /* like AWK */ - { - VALUE *flip = rb_svar(node->nd_cnt); - if (!flip) rb_bug("unexpected local variable"); - if (!RTEST(*flip)) { - if (RTEST(rb_eval(self, node->nd_beg))) { - *flip = RTEST(rb_eval(self, node->nd_end))?Qfalse:Qtrue; - result = Qtrue; - } - else { - result = Qfalse; - } - } - else { - if (RTEST(rb_eval(self, node->nd_end))) { - *flip = Qfalse; - } - result = Qtrue; - } - } + result = eval_flip2(self,node); break; case NODE_FLIP3: /* like SED */ - { - VALUE *flip = rb_svar(node->nd_cnt); - if (!flip) rb_bug("unexpected local variable"); - if (!RTEST(*flip)) { - result = RTEST(rb_eval(self, node->nd_beg)) ? Qtrue : Qfalse; - *flip = result; - } - else { - if (RTEST(rb_eval(self, node->nd_end))) { - *flip = Qfalse; - } - result = Qtrue; - } - } + result = eval_flip3(self,node); break; case NODE_RETURN: @@ -3444,75 +4060,25 @@ break; case NODE_ARGSCAT: - { - VALUE args = rb_eval(self, node->nd_head); - result = rb_ary_concat(args, splat_value(rb_eval(self, node->nd_body))); - } + result = rb_eval(self, node->nd_head); + result = rb_ary_concat(result, splat_value(rb_eval(self, node->nd_body))); break; case NODE_ARGSPUSH: - { - VALUE args = rb_ary_dup(rb_eval(self, node->nd_head)); - result = rb_ary_push(args, rb_eval(self, node->nd_body)); - } + result = rb_ary_dup(rb_eval(self, node->nd_head)); + result = rb_ary_push(result, rb_eval(self, node->nd_body)); break; case NODE_ATTRASGN: - { - VALUE recv; - int argc; VALUE *argv; /* used in SETUP_ARGS */ - int scope; - TMP_PROTECT; - - BEGIN_CALLARGS; - if (node->nd_recv == (NODE *)1) { - recv = self; - scope = 1; - } - else { - recv = rb_eval(self, node->nd_recv); - scope = 0; - } - SETUP_ARGS(node->nd_args); - END_CALLARGS; - - ruby_current_node = node; - SET_CURRENT_SOURCE(); - rb_call(CLASS_OF(recv),recv,node->nd_mid,argc,argv,scope,self); - result = argv[argc-1]; - } - break; + result = eval_attrasgn(self,node); + break; case NODE_CALL: - { - VALUE recv; - int argc; VALUE *argv; /* used in SETUP_ARGS */ - TMP_PROTECT; - - BEGIN_CALLARGS; - recv = rb_eval(self, node->nd_recv); - SETUP_ARGS(node->nd_args); - END_CALLARGS; - - ruby_current_node = node; - SET_CURRENT_SOURCE(); - result = rb_call(CLASS_OF(recv),recv,node->nd_mid,argc,argv,0,self); - } + result = eval_call(self,node); break; case NODE_FCALL: - { - int argc; VALUE *argv; /* used in SETUP_ARGS */ - TMP_PROTECT; - - BEGIN_CALLARGS; - SETUP_ARGS(node->nd_args); - END_CALLARGS; - - ruby_current_node = node; - SET_CURRENT_SOURCE(); - result = rb_call(CLASS_OF(self),self,node->nd_mid,argc,argv,1,self); - } + result = eval_fcall(self,node); break; case NODE_VCALL: @@ -3522,142 +4088,19 @@ case NODE_SUPER: case NODE_ZSUPER: - { - int argc; VALUE *argv; /* used in SETUP_ARGS */ - TMP_PROTECT; - - if (ruby_frame->last_class == 0) { - if (ruby_frame->last_func) { - rb_name_error(ruby_frame->last_func, - "superclass method `%s' disabled", - rb_id2name(ruby_frame->orig_func)); - } - else { - rb_raise(rb_eNoMethodError, "super called outside of method"); - } - } - if (nd_type(node) == NODE_ZSUPER) { - argc = ruby_frame->argc; - if (argc && DMETHOD_P()) { - if (TYPE(RBASIC(ruby_scope)->klass) != T_ARRAY || - RARRAY(RBASIC(ruby_scope)->klass)->len != argc) { - rb_raise(rb_eRuntimeError, - "super: specify arguments explicitly"); - } - argv = RARRAY(RBASIC(ruby_scope)->klass)->ptr; - } - else if (!ruby_scope->local_vars) { - argc = 0; - argv = 0; - } - else { - argv = ruby_scope->local_vars + 2; - } - } - else { - BEGIN_CALLARGS; - SETUP_ARGS(node->nd_args); - END_CALLARGS; - ruby_current_node = node; - } - - SET_CURRENT_SOURCE(); - result = rb_call_super(argc, argv); - } + result = eval_super(self,node); break; case NODE_SCOPE: - { - struct FRAME frame; - NODE *saved_cref = 0; - - frame = *ruby_frame; - frame.tmp = ruby_frame; - ruby_frame = &frame; - - PUSH_SCOPE(); - PUSH_TAG(PROT_NONE); - if (node->nd_rval) { - saved_cref = ruby_cref; - ruby_cref = (NODE*)node->nd_rval; - } - if (node->nd_tbl) { - VALUE *vars = ALLOCA_N(VALUE, node->nd_tbl[0]+1); - *vars++ = (VALUE)node; - ruby_scope->local_vars = vars; - rb_mem_clear(ruby_scope->local_vars, node->nd_tbl[0]); - ruby_scope->local_tbl = node->nd_tbl; - } - else { - ruby_scope->local_vars = 0; - ruby_scope->local_tbl = 0; - } - if ((state = EXEC_TAG()) == 0) { - result = rb_eval(self, node->nd_next); - } - POP_TAG(); - POP_SCOPE(); - ruby_frame = frame.tmp; - if (saved_cref) - ruby_cref = saved_cref; - if (state) JUMP_TAG(state); - } - break; + result = eval_scope(self,node); + break; case NODE_OP_ASGN1: - { - int argc; VALUE *argv; /* used in SETUP_ARGS */ - VALUE recv, val, tmp; - NODE *rval; - TMP_PROTECT; - - recv = rb_eval(self, node->nd_recv); - rval = node->nd_args->nd_head; - SETUP_ARGS0(node->nd_args->nd_body, 1); - val = rb_funcall3(recv, aref, argc, argv); - switch (node->nd_mid) { - case 0: /* OR */ - if (RTEST(val)) RETURN(val); - val = rb_eval(self, rval); - break; - case 1: /* AND */ - if (!RTEST(val)) RETURN(val); - val = rb_eval(self, rval); - break; - default: - tmp = rb_eval(self, rval); - val = rb_funcall3(val, node->nd_mid, 1, &tmp); - } - argv[argc] = val; - rb_funcall2(recv, aset, argc+1, argv); - result = val; - } + result = eval_op_asgn1(self,node); break; case NODE_OP_ASGN2: - { - ID id = node->nd_next->nd_vid; - VALUE recv, val, tmp; - - recv = rb_eval(self, node->nd_recv); - val = rb_funcall3(recv, id, 0, 0); - switch (node->nd_next->nd_mid) { - case 0: /* OR */ - if (RTEST(val)) RETURN(val); - val = rb_eval(self, node->nd_value); - break; - case 1: /* AND */ - if (!RTEST(val)) RETURN(val); - val = rb_eval(self, node->nd_value); - break; - default: - tmp = rb_eval(self, node->nd_value); - val = rb_funcall3(val, node->nd_next->nd_mid, 1, &tmp); - } - - rb_funcall2(recv, node->nd_next->nd_aid, 1, &val); - result = val; - } + result = eval_op_asgn2(self,node); break; case NODE_OP_ASGN_AND: @@ -3706,26 +4149,21 @@ break; case NODE_CDECL: - result = rb_eval(self, node->nd_value); - if (node->nd_vid == 0) { - rb_const_set(class_prefix(self, node->nd_else), node->nd_else->nd_mid, result); - } - else { - rb_const_set(ruby_cbase, node->nd_vid, result); - } + result = rb_eval(self, node->nd_value); + eval_cdecl(self, node, result); break; case NODE_CVDECL: if (NIL_P(ruby_cbase)) { rb_raise(rb_eTypeError, "no class/module to define class variable"); } - result = rb_eval(self, node->nd_value); - rb_cvar_set(cvar_cbase(), node->nd_vid, result, Qtrue); + result = rb_eval(self, node->nd_value); + eval_cvar_set(result, node, Qtrue); break; case NODE_CVASGN: - result = rb_eval(self, node->nd_value); - rb_cvar_set(cvar_cbase(), node->nd_vid, result, Qfalse); + result = rb_eval(self, node->nd_value); + eval_cvar_set(result, node, Qfalse); break; case NODE_LVAR: @@ -3768,26 +4206,21 @@ break; case NODE_COLON2: - { - VALUE klass; - - klass = rb_eval(self, node->nd_head); - if (rb_is_const_id(node->nd_mid)) { - switch (TYPE(klass)) { - case T_CLASS: - case T_MODULE: - result = rb_const_get_from(klass, node->nd_mid); - break; - default: - rb_raise(rb_eTypeError, "%s is not a class/module", - RSTRING(rb_obj_as_string(klass))->ptr); - break; - } - } - else { - result = rb_funcall(klass, node->nd_mid, 0, 0); + result = rb_eval(self, node->nd_head); + if (rb_is_const_id(node->nd_mid)) { + switch (TYPE(result)) { + case T_CLASS: + case T_MODULE: + result = rb_const_get_from(result, node->nd_mid); + break; + default: + rb_raise(rb_eTypeError, "%s is not a class/module", + RSTRING(rb_obj_as_string(result))->ptr); + break; } } + else + result = rb_funcall(result, node->nd_mid, 0, 0); break; case NODE_COLON3: @@ -3818,23 +4251,7 @@ break; case NODE_HASH: - { - NODE *list; - VALUE hash = rb_hash_new(); - VALUE key, val; - - list = node->nd_head; - while (list) { - key = rb_eval(self, list->nd_head); - list = list->nd_next; - if (list == 0) - rb_bug("odd number list for Hash"); - val = rb_eval(self, list->nd_head); - list = list->nd_next; - rb_hash_aset(hash, key, val); - } - result = hash; - } + result = eval_hash(self,node); break; case NODE_ZARRAY: /* zero length list */ @@ -3842,19 +4259,7 @@ break; case NODE_ARRAY: - { - VALUE ary; - long i; - - i = node->nd_alen; - ary = rb_ary_new2(i); - for (i=0;node;node=node->nd_next) { - RARRAY(ary)->ptr[i++] = rb_eval(self, node->nd_head); - RARRAY(ary)->len = i; - } - - result = ary; - } + result = eval_array(self,node); break; case NODE_STR: @@ -3870,51 +4275,8 @@ case NODE_DREGX: case NODE_DREGX_ONCE: case NODE_DSYM: - { - VALUE str, str2; - NODE *list = node->nd_next; - - str = rb_str_new3(node->nd_lit); - while (list) { - if (list->nd_head) { - switch (nd_type(list->nd_head)) { - case NODE_STR: - str2 = list->nd_head->nd_lit; - break; - default: - str2 = rb_eval(self, list->nd_head); - break; - } - rb_str_append(str, str2); - OBJ_INFECT(str, str2); - } - list = list->nd_next; - } - switch (nd_type(node)) { - case NODE_DREGX: - result = rb_reg_new(RSTRING(str)->ptr, RSTRING(str)->len, - node->nd_cflag); - break; - case NODE_DREGX_ONCE: /* regexp expand once */ - result = rb_reg_new(RSTRING(str)->ptr, RSTRING(str)->len, - node->nd_cflag); - nd_set_type(node, NODE_LIT); - node->nd_lit = result; - break; - case NODE_LIT: - /* other thread may replace NODE_DREGX_ONCE to NODE_LIT */ - goto again; - case NODE_DXSTR: - result = rb_funcall(self, '`', 1, str); - break; - case NODE_DSYM: - result = rb_str_intern(str); - break; - default: - result = str; - break; - } - } + result = eval_slit(self, node); + if (result == Qundef) goto again; break; case NODE_XSTR: @@ -3926,84 +4288,13 @@ break; case NODE_DEFN: - if (node->nd_defn) { - NODE *body, *defn; - VALUE origin = 0; - int noex; - - if (NIL_P(ruby_class)) { - rb_raise(rb_eTypeError, "no class/module to add method"); - } - if (ruby_class == rb_cObject && node->nd_mid == init) { - rb_warn("redefining Object#initialize may cause infinite loop"); - } - if (node->nd_mid == __id__ || node->nd_mid == __send__) { - rb_warn("redefining `%s' may cause serious problem", - rb_id2name(node->nd_mid)); - } - rb_frozen_class_p(ruby_class); - body = search_method(ruby_class, node->nd_mid, &origin); - if (body){ - if (RTEST(ruby_verbose) && ruby_class == origin && body->nd_cnt == 0 && body->nd_body) { - rb_warning("method redefined; discarding old %s", rb_id2name(node->nd_mid)); - } - } - - if (SCOPE_TEST(SCOPE_PRIVATE) || node->nd_mid == init) { - noex = NOEX_PRIVATE; - } - else if (SCOPE_TEST(SCOPE_PROTECTED)) { - noex = NOEX_PROTECTED; - } - else { - noex = NOEX_PUBLIC; - } - if (body && origin == ruby_class && body->nd_body == 0) { - noex |= NOEX_NOSUPER; - } - - defn = rb_copy_node_scope(node->nd_defn, ruby_cref); - rb_add_method(ruby_class, node->nd_mid, defn, noex); - if (scope_vmode == SCOPE_MODFUNC) { - rb_add_method(rb_singleton_class(ruby_class), - node->nd_mid, defn, NOEX_PUBLIC); - } - result = Qnil; - } + if (node->nd_defn) + eval_defn(self,node); break; case NODE_DEFS: - if (node->nd_defn) { - VALUE recv = rb_eval(self, node->nd_recv); - VALUE klass; - NODE *body = 0, *defn; - - if (ruby_safe_level >= 4 && !OBJ_TAINTED(recv)) { - rb_raise(rb_eSecurityError, "Insecure: can't define singleton method"); - } - if (FIXNUM_P(recv) || SYMBOL_P(recv)) { - rb_raise(rb_eTypeError, - "can't define singleton method \"%s\" for %s", - rb_id2name(node->nd_mid), - rb_obj_classname(recv)); - } - - if (OBJ_FROZEN(recv)) rb_error_frozen("object"); - klass = rb_singleton_class(recv); - if (st_lookup(RCLASS(klass)->m_tbl, node->nd_mid, &data)) { - body = (NODE *)data; - if (ruby_safe_level >= 4) { - rb_raise(rb_eSecurityError, "redefining method prohibited"); - } - if (RTEST(ruby_verbose)) { - rb_warning("redefine %s", rb_id2name(node->nd_mid)); - } - } - defn = rb_copy_node_scope(node->nd_defn, ruby_cref); - rb_add_method(klass, node->nd_mid, defn, - NOEX_PUBLIC|(body?body->nd_noex&NOEX_UNDEF:0)); - result = Qnil; - } + if (node->nd_defn) + eval_defs(self,node); break; case NODE_UNDEF: @@ -4011,7 +4302,6 @@ rb_raise(rb_eTypeError, "no class to undef method"); } rb_undef(ruby_class, rb_to_id(rb_eval(self, node->u2.node))); - result = Qnil; break; case NODE_ALIAS: @@ -4020,134 +4310,26 @@ } rb_alias(ruby_class, rb_to_id(rb_eval(self, node->u1.node)), rb_to_id(rb_eval(self, node->u2.node))); - result = Qnil; break; case NODE_VALIAS: rb_alias_variable(node->u1.id, node->u2.id); - result = Qnil; break; case NODE_CLASS: - { - VALUE super, klass, tmp, cbase; - ID cname; - int gen = Qfalse; - - cbase = class_prefix(self, node->nd_cpath); - cname = node->nd_cpath->nd_mid; - - if (NIL_P(ruby_cbase)) { - rb_raise(rb_eTypeError, "no outer class/module"); - } - if (node->nd_super) { - super = rb_eval(self, node->nd_super); - rb_check_inheritable(super); - } - else { - super = 0; - } - - if (rb_const_defined_at(cbase, cname)) { - klass = rb_const_get_at(cbase, cname); - if (TYPE(klass) != T_CLASS) { - rb_raise(rb_eTypeError, "%s is not a class", - rb_id2name(cname)); - } - if (super) { - tmp = rb_class_real(RCLASS(klass)->super); - if (tmp != super) { - rb_raise(rb_eTypeError, "superclass mismatch for class %s", - rb_id2name(cname)); - } - super = 0; - } - if (ruby_safe_level >= 4) { - rb_raise(rb_eSecurityError, "extending class prohibited"); - } - } - else { - if (!super) super = rb_cObject; - klass = rb_define_class_id(cname, super); - rb_set_class_path(klass, cbase, rb_id2name(cname)); - rb_const_set(cbase, cname, klass); - gen = Qtrue; - } - if (ruby_wrapper) { - rb_extend_object(klass, ruby_wrapper); - rb_include_module(klass, ruby_wrapper); - } - if (super && gen) { - rb_class_inherited(super, klass); - } - result = module_setup(klass, node); - } + result = eval_class(self,node); break; case NODE_MODULE: - { - VALUE module, cbase; - ID cname; - - if (NIL_P(ruby_cbase)) { - rb_raise(rb_eTypeError, "no outer class/module"); - } - cbase = class_prefix(self, node->nd_cpath); - cname = node->nd_cpath->nd_mid; - if (rb_const_defined_at(cbase, cname)) { - module = rb_const_get_at(cbase, cname); - if (TYPE(module) != T_MODULE) { - rb_raise(rb_eTypeError, "%s is not a module", - rb_id2name(cname)); - } - if (ruby_safe_level >= 4) { - rb_raise(rb_eSecurityError, "extending module prohibited"); - } - } - else { - module = rb_define_module_id(cname); - rb_set_class_path(module, cbase, rb_id2name(cname)); - rb_const_set(cbase, cname, module); - } - if (ruby_wrapper) { - rb_extend_object(module, ruby_wrapper); - rb_include_module(module, ruby_wrapper); - } - - result = module_setup(module, node); - } + result = eval_module(self,node); break; case NODE_SCLASS: - { - VALUE klass; - - result = rb_eval(self, node->nd_recv); - if (FIXNUM_P(result) || SYMBOL_P(result)) { - rb_raise(rb_eTypeError, "no virtual class for %s", - rb_obj_classname(result)); - } - if (ruby_safe_level >= 4 && !OBJ_TAINTED(result)) - rb_raise(rb_eSecurityError, "Insecure: can't extend object"); - klass = rb_singleton_class(result); - - if (ruby_wrapper) { - rb_extend_object(klass, ruby_wrapper); - rb_include_module(klass, ruby_wrapper); - } - - result = module_setup(klass, node); - } + result = eval_sclass(self,node); break; case NODE_DEFINED: - { - char buf[20]; - const char *desc = is_defined(self, node->nd_head, buf); - - if (desc) result = rb_str_new2(desc); - else result = Qnil; - } + result = eval_defined(self,node); break; case NODE_NEWLINE: @@ -4160,14 +4342,8 @@ default: unknown_node(node); } - finish: - CHECK_INTS; - if (contnode) { - node = contnode; - contnode = 0; - goto again; - } - return result; + } + return result; } static VALUE @@ -13081,6 +13257,32 @@ VALUE rb_cCont; + +static rb_thread_t prep4callcc(void) +{ + rb_thread_t th; + struct tag *tag; + struct RVarmap *vars; + + THREAD_ALLOC(th); + /* must finish th initialization before any possible gc */ + th->thread = curr_thread->thread; /* brent@mbari.org */ + th->thgroup = cont_protect; + + scope_dup(ruby_scope); + for (tag=prot_tag; tag; tag=tag->prev) { + if (tag->tag == PROT_THREAD) break; + scope_dup(tag->scope); + } + + for (vars = ruby_dyna_vars; vars; vars = vars->next) { + if (FL_TEST(vars, DVAR_DONT_RECYCLE)) break; + FL_SET(vars, DVAR_DONT_RECYCLE); + } + return th; +} + + /* * call-seq: * callcc {|cont| block } => obj @@ -13099,37 +13301,14 @@ rb_callcc(self) VALUE self; { - volatile VALUE cont; - rb_thread_t th; - volatile rb_thread_t th_save; - struct tag *tag; - struct RVarmap *vars; - - THREAD_ALLOC(th); - /* must finish th initialization before any possible gc */ - th->thread = curr_thread->thread; /* brent@mbari.org */ - th->thgroup = cont_protect; - cont = Data_Wrap_Struct(rb_cCont, cc_mark, thread_free, th); - - scope_dup(ruby_scope); - for (tag=prot_tag; tag; tag=tag->prev) { - if (tag->tag == PROT_THREAD) break; - scope_dup(tag->scope); - } - - for (vars = ruby_dyna_vars; vars; vars = vars->next) { - if (FL_TEST(vars, DVAR_DONT_RECYCLE)) break; - FL_SET(vars, DVAR_DONT_RECYCLE); - } - th_save = th; - if (THREAD_SAVE_CONTEXT(th)) { - return th_save->result; - } - else { - return rb_yield(cont); - } + rb_thread_t th = prep4callcc(); + return THREAD_SAVE_CONTEXT(th) ? + th->result + : + rb_yield(Data_Wrap_Struct(rb_cCont, cc_mark, thread_free, th)); } + /* * call-seq: * cont.call(args, ...) diff -rux '*.o' ruby-1.8.7-p72/version.h ruby-1.8.7-mbari/version.h --- ruby-1.8.7-p72/version.h 2008-12-16 00:47:26.000000000 -0800 +++ ruby-1.8.7-mbari/version.h 2008-12-16 20:02:42.000000000 -0800 @@ -1,7 +1,7 @@ #define RUBY_VERSION "1.8.7" -#define RUBY_RELEASE_DATE "2008-12-13" +#define RUBY_RELEASE_DATE "2008-12-16" #define RUBY_VERSION_CODE 187 -#define RUBY_RELEASE_CODE 20081213 +#define RUBY_RELEASE_CODE 20081216 #define RUBY_PATCHLEVEL 72 #define RUBY_VERSION_MAJOR 1 @@ -9,7 +9,7 @@ #define RUBY_VERSION_TEENY 7 #define RUBY_RELEASE_YEAR 2008 #define RUBY_RELEASE_MONTH 12 -#define RUBY_RELEASE_DAY 13 +#define RUBY_RELEASE_DAY 16 #ifdef RUBY_EXTERN RUBY_EXTERN const char ruby_version[]; @@ -25,7 +25,7 @@ #define RUBY_BIRTH_MONTH 2 #define RUBY_BIRTH_DAY 24 -#define RUBY_RELEASE_STR "MBARI 3 on patchlevel" +#define RUBY_RELEASE_STR "MBARI 4 on patchlevel" #define RUBY_RELEASE_NUM RUBY_PATCHLEVEL
Copyright ©2021 || Defacer Indonesia