1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 19:37:35 +00:00

LibJS: Use regular stack for VM call frames instead of Vector storage

Keeping the VM call frames in a Vector could cause them to move around
underneath us due to Vector resizing. Avoid this issue by allocating
CallFrame objects on the stack and having the VM simply keep a list
of pointers to each CallFrame, instead of the CallFrames themselves.

Fixes #3830.
Fixes #3951.
This commit is contained in:
Andreas Kling 2020-11-07 11:07:17 +01:00
parent a950d3dd5f
commit 43ff2ea8d8
6 changed files with 36 additions and 27 deletions

View file

@ -114,19 +114,20 @@ public:
return *m_single_ascii_character_strings[character];
}
CallFrame& push_call_frame(bool strict_mode = false)
void push_call_frame(CallFrame& call_frame)
{
m_call_stack.append({ {}, js_undefined(), {}, nullptr, strict_mode });
return m_call_stack.last();
m_call_stack.append(&call_frame);
}
void pop_call_frame() { m_call_stack.take_last(); }
CallFrame& call_frame() { return m_call_stack.last(); }
const CallFrame& call_frame() const { return m_call_stack.last(); }
const Vector<CallFrame>& call_stack() const { return m_call_stack; }
Vector<CallFrame>& call_stack() { return m_call_stack; }
const LexicalEnvironment* current_environment() const { return m_call_stack.last().environment; }
LexicalEnvironment* current_environment() { return m_call_stack.last().environment; }
void pop_call_frame() { m_call_stack.take_last(); }
CallFrame& call_frame() { return *m_call_stack.last(); }
const CallFrame& call_frame() const { return *m_call_stack.last(); }
const Vector<CallFrame*>& call_stack() const { return m_call_stack; }
Vector<CallFrame*>& call_stack() { return m_call_stack; }
const LexicalEnvironment* current_environment() const { return call_frame().environment; }
LexicalEnvironment* current_environment() { return call_frame().environment; }
bool in_strict_mode() const;
@ -135,7 +136,7 @@ public:
{
if (m_call_stack.is_empty())
return;
for (auto& value : m_call_stack.last().arguments)
for (auto& value : call_frame().arguments)
callback(value);
}
@ -143,14 +144,14 @@ public:
{
if (m_call_stack.is_empty())
return 0;
return m_call_stack.last().arguments.size();
return call_frame().arguments.size();
}
Value argument(size_t index) const
{
if (m_call_stack.is_empty())
return {};
auto& arguments = m_call_stack.last().arguments;
auto& arguments = call_frame().arguments;
return index < arguments.size() ? arguments[index] : js_undefined();
}
@ -158,7 +159,7 @@ public:
{
if (m_call_stack.is_empty())
return &global_object;
return m_call_stack.last().this_value;
return call_frame().this_value;
}
Value last_value() const { return m_last_value; }
@ -241,7 +242,7 @@ private:
Heap m_heap;
Vector<Interpreter*> m_interpreters;
Vector<CallFrame> m_call_stack;
Vector<CallFrame*> m_call_stack;
Value m_last_value;
ScopeType m_unwind_until { ScopeType::None };