Как запустить Haskell на GraalVM? - PullRequest
4 голосов
/ 20 июня 2019

Я пытался запустить Haskell на GraalVM , но я не смог включить среду выполнения. В Rust достаточно указать правильный путь для стандартной библиотеки Rust, как описано здесь .

Есть ли такое же простое решение для Haskell? Это вообще возможно?

1 Ответ

4 голосов
/ 20 июня 2019

Это не полный ответ, но это большая часть пути.Это не слишком сложно:

Среда выполнения Haskell - это просто библиотека, которую вы можете найти в вашей установке GHC.На моем Mac он находится в $PREFIX/lib/ghc-$VERSION/rts, где $PREFIX - это префикс установки GHC (например, /, /usr, /usr/local и т. Д. - исполняемый файл компилятора должен быть $PREFIX/bin/ghc).Вам нужно использовать одну из разделяемых библиотек (для меня они называются .dylib s).Однако ни среда выполнения Haskell, ни скомпилированный код Haskell не содержат main.GHC создает файл-заглушку C:

#include "Rts.h"
extern StgClosure ZCMain_main_closure;
int main(int argc, char *argv[])
{
 RtsConfig __conf = defaultRtsConfig;
 __conf.rts_opts_enabled = RtsOptsSafeOnly;
 __conf.rts_opts_suggestions = true;
 __conf.rts_hs_main = true;
 return hs_main(argc,argv,&ZCMain_main_closure,__conf);
}

, где ZCMain_main_closure относится к действию main, написанному на Haskell, а hs_main относится к символу из RTS.Вам нужно будет скомпилировать это в битовый код с clang, скомпилировать код Haskell с ghc, llvm-link их в один большой .bc, а затем передать его в GraalVM lli.С учетом вышеприведенного в c_main.c, поместите пример программы в Main.hs:

main = putStrLn "Hello, World!"

Компиляция и ссылка:

$ clang -emit-llvm -I/usr/local/lib/ghc-8.6.5/include -c c_main.c
# Change -I path as needed
$ ghc -fllvm -keep-llvm-files -S Main.hs
$ llvm-link Main.ll c_main.bc -o prog.bc

Теперь, в идеальном мире, будет работать следующее:

$ lli --lib /usr/local/lib/ghc-8.6.5/rts/libHSrts-ghc8.6.5.dylib \
      --lib /usr/local/lib/ghc-8.6.5/base-4.12.0.0/libHSbase-4.12.0.0-ghc8.6.5.dylib \
      prog.bc
# Maybe you need more of the base libraries
# It's kind of hard to test because it doesn't work, anyway

Однако это не работает, потому что библиотеки имеют взаимные зависимости.base, написанный в основном на Хаскеле, нуждается в RTS.RTS подключается к base для связи с Haskell (например, с исключениями).GraalVM пытается dlopen их по одному с RTLD_NOW, который пытается и не может строго разрешить символы.Для этого нужно будет использовать RTLD_LAZY.Это должно быть легко исправимо в GraalVM.

...