VM: bignum_to_fixnum_strict and an accompanying vm error in case the conversion fails
parent
877e3a12e1
commit
a9a52d9174
|
@ -101,6 +101,9 @@ HOOK: signal-error. os ( obj -- )
|
||||||
"Invalid array size: " write dup third .
|
"Invalid array size: " write dup third .
|
||||||
"Maximum: " write fourth 1 - . ;
|
"Maximum: " write fourth 1 - . ;
|
||||||
|
|
||||||
|
: fixnum-range-error. ( obj -- )
|
||||||
|
"Cannot convert to fixnum: " write third . ;
|
||||||
|
|
||||||
: c-string-error. ( obj -- )
|
: c-string-error. ( obj -- )
|
||||||
"Cannot convert to C string: " write third . ;
|
"Cannot convert to C string: " write third . ;
|
||||||
|
|
||||||
|
@ -156,6 +159,7 @@ PREDICATE: vm-error < array
|
||||||
[ divide-by-zero-error. ]
|
[ divide-by-zero-error. ]
|
||||||
[ signal-error. ]
|
[ signal-error. ]
|
||||||
[ array-size-error. ]
|
[ array-size-error. ]
|
||||||
|
[ fixnum-range-error. ]
|
||||||
[ c-string-error. ]
|
[ c-string-error. ]
|
||||||
[ ffi-error. ]
|
[ ffi-error. ]
|
||||||
[ undefined-symbol-error. ]
|
[ undefined-symbol-error. ]
|
||||||
|
|
|
@ -19,3 +19,5 @@ IN: arrays.tests
|
||||||
|
|
||||||
[ -1 f <array> ] must-fail
|
[ -1 f <array> ] must-fail
|
||||||
[ cell-bits cell log2 - 2^ f <array> ] must-fail
|
[ cell-bits cell log2 - 2^ f <array> ] must-fail
|
||||||
|
! To big for a fixnum #1045
|
||||||
|
[ 67 2^ 3 <array> ] must-fail
|
||||||
|
|
|
@ -383,6 +383,17 @@ BIGNUM_TO_FOO(fixnum, fixnum, fixnum, cell)
|
||||||
BIGNUM_TO_FOO(long_long, int64_t, int64_t, uint64_t)
|
BIGNUM_TO_FOO(long_long, int64_t, int64_t, uint64_t)
|
||||||
BIGNUM_TO_FOO(ulong_long, uint64_t, int64_t, uint64_t)
|
BIGNUM_TO_FOO(ulong_long, uint64_t, int64_t, uint64_t)
|
||||||
|
|
||||||
|
/* does allocate memory */
|
||||||
|
fixnum factor_vm::bignum_to_fixnum_strict(bignum* bignum_in) {
|
||||||
|
fixnum fix = bignum_to_fixnum(bignum_in);
|
||||||
|
bignum* bignum_out = fixnum_to_bignum(fix);
|
||||||
|
GC_BIGNUM(bignum_out);
|
||||||
|
if (bignum_compare(bignum_in, bignum_out) != bignum_comparison_equal) {
|
||||||
|
general_error(ERROR_OUT_OF_FIXNUM_RANGE, tag<bignum>(bignum_in), false_object);
|
||||||
|
}
|
||||||
|
return fix;
|
||||||
|
}
|
||||||
|
|
||||||
#define DTB_WRITE_DIGIT(factor) \
|
#define DTB_WRITE_DIGIT(factor) \
|
||||||
{ \
|
{ \
|
||||||
significand *= (factor); \
|
significand *= (factor); \
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
namespace factor {
|
namespace factor {
|
||||||
|
|
||||||
// Runtime errors must be kept in sync with:
|
// Runtime errors must be kept in sync with:
|
||||||
|
// basis/debugger/debugger.factor
|
||||||
// core/kernel/kernel.factor
|
// core/kernel/kernel.factor
|
||||||
enum vm_error_type {
|
enum vm_error_type {
|
||||||
ERROR_EXPIRED = 0,
|
ERROR_EXPIRED = 0,
|
||||||
|
@ -10,6 +11,7 @@ enum vm_error_type {
|
||||||
ERROR_DIVIDE_BY_ZERO,
|
ERROR_DIVIDE_BY_ZERO,
|
||||||
ERROR_SIGNAL,
|
ERROR_SIGNAL,
|
||||||
ERROR_ARRAY_SIZE,
|
ERROR_ARRAY_SIZE,
|
||||||
|
ERROR_OUT_OF_FIXNUM_RANGE,
|
||||||
ERROR_C_STRING,
|
ERROR_C_STRING,
|
||||||
ERROR_FFI,
|
ERROR_FFI,
|
||||||
ERROR_UNDEFINED_SYMBOL,
|
ERROR_UNDEFINED_SYMBOL,
|
||||||
|
|
|
@ -277,13 +277,13 @@ void factor_vm::primitive_bits_double() {
|
||||||
ctx->push(allot_float(bits_double(to_unsigned_8(ctx->pop()))));
|
ctx->push(allot_float(bits_double(to_unsigned_8(ctx->pop()))));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cannot allocate */
|
/* Allocates memory */
|
||||||
fixnum factor_vm::to_fixnum(cell tagged) {
|
fixnum factor_vm::to_fixnum(cell tagged) {
|
||||||
switch (TAG(tagged)) {
|
switch (TAG(tagged)) {
|
||||||
case FIXNUM_TYPE:
|
case FIXNUM_TYPE:
|
||||||
return untag_fixnum(tagged);
|
return untag_fixnum(tagged);
|
||||||
case BIGNUM_TYPE:
|
case BIGNUM_TYPE:
|
||||||
return bignum_to_fixnum(untag<bignum>(tagged));
|
return bignum_to_fixnum_strict(untag<bignum>(tagged));
|
||||||
default:
|
default:
|
||||||
type_error(FIXNUM_TYPE, tagged);
|
type_error(FIXNUM_TYPE, tagged);
|
||||||
return 0; /* can't happen */
|
return 0; /* can't happen */
|
||||||
|
|
|
@ -239,6 +239,7 @@ struct factor_vm {
|
||||||
bignum* bignum_quotient(bignum* numerator, bignum* denominator);
|
bignum* bignum_quotient(bignum* numerator, bignum* denominator);
|
||||||
bignum* bignum_remainder(bignum* numerator, bignum* denominator);
|
bignum* bignum_remainder(bignum* numerator, bignum* denominator);
|
||||||
cell bignum_to_cell(bignum* bignum);
|
cell bignum_to_cell(bignum* bignum);
|
||||||
|
fixnum bignum_to_fixnum_strict(bignum* bignum);
|
||||||
fixnum bignum_to_fixnum(bignum* bignum);
|
fixnum bignum_to_fixnum(bignum* bignum);
|
||||||
int64_t bignum_to_long_long(bignum* bignum);
|
int64_t bignum_to_long_long(bignum* bignum);
|
||||||
uint64_t bignum_to_ulong_long(bignum* bignum);
|
uint64_t bignum_to_ulong_long(bignum* bignum);
|
||||||
|
@ -505,7 +506,6 @@ struct factor_vm {
|
||||||
void primitive_bignum_bitp();
|
void primitive_bignum_bitp();
|
||||||
void primitive_bignum_log2();
|
void primitive_bignum_log2();
|
||||||
inline cell unbox_array_size();
|
inline cell unbox_array_size();
|
||||||
cell unbox_array_size_slow();
|
|
||||||
void primitive_fixnum_to_float();
|
void primitive_fixnum_to_float();
|
||||||
void primitive_format_float();
|
void primitive_format_float();
|
||||||
void primitive_float_eq();
|
void primitive_float_eq();
|
||||||
|
|
Loading…
Reference in New Issue