diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2017-10-26 01:13:57 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2017-10-28 00:29:30 +0900 |
| commit | 93f5f225772c398be6e409da3d3ef0f07ffbe1cf (patch) | |
| tree | 37198a8c50baaf1a5714a581e049167073249ddc /src/class.c | |
| parent | 3f9d00ded3ce987927d975f7ce70637a973de1fc (diff) | |
| download | mruby-93f5f225772c398be6e409da3d3ef0f07ffbe1cf.tar.gz mruby-93f5f225772c398be6e409da3d3ef0f07ffbe1cf.zip | |
Heavily refactored how lexical scope links are implemented; fix #3821
Instead of `irep` links, we added a `upper` link to `struct RProc`.
To make a space for the `upper` link, we moved `target_class` reference.
If a `Proc` does not have `env`, `target_class` is saved in an `union`
shared with `env` (if a `Proc` has env, you can tell it by `MRB_PROC_ENV_P()).
Otherwise `target_class` is referenced from `env->c`. We removed links
in `env` as well.
This change removes 2 members from `mrb_irep` struct, thus saving 2
words per method/proc/block. This also fixes potential memory leaks
due to the circular references caused by a link from `mrb_irep`.
Diffstat (limited to 'src/class.c')
| -rw-r--r-- | src/class.c | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/src/class.c b/src/class.c index a35eb4c92..77a7050da 100644 --- a/src/class.c +++ b/src/class.c @@ -436,8 +436,11 @@ mrb_define_method_raw(mrb_state *mrb, struct RClass *c, mrb_sym mid, struct RPro k = kh_put(mt, mrb, h, mid); kh_value(h, k) = p; if (p) { + p->flags |= MRB_PROC_SCOPE; p->c = NULL; - mrb_field_write_barrier(mrb, (struct RBasic *)c, (struct RBasic *)p); + mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)p); + MRB_PROC_SET_TARGET_CLASS(p, c); + mrb_field_write_barrier(mrb, (struct RBasic*)p, (struct RBasic*)c); } mc_clear_by_id(mrb, c, mid); } @@ -449,7 +452,7 @@ mrb_define_method_id(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_func_t f int ai = mrb_gc_arena_save(mrb); p = mrb_proc_new_cfunc(mrb, func); - p->target_class = c; + MRB_PROC_SET_TARGET_CLASS(p, c); mrb_define_method_raw(mrb, c, mid, p); mrb_gc_arena_restore(mrb, ai); } |
