这是我之前问题的后续here https://stackoverflow.com/questions/41213378/using-foreign-import-prim-with-a-c-function-using-stg-calling-convention。我已经能够得到一些工作里德·巴顿的回答 https://stackoverflow.com/a/41214165/176841,但我注意到我看到的核心__pkg_ccall_GC
:
case {__pkg_ccall_GC hashabler-2.0.0 sipRound_s_x2 Word#
-> Word#
-> Word#
-> Word#
-> (# Word#, Word#, Word#, Word# #)}
ww1 ww2 ww3 (xor# ww4 b1)
我认为这就是您对“安全”的 ffi 通话的期望。然而,不允许在外部导入字符串中添加“不安全”(尽管错误消息没有说明原因):
src/Data/Hashabler/SipHash.hs:60:1: error:
• The safe/unsafe annotation should not be used with `foreign import prim'.
• When checking declaration:
foreign import prim unsafe "static sipRound_s_x4" sipRound_s_x4#
:: Word#
-> Word# -> Word# -> Word# -> (# Word#, Word#, Word#, Word# #)
我的外国程序只是一点点,但有点麻烦,所以我不认为我想要什么_GC
正在给我。我看过的 GHC 源代码的一些相关部分、FWIW 和背景:
compiler/prelude/ForeignCall.hs:只有“Risky”省略了“_GC”
data Safety
= PlaySafe -- Might invoke Haskell GC, or do a call back, or
-- switch threads, etc. So make sure things are
-- tidy before the call. Additionally, in the threaded
-- RTS we arrange for the external call to be executed
-- by a separate OS thread, i.e., _concurrently_ to the
-- execution of other Haskell threads.
| PlayInterruptible -- Like PlaySafe, but additionally
-- the worker thread running this foreign call may
-- be unceremoniously killed, so it must be scheduled
-- on an unbound thread.
| PlayRisky -- None of the above can happen; the call will return
-- without interacting with the runtime system at all
deriving ( Eq, Show, Data )
-- Show used just for Show Lex.Token, I think
我也看到一些foreign import prim unsafe
and ... safe
在 GHC 树中,尽管我认为它是死代码。例如testsuite/tests/printer/Ppr046.hs
.
所以我的问题是:
- 从 a 生成的代码有什么区别
__pkg_ccall_GC
vs a __pkg_ccall
在这种情况下(我正在做的地方foreign import prim
not ccall
)?和描述的一样吗here https://wiki.haskell.org/Foreign_Function_Interface#Unsafe_calls?
- 为什么没有
foreign import prim unsafe
好像支持?
- 假设我理解(1):我是否可以解决这个问题,既获得多个值的有效返回,又避免(1)中发生的任何簿记?
EDIT: 从装配体来看-ddump-asm
清楚地表明没有发生任何事情(不应该害怕看大会),支持里德·巴顿(Reid Barton)的评论如下:
movq %rdi,%rax
movq %r8,%rdi
xorq %r9,%rdi
movq %rsi,%rcx
movq %rax,%rsi
movq %r14,%rax
movq %rcx,%r14
movq %rbx,%rcx
movq %rax,%rbx
movq %r9,-8(%rbp)
movq %rcx,(%rbp)
addq $-16,%rbp
jmp sipRound_s_x2
The xorq
朝向顶部对应于 haskellxor
。所有那些movq
虽然看起来确实很无赖……