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-compiler/core/y.tab.c | |
| 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-compiler/core/y.tab.c')
| -rw-r--r-- | mrbgems/mruby-compiler/core/y.tab.c | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/mrbgems/mruby-compiler/core/y.tab.c b/mrbgems/mruby-compiler/core/y.tab.c index 22752e050..81f4efc26 100644 --- a/mrbgems/mruby-compiler/core/y.tab.c +++ b/mrbgems/mruby-compiler/core/y.tab.c @@ -13950,3 +13950,19 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) } #endif } + +typedef mrb_bool mrb_parser_foreach_top_variable_func(mrb_state *mrb, mrb_sym sym, void *user); +void mrb_parser_foreach_top_variable(mrb_state *mrb, struct mrb_parser_state *p, mrb_parser_foreach_top_variable_func *func, void *user); + +void +mrb_parser_foreach_top_variable(mrb_state *mrb, struct mrb_parser_state *p, mrb_parser_foreach_top_variable_func *func, void *user) +{ + const mrb_ast_node *n = p->tree; + if ((intptr_t)n->car == NODE_SCOPE) { + n = n->cdr->car; + for (; n; n = n->cdr) { + mrb_sym sym = (intptr_t)n->car; + if (sym && !func(mrb, sym, user)) break; + } + } +} |
