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

📄 init.c

📁 gcc的组件
💻 C
📖 第 1 页 / 共 2 页
字号:
      int module_initialized = 1;      for (statics_in_module = (*cell)->head;	   *statics_in_module; statics_in_module++)	{	  struct objc_static_instances *statics = *statics_in_module;	  Class class = objc_lookup_class (statics->class_name);	  if (! class)	    module_initialized = 0;	  /* Actually, the static's class_pointer will be NULL when we             haven't been here before.  However, the comparison is to be             reminded of taking into account class posing and to think about             possible semantics...  */	  else if (class != statics->instances[0]->class_pointer)	    {	      id *inst;	      for (inst = &statics->instances[0]; *inst; inst++)		{		  (*inst)->class_pointer = class;		  /* ??? Make sure the object will not be freed.  With                     refcounting, invoke `-retain'.  Without refcounting, do                     nothing and hope that `-free' will never be invoked.  */		  /* ??? Send the object an `-initStatic' or something to                     that effect now or later on?  What are the semantics of                     statically allocated instances, besides the trivial                     NXConstantString, anyway?  */		}	    }	}      if (module_initialized)	{	  /* Remove this module from the uninitialized list.  */	  struct objc_list *this = *cell;	  *cell = this->tail;	  objc_free (this);	}      else	cell = &(*cell)->tail;    }  objc_mutex_unlock (__objc_runtime_mutex);} /* objc_init_statics *//* This function is called by constructor functions generated for each   module compiled.  (_GLOBAL_$I$...) The purpose of this function is   to gather the module pointers so that they may be processed by the   initialization routines as soon as possible.  */void__objc_exec_class (Module_t module){  /* Have we processed any constructors previously?  This flag is used to     indicate that some global data structures need to be built.  */  static BOOL previous_constructors = 0;  static struct objc_list *unclaimed_categories = 0;  /* The symbol table (defined in objc-api.h) generated by gcc */  Symtab_t symtab = module->symtab;  /* The statics in this module */  struct objc_static_instances **statics    = symtab->defs[symtab->cls_def_cnt + symtab->cat_def_cnt];  /* Entry used to traverse hash lists */  struct objc_list **cell;  /* The table of selector references for this module */  SEL selectors = symtab->refs;   /* dummy counter */  int i;  DEBUG_PRINTF ("received module: %s\n", module->name);  /* check gcc version */  init_check_module_version (module);  /* On the first call of this routine, initialize some data structures.  */  if (! previous_constructors)    {	/* Initialize thread-safe system */      __objc_init_thread_system ();      __objc_runtime_threads_alive = 1;      __objc_runtime_mutex = objc_mutex_allocate ();      __objc_init_selector_tables ();      __objc_init_class_tables ();      __objc_init_dispatch_tables ();      __objc_class_tree_list = list_cons (NULL, __objc_class_tree_list);      __objc_load_methods = objc_hash_new (128, 					   (hash_func_type)objc_hash_ptr,					   objc_compare_ptrs);      previous_constructors = 1;    }  /* Save the module pointer for later processing. (not currently used) */  objc_mutex_lock (__objc_runtime_mutex);  __objc_module_list = list_cons (module, __objc_module_list);  /* Replace referenced selectors from names to SEL's.  */  if (selectors)    {      for (i = 0; selectors[i].sel_id; ++i)	{	  const char *name, *type;	  name = (char *) selectors[i].sel_id;	  type = (char *) selectors[i].sel_types;	  /* Constructors are constant static data so we can safely store	     pointers to them in the runtime structures. is_const == YES */	  __sel_register_typed_name (name, type, 				     (struct objc_selector *) &(selectors[i]),				     YES);	}    }  /* Parse the classes in the load module and gather selector information.  */  DEBUG_PRINTF ("gathering selectors from module: %s\n", module->name);  for (i = 0; i < symtab->cls_def_cnt; ++i)    {      Class class = (Class) symtab->defs[i];      const char *superclass = (char *) class->super_class;      /* Make sure we have what we think.  */      assert (CLS_ISCLASS (class));      assert (CLS_ISMETA (class->class_pointer));      DEBUG_PRINTF ("phase 1, processing class: %s\n", class->name);      /* Initialize the subclass list to be NULL.	 In some cases it isn't and this crashes the program.  */      class->subclass_list = NULL;      /* Store the class in the class table and assign class numbers.  */      __objc_add_class_to_hash (class);      /* Register all of the selectors in the class and meta class.  */      __objc_register_selectors_from_class (class);      __objc_register_selectors_from_class ((Class) class->class_pointer);      /* Install the fake dispatch tables */      __objc_install_premature_dtable (class);      __objc_install_premature_dtable (class->class_pointer);      /* Register the instance methods as class methods, this is	 only done for root classes.  */      __objc_register_instance_methods_to_class (class);      if (class->protocols)	__objc_init_protocols (class->protocols);      /* Check to see if the superclass is known in this point. If it's not	 add the class to the unresolved_classes list.  */      if (superclass && ! objc_lookup_class (superclass))	unresolved_classes = list_cons (class, unresolved_classes);   }  /* Process category information from the module.  */  for (i = 0; i < symtab->cat_def_cnt; ++i)    {      Category_t category = symtab->defs[i + symtab->cls_def_cnt];      Class class = objc_lookup_class (category->class_name);            /* If the class for the category exists then append its methods.  */      if (class)	{	  DEBUG_PRINTF ("processing categories from (module,object): %s, %s\n",			module->name,			class->name);	  /* Do instance methods.  */	  if (category->instance_methods)	    class_add_method_list (class, category->instance_methods);	  /* Do class methods.  */	  if (category->class_methods)	    class_add_method_list ((Class) class->class_pointer, 				   category->class_methods);	  if (category->protocols)	    {	      __objc_init_protocols (category->protocols);	      __objc_class_add_protocols (class, category->protocols);	    }          /* Register the instance methods as class methods, this is             only done for root classes.  */          __objc_register_instance_methods_to_class (class);	}      else	{	  /* The object to which the category methods belong can't be found.	     Save the information.  */	  unclaimed_categories = list_cons (category, unclaimed_categories);	}    }  if (statics)    uninitialized_statics = list_cons (statics, uninitialized_statics);  if (uninitialized_statics)    objc_init_statics ();  /* Scan the unclaimed category hash.  Attempt to attach any unclaimed     categories to objects.  */  for (cell = &unclaimed_categories; *cell; )    {      Category_t category = (*cell)->head;      Class class = objc_lookup_class (category->class_name);            if (class)	{	  DEBUG_PRINTF ("attaching stored categories to object: %s\n",			class->name);	  	  list_remove_head (cell);	  	  if (category->instance_methods)	    class_add_method_list (class, category->instance_methods);	  	  if (category->class_methods)	    class_add_method_list ((Class) class->class_pointer,				   category->class_methods);	  if (category->protocols)	    {	      __objc_init_protocols (category->protocols);	      __objc_class_add_protocols (class, category->protocols);	    }          /* Register the instance methods as class methods, this is             only done for root classes.  */          __objc_register_instance_methods_to_class (class);	}      else	cell = &(*cell)->tail;    }    if (unclaimed_proto_list && objc_lookup_class ("Protocol"))    {      list_mapcar (unclaimed_proto_list,		   (void (*) (void *))__objc_init_protocols);      list_free (unclaimed_proto_list);      unclaimed_proto_list = 0;    }  objc_send_load ();  objc_mutex_unlock (__objc_runtime_mutex);}static voidobjc_send_load (void){  if (! __objc_module_list)    return;   /* Try to find out if all the classes loaded so far also have their     superclasses known to the runtime. We suppose that the objects     that are allocated in the +load method are in general of a class     declared in the same module.  */  if (unresolved_classes)    {      Class class = unresolved_classes->head;      while (objc_lookup_class ((char *) class->super_class))	{	  list_remove_head (&unresolved_classes);	  if (unresolved_classes)	    class = unresolved_classes->head;	  else	    break;	}      /* If we still have classes for whom we don't have yet their         super classes known to the runtime we don't send the +load         messages.  */      if (unresolved_classes)	return;    }  /* Special check to allow creating and sending messages to constant     strings in +load methods. If these classes are not yet known,     even if all the other classes are known, delay sending of +load.  */  if (! objc_lookup_class ("NXConstantString") ||      ! objc_lookup_class ("Object"))    return;  /* Iterate over all modules in the __objc_module_list and call on     them the __objc_create_classes_tree function. This function     creates a tree of classes that resembles the class hierarchy.  */  list_mapcar (__objc_module_list,	       (void (*) (void *)) __objc_create_classes_tree);  while (__objc_class_tree_list)    {#ifdef DEBUG      objc_preorder_traverse (__objc_class_tree_list->head,			      0, __objc_tree_print);#endif      objc_preorder_traverse (__objc_class_tree_list->head,			      0, __objc_send_load);      objc_postorder_traverse (__objc_class_tree_list->head,			      0, __objc_destroy_class_tree_node);      list_remove_head (&__objc_class_tree_list);    }  list_mapcar (__objc_module_list, (void (*) (void *)) __objc_call_callback);  list_free (__objc_module_list);  __objc_module_list = NULL;}static void__objc_create_classes_tree (Module_t module){  /* The runtime mutex is locked in this point */  Symtab_t symtab = module->symtab;  int i;  /* Iterate thru classes defined in this module and insert them in     the classes tree hierarchy.  */  for (i = 0; i < symtab->cls_def_cnt; i++)    {      Class class = (Class) symtab->defs[i];      objc_tree_insert_class (class);    }}static void__objc_call_callback (Module_t module){  /* The runtime mutex is locked in this point.  */  Symtab_t symtab = module->symtab;  int i;  /* Iterate thru classes defined in this module and call the callback     for each one.  */  for (i = 0; i < symtab->cls_def_cnt; i++)    {      Class class = (Class) symtab->defs[i];      /* Call the _objc_load_callback for this class.  */      if (_objc_load_callback)	_objc_load_callback (class, 0);    }  /* Call the _objc_load_callback for categories. Don't register the     instance methods as class methods for categories to root classes     since they were already added in the class.  */  for (i = 0; i < symtab->cat_def_cnt; i++)    {      Category_t category = symtab->defs[i + symtab->cls_def_cnt];      Class class = objc_lookup_class (category->class_name);            if (_objc_load_callback)	_objc_load_callback (class, category);    }}/* Sanity check the version of gcc used to compile `module'.  */static voidinit_check_module_version (Module_t module){  if ((module->version != OBJC_VERSION) || (module->size != sizeof (Module)))    {      int code;      if (module->version > OBJC_VERSION)	code = OBJC_ERR_OBJC_VERSION;      else if (module->version < OBJC_VERSION)	code = OBJC_ERR_GCC_VERSION;      else	code = OBJC_ERR_MODULE_SIZE;      objc_error (nil, code, "Module %s version %d doesn't match runtime %d\n",		  module->name, (int)module->version, OBJC_VERSION);    }}static void__objc_init_protocols (struct objc_protocol_list *protos){  size_t i;  static Class proto_class = 0;  if (! protos)    return;  objc_mutex_lock (__objc_runtime_mutex);  if (! proto_class)    proto_class = objc_lookup_class ("Protocol");  if (! proto_class)    {      unclaimed_proto_list = list_cons (protos, unclaimed_proto_list);      objc_mutex_unlock (__objc_runtime_mutex);      return;    }#if 0  assert (protos->next == 0);	/* only single ones allowed */#endif  for (i = 0; i < protos->count; i++)    {      struct objc_protocol *aProto = protos->list[i];      if (((size_t)aProto->class_pointer) == PROTOCOL_VERSION)	{	  /* assign class pointer */	  aProto->class_pointer = proto_class;	  /* init super protocols */	  __objc_init_protocols (aProto->protocol_list);	}      else if (protos->list[i]->class_pointer != proto_class)	{	  objc_error (nil, OBJC_ERR_PROTOCOL_VERSION,		     "Version %d doesn't match runtime protocol version %d\n",		     (int) ((char *) protos->list[i]->class_pointer			    - (char *) 0),		     PROTOCOL_VERSION);	}    }  objc_mutex_unlock (__objc_runtime_mutex);}static void__objc_class_add_protocols (Class class, struct objc_protocol_list *protos){  /* Well...  */  if (! protos)    return;  /* Add it...  */  protos->next = class->protocols;  class->protocols = protos;}

⌨️ 快捷键说明

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