⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gtype.c

📁 嵌入式下基于MiniGUI的Web Browser
💻 C
📖 第 1 页 / 共 5 页
字号:
/* GObject - GLib Type, Object, Parameter and Signal Library * Copyright (C) 1998-1999, 2000-2001 Tim Janik and Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General * Public License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */#include        "glibconfig.h"#include	"gtype.h"/* * MT safe */#include	"gtypeplugin.h"#include	"gvaluecollector.h"#include	<string.h>/* NOTE: some functions (some internal variants and exported ones) * invalidate data portions of the TypeNodes. if external functions/callbacks * are called, pointers to memory maintained by TypeNodes have to be looked up * again. this affects most of the struct TypeNode fields, e.g. ->children or * CLASSED_NODE_IFACES_ENTRIES() respectively IFACE_NODE_PREREQUISITES() (but * not ->supers[]), as all those memory portions can get realloc()ed during * callback invocation. * * TODO: * - g_type_from_name() should do an ordered array lookup after fetching the *   the quark, instead of a second hashtable lookup. * * LOCKING: * lock handling issues when calling static functions are indicated by * uppercase letter postfixes, all static functions have to have * one of the below postfixes: * - _I:	[Indifferent about locking] *   function doesn't care about locks at all * - _U:	[Unlocked invocation] *   no read or write lock has to be held across function invocation *   (locks may be acquired and released during invocation though) * - _L:	[Locked invocation] *   a write lock or more than 0 read locks have to be held across *   function invocation * - _W:	[Write-locked invocation] *   a write lock has to be held across function invokation * - _Wm:	[Write-locked invocation, mutatable] *   like _W, but the write lock might be released and reacquired *   during invocation, watch your pointers */static GStaticRWLock            type_rw_lock = G_STATIC_RW_LOCK_INIT;#ifdef LOCK_DEBUG#define G_READ_LOCK(rw_lock)    do { g_printerr (G_STRLOC ": readL++\n"); g_static_rw_lock_reader_lock (rw_lock); } while (0)#define G_READ_UNLOCK(rw_lock)  do { g_printerr (G_STRLOC ": readL--\n"); g_static_rw_lock_reader_unlock (rw_lock); } while (0)#define G_WRITE_LOCK(rw_lock)   do { g_printerr (G_STRLOC ": writeL++\n"); g_static_rw_lock_writer_lock (rw_lock); } while (0)#define G_WRITE_UNLOCK(rw_lock) do { g_printerr (G_STRLOC ": writeL--\n"); g_static_rw_lock_writer_unlock (rw_lock); } while (0)#else#define G_READ_LOCK(rw_lock)    g_static_rw_lock_reader_lock (rw_lock)#define G_READ_UNLOCK(rw_lock)  g_static_rw_lock_reader_unlock (rw_lock)#define G_WRITE_LOCK(rw_lock)   g_static_rw_lock_writer_lock (rw_lock)#define G_WRITE_UNLOCK(rw_lock) g_static_rw_lock_writer_unlock (rw_lock)#endif#define	INVALID_RECURSION(func, arg, type_name) G_STMT_START{ \    static const gchar *_action = " invalidly modified type "; \    gpointer _arg = (gpointer) (arg); const gchar *_tname = (type_name), *_fname = (func); \    if (_arg) \      g_error ("%s(%p)%s`%s'", _fname, _arg, _action, _tname); \    else \      g_error ("%s()%s`%s'", _fname, _action, _tname); \}G_STMT_END#define	g_return_val_if_uninitialized(condition, init_function, return_value) G_STMT_START{	\  if (!(condition))										\    {												\      g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,						\	     "%s: initialization assertion failed, use %s() prior to this function",		\	     G_STRLOC, G_STRINGIFY (init_function));						\      return (return_value);									\    }												\}G_STMT_END#ifdef  G_ENABLE_DEBUG#define DEBUG_CODE(debug_type, code_block)  G_STMT_START {    \    if (_g_type_debug_flags & G_TYPE_DEBUG_ ## debug_type) \      { code_block; }                                     \} G_STMT_END#else /* !G_ENABLE_DEBUG */#define DEBUG_CODE(debug_type, code_block)  /* code_block */#endif  /* G_ENABLE_DEBUG */#define TYPE_FUNDAMENTAL_FLAG_MASK (G_TYPE_FLAG_CLASSED | \				    G_TYPE_FLAG_INSTANTIATABLE | \				    G_TYPE_FLAG_DERIVABLE | \				    G_TYPE_FLAG_DEEP_DERIVABLE)#define	TYPE_FLAG_MASK		   (G_TYPE_FLAG_ABSTRACT | G_TYPE_FLAG_VALUE_ABSTRACT)#define	SIZEOF_FUNDAMENTAL_INFO	   ((gssize) MAX (MAX (sizeof (GTypeFundamentalInfo), \						       sizeof (gpointer)), \                                                  sizeof (glong)))/* --- typedefs --- */typedef struct _TypeNode        TypeNode;typedef struct _CommonData      CommonData;typedef struct _IFaceData       IFaceData;typedef struct _ClassData       ClassData;typedef struct _InstanceData    InstanceData;typedef union  _TypeData        TypeData;typedef struct _IFaceEntry      IFaceEntry;typedef struct _IFaceHolder	IFaceHolder;/* --- prototypes --- */static inline GTypeFundamentalInfo*	type_node_fundamental_info_I	(TypeNode		*node);static	      void			type_add_flags_W		(TypeNode		*node,									 GTypeFlags		 flags);static	      void			type_data_make_W		(TypeNode		*node,									 const GTypeInfo	*info,									 const GTypeValueTable	*value_table);static inline void			type_data_ref_Wm		(TypeNode		*node);static inline void			type_data_unref_Wm		(TypeNode		*node,									 gboolean		 uncached);static void				type_data_last_unref_Wm		(GType			 type,									 gboolean		 uncached);static inline gpointer			type_get_qdata_L		(TypeNode		*node,									 GQuark			 quark);static inline void			type_set_qdata_W		(TypeNode		*node,									 GQuark			 quark,									 gpointer		 data);static IFaceHolder*			type_iface_peek_holder_L	(TypeNode		*iface,									 GType			 instance_type);static gboolean				type_node_is_a_L		(TypeNode		*node,									 TypeNode		*iface_node);/* --- structures --- */struct _TypeNode{  GTypePlugin *plugin;  guint        n_children : 12;  guint        n_supers : 8;  guint        _prot_n_ifaces_prerequisites : 9;  guint        is_classed : 1;  guint        is_instantiatable : 1;  guint        mutatable_check_cache : 1;	/* combines some common path checks */  GType       *children;  TypeData * volatile data;  GQuark       qname;  GData       *global_gdata;  union {    IFaceEntry  *iface_entries;		/* for !iface types */    GType       *prerequisistes;  } _prot;  GType        supers[1]; /* flexible array */};#define SIZEOF_BASE_TYPE_NODE()			(G_STRUCT_OFFSET (TypeNode, supers))#define MAX_N_SUPERS				(255)#define MAX_N_CHILDREN				(4095)#define MAX_N_IFACES				(511)#define	MAX_N_PREREQUISITES			(MAX_N_IFACES)#define NODE_TYPE(node)				(node->supers[0])#define NODE_PARENT_TYPE(node)			(node->supers[1])#define NODE_FUNDAMENTAL_TYPE(node)		(node->supers[node->n_supers])#define NODE_NAME(node)				(g_quark_to_string (node->qname))#define	NODE_IS_IFACE(node)			(NODE_FUNDAMENTAL_TYPE (node) == G_TYPE_INTERFACE)#define	CLASSED_NODE_N_IFACES(node)		((node)->_prot_n_ifaces_prerequisites)#define	CLASSED_NODE_IFACES_ENTRIES(node)	((node)->_prot.iface_entries)#define	IFACE_NODE_N_PREREQUISITES(node)	((node)->_prot_n_ifaces_prerequisites)#define	IFACE_NODE_PREREQUISITES(node)		((node)->_prot.prerequisistes)#define	iface_node_get_holders_L(node)		((IFaceHolder*) type_get_qdata_L ((node), static_quark_iface_holder))#define	iface_node_set_holders_W(node, holders)	(type_set_qdata_W ((node), static_quark_iface_holder, (holders)))#define	iface_node_get_dependants_array_L(n)	((GType*) type_get_qdata_L ((n), static_quark_dependants_array))#define	iface_node_set_dependants_array_W(n,d)	(type_set_qdata_W ((n), static_quark_dependants_array, (d)))#define	TYPE_ID_MASK				((GType) ((1 << G_TYPE_FUNDAMENTAL_SHIFT) - 1))struct _IFaceHolder{  GType           instance_type;  GInterfaceInfo *info;  GTypePlugin    *plugin;  IFaceHolder    *next;};struct _IFaceEntry{  GType           iface_type;  GTypeInterface *vtable;};struct _CommonData{  guint             ref_count;  GTypeValueTable  *value_table;};struct _IFaceData{  CommonData         common;  guint16            vtable_size;  GBaseInitFunc      vtable_init_base;  GBaseFinalizeFunc  vtable_finalize_base;};struct _ClassData{  CommonData         common;  guint16            class_size;  GBaseInitFunc      class_init_base;  GBaseFinalizeFunc  class_finalize_base;  GClassInitFunc     class_init;  GClassFinalizeFunc class_finalize;  gconstpointer      class_data;  gpointer           class;};struct _InstanceData{  CommonData         common;  guint16            class_size;  GBaseInitFunc      class_init_base;  GBaseFinalizeFunc  class_finalize_base;  GClassInitFunc     class_init;  GClassFinalizeFunc class_finalize;  gconstpointer      class_data;  gpointer           class;  guint16            instance_size;  guint16            n_preallocs;  GInstanceInitFunc  instance_init;  GMemChunk        *mem_chunk;};union _TypeData{  CommonData         common;  IFaceData          iface;  ClassData          class;  InstanceData       instance;};typedef struct {  gpointer            cache_data;  GTypeClassCacheFunc cache_func;} ClassCacheFunc;/* --- variables --- */static guint           static_n_class_cache_funcs = 0;static ClassCacheFunc *static_class_cache_funcs = NULL;static GQuark          static_quark_type_flags = 0;static GQuark          static_quark_iface_holder = 0;static GQuark          static_quark_dependants_array = 0;GTypeDebugFlags	       _g_type_debug_flags = 0;/* --- type nodes --- */static GHashTable       *static_type_nodes_ht = NULL;static TypeNode		*static_fundamental_type_nodes[(G_TYPE_FUNDAMENTAL_MAX >> G_TYPE_FUNDAMENTAL_SHIFT) + 1] = { 0, };static GType		 static_fundamental_next = G_TYPE_RESERVED_USER_FIRST;static inline TypeNode*lookup_type_node_I (register GType utype){  if (utype > G_TYPE_FUNDAMENTAL_MAX)    return (TypeNode*) (utype & ~TYPE_ID_MASK);  else    return static_fundamental_type_nodes[utype >> G_TYPE_FUNDAMENTAL_SHIFT];}static TypeNode*type_node_any_new_W (TypeNode             *pnode,		     GType                 ftype,		     const gchar          *name,		     GTypePlugin          *plugin,		     GTypeFundamentalFlags type_flags){  guint n_supers;  GType type;  TypeNode *node;  guint i, node_size = 0;    n_supers = pnode ? pnode->n_supers + 1 : 0;    if (!pnode)    node_size += SIZEOF_FUNDAMENTAL_INFO;	      /* fundamental type info */  node_size += SIZEOF_BASE_TYPE_NODE ();	      /* TypeNode structure */  node_size += (sizeof (GType) * (1 + n_supers + 1)); /* self + ancestors + (0) for ->supers[] */  node = g_malloc0 (node_size);  if (!pnode)					      /* offset fundamental types */    {      node = G_STRUCT_MEMBER_P (node, SIZEOF_FUNDAMENTAL_INFO);      static_fundamental_type_nodes[ftype >> G_TYPE_FUNDAMENTAL_SHIFT] = node;      type = ftype;    }  else    type = (GType) node;    g_assert ((type & TYPE_ID_MASK) == 0);    node->n_supers = n_supers;  if (!pnode)    {      node->supers[0] = type;      node->supers[1] = 0;            node->is_classed = (type_flags & G_TYPE_FLAG_CLASSED) != 0;      node->is_instantiatable = (type_flags & G_TYPE_FLAG_INSTANTIATABLE) != 0;            if (NODE_IS_IFACE (node))	{          IFACE_NODE_N_PREREQUISITES (node) = 0;	  IFACE_NODE_PREREQUISITES (node) = NULL;	}      else	{	  CLASSED_NODE_N_IFACES (node) = 0;	  CLASSED_NODE_IFACES_ENTRIES (node) = NULL;	}    }  else    {      node->supers[0] = type;      memcpy (node->supers + 1, pnode->supers, sizeof (GType) * (1 + pnode->n_supers + 1));            node->is_classed = pnode->is_classed;      node->is_instantiatable = pnode->is_instantiatable;            if (NODE_IS_IFACE (node))	{	  IFACE_NODE_N_PREREQUISITES (node) = 0;	  IFACE_NODE_PREREQUISITES (node) = NULL;	}      else	{	  guint j;	  	  CLASSED_NODE_N_IFACES (node) = CLASSED_NODE_N_IFACES (pnode);	  CLASSED_NODE_IFACES_ENTRIES (node) = g_memdup (CLASSED_NODE_IFACES_ENTRIES (pnode),							 sizeof (CLASSED_NODE_IFACES_ENTRIES (pnode)[0]) *							 CLASSED_NODE_N_IFACES (node));	  for (j = 0; j < CLASSED_NODE_N_IFACES (node); j++)	    CLASSED_NODE_IFACES_ENTRIES (node)[j].vtable = NULL;	}            i = pnode->n_children++;      pnode->children = g_renew (GType, pnode->children, pnode->n_children);      pnode->children[i] = type;    }    node->plugin = plugin;  node->n_children = 0;  node->children = NULL;  node->data = NULL;  node->qname = g_quark_from_string (name);  node->global_gdata = NULL;    g_hash_table_insert (static_type_nodes_ht,		       GUINT_TO_POINTER (node->qname),		       (gpointer) type);  return node;}static inline GTypeFundamentalInfo*type_node_fundamental_info_I (TypeNode *node){  GType ftype = NODE_FUNDAMENTAL_TYPE (node);    if (ftype != NODE_TYPE (node))    node = lookup_type_node_I (ftype);    return node ? G_STRUCT_MEMBER_P (node, -SIZEOF_FUNDAMENTAL_INFO) : NULL;}static TypeNode*type_node_fundamental_new_W (GType                 ftype,			     const gchar          *name,			     GTypeFundamentalFlags type_flags){  GTypeFundamentalInfo *finfo;  TypeNode *node;    g_assert ((ftype & TYPE_ID_MASK) == 0);  g_assert (ftype <= G_TYPE_FUNDAMENTAL_MAX);    if (ftype >> G_TYPE_FUNDAMENTAL_SHIFT == static_fundamental_next)    static_fundamental_next++;    type_flags &= TYPE_FUNDAMENTAL_FLAG_MASK;    node = type_node_any_new_W (NULL, ftype, name, NULL, type_flags);    finfo = type_node_fundamental_info_I (node);  finfo->type_flags = type_flags;    return node;}static TypeNode*type_node_new_W (TypeNode    *pnode,		 const gchar *name,		 GTypePlugin *plugin)     {  g_assert (pnode);  g_assert (pnode->n_supers < MAX_N_SUPERS);  g_assert (pnode->n_children < MAX_N_CHILDREN);    return type_node_any_new_W (pnode, NODE_FUNDAMENTAL_TYPE (pnode), name, plugin, 0);}static inline IFaceEntry*type_lookup_iface_entry_L (TypeNode *node,			   TypeNode *iface_node){  if (NODE_IS_IFACE (iface_node) && CLASSED_NODE_N_IFACES (node))    {      IFaceEntry *ifaces = CLASSED_NODE_IFACES_ENTRIES (node) - 1;      guint n_ifaces = CLASSED_NODE_N_IFACES (node);      GType iface_type = NODE_TYPE (iface_node);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -