Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

direct-c-ffi: Invalid return type default for %call-c-function signature specification #730

Closed
waywardmonkeys opened this issue Apr 28, 2014 · 1 comment

Comments

@waywardmonkeys
Copy link
Member

Doing (note the => ()):

  %call-c-function("exit")
    (status :: <raw-c-signed-int>) => ()
    (integer-as-raw(3))
  end;

Will result in a compile time error:

_build/build/test/test.c:146:8: error: unknown type name 'KLobjectGVKd'; did
you mean '_KLobjectGVKd'?
extern KLobjectGVKd exit (int);
       ^~~~~~~~~~~~
       _KLobjectGVKd
_build/build/test/test.c:29:3: note: '_KLobjectGVKd' declared here
} _KLobjectGVKd;
  ^
1 error generated.

To get that to compile, you need to do the non-intuitive:

  %call-c-function("exit")
    (status :: <raw-c-signed-int>) => (nothing :: <raw-c-void>)
    (integer-as-raw(3))
  end;
@waywardmonkeys
Copy link
Member Author

I've tried to fix this by improving some code when generating the C:

--- a/sources/dfmc/c-back-end/c-emit-c-computation.dylan
+++ b/sources/dfmc/c-back-end/c-emit-c-computation.dylan
@@ -59,7 +59,7 @@ define method emit-primitive-call
     (b :: <c-back-end>, s :: <stream>, d :: <integer>,
      c :: <primitive-call>, f :: <&objc-msgsend>)
   let sig-values = f.primitive-signature.^signature-values;
-  let return-type = first(sig-values, default: dylan-value(#"<object>"));
+  let return-type = first(sig-values, default: dylan-value(#"<raw-c-void>"));
   format-emit(b, s, d, "((^(*)(", return-type);
   for (type in f.c-signature.^signature-required,
        first? = #t then #f)
diff --git a/sources/dfmc/c-linker/c-link-c-object.dylan b/sources/dfmc/c-linker/c-link-c-object.dylan
index 64debbb..e1bbdcb 100644
--- a/sources/dfmc/c-linker/c-link-c-object.dylan
+++ b/sources/dfmc/c-linker/c-link-c-object.dylan
@@ -34,7 +34,7 @@ define method emit-forward
     (back-end :: <c-back-end>, stream :: <stream>, o :: <&c-function>) => ();
   unless(member?(o.binding-name, $generic-names-not-to-emit, test: \=))
     let sig-values = o.primitive-signature.^signature-values;
-    let return-type = first(sig-values, default: dylan-value(#"<object>"));
+    let return-type = first(sig-values, default: dylan-value(#"<raw-c-void>"));
     if (target-os-name() == #"win32")
       format-emit*(back-end, stream, "~ ^ ~ ^ ",
                   if (o.binding-name) "extern" else "typedef" end,

But that doesn't actually address the issue.

I suspect that it may have to be dealt with at parse time. The code involved there is parse-variables-list, parse-values-list and parse-signature-as from sources/dfmc/definitions/parse-signatures.dylan which is called from parse-primitive-signature in sources/dfmc/conversion/convert-c-ffi.dylan

waywardmonkeys added a commit to waywardmonkeys/opendylan that referenced this issue Jun 2, 2015
When no return values are specified in %call-c-function or
%objc-msgsend, we shouldn't have to explicitly say <raw-c-void>
is the return type, the "=> ()" should be sufficient.

Fixes dylan-lang#730.

* sources/dfmc/conversion/convert-c-ffi.dylan
  (parse-ffi-result-type): New method to replace an empty result
    specification with a <raw-c-void> result type.
  (&converter %call-c-function): Use parse-ffi-result-type.
  (&converter %call-c-function-indirect): Use parse-ffi-result-type.
  (&converter %objc-msgsend): Use parse-ffi-result-type.

* sources/dfmc/c-back-end/c-emit-c-computation.dylan
  (emit-primitive-call on <&objc-msgsend>): Default to <raw-c-void>
    if there are no specified result types. This should never happen
    given that conversion always supplies a result type.

* sources/dfmc/c-linker/c-link-c-object.dylan
  (emit-forward on <&c-function>): Default to <raw-c-void>
    if there are no specified result types. This should never happen
    given that conversion always supplies a result type.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant