summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibJS
diff options
context:
space:
mode:
authorLuke Wilde <lukew@serenityos.org>2022-03-19 19:40:21 +0000
committerAndreas Kling <kling@serenityos.org>2022-03-19 22:01:52 +0100
commiteac5534ce40c79f98f0e92c7dfad0e3b15acc54c (patch)
treec51424a6814655c1e1fff4203256f32c2cc62a64 /Userland/Libraries/LibJS
parentfd235d8a06b80a09ed0af8002d86b141171f8ef1 (diff)
downloadserenity-eac5534ce40c79f98f0e92c7dfad0e3b15acc54c.zip
LibJS/Bytecode: Add support for new.target
Diffstat (limited to 'Userland/Libraries/LibJS')
-rw-r--r--Userland/Libraries/LibJS/AST.h1
-rw-r--r--Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp21
-rw-r--r--Userland/Libraries/LibJS/Bytecode/Instruction.h1
-rw-r--r--Userland/Libraries/LibJS/Bytecode/Op.cpp11
-rw-r--r--Userland/Libraries/LibJS/Bytecode/Op.h12
5 files changed, 46 insertions, 0 deletions
diff --git a/Userland/Libraries/LibJS/AST.h b/Userland/Libraries/LibJS/AST.h
index 4880b30766..ea9b283116 100644
--- a/Userland/Libraries/LibJS/AST.h
+++ b/Userland/Libraries/LibJS/AST.h
@@ -1866,6 +1866,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:
Type m_type;
diff --git a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp
index cd68d08209..49001ab8de 100644
--- a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp
+++ b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp
@@ -2031,4 +2031,25 @@ Bytecode::CodeGenerationErrorOr<void> ForOfStatement::generate_bytecode(Bytecode
return for_in_of_body_evaluation(generator, *this, m_lhs, body(), head_result, loop_end, loop_update);
}
+// 13.3.12.1 Runtime Semantics: Evaluation, https://tc39.es/ecma262/#sec-meta-properties-runtime-semantics-evaluation
+Bytecode::CodeGenerationErrorOr<void> MetaProperty::generate_bytecode(Bytecode::Generator& generator) const
+{
+ // NewTarget : new . target
+ if (m_type == MetaProperty::Type::NewTarget) {
+ // 1. Return GetNewTarget().
+ generator.emit<Bytecode::Op::GetNewTarget>();
+ return {};
+ }
+
+ // ImportMeta : import . meta
+ if (m_type == MetaProperty::Type::ImportMeta) {
+ return Bytecode::CodeGenerationError {
+ this,
+ "Unimplemented meta property: import.meta"sv,
+ };
+ }
+
+ VERIFY_NOT_REACHED();
+}
+
}
diff --git a/Userland/Libraries/LibJS/Bytecode/Instruction.h b/Userland/Libraries/LibJS/Bytecode/Instruction.h
index cf28733751..f9c8dffa0c 100644
--- a/Userland/Libraries/LibJS/Bytecode/Instruction.h
+++ b/Userland/Libraries/LibJS/Bytecode/Instruction.h
@@ -31,6 +31,7 @@
O(GetById) \
O(GetByValue) \
O(GetIterator) \
+ O(GetNewTarget) \
O(GetObjectPropertyIterator) \
O(GetVariable) \
O(GreaterThan) \
diff --git a/Userland/Libraries/LibJS/Bytecode/Op.cpp b/Userland/Libraries/LibJS/Bytecode/Op.cpp
index 76d3e606bb..5e8d6183be 100644
--- a/Userland/Libraries/LibJS/Bytecode/Op.cpp
+++ b/Userland/Libraries/LibJS/Bytecode/Op.cpp
@@ -358,6 +358,12 @@ ThrowCompletionOr<void> ResolveThisBinding::execute_impl(Bytecode::Interpreter&
return {};
}
+ThrowCompletionOr<void> GetNewTarget::execute_impl(Bytecode::Interpreter& interpreter) const
+{
+ interpreter.accumulator() = interpreter.vm().get_new_target();
+ return {};
+}
+
void Jump::replace_references_impl(BasicBlock const& from, BasicBlock const& to)
{
if (m_true_target.has_value() && &m_true_target->block() == &from)
@@ -976,4 +982,9 @@ String ResolveThisBinding::to_string_impl(Bytecode::Executable const&) const
return "ResolveThisBinding"sv;
}
+String GetNewTarget::to_string_impl(Bytecode::Executable const&) const
+{
+ return "GetNewTarget"sv;
+}
+
}
diff --git a/Userland/Libraries/LibJS/Bytecode/Op.h b/Userland/Libraries/LibJS/Bytecode/Op.h
index 0c6f4116a8..d3c5284af4 100644
--- a/Userland/Libraries/LibJS/Bytecode/Op.h
+++ b/Userland/Libraries/LibJS/Bytecode/Op.h
@@ -838,6 +838,18 @@ public:
void replace_references_impl(BasicBlock const&, BasicBlock const&) { }
};
+class GetNewTarget final : public Instruction {
+public:
+ explicit GetNewTarget()
+ : Instruction(Type::GetNewTarget)
+ {
+ }
+
+ ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
+ String to_string_impl(Bytecode::Executable const&) const;
+ void replace_references_impl(BasicBlock const&, BasicBlock const&) { }
+};
+
}
namespace JS::Bytecode {