Exemple #1
0
/* The following three functions can be used to determine how a
   structure is laid out by the compiler. For example:

  struct objc_struct_layout layout;
  int i;

  objc_layout_structure (type, &layout);
  while (objc_layout_structure_next_member (&layout))
    {
      int position, align;
      const char *type;

      objc_layout_structure_get_info (&layout, &position, &align, &type);
      printf ("element %d has offset %d, alignment %d\n",
              i++, position, align);
    }

  These functions are used by objc_sizeof_type and objc_alignof_type
  functions to compute the size and alignment of structures. The
  previous method of computing the size and alignment of a structure
  was not working on some architectures, particularly on AIX, and in
  the presence of bitfields inside the structure.  */
void
objc_layout_structure (const char *type,
		       struct objc_struct_layout *layout)
{
  const char *ntype;

  if (*type != _C_UNION_B && *type != _C_STRUCT_B)
    {
      _objc_abort ("record (or union) type expected in objc_layout_structure, got %s\n",
		   type);
    }

  type ++;
  layout->original_type = type;

  /* Skip "<name>=" if any. Avoid embedded structures and unions. */
  ntype = type;
  while (*ntype != _C_STRUCT_E && *ntype != _C_STRUCT_B && *ntype != _C_UNION_B
         && *ntype++ != '=')
    /* do nothing */;

  /* If there's a "<name>=", ntype - 1 points to '='; skip the the name */
  if (*(ntype - 1) == '=')
    type = ntype;

  layout->type = type;
  layout->prev_type = NULL;
  layout->record_size = 0;
  layout->record_align = BITS_PER_UNIT;

  layout->record_align = MAX (layout->record_align, STRUCTURE_SIZE_BOUNDARY);
}
Exemple #2
0
void *
objc_realloc (void *mem, size_t size)
{
  void *res = (void *)(GC_realloc (mem, size));
  if (! res)
    _objc_abort ("Virtual memory exhausted\n");
  return res;
}
Exemple #3
0
void *
objc_atomic_malloc (size_t size)
{
  void *res = (void *)(GC_malloc_atomic (size));
  if (! res)
    _objc_abort ("Virtual memory exhausted\n");
  return res;
}
Exemple #4
0
void *
objc_calloc (size_t nelem, size_t size)
{
  /* Note that GC_malloc returns cleared memory (see documentation) so
     there is no need to clear it.  */
  void *res = (void *)(GC_malloc (nelem * size));
  if (! res)
    _objc_abort ("Virtual memory exhausted\n");
  return res;
}
Exemple #5
0
inline
const char *
objc_skip_typespec (const char *type)
{
  type = objc_skip_variable_name (type);
  type = objc_skip_type_qualifiers (type);

  switch (*type) {

  case _C_ID:
    /* An id may be annotated by the actual type if it is known
       with the @"ClassName" syntax */

    if (*++type != '"')
      return type;
    else
      {
	while (*++type != '"')
	  /* do nothing */;
	return type + 1;
      }

    /* The following are one character type codes */
  case _C_CLASS:
  case _C_SEL:
  case _C_CHR:
  case _C_UCHR:
  case _C_CHARPTR:
  case _C_ATOM:
  case _C_SHT:
  case _C_USHT:
  case _C_INT:
  case _C_UINT:
  case _C_LNG:
  case _C_BOOL:
  case _C_ULNG:
  case _C_LNG_LNG:
  case _C_ULNG_LNG:
  case _C_FLT:
  case _C_DBL:
  case _C_LNG_DBL:
  case _C_VOID:
  case _C_UNDEF:
    return ++type;
    break;
    
  case _C_COMPLEX:
    return type + 2;
    break;

  case _C_ARY_B:
    /* skip digits, typespec and closing ']' */
    while (isdigit ((unsigned char)*++type))
      ;
    type = objc_skip_typespec (type);
    if (*type == _C_ARY_E)
      return ++type;
    else
      {
	_objc_abort ("bad array type %s\n", type);
	return 0;
      }

  case _C_VECTOR:
    /* Skip '!' */
    type++;
    /* Skip '[' */
    type++;
    /* Skip digits (size) */
    while (isdigit ((unsigned char)*type))
      type++;
    /* Skip ',' */
    type++;
    /* Skip digits (alignment) */
    while (isdigit ((unsigned char)*type))
      type++;
    /* Skip typespec.  */
    type = objc_skip_typespec (type);
    /* Skip closing ']'.  */
    if (*type == _C_ARY_E)
      return ++type;
    else
      {
	_objc_abort ("bad vector type %s\n", type);
	return 0;
      }

  case _C_BFLD:
    /* The GNU encoding of bitfields is: b 'position' 'type'
       'size'.  */
    while (isdigit ((unsigned char)*++type))
      ;	/* skip position */
    while (isdigit ((unsigned char)*++type))
      ;	/* skip type and size */
    return type;

  case _C_STRUCT_B:
    /* skip name, and elements until closing '}'  */

    while (*type != _C_STRUCT_E && *type++ != '=')
      ;
    while (*type != _C_STRUCT_E)
      {
	type = objc_skip_typespec (type);
      }
    return ++type;

  case _C_UNION_B:
    /* skip name, and elements until closing ')'  */

    while (*type != _C_UNION_E && *type++ != '=')
      ;
    while (*type != _C_UNION_E)
      {
	type = objc_skip_typespec (type);
      }
    return ++type;

  case _C_PTR:
    /* Just skip the following typespec */

    return objc_skip_typespec (++type);

  default:
    {
      _objc_abort ("unknown type %s\n", type);
      return 0;
    }
  }
}
Exemple #6
0
int
objc_alignof_type (const char *type)
{
  type = objc_skip_variable_name (type);

  switch (*type) {
  case _C_BOOL:
    return __alignof__ (_Bool);
    break;

  case _C_ID:
    return __alignof__ (id);
    break;

  case _C_CLASS:
    return __alignof__ (Class);
    break;

  case _C_SEL:
    return __alignof__ (SEL);
    break;

  case _C_CHR:
    return __alignof__ (char);
    break;

  case _C_UCHR:
    return __alignof__ (unsigned char);
    break;

  case _C_SHT:
    return __alignof__ (short);
    break;

  case _C_USHT:
    return __alignof__ (unsigned short);
    break;

  case _C_INT:
    return __alignof__ (int);
    break;

  case _C_UINT:
    return __alignof__ (unsigned int);
    break;

  case _C_LNG:
    return __alignof__ (long);
    break;

  case _C_ULNG:
    return __alignof__ (unsigned long);
    break;

  case _C_LNG_LNG:
    return __alignof__ (long long);
    break;

  case _C_ULNG_LNG:
    return __alignof__ (unsigned long long);
    break;

  case _C_FLT:
    return __alignof__ (float);
    break;

  case _C_DBL:
    return __alignof__ (double);
    break;

  case _C_LNG_DBL:
    return __alignof__ (long double);
    break;

  case _C_PTR:
  case _C_ATOM:
  case _C_CHARPTR:
    return __alignof__ (char *);
    break;

  case _C_ARY_B:
    while (isdigit ((unsigned char)*++type))
      /* do nothing */;
    return objc_alignof_type (type);

  case _C_VECTOR:
    {   
      /* Skip the '!'.  */
      type++;
      /* Skip the '['.  */
      type++;
      
      /* Skip the size.  */
      while (isdigit ((unsigned char)*type))
	type++;
      
      /* Skip the ','.  */
      type++;
      
      /* The alignment in bytes is the following number.  */
      return atoi (type);
    }
  case _C_STRUCT_B:
  case _C_UNION_B:
    {
      struct objc_struct_layout layout;
      unsigned int align;

      objc_layout_structure (type, &layout);
      while (objc_layout_structure_next_member (&layout))
        /* do nothing */;
      objc_layout_finish_structure (&layout, NULL, &align);

      return align;
    }
    
    
  case _C_COMPLEX:
    {
      type++; /* Skip after the 'j'. */
      switch (*type)
        {
	    case _C_CHR:
	      return __alignof__ (_Complex char);
	      break;

	    case _C_UCHR:
	      return __alignof__ (_Complex unsigned char);
	      break;

	    case _C_SHT:
	      return __alignof__ (_Complex short);
	      break;

	    case _C_USHT:
	      return __alignof__ (_Complex unsigned short);
	      break;

	    case _C_INT:
	      return __alignof__ (_Complex int);
	      break;

	    case _C_UINT:
	      return __alignof__ (_Complex unsigned int);
	      break;

	    case _C_LNG:
	      return __alignof__ (_Complex long);
	      break;

	    case _C_ULNG:
	      return __alignof__ (_Complex unsigned long);
	      break;

	    case _C_LNG_LNG:
	      return __alignof__ (_Complex long long);
	      break;

	    case _C_ULNG_LNG:
	      return __alignof__ (_Complex unsigned long long);
	      break;

	    case _C_FLT:
	      return __alignof__ (_Complex float);
	      break;

	    case _C_DBL:
	      return __alignof__ (_Complex double);
	      break;

	    case _C_LNG_DBL:
	      return __alignof__ (_Complex long double);
	      break;
	    
	    default:
	      {
		_objc_abort ("unknown complex type %s\n", type);
		return 0;
	      }
	}
    }

  default:
    {
      _objc_abort ("unknown type %s\n", type);
      return 0;
    }
  }
}
Exemple #7
0
int
objc_sizeof_type (const char *type)
{
  type = objc_skip_variable_name (type);

  switch (*type) {
  case _C_BOOL:
    return sizeof (_Bool);
    break;

  case _C_ID:
    return sizeof (id);
    break;

  case _C_CLASS:
    return sizeof (Class);
    break;

  case _C_SEL:
    return sizeof (SEL);
    break;

  case _C_CHR:
    return sizeof (char);
    break;

  case _C_UCHR:
    return sizeof (unsigned char);
    break;

  case _C_SHT:
    return sizeof (short);
    break;

  case _C_USHT:
    return sizeof (unsigned short);
    break;

  case _C_INT:
    return sizeof (int);
    break;

  case _C_UINT:
    return sizeof (unsigned int);
    break;

  case _C_LNG:
    return sizeof (long);
    break;

  case _C_ULNG:
    return sizeof (unsigned long);
    break;

  case _C_LNG_LNG:
    return sizeof (long long);
    break;

  case _C_ULNG_LNG:
    return sizeof (unsigned long long);
    break;

  case _C_FLT:
    return sizeof (float);
    break;

  case _C_DBL:
    return sizeof (double);
    break;

  case _C_LNG_DBL:
    return sizeof (long double);
    break;

  case _C_VOID:
    return sizeof (void);
    break;

  case _C_PTR:
  case _C_ATOM:
  case _C_CHARPTR:
    return sizeof (char *);
    break;

  case _C_ARY_B:
    {
      int len = atoi (type + 1);
      while (isdigit ((unsigned char)*++type))
	;
      return len * objc_aligned_size (type);
    }
    break;

  case _C_VECTOR:
    {
      /* Skip the '!'.  */
      type++;
      /* Skip the '['.  */
      type++;

      /* The size in bytes is the following number.  */
      int size = atoi (type);
      return size;
    }
    break;

  case _C_BFLD:
    {
      /* The GNU encoding of bitfields is: b 'position' 'type'
	 'size'.  */
      int position, size;
      int startByte, endByte;

      position = atoi (type + 1);
      while (isdigit ((unsigned char)*++type))
	;
      size = atoi (type + 1);

      startByte = position / BITS_PER_UNIT;
      endByte = (position + size) / BITS_PER_UNIT;
      return endByte - startByte;
    }

  case _C_UNION_B:
  case _C_STRUCT_B:
    {
      struct objc_struct_layout layout;
      unsigned int size;

      objc_layout_structure (type, &layout);
      while (objc_layout_structure_next_member (&layout))
        /* do nothing */ ;
      objc_layout_finish_structure (&layout, &size, NULL);

      return size;
    }
    
  case _C_COMPLEX:
    {
      type++; /* Skip after the 'j'. */
      switch (*type)
        {
	    case _C_CHR:
	      return sizeof (_Complex char);
	      break;

	    case _C_UCHR:
	      return sizeof (_Complex unsigned char);
	      break;

	    case _C_SHT:
	      return sizeof (_Complex short);
	      break;

	    case _C_USHT:
	      return sizeof (_Complex unsigned short);
	      break;

	    case _C_INT:
	      return sizeof (_Complex int);
	      break;

	    case _C_UINT:
	      return sizeof (_Complex unsigned int);
	      break;

	    case _C_LNG:
	      return sizeof (_Complex long);
	      break;

	    case _C_ULNG:
	      return sizeof (_Complex unsigned long);
	      break;

	    case _C_LNG_LNG:
	      return sizeof (_Complex long long);
	      break;

	    case _C_ULNG_LNG:
	      return sizeof (_Complex unsigned long long);
	      break;

	    case _C_FLT:
	      return sizeof (_Complex float);
	      break;

	    case _C_DBL:
	      return sizeof (_Complex double);
	      break;

	    case _C_LNG_DBL:
	      return sizeof (_Complex long double);
	      break;
	    
	    default:
	      {
		/* FIXME: Is this so bad that we have to abort the
		   entire program ?  (it applies to all the other
		   _objc_abort calls in this file).
		*/
		_objc_abort ("unknown complex type %s\n", type);
		return 0;
	      }
	}
    }

  default:
    {
      _objc_abort ("unknown type %s\n", type);
      return 0;
    }
  }
}