From 1dc60b028f37366ec01b809a101224ada7dc82aa Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Mon, 25 Oct 2021 15:16:22 +0200 Subject: [PATCH] LibJS: Add BytecodeGenerator helpers for reference get/put This allows code sharing between all AST nodes that want to get and/or put through a reference. --- .../Libraries/LibJS/Bytecode/Generator.cpp | 61 +++++++++++++++++++ Userland/Libraries/LibJS/Bytecode/Generator.h | 3 + 2 files changed, 64 insertions(+) diff --git a/Userland/Libraries/LibJS/Bytecode/Generator.cpp b/Userland/Libraries/LibJS/Bytecode/Generator.cpp index f6dfc923cc..21ee3822c8 100644 --- a/Userland/Libraries/LibJS/Bytecode/Generator.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Generator.cpp @@ -93,4 +93,65 @@ void Generator::end_breakable_scope() { m_breakable_scopes.take_last(); } + +void Generator::emit_load_from_reference(JS::ASTNode const& node) +{ + if (is(node)) { + auto& identifier = static_cast(node); + emit(intern_identifier(identifier.string())); + return; + } + if (is(node)) { + auto& expression = static_cast(node); + expression.object().generate_bytecode(*this); + + auto object_reg = allocate_register(); + emit(object_reg); + + if (expression.is_computed()) { + expression.property().generate_bytecode(*this); + emit(object_reg); + } else { + auto identifier_table_ref = intern_identifier(verify_cast(expression.property()).string()); + emit(identifier_table_ref); + } + return; + } + VERIFY_NOT_REACHED(); +} + +void Generator::emit_store_to_reference(JS::ASTNode const& node) +{ + if (is(node)) { + auto& identifier = static_cast(node); + emit(intern_identifier(identifier.string())); + return; + } + if (is(node)) { + // NOTE: The value is in the accumulator, so we have to store that away first. + auto value_reg = allocate_register(); + emit(value_reg); + + auto& expression = static_cast(node); + expression.object().generate_bytecode(*this); + + auto object_reg = allocate_register(); + emit(object_reg); + + if (expression.is_computed()) { + expression.property().generate_bytecode(*this); + auto property_reg = allocate_register(); + emit(property_reg); + emit(value_reg); + emit(object_reg, property_reg); + } else { + emit(value_reg); + auto identifier_table_ref = intern_identifier(verify_cast(expression.property()).string()); + emit(object_reg, identifier_table_ref); + } + return; + } + VERIFY_NOT_REACHED(); +} + } diff --git a/Userland/Libraries/LibJS/Bytecode/Generator.h b/Userland/Libraries/LibJS/Bytecode/Generator.h index 48140c9998..669f05a327 100644 --- a/Userland/Libraries/LibJS/Bytecode/Generator.h +++ b/Userland/Libraries/LibJS/Bytecode/Generator.h @@ -70,6 +70,9 @@ public: return *static_cast(slot); } + void emit_load_from_reference(JS::ASTNode const&); + void emit_store_to_reference(JS::ASTNode const&); + void begin_continuable_scope(Label continue_target); void end_continuable_scope(); void begin_breakable_scope(Label breakable_target);