diff options
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | class.c | 8 | ||||
-rw-r--r-- | error.c | 56 | ||||
-rw-r--r-- | internal.h | 6 | ||||
-rw-r--r-- | vm.c | 4 |
5 files changed, 54 insertions, 24 deletions
@@ -1,3 +1,7 @@ +Sat Jul 23 22:43:41 2016 Nobuyoshi Nakada <nobu@ruby-lang.org> + + * internal.h (Check_Type): inline check for the object type. + Sat Jul 23 04:06:04 2016 Nobuyoshi Nakada <nobu@ruby-lang.org> * include/ruby/ruby.h (RTEST, NIL_P): use RUBY prefixed name in @@ -855,11 +855,7 @@ rb_include_module(VALUE klass, VALUE module) int changed = 0; rb_frozen_class_p(klass); - - if (!RB_TYPE_P(module, T_MODULE)) { - Check_Type(module, T_MODULE); - } - + Check_Type(module, T_MODULE); OBJ_INFECT(klass, module); changed = include_modules_at(klass, RCLASS_ORIGIN(klass), module, TRUE); @@ -971,9 +967,7 @@ rb_prepend_module(VALUE klass, VALUE module) int changed = 0; rb_frozen_class_p(klass); - Check_Type(module, T_MODULE); - OBJ_INFECT(klass, module); origin = RCLASS_ORIGIN(klass); @@ -553,32 +553,58 @@ rb_builtin_class_name(VALUE x) return etype; } +NORETURN(static void unexpected_type(VALUE, int, int)); +#define UNDEF_LEAKED "undef leaked to the Ruby space" + +static void +unexpected_type(VALUE x, int xt, int t) +{ + const char *tname = rb_builtin_type_name(t); + VALUE mesg, exc = rb_eFatal; + + if (tname) { + const char *cname = builtin_class_name(x); + if (cname) + mesg = rb_sprintf("wrong argument type %s (expected %s)", + cname, tname); + else + mesg = rb_sprintf("wrong argument type %"PRIsVALUE" (expected %s)", + rb_obj_class(x), tname); + exc = rb_eTypeError; + } + else if (xt > T_MASK && xt <= 0x3f) { + mesg = rb_sprintf("unknown type 0x%x (0x%x given, probably comes" + " from extension library for ruby 1.8)", t, xt); + } + else { + mesg = rb_sprintf("unknown type 0x%x (0x%x given)", t, xt); + } + rb_exc_raise(rb_exc_new_str(exc, mesg)); +} + void rb_check_type(VALUE x, int t) { int xt; if (x == Qundef) { - rb_bug("undef leaked to the Ruby space"); + rb_bug(UNDEF_LEAKED); } xt = TYPE(x); if (xt != t || (xt == T_DATA && RTYPEDDATA_P(x))) { - const char *tname = rb_builtin_type_name(t); - if (tname) { - const char *cname = builtin_class_name(x); - if (cname) - rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)", - cname, tname); - else - rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (expected %s)", - rb_obj_class(x), tname); - } - if (xt > T_MASK && xt <= 0x3f) { - rb_fatal("unknown type 0x%x (0x%x given, probably comes from extension library for ruby 1.8)", t, xt); - } - rb_bug("unknown type 0x%x (0x%x given)", t, xt); + unexpected_type(x, xt, t); + } +} + +void +rb_unexpected_type(VALUE x, int t) +{ + if (x == Qundef) { + rb_bug(UNDEF_LEAKED); } + + unexpected_type(x, TYPE(x), t); } int diff --git a/internal.h b/internal.h index c59ccc5e19..edadce991a 100644 --- a/internal.h +++ b/internal.h @@ -1540,6 +1540,12 @@ VALUE rb_str2big_gmp(VALUE arg, int base, int badcheck); /* error.c (export) */ int rb_bug_reporter_add(void (*func)(FILE *, void *), void *data); +NORETURN(void rb_unexpected_type(VALUE,int)); +#undef Check_Type +#define Check_Type(v, t) \ + (!RB_TYPE_P((VALUE)(v), (t)) || \ + ((t) == RUBY_T_DATA && RTYPEDDATA_P(v)) ? \ + rb_unexpected_type((VALUE)(v), (t)) : (void)0) /* file.c (export) */ #ifdef HAVE_READLINK @@ -2583,7 +2583,7 @@ m_core_hash_merge_ptr(int argc, VALUE *argv, VALUE recv) static int kwmerge_i(VALUE key, VALUE value, VALUE hash) { - if (!SYMBOL_P(key)) Check_Type(key, T_SYMBOL); + Check_Type(key, T_SYMBOL); rb_hash_aset(hash, key, value); return ST_CONTINUE; } @@ -2591,7 +2591,7 @@ kwmerge_i(VALUE key, VALUE value, VALUE hash) static int kwcheck_i(VALUE key, VALUE value, VALUE hash) { - if (!SYMBOL_P(key)) Check_Type(key, T_SYMBOL); + Check_Type(key, T_SYMBOL); return ST_CONTINUE; } |