summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--mrbgems/mruby-catch/src/catch.c16
-rw-r--r--src/class.c27
-rw-r--r--src/proc.c19
3 files changed, 39 insertions, 23 deletions
diff --git a/mrbgems/mruby-catch/src/catch.c b/mrbgems/mruby-catch/src/catch.c
index d910cac7f..148639530 100644
--- a/mrbgems/mruby-catch/src/catch.c
+++ b/mrbgems/mruby-catch/src/catch.c
@@ -61,21 +61,20 @@ static const mrb_irep catch_irep = {
29,0,3,1,0
};
-#define ID_PRESERVED_CATCH MRB_SYM(__preserved_catch_proc)
+static const struct RProc catch_proc = {
+ NULL, NULL, MRB_TT_PROC, 7 /* GC_RED */, MRB_FL_OBJ_IS_FROZEN | MRB_PROC_SCOPE | MRB_PROC_STRICT,
+ { &catch_irep }, NULL, { NULL }
+};
static const mrb_callinfo *
find_catcher(mrb_state *mrb, mrb_value tag)
{
- mrb_value pval = mrb_obj_iv_get(mrb, (struct RObject *)mrb->kernel_module, ID_PRESERVED_CATCH);
- mrb_assert(mrb_proc_p(pval));
- const struct RProc *proc = mrb_proc_ptr(pval);
-
const mrb_callinfo *ci = mrb->c->ci;
size_t n = ci - mrb->c->cibase;
ci--;
for (; n > 0; n--, ci--) {
const mrb_value *arg1 = ci->stack + 1;
- if (ci->proc == proc && mrb_obj_eq(mrb, *arg1, tag)) {
+ if (ci->proc == &catch_proc && mrb_obj_eq(mrb, *arg1, tag)) {
return ci;
}
}
@@ -109,15 +108,12 @@ mrb_f_throw(mrb_state *mrb, mrb_value self)
void
mrb_mruby_catch_gem_init(mrb_state *mrb)
{
- struct RProc *p;
mrb_method_t m;
MRB_PRESYM_INIT_SYMBOLS(mrb, catch_syms_3);
MRB_PRESYM_INIT_SYMBOLS(mrb, catch_syms_1);
- p = mrb_proc_new(mrb, &catch_irep);
- MRB_METHOD_FROM_PROC(m, p);
+ MRB_METHOD_FROM_PROC(m, &catch_proc);
mrb_define_method_raw(mrb, mrb->kernel_module, MRB_SYM(catch), m);
- mrb_obj_iv_set(mrb, (struct RObject *)mrb->kernel_module, ID_PRESERVED_CATCH, mrb_obj_value(p));
mrb_define_method(mrb, mrb->kernel_module, "throw", mrb_f_throw, MRB_ARGS_ARG(1,1));
}
diff --git a/src/class.c b/src/class.c
index 09e52d24a..33a65f7d6 100644
--- a/src/class.c
+++ b/src/class.c
@@ -736,11 +736,17 @@ mrb_define_method_raw(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_method_
ptr.proc = p;
if (p) {
- p->flags |= MRB_PROC_SCOPE;
- p->c = NULL;
- mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)p);
- if (!MRB_PROC_ENV_P(p)) {
- MRB_PROC_SET_TARGET_CLASS(p, c);
+ if (p->color != 7 /* GC_RED */) {
+ p->flags |= MRB_PROC_SCOPE;
+ p->c = NULL;
+ mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)p);
+ if (!MRB_PROC_ENV_P(p)) {
+ MRB_PROC_SET_TARGET_CLASS(p, c);
+ }
+ }
+ else {
+ mrb_assert(MRB_FROZEN_P(p) && MRB_PROC_SCOPE_P(p));
+ mrb_assert(p->c == NULL && p->upper == NULL && p->e.target_class == NULL);
}
}
}
@@ -2199,7 +2205,7 @@ mrb_alias_method(mrb_state *mrb, struct RClass *c, mrb_sym a, mrb_sym b)
if (MRB_PROC_ENV_P(p)) {
MRB_PROC_ENV(p)->mid = b;
}
- else {
+ else if (p->color != 7 /* GC_RED */) {
struct RClass *tc = MRB_PROC_TARGET_CLASS(p);
struct REnv *e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV, NULL);
@@ -2812,15 +2818,18 @@ static const mrb_irep new_irep = {
sizeof(new_iseq), 0, 2, 0, 0,
};
+static const struct RProc new_proc = {
+ NULL, NULL, MRB_TT_PROC, 7 /* GC_RED */, MRB_FL_OBJ_IS_FROZEN | MRB_PROC_SCOPE | MRB_PROC_STRICT,
+ { &new_irep }, NULL, { NULL }
+};
+
static void
init_class_new(mrb_state *mrb, struct RClass *cls)
{
- struct RProc *p;
mrb_method_t m;
MRB_PRESYM_INIT_SYMBOLS(mrb, new_syms);
- p = mrb_proc_new(mrb, &new_irep);
- MRB_METHOD_FROM_PROC(m, p);
+ MRB_METHOD_FROM_PROC(m, &new_proc);
mrb_define_method_raw(mrb, cls, MRB_SYM(new), m);
}
diff --git a/src/proc.c b/src/proc.c
index 4a202525c..5419ac002 100644
--- a/src/proc.c
+++ b/src/proc.c
@@ -35,6 +35,11 @@ static const mrb_irep call_irep = {
0, /* refcnt */
};
+static const struct RProc call_proc = {
+ NULL, NULL, MRB_TT_PROC, 7 /* GC_RED */, MRB_FL_OBJ_IS_FROZEN | MRB_PROC_SCOPE | MRB_PROC_STRICT,
+ { &call_irep }, NULL, { NULL }
+};
+
struct RProc*
mrb_proc_new(mrb_state *mrb, const mrb_irep *irep)
{
@@ -46,7 +51,15 @@ mrb_proc_new(mrb_state *mrb, const mrb_irep *irep)
struct RClass *tc = NULL;
if (ci->proc) {
- tc = MRB_PROC_TARGET_CLASS(ci->proc);
+ if (ci->proc->color != 7 /* GC_RED */) {
+ tc = MRB_PROC_TARGET_CLASS(ci->proc);
+ }
+ else {
+ tc = mrb_vm_ci_target_class(ci);
+ if (tc && tc->tt == MRB_TT_ICLASS) {
+ tc = tc->c;
+ }
+ }
}
if (tc == NULL) {
tc = mrb_vm_ci_target_class(ci);
@@ -413,15 +426,13 @@ mrb_proc_merge_lvar(mrb_state *mrb, mrb_irep *irep, struct REnv *env, int num, c
void
mrb_init_proc(mrb_state *mrb)
{
- struct RProc *p;
mrb_method_t m;
mrb_define_class_method(mrb, mrb->proc_class, "new", mrb_proc_s_new, MRB_ARGS_NONE()|MRB_ARGS_BLOCK());
mrb_define_method(mrb, mrb->proc_class, "initialize_copy", mrb_proc_init_copy, MRB_ARGS_REQ(1));
mrb_define_method(mrb, mrb->proc_class, "arity", proc_arity, MRB_ARGS_NONE());
- p = mrb_proc_new(mrb, &call_irep);
- MRB_METHOD_FROM_PROC(m, p);
+ MRB_METHOD_FROM_PROC(m, &call_proc);
mrb_define_method_raw(mrb, mrb->proc_class, MRB_SYM(call), m);
mrb_define_method_raw(mrb, mrb->proc_class, MRB_OPSYM(aref), m);