Groonga 3.0.9 Source Code Document
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
value.h
Go to the documentation of this file.
1 /*
2 ** mruby/value.h - mrb_value definition
3 **
4 ** See Copyright Notice in mruby.h
5 */
6 
7 #ifndef MRUBY_VALUE_H
8 #define MRUBY_VALUE_H
9 
10 #ifdef MRB_USE_FLOAT
11  typedef float mrb_float;
12 # define mrb_float_to_str(buf, i) sprintf(buf, "%.7e", i)
13 # define str_to_mrb_float(buf) strtof(buf, NULL)
14 #else
15  typedef double mrb_float;
16 # define mrb_float_to_str(buf, i) sprintf(buf, "%.16e", i)
17 # define str_to_mrb_float(buf) strtod(buf, NULL)
18 #endif
19 
20 #if defined(MRB_INT16) && defined(MRB_INT64)
21 # error "You can't define MRB_INT16 and MRB_INT64 at the same time."
22 #endif
23 
24 #if defined(MRB_INT64)
25 # ifdef MRB_NAN_BOXING
26 # error Cannot use NaN boxing when mrb_int is 64bit
27 # else
28  typedef int64_t mrb_int;
29 # define MRB_INT_MIN INT64_MIN
30 # define MRB_INT_MAX INT64_MAX
31 # define PRIdMRB_INT PRId64
32 # define PRIiMRB_INT PRIi64
33 # define PRIoMRB_INT PRIo64
34 # define PRIxMRB_INT PRIx64
35 # define PRIXMRB_INT PRIX64
36 # endif
37 #elif defined(MRB_INT16)
38  typedef int16_t mrb_int;
39 # define MRB_INT_MIN INT16_MIN
40 # define MRB_INT_MAX INT16_MAX
41 #else
42  typedef int32_t mrb_int;
43 # define MRB_INT_MIN INT32_MIN
44 # define MRB_INT_MAX INT32_MAX
45 # define PRIdMRB_INT PRId32
46 # define PRIiMRB_INT PRIi32
47 # define PRIoMRB_INT PRIo32
48 # define PRIxMRB_INT PRIx32
49 # define PRIXMRB_INT PRIX32
50 #endif
51 typedef short mrb_sym;
52 
53 #ifdef _MSC_VER
54 # ifndef __cplusplus
55 # define inline __inline
56 # endif
57 # define snprintf _snprintf
58 # if _MSC_VER < 1800
59 # include <float.h>
60 # define isnan _isnan
61 # define isinf(n) (!_finite(n) && !_isnan(n))
62 # define strtoll _strtoi64
63 # define strtof (float)strtod
64 # define PRId32 "I32d"
65 # define PRIi32 "I32i"
66 # define PRIo32 "I32o"
67 # define PRIx32 "I32x"
68 # define PRIX32 "I32X"
69 # define PRId64 "I64d"
70 # define PRIi64 "I64i"
71 # define PRIo64 "I64o"
72 # define PRIx64 "I64x"
73 # define PRIX64 "I64X"
74 # else
75 # include <inttypes.h>
76 # endif
77 #else
78 # include <inttypes.h>
79 #endif
80 
81 typedef uint8_t mrb_bool;
82 struct mrb_state;
83 
84 #if defined(MRB_NAN_BOXING)
85 
86 #ifdef MRB_USE_FLOAT
87 # error ---->> MRB_NAN_BOXING and MRB_USE_FLOAT conflict <<----
88 #endif
89 
90 #ifdef MRB_INT64
91 # error ---->> MRB_NAN_BOXING and MRB_INT64 conflict <<----
92 #endif
93 
94 enum mrb_vtype {
95  MRB_TT_FALSE = 1, /* 1 */
96  MRB_TT_FREE, /* 2 */
97  MRB_TT_TRUE, /* 3 */
98  MRB_TT_FIXNUM, /* 4 */
99  MRB_TT_SYMBOL, /* 5 */
100  MRB_TT_UNDEF, /* 6 */
101  MRB_TT_FLOAT, /* 7 */
102  MRB_TT_CPTR, /* 8 */
103  MRB_TT_OBJECT, /* 9 */
104  MRB_TT_CLASS, /* 10 */
105  MRB_TT_MODULE, /* 11 */
106  MRB_TT_ICLASS, /* 12 */
107  MRB_TT_SCLASS, /* 13 */
108  MRB_TT_PROC, /* 14 */
109  MRB_TT_ARRAY, /* 15 */
110  MRB_TT_HASH, /* 16 */
111  MRB_TT_STRING, /* 17 */
112  MRB_TT_RANGE, /* 18 */
113  MRB_TT_EXCEPTION, /* 19 */
114  MRB_TT_FILE, /* 20 */
115  MRB_TT_ENV, /* 21 */
116  MRB_TT_DATA, /* 22 */
117  MRB_TT_FIBER, /* 23 */
118  MRB_TT_MAXDEFINE /* 24 */
119 };
120 
121 #define MRB_TT_HAS_BASIC MRB_TT_OBJECT
122 
123 #ifdef MRB_ENDIAN_BIG
124 #define MRB_ENDIAN_LOHI(a,b) a b
125 #else
126 #define MRB_ENDIAN_LOHI(a,b) b a
127 #endif
128 
129 typedef struct mrb_value {
130  union {
131  mrb_float f;
132  union {
133  void *p;
134  struct {
135  MRB_ENDIAN_LOHI(
136  uint32_t ttt;
137  ,union {
138  mrb_int i;
139  mrb_sym sym;
140  };
141  )
142  };
143  } value;
144  };
145 } mrb_value;
146 
147 /* value representation by nan-boxing:
148  * float : FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF
149  * object: 111111111111TTTT TTPPPPPPPPPPPPPP PPPPPPPPPPPPPPPP PPPPPPPPPPPPPPPP
150  * int : 1111111111110001 0000000000000000 IIIIIIIIIIIIIIII IIIIIIIIIIIIIIII
151  * sym : 1111111111110001 0100000000000000 SSSSSSSSSSSSSSSS SSSSSSSSSSSSSSSS
152  * In order to get enough bit size to save TT, all pointers are shifted 2 bits
153  * in the right direction.
154  */
155 #define mrb_tt(o) (((o).value.ttt & 0xfc000)>>14)
156 #define mrb_mktt(tt) (0xfff00000|((tt)<<14))
157 #define mrb_type(o) ((uint32_t)0xfff00000 < (o).value.ttt ? mrb_tt(o) : MRB_TT_FLOAT)
158 #define mrb_ptr(o) ((void*)((((intptr_t)0x3fffffffffff)&((intptr_t)((o).value.p)))<<2))
159 #define mrb_float(o) (o).f
160 
161 #define MRB_SET_VALUE(o, tt, attr, v) do {\
162  (o).value.ttt = mrb_mktt(tt);\
163  switch (tt) {\
164  case MRB_TT_FALSE:\
165  case MRB_TT_TRUE:\
166  case MRB_TT_UNDEF:\
167  case MRB_TT_FIXNUM:\
168  case MRB_TT_SYMBOL: (o).attr = (v); break;\
169  default: (o).value.i = 0; (o).value.p = (void*)((intptr_t)(o).value.p | (((intptr_t)(v))>>2)); break;\
170  }\
171 } while (0)
172 
173 static inline mrb_value
174 mrb_float_value(struct mrb_state *mrb, mrb_float f)
175 {
176  mrb_value v;
177 
178  if (f != f) {
179  v.value.ttt = 0x7ff80000;
180  v.value.i = 0;
181  } else {
182  v.f = f;
183  }
184  return v;
185 }
186 
187 #else
188 
189 enum mrb_vtype {
190  MRB_TT_FALSE = 0, /* 0 */
191  MRB_TT_FREE, /* 1 */
192  MRB_TT_TRUE, /* 2 */
193  MRB_TT_FIXNUM, /* 3 */
194  MRB_TT_SYMBOL, /* 4 */
195  MRB_TT_UNDEF, /* 5 */
196  MRB_TT_FLOAT, /* 6 */
197  MRB_TT_CPTR, /* 7 */
198  MRB_TT_OBJECT, /* 8 */
199  MRB_TT_CLASS, /* 9 */
200  MRB_TT_MODULE, /* 10 */
201  MRB_TT_ICLASS, /* 11 */
202  MRB_TT_SCLASS, /* 12 */
203  MRB_TT_PROC, /* 13 */
204  MRB_TT_ARRAY, /* 14 */
205  MRB_TT_HASH, /* 15 */
206  MRB_TT_STRING, /* 16 */
207  MRB_TT_RANGE, /* 17 */
209  MRB_TT_FILE, /* 19 */
210  MRB_TT_ENV, /* 20 */
211  MRB_TT_DATA, /* 21 */
212  MRB_TT_FIBER, /* 22 */
214 };
215 
216 #if defined(MRB_WORD_BOXING)
217 
218 #define MRB_TT_HAS_BASIC MRB_TT_FLOAT
219 
220 enum mrb_special_consts {
221  MRB_Qnil = 0,
222  MRB_Qfalse = 2,
223  MRB_Qtrue = 4,
224  MRB_Qundef = 6,
225 };
226 
227 #define MRB_FIXNUM_FLAG 0x01
228 #define MRB_FIXNUM_SHIFT 1
229 #define MRB_SYMBOL_FLAG 0x0e
230 #define MRB_SPECIAL_SHIFT 8
231 
232 typedef union mrb_value {
233  union {
234  void *p;
235  struct {
236  unsigned int i_flag : MRB_FIXNUM_SHIFT;
237  mrb_int i : (sizeof(mrb_int) * CHAR_BIT - MRB_FIXNUM_SHIFT);
238  };
239  struct {
240  unsigned int sym_flag : MRB_SPECIAL_SHIFT;
241  int sym : (sizeof(mrb_sym) * CHAR_BIT);
242  };
243  struct RBasic *bp;
244  struct RFloat *fp;
245  struct RCptr *vp;
246  } value;
247  unsigned long w;
248 } mrb_value;
249 
250 #define mrb_ptr(o) (o).value.p
251 #define mrb_float(o) (o).value.fp->f
252 
253 #define MRB_SET_VALUE(o, ttt, attr, v) do {\
254  (o).w = 0;\
255  (o).attr = (v);\
256  switch (ttt) {\
257  case MRB_TT_FALSE: (o).w = (v) ? MRB_Qfalse : MRB_Qnil; break;\
258  case MRB_TT_TRUE: (o).w = MRB_Qtrue; break;\
259  case MRB_TT_UNDEF: (o).w = MRB_Qundef; break;\
260  case MRB_TT_FIXNUM: (o).value.i_flag = MRB_FIXNUM_FLAG; break;\
261  case MRB_TT_SYMBOL: (o).value.sym_flag = MRB_SYMBOL_FLAG; break;\
262  default: if ((o).value.bp) (o).value.bp->tt = ttt; break;\
263  }\
264 } while (0)
265 
266 extern mrb_value
267 mrb_float_value(struct mrb_state *mrb, mrb_float f);
268 
269 #else /* No MRB_xxx_BOXING */
270 
271 #define MRB_TT_HAS_BASIC MRB_TT_OBJECT
272 
273 typedef struct mrb_value {
274  union {
276  void *p;
279  } value;
280  enum mrb_vtype tt;
281 } mrb_value;
282 
283 #define mrb_type(o) (o).tt
284 #define mrb_ptr(o) (o).value.p
285 #define mrb_float(o) (o).value.f
286 
287 #define MRB_SET_VALUE(o, ttt, attr, v) do {\
288  (o).tt = ttt;\
289  (o).attr = v;\
290 } while (0)
291 
292 static inline mrb_value
293 mrb_float_value(struct mrb_state *mrb, mrb_float f)
294 {
295  mrb_value v;
296  (void) mrb;
297 
298  MRB_SET_VALUE(v, MRB_TT_FLOAT, value.f, f);
299  return v;
300 }
301 
302 #endif /* no boxing */
303 
304 #endif
305 
306 #ifdef MRB_WORD_BOXING
307 
308 #define mrb_cptr(o) (o).value.vp->p
309 #define mrb_fixnum_p(o) ((o).value.i_flag == MRB_FIXNUM_FLAG)
310 #define mrb_undef_p(o) ((o).w == MRB_Qundef)
311 #define mrb_nil_p(o) ((o).w == MRB_Qnil)
312 #define mrb_bool(o) ((o).w != MRB_Qnil && (o).w != MRB_Qfalse)
313 
314 #else
315 #define mrb_cptr(o) mrb_ptr(o)
316 #define mrb_fixnum_p(o) (mrb_type(o) == MRB_TT_FIXNUM)
317 #define mrb_undef_p(o) (mrb_type(o) == MRB_TT_UNDEF)
318 #define mrb_nil_p(o) (mrb_type(o) == MRB_TT_FALSE && !(o).value.i)
319 #define mrb_bool(o) (mrb_type(o) != MRB_TT_FALSE)
320 
321 #endif /* no boxing */
322 
323 #define mrb_fixnum(o) (o).value.i
324 #define mrb_symbol(o) (o).value.sym
325 #define mrb_float_p(o) (mrb_type(o) == MRB_TT_FLOAT)
326 #define mrb_symbol_p(o) (mrb_type(o) == MRB_TT_SYMBOL)
327 #define mrb_array_p(o) (mrb_type(o) == MRB_TT_ARRAY)
328 #define mrb_string_p(o) (mrb_type(o) == MRB_TT_STRING)
329 #define mrb_hash_p(o) (mrb_type(o) == MRB_TT_HASH)
330 #define mrb_cptr_p(o) (mrb_type(o) == MRB_TT_CPTR)
331 #define mrb_test(o) mrb_bool(o)
332 
333 #define MRB_OBJECT_HEADER \
334  enum mrb_vtype tt:8;\
335  uint32_t color:3;\
336  uint32_t flags:21;\
337  struct RClass *c;\
338  struct RBasic *gcnext
339 
340 /* white: 011, black: 100, gray: 000 */
341 #define MRB_GC_GRAY 0
342 #define MRB_GC_WHITE_A 1
343 #define MRB_GC_WHITE_B (1 << 1)
344 #define MRB_GC_BLACK (1 << 2)
345 #define MRB_GC_WHITES (MRB_GC_WHITE_A | MRB_GC_WHITE_B)
346 #define MRB_GC_COLOR_MASK 7
347 
348 #define paint_gray(o) ((o)->color = MRB_GC_GRAY)
349 #define paint_black(o) ((o)->color = MRB_GC_BLACK)
350 #define paint_white(o) ((o)->color = MRB_GC_WHITES)
351 #define paint_partial_white(s, o) ((o)->color = (s)->current_white_part)
352 #define is_gray(o) ((o)->color == MRB_GC_GRAY)
353 #define is_white(o) ((o)->color & MRB_GC_WHITES)
354 #define is_black(o) ((o)->color & MRB_GC_BLACK)
355 #define is_dead(s, o) (((o)->color & other_white_part(s) & MRB_GC_WHITES) || (o)->tt == MRB_TT_FREE)
356 #define flip_white_part(s) ((s)->current_white_part = other_white_part(s))
357 #define other_white_part(s) ((s)->current_white_part ^ MRB_GC_WHITES)
358 
359 struct RBasic {
361 };
362 #define mrb_basic_ptr(v) ((struct RBasic*)(mrb_ptr(v)))
363 /* obsolete macro mrb_basic; will be removed soon */
364 #define mrb_basic(v) mrb_basic_ptr(v)
365 
366 struct RObject {
368  struct iv_tbl *iv;
369 };
370 #define mrb_obj_ptr(v) ((struct RObject*)(mrb_ptr(v)))
371 /* obsolete macro mrb_object; will be removed soon */
372 #define mrb_object(o) mrb_obj_ptr(o)
373 #define mrb_immediate_p(x) (mrb_type(x) <= MRB_TT_CPTR)
374 #define mrb_special_const_p(x) mrb_immediate_p(x)
375 
376 struct RFiber {
378  struct mrb_context *cxt;
379 };
380 
381 #ifdef MRB_WORD_BOXING
382 struct RFloat {
384  mrb_float f;
385 };
386 
387 struct RCptr {
389  void *p;
390 };
391 
392 static inline enum mrb_vtype
394 {
395  switch (o.w) {
396  case MRB_Qfalse:
397  case MRB_Qnil:
398  return MRB_TT_FALSE;
399  case MRB_Qtrue:
400  return MRB_TT_TRUE;
401  case MRB_Qundef:
402  return MRB_TT_UNDEF;
403  }
404  if (o.value.i_flag == MRB_FIXNUM_FLAG) {
405  return MRB_TT_FIXNUM;
406  }
407  if (o.value.sym_flag == MRB_SYMBOL_FLAG) {
408  return MRB_TT_SYMBOL;
409  }
410  return o.value.bp->tt;
411 }
412 #endif /* MRB_WORD_BOXING */
413 
414 static inline mrb_value
415 mrb_fixnum_value(mrb_int i)
416 {
417  mrb_value v;
418 
420  return v;
421 }
422 
423 static inline mrb_value
424 mrb_symbol_value(mrb_sym i)
425 {
426  mrb_value v;
427 
428  MRB_SET_VALUE(v, MRB_TT_SYMBOL, value.sym, i);
429  return v;
430 }
431 
432 static inline mrb_value
433 mrb_obj_value(void *p)
434 {
435  mrb_value v;
436  struct RBasic *b = (struct RBasic*)p;
437 
438  MRB_SET_VALUE(v, b->tt, value.p, p);
439  return v;
440 }
441 
442 #ifdef MRB_WORD_BOXING
443 mrb_value
444 mrb_cptr_value(struct mrb_state *mrb, void *p);
445 #else
446 static inline mrb_value
447 mrb_cptr_value(struct mrb_state *mrb, void *p)
448 {
449  mrb_value v;
450  (void) mrb;
451 
452  MRB_SET_VALUE(v, MRB_TT_CPTR, value.p, p);
453  return v;
454 }
455 #endif
456 /* obsolete macros; will be removed */
457 #define MRB_TT_VOIDP MRB_TT_CPTR
458 #define mrb_voidp_value(m,p) mrb_cptr_value((m),(p))
459 #define mrb_voidp(o) mrb_cptr(o)
460 #define mrb_voidp_p(o) mrb_cptr_p(o)
461 
462 static inline mrb_value
463 mrb_false_value(void)
464 {
465  mrb_value v;
466 
467  MRB_SET_VALUE(v, MRB_TT_FALSE, value.i, 1);
468  return v;
469 }
470 
471 static inline mrb_value
472 mrb_nil_value(void)
473 {
474  mrb_value v;
475 
476  MRB_SET_VALUE(v, MRB_TT_FALSE, value.i, 0);
477  return v;
478 }
479 
480 static inline mrb_value
481 mrb_true_value(void)
482 {
483  mrb_value v;
484 
485  MRB_SET_VALUE(v, MRB_TT_TRUE, value.i, 1);
486  return v;
487 }
488 
489 static inline mrb_value
490 mrb_undef_value(void)
491 {
492  mrb_value v;
493 
494  MRB_SET_VALUE(v, MRB_TT_UNDEF, value.i, 0);
495  return v;
496 }
497 
498 static inline mrb_value
499 mrb_bool_value(mrb_bool boolean)
500 {
501  mrb_value v;
502 
503  MRB_SET_VALUE(v, boolean ? MRB_TT_TRUE : MRB_TT_FALSE, value.i, 1);
504  return v;
505 }
506 
507 #endif /* MRUBY_OBJECT_H */