1 /* $Id: __oo2c.h,v 1.49 2005/12/05 17:32:57 mva Exp $ */ 2 /* Run-time system for C back-ends of OOC2 3 Copyright (C) 2001-2003, 2005 Michael van Acken 4 5 This module is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public License 7 as published by the Free Software Foundation; either version 2 of 8 the License, or (at your option) any later version. 9 10 This module is distributed in the hope that it will be useful, but 11 WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with OOC. If not, write to the Free Software Foundation, 17 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 */ 19 #ifndef __oo2c__ 20 #define __oo2c__ 21 22 #include "__config.h" 23 #include "__typemap.h" 24 #include "__libc.h" 25 #include "__dynvar.h" 26 27 /* Define attributes that mark functions that won't return. These attributes 28 are only used in __oo2c.h and __oo2c.c: */ 29 #undef NORETURN 30 #undef NORETURN2 31 #if defined(__GNUC__) && (__GNUC__>2 || (__GNUC__==2 && __GNUC_MINOR__>=6)) 32 #define NORETURN 33 #define NORETURN2 __attribute__ ((__noreturn__)) 34 #else 35 #define NORETURN 36 #define NORETURN2 37 #endif 38 39 /* Testing for __builtin_strcmp is not as easy as expected, so we 40 hardcode it here. */ 41 #define HAVE_BUILTIN_STRCMP 1 42 43 /* Use lrint() for round() in RealMath and LRealMath if it is available, 44 otherwise use our own definitions in __oo2c.c. The prototype for lrint() 45 is in __libc.h. */ 46 #ifdef HAVE_LRINT 47 #define ooc_round_real32(_x) (OOC_INT32)lrint(_x) 48 #define ooc_round_real64(_x) (OOC_INT32)lrint(_x) 49 #endif 50 51 52 #define _check_index(index,length,utype,pos) \ 53 ({ if ((utype)index >= (OOC_ULEN)length) { \ 54 RT0__ErrorIndexOutOfRange(&_mid,pos,index,length); \ 55 } \ 56 index; }) 57 #define _check_pointer(adr,pos) \ 58 ({ if ((void*)adr == NULL) { \ 59 RT0__ErrorDerefOfNil(&_mid,pos); \ 60 } \ 61 adr; }) 62 #define _type_guard(adr,tag,guard,pos) \ 63 ({ if (!OOC_TYPE_TEST(tag,guard)) { \ 64 RT0__ErrorFailedTypeGuard(&_mid,pos,(RT0__Struct)tag); \ 65 } \ 66 adr; }) 67 #define _type_guard_q(adr,tag,receiver,guard,pos) \ 68 ({ if (!RT0__TypeTest((RT0__Struct)tag,(RT0__Struct)guard,(RT0__Struct)receiver)) { \ 69 RT0__ErrorFailedTypeGuard(&_mid,pos,(RT0__Struct)tag); \ 70 } \ 71 adr; }) 72 #define _failed_case(select,pos) RT0__ErrorFailedCase(&_mid,pos,select) 73 #define _failed_with(type_tag,pos) RT0__ErrorFailedWith(&_mid,pos,(RT0__Struct)type_tag) 74 #define _failed_type_assert(pos) RT0__ErrorFailedTypeAssert(&_mid,pos) 75 #define _failed_function(pos) RT0__ErrorFailedFunction(&_mid,pos) 76 77 78 /* ASSERT(p), ASSERT(p,code), and HALT(code) */ 79 #define _assert(p,code,pos) \ 80 if (!(p)) { RT0__ErrorAssertionFailed(&_mid,pos,code); } 81 #define _halt(code) RT0__Halt(code); 82 83 /* COPY(s,d) */ 84 extern void _copy_8(const OOC_CHAR8* src, OOC_CHAR8* dest, OOC_LEN max_len); 85 extern void _copy_8to16(const OOC_CHAR8* src, OOC_CHAR16* dest, OOC_LEN max_len); 86 extern void _copy_8to32(const OOC_CHAR8* src, OOC_CHAR32* dest, OOC_LEN max_len); 87 extern void _copy_16(const OOC_CHAR16* src, OOC_CHAR16* dest, OOC_LEN max_len); 88 extern void _copy_16to32(const OOC_CHAR16* src, OOC_CHAR32* dest, OOC_LEN max_len); 89 extern void _copy_32(const OOC_CHAR32* src, OOC_CHAR32* dest, OOC_LEN max_len); 90 91 /* copy record or array value */ 92 #define _copy_block(_src,_dest,_len) \ 93 memcpy((void*)_dest,(void*)_src,_len) 94 95 /* copy memory block (SYSTEM.MOVE) */ 96 #define _move_block(_source,_dest,_size) \ 97 memcpy((void*)_dest,(void*)_source,_size) 98 99 /* string compare */ 100 #ifdef HAVE_BUILTIN_STRCMP 101 #define _cmp8(a,b) ((OOC_INT32)__builtin_strcmp((a),(b))) 102 #else 103 extern OOC_INT32 _cmp8(const OOC_CHAR8* l, const OOC_CHAR8* r); 104 #endif 105 extern OOC_INT32 _cmp16(const OOC_CHAR16* l, const OOC_CHAR16* r); 106 extern OOC_INT32 _cmp32(const OOC_CHAR32* l, const OOC_CHAR32* r); 107 108 /* range of set values */ 109 #define _bit_range(_from,_to) (_from > _to) ? (OOC_UINT32)0 : \ 110 (((OOC_UINT32)1 << _to)*2-1) & ~(((OOC_UINT32)1 << _from)-1) 111 112 /* ABS(numeric) */ 113 #define _abs(_x) (_x<0?-_x:_x) 114 115 /* ASH(x,n) */ 116 #define _ashl(_x,_n) (_x << _n) 117 #define _ashr(_x,_n) (_x >> _n) | ((_x >= 0) ? 0 : ~(~(OOC_INT32)0 >> _n)) 118 #define _ash(_x,_n) (_n >= 0) ? _ashl(_x,_n) : _ashr(_x,- _n) 119 120 /* SYSTEM.LSH(x,n) */ 121 #define _lshl(_x,_n,_type,_typeU) ((_type)((_typeU)(_x) << _n)) 122 #define _lshr(_x,_n,_type,_typeU) ((_type)((_typeU)(_x) >> _n)) 123 #define _lsh(_type,_typeU,_x,_n) ((_n >= 0) ? _lshl(_x,_n,_type,_typeU) : _lshr(_x,- _n,_type,_typeU)) 124 125 /* SYSTEM.ROT(x,n) */ 126 #define _rot(_type,_typeU,_x,_n) \ 127 ({ int bits = sizeof(_type)*8; \ 128 _type res; \ 129 if (_n % bits >= 0) { \ 130 res = ((_typeU)_x << _n % bits) | ((_typeU)_x >> (bits - _n % bits)); \ 131 } else { \ 132 res = ((_typeU)_x >> -(_n % bits)) | ((_typeU)_x << (bits + _n % bits)); \ 133 } \ 134 res; }) 135 136 /* CAP(CHAR) and CAP(LONGCHAR) */ 137 #define _cap(_c) ((96<_c && _c<123) || (224<=_c && _c<255 && _c!=247)) ? (_c-32) : _c 138 #define _capl(_c) _cap(_c) 139 140 /* ENTIER(real) */ 141 #define _entier(_r) ((OOC_INT32)floor(_r)) 142 143 /* ODD(integer) */ 144 #define _odd(_i) ((_i) & 1) 145 146 /* DIV(integer, integer) -- note: macro uses gcc style expression statement */ 147 /* def: sign(_x MOD _y)==sign(_y) */ 148 /*#define _div(_x,_y) ({ \ 149 typeof(_x) _quot = _x / _y, _rem = _x % _y; \ 150 if (_rem && ((_rem > 0) != (_y > 0))) _quot--; \ 151 _quot; })*/ 152 /* def: _x MOD _y >= 0 for _y>0, and undefined otherwise */ 153 #define _div(_x,_y) ({ \ 154 typeof(_x) _quot = _x / _y; \ 155 if ((_x<0) && (_y>0) && (_quot*_y!=_x)) _quot--; \ 156 _quot; }) 157 158 /* MOD(integer, integer) -- note: macro uses gcc style expression statement */ 159 /* def: sign(_x MOD _y)==sign(_y) */ 160 /*#define _mod(_x,_y) ({ \ 161 typeof(_x) _rem = _x % _y; \ 162 if (_rem && ((_rem > 0) != (_y > 0))) _rem += _y; \ 163 _rem; })*/ 164 /* def: _x MOD _y >= 0 for _y>0, and undefined otherwise */ 165 #define _mod(_x,_y) ({ \ 166 typeof(_x) _rem = _x % _y; \ 167 if ((_x<0) && (_y>0) && (_rem != 0)) _rem += _y; \ 168 _rem; }) 169 170 /* i IN s */ 171 #define _in(_i,_s) (((_s)>>(_i))&1) 172 173 /* set difference */ 174 #define _logical_subtr(_a,_b) (_a & ~(_b)) 175 176 /* INCL, EXCL */ 177 #define _set_bit(_s,_i) ((_s) | (((typeof(_s))1) << (_i))) 178 #define _clear_bit(_s,_i) ((_s) & ~(((typeof(_s))1) << (_i))) 179 180 181 /* SYSTEM.VAL */ 182 #define _type_cast(_destType, _sourceType, _x) \ 183 ({ union {_sourceType s; _destType d;} _v; _v.s=_x; _v.d; }) 184 #define _type_cast_fast(_destType, _sourceType, _x) \ 185 (_destType)(_sourceType)_x 186 187 188 189 /* run-time meta data: type tags, dynamic array length, type test */ 190 #define OOC_ARRAY_LENGTH(_adr,_dim) (((OOC_LEN*)(_adr))[-(_dim)-1]) 191 192 #define OOC_TYPE_DESCR(_module,_type_name) &_td_##_module##__##_type_name 193 194 #define OOC_PTRBASE_DESCR(_module,_type_name) \ 195 (_td_##_module##__##_type_name.baseTypes[0]) 196 197 #define OOC_TYPE_TAG(_adr) (((RT0__Struct*)(_adr))[-1]) 198 199 #define OOC_TYPE_TEST(_tag,_td) \ 200 ((((RT0__Struct)(_tag))->len >= (_td)->len) && \ 201 (((RT0__Struct)(_tag))->baseTypes[(_td)->len] == (_td))) 202 #define OOC_TYPE_TEST_Q(_tag,_td,_receiver) \ 203 RT0__TypeTest((RT0__Struct)_tag, (RT0__Struct)_td, (RT0__Struct)_receiver) 204 205 #define OOC_TBPROC_ADR(_tag,_name) (((RT0__Struct)(_tag))->tbProcs[_TBN_##_name]) 206 207 #define OOC_VTABLEPROC_ADR(_adr,_name) (((OOC_PTR **) _adr)[0][_TBN_##_name]) 208 209 #define OOC_TBCALL(_adr,_name) ((_TBP_##_name)(_adr)) 210 211 #define OOC_METHOD(_obj,_name) \ 212 ((_TBP_##_name)OOC_TBPROC_ADR(OOC_TYPE_TAG(_obj),_name)) 213 214 215 #define STATIC_TBCALL(_module,_type_name,_tb_proc_name,_receiver,_param_list) \ 216 _module##__##_type_name##_##_tb_proc_name _param_list 217 #define DYN_TBCALL(_module,_type_name,_tb_proc_name,_receiver,_param_list) \ 218 ((_TBP_##_module##__##_type_name##_##_tb_proc_name)((*((RT0__Struct*)(_receiver)-1))->tbProcs[_TBN_##_module##__##_type_name##_##_tb_proc_name]))_param_list 219 220 221 #endif /* __oo2c__ */ 222