示例#1
0
BOOL 
class_addProtocol (Class class_, Protocol *protocol)
{
  struct objc_protocol_list *protocols;

  if (class_ == Nil  ||  protocol == NULL)
    return NO;

  if (class_conformsToProtocol (class_, protocol))
    return NO;

  /* Check that it is a Protocol object before casting it to (struct
     objc_protocol *).  */
  if (protocol->class_pointer != objc_lookUpClass ("Protocol"))
    return NO;

  objc_mutex_lock (__objc_runtime_mutex);

  /* Create the objc_protocol_list.  */
  protocols = malloc (sizeof (struct objc_protocol_list));
  protocols->count = 1;
  protocols->list[0] = (struct objc_protocol *)protocol;

  /* Attach it to the list of class protocols.  */
  protocols->next = class_->protocols;
  class_->protocols = protocols;

  objc_mutex_unlock (__objc_runtime_mutex);

  return YES;
}
示例#2
0
struct objc_method_description *protocol_copyMethodDescriptionList (Protocol *protocol,
								    BOOL requiredMethod,
								    BOOL instanceMethod,
								    unsigned int *numberOfReturnedMethods)
{
  struct objc_method_description_list *methods;
  unsigned int count = 0;
  struct objc_method_description *returnValue = NULL;

  /* TODO: New ABI */
  /* The current ABI does not have any information on optional protocol methods.  */
  if (! requiredMethod)
    {
      if (numberOfReturnedMethods)
	*numberOfReturnedMethods = 0;

      return NULL;
    }

  /* Check that it is a Protocol object before casting it to (struct
     objc_protocol *).  */
  if (protocol == NULL  ||  protocol->class_pointer != objc_lookUpClass ("Protocol"))
    {
      if (numberOfReturnedMethods)
	*numberOfReturnedMethods = 0;

      return NULL;
    }
  
  /* We do not acquire any lock because protocols are currently
     immutable.  We can freely iterate over a protocol structure.  */

  if (instanceMethod)
    methods = ((struct objc_protocol *)protocol)->instance_methods;
  else
    methods = ((struct objc_protocol *)protocol)->class_methods;

  if (methods)
    {
      unsigned int i;
      count = methods->count;

      /* Allocate enough memory to hold them.  */
      returnValue = (struct objc_method_description *)(malloc (sizeof (struct objc_method_description) * (count + 1)));

      /* Copy them.  */
      for (i = 0; i < count; i++)
	{
	  returnValue[i].name = methods->list[i].name;
	  returnValue[i].types = methods->list[i].types;
	}
      returnValue[i].name = NULL;
      returnValue[i].types = NULL;
    }

  if (numberOfReturnedMethods)
    *numberOfReturnedMethods = count;

  return returnValue;
}
示例#3
0
Property *protocol_copyPropertyList (Protocol *protocol, unsigned int *numberOfReturnedProperties)
{
  unsigned int count = 0;
  Property *returnValue = NULL;

  /* Check that it is a Protocol object before casting it to (struct
     objc_protocol *).  */
  if (protocol == NULL  ||  protocol->class_pointer != objc_lookUpClass ("Protocol"))
    {
      if (numberOfReturnedProperties)
	*numberOfReturnedProperties = 0;

      return NULL;
    }
  
  /* We do not acquire any lock because protocols are currently
     immutable.  We can freely iterate over a protocol structure.  */

  /* TODO: New ABI.  */
  /* The current ABI does not have any information on protocol properties.  */
  if (numberOfReturnedProperties)
    *numberOfReturnedProperties = count;

  return returnValue;
}
示例#4
0
int SDL_main(int argc, char *argv[])
{
  int i;
 
#ifdef __APPLE__
  void * pool = objc_msgSend((id)objc_lookUpClass("NSAutoreleasePool"), sel_getUid("alloc"));
  objc_msgSend(pool, sel_getUid("init"));
#endif
 
  hs_init(&argc, &argv);

#ifdef __GLASGOW_HASKELL__
  hs_add_root(__stginit_RectanglesMain);
#endif
 
  rectangles_main();
 
  hs_exit();

#ifdef __APPLE__
  objc_msgSend(pool, sel_getUid("release"));
#endif
  
  return 0;
}
示例#5
0
void
objc_registerClassPair(Class cls)
{
  Class metaClass;
  Class	existing;

  if (Nil == cls)
    {
      fprintf(stderr, "*** ERROR *** function objc_registerClassPair() called "
	"on Nil class pair '%s'\n", class_getName(cls));
    }
  existing = (Class)objc_lookUpClass (class_getName (cls));
  if (existing == cls)
    {
      return;	// Already registered
    }
  else if (Nil != existing)
    {
      fprintf(stderr, "*** ERROR *** function objc_registerClassPair() called "
	"for class pair with name ('%s') of existing class.\n",
	class_getName(cls));
      return;
    }

  // Initialize the dispatch table for the class and metaclass.
  metaClass = cls->class_pointer;
  __objc_update_dispatch_table_for_class(metaClass);
  __objc_update_dispatch_table_for_class(cls);
  __objc_add_class_to_hash(cls);
  // Add pointer from super class
  __objc_resolve_class_links();
}
示例#6
0
Class objc_allocateClassPair(Class superclass, const char *name, size_t extraBytes)
{
	// Check the class doesn't already exist.
	if (nil != objc_lookUpClass(name)) { return Nil; }

	Class newClass = gc->malloc(sizeof(struct objc_class) + extraBytes);

	if (Nil == newClass) { return Nil; }

	// Create the metaclass
	Class metaClass = gc->malloc(sizeof(struct objc_class));

	if (Nil == superclass)
	{
		/*
		 * Metaclasses of root classes are precious little flowers and work a
		 * little differently:
		 */
		metaClass->isa = metaClass;
		metaClass->super_class = newClass;
	}
	else
	{
		// Initialize the metaclass
		// Set the meta-metaclass pointer to the name.  The runtime will fix this
		// in objc_resolve_class().
		// If the superclass is not yet resolved, then we need to look it up
		// via the class table.
		metaClass->isa = (Class)superclass->isa->isa->name;
		metaClass->super_class = superclass->isa;
	}
	metaClass->name = strdup(name);
	metaClass->info = objc_class_flag_meta | objc_class_flag_user_created |
		objc_class_flag_new_abi;
	metaClass->dtable = uninstalled_dtable;
	metaClass->instance_size = sizeof(struct objc_class);

	// Set up the new class
	newClass->isa = metaClass;
	// Set the superclass pointer to the name.  The runtime will fix this when
	// the class links are resolved.
	newClass->super_class = (Nil == superclass) ? Nil : (Class)(superclass->name);

	newClass->name = strdup(name);
	newClass->info = objc_class_flag_class | objc_class_flag_user_created |
		objc_class_flag_new_abi;
	newClass->dtable = uninstalled_dtable;

	if (Nil == superclass)
	{
		newClass->instance_size = sizeof(struct objc_class);
	}
	else
	{
		newClass->instance_size = superclass->instance_size;
	}

	return newClass;
}
示例#7
0
const char *
protocol_getName (Protocol *protocol)
{
  /* Check that it is a Protocol object before casting it to (struct
     objc_protocol *).  */
  if (protocol->class_pointer != objc_lookUpClass ("Protocol"))
    return NULL;

  return ((struct objc_protocol *)protocol)->protocol_name;
}
示例#8
0
Property protocol_getProperty (Protocol *protocol, const char *propertyName, 
			       BOOL requiredProperty, BOOL instanceProperty)
{
  if (protocol == NULL  ||  propertyName == NULL)
    return NULL;

  if (!requiredProperty  ||  !instanceProperty)
    return NULL;

  /* Check that it is a Protocol object before casting it to (struct
     objc_protocol *).  */
  if (protocol->class_pointer != objc_lookUpClass ("Protocol"))
    return NULL;

  /* TODO: New ABI.  */
  /* The current ABI does not have any information on protocol properties.  */
  return NULL;
}
示例#9
0
void
objc_disposeClassPair(Class cls)
{
  Class meta;

  if (cls == 0)
    {
      return;
    }
  meta = ((id) cls)->isa;

  if (objc_lookUpClass (class_getName (cls)) == (id)cls)
    {
      fprintf(stderr, "*** ERROR *** function objc_disposeClassPair() called "
	"on registered class pair '%s'\n", class_getName(cls));
      return;
    /*
       The runtime provides no mechanism to remove a class.
       The following code essentially frees the memory used by a class without
       fully removing it ... which obviously tends to cause random crashes
       later on if anything tries to use the class or to traverse data
       structures containing the class.
       Indeed, it's hard to see how this function could ever be made to work
       (what if there are subclasses of the class being removed, or if
       there are instances of the class?) even with changes to the runtime.
      
      // Remove from the runtime system so nothing tries updating the dtable
      // while we are freeing the class.
      objc_mutex_lock(__objc_runtime_mutex);
      safe_remove_from_subclass_list(meta);
      safe_remove_from_subclass_list(cls);
      objc_mutex_unlock(__objc_runtime_mutex);
    */
    }

  // Free the method and ivar lists.
  freeMethodLists(cls);
  freeMethodLists(meta);
  freeIvarLists(cls);

  // Free the class and metaclass
  free(meta);
  free(cls);
}
示例#10
0
Class
objc_allocateClassPair(Class superclass, const char *name, size_t extraBytes)
{
  Class newClass;
  Class metaClass;

  // Check the class doesn't already exist.
  if (nil != objc_lookUpClass(name))
    {
      return Nil;
    }

  newClass = calloc(1, sizeof(struct objc_class) + extraBytes);

  if (Nil == newClass)
    {
      return Nil;
    }

  // Create the metaclass
  metaClass = calloc(1, sizeof(struct objc_class));

  // Initialize the metaclass
  metaClass->class_pointer = superclass->class_pointer->class_pointer;
  metaClass->super_class = superclass->class_pointer;
  metaClass->name = strdup(name);
  metaClass->info = _CLS_META;
  metaClass->dtable = __objc_uninstalled_dtable;
  metaClass->instance_size = sizeof(struct objc_class);

  // Set up the new class
  newClass->class_pointer = metaClass;
  // Set the superclass pointer to the name.  The runtime will fix this when
  // the class links are resolved.
  newClass->super_class = (Class) superclass->name;
  newClass->name = strdup(name);
  newClass->info = _CLS_CLASS;
  newClass->dtable = __objc_uninstalled_dtable;
  newClass->instance_size = superclass->instance_size;

  return newClass;
}
示例#11
0
BOOL 
protocol_conformsToProtocol (Protocol *protocol, Protocol *anotherProtocol)
{
  struct objc_protocol_list* proto_list;

  if (protocol == NULL  ||  anotherProtocol == NULL)
    return NO;

  if (protocol == anotherProtocol)
    return YES;
    
  /* Check that the objects are Protocol objects before casting them
     to (struct objc_protocol *).  */
  if (protocol->class_pointer != anotherProtocol->class_pointer)
    return NO;
  
  if (protocol->class_pointer != objc_lookUpClass ("Protocol"))
    return NO;

  if (strcmp (((struct objc_protocol *)protocol)->protocol_name,
	      ((struct objc_protocol *)anotherProtocol)->protocol_name) == 0)
    return YES;

  /* We do not acquire any lock because protocols are currently
     immutable.  We can freely iterate over a protocol structure.  */
  proto_list = ((struct objc_protocol *)protocol)->protocol_list;
  while (proto_list)
    {
      size_t i;
      
      for (i = 0; i < proto_list->count; i++)
	{
	  if (protocol_conformsToProtocol ((Protocol *)proto_list->list[i], anotherProtocol))
	    return YES;
	}
      proto_list = proto_list->next;
    }

  return NO;
}
示例#12
0
BOOL 
class_conformsToProtocol (Class class_, Protocol *protocol)
{
  struct objc_protocol_list* proto_list;

  if (class_ == Nil  ||  protocol == NULL)
    return NO;

  /* Check that it is a Protocol object before casting it to (struct
     objc_protocol *).  */
  if (protocol->class_pointer != objc_lookUpClass ("Protocol"))
    return NO;

  /* Acquire the runtime lock because the list of protocols for a
     class may be modified concurrently, for example if another thread
     calls class_addProtocol(), or dynamically loads from a file a
     category of the class.  */
  objc_mutex_lock (__objc_runtime_mutex);
  proto_list = class_->protocols;

  while (proto_list)
    {
      size_t i;
      for (i = 0; i < proto_list->count; i++)
	{
	  if (proto_list->list[i] == (struct objc_protocol *)protocol
	      || protocol_conformsToProtocol ((Protocol *)proto_list->list[i],
					      protocol))
	    {
	      objc_mutex_unlock (__objc_runtime_mutex);
	      return YES;
	    }
	}
      proto_list = proto_list->next;
    }
  
  objc_mutex_unlock (__objc_runtime_mutex);
  return NO;
}
示例#13
0
struct objc_method_description protocol_getMethodDescription (Protocol *protocol, 
							      SEL selector,
							      BOOL requiredMethod,
							      BOOL instanceMethod)
{
  struct objc_method_description no_result = { NULL, NULL };
  struct objc_method_description_list *methods;
  int i;

  /* TODO: New ABI.  */
  /* The current ABI does not have any information on optional protocol methods.  */
  if (! requiredMethod)
    return no_result;

  /* Check that it is a Protocol object before casting it to (struct
     objc_protocol *).  */
  if (protocol->class_pointer != objc_lookUpClass ("Protocol"))
    return no_result;

  if (instanceMethod)
    methods = ((struct objc_protocol *)protocol)->instance_methods;
  else
    methods = ((struct objc_protocol *)protocol)->class_methods;

  if (methods)
    {
      for (i = 0; i < methods->count; i++)
	{
	  if (sel_isEqual (methods->list[i].name, selector))
	    return methods->list[i];
	  /*
	  if (strcmp (sel_getName (methods->list[i].name), selector_name) == 0)
	    return methods->list[i];
	  */
	}
    }

  return no_result;
}
示例#14
0
BOOL 
protocol_isEqual (Protocol *protocol, Protocol *anotherProtocol)
{
  if (protocol == anotherProtocol)
    return YES;

  if (protocol == NULL  ||  anotherProtocol == NULL)
    return NO;
  
  /* Check that the objects are Protocol objects before casting them
     to (struct objc_protocol *).  */
  if (protocol->class_pointer != anotherProtocol->class_pointer)
    return NO;
  
  if (protocol->class_pointer != objc_lookUpClass ("Protocol"))
    return NO;

  /* Equality between formal protocols is only formal (nothing to do
     with actually checking the list of methods they have!).  Two
     formal Protocols are equal if and only if they have the same
     name.

     Please note (for comparisons with other implementations) that
     checking the names is equivalent to checking that Protocol A
     conforms to Protocol B and Protocol B conforms to Protocol A,
     because this happens iff they have the same name.  If they have
     different names, A conforms to B if and only if A includes B, but
     the situation where A includes B and B includes A is a circular
     dependency between Protocols which is forbidden by the compiler,
     so A conforms to B and B conforms to A with A and B having
     different names is an impossible case.  */
  if (strcmp (((struct objc_protocol *)protocol)->protocol_name,
	      ((struct objc_protocol *)anotherProtocol)->protocol_name) == 0)
    return YES;
  
  return NO;
}
示例#15
0
void CFArraySortValues(CFMutableArrayRef array, CFRange range, CFComparatorFunction comparator, void *context) {
    FAULT_CALLBACK((void **)&(comparator));
    __CFArrayValidateRange(array, range, __PRETTY_FUNCTION__);
    CFAssert1(NULL != comparator, __kCFLogAssertion, "%s(): pointer to comparator function may not be NULL", __PRETTY_FUNCTION__);
    Boolean immutable = false;
    if (CF_IS_OBJC(__kCFArrayTypeID, array)) {
        BOOL result;
        CF_OBJC_CALL1(BOOL, result, array, "isKindOfClass:", objc_lookUpClass("NSMutableArray"));
        immutable = !result;
    } else if (__kCFArrayImmutable == __CFArrayGetType(array)) {
        immutable = true;
    }
    const CFArrayCallBacks *cb = NULL;
    if (CF_IS_OBJC(__kCFArrayTypeID, array)) {
        cb = &kCFTypeArrayCallBacks;
    } else {
        cb = __CFArrayGetCallBacks(array);
    }
    if (!immutable && ((cb->retain && !cb->release) || (!cb->retain && cb->release))) {
	__CFZSort(array, range, comparator, context);
	return;
    }
    if (range.length < 2) {
        return;
    }
    // implemented abstractly, careful!
    const void **values, *buffer[256];
    values = (range.length <= 256) ? (const void **)buffer : (const void **)CFAllocatorAllocate(kCFAllocatorSystemDefault, range.length * sizeof(void *), 0); // GC OK
    CFArrayGetValues(array, range, values);
    struct _acompareContext ctx;
    ctx.func = comparator;
    ctx.context = context;
    CFQSortArray(values, range.length, sizeof(void *), (CFComparatorFunction)__CFArrayCompareValues, &ctx);
    if (!immutable) CFArrayReplaceValues(array, range, values, range.length);
    if (values != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, values);
}
示例#16
0
Class classForName(const char *className)
{
  return objc_lookUpClass(className);
}
示例#17
0
Class superclassForName(const char *className)
{
  return class_getSuperclass(objc_lookUpClass(className));
}
示例#18
0
Class metaclassForName(const char *className)
{
  return object_getClass((id)objc_lookUpClass(className));
}