chicken-hackers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Chicken-hackers] [PATCH] Avoid invalid specializations for multi-valued


From: Evan Hanson
Subject: [Chicken-hackers] [PATCH] Avoid invalid specializations for multi-valued foreign-primitives
Date: Thu, 9 Oct 2014 07:08:59 +1300

The foreign-primitive form may return multiple values with the C_values
function, but its expansion is always declared to return a (single)
undefined value. This triggers invalid ##sys#c-w-v specializations for
single-valued producers where multiple values may in fact result.

This fixes that declaration so that multiple values are expected when no
return type is specified.
---
 chicken-ffi-syntax.scm            |    6 ++++--
 manual/Accessing external objects |   14 +++++++-------
 tests/specialization-test-1.scm   |    9 +++++++++
 3 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/chicken-ffi-syntax.scm b/chicken-ffi-syntax.scm
index d07764f..d48b0f9 100644
--- a/chicken-ffi-syntax.scm
+++ b/chicken-ffi-syntax.scm
@@ -211,12 +211,14 @@
   (lambda (form r c)
     (##sys#check-syntax 'foreign-primitive form '(_ _ . _))
     (let* ((hasrtype (and (pair? (cddr form)) (not (string? (caddr form)))))
-          (rtype (or (and hasrtype (##sys#strip-syntax (cadr form))) 'void))
+          (rtype (and hasrtype (##sys#strip-syntax (cadr form))))
           (args (##sys#strip-syntax (if hasrtype (caddr form) (cadr form))))
           (argtypes (map car args)))
       `(##core#the (procedure
                    ,(map (cut ##compiler#foreign-type->scrutiny-type <> 'arg) 
argtypes)
-                   ,(##compiler#foreign-type->scrutiny-type rtype 'result))
+                   ,@(if (not rtype)
+                         '* ; special case for C_values(...)
+                         (list (##compiler#foreign-type->scrutiny-type rtype 
'result))))
                   #f
                   (##core#foreign-primitive ,@(cdr form)))))))
 
diff --git a/manual/Accessing external objects b/manual/Accessing external 
objects
index 2fcec62..2310702 100644
--- a/manual/Accessing external objects 
+++ b/manual/Accessing external objects 
@@ -167,13 +167,13 @@ function to call Scheme functions and allocate Scheme 
data-objects. See [[Callba
 
 <macro>(foreign-primitive [RETURNTYPE] ((ARGTYPE VARIABLE) ...) STRING 
...)</macro>
 
-This is also similar to {{foreign-lambda*}} but the code will be executed
-in a ''primitive'' CPS context, which means it will not actually return, but
-call its continuation on exit. This means that code inside this form may
-allocate Scheme data on the C stack (the ''nursery'') with {{C_alloc}}
-(see below). If the {{RETURNTYPE}} is omitted it defaults to {{void}}.
-You can return multiple values inside the body of the {{foreign-primitive}}
-form by calling this C function:
+This is also similar to {{foreign-lambda*}} but the code will be
+executed in a ''primitive'' CPS context, which means it will not
+actually return, but call its continuation on exit. This means that code
+inside this form may allocate Scheme data on the C stack (the
+''nursery'') with {{C_alloc}} (see below). You can return multiple
+values inside the body of the {{foreign-primitive}} form by calling this
+C function:
 
 <enscript highlight=scheme>
 C_values(N + 2, C_SCHEME_UNDEFINED, C_k, X1, ...)
diff --git a/tests/specialization-test-1.scm b/tests/specialization-test-1.scm
index 37e8d6b..344e445 100644
--- a/tests/specialization-test-1.scm
+++ b/tests/specialization-test-1.scm
@@ -46,5 +46,14 @@ return n;}
 
 (assert (null? (the (or undefined *) (list))))
 
+;; Ensure a foreign-primitive returning multiple values with C_values()
+;; isn't specialized to a single result.
+(let ((result (receive ((foreign-primitive ()
+                         "C_values(4,"
+                         "         C_SCHEME_UNDEFINED,"
+                         "         C_k,"
+                         "         C_fix(1),"
+                         "         C_fix(2));")))))
+  (assert (equal? '(1 2) result)))
 
 )
-- 
1.7.10.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]