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

📄 core.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
  assert (initialized);  /* Objective-C allows messages to be sent to a nil object.  */  if (receiver) {    /* Check for common programmer error.  */    if (!receiver->class_pointer) {      fprintf (stderr, "method %s sent to deallocated object %#x\n", 	       sel_getName (sel), receiver);      abort ();    }        /* Initialize the class if need be.  */    if (!(receiver->class_pointer->info & CLS_INITIALIZED))      initialize_class (receiver->class_pointer->name);    /*     * If we're passed a object then its class_pointer is a Class.  If     * we're passed a Class then its class_pointer is a MetaClass.      * Therefore, searching for a instance or class method     * requires no special decision making here.      *     * Look for the method.      */    imp = get_imp (receiver->class_pointer, sel);    /* If the method cannot be found then perform error handling.  */    if (!imp)      imp = handle_runtime_error (receiver, sel);  }  /* Nice debugging messages if enabled.  */  if (objc_trace) {    printf ("trace: objc_msgSend , obj=%#x, class=%s, method=%s\n",	    receiver, 	    receiver->class_pointer->name, 	    sel_getName (sel));    fflush (stdout);  }    return imp;}IMP objc_msgSendSuper (Super_t super, SEL sel){  IMP	imp;  assert (initialized);  if (!(super->class->info & CLS_INITIALIZED))    initialize_class (super->class->name);  if (!(super->receiver->class_pointer->info & CLS_INITIALIZED))    initialize_class (super->receiver->class_pointer->name);  imp = get_imp (super->class, sel);    if (!imp)    imp = handle_runtime_error (super->receiver, sel);  if (objc_trace) {    printf ("trace: objc_msgSendSuper , obj=%#x, class=%s, method=%s\n",	    super->receiver, 	    super->receiver->class_pointer->name, 	    sel_getName (sel));    fflush (stdout);  }  return imp;}/* * This function is called by objc_msgSend or objc_msgSendSuper when a * message is sent to a object which it does not recognize.  */static IMP  handle_runtime_error (id object, SEL sel){  IMP	imp;  /*   * If the object recognizes the doesNotRecognize: method then we're   * going to send it.    */  imp = get_imp (object->class_pointer, sel_getUid ("doesNotRecognize:"));  if (imp)    error_static = (*imp)(object, sel_getUid ("doesNotRecognize:"), sel);  else {    /*     * The object doesn't recognize the method.  Check for     * responding to error:.  If it does then sent it.      */    char msg[256 + strlen (sel_getName (sel)) 	     + strlen (object->class_pointer->name)];            sprintf (msg, "%s does not recognize %s", 	     object->class_pointer->name, sel_getName (sel));            imp = get_imp (object->class_pointer, sel_getUid ("error:"));    if (imp)      error_static = (*imp)(object, sel_getUid ("error:"), msg);    else {      /*       * The object doesn't respond to doesNotRecognize: or       * error:;  Therefore, a default action is taken.        */      fprintf (stderr, "%s\n", msg);      abort ();    }  }  /*   * Either doesNotRecognize: or error: has been overridden.  We have   * to return that value as the default action.    */  return return_error_static;}/* * This function is used by the run-time to provide a method where nil * objects can receive messages.  * * This method simply returns self.  */static id  nil_method (id object, SEL sel, ...){  return object;}/* * This function is used by the run-time to provide a method where nil * objects can receive messages.  * * This method simply returns self.  * * Note: multiple thread problem area.  */static id  return_error_static (id object, SEL sel, ...){  return error_static;}/* * These variables provide a way for the defalut methods of object * allocation, destruction, and reallocation to be overridden.  */id    (*_alloc)(Class_t)                  = objc_object_create;id    (*_dealloc)(id)                     = objc_object_dispose;id    (*_realloc)(id, unsigned int)              = objc_object_realloc;id    (*_copy)(id)                        = objc_object_copy;void  (*_error)(id, const char*, va_list) = objc_error;id objc_object_create (Class_t class){  id     object;  assert (class);  /*   * Allocate memory for the object, initialize the memory to 0, and   * set the object's class_pointer.    *   * The object's class_pointer is the class's TEXT image.  It is used by   * the messager as the key to the class hash for methods.    *   * No need to initialize the class.  That was done in objcInit.    */  object = (id) xcalloc (1, class->instance_size);  object->class_pointer = class;  return object;}id  objc_object_dispose (id object){  object->class_pointer = NULL;  free (object);  return nil;}id  objc_object_realloc (id object, unsigned int length){  id  obj;  /* Can't resize a object smaller than its instance size.  */  /* Don't use assert here;     checks for user errors shouldn't depend on NDEBUG.  */  if (length < object->class_pointer->instance_size)    abort ();  obj = (id) realloc (object, length);  bzero ((char*)obj + object->class_pointer->instance_size,  	 length - object->class_pointer->instance_size);    return obj;}id  objc_object_copy (id object){  id  obj;  obj = class_createInstance (object->class_pointer);  bcopy (object, obj, objc_classSize (object));    return obj;}void  objc_error (id object, const char *fmt, va_list ap){  vfprintf (stderr, fmt, ap);  abort ();}/* Silly function to skip past a sequence of digits in a string.  */static inline const char *skip_digits (const char *str){  while (isdigit (*str))    ++str;  return str;}unsigned int method_getNumberOfArguments (Method_t method){  unsigned int       num = 0;  const char *args = &method->method_types[1];      while (*args) {      /* Skip past size info.  */    args = skip_digits (args);        /* Argument type next.  */    assert (*args);    ++num;        /* Step to next arg.  */    ++args;  }    assert (num >= 2);  return num;}unsigned int method_getArgumentInfo (Method_t method, int indx, const char **type, 			int *offset){  const char *args = skip_digits (&method->method_types[1]);  int         i;    assert (method_getNumberOfArguments (method) >= indx);  /* Step to arg.  */  for (i = 0; i < indx; ++i) {    ++args;    args = skip_digits (args);  }    /* Return arg data.  */  *type = args++;  *offset = atoi (args);    return indx;}/* This function is not thread safe.  */Ivar_t  object_getIvarAddress (id object, const char *name){  Class_t class = object->class_pointer; /* Here is the thread safe problem.  */  Ivar_t  ivar = NULL;    do {    IvarList_t  ivars = class->ivars;    int         i;          /* Look at all of the ivar names.  */    for (i = 0; i < ivars->ivar_count; ++i)      if (!strcmp (name, ivars->ivar_list[i].ivar_name))        ivar = &ivars->ivar_list[i];               /*     * If the ivar wasn't found then lets look to the     * super class.      *     * If the class is Object then the super class is NULL     * and we're done.      */    class = class->super_class;          } while (!ivar && class);  return ivar;}/* * Search for a method starting from the current class up its hierarchy.   * * Return a pointer to the method's method structure if found.  NULL otherwise.  */Method_t  searchForMethodInHierarchy (Class_t class, SEL sel){  Method_t  	method = NULL;  const char*	name;  if (sel == 0)    return NULL;  name = sel_getName (sel);  if (name == 0)    return NULL;  /*   * Scan the method list of the class.  If the method isn't found in   * the list then step to its super class.    */  do {        method = searchForMethodInList (class->methods, name);    class = class->super_class;  } while (!method && class);      return method;}/* * Given a linked list of method and a method's name.  Search for the named * method's method structure.  * * Return a pointer to the method's method structure if found.  NULL otherwise.  */Method_t  searchForMethodInList (MethodList_t list, const char *name){  MethodList_t  method_list = list;    /* Check for bumbling.  */  /* ??? Who generates the name?  Is it the user, or part of this file?     If we crash here, whose fault is it?  */  assert (name);  /* If not found then we'll search the list.  */  while (method_list) {    int   i;      /* Search the method list.  */    for (i = 0; i < method_list->method_count; ++i) {      Method_t method = &method_list->method_list[i];      if (method->method_name)	if (!strcmp (method->method_name, name))	  return method;    }            /* The method wasn't found.  Follow the link to the next list of        methods.  */    method_list = method_list->method_next;  }    return NULL;}/* * This function adds a method list to a class.   * * This function is typically called by another function specific to the * run-time.  As such this function does not worry about thread safe issued.   */void  addMethodsToClass (Class_t class, MethodList_t list){  int i;      /* Passing of a linked list is not allowed.  Do multiple calls.  */  assert (!list->method_next);  /* Check for duplicates.  */   for (i = 0; i < list->method_count; ++i) {    Method_t  method = &list->method_list[i];    if (method->method_name)	/* Sometimes these are NULL */      if (searchForMethodInList (class->methods, method->method_name)) {	/*	 * Duplication. Print a error message an change the	 * method name to NULL. 	 */	fprintf (stderr, "attempt to add a existing method: %s\n",		 method->method_name);	method->method_name = NULL;      }  }    /* Add the methods to the class's method list.  */  list->method_next = class->methods;  class->methods = list;}/* * This function removes the instance and factory methods in the passed list * from a class.   * * Methods are removed from a class by replacing the method's name with NULL.  * * * This function is typically called by another function specific to the * run-time.  As such this function does not worry about thread safe issued.   */void  class_removeMethods (Class_t class, MethodList_t method_list){  int i;      /* Passing of a linked list is not allowed.  Do multiple calls.  */  assert (!method_list->method_next);  /*   * For each method in the list search the method lists erasing any   * entries found. 

⌨️ 快捷键说明

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