Shell: Store LocalFrames as NonnullOwnPtr<LocalFrame> instead

As Vector<T> will relocate objects to resize, we cannot assume that the
address of a specific LocalFrame will stay constant, or that the
reference will not be dangling to begin with.
Fixes an assertion that fires when a frame push causes the Vector to
reallocate.
This commit is contained in:
AnotherTest 2020-11-01 13:28:11 +03:30 committed by Andreas Kling
parent a7f4f6afc3
commit bedad383b5
Notes: sideshowbarker 2024-07-19 01:36:05 +09:00
3 changed files with 28 additions and 12 deletions

View file

@ -463,7 +463,7 @@ bool Shell::invoke_function(const AST::Command& command, int& retval)
return true;
}
auto frame = push_frame();
auto frame = push_frame(String::formatted("function {}", function.name));
size_t index = 0;
for (auto& arg : function.arguments) {
++index;
@ -489,9 +489,12 @@ String Shell::format(const StringView& source, ssize_t& cursor) const
return result;
}
Shell::Frame Shell::push_frame()
Shell::Frame Shell::push_frame(String name)
{
m_local_frames.empend();
m_local_frames.append(make<LocalFrame>(name, decltype(LocalFrame::local_variables) {}));
#ifdef SH_DEBUG
dbg() << "New frame '" << name << "' at " << &m_local_frames.last();
#endif
return { m_local_frames, m_local_frames.last() };
}
@ -505,7 +508,12 @@ Shell::Frame::~Frame()
{
if (!should_destroy_frame)
return;
ASSERT(&frames.last() == &frame);
if (&frames.last() != &frame) {
dbg() << "Frame destruction order violation near " << &frame << " (container = " << this << ") '" << frame.name << "'; current frames:";
for (auto& frame : frames)
dbg() << "- " << &frame << ": " << frame.name;
ASSERT_NOT_REACHED();
}
frames.take_last();
}
@ -1504,7 +1512,7 @@ void Shell::notify_child_event()
Shell::Shell()
: m_default_constructed(true)
{
push_frame().leak_frame();
push_frame("main").leak_frame();
int rc = gethostname(hostname, Shell::HostNameSize);
if (rc < 0)
@ -1544,7 +1552,7 @@ Shell::Shell(Line::Editor& editor)
tcsetpgrp(0, getpgrp());
m_pid = getpid();
push_frame().leak_frame();
push_frame("main").leak_frame();
int rc = gethostname(hostname, Shell::HostNameSize);
if (rc < 0)