@@ -114,28 +114,35 @@ bool UnitUnified::add(Component& u, SPIClass& spi, const SPISettings& settings)
114114 return false ;
115115}
116116
117- // Add children if exists
117+ // Add children if exists (iterative to avoid stack overflow)
118118bool UnitUnified::add_children (Component& u)
119119{
120- auto it = u.childBegin ();
121- while (it != u.childEnd ()) {
122- auto ch = it->channel ();
123-
124- M5_LIB_LOGV (" %s child:%s channel:%u" , u.deviceName (), it->deviceName (), ch);
125- if (it->isRegistered ()) {
126- M5_LIB_LOGE (" Already registered %s" , it->deviceName ());
127- return false ;
120+ std::vector<Component*> stack;
121+ stack.reserve (8 );
122+ stack.push_back (&u);
123+
124+ while (!stack.empty ()) {
125+ Component* parent = stack.back ();
126+ stack.pop_back ();
127+
128+ for (auto it = parent->childBegin (); it != parent->childEnd (); ++it) {
129+ auto ch = it->channel ();
130+
131+ M5_LIB_LOGV (" %s child:%s channel:%u" , parent->deviceName (), it->deviceName (), ch);
132+ if (it->isRegistered ()) {
133+ M5_LIB_LOGE (" Already registered %s" , it->deviceName ());
134+ return false ;
135+ }
136+ it->_manager = this ;
137+ it->_adapter = parent->ensure_adapter (ch);
138+ M5_LIB_LOGD (" Shared:%u %u" , parent->_adapter .use_count (), it->_adapter .use_count ());
139+ it->_order = ++_registerCount;
140+ _units.emplace_back (&*it);
141+
142+ if (it->hasChildren ()) {
143+ stack.push_back (&*it);
144+ }
128145 }
129- it->_manager = this ;
130- it->_adapter = u.ensure_adapter (ch);
131- M5_LIB_LOGD (" Shared:%u %u" , u._adapter .use_count (), it->_adapter .use_count ());
132- it->_order = ++_registerCount;
133- _units.emplace_back (&*it);
134-
135- if (!add_children (*it)) {
136- return false ;
137- }
138- ++it;
139146 }
140147 return true ;
141148}
@@ -175,13 +182,33 @@ std::string UnitUnified::debugInfo() const
175182
176183std::string UnitUnified::make_unit_info (const Component* u, const uint8_t indent) const
177184{
178- std::string s = m5::utility::formatString (" %*c%s\n " , indent * 4 , ' ' , u->debugInfo ().c_str ());
179-
180- if (u->hasChildren ()) {
181- s += make_unit_info (u->_child , indent + 1 );
185+ std::string s;
186+ s.reserve (256 );
187+
188+ struct StackEntry {
189+ const Component* node;
190+ uint8_t indent;
191+ };
192+ std::vector<StackEntry> stack;
193+ stack.reserve (16 );
194+ stack.push_back ({u, indent});
195+
196+ while (!stack.empty ()) {
197+ auto entry = stack.back ();
198+ stack.pop_back ();
199+
200+ s += m5::utility::formatString (" %*c%s\n " , entry.indent * 4 , ' ' , entry.node ->debugInfo ().c_str ());
201+
202+ // Push sibling first (processed later = output later)
203+ if (entry.node ->_next ) {
204+ stack.push_back ({entry.node ->_next , entry.indent });
205+ }
206+ // Push child second (processed first = output first)
207+ if (entry.node ->hasChildren ()) {
208+ stack.push_back ({entry.node ->_child , static_cast <uint8_t >(entry.indent + 1 )});
209+ }
182210 }
183- u = u->_next ;
184- return u ? s += make_unit_info (u, indent) : s;
211+ return s;
185212}
186213
187214} // namespace unit
0 commit comments