fixed an object protection mistake in moo_divints() with regards to garbage collection
This commit is contained in:
parent
023d147e14
commit
d1bdfd75d3
151
moo/lib/bigint.c
151
moo/lib/bigint.c
@ -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);
|
||||
}
|
||||
|
||||
if (!z) return MOO_NULL;
|
||||
if (MOO_UNLIKELY(!z)) return MOO_NULL;
|
||||
MOO_OBJ_SET_LIWORD_VAL (z, 0, w);
|
||||
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);
|
||||
}
|
||||
|
||||
if (!z) return MOO_NULL;
|
||||
if (MOO_UNLIKELY(!z)) return MOO_NULL;
|
||||
MOO_OBJ_SET_LIWORD_VAL (z, 0, hw[0]);
|
||||
if (hw[1] > 0) MOO_OBJ_SET_LIWORD_VAL (z, 1, hw[1]);
|
||||
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);
|
||||
z = moo_instantiate(moo, MOO_OBJ_GET_CLASS(oop), MOO_NULL, count + inc);
|
||||
moo_popvolat (moo);
|
||||
if (!z) return MOO_NULL;
|
||||
if (MOO_UNLIKELY(!z)) return MOO_NULL;
|
||||
|
||||
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);
|
||||
z = moo_instantiate(moo, _class, MOO_NULL, count);
|
||||
moo_popvolat (moo);
|
||||
if (!z) return MOO_NULL;
|
||||
if (MOO_UNLIKELY(!z)) return MOO_NULL;
|
||||
|
||||
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;
|
||||
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 */
|
||||
if (!tmp[1]) goto oops;
|
||||
if (MOO_UNLIKELY(!tmp[1])) goto oops;
|
||||
|
||||
/* make a temporary for (a0 + a1) and (a0 * b0) */
|
||||
tmplen[0] = ndigits_xl + ndigits_yl + 1;
|
||||
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 */
|
||||
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);
|
||||
z = moo_instantiate(moo, MOO_OBJ_GET_CLASS(x), MOO_NULL, zs);
|
||||
moo_popvolats (moo, 2);
|
||||
if (!z) return MOO_NULL;
|
||||
if (MOO_UNLIKELY(!z)) return MOO_NULL;
|
||||
|
||||
add_unsigned_array (
|
||||
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);
|
||||
z = moo_instantiate(moo, moo->_large_positive_integer, MOO_NULL, MOO_OBJ_GET_SIZE(x));
|
||||
moo_popvolats (moo, 2);
|
||||
if (!z) return MOO_NULL;
|
||||
if (MOO_UNLIKELY(!z)) return MOO_NULL;
|
||||
|
||||
subtract_unsigned_array (moo,
|
||||
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);
|
||||
z = moo_instantiate(moo, moo->_large_positive_integer, MOO_NULL, xs + ys);
|
||||
moo_popvolats (moo, 2);
|
||||
if (!z) return MOO_NULL;
|
||||
if (MOO_UNLIKELY(!z)) return MOO_NULL;
|
||||
|
||||
#if defined(MOO_ENABLE_KARATSUBA)
|
||||
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);
|
||||
x = make_bigint_with_ooi(moo, v);
|
||||
moo_popvolat (moo);
|
||||
if (!x) return MOO_NULL;
|
||||
if (MOO_UNLIKELY(!x)) return MOO_NULL;
|
||||
}
|
||||
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))
|
||||
{
|
||||
z = subtract_unsigned_integers(moo, y, x);
|
||||
if (!z) return MOO_NULL;
|
||||
if (MOO_UNLIKELY(!z)) return MOO_NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -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))
|
||||
{
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
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 */
|
||||
neg = (MOO_POINTER_IS_NBIGINT(moo, x));
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -2583,7 +2583,7 @@ moo_oop_t moo_subints (moo_t* moo, moo_oop_t x, moo_oop_t y)
|
||||
moo_pushvolat (moo, &y);
|
||||
x = make_bigint_with_ooi(moo, v);
|
||||
moo_popvolat (moo);
|
||||
if (!x) return MOO_NULL;
|
||||
if (MOO_UNLIKELY(!x)) return MOO_NULL;
|
||||
}
|
||||
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);
|
||||
y = make_bigint_with_ooi(moo, v);
|
||||
moo_popvolat (moo);
|
||||
if (!y) return MOO_NULL;
|
||||
if (MOO_UNLIKELY(!y)) return MOO_NULL;
|
||||
}
|
||||
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));
|
||||
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);
|
||||
}
|
||||
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));
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
neg = (MOO_POINTER_IS_NBIGINT(moo, x));
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
* xv and yv contains actual values needed */
|
||||
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 */
|
||||
y = make_bigint_with_ooi(moo, yv);
|
||||
moo_popvolat (moo);
|
||||
if (!y) return MOO_NULL;
|
||||
if (MOO_UNLIKELY(!y)) return MOO_NULL;
|
||||
|
||||
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);
|
||||
x = make_bigint_with_ooi(moo, v);
|
||||
moo_popvolat (moo);
|
||||
if (!x) return MOO_NULL;
|
||||
if (MOO_UNLIKELY(!x)) return MOO_NULL;
|
||||
}
|
||||
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:
|
||||
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);
|
||||
if (!z) return MOO_NULL;
|
||||
if (MOO_UNLIKELY(!z)) return MOO_NULL;
|
||||
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);
|
||||
x = make_bigint_with_ooi(moo, xv);
|
||||
moo_popvolat (moo);
|
||||
if (!x) return MOO_NULL;
|
||||
if (MOO_UNLIKELY(!x)) return MOO_NULL;
|
||||
}
|
||||
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 */
|
||||
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);
|
||||
return z;
|
||||
|
||||
case -1: /* divide by -1 */
|
||||
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);
|
||||
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);
|
||||
|
||||
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);
|
||||
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;
|
||||
|
||||
z = normalize_bigint(moo, z);
|
||||
if (!z) return MOO_NULL;
|
||||
if (MOO_UNLIKELY(!z)) return MOO_NULL;
|
||||
|
||||
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)
|
||||
{
|
||||
z = moo_subints(moo, z, MOO_SMOOI_TO_OOP(1));
|
||||
if (!z) return MOO_NULL;
|
||||
if (MOO_UNLIKELY(!z)) return MOO_NULL;
|
||||
if (rem)
|
||||
{
|
||||
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);
|
||||
z = divide_unsigned_integers(moo, x, y, &r);
|
||||
moo_popvolats (moo, 2);
|
||||
if (!z) return MOO_NULL;
|
||||
if (MOO_UNLIKELY(!z)) return MOO_NULL;
|
||||
|
||||
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);
|
||||
z = normalize_bigint(moo, z);
|
||||
moo_popvolat (moo);
|
||||
if (!z) return MOO_NULL;
|
||||
if (MOO_UNLIKELY(!z)) return MOO_NULL;
|
||||
|
||||
moo_pushvolat (moo, &r);
|
||||
z = moo_subints(moo, z, MOO_SMOOI_TO_OOP(1));
|
||||
moo_popvolat (moo);
|
||||
if (!z) return MOO_NULL;
|
||||
if (MOO_UNLIKELY(!z)) return MOO_NULL;
|
||||
|
||||
*rem = r;
|
||||
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 */
|
||||
/* TODO: subtract 1 without normalization??? */
|
||||
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));
|
||||
}
|
||||
}
|
||||
@ -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 (rem) *rem = r;
|
||||
return normalize_bigint(moo, z);
|
||||
moo_pushvolat (moo, &r);
|
||||
z = normalize_bigint(moo, z);
|
||||
moo_popvolat (moo);
|
||||
|
||||
if (z && rem) *rem = r;
|
||||
|
||||
return z;
|
||||
|
||||
oops_einval:
|
||||
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);
|
||||
|
||||
moo_pushvolat (moo, &y);
|
||||
x = make_bigint_with_ooi (moo, v);
|
||||
x = make_bigint_with_ooi(moo, v);
|
||||
moo_popvolat (moo);
|
||||
if (!x) return MOO_NULL;
|
||||
if (MOO_UNLIKELY(!x)) return MOO_NULL;
|
||||
|
||||
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);
|
||||
y = make_bigint_with_ooi (moo, v);
|
||||
moo_popvolat (moo);
|
||||
if (!x) return MOO_NULL;
|
||||
if (MOO_UNLIKELY(!x)) return MOO_NULL;
|
||||
|
||||
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);
|
||||
z = moo_instantiate(moo, moo->_large_positive_integer, MOO_NULL, zalloc);
|
||||
moo_popvolats (moo, 2);
|
||||
if (!z) return MOO_NULL;
|
||||
if (MOO_UNLIKELY(!z)) return MOO_NULL;
|
||||
|
||||
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);
|
||||
x = make_bigint_with_ooi(moo, v);
|
||||
moo_popvolat (moo);
|
||||
if (!x) return MOO_NULL;
|
||||
if (MOO_UNLIKELY(!x)) return MOO_NULL;
|
||||
|
||||
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);
|
||||
y = make_bigint_with_ooi(moo, v);
|
||||
moo_popvolat (moo);
|
||||
if (!x) return MOO_NULL;
|
||||
if (MOO_UNLIKELY(!x)) return MOO_NULL;
|
||||
|
||||
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);
|
||||
z = moo_instantiate(moo, moo->_large_positive_integer, MOO_NULL, zalloc);
|
||||
moo_popvolats (moo, 2);
|
||||
if (!z) return MOO_NULL;
|
||||
if (MOO_UNLIKELY(!z)) return MOO_NULL;
|
||||
|
||||
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);
|
||||
x = make_bigint_with_ooi (moo, v);
|
||||
moo_popvolat (moo);
|
||||
if (!x) return MOO_NULL;
|
||||
if (MOO_UNLIKELY(!x)) return MOO_NULL;
|
||||
|
||||
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);
|
||||
y = make_bigint_with_ooi (moo, v);
|
||||
moo_popvolat (moo);
|
||||
if (!x) return MOO_NULL;
|
||||
if (MOO_UNLIKELY(!x)) return MOO_NULL;
|
||||
|
||||
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);
|
||||
z = moo_instantiate(moo, moo->_large_positive_integer, MOO_NULL, zalloc);
|
||||
moo_popvolats (moo, 2);
|
||||
if (!z) return MOO_NULL;
|
||||
if (MOO_UNLIKELY(!z)) return MOO_NULL;
|
||||
|
||||
if (negx && negy)
|
||||
{
|
||||
@ -3932,7 +3937,7 @@ moo_oop_t moo_bitinvint (moo_t* moo, moo_oop_t x)
|
||||
moo_pushvolat (moo, &x);
|
||||
z = moo_instantiate(moo, moo->_large_positive_integer, MOO_NULL, zalloc);
|
||||
moo_popvolat (moo);
|
||||
if (!z) return MOO_NULL;
|
||||
if (MOO_UNLIKELY(!z)) return MOO_NULL;
|
||||
|
||||
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 */
|
||||
z = moo_instantiate(moo, moo->_large_negative_integer, MOO_NULL, xs + 1);
|
||||
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)' */
|
||||
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);
|
||||
z = rshift_negative_bigint(moo, x, shift);
|
||||
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 */
|
||||
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);
|
||||
x = normalize_bigint(moo, z);
|
||||
moo_popvolat (moo);
|
||||
if (!x) return MOO_NULL;
|
||||
if (MOO_UNLIKELY(!x)) return MOO_NULL;
|
||||
|
||||
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);
|
||||
z = clone_bigint(moo, x, zs);
|
||||
moo_popvolat (moo);
|
||||
if (!z) return MOO_NULL;
|
||||
if (MOO_UNLIKELY(!z)) return MOO_NULL;
|
||||
|
||||
/* for convenience in subtraction below.
|
||||
* 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);
|
||||
z = expand_bigint(moo, x, wshift);
|
||||
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);
|
||||
|
||||
moo_pushvolat (moo, &y);
|
||||
x = normalize_bigint(moo, z);
|
||||
moo_popvolat (moo);
|
||||
if (!x) return MOO_NULL;
|
||||
if (MOO_UNLIKELY(!x)) return MOO_NULL;
|
||||
|
||||
moo_pushvolat (moo, &x);
|
||||
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++;
|
||||
|
||||
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);
|
||||
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);
|
||||
x = make_bigint_with_ooi (moo, v);
|
||||
x = make_bigint_with_ooi(moo, v);
|
||||
moo_popvolat (moo);
|
||||
if (!x) return MOO_NULL;
|
||||
if (MOO_UNLIKELY(!x)) return MOO_NULL;
|
||||
|
||||
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++;
|
||||
|
||||
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);
|
||||
}
|
||||
@ -4443,12 +4448,12 @@ moo_oop_t moo_bitshiftint (moo_t* moo, moo_oop_t x, moo_oop_t y)
|
||||
if (negx)
|
||||
{
|
||||
z = rshift_negative_bigint(moo, x, shift);
|
||||
if (!z) return MOO_NULL;
|
||||
if (MOO_UNLIKELY(!z)) return MOO_NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -4887,52 +4892,52 @@ moo_oop_t moo_sqrtint (moo_t* moo, moo_oop_t x)
|
||||
moo_pushvolat (moo, &m2);
|
||||
|
||||
a = moo_ltints(moo, x, MOO_SMOOI_TO_OOP(0));
|
||||
if (!a) goto oops;
|
||||
if (MOO_UNLIKELY(!a)) goto oops;
|
||||
if (a == moo->_true)
|
||||
{
|
||||
/* the given number is a negative number.
|
||||
* i will arrange the return value to be negative. */
|
||||
x = moo_negateint(moo, x);
|
||||
if (!x) goto oops;
|
||||
if (MOO_UNLIKELY(!x)) goto oops;
|
||||
neg = 1;
|
||||
}
|
||||
else neg = 0;
|
||||
|
||||
a = MOO_SMOOI_TO_OOP(1);
|
||||
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));
|
||||
if (!b) goto oops;
|
||||
if (MOO_UNLIKELY(!b)) goto oops;
|
||||
|
||||
while (1)
|
||||
{
|
||||
t = moo_geints(moo, b, a);
|
||||
if (!t) return MOO_NULL;
|
||||
if (MOO_UNLIKELY(!t)) return MOO_NULL;
|
||||
if (t == moo->_false) break;
|
||||
|
||||
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));
|
||||
if (!m) goto oops;
|
||||
if (MOO_UNLIKELY(!m)) goto oops;
|
||||
m2 = moo_mulints(moo, m, m);
|
||||
if (!m2) goto oops;
|
||||
if (MOO_UNLIKELY(!m2)) goto oops;
|
||||
t = moo_gtints(moo, m2, x);
|
||||
if (!t) return MOO_NULL;
|
||||
if (MOO_UNLIKELY(!t)) return MOO_NULL;
|
||||
if (t == moo->_true)
|
||||
{
|
||||
b = moo_subints(moo, m, MOO_SMOOI_TO_OOP(1));
|
||||
if (!b) goto oops;
|
||||
if (MOO_UNLIKELY(!b)) goto oops;
|
||||
}
|
||||
else
|
||||
{
|
||||
a = moo_addints(moo, m, MOO_SMOOI_TO_OOP(1));
|
||||
if (!a) goto oops;
|
||||
if (MOO_UNLIKELY(!a)) goto oops;
|
||||
}
|
||||
}
|
||||
|
||||
moo_popvolats (moo, 5);
|
||||
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);
|
||||
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)
|
||||
{
|
||||
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.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)
|
||||
{
|
||||
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.ptr = t;
|
||||
}
|
||||
|
@ -5627,8 +5627,7 @@ static int __execute (moo_t* moo)
|
||||
bx = b1;
|
||||
MOO_ASSERT (moo, MOO_CLASSOF(moo, ctx) == moo->_method_context);
|
||||
#else
|
||||
/* otherwise, the index may point to a temporaries
|
||||
* declared inside a block */
|
||||
/* otherwise, the index may point to a temporaries declared inside a block */
|
||||
|
||||
if (moo->active_context->home != moo->_nil)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user