#include #include uint64_t uwsgi_libtcc_counter = 0; static int uwsgi_libtcc_hook(char *arg) { char *func_base = "uwsgi_libtcc_func"; size_t func_len = strlen(func_base) + sizeof(UMAX64_STR); char *func_name = uwsgi_malloc(func_len); if (snprintf(func_name, func_len, "%s%llu", func_base, uwsgi_libtcc_counter) < (int) strlen(func_base)) { free(func_name); return -1; } uwsgi_libtcc_counter++; size_t source_len = 64 + func_len + strlen(arg); char *source = uwsgi_malloc(source_len); if (snprintf(source, source_len, "void %s() { %s ;}", func_name, arg) < (int) ( strlen(func_base) + strlen(arg))) { free(func_name); free(source); return -1; } TCCState *s = tcc_new(); if (tcc_compile_string(s, source)) goto error; if (tcc_relocate(s, TCC_RELOCATE_AUTO)) goto error; void (*func)() = tcc_get_symbol(s, func_name); if (!func) goto error; free(func_name); free(source); // call the function func(); tcc_delete(s); return 0; error: free(func_name); free(source); tcc_delete(s); return -1; } static void uwsgi_libtcc_setup() { uwsgi_register_hook("tcc", uwsgi_libtcc_hook); } struct uwsgi_plugin libtcc_plugin = { .name = "libtcc", .on_load = uwsgi_libtcc_setup, };