diff options
author | Luke Wilde <lukew@serenityos.org> | 2022-03-19 19:40:21 +0000 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-03-19 22:01:52 +0100 |
commit | eac5534ce40c79f98f0e92c7dfad0e3b15acc54c (patch) | |
tree | c51424a6814655c1e1fff4203256f32c2cc62a64 /Userland/Libraries/LibJS | |
parent | fd235d8a06b80a09ed0af8002d86b141171f8ef1 (diff) | |
download | serenity-eac5534ce40c79f98f0e92c7dfad0e3b15acc54c.zip |
LibJS/Bytecode: Add support for new.target
Diffstat (limited to 'Userland/Libraries/LibJS')
-rw-r--r-- | Userland/Libraries/LibJS/AST.h | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp | 21 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Bytecode/Instruction.h | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Bytecode/Op.cpp | 11 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Bytecode/Op.h | 12 |
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 { |