[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]