From 670d5a0e989c4527e2f9b4e0a813ad1530b30349 Mon Sep 17 00:00:00 2001 From: Justin Ethier Date: Thu, 16 Feb 2017 04:01:00 -0500 Subject: [PATCH] Improve range checks --- include/cyclone/types.h | 3 +++ runtime.c | 23 +++++++++++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/include/cyclone/types.h b/include/cyclone/types.h index 5e43a96e..9b3b4868 100644 --- a/include/cyclone/types.h +++ b/include/cyclone/types.h @@ -270,6 +270,9 @@ struct gc_thread_data_t { #define is_value_type(x) ((unsigned long)(x) & (unsigned long)3) #define is_object_type(x) (x && !is_value_type(x)) +#define CYC_FIXNUM_MAX 1073741823 +#define CYC_FIXNUM_MIN -1073741824 + /* Function type */ typedef void (*function_type) (); diff --git a/runtime.c b/runtime.c index 58cc7ebe..901749c3 100644 --- a/runtime.c +++ b/runtime.c @@ -1814,9 +1814,9 @@ str2int_errno str2int(int *out, char *s, int base) errno = 0; long l = strtol(s, &end, base); /* Both checks are needed because INT_MAX == LONG_MAX is possible. */ - if (l > INT_MAX || (errno == ERANGE && l == LONG_MAX)) + if (l > CYC_FIXNUM_MAX /*INT_MAX*/ || (errno == ERANGE && l == LONG_MAX)) return STR2INT_OVERFLOW; - if (l < INT_MIN || (errno == ERANGE && l == LONG_MIN)) + if (l < CYC_FIXNUM_MIN /*INT_MIN*/ || (errno == ERANGE && l == LONG_MIN)) return STR2INT_UNDERFLOW; if (*end != '\0') return STR2INT_INCONVERTIBLE; @@ -3089,6 +3089,25 @@ bad_arg_type_error: } } +object Cyc_expt(void *data, object cont, object z1, object z2) +{ + // TODO: if either is double, promote result to double + // if both int, do mp_expt_d and normalize back to fixnum if necessary +// c = a **b +// int mp_expt_d(mp_int *a, mp_digit b, mp_int *c); + make_double(d, 0.0); + Cyc_check_num(data, z1); + Cyc_check_num(data, z2); + d.value = pow( unbox_number(z1), unbox_number(z2) ); + return_closcall1(data, cont, &d); +} + +// TODO: convert bignum back to fixnum if possible +object Cyc_bignum_normalize(void *data, object n) +{ + return n; +} + /* I/O functions */ port_type Cyc_stdout()