1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-28 05:05:08 +00:00

LibJS: Add MarkedValueList and use it for argument passing

A MarkedValueList is basically a Vector<JS::Value> that registers with
the Heap and makes sure that the stored values don't get GC'd.

Before this change, we were unsafely keeping Vector<JS::Value> in some
places, which is out-of-reach for the live reference finding logic
since Vector puts its elements on the heap by default.

We now pass all the JavaScript tests even when running with "js -g",
which does a GC on every heap allocation.
This commit is contained in:
Andreas Kling 2020-04-19 17:24:56 +02:00
parent cb3cf589ed
commit f7a1696087
13 changed files with 178 additions and 16 deletions

View file

@ -33,6 +33,7 @@
#include <LibJS/Runtime/Array.h>
#include <LibJS/Runtime/Error.h>
#include <LibJS/Runtime/GlobalObject.h>
#include <LibJS/Runtime/MarkedValueList.h>
#include <LibJS/Runtime/NativeFunction.h>
#include <LibJS/Runtime/PrimitiveString.h>
#include <LibJS/Runtime/ScriptFunction.h>
@ -112,8 +113,7 @@ Value CallExpression::execute(Interpreter& interpreter) const
auto& function = static_cast<Function&>(callee.as_object());
Vector<Value> arguments;
arguments.ensure_capacity(m_arguments.size());
MarkedValueList arguments(interpreter.heap());
for (size_t i = 0; i < m_arguments.size(); ++i) {
auto value = m_arguments[i].execute(interpreter);
if (interpreter.exception())
@ -125,7 +125,7 @@ Value CallExpression::execute(Interpreter& interpreter) const
auto& call_frame = interpreter.push_call_frame();
call_frame.function_name = function.name();
call_frame.arguments = move(arguments);
call_frame.arguments = arguments.values();
call_frame.environment = function.create_environment();
Object* new_object = nullptr;