diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2009-10-29 04:55:10 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2009-10-29 04:55:10 +0000 |
commit | 0580ba06110f7998fdaead724907a4c8d6540107 (patch) | |
tree | 4ceed7d1642d46a147114fc1a303ce5257af49bb /eval.c | |
parent | 2bb26c118d9e52a52940f73c9cb1fc26e07003d6 (diff) | |
download | ruby-0580ba06110f7998fdaead724907a4c8d6540107.tar.gz |
* array.c (rb_ary_to_ary): do not use #respond_to? to detect
to_ary. Just call. [ruby-core:23738]
* eval.c (rb_check_funcall): new function with method existence
check. returns Qundef when the method does not exist.
* enumerator.c (enumerator_rewind): just call method, using
rb_check_funcall(). [ruby-core:23738]
* error.c (exc_equal): ditto.
* object.c (convert_type): ditto.
* error.c (rb_name_err_mesg_new): export function.
* eval.c (make_exception): ditto.
* io.c (pop_last_hash): return early when the last argument is nil.
* io.c (rb_io_puts): treat T_STRING specially for small
optimization.
* vm_eval.c (raise_method_missing): skip method call if possible
using rb_method_basic_definition_p().
* vm_eval.c (method_missing): ditto.
* test/ruby/test_rubyoptions.rb (TestRubyOptions#test_debug): test
suites changed to ignore exceptions caused by just-call policy.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@25556 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'eval.c')
-rw-r--r-- | eval.c | 60 |
1 files changed, 51 insertions, 9 deletions
@@ -425,11 +425,13 @@ rb_longjmp(int tag, volatile VALUE mesg) JUMP_TAG(tag); } +static VALUE make_exception(int argc, VALUE *argv, int isstr); + void rb_exc_raise(VALUE mesg) { if (!NIL_P(mesg)) { - mesg = rb_make_exception(1, &mesg); + mesg = make_exception(1, &mesg, Qfalse); } rb_longjmp(TAG_RAISE, mesg); } @@ -438,7 +440,7 @@ void rb_exc_fatal(VALUE mesg) { if (!NIL_P(mesg)) { - mesg = rb_make_exception(1, &mesg); + mesg = make_exception(1, &mesg, Qfalse); } rb_longjmp(TAG_FATAL, mesg); } @@ -490,8 +492,40 @@ rb_f_raise(int argc, VALUE *argv) return Qnil; /* not reached */ } +struct rescue_funcall_args { + VALUE obj; + ID id; + int argc; + VALUE *argv; +}; + +static VALUE +check_funcall(struct rescue_funcall_args *args) +{ + return rb_funcall2(args->obj, args->id, args->argc, args->argv); +} + +static VALUE +check_failed(VALUE data) +{ + return data; +} + VALUE -rb_make_exception(int argc, VALUE *argv) +rb_check_funcall(VALUE obj, ID id, int argc, VALUE *argv) +{ + struct rescue_funcall_args args; + + args.obj = obj; + args.id = id; + args.argc = argc; + args.argv = argv; + return rb_rescue2(check_funcall, (VALUE)&args, check_failed, Qundef, + rb_eNoMethodError, (VALUE)0); +} + +static VALUE +make_exception(int argc, VALUE *argv, int isstr) { VALUE mesg; ID exception; @@ -504,10 +538,12 @@ rb_make_exception(int argc, VALUE *argv) case 1: if (NIL_P(argv[0])) break; - mesg = rb_check_string_type(argv[0]); - if (!NIL_P(mesg)) { - mesg = rb_exc_new3(rb_eRuntimeError, mesg); - break; + if (isstr) { + mesg = rb_check_string_type(argv[0]); + if (!NIL_P(mesg)) { + mesg = rb_exc_new3(rb_eRuntimeError, mesg); + break; + } } n = 0; goto exception_call; @@ -517,10 +553,10 @@ rb_make_exception(int argc, VALUE *argv) n = 1; exception_call: CONST_ID(exception, "exception"); - if (!rb_respond_to(argv[0], exception)) { + mesg = rb_check_funcall(argv[0], exception, n, argv+1); + if (mesg == Qundef) { rb_raise(rb_eTypeError, "exception class/object expected"); } - mesg = rb_funcall(argv[0], exception, n, argv[1]); break; default: rb_raise(rb_eArgError, "wrong number of arguments"); @@ -536,6 +572,12 @@ rb_make_exception(int argc, VALUE *argv) return mesg; } +VALUE +rb_make_exception(int argc, VALUE *argv) +{ + return make_exception(argc, argv, Qtrue); +} + void rb_raise_jump(VALUE mesg) { |