-
078d8ad0
by Duncan Coutts at 2026-09-25T13:34:03+01:00
Change dsCCall to take a CCallSpec
and change callers as appropriate. There should be no semantic change.
It's just moving the CCallSpec construction into the two callers.
It is currently only used by the C & JS functions that generate code for
the foreign import wrapper constructs (in the call to createAdjustor).
-
8024d575
by Duncan Coutts at 2026-09-25T13:34:04+01:00
Change calls to createAdjustor to specify that it comes from the rts
Previously it said TargetIsInThisUnit, meaning that createAdjustor lives
in the local library. This is false since createAdjustor is defined in
the RTS.
In practice, this false source information did not matter because the
source information is not used (yet). However in future it will be, for
better Windows DLL support (which does care about such distinctions).
It doesn't really matter that we say it's the RTS (though that is
actually true), what's important is that it will always be external to
the current shared library.
-
083ba611
by Duncan Coutts at 2026-09-25T13:34:04+01:00
Remove unused TargetIsInThisUnit case from CCallStaticTargetUnit
The CCallStaticTargetUnit infortmation in the XStaticTarget (TTG
exstension point) is actually pretty dubious.
Historically it was a (Maybe Unit) and the comments say that it is only
used by out-of-line primop calls on Windows. Indeed it is only used on
Windows for the dynamic way, when each unit is built as a separate DLL
(which we currently do not support). And even in that hypothetical
situation, the information that actually gets filled in is completely
bogus.
It _could_ be used in the windows dll case to correctly distinguish
making an out-of-line call to a cmm primop that is defined in the
current dll or in an external dll. But the information gets filled in in
the renaming phase with the _current_ unit. This is blatently wrong.
Many out-of-line primops are defined in the rts, which is obviously not
the current unit. It _could_ be a reasonable default, that cmm primops
are expected to be in the current dll, but we would have to have support
to specify a different location, i.e. the rts.
Furthermore, in addition to TargetIsInThisUnit being unused (after the
previous patch) it should never be used because it uses an implicit
"this" which will be wrong as soon as the information is inlined across
units. Instead of an implicit unit, it should use an explicit unit which
can be initialised to the defining unit and then be compared later to
the current unit. This will work correctly when looking at unfoldings
across unit boundaries.
-
3de1a8ae
by Duncan Coutts at 2026-09-25T13:34:04+01:00
Rename CCallStaticTargetUnit to CLabelTargetLibrary
And the constructor TargetIsInThat to CLabelTargetInUnit.
We will end up using this type both for calls and for labels/addresses
(used in core literals), so adjust the name to be about C names/labels
rather than about calls specifically.
Also improve related code docs. And introduce a conversion function from
CLabelTargetLibrary to ForeignLabelSource. We will extend this
conversion when we add more constructors to CLabelTargetLibrary.
-
a00f28d1
by Duncan Coutts at 2026-09-25T13:34:04+01:00
Change data PrimOp to use a UnitId rather than Unit
This simplifies the conversions slightly, but more importantly in a
later change we are going to want to specify a unit where we will only
have a UnitId to hand, not a Unit.
-
07bf7fa3
by Duncan Coutts at 2026-09-29T11:38:16+01:00
Extend 'foreign import prim' syntax to allow specifying the source package
that is: the package where the cmm entity comes from.
The package name is stashed in the "header" field for the FFI call, and
then the renamer resolves the package name to a unit id (with a new
ghc error for the failure of the package name resolution).
Fixes issue #27206
Adds test case T27206
-
3d5e5e56
by Duncan Coutts at 2026-09-29T11:38:16+01:00
Use new package name syntax for primops from the RTS
foreign import prim "rts stg_thething"
Most uses of foreign import prim in the libraries are for primops
defined in .cmm files local to that library, but some import primops
defined in the rts. These cases should use the new syntax to specify the
package name in the ffi entity string.
-
26a5ed6d
by Duncan Coutts at 2026-09-29T11:38:17+01:00
Extend ForeignLabelSource with ForeignLabelInUnknownPackage case
Initially this is treated the same way as ForeignLabelInExternalPackage.
Later we will extend this for Windows/PE to support building each
Haskell unit as a separate DLL, to support this unknown case
specifically.
-
f5261593
by Duncan Coutts at 2026-09-29T11:38:17+01:00
Extend CLabelTargetLibrary with CLabelTargetUnknown case
Initially unused, but this will become the typical case, because in fact
when Haskell code uses ffi imports, we do not know where the name comes
from: we do not know if the named entity is defined in the current
shared lib or in another one. Knowing where C entities come from is the
exception rather than the rule.
-
e216bc53
by Duncan Coutts at 2026-09-29T11:38:17+01:00
Extend LitLabel with CLabelTargetLibrary
Bundle the three fields of LitLabel into a new data CLabelSpec, defined
in GHC.Types.ForeignCall
Apart from the binary format, this should not change behaviour.
Behaviour changes are in the next patch
-
1c2891e2
by Duncan Coutts at 2026-09-29T11:38:17+01:00
Change FFI imports to use CLabelTargetUnknown
We never know the target for normal foreign imports.
Historically, this information was only actually used for
"foreign import prim", and only on Windows when building with one DLL
per unit (which bitrotted). The previous default of using the current
package as the source was wrong, even for the limited case of Windows
DLLs, because many of the imports are for primops defined in the RTS,
which is certainly not the current package.
-
1d64f750
by Duncan Coutts at 2026-09-29T11:38:17+01:00
Pass through the label source in stg->cmm conversion
Previously we had to hard code the (often incorrect) source
ForeignLabelInThisPackage. Now the Core label literal representation
carries the source, so we just convert that and pass it down.
As a consequence, if the source will now be either
ForeignLabelInUnknownPackage or ForeignLabelInPackage. The typical
value will be ForeignLabelInUnknownPackage, since that's what we get
for FFI imports of addresses.
In practice is not an immediate change of behaviour, because the only
user of this information is on Windows when building each Haskell unit
as a separate DLl, which isn't (yet) supported.
-
2ba26f14
by Duncan Coutts at 2026-09-29T11:38:17+01:00
Fix source for generated C name for 'foreign import "wrapper"'
For a 'foreign import "wrapper"' construct we generate a local wrapper
C function. We need to refer to the name of this local C function. We
_know_ that this function lives in the local shared lib, because it is
compiled into the same library. Thus we set the label source to be
CLabelTargetInUnit.
-
f117b62c
by Duncan Coutts at 2026-09-29T11:38:17+01:00
Fix source for generated C name for 'foreign import capi'
For a 'foreign import capi' we generate a local wrapper function and
then call that. We need to refer to the name of this local C function.
We _know_ that this function lives in the local shared lib, because it
is compiled into the same library. Thus we set the label source to be
CLabelTargetInUnit.
-
c2958f0e
by David Eichmann at 2026-09-29T11:38:17+01:00
Documentation: foreign imports of Cmm code may now specify source package