Changeset 331 for EcnlProtoTool/trunk/mruby-1.3.0/src/array.c
- Timestamp:
- Jan 21, 2018, 12:10:09 AM (6 years ago)
- Location:
- EcnlProtoTool/trunk/mruby-1.3.0
- Files:
-
- 1 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
EcnlProtoTool/trunk/mruby-1.3.0/src/array.c
r321 r331 5 5 */ 6 6 7 #include "mruby.h"8 #include "mruby/array.h"9 #include "mruby/class.h"10 #include "mruby/string.h"11 #include "mruby/range.h"7 #include <mruby.h> 8 #include <mruby/array.h> 9 #include <mruby/class.h> 10 #include <mruby/string.h> 11 #include <mruby/range.h> 12 12 #include "value_array.h" 13 13 … … 17 17 #define ARY_MAX_SIZE ((ARY_C_MAX_SIZE < (size_t)MRB_INT_MAX) ? (mrb_int)ARY_C_MAX_SIZE : MRB_INT_MAX-1) 18 18 19 static inline mrb_value20 ary_elt(mrb_value ary, mrb_int offset)21 {22 if (offset < 0 || RARRAY_LEN(ary) <= offset) {23 return mrb_nil_value();24 }25 return RARRAY_PTR(ary)[offset];26 }27 28 19 static struct RArray* 29 20 ary_new_capa(mrb_state *mrb, mrb_int capa) 30 21 { 31 22 struct RArray *a; 32 mrb_int blen;23 size_t blen; 33 24 34 25 if (capa > ARY_MAX_SIZE) { … … 36 27 } 37 28 blen = capa * sizeof(mrb_value); 38 if (blen < capa) {39 mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big");40 }41 29 42 30 a = (struct RArray*)mrb_obj_alloc(mrb, MRB_TT_ARRAY, mrb->array_class); … … 121 109 ary_modify(mrb_state *mrb, struct RArray *a) 122 110 { 111 if (MRB_FROZEN_P(a)) { 112 mrb_raise(mrb, E_RUNTIME_ERROR, "can't modify frozen array"); 113 } 114 123 115 if (ARY_SHARED_P(a)) { 124 116 mrb_shared_array *shared = a->aux.shared; … … 179 171 180 172 if (len > ARY_MAX_SIZE) { 173 size_error: 181 174 mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); 182 175 } … … 186 179 } 187 180 while (capa < len) { 188 capa *= 2; 189 } 190 191 if (capa > ARY_MAX_SIZE) capa = ARY_MAX_SIZE; /* len <= capa <= ARY_MAX_SIZE */ 181 if (capa <= ARY_MAX_SIZE / 2) { 182 capa *= 2; 183 } 184 else { 185 capa = len; 186 } 187 } 188 if (capa < len || capa > ARY_MAX_SIZE) { 189 goto size_error; 190 } 192 191 193 192 if (capa > a->aux.capa) { … … 244 243 245 244 static mrb_value 246 mrb_ary_s_create(mrb_state *mrb, mrb_value self) 247 { 245 mrb_ary_s_create(mrb_state *mrb, mrb_value klass) 246 { 247 mrb_value ary; 248 248 mrb_value *vals; 249 249 mrb_int len; 250 struct RArray *a; 250 251 251 252 mrb_get_args(mrb, "*", &vals, &len); 252 253 return mrb_ary_new_from_values(mrb, len, vals); 253 ary = mrb_ary_new_from_values(mrb, len, vals); 254 a = mrb_ary_ptr(ary); 255 a->c = mrb_class_ptr(klass); 256 257 return ary; 254 258 } 255 259 256 260 static void 257 ary_concat(mrb_state *mrb, struct RArray *a, mrb_value *ptr, mrb_int blen) 258 { 259 mrb_int len = a->len + blen; 261 ary_concat(mrb_state *mrb, struct RArray *a, struct RArray *a2) 262 { 263 mrb_int len; 264 265 if (a2->len > ARY_MAX_SIZE - a->len) { 266 mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); 267 } 268 len = a->len + a2->len; 260 269 261 270 ary_modify(mrb, a); 262 if (a->aux.capa < len) ary_expand_capa(mrb, a, len); 263 array_copy(a->ptr+a->len, ptr, blen); 271 if (a->aux.capa < len) { 272 ary_expand_capa(mrb, a, len); 273 } 274 array_copy(a->ptr+a->len, a2->ptr, a2->len); 264 275 mrb_write_barrier(mrb, (struct RBasic*)a); 265 276 a->len = len; … … 271 282 struct RArray *a2 = mrb_ary_ptr(other); 272 283 273 ary_concat(mrb, mrb_ary_ptr(self), a2 ->ptr, a2->len);284 ary_concat(mrb, mrb_ary_ptr(self), a2); 274 285 } 275 286 … … 277 288 mrb_ary_concat_m(mrb_state *mrb, mrb_value self) 278 289 { 279 mrb_value *ptr; 280 mrb_int blen; 281 282 mrb_get_args(mrb, "a", &ptr, &blen); 283 ary_concat(mrb, mrb_ary_ptr(self), ptr, blen); 290 mrb_value ary; 291 292 mrb_get_args(mrb, "A", &ary); 293 mrb_ary_concat(mrb, self, ary); 284 294 return self; 285 295 } … … 319 329 mrb_ary_replace(mrb_state *mrb, mrb_value self, mrb_value other) 320 330 { 331 struct RArray *a1 = mrb_ary_ptr(self); 321 332 struct RArray *a2 = mrb_ary_ptr(other); 322 333 323 ary_replace(mrb, mrb_ary_ptr(self), a2->ptr, a2->len); 334 if (a1 != a2) { 335 ary_replace(mrb, a1, a2->ptr, a2->len); 336 } 324 337 } 325 338 … … 433 446 struct RArray *a = mrb_ary_ptr(ary); 434 447 448 ary_modify(mrb, a); 435 449 if (a->len == 0) return mrb_nil_value(); 436 450 return a->ptr[--a->len]; … … 445 459 mrb_value val; 446 460 461 ary_modify(mrb, a); 447 462 if (a->len == 0) return mrb_nil_value(); 448 463 if (ARY_SHARED_P(a)) { … … 507 522 508 523 mrb_get_args(mrb, "*", &vals, &len); 524 if (len > ARY_MAX_SIZE - a->len) { 525 mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); 526 } 509 527 if (ARY_SHARED_P(a) 510 528 && a->aux.shared->refcnt == 1 /* shared only referenced from this array */ … … 564 582 } 565 583 584 static struct RArray* 585 ary_dup(mrb_state *mrb, struct RArray *a) 586 { 587 struct RArray *d = ary_new_capa(mrb, a->len); 588 589 ary_replace(mrb, d, a->ptr, a->len); 590 return d; 591 } 592 566 593 MRB_API mrb_value 567 594 mrb_ary_splice(mrb_state *mrb, mrb_value ary, mrb_int head, mrb_int len, mrb_value rpl) 568 595 { 569 596 struct RArray *a = mrb_ary_ptr(ary); 570 mrb_int tail, size;571 597 const mrb_value *argv; 572 mrb_int i, argc; 598 mrb_int argc; 599 mrb_int tail; 573 600 574 601 ary_modify(mrb, a); … … 584 611 } 585 612 } 586 if (a->len < len || a->len < head + len) { 613 tail = head + len; 614 if (a->len < len || a->len < tail) { 587 615 len = a->len - head; 588 616 } 589 tail = head + len;590 617 591 618 /* size check */ … … 593 620 argc = RARRAY_LEN(rpl); 594 621 argv = RARRAY_PTR(rpl); 622 if (argv == a->ptr) { 623 struct RArray *r; 624 625 if (argc > 32767) { 626 mrb_raise(mrb, E_ARGUMENT_ERROR, "too big recursive splice"); 627 } 628 r = ary_dup(mrb, a); 629 argv = r->ptr; 630 } 595 631 } 596 632 else { … … 598 634 argv = &rpl; 599 635 } 600 size = head + argc; 601 602 if (tail < a->len) size += a->len - tail; 603 if (size > a->aux.capa) 604 ary_expand_capa(mrb, a, size); 605 606 if (head > a->len) { 636 if (head >= a->len) { 637 if (head > ARY_MAX_SIZE - argc) { 638 mrb_raisef(mrb, E_INDEX_ERROR, "index %S too big", mrb_fixnum_value(head)); 639 } 640 len = head + argc; 641 if (len > a->aux.capa) { 642 ary_expand_capa(mrb, a, head + argc); 643 } 607 644 ary_fill_with_nil(a->ptr + a->len, head - a->len); 608 } 609 else if (head < a->len) { 610 value_move(a->ptr + head + argc, a->ptr + tail, a->len - tail); 611 } 612 613 for (i = 0; i < argc; i++) { 614 *(a->ptr + head + i) = *(argv + i); 615 mrb_field_write_barrier_value(mrb, (struct RBasic*)a, argv[i]); 616 } 617 618 a->len = size; 619 645 if (argc > 0) { 646 array_copy(a->ptr + head, argv, argc); 647 } 648 a->len = len; 649 } 650 else { 651 mrb_int alen; 652 653 if (a->len - len > ARY_MAX_SIZE - argc) { 654 mrb_raisef(mrb, E_INDEX_ERROR, "index %S too big", mrb_fixnum_value(a->len + argc - len)); 655 } 656 alen = a->len + argc - len; 657 if (alen > a->aux.capa) { 658 ary_expand_capa(mrb, a, alen); 659 } 660 661 if (len != argc) { 662 tail = head + len; 663 value_move(a->ptr + head + argc, a->ptr + tail, a->len - tail); 664 a->len = alen; 665 } 666 if (argc > 0) { 667 value_move(a->ptr + head, argv, argc); 668 } 669 } 670 mrb_write_barrier(mrb, (struct RBasic*)a); 620 671 return ary; 621 672 } … … 703 754 /* a[n..m] */ 704 755 case MRB_TT_RANGE: 705 if (mrb_range_beg_len(mrb, index, &i, &len, a->len )) {756 if (mrb_range_beg_len(mrb, index, &i, &len, a->len, TRUE) == 1) { 706 757 return ary_subseq(mrb, a, i, len); 707 758 } … … 767 818 mrb_int i, len; 768 819 820 mrb_ary_modify(mrb, mrb_ary_ptr(self)); 769 821 if (mrb_get_args(mrb, "oo|o", &v1, &v2, &v3) == 2) { 770 switch (mrb_type(v1)) {771 822 /* a[n..m] = v */ 772 case MRB_TT_RANGE: 773 if (mrb_range_beg_len(mrb, v1, &i, &len, RARRAY_LEN(self))) { 774 mrb_ary_splice(mrb, self, i, len, v2); 775 } 823 switch (mrb_range_beg_len(mrb, v1, &i, &len, RARRAY_LEN(self), FALSE)) { 824 case 0: /* not range */ 825 mrb_ary_set(mrb, self, aget_index(mrb, v1), v2); 776 826 break; 777 /* a[n] = v */ 778 case MRB_TT_FIXNUM: 779 mrb_ary_set(mrb, self, mrb_fixnum(v1), v2); 827 case 1: /* range */ 828 mrb_ary_splice(mrb, self, i, len, v2); 780 829 break; 781 default:782 mrb_ ary_set(mrb, self, aget_index(mrb, v1), v2);830 case 2: /* out of range */ 831 mrb_raisef(mrb, E_RANGE_ERROR, "%S out of range", v1); 783 832 break; 784 833 } … … 878 927 { 879 928 mrb_value obj; 880 mrb_int i ;929 mrb_int i, len; 881 930 882 931 mrb_get_args(mrb, "o", &obj); … … 885 934 return mrb_fixnum_value(i); 886 935 } 936 if (i > (len = RARRAY_LEN(self))) { 937 i = len; 938 } 887 939 } 888 940 return mrb_nil_value(); … … 892 944 mrb_ary_splat(mrb_state *mrb, mrb_value v) 893 945 { 946 mrb_value a, recv_class; 947 894 948 if (mrb_array_p(v)) { 895 949 return v; 896 950 } 897 if (mrb_respond_to(mrb, v, mrb_intern_lit(mrb, "to_a"))) { 898 return mrb_funcall(mrb, v, "to_a", 0); 951 952 if (!mrb_respond_to(mrb, v, mrb_intern_lit(mrb, "to_a"))) { 953 return mrb_ary_new_from_values(mrb, 1, &v); 954 } 955 956 a = mrb_funcall(mrb, v, "to_a", 0); 957 if (mrb_array_p(a)) { 958 return a; 959 } 960 else if (mrb_nil_p(a)) { 961 return mrb_ary_new_from_values(mrb, 1, &v); 899 962 } 900 963 else { 901 return mrb_ary_new_from_values(mrb, 1, &v); 964 recv_class = mrb_obj_value(mrb_obj_class(mrb, v)); 965 mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %S to Array (%S#to_a gives %S)", 966 recv_class, 967 recv_class, 968 mrb_obj_value(mrb_obj_class(mrb, a)) 969 ); 970 /* not reached */ 971 return mrb_undef_value(); 902 972 } 903 973 } … … 916 986 struct RArray *a = mrb_ary_ptr(self); 917 987 988 ary_modify(mrb, a); 918 989 if (ARY_SHARED_P(a)) { 919 990 mrb_ary_decref(mrb, a->aux.shared); … … 988 1059 989 1060 default: 990 tmp = mrb_check_string_type(mrb, val); 991 if (!mrb_nil_p(tmp)) { 992 val = tmp; 993 goto str_join; 994 } 995 tmp = mrb_check_convert_type(mrb, val, MRB_TT_ARRAY, "Array", "to_ary"); 996 if (!mrb_nil_p(tmp)) { 997 val = tmp; 998 goto ary_join; 1061 if (!mrb_immediate_p(val)) { 1062 tmp = mrb_check_string_type(mrb, val); 1063 if (!mrb_nil_p(tmp)) { 1064 val = tmp; 1065 goto str_join; 1066 } 1067 tmp = mrb_check_convert_type(mrb, val, MRB_TT_ARRAY, "Array", "to_ary"); 1068 if (!mrb_nil_p(tmp)) { 1069 val = tmp; 1070 goto ary_join; 1071 } 999 1072 } 1000 1073 val = mrb_obj_as_string(mrb, val); … … 1011 1084 mrb_ary_join(mrb_state *mrb, mrb_value ary, mrb_value sep) 1012 1085 { 1013 sep = mrb_obj_as_string(mrb, sep); 1086 if (!mrb_nil_p(sep)) { 1087 sep = mrb_obj_as_string(mrb, sep); 1088 } 1014 1089 return join_ary(mrb, ary, sep, mrb_ary_new(mrb)); 1015 1090 } … … 1091 1166 mrb_define_method(mrb, a, "pop", mrb_ary_pop, MRB_ARGS_NONE()); /* 15.2.12.5.21 */ 1092 1167 mrb_define_method(mrb, a, "push", mrb_ary_push_m, MRB_ARGS_ANY()); /* 15.2.12.5.22 */ 1168 mrb_define_method(mrb, a, "append", mrb_ary_push_m, MRB_ARGS_ANY()); 1093 1169 mrb_define_method(mrb, a, "replace", mrb_ary_replace_m, MRB_ARGS_REQ(1)); /* 15.2.12.5.23 */ 1094 1170 mrb_define_method(mrb, a, "reverse", mrb_ary_reverse, MRB_ARGS_NONE()); /* 15.2.12.5.24 */ … … 1099 1175 mrb_define_method(mrb, a, "slice", mrb_ary_aget, MRB_ARGS_ANY()); /* 15.2.12.5.29 */ 1100 1176 mrb_define_method(mrb, a, "unshift", mrb_ary_unshift_m, MRB_ARGS_ANY()); /* 15.2.12.5.30 */ 1177 mrb_define_method(mrb, a, "prepend", mrb_ary_unshift_m, MRB_ARGS_ANY()); 1101 1178 1102 1179 mrb_define_method(mrb, a, "__ary_eq", mrb_ary_eq, MRB_ARGS_REQ(1));
Note:
See TracChangeset
for help on using the changeset viewer.