mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Making a proc object static for a method with static irep
The following methods will be made static. - `Class#new` - `Proc#call` - `Kernel#catch` Previously, static const RProc could not be registered as a method, but this has been changed to allow it.
This commit is contained in:
+18
-9
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
+15
-4
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user