关于elisp ffi的调查

elisp似乎并没有关注是否应该实现一套标准的elisp cffi。

我不清楚emacs module机制出现的确切时间,但是module机制或许减弱了对ffi的需求。我发现了一些很早的项目,这些工作致力于在emacs中实现一套可用的cffi:

emacs-with-ffi 是基于emacs 25的源码补丁,为emacs增加了ffi feature,但是存在内存泄漏和崩溃等问题,作者在提交了最后一个名为no idea的补丁之后弃坑了。

elisp-ffi用cpp实现了一个简单的胶水,直接通过读写std流进行交互。因此,它不需要改造emacs,是一个有趣的小玩具。

emacs-ffi基于emacs module和libffi实现,看上去是里面设计最好的一个了,但是在7年前也停止了维护。

通过比较这些项目,我认为实现ffi接口面临的主要问题是:

  1. 实现安全的参数传递,这需要正确的类型转译以及对象生命周期管理。对于潜在的同步问题需要提供对应的同步机制(这可能会非常困难)。
  2. 实现错误处理机制,当函数调用失败时可以捕获错误,不应该导致调用者挂死。

上述实现都只是简单地实现了类型转译和函数接口的封装。从issue来看,它们对于内存和线程同步问题都存在不同程度的明显的bug,也没有专门设计任何错误处理。

Guile Emacs似乎是唯一把这些问题纳入考量的。虽然它的目的不是实现ffi,而是elisp到guile的翻译器。这件事比实现cffi要困难得多,它的目标差不多是用scheme实现emacs,尽管原有的c代码对guile是透明的,但是它们本身有不同的内存布局和工作机制。目前这个项目处于停滞状态。

在某些我们觉得对lisp理所当然的事情上,elisp似乎已经无法跟上了……

GNU Emacs 是故意不提供 ffi 的,就是为了防止 Emacs 加载非自由的库。

论坛里查一下就知道了,25

可是用module也可以加载第三方库啊,这是上游主动放开了吗?按LdBeth的引用,module的引入发生在2016年,这些项目大多发起于2015年之前。

我出生还不到12个火星年,不太清楚上游社区发生的事情。

module 要声明一个符号 plugin_is_GPL_compatible 不然 Emacs 会拒绝加载

XEmacs 2002 年就有了 Emodules,但是 2013 年后开发基本停滯了。GNU Emacs 在 RMS 以加上上面的限制为条件才同意以后开始才把 XEmacs 的功能逆向过来。

额……像emacs-ffi这样子加载一个专门用来加载第三方库的第三方库的做法是不是钻了空子?

不算,因为本身用户自己修改 Emacs 链接非自由软件只是自己用也不违反 GPL