如何使用JIT编译从捕获的Lambda生成C指针回调? [英] How do you use JIT compilation to produce a C pointer callback from a captured lambda?

查看:77
本文介绍了如何使用JIT编译从捕获的Lambda生成C指针回调?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C ++ 11和更高版本中,转换没有捕获变量的lambda表达式非常简单,但是对于具有捕获变量的lambda,要正确执行此操作,则需要动态生成代码,如

In C++11 and later converting a lambda expression with no captured variables is very simple, but for lambdas with captured variables to do it properly requires dynamic code generation as per this guys answer.

基本上我认为必须动态生成的是这个. (请注意,这里的代码表示我想要的语义,而不是任何实际代码)

Basically what I figure will have to be dynamically generate is this. (Note the code here indicates my desired semantics not any real code)

UserData *userdata;
api_return_value callback(api_data arg) {
    return customized_callback(arg, userdata);
}

然后我将生成此代码,以便将动态生成的代码绑定到某些api中定义的相应函数指针回调

And I would generate this so I can bind the dynamically generated code to a corresponding function pointer callback defined in some api

api_return_value (*callback) (api_data);

是否存在使用LLVM或NativeJIT之类的合理干净且可移植的方式进行此操作?我一直在使用没有提供用户数据指针的C api,因此这似乎是我唯一的选择.

Is there a reasonably clean and portable way to go about this using something like LLVM or NativeJIT? I'm stuck using a C api with no provided user data pointer so this seems to be my only alternative.

推荐答案

您可以在编译时预创建"(外部"C")函数池并管理分配,而不是在运行时生成JIT代码.他们的游泳池.像这样:

Rather than doing JIT code generation at runtime, you can "pre-create" a pool of (extern "C") functions at compile time and manage an allocation pool of them. Something like:

#define REP10(P, M)  M(P##0) M(P##1) M(P##2) M(P##3) M(P##4) M(P##5) M(P##6) M(P##7) M(P##8) M(P##9)
#define REP100(M) REP10(,M) REP10(1,M) REP10(2,M) REP10(3,M) REP10(4,M) REP10(5,M) REP10(6,M) REP10(7,M) REP10(8,M) REP10(9,M)

extern struct func_wrap_t {
    func_wrap_t              *next;
    extern "C" void          (*c_fn)();
    std::function<void()>    fn;
} func_wrap_table[];
#define FUNC_WRAP_INIT(M) { M ? func_wrap_table+M-1 : 0, func_wrap_cfunc##M },
#define FUNC_WRAP_DEF(M) extern "C" void func_wrap_cfunc##M() { func_wrap_table[M].fn(); }
REP100(FUNC_WRAP_DEF)
func_wrap_t func_wrap_table[] = { REP100(FUNC_WRAP_INIT) };
func_wrap_t *func_wrap_freelist = &func_wrap_table[99];

将静态创建100个此类函数并将其链接到空闲列表.然后,您可以编写包装RAII类型,从该列表中分配它们,并在完成后返回它们.

will create 100 such functions statically and link them up into a freelist. You can then write a wrapper RAII type that allocates them from this list and returns them when finished.

这篇关于如何使用JIT编译从捕获的Lambda生成C指针回调?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆