W przypadku deklaracji najwyższego poziomu nie jest to zbyt trudne. Lokalne definicje mogą być trudniejsze do rozpoznania, ponieważ ich nazwy zostają zniekształcone i prawdopodobnie zostaną przedstawione.
Zobaczmy, co się stanie, gdy skompilujemy ten prosty moduł.
module Example where
add :: Int -> Int -> Int
add x y = x + y
.data .align 8 .globl Example_add_closure .type Example_add_closure, @object Example_add_closure: .quad Example_add_info .text .align 8 .quad 8589934604 .quad 0 .quad 15 .globl Example_add_info .type Example_add_info, @object Example_add_info: .LckX: jmp base_GHCziBase_plusInt_info
.data
.align 8
_module_registered:
.quad 0
.text
.align 8
.globl __stginit_Example_
.type __stginit_Example_, @object
__stginit_Example_:
.Lcl7:
cmpq $0,_module_registered
jne .Lcl8
.Lcl9:
movq $1,_module_registered
addq $-8,%rbp
movq $__stginit_base_Prelude_,(%rbp)
.Lcl8:
addq $8,%rbp
jmp *-8(%rbp)
.text
.align 8
.globl __stginit_Example
.type __stginit_Example, @object
__stginit_Example:
.Lcld:
jmp __stginit_Example_
.section .note.GNU-stack,"",@progbits
.ident "GHC 7.0.2"
Widać, że nasza funkcja Example.add
spowodowało wygenerowanie Example_add_closure
i Example_add_info
. Część _closure
, jak sama nazwa wskazuje, ma związek z zamknięciami. Część _info
zawiera rzeczywiste instrukcje funkcji. W tym przypadku jest to po prostu skok do wbudowanej funkcji GHC.Base.plusInt
.
Należy zauważyć, że zestaw generowany z kodu Haskella wygląda zupełnie inaczej niż w innych językach. Konwencje wywoływania są różne i wiele rzeczy może się zmienić.
W większości przypadków nie należy przeskakiwać bezpośrednio do montażu. Zwykle znacznie łatwiej jest zrozumieć rdzeń, uproszczoną wersję Haskella. (Prostsze do kompilacji, niekoniecznie do czytania). Aby dostać się do rdzenia, skompiluj z opcją -ddump-simpl
.
Example.add :: GHC.Types.Int -> GHC.Types.Int -> GHC.Types.Int
[GblId, Arity=2]
Example.add =
\ (x_abt :: GHC.Types.Int) (y_abu :: GHC.Types.Int) ->
GHC.Num.+ @ GHC.Types.Int GHC.Num.$fNumInt x_abt y_abu
Aby uzyskać informacje na temat dobrego odczytu rdzenia, zobacz this question.