diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2016-11-01 22:34:30 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2016-11-01 22:34:30 +0000 |
commit | 13149a59d8472db4cdd5a63a3eb2e7296e9a6713 (patch) | |
tree | eb5c53df995cf03c199d87b1f5e6673547d58fc6 /numeric.c | |
parent | c7e99cbfc8dea00ffa5d0a286ea484e90e789df4 (diff) | |
download | ruby-13149a59d8472db4cdd5a63a3eb2e7296e9a6713.tar.gz |
numeric.c: bit op with non-integer
* numeric.c (rb_num_coerce_bit): enable bit operations with
coercing by non-integer object. [ruby-core:77783] [Bug #12875]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56543 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'numeric.c')
-rw-r--r-- | numeric.c | 55 |
1 files changed, 35 insertions, 20 deletions
@@ -293,21 +293,27 @@ num_funcall0(VALUE x, ID func) return rb_exec_recursive(num_funcall_op_0, x, (VALUE)func); } +static void +num_funcall_op_1_recursion(VALUE x, ID func, VALUE y) +{ + const char *name = rb_id2name(func); + if (ISALNUM(name[0])) { + rb_name_error(func, "%"PRIsVALUE".%"PRIsVALUE"(%"PRIsVALUE")", + x, ID2SYM(func), y); + } + else { + rb_name_error(func, "%"PRIsVALUE"%"PRIsVALUE"%"PRIsVALUE, + x, ID2SYM(func), y); + } +} + static VALUE num_funcall_op_1(VALUE y, VALUE arg, int recursive) { ID func = (ID)((VALUE *)arg)[0]; VALUE x = ((VALUE *)arg)[1]; if (recursive) { - const char *name = rb_id2name(func); - if (ISALNUM(name[0])) { - rb_name_error(func, "%"PRIsVALUE".%"PRIsVALUE"(%"PRIsVALUE")", - x, ID2SYM(func), y); - } - else { - rb_name_error(func, "%"PRIsVALUE"%"PRIsVALUE"%"PRIsVALUE, - x, ID2SYM(func), y); - } + num_funcall_op_1_recursion(x, func, y); } return rb_funcall(x, func, 1, y); } @@ -4128,24 +4134,33 @@ int_comp(VALUE num) return Qnil; } -static int -bit_coerce(VALUE *x, VALUE *y) +static VALUE +num_funcall_bit_1(VALUE y, VALUE arg, int recursive) { - if (!RB_INTEGER_TYPE_P(*y)) { - VALUE orig = *x; - do_coerce(x, y, TRUE); - if (!RB_INTEGER_TYPE_P(*x) && !RB_INTEGER_TYPE_P(*y)) { - coerce_failed(orig, *y); - } + ID func = (ID)((VALUE *)arg)[0]; + VALUE x = ((VALUE *)arg)[1]; + if (recursive) { + num_funcall_op_1_recursion(x, func, y); } - return TRUE; + return rb_check_funcall(x, func, 1, &y); } VALUE rb_num_coerce_bit(VALUE x, VALUE y, ID func) { - bit_coerce(&x, &y); - return num_funcall1(x, func, y); + VALUE ret, args[3]; + + args[0] = (VALUE)func; + args[1] = x; + args[2] = y; + do_coerce(&args[1], &args[2], TRUE); + ret = rb_exec_recursive_paired(num_funcall_bit_1, + args[2], args[1], (VALUE)args); + if (ret == Qundef) { + /* show the original object, not coerced object */ + coerce_failed(x, y); + } + return ret; } /* |