Annotation of gcc/objc/encoding.c, revision 1.1

1.1     ! root        1: /* Encoding of types for Objective C.
        !             2:    Copyright (C) 1993 Free Software Foundation, Inc.
        !             3: 
        !             4: Author: Kresten Krab Thorup
        !             5: 
        !             6: This file is part of GNU CC.
        !             7: 
        !             8: GNU CC is free software; you can redistribute it and/or modify
        !             9: it under the terms of the GNU General Public License as published by
        !            10: the Free Software Foundation; either version 2, or (at your option)
        !            11: any later version.
        !            12: 
        !            13: GNU CC is distributed in the hope that it will be useful,
        !            14: but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            15: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            16: GNU General Public License for more details.
        !            17: 
        !            18: You should have received a copy of the GNU General Public License
        !            19: along with GNU CC; see the file COPYING.  If not, write to
        !            20: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
        !            21: 
        !            22: /* As a special exception, if you link this library with files
        !            23:    compiled with GCC to produce an executable, this does not cause
        !            24:    the resulting executable to be covered by the GNU General Public License.
        !            25:    This exception does not however invalidate any other reasons why
        !            26:    the executable file might be covered by the GNU General Public License.  */
        !            27: 
        !            28: #include "encoding.h"
        !            29: 
        !            30: #define MAX(X, Y)                    \
        !            31:   ({ typeof(X) __x = (X), __y = (Y); \
        !            32:      (__x > __y ? __x : __y); })
        !            33: 
        !            34: #define MIN(X, Y)                    \
        !            35:   ({ typeof(X) __x = (X), __y = (Y); \
        !            36:      (__x < __y ? __x : __y); })
        !            37: 
        !            38: 
        !            39: static inline int
        !            40: atoi (const char* str)
        !            41: {
        !            42:   int res = 0;
        !            43:   
        !            44:   while (isdigit (*str))
        !            45:     res *= 10, res += (*str++ - '0');
        !            46: 
        !            47:   return res;
        !            48: }
        !            49: 
        !            50: /*
        !            51:   return the size of an object specified by type 
        !            52: */
        !            53: 
        !            54: int
        !            55: objc_sizeof_type(const char* type)
        !            56: {
        !            57:   switch(*type) {
        !            58:   case _C_ID:
        !            59:     return sizeof(id);
        !            60:     break;
        !            61: 
        !            62:   case _C_CLASS:
        !            63:     return sizeof(Class*);
        !            64:     break;
        !            65: 
        !            66:   case _C_SEL:
        !            67:     return sizeof(SEL);
        !            68:     break;
        !            69: 
        !            70:   case _C_CHR:
        !            71:     return sizeof(char);
        !            72:     break;
        !            73:     
        !            74:   case _C_UCHR:
        !            75:     return sizeof(unsigned char);
        !            76:     break;
        !            77: 
        !            78:   case _C_SHT:
        !            79:     return sizeof(short);
        !            80:     break;
        !            81: 
        !            82:   case _C_USHT:
        !            83:     return sizeof(unsigned short);
        !            84:     break;
        !            85: 
        !            86:   case _C_INT:
        !            87:     return sizeof(int);
        !            88:     break;
        !            89: 
        !            90:   case _C_UINT:
        !            91:     return sizeof(unsigned int);
        !            92:     break;
        !            93: 
        !            94:   case _C_LNG:
        !            95:     return sizeof(long);
        !            96:     break;
        !            97: 
        !            98:   case _C_ULNG:
        !            99:     return sizeof(unsigned long);
        !           100:     break;
        !           101: 
        !           102:   case _C_PTR:
        !           103:   case _C_ATOM:
        !           104:   case _C_CHARPTR:
        !           105:     return sizeof(char*);
        !           106:     break;
        !           107: 
        !           108:   case _C_ARY_B:
        !           109:     {
        !           110:       int len = atoi(type+1);
        !           111:       while (isdigit(*++type));
        !           112:       return len*objc_aligned_size (type);
        !           113:     }
        !           114:     break; 
        !           115: 
        !           116:   case _C_STRUCT_B:
        !           117:     {
        !           118:       int acc_size = 0;
        !           119:       int align;
        !           120:       while (*type != _C_STRUCT_E && *type++ != '='); /* skip "<name>=" */
        !           121:       while (*type != _C_STRUCT_E);
        !           122:        {
        !           123:          align = objc_alignof_type (type);       /* padd to alignment */
        !           124:          if ((acc_size % align) != 0)
        !           125:            acc_size += align - (acc_size % align);
        !           126:          acc_size += objc_sizeof_type (type);   /* add component size */
        !           127:          type = objc_skip_typespec (type);              /* skip component */
        !           128:        }
        !           129:       return acc_size;
        !           130:     }
        !           131: 
        !           132:   case _C_UNION_B:
        !           133:     {
        !           134:       int max_size = 0;
        !           135:       while (*type != _C_UNION_E && *type++ != '=') /* do nothing */;
        !           136:       while (*type != _C_UNION_E)
        !           137:        {
        !           138:          max_size = MAX (max_size, objc_sizeof_type (type));
        !           139:          type = objc_skip_typespec (type);
        !           140:        }
        !           141:       return max_size;
        !           142:     }
        !           143:     
        !           144:   default:
        !           145:     abort();
        !           146:   }
        !           147: }
        !           148: 
        !           149: 
        !           150: /*
        !           151:   Return the alignment of an object specified by type 
        !           152: */
        !           153: 
        !           154: int
        !           155: objc_alignof_type(const char* type)
        !           156: {
        !           157:   switch(*type) {
        !           158:   case _C_ID:
        !           159:     return __alignof__(id);
        !           160:     break;
        !           161: 
        !           162:   case _C_CLASS:
        !           163:     return __alignof__(Class*);
        !           164:     break;
        !           165:     
        !           166:   case _C_SEL:
        !           167:     return __alignof__(SEL);
        !           168:     break;
        !           169: 
        !           170:   case _C_CHR:
        !           171:     return __alignof__(char);
        !           172:     break;
        !           173:     
        !           174:   case _C_UCHR:
        !           175:     return __alignof__(unsigned char);
        !           176:     break;
        !           177: 
        !           178:   case _C_SHT:
        !           179:     return __alignof__(short);
        !           180:     break;
        !           181: 
        !           182:   case _C_USHT:
        !           183:     return __alignof__(unsigned short);
        !           184:     break;
        !           185: 
        !           186:   case _C_INT:
        !           187:     return __alignof__(int);
        !           188:     break;
        !           189: 
        !           190:   case _C_UINT:
        !           191:     return __alignof__(unsigned int);
        !           192:     break;
        !           193: 
        !           194:   case _C_LNG:
        !           195:     return __alignof__(long);
        !           196:     break;
        !           197: 
        !           198:   case _C_ULNG:
        !           199:     return __alignof__(unsigned long);
        !           200:     break;
        !           201: 
        !           202:   case _C_ATOM:
        !           203:   case _C_CHARPTR:
        !           204:     return __alignof__(char*);
        !           205:     break;
        !           206: 
        !           207:   case _C_ARY_B:
        !           208:     while (isdigit(*++type)) /* do nothing */;
        !           209:     return objc_alignof_type (type);
        !           210:       
        !           211:   case _C_STRUCT_B:
        !           212:     {
        !           213:       struct { int x; double y; } fooalign;
        !           214:       while(*type != _C_STRUCT_E && *type++ != '=') /* do nothing */;
        !           215:       if (*type != _C_STRUCT_E)
        !           216:        return MAX (objc_alignof_type (type), __alignof__ (fooalign));
        !           217:       else
        !           218:        return __alignof__ (fooalign);
        !           219:     }
        !           220: 
        !           221:   case _C_UNION_B:
        !           222:     {
        !           223:       int maxalign = 0;
        !           224:       while (*type != _C_UNION_E && *type++ != '=') /* do nothing */;
        !           225:       while (*type != _C_UNION_E)
        !           226:        {
        !           227:          maxalign = MAX (maxalign, objc_alignof_type (type));
        !           228:          type = objc_skip_typespec (type);
        !           229:        }
        !           230:       return maxalign;
        !           231:     }
        !           232:     
        !           233:   default:
        !           234:     abort();
        !           235:   }
        !           236: }
        !           237: 
        !           238: /*
        !           239:   The aligned size if the size rounded up to the nearest alignment.
        !           240: */
        !           241: 
        !           242: int
        !           243: objc_aligned_size (const char* type)
        !           244: {
        !           245:   int size = objc_sizeof_type (type);
        !           246:   int align = objc_alignof_type (type);
        !           247: 
        !           248:   if ((size % align) != 0)
        !           249:     return size + align - (size % align);
        !           250:   else
        !           251:     return size;
        !           252: }
        !           253: 
        !           254: /*
        !           255:   The size rounded up to the nearest integral of the wordsize, taken
        !           256:   to be the size of a void*.
        !           257: */
        !           258: 
        !           259: int 
        !           260: objc_promoted_size (const char* type)
        !           261: {
        !           262:   int size = objc_sizeof_type (type);
        !           263:   int wordsize = sizeof (void*);
        !           264: 
        !           265:   if ((size % wordsize) != 0)
        !           266:     return size + wordsize - (size % wordsize);
        !           267:   else
        !           268:     return size;
        !           269: }
        !           270: 
        !           271: /*
        !           272:   Skip type qualifiers.  These may eventually precede typespecs
        !           273:   occuring in method prototype encodings.
        !           274: */
        !           275: 
        !           276: inline const char*
        !           277: objc_skip_type_qualifiers (const char* type)
        !           278: {
        !           279:   while (*type == _C_CONST
        !           280:         || *type == _C_IN 
        !           281:         || *type == _C_INOUT
        !           282:         || *type == _C_OUT 
        !           283:         || *type == _C_BYCOPY
        !           284:         || *type == _C_ONEWAY)
        !           285:     {
        !           286:       type += 1;
        !           287:     }
        !           288:   return type;
        !           289: }
        !           290: 
        !           291:   
        !           292: /*
        !           293:   Skip one typespec element.  If the typespec is prepended by type
        !           294:   qualifiers, these are skipped as well.
        !           295: */
        !           296: 
        !           297: const char* 
        !           298: objc_skip_typespec (const char* type)
        !           299: {
        !           300:   type = objc_skip_type_qualifiers (type);
        !           301:   
        !           302:   switch (*type) {
        !           303: 
        !           304:   case _C_ID:
        !           305:     /* An id may be annotated by the actual type if it is known
        !           306:        with the @"ClassName" syntax */
        !           307: 
        !           308:     if (*++type != '"')
        !           309:       return type;
        !           310:     else
        !           311:       {
        !           312:        while (*++type != '"') /* do nothing */;
        !           313:        return type + 1;
        !           314:       }
        !           315: 
        !           316:     /* The following are one character type codes */
        !           317:   case _C_CLASS:
        !           318:   case _C_SEL:
        !           319:   case _C_CHR:
        !           320:   case _C_UCHR:
        !           321:   case _C_CHARPTR:
        !           322:   case _C_ATOM:
        !           323:   case _C_SHT:
        !           324:   case _C_USHT:
        !           325:   case _C_INT:
        !           326:   case _C_UINT:
        !           327:   case _C_LNG:
        !           328:   case _C_ULNG:
        !           329:   case _C_FLT:
        !           330:   case _C_DBL:
        !           331:   case _C_VOID:
        !           332:     return ++type;
        !           333:     break;
        !           334: 
        !           335:   case _C_ARY_B:
        !           336:     /* skip digits, typespec and closing ']' */
        !           337:     
        !           338:     while(isdigit(*++type));
        !           339:     type = objc_skip_typespec(type);
        !           340:     if (*type == _C_ARY_E)
        !           341:       return ++type;
        !           342:     else
        !           343:       abort();
        !           344: 
        !           345:   case _C_STRUCT_B:
        !           346:     /* skip name, and elements until closing '}'  */
        !           347:     
        !           348:     while (*type != _C_STRUCT_E && *type++ != '=');
        !           349:     while (*type != _C_STRUCT_E) { type = objc_skip_typespec (type); }
        !           350:     return ++type;
        !           351: 
        !           352:   case _C_UNION_B:
        !           353:     /* skip name, and elements until closing ')'  */
        !           354:     
        !           355:     while (*type != _C_UNION_E && *type++ != '=');
        !           356:     while (*type != _C_UNION_E) { type = objc_skip_typespec (type); }
        !           357:     return ++type;
        !           358: 
        !           359:   case _C_PTR:
        !           360:     /* Just skip the following typespec */
        !           361:     
        !           362:     return objc_skip_typespec (++type);
        !           363:     
        !           364:   default:
        !           365:     abort();
        !           366:   }
        !           367: }
        !           368: 
        !           369: /*
        !           370:   Skip an offset as part of a method encoding.  This is prepended by a
        !           371:   '+' if the argument is passed in registers.
        !           372: */
        !           373: inline const char* 
        !           374: objc_skip_offset (const char* type)
        !           375: {
        !           376:   if (*type == '+') type++;
        !           377:   while(isdigit(*++type));
        !           378:   return type;
        !           379: }
        !           380: 
        !           381: /*
        !           382:   Skip an argument specification of a method encoding.
        !           383: */
        !           384: const char*
        !           385: objc_skip_argspec (const char* type)
        !           386: {
        !           387:   type = objc_skip_typespec (type);
        !           388:   type = objc_skip_offset (type);
        !           389:   return type;
        !           390: }
        !           391: 
        !           392: /*
        !           393:   Return the number of arguments that the method MTH expects.
        !           394:   Note that all methods need two implicit arguments `self' and
        !           395:   `_cmd'. 
        !           396: */
        !           397: int
        !           398: method_get_number_of_arguments (struct objc_method* mth)
        !           399: {
        !           400:   int i = 0;
        !           401:   const char* type = mth->method_types;
        !           402:   while (*type)
        !           403:     {
        !           404:       type = objc_skip_argspec (type);
        !           405:       i += 1;
        !           406:     }
        !           407:   return i - 1;
        !           408: }
        !           409: 
        !           410: /*
        !           411:   Return the size of the argument block needed on the stack to invoke
        !           412:   the method MTH.  This may be zero, if all arguments are passed in
        !           413:   registers.
        !           414: */
        !           415: 
        !           416: int
        !           417: method_get_sizeof_arguments (struct objc_method* mth)
        !           418: {
        !           419:   const char* type = objc_skip_typespec (mth->method_types);
        !           420:   return atoi (type);
        !           421: }
        !           422: 
        !           423: /*
        !           424:   Return a pointer to the next argument of ARGFRAME.  type points to
        !           425:   the last argument.  Typical use of this look like:
        !           426: 
        !           427:   {
        !           428:     char *datum, *type; 
        !           429:     for (datum = method_get_first_argument (method, argframe, &type);
        !           430:          datum; datum = method_get_next_argument (argframe, &type))
        !           431:       {
        !           432:         unsigned flags = objc_get_type_qualifiers (type);
        !           433:         type = objc_skip_type_qualifiers (type);
        !           434:        if (*type != _C_PTR)
        !           435:           [portal encodeData: datum ofType: type];
        !           436:        else
        !           437:          {
        !           438:            if ((flags & _F_IN) == _F_IN)
        !           439:               [portal encodeData: *(char**)datum ofType: ++type];
        !           440:          }
        !           441:       }
        !           442:   }
        !           443: */  
        !           444: 
        !           445: char*
        !           446: method_get_next_argument (arglist_t argframe,
        !           447:                          const char **type)
        !           448: {
        !           449:   const char *t = objc_skip_argspec (*type);
        !           450: 
        !           451:   if (*t == '\0')
        !           452:     return 0;
        !           453: 
        !           454:   *type = t;
        !           455:   t = objc_skip_typespec (t);
        !           456: 
        !           457:   if (*t == '+')
        !           458:     return argframe->arg_regs + atoi (++t);
        !           459:   else
        !           460:     return argframe->arg_ptr + atoi (t);
        !           461: }
        !           462: 
        !           463: /*
        !           464:   Return a pointer to the value of the first argument of the method 
        !           465:   described in M with the given argumentframe ARGFRAME.  The type
        !           466:   is returned in TYPE.  type must be passed to successive calls of 
        !           467:   method_get_next_argument.
        !           468: */
        !           469: char*
        !           470: method_get_first_argument (struct objc_method* m,
        !           471:                           arglist_t argframe, 
        !           472:                           const char** type)
        !           473: {
        !           474:   *type = m->method_types;
        !           475:   return method_get_next_argument (argframe, type);
        !           476: }
        !           477: 
        !           478: /*
        !           479:    Return a pointer to the ARGth argument of the method
        !           480:    M from the frame ARGFRAME.  The type of the argument
        !           481:    is returned in the value-result argument TYPE 
        !           482: */
        !           483: 
        !           484: char*
        !           485: method_get_nth_argument (struct objc_method* m,
        !           486:                         arglist_t argframe, int arg, 
        !           487:                         const char **type)
        !           488: {
        !           489:   const char* t = objc_skip_argspec (m->method_types);
        !           490: 
        !           491:   if (arg > method_get_number_of_arguments (m))
        !           492:     return 0;
        !           493: 
        !           494:   while (arg--)
        !           495:     t = objc_skip_argspec (t);
        !           496:   
        !           497:   *type = t;
        !           498:   t = objc_skip_typespec (t);
        !           499: 
        !           500:   if (*t == '+')
        !           501:     return argframe->arg_regs + atoi (++t);
        !           502:   else
        !           503:     return argframe->arg_ptr + atoi (t);
        !           504: }
        !           505: 
        !           506: unsigned
        !           507: objc_get_type_qualifiers (const char* type)
        !           508: {
        !           509:   unsigned res = 0;
        !           510:   BOOL flag = YES;
        !           511: 
        !           512:   while (flag)
        !           513:     switch (*type++)
        !           514:       {
        !           515:       case _C_CONST:  res |= _F_CONST; break;
        !           516:       case _C_IN:     res |= _F_IN; break;
        !           517:       case _C_INOUT:  res |= _F_INOUT; break;
        !           518:       case _C_OUT:    res |= _F_OUT; break;
        !           519:       case _C_BYCOPY: res |= _F_BYCOPY; break;
        !           520:       case _C_ONEWAY: res |= _F_ONEWAY; break;
        !           521:       default: flag = NO;
        !           522:     }
        !           523: 
        !           524:   return res;
        !           525: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.