1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 14:57:35 +00:00

LibJS: Add JS_CELL macro and use it in all JS::Cell subclasses

This is similar to what we already had with JS_OBJECT (and also
JS_ENVIRONMENT) but sits at the top of the Cell inheritance hierarchy.
This commit is contained in:
Andreas Kling 2022-08-28 22:11:20 +02:00
parent 94f016b363
commit 6e973ce69b
16 changed files with 37 additions and 23 deletions

View file

@ -14,6 +14,14 @@
namespace JS {
#define JS_CELL(class_, base_class) \
public: \
using Base = base_class; \
virtual StringView class_name() const override \
{ \
return #class_##sv; \
}
class Cell {
AK_MAKE_NONCOPYABLE(Cell);
AK_MAKE_NONMOVABLE(Cell);

View file

@ -97,9 +97,9 @@ private:
bool has_lazy_freelist() const { return m_next_lazy_freelist_index < cell_count(); }
struct FreelistEntry final : public Cell {
FreelistEntry* next { nullptr };
JS_CELL(FreelistEntry, Cell);
virtual StringView class_name() const override { return "FreelistEntry"sv; }
FreelistEntry* next { nullptr };
};
Cell* cell(size_t index)

View file

@ -14,6 +14,8 @@
namespace JS {
class Accessor final : public Cell {
JS_CELL(Accessor, Cell);
public:
static Accessor* create(VM& vm, FunctionObject* getter, FunctionObject* setter)
{
@ -39,8 +41,6 @@ public:
}
private:
StringView class_name() const override { return "Accessor"sv; };
FunctionObject* m_getter { nullptr };
FunctionObject* m_setter { nullptr };
};

View file

@ -35,7 +35,6 @@ public:
return Array::create_from(realm, values);
}
explicit Array(Object& prototype);
virtual ~Array() override = default;
virtual ThrowCompletionOr<Optional<PropertyDescriptor>> internal_get_own_property(PropertyKey const&) const override;

View file

@ -13,6 +13,8 @@
namespace JS {
class BigInt final : public Cell {
JS_CELL(BigInt, Cell);
public:
explicit BigInt(Crypto::SignedBigInteger);
virtual ~BigInt() override = default;
@ -21,8 +23,6 @@ public:
const String to_string() const { return String::formatted("{}n", m_big_integer.to_base(10)); }
private:
virtual StringView class_name() const override { return "BigInt"sv; }
Crypto::SignedBigInteger m_big_integer;
};

View file

@ -23,6 +23,8 @@ public: \
virtual StringView class_name() const override { return #class_##sv; }
class Environment : public Cell {
JS_CELL(Environment, Cell);
public:
virtual bool has_this_binding() const { return false; }
virtual ThrowCompletionOr<Value> get_this_binding(VM&) const { return Value {}; }
@ -48,8 +50,6 @@ public:
template<typename T>
bool fast_is() const = delete;
virtual StringView class_name() const override { return "Environment"sv; }
// This flag is set on the entire variable environment chain when direct eval() is performed.
// It is used to disable non-local variable access caching.
bool is_permanently_screwed_by_eval() const { return m_permanently_screwed_by_eval; }

View file

@ -13,6 +13,8 @@
namespace JS {
class Intrinsics final : public Cell {
JS_CELL(Intrinsics, Cell);
public:
static Intrinsics* create(Realm&);
@ -112,7 +114,6 @@ public:
#undef __JS_ENUMERATE
private:
virtual StringView class_name() const override { return "Intrinsics"sv; }
virtual void visit_edges(Visitor&) override;
void initialize_intrinsics(Realm&);

View file

@ -46,6 +46,8 @@ struct PrivateElement {
};
class Object : public Cell {
JS_CELL(Object, Cell);
public:
static Object* create(Realm&, Object* prototype);
@ -174,7 +176,6 @@ public:
bool has_parameter_map() const { return m_has_parameter_map; }
void set_has_parameter_map() { m_has_parameter_map = true; }
virtual StringView class_name() const override { return "Object"sv; }
virtual void visit_edges(Cell::Visitor&) override;
Value get_direct(size_t index) const { return m_storage[index]; }

View file

@ -16,6 +16,8 @@
namespace JS {
class PrimitiveString final : public Cell {
JS_CELL(PrimitiveString, Cell);
public:
explicit PrimitiveString(PrimitiveString&, PrimitiveString&);
explicit PrimitiveString(String);
@ -37,7 +39,6 @@ public:
Optional<Value> get(VM&, PropertyKey const&) const;
private:
virtual StringView class_name() const override { return "PrimitiveString"sv; }
virtual void visit_edges(Cell::Visitor&) override;
void resolve_rope_if_needed() const;

View file

@ -28,6 +28,8 @@ struct PrivateName {
};
class PrivateEnvironment : public Cell {
JS_CELL(PrivateEnvironment, Cell);
public:
explicit PrivateEnvironment(PrivateEnvironment* parent);
@ -36,7 +38,6 @@ public:
void add_private_name(Badge<ClassExpression>, FlyString description);
private:
virtual StringView class_name() const override { return "PrivateEnvironment"sv; }
virtual void visit_edges(Visitor&) override;
auto find_private_name(FlyString const& description) const

View file

@ -65,6 +65,8 @@ ThrowCompletionOr<PromiseCapability> new_promise_capability(VM& vm, Value constr
// 27.2.1.2 PromiseReaction Records, https://tc39.es/ecma262/#sec-promisereaction-records
class PromiseReaction final : public Cell {
JS_CELL(PromiseReaction, Cell);
public:
enum class Type {
Fulfill,
@ -86,7 +88,6 @@ public:
Optional<JobCallback> const& handler() const { return m_handler; }
private:
virtual StringView class_name() const override { return "PromiseReaction"sv; }
virtual void visit_edges(Visitor&) override;
Type m_type;

View file

@ -13,6 +13,8 @@
namespace JS {
struct RemainingElements final : public Cell {
JS_CELL(RemainingElements, Cell);
RemainingElements() = default;
explicit RemainingElements(u64 initial_value)
@ -20,12 +22,12 @@ struct RemainingElements final : public Cell {
{
}
virtual StringView class_name() const override { return "RemainingElements"sv; }
u64 value { 0 };
};
class PromiseValueList final : public Cell {
JS_CELL(PromiseValueList, Cell);
public:
PromiseValueList()
{
@ -35,7 +37,6 @@ public:
Vector<Value> const& values() const { return m_values; }
private:
virtual StringView class_name() const override { return "PromiseValueList"sv; }
virtual void visit_edges(Visitor&) override;
Vector<Value> m_values;

View file

@ -12,9 +12,9 @@
namespace JS {
struct AlreadyResolved final : public Cell {
bool value { false };
JS_CELL(AlreadyResolved, Cell);
virtual StringView class_name() const override { return "AlreadyResolved"sv; }
bool value { false };
protected:
// Allocated cells must be >= sizeof(FreelistEntry), which is 24 bytes -

View file

@ -20,6 +20,8 @@ namespace JS {
class Realm final
: public Cell
, public Weakable<Realm> {
JS_CELL(Realm, Cell);
public:
struct HostDefined {
virtual ~HostDefined() = default;
@ -47,7 +49,6 @@ public:
void set_host_defined(OwnPtr<HostDefined> host_defined) { m_host_defined = move(host_defined); }
private:
virtual StringView class_name() const override { return "Realm"sv; }
virtual void visit_edges(Visitor&) override;
Intrinsics* m_intrinsics { nullptr }; // [[Intrinsics]]

View file

@ -37,6 +37,8 @@ struct TransitionKey {
class Shape final
: public Cell
, public Weakable<Shape> {
JS_CELL(Shape, Cell);
public:
virtual ~Shape() override = default;
@ -84,7 +86,6 @@ public:
void reconfigure_property_in_unique_shape(StringOrSymbol const& property_key, PropertyAttributes attributes);
private:
virtual StringView class_name() const override { return "Shape"sv; }
virtual void visit_edges(Visitor&) override;
Shape* get_or_prune_cached_forward_transition(TransitionKey const&);

View file

@ -13,6 +13,7 @@
namespace JS {
class Symbol final : public Cell {
JS_CELL(Symbol, Cell);
AK_MAKE_NONCOPYABLE(Symbol);
AK_MAKE_NONMOVABLE(Symbol);
@ -26,8 +27,6 @@ public:
String to_string() const { return String::formatted("Symbol({})", description()); }
private:
virtual StringView class_name() const override { return "Symbol"sv; }
Optional<String> m_description;
bool m_is_global;
};