Crystal-lang中的'Primitive'属性是什么?

Max*_*Max 1 crystal-lang

在阅读Crystal-lang内部代码时,我遇到了一些片段,如:

@[Primitive(:some_name)]
def some_method
end
Run Code Online (Sandbox Code Playgroud)

任何人都可以解释一下该Primitive属性的作用及其工作原理(例如,告诉编译器使用LLVM函数)?

Ole*_*pin 5

这是无法用纯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给变量并将指针强制转换为Crystal Int32,然后读回值来实现Crystal .

旁注:
这不是编译器实现不能成为普通stdlib方法的方法的唯一方法.这也发生了伪方法,如,在句法层面.这是一种甚至"更强大"的能力,并且它作为一种方法的伪装被删除(你将无法在Object的文档中找到).这种构造与编译器紧密相关,可以影响类型信息.obj.is_a?is_a?

  • 很棒的答案!鉴于这从未被解释过,你能够如此彻底地解释它真的很棒. (2认同)