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

📄 init.c

📁 GCC编译器源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		  /* ??? 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	  = hash_new (128, (hash_func_type)hash_ptr, 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;       ({ if (*cell) cell = &(*cell)->tail; }))    {      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);	}    }    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 void objc_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 void init_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){  int 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 + -