Comment comstackr un code C pendant le temps d’exécution et obtenir un pointeur sur la fonction correspondante?

Supposons que je génère un programme C pendant le temps d’exécution:

source = "int add_x_y(int x, int y){ return x + y; }"; source_size = 42; 

Je veux la fonction suivante:

 void* comstack(char* source, int source_size); 

Tel que:

 int (*f)(int,int) = comstack(source, source_size); printf("%d\n",f(2,3)); 

Les sorties:

 5 

Et comstack ne peut pas dépendre d’outils externes (compilateurs), car j’aimerais l’utiliser dans emscripten (qui convertit un programme C en un fichier .js).

Est-ce possible?

Quelqu’un d’autre peut probablement mieux préciser certains détails que moi, mais si cela ne vous dérange pas d’appeler GCC ou de vous y connecter, cela devrait être faisable. Si vous écrivez le code dans un fichier, comstackz-le dans une bibliothèque partagée (.SO). À partir de là, il suffit de charger la bibliothèque partagée et d’obtenir l’adresse du symbole souhaité.

Il est spécifique au système d’exploitation et au processeur. Je suppose que vous êtes sur Linux x86-64 (64 bits x86) ou ia32 (32 bits x86)

Vous pouvez utiliser tinycc (c’est un compilateur qui comstack rapidement le code C en code machine très lent et non optimisé) qui fournit une bibliothèque libtcc contenant une fonction tcc_comstack_ssortingng .

Vous pouvez utiliser une bibliothèque de compilation JIT telle que libjit , GNU lightning , asmjit , LLVM (et GCC 5 aura des capacités JIT-ing ).

Et vous pourriez simplement écrire votre chaîne dans un fichier C temporaire /tmp/genfoo.c (si ce fichier se trouve dans un système de fichiers tmpfs , aucune /tmp/genfoo.c / /tmp/genfoo.c disque réelle n’est impliquée, elle est donc rapide), puis créez une commande réelle:

 gcc -Wall -fPIC -shared -O /tmp/genfoo.c -o /tmp/genfoo.so 

puis dlopen (3) l’object partagé /tmp/genfoo.so produit (et dlsym pour obtenir un pointeur de fonction à partir de son nom).

Si vous voulez des performances du code généré, vous avez besoin d’un vrai compilateur d’optimisation tel que GCC ou Clang / LLVM ; la tâche d’écriture d’un fichier source temporaire (et son parsing dans le compilateur) est négligeable: l’essentiel du travail est effectué à l’intérieur du compilateur lors de passes d’optimisation. La génération de code C est pratique, en particulier lorsque vous souhaitez que le code généré soit optimisé par un compilateur C.

Notez que toutes ces techniques ne fonctionneront probablement pas dans emscripten , tout simplement parce que vous ne pouvez probablement pas transtyper un pointeur de données sur un pointeur de fonction font un tel casting dans votre question)! Si vous avez besoin de générer du code dans un navigateur, vous aurez probablement besoin de générer du Javascript ou un sous-ensemble de celui-ci (par exemple, pour asm.js ). Voir l’ appel de Javascript depuis C / C ++ dans Emscripten

Si vous développez un langage à utiliser dans le navigateur, faites-le générer du Javascript (par exemple, asm.js ).

Voir aussi NaCl (Client natif sur les navigateurs Google)