diff options
Diffstat (limited to 'eval.c')
-rw-r--r-- | eval.c | 69 |
1 files changed, 57 insertions, 12 deletions
@@ -1079,7 +1079,9 @@ get_backtrace(info) VALUE info; { if (NIL_P(info)) return Qnil; - return rb_check_array_type(rb_funcall(info, rb_intern("backtrace"), 0)); + info = rb_funcall(info, rb_intern("backtrace"), 0); + if (NIL_P(info)) return Qnil; + return rb_check_array_type(info); } static void @@ -5799,18 +5801,13 @@ rb_f_send(argc, argv, recv) return vid; } -VALUE -#ifdef HAVE_STDARG_PROTOTYPES -rb_funcall(VALUE recv, ID mid, int n, ...) -#else -rb_funcall(recv, mid, n, va_alist) +static VALUE +vafuncall(recv, mid, n, ar) VALUE recv; ID mid; int n; - va_dcl -#endif + va_list *ar; { - va_list ar; VALUE *argv; if (n > 0) { @@ -5818,11 +5815,10 @@ rb_funcall(recv, mid, n, va_alist) argv = ALLOCA_N(VALUE, n); - va_init_list(ar, n); for (i=0;i<n;i++) { - argv[i] = va_arg(ar, VALUE); + argv[i] = va_arg(*ar, VALUE); } - va_end(ar); + va_end(*ar); } else { argv = 0; @@ -5832,6 +5828,55 @@ rb_funcall(recv, mid, n, va_alist) } VALUE +#ifdef HAVE_STDARG_PROTOTYPES +rb_funcall(VALUE recv, ID mid, int n, ...) +#else +rb_funcall(recv, mid, n, va_alist) + VALUE recv; + ID mid; + int n; + va_dcl +#endif +{ + va_list ar; + va_init_list(ar, n); + + return vafuncall(recv, mid, n, &ar); +} + +VALUE +#ifdef HAVE_STDARG_PROTOTYPES +rb_funcall_rescue(VALUE recv, ID mid, int n, ...) +#else +rb_funcall_rescue(recv, mid, n, va_alist) + VALUE recv; + ID mid; + int n; + va_dcl +#endif +{ + VALUE result = Qnil; /* OK */ + int status; + va_list ar; + + va_init_list(ar, n); + + PUSH_TAG(PROT_NONE); + if ((status = EXEC_TAG()) == 0) { + result = vafuncall(recv, mid, n, &ar); + } + POP_TAG(); + switch (status) { + case 0: + return result; + case TAG_RAISE: + return Qundef; + default: + JUMP_TAG(status); + } +} + +VALUE rb_funcall2(recv, mid, argc, argv) VALUE recv; ID mid; |