diff options
Diffstat (limited to 'src/array.c')
| -rw-r--r-- | src/array.c | 201 |
1 files changed, 100 insertions, 101 deletions
diff --git a/src/array.c b/src/array.c index c767283aa..88f56f6b4 100644 --- a/src/array.c +++ b/src/array.c @@ -4,20 +4,25 @@ ** See Copyright Notice in mruby.h */ +#ifndef SIZE_MAX + /* Some versions of VC++ + * has SIZE_MAX in stdint.h + */ +# include <limits.h> +#endif #include "mruby.h" #include "mruby/array.h" -#include <string.h> -#include "mruby/string.h" #include "mruby/class.h" +#include "mruby/string.h" +#include "value_array.h" #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 +32,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 +54,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); @@ -87,21 +90,6 @@ 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_value ary; - struct RArray *a; - - ary = mrb_ary_new_capa(mrb, size); - a = mrb_ary_ptr(ary); - array_copy(a->ptr, vals, size); - a->len = size; - - return ary; -} - mrb_value mrb_assoc_new(mrb_state *mrb, mrb_value car, mrb_value cdr) { @@ -112,7 +100,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(); @@ -134,13 +122,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; @@ -170,15 +158,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) { @@ -189,20 +175,24 @@ 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) { + mrb_value *expanded_ptr = (mrb_value *)mrb_realloc(mrb, a->ptr, sizeof(mrb_value)*capa); + + if(!expanded_ptr) { + mrb_raise(mrb, E_RUNTIME_ERROR, "out of memory"); + } + a->aux.capa = capa; - a->ptr = (mrb_value *)mrb_realloc(mrb, a->ptr, sizeof(mrb_value)*capa); + a->ptr = expanded_ptr; } } 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; @@ -228,13 +218,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); @@ -255,7 +245,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); @@ -269,7 +259,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); @@ -305,14 +295,14 @@ 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(); a1 = RARRAY(ary1); a2 = RARRAY(ary2); if (a1->len == a2->len && a1->ptr == a2->ptr) return mrb_fixnum_value(0); else { - mrb_sym cmp = mrb_intern(mrb, "<=>"); + mrb_sym cmp = mrb_intern2(mrb, "<=>", 3); len = RARRAY_LEN(ary1); if (len > RARRAY_LEN(ary2)) { @@ -329,7 +319,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) @@ -429,25 +419,19 @@ 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_new_from_values(mrb_state *mrb, mrb_int size, const mrb_value *vals) { mrb_value ary; + struct RArray *a; - ary = mrb_ary_new_capa(mrb, n); - if (n > 0 && elts) { - array_copy(RARRAY_PTR(ary), elts, n); - RARRAY_LEN(ary) = n; - } + ary = mrb_ary_new_capa(mrb, size); + a = mrb_ary_ptr(ary); + array_copy(a->ptr, vals, size); + a->len = size; return ary; } -mrb_value -mrb_ary_new_elts(mrb_state *mrb, int n, const mrb_value *elts) -{ - return mrb_ary_new4(mrb, n, elts); -} - void mrb_ary_push(mrb_state *mrb, mrb_value ary, mrb_value elem) /* mrb_ary_push */ { @@ -505,7 +489,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)) { @@ -536,7 +520,7 @@ mrb_ary_unshift(mrb_state *mrb, mrb_value self, mrb_value item) ary_modify(mrb, a); if (a->aux.capa < a->len + 1) ary_expand_capa(mrb, a, a->len + 1); - memmove(a->ptr + 1, a->ptr, sizeof(mrb_value)*a->len); + value_move(a->ptr + 1, a->ptr, a->len); a->ptr[0] = item; } a->len++; @@ -563,7 +547,7 @@ mrb_ary_unshift_m(mrb_state *mrb, mrb_value self) if (len == 0) return self; if (a->aux.capa < a->len + len) ary_expand_capa(mrb, a, a->len + len); - memmove(a->ptr + len, a->ptr, sizeof(mrb_value)*a->len); + value_move(a->ptr + len, a->ptr, a->len); } array_copy(a->ptr, vals, len); a->len += len; @@ -594,7 +578,7 @@ mrb_ary_set(mrb_state *mrb, mrb_value ary, mrb_int n, mrb_value val) /* rb_ary_s if (n < 0) { n += a->len; if (n < 0) { - mrb_raisef(mrb, E_INDEX_ERROR, "index %ld out of array", n - a->len); + mrb_raisef(mrb, E_INDEX_ERROR, "index %S out of array", mrb_fixnum_value(n - a->len)); } } if (a->len <= (int)n) { @@ -612,9 +596,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 */ @@ -648,7 +632,7 @@ mrb_ary_splice(mrb_state *mrb, mrb_value ary, mrb_int head, mrb_int len, mrb_val ary_fill_with_nil(a->ptr + a->len, (int)(head - a->len)); } else if (head < a->len) { - memmove(a->ptr + head + argc, a->ptr + tail, sizeof(mrb_value)*(a->len - tail)); + value_move(a->ptr + head + argc, a->ptr + tail, a->len - tail); } for(i = 0; i < argc; i++) { @@ -660,7 +644,7 @@ 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); @@ -677,7 +661,7 @@ mrb_ary_decref(mrb_state *mrb, 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; @@ -714,11 +698,12 @@ 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: mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments"); + break; } return mrb_nil_value(); /* dummy to avoid warning : not reach here */ @@ -757,7 +742,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; @@ -803,7 +788,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; @@ -830,7 +815,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++) { @@ -845,7 +830,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--) { @@ -894,7 +879,7 @@ mrb_ary_empty_p(mrb_state *mrb, mrb_value self) { struct RArray *a = mrb_ary_ptr(self); - return ((a->len == 0)? mrb_true_value(): mrb_false_value()); + return mrb_bool_value(a->len == 0); } mrb_value @@ -904,7 +889,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); @@ -915,7 +900,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[] = { ',', ' ' }; @@ -967,17 +952,13 @@ static mrb_value mrb_ary_inspect(mrb_state *mrb, mrb_value ary) { if (RARRAY_LEN(ary) == 0) return mrb_str_new(mrb, "[]", 2); - #if 0 /* THREAD */ - return mrb_exec_recursive(inspect_ary_r, ary, 0); - #else return inspect_ary(mrb, ary, mrb_ary_new(mrb)); - #endif } 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 */ @@ -1075,31 +1056,39 @@ static mrb_value mrb_ary_equal(mrb_state *mrb, mrb_value ary1) { mrb_value ary2; + mrb_bool equal_p; 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)) { - if (!mrb_respond_to(mrb, ary2, mrb_intern(mrb, "to_ary"))) { - return mrb_false_value(); - } - if (mrb_equal(mrb, ary2, ary1)){ - return mrb_true_value(); + if (mrb_obj_equal(mrb, ary1, ary2)) { + equal_p = 1; + } + else if (mrb_special_const_p(ary2)) { + equal_p = 0; + } + else if (!mrb_array_p(ary2)) { + if (!mrb_respond_to(mrb, ary2, mrb_intern2(mrb, "to_ary", 6))) { + equal_p = 0; } else { - return mrb_false_value(); + equal_p = mrb_equal(mrb, ary2, ary1); } } - if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return mrb_false_value(); + else if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) { + equal_p = 0; + } else { - int i; + mrb_int i; + equal_p = 1; for (i=0; i<RARRAY_LEN(ary1); i++) { - if (!mrb_equal(mrb, ary_elt(ary1, i), ary_elt(ary2, i))) - return mrb_false_value(); + if (!mrb_equal(mrb, ary_elt(ary1, i), ary_elt(ary2, i))) { + equal_p = 0; + break; + } } - return mrb_true_value(); } + + return mrb_bool_value(equal_p); } /* 15.2.12.5.34 (x) */ @@ -1115,20 +1104,30 @@ static mrb_value mrb_ary_eql(mrb_state *mrb, mrb_value ary1) { mrb_value ary2; + mrb_bool eql_p; mrb_get_args(mrb, "o", &ary2); - if (mrb_obj_equal(mrb, ary1, ary2)) return mrb_true_value(); - if (!mrb_array_p(ary2)) return mrb_false_value(); - if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return mrb_false_value(); + if (mrb_obj_equal(mrb, ary1, ary2)) { + eql_p = 1; + } + else if (!mrb_array_p(ary2)) { + eql_p = 0; + } + else if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) { + eql_p = 0; + } else { - int i; - + mrb_int i; + eql_p = 1; for (i=0; i<RARRAY_LEN(ary1); i++) { - if (!mrb_eql(mrb, ary_elt(ary1, i), ary_elt(ary2, i))) - return mrb_false_value(); + if (!mrb_eql(mrb, ary_elt(ary1, i), ary_elt(ary2, i))) { + eql_p = 0; + break; + } } - return mrb_true_value(); } + + return mrb_bool_value(eql_p); } void |
