Schema zu WebAssembly kompilieren – Eli Benderskys Website

Schema zu WebAssembly kompilieren – Eli Benderskys Website


Eines meiner ältesten Open-Source-Projekte – Bob – hat vor ein paar Monaten seinen 15. Geburtstag gefeiert. Bob ist eine Suite von Implementierungen der Programmiersprache Scheme in Python, einschließlich eines Interpreters, eines Compilers und einer VM. Damals habe ich mich mit CPython-Interna befasst und war sehr neugierig, wie CPython-ähnliche Bytecode-VMs funktionieren. Bob führte ein Experiment durch, um dies herauszufinden, indem er eines von Grund auf für das R5RS-Schema implementierte.

Einige Monate später fügte ich Bob eine C++-VM hinzu, als Übung, um zu lernen, wie solche VMs in einer Low-Level-Sprache implementiert werden, ohne die gesamte Laufzeitunterstützung, die Python bietet; vor allem ohne den eingebauten GC. Die C++-VM in Bob implementiert ihren eigenen Mark-and-Sweep-GC.

Nach vielen ruhigen Jahren (mit nur ein paar kosmetischen Änderungen, Portierungen auf GitHub, Updates auf Python 3 usw.) verspürte ich kurz vor den Feiertagen den Drang, wieder an Bob zu arbeiten. Konkret habe ich beschlossen, der Suite einen weiteren Compiler hinzuzufügen – diesen von Scheme direkt zu WebAssembly.

Die Ziele dieser Bemühungen waren zweierlei:

  1. Experimentieren Sie mit der Herabstufung einer echten Hochsprache wie Scheme auf WebAssembly. Experimente wie das jüngste Let’s Build a Compiler kompilieren Spielzeugsprachen auf C-Ebene (keine Laufzeit). Scheme verfügt über integrierte Datenstrukturen, lexikalische Abschlüsse, Speicherbereinigung usw. Es ist viel anspruchsvoller.
  2. Sammeln Sie praktische Erfahrungen mit der WASM GC-Erweiterung. Ich habe mehrere Beispiele für die Verwendung von WASM GC im Wasm-Wat-Samples-Repository, aber ich wollte es unbedingt für etwas „Echtes“ ausprobieren.

Nun, es ist jetzt erledigt; Hier ist ein aktualisierter Schaltplan des Bob-Projekts:

Schema zu WebAssembly kompilieren – Eli Benderskys Website

Der neue Teil ist der vertikale Pfad ganz rechts. Eine WasmCompiler-Klasse reduziert geparste Scheme-Ausdrücke bis hin zum WebAssembly-Text, der dann in eine Binärdatei kompiliert und mit Standard-WASM-Tools ausgeführt werden kann.

Höhepunkte

Der interessanteste Aspekt dieses Projekts war die Arbeit mit WASM GC zur Darstellung von Scheme-Objekten. Solange wir alle Werte richtig einpacken/verpacken
refs, die zugrunde liegende WASM-Ausführungsumgebung kümmert sich um die Speicherverwaltung.

Für Bob werden einige wichtige Scheme-Objekte wie folgt dargestellt:

;; PAIR holds the car and cdr of a cons cell.
(type $PAIR (struct (field (mut (ref null eq))) (field (mut (ref null eq)))))

;; BOOL represents a Scheme boolean. zero -> false, nonzero -> true.
(type $BOOL (struct (field i32)))

;; SYMBOL represents a Scheme symbol. It holds an offset in linear memory
;; and the length of the symbol name.
(type $SYMBOL (struct (field i32) (field i32)))

$PAAR ist von besonderem Interesse, da es beliebige Objekte in seinen Feldern enthalten kann; (ref null eq) bedeutet „ein nullbarer Verweis auf etwas, das Identität hat“. ref.test kann verwendet werden, um für eine bestimmte Referenz den Laufzeittyp des Werts zu überprüfen, auf den sie verweist.

Sie fragen sich vielleicht: Was ist mit numerischen Werten? Hier hat WASM einen Trick – den i31
Der Typ kann verwendet werden, um einen Verweis auf eine Ganzzahl darzustellen, ohne ihn jedoch tatsächlich einzurahmen (ein Bit wird verwendet, um ein solches Objekt von einem echten Verweis zu unterscheiden). Wir benötigen also keinen separaten Typ, um Verweise auf Zahlen zu speichern.

Auch die $SYMBOL Typ sieht ungewöhnlich aus – wie wird er mit zwei Zahlen dargestellt? Der Schlüssel zum Rätsel liegt darin, dass WASM keine integrierte Unterstützung für Strings bietet; Sie sollten manuell mithilfe von Offsets zum linearen Speicher implementiert werden. Der Bob WASM-Compiler gibt die Zeichenfolgenwerte aller gefundenen Symbole in den linearen Speicher aus und verfolgt dabei den Offset und die Länge jedes einzelnen Symbols. Das sind die beiden eingegebenen Zahlen $SYMBOL. Dies ermöglicht auch die relativ einfache Implementierung der String-Interning-Funktion von Scheme; Mehrere Instanzen desselben Symbols werden nur einmal zugewiesen.

Betrachten Sie diesen trivialen Scheme-Ausschnitt:

Der Compiler gibt die Symbole „foo“ und „bar“ wie folgt in den linearen Speicher aus:

(data (i32.const 2048) "foo")
(data (i32.const 2051) "bar")

Und wenn wir im Rest des ausgegebenen Codes nach einer dieser Adressen suchen, finden wir:

(struct.new $SYMBOL (i32.const 2051) (i32.const 3))

Als Teil des Codes zum Erstellen der Konstante Nachteile Liste, die das Argument darstellt schreiben; Adresse 2051 und Länge 3: Das ist das Symbol Bar.

Apropos schreibendie Implementierung dieses Builtins war sehr interessant. Aus Kompatibilitätsgründen mit den anderen Bob-Implementierungen in meinem Repository: schreiben
muss in der Lage sein, rekursive Darstellungen beliebiger Scheme-Werte zu drucken, einschließlich Listen, Symbolen usw.

Anfangs zögerte ich, all diese Funktionen manuell in WASM-Text zu implementieren, aber alle Alternativen stießen auf Herausforderungen:

  1. Dies auf den Host zu verlagern ist schwierig, da die Hostumgebung keinen Zugriff auf WASM GC-Referenzen hat – diese sind völlig undurchsichtig.
  2. Die Implementierung in einer anderen Sprache (vielleicht C?) und die Reduzierung auf WASM ist aus einem ähnlichen Grund ebenfalls eine Herausforderung – die andere Sprache verfügt wahrscheinlich nicht über eine gute Darstellung von WASM-GC-Objekten.

Also habe ich in den sauren Apfel gebissen und – mit etwas KI-Hilfe für die mühsamen Teile – einfach eine Implementierung von geschrieben schreiben direkt im WASM-Text; es war nicht wirklich so schlimm. Ich importiere nur zwei Funktionen vom Host:

(import "env" "write_char" (func $write_char (param i32)))
(import "env" "write_i32" (func $write_i32 (param i32)))

Obwohl es nicht schwierig ist, Ganzzahlen direkt aus WASM auszugeben, dachte ich, dass dieses Projekt bereits über genügend Code verfügt und dass hier etwas Host-Hilfe willkommen wäre. Im Übrigen nur die unterste Stufe write_char verwendet wird. So werden beispielsweise boolesche Werte in der kanonischen Scheme-Notation ausgegeben (#T Und #F):

(func $emit_bool (param $b (ref $BOOL))
    (call $emit (i32.const 35)) ;; '#'
    (if (i32.eqz (struct.get $BOOL 0 (local.get $b)))
        (then (call $emit (i32.const 102))) ;; 'f'
        (else (call $emit (i32.const 116))) ;; 't'
    )
)

Abschluss

Das war ein wirklich unterhaltsames Projekt und ich habe einiges über die realistische Codeausgabe an WASM gelernt. Schauen Sie sich gerne den Quellcode von WasmCompiler an – er ist sehr gut dokumentiert. Obwohl es insgesamt etwas mehr als 1000 LOC sind, handelt es sich bei mehr als der Hälfte davon tatsächlich um WASM-Textschnipsel, die die integrierten Typen und Funktionen implementieren, die für eine grundlegende Scheme-Implementierung erforderlich sind.




Source link

Postagens Similares

  • ਹੁਣ ਮੇਰਾ ਮੌਕਾ ਹੈ ਤੁਹਾਨੂੰ ਇਹ ਦੱਸਣ ਦਾ ਕਿ ਮੈਂ ਹਾਰਵਰਡ ਗਿਆ ਸੀ

    ਮੂਲ ਤੱਥ: ਮੈਂ ਹਾਰਵਰਡ ਤੋਂ ਪੀਐਚਡੀ ਕੀਤੀ ਹੈ। ਨਾਲ ਹੀ, ਇੱਕ ਮਾਸਟਰ ਡਿਗਰੀ. ਓਹ, ਅਤੇ ਤਰੀਕੇ ਨਾਲ, ਇਹ ਇੱਕ ਡਬਲ ਪੀਐਚਡੀ ਦੀ ਤਰ੍ਹਾਂ ਹੈ ਕਿਉਂਕਿ ਪ੍ਰੋਗਰਾਮ ਮੈਂ ਦੋ ਵੱਖ-ਵੱਖ ਖੇਤਰਾਂ ਵਿੱਚ ਸੰਯੁਕਤ ਸੀ, ਹਰੇਕ (ਮੇਰੀ ਪਸੰਦ ਦੀ) ਵਿੱਚੋਂ ਕਈ ਲੋੜਾਂ ਵਿੱਚੋਂ ਸਿਰਫ ਇੱਕ ਨੂੰ ਹਟਾ ਰਿਹਾ ਸੀ, ਪਰ ਮੈਂ ਅਸਲ ਵਿੱਚ ਸਾਰੀਆਂ ਜ਼ਰੂਰਤਾਂ ਨੂੰ ਪੂਰਾ…

  • AI ਖਲਨਾਇਕ (ਜਾਂ ਹੀਰੋ) ਨਹੀਂ ਹੈ

    ਹੇ ਸਭ, ਮੈਂ ਇਹ ਸਪੱਸ਼ਟ ਕਰਨ ਲਈ ਇੱਕ ਪਲ ਕੱਢਣਾ ਚਾਹੁੰਦਾ ਹਾਂ ਕਿ ਮੇਰੇ ਖਿਆਲ ਵਿੱਚ ਇਸ ਸਮੇਂ ਆਮ ਤੌਰ ‘ਤੇ ਨੌਕਰੀਆਂ, AI, ਅਤੇ ਤਕਨੀਕੀ ਨਾਲ ਕੀ ਹੋ ਰਿਹਾ ਹੈ। ਆਮ ਬਿਰਤਾਂਤ ਇਹ ਹੈ ਕਿ AI ਖਲਨਾਇਕ ਹੈ, ਅਤੇ ਇਹ ਸਾਡੀਆਂ ਸ਼ਾਨਦਾਰ ਕਾਰਪੋਰੇਟ ਨੌਕਰੀਆਂ ਨੂੰ ਖੋਹ ਰਿਹਾ ਹੈ। ਅਤੇ ਇਹ ਕਿ ਇਹ ਇੱਕ ਬਹੁਤ ਵੱਡੀ…

  • AI には逆のデータ問題がある

    AI にはデータ不足の問題があるという話をよく聞きます。そして、トルストイレベルのユニークな文学などに関しては、それは真実かもしれません。 しかし、ビジネスの世界では、正確な情報があると思います。 反対 問題。 私たちが実際に抱えているのは、「私たちが生成しているデータの大部分を確認できる人がまったくいない」という問題です。 IDC の Data Age 2025 レポートによると、私たちは年間 149 ゼタバイトのデータを生成しています。それは 149 兆ギガバイトです。毎年です。 実際に何が起こっているかは次のとおりです。 監視とセキュリティ: IoT および産業用センサー: エンタープライズ業務: 合計に関して言えば、毎年世界中で 149 ゼタバイトが生成されており、人間や AI によって検査されるのは 12 ~ 15% だけです (IDC Data Age 2025)。これは約 20 ゼタバイトです。 私に関する限り、確かに、新しい質の高い文献が生み出されない可能性はありますが、それが問題だと思います。おそらくそれが不足しつつあり、どこでさらに入手できるかわかりません。 しかし、実際的に言えば、より大きな問題は、企業、会社、人々がおそらくゼタバイト規模のデータを生成しているのに、実際にはそのデータの一部、または少なくとも一部を誰も見ていないということだと思います。 私にとって、これは、AI が実際に可視性をもたらし、誰も見ていないこのすべてのデータから洞察を抽出できる素晴らしい機会を提供します。 確かにデータの問題はありますが、人々が考えているような問題ではありません。 Source link

  • Manton Reece – GPT-Live

    Inafikiria juu ya athari za GPT-Live iliyotangazwa leo. Mambo mawili… Kwanza, Apple inakuza msingi wa Siri kwa Google inawaweka katika hali ya kushangaza ambapo labda hawawezi kuunda kitu kama hiki kitaalam, lakini pia hawawezi kutumia tu mfano wa mtu mwingine. Kana kwamba wamenaswa. Na pili, nina uhakika GPT-Live iliundwa kwa kifaa cha Jony Ive. Nimekuwa…

  • 世代を形作ったコードの保存: Zork I、II、III のオープンソース化

    現在、私たちは、私たちの心に近い、大切なゲームの歴史の基礎を保存しています。 Microsoft の Open Source Programs Office (OSPO)、​​Team Xbox、Activision が協力して、 ゾークI、 ゾーク II、 そして ゾークIII MIT ライセンスに基づいて利用可能です。私たちの目標はシンプルです。歴史的に重要なコードを生徒、教師、開発者の手に渡し、彼らがコードを研究し、そこから学び、そしておそらく最も重要なことに、コードを再生できるようにすることです。 遊びに対する考え方を変えたゲーム いつ ゾーク 登場したのは、プレイヤーに勝つことを求めるだけではありませんでした。それは彼らに想像してもらいました。グラフィックス、ジョイスティック、サウンドトラックはなく、画面上の文字とプレイヤーの好奇心だけがありました。しかし、これらの言葉は、当時のほとんどのゲームよりも鮮やかな世界を構築しました。それを可能にしたのは、単に巧みな文章を書いただけではなく、巧みなエンジニアリングでした。 その言葉の世界の下には、静かに革命的なものが存在していました。それは、カスタムビルドのエンジンである Z-Machine です。 Z-Machine は仮想マシンの仕様であり、現在私たちが使用している多くの Z-Machine インタプリタは、その VM のソフトウェア実装です。オリジナルのメインフレーム バージョン ゾーク 初期の家庭用コンピュータでは処理できないほど大きすぎたため、Infocom のチームは現実的な選択を行いました。彼らはそれを 3 つのゲームに分割し、 ゾークI、 ゾーク II、 そして ゾークIII、すべて同じ基盤システムによって動作します。これは、プラットフォームごとにゲームを再構築する代わりに、Z-Machine を使用して同じストーリー ファイルをどのコンピュータでも解釈できることも意味しました。あのデザインが作ったのは ゾーク 真のクロスプラットフォームとなった最初のゲームの 1 つであり、Apple II、IBM PC などで登場します。 歴史の一部を保存する ゲームの保存にはさまざまな形があり、遊びだけでなく研究も考慮することが重要です。 Zork のソース コードは保存して研究する価値があります。私たちは新しいリポジトリを作成するのではなく、歴史に直接貢献しています。…

  • 📚 Flybot – Kev Quirk

    Autor: Dennisa E. TayloraMoja ocena: 👍🏻👍🏻 (okej) Fizyk Philip Moray ma dobry dzień. Kończy swój wielki projekt. Obiad w stołówce jest przynajmniej jadalny. Nie może się doczekać drinka na koniec dnia i kąpieli w wannie z hydromasażem. Następnie w jego biurze pojawia się dziwne urządzenie. Kawałek technologii, którego nigdy wcześniej nie widział – i który…

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *