2010-12-13 53 views
15

J'écris un moteur de script LLVM qui compile le code de script dans un langage personnalisé. Mon problème est que je suis incapable d'appeler des fonctions externes (même la fonction C99 erf() échoue).Liaison du code JL de LLVM aux fonctions C++ externes

Par exemple, si j'extern "C" la fonction erf,

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

et créer une fonction avec lien externe

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); 

le message d'erreur suivant lors de l'exécution de mon script avec Erft (0.0):

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

Faire le mappage manuellement,

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

va me faire l'erreur suivante:

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

Il est évident que je fais quelque chose de très mal. Toute aide serait appréciée

+1

Un avertissement pour les futurs visiteurs: Les réponses se réfèrent à des méthodes obsolètes .. – antipattern

+0

La réponse à [this] (https://stackoverflow.com/questions/48105342/llvm-jit-add-library-to-module) question montre comment faire cela avec des méthodes non-obsolètes. –

Répondre

0

Je ne sais pas LLVM, mais cela n'a pas de sens:

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

qui définit une nouvelle fonction en C++. Ce que vous devez faire est en quelque sorte d'enregistrer votre fonction avec LLVM. Définir cette fonction, c'est comme essayer d'ajouter de nouvelles méthodes aux classes LLVM, pas ce que vous voulez faire.

2

Cela peut se produire parce que vous avez oublié d'ajouter le « libm » depedency, essayez d'utiliser:

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

Voir here pour plus d'informations sur le Module::addLibrary().

13

En supposant que vous ne l'avez pas désactivé (en appelant EE->DisableSymbolSearching()) alors LLVM utilisera dlsym() pour trouver les symboles dans le programme JIT lui-même. En fonction de votre plate-forme, cela peut signifier que vous devez construire votre JIT avec -fPIC, ou qu'il peut ne pas être disponible du tout (comme sur Windows). En plus de la recherche automatique de symboles, vous pouvez toujours enregistrer vous-même les différentes fonctions en utilisant EE->addGlobalMapping(GV, &function) où GV = la déclaration de fonction llvm :: Function * qui correspond à la fonction native que vous appelez. Dans votre cas avec FERV() qui est:

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

Notez que vous avez nommé la fonction globale erft() et la variable locale erft, d'où le « :: ». S'il vous plaît choisir des noms différents la prochaine fois!