Tenshi的类型系统<续>
Tenshi的内存池算法

Tenshi的函数接口

太阳神上 posted @ 2008年4月11日 15:13 in Tenshi with tags Tenshi , 1579 阅读

  脚本语言的函数一般都有一个C语言的函数原型,以便程序进行扩展,与C进行交互,这对于脚本语言几乎是必须的,那么,就要设计出一个合适的函数接口。在设计过程中,要考虑到以下一些问题:
(1)接口是否要一致的问题
  在同一个脚本语言中,不同类型的函数是否可以使用不同的接口。如使用三个操作数的函数与使用两个操作数的函数,或是有返回值的函数与返回值的函数。一般的脚本语言一般只能使用统一的接口,但由于Tenshi使用了JIT的技术,因此完全可以采用不同的接口,使用不同接口的好处是使得编译成的函数可以与一般的C函数相近或完全相同,这样写扩展时就非常方便了。但是接口如果不统一,同时也带来了一些复杂性,我们还必须保存函数的原型,而且动态类型的动态特性也就大为折扣。而且很多动态类型的函数参数都是不固定的,由此,我决定还是使用统一的接口。
(2)是否使用解释器引用作为参数
  我最早的设计中,函数接口就是简单的

  1. typedef void (* tns_api)(TInterpreter *)

  可以说,这个接口非常简洁,而且功能足够强大,一个函数的参数可以从这个解释器引用中获得,同时返回值也是在这个解释中设置。不过这样的设计对于写扩展的确有些麻烦,Lua的设计与此类似,不过返回值是int,用来表示返回值的个数。由于使用了JIT,我于是想用JIT来获得更高的执行效率,尽量使用系统的堆栈,而不是设置于解释器中。如果是这样,解释器引用反而在很多时候用不上,偏偏每次都得传入这个参数,有些麻烦。不过有了解释器引用参数,就可以有了很多扩展的余地,同时也容易方便地实现异常处理等。将来如果添加更多功能时就非常有用了。
(3)不定参数如何参数
  由于脚本语言的特点,一个函数的参数往往不是固定的,这样一来所有的参数必须放置在数组中传入。这样一来,就有一个问题,如何确定参数的个数?一种是像C语言的字符串那样使用一个哨位,也就是最后一个值使用空引用,另外一种是像C语言main参数那样,参数个数和参数数组都是两个不同的参数,参数的个数不是通过参数数组中的哨位隐含确定,而是直接给出。
  我选择的是后一种,虽然前者的好处有便于遍历和简化接口的作用。
(4)返回值的设置
  由于Tenshi的基本元素是一个结构体,是机器字长的两倍,这样一来如果直接使用返回值就比较麻烦。于是就干脆传一个返回值引用好了。只需设置这个值即可。
(5)参数传引用还是传值
  本来按照一般的习惯,一般函数的参数都是传值,不过感觉统一传引用更方便,这样一样要省掉很多心思,甚至左右值都可以轻松处理了。反正都统一看成引用。
  综上以上考虑,最后的方案如下: 

  1. typedef void (*tns_api)(TInterpreter *tns, //解释器引用
  2.    TObject* result, // 返回值引用
  3.    int argc, //参数个数
  4.    TObject *argv[]); //参数数组

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter