2017-01-08 3 views
8

これは私の以前の質問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

は、だから私の質問は以下のとおりです。

  1. (私はないccallforeign import primをやっている)この場合__pkg_ccall__pkg_ccall_GCから生成されたコードの違いは何ですか?それはhereと同じですか?
  2. foreign import prim unsafeがサポートされているように見えるのはなぜですか?
  3. 私は(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は、しかし、ぼんやりとしているようです...

+1

生成されたCmmを見ると、安全な呼び出しの周りに見える 'suspendThread' /' resumeThread'のものはありません。なぜコアで '__pkg_ccall_GC'と表示されているのか分かりません。 –

+0

@ReidBartonありがとうございました:)私は少しバグを報告すべきだと思いますか? – jberryman

+3

テールコールの前に正しいレジスタに引数を渡すための 'movq 'はありませんか?彼らは私に冗長に見えません。 – augustss

答えて

2

Reid Bartonが指摘しているように、__pkg_ccall_GCは何も示していません。生成されたコードは、safe FFIコールで表示される簿記を行いません。

関連する問題