メインコンテンツまでスキップ
バージョン: 0.3.1

コンパイラとランタイムの構成

公式ツールチェーン​

Rust seed -> stage 1 glyph compiler -> stage 2 -> stage 3
| |
+-- byte equality + conformance

.dicks bytes -> glyph lexer/parser/checker -> checked token links
|
v
glyph JavaScript emitter
|
v
standalone ES2022 module + JavaScript runtime ABI
|
v
statically imported by a Workers application

実運用のコンパイラは selfhost/compiler.dicks です。上限を設けたアダプターがバイト入出力、スカラーのビット演算、不変の入力テーブルを提供します。アダプターは命令の構文解析・検査・コード生成を行いません。最初に手書きしたRustコンパイラは、シードと独立した比較実装として残します。Rust側のコード生成器が受け取るのは、非公開の CheckedProgram 型です。セルフホストのコンパイラも、すべての定義が検査を通過してからコードを生成します。セルフホストとメモリー・関数の対応表を参照してください。

生成器は具体的なJavaScript演算、構造化された if / for、直接の関数呼び出しを使います。オペコードを振り分けるループ、eval、Functionコンストラクター、動的なソースのコンパイル、動的モジュール読み込み、Nodeのインポートは生成しません。すべてのソースとABI宣言はコンパイル時の入力です。未使用の関数本体も検査し、その後で実行用の出力から除きます。純粋関数の呼び出しにはawait地点を追加せず、非同期性は非同期ホストのインポートからだけ伝播します。

runtime/runtime.js は各出力モジュールに埋め込む、保守対象のJavaScriptランタイムです。最初の実装は検証済みランタイムの試作から取り出しました。それ以降の変更は reference/language/ の独立したTypeScript参照実装と照合します。設計の起源を共有しているため、両者の一致は有用な根拠ですが、数学的な証明や完全に独立した仕様の発見を意味するものではありません。

現在のバックエンドは、検査済みの意味と診断を優先しています。SSA、レジスター割り当て、定数畳み込み、インライン化は未実装で、速度の優位性も証明していません。フレームにはJavaScriptの配列、ローカル変数にはMapを使います。Int64はBigIntと明示的な範囲検査で実装します。将来の最適化IRでは、実行量を表すfuelと診断の動作を保つか、バージョンを明示した新しい計上方式を導入する必要があります。

ホストABI​

各ホストのインポートは {id,name,inputs,outputs,effects,async} を持ちます。IDはモジュール内で有効な正の16ビット整数です。型にはInt/Bool/Text/Jsonと宣言済みの名目的な型参照を使い、エフェクト名は [a-z][a-z0-9_.-]{0,63} に一致させます。ランタイムはABIの完全一致を要求しますが、エフェクトの順序は問いません。型とエフェクトの宣言配列はランタイムでスナップショットにするため、後から変更しても検証済みABIは変わりません。エントリーの引数とホストの戻り値は、実行境界で再び検証します。

invoke(args, signal) は同期ホストなら配列、非同期ホストなら配列またはPromiseを返します。同期宣言でPromiseを返すとABI違反です。ホストはAbortSignalを受け取ります。関数呼び出しを通じて推論された間接的なものも含め、すべてのエフェクトに実行時の許可が必要です。初期状態で許可するのは output だけです。ホスト実装を渡しただけでは、追加の機能は許可されません。

実装済みのCloudflareアダプターは random、clock、storage、http.body、crypto などを宣言します。各ホスト宣言はプリミティブのエフェクトを正確に記述し、アプリケーションが明示的に許可します。D1・R2の操作、安全な乱数、SHA-256、通信は、上限を持つホストプリミティブです。DicksソースからJavaScriptの評価や暗黙のグローバル変数へアクセスすることはできません。現在の契約はCloudflareバインディングとホストABIマニフェストを参照してください。

ホスト例外は秘匿情報を除去して扱います。HostFault(code, certainty) は明示的な失敗プロトコルで、確実性は not-applied または unknown です。共有Symbolレジストリを使うため、ランタイムが別々にバンドルされていても、任意の例外文を出力せずにプロトコルを認識できます。想定外の例外のコードや引数は転送しません。どちらの確実性でも自動再試行はしません。書き込みの冪等性とトランザクションの規則はアプリケーションが決めます。

信頼境界​

上限付きの構文解析器・検査器に渡すのは、有効な言語ソースだけです。そのソースからJavaScriptの文字列を注入することはできません。ABIの名前とエフェクトは、実行可能な識別子へ埋め込まずJSONとして直列化します。生成されたエクスポート、同じWorker内のほかのJavaScript、ABI実装、コンパイラ、配備する生成物は信頼対象です。任意の利用者が渡すJavaScriptを、そのまま信頼対象として受け入れてはいけません。

実行時の検査は、コンパイル済みプログラムのリソースと機能を制限するもので、悪意あるホストJavaScriptを隔離するサンドボックスではありません。ホストがメモリーを確保し、イベントループを止め、宣言外の副作用を起こし、トラップ付きProxyを渡す可能性はあります。これらはソース言語の隔離境界の外にあるアプリケーションの不具合です。タイムアウトしたリモート書き込みが成功することもあります。1回の呼び出しが自動的に不可分になるわけではなく、出力のバッファもホストの状態をロールバックしません。

決定性と生成物​

コンパイラ、ソースのバイト列、ABIメタデータとその順序、対象ランタイムが同じなら、生成モジュールのバイト列も同じです。ローカルのファイル名、時刻、ランダムなビルドID、秘密情報は含めません。整形でソース上の位置が変わると、意味が同じでも生成バイト列が変わる場合があります。シグネチャとエフェクトの順序は決定的で、ソースの関数の順序も保持します。

Cargo.lockとpackage-lock.jsonは2つのツールチェーンの依存を固定します。ランタイムABIの変更はコンパイラとともにバージョン管理してください。現在の languageVersion は言語のリビジョンを識別するもので、生成物の真正性を暗号学的に保証するものではありません。ブートストラップのマニフェストには、ソース、ABI、ランタイム、ドライバー、シードバイナリ、Nodeのバージョン、各段階の生成物のダイジェストを固定します。セルフホストを参照してください。

ドメイン​

dicks.pink はCloudflareで管理しています。言語サイトは https://lang.dicks.pink で、プロジェクトは site/ にあります。https://registry.dicks.pink のレジストリは独立した dicks-lang/registry リポジトリで管理します。DaaS、フロントエンド、各ライブラリも独立したリポジトリです。リポジトリ構成を参照してください。言語リポジトリは非公開を維持し、サイトではAGPLに基づく対応ソースのアーカイブを提供します。