Created
May 5, 2018 02:30
-
-
Save pulsejet/29ec1fd9fdc77f12a96798f4b32f1d47 to your computer and use it in GitHub Desktop.
Patch to force 1/2 == 0 in mruby
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From e36e2760f2c168c179a35cc8bf7a4103ce523f61 Mon Sep 17 00:00:00 2001 | |
From: Rob Lyman <[email protected]> | |
Date: Sat, 20 Jan 2018 13:52:04 -0600 | |
Subject: [PATCH 1/2] Updated support for integer division behavior | |
This adds an adapted fix to give conditional integer division support, | |
based on the environment variable MRB_INTEGER_DIVISION. This adapts from | |
the previous fix to the latest stable mRuby branch, taking into | |
account their new MRB_WITHOUT_FLOAT environment variable. | |
Note that MRB_WITHOUT_FLOAT and MRB_INTEGER_DIVISION are not compatible | |
and should not be used together. | |
With the former unset and the latter set, we can build an mRuby that | |
supports native floating point values, but still gives an integer | |
quotient result for dividing two integers (non-integer dividend or | |
divisor give float results, as usual). | |
This fix is adapted from the fix in this open PR on the mRuby project: | |
https://github.com/mruby/mruby/pull/3123 | |
--- | |
src/vm.c | 38 ++++++++++++++++++++++++++++++++++++++ | |
1 file changed, 38 insertions(+) | |
diff --git a/src/vm.c b/src/vm.c | |
index 084811499..59646ed6c 100644 | |
--- a/src/vm.c | |
+++ b/src/vm.c | |
@@ -2416,6 +2416,9 @@ mrb_vm_exec(mrb_state *mrb, struct RProc *proc, mrb_code *pc) | |
CASE(OP_DIV) { | |
/* A B C R(A) := R(A)/R(A+1) (Syms[B]=:/,C=1)*/ | |
int a = GETARG_A(i); | |
+#ifdef MRB_INTEGER_DIVISION | |
+ int integer_div = FALSE; | |
+#endif | |
#ifndef MRB_WITHOUT_FLOAT | |
double x, y, f; | |
#endif | |
@@ -2433,6 +2436,9 @@ mrb_vm_exec(mrb_state *mrb, struct RProc *proc, mrb_code *pc) | |
#else | |
x = (mrb_float)mrb_fixnum(regs[a]); | |
y = (mrb_float)mrb_fixnum(regs[a+1]); | |
+#ifdef MRB_INTEGER_DIVISION | |
+ integer_div = TRUE; | |
+#endif | |
break; | |
case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT): | |
x = (mrb_float)mrb_fixnum(regs[a]); | |
@@ -2452,6 +2458,35 @@ mrb_vm_exec(mrb_state *mrb, struct RProc *proc, mrb_code *pc) | |
} | |
#ifndef MRB_WITHOUT_FLOAT | |
+#ifdef MRB_INTEGER_DIVISION | |
+ if (integer_div) | |
+ { | |
+ if (y == 0 || (x == MRB_INT_MIN && y == -1)) { | |
+ SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x / (mrb_float)y); | |
+ } | |
+ else { | |
+ mrb_int div, mod; | |
+ if (y < 0) { | |
+ if (x < 0) | |
+ div = -x / -y; | |
+ else | |
+ div = - (x / -y); | |
+ } | |
+ else { | |
+ if (x < 0) | |
+ div = - (-x / y); | |
+ else | |
+ div = x / y; | |
+ } | |
+ mod = x - div*y; | |
+ if ((mod < 0 && y > 0) || (mod > 0 && y < 0)) { | |
+ div -= 1; | |
+ } | |
+ SET_INT_VALUE(regs[a], div); | |
+ } | |
+ } | |
+ else { | |
+#endif | |
if (y == 0) { | |
if (x > 0) f = INFINITY; | |
else if (x < 0) f = -INFINITY; | |
@@ -2461,7 +2496,10 @@ mrb_vm_exec(mrb_state *mrb, struct RProc *proc, mrb_code *pc) | |
f = x / y; | |
} | |
SET_FLOAT_VALUE(mrb, regs[a], f); | |
+#ifdef MRB_INTEGER_DIVISION | |
+ } | |
#endif | |
+#endif /* #ifndef MRB_WITHOUT_FLOAT */ | |
NEXT; | |
} | |
From 116c6373e188109e27f00012f8ed3a965c75ad53 Mon Sep 17 00:00:00 2001 | |
From: Rob Lyman <[email protected]> | |
Date: Sat, 20 Jan 2018 13:52:38 -0600 | |
Subject: [PATCH 2/2] Add explanation of integer division support to README | |
MIME-Version: 1.0 | |
Content-Type: text/plain; charset=UTF-8 | |
Content-Transfer-Encoding: 8bit | |
This explains the raison d'être for this fork of mRuby. | |
--- | |
README.md | 8 ++++++++ | |
1 file changed, 8 insertions(+) | |
diff --git a/README.md b/README.md | |
index 196cc2ef7..6ba0b4c42 100644 | |
--- a/README.md | |
+++ b/README.md | |
@@ -1,5 +1,13 @@ | |
[![Build Status][build-status-img]][travis-ci] | |
+## mruby with Integer Division Support | |
+ | |
+This is a fork of the mruby project that includes support for integer division compatible with that in other Rubys, so that | |
+ | |
+`(1 / 2) => 0` | |
+ | |
+This is enabled with the compiler variable `MRB_INTEGER_DIVISION`: when set during compilation, it will enable integer division behavior. This mruby is otherwise compatible with mruby 1.4.0. | |
+ | |
## What is mruby | |
mruby is the lightweight implementation of the Ruby language complying to (part |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment