[GHC] #9352: Allow `State# s` argument/result types in `ccall` FFI imports
GHC
ghc-devs at haskell.org
Fri Jul 25 10:27:41 UTC 2014
#9352: Allow `State# s` argument/result types in `ccall` FFI imports
-------------------------------------+-------------------------------------
Reporter: hvr | Owner:
Type: feature | Status: new
request | Milestone: 7.10.1
Priority: normal | Version: 7.8.2
Component: Compiler | Keywords:
(Type checker) | Architecture: Unknown/Multiple
Resolution: | Difficulty: Unknown
Operating System: | Blocked By:
Unknown/Multiple | Related Tickets: #9281
Type of failure: |
None/Unknown |
Test Case: |
Blocking: |
Differential Revisions: |
-------------------------------------+-------------------------------------
Comment (by simonpj):
Simon M: looking into the code, I'm quite perplexed. Have a look at:
DsCCall.boxResult. It seems the when we say
{{{
foreign import foo :: Int -> Int
}}}
we actually generate (in effect) an inline use of `unsafePerformIO`.
Here's the tidy core:
{{{
M.foo :: GHC.Types.Int -> GHC.Types.Int
[GblId, Arity=1, Caf=NoCafRefs, Str=DmdType]
M.foo =
\ (ds_d1A2 :: GHC.Types.Int) ->
case ds_d1A2 of _ [Occ=Dead] { GHC.Types.I# ds2_d1A4 ->
case {__pkg_ccall main foo Int#
-> State# RealWorld -> (# State# RealWorld, Int#
#)}_d1A7
ds2_d1A4 GHC.Prim.realWorld#
of _ [Occ=Dead] { (# ds3_d1A6, ds4_d1A5 #) ->
GHC.Types.I# ds4_d1A5 } }
}}}
Note that we come up with a `realWorld#` out of thin air and then discard
it again... that's the `unsafePerformIO` stuff. Then the code generator
has to painstakingly discard all that state-passing nonsense, to get back
to a simple C call to "foo".
Why do we bother with this? Why not produce this core:
{{{
M.foo :: GHC.Types.Int -> GHC.Types.Int
M.foo =
\ (ds_d1A2 :: GHC.Types.Int) ->
case ds_d1A2 of _ [Occ=Dead] { GHC.Types.I# ds2_d1A4 ->
case {__pkg_ccall main foo Int# -> Int#}_d1A7
ds2_d1A4
of ds4_d1A5 [Occ=Dead] { DEFAULT ->
GHC.Types.I# ds4_d1A5 } }
}}}
Simpler, more direct, and should generate exactly the same code. At the
moment the built-in `FCallId` Ids always have an IO-ish type, but I see no
reason to require that.
If we did this, then I think the distinction between `boxResult` and
`resultWrapper` could disappear, leading to a simpler, compositional
structur.
Moreover, if we want to accommodate
{{{
foreign import foo :: Int -> State# s -> (# State# s, Int #)
}}}
which doesn't have an IO-ish type (at least not built with the `IO` type
constructor), it would seem utterly bizarre to enclose it in the
`unsafePerformIO` boilerplate as above.
I think Herbert might be able to act on all this, but first let's check
that I have not forgotten anything stupid.
Simon
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/9352#comment:5>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list