SimpleLanguageの概要

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

SimpleLanguageデモンストレーション言語は、Universal Permissive License (UPL)に基づいてライセンス供与されます。

前提条件

スタート・ガイド

  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実行可能ファイル、およびGraalVMアップデータ・ツールを使用して後でGraalVMにインストールできる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リリース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」を押します。すべての依存性が自動的に含まれます。

グラフのダンプ

パフォーマンスの問題を調査するには、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
      
    • mxPATH環境変数に追加します:
       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プロセスにネットワーク経由でダンプされます。接続が確立されると、「アウトライン」ウィンドウにグラフが表示されます。特定のグラフを開き、名前、IDまたは property=valueデータでノードを検索すると、一致するすべての結果が表示されます。詳細は、こちらを参照してください。

デバッグ

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] ------------------------------------------------------------------------
...

SimpleLanguageを最新(開発)バージョンのコンパイラで実行

Graalコンパイラの開発バージョンでSimpleLanguageを実行するには、そのコンパイラでGraalVMをビルドする必要があります。graalリポジトリ(https://github.com/oracle/graal)をクローニングし、vm/README.mdファイルの指示に従ってGraalVMをビルドします。

これが完了したら、JAVA_HOMEを新しくビルドされたGraalVMに指定し、SimpleLanguageの通常のビルドと実行に進みます。

コマンドラインを使用したSimpleLanguageの実行

SimpleLanguageコードの実行は通常、JAVA_HOMEがGraalVMと別のJVMインストールのどちらを指しているかに応じて必要なコマンドラインを設定するslスクリプトを使用して行います。次の各項では、両方の場合のコマンドラインについて説明します。

JAVA_HOMEとしてGraalVMを使用した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オプションを使用してfat言語JARへのパスを指定することで、SimpleLanguageの存在を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

--upgrade-module-pathを使用して言語APIパッケージをエクスポートするサンプルPOMは、Simple Language POM.xmlファイルにあります。

ノート: ロケータを無効にすると、インストールされているすべての言語がモジュール・パスから効率的に削除されます。これは、ロケータが言語用のクラス・ローダーも作成するためです。組込み言語を引き続き使用するには、モジュール・パスを必要なすべての言語ホーム($GRAALVM/languages/jsなど)に指定することで、言語をモジュール・パスに追加します。

その他の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-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