summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/mruby.h2
-rw-r--r--src/etc.c8
-rw-r--r--src/range.c33
-rw-r--r--src/string.c48
-rw-r--r--src/struct.c57
5 files changed, 64 insertions, 84 deletions
diff --git a/include/mruby.h b/include/mruby.h
index 70bbdf3c2..3dc160535 100644
--- a/include/mruby.h
+++ b/include/mruby.h
@@ -469,8 +469,6 @@ mrb_value mrb_yield_with_self(mrb_state *mrb, mrb_value b, int argc, mrb_value *
mrb_value mrb_class_new_instance(mrb_state *mrb, int, mrb_value*, struct RClass *);
mrb_value mrb_class_new_instance_m(mrb_state *mrb, mrb_value klass);
-mrb_value mrb_exec_recursive(mrb_state *mrb, mrb_value(*)(mrb_state *, mrb_value, mrb_value, int),mrb_value,void *);
-
#ifndef xmalloc
#define xmalloc malloc
#define xrealloc realloc
diff --git a/src/etc.c b/src/etc.c
index 90ec47fb9..5d70c8bc7 100644
--- a/src/etc.c
+++ b/src/etc.c
@@ -111,14 +111,6 @@ mrb_exec_recursive(mrb_state *mrb, mrb_value (*func) (mrb_state *, mrb_value, mr
* current method is called recursively on the ordered pair <obj, paired_obj>
*/
-mrb_value
-mrb_exec_recursive_paired(mrb_state *mrb, mrb_value (*func) (mrb_state *, mrb_value, mrb_value, int),
- mrb_value obj, mrb_value paired_obj, void* arg)
-{
- // return mrb_exec_recursive_paired(mrb, recursive_eql, hash1, hash2, mrb_fixnum_value((int)&data));
- return func(mrb, obj, paired_obj, 0);
-}
-
mrb_sym
mrb_to_id(mrb_state *mrb, mrb_value name)
{
diff --git a/src/range.c b/src/range.c
index c1fb580b5..b8b1d3926 100644
--- a/src/range.c
+++ b/src/range.c
@@ -29,9 +29,6 @@
#define RANGE_CLASS (mrb_class_obj_get(mrb, "Range"))
-mrb_value mrb_exec_recursive_paired(mrb_state *mrb, mrb_value (*func) (mrb_state *, mrb_value, mrb_value, int),
- mrb_value obj, mrb_value paired_obj, void* arg);
-
mrb_value
mrb_range_new(mrb_state *mrb, mrb_value beg, mrb_value end, int excl)
{
@@ -397,23 +394,6 @@ range_inspect(mrb_state *mrb, mrb_value range)
return inspect_range(mrb, range, range, 0);
}
-static mrb_value
-recursive_eql(mrb_state *mrb, mrb_value range, mrb_value obj, int recur)
-{
- struct RRange *r = mrb_range_ptr(range);
- struct RRange *o = mrb_range_ptr(obj);
-
- if (recur) return mrb_true_value(); /* Subtle! */
- if (!mrb_eql(mrb, r->edges->beg, o->edges->beg))
- return mrb_false_value();
- if (!mrb_eql(mrb, r->edges->end, o->edges->end))
- return mrb_false_value();
-
- if (r->excl != o->excl)
- return mrb_false_value();
- return mrb_true_value();
-}
-
/* 15.2.14.4.14(x) */
/*
* call-seq:
@@ -433,13 +413,24 @@ static mrb_value
range_eql(mrb_state *mrb, mrb_value range)
{
mrb_value obj;
+ struct RRange *r, *o;
mrb_get_args(mrb, "o", &obj);
if (mrb_obj_equal(mrb, range, obj))
return mrb_true_value();
if (!mrb_obj_is_kind_of(mrb, obj, RANGE_CLASS))
return mrb_false_value();
- return mrb_exec_recursive_paired(mrb, recursive_eql, range, obj, &obj);
+
+ r = mrb_range_ptr(range);
+ if (obj.tt != MRB_TT_RANGE) return mrb_false_value();
+ o = mrb_range_ptr(obj);
+ if (!mrb_eql(mrb, r->edges->beg, o->edges->beg))
+ return mrb_false_value();
+ if (!mrb_eql(mrb, r->edges->end, o->edges->end))
+ return mrb_false_value();
+ if (r->excl != o->excl)
+ return mrb_false_value();
+ return mrb_true_value();
}
/* 15.2.14.4.15(x) */
diff --git a/src/string.c b/src/string.c
index 6eba9cb20..d7749c27b 100644
--- a/src/string.c
+++ b/src/string.c
@@ -261,11 +261,8 @@ mrb_str_new_cstr(mrb_state *mrb, const char *p)
}
static void
-str_make_shared(mrb_state *mrb, mrb_value str)
+str_make_shared(mrb_state *mrb, struct RString *s)
{
- struct RString *s;
-
- s = mrb_str_ptr(str);
if (!(s->flags & MRB_STR_SHARED)) {
struct mrb_shared_string *shared = mrb_malloc(mrb, sizeof(struct mrb_shared_string));
@@ -298,7 +295,7 @@ mrb_str_literal(mrb_state *mrb, mrb_value str)
s = str_new(mrb, 0, 0);
orig = mrb_str_ptr(str);
if (!(orig->flags & MRB_STR_SHARED)) {
- str_make_shared(mrb, str);
+ str_make_shared(mrb, mrb_str_ptr(str));
}
shared = orig->aux.shared;
shared->refcnt++;
@@ -1199,11 +1196,15 @@ mrb_str_subseq(mrb_state *mrb, mrb_value str, int beg, int len)
struct RString *s;
struct mrb_shared_string *shared;
- str_make_shared(mrb, str);
- shared = RSTRING(str)->aux.shared;
+ s = mrb_str_ptr(str);
+ str_make_shared(mrb, s);
+ shared = s->aux.shared;
s = mrb_obj_alloc_string(mrb);
s->buf = shared->buf + beg;
s->len = len;
+ s->aux.shared = shared;
+ s->flags |= MRB_STR_SHARED;
+ shared->refcnt++;
return mrb_obj_value(s);
}
@@ -1541,16 +1542,35 @@ mrb_str_index_m(mrb_state *mrb, mrb_value str)
return mrb_fixnum_value(pos);
}
+#define STR_REPLACE_SHARED_MIN 10
+
static mrb_value
str_replace(mrb_state *mrb, struct RString *s1, struct RString *s2)
{
- int len = s2->len;
-
- str_modify(mrb, s1);
- s1->buf = mrb_realloc(mrb, s1->buf, len);
- memcpy(s1->buf, s2->buf, len);
- s1->len = s2->len;
- s2->aux.capa = s2->len;
+ if (s2->flags & MRB_STR_SHARED) {
+ L_SHARE:
+ s1->buf = s2->buf;
+ s1->len = s2->len;
+ s1->aux.shared = s2->aux.shared;
+ s1->flags |= MRB_STR_SHARED;
+ }
+ else if (s2->len > STR_REPLACE_SHARED_MIN) {
+ str_make_shared(mrb, s2);
+ goto L_SHARE;
+ }
+ else {
+ if (s1->flags & MRB_STR_SHARED) {
+ mrb_str_decref(mrb, s1->aux.shared);
+ s1->buf = mrb_malloc(mrb, s2->len+1);
+ }
+ else {
+ s1->buf = mrb_realloc(mrb, s1->buf, s2->len+1);
+ }
+ memcpy(s1->buf, s2->buf, s2->len);
+ s1->buf[s2->len] = 0;
+ s1->len = s2->len;
+ s2->aux.capa = s2->len;
+ }
return mrb_obj_value(s1);
}
diff --git a/src/struct.c b/src/struct.c
index 9f7010e0b..e9266ad17 100644
--- a/src/struct.c
+++ b/src/struct.c
@@ -15,10 +15,6 @@
#ifdef INCLUDE_REGEXP
#include "encoding.h"
#endif
-mrb_sym rb_frame_this_func(mrb_state *mrb);
-mrb_sym mrb_frame_callee(mrb_state *mrb);
-mrb_value mrb_exec_recursive_paired(mrb_state *mrb, mrb_value (*func) (mrb_state *, mrb_value, mrb_value, int),
- mrb_value obj, mrb_value paired_obj, void* arg);
#include "mruby/numeric.h"
#include "mruby/hash.h"
@@ -688,22 +684,6 @@ mrb_struct_aset(mrb_state *mrb, mrb_value s)
return RSTRUCT_PTR(s)[i] = val;
}
-static mrb_value
-recursive_equal(mrb_state *mrb, mrb_value s, mrb_value s2, int recur)
-{
- mrb_value *ptr, *ptr2;
- long i, len;
-
- if (recur) return mrb_true_value(); /* Subtle! */
- ptr = RSTRUCT_PTR(s);
- ptr2 = RSTRUCT_PTR(s2);
- len = RSTRUCT_LEN(s);
- for (i=0; i<len; i++) {
- if (!mrb_equal(mrb, ptr[i], ptr2[i])) return mrb_false_value();
- }
- return mrb_true_value();
-}
-
/* 15.2.18.4.1 */
/*
* call-seq:
@@ -726,6 +706,8 @@ static mrb_value
mrb_struct_equal(mrb_state *mrb, mrb_value s)
{
mrb_value s2;
+ mrb_value *ptr, *ptr2;
+ long i, len;
mrb_get_args(mrb, "o", &s2);
if (mrb_obj_equal(mrb, s, s2)) return mrb_true_value();
@@ -734,24 +716,13 @@ mrb_struct_equal(mrb_state *mrb, mrb_value s)
if (RSTRUCT_LEN(s) != RSTRUCT_LEN(s2)) {
mrb_bug("inconsistent struct"); /* should never happen */
}
-
- return mrb_exec_recursive_paired(mrb, recursive_equal, s, s2, (void*)0);
-}
-
-static mrb_value
-recursive_eql(mrb_state *mrb, mrb_value s, mrb_value s2, int recur)
-{
- mrb_value *ptr, *ptr2;
- long i, len;
-
- if (recur) return mrb_true_value(); /* Subtle! */
- ptr = RSTRUCT_PTR(s);
- ptr2 = RSTRUCT_PTR(s2);
- len = RSTRUCT_LEN(s);
- for (i=0; i<len; i++) {
- if (!mrb_eql(mrb, ptr[i], ptr2[i])) return mrb_false_value();
- }
- return mrb_true_value();
+ ptr = RSTRUCT_PTR(s);
+ ptr2 = RSTRUCT_PTR(s2);
+ len = RSTRUCT_LEN(s);
+ for (i=0; i<len; i++) {
+ if (!mrb_equal(mrb, ptr[i], ptr2[i])) return mrb_false_value();
+ }
+ return mrb_true_value();
}
/* 15.2.18.4.12(x) */
@@ -766,6 +737,8 @@ static mrb_value
mrb_struct_eql(mrb_state *mrb, mrb_value s)
{
mrb_value s2;
+ mrb_value *ptr, *ptr2;
+ long i, len;
mrb_get_args(mrb, "o", &s2);
if (mrb_obj_equal(mrb, s, s2)) return mrb_true_value();
@@ -775,7 +748,13 @@ mrb_struct_eql(mrb_state *mrb, mrb_value s)
mrb_bug("inconsistent struct"); /* should never happen */
}
- return mrb_exec_recursive_paired(mrb, recursive_eql, s, s2, (void*)0);
+ ptr = RSTRUCT_PTR(s);
+ ptr2 = RSTRUCT_PTR(s2);
+ len = RSTRUCT_LEN(s);
+ for (i=0; i<len; i++) {
+ if (!mrb_eql(mrb, ptr[i], ptr2[i])) return mrb_false_value();
+ }
+ return mrb_true_value();
}
/*