mirror of
https://github.com/RGBCube/serenity
synced 2025-05-20 14:45:07 +00:00

This commit introduces the concept of an accumulator register to LibJS's bytecode interpreter. The accumulator register is always register 0, and most simple instructions use it for reading and writing. Not only does this slim down the AST, but it also simplifies a lot of the code. For example, the generate_bytecode methods no longer need to return an Optional<Register>, as any opcode which has a "return" value will always put it into the accumulator. This also renames the old Op::Load to Op::LoadImmediate, and uses Op::Load to load from a register into the accumulator. There is also an Op::Store to put the value in the accumulator into another register.
86 lines
2.3 KiB
C++
86 lines
2.3 KiB
C++
/*
|
|
* Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <AK/Forward.h>
|
|
#include <LibJS/Forward.h>
|
|
|
|
#define ENUMERATE_BYTECODE_OPS(O) \
|
|
O(Load) \
|
|
O(LoadImmediate) \
|
|
O(Store) \
|
|
O(Add) \
|
|
O(Sub) \
|
|
O(Mul) \
|
|
O(Div) \
|
|
O(Mod) \
|
|
O(Exp) \
|
|
O(GreaterThan) \
|
|
O(GreaterThanEquals) \
|
|
O(LessThan) \
|
|
O(LessThanEquals) \
|
|
O(AbstractInequals) \
|
|
O(AbstractEquals) \
|
|
O(TypedInequals) \
|
|
O(TypedEquals) \
|
|
O(NewBigInt) \
|
|
O(NewString) \
|
|
O(NewObject) \
|
|
O(GetVariable) \
|
|
O(SetVariable) \
|
|
O(PutById) \
|
|
O(GetById) \
|
|
O(Jump) \
|
|
O(JumpIfFalse) \
|
|
O(JumpIfTrue) \
|
|
O(JumpIfNotNullish) \
|
|
O(Call) \
|
|
O(EnterScope) \
|
|
O(Return) \
|
|
O(BitwiseAnd) \
|
|
O(BitwiseOr) \
|
|
O(BitwiseXor) \
|
|
O(BitwiseNot) \
|
|
O(Not) \
|
|
O(UnaryPlus) \
|
|
O(UnaryMinus) \
|
|
O(Typeof) \
|
|
O(LeftShift) \
|
|
O(RightShift) \
|
|
O(UnsignedRightShift) \
|
|
O(In) \
|
|
O(InstanceOf) \
|
|
O(ConcatString)
|
|
|
|
namespace JS::Bytecode {
|
|
|
|
class Instruction {
|
|
public:
|
|
enum class Type {
|
|
#define __BYTECODE_OP(op) \
|
|
op,
|
|
ENUMERATE_BYTECODE_OPS(__BYTECODE_OP)
|
|
#undef __BYTECODE_OP
|
|
};
|
|
|
|
Type type() const { return m_type; }
|
|
size_t length() const;
|
|
String to_string() const;
|
|
void execute(Bytecode::Interpreter&) const;
|
|
static void destroy(Instruction&);
|
|
|
|
protected:
|
|
explicit Instruction(Type type)
|
|
: m_type(type)
|
|
{
|
|
}
|
|
|
|
private:
|
|
Type m_type {};
|
|
};
|
|
|
|
}
|