SimpleLanguageの概要
独自の言語の実装を開始するには、SimpleLanguageなどの既存の言語を拡張すると最も簡単です。SimpleLanguageは、言語APIを使用してビルドされたデモンストレーション言語です。SimpleLanguageプロジェクトは、言語APIを使用して独自の言語を記述する方法を説明します。これは使用可能なTruffle言語実装フレームワーク(以降、Truffle)のほとんどの機能を使用することを目的とし、インライン・ソース・ドキュメントで使用方法を広範囲にわたってドキュメント化しています。
開始するには、Maven3およびGraalVMがシステムで使用可能であることを確認します。
- 次を使用してSimpleLanguageリポジトリをクローニングします:
git clone https://github.com/graalvm/simplelanguage
- Linuxのコマンドライン・シェルを使用して、
JAVA_HOME
およびPATH
環境変数をGraalVMホームおよびbinフォルダに設定します:export JAVA_HOME=/path/to/graalvm export PATH=/path/to/graalvm/bin:$PATH
macOSの場合は、次を使用します:
export JAVA_HOME=/path/to/graalvm/Contents/Home export PATH=/path/to/graalvm/Contents/Home/bin:$PATH
- SimpleLanguageフォルダから
mvn package
を実行して、言語をビルドします。このコマンドでは、simplelanguage/native
ディレクトリにslnative
実行可能ファイル、およびGraalVMアップデータ・ツールを使用して後でGraalVMにインストールできるsl-component.jar
言語コンポーネントもビルドされます。ビルドの失敗を回避するために、GraalVMディストリビューションでnative-image
プラグインが使用可能であることを確認してください:gu list gu install native-image
次のコマンドを実行すると、パッケージ化フェーズ中にSimpleLanguageネイティブ実行可能ファイルのビルドを無効にできます:
export SL_BUILD_NATIVE=false mvn package
- SimpleLanguageルート・フォルダで実行します:
./sl ./language/tests/HelloWorld.sl
SimpleLanguageデモンストレーション言語は、Universal Permissive License (UPL)に基づいてライセンス供与されます。
IDE設定
Truffleフレームワークは、追加のAPIを提供することで、標準IDE機能を実現するための言語に依存しないインフラストラクチャを提供します。言語を試し、IDEの利点を得るには、例としてSimpleLanguageをインポートすることを検討してください。
Eclipse
SimpleLanguageの教育プロジェクトは、Eclipse Neon.2リリース4.6.2およびEclipse Oxygen.3Aでテストされています。プロジェクト・フォルダを目的のEclipse環境にインポートするには:
- 新しいワークスペースでEclipseを開きます。
- Eclipse marketplaceから
m2e
およびm2e-apt
プラグインをインストールします(「Help」→「Eclipse Marketplace」)。 - 最後に、
SimpleLanguage
プロジェクトをインポートします(「File」→「Import」→「Maven」→「Existing Maven Projects」→SimpleLanguageフォルダを参照→「Finish」)。
NetBeans
NetBeansは、任意の言語をデバッグするためのGUIサポートを提供します。SimpleLanguageをNetBeansインタフェースにアップロードするには、「File」→「Open Project」→simplelanguage
フォルダを選択→「Open Required Projects」を選択し、プロジェクトを開きます。
IntelliJ IDEA
SimpleLanguageプロジェクトは、IntelliJ IDEAでテストされています。IntelliJ IDEAを開き、メイン・メニュー・バーから「File」→「Open」→「Navigate to」を選択し、simplelanguage
フォルダを選択して「OK」を押します。すべての依存性が自動的に含まれます。
SimpleLanguageの実行
SimpleLanguageソース・ファイルを実行するには、次を実行します:
./sl language/tests/HelloWorld.sl
コンパイルされた関数のアセンブリ・コードを表示するには、次を実行します:
./sl -disassemble language/tests/SumPrint.sl
グラフのダンプ
パフォーマンスの問題を調べるには、Ideal Graph Visualizer (IGV)をお薦めします。これは、Oracle GraalVM Enterprise Editionに基づいてビルドするすべての言語実装者にとって不可欠なツールです。これは、Oracle Technology Networkのダウンロード・ページで個別のダウンロードとして入手できます。
- ダウンロードしたパッケージを解凍し、
bin
ディレクトリに入り、IGVを起動します:cd idealgraphvisualizer/bin idealgraphvisualizer
- SimpleLanguageルート・フォルダから次を実行して、グラフをIGVにダンプします:
./sl -dump language/tests/SumPrint.sl
デバッグ
Javaデバッガを使用してSimpleLanguage実装のデバッグを開始するには、プログラムのコマンドライン・ランチャに-debug
オプションを渡します:
./sl -debug language/tests/HelloWorld.sl
次に、Javaリモート・デバッガ(Eclipseなど)をポート8000に接続します。
GraalVMのSimpleLanguageコンポーネント
Truffleフレームワークで実装された言語は、後でGraalVMアップデータ・ツールを使用してGraalVMにインストールできるコンポーネントとしてパッケージ化できます。SimpleLanguageフォルダでmvn package
を実行すると、sl-component.jar
もビルドされます。このファイルはGraalVMのSimpleLanguageコンポーネントであり、次を実行してインストールできます:
gu -L install /path/to/sl-component.jar
SimpleLanguageネイティブ・イメージ
Truffleでビルドされた言語は、ネイティブ・イメージを使用して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
このスニペットは、ネイティブ・イメージを使用してGraalVM上でSimpleLanguageを実行するsl
ランチャ・スクリプトを使用したHello Worldプログラムの時間測定実行を示しています。GraalVMで実行すると、実行に405ミリ秒かかることがわかります。SimpleLanguageプログラムで実行されるprint文は1つのみであるため、この時間のほとんどがGraalVMの起動と言語自体の初期化に費やされていると結論付けることができます。ネイティブ実行可能ファイルを使用すると、実行にかかる時間はわずか4ミリ秒になり、GraalVMで実行するよりも起動速度が100倍速くなります。
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] ------------------------------------------------------------------------
...
最新のコンパイラ21.2.0でのSimpleLanguageの実行
最新バージョンのGraalVMコンパイラでSimpleLanguageを実行する必要があるという未解決のケースでは、次の手順に従ってください:
- 最新のJVMCI JDK 8をダウンロードし、JAVA_HOMEがこれを指すようにします:
export JAVA_HOME=/path/to/openjdk-8u292-jvmci-21.1-b04
- SimpleLanguageフォルダからGraalリポジトリをクローニングします:
cd /path/to/simplelanguage git clone https://github.com/oracle/graal.git
- mxリポジトリをクローニングします:
git clone https://github.com/graalvm/mx.git
- mxをパスに追加します:
export PATH=/path/to/mx:$PATH
- compilerフォルダに移動します:
cd /path/to/graal/compiler
- GraalVMコンパイラをビルドします:
mx build
- mxコマンドを使用してSimpleLanguageを実行します:
mx -v --jdk=jvmci vm -cp /path/to/simplelanguage/launcher/target/launcher-21.2.0-SNAPSHOT.jar:/path/to/simplelanguage/language/target/simplelanguage.jar com.oracle.truffle.sl.launcher.SLMain /path/to/simplelanguage/language/tests/SlScript.sl
コマンドラインを使用したSimpleLanguageの実行
SimpleLanguageコードの実行は通常、JAVA_HOME
がGraalVMと別のJVMインストールのどちらを指しているかに応じて必要なコマンドラインを設定するsl
スクリプトを使用して行います。次の各項では、両方の場合のコマンドラインについて説明します。
JAVA_HOMEとしてGraalVMを使用したSimpleLanguageの実行
JAVA_HOME
がGraalVMインストールを指し、現在の作業ディレクトリがsimplelanguage
ディレクトリである場合、SimpleLanguageを実行するには、次のコマンドを実行する必要があります:
$JAVA_HOME/bin/java \
-cp launcher/target/launcher-21.2.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
オプションを使用してfat言語JARへのパスを指定することで、SimpleLanguageの存在をGraalVMに通知します。言語を別のクラス・パスに配置することにより、言語の実装とその埋込みコンテキスト(この場合はランチャ)を強力に分離できます。
クラス・パス分離の無効化
ノート!開発中にのみ使用してください。
開発目的では、クラス・パスの分離を無効にして、言語実装をアプリケーション・クラス・パスに配置できるようにすると役立ちます(たとえば、言語の内部をテストする場合)。
JDK 8に基づくGraalVMディストリビューションの場合、-XX:-UseJVMCIClassLoader
オプションを追加できます。これにより、クラス・パスの分離が無効になり、言語実装をアプリケーション・クラス・パスに配置できるようになります。コマンドラインは次のようになります:
$JAVA_HOME/bin/java \
-XX:-UseJVMCIClassLoader -Dgraalvm.locatorDisabled=true \
-cp launcher/target/launcher-21.2.0-SNAPSHOT.jar:language/target/simplelanguage.jar \
com.oracle.truffle.sl.launcher.SLMain language/tests/Add.sl
JDK 11に基づくGraalVMのディストリビューションでは、-XX:-UseJVMCIClassLoader
オプションは無効です。Javaモジュール・システム分離が使用されます。--add-exports
または--upgrade-module-path
を使用して、同じ動作を実行できます。後者をお薦めします。
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
--upgrade-module-path
を使用して言語APIパッケージをエクスポートするサンプルPOMは、Simple Language POM.xmlファイルにあります。
その他のJVM実装
Truffleで実装された言語を実行するために必要なすべての依存性を含むGraalVMとは異なり、他のJVM実装では、クラス・パスに追加のJARが存在する必要があります。これらは、Maven Centralから入手できる言語API JARとGraalVM SDK JARです。
JAVA_HOME
がストックJDKインストールを指し、現在の作業ディレクトリがsimplelanguage
ディレクトリであり、そのディレクトリに言語API JARとGraalVM SDK JARが存在する場合、次のコマンドを使用してSimpleLanguageを実行できます:
$JAVA_HOME/bin/java \
-cp graal-sdk-21.2.0.jar:truffle-api-21.2.0.jar:launcher/target/launcher-21.2.0-SNAPSHOT.jar:language/target/simplelanguage.jar \
com.oracle.truffle.sl.launcher.SLMain language/tests/Add.sl