Skip to content

Conversation

JeffBezanson
Copy link
Member

Fixes #36458.

This is a bit ugly since ccall still has non-standard IR with call expressions nested inside it. The nice part is that we can piggyback on the existing caching mechanism, and still do only one NULL pointer check.

cc @staticfloat

@JeffBezanson JeffBezanson added compiler:codegen Generation of LLVM IR and native code needs docs Documentation for this change is required needs news A NEWS entry is required for this change labels Aug 19, 2020
@staticfloat
Copy link
Member

Fantabulous!

Copy link
Member

@vtjnash vtjnash left a comment

Choose a reason for hiding this comment

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

It seems to work, though as you mention, still an awful hack. Not great that if the user makes a slight mistake, the ccall will just segfault.

julia> f(x) = (y = x + 1; ccall((:a, y), Cvoid, ()))
f (generic function with 1 method)

julia> f(1)
signal (11): Segmentation fault: 11

Is it possible to instead modify the new @ccall macro to let us do this without the syntactic ambiguity?

@yuyichao
Copy link
Contributor

Should also document that the user code may be called multiple times and it's undefined behavior if they return different values.

@JeffBezanson JeffBezanson changed the title WIP: allow ccall library name to be non-constant allow ccall library name to be non-constant Aug 26, 2020
@JeffBezanson JeffBezanson removed needs docs Documentation for this change is required needs news A NEWS entry is required for this change labels Aug 26, 2020
@JeffBezanson
Copy link
Member Author

I added a check to replace some of the more likely crashes with a lowering error. AFAICT everything caught by this error used to segfault, so it should be ok.

@JeffBezanson JeffBezanson added the merge me PR is reviewed. Merge when all tests are passing label Aug 28, 2020
@JeffBezanson JeffBezanson merged commit 5cba88c into master Sep 2, 2020
@JeffBezanson JeffBezanson deleted the jb/lazylibpath branch September 2, 2020 22:20
be executed when the `ccall` itself is executed. However, it is assumed that the library
location does not change once it is determined, so the result of the call can be cached and
reused. Therefore, the number of times the expression executes is undefined, and returning
different values for multiple calls results in undefined behavior.
Copy link
Member

Choose a reason for hiding this comment

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

UB has a rather strong connotation, when this seems merely unspecified?

gvname += f_name;
gvname += "_";
gvname += std::to_string(globalUnique++);
Module *M = ctx.emission_context.shared_module(jl_LLVMContext);
Copy link
Member

Choose a reason for hiding this comment

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

Seems odd to explicitly share a private variable. This could go in jl_Module

@vtjnash
Copy link
Member

vtjnash commented Sep 2, 2020

Yay! 🎉

maleadt added a commit to JuliaLLVM/LLVM.jl that referenced this pull request Sep 3, 2020
maleadt added a commit to JuliaLLVM/LLVM.jl that referenced this pull request Sep 3, 2020
@DilumAluthge DilumAluthge removed the merge me PR is reviewed. Merge when all tests are passing label Jan 11, 2021
vtjnash added a commit that referenced this pull request Jul 30, 2025
We have long expected users to be explicit about the library name for
`ccall`, and the `@ccall` macro has even always enforced that. That
means users should have already been using explicit syntax. And indeed,
other syntax forms weren't handled reliably (since doing so would
require linearizing IR if and only if the runtime values required it,
which is not something that is computable, and thus was often done
wrong). This now aligns the runtime and compiler to expect only syntax
forms that we could reliably handle before without errors, and adds
explicit errors for cases that we previously knew would be unreliable
because they relied upon inference making particular decisions for the
semantics. The `ccall` function is already very special since it is more
like a actual macro (it does not exist as a binding or value), so we can
make unusual syntax decisions like this, mirroring `@ccall`.

This drops support for #37123,
since we were going to use that for LazyLibraries, be we decided that
approach was quite buggy and that PR would make static compilation quite
impossible to support, so we instead actually implemented LazyLibraries
with a different approach. It could be re-enabled, but we never had
correct lowering or inference support for it, so it is presumably
still unused.
vtjnash added a commit that referenced this pull request Jul 30, 2025
We have long expected users to be explicit about the library name for
`ccall`, and the `@ccall` macro has even always enforced that. That
means users should have already been using explicit syntax. And indeed,
other syntax forms weren't handled reliably (since doing so would
require linearizing IR if and only if the runtime values required it,
which is not something that is computable, and thus was often done
wrong). This now aligns the runtime and compiler to expect only syntax
forms that we could reliably handle before without errors, and adds
explicit errors for cases that we previously knew would be unreliable
because they relied upon inference making particular decisions for the
semantics. The `ccall` function is already very special since it is more
like a actual macro (it does not exist as a binding or value), so we can
make unusual syntax decisions like this, mirroring `@ccall`.

This drops support for #37123,
since we were going to use that for LazyLibraries, be we decided that
approach was quite buggy and that PR would make static compilation quite
impossible to support, so we instead actually implemented LazyLibraries
with a different approach. It could be re-enabled, but we never had
correct lowering or inference support for it, so it is presumably
still unused.
vtjnash added a commit that referenced this pull request Jul 30, 2025
We have long expected users to be explicit about the library name for
`ccall`, and the `@ccall` macro has even always enforced that. That
means users should have already been using explicit syntax. And indeed,
other syntax forms weren't handled reliably (since doing so would
require linearizing IR if and only if the runtime values required it,
which is not something that is computable, and thus was often done
wrong). This now aligns the runtime and compiler to expect only syntax
forms that we could reliably handle before without errors, and adds
explicit errors for cases that we previously knew would be unreliable
because they relied upon inference making particular decisions for the
semantics. The `ccall` function is already very special since it is more
like a actual macro (it does not exist as a binding or value), so we can
make unusual syntax decisions like this, mirroring `@ccall`.

This drops support for #37123,
since we were going to use that for LazyLibraries, be we decided that
approach was quite buggy and that PR would make static compilation quite
impossible to support, so we instead actually implemented LazyLibraries
with a different approach. It could be re-enabled, but we never had
correct lowering or inference support for it, so it is presumably
still unused.

The goal is to cause breakage only where the package authors really
failed to express intent with syntax, and otherwise to explicitly
maintain support by adding cases to normalize the given syntax into one
of the supported cases. All existing functionality (and more) can be
accessed by explicit management of a pointer or by a LazyLibrary-like
type, so this shouldn't cause any reduction in possible functionality,
just possibly altered syntax.
vtjnash added a commit that referenced this pull request Jul 31, 2025
We have long expected users to be explicit about the library name for
`ccall`, and the `@ccall` macro has even always enforced that. That
means users should have already been using explicit syntax. And indeed,
other syntax forms weren't handled reliably (since doing so would
require linearizing IR if and only if the runtime values required it,
which is not something that is computable, and thus was often done
wrong). This now aligns the runtime and compiler to expect only syntax
forms that we could reliably handle before without errors, and adds
explicit errors for cases that we previously knew would be unreliable
because they relied upon inference making particular decisions for the
semantics. The `ccall` function is already very special since it is more
like a actual macro (it does not exist as a binding or value), so we can
make unusual syntax decisions like this, mirroring `@ccall`.

This drops support for #37123,
since we were going to use that for LazyLibraries, be we decided that
approach was quite buggy and that PR would make static compilation quite
impossible to support, so we instead actually implemented LazyLibraries
with a different approach. It could be re-enabled, but we never had
correct lowering or inference support for it, so it is presumably
still unused.

The goal is to cause breakage only where the package authors really
failed to express intent with syntax, and otherwise to explicitly
maintain support by adding cases to normalize the given syntax into one
of the supported cases. All existing functionality (and more) can be
accessed by explicit management of a pointer or by a LazyLibrary-like
type, so this shouldn't cause any reduction in possible functionality,
just possibly altered syntax.
vtjnash added a commit that referenced this pull request Aug 1, 2025
We have long expected users to be explicit about the library name for
`ccall`, and the `@ccall` macro has even always enforced that. That
means users should have already been using explicit syntax. And indeed,
other syntax forms weren't handled reliably (since doing so would
require linearizing IR if and only if the runtime values required it,
which is not something that is computable, and thus was often done
wrong). This now aligns the runtime and compiler to expect only syntax
forms that we could reliably handle before without errors, and adds
explicit errors for cases that we previously knew would be unreliable
because they relied upon inference making particular decisions for the
semantics. The `ccall` function is already very special since it is more
like a actual macro (it does not exist as a binding or value), so we can
make unusual syntax decisions like this, mirroring `@ccall`.

This drops support for #37123,
since we were going to use that for LazyLibraries, be we decided that
approach was quite buggy and that PR would make static compilation quite
impossible to support, so we instead actually implemented LazyLibraries
with a different approach. It could be re-enabled, but we never had
correct lowering or inference support for it, so it is presumably
still unused.

The goal is to cause breakage only where the package authors really
failed to express intent with syntax, and otherwise to explicitly
maintain support by adding cases to normalize the given syntax into one
of the supported cases. All existing functionality (and more) can be
accessed by explicit management of a pointer or by a LazyLibrary-like
type, so this shouldn't cause any reduction in possible functionality,
just possibly altered syntax.
vtjnash added a commit that referenced this pull request Sep 16, 2025
We have long expected users to be explicit about the library name for
`ccall`, and the `@ccall` macro has even always enforced that. That
means users should have already been using explicit syntax. And indeed,
other syntax forms weren't handled reliably (since doing so would
require linearizing IR if and only if the runtime values required it,
which is not something that is computable, and thus was often done
wrong). This now aligns the runtime and compiler to expect only syntax
forms that we could reliably handle before without errors, and adds
explicit errors for cases that we previously knew would be unreliable
because they relied upon inference making particular decisions for the
semantics. The `ccall` function is already very special since it is more
like a actual macro (it does not exist as a binding or value), so we can
make unusual syntax decisions like this, mirroring `@ccall`.

This drops support for #37123,
since we were going to use that for LazyLibraries, be we decided that
approach was quite buggy and that PR would make static compilation quite
impossible to support, so we instead actually implemented LazyLibraries
with a different approach. It could be re-enabled, but we never had
correct lowering or inference support for it, so it is presumably
still unused.

The goal is to cause breakage only where the package authors really
failed to express intent with syntax, and otherwise to explicitly
maintain support by adding cases to normalize the given syntax into one
of the supported cases. All existing functionality (and more) can be
accessed by explicit management of a pointer or by a LazyLibrary-like
type, so this shouldn't cause any reduction in possible functionality,
just possibly altered syntax.
vtjnash added a commit that referenced this pull request Sep 17, 2025
We have long expected users to be explicit about the library name for
`ccall`, and the `@ccall` macro has even always enforced that. That
means users should have already been using explicit syntax. And indeed,
other syntax forms weren't handled reliably (since doing so would
require linearizing IR if and only if the runtime values required it,
which is not something that is computable, and thus was often done
wrong). This now aligns the runtime and compiler to expect only syntax
forms that we could reliably handle before without errors, and adds
explicit errors for cases that we previously knew would be unreliable
because they relied upon inference making particular decisions for the
semantics. The `ccall` function is already very special since it is more
like a actual macro (it does not exist as a binding or value), so we can
make unusual syntax decisions like this, mirroring `@ccall`.

This drops support for #37123,
since we were going to use that for LazyLibraries, be we decided that
approach was quite buggy and that PR would make static compilation quite
impossible to support, so we instead actually implemented LazyLibraries
with a different approach. It could be re-enabled, but we never had
correct lowering or inference support for it, so it is presumably
still unused.

The goal is to cause breakage only where the package authors really
failed to express intent with syntax, and otherwise to explicitly
maintain support by adding cases to normalize the given syntax into one
of the supported cases. All existing functionality (and more) can be
accessed by explicit management of a pointer or by a LazyLibrary-like
type, so this shouldn't cause any reduction in possible functionality,
just possibly altered syntax.
vtjnash added a commit that referenced this pull request Sep 17, 2025
We have long expected users to be explicit about the library name for
`ccall`, and the `@ccall` macro has even always enforced that. That
means users should have already been using explicit syntax. And indeed,
other syntax forms weren't handled reliably (since doing so would
require linearizing IR if and only if the runtime values required it,
which is not something that is computable, and thus was often done
wrong). This now aligns the runtime and compiler to expect only syntax
forms that we could reliably handle before without errors, and adds
explicit errors for cases that we previously knew would be unreliable
because they relied upon inference making particular decisions for the
semantics. The `ccall` function is already very special since it is more
like a actual macro (it does not exist as a binding or value), so we can
make unusual syntax decisions like this, mirroring `@ccall`.

This drops support for #37123,
since we were going to use that for LazyLibraries, be we decided that
approach was quite buggy and that PR would make static compilation quite
impossible to support, so we instead actually implemented LazyLibraries
with a different approach. It could be re-enabled, but we never had
correct lowering or inference support for it, so it is presumably
still unused.

The goal is to cause breakage only where the package authors really
failed to express intent with syntax, and otherwise to explicitly
maintain support by adding cases to normalize the given syntax into one
of the supported cases. All existing functionality (and more) can be
accessed by explicit management of a pointer or by a LazyLibrary-like
type, so this shouldn't cause any reduction in possible functionality,
just possibly altered syntax.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler:codegen Generation of LLVM IR and native code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

On Musl systems, can't ccall into a library with the soname
5 participants