~ chicken-core (chicken-5) 9a89a61c0830bde5962b2c34153dbf28d4da38b6
commit 9a89a61c0830bde5962b2c34153dbf28d4da38b6 Author: felix <felix@call-with-current-continuation.org> AuthorDate: Thu Nov 25 06:03:20 2010 -0500 Commit: felix <felix@call-with-current-continuation.org> CommitDate: Thu Nov 25 06:03:20 2010 -0500 more efficient inline_allocate functions for string->number and exact->inexact diff --git a/c-platform.scm b/c-platform.scm index bca49ee7..d915ebde 100644 --- a/c-platform.scm +++ b/c-platform.scm @@ -783,6 +783,8 @@ (rewrite '+ 16 2 "C_a_i_plus" #t 4) ; words-per-flonum (rewrite '- 16 2 "C_a_i_minus" #t 4) ; words-per-flonum (rewrite '/ 16 2 "C_a_i_divide" #t 4) ; words-per-flonum +(rewrite 'exact->inexact 16 1 "C_a_i_exact_to_inexact" #t 4) ; words-per-flonum + (rewrite '= 17 2 "C_i_nequalp") (rewrite '> 17 2 "C_i_greaterp") (rewrite '< 17 2 "C_i_lessp") @@ -799,8 +801,6 @@ (rewrite '>= 13 "C_greater_or_equal_p" #t) (rewrite '<= 13 "C_less_or_equal_p" #t) -(rewrite 'exact->inexact 13 "C_exact_to_inexact" #t) -(rewrite 'string->number 13 "C_string_to_number" #t) (rewrite 'number->string 13 "C_number_to_string" #t) (rewrite '##sys#call-with-current-continuation 13 "C_call_cc" #t) (rewrite '##sys#allocate-vector 13 "C_allocate_vector" #t) @@ -842,6 +842,24 @@ (rewrite 'fpceiling 16 1 "C_a_i_flonum_truncate" 'specialized words-per-flonum) (rewrite 'fpround 16 1 "C_a_i_flonum_truncate" 'specialized words-per-flonum) +(rewrite + 'string->number 8 + (lambda (db classargs cont callargs) + ;; (string->number X) -> (##core#inline_allocate ("C_a_i_string_to_number" 4) X 10) + ;; (string->number X Y) -> (##core#inline_allocate ("C_a_i_string_to_number" 4) X Y) + (define (build x y) + (make-node + '##core#call '(#t) + (list cont + (make-node + '##core#inline_allocate + '("C_a_i_string_to_number" 4) ; words-per-flonum + (list x y))))) + (case (length callargs) + ((1) (build (first callargs) (qnode 10))) + ((2) (build (first callargs) (second callargs))) + (else #f)))) + (rewrite 'cons 16 2 "C_a_i_cons" #t 3) (rewrite '##sys#cons 16 2 "C_a_i_cons" #t 3) (rewrite 'list 16 #f "C_a_i_list" #t '(3) #t) diff --git a/chicken.h b/chicken.h index 0167fd16..25cd834f 100644 --- a/chicken.h +++ b/chicken.h @@ -1676,9 +1676,9 @@ C_fctexport void C_ccall C_allocate_vector(C_word c, C_word closure, C_word k, C C_fctexport void C_ccall C_string_to_symbol(C_word c, C_word closure, C_word k, C_word string) C_noret; C_fctexport void C_ccall C_build_symbol(C_word c, C_word closure, C_word k, C_word string) C_noret; C_fctexport void C_ccall C_flonum_fraction(C_word c, C_word closure, C_word k, C_word n) C_noret; -C_fctexport void C_ccall C_exact_to_inexact(C_word c, C_word closure, C_word k, C_word n) C_noret; +C_fctexport void C_ccall C_exact_to_inexact(C_word c, C_word closure, C_word k, C_word n) C_noret; /*XXX left for binary compatibility */ C_fctexport void C_ccall C_quotient(C_word c, C_word closure, C_word k, C_word n1, C_word n2) C_noret; -C_fctexport void C_ccall C_string_to_number(C_word c, C_word closure, C_word k, C_word str, ...) C_noret; +C_fctexport void C_ccall C_string_to_number(C_word c, C_word closure, C_word k, C_word str, ...) C_noret; /*XXX left for binary compatibility */ C_fctexport void C_ccall C_number_to_string(C_word c, C_word closure, C_word k, C_word num, ...) C_noret; C_fctexport void C_ccall C_get_argv(C_word c, C_word closure, C_word k) C_noret; C_fctexport void C_ccall C_make_structure(C_word c, C_word closure, C_word k, C_word type, ...) C_noret; @@ -1830,6 +1830,8 @@ C_fctexport C_word C_fcall C_i_get_keyword(C_word key, C_word args, C_word def) C_fctexport double C_fcall C_milliseconds(void) C_regparm; C_fctexport double C_fcall C_cpu_milliseconds(void) C_regparm; C_fctexport C_word C_fcall C_a_i_cpu_time(C_word **a, int c, C_word buf) C_regparm; +C_fctexport C_word C_fcall C_a_i_string_to_number(C_word **a, int c, C_word str, C_word radix) C_regparm; +C_fctexport C_word C_fcall C_a_i_exact_to_inexact(C_word **a, int c, C_word n) C_regparm; C_fctexport C_word C_fcall C_i_foreign_char_argumentp(C_word x) C_regparm; C_fctexport C_word C_fcall C_i_foreign_fixnum_argumentp(C_word x) C_regparm; diff --git a/library.scm b/library.scm index 71fd37c7..9719e7d6 100644 --- a/library.scm +++ b/library.scm @@ -925,7 +925,7 @@ EOF (else (if (##sys#exact? n) 0 0.0) ) ) ) ;; hooks for numbers -(define ##sys#exact->inexact (##core#primitive "C_exact_to_inexact")) +(define (##sys#exact->inexact n) (##core#inline_allocate ("C_a_i_exact_to_inexact" 4) n)) (define (##sys#inexact->exact n) (##core#inline "C_i_inexact_to_exact" n)) (define exact->inexact ##sys#exact->inexact) @@ -1059,7 +1059,9 @@ EOF (##sys#lcm head (##sys#slot next 0)) (##sys#slot next 1)) #f) ) ) ) ) ) ) -(define ##sys#string->number (##core#primitive "C_string_to_number")) +(define (##sys#string->number str #!optional (radix 10)) + (##core#inline_allocate ("C_a_i_string_to_number" 4) str radix)) + (define string->number ##sys#string->number) (define ##sys#number->string (##core#primitive "C_number_to_string")) (define number->string ##sys#number->string) diff --git a/runtime.c b/runtime.c index 13df40bb..7e20f67c 100644 --- a/runtime.c +++ b/runtime.c @@ -763,7 +763,7 @@ static C_PTABLE_ENTRY *create_initial_ptable() C_pte(C_quotient); C_pte(C_flonum_fraction); C_pte(C_expt); - C_pte(C_exact_to_inexact); + C_pte(C_exact_to_inexact); /*XXX left for binary compatbility */ C_pte(C_string_to_number); C_pte(C_number_to_string); C_pte(C_make_symbol); @@ -7071,6 +7071,7 @@ void C_ccall C_flonum_fraction(C_word c, C_word closure, C_word k, C_word n) } +/* XXX left for binary compatibility */ void C_ccall C_exact_to_inexact(C_word c, C_word closure, C_word k, C_word n) { C_alloc_flonum; @@ -7087,6 +7088,18 @@ void C_ccall C_exact_to_inexact(C_word c, C_word closure, C_word k, C_word n) } +C_regparm C_word C_fcall +C_a_i_exact_to_inexact(C_word **a, int c, C_word n) +{ + if(n & C_FIXNUM_BIT) + return C_flonum(a, (double)C_unfix(n)); + else if(C_immediatep(n) || C_block_header(n) != C_FLONUM_TAG) + barf(C_BAD_ARGUMENT_TYPE_ERROR, "exact->inexact", n); + + return n; +} + + /* this is different from C_a_i_flonum_round, for R5RS compatibility */ C_regparm C_word C_fcall C_a_i_flonum_round_proper(C_word **ptr, int c, C_word n) { @@ -7155,24 +7168,16 @@ void C_ccall C_quotient(C_word c, C_word closure, C_word k, C_word n1, C_word n2 } -void C_ccall C_string_to_number(C_word c, C_word closure, C_word k, C_word str, ...) +C_regparm C_word C_fcall +C_a_i_string_to_number(C_word **a, int c, C_word str, C_word radix0) { int radix, radixpf = 0, sharpf = 0, ratp = 0, exactf, exactpf = 0, periodf = 0; - C_word n1, n, *a = C_alloc(WORDS_PER_FLONUM); + C_word n1, n; C_char *sptr, *eptr; double fn1, fn; - va_list v; - if(c == 3) radix = 10; /* default radix is 10 */ - else if(c == 4) { - va_start(v, str); - radix = va_arg(v, C_word); - va_end(v); - - if(radix & C_FIXNUM_BIT) radix = C_unfix(radix); - else barf(C_BAD_ARGUMENT_TYPE_BAD_BASE_ERROR, "string->number", radix); - } - else C_bad_argc(c, 3); + if(radix0 & C_FIXNUM_BIT) radix = C_unfix(radix0); + else barf(C_BAD_ARGUMENT_TYPE_BAD_BASE_ERROR, "string->number", radix0); if(C_immediatep(str) || C_header_bits(str) != C_STRING_TYPE) barf(C_BAD_ARGUMENT_TYPE_ERROR, "string->number", str); @@ -7254,7 +7259,7 @@ void C_ccall C_string_to_number(C_word c, C_word closure, C_word k, C_word str, case 1: /* fixnum */ if(sharpf || ratp || (exactpf && !exactf)) { - n = C_flonum(&a, ratp ? fn1 / (double)n : (double)n); + n = C_flonum(a, ratp ? fn1 / (double)n : (double)n); if(exactpf && exactf) n = C_i_inexact_to_exact(n); } @@ -7263,7 +7268,7 @@ void C_ccall C_string_to_number(C_word c, C_word closure, C_word k, C_word str, break; case 2: /* flonum */ - n = C_flonum(&a, ratp ? fn1 / fn : fn); + n = C_flonum(a, ratp ? fn1 / fn : fn); if(exactpf && exactf) n = C_i_inexact_to_exact(n); @@ -7271,7 +7276,27 @@ void C_ccall C_string_to_number(C_word c, C_word closure, C_word k, C_word str, } fini: - C_kontinue(k, n); + return n; +} + + +/* only left for backwards-compatibility */ +void C_ccall +C_string_to_number(C_word c, C_word closure, C_word k, C_word str, ...) +{ + va_list va; + C_word data[ C_SIZEOF_FLONUM + 2 ]; /* alignment */ + C_word *a = data; + C_word radix = C_fix(10); + + if(c == 4) { + va_start(va, str); + radix = va_arg(va, C_word); + va_end(va); + } + else if(c != 3) C_bad_argc(c, 3); + + C_kontinue(k, C_a_i_string_to_number(&a, 2, str, radix)); }Trap