Add line_count field to rb_ast_body_t
This patch adds `int line_count` field to `rb_ast_body_t` structure. Instead, we no longer cast `script_lines` to Fixnum. ## Background Ref https://github.com/ruby/ruby/pull/10618 In the PR above, we have decoupled IMEMO from `rb_ast_t`. This means we could lift the five-words-restriction of the structure that forced us to unionize `rb_ast_t *` and `FIXNUM` in one field. ## Relating refactor - Remove the second parameter of `rb_ruby_ast_new()` function ## Attention I will remove a code that assigns -1 to line_count, in `rb_binding_add_dynavars()` of vm.c, because I don't think it is necessary. But I will make another PR for this so that we can atomically revert in case I was wrong (See the comment on the code)
This commit is contained in:
parent
bf1f16ef47
commit
55a402bb75
1
ast.c
1
ast.c
@ -802,7 +802,6 @@ ast_node_script_lines(rb_execution_context_t *ec, VALUE self)
|
|||||||
TypedData_Get_Struct(self, struct ASTNodeData, &rb_node_type, data);
|
TypedData_Get_Struct(self, struct ASTNodeData, &rb_node_type, data);
|
||||||
ast = rb_ruby_ast_data_get(data->vast);
|
ast = rb_ruby_ast_data_get(data->vast);
|
||||||
rb_parser_ary_t *ret = ast->body.script_lines;
|
rb_parser_ary_t *ret = ast->body.script_lines;
|
||||||
if (!ret || FIXNUM_P((VALUE)ret)) return Qnil;
|
|
||||||
return rb_parser_build_script_lines_from(ret);
|
return rb_parser_build_script_lines_from(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1479,7 +1479,7 @@ new_child_iseq(rb_iseq_t *iseq, const NODE *const node,
|
|||||||
VALUE name, const rb_iseq_t *parent, enum rb_iseq_type type, int line_no)
|
VALUE name, const rb_iseq_t *parent, enum rb_iseq_type type, int line_no)
|
||||||
{
|
{
|
||||||
rb_iseq_t *ret_iseq;
|
rb_iseq_t *ret_iseq;
|
||||||
VALUE vast = rb_ruby_ast_new(node, NULL);
|
VALUE vast = rb_ruby_ast_new(node);
|
||||||
|
|
||||||
debugs("[new_child_iseq]> ---------------------------------------\n");
|
debugs("[new_child_iseq]> ---------------------------------------\n");
|
||||||
int isolated_depth = ISEQ_COMPILE_DATA(iseq)->isolated_depth;
|
int isolated_depth = ISEQ_COMPILE_DATA(iseq)->isolated_depth;
|
||||||
@ -8771,7 +8771,7 @@ compile_builtin_mandatory_only_method(rb_iseq_t *iseq, const NODE *node, const N
|
|||||||
scope_node.nd_body = mandatory_node(iseq, node);
|
scope_node.nd_body = mandatory_node(iseq, node);
|
||||||
scope_node.nd_args = &args_node;
|
scope_node.nd_args = &args_node;
|
||||||
|
|
||||||
VALUE vast = rb_ruby_ast_new(RNODE(&scope_node), NULL);
|
VALUE vast = rb_ruby_ast_new(RNODE(&scope_node));
|
||||||
|
|
||||||
ISEQ_BODY(iseq)->mandatory_only_iseq =
|
ISEQ_BODY(iseq)->mandatory_only_iseq =
|
||||||
rb_iseq_new_with_opt(vast, rb_iseq_base_label(iseq),
|
rb_iseq_new_with_opt(vast, rb_iseq_base_label(iseq),
|
||||||
|
@ -96,7 +96,7 @@ enum lex_state_e {
|
|||||||
EXPR_NONE = 0
|
EXPR_NONE = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
VALUE rb_ruby_ast_new(const NODE *const root, rb_parser_ary_t *script_lines);
|
VALUE rb_ruby_ast_new(const NODE *const root);
|
||||||
rb_ast_t *rb_ruby_ast_data_get(VALUE vast);
|
rb_ast_t *rb_ruby_ast_data_get(VALUE vast);
|
||||||
|
|
||||||
#endif /* INTERNAL_RUBY_PARSE_H */
|
#endif /* INTERNAL_RUBY_PARSE_H */
|
||||||
|
11
iseq.c
11
iseq.c
@ -851,14 +851,7 @@ static int
|
|||||||
ast_line_count(const VALUE vast)
|
ast_line_count(const VALUE vast)
|
||||||
{
|
{
|
||||||
rb_ast_t *ast = rb_ruby_ast_data_get(vast);
|
rb_ast_t *ast = rb_ruby_ast_data_get(vast);
|
||||||
if (!ast || !ast->body.script_lines) {
|
return ast->body.line_count;
|
||||||
// this occurs when failed to parse the source code with a syntax error
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (!FIXNUM_P((VALUE)ast->body.script_lines)) {
|
|
||||||
return (int)ast->body.script_lines->len;
|
|
||||||
}
|
|
||||||
return FIX2INT((VALUE)ast->body.script_lines);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
@ -999,7 +992,7 @@ rb_iseq_new_with_opt(const VALUE vast, VALUE name, VALUE path, VALUE realpath,
|
|||||||
if (!NIL_P(script_lines)) {
|
if (!NIL_P(script_lines)) {
|
||||||
// noop
|
// noop
|
||||||
}
|
}
|
||||||
else if (body && !FIXNUM_P((VALUE)body->script_lines) && body->script_lines) {
|
else if (body && body->script_lines) {
|
||||||
script_lines = rb_parser_build_script_lines_from(body->script_lines);
|
script_lines = rb_parser_build_script_lines_from(body->script_lines);
|
||||||
}
|
}
|
||||||
else if (parent) {
|
else if (parent) {
|
||||||
|
15
node.c
15
node.c
@ -340,6 +340,7 @@ iterate_node_values(rb_ast_t *ast, node_buffer_list_t *nb, node_itr_t * func, vo
|
|||||||
static void
|
static void
|
||||||
script_lines_free(rb_ast_t *ast, rb_parser_ary_t *script_lines)
|
script_lines_free(rb_ast_t *ast, rb_parser_ary_t *script_lines)
|
||||||
{
|
{
|
||||||
|
if (!script_lines) return;
|
||||||
for (long i = 0; i < script_lines->len; i++) {
|
for (long i = 0; i < script_lines->len; i++) {
|
||||||
parser_string_free(ast, (rb_parser_string_t *)script_lines->data[i]);
|
parser_string_free(ast, (rb_parser_string_t *)script_lines->data[i]);
|
||||||
}
|
}
|
||||||
@ -358,10 +359,8 @@ rb_ast_free(rb_ast_t *ast)
|
|||||||
#ifdef UNIVERSAL_PARSER
|
#ifdef UNIVERSAL_PARSER
|
||||||
if (ast && ast->node_buffer) {
|
if (ast && ast->node_buffer) {
|
||||||
void (*free_func)(void *) = xfree;
|
void (*free_func)(void *) = xfree;
|
||||||
if (ast->body.script_lines && !FIXNUM_P((VALUE)ast->body.script_lines)) {
|
script_lines_free(ast, ast->body.script_lines);
|
||||||
script_lines_free(ast, ast->body.script_lines);
|
ast->body.script_lines = NULL;
|
||||||
ast->body.script_lines = NULL;
|
|
||||||
}
|
|
||||||
rb_node_buffer_free(ast, ast->node_buffer);
|
rb_node_buffer_free(ast, ast->node_buffer);
|
||||||
ast->node_buffer = 0;
|
ast->node_buffer = 0;
|
||||||
free_func(ast);
|
free_func(ast);
|
||||||
@ -418,7 +417,7 @@ rb_ast_memsize(const rb_ast_t *ast)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (script_lines && !FIXNUM_P((VALUE)script_lines)) {
|
if (script_lines) {
|
||||||
size += sizeof(rb_parser_ary_t);
|
size += sizeof(rb_parser_ary_t);
|
||||||
for (i = 0; i < script_lines->len; i++) {
|
for (i = 0; i < script_lines->len; i++) {
|
||||||
size += sizeof(rb_parser_string_t);
|
size += sizeof(rb_parser_string_t);
|
||||||
@ -436,10 +435,8 @@ rb_ast_dispose(rb_ast_t *ast)
|
|||||||
// noop. See the comment in rb_ast_free().
|
// noop. See the comment in rb_ast_free().
|
||||||
#else
|
#else
|
||||||
if (ast && ast->node_buffer) {
|
if (ast && ast->node_buffer) {
|
||||||
if (ast->body.script_lines && !FIXNUM_P((VALUE)ast->body.script_lines)) {
|
script_lines_free(ast, ast->body.script_lines);
|
||||||
script_lines_free(ast, ast->body.script_lines);
|
ast->body.script_lines = NULL;
|
||||||
ast->body.script_lines = NULL;
|
|
||||||
}
|
|
||||||
rb_node_buffer_free(ast, ast->node_buffer);
|
rb_node_buffer_free(ast, ast->node_buffer);
|
||||||
ast->node_buffer = 0;
|
ast->node_buffer = 0;
|
||||||
}
|
}
|
||||||
|
2
parse.y
2
parse.y
@ -7755,7 +7755,7 @@ yycompile0(VALUE arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
p->ast->body.root = tree;
|
p->ast->body.root = tree;
|
||||||
if (!p->ast->body.script_lines) p->ast->body.script_lines = (rb_parser_ary_t *)INT2FIX(p->line_count);
|
p->ast->body.line_count = p->line_count;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -893,6 +893,7 @@ VALUE
|
|||||||
rb_parser_build_script_lines_from(rb_parser_ary_t *lines)
|
rb_parser_build_script_lines_from(rb_parser_ary_t *lines)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
if (!lines) return Qnil;
|
||||||
if (lines->data_type != PARSER_ARY_DATA_SCRIPT_LINE) {
|
if (lines->data_type != PARSER_ARY_DATA_SCRIPT_LINE) {
|
||||||
rb_bug("unexpected rb_parser_ary_data_type (%d) for script lines", lines->data_type);
|
rb_bug("unexpected rb_parser_ary_data_type (%d) for script lines", lines->data_type);
|
||||||
}
|
}
|
||||||
@ -1115,7 +1116,7 @@ parser_aset_script_lines_for(VALUE path, rb_parser_ary_t *lines)
|
|||||||
{
|
{
|
||||||
VALUE hash, script_lines;
|
VALUE hash, script_lines;
|
||||||
ID script_lines_id;
|
ID script_lines_id;
|
||||||
if (NIL_P(path) || !lines || FIXNUM_P((VALUE)lines)) return;
|
if (NIL_P(path) || !lines) return;
|
||||||
CONST_ID(script_lines_id, "SCRIPT_LINES__");
|
CONST_ID(script_lines_id, "SCRIPT_LINES__");
|
||||||
if (!rb_const_defined_at(rb_cObject, script_lines_id)) return;
|
if (!rb_const_defined_at(rb_cObject, script_lines_id)) return;
|
||||||
hash = rb_const_get_at(rb_cObject, script_lines_id);
|
hash = rb_const_get_at(rb_cObject, script_lines_id);
|
||||||
@ -1126,7 +1127,7 @@ parser_aset_script_lines_for(VALUE path, rb_parser_ary_t *lines)
|
|||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
rb_ruby_ast_new(const NODE *const root, rb_parser_ary_t *script_lines)
|
rb_ruby_ast_new(const NODE *const root)
|
||||||
{
|
{
|
||||||
VALUE vast = ast_alloc();
|
VALUE vast = ast_alloc();
|
||||||
rb_ast_t *ast = DATA_PTR(vast);
|
rb_ast_t *ast = DATA_PTR(vast);
|
||||||
@ -1134,7 +1135,8 @@ rb_ruby_ast_new(const NODE *const root, rb_parser_ary_t *script_lines)
|
|||||||
.root = root,
|
.root = root,
|
||||||
.frozen_string_literal = -1,
|
.frozen_string_literal = -1,
|
||||||
.coverage_enabled = -1,
|
.coverage_enabled = -1,
|
||||||
.script_lines = script_lines
|
.script_lines = NULL,
|
||||||
|
.line_count = 0,
|
||||||
};
|
};
|
||||||
return vast;
|
return vast;
|
||||||
}
|
}
|
||||||
|
@ -1212,9 +1212,7 @@ typedef struct node_buffer_struct node_buffer_t;
|
|||||||
typedef struct rb_ast_body_struct {
|
typedef struct rb_ast_body_struct {
|
||||||
const NODE *root;
|
const NODE *root;
|
||||||
rb_parser_ary_t *script_lines;
|
rb_parser_ary_t *script_lines;
|
||||||
// script_lines is either:
|
int line_count;
|
||||||
// - a Fixnum that represents the line count of the original source, or
|
|
||||||
// - an rb_parser_ary_t* that contains the lines of the original source
|
|
||||||
signed int frozen_string_literal:2; /* -1: not specified, 0: false, 1: true */
|
signed int frozen_string_literal:2; /* -1: not specified, 0: false, 1: true */
|
||||||
signed int coverage_enabled:2; /* -1: not specified, 0: false, 1: true */
|
signed int coverage_enabled:2; /* -1: not specified, 0: false, 1: true */
|
||||||
} rb_ast_body_t;
|
} rb_ast_body_t;
|
||||||
|
12
vm.c
12
vm.c
@ -1480,7 +1480,17 @@ rb_binding_add_dynavars(VALUE bindval, rb_binding_t *bind, int dyncount, const I
|
|||||||
tmp_node.nd_body = 0;
|
tmp_node.nd_body = 0;
|
||||||
tmp_node.nd_args = 0;
|
tmp_node.nd_args = 0;
|
||||||
|
|
||||||
VALUE vast = rb_ruby_ast_new(RNODE(&tmp_node), (rb_parser_ary_t *)INT2FIX(-1));
|
VALUE vast = rb_ruby_ast_new(RNODE(&tmp_node));
|
||||||
|
{ /*
|
||||||
|
* TODO:
|
||||||
|
* Assigning -1 to line_count is to maintain the previous code.
|
||||||
|
* However, the author of this patch guesses this code is no longer necessary.
|
||||||
|
* We will try to remove this code in the next commit which is atomically
|
||||||
|
* revertable if the author is wrong.
|
||||||
|
*/
|
||||||
|
rb_ast_t *ast = (rb_ast_t *)DATA_PTR(vast);
|
||||||
|
ast->body.line_count = -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (base_iseq) {
|
if (base_iseq) {
|
||||||
iseq = rb_iseq_new(vast, ISEQ_BODY(base_iseq)->location.label, path, realpath, base_iseq, ISEQ_TYPE_EVAL);
|
iseq = rb_iseq_new(vast, ISEQ_BODY(base_iseq)->location.label, path, realpath, base_iseq, ISEQ_TYPE_EVAL);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user