Change the arguments of following implicit conversion functions:
`mrb_convert_type`
`mrb_check_convert_type`
Those function no longer take `tname` string representation of desired
type, and take method symbols instead of `const char*` names. This is
incompatible change. I hope no third-party gems use those functions.
MODIFY
include/mruby.h
include/mruby.h
@@ -1252,12 +1252,12 @@ MRB_API void mrb_field_write_barrier(mrb_state *, struct RBasic*, struct RBasic*
} while (0)
MRB_API void mrb_write_barrier(mrb_state *, struct RBasic*);
-MRB_API mrb_value mrb_check_convert_type(mrb_state *mrb, mrb_value val, enum mrb_vtype type, const char *tname, const char *method);
+MRB_API mrb_value mrb_check_convert_type(mrb_state *mrb, mrb_value val, enum mrb_vtype type, mrb_sym method);
MRB_API mrb_value mrb_any_to_s(mrb_state *mrb, mrb_value obj);
MRB_API const char * mrb_obj_classname(mrb_state *mrb, mrb_value obj);
MRB_API struct RClass* mrb_obj_class(mrb_state *mrb, mrb_value obj);
MRB_API mrb_value mrb_class_path(mrb_state *mrb, struct RClass *c);
-MRB_API mrb_value mrb_convert_type(mrb_state *mrb, mrb_value val, enum mrb_vtype type, const char *tname, const char *method);
+MRB_API mrb_value mrb_convert_type(mrb_state *mrb, mrb_value val, enum mrb_vtype type, mrb_sym method);
MRB_API mrb_bool mrb_obj_is_kind_of(mrb_state *mrb, mrb_value obj, struct RClass *c);
MRB_API mrb_value mrb_obj_inspect(mrb_state *mrb, mrb_value self);
MRB_API mrb_value mrb_obj_clone(mrb_state *mrb, mrb_value self);

MODIFY
mrbgems/mruby-kernel-ext/src/kernel.c
mrbgems/mruby-kernel-ext/src/kernel.c
@@ -151,7 +151,7 @@ mrb_f_string(mrb_state *mrb, mrb_value self)
mrb_value arg = mrb_get_arg1(mrb);
mrb_value tmp;
- tmp = mrb_convert_type(mrb, arg, MRB_TT_STRING, "String", "to_s");
+ tmp = mrb_convert_type(mrb, arg, MRB_TT_STRING, MRB_SYM(to_s));
return tmp;
}
@@ -170,7 +170,7 @@ mrb_f_array(mrb_state *mrb, mrb_value self)
mrb_value arg = mrb_get_arg1(mrb);
mrb_value tmp;
- tmp = mrb_check_convert_type(mrb, arg, MRB_TT_ARRAY, "Array", "to_a");
+ tmp = mrb_check_convert_type(mrb, arg, MRB_TT_ARRAY, MRB_SYM(to_a));
if (mrb_nil_p(tmp)) {
return mrb_ary_new_from_values(mrb, 1, &arg);
}

MODIFY
src/object.c
src/object.c
@@ -315,110 +315,115 @@ mrb_init_object(mrb_state *mrb)
mrb_define_method(mrb, f, "inspect", false_to_s, MRB_ARGS_NONE());
}
-static mrb_value
-convert_type(mrb_state *mrb, mrb_value val, const char *tname, const char *method, mrb_bool raise)
+static const struct types {
+ const enum mrb_vtype type;
+ const char *name;
+} builtin_types[] = {
+/* {MRB_TT_NIL, "nil"}, */
+ {MRB_TT_FALSE, "false"},
+ {MRB_TT_TRUE, "true"},
+ {MRB_TT_FIXNUM, "Fixnum"},
+ {MRB_TT_SYMBOL, "Symbol"}, /* :symbol */
+ {MRB_TT_MODULE, "Module"},
+ {MRB_TT_OBJECT, "Object"},
+ {MRB_TT_CLASS, "Class"},
+ {MRB_TT_ICLASS, "iClass"}, /* internal use: mixed-in module holder */
+ {MRB_TT_SCLASS, "SClass"},
+ {MRB_TT_PROC, "Proc"},
+#ifndef MRB_WITHOUT_FLOAT
+ {MRB_TT_FLOAT, "Float"},
+#endif
+ {MRB_TT_ARRAY, "Array"},
+ {MRB_TT_HASH, "Hash"},
+ {MRB_TT_STRING, "String"},
+ {MRB_TT_RANGE, "Range"},
+/* {MRB_TT_BIGNUM, "Bignum"}, */
+ {MRB_TT_DATA, "Data"}, /* internal use: wrapped C pointers */
+/* {MRB_TT_UNDEF, "undef"}, */ /* internal use: #undef; should not happen */
+ {MRB_TT_MAXDEFINE, 0}
+};
+
+static const char*
+type_name(enum mrb_vtype t)
{
- mrb_sym m = 0;
+ const struct types *type = builtin_types;
+
+ while (type->type < MRB_TT_MAXDEFINE) {
+ if (type->type == t) return type->name;
+ type++;
+ }
+ return NULL;
+}
- m = mrb_intern_cstr(mrb, method);
- if (!mrb_respond_to(mrb, val, m)) {
+static mrb_value
+convert_type(mrb_state *mrb, mrb_value val, const char *tname, mrb_sym method, mrb_bool raise)
+{
+ if (!mrb_respond_to(mrb, val, method)) {
if (raise) {
- mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %Y into %s", val, tname);
+ if (tname) mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %Y into %s", val, tname);
+ mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %Y", val);
}
return mrb_nil_value();
}
- return mrb_funcall_argv(mrb, val, m, 0, 0);
+ return mrb_funcall_argv(mrb, val, method, 0, 0);
}
MRB_API mrb_value
-mrb_convert_type(mrb_state *mrb, mrb_value val, enum mrb_vtype type, const char *tname, const char *method)
+mrb_convert_type(mrb_state *mrb, mrb_value val, enum mrb_vtype type, mrb_sym method)
{
mrb_value v;
+ const char *tname;
if (mrb_type(val) == type) return val;
+ tname = type_name(type);
v = convert_type(mrb, val, tname, method, TRUE);
if (mrb_type(v) != type) {
if (type == MRB_TT_STRING) return mrb_any_to_s(mrb, val);
- mrb_raisef(mrb, E_TYPE_ERROR, "%v cannot be converted to %s by #%s", val, tname, method);
+ mrb_raisef(mrb, E_TYPE_ERROR, "%v cannot be converted to %s by #%n", val, tname, method);
}
return v;
}
MRB_API mrb_value
-mrb_check_convert_type(mrb_state *mrb, mrb_value val, enum mrb_vtype type, const char *tname, const char *method)
+mrb_check_convert_type(mrb_state *mrb, mrb_value val, enum mrb_vtype type, mrb_sym method)
{
mrb_value v;
if (mrb_type(val) == type && type != MRB_TT_DATA && type != MRB_TT_ISTRUCT) return val;
- v = convert_type(mrb, val, tname, method, FALSE);
+ v = convert_type(mrb, val, type_name(type), method, FALSE);
if (mrb_nil_p(v) || mrb_type(v) != type) return mrb_nil_value();
return v;
}
-static const struct types {
- unsigned char type;
- const char *name;
-} builtin_types[] = {
-/* {MRB_TT_NIL, "nil"}, */
- {MRB_TT_FALSE, "false"},
- {MRB_TT_TRUE, "true"},
- {MRB_TT_FIXNUM, "Fixnum"},
- {MRB_TT_SYMBOL, "Symbol"}, /* :symbol */
- {MRB_TT_MODULE, "Module"},
- {MRB_TT_OBJECT, "Object"},
- {MRB_TT_CLASS, "Class"},
- {MRB_TT_ICLASS, "iClass"}, /* internal use: mixed-in module holder */
- {MRB_TT_SCLASS, "SClass"},
- {MRB_TT_PROC, "Proc"},
-#ifndef MRB_WITHOUT_FLOAT
- {MRB_TT_FLOAT, "Float"},
-#endif
- {MRB_TT_ARRAY, "Array"},
- {MRB_TT_HASH, "Hash"},
- {MRB_TT_STRING, "String"},
- {MRB_TT_RANGE, "Range"},
-/* {MRB_TT_BIGNUM, "Bignum"}, */
- {MRB_TT_DATA, "Data"}, /* internal use: wrapped C pointers */
-/* {MRB_TT_VARMAP, "Varmap"}, */ /* internal use: dynamic variables */
-/* {MRB_TT_NODE, "Node"}, */ /* internal use: syntax tree node */
-/* {MRB_TT_UNDEF, "undef"}, */ /* internal use: #undef; should not happen */
- {MRB_TT_MAXDEFINE, 0}
-};
-
MRB_API void
mrb_check_type(mrb_state *mrb, mrb_value x, enum mrb_vtype t)
{
- const struct types *type = builtin_types;
- enum mrb_vtype xt;
+ enum mrb_vtype xt = mrb_type(x);
+ const char *tname, *ename;
- xt = mrb_type(x);
- if ((xt != t) || (xt == MRB_TT_DATA) || (xt == MRB_TT_ISTRUCT)) {
- while (type->type < MRB_TT_MAXDEFINE) {
- if (type->type == t) {
- const char *etype;
+ if (t == xt) return;
+ tname = type_name(t);
if (mrb_nil_p(x)) {
- etype = "nil";
+ ename = "nil";
}
else if (mrb_fixnum_p(x)) {
- etype = "Fixnum";
+ ename = "Fixnum";
}
else if (mrb_symbol_p(x)) {
- etype = "Symbol";
+ ename = "Symbol";
}
else if (mrb_immediate_p(x)) {
- etype = RSTRING_PTR(mrb_obj_as_string(mrb, x));
+ ename = RSTRING_PTR(mrb_obj_as_string(mrb, x));
}
else {
- etype = mrb_obj_classname(mrb, x);
+ ename = mrb_obj_classname(mrb, x);
}
+ if (tname) {
mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %s (expected %s)",
- etype, type->name);
- }
- type++;
- }
- mrb_raisef(mrb, E_TYPE_ERROR, "unknown type %d (%d given)", t, mrb_type(x));
+ ename, tname);
}
+ mrb_raisef(mrb, E_TYPE_ERROR, "unknown type %d (%s given)", t, ename);
}
/* 15.3.1.3.46 */
@@ -579,7 +584,7 @@ mrb_Float(mrb_state *mrb, mrb_value val)
return mrb_float_value(mrb, mrb_str_to_dbl(mrb, val, TRUE));
default:
- return mrb_convert_type(mrb, val, MRB_TT_FLOAT, "Float", "to_f");
+ return mrb_convert_type(mrb, val, MRB_TT_FLOAT, MRB_SYM(to_f));
}
}
#endif

MODIFY
src/string.c
src/string.c
@@ -1126,7 +1126,7 @@ mrb_str_to_str(mrb_state *mrb, mrb_value str)
case MRB_TT_MODULE:
return mrb_mod_to_s(mrb, str);
default:
- return mrb_convert_type(mrb, str, MRB_TT_STRING, "String", "to_s");
+ return mrb_convert_type(mrb, str, MRB_TT_STRING, MRB_SYM(to_s));
}
}

MODIFY
src/vm.c
src/vm.c
@@ -1375,7 +1375,7 @@ RETRY_TRY_BLOCK:
recv = regs[a];
blk = regs[bidx];
if (!mrb_nil_p(blk) && !mrb_proc_p(blk)) {
- blk = mrb_convert_type(mrb, blk, MRB_TT_PROC, "Proc", "to_proc");
+ blk = mrb_convert_type(mrb, blk, MRB_TT_PROC, MRB_SYM(to_proc));
/* The stack might have been reallocated during mrb_convert_type(),
see #3622 */
regs[bidx] = blk;
@@ -1557,7 +1557,7 @@ RETRY_TRY_BLOCK:
}
blk = regs[bidx];
if (!mrb_nil_p(blk) && !mrb_proc_p(blk)) {
- blk = mrb_convert_type(mrb, blk, MRB_TT_PROC, "Proc", "to_proc");
+ blk = mrb_convert_type(mrb, blk, MRB_TT_PROC, MRB_SYM(to_proc));
/* The stack or ci stack might have been reallocated during
mrb_convert_type(), see #3622 and #3784 */
regs[bidx] = blk;

Change the arguments of following implicit conversion functions:

- `mrb_convert_type`
- `mrb_check_convert_type`

Those function no longer take `tname` string representation of desired
type, and take method symbols instead of `const char*` names. This is
incompatible change. I hope no third-party gems use those functions.