feat: GC機能復活&VM整理&json_native調査完了

## 🎉 ChatGPT×Claude協働成果
-  **GC機能復活**: vm-legacy削除で失われたGC機能を新実装で復活
  - GCメトリクス追跡システム実装(alloc/collect/pause計測)
  - 3種類のGCモード対応(counting/mark_sweep/generational)
  - host_handles.rsでハンドル管理復活

-  **VM整理とエイリアス追加**: 混乱していた名前を整理
  - MirInterpreter = NyashVm = VM のエイリアス統一
  - vm-legacyとインタープリターの違いを明確化
  - 壊れていたvm.rsの互換性修復

-  **スモークテスト整理**: v2構造でプラグイン/コア分離
  - plugins/ディレクトリにプラグインテスト移動
  - gc_metrics.sh, gc_mode_off.sh, async_await.sh追加
  - _ensure_fixture.shでプラグイン事前ビルド確認

## 📊 json_native調査結果
- **現状**: 25%完成(配列/オブジェクトパース未実装)
- **将来性**: 並行処理でyyjson超えの可能性大
  - 100KB以上のJSONで2-10倍速の可能性
  - Nyash ABI実装後はゼロコピー最適化
- **判断**: 現時点では置換不可、将来の大きな足場

## 🔍 技術的発見
- vm-legacy = 完全なVM実装(GC付き)だった
- MirInterpreter = 現在のRust VM(712行、Arc使用)
- 200行簡易JSONは既に削除済み(存在しない)

ChatGPT爆速修復×Claude詳細調査の完璧な協働!

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Selfhosting Dev
2025-09-24 23:27:59 +09:00
parent e5f6d51b3c
commit 9b9a91c859
36 changed files with 556 additions and 178 deletions

View File

@ -242,6 +242,47 @@ impl MirInterpreter {
.insert(fname, valv);
continue;
}
// Builtin StringBox minimal methods (length/concat) to bridge plugin-first gaps
{
let recv = self.reg_load(*box_val)?;
let recv_box_any: Box<dyn crate::box_trait::NyashBox> = match recv.clone() {
VMValue::BoxRef(b) => b.share_box(),
other => other.to_nyash_box(),
};
if let Some(sb) = recv_box_any
.as_any()
.downcast_ref::<crate::box_trait::StringBox>()
{
match method.as_str() {
"length" => {
let ret = sb.length();
if let Some(d) = dst {
self.regs.insert(*d, VMValue::from_nyash_box(ret));
}
continue;
}
"concat" => {
if args.len() != 1 {
return Err(VMError::InvalidInstruction(
"concat expects 1 arg".into(),
));
}
let rhs = self.reg_load(args[0])?;
let new_s = format!("{}{}", sb.value, rhs.to_string());
if let Some(d) = dst {
self.regs.insert(
*d,
VMValue::from_nyash_box(Box::new(
crate::box_trait::StringBox::new(new_s),
)),
);
}
continue;
}
_ => { /* fallthrough to plugin or error */ }
}
}
}
// Fallback: treat like PluginInvoke for plugin-backed boxes
let recv = self.reg_load(*box_val)?;
let recv_box: Box<dyn crate::box_trait::NyashBox> = match recv.clone() {
@ -322,20 +363,87 @@ impl MirInterpreter {
args,
..
} => {
// Minimal env.console.log bridge
if iface_name == "env.console" && method_name == "log" {
if let Some(a0) = args.get(0) {
let v = self.reg_load(*a0)?;
println!("{}", v.to_string());
match (iface_name.as_str(), method_name.as_str()) {
("env.console", "log") => {
if let Some(a0) = args.get(0) {
let v = self.reg_load(*a0)?;
println!("{}", v.to_string());
}
if let Some(d) = dst {
self.regs.insert(*d, VMValue::Void);
}
}
if let Some(d) = dst {
self.regs.insert(*d, VMValue::Void);
("env.future", "new") => {
let fut = crate::boxes::future::NyashFutureBox::new();
if let Some(a0) = args.get(0) {
let v = self.reg_load(*a0)?;
fut.set_result(v.to_nyash_box());
}
if let Some(d) = dst {
self.regs.insert(*d, VMValue::Future(fut));
}
}
("env.future", "set") => {
if args.len() >= 2 {
let f = self.reg_load(args[0])?;
let v = self.reg_load(args[1])?;
if let VMValue::Future(fut) = f {
fut.set_result(v.to_nyash_box());
} else {
return Err(VMError::TypeError("env.future.set expects Future".into()));
}
}
if let Some(d) = dst {
self.regs.insert(*d, VMValue::Void);
}
}
("env.future", "await") => {
if let Some(a0) = args.get(0) {
let f = self.reg_load(*a0)?;
match f {
VMValue::Future(fut) => {
// Coarse safepoint while blocking
let v = fut.get();
if let Some(d) = dst {
self.regs.insert(*d, VMValue::from_nyash_box(v));
}
}
_ => return Err(VMError::TypeError("await expects Future".into())),
}
}
}
("env.runtime", "checkpoint") => {
crate::runtime::global_hooks::safepoint_and_poll();
if let Some(d) = dst {
self.regs.insert(*d, VMValue::Void);
}
}
("env.modules", "set") => {
if args.len() >= 2 {
let k = self.reg_load(args[0])?.to_string();
let v = self.reg_load(args[1])?.to_nyash_box();
crate::runtime::modules_registry::set(k, v);
}
if let Some(d) = dst {
self.regs.insert(*d, VMValue::Void);
}
}
("env.modules", "get") => {
if let Some(a0) = args.get(0) {
let k = self.reg_load(*a0)?.to_string();
let vb = crate::runtime::modules_registry::get(&k)
.unwrap_or_else(|| Box::new(crate::box_trait::VoidBox::new()));
if let Some(d) = dst {
self.regs.insert(*d, VMValue::from_nyash_box(vb));
}
}
}
_ => {
return Err(VMError::InvalidInstruction(format!(
"ExternCall {}.{} not supported",
iface_name, method_name
)));
}
} else {
return Err(VMError::InvalidInstruction(format!(
"ExternCall {}.{} not supported",
iface_name, method_name
)));
}
}
MirInstruction::RefSet {

View File

@ -14,7 +14,7 @@ pub mod vm {
// Core backend modules
pub mod abi_util; // Shared ABI/utility helpers
pub mod gc_helpers;
pub mod mir_interpreter; // Lightweight MIR interpreter
pub mod mir_interpreter; // Lightweight MIR interpreter (Rust VM core)
#[cfg(feature = "wasm-backend")]
pub mod aot;
@ -31,7 +31,12 @@ pub mod cranelift;
#[cfg(feature = "llvm-inkwell-legacy")]
pub mod llvm;
// Public aliases to make the role of the VM clear in runner/tests
pub use mir_interpreter::MirInterpreter;
/// Primary Rust VM executor alias (preferred name)
pub type NyashVm = mir_interpreter::MirInterpreter;
/// Back-compat shim used across runner/tests
pub type VM = NyashVm;
// Always re-export VMError/VMValue from vm_types
pub use vm_types::{VMError, VMValue};