diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-08-08 03:24:27 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-08-08 03:25:02 +0900 |
| commit | b4f16a379e919eefc2cb37bcddee589c0f26eaad (patch) | |
| tree | fcd970b83deb89a04fb5daf2c107d6f75b34e0f2 | |
| parent | da0d38a8e16ebefd59ef5291b5788e6238cc78ba (diff) | |
| download | php-shirabe-b4f16a379e919eefc2cb37bcddee589c0f26eaad.tar.gz php-shirabe-b4f16a379e919eefc2cb37bcddee589c0f26eaad.tar.zst php-shirabe-b4f16a379e919eefc2cb37bcddee589c0f26eaad.zip | |
refactor(php-shim): dispatch spl_object_hash on Rc and references
Getting a rule's identity meant spl_object_hash(&*rule.borrow()), so the
solver borrowed a RefCell just to read an address, and a second function
spl_object_hash_process existed because one generic fn cannot tell Rc<T>
from &T.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
4 files changed, 23 insertions, 15 deletions
diff --git a/crates/shirabe-external-packages/src/symfony/console/helper/process_helper.rs b/crates/shirabe-external-packages/src/symfony/console/helper/process_helper.rs index 58d1ea3f..312d8e15 100644 --- a/crates/shirabe-external-packages/src/symfony/console/helper/process_helper.rs +++ b/crates/shirabe-external-packages/src/symfony/console/helper/process_helper.rs @@ -116,7 +116,7 @@ impl ProcessHelper { if verbosity <= output.borrow().get_verbosity() { let started = Self::formatter_start( &formatter, - &shirabe_php_shim::spl_object_hash_process(&process), + &shirabe_php_shim::spl_object_hash(&process), &self.escape_string(&process.get_command_line()), ); output @@ -163,7 +163,7 @@ impl ProcessHelper { }; let stopped = Self::formatter_stop( &formatter, - &shirabe_php_shim::spl_object_hash_process(&process), + &shirabe_php_shim::spl_object_hash(&process), &message, process.is_successful(), ); @@ -242,7 +242,7 @@ impl ProcessHelper { .borrow() .get_debug_formatter(); - let object_hash = shirabe_php_shim::spl_object_hash_process(process); + let object_hash = shirabe_php_shim::spl_object_hash(process); Box::new(move |r#type: &str, buffer: &str| { let progressed = Self::formatter_progress( diff --git a/crates/shirabe-php-shim/src/runtime.rs b/crates/shirabe-php-shim/src/runtime.rs index a059a59d..591c7260 100644 --- a/crates/shirabe-php-shim/src/runtime.rs +++ b/crates/shirabe-php-shim/src/runtime.rs @@ -315,16 +315,24 @@ pub fn version_compare_ordering(v1: &str, v2: &str) -> std::cmp::Ordering { // Paired with set_error_handler, which is a no-op in this shim. pub fn restore_error_handler() {} -pub fn spl_object_hash<T: ?Sized>(_object: &T) -> String { - // PHP returns a unique 32-char hex id per object instance; the object's address serves as the - // identity here. - // TODO(phase-c): as in PHP, an address can be reused after an object is freed, so uniqueness is - // not guaranteed across an object's whole lifetime without an object store. - format!("{:032x}", _object as *const T as *const u8 as usize) +pub trait HasAddress { + fn address(&self) -> usize; } -pub fn spl_object_hash_process<T>(_object: &T) -> String { - format!("{:032x}", _object as *const T as usize) +impl<T: ?Sized> HasAddress for &T { + fn address(&self) -> usize { + *self as *const T as *const u8 as usize + } +} + +impl<T: ?Sized> HasAddress for std::rc::Rc<T> { + fn address(&self) -> usize { + std::rc::Rc::as_ptr(self) as *const u8 as usize + } +} + +pub fn spl_object_hash<T: HasAddress>(object: T) -> String { + format!("{:032x}", object.address()) } // TODO(phase-c): the Windows branch of php_uname is missing. There PHP reports "Windows NT" as the diff --git a/crates/shirabe/src/dependency_resolver/problem.rs b/crates/shirabe/src/dependency_resolver/problem.rs index f9e525bf..3c69babe 100644 --- a/crates/shirabe/src/dependency_resolver/problem.rs +++ b/crates/shirabe/src/dependency_resolver/problem.rs @@ -50,7 +50,7 @@ impl Problem { /// Add a rule as a reason pub fn add_rule(&mut self, rule: std::rc::Rc<std::cell::RefCell<Rule>>) { - let id = spl_object_hash(&*rule.borrow()); + let id = spl_object_hash(rule.clone()); self.add_reason(id, rule); } diff --git a/crates/shirabe/src/dependency_resolver/solver.rs b/crates/shirabe/src/dependency_resolver/solver.rs index 09a51ef8..dd5bd383 100644 --- a/crates/shirabe/src/dependency_resolver/solver.rs +++ b/crates/shirabe/src/dependency_resolver/solver.rs @@ -397,7 +397,7 @@ impl Solver { self.rules.add(new_rule.clone(), RuleSet::TYPE_LEARNED)?; self.learned_why - .insert(spl_object_hash(&*new_rule.borrow()), why); + .insert(spl_object_hash(new_rule.clone()), why); let rule_node = std::rc::Rc::new(std::cell::RefCell::new(RuleWatchNode::new( new_rule.clone(), @@ -610,7 +610,7 @@ impl Solver { conflict_rule: std::rc::Rc<std::cell::RefCell<Rule>>, rule_seen: &mut IndexMap<String, bool>, ) { - let why = spl_object_hash(&*conflict_rule.borrow()); + let why = spl_object_hash(conflict_rule.clone()); rule_seen.insert(why.clone(), true); if conflict_rule.borrow().get_type() == RuleSet::TYPE_LEARNED { @@ -618,7 +618,7 @@ impl Solver { let problem_rules = self.learned_pool[learned_why as usize].clone(); for problem_rule in problem_rules { - if !rule_seen.contains_key(&spl_object_hash(&*problem_rule.borrow())) { + if !rule_seen.contains_key(&spl_object_hash(problem_rule.clone())) { self.analyze_unsolvable_rule(problem, problem_rule, rule_seen); } } |
