2017-01-08 7 views
8

이것은 내 이전 질문 here의 후속 조치입니다. 내가 __pkg_ccall_GC을 볼 나는 Reid Barton's answer 당 작업 뭔가를 얻을 수있었습니다,하지만 핵심에주의 사항 :왜 'foreign import prim unsafe'도 없습니까?

   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. (I하지 ccallforeign import prim하고 있어요)이 경우에 __pkg_ccall을 대 __pkg_ccall_GC에서 생성 된 코드의 차이점은 무엇입니까? 그것은 here과 동일합니까?
  2. foreign import prim unsafe이 지원되는 것 같습니다.
  3. 내가 이해한다고 가정하기 : 어쨌든 나는 여러 값을 효율적으로 반환하고 (1)에서 일어나는 부기를 피하면서이 문제를 해결할 수 있습니까?

편집 : -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

tail 호출 전에 올바른 레지스터에 인수를 가져 오는 'movq'가 아닌가요? 그들은 나에게 불필요하게 보이지 않는다. – augustss

답변

2

Reid Barton이 지적한대로 __pkg_ccall_GC은 아무 것도 표시하지 않습니다. 생성 된 코드는 safe FFI 통화에서 볼 수있는 부기를 수행하지 않습니다.