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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54343 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
0a41425ad4
commit
d7935475fc
13
ChangeLog
13
ChangeLog
@ -1,3 +1,16 @@
|
||||
Tue Mar 29 06:39:22 2016 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* 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@mbf.nifty.com>
|
||||
|
||||
* numeric.c (int_pos_p): fix typos.
|
||||
|
24
compile.c
24
compile.c
@ -6764,12 +6764,11 @@ rb_iseq_build_from_ary(rb_iseq_t *iseq, VALUE misc, VALUE locals, VALUE params,
|
||||
/* 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)
|
||||
}
|
||||
|
||||
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)
|
||||
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)
|
||||
{
|
||||
|
@ -808,10 +808,9 @@ int rb_class_has_methods(VALUE c);
|
||||
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 {
|
||||
#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);
|
||||
|
67
iseq.c
67
iseq.c
@ -442,10 +442,8 @@ rb_iseq_new_top(NODE *node, VALUE name, VALUE path, VALUE absolute_path, const r
|
||||
}
|
||||
|
||||
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, VALUE opt)
|
||||
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, VALUE file, VALUE absolute_path, VALUE li
|
||||
#else
|
||||
# define INITIALIZED /* volatile */
|
||||
#endif
|
||||
/* 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();
|
||||
NODE *(*parse)(VALUE vparser, VALUE fname, VALUE file, int start);
|
||||
int ln;
|
||||
NODE *INITIALIZED node;
|
||||
|
||||
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 */
|
||||
/* safe results first */
|
||||
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_POP_TAG();
|
||||
*base_block_ptr = prev_base_block;
|
||||
|
||||
th->base_block = prev_base_block;
|
||||
|
||||
if (state) {
|
||||
JUMP_TAG(state);
|
||||
if (state) JUMP_TAG(state);
|
||||
}
|
||||
if (!iseq) rb_exc_raise(th->errinfo);
|
||||
|
||||
return iseq;
|
||||
}
|
||||
|
2
load.c
2
load.c
@ -610,7 +610,7 @@ rb_load_internal0(rb_thread_t *th, VALUE fname, int wrap)
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
27
parse.y
27
parse.y
@ -228,6 +228,7 @@ vtable_included(const struct vtable * tbl, ID id)
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef struct rb_block_struct rb_block_t;
|
||||
|
||||
typedef struct token_info {
|
||||
const char *token;
|
||||
@ -295,7 +296,7 @@ struct parser_params {
|
||||
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 {
|
||||
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_params*, const char*);
|
||||
#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_params*, const char*);
|
||||
#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)
|
||||
|
||||
#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 parser_params*, const char *token, size_t
|
||||
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)
|
||||
#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, VALUE fname, VALUE s, int line)
|
||||
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 vparser, VALUE fname, VALUE file, int start)
|
||||
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 *parser, ID id)
|
||||
}
|
||||
|
||||
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 *parser, ID id, int get)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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
|
||||
|
50
ruby.c
50
ruby.c
@ -598,10 +598,7 @@ require_libraries(VALUE *req_list)
|
||||
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)
|
||||
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, struct cmdline_options *opt)
|
||||
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, struct cmdline_options *opt)
|
||||
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, struct cmdline_options *opt)
|
||||
}
|
||||
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 Qtrue;
|
||||
@ -1657,13 +1644,14 @@ process_options(int argc, char **argv, struct cmdline_options *opt)
|
||||
return Qtrue;
|
||||
}
|
||||
|
||||
PREPARE_PARSE_MAIN({
|
||||
{
|
||||
VALUE path = Qnil;
|
||||
if (!opt->e_script && strcmp(opt->script, "-")) {
|
||||
path = rb_realpath_internal(Qnil, opt->script_name, 1);
|
||||
}
|
||||
iseq = rb_iseq_new_main(tree, opt->script_name, path);
|
||||
});
|
||||
base_block = toplevel_context(toplevel_binding);
|
||||
iseq = rb_iseq_new_main(tree, opt->script_name, path, base_block->iseq);
|
||||
}
|
||||
|
||||
if (opt->dump & DUMP_BIT(insns)) {
|
||||
rb_io_write(rb_stdout, rb_iseq_disasm((const rb_iseq_t *)iseq));
|
||||
|
10
vm_core.h
10
vm_core.h
@ -742,14 +742,6 @@ typedef struct rb_thread_struct {
|
||||
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
|
||||
/* 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*);
|
||||
|
||||
|
59
vm_eval.c
59
vm_eval.c
@ -1273,6 +1273,23 @@ rb_each(VALUE obj)
|
||||
return rb_call(obj, idEach, 0, 0, CALL_FCALL);
|
||||
}
|
||||
|
||||
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 src, VALUE scope, rb_cref_t *const cref_
|
||||
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 src, VALUE scope, rb_cref_t *const cref_
|
||||
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 src, VALUE scope, rb_cref_t *const cref_
|
||||
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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user