Skip to content

Commit

Permalink
[Bug #20504] Move string literal concatenation to iseq compiler
Browse files Browse the repository at this point in the history
  • Loading branch information
nobu committed Dec 28, 2024
1 parent 931f376 commit 0241b2e
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 53 deletions.
50 changes: 27 additions & 23 deletions compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -4506,42 +4506,46 @@ static int
compile_dstr_fragments(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int *cntp)
{
const struct RNode_LIST *list = RNODE_DSTR(node)->nd_next;
VALUE lit = rb_node_dstr_string_val(node);
LINK_ELEMENT *first_lit = 0;
rb_parser_string_t *str = RNODE_DSTR(node)->string;
VALUE lit = 0;
const NODE *lit_node = node;
int cnt = 0;

debugp_param("nd_lit", lit);
if (!NIL_P(lit)) {
cnt++;
if (!RB_TYPE_P(lit, T_STRING)) {
COMPILE_ERROR(ERROR_ARGS "dstr: must be string: %s",
rb_builtin_type_name(TYPE(lit)));
return COMPILE_NG;
}
lit = rb_fstring(lit);
ADD_INSN1(ret, node, putobject, lit);
RB_OBJ_WRITTEN(iseq, Qundef, lit);
if (RSTRING_LEN(lit) == 0) first_lit = LAST_ELEMENT(ret);
if (str) {
lit = rb_str_new_mutable_parser_string(str);
debugp_param("nd_lit", lit);
}

# define FLUSH_LIT() if (lit) { \
lit = rb_fstring(lit); \
ADD_INSN1(ret, lit_node, putobject, lit); \
RB_OBJ_WRITTEN(iseq, Qundef, lit); \
cnt++; \
}

while (list) {
const NODE *const head = list->nd_head;
if (nd_type_p(head, NODE_STR)) {
lit = rb_node_str_string_val(head);
ADD_INSN1(ret, head, putobject, lit);
RB_OBJ_WRITTEN(iseq, Qundef, lit);
lit = Qnil;
str = RNODE_STR(head)->string;
if (lit) {
rb_enc_str_buf_cat(lit, str->ptr, str->len, str->enc);
}
else {
lit = rb_str_new_mutable_parser_string(str);
lit_node = head;
}
}
else {
FLUSH_LIT();
lit = 0;
CHECK(COMPILE(ret, "each string", head));
cnt++;
}
cnt++;
list = (struct RNode_LIST *)list->nd_next;
}
if (NIL_P(lit) && first_lit) {
ELEM_REMOVE(first_lit);
--cnt;
}
FLUSH_LIT();
# undef FLUSH_LIT

*cntp = cnt;

return COMPILE_OK;
Expand Down
28 changes: 0 additions & 28 deletions parse.y
Original file line number Diff line number Diff line change
Expand Up @@ -13157,9 +13157,6 @@ symbol_append(struct parser_params *p, NODE *symbols, NODE *symbol)
static NODE *
new_regexp(struct parser_params *p, NODE *node, int options, const YYLTYPE *loc)
{
struct RNode_LIST *list;
NODE *prev;

if (!node) {
/* Check string is valid regex */
rb_parser_string_t *str = STRING_NEW0();
Expand Down Expand Up @@ -13187,31 +13184,6 @@ new_regexp(struct parser_params *p, NODE *node, int options, const YYLTYPE *loc)
/* Check string is valid regex */
reg_compile(p, dreg->string, options);
}
prev = node;
for (list = dreg->nd_next; list; list = RNODE_LIST(list->nd_next)) {
NODE *frag = list->nd_head;
enum node_type type = nd_type(frag);
if (type == NODE_STR || (type == NODE_DSTR && !RNODE_DSTR(frag)->nd_next)) {
rb_parser_string_t *tail = RNODE_STR(frag)->string;
if (prev && RNODE_DREGX(prev)->string) {
rb_parser_string_t *lit = prev == node ? dreg->string : RNODE_STR(RNODE_LIST(prev)->nd_head)->string;
if (!literal_concat0(p, lit, tail)) {
return NEW_NIL(loc); /* dummy node on error */
}
rb_parser_str_resize(p, tail, 0);
RNODE_LIST(prev)->nd_next = list->nd_next;
rb_discard_node(p, list->nd_head);
rb_discard_node(p, (NODE *)list);
list = RNODE_LIST(prev);
}
else {
prev = (NODE *)list;
}
}
else {
prev = 0;
}
}
if (options & RE_OPTION_ONCE) {
node = NEW_ONCE(node, loc);
}
Expand Down
1 change: 0 additions & 1 deletion test/.excludes-parsey/TestM17N.rb

This file was deleted.

1 change: 0 additions & 1 deletion test/.excludes-parsey/TestMixedUnicodeEscape.rb

This file was deleted.

0 comments on commit 0241b2e

Please sign in to comment.