Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,24 @@ dump_array(VALUE ast_value, const struct RNode_LIST *node)
return ary;
}

static VALUE
dump_parser_array(VALUE ast_value, rb_parser_ary_t *p_ary)
{
VALUE ary;

if (p_ary->data_type != PARSER_ARY_DATA_NODE) {
rb_bug("unexpected rb_parser_ary_data_type: %d", p_ary->data_type);
}

ary = rb_ary_new();

for (long i = 0; i < p_ary->len; i++) {
rb_ary_push(ary, NEW_CHILD(ast_value, p_ary->data[i]));
}

return ary;
}

static VALUE
var_name(ID id)
{
Expand Down Expand Up @@ -577,7 +595,7 @@ node_children(VALUE ast_value, const NODE *node)
case NODE_VALIAS:
return rb_ary_new_from_args(2, ID2SYM(RNODE_VALIAS(node)->nd_alias), ID2SYM(RNODE_VALIAS(node)->nd_orig));
case NODE_UNDEF:
return rb_ary_new_from_node_args(ast_value, 1, RNODE_UNDEF(node)->nd_undef);
return rb_ary_new_from_args(1, dump_parser_array(ast_value, RNODE_UNDEF(node)->nd_undefs));
case NODE_CLASS:
return rb_ary_new_from_node_args(ast_value, 3, RNODE_CLASS(node)->nd_cpath, RNODE_CLASS(node)->nd_super, RNODE_CLASS(node)->nd_body);
case NODE_MODULE:
Expand Down
16 changes: 12 additions & 4 deletions compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -11016,10 +11016,18 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no
break;
}
case NODE_UNDEF:{
ADD_INSN1(ret, node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
ADD_INSN1(ret, node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_CBASE));
CHECK(COMPILE(ret, "undef arg", RNODE_UNDEF(node)->nd_undef));
ADD_SEND(ret, node, id_core_undef_method, INT2FIX(2));
const rb_parser_ary_t *ary = RNODE_UNDEF(node)->nd_undefs;

for (long i = 0; i < ary->len; i++) {
ADD_INSN1(ret, node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
ADD_INSN1(ret, node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_CBASE));
CHECK(COMPILE(ret, "undef arg", ary->data[i]));
ADD_SEND(ret, node, id_core_undef_method, INT2FIX(2));

if (i < ary->len - 1) {
ADD_INSN(ret, node, pop);
}
}

if (popped) {
ADD_INSN(ret, node, pop);
Expand Down
11 changes: 11 additions & 0 deletions node.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,14 @@ parser_tokens_free(rb_ast_t *ast, rb_parser_ary_t *tokens)
xfree(tokens);
}

static void
parser_nodes_free(rb_ast_t *ast, rb_parser_ary_t *nodes)
{
/* Do nothing for nodes because nodes are freed when rb_ast_t is freed */
xfree(nodes->data);
xfree(nodes);
}

static void
free_ast_value(rb_ast_t *ast, void *ctx, NODE *node)
{
Expand Down Expand Up @@ -206,6 +214,9 @@ free_ast_value(rb_ast_t *ast, void *ctx, NODE *node)
case NODE_IMAGINARY:
xfree(RNODE_IMAGINARY(node)->val);
break;
case NODE_UNDEF:
parser_nodes_free(ast, RNODE_UNDEF(node)->nd_undefs);
break;
default:
break;
}
Expand Down
29 changes: 27 additions & 2 deletions node_dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@
#define F_NODE2(name, n, ann) \
COMPOUND_FIELD1(#name, ann) {dump_node(buf, indent, comment, n);}

#define F_ARRAY(name, type, ann) \
COMPOUND_FIELD1(#name, ann) {dump_parser_array(buf, indent, comment, type(node)->name);}

#define ANN(ann) \
if (comment) { \
A_INDENT; A("| # " ann "\n"); \
Expand Down Expand Up @@ -164,6 +167,28 @@ dump_array(VALUE buf, VALUE indent, int comment, const NODE *node)
F_NODE(nd_next, RNODE_LIST, "next element");
}

static void
dump_parser_array(VALUE buf, VALUE indent, int comment, const rb_parser_ary_t *ary)
{
int field_flag;
const char *next_indent = default_indent;

if (ary->data_type != PARSER_ARY_DATA_NODE) {
rb_bug("unexpected rb_parser_ary_data_type: %d", ary->data_type);
}

F_CUSTOM1(length, "length") { A_LONG(ary->len); }
for (long i = 0; i < ary->len; i++) {
if (i == ary->len - 1) LAST_NODE;
A_INDENT;
rb_str_catf(buf, "+- element (%s%ld):\n",
comment ? "statement #" : "", i);
D_INDENT;
dump_node(buf, indent, comment, ary->data[i]);
D_DEDENT;
}
}

static void
dump_node(VALUE buf, VALUE indent, int comment, const NODE * node)
{
Expand Down Expand Up @@ -896,10 +921,10 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node)

case NODE_UNDEF:
ANN("method undef statement");
ANN("format: undef [nd_undef]");
ANN("format: undef [nd_undefs]");
ANN("example: undef foo");
LAST_NODE;
F_NODE(nd_undef, RNODE_UNDEF, "old name");
F_ARRAY(nd_undefs, RNODE_UNDEF, "nd_undefs");
return;

case NODE_CLASS:
Expand Down
37 changes: 31 additions & 6 deletions parse.y
Original file line number Diff line number Diff line change
Expand Up @@ -2487,7 +2487,6 @@ rb_parser_string_hash_cmp(rb_parser_string_t *str1, rb_parser_string_t *str2)
memcmp(ptr1, ptr2, len1) != 0);
}

#ifndef RIPPER
static void
rb_parser_ary_extend(rb_parser_t *p, rb_parser_ary_t *ary, long len)
{
Expand All @@ -2503,7 +2502,7 @@ rb_parser_ary_extend(rb_parser_t *p, rb_parser_ary_t *ary, long len)

/*
* Do not call this directly.
* Use rb_parser_ary_new_capa_for_script_line() or rb_parser_ary_new_capa_for_ast_token() instead.
* Use rb_parser_ary_new_capa_for_XXX() instead.
*/
static rb_parser_ary_t *
parser_ary_new_capa(rb_parser_t *p, long len)
Expand All @@ -2524,6 +2523,7 @@ parser_ary_new_capa(rb_parser_t *p, long len)
return ary;
}

#ifndef RIPPER
static rb_parser_ary_t *
rb_parser_ary_new_capa_for_script_line(rb_parser_t *p, long len)
{
Expand All @@ -2539,10 +2539,19 @@ rb_parser_ary_new_capa_for_ast_token(rb_parser_t *p, long len)
ary->data_type = PARSER_ARY_DATA_AST_TOKEN;
return ary;
}
#endif

static rb_parser_ary_t *
rb_parser_ary_new_capa_for_node(rb_parser_t *p, long len)
{
rb_parser_ary_t *ary = parser_ary_new_capa(p, len);
ary->data_type = PARSER_ARY_DATA_NODE;
return ary;
}

/*
* Do not call this directly.
* Use rb_parser_ary_push_script_line() or rb_parser_ary_push_ast_token() instead.
* Use rb_parser_ary_push_XXX() instead.
*/
static rb_parser_ary_t *
parser_ary_push(rb_parser_t *p, rb_parser_ary_t *ary, rb_parser_ary_data val)
Expand All @@ -2554,6 +2563,7 @@ parser_ary_push(rb_parser_t *p, rb_parser_ary_t *ary, rb_parser_ary_data val)
return ary;
}

#ifndef RIPPER
static rb_parser_ary_t *
rb_parser_ary_push_ast_token(rb_parser_t *p, rb_parser_ary_t *ary, rb_parser_ast_token_t *val)
{
Expand All @@ -2571,7 +2581,18 @@ rb_parser_ary_push_script_line(rb_parser_t *p, rb_parser_ary_t *ary, rb_parser_s
}
return parser_ary_push(p, ary, val);
}
#endif

static rb_parser_ary_t *
rb_parser_ary_push_node(rb_parser_t *p, rb_parser_ary_t *ary, NODE *val)
{
if (ary->data_type != PARSER_ARY_DATA_NODE) {
rb_bug("unexpected rb_parser_ary_data_type: %d", ary->data_type);
}
return parser_ary_push(p, ary, val);
}

#ifndef RIPPER
static void
rb_parser_ast_token_free(rb_parser_t *p, rb_parser_ast_token_t *token)
{
Expand All @@ -2593,6 +2614,9 @@ rb_parser_ary_free(rb_parser_t *p, rb_parser_ary_t *ary)
case PARSER_ARY_DATA_SCRIPT_LINE:
foreach_ary(data) {rb_parser_string_free(p, *data);}
break;
case PARSER_ARY_DATA_NODE:
/* Do nothing because nodes are freed when rb_ast_t is freed */
break;
default:
rb_bug("unexpected rb_parser_ary_data_type: %d", ary->data_type);
break;
Expand Down Expand Up @@ -3774,8 +3798,8 @@ undef_list : fitem
}
| undef_list ',' {SET_LEX_STATE(EXPR_FNAME|EXPR_FITEM);} fitem
{
NODE *undef = NEW_UNDEF($4, &@4);
$$ = block_append(p, $1, undef);
nd_set_last_loc($1, @4.end_pos);
rb_parser_ary_push_node(p, RNODE_UNDEF($1)->nd_undefs, $4);
/*% ripper: rb_ary_push($:1, $:4) %*/
}
;
Expand Down Expand Up @@ -12286,7 +12310,8 @@ static rb_node_undef_t *
rb_node_undef_new(struct parser_params *p, NODE *nd_undef, const YYLTYPE *loc)
{
rb_node_undef_t *n = NODE_NEWNODE(NODE_UNDEF, rb_node_undef_t, loc);
n->nd_undef = nd_undef;
n->nd_undefs = rb_parser_ary_new_capa_for_node(p, 1);
rb_parser_ary_push_node(p, n->nd_undefs, nd_undef);

return n;
}
Expand Down
5 changes: 3 additions & 2 deletions rubyparser.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,8 @@ typedef void* rb_parser_ary_data;

enum rb_parser_ary_data_type {
PARSER_ARY_DATA_AST_TOKEN = 1,
PARSER_ARY_DATA_SCRIPT_LINE
PARSER_ARY_DATA_SCRIPT_LINE,
PARSER_ARY_DATA_NODE
};

typedef struct rb_parser_ary {
Expand Down Expand Up @@ -885,7 +886,7 @@ typedef struct RNode_VALIAS {
typedef struct RNode_UNDEF {
NODE node;

struct RNode *nd_undef;
rb_parser_ary_t *nd_undefs;
} rb_node_undef_t;

typedef struct RNode_CLASS {
Expand Down