Beispiel #1
0
Ivar object_getInstanceVariable(id obj, const char *name, void **outValue)
{
  Ivar ivar = class_getInstanceVariable(object_getClass(obj), name);
  if (NULL != outValue)
    {
      *outValue = object_getIvar(obj, ivar);
    }
  return ivar;
}
Beispiel #2
0
BOOL class_addIvar(Class cls, const char *name, size_t size, uint8_t alignment,
		const char *types)
{
	CHECK_ARG(cls);
	CHECK_ARG(name);
	CHECK_ARG(types);
	// You can't add ivars to initialized classes.  Note: We can't use the
	// resolved flag here because class_getInstanceVariable() sets it.
	if (objc_test_class_flag(cls, objc_class_flag_initialized))
	{
		return NO;
	}

	if (class_getInstanceVariable(cls, name) != NULL)
	{
		return NO;
	}

	struct objc_ivar_list *ivarlist = cls->ivars;

	if (NULL == ivarlist)
	{
		cls->ivars = malloc(sizeof(struct objc_ivar_list) + sizeof(struct objc_ivar));
		cls->ivars->count = 1;
	}
	else
	{
		ivarlist->count++;
		// objc_ivar_list contains one ivar.  Others follow it.
		cls->ivars = realloc(ivarlist, sizeof(struct objc_ivar_list) +
				(ivarlist->count) * sizeof(struct objc_ivar));
	}
	Ivar ivar = &cls->ivars->ivar_list[cls->ivars->count - 1];
	ivar->name = strdup(name);
	ivar->type = strdup(types);
	// Round up the offset of the ivar so it is correctly aligned.
	long offset = cls->instance_size >> alignment;

	if (offset << alignment != cls->instance_size)
	{
		offset++;
	}
	offset <<= alignment;

	ivar->offset = offset;
	// Increase the instance size to make space for this.
	cls->instance_size = ivar->offset + size;
	return YES;
}
Beispiel #3
0
BOOL
class_addIvar(Class cls, const char *name,
  size_t size, uint8_t alignment, const char *types)
{
  struct objc_ivar_list *ivarlist;
  unsigned off;
  Ivar ivar;

  if (Nil == cls || CLS_ISRESOLV(cls) || CLS_ISMETA(cls))
    {
      return NO;
    }

  if (class_getInstanceVariable(cls, name) != NULL)
    {
      return NO;
    }

  ivarlist = cls->ivars;

  if (NULL == ivarlist)
    {
      cls->ivars = malloc(sizeof(struct objc_ivar_list));
      cls->ivars->ivar_count = 1;
    }
  else
    {
      ivarlist->ivar_count++;
      // objc_ivar_list contains one ivar.  Others follow it.
      cls->ivars = realloc(ivarlist, sizeof(struct objc_ivar_list)
	+ (ivarlist->ivar_count - 1) * sizeof(struct objc_ivar));
    }

  ivar = &cls->ivars->ivar_list[cls->ivars->ivar_count - 1];
  ivar->ivar_name = strdup(name);
  ivar->ivar_type = strdup(types);
  // Round up the offset of the ivar so it is correctly aligned.
  off = cls->instance_size >> alignment;
  if (off << alignment != cls->instance_size)
    off = (off + 1) << alignment;
  ivar->ivar_offset = off;
  // Increase the instance size to make space for this.
  cls->instance_size = ivar->ivar_offset + size;
  return YES;
}
Beispiel #4
0
struct objc_ivar *
class_getClassVariable (Class class_, const char *name)
{
  if (class_ == Nil)
    return NULL;

  /* Logically, since a class is an instance of its meta-class, and
     since its class methods are the instance methods of the
     meta-class, class variables should be instance variables of the
     meta-class.  That is different from the normal use of having
     'static' variables in the class implementation file, because
     every class would have its own variables.

     Anyway, it is all speculative at this stage, but if we get class
     variables in Objective-C, it is conceivable that this
     implementation should work.  */
  return class_getInstanceVariable (class_->class_pointer, name);
}
Beispiel #5
0
struct objc_ivar *
object_getInstanceVariable (id object, const char *name, void **returnValue)
{
  if (object == nil  ||  name == NULL)
    return NULL;
  else
    {
      struct objc_ivar * variable = class_getInstanceVariable (object->class_pointer, name);

      if (variable != NULL  &&  returnValue != NULL)
	{
	  char *location = (char *)object + variable->ivar_offset;
	 
	  *returnValue = *((id *)location);
	}

      return variable;
    }
}
Beispiel #6
0
void ConvertIvarList(Class c, const ivar_list_t* list)
{
	LOG << list->count << " ivars within\n";

	for (size_t i = 0; i < list->count; i++)
	{
		auto* v = &list->ivar_list[i];
		int align = __builtin_ffs(v->alignment) - 1;

		LOG << "Ivar: name: " << v->name << "; type: " << v->type << "; offset: " << *v->offset << "; size: " << v->size << "; alignment: " << v->alignment << std::endl;
		class_addIvar(c, v->name, v->size, v->alignment, v->type);
		
		Ivar ivar = class_getInstanceVariable(c, v->name);
		
		if (ivar)
		{
			*v->offset = ivar_getOffset(ivar);
			LOG << "Ivar registered, ivar_getOffset() = " << ivar_getOffset(ivar) << " in " << class_getInstanceSize(c) << std::endl;
		}

		assert(ivar != nullptr);
		// assert(ivar_getOffset(ivar) == *v->offset);
	}
}
Beispiel #7
0
BOOL
class_addIvar (Class class_, const char * ivar_name, size_t size,
	       unsigned char log_2_of_alignment, const char *type)
{
  struct objc_ivar_list *ivars;

  if (class_ == Nil
      || (! CLS_IS_IN_CONSTRUCTION (class_))  
      || ivar_name == NULL  
      || (strcmp (ivar_name, "") == 0)
      || size == 0
      || type == NULL)
    return NO;

  /* Check if the class has an instance variable with that name
     already.  */
  ivars = class_->ivars;

  if (ivars != NULL)
    {
      int i;
      
      for (i = 0; i < ivars->ivar_count; i++)
	{
	  struct objc_ivar *ivar = &(ivars->ivar_list[i]);
	  
	  if (strcmp (ivar->ivar_name, ivar_name) == 0)
	    return NO;
	}
    }

  /* Ok, no direct ivars.  Check superclasses.  */
  if (class_getInstanceVariable (objc_getClass ((char *)(class_->super_class)),
				 ivar_name))
    return NO;

  /* Good.  Create space for the new instance variable.  */
  if (ivars)
    {
      int ivar_count = ivars->ivar_count + 1;
      int new_size = sizeof (struct objc_ivar_list) 
	+ (ivar_count - 1) * sizeof (struct objc_ivar);
      
      ivars = (struct objc_ivar_list*) objc_realloc (ivars, new_size);
      ivars->ivar_count = ivar_count;
      class_->ivars = ivars;
    }
  else
    {
      int new_size = sizeof (struct objc_ivar_list);
      
      ivars = (struct objc_ivar_list*) objc_malloc (new_size);
      ivars->ivar_count = 1;
      class_->ivars = ivars;
    }
    
  /* Now ivars is set to a list of instance variables of the right
     size. */
  {
    struct objc_ivar *ivar = &(ivars->ivar_list[ivars->ivar_count - 1]);
    unsigned int alignment = 1 << log_2_of_alignment;
    int misalignment;
    
    ivar->ivar_name = objc_malloc (strlen (ivar_name) + 1);
    strcpy ((char *)ivar->ivar_name, ivar_name);

    ivar->ivar_type = objc_malloc (strlen (type) + 1);
    strcpy ((char *)ivar->ivar_type, type);

    /* The new instance variable is placed at the end of the existing
       instance_size, at the first byte that is aligned with
       alignment.  */
    misalignment = class_->instance_size % alignment;
    
    if (misalignment == 0)
      ivar->ivar_offset = class_->instance_size;
    else
      ivar->ivar_offset = class_->instance_size - misalignment + alignment;
    
    class_->instance_size = ivar->ivar_offset + size;
  }
  
  return YES;
}
Beispiel #8
0
Ivar class_getClassVariable(Class cls, const char* name)
{
	// Note: We don't have compiler support for cvars in ObjC
	return class_getInstanceVariable(object_getClass((id)cls), name);
}
Beispiel #9
0
Ivar object_setInstanceVariable(id obj, const char *name, void *value)
{
  Ivar ivar = class_getInstanceVariable(object_getClass(obj), name);
  object_setIvar(obj, ivar, value);
  return ivar;
}