SimpleLanguage 简介

要实现您自己的语言,请从扩展现有语言(如 SimpleLanguage)开始。SimpleLanguage 是一种使用 Language API 构建的演示语言。SimpleLanguage 项目展示了如何使用 Language API 编写您自己的语言。它旨在利用大多数可用的 Truffle 语言实现框架(下文简称“Truffle”)功能,并通过内联源代码文档详细记录其使用方法。

SimpleLanguage 演示语言根据 《通用许可协议 (UPL)》获得许可。

先决条件 #

  • 您的系统上安装了 Maven
  • 安装了 GraalVM
  • 用于 GraalVM 项目开发的 mx 工具(参见下文)。

开始使用 #

  1. 通过运行以下命令克隆 SimpleLanguage 存储库:
     git clone https://github.com/graalvm/simplelanguage
    
  2. 从 SimpleLanguage 目录执行 mvn package 来构建该语言。在此之前,请验证您的 GraalVM 安装中是否提供了 native-image,以避免构建失败:
     cd simplelanguage
    
     native-image --version
    
     mvn package
    

    该命令在 simplelanguage/native 目录中构建 slnative 可执行文件和 sl-component.jar 语言组件。

    您可以通过运行以下命令在打包阶段禁用 SimpleLanguage 本机可执行文件构建:

     export SL_BUILD_NATIVE=false
     mvn package
    
  3. 从项目根目录运行 SimpleLanguage:
     ./sl language/tests/HelloWorld.sl
    
  4. 要查看已编译函数的汇编代码,请运行:
     ./sl -disassemble language/tests/SumPrint.sl
    

IDE 设置 #

Truffle 框架提供与语言无关的基础设施,通过提供额外的 API 来实现标准的 IDE 功能。如果您想尝试使用您的语言并获得 IDE 的优势,请考虑导入 SimpleLanguage 作为示例。

Eclipse #

SimpleLanguage 教学项目已在 Eclipse Neon.2 Release 4.6.2 和 Eclipse Oxygen.3A 上进行了测试。要将项目目录导入到所需的 Eclipse 环境中:

  1. 使用新工作区打开 Eclipse。
  2. 从 Eclipse Marketplace(Help -> Eclipse Marketplace)安装 m2em2e-apt 插件。
  3. 最后,从 File -> Import -> Maven -> Existing Maven Projects -> 浏览到 SimpleLanguage 目录 -> Finish 导入 SimpleLanguage 项目。

NetBeans #

NetBeans 为调试任意语言提供了 GUI 支持。要将 SimpleLanguage 上传到 NetBeans 界面,请转到 File -> Open Project -> 选择 simplelanguage 目录 -> 勾选 Open Required Projects -> 打开项目。

IntelliJ IDEA #

SimpleLanguage 项目已在 IntelliJ IDEA 上进行测试。打开 IntelliJ IDEA,在主菜单栏中选择 File -> Open -> 导航并选择 simplelanguage 目录 -> 按 OK。所有依赖项将自动包含。

转储图 #

要调查性能问题,请考虑在 GraalVM 之上使用 Ideal Graph Visualizer (IGV)。IGV 旨在查看和检查中间表示图——一种由编译器生成的、在源语言和机器代码之间与语言无关的中间表示 (IR)。IGV 可免费使用。

  1. 在您的计算机上设置 mx 工具
    • 通过运行以下命令克隆 mx 存储库:
       git clone https://github.com/graalvm/mx.git
      
    • Graal 存储库克隆到您的工作目录:
       git clone https://github.com/oracle/graal.git
      
    • mx 添加到 PATH 环境变量中:
       export PATH="/path/to/mx:$PATH"
      
    • 要检查安装是否成功,请运行以下命令:
       mx --version 
      
  2. 使用 mx 启动 IGV:
     mx -p graal/compiler igv
    
  3. 从 SimpleLanguage 根目录执行以下命令以将图转储到 IGV:
     ./sl -dump language/tests/SumPrint.sl
    

这将以 IGV 格式通过网络将编译器图转储到监听 127.0.0.1:4445 的 IGV 进程。建立连接后,您将在 Outline 窗口中看到这些图。打开特定图,按名称、ID 或 property=value 数据搜索节点,所有匹配结果都将显示。在此处了解更多信息。

调试 #

要使用 Java 调试器开始调试 SimpleLanguage 实现,请将 -debug 选项传递给程序的命令行启动器:

./sl -debug language/tests/HelloWorld.sl

然后将 Java 远程调试器(如 Eclipse)连接到端口 8000。

适用于 GraalVM 的 SimpleLanguage 组件 #

使用 Truffle 框架实现的语言可以打包为组件,稍后可以使用 GraalVM Updater 工具安装到 GraalVM 中。在 SimpleLanguage 目录中运行 mvn package 也会构建一个 sl-component.jar。此文件是适用于 GraalVM 的 SimpleLanguage 组件,可以通过运行以下命令进行安装:

gu -L install /path/to/sl-component.jar

SimpleLanguage 本机镜像 #

使用 Truffle 构建的语言可以使用 Native Image 进行 AOT 编译。在 SimpleLanguage 目录中运行 mvn package 也会在 native 目录中构建一个 slnative 可执行文件。此可执行文件是 SimpleLanguage 的完整实现,作为一个独立的本机应用程序,执行 SimpleLanguage 代码时不需要 GraalVM。除此之外,与在 GraalVM 上运行相比,使用本机可执行文件的一个巨大优势是启动时间大大加快,如下所示:

time ./sl language/tests/HelloWorld.sl
== running on org.graalvm.polyglot.Engine@2db0f6b2
Hello World!

real    0m0.405s
user    0m0.660s
sys     0m0.108s

time ./native/slnative
language/tests/HelloWorld.sl
== running on org.graalvm.polyglot.Engine@7fd046f06898
Hello World!

real    0m0.004s
user    0m0.000s
sys     0m0.000s

此片段显示了一个“Hello World”程序的计时执行,该程序使用 sl 启动器脚本在 GraalVM 上运行 SimpleLanguage,并使用 Native Image。我们可以看到,在 GraalVM 上运行时,执行时间为 405 毫秒。由于我们的 SimpleLanguage 程序只执行一条打印语句,我们可以得出结论,几乎所有时间都花在了启动 GraalVM 和初始化语言本身上。当使用本机可执行文件时,我们看到执行时间仅为 4 毫秒,这表明启动速度比在 GraalVM 上运行快两个数量级。

有关 native-image 工具的更多信息,请参阅参考手册

禁用 SimpleLanguage 本机镜像构建 #

通过 Maven 构建本机可执行文件绑定到 Maven package 阶段。由于本机可执行文件构建可能需要一些时间,我们提供了通过将 SL_BUILD_NATIVE 环境变量设置为 false 来跳过此构建的选项,如下所示:

export SL_BUILD_NATIVE=false
mvn package
...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building simplelanguage-graalvm-native
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- exec-maven-plugin:1.6.0:exec (make_native) @ simplelanguage-graalvm-native ---
Skipping the native image build because SL_BUILD_NATIVE is set to false.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
...

使用最新(开发)版编译器运行 SimpleLanguage #

要使用 Graal 编译器的开发版本运行 SimpleLanguage,我们必须使用该编译器构建一个 GraalVM。克隆 graal 存储库 (https://github.com/oracle/graal) 并按照 vm/README.md 文件中的说明构建 GraalVM。

完成后,将 JAVA_HOME 指向新构建的 GraalVM,然后继续正常构建和运行 SimpleLanguage。

使用命令行运行 SimpleLanguage #

执行 SimpleLanguage 代码通常使用 sl 脚本完成,该脚本根据 JAVA_HOME 指向 GraalVM 还是其他 JVM 安装来设置必要的命令行。以下小节描述了这两种情况的命令行。

将 GraalVM 作为 JAVA_HOME 运行 SimpleLanguage #

假设 JAVA_HOME 指向 GraalVM 安装目录且当前工作目录是 simplelanguage 目录,要运行 SimpleLanguage,应执行以下命令:

$JAVA_HOME/bin/java \
    -cp launcher/target/launcher-22.1.0-SNAPSHOT.jar \
    -Dtruffle.class.path.append=language/target/simplelanguage.jar \
    com.oracle.truffle.sl.launcher.SLMain language/tests/Add.sl

简而言之,我们将启动器 JAR 文件放置在类路径上并执行其主类,但通过使用 -Dtruffle.class.path.append 选项并提供胖语言 JAR 文件的路径来告知 GraalVM SimpleLanguage 的存在。将语言放在单独的类路径上可确保语言实现与其嵌入上下文(在此情况下为启动器)之间保持强分离。

禁用类路径分离

注意!此功能仅应在开发期间使用。

出于开发目的,禁用类路径分离并允许将语言实现放在应用程序类路径上(例如,用于测试语言内部结构)非常有用。

Maven Central 上的 Language API JAR 文件在其 module-info 中导出所有 API 包。将 --upgrade-module-path 选项与 -Dgraalvm.locatorDisabled=true 和此 JAR 文件一起应用,以导出 Language API 包:

-Dgraalvm.locatorDisabled=true --module-path=<yourModulePath>:${truffle.dir} --upgrade-module-path=${truffle.dir}/truffle-api.jar

使用 --upgrade-module-path 导出 Language API 包的示例 POM 可以在 Simple Language POM.xml 文件中找到。

注意:禁用定位器会有效地从模块路径中移除所有已安装的语言,因为定位器还会为这些语言创建类加载器。要继续使用内置语言,请通过更新模块路径以包含您所需所有语言的路径来将其添加到模块路径中(例如,$GRAALVM/languages/js)。

其他 JVM 实现 #

与包含运行使用 Truffle 实现的语言所需所有依赖项的 GraalVM 不同,其他 JVM 实现需要类路径中存在额外的 JAR 文件。这些是可从 Maven Central 获取的 Language API 和 GraalVM SDK JAR 文件。

假设 JAVA_HOME 指向标准 JDK 安装,且当前工作目录是 simplelanguage 目录,并且 Language API 和 GraalVM SDK JAR 文件存在于该目录中,则可以使用以下命令执行 SimpleLanguage:

$JAVA_HOME/bin/java \
    -cp graal-sdk-22.1.0.jar:truffle-api-22.1.0.jar:launcher/target/launcher-22.1.0-SNAPSHOT.jar:language/target/simplelanguage.jar \
    com.oracle.truffle.sl.launcher.SLMain language/tests/Add.sl

联系我们