Beispiel #1
0
static void
__objc_gc_setup_struct (GC_bitmap mask, const char *type, int offset)
{
  struct objc_struct_layout layout;
  unsigned int position;
  const char *mtype;

  objc_layout_structure (type, &layout);

  while (objc_layout_structure_next_member (&layout))
    {
      BOOL gc_invisible = NO;

      objc_layout_structure_get_info (&layout, &position, NULL, &mtype);

      /* Skip the variable name */
      if (*mtype == '"')
	{
	  for (mtype++; *mtype++ != '"';)
	    /* do nothing */;
	}

      if (*mtype == _C_GCINVISIBLE)
	{
	  gc_invisible = YES;
	  mtype++;
	}

      /* Add to position the offset of this structure */
      position += offset;

      switch (*mtype) {
      case _C_ID:
      case _C_CLASS:
      case _C_SEL:
      case _C_PTR:
      case _C_CHARPTR:
      case _C_ATOM:
	if (! gc_invisible)
	  SET_BIT_FOR_OFFSET (mask, position);
	break;

      case _C_ARY_B:
	__objc_gc_setup_array (mask, mtype, position);
	break;

      case _C_STRUCT_B:
	__objc_gc_setup_struct (mask, mtype, position);
	break;

      case _C_UNION_B:
	__objc_gc_setup_union (mask, mtype, position);
	break;

      default:
        break;
      }
    }
}
Beispiel #2
0
/* Iterates over the types in the structure that represents the class
   encoding and sets the bits in mask according to each ivar type.  */
static void
__objc_gc_type_description_from_type (GC_bitmap mask, const char *type)
{
  struct objc_struct_layout layout;
  unsigned int offset, align;
  const char *ivar_type;

  objc_layout_structure (type, &layout);

  while (objc_layout_structure_next_member (&layout))
    {
      BOOL gc_invisible = NO;

      objc_layout_structure_get_info (&layout, &offset, &align, &ivar_type);

      /* Skip the variable name */
      if (*ivar_type == '"')
	{
	  for (ivar_type++; *ivar_type++ != '"';)
	    /* do nothing */;
	}

      if (*ivar_type == _C_GCINVISIBLE)
	{
	  gc_invisible = YES;
	  ivar_type++;
	}

      switch (*ivar_type) {
      case _C_ID:
      case _C_CLASS:
      case _C_SEL:
      case _C_PTR:
      case _C_CHARPTR:
        if (! gc_invisible)
          SET_BIT_FOR_OFFSET (mask, offset);
	break;

      case _C_ARY_B:
	__objc_gc_setup_array (mask, ivar_type, offset);
	break;

      case _C_STRUCT_B:
	__objc_gc_setup_struct (mask, ivar_type, offset);
	break;

      case _C_UNION_B:
	__objc_gc_setup_union (mask, ivar_type, offset);
	break;

      default:
        break;
      }
    }
}
Beispiel #3
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;
    }
  }
}
Beispiel #4
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;
    }
  }
}
Beispiel #5
0
int
objc_sizeof_type (const char* type)
{
  /* Skip the variable name if any */
  if (*type == '"')
    {
      for (type++; *type++ != '"';)
	/* do nothing */;
    }

  switch(*type) {
  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_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(*++type));
      return len*objc_aligned_size (type);
    }
    break; 

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

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

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

  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_UNION_B:
    {
      int max_size = 0;
      while (*type != _C_UNION_E && *type++ != '=') /* do nothing */;
      while (*type != _C_UNION_E)
	{
	  /* Skip the variable name if any */
	  if (*type == '"')
	    {
	      for (type++; *type++ != '"';)
		/* do nothing */;
	    }
	  max_size = MAX (max_size, objc_sizeof_type (type));
	  type = objc_skip_typespec (type);
	}
      return max_size;
    }
    
  default:
    {
      objc_error(nil, OBJC_ERR_BAD_TYPE, "unknown type %s\n", type);
      return 0;
    }
  }
}
Beispiel #6
0
int
objc_alignof_type(const char* type)
{
  /* Skip the variable name if any */
  if (*type == '"')
    {
      for (type++; *type++ != '"';)
	/* do nothing */;
    }
  switch(*type) {
  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_PTR:
  case _C_ATOM:
  case _C_CHARPTR:
    return __alignof__(char*);
    break;

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

  case _C_STRUCT_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_UNION_B:
    {
      int maxalign = 0;
      while (*type != _C_UNION_E && *type++ != '=') /* do nothing */;
      while (*type != _C_UNION_E)
	{
	  /* Skip the variable name if any */
	  if (*type == '"')
	    {
	      for (type++; *type++ != '"';)
		/* do nothing */;
	    }
	  maxalign = MAX (maxalign, objc_alignof_type (type));
	  type = objc_skip_typespec (type);
	}
      return maxalign;
    }

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