Commit 648b5762 authored by KOBAYASHI Shuji's avatar KOBAYASHI Shuji

range: Embed edges in RRange on boxing environment.

[Breaking changes]

Developers must use following APIs for accessing attributes of RRange
because RRange structure depends on boxing setting.

- mrb_range_beg
- mrb_range_end
- mrb_range_excl_p
parent c6f9a09e
...@@ -14,20 +14,43 @@ ...@@ -14,20 +14,43 @@
*/ */
MRB_BEGIN_DECL MRB_BEGIN_DECL
#if defined(MRB_NAN_BOXING) || defined(MRB_WORD_BOXING)
# define MRB_RANGE_EMBED
#endif
#ifdef MRB_RANGE_EMBED
struct RRange {
MRB_OBJECT_HEADER;
mrb_value beg;
mrb_value end;
mrb_bool excl;
};
# define mrb_gc_free_range(mrb, p) ((void)0)
# define RANGE_BEG(p) ((p)->beg)
# define RANGE_END(p) ((p)->end)
#else
typedef struct mrb_range_edges { typedef struct mrb_range_edges {
mrb_value beg; mrb_value beg;
mrb_value end; mrb_value end;
} mrb_range_edges; } mrb_range_edges;
struct RRange { struct RRange {
MRB_OBJECT_HEADER; MRB_OBJECT_HEADER;
mrb_range_edges *edges; mrb_range_edges *edges;
mrb_bool excl : 1; mrb_bool excl;
}; };
# define mrb_gc_free_range(mrb, p) mrb_free(mrb, ((struct RRange*)p)->edges)
# define RANGE_BEG(p) ((p)->edges->beg)
# define RANGE_END(p) ((p)->edges->end)
#endif
#define mrb_range_beg(mrb, r) RANGE_BEG(mrb_range_ptr(mrb, r))
#define mrb_range_end(mrb, r) RANGE_END(mrb_range_ptr(mrb, r))
#define mrb_range_excl_p(mrb, r) RANGE_EXCL(mrb_range_ptr(mrb, r))
#define mrb_range_raw_ptr(r) ((struct RRange*)mrb_ptr(r))
#define mrb_range_value(p) mrb_obj_value((void*)(p))
#define RANGE_EXCL(p) ((p)->excl)
MRB_API struct RRange* mrb_range_ptr(mrb_state *mrb, mrb_value v); MRB_API struct RRange* mrb_range_ptr(mrb_state *mrb, mrb_value range);
#define mrb_range_raw_ptr(v) ((struct RRange*)mrb_ptr(v))
#define mrb_range_value(p) mrb_obj_value((void*)(p))
/* /*
* Initializes a Range. * Initializes a Range.
...@@ -43,6 +66,7 @@ MRB_API mrb_value mrb_range_new(mrb_state *mrb, mrb_value start, mrb_value end, ...@@ -43,6 +66,7 @@ MRB_API mrb_value mrb_range_new(mrb_state *mrb, mrb_value start, mrb_value end,
MRB_API mrb_int mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len, mrb_bool trunc); MRB_API mrb_int mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len, mrb_bool trunc);
mrb_value mrb_get_values_at(mrb_state *mrb, mrb_value obj, mrb_int olen, mrb_int argc, const mrb_value *argv, mrb_value (*func)(mrb_state*, mrb_value, mrb_int)); mrb_value mrb_get_values_at(mrb_state *mrb, mrb_value obj, mrb_int olen, mrb_int argc, const mrb_value *argv, mrb_value (*func)(mrb_state*, mrb_value, mrb_int));
void mrb_gc_mark_range(mrb_state *mrb, struct RRange *r);
MRB_END_DECL MRB_END_DECL
......
...@@ -48,11 +48,11 @@ mrb_range_cover(mrb_state *mrb, mrb_value range) ...@@ -48,11 +48,11 @@ mrb_range_cover(mrb_state *mrb, mrb_value range)
mrb_get_args(mrb, "o", &val); mrb_get_args(mrb, "o", &val);
beg = r->edges->beg; beg = RANGE_BEG(r);
end = r->edges->end; end = RANGE_END(r);
if (r_le(mrb, beg, val)) { if (r_le(mrb, beg, val)) {
if (r->excl) { if (RANGE_EXCL(r)) {
if (r_lt(mrb, val, end)) if (r_lt(mrb, val, end))
return mrb_true_value(); return mrb_true_value();
} }
...@@ -86,10 +86,9 @@ mrb_range_last(mrb_state *mrb, mrb_value range) ...@@ -86,10 +86,9 @@ mrb_range_last(mrb_state *mrb, mrb_value range)
{ {
mrb_value num; mrb_value num;
mrb_value array; mrb_value array;
struct RRange *r = mrb_range_ptr(mrb, range);
if (mrb_get_args(mrb, "|o", &num) == 0) { if (mrb_get_args(mrb, "|o", &num) == 0) {
return r->edges->end; return mrb_range_end(mrb, range);
} }
array = mrb_funcall(mrb, range, "to_a", 0); array = mrb_funcall(mrb, range, "to_a", 0);
...@@ -116,9 +115,9 @@ mrb_range_size(mrb_state *mrb, mrb_value range) ...@@ -116,9 +115,9 @@ mrb_range_size(mrb_state *mrb, mrb_value range)
mrb_bool num_p = TRUE; mrb_bool num_p = TRUE;
mrb_bool excl; mrb_bool excl;
beg = r->edges->beg; beg = RANGE_BEG(r);
end = r->edges->end; end = RANGE_END(r);
excl = r->excl; excl = RANGE_EXCL(r);
if (mrb_fixnum_p(beg)) { if (mrb_fixnum_p(beg)) {
beg_f = (mrb_float)mrb_fixnum(beg); beg_f = (mrb_float)mrb_fixnum(beg);
} }
......
...@@ -739,14 +739,7 @@ gc_mark_children(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) ...@@ -739,14 +739,7 @@ gc_mark_children(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj)
break; break;
case MRB_TT_RANGE: case MRB_TT_RANGE:
{ mrb_gc_mark_range(mrb, (struct RRange*)obj);
struct RRange *r = (struct RRange*)obj;
if (r->edges) {
mrb_gc_mark_value(mrb, r->edges->beg);
mrb_gc_mark_value(mrb, r->edges->end);
}
}
break; break;
default: default:
...@@ -870,7 +863,7 @@ obj_free(mrb_state *mrb, struct RBasic *obj, int end) ...@@ -870,7 +863,7 @@ obj_free(mrb_state *mrb, struct RBasic *obj, int end)
break; break;
case MRB_TT_RANGE: case MRB_TT_RANGE:
mrb_free(mrb, ((struct RRange*)obj)->edges); mrb_gc_free_range(mrb, ((struct RRange*)obj));
break; break;
case MRB_TT_DATA: case MRB_TT_DATA:
......
This diff is collapsed.
...@@ -93,3 +93,19 @@ assert('Range#eql?', '15.2.14.4.14') do ...@@ -93,3 +93,19 @@ assert('Range#eql?', '15.2.14.4.14') do
assert_false (1..10).eql? (Range.new(1.0, 10.0)) assert_false (1..10).eql? (Range.new(1.0, 10.0))
assert_false (1..10).eql? "1..10" assert_false (1..10).eql? "1..10"
end end
assert('Range#initialize_copy', '15.2.14.4.15') do
assert_raise(NameError) { (0..1).__send__(:initialize_copy, 1..3) }
end
assert('Range#dup') do
r = (1..3).dup
assert_equal r.begin, 1
assert_equal r.end, 3
assert_false r.exclude_end?
r = ("a"..."z").dup
assert_equal r.begin, "a"
assert_equal r.end, "z"
assert_true r.exclude_end?
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment