Files
hakorune/docs/private/papers/paper-z-nyash-box-ffi

Nyash Box → C ABI → MultiLanguage FFI

要約Abstract

  • Nyash 言語で高レベルに実装した Box を LLVM AOT でオブジェクト化し、安定した C ABI をエクスポートすることで、Python / Rust / Go / Node.js / C++ など任意言語から単一の .so/.dll を即利用可能にする開発手法を提案する。内部では NyRT の C ABI を用いて組み込み BoxString/Array/Map 等)を安全に操作し、外部には簡潔で言語非依存の API を提供する。C ABI → C ABI の多層構成により、実装の生産性と配布・統合の容易さを両立する。

背景と課題

  • 既存のライブラリ開発では、C/C++ 実装+各言語向けバインディングの整備が恒常的なコストとなる。
  • 高速化や保守を優先すると低レベル実装が増え、開発速度や品質保証(型・所有権)が課題化する。
  • Nyash には Box 抽象と NyRTランタイムがあり、文字列・配列などの基本操作を統一的に扱える基盤が存在する。

提案Nyash×C ABI 多層アーキテクチャ)

  • 外層(公開):安定した C ABI関数名・引数/戻り値・所有権規約)
  • 内層実装Nyash で Box を高レベル記述し、NyRT の C ABI を通じて組み込み Box を操作
  • ビルドNyash → LLVM IR/objPIC→ .so/.dll/.dylibNyRT にリンク)

呼び出し経路(概念)

  • Host(App/Script) → FFI(C ABI) → lib<your_box>.so → NyRT(C ABI) → OS/stdlib

API/ABI 設計指針(最小)

  • 基本型i64 / f64 / bool / (ptr,len) 文字列・バイト列
  • 文字列返却:ヒープ確保して返す→呼び手が ny_free_str(void*) で解放
  • エラーint 戻り値0=OK, 非0=ERR詳細は必要なら out-param or errno スタイル
  • 可視性:公開関数は visibility=default,内部記号は hidden
  • 初期化:ny_init()/ny_shutdown() を用意方針により省略可。NyRT と二重初期化しない運用規約を明示
  • ビルド:全 .o を -fPICNyRT は動的(推奨)または PIC な静的リンクに統一

ケーススタディPoCStringBuilderBox

  • Nyash 実装(内部)
    • birth() で内部バッファArrayBox初期化
    • append(string) で pushtoString() で連結
  • 公開 C API
    • sb_handle* sb_new();
    • int sb_append(sb_handle*, const char* s, size_t n);
    • int sb_to_string(sb_handle*, char** out, size_t* out_len); // 呼び手が ny_free_str()
    • void sb_free(sb_handle*); void ny_free_str(void*);
    • (任意)int ny_init(); int ny_shutdown(); const char* ny_get_version();

多言語からの利用例(断片)

  • Python(ctypes)
    from ctypes import *
    lib = cdll.LoadLibrary('./libstringbuilder.so')
    lib.sb_new.restype = c_void_p
    h = lib.sb_new()
    lib.sb_append(h, b"hello", 5)
    out = c_void_p(); ln = c_size_t()
    lib.sb_to_string(h, byref(out), byref(ln))
    s = string_at(out.value, ln.value).decode('utf-8')
    lib.ny_free_str(out)
    lib.sb_free(h)
    
  • Rust(ffi)
    extern "C" {
        fn sb_new() -> *mut core::ffi::c_void;
        fn sb_append(h:*mut core::ffi::c_void, p:*const u8, n:usize) -> i32;
        fn sb_to_string(h:*mut core::ffi::c_void, out:*mut *mut u8, len:*mut usize) -> i32;
        fn ny_free_str(p:*mut core::ffi::c_void);
        fn sb_free(h:*mut core::ffi::c_void);
    }
    

評価計画(実務+学術)

  • 生産性:実装 LoC / 時間改修差分の小ささC 実装比)
  • 性能:連結 10^6 回のスループットFFI 境界のオーバーヘッド(まとめ API で最適化)
  • 信頼性ASan/valgrind文字列所有権リークゼロ
  • 多言語統合Python/Rust/Go/Node で同一 .so をスモーク
  • 再利用性:同一成果物を Nyash プラグイン(v2) と汎用 C ライブラリの両用途で利用

限界とリスク

  • NyRT とのリンク方針不一致(動的/静的)やバージョン差異で未定義動作の恐れ → 版照合 API と CI を用意
  • 返却バッファの所有権取り決めが曖昧だとリーク → ny_free_str() を ABI の一部に
  • マルチスレッドでの再入性 → 仕様として明示(必要に応じロック/TLS

ロードマップ

  1. PoCStringBuilderBox を .so 化PICNyRTリンクPython/Rust スモークとリーク検査
  2. Nyash プラグイン(v2) ラッパ追加(nyash.toml に登録)
  3. JSON/文字列ユーティリティの横展開(共通 ABI ルール化)
  4. ABI 自動生成Nyash シグネチャ → C ヘッダ/ラッパ生成
  5. パッケージ化テンプレヘッダpkg-configCI スモーク)

関連文書

  • ScopeBox/LoopForm制御構造の正規化構想docs/guides/loopform.md
  • Nyash LLVM/LlvmPy 概要docs/design/LLVM_LAYER_OVERVIEW.md
  • Seamaware JSON Unification前処理と決定論実装papers/paper-y-seam-aware-json-unification/README.md