在阅读Crystal-lang内部代码时,我遇到了一些片段,如:
@[Primitive(:some_name)]
def some_method
end
Run Code Online (Sandbox Code Playgroud)
任何人都可以解释一下该Primitive属性的作用及其工作原理(例如,告诉编译器使用LLVM函数)?
这是无法用纯Crystal表示的功能.每次调用此类方法时,都需要由编译器直接替换为低级指令(LLVM IR),而不是由实际函数支持.
这是必要的,因为一些操作已经处于最低级别.例如,如何实现添加两个数字?呃,a+b?等等,但这就是我们要实现的目标.因此,除了诉诸if a==1 && b==1 ...这种荒谬的事情之外,还需要推迟到CPU(通过LLVM IR).
文件primitives.cr只包含这些方法的空壳,还包含它们的文档,因此它们看起来像标准库的正常部分.它们由编译器标记,以便知道何时替换它们.实际操作发生在compiler/crystal/codegen/primitives.cr中:case每个注释名称都有一个分支,这会产生生成适当代码的代码.
为了完整起见,这里是来自primitives.cr的摘录:
这里定义的方法是原语,因为它们可以:
- 不能用Crystal表示(需要用LLVM表示).例如,一元和二元数学运算符属于这一类.
- 出于性能原因,应始终使用LLVM指令内联,即使在非发布版本中也是如此.这方面的一个例子是
Char#ord,可以通过分配self给变量并将指针强制转换为CrystalInt32,然后读回值来实现Crystal .
旁注:
这不是编译器实现不能成为普通stdlib方法的方法的唯一方法.这也发生了伪方法,如,在句法层面.这是一种甚至"更强大"的能力,并且它作为一种方法的伪装被删除(你将无法在Object的文档中找到).这种构造与编译器紧密相关,可以影响类型信息.obj.is_a?is_a?
| 归档时间: |
|
| 查看次数: |
95 次 |
| 最近记录: |