--- gcc/objc/archive.c 2018/04/24 18:13:38 1.1.1.2 +++ gcc/objc/archive.c 2018/04/24 18:26:48 1.1.1.4 @@ -1,22 +1,22 @@ /* GNU Objective C Runtime archiving - Copyright (C) 1993 Free Software Foundation, Inc. - -Author: Kresten Krab Thorup + Copyright (C) 1993, 1995 Free Software Foundation, Inc. + Contributed by Kresten Krab Thorup This file is part of GNU CC. GNU CC is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 2, or (at your option) any later version. +terms of the GNU General Public License as published by the Free Software +Foundation; either version 2, or (at your option) any later version. GNU CC is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - details. +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. You should have received a copy of the GNU General Public License along with - GNU CC; see the file COPYING. If not, write to the Free Software - Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ +GNU CC; see the file COPYING. If not, write to the Free Software +Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ /* As a special exception, if you link this library with files compiled with GCC to produce an executable, this does not cause the resulting executable @@ -24,14 +24,18 @@ You should have received a copy of the G however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ -/* -** Note: This version assumes that int and longs are both 32bit. -*/ - -#ifndef __alpha__ - #include "runtime.h" #include "typedstream.h" +#include "encoding.h" + +extern int fflush(FILE*); + +#define ROUND(V, A) \ + ({ typeof(V) __v=(V); typeof(A) __a=(A); \ + __a*((__v+__a-1)/__a); }) + +#define PTR2LONG(P) (((char*)(P))-(char*)0) +#define LONG2PTR(L) (((char*)0)+(L)) #define __objc_fatal(format, args...) \ { fprintf(stderr, "archiving: "); \ @@ -41,24 +45,22 @@ You should have received a copy of the G /* Declare some functions... */ static int -objc_read_class (struct objc_typed_stream* stream, Class** class); +objc_read_class (struct objc_typed_stream* stream, Class* class); -static int -objc_sizeof_type(const char* type); +int objc_sizeof_type(const char* type); static int -objc_write_use_common (struct objc_typed_stream* stream, unsigned int key); +objc_write_use_common (struct objc_typed_stream* stream, unsigned long key); static int objc_write_register_common (struct objc_typed_stream* stream, - unsigned int key); + unsigned long key); static int objc_write_class (struct objc_typed_stream* stream, struct objc_class* class); -static const char* -__objc_skip_type (const char* type); +const char* objc_skip_type (const char* type); static void __objc_finish_write_root_object(struct objc_typed_stream*); static void __objc_finish_read_root_object(struct objc_typed_stream*); @@ -112,15 +114,29 @@ objc_write_char (struct objc_typed_strea static __inline__ int __objc_code_unsigned_short (unsigned char* buf, unsigned short val) { - if (val <= 0xffU) - return __objc_code_unsigned_char (buf, val); - + if ((val&_B_VALUE) == val) + { + buf[0] = val|_B_SINT; + return 1; + } else { - buf[0] = _B_NINT|0x02; - buf[1] = val/0x100; - buf[2] = val%0x100; - return 3; + int c, b; + + buf[0] = _B_NINT; + + for (c= sizeof(short); c != 0; c -= 1) + if (((val>>(8*(c-1)))%0x100) != 0) + break; + + buf[0] |= c; + + for (b = 1; c != 0; c--, b++) + { + buf[b] = (val >> (8*(c-1)))%0x100; + } + + return b; } } @@ -135,18 +151,11 @@ objc_write_unsigned_short (struct objc_t static __inline__ int __objc_code_short (unsigned char* buf, short val) { - if (val > 0) - return __objc_code_unsigned_short (buf, val); - - if (val > -0x7f) /* val > -128 */ - return __objc_code_char (buf, val); - - else - { - int len = __objc_code_unsigned_short (buf, -val); - buf[0] |= _B_SIGN; - return len; - } + int sign = (val < 0); + int size = __objc_code_unsigned_short (buf, sign ? -val : val); + if (sign) + buf[0] |= _B_SIGN; + return size; } int @@ -161,26 +170,29 @@ objc_write_short (struct objc_typed_stre static __inline__ int __objc_code_unsigned_int (unsigned char* buf, unsigned int val) { - if (val < 0x10000) - return __objc_code_unsigned_short (buf, val%0x10000); - - else if (val < 0x1000000) + if ((val&_B_VALUE) == val) { - buf[0] = _B_NINT|3; - buf[1] = val/0x10000; - buf[2] = (val%0x10000)/0x100; - buf[3] = val%0x100; - return 4; + buf[0] = val|_B_SINT; + return 1; } - else { - buf[0] = _B_NINT|4; - buf[1] = val/0x1000000; - buf[2] = (val%0x1000000)/0x10000; - buf[3] = (val%0x10000)/0x100; - buf[4] = val%0x100; - return 5; + int c, b; + + buf[0] = _B_NINT; + + for (c= sizeof(int); c != 0; c -= 1) + if (((val>>(8*(c-1)))%0x100) != 0) + break; + + buf[0] |= c; + + for (b = 1; c != 0; c--, b++) + { + buf[b] = (val >> (8*(c-1)))%0x100; + } + + return b; } } @@ -195,28 +207,77 @@ objc_write_unsigned_int (struct objc_typ static __inline__ int __objc_code_int (unsigned char* buf, int val) { - if (val >= 0) - return __objc_code_unsigned_int (buf, val); + int sign = (val < 0); + int size = __objc_code_unsigned_int (buf, sign ? -val : val); + if (sign) + buf[0] |= _B_SIGN; + return size; +} - if (val > -0x7f) - return __objc_code_char (buf, val); +int +objc_write_int (struct objc_typed_stream* stream, int value) +{ + unsigned char buf[sizeof(int)+1]; + int len = __objc_code_int (buf, value); + return (*stream->write)(stream->physical, buf, len); +} +static __inline__ int +__objc_code_unsigned_long (unsigned char* buf, unsigned long val) +{ + if ((val&_B_VALUE) == val) + { + buf[0] = val|_B_SINT; + return 1; + } else { - int len = __objc_code_unsigned_int (buf, -val); - buf[0] |= _B_SIGN; - return len; + int c, b; + + buf[0] = _B_NINT; + + for (c= sizeof(long); c != 0; c -= 1) + if (((val>>(8*(c-1)))%0x100) != 0) + break; + + buf[0] |= c; + + for (b = 1; c != 0; c--, b++) + { + buf[b] = (val >> (8*(c-1)))%0x100; + } + + return b; } } int -objc_write_int (struct objc_typed_stream* stream, int value) +objc_write_unsigned_long (struct objc_typed_stream* stream, unsigned long value) { - unsigned char buf[sizeof(int)+1]; - int len = __objc_code_int (buf, value); + unsigned char buf[sizeof(unsigned long)+1]; + int len = __objc_code_unsigned_long (buf, value); return (*stream->write)(stream->physical, buf, len); } +static __inline__ int +__objc_code_long (unsigned char* buf, long val) +{ + int sign = (val < 0); + int size = __objc_code_unsigned_long (buf, sign ? -val : val); + if (sign) + buf[0] |= _B_SIGN; + return size; +} + +int +objc_write_long (struct objc_typed_stream* stream, long value) +{ + unsigned char buf[sizeof(long)+1]; + int len = __objc_code_long (buf, value); + return (*stream->write)(stream->physical, buf, len); +} + + int objc_write_string (struct objc_typed_stream* stream, const unsigned char* string, unsigned int nbytes) @@ -240,13 +301,13 @@ int objc_write_string_atomic (struct objc_typed_stream* stream, unsigned char* string, unsigned int nbytes) { - unsigned int key; - if ((key = (unsigned int)hash_value_for_key (stream->stream_table, string))) + unsigned long key; + if ((key = PTR2LONG(hash_value_for_key (stream->stream_table, string)))) return objc_write_use_common (stream, key); else { int length; - hash_add (&stream->stream_table, (void*)key=(unsigned int)string, string); + hash_add (&stream->stream_table, LONG2PTR(key=PTR2LONG(string)), string); if ((length = objc_write_register_common (stream, key))) return objc_write_string (stream, string, nbytes); return length; @@ -254,10 +315,10 @@ objc_write_string_atomic (struct objc_ty } static int -objc_write_register_common (struct objc_typed_stream* stream, unsigned int key) +objc_write_register_common (struct objc_typed_stream* stream, unsigned long key) { - unsigned char buf[sizeof (unsigned int)+2]; - int len = __objc_code_unsigned_int (buf+1, key); + unsigned char buf[sizeof (unsigned long)+2]; + int len = __objc_code_unsigned_long (buf+1, key); if (len == 1) { buf[0] = _B_RCOMM|0x01; @@ -272,10 +333,10 @@ objc_write_register_common (struct objc_ } static int -objc_write_use_common (struct objc_typed_stream* stream, unsigned int key) +objc_write_use_common (struct objc_typed_stream* stream, unsigned long key) { - unsigned char buf[sizeof (unsigned int)+2]; - int len = __objc_code_unsigned_int (buf+1, key); + unsigned char buf[sizeof (unsigned long)+2]; + int len = __objc_code_unsigned_long (buf+1, key); if (len == 1) { buf[0] = _B_UCOMM|0x01; @@ -305,7 +366,7 @@ __inline__ int __objc_write_object (struct objc_typed_stream* stream, id object) { unsigned char buf = '\0'; - SEL write_sel = sel_get_uid ("write:"); + SEL write_sel = sel_get_any_uid ("write:"); if (object) { __objc_write_extension (stream, _BX_OBJECT); @@ -320,12 +381,12 @@ __objc_write_object (struct objc_typed_s int objc_write_object_reference (struct objc_typed_stream* stream, id object) { - unsigned int key; - if ((key = (unsigned int)hash_value_for_key (stream->object_table, object))) + unsigned long key; + if ((key = PTR2LONG(hash_value_for_key (stream->object_table, object)))) return objc_write_use_common (stream, key); __objc_write_extension (stream, _BX_OBJREF); - return objc_write_unsigned_int (stream, (unsigned int)object); + return objc_write_unsigned_long (stream, PTR2LONG (object)); } int @@ -348,8 +409,8 @@ objc_write_root_object (struct objc_type int objc_write_object (struct objc_typed_stream* stream, id object) { - unsigned int key; - if ((key = (unsigned int)hash_value_for_key (stream->object_table, object))) + unsigned long key; + if ((key = PTR2LONG(hash_value_for_key (stream->object_table, object)))) return objc_write_use_common (stream, key); else if (object == nil) @@ -358,20 +419,26 @@ objc_write_object (struct objc_typed_str else { int length; - hash_add (&stream->object_table, (void*)key=(unsigned int)object, object); + hash_add (&stream->object_table, LONG2PTR(key=PTR2LONG(object)), object); if ((length = objc_write_register_common (stream, key))) return __objc_write_object (stream, object); return length; } } +#ifdef __alpha__ +extern int atoi (const char*); +extern size_t strlen(const char*); +extern size_t strcpy(char*, const char*); +#endif + __inline__ int __objc_write_class (struct objc_typed_stream* stream, struct objc_class* class) { __objc_write_extension (stream, _BX_CLASS); objc_write_string_atomic(stream, (char*)class->name, strlen((char*)class->name)); - return objc_write_unsigned_int (stream, CLS_GETNUMBER(class)); + return objc_write_unsigned_long (stream, class->version); } @@ -379,13 +446,13 @@ static int objc_write_class (struct objc_typed_stream* stream, struct objc_class* class) { - unsigned int key; - if ((key = (unsigned int)hash_value_for_key (stream->stream_table, class))) + unsigned long key; + if ((key = PTR2LONG(hash_value_for_key (stream->stream_table, class)))) return objc_write_use_common (stream, key); else { int length; - hash_add (&stream->stream_table, (void*)key=(unsigned int)class, class); + hash_add (&stream->stream_table, LONG2PTR(key=PTR2LONG(class)), class); if ((length = objc_write_register_common (stream, key))) return __objc_write_class (stream, class); return length; @@ -396,22 +463,32 @@ objc_write_class (struct objc_typed_stre __inline__ int __objc_write_selector (struct objc_typed_stream* stream, SEL selector) { - const char* sel_name = sel_get_name (selector); + const char* sel_name; __objc_write_extension (stream, _BX_SEL); + /* to handle NULL selectors */ + if ((SEL)0 == selector) + return objc_write_string (stream, "", 0); + sel_name = sel_get_name (selector); return objc_write_string (stream, sel_name, strlen ((char*)sel_name)); } int objc_write_selector (struct objc_typed_stream* stream, SEL selector) { - const char* sel_name = sel_get_name (selector); - unsigned int key; - if ((key = (unsigned int)hash_value_for_key (stream->stream_table, sel_name))) + const char* sel_name; + unsigned long key; + + /* to handle NULL selectors */ + if ((SEL)0 == selector) + return __objc_write_selector (stream, selector); + + sel_name = sel_get_name (selector); + if ((key = PTR2LONG(hash_value_for_key (stream->stream_table, sel_name)))) return objc_write_use_common (stream, key); else { int length; - hash_add (&stream->stream_table, (void*)key=(unsigned int)sel_name, (char*)sel_name); + hash_add (&stream->stream_table, LONG2PTR(key=PTR2LONG(sel_name)), (char*)sel_name); if ((length = objc_write_register_common (stream, key))) return __objc_write_selector (stream, selector); return length; @@ -552,6 +629,33 @@ objc_read_int (struct objc_typed_stream* } __inline__ int +objc_read_long (struct objc_typed_stream* stream, long* value) +{ + unsigned char buf[sizeof(long)+1]; + int len; + if ((len = (*stream->read)(stream->physical, buf, 1))) + { + if ((buf[0] & _B_CODE) == _B_SINT) + (*value) = (buf[0] & _B_VALUE); + + else + { + int pos = 1; + int nbytes = buf[0] & _B_NUMBER; + if (nbytes > sizeof (long)) + __objc_fatal("expected long, got bigger"); + len = (*stream->read)(stream->physical, buf+1, nbytes); + (*value) = 0; + while (pos <= nbytes) + (*value) = ((*value)*0x100) + buf[pos++]; + if (buf[0] & _B_SIGN) + (*value) = -(*value); + } + } + return len; +} + +__inline__ int __objc_read_nbyte_uint (struct objc_typed_stream* stream, unsigned int nbytes, unsigned int* val) { @@ -587,6 +691,42 @@ objc_read_unsigned_int (struct objc_type return len; } +int +__objc_read_nbyte_ulong (struct objc_typed_stream* stream, + unsigned int nbytes, unsigned long* val) +{ + int len, pos = 0; + unsigned char buf[sizeof(unsigned long)+1]; + + if (nbytes > sizeof (long)) + __objc_fatal("expected long, got bigger"); + + len = (*stream->read)(stream->physical, buf, nbytes); + (*val) = 0; + while (pos < nbytes) + (*val) = ((*val)*0x100) + buf[pos++]; + return len; +} + + +__inline__ int +objc_read_unsigned_long (struct objc_typed_stream* stream, + unsigned long* value) +{ + unsigned char buf[sizeof(unsigned long)+1]; + int len; + if ((len = (*stream->read)(stream->physical, buf, 1))) + { + if ((buf[0] & _B_CODE) == _B_SINT) + (*value) = (buf[0] & _B_VALUE); + + else + len = __objc_read_nbyte_ulong (stream, (buf[0] & _B_VALUE), value); + + } + return len; +} + __inline__ int objc_read_string (struct objc_typed_stream* stream, char** string) @@ -595,11 +735,11 @@ objc_read_string (struct objc_typed_stre int len; if ((len = (*stream->read)(stream->physical, buf, 1))) { - unsigned int key = 0; + unsigned long key = 0; if ((buf[0]&_B_CODE) == _B_RCOMM) /* register following */ { - len = __objc_read_nbyte_uint(stream, (buf[0] & _B_VALUE), &key); + len = __objc_read_nbyte_ulong(stream, (buf[0] & _B_VALUE), &key); len = (*stream->read)(stream->physical, buf, 1); } @@ -609,7 +749,7 @@ objc_read_string (struct objc_typed_stre int length = buf[0]&_B_VALUE; (*string) = (char*)__objc_xmalloc(length+1); if (key) - hash_add (&stream->stream_table, (void*)key, *string); + hash_add (&stream->stream_table, LONG2PTR(key), *string); len = (*stream->read)(stream->physical, *string, length); (*string)[length] = '\0'; } @@ -618,9 +758,9 @@ objc_read_string (struct objc_typed_stre case _B_UCOMM: { char *tmp; - len = __objc_read_nbyte_uint (stream, (buf[0] & _B_VALUE), &key); - tmp = hash_value_for_key (stream->stream_table, (void*)key); - *string = __objc_xmalloc (strlen (tmp) + 1); + len = __objc_read_nbyte_ulong(stream, (buf[0] & _B_VALUE), &key); + tmp = hash_value_for_key (stream->stream_table, LONG2PTR (key)); + *string = __objc_xmalloc (strlen(tmp) + 1); strcpy (*string, tmp); } break; @@ -632,7 +772,7 @@ objc_read_string (struct objc_typed_stre if (len) { (*string) = (char*)__objc_xmalloc(nbytes+1); if (key) - hash_add (&stream->stream_table, (void*)key, *string); + hash_add (&stream->stream_table, LONG2PTR(key), *string); len = (*stream->read)(stream->physical, *string, nbytes); (*string)[nbytes] = '\0'; } @@ -655,18 +795,18 @@ objc_read_object (struct objc_typed_stre int len; if ((len = (*stream->read)(stream->physical, buf, 1))) { - SEL read_sel = sel_get_uid ("read:"); - unsigned int key = 0; + SEL read_sel = sel_get_any_uid ("read:"); + unsigned long key = 0; if ((buf[0]&_B_CODE) == _B_RCOMM) /* register common */ { - len = __objc_read_nbyte_uint(stream, (buf[0] & _B_VALUE), &key); + len = __objc_read_nbyte_ulong(stream, (buf[0] & _B_VALUE), &key); len = (*stream->read)(stream->physical, buf, 1); } if (buf[0] == (_B_EXT | _BX_OBJECT)) { - Class* class; + Class class; /* get class */ len = objc_read_class (stream, &class); @@ -676,7 +816,7 @@ objc_read_object (struct objc_typed_stre /* register? */ if (key) - hash_add (&stream->object_table, (void*)key, *object); + hash_add (&stream->object_table, LONG2PTR(key), *object); /* send -read: */ if (__objc_responds_to (*object, read_sel)) @@ -692,16 +832,16 @@ objc_read_object (struct objc_typed_stre { if (key) __objc_fatal("cannot register use upcode..."); - len = __objc_read_nbyte_uint(stream, (buf[0] & _B_VALUE), &key); - (*object) = hash_value_for_key (stream->object_table, (void*)key); + len = __objc_read_nbyte_ulong(stream, (buf[0] & _B_VALUE), &key); + (*object) = hash_value_for_key (stream->object_table, LONG2PTR(key)); } else if (buf[0] == (_B_EXT | _BX_OBJREF)) /* a forward reference */ { struct objc_list* other; - len = objc_read_unsigned_int (stream, &key); - other = (struct objc_list*)hash_value_for_key (stream->object_refs, (void*)key); - hash_add (&stream->object_refs, (void*)key, (void*)list_cons(object, other)); + len = objc_read_unsigned_long (stream, &key); + other = (struct objc_list*)hash_value_for_key (stream->object_refs, LONG2PTR(key)); + hash_add (&stream->object_refs, LONG2PTR(key), (void*)list_cons(object, other)); } else if (buf[0] == (_B_EXT | _BX_OBJROOT)) /* a root object */ @@ -719,24 +859,24 @@ objc_read_object (struct objc_typed_stre } static int -objc_read_class (struct objc_typed_stream* stream, Class** class) +objc_read_class (struct objc_typed_stream* stream, Class* class) { unsigned char buf[sizeof (unsigned int)]; int len; if ((len = (*stream->read)(stream->physical, buf, 1))) { - unsigned int key = 0; + unsigned long key = 0; if ((buf[0]&_B_CODE) == _B_RCOMM) /* register following */ { - len = __objc_read_nbyte_uint(stream, (buf[0] & _B_VALUE), &key); + len = __objc_read_nbyte_ulong(stream, (buf[0] & _B_VALUE), &key); len = (*stream->read)(stream->physical, buf, 1); } if (buf[0] == (_B_EXT | _BX_CLASS)) { char* class_name; - int version; + unsigned long version; /* get class */ len = objc_read_string (stream, &class_name); @@ -745,9 +885,9 @@ objc_read_class (struct objc_typed_strea /* register */ if (key) - hash_add (&stream->stream_table, (void*)key, *class); + hash_add (&stream->stream_table, LONG2PTR(key), *class); - objc_read_unsigned_int(stream, &version); + objc_read_unsigned_long(stream, &version); hash_add (&stream->class_table, (*class)->name, (void*)version); } @@ -755,10 +895,10 @@ objc_read_class (struct objc_typed_strea { if (key) __objc_fatal("cannot register use upcode..."); - len = __objc_read_nbyte_uint(stream, (buf[0] & _B_VALUE), &key); - (*class) = hash_value_for_key (stream->stream_table, (void*)key); + len = __objc_read_nbyte_ulong(stream, (buf[0] & _B_VALUE), &key); + (*class) = hash_value_for_key (stream->stream_table, LONG2PTR(key)); if (!*class) - __objc_fatal("cannot find class for key %x", key); + __objc_fatal("cannot find class for key %lu", key); } else @@ -774,11 +914,11 @@ objc_read_selector (struct objc_typed_st int len; if ((len = (*stream->read)(stream->physical, buf, 1))) { - unsigned int key = 0; + unsigned long key = 0; if ((buf[0]&_B_CODE) == _B_RCOMM) /* register following */ { - len = __objc_read_nbyte_uint(stream, (buf[0] & _B_VALUE), &key); + len = __objc_read_nbyte_ulong(stream, (buf[0] & _B_VALUE), &key); len = (*stream->read)(stream->physical, buf, 1); } @@ -788,20 +928,27 @@ objc_read_selector (struct objc_typed_st /* get selector */ len = objc_read_string (stream, &selector_name); - (*selector) = sel_get_uid(selector_name); + /* To handle NULL selectors */ + if (0 == strlen(selector_name)) + { + (*selector) = (SEL)0; + return 0; + } + else + (*selector) = sel_get_any_uid(selector_name); free (selector_name); /* register */ if (key) - hash_add (&stream->stream_table, (void*)key, *selector); + hash_add (&stream->stream_table, LONG2PTR(key), (void*)*selector); } else if ((buf[0]&_B_CODE) == _B_UCOMM) { if (key) __objc_fatal("cannot register use upcode..."); - len = __objc_read_nbyte_uint(stream, (buf[0] & _B_VALUE), &key); - (*selector) = hash_value_for_key (stream->stream_table, (void*)key); + len = __objc_read_nbyte_ulong(stream, (buf[0] & _B_VALUE), &key); + (*selector) = hash_value_for_key (stream->stream_table, LONG2PTR(key)); } else @@ -810,96 +957,6 @@ objc_read_selector (struct objc_typed_st return len; } -static int -objc_sizeof_type(const char* type) -{ - 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: - case _C_LNG: - return sizeof(int); - break; - - case _C_UINT: - case _C_ULNG: - return sizeof(unsigned int); - break; - - case _C_ATOM: - case _C_CHARPTR: - return sizeof(char*); - break; - - default: - fprintf(stderr, "objc_sizeof_type: cannot parse typespec: %s\n", type); - abort(); - } -} - - -static const char* -__objc_skip_type (const char* type) -{ - switch (*type) { - case _C_ID: - 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_ULNG: - case _C_FLT: - case _C_DBL: - return ++type; - break; - - case _C_ARY_B: - while(isdigit(*++type)); - type = __objc_skip_type(type); - if (*type == _C_ARY_E) - return ++type; - else - __objc_fatal("cannot parse typespec: %s", type); - break; - - default: - fprintf(stderr, "__objc_skip_type: cannot parse typespec: %s\n", type); - abort(); - } -} - /* ** USER LEVEL FUNCTIONS */ @@ -918,7 +975,7 @@ objc_write_type(TypedStream* stream, con break; case _C_CLASS: - return objc_write_class (stream, *(Class**)data); + return objc_write_class (stream, *(Class*)data); break; case _C_SEL: @@ -942,15 +999,21 @@ objc_write_type(TypedStream* stream, con break; case _C_INT: - case _C_LNG: return objc_write_int(stream, *(int*)data); break; case _C_UINT: - case _C_ULNG: return objc_write_unsigned_int(stream, *(unsigned int*)data); break; + case _C_LNG: + return objc_write_long(stream, *(long*)data); + break; + + case _C_ULNG: + return objc_write_unsigned_long(stream, *(unsigned long*)data); + break; + case _C_CHARPTR: return objc_write_string (stream, *(char**)data, strlen(*(char**)data)); break; @@ -967,6 +1030,22 @@ objc_write_type(TypedStream* stream, con } break; + case _C_STRUCT_B: + { + int acc_size = 0; + int align; + while (*type != _C_STRUCT_E && *type++ != '='); /* skip "=" */ + while (*type != _C_STRUCT_E); + { + align = objc_alignof_type (type); /* padd to alignment */ + acc_size += ROUND (acc_size, align); + objc_write_type (stream, type, ((char*)data)+acc_size); + acc_size += objc_sizeof_type (type); /* add component size */ + type = objc_skip_typespec (type); /* skip component */ + } + return 1; + } + default: fprintf(stderr, "objc_write_type: cannot parse typespec: %s\n", type); abort(); @@ -990,7 +1069,7 @@ objc_read_type(TypedStream* stream, cons break; case _C_CLASS: - return objc_read_class (stream, (Class**)data); + return objc_read_class (stream, (Class*)data); break; case _C_SEL: @@ -1014,15 +1093,21 @@ objc_read_type(TypedStream* stream, cons break; case _C_INT: - case _C_LNG: return objc_read_int (stream, (int*)data); break; case _C_UINT: - case _C_ULNG: return objc_read_unsigned_int (stream, (unsigned int*)data); break; + case _C_LNG: + return objc_read_long (stream, (long*)data); + break; + + case _C_ULNG: + return objc_read_unsigned_long (stream, (unsigned long*)data); + break; + case _C_CHARPTR: case _C_ATOM: return objc_read_string (stream, (char**)data); @@ -1036,6 +1121,22 @@ objc_read_type(TypedStream* stream, cons } break; + case _C_STRUCT_B: + { + int acc_size = 0; + int align; + while (*type != _C_STRUCT_E && *type++ != '='); /* skip "=" */ + while (*type != _C_STRUCT_E); + { + align = objc_alignof_type (type); /* padd to alignment */ + acc_size += ROUND (acc_size, align); + objc_read_type (stream, type, ((char*)data)+acc_size); + acc_size += objc_sizeof_type (type); /* add component size */ + type = objc_skip_typespec (type); /* skip component */ + } + return 1; + } + default: fprintf(stderr, "objc_read_type: cannot parse typespec: %s\n", type); abort(); @@ -1061,7 +1162,7 @@ objc_write_types (TypedStream* stream, c va_start(args, type); - for (c = type; *c; c = __objc_skip_type (c)) + for (c = type; *c; c = objc_skip_typespec (c)) { switch(*c) { case _C_ID: @@ -1069,7 +1170,7 @@ objc_write_types (TypedStream* stream, c break; case _C_CLASS: - res = objc_write_class (stream, *va_arg(args, Class**)); + res = objc_write_class (stream, *va_arg(args, Class*)); break; case _C_SEL: @@ -1095,15 +1196,21 @@ objc_write_types (TypedStream* stream, c break; case _C_INT: - case _C_LNG: res = objc_write_int(stream, *va_arg(args, int*)); break; case _C_UINT: - case _C_ULNG: res = objc_write_unsigned_int(stream, *va_arg(args, unsigned int*)); break; + case _C_LNG: + res = objc_write_long(stream, *va_arg(args, long*)); + break; + + case _C_ULNG: + res = objc_write_unsigned_long(stream, *va_arg(args, unsigned long*)); + break; + case _C_CHARPTR: { char** str = va_arg(args, char**); @@ -1124,7 +1231,7 @@ objc_write_types (TypedStream* stream, c const char* t = c; while (isdigit(*++t)); res = objc_write_array (stream, t, len, va_arg(args, void*)); - t = __objc_skip_type (t); + t = objc_skip_typespec (t); if (*t != _C_ARY_E) __objc_fatal("expected `]', got: %s", t); } @@ -1154,7 +1261,7 @@ objc_read_types(TypedStream* stream, con va_start(args, type); - for (c = type; *c; c = __objc_skip_type(c)) + for (c = type; *c; c = objc_skip_typespec(c)) { switch(*c) { case _C_ID: @@ -1162,7 +1269,7 @@ objc_read_types(TypedStream* stream, con break; case _C_CLASS: - res = objc_read_class(stream, va_arg(args, Class**)); + res = objc_read_class(stream, va_arg(args, Class*)); break; case _C_SEL: @@ -1186,15 +1293,21 @@ objc_read_types(TypedStream* stream, con break; case _C_INT: - case _C_LNG: res = objc_read_int(stream, va_arg(args, int*)); break; case _C_UINT: - case _C_ULNG: res = objc_read_unsigned_int(stream, va_arg(args, unsigned int*)); break; + case _C_LNG: + res = objc_read_long(stream, va_arg(args, long*)); + break; + + case _C_ULNG: + res = objc_read_unsigned_long(stream, va_arg(args, unsigned long*)); + break; + case _C_CHARPTR: case _C_ATOM: { @@ -1209,7 +1322,7 @@ objc_read_types(TypedStream* stream, con const char* t = c; while (isdigit(*++t)); res = objc_read_array (stream, t, len, va_arg(args, void*)); - t = __objc_skip_type (t); + t = objc_skip_typespec (t); if (*t != _C_ARY_E) __objc_fatal("expected `]', got: %s", t); } @@ -1266,6 +1379,12 @@ objc_read_array (TypedStream* stream, co return 1; } +static void +__objc_free (void* p) +{ + free (p); +} + static int __objc_fread(FILE* file, char* data, int len) { @@ -1331,9 +1450,11 @@ static void __objc_finish_write_root_obj static void __objc_finish_read_root_object(struct objc_typed_stream* stream) { node_ptr node; - SEL awake_sel = sel_get_uid ("awake"); + struct objc_list* free_list; + SEL awake_sel = sel_get_any_uid ("awake"); /* resolve object forward references */ + free_list = list_cons(NULL, NULL); for (node = hash_next (stream->object_refs, NULL); node; node = hash_next (stream->object_refs, node)) { @@ -1343,10 +1464,13 @@ static void __objc_finish_read_root_obje while(reflist) { *((id*)reflist->head) = object; + if (list_find(&free_list, reflist) == NULL) + free_list = list_cons (reflist, free_list); reflist = reflist->tail; } - list_free (node->value); } + list_mapcar (free_list, __objc_free); + list_free (free_list); /* empty object reference table */ hash_delete (stream->object_refs); @@ -1379,8 +1503,6 @@ static void __objc_finish_read_root_obje TypedStream* objc_open_typed_stream (FILE* physical, int mode) { - int fflush(FILE*); - TypedStream* s = (TypedStream*)__objc_xmalloc(sizeof(TypedStream)); s->mode = mode; @@ -1483,13 +1605,12 @@ objc_flush_typed_stream (TypedStream* st (*stream->flush)(stream->physical); } -int -objc_get_stream_class_version (TypedStream* stream, Class* class) +long +objc_get_stream_class_version (TypedStream* stream, Class class) { if (stream->class_table) - return (int) hash_value_for_key (stream->class_table, class->name); + return PTR2LONG(hash_value_for_key (stream->class_table, class->name)); else return class_get_version (class); } -#endif /* __alpha__ */