Change RNode structure from union to struct

All kind of AST nodes use same struct RNode, which has u1, u2, u3 union members
for holding different kind of data.
This has two problems.

1. Low flexibility of data structure

Some nodes, for example NODE_TRUE, don’t use u1, u2, u3. On the other hand,
NODE_OP_ASGN2 needs more than three union members. However they use same
structure definition, need to allocate three union members for NODE_TRUE and
need to separate NODE_OP_ASGN2 into another node.
This change removes the restriction so make it possible to
change data structure by each node type.

2. No compile time check for union member access

It’s developer’s responsibility for using correct member for each node type when it’s union.
This change clarifies which node has which type of fields and enables compile time check.

This commit also changes node_buffer_elem_struct buf management to handle
different size data with alignment.
This commit is contained in:
yui-knk 2023-08-22 10:26:38 +09:00 коммит произвёл Yuichiro Kaneko
Родитель 684686a1e1
Коммит 74c6781153
12 изменённых файлов: 3740 добавлений и 1450 удалений

225
ast.c
Просмотреть файл

@ -331,14 +331,14 @@ rb_ary_new_from_node_args(rb_ast_t *ast, long n, ...)
}
static VALUE
dump_block(rb_ast_t *ast, const NODE *node)
dump_block(rb_ast_t *ast, const struct RNode_BLOCK *node)
{
VALUE ary = rb_ary_new();
do {
rb_ary_push(ary, NEW_CHILD(ast, node->nd_head));
} while (node->nd_next &&
nd_type_p(node->nd_next, NODE_BLOCK) &&
(node = node->nd_next, 1));
(node = RNODE_BLOCK(node->nd_next), 1));
if (node->nd_next) {
rb_ary_push(ary, NEW_CHILD(ast, node->nd_next));
}
@ -347,13 +347,13 @@ dump_block(rb_ast_t *ast, const NODE *node)
}
static VALUE
dump_array(rb_ast_t *ast, const NODE *node)
dump_array(rb_ast_t *ast, const struct RNode_LIST *node)
{
VALUE ary = rb_ary_new();
rb_ary_push(ary, NEW_CHILD(ast, node->nd_head));
while (node->nd_next && nd_type_p(node->nd_next, NODE_LIST)) {
node = node->nd_next;
node = RNODE_LIST(node->nd_next);
rb_ary_push(ary, NEW_CHILD(ast, node->nd_head));
}
rb_ary_push(ary, NEW_CHILD(ast, node->nd_next));
@ -391,67 +391,67 @@ node_children(rb_ast_t *ast, const NODE *node)
enum node_type type = nd_type(node);
switch (type) {
case NODE_BLOCK:
return dump_block(ast, node);
return dump_block(ast, RNODE_BLOCK(node));
case NODE_IF:
return rb_ary_new_from_node_args(ast, 3, node->nd_cond, node->nd_body, node->nd_else);
return rb_ary_new_from_node_args(ast, 3, RNODE_IF(node)->nd_cond, RNODE_IF(node)->nd_body, RNODE_IF(node)->nd_else);
case NODE_UNLESS:
return rb_ary_new_from_node_args(ast, 3, node->nd_cond, node->nd_body, node->nd_else);
return rb_ary_new_from_node_args(ast, 3, RNODE_UNLESS(node)->nd_cond, RNODE_UNLESS(node)->nd_body, RNODE_UNLESS(node)->nd_else);
case NODE_CASE:
return rb_ary_new_from_node_args(ast, 2, node->nd_head, node->nd_body);
return rb_ary_new_from_node_args(ast, 2, RNODE_CASE(node)->nd_head, RNODE_CASE(node)->nd_body);
case NODE_CASE2:
return rb_ary_new_from_node_args(ast, 2, node->nd_head, node->nd_body);
return rb_ary_new_from_node_args(ast, 2, RNODE_CASE2(node)->nd_head, RNODE_CASE2(node)->nd_body);
case NODE_CASE3:
return rb_ary_new_from_node_args(ast, 2, node->nd_head, node->nd_body);
return rb_ary_new_from_node_args(ast, 2, RNODE_CASE3(node)->nd_head, RNODE_CASE3(node)->nd_body);
case NODE_WHEN:
return rb_ary_new_from_node_args(ast, 3, node->nd_head, node->nd_body, node->nd_next);
return rb_ary_new_from_node_args(ast, 3, RNODE_WHEN(node)->nd_head, RNODE_WHEN(node)->nd_body, RNODE_WHEN(node)->nd_next);
case NODE_IN:
return rb_ary_new_from_node_args(ast, 3, node->nd_head, node->nd_body, node->nd_next);
return rb_ary_new_from_node_args(ast, 3, RNODE_IN(node)->nd_head, RNODE_IN(node)->nd_body, RNODE_IN(node)->nd_next);
case NODE_WHILE:
case NODE_UNTIL:
return rb_ary_push(rb_ary_new_from_node_args(ast, 2, node->nd_cond, node->nd_body),
RBOOL(node->nd_state));
return rb_ary_push(rb_ary_new_from_node_args(ast, 2, RNODE_WHILE(node)->nd_cond, RNODE_WHILE(node)->nd_body),
RBOOL(RNODE_WHILE(node)->nd_state));
case NODE_ITER:
case NODE_FOR:
return rb_ary_new_from_node_args(ast, 2, node->nd_iter, node->nd_body);
return rb_ary_new_from_node_args(ast, 2, RNODE_ITER(node)->nd_iter, RNODE_ITER(node)->nd_body);
case NODE_FOR_MASGN:
return rb_ary_new_from_node_args(ast, 1, node->nd_var);
return rb_ary_new_from_node_args(ast, 1, RNODE_FOR_MASGN(node)->nd_var);
case NODE_BREAK:
case NODE_NEXT:
case NODE_RETURN:
return rb_ary_new_from_node_args(ast, 1, node->nd_stts);
return rb_ary_new_from_node_args(ast, 1, RNODE_BREAK(node)->nd_stts);
case NODE_REDO:
return rb_ary_new_from_node_args(ast, 0);
case NODE_RETRY:
return rb_ary_new_from_node_args(ast, 0);
case NODE_BEGIN:
return rb_ary_new_from_node_args(ast, 1, node->nd_body);
return rb_ary_new_from_node_args(ast, 1, RNODE_BEGIN(node)->nd_body);
case NODE_RESCUE:
return rb_ary_new_from_node_args(ast, 3, node->nd_head, node->nd_resq, node->nd_else);
return rb_ary_new_from_node_args(ast, 3, RNODE_RESCUE(node)->nd_head, RNODE_RESCUE(node)->nd_resq, RNODE_RESCUE(node)->nd_else);
case NODE_RESBODY:
return rb_ary_new_from_node_args(ast, 3, node->nd_args, node->nd_body, node->nd_head);
return rb_ary_new_from_node_args(ast, 3, RNODE_RESBODY(node)->nd_args, RNODE_RESBODY(node)->nd_body, RNODE_RESBODY(node)->nd_head);
case NODE_ENSURE:
return rb_ary_new_from_node_args(ast, 2, node->nd_head, node->nd_ensr);
return rb_ary_new_from_node_args(ast, 2, RNODE_ENSURE(node)->nd_head, RNODE_ENSURE(node)->nd_ensr);
case NODE_AND:
case NODE_OR:
{
VALUE ary = rb_ary_new();
while (1) {
rb_ary_push(ary, NEW_CHILD(ast, node->nd_1st));
if (!node->nd_2nd || !nd_type_p(node->nd_2nd, type))
rb_ary_push(ary, NEW_CHILD(ast, RNODE_AND(node)->nd_1st));
if (!RNODE_AND(node)->nd_2nd || !nd_type_p(RNODE_AND(node)->nd_2nd, type))
break;
node = node->nd_2nd;
node = RNODE_AND(node)->nd_2nd;
}
rb_ary_push(ary, NEW_CHILD(ast, node->nd_2nd));
rb_ary_push(ary, NEW_CHILD(ast, RNODE_AND(node)->nd_2nd));
return ary;
}
case NODE_MASGN:
if (NODE_NAMED_REST_P(node->nd_args)) {
return rb_ary_new_from_node_args(ast, 3, node->nd_value, node->nd_head, node->nd_args);
if (NODE_NAMED_REST_P(RNODE_MASGN(node)->nd_args)) {
return rb_ary_new_from_node_args(ast, 3, RNODE_MASGN(node)->nd_value, RNODE_MASGN(node)->nd_head, RNODE_MASGN(node)->nd_args);
}
else {
return rb_ary_new_from_args(3, NEW_CHILD(ast, node->nd_value),
NEW_CHILD(ast, node->nd_head),
return rb_ary_new_from_args(3, NEW_CHILD(ast, RNODE_MASGN(node)->nd_value),
NEW_CHILD(ast, RNODE_MASGN(node)->nd_head),
no_name_rest());
}
case NODE_LASGN:
@ -459,138 +459,141 @@ node_children(rb_ast_t *ast, const NODE *node)
case NODE_IASGN:
case NODE_CVASGN:
case NODE_GASGN:
if (NODE_REQUIRED_KEYWORD_P(node)) {
return rb_ary_new_from_args(2, var_name(node->nd_vid), ID2SYM(rb_intern("NODE_SPECIAL_REQUIRED_KEYWORD")));
if (NODE_REQUIRED_KEYWORD_P(RNODE_LASGN(node))) {
return rb_ary_new_from_args(2, var_name(RNODE_LASGN(node)->nd_vid), ID2SYM(rb_intern("NODE_SPECIAL_REQUIRED_KEYWORD")));
}
return rb_ary_new_from_args(2, var_name(node->nd_vid), NEW_CHILD(ast, node->nd_value));
return rb_ary_new_from_args(2, var_name(RNODE_LASGN(node)->nd_vid), NEW_CHILD(ast, RNODE_LASGN(node)->nd_value));
case NODE_CDECL:
if (node->nd_vid) {
return rb_ary_new_from_args(2, ID2SYM(node->nd_vid), NEW_CHILD(ast, node->nd_value));
if (RNODE_CDECL(node)->nd_vid) {
return rb_ary_new_from_args(2, ID2SYM(RNODE_CDECL(node)->nd_vid), NEW_CHILD(ast, RNODE_CDECL(node)->nd_value));
}
return rb_ary_new_from_args(3, NEW_CHILD(ast, node->nd_else), ID2SYM(node->nd_else->nd_mid), NEW_CHILD(ast, node->nd_value));
return rb_ary_new_from_args(3, NEW_CHILD(ast, RNODE_CDECL(node)->nd_else), ID2SYM(RNODE_COLON2(RNODE_CDECL(node)->nd_else)->nd_mid), NEW_CHILD(ast, RNODE_CDECL(node)->nd_value));
case NODE_OP_ASGN1:
return rb_ary_new_from_args(4, NEW_CHILD(ast, node->nd_recv),
ID2SYM(node->nd_mid),
NEW_CHILD(ast, node->nd_args->nd_head),
NEW_CHILD(ast, node->nd_args->nd_body));
return rb_ary_new_from_args(4, NEW_CHILD(ast, RNODE_OP_ASGN1(node)->nd_recv),
ID2SYM(RNODE_OP_ASGN1(node)->nd_mid),
NEW_CHILD(ast, RNODE_ARGSCAT(RNODE_OP_ASGN1(node)->nd_args)->nd_head),
NEW_CHILD(ast, RNODE_ARGSCAT(RNODE_OP_ASGN1(node)->nd_args)->nd_body));
case NODE_OP_ASGN2:
return rb_ary_new_from_args(5, NEW_CHILD(ast, node->nd_recv),
RBOOL(node->nd_next->nd_aid),
ID2SYM(node->nd_next->nd_vid),
ID2SYM(node->nd_next->nd_mid),
NEW_CHILD(ast, node->nd_value));
// NODE_OP_ASGN2 has NODE_OP_ASGN2 in its nd_next, however nd_next
// has different structure, whose u1 is ID attr, u2 is ID op, u3 is bool.
// See: NEW_OP_ASGN2
return rb_ary_new_from_args(5, NEW_CHILD(ast, RNODE_OP_ASGN2(node)->nd_recv),
RBOOL(RNODE_OP_ASGN22(RNODE_OP_ASGN2(node)->nd_next)->nd_aid),
ID2SYM(RNODE_OP_ASGN22(RNODE_OP_ASGN2(node)->nd_next)->nd_vid),
ID2SYM(RNODE_OP_ASGN22(RNODE_OP_ASGN2(node)->nd_next)->nd_mid),
NEW_CHILD(ast, RNODE_OP_ASGN2(node)->nd_value));
case NODE_OP_ASGN_AND:
return rb_ary_new_from_args(3, NEW_CHILD(ast, node->nd_head), ID2SYM(idANDOP),
NEW_CHILD(ast, node->nd_value));
return rb_ary_new_from_args(3, NEW_CHILD(ast, RNODE_OP_ASGN_AND(node)->nd_head), ID2SYM(idANDOP),
NEW_CHILD(ast, RNODE_OP_ASGN_AND(node)->nd_value));
case NODE_OP_ASGN_OR:
return rb_ary_new_from_args(3, NEW_CHILD(ast, node->nd_head), ID2SYM(idOROP),
NEW_CHILD(ast, node->nd_value));
return rb_ary_new_from_args(3, NEW_CHILD(ast, RNODE_OP_ASGN_OR(node)->nd_head), ID2SYM(idOROP),
NEW_CHILD(ast, RNODE_OP_ASGN_OR(node)->nd_value));
case NODE_OP_CDECL:
return rb_ary_new_from_args(3, NEW_CHILD(ast, node->nd_head),
ID2SYM(node->nd_aid),
NEW_CHILD(ast, node->nd_value));
return rb_ary_new_from_args(3, NEW_CHILD(ast, RNODE_OP_CDECL(node)->nd_head),
ID2SYM(RNODE_OP_CDECL(node)->nd_aid),
NEW_CHILD(ast, RNODE_OP_CDECL(node)->nd_value));
case NODE_CALL:
case NODE_OPCALL:
case NODE_QCALL:
return rb_ary_new_from_args(3, NEW_CHILD(ast, node->nd_recv),
ID2SYM(node->nd_mid),
NEW_CHILD(ast, node->nd_args));
return rb_ary_new_from_args(3, NEW_CHILD(ast, RNODE_CALL(node)->nd_recv),
ID2SYM(RNODE_CALL(node)->nd_mid),
NEW_CHILD(ast, RNODE_CALL(node)->nd_args));
case NODE_FCALL:
return rb_ary_new_from_args(2, ID2SYM(node->nd_mid),
NEW_CHILD(ast, node->nd_args));
return rb_ary_new_from_args(2, ID2SYM(RNODE_FCALL(node)->nd_mid),
NEW_CHILD(ast, RNODE_FCALL(node)->nd_args));
case NODE_VCALL:
return rb_ary_new_from_args(1, ID2SYM(node->nd_mid));
return rb_ary_new_from_args(1, ID2SYM(RNODE_VCALL(node)->nd_mid));
case NODE_SUPER:
return rb_ary_new_from_node_args(ast, 1, node->nd_args);
return rb_ary_new_from_node_args(ast, 1, RNODE_SUPER(node)->nd_args);
case NODE_ZSUPER:
return rb_ary_new_from_node_args(ast, 0);
case NODE_LIST:
case NODE_VALUES:
return dump_array(ast, node);
return dump_array(ast, RNODE_LIST(node));
case NODE_ZLIST:
return rb_ary_new_from_node_args(ast, 0);
case NODE_HASH:
return rb_ary_new_from_node_args(ast, 1, node->nd_head);
return rb_ary_new_from_node_args(ast, 1, RNODE_HASH(node)->nd_head);
case NODE_YIELD:
return rb_ary_new_from_node_args(ast, 1, node->nd_head);
return rb_ary_new_from_node_args(ast, 1, RNODE_YIELD(node)->nd_head);
case NODE_LVAR:
case NODE_DVAR:
return rb_ary_new_from_args(1, var_name(node->nd_vid));
return rb_ary_new_from_args(1, var_name(RNODE_LVAR(node)->nd_vid));
case NODE_IVAR:
case NODE_CONST:
case NODE_CVAR:
case NODE_GVAR:
return rb_ary_new_from_args(1, ID2SYM(node->nd_vid));
return rb_ary_new_from_args(1, ID2SYM(RNODE_IVAR(node)->nd_vid));
case NODE_NTH_REF:
snprintf(name, sizeof(name), "$%ld", node->nd_nth);
snprintf(name, sizeof(name), "$%ld", RNODE_NTH_REF(node)->nd_nth);
return rb_ary_new_from_args(1, ID2SYM(rb_intern(name)));
case NODE_BACK_REF:
name[0] = '$';
name[1] = (char)node->nd_nth;
name[1] = (char)RNODE_BACK_REF(node)->nd_nth;
name[2] = '\0';
return rb_ary_new_from_args(1, ID2SYM(rb_intern(name)));
case NODE_MATCH2:
if (node->nd_args) {
return rb_ary_new_from_node_args(ast, 3, node->nd_recv, node->nd_value, node->nd_args);
if (RNODE_MATCH2(node)->nd_args) {
return rb_ary_new_from_node_args(ast, 3, RNODE_MATCH2(node)->nd_recv, RNODE_MATCH2(node)->nd_value, RNODE_MATCH2(node)->nd_args);
}
return rb_ary_new_from_node_args(ast, 2, node->nd_recv, node->nd_value);
return rb_ary_new_from_node_args(ast, 2, RNODE_MATCH2(node)->nd_recv, RNODE_MATCH2(node)->nd_value);
case NODE_MATCH3:
return rb_ary_new_from_node_args(ast, 2, node->nd_recv, node->nd_value);
return rb_ary_new_from_node_args(ast, 2, RNODE_MATCH3(node)->nd_recv, RNODE_MATCH3(node)->nd_value);
case NODE_MATCH:
case NODE_LIT:
case NODE_STR:
case NODE_XSTR:
return rb_ary_new_from_args(1, node->nd_lit);
return rb_ary_new_from_args(1, RNODE_LIT(node)->nd_lit);
case NODE_ONCE:
return rb_ary_new_from_node_args(ast, 1, node->nd_body);
return rb_ary_new_from_node_args(ast, 1, RNODE_ONCE(node)->nd_body);
case NODE_DSTR:
case NODE_DXSTR:
case NODE_DREGX:
case NODE_DSYM:
{
NODE *n = node->nd_next;
struct RNode_LIST *n = RNODE_DSTR(node)->nd_next;
VALUE head = Qnil, next = Qnil;
if (n) {
head = NEW_CHILD(ast, n->nd_head);
next = NEW_CHILD(ast, n->nd_next);
}
return rb_ary_new_from_args(3, node->nd_lit, head, next);
return rb_ary_new_from_args(3, RNODE_DSTR(node)->nd_lit, head, next);
}
case NODE_EVSTR:
return rb_ary_new_from_node_args(ast, 1, node->nd_body);
return rb_ary_new_from_node_args(ast, 1, RNODE_EVSTR(node)->nd_body);
case NODE_ARGSCAT:
return rb_ary_new_from_node_args(ast, 2, node->nd_head, node->nd_body);
return rb_ary_new_from_node_args(ast, 2, RNODE_ARGSCAT(node)->nd_head, RNODE_ARGSCAT(node)->nd_body);
case NODE_ARGSPUSH:
return rb_ary_new_from_node_args(ast, 2, node->nd_head, node->nd_body);
return rb_ary_new_from_node_args(ast, 2, RNODE_ARGSPUSH(node)->nd_head, RNODE_ARGSPUSH(node)->nd_body);
case NODE_SPLAT:
return rb_ary_new_from_node_args(ast, 1, node->nd_head);
return rb_ary_new_from_node_args(ast, 1, RNODE_SPLAT(node)->nd_head);
case NODE_BLOCK_PASS:
return rb_ary_new_from_node_args(ast, 2, node->nd_head, node->nd_body);
return rb_ary_new_from_node_args(ast, 2, RNODE_BLOCK_PASS(node)->nd_head, RNODE_BLOCK_PASS(node)->nd_body);
case NODE_DEFN:
return rb_ary_new_from_args(2, ID2SYM(node->nd_mid), NEW_CHILD(ast, node->nd_defn));
return rb_ary_new_from_args(2, ID2SYM(RNODE_DEFN(node)->nd_mid), NEW_CHILD(ast, RNODE_DEFN(node)->nd_defn));
case NODE_DEFS:
return rb_ary_new_from_args(3, NEW_CHILD(ast, node->nd_recv), ID2SYM(node->nd_mid), NEW_CHILD(ast, node->nd_defn));
return rb_ary_new_from_args(3, NEW_CHILD(ast, RNODE_DEFS(node)->nd_recv), ID2SYM(RNODE_DEFS(node)->nd_mid), NEW_CHILD(ast, RNODE_DEFS(node)->nd_defn));
case NODE_ALIAS:
return rb_ary_new_from_node_args(ast, 2, node->nd_1st, node->nd_2nd);
return rb_ary_new_from_node_args(ast, 2, RNODE_ALIAS(node)->nd_1st, RNODE_ALIAS(node)->nd_2nd);
case NODE_VALIAS:
return rb_ary_new_from_args(2, ID2SYM(node->nd_alias), ID2SYM(node->nd_orig));
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, 1, node->nd_undef);
return rb_ary_new_from_node_args(ast, 1, RNODE_UNDEF(node)->nd_undef);
case NODE_CLASS:
return rb_ary_new_from_node_args(ast, 3, node->nd_cpath, node->nd_super, node->nd_body);
return rb_ary_new_from_node_args(ast, 3, RNODE_CLASS(node)->nd_cpath, RNODE_CLASS(node)->nd_super, RNODE_CLASS(node)->nd_body);
case NODE_MODULE:
return rb_ary_new_from_node_args(ast, 2, node->nd_cpath, node->nd_body);
return rb_ary_new_from_node_args(ast, 2, RNODE_MODULE(node)->nd_cpath, RNODE_MODULE(node)->nd_body);
case NODE_SCLASS:
return rb_ary_new_from_node_args(ast, 2, node->nd_recv, node->nd_body);
return rb_ary_new_from_node_args(ast, 2, RNODE_SCLASS(node)->nd_recv, RNODE_SCLASS(node)->nd_body);
case NODE_COLON2:
return rb_ary_new_from_args(2, NEW_CHILD(ast, node->nd_head), ID2SYM(node->nd_mid));
return rb_ary_new_from_args(2, NEW_CHILD(ast, RNODE_COLON2(node)->nd_head), ID2SYM(RNODE_COLON2(node)->nd_mid));
case NODE_COLON3:
return rb_ary_new_from_args(1, ID2SYM(node->nd_mid));
return rb_ary_new_from_args(1, ID2SYM(RNODE_COLON3(node)->nd_mid));
case NODE_DOT2:
case NODE_DOT3:
case NODE_FLIP2:
case NODE_FLIP3:
return rb_ary_new_from_node_args(ast, 2, node->nd_beg, node->nd_end);
return rb_ary_new_from_node_args(ast, 2, RNODE_DOT2(node)->nd_beg, RNODE_DOT2(node)->nd_end);
case NODE_SELF:
return rb_ary_new_from_node_args(ast, 0);
case NODE_NIL:
@ -602,26 +605,26 @@ node_children(rb_ast_t *ast, const NODE *node)
case NODE_ERRINFO:
return rb_ary_new_from_node_args(ast, 0);
case NODE_DEFINED:
return rb_ary_new_from_node_args(ast, 1, node->nd_head);
return rb_ary_new_from_node_args(ast, 1, RNODE_DEFINED(node)->nd_head);
case NODE_POSTEXE:
return rb_ary_new_from_node_args(ast, 1, node->nd_body);
return rb_ary_new_from_node_args(ast, 1, RNODE_POSTEXE(node)->nd_body);
case NODE_ATTRASGN:
return rb_ary_new_from_args(3, NEW_CHILD(ast, node->nd_recv), ID2SYM(node->nd_mid), NEW_CHILD(ast, node->nd_args));
return rb_ary_new_from_args(3, NEW_CHILD(ast, RNODE_ATTRASGN(node)->nd_recv), ID2SYM(RNODE_ATTRASGN(node)->nd_mid), NEW_CHILD(ast, RNODE_ATTRASGN(node)->nd_args));
case NODE_LAMBDA:
return rb_ary_new_from_node_args(ast, 1, node->nd_body);
return rb_ary_new_from_node_args(ast, 1, RNODE_LAMBDA(node)->nd_body);
case NODE_OPT_ARG:
return rb_ary_new_from_node_args(ast, 2, node->nd_body, node->nd_next);
return rb_ary_new_from_node_args(ast, 2, RNODE_OPT_ARG(node)->nd_body, RNODE_OPT_ARG(node)->nd_next);
case NODE_KW_ARG:
return rb_ary_new_from_node_args(ast, 2, node->nd_body, node->nd_next);
return rb_ary_new_from_node_args(ast, 2, RNODE_KW_ARG(node)->nd_body, RNODE_KW_ARG(node)->nd_next);
case NODE_POSTARG:
if (NODE_NAMED_REST_P(node->nd_1st)) {
return rb_ary_new_from_node_args(ast, 2, node->nd_1st, node->nd_2nd);
if (NODE_NAMED_REST_P(RNODE_POSTARG(node)->nd_1st)) {
return rb_ary_new_from_node_args(ast, 2, RNODE_POSTARG(node)->nd_1st, RNODE_POSTARG(node)->nd_2nd);
}
return rb_ary_new_from_args(2, no_name_rest(),
NEW_CHILD(ast, node->nd_2nd));
NEW_CHILD(ast, RNODE_POSTARG(node)->nd_2nd));
case NODE_ARGS:
{
struct rb_args_info *ainfo = node->nd_ainfo;
struct rb_args_info *ainfo = RNODE_ARGS(node)->nd_ainfo;
return rb_ary_new_from_args(10,
INT2NUM(ainfo->pre_args_num),
NEW_CHILD(ast, ainfo->pre_init),
@ -638,48 +641,52 @@ node_children(rb_ast_t *ast, const NODE *node)
}
case NODE_SCOPE:
{
rb_ast_id_table_t *tbl = node->nd_tbl;
rb_ast_id_table_t *tbl = RNODE_SCOPE(node)->nd_tbl;
int i, size = tbl ? tbl->size : 0;
VALUE locals = rb_ary_new_capa(size);
for (i = 0; i < size; i++) {
rb_ary_push(locals, var_name(tbl->ids[i]));
}
return rb_ary_new_from_args(3, locals, NEW_CHILD(ast, node->nd_args), NEW_CHILD(ast, node->nd_body));
return rb_ary_new_from_args(3, locals, NEW_CHILD(ast, RNODE_SCOPE(node)->nd_args), NEW_CHILD(ast, RNODE_SCOPE(node)->nd_body));
}
case NODE_ARYPTN:
{
struct rb_ary_pattern_info *apinfo = node->nd_apinfo;
struct rb_ary_pattern_info *apinfo = RNODE_ARYPTN(node)->nd_apinfo;
VALUE rest = rest_arg(ast, apinfo->rest_arg);
return rb_ary_new_from_args(4,
NEW_CHILD(ast, node->nd_pconst),
NEW_CHILD(ast, RNODE_ARYPTN(node)->nd_pconst),
NEW_CHILD(ast, apinfo->pre_args),
rest,
NEW_CHILD(ast, apinfo->post_args));
}
case NODE_FNDPTN:
{
struct rb_fnd_pattern_info *fpinfo = node->nd_fpinfo;
struct rb_fnd_pattern_info *fpinfo = RNODE_FNDPTN(node)->nd_fpinfo;
VALUE pre_rest = rest_arg(ast, fpinfo->pre_rest_arg);
VALUE post_rest = rest_arg(ast, fpinfo->post_rest_arg);
return rb_ary_new_from_args(4,
NEW_CHILD(ast, node->nd_pconst),
NEW_CHILD(ast, RNODE_FNDPTN(node)->nd_pconst),
pre_rest,
NEW_CHILD(ast, fpinfo->args),
post_rest);
}
case NODE_HSHPTN:
{
VALUE kwrest = node->nd_pkwrestarg == NODE_SPECIAL_NO_REST_KEYWORD ? ID2SYM(rb_intern("NODE_SPECIAL_NO_REST_KEYWORD")) :
NEW_CHILD(ast, node->nd_pkwrestarg);
VALUE kwrest = RNODE_HSHPTN(node)->nd_pkwrestarg == NODE_SPECIAL_NO_REST_KEYWORD ? ID2SYM(rb_intern("NODE_SPECIAL_NO_REST_KEYWORD")) :
NEW_CHILD(ast, RNODE_HSHPTN(node)->nd_pkwrestarg);
return rb_ary_new_from_args(3,
NEW_CHILD(ast, node->nd_pconst),
NEW_CHILD(ast, node->nd_pkwargs),
NEW_CHILD(ast, RNODE_HSHPTN(node)->nd_pconst),
NEW_CHILD(ast, RNODE_HSHPTN(node)->nd_pkwargs),
kwrest);
}
case NODE_ERROR:
return rb_ary_new_from_node_args(ast, 0);
case NODE_ARGS_AUX:
case NODE_DEF_TEMP:
case NODE_DEF_TEMP2:
case NODE_RIPPER:
case NODE_RIPPER_VALUES:
case NODE_LAST:
break;
}

918
compile.c

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -493,6 +493,10 @@ count_nodes(int argc, VALUE *argv, VALUE os)
COUNT_NODE(NODE_ARYPTN);
COUNT_NODE(NODE_FNDPTN);
COUNT_NODE(NODE_HSHPTN);
COUNT_NODE(NODE_DEF_TEMP);
COUNT_NODE(NODE_DEF_TEMP2);
COUNT_NODE(NODE_RIPPER);
COUNT_NODE(NODE_RIPPER_VALUES);
COUNT_NODE(NODE_ERROR);
#undef COUNT_NODE
case NODE_LAST: break;

Просмотреть файл

@ -14,7 +14,6 @@
#include "ripper_init.h"
#define STR_NEW2(ptr) rb_enc_str_new((ptr),strlen(ptr),rb_ruby_parser_enc(p))
#define NODE_RIPPER NODE_CDECL
#define RIPPER_VERSION "0.1.0"
ID id_warn, id_warning, id_gets, id_assoc;
@ -62,7 +61,7 @@ ripper_get_id(VALUE v)
if (!RB_TYPE_P(v, T_NODE)) return 0;
nd = (NODE *)v;
if (!nd_type_p(nd, NODE_RIPPER)) return 0;
return nd->nd_vid;
return RNODE_RIPPER(nd)->nd_vid;
}
VALUE
@ -73,7 +72,7 @@ ripper_get_value(VALUE v)
if (!RB_TYPE_P(v, T_NODE)) return v;
nd = (NODE *)v;
if (!nd_type_p(nd, NODE_RIPPER)) return Qnil;
return nd->nd_rval;
return RNODE_RIPPER(nd)->nd_rval;
}
static VALUE

213
node.c
Просмотреть файл

@ -17,21 +17,6 @@
#include "internal/parse.h"
#define T_NODE 0x1b
#define ruby_xmalloc ast->node_buffer->config->malloc
#undef xfree
#define xfree ast->node_buffer->config->free
#define rb_ident_hash_new ast->node_buffer->config->ident_hash_new
#define rb_xmalloc_mul_add ast->node_buffer->config->xmalloc_mul_add
#define ruby_xrealloc(var,size) (ast->node_buffer->config->realloc_n((void *)var, 1, size))
#define rb_gc_mark ast->node_buffer->config->gc_mark
#define rb_gc_location ast->node_buffer->config->gc_location
#define rb_gc_mark_movable ast->node_buffer->config->gc_mark_movable
#define Qnil ast->node_buffer->config->qnil
#define Qtrue ast->node_buffer->config->qtrue
#define NIL_P ast->node_buffer->config->nil_p
#define rb_hash_aset ast->node_buffer->config->hash_aset
#define RB_OBJ_WRITE(old, slot, young) ast->node_buffer->config->obj_write((VALUE)(old), (VALUE *)(slot), (VALUE)(young))
#else
#include "internal.h"
@ -42,9 +27,76 @@
#endif
#define NODE_BUF_DEFAULT_LEN 16
#define NODE_BUF_DEFAULT_SIZE (sizeof(struct RNode) * 16)
typedef void node_itr_t(rb_ast_t *ast, void *ctx, NODE * node);
static void
init_node_buffer_elem(node_buffer_elem_t *nbe, size_t allocated, void *xmalloc(size_t))
{
nbe->allocated = allocated;
nbe->used = 0;
nbe->len = 0;
nbe->nodes = xmalloc(allocated / sizeof(struct RNode) * sizeof(struct RNode *)); /* All node requires at least RNode */
}
static void
init_node_buffer_list(node_buffer_list_t * nb, node_buffer_elem_t *head, void *xmalloc(size_t))
{
init_node_buffer_elem(head, NODE_BUF_DEFAULT_SIZE, xmalloc);
nb->head = nb->last = head;
nb->head->next = NULL;
}
#ifdef UNIVERSAL_PARSER
#define ruby_xmalloc config->malloc
#define Qnil config->qnil
#endif
#ifdef UNIVERSAL_PARSER
static node_buffer_t *
rb_node_buffer_new(rb_parser_config_t *config)
#else
static node_buffer_t *
rb_node_buffer_new(void)
#endif
{
const size_t bucket_size = offsetof(node_buffer_elem_t, buf) + NODE_BUF_DEFAULT_SIZE;
const size_t alloc_size = sizeof(node_buffer_t) + (bucket_size * 2);
STATIC_ASSERT(
integer_overflow,
offsetof(node_buffer_elem_t, buf) + NODE_BUF_DEFAULT_SIZE
> sizeof(node_buffer_t) + 2 * sizeof(node_buffer_elem_t));
node_buffer_t *nb = ruby_xmalloc(alloc_size);
init_node_buffer_list(&nb->unmarkable, (node_buffer_elem_t*)&nb[1], ruby_xmalloc);
init_node_buffer_list(&nb->markable, (node_buffer_elem_t*)((size_t)nb->unmarkable.head + bucket_size), ruby_xmalloc);
nb->local_tables = 0;
nb->mark_hash = Qnil;
nb->tokens = Qnil;
#ifdef UNIVERSAL_PARSER
nb->config = config;
#endif
return nb;
}
#ifdef UNIVERSAL_PARSER
#undef ruby_xmalloc
#define ruby_xmalloc ast->node_buffer->config->malloc
#undef xfree
#define xfree ast->node_buffer->config->free
#define rb_ident_hash_new ast->node_buffer->config->ident_hash_new
#define rb_xmalloc_mul_add ast->node_buffer->config->xmalloc_mul_add
#define ruby_xrealloc(var,size) (ast->node_buffer->config->realloc_n((void *)var, 1, size))
#define rb_gc_mark ast->node_buffer->config->gc_mark
#define rb_gc_location ast->node_buffer->config->gc_location
#define rb_gc_mark_movable ast->node_buffer->config->gc_mark_movable
#undef Qnil
#define Qnil ast->node_buffer->config->qnil
#define Qtrue ast->node_buffer->config->qtrue
#define NIL_P ast->node_buffer->config->nil_p
#define rb_hash_aset ast->node_buffer->config->hash_aset
#define RB_OBJ_WRITE(old, slot, young) ast->node_buffer->config->obj_write((VALUE)(old), (VALUE *)(slot), (VALUE)(young))
#endif
typedef void node_itr_t(rb_ast_t *ast, void *ctx, NODE *node);
static void iterate_node_values(rb_ast_t *ast, node_buffer_list_t *nb, node_itr_t * func, void *ctx);
/* Setup NODE structure.
@ -54,18 +106,15 @@ static void iterate_node_values(rb_ast_t *ast, node_buffer_list_t *nb, node_itr_
* objects.
*/
void
rb_node_init(NODE *n, enum node_type type, VALUE a0, VALUE a1, VALUE a2)
rb_node_init(NODE *n, enum node_type type)
{
n->flags = T_NODE;
nd_init_type(n, type);
n->u1.value = a0;
n->u2.value = a1;
n->u3.value = a2;
n->nd_loc.beg_pos.lineno = 0;
n->nd_loc.beg_pos.column = 0;
n->nd_loc.end_pos.lineno = 0;
n->nd_loc.end_pos.column = 0;
n->node_id = -1;
RNODE(n)->flags = T_NODE;
nd_init_type(RNODE(n), type);
RNODE(n)->nd_loc.beg_pos.lineno = 0;
RNODE(n)->nd_loc.beg_pos.column = 0;
RNODE(n)->nd_loc.end_pos.lineno = 0;
RNODE(n)->nd_loc.end_pos.column = 0;
RNODE(n)->node_id = -1;
}
const char *
@ -95,62 +144,13 @@ ruby_node_name(int node)
}
#endif
static void
init_node_buffer_list(node_buffer_list_t * nb, node_buffer_elem_t *head)
{
nb->idx = 0;
nb->len = NODE_BUF_DEFAULT_LEN;
nb->head = nb->last = head;
nb->head->len = nb->len;
nb->head->next = NULL;
}
#ifdef UNIVERSAL_PARSER
static node_buffer_t *
rb_node_buffer_new(rb_parser_config_t *config)
{
const size_t bucket_size = offsetof(node_buffer_elem_t, buf) + NODE_BUF_DEFAULT_LEN * sizeof(NODE);
const size_t alloc_size = sizeof(node_buffer_t) + (bucket_size * 2);
STATIC_ASSERT(
integer_overflow,
offsetof(node_buffer_elem_t, buf) + NODE_BUF_DEFAULT_LEN * sizeof(NODE)
> sizeof(node_buffer_t) + 2 * sizeof(node_buffer_elem_t));
node_buffer_t *nb = config->malloc(alloc_size);
init_node_buffer_list(&nb->unmarkable, (node_buffer_elem_t*)&nb[1]);
init_node_buffer_list(&nb->markable, (node_buffer_elem_t*)((size_t)nb->unmarkable.head + bucket_size));
nb->local_tables = 0;
nb->mark_hash = config->qnil;
nb->tokens = config->qnil;
nb->config = config;
return nb;
}
#else
static node_buffer_t *
rb_node_buffer_new(void)
{
const size_t bucket_size = offsetof(node_buffer_elem_t, buf) + NODE_BUF_DEFAULT_LEN * sizeof(NODE);
const size_t alloc_size = sizeof(node_buffer_t) + (bucket_size * 2);
STATIC_ASSERT(
integer_overflow,
offsetof(node_buffer_elem_t, buf) + NODE_BUF_DEFAULT_LEN * sizeof(NODE)
> sizeof(node_buffer_t) + 2 * sizeof(node_buffer_elem_t));
node_buffer_t *nb = ruby_xmalloc(alloc_size);
init_node_buffer_list(&nb->unmarkable, (node_buffer_elem_t*)&nb[1]);
init_node_buffer_list(&nb->markable, (node_buffer_elem_t*)((size_t)nb->unmarkable.head + bucket_size));
nb->local_tables = 0;
nb->mark_hash = Qnil;
nb->tokens = Qnil;
return nb;
}
#endif
static void
node_buffer_list_free(rb_ast_t *ast, node_buffer_list_t * nb)
{
node_buffer_elem_t *nbe = nb->head;
while (nbe != nb->last) {
void *buf = nbe;
xfree(nbe->nodes);
nbe = nbe->next;
xfree(buf);
}
@ -165,17 +165,17 @@ struct rb_ast_local_table_link {
};
static void
free_ast_value(rb_ast_t *ast, void *ctx, NODE * node)
free_ast_value(rb_ast_t *ast, void *ctx, NODE *node)
{
switch (nd_type(node)) {
case NODE_ARGS:
xfree(node->nd_ainfo);
xfree(RNODE_ARGS(node)->nd_ainfo);
break;
case NODE_ARYPTN:
xfree(node->nd_apinfo);
xfree(RNODE_ARYPTN(node)->nd_apinfo);
break;
case NODE_FNDPTN:
xfree(node->nd_fpinfo);
xfree(RNODE_FNDPTN(node)->nd_fpinfo);
break;
}
}
@ -195,20 +195,31 @@ rb_node_buffer_free(rb_ast_t *ast, node_buffer_t *nb)
xfree(nb);
}
#define buf_add_offset(nbe, offset) ((char *)(nbe->buf) + (offset))
static NODE *
ast_newnode_in_bucket(rb_ast_t *ast, node_buffer_list_t *nb)
ast_newnode_in_bucket(rb_ast_t *ast, node_buffer_list_t *nb, size_t size, size_t alignment)
{
if (nb->idx >= nb->len) {
long n = nb->len * 2;
size_t padding;
NODE *ptr;
padding = alignment - (size_t)buf_add_offset(nb->head, nb->head->used) % alignment;
padding = padding == alignment ? 0 : padding;
if (nb->head->used + size + padding > nb->head->allocated) {
size_t n = nb->head->allocated * 2;
node_buffer_elem_t *nbe;
nbe = rb_xmalloc_mul_add(n, sizeof(NODE), offsetof(node_buffer_elem_t, buf));
nbe->len = n;
nb->idx = 0;
nb->len = n;
nbe = rb_xmalloc_mul_add(n, sizeof(char *), offsetof(node_buffer_elem_t, buf));
init_node_buffer_elem(nbe, n, ruby_xmalloc);
nbe->next = nb->head;
nb->head = nbe;
padding = 0; /* malloc returns aligned address then no need to add padding */
}
return &nb->head->buf[nb->idx++];
ptr = (NODE *)buf_add_offset(nb->head, nb->head->used + padding);
nb->head->used += (size + padding);
nb->head->nodes[nb->head->len++] = ptr;
return ptr;
}
RBIMPL_ATTR_PURE()
@ -231,12 +242,12 @@ nodetype_markable_p(enum node_type type)
}
NODE *
rb_ast_newnode(rb_ast_t *ast, enum node_type type)
rb_ast_newnode(rb_ast_t *ast, enum node_type type, size_t size, size_t alignment)
{
node_buffer_t *nb = ast->node_buffer;
node_buffer_list_t *bucket =
(nodetype_markable_p(type) ? &nb->markable : &nb->unmarkable);
return ast_newnode_in_bucket(ast, bucket);
return ast_newnode_in_bucket(ast, bucket, size, alignment);
}
#if RUBY_DEBUG
@ -306,7 +317,7 @@ iterate_buffer_elements(rb_ast_t *ast, node_buffer_elem_t *nbe, long len, node_i
{
long cursor;
for (cursor = 0; cursor < len; cursor++) {
func(ast, ctx, &nbe->buf[cursor]);
func(ast, ctx, nbe->nodes[cursor]);
}
}
@ -315,10 +326,6 @@ iterate_node_values(rb_ast_t *ast, node_buffer_list_t *nb, node_itr_t * func, vo
{
node_buffer_elem_t *nbe = nb->head;
/* iterate over the head first because it's not full */
iterate_buffer_elements(ast, nbe, nb->idx, func, ctx);
nbe = nbe->next;
while (nbe) {
iterate_buffer_elements(ast, nbe, nbe->len, func, ctx);
nbe = nbe->next;
@ -326,7 +333,7 @@ iterate_node_values(rb_ast_t *ast, node_buffer_list_t *nb, node_itr_t * func, vo
}
static void
mark_ast_value(rb_ast_t *ast, void *ctx, NODE * node)
mark_ast_value(rb_ast_t *ast, void *ctx, NODE *node)
{
#ifdef UNIVERSAL_PARSER
bug_report_func rb_bug = ast->node_buffer->config->bug;
@ -341,7 +348,7 @@ mark_ast_value(rb_ast_t *ast, void *ctx, NODE * node)
case NODE_DXSTR:
case NODE_DREGX:
case NODE_DSYM:
rb_gc_mark_movable(node->nd_lit);
rb_gc_mark_movable(RNODE_LIT(node)->nd_lit);
break;
default:
rb_bug("unreachable node %s", ruby_node_name(nd_type(node)));
@ -349,7 +356,7 @@ mark_ast_value(rb_ast_t *ast, void *ctx, NODE * node)
}
static void
update_ast_value(rb_ast_t *ast, void *ctx, NODE * node)
update_ast_value(rb_ast_t *ast, void *ctx, NODE *node)
{
#ifdef UNIVERSAL_PARSER
bug_report_func rb_bug = ast->node_buffer->config->bug;
@ -364,7 +371,7 @@ update_ast_value(rb_ast_t *ast, void *ctx, NODE * node)
case NODE_DXSTR:
case NODE_DREGX:
case NODE_DSYM:
node->nd_lit = rb_gc_location(node->nd_lit);
RNODE_LIT(node)->nd_lit = rb_gc_location(RNODE_LIT(node)->nd_lit);
break;
default:
rb_bug("unreachable");
@ -418,8 +425,8 @@ buffer_list_size(node_buffer_list_t *nb)
size_t size = 0;
node_buffer_elem_t *nbe = nb->head;
while (nbe != nb->last) {
size += offsetof(node_buffer_elem_t, buf) + nbe->used;
nbe = nbe->next;
size += offsetof(node_buffer_elem_t, buf) + nb->len * sizeof(NODE);
}
return size;
}
@ -431,7 +438,7 @@ rb_ast_memsize(const rb_ast_t *ast)
node_buffer_t *nb = ast->node_buffer;
if (nb) {
size += sizeof(node_buffer_t) + offsetof(node_buffer_elem_t, buf) + NODE_BUF_DEFAULT_LEN * sizeof(NODE);
size += sizeof(node_buffer_t);
size += buffer_list_size(&nb->unmarkable);
size += buffer_list_size(&nb->markable);
}

36
node.h
Просмотреть файл

@ -19,12 +19,14 @@ typedef void (*bug_report_func)(const char *fmt, ...);
typedef struct node_buffer_elem_struct {
struct node_buffer_elem_struct *next;
long len;
NODE buf[FLEX_ARY_LEN];
long len; /* Length of nodes */
size_t allocated; /* Total memory size of allocated buf */
size_t used; /* Current usage of buf */
NODE **nodes; /* Array of node pointers */
NODE *buf[FLEX_ARY_LEN];
} node_buffer_elem_t;
typedef struct {
long idx, len;
node_buffer_elem_t *head;
node_buffer_elem_t *last;
} node_buffer_list_t;
@ -59,14 +61,14 @@ VALUE rb_ast_tokens(rb_ast_t *ast);
void rb_ast_node_type_change(NODE *n, enum node_type type);
#endif
const char *ruby_node_name(int node);
void rb_node_init(NODE *n, enum node_type type, VALUE a0, VALUE a1, VALUE a2);
void rb_node_init(NODE *n, enum node_type type);
void rb_ast_mark(rb_ast_t*);
void rb_ast_update_references(rb_ast_t*);
void rb_ast_free(rb_ast_t*);
void rb_ast_add_mark_object(rb_ast_t*, VALUE);
void rb_ast_set_tokens(rb_ast_t*, VALUE);
NODE *rb_ast_newnode(rb_ast_t*, enum node_type type);
NODE *rb_ast_newnode(rb_ast_t*, enum node_type type, size_t size, size_t alignment);
void rb_ast_delete_node(rb_ast_t*, NODE *n);
rb_ast_id_table_t *rb_ast_new_local_table(rb_ast_t*, int);
rb_ast_id_table_t *rb_ast_resize_latest_local_table(rb_ast_t*, int);
@ -100,21 +102,21 @@ RUBY_SYMBOL_EXPORT_END
#define NODE_SPECIAL_EXCESSIVE_COMMA ((ID)1)
#define NODE_SPECIAL_NO_REST_KEYWORD ((NODE *)-1)
#define nd_first_column(n) ((int)((n)->nd_loc.beg_pos.column))
#define nd_set_first_column(n, v) ((n)->nd_loc.beg_pos.column = (v))
#define nd_first_lineno(n) ((int)((n)->nd_loc.beg_pos.lineno))
#define nd_set_first_lineno(n, v) ((n)->nd_loc.beg_pos.lineno = (v))
#define nd_first_loc(n) ((n)->nd_loc.beg_pos)
#define nd_first_column(n) ((int)(RNODE(n)->nd_loc.beg_pos.column))
#define nd_set_first_column(n, v) (RNODE(n)->nd_loc.beg_pos.column = (v))
#define nd_first_lineno(n) ((int)(RNODE(n)->nd_loc.beg_pos.lineno))
#define nd_set_first_lineno(n, v) (RNODE(n)->nd_loc.beg_pos.lineno = (v))
#define nd_first_loc(n) (RNODE(n)->nd_loc.beg_pos)
#define nd_set_first_loc(n, v) (nd_first_loc(n) = (v))
#define nd_last_column(n) ((int)((n)->nd_loc.end_pos.column))
#define nd_set_last_column(n, v) ((n)->nd_loc.end_pos.column = (v))
#define nd_last_lineno(n) ((int)((n)->nd_loc.end_pos.lineno))
#define nd_set_last_lineno(n, v) ((n)->nd_loc.end_pos.lineno = (v))
#define nd_last_loc(n) ((n)->nd_loc.end_pos)
#define nd_last_column(n) ((int)(RNODE(n)->nd_loc.end_pos.column))
#define nd_set_last_column(n, v) (RNODE(n)->nd_loc.end_pos.column = (v))
#define nd_last_lineno(n) ((int)(RNODE(n)->nd_loc.end_pos.lineno))
#define nd_set_last_lineno(n, v) (RNODE(n)->nd_loc.end_pos.lineno = (v))
#define nd_last_loc(n) (RNODE(n)->nd_loc.end_pos)
#define nd_set_last_loc(n, v) (nd_last_loc(n) = (v))
#define nd_node_id(n) ((n)->node_id)
#define nd_set_node_id(n,id) ((n)->node_id = (id))
#define nd_node_id(n) (RNODE(n)->node_id)
#define nd_set_node_id(n,id) (RNODE(n)->node_id = (id))
static inline bool
nd_type_p(const NODE *n, enum node_type t)

Разница между файлами не показана из-за своего большого размера Загрузить разницу

2139
parse.y

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -22,107 +22,6 @@ code_loc_gen(const rb_code_location_t *loc1, const rb_code_location_t *loc2)
return loc;
}
#define RNODE(obj) ((struct RNode *)(obj))
#define NEW_NODE(t,a0,a1,a2,loc) rb_node_newnode((t),(VALUE)(a0),(VALUE)(a1),(VALUE)(a2),loc)
#define NEW_NODE_WITH_LOCALS(t,a1,a2,loc) node_newnode_with_locals(p, (t),(VALUE)(a1),(VALUE)(a2),loc)
#define NEW_DEFN(i,a,d,loc) NEW_NODE(NODE_DEFN,0,i,NEW_SCOPE(a,d,loc),loc)
#define NEW_DEFS(r,i,a,d,loc) NEW_NODE(NODE_DEFS,r,i,NEW_SCOPE(a,d,loc),loc)
#define NEW_SCOPE(a,b,loc) NEW_NODE_WITH_LOCALS(NODE_SCOPE,b,a,loc)
#define NEW_BLOCK(a,loc) NEW_NODE(NODE_BLOCK,a,0,0,loc)
#define NEW_IF(c,t,e,loc) NEW_NODE(NODE_IF,c,t,e,loc)
#define NEW_UNLESS(c,t,e,loc) NEW_NODE(NODE_UNLESS,c,t,e,loc)
#define NEW_CASE(h,b,loc) NEW_NODE(NODE_CASE,h,b,0,loc)
#define NEW_CASE2(b,loc) NEW_NODE(NODE_CASE2,0,b,0,loc)
#define NEW_CASE3(h,b,loc) NEW_NODE(NODE_CASE3,h,b,0,loc)
#define NEW_WHEN(c,t,e,loc) NEW_NODE(NODE_WHEN,c,t,e,loc)
#define NEW_IN(c,t,e,loc) NEW_NODE(NODE_IN,c,t,e,loc)
#define NEW_WHILE(c,b,n,loc) NEW_NODE(NODE_WHILE,c,b,n,loc)
#define NEW_UNTIL(c,b,n,loc) NEW_NODE(NODE_UNTIL,c,b,n,loc)
#define NEW_FOR(i,b,loc) NEW_NODE(NODE_FOR,0,b,i,loc)
#define NEW_FOR_MASGN(v,loc) NEW_NODE(NODE_FOR_MASGN,v,0,0,loc)
#define NEW_ITER(a,b,loc) NEW_NODE(NODE_ITER,0,NEW_SCOPE(a,b,loc),0,loc)
#define NEW_LAMBDA(a,b,loc) NEW_NODE(NODE_LAMBDA,0,NEW_SCOPE(a,b,loc),0,loc)
#define NEW_BREAK(s,loc) NEW_NODE(NODE_BREAK,s,0,0,loc)
#define NEW_NEXT(s,loc) NEW_NODE(NODE_NEXT,s,0,0,loc)
#define NEW_REDO(loc) NEW_NODE(NODE_REDO,0,0,0,loc)
#define NEW_RETRY(loc) NEW_NODE(NODE_RETRY,0,0,0,loc)
#define NEW_BEGIN(b,loc) NEW_NODE(NODE_BEGIN,0,b,0,loc)
#define NEW_RESCUE(b,res,e,loc) NEW_NODE(NODE_RESCUE,b,res,e,loc)
#define NEW_RESBODY(a,ex,n,loc) NEW_NODE(NODE_RESBODY,n,ex,a,loc)
#define NEW_ENSURE(b,en,loc) NEW_NODE(NODE_ENSURE,b,0,en,loc)
#define NEW_RETURN(s,loc) NEW_NODE(NODE_RETURN,s,0,0,loc)
#define NEW_YIELD(a,loc) NEW_NODE(NODE_YIELD,a,0,0,loc)
#define NEW_LIST(a,loc) NEW_NODE(NODE_LIST,a,1,0,loc)
#define NEW_ZLIST(loc) NEW_NODE(NODE_ZLIST,0,0,0,loc)
#define NEW_HASH(a,loc) NEW_NODE(NODE_HASH,a,0,0,loc)
#define NEW_MASGN(l,r,loc) NEW_NODE(NODE_MASGN,l,0,r,loc)
#define NEW_GASGN(v,val,loc) NEW_NODE(NODE_GASGN,v,val,0,loc)
#define NEW_LASGN(v,val,loc) NEW_NODE(NODE_LASGN,v,val,0,loc)
#define NEW_DASGN(v,val,loc) NEW_NODE(NODE_DASGN,v,val,0,loc)
#define NEW_IASGN(v,val,loc) NEW_NODE(NODE_IASGN,v,val,0,loc)
#define NEW_CDECL(v,val,path,loc) NEW_NODE(NODE_CDECL,v,val,path,loc)
#define NEW_CVASGN(v,val,loc) NEW_NODE(NODE_CVASGN,v,val,0,loc)
#define NEW_OP_ASGN1(p,id,a,loc) NEW_NODE(NODE_OP_ASGN1,p,id,a,loc)
#define NEW_OP_ASGN2(r,t,i,o,val,loc) NEW_NODE(NODE_OP_ASGN2,r,val,NEW_OP_ASGN22(i,o,t,loc),loc)
#define NEW_OP_ASGN22(i,o,t,loc) NEW_NODE(NODE_OP_ASGN2,i,o,t,loc)
#define NEW_OP_ASGN_OR(i,val,loc) NEW_NODE(NODE_OP_ASGN_OR,i,val,0,loc)
#define NEW_OP_ASGN_AND(i,val,loc) NEW_NODE(NODE_OP_ASGN_AND,i,val,0,loc)
#define NEW_OP_CDECL(v,op,val,loc) NEW_NODE(NODE_OP_CDECL,v,val,op,loc)
#define NEW_GVAR(v,loc) NEW_NODE(NODE_GVAR,v,0,0,loc)
#define NEW_LVAR(v,loc) NEW_NODE(NODE_LVAR,v,0,0,loc)
#define NEW_DVAR(v,loc) NEW_NODE(NODE_DVAR,v,0,0,loc)
#define NEW_IVAR(v,loc) NEW_NODE(NODE_IVAR,v,0,0,loc)
#define NEW_CONST(v,loc) NEW_NODE(NODE_CONST,v,0,0,loc)
#define NEW_CVAR(v,loc) NEW_NODE(NODE_CVAR,v,0,0,loc)
#define NEW_NTH_REF(n,loc) NEW_NODE(NODE_NTH_REF,0,n,0,loc)
#define NEW_BACK_REF(n,loc) NEW_NODE(NODE_BACK_REF,0,n,0,loc)
#define NEW_MATCH(c,loc) NEW_NODE(NODE_MATCH,c,0,0,loc)
#define NEW_MATCH2(n1,n2,loc) NEW_NODE(NODE_MATCH2,n1,n2,0,loc)
#define NEW_MATCH3(r,n2,loc) NEW_NODE(NODE_MATCH3,r,n2,0,loc)
#define NEW_LIT(l,loc) NEW_NODE(NODE_LIT,l,0,0,loc)
#define NEW_STR(s,loc) NEW_NODE(NODE_STR,s,0,0,loc)
#define NEW_DSTR(s,loc) NEW_NODE(NODE_DSTR,s,1,0,loc)
#define NEW_XSTR(s,loc) NEW_NODE(NODE_XSTR,s,0,0,loc)
#define NEW_DXSTR(s,loc) NEW_NODE(NODE_DXSTR,s,0,0,loc)
#define NEW_DSYM(s,loc) NEW_NODE(NODE_DSYM,s,0,0,loc)
#define NEW_EVSTR(n,loc) NEW_NODE(NODE_EVSTR,0,(n),0,loc)
#define NEW_CALL(r,m,a,loc) NEW_NODE(NODE_CALL,r,m,a,loc)
#define NEW_OPCALL(r,m,a,loc) NEW_NODE(NODE_OPCALL,r,m,a,loc)
#define NEW_FCALL(m,a,loc) NEW_NODE(NODE_FCALL,0,m,a,loc)
#define NEW_VCALL(m,loc) NEW_NODE(NODE_VCALL,0,m,0,loc)
#define NEW_SUPER(a,loc) NEW_NODE(NODE_SUPER,0,0,a,loc)
#define NEW_ZSUPER(loc) NEW_NODE(NODE_ZSUPER,0,0,0,loc)
#define NEW_ARGS_AUX(r,b,loc) NEW_NODE(NODE_ARGS_AUX,r,b,0,loc)
#define NEW_OPT_ARG(v,loc) NEW_NODE(NODE_OPT_ARG,0,v,0,loc)
#define NEW_KW_ARG(v,loc) NEW_NODE(NODE_KW_ARG,0,v,0,loc)
#define NEW_POSTARG(i,v,loc) NEW_NODE(NODE_POSTARG,i,v,0,loc)
#define NEW_ARGSCAT(a,b,loc) NEW_NODE(NODE_ARGSCAT,a,b,0,loc)
#define NEW_ARGSPUSH(a,b,loc) NEW_NODE(NODE_ARGSPUSH,a,b,0,loc)
#define NEW_SPLAT(a,loc) NEW_NODE(NODE_SPLAT,a,0,0,loc)
#define NEW_BLOCK_PASS(b,loc) NEW_NODE(NODE_BLOCK_PASS,0,b,0,loc)
#define NEW_ALIAS(n,o,loc) NEW_NODE(NODE_ALIAS,n,o,0,loc)
#define NEW_VALIAS(n,o,loc) NEW_NODE(NODE_VALIAS,n,o,0,loc)
#define NEW_UNDEF(i,loc) NEW_NODE(NODE_UNDEF,0,i,0,loc)
#define NEW_CLASS(n,b,s,loc) NEW_NODE(NODE_CLASS,n,NEW_SCOPE(0,b,loc),(s),loc)
#define NEW_SCLASS(r,b,loc) NEW_NODE(NODE_SCLASS,r,NEW_SCOPE(0,b,loc),0,loc)
#define NEW_MODULE(n,b,loc) NEW_NODE(NODE_MODULE,n,NEW_SCOPE(0,b,loc),0,loc)
#define NEW_COLON2(c,i,loc) NEW_NODE(NODE_COLON2,c,i,0,loc)
#define NEW_COLON3(i,loc) NEW_NODE(NODE_COLON3,0,i,0,loc)
#define NEW_DOT2(b,e,loc) NEW_NODE(NODE_DOT2,b,e,0,loc)
#define NEW_DOT3(b,e,loc) NEW_NODE(NODE_DOT3,b,e,0,loc)
#define NEW_SELF(loc) NEW_NODE(NODE_SELF,0,0,1,loc)
#define NEW_NIL(loc) NEW_NODE(NODE_NIL,0,0,0,loc)
#define NEW_TRUE(loc) NEW_NODE(NODE_TRUE,0,0,0,loc)
#define NEW_FALSE(loc) NEW_NODE(NODE_FALSE,0,0,0,loc)
#define NEW_ERRINFO(loc) NEW_NODE(NODE_ERRINFO,0,0,0,loc)
#define NEW_DEFINED(e,loc) NEW_NODE(NODE_DEFINED,e,0,0,loc)
#define NEW_POSTEXE(b,loc) NEW_NODE(NODE_POSTEXE,0,b,0,loc)
#define NEW_ATTRASGN(r,m,a,loc) NEW_NODE(NODE_ATTRASGN,r,m,a,loc)
#define NEW_ERROR(loc) NEW_NODE(NODE_ERROR,0,0,0,loc)
#if defined(__cplusplus)
#if 0
{ /* satisfy cc-mode */

Просмотреть файл

@ -356,7 +356,7 @@ reg_named_capture_assign(struct parser_params* p, VALUE regexp, const rb_code_lo
onig_foreach_name(RREGEXP_PTR(regexp), reg_named_capture_assign_iter, &arg);
if (!arg.succ_block) return 0;
return arg.succ_block->nd_next;
return RNODE_BLOCK(arg.succ_block)->nd_next;
}
static VALUE

Разница между файлами не показана из-за своего большого размера Загрузить разницу

10
vm.c
Просмотреть файл

@ -1384,7 +1384,7 @@ rb_binding_add_dynavars(VALUE bindval, rb_binding_t *bind, int dyncount, const I
rb_execution_context_t *ec = GET_EC();
const rb_iseq_t *base_iseq, *iseq;
rb_ast_body_t ast;
NODE tmp_node;
rb_node_scope_t tmp_node;
if (dyncount < 0) return 0;
@ -1396,8 +1396,12 @@ rb_binding_add_dynavars(VALUE bindval, rb_binding_t *bind, int dyncount, const I
dyns->size = dyncount;
MEMCPY(dyns->ids, dynvars, ID, dyncount);
rb_node_init(&tmp_node, NODE_SCOPE, (VALUE)dyns, 0, 0);
ast.root = &tmp_node;
rb_node_init(RNODE(&tmp_node), NODE_SCOPE);
tmp_node.nd_tbl = dyns;
tmp_node.nd_body = 0;
tmp_node.nd_args = 0;
ast.root = RNODE(&tmp_node);
ast.frozen_string_literal = -1;
ast.coverage_enabled = -1;
ast.script_lines = INT2FIX(-1);