mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* 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(). git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@13331 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
2c8e7a50c1
commit
49be22d8df
5 changed files with 62 additions and 18 deletions
18
ChangeLog
18
ChangeLog
|
@ -46,6 +46,24 @@ Sat Sep 1 14:24:23 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
* include/ruby/st.h (rb_index_t): use st_data_t for the platforms it
|
* include/ruby/st.h (rb_index_t): use st_data_t for the platforms it
|
||||||
is larger than int.
|
is larger than int.
|
||||||
|
|
||||||
|
Sat Sep 1 10:43:30 2007 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
|
* 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@ruby-lang.org>
|
Fri Aug 31 07:12:24 2007 NAKAMURA Usaku <usa@ruby-lang.org>
|
||||||
|
|
||||||
* numeric.c (SQRT_LONG_MAX): use SIZEOF_LONG instead of SIZEOF_VALUE
|
* numeric.c (SQRT_LONG_MAX): use SIZEOF_LONG instead of SIZEOF_VALUE
|
||||||
|
|
|
@ -230,3 +230,10 @@ assert_equal %q{1}, %q{
|
||||||
|
|
||||||
m
|
m
|
||||||
}
|
}
|
||||||
|
assert_equal 'ok', %q{
|
||||||
|
begin
|
||||||
|
catch {|t| throw t, :ok }
|
||||||
|
rescue ArgumentError
|
||||||
|
:ng
|
||||||
|
end
|
||||||
|
}, '[ruby-dev:31609]'
|
||||||
|
|
|
@ -3,11 +3,3 @@
|
||||||
# So all tests will cause failure.
|
# 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]'
|
|
||||||
|
|
44
eval_jump.ci
44
eval_jump.ci
|
@ -27,8 +27,6 @@ rb_f_throw(int argc, VALUE *argv)
|
||||||
struct rb_vm_tag *tt = th->tag;
|
struct rb_vm_tag *tt = th->tag;
|
||||||
|
|
||||||
rb_scan_args(argc, argv, "11", &tag, &value);
|
rb_scan_args(argc, argv, "11", &tag, &value);
|
||||||
tag = ID2SYM(rb_to_id(tag));
|
|
||||||
|
|
||||||
while (tt) {
|
while (tt) {
|
||||||
if (tt->tag == tag) {
|
if (tt->tag == tag) {
|
||||||
tt->retval = value;
|
tt->retval = value;
|
||||||
|
@ -37,8 +35,8 @@ rb_f_throw(int argc, VALUE *argv)
|
||||||
tt = tt->prev;
|
tt = tt->prev;
|
||||||
}
|
}
|
||||||
if (!tt) {
|
if (!tt) {
|
||||||
rb_name_error(SYM2ID(tag), "uncaught throw `%s'",
|
VALUE desc = rb_inspect(tag);
|
||||||
rb_id2name(SYM2ID(tag)));
|
rb_raise(rb_eArgError, "uncaught throw %s", RSTRING_PTR(desc));
|
||||||
}
|
}
|
||||||
rb_trap_restore_mask();
|
rb_trap_restore_mask();
|
||||||
th->errinfo = tag;
|
th->errinfo = tag;
|
||||||
|
@ -59,6 +57,16 @@ rb_throw(const char *tag, VALUE val)
|
||||||
rb_f_throw(2, argv);
|
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:
|
* call-seq:
|
||||||
* catch(symbol) {| | block } > obj
|
* catch(symbol) {| | block } > obj
|
||||||
|
@ -91,13 +99,17 @@ rb_throw(const char *tag, VALUE val)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
rb_f_catch(VALUE dmy, VALUE tag)
|
rb_f_catch(int argc, VALUE *argv)
|
||||||
{
|
{
|
||||||
|
VALUE tag;
|
||||||
int state;
|
int state;
|
||||||
VALUE val = Qnil; /* OK */
|
VALUE val = Qnil; /* OK */
|
||||||
rb_thread_t *th = GET_THREAD();
|
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();
|
PUSH_TAG();
|
||||||
|
|
||||||
th->tag->tag = tag;
|
th->tag->tag = tag;
|
||||||
|
@ -117,6 +129,12 @@ rb_f_catch(VALUE dmy, VALUE tag)
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
catch_null_i(VALUE dmy)
|
||||||
|
{
|
||||||
|
return rb_funcall(Qnil, rb_intern("catch"), 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
catch_i(VALUE tag)
|
catch_i(VALUE tag)
|
||||||
{
|
{
|
||||||
|
@ -126,8 +144,16 @@ catch_i(VALUE tag)
|
||||||
VALUE
|
VALUE
|
||||||
rb_catch(const char *tag, VALUE (*func)(), VALUE data)
|
rb_catch(const char *tag, VALUE (*func)(), VALUE data)
|
||||||
{
|
{
|
||||||
return rb_iterate((VALUE (*)_((VALUE)))catch_i, ID2SYM(rb_intern(tag)),
|
if (!tag) {
|
||||||
func, data);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -276,7 +302,7 @@ rb_exec_end_proc(void)
|
||||||
void
|
void
|
||||||
Init_jump(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("throw", rb_f_throw, -1);
|
||||||
rb_define_global_function("at_exit", rb_f_at_exit, 0);
|
rb_define_global_function("at_exit", rb_f_at_exit, 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1166,7 +1166,8 @@ check_autoload_table(VALUE av)
|
||||||
Check_Type(av, T_DATA);
|
Check_Type(av, T_DATA);
|
||||||
if (RDATA(av)->dmark != (RUBY_DATA_FUNC)rb_mark_tbl ||
|
if (RDATA(av)->dmark != (RUBY_DATA_FUNC)rb_mark_tbl ||
|
||||||
RDATA(av)->dfree != (RUBY_DATA_FUNC)st_free_table) {
|
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);
|
return (struct st_table *)DATA_PTR(av);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue