summaryrefslogtreecommitdiff
path: root/Libraries/LibJS/AST.cpp
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2020-03-17 11:00:09 +0100
committerAndreas Kling <kling@serenityos.org>2020-03-17 11:06:00 +0100
commitbf9912cc59327904ac7023f0aac31dbccc84d8de (patch)
tree37847b9dc06c7c518ee2a3c9b1f231b0fda415aa /Libraries/LibJS/AST.cpp
parent666f84b9339a9a646d3cd8316f4be038a6171cbc (diff)
downloadserenity-bf9912cc59327904ac7023f0aac31dbccc84d8de.zip
LibJS: Protect function call "this" and arguments from GC
This patch adds a CallFrame stack to Interpreter, which keeps track of the "this" value and all argument values passed in function calls. Interpreter::gather_roots() scans the call stack, making sure that all argument values get marked. :^)
Diffstat (limited to 'Libraries/LibJS/AST.cpp')
-rw-r--r--Libraries/LibJS/AST.cpp16
1 files changed, 5 insertions, 11 deletions
diff --git a/Libraries/LibJS/AST.cpp b/Libraries/LibJS/AST.cpp
index fb7993aea7..d1e9d53828 100644
--- a/Libraries/LibJS/AST.cpp
+++ b/Libraries/LibJS/AST.cpp
@@ -59,21 +59,15 @@ Value CallExpression::execute(Interpreter& interpreter) const
ASSERT(callee.as_object()->is_function());
auto* function = static_cast<Function*>(callee.as_object());
- Vector<Value> argument_values;
+ auto& call_frame = interpreter.push_call_frame();
for (size_t i = 0; i < m_arguments.size(); ++i)
- argument_values.append(m_arguments[i].execute(interpreter));
+ call_frame.arguments.append(m_arguments[i].execute(interpreter));
- Value this_value = js_undefined();
if (m_callee->is_member_expression())
- this_value = static_cast<const MemberExpression&>(*m_callee).object().execute(interpreter).to_object(interpreter.heap());
+ call_frame.this_value = static_cast<const MemberExpression&>(*m_callee).object().execute(interpreter).to_object(interpreter.heap());
- if (!this_value.is_undefined())
- interpreter.push_this_value(this_value);
-
- auto result = function->call(interpreter, move(argument_values));
-
- if (!this_value.is_undefined())
- interpreter.pop_this_value();
+ auto result = function->call(interpreter, call_frame.arguments);
+ interpreter.pop_call_frame();
return result;
}