diff options
Diffstat (limited to 'src/array.c')
| -rw-r--r-- | src/array.c | 90 |
1 files changed, 42 insertions, 48 deletions
diff --git a/src/array.c b/src/array.c index 875214105..f48719310 100644 --- a/src/array.c +++ b/src/array.c @@ -15,9 +15,6 @@ #define ARY_SHRINK_RATIO 5 /* must be larger than 2 */ #define ARY_C_MAX_SIZE (SIZE_MAX / sizeof(mrb_value)) #define ARY_MAX_SIZE ((ARY_C_MAX_SIZE < (size_t)MRB_INT_MAX) ? (mrb_int)ARY_C_MAX_SIZE : MRB_INT_MAX-1) -#define ARY_SHARED_P(a) ((a)->flags & MRB_ARY_SHARED) -#define ARY_SET_SHARED_FLAG(a) ((a)->flags |= MRB_ARY_SHARED) -#define ARY_UNSET_SHARED_FLAG(a) ((a)->flags &= ~MRB_ARY_SHARED) static inline mrb_value ary_elt(mrb_value ary, mrb_int offset) @@ -51,14 +48,14 @@ ary_new_capa(mrb_state *mrb, mrb_int capa) return a; } -mrb_value +MRB_API mrb_value mrb_ary_new_capa(mrb_state *mrb, mrb_int capa) { struct RArray *a = ary_new_capa(mrb, capa); return mrb_obj_value(a); } -mrb_value +MRB_API mrb_value mrb_ary_new(mrb_state *mrb) { return mrb_ary_new_capa(mrb, 0); @@ -88,21 +85,18 @@ array_copy(mrb_value *dst, const mrb_value *src, mrb_int size) } } -mrb_value +MRB_API mrb_value mrb_ary_new_from_values(mrb_state *mrb, mrb_int size, const mrb_value *vals) { - mrb_value ary; - struct RArray *a; + struct RArray *a = ary_new_capa(mrb, size); - ary = mrb_ary_new_capa(mrb, size); - a = mrb_ary_ptr(ary); array_copy(a->ptr, vals, size); a->len = size; - return ary; + return mrb_obj_value(a); } -mrb_value +MRB_API mrb_value mrb_assoc_new(mrb_state *mrb, mrb_value car, mrb_value cdr) { struct RArray *a; @@ -153,7 +147,7 @@ ary_modify(mrb_state *mrb, struct RArray *a) } } -void +MRB_API void mrb_ary_modify(mrb_state *mrb, struct RArray* a) { mrb_write_barrier(mrb, (struct RBasic*)a); @@ -227,7 +221,7 @@ ary_shrink_capa(mrb_state *mrb, struct RArray *a) } } -mrb_value +MRB_API mrb_value mrb_ary_resize(mrb_state *mrb, mrb_value ary, mrb_int new_len) { mrb_int old_len; @@ -272,7 +266,7 @@ ary_concat(mrb_state *mrb, struct RArray *a, mrb_value *ptr, mrb_int blen) a->len = len; } -void +MRB_API void mrb_ary_concat(mrb_state *mrb, mrb_value self, mrb_value other) { struct RArray *a2 = mrb_ary_ptr(other); @@ -296,18 +290,19 @@ mrb_ary_plus(mrb_state *mrb, mrb_value self) { struct RArray *a1 = mrb_ary_ptr(self); struct RArray *a2; - mrb_value ary; mrb_value *ptr; mrb_int blen; mrb_get_args(mrb, "a", &ptr, &blen); - ary = mrb_ary_new_capa(mrb, a1->len + blen); - a2 = mrb_ary_ptr(ary); + if (ARY_MAX_SIZE - blen < a1->len) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); + } + a2 = ary_new_capa(mrb, a1->len + blen); array_copy(a2->ptr, a1->ptr, a1->len); array_copy(a2->ptr + a1->len, ptr, blen); a2->len = a1->len + blen; - return ary; + return mrb_obj_value(a2); } static void @@ -321,7 +316,7 @@ ary_replace(mrb_state *mrb, struct RArray *a, mrb_value *argv, mrb_int len) a->len = len; } -void +MRB_API void mrb_ary_replace(mrb_state *mrb, mrb_value self, mrb_value other) { struct RArray *a2 = mrb_ary_ptr(other); @@ -345,7 +340,6 @@ mrb_ary_times(mrb_state *mrb, mrb_value self) { struct RArray *a1 = mrb_ary_ptr(self); struct RArray *a2; - mrb_value ary; mrb_value *ptr; mrb_int times; @@ -354,9 +348,10 @@ mrb_ary_times(mrb_state *mrb, mrb_value self) mrb_raise(mrb, E_ARGUMENT_ERROR, "negative argument"); } if (times == 0) return mrb_ary_new(mrb); - - ary = mrb_ary_new_capa(mrb, a1->len * times); - a2 = mrb_ary_ptr(ary); + if (ARY_MAX_SIZE / times < a1->len) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); + } + a2 = ary_new_capa(mrb, a1->len * times); ptr = a2->ptr; while (times--) { array_copy(ptr, a1->ptr, a1->len); @@ -364,7 +359,7 @@ mrb_ary_times(mrb_state *mrb, mrb_value self) a2->len += a1->len; } - return ary; + return mrb_obj_value(a2); } static mrb_value @@ -391,11 +386,8 @@ mrb_ary_reverse_bang(mrb_state *mrb, mrb_value self) static mrb_value mrb_ary_reverse(mrb_state *mrb, mrb_value self) { - struct RArray *a = mrb_ary_ptr(self), *b; - mrb_value ary; + struct RArray *a = mrb_ary_ptr(self), *b = ary_new_capa(mrb, a->len); - ary = mrb_ary_new_capa(mrb, a->len); - b = mrb_ary_ptr(ary); if (a->len > 0) { mrb_value *p1, *p2, *e; @@ -407,10 +399,10 @@ mrb_ary_reverse(mrb_state *mrb, mrb_value self) } b->len = a->len; } - return ary; + return mrb_obj_value(b); } -void +MRB_API void mrb_ary_push(mrb_state *mrb, mrb_value ary, mrb_value elem) { struct RArray *a = mrb_ary_ptr(ary); @@ -436,7 +428,7 @@ mrb_ary_push_m(mrb_state *mrb, mrb_value self) return self; } -mrb_value +MRB_API mrb_value mrb_ary_pop(mrb_state *mrb, mrb_value ary) { struct RArray *a = mrb_ary_ptr(ary); @@ -447,7 +439,7 @@ mrb_ary_pop(mrb_state *mrb, mrb_value ary) #define ARY_SHIFT_SHARED_MIN 10 -mrb_value +MRB_API mrb_value mrb_ary_shift(mrb_state *mrb, mrb_value self) { struct RArray *a = mrb_ary_ptr(self); @@ -483,7 +475,7 @@ mrb_ary_shift(mrb_state *mrb, mrb_value self) item = 0 self.unshift item p self #=> [0, 1, 2, 3] */ -mrb_value +MRB_API mrb_value mrb_ary_unshift(mrb_state *mrb, mrb_value self, mrb_value item) { struct RArray *a = mrb_ary_ptr(self); @@ -536,7 +528,7 @@ mrb_ary_unshift_m(mrb_state *mrb, mrb_value self) return self; } -mrb_value +MRB_API mrb_value mrb_ary_ref(mrb_state *mrb, mrb_value ary, mrb_int n) { struct RArray *a = mrb_ary_ptr(ary); @@ -548,7 +540,7 @@ mrb_ary_ref(mrb_state *mrb, mrb_value ary, mrb_int n) return a->ptr[n]; } -void +MRB_API void mrb_ary_set(mrb_state *mrb, mrb_value ary, mrb_int n, mrb_value val) { struct RArray *a = mrb_ary_ptr(ary); @@ -572,12 +564,12 @@ mrb_ary_set(mrb_state *mrb, mrb_value ary, mrb_int n, mrb_value val) mrb_field_write_barrier_value(mrb, (struct RBasic*)a, val); } -mrb_value +MRB_API mrb_value mrb_ary_splice(mrb_state *mrb, mrb_value ary, mrb_int head, mrb_int len, mrb_value rpl) { struct RArray *a = mrb_ary_ptr(ary); mrb_int tail, size; - mrb_value *argv; + const mrb_value *argv; mrb_int i, argc; ary_modify(mrb, a); @@ -661,10 +653,14 @@ aget_index(mrb_state *mrb, mrb_value index) if (mrb_fixnum_p(index)) { return mrb_fixnum(index); } + else if (mrb_float_p(index)) { + return (mrb_int)mrb_float(index); + } else { - mrb_int i; + mrb_int i, argc; + mrb_value *argv; - mrb_get_args(mrb, "i", &i); + mrb_get_args(mrb, "i*", &i, &argv, &argc); return i; } } @@ -893,7 +889,7 @@ mrb_ary_rindex_m(mrb_state *mrb, mrb_value self) return mrb_nil_value(); } -mrb_value +MRB_API mrb_value mrb_ary_splat(mrb_state *mrb, mrb_value v) { if (mrb_array_p(v)) { @@ -915,7 +911,7 @@ mrb_ary_size(mrb_state *mrb, mrb_value self) return mrb_fixnum_value(a->len); } -mrb_value +MRB_API mrb_value mrb_ary_clear(mrb_state *mrb, mrb_value self) { struct RArray *a = mrb_ary_ptr(self); @@ -942,13 +938,13 @@ mrb_ary_empty_p(mrb_state *mrb, mrb_value self) return mrb_bool_value(a->len == 0); } -mrb_value +MRB_API mrb_value mrb_check_array_type(mrb_state *mrb, mrb_value ary) { return mrb_check_convert_type(mrb, ary, MRB_TT_ARRAY, "Array", "to_ary"); } -mrb_value +MRB_API mrb_value mrb_ary_entry(mrb_value ary, mrb_int offset) { if (offset < 0) { @@ -1012,7 +1008,7 @@ join_ary(mrb_state *mrb, mrb_value ary, mrb_value sep, mrb_value list) return result; } -mrb_value +MRB_API mrb_value mrb_ary_join(mrb_state *mrb, mrb_value ary, mrb_value sep) { sep = mrb_obj_as_string(mrb, sep); @@ -1046,7 +1042,6 @@ mrb_ary_eq(mrb_state *mrb, mrb_value ary1) mrb_get_args(mrb, "o", &ary2); if (mrb_obj_equal(mrb, ary1, ary2)) return mrb_true_value(); - if (mrb_special_const_p(ary2)) return mrb_false_value(); if (!mrb_array_p(ary2)) { return mrb_false_value(); } @@ -1062,7 +1057,6 @@ mrb_ary_cmp(mrb_state *mrb, mrb_value ary1) mrb_get_args(mrb, "o", &ary2); if (mrb_obj_equal(mrb, ary1, ary2)) return mrb_fixnum_value(0); - if (mrb_special_const_p(ary2)) return mrb_nil_value(); if (!mrb_array_p(ary2)) { return mrb_nil_value(); } @@ -1107,5 +1101,5 @@ mrb_init_array(mrb_state *mrb) mrb_define_method(mrb, a, "unshift", mrb_ary_unshift_m, MRB_ARGS_ANY()); /* 15.2.12.5.30 */ mrb_define_method(mrb, a, "__ary_eq", mrb_ary_eq, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, a, "__ary_cmp", mrb_ary_cmp, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, a, "__ary_cmp", mrb_ary_cmp, MRB_ARGS_REQ(1)); } |
