diff options
author | Ali Mohammad Pur <ali.mpfard@gmail.com> | 2021-06-11 01:36:10 +0430 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-06-11 00:30:09 +0200 |
commit | c53a86a3fe530d6adaa095944a59a8a0333be3c6 (patch) | |
tree | 942f2137894f0b30cb3b9ac5ca31939d5e0e4e74 | |
parent | 4cfdfb6a887f083b7b495350e5ac09d9c2271802 (diff) | |
download | serenity-c53a86a3fe530d6adaa095944a59a8a0333be3c6.zip |
LibJS: Resolve the `this' value in call expression bytecode
-rw-r--r-- | Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp | 29 |
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); |