これは私の以前の質問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
が私に与えていることを何でも欲しいと思う。
コンパイラ/プレリュード/ ForeignCall.hs::私は、FWIW、バックグラウンドで見てきたGHCソースのいくつかの関連ビットのみ「危険は」私も、いくつかforeign import prim unsafe
を参照してください
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
「_GC」を省略しますGHCツリーには... safe
がありますが、それはデッドコードだと思います。例えばtestsuite/tests/printer/Ppr046.hs
。
は、だから私の質問は以下のとおりです。
- (私はない
ccall
foreign import prim
をやっている)この場合__pkg_ccall
対__pkg_ccall_GC
から生成されたコードの違いは何ですか?それはhereと同じですか? foreign import prim unsafe
がサポートされているように見えるのはなぜですか?- 私は(1)を理解していると仮定します。とにかく、複数の値を効率的に返し、(1)で起こっている簿記を回避することができますか?
EDIT:-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
は、しかし、ぼんやりとしているようです...
生成されたCmmを見ると、安全な呼び出しの周りに見える 'suspendThread' /' resumeThread'のものはありません。なぜコアで '__pkg_ccall_GC'と表示されているのか分かりません。 –
@ReidBartonありがとうございました:)私は少しバグを報告すべきだと思いますか? – jberryman
テールコールの前に正しいレジスタに引数を渡すための 'movq 'はありませんか?彼らは私に冗長に見えません。 – augustss