diff options
author | Yusuke Endoh <mame@ruby-lang.org> | 2019-10-04 01:29:21 +0900 |
---|---|---|
committer | Yusuke Endoh <mame@ruby-lang.org> | 2019-10-04 02:30:36 +0900 |
commit | 711c40ebdcd0974ef3e6ac6870412dc88ae25f3e (patch) | |
tree | 01e4b774c92c8a873bac38826ab7136c631c396d | |
parent | 8f7fca784a46c4d4213ed7b166945f5b9143062d (diff) |
Refactor parser_params by removing "in_main" flag
The relation between parser_param#base_block and #in_main were very
subtle.
A main script (that is passed via a command line) was parsed under
base_block = TOPLEVEL_BINDING and in_main = 1.
A script loaded by Kernel#require was parsed under
base_block = NULL and in_main = 0.
If base_block is non-NULL and in_main == 0, it is parsed by Kernel#eval
or family.
However, we know that TOPLEVEL_BINDING has no local variables when a
main script is parsed. So, we don't have to parse a main script under
base_block = TOPLEVEL_BINDING.
Instead, this change parses a main script under base_block = 0.
If base_block is non-NULL, it is parsed by Kernel#eval or family.
By this simplication, "in_main" is no longer needed.
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/2519
-rw-r--r-- | parse.y | 6 | ||||
-rw-r--r-- | ruby.c | 16 |
2 files changed, 8 insertions, 14 deletions
@@ -270,7 +270,6 @@ struct parser_params { unsigned int debug: 1; unsigned int has_shebang: 1; unsigned int in_defined: 1; - unsigned int in_main: 1; unsigned int in_kwarg: 1; unsigned int in_def: 1; unsigned int in_class: 1; @@ -330,7 +329,7 @@ static int parser_yyerror(struct parser_params*, const YYLTYPE *yylloc, const ch #ifdef RIPPER #define compile_for_eval (0) #else -#define compile_for_eval (p->base_block != 0 && !p->in_main) +#define compile_for_eval (p->base_block != 0) #endif #define token_column ((int)(p->lex.ptok - p->lex.pbeg)) @@ -11649,7 +11648,7 @@ static void local_push(struct parser_params *p, int toplevel_scope) { struct local_vars *local; - int inherits_dvars = toplevel_scope && (compile_for_eval || p->in_main /* is p->in_main really needed? */); + int inherits_dvars = toplevel_scope && compile_for_eval; int warn_unused_vars = RTEST(ruby_verbose); local = ALLOC(struct local_vars); @@ -12309,7 +12308,6 @@ rb_parser_set_context(VALUE vparser, const struct rb_block *base, int main) TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, p); p->error_buffer = main ? Qfalse : Qnil; p->base_block = base; - p->in_main = main; return vparser; } #endif @@ -1562,8 +1562,6 @@ process_options(int argc, char **argv, ruby_cmdline_options_t *opt) const char *s; char fbuf[MAXPATHLEN]; int i = (int)proc_options(argc, argv, opt, 0); - rb_binding_t *toplevel_binding; - const struct rb_block *base_block; unsigned int dump = opt->dump & dump_exit_bits; if (opt->dump & (DUMP_BIT(usage)|DUMP_BIT(help))) { @@ -1760,13 +1758,7 @@ process_options(int argc, char **argv, ruby_cmdline_options_t *opt) ruby_set_argv(argc, argv); process_sflag(&opt->sflag); - GetBindingPtr(rb_const_get(rb_cObject, rb_intern("TOPLEVEL_BINDING")), - toplevel_binding); - /* need to acquire env from toplevel_binding each time, since it - * may update after eval() */ - - base_block = toplevel_context(toplevel_binding); - rb_parser_set_context(parser, base_block, TRUE); + rb_parser_set_context(parser, 0, TRUE); if (opt->e_script) { VALUE progname = rb_progname; @@ -1867,7 +1859,11 @@ process_options(int argc, char **argv, ruby_cmdline_options_t *opt) rb_enc_copy(path, opt->script_name); } } - base_block = toplevel_context(toplevel_binding); + + rb_binding_t *toplevel_binding; + GetBindingPtr(rb_const_get(rb_cObject, rb_intern("TOPLEVEL_BINDING")), + toplevel_binding); + const struct rb_block *base_block = toplevel_context(toplevel_binding); iseq = rb_iseq_new_main(&ast->body, opt->script_name, path, vm_block_iseq(base_block)); rb_ast_dispose(ast); } |