summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--class.c8
-rw-r--r--error.c56
-rw-r--r--internal.h6
-rw-r--r--vm.c4
5 files changed, 54 insertions, 24 deletions
diff --git a/ChangeLog b/ChangeLog
index d1d239058b..6e9bd9a1a2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/class.c b/class.c
index 6b818a326f..8ab496ef7e 100644
--- a/class.c
+++ b/class.c
@@ -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);
diff --git a/error.c b/error.c
index b795dc185c..27ca7db8d2 100644
--- a/error.c
+++ b/error.c
@@ -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
diff --git a/vm.c b/vm.c
index 4f4c646b94..77e08ab45c 100644
--- a/vm.c
+++ b/vm.c
@@ -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;
}