pike.git/
src/
operators.c
Branch:
Tag:
Non-build tags
All tags
No tags
2014-12-04
2014-12-04 19:23:05 by Arne Goedeke <el@laramies.com>
4c86e39dab9e7f986d7ca330f30426bf71e1df11 (
47
lines) (+
36
/-
11
)
[
Show
|
Annotate
]
Branch:
bill/master_archive_support
`%: add overflow checks
4231:
{ if(TYPEOF(sp[-2]) != TYPEOF(sp[-1]) && !float_promote()) {
+
#ifdef AUTO_BIGNUM
+
do_lfun_modulo:
+
#endif
if(call_lfun(LFUN_MOD, LFUN_RMOD)) return;
4305:
return; } case T_INT:
-
if
(
sp[-1].u.integer == 0)
+
{
+
int of = 0;
+
INT_TYPE a =
sp[-
2].u.integer,
+
b = sp[-
1].u.integer
;
+
INT_TYPE res;
+
if (b
== 0)
OP_MODULO_BY_ZERO_ERROR("`%");
-
sp--;
-
if(
sp[-1].u.integer
>=0)
+
if(
a
>=0)
{
-
if(
sp[0].u.integer
>=0)
+
if(
b
>=0)
{
-
sp[-1].u.integer
%
=
sp[0].u.integer
;
+
res
=
a % b
;
}else{
-
sp[-1].u.integer
=((
sp[-1].u.integer+
~
sp[0].u.integer
)%-
sp[0].u.integer
)-~
sp[0].u.integer
;
+
/* res
=
((
a+
~
b
)%-
b
)-~
b */
+
res = DO_INT_TYPE_ADD_OVERFLOW(a, ~b, &of)
;
+
res = DO_INT_TYPE_MOD_OVERFLOW(res, b, &of);
+
res = DO_INT_TYPE_SUB_OVERFLOW(res, ~b, &of);
} }else{
-
if(
sp[0].u.integer
>=0)
+
if(
b
>=0)
{
-
sp[-1].u.integer
=
sp[0].u.integer+
~((~
sp[-1].u.integer
) %
sp[0].u.integer
);
+
/* res
=
b+
~((~
a
) %
b
)
*/
+
res = DO_INT_TYPE_MOD_OVERFLOW(~a, b, &of)
;
+
res = DO_INT_TYPE_ADD_OVERFLOW(b, ~res, &of);
}else{
-
sp[
-
1].u.integer
=-(-
sp[-1].u.integer
% -
sp[0].u.integer
);
+
/* a % b and a %
-
b are equivalent, if overflow does not
+
* happen
+
* res
=
-(-
a
% -
b
)
= a % b
;
*/
+
res = DO_INT_TYPE_MOD_OVERFLOW(a, b, &of);
} }
-
SET_SVAL
_SUBTYPE
(sp[-1], NUMBER_NUMBER);
+
#ifdef
AUTO_BIGNUM
+
if (of) {
+
stack_swap();
+
convert_stack_top_to_bignum();
+
stack_swap();
+
goto do_lfun_modulo;
+
}
+
#endif
+
sp--;
+
SET_SVAL(sp[-1],
T_INT,
NUMBER_NUMBER
, integer, res
);
return;
-
+
}
default: PIKE_ERROR("`%", "Bad argument 1.\n", sp, 2); }