- 适用于 JDK 23 的 GraalVM(最新)
- 适用于 JDK 24 的 GraalVM(抢先体验)
- 适用于 JDK 21 的 GraalVM
- 适用于 JDK 17 的 GraalVM
- 归档
- 开发版本
简单语言简介
要实现您自己的语言,请从扩展现有语言(例如简单语言)开始。 简单语言 是使用 语言 API 构建的演示语言。 简单语言项目展示了如何使用语言 API 来编写自己的语言。 它旨在使用大多数可用的 Truffle 语言实现框架(以下简称“Truffle”)功能,并通过内联源代码文档对其使用进行了详细说明。
简单语言演示语言根据 通用许可协议 (UPL) 授权。
先决条件 #
入门 #
- 通过运行以下命令克隆简单语言存储库
git clone https://github.com/graalvm/simplelanguage
- 从简单语言目录执行
mvn package
以构建语言。 之前,请验证您的 GraalVM 安装中是否可以使用native-image
,以避免构建失败cd simplelanguage
native-image --version
mvn package
该命令在
simplelanguage/native
目录中构建slnative
可执行文件和sl-component.jar
语言组件。您可以通过运行以下命令在打包阶段禁用简单语言本机可执行文件构建
export SL_BUILD_NATIVE=false mvn package
- 从项目根目录运行简单语言
./sl language/tests/HelloWorld.sl
- 要查看已编译函数的汇编代码,请运行以下命令
./sl -disassemble language/tests/SumPrint.sl
IDE 设置 #
通过提供其他 API,Truffle 框架 提供与语言无关的基础架构来实现标准 IDE 功能。 如果您想尝试使用您的语言并获得 IDE 的好处,请考虑将简单语言导入作为示例。
Eclipse #
简单语言教学项目已使用 Eclipse Neon.2 Release 4.6.2 和 Eclipse Oxygen.3A 进行测试。 要将项目目录导入到所需的 Eclipse 环境中
- 使用新工作区打开 Eclipse。
- 从 Eclipse 市场安装
m2e
和m2e-apt
插件(帮助 -> Eclipse 市场)。 - 最后,从文件 -> 导入 -> Maven -> 现有 Maven 项目 -> 浏览到简单语言目录 -> 完成导入
SimpleLanguage
项目。
NetBeans #
NetBeans 为调试任意语言提供 GUI 支持。 要将简单语言上传到 NetBeans 界面,请转到文件 -> 打开项目 -> 选择 simplelanguage
目录 -> 选中打开所需项目 -> 打开项目。
IntelliJ IDEA #
简单语言项目已使用 IntelliJ IDEA 进行测试。 打开 IntelliJ IDEA,从主菜单栏中选择文件 -> 打开 -> 导航到并选择 simplelanguage
目录 -> 按确定。 所有依赖项将自动包含。
转储图表 #
要调查性能问题,请考虑在 GraalVM 之上使用 理想图表可视化器 (IGV)。 IGV 的开发目的是查看和检查中间表示图表 - 编译器生成的源语言和机器代码之间的一种与语言无关的中间表示 (IR)。 IGV 免费使用。
- 在您的计算机上设置
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
- 通过运行以下命令克隆
- 使用
mx
启动 IGVmx -p graal/compiler igv
- 从简单语言根目录执行以下命令以将图表转储到 IGV
./sl -dump language/tests/SumPrint.sl
这会以 IGV 格式通过网络将编译器图表转储到侦听 127.0.0.1:4445 的 IGV 进程。 建立连接后,您就可以在“大纲”窗口中查看图表。 打开特定图表,按名称、ID 或 property=value
数据搜索节点,所有匹配的结果都将显示出来。 了解更多 信息。
调试 #
要使用 Java 调试器开始调试简单语言实现,请将 -debug
选项传递到程序的命令行启动器
./sl -debug language/tests/HelloWorld.sl
然后在端口 8000 上附加 Java 远程调试器(例如 Eclipse)。
适用于 GraalVM 的简单语言组件 #
使用 Truffle 框架 实现的语言可以打包为组件,这些组件稍后可以使用 GraalVM 更新程序 工具安装到 GraalVM 中。 在简单语言目录中运行 mvn package
还会构建 sl-component.jar
。 此文件是适用于 GraalVM 的简单语言组件,可以通过运行以下命令进行安装
gu -L install /path/to/sl-component.jar
简单语言 Native Image #
使用 Truffle 构建的语言可以使用 Native Image 进行 AOT 编译。 在简单语言目录中运行 mvn package
还会在 native
目录中构建 slnative
可执行文件。 此可执行文件是完整的简单语言实现,作为一个单独的本机应用程序,无需 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
此代码段显示了使用 sl
启动器脚本(在 GraalVM 上运行简单语言)和使用 Native Image 运行“Hello World”程序的计时执行情况。 我们可以看到,在 GraalVM 上运行时,执行需要 405 毫秒。 由于我们的简单语言程序只执行一个打印语句,我们可以得出结论,几乎所有这段时间都花在了启动 GraalVM 和初始化语言本身。 使用本机可执行文件时,我们看到执行只需要 4 毫秒,显示启动速度比在 GraalVM 上运行快两个数量级。
有关 native-image
工具的更多信息,请参阅 参考手册。
禁用简单语言 Native Image 构建 #
通过 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] ------------------------------------------------------------------------
...
使用最新的(开发)版本的编译器运行简单语言 #
要使用 Graal 编译器的开发版本运行简单语言,我们必须使用该编译器构建 GraalVM。 克隆 graal
存储库 (https://github.com/oracle/graal),并按照 vm/README.md
文件中的说明构建 GraalVM。
完成后,将 JAVA_HOME
指向新构建的 GraalVM,然后继续正常构建和运行简单语言。
使用命令行运行简单语言 #
通常使用 sl
脚本执行简单语言代码,该脚本根据 JAVA_HOME
是否指向 GraalVM 或其他 JVM 安装来设置必要的命令行。 以下各节将描述这两种情况下的命令行。
使用 GraalVM 作为 JAVA_HOME 运行简单语言 #
假设 JAVA_HOME
指向 GraalVM 安装,并且当前工作目录是 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 知道简单语言的存在。 将语言放在单独的类路径上可确保语言实现与其嵌入上下文(在本例中为启动器)之间有严格的隔离。
禁用类路径隔离
注意! 这只能在开发过程中使用。
出于开发目的,禁用类路径隔离并将语言实现放在应用程序类路径上非常有用(例如,用于测试语言的内部机制)。
Maven Central 上的语言 API JAR 文件在它的 module-info 中导出所有 API 包。 将 --upgrade-module-path
选项与 -Dgraalvm.locatorDisabled=true
和此 JAR 文件一起应用以导出语言 API 包
-Dgraalvm.locatorDisabled=true --module-path=<yourModulePath>:${truffle.dir} --upgrade-module-path=${truffle.dir}/truffle-api.jar
在 简单语言 POM.xml 文件中可以找到使用 --upgrade-module-path
导出语言 API 包的示例 POM。
注意:禁用定位器实际上会从模块路径中删除所有已安装的语言,因为定位器还会为语言创建类加载器。 要继续使用内置语言,请将它们添加到模块路径中,方法是更新模块路径以包含您需要的 所有语言的路径(例如,
$GRAALVM/languages/js
)。
其他 JVM 实现 #
与 GraalVM(包含运行使用 Truffle 实现的语言所需的所有依赖项)不同,其他 JVM 实现需要在类路径上存在其他 JAR 文件。 这些是来自 Maven Central 的语言 API 和 GraalVM SDK JAR 文件。
假设 JAVA_HOME
指向库存 JDK 安装,并且当前工作目录是 simplelanguage
目录,并且语言 API 和 GraalVM SDK JAR 文件存在于该目录中,则可以使用以下命令执行简单语言
$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