1 /**
2 ** @file mruby/value.h - mruby value definitions
3 **
4 ** See Copyright Notice in mruby.h
5 */
6 
7 #ifndef MRUBY_VALUE_H
8 #define MRUBY_VALUE_H
9 
10 #include "common.h"
11 
12 /*
13  * MRuby Value definition functions and macros.
14  */
15 MRB_BEGIN_DECL
16 
17 /**
18  * mruby Symbol.
19  * @class mrb_sym
20  *
21  * You can create an mrb_sym by simply using mrb_str_intern() or mrb_intern_cstr()
22  */
23 typedef uint32_t mrb_sym;
24 
25 /**
26  * mruby Boolean.
27  * @class mrb_bool
28  *
29  *
30  * Used internally to represent boolean. Can be TRUE or FALSE.
31  * Not to be confused with Ruby's boolean classes, which can be
32  * obtained using mrb_false_value() and mrb_true_value()
33  */
34 typedef uint8_t mrb_bool;
35 struct mrb_state;
36 
37 #if defined _MSC_VER && _MSC_VER < 1800
38 # define PRIo64 "llo"
39 # define PRId64 "lld"
40 # define PRIu64 "llu"
41 # define PRIx64 "llx"
42 # define PRIo16 "ho"
43 # define PRId16 "hd"
44 # define PRIu16 "hu"
45 # define PRIx16 "hx"
46 # define PRIo32 "o"
47 # define PRId32 "d"
48 # define PRIu32 "u"
49 # define PRIx32 "x"
50 #else
51 # include <inttypes.h>
52 #endif
53 
54 #if defined(MRB_INT64)
55   typedef int64_t mrb_int;
56 # define MRB_INT_BIT 64
57 # define MRB_INT_MIN (INT64_MIN>>MRB_FIXNUM_SHIFT)
58 # define MRB_INT_MAX (INT64_MAX>>MRB_FIXNUM_SHIFT)
59 # define MRB_PRIo PRIo64
60 # define MRB_PRId PRId64
61 # define MRB_PRIx PRIx64
62 #else
63   typedef int32_t mrb_int;
64 # define MRB_INT_BIT 32
65 # define MRB_INT_MIN (INT32_MIN>>MRB_FIXNUM_SHIFT)
66 # define MRB_INT_MAX (INT32_MAX>>MRB_FIXNUM_SHIFT)
67 # define MRB_PRIo PRIo32
68 # define MRB_PRId PRId32
69 # define MRB_PRIx PRIx32
70 #endif
71 
72 #ifdef MRB_ENDIAN_BIG
73 # define MRB_ENDIAN_LOHI(a,b) a b
74 #else
75 # define MRB_ENDIAN_LOHI(a,b) b a
76 #endif
77 
78 #ifndef MRB_WITHOUT_FLOAT
79 MRB_API double mrb_float_read(const char*, char**);
80 #ifdef MRB_USE_FLOAT
81   typedef float mrb_float;
82 #else
83   typedef double mrb_float;
84 #endif
85 #endif
86 
87 #if defined _MSC_VER && _MSC_VER < 1900
88 # include <stdarg.h>
89 MRB_API int mrb_msvc_vsnprintf(char *s, size_t n, const char *format, va_list arg);
90 MRB_API int mrb_msvc_snprintf(char *s, size_t n, const char *format, ...);
91 # define vsnprintf(s, n, format, arg) mrb_msvc_vsnprintf(s, n, format, arg)
92 # define snprintf(s, n, format, ...) mrb_msvc_snprintf(s, n, format, __VA_ARGS__)
93 # if _MSC_VER < 1800 && !defined MRB_WITHOUT_FLOAT
94 #  include <float.h>
95 #  define isfinite(n) _finite(n)
96 #  define isnan _isnan
97 #  define isinf(n) (!_finite(n) && !_isnan(n))
98 #  define signbit(n) (_copysign(1.0, (n)) < 0.0)
99 static const unsigned int IEEE754_INFINITY_BITS_SINGLE = 0x7F800000;
100 #  define INFINITY (*(float *)&IEEE754_INFINITY_BITS_SINGLE)
101 #  define NAN ((float)(INFINITY - INFINITY))
102 # endif
103 #endif
104 
105 enum mrb_vtype {
106   MRB_TT_FALSE = 0,
107   MRB_TT_TRUE,
108   MRB_TT_FLOAT,
109   MRB_TT_FIXNUM,
110   MRB_TT_SYMBOL,
111   MRB_TT_UNDEF,
112   MRB_TT_CPTR,
113   MRB_TT_FREE,
114   MRB_TT_OBJECT,
115   MRB_TT_CLASS,
116   MRB_TT_MODULE,
117   MRB_TT_ICLASS,
118   MRB_TT_SCLASS,
119   MRB_TT_PROC,
120   MRB_TT_ARRAY,
121   MRB_TT_HASH,
122   MRB_TT_STRING,
123   MRB_TT_RANGE,
124   MRB_TT_EXCEPTION,
125   MRB_TT_ENV,
126   MRB_TT_DATA,
127   MRB_TT_FIBER,
128   MRB_TT_ISTRUCT,
129   MRB_TT_BREAK,
130   MRB_TT_MAXDEFINE
131 };
132 
133 #include <mruby/object.h>
134 
135 #ifdef MRB_DOCUMENTATION_BLOCK
136 
137 /**
138  * @abstract
139  * MRuby value boxing.
140  *
141  * Actual implementation depends on configured boxing type.
142  *
143  * @see mruby/boxing_no.h Default boxing representation
144  * @see mruby/boxing_word.h Word representation
145  * @see mruby/boxing_nan.h Boxed double representation
146  */
147 typedef void mrb_value;
148 
149 #endif
150 
151 #if defined(MRB_WORD_BOXING) || (defined(MRB_NAN_BOXING) && defined(MRB_64BIT))
152 struct RCptr {
153   MRB_OBJECT_HEADER;
154   void *p;
155 };
156 #endif
157 
158 #if defined(MRB_NAN_BOXING)
159 #include "boxing_nan.h"
160 #elif defined(MRB_WORD_BOXING)
161 #include "boxing_word.h"
162 #else
163 #include "boxing_no.h"
164 #endif
165 
166 #define MRB_SYMBOL_BIT (sizeof(mrb_sym) * CHAR_BIT - MRB_SYMBOL_SHIFT)
167 #define MRB_SYMBOL_MAX (UINT32_MAX >> MRB_SYMBOL_SHIFT)
168 
169 #if INTPTR_MAX < MRB_INT_MAX
170   typedef intptr_t mrb_ssize;
171 # define MRB_SSIZE_MAX (INTPTR_MAX>>MRB_FIXNUM_SHIFT)
172 #else
173   typedef mrb_int mrb_ssize;
174 # define MRB_SSIZE_MAX MRB_INT_MAX
175 #endif
176 
177 #ifndef mrb_immediate_p
178 #define mrb_immediate_p(o) (mrb_type(o) < MRB_TT_FREE)
179 #endif
180 #ifndef mrb_fixnum_p
181 #define mrb_fixnum_p(o) (mrb_type(o) == MRB_TT_FIXNUM)
182 #endif
183 #ifndef mrb_symbol_p
184 #define mrb_symbol_p(o) (mrb_type(o) == MRB_TT_SYMBOL)
185 #endif
186 #ifndef mrb_undef_p
187 #define mrb_undef_p(o) (mrb_type(o) == MRB_TT_UNDEF)
188 #endif
189 #ifndef mrb_nil_p
190 #define mrb_nil_p(o)  (mrb_type(o) == MRB_TT_FALSE && !mrb_fixnum(o))
191 #endif
192 #ifndef mrb_false_p
193 #define mrb_false_p(o) (mrb_type(o) == MRB_TT_FALSE && !!mrb_fixnum(o))
194 #endif
195 #ifndef mrb_true_p
196 #define mrb_true_p(o)  (mrb_type(o) == MRB_TT_TRUE)
197 #endif
198 #ifndef MRB_WITHOUT_FLOAT
199 #ifndef mrb_float_p
200 #define mrb_float_p(o) (mrb_type(o) == MRB_TT_FLOAT)
201 #endif
202 #endif
203 #ifndef mrb_array_p
204 #define mrb_array_p(o) (mrb_type(o) == MRB_TT_ARRAY)
205 #endif
206 #ifndef mrb_string_p
207 #define mrb_string_p(o) (mrb_type(o) == MRB_TT_STRING)
208 #endif
209 #ifndef mrb_hash_p
210 #define mrb_hash_p(o) (mrb_type(o) == MRB_TT_HASH)
211 #endif
212 #ifndef mrb_cptr_p
213 #define mrb_cptr_p(o) (mrb_type(o) == MRB_TT_CPTR)
214 #endif
215 #ifndef mrb_exception_p
216 #define mrb_exception_p(o) (mrb_type(o) == MRB_TT_EXCEPTION)
217 #endif
218 #ifndef mrb_free_p
219 #define mrb_free_p(o) (mrb_type(o) == MRB_TT_FREE)
220 #endif
221 #ifndef mrb_object_p
222 #define mrb_object_p(o) (mrb_type(o) == MRB_TT_OBJECT)
223 #endif
224 #ifndef mrb_class_p
225 #define mrb_class_p(o) (mrb_type(o) == MRB_TT_CLASS)
226 #endif
227 #ifndef mrb_module_p
228 #define mrb_module_p(o) (mrb_type(o) == MRB_TT_MODULE)
229 #endif
230 #ifndef mrb_iclass_p
231 #define mrb_iclass_p(o) (mrb_type(o) == MRB_TT_ICLASS)
232 #endif
233 #ifndef mrb_sclass_p
234 #define mrb_sclass_p(o) (mrb_type(o) == MRB_TT_SCLASS)
235 #endif
236 #ifndef mrb_proc_p
237 #define mrb_proc_p(o) (mrb_type(o) == MRB_TT_PROC)
238 #endif
239 #ifndef mrb_range_p
240 #define mrb_range_p(o) (mrb_type(o) == MRB_TT_RANGE)
241 #endif
242 #ifndef mrb_env_p
243 #define mrb_env_p(o) (mrb_type(o) == MRB_TT_ENV)
244 #endif
245 #ifndef mrb_data_p
246 #define mrb_data_p(o) (mrb_type(o) == MRB_TT_DATA)
247 #endif
248 #ifndef mrb_fiber_p
249 #define mrb_fiber_p(o) (mrb_type(o) == MRB_TT_FIBER)
250 #endif
251 #ifndef mrb_istruct_p
252 #define mrb_istruct_p(o) (mrb_type(o) == MRB_TT_ISTRUCT)
253 #endif
254 #ifndef mrb_break_p
255 #define mrb_break_p(o) (mrb_type(o) == MRB_TT_BREAK)
256 #endif
257 #ifndef mrb_bool
258 #define mrb_bool(o)   (mrb_type(o) != MRB_TT_FALSE)
259 #endif
260 #define mrb_test(o)   mrb_bool(o)
261 
262 /**
263  * Returns a float in Ruby.
264  *
265  * Takes a float and boxes it into an mrb_value
266  */
267 #ifndef MRB_WITHOUT_FLOAT
mrb_float_value(struct mrb_state * mrb,mrb_float f)268 MRB_INLINE mrb_value mrb_float_value(struct mrb_state *mrb, mrb_float f)
269 {
270   mrb_value v;
271   (void) mrb;
272   SET_FLOAT_VALUE(mrb, v, f);
273   return v;
274 }
275 #endif
276 
277 MRB_INLINE mrb_value
mrb_cptr_value(struct mrb_state * mrb,void * p)278 mrb_cptr_value(struct mrb_state *mrb, void *p)
279 {
280   mrb_value v;
281   (void) mrb;
282   SET_CPTR_VALUE(mrb,v,p);
283   return v;
284 }
285 
286 /**
287  * Returns a fixnum in Ruby.
288  *
289  * Takes an integer and boxes it into an mrb_value
290  */
mrb_fixnum_value(mrb_int i)291 MRB_INLINE mrb_value mrb_fixnum_value(mrb_int i)
292 {
293   mrb_value v;
294   SET_INT_VALUE(v, i);
295   return v;
296 }
297 
298 MRB_INLINE mrb_value
mrb_symbol_value(mrb_sym i)299 mrb_symbol_value(mrb_sym i)
300 {
301   mrb_value v;
302   SET_SYM_VALUE(v, i);
303   return v;
304 }
305 
306 MRB_INLINE mrb_value
mrb_obj_value(void * p)307 mrb_obj_value(void *p)
308 {
309   mrb_value v;
310   SET_OBJ_VALUE(v, (struct RBasic*)p);
311   mrb_assert(p == mrb_ptr(v));
312   mrb_assert(((struct RBasic*)p)->tt == mrb_type(v));
313   return v;
314 }
315 
316 /**
317  * Get a nil mrb_value object.
318  *
319  * @return
320  *      nil mrb_value object reference.
321  */
mrb_nil_value(void)322 MRB_INLINE mrb_value mrb_nil_value(void)
323 {
324   mrb_value v;
325   SET_NIL_VALUE(v);
326   return v;
327 }
328 
329 /**
330  * Returns false in Ruby.
331  */
mrb_false_value(void)332 MRB_INLINE mrb_value mrb_false_value(void)
333 {
334   mrb_value v;
335   SET_FALSE_VALUE(v);
336   return v;
337 }
338 
339 /**
340  * Returns true in Ruby.
341  */
mrb_true_value(void)342 MRB_INLINE mrb_value mrb_true_value(void)
343 {
344   mrb_value v;
345   SET_TRUE_VALUE(v);
346   return v;
347 }
348 
349 MRB_INLINE mrb_value
mrb_bool_value(mrb_bool boolean)350 mrb_bool_value(mrb_bool boolean)
351 {
352   mrb_value v;
353   SET_BOOL_VALUE(v, boolean);
354   return v;
355 }
356 
357 MRB_INLINE mrb_value
mrb_undef_value(void)358 mrb_undef_value(void)
359 {
360   mrb_value v;
361   SET_UNDEF_VALUE(v);
362   return v;
363 }
364 
365 #if defined(MRB_USE_ETEXT_EDATA) && !defined(MRB_USE_LINK_TIME_RO_DATA_P)
366 # ifdef __GNUC__
367 #  warning MRB_USE_ETEXT_EDATA is deprecated. Define MRB_USE_LINK_TIME_RO_DATA_P instead.
368 # endif
369 # define MRB_USE_LINK_TIME_RO_DATA_P
370 #endif
371 
372 #if defined(MRB_USE_CUSTOM_RO_DATA_P)
373 /* If you define `MRB_USE_CUSTOM_RO_DATA_P`, you must implement `mrb_ro_data_p()`. */
374 mrb_bool mrb_ro_data_p(const char *p);
375 #elif defined(MRB_USE_LINK_TIME_RO_DATA_P)
376 extern char __ehdr_start[];
377 extern char __init_array_start[];
378 
379 static inline mrb_bool
mrb_ro_data_p(const char * p)380 mrb_ro_data_p(const char *p)
381 {
382   return __ehdr_start < p && p < __init_array_start;
383 }
384 #else
385 # define mrb_ro_data_p(p) FALSE
386 #endif
387 
388 MRB_END_DECL
389 
390 #endif  /* MRUBY_VALUE_H */
391