diff options
author | Ali Mohammad Pur <ali.mpfard@gmail.com> | 2022-03-13 16:01:18 +0330 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-03-13 17:50:21 +0100 |
commit | 20002513339dffb586ee774789f04aa7d5030c91 (patch) | |
tree | 0760ec4a8a888e43f4b1862ad6c7059e015f61dd /Userland/Libraries/LibJS | |
parent | 57386ca8398e38ad21a6b91edef13b8024fc5510 (diff) | |
download | serenity-20002513339dffb586ee774789f04aa7d5030c91.zip |
LibJS: Implement bytecode generation for WithStatement
Diffstat (limited to 'Userland/Libraries/LibJS')
-rw-r--r-- | Userland/Libraries/LibJS/AST.h | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp | 9 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Bytecode/Instruction.h | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Bytecode/Op.cpp | 15 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Bytecode/Op.h | 12 |
5 files changed, 38 insertions, 0 deletions
diff --git a/Userland/Libraries/LibJS/AST.h b/Userland/Libraries/LibJS/AST.h index d3ebb2dca8..00a47ed90d 100644 --- a/Userland/Libraries/LibJS/AST.h +++ b/Userland/Libraries/LibJS/AST.h @@ -844,6 +844,7 @@ public: virtual Completion execute(Interpreter&, GlobalObject&) const override; virtual void dump(int indent) const override; + virtual Bytecode::CodeGenerationErrorOr<void> generate_bytecode(Bytecode::Generator&) const override; private: NonnullRefPtr<Expression> m_object; diff --git a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp index a952ded98f..b26e55cc58 100644 --- a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp +++ b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp @@ -1618,4 +1618,13 @@ Bytecode::CodeGenerationErrorOr<void> AwaitExpression::generate_bytecode(Bytecod return {}; } +Bytecode::CodeGenerationErrorOr<void> WithStatement::generate_bytecode(Bytecode::Generator& generator) const +{ + TRY(m_object->generate_bytecode(generator)); + generator.emit<Bytecode::Op::EnterObjectEnvironment>(); + TRY(m_body->generate_bytecode(generator)); + generator.emit<Bytecode::Op::LeaveEnvironment>(Bytecode::Op::EnvironmentMode::Lexical); + return {}; +} + } diff --git a/Userland/Libraries/LibJS/Bytecode/Instruction.h b/Userland/Libraries/LibJS/Bytecode/Instruction.h index 720ad67b21..e76529ee89 100644 --- a/Userland/Libraries/LibJS/Bytecode/Instruction.h +++ b/Userland/Libraries/LibJS/Bytecode/Instruction.h @@ -25,6 +25,7 @@ O(Decrement) \ O(Div) \ O(EnterUnwindContext) \ + O(EnterObjectEnvironment) \ O(Exp) \ O(FinishUnwind) \ O(GetById) \ diff --git a/Userland/Libraries/LibJS/Bytecode/Op.cpp b/Userland/Libraries/LibJS/Bytecode/Op.cpp index da022f5b3a..8202bc1f8f 100644 --- a/Userland/Libraries/LibJS/Bytecode/Op.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Op.cpp @@ -18,6 +18,7 @@ #include <LibJS/Runtime/GlobalObject.h> #include <LibJS/Runtime/Iterator.h> #include <LibJS/Runtime/IteratorOperations.h> +#include <LibJS/Runtime/ObjectEnvironment.h> #include <LibJS/Runtime/RegExpObject.h> #include <LibJS/Runtime/Value.h> @@ -274,6 +275,15 @@ ThrowCompletionOr<void> CreateEnvironment::execute_impl(Bytecode::Interpreter& i return {}; } +ThrowCompletionOr<void> EnterObjectEnvironment::execute_impl(Bytecode::Interpreter& interpreter) const +{ + auto& old_environment = interpreter.vm().running_execution_context().lexical_environment; + interpreter.saved_lexical_environment_stack().append(old_environment); + auto object = TRY(interpreter.accumulator().to_object(interpreter.global_object())); + interpreter.vm().running_execution_context().lexical_environment = new_object_environment(*object, true, old_environment); + return {}; +} + ThrowCompletionOr<void> CreateVariable::execute_impl(Bytecode::Interpreter& interpreter) const { auto& vm = interpreter.vm(); @@ -695,6 +705,11 @@ String CreateVariable::to_string_impl(Bytecode::Executable const& executable) co return String::formatted("CreateVariable env:{} immutable:{} {} ({})", mode_string, m_is_immutable, m_identifier, executable.identifier_table->get(m_identifier)); } +String EnterObjectEnvironment::to_string_impl(const Executable&) const +{ + return String::formatted("EnterObjectEnvironment"); +} + String SetVariable::to_string_impl(Bytecode::Executable const& executable) const { auto initialization_mode_name = m_initialization_mode == InitializationMode ::Initialize ? "Initialize" diff --git a/Userland/Libraries/LibJS/Bytecode/Op.h b/Userland/Libraries/LibJS/Bytecode/Op.h index 00b8b0ecc1..b286e925e0 100644 --- a/Userland/Libraries/LibJS/Bytecode/Op.h +++ b/Userland/Libraries/LibJS/Bytecode/Op.h @@ -303,6 +303,18 @@ private: EnvironmentMode m_mode { EnvironmentMode::Lexical }; }; +class EnterObjectEnvironment final : public Instruction { +public: + explicit EnterObjectEnvironment() + : Instruction(Type::EnterObjectEnvironment) + { + } + + ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; + String to_string_impl(Bytecode::Executable const&) const; + void replace_references_impl(BasicBlock const&, BasicBlock const&) { } +}; + class CreateVariable final : public Instruction { public: explicit CreateVariable(IdentifierTableIndex identifier, EnvironmentMode mode, bool is_immutable) |