1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 05:07:34 +00:00

LibJS: Make super() in catch block work

The TryStatement handler execution creates a new LexicalEnvironment
without a current function set, which we were not accounting for when
trying to get the super constructor while executing a SuperExpression.
This makes it work but isn't pretty - this needs some refactoring to be
close to the spec for that to happen.

Fixes #7045.
This commit is contained in:
Linus Groh 2021-05-11 23:31:30 +01:00
parent d85b9fd5a0
commit 0a329d2d70
2 changed files with 30 additions and 2 deletions

View file

@ -220,7 +220,14 @@ Value CallExpression::execute(Interpreter& interpreter, GlobalObject& global_obj
if (result.is_object())
new_object = &result.as_object();
} else if (is<SuperExpression>(*m_callee)) {
auto* super_constructor = interpreter.current_environment()->current_function()->prototype();
// FIXME: This is merely a band-aid to make super() inside catch {} work (which constructs
// a new LexicalEnvironment without current function). Implement GetSuperConstructor()
// and subsequently GetThisEnvironment() instead.
auto* function_environment = interpreter.current_environment();
if (!function_environment->current_function())
function_environment = static_cast<LexicalEnvironment*>(function_environment->parent());
auto* super_constructor = function_environment->current_function()->prototype();
// FIXME: Functions should track their constructor kind.
if (!super_constructor || !super_constructor->is_function()) {
vm.throw_exception<TypeError>(global_object, ErrorType::NotAConstructor, "Super constructor");
@ -230,7 +237,7 @@ Value CallExpression::execute(Interpreter& interpreter, GlobalObject& global_obj
if (vm.exception())
return {};
interpreter.current_environment()->bind_this_value(global_object, result);
function_environment->bind_this_value(global_object, result);
} else {
result = vm.call(function, this_value, move(arguments));
}