为什么没有'外国进口原料不安全'? [英] Why is there no 'foreign import prim unsafe'?
问题描述
这是我之前提出的问题的一个后续步骤这里。我已经能够根据 Reid Barton的回答得到一些结果,但我注意到在核心中我看到 __ 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:
•安全/不安全批注不应与`foreign import prim'一起使用。
•检查声明时:
国外进口原料不安全静态sipRound_s_x4sipRound_s_x4#
:: Word#
- >单词# - >单词# - >单词# - > (#Word#,Word#,Word#,Word##)
我的外国程序只是一个一点点,但有点扭曲,所以我不认为我想要什么 _GC
给我。我看过的GHC源代码的一些相关位,FWIW和background:
编译器/前奏/ ForeignCall.hs:只有Risky省略了_GC
数据安全性
= PlaySafe - 可以调用Haskell GC,或者进行回调或
- 切换线程等。因此,在通话之前确保事情是
- tidy。此外,在线程
- RTS中,我们安排外部调用被执行
- 由单独的OS线程执行,即_concurrently_到
- 执行其他Haskell线程。
| PlayInterruptible - 与PlaySafe一样,但另外
- 运行此外部调用的工作线程可能
- 会被不必要地终止,因此必须在未绑定的线程上调度
。
| PlayRisky - 以上都不会发生;该调用将返回
- 不与所有运行时系统交互
派生(Eq,Show,Data)
- 仅用于显示Lex.Token的显示,我认为
我还看到一些外部import prim unsafe
和 ... safe
在GHC树中,但我认为它是死代码。例如 testsuite / tests / printer / Ppr046.hs
。
所以我的问题是:
- 从
__ pkg_ccall_GC
与a__ pkg_ccall $生成的代码之间有什么区别c $ c>在这种情况下(我在做
foreign import prim
不是ccall
)?是否与 here 中描述的相同? - 为什么不是
foreign import unsafe
似乎被支持吗? - 假设我明白了(1):有没有我可以工作的(1)?
$ b是否有效地返回多个值并避免发生$ b
编辑:从 -ddump-asm
查看程序集清楚地说明没有任何事情发生(不应该有人害怕看看大会),支持雷德巴顿的评论如下:
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
似乎都是一件坏事,尽管...
正如里德巴顿指出的 __ pkg_ccall_GC
不表示任何东西。生成的代码不会执行您在 safe
FFI调用中看到的簿记。
This is a followup to my earlier question here. I've been able to get something working per Reid Barton's answer, but I notice in the core I see __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)
Which is I think what you'd expect for a "safe" ffi call. Yet adding "unsafe" to the foreign import string is not allowed (though the error messages doesn't say why):
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# #)
My foreign procedure is just a little but of bit-twiddling, so I don't think I want whatever the _GC
is giving me. Some relevant bits of GHC source I've looked at, FWIW and background:
compiler/prelude/ForeignCall.hs: only "Risky" omits the "_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
I also see some foreign import prim unsafe
and ... safe
in the GHC tree, though I suppose it's dead code. e.g. testsuite/tests/printer/Ppr046.hs
.
So my questions are:
- What is the difference between code generated from a
__pkg_ccall_GC
vs a__pkg_ccall
in this case (where I'm doingforeign import prim
notccall
)? Is it the same as described here? - Why doesn't a
foreign import prim unsafe
seem to be supported? - Assuming I understand (1): Is there anyway I can work around this, getting both efficient return of multiple values and avoiding whatever bookkeeping is happening in (1)?
EDIT: Looking at the assembly from -ddump-asm
makes it clear nothing much is happening (shouldn't have been scared to look at the assembly), support Reid Barton's comment below:
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
towards the top corresponds to a haskell xor
. All those movq
do seem to be a bummer though...
As Reid Barton points out the __pkg_ccall_GC
doesn't indicate anything. The code generated doesn't do the bookkeeping you would see in a safe
FFI call.
这篇关于为什么没有'外国进口原料不安全'?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!