Phase 1-3 implementation: Arc sharing in core data structures
Co-authored-by: moe-charm <217100418+moe-charm@users.noreply.github.com>
This commit is contained in:
@ -13,6 +13,9 @@ use std::sync::atomic::{AtomicU64, Ordering};
|
|||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
|
// 🔥 新しい型エイリアス - 将来的にBox<dyn NyashBox>を全て置き換える
|
||||||
|
pub type SharedNyashBox = Arc<dyn NyashBox>;
|
||||||
|
|
||||||
/// 🔥 BoxBase + BoxCore革命 - 統一ID生成システム
|
/// 🔥 BoxBase + BoxCore革命 - 統一ID生成システム
|
||||||
/// CharmFlow教訓を活かした互換性保証の基盤
|
/// CharmFlow教訓を活かした互換性保証の基盤
|
||||||
pub fn next_box_id() -> u64 {
|
pub fn next_box_id() -> u64 {
|
||||||
@ -84,6 +87,11 @@ pub trait NyashBox: BoxCore + Debug {
|
|||||||
/// Clone this box (equivalent to Python's copy())
|
/// Clone this box (equivalent to Python's copy())
|
||||||
fn clone_box(&self) -> Box<dyn NyashBox>;
|
fn clone_box(&self) -> Box<dyn NyashBox>;
|
||||||
|
|
||||||
|
/// Arc参照を返す新しいcloneメソッド(参照共有)
|
||||||
|
fn clone_arc(&self) -> SharedNyashBox {
|
||||||
|
Arc::from(self.clone_box())
|
||||||
|
}
|
||||||
|
|
||||||
// 🌟 TypeBox革命: Get type information as a Box
|
// 🌟 TypeBox革命: Get type information as a Box
|
||||||
// Everything is Box極限実現 - 型情報もBoxとして取得!
|
// Everything is Box極限実現 - 型情報もBoxとして取得!
|
||||||
// TODO: 次のステップで完全実装
|
// TODO: 次のステップで完全実装
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
* Everything is Box哲学に基づくオブジェクト指向システム
|
* Everything is Box哲学に基づくオブジェクト指向システム
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use crate::box_trait::{NyashBox, StringBox, BoolBox, VoidBox, BoxCore, BoxBase};
|
use crate::box_trait::{NyashBox, StringBox, BoolBox, VoidBox, BoxCore, BoxBase, SharedNyashBox};
|
||||||
use crate::ast::ASTNode;
|
use crate::ast::ASTNode;
|
||||||
use crate::value::NyashValue;
|
use crate::value::NyashValue;
|
||||||
use crate::interpreter::NyashInterpreter;
|
use crate::interpreter::NyashInterpreter;
|
||||||
@ -20,8 +20,8 @@ pub struct InstanceBox {
|
|||||||
/// クラス名
|
/// クラス名
|
||||||
pub class_name: String,
|
pub class_name: String,
|
||||||
|
|
||||||
/// フィールド値 (Legacy compatibility)
|
/// フィールド値 (Updated to use Arc for reference sharing)
|
||||||
pub fields: Arc<Mutex<HashMap<String, Box<dyn NyashBox>>>>,
|
pub fields: Arc<Mutex<HashMap<String, SharedNyashBox>>>,
|
||||||
|
|
||||||
/// 🔗 Next-generation fields (weak reference capable)
|
/// 🔗 Next-generation fields (weak reference capable)
|
||||||
pub fields_ng: Arc<Mutex<HashMap<String, NyashValue>>>,
|
pub fields_ng: Arc<Mutex<HashMap<String, NyashValue>>>,
|
||||||
@ -49,9 +49,9 @@ pub struct InstanceBox {
|
|||||||
impl InstanceBox {
|
impl InstanceBox {
|
||||||
pub fn new(class_name: String, fields: Vec<String>, methods: HashMap<String, ASTNode>) -> Self {
|
pub fn new(class_name: String, fields: Vec<String>, methods: HashMap<String, ASTNode>) -> Self {
|
||||||
// フィールドをVoidBoxで初期化
|
// フィールドをVoidBoxで初期化
|
||||||
let mut field_map = HashMap::new();
|
let mut field_map: HashMap<String, SharedNyashBox> = HashMap::new();
|
||||||
for field in &fields {
|
for field in &fields {
|
||||||
field_map.insert(field.clone(), Box::new(VoidBox::new()) as Box<dyn NyashBox>);
|
field_map.insert(field.clone(), Arc::new(VoidBox::new()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
@ -270,14 +270,24 @@ impl InstanceBox {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// フィールドの値を取得
|
/// フィールドの値を取得
|
||||||
pub fn get_field(&self, field_name: &str) -> Option<Box<dyn NyashBox>> {
|
pub fn get_field(&self, field_name: &str) -> Option<SharedNyashBox> {
|
||||||
self.fields.lock().unwrap().get(field_name).map(|v| v.clone_box())
|
eprintln!("✅ FIX: get_field('{}') returning shared Arc reference", field_name);
|
||||||
|
|
||||||
|
// 🔧 修正:v.clone_box() → Arc::clone(v) で参照共有
|
||||||
|
self.fields.lock().unwrap().get(field_name).map(Arc::clone)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// フィールドに値を設定
|
/// フィールドに値を設定
|
||||||
pub fn set_field(&self, field_name: &str, value: Box<dyn NyashBox>) -> Result<(), String> {
|
pub fn set_field(&self, field_name: &str, value: SharedNyashBox) -> Result<(), String> {
|
||||||
|
eprintln!("🔧 INSTANCE: set_field('{}') with shared Arc reference id={}",
|
||||||
|
field_name, value.box_id());
|
||||||
|
|
||||||
let mut fields = self.fields.lock().unwrap();
|
let mut fields = self.fields.lock().unwrap();
|
||||||
if fields.contains_key(field_name) {
|
if fields.contains_key(field_name) {
|
||||||
|
if let Some(old_value) = fields.get(field_name) {
|
||||||
|
eprintln!("🔧 INSTANCE: Replacing field '{}': old_id={} -> new_id={}",
|
||||||
|
field_name, old_value.box_id(), value.box_id());
|
||||||
|
}
|
||||||
fields.insert(field_name.to_string(), value);
|
fields.insert(field_name.to_string(), value);
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
@ -286,7 +296,7 @@ impl InstanceBox {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// 🌍 GlobalBox用:フィールドを動的に追加・設定
|
/// 🌍 GlobalBox用:フィールドを動的に追加・設定
|
||||||
pub fn set_field_dynamic(&mut self, field_name: String, value: Box<dyn NyashBox>) {
|
pub fn set_field_dynamic(&mut self, field_name: String, value: SharedNyashBox) {
|
||||||
let mut fields = self.fields.lock().unwrap();
|
let mut fields = self.fields.lock().unwrap();
|
||||||
fields.insert(field_name, value);
|
fields.insert(field_name, value);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
use crate::ast::{ASTNode, Span};
|
use crate::ast::{ASTNode, Span};
|
||||||
use crate::box_trait::{NyashBox, StringBox, IntegerBox, BoolBox, VoidBox};
|
use crate::box_trait::{NyashBox, StringBox, IntegerBox, BoolBox, VoidBox, SharedNyashBox};
|
||||||
use crate::instance::InstanceBox;
|
use crate::instance::InstanceBox;
|
||||||
use crate::parser::ParseError;
|
use crate::parser::ParseError;
|
||||||
use std::sync::{Arc, Mutex, RwLock};
|
use std::sync::{Arc, Mutex, RwLock};
|
||||||
@ -192,10 +192,10 @@ pub struct NyashInterpreter {
|
|||||||
pub(super) shared: SharedState,
|
pub(super) shared: SharedState,
|
||||||
|
|
||||||
/// 📦 local変数スタック(関数呼び出し時の一時変数)
|
/// 📦 local変数スタック(関数呼び出し時の一時変数)
|
||||||
pub(super) local_vars: HashMap<String, Box<dyn NyashBox>>,
|
pub(super) local_vars: HashMap<String, SharedNyashBox>,
|
||||||
|
|
||||||
/// 📤 outbox変数スタック(static関数内の所有権移転変数)
|
/// 📤 outbox変数スタック(static関数内の所有権移転変数)
|
||||||
pub(super) outbox_vars: HashMap<String, Box<dyn NyashBox>>,
|
pub(super) outbox_vars: HashMap<String, SharedNyashBox>,
|
||||||
|
|
||||||
/// 制御フロー状態
|
/// 制御フロー状態
|
||||||
pub(super) control_flow: ControlFlow,
|
pub(super) control_flow: ControlFlow,
|
||||||
@ -322,7 +322,7 @@ impl NyashInterpreter {
|
|||||||
// ========== 🌍 GlobalBox変数解決システム ==========
|
// ========== 🌍 GlobalBox変数解決システム ==========
|
||||||
|
|
||||||
/// 革命的変数解決: local変数 → GlobalBoxフィールド → エラー
|
/// 革命的変数解決: local変数 → GlobalBoxフィールド → エラー
|
||||||
pub(super) fn resolve_variable(&self, name: &str) -> Result<Box<dyn NyashBox>, RuntimeError> {
|
pub(super) fn resolve_variable(&self, name: &str) -> Result<SharedNyashBox, RuntimeError> {
|
||||||
let log_msg = format!("resolve_variable: name='{}', local_vars={:?}",
|
let log_msg = format!("resolve_variable: name='{}', local_vars={:?}",
|
||||||
name, self.local_vars.keys().collect::<Vec<_>>());
|
name, self.local_vars.keys().collect::<Vec<_>>());
|
||||||
debug_log(&log_msg);
|
debug_log(&log_msg);
|
||||||
@ -331,13 +331,27 @@ impl NyashInterpreter {
|
|||||||
// 1. outbox変数を最初にチェック(static関数内で優先)
|
// 1. outbox変数を最初にチェック(static関数内で優先)
|
||||||
if let Some(outbox_value) = self.outbox_vars.get(name) {
|
if let Some(outbox_value) = self.outbox_vars.get(name) {
|
||||||
eprintln!("🔍 DEBUG: Found '{}' in outbox_vars", name);
|
eprintln!("🔍 DEBUG: Found '{}' in outbox_vars", name);
|
||||||
return Ok(outbox_value.clone_box());
|
|
||||||
|
// 🔧 修正:clone_box() → Arc::clone() で参照共有
|
||||||
|
let shared_value = Arc::clone(outbox_value);
|
||||||
|
|
||||||
|
eprintln!("✅ RESOLVE_VARIABLE shared reference: {} id={}",
|
||||||
|
name, shared_value.box_id());
|
||||||
|
|
||||||
|
return Ok(shared_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. local変数をチェック
|
// 2. local変数をチェック
|
||||||
if let Some(local_value) = self.local_vars.get(name) {
|
if let Some(local_value) = self.local_vars.get(name) {
|
||||||
eprintln!("🔍 DEBUG: Found '{}' in local_vars", name);
|
eprintln!("🔍 DEBUG: Found '{}' in local_vars", name);
|
||||||
return Ok(local_value.clone_box());
|
|
||||||
|
// 🔧 修正:clone_box() → Arc::clone() で参照共有
|
||||||
|
let shared_value = Arc::clone(local_value);
|
||||||
|
|
||||||
|
eprintln!("✅ RESOLVE_VARIABLE shared reference: {} id={}",
|
||||||
|
name, shared_value.box_id());
|
||||||
|
|
||||||
|
return Ok(shared_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. GlobalBoxのフィールドをチェック
|
// 3. GlobalBoxのフィールドをチェック
|
||||||
@ -357,15 +371,17 @@ impl NyashInterpreter {
|
|||||||
|
|
||||||
/// 🔥 厳密変数設定: 明示的宣言のみ許可 - Everything is Box哲学
|
/// 🔥 厳密変数設定: 明示的宣言のみ許可 - Everything is Box哲学
|
||||||
pub(super) fn set_variable(&mut self, name: &str, value: Box<dyn NyashBox>) -> Result<(), RuntimeError> {
|
pub(super) fn set_variable(&mut self, name: &str, value: Box<dyn NyashBox>) -> Result<(), RuntimeError> {
|
||||||
|
let shared_value = Arc::from(value); // Convert Box to Arc
|
||||||
|
|
||||||
// 1. outbox変数が存在する場合は更新
|
// 1. outbox変数が存在する場合は更新
|
||||||
if self.outbox_vars.contains_key(name) {
|
if self.outbox_vars.contains_key(name) {
|
||||||
self.outbox_vars.insert(name.to_string(), value);
|
self.outbox_vars.insert(name.to_string(), shared_value);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. local変数が存在する場合は更新
|
// 2. local変数が存在する場合は更新
|
||||||
if self.local_vars.contains_key(name) {
|
if self.local_vars.contains_key(name) {
|
||||||
self.local_vars.insert(name.to_string(), value);
|
self.local_vars.insert(name.to_string(), shared_value);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -375,7 +391,7 @@ impl NyashInterpreter {
|
|||||||
if global_box.get_field(name).is_some() {
|
if global_box.get_field(name).is_some() {
|
||||||
drop(global_box); // lockを解放
|
drop(global_box); // lockを解放
|
||||||
let mut global_box = self.shared.global_box.lock().unwrap();
|
let mut global_box = self.shared.global_box.lock().unwrap();
|
||||||
global_box.set_field_dynamic(name.to_string(), value);
|
global_box.set_field_dynamic(name.to_string(), shared_value);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -391,34 +407,38 @@ impl NyashInterpreter {
|
|||||||
|
|
||||||
/// local変数を宣言(関数内でのみ有効)
|
/// local変数を宣言(関数内でのみ有効)
|
||||||
pub(super) fn declare_local_variable(&mut self, name: &str, value: Box<dyn NyashBox>) {
|
pub(super) fn declare_local_variable(&mut self, name: &str, value: Box<dyn NyashBox>) {
|
||||||
self.local_vars.insert(name.to_string(), value);
|
self.local_vars.insert(name.to_string(), Arc::from(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// outbox変数を宣言(static関数内で所有権移転)
|
/// outbox変数を宣言(static関数内で所有権移転)
|
||||||
pub(super) fn declare_outbox_variable(&mut self, name: &str, value: Box<dyn NyashBox>) {
|
pub(super) fn declare_outbox_variable(&mut self, name: &str, value: Box<dyn NyashBox>) {
|
||||||
self.outbox_vars.insert(name.to_string(), value);
|
self.outbox_vars.insert(name.to_string(), Arc::from(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// local変数スタックを保存・復元(関数呼び出し時)
|
/// local変数スタックを保存・復元(関数呼び出し時)
|
||||||
pub(super) fn save_local_vars(&self) -> HashMap<String, Box<dyn NyashBox>> {
|
pub(super) fn save_local_vars(&self) -> HashMap<String, Box<dyn NyashBox>> {
|
||||||
self.local_vars.iter()
|
self.local_vars.iter()
|
||||||
.map(|(k, v)| (k.clone(), v.clone_box()))
|
.map(|(k, v)| (k.clone(), (**v).clone_box())) // Deref Arc to get the Box
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn restore_local_vars(&mut self, saved: HashMap<String, Box<dyn NyashBox>>) {
|
pub(super) fn restore_local_vars(&mut self, saved: HashMap<String, Box<dyn NyashBox>>) {
|
||||||
self.local_vars = saved;
|
self.local_vars = saved.into_iter()
|
||||||
|
.map(|(k, v)| (k, Arc::from(v))) // Convert Box to Arc
|
||||||
|
.collect();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// outbox変数スタックを保存・復元(static関数呼び出し時)
|
/// outbox変数スタックを保存・復元(static関数呼び出し時)
|
||||||
pub(super) fn save_outbox_vars(&self) -> HashMap<String, Box<dyn NyashBox>> {
|
pub(super) fn save_outbox_vars(&self) -> HashMap<String, Box<dyn NyashBox>> {
|
||||||
self.outbox_vars.iter()
|
self.outbox_vars.iter()
|
||||||
.map(|(k, v)| (k.clone(), v.clone_box()))
|
.map(|(k, v)| (k.clone(), (**v).clone_box())) // Deref Arc to get the Box
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn restore_outbox_vars(&mut self, saved: HashMap<String, Box<dyn NyashBox>>) {
|
pub(super) fn restore_outbox_vars(&mut self, saved: HashMap<String, Box<dyn NyashBox>>) {
|
||||||
self.outbox_vars = saved;
|
self.outbox_vars = saved.into_iter()
|
||||||
|
.map(|(k, v)| (k, Arc::from(v))) // Convert Box to Arc
|
||||||
|
.collect();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// トップレベル関数をGlobalBoxのメソッドとして登録 - 🔥 暗黙オーバーライド禁止対応
|
/// トップレベル関数をGlobalBoxのメソッドとして登録 - 🔥 暗黙オーバーライド禁止対応
|
||||||
@ -453,7 +473,8 @@ impl NyashInterpreter {
|
|||||||
|
|
||||||
/// 🌍 革命的変数取得(テスト用):GlobalBoxのフィールドから取得
|
/// 🌍 革命的変数取得(テスト用):GlobalBoxのフィールドから取得
|
||||||
pub fn get_variable(&self, name: &str) -> Result<Box<dyn NyashBox>, RuntimeError> {
|
pub fn get_variable(&self, name: &str) -> Result<Box<dyn NyashBox>, RuntimeError> {
|
||||||
self.resolve_variable(name)
|
let shared_var = self.resolve_variable(name)?;
|
||||||
|
Ok((*shared_var).clone_box()) // Convert Arc back to Box for external interface
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -25,11 +25,12 @@ impl NyashInterpreter {
|
|||||||
|
|
||||||
ASTNode::Variable { name, .. } => {
|
ASTNode::Variable { name, .. } => {
|
||||||
// 🌍 革命的変数解決:local変数 → GlobalBoxフィールド → エラー
|
// 🌍 革命的変数解決:local変数 → GlobalBoxフィールド → エラー
|
||||||
self.resolve_variable(name)
|
let shared_var = self.resolve_variable(name)
|
||||||
.map_err(|_| RuntimeError::UndefinedVariableAt {
|
.map_err(|_| RuntimeError::UndefinedVariableAt {
|
||||||
name: name.clone(),
|
name: name.clone(),
|
||||||
span: expression.span()
|
span: expression.span()
|
||||||
})
|
})?;
|
||||||
|
Ok((*shared_var).clone_box()) // Convert for external interface
|
||||||
}
|
}
|
||||||
|
|
||||||
ASTNode::BinaryOp { operator, left, right, .. } => {
|
ASTNode::BinaryOp { operator, left, right, .. } => {
|
||||||
@ -702,6 +703,8 @@ impl NyashInterpreter {
|
|||||||
message: format!("Field '{}' not found in {}", field, instance.class_name),
|
message: format!("Field '{}' not found in {}", field, instance.class_name),
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
eprintln!("✅ FIELD ACCESS: Returning shared reference id={}", field_value.box_id());
|
||||||
|
|
||||||
// 🔗 Weak Reference Check: Use unified accessor for weak fields
|
// 🔗 Weak Reference Check: Use unified accessor for weak fields
|
||||||
let box_decls = self.shared.box_declarations.read().unwrap();
|
let box_decls = self.shared.box_declarations.read().unwrap();
|
||||||
if let Some(box_decl) = box_decls.get(&instance.class_name) {
|
if let Some(box_decl) = box_decls.get(&instance.class_name) {
|
||||||
@ -731,8 +734,8 @@ impl NyashInterpreter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Normal field access for now
|
// Normal field access - convert Arc back to Box for compatibility
|
||||||
Ok(field_value)
|
Ok((*field_value).clone_box())
|
||||||
} else {
|
} else {
|
||||||
Err(RuntimeError::TypeError {
|
Err(RuntimeError::TypeError {
|
||||||
message: format!("Cannot access field '{}' on non-instance type. Type: {}", field, obj_value.type_name()),
|
message: format!("Cannot access field '{}' on non-instance type. Type: {}", field, obj_value.type_name()),
|
||||||
|
|||||||
Reference in New Issue
Block a user