From b56ecc7e349cddd4acae8b4bc10c22b6e016eb1b Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Fri, 20 Oct 2023 13:20:28 +0200 Subject: [PATCH] LibJS/Bytecode: Move perform_call helper to CommonImplementations --- .../LibJS/Bytecode/CommonImplementations.cpp | 23 ++++++++++++++++ .../LibJS/Bytecode/CommonImplementations.h | 2 ++ .../Libraries/LibJS/Bytecode/Interpreter.cpp | 26 +++---------------- 3 files changed, 29 insertions(+), 22 deletions(-) diff --git a/Userland/Libraries/LibJS/Bytecode/CommonImplementations.cpp b/Userland/Libraries/LibJS/Bytecode/CommonImplementations.cpp index 00359a01b30..446c179cf8a 100644 --- a/Userland/Libraries/LibJS/Bytecode/CommonImplementations.cpp +++ b/Userland/Libraries/LibJS/Bytecode/CommonImplementations.cpp @@ -184,4 +184,27 @@ ThrowCompletionOr put_by_property_key(VM& vm, Value base, Value this_value return {}; } +template +ThrowCompletionOr perform_call(Interpreter& interpreter, InstructionType const& call, Value callee, MarkedVector argument_values) +{ + auto& vm = interpreter.vm(); + auto this_value = interpreter.reg(call.this_value()); + auto& function = callee.as_function(); + Value return_value; + if (call.call_type() == Op::CallType::DirectEval) { + if (callee == interpreter.realm().intrinsics().eval_function()) + return_value = TRY(perform_eval(vm, !argument_values.is_empty() ? argument_values[0].value_or(JS::js_undefined()) : js_undefined(), vm.in_strict_mode() ? CallerMode::Strict : CallerMode::NonStrict, EvalMode::Direct)); + else + return_value = TRY(JS::call(vm, function, this_value, move(argument_values))); + } else if (call.call_type() == Op::CallType::Call) + return_value = TRY(JS::call(vm, function, this_value, move(argument_values))); + else + return_value = TRY(construct(vm, function, move(argument_values))); + + return return_value; +} + +template ThrowCompletionOr perform_call(Interpreter&, Op::Call const&, Value, MarkedVector); +template ThrowCompletionOr perform_call(Interpreter&, Op::CallWithArgumentArray const&, Value, MarkedVector); + } diff --git a/Userland/Libraries/LibJS/Bytecode/CommonImplementations.h b/Userland/Libraries/LibJS/Bytecode/CommonImplementations.h index 81edbbb8c7b..cf3a2debbe1 100644 --- a/Userland/Libraries/LibJS/Bytecode/CommonImplementations.h +++ b/Userland/Libraries/LibJS/Bytecode/CommonImplementations.h @@ -17,5 +17,7 @@ ThrowCompletionOr get_by_id(Bytecode::Interpreter&, IdentifierTableIndex, ThrowCompletionOr get_by_value(Bytecode::Interpreter&, Value base_value, Value property_key_value); ThrowCompletionOr get_global(Bytecode::Interpreter&, IdentifierTableIndex, u32 cache_index); ThrowCompletionOr put_by_property_key(VM&, Value base, Value this_value, Value value, PropertyKey name, Op::PropertyKind kind); +template +ThrowCompletionOr perform_call(Interpreter&, InstructionType const&, Value callee, MarkedVector argument_values); } diff --git a/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp b/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp index 5a0417160a7..f0e1e7a8158 100644 --- a/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp @@ -1155,26 +1155,6 @@ static ThrowCompletionOr throw_if_needed_for_call(Interpreter& interpreter return {}; } -static ThrowCompletionOr perform_call(Interpreter& interpreter, auto& call, Value callee, MarkedVector argument_values) -{ - auto& vm = interpreter.vm(); - auto this_value = interpreter.reg(call.this_value()); - auto& function = callee.as_function(); - Value return_value; - if (call.call_type() == CallType::DirectEval) { - if (callee == interpreter.realm().intrinsics().eval_function()) - return_value = TRY(perform_eval(vm, !argument_values.is_empty() ? argument_values[0].value_or(JS::js_undefined()) : js_undefined(), vm.in_strict_mode() ? CallerMode::Strict : CallerMode::NonStrict, EvalMode::Direct)); - else - return_value = TRY(JS::call(vm, function, this_value, move(argument_values))); - } else if (call.call_type() == CallType::Call) - return_value = TRY(JS::call(vm, function, this_value, move(argument_values))); - else - return_value = TRY(construct(vm, function, move(argument_values))); - - interpreter.accumulator() = return_value; - return {}; -} - ThrowCompletionOr Call::execute_impl(Bytecode::Interpreter& interpreter) const { auto& vm = interpreter.vm(); @@ -1187,7 +1167,8 @@ ThrowCompletionOr Call::execute_impl(Bytecode::Interpreter& interpreter) c for (u32 i = 0; i < m_argument_count; ++i) { argument_values.unchecked_append(interpreter.reg(Register { m_first_argument.index() + i })); } - return perform_call(interpreter, *this, callee, move(argument_values)); + interpreter.accumulator() = TRY(perform_call(interpreter, *this, callee, move(argument_values))); + return {}; } ThrowCompletionOr CallWithArgumentArray::execute_impl(Bytecode::Interpreter& interpreter) const @@ -1195,7 +1176,8 @@ ThrowCompletionOr CallWithArgumentArray::execute_impl(Bytecode::Interprete auto callee = interpreter.reg(m_callee); TRY(throw_if_needed_for_call(interpreter, *this, callee)); auto argument_values = argument_list_evaluation(interpreter); - return perform_call(interpreter, *this, callee, move(argument_values)); + interpreter.accumulator() = TRY(perform_call(interpreter, *this, callee, move(argument_values))); + return {}; } // 13.3.7.1 Runtime Semantics: Evaluation, https://tc39.es/ecma262/#sec-super-keyword-runtime-semantics-evaluation