mirror of
https://github.com/ashinn/chibi-scheme.git
synced 2025-07-05 12:16:37 +02:00
Giving a proper OOM error on arithmetic-shift with a huge shift.
This commit is contained in:
parent
a54c49d48a
commit
12b25c01ba
2 changed files with 25 additions and 17 deletions
12
bignum.c
12
bignum.c
|
@ -19,15 +19,19 @@ static int hex_digit (int n) {
|
||||||
sexp sexp_make_bignum (sexp ctx, sexp_uint_t len) {
|
sexp sexp_make_bignum (sexp ctx, sexp_uint_t len) {
|
||||||
sexp_uint_t size = sexp_sizeof(bignum) + len*sizeof(sexp_uint_t);
|
sexp_uint_t size = sexp_sizeof(bignum) + len*sizeof(sexp_uint_t);
|
||||||
sexp res = sexp_alloc_tagged(ctx, size, SEXP_BIGNUM);
|
sexp res = sexp_alloc_tagged(ctx, size, SEXP_BIGNUM);
|
||||||
sexp_bignum_length(res) = len;
|
if (!sexp_exceptionp(res)) {
|
||||||
sexp_bignum_sign(res) = 1;
|
sexp_bignum_length(res) = len;
|
||||||
|
sexp_bignum_sign(res) = 1;
|
||||||
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
sexp sexp_fixnum_to_bignum (sexp ctx, sexp a) {
|
sexp sexp_fixnum_to_bignum (sexp ctx, sexp a) {
|
||||||
sexp res = sexp_make_bignum(ctx, 1);
|
sexp res = sexp_make_bignum(ctx, 1);
|
||||||
sexp_bignum_data(res)[0] = sexp_unbox_fixnum(sexp_fx_abs(a));
|
if (!sexp_exceptionp(res)) {
|
||||||
sexp_bignum_sign(res) = sexp_fx_sign(a);
|
sexp_bignum_data(res)[0] = sexp_unbox_fixnum(sexp_fx_abs(a));
|
||||||
|
sexp_bignum_sign(res) = sexp_fx_sign(a);
|
||||||
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -215,12 +215,14 @@ static sexp sexp_arithmetic_shift (sexp ctx, sexp self, sexp_sint_t n, sexp i, s
|
||||||
res = sexp_make_fixnum(sexp_bignum_sign(i) > 0 ? 0 : -1);
|
res = sexp_make_fixnum(sexp_bignum_sign(i) > 0 ? 0 : -1);
|
||||||
} else {
|
} else {
|
||||||
res = sexp_make_bignum(ctx, len - offset + 1);
|
res = sexp_make_bignum(ctx, len - offset + 1);
|
||||||
sexp_bignum_sign(res) = sexp_bignum_sign(i);
|
if (!sexp_exceptionp(res)) {
|
||||||
for (j=len-offset-1, tmp=0; j>=0; j--) {
|
sexp_bignum_sign(res) = sexp_bignum_sign(i);
|
||||||
sexp_bignum_data(res)[j]
|
for (j=len-offset-1, tmp=0; j>=0; j--) {
|
||||||
= (sexp_bignum_data(i)[j+offset] >> bit_shift)+ tmp;
|
sexp_bignum_data(res)[j]
|
||||||
tmp = sexp_bignum_data(i)[j+offset]
|
= (sexp_bignum_data(i)[j+offset] >> bit_shift)+ tmp;
|
||||||
<< (sizeof(sexp_uint_t)*CHAR_BIT-bit_shift);
|
tmp = sexp_bignum_data(i)[j+offset]
|
||||||
|
<< (sizeof(sexp_uint_t)*CHAR_BIT-bit_shift);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -228,14 +230,16 @@ static sexp sexp_arithmetic_shift (sexp ctx, sexp self, sexp_sint_t n, sexp i, s
|
||||||
bit_shift = c - offset*(sizeof(sexp_uint_t)*CHAR_BIT);
|
bit_shift = c - offset*(sizeof(sexp_uint_t)*CHAR_BIT);
|
||||||
tail_shift = (sizeof(sexp_uint_t)*CHAR_BIT-bit_shift);
|
tail_shift = (sizeof(sexp_uint_t)*CHAR_BIT-bit_shift);
|
||||||
res = sexp_make_bignum(ctx, len + offset + 1);
|
res = sexp_make_bignum(ctx, len + offset + 1);
|
||||||
sexp_bignum_sign(res) = sexp_bignum_sign(i);
|
if (!sexp_exceptionp(res)) {
|
||||||
for (j=tmp=0; j<len; j++) {
|
sexp_bignum_sign(res) = sexp_bignum_sign(i);
|
||||||
sexp_bignum_data(res)[j+offset]
|
for (j=tmp=0; j<len; j++) {
|
||||||
= (sexp_bignum_data(i)[j] << bit_shift) + tmp;
|
sexp_bignum_data(res)[j+offset]
|
||||||
if (bit_shift != 0)
|
= (sexp_bignum_data(i)[j] << bit_shift) + tmp;
|
||||||
tmp = sexp_bignum_data(i)[j] >> tail_shift;
|
if (bit_shift != 0)
|
||||||
|
tmp = sexp_bignum_data(i)[j] >> tail_shift;
|
||||||
|
}
|
||||||
|
if (bit_shift != 0) sexp_bignum_data(res)[len+offset] = tmp;
|
||||||
}
|
}
|
||||||
if (bit_shift != 0) sexp_bignum_data(res)[len+offset] = tmp;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Add table
Reference in a new issue