Files
hakorune/docs/papers/active/unified-lifecycle/technical-details.md
Moe Charm fff9749f47 📚 Reorganize CLAUDE.md: slim down from 916 to 395 lines with proper doc links
- Keep essential information within 500 lines (now 395 lines)
- Maintain important syntax examples and development principles
- Move detailed information to appropriate docs files:
  - Development practices → docs/guides/development-practices.md
  - Testing guide → docs/guides/testing-guide.md
  - Claude issues → docs/tools/claude-issues.md
- Add proper links to all referenced documentation
- Balance between minimal entry point and practical usability
2025-08-31 06:22:48 +09:00

231 lines
5.7 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.

# Technical Details
## 1. ライフサイクル設計の詳細
### 1.1 所有権の森Ownership Forest
```
A (strong owner)
├── B (strong)
│ └── D (strong)
└── C (strong)
└── E (weak) → B
```
**不変条件**:
-ードの強参照in-degreeは最大1
- weakエッジは所有権に関与しない
- サイクルはweakエッジでのみ許可
### 1.2 決定的破棄順序
```rust
// ScopeTrackerの実装
impl ScopeTracker {
fn exit_scope(&mut self) {
// LIFO順で破棄
while let Some(box_id) = self.scope_stack.pop() {
if let Some(pbox) = self.get_box(box_id) {
// finiを呼ぶ
pbox.call_fini();
}
}
}
}
```
## 2. プラグインシステムの実装
### 2.1 TLVエンコーディング
```rust
// Type定義
const TLV_BOOL: u16 = 1; // 1 byte: 0 or 1
const TLV_I64: u16 = 3; // 8 bytes: little endian
const TLV_STRING: u16 = 4; // n bytes: UTF-8
const TLV_HANDLE: u16 = 8; // 8 bytes: type_id(4) + instance_id(4)
const TLV_VOID: u16 = 9; // 0 bytes
// エンコード例
fn encode_string(s: &str) -> Vec<u8> {
let mut buf = vec![];
buf.extend(&TLV_STRING.to_le_bytes());
buf.extend(&(s.len() as u16).to_le_bytes());
buf.extend(s.as_bytes());
buf
}
```
### 2.2 プラグイン実装例StringBox
```rust
// StringBoxプラグイン
struct StringInstance {
data: String,
}
static INSTANCES: Lazy<Mutex<HashMap<u32, StringInstance>>> =
Lazy::new(|| Mutex::new(HashMap::new()));
#[no_mangle]
extern "C" fn nyash_plugin_invoke(
type_id: u32,
method_id: u32,
instance_id: u32,
args: *const u8,
args_len: usize,
result: *mut u8,
result_len: *mut usize,
) -> i32 {
match method_id {
METHOD_BIRTH => {
// 新しいインスタンス作成
let inst = StringInstance {
data: String::new(),
};
let id = INSTANCE_COUNTER.fetch_add(1, Ordering::SeqCst);
INSTANCES.lock().unwrap().insert(id, inst);
write_tlv_handle(type_id, id, result, result_len)
}
METHOD_LENGTH => {
// 文字列長を返す
let instances = INSTANCES.lock().unwrap();
if let Some(inst) = instances.get(&instance_id) {
let len = inst.data.len() as i64;
write_tlv_i64(len, result, result_len)
} else {
NYB_E_INVALID_HANDLE
}
}
METHOD_FINI => {
// インスタンス破棄Dropが自動実行
INSTANCES.lock().unwrap().remove(&instance_id);
NYB_OK
}
_ => NYB_E_INVALID_METHOD,
}
}
```
## 3. JIT統合
### 3.1 プラグイン呼び出しのJITコンパイル
```rust
// LowerCoreでのプラグイン呼び出し生成
fn lower_box_call(&mut self, method: &str, args: &[ValueId]) {
if let Ok(h) = plugin_host.resolve_method("StringBox", method) {
// スタックに引数を積む
self.builder.emit_param_i64(receiver_idx);
for arg in args {
self.push_value(arg);
}
// プラグイン呼び出し命令を生成
self.builder.emit_plugin_invoke(
h.type_id,
h.method_id,
args.len() + 1,
has_return
);
}
}
```
### 3.2 Craneliftでのコード生成
```rust
// nyash_plugin_invoke3_i64 シムの実装
extern "C" fn nyash_plugin_invoke3_i64(
type_id: i64,
method_id: i64,
argc: i64,
a0: i64, // receiver (param index)
a1: i64, // arg1
a2: i64, // arg2
) -> i64 {
// レシーバーをVMの引数から解決
let instance_id = resolve_instance_from_vm_args(a0);
// TLVエンコードで引数準備
let mut tlv_args = encode_tlv_header(argc - 1);
if argc >= 2 { encode_i64(&mut tlv_args, a1); }
if argc >= 3 { encode_i64(&mut tlv_args, a2); }
// プラグイン呼び出し
let mut result = [0u8; 32];
let mut result_len = result.len();
let rc = invoke_plugin(
type_id as u32,
method_id as u32,
instance_id,
&tlv_args,
&mut result,
&mut result_len
);
// 結果をデコードして返す
decode_tlv_i64(&result[..result_len]).unwrap_or(0)
}
```
## 4. GCオン/オフ等価性
### 4.1 アノテーション処理
```rust
enum BoxAnnotation {
MustDrop, // @must_drop - 即時破棄必須
GCable, // @gcable - GC可能遅延OK
}
impl GarbageCollector {
fn should_collect(&self, box_type: &BoxType) -> bool {
match box_type.annotation {
BoxAnnotation::MustDrop => false, // GC対象外
BoxAnnotation::GCable => self.gc_enabled,
}
}
}
```
### 4.2 観測不可能性の保証
```rust
// テストケースGCオン/オフで同じ結果
#[test]
fn test_gc_equivalence() {
let output_gc_on = run_with_gc(true, "test.nyash");
let output_gc_off = run_with_gc(false, "test.nyash");
assert_eq!(output_gc_on.io_trace, output_gc_off.io_trace);
assert_eq!(output_gc_on.result, output_gc_off.result);
}
```
## 5. 静的リンクによる最適化
### 5.1 AOT変換
```bash
# NyashからCLIFへ
nyashc --emit-clif program.nyash > program.clif
# CLIFからオブジェクトファイルへ
cranelift-objdump program.clif -o program.o
# 静的リンクPLT回避
cc program.o -static \
-L. -lnyrt \
-lnyplug_array \
-lnyplug_string \
-o program
```
### 5.2 パフォーマンス比較
```
動的リンクPLT経由: ~15ns/call
静的リンク(直接呼出): ~2ns/call
インライン展開後: ~0.5ns/call
```