diff options
Diffstat (limited to 'src/array.c')
| -rw-r--r-- | src/array.c | 110 |
1 files changed, 61 insertions, 49 deletions
diff --git a/src/array.c b/src/array.c index 29e43b34f..b55a47f66 100644 --- a/src/array.c +++ b/src/array.c @@ -10,14 +10,18 @@ #include "mruby/string.h" #include "mruby/class.h" +/* SIZE_MAX is not supported by VC++. */ +#ifndef SIZE_MAX +# define SIZE_MAX ((size_t)-1) +#endif + #define ARY_DEFAULT_LEN 4 #define ARY_SHRINK_RATIO 5 /* must be larger than 2 */ -#ifdef INT_MAX -# define ARY_MAX_SIZE (INT_MAX / sizeof(mrb_value)) -#endif +#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) static inline mrb_value -ary_elt(mrb_value ary, int offset) +ary_elt(mrb_value ary, mrb_int offset) { if (RARRAY_LEN(ary) == 0) return mrb_nil_value(); if (offset < 0 || RARRAY_LEN(ary) <= offset) { @@ -27,16 +31,14 @@ ary_elt(mrb_value ary, int offset) } static struct RArray* -ary_new_capa(mrb_state *mrb, int capa) +ary_new_capa(mrb_state *mrb, mrb_int capa) { struct RArray *a; - int blen; + mrb_int blen; -#ifdef INT_MAX if (capa > ARY_MAX_SIZE) { mrb_raise(mrb, E_ARGUMENT_ERROR, "ary size too big"); } -#endif blen = capa * sizeof(mrb_value) ; if (blen < capa) { mrb_raise(mrb, E_ARGUMENT_ERROR, "ary size too big"); @@ -51,7 +53,7 @@ ary_new_capa(mrb_state *mrb, int capa) } mrb_value -mrb_ary_new_capa(mrb_state *mrb, int capa) +mrb_ary_new_capa(mrb_state *mrb, mrb_int capa) { struct RArray *a = ary_new_capa(mrb, capa); return mrb_obj_value(a); @@ -63,6 +65,20 @@ mrb_ary_new(mrb_state *mrb) return mrb_ary_new_capa(mrb, 0); } +/* + * to copy array, use this instead of memcpy because of portability + * * gcc on ARM may fail optimization of memcpy + * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka3934.html + * * gcc on MIPS also fail + * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39755 + * * memcpy doesn't exist on freestanding environment + * + * If you optimize for binary size, use memcpy instead of this at your own risk + * of above portability issue. + * + * see also http://togetter.com/li/462898 + * + */ static inline void array_copy(mrb_value *dst, const mrb_value *src, size_t size) { @@ -75,7 +91,7 @@ array_copy(mrb_value *dst, const mrb_value *src, size_t size) mrb_value -mrb_ary_new_from_values(mrb_state *mrb, int size, mrb_value *vals) +mrb_ary_new_from_values(mrb_state *mrb, mrb_int size, mrb_value *vals) { mrb_value ary; struct RArray *a; @@ -98,7 +114,7 @@ mrb_assoc_new(mrb_state *mrb, mrb_value car, mrb_value cdr) } static void -ary_fill_with_nil(mrb_value *ptr, int size) +ary_fill_with_nil(mrb_value *ptr, mrb_int size) { mrb_value nil = mrb_nil_value(); @@ -111,7 +127,7 @@ static void ary_modify(mrb_state *mrb, struct RArray *a) { if (a->flags & MRB_ARY_SHARED) { - struct mrb_shared_array *shared = a->aux.shared; + mrb_shared_array *shared = a->aux.shared; if (shared->refcnt == 1 && a->ptr == shared->ptr) { a->ptr = shared->ptr; @@ -120,13 +136,13 @@ ary_modify(mrb_state *mrb, struct RArray *a) } else { mrb_value *ptr, *p; - int len; + mrb_int len; p = a->ptr; len = a->len * sizeof(mrb_value); ptr = (mrb_value *)mrb_malloc(mrb, len); if (p) { - array_copy(ptr, p, a->len); + array_copy(ptr, p, a->len); } a->ptr = ptr; a->aux.capa = a->len; @@ -140,7 +156,7 @@ static void ary_make_shared(mrb_state *mrb, struct RArray *a) { if (!(a->flags & MRB_ARY_SHARED)) { - struct mrb_shared_array *shared = (struct mrb_shared_array *)mrb_malloc(mrb, sizeof(struct mrb_shared_array)); + mrb_shared_array *shared = (mrb_shared_array *)mrb_malloc(mrb, sizeof(mrb_shared_array)); shared->refcnt = 1; if (a->aux.capa > a->len) { @@ -156,15 +172,13 @@ ary_make_shared(mrb_state *mrb, struct RArray *a) } static void -ary_expand_capa(mrb_state *mrb, struct RArray *a, int len) +ary_expand_capa(mrb_state *mrb, struct RArray *a, mrb_int len) { - int capa = a->aux.capa; + mrb_int capa = a->aux.capa; -#ifdef INT_MAX if (len > ARY_MAX_SIZE) { mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); } -#endif while(capa < len) { if (capa == 0) { @@ -175,9 +189,7 @@ ary_expand_capa(mrb_state *mrb, struct RArray *a, int len) } } -#ifdef INT_MAX if (capa > ARY_MAX_SIZE) capa = ARY_MAX_SIZE; /* len <= capa <= ARY_MAX_SIZE */ -#endif if (capa > a->aux.capa) { a->aux.capa = capa; @@ -188,7 +200,7 @@ ary_expand_capa(mrb_state *mrb, struct RArray *a, int len) static void ary_shrink_capa(mrb_state *mrb, struct RArray *a) { - int capa = a->aux.capa; + mrb_int capa = a->aux.capa; if (capa < ARY_DEFAULT_LEN * 2) return; if (capa <= a->len * ARY_SHRINK_RATIO) return; @@ -214,13 +226,13 @@ mrb_ary_s_create(mrb_state *mrb, mrb_value self) int len; mrb_get_args(mrb, "*", &vals, &len); - return mrb_ary_new_from_values(mrb, (int)len, vals); + return mrb_ary_new_from_values(mrb, len, vals); } static void -ary_concat(mrb_state *mrb, struct RArray *a, mrb_value *ptr, int blen) +ary_concat(mrb_state *mrb, struct RArray *a, mrb_value *ptr, mrb_int blen) { - int len = a->len + blen; + mrb_int len = a->len + blen; ary_modify(mrb, a); if (a->aux.capa < len) ary_expand_capa(mrb, a, len); @@ -241,7 +253,7 @@ mrb_value mrb_ary_concat_m(mrb_state *mrb, mrb_value self) { mrb_value *ptr; - int blen; + mrb_int blen; mrb_get_args(mrb, "a", &ptr, &blen); ary_concat(mrb, mrb_ary_ptr(self), ptr, blen); @@ -255,7 +267,7 @@ mrb_ary_plus(mrb_state *mrb, mrb_value self) struct RArray *a2; mrb_value ary; mrb_value *ptr; - int blen; + mrb_int blen; mrb_get_args(mrb, "a", &ptr, &blen); ary = mrb_ary_new_capa(mrb, a1->len + blen); @@ -291,7 +303,7 @@ mrb_ary_cmp(mrb_state *mrb, mrb_value ary1) mrb_value ary2; struct RArray *a1, *a2; mrb_value r = mrb_nil_value(); - int i, len; + mrb_int i, len; mrb_get_args(mrb, "o", &ary2); if (!mrb_array_p(ary2)) return mrb_nil_value(); @@ -315,7 +327,7 @@ mrb_ary_cmp(mrb_state *mrb, mrb_value ary1) } static void -ary_replace(mrb_state *mrb, struct RArray *a, mrb_value *argv, int len) +ary_replace(mrb_state *mrb, struct RArray *a, mrb_value *argv, mrb_int len) { ary_modify(mrb, a); if (a->aux.capa < len) @@ -415,7 +427,7 @@ mrb_ary_reverse(mrb_state *mrb, mrb_value self) } mrb_value -mrb_ary_new4(mrb_state *mrb, int n, const mrb_value *elts) +mrb_ary_new4(mrb_state *mrb, mrb_int n, const mrb_value *elts) { mrb_value ary; @@ -429,7 +441,7 @@ mrb_ary_new4(mrb_state *mrb, int n, const mrb_value *elts) } mrb_value -mrb_ary_new_elts(mrb_state *mrb, int n, const mrb_value *elts) +mrb_ary_new_elts(mrb_state *mrb, mrb_int n, const mrb_value *elts) { return mrb_ary_new4(mrb, n, elts); } @@ -491,7 +503,7 @@ mrb_ary_shift(mrb_state *mrb, mrb_value self) } else { mrb_value *ptr = a->ptr; - int size = a->len; + mrb_int size = a->len; val = *ptr; while((int)(--size)) { @@ -598,9 +610,9 @@ 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); - int tail, size; + mrb_int tail, size; mrb_value *argv; - int i, argc; + mrb_int i, argc; ary_modify(mrb, a); /* range check */ @@ -646,14 +658,14 @@ mrb_ary_splice(mrb_state *mrb, mrb_value ary, mrb_int head, mrb_int len, mrb_val return ary; } -int +mrb_int mrb_ary_len(mrb_state *mrb, mrb_value ary) { return RARRAY_LEN(ary); } void -mrb_ary_decref(mrb_state *mrb, struct mrb_shared_array *shared) +mrb_ary_decref(mrb_state *mrb, mrb_shared_array *shared) { shared->refcnt--; if (shared->refcnt == 0) { @@ -663,7 +675,7 @@ mrb_ary_decref(mrb_state *mrb, struct mrb_shared_array *shared) } static mrb_value -ary_subseq(mrb_state *mrb, struct RArray *a, int beg, int len) +ary_subseq(mrb_state *mrb, struct RArray *a, mrb_int beg, mrb_int len) { struct RArray *b; @@ -700,7 +712,7 @@ mrb_ary_aget(mrb_state *mrb, mrb_value self) len = mrb_fixnum(argv[0]); if (len < 0) return mrb_nil_value(); if (a->len == (int)index) return mrb_ary_new(mrb); - if ((int)len > a->len - index) len = a->len - index; + if (len > a->len - index) len = a->len - index; return ary_subseq(mrb, a, index, len); default: @@ -743,7 +755,7 @@ mrb_ary_delete_at(mrb_state *mrb, mrb_value self) mrb_int index; mrb_value val; mrb_value *ptr; - int len; + mrb_int len; mrb_get_args(mrb, "i", &index); if (index < 0) index += a->len; @@ -789,7 +801,7 @@ mrb_value mrb_ary_last(mrb_state *mrb, mrb_value self) { struct RArray *a = mrb_ary_ptr(self); - int size; + mrb_int size; mrb_value *vals; int len; @@ -816,7 +828,7 @@ mrb_value mrb_ary_index_m(mrb_state *mrb, mrb_value self) { mrb_value obj; - int i; + mrb_int i; mrb_get_args(mrb, "o", &obj); for (i = 0; i < RARRAY_LEN(self); i++) { @@ -831,7 +843,7 @@ mrb_value mrb_ary_rindex_m(mrb_state *mrb, mrb_value self) { mrb_value obj; - int i; + mrb_int i; mrb_get_args(mrb, "o", &obj); for (i = RARRAY_LEN(self) - 1; i >= 0; i--) { @@ -890,7 +902,7 @@ mrb_check_array_type(mrb_state *mrb, mrb_value ary) } mrb_value -mrb_ary_entry(mrb_value ary, int offset) +mrb_ary_entry(mrb_value ary, mrb_int offset) { if (offset < 0) { offset += RARRAY_LEN(ary); @@ -901,7 +913,7 @@ mrb_ary_entry(mrb_value ary, int offset) static mrb_value inspect_ary(mrb_state *mrb, mrb_value ary, mrb_value list) { - int i; + mrb_int i; mrb_value s, arystr; char head[] = { '[' }; char sep[] = { ',', ' ' }; @@ -920,7 +932,7 @@ inspect_ary(mrb_state *mrb, mrb_value ary, mrb_value list) mrb_str_buf_cat(mrb, arystr, head, sizeof(head)); for(i=0; i<RARRAY_LEN(ary); i++) { - int ai = mrb_gc_arena_save(mrb); + mrb_int ai = mrb_gc_arena_save(mrb); if (i > 0) { mrb_str_buf_cat(mrb, arystr, sep, sizeof(sep)); @@ -963,7 +975,7 @@ mrb_ary_inspect(mrb_state *mrb, mrb_value ary) static mrb_value join_ary(mrb_state *mrb, mrb_value ary, mrb_value sep, mrb_value list) { - int i; + mrb_int i; mrb_value result, val, tmp; /* check recursive */ @@ -1078,7 +1090,7 @@ mrb_ary_equal(mrb_state *mrb, mrb_value ary1) } if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return mrb_false_value(); else { - int i; + mrb_int i; for (i=0; i<RARRAY_LEN(ary1); i++) { if (!mrb_equal(mrb, ary_elt(ary1, i), ary_elt(ary2, i))) @@ -1107,11 +1119,11 @@ mrb_ary_eql(mrb_state *mrb, mrb_value ary1) if (!mrb_array_p(ary2)) return mrb_false_value(); if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return mrb_false_value(); else { - int i; + mrb_int i; for (i=0; i<RARRAY_LEN(ary1); i++) { if (!mrb_eql(mrb, ary_elt(ary1, i), ary_elt(ary2, i))) - return mrb_false_value(); + return mrb_false_value(); } return mrb_true_value(); } |
