2010-12-13 9 views
15

Piszę silnik skryptowy LLVM, który JIT kompiluje kod skryptu w niestandardowym języku. Mój problem polega na tym, że nie mogę wywoływać funkcji zewnętrznych (nawet funkcja erf() w C99 nie działa).Łączenie kodu JIT LLVM z zewnętrznymi funkcjami C++

Na przykład jeśli extern "C" funkcji erf,

extern "C" double erft(double x){ 
return erf(x); 
} 

i utworzyć funkcję z zewnętrznym wiązaniem

std::vector<const Type*> Double1(1,Type::getDoubleTy(getGlobalContext())); 
FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()),Double1,false); 
Function *erft = Function::Create(FT,Function::ExternalLinkage,"erft",TheModule); 

pojawia się następujący komunikat o błędzie podczas uruchamiania mój skrypt z Erft (0.0)

LLVM ERROR: Program used external function 'erft' which could not be resolved!

Robi mapowanie ręcznie

void ExecutionEngine::addGlobalMapping(const GlobalValue * erfF, void * erft); 

dostanie mi się następujący błąd:

declaration of `void llvm::ExecutionEngine::addGlobalMapping(const llvm::GlobalValue*, void*)' outside of class is not definition

Oczywiście robię coś bardzo złego. Każda pomoc będzie mile widziane

+1

Ostrzeżenie dla przyszłych odwiedzających: odpowiedzi odnoszą się do przestarzałych metod. – antipattern

+0

Odpowiedź na [to] (https://stackoverflow.com/questions/48105342/llvm-jit-add-library-to-module) Pytanie pokazuje, jak to zrobić z nie-przestarzałymi metodami. –

Odpowiedz

0

nie wiem LLVM, ale to nie ma sensu:

void ExecutionEngine::addGlobalMapping(const GlobalValue * erfF, void * erft); 

który definiuje nową funkcję w C++. Musisz tylko zarejestrować swoją funkcję za pomocą LLVM. Zdefiniowanie tej funkcji przypomina próbę dodania nowych metod do klas LLVM, a nie tego, co chcesz zrobić.

2

To może się dziać, ponieważ zapomniałeś dodać „libm” zależności, spróbuj:

[your module]->addLibrary("m"); 

Zobacz here uzyskać więcej informacji na temat Module::addLibrary().

13

Zakładając, że go nie wyłączyłeś (dzwoniąc pod numer EE->DisableSymbolSearching()), wówczas LLVM użyje dlsym(), aby znaleźć symbole w samym programie JIT. W zależności od platformy może to oznaczać, że musisz zbudować swój JIT pod numerem -fPIC lub że może on w ogóle nie być dostępny (na przykład w systemie Windows).

Oprócz automatycznego wyszukiwania symboli, zawsze można zarejestrować poszczególne funkcje samodzielnie, używając EE->addGlobalMapping(GV, &function) gdzie GV = deklaracja funkcji llvm :: Function *, która odpowiada natywnej funkcji, do której dzwonisz. W twoim przypadku z ERTF() to:

EE->addGlobalMapping(erft, &::erft); 

pamiętać, że nazwał globalną funkcję erft() i lokalną zmienną erft, stąd „::”. Proszę wybrać inne nazwiska następnym razem!

Powiązane problemy