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.
This commit is contained in:
Yukihiro "Matz" Matsumoto
2020-06-04 10:04:08 +09:00
parent 2a366ffba8
commit b67955b8ca
5 changed files with 84 additions and 79 deletions
+2 -2
View File
@@ -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);
+2 -2
View File
@@ -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);
}
+77 -72
View File
@@ -315,48 +315,8 @@ 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)
{
mrb_sym m = 0;
m = mrb_intern_cstr(mrb, method);
if (!mrb_respond_to(mrb, val, m)) {
if (raise) {
mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %Y into %s", val, tname);
}
return mrb_nil_value();
}
return mrb_funcall_argv(mrb, val, m, 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_value v;
if (mrb_type(val) == type) return val;
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);
}
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_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);
if (mrb_nil_p(v) || mrb_type(v) != type) return mrb_nil_value();
return v;
}
static const struct types {
unsigned char type;
const enum mrb_vtype type;
const char *name;
} builtin_types[] = {
/* {MRB_TT_NIL, "nil"}, */
@@ -379,46 +339,91 @@ static const struct types {
{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}
};
static const char*
type_name(enum mrb_vtype t)
{
const struct types *type = builtin_types;
while (type->type < MRB_TT_MAXDEFINE) {
if (type->type == t) return type->name;
type++;
}
return NULL;
}
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) {
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, method, 0, 0);
}
MRB_API mrb_value
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 #%n", val, tname, method);
}
return v;
}
MRB_API mrb_value
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, type_name(type), method, FALSE);
if (mrb_nil_p(v) || mrb_type(v) != type) return mrb_nil_value();
return v;
}
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;
if (mrb_nil_p(x)) {
etype = "nil";
}
else if (mrb_fixnum_p(x)) {
etype = "Fixnum";
}
else if (mrb_symbol_p(x)) {
etype = "Symbol";
}
else if (mrb_immediate_p(x)) {
etype = RSTRING_PTR(mrb_obj_as_string(mrb, x));
}
else {
etype = mrb_obj_classname(mrb, x);
}
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));
tname = type_name(t);
if (mrb_nil_p(x)) {
ename = "nil";
}
else if (mrb_fixnum_p(x)) {
ename = "Fixnum";
}
else if (mrb_symbol_p(x)) {
ename = "Symbol";
}
else if (mrb_immediate_p(x)) {
ename = RSTRING_PTR(mrb_obj_as_string(mrb, x));
}
else {
ename = mrb_obj_classname(mrb, x);
}
if (tname) {
mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %s (expected %s)",
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
+1 -1
View File
@@ -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));
}
}
+2 -2
View File
@@ -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;