VM: bignum_to_fixnum_strict and an accompanying vm error in case the conversion fails

db4
Björn Lindqvist 2014-06-03 18:52:38 +02:00
parent 877e3a12e1
commit a9a52d9174
6 changed files with 22 additions and 3 deletions

View File

@ -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. ]

View File

@ -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

View File

@ -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); \

View File

@ -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,

View File

@ -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 */

View File

@ -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();