summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/array.c7
-rw-r--r--src/etc.c6
-rw-r--r--src/gc.c59
-rw-r--r--src/kernel.c4
-rw-r--r--src/object.c2
-rw-r--r--src/range.c4
-rw-r--r--src/string.c2
-rw-r--r--src/vm.c11
8 files changed, 51 insertions, 44 deletions
diff --git a/src/array.c b/src/array.c
index 00b045d51..d4a82c1e6 100644
--- a/src/array.c
+++ b/src/array.c
@@ -15,9 +15,6 @@
#define ARY_SHRINK_RATIO 5 /* must be larger than 2 */
#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-1)
-#define ARY_SHARED_P(a) ((a)->flags & MRB_ARY_SHARED)
-#define ARY_SET_SHARED_FLAG(a) ((a)->flags |= MRB_ARY_SHARED)
-#define ARY_UNSET_SHARED_FLAG(a) ((a)->flags &= ~MRB_ARY_SHARED)
static inline mrb_value
ary_elt(mrb_value ary, mrb_int offset)
@@ -1046,7 +1043,7 @@ mrb_ary_eq(mrb_state *mrb, mrb_value ary1)
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_immediate_p(ary2)) return mrb_false_value();
if (!mrb_array_p(ary2)) {
return mrb_false_value();
}
@@ -1062,7 +1059,7 @@ mrb_ary_cmp(mrb_state *mrb, mrb_value ary1)
mrb_get_args(mrb, "o", &ary2);
if (mrb_obj_equal(mrb, ary1, ary2)) return mrb_fixnum_value(0);
- if (mrb_special_const_p(ary2)) return mrb_nil_value();
+ if (mrb_immediate_p(ary2)) return mrb_nil_value();
if (!mrb_array_p(ary2)) {
return mrb_nil_value();
}
diff --git a/src/etc.c b/src/etc.c
index 9125aa16a..b5cb9ed01 100644
--- a/src/etc.c
+++ b/src/etc.c
@@ -26,7 +26,7 @@ mrb_data_object_alloc(mrb_state *mrb, struct RClass *klass, void *ptr, const mrb
MRB_API void
mrb_data_check_type(mrb_state *mrb, mrb_value obj, const mrb_data_type *type)
{
- if (mrb_special_const_p(obj) || (mrb_type(obj) != MRB_TT_DATA)) {
+ if (mrb_immediate_p(obj) || (mrb_type(obj) != MRB_TT_DATA)) {
mrb_check_type(mrb, obj, MRB_TT_DATA);
}
if (DATA_TYPE(obj) != type) {
@@ -48,7 +48,7 @@ mrb_data_check_type(mrb_state *mrb, mrb_value obj, const mrb_data_type *type)
MRB_API void*
mrb_data_check_get_ptr(mrb_state *mrb, mrb_value obj, const mrb_data_type *type)
{
- if (mrb_special_const_p(obj) || (mrb_type(obj) != MRB_TT_DATA)) {
+ if (mrb_immediate_p(obj) || (mrb_type(obj) != MRB_TT_DATA)) {
return NULL;
}
if (DATA_TYPE(obj) != type) {
@@ -192,7 +192,7 @@ mrb_msvc_va_copy(va_list *dest, va_list src)
{
*dest = src;
}
-#define va_copy(dest, src) msvc_va_copy(&(dest), src)
+#define va_copy(dest, src) mrb_msvc_va_copy(&(dest), src)
#endif
MRB_API int
diff --git a/src/gc.c b/src/gc.c
index 8ff1ecc10..253128a44 100644
--- a/src/gc.c
+++ b/src/gc.c
@@ -63,12 +63,13 @@
== Write Barrier
- mruby implementer and C extension library writer must write a write
- barrier when writing a pointer to an object on object's field.
- Two different write barrier are available:
+ mruby implementer and C extension library writer must insert a write
+ barrier when updating a reference from a field of an object.
+ When updating a reference from a field of object A to object B,
+ two different types of write barrier are available:
- * mrb_field_write_barrier
- * mrb_write_barrier
+ * mrb_field_write_barrier - target B object for a mark.
+ * mrb_write_barrier - target A object for a mark.
== Generational Mode
@@ -389,7 +390,7 @@ gc_protect(mrb_state *mrb, struct RBasic *p)
MRB_API void
mrb_gc_protect(mrb_state *mrb, mrb_value obj)
{
- if (mrb_special_const_p(obj)) return;
+ if (mrb_immediate_p(obj)) return;
gc_protect(mrb, mrb_basic_ptr(obj));
}
@@ -647,7 +648,7 @@ obj_free(mrb_state *mrb, struct RBasic *obj)
break;
case MRB_TT_ARRAY:
- if (obj->flags & MRB_ARY_SHARED)
+ if (ARY_SHARED_P(obj))
mrb_ary_decref(mrb, ((struct RArray*)obj)->aux.shared);
else
mrb_free(mrb, ((struct RArray*)obj)->ptr);
@@ -862,7 +863,7 @@ incremental_sweep_phase(mrb_state *mrb, size_t limit)
RVALUE *e = p + MRB_HEAP_PAGE_SIZE;
size_t freed = 0;
mrb_bool dead_slot = TRUE;
- int full = (page->freelist == NULL);
+ mrb_bool full = (page->freelist == NULL);
if (is_minor_gc(mrb) && page->old) {
/* skip a slot which doesn't contain any young object */
@@ -917,7 +918,7 @@ static size_t
incremental_gc(mrb_state *mrb, size_t limit)
{
switch (mrb->gc_state) {
- case GC_STATE_NONE:
+ case GC_STATE_ROOT:
root_scan_phase(mrb);
mrb->gc_state = GC_STATE_MARK;
flip_white_part(mrb);
@@ -935,7 +936,7 @@ incremental_gc(mrb_state *mrb, size_t limit)
size_t tried_sweep = 0;
tried_sweep = incremental_sweep_phase(mrb, limit);
if (tried_sweep == 0)
- mrb->gc_state = GC_STATE_NONE;
+ mrb->gc_state = GC_STATE_ROOT;
return tried_sweep;
}
default:
@@ -960,7 +961,7 @@ incremental_gc_step(mrb_state *mrb)
limit = (GC_STEP_SIZE/100) * mrb->gc_step_ratio;
while (result < limit) {
result += incremental_gc(mrb, limit);
- if (mrb->gc_state == GC_STATE_NONE)
+ if (mrb->gc_state == GC_STATE_ROOT)
break;
}
@@ -975,17 +976,17 @@ clear_all_old(mrb_state *mrb)
mrb_assert(is_generational(mrb));
if (is_major_gc(mrb)) {
/* finish the half baked GC */
- incremental_gc_until(mrb, GC_STATE_NONE);
+ incremental_gc_until(mrb, GC_STATE_ROOT);
}
/* Sweep the dead objects, then reset all the live objects
* (including all the old objects, of course) to white. */
mrb->is_generational_gc_mode = FALSE;
prepare_incremental_sweep(mrb);
- incremental_gc_until(mrb, GC_STATE_NONE);
+ incremental_gc_until(mrb, GC_STATE_ROOT);
mrb->is_generational_gc_mode = origin_mode;
- /* The gray objects has already been painted as white */
+ /* The gray objects have already been painted as white */
mrb->atomic_gray_list = mrb->gray_list = NULL;
}
@@ -998,13 +999,13 @@ mrb_incremental_gc(mrb_state *mrb)
GC_TIME_START;
if (is_minor_gc(mrb)) {
- incremental_gc_until(mrb, GC_STATE_NONE);
+ incremental_gc_until(mrb, GC_STATE_ROOT);
}
else {
incremental_gc_step(mrb);
}
- if (mrb->gc_state == GC_STATE_NONE) {
+ if (mrb->gc_state == GC_STATE_ROOT) {
mrb_assert(mrb->live >= mrb->gc_live_after_mark);
mrb->gc_threshold = (mrb->gc_live_after_mark/100) * mrb->gc_interval_ratio;
if (mrb->gc_threshold < GC_STEP_SIZE) {
@@ -1039,12 +1040,12 @@ mrb_full_gc(mrb_state *mrb)
clear_all_old(mrb);
mrb->gc_full = TRUE;
}
- else if (mrb->gc_state != GC_STATE_NONE) {
+ else if (mrb->gc_state != GC_STATE_ROOT) {
/* finish half baked GC cycle */
- incremental_gc_until(mrb, GC_STATE_NONE);
+ incremental_gc_until(mrb, GC_STATE_ROOT);
}
- incremental_gc_until(mrb, GC_STATE_NONE);
+ incremental_gc_until(mrb, GC_STATE_ROOT);
mrb->gc_threshold = (mrb->gc_live_after_mark/100) * mrb->gc_interval_ratio;
if (is_generational(mrb)) {
@@ -1099,7 +1100,7 @@ mrb_field_write_barrier(mrb_state *mrb, struct RBasic *obj, struct RBasic *value
if (!is_white(value)) return;
mrb_assert(!is_dead(mrb, value) && !is_dead(mrb, obj));
- mrb_assert(is_generational(mrb) || mrb->gc_state != GC_STATE_NONE);
+ mrb_assert(is_generational(mrb) || mrb->gc_state != GC_STATE_ROOT);
if (is_generational(mrb) || mrb->gc_state == GC_STATE_MARK) {
add_gray_list(mrb, value);
@@ -1125,7 +1126,7 @@ mrb_write_barrier(mrb_state *mrb, struct RBasic *obj)
if (!is_black(obj)) return;
mrb_assert(!is_dead(mrb, obj));
- mrb_assert(is_generational(mrb) || mrb->gc_state != GC_STATE_NONE);
+ mrb_assert(is_generational(mrb) || mrb->gc_state != GC_STATE_ROOT);
paint_gray(obj);
obj->gcnext = mrb->atomic_gray_list;
mrb->atomic_gray_list = obj;
@@ -1262,11 +1263,11 @@ change_gen_gc_mode(mrb_state *mrb, mrb_bool enable)
{
if (is_generational(mrb) && !enable) {
clear_all_old(mrb);
- mrb_assert(mrb->gc_state == GC_STATE_NONE);
+ mrb_assert(mrb->gc_state == GC_STATE_ROOT);
mrb->gc_full = FALSE;
}
else if (!is_generational(mrb) && enable) {
- incremental_gc_until(mrb, GC_STATE_NONE);
+ incremental_gc_until(mrb, GC_STATE_ROOT);
mrb->majorgc_old_threshold = mrb->gc_live_after_mark/100 * DEFAULT_MAJOR_GC_INC_RATIO;
mrb->gc_full = FALSE;
}
@@ -1515,8 +1516,8 @@ test_incremental_gc(void)
puts(" in mrb_full_gc");
mrb_full_gc(mrb);
- mrb_assert(mrb->gc_state == GC_STATE_NONE);
- puts(" in GC_STATE_NONE");
+ mrb_assert(mrb->gc_state == GC_STATE_ROOT);
+ puts(" in GC_STATE_ROOT");
incremental_gc(mrb, max);
mrb_assert(mrb->gc_state == GC_STATE_MARK);
puts(" in GC_STATE_MARK");
@@ -1547,7 +1548,7 @@ test_incremental_gc(void)
mrb_assert(mrb->gc_state == GC_STATE_SWEEP);
incremental_gc(mrb, max);
- mrb_assert(mrb->gc_state == GC_STATE_NONE);
+ mrb_assert(mrb->gc_state == GC_STATE_ROOT);
free = (RVALUE*)mrb->heaps->freelist;
while (free) {
@@ -1563,7 +1564,7 @@ test_incremental_gc(void)
change_gen_gc_mode(mrb, TRUE);
mrb_assert(mrb->gc_full == FALSE);
- mrb_assert(mrb->gc_state == GC_STATE_NONE);
+ mrb_assert(mrb->gc_state == GC_STATE_ROOT);
puts(" in minor");
mrb_assert(is_minor_gc(mrb));
@@ -1571,13 +1572,13 @@ test_incremental_gc(void)
mrb->majorgc_old_threshold = 0;
mrb_incremental_gc(mrb);
mrb_assert(mrb->gc_full == TRUE);
- mrb_assert(mrb->gc_state == GC_STATE_NONE);
+ mrb_assert(mrb->gc_state == GC_STATE_ROOT);
puts(" in major");
mrb_assert(is_major_gc(mrb));
do {
mrb_incremental_gc(mrb);
- } while (mrb->gc_state != GC_STATE_NONE);
+ } while (mrb->gc_state != GC_STATE_ROOT);
mrb_assert(mrb->gc_full == FALSE);
mrb_close(mrb);
diff --git a/src/kernel.c b/src/kernel.c
index 62e1bee09..7ff94c1d9 100644
--- a/src/kernel.c
+++ b/src/kernel.c
@@ -317,7 +317,7 @@ mrb_obj_clone(mrb_state *mrb, mrb_value self)
struct RObject *p;
mrb_value clone;
- if (mrb_special_const_p(self)) {
+ if (mrb_immediate_p(self)) {
mrb_raisef(mrb, E_TYPE_ERROR, "can't clone %S", self);
}
p = (struct RObject*)mrb_obj_alloc(mrb, mrb_type(self), mrb_obj_class(mrb, self));
@@ -353,7 +353,7 @@ mrb_obj_dup(mrb_state *mrb, mrb_value obj)
struct RBasic *p;
mrb_value dup;
- if (mrb_special_const_p(obj)) {
+ if (mrb_immediate_p(obj)) {
mrb_raisef(mrb, E_TYPE_ERROR, "can't dup %S", obj);
}
p = mrb_obj_alloc(mrb, mrb_type(obj), mrb_obj_class(mrb, obj));
diff --git a/src/object.c b/src/object.c
index 8c278f1f9..ba03f34ef 100644
--- a/src/object.c
+++ b/src/object.c
@@ -407,7 +407,7 @@ mrb_check_type(mrb_state *mrb, mrb_value x, enum mrb_vtype t)
else if (mrb_type(x) == MRB_TT_SYMBOL) {
etype = "Symbol";
}
- else if (mrb_special_const_p(x)) {
+ else if (mrb_immediate_p(x)) {
etype = RSTRING_PTR(mrb_obj_as_string(mrb, x));
}
else {
diff --git a/src/range.c b/src/range.c
index 3ce31d684..e96e7a6ba 100644
--- a/src/range.c
+++ b/src/range.c
@@ -234,7 +234,7 @@ mrb_range_include(mrb_state *mrb, mrb_value range)
return mrb_bool_value(include_p);
}
-MRB_API mrb_bool
+static mrb_bool
range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len, mrb_bool trunc)
{
mrb_int beg, end, b, e;
@@ -266,7 +266,7 @@ range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb
return TRUE;
}
-mrb_bool
+MRB_API mrb_bool
mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len)
{
return range_beg_len(mrb, range, begp, lenp, len, TRUE);
diff --git a/src/string.c b/src/string.c
index 8ac5a436a..66777d9e5 100644
--- a/src/string.c
+++ b/src/string.c
@@ -306,7 +306,7 @@ mrb_gc_free_str(mrb_state *mrb, struct RString *str)
mrb_free(mrb, str->as.heap.ptr);
}
-MRB_API const char*
+MRB_API char*
mrb_str_to_cstr(mrb_state *mrb, mrb_value str0)
{
struct RString *s;
diff --git a/src/vm.c b/src/vm.c
index 9a694bef4..4b7a30d71 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -1,4 +1,4 @@
- /*
+/*
** vm.c - virtual machine for mruby
**
** See Copyright Notice in mruby.h
@@ -2175,6 +2175,15 @@ RETRY_TRY_BLOCK:
}
else {
p = mrb_proc_new(mrb, irep->reps[GETARG_b(i)]);
+ if (c & OP_L_METHOD) {
+ if (p->target_class->tt == MRB_TT_SCLASS) {
+ mrb_value klass;
+ klass = mrb_obj_iv_get(mrb,
+ (struct RObject *)p->target_class,
+ mrb_intern_lit(mrb, "__attached__"));
+ p->target_class = mrb_class_ptr(klass);
+ }
+ }
}
if (c & OP_L_STRICT) p->flags |= MRB_PROC_STRICT;
regs[GETARG_A(i)] = mrb_obj_value(p);