Skip to content

Commit 7a05063

Browse files
committed
Introduce NODE_FILE
`__FILE__` was managed by `NODE_STR` with `String` object. This commit introduces `NODE_FILE` and `struct rb_parser_string` so that 1. `__FILE__` is detectable from AST Node 2. Reduce dependency ruby object
1 parent 91a0d1c commit 7a05063

File tree

12 files changed

+185
-37
lines changed

12 files changed

+185
-37
lines changed

ast.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,8 @@ node_children(rb_ast_t *ast, const NODE *node)
694694
}
695695
case NODE_LINE:
696696
return rb_ary_new_from_args(1, rb_node_line_lineno_val(node));
697+
case NODE_FILE:
698+
return rb_ary_new_from_args(1, rb_node_file_path_val(node));
697699
case NODE_ERROR:
698700
return rb_ary_new_from_node_args(ast, 0);
699701
case NODE_ARGS_AUX:

common.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10495,6 +10495,7 @@ node_dump.$(OBJEXT): $(top_srcdir)/internal/compilers.h
1049510495
node_dump.$(OBJEXT): $(top_srcdir)/internal/gc.h
1049610496
node_dump.$(OBJEXT): $(top_srcdir)/internal/hash.h
1049710497
node_dump.$(OBJEXT): $(top_srcdir)/internal/imemo.h
10498+
node_dump.$(OBJEXT): $(top_srcdir)/internal/ruby_parser.h
1049810499
node_dump.$(OBJEXT): $(top_srcdir)/internal/serial.h
1049910500
node_dump.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
1050010501
node_dump.$(OBJEXT): $(top_srcdir)/internal/variable.h

compile.c

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -819,7 +819,6 @@ get_nd_vid(const NODE *node)
819819
}
820820
}
821821

822-
823822
static NODE *
824823
get_nd_value(const NODE *node)
825824
{
@@ -833,6 +832,19 @@ get_nd_value(const NODE *node)
833832
}
834833
}
835834

835+
static VALUE
836+
get_string_value(const NODE *node)
837+
{
838+
switch (nd_type(node)) {
839+
case NODE_STR:
840+
return RNODE_STR(node)->nd_lit;
841+
case NODE_FILE:
842+
return rb_node_file_path_val(node);
843+
default:
844+
rb_bug("unexpected node: %s", ruby_node_name(nd_type(node)));
845+
}
846+
}
847+
836848
VALUE
837849
rb_iseq_compile_callback(rb_iseq_t *iseq, const struct rb_iseq_new_with_callback_callback_func * ifunc)
838850
{
@@ -4282,7 +4294,7 @@ all_string_result_p(const NODE *node)
42824294
{
42834295
if (!node) return FALSE;
42844296
switch (nd_type(node)) {
4285-
case NODE_STR: case NODE_DSTR:
4297+
case NODE_STR: case NODE_DSTR: case NODE_FILE:
42864298
return TRUE;
42874299
case NODE_IF: case NODE_UNLESS:
42884300
if (!RNODE_IF(node)->nd_body || !RNODE_IF(node)->nd_else) return FALSE;
@@ -4493,6 +4505,7 @@ compile_branch_condition(rb_iseq_t *iseq, LINK_ANCHOR *ret, const NODE *cond,
44934505
goto again;
44944506
case NODE_LIT: /* NODE_LIT is always true */
44954507
case NODE_LINE:
4508+
case NODE_FILE:
44964509
case NODE_TRUE:
44974510
case NODE_STR:
44984511
case NODE_ZLIST:
@@ -4658,6 +4671,7 @@ static_literal_node_p(const NODE *node, const rb_iseq_t *iseq)
46584671
case NODE_FALSE:
46594672
return TRUE;
46604673
case NODE_STR:
4674+
case NODE_FILE:
46614675
return ISEQ_COMPILE_DATA(iseq)->option->frozen_string_literal;
46624676
default:
46634677
return FALSE;
@@ -4676,16 +4690,17 @@ static_literal_value(const NODE *node, rb_iseq_t *iseq)
46764690
return Qfalse;
46774691
case NODE_LINE:
46784692
return rb_node_line_lineno_val(node);
4693+
case NODE_FILE:
46794694
case NODE_STR:
46804695
if (ISEQ_COMPILE_DATA(iseq)->option->debug_frozen_string_literal || RTEST(ruby_debug)) {
46814696
VALUE lit;
46824697
VALUE debug_info = rb_ary_new_from_args(2, rb_iseq_path(iseq), INT2FIX((int)nd_line(node)));
4683-
lit = rb_str_dup(RNODE_STR(node)->nd_lit);
4698+
lit = rb_str_dup(get_string_value(node));
46844699
rb_ivar_set(lit, id_debug_created_info, rb_obj_freeze(debug_info));
46854700
return rb_str_freeze(lit);
46864701
}
46874702
else {
4688-
return rb_fstring(RNODE_STR(node)->nd_lit);
4703+
return rb_fstring(get_string_value(node));
46894704
}
46904705
case NODE_LIT:
46914706
return RNODE_LIT(node)->nd_lit;
@@ -5067,6 +5082,8 @@ rb_node_case_when_optimizable_literal(const NODE *const node)
50675082
return rb_node_line_lineno_val(node);
50685083
case NODE_STR:
50695084
return rb_fstring(RNODE_STR(node)->nd_lit);
5085+
case NODE_FILE:
5086+
return rb_fstring(rb_node_file_path_val(node));
50705087
}
50715088
return Qundef;
50725089
}
@@ -5086,9 +5103,9 @@ when_vals(rb_iseq_t *iseq, LINK_ANCHOR *const cond_seq, const NODE *vals,
50865103
rb_hash_aset(literals, lit, (VALUE)(l1) | 1);
50875104
}
50885105

5089-
if (nd_type_p(val, NODE_STR)) {
5090-
debugp_param("nd_lit", RNODE_STR(val)->nd_lit);
5091-
lit = rb_fstring(RNODE_STR(val)->nd_lit);
5106+
if (nd_type_p(val, NODE_STR) || nd_type_p(val, NODE_FILE)) {
5107+
debugp_param("nd_lit", get_string_value(val));
5108+
lit = rb_fstring(get_string_value(val));
50925109
ADD_INSN1(cond_seq, val, putobject, lit);
50935110
RB_OBJ_WRITTEN(iseq, Qundef, lit);
50945111
}
@@ -5692,6 +5709,7 @@ defined_expr0(rb_iseq_t *iseq, LINK_ANCHOR *const ret,
56925709
case NODE_STR:
56935710
case NODE_LIT:
56945711
case NODE_LINE:
5712+
case NODE_FILE:
56955713
case NODE_ZLIST:
56965714
case NODE_AND:
56975715
case NODE_OR:
@@ -7105,6 +7123,7 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c
71057123
}
71067124
case NODE_LIT:
71077125
case NODE_LINE:
7126+
case NODE_FILE:
71087127
case NODE_STR:
71097128
case NODE_XSTR:
71107129
case NODE_DSTR:
@@ -8321,12 +8340,13 @@ compile_call_precheck_freeze(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE
83218340
/* optimization shortcut
83228341
* "literal".freeze -> opt_str_freeze("literal")
83238342
*/
8324-
if (get_nd_recv(node) && nd_type_p(get_nd_recv(node), NODE_STR) &&
8343+
if (get_nd_recv(node) &&
8344+
(nd_type_p(get_nd_recv(node), NODE_STR) || nd_type_p(get_nd_recv(node), NODE_FILE)) &&
83258345
(get_node_call_nd_mid(node) == idFreeze || get_node_call_nd_mid(node) == idUMinus) &&
83268346
get_nd_args(node) == NULL &&
83278347
ISEQ_COMPILE_DATA(iseq)->current_block == NULL &&
83288348
ISEQ_COMPILE_DATA(iseq)->option->specialized_instruction) {
8329-
VALUE str = rb_fstring(RNODE_STR(get_nd_recv(node))->nd_lit);
8349+
VALUE str = rb_fstring(get_string_value(get_nd_recv(node)));
83308350
if (get_node_call_nd_mid(node) == idUMinus) {
83318351
ADD_INSN2(ret, line_node, opt_str_uminus, str,
83328352
new_callinfo(iseq, idUMinus, 0, 0, NULL, FALSE));
@@ -8346,11 +8366,11 @@ compile_call_precheck_freeze(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE
83468366
*/
83478367
if (get_node_call_nd_mid(node) == idAREF && !private_recv_p(node) && get_nd_args(node) &&
83488368
nd_type_p(get_nd_args(node), NODE_LIST) && RNODE_LIST(get_nd_args(node))->as.nd_alen == 1 &&
8349-
nd_type_p(RNODE_LIST(get_nd_args(node))->nd_head, NODE_STR) &&
8369+
(nd_type_p(RNODE_LIST(get_nd_args(node))->nd_head, NODE_STR) || nd_type_p(RNODE_LIST(get_nd_args(node))->nd_head, NODE_FILE)) &&
83508370
ISEQ_COMPILE_DATA(iseq)->current_block == NULL &&
83518371
!ISEQ_COMPILE_DATA(iseq)->option->frozen_string_literal &&
83528372
ISEQ_COMPILE_DATA(iseq)->option->specialized_instruction) {
8353-
VALUE str = rb_fstring(RNODE_STR(RNODE_LIST(get_nd_args(node))->nd_head)->nd_lit);
8373+
VALUE str = rb_fstring(get_string_value(RNODE_LIST(get_nd_args(node))->nd_head));
83548374
CHECK(COMPILE(ret, "recv", get_nd_recv(node)));
83558375
ADD_INSN2(ret, line_node, opt_aref_with, str,
83568376
new_callinfo(iseq, idAREF, 1, 0, NULL, FALSE));
@@ -9697,12 +9717,12 @@ compile_attrasgn(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node
96979717
*/
96989718
if (mid == idASET && !private_recv_p(node) && RNODE_ATTRASGN(node)->nd_args &&
96999719
nd_type_p(RNODE_ATTRASGN(node)->nd_args, NODE_LIST) && RNODE_LIST(RNODE_ATTRASGN(node)->nd_args)->as.nd_alen == 2 &&
9700-
nd_type_p(RNODE_LIST(RNODE_ATTRASGN(node)->nd_args)->nd_head, NODE_STR) &&
9720+
(nd_type_p(RNODE_LIST(RNODE_ATTRASGN(node)->nd_args)->nd_head, NODE_STR) || nd_type_p(RNODE_LIST(RNODE_ATTRASGN(node)->nd_args)->nd_head, NODE_FILE)) &&
97019721
ISEQ_COMPILE_DATA(iseq)->current_block == NULL &&
97029722
!ISEQ_COMPILE_DATA(iseq)->option->frozen_string_literal &&
97039723
ISEQ_COMPILE_DATA(iseq)->option->specialized_instruction)
97049724
{
9705-
VALUE str = rb_fstring(RNODE_STR(RNODE_LIST(RNODE_ATTRASGN(node)->nd_args)->nd_head)->nd_lit);
9725+
VALUE str = rb_fstring(get_string_value(RNODE_LIST(RNODE_ATTRASGN(node)->nd_args)->nd_head));
97069726
CHECK(COMPILE(ret, "recv", RNODE_ATTRASGN(node)->nd_recv));
97079727
CHECK(COMPILE(ret, "value", RNODE_LIST(RNODE_LIST(RNODE_ATTRASGN(node)->nd_args)->nd_next)->nd_head));
97089728
if (!popped) {
@@ -10134,10 +10154,11 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no
1013410154
}
1013510155
break;
1013610156
}
10157+
case NODE_FILE:
1013710158
case NODE_STR:{
10138-
debugp_param("nd_lit", RNODE_STR(node)->nd_lit);
10159+
debugp_param("nd_lit", get_string_value(node));
1013910160
if (!popped) {
10140-
VALUE lit = RNODE_STR(node)->nd_lit;
10161+
VALUE lit = get_string_value(node);
1014110162
if (!ISEQ_COMPILE_DATA(iseq)->option->frozen_string_literal) {
1014210163
lit = rb_fstring(lit);
1014310164
ADD_INSN1(ret, node, putstring, lit);

internal/ruby_parser.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,5 @@ enum lex_state_e {
6868
};
6969

7070
VALUE rb_node_line_lineno_val(const NODE *);
71+
VALUE rb_node_file_path_val(const NODE *);
7172
#endif /* INTERNAL_RUBY_PARSE_H */

misc/lldb_rb/utils.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,8 @@ def inspect(self, val):
457457
self._append_expression("*(struct RNode_ERROR *) %0#x" % val.GetValueAsUnsigned())
458458
elif nd_type == self.ruby_globals["NODE_LINE"]:
459459
self._append_expression("*(struct RNode_LINE *) %0#x" % val.GetValueAsUnsigned())
460+
elif nd_type == self.ruby_globals["NODE_FILE"]:
461+
self._append_expression("*(struct RNode_FILE *) %0#x" % val.GetValueAsUnsigned())
460462
elif nd_type == self.ruby_globals["NODE_RIPPER"]:
461463
self._append_expression("*(struct RNode_RIPPER *) %0#x" % val.GetValueAsUnsigned())
462464
elif nd_type == self.ruby_globals["NODE_RIPPER_VALUES"]:

node.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,10 +169,19 @@ struct rb_ast_local_table_link {
169169
// }
170170
};
171171

172+
static void
173+
parser_string_free(rb_ast_t *ast, rb_parser_string_t *str)
174+
{
175+
xfree(str);
176+
}
177+
172178
static void
173179
free_ast_value(rb_ast_t *ast, void *ctx, NODE *node)
174180
{
175181
switch (nd_type(node)) {
182+
case NODE_FILE:
183+
parser_string_free(ast, RNODE_FILE(node)->path);
184+
break;
176185
default:
177186
break;
178187
}

node_dump.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include "internal.h"
1313
#include "internal/hash.h"
14+
#include "internal/ruby_parser.h"
1415
#include "internal/variable.h"
1516
#include "ruby/ruby.h"
1617
#include "vm_core.h"
@@ -64,6 +65,7 @@
6465
#define F_INT(name, type, ann) SIMPLE_FIELD1(#name, ann) A_INT(type(node)->name)
6566
#define F_LONG(name, type, ann) SIMPLE_FIELD1(#name, ann) A_LONG(type(node)->name)
6667
#define F_LIT(name, type, ann) SIMPLE_FIELD1(#name, ann) A_LIT(type(node)->name)
68+
#define F_VALUE(name, val, ann) SIMPLE_FIELD1(#name, ann) A_LIT(val)
6769
#define F_MSG(name, ann, desc) SIMPLE_FIELD1(#name, ann) A(desc)
6870

6971
#define F_NODE(name, type, ann) \
@@ -1105,6 +1107,13 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node)
11051107
ANN("example: __LINE__");
11061108
return;
11071109

1110+
case NODE_FILE:
1111+
ANN("line");
1112+
ANN("format: [path]");
1113+
ANN("example: __FILE__");
1114+
F_VALUE(path, rb_node_file_path_val(node), "path");
1115+
return;
1116+
11081117
case NODE_ERROR:
11091118
ANN("Broken input recovered by Error Tolerant mode");
11101119
return;

parse.y

Lines changed: 72 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -954,6 +954,7 @@ static rb_node_aryptn_t *rb_node_aryptn_new(struct parser_params *p, NODE *pre_a
954954
static rb_node_hshptn_t *rb_node_hshptn_new(struct parser_params *p, NODE *nd_pconst, NODE *nd_pkwargs, NODE *nd_pkwrestarg, const YYLTYPE *loc);
955955
static rb_node_fndptn_t *rb_node_fndptn_new(struct parser_params *p, NODE *pre_rest_arg, NODE *args, NODE *post_rest_arg, const YYLTYPE *loc);
956956
static rb_node_line_t *rb_node_line_new(struct parser_params *p, const YYLTYPE *loc);
957+
static rb_node_file_t *rb_node_file_new(struct parser_params *p, VALUE str, const YYLTYPE *loc);
957958
static rb_node_error_t *rb_node_error_new(struct parser_params *p, const YYLTYPE *loc);
958959

959960
#define NEW_SCOPE(a,b,loc) (NODE *)rb_node_scope_new(p,a,b,loc)
@@ -1056,6 +1057,7 @@ static rb_node_error_t *rb_node_error_new(struct parser_params *p, const YYLTYPE
10561057
#define NEW_HSHPTN(c,kw,kwrest,loc) (NODE *)rb_node_hshptn_new(p,c,kw,kwrest,loc)
10571058
#define NEW_FNDPTN(pre,a,post,loc) (NODE *)rb_node_fndptn_new(p,pre,a,post,loc)
10581059
#define NEW_LINE(loc) (NODE *)rb_node_line_new(p,loc)
1060+
#define NEW_FILE(str,loc) (NODE *)rb_node_file_new(p,str,loc)
10591061
#define NEW_ERROR(loc) (NODE *)rb_node_error_new(p,loc)
10601062

10611063
#endif
@@ -1911,6 +1913,56 @@ get_nd_args(struct parser_params *p, NODE *node)
19111913
}
19121914
}
19131915
#endif
1916+
1917+
#ifndef RIPPER
1918+
static rb_parser_string_t *
1919+
rb_parser_string_new(rb_parser_t *p, const char *ptr, long len)
1920+
{
1921+
size_t size;
1922+
rb_parser_string_t *str;
1923+
1924+
if (len < 0) {
1925+
rb_bug("negative string size (or size too big): %ld", len);
1926+
}
1927+
1928+
size = offsetof(rb_parser_string_t, ptr) + len + 1;
1929+
str = xcalloc(1, size);
1930+
1931+
if (ptr) {
1932+
memcpy(str->ptr, ptr, len);
1933+
}
1934+
str->len = len;
1935+
str->ptr[len] = '\0';
1936+
return str;
1937+
}
1938+
1939+
static rb_parser_string_t *
1940+
rb_parser_encoding_string_new(rb_parser_t *p, const char *ptr, long len, rb_encoding *enc)
1941+
{
1942+
rb_parser_string_t *str = rb_parser_string_new(p, ptr, len);
1943+
str->enc = enc;
1944+
return str;
1945+
}
1946+
1947+
long
1948+
rb_parser_string_length(rb_parser_string_t *str)
1949+
{
1950+
return str->len;
1951+
}
1952+
1953+
char *
1954+
rb_parser_string_pointer(rb_parser_string_t *str)
1955+
{
1956+
return str->ptr;
1957+
}
1958+
1959+
static rb_parser_string_t *
1960+
rb_str_to_parser_encoding_string(rb_parser_t *p, VALUE str)
1961+
{
1962+
/* Type check */
1963+
return rb_parser_encoding_string_new(p, RSTRING_PTR(str), RSTRING_LEN(str), rb_enc_get(str));
1964+
}
1965+
#endif
19141966
%}
19151967

19161968
%expect 0
@@ -6599,6 +6651,7 @@ singleton : var_ref
65996651
case NODE_DREGX:
66006652
case NODE_LIT:
66016653
case NODE_LINE:
6654+
case NODE_FILE:
66026655
case NODE_DSYM:
66036656
case NODE_LIST:
66046657
case NODE_ZLIST:
@@ -12186,6 +12239,15 @@ rb_node_line_new(struct parser_params *p, const YYLTYPE *loc)
1218612239
return n;
1218712240
}
1218812241

12242+
static rb_node_file_t *
12243+
rb_node_file_new(struct parser_params *p, VALUE str, const YYLTYPE *loc)
12244+
{
12245+
rb_node_file_t *n = NODE_NEWNODE(NODE_FILE, rb_node_file_t, loc);
12246+
n->path = rb_str_to_parser_encoding_string(p, str);
12247+
12248+
return n;
12249+
}
12250+
1218912251
static rb_node_cdecl_t *
1219012252
rb_node_cdecl_new(struct parser_params *p, ID nd_vid, NODE *nd_value, NODE *nd_else, const YYLTYPE *loc)
1219112253
{
@@ -12786,10 +12848,7 @@ gettable(struct parser_params *p, ID id, const YYLTYPE *loc)
1278612848
VALUE file = p->ruby_sourcefile_string;
1278712849
if (NIL_P(file))
1278812850
file = rb_str_new(0, 0);
12789-
else
12790-
file = rb_str_dup(file);
12791-
node = NEW_STR(file, loc);
12792-
RB_OBJ_WRITTEN(p->ast, Qnil, file);
12851+
node = NEW_FILE(file, loc);
1279312852
}
1279412853
return node;
1279512854
case keyword__LINE__:
@@ -13691,6 +13750,12 @@ shareable_literal_constant(struct parser_params *p, enum shareability shareable,
1369113750
RB_OBJ_WRITE(p->ast, &RNODE_LIT(value)->nd_lit, lit);
1369213751
return value;
1369313752

13753+
case NODE_FILE:
13754+
lit = rb_fstring(rb_node_file_path_val(value));
13755+
value = NEW_LIT(lit, loc);
13756+
RB_OBJ_WRITTEN(p->ast, Qnil, RNODE_LIT(value)->nd_lit);
13757+
return value;
13758+
1369413759
case NODE_ZLIST:
1369513760
lit = rb_ary_new();
1369613761
OBJ_FREEZE_RAW(lit);
@@ -13985,6 +14050,7 @@ void_expr(struct parser_params *p, NODE *node)
1398514050
break;
1398614051
case NODE_LIT:
1398714052
case NODE_LINE:
14053+
case NODE_FILE:
1398814054
case NODE_STR:
1398914055
case NODE_DSTR:
1399014056
case NODE_DREGX:
@@ -14123,6 +14189,7 @@ is_static_content(NODE *node)
1412314189
} while ((node = RNODE_LIST(node)->nd_next) != 0);
1412414190
case NODE_LIT:
1412514191
case NODE_LINE:
14192+
case NODE_FILE:
1412614193
case NODE_STR:
1412714194
case NODE_NIL:
1412814195
case NODE_TRUE:
@@ -14208,6 +14275,7 @@ cond0(struct parser_params *p, NODE *node, enum cond_type type, const YYLTYPE *l
1420814275
case NODE_DSTR:
1420914276
case NODE_EVSTR:
1421014277
case NODE_STR:
14278+
case NODE_FILE:
1421114279
SWITCH_BY_COND_TYPE(type, warn, "string ");
1421214280
break;
1421314281

0 commit comments

Comments
 (0)