Replace parser & node compile_option from Hash to bit field

This commit reduces dependency to CRuby object.
This commit is contained in:
yui-knk 2023-06-17 10:21:37 +09:00 коммит произвёл Yuichiro Kaneko
Родитель e5ae7a16b4
Коммит 19c62b400d
7 изменённых файлов: 34 добавлений и 27 удалений

Просмотреть файл

@ -1326,7 +1326,8 @@ new_child_iseq(rb_iseq_t *iseq, const NODE *const node,
rb_ast_body_t ast; rb_ast_body_t ast;
ast.root = node; ast.root = node;
ast.compile_option = 0; ast.frozen_string_literal = -1;
ast.coverage_enabled = -1;
ast.script_lines = ISEQ_BODY(iseq)->variable.script_lines; ast.script_lines = ISEQ_BODY(iseq)->variable.script_lines;
debugs("[new_child_iseq]> ---------------------------------------\n"); debugs("[new_child_iseq]> ---------------------------------------\n");
@ -8372,7 +8373,8 @@ compile_builtin_mandatory_only_method(rb_iseq_t *iseq, const NODE *node, const N
rb_ast_body_t ast = { rb_ast_body_t ast = {
.root = &scope_node, .root = &scope_node,
.compile_option = 0, .frozen_string_literal = -1,
.coverage_enabled = -1,
.script_lines = ISEQ_BODY(iseq)->variable.script_lines, .script_lines = ISEQ_BODY(iseq)->variable.script_lines,
}; };

11
iseq.c
Просмотреть файл

@ -741,6 +741,15 @@ set_compile_option_from_hash(rb_compile_option_t *option, VALUE opt)
#undef SET_COMPILE_OPTION_NUM #undef SET_COMPILE_OPTION_NUM
} }
static VALUE
make_compile_option_from_ast(const rb_ast_body_t *ast)
{
VALUE opt = rb_obj_hide(rb_ident_hash_new());
if (ast->frozen_string_literal >= 0) rb_hash_aset(opt, rb_sym_intern_ascii_cstr("frozen_string_literal"), RBOOL(ast->frozen_string_literal));
if (ast->coverage_enabled >= 0) rb_hash_aset(opt, rb_sym_intern_ascii_cstr("coverage_enabled"), RBOOL(ast->coverage_enabled));
return opt;
}
static void static void
rb_iseq_make_compile_option(rb_compile_option_t *option, VALUE opt) rb_iseq_make_compile_option(rb_compile_option_t *option, VALUE opt)
{ {
@ -908,7 +917,7 @@ rb_iseq_new_with_opt(const rb_ast_body_t *ast, VALUE name, VALUE path, VALUE rea
else { else {
new_opt = COMPILE_OPTION_DEFAULT; new_opt = COMPILE_OPTION_DEFAULT;
} }
if (ast && ast->compile_option) rb_iseq_make_compile_option(&new_opt, ast->compile_option); if (ast) rb_iseq_make_compile_option(&new_opt, make_compile_option_from_ast(ast));
VALUE script_lines = Qnil; VALUE script_lines = Qnil;

1
node.c
Просмотреть файл

@ -392,7 +392,6 @@ rb_ast_mark(rb_ast_t *ast)
if (ast->node_buffer) { if (ast->node_buffer) {
rb_gc_mark(ast->node_buffer->mark_hash); rb_gc_mark(ast->node_buffer->mark_hash);
rb_gc_mark(ast->node_buffer->tokens); rb_gc_mark(ast->node_buffer->tokens);
if (ast->body.compile_option) rb_gc_mark(ast->body.compile_option);
node_buffer_t *nb = ast->node_buffer; node_buffer_t *nb = ast->node_buffer;
iterate_node_values(ast, &nb->markable, mark_ast_value, NULL); iterate_node_values(ast, &nb->markable, mark_ast_value, NULL);
if (ast->body.script_lines) rb_gc_mark(ast->body.script_lines); if (ast->body.script_lines) rb_gc_mark(ast->body.script_lines);

27
parse.y
Просмотреть файл

@ -416,7 +416,6 @@ struct parser_params {
rb_encoding *enc; rb_encoding *enc;
token_info *token_info; token_info *token_info;
VALUE case_labels; VALUE case_labels;
VALUE compile_option;
VALUE debug_buffer; VALUE debug_buffer;
VALUE debug_output; VALUE debug_output;
@ -441,6 +440,9 @@ struct parser_params {
#ifdef UNIVERSAL_PARSER #ifdef UNIVERSAL_PARSER
rb_parser_config_t *config; rb_parser_config_t *config;
#endif #endif
/* compile_option */
int frozen_string_literal:2; /* -1: not specified, 0: false, 1: true */
int coverage_enabled:2; /* -1: not specified, 0: false, 1: true */
unsigned int command_start:1; unsigned int command_start:1;
unsigned int eofp: 1; unsigned int eofp: 1;
@ -6773,7 +6775,7 @@ yycompile0(VALUE arg)
int n; int n;
NODE *tree; NODE *tree;
struct parser_params *p = (struct parser_params *)arg; struct parser_params *p = (struct parser_params *)arg;
VALUE cov = Qfalse; int cov = FALSE;
if (!compile_for_eval && !NIL_P(p->ruby_sourcefile_string)) { if (!compile_for_eval && !NIL_P(p->ruby_sourcefile_string)) {
p->debug_lines = debug_lines(p, p->ruby_sourcefile_string); p->debug_lines = debug_lines(p, p->ruby_sourcefile_string);
@ -6786,7 +6788,7 @@ yycompile0(VALUE arg)
} }
if (!e_option_supplied(p)) { if (!e_option_supplied(p)) {
cov = Qtrue; cov = TRUE;
} }
} }
@ -6825,15 +6827,14 @@ yycompile0(VALUE arg)
tree = NEW_NIL(&NULL_LOC); tree = NEW_NIL(&NULL_LOC);
} }
else { else {
VALUE opt = p->compile_option;
VALUE tokens = p->tokens; VALUE tokens = p->tokens;
NODE *prelude; NODE *prelude;
NODE *body = parser_append_options(p, tree->nd_body); NODE *body = parser_append_options(p, tree->nd_body);
if (!opt) opt = rb_obj_hide(rb_ident_hash_new()); p->coverage_enabled = cov;
rb_hash_aset(opt, rb_sym_intern_ascii_cstr("coverage_enabled"), cov);
prelude = block_append(p, p->eval_tree_begin, body); prelude = block_append(p, p->eval_tree_begin, body);
tree->nd_body = prelude; tree->nd_body = prelude;
RB_OBJ_WRITE(p->ast, &p->ast->body.compile_option, opt); p->ast->body.frozen_string_literal = p->frozen_string_literal;
p->ast->body.coverage_enabled = p->coverage_enabled;
if (p->keep_tokens) { if (p->keep_tokens) {
rb_obj_freeze(tokens); rb_obj_freeze(tokens);
rb_ast_set_tokens(p->ast, tokens); rb_ast_set_tokens(p->ast, tokens);
@ -8656,7 +8657,7 @@ parser_set_token_info(struct parser_params *p, const char *name, const char *val
} }
static void static void
parser_set_compile_option_flag(struct parser_params *p, const char *name, const char *val) parser_set_frozen_string_literal(struct parser_params *p, const char *name, const char *val)
{ {
int b; int b;
@ -8668,10 +8669,7 @@ parser_set_compile_option_flag(struct parser_params *p, const char *name, const
b = parser_get_bool(p, name, val); b = parser_get_bool(p, name, val);
if (b < 0) return; if (b < 0) return;
if (!p->compile_option) p->frozen_string_literal = b;
p->compile_option = rb_obj_hide(rb_ident_hash_new());
rb_hash_aset(p->compile_option, ID2SYM(rb_intern(name)),
RBOOL(b));
} }
static void static void
@ -8729,7 +8727,7 @@ struct magic_comment {
static const struct magic_comment magic_comments[] = { static const struct magic_comment magic_comments[] = {
{"coding", magic_comment_encoding, parser_encode_length}, {"coding", magic_comment_encoding, parser_encode_length},
{"encoding", magic_comment_encoding, parser_encode_length}, {"encoding", magic_comment_encoding, parser_encode_length},
{"frozen_string_literal", parser_set_compile_option_flag}, {"frozen_string_literal", parser_set_frozen_string_literal},
{"shareable_constant_value", parser_set_shareable_constant_value}, {"shareable_constant_value", parser_set_shareable_constant_value},
{"warn_indent", parser_set_token_info}, {"warn_indent", parser_set_token_info},
# if WARN_PAST_SCOPE # if WARN_PAST_SCOPE
@ -13674,6 +13672,8 @@ parser_initialize(struct parser_params *p)
p->lex.lpar_beg = -1; /* make lambda_beginning_p() == FALSE at first */ p->lex.lpar_beg = -1; /* make lambda_beginning_p() == FALSE at first */
p->node_id = 0; p->node_id = 0;
p->delayed.token = Qnil; p->delayed.token = Qnil;
p->frozen_string_literal = -1; /* not specified */
p->coverage_enabled = -1; /* not specified */
#ifdef RIPPER #ifdef RIPPER
p->result = Qnil; p->result = Qnil;
p->parsing_thread = Qnil; p->parsing_thread = Qnil;
@ -13709,7 +13709,6 @@ rb_ruby_parser_mark(void *ptr)
rb_gc_mark(p->delayed.token); rb_gc_mark(p->delayed.token);
#ifndef RIPPER #ifndef RIPPER
rb_gc_mark(p->debug_lines); rb_gc_mark(p->debug_lines);
rb_gc_mark(p->compile_option);
rb_gc_mark(p->error_buffer); rb_gc_mark(p->error_buffer);
rb_gc_mark(p->end_expect_token_locations); rb_gc_mark(p->end_expect_token_locations);
rb_gc_mark(p->tokens); rb_gc_mark(p->tokens);

Просмотреть файл

@ -309,11 +309,12 @@ typedef struct node_buffer_struct node_buffer_t;
/* T_IMEMO/ast */ /* T_IMEMO/ast */
typedef struct rb_ast_body_struct { typedef struct rb_ast_body_struct {
const NODE *root; const NODE *root;
VALUE compile_option;
VALUE script_lines; VALUE script_lines;
// script_lines is either: // script_lines is either:
// - a Fixnum that represents the line count of the original source, or // - a Fixnum that represents the line count of the original source, or
// - an Array that contains the lines of the original source // - an Array that contains the lines of the original source
int frozen_string_literal:2; /* -1: not specified, 0: false, 1: true */
int coverage_enabled:2; /* -1: not specified, 0: false, 1: true */
} rb_ast_body_t; } rb_ast_body_t;
typedef struct rb_ast_struct { typedef struct rb_ast_struct {
VALUE flags; VALUE flags;

3
vm.c
Просмотреть файл

@ -1350,7 +1350,8 @@ rb_binding_add_dynavars(VALUE bindval, rb_binding_t *bind, int dyncount, const I
rb_node_init(&tmp_node, NODE_SCOPE, (VALUE)dyns, 0, 0); rb_node_init(&tmp_node, NODE_SCOPE, (VALUE)dyns, 0, 0);
ast.root = &tmp_node; ast.root = &tmp_node;
ast.compile_option = 0; ast.frozen_string_literal = -1;
ast.coverage_enabled = -1;
ast.script_lines = INT2FIX(-1); ast.script_lines = INT2FIX(-1);
if (base_iseq) { if (base_iseq) {

Просмотреть файл

@ -1626,7 +1626,7 @@ eval_make_iseq(VALUE src, VALUE fname, int line, const rb_binding_t *bind,
int isolated_depth = 0; int isolated_depth = 0;
// Conditionally enable coverage depending on the current mode: // Conditionally enable coverage depending on the current mode:
VALUE coverage_enabled = RBOOL(rb_get_coverage_mode() & COVERAGE_TARGET_EVAL); int coverage_enabled = (rb_get_coverage_mode() & COVERAGE_TARGET_EVAL) != 0;
{ {
int depth = 1; int depth = 1;
@ -1659,17 +1659,13 @@ eval_make_iseq(VALUE src, VALUE fname, int line, const rb_binding_t *bind,
rb_gc_register_mark_object(eval_default_path); rb_gc_register_mark_object(eval_default_path);
} }
fname = eval_default_path; fname = eval_default_path;
coverage_enabled = Qfalse; coverage_enabled = FALSE;
} }
rb_parser_set_context(parser, parent, FALSE); rb_parser_set_context(parser, parent, FALSE);
ast = rb_parser_compile_string_path(parser, fname, src, line); ast = rb_parser_compile_string_path(parser, fname, src, line);
if (ast->body.root) { if (ast->body.root) {
if (ast->body.compile_option == Qnil) { ast->body.coverage_enabled = coverage_enabled;
ast->body.compile_option = rb_obj_hide(rb_ident_hash_new());
}
rb_hash_aset(ast->body.compile_option, rb_sym_intern_ascii_cstr("coverage_enabled"), coverage_enabled);
iseq = rb_iseq_new_eval(&ast->body, iseq = rb_iseq_new_eval(&ast->body,
ISEQ_BODY(parent)->location.label, ISEQ_BODY(parent)->location.label,
fname, Qnil, line, fname, Qnil, line,