fixed an object protection mistake in moo_divints() with regards to garbage collection

This commit is contained in:
hyunghwan.chung 2020-10-25 05:54:54 +00:00
parent 023d147e14
commit d1bdfd75d3
2 changed files with 79 additions and 75 deletions

View File

@ -777,7 +777,7 @@ static MOO_INLINE moo_oop_t make_bloated_bigint_with_ooi (moo_t* moo, moo_ooi_t
z = moo_instantiate(moo, moo->_large_negative_integer, MOO_NULL, 1 + extra); z = moo_instantiate(moo, moo->_large_negative_integer, MOO_NULL, 1 + extra);
} }
if (!z) return MOO_NULL; if (MOO_UNLIKELY(!z)) return MOO_NULL;
MOO_OBJ_SET_LIWORD_VAL (z, 0, w); MOO_OBJ_SET_LIWORD_VAL (z, 0, w);
return z; return z;
@ -802,7 +802,7 @@ static MOO_INLINE moo_oop_t make_bloated_bigint_with_ooi (moo_t* moo, moo_ooi_t
z = moo_instantiate(moo, moo->_large_negative_integer, MOO_NULL, (hw[1] > 0? 2: 1) + extra); z = moo_instantiate(moo, moo->_large_negative_integer, MOO_NULL, (hw[1] > 0? 2: 1) + extra);
} }
if (!z) return MOO_NULL; if (MOO_UNLIKELY(!z)) return MOO_NULL;
MOO_OBJ_SET_LIWORD_VAL (z, 0, hw[0]); MOO_OBJ_SET_LIWORD_VAL (z, 0, hw[0]);
if (hw[1] > 0) MOO_OBJ_SET_LIWORD_VAL (z, 1, hw[1]); if (hw[1] > 0) MOO_OBJ_SET_LIWORD_VAL (z, 1, hw[1]);
return z; return z;
@ -924,7 +924,7 @@ static MOO_INLINE moo_oop_t expand_bigint (moo_t* moo, moo_oop_t oop, moo_oow_t
moo_pushvolat (moo, &oop); moo_pushvolat (moo, &oop);
z = moo_instantiate(moo, MOO_OBJ_GET_CLASS(oop), MOO_NULL, count + inc); z = moo_instantiate(moo, MOO_OBJ_GET_CLASS(oop), MOO_NULL, count + inc);
moo_popvolat (moo); moo_popvolat (moo);
if (!z) return MOO_NULL; if (MOO_UNLIKELY(!z)) return MOO_NULL;
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
{ {
@ -945,7 +945,7 @@ static MOO_INLINE moo_oop_t _clone_bigint (moo_t* moo, moo_oop_t oop, moo_oow_t
moo_pushvolat (moo, &oop); moo_pushvolat (moo, &oop);
z = moo_instantiate(moo, _class, MOO_NULL, count); z = moo_instantiate(moo, _class, MOO_NULL, count);
moo_popvolat (moo); moo_popvolat (moo);
if (!z) return MOO_NULL; if (MOO_UNLIKELY(!z)) return MOO_NULL;
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
{ {
@ -1603,12 +1603,12 @@ static MOO_INLINE moo_oow_t multiply_unsigned_array_karatsuba (moo_t* moo, const
tmplen[1] = ndigits_yl + ndigits_yh + 1; tmplen[1] = ndigits_yl + ndigits_yh + 1;
if (tmplen[1] < tmplen[0]) tmplen[1] = tmplen[0]; if (tmplen[1] < tmplen[0]) tmplen[1] = tmplen[0];
tmp[1] = (moo_liw_t*)moo_callocmem(moo, MOO_SIZEOF(moo_liw_t) * tmplen[1]); /* TODO: should i use the object memory? if not, reuse the buffer and minimize memory allocation */ tmp[1] = (moo_liw_t*)moo_callocmem(moo, MOO_SIZEOF(moo_liw_t) * tmplen[1]); /* TODO: should i use the object memory? if not, reuse the buffer and minimize memory allocation */
if (!tmp[1]) goto oops; if (MOO_UNLIKELY(!tmp[1])) goto oops;
/* make a temporary for (a0 + a1) and (a0 * b0) */ /* make a temporary for (a0 + a1) and (a0 * b0) */
tmplen[0] = ndigits_xl + ndigits_yl + 1; tmplen[0] = ndigits_xl + ndigits_yl + 1;
tmp[0] = (moo_liw_t*)moo_callocmem(moo, MOO_SIZEOF(moo_liw_t) * tmplen[0]); tmp[0] = (moo_liw_t*)moo_callocmem(moo, MOO_SIZEOF(moo_liw_t) * tmplen[0]);
if (!tmp[0]) goto oops; if (MOO_UNLIKELY(!tmp[0])) goto oops;
/* tmp[0] = a0 + a1 */ /* tmp[0] = a0 + a1 */
tmplen[0] = add_unsigned_array(x, ndigits_xl, x + nshifts, ndigits_xh, tmp[0]); tmplen[0] = add_unsigned_array(x, ndigits_xl, x + nshifts, ndigits_xh, tmp[0]);
@ -2292,7 +2292,7 @@ static moo_oop_t add_unsigned_integers (moo_t* moo, moo_oop_t x, moo_oop_t y)
moo_pushvolat (moo, &y); moo_pushvolat (moo, &y);
z = moo_instantiate(moo, MOO_OBJ_GET_CLASS(x), MOO_NULL, zs); z = moo_instantiate(moo, MOO_OBJ_GET_CLASS(x), MOO_NULL, zs);
moo_popvolats (moo, 2); moo_popvolats (moo, 2);
if (!z) return MOO_NULL; if (MOO_UNLIKELY(!z)) return MOO_NULL;
add_unsigned_array ( add_unsigned_array (
MOO_OBJ_GET_LIWORD_SLOT(x), as, MOO_OBJ_GET_LIWORD_SLOT(x), as,
@ -2313,7 +2313,7 @@ static moo_oop_t subtract_unsigned_integers (moo_t* moo, moo_oop_t x, moo_oop_t
moo_pushvolat (moo, &y); moo_pushvolat (moo, &y);
z = moo_instantiate(moo, moo->_large_positive_integer, MOO_NULL, MOO_OBJ_GET_SIZE(x)); z = moo_instantiate(moo, moo->_large_positive_integer, MOO_NULL, MOO_OBJ_GET_SIZE(x));
moo_popvolats (moo, 2); moo_popvolats (moo, 2);
if (!z) return MOO_NULL; if (MOO_UNLIKELY(!z)) return MOO_NULL;
subtract_unsigned_array (moo, subtract_unsigned_array (moo,
MOO_OBJ_GET_LIWORD_SLOT(x), MOO_OBJ_GET_SIZE(x), MOO_OBJ_GET_LIWORD_SLOT(x), MOO_OBJ_GET_SIZE(x),
@ -2340,7 +2340,7 @@ static moo_oop_t multiply_unsigned_integers (moo_t* moo, moo_oop_t x, moo_oop_t
moo_pushvolat (moo, &y); moo_pushvolat (moo, &y);
z = moo_instantiate(moo, moo->_large_positive_integer, MOO_NULL, xs + ys); z = moo_instantiate(moo, moo->_large_positive_integer, MOO_NULL, xs + ys);
moo_popvolats (moo, 2); moo_popvolats (moo, 2);
if (!z) return MOO_NULL; if (MOO_UNLIKELY(!z)) return MOO_NULL;
#if defined(MOO_ENABLE_KARATSUBA) #if defined(MOO_ENABLE_KARATSUBA)
if (CANNOT_KARATSUBA(moo, xs, ys)) if (CANNOT_KARATSUBA(moo, xs, ys))
@ -2475,7 +2475,7 @@ moo_oop_t moo_addints (moo_t* moo, moo_oop_t x, moo_oop_t y)
moo_pushvolat (moo, &y); moo_pushvolat (moo, &y);
x = make_bigint_with_ooi(moo, v); x = make_bigint_with_ooi(moo, v);
moo_popvolat (moo); moo_popvolat (moo);
if (!x) return MOO_NULL; if (MOO_UNLIKELY(!x)) return MOO_NULL;
} }
else if (MOO_OOP_IS_SMOOI(y)) else if (MOO_OOP_IS_SMOOI(y))
{ {
@ -2503,12 +2503,12 @@ moo_oop_t moo_addints (moo_t* moo, moo_oop_t x, moo_oop_t y)
if (is_less_unsigned(x, y)) if (is_less_unsigned(x, y))
{ {
z = subtract_unsigned_integers(moo, y, x); z = subtract_unsigned_integers(moo, y, x);
if (!z) return MOO_NULL; if (MOO_UNLIKELY(!z)) return MOO_NULL;
} }
else else
{ {
z = subtract_unsigned_integers(moo, x, y); z = subtract_unsigned_integers(moo, x, y);
if (!z) return MOO_NULL; if (MOO_UNLIKELY(!z)) return MOO_NULL;
MOO_OBJ_SET_CLASS(z, moo->_large_negative_integer); MOO_OBJ_SET_CLASS(z, moo->_large_negative_integer);
} }
} }
@ -2518,13 +2518,13 @@ moo_oop_t moo_addints (moo_t* moo, moo_oop_t x, moo_oop_t y)
if (is_less_unsigned(x, y)) if (is_less_unsigned(x, y))
{ {
z = subtract_unsigned_integers(moo, y, x); z = subtract_unsigned_integers(moo, y, x);
if (!z) return MOO_NULL; if (MOO_UNLIKELY(!z)) return MOO_NULL;
MOO_OBJ_SET_CLASS(z, moo->_large_negative_integer); MOO_OBJ_SET_CLASS(z, moo->_large_negative_integer);
} }
else else
{ {
z = subtract_unsigned_integers(moo, x, y); z = subtract_unsigned_integers(moo, x, y);
if (!z) return MOO_NULL; if (MOO_UNLIKELY(!z)) return MOO_NULL;
} }
} }
} }
@ -2534,7 +2534,7 @@ moo_oop_t moo_addints (moo_t* moo, moo_oop_t x, moo_oop_t y)
/* both are positive or negative */ /* both are positive or negative */
neg = (MOO_POINTER_IS_NBIGINT(moo, x)); neg = (MOO_POINTER_IS_NBIGINT(moo, x));
z = add_unsigned_integers(moo, x, y); z = add_unsigned_integers(moo, x, y);
if (!z) return MOO_NULL; if (MOO_UNLIKELY(!z)) return MOO_NULL;
if (neg) MOO_OBJ_SET_CLASS(z, moo->_large_negative_integer); if (neg) MOO_OBJ_SET_CLASS(z, moo->_large_negative_integer);
} }
} }
@ -2583,7 +2583,7 @@ moo_oop_t moo_subints (moo_t* moo, moo_oop_t x, moo_oop_t y)
moo_pushvolat (moo, &y); moo_pushvolat (moo, &y);
x = make_bigint_with_ooi(moo, v); x = make_bigint_with_ooi(moo, v);
moo_popvolat (moo); moo_popvolat (moo);
if (!x) return MOO_NULL; if (MOO_UNLIKELY(!x)) return MOO_NULL;
} }
else if (MOO_OOP_IS_SMOOI(y)) else if (MOO_OOP_IS_SMOOI(y))
{ {
@ -2595,7 +2595,7 @@ moo_oop_t moo_subints (moo_t* moo, moo_oop_t x, moo_oop_t y)
moo_pushvolat (moo, &x); moo_pushvolat (moo, &x);
y = make_bigint_with_ooi(moo, v); y = make_bigint_with_ooi(moo, v);
moo_popvolat (moo); moo_popvolat (moo);
if (!y) return MOO_NULL; if (MOO_UNLIKELY(!y)) return MOO_NULL;
} }
else else
{ {
@ -2607,7 +2607,7 @@ moo_oop_t moo_subints (moo_t* moo, moo_oop_t x, moo_oop_t y)
{ {
neg = (MOO_POINTER_IS_NBIGINT(moo, x)); neg = (MOO_POINTER_IS_NBIGINT(moo, x));
z = add_unsigned_integers(moo, x, y); z = add_unsigned_integers(moo, x, y);
if (!z) return MOO_NULL; if (MOO_UNLIKELY(!z)) return MOO_NULL;
if (neg) MOO_OBJ_SET_CLASS(z, moo->_large_negative_integer); if (neg) MOO_OBJ_SET_CLASS(z, moo->_large_negative_integer);
} }
else else
@ -2617,14 +2617,14 @@ moo_oop_t moo_subints (moo_t* moo, moo_oop_t x, moo_oop_t y)
{ {
neg = (MOO_POINTER_IS_NBIGINT(moo, x)); neg = (MOO_POINTER_IS_NBIGINT(moo, x));
z = subtract_unsigned_integers (moo, y, x); z = subtract_unsigned_integers (moo, y, x);
if (!z) return MOO_NULL; if (MOO_UNLIKELY(!z)) return MOO_NULL;
if (!neg) MOO_OBJ_SET_CLASS(z, moo->_large_negative_integer); if (!neg) MOO_OBJ_SET_CLASS(z, moo->_large_negative_integer);
} }
else else
{ {
neg = (MOO_POINTER_IS_NBIGINT(moo, x)); neg = (MOO_POINTER_IS_NBIGINT(moo, x));
z = subtract_unsigned_integers (moo, x, y); /* take x's sign */ z = subtract_unsigned_integers (moo, x, y); /* take x's sign */
if (!z) return MOO_NULL; if (MOO_UNLIKELY(!z)) return MOO_NULL;
if (neg) MOO_OBJ_SET_CLASS(z, moo->_large_negative_integer); if (neg) MOO_OBJ_SET_CLASS(z, moo->_large_negative_integer);
} }
} }
@ -2661,12 +2661,12 @@ moo_oop_t moo_mulints (moo_t* moo, moo_oop_t x, moo_oop_t y)
/* no need to call moo_pushvolat before creating x because /* no need to call moo_pushvolat before creating x because
* xv and yv contains actual values needed */ * xv and yv contains actual values needed */
x = make_bigint_with_ooi (moo, xv); x = make_bigint_with_ooi (moo, xv);
if (!x) return MOO_NULL; if (MOO_UNLIKELY(!x)) return MOO_NULL;
moo_pushvolat (moo, &x); /* protect x made above */ moo_pushvolat (moo, &x); /* protect x made above */
y = make_bigint_with_ooi(moo, yv); y = make_bigint_with_ooi(moo, yv);
moo_popvolat (moo); moo_popvolat (moo);
if (!y) return MOO_NULL; if (MOO_UNLIKELY(!y)) return MOO_NULL;
goto full_multiply; goto full_multiply;
} }
@ -2700,7 +2700,7 @@ moo_oop_t moo_mulints (moo_t* moo, moo_oop_t x, moo_oop_t y)
moo_pushvolat (moo, &y); moo_pushvolat (moo, &y);
x = make_bigint_with_ooi(moo, v); x = make_bigint_with_ooi(moo, v);
moo_popvolat (moo); moo_popvolat (moo);
if (!x) return MOO_NULL; if (MOO_UNLIKELY(!x)) return MOO_NULL;
} }
else if (MOO_OOP_IS_SMOOI(y)) else if (MOO_OOP_IS_SMOOI(y))
{ {
@ -2731,7 +2731,7 @@ moo_oop_t moo_mulints (moo_t* moo, moo_oop_t x, moo_oop_t y)
full_multiply: full_multiply:
neg = (MOO_OBJ_GET_CLASS(x) != MOO_OBJ_GET_CLASS(y)); /* checking sign before multication. no need to preserve x and y */ neg = (MOO_OBJ_GET_CLASS(x) != MOO_OBJ_GET_CLASS(y)); /* checking sign before multication. no need to preserve x and y */
z = multiply_unsigned_integers(moo, x, y); z = multiply_unsigned_integers(moo, x, y);
if (!z) return MOO_NULL; if (MOO_UNLIKELY(!z)) return MOO_NULL;
if (neg) MOO_OBJ_SET_CLASS(z, moo->_large_negative_integer); if (neg) MOO_OBJ_SET_CLASS(z, moo->_large_negative_integer);
} }
@ -2876,7 +2876,7 @@ moo_oop_t moo_divints (moo_t* moo, moo_oop_t x, moo_oop_t y, int modulo, moo_oop
moo_pushvolat (moo, &y); moo_pushvolat (moo, &y);
x = make_bigint_with_ooi(moo, xv); x = make_bigint_with_ooi(moo, xv);
moo_popvolat (moo); moo_popvolat (moo);
if (!x) return MOO_NULL; if (MOO_UNLIKELY(!x)) return MOO_NULL;
} }
else if (MOO_OOP_IS_SMOOI(y)) else if (MOO_OOP_IS_SMOOI(y))
{ {
@ -2895,13 +2895,13 @@ moo_oop_t moo_divints (moo_t* moo, moo_oop_t x, moo_oop_t y, int modulo, moo_oop
case 1: /* divide by 1 */ case 1: /* divide by 1 */
z = clone_bigint(moo, x, MOO_OBJ_GET_SIZE(x)); z = clone_bigint(moo, x, MOO_OBJ_GET_SIZE(x));
if (!z) return MOO_NULL; if (MOO_UNLIKELY(!z)) return MOO_NULL;
if (rem) *rem = MOO_SMOOI_TO_OOP(0); if (rem) *rem = MOO_SMOOI_TO_OOP(0);
return z; return z;
case -1: /* divide by -1 */ case -1: /* divide by -1 */
z = clone_bigint_negated(moo, x, MOO_OBJ_GET_SIZE(x)); z = clone_bigint_negated(moo, x, MOO_OBJ_GET_SIZE(x));
if (!z) return MOO_NULL; if (MOO_UNLIKELY(!z)) return MOO_NULL;
if (rem) *rem = MOO_SMOOI_TO_OOP(0); if (rem) *rem = MOO_SMOOI_TO_OOP(0);
return z; return z;
@ -2922,7 +2922,7 @@ moo_oop_t moo_divints (moo_t* moo, moo_oop_t x, moo_oop_t y, int modulo, moo_oop
y_neg_sign = (yv < 0); y_neg_sign = (yv < 0);
z = clone_bigint_to_positive(moo, x, MOO_OBJ_GET_SIZE(x)); z = clone_bigint_to_positive(moo, x, MOO_OBJ_GET_SIZE(x));
if (!z) return MOO_NULL; if (MOO_UNLIKELY(!z)) return MOO_NULL;
zw = MOO_OBJ_GET_LIWORD_SLOT(z); zw = MOO_OBJ_GET_LIWORD_SLOT(z);
zs = MOO_OBJ_GET_SIZE(z); zs = MOO_OBJ_GET_SIZE(z);
@ -2941,7 +2941,7 @@ moo_oop_t moo_divints (moo_t* moo, moo_oop_t x, moo_oop_t y, int modulo, moo_oop
if (x_neg_sign) ri = -ri; if (x_neg_sign) ri = -ri;
z = normalize_bigint(moo, z); z = normalize_bigint(moo, z);
if (!z) return MOO_NULL; if (MOO_UNLIKELY(!z)) return MOO_NULL;
if (x_neg_sign != y_neg_sign) if (x_neg_sign != y_neg_sign)
{ {
@ -2949,7 +2949,7 @@ moo_oop_t moo_divints (moo_t* moo, moo_oop_t x, moo_oop_t y, int modulo, moo_oop
if (ri && modulo) if (ri && modulo)
{ {
z = moo_subints(moo, z, MOO_SMOOI_TO_OOP(1)); z = moo_subints(moo, z, MOO_SMOOI_TO_OOP(1));
if (!z) return MOO_NULL; if (MOO_UNLIKELY(!z)) return MOO_NULL;
if (rem) if (rem)
{ {
moo_pushvolat (moo, &z); moo_pushvolat (moo, &z);
@ -2987,7 +2987,7 @@ moo_oop_t moo_divints (moo_t* moo, moo_oop_t x, moo_oop_t y, int modulo, moo_oop
moo_pushvolat (moo, &y); moo_pushvolat (moo, &y);
z = divide_unsigned_integers(moo, x, y, &r); z = divide_unsigned_integers(moo, x, y, &r);
moo_popvolats (moo, 2); moo_popvolats (moo, 2);
if (!z) return MOO_NULL; if (MOO_UNLIKELY(!z)) return MOO_NULL;
if (x_neg_sign) if (x_neg_sign)
{ {
@ -3020,12 +3020,12 @@ moo_oop_t moo_divints (moo_t* moo, moo_oop_t x, moo_oop_t y, int modulo, moo_oop
moo_pushvolat (moo, &r); moo_pushvolat (moo, &r);
z = normalize_bigint(moo, z); z = normalize_bigint(moo, z);
moo_popvolat (moo); moo_popvolat (moo);
if (!z) return MOO_NULL; if (MOO_UNLIKELY(!z)) return MOO_NULL;
moo_pushvolat (moo, &r); moo_pushvolat (moo, &r);
z = moo_subints(moo, z, MOO_SMOOI_TO_OOP(1)); z = moo_subints(moo, z, MOO_SMOOI_TO_OOP(1));
moo_popvolat (moo); moo_popvolat (moo);
if (!z) return MOO_NULL; if (MOO_UNLIKELY(!z)) return MOO_NULL;
*rem = r; *rem = r;
return z; return z;
@ -3035,7 +3035,7 @@ moo_oop_t moo_divints (moo_t* moo, moo_oop_t x, moo_oop_t y, int modulo, moo_oop
/* remainder is not needed at all */ /* remainder is not needed at all */
/* TODO: subtract 1 without normalization??? */ /* TODO: subtract 1 without normalization??? */
z = normalize_bigint(moo, z); z = normalize_bigint(moo, z);
if (!z) return MOO_NULL; if (MOO_UNLIKELY(!z)) return MOO_NULL;
return moo_subints(moo, z, MOO_SMOOI_TO_OOP(1)); return moo_subints(moo, z, MOO_SMOOI_TO_OOP(1));
} }
} }
@ -3048,8 +3048,13 @@ moo_oop_t moo_divints (moo_t* moo, moo_oop_t x, moo_oop_t y, int modulo, moo_oop
if (!r) return MOO_NULL; if (!r) return MOO_NULL;
} }
if (rem) *rem = r; moo_pushvolat (moo, &r);
return normalize_bigint(moo, z); z = normalize_bigint(moo, z);
moo_popvolat (moo);
if (z && rem) *rem = r;
return z;
oops_einval: oops_einval:
moo_seterrbfmt (moo, MOO_EINVAL, "invalid parameters - %O, %O", x, y); moo_seterrbfmt (moo, MOO_EINVAL, "invalid parameters - %O, %O", x, y);
@ -3263,9 +3268,9 @@ moo_oop_t moo_bitandints (moo_t* moo, moo_oop_t x, moo_oop_t y)
if (v == 0) return MOO_SMOOI_TO_OOP(0); if (v == 0) return MOO_SMOOI_TO_OOP(0);
moo_pushvolat (moo, &y); moo_pushvolat (moo, &y);
x = make_bigint_with_ooi (moo, v); x = make_bigint_with_ooi(moo, v);
moo_popvolat (moo); moo_popvolat (moo);
if (!x) return MOO_NULL; if (MOO_UNLIKELY(!x)) return MOO_NULL;
goto bigint_and_bigint; goto bigint_and_bigint;
} }
@ -3281,7 +3286,7 @@ moo_oop_t moo_bitandints (moo_t* moo, moo_oop_t x, moo_oop_t y)
moo_pushvolat (moo, &x); moo_pushvolat (moo, &x);
y = make_bigint_with_ooi (moo, v); y = make_bigint_with_ooi (moo, v);
moo_popvolat (moo); moo_popvolat (moo);
if (!x) return MOO_NULL; if (MOO_UNLIKELY(!x)) return MOO_NULL;
goto bigint_and_bigint; goto bigint_and_bigint;
} }
@ -3336,7 +3341,7 @@ moo_oop_t moo_bitandints (moo_t* moo, moo_oop_t x, moo_oop_t y)
moo_pushvolat (moo, &y); moo_pushvolat (moo, &y);
z = moo_instantiate(moo, moo->_large_positive_integer, MOO_NULL, zalloc); z = moo_instantiate(moo, moo->_large_positive_integer, MOO_NULL, zalloc);
moo_popvolats (moo, 2); moo_popvolats (moo, 2);
if (!z) return MOO_NULL; if (MOO_UNLIKELY(!z)) return MOO_NULL;
if (negx && negy) if (negx && negy)
{ {
@ -3478,7 +3483,7 @@ moo_oop_t moo_bitorints (moo_t* moo, moo_oop_t x, moo_oop_t y)
moo_pushvolat (moo, &y); moo_pushvolat (moo, &y);
x = make_bigint_with_ooi(moo, v); x = make_bigint_with_ooi(moo, v);
moo_popvolat (moo); moo_popvolat (moo);
if (!x) return MOO_NULL; if (MOO_UNLIKELY(!x)) return MOO_NULL;
goto bigint_and_bigint; goto bigint_and_bigint;
} }
@ -3494,7 +3499,7 @@ moo_oop_t moo_bitorints (moo_t* moo, moo_oop_t x, moo_oop_t y)
moo_pushvolat (moo, &x); moo_pushvolat (moo, &x);
y = make_bigint_with_ooi(moo, v); y = make_bigint_with_ooi(moo, v);
moo_popvolat (moo); moo_popvolat (moo);
if (!x) return MOO_NULL; if (MOO_UNLIKELY(!x)) return MOO_NULL;
goto bigint_and_bigint; goto bigint_and_bigint;
} }
@ -3556,7 +3561,7 @@ moo_oop_t moo_bitorints (moo_t* moo, moo_oop_t x, moo_oop_t y)
moo_pushvolat (moo, &y); moo_pushvolat (moo, &y);
z = moo_instantiate(moo, moo->_large_positive_integer, MOO_NULL, zalloc); z = moo_instantiate(moo, moo->_large_positive_integer, MOO_NULL, zalloc);
moo_popvolats (moo, 2); moo_popvolats (moo, 2);
if (!z) return MOO_NULL; if (MOO_UNLIKELY(!z)) return MOO_NULL;
if (negx && negy) if (negx && negy)
{ {
@ -3696,7 +3701,7 @@ moo_oop_t moo_bitxorints (moo_t* moo, moo_oop_t x, moo_oop_t y)
moo_pushvolat (moo, &y); moo_pushvolat (moo, &y);
x = make_bigint_with_ooi (moo, v); x = make_bigint_with_ooi (moo, v);
moo_popvolat (moo); moo_popvolat (moo);
if (!x) return MOO_NULL; if (MOO_UNLIKELY(!x)) return MOO_NULL;
goto bigint_and_bigint; goto bigint_and_bigint;
} }
@ -3712,7 +3717,7 @@ moo_oop_t moo_bitxorints (moo_t* moo, moo_oop_t x, moo_oop_t y)
moo_pushvolat (moo, &x); moo_pushvolat (moo, &x);
y = make_bigint_with_ooi (moo, v); y = make_bigint_with_ooi (moo, v);
moo_popvolat (moo); moo_popvolat (moo);
if (!x) return MOO_NULL; if (MOO_UNLIKELY(!x)) return MOO_NULL;
goto bigint_and_bigint; goto bigint_and_bigint;
} }
@ -3774,7 +3779,7 @@ moo_oop_t moo_bitxorints (moo_t* moo, moo_oop_t x, moo_oop_t y)
moo_pushvolat (moo, &y); moo_pushvolat (moo, &y);
z = moo_instantiate(moo, moo->_large_positive_integer, MOO_NULL, zalloc); z = moo_instantiate(moo, moo->_large_positive_integer, MOO_NULL, zalloc);
moo_popvolats (moo, 2); moo_popvolats (moo, 2);
if (!z) return MOO_NULL; if (MOO_UNLIKELY(!z)) return MOO_NULL;
if (negx && negy) if (negx && negy)
{ {
@ -3932,7 +3937,7 @@ moo_oop_t moo_bitinvint (moo_t* moo, moo_oop_t x)
moo_pushvolat (moo, &x); moo_pushvolat (moo, &x);
z = moo_instantiate(moo, moo->_large_positive_integer, MOO_NULL, zalloc); z = moo_instantiate(moo, moo->_large_positive_integer, MOO_NULL, zalloc);
moo_popvolat (moo); moo_popvolat (moo);
if (!z) return MOO_NULL; if (MOO_UNLIKELY(!z)) return MOO_NULL;
if (negx) if (negx)
{ {
@ -4004,7 +4009,7 @@ static MOO_INLINE moo_oop_t rshift_negative_bigint (moo_t* moo, moo_oop_t x, moo
/* +1 for the second inversion below */ /* +1 for the second inversion below */
z = moo_instantiate(moo, moo->_large_negative_integer, MOO_NULL, xs + 1); z = moo_instantiate(moo, moo->_large_negative_integer, MOO_NULL, xs + 1);
moo_popvolat (moo); moo_popvolat (moo);
if (!z) return MOO_NULL; if (MOO_UNLIKELY(!z)) return MOO_NULL;
/* the following lines roughly for 'z = moo_bitinv (moo, x)' */ /* the following lines roughly for 'z = moo_bitinv (moo, x)' */
carry = 1; carry = 1;
@ -4073,7 +4078,7 @@ static MOO_INLINE moo_oop_t rshift_negative_bigint_and_normalize (moo_t* moo, mo
moo_pushvolat (moo, &y); moo_pushvolat (moo, &y);
z = rshift_negative_bigint(moo, x, shift); z = rshift_negative_bigint(moo, x, shift);
moo_popvolat (moo); moo_popvolat (moo);
if (!z) return MOO_NULL; if (MOO_UNLIKELY(!z)) return MOO_NULL;
/* y is a negative number. use moo_addints() until it becomes 0 */ /* y is a negative number. use moo_addints() until it becomes 0 */
moo_pushvolat (moo, &z); moo_pushvolat (moo, &z);
@ -4096,7 +4101,7 @@ static MOO_INLINE moo_oop_t rshift_negative_bigint_and_normalize (moo_t* moo, mo
moo_pushvolat (moo, &y); moo_pushvolat (moo, &y);
x = normalize_bigint(moo, z); x = normalize_bigint(moo, z);
moo_popvolat (moo); moo_popvolat (moo);
if (!x) return MOO_NULL; if (MOO_UNLIKELY(!x)) return MOO_NULL;
if (MOO_OOP_IS_SMOOI(x)) if (MOO_OOP_IS_SMOOI(x))
{ {
@ -4146,7 +4151,7 @@ static MOO_INLINE moo_oop_t rshift_positive_bigint_and_normalize (moo_t* moo, mo
moo_pushvolat (moo, &y); moo_pushvolat (moo, &y);
z = clone_bigint(moo, x, zs); z = clone_bigint(moo, x, zs);
moo_popvolat (moo); moo_popvolat (moo);
if (!z) return MOO_NULL; if (MOO_UNLIKELY(!z)) return MOO_NULL;
/* for convenience in subtraction below. /* for convenience in subtraction below.
* it could be MOO_TYPE_MAX(moo_oow_t) * it could be MOO_TYPE_MAX(moo_oow_t)
@ -4208,14 +4213,14 @@ static MOO_INLINE moo_oop_t lshift_bigint_and_normalize (moo_t* moo, moo_oop_t x
moo_pushvolat (moo, &y); moo_pushvolat (moo, &y);
z = expand_bigint(moo, x, wshift); z = expand_bigint(moo, x, wshift);
moo_popvolat (moo); moo_popvolat (moo);
if (!z) return MOO_NULL; if (MOO_UNLIKELY(!z)) return MOO_NULL;
lshift_unsigned_array (MOO_OBJ_GET_LIWORD_SLOT(z), MOO_OBJ_GET_SIZE(z), shift); lshift_unsigned_array (MOO_OBJ_GET_LIWORD_SLOT(z), MOO_OBJ_GET_SIZE(z), shift);
moo_pushvolat (moo, &y); moo_pushvolat (moo, &y);
x = normalize_bigint(moo, z); x = normalize_bigint(moo, z);
moo_popvolat (moo); moo_popvolat (moo);
if (!x) return MOO_NULL; if (MOO_UNLIKELY(!x)) return MOO_NULL;
moo_pushvolat (moo, &x); moo_pushvolat (moo, &x);
y = moo_subints(moo, y, MOO_SMOOI_TO_OOP(shift)); y = moo_subints(moo, y, MOO_SMOOI_TO_OOP(shift));
@ -4271,7 +4276,7 @@ moo_oop_t moo_bitshiftint (moo_t* moo, moo_oop_t x, moo_oop_t y)
if (v2 > wshift * MOO_LIW_BITS) wshift++; if (v2 > wshift * MOO_LIW_BITS) wshift++;
z = make_bloated_bigint_with_ooi(moo, v1, wshift); z = make_bloated_bigint_with_ooi(moo, v1, wshift);
if (!z) return MOO_NULL; if (MOO_UNLIKELY(!z)) return MOO_NULL;
lshift_unsigned_array (MOO_OBJ_GET_LIWORD_SLOT(z), MOO_OBJ_GET_SIZE(z), v2); lshift_unsigned_array (MOO_OBJ_GET_LIWORD_SLOT(z), MOO_OBJ_GET_SIZE(z), v2);
return normalize_bigint(moo, z); return normalize_bigint(moo, z);
@ -4342,9 +4347,9 @@ moo_oop_t moo_bitshiftint (moo_t* moo, moo_oop_t x, moo_oop_t y)
} }
moo_pushvolat (moo, &y); moo_pushvolat (moo, &y);
x = make_bigint_with_ooi (moo, v); x = make_bigint_with_ooi(moo, v);
moo_popvolat (moo); moo_popvolat (moo);
if (!x) return MOO_NULL; if (MOO_UNLIKELY(!x)) return MOO_NULL;
goto bigint_and_bigint; goto bigint_and_bigint;
} }
@ -4429,7 +4434,7 @@ moo_oop_t moo_bitshiftint (moo_t* moo, moo_oop_t x, moo_oop_t y)
if (shift > wshift * MOO_LIW_BITS) wshift++; if (shift > wshift * MOO_LIW_BITS) wshift++;
z = expand_bigint(moo, x, wshift); z = expand_bigint(moo, x, wshift);
if (!z) return MOO_NULL; if (MOO_UNLIKELY(!z)) return MOO_NULL;
lshift_unsigned_array (MOO_OBJ_GET_LIWORD_SLOT(z), MOO_OBJ_GET_SIZE(z), shift); lshift_unsigned_array (MOO_OBJ_GET_LIWORD_SLOT(z), MOO_OBJ_GET_SIZE(z), shift);
} }
@ -4443,12 +4448,12 @@ moo_oop_t moo_bitshiftint (moo_t* moo, moo_oop_t x, moo_oop_t y)
if (negx) if (negx)
{ {
z = rshift_negative_bigint(moo, x, shift); z = rshift_negative_bigint(moo, x, shift);
if (!z) return MOO_NULL; if (MOO_UNLIKELY(!z)) return MOO_NULL;
} }
else else
{ {
z = clone_bigint(moo, x, MOO_OBJ_GET_SIZE(x)); z = clone_bigint(moo, x, MOO_OBJ_GET_SIZE(x));
if (!z) return MOO_NULL; if (MOO_UNLIKELY(!z)) return MOO_NULL;
rshift_unsigned_array (MOO_OBJ_GET_LIWORD_SLOT(z), MOO_OBJ_GET_SIZE(z), shift); rshift_unsigned_array (MOO_OBJ_GET_LIWORD_SLOT(z), MOO_OBJ_GET_SIZE(z), shift);
} }
} }
@ -4887,52 +4892,52 @@ moo_oop_t moo_sqrtint (moo_t* moo, moo_oop_t x)
moo_pushvolat (moo, &m2); moo_pushvolat (moo, &m2);
a = moo_ltints(moo, x, MOO_SMOOI_TO_OOP(0)); a = moo_ltints(moo, x, MOO_SMOOI_TO_OOP(0));
if (!a) goto oops; if (MOO_UNLIKELY(!a)) goto oops;
if (a == moo->_true) if (a == moo->_true)
{ {
/* the given number is a negative number. /* the given number is a negative number.
* i will arrange the return value to be negative. */ * i will arrange the return value to be negative. */
x = moo_negateint(moo, x); x = moo_negateint(moo, x);
if (!x) goto oops; if (MOO_UNLIKELY(!x)) goto oops;
neg = 1; neg = 1;
} }
else neg = 0; else neg = 0;
a = MOO_SMOOI_TO_OOP(1); a = MOO_SMOOI_TO_OOP(1);
b = moo_bitshiftint(moo, x, MOO_SMOOI_TO_OOP(-5)); b = moo_bitshiftint(moo, x, MOO_SMOOI_TO_OOP(-5));
if (!b) goto oops; if (MOO_UNLIKELY(!b)) goto oops;
b = moo_addints(moo, b, MOO_SMOOI_TO_OOP(8)); b = moo_addints(moo, b, MOO_SMOOI_TO_OOP(8));
if (!b) goto oops; if (MOO_UNLIKELY(!b)) goto oops;
while (1) while (1)
{ {
t = moo_geints(moo, b, a); t = moo_geints(moo, b, a);
if (!t) return MOO_NULL; if (MOO_UNLIKELY(!t)) return MOO_NULL;
if (t == moo->_false) break; if (t == moo->_false) break;
m = moo_addints(moo, a, b); m = moo_addints(moo, a, b);
if (!m) goto oops; if (MOO_UNLIKELY(!m)) goto oops;
m = moo_bitshiftint(moo, m, MOO_SMOOI_TO_OOP(-1)); m = moo_bitshiftint(moo, m, MOO_SMOOI_TO_OOP(-1));
if (!m) goto oops; if (MOO_UNLIKELY(!m)) goto oops;
m2 = moo_mulints(moo, m, m); m2 = moo_mulints(moo, m, m);
if (!m2) goto oops; if (MOO_UNLIKELY(!m2)) goto oops;
t = moo_gtints(moo, m2, x); t = moo_gtints(moo, m2, x);
if (!t) return MOO_NULL; if (MOO_UNLIKELY(!t)) return MOO_NULL;
if (t == moo->_true) if (t == moo->_true)
{ {
b = moo_subints(moo, m, MOO_SMOOI_TO_OOP(1)); b = moo_subints(moo, m, MOO_SMOOI_TO_OOP(1));
if (!b) goto oops; if (MOO_UNLIKELY(!b)) goto oops;
} }
else else
{ {
a = moo_addints(moo, m, MOO_SMOOI_TO_OOP(1)); a = moo_addints(moo, m, MOO_SMOOI_TO_OOP(1));
if (!a) goto oops; if (MOO_UNLIKELY(!a)) goto oops;
} }
} }
moo_popvolats (moo, 5); moo_popvolats (moo, 5);
x = moo_subints(moo, a, MOO_SMOOI_TO_OOP(1)); x = moo_subints(moo, a, MOO_SMOOI_TO_OOP(1));
if (!x) return MOO_NULL; if (MOO_UNLIKELY(!x)) return MOO_NULL;
if (neg) x = moo_negateint(moo, x); if (neg) x = moo_negateint(moo, x);
return x; return x;
@ -5055,7 +5060,7 @@ moo_oop_t moo_inttostr (moo_t* moo, moo_oop_t num, int flagged_radix)
if (moo->inttostr.xbuf.capa < reqcapa) if (moo->inttostr.xbuf.capa < reqcapa)
{ {
xbuf = (moo_ooch_t*)moo_reallocmem(moo, moo->inttostr.xbuf.ptr, reqcapa * MOO_SIZEOF(*xbuf)); xbuf = (moo_ooch_t*)moo_reallocmem(moo, moo->inttostr.xbuf.ptr, reqcapa * MOO_SIZEOF(*xbuf));
if (!xbuf) return MOO_NULL; if (MOO_UNLIKELY(!xbuf)) return MOO_NULL;
moo->inttostr.xbuf.capa = reqcapa; moo->inttostr.xbuf.capa = reqcapa;
moo->inttostr.xbuf.ptr = xbuf; moo->inttostr.xbuf.ptr = xbuf;
} }
@ -5067,7 +5072,7 @@ moo_oop_t moo_inttostr (moo_t* moo, moo_oop_t num, int flagged_radix)
if (moo->inttostr.t.capa < as) if (moo->inttostr.t.capa < as)
{ {
t = (moo_liw_t*)moo_reallocmem(moo, moo->inttostr.t.ptr, reqcapa * MOO_SIZEOF(*t)); t = (moo_liw_t*)moo_reallocmem(moo, moo->inttostr.t.ptr, reqcapa * MOO_SIZEOF(*t));
if (!t) return MOO_NULL; if (MOO_UNLIKELY(!t)) return MOO_NULL;
moo->inttostr.t.capa = as; moo->inttostr.t.capa = as;
moo->inttostr.t.ptr = t; moo->inttostr.t.ptr = t;
} }

View File

@ -5627,8 +5627,7 @@ static int __execute (moo_t* moo)
bx = b1; bx = b1;
MOO_ASSERT (moo, MOO_CLASSOF(moo, ctx) == moo->_method_context); MOO_ASSERT (moo, MOO_CLASSOF(moo, ctx) == moo->_method_context);
#else #else
/* otherwise, the index may point to a temporaries /* otherwise, the index may point to a temporaries declared inside a block */
* declared inside a block */
if (moo->active_context->home != moo->_nil) if (moo->active_context->home != moo->_nil)
{ {