[GHC] #10867: Primop types should not mention ()
GHC
ghc-devs at haskell.org
Mon Sep 14 10:43:57 UTC 2015
#10867: Primop types should not mention ()
-------------------------------------+-------------------------------------
Reporter: simonpj | Owner:
Type: bug | Status: new
Priority: normal | Milestone:
Component: Compiler | Version: 7.10.2
Resolution: | Keywords:
Operating System: Unknown/Multiple | Architecture:
| Unknown/Multiple
Type of failure: None/Unknown | Test Case:
Blocked By: | Blocking:
Related Tickets: | Differential Revisions:
-------------------------------------+-------------------------------------
Changes (by simonpj):
* cc: core-libraries-committee (added)
Comment:
Simon, can you help a little more? I'm also copying the core libraries
committee,
since I propose an API change for weak-pointer primpops.
The type `Weak#` and primop `mkWeak#`, are declared thus:
{{{
primtype Weak# b
primop MkWeakOp "mkWeak#" GenPrimOp
o -> b -> c -> State# RealWorld -> (# State# RealWorld, Weak# b #)
}}}
I think `c` is the finalizer. This type suggests that you can put any
old value in for the finalizer, which seems unlikely. '''In fact it can
easily lead to a seg-fault (with no use of `unsafeCoerce` by building
a weak pointer whose "finaliser" with the wrong type.'''
Then the primop `finalizeWeak#` is declared thus:
{{{
primop FinalizeWeakOp "finalizeWeak#" GenPrimOp
Weak# a -> State# RealWorld
-> (# State# RealWorld
, Int#
, State# RealWorld -> (# State# RealWorld, () #)
#)
}}}
I believe the following:
* The third argument to `mkWeak#` is returned as the third component of
the result to `finalizeWeak#`, but is otherwise totally un-examined by the
RTS.
Is that true? In that case it would be far, far better to declare them
like this:
{{{
primtype Weak# value finalizer
primop MkWeakOp "mkWeak#" GenPrimOp
key -> value -> finalizer
-> State# RealWorld -> (# State# RealWorld, Weak# payload finalizer #)
}}}
So `Weak#` gets two type parameters, the second recording the type of
the "finaliser". All the RTS promises to do is to cough up the
"finalizer"
when the `key` dies.
Now in `GHC.Weak` we can declare `Weak` thus:
{{{
data Weak v = Weak (Weak# v) (IO ())
}}}
That is `Weak` specialises the "any only value can be a finaliser" API
offered by `Weak#` to "the finaliser is a vlaue of type `IO ()`" API
for `Weak`.
Doing this would eliminate an unpleasant potential source of seg-faults;
and it would eliminate one of the two unpleasant uses of `()` in
`primpops.txt.pp`.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/10867#comment:10>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list