Remove `mrb_funcall` from `<=>` operations.
MODIFY
include/mruby.h
include/mruby.h
@@ -1104,6 +1104,8 @@ MRB_API mrb_value mrb_Float(mrb_state *mrb, mrb_value val);
#endif
MRB_API mrb_value mrb_inspect(mrb_state *mrb, mrb_value obj);
MRB_API mrb_bool mrb_eql(mrb_state *mrb, mrb_value obj1, mrb_value obj2);
+/* mrb_cmp(mrb, obj1, obj2): 1:0:-1; -2 for error */
+MRB_API mrb_int mrb_cmp(mrb_state *mrb, mrb_value obj1, mrb_value obj2);
MRB_INLINE int
mrb_gc_arena_save(mrb_state *mrb)

MODIFY
mrbgems/mruby-range-ext/src/range.c
mrbgems/mruby-range-ext/src/range.c
static mrb_bool
r_le(mrb_state *mrb, mrb_value a, mrb_value b)
{
- mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b); /* compare result */
- /* output :a < b => -1, a = b => 0, a > b => +1 */
-
- if (mrb_fixnum_p(r)) {
- mrb_int c = mrb_fixnum(r);
- if (c == 0 || c == -1) return TRUE;
- }
+ mrb_int n = mrb_cmp(mrb, a, b);
+ if (n == 0 || n == -1) return TRUE;
return FALSE;
}
static mrb_bool
r_lt(mrb_state *mrb, mrb_value a, mrb_value b)
{
- mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b);
- /* output :a < b => -1, a = b => 0, a > b => +1 */
-
- return mrb_fixnum_p(r) && mrb_fixnum(r) == -1;
+ return mrb_cmp(mrb, a, b) == -1;
}
/*

MODIFY
src/numeric.c
src/numeric.c
@@ -1553,6 +1553,27 @@ integral_ge(mrb_state *mrb, mrb_value self)
return mrb_false_value();
}
+MRB_API mrb_int
+mrb_cmp(mrb_state *mrb, mrb_value obj1, mrb_value obj2)
+{
+ mrb_value v;
+
+ switch (mrb_type(obj1)) {
+ case MRB_TT_FIXNUM:
+ case MRB_TT_FLOAT:
+ return cmpnum(mrb, obj1, obj2);
+ case MRB_TT_STRING:
+ if (mrb_type(obj2) != MRB_TT_STRING)
+ return -2;
+ return mrb_str_cmp(mrb, obj1, obj2);
+ default:
+ v = mrb_funcall(mrb, obj1, "<=>", 1, obj2);
+ if (mrb_nil_p(v) || !mrb_fixnum_p(v))
+ return -2;
+ return mrb_fixnum(v);
+ }
+}
+
static mrb_value
num_finite_p(mrb_state *mrb, mrb_value self)
{

MODIFY
src/range.c
src/range.c
static void
r_check(mrb_state *mrb, mrb_value a, mrb_value b)
{
- mrb_value ans;
enum mrb_vtype ta;
enum mrb_vtype tb;
+ mrb_int n;
ta = mrb_type(a);
tb = mrb_type(b);
@@ -32,9 +32,8 @@ r_check(mrb_state *mrb, mrb_value a, mrb_value b)
return;
}
- ans = mrb_funcall(mrb, a, "<=>", 1, b);
- if (mrb_nil_p(ans)) {
- /* can not be compared */
+ n = mrb_cmp(mrb, a, b);
+ if (n == -2) { /* can not be compared */
mrb_raise(mrb, E_ARGUMENT_ERROR, "bad value for range");
}
}
@@ -42,37 +41,24 @@ r_check(mrb_state *mrb, mrb_value a, mrb_value b)
static mrb_bool
r_le(mrb_state *mrb, mrb_value a, mrb_value b)
{
- mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b); /* compare result */
- /* output :a < b => -1, a = b => 0, a > b => +1 */
-
- if (mrb_fixnum_p(r)) {
- mrb_int c = mrb_fixnum(r);
- if (c == 0 || c == -1) return TRUE;
- }
+ mrb_int n = mrb_cmp(mrb, a, b);
+ if (n == 0 || n == -1) return TRUE;
return FALSE;
}
static mrb_bool
r_gt(mrb_state *mrb, mrb_value a, mrb_value b)
{
- mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b);
- /* output :a < b => -1, a = b => 0, a > b => +1 */
-
- return mrb_fixnum_p(r) && mrb_fixnum(r) == 1;
+ return mrb_cmp(mrb, a, b) == 1;
}
static mrb_bool
r_ge(mrb_state *mrb, mrb_value a, mrb_value b)
{
- mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b); /* compare result */
- /* output :a < b => -1, a = b => 0, a > b => +1 */
-
- if (mrb_fixnum_p(r)) {
- mrb_int c = mrb_fixnum(r);
- if (c == 0 || c == 1) return TRUE;
- }
+ mrb_int n = mrb_cmp(mrb, a, b);
+ if (n == 0 || n == 1) return TRUE;
return FALSE;
}

Remove `mrb_funcall` from `<=>` operations.