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