14#include "debug_counter.h"
17#include "internal/array.h"
18#include "internal/compar.h"
19#include "internal/enum.h"
20#include "internal/gc.h"
21#include "internal/hash.h"
22#include "internal/numeric.h"
23#include "internal/object.h"
24#include "internal/proc.h"
25#include "internal/rational.h"
26#include "internal/vm.h"
31#include "transient_heap.h"
38#include "ruby_assert.h"
76#define ARY_DEFAULT_SIZE 16
77#define ARY_MAX_SIZE (LONG_MAX / (int)sizeof(VALUE))
78#define SMALL_ARRAY_LEN 16
82should_be_T_ARRAY(
VALUE ary)
87#define ARY_HEAP_PTR(a) (assert(!ARY_EMBED_P(a)), RARRAY(a)->as.heap.ptr)
88#define ARY_HEAP_LEN(a) (assert(!ARY_EMBED_P(a)), RARRAY(a)->as.heap.len)
89#define ARY_HEAP_CAPA(a) (assert(!ARY_EMBED_P(a)), assert(!ARY_SHARED_ROOT_P(a)), \
90 RARRAY(a)->as.heap.aux.capa)
92#define ARY_EMBED_PTR(a) (assert(ARY_EMBED_P(a)), RARRAY(a)->as.ary)
93#define ARY_EMBED_LEN(a) \
94 (assert(ARY_EMBED_P(a)), \
95 (long)((RBASIC(a)->flags >> RARRAY_EMBED_LEN_SHIFT) & \
96 (RARRAY_EMBED_LEN_MASK >> RARRAY_EMBED_LEN_SHIFT)))
97#define ARY_HEAP_SIZE(a) (assert(!ARY_EMBED_P(a)), assert(ARY_OWNS_HEAP_P(a)), ARY_CAPA(a) * sizeof(VALUE))
99#define ARY_OWNS_HEAP_P(a) (assert(should_be_T_ARRAY((VALUE)(a))), \
100 !FL_TEST_RAW((a), RARRAY_SHARED_FLAG|RARRAY_EMBED_FLAG))
102#define FL_SET_EMBED(a) do { \
103 assert(!ARY_SHARED_P(a)); \
104 FL_SET((a), RARRAY_EMBED_FLAG); \
105 RARY_TRANSIENT_UNSET(a); \
109#define FL_UNSET_EMBED(ary) FL_UNSET((ary), RARRAY_EMBED_FLAG|RARRAY_EMBED_LEN_MASK)
110#define FL_SET_SHARED(ary) do { \
111 assert(!ARY_EMBED_P(ary)); \
112 FL_SET((ary), RARRAY_SHARED_FLAG); \
114#define FL_UNSET_SHARED(ary) FL_UNSET((ary), RARRAY_SHARED_FLAG)
116#define ARY_SET_PTR(ary, p) do { \
117 assert(!ARY_EMBED_P(ary)); \
118 assert(!OBJ_FROZEN(ary)); \
119 RARRAY(ary)->as.heap.ptr = (p); \
121#define ARY_SET_EMBED_LEN(ary, n) do { \
123 assert(ARY_EMBED_P(ary)); \
124 RBASIC(ary)->flags &= ~RARRAY_EMBED_LEN_MASK; \
125 RBASIC(ary)->flags |= (tmp_n) << RARRAY_EMBED_LEN_SHIFT; \
127#define ARY_SET_HEAP_LEN(ary, n) do { \
128 assert(!ARY_EMBED_P(ary)); \
129 RARRAY(ary)->as.heap.len = (n); \
131#define ARY_SET_LEN(ary, n) do { \
132 if (ARY_EMBED_P(ary)) { \
133 ARY_SET_EMBED_LEN((ary), (n)); \
136 ARY_SET_HEAP_LEN((ary), (n)); \
138 assert(RARRAY_LEN(ary) == (n)); \
140#define ARY_INCREASE_PTR(ary, n) do { \
141 assert(!ARY_EMBED_P(ary)); \
142 assert(!OBJ_FROZEN(ary)); \
143 RARRAY(ary)->as.heap.ptr += (n); \
145#define ARY_INCREASE_LEN(ary, n) do { \
146 assert(!OBJ_FROZEN(ary)); \
147 if (ARY_EMBED_P(ary)) { \
148 ARY_SET_EMBED_LEN((ary), RARRAY_LEN(ary)+(n)); \
151 RARRAY(ary)->as.heap.len += (n); \
155#define ARY_CAPA(ary) (ARY_EMBED_P(ary) ? ary_embed_capa(ary) : \
156 ARY_SHARED_ROOT_P(ary) ? RARRAY_LEN(ary) : ARY_HEAP_CAPA(ary))
157#define ARY_SET_CAPA(ary, n) do { \
158 assert(!ARY_EMBED_P(ary)); \
159 assert(!ARY_SHARED_P(ary)); \
160 assert(!OBJ_FROZEN(ary)); \
161 RARRAY(ary)->as.heap.aux.capa = (n); \
164#define ARY_SET_SHARED(ary, value) do { \
165 const VALUE _ary_ = (ary); \
166 const VALUE _value_ = (value); \
167 assert(!ARY_EMBED_P(_ary_)); \
168 assert(ARY_SHARED_P(_ary_)); \
169 assert(!OBJ_FROZEN(_ary_)); \
170 assert(ARY_SHARED_ROOT_P(_value_) || OBJ_FROZEN(_value_)); \
171 RB_OBJ_WRITE(_ary_, &RARRAY(_ary_)->as.heap.aux.shared_root, _value_); \
174#define ARY_SHARED_ROOT_OCCUPIED(ary) (!OBJ_FROZEN(ary) && ARY_SHARED_ROOT_REFCNT(ary) == 1)
175#define ARY_SET_SHARED_ROOT_REFCNT(ary, value) do { \
176 assert(ARY_SHARED_ROOT_P(ary)); \
177 assert(!OBJ_FROZEN(ary)); \
178 assert((value) >= 0); \
179 RARRAY(ary)->as.heap.aux.capa = (value); \
181#define FL_SET_SHARED_ROOT(ary) do { \
182 assert(!OBJ_FROZEN(ary)); \
183 assert(!ARY_EMBED_P(ary)); \
184 assert(!RARRAY_TRANSIENT_P(ary)); \
185 FL_SET((ary), RARRAY_SHARED_ROOT_FLAG); \
191 assert(!ARY_SHARED_P(a));
194 RARRAY_ASET(a, i, v);
199ary_embed_capa(
VALUE ary)
202 size_t size = rb_gc_obj_slot_size(ary) - offsetof(
struct RArray, as.
ary);
203 assert(size %
sizeof(
VALUE) == 0);
204 return size /
sizeof(
VALUE);
206 return RARRAY_EMBED_LEN_MAX;
211ary_embed_size(
long capa)
217ary_embeddable_p(
long capa)
220 return rb_gc_size_allocatable_p(ary_embed_size(capa));
222 return capa <= RARRAY_EMBED_LEN_MAX;
227rb_ary_embeddable_p(
VALUE ary)
237 return !(ARY_SHARED_ROOT_P(ary) ||
OBJ_FROZEN(ary) || ARY_SHARED_P(ary));
241rb_ary_size_as_embedded(
VALUE ary)
245 if (ARY_EMBED_P(ary)) {
246 real_size = ary_embed_size(ARY_EMBED_LEN(ary));
248 else if (rb_ary_embeddable_p(ary)) {
249 real_size = ary_embed_size(ARY_HEAP_CAPA(ary));
252 real_size =
sizeof(
struct RArray);
259#define ary_verify(ary) ary_verify_(ary, __FILE__, __LINE__)
262ary_verify_(
VALUE ary,
const char *file,
int line)
266 if (ARY_SHARED_P(
ary)) {
271 assert(ARY_SHARED_ROOT_P(root) ||
OBJ_FROZEN(root));
272 assert(root_ptr <=
ptr &&
ptr +
len <= root_ptr + root_len);
275 else if (ARY_EMBED_P(
ary)) {
276 assert(!RARRAY_TRANSIENT_P(
ary));
277 assert(!ARY_SHARED_P(
ary));
286 for (i=0; i<
len; i++) {
293#if USE_TRANSIENT_HEAP
294 if (RARRAY_TRANSIENT_P(
ary)) {
299 rb_transient_heap_verify();
310#define ary_verify(ary) ((void)0)
339ary_mem_clear(
VALUE ary,
long beg,
long size)
342 rb_mem_clear(
ptr + beg, size);
347memfill(
register VALUE *mem,
register long size,
register VALUE val)
358 memfill(
ptr + beg, size, val);
366 assert(!ARY_SHARED_P(buff_owner_ary));
368 if (argc > (
int)(128/
sizeof(
VALUE)) ) {
369 rb_gc_writebarrier_remember(buff_owner_ary);
377 for (i=0; i<argc; i++) {
387 ary_memcpy0(
ary, beg, argc, argv,
ary);
396 RARY_TRANSIENT_SET(
ary);
399 RARY_TRANSIENT_UNSET(
ary);
409 if (RARRAY_TRANSIENT_P(
ary)) {
413 ruby_sized_xfree((
void *)
ptr, size);
420 if (RARRAY_TRANSIENT_P(
ary)) {
421 RARY_TRANSIENT_UNSET(
ary);
424 ary_heap_free_ptr(
ary, ARY_HEAP_PTR(
ary), ARY_HEAP_SIZE(
ary));
429ary_heap_realloc(
VALUE ary,
size_t new_capa)
431 size_t alloc_capa = new_capa;
432 size_t old_capa = ARY_HEAP_CAPA(
ary);
434 if (RARRAY_TRANSIENT_P(
ary)) {
435 if (new_capa <= old_capa) {
437 alloc_capa = old_capa;
440 VALUE *new_ptr = rb_transient_heap_alloc(
ary,
sizeof(
VALUE) * new_capa);
442 if (new_ptr == NULL) {
444 RARY_TRANSIENT_UNSET(
ary);
448 ARY_SET_PTR(
ary, new_ptr);
459#if USE_TRANSIENT_HEAP
461rb_ary_transient_heap_evacuate_(
VALUE ary,
int transient,
int promote)
464 assert(!ARY_SHARED_ROOT_P(
ary));
467 const VALUE *old_ptr = ARY_HEAP_PTR(
ary);
468 long capa = ARY_HEAP_CAPA(
ary);
470 assert(ARY_OWNS_HEAP_P(
ary));
471 assert(RARRAY_TRANSIENT_P(
ary));
472 assert(!ARY_PTR_USING_P(
ary));
476 RARY_TRANSIENT_UNSET(
ary);
479 new_ptr = ary_heap_alloc(
ary,
capa);
491rb_ary_transient_heap_evacuate(
VALUE ary,
int promote)
493 rb_ary_transient_heap_evacuate_(
ary, RARRAY_TRANSIENT_P(
ary), promote);
499 assert(RARRAY_TRANSIENT_P(
ary));
500 rb_ary_transient_heap_evacuate_(
ary, TRUE, TRUE);
513 assert(rb_ary_embeddable_p(
ary));
514 if (!ARY_EMBED_P(
ary)) {
515 const VALUE *buf = ARY_HEAP_PTR(
ary);
516 long len = ARY_HEAP_LEN(
ary);
517 bool was_transient = RARRAY_TRANSIENT_P(
ary);
521 ARY_SET_EMBED_LEN(
ary,
len);
525 if (!was_transient) {
532ary_resize_capa(
VALUE ary,
long capacity)
536 assert(!ARY_SHARED_P(
ary));
538 if (capacity > ary_embed_capa(
ary)) {
539 size_t new_capa = capacity;
540 if (ARY_EMBED_P(
ary)) {
541 long len = ARY_EMBED_LEN(
ary);
547 ARY_SET_HEAP_LEN(
ary,
len);
550 new_capa = ary_heap_realloc(
ary, capacity);
552 ARY_SET_CAPA(
ary, new_capa);
555 if (!ARY_EMBED_P(
ary)) {
556 long len = ARY_HEAP_LEN(
ary);
557 long old_capa = ARY_HEAP_CAPA(
ary);
560 if (
len > capacity)
len = capacity;
562 ary_heap_free_ptr(
ary,
ptr, old_capa);
575 long capacity = ARY_HEAP_LEN(
ary);
576 long old_capa = ARY_HEAP_CAPA(
ary);
577 assert(!ARY_SHARED_P(
ary));
578 assert(old_capa >= capacity);
579 if (old_capa > capacity) ary_heap_realloc(
ary, capacity);
587 long new_capa = ARY_CAPA(
ary) / 2;
589 if (new_capa < ARY_DEFAULT_SIZE) {
590 new_capa = ARY_DEFAULT_SIZE;
592 if (new_capa >= ARY_MAX_SIZE - min) {
593 new_capa = (ARY_MAX_SIZE - min) / 2;
596 ary_resize_capa(
ary, new_capa);
615 FL_UNSET_SHARED(
ary);
621 if (ARY_OWNS_HEAP_P(
ary)) {
624 else if (ARY_SHARED_P(
ary)) {
629 ARY_SET_EMBED_LEN(
ary, 0);
648 RB_DEBUG_COUNTER_INC(obj_ary_shared_create);
662 if (ARY_SHARED_P(
ary)) {
668 if (
len <= ary_embed_capa(
ary)) {
670 FL_UNSET_SHARED(
ary);
674 ARY_SET_EMBED_LEN(
ary,
len);
678 FL_UNSET_SHARED(
ary);
680 ARY_SET_CAPA(
ary, shared_len);
695 rb_gc_writebarrier_remember(
ary);
703 rb_ary_modify_check(
ary);
704 rb_ary_cancel_sharing(
ary);
708ary_ensure_room_for_push(
VALUE ary,
long add_len)
711 long new_len = old_len + add_len;
714 if (old_len > ARY_MAX_SIZE - add_len) {
717 if (ARY_SHARED_P(
ary)) {
718 if (new_len > ary_embed_capa(
ary)) {
722 rb_ary_modify_check(
ary);
733 ary_double_capa(
ary, new_len);
744 rb_ary_modify_check(
ary);
747 if (new_len >
capa) {
748 ary_double_capa(
ary, new_len);
785 if (!ARY_EMBED_P(ary1) && ARY_SHARED_P(ary1) &&
786 !ARY_EMBED_P(ary2) && ARY_SHARED_P(ary2) &&
787 ARY_SHARED_ROOT(ary1) == ARY_SHARED_ROOT(ary2) &&
788 ARY_HEAP_LEN(ary1) == ARY_HEAP_LEN(ary2)) {
797 size_t size = ary_embed_size(
capa);
798 assert(rb_gc_size_allocatable_p(size));
800 assert(size <=
sizeof(
struct RArray));
802 RVARGC_NEWOBJ_OF(
ary,
struct RArray, klass,
813ary_alloc_heap(
VALUE klass)
815 RVARGC_NEWOBJ_OF(
ary,
struct RArray, klass,
822empty_ary_alloc(
VALUE klass)
824 RUBY_DTRACE_CREATE_HOOK(ARRAY, 0);
825 return ary_alloc_embed(klass, 0);
836 if (
capa > ARY_MAX_SIZE) {
840 RUBY_DTRACE_CREATE_HOOK(ARRAY,
capa);
842 if (ary_embeddable_p(
capa)) {
843 ary = ary_alloc_embed(klass,
capa);
846 ary = ary_alloc_heap(klass);
848 assert(!ARY_EMBED_P(
ary));
852 ARY_SET_HEAP_LEN(
ary, 0);
867 return rb_ary_new_capa(0);
871(rb_ary_new_from_args)(
long n, ...)
880 for (i=0; i<n; i++) {
889MJIT_FUNC_EXPORTED
VALUE
890rb_ary_tmp_new_from_values(
VALUE klass,
long n,
const VALUE *elts)
894 ary = ary_new(klass, n);
896 ary_memcpy(
ary, 0, n, elts);
904rb_ary_new_from_values(
long n,
const VALUE *elts)
906 return rb_ary_tmp_new_from_values(
rb_cArray, n, elts);
912 size_t size = ary_embed_size(
capa);
913 assert(rb_gc_size_allocatable_p(size));
915 assert(size <=
sizeof(
struct RArray));
917 RB_RVARGC_EC_NEWOBJ_OF(ec,
ary,
struct RArray, klass,
930 RB_RVARGC_EC_NEWOBJ_OF(ec,
ary,
struct RArray, klass,
944 if (
capa > ARY_MAX_SIZE) {
948 RUBY_DTRACE_CREATE_HOOK(ARRAY,
capa);
950 if (ary_embeddable_p(
capa)) {
951 ary = ec_ary_alloc_embed(ec, klass,
capa);
954 ary = ec_ary_alloc_heap(ec, klass);
956 assert(!ARY_EMBED_P(
ary));
960 ARY_SET_HEAP_LEN(
ary, 0);
973 ary_memcpy(
ary, 0, n, elts);
984 rb_ary_transient_heap_evacuate(
ary, TRUE);
989rb_ary_hidden_new_fill(
long capa)
1000 if (ARY_OWNS_HEAP_P(
ary)) {
1001 if (USE_DEBUG_COUNTER &&
1002 !ARY_SHARED_ROOT_P(
ary) &&
1004 RB_DEBUG_COUNTER_INC(obj_ary_extracapa);
1007 if (RARRAY_TRANSIENT_P(
ary)) {
1008 RB_DEBUG_COUNTER_INC(obj_ary_transient);
1011 RB_DEBUG_COUNTER_INC(obj_ary_ptr);
1016 RB_DEBUG_COUNTER_INC(obj_ary_embed);
1019 if (ARY_SHARED_P(
ary)) {
1020 RB_DEBUG_COUNTER_INC(obj_ary_shared);
1022 if (ARY_SHARED_ROOT_P(
ary) && ARY_SHARED_ROOT_OCCUPIED(
ary)) {
1023 RB_DEBUG_COUNTER_INC(obj_ary_shared_root_occupied);
1027RUBY_FUNC_EXPORTED
size_t
1030 if (ARY_OWNS_HEAP_P(
ary)) {
1031 return ARY_CAPA(
ary) *
sizeof(
VALUE);
1041 assert(USE_RVARGC || !ARY_EMBED_P(
ary));
1044 if (ARY_SHARED_P(
ary)) {
1045 return ARY_SHARED_ROOT(
ary);
1047 else if (ARY_SHARED_ROOT_P(
ary)) {
1051 if (!ARY_EMBED_P(
ary)) {
1052 rb_ary_transient_heap_evacuate(
ary, TRUE);
1053 ary_shrink_capa(
ary);
1058 rb_ary_transient_heap_evacuate(
ary, TRUE);
1065 VALUE shared = ary_alloc_heap(0);
1066 FL_SET_SHARED_ROOT(shared);
1068 if (ARY_EMBED_P(
ary)) {
1072 ARY_SET_PTR(shared,
ptr);
1073 ary_memcpy(shared, 0,
len, RARRAY_PTR(
ary));
1075 FL_UNSET_EMBED(
ary);
1076 ARY_SET_HEAP_LEN(
ary,
len);
1080 ARY_SET_PTR(shared, RARRAY_PTR(
ary));
1083 ARY_SET_LEN(shared,
capa);
1085 ARY_SET_SHARED_ROOT_REFCNT(shared, 1);
1087 RB_DEBUG_COUNTER_INC(obj_ary_shared_create);
1088 ARY_SET_SHARED(
ary, shared);
1102 if (ary_embeddable_p(
len)) {
1103 VALUE subst = rb_ary_new_capa(
len);
1104 assert(ARY_EMBED_P(subst));
1107 ARY_SET_EMBED_LEN(subst,
len);
1111 return rb_ary_increment_share(ary_make_shared(
ary));
1124 return rb_convert_type_with_id(
ary,
T_ARRAY,
"Array", idTo_ary);
1126#define to_ary rb_to_array_type
1131 return rb_check_convert_type_with_id(
ary,
T_ARRAY,
"Array", idTo_ary);
1134MJIT_FUNC_EXPORTED
VALUE
1137 return rb_check_convert_type_with_id(
ary,
T_ARRAY,
"Array", idTo_a);
1143 return rb_convert_type_with_id(
ary,
T_ARRAY,
"Array", idTo_a);
1163 return rb_check_array_type(
ary);
1168rb_ary_s_new(
int argc,
VALUE *argv,
VALUE klass)
1174 if (argc > 0 &&
FIXNUM_P(argv[0])) {
1176 if (size < 0) size = 0;
1179 ary = ary_new(klass, size);
1247 assert(ARY_EMBED_P(
ary));
1248 assert(ARY_EMBED_LEN(
ary) == 0);
1254 rb_scan_args(argc, argv,
"02", &size, &val);
1255 if (argc == 1 && !
FIXNUM_P(size)) {
1256 val = rb_check_array_type(size);
1258 rb_ary_replace(
ary, val);
1268 if (
len > ARY_MAX_SIZE) {
1273 ary_resize_capa(
ary,
len);
1278 rb_warn(
"block supersedes default value argument");
1280 for (i=0; i<
len; i++) {
1282 ARY_SET_LEN(
ary, i + 1);
1286 ary_memfill(
ary, 0,
len, val);
1301rb_ary_s_create(
int argc,
VALUE *argv,
VALUE klass)
1304 if (argc > 0 && argv) {
1305 ary_memcpy(
ary, 0, argc, argv);
1306 ARY_SET_LEN(
ary, argc);
1324 else if (idx >= ARY_MAX_SIZE) {
1329 if (idx >= ARY_CAPA(
ary)) {
1330 ary_double_capa(
ary, idx);
1337 ARY_SET_LEN(
ary, idx + 1);
1339 ARY_SET(
ary, idx, val);
1345 assert(offset >= 0);
1349 const size_t rarray_embed_capa_max = (
sizeof(
struct RArray) - offsetof(struct
RArray,
as.
ary)) / sizeof(
VALUE);
1351 if ((
size_t)
len <= rarray_embed_capa_max && ary_embeddable_p(
len)) {
1352 VALUE result = ary_alloc_embed(klass,
len);
1354 ARY_SET_EMBED_LEN(result,
len);
1358 VALUE shared = ary_make_shared(
ary);
1360 VALUE result = ary_alloc_heap(klass);
1361 assert(!ARY_EMBED_P(result));
1365 rb_ary_set_shared(result, shared);
1367 ARY_INCREASE_PTR(result, offset);
1368 ARY_SET_LEN(result,
len);
1377ary_make_partial_step(
VALUE ary,
VALUE klass,
long offset,
long len,
long step)
1379 assert(offset >= 0);
1385 const long orig_len =
len;
1387 if (step > 0 && step >=
len) {
1388 VALUE result = ary_new(klass, 1);
1391 ARY_SET_EMBED_LEN(result, 1);
1394 else if (step < 0 && step < -
len) {
1398 long ustep = (step < 0) ? -step : step;
1399 len = roomof(
len, ustep);
1402 long j = offset + ((step > 0) ? 0 : (orig_len - 1));
1404 VALUE result = ary_new(klass,
len);
1405 if (ARY_EMBED_P(result)) {
1407 for (i = 0; i <
len; ++i) {
1411 ARY_SET_EMBED_LEN(result,
len);
1415 for (i = 0; i <
len; ++i) {
1420 ARY_SET_LEN(result,
len);
1432enum ary_take_pos_flags
1439ary_take_first_or_last(
int argc,
const VALUE *argv,
VALUE ary,
enum ary_take_pos_flags last)
1445 argc = rb_check_arity(argc, 0, 1);
1486 VALUE target_ary = ary_ensure_room_for_push(
ary, 1);
1490 ARY_SET_LEN(
ary, idx + 1);
1499 VALUE target_ary = ary_ensure_room_for_push(
ary,
len);
1500 ary_memcpy0(
ary, oldlen,
len, argv, target_ary);
1501 ARY_SET_LEN(
ary, oldlen +
len);
1530 return rb_ary_cat(
ary, argv, argc);
1537 rb_ary_modify_check(
ary);
1539 if (n == 0)
return Qnil;
1540 if (ARY_OWNS_HEAP_P(
ary) &&
1541 n * 3 < ARY_CAPA(
ary) &&
1542 ARY_CAPA(
ary) > ARY_DEFAULT_SIZE)
1544 ary_resize_capa(
ary, n * 2);
1547 ARY_SET_LEN(
ary, n);
1589 return rb_ary_pop(
ary);
1592 rb_ary_modify_check(
ary);
1593 result = ary_take_first_or_last(argc, argv,
ary, ARY_TAKE_LAST);
1606 rb_ary_modify_check(
ary);
1612 rb_ary_behead(
ary, 1);
1657 return rb_ary_shift(
ary);
1660 rb_ary_modify_check(
ary);
1661 result = ary_take_first_or_last(argc, argv,
ary, ARY_TAKE_FIRST);
1663 rb_ary_behead(
ary,n);
1668MJIT_FUNC_EXPORTED
VALUE
1675 rb_ary_modify_check(
ary);
1677 if (!ARY_SHARED_P(
ary)) {
1682 ARY_INCREASE_LEN(
ary, -n);
1687 ary_mem_clear(
ary, 0, n);
1688 ary_make_shared(
ary);
1690 else if (ARY_SHARED_ROOT_OCCUPIED(ARY_SHARED_ROOT(
ary))) {
1691 ary_mem_clear(
ary, 0, n);
1694 ARY_INCREASE_PTR(
ary, n);
1695 ARY_INCREASE_LEN(
ary, -n);
1704 if (head - sharedp < argc) {
1705 long room =
capa -
len - argc;
1709 head = sharedp + argc + room;
1711 ARY_SET_PTR(
ary, head - argc);
1712 assert(ARY_SHARED_ROOT_OCCUPIED(ARY_SHARED_ROOT(
ary)));
1715 return ARY_SHARED_ROOT(
ary);
1719ary_modify_for_unshift(
VALUE ary,
int argc)
1722 long new_len =
len + argc;
1724 const VALUE *head, *sharedp;
1728 if (
capa - (
capa >> 6) <= new_len) {
1729 ary_double_capa(
ary, new_len);
1733 if (new_len > ARY_DEFAULT_SIZE * 4 && !ARY_EMBED_P(
ary)) {
1738 ary_make_shared(
ary);
1741 return make_room_for_unshift(
ary, head, (
void *)sharedp, argc,
capa,
len);
1755ary_ensure_room_for_unshift(
VALUE ary,
int argc)
1758 long new_len =
len + argc;
1760 if (
len > ARY_MAX_SIZE - argc) {
1763 else if (! ARY_SHARED_P(
ary)) {
1764 return ary_modify_for_unshift(
ary, argc);
1771 return ary_modify_for_unshift(
ary, argc);
1773 else if (new_len >
capa) {
1774 return ary_modify_for_unshift(
ary, argc);
1780 rb_ary_modify_check(
ary);
1781 return make_room_for_unshift(
ary, head, sharedp, argc,
capa,
len);
1807 rb_ary_modify_check(
ary);
1811 target_ary = ary_ensure_room_for_unshift(
ary, argc);
1812 ary_memcpy0(
ary, 0, argc, argv, target_ary);
1813 ARY_SET_LEN(
ary,
len + argc);
1820 return rb_ary_unshift_m(1,&item,
ary);
1829 if (offset < 0 ||
len <= offset) {
1838 return rb_ary_entry_internal(
ary, offset);
1842rb_ary_subseq_step(
VALUE ary,
long beg,
long len,
long step)
1847 if (beg > alen)
return Qnil;
1848 if (beg < 0 ||
len < 0)
return Qnil;
1850 if (alen <
len || alen < beg +
len) {
1854 if (
len == 0)
return ary_new(klass, 0);
1858 return ary_make_partial(
ary, klass, beg,
len);
1860 return ary_make_partial_step(
ary, klass, beg,
len, step);
1866 return rb_ary_subseq_step(
ary, beg,
len, 1);
1979 rb_check_arity(argc, 1, 2);
1981 return rb_ary_aref2(
ary, argv[0], argv[1]);
1983 return rb_ary_aref1(
ary, argv[0]);
1994 return rb_ary_subseq(
ary, beg,
len);
1997MJIT_FUNC_EXPORTED
VALUE
2000 long beg,
len, step;
2007 switch (rb_arithmetic_sequence_beg_len_step(arg, &beg, &
len, &step,
RARRAY_LEN(
ary), 0)) {
2013 return rb_ary_subseq_step(
ary, beg,
len, step);
2077 return ary_take_first_or_last(argc, argv,
ary, ARY_TAKE_FIRST);
2124 return ary_take_first_or_last(argc, argv,
ary, ARY_TAKE_LAST);
2172 rb_scan_args(argc, argv,
"11", &pos, &ifnone);
2174 if (block_given && argc == 2) {
2175 rb_warn(
"block supersedes default value argument");
2183 if (block_given)
return rb_yield(pos);
2246 rb_check_arity(argc, 0, 1);
2249 rb_warn(
"given block not used");
2309 rb_check_arity(argc, 0, 1);
2312 rb_warn(
"given block not used");
2328 VALUE tmp = rb_check_array_type(obj);
2330 if (!
NIL_P(tmp))
return tmp;
2349 if (olen <
len || olen < beg +
len) {
2355 rofs = (rptr >= optr && rptr < optr + olen) ? rptr - optr : -1;
2360 if (beg > ARY_MAX_SIZE - rlen) {
2363 target_ary = ary_ensure_room_for_push(
ary, rlen-
len);
2365 ary_mem_clear(
ary, olen, beg - olen);
2368 ary_memcpy0(
ary, beg, rlen, rptr, target_ary);
2375 if (olen -
len > ARY_MAX_SIZE - rlen) {
2379 alen = olen + rlen -
len;
2380 if (alen >= ARY_CAPA(
ary)) {
2381 ary_double_capa(
ary, alen);
2388 ARY_SET_LEN(
ary, alen);
2409 rb_ary_modify_check(
ary);
2410 if (ARY_SHARED_P(
ary)) {
2426 if (
len == olen)
return ary;
2427 if (
len > ARY_MAX_SIZE) {
2431 if (
len >= ARY_CAPA(
ary)) {
2432 ary_double_capa(
ary,
len);
2434 ary_mem_clear(
ary, olen,
len - olen);
2437 else if (ARY_EMBED_P(
ary)) {
2438 ARY_SET_EMBED_LEN(
ary,
len);
2440 else if (
len <= ary_embed_capa(
ary)) {
2442 long ptr_capa = ARY_HEAP_SIZE(
ary);
2443 bool is_malloc_ptr = !ARY_SHARED_P(
ary) && !RARRAY_TRANSIENT_P(
ary);
2449 ARY_SET_EMBED_LEN(
ary,
len);
2451 if (is_malloc_ptr) ruby_sized_xfree((
void *)
ptr, ptr_capa);
2454 if (olen >
len + ARY_DEFAULT_SIZE) {
2455 size_t new_capa = ary_heap_realloc(
ary,
len);
2456 ARY_SET_CAPA(
ary, new_capa);
2458 ARY_SET_HEAP_LEN(
ary,
len);
2467 rb_ary_store(
ary, key, val);
2474 VALUE rpl = rb_ary_to_ary(val);
2597 long offset, beg,
len;
2599 rb_check_arity(argc, 2, 3);
2600 rb_ary_modify_check(
ary);
2604 return ary_aset_by_rb_ary_splice(
ary, beg,
len, argv[2]);
2608 return ary_aset_by_rb_ary_store(
ary, offset, argv[1]);
2612 return ary_aset_by_rb_ary_splice(
ary, beg,
len, argv[1]);
2616 return ary_aset_by_rb_ary_store(
ary, offset, argv[1]);
2661 rb_ary_modify_check(
ary);
2663 if (argc == 1)
return ary;
2675 rb_ary_splice(
ary, pos, 0, argv + 1, argc - 1);
2685 return rb_ary_length(
ary);
2899 ARY_SET_LEN(dup,
len);
2912extern VALUE rb_output_fs;
2917recursive_join(
VALUE obj,
VALUE argp,
int recur)
2922 VALUE result = arg[2];
2923 int *first = (
int *)arg[3];
2929 ary_join_1(obj,
ary, sep, 0, result, first);
2941 for (i=0; i<max; i++) {
2943 if (!RB_TYPE_P(val,
T_STRING))
break;
2944 if (i > 0 && !
NIL_P(sep))
2952ary_join_1_str(
VALUE dst,
VALUE src,
int *first)
2956 rb_enc_copy(dst, src);
2974 args[3] = (
VALUE)first;
2985 if (i > 0 && !
NIL_P(sep))
2990 ary_join_1_str(result, val, first);
2992 else if (RB_TYPE_P(val,
T_ARRAY)) {
2993 ary_join_1_ary(val,
ary, sep, result, val, first);
2996 ary_join_1_str(result, tmp, first);
2998 else if (!
NIL_P(tmp = rb_check_array_type(val))) {
2999 ary_join_1_ary(val,
ary, sep, result, tmp, first);
3011 VALUE val, tmp, result;
3023 if (
NIL_P(tmp) || tmp != val) {
3028 rb_enc_associate(result, rb_usascii_encoding());
3029 i = ary_join_0(
ary, sep, i, result);
3031 ary_join_1(
ary,
ary, sep, i, result, &first);
3035 len += RSTRING_LEN(tmp);
3079 if (rb_check_arity(argc, 0, 1) == 0 ||
NIL_P(sep = argv[0])) {
3086 return rb_ary_join(
ary, sep);
3100 else rb_enc_copy(str, s);
3130 return rb_ary_inspect(
ary);
3159 rb_ary_replace(dup,
ary);
3198 const VALUE e = rb_ary_elt(
ary, i);
3199 const VALUE elt = block_given ? rb_yield_force_blockarg(e) : e;
3200 const VALUE key_value_pair = rb_check_array_type(elt);
3201 if (
NIL_P(key_value_pair)) {
3247 ary_reverse(p1, p2);
3267 return rb_ary_reverse(
ary);
3291 do *p2-- = *p1++;
while (--
len > 0);
3298rotate_count(
long cnt,
long len)
3300 return (cnt < 0) ? (
len - (~cnt %
len) - 1) : (cnt %
len);
3311 else if (cnt ==
len - 1) {
3319 if (--cnt > 0) ary_reverse(
ptr,
ptr + cnt);
3331 if (
len > 1 && (cnt = rotate_count(cnt,
len)) > 0) {
3388 long n = (rb_check_arity(argc, 0, 1) ?
NUM2LONG(argv[0]) : 1);
3389 rb_ary_rotate(
ary, n);
3448 long cnt = (rb_check_arity(argc, 0, 1) ?
NUM2LONG(argv[0]) : 1);
3453 cnt = rotate_count(cnt,
len);
3456 ary_memcpy(rotated, 0,
len,
ptr + cnt);
3457 ary_memcpy(rotated,
len, cnt,
ptr);
3469sort_reentered(
VALUE ary)
3471 if (
RBASIC(ary)->klass) {
3483 sort_reentered(data->ary);
3487sort_1(
const void *ap,
const void *bp,
void *dummy)
3490 VALUE retval = sort_reentered(data->ary);
3498 n = rb_cmpint(retval, a, b);
3499 sort_returned(data);
3504sort_2(
const void *ap,
const void *bp,
void *dummy)
3507 VALUE retval = sort_reentered(data->ary);
3512 if ((
long)a > (long)b)
return 1;
3513 if ((
long)a < (long)b)
return -1;
3516 if (STRING_P(a) && STRING_P(b) && CMP_OPTIMIZABLE(STRING)) {
3519 if (RB_FLOAT_TYPE_P(a) && CMP_OPTIMIZABLE(FLOAT)) {
3520 return rb_float_cmp(a, b);
3523 retval = rb_funcallv(a, id_cmp, 1, &b);
3524 n = rb_cmpint(retval, a, b);
3525 sort_returned(data);
3575 assert(!ARY_SHARED_P(ary));
3577 VALUE tmp = ary_make_substitution(ary);
3580 RBASIC_CLEAR_CLASS(tmp);
3582 data.receiver = ary;
3588 if (ARY_EMBED_P(tmp)) {
3589 if (ARY_SHARED_P(ary)) {
3590 rb_ary_unshare(ary);
3593 ary_memcpy(ary, 0, ARY_EMBED_LEN(tmp), ARY_EMBED_PTR(tmp));
3594 ARY_SET_LEN(ary, ARY_EMBED_LEN(tmp));
3597 if (!ARY_EMBED_P(ary) && ARY_HEAP_PTR(ary) == ARY_HEAP_PTR(tmp)) {
3598 FL_UNSET_SHARED(ary);
3602 assert(!ARY_SHARED_P(tmp));
3603 if (ARY_EMBED_P(ary)) {
3604 FL_UNSET_EMBED(ary);
3606 else if (ARY_SHARED_P(ary)) {
3608 rb_ary_unshare(ary);
3613 ARY_SET_PTR(ary, ARY_HEAP_PTR(tmp));
3614 ARY_SET_HEAP_LEN(ary, len);
3615 ARY_SET_CAPA(ary, ARY_HEAP_LEN(tmp));
3620 ARY_SET_EMBED_LEN(tmp, 0);
3675 ary = rb_ary_dup(ary);
3676 rb_ary_sort_bang(ary);
3693rb_ary_bsearch(
VALUE ary)
3695 VALUE index_result = rb_ary_bsearch_index(ary);
3698 return rb_ary_entry(ary,
FIX2LONG(index_result));
3700 return index_result;
3713rb_ary_bsearch_index(
VALUE ary)
3716 int smaller = 0, satisfied = 0;
3720 while (low < high) {
3721 mid = low + ((high - low) / 2);
3722 val = rb_ary_entry(ary, mid);
3728 else if (v ==
Qtrue) {
3732 else if (!
RTEST(v)) {
3737 switch (rb_cmpint(rb_funcallv(v, id_cmp, 1, &zero), v, zero)) {
3739 case 1: smaller = 1;
break;
3740 case -1: smaller = 0;
3745 " (must be numeric, true, false or nil)",
3755 if (!satisfied)
return Qnil;
3793rb_ary_sort_by_bang(
VALUE ary)
3799 sorted =
rb_block_call(ary, rb_intern(
"sort_by"), 0, 0, sort_by_i, 0);
3800 rb_ary_replace(ary, sorted);
3826rb_ary_collect(
VALUE ary)
3861rb_ary_collect_bang(
VALUE ary)
3874rb_get_values_at(
VALUE obj,
long olen,
int argc,
const VALUE *argv,
VALUE (*func) (
VALUE,
long))
3877 long beg, len, i, j;
3879 for (i=0; i<argc; i++) {
3881 rb_ary_push(result, (*func)(obj,
FIX2LONG(argv[i])));
3886 long end = olen < beg+len ? olen : beg+len;
3887 for (j = beg; j < end; j++) {
3888 rb_ary_push(result, (*func)(obj, j));
3891 rb_ary_resize(result,
RARRAY_LEN(result) + (beg + len) - j);
3894 rb_ary_push(result, (*func)(obj,
NUM2LONG(argv[i])));
3910 const long end = beg + len;
3913 rb_ary_cat(result, src + beg, end > olen ? olen-beg : len);
3916 rb_ary_store(result, prevlen + len - 1,
Qnil);
3924 return rb_ary_push(result, rb_ary_entry(ary, beg));
3971rb_ary_values_at(
int argc,
VALUE *argv,
VALUE ary)
3974 VALUE result = rb_ary_new_capa(argc);
3975 for (i = 0; i < argc; ++i) {
3976 append_values_at_single(result, ary, olen, argv[i]);
4005rb_ary_select(
VALUE ary)
4014 rb_ary_push(result, rb_ary_elt(ary, i));
4026select_bang_i(
VALUE a)
4029 VALUE ary = arg->ary;
4032 for (i1 = i2 = 0; i1 <
RARRAY_LEN(ary); arg->len[0] = ++i1) {
4036 rb_ary_store(ary, i2, v);
4040 return (i1 == i2) ?
Qnil : ary;
4044select_bang_ensure(
VALUE a)
4047 VALUE ary = arg->ary;
4049 long i1 = arg->len[0], i2 = arg->len[1];
4051 if (i2 < len && i2 < i1) {
4060 ARY_SET_LEN(ary, i2 + tail);
4089rb_ary_select_bang(
VALUE ary)
4097 args.len[0] = args.len[1] = 0;
4120rb_ary_keep_if(
VALUE ary)
4123 rb_ary_select_bang(ary);
4128ary_resize_smaller(
VALUE ary,
long len)
4132 ARY_SET_LEN(ary, len);
4133 if (len * 2 < ARY_CAPA(ary) &&
4134 ARY_CAPA(ary) > ARY_DEFAULT_SIZE) {
4135 ary_resize_capa(ary, len * 2);
4182 for (i1 = i2 = 0; i1 <
RARRAY_LEN(ary); i1++) {
4190 rb_ary_store(ary, i2, e);
4201 ary_resize_smaller(ary, i2);
4212 for (i1 = i2 = 0; i1 <
RARRAY_LEN(ary); i1++) {
4219 rb_ary_store(ary, i2, e);
4227 ary_resize_smaller(ary, i2);
4236 if (pos >= len)
return Qnil;
4239 if (pos < 0)
return Qnil;
4247 ARY_INCREASE_LEN(ary, -1);
4278 return rb_ary_delete_at(ary,
NUM2LONG(pos));
4282ary_slice_bang_by_rb_ary_splice(
VALUE ary,
long pos,
long len)
4289 else if (pos < -orig_len) {
4295 else if (orig_len < pos) {
4298 if (orig_len < pos + len) {
4299 len = orig_len - pos;
4306 rb_ary_splice(ary, pos, len, 0, 0);
4381rb_ary_slice_bang(
int argc,
VALUE *argv,
VALUE ary)
4386 rb_ary_modify_check(ary);
4387 rb_check_arity(argc, 1, 2);
4393 return ary_slice_bang_by_rb_ary_splice(ary, pos, len);
4400 return ary_slice_bang_by_rb_ary_splice(ary, pos, len);
4410 return rb_ary_delete_at(ary,
NUM2LONG(arg1));
4422 rb_ary_push(result, v);
4429reject_bang_i(
VALUE a)
4432 VALUE ary = arg->ary;
4435 for (i1 = i2 = 0; i1 <
RARRAY_LEN(ary); arg->len[0] = ++i1) {
4439 rb_ary_store(ary, i2, v);
4443 return (i1 == i2) ?
Qnil : ary;
4447ary_reject_bang(
VALUE ary)
4450 rb_ary_modify_check(ary);
4452 args.len[0] = args.len[1] = 0;
4478rb_ary_reject_bang(
VALUE ary)
4482 return ary_reject_bang(ary);
4505rb_ary_reject(
VALUE ary)
4510 rejected_ary = rb_ary_new();
4511 ary_reject(ary, rejected_ary);
4512 return rejected_ary;
4534rb_ary_delete_if(
VALUE ary)
4538 ary_reject_bang(ary);
4547 rb_ary_push(args[0], val);
4553take_items(
VALUE obj,
long n)
4555 VALUE result = rb_check_array_type(obj);
4558 if (n == 0)
return result;
4559 if (!
NIL_P(result))
return rb_ary_subseq(result, 0, n);
4561 args[0] = result; args[1] = (
VALUE)n;
4562 if (UNDEF_P(rb_check_block_call(obj, idEach, 0, 0, take_i, (
VALUE)args)))
4632 for (i=0; i<argc; i++) {
4633 argv[i] = take_items(argv[i], len);
4637 int arity = rb_block_arity();
4646 for (j=0; j<argc; j++) {
4647 tmp[j+1] = rb_ary_elt(argv[j], i);
4659 for (j=0; j<argc; j++) {
4660 rb_ary_push(tmp, rb_ary_elt(argv[j], i));
4667 result = rb_ary_new_capa(len);
4669 for (i=0; i<len; i++) {
4670 VALUE tmp = rb_ary_new_capa(argc+1);
4673 for (j=0; j<argc; j++) {
4674 rb_ary_push(tmp, rb_ary_elt(argv[j], i));
4676 rb_ary_push(result, tmp);
4696rb_ary_transpose(
VALUE ary)
4698 long elen = -1, alen, i, j;
4699 VALUE tmp, result = 0;
4702 if (alen == 0)
return rb_ary_dup(ary);
4703 for (i=0; i<alen; i++) {
4704 tmp = to_ary(rb_ary_elt(ary, i));
4708 for (j=0; j<elen; j++) {
4716 for (j=0; j<elen; j++) {
4717 rb_ary_store(rb_ary_elt(result, j), i, rb_ary_elt(tmp, j));
4737 rb_ary_modify_check(copy);
4738 orig = to_ary(orig);
4739 if (copy == orig)
return copy;
4744 if (
RARRAY_LEN(orig) <= ary_embed_capa(copy)) {
4745 assert(ARY_EMBED_P(copy));
4752 else if (ARY_EMBED_P(orig)) {
4753 long len = ARY_EMBED_LEN(orig);
4754 VALUE *ptr = ary_heap_alloc(copy, len);
4756 FL_UNSET_EMBED(copy);
4757 ARY_SET_PTR(copy, ptr);
4758 ARY_SET_LEN(copy, len);
4759 ARY_SET_CAPA(copy, len);
4769 VALUE shared_root = ary_make_shared(orig);
4770 FL_UNSET_EMBED(copy);
4771 ARY_SET_PTR(copy, ARY_HEAP_PTR(orig));
4772 ARY_SET_LEN(copy, ARY_HEAP_LEN(orig));
4773 rb_ary_set_shared(copy, shared_root);
4793 rb_ary_modify_check(ary);
4794 if (ARY_SHARED_P(ary)) {
4795 if (!ARY_EMBED_P(ary)) {
4796 rb_ary_unshare(ary);
4798 ARY_SET_EMBED_LEN(ary, 0);
4802 ARY_SET_LEN(ary, 0);
4803 if (ARY_DEFAULT_SIZE * 2 < ARY_CAPA(ary)) {
4804 ary_resize_capa(ary, ARY_DEFAULT_SIZE * 2);
5011 long beg = 0, end = 0, len = 0;
5014 rb_scan_args(argc, argv,
"02", &arg1, &arg2);
5018 rb_scan_args(argc, argv,
"12", &item, &arg1, &arg2);
5034 if (beg < 0) beg = 0;
5043 if (beg >= ARY_MAX_SIZE || len > ARY_MAX_SIZE - beg) {
5048 if (end >= ARY_CAPA(ary)) {
5049 ary_resize_capa(ary, end);
5052 ARY_SET_LEN(ary, end);
5055 if (UNDEF_P(item)) {
5059 for (i=beg; i<end; i++) {
5066 ary_memfill(ary, beg, len, item);
5088 long len, xlen, ylen;
5098 ARY_SET_LEN(z, len);
5124rb_ary_concat_multi(
int argc,
VALUE *argv,
VALUE ary)
5126 rb_ary_modify_check(ary);
5129 rb_ary_concat(ary, argv[0]);
5131 else if (argc > 1) {
5133 VALUE args = rb_ary_hidden_new(argc);
5134 for (i = 0; i < argc; i++) {
5135 rb_ary_concat(args, argv[i]);
5137 ary_append(ary, args);
5147 return ary_append(x, to_ary(y));
5177 return rb_ary_join(ary, tmp);
5194 ARY_SET_LEN(ary2, len);
5199 ary_memcpy(ary2, 0, t, ptr);
5200 while (t <= len/2) {
5274recursive_equal(
VALUE ary1,
VALUE ary2,
int recur)
5277 const VALUE *p1, *p2;
5279 if (recur)
return Qtrue;
5286 for (i = 0; i < len1; i++) {
5328 if (ary1 == ary2)
return Qtrue;
5329 if (!RB_TYPE_P(ary2,
T_ARRAY)) {
5341recursive_eql(
VALUE ary1,
VALUE ary2,
int recur)
5345 if (recur)
return Qtrue;
5347 if (!
rb_eql(rb_ary_elt(ary1, i), rb_ary_elt(ary2, i)))
5373 if (ary1 == ary2)
return Qtrue;
5394rb_ary_hash(
VALUE ary)
5452recursive_cmp(
VALUE ary1,
VALUE ary2,
int recur)
5456 if (recur)
return Qundef;
5461 for (i=0; i<len; i++) {
5462 VALUE e1 = rb_ary_elt(ary1, i), e2 = rb_ary_elt(ary2, i);
5463 VALUE v = rb_funcallv(e1, id_cmp, 1, &e2);
5508 ary2 = rb_check_array_type(ary2);
5510 if (ary1 == ary2)
return INT2FIX(0);
5512 if (!UNDEF_P(v))
return v;
5514 if (len == 0)
return INT2FIX(0);
5515 if (len > 0)
return INT2FIX(1);
5526 rb_hash_add_new_element(hash, elt, elt);
5532ary_tmp_hash_new(
VALUE ary)
5535 VALUE hash = rb_hash_new_with_size(size);
5537 RBASIC_CLEAR_CLASS(hash);
5542ary_make_hash(
VALUE ary)
5544 VALUE hash = ary_tmp_hash_new(ary);
5545 return ary_add_hash(hash, ary);
5555 rb_hash_add_new_element(hash, k, v);
5561ary_make_hash_by(
VALUE ary)
5563 VALUE hash = ary_tmp_hash_new(ary);
5564 return ary_add_hash_by(hash, ary);
5568ary_recycle_hash(
VALUE hash)
5570 assert(RBASIC_CLASS(hash) == 0);
5571 if (RHASH_ST_TABLE_P(hash)) {
5572 st_table *tbl = RHASH_ST_TABLE(hash);
5574 RHASH_ST_CLEAR(hash);
5601 ary2 = to_ary(ary2);
5602 if (
RARRAY_LEN(ary2) == 0) {
return ary_make_shared_copy(ary1); }
5603 ary3 = rb_ary_new();
5607 VALUE elt = rb_ary_elt(ary1, i);
5608 if (rb_ary_includes_by_eql(ary2, elt))
continue;
5609 rb_ary_push(ary3, elt);
5614 hash = ary_make_hash(ary2);
5616 if (rb_hash_stlike_lookup(hash,
RARRAY_AREF(ary1, i), NULL))
continue;
5617 rb_ary_push(ary3, rb_ary_elt(ary1, i));
5619 ary_recycle_hash(hash);
5641rb_ary_difference_multi(
int argc,
VALUE *argv,
VALUE ary)
5646 bool *is_hash =
ALLOCV_N(
bool, t0, argc);
5647 ary_diff = rb_ary_new();
5650 for (i = 0; i < argc; i++) {
5651 argv[i] = to_ary(argv[i]);
5652 is_hash[i] = (length > SMALL_ARRAY_LEN &&
RARRAY_LEN(argv[i]) > SMALL_ARRAY_LEN);
5653 if (is_hash[i]) argv[i] = ary_make_hash(argv[i]);
5658 VALUE elt = rb_ary_elt(ary, i);
5659 for (j = 0; j < argc; j++) {
5661 if (rb_hash_stlike_lookup(argv[j],
RARRAY_AREF(ary, i), NULL))
5665 if (rb_ary_includes_by_eql(argv[j], elt))
break;
5668 if (j == argc) rb_ary_push(ary_diff, elt);
5698 VALUE hash, ary3, v;
5702 ary2 = to_ary(ary2);
5703 ary3 = rb_ary_new();
5709 if (!rb_ary_includes_by_eql(ary2, v))
continue;
5710 if (rb_ary_includes_by_eql(ary3, v))
continue;
5711 rb_ary_push(ary3, v);
5716 hash = ary_make_hash(ary2);
5721 if (rb_hash_stlike_delete(hash, &vv, 0)) {
5722 rb_ary_push(ary3, v);
5725 ary_recycle_hash(hash);
5751rb_ary_intersection_multi(
int argc,
VALUE *argv,
VALUE ary)
5753 VALUE result = rb_ary_dup(ary);
5756 for (i = 0; i < argc; i++) {
5757 result = rb_ary_and(result, argv[i]);
5764ary_hash_orset(st_data_t *key, st_data_t *value, st_data_t arg,
int existing)
5766 if (existing)
return ST_STOP;
5767 *key = *value = (
VALUE)arg;
5776 VALUE elt = rb_ary_elt(ary, i);
5777 if (rb_ary_includes_by_eql(ary_union, elt))
continue;
5778 rb_ary_push(ary_union, elt);
5788 if (!rb_hash_stlike_update(hash, (st_data_t)elt, ary_hash_orset, (st_data_t)elt)) {
5814 ary2 = to_ary(ary2);
5816 ary3 = rb_ary_new();
5817 rb_ary_union(ary3, ary1);
5818 rb_ary_union(ary3, ary2);
5822 hash = ary_make_hash(ary1);
5823 rb_ary_union_hash(hash, ary2);
5825 ary3 = rb_hash_values(hash);
5826 ary_recycle_hash(hash);
5847rb_ary_union_multi(
int argc,
VALUE *argv,
VALUE ary)
5851 VALUE hash, ary_union;
5854 for (i = 0; i < argc; i++) {
5855 argv[i] = to_ary(argv[i]);
5859 if (sum <= SMALL_ARRAY_LEN) {
5860 ary_union = rb_ary_new();
5862 rb_ary_union(ary_union, ary);
5863 for (i = 0; i < argc; i++) rb_ary_union(ary_union, argv[i]);
5868 hash = ary_make_hash(ary);
5869 for (i = 0; i < argc; i++) rb_ary_union_hash(hash, argv[i]);
5871 ary_union = rb_hash_values(hash);
5872 ary_recycle_hash(hash);
5894 VALUE hash, v, result, shorter, longer;
5898 ary2 = to_ary(ary2);
5904 if (rb_ary_includes_by_eql(ary2, v))
return Qtrue;
5916 hash = ary_make_hash(shorter);
5922 if (rb_hash_stlike_lookup(hash, vv, 0)) {
5927 ary_recycle_hash(hash);
5933ary_max_generic(
VALUE ary,
long i,
VALUE vmax)
5941 if (rb_cmpint(rb_funcallv(vmax, id_cmp, 1, &v), vmax, v) < 0) {
5950ary_max_opt_fixnum(
VALUE ary,
long i,
VALUE vmax)
5957 for (; i < n; ++i) {
5961 if ((
long)vmax < (
long)v) {
5966 return ary_max_generic(ary, i, vmax);
5974ary_max_opt_float(
VALUE ary,
long i,
VALUE vmax)
5981 for (; i < n; ++i) {
5984 if (RB_FLOAT_TYPE_P(v)) {
5985 if (rb_float_cmp(vmax, v) < 0) {
5990 return ary_max_generic(ary, i, vmax);
5998ary_max_opt_string(
VALUE ary,
long i,
VALUE vmax)
6005 for (; i < n; ++i) {
6014 return ary_max_generic(ary, i, vmax);
6067 if (rb_check_arity(argc, 0, 1) && !
NIL_P(num = argv[0]))
6068 return rb_nmin_run(ary, num, 0, 1, 1);
6074 if (UNDEF_P(result) || rb_cmpint(rb_yield_values(2, v, result), v, result) > 0) {
6082 if (
FIXNUM_P(result) && CMP_OPTIMIZABLE(INTEGER)) {
6083 return ary_max_opt_fixnum(ary, 1, result);
6085 else if (STRING_P(result) && CMP_OPTIMIZABLE(STRING)) {
6086 return ary_max_opt_string(ary, 1, result);
6088 else if (RB_FLOAT_TYPE_P(result) && CMP_OPTIMIZABLE(FLOAT)) {
6089 return ary_max_opt_float(ary, 1, result);
6092 return ary_max_generic(ary, 1, result);
6096 if (UNDEF_P(result))
return Qnil;
6101ary_min_generic(
VALUE ary,
long i,
VALUE vmin)
6109 if (rb_cmpint(rb_funcallv(vmin, id_cmp, 1, &v), vmin, v) > 0) {
6118ary_min_opt_fixnum(
VALUE ary,
long i,
VALUE vmin)
6125 for (; i < n; ++i) {
6129 if ((
long)vmin > (
long)a) {
6134 return ary_min_generic(ary, i, vmin);
6142ary_min_opt_float(
VALUE ary,
long i,
VALUE vmin)
6149 for (; i < n; ++i) {
6152 if (RB_FLOAT_TYPE_P(a)) {
6153 if (rb_float_cmp(vmin, a) > 0) {
6158 return ary_min_generic(ary, i, vmin);
6166ary_min_opt_string(
VALUE ary,
long i,
VALUE vmin)
6173 for (; i < n; ++i) {
6182 return ary_min_generic(ary, i, vmin);
6235 if (rb_check_arity(argc, 0, 1) && !
NIL_P(num = argv[0]))
6236 return rb_nmin_run(ary, num, 0, 0, 1);
6242 if (UNDEF_P(result) || rb_cmpint(rb_yield_values(2, v, result), v, result) < 0) {
6250 if (
FIXNUM_P(result) && CMP_OPTIMIZABLE(INTEGER)) {
6251 return ary_min_opt_fixnum(ary, 1, result);
6253 else if (STRING_P(result) && CMP_OPTIMIZABLE(STRING)) {
6254 return ary_min_opt_string(ary, 1, result);
6256 else if (RB_FLOAT_TYPE_P(result) && CMP_OPTIMIZABLE(FLOAT)) {
6257 return ary_min_opt_float(ary, 1, result);
6260 return ary_min_generic(ary, 1, result);
6264 if (UNDEF_P(result))
return Qnil;
6292rb_ary_minmax(
VALUE ary)
6297 return rb_assoc_new(rb_ary_min(0, 0, ary), rb_ary_max(0, 0, ary));
6301push_value(st_data_t key, st_data_t val, st_data_t ary)
6337rb_ary_uniq_bang(
VALUE ary)
6342 rb_ary_modify_check(ary);
6346 hash = ary_make_hash_by(ary);
6348 hash = ary_make_hash(ary);
6354 rb_ary_modify_check(ary);
6355 ARY_SET_LEN(ary, 0);
6356 if (ARY_SHARED_P(ary) && !ARY_EMBED_P(ary)) {
6357 rb_ary_unshare(ary);
6360 ary_resize_capa(ary, hash_size);
6361 rb_hash_foreach(hash, push_value, ary);
6362 ary_recycle_hash(hash);
6391rb_ary_uniq(
VALUE ary)
6397 uniq = rb_ary_dup(ary);
6400 hash = ary_make_hash_by(ary);
6401 uniq = rb_hash_values(hash);
6404 hash = ary_make_hash(ary);
6405 uniq = rb_hash_values(hash);
6408 ary_recycle_hash(hash);
6424rb_ary_compact_bang(
VALUE ary)
6441 ary_resize_smaller(ary, n);
6457rb_ary_compact(
VALUE ary)
6459 ary = rb_ary_dup(ary);
6460 rb_ary_compact_bang(ary);
6492rb_ary_count(
int argc,
VALUE *argv,
VALUE ary)
6496 if (rb_check_arity(argc, 0, 1) == 0) {
6508 VALUE obj = argv[0];
6511 rb_warn(
"given block not used");
6522flatten(
VALUE ary,
int level)
6525 VALUE stack, result, tmp = 0, elt, vmemo;
6531 tmp = rb_check_array_type(elt);
6542 ARY_SET_LEN(result, i);
6544 stack = ary_new(0, ARY_DEFAULT_SIZE);
6545 rb_ary_push(stack, ary);
6546 rb_ary_push(stack,
LONG2NUM(i + 1));
6549 vmemo = rb_hash_new();
6550 RBASIC_CLEAR_CLASS(vmemo);
6551 memo = st_init_numtable();
6552 rb_hash_st_table_set(vmemo, memo);
6553 st_insert(memo, (st_data_t)ary, (st_data_t)
Qtrue);
6554 st_insert(memo, (st_data_t)tmp, (st_data_t)
Qtrue);
6563 if (level >= 0 &&
RARRAY_LEN(stack) / 2 >= level) {
6564 rb_ary_push(result, elt);
6567 tmp = rb_check_array_type(elt);
6568 if (
RBASIC(result)->klass) {
6576 rb_ary_push(result, elt);
6580 id = (st_data_t)tmp;
6581 if (st_is_member(memo,
id)) {
6585 st_insert(memo,
id, (st_data_t)
Qtrue);
6587 rb_ary_push(stack, ary);
6597 id = (st_data_t)ary;
6598 st_delete(memo, &
id, 0);
6600 tmp = rb_ary_pop(stack);
6602 ary = rb_ary_pop(stack);
6645rb_ary_flatten_bang(
int argc,
VALUE *argv,
VALUE ary)
6647 int mod = 0, level = -1;
6650 lv = (rb_check_arity(argc, 0, 1) ? argv[0] :
Qnil);
6651 rb_ary_modify_check(ary);
6653 if (level == 0)
return Qnil;
6655 result = flatten(ary, level);
6656 if (result == ary) {
6660 rb_ary_replace(ary, result);
6661 if (mod) ARY_SET_EMBED_LEN(result, 0);
6700rb_ary_flatten(
int argc,
VALUE *argv,
VALUE ary)
6705 if (rb_check_arity(argc, 0, 1) && !
NIL_P(argv[0])) {
6707 if (level == 0)
return ary_make_shared_copy(ary);
6710 result = flatten(ary, level);
6711 if (result == ary) {
6712 result = ary_make_shared_copy(ary);
6718#define RAND_UPTO(max) (long)rb_random_ulong_limited((randgen), (max)-1)
6729 long j = RAND_UPTO(i);
6745 ary = rb_ary_dup(ary);
6746 rb_ary_shuffle_bang(ec, ary, randgen);
6754 long n, len, i, j, k, idx[10];
6755 long rnds[numberof(idx)];
6756 long memo_threshold;
6765 return rb_ary_elt(ary, i);
6769 if (n > len) n = len;
6770 if (n <= numberof(idx)) {
6771 for (i = 0; i < n; ++i) {
6772 rnds[i] = RAND_UPTO(len - i);
6777 if (len < k && n <= numberof(idx)) {
6778 for (i = 0; i < n; ++i) {
6779 if (rnds[i] >= len)
return rb_ary_new_capa(0);
6782 if (n > len) n = len;
6785 return rb_ary_new_capa(0);
6788 return rb_ary_new_from_args(1,
RARRAY_AREF(ary, i));
6800 if (j >= i) l = i, g = ++j;
6801 if (k >= l && (++k >= g)) ++k;
6806 len < 2560 ? len / 128 :
6807 len < 5120 ? len / 64 :
6808 len < 10240 ? len / 32 :
6810 if (n <= numberof(idx)) {
6811 long sorted[numberof(idx)];
6812 sorted[0] = idx[0] = rnds[0];
6813 for (i=1; i<n; i++) {
6815 for (j = 0; j < i; ++j) {
6816 if (k < sorted[j])
break;
6819 memmove(&sorted[j+1], &sorted[j],
sizeof(sorted[0])*(i-j));
6820 sorted[j] = idx[i] = k;
6822 result = rb_ary_new_capa(n);
6824 for (i=0; i<n; i++) {
6829 else if (n <= memo_threshold / 2) {
6831#undef RUBY_UNTYPED_DATA_WARNING
6832#define RUBY_UNTYPED_DATA_WARNING 0
6834 st_table *memo = st_init_numtable_with_size(n);
6836 result = rb_ary_new_capa(n);
6838 for (i=0; i<n; i++) {
6839 long r = RAND_UPTO(len-i) + i;
6841 if (r > max_idx) max_idx = r;
6844 if (len <= max_idx) n = 0;
6845 else if (n > len) n = len;
6847 for (i=0; i<n; i++) {
6848 long j2 = j = ptr_result[i];
6851 if (st_lookup(memo, (st_data_t)i, &value)) i2 = (
long)value;
6852 if (st_lookup(memo, (st_data_t)j, &value)) j2 = (
long)value;
6853 st_insert(memo, (st_data_t)j, (st_data_t)i2);
6854 ptr_result[i] = ptr_ary[j2];
6859 st_free_table(memo);
6862 result = rb_ary_dup(ary);
6863 RBASIC_CLEAR_CLASS(result);
6866 for (i=0; i<n; i++) {
6867 j = RAND_UPTO(len-i) + i;
6869 ptr_result[j] = ptr_result[i];
6873 RBASIC_SET_CLASS_RAW(result,
rb_cArray);
6875 ARY_SET_LEN(result, n);
6897 if (mul <= 0)
return INT2FIX(0);
6899 return rb_fix_mul_fix(rb_ary_length(self), n);
6936rb_ary_cycle(
int argc,
VALUE *argv,
VALUE ary)
6940 rb_check_arity(argc, 0, 1);
6943 if (argc == 0 ||
NIL_P(argv[0])) {
6948 if (n <= 0)
return Qnil;
6951 while (
RARRAY_LEN(ary) > 0 && (n < 0 || 0 < n--)) {
6965yield_indexed_values(
const VALUE values,
const long r,
const long *
const p)
6970 for (i = 0; i < r; i++) ARY_SET(result, i,
RARRAY_AREF(values, p[i]));
6971 ARY_SET_LEN(result, r);
6973 return !
RBASIC(values)->klass;
6989permute0(
const long n,
const long r,
long *
const p,
char *
const used,
const VALUE values)
6991 long i = 0, index = 0;
6994 const char *
const unused = memchr(&used[i], 0, n-i);
7009 for (i = 0; i < n; ++i) {
7010 if (used[i])
continue;
7012 if (!yield_indexed_values(values, r, p)) {
7028descending_factorial(
long from,
long how_many)
7033 while (--how_many > 0) {
7035 cnt = rb_int_mul(cnt,
LONG2FIX(v));
7045binomial_coefficient(
long comb,
long size)
7049 if (comb > size-comb) {
7055 else if (comb == 0) {
7059 for (i = 1; i < comb; ++i) {
7060 r = rb_int_mul(r,
LONG2FIX(size - i));
7061 r = rb_int_idiv(r,
LONG2FIX(i + 1));
7072 return descending_factorial(n, k);
7156rb_ary_permutation(
int argc,
VALUE *argv,
VALUE ary)
7163 if (rb_check_arity(argc, 0, 1) && !
NIL_P(argv[0]))
7166 if (r < 0 || n < r) {
7179 long *p =
ALLOCV_N(
long, t0, r+roomof(n,
sizeof(
long)));
7180 char *used = (
char*)(p + r);
7181 VALUE ary0 = ary_make_shared_copy(ary);
7182 RBASIC_CLEAR_CLASS(ary0);
7186 permute0(n, r, p, used, ary0);
7194combinate0(
const long len,
const long n,
long *
const stack,
const VALUE values)
7201 for (lev++; lev < n; lev++) {
7202 stack[lev+1] = stack[lev]+1;
7204 if (!yield_indexed_values(values, n, stack+1)) {
7208 if (lev == 0)
return;
7210 }
while (stack[lev+1]+n == len+lev+1);
7220 return binomial_coefficient(k, n);
7285 if (n < 0 || len < n) {
7297 VALUE ary0 = ary_make_shared_copy(ary);
7299 long *stack =
ALLOCV_N(
long, t0, n+1);
7301 RBASIC_CLEAR_CLASS(ary0);
7302 combinate0(len, n, stack, ary0);
7322rpermute0(
const long n,
const long r,
long *
const p,
const VALUE values)
7324 long i = 0, index = 0;
7328 if (++index < r-1) {
7332 for (i = 0; i < n; ++i) {
7334 if (!yield_indexed_values(values, r, p)) {
7339 if (index <= 0)
return;
7340 }
while ((i = ++p[--index]) >= n);
7425rb_ary_repeated_permutation(
VALUE ary,
VALUE num)
7447 VALUE ary0 = ary_make_shared_copy(ary);
7448 RBASIC_CLEAR_CLASS(ary0);
7450 rpermute0(n, r, p, ary0);
7458rcombinate0(
const long n,
const long r,
long *
const p,
const long rest,
const VALUE values)
7460 long i = 0, index = 0;
7464 if (++index < r-1) {
7468 for (; i < n; ++i) {
7470 if (!yield_indexed_values(values, r, p)) {
7475 if (index <= 0)
return;
7476 }
while ((i = ++p[--index]) >= n);
7488 return binomial_coefficient(k, n + k - 1);
7555rb_ary_repeated_combination(
VALUE ary,
VALUE num)
7573 else if (len == 0) {
7579 VALUE ary0 = ary_make_shared_copy(ary);
7580 RBASIC_CLEAR_CLASS(ary0);
7582 rcombinate0(len, n, p, n, ary0);
7650rb_ary_product(
int argc,
VALUE *argv,
VALUE ary)
7653 volatile VALUE t0 = rb_ary_hidden_new(n);
7655 VALUE *arrays = RARRAY_PTR(t0);
7656 int *counters =
ALLOCV_N(
int, t1, n);
7661 RBASIC_CLEAR_CLASS(t0);
7666 for (i = 1; i < n; i++) arrays[i] =
Qnil;
7667 for (i = 1; i < n; i++) arrays[i] = to_ary(argv[i-1]);
7670 for (i = 0; i < n; i++) counters[i] = 0;
7675 for (i = 0; i < n; i++) {
7677 arrays[i] = ary_make_shared_copy(arrays[i]);
7682 for (i = 0; i < n; i++) {
7688 if (MUL_OVERFLOW_LONG_P(resultlen, k))
7698 for (j = 0; j < n; j++) {
7699 rb_ary_push(subarray, rb_ary_entry(arrays[j], counters[j]));
7703 if (
NIL_P(result)) {
7704 FL_SET(t0, RARRAY_SHARED_ROOT_FLAG);
7706 if (!
FL_TEST(t0, RARRAY_SHARED_ROOT_FLAG)) {
7710 FL_UNSET(t0, RARRAY_SHARED_ROOT_FLAG);
7714 rb_ary_push(result, subarray);
7723 while (counters[m] ==
RARRAY_LEN(arrays[m])) {
7726 if (--m < 0)
goto done;
7734 return NIL_P(result) ? ary : result;
7762 return rb_ary_subseq(obj, 0, len);
7789rb_ary_take_while(
VALUE ary)
7797 return rb_ary_take(ary,
LONG2FIX(i));
7826 result = rb_ary_subseq(ary, pos,
RARRAY_LEN(ary));
7827 if (
NIL_P(result)) result = rb_ary_new();
7853rb_ary_drop_while(
VALUE ary)
7861 return rb_ary_drop(ary,
LONG2FIX(i));
7898rb_ary_any_p(
int argc,
VALUE *argv,
VALUE ary)
7902 rb_check_arity(argc, 0, 1);
7906 rb_warn(
"given block not used");
7913 for (i = 0; i < len; ++i) {
7958rb_ary_all_p(
int argc,
VALUE *argv,
VALUE ary)
7962 rb_check_arity(argc, 0, 1);
7963 if (!len)
return Qtrue;
7966 rb_warn(
"given block not used");
7973 for (i = 0; i < len; ++i) {
8018rb_ary_none_p(
int argc,
VALUE *argv,
VALUE ary)
8022 rb_check_arity(argc, 0, 1);
8023 if (!len)
return Qtrue;
8026 rb_warn(
"given block not used");
8033 for (i = 0; i < len; ++i) {
8082rb_ary_one_p(
int argc,
VALUE *argv,
VALUE ary)
8087 rb_check_arity(argc, 0, 1);
8091 rb_warn(
"given block not used");
8095 if (result)
return Qfalse;
8101 for (i = 0; i < len; ++i) {
8103 if (result)
return Qfalse;
8111 if (result)
return Qfalse;
8142 self = rb_ary_at(self, *argv);
8143 if (!--argc)
return self;
8145 return rb_obj_dig(argc, argv, self,
Qnil);
8149finish_exact_sum(
long n,
VALUE r,
VALUE v,
int z)
8154 v = rb_rational_plus(r, v);
8209 v = (rb_check_arity(argc, 0, 1) ? argv[0] :
LONG2FIX(0));
8229 else if (RB_BIGNUM_TYPE_P(e))
8230 v = rb_big_plus(e, v);
8235 r = rb_rational_plus(r, e);
8240 v = finish_exact_sum(n, r, v, argc!=0);
8244 v = finish_exact_sum(n, r, v, i!=0);
8246 if (RB_FLOAT_TYPE_P(e)) {
8256 goto has_float_value;
8261 if (RB_FLOAT_TYPE_P(e))
8266 else if (RB_BIGNUM_TYPE_P(e))
8273 if (isnan(f))
continue;
8279 if (isinf(f) && signbit(x) != signbit(f))
8285 if (isinf(f))
continue;
8288 if (fabs(f) >= fabs(x))
8301 goto has_some_value;
8307 v = rb_funcall(v, idPLUS, 1, e);
8313rb_ary_deconstruct(
VALUE ary)
8941#include "array.rbinc"
#define RUBY_ASSERT(expr)
Asserts that the given expression is truthy if and only if RUBY_DEBUG is truthy.
#define RUBY_ASSERT_ALWAYS(expr)
A variant of RUBY_ASSERT that does not interface with RUBY_DEBUG.
#define rb_define_method(klass, mid, func, arity)
Defines klass#mid.
#define rb_define_singleton_method(klass, mid, func, arity)
Defines klass.mid.
void rb_include_module(VALUE klass, VALUE module)
Includes a module to a class.
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
int rb_block_given_p(void)
Determines if the current method is given a block.
#define FL_UNSET_RAW
Old name of RB_FL_UNSET_RAW.
#define rb_str_buf_cat2
Old name of rb_usascii_str_new_cstr.
#define RFLOAT_VALUE
Old name of rb_float_value.
#define T_STRING
Old name of RUBY_T_STRING.
#define Qundef
Old name of RUBY_Qundef.
#define INT2FIX
Old name of RB_INT2FIX.
#define OBJ_FROZEN
Old name of RB_OBJ_FROZEN.
#define rb_str_buf_new2
Old name of rb_str_buf_new_cstr.
#define rb_ary_new4
Old name of rb_ary_new_from_values.
#define FIXABLE
Old name of RB_FIXABLE.
#define LONG2FIX
Old name of RB_INT2FIX.
#define T_RATIONAL
Old name of RUBY_T_RATIONAL.
#define ALLOC_N
Old name of RB_ALLOC_N.
#define NUM2DBL
Old name of rb_num2dbl.
#define FL_SET
Old name of RB_FL_SET.
#define rb_ary_new3
Old name of rb_ary_new_from_args.
#define LONG2NUM
Old name of RB_LONG2NUM.
#define rb_usascii_str_new2
Old name of rb_usascii_str_new_cstr.
#define Qtrue
Old name of RUBY_Qtrue.
#define ST2FIX
Old name of RB_ST2FIX.
#define NUM2INT
Old name of RB_NUM2INT.
#define Qnil
Old name of RUBY_Qnil.
#define Qfalse
Old name of RUBY_Qfalse.
#define FIX2LONG
Old name of RB_FIX2LONG.
#define T_ARRAY
Old name of RUBY_T_ARRAY.
#define NIL_P
Old name of RB_NIL_P.
#define ALLOCV_N
Old name of RB_ALLOCV_N.
#define FL_WB_PROTECTED
Old name of RUBY_FL_WB_PROTECTED.
#define DBL2NUM
Old name of rb_float_new.
#define FL_TEST
Old name of RB_FL_TEST.
#define FL_FREEZE
Old name of RUBY_FL_FREEZE.
#define NUM2LONG
Old name of RB_NUM2LONG.
#define FL_UNSET
Old name of RB_FL_UNSET.
#define FIXNUM_P
Old name of RB_FIXNUM_P.
#define rb_ary_new2
Old name of rb_ary_new_capa.
#define FL_SET_RAW
Old name of RB_FL_SET_RAW.
#define ALLOCV_END
Old name of RB_ALLOCV_END.
void rb_category_warn(rb_warning_category_t category, const char *fmt,...)
Identical to rb_category_warning(), except it reports always regardless of runtime -W flag.
void rb_raise(VALUE exc, const char *fmt,...)
Exception entry point.
void rb_bug(const char *fmt,...)
Interpreter panic switch.
void rb_iter_break(void)
Breaks from a block.
VALUE rb_eFrozenError
FrozenError exception.
VALUE rb_eRangeError
RangeError exception.
VALUE rb_eTypeError
TypeError exception.
VALUE rb_eRuntimeError
RuntimeError exception.
void rb_warn(const char *fmt,...)
Identical to rb_warning(), except it reports always regardless of runtime -W flag.
VALUE rb_eArgError
ArgumentError exception.
VALUE rb_eIndexError
IndexError exception.
VALUE rb_ensure(VALUE(*b_proc)(VALUE), VALUE data1, VALUE(*e_proc)(VALUE), VALUE data2)
An equivalent to ensure clause.
void rb_warning(const char *fmt,...)
Issues a warning.
@ RB_WARN_CATEGORY_DEPRECATED
Warning is for deprecated features.
VALUE rb_cArray
Array class.
VALUE rb_mEnumerable
Enumerable module.
VALUE rb_class_new_instance_pass_kw(int argc, const VALUE *argv, VALUE klass)
Identical to rb_class_new_instance(), except it passes the passed keywords if any to the #initialize ...
VALUE rb_obj_frozen_p(VALUE obj)
Just calls RB_OBJ_FROZEN() inside.
int rb_eql(VALUE lhs, VALUE rhs)
Checks for equality of the passed objects, in terms of Object#eql?.
VALUE rb_cNumeric
Numeric class.
VALUE rb_cRandom
Random class.
VALUE rb_obj_class(VALUE obj)
Queries the class of an object.
VALUE rb_inspect(VALUE obj)
Generates a human-readable textual representation of the given object.
double rb_num2dbl(VALUE num)
Converts an instance of rb_cNumeric into C's double.
VALUE rb_equal(VALUE lhs, VALUE rhs)
This function is an optimised version of calling #==.
VALUE rb_obj_is_kind_of(VALUE obj, VALUE klass)
Queries if the given object is an instance (of possibly descendants) of the given class.
VALUE rb_obj_freeze(VALUE obj)
Just calls rb_obj_freeze_inline() inside.
#define RB_OBJ_WRITTEN(old, oldv, young)
Identical to RB_OBJ_WRITE(), except it doesn't write any values, but only a WB declaration.
#define RB_OBJ_WRITE(old, slot, young)
Declaration of a "back" pointer.
VALUE rb_call_super(int argc, const VALUE *argv)
This resembles ruby's super.
Defines RBIMPL_HAS_BUILTIN.
#define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn)
This roughly resembles return enum_for(__callee__) unless block_given?.
#define RETURN_ENUMERATOR(obj, argc, argv)
Identical to RETURN_SIZED_ENUMERATOR(), except its size is unknown.
#define UNLIMITED_ARGUMENTS
This macro is used in conjunction with rb_check_arity().
#define rb_check_frozen
Just another name of rb_check_frozen.
VALUE rb_int_positive_pow(long x, unsigned long y)
Raises the passed x to the power of y.
VALUE rb_range_beg_len(VALUE range, long *begp, long *lenp, long len, int err)
Deconstructs a numerical range.
#define rb_hash_uint(h, i)
Just another name of st_hash_uint.
#define rb_hash_end(h)
Just another name of st_hash_end.
#define rb_str_new(str, len)
Allocates an instance of rb_cString.
#define rb_usascii_str_new(str, len)
Identical to rb_str_new, except it generates a string of "US ASCII" encoding.
#define rb_usascii_str_new_cstr(str)
Identical to rb_str_new_cstr, except it generates a string of "US ASCII" encoding.
VALUE rb_str_buf_append(VALUE dst, VALUE src)
Identical to rb_str_cat_cstr(), except it takes Ruby's string instead of C's.
void rb_str_set_len(VALUE str, long len)
Overwrites the length of the string.
st_index_t rb_hash_start(st_index_t i)
Starts a series of hashing.
int rb_str_cmp(VALUE lhs, VALUE rhs)
Compares two strings, as in strcmp(3).
VALUE rb_check_string_type(VALUE obj)
Try converting an object to its stringised representation using its to_str method,...
VALUE rb_str_buf_new(long capa)
Allocates a "string buffer".
VALUE rb_obj_as_string(VALUE obj)
Try converting an object to its stringised representation using its to_s method, if any.
VALUE rb_exec_recursive(VALUE(*f)(VALUE g, VALUE h, int r), VALUE g, VALUE h)
"Recursion" API entry point.
VALUE rb_exec_recursive_paired(VALUE(*f)(VALUE g, VALUE h, int r), VALUE g, VALUE p, VALUE h)
Identical to rb_exec_recursive(), except it checks for the recursion on the ordered pair of { g,...
int rb_respond_to(VALUE obj, ID mid)
Queries if the object responds to the method.
void rb_define_alloc_func(VALUE klass, rb_alloc_func_t func)
Sets the allocator function of a class.
void ruby_qsort(void *, const size_t, const size_t, int(*)(const void *, const void *, void *), void *)
Reentrant implementation of quick sort.
#define RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg)
Shim for block function parameters.
VALUE rb_yield_values2(int n, const VALUE *argv)
Identical to rb_yield_values(), except it takes the parameters as a C array instead of variadic argum...
VALUE rb_yield(VALUE val)
Yields the block.
#define RBIMPL_ATTR_MAYBE_UNUSED()
Wraps (or simulates) [[maybe_unused]]
#define MEMCPY(p1, p2, type, n)
Handy macro to call memcpy.
#define MEMZERO(p, type, n)
Handy macro to erase a region of memory.
#define RB_GC_GUARD(v)
Prevents premature destruction of local objects.
#define MEMMOVE(p1, p2, type, n)
Handy macro to call memmove.
VALUE rb_block_call(VALUE q, ID w, int e, const VALUE *r, type *t, VALUE y)
Call a method with a block.
#define RARRAY_LEN
Just another name of rb_array_len.
#define RARRAY_CONST_PTR_TRANSIENT
Just another name of rb_array_const_ptr_transient.
#define RARRAY(obj)
Convenient casting macro.
#define RARRAY_PTR_USE(ary, ptr_name, expr)
Declares a section of code where raw pointers are used.
#define RARRAY_AREF(a, i)
#define RARRAY_PTR_USE_TRANSIENT(ary, ptr_name, expr)
Identical to RARRAY_PTR_USE, except the pointer can be a transient one.
#define RARRAY_CONST_PTR
Just another name of rb_array_const_ptr.
#define RBASIC(obj)
Convenient casting macro.
#define Data_Wrap_Struct(klass, mark, free, sval)
Converts sval, a pointer to your struct, into a Ruby object.
#define DATA_PTR(obj)
Convenient getter macro.
#define RGENGC_WB_PROTECTED_ARRAY
This is a compile-time flag to enable/disable write barrier for struct RArray.
#define RB_OBJ_WB_UNPROTECT_FOR(type, obj)
Identical to RB_OBJ_WB_UNPROTECT(), except it can also assert that the given object is of given type.
#define RHASH_SIZE(h)
Queries the size of the hash.
#define StringValue(v)
Ensures that the parameter object is a String.
#define RB_PASS_CALLED_KEYWORDS
Pass keywords if current method is called with keywords, useful for argument delegation.
#define RTEST
This is an old name of RB_TEST.
const VALUE ary[RARRAY_EMBED_LEN_MAX]
Embedded elements.
union RArray::@45 as
Array's specific fields.
const VALUE shared_root
Parent of the array.
long capa
Capacity of *ptr.
long len
Number of elements of the array.
const VALUE * ptr
Pointer to the C array that holds the elements of the array.
intptr_t SIGNED_VALUE
A signed integer type that has the same width with VALUE.
uintptr_t VALUE
Type that represents a Ruby object.