ruby-changes:1840
From: ko1@a...
Date: 1 Sep 2007 21:56:39 +0900
Subject: [ruby-changes:1840] matz - Ruby:r13331 (trunk): * eval_jump.ci (rb_f_catch): generate new tag object if no argument is
matz 2007-09-01 21:56:29 +0900 (Sat, 01 Sep 2007) New Revision: 13331 Modified files: trunk/ChangeLog trunk/bootstraptest/test_jump.rb trunk/bootstraptest/test_knownbug.rb trunk/eval_jump.ci trunk/variable.c Log: * eval_jump.ci (rb_f_catch): generate new tag object if no argument is given. backported from MatzRuby. [ruby-dev:31609] * eval_jump.ci (rb_catch): call #catch without arguments if tag string is NULL. * eval_jump.ci (rb_f_throw): allow throwing non-symbol object. * eval.c (rb_catch_obj): new function to wait throw with arbitrary object. * eval.c (rb_throw_obj): new function to throw arbitrary object. * variable.c (check_autoload_table): prevent multiple calls from RSTRING_PTR(). http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/variable.c?r1=13331&r2=13330 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/bootstraptest/test_jump.rb?r1=13331&r2=13330 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/ChangeLog?r1=13331&r2=13330 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/eval_jump.ci?r1=13331&r2=13330 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/bootstraptest/test_knownbug.rb?r1=13331&r2=13330 Index: ChangeLog =================================================================== --- ChangeLog (revision 13330) +++ ChangeLog (revision 13331) @@ -46,6 +46,24 @@ * include/ruby/st.h (rb_index_t): use st_data_t for the platforms it is larger than int. +Sat Sep 1 10:43:30 2007 Yukihiro Matsumoto <matz@r...> + + * eval_jump.ci (rb_f_catch): generate new tag object if no argument is + given. backported from MatzRuby. [ruby-dev:31609] + + * eval_jump.ci (rb_catch): call #catch without arguments if tag + string is NULL. + + * eval_jump.ci (rb_f_throw): allow throwing non-symbol object. + + * eval.c (rb_catch_obj): new function to wait throw with arbitrary + object. + + * eval.c (rb_throw_obj): new function to throw arbitrary object. + + * variable.c (check_autoload_table): prevent multiple calls from + RSTRING_PTR(). + Fri Aug 31 07:12:24 2007 NAKAMURA Usaku <usa@r...> * numeric.c (SQRT_LONG_MAX): use SIZEOF_LONG instead of SIZEOF_VALUE Index: variable.c =================================================================== --- variable.c (revision 13330) +++ variable.c (revision 13331) @@ -1166,7 +1166,8 @@ Check_Type(av, T_DATA); if (RDATA(av)->dmark != (RUBY_DATA_FUNC)rb_mark_tbl || RDATA(av)->dfree != (RUBY_DATA_FUNC)st_free_table) { - rb_raise(rb_eTypeError, "wrong autoload table: %s", RSTRING_PTR(rb_inspect(av))); + VALUE desc = rb_inspect(av); + rb_raise(rb_eTypeError, "wrong autoload table: %s", RSTRING_PTR(desc)); } return (struct st_table *)DATA_PTR(av); } Index: bootstraptest/test_knownbug.rb =================================================================== --- bootstraptest/test_knownbug.rb (revision 13330) +++ bootstraptest/test_knownbug.rb (revision 13331) @@ -3,11 +3,3 @@ # So all tests will cause failure. # -# catch/throw -assert_equal 'ok', %q{ - begin - catch {|t| throw t, :ok } - rescue ArgumentError - :ng - end -}, '[ruby-dev:31609]' Index: bootstraptest/test_jump.rb =================================================================== --- bootstraptest/test_jump.rb (revision 13330) +++ bootstraptest/test_jump.rb (revision 13331) @@ -230,3 +230,10 @@ m } +assert_equal 'ok', %q{ + begin + catch {|t| throw t, :ok } + rescue ArgumentError + :ng + end +}, '[ruby-dev:31609]' Index: eval_jump.ci =================================================================== --- eval_jump.ci (revision 13330) +++ eval_jump.ci (revision 13331) @@ -27,8 +27,6 @@ struct rb_vm_tag *tt = th->tag; rb_scan_args(argc, argv, "11", &tag, &value); - tag = ID2SYM(rb_to_id(tag)); - while (tt) { if (tt->tag == tag) { tt->retval = value; @@ -37,8 +35,8 @@ tt = tt->prev; } if (!tt) { - rb_name_error(SYM2ID(tag), "uncaught throw `%s'", - rb_id2name(SYM2ID(tag))); + VALUE desc = rb_inspect(tag); + rb_raise(rb_eArgError, "uncaught throw %s", RSTRING_PTR(desc)); } rb_trap_restore_mask(); th->errinfo = tag; @@ -59,6 +57,16 @@ rb_f_throw(2, argv); } +void +rb_throw_obj(VALUE tag, VALUE val) +{ + VALUE argv[2]; + + argv[0] = tag; + argv[1] = val; + rb_f_throw(2, argv); +} + /* * call-seq: * catch(symbol) {| | block } > obj @@ -91,13 +99,17 @@ */ static VALUE -rb_f_catch(VALUE dmy, VALUE tag) +rb_f_catch(int argc, VALUE *argv) { + VALUE tag; int state; VALUE val = Qnil; /* OK */ rb_thread_t *th = GET_THREAD(); - tag = ID2SYM(rb_to_id(tag)); + rb_scan_args(argc, argv, "01", &tag); + if (argc == 0) { + tag = rb_obj_alloc(rb_cObject); + } PUSH_TAG(); th->tag->tag = tag; @@ -118,6 +130,12 @@ } static VALUE +catch_null_i(VALUE dmy) +{ + return rb_funcall(Qnil, rb_intern("catch"), 0, 0); +} + +static VALUE catch_i(VALUE tag) { return rb_funcall(Qnil, rb_intern("catch"), 1, tag); @@ -126,11 +144,19 @@ VALUE rb_catch(const char *tag, VALUE (*func)(), VALUE data) { - return rb_iterate((VALUE (*)_((VALUE)))catch_i, ID2SYM(rb_intern(tag)), - func, data); + if (!tag) { + return rb_iterate(catch_null_i, 0, func, data); + } + return rb_iterate(catch_i, ID2SYM(rb_intern(tag)), func, data); } +VALUE +rb_catch_obj(VALUE tag, VALUE (*func)(), VALUE data) +{ + return rb_iterate((VALUE (*)_((VALUE)))catch_i, tag, func, data); +} + /* exit */ static void call_end_proc _((VALUE data)); @@ -276,7 +302,7 @@ void Init_jump(void) { - rb_define_global_function("catch", rb_f_catch, 1); + rb_define_global_function("catch", rb_f_catch, -1); rb_define_global_function("throw", rb_f_throw, -1); rb_define_global_function("at_exit", rb_f_at_exit, 0); } -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml