Browse Source

LibJS: Generate bytecode for throw statements

Gunnar Beutner 4 years ago
parent
commit
b78f1c1261

+ 1 - 0
Userland/Libraries/LibJS/AST.h

@@ -1245,6 +1245,7 @@ public:
 
 
     virtual void dump(int indent) const override;
     virtual void dump(int indent) const override;
     virtual Value execute(Interpreter&, GlobalObject&) const override;
     virtual Value execute(Interpreter&, GlobalObject&) const override;
+    virtual void generate_bytecode(Bytecode::Generator&) const override;
 
 
 private:
 private:
     NonnullRefPtr<Expression> m_argument;
     NonnullRefPtr<Expression> m_argument;

+ 7 - 0
Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp

@@ -1,6 +1,7 @@
 /*
 /*
  * Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
  * Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
  * Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
  * Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
+ * Copyright (c) 2021, Gunnar Beutner <gbeutner@serenityos.org>
  *
  *
  * SPDX-License-Identifier: BSD-2-Clause
  * SPDX-License-Identifier: BSD-2-Clause
  */
  */
@@ -668,4 +669,10 @@ void UpdateExpression::generate_bytecode(Bytecode::Generator& generator) const
     TODO();
     TODO();
 }
 }
 
 
+void ThrowStatement::generate_bytecode(Bytecode::Generator& generator) const
+{
+    m_argument->generate_bytecode(generator);
+    generator.emit<Bytecode::Op::Throw>();
+}
+
 }
 }

+ 2 - 1
Userland/Libraries/LibJS/Bytecode/Instruction.h

@@ -56,7 +56,8 @@
     O(InstanceOf)                 \
     O(InstanceOf)                 \
     O(ConcatString)               \
     O(ConcatString)               \
     O(Increment)                  \
     O(Increment)                  \
-    O(Decrement)
+    O(Decrement)                  \
+    O(Throw)
 
 
 namespace JS::Bytecode {
 namespace JS::Bytecode {
 
 

+ 11 - 0
Userland/Libraries/LibJS/Bytecode/Op.cpp

@@ -1,6 +1,7 @@
 /*
 /*
  * Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
  * Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
  * Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
  * Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
+ * Copyright (c) 2021, Gunnar Beutner <gbeutner@serenityos.org>
  *
  *
  * SPDX-License-Identifier: BSD-2-Clause
  * 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 }));
         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
 String Load::to_string(Bytecode::Executable const&) const
 {
 {
     return String::formatted("Load {}", m_src);
     return String::formatted("Load {}", m_src);
@@ -383,4 +389,9 @@ String Decrement::to_string(Bytecode::Executable const&) const
     return "Decrement";
     return "Decrement";
 }
 }
 
 
+String Throw::to_string(Bytecode::Executable const&) const
+{
+    return "Throw";
+}
+
 }
 }

+ 14 - 0
Userland/Libraries/LibJS/Bytecode/Op.h

@@ -1,6 +1,7 @@
 /*
 /*
  * Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
  * Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
  * Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
  * Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
+ * Copyright (c) 2021, Gunnar Beutner <gbeutner@serenityos.org>
  *
  *
  * SPDX-License-Identifier: BSD-2-Clause
  * SPDX-License-Identifier: BSD-2-Clause
  */
  */
@@ -395,6 +396,19 @@ public:
     String to_string(Bytecode::Executable const&) const;
     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 {
 namespace JS::Bytecode {