summaryrefslogtreecommitdiff
path: root/Userland/Libraries
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2021-07-02 14:24:50 +0200
committerAndreas Kling <kling@serenityos.org>2021-07-02 17:54:34 +0200
commitbad1acf137c03ef6f808632308e75400154f92f1 (patch)
treeceaaa55572a0d8f35a36c25a16c6939974fd4aaa /Userland/Libraries
parent05e8bea73684acfadb1c1b41dd839e865c43df8d (diff)
downloadserenity-bad1acf137c03ef6f808632308e75400154f92f1.zip
LibJS: Break out ArgumentListEvaluation AO from CallExpression
Diffstat (limited to 'Userland/Libraries')
-rw-r--r--Userland/Libraries/LibJS/AST.cpp57
1 files changed, 33 insertions, 24 deletions
diff --git a/Userland/Libraries/LibJS/AST.cpp b/Userland/Libraries/LibJS/AST.cpp
index 66d90aa2bf..15ff3b8e33 100644
--- a/Userland/Libraries/LibJS/AST.cpp
+++ b/Userland/Libraries/LibJS/AST.cpp
@@ -167,6 +167,31 @@ CallExpression::ThisAndCallee CallExpression::compute_this_and_callee(Interprete
return { &global_object, m_callee->execute(interpreter, global_object) };
}
+// 13.3.8.1 Runtime Semantics: ArgumentListEvaluation, https://tc39.es/ecma262/#sec-runtime-semantics-argumentlistevaluation
+static void argument_list_evaluation(Interpreter& interpreter, GlobalObject& global_object, Vector<CallExpression::Argument> const& arguments, MarkedValueList& list)
+{
+ auto& vm = global_object.vm();
+ list.ensure_capacity(arguments.size());
+
+ for (auto& argument : arguments) {
+ auto value = argument.value->execute(interpreter, global_object);
+ if (vm.exception())
+ return;
+ if (argument.is_spread) {
+ get_iterator_values(global_object, value, [&](Value iterator_value) {
+ if (vm.exception())
+ return IterationDecision::Break;
+ list.append(iterator_value);
+ return IterationDecision::Continue;
+ });
+ if (vm.exception())
+ return;
+ } else {
+ list.append(value);
+ }
+ }
+}
+
Value CallExpression::execute(Interpreter& interpreter, GlobalObject& global_object) const
{
InterpreterNodeScope node_scope { interpreter, *this };
@@ -197,29 +222,13 @@ Value CallExpression::execute(Interpreter& interpreter, GlobalObject& global_obj
auto& function = callee.as_function();
- MarkedValueList arguments(vm.heap());
- arguments.ensure_capacity(m_arguments.size());
-
- for (auto& argument : m_arguments) {
- auto value = argument.value->execute(interpreter, global_object);
- if (vm.exception())
- return {};
- if (argument.is_spread) {
- get_iterator_values(global_object, value, [&](Value iterator_value) {
- if (vm.exception())
- return IterationDecision::Break;
- arguments.append(iterator_value);
- return IterationDecision::Continue;
- });
- if (vm.exception())
- return {};
- } else {
- arguments.append(value);
- }
- }
+ MarkedValueList arg_list(vm.heap());
+ argument_list_evaluation(interpreter, global_object, m_arguments, arg_list);
+ if (interpreter.exception())
+ return {};
if (!is<NewExpression>(*this) && is<Identifier>(*m_callee) && static_cast<Identifier const&>(*m_callee).string() == vm.names.eval.as_string() && &callee.as_function() == global_object.eval_function()) {
- auto script_value = arguments.size() == 0 ? js_undefined() : arguments[0];
+ auto script_value = arg_list.size() == 0 ? js_undefined() : arg_list[0];
return perform_eval(script_value, global_object, vm.in_strict_mode() ? CallerMode::Strict : CallerMode::NonStrict, EvalMode::Direct);
}
@@ -227,7 +236,7 @@ Value CallExpression::execute(Interpreter& interpreter, GlobalObject& global_obj
Object* new_object = nullptr;
Value result;
if (is<NewExpression>(*this)) {
- result = vm.construct(function, function, move(arguments));
+ result = vm.construct(function, function, move(arg_list));
if (result.is_object())
new_object = &result.as_object();
} else if (is<SuperExpression>(*m_callee)) {
@@ -237,14 +246,14 @@ Value CallExpression::execute(Interpreter& interpreter, GlobalObject& global_obj
vm.throw_exception<TypeError>(global_object, ErrorType::NotAConstructor, "Super constructor");
return {};
}
- result = vm.construct(static_cast<FunctionObject&>(*super_constructor), function, move(arguments));
+ result = vm.construct(static_cast<FunctionObject&>(*super_constructor), function, move(arg_list));
if (vm.exception())
return {};
auto& this_er = get_this_environment(interpreter.vm());
verify_cast<FunctionEnvironment>(this_er).bind_this_value(global_object, result);
} else {
- result = vm.call(function, this_value, move(arguments));
+ result = vm.call(function, this_value, move(arg_list));
}
if (vm.exception())