SimpleLanguage入門

独自の言語を実装するには、SimpleLanguageなどの既存の言語を拡張することから始めます。SimpleLanguageは、言語APIを使用して構築されたデモ言語です。SimpleLanguageプロジェクトは、独自の言語を記述するために言語APIを使用する方法を示すショーケースを提供します。これは、利用可能なほとんどのTruffle言語実装フレームワーク(以下「Truffle」)の機能を使用することを目的としており、インラインソースドキュメントでその使用方法を詳細に説明しています。

SimpleLanguageデモ言語は、Universal Permissive License (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マーケットプレイス(ヘルプ -> Eclipseマーケットプレイス)からm2eおよびm2e-aptプラグインをインストールします。
  3. 最後に、ファイル -> インポート -> Maven -> 既存のMavenプロジェクト -> SimpleLanguageディレクトリを参照 -> 完了 からSimpleLanguageプロジェクトをインポートします。

NetBeans #

NetBeansは、任意の言語をデバッグするためのGUIサポートを提供します。SimpleLanguageをNetBeansインターフェースにアップロードするには、ファイル -> プロジェクトを開く -> simplelanguageディレクトリを選択 -> 必要なプロジェクトを開く をチェック -> プロジェクトを開く に移動します。

IntelliJ IDEA #

SimpleLanguageプロジェクトは、IntelliJ IDEAでテストされました。IntelliJ IDEAを開き、メインメニューバーからファイル -> 開く -> 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
      
    • PATH環境変数にmxを追加します。
       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

次に、ポート8000でJavaリモートデバッガ(Eclipseなど)をアタッチします。

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

このスニペットは、ネイティブイメージを使用してGraalVMでSimpleLanguageを実行する`sl`ランチャースクリプトを使用した「Hello World」プログラムのタイミング実行を示しています。GraalVMで実行する場合、実行には405ミリ秒かかります。SimpleLanguageプログラムは1つのprintステートメントのみを実行するため、この時間のほぼすべてがGraalVMの起動と言語自体の初期化に費やされていると結論付けることができます。ネイティブ実行可能ファイルを使用すると、実行には4ミリ秒しかかからず、GraalVMで実行するよりも2桁高速に起動することがわかります。

`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`オプションを使用して、SimpleLanguageが存在することをGraalVMに通知し、fat言語JARファイルへのパスを提供します。言語を別のクラスパスに配置することで、言語実装とその埋め込みコンテキスト(この場合はランチャー)を明確に分離できます。

クラスパスの分離を無効にする

注意!これは開発中にのみ使用する必要があります。

開発目的では、クラスパスの分離を無効にし、アプリケーションクラスパスに言語実装を配置できるようにすると便利です(たとえば、言語の内部をテストするため)。

Maven CentralのLanguage API JARファイルは、module-infoですべてのAPIパッケージをエクスポートします。言語APIパッケージをエクスポートするには、`--upgrade-module-path`オプションを`-Dgraalvm.locatorDisabled=true`およびこのJARファイルと一緒に適用します。

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

言語APIパッケージをエクスポートするために`--upgrade-module-path`を使用するサンプル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

お問い合わせ