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

unix.superglobalmegacorp.com

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