2017-01-08 44 views
8

Bu, önceki soruma ait here numaralı takip için bir takiptir. Ben __pkg_ccall_GC bkz ben Reid Barton's answer başına çalışan bir şey almak mümkün oldum ama özünde fark:Niçin 'yabancı ithalat prim güvensiz' yok?

   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) 

İşte bu yüzden "güvenli" bir ffi çağrısı için beklediğiniz düşünüyorum.

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# #) 

Benim yabancı prosedür sadece küçük ama bit twiddling taşımaktadır, bu yüzden yok: Yine yabancı ithalat dizesine "emniyetsiz" ekleyerek (hata iletileri olsa neden farklı) izin verilmez _GC'un bana verdiği her şeyi istediğimi düşünüyorum.

derleyici/başlangıcı/ForeignCall.hs: Ben, FWIW ve arka baktım GHC kaynağının Bazı alakalı bitleri sadece "Riskli" Ben de ve bazı foreign import prim unsafe bkz

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" atlar GHC ağacında ... safe, yine de ölü kod olduğunu varsayalım. Örneğin. testsuite/tests/printer/Ppr046.hs.

Yani benim sorular şunlardır:

  1. (Ben ccallforeign import prim yapıyorum) bu durumda bir __pkg_ccall vs bir __pkg_ccall_GC oluşturulan kodu arasındaki fark nedir? here açıklandığı gibi mi?
  2. Neden foreign import prim unsafe desteklenmiyor gibi görünüyor?
  3. Anladığımı varsayarsak (1): Her halükarda bunun üzerinde çalışabilirim, hem birden çok değerin verimli geri dönüşünü elde etmek hem de (1) 'de her hangi bir defter tutma olayından kaçınmaktan kaçınıyorum?

DÜZENLEME: -ddump-asm gelen montaj baktığımızda o (montaj bakmak korkmuş olmamalıdır) oluyor çok net bir şey yapar, aşağıdaki destek Reid Barton'ın comment:

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 yukarı doğru bir haskell xor karşılık gelir. Tüm bu movq, bir bummer gibi görünmektedir ...

+1

Oluşturulan Cmm'ye bakarsanız, güvenli aramanın çevresinde gördüğünüz 'suspendThread' /' resumeThread' türlerinden hiçbiri yoktur. Neden Core'da '__pkg_ccall_GC', belki sadece bir ekran hatası olduğunu bilmiyorum. –

+0

@ReidBarton Bir kez daha teşekkürler :) Biraz hata yapmam gerektiğini düşünüyor musunuz? – jberryman

+3

Kuyrukta aramadan önce argümanları doğru kayıtlara almak için bu “mov” lar değil mi? Bana gereksiz bakmıyorlar. – augustss

cevap

2

Reid Barton'un işaret ettiği gibi __pkg_ccall_GC hiçbir şey belirtmiyor. Oluşturulan kod, safe FFI çağrısında göreceğiniz muhasebe işlemini yapmaz.