summaryrefslogtreecommitdiff
path: root/eval.c
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-10-29 04:55:10 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-10-29 04:55:10 +0000
commit0580ba06110f7998fdaead724907a4c8d6540107 (patch)
tree4ceed7d1642d46a147114fc1a303ce5257af49bb /eval.c
parent2bb26c118d9e52a52940f73c9cb1fc26e07003d6 (diff)
* 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.c60
1 files changed, 51 insertions, 9 deletions
diff --git a/eval.c b/eval.c
index 5133181c4b..dec628204a 100644
--- a/eval.c
+++ b/eval.c
@@ -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)
{