diff options
| author | dearblue <[email protected]> | 2021-06-26 10:52:56 +0900 |
|---|---|---|
| committer | dearblue <[email protected]> | 2021-06-26 13:43:36 +0900 |
| commit | c182903ea0ee5c904725f336373f608962059996 (patch) | |
| tree | 9ec19890875f891f287d002664699ccdfb12318b /mrbgems/mruby-binding-core | |
| parent | 5fc301f07d0ce26ab93ff237d15fa81894c9f1d6 (diff) | |
| download | mruby-c182903ea0ee5c904725f336373f608962059996.tar.gz mruby-c182903ea0ee5c904725f336373f608962059996.zip | |
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
Diffstat (limited to 'mrbgems/mruby-binding-core')
| -rw-r--r-- | mrbgems/mruby-binding-core/src/binding-core.c | 22 |
1 files changed, 11 insertions, 11 deletions
diff --git a/mrbgems/mruby-binding-core/src/binding-core.c b/mrbgems/mruby-binding-core/src/binding-core.c index 57b1b5434..7b70cfb78 100644 --- a/mrbgems/mruby-binding-core/src/binding-core.c +++ b/mrbgems/mruby-binding-core/src/binding-core.c @@ -24,16 +24,16 @@ binding_extract_pc(mrb_state *mrb, mrb_value binding) } } -static const struct RProc * -binding_extract_proc(mrb_state *mrb, mrb_value binding) +const struct RProc * +mrb_binding_extract_proc(mrb_state *mrb, mrb_value binding) { mrb_value obj = mrb_iv_get(mrb, binding, MRB_SYM(proc)); mrb_check_type(mrb, obj, MRB_TT_PROC); return mrb_proc_ptr(obj); } -static struct REnv * -binding_extract_env(mrb_state *mrb, mrb_value binding) +struct REnv * +mrb_binding_extract_env(mrb_state *mrb, mrb_value binding) { mrb_value obj = mrb_iv_get(mrb, binding, MRB_SYM(env)); if (mrb_nil_p(obj)) { @@ -108,8 +108,8 @@ binding_local_variable_defined_p(mrb_state *mrb, mrb_value self) mrb_sym varname; mrb_get_args(mrb, "n", &varname); - const struct RProc *proc = binding_extract_proc(mrb, self); - struct REnv *env = binding_extract_env(mrb, self); + const struct RProc *proc = mrb_binding_extract_proc(mrb, self); + struct REnv *env = mrb_binding_extract_env(mrb, self); mrb_value *e = binding_local_variable_search(mrb, proc, env, varname); if (e) { return mrb_true_value(); @@ -129,8 +129,8 @@ binding_local_variable_get(mrb_state *mrb, mrb_value self) mrb_sym varname; mrb_get_args(mrb, "n", &varname); - const struct RProc *proc = binding_extract_proc(mrb, self); - struct REnv *env = binding_extract_env(mrb, self); + const struct RProc *proc = mrb_binding_extract_proc(mrb, self); + struct REnv *env = mrb_binding_extract_env(mrb, self); mrb_value *e = binding_local_variable_search(mrb, proc, env, varname); if (!e) { mrb_raisef(mrb, E_NAME_ERROR, "local variable %!n is not defined", varname); @@ -146,8 +146,8 @@ binding_local_variable_set(mrb_state *mrb, mrb_value self) mrb_value obj; mrb_get_args(mrb, "no", &varname, &obj); - const struct RProc *proc = binding_extract_proc(mrb, self); - struct REnv *env = binding_extract_env(mrb, self); + const struct RProc *proc = mrb_binding_extract_proc(mrb, self); + struct REnv *env = mrb_binding_extract_env(mrb, self); mrb_value *e = binding_local_variable_search(mrb, proc, env, varname); if (e) { *e = obj; @@ -184,7 +184,7 @@ binding_source_location(mrb_state *mrb, mrb_value self) } mrb_value srcloc; - const struct RProc *proc = binding_extract_proc(mrb, self); + const struct RProc *proc = mrb_binding_extract_proc(mrb, self); if (!proc || MRB_PROC_CFUNC_P(proc) || !proc->upper || MRB_PROC_CFUNC_P(proc->upper)) { srcloc = mrb_nil_value(); |
