Ruby  3.4.0dev (2024-12-06 revision 892c46283a5ea4179500d951c9d4866c0051f27b)
special_consts.h
Go to the documentation of this file.
1 #ifndef RBIMPL_SPECIAL_CONSTS_H /*-*-C++-*-vi:se ft=cpp:*/
2 #define RBIMPL_SPECIAL_CONSTS_H
31 #include "ruby/internal/stdbool.h"
32 #include "ruby/internal/value.h"
33 
42 #if defined(USE_FLONUM)
43 # /* Take that. */
44 #elif SIZEOF_VALUE >= SIZEOF_DOUBLE
45 # define USE_FLONUM 1
46 #else
47 # define USE_FLONUM 0
48 #endif
49 
51 #define RTEST RB_TEST
52 
53 #define FIXNUM_P RB_FIXNUM_P
54 #define IMMEDIATE_P RB_IMMEDIATE_P
55 #define NIL_P RB_NIL_P
56 #define SPECIAL_CONST_P RB_SPECIAL_CONST_P
57 #define STATIC_SYM_P RB_STATIC_SYM_P
59 #define Qfalse RUBY_Qfalse
60 #define Qnil RUBY_Qnil
61 #define Qtrue RUBY_Qtrue
62 #define Qundef RUBY_Qundef
64 #define FIXNUM_FLAG RUBY_FIXNUM_FLAG
65 #define FLONUM_FLAG RUBY_FLONUM_FLAG
66 #define FLONUM_MASK RUBY_FLONUM_MASK
67 #define FLONUM_P RB_FLONUM_P
68 #define IMMEDIATE_MASK RUBY_IMMEDIATE_MASK
69 #define SYMBOL_FLAG RUBY_SYMBOL_FLAG
72 #define RB_FIXNUM_P RB_FIXNUM_P
73 #define RB_FLONUM_P RB_FLONUM_P
74 #define RB_IMMEDIATE_P RB_IMMEDIATE_P
75 #define RB_NIL_P RB_NIL_P
76 #define RB_SPECIAL_CONST_P RB_SPECIAL_CONST_P
77 #define RB_STATIC_SYM_P RB_STATIC_SYM_P
78 #define RB_TEST RB_TEST
79 #define RB_UNDEF_P RB_UNDEF_P
80 #define RB_NIL_OR_UNDEF_P RB_NIL_OR_UNDEF_P
84 enum
87 #if defined(__DOXYGEN__)
97 #elif USE_FLONUM
98  RUBY_Qfalse = 0x00, /* ...0000 0000 */
99  RUBY_Qnil = 0x04, /* ...0000 0100 */
100  RUBY_Qtrue = 0x14, /* ...0001 0100 */
101  RUBY_Qundef = 0x24, /* ...0010 0100 */
102  RUBY_IMMEDIATE_MASK = 0x07, /* ...0000 0111 */
103  RUBY_FIXNUM_FLAG = 0x01, /* ...xxxx xxx1 */
104  RUBY_FLONUM_MASK = 0x03, /* ...0000 0011 */
105  RUBY_FLONUM_FLAG = 0x02, /* ...xxxx xx10 */
106  RUBY_SYMBOL_FLAG = 0x0c, /* ...xxxx 1100 */
107 #else
108  RUBY_Qfalse = 0x00, /* ...0000 0000 */
109  RUBY_Qnil = 0x02, /* ...0000 0010 */
110  RUBY_Qtrue = 0x06, /* ...0000 0110 */
111  RUBY_Qundef = 0x0a, /* ...0000 1010 */
112  RUBY_IMMEDIATE_MASK = 0x03, /* ...0000 0011 */
113  RUBY_FIXNUM_FLAG = 0x01, /* ...xxxx xxx1 */
114  RUBY_FLONUM_MASK = 0x00, /* any values ANDed with FLONUM_MASK cannot be FLONUM_FLAG */
115  RUBY_FLONUM_FLAG = 0x02, /* ...0000 0010 */
116  RUBY_SYMBOL_FLAG = 0x0e, /* ...xxxx 1110 */
117 #endif
118 
119  RUBY_SPECIAL_SHIFT = 8
120 };
121 
137 static inline bool
139 {
140  /*
141  * if USE_FLONUM
142  * Qfalse: ....0000 0000
143  * Qnil: ....0000 0100
144  * ~Qnil: ....1111 1011
145  * v ....xxxx xxxx
146  * ----------------------------
147  * RTEST(v) ....xxxx x0xx
148  *
149  * if ! USE_FLONUM
150  * Qfalse: ....0000 0000
151  * Qnil: ....0000 0010
152  * ~Qnil: ....1111 1101
153  * v ....xxxx xxxx
154  * ----------------------------
155  * RTEST(v) ....xxxx xx0x
156  *
157  * RTEST(v) can be 0 if and only if (v == Qfalse || v == Qnil).
158  */
159  return obj & RBIMPL_CAST((VALUE)~RUBY_Qnil);
160 }
161 
172 static inline bool
174 {
175  return obj == RUBY_Qnil;
176 }
177 
188 static inline bool
190 {
191  return obj == RUBY_Qundef;
192 }
193 
205 static inline bool
207 {
208  /*
209  * if USE_FLONUM
210  * Qundef: ....0010 0100
211  * Qnil: ....0000 0100
212  * mask: ....1101 1111
213  * common_bits: ....0000 0100
214  * ---------------------------------
215  * Qnil & mask ....0000 0100
216  * Qundef & mask ....0000 0100
217  *
218  * if ! USE_FLONUM
219  * Qundef: ....0000 1010
220  * Qnil: ....0000 0010
221  * mask: ....1111 0111
222  * common_bits: ....0000 0010
223  * ----------------------------
224  * Qnil & mask ....0000 0010
225  * Qundef & mask ....0000 0010
226  *
227  * NIL_OR_UNDEF_P(v) can be true only when v is Qundef or Qnil.
228  */
229  const VALUE mask = RBIMPL_CAST((VALUE)~(RUBY_Qundef ^ RUBY_Qnil));
230  const VALUE common_bits = RUBY_Qundef & RUBY_Qnil;
231  return (obj & mask) == common_bits;
232 }
233 
246 static inline bool
248 {
249  return obj & RUBY_FIXNUM_FLAG;
250 }
251 
266 static inline bool
268 {
269  RBIMPL_ATTR_CONSTEXPR(CXX14)
270  const VALUE mask = ~(RBIMPL_VALUE_FULL << RUBY_SPECIAL_SHIFT);
271  return (obj & mask) == RUBY_SYMBOL_FLAG;
272 }
273 
287 static inline bool
289 {
290 #if USE_FLONUM
291  return (obj & RUBY_FLONUM_MASK) == RUBY_FLONUM_FLAG;
292 #else
293  return false;
294 #endif
295 }
296 
310 static inline bool
312 {
313  return obj & RUBY_IMMEDIATE_MASK;
314 }
315 
326 static inline bool
328 {
329  return (obj == RUBY_Qfalse) || RB_IMMEDIATE_P(obj);
330 }
331 
346 static inline VALUE
348 {
349  return (unsigned int)RB_SPECIAL_CONST_P(obj) * RUBY_Qtrue;
350 }
351 
356 #define RUBY_Qfalse RBIMPL_CAST((VALUE)RUBY_Qfalse)
357 #define RUBY_Qtrue RBIMPL_CAST((VALUE)RUBY_Qtrue)
358 #define RUBY_Qnil RBIMPL_CAST((VALUE)RUBY_Qnil)
359 #define RUBY_Qundef RBIMPL_CAST((VALUE)RUBY_Qundef)
362 #endif /* RBIMPL_SPECIAL_CONSTS_H */
Defines RBIMPL_ATTR_ARTIFICIAL.
#define RBIMPL_ATTR_ARTIFICIAL()
Wraps (or simulates) __attribute__((artificial))
Definition: artificial.h:41
Defines RBIMPL_ATTR_CONST.
RBIMPL_ATTR_CONSTEXPR.
#define RBIMPL_ATTR_CONSTEXPR(_)
Wraps (or simulates) C++11 constexpr.
Definition: constexpr.h:74
RBIMPL_ATTR_ENUM_EXTENSIBILITY.
#define RBIMPL_ATTR_ENUM_EXTENSIBILITY(_)
Wraps (or simulates) __attribute__((enum_extensibility))
RBIMPL_ATTR_CONST() int rb_io_oflags_fmode(int oflags)
Converts an oflags (that rb_io_modestr_oflags() returns) to a fmode (that rb_io_mode_flags() returns)...
#define inline
Old Visual Studio versions do not support the inline keyword, so we need to define it to be __inline.
Definition: defines.h:88
static bool RB_STATIC_SYM_P(VALUE obj)
Checks if the given object is a static symbol.
static bool RB_TEST(VALUE obj)
Emulates Ruby's "if" statement.
static bool RB_FIXNUM_P(VALUE obj)
Checks if the given object is a so-called Fixnum.
static bool RB_IMMEDIATE_P(VALUE obj)
Checks if the given object is an immediate i.e.
static bool RB_NIL_OR_UNDEF_P(VALUE obj)
Checks if the given object is nil or undef.
static bool RB_SPECIAL_CONST_P(VALUE obj)
Checks if the given object is of enum ruby_special_consts.
static VALUE rb_special_const_p(VALUE obj)
Identical to RB_SPECIAL_CONST_P, except it returns a VALUE.
ruby_special_consts
special constants - i.e.
@ RUBY_Qtrue
@ RUBY_SPECIAL_SHIFT
Least significant 8 bits are reserved.
@ RUBY_FIXNUM_FLAG
Flag to denote a fixnum.
@ RUBY_Qnil
@ RUBY_FLONUM_MASK
Bit mask detecting a flonum.
@ RUBY_FLONUM_FLAG
Flag to denote a flonum.
@ RUBY_Qundef
Represents so-called undef.
@ RUBY_SYMBOL_FLAG
Flag to denote a static symbol.
@ RUBY_IMMEDIATE_MASK
Bit mask detecting special consts.
@ RUBY_Qfalse
static bool RB_NIL_P(VALUE obj)
Checks if the given object is nil.
static bool RB_UNDEF_P(VALUE obj)
Checks if the given object is undef.
static bool RB_FLONUM_P(VALUE obj)
Checks if the given object is a so-called Flonum.
C99 shim for <stdbool.h>
Defines VALUE and ID.
#define RBIMPL_VALUE_FULL
Maximum possible value that a VALUE can take.
Definition: value.h:90
uintptr_t VALUE
Type that represents a Ruby object.
Definition: value.h:40