Fixes local variables in mruby-binding.

There are two issues to be fixed:
  - `mrb_irep` could leak if `mrb_calloc()` encountered an out-of-memory exception
  - `mrb_proc_merge_lvar()` allocated one extra variable name.

`irep->lv` can always refer to only one less range than `irep->nlocals`.
Also, when `mrb_proc_merge_lvar()` extends `irep->lv`, `mrb_realloc()` with `NULL` has the same behavior as `mrb_malloc()`.
This commit is contained in:
dearblue
2024-05-30 21:25:30 +09:00
parent 0a11af74f4
commit e82b36035e
2 changed files with 3 additions and 3 deletions
+1 -1
View File
@@ -68,7 +68,7 @@ binding_irep_new_lvspace(mrb_state *mrb)
irep->flags = MRB_ISEQ_NO_FREE;
irep->iseq = iseq_dummy;
irep->ilen = sizeof(iseq_dummy) / sizeof(iseq_dummy[0]);
irep->lv = (mrb_sym*)mrb_calloc(mrb, 1, sizeof(mrb_sym)); /* initial allocation for dummy */
irep->lv = NULL;
irep->nlocals = 1;
irep->nregs = 1;
return irep;
+2 -2
View File
@@ -461,8 +461,8 @@ mrb_proc_merge_lvar(mrb_state *mrb, mrb_irep *irep, struct REnv *env, int num, c
mrb_raise(mrb, E_RUNTIME_ERROR, "unavailable local variable names");
}
irep->lv = (mrb_sym*)mrb_realloc(mrb, (mrb_sym*)irep->lv, sizeof(mrb_sym) * (irep->nlocals + num));
env->stack = (mrb_value*)mrb_realloc(mrb, env->stack, sizeof(mrb_value) * (irep->nlocals + 1 /* self */ + num));
irep->lv = (mrb_sym*)mrb_realloc(mrb, (mrb_sym*)irep->lv, sizeof(mrb_sym) * (irep->nlocals - 1 /* self */ + num));
env->stack = (mrb_value*)mrb_realloc(mrb, env->stack, sizeof(mrb_value) * (irep->nlocals + num));
mrb_sym *destlv = (mrb_sym*)irep->lv + irep->nlocals - 1 /* self */;
mrb_value *destst = env->stack + irep->nlocals;