#> #import "objc-runtime.h" <# #>! int alignof_type (const char *type) { switch (*type) { case _C_ID: return __alignof__ (id); case _C_CLASS: return __alignof__ (Class); case _C_SEL: return __alignof__ (SEL); case _C_CHR: return __alignof__ (char); case _C_UCHR: return __alignof__ (unsigned char); case _C_SHT: return __alignof__ (short); case _C_USHT: return __alignof__ (unsigned short); #ifdef _C_BOOL case _C_BOOL: return __alignof__ (bool); #endif case _C_INT: return __alignof__ (int); case _C_UINT: return __alignof__ (unsigned int); case _C_LNG: return __alignof__ (long); case _C_ULNG: return __alignof__ (unsigned long); case _C_FLT: return __alignof__ (float); case _C_DBL: return __alignof__ (double); case _C_CHARPTR: return __alignof__ (char *); #ifdef _C_ATOM case _C_ATOM: return __alignof__ (char *); #endif case _C_PTR: return __alignof__ (void *); case _C_LNGLNG: return __alignof__(long long); case _C_ULNGLNG: return __alignof__(unsigned long long); case _C_ARY_B: while (isdigit(*++type)) /* do nothing */; return alignof_type(type); case _C_CONST: case _C_IN: case _C_INOUT: case _C_OUT: case _C_BYCOPY: case _C_ONEWAY: return alignof_type(type+1); #if 0 /* unsupported types struct and union */ case _C_STRUCT_B: { /* The alignment of a struct is the alignment of it's first * member */ struct { int x; double y; } fooalign; while(*type != _C_STRUCT_E && *type++ != '=') /* do nothing */; if (*type != _C_STRUCT_E) { int have_align = 0; int align = 0; while (type != NULL && *type != _C_STRUCT_E) { if (*type == '"') { type = strchr(type+1, '"'); if (type) type++; } if (have_align) { align = MAX(align, PyObjC_EmbeddedAlignOfType(type)); } else { align = PyObjCRT_AlignOfType(type); have_align = 1; } type = PyObjCRT_SkipTypeSpec(type); } if (type == NULL) return -1; return align; } else { return __alignof__ (fooalign); } } case _C_UNION_B: { int maxalign = 0; type++; while (*type != _C_UNION_E) { int item_align = alignof_type(type); if (item_align == -1) return -1; maxalign = MAX (maxalign, item_align); type = PyObjCRT_SkipTypeSpec (type); } return maxalign; } #endif default: { unsigned int size, align; NSGetSizeAndAlignment(type, &size, &align); return align; } } } int sizeof_type(const char *type) { int itemSize; switch (*type) { case _C_VOID: return 0; case _C_ID: return sizeof(id); case _C_CLASS: return sizeof(Class); case _C_SEL: return sizeof(SEL); case _C_CHR: return sizeof(char); case _C_UCHR: return sizeof(unsigned char); case _C_SHT: return sizeof(short); case _C_USHT: return sizeof(unsigned short); #ifdef _C_BOOL case _C_BOOL: return sizeof(bool); #endif case _C_INT: return sizeof(int); case _C_UINT: return sizeof(unsigned int); case _C_LNG: return sizeof(long); case _C_ULNG: return sizeof(unsigned long); case _C_FLT: return sizeof(float); case _C_DBL: return sizeof(double); case _C_LNGLNG: return sizeof(long long); case _C_ULNGLNG: return sizeof(unsigned long long); case _C_PTR: case _C_CHARPTR: #ifdef _C_ATOM case _C_ATOM: #endif return sizeof(char*); #if 0 /* unsupported types array, struct, union */ case _C_ARY_B: { int len = atoi(type+1); int item_align; while (isdigit(*++type)) ; item_align = PyObjCRT_AlignedSize(type); if (item_align == -1) return -1; return len*item_align; } break; case _C_STRUCT_B: { int acc_size = 0; int have_align = 0; int align; int max_align = 0; while (*type != _C_STRUCT_E && *type++ != '=') ; /* skip "=" */ while (*type != _C_STRUCT_E) { if (*type == '"') { type = strchr(type+1, '"'); if (type) type++; } if (have_align) { align = PyObjC_EmbeddedAlignOfType(type); if (align == -1) return -1; } else { align = PyObjCRT_AlignOfType(type); if (align == -1) return -1; have_align = 1; } max_align = MAX(align, max_align); acc_size = ROUND (acc_size, align); itemSize = PyObjCRT_SizeOfType (type); if (itemSize == -1) return -1; acc_size += itemSize; type = PyObjCRT_SkipTypeSpec (type); } if (max_align) { acc_size = ROUND(acc_size, max_align); } return acc_size; } case _C_UNION_B: { int max_size = 0; type++; while (*type != _C_UNION_E) { itemSize = PyObjCRT_SizeOfType (type); if (itemSize == -1) return -1; max_size = MAX (max_size, itemSize); type = PyObjCRT_SkipTypeSpec (type); } return max_size; } #endif case _C_CONST: case _C_IN: case _C_INOUT: case _C_OUT: case _C_BYCOPY: case _C_ONEWAY: return sizeof_type(type+1); default: { unsigned int size, align; NSGetSizeAndAlignment(type, &size, &align); return size; } } } <# (define (objc:alignof-type type) (let ((result (alignof-type type))) (if (eqv? result -1) (error 'objc:alignof-type "unsupported type" type) result))) (define (objc:sizeof-type type) (let ((result (sizeof-type type))) (if (eqv? result -1) (error 'objc:alignof-type "unsupported type" type) result)))