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