Files
hakorune/docs/説明書/reference/box-design/ffi-abi-specification.md
Moe Charm e0f0a658e6 docs: Phase 9.75 Box設計根本革命 - SocketBox Arc<Mutex>責務一元化
 Phase 9.75実装計画追加:
- copilot_issues.txtにPhase 9.75追加(Phase 9.7と9.8の間)
- Arc<Mutex>二重化問題の根本解決計画
- 段階的実装戦略(Phase A-D)定義

📚 Box設計ドキュメント完全体系化:
- docs/説明書/reference/box-design/ 新設
- everything-is-box.md: 核心哲学の完全解説
- memory-management.md: Arc<Mutex>設計・fini/weak参照
- delegation-system.md: 完全明示デリゲーション仕様
- box-types-catalog.md: 全Box型の完全カタログ
- ffi-abi-specification.md: FFI/ABI仕様(移動済み)

🔧 実装ノート完備:
- current-issues.md: 現在進行中の設計課題
- socket-box-problem.md: Arc<Mutex>二重化問題詳細分析
- phase-9-75-redesign.md: 実装計画詳細

👥 Copilot実装ガイド作成:
- phase9_75_socketbox_arc_mutex_redesign.md
- SocketBox優先対応の具体的実装手順
- 完全テストスイート設計
- 段階的実装戦略(Step 1-5)

📋 CURRENT_TASK.md更新:
- Box設計ドキュメント完成記録
- Phase 9.75準備完了状況

🎯 効果:
- Everything is Box哲学の体系的文書化
- SocketBox問題解決の明確な道筋
- Copilot協調実装の準備完了
- 新規開発者オンボーディング改善

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-15 07:47:09 +09:00

11 KiB
Raw Blame History

Box FFI/ABI v0 (Draft)

Purpose

  • Define a language-agnostic ABI to call external libraries as Boxes.
  • Serve as a single source of truth for MIR ExternCall, WASM RuntimeImports, VM stubs, and future language codegens (TS/Python/Rust/LLVM IR).

Design Goals

  • Simple first: UTF-8 strings as (ptr,len), i32 for small integers, 32-bit linear memory alignment friendly.
  • Deterministic and portable across WASM/VM/native backends.
  • Align with MIR effect system (pure/mut/io/control) to preserve optimization safety.

Core Types

  • i32, i64, f32, f64, bool (0|1)
  • string: UTF-8 in linear memory as (ptr: i32, len: i32)
  • boxref: opaque 32-bit handle or pointer (backend-dependent)
  • array(T): (ptr: i32, len: i32, [cap: i32 optional])
  • void, null (represented as 0 for pointer-like values)

Memory & Alignment

  • All pointers are 32-bit in WASM MVP. Align to 4 bytes.
  • Strings/arrays must be contiguous in linear memory; no NUL terminator required (len is authoritative).
  • Box layout examples for built-ins (for backends that materialize Boxes in memory):
    • Header: [type_id:i32][ref_count:i32][field_count:i32]
    • StringBox: header + [data_ptr:i32][length:i32]

Naming & Resolution

  • Interface namespace: env.console, env.canvas, etc.
  • Method: log, fillRect, fillText.
  • Fully-qualified name: env.console.log, env.canvas.fillRect.

Calling Convention (v0)

  • Positional parameters, no varargs.
  • Strings/arrays passed as (ptr,len) pairs.
  • Return values:
    • Single scalar (i32/i64/f32/f64/bool) or void.
    • Box/complex returns are out-of-scope for v0; use out-params if necessary.

Error Model (v0)

  • Prefer total functions for v0 demos.
  • If needed, return i32 status (0=ok, nonzero=error) and use out-params.
  • Exceptions/signals are out-of-scope.

Effects

  • Each BID method declares one of: pure | mut | io | control.
  • Optimizer/verifier rules:
    • pure: reordering permitted
    • mut: preserve order w.r.t same resource
    • io: preserve program order
    • control: affects CFG; handled as terminators or dedicated ops

BID (Box Interface Definition) — YAML

version: 0
interfaces:
  - name: env.console
    box: Console
    methods:
      - name: log
        params: [ {string: msg} ]
        returns: void
        effect: io

  - name: env.canvas
    box: Canvas
    methods:
      - name: fillRect
        params:
          - {string: canvas_id}
          - {i32: x}
          - {i32: y}
          - {i32: w}
          - {i32: h}
          - {string: color}
        returns: void
        effect: io

      - name: fillText
        params:
          - {string: canvas_id}
          - {string: text}
          - {i32: x}
          - {i32: y}
          - {string: font}
          - {string: color}
        returns: void
        effect: io

WASM Mapping (RuntimeImports)

  • Import examples:
    • (import "env" "console_log" (func $console_log (param i32 i32))) // (ptr,len)
    • (import "env" "canvas_fillRect" (func $canvas_fillRect (param i32 i32 i32 i32 i32 i32)))
    • (import "env" "canvas_fillText" (func $canvas_fillText (param i32 i32 i32 i32 i32 i32 i32 i32))) // two strings as (ptr,len) each
  • Host responsibilities:
    • Resolve strings from memory via (ptr,len) using TextDecoder('utf-8')
    • Map to DOM/Canvas/Console as appropriate

WASM Mapping Rules (v0)

  • String marshalling: UTF-8 (ptr:i32, len:i32); memory exported as memory.
  • Alignment: ptr 4-byte aligned is推奨必須ではないが実装簡素化のため
  • Import naming: env.<iface>_<method> or nested env modules実装都合でどちらでも可
    • 推奨: env.console_log, env.canvas_fillRect, env.canvas_fillText
  • Argument order: 文字列は (ptr,len) を1引数扱いで連続配置。複数文字列はその都度 (ptr,len)
  • Return: v0ではvoidまたは整数のみ複合戻りはout-paramに委譲
  • Memory growth: ホストはmemory.bufferの再割当を考慮(必要に応じて毎回ビューを取り直す)。

RuntimeImportsとBIDの関係

  • RuntimeImports は ABI/BID をWASM向けに具体化した実装レイヤーWASM専用の橋渡し
  • 生成方針: 将来的にBIDYAML/JSONからimportObject(import ...)宣言を自動生成する。
  • BID→WASM:
    • env.console.log(string msg)console_log(ptr:i32, len:i32)
    • env.canvas.fillRect(string canvasId, i32 x, i32 y, i32 w, i32 h, string color)canvas_fillRect(id_ptr, id_len, x, y, w, h, color_ptr, color_len)

============================================================ ABIの確定事項v0, 日本語)

基本方針v0

  • 文字列は UTF-8 の (ptr:i32, len:i32) で受け渡すNUL終端不要
  • 配列/バイト列は (ptr:i32, len:i32[, cap:i32]) とし、v0では (ptr,len) を基本とする。
  • 数値は WASM/LLVM と親和性の高い素のプリミティブi32/i64/f32/f64
  • 真偽値は i32 で 0=false, 1=true。
  • ポインタは i32WASM MVPを基本。ネイティブAOTではプラットフォーム幅に合わせる将来
  • エンディアンはリトルエンディアンWASM/一般的なネイティブと一致)。
  • 呼出規約は位置パラメータのみ(可変長/キーワードは範囲外)。
  • 戻り値は単一スカラvoid含む。複合は out-param で表現(将来拡張)。
  • メモリは memory をエクスポートWASMTextDecoder('utf-8') 等で復元Host側責務
  • 効果effectは BID に必須。pure は再順序化可、mut/io は順序保持。
  • 同期のみ(非同期は将来拡張)。

型と表現v0

  • i32: 32bit 符号付き整数
  • i64: 64bit 符号付き整数WASMではJSブリッジ注意。Host側はBigInt等
  • f32/f64: IEEE 754
  • bool: i320/1
  • string: UTF-8 (ptr:i32, len:i32)
  • array<T>: (ptr:i32, len:i32[, cap:i32])v0は (ptr,len) を優先)
  • boxref: Opaque数値ハンドル or ポインタ。v0では数値 i32 を推奨。

アラインメント/境界

  • ptr は 4byte アライン推奨(必須ではないが実装が簡潔)。
  • 範囲外アクセスは未定義ではなく「Hostが防ぐ/検証する」方針将来、Verifier/境界チェック生成)。

命名規約

  • env.console.log, env.canvas.fillRect のように <namespace>.<iface>.<method>
  • WASM import 名は env.console_log 等の平坦化でも可(生成側で一貫)。

エラー/例外

  • v0は例外なし。失敗は整数ステータス or 明示エラーコールバックに委譲(将来)。

セキュリティ/権限(将来)

  • BID に必要権限console/canvas/storage/net…を記述。HostはAllowlistで制御Phase 9.9)。

============================================================ BIDサンプルYAML, 日本語)

version: 0
interfaces:
  - name: env.console
    box: Console
    methods:
      - name: log
        params: [ { string: msg } ]
        returns: void
        effect: io

  - name: env.canvas
    box: Canvas
    methods:
      - name: fillRect
        params:
          - { string: canvas_id }
          - { i32: x }
          - { i32: y }
          - { i32: w }
          - { i32: h }
          - { string: color }
        returns: void
        effect: io

      - name: fillText
        params:
          - { string: canvas_id }
          - { string: text }
          - { i32: x }
          - { i32: y }
          - { string: font }
          - { string: color }
        returns: void
        effect: io

ファイルとしてのサンプル(同等内容)

  • docs/nyir/bid_samples/console.yaml
  • docs/nyir/bid_samples/canvas.yaml

============================================================ Host側 importObject サンプル(ブラウザ, 日本語)

// 文字列(ptr,len)の復元ヘルパ
function utf8FromMemory(memory, ptr, len) {
  const u8 = new Uint8Array(memory.buffer, ptr, len);
  return new TextDecoder('utf-8').decode(u8);
}

const importObject = {
  env: {
    print: (v) => console.log(v),
    print_str: (ptr, len) => {
      console.log(utf8FromMemory(wasmInstance.exports.memory, ptr, len));
    },
    console_log: (ptr, len) => {
      console.log(utf8FromMemory(wasmInstance.exports.memory, ptr, len));
    },
    canvas_fillRect: (idPtr, idLen, x, y, w, h, colorPtr, colorLen) => {
      const mem = wasmInstance.exports.memory;
      const id = utf8FromMemory(mem, idPtr, idLen);
      const color = utf8FromMemory(mem, colorPtr, colorLen);
      const cv = document.getElementById(id);
      if (!cv) return;
      const ctx = cv.getContext('2d');
      ctx.fillStyle = color;
      ctx.fillRect(x, y, w, h);
    },
    canvas_fillText: (idPtr, idLen, textPtr, textLen, x, y, fontPtr, fontLen, colorPtr, colorLen) => {
      const mem = wasmInstance.exports.memory;
      const id = utf8FromMemory(mem, idPtr, idLen);
      const text = utf8FromMemory(mem, textPtr, textLen);
      const font = utf8FromMemory(mem, fontPtr, fontLen);
      const color = utf8FromMemory(mem, colorPtr, colorLen);
      const cv = document.getElementById(id);
      if (!cv) return;
      const ctx = cv.getContext('2d');
      ctx.font = font;
      ctx.fillStyle = color;
      ctx.fillText(text, x, y);
    }
  }
};

============================================================ ExternCall → WASM 呼び出しの例(日本語)

Nyash コード(概念):

console = new WebConsoleBox("output")
console.log("Hello Nyash!")

canvas = new WebCanvasBox("game-canvas", 400, 300)
canvas.fillRect(50, 50, 80, 60, "red")

MIRExternCall化のイメージ:

ExternCall { iface: "env.console", method: "log", args: [ string("Hello Nyash!") ] }
ExternCall { iface: "env.canvas", method: "fillRect", args: [ string("game-canvas"), 50, 50, 80, 60, string("red") ] }

WASM import 呼び出し(概念):

call $console_log(msg_ptr, msg_len)
call $canvas_fillRect(id_ptr, id_len, 50, 50, 80, 60, color_ptr, color_len)

備考

  • 文字列定数は data segment に配置し、実行時に (ptr,len) を与える。
  • 動的文字列はランタイムでバッファ確保→(ptr,len) を渡す。

VM Mapping (Stub v0)

  • Maintain a registry of externs by FQN (e.g., env.console.log) → function pointer.
  • Console: print to stdout; Canvas: log params or no-op.

LLVM IR Mapping (Preview)

  • Declare external functions with matching signatures (i32/i64/f32/f64/bool, i8* + i32 for strings).
  • Example: declare void @env_console_log(i8* nocapture, i32)
  • Strings allocated in data segment or heap; pass pointer + length.

Versioning

  • version: 0 for the first public draft.
  • Backward-compatible extensions should add new methods/imports; breaking changes bump major.

Open Points (to validate post v0)

  • Boxref passing across FFI boundaries (opaque handles vs pointers).
  • Async externs and scheduling.
  • Error model harmonization (status vs result-box).