11

我试图了解 Kotlin 源代码在编译时所经历的过程。该文件指出

当以 JVM 为目标时,Kotlin 生成与 Java 兼容的字节码。当以 JavaScript 为目标时,Kotlin 转译为 ES5.1 并生成与包括 AMD 和 CommonJS 在内的模块系统兼容的代码。当以原生为目标时,Kotlin 将生成特定于平台的代码(通过 LLVM)。

我的理解是,当 Kotlin 以 JVM 为目标时,代码被编译/翻译成字节码,然后 JVM 将其解释(?)成机器码。这会是 JIT(及时)编译的一个例子吗?

当定位 javascript 时,使用了“transpiles”这个词。代码究竟被编译成什么,它在任何步骤中是否被进一步解释或编译?

以本机为目标时,代码是否直接编译为机器码?LLVM 采取了哪些步骤?

最后,这是否意味着 Kotlin 既是编译语言又是解释语言?

4

1 回答 1

22

<...> 代码被编译/翻译成字节码,然后 JVM 将其解释(?)成机器码。这会是 JIT(及时)编译的一个例子吗?

是的,当面向 JVM 时,Kotlin 被编译为 JVM*.class文件,这是一种字节码格式,以后可以由 JVM 解释,或在程序运行 (JIT) 期间由 JVM 编译为机器码,甚至提前编译时间(AOT)到机器代码。在这里,Kotlin 编译器不需要知道字节码将如何被使用。

当定位 javascript 时,使用了“transpiles”这个词。代码究竟被编译成什么,它在任何步骤中是否被进一步解释或编译?

Kotlin/JS 的目标格式是 JavaScript 源代码。您可以尝试构建任何 Kotlin/JS 示例,并检查*.js包含 Kotlin 代码翻译成的 JS 源代码的输出文件。我相信这里使用transpile ( translate + compile ) 这个词来强调目标格式是源代码而不是二进制文件,而编译器仍然执行了很多转换和优化。

JavaScript 源代码也可以解释或 JIT 编译,这取决于用于运行程序的 JavaScript 引擎。

以本机为目标时,代码是否直接编译为机器码?LLVM 采取了哪些步骤?

Kotlin/Native 有两种可能的目标形式:

  • 可以在另一个 Kotlin/Native 项目中重用的*.klib库。这是一个包含 LLVM 位码以及一些 Kotlin 特定元数据的 ZIP 存档
  • 特定于平台的二进制文件,采用多种格式之一,包括静态和动态库以及可执行文件。这确实是特定目标平台的机器代码,如果它是库,则可用于链接,如果它是可执行文件,则可直接运行。在这种情况下,Kotlin 编译器调用LLVM 链接器lld来链接来自 LLVM 位码的二进制文件。
于 2018-11-25T23:11:24.810 回答