summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibJS
diff options
context:
space:
mode:
authorAli Mohammad Pur <ali.mpfard@gmail.com>2022-03-13 16:01:18 +0330
committerAndreas Kling <kling@serenityos.org>2022-03-13 17:50:21 +0100
commit20002513339dffb586ee774789f04aa7d5030c91 (patch)
tree0760ec4a8a888e43f4b1862ad6c7059e015f61dd /Userland/Libraries/LibJS
parent57386ca8398e38ad21a6b91edef13b8024fc5510 (diff)
downloadserenity-20002513339dffb586ee774789f04aa7d5030c91.zip
LibJS: Implement bytecode generation for WithStatement
Diffstat (limited to 'Userland/Libraries/LibJS')
-rw-r--r--Userland/Libraries/LibJS/AST.h1
-rw-r--r--Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp9
-rw-r--r--Userland/Libraries/LibJS/Bytecode/Instruction.h1
-rw-r--r--Userland/Libraries/LibJS/Bytecode/Op.cpp15
-rw-r--r--Userland/Libraries/LibJS/Bytecode/Op.h12
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)