/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ // SPDX-License-Identifier: MIT OR LGPL-2.0-or-later // SPDX-FileCopyrightText: 2013 Intel Corporation // SPDX-FileCopyrightText: 2008-2010 litl, LLC #ifndef GI_FUNDAMENTAL_H_ #define GI_FUNDAMENTAL_H_ #include #include #include #include #include "gi/cwrapper.h" #include "gi/wrapperutils.h" #include "gjs/jsapi-util.h" // for GjsAutoCallableInfo #include "gjs/macros.h" #include "util/log.h" class FundamentalPrototype; class FundamentalInstance; namespace JS { class CallArgs; } /* To conserve memory, we have two different kinds of private data for JS * wrappers for fundamental types: FundamentalInstance, and * FundamentalPrototype. Both inherit from FundamentalBase for their common * functionality. For more information, see the notes in wrapperutils.h. */ class FundamentalBase : public GIWrapperBase { friend class CWrapperPointerOps; friend class GIWrapperBase; protected: explicit FundamentalBase(FundamentalPrototype* proto = nullptr) : GIWrapperBase(proto) {} static constexpr GjsDebugTopic DEBUG_TOPIC = GJS_DEBUG_GFUNDAMENTAL; static constexpr const char* DEBUG_TAG = "fundamental"; static const struct JSClassOps class_ops; static const struct JSClass klass; // Public API public: GJS_JSAPI_RETURN_CONVENTION static bool to_gvalue(JSContext* cx, JS::HandleObject obj, GValue* gvalue); }; class FundamentalPrototype : public GIWrapperPrototype { friend class GIWrapperPrototype; friend class GIWrapperBase; GIObjectInfoRefFunction m_ref_function; GIObjectInfoUnrefFunction m_unref_function; GIObjectInfoGetValueFunction m_get_value_function; GIObjectInfoSetValueFunction m_set_value_function; GjsAutoCallableInfo m_constructor_info; explicit FundamentalPrototype(GIObjectInfo* info, GType gtype); ~FundamentalPrototype(void); static constexpr InfoType::Tag info_type_tag = InfoType::Object; public: GJS_JSAPI_RETURN_CONVENTION static FundamentalPrototype* for_gtype(JSContext* cx, GType gtype); // Accessors [[nodiscard]] GICallableInfo* constructor_info() const { return m_constructor_info; } void* call_ref_function(void* ptr) const { if (!m_ref_function) return ptr; return m_ref_function(ptr); } void call_unref_function(void* ptr) const { if (m_unref_function) m_unref_function(ptr); } [[nodiscard]] bool call_get_value_function(const GValue* value, void** ptr_out) const { if (!m_get_value_function) return false; *ptr_out = m_get_value_function(value); return true; } bool call_set_value_function(GValue* value, void* object) const { if (m_set_value_function) { m_set_value_function(value, object); return true; } return false; } // Helper methods private: GJS_JSAPI_RETURN_CONVENTION bool get_parent_proto(JSContext* cx, JS::MutableHandleObject proto) const; [[nodiscard]] unsigned constructor_nargs() const; GJS_JSAPI_RETURN_CONVENTION bool resolve_interface(JSContext* cx, JS::HandleObject obj, bool* resolved, const char* name); // JSClass operations GJS_JSAPI_RETURN_CONVENTION bool resolve_impl(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* resolved); // Public API public: GJS_JSAPI_RETURN_CONVENTION static bool define_class(JSContext* cx, JS::HandleObject in_object, GIObjectInfo* info, JS::MutableHandleObject constructor); }; class FundamentalInstance : public GIWrapperInstance { friend class FundamentalBase; // for set_value() friend class GIWrapperInstance; friend class GIWrapperBase; explicit FundamentalInstance(FundamentalPrototype* prototype, JS::HandleObject obj); ~FundamentalInstance(void); // Helper methods GJS_JSAPI_RETURN_CONVENTION bool invoke_constructor(JSContext* cx, JS::HandleObject obj, const JS::CallArgs& args, GIArgument* rvalue); void ref(void) { get_prototype()->call_ref_function(m_ptr); } void unref(void) { get_prototype()->call_unref_function(m_ptr); } [[nodiscard]] bool set_value(GValue* gvalue) const { return get_prototype()->call_set_value_function(gvalue, m_ptr); } GJS_JSAPI_RETURN_CONVENTION bool associate_js_instance(JSContext* cx, JSObject* object, void* gfundamental); // JS constructor GJS_JSAPI_RETURN_CONVENTION bool constructor_impl(JSContext* cx, JS::HandleObject obj, const JS::CallArgs& args); public: GJS_JSAPI_RETURN_CONVENTION static JSObject* object_for_c_ptr(JSContext* cx, void* gfundamental); GJS_JSAPI_RETURN_CONVENTION static bool object_for_gvalue(JSContext* cx, const GValue* gvalue, GType gtype, JS::MutableHandleObject object_out); static void* copy_ptr(JSContext* cx, GType gtype, void* gfundamental); }; #endif // GI_FUNDAMENTAL_H_