4 /* Each of these operations intend to implement safe code according to
5 https://www.securecoding.cert.org/confluence/display/seccode/INT32-C.+Ensure+that+integer+operations+do+not+result+in+an+overflow
6 Thanks defn52 for the link.
9 static inline OBJECT
fixnum_add(STATE
, OBJECT a
, OBJECT b
) {
12 // + will never overflow an int because of the size of a Fixnum
16 if(m
> FIXNUM_MAX
|| m
< FIXNUM_MIN
) {
17 return bignum_new(state
, m
);
19 return APPLY_TAG(m
, TAG_FIXNUM
);
23 static inline OBJECT
fixnum_sub(STATE
, OBJECT a
, OBJECT b
) {
27 // - will never overflow a signed int because of the size of a Fixnum
33 r
= bignum_sub(state
, bignum_new(state
, j
), bignum_new(state
, k
));
39 static inline OBJECT
fixnum_mul(STATE
, OBJECT a
, OBJECT b
) {
40 native_int na
= N2I(a
);
41 native_int nb
= N2I(b
);
42 unsigned int overflow
= FALSE
;
44 /* There is no C type large enough to (always) hold the result of
45 * multiplying two native_ints together
48 if (na
> 0) { /* a is positive */
49 if (nb
> 0) { /* a and b are positive */
50 if (na
> (FIXNUM_MAX
/ nb
)) { overflow
= TRUE
; }
51 } else { /* a is positive, b is non-positive */
52 if (nb
< (FIXNUM_MIN
/ na
)) { overflow
= TRUE
; }
54 } else { /* a is non-positive */
55 if (nb
> 0) { /* a is non-positive, b is positive */
56 if (na
< (FIXNUM_MIN
/ nb
)) { overflow
= TRUE
; }
57 } else { /* a and b are non-positive */
58 if ( (na
!= 0) && (nb
< (FIXNUM_MAX
/ na
))) { overflow
= TRUE
; }
62 return bignum_mul(state
, bignum_new(state
, na
), b
);
68 static inline native_int
fixnum_div(STATE
, OBJECT a
, OBJECT b
, native_int
*mod
) {
75 // adapted from ruby 1.8.x
89 if ((*mod
< 0 && y
> 0) || (*mod
> 0 && y
< 0)) {
97 static inline OBJECT
fixnum_divmod(STATE
, OBJECT a
, OBJECT b
) {
101 div
= fixnum_div(state
, a
, b
, &mod
);
103 ary
= array_new(state
, 2);
104 array_set(state
, ary
, 0, I2N(div
));
105 array_set(state
, ary
, 1, I2N(mod
));