~ chicken-core (chicken-5) eb07a140d8959d88aa848b6c79c2469d0b476416


commit eb07a140d8959d88aa848b6c79c2469d0b476416
Author:     felix <felix@call-with-current-continuation.org>
AuthorDate: Fri Jan 14 04:54:32 2011 -0500
Commit:     felix <felix@call-with-current-continuation.org>
CommitDate: Fri Jan 14 04:54:32 2011 -0500

    foreign-argument checks for 64-bit integer types where insufficient (thanks to Kon Lovett)

diff --git a/chicken.h b/chicken.h
index aa1654f9..af60209e 100644
--- a/chicken.h
+++ b/chicken.h
@@ -776,6 +776,10 @@ DECL_C_PROC_p0 (128,  1,0,0,0,0,0,0,0)
 # define C_UWORD_MAX               UINT_MAX
 #endif
 
+#define C_WORD64_MIN               LLONG_MIN
+#define C_WORD64_MAX               LLONG_MAX
+#define C_UWORD64_MAX              ULLONG_MAX
+
 #ifndef C_PROVIDE_LIBC_STUBS
 # define C_FILEPTR                  FILE *
 
@@ -1803,6 +1807,8 @@ C_fctexport C_word C_fcall C_i_foreign_pointer_argumentp(C_word x) C_regparm;
 C_fctexport C_word C_fcall C_i_foreign_scheme_or_c_pointer_argumentp(C_word x) C_regparm;
 C_fctexport C_word C_fcall C_i_foreign_integer_argumentp(C_word x) C_regparm;
 C_fctexport C_word C_fcall C_i_foreign_unsigned_integer_argumentp(C_word x) C_regparm;
+C_fctexport C_word C_fcall C_i_foreign_integer64_argumentp(C_word x) C_regparm;
+C_fctexport C_word C_fcall C_i_foreign_unsigned_integer64_argumentp(C_word x) C_regparm;
 
 C_fctexport C_char *C_lookup_procedure_id(void *ptr);
 C_fctexport void *C_lookup_procedure_ptr(C_char *id);
diff --git a/library.scm b/library.scm
index 22e34e29..df45376b 100644
--- a/library.scm
+++ b/library.scm
@@ -4145,7 +4145,13 @@ EOF
 (define (##sys#foreign-pointer-argument x) (##core#inline "C_i_foreign_pointer_argumentp" x))
 (define (##sys#foreign-tagged-pointer-argument x tx) (##core#inline "C_i_foreign_tagged_pointer_argumentp" x tx))
 (define (##sys#foreign-integer-argument x) (##core#inline "C_i_foreign_integer_argumentp" x))
-(define (##sys#foreign-unsigned-integer-argument x) (##core#inline "C_i_foreign_unsigned_integer_argumentp" x))
+(define (##sys#foreign-integer64-argument x) (##core#inline "C_i_foreign_integer64_argumentp" x))
+
+(define (##sys#foreign-unsigned-integer64-argument x)
+  (##core#inline "C_i_foreign_unsigned_integer64_argumentp" x))
+
+(define (##sys#foreign-unsigned-integer64-argument x)
+  (##core#inline "C_i_foreign_unsigned_integer64_argumentp" x))
 
 
 ;;; Low-level threading interface:
diff --git a/manual/Non-standard macros and special forms b/manual/Non-standard macros and special forms
index 4d4e4923..939fce20 100644
--- a/manual/Non-standard macros and special forms	
+++ b/manual/Non-standard macros and special forms	
@@ -230,6 +230,12 @@ Binds the parameters {{PARAMETER1 ...}} dynamically to the values
 {{make-parameter}} in [[Parameters]]). Note that {{PARAMETER}} may be any
 expression that evaluates to a parameter procedure.
 
+Note: due to a bug in the implementation of {{parameterize}},
+restoring the previous parameter values does reinvoke the guard
+procedure of the parameter, if it has any. If the guard procedure
+performs a conversion, then the conversion will be reinvoked
+on restoration of the old value.
+
 ==== receive
 
 <macro>(receive (NAME ...) VALUEEXP BODY ...)</macro><br>
diff --git a/runtime.c b/runtime.c
index 03a85f35..18f10b52 100644
--- a/runtime.c
+++ b/runtime.c
@@ -5675,6 +5675,23 @@ C_regparm C_word C_fcall C_i_foreign_integer_argumentp(C_word x)
 }
 
 
+C_regparm C_word C_fcall C_i_foreign_integer64_argumentp(C_word x)
+{
+  double m;
+
+  if((x & C_FIXNUM_BIT) != 0) return x;
+
+  if(!C_immediatep(x) && C_block_header(x) == C_FLONUM_TAG) {
+    m = C_flonum_magnitude(x);
+
+    if(m >= C_WORD64_MIN && m <= C_WORD64_MAX) return x;
+  }
+
+  barf(C_BAD_ARGUMENT_TYPE_NO_INTEGER_ERROR, NULL, x);
+  return C_SCHEME_UNDEFINED;
+}
+
+
 C_regparm C_word C_fcall C_i_foreign_unsigned_integer_argumentp(C_word x)
 {
   double m;
@@ -5692,6 +5709,23 @@ C_regparm C_word C_fcall C_i_foreign_unsigned_integer_argumentp(C_word x)
 }
 
 
+C_regparm C_word C_fcall C_i_foreign_unsigned_integer64_argumentp(C_word x)
+{
+  double m;
+
+  if((x & C_FIXNUM_BIT) != 0) return x;
+
+  if(!C_immediatep(x) && C_block_header(x) == C_FLONUM_TAG) {
+    m = C_flonum_magnitude(x);
+
+    if(m >= 0 && m <= C_UWORD64_MAX) return x;
+  }
+
+  barf(C_BAD_ARGUMENT_TYPE_NO_UINTEGER_ERROR, NULL, x);
+  return C_SCHEME_UNDEFINED;
+}
+
+
 /* I */
 C_regparm C_word C_fcall C_i_not_pair_p_2(C_word x)
 {
diff --git a/support.scm b/support.scm
index 7eab089b..4c84cd99 100644
--- a/support.scm
+++ b/support.scm
@@ -965,12 +965,18 @@
 		  `(##sys#foreign-struct-wrapper-argument 
 		    ',(##sys#slot (assq t tmap) 1)
 		    ,param) ) ]
-	     [(integer long size_t integer32 integer64)
+	     [(integer long size_t integer32)
 	      (if unsafe param `(##sys#foreign-integer-argument ,param))]
-	     [(unsigned-integer unsigned-integer32 unsigned-long unsigned-integer64)
+	     [(integer64)
+	      (if unsafe param `(##sys#foreign-integer64-argument ,param))]
+	     [(unsigned-integer unsigned-integer32 unsigned-long)
 	      (if unsafe
 		  param
 		  `(##sys#foreign-unsigned-integer-argument ,param) ) ]
+	     [(unsigned-integer32)
+	      (if unsafe
+		  param
+		  `(##sys#foreign-unsigned-integer64-argument ,param) ) ]
 	     [(c-pointer c-string-list c-string-list*)
 	      (let ([tmp (gensym)])
 		`(let ([,tmp ,param])
Trap