summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibJS/Bytecode/Instruction.h
blob: b38ed0b804f1a585a3883ddcea8e4cfb04fb69db (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/*
 * Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */

#pragma once

#include <AK/Forward.h>
#include <LibJS/Bytecode/Block.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 {};
};

template<typename OpType>
class InstructionHandle {
public:
    InstructionHandle() = default;

    InstructionHandle(size_t offset, Block* block)
        : m_offset(offset)
        , m_block(block)
    {
    }

    OpType* operator->() const
    {
        VERIFY(m_block);
        return reinterpret_cast<OpType*>(m_block->buffer().data() + m_offset);
    }

    OpType& operator*() const
    {
        VERIFY(m_block);
        return *reinterpret_cast<OpType*>(m_block->buffer().data() + m_offset);
    }

    template<typename T>
    InstructionHandle<OpType>& operator=(InstructionHandle<T> const& other) requires(IsBaseOf<OpType, T>)
    {
        m_offset = other.offset();
        m_block = other.block();
        return *this;
    }

    size_t offset() const { return m_offset; }
    Block* block() const { return m_block; }

private:
    friend class Block;

    size_t m_offset { 0 };
    Block* m_block { nullptr };
};

}