Phase 10.10: GC Switchable Runtime & Unified Debug System 実装完了

Phase 10.10の主要実装:
- GcConfigBox: GC設定の実行時制御(counting/trace/barrier_strict)
- DebugConfigBox: デバッグ設定の統一管理(JIT events/stats/dump/dot)
- メソッドディスパッチ: system_methods.rsで両Boxのメソッド実装
- CountingGC動作確認: write_barriers正常カウント(VM実行時)

技術的詳細:
- BoxCore/BoxBase統一アーキテクチャを活用
- setFlag/getFlag/apply/summaryメソッドで統一API提供
- 環境変数経由でVM/JITランタイムと連携
- GcConfigBox.apply()は次回実行から有効(ランタイム作成前に環境変数参照)

テスト済み:
- examples/gc_counting_demo.nyash: CountingGCの動作確認
- write_barriers=3でArray.push/set, Map.setを正しくカウント
- NYASH_GC_TRACE=1でGC統計出力確認

Box-First哲学の体現: 設定も制御も観測もすべてBox!

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Moe Charm
2025-08-28 22:31:51 +09:00
parent 4e1b595796
commit d67f27f4b8
27 changed files with 1341 additions and 63 deletions

View File

@ -91,7 +91,7 @@ impl VMValue {
pub fn to_nyash_box(&self) -> Box<dyn NyashBox> {
match self {
VMValue::Integer(i) => Box::new(IntegerBox::new(*i)),
VMValue::Float(f) => Box::new(StringBox::new(&f.to_string())), // Simplified for now
VMValue::Float(f) => Box::new(crate::boxes::FloatBox::new(*f)),
VMValue::Bool(b) => Box::new(BoolBox::new(*b)),
VMValue::String(s) => Box::new(StringBox::new(s)),
VMValue::Future(f) => Box::new(f.clone()),
@ -591,7 +591,7 @@ impl VM {
self.pin_roots(args_vec.iter());
if let Some(jm_mut) = self.jit_manager.as_mut() {
if jm_mut.is_compiled(&function.signature.name) {
if let Some(val) = jm_mut.execute_compiled(&function.signature.name, &args_vec) {
if let Some(val) = jm_mut.execute_compiled(&function.signature.name, &function.signature.return_type, &args_vec) {
// Exit scope before returning
self.leave_root_region();
self.scope_tracker.pop_scope();
@ -609,7 +609,7 @@ impl VM {
// Try to compile now and execute; if not possible, error out
let _ = jm_mut.maybe_compile(&function.signature.name, function);
if jm_mut.is_compiled(&function.signature.name) {
if let Some(val) = jm_mut.execute_compiled(&function.signature.name, &args_vec) {
if let Some(val) = jm_mut.execute_compiled(&function.signature.name, &function.signature.return_type, &args_vec) {
self.leave_root_region();
self.scope_tracker.pop_scope();
return Ok(val);
@ -1018,6 +1018,50 @@ impl VM {
}
}
// MathBox methods (minimal set)
if let Some(math_box) = box_value.as_any().downcast_ref::<crate::boxes::math_box::MathBox>() {
// Coerce numeric-like StringBox to FloatBox for function-style lowering path
let mut coerce_num = |b: &Box<dyn NyashBox>| -> Box<dyn NyashBox> {
if let Some(sb) = b.as_any().downcast_ref::<StringBox>() {
let s = sb.value.trim();
if let Ok(f) = s.parse::<f64>() { return Box::new(crate::boxes::FloatBox::new(f)); }
if let Ok(i) = s.parse::<i64>() { return Box::new(IntegerBox::new(i)); }
}
b.clone_or_share()
};
match method {
"min" => {
if _args.len() >= 2 {
let a = coerce_num(&_args[0]);
let b = coerce_num(&_args[1]);
return Ok(math_box.min(a, b));
}
return Ok(Box::new(StringBox::new("Error: min(a,b) requires 2 args")));
}
"max" => {
if _args.len() >= 2 {
let a = coerce_num(&_args[0]);
let b = coerce_num(&_args[1]);
return Ok(math_box.max(a, b));
}
return Ok(Box::new(StringBox::new("Error: max(a,b) requires 2 args")));
}
"abs" => {
if let Some(v) = _args.get(0) { return Ok(math_box.abs(coerce_num(v))); }
return Ok(Box::new(StringBox::new("Error: abs(x) requires 1 arg")));
}
"sin" => {
if let Some(v) = _args.get(0) { return Ok(math_box.sin(coerce_num(v))); }
return Ok(Box::new(StringBox::new("Error: sin(x) requires 1 arg")));
}
"cos" => {
if let Some(v) = _args.get(0) { return Ok(math_box.cos(coerce_num(v))); }
return Ok(Box::new(StringBox::new("Error: cos(x) requires 1 arg")));
}
_ => return Ok(Box::new(VoidBox::new())),
}
}
// SocketBox methods (minimal set + timeout variants)
if let Some(sock) = box_value.as_any().downcast_ref::<crate::boxes::socket_box::SocketBox>() {
match method {