mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 02:07:35 +00:00
LibJS: Use references in CallExpression::compute_this_and_callee()
This has the nice side effect of giving us a decent error message for something like undefined.foo() - another useless "ToObject on null or undefined" gone. :^) Also turn the various ternary operators into two separate if branches, they don't really share that much.
This commit is contained in:
parent
94bc886593
commit
726d631527
1 changed files with 27 additions and 14 deletions
|
@ -147,22 +147,35 @@ CallExpression::ThisAndCallee CallExpression::compute_this_and_callee(Interprete
|
||||||
|
|
||||||
if (is<MemberExpression>(*m_callee)) {
|
if (is<MemberExpression>(*m_callee)) {
|
||||||
auto& member_expression = static_cast<const MemberExpression&>(*m_callee);
|
auto& member_expression = static_cast<const MemberExpression&>(*m_callee);
|
||||||
bool is_super_property_lookup = is<SuperExpression>(member_expression.object());
|
Value callee;
|
||||||
auto lookup_target = is_super_property_lookup ? interpreter.current_environment()->get_super_base() : member_expression.object().execute(interpreter, global_object);
|
Object* this_value = nullptr;
|
||||||
if (vm.exception())
|
|
||||||
return {};
|
if (is<SuperExpression>(member_expression.object())) {
|
||||||
if (is_super_property_lookup && lookup_target.is_nullish()) {
|
auto super_base = interpreter.current_environment()->get_super_base();
|
||||||
vm.throw_exception<TypeError>(global_object, ErrorType::ObjectPrototypeNullOrUndefinedOnSuperPropertyAccess, lookup_target.to_string_without_side_effects());
|
if (super_base.is_nullish()) {
|
||||||
return {};
|
vm.throw_exception<TypeError>(global_object, ErrorType::ObjectPrototypeNullOrUndefinedOnSuperPropertyAccess, super_base.to_string_without_side_effects());
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
auto property_name = member_expression.computed_property_name(interpreter, global_object);
|
||||||
|
if (!property_name.is_valid())
|
||||||
|
return {};
|
||||||
|
auto reference = Reference(super_base, property_name);
|
||||||
|
callee = reference.get(global_object);
|
||||||
|
if (vm.exception())
|
||||||
|
return {};
|
||||||
|
this_value = &vm.this_value(global_object).as_object();
|
||||||
|
} else {
|
||||||
|
auto reference = member_expression.to_reference(interpreter, global_object);
|
||||||
|
if (vm.exception())
|
||||||
|
return {};
|
||||||
|
callee = reference.get(global_object);
|
||||||
|
if (vm.exception())
|
||||||
|
return {};
|
||||||
|
this_value = reference.base().to_object(global_object);
|
||||||
|
if (vm.exception())
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* this_value = is_super_property_lookup ? &vm.this_value(global_object).as_object() : lookup_target.to_object(global_object);
|
|
||||||
if (vm.exception())
|
|
||||||
return {};
|
|
||||||
auto property_name = member_expression.computed_property_name(interpreter, global_object);
|
|
||||||
if (!property_name.is_valid())
|
|
||||||
return {};
|
|
||||||
auto callee = lookup_target.to_object(global_object)->get(property_name).value_or(js_undefined());
|
|
||||||
return { this_value, callee };
|
return { this_value, callee };
|
||||||
}
|
}
|
||||||
return { &global_object, m_callee->execute(interpreter, global_object) };
|
return { &global_object, m_callee->execute(interpreter, global_object) };
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue