diff --git a/Userland/Libraries/LibJS/AST.h b/Userland/Libraries/LibJS/AST.h index 76176fb771d..18c8a0b130b 100644 --- a/Userland/Libraries/LibJS/AST.h +++ b/Userland/Libraries/LibJS/AST.h @@ -1245,6 +1245,7 @@ public: virtual void dump(int indent) const override; virtual Value execute(Interpreter&, GlobalObject&) const override; + virtual void generate_bytecode(Bytecode::Generator&) const override; private: NonnullRefPtr m_argument; diff --git a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp index 866a1431365..1db9b3f5e8c 100644 --- a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp +++ b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp @@ -1,6 +1,7 @@ /* * Copyright (c) 2021, Andreas Kling * Copyright (c) 2021, Linus Groh + * Copyright (c) 2021, Gunnar Beutner * * SPDX-License-Identifier: BSD-2-Clause */ @@ -668,4 +669,10 @@ void UpdateExpression::generate_bytecode(Bytecode::Generator& generator) const TODO(); } +void ThrowStatement::generate_bytecode(Bytecode::Generator& generator) const +{ + m_argument->generate_bytecode(generator); + generator.emit(); +} + } diff --git a/Userland/Libraries/LibJS/Bytecode/Instruction.h b/Userland/Libraries/LibJS/Bytecode/Instruction.h index 9b67fa096cc..b52a7121239 100644 --- a/Userland/Libraries/LibJS/Bytecode/Instruction.h +++ b/Userland/Libraries/LibJS/Bytecode/Instruction.h @@ -56,7 +56,8 @@ O(InstanceOf) \ O(ConcatString) \ O(Increment) \ - O(Decrement) + O(Decrement) \ + O(Throw) namespace JS::Bytecode { diff --git a/Userland/Libraries/LibJS/Bytecode/Op.cpp b/Userland/Libraries/LibJS/Bytecode/Op.cpp index cea771567f9..cdd26dd7bac 100644 --- a/Userland/Libraries/LibJS/Bytecode/Op.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Op.cpp @@ -1,6 +1,7 @@ /* * Copyright (c) 2021, Andreas Kling * Copyright (c) 2021, Linus Groh + * Copyright (c) 2021, Gunnar Beutner * * SPDX-License-Identifier: BSD-2-Clause */ @@ -255,6 +256,11 @@ void Decrement::execute(Bytecode::Interpreter& interpreter) const interpreter.accumulator() = js_bigint(interpreter.vm().heap(), old_value.as_bigint().big_integer().minus(Crypto::SignedBigInteger { 1 })); } +void Throw::execute(Bytecode::Interpreter& interpreter) const +{ + interpreter.vm().throw_exception(interpreter.global_object(), interpreter.accumulator()); +} + String Load::to_string(Bytecode::Executable const&) const { return String::formatted("Load {}", m_src); @@ -383,4 +389,9 @@ String Decrement::to_string(Bytecode::Executable const&) const return "Decrement"; } +String Throw::to_string(Bytecode::Executable const&) const +{ + return "Throw"; +} + } diff --git a/Userland/Libraries/LibJS/Bytecode/Op.h b/Userland/Libraries/LibJS/Bytecode/Op.h index 7398724afc7..8893bf925e7 100644 --- a/Userland/Libraries/LibJS/Bytecode/Op.h +++ b/Userland/Libraries/LibJS/Bytecode/Op.h @@ -1,6 +1,7 @@ /* * Copyright (c) 2021, Andreas Kling * Copyright (c) 2021, Linus Groh + * Copyright (c) 2021, Gunnar Beutner * * SPDX-License-Identifier: BSD-2-Clause */ @@ -395,6 +396,19 @@ public: String to_string(Bytecode::Executable const&) const; }; +class Throw final : public Instruction { +public: + constexpr static bool IsTerminator = true; + + Throw() + : Instruction(Type::Throw) + { + } + + void execute(Bytecode::Interpreter&) const; + String to_string(Bytecode::Executable const&) const; +}; + } namespace JS::Bytecode {