summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/mruby.h2
-rw-r--r--include/mruby/array.h3
-rw-r--r--include/mruby/string.h21
-rw-r--r--mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c2
-rw-r--r--mrbgems/mruby-enumerator/mrblib/enumerator.rb4
-rw-r--r--mrbgems/mruby-eval/src/eval.c3
-rw-r--r--mrbgems/mruby-eval/test/eval.rb13
-rw-r--r--mrbgems/mruby-math/test/math.rb16
-rw-r--r--mrbgems/mruby-string-ext/src/string.c74
-rw-r--r--mrbgems/mruby-string-ext/test/string.rb109
-rw-r--r--mrbgems/mruby-time/src/time.c2
-rw-r--r--mrblib/error.rb3
-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
-rw-r--r--test/t/class.rb13
21 files changed, 292 insertions, 68 deletions
diff --git a/include/mruby.h b/include/mruby.h
index 1337d7285..480080e8b 100644
--- a/include/mruby.h
+++ b/include/mruby.h
@@ -99,7 +99,7 @@ struct mrb_context {
};
enum gc_state {
- GC_STATE_NONE = 0,
+ GC_STATE_ROOT = 0,
GC_STATE_MARK,
GC_STATE_SWEEP
};
diff --git a/include/mruby/array.h b/include/mruby/array.h
index 9f1ef4d2f..c984c16a7 100644
--- a/include/mruby/array.h
+++ b/include/mruby/array.h
@@ -34,6 +34,9 @@ struct RArray {
#define RARRAY_LEN(a) (RARRAY(a)->len)
#define RARRAY_PTR(a) (RARRAY(a)->ptr)
#define MRB_ARY_SHARED 256
+#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)
void mrb_ary_decref(mrb_state*, mrb_shared_array*);
MRB_API void mrb_ary_modify(mrb_state*, struct RArray*);
diff --git a/include/mruby/string.h b/include/mruby/string.h
index 70ace95ae..0bd4cfc0f 100644
--- a/include/mruby/string.h
+++ b/include/mruby/string.h
@@ -101,29 +101,16 @@ MRB_API mrb_value mrb_str_cat_str(mrb_state *mrb, mrb_value str, mrb_value str2)
MRB_API mrb_value mrb_str_append(mrb_state *mrb, mrb_value str, mrb_value str2);
MRB_API int mrb_str_cmp(mrb_state *mrb, mrb_value str1, mrb_value str2);
-MRB_API const char *mrb_str_to_cstr(mrb_state *mrb, mrb_value str);
+MRB_API char *mrb_str_to_cstr(mrb_state *mrb, mrb_value str);
mrb_value mrb_str_pool(mrb_state *mrb, mrb_value str);
mrb_int mrb_str_hash(mrb_state *mrb, mrb_value str);
mrb_value mrb_str_dump(mrb_state *mrb, mrb_value str);
mrb_value mrb_str_inspect(mrb_state *mrb, mrb_value str);
/* For backward compatibility */
-static inline mrb_value
-mrb_str_cat2(mrb_state *mrb, mrb_value str, const char *ptr) {
- return mrb_str_cat_cstr(mrb, str, ptr);
-}
-
-static inline mrb_value
-mrb_str_buf_cat(mrb_state *mrb, mrb_value str, const char *ptr, size_t len)
-{
- return mrb_str_cat(mrb, str, ptr, len);
-}
-
-static inline mrb_value
-mrb_str_buf_append(mrb_state *mrb, mrb_value str, mrb_value str2)
-{
- return mrb_str_cat_str(mrb, str, str2);
-}
+#define mrb_str_cat2(mrb, str, ptr) mrb_str_cat_cstr(mrb, str, ptr)
+#define mrb_str_buf_cat(mrb, str, ptr, len) mrb_str_cat(mrb, str, ptr, len)
+#define mrb_str_buf_append(mrb, str, str2) mrb_str_cat_str(mrb, str, str2)
#if defined(__cplusplus)
} /* extern "C" { */
diff --git a/mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c b/mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c
index 75d6d49fd..7fe1ebfa1 100644
--- a/mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c
+++ b/mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c
@@ -142,7 +142,7 @@ main(int argc, char **argv)
print_usage(argv[0]);
return EXIT_FAILURE;
}
- mrb = mrb_open();
+ mrb = mrb_open_core(mrb_default_allocf, NULL);
if (mrb == NULL) {
fputs("Invalid mrb_state, exiting mruby-strip\n", stderr);
return EXIT_FAILURE;
diff --git a/mrbgems/mruby-enumerator/mrblib/enumerator.rb b/mrbgems/mruby-enumerator/mrblib/enumerator.rb
index 58996adc8..c54959e91 100644
--- a/mrbgems/mruby-enumerator/mrblib/enumerator.rb
+++ b/mrbgems/mruby-enumerator/mrblib/enumerator.rb
@@ -549,10 +549,6 @@ class Enumerator
end
end
-class StopIteration < IndexError
- attr_accessor :result
-end
-
module Kernel
##
# call-seq:
diff --git a/mrbgems/mruby-eval/src/eval.c b/mrbgems/mruby-eval/src/eval.c
index ece769faf..56f4877cc 100644
--- a/mrbgems/mruby-eval/src/eval.c
+++ b/mrbgems/mruby-eval/src/eval.c
@@ -132,6 +132,9 @@ create_proc_from_string(mrb_state *mrb, char *s, int len, mrb_value binding, cha
}
proc = mrb_generate_code(mrb, p);
+ if (mrb->c->ci[-1].proc->target_class) {
+ proc->target_class = mrb->c->ci[-1].proc->target_class;
+ }
e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV, (struct RClass*)mrb->c->ci[-1].proc->env);
e->mid = mrb->c->ci[-1].mid;
e->cioff = mrb->c->ci - mrb->c->cibase - 1;
diff --git a/mrbgems/mruby-eval/test/eval.rb b/mrbgems/mruby-eval/test/eval.rb
index 87c64732d..a4e7786da 100644
--- a/mrbgems/mruby-eval/test/eval.rb
+++ b/mrbgems/mruby-eval/test/eval.rb
@@ -60,3 +60,16 @@ assert('String instance_eval') do
assert_equal('test') { obj.instance_eval('@test') }
assert_equal('test') { obj.instance_eval { @test } }
end
+
+assert('Kernel.#eval(string) context') do
+ class TestEvalConstScope
+ EVAL_CONST_CLASS = 'class'
+ def const_string
+ eval 'EVAL_CONST_CLASS'
+ end
+ end
+ obj = TestEvalConstScope.new
+ assert_raise(NameError) { eval 'EVAL_CONST_CLASS' }
+ assert_equal('class') { obj.const_string }
+end
+
diff --git a/mrbgems/mruby-math/test/math.rb b/mrbgems/mruby-math/test/math.rb
index 1cc3a20b0..e9ea07cc1 100644
--- a/mrbgems/mruby-math/test/math.rb
+++ b/mrbgems/mruby-math/test/math.rb
@@ -23,6 +23,22 @@ assert('Math.sin PI/2') do
check_float(Math.sin(Math::PI / 2), 1)
end
+assert('Math.cos 0') do
+ check_float(Math.cos(0), 1)
+end
+
+assert('Math.cos PI/2') do
+ check_float(Math.cos(Math::PI / 2), 0)
+end
+
+assert('Math.tan 0') do
+ check_float(Math.tan(0), 0)
+end
+
+assert('Math.tan PI/4') do
+ check_float(Math.tan(Math::PI / 4), 1)
+end
+
assert('Fundamental trig identities') do
result = true
N = 13
diff --git a/mrbgems/mruby-string-ext/src/string.c b/mrbgems/mruby-string-ext/src/string.c
index f04f12c4b..2d745589b 100644
--- a/mrbgems/mruby-string-ext/src/string.c
+++ b/mrbgems/mruby-string-ext/src/string.c
@@ -239,6 +239,76 @@ mrb_str_lines(mrb_state *mrb, mrb_value self)
return result;
}
+/*
+ * call-seq:
+ * string.succ -> string
+ *
+ * Returns next sequence of the string;
+ *
+ * a = "abc"
+ * a.succ #=> "abd"
+ */
+static mrb_value
+mrb_str_succ_bang(mrb_state *mrb, mrb_value self)
+{
+ mrb_value result;
+ char *p, *e, *b, *t, *prepend;
+ struct RString *s = mrb_str_ptr(self);
+ size_t l;
+
+ if (RSTRING_LEN(self) == 0)
+ return self;
+
+ mrb_str_modify(mrb, s);
+ l = RSTRING_LEN(self);
+ b = p = RSTRING_PTR(self);
+ t = e = p + l;
+ *(e--) = 0;
+
+ while (b < e) {
+ if (ISALNUM(*b))
+ break;
+ b++;
+ }
+ result = mrb_str_new(mrb, p, b - p);
+
+ while (e >= b) {
+ if (!ISALNUM(*e))
+ break;
+ prepend = NULL;
+ if (*e == '9') {
+ if (e == b) prepend = "1";
+ *e = '0';
+ } else if (*e == 'z') {
+ if (e == b) prepend = "a";
+ *e = 'a';
+ } else if (*e == 'Z') {
+ if (e == b) prepend = "A";
+ *e = 'A';
+ } else {
+ (*e)++;
+ break;
+ }
+ if (prepend) mrb_str_cat_cstr(mrb, result, prepend);
+ e--;
+ }
+ result = mrb_str_cat(mrb, result, b, t - b);
+ l = RSTRING_LEN(result);
+ mrb_str_resize(mrb, self, l);
+ memcpy(RSTRING_PTR(self), RSTRING_PTR(result), l);
+ return self;
+}
+
+static mrb_value
+mrb_str_succ(mrb_state *mrb, mrb_value self)
+{
+ mrb_value str;
+
+ str = mrb_str_dup(mrb, self);
+ mrb_str_succ_bang(mrb, str);
+ return str;
+}
+
void
mrb_mruby_string_ext_gem_init(mrb_state* mrb)
{
@@ -256,6 +326,10 @@ mrb_mruby_string_ext_gem_init(mrb_state* mrb)
mrb_define_method(mrb, s, "oct", mrb_str_oct, MRB_ARGS_NONE());
mrb_define_method(mrb, s, "chr", mrb_str_chr, MRB_ARGS_NONE());
mrb_define_method(mrb, s, "lines", mrb_str_lines, MRB_ARGS_NONE());
+ mrb_define_method(mrb, s, "succ", mrb_str_succ, MRB_ARGS_NONE());
+ mrb_define_method(mrb, s, "succ!", mrb_str_succ_bang, MRB_ARGS_NONE());
+ mrb_alias_method(mrb, s, mrb_intern_lit(mrb, "next"), mrb_intern_lit(mrb, "succ"));
+ mrb_alias_method(mrb, s, mrb_intern_lit(mrb, "next!"), mrb_intern_lit(mrb, "succ!"));
}
void
diff --git a/mrbgems/mruby-string-ext/test/string.rb b/mrbgems/mruby-string-ext/test/string.rb
index 2a8dd0cca..4067abdbf 100644
--- a/mrbgems/mruby-string-ext/test/string.rb
+++ b/mrbgems/mruby-string-ext/test/string.rb
@@ -251,3 +251,112 @@ assert('String#slice!') do
assert_raise(ArgumentError) { "foo".slice! }
end
+
+assert('String#succ') do
+ assert_equal "", "".succ
+ assert_equal "1", "0".succ
+ assert_equal "10", "9".succ
+ assert_equal "01", "00".succ
+ assert_equal "a1", "a0".succ
+ assert_equal "A1", "A0".succ
+ assert_equal "10", "09".succ
+ assert_equal "b0", "a9".succ
+ assert_equal "B0", "A9".succ
+
+ assert_equal "b", "a".succ
+ assert_equal "aa", "z".succ
+ assert_equal "ab", "aa".succ
+ assert_equal "Ab", "Aa".succ
+ assert_equal "0b", "0a".succ
+ assert_equal "ba", "az".succ
+ assert_equal "Ba", "Az".succ
+ assert_equal "1a", "0z".succ
+
+ assert_equal "B", "A".succ
+ assert_equal "AA", "Z".succ
+ assert_equal "AB", "AA".succ
+ assert_equal "aB", "aA".succ
+ assert_equal "0B", "0A".succ
+ assert_equal "BA", "AZ".succ
+ assert_equal "bA", "aZ".succ
+ assert_equal "1A", "0Z".succ
+
+ assert_equal "-", "-".succ
+ assert_equal "-b", "-a".succ
+ assert_equal "-aa", "-z".succ
+ assert_equal "あb", "あa".succ
+ assert_equal "あba", "あaz".succ
+
+ a = ""; a.succ!
+ assert_equal "", a
+ a = "0"; a.succ!
+ assert_equal "1", a
+ a = "9"; a.succ!
+ assert_equal "10", a
+ a = "00"; a.succ!
+ assert_equal "01", a
+ a = "a0"; a.succ!
+ assert_equal "a1", a
+ a = "A0"; a.succ!
+ assert_equal "A1", a
+ a = "09"; a.succ!
+ assert_equal "10", a
+ a = "a9"; a.succ!
+ assert_equal "b0", a
+ a = "A9"; a.succ!
+ assert_equal "B0", a
+
+ a = "a"; a.succ!
+ assert_equal "b", a
+ a = "z"; a.succ!
+ assert_equal "aa", a
+ a = "aa"; a.succ!
+ assert_equal "ab", a
+ a = "Aa"; a.succ!
+ assert_equal "Ab", a
+ a = "0a"; a.succ!
+ assert_equal "0b", a
+ a = "az"; a.succ!
+ assert_equal "ba", a
+ a = "Az"; a.succ!
+ assert_equal "Ba", a
+ a = "0z"; a.succ!
+ assert_equal "1a", a
+
+ a = "A"; a.succ!
+ assert_equal "B", a
+ a = "Z"; a.succ!
+ assert_equal "AA", a
+ a = "AA"; a.succ!
+ assert_equal "AB", a
+ a = "aA"; a.succ!
+ assert_equal "aB", a
+ a = "0A"; a.succ!
+ assert_equal "0B", a
+ a = "AZ"; a.succ!
+ assert_equal "BA", a
+ a = "aZ"; a.succ!
+ assert_equal "bA", a
+ a = "0Z"; a.succ!
+ assert_equal "1A", a
+
+ a = "-"; a.succ!
+ assert_equal "-", a
+ a = "-a"; a.succ!
+ assert_equal "-b", a
+ a = "-z"; a.succ!
+ assert_equal "-aa", a
+ a = "あ"; a.succ!
+ assert_equal "あ", a
+ a = "あa"; a.succ!
+ assert_equal "あb", a
+ a = "あaz"; a.succ!
+ assert_equal "あba", a
+end
+
+assert('String#next') do
+ assert_equal "01", "00".next
+
+ a = "00"; a.next!
+ assert_equal "01", a
+end
diff --git a/mrbgems/mruby-time/src/time.c b/mrbgems/mruby-time/src/time.c
index f9dd0cb33..009c01acb 100644
--- a/mrbgems/mruby-time/src/time.c
+++ b/mrbgems/mruby-time/src/time.c
@@ -80,7 +80,7 @@ gettimeofday(struct timeval *tv, void *tz)
t.u64 -= UI64(116444736000000000); /* Unix epoch bias */
t.u64 /= 10; /* to microseconds */
tv->tv_sec = (time_t)(t.u64 / (1000 * 1000));
- tv->tv_usec = t.u64 % 1000 * 1000;
+ tv->tv_usec = t.u64 % (1000 * 1000);
}
return 0;
}
diff --git a/mrblib/error.rb b/mrblib/error.rb
index a5b6b3223..d76dd9c56 100644
--- a/mrblib/error.rb
+++ b/mrblib/error.rb
@@ -66,3 +66,6 @@ end
class NotImplementedError < ScriptError
end
+class StopIteration < IndexError
+ attr_accessor :result
+end
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);
diff --git a/test/t/class.rb b/test/t/class.rb
index f49ccf494..d4ecf99d0 100644
--- a/test/t/class.rb
+++ b/test/t/class.rb
@@ -370,3 +370,16 @@ assert('clone Class') do
Foo.clone.new.func
end
+
+assert('class variable and class << self style class method') do
+ class ClassVariableTest
+ @@class_variable = "value"
+ class << self
+ def class_variable
+ @@class_variable
+ end
+ end
+ end
+
+ assert_equal("value", ClassVariableTest.class_variable)
+end