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

Support void* (Pointer[None]) parameters in bare lambdas and functions #4152

Merged
merged 10 commits into from
Jun 24, 2022

Conversation

stefandd
Copy link
Contributor

@stefandd stefandd commented Jun 23, 2022

Unlike conventional FFI functions, bare lambdas @{(...)} do so far not support Pointer[None] parameters, Pony's equivalent of void*, despite the fact that like the former these lambdas are strictly intended for use with FFI calls and callbacks.
Therefore, code like this failed to compile:

use @wglGetProcAddress[@{()}](name: Pointer[U8] tag)

class GlExt
    let glBufferData: @{(GLenum, GLsizeiptr, Pointer[None] tag, GLenum)}

    new create() =>
        glBufferData = @wglGetProcAddress[@{(GLenum, GLsizeiptr, Pointer[None] tag, GLenum)}]("glBindBuffer".cstring())

...

let maxParticles: ISize = 1000
var particles: Array[F32] = [] // holds Vector3f {float, float, float} particles
//fill particle array
for i in Range[ISize](0, maxParticles) do
    particles.push(sr.frand()) // x
    particles.push(sr.frand()) // y
    particles.push(sr.frand()) // z
end
...

glExt.glBufferData(GLArrayBuffer(), maxParticles * ISize(12), particles.cpointer(), GLStaticDraw()) // <- type error

This commit adds to the bare lambdas and functions the same lenience that conventional FFI functions enjoy: it allows the declaration of Pointer[None] parameters that can accept any of the Pony Pointer[A] types.

@ponylang-main ponylang-main added the discuss during sync Should be discussed during an upcoming sync label Jun 23, 2022
@SeanTAllen SeanTAllen added enhancement New feature or request help wanted Extra attention is needed changelog - fixed Automatically add "Fixed" CHANGELOG entry on merge and removed help wanted Extra attention is needed enhancement New feature or request labels Jun 23, 2022
@ponylang-main
Copy link
Contributor

Hi @stefandd,

The changelog - fixed label was added to this pull request; all PRs with a changelog label need to have release notes included as part of the PR. If you haven't added release notes already, please do.

Release notes are added by creating a uniquely named file in the .release-notes directory. We suggest you call the file 4152.md to match the number of this pull request.

The basic format of the release notes (using markdown) should be:

## Title

End user description of changes, why it's important,
problems it solves etc.

If a breaking change, make sure to include 1 or more
examples what code would look like prior to this change
and how to update it to work after this change.

Thanks.

@SeanTAllen
Copy link
Member

Please change the test to a ponyc-run test. We only do error messages tests now that aren't ponyc-run.

Let me know if you need any help getting oriented with the ponyc-run tests.

Copy link
Member

@ergl ergl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like Sean mentioned, can you add the test to the runner? It would also make sense to test that partial application also works with this change, like so:

use @printf[I32](fmt: Pointer[None] tag, ...)

actor Main
  new create(env: Env) =>
    let cb = this~print()
    cb("Hello, world!\n".cstring())

  fun @print(fmt: Pointer[None]) =>
    @printf(fmt)

src/libponyc/expr/call.c Outdated Show resolved Hide resolved
src/libponyc/expr/call.c Outdated Show resolved Hide resolved
@stefandd
Copy link
Contributor Author

stefandd commented Jun 23, 2022

Like Sean mentioned, can you add the test to the runner? It would also make sense to test that partial application also works with this change, like so:

use @printf[I32](fmt: Pointer[None] tag, ...)

actor Main
  new create(env: Env) =>
    let cb = this~print()
    cb("Hello, world!\n".cstring())

  fun @print(fmt: Pointer[None]) =>
    @printf(fmt)

Thanks for the test. It does run and print hello world. I am not familiar enough with the test suite to know if the actual output needs to be captured here or if I should simply add an exit code that matches the .txt file. Also, I struggled a bit to understand

We only do error messages tests now that aren't ponyc-run.

The compile test I had proposed was not an error message test, was it? Should I simply add an exit code test for that one too, i.e., move both tests to the libponyc-run suite?

@ergl
Copy link
Member

ergl commented Jun 23, 2022

@stefandd No need to capture the output. Take a look at how I did the runner test for my other PR here: https://github.com/ponylang/ponyc/tree/4f64cc5a87ae3e9641e1596d7dddb4f15d737395/test/libponyc-run/ffi-return-arg-reachable

The ideal test would show that you're able to any pointer to C using bare lambdas, and that you get something back that makes sense.

Edit:

The compile test I had proposed was not an error message test, was it? Should I simply add an exit code test for that one too, i.e., move both tests to the libponyc-run suite?

So, for runner tests, we're interested in that the code compiles, and that it does what is supposed to. That's why I mentioned the bit about verifying that the C code works as expected.

@stefandd
Copy link
Contributor Author

stefandd commented Jun 23, 2022

@ergl I combined the test you suggested for the bare functions with one for bare lambdas. It only produces the expected exit code if both pass. Ok so?

EDIT: I realize the tests should be in seperate folders for bare lamdas and bare functions...

test/libponyc/bare.cc Outdated Show resolved Hide resolved
@ergl
Copy link
Member

ergl commented Jun 23, 2022

I realize the tests should be in seperate folders for bare lamdas and bare functions...

@stefandd I don't think this matters too much. I'll be okay with you putting them all in the same test.

@SeanTAllen
Copy link
Member

I'd prefer separate tests

@stefandd stefandd changed the title Support void* (Pointer[None]) parameters in bare lambdas Support void* (Pointer[None]) parameters in bare lambdas and functions Jun 23, 2022
Copy link
Member

@ergl ergl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me except for some wording and spacing nits.

.release-notes/4152.md Outdated Show resolved Hide resolved
.release-notes/4152.md Outdated Show resolved Hide resolved
@SeanTAllen SeanTAllen merged commit 4059631 into ponylang:main Jun 24, 2022
@ponylang-main ponylang-main removed the discuss during sync Should be discussed during an upcoming sync label Jun 24, 2022
github-actions bot pushed a commit that referenced this pull request Jun 24, 2022
github-actions bot pushed a commit that referenced this pull request Jun 24, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
changelog - fixed Automatically add "Fixed" CHANGELOG entry on merge
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants