Truffle框架

imissinstagram發表於2024-08-26

這兩天上網衝浪的時候,偶然發現一個介紹Truffle這個開發程式語言框架的一個影片:

影片比較有意思的就是使用了Graal VM提供的Truffle語言框架區開發了一個程式語言,實現了一些基本的功能,比如四則運算和函式定義。個人看了看,對於想要了解編譯器的入門者還是比較有啟發的。

我在網上找了個幻燈片,透過sulong幻燈片的描述,我們能看到Graal這個生態系統的構成時這樣的:

Graal編譯器是一個用Java開發用來替換Hotspot虛擬機器裡C2編譯器的即使編譯器,和SubstrateVM配合起來也可以實現AOT。圖中看出,多種程式語言都可以透過GraalVM最終獲得多種產物,例如二進位制可執行檔案,各種資料庫,甚至是程式語言本身。而輸入方則為各種程式語言,例如本身跑在JVM上的Scala, kotlin, java等等。第二類是不執行在JVM但是也執行在其他虛擬機器的語言,比如Js,R(這個應該只是直譯器),Ruby,Python(如PyPy)等。第三類是原生編譯成機器碼的語言,如C, C++, Rust。執行在JVM的語言比較好理解,只要實現一個編譯為JVM位元組碼的前端編譯器就行。而像Js這總語言,GraalVM給出了一個Truffle框架,這個框架本質就是一個Java框架,只是它是用來開發程式語言的。使用者可以透過這個框架實現AST語法分析樹,最終交給Graal編譯器編譯為二進位制,就製造了了一個程式語言。具體而言,我從網上找了個開源專案,類似於:

package nl.node;

import com.oracle.truffle.api.TruffleLanguage;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.nodes.NodeInfo;

@NodeInfo(shortName = "*")
public abstract class MulExpression extends NumberBinaryExpression {

    protected MulExpression(TruffleLanguage<?> language) {
        super(language);
    }

    @Specialization(rewriteOn = ArithmeticException.class)
    protected long doLong(long left, long right) {
        return Math.multiplyExact(left, right);
    }


    @Specialization(rewriteOn = ArithmeticException.class)
    protected double doDouble(double left, double right) {
        return left * right;
    }

    @Specialization(rewriteOn = ArithmeticException.class)
    protected double doDoubleLong(double left, long right) {
        return left * (double) right;
    }
    @Specialization(rewriteOn = ArithmeticException.class)
    protected double doLongDouble(long left, double right) {
        return  (double) left * right;
    }

    @Override
    public String toString() {
        return getLeft()+"*"+getRight();
    }
}

去依賴Truffle框架實現一個乘法符號對應的語義。GraalVM官方為了推這個生態,把上述著這些語言都給重新實現了一遍例如:R(FastR),Js(GraalJs),Python(GraalPython),Python(GraalPython),Ruby(TruffleRuby)。這些工作量無疑是巨大的,但是基於Graal生態,就可以用比較小的代價統一使用最優秀的編譯器和執行時,是很偉大的突破。

對於C, C++, Rust這種純編譯型語言,路徑似乎和執行在虛擬機器的語言不同。GraalVM統一它們的方式是藉助LLVM,可能由於人力的原因沒辦法再實現它們一次,就一勞永逸,使用Sulong這個工具,將LLVM位元組碼轉化為Truffle框架裡的AST語法分析樹,再用Graal編譯器編譯。最終他們的關係可以用這張圖敘述:

之後可以抽空了解一下基於Truffle框架如何實現一個簡單的程式語言。

相關文章