ruby-changes:42270
From: nobu <ko1@a...>
Date: Tue, 29 Mar 2016 06:40:23 +0900 (JST)
Subject: [ruby-changes:42270] nobu:r54343 (trunk): remove rb_thread_t::parse_in_eval
nobu 2016-03-29 06:39:24 +0900 (Tue, 29 Mar 2016) New Revision: 54343 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=54343 Log: remove rb_thread_t::parse_in_eval * parse.y (struct parser_params): move parse_in_eval flag from rb_thread_t. * parse.y (rb_parser_set_context): set parsing context, not only mild error flag. * iseq.c (rb_iseq_compile_with_option): the parser now refers no thread local states to be restored. * vm_eval.c (eval_string_with_cref): ditto. Modified files: trunk/ChangeLog trunk/compile.c trunk/internal.h trunk/iseq.c trunk/load.c trunk/parse.y trunk/ruby.c trunk/vm_core.h trunk/vm_eval.c Index: ChangeLog =================================================================== --- ChangeLog (revision 54342) +++ ChangeLog (revision 54343) @@ -1,3 +1,16 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Tue Mar 29 06:39:22 2016 Nobuyoshi Nakada <nobu@r...> + + * parse.y (struct parser_params): move parse_in_eval flag from + rb_thread_t. + + * parse.y (rb_parser_set_context): set parsing context, not only + mild error flag. + + * iseq.c (rb_iseq_compile_with_option): the parser now refers no + thread local states to be restored. + + * vm_eval.c (eval_string_with_cref): ditto. + Mon Mar 28 21:24:02 2016 Kazuhiro NISHIYAMA <zn@m...> * numeric.c (int_pos_p): fix typos. Index: vm_core.h =================================================================== --- vm_core.h (revision 54342) +++ vm_core.h (revision 54343) @@ -742,14 +742,6 @@ typedef struct rb_thread_struct { https://github.com/ruby/ruby/blob/trunk/vm_core.h#L742 struct rb_vm_tag *tag; struct rb_vm_protect_tag *protect_tag; - /*! Thread-local state of evaluation context. - * - * If negative, this thread is evaluating the main program. - * If positive, this thread is evaluating a program under Kernel::eval - * family. - */ - int parse_in_eval; - /* storage */ st_table *local_storage; VALUE local_storage_recursive_hash; @@ -820,7 +812,7 @@ RUBY_SYMBOL_EXPORT_BEGIN https://github.com/ruby/ruby/blob/trunk/vm_core.h#L812 /* node -> iseq */ rb_iseq_t *rb_iseq_new(NODE*, VALUE, VALUE, VALUE, const rb_iseq_t *parent, enum iseq_type); rb_iseq_t *rb_iseq_new_top(NODE *node, VALUE name, VALUE path, VALUE absolute_path, const rb_iseq_t *parent); -rb_iseq_t *rb_iseq_new_main(NODE *node, VALUE path, VALUE absolute_path); +rb_iseq_t *rb_iseq_new_main(NODE *node, VALUE path, VALUE absolute_path, const rb_iseq_t *parent); rb_iseq_t *rb_iseq_new_with_bopt(NODE*, VALUE, VALUE, VALUE, VALUE, VALUE, enum iseq_type, VALUE); rb_iseq_t *rb_iseq_new_with_opt(NODE*, VALUE, VALUE, VALUE, VALUE, const rb_iseq_t *parent, enum iseq_type, const rb_compile_option_t*); Index: iseq.c =================================================================== --- iseq.c (revision 54342) +++ iseq.c (revision 54343) @@ -442,10 +442,8 @@ rb_iseq_new_top(NODE *node, VALUE name, https://github.com/ruby/ruby/blob/trunk/iseq.c#L442 } rb_iseq_t * -rb_iseq_new_main(NODE *node, VALUE path, VALUE absolute_path) +rb_iseq_new_main(NODE *node, VALUE path, VALUE absolute_path, const rb_iseq_t *parent) { - rb_thread_t *th = GET_THREAD(); - const rb_iseq_t *parent = th->base_block->iseq; return rb_iseq_new_with_opt(node, rb_fstring_cstr("<main>"), path, absolute_path, INT2FIX(0), parent, ISEQ_TYPE_MAIN, &COMPILE_OPTION_DEFAULT); @@ -605,9 +603,7 @@ rb_iseq_load(VALUE data, VALUE parent, V https://github.com/ruby/ruby/blob/trunk/iseq.c#L603 rb_iseq_t * rb_iseq_compile_with_option(VALUE src, VALUE file, VALUE absolute_path, VALUE line, rb_block_t *base_block, VALUE opt) { - int state; rb_thread_t *th = GET_THREAD(); - rb_block_t *prev_base_block = th->base_block; rb_iseq_t *iseq = NULL; const rb_iseq_t *const parent = base_block ? base_block->iseq : NULL; rb_compile_option_t option; @@ -617,36 +613,49 @@ rb_iseq_compile_with_option(VALUE src, V https://github.com/ruby/ruby/blob/trunk/iseq.c#L613 #else # define INITIALIZED /* volatile */ #endif + NODE *(*parse)(VALUE vparser, VALUE fname, VALUE file, int start); + int ln; + NODE *INITIALIZED node; + /* safe results first */ - const INITIALIZED int ln = (make_compile_option(&option, opt), NUM2INT(line)); - NODE *(*const INITIALIZED parse)(VALUE vparser, VALUE fname, VALUE file, int start) = - (StringValueCStr(file), RB_TYPE_P(src, T_FILE)) ? - rb_parser_compile_file_path : - (StringValue(src), rb_parser_compile_string_path); - /* should never fail usually */ - const INITIALIZED VALUE label = parent ? - parent->body->location.label : - rb_fstring_cstr("<compiled>"); - const INITIALIZED VALUE parser = rb_parser_new(); - - rb_parser_mild_error(parser); - th->base_block = base_block; - TH_PUSH_TAG(th); - if ((state = EXEC_TAG()) == 0) { - NODE *node = (*parse)(parser, file, src, ln); - if (node) { /* TODO: check err */ + make_compile_option(&option, opt); + ln = NUM2INT(line); + StringValueCStr(file); + if (RB_TYPE_P(src, T_FILE)) { + parse = rb_parser_compile_file_path; + } + else { + parse = rb_parser_compile_string_path; + StringValue(src); + } + { + const VALUE parser = rb_parser_new(); + rb_parser_set_context(parser, base_block, FALSE); + node = (*parse)(parser, file, src, ln); + } + + if (!node) { + rb_exc_raise(th->errinfo); + } + else { + int state; + INITIALIZED VALUE label = parent ? + parent->body->location.label : + rb_fstring_cstr("<compiled>"); + rb_block_t **volatile const base_block_ptr = &th->base_block; + rb_block_t *volatile const prev_base_block = th->base_block; + + th->base_block = base_block; + TH_PUSH_TAG(th); + if ((state = EXEC_TAG()) == 0) { iseq = rb_iseq_new_with_opt(node, label, file, absolute_path, line, parent, type, &option); } - } - TH_POP_TAG(); - - th->base_block = prev_base_block; + TH_POP_TAG(); + *base_block_ptr = prev_base_block; - if (state) { - JUMP_TAG(state); + if (state) JUMP_TAG(state); } - if (!iseq) rb_exc_raise(th->errinfo); return iseq; } Index: load.c =================================================================== --- load.c (revision 54342) +++ load.c (revision 54343) @@ -610,7 +610,7 @@ rb_load_internal0(rb_thread_t *th, VALUE https://github.com/ruby/ruby/blob/trunk/load.c#L610 } else { VALUE parser = rb_parser_new(); - rb_parser_mild_error(parser); + rb_parser_set_context(parser, NULL, TRUE); node = (NODE *)rb_parser_load_file(parser, fname); iseq = rb_iseq_new_top(node, rb_str_new2("<top (required)>"), fname, rb_realpath_internal(Qnil, fname, 1), NULL); } Index: compile.c =================================================================== --- compile.c (revision 54342) +++ compile.c (revision 54343) @@ -6764,12 +6764,11 @@ rb_iseq_build_from_ary(rb_iseq_t *iseq, https://github.com/ruby/ruby/blob/trunk/compile.c#L6764 /* for parser */ int -rb_dvar_defined(ID id) +rb_dvar_defined(ID id, const rb_block_t *base_block) { - rb_thread_t *th = GET_THREAD(); const rb_iseq_t *iseq; - if (th->base_block && (iseq = th->base_block->iseq)) { + if (base_block && (iseq = base_block->iseq)) { while (iseq->body->type == ISEQ_TYPE_BLOCK || iseq->body->type == ISEQ_TYPE_RESCUE || iseq->body->type == ISEQ_TYPE_ENSURE || @@ -6790,14 +6789,13 @@ rb_dvar_defined(ID id) https://github.com/ruby/ruby/blob/trunk/compile.c#L6789 } int -rb_local_defined(ID id) +rb_local_defined(ID id, const rb_block_t *base_block) { - rb_thread_t *th = GET_THREAD(); const rb_iseq_t *iseq; - if (th->base_block && th->base_block->iseq) { + if (base_block && base_block->iseq) { unsigned int i; - iseq = th->base_block->iseq->body->local_iseq; + iseq = base_block->iseq->body->local_iseq; for (i=0; i<iseq->body->local_table_size; i++) { if (iseq->body->local_table[i] == id) { @@ -6808,18 +6806,6 @@ rb_local_defined(ID id) https://github.com/ruby/ruby/blob/trunk/compile.c#L6806 return 0; } -int -rb_parse_in_eval(void) -{ - return GET_THREAD()->parse_in_eval > 0; -} - -int -rb_parse_in_main(void) -{ - return GET_THREAD()->parse_in_eval < 0; -} - static int caller_location(VALUE *path, VALUE *absolute_path) { Index: vm_eval.c =================================================================== --- vm_eval.c (revision 54342) +++ vm_eval.c (revision 54343) @@ -1274,6 +1274,23 @@ rb_each(VALUE obj) https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L1274 } static VALUE +adjust_backtrace_in_eval(rb_thread_t *th, VALUE errinfo) +{ + VALUE errat = rb_get_backtrace(errinfo); + VALUE mesg = rb_attr_get(errinfo, id_mesg); + if (RB_TYPE_P(errat, T_ARRAY)) { + VALUE bt2 = rb_vm_backtrace_str_ary(th, 0, 0); + if (RARRAY_LEN(bt2) > 0) { + if (RB_TYPE_P(mesg, T_STRING) && !RSTRING_LEN(mesg)) { + rb_ivar_set(errinfo, id_mesg, RARRAY_AREF(errat, 0)); + } + RARRAY_ASET(errat, 0, RARRAY_AREF(bt2, 0)); + } + } + return errinfo; +} + +static VALUE eval_string_with_cref(VALUE self, VALUE src, VALUE scope, rb_cref_t *const cref_arg, VALUE filename, int lineno) { @@ -1283,16 +1300,13 @@ eval_string_with_cref(VALUE self, VALUE https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L1300 rb_thread_t *th = GET_THREAD(); rb_env_t *env = NULL; rb_block_t block, *base_block; - volatile int parse_in_eval; volatile VALUE file; volatile int line; file = filename ? filename : rb_source_location(&lineno); line = lineno; - parse_in_eval = th->parse_in_eval; - TH_PUSH_TAG(th); - if ((state = TH_EXEC_TAG()) == 0) { + { rb_cref_t *cref = cref_arg; rb_binding_t *bind = 0; const rb_iseq_t *iseq; @@ -1340,9 +1354,11 @@ eval_string_with_cref(VALUE self, VALUE https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L1354 absolute_path = rb_fstring(absolute_path); /* make eval iseq */ - th->parse_in_eval++; iseq = rb_iseq_compile_with_option(src, fname, absolute_path, INT2FIX(line), base_block, Qnil); - th->parse_in_eval--; + + if (!iseq) { + rb_exc_raise(adjust_backtrace_in_eval(th, th->errinfo)); + } if (!cref && base_block->iseq) { if (NIL_P(scope)) { @@ -1364,37 +1380,22 @@ eval_string_with_cref(VALUE self, VALUE https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L1380 if (bind && iseq->body->local_table_size > 0) { bind->env = vm_make_env_object(th, th->cfp); } + } + if (file != Qundef) { /* kick */ + return vm_exec(th); + } + + TH_PUSH_TAG(th); + if ((state = TH_EXEC_TAG()) == 0) { result = vm_exec(th); } TH_POP_TAG(); - th->parse_in_eval = parse_in_eval; if (state) { if (state == TAG_RAISE) { - VALUE errinfo = th->errinfo; - if (file == Qundef) { - VALUE mesg, errat, bt2; - - errat = rb_get_backtrace(errinfo); - mesg = rb_attr_get(errinfo, id_mesg); - if (!NIL_P(errat) && RB_TYPE_P(errat, T_ARRAY) && - (bt2 = rb_vm_backtrace_str_ary(th, 0, 0), RARRAY_LEN(bt2) > 0)) { - if (!NIL_P(mesg) && RB_TYPE_P(mesg, T_STRING) && !RSTRING_LEN(mesg)) { - if (OBJ_FROZEN(mesg)) { - VALUE m = rb_str_cat(rb_str_dup(RARRAY_AREF(errat, 0)), ": ", 2); - rb_ivar_set(errinfo, id_mesg, rb_str_append(m, mesg)); - } - else { - rb_str_update(mesg, 0, 0, rb_str_new2(": ")); - rb_str_update(mesg, 0, 0, RARRAY_AREF(errat, 0)); - } - } - RARRAY_ASET(errat, 0, RARRAY_AREF(bt2, 0)); - } - } - rb_exc_raise(errinfo); + adjust_backtrace_in_eval(th, th->errinfo); } JUMP_TAG(state); } Index: parse.y =================================================================== --- parse.y (revision 54342) +++ parse.y (revision 54343) @@ -228,6 +228,7 @@ vtable_included(const struct vtable * tb https://github.com/ruby/ruby/blob/trunk/parse.y#L228 return 0; } +typedef struct rb_block_struct rb_block_t; typedef struct token_info { const char *token; @@ -295,7 +296,7 @@ struct parser_params { https://github.com/ruby/ruby/blob/trunk/parse.y#L296 unsigned int yydebug: 1; unsigned int has_shebang: 1; unsigned int in_defined: 1; - unsigned int compile_for_eval: 1; + unsigned int in_main: 1; unsigned int in_kwarg: 1; unsigned int in_single: 1; unsigned int in_def: 1; @@ -315,6 +316,7 @@ struct parser_params { https://github.com/ruby/ruby/blob/trunk/parse.y#L316 VALUE error_buffer; VALUE debug_lines; VALUE coverage; + const rb_block_t *base_block; #else /* Ripper only */ @@ -353,7 +355,7 @@ static int parser_yyerror(struct parser_ https://github.com/ruby/ruby/blob/trunk/parse.y#L355 #define brace_nest (parser->lex.brace_nest) #define in_single (parser->in_single) #define in_def (parser->in_def) -#define compile_for_eval (parser->compile_for_eval) +#define in_main (parser->in_main) #define in_defined (parser->in_defined) #define tokenbuf (parser->tokenbuf) #define tokidx (parser->tokidx) @@ -381,7 +383,9 @@ static int parser_yyerror(struct parser_ https://github.com/ruby/ruby/blob/trunk/parse.y#L383 #define current_arg (parser->cur_arg) #define yydebug (parser->yydebug) #ifdef RIPPER +#define compile_for_eval (0) #else +#define compile_for_eval (parser->base_block != 0 && !in_main) #define ruby_eval_tree (parser->eval_tree) #define ruby_eval_tree_begin (parser->eval_tree_begin) #define ruby_debug_lines (parser->debug_lines) @@ -530,8 +534,8 @@ ripper_is_node_yylval(VALUE n) https://github.com/ruby/ruby/blob/trunk/parse.y#L534 #define value_expr(node) ((void)(node)) #define remove_begin(node) (node) -#define rb_dvar_defined(id) 0 -#define rb_local_defined(id) 0 +#define rb_dvar_defined(id, base) 0 +#define rb_local_defined(id, base) 0 static ID ripper_get_id(VALUE); #define get_id(id) ripper_get_id(id) static VALUE ripper_get_value(VALUE); @@ -945,7 +949,7 @@ static void token_info_pop_gen(struct pa https://github.com/ruby/ruby/blob/trunk/parse.y#L949 program : { SET_LEX_STATE(EXPR_BEG); /*%%%*/ - local_push(compile_for_eval || rb_parse_in_main()); + local_push(compile_for_eval || in_main); /*% local_push(0); %*/ @@ -5540,7 +5544,6 @@ yycompile0(VALUE arg) https://github.com/ruby/ruby/blob/trunk/parse.y#L5544 #endif ruby_debug_lines = 0; ruby_coverage = 0; - compile_for_eval = 0; lex_strterm = 0; lex_p = lex_pbeg = lex_pend = 0; @@ -5636,7 +5639,6 @@ parser_compile_string(VALUE vparser, VAL https://github.com/ruby/ruby/blob/trunk/parse.y#L5639 lex_gets_ptr = 0; lex_input = rb_str_new_frozen(s); lex_pbeg = lex_p = lex_pend = 0; - compile_for_eval = !!rb_parse_in_eval(); node = yycompile(parser, fname, line); RB_GC_GUARD(vparser); /* prohibit tail call optimization */ @@ -5710,7 +5712,6 @@ rb_parser_compile_file_path(VALUE vparse https://github.com/ruby/ruby/blob/trunk/parse.y#L5712 lex_gets = lex_io_gets; lex_input = file; lex_pbeg = lex_p = lex_pend = 0; - compile_for_eval = !!rb_parse_in_eval(); node = yycompile(parser, fname, start); RB_GC_GUARD(vparser); /* prohibit tail call optimization */ @@ -10428,7 +10429,7 @@ local_id_gen(struct parser_params *parse https://github.com/ruby/ruby/blob/trunk/parse.y#L10429 } if (vars && vars->prev == DVARS_INHERIT) { - return rb_local_defined(id); + return rb_local_defined(id, parser->base_block); } else if (vtable_included(args, id)) { return 1; @@ -10525,7 +10526,7 @@ dvar_defined_gen(struct parser_params *p https://github.com/ruby/ruby/blob/trunk/parse.y#L10526 } if (vars == DVARS_INHERIT) { - return rb_dvar_defined(id); + return rb_dvar_defined(id, parser->base_block); } return 0; @@ -10897,12 +10898,14 @@ rb_parser_new(void) https://github.com/ruby/ruby/blob/trunk/parse.y#L10898 } VALUE -rb_parser_mild_error(VALUE vparser) +rb_parser_set_context(VALUE vparser, const rb_block_t *base, int main) { struct parser_params *parser; TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser); - parser->error_buffer = Qnil; + parser->error_buffer = main ? Qfalse : Qnil; + parser->base_block = base; + in_main = main; return vparser; } #endif Index: internal.h =================================================================== --- internal.h (revision 54342) +++ internal.h (revision 54343) @@ -808,10 +808,9 @@ int rb_class_has_methods(VALUE c); https://github.com/ruby/ruby/blob/trunk/internal.h#L808 VALUE rb_invcmp(VALUE, VALUE); /* compile.c */ -int rb_dvar_defined(ID); -int rb_local_defined(ID); -int rb_parse_in_eval(void); -int rb_parse_in_main(void); +struct rb_block_struct; +int rb_dvar_defined(ID, const struct rb_block_struct *); +int rb_local_defined(ID, const struct rb_block_struct *); const char * rb_insns_name(int i); VALUE rb_insns_name_array(void); @@ -1118,7 +1117,7 @@ struct RBasicRaw { https://github.com/ruby/ruby/blob/trunk/internal.h#L1117 #endif VALUE rb_parser_get_yydebug(VALUE); VALUE rb_parser_set_yydebug(VALUE, VALUE); -VALUE rb_parser_mild_error(VALUE parser); +VALUE rb_parser_set_context(VALUE, const struct rb_block_struct *, int); void *rb_parser_load_file(VALUE parser, VALUE name); int rb_is_const_name(VALUE name); int rb_is_class_name(VALUE name); Index: ruby.c =================================================================== --- ruby.c (revision 54342) +++ ruby.c (revision 54343) @@ -598,10 +598,7 @@ require_libraries(VALUE *req_list) https://github.com/ruby/ruby/blob/trunk/ruby.c#L598 VALUE list = *req_list; VALUE self = rb_vm_top_self(); ID require; - rb_thread_t *th = GET_THREAD(); rb_encoding *extenc = rb_default_external_encoding(); - int prev_parse_in_eval = th->parse_in_eval; - th->parse_in_eval = 0; CONST_ID(require, "require"); while (list && RARRAY_LEN(list) > 0) { @@ -612,19 +609,15 @@ require_libraries(VALUE *req_list) https://github.com/ruby/ruby/blob/trunk/ruby.c#L609 rb_funcall2(self, require, 1, &feature); } *req_list = 0; - - th->parse_in_eval = prev_parse_in_eval; } -static rb_env_t* -toplevel_context(VALUE toplevel_binding) +static rb_block_t* +toplevel_context(rb_binding_t *bind) { rb_env_t *env; - rb_binding_t *bind; - GetBindingPtr(toplevel_binding, bind); GetEnvPtr(bind->env, env); - return env; + return &env->block; } static void @@ -1422,8 +1415,8 @@ process_options(int argc, char **argv, s https://github.com/ruby/ruby/blob/trunk/ruby.c#L1415 const char *s; char fbuf[MAXPATHLEN]; int i = (int)proc_options(argc, argv, opt, 0); - rb_thread_t *th = GET_THREAD(); - VALUE toplevel_binding = Qundef; + rb_binding_t *toplevel_binding; + rb_block_t *base_block; argc -= i; argv += i; @@ -1570,16 +1563,10 @@ process_options(int argc, char **argv, s https://github.com/ruby/ruby/blob/trunk/ruby.c#L1563 ruby_set_argv(argc, argv); process_sflag(&opt->sflag); - toplevel_binding = rb_const_get(rb_cObject, rb_intern("TOPLEVEL_BINDING")); - -#define PREPARE_PARSE_MAIN(expr) do { \ - rb_env_t *env = toplevel_context(toplevel_binding); \ - th->parse_in_eval--; \ - th->base_block = &env->block; \ - expr; \ - th->parse_in_eval++; \ - th->base_block = 0; \ -} while (0) + 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() */ if (opt->e_script) { VALUE progname = rb_progname; @@ -1597,18 +1584,18 @@ process_options(int argc, char **argv, s https://github.com/ruby/ruby/blob/trunk/ruby.c#L1584 } ruby_set_script_name(progname); - PREPARE_PARSE_MAIN({ - tree = rb_parser_compile_string(parser, opt->script, opt->e_script, 1); - }); + base_block = toplevel_context(toplevel_binding); + rb_parser_set_context(parser, base_block, TRUE); + tree = rb_parser_compile_string(parser, opt->script, opt->e_script, 1); } else { if (opt->script[0] == '-' && !opt->script[1]) { forbid_setid("program input from stdin"); } - PREPARE_PARSE_MAIN({ - tree = load_file(parser, opt->script_name, 1, opt); - }); + base_block = toplevel_context(toplevel_binding); + rb_parser_set_context(parser, base_block, TRUE); + tree = load_file(parser, opt->script_name, 1, opt); } ruby_set_script_name(opt->script_name); if (opt->dump & DUMP_BIT(yydebug)) return Qtru (... truncated) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/