~ chicken-core (chicken-5) 4b517f9e64b0bb209de261a7f15072009016be2d


commit 4b517f9e64b0bb209de261a7f15072009016be2d
Author:     Peter Bex <peter@more-magic.net>
AuthorDate: Thu Mar 19 22:25:58 2015 +0100
Commit:     Peter Bex <peter@more-magic.net>
CommitDate: Sun May 31 14:55:23 2015 +0200

    Convert generic negate and abs procedures to inlinable scratchspace-based versions

diff --git a/chicken.h b/chicken.h
index 8d85947a..d66cc772 100644
--- a/chicken.h
+++ b/chicken.h
@@ -538,7 +538,8 @@ static inline int isinf_ld (long double x)
 
 /* This is for convenience and allows flexibility in representation */
 #define C_SIZEOF_FIX_BIGNUM       C_SIZEOF_BIGNUM(1)
-#define C_SIZEOF_BIGNUM(n)        (C_SIZEOF_INTERNAL_BIGNUM_VECTOR(n)+C_SIZEOF_STRUCTURE(2))
+#define C_SIZEOF_BIGNUM_WRAPPER   C_SIZEOF_STRUCTURE(2)
+#define C_SIZEOF_BIGNUM(n)        (C_SIZEOF_INTERNAL_BIGNUM_VECTOR(n)+C_SIZEOF_BIGNUM_WRAPPER)
 
 /* Fixed size types have pre-computed header tags */
 #define C_PAIR_TAG                (C_PAIR_TYPE | (C_SIZEOF_PAIR - 1))
@@ -694,6 +695,7 @@ static inline int isinf_ld (long double x)
 #define C_BAD_ARGUMENT_TYPE_COMPLEX_NO_ORDERING_ERROR 51
 #define C_BAD_ARGUMENT_TYPE_NO_EXACT_INTEGER_ERROR    52
 #define C_BAD_ARGUMENT_TYPE_FOREIGN_LIMITATION        53
+#define C_BAD_ARGUMENT_TYPE_COMPLEX_ABS               54
 
 /* Platform information */
 #if defined(C_BIG_ENDIAN)
@@ -1944,7 +1946,6 @@ C_fctexport C_char *C_private_repository_path();
 C_fctimport void C_ccall C_toplevel(C_word c, C_word self, C_word k) C_noret;
 C_fctimport void C_ccall C_invalid_procedure(int c, C_word self, ...) C_noret;
 C_fctexport void C_ccall C_stop_timer(C_word c, C_word closure, C_word k) C_noret;
-C_fctexport void C_ccall C_abs(C_word c, C_word self, C_word k, C_word x) C_noret;
 C_fctexport void C_ccall C_signum(C_word c, C_word self, C_word k, C_word x) C_noret;
 C_fctexport void C_ccall C_apply(C_word c, C_word closure, C_word k, C_word fn, ...) C_noret;
 C_fctexport void C_ccall C_do_apply(C_word n, C_word closure, C_word k) C_noret;
@@ -1964,7 +1965,6 @@ C_fctexport void C_ccall C_2_basic_plus(C_word c, C_word self, C_word k, C_word
 C_fctexport void C_ccall C_u_2_integer_plus(C_word c, C_word self, C_word k, C_word x, C_word y) C_noret;
 /* XXX TODO OBSOLETE: This can be removed after recompiling c-platform.scm */
 C_fctexport void C_ccall C_minus(C_word c, C_word closure, C_word k, C_word n1, ...) C_noret;
-C_fctexport void C_ccall C_negate(C_word c, C_word self, C_word k, C_word x) C_noret;
 C_fctexport void C_ccall C_2_basic_minus(C_word c, C_word self, C_word k, C_word x, C_word y) C_noret;
 C_fctexport void C_ccall C_u_2_integer_minus(C_word c, C_word self, C_word k, C_word x, C_word y) C_noret;
 /* XXX TODO OBSOLETE: This can be removed after recompiling c-platform.scm */
@@ -2184,6 +2184,8 @@ C_fctexport C_word C_fcall C_a_i_string_to_number(C_word **a, int c, C_word str,
 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_file_exists_p(C_word name, C_word file, C_word dir) C_regparm;
 
+C_fctexport C_word C_fcall C_s_a_i_abs(C_word **ptr, C_word n, C_word x) C_regparm;
+C_fctexport C_word C_fcall C_s_a_i_negate(C_word **ptr, C_word n, C_word x) C_regparm;
 C_fctexport C_word C_fcall C_s_a_u_i_integer_negate(C_word **ptr, C_word n, C_word x) C_regparm;
 
 
@@ -2431,6 +2433,17 @@ C_inline C_word C_a_i_record8(C_word **ptr, int n, C_word x1, C_word x2, C_word
   return (C_word)p0;
 }
 
+C_inline C_word C_cplxnum(C_word **ptr, C_word x, C_word y)
+{
+  return C_a_i_record3(ptr, 2, C_cplxnum_type_tag, x, y);
+}
+
+C_inline C_word C_ratnum(C_word **ptr, C_word x, C_word y)
+{
+  return C_a_i_record3(ptr, 2, C_ratnum_type_tag, x, y);
+}
+
+
 /* Silly (this is not normalized) but in some cases needed internally */
 C_inline C_word C_bignum0(C_word **ptr)
 {
diff --git a/library.scm b/library.scm
index ece34b4f..0acbc0f0 100644
--- a/library.scm
+++ b/library.scm
@@ -1188,19 +1188,10 @@ EOF
 
 ;;; Basic arithmetic:
 
-(define abs (##core#primitive "C_abs"))
+(define (abs x) (##core#inline_allocate ("C_s_a_i_abs" 10) x))
 ;; OBSOLETE: Remove this (or change to define-inline)
 (define (##sys#integer-abs x)
   (##core#inline_allocate ("C_s_a_u_i_integer_abs" 6) x))
-(define (##sys#extended-abs x)
-  (cond ((ratnum? x)
-         (%make-ratnum (##sys#integer-abs (%ratnum-numerator x))
-		       (%ratnum-denominator x)))
-        ((cplxnum? x)
-         (##sys#signal-hook
-          #:type-error 'abs
-          "can not compute absolute value of complex number" x))
-        (else (##sys#error-bad-number x 'abs))))
 
 (define (+ . args)
   (if (null? args) 
@@ -1244,7 +1235,8 @@ EOF
                (%make-ratnum numerator d))))
         (else (##sys#error-bad-number y '+)) ) )
 
-(define ##sys#negate (##core#primitive "C_negate"))
+;; OBSOLETE: Remove this (or change to define-inline)
+(define (##sys#negate x) (##core#inline_allocate ("C_s_a_i_negate" 36) x))
 ;; OBSOLETE: Remove this (or change to define-inline)
 (define (##sys#integer-negate x)
   (##core#inline_allocate ("C_s_a_u_i_integer_negate" 6) x))
@@ -1262,15 +1254,6 @@ EOF
 (define ##sys#--2 (##core#primitive "C_2_basic_minus"))
 (define ##sys#integer-minus (##core#primitive "C_u_2_integer_minus"))
 
-(define (##sys#extended-negate x)
-  (cond ((ratnum? x)
-         (%make-ratnum (##sys#integer-negate (%ratnum-numerator x))
-                       (%ratnum-denominator x)))
-        ((cplxnum? x)
-         (make-complex (##sys#negate (%cplxnum-real x))
-		       (##sys#negate (%cplxnum-imag x))))
-        (else (##sys#error-bad-number x '-)) ) ) ; loc?
-
 (define (##sys#extended-minus x y)
   (cond ((or (cplxnum? x) (cplxnum? y))
          ;; Just subtract real and imag parts from eachother
@@ -5444,6 +5427,7 @@ EOF
 	((51) (apply ##sys#signal-hook #:type-error loc "bad argument type - complex number has no ordering" args))
 	((52) (apply ##sys#signal-hook #:type-error loc "bad argument type - not an exact integer" args))
 	((53) (apply ##sys#signal-hook #:type-error loc "number does not fit in foreign type" args))
+	((54) (apply ##sys#signal-hook #:type-error loc "cannot compute absolute value of complex number" args))
 	(else (apply ##sys#signal-hook #:runtime-error loc "unknown internal error" args)) ) ) ) )
 
 
diff --git a/runtime.c b/runtime.c
index 1008727a..908ea064 100644
--- a/runtime.c
+++ b/runtime.c
@@ -842,7 +842,7 @@ static C_PTABLE_ENTRY *create_initial_ptable()
 {
   /* IMPORTANT: hardcoded table size -
      this must match the number of C_pte calls + 1 (NULL terminator)! */
-  C_PTABLE_ENTRY *pt = (C_PTABLE_ENTRY *)C_malloc(sizeof(C_PTABLE_ENTRY) * 78);
+  C_PTABLE_ENTRY *pt = (C_PTABLE_ENTRY *)C_malloc(sizeof(C_PTABLE_ENTRY) * 76);
   int i = 0;
 
   if(pt == NULL)
@@ -913,8 +913,6 @@ static C_PTABLE_ENTRY *create_initial_ptable()
   C_pte(C_flonum_to_string);
   /* IMPORTANT: have you read the comments at the start and the end of this function? */
   C_pte(C_signum);
-  C_pte(C_abs);
-  C_pte(C_negate);
   C_pte(C_2_basic_plus);
   C_pte(C_2_basic_minus);
   C_pte(C_2_basic_times);
@@ -1871,6 +1869,11 @@ void barf(int code, char *loc, ...)
     c = 1;
     break;
 
+  case C_BAD_ARGUMENT_TYPE_COMPLEX_ABS:
+    msg = C_text("cannot compute absolute value of complex number");
+    c = 1;
+    break;
+
   default: panic(C_text("illegal internal error code"));
   }
   
@@ -5657,23 +5660,27 @@ C_regparm C_word C_fcall C_i_vector_set(C_word v, C_word i, C_word x)
   return C_SCHEME_UNDEFINED;
 }
 
-void C_ccall C_abs(C_word c, C_word self, C_word k, C_word x)
+/* This needs at most C_SIZEOF_FIX_BIGNUM + C_SIZEOF_STRUCTURE(3) so 10 words */
+C_regparm C_word C_fcall
+C_s_a_i_abs(C_word **ptr, C_word n, C_word x)
 {
-  if (c != 3) {
-    C_bad_argc_2(c, 3, self);
-  } else if (x & C_FIXNUM_BIT) {
-    C_word *a = C_alloc(C_SIZEOF_FIX_BIGNUM);
-    C_kontinue(k, C_a_i_fixnum_abs(&a, 1, x));
+  if (x & C_FIXNUM_BIT) {
+    return C_a_i_fixnum_abs(ptr, 1, x);
   } else if (C_immediatep(x)) {
     barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "abs", x);
   } else if (C_block_header(x) == C_FLONUM_TAG) {
-    C_word *a = C_alloc(C_SIZEOF_FLONUM);
-    C_kontinue(k, C_a_i_flonum_abs(&a, 1, x));
+    return C_a_i_flonum_abs(ptr, 1, x);
   } else if (C_truep(C_bignump(x))) {
-    C_word *a = C_alloc(C_SIZEOF_FIX_BIGNUM);
-    C_kontinue(k, C_s_a_u_i_integer_abs(&a, 1, x));
+    return C_s_a_u_i_integer_abs(ptr, 1, x);
+  } else if (C_block_header(x) == C_STRUCTURE3_TAG &&
+             (C_block_item(x, 0) == C_ratnum_type_tag)) {
+    return C_ratnum(ptr, C_s_a_u_i_integer_abs(ptr, 1, C_block_item(x, 1)),
+                    C_block_item(x, 2));
+  } else if (C_block_header(x) == C_STRUCTURE3_TAG &&
+             (C_block_item(x, 0) == C_cplxnum_type_tag)) {
+    barf(C_BAD_ARGUMENT_TYPE_COMPLEX_ABS, "abs", x);
   } else {
-    try_extended_number("\003sysextended-abs", 2, k, x);
+    barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "abs", x);
   }
 }
 
@@ -5707,21 +5714,31 @@ C_regparm C_word C_fcall C_a_i_abs(C_word **a, int c, C_word x)
   return C_flonum(a, fabs(C_flonum_magnitude(x)));
 }
 
-void C_ccall C_negate(C_word c, C_word self, C_word k, C_word x)
+/* The maximum this can allocate is a cplxnum which consists of two
+ * ratnums that consist of 2 fix bignums each.  So that's
+ * C_SIZEOF_STRUCTURE(3) * 3 + C_SIZEOF_FIX_BIGNUM * 4 = 36 words!
+ */
+C_regparm C_word C_fcall
+C_s_a_i_negate(C_word **ptr, C_word n, C_word x)
 {
   if (x & C_FIXNUM_BIT) {
-    C_word *a = C_alloc(C_SIZEOF_FIX_BIGNUM);
-    C_kontinue(k, C_a_i_fixnum_negate(&a, 1, x));
+    return C_a_i_fixnum_negate(ptr, 1, x);
   } else if (C_immediatep(x)) {
     barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "-", x);
   } else if (C_block_header(x) == C_FLONUM_TAG) {
-    C_word *a = C_alloc(C_SIZEOF_FLONUM);
-    C_kontinue(k, C_a_i_flonum_negate(&a, 1, x));
+    return C_a_i_flonum_negate(ptr, 1, x);
   } else if (C_truep(C_bignump(x))) {
-    C_word *a = C_alloc(C_SIZEOF_FIX_BIGNUM);
-    C_kontinue(k, C_s_a_u_i_integer_negate(&a, 1, x));
+    return C_s_a_u_i_integer_negate(ptr, 1, x);
+  } else if (C_block_header(x) == C_STRUCTURE3_TAG &&
+             (C_block_item(x, 0) == C_ratnum_type_tag)) {
+    return C_ratnum(ptr, C_s_a_u_i_integer_negate(ptr, 1, C_block_item(x, 1)),
+                    C_block_item(x, 2));
+  } else if (C_block_header(x) == C_STRUCTURE3_TAG &&
+             (C_block_item(x, 0) == C_cplxnum_type_tag)) {
+    return C_cplxnum(ptr, C_s_a_i_negate(ptr, 1, C_block_item(x, 1)),
+                     C_s_a_i_negate(ptr, 1, C_block_item(x, 2)));
   } else {
-    try_extended_number("\003sysextended-negate", 2, k, x);
+    barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "-", x);
   }
 }
 
diff --git a/types.db b/types.db
index e309d943..e12706f9 100644
--- a/types.db
+++ b/types.db
@@ -328,7 +328,7 @@
    ((integer) (integer)
     (##core#inline_allocate ("C_s_a_u_i_integer_negate" 6) #(1)))
    ((float) (float) (##core#inline_allocate ("C_a_i_flonum_negate" 4) #(1)))
-   ((number) (number) (##sys#negate #(1)))
+   ((*) (*) (##core#inline_allocate ("C_s_a_i_negate" 36) #(1)))
    ((float fixnum) (float)
     (##core#inline_allocate 
      ("C_a_i_flonum_difference" 4) 
@@ -501,7 +501,9 @@
      ((fixnum) (integer) (##core#inline_allocate ("C_a_i_fixnum_abs" 6) #(1)))
      ((float) (float) (##core#inline_allocate ("C_a_i_flonum_abs" 4) #(1)))
      ((integer) (integer)
-      (##core#inline_allocate ("C_s_a_u_i_integer_abs" 6) #(1))))
+      (##core#inline_allocate ("C_s_a_u_i_integer_abs" 6) #(1)))
+     ((*) (*)
+      (##core#inline_allocate ("C_s_a_i_abs" 10) #(1))))
 
 (floor (#(procedure #:clean #:enforce #:foldable) floor ((or integer ratnum float)) (or integer ratnum float))
        ((fixnum) (fixnum) #(1))
@@ -797,7 +799,8 @@
 	   ((fixnum) (integer) (##core#inline_allocate ("C_a_i_fixnum_abs" 6) #(1)))
 	   ((integer) (##core#inline_allocate ("C_s_a_u_i_integer_abs" 6) #(1)))
 	   ((float) (float) (##core#inline_allocate ("C_a_i_flonum_abs" 4) #(1)))
-	   (((or fixnum float bignum ratnum)) (abs #(1))))
+	   (((or fixnum float bignum ratnum))
+	    (##core#inline_allocate ("C_s_a_i_abs" 10) #(1))))
 
 (angle (#(procedure #:clean #:enforce #:foldable) angle (number) float)
        ((float) (##core#inline_allocate ("C_a_i_flonum_atan2" 4) '0.0 #(1)))
Trap