diff options
| -rw-r--r-- | include/mruby.h | 2 | ||||
| -rw-r--r-- | include/mruby/array.h | 3 | ||||
| -rw-r--r-- | include/mruby/string.h | 21 | ||||
| -rw-r--r-- | mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c | 2 | ||||
| -rw-r--r-- | mrbgems/mruby-enumerator/mrblib/enumerator.rb | 4 | ||||
| -rw-r--r-- | mrbgems/mruby-eval/src/eval.c | 3 | ||||
| -rw-r--r-- | mrbgems/mruby-eval/test/eval.rb | 13 | ||||
| -rw-r--r-- | mrbgems/mruby-math/test/math.rb | 16 | ||||
| -rw-r--r-- | mrbgems/mruby-string-ext/src/string.c | 74 | ||||
| -rw-r--r-- | mrbgems/mruby-string-ext/test/string.rb | 109 | ||||
| -rw-r--r-- | mrbgems/mruby-time/src/time.c | 2 | ||||
| -rw-r--r-- | mrblib/error.rb | 3 | ||||
| -rw-r--r-- | src/array.c | 7 | ||||
| -rw-r--r-- | src/etc.c | 6 | ||||
| -rw-r--r-- | src/gc.c | 59 | ||||
| -rw-r--r-- | src/kernel.c | 4 | ||||
| -rw-r--r-- | src/object.c | 2 | ||||
| -rw-r--r-- | src/range.c | 4 | ||||
| -rw-r--r-- | src/string.c | 2 | ||||
| -rw-r--r-- | src/vm.c | 11 | ||||
| -rw-r--r-- | test/t/class.rb | 13 |
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(); } @@ -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 @@ -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; @@ -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 |
