1 /**********************************************************************
2 
3   internal.h -
4 
5   $Author$
6   created at: Tue May 17 11:42:20 JST 2011
7 
8   Copyright (C) 2011 Yukihiro Matsumoto
9 
10 **********************************************************************/
11 
12 #ifndef RUBY_INTERNAL_H
13 #define RUBY_INTERNAL_H 1
14 
15 #include "ruby.h"
16 
17 #if defined(__cplusplus)
18 extern "C" {
19 #if 0
20 } /* satisfy cc-mode */
21 #endif
22 #endif
23 
24 #ifdef HAVE_STDBOOL_H
25 # include <stdbool.h>
26 #endif
27 
28 #ifndef __bool_true_false_are_defined
29 # ifndef __cplusplus
30 #  undef bool
31 #  undef false
32 #  undef true
33 #  define bool signed char
34 #  define false 0
35 #  define true 1
36 #  define __bool_true_false_are_defined 1
37 # endif
38 #endif
39 
40 /* The most significant bit of the lower part of half-long integer.
41  * If sizeof(long) == 4, this is 0x8000.
42  * If sizeof(long) == 8, this is 0x80000000.
43  */
44 #define HALF_LONG_MSB ((SIGNED_VALUE)1<<((SIZEOF_LONG*CHAR_BIT-1)/2))
45 
46 #define LIKELY(x) RB_LIKELY(x)
47 #define UNLIKELY(x) RB_UNLIKELY(x)
48 
49 #ifndef MAYBE_UNUSED
50 # define MAYBE_UNUSED(x) x
51 #endif
52 
53 #ifndef WARN_UNUSED_RESULT
54 # define WARN_UNUSED_RESULT(x) x
55 #endif
56 
57 #if 0
58 #elif defined(NO_SANITIZE)
59 # define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS(x) \
60     NO_SANITIZE("address", NOINLINE(x))
61 #elif defined(NO_SANITIZE_ADDRESS)
62 # define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS(x) \
63     NO_SANITIZE_ADDRESS(NOINLINE(x))
64 #elif defined(NO_ADDRESS_SAFETY_ANALYSIS)
65 # define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS(x) \
66     NO_ADDRESS_SAFETY_ANALYSIS(NOINLINE(x))
67 #else
68 # define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS(x) x
69 #endif
70 
71 #if defined(NO_SANITIZE) && defined(__GNUC__) &&! defined(__clang__)
72 /* GCC warns about unknown sanitizer, which is annoying. */
73 #undef NO_SANITIZE
74 #define NO_SANITIZE(x, y) \
75     COMPILER_WARNING_PUSH; \
76     COMPILER_WARNING_IGNORED(-Wattributes); \
77     __attribute__((__no_sanitize__(x))) y; \
78     COMPILER_WARNING_POP
79 #endif
80 
81 #ifndef NO_SANITIZE
82 # define NO_SANITIZE(x, y) y
83 #endif
84 
85 #ifdef HAVE_VALGRIND_MEMCHECK_H
86 # include <valgrind/memcheck.h>
87 # ifndef VALGRIND_MAKE_MEM_DEFINED
88 #  define VALGRIND_MAKE_MEM_DEFINED(p, n) VALGRIND_MAKE_READABLE((p), (n))
89 # endif
90 # ifndef VALGRIND_MAKE_MEM_UNDEFINED
91 #  define VALGRIND_MAKE_MEM_UNDEFINED(p, n) VALGRIND_MAKE_WRITABLE((p), (n))
92 # endif
93 #else
94 # define VALGRIND_MAKE_MEM_DEFINED(p, n) 0
95 # define VALGRIND_MAKE_MEM_UNDEFINED(p, n) 0
96 #endif
97 
98 #define numberof(array) ((int)(sizeof(array) / sizeof((array)[0])))
99 
100 #ifndef __has_feature
101 # define __has_feature(x) 0
102 #endif
103 
104 #ifndef __has_extension
105 # define __has_extension __has_feature
106 #endif
107 
108 #ifndef MJIT_HEADER
109 
110 #ifdef HAVE_SANITIZER_ASAN_INTERFACE_H
111 # include <sanitizer/asan_interface.h>
112 #endif
113 
114 #if !__has_feature(address_sanitizer)
115 # define __asan_poison_memory_region(x, y)
116 # define __asan_unpoison_memory_region(x, y)
117 # define __asan_region_is_poisoned(x, y) 0
118 #endif
119 
120 #ifdef HAVE_SANITIZER_MSAN_INTERFACE_H
121 # include <sanitizer/msan_interface.h>
122 #endif
123 
124 #if !__has_feature(memory_sanitizer)
125 # define __msan_allocated_memory(x, y)
126 # define __msan_poison(x, y)
127 # define __msan_unpoison(x, y)
128 # define __msan_unpoison_string(x)
129 #endif
130 
131 static inline void
poison_memory_region(const volatile void * ptr,size_t size)132 poison_memory_region(const volatile void *ptr, size_t size)
133 {
134     __msan_poison(ptr, size);
135     __asan_poison_memory_region(ptr, size);
136 }
137 
138 static inline void
poison_object(VALUE obj)139 poison_object(VALUE obj)
140 {
141     struct RVALUE *ptr = (void *)obj;
142     poison_memory_region(ptr, SIZEOF_VALUE);
143 }
144 
145 static inline void
unpoison_memory_region(const volatile void * ptr,size_t size,bool malloc_p)146 unpoison_memory_region(const volatile void *ptr, size_t size, bool malloc_p)
147 {
148     __asan_unpoison_memory_region(ptr, size);
149     if (malloc_p) {
150         __msan_allocated_memory(ptr, size);
151     }
152     else {
153         __msan_unpoison(ptr, size);
154     }
155 }
156 
157 static inline void
unpoison_object(VALUE obj,bool newobj_p)158 unpoison_object(VALUE obj, bool newobj_p)
159 {
160     struct RVALUE *ptr = (void *)obj;
161     unpoison_memory_region(ptr, SIZEOF_VALUE, newobj_p);
162 }
163 
164 #endif
165 
166 /* Prevent compiler from reordering access */
167 #define ACCESS_ONCE(type,x) (*((volatile type *)&(x)))
168 
169 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
170 # define STATIC_ASSERT(name, expr) _Static_assert(expr, #name ": " #expr)
171 #elif GCC_VERSION_SINCE(4, 6, 0) || __has_extension(c_static_assert)
172 # define STATIC_ASSERT(name, expr) RB_GNUC_EXTENSION _Static_assert(expr, #name ": " #expr)
173 #else
174 # define STATIC_ASSERT(name, expr) typedef int static_assert_##name##_check[1 - 2*!(expr)]
175 #endif
176 
177 #define SIGNED_INTEGER_TYPE_P(int_type) (0 > ((int_type)0)-1)
178 #define SIGNED_INTEGER_MAX(sint_type) \
179   (sint_type) \
180   ((((sint_type)1) << (sizeof(sint_type) * CHAR_BIT - 2)) | \
181   ((((sint_type)1) << (sizeof(sint_type) * CHAR_BIT - 2)) - 1))
182 #define SIGNED_INTEGER_MIN(sint_type) (-SIGNED_INTEGER_MAX(sint_type)-1)
183 #define UNSIGNED_INTEGER_MAX(uint_type) (~(uint_type)0)
184 
185 #if SIGNEDNESS_OF_TIME_T < 0	/* signed */
186 # define TIMET_MAX SIGNED_INTEGER_MAX(time_t)
187 # define TIMET_MIN SIGNED_INTEGER_MIN(time_t)
188 #elif SIGNEDNESS_OF_TIME_T > 0	/* unsigned */
189 # define TIMET_MAX UNSIGNED_INTEGER_MAX(time_t)
190 # define TIMET_MIN ((time_t)0)
191 #endif
192 #define TIMET_MAX_PLUS_ONE (2*(double)(TIMET_MAX/2+1))
193 
194 #ifdef HAVE_BUILTIN___BUILTIN_MUL_OVERFLOW_P
195 #define MUL_OVERFLOW_P(a, b) \
196     __builtin_mul_overflow_p((a), (b), (__typeof__(a * b))0)
197 #elif defined HAVE_BUILTIN___BUILTIN_MUL_OVERFLOW
198 #define MUL_OVERFLOW_P(a, b) \
199     RB_GNUC_EXTENSION_BLOCK(__typeof__(a) c; __builtin_mul_overflow((a), (b), &c))
200 #endif
201 
202 #define MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, min, max) ( \
203     (a) == 0 ? 0 : \
204     (a) == -1 ? (b) < -(max) : \
205     (a) > 0 ? \
206       ((b) > 0 ? (max) / (a) < (b) : (min) / (a) > (b)) : \
207       ((b) > 0 ? (min) / (a) < (b) : (max) / (a) > (b)))
208 
209 #ifdef HAVE_BUILTIN___BUILTIN_MUL_OVERFLOW_P
210 /* __builtin_mul_overflow_p can take bitfield */
211 /* and GCC permits bitfields for integers other than int */
212 #define MUL_OVERFLOW_FIXNUM_P(a, b) RB_GNUC_EXTENSION_BLOCK( \
213     struct { long fixnum : SIZEOF_LONG * CHAR_BIT - 1; } c; \
214     __builtin_mul_overflow_p((a), (b), c.fixnum); \
215 )
216 #else
217 #define MUL_OVERFLOW_FIXNUM_P(a, b) MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, FIXNUM_MIN, FIXNUM_MAX)
218 #endif
219 
220 #ifdef MUL_OVERFLOW_P
221 #define MUL_OVERFLOW_LONG_LONG_P(a, b) MUL_OVERFLOW_P(a, b)
222 #define MUL_OVERFLOW_LONG_P(a, b)      MUL_OVERFLOW_P(a, b)
223 #define MUL_OVERFLOW_INT_P(a, b)       MUL_OVERFLOW_P(a, b)
224 #else
225 #define MUL_OVERFLOW_LONG_LONG_P(a, b) MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, LLONG_MIN, LLONG_MAX)
226 #define MUL_OVERFLOW_LONG_P(a, b)      MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, LONG_MIN, LONG_MAX)
227 #define MUL_OVERFLOW_INT_P(a, b)       MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, INT_MIN, INT_MAX)
228 #endif
229 
230 #ifndef swap16
231 # ifdef HAVE_BUILTIN___BUILTIN_BSWAP16
232 #  define swap16(x) __builtin_bswap16(x)
233 # endif
234 #endif
235 
236 #ifndef swap16
237 # define swap16(x)      ((uint16_t)((((x)&0xFF)<<8) | (((x)>>8)&0xFF)))
238 #endif
239 
240 #ifndef swap32
241 # ifdef HAVE_BUILTIN___BUILTIN_BSWAP32
242 #  define swap32(x) __builtin_bswap32(x)
243 # endif
244 #endif
245 
246 #ifndef swap32
247 # define swap32(x)      ((uint32_t)((((x)&0xFF)<<24)    \
248                         |(((x)>>24)&0xFF)       \
249                         |(((x)&0x0000FF00)<<8)  \
250                         |(((x)&0x00FF0000)>>8)  ))
251 #endif
252 
253 #ifndef swap64
254 # ifdef HAVE_BUILTIN___BUILTIN_BSWAP64
255 #  define swap64(x) __builtin_bswap64(x)
256 # endif
257 #endif
258 
259 #ifndef swap64
260 # ifdef HAVE_INT64_T
261 #  define byte_in_64bit(n) ((uint64_t)0xff << (n))
262 #  define swap64(x)       ((uint64_t)((((x)&byte_in_64bit(0))<<56)      \
263                            |(((x)>>56)&0xFF)                    \
264                            |(((x)&byte_in_64bit(8))<<40)        \
265                            |(((x)&byte_in_64bit(48))>>40)       \
266                            |(((x)&byte_in_64bit(16))<<24)       \
267                            |(((x)&byte_in_64bit(40))>>24)       \
268                            |(((x)&byte_in_64bit(24))<<8)        \
269                            |(((x)&byte_in_64bit(32))>>8)))
270 # endif
271 #endif
272 
273 static inline unsigned int
nlz_int(unsigned int x)274 nlz_int(unsigned int x)
275 {
276 #if defined(HAVE_BUILTIN___BUILTIN_CLZ)
277     if (x == 0) return SIZEOF_INT * CHAR_BIT;
278     return (unsigned int)__builtin_clz(x);
279 #else
280     unsigned int y;
281 # if 64 < SIZEOF_INT * CHAR_BIT
282     unsigned int n = 128;
283 # elif 32 < SIZEOF_INT * CHAR_BIT
284     unsigned int n = 64;
285 # else
286     unsigned int n = 32;
287 # endif
288 # if 64 < SIZEOF_INT * CHAR_BIT
289     y = x >> 64; if (y) {n -= 64; x = y;}
290 # endif
291 # if 32 < SIZEOF_INT * CHAR_BIT
292     y = x >> 32; if (y) {n -= 32; x = y;}
293 # endif
294     y = x >> 16; if (y) {n -= 16; x = y;}
295     y = x >>  8; if (y) {n -=  8; x = y;}
296     y = x >>  4; if (y) {n -=  4; x = y;}
297     y = x >>  2; if (y) {n -=  2; x = y;}
298     y = x >>  1; if (y) {return n - 2;}
299     return (unsigned int)(n - x);
300 #endif
301 }
302 
303 static inline unsigned int
nlz_long(unsigned long x)304 nlz_long(unsigned long x)
305 {
306 #if defined(HAVE_BUILTIN___BUILTIN_CLZL)
307     if (x == 0) return SIZEOF_LONG * CHAR_BIT;
308     return (unsigned int)__builtin_clzl(x);
309 #else
310     unsigned long y;
311 # if 64 < SIZEOF_LONG * CHAR_BIT
312     unsigned int n = 128;
313 # elif 32 < SIZEOF_LONG * CHAR_BIT
314     unsigned int n = 64;
315 # else
316     unsigned int n = 32;
317 # endif
318 # if 64 < SIZEOF_LONG * CHAR_BIT
319     y = x >> 64; if (y) {n -= 64; x = y;}
320 # endif
321 # if 32 < SIZEOF_LONG * CHAR_BIT
322     y = x >> 32; if (y) {n -= 32; x = y;}
323 # endif
324     y = x >> 16; if (y) {n -= 16; x = y;}
325     y = x >>  8; if (y) {n -=  8; x = y;}
326     y = x >>  4; if (y) {n -=  4; x = y;}
327     y = x >>  2; if (y) {n -=  2; x = y;}
328     y = x >>  1; if (y) {return n - 2;}
329     return (unsigned int)(n - x);
330 #endif
331 }
332 
333 #ifdef HAVE_LONG_LONG
334 static inline unsigned int
nlz_long_long(unsigned LONG_LONG x)335 nlz_long_long(unsigned LONG_LONG x)
336 {
337 #if defined(HAVE_BUILTIN___BUILTIN_CLZLL)
338     if (x == 0) return SIZEOF_LONG_LONG * CHAR_BIT;
339     return (unsigned int)__builtin_clzll(x);
340 #else
341     unsigned LONG_LONG y;
342 # if 64 < SIZEOF_LONG_LONG * CHAR_BIT
343     unsigned int n = 128;
344 # elif 32 < SIZEOF_LONG_LONG * CHAR_BIT
345     unsigned int n = 64;
346 # else
347     unsigned int n = 32;
348 # endif
349 # if 64 < SIZEOF_LONG_LONG * CHAR_BIT
350     y = x >> 64; if (y) {n -= 64; x = y;}
351 # endif
352 # if 32 < SIZEOF_LONG_LONG * CHAR_BIT
353     y = x >> 32; if (y) {n -= 32; x = y;}
354 # endif
355     y = x >> 16; if (y) {n -= 16; x = y;}
356     y = x >>  8; if (y) {n -=  8; x = y;}
357     y = x >>  4; if (y) {n -=  4; x = y;}
358     y = x >>  2; if (y) {n -=  2; x = y;}
359     y = x >>  1; if (y) {return n - 2;}
360     return (unsigned int)(n - x);
361 #endif
362 }
363 #endif
364 
365 #ifdef HAVE_UINT128_T
366 static inline unsigned int
nlz_int128(uint128_t x)367 nlz_int128(uint128_t x)
368 {
369     uint128_t y;
370     unsigned int n = 128;
371     y = x >> 64; if (y) {n -= 64; x = y;}
372     y = x >> 32; if (y) {n -= 32; x = y;}
373     y = x >> 16; if (y) {n -= 16; x = y;}
374     y = x >>  8; if (y) {n -=  8; x = y;}
375     y = x >>  4; if (y) {n -=  4; x = y;}
376     y = x >>  2; if (y) {n -=  2; x = y;}
377     y = x >>  1; if (y) {return n - 2;}
378     return (unsigned int)(n - x);
379 }
380 #endif
381 
382 static inline unsigned int
nlz_intptr(uintptr_t x)383 nlz_intptr(uintptr_t x)
384 {
385 #if SIZEOF_UINTPTR_T == SIZEOF_INT
386     return nlz_int(x);
387 #elif SIZEOF_UINTPTR_T == SIZEOF_LONG
388     return nlz_long(x);
389 #elif SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG
390     return nlz_long_long(x);
391 #else
392     #error no known integer type corresponds uintptr_t
393     return /* sane compiler */ ~0;
394 #endif
395 }
396 
397 static inline unsigned int
rb_popcount32(uint32_t x)398 rb_popcount32(uint32_t x)
399 {
400 #ifdef HAVE_BUILTIN___BUILTIN_POPCOUNT
401     return (unsigned int)__builtin_popcount(x);
402 #else
403     x = (x & 0x55555555) + (x >> 1 & 0x55555555);
404     x = (x & 0x33333333) + (x >> 2 & 0x33333333);
405     x = (x & 0x0f0f0f0f) + (x >> 4 & 0x0f0f0f0f);
406     x = (x & 0x001f001f) + (x >> 8 & 0x001f001f);
407     return (x & 0x0000003f) + (x >>16 & 0x0000003f);
408 #endif
409 }
410 
411 static inline int
rb_popcount64(uint64_t x)412 rb_popcount64(uint64_t x)
413 {
414 #ifdef HAVE_BUILTIN___BUILTIN_POPCOUNT
415     return __builtin_popcountll(x);
416 #else
417     x = (x & 0x5555555555555555) + (x >> 1 & 0x5555555555555555);
418     x = (x & 0x3333333333333333) + (x >> 2 & 0x3333333333333333);
419     x = (x & 0x0707070707070707) + (x >> 4 & 0x0707070707070707);
420     x = (x & 0x001f001f001f001f) + (x >> 8 & 0x001f001f001f001f);
421     x = (x & 0x0000003f0000003f) + (x >>16 & 0x0000003f0000003f);
422     return (x & 0x7f) + (x >>32 & 0x7f);
423 #endif
424 }
425 
426 static inline int
rb_popcount_intptr(uintptr_t x)427 rb_popcount_intptr(uintptr_t x)
428 {
429 #if SIZEOF_VOIDP == 8
430     return rb_popcount64(x);
431 #elif SIZEOF_VOIDP == 4
432     return rb_popcount32(x);
433 #endif
434 }
435 
436 static inline int
ntz_int32(uint32_t x)437 ntz_int32(uint32_t x)
438 {
439 #ifdef HAVE_BUILTIN___BUILTIN_CTZ
440     return __builtin_ctz(x);
441 #else
442     return rb_popcount32((~x) & (x-1));
443 #endif
444 }
445 
446 static inline int
ntz_int64(uint64_t x)447 ntz_int64(uint64_t x)
448 {
449 #ifdef HAVE_BUILTIN___BUILTIN_CTZLL
450     return __builtin_ctzll(x);
451 #else
452     return rb_popcount64((~x) & (x-1));
453 #endif
454 }
455 
456 static inline int
ntz_intptr(uintptr_t x)457 ntz_intptr(uintptr_t x)
458 {
459 #if SIZEOF_VOIDP == 8
460     return ntz_int64(x);
461 #elif SIZEOF_VOIDP == 4
462     return ntz_int32(x);
463 #endif
464 }
465 
466 #if HAVE_LONG_LONG && SIZEOF_LONG * 2 <= SIZEOF_LONG_LONG
467 # define DLONG LONG_LONG
468 # define DL2NUM(x) LL2NUM(x)
469 #elif defined(HAVE_INT128_T)
470 # define DLONG int128_t
471 # define DL2NUM(x) (RB_FIXABLE(x) ? LONG2FIX(x) : rb_int128t2big(x))
472 VALUE rb_int128t2big(int128_t n);
473 #endif
474 
475 static inline long
rb_overflowed_fix_to_int(long x)476 rb_overflowed_fix_to_int(long x)
477 {
478     return (long)((unsigned long)(x >> 1) ^ (1LU << (SIZEOF_LONG * CHAR_BIT - 1)));
479 }
480 
481 static inline VALUE
rb_fix_plus_fix(VALUE x,VALUE y)482 rb_fix_plus_fix(VALUE x, VALUE y)
483 {
484 #ifdef HAVE_BUILTIN___BUILTIN_ADD_OVERFLOW
485     long lz;
486     /* NOTE
487      * (1) `LONG2FIX(FIX2LONG(x)+FIX2LONG(y))`
488      +     = `((lx*2+1)/2 + (ly*2+1)/2)*2+1`
489      +     = `lx*2 + ly*2 + 1`
490      +     = `(lx*2+1) + (ly*2+1) - 1`
491      +     = `x + y - 1`
492      * (2) Fixnum's LSB is always 1.
493      *     It means you can always run `x - 1` without overflow.
494      * (3) Of course `z = x + (y-1)` may overflow.
495      *     At that time true value is
496      *     * positive: 0b0 1xxx...1, and z = 0b1xxx...1
497      *     * nevative: 0b1 0xxx...1, and z = 0b0xxx...1
498      *     To convert this true value to long,
499      *     (a) Use arithmetic shift
500      *         * positive: 0b11xxx...
501      *         * negative: 0b00xxx...
502      *     (b) invert MSB
503      *         * positive: 0b01xxx...
504      *         * negative: 0b10xxx...
505      */
506     if (__builtin_add_overflow((long)x, (long)y-1, &lz)) {
507 	return rb_int2big(rb_overflowed_fix_to_int(lz));
508     }
509     else {
510 	return (VALUE)lz;
511     }
512 #else
513     long lz = FIX2LONG(x) + FIX2LONG(y);
514     return LONG2NUM(lz);
515 #endif
516 }
517 
518 static inline VALUE
rb_fix_minus_fix(VALUE x,VALUE y)519 rb_fix_minus_fix(VALUE x, VALUE y)
520 {
521 #ifdef HAVE_BUILTIN___BUILTIN_SUB_OVERFLOW
522     long lz;
523     if (__builtin_sub_overflow((long)x, (long)y-1, &lz)) {
524 	return rb_int2big(rb_overflowed_fix_to_int(lz));
525     }
526     else {
527 	return (VALUE)lz;
528     }
529 #else
530     long lz = FIX2LONG(x) - FIX2LONG(y);
531     return LONG2NUM(lz);
532 #endif
533 }
534 
535 /* arguments must be Fixnum */
536 static inline VALUE
rb_fix_mul_fix(VALUE x,VALUE y)537 rb_fix_mul_fix(VALUE x, VALUE y)
538 {
539     long lx = FIX2LONG(x);
540     long ly = FIX2LONG(y);
541 #ifdef DLONG
542     return DL2NUM((DLONG)lx * (DLONG)ly);
543 #else
544     if (MUL_OVERFLOW_FIXNUM_P(lx, ly)) {
545 	return rb_big_mul(rb_int2big(lx), rb_int2big(ly));
546     }
547     else {
548 	return LONG2FIX(lx * ly);
549     }
550 #endif
551 }
552 
553 /*
554  * This behaves different from C99 for negative arguments.
555  * Note that div may overflow fixnum.
556  */
557 static inline void
rb_fix_divmod_fix(VALUE a,VALUE b,VALUE * divp,VALUE * modp)558 rb_fix_divmod_fix(VALUE a, VALUE b, VALUE *divp, VALUE *modp)
559 {
560     /* assume / and % comply C99.
561      * ldiv(3) won't be inlined by GCC and clang.
562      * I expect / and % are compiled as single idiv.
563      */
564     long x = FIX2LONG(a);
565     long y = FIX2LONG(b);
566     long div, mod;
567     if (x == FIXNUM_MIN && y == -1) {
568 	if (divp) *divp = LONG2NUM(-FIXNUM_MIN);
569 	if (modp) *modp = LONG2FIX(0);
570 	return;
571     }
572     div = x / y;
573     mod = x % y;
574     if (y > 0 ? mod < 0 : mod > 0) {
575 	mod += y;
576 	div -= 1;
577     }
578     if (divp) *divp = LONG2FIX(div);
579     if (modp) *modp = LONG2FIX(mod);
580 }
581 
582 /* div() for Ruby
583  * This behaves different from C99 for negative arguments.
584  */
585 static inline VALUE
rb_fix_div_fix(VALUE x,VALUE y)586 rb_fix_div_fix(VALUE x, VALUE y)
587 {
588     VALUE div;
589     rb_fix_divmod_fix(x, y, &div, NULL);
590     return div;
591 }
592 
593 /* mod() for Ruby
594  * This behaves different from C99 for negative arguments.
595  */
596 static inline VALUE
rb_fix_mod_fix(VALUE x,VALUE y)597 rb_fix_mod_fix(VALUE x, VALUE y)
598 {
599     VALUE mod;
600     rb_fix_divmod_fix(x, y, NULL, &mod);
601     return mod;
602 }
603 
604 #if defined(HAVE_UINT128_T) && defined(HAVE_LONG_LONG)
605 #   define bit_length(x) \
606     (unsigned int) \
607     (sizeof(x) <= SIZEOF_INT ? SIZEOF_INT * CHAR_BIT - nlz_int((unsigned int)(x)) : \
608      sizeof(x) <= SIZEOF_LONG ? SIZEOF_LONG * CHAR_BIT - nlz_long((unsigned long)(x)) : \
609      sizeof(x) <= SIZEOF_LONG_LONG ? SIZEOF_LONG_LONG * CHAR_BIT - nlz_long_long((unsigned LONG_LONG)(x)) : \
610      SIZEOF_INT128_T * CHAR_BIT - nlz_int128((uint128_t)(x)))
611 #elif defined(HAVE_UINT128_T)
612 #   define bit_length(x) \
613     (unsigned int) \
614     (sizeof(x) <= SIZEOF_INT ? SIZEOF_INT * CHAR_BIT - nlz_int((unsigned int)(x)) : \
615      sizeof(x) <= SIZEOF_LONG ? SIZEOF_LONG * CHAR_BIT - nlz_long((unsigned long)(x)) : \
616      SIZEOF_INT128_T * CHAR_BIT - nlz_int128((uint128_t)(x)))
617 #elif defined(HAVE_LONG_LONG)
618 #   define bit_length(x) \
619     (unsigned int) \
620     (sizeof(x) <= SIZEOF_INT ? SIZEOF_INT * CHAR_BIT - nlz_int((unsigned int)(x)) : \
621      sizeof(x) <= SIZEOF_LONG ? SIZEOF_LONG * CHAR_BIT - nlz_long((unsigned long)(x)) : \
622      SIZEOF_LONG_LONG * CHAR_BIT - nlz_long_long((unsigned LONG_LONG)(x)))
623 #else
624 #   define bit_length(x) \
625     (unsigned int) \
626     (sizeof(x) <= SIZEOF_INT ? SIZEOF_INT * CHAR_BIT - nlz_int((unsigned int)(x)) : \
627      SIZEOF_LONG * CHAR_BIT - nlz_long((unsigned long)(x)))
628 #endif
629 
630 #ifndef BDIGIT
631 # if SIZEOF_INT*2 <= SIZEOF_LONG_LONG
632 #  define BDIGIT unsigned int
633 #  define SIZEOF_BDIGIT SIZEOF_INT
634 #  define BDIGIT_DBL unsigned LONG_LONG
635 #  define BDIGIT_DBL_SIGNED LONG_LONG
636 #  define PRI_BDIGIT_PREFIX ""
637 #  define PRI_BDIGIT_DBL_PREFIX PRI_LL_PREFIX
638 # elif SIZEOF_INT*2 <= SIZEOF_LONG
639 #  define BDIGIT unsigned int
640 #  define SIZEOF_BDIGIT SIZEOF_INT
641 #  define BDIGIT_DBL unsigned long
642 #  define BDIGIT_DBL_SIGNED long
643 #  define PRI_BDIGIT_PREFIX ""
644 #  define PRI_BDIGIT_DBL_PREFIX "l"
645 # elif SIZEOF_SHORT*2 <= SIZEOF_LONG
646 #  define BDIGIT unsigned short
647 #  define SIZEOF_BDIGIT SIZEOF_SHORT
648 #  define BDIGIT_DBL unsigned long
649 #  define BDIGIT_DBL_SIGNED long
650 #  define PRI_BDIGIT_PREFIX "h"
651 #  define PRI_BDIGIT_DBL_PREFIX "l"
652 # else
653 #  define BDIGIT unsigned short
654 #  define SIZEOF_BDIGIT (SIZEOF_LONG/2)
655 #  define SIZEOF_ACTUAL_BDIGIT SIZEOF_LONG
656 #  define BDIGIT_DBL unsigned long
657 #  define BDIGIT_DBL_SIGNED long
658 #  define PRI_BDIGIT_PREFIX "h"
659 #  define PRI_BDIGIT_DBL_PREFIX "l"
660 # endif
661 #endif
662 #ifndef SIZEOF_ACTUAL_BDIGIT
663 # define SIZEOF_ACTUAL_BDIGIT SIZEOF_BDIGIT
664 #endif
665 
666 #ifdef PRI_BDIGIT_PREFIX
667 # define PRIdBDIGIT PRI_BDIGIT_PREFIX"d"
668 # define PRIiBDIGIT PRI_BDIGIT_PREFIX"i"
669 # define PRIoBDIGIT PRI_BDIGIT_PREFIX"o"
670 # define PRIuBDIGIT PRI_BDIGIT_PREFIX"u"
671 # define PRIxBDIGIT PRI_BDIGIT_PREFIX"x"
672 # define PRIXBDIGIT PRI_BDIGIT_PREFIX"X"
673 #endif
674 
675 #ifdef PRI_BDIGIT_DBL_PREFIX
676 # define PRIdBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"d"
677 # define PRIiBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"i"
678 # define PRIoBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"o"
679 # define PRIuBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"u"
680 # define PRIxBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"x"
681 # define PRIXBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"X"
682 #endif
683 
684 #define BIGNUM_EMBED_LEN_NUMBITS 3
685 #ifndef BIGNUM_EMBED_LEN_MAX
686 # if (SIZEOF_VALUE*3/SIZEOF_ACTUAL_BDIGIT) < (1 << BIGNUM_EMBED_LEN_NUMBITS)-1
687 #   define BIGNUM_EMBED_LEN_MAX (SIZEOF_VALUE*3/SIZEOF_ACTUAL_BDIGIT)
688 # else
689 #   define BIGNUM_EMBED_LEN_MAX ((1 << BIGNUM_EMBED_LEN_NUMBITS)-1)
690 # endif
691 #endif
692 
693 struct RBignum {
694     struct RBasic basic;
695     union {
696         struct {
697             size_t len;
698             BDIGIT *digits;
699         } heap;
700         BDIGIT ary[BIGNUM_EMBED_LEN_MAX];
701     } as;
702 };
703 #define BIGNUM_SIGN_BIT ((VALUE)FL_USER1)
704 /* sign: positive:1, negative:0 */
705 #define BIGNUM_SIGN(b) ((RBASIC(b)->flags & BIGNUM_SIGN_BIT) != 0)
706 #define BIGNUM_SET_SIGN(b,sign) \
707   ((sign) ? (RBASIC(b)->flags |= BIGNUM_SIGN_BIT) \
708           : (RBASIC(b)->flags &= ~BIGNUM_SIGN_BIT))
709 #define BIGNUM_POSITIVE_P(b) BIGNUM_SIGN(b)
710 #define BIGNUM_NEGATIVE_P(b) (!BIGNUM_SIGN(b))
711 #define BIGNUM_NEGATE(b) (RBASIC(b)->flags ^= BIGNUM_SIGN_BIT)
712 
713 #define BIGNUM_EMBED_FLAG ((VALUE)FL_USER2)
714 #define BIGNUM_EMBED_LEN_MASK \
715     (~(~(VALUE)0U << BIGNUM_EMBED_LEN_NUMBITS) << BIGNUM_EMBED_LEN_SHIFT)
716 #define BIGNUM_EMBED_LEN_SHIFT \
717     (FL_USHIFT+3) /* bit offset of BIGNUM_EMBED_LEN_MASK */
718 #define BIGNUM_LEN(b) \
719     ((RBASIC(b)->flags & BIGNUM_EMBED_FLAG) ? \
720      (size_t)((RBASIC(b)->flags >> BIGNUM_EMBED_LEN_SHIFT) & \
721 	      (BIGNUM_EMBED_LEN_MASK >> BIGNUM_EMBED_LEN_SHIFT)) : \
722      RBIGNUM(b)->as.heap.len)
723 /* LSB:BIGNUM_DIGITS(b)[0], MSB:BIGNUM_DIGITS(b)[BIGNUM_LEN(b)-1] */
724 #define BIGNUM_DIGITS(b) \
725     ((RBASIC(b)->flags & BIGNUM_EMBED_FLAG) ? \
726      RBIGNUM(b)->as.ary : \
727      RBIGNUM(b)->as.heap.digits)
728 #define BIGNUM_LENINT(b) rb_long2int(BIGNUM_LEN(b))
729 
730 #define RBIGNUM(obj) (R_CAST(RBignum)(obj))
731 
732 struct RRational {
733     struct RBasic basic;
734     const VALUE num;
735     const VALUE den;
736 };
737 
738 #define RRATIONAL(obj) (R_CAST(RRational)(obj))
739 #define RRATIONAL_SET_NUM(rat, n) RB_OBJ_WRITE((rat), &((struct RRational *)(rat))->num,(n))
740 #define RRATIONAL_SET_DEN(rat, d) RB_OBJ_WRITE((rat), &((struct RRational *)(rat))->den,(d))
741 
742 struct RFloat {
743     struct RBasic basic;
744     double float_value;
745 };
746 
747 #define RFLOAT(obj)  (R_CAST(RFloat)(obj))
748 
749 struct RComplex {
750     struct RBasic basic;
751     const VALUE real;
752     const VALUE imag;
753 };
754 
755 #define RCOMPLEX(obj) (R_CAST(RComplex)(obj))
756 
757 /* shortcut macro for internal only */
758 #define RCOMPLEX_SET_REAL(cmp, r) RB_OBJ_WRITE((cmp), &((struct RComplex *)(cmp))->real,(r))
759 #define RCOMPLEX_SET_IMAG(cmp, i) RB_OBJ_WRITE((cmp), &((struct RComplex *)(cmp))->imag,(i))
760 
761 enum ruby_rhash_flags {
762     RHASH_ST_TABLE_FLAG = FL_USER3,
763     RHASH_AR_TABLE_MAX_SIZE = 8,
764     RHASH_AR_TABLE_SIZE_MASK = (FL_USER4|FL_USER5|FL_USER6|FL_USER7),
765     RHASH_AR_TABLE_SIZE_SHIFT = (FL_USHIFT+4),
766     RHASH_AR_TABLE_BOUND_MASK = (FL_USER8|FL_USER9|FL_USER10|FL_USER11),
767     RHASH_AR_TABLE_BOUND_SHIFT = (FL_USHIFT+8),
768 
769     RHASH_ENUM_END
770 };
771 
772 #define HASH_PROC_DEFAULT FL_USER2
773 
774 #define RHASH_AR_TABLE_SIZE_RAW(h) \
775   ((unsigned int)((RBASIC(h)->flags & RHASH_AR_TABLE_SIZE_MASK) >> RHASH_AR_TABLE_SIZE_SHIFT))
776 
777 int rb_hash_ar_table_p(VALUE hash);
778 struct ar_table_struct *rb_hash_ar_table(VALUE hash);
779 st_table *rb_hash_st_table(VALUE hash);
780 void rb_hash_st_table_set(VALUE hash, st_table *st);
781 
782 #if 0 /* for debug */
783 #define RHASH_AR_TABLE_P(hash)       rb_hash_ar_table_p(hash)
784 #define RHASH_AR_TABLE(h)            rb_hash_ar_table(h)
785 #define RHASH_ST_TABLE(h)            rb_hash_st_table(h)
786 #else
787 #define RHASH_AR_TABLE_P(hash)       (!FL_TEST_RAW((hash), RHASH_ST_TABLE_FLAG))
788 #define RHASH_AR_TABLE(hash)         (RHASH(hash)->as.ar)
789 #define RHASH_ST_TABLE(hash)         (RHASH(hash)->as.st)
790 #endif
791 
792 #define RHASH(obj)                   (R_CAST(RHash)(obj))
793 #define RHASH_ST_SIZE(h)             (RHASH_ST_TABLE(h)->num_entries)
794 #define RHASH_ST_TABLE_P(h)          (!RHASH_AR_TABLE_P(h))
795 #define RHASH_ST_CLEAR(h)            (FL_UNSET_RAW(h, RHASH_ST_TABLE_FLAG), RHASH(h)->as.ar = NULL)
796 
797 #define RHASH_AR_TABLE_SIZE_MASK     (VALUE)RHASH_AR_TABLE_SIZE_MASK
798 #define RHASH_AR_TABLE_SIZE_SHIFT    RHASH_AR_TABLE_SIZE_SHIFT
799 #define RHASH_AR_TABLE_BOUND_MASK    (VALUE)RHASH_AR_TABLE_BOUND_MASK
800 #define RHASH_AR_TABLE_BOUND_SHIFT   RHASH_AR_TABLE_BOUND_SHIFT
801 
802 #if USE_TRANSIENT_HEAP
803 #define RHASH_TRANSIENT_FLAG      FL_USER14
804 #define RHASH_TRANSIENT_P(hash)   FL_TEST_RAW((hash), RHASH_TRANSIENT_FLAG)
805 #define RHASH_SET_TRANSIENT_FLAG(h)   FL_SET_RAW(h, RHASH_TRANSIENT_FLAG)
806 #define RHASH_UNSET_TRANSIENT_FLAG(h) FL_UNSET_RAW(h, RHASH_TRANSIENT_FLAG)
807 #else
808 #define RHASH_TRANSIENT_P(hash)   0
809 #define RHASH_SET_TRANSIENT_FLAG(h)   ((void)0)
810 #define RHASH_UNSET_TRANSIENT_FLAG(h) ((void)0)
811 #endif
812 
813 #define RHASH_AR_TABLE_MAX_SIZE      8
814 #define RHASH_AR_TABLE_MAX_BOUND     RHASH_AR_TABLE_MAX_SIZE
815 
816 typedef struct ar_table_entry {
817     VALUE hash;
818     VALUE key;
819     VALUE record;
820 } ar_table_entry;
821 
822 typedef struct ar_table_struct {
823     ar_table_entry entries[RHASH_AR_TABLE_MAX_SIZE];
824 } ar_table;
825 
826 /*
827  * RHASH_AR_TABLE_P(h):
828  * * as.ar == NULL or
829  *   as.ar points ar_table.
830  * * as.ar is allocated by transient heap or xmalloc.
831  *
832  * !RHASH_AR_TABLE_P(h):
833  * * as.st points st_table.
834  */
835 struct RHash {
836     struct RBasic basic;
837     union {
838         st_table *st;
839         ar_table *ar; /* possibly 0 */
840     } as;
841     int iter_lev;
842     const VALUE ifnone;
843 };
844 
845 #ifdef RHASH_ITER_LEV
846 #  undef RHASH_ITER_LEV
847 #  undef RHASH_IFNONE
848 #  undef RHASH_SIZE
849 
850 #  define RHASH_ITER_LEV(h)  (RHASH(h)->iter_lev)
851 #  define RHASH_IFNONE(h)    (RHASH(h)->ifnone)
852 #  define RHASH_SIZE(h)      (RHASH_AR_TABLE_P(h) ? RHASH_AR_TABLE_SIZE_RAW(h) : RHASH_ST_SIZE(h))
853 #endif /* #ifdef RHASH_ITER_LEV */
854 
855 /* missing/setproctitle.c */
856 #ifndef HAVE_SETPROCTITLE
857 extern void ruby_init_setproctitle(int argc, char *argv[]);
858 #endif
859 
860 #define RSTRUCT_EMBED_LEN_MAX RSTRUCT_EMBED_LEN_MAX
861 #define RSTRUCT_EMBED_LEN_MASK RSTRUCT_EMBED_LEN_MASK
862 #define RSTRUCT_EMBED_LEN_SHIFT RSTRUCT_EMBED_LEN_SHIFT
863 
864 enum {
865     RSTRUCT_EMBED_LEN_MAX = 3,
866     RSTRUCT_EMBED_LEN_MASK = (RUBY_FL_USER2|RUBY_FL_USER1),
867     RSTRUCT_EMBED_LEN_SHIFT = (RUBY_FL_USHIFT+1),
868     RSTRUCT_TRANSIENT_FLAG = FL_USER3,
869 
870     RSTRUCT_ENUM_END
871 };
872 
873 #if USE_TRANSIENT_HEAP
874 #define RSTRUCT_TRANSIENT_P(st) FL_TEST_RAW((obj), RSTRUCT_TRANSIENT_FLAG)
875 #define RSTRUCT_TRANSIENT_SET(st) FL_SET_RAW((st), RSTRUCT_TRANSIENT_FLAG)
876 #define RSTRUCT_TRANSIENT_UNSET(st) FL_UNSET_RAW((st), RSTRUCT_TRANSIENT_FLAG)
877 #else
878 #define RSTRUCT_TRANSIENT_P(st) 0
879 #define RSTRUCT_TRANSIENT_SET(st) ((void)0)
880 #define RSTRUCT_TRANSIENT_UNSET(st) ((void)0)
881 #endif
882 
883 struct RStruct {
884     struct RBasic basic;
885     union {
886 	struct {
887 	    long len;
888 	    const VALUE *ptr;
889 	} heap;
890 	const VALUE ary[RSTRUCT_EMBED_LEN_MAX];
891     } as;
892 };
893 
894 #undef RSTRUCT_LEN
895 #undef RSTRUCT_PTR
896 #undef RSTRUCT_SET
897 #undef RSTRUCT_GET
898 #define RSTRUCT_EMBED_LEN(st)                               \
899     (long)((RBASIC(st)->flags >> RSTRUCT_EMBED_LEN_SHIFT) & \
900 	   (RSTRUCT_EMBED_LEN_MASK >> RSTRUCT_EMBED_LEN_SHIFT))
901 #define RSTRUCT_LEN(st) rb_struct_len(st)
902 #define RSTRUCT_LENINT(st) rb_long2int(RSTRUCT_LEN(st))
903 #define RSTRUCT_CONST_PTR(st) rb_struct_const_ptr(st)
904 #define RSTRUCT_PTR(st) ((VALUE *)RSTRUCT_CONST_PTR(RB_OBJ_WB_UNPROTECT_FOR(STRUCT, st)))
905 #define RSTRUCT_SET(st, idx, v) RB_OBJ_WRITE(st, &RSTRUCT_CONST_PTR(st)[idx], (v))
906 #define RSTRUCT_GET(st, idx)    (RSTRUCT_CONST_PTR(st)[idx])
907 #define RSTRUCT(obj) (R_CAST(RStruct)(obj))
908 
909 static inline long
rb_struct_len(VALUE st)910 rb_struct_len(VALUE st)
911 {
912     return (RBASIC(st)->flags & RSTRUCT_EMBED_LEN_MASK) ?
913 	RSTRUCT_EMBED_LEN(st) : RSTRUCT(st)->as.heap.len;
914 }
915 
916 static inline const VALUE *
rb_struct_const_ptr(VALUE st)917 rb_struct_const_ptr(VALUE st)
918 {
919     return FIX_CONST_VALUE_PTR((RBASIC(st)->flags & RSTRUCT_EMBED_LEN_MASK) ?
920 	RSTRUCT(st)->as.ary : RSTRUCT(st)->as.heap.ptr);
921 }
922 
923 static inline const VALUE *
rb_struct_const_heap_ptr(VALUE st)924 rb_struct_const_heap_ptr(VALUE st)
925 {
926     /* TODO: check embed on debug mode */
927     return RSTRUCT(st)->as.heap.ptr;
928 }
929 
930 /* class.c */
931 
932 struct rb_deprecated_classext_struct {
933     char conflict[sizeof(VALUE) * 3];
934 };
935 
936 struct rb_subclass_entry;
937 typedef struct rb_subclass_entry rb_subclass_entry_t;
938 
939 struct rb_subclass_entry {
940     VALUE klass;
941     rb_subclass_entry_t *next;
942 };
943 
944 #if defined(HAVE_LONG_LONG)
945 typedef unsigned LONG_LONG rb_serial_t;
946 #define SERIALT2NUM ULL2NUM
947 #define PRI_SERIALT_PREFIX PRI_LL_PREFIX
948 #elif defined(HAVE_UINT64_T)
949 typedef uint64_t rb_serial_t;
950 #define SERIALT2NUM SIZET2NUM
951 #define PRI_SERIALT_PREFIX PRI_64_PREFIX
952 #else
953 typedef unsigned long rb_serial_t;
954 #define SERIALT2NUM ULONG2NUM
955 #define PRI_SERIALT_PREFIX PRI_LONG_PREFIX
956 #endif
957 
958 struct rb_classext_struct {
959     struct st_table *iv_index_tbl;
960     struct st_table *iv_tbl;
961     struct rb_id_table *const_tbl;
962     struct rb_id_table *callable_m_tbl;
963     rb_subclass_entry_t *subclasses;
964     rb_subclass_entry_t **parent_subclasses;
965     /**
966      * In the case that this is an `ICLASS`, `module_subclasses` points to the link
967      * in the module's `subclasses` list that indicates that the klass has been
968      * included. Hopefully that makes sense.
969      */
970     rb_subclass_entry_t **module_subclasses;
971     rb_serial_t class_serial;
972     const VALUE origin_;
973     VALUE refined_class;
974     rb_alloc_func_t allocator;
975 };
976 
977 typedef struct rb_classext_struct rb_classext_t;
978 
979 #undef RClass
980 struct RClass {
981     struct RBasic basic;
982     VALUE super;
983     rb_classext_t *ptr;
984     struct rb_id_table *m_tbl;
985 };
986 
987 void rb_class_subclass_add(VALUE super, VALUE klass);
988 void rb_class_remove_from_super_subclasses(VALUE);
989 int rb_singleton_class_internal_p(VALUE sklass);
990 
991 #define RCLASS_EXT(c) (RCLASS(c)->ptr)
992 #define RCLASS_IV_TBL(c) (RCLASS_EXT(c)->iv_tbl)
993 #define RCLASS_CONST_TBL(c) (RCLASS_EXT(c)->const_tbl)
994 #define RCLASS_M_TBL(c) (RCLASS(c)->m_tbl)
995 #define RCLASS_CALLABLE_M_TBL(c) (RCLASS_EXT(c)->callable_m_tbl)
996 #define RCLASS_IV_INDEX_TBL(c) (RCLASS_EXT(c)->iv_index_tbl)
997 #define RCLASS_ORIGIN(c) (RCLASS_EXT(c)->origin_)
998 #define RCLASS_REFINED_CLASS(c) (RCLASS_EXT(c)->refined_class)
999 #define RCLASS_SERIAL(c) (RCLASS_EXT(c)->class_serial)
1000 
1001 #define RICLASS_IS_ORIGIN FL_USER5
1002 
1003 static inline void
RCLASS_SET_ORIGIN(VALUE klass,VALUE origin)1004 RCLASS_SET_ORIGIN(VALUE klass, VALUE origin)
1005 {
1006     RB_OBJ_WRITE(klass, &RCLASS_ORIGIN(klass), origin);
1007     if (klass != origin) FL_SET(origin, RICLASS_IS_ORIGIN);
1008 }
1009 
1010 #undef RCLASS_SUPER
1011 static inline VALUE
RCLASS_SUPER(VALUE klass)1012 RCLASS_SUPER(VALUE klass)
1013 {
1014     return RCLASS(klass)->super;
1015 }
1016 
1017 static inline VALUE
RCLASS_SET_SUPER(VALUE klass,VALUE super)1018 RCLASS_SET_SUPER(VALUE klass, VALUE super)
1019 {
1020     if (super) {
1021 	rb_class_remove_from_super_subclasses(klass);
1022 	rb_class_subclass_add(super, klass);
1023     }
1024     RB_OBJ_WRITE(klass, &RCLASS(klass)->super, super);
1025     return super;
1026 }
1027 /* IMEMO: Internal memo object */
1028 
1029 #ifndef IMEMO_DEBUG
1030 #define IMEMO_DEBUG 0
1031 #endif
1032 
1033 struct RIMemo {
1034     VALUE flags;
1035     VALUE v0;
1036     VALUE v1;
1037     VALUE v2;
1038     VALUE v3;
1039 };
1040 
1041 enum imemo_type {
1042     imemo_env            =  0,
1043     imemo_cref           =  1, /*!< class reference */
1044     imemo_svar           =  2, /*!< special variable */
1045     imemo_throw_data     =  3,
1046     imemo_ifunc          =  4, /*!< iterator function */
1047     imemo_memo           =  5,
1048     imemo_ment           =  6,
1049     imemo_iseq           =  7,
1050     imemo_tmpbuf         =  8,
1051     imemo_ast            =  9,
1052     imemo_parser_strterm = 10
1053 };
1054 #define IMEMO_MASK   0x0f
1055 
1056 static inline enum imemo_type
imemo_type(VALUE imemo)1057 imemo_type(VALUE imemo)
1058 {
1059     return (RBASIC(imemo)->flags >> FL_USHIFT) & IMEMO_MASK;
1060 }
1061 
1062 static inline int
imemo_type_p(VALUE imemo,enum imemo_type imemo_type)1063 imemo_type_p(VALUE imemo, enum imemo_type imemo_type)
1064 {
1065     if (LIKELY(!RB_SPECIAL_CONST_P(imemo))) {
1066 	/* fixed at compile time if imemo_type is given. */
1067 	const VALUE mask = (IMEMO_MASK << FL_USHIFT) | RUBY_T_MASK;
1068 	const VALUE expected_type = (imemo_type << FL_USHIFT) | T_IMEMO;
1069 	/* fixed at runtime. */
1070 	return expected_type == (RBASIC(imemo)->flags & mask);
1071     }
1072     else {
1073 	return 0;
1074     }
1075 }
1076 
1077 /* FL_USER0 to FL_USER3 is for type */
1078 #define IMEMO_FL_USHIFT (FL_USHIFT + 4)
1079 #define IMEMO_FL_USER0 FL_USER4
1080 #define IMEMO_FL_USER1 FL_USER5
1081 #define IMEMO_FL_USER2 FL_USER6
1082 #define IMEMO_FL_USER3 FL_USER7
1083 #define IMEMO_FL_USER4 FL_USER8
1084 
1085 /* CREF (Class REFerence) is defined in method.h */
1086 
1087 /*! SVAR (Special VARiable) */
1088 struct vm_svar {
1089     VALUE flags;
1090     const VALUE cref_or_me; /*!< class reference or rb_method_entry_t */
1091     const VALUE lastline;
1092     const VALUE backref;
1093     const VALUE others;
1094 };
1095 
1096 
1097 #define THROW_DATA_CONSUMED IMEMO_FL_USER0
1098 
1099 /*! THROW_DATA */
1100 struct vm_throw_data {
1101     VALUE flags;
1102     VALUE reserved;
1103     const VALUE throw_obj;
1104     const struct rb_control_frame_struct *catch_frame;
1105     VALUE throw_state;
1106 };
1107 
1108 #define THROW_DATA_P(err) RB_TYPE_P((VALUE)(err), T_IMEMO)
1109 
1110 /* IFUNC (Internal FUNCtion) */
1111 
1112 struct vm_ifunc_argc {
1113 #if SIZEOF_INT * 2 > SIZEOF_VALUE
1114     signed int min: (SIZEOF_VALUE * CHAR_BIT) / 2;
1115     signed int max: (SIZEOF_VALUE * CHAR_BIT) / 2;
1116 #else
1117     int min, max;
1118 #endif
1119 };
1120 
1121 /*! IFUNC (Internal FUNCtion) */
1122 struct vm_ifunc {
1123     VALUE flags;
1124     VALUE reserved;
1125     VALUE (*func)(ANYARGS);
1126     const void *data;
1127     struct vm_ifunc_argc argc;
1128 };
1129 
1130 #define IFUNC_NEW(a, b, c) ((struct vm_ifunc *)rb_imemo_new(imemo_ifunc, (VALUE)(a), (VALUE)(b), (VALUE)(c), 0))
1131 struct vm_ifunc *rb_vm_ifunc_new(VALUE (*func)(ANYARGS), const void *data, int min_argc, int max_argc);
1132 static inline struct vm_ifunc *
rb_vm_ifunc_proc_new(VALUE (* func)(ANYARGS),const void * data)1133 rb_vm_ifunc_proc_new(VALUE (*func)(ANYARGS), const void *data)
1134 {
1135     return rb_vm_ifunc_new(func, data, 0, UNLIMITED_ARGUMENTS);
1136 }
1137 
1138 typedef struct rb_imemo_tmpbuf_struct {
1139     VALUE flags;
1140     VALUE reserved;
1141     VALUE *ptr; /* malloc'ed buffer */
1142     struct rb_imemo_tmpbuf_struct *next; /* next imemo */
1143     size_t cnt; /* buffer size in VALUE */
1144 } rb_imemo_tmpbuf_t;
1145 
1146 VALUE rb_imemo_tmpbuf_auto_free_pointer(void *buf);
1147 VALUE rb_imemo_tmpbuf_auto_free_maybe_mark_buffer(void *buf, size_t cnt);
1148 rb_imemo_tmpbuf_t *rb_imemo_tmpbuf_parser_heap(void *buf, rb_imemo_tmpbuf_t *old_heap, size_t cnt);
1149 
1150 #define RB_IMEMO_TMPBUF_PTR(v) \
1151     ((void *)(((const struct rb_imemo_tmpbuf_struct *)(v))->ptr))
1152 
1153 static inline VALUE
rb_imemo_tmpbuf_auto_free_pointer_new_from_an_RString(VALUE str)1154 rb_imemo_tmpbuf_auto_free_pointer_new_from_an_RString(VALUE str)
1155 {
1156     const void *src;
1157     void *dst;
1158     size_t len;
1159 
1160     SafeStringValue(str);
1161     len = RSTRING_LEN(str);
1162     src = RSTRING_PTR(str);
1163     dst = ruby_xmalloc(len);
1164     memcpy(dst, src, len);
1165     return rb_imemo_tmpbuf_auto_free_pointer(dst);
1166 }
1167 
1168 void rb_strterm_mark(VALUE obj);
1169 
1170 /*! MEMO
1171  *
1172  * @see imemo_type
1173  * */
1174 struct MEMO {
1175     VALUE flags;
1176     VALUE reserved;
1177     const VALUE v1;
1178     const VALUE v2;
1179     union {
1180 	long cnt;
1181 	long state;
1182 	const VALUE value;
1183 	VALUE (*func)(ANYARGS);
1184     } u3;
1185 };
1186 
1187 #define MEMO_V1_SET(m, v) RB_OBJ_WRITE((m), &(m)->v1, (v))
1188 #define MEMO_V2_SET(m, v) RB_OBJ_WRITE((m), &(m)->v2, (v))
1189 
1190 #define MEMO_CAST(m) ((struct MEMO *)m)
1191 
1192 #define MEMO_NEW(a, b, c) ((struct MEMO *)rb_imemo_new(imemo_memo, (VALUE)(a), (VALUE)(b), (VALUE)(c), 0))
1193 
1194 #define roomof(x, y) (((x) + (y) - 1) / (y))
1195 #define type_roomof(x, y) roomof(sizeof(x), sizeof(y))
1196 #define MEMO_FOR(type, value) ((type *)RARRAY_PTR(value))
1197 #define NEW_MEMO_FOR(type, value) \
1198   ((value) = rb_ary_tmp_new_fill(type_roomof(type, VALUE)), MEMO_FOR(type, value))
1199 #define NEW_PARTIAL_MEMO_FOR(type, value, member) \
1200   ((value) = rb_ary_tmp_new_fill(type_roomof(type, VALUE)), \
1201    rb_ary_set_len((value), offsetof(type, member) / sizeof(VALUE)), \
1202    MEMO_FOR(type, value))
1203 
1204 #define STRING_P(s) (RB_TYPE_P((s), T_STRING) && CLASS_OF(s) == rb_cString)
1205 
1206 #ifdef RUBY_INTEGER_UNIFICATION
1207 # define rb_cFixnum rb_cInteger
1208 # define rb_cBignum rb_cInteger
1209 #endif
1210 
1211 enum {
1212     cmp_opt_Fixnum,
1213     cmp_opt_String,
1214     cmp_opt_Float,
1215     cmp_optimizable_count
1216 };
1217 
1218 struct cmp_opt_data {
1219     unsigned int opt_methods;
1220     unsigned int opt_inited;
1221 };
1222 
1223 #define NEW_CMP_OPT_MEMO(type, value) \
1224     NEW_PARTIAL_MEMO_FOR(type, value, cmp_opt)
1225 #define CMP_OPTIMIZABLE_BIT(type) (1U << TOKEN_PASTE(cmp_opt_,type))
1226 #define CMP_OPTIMIZABLE(data, type) \
1227     (((data).opt_inited & CMP_OPTIMIZABLE_BIT(type)) ? \
1228      ((data).opt_methods & CMP_OPTIMIZABLE_BIT(type)) : \
1229      (((data).opt_inited |= CMP_OPTIMIZABLE_BIT(type)), \
1230       rb_method_basic_definition_p(TOKEN_PASTE(rb_c,type), id_cmp) && \
1231       ((data).opt_methods |= CMP_OPTIMIZABLE_BIT(type))))
1232 
1233 #define OPTIMIZED_CMP(a, b, data) \
1234     ((FIXNUM_P(a) && FIXNUM_P(b) && CMP_OPTIMIZABLE(data, Fixnum)) ? \
1235      (((long)a > (long)b) ? 1 : ((long)a < (long)b) ? -1 : 0) : \
1236      (STRING_P(a) && STRING_P(b) && CMP_OPTIMIZABLE(data, String)) ? \
1237      rb_str_cmp(a, b) : \
1238      (RB_FLOAT_TYPE_P(a) && RB_FLOAT_TYPE_P(b) && CMP_OPTIMIZABLE(data, Float)) ? \
1239      rb_float_cmp(a, b) : \
1240      rb_cmpint(rb_funcallv(a, id_cmp, 1, &b), a, b))
1241 
1242 /* ment is in method.h */
1243 
1244 /* global variable */
1245 
1246 struct rb_global_entry {
1247     struct rb_global_variable *var;
1248     ID id;
1249 };
1250 
1251 struct rb_global_entry *rb_global_entry(ID);
1252 VALUE rb_gvar_get(struct rb_global_entry *);
1253 VALUE rb_gvar_set(struct rb_global_entry *, VALUE);
1254 VALUE rb_gvar_defined(struct rb_global_entry *);
1255 
1256 /* array.c */
1257 
1258 #ifndef ARRAY_DEBUG
1259 #define ARRAY_DEBUG 0
1260 #endif
1261 
1262 #ifdef ARRAY_DEBUG
1263 #define RARRAY_PTR_IN_USE_FLAG FL_USER14
1264 #define ARY_PTR_USING_P(ary) FL_TEST_RAW((ary), RARRAY_PTR_IN_USE_FLAG)
1265 #else
1266 
1267 /* disable debug function */
1268 #undef  RARRAY_PTR_USE_START_TRANSIENT
1269 #undef  RARRAY_PTR_USE_END_TRANSIENT
1270 #define RARRAY_PTR_USE_START_TRANSIENT(a) ((VALUE *)RARRAY_CONST_PTR_TRANSIENT(a))
1271 #define RARRAY_PTR_USE_END_TRANSIENT(a)
1272 #define ARY_PTR_USING_P(ary) 0
1273 
1274 #endif
1275 
1276 #if USE_TRANSIENT_HEAP
1277 #define RARY_TRANSIENT_SET(ary) FL_SET_RAW((ary), RARRAY_TRANSIENT_FLAG);
1278 #define RARY_TRANSIENT_UNSET(ary) FL_UNSET_RAW((ary), RARRAY_TRANSIENT_FLAG);
1279 #else
1280 #undef RARRAY_TRANSIENT_P
1281 #define RARRAY_TRANSIENT_P(a) 0
1282 #define RARY_TRANSIENT_SET(ary) ((void)0)
1283 #define RARY_TRANSIENT_UNSET(ary) ((void)0)
1284 #endif
1285 
1286 
1287 VALUE rb_ary_last(int, const VALUE *, VALUE);
1288 void rb_ary_set_len(VALUE, long);
1289 void rb_ary_delete_same(VALUE, VALUE);
1290 VALUE rb_ary_tmp_new_fill(long capa);
1291 VALUE rb_ary_at(VALUE, VALUE);
1292 VALUE rb_ary_aref1(VALUE ary, VALUE i);
1293 VALUE rb_ary_aref2(VALUE ary, VALUE b, VALUE e);
1294 size_t rb_ary_memsize(VALUE);
1295 VALUE rb_to_array_type(VALUE obj);
1296 VALUE rb_check_to_array(VALUE ary);
1297 VALUE rb_ary_tmp_new_from_values(VALUE, long, const VALUE *);
1298 VALUE rb_ary_behead(VALUE, long);
1299 #if defined(__GNUC__) && defined(HAVE_VA_ARGS_MACRO)
1300 #define rb_ary_new_from_args(n, ...) \
1301     __extension__ ({ \
1302 	const VALUE args_to_new_ary[] = {__VA_ARGS__}; \
1303 	if (__builtin_constant_p(n)) { \
1304 	    STATIC_ASSERT(rb_ary_new_from_args, numberof(args_to_new_ary) == (n)); \
1305 	} \
1306 	rb_ary_new_from_values(numberof(args_to_new_ary), args_to_new_ary); \
1307     })
1308 #endif
1309 
1310 static inline VALUE
rb_ary_entry_internal(VALUE ary,long offset)1311 rb_ary_entry_internal(VALUE ary, long offset)
1312 {
1313     long len = RARRAY_LEN(ary);
1314     const VALUE *ptr = RARRAY_CONST_PTR_TRANSIENT(ary);
1315     if (len == 0) return Qnil;
1316     if (offset < 0) {
1317         offset += len;
1318         if (offset < 0) return Qnil;
1319     }
1320     else if (len <= offset) {
1321         return Qnil;
1322     }
1323     return ptr[offset];
1324 }
1325 
1326 /* bignum.c */
1327 extern const char ruby_digitmap[];
1328 double rb_big_fdiv_double(VALUE x, VALUE y);
1329 VALUE rb_big_uminus(VALUE x);
1330 VALUE rb_big_hash(VALUE);
1331 VALUE rb_big_odd_p(VALUE);
1332 VALUE rb_big_even_p(VALUE);
1333 size_t rb_big_size(VALUE);
1334 VALUE rb_integer_float_cmp(VALUE x, VALUE y);
1335 VALUE rb_integer_float_eq(VALUE x, VALUE y);
1336 VALUE rb_cstr_parse_inum(const char *str, ssize_t len, char **endp, int base);
1337 VALUE rb_str_convert_to_inum(VALUE str, int base, int badcheck, int raise_exception);
1338 VALUE rb_big_comp(VALUE x);
1339 VALUE rb_big_aref(VALUE x, VALUE y);
1340 VALUE rb_big_abs(VALUE x);
1341 VALUE rb_big_size_m(VALUE big);
1342 VALUE rb_big_bit_length(VALUE big);
1343 VALUE rb_big_remainder(VALUE x, VALUE y);
1344 VALUE rb_big_gt(VALUE x, VALUE y);
1345 VALUE rb_big_ge(VALUE x, VALUE y);
1346 VALUE rb_big_lt(VALUE x, VALUE y);
1347 VALUE rb_big_le(VALUE x, VALUE y);
1348 VALUE rb_int_powm(int const argc, VALUE * const argv, VALUE const num);
1349 
1350 /* class.c */
1351 VALUE rb_class_boot(VALUE);
1352 VALUE rb_class_inherited(VALUE, VALUE);
1353 VALUE rb_make_metaclass(VALUE, VALUE);
1354 VALUE rb_include_class_new(VALUE, VALUE);
1355 void rb_class_foreach_subclass(VALUE klass, void (*f)(VALUE, VALUE), VALUE);
1356 void rb_class_detach_subclasses(VALUE);
1357 void rb_class_detach_module_subclasses(VALUE);
1358 void rb_class_remove_from_module_subclasses(VALUE);
1359 VALUE rb_obj_methods(int argc, const VALUE *argv, VALUE obj);
1360 VALUE rb_obj_protected_methods(int argc, const VALUE *argv, VALUE obj);
1361 VALUE rb_obj_private_methods(int argc, const VALUE *argv, VALUE obj);
1362 VALUE rb_obj_public_methods(int argc, const VALUE *argv, VALUE obj);
1363 VALUE rb_special_singleton_class(VALUE);
1364 VALUE rb_singleton_class_clone_and_attach(VALUE obj, VALUE attach);
1365 VALUE rb_singleton_class_get(VALUE obj);
1366 void Init_class_hierarchy(void);
1367 
1368 int rb_class_has_methods(VALUE c);
1369 void rb_undef_methods_from(VALUE klass, VALUE super);
1370 
1371 /* compar.c */
1372 VALUE rb_invcmp(VALUE, VALUE);
1373 
1374 /* compile.c */
1375 struct rb_block;
1376 int rb_dvar_defined(ID, const struct rb_block *);
1377 int rb_local_defined(ID, const struct rb_block *);
1378 const char * rb_insns_name(int i);
1379 VALUE rb_insns_name_array(void);
1380 int rb_vm_insn_addr2insn(const void *);
1381 
1382 /* complex.c */
1383 VALUE rb_dbl_complex_new_polar_pi(double abs, double ang);
1384 
1385 struct rb_thread_struct;
1386 /* cont.c */
1387 struct rb_fiber_struct;
1388 VALUE rb_obj_is_fiber(VALUE);
1389 void rb_fiber_reset_root_local_storage(struct rb_thread_struct *);
1390 void ruby_register_rollback_func_for_ensure(VALUE (*ensure_func)(ANYARGS), VALUE (*rollback_func)(ANYARGS));
1391 void rb_fiber_init_mjit_cont(struct rb_fiber_struct *fiber);
1392 
1393 /* debug.c */
1394 PRINTF_ARGS(void ruby_debug_printf(const char*, ...), 1, 2);
1395 
1396 /* dir.c */
1397 VALUE rb_dir_getwd_ospath(void);
1398 
1399 /* dmyext.c */
1400 void Init_enc(void);
1401 void Init_ext(void);
1402 
1403 /* encoding.c */
1404 ID rb_id_encoding(void);
1405 #ifdef RUBY_ENCODING_H
1406 rb_encoding *rb_enc_get_from_index(int index);
1407 rb_encoding *rb_enc_check_str(VALUE str1, VALUE str2);
1408 #endif
1409 int rb_encdb_replicate(const char *alias, const char *orig);
1410 int rb_encdb_alias(const char *alias, const char *orig);
1411 int rb_encdb_dummy(const char *name);
1412 void rb_encdb_declare(const char *name);
1413 void rb_enc_set_base(const char *name, const char *orig);
1414 int rb_enc_set_dummy(int index);
1415 void rb_encdb_set_unicode(int index);
1416 PUREFUNC(int rb_data_is_encoding(VALUE obj));
1417 
1418 /* enum.c */
1419 extern VALUE rb_cArithSeq;
1420 VALUE rb_f_send(int argc, VALUE *argv, VALUE recv);
1421 VALUE rb_nmin_run(VALUE obj, VALUE num, int by, int rev, int ary);
1422 
1423 /* error.c */
1424 extern VALUE rb_eEAGAIN;
1425 extern VALUE rb_eEWOULDBLOCK;
1426 extern VALUE rb_eEINPROGRESS;
1427 void rb_report_bug_valist(VALUE file, int line, const char *fmt, va_list args);
1428 VALUE rb_check_backtrace(VALUE);
1429 NORETURN(void rb_async_bug_errno(const char *,int));
1430 const char *rb_builtin_type_name(int t);
1431 const char *rb_builtin_class_name(VALUE x);
1432 PRINTF_ARGS(void rb_sys_warn(const char *fmt, ...), 1, 2);
1433 PRINTF_ARGS(void rb_syserr_warn(int err, const char *fmt, ...), 2, 3);
1434 PRINTF_ARGS(void rb_sys_warning(const char *fmt, ...), 1, 2);
1435 PRINTF_ARGS(void rb_syserr_warning(int err, const char *fmt, ...), 2, 3);
1436 #ifdef RUBY_ENCODING_H
1437 VALUE rb_syntax_error_append(VALUE, VALUE, int, int, rb_encoding*, const char*, va_list);
1438 PRINTF_ARGS(void rb_enc_warn(rb_encoding *enc, const char *fmt, ...), 2, 3);
1439 PRINTF_ARGS(void rb_sys_enc_warn(rb_encoding *enc, const char *fmt, ...), 2, 3);
1440 PRINTF_ARGS(void rb_syserr_enc_warn(int err, rb_encoding *enc, const char *fmt, ...), 3, 4);
1441 PRINTF_ARGS(void rb_enc_warning(rb_encoding *enc, const char *fmt, ...), 2, 3);
1442 PRINTF_ARGS(void rb_sys_enc_warning(rb_encoding *enc, const char *fmt, ...), 2, 3);
1443 PRINTF_ARGS(void rb_syserr_enc_warning(int err, rb_encoding *enc, const char *fmt, ...), 3, 4);
1444 #endif
1445 
1446 #define rb_raise_cstr(etype, mesg) \
1447     rb_exc_raise(rb_exc_new_str(etype, rb_str_new_cstr(mesg)))
1448 #define rb_raise_static(etype, mesg) \
1449     rb_exc_raise(rb_exc_new_str(etype, rb_str_new_static(mesg, rb_strlen_lit(mesg))))
1450 
1451 VALUE rb_name_err_new(VALUE mesg, VALUE recv, VALUE method);
1452 #define rb_name_err_raise_str(mesg, recv, name) \
1453     rb_exc_raise(rb_name_err_new(mesg, recv, name))
1454 #define rb_name_err_raise(mesg, recv, name) \
1455     rb_name_err_raise_str(rb_fstring_cstr(mesg), (recv), (name))
1456 VALUE rb_nomethod_err_new(VALUE mesg, VALUE recv, VALUE method, VALUE args, int priv);
1457 VALUE rb_key_err_new(VALUE mesg, VALUE recv, VALUE name);
1458 #define rb_key_err_raise(mesg, recv, name) \
1459     rb_exc_raise(rb_key_err_new(mesg, recv, name))
1460 NORETURN(void ruby_deprecated_internal_feature(const char *));
1461 #define DEPRECATED_INTERNAL_FEATURE(func) \
1462     (ruby_deprecated_internal_feature(func), UNREACHABLE)
1463 VALUE rb_warning_warn(VALUE mod, VALUE str);
1464 PRINTF_ARGS(VALUE rb_warning_string(const char *fmt, ...), 1, 2);
1465 
1466 /* eval.c */
1467 VALUE rb_refinement_module_get_refined_class(VALUE module);
1468 extern ID ruby_static_id_signo, ruby_static_id_status;
1469 void rb_class_modify_check(VALUE);
1470 #define id_signo ruby_static_id_signo
1471 #define id_status ruby_static_id_status
1472 
1473 /* eval_error.c */
1474 VALUE rb_get_backtrace(VALUE info);
1475 
1476 /* eval_jump.c */
1477 void rb_call_end_proc(VALUE data);
1478 void rb_mark_end_proc(void);
1479 
1480 /* file.c */
1481 extern const char ruby_null_device[];
1482 VALUE rb_home_dir_of(VALUE user, VALUE result);
1483 VALUE rb_default_home_dir(VALUE result);
1484 VALUE rb_realpath_internal(VALUE basedir, VALUE path, int strict);
1485 VALUE rb_check_realpath(VALUE basedir, VALUE path);
1486 void rb_file_const(const char*, VALUE);
1487 int rb_file_load_ok(const char *);
1488 VALUE rb_file_expand_path_fast(VALUE, VALUE);
1489 VALUE rb_file_expand_path_internal(VALUE, VALUE, int, int, VALUE);
1490 VALUE rb_get_path_check_to_string(VALUE, int);
1491 VALUE rb_get_path_check_convert(VALUE, VALUE, int);
1492 VALUE rb_get_path_check(VALUE, int);
1493 void Init_File(void);
1494 int ruby_is_fd_loadable(int fd);
1495 
1496 #ifdef RUBY_FUNCTION_NAME_STRING
1497 # if defined __GNUC__ && __GNUC__ >= 4
1498 #   pragma GCC visibility push(default)
1499 # endif
1500 NORETURN(void rb_sys_fail_path_in(const char *func_name, VALUE path));
1501 NORETURN(void rb_syserr_fail_path_in(const char *func_name, int err, VALUE path));
1502 # if defined __GNUC__ && __GNUC__ >= 4
1503 #   pragma GCC visibility pop
1504 # endif
1505 # define rb_sys_fail_path(path) rb_sys_fail_path_in(RUBY_FUNCTION_NAME_STRING, path)
1506 # define rb_syserr_fail_path(err, path) rb_syserr_fail_path_in(RUBY_FUNCTION_NAME_STRING, (err), (path))
1507 #else
1508 # define rb_sys_fail_path(path) rb_sys_fail_str(path)
1509 # define rb_syserr_fail_path(err, path) rb_syserr_fail_str((err), (path))
1510 #endif
1511 
1512 /* gc.c */
1513 extern VALUE *ruby_initial_gc_stress_ptr;
1514 extern int ruby_disable_gc;
1515 void Init_heap(void);
1516 void *ruby_mimmalloc(size_t size);
1517 void ruby_mimfree(void *ptr);
1518 void rb_objspace_set_event_hook(const rb_event_flag_t event);
1519 #if USE_RGENGC
1520 void rb_gc_writebarrier_remember(VALUE obj);
1521 #else
1522 #define rb_gc_writebarrier_remember(obj) 0
1523 #endif
1524 void ruby_gc_set_params(int safe_level);
1525 void rb_copy_wb_protected_attribute(VALUE dest, VALUE obj);
1526 
1527 #if defined(HAVE_MALLOC_USABLE_SIZE) || defined(HAVE_MALLOC_SIZE) || defined(_WIN32)
1528 #define ruby_sized_xrealloc(ptr, new_size, old_size) ruby_xrealloc(ptr, new_size)
1529 #define ruby_sized_xrealloc2(ptr, new_count, element_size, old_count) ruby_xrealloc(ptr, new_count, element_size)
1530 #define ruby_sized_xfree(ptr, size) ruby_xfree(ptr)
1531 #define SIZED_REALLOC_N(var,type,n,old_n) REALLOC_N(var, type, n)
1532 #else
1533 RUBY_SYMBOL_EXPORT_BEGIN
1534 void *ruby_sized_xrealloc(void *ptr, size_t new_size, size_t old_size) RUBY_ATTR_ALLOC_SIZE((2));
1535 void *ruby_sized_xrealloc2(void *ptr, size_t new_count, size_t element_size, size_t old_count) RUBY_ATTR_ALLOC_SIZE((2, 3));
1536 void ruby_sized_xfree(void *x, size_t size);
1537 RUBY_SYMBOL_EXPORT_END
1538 #define SIZED_REALLOC_N(var,type,n,old_n) ((var)=(type*)ruby_sized_xrealloc((char*)(var), (n) * sizeof(type), (old_n) * sizeof(type)))
1539 #endif
1540 
1541 /* optimized version of NEWOBJ() */
1542 #undef NEWOBJF_OF
1543 #undef RB_NEWOBJ_OF
1544 #define RB_NEWOBJ_OF(obj,type,klass,flags) \
1545   type *(obj) = (type*)(((flags) & FL_WB_PROTECTED) ? \
1546 			rb_wb_protected_newobj_of(klass, (flags) & ~FL_WB_PROTECTED) : \
1547 			rb_wb_unprotected_newobj_of(klass, flags))
1548 #define NEWOBJ_OF(obj,type,klass,flags) RB_NEWOBJ_OF(obj,type,klass,flags)
1549 
1550 void *rb_aligned_malloc(size_t, size_t);
1551 void rb_aligned_free(void *);
1552 
1553 /* hash.c */
1554 #if RHASH_CONVERT_TABLE_DEBUG
1555 struct st_table *rb_hash_tbl_raw(VALUE hash, const char *file, int line);
1556 #define RHASH_TBL_RAW(h) rb_hash_tbl_raw(h, __FILE__, __LINE__)
1557 #else
1558 struct st_table *rb_hash_tbl_raw(VALUE hash);
1559 #define RHASH_TBL_RAW(h) rb_hash_tbl_raw(h)
1560 #endif
1561 
1562 VALUE rb_hash_new_with_size(st_index_t size);
1563 RUBY_SYMBOL_EXPORT_BEGIN
1564 VALUE rb_hash_new_compare_by_id(void);
1565 RUBY_SYMBOL_EXPORT_END
1566 VALUE rb_hash_has_key(VALUE hash, VALUE key);
1567 VALUE rb_hash_default_value(VALUE hash, VALUE key);
1568 VALUE rb_hash_set_default_proc(VALUE hash, VALUE proc);
1569 long rb_objid_hash(st_index_t index);
1570 long rb_dbl_long_hash(double d);
1571 st_table *rb_init_identtable(void);
1572 st_table *rb_init_identtable_with_size(st_index_t size);
1573 VALUE rb_hash_compare_by_id_p(VALUE hash);
1574 VALUE rb_to_hash_type(VALUE obj);
1575 VALUE rb_hash_key_str(VALUE);
1576 VALUE rb_hash_keys(VALUE hash);
1577 VALUE rb_hash_values(VALUE hash);
1578 VALUE rb_hash_rehash(VALUE hash);
1579 VALUE rb_hash_resurrect(VALUE hash);
1580 int rb_hash_add_new_element(VALUE hash, VALUE key, VALUE val);
1581 VALUE rb_hash_set_pair(VALUE hash, VALUE pair);
1582 void rb_hash_bulk_insert(long, const VALUE *, VALUE);
1583 
1584 int rb_hash_stlike_lookup(VALUE hash, st_data_t key, st_data_t *pval);
1585 int rb_hash_stlike_delete(VALUE hash, st_data_t *pkey, st_data_t *pval);
1586 int rb_hash_stlike_foreach(VALUE hash, int (*func)(ANYARGS), st_data_t arg);
1587 int rb_hash_stlike_update(VALUE hash, st_data_t key, st_update_callback_func func, st_data_t arg);
1588 
1589 /* inits.c */
1590 void rb_call_inits(void);
1591 
1592 /* io.c */
1593 const char *ruby_get_inplace_mode(void);
1594 void ruby_set_inplace_mode(const char *);
1595 ssize_t rb_io_bufread(VALUE io, void *buf, size_t size);
1596 void rb_stdio_set_default_encoding(void);
1597 VALUE rb_io_flush_raw(VALUE, int);
1598 #ifdef RUBY_IO_H
1599 size_t rb_io_memsize(const rb_io_t *);
1600 #endif
1601 int rb_stderr_tty_p(void);
1602 void rb_io_fptr_finalize_internal(void *ptr);
1603 #define rb_io_fptr_finalize rb_io_fptr_finalize_internal
1604 
1605 /* load.c */
1606 VALUE rb_get_load_path(void);
1607 VALUE rb_get_expanded_load_path(void);
1608 int rb_require_internal(VALUE fname, int safe);
1609 NORETURN(void rb_load_fail(VALUE, const char*));
1610 
1611 /* loadpath.c */
1612 extern const char ruby_exec_prefix[];
1613 extern const char ruby_initial_load_paths[];
1614 
1615 /* localeinit.c */
1616 int Init_enc_set_filesystem_encoding(void);
1617 
1618 /* math.c */
1619 VALUE rb_math_atan2(VALUE, VALUE);
1620 VALUE rb_math_cos(VALUE);
1621 VALUE rb_math_cosh(VALUE);
1622 VALUE rb_math_exp(VALUE);
1623 VALUE rb_math_hypot(VALUE, VALUE);
1624 VALUE rb_math_log(int argc, const VALUE *argv);
1625 VALUE rb_math_sin(VALUE);
1626 VALUE rb_math_sinh(VALUE);
1627 VALUE rb_math_sqrt(VALUE);
1628 
1629 /* mjit.c */
1630 
1631 #if USE_MJIT
1632 extern int mjit_enabled;
1633 VALUE mjit_pause(int wait_p);
1634 VALUE mjit_resume(void);
1635 void mjit_finish(int close_handle_p);
1636 #else
1637 #define mjit_enabled 0
mjit_pause(int wait_p)1638 static inline VALUE mjit_pause(int wait_p){ return Qnil; } /* unreachable */
mjit_resume(void)1639 static inline VALUE mjit_resume(void){ return Qnil; } /* unreachable */
mjit_finish(int close_handle_p)1640 static inline void mjit_finish(int close_handle_p){}
1641 #endif
1642 
1643 /* newline.c */
1644 void Init_newline(void);
1645 
1646 /* numeric.c */
1647 
1648 #define FIXNUM_POSITIVE_P(num) ((SIGNED_VALUE)(num) > (SIGNED_VALUE)INT2FIX(0))
1649 #define FIXNUM_NEGATIVE_P(num) ((SIGNED_VALUE)(num) < 0)
1650 #define FIXNUM_ZERO_P(num) ((num) == INT2FIX(0))
1651 
1652 #define INT_NEGATIVE_P(x) (FIXNUM_P(x) ? FIXNUM_NEGATIVE_P(x) : BIGNUM_NEGATIVE_P(x))
1653 
1654 #ifndef ROUND_DEFAULT
1655 # define ROUND_DEFAULT RUBY_NUM_ROUND_HALF_UP
1656 #endif
1657 enum ruby_num_rounding_mode {
1658     RUBY_NUM_ROUND_HALF_UP,
1659     RUBY_NUM_ROUND_HALF_EVEN,
1660     RUBY_NUM_ROUND_HALF_DOWN,
1661     RUBY_NUM_ROUND_DEFAULT = ROUND_DEFAULT
1662 };
1663 #define ROUND_TO(mode, even, up, down) \
1664     ((mode) == RUBY_NUM_ROUND_HALF_EVEN ? even : \
1665      (mode) == RUBY_NUM_ROUND_HALF_UP ? up : down)
1666 #define ROUND_FUNC(mode, name) \
1667     ROUND_TO(mode, name##_half_even, name##_half_up, name##_half_down)
1668 #define ROUND_CALL(mode, name, args) \
1669     ROUND_TO(mode, name##_half_even args, \
1670 	     name##_half_up args, name##_half_down args)
1671 
1672 int rb_num_to_uint(VALUE val, unsigned int *ret);
1673 VALUE ruby_num_interval_step_size(VALUE from, VALUE to, VALUE step, int excl);
1674 double ruby_float_step_size(double beg, double end, double unit, int excl);
1675 int ruby_float_step(VALUE from, VALUE to, VALUE step, int excl, int allow_endless);
1676 double ruby_float_mod(double x, double y);
1677 int rb_num_negative_p(VALUE);
1678 VALUE rb_int_succ(VALUE num);
1679 VALUE rb_int_pred(VALUE num);
1680 VALUE rb_int_uminus(VALUE num);
1681 VALUE rb_float_uminus(VALUE num);
1682 VALUE rb_int_plus(VALUE x, VALUE y);
1683 VALUE rb_float_plus(VALUE x, VALUE y);
1684 VALUE rb_int_minus(VALUE x, VALUE y);
1685 VALUE rb_float_minus(VALUE x, VALUE y);
1686 VALUE rb_int_mul(VALUE x, VALUE y);
1687 VALUE rb_float_mul(VALUE x, VALUE y);
1688 VALUE rb_int_idiv(VALUE x, VALUE y);
1689 VALUE rb_float_div(VALUE x, VALUE y);
1690 VALUE rb_int_modulo(VALUE x, VALUE y);
1691 VALUE rb_int_round(VALUE num, int ndigits, enum ruby_num_rounding_mode mode);
1692 VALUE rb_int2str(VALUE num, int base);
1693 VALUE rb_dbl_hash(double d);
1694 VALUE rb_fix_plus(VALUE x, VALUE y);
1695 VALUE rb_int_gt(VALUE x, VALUE y);
1696 int rb_float_cmp(VALUE x, VALUE y);
1697 VALUE rb_float_gt(VALUE x, VALUE y);
1698 VALUE rb_int_ge(VALUE x, VALUE y);
1699 enum ruby_num_rounding_mode rb_num_get_rounding_option(VALUE opts);
1700 double rb_int_fdiv_double(VALUE x, VALUE y);
1701 VALUE rb_int_pow(VALUE x, VALUE y);
1702 VALUE rb_float_pow(VALUE x, VALUE y);
1703 VALUE rb_int_cmp(VALUE x, VALUE y);
1704 VALUE rb_int_equal(VALUE x, VALUE y);
1705 VALUE rb_int_divmod(VALUE x, VALUE y);
1706 VALUE rb_int_and(VALUE x, VALUE y);
1707 VALUE rb_int_lshift(VALUE x, VALUE y);
1708 VALUE rb_int_div(VALUE x, VALUE y);
1709 VALUE rb_int_abs(VALUE num);
1710 VALUE rb_int_odd_p(VALUE num);
1711 int rb_int_positive_p(VALUE num);
1712 int rb_int_negative_p(VALUE num);
1713 VALUE rb_num_pow(VALUE x, VALUE y);
1714 VALUE rb_float_floor(VALUE x, int ndigits);
1715 
1716 
1717 static inline VALUE
rb_num_compare_with_zero(VALUE num,ID mid)1718 rb_num_compare_with_zero(VALUE num, ID mid)
1719 {
1720     VALUE zero = INT2FIX(0);
1721     VALUE r = rb_check_funcall(num, mid, 1, &zero);
1722     if (r == Qundef) {
1723 	rb_cmperr(num, zero);
1724     }
1725     return r;
1726 }
1727 
1728 static inline int
rb_num_positive_int_p(VALUE num)1729 rb_num_positive_int_p(VALUE num)
1730 {
1731     const ID mid = '>';
1732 
1733     if (FIXNUM_P(num)) {
1734 	if (rb_method_basic_definition_p(rb_cInteger, mid))
1735 	    return FIXNUM_POSITIVE_P(num);
1736     }
1737     else if (RB_TYPE_P(num, T_BIGNUM)) {
1738 	if (rb_method_basic_definition_p(rb_cInteger, mid))
1739 	    return BIGNUM_POSITIVE_P(num);
1740     }
1741     return RTEST(rb_num_compare_with_zero(num, mid));
1742 }
1743 
1744 
1745 static inline int
rb_num_negative_int_p(VALUE num)1746 rb_num_negative_int_p(VALUE num)
1747 {
1748     const ID mid = '<';
1749 
1750     if (FIXNUM_P(num)) {
1751 	if (rb_method_basic_definition_p(rb_cInteger, mid))
1752 	    return FIXNUM_NEGATIVE_P(num);
1753     }
1754     else if (RB_TYPE_P(num, T_BIGNUM)) {
1755 	if (rb_method_basic_definition_p(rb_cInteger, mid))
1756 	    return BIGNUM_NEGATIVE_P(num);
1757     }
1758     return RTEST(rb_num_compare_with_zero(num, mid));
1759 }
1760 
1761 
1762 VALUE rb_float_abs(VALUE flt);
1763 VALUE rb_float_equal(VALUE x, VALUE y);
1764 VALUE rb_float_eql(VALUE x, VALUE y);
1765 VALUE rb_flo_div_flo(VALUE x, VALUE y);
1766 
1767 #if USE_FLONUM
1768 #define RUBY_BIT_ROTL(v, n) (((v) << (n)) | ((v) >> ((sizeof(v) * 8) - n)))
1769 #define RUBY_BIT_ROTR(v, n) (((v) >> (n)) | ((v) << ((sizeof(v) * 8) - n)))
1770 #endif
1771 
1772 static inline double
rb_float_flonum_value(VALUE v)1773 rb_float_flonum_value(VALUE v)
1774 {
1775 #if USE_FLONUM
1776     if (v != (VALUE)0x8000000000000002) { /* LIKELY */
1777 	union {
1778 	    double d;
1779 	    VALUE v;
1780 	} t;
1781 
1782 	VALUE b63 = (v >> 63);
1783 	/* e: xx1... -> 011... */
1784 	/*    xx0... -> 100... */
1785 	/*      ^b63           */
1786 	t.v = RUBY_BIT_ROTR((2 - b63) | (v & ~(VALUE)0x03), 3);
1787 	return t.d;
1788     }
1789 #endif
1790     return 0.0;
1791 }
1792 
1793 static inline double
rb_float_noflonum_value(VALUE v)1794 rb_float_noflonum_value(VALUE v)
1795 {
1796     return ((struct RFloat *)v)->float_value;
1797 }
1798 
1799 static inline double
rb_float_value_inline(VALUE v)1800 rb_float_value_inline(VALUE v)
1801 {
1802     if (FLONUM_P(v)) {
1803 	return rb_float_flonum_value(v);
1804     }
1805     return rb_float_noflonum_value(v);
1806 }
1807 
1808 static inline VALUE
rb_float_new_inline(double d)1809 rb_float_new_inline(double d)
1810 {
1811 #if USE_FLONUM
1812     union {
1813 	double d;
1814 	VALUE v;
1815     } t;
1816     int bits;
1817 
1818     t.d = d;
1819     bits = (int)((VALUE)(t.v >> 60) & 0x7);
1820     /* bits contains 3 bits of b62..b60. */
1821     /* bits - 3 = */
1822     /*   b011 -> b000 */
1823     /*   b100 -> b001 */
1824 
1825     if (t.v != 0x3000000000000000 /* 1.72723e-77 */ &&
1826 	!((bits-3) & ~0x01)) {
1827 	return (RUBY_BIT_ROTL(t.v, 3) & ~(VALUE)0x01) | 0x02;
1828     }
1829     else if (t.v == (VALUE)0) {
1830 	/* +0.0 */
1831 	return 0x8000000000000002;
1832     }
1833     /* out of range */
1834 #endif
1835     return rb_float_new_in_heap(d);
1836 }
1837 
1838 #define rb_float_value(v) rb_float_value_inline(v)
1839 #define rb_float_new(d)   rb_float_new_inline(d)
1840 
1841 /* object.c */
1842 void rb_obj_copy_ivar(VALUE dest, VALUE obj);
1843 CONSTFUNC(VALUE rb_obj_equal(VALUE obj1, VALUE obj2));
1844 CONSTFUNC(VALUE rb_obj_not(VALUE obj));
1845 VALUE rb_class_search_ancestor(VALUE klass, VALUE super);
1846 NORETURN(void rb_undefined_alloc(VALUE klass));
1847 double rb_num_to_dbl(VALUE val);
1848 VALUE rb_obj_dig(int argc, VALUE *argv, VALUE self, VALUE notfound);
1849 VALUE rb_immutable_obj_clone(int, VALUE *, VALUE);
1850 VALUE rb_obj_not_equal(VALUE obj1, VALUE obj2);
1851 VALUE rb_convert_type_with_id(VALUE,int,const char*,ID);
1852 VALUE rb_check_convert_type_with_id(VALUE,int,const char*,ID);
1853 
1854 struct RBasicRaw {
1855     VALUE flags;
1856     VALUE klass;
1857 };
1858 
1859 #define RBASIC_CLEAR_CLASS(obj)        memset(&(((struct RBasicRaw *)((VALUE)(obj)))->klass), 0, sizeof(VALUE))
1860 #define RBASIC_SET_CLASS_RAW(obj, cls) memcpy(&((struct RBasicRaw *)((VALUE)(obj)))->klass, &(cls), sizeof(VALUE))
1861 #define RBASIC_SET_CLASS(obj, cls)     do { \
1862     VALUE _obj_ = (obj); \
1863     RB_OBJ_WRITE(_obj_, &((struct RBasicRaw *)(_obj_))->klass, cls); \
1864 } while (0)
1865 
1866 /* parse.y */
1867 #ifndef USE_SYMBOL_GC
1868 #define USE_SYMBOL_GC 1
1869 #endif
1870 VALUE rb_parser_get_yydebug(VALUE);
1871 VALUE rb_parser_set_yydebug(VALUE, VALUE);
1872 RUBY_SYMBOL_EXPORT_BEGIN
1873 VALUE rb_parser_set_context(VALUE, const struct rb_block *, int);
1874 RUBY_SYMBOL_EXPORT_END
1875 void *rb_parser_load_file(VALUE parser, VALUE name);
1876 int rb_is_const_name(VALUE name);
1877 int rb_is_class_name(VALUE name);
1878 int rb_is_global_name(VALUE name);
1879 int rb_is_instance_name(VALUE name);
1880 int rb_is_attrset_name(VALUE name);
1881 int rb_is_local_name(VALUE name);
1882 int rb_is_method_name(VALUE name);
1883 int rb_is_junk_name(VALUE name);
1884 PUREFUNC(int rb_is_const_sym(VALUE sym));
1885 PUREFUNC(int rb_is_class_sym(VALUE sym));
1886 PUREFUNC(int rb_is_global_sym(VALUE sym));
1887 PUREFUNC(int rb_is_instance_sym(VALUE sym));
1888 PUREFUNC(int rb_is_attrset_sym(VALUE sym));
1889 PUREFUNC(int rb_is_local_sym(VALUE sym));
1890 PUREFUNC(int rb_is_method_sym(VALUE sym));
1891 PUREFUNC(int rb_is_junk_sym(VALUE sym));
1892 ID rb_make_internal_id(void);
1893 void rb_gc_free_dsymbol(VALUE);
1894 ID rb_id_attrget(ID id);
1895 
1896 /* proc.c */
1897 VALUE rb_proc_location(VALUE self);
1898 st_index_t rb_hash_proc(st_index_t hash, VALUE proc);
1899 int rb_block_arity(void);
1900 int rb_block_min_max_arity(int *max);
1901 VALUE rb_func_proc_new(rb_block_call_func_t func, VALUE val);
1902 VALUE rb_func_lambda_new(rb_block_call_func_t func, VALUE val, int min_argc, int max_argc);
1903 VALUE rb_block_to_s(VALUE self, const struct rb_block *block, const char *additional_info);
1904 
1905 /* process.c */
1906 #define RB_MAX_GROUPS (65536)
1907 
1908 struct waitpid_state;
1909 struct rb_execarg {
1910     union {
1911         struct {
1912             VALUE shell_script;
1913         } sh;
1914         struct {
1915             VALUE command_name;
1916             VALUE command_abspath; /* full path string or nil */
1917             VALUE argv_str;
1918             VALUE argv_buf;
1919         } cmd;
1920     } invoke;
1921     VALUE redirect_fds;
1922     VALUE envp_str;
1923     VALUE envp_buf;
1924     VALUE dup2_tmpbuf;
1925     unsigned use_shell : 1;
1926     unsigned pgroup_given : 1;
1927     unsigned umask_given : 1;
1928     unsigned unsetenv_others_given : 1;
1929     unsigned unsetenv_others_do : 1;
1930     unsigned close_others_given : 1;
1931     unsigned close_others_do : 1;
1932     unsigned chdir_given : 1;
1933     unsigned new_pgroup_given : 1;
1934     unsigned new_pgroup_flag : 1;
1935     unsigned uid_given : 1;
1936     unsigned gid_given : 1;
1937     unsigned exception : 1;
1938     struct waitpid_state *waitpid_state; /* for async process management */
1939     rb_pid_t pgroup_pgid; /* asis(-1), new pgroup(0), specified pgroup (0<V). */
1940     VALUE rlimit_limits; /* Qfalse or [[rtype, softlim, hardlim], ...] */
1941     mode_t umask_mask;
1942     rb_uid_t uid;
1943     rb_gid_t gid;
1944     int close_others_maxhint;
1945     VALUE fd_dup2;
1946     VALUE fd_close;
1947     VALUE fd_open;
1948     VALUE fd_dup2_child;
1949     VALUE env_modification; /* Qfalse or [[k1,v1], ...] */
1950     VALUE path_env;
1951     VALUE chdir_dir;
1952 };
1953 
1954 /* argv_str contains extra two elements.
1955  * The beginning one is for /bin/sh used by exec_with_sh.
1956  * The last one for terminating NULL used by execve.
1957  * See rb_exec_fillarg() in process.c. */
1958 #define ARGVSTR2ARGV(argv_str) ((char **)RB_IMEMO_TMPBUF_PTR(argv_str) + 1)
1959 
1960 static inline size_t
ARGVSTR2ARGC(VALUE argv_str)1961 ARGVSTR2ARGC(VALUE argv_str)
1962 {
1963     size_t i = 0;
1964     char *const *p = ARGVSTR2ARGV(argv_str);
1965     while (p[i++])
1966         ;
1967     return i - 1;
1968 }
1969 
1970 rb_pid_t rb_fork_ruby(int *status);
1971 void rb_last_status_clear(void);
1972 
1973 /* range.c */
1974 #define RANGE_BEG(r) (RSTRUCT(r)->as.ary[0])
1975 #define RANGE_END(r) (RSTRUCT(r)->as.ary[1])
1976 #define RANGE_EXCL(r) (RSTRUCT(r)->as.ary[2])
1977 
1978 /* rational.c */
1979 VALUE rb_rational_canonicalize(VALUE x);
1980 VALUE rb_rational_uminus(VALUE self);
1981 VALUE rb_rational_plus(VALUE self, VALUE other);
1982 VALUE rb_rational_minus(VALUE self, VALUE other);
1983 VALUE rb_rational_mul(VALUE self, VALUE other);
1984 VALUE rb_rational_div(VALUE self, VALUE other);
1985 VALUE rb_lcm(VALUE x, VALUE y);
1986 VALUE rb_rational_reciprocal(VALUE x);
1987 VALUE rb_cstr_to_rat(const char *, int);
1988 VALUE rb_rational_abs(VALUE self);
1989 VALUE rb_rational_cmp(VALUE self, VALUE other);
1990 VALUE rb_rational_pow(VALUE self, VALUE other);
1991 VALUE rb_rational_floor(VALUE self, int ndigits);
1992 VALUE rb_numeric_quo(VALUE x, VALUE y);
1993 
1994 /* re.c */
1995 VALUE rb_reg_compile(VALUE str, int options, const char *sourcefile, int sourceline);
1996 VALUE rb_reg_check_preprocess(VALUE);
1997 long rb_reg_search0(VALUE, VALUE, long, int, int);
1998 VALUE rb_reg_match_p(VALUE re, VALUE str, long pos);
1999 bool rb_reg_start_with_p(VALUE re, VALUE str);
2000 void rb_backref_set_string(VALUE string, long pos, long len);
2001 void rb_match_unbusy(VALUE);
2002 int rb_match_count(VALUE match);
2003 int rb_match_nth_defined(int nth, VALUE match);
2004 VALUE rb_reg_new_ary(VALUE ary, int options);
2005 
2006 /* signal.c */
2007 extern int ruby_enable_coredump;
2008 int rb_get_next_signal(void);
2009 
2010 /* string.c */
2011 VALUE rb_fstring(VALUE);
2012 VALUE rb_fstring_new(const char *ptr, long len);
2013 #define rb_fstring_lit(str) rb_fstring_new((str), rb_strlen_lit(str))
2014 #define rb_fstring_literal(str) rb_fstring_lit(str)
2015 VALUE rb_fstring_cstr(const char *str);
2016 #ifdef HAVE_BUILTIN___BUILTIN_CONSTANT_P
2017 # define rb_fstring_cstr(str) RB_GNUC_EXTENSION_BLOCK(	\
2018     (__builtin_constant_p(str)) ?		\
2019 	rb_fstring_new((str), (long)strlen(str)) : \
2020 	rb_fstring_cstr(str) \
2021 )
2022 #endif
2023 #ifdef RUBY_ENCODING_H
2024 VALUE rb_fstring_enc_new(const char *ptr, long len, rb_encoding *enc);
2025 #define rb_fstring_enc_lit(str, enc) rb_fstring_enc_new((str), rb_strlen_lit(str), (enc))
2026 #define rb_fstring_enc_literal(str, enc) rb_fstring_enc_lit(str, enc)
2027 VALUE rb_fstring_enc_cstr(const char *ptr, rb_encoding *enc);
2028 # ifdef HAVE_BUILTIN___BUILTIN_CONSTANT_P
2029 #  define rb_fstring_enc_cstr(str, enc) RB_GNUC_EXTENSION_BLOCK( \
2030     (__builtin_constant_p(str)) ?		\
2031 	rb_fstring_enc_new((str), (long)strlen(str), (enc)) : \
2032 	rb_fstring_enc_cstr(str, enc) \
2033 )
2034 # endif
2035 #endif
2036 int rb_str_buf_cat_escaped_char(VALUE result, unsigned int c, int unicode_p);
2037 int rb_str_symname_p(VALUE);
2038 VALUE rb_str_quote_unprintable(VALUE);
2039 VALUE rb_id_quote_unprintable(ID);
2040 #define QUOTE(str) rb_str_quote_unprintable(str)
2041 #define QUOTE_ID(id) rb_id_quote_unprintable(id)
2042 char *rb_str_fill_terminator(VALUE str, const int termlen);
2043 void rb_str_change_terminator_length(VALUE str, const int oldtermlen, const int termlen);
2044 VALUE rb_str_locktmp_ensure(VALUE str, VALUE (*func)(VALUE), VALUE arg);
2045 VALUE rb_str_tmp_frozen_acquire(VALUE str);
2046 void rb_str_tmp_frozen_release(VALUE str, VALUE tmp);
2047 VALUE rb_str_chomp_string(VALUE str, VALUE chomp);
2048 #ifdef RUBY_ENCODING_H
2049 VALUE rb_external_str_with_enc(VALUE str, rb_encoding *eenc);
2050 VALUE rb_str_cat_conv_enc_opts(VALUE newstr, long ofs, const char *ptr, long len,
2051 			       rb_encoding *from, int ecflags, VALUE ecopts);
2052 VALUE rb_enc_str_scrub(rb_encoding *enc, VALUE str, VALUE repl);
2053 VALUE rb_str_initialize(VALUE str, const char *ptr, long len, rb_encoding *enc);
2054 #endif
2055 #define STR_NOEMBED      FL_USER1
2056 #define STR_SHARED       FL_USER2 /* = ELTS_SHARED */
2057 #define STR_EMBED_P(str) (!FL_TEST_RAW((str), STR_NOEMBED))
2058 #define STR_SHARED_P(s)  FL_ALL_RAW((s), STR_NOEMBED|ELTS_SHARED)
2059 #define is_ascii_string(str) (rb_enc_str_coderange(str) == ENC_CODERANGE_7BIT)
2060 #define is_broken_string(str) (rb_enc_str_coderange(str) == ENC_CODERANGE_BROKEN)
2061 size_t rb_str_memsize(VALUE);
2062 VALUE rb_sym_proc_call(ID mid, int argc, const VALUE *argv, VALUE passed_proc);
2063 VALUE rb_sym_to_proc(VALUE sym);
2064 char *rb_str_to_cstr(VALUE str);
2065 VALUE rb_str_eql(VALUE str1, VALUE str2);
2066 VALUE rb_obj_as_string_result(VALUE str, VALUE obj);
2067 
2068 /* symbol.c */
2069 #ifdef RUBY_ENCODING_H
2070 VALUE rb_sym_intern(const char *ptr, long len, rb_encoding *enc);
2071 VALUE rb_sym_intern_cstr(const char *ptr, rb_encoding *enc);
2072 #ifdef __GNUC__
2073 #define rb_sym_intern_cstr(ptr, enc) __extension__ ( \
2074 {						\
2075     (__builtin_constant_p(ptr)) ?		\
2076 	rb_sym_intern((ptr), (long)strlen(ptr), (enc)) : \
2077 	rb_sym_intern_cstr((ptr), (enc)); \
2078 })
2079 #endif
2080 #endif
2081 VALUE rb_sym_intern_ascii(const char *ptr, long len);
2082 VALUE rb_sym_intern_ascii_cstr(const char *ptr);
2083 #ifdef __GNUC__
2084 #define rb_sym_intern_ascii_cstr(ptr) __extension__ ( \
2085 {						\
2086     (__builtin_constant_p(ptr)) ?		\
2087 	rb_sym_intern_ascii((ptr), (long)strlen(ptr)) : \
2088 	rb_sym_intern_ascii_cstr(ptr); \
2089 })
2090 #endif
2091 VALUE rb_to_symbol_type(VALUE obj);
2092 
2093 /* struct.c */
2094 VALUE rb_struct_init_copy(VALUE copy, VALUE s);
2095 VALUE rb_struct_lookup(VALUE s, VALUE idx);
2096 VALUE rb_struct_s_keyword_init(VALUE klass);
2097 
2098 /* time.c */
2099 struct timeval rb_time_timeval(VALUE);
2100 
2101 /* thread.c */
2102 #define COVERAGE_INDEX_LINES    0
2103 #define COVERAGE_INDEX_BRANCHES 1
2104 #define COVERAGE_TARGET_LINES    1
2105 #define COVERAGE_TARGET_BRANCHES 2
2106 #define COVERAGE_TARGET_METHODS  4
2107 #define COVERAGE_TARGET_ONESHOT_LINES 8
2108 
2109 VALUE rb_obj_is_mutex(VALUE obj);
2110 VALUE rb_suppress_tracing(VALUE (*func)(VALUE), VALUE arg);
2111 void rb_thread_execute_interrupts(VALUE th);
2112 void rb_clear_trace_func(void);
2113 VALUE rb_get_coverages(void);
2114 int rb_get_coverage_mode(void);
2115 VALUE rb_default_coverage(int);
2116 VALUE rb_thread_shield_new(void);
2117 VALUE rb_thread_shield_wait(VALUE self);
2118 VALUE rb_thread_shield_release(VALUE self);
2119 VALUE rb_thread_shield_destroy(VALUE self);
2120 int rb_thread_to_be_killed(VALUE thread);
2121 void rb_mutex_allow_trap(VALUE self, int val);
2122 VALUE rb_uninterruptible(VALUE (*b_proc)(ANYARGS), VALUE data);
2123 VALUE rb_mutex_owned_p(VALUE self);
2124 
2125 /* transcode.c */
2126 extern VALUE rb_cEncodingConverter;
2127 #ifdef RUBY_ENCODING_H
2128 size_t rb_econv_memsize(rb_econv_t *);
2129 #endif
2130 
2131 /* us_ascii.c */
2132 #ifdef RUBY_ENCODING_H
2133 extern rb_encoding OnigEncodingUS_ASCII;
2134 #endif
2135 
2136 /* util.c */
2137 char *ruby_dtoa(double d_, int mode, int ndigits, int *decpt, int *sign, char **rve);
2138 char *ruby_hdtoa(double d, const char *xdigs, int ndigits, int *decpt, int *sign, char **rve);
2139 
2140 /* utf_8.c */
2141 #ifdef RUBY_ENCODING_H
2142 extern rb_encoding OnigEncodingUTF_8;
2143 #endif
2144 
2145 /* variable.c */
2146 #if USE_TRANSIENT_HEAP
2147 #define ROBJECT_TRANSIENT_FLAG    FL_USER13
2148 #define ROBJ_TRANSIENT_P(obj)     FL_TEST_RAW((obj), ROBJECT_TRANSIENT_FLAG)
2149 #define ROBJ_TRANSIENT_SET(obj)   FL_SET_RAW((obj), ROBJECT_TRANSIENT_FLAG)
2150 #define ROBJ_TRANSIENT_UNSET(obj) FL_UNSET_RAW((obj), ROBJECT_TRANSIENT_FLAG)
2151 #else
2152 #define ROBJ_TRANSIENT_P(obj)     0
2153 #define ROBJ_TRANSIENT_SET(obj)   ((void)0)
2154 #define ROBJ_TRANSIENT_UNSET(obj) ((void)0)
2155 #endif
2156 void rb_gc_mark_global_tbl(void);
2157 size_t rb_generic_ivar_memsize(VALUE);
2158 VALUE rb_search_class_path(VALUE);
2159 VALUE rb_attr_delete(VALUE, ID);
2160 VALUE rb_ivar_lookup(VALUE obj, ID id, VALUE undef);
2161 void rb_autoload_str(VALUE mod, ID id, VALUE file);
2162 void rb_deprecate_constant(VALUE mod, const char *name);
2163 NORETURN(VALUE rb_mod_const_missing(VALUE,VALUE));
2164 rb_gvar_getter_t *rb_gvar_getter_function_of(const struct rb_global_entry *);
2165 rb_gvar_setter_t *rb_gvar_setter_function_of(const struct rb_global_entry *);
2166 bool rb_gvar_is_traced(const struct rb_global_entry *);
2167 
2168 /* vm_insnhelper.h */
2169 rb_serial_t rb_next_class_serial(void);
2170 
2171 /* vm.c */
2172 VALUE rb_obj_is_thread(VALUE obj);
2173 void rb_vm_mark(void *ptr);
2174 void Init_BareVM(void);
2175 void Init_vm_objects(void);
2176 PUREFUNC(VALUE rb_vm_top_self(void));
2177 void rb_thread_recycle_stack_release(VALUE *);
2178 VALUE *rb_thread_recycle_stack(size_t);
2179 void rb_vm_change_state(void);
2180 void rb_vm_inc_const_missing_count(void);
2181 const void **rb_vm_get_insns_address_table(void);
2182 VALUE rb_source_location(int *pline);
2183 const char *rb_source_location_cstr(int *pline);
2184 MJIT_STATIC void rb_vm_pop_cfunc_frame(void);
2185 int rb_vm_add_root_module(ID id, VALUE module);
2186 void rb_vm_check_redefinition_by_prepend(VALUE klass);
2187 VALUE rb_yield_refine_block(VALUE refinement, VALUE refinements);
2188 MJIT_STATIC VALUE ruby_vm_special_exception_copy(VALUE);
2189 PUREFUNC(st_table *rb_vm_fstring_table(void));
2190 
2191 
2192 /* vm_dump.c */
2193 void rb_print_backtrace(void);
2194 
2195 /* vm_eval.c */
2196 void Init_vm_eval(void);
2197 VALUE rb_current_realfilepath(void);
2198 VALUE rb_check_block_call(VALUE, ID, int, const VALUE *, rb_block_call_func_t, VALUE);
2199 typedef void rb_check_funcall_hook(int, VALUE, ID, int, const VALUE *, VALUE);
2200 VALUE rb_check_funcall_with_hook(VALUE recv, ID mid, int argc, const VALUE *argv,
2201 				 rb_check_funcall_hook *hook, VALUE arg);
2202 const char *rb_type_str(enum ruby_value_type type);
2203 VALUE rb_check_funcall_default(VALUE, ID, int, const VALUE *, VALUE);
2204 VALUE rb_yield_1(VALUE val);
2205 VALUE rb_yield_force_blockarg(VALUE values);
2206 VALUE rb_lambda_call(VALUE obj, ID mid, int argc, const VALUE *argv,
2207 		     rb_block_call_func_t bl_proc, int min_argc, int max_argc,
2208 		     VALUE data2);
2209 
2210 /* vm_insnhelper.c */
2211 VALUE rb_equal_opt(VALUE obj1, VALUE obj2);
2212 VALUE rb_eql_opt(VALUE obj1, VALUE obj2);
2213 void Init_vm_stack_canary(void);
2214 
2215 /* vm_method.c */
2216 void Init_eval_method(void);
2217 int rb_method_defined_by(VALUE obj, ID mid, VALUE (*cfunc)(ANYARGS));
2218 
2219 /* miniprelude.c, prelude.c */
2220 void Init_prelude(void);
2221 
2222 /* vm_backtrace.c */
2223 void Init_vm_backtrace(void);
2224 VALUE rb_vm_thread_backtrace(int argc, const VALUE *argv, VALUE thval);
2225 VALUE rb_vm_thread_backtrace_locations(int argc, const VALUE *argv, VALUE thval);
2226 
2227 VALUE rb_make_backtrace(void);
2228 void rb_backtrace_print_as_bugreport(void);
2229 int rb_backtrace_p(VALUE obj);
2230 VALUE rb_backtrace_to_str_ary(VALUE obj);
2231 VALUE rb_backtrace_to_location_ary(VALUE obj);
2232 void rb_backtrace_each(VALUE (*iter)(VALUE recv, VALUE str), VALUE output);
2233 
2234 RUBY_SYMBOL_EXPORT_BEGIN
2235 const char *rb_objspace_data_type_name(VALUE obj);
2236 
2237 /* Temporary.  This API will be removed (renamed). */
2238 VALUE rb_thread_io_blocking_region(rb_blocking_function_t *func, void *data1, int fd);
2239 
2240 /* array.c (export) */
2241 void rb_ary_detransient(VALUE a);
2242 VALUE *rb_ary_ptr_use_start(VALUE ary);
2243 void rb_ary_ptr_use_end(VALUE ary);
2244 
2245 /* bignum.c (export) */
2246 VALUE rb_big_mul_normal(VALUE x, VALUE y);
2247 VALUE rb_big_mul_balance(VALUE x, VALUE y);
2248 VALUE rb_big_mul_karatsuba(VALUE x, VALUE y);
2249 VALUE rb_big_mul_toom3(VALUE x, VALUE y);
2250 VALUE rb_big_sq_fast(VALUE x);
2251 VALUE rb_big_divrem_normal(VALUE x, VALUE y);
2252 VALUE rb_big2str_poweroftwo(VALUE x, int base);
2253 VALUE rb_big2str_generic(VALUE x, int base);
2254 VALUE rb_str2big_poweroftwo(VALUE arg, int base, int badcheck);
2255 VALUE rb_str2big_normal(VALUE arg, int base, int badcheck);
2256 VALUE rb_str2big_karatsuba(VALUE arg, int base, int badcheck);
2257 #if defined(HAVE_LIBGMP) && defined(HAVE_GMP_H)
2258 VALUE rb_big_mul_gmp(VALUE x, VALUE y);
2259 VALUE rb_big_divrem_gmp(VALUE x, VALUE y);
2260 VALUE rb_big2str_gmp(VALUE x, int base);
2261 VALUE rb_str2big_gmp(VALUE arg, int base, int badcheck);
2262 #endif
2263 enum rb_int_parse_flags {
2264     RB_INT_PARSE_SIGN       = 0x01,
2265     RB_INT_PARSE_UNDERSCORE = 0x02,
2266     RB_INT_PARSE_PREFIX     = 0x04,
2267     RB_INT_PARSE_ALL        = 0x07,
2268     RB_INT_PARSE_DEFAULT    = 0x07
2269 };
2270 VALUE rb_int_parse_cstr(const char *str, ssize_t len, char **endp, size_t *ndigits, int base, int flags);
2271 
2272 /* enumerator.c (export) */
2273 VALUE rb_arith_seq_new(VALUE obj, VALUE meth, int argc, VALUE const *argv,
2274                        rb_enumerator_size_func *size_fn,
2275                        VALUE beg, VALUE end, VALUE step, int excl);
2276 
2277 /* error.c (export) */
2278 int rb_bug_reporter_add(void (*func)(FILE *, void *), void *data);
2279 NORETURN(void rb_unexpected_type(VALUE,int));
2280 #undef Check_Type
2281 #define Check_Type(v, t) \
2282     (!RB_TYPE_P((VALUE)(v), (t)) || \
2283      ((t) == RUBY_T_DATA && RTYPEDDATA_P(v)) ? \
2284      rb_unexpected_type((VALUE)(v), (t)) : (void)0)
2285 
2286 static inline int
rb_typeddata_is_instance_of_inline(VALUE obj,const rb_data_type_t * data_type)2287 rb_typeddata_is_instance_of_inline(VALUE obj, const rb_data_type_t *data_type)
2288 {
2289     return RB_TYPE_P(obj, T_DATA) && RTYPEDDATA_P(obj) && (RTYPEDDATA_TYPE(obj) == data_type);
2290 }
2291 #define rb_typeddata_is_instance_of rb_typeddata_is_instance_of_inline
2292 
2293 /* file.c (export) */
2294 #if defined HAVE_READLINK && defined RUBY_ENCODING_H
2295 VALUE rb_readlink(VALUE path, rb_encoding *enc);
2296 #endif
2297 #ifdef __APPLE__
2298 VALUE rb_str_normalize_ospath(const char *ptr, long len);
2299 #endif
2300 
2301 /* hash.c (export) */
2302 VALUE rb_hash_delete_entry(VALUE hash, VALUE key);
2303 VALUE rb_ident_hash_new(void);
2304 
2305 /* io.c (export) */
2306 void rb_maygvl_fd_fix_cloexec(int fd);
2307 int rb_gc_for_fd(int err);
2308 void rb_write_error_str(VALUE mesg);
2309 
2310 /* numeric.c (export) */
2311 VALUE rb_int_positive_pow(long x, unsigned long y);
2312 
2313 #ifdef HAVE_PWD_H
2314 VALUE rb_getlogin(void);
2315 VALUE rb_getpwdirnam_for_login(VALUE login);  /* read as: "get pwd db home dir by username for login" */
2316 VALUE rb_getpwdiruid(void);                   /* read as: "get pwd db home dir for getuid()" */
2317 #endif
2318 
2319 /* process.c (export) */
2320 int rb_exec_async_signal_safe(const struct rb_execarg *e, char *errmsg, size_t errmsg_buflen);
2321 rb_pid_t rb_fork_async_signal_safe(int *status, int (*chfunc)(void*, char *, size_t), void *charg, VALUE fds, char *errmsg, size_t errmsg_buflen);
2322 VALUE rb_execarg_new(int argc, const VALUE *argv, int accept_shell, int allow_exc_opt);
2323 struct rb_execarg *rb_execarg_get(VALUE execarg_obj); /* dangerous.  needs GC guard. */
2324 int rb_execarg_addopt(VALUE execarg_obj, VALUE key, VALUE val);
2325 void rb_execarg_parent_start(VALUE execarg_obj);
2326 void rb_execarg_parent_end(VALUE execarg_obj);
2327 int rb_execarg_run_options(const struct rb_execarg *e, struct rb_execarg *s, char* errmsg, size_t errmsg_buflen);
2328 VALUE rb_execarg_extract_options(VALUE execarg_obj, VALUE opthash);
2329 void rb_execarg_setenv(VALUE execarg_obj, VALUE env);
2330 
2331 /* rational.c (export) */
2332 VALUE rb_gcd(VALUE x, VALUE y);
2333 VALUE rb_gcd_normal(VALUE self, VALUE other);
2334 #if defined(HAVE_LIBGMP) && defined(HAVE_GMP_H)
2335 VALUE rb_gcd_gmp(VALUE x, VALUE y);
2336 #endif
2337 
2338 /* signal.c (export) */
2339 int rb_grantpt(int fd);
2340 
2341 /* string.c (export) */
2342 #ifdef RUBY_ENCODING_H
2343 /* internal use */
2344 VALUE rb_setup_fake_str(struct RString *fake_str, const char *name, long len, rb_encoding *enc);
2345 #endif
2346 VALUE rb_str_upto_each(VALUE, VALUE, int, int (*each)(VALUE, VALUE), VALUE);
2347 VALUE rb_str_upto_endless_each(VALUE, int (*each)(VALUE, VALUE), VALUE);
2348 
2349 /* thread.c (export) */
2350 int ruby_thread_has_gvl_p(void); /* for ext/fiddle/closure.c */
2351 
2352 /* time.c (export) */
2353 void ruby_reset_leap_second_info(void);
2354 
2355 /* util.c (export) */
2356 extern const signed char ruby_digit36_to_number_table[];
2357 extern const char ruby_hexdigits[];
2358 extern unsigned long ruby_scan_digits(const char *str, ssize_t len, int base, size_t *retlen, int *overflow);
2359 
2360 /* variable.c (export) */
2361 void rb_mark_generic_ivar(VALUE);
2362 VALUE rb_const_missing(VALUE klass, VALUE name);
2363 int rb_class_ivar_set(VALUE klass, ID vid, VALUE value);
2364 st_table *rb_st_copy(VALUE obj, struct st_table *orig_tbl);
2365 
2366 /* gc.c (export) */
2367 VALUE rb_wb_protected_newobj_of(VALUE, VALUE);
2368 VALUE rb_wb_unprotected_newobj_of(VALUE, VALUE);
2369 
2370 size_t rb_obj_memsize_of(VALUE);
2371 void rb_gc_verify_internal_consistency(void);
2372 
2373 #define RB_OBJ_GC_FLAGS_MAX 5
2374 size_t rb_obj_gc_flags(VALUE, ID[], size_t);
2375 void rb_gc_mark_values(long n, const VALUE *values);
2376 
2377 #if IMEMO_DEBUG
2378 VALUE rb_imemo_new_debug(enum imemo_type type, VALUE v1, VALUE v2, VALUE v3, VALUE v0, const char *file, int line);
2379 #define rb_imemo_new(type, v1, v2, v3, v0) rb_imemo_new_debug(type, v1, v2, v3, v0, __FILE__, __LINE__)
2380 #else
2381 VALUE rb_imemo_new(enum imemo_type type, VALUE v1, VALUE v2, VALUE v3, VALUE v0);
2382 #endif
2383 
2384 /* random.c */
2385 int ruby_fill_random_bytes(void *, size_t, int);
2386 
2387 RUBY_SYMBOL_EXPORT_END
2388 
2389 #define RUBY_DTRACE_CREATE_HOOK(name, arg) \
2390     RUBY_DTRACE_HOOK(name##_CREATE, arg)
2391 #define RUBY_DTRACE_HOOK(name, arg) \
2392 do { \
2393     if (UNLIKELY(RUBY_DTRACE_##name##_ENABLED())) { \
2394 	int dtrace_line; \
2395 	const char *dtrace_file = rb_source_location_cstr(&dtrace_line); \
2396 	if (!dtrace_file) dtrace_file = ""; \
2397 	RUBY_DTRACE_##name(arg, dtrace_file, dtrace_line); \
2398     } \
2399 } while (0)
2400 
2401 #define RB_OBJ_BUILTIN_TYPE(obj) rb_obj_builtin_type(obj)
2402 #define OBJ_BUILTIN_TYPE(obj) RB_OBJ_BUILTIN_TYPE(obj)
2403 #ifdef __GNUC__
2404 #define rb_obj_builtin_type(obj) \
2405 __extension__({ \
2406     VALUE arg_obj = (obj); \
2407     RB_SPECIAL_CONST_P(arg_obj) ? -1 : \
2408 	RB_BUILTIN_TYPE(arg_obj); \
2409     })
2410 #else
2411 static inline int
2412 rb_obj_builtin_type(VALUE obj)
2413 {
2414     return RB_SPECIAL_CONST_P(obj) ? -1 :
2415 	RB_BUILTIN_TYPE(obj);
2416 }
2417 #endif
2418 
2419 /* A macro for defining a flexible array, like: VALUE ary[FLEX_ARY_LEN]; */
2420 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
2421 # define FLEX_ARY_LEN   /* VALUE ary[]; */
2422 #elif defined(__GNUC__) && !defined(__STRICT_ANSI__)
2423 # define FLEX_ARY_LEN 0 /* VALUE ary[0]; */
2424 #else
2425 # define FLEX_ARY_LEN 1 /* VALUE ary[1]; */
2426 #endif
2427 
2428 /*
2429  * For declaring bitfields out of non-unsigned int types:
2430  *   struct date {
2431  *      BITFIELD(enum months, month, 4);
2432  *      ...
2433  *   };
2434  */
2435 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
2436 # define BITFIELD(type, name, size) type name : size
2437 #else
2438 # define BITFIELD(type, name, size) unsigned int name : size
2439 #endif
2440 
2441 #if defined(_MSC_VER)
2442 # define COMPILER_WARNING_PUSH          __pragma(warning(push))
2443 # define COMPILER_WARNING_POP           __pragma(warning(pop))
2444 # define COMPILER_WARNING_ERROR(flag)   __pragma(warning(error: flag)))
2445 # define COMPILER_WARNING_IGNORED(flag) __pragma(warning(suppress: flag)))
2446 
2447 #elif defined(__clang__) /* clang 2.6 already had this feature */
2448 # define COMPILER_WARNING_PUSH          _Pragma("clang diagnostic push")
2449 # define COMPILER_WARNING_POP           _Pragma("clang diagnostic pop")
2450 # define COMPILER_WARNING_SPECIFIER(kind, msg) \
2451     clang diagnostic kind # msg
2452 # define COMPILER_WARNING_ERROR(flag) \
2453     COMPILER_WARNING_PRAGMA(COMPILER_WARNING_SPECIFIER(error, flag))
2454 # define COMPILER_WARNING_IGNORED(flag) \
2455     COMPILER_WARNING_PRAGMA(COMPILER_WARNING_SPECIFIER(ignored, flag))
2456 
2457 #elif GCC_VERSION_SINCE(4, 2, 0)
2458 /* https://gcc.gnu.org/onlinedocs/gcc-4.2.0/gcc/Diagnostic-Pragmas.html */
2459 # define COMPILER_WARNING_PUSH          _Pragma("GCC diagnostic push")
2460 # define COMPILER_WARNING_POP           _Pragma("GCC diagnostic pop")
2461 # define COMPILER_WARNING_SPECIFIER(kind, msg) \
2462     GCC diagnostic kind # msg
2463 # define COMPILER_WARNING_ERROR(flag) \
2464     COMPILER_WARNING_PRAGMA(COMPILER_WARNING_SPECIFIER(error, flag))
2465 # define COMPILER_WARNING_IGNORED(flag) \
2466     COMPILER_WARNING_PRAGMA(COMPILER_WARNING_SPECIFIER(ignored, flag))
2467 
2468 #else /* other compilers to follow? */
2469 # define COMPILER_WARNING_PUSH          /* nop */
2470 # define COMPILER_WARNING_POP           /* nop */
2471 # define COMPILER_WARNING_ERROR(flag)   /* nop */
2472 # define COMPILER_WARNING_IGNORED(flag) /* nop */
2473 #endif
2474 
2475 #define COMPILER_WARNING_PRAGMA(str) COMPILER_WARNING_PRAGMA_(str)
2476 #define COMPILER_WARNING_PRAGMA_(str) _Pragma(#str)
2477 
2478 #if defined(__cplusplus)
2479 #if 0
2480 { /* satisfy cc-mode */
2481 #endif
2482 }  /* extern "C" { */
2483 #endif
2484 
2485 #endif /* RUBY_INTERNAL_H */
2486