SimpleLanguageの概要

独自の言語の実装を開始するには、SimpleLanguageなどの既存の言語を拡張すると最も簡単です。SimpleLanguageは、言語APIを使用してビルドされたデモンストレーション言語です。SimpleLanguageプロジェクトは、言語APIを使用して独自の言語を記述する方法を説明します。これは使用可能なTruffle言語実装フレームワーク(以降、Truffle)のほとんどの機能を使用することを目的とし、インライン・ソース・ドキュメントで使用方法を広範囲にわたってドキュメント化しています。

開始するには、Maven3およびGraalVMがシステムで使用可能であることを確認します。

  1. 次を使用してSimpleLanguageリポジトリをクローニングします:
    git clone https://github.com/graalvm/simplelanguage
    
  2. 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
    
  3. 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
    
  4. 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環境にインポートするには:

  1. 新しいワークスペースでEclipseを開きます。
  2. Eclipse marketplaceからm2eおよびm2e-aptプラグインをインストールします(「Help」→「Eclipse Marketplace」)。
  3. 最後に、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のダウンロード・ページで個別のダウンロードとして入手できます。

  1. ダウンロードしたパッケージを解凍し、binディレクトリに入り、IGVを起動します:
    cd idealgraphvisualizer/bin
    idealgraphvisualizer
    
  2. 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を実行する必要があるという未解決のケースでは、次の手順に従ってください:

  1. 最新のJVMCI JDK 8をダウンロードし、JAVA_HOMEがこれを指すようにします:
    export JAVA_HOME=/path/to/openjdk-8u292-jvmci-21.1-b04
    
  2. SimpleLanguageフォルダからGraalリポジトリをクローニングします:
    cd /path/to/simplelanguage
    git clone https://github.com/oracle/graal.git
    
  3. mxリポジトリをクローニングします:
    git clone https://github.com/graalvm/mx.git
    
  4. mxをパスに追加します:
    export PATH=/path/to/mx:$PATH
    
  5. compilerフォルダに移動します:
    cd /path/to/graal/compiler
    
  6. GraalVMコンパイラをビルドします:
    mx build
    
  7. 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