mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 20:57:35 +00:00
LibJS/Bytecode: Add support for direct eval()
This is implemented as a special mode of the Call opcode that invokes the PerformEval AO (instead of the Call or Construct AO).
This commit is contained in:
parent
8a3e350321
commit
2ac8a4bbb7
3 changed files with 25 additions and 4 deletions
|
@ -1379,6 +1379,8 @@ Bytecode::CodeGenerationErrorOr<void> CallExpression::generate_bytecode(Bytecode
|
|||
Bytecode::Op::Call::CallType call_type;
|
||||
if (is<NewExpression>(*this)) {
|
||||
call_type = Bytecode::Op::Call::CallType::Construct;
|
||||
} else if (m_callee->is_identifier() && static_cast<Identifier const&>(*m_callee).string() == "eval"sv) {
|
||||
call_type = Bytecode::Op::Call::CallType::DirectEval;
|
||||
} else {
|
||||
call_type = Bytecode::Op::Call::CallType::Call;
|
||||
}
|
||||
|
|
|
@ -661,7 +661,12 @@ ThrowCompletionOr<void> Call::execute_impl(Bytecode::Interpreter& interpreter) c
|
|||
auto argument_values = argument_list_evaluation(interpreter);
|
||||
|
||||
Value return_value;
|
||||
if (m_type == CallType::Call)
|
||||
if (m_type == CallType::DirectEval) {
|
||||
if (callee == interpreter.realm().intrinsics().eval_function())
|
||||
return_value = TRY(perform_eval(vm, argument_values[0].value_or(JS::js_undefined()), vm.in_strict_mode() ? CallerMode::Strict : CallerMode::NonStrict, EvalMode::Direct));
|
||||
else
|
||||
return_value = TRY(call(vm, function, this_value, move(argument_values)));
|
||||
} else if (m_type == CallType::Call)
|
||||
return_value = TRY(call(vm, function, this_value, move(argument_values)));
|
||||
else
|
||||
return_value = TRY(construct(vm, function, move(argument_values)));
|
||||
|
@ -1239,10 +1244,23 @@ DeprecatedString JumpUndefined::to_deprecated_string_impl(Bytecode::Executable c
|
|||
|
||||
DeprecatedString Call::to_deprecated_string_impl(Bytecode::Executable const& executable) const
|
||||
{
|
||||
if (m_expression_string.has_value())
|
||||
return DeprecatedString::formatted("Call callee:{}, this:{}, arguments:[...acc] ({})", m_callee, m_this_value, executable.get_string(m_expression_string.value()));
|
||||
StringView type;
|
||||
switch (m_type) {
|
||||
case Call::CallType::Call:
|
||||
type = ""sv;
|
||||
break;
|
||||
case Call::CallType::Construct:
|
||||
type = " (Construct)"sv;
|
||||
break;
|
||||
case Call::CallType::DirectEval:
|
||||
type = " (DirectEval)"sv;
|
||||
break;
|
||||
}
|
||||
|
||||
return DeprecatedString::formatted("Call callee:{}, this:{}, arguments:[...acc]", m_callee, m_this_value);
|
||||
if (m_expression_string.has_value())
|
||||
return DeprecatedString::formatted("Call{} callee:{}, this:{}, arguments:[...acc] ({})", type, m_callee, m_this_value, executable.get_string(m_expression_string.value()));
|
||||
|
||||
return DeprecatedString::formatted("Call{} callee:{}, this:{}, arguments:[...acc]", type, m_callee, m_this_value);
|
||||
}
|
||||
|
||||
DeprecatedString SuperCall::to_deprecated_string_impl(Bytecode::Executable const&) const
|
||||
|
|
|
@ -714,6 +714,7 @@ public:
|
|||
enum class CallType {
|
||||
Call,
|
||||
Construct,
|
||||
DirectEval,
|
||||
};
|
||||
|
||||
Call(CallType type, Register callee, Register this_value, Optional<StringTableIndex> expression_string = {})
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue