Skip to content

Commit 900f209

Browse files
committed
LibJS: Make Optional<Operand> use less space
Shrink these down from 12 bytes to 8 bytes, which helps make many bytecode instructions smaller.
1 parent a29d820 commit 900f209

File tree

1 file changed

+100
-0
lines changed

1 file changed

+100
-0
lines changed

Libraries/LibJS/Bytecode/Operand.h

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ namespace JS::Bytecode {
1414
class Operand {
1515
public:
1616
enum class Type {
17+
Invalid,
1718
Register,
1819
Local,
1920
Constant,
@@ -46,3 +47,102 @@ class Operand {
4647
};
4748

4849
}
50+
51+
namespace AK {
52+
template<>
53+
class Optional<JS::Bytecode::Operand> : public OptionalBase<JS::Bytecode::Operand> {
54+
template<typename U>
55+
friend class Optional;
56+
57+
public:
58+
using ValueType = JS::Bytecode::Operand;
59+
60+
Optional() = default;
61+
62+
template<SameAs<OptionalNone> V>
63+
Optional(V) { }
64+
65+
Optional(Optional<JS::Bytecode::Operand> const& other)
66+
{
67+
if (other.has_value())
68+
m_value = other.m_value;
69+
}
70+
71+
Optional(Optional&& other)
72+
: m_value(other.m_value)
73+
{
74+
}
75+
76+
template<typename U = JS::Bytecode::Operand>
77+
requires(!IsSame<OptionalNone, RemoveCVReference<U>>)
78+
explicit(!IsConvertible<U&&, JS::Bytecode::Operand>) Optional(U&& value)
79+
requires(!IsSame<RemoveCVReference<U>, Optional<JS::Bytecode::Operand>> && IsConstructible<JS::Bytecode::Operand, U &&>)
80+
: m_value(forward<U>(value))
81+
{
82+
}
83+
84+
template<SameAs<OptionalNone> V>
85+
Optional& operator=(V)
86+
{
87+
clear();
88+
return *this;
89+
}
90+
91+
Optional& operator=(Optional const& other)
92+
{
93+
if (this != &other) {
94+
clear();
95+
m_value = other.m_value;
96+
}
97+
return *this;
98+
}
99+
100+
Optional& operator=(Optional&& other)
101+
{
102+
if (this != &other) {
103+
clear();
104+
m_value = other.m_value;
105+
}
106+
return *this;
107+
}
108+
109+
void clear()
110+
{
111+
m_value = JS::Bytecode::Operand { JS::Bytecode::Operand::Type::Invalid, 0 };
112+
}
113+
114+
[[nodiscard]] bool has_value() const
115+
{
116+
return m_value.type() != JS::Bytecode::Operand::Type::Invalid;
117+
}
118+
119+
[[nodiscard]] JS::Bytecode::Operand& value() &
120+
{
121+
VERIFY(has_value());
122+
return m_value;
123+
}
124+
125+
[[nodiscard]] JS::Bytecode::Operand const& value() const&
126+
{
127+
VERIFY(has_value());
128+
return m_value;
129+
}
130+
131+
[[nodiscard]] JS::Bytecode::Operand value() &&
132+
{
133+
return release_value();
134+
}
135+
136+
[[nodiscard]] JS::Bytecode::Operand release_value()
137+
{
138+
VERIFY(has_value());
139+
JS::Bytecode::Operand released_value = m_value;
140+
clear();
141+
return released_value;
142+
}
143+
144+
private:
145+
JS::Bytecode::Operand m_value { JS::Bytecode::Operand::Type::Invalid, 0 };
146+
};
147+
148+
}

0 commit comments

Comments
 (0)