diff options
| -rw-r--r-- | include/mruby.h | 5 | ||||
| -rw-r--r-- | src/codegen.c | 18 | ||||
| -rw-r--r-- | src/gc.c | 49 |
3 files changed, 67 insertions, 5 deletions
diff --git a/include/mruby.h b/include/mruby.h index dbd6b2650..353ff93f4 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -268,8 +268,9 @@ typedef struct mrb_state { struct RBasic *variable_gray_list; /* list of objects to be traversed atomically */ size_t gc_live_after_mark; size_t gc_threshold; - mrb_int gc_interval_ratio; - mrb_int gc_step_ratio; + int gc_interval_ratio; + int gc_step_ratio; + int gc_disabled; mrb_sym symidx; struct kh_n2s *name2sym; /* symbol table */ diff --git a/src/codegen.c b/src/codegen.c index bf6fd0b3e..4f118753e 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -142,6 +142,9 @@ genop(codegen_scope *s, mrb_code i) s->pc++; } +#define NOVAL 0 +#define VAL 1 + static void genop_peep(codegen_scope *s, mrb_code i, int val) { @@ -217,6 +220,7 @@ genop_peep(codegen_scope *s, mrb_code i, int val) case OP_SETCV: case OP_SETCONST: case OP_SETMCNST: + case OP_SETGLOBAL: if (c0 == OP_MOVE) { if (GETARG_A(i) == GETARG_A(i0)) { s->iseq[s->pc-1] = MKOP_ABx(c1, GETARG_B(i0), GETARG_Bx(i)); @@ -261,6 +265,17 @@ genop_peep(codegen_scope *s, mrb_code i, int val) s->iseq[s->pc-1] = MKOP_ABC(c0, 0, GETARG_B(i0), GETARG_C(i0)); genop(s, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL)); return; + case OP_SETIV: + case OP_SETCV: + case OP_SETCONST: + case OP_SETMCNST: + case OP_SETUPVAR: + case OP_SETGLOBAL: + s->pc--; + genop_peep(s, i0, NOVAL); + i0 = s->iseq[s->pc-1]; + genop(s, MKOP_AB(OP_RETURN, GETARG_A(i0), OP_R_NORMAL)); + return; case OP_LOADSYM: case OP_GETGLOBAL: case OP_GETIV: @@ -436,9 +451,6 @@ lv_idx(codegen_scope *s, mrb_sym id) return 0; } -#define NOVAL 0 -#define VAL 1 - static void for_body(codegen_scope *s, node *tree) { @@ -796,6 +796,7 @@ mrb_incremental_gc(mrb_state *mrb) { size_t limit = 0, result = 0; + if (mrb->gc_disabled) return; GC_INVOKE_TIME_REPORT; GC_TIME_START; @@ -826,6 +827,7 @@ mrb_garbage_collect(mrb_state *mrb) { size_t max_limit = ~0; + if (mrb->gc_disabled) return; GC_INVOKE_TIME_REPORT; GC_TIME_START; @@ -918,6 +920,51 @@ gc_start(mrb_state *mrb, mrb_value obj) /* * call-seq: + * GC.enable -> true or false + * + * Enables garbage collection, returning <code>true</code> if garbage + * collection was previously disabled. + * + * GC.disable #=> false + * GC.enable #=> true + * GC.enable #=> false + * + */ + +static mrb_value +gc_enable(mrb_state *mrb, mrb_value obj) +{ + int old = mrb->gc_disabled; + + mrb->gc_disabled = FALSE; + if (old) return mrb_true_value(); + return mrb_false_value(); +} + +/* + * call-seq: + * GC.disable -> true or false + * + * Disables garbage collection, returning <code>true</code> if garbage + * collection was already disabled. + * + * GC.disable #=> false + * GC.disable #=> true + * + */ + +static mrb_value +gc_disable(mrb_state *mrb, mrb_value obj) +{ + int old = mrb->gc_disabled; + + mrb->gc_disabled = TRUE; + if (old) return mrb_true_value(); + return mrb_false_value(); +} + +/* + * call-seq: * GC.interval_ratio -> fixnum * * Returns ratio of GC interval. Default value is 200(%). @@ -989,6 +1036,8 @@ mrb_init_gc(mrb_state *mrb) gc = mrb_define_module(mrb, "GC"); mrb_define_class_method(mrb, gc, "start", gc_start, ARGS_NONE()); + mrb_define_class_method(mrb, gc, "enable", gc_enable, ARGS_NONE()); + mrb_define_class_method(mrb, gc, "disable", gc_disable, ARGS_NONE()); mrb_define_class_method(mrb, gc, "interval_ratio", gc_interval_ratio_get, ARGS_NONE()); mrb_define_class_method(mrb, gc, "interval_ratio=", gc_interval_ratio_set, ARGS_REQ(1)); mrb_define_class_method(mrb, gc, "step_ratio", gc_step_ratio_get, ARGS_NONE()); |
