W jaki sposób programy Haskell są kompilowane i wykonywane wewnętrznie?

Mam problem ze zrozumieniem jak Haskell (GHC) kompiluje programy i jak te programy są uruchamiane.

    GHC jest kanonicznym przykładem nietrywialnego programu napisanego w Haskell. Jednak część GHC wydaje się nie być napisana w Haskell, a mianowicie w środowisku uruchomieniowym (w C / C--). Dlaczego? Przyczyny wydajności? (Jestem świadomy tej strony i jej przyjaciół, ale nie może mieć z nich większego sensu.)
  1. mówiąc o środowisku runtime: dlaczego jest skompilowany język potrzebujesz? Czy skompilowany program nie powinien być kodem maszynowym i niczym innym? Z tego, co rozumiem, środowisko uruchomieniowe jest nieco podobne do maszyny Wirtualnej lub interpretera kodu bajtowego, który zajmuje się jakąś formą meta kodu i wykonuje rzeczywiste obliczenia na tej podstawie. Więc: co dokładnie robi GHC runtime i dlaczego jest to konieczne w pierwszej kolejności?
  2. odnośnie FFI: jak obsługiwane są połączenia C? Początkowo myślałem, że używając FFI generuje jeden plik wykonywalny gdzie Haskell i C są kompilowane razem. Jednak, czytałem wiele razy, że programy GHC rodzaj zrobić wywołanie z programu do funkcji C. Jest to szczególnie istotne, aby zrozumieć problem FFI z programowaniem równoległym. Więc: czym różnią się funkcje FFI od normalnych funkcji Haskella?
Author: David, 2012-09-14

3 answers

Aby skompilować i uruchomić język programowania na stockowym sprzęcie, potrzebujesz kilku rzeczy:

  • kompilator do tłumaczenia języka źródłowego na kod assembly wykonywalny przez natywny host
  • biblioteka wsparcia (aka runtime) dla prymitywnych usług językowych, takich jak zarządzanie pamięcią, IO i zarządzanie wątkami. Rzeczy, które należy wykorzystać z usług systemowych niższego poziomu.

C, Java i GHC Haskell są przykładami takich systemów. W przypadku GHC, cała architektura jest opisana tutaj . Utwory są również opisywane indywidualnie i szczegółowo.

 26
Author: Don Stewart,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-14 12:08:12

Mogę zaoferować pewną precyzję co to jest runtime.

Maszyna wirtualna jest "rodzajem" środowiska wykonawczego , ale nie jedynym. System runtime to po prostu środowisko (i zestaw usług), które twój program może założyć, że będzie obecny podczas jego wykonywania. Nawet języki bardzo niskiego poziomu, takie jak C i C++, mają systemy uruchomieniowe (pomyśl o malloc... ktoś / coś robi przydział dla Ciebie, a nawet podział przez zero kontroli).

Ogólnie języki wyższego poziomu mają bogatsze środowisko uruchomieniowe (co oznacza, że runtime oferuje więcej usług dla wykonującego program), od zarządzania pamięcią (np. garbage collection)po infrastrukturę refleksyjną / introspekcyjną (think ruby itd...) do sprawdzania granic tablicy, ale prawie wszystkie języki mają jakiś system runtime (jeśli tylko system operacyjny).

 13
Author: GreyGeek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-14 02:36:18

1: Dlaczego RTS nie jest napisany w Haskell?

Ponieważ robi rzeczy niskiego poziomu, które nie mogą być wyrażone w Haskell. Podobnie jak jądro Linuksa jest systemem do uruchamiania programów w języku C, a mimo to części jądra Linuksa są napisane w assembly, a nie w C. {]}

2: Dlaczego skompilowany program potrzebuje środowiska uruchomieniowego? Z tego co rozumiem, to coś w stylu Java bytecode interpreter.

GHCi używa czegoś prawie dokładnie takiego jak kod bajtowy Javy Tłumacz. skompilowane programy GHC nie; skompilowany program jest surowym kodem maszynowym.

Raczej, Haskell RTS jest bardziej jak rodzaj mini-OS. Zajmuje się zarządzaniem pamięcią, wykonuje thread sheduling, wykonuje pewne aspekty obsługi wyjątków, wykonuje obsługę transakcji. Każdy program Haskell działa pod tym mini-OS.

(jest to trochę tak, jakby program C był skompilowany , to jest to surowy kod maszynowy, ale nadal nie można uruchomić bez system operacyjny jak Windows, Linux czy coś.)

Na przykład, za każdym razem, gdy program Haskell kończy pamięć, program Haskell przestaje działać, a garbage collector zaczyna działać. Garbage collector próbuje zwolnić trochę pamięci, a gdy już to zrobi, program Haskell zaczyna działać ponownie.

Każdy skompilowany program Haskell posiada kopię tego programu garbage collector, który jest tylko częścią programu Haskell RTS. Podobnie, wiele wątków Haskell może działać wewnątrz jeden wątek OS, więc RTS ma w sobie scheduler wątków. Mogę kontynuować...

3: Jak działa FFI? Myślałem, że wszystko zostało skompilowane.

It is all compiled [a raczej linked] together. Jeśli napiszesz program C, jedna funkcja C może wywołać inną funkcję C. Gdy Haskell wywołuje funkcję C, jest to prawie jak każda inna funkcja wywołująca tę funkcję C. W zależności od tego, co robi wywołanie funkcji, jest kilka rzeczy, które dzieją się na Haskell side jednak, który może dodać trochę nad głową.

 7
Author: MathematicalOrchid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-15 09:12:22