2010-05-10 9 views
16

Jestem w trakcie wdrażania aplikacji wieloplatformowej (Mac OS X, Windows i Linux), która wykona wiele intensywnych analiz danych finansowych. Większość mechanizmu analizy zostanie napisana w języku C++ ze względu na szybkość, z dostępnym dla użytkownika mechanizmem skryptowym współpracującym z silnikiem testującym C++. Chcę napisać kilka skryptów z wyprzedzeniem, aby emulować inne popularne oprogramowanie z istniejącymi dużymi bazami użytkowników. Pierwszym frontem będzie język skryptowy podobny do VisualBasic.Łączenie kodu JL LLVM ze statycznymi bibliotekami LLVM?

Myślę, że LLVM byłby idealny do moich potrzeb. Wydajność jest bardzo ważna ze względu na ogromną ilość danych; przeprowadzenie jednego testu może potrwać kilka godzin lub dni, aby uzyskać odpowiedź. Wierzę, że korzystanie z LLVM pozwoli mi również korzystać z jednego rozwiązania back-end, podczas gdy zaimplementuję różne front-endy dla różnych smaków języka skryptowego w czasie.

Sam silnik testowy zostanie oddzielony od interfejsu, a testowanie będzie nawet odbywać się w oddzielnym procesie z postępem, a wyniki będą raportowane do interfejsu zarządzania testowaniem. Testy będą składały się z kodu skryptowego zintegrowanego z kodem silnika testującego.

W poprzedniej implementacji podobnego komercyjnego systemu testowego, który napisałem, zbudowałem szybki interpreter, który łatwo łączył się z biblioteką testową, ponieważ został napisany w C++ i połączony bezpośrednio z biblioteką silników testujących. Odwołania od kodu skryptu do testowania obiektów biblioteki polegały na tłumaczeniu formatów ze znacznym narzutem.

Wyobrażam sobie, że z LLVM, mógłbym zaimplementować wywołania zwrotne w C++ bezpośrednio, tak żebym mógł sprawić, by kod skryptowy działał prawie tak, jakby był napisany w C++. Podobnie, jeśli cały kod został skompilowany do formatu kodu bajtowego LLVM, wydaje się, że optymalizatory LLVM mogą zoptymalizować granice między językiem skryptowym a kodem silnika testującego, który został napisany w C++.

Nie chcę kompilować silnika testowego za każdym razem. Idealnie chciałbym, aby JIT skompilował tylko kod skryptu. W przypadku niewielkich testów pominąłbym kilka przejść optymalizacyjnych, natomiast w przypadku dużych testów wykonałbym pełne optymalizacje podczas połączenia.

Czy to możliwe? Czy mogę wstępnie skompilować silnik testujący do pliku obiektu .o lub pliku biblioteki .a, a następnie połączyć kod skryptowy za pomocą JIT?

Na koniec, chciałbym, aby kod skryptowy implementował określone metody jako podklasy dla określonej klasy C++. Tak więc silnik testujący C++ widziałby tylko obiekty C++, podczas gdy kod instalacyjny JIT skompilował kod skryptowy, który zaimplementował niektóre metody dla obiektów. Wydaje się, że gdybym użył prawidłowego algorytmu mapowania nazw, stosunkowo łatwo byłoby ustawić generację LLVM dla języka skryptowego, tak aby wyglądał jak wywołanie metody C++, które następnie może być połączone z silnikiem testowym.

Tak więc etap łączenia prowadziłby się w dwóch kierunkach, wywoływania z języka skryptowego do obiektów mechanizmu testowego w celu pobrania informacji o cenach i informacji o stanie testu oraz wywołań z silnika testowego metod niektórych konkretnych obiektów C++, w których dostarczono kod nie z C++, ale z języka skryptowego.

Podsumowując:

1) Czy mogę połączyć w prekompilowanymi (albo .BC, .o lub .a) pliki jako część kompilacji JIT, procesu kod generacji?

2) Czy mogę połączyć kod za pomocą procesu w 1) powyżej w taki sposób, że mogę utworzyć kod, który działa tak, jakby był napisany w C++?

Odpowiedz

14
  1. Tak, możemy! W zależności od używanej wersji LLVM istnieją różne wywołania interfejsu API. będziesz potrzebował llvm :: getBitcodeModuleProvider w wersji 2.5.
  2. Najprostszym sposobem wywoływania funkcji C++ jest utworzenie funkcji (llvm :: Function :: Create) za pomocą flagi llvm :: Function :: ExternalLinkage, a następnie addGlobalMapping, aby wskazywała na twoją funkcję C++.
+0

Dziękuję za pomoc. Sprawdzę to. – inflector

3
  1. Tak sądzę.
  2. To jest włochate. Musisz dopasować ABI ABI do funkcji, do których dzwonisz, i musisz upewnić się, że wygenerowany kod wykorzystuje te same struktury danych, klasy, układ, itp. (Poprzez odpowiednik plików nagłówkowych). ABI AB ma wiele niuansów i problemów z przenośnością. Być może prototyp z robieniem współdziałania z C najpierw. clang ma teraz ograniczone wsparcie dla C++.
1

1) Możesz załadować i połączyć pliki .bc, pliki .o, jeśli zostały połączone z archiwum .so, powinny być ładowalne, a symbole w nich powinny być możliwe do użycia.

2) Tak długo, jak nie chcesz robić okropnych rzeczy za pomocą wywołań zwrotnych, prawdopodobnie możesz po prostu przekazać standardowe wskaźniki funkcyjne C i wywoływać zwrotne połączenia za pomocą wskaźników funkcji. Możesz robić także inne rzeczy, ale zajmowanie się próbami definiowania obiektów lub szablonów C++ lub funkcji członków wywołania bez bycia kompilatorem C++ jest czymś, czego nie chcesz robić.

musisz znać C++ ABI, musisz wiedzieć o platformie, na którą celujesz, musisz znać różne rzeczy, faktycznie musisz być kompilatorem C++, aby wygenerować kod, który wygląda tak, jak C++. Nazwa mangler jest jedną z najbardziej irytujących części.