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

294 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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
```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。
- ポインタは `i32`WASM MVPを基本。ネイティブAOTではプラットフォーム幅に合わせる将来
- エンディアンはリトルエンディアンWASM/一般的なネイティブと一致)。
- 呼出規約は位置パラメータのみ(可変長/キーワードは範囲外)。
- 戻り値は単一スカラvoid含む。複合は out-param で表現(将来拡張)。
- メモリは `memory` をエクスポートWASM`TextDecoder('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, 日本語)
============================================================
```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 サンプル(ブラウザ, 日本語)
============================================================
```js
// 文字列(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).