summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/mruby.h5
-rw-r--r--src/codegen.c18
-rw-r--r--src/gc.c49
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)
{
diff --git a/src/gc.c b/src/gc.c
index 9a630f626..0b01164d5 100644
--- a/src/gc.c
+++ b/src/gc.c
@@ -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());