这是我之前的问题here的后续内容。我已经能够按Reid Barton's answer获得一些工作,但我注意到核心中__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
我在GHC树中也看到了一些foreign import prim unsafe
和... safe
,但我认为它是死代码。例如testsuite/tests/printer/Ppr046.hs
。
所以我的问题是:
__pkg_ccall_GC
与__pkg_ccall
生成的代码之间有什么区别(我在foreign import prim
而不是ccall
)?是否与描述here?foreign import prim unsafe
? 编辑:查看来自-ddump-asm
的程序集,清楚地表明没有发生任何事情(不应该害怕看到程序集),支持Reid Barton&#39的评论如下:
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
顶部的xorq
对应于haskell xor
。所有那些movq
确实似乎是一个无赖......但
答案 0 :(得分:3)
正如Reid Barton所指出的,__pkg_ccall_GC
并没有表明任何事情。生成的代码不会执行您在safe
FFI调用中看到的簿记。