[Bug #20969] Pass assignable
from ripper
For the universal parser, `rb_reg_named_capture_assign_iter_impl` function is shared between the parser and ripper. However `parser_params` struct is partially different, and `assignable` function depends on that part indirectly.
This commit is contained in:
parent
a58675386c
commit
7b2ae8df90
Notes:
git
2024-12-19 15:08:23 +00:00
@ -79,8 +79,9 @@ void rb_parser_string_free(rb_parser_t *p, rb_parser_string_t *str);
|
|||||||
int rb_parser_dvar_defined_ref(struct parser_params*, ID, ID**);
|
int rb_parser_dvar_defined_ref(struct parser_params*, ID, ID**);
|
||||||
ID rb_parser_internal_id(struct parser_params*);
|
ID rb_parser_internal_id(struct parser_params*);
|
||||||
int rb_parser_reg_fragment_check(struct parser_params*, rb_parser_string_t*, int);
|
int rb_parser_reg_fragment_check(struct parser_params*, rb_parser_string_t*, int);
|
||||||
int rb_reg_named_capture_assign_iter_impl(struct parser_params *p, const char *s, long len, rb_encoding *enc, NODE **succ_block, const rb_code_location_t *loc);
|
int rb_reg_named_capture_assign_iter_impl(struct parser_params *p, const char *s, long len, rb_encoding *enc, NODE **succ_block, const rb_code_location_t *loc, rb_parser_assignable_func assignable);
|
||||||
int rb_parser_local_defined(struct parser_params *p, ID id, const struct rb_iseq_struct *iseq);
|
int rb_parser_local_defined(struct parser_params *p, ID id, const struct rb_iseq_struct *iseq);
|
||||||
|
NODE *rb_parser_assignable(struct parser_params *p, ID id, NODE *val, const YYLTYPE *loc);
|
||||||
|
|
||||||
RUBY_SYMBOL_EXPORT_END
|
RUBY_SYMBOL_EXPORT_END
|
||||||
|
|
||||||
|
18
parse.y
18
parse.y
@ -76,7 +76,7 @@ syntax_error_new(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static NODE *reg_named_capture_assign(struct parser_params* p, VALUE regexp, const YYLTYPE *loc);
|
static NODE *reg_named_capture_assign(struct parser_params* p, VALUE regexp, const YYLTYPE *loc, rb_parser_assignable_func assignable);
|
||||||
|
|
||||||
#define compile_callback rb_suppress_tracing
|
#define compile_callback rb_suppress_tracing
|
||||||
#endif /* !UNIVERSAL_PARSER */
|
#endif /* !UNIVERSAL_PARSER */
|
||||||
@ -12916,7 +12916,7 @@ match_op(struct parser_params *p, NODE *node1, NODE *node2, const YYLTYPE *op_lo
|
|||||||
const VALUE lit = rb_node_regx_string_val(n);
|
const VALUE lit = rb_node_regx_string_val(n);
|
||||||
if (!NIL_P(lit)) {
|
if (!NIL_P(lit)) {
|
||||||
NODE *match = NEW_MATCH2(node1, node2, loc);
|
NODE *match = NEW_MATCH2(node1, node2, loc);
|
||||||
RNODE_MATCH2(match)->nd_args = reg_named_capture_assign(p, lit, loc);
|
RNODE_MATCH2(match)->nd_args = reg_named_capture_assign(p, lit, loc, assignable);
|
||||||
nd_set_line(match, line);
|
nd_set_line(match, line);
|
||||||
return match;
|
return match;
|
||||||
}
|
}
|
||||||
@ -15402,6 +15402,7 @@ typedef struct {
|
|||||||
rb_encoding *enc;
|
rb_encoding *enc;
|
||||||
NODE *succ_block;
|
NODE *succ_block;
|
||||||
const YYLTYPE *loc;
|
const YYLTYPE *loc;
|
||||||
|
rb_parser_assignable_func assignable;
|
||||||
} reg_named_capture_assign_t;
|
} reg_named_capture_assign_t;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -15414,11 +15415,11 @@ reg_named_capture_assign_iter(const OnigUChar *name, const OnigUChar *name_end,
|
|||||||
long len = name_end - name;
|
long len = name_end - name;
|
||||||
const char *s = (const char *)name;
|
const char *s = (const char *)name;
|
||||||
|
|
||||||
return rb_reg_named_capture_assign_iter_impl(p, s, len, enc, &arg->succ_block, arg->loc);
|
return rb_reg_named_capture_assign_iter_impl(p, s, len, enc, &arg->succ_block, arg->loc, arg->assignable);
|
||||||
}
|
}
|
||||||
|
|
||||||
static NODE *
|
static NODE *
|
||||||
reg_named_capture_assign(struct parser_params* p, VALUE regexp, const YYLTYPE *loc)
|
reg_named_capture_assign(struct parser_params* p, VALUE regexp, const YYLTYPE *loc, rb_parser_assignable_func assignable)
|
||||||
{
|
{
|
||||||
reg_named_capture_assign_t arg;
|
reg_named_capture_assign_t arg;
|
||||||
|
|
||||||
@ -15426,6 +15427,7 @@ reg_named_capture_assign(struct parser_params* p, VALUE regexp, const YYLTYPE *l
|
|||||||
arg.enc = rb_enc_get(regexp);
|
arg.enc = rb_enc_get(regexp);
|
||||||
arg.succ_block = 0;
|
arg.succ_block = 0;
|
||||||
arg.loc = loc;
|
arg.loc = loc;
|
||||||
|
arg.assignable = assignable;
|
||||||
onig_foreach_name(RREGEXP_PTR(regexp), reg_named_capture_assign_iter, &arg);
|
onig_foreach_name(RREGEXP_PTR(regexp), reg_named_capture_assign_iter, &arg);
|
||||||
|
|
||||||
if (!arg.succ_block) return 0;
|
if (!arg.succ_block) return 0;
|
||||||
@ -15434,9 +15436,15 @@ reg_named_capture_assign(struct parser_params* p, VALUE regexp, const YYLTYPE *l
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef RIPPER
|
#ifndef RIPPER
|
||||||
|
NODE *
|
||||||
|
rb_parser_assignable(struct parser_params *p, ID id, NODE *val, const YYLTYPE *loc)
|
||||||
|
{
|
||||||
|
return assignable(p, id, val, loc);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
rb_reg_named_capture_assign_iter_impl(struct parser_params *p, const char *s, long len,
|
rb_reg_named_capture_assign_iter_impl(struct parser_params *p, const char *s, long len,
|
||||||
rb_encoding *enc, NODE **succ_block, const rb_code_location_t *loc)
|
rb_encoding *enc, NODE **succ_block, const rb_code_location_t *loc, rb_parser_assignable_func assignable)
|
||||||
{
|
{
|
||||||
ID var;
|
ID var;
|
||||||
NODE *node, *succ;
|
NODE *node, *succ;
|
||||||
|
@ -197,6 +197,7 @@ typedef struct {
|
|||||||
rb_encoding *enc;
|
rb_encoding *enc;
|
||||||
NODE *succ_block;
|
NODE *succ_block;
|
||||||
const rb_code_location_t *loc;
|
const rb_code_location_t *loc;
|
||||||
|
rb_parser_assignable_func assignable;
|
||||||
} reg_named_capture_assign_t;
|
} reg_named_capture_assign_t;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -210,11 +211,12 @@ reg_named_capture_assign_iter(const OnigUChar *name, const OnigUChar *name_end,
|
|||||||
long len = name_end - name;
|
long len = name_end - name;
|
||||||
const char *s = (const char *)name;
|
const char *s = (const char *)name;
|
||||||
|
|
||||||
return rb_reg_named_capture_assign_iter_impl(p, s, len, enc, &arg->succ_block, loc);
|
return rb_reg_named_capture_assign_iter_impl(p, s, len, enc, &arg->succ_block, loc, arg->assignable);
|
||||||
}
|
}
|
||||||
|
|
||||||
static NODE *
|
static NODE *
|
||||||
reg_named_capture_assign(struct parser_params* p, VALUE regexp, const rb_code_location_t *loc)
|
reg_named_capture_assign(struct parser_params* p, VALUE regexp, const rb_code_location_t *loc,
|
||||||
|
rb_parser_assignable_func assignable)
|
||||||
{
|
{
|
||||||
reg_named_capture_assign_t arg;
|
reg_named_capture_assign_t arg;
|
||||||
|
|
||||||
@ -222,6 +224,7 @@ reg_named_capture_assign(struct parser_params* p, VALUE regexp, const rb_code_lo
|
|||||||
arg.enc = rb_enc_get(regexp);
|
arg.enc = rb_enc_get(regexp);
|
||||||
arg.succ_block = 0;
|
arg.succ_block = 0;
|
||||||
arg.loc = loc;
|
arg.loc = loc;
|
||||||
|
arg.assignable = assignable;
|
||||||
onig_foreach_name(RREGEXP_PTR(regexp), reg_named_capture_assign_iter, &arg);
|
onig_foreach_name(RREGEXP_PTR(regexp), reg_named_capture_assign_iter, &arg);
|
||||||
|
|
||||||
if (!arg.succ_block) return 0;
|
if (!arg.succ_block) return 0;
|
||||||
|
@ -1171,6 +1171,8 @@ typedef struct parser_params rb_parser_t;
|
|||||||
typedef struct rb_imemo_tmpbuf_struct rb_imemo_tmpbuf_t;
|
typedef struct rb_imemo_tmpbuf_struct rb_imemo_tmpbuf_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef NODE *(*rb_parser_assignable_func)(struct parser_params *p, ID id, NODE *val, const rb_code_location_t *loc);
|
||||||
|
|
||||||
#ifdef UNIVERSAL_PARSER
|
#ifdef UNIVERSAL_PARSER
|
||||||
typedef struct rb_parser_config_struct {
|
typedef struct rb_parser_config_struct {
|
||||||
/* Memory */
|
/* Memory */
|
||||||
@ -1188,7 +1190,7 @@ typedef struct rb_parser_config_struct {
|
|||||||
|
|
||||||
// VALUE rb_suppress_tracing(VALUE (*func)(VALUE), VALUE arg);
|
// VALUE rb_suppress_tracing(VALUE (*func)(VALUE), VALUE arg);
|
||||||
VALUE (*compile_callback)(VALUE (*func)(VALUE), VALUE arg);
|
VALUE (*compile_callback)(VALUE (*func)(VALUE), VALUE arg);
|
||||||
NODE *(*reg_named_capture_assign)(struct parser_params* p, VALUE regexp, const rb_code_location_t *loc);
|
NODE *(*reg_named_capture_assign)(struct parser_params* p, VALUE regexp, const rb_code_location_t *loc, rb_parser_assignable_func assignable);
|
||||||
|
|
||||||
/* Variable */
|
/* Variable */
|
||||||
VALUE (*attr_get)(VALUE obj, ID id);
|
VALUE (*attr_get)(VALUE obj, ID id);
|
||||||
|
@ -148,6 +148,13 @@ end
|
|||||||
assert_nothing_raised { Ripper.lex src }
|
assert_nothing_raised { Ripper.lex src }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_assignable_in_regexp
|
||||||
|
assert_separately(%w(-rripper), "", "#{<<~"begin;"}\n#{<<~'end;'}")
|
||||||
|
begin;
|
||||||
|
assert_nil(Ripper.parse('/(?<_1>)/ =~ s'))
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
|
||||||
def test_no_memory_leak
|
def test_no_memory_leak
|
||||||
assert_no_memory_leak(%w(-rripper), "", "#{<<~'end;'}", rss: true)
|
assert_no_memory_leak(%w(-rripper), "", "#{<<~'end;'}", rss: true)
|
||||||
2_000_000.times do
|
2_000_000.times do
|
||||||
|
Loading…
x
Reference in New Issue
Block a user