From c182903ea0ee5c904725f336373f608962059996 Mon Sep 17 00:00:00 2001 From: dearblue Date: Sat, 26 Jun 2021 10:52:56 +0900 Subject: Fixed finding variables from `proc` in `binding.eval` failed Previously the following code did not produce the expected results: ```ruby bx = binding block = bx.eval("a = 1; proc { a }") bx.eval("a = 2") p block.call # Expect 2 but return 1 due to a bug ``` The previous implementation of `Binding#eval` evaluated the code and then merged the top layer variables. This patch will parse and expand the variable space before making a call to `eval`. This means that the call to `Binding#eval` will do the parsing twice. In addition, the following changes will be made: - Make `mrb_parser_foreach_top_variable()`, `mrb_binding_extract_proc()` and `mrb_binding_extract_env()` functions private global functions. - Remove the `posthook` argument from `mrb_exec_irep()`. The `posthook` argument was introduced to implement the `binding` method. This patch is unnecessary because it uses a different implementation method. ref #5362 fixed #5491 --- src/proc.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src/proc.c') diff --git a/src/proc.c b/src/proc.c index 2717cd610..1d5a4aa76 100644 --- a/src/proc.c +++ b/src/proc.c @@ -417,7 +417,14 @@ mrb_proc_merge_lvar(mrb_state *mrb, mrb_irep *irep, struct REnv *env, int num, c mrb_sym *destlv = (mrb_sym*)irep->lv + irep->nlocals - 1 /* self */; mrb_value *destst = env->stack + irep->nlocals; memmove(destlv, lv, sizeof(mrb_sym) * num); - memmove(destst, stack, sizeof(mrb_value) * num); + if (stack) { + memmove(destst, stack, sizeof(mrb_value) * num); + } + else { + for (int i = num; i > 0; i--, destst++) { + *destst = mrb_nil_value(); + } + } irep->nlocals += num; irep->nregs = irep->nlocals; MRB_ENV_SET_LEN(env, irep->nlocals); -- cgit v1.2.3