зеркало из https://github.com/github/ruby.git
Refactor hacky ID tables to struct rb_ast_id_table_t
The implementation of a local variable tables was represented as `ID*`, but it was very hacky: the first element is not an ID but the size of the table, and, the last element is (sometimes) a link to the next local table only when the id tables are a linked list. This change converts the hacky implementation to a normal struct.
This commit is contained in:
Родитель
86ad878e6a
Коммит
feda058531
6
ast.c
6
ast.c
|
@ -600,11 +600,11 @@ node_children(rb_ast_t *ast, const NODE *node)
|
|||
}
|
||||
case NODE_SCOPE:
|
||||
{
|
||||
ID *tbl = node->nd_tbl;
|
||||
int i, size = tbl ? (int)*tbl++ : 0;
|
||||
rb_ast_id_table_t *tbl = 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[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));
|
||||
}
|
||||
|
|
|
@ -7937,6 +7937,7 @@ localeinit.$(OBJEXT): {$(VPATH)}st.h
|
|||
localeinit.$(OBJEXT): {$(VPATH)}subst.h
|
||||
main.$(OBJEXT): $(hdrdir)/ruby.h
|
||||
main.$(OBJEXT): $(hdrdir)/ruby/ruby.h
|
||||
main.$(OBJEXT): $(top_srcdir)/internal/compilers.h
|
||||
main.$(OBJEXT): {$(VPATH)}assert.h
|
||||
main.$(OBJEXT): {$(VPATH)}backward.h
|
||||
main.$(OBJEXT): {$(VPATH)}backward/2/assume.h
|
||||
|
@ -8463,6 +8464,7 @@ math.$(OBJEXT): {$(VPATH)}missing.h
|
|||
math.$(OBJEXT): {$(VPATH)}st.h
|
||||
math.$(OBJEXT): {$(VPATH)}subst.h
|
||||
memory_view.$(OBJEXT): $(hdrdir)/ruby/ruby.h
|
||||
memory_view.$(OBJEXT): $(top_srcdir)/internal/compilers.h
|
||||
memory_view.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
||||
memory_view.$(OBJEXT): $(top_srcdir)/internal/variable.h
|
||||
memory_view.$(OBJEXT): {$(VPATH)}assert.h
|
||||
|
|
28
compile.c
28
compile.c
|
@ -482,7 +482,7 @@ static int iseq_setup_insn(rb_iseq_t *iseq, LINK_ANCHOR *const anchor);
|
|||
static int iseq_optimize(rb_iseq_t *iseq, LINK_ANCHOR *const anchor);
|
||||
static int iseq_insns_unification(rb_iseq_t *iseq, LINK_ANCHOR *const anchor);
|
||||
|
||||
static int iseq_set_local_table(rb_iseq_t *iseq, const ID *tbl);
|
||||
static int iseq_set_local_table(rb_iseq_t *iseq, const rb_ast_id_table_t *tbl);
|
||||
static int iseq_set_exception_local_table(rb_iseq_t *iseq);
|
||||
static int iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *const anchor, const NODE *const node);
|
||||
|
||||
|
@ -1946,21 +1946,13 @@ iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *const optargs, const NODE *cons
|
|||
}
|
||||
|
||||
static int
|
||||
iseq_set_local_table(rb_iseq_t *iseq, const ID *tbl)
|
||||
iseq_set_local_table(rb_iseq_t *iseq, const rb_ast_id_table_t *tbl)
|
||||
{
|
||||
unsigned int size;
|
||||
|
||||
if (tbl) {
|
||||
size = (unsigned int)*tbl;
|
||||
tbl++;
|
||||
}
|
||||
else {
|
||||
size = 0;
|
||||
}
|
||||
unsigned int size = tbl ? tbl->size : 0;
|
||||
|
||||
if (size > 0) {
|
||||
ID *ids = (ID *)ALLOC_N(ID, size);
|
||||
MEMCPY(ids, tbl, ID, size);
|
||||
MEMCPY(ids, tbl->ids, ID, size);
|
||||
iseq->body->local_table = ids;
|
||||
}
|
||||
iseq->body->local_table_size = size;
|
||||
|
@ -7908,17 +7900,20 @@ compile_builtin_mandatory_only_method(rb_iseq_t *iseq, const NODE *node, const N
|
|||
// local table without non-mandatory parameters
|
||||
const int skip_local_size = iseq->body->param.size - iseq->body->param.lead_num;
|
||||
const int table_size = iseq->body->local_table_size - skip_local_size;
|
||||
ID *tbl = ALLOCA_N(ID, table_size + 1);
|
||||
tbl[0] = table_size;
|
||||
|
||||
VALUE idtmp = 0;
|
||||
rb_ast_id_table_t *tbl = ALLOCV(idtmp, sizeof(rb_ast_id_table_t) + table_size * sizeof(ID));
|
||||
tbl->size = table_size;
|
||||
|
||||
int i;
|
||||
|
||||
// lead parameters
|
||||
for (i=0; i<iseq->body->param.lead_num; i++) {
|
||||
tbl[i+1] = iseq->body->local_table[i];
|
||||
tbl->ids[i] = iseq->body->local_table[i];
|
||||
}
|
||||
// local variables
|
||||
for (; i<table_size; i++) {
|
||||
tbl[i+1] = iseq->body->local_table[i + skip_local_size];
|
||||
tbl->ids[i] = iseq->body->local_table[i + skip_local_size];
|
||||
}
|
||||
|
||||
NODE scope_node;
|
||||
|
@ -7939,6 +7934,7 @@ compile_builtin_mandatory_only_method(rb_iseq_t *iseq, const NODE *node, const N
|
|||
ISEQ_TYPE_METHOD, ISEQ_COMPILE_DATA(iseq)->option);
|
||||
|
||||
GET_VM()->builtin_inline_index = prev_inline_index;
|
||||
ALLOCV_END(idtmp);
|
||||
return COMPILE_OK;
|
||||
}
|
||||
|
||||
|
|
47
node.c
47
node.c
|
@ -1043,12 +1043,12 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node)
|
|||
ANN("new scope");
|
||||
ANN("format: [nd_tbl]: local table, [nd_args]: arguments, [nd_body]: body");
|
||||
F_CUSTOM1(nd_tbl, "local table") {
|
||||
ID *tbl = node->nd_tbl;
|
||||
rb_ast_id_table_t *tbl = node->nd_tbl;
|
||||
int i;
|
||||
int size = tbl ? (int)*tbl++ : 0;
|
||||
int size = tbl ? tbl->size : 0;
|
||||
if (size == 0) A("(empty)");
|
||||
for (i = 0; i < size; i++) {
|
||||
A_ID(tbl[i]); if (i < size - 1) A(",");
|
||||
A_ID(tbl->ids[i]); if (i < size - 1) A(",");
|
||||
}
|
||||
}
|
||||
F_NODE(nd_args, "arguments");
|
||||
|
@ -1162,7 +1162,7 @@ typedef struct {
|
|||
struct node_buffer_struct {
|
||||
node_buffer_list_t unmarkable;
|
||||
node_buffer_list_t markable;
|
||||
ID *local_tables;
|
||||
struct rb_ast_local_table_link *local_tables;
|
||||
VALUE mark_hash;
|
||||
};
|
||||
|
||||
|
@ -1205,15 +1205,22 @@ node_buffer_list_free(node_buffer_list_t * nb)
|
|||
}
|
||||
}
|
||||
|
||||
struct rb_ast_local_table_link {
|
||||
struct rb_ast_local_table_link *next;
|
||||
// struct rb_ast_id_table {
|
||||
int size;
|
||||
ID ids[FLEX_ARY_LEN];
|
||||
// }
|
||||
};
|
||||
|
||||
static void
|
||||
rb_node_buffer_free(node_buffer_t *nb)
|
||||
{
|
||||
node_buffer_list_free(&nb->unmarkable);
|
||||
node_buffer_list_free(&nb->markable);
|
||||
ID * local_table = nb->local_tables;
|
||||
struct rb_ast_local_table_link *local_table = nb->local_tables;
|
||||
while (local_table) {
|
||||
unsigned int size = (unsigned int)*local_table;
|
||||
ID * next_table = (ID *)local_table[size + 1];
|
||||
struct rb_ast_local_table_link *next_table = local_table->next;
|
||||
xfree(local_table);
|
||||
local_table = next_table;
|
||||
}
|
||||
|
@ -1277,12 +1284,28 @@ rb_ast_node_type_change(NODE *n, enum node_type type)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
rb_ast_add_local_table(rb_ast_t *ast, ID *buf)
|
||||
rb_ast_id_table_t *
|
||||
rb_ast_new_local_table(rb_ast_t *ast, int size)
|
||||
{
|
||||
unsigned int size = (unsigned int)*buf;
|
||||
buf[size + 1] = (ID)ast->node_buffer->local_tables;
|
||||
ast->node_buffer->local_tables = buf;
|
||||
size_t alloc_size = sizeof(struct rb_ast_local_table_link) + size * sizeof(ID);
|
||||
struct rb_ast_local_table_link *link = ruby_xmalloc(alloc_size);
|
||||
link->next = ast->node_buffer->local_tables;
|
||||
ast->node_buffer->local_tables = link;
|
||||
link->size = size;
|
||||
|
||||
return (rb_ast_id_table_t *) &link->size;
|
||||
}
|
||||
|
||||
rb_ast_id_table_t *
|
||||
rb_ast_resize_latest_local_table(rb_ast_t *ast, int size)
|
||||
{
|
||||
struct rb_ast_local_table_link *link = ast->node_buffer->local_tables;
|
||||
size_t alloc_size = sizeof(struct rb_ast_local_table_link) + size * sizeof(ID);
|
||||
link = ruby_xrealloc(link, alloc_size);
|
||||
ast->node_buffer->local_tables = link;
|
||||
link->size = size;
|
||||
|
||||
return (rb_ast_id_table_t *) &link->size;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
12
node.h
12
node.h
|
@ -11,6 +11,8 @@
|
|||
|
||||
**********************************************************************/
|
||||
|
||||
#include "internal/compilers.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#if 0
|
||||
|
@ -146,13 +148,18 @@ code_loc_gen(const rb_code_location_t *loc1, const rb_code_location_t *loc2)
|
|||
return loc;
|
||||
}
|
||||
|
||||
typedef struct rb_ast_id_table {
|
||||
int size;
|
||||
ID ids[FLEX_ARY_LEN];
|
||||
} rb_ast_id_table_t;
|
||||
|
||||
typedef struct RNode {
|
||||
VALUE flags;
|
||||
union {
|
||||
struct RNode *node;
|
||||
ID id;
|
||||
VALUE value;
|
||||
ID *tbl;
|
||||
rb_ast_id_table_t *tbl;
|
||||
} u1;
|
||||
union {
|
||||
struct RNode *node;
|
||||
|
@ -411,13 +418,14 @@ typedef struct rb_ast_struct {
|
|||
rb_ast_t *rb_ast_new(void);
|
||||
void rb_ast_mark(rb_ast_t*);
|
||||
void rb_ast_update_references(rb_ast_t*);
|
||||
void rb_ast_add_local_table(rb_ast_t*, ID *buf);
|
||||
void rb_ast_dispose(rb_ast_t*);
|
||||
void rb_ast_free(rb_ast_t*);
|
||||
size_t rb_ast_memsize(const rb_ast_t*);
|
||||
void rb_ast_add_mark_object(rb_ast_t*, VALUE);
|
||||
NODE *rb_ast_newnode(rb_ast_t*, enum node_type type);
|
||||
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);
|
||||
|
||||
VALUE rb_parser_new(void);
|
||||
VALUE rb_parser_end_seen_p(VALUE);
|
||||
|
|
29
parse.y
29
parse.y
|
@ -574,7 +574,7 @@ static NODE *symbol_append(struct parser_params *p, NODE *symbols, NODE *symbol)
|
|||
|
||||
static NODE *match_op(struct parser_params*,NODE*,NODE*,const YYLTYPE*,const YYLTYPE*);
|
||||
|
||||
static ID *local_tbl(struct parser_params*);
|
||||
static rb_ast_id_table_t *local_tbl(struct parser_params*);
|
||||
|
||||
static VALUE reg_compile(struct parser_params*, VALUE, int);
|
||||
static void reg_fragment_setenc(struct parser_params*, VALUE, int);
|
||||
|
@ -3172,9 +3172,8 @@ primary : literal
|
|||
ID id = internal_id(p);
|
||||
NODE *m = NEW_ARGS_AUX(0, 0, &NULL_LOC);
|
||||
NODE *args, *scope, *internal_var = NEW_DVAR(id, &@2);
|
||||
ID *tbl = ALLOC_N(ID, 3);
|
||||
tbl[0] = 1 /* length of local var table */; tbl[1] = id /* internal id */;
|
||||
rb_ast_add_local_table(p->ast, tbl);
|
||||
rb_ast_id_table_t *tbl = rb_ast_new_local_table(p->ast, 1);
|
||||
tbl->ids[0] = id; /* internal id */
|
||||
|
||||
switch (nd_type($2)) {
|
||||
case NODE_LASGN:
|
||||
|
@ -12585,38 +12584,36 @@ local_pop(struct parser_params *p)
|
|||
}
|
||||
|
||||
#ifndef RIPPER
|
||||
static ID*
|
||||
static rb_ast_id_table_t *
|
||||
local_tbl(struct parser_params *p)
|
||||
{
|
||||
int cnt_args = vtable_size(p->lvtbl->args);
|
||||
int cnt_vars = vtable_size(p->lvtbl->vars);
|
||||
int cnt = cnt_args + cnt_vars;
|
||||
int i, j;
|
||||
ID *buf;
|
||||
rb_ast_id_table_t *tbl;
|
||||
|
||||
if (cnt <= 0) return 0;
|
||||
buf = ALLOC_N(ID, cnt + 2);
|
||||
MEMCPY(buf+1, p->lvtbl->args->tbl, ID, cnt_args);
|
||||
tbl = rb_ast_new_local_table(p->ast, cnt);
|
||||
MEMCPY(tbl->ids, p->lvtbl->args->tbl, ID, cnt_args);
|
||||
/* remove IDs duplicated to warn shadowing */
|
||||
for (i = 0, j = cnt_args+1; i < cnt_vars; ++i) {
|
||||
for (i = 0, j = cnt_args; i < cnt_vars; ++i) {
|
||||
ID id = p->lvtbl->vars->tbl[i];
|
||||
if (!vtable_included(p->lvtbl->args, id)) {
|
||||
buf[j++] = id;
|
||||
tbl->ids[j++] = id;
|
||||
}
|
||||
}
|
||||
if (--j < cnt) {
|
||||
REALLOC_N(buf, ID, (cnt = j) + 2);
|
||||
if (j < cnt) {
|
||||
tbl = rb_ast_resize_latest_local_table(p->ast, j);
|
||||
}
|
||||
buf[0] = cnt;
|
||||
rb_ast_add_local_table(p->ast, buf);
|
||||
|
||||
return buf;
|
||||
return tbl;
|
||||
}
|
||||
|
||||
static NODE*
|
||||
node_newnode_with_locals(struct parser_params *p, enum node_type type, VALUE a1, VALUE a2, const rb_code_location_t *loc)
|
||||
{
|
||||
ID *a0;
|
||||
rb_ast_id_table_t *a0;
|
||||
NODE *n;
|
||||
|
||||
a0 = local_tbl(p);
|
||||
|
|
9
vm.c
9
vm.c
|
@ -1256,18 +1256,17 @@ rb_binding_add_dynavars(VALUE bindval, rb_binding_t *bind, int dyncount, const I
|
|||
const rb_iseq_t *base_iseq, *iseq;
|
||||
rb_ast_body_t ast;
|
||||
NODE tmp_node;
|
||||
ID minibuf[4], *dyns = minibuf;
|
||||
VALUE idtmp = 0;
|
||||
|
||||
if (dyncount < 0) return 0;
|
||||
|
||||
base_block = &bind->block;
|
||||
base_iseq = vm_block_iseq(base_block);
|
||||
|
||||
if (dyncount >= numberof(minibuf)) dyns = ALLOCV_N(ID, idtmp, dyncount + 1);
|
||||
VALUE idtmp = 0;
|
||||
rb_ast_id_table_t *dyns = ALLOCV(idtmp, sizeof(rb_ast_id_table_t) + dyncount * sizeof(ID));
|
||||
dyns->size = dyncount;
|
||||
MEMCPY(dyns->ids, dynvars, ID, dyncount);
|
||||
|
||||
dyns[0] = dyncount;
|
||||
MEMCPY(dyns + 1, dynvars, ID, dyncount);
|
||||
rb_node_init(&tmp_node, NODE_SCOPE, (VALUE)dyns, 0, 0);
|
||||
ast.root = &tmp_node;
|
||||
ast.compile_option = 0;
|
||||
|
|
Загрузка…
Ссылка в новой задаче