ladybird/Libraries/LibJS/Bytecode/PropertyKeyTable.h
Jelle Raaijmakers e123d48043 AK: Add SentinelOptional
We specialize `Optional<T>` for value types that inherently support some
kind of "empty" value or whose value range allow for a unlikely to be
useful sentinel value that can mean "empty", instead of the boolean flag
a regular Optional<T> needs to store. Because of padding, this often
means saving 4 to 8 bytes per instance.

By extending the new `SentinelOptional<T, Traits>`, these
specializations are significantly simplified to just having to define
what the sentinel value is, and how to identify a sentinel value.
2026-03-20 12:03:36 +01:00

61 lines
1.5 KiB
C++

/*
* Copyright (c) 2025, Andreas Kling <andreas@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/DistinctNumeric.h>
#include <AK/Vector.h>
#include <LibJS/Runtime/PropertyKey.h>
namespace JS::Bytecode {
struct PropertyKeyTableIndex {
static constexpr u32 invalid = 0xffffffffu;
bool is_valid() const { return value != invalid; }
u32 value { 0 };
};
class PropertyKeyTable {
AK_MAKE_NONMOVABLE(PropertyKeyTable);
AK_MAKE_NONCOPYABLE(PropertyKeyTable);
public:
PropertyKeyTable() = default;
PropertyKeyTableIndex insert(PropertyKey);
PropertyKey const& get(PropertyKeyTableIndex) const;
void dump() const;
bool is_empty() const { return m_property_keys.is_empty(); }
ReadonlySpan<PropertyKey const> property_keys() const { return m_property_keys; }
void visit_edges(GC::Cell::Visitor& visitor)
{
for (auto& key : m_property_keys)
key.visit_edges(visitor);
}
private:
Vector<PropertyKey> m_property_keys;
};
}
namespace AK {
template<>
struct SentinelOptionalTraits<JS::Bytecode::PropertyKeyTableIndex> {
static constexpr JS::Bytecode::PropertyKeyTableIndex sentinel_value() { return { JS::Bytecode::PropertyKeyTableIndex::invalid }; }
static constexpr bool is_sentinel(JS::Bytecode::PropertyKeyTableIndex const& value) { return !value.is_valid(); }
};
template<>
class Optional<JS::Bytecode::PropertyKeyTableIndex> : public SentinelOptional<JS::Bytecode::PropertyKeyTableIndex> {
public:
using SentinelOptional::SentinelOptional;
};
}