/* * Copyright (c) 2022, Andrew Kaster * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include #include #include namespace Web::Bindings { class Intrinsics final : public JS::Cell { JS_CELL(Intrinsics, JS::Cell); public: Intrinsics(JS::Realm& realm) : m_realm(realm) { } JS::Object& cached_web_prototype(DeprecatedString const& class_name); template JS::Object& ensure_web_prototype(DeprecatedString const& class_name) { auto it = m_prototypes.find(class_name); if (it != m_prototypes.end()) return *it->value; auto& realm = *m_realm; auto* prototype = heap().allocate(realm, realm); m_prototypes.set(class_name, prototype); return *prototype; } template JS::NativeFunction& ensure_web_constructor(DeprecatedString const& class_name) { auto it = m_constructors.find(class_name); if (it != m_constructors.end()) return *it->value; auto& realm = *m_realm; auto* constructor = heap().allocate(realm, realm); m_constructors.set(class_name, constructor); return *constructor; } private: virtual void visit_edges(JS::Cell::Visitor&) override; HashMap m_prototypes; HashMap m_constructors; JS::NonnullGCPtr m_realm; }; [[nodiscard]] inline Intrinsics& host_defined_intrinsics(JS::Realm& realm) { return *verify_cast(realm.host_defined())->intrinsics; } template [[nodiscard]] JS::Object& ensure_web_prototype(JS::Realm& realm, DeprecatedString const& class_name) { return host_defined_intrinsics(realm).ensure_web_prototype(class_name); } template [[nodiscard]] JS::NativeFunction& ensure_web_constructor(JS::Realm& realm, DeprecatedString const& class_name) { return host_defined_intrinsics(realm).ensure_web_constructor(class_name); } [[nodiscard]] inline JS::Object& cached_web_prototype(JS::Realm& realm, DeprecatedString const& class_name) { return host_defined_intrinsics(realm).cached_web_prototype(class_name); } }