summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAli Mohammad Pur <ali.mpfard@gmail.com>2021-06-11 01:36:10 +0430
committerAndreas Kling <kling@serenityos.org>2021-06-11 00:30:09 +0200
commitc53a86a3fe530d6adaa095944a59a8a0333be3c6 (patch)
tree942f2137894f0b30cb3b9ac5ca31939d5e0e4e74
parent4cfdfb6a887f083b7b495350e5ac09d9c2271802 (diff)
downloadserenity-c53a86a3fe530d6adaa095944a59a8a0333be3c6.zip
LibJS: Resolve the `this' value in call expression bytecode
-rw-r--r--Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp29
1 files changed, 25 insertions, 4 deletions
diff --git a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp
index 2264dc85a0..6397ca2e8c 100644
--- a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp
+++ b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp
@@ -616,15 +616,36 @@ void VariableDeclaration::generate_bytecode(Bytecode::Generator& generator) cons
void CallExpression::generate_bytecode(Bytecode::Generator& generator) const
{
- m_callee->generate_bytecode(generator);
auto callee_reg = generator.allocate_register();
- generator.emit<Bytecode::Op::Store>(callee_reg);
-
- // FIXME: Load the correct 'this' value into 'this_reg'.
auto this_reg = generator.allocate_register();
generator.emit<Bytecode::Op::LoadImmediate>(js_undefined());
generator.emit<Bytecode::Op::Store>(this_reg);
+ if (is<NewExpression>(this)) {
+ m_callee->generate_bytecode(generator);
+ generator.emit<Bytecode::Op::Store>(callee_reg);
+ } else if (is<SuperExpression>(*m_callee)) {
+ TODO();
+ } else if (is<MemberExpression>(*m_callee)) {
+ auto& member_expression = static_cast<const MemberExpression&>(*m_callee);
+ if (is<SuperExpression>(member_expression.object())) {
+ TODO();
+ } else {
+ member_expression.object().generate_bytecode(generator);
+ generator.emit<Bytecode::Op::Store>(this_reg);
+ // FIXME: Don't copy this logic here, make MemberExpression generate it.
+ if (!is<Identifier>(member_expression.property()))
+ TODO();
+ auto identifier_table_ref = generator.intern_string(static_cast<Identifier const&>(member_expression.property()).string());
+ generator.emit<Bytecode::Op::GetById>(identifier_table_ref);
+ generator.emit<Bytecode::Op::Store>(callee_reg);
+ }
+ } else {
+ // FIXME: this = global object in sloppy mode.
+ m_callee->generate_bytecode(generator);
+ generator.emit<Bytecode::Op::Store>(callee_reg);
+ }
+
Vector<Bytecode::Register> argument_registers;
for (auto& arg : m_arguments) {
arg.value->generate_bytecode(generator);