summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGunnar Beutner <gbeutner@serenityos.org>2021-06-08 07:59:25 +0200
committerLinus Groh <mail@linusgroh.de>2021-06-08 10:57:28 +0100
commit50ece3dd1bdfb77091b48efaaaf2f1be7e8db283 (patch)
treea6ead3d0e90f12de112290e4ef1b6b2dca22c661
parent0975e082858af4114c3f953c32f4440ab407e8b1 (diff)
downloadserenity-50ece3dd1bdfb77091b48efaaaf2f1be7e8db283.zip
LibJS: Implement bytecode generation for BigInts
-rw-r--r--Userland/Libraries/LibJS/AST.h1
-rw-r--r--Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp7
-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.h18
5 files changed, 38 insertions, 0 deletions
diff --git a/Userland/Libraries/LibJS/AST.h b/Userland/Libraries/LibJS/AST.h
index dd2395e810..d243453aeb 100644
--- a/Userland/Libraries/LibJS/AST.h
+++ b/Userland/Libraries/LibJS/AST.h
@@ -660,6 +660,7 @@ public:
virtual Value execute(Interpreter&, GlobalObject&) const override;
virtual void dump(int indent) const override;
+ virtual Optional<Bytecode::Register> generate_bytecode(Bytecode::Generator&) const override;
private:
String m_value;
diff --git a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp
index e473aadf73..8b56fa54ce 100644
--- a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp
+++ b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp
@@ -208,6 +208,13 @@ Optional<Bytecode::Register> NullLiteral::generate_bytecode(Bytecode::Generator&
return dst;
}
+Optional<Bytecode::Register> BigIntLiteral::generate_bytecode(Bytecode::Generator& generator) const
+{
+ auto dst = generator.allocate_register();
+ generator.emit<Bytecode::Op::NewBigInt>(dst, Crypto::SignedBigInteger::from_base10(m_value.substring(0, m_value.length() - 1)));
+ return dst;
+}
+
Optional<Bytecode::Register> StringLiteral::generate_bytecode(Bytecode::Generator& generator) const
{
auto dst = generator.allocate_register();
diff --git a/Userland/Libraries/LibJS/Bytecode/Instruction.h b/Userland/Libraries/LibJS/Bytecode/Instruction.h
index 5679c47a92..6bea827a35 100644
--- a/Userland/Libraries/LibJS/Bytecode/Instruction.h
+++ b/Userland/Libraries/LibJS/Bytecode/Instruction.h
@@ -26,6 +26,7 @@
O(AbstractEquals) \
O(TypedInequals) \
O(TypedEquals) \
+ O(NewBigInt) \
O(NewString) \
O(NewObject) \
O(GetVariable) \
diff --git a/Userland/Libraries/LibJS/Bytecode/Op.cpp b/Userland/Libraries/LibJS/Bytecode/Op.cpp
index 32057060f5..e2691681ed 100644
--- a/Userland/Libraries/LibJS/Bytecode/Op.cpp
+++ b/Userland/Libraries/LibJS/Bytecode/Op.cpp
@@ -8,6 +8,7 @@
#include <LibJS/AST.h>
#include <LibJS/Bytecode/Interpreter.h>
#include <LibJS/Bytecode/Op.h>
+#include <LibJS/Runtime/BigInt.h>
#include <LibJS/Runtime/GlobalObject.h>
#include <LibJS/Runtime/ScriptFunction.h>
#include <LibJS/Runtime/Value.h>
@@ -112,6 +113,11 @@ static Value typeof_(GlobalObject& global_object, Value value)
JS_ENUMERATE_COMMON_UNARY_OPS(JS_DEFINE_COMMON_UNARY_OP)
+void NewBigInt::execute(Bytecode::Interpreter& interpreter) const
+{
+ interpreter.reg(m_dst) = js_bigint(interpreter.vm().heap(), m_bigint);
+}
+
void NewString::execute(Bytecode::Interpreter& interpreter) const
{
interpreter.reg(m_dst) = js_string(interpreter.vm(), m_string);
@@ -231,6 +237,11 @@ String LoadRegister::to_string() const
return String::formatted("LoadRegister dst:{}, src:{}", m_dst, m_src);
}
+String NewBigInt::to_string() const
+{
+ return String::formatted("NewBigInt dst:{}, bigint:\"{}\"", m_dst, m_bigint.to_base10());
+}
+
String NewString::to_string() const
{
return String::formatted("NewString dst:{}, string:\"{}\"", m_dst, m_string);
diff --git a/Userland/Libraries/LibJS/Bytecode/Op.h b/Userland/Libraries/LibJS/Bytecode/Op.h
index b80b744a77..fb286ef2fa 100644
--- a/Userland/Libraries/LibJS/Bytecode/Op.h
+++ b/Userland/Libraries/LibJS/Bytecode/Op.h
@@ -8,6 +8,7 @@
#pragma once
#include <AK/FlyString.h>
+#include <LibCrypto/BigInt/SignedBigInteger.h>
#include <LibJS/Bytecode/Instruction.h>
#include <LibJS/Bytecode/Label.h>
#include <LibJS/Bytecode/Register.h>
@@ -157,6 +158,23 @@ private:
Register m_dst;
};
+class NewBigInt final : public Instruction {
+public:
+ explicit NewBigInt(Register dst, Crypto::SignedBigInteger bigint)
+ : Instruction(Type::NewBigInt)
+ , m_dst(dst)
+ , m_bigint(move(bigint))
+ {
+ }
+
+ void execute(Bytecode::Interpreter&) const;
+ String to_string() const;
+
+private:
+ Register m_dst;
+ Crypto::SignedBigInteger m_bigint;
+};
+
class SetVariable final : public Instruction {
public:
SetVariable(FlyString identifier, Register src)