Crystal-lang中的“原始”属性是什么?

时间:2018-08-18 21:09:10

标签: crystal-lang

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

@[Primitive(:some_name)]
def some_method
end

有人可以向我解释Primitive属性的作用以及它的工作方式(例如,告诉编译器使用LLVM函数)吗?

1 个答案:

答案 0 :(得分:5)

这是无法用纯Crystal表示的功能。每当出现对这种方法的调用时,都需要由编译器直接将其替换为低级指令(LLVM IR),而不是由实际函数来支持。

这是必需的,因为某些操作已经处于最低级别。例如,如何实现两个数字的加法?嗯,a+b?等等,但这就是我们要实现的。因此,除了诉诸if a==1 && b==1 ...之类的荒谬事物之外,还需要将其推迟到CPU(通过LLVM IR)。

文件primitives.cr仅包含此类方法的空shell,以及它们的文档,因此它们看起来像标准库的正常部分。它们由注释标记,供编译器知道何时替换它们。真正的动作发生在compiler/crystal/codegen/primitives.cr中:每个注解名称都有一个case分支,这会导致代码生成适当的代码。

为完整起见,以下是primitives.cr的摘录:

  

此处定义的方法是基元,因为它们是:

     
      
  • 不能用Crystal表示(需要用LLVM表示)。例如一元   二元数学运算符属于此类。
  •   出于性能原因,
  • 应始终内联LLVM指令,甚至   在非发行版中。例如Char#ord,可以实现   在Crystal中,通过为变量分配self并将其指针转换为Int32,   然后读回值。
  •   

旁注:
这不是编译器实现非标准stdlib方法的唯一方法。对于obj.is_a?on a syntactic level之类的伪方法,也会发生这种情况。这甚至是一个“更强”的功能,并且它假装为一种方法的伪装(在Object's documentation中找不到is_a?)。这种构造与编译器紧密相关,可以affect type information

相关问题