summaryrefslogtreecommitdiffhomepage
path: root/src/array.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/array.c')
-rw-r--r--src/array.c201
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