Skip to content

Releases: shadowlink0122/Cm

v0.15.0

09 Mar 16:57
d17b81a

Choose a tag to compare


title: v0.15.0
parent: Release Notes
nav_order: 1

Cm v0.15.0 リリースノート

リリース日: 2026-03-09
前バージョン: v0.14.2

✨ ハイライト

v0.15.0はSystemVerilog (SV) バックエンドの本格実装プラットフォームディレクティブによるレキサーモード分離を含むメジャーアップデートです。CmからFPGA向けのSystemVerilogコードを生成し、iverilogによるシミュレーション検証まで一貫して実行可能になりました。


🔧 SystemVerilogバックエンド(新規)

Phase 1-5: コア実装

MIRからSystemVerilogへの変換パイプラインを実装。構造化CFG走査により、MIRの基本ブロックからif/else/case等のSV制御構文を正確に再構築します。

cm compile --target=sv program.cm -o output.sv

ポート宣言と回路タイプ

アトリビュート 生成されるSV
#[input] input logic [N:0] name
#[output] output logic [N:0] name
通常関数 always_comb begin ... end
posedge型引数 always_ff @(posedge clk) begin ... end
negedge型引数 always_ff @(negedge clk) begin ... end

SV固有型(文脈キーワード)

posedgenegedgewirereg型をCm言語レベルで直接サポート。SVプラットフォーム時のみキーワードとして認識され、非SVモードでは通常の識別子として使用可能。

SV幅付きリテラル

SystemVerilog形式の幅付きリテラル(N'd, N'b, N'h)をCmパーサーで直接サポート。Token→AST→HIR→MIR→SV codegen の全段で元のベース形式を保持して出力します。

out = 3'b101;   // → 3'b101 (2進数)
out = 8'hFF;    // → 8'hFF  (16進数)
out = 8'd170;   // → 8'd170 (10進数)

一時変数の最適化

MIR→SV変換時に一時変数(_tXXXX)をインライン展開し、使用されなくなった変数のlogic宣言を自動除去。クリーンなSV出力を実現。

三項演算子の自動最適化

if/elseが同一変数への単一代入のみの場合、cond ? a : b に自動変換。合成ツールの効率向上と可読性改善。

テストベンチ自動生成

cm compile --target=sv実行時にiverilog互換のテストベンチ(_tb.sv)を自動生成。

その他の機能

機能 説明
BRAM推論 配列をBlock RAMとして推論
マルチクロックドメイン sv::clock_domain(clk_name)アトリビュート
XDC制約ファイル生成 sv::pinアトリビュートでピン配置指定
非ブロッキング代入 順序回路で<=を自動使用

🆕 プラットフォームディレクティブ

ソースファイル先頭の //! platform: sv ディレクティブまたは --target=sv CLIオプションにより、レキサーのキーワードテーブルをプラットフォームごとに切り替える仕組みを導入。

//! platform: sv
// posedge/negedge/wire/reg がキーワードトークンとして認識される
モード キーワード追加 用途
LexerPlatform::Default なし 通常のCmコード
LexerPlatform::SV posedge, negedge, wire, reg SVターゲット

🐛 バグ修正

問題 修正内容
型キーワードnamespace関数呼び出し失敗 parse_namespace()/current_text()get_string()token_kind_to_string()に修正
posedge等が非SVコードで型消費 parse_type()のIdentテキスト比較ブロック削除、レキサーKwトークンに完全移行
rstポート挿入位置 clk実位置を検索して直後に挿入するよう修正
非合成型チェック未呼び出し compile()からvalidateSynthesizableTypes()を呼び出し、エラー時にコンパイル中止
parameter二重宣言 sv::param変数がparameter/logicで二重定義されるバグを修正
SV幅付きリテラル例外クラッシュ stoi/stoulltry-catchで保護、値部空チェック・基数文字検証を追加
グローバル変数初期化子省略範囲 SVポート型/アトリビュートのみ省略可能に限定

⚡ ビルド高速化

変更 説明
ccache自動検出 インストール済みなら自動でコンパイルキャッシュ有効化
Unity build ソースファイル結合(バッチ16)でヘッダパース回数を大幅削減
SV生成物管理 デフォルトSV出力を.tmp/配下に変更、ルートディレクトリの汚染を防止
コンパイラ警告0件達成 符号比較・演算子優先順位・未使用変数の警告を全解消
Token/AST/HIR/MIR最適化 SV幅付きリテラル情報をstd::optional<BitLiteralInfo>に統一

🎨 VSCode拡張機能

SV幅付きリテラルのハイライト

N'[dbh]VALUEパターンをconstant.numeric.sv-literal.cmスコープとして認識。8'hFF等が文字リテラルではなく数値リテラルとしてハイライトされるよう修正。

文字リテラルパターン修正

シングルクォートの文字リテラルを'X'(1文字のみ)にマッチするmatchパターンに変更。


🧪 テスト基盤

テストディレクトリ統合

tests/programs/を廃止し、全テストをtests/直下のカテゴリディレクトリに統合。

SVテストの並列実行

unified_test_runner.shrun_parallel_testにSVバックエンドを追加。make tsvpでiverilogシミュレーション検証を含む全SVテストを並列実行可能に。

CIへのSVテスト・iverilog追加

GitHub Actions CIにiverilogのインストールとSVシミュレーション検証を追加。macOSでのbrew install失敗時はwarning出力+SVテストスキップへ明示的分岐。

テストカバレッジ

カテゴリ テスト数
sv/advanced 6 (fsm, led_blinker, multi_clock, negedge_reset, parameterized, posedge_counter)
sv/basic 11 (adder, arithmetic, binary_bits, bitwise, counter, multi_expr, mux, shift, sv_width_literal, ternary, unary)
sv/control 5 (compare, nested_if, priority_encoder, shift_register, signed_ops)
sv/memory 1 (bram)
合計 23テスト

📁 主要な変更ファイル

ファイル 変更内容
src/codegen/sv/codegen.cpp SVコード生成エンジン全体
src/frontend/lexer/lexer.hpp LexerPlatform enum、add_sv_keywords()定義
src/frontend/lexer/lexer.cpp SVキーワード動的追加、プラットフォームディレクティブ検出
src/frontend/parser/parser_type.cpp SV Identテキスト比較ブロック削除
src/frontend/parser/parser_module.cpp namespace名取得のget_string()修正
src/frontend/parser/parser_expr.cpp SV幅付きリテラル・型キーワード名前空間修飾
vscode-extension/syntaxes/cm.tmLanguage.json SV幅付きリテラルハイライト
.github/workflows/ci.yml SVテスト+iverilog追加
tests/unified_test_runner.sh SVテスト並列実行対応

📊 テスト結果

バックエンド 通過 失敗 スキップ
JIT (O0) 368 0 5
SV 23 0 0

📖 ドキュメント

  • 新規チュートリアル: SVバックエンド (ja/en)
  • 設計書更新: SV設計書2件をPhase 1 IMPLEMENTED、他3件のステータスを更新

🔮 今後の予定

  • v0.16.0: 型同一性改善、メソッドチェーン型チェッカー拡張、モジュール分離コンパイル

v0.14.2

08 Mar 16:28
c5232ec

Choose a tag to compare


title: v0.14.2
parent: Release Notes
nav_order: 1

Cm v0.14.2 リリースノート

リリース日: 2026-03-07
前バージョン: v0.14.1

✨ ハイライト

v0.14.2はTagged Union(Result/Option/enum)のペイロード抽出に関する重大バグ2件の修正ASM過剰volatile生成の修正Dead Function Elimination(DFE)の追加__asm__定数展開モノモーフィゼーション最適化を含むパッチリリースです。ベアメタル環境でのResult型エラーハンドリングを安全に使用可能にし、コンパイル・テスト性能を改善しました。


🐛 重大バグ修正: Tagged Union ペイロード

Bug#1: ペイロード型の64bitハードコード問題

mir_to_llvm.cppconvertPlaceToAddressでTagged Union(enum/Result/Option)のペイロード型がhir::make_int()(i32)にハードコードされ、64bit型のペイロードが切り詰められる問題。

項目 詳細
症状 Result::Ok(0)のペイロード抽出で188050848088064等の不正値
原因 ペイロード型がi32固定 → 64bit値の上位4バイトが未読
修正 type_argsから動的にペイロード型を推論、64bit型存在時はi64を使用
テスト JIT 365 PASS / LLVM 399 PASS、回帰なし

Bug#2: ペイロード部分書き込みによるundef bytes

Result::Ok(0)等のenum construct時、ペイロード値(i32)がi8[N]に部分書き込みされ、LLVM最適化がmemset+storeconstant phiに畳み込む際にundef bytesが生成される問題。

項目 詳細
症状 ベアメタル環境でResult<ulong, long>::Ok(0)の値にゴミデータ混入
原因 ペイロードストアが32bitのみ→残りバイトがundefined
修正1 payload storeにZExt(Zero-Extension)を追加し正確なビット幅に拡張
修正2 retval allocaにstruct型ゼロ初期化を追加
修正3 resolve_typedefにモノモーフ化enum名フォールバック追加

影響: この修正によりResult<T, E>でT==E(例: Result<long, long>)が正しく動作。ベアメタル環境を含む全レイヤーでResult型エラーハンドリングが使用可能に。


🐛 その他のバグ修正

ASM含有関数の過剰volatile生成

__asm__を含む関数で全ローカル変数にvolatile属性が付与され、不要なalloca → volatile store → volatile loadチェーンが生成される問題を修正。

修正前: outb(ushort, utiny) → 13回のメモリ操作、0x43バイト
修正後: outb(ushort, utiny) → 0回のメモリ操作、0x4バイト

型キーワードのnamespace名衝突

import ../lib/string;で展開されるnamespace string { ... }がCm組み込み型stringと衝突する問題を修正。

その他

問題 修正内容
varargs関数のパラメータ数検証 最小引数数でのガードに修正
callee関数のシンボル検索失敗 impl内関数のルックアップロジック修正
文字列スライスの範囲外アクセス スライス境界チェック追加
プリプロセッサのデバッグログ debug_modeガードで保護
パーサ無限再帰 安全ガード追加
DFEラムダ関数誤削除 ラムダ関数をDFEスキップ対象に追加
interface impl関数のDCE除去 未使用誤判定の修正
フォーマッター バッククォートインデント崩壊修正、括弧内継続行修正

✨ 新機能

Dead Function Elimination (DFE)

MIR→LLVM変換時に未使用関数を除去する最適化パスを追加。ベアメタル環境でのバイナリサイズ削減に有効。

enum値の文字リテラルサポート

parse_enum_declCharLiteralを受け付けるよう拡張。

export enum Ascii {
    LowerA = 'a',
    LowerB,        // 98 (オートインクリメント)
    UpperA = 'A',
    Digit0 = '0',
}

__asm__内の${CONST_NAME}定数展開

lower_asmでasm文字列中の${CONST_NAME}パターンを検出し、global_const_valuesテーブルから定数値を取得して16進数リテラルに直接置換。colonを含む${+r:var}等のオペランド記法はスキップ。

x86_64 Dockerクロスビルド対応

x86_64ターゲット向けDockerビルド環境を追加。LLVM共有ライブラリ + C++静的リンクの最適構成。


⚡ パフォーマンス改善

モノモーフィゼーション反復ループ最適化

項目
最大反復数 10パス (全関数フルスキャン) 2パス (2パス目は新規関数のみ)
monomorphize_structs() 2回実行 1回に統合

ネストジェネリクス(Queue等)にも対応。

テストランナー並列化改善(FIFOセマフォ方式)

項目
同期方式 PIDポーリング (kill -0 + sleep 0.05) FIFOセマフォ (mkfifo + fd)
max_jobs CPU数 CPU数×4 (I/Oバウンド考慮)
実行時間 1:57 51.5s (55%短縮)
CPU使用率 100% 232%

📁 主要な変更ファイル

ファイル 変更内容
src/codegen/llvm/core/mir_to_llvm.cpp ASM volatile修正、DFE連携、64bit payload型推論、ZExtストア、retvalゼロ初期化
src/mir/lowering/base.cpp resolve_typedefモノモーフ化enum名フォールバック
src/mir/lowering/context.cpp resolve_typedef enum_defs検索フォールバック
src/mir/lowering/stmt.cpp __asm__${CONST_NAME}定数展開
src/mir/passes/cleanup/program_dce.cpp Dead Function Elimination実装
src/mir/passes/monomorphization_impl.cpp モノモーフ反復ループ2パス最適化
src/frontend/parser/parser_expr.cpp 型キーワード名前空間修飾子対応
src/frontend/parser/parser_module.cpp enum値CharLiteralサポート、無限再帰ガード
src/frontend/types/checking/stmt.cpp Tagged Union 64bitペイロード型チェック
src/fmt/formatter.cpp バッククォート+括弧継続行修正
tests/unified_test_runner.sh FIFOセマフォ並列化 (55%短縮)
Dockerfile x86_64クロスビルド環境 (新規)

📊 テスト結果

バックエンド 通過 失敗
JIT (O0) 365 0
LLVM Native 399 0
Baremetal 全通過 0

🔮 今後の予定

  • v0.15.0: File I/O、パッケージ管理、JSバックエンドのポインタ/VTable対応

v0.14.1

20 Feb 16:50
a986423

Choose a tag to compare


title: v0.14.1
parent: Release Notes
nav_order: 1

Cm v0.14.1 リリースノート

リリース日: 2026-02-19
最終更新: 2026-02-21

✨ ハイライト

v0.14.1はUEFIコンパイラバグ17件の修正typedef算術演算サポートGCC/Linux CIビルド修正を含むパッチリリースです。CosmOS UEFI開発で発見されたコンパイラバグを全件修正し、MIR最適化パスのASM対応、naked関数コード生成の根本修正など広範な安定化を実施しました。


🐛 UEFIコンパイラバグ全件修正(Bug#1〜#17)

CosmOS UEFI開発中に発見されたコンパイラバグ17件を全て修正しました。

Bug# 問題 重要度 修正内容 回帰テスト
#1 3引数関数でのポインタ破損(Win64呼出規約) 重大 全関数にWin64呼出規約を設定 uefi_struct
#2 *ptr as ulongデリファレンスエラー 仕様通り(括弧付きで正常)
#5 LICM最適化がASM出力変数を移動 重大 ASM出力変数のループ不変判定修正 uefi_bug5_direct
#6 constant foldingのASM出力追跡 重大 ASM→変数代入チェーン最適化抑制 uefi_asm_while
#7 must{__asm__()}の制御フロー干渉 全ASMにhasSideEffects+クロバー設定 uefi_bug7_*
#8 const式でのI/Oポート計算 const式評価パイプライン修正 uefi_arithmetic
#9 ローカル配列のスタックオフセット重複 重大 alloca skipルール削除+array-to-pointer decay uefi_bug9_array_ptr
#10 ptr->method()のself書き戻し不在 重大 MIR loweringでポインタ経由書き戻し実装 impl_nested_self, impl_ptr_self
#11 インライン展開によるASMレジスタ割当変更 重大 ASM含有関数にNoInline属性付与 uefi_bug11_asm_func
#12 インライン展開時のret先不在 重大 Naked+$N事前置換方式に統一 uefi_bug12_asm_ret
#13 インライン展開時のレジスタ上書き(クラッシュ) 致命的 UEFI全関数NoInline+efi_mainにOptimizeNone uefi_impl_inline
#14 構造体配列の全体再代入でゴミ値 重大 memcpy/配列代入の型サイズ修正 uefi_large_impl
#15 非export関数がexport関数から呼出不可 シンボル解決(extract_exported_blocks)修正 uefi_cross_module_call
#16 &local as ulongキャスト不正 ポインタ→整数キャスト修正 uefi_pointer_cast
#17 UEFIスタックプローブクラッシュ スタックプローブの無効化 uefi_stack_probe

🔧 言語機能の修正

修正済みバグ(6件)

問題 修正内容 回帰テスト
typedef算術演算エラー typedef型のis_numeric判定修正 typedef_compound_assign
typedef引数の型不整合 static→static呼び出し時の型解決 typedef_struct_param
GCC CIビルドエラー <unordered_map>ヘッダー追加 CI自動テスト
大きな16進リテラルのprintln println関数選択にlong/ulong追加 ulong_large_hex
ビット演算の型幅不一致 BitAnd/BitOr/BitXorに型統一ロジック追加 operator_bitwise
ASM関数のインライン展開 ASM含有関数のインライン展開禁止 uefi_bug11_asm_func

typedef算術演算サポート

typedef型の値に対する算術演算・比較演算が正常に動作するようになりました。

typedef EFI_STATUS = ulong;
EFI_STATUS status = 0;
if (status != 0) { /* 修正前: コンパイルエラー → 修正後: 正常動作 */ }

整数型出力の完全対応

MIR loweringのprintln関数選択ロジックにlong/ulong/uint/isize/usize型のケースを追加。i32範囲を超える値が正しく出力されるようになりました。

long v = 0x80000000;  // 2147483648
println(v);           // 修正前: -2147483648 (i32切り詰め)
                      // 修正後: 2147483648 (正しい出力)

🏗️ バックエンド改善

GCC/Linux CIビルド修正

src/mir/nodes.hpp<unordered_map>ヘッダーを追加。AppleClangでは間接インクルードで解決されていたが、GCCでは明示的なインクルードが必要でした。

JS/WASMランタイム改善

ファイル 変更内容
src/codegen/js/builtins.cpp cm_println_long/ulong/uintとformat/to_string版追加
src/codegen/llvm/wasm/runtime_print.c cm_println_long/ulong出力関数追加
src/codegen/llvm/core/operators.cpp ビット演算(BitAnd/BitOr/BitXor)の型幅統一ロジック追加
src/mir/passes/interprocedural/inlining.cpp ASM含有関数のインライン展開禁止

MIR最適化パスのASM対応

パス 修正内容
LICM (Loop Invariant Code Motion) ASM出力変数をループ不変と誤判定しない修正
Constant Folding ASM→変数代入チェーンの最適化を抑制
Constant Folding 構造体フィールドアクセスの最適化を抑制
Inlining ASM含有関数のインライン展開を禁止

📁 主要な変更ファイル

ファイル 変更内容
src/codegen/llvm/core/mir_to_llvm.cpp Bug#1/7/8/11/12/14/16修正、naked関数統一
src/codegen/llvm/native/codegen.cpp Bug#13/17: UEFI最適化レベル調整、スタックプローブ無効化
src/mir/lowering/expr_call.cpp println型選択にlong/ulong/uint/isize/usize追加
src/mir/lowering/stmt.cpp Bug#10: ptr->method()のself書き戻し
src/mir/lowering/monomorphization_impl.cpp typedef引数の型解決修正
src/mir/passes/scalar/folding.cpp Bug#6/9: ASM出力・構造体フィールド最適化抑制
src/mir/passes/loop/licm.cpp Bug#5: ASM出力変数のループ不変判定修正
src/mir/nodes.hpp GCC CIビルド修正(unordered_mapヘッダー追加)
src/frontend/types/checking/expr.cpp typedef算術演算サポート
src/preprocessor/import.cpp Bug#15: 非export関数のシンボル解決修正

🧪 リグレッションテスト

UEFIコンパイルテスト(20件)

テストファイル 対象バグ/機能
uefi_arithmetic.cm Bug#8: const式計算
uefi_asm_scratch_reg.cm ASMスクラッチレジスタ
uefi_asm_while.cm Bug#6: ASMループ
uefi_bug5_direct.cm Bug#5: LICM最適化
uefi_bug7_compiler_barrier.cm Bug#7: コンパイラバリア
uefi_bug7_must_hlt.cm Bug#7: must+hlt
uefi_bug9_array_ptr.cm Bug#9: 配列ポインタ
uefi_bug11_asm_func.cm Bug#11: ASM関数
uefi_bug12_asm_ret.cm Bug#12: naked関数
uefi_control_flow.cm 制御フロー
uefi_cross_module_call.cm Bug#15: クロスモジュール
uefi_export_many.cm Bug#14: export数
uefi_impl_inline.cm Bug#13: インライン展開
uefi_large_impl.cm Bug#14: 大構造体
uefi_must_asm.cm must+ASM
uefi_naked_mixed_func.cm naked混在関数
uefi_pointer_cast.cm Bug#16: ポインタキャスト
uefi_stack_large.cm 大スタック
uefi_stack_probe.cm Bug#17: スタックプローブ
uefi_struct.cm Bug#1: 構造体

JIT/LLVM回帰テスト(主要)

テストファイル 対象
impl_nested_self.cm Bug#10: ネストself
impl_nested_self_deep.cm Bug#10: 深いネスト
impl_ptr_self.cm Bug#10: ポインタself
impl_ptr_large_struct.cm Bug#10: 大構造体
while_sccp_regression.cm Bug#5: SCCP回帰
ptr_to_int_cast.cm Bug#16: ポインタ→整数
typedef_compound_assign.cm typedef算術
operator_bitwise.cm ビット演算

📊 テスト結果

バックエンド 通過 失敗 スキップ
JIT (O0) 347 0 4
LLVM Native 380 0 7
LLVM WASM 346 0 5
JavaScript 306 0 49
Baremetal 11 0 0
UEFI 20 0 0

⚠️ 既知の制約事項(UEFIターゲット固有)

以下はUEFIバックエンド固有の制約であり、JIT/LLVM Native/WASM/JSでは発生しません。
全件に回避策があり、CosmOS開発で実証済みです。

# 制約 回避策
5 ASM出力変数のwhile条件不具合 ループ内でスコープ宣言+break
7 must{__asm__()}の制御フロー干渉 mustなしで直接使用
9 ローカル配列+ポインタ変数のオフセットずれ アドレスを変数に格納しない
11 ABIレジスタ直接参照の不正動作 ${r:var}構文を使用
12 インライン展開時のret先不在 数値ラベルでreturn address push
17 ___chkstk_ms未定義シンボル no-opスタブをリンク

: これらの制約はCmコンパイラのUEFIバックエンド固有の問題であり、
JITモード(cm run)では再現しません。将来のリリースで改善予定です。


🔮 今後の予定

  • v0.15.0: File I/O、パッケージ管理、JSバックエンドのポインタ/VTable対応、UEFI/ベアメタルの拡充

v0.14.0

15 Feb 11:58
472ccd8

Choose a tag to compare


title: v0.14.0
parent: Release Notes
nav_order: 1

Cm v0.14.0 リリースノート

リリース日: 2026-02-15

✨ ハイライト

v0.14.0は、JavaScriptバックエンドの大規模改善演算子オーバーロードの設計改善ベアメタル/UEFIサポートインラインユニオン型 (int | null) の実装プラットフォームディレクティブの導入を含むリリースです。JSバックエンドのテスト通過率が55%から87%に向上し、演算子オーバーロードではimpl T構文と複合代入演算子(+=等)をサポートしました。また、UEFIターゲットでのベアメタル開発が可能になりました。

主要な変更点

  • JSバックエンド大規模リファクタリング: codegen.cppから1,600行以上を削り、モジュール分割でコード品質を向上
  • JSテスト通過率向上: 55% → 87%(206/372 → 298/347)
  • 演算子オーバーロード改善: impl T { operator ... } 構文で直接演算子定義が可能に
  • 複合代入演算子: +=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>= をサポート
  • ビット演算子オーバーロード: &, |, ^, <<, >> のカスタム定義に対応
  • インラインユニオン型: int | null のようなインラインユニオン構文を導入
  • null型: 独立したnull型を追加(TypeKind::Null
  • プラットフォームディレクティブ: //! platform: でファイルレベルの実行環境制約を指定
  • ベアメタル/UEFIサポート: --target=uefiでUEFI Hello Worldが動作、QEMUで出力確認済み
  • インラインASM自動クロバー検出: ハードコードレジスタの自動検出でインライン展開時のバグを防止
  • Enum Associated Data修正: 文字列・構造体ペイロードのprintln出力が正常に動作
  • Tagged Union構造体ペイロードサイズ修正: 3フィールド以上の構造体ペイロードの破損を修正
  • interface存在チェック: impl T for II が宣言済みinterfaceであることを検証

🚀 JSバックエンド改善

codegen.cppの大規模リファクタリング

JSコードジェネレータを大幅にリファクタリングし、コードの保守性と品質を向上させました。

変更 詳細
codegen.cpp -1,618行(不要なコード削除・整理)
emit_expressions.cpp +124行(式の出力改善)
emit_statements.cpp +80行(文の出力改善)
builtins.hpp +71行(ビルトイン関数マッピング拡充)
runtime.hpp +19行(ランタイムヘルパー追加)
types.hpp +9行(型マッピング改善)

JSテスト通過率

バージョン パス 失敗 スキップ 通過率
v0.13.1 206 119 47 55%
v0.14.0 298 0 49 87%

失敗テスト: 119 → 0(未対応テストは適切にスキップに移行)

JSコンパイルの使い方

# JSへコンパイル
./cm compile --target=js hello.cm -o output.js

# 実行
node output.js

詳細は JSコンパイルチュートリアル を参照してください。


🐛 バグ修正

Enum Associated Dataのprintln出力修正

match armのペイロード変数をprintlnで出力する際、ランタイムハングや不正な出力が発生するバグを修正しました。

enum Message {
    Quit,
    Write(string)
}

int main() {
    Message m = Message::Write("Hello");
    match (m) {
        Message::Write(t) => {
            println(t);  // v0.13.1: ハング → v0.14.0: "Hello"
        }
        _ => {}
    }
    return 0;
}
問題 原因 修正ファイル
println型判定の誤り AST型チェッカーがmatch armのpayload変数の型をintに設定 expr_call.cpp
ペイロードロードエラー Tagged Unionの非構造体ペイロードの型がi32にハードコード mir_to_llvm.cpp

Tagged Union構造体ペイロードのサイズ修正

3フィールド以上の構造体をenumペイロードに格納すると、3番目以降のフィールドが破損するバグを修正しました。

struct RGB {
    int r;
    int g;
    int b;
}

enum Color {
    None,
    Set(RGB)
}

int main() {
    Color c = Color::Set(RGB { r: 255, g: 128, b: 0 });
    match (c) {
        Color::Set(v) => {
            println("RGB({v.r}, {v.g}, {v.b})");
            // v0.13.1: RGB(255, 128, 1) ← b=0が1に破損
            // v0.14.0: RGB(255, 128, 0) ← 正常
        }
        _ => {}
    }
    return 0;
}
問題 原因 修正ファイル
構造体3番目以降のフィールドが破損 max_payload_size()がStruct型をデフォルト8バイトで計算 types.cpp

修正: LLVM DataLayoutを使用して構造体型のサイズを正確に計算するよう変更。


🎼 演算子オーバーロード改善

impl T { operator ... } 構文

演算子を impl T for InterfaceName ではなく、直接 impl T { operator ... } で定義可能になりました。

struct Vec2 {
    int x;
    int y;
}

impl Vec2 {
    operator Vec2 +(Vec2 other) {
        return Vec2{x: self.x + other.x, y: self.y + other.y};
    }

    operator Vec2 -(Vec2 other) {
        return Vec2{x: self.x - other.x, y: self.y - other.y};
    }
}

複合代入演算子

二項演算子を定義すると、対応する複合代入演算子(+=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=)が自動的に使えます。

int main() {
    Vec2 v = Vec2{x: 10, y: 20};
    v += Vec2{x: 5, y: 3};   // Vec2{15, 23}
    v -= Vec2{x: 2, y: 1};   // Vec2{13, 22}
    return 0;
}

ビット演算子オーバーロード

&, |, ^, <<, >> の全ビット演算子をオーバーロード可能になりました。

interface存在チェック

impl T for I 構文で I が宣言済みinterfaceでない場合、コンパイルエラーになります。これにより、マジックストリング(impl T for Add 等)によるバグを防止します。


🧬 インラインユニオン型とnull型

インラインユニオン構文 (int | null)

インラインユニオン構文(|)でnull許容型を表現できるようになりました。

import std::io::println;

// typedefのユニオン型は従来通り
typedef MaybeInt = int | null;

// インラインユニオン型: typedefなしで直接型を結合
int main() {
    int | null a = null;           // nullが代入可能
    int | null b = 42 as MaybeInt; // int値も代入可能
    int | string | null c = null;  // 3型以上のユニオンも可能
    return 0;
}
変更 詳細
null型追加 TypeKind::Nullmake_null()
parse_type_with_union() 変数宣言・関数戻り値・構造体フィールドで使用
型互換性 Unionメンバー型とのnull代入・値代入に対応

注意: operator戻り値型では | がビットOR演算子と競合するため、インラインユニオンは使用できません。typedefを使用してください。


🌍 プラットフォームディレクティブ

ファイル先頭に //! platform: ディレクティブを記述することで、そのファイルが実行可能なプラットフォームを制約できます。

//! platform: native
// このファイルはLLVM Native/JITでのみコンパイル可能

import std::io::println;
int main() {
    println("Native only");
    return 0;
}

対応プラットフォーム: native, js, wasm, uefi, baremetal


🔧 ビルド・テスト改善

JSスキップファイルの整理

JSバックエンドで未サポートのネイティブAPI機能カテゴリに.skipファイルを追加:

カテゴリ 理由
asm/ インラインアセンブリはJS非対応
io/ ファイルI/OはJS非対応
net/ TCP/HTTPソケットはJS非対応
sync/ Mutex/Channel/AtomicはJS非対応
thread/ スレッドはJS非対応

reimportテストの修正

advanced_modules/reimport.cmテストの出力を修正し、NativeとJSの両方で正しい結果を出力するようにしました。

不安定テストの分割

macOSで不安定なoperator_comprehensiveテストを5つの個別テストに分割し、問題の切り分けを可能にしました:

  • operator_arithmetic — 算術演算子 (+, -, *, /, %)
  • operator_compare — 比較演算子 (==, !=, <, >)
  • operator_bitwise — ビット演算子 (&, |, ^, <<, >>)
  • operator_compound_assign — 算術複合代入 (+=, -=, *=, /=, %=)
  • operator_bitwise_assign — ビット複合代入 (&=, |=, ^=, <<=, >>=)

⚡ パフォーマンス改善

コンパイル速度の大幅改善

MIR最適化パイプラインとキャッシュデフォルトの見直しにより、コンパイル時間を大幅に削減しました。

項目 改善前 改善後 削減率
UEFIコンパイル 2764ms 646ms 76%削減
MIR最適化 593ms 389ms 34%削減

主な変更点:

  • キャッシュ(インクリメンタルビルド)をデフォルト無効化(--incrementalで明示的に有効化可能)
  • MIR最適化パイプラインに「前回変更なしパスのスキップ」ロジックを追加
  • SCCPに小規模関数の早期リターンを追加

🖥️ ベアメタル / UEFI サポート

UEFI Hello World

--target=uefi オプションでUEFIアプリケーションをコンパイルできるようになりました。OSなし(no_std)のベアメタル環境で動作し、QEMU + OVMFで「Hello World from Cm!」の出力を確認しています。

# UEFIアプリケーションのビルド
cm compile --target=uefi -o hello.o hello_world.cm
lld-link /subsystem:efi_application /entry:efi_main /out:BOOTX64.EFI hello.o

# QEMUで実行
qemu-system-x86_64 -drive if=pflash,format=raw,readonly=on,file=OVMF.fd \
    -drive format=raw,file=fat:rw:esp -net none -nographic
// UEFI Hello World
import ./libs/efi_core;
import ./libs/efi_text;

ulong efi_main(void* image_handle, void* system_table) {
    efi_clear_screen(system_table);
    string msg = "Hello World from Cm!";
    efi_println(system_table, msg as void*);
    while (true) { __asm__("hlt"); }
    return 0;
}

インラインASM自動クロバー検出

インラインアセンブリ内のハードコードレジスタ(%rax, %rcx, %rdi等)を自動検出し、LLVMクロバーリストに追加する機能を実装しました。これにより、インライン展開時にLLVMがASMで破壊されたレジスタの値を再利用するバグを防止します。

問題 原因 修正
UEFI出力なし ASMのハードコードレジスタがクロバー未宣言 mir_to_llvm.cpp: 自動クロバー検出
#GPクラッシュ LLVMレジスタ割当とハードコードの競合 efi_text.cm: pushq/popqパターン

🛠️ VSCode拡張機能の改善

TypeScript移行

VSCode拡張機能のスクリプト(update-version, verify-version)をJavaScriptからTypeScriptに移行しました。strict modeで型安全性を確保しています。

ESLint + Prettier導入

拡張機能にESLint(Flat Config v9+)とPrettierを導入し、コード品質を自動チェックするようにしました。

ツール 設定 コマンド
TypeScript tsconfig.json (strict, ES2020) pnpm run compile
ESLint eslint.config.mjs (typescript-eslint) pnpm run lint
Prettier .prettierrc pnpm run format:check

CI統合

ci.ymlextension-lint ジョブを追加。push/PRごとに以下を自動チェック:

  1. TypeScript compile
  2. ESLint check
  3. Prettier format check

📁 主要な変更ファイル

JSバックエンド

ファイル 変更内容
src/codegen/js/codegen.cpp 大規模リファクタリング(-1,618行)
src/codegen/js/emit_expressions.cpp 式出力の改善
src/codegen/js/emit_statements.cpp 文出力の改善
src/codegen/js/builtins.hpp ビルトイン関数マッピング拡充
src/codegen/js/runtime.hpp ランタイムヘルパー追加
src/codegen/js/types.hpp 型マッピング改善
src/codegen/js/codegen.hpp ヘッダ追加

LLVMバックエンド修正

ファイル 変更内容
src/codegen/llvm/core/types.cpp Tagged Unionペイロードサイズ計算修正
src/codegen/llvm/core/mir_to_llvm.cpp ペイロードロード修正、デバッグ出力削除

MIR Lowering修正

ファイル 変更内容
src/mir/lowering/expr_call.cpp println型判定でMIRローカル型を優先
src/mir/lowering/impl.cpp impl lowering改善

テスト

ファイル 変更内容
tests/programs/interface/operator_arithmetic.* 算術演算子テスト(分割)
tests/programs/interface/operator_compare.* 比較演算子テスト(分割)
tests/programs/interface/operator_bitwise.* ビット演算子テスト(分割)
tests/programs/interface/operator_compound_assign.* 算術複合代入テスト(分割)
tests/programs/interface/operator_bitwise_assign.* ビット複合代入テスト(分割)
tests/programs/enum/associated_data.* 新規(.error → .expected)
tests/programs/asm/.skip JSスキップファイル追加
tests/unified_test_runner.sh テストランナー改善

🧪 テスト状況

バックエンド 通過 失敗 スキップ
JIT (O0) 343 0 4
LLVM Native 343 0 4
LLVM WASM 338 0 5
JavaScript 298 0 49

📊 統計

  • テスト総数: 347
  • JIT/LLVMテスト通過: 343(0失敗)
  • WASMテスト通過: 338(0失敗)
  • JSテスト通過: 298(0失敗、v0.13.1の206から+92改善)
  • UEFIテスト: QEMUでHello World出力確認済み

🔮 今後の予定

  • v0.15.0: File I/O、パッケージ管理、JSバックエンドのポインタ/V...
Read more