summaryrefslogtreecommitdiffhomepage
path: root/mrbgems/mruby-compiler/core
diff options
context:
space:
mode:
authordearblue <[email protected]>2021-06-26 10:52:56 +0900
committerdearblue <[email protected]>2021-06-26 13:43:36 +0900
commitc182903ea0ee5c904725f336373f608962059996 (patch)
tree9ec19890875f891f287d002664699ccdfb12318b /mrbgems/mruby-compiler/core
parent5fc301f07d0ce26ab93ff237d15fa81894c9f1d6 (diff)
downloadmruby-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')
-rw-r--r--mrbgems/mruby-compiler/core/parse.y16
-rw-r--r--mrbgems/mruby-compiler/core/y.tab.c16
2 files changed, 32 insertions, 0 deletions
diff --git a/mrbgems/mruby-compiler/core/parse.y b/mrbgems/mruby-compiler/core/parse.y
index 8e68fa21a..b20dc1713 100644
--- a/mrbgems/mruby-compiler/core/parse.y
+++ b/mrbgems/mruby-compiler/core/parse.y
@@ -7758,3 +7758,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;
+ }
+ }
+}
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;
+ }
+ }
+}