зеркало из https://github.com/github/ruby.git
[PRISM] Compile constant reads using opt_getconstant_path
This commit is contained in:
Родитель
b2d468fced
Коммит
54295ba5e1
|
@ -186,7 +186,7 @@ pm_constant_pool_id_to_constant(const pm_constant_pool_t *pool, pm_constant_id_t
|
|||
* the constant is not found.
|
||||
*/
|
||||
pm_constant_id_t
|
||||
pm_constant_pool_find(pm_constant_pool_t *pool, const uint8_t *start, size_t length) {
|
||||
pm_constant_pool_find(const pm_constant_pool_t *pool, const uint8_t *start, size_t length) {
|
||||
assert(is_power_of_two(pool->capacity));
|
||||
const uint32_t mask = pool->capacity - 1;
|
||||
|
||||
|
|
|
@ -163,7 +163,7 @@ pm_constant_t * pm_constant_pool_id_to_constant(const pm_constant_pool_t *pool,
|
|||
* @param length The length of the constant.
|
||||
* @return The id of the constant.
|
||||
*/
|
||||
pm_constant_id_t pm_constant_pool_find(pm_constant_pool_t *pool, const uint8_t *start, size_t length);
|
||||
pm_constant_id_t pm_constant_pool_find(const pm_constant_pool_t *pool, const uint8_t *start, size_t length);
|
||||
|
||||
/**
|
||||
* Insert a constant into a constant pool that is a slice of a source string.
|
||||
|
|
131
prism_compile.c
131
prism_compile.c
|
@ -470,9 +470,7 @@ pm_compile_branch_condition(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const pm_no
|
|||
static void
|
||||
pm_compile_logical(rb_iseq_t *iseq, LINK_ANCHOR *const ret, pm_node_t *cond, LABEL *then_label, LABEL *else_label, bool popped, pm_scope_node_t *scope_node)
|
||||
{
|
||||
pm_parser_t *parser = scope_node->parser;
|
||||
pm_newline_list_t newline_list = parser->newline_list;
|
||||
int lineno = (int)pm_newline_list_line_column(&newline_list, cond->location.start).line;
|
||||
int lineno = (int) pm_newline_list_line_column(&scope_node->parser->newline_list, cond->location.start).line;
|
||||
NODE dummy_line_node = generate_dummy_line_node(lineno, lineno);
|
||||
|
||||
DECL_ANCHOR(seq);
|
||||
|
@ -550,9 +548,7 @@ static void
|
|||
pm_compile_branch_condition(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const pm_node_t *cond,
|
||||
LABEL *then_label, LABEL *else_label, bool popped, pm_scope_node_t *scope_node)
|
||||
{
|
||||
pm_parser_t *parser = scope_node->parser;
|
||||
pm_newline_list_t newline_list = parser->newline_list;
|
||||
int lineno = (int) pm_newline_list_line_column(&newline_list, cond->location.start).line;
|
||||
int lineno = (int) pm_newline_list_line_column(&scope_node->parser->newline_list, cond->location.start).line;
|
||||
NODE dummy_line_node = generate_dummy_line_node(lineno, lineno);
|
||||
|
||||
again:
|
||||
|
@ -731,7 +727,7 @@ pm_compile_while(rb_iseq_t *iseq, int lineno, pm_node_flags_t flags, enum pm_nod
|
|||
}
|
||||
|
||||
static int
|
||||
pm_interpolated_node_compile(pm_node_list_t *parts, rb_iseq_t *iseq, NODE dummy_line_node, LINK_ANCHOR *const ret, bool popped, pm_scope_node_t *scope_node, pm_parser_t *parser)
|
||||
pm_interpolated_node_compile(pm_node_list_t *parts, rb_iseq_t *iseq, NODE dummy_line_node, LINK_ANCHOR *const ret, bool popped, pm_scope_node_t *scope_node, const pm_parser_t *parser)
|
||||
{
|
||||
int number_of_items_pushed = 0;
|
||||
size_t parts_size = parts->size;
|
||||
|
@ -859,7 +855,7 @@ pm_constant_id_lookup(pm_scope_node_t *scope_node, pm_constant_id_t constant_id)
|
|||
}
|
||||
|
||||
static rb_iseq_t *
|
||||
pm_new_child_iseq(rb_iseq_t *iseq, pm_scope_node_t *node, pm_parser_t *parser,
|
||||
pm_new_child_iseq(rb_iseq_t *iseq, pm_scope_node_t *node, const pm_parser_t *parser,
|
||||
VALUE name, const rb_iseq_t *parent, enum rb_iseq_type type, int line_no)
|
||||
{
|
||||
debugs("[new_child_iseq]> ---------------------------------------\n");
|
||||
|
@ -1033,7 +1029,7 @@ pm_arg_compile_keyword_hash_node(pm_keyword_hash_node_t *node, rb_iseq_t *iseq,
|
|||
|
||||
// This is details. Users should call pm_setup_args() instead.
|
||||
static int
|
||||
pm_setup_args_core(const pm_arguments_node_t *arguments_node, const pm_node_t *block, int *flags, const bool has_regular_blockarg, struct rb_callinfo_kwarg **kw_arg, rb_iseq_t *iseq, LINK_ANCHOR *const ret, pm_scope_node_t *scope_node, NODE dummy_line_node, pm_parser_t *parser)
|
||||
pm_setup_args_core(const pm_arguments_node_t *arguments_node, const pm_node_t *block, int *flags, const bool has_regular_blockarg, struct rb_callinfo_kwarg **kw_arg, rb_iseq_t *iseq, LINK_ANCHOR *const ret, pm_scope_node_t *scope_node, NODE dummy_line_node, const pm_parser_t *parser)
|
||||
{
|
||||
int orig_argc = 0;
|
||||
bool has_splat = false;
|
||||
|
@ -1249,7 +1245,7 @@ pm_setup_args_core(const pm_arguments_node_t *arguments_node, const pm_node_t *b
|
|||
|
||||
// Compile the argument parts of a call
|
||||
static int
|
||||
pm_setup_args(const pm_arguments_node_t *arguments_node, const pm_node_t *block, int *flags, struct rb_callinfo_kwarg **kw_arg, rb_iseq_t *iseq, LINK_ANCHOR *const ret, pm_scope_node_t *scope_node, NODE dummy_line_node, pm_parser_t *parser)
|
||||
pm_setup_args(const pm_arguments_node_t *arguments_node, const pm_node_t *block, int *flags, struct rb_callinfo_kwarg **kw_arg, rb_iseq_t *iseq, LINK_ANCHOR *const ret, pm_scope_node_t *scope_node, NODE dummy_line_node, const pm_parser_t *parser)
|
||||
{
|
||||
if (block && PM_NODE_TYPE_P(block, PM_BLOCK_ARGUMENT_NODE)) {
|
||||
// We compile the `&block_arg` expression first and stitch it later
|
||||
|
@ -2441,7 +2437,7 @@ pm_compile_pattern(rb_iseq_t *iseq, pm_scope_node_t *scope_node, const pm_node_t
|
|||
|
||||
// Generate a scope node from the given node.
|
||||
void
|
||||
pm_scope_node_init(const pm_node_t *node, pm_scope_node_t *scope, pm_scope_node_t *previous, pm_parser_t *parser)
|
||||
pm_scope_node_init(const pm_node_t *node, pm_scope_node_t *scope, pm_scope_node_t *previous, const pm_parser_t *parser)
|
||||
{
|
||||
scope->base.type = PM_SCOPE_NODE;
|
||||
scope->base.location.start = node->location.start;
|
||||
|
@ -2912,13 +2908,11 @@ pm_compile_defined_expr(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *con
|
|||
static void
|
||||
pm_compile_call(rb_iseq_t *iseq, const pm_call_node_t *call_node, LINK_ANCHOR *const ret, bool popped, pm_scope_node_t *scope_node, ID method_id, LABEL *start)
|
||||
{
|
||||
pm_parser_t *parser = scope_node->parser;
|
||||
pm_newline_list_t newline_list = parser->newline_list;
|
||||
|
||||
const pm_parser_t *parser = scope_node->parser;
|
||||
const uint8_t *call_start = call_node->message_loc.start;
|
||||
if (call_start == NULL) call_start = call_node->base.location.start;
|
||||
|
||||
int lineno = (int) pm_newline_list_line_column(&newline_list, call_start).line;
|
||||
int lineno = (int) pm_newline_list_line_column(&parser->newline_list, call_start).line;
|
||||
NODE dummy_line_node = generate_dummy_line_node(lineno, lineno);
|
||||
|
||||
LABEL *else_label = NEW_LABEL(lineno);
|
||||
|
@ -2940,7 +2934,7 @@ pm_compile_call(rb_iseq_t *iseq, const pm_call_node_t *call_node, LINK_ANCHOR *c
|
|||
pm_scope_node_t next_scope_node;
|
||||
pm_scope_node_init(call_node->block, &next_scope_node, scope_node, parser);
|
||||
|
||||
int block_lineno = (int) pm_newline_list_line_column(&newline_list, call_node->block->location.start).line;
|
||||
int block_lineno = (int) pm_newline_list_line_column(&parser->newline_list, call_node->block->location.start).line;
|
||||
block_iseq = NEW_CHILD_ISEQ(&next_scope_node, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, block_lineno);
|
||||
|
||||
pm_scope_node_destroy(&next_scope_node);
|
||||
|
@ -3763,7 +3757,7 @@ static void
|
|||
pm_compile_rescue(rb_iseq_t *iseq, pm_begin_node_t *begin_node, LINK_ANCHOR *const ret, int lineno, bool popped, pm_scope_node_t *scope_node)
|
||||
{
|
||||
NODE dummy_line_node = generate_dummy_line_node(lineno, lineno);
|
||||
pm_parser_t *parser = scope_node->parser;
|
||||
const pm_parser_t *parser = scope_node->parser;
|
||||
LABEL *lstart = NEW_LABEL(lineno);
|
||||
LABEL *lend = NEW_LABEL(lineno);
|
||||
LABEL *lcont = NEW_LABEL(lineno);
|
||||
|
@ -3812,7 +3806,7 @@ static void
|
|||
pm_compile_ensure(rb_iseq_t *iseq, pm_begin_node_t *begin_node, LINK_ANCHOR *const ret, int lineno, bool popped, pm_scope_node_t *scope_node)
|
||||
{
|
||||
NODE dummy_line_node = generate_dummy_line_node(lineno, lineno);
|
||||
pm_parser_t *parser = scope_node->parser;
|
||||
const pm_parser_t *parser = scope_node->parser;
|
||||
|
||||
LABEL *estart = NEW_LABEL(lineno);
|
||||
LABEL *eend = NEW_LABEL(lineno);
|
||||
|
@ -3929,6 +3923,28 @@ pm_opt_aset_with_p(const rb_iseq_t *iseq, const pm_call_node_t *node)
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the instructions necessary to read a constant, based on the options
|
||||
* of the current iseq.
|
||||
*/
|
||||
static inline void
|
||||
pm_compile_constant_read(rb_iseq_t *iseq, VALUE name, const pm_location_t *name_loc, LINK_ANCHOR *const ret, const pm_scope_node_t *scope_node)
|
||||
{
|
||||
int lineno = (int) pm_newline_list_line_column(&scope_node->parser->newline_list, name_loc->start).line;
|
||||
NODE dummy_line_node = generate_dummy_line_node(lineno, lineno);
|
||||
|
||||
if (ISEQ_COMPILE_DATA(iseq)->option->inline_const_cache) {
|
||||
ISEQ_BODY(iseq)->ic_size++;
|
||||
VALUE segments = rb_ary_new_from_args(1, name);
|
||||
ADD_INSN1(ret, &dummy_line_node, opt_getconstant_path, segments);
|
||||
}
|
||||
else {
|
||||
PM_PUTNIL;
|
||||
ADD_INSN1(ret, &dummy_line_node, putobject, Qtrue);
|
||||
ADD_INSN1(ret, &dummy_line_node, getconstant, name);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Compiles a prism node into instruction sequences
|
||||
*
|
||||
|
@ -3942,9 +3958,8 @@ pm_opt_aset_with_p(const rb_iseq_t *iseq, const pm_call_node_t *node)
|
|||
static void
|
||||
pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, bool popped, pm_scope_node_t *scope_node)
|
||||
{
|
||||
pm_parser_t *parser = scope_node->parser;
|
||||
pm_newline_list_t newline_list = parser->newline_list;
|
||||
int lineno = (int)pm_newline_list_line_column(&newline_list, node->location.start).line;
|
||||
const pm_parser_t *parser = scope_node->parser;
|
||||
int lineno = (int) pm_newline_list_line_column(&parser->newline_list, node->location.start).line;
|
||||
NODE dummy_line_node = generate_dummy_line_node(lineno, lineno);
|
||||
|
||||
if (node->flags & PM_NODE_FLAG_NEWLINE && ISEQ_COMPILE_DATA(iseq)->last_line != lineno) {
|
||||
|
@ -4889,90 +4904,80 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
|
|||
return;
|
||||
}
|
||||
case PM_CONSTANT_READ_NODE: {
|
||||
pm_constant_read_node_t *constant_read_node = (pm_constant_read_node_t *) node;
|
||||
PM_PUTNIL;
|
||||
ADD_INSN1(ret, &dummy_line_node, putobject, Qtrue);
|
||||
ADD_INSN1(ret, &dummy_line_node, getconstant, ID2SYM(pm_constant_id_lookup(scope_node, constant_read_node->name)));
|
||||
// Foo
|
||||
// ^^^
|
||||
const pm_constant_read_node_t *cast = (const pm_constant_read_node_t *) node;
|
||||
VALUE name = ID2SYM(pm_constant_id_lookup(scope_node, cast->name));
|
||||
|
||||
pm_compile_constant_read(iseq, name, &cast->base.location, ret, scope_node);
|
||||
|
||||
PM_POP_IF_POPPED;
|
||||
return;
|
||||
}
|
||||
case PM_CONSTANT_AND_WRITE_NODE: {
|
||||
pm_constant_and_write_node_t *constant_and_write_node = (pm_constant_and_write_node_t*) node;
|
||||
|
||||
// Foo &&= bar
|
||||
// ^^^^^^^^^^^
|
||||
const pm_constant_and_write_node_t *cast = (const pm_constant_and_write_node_t *) node;
|
||||
VALUE name = ID2SYM(pm_constant_id_lookup(scope_node, cast->name));
|
||||
LABEL *end_label = NEW_LABEL(lineno);
|
||||
|
||||
VALUE constant_name = ID2SYM(pm_constant_id_lookup(scope_node, constant_and_write_node->name));
|
||||
pm_compile_constant_read(iseq, name, &cast->name_loc, ret, scope_node);
|
||||
|
||||
PM_PUTNIL;
|
||||
ADD_INSN1(ret, &dummy_line_node, putobject, Qtrue);
|
||||
ADD_INSN1(ret, &dummy_line_node, getconstant, constant_name);
|
||||
PM_DUP_UNLESS_POPPED;
|
||||
|
||||
ADD_INSNL(ret, &dummy_line_node, branchunless, end_label);
|
||||
|
||||
PM_POP_UNLESS_POPPED;
|
||||
|
||||
PM_COMPILE_NOT_POPPED(constant_and_write_node->value);
|
||||
|
||||
PM_COMPILE_NOT_POPPED(cast->value);
|
||||
PM_DUP_UNLESS_POPPED;
|
||||
|
||||
ADD_INSN1(ret, &dummy_line_node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_CONST_BASE));
|
||||
ADD_INSN1(ret, &dummy_line_node, setconstant, constant_name);
|
||||
ADD_INSN1(ret, &dummy_line_node, setconstant, name);
|
||||
ADD_LABEL(ret, end_label);
|
||||
|
||||
return;
|
||||
}
|
||||
case PM_CONSTANT_OPERATOR_WRITE_NODE: {
|
||||
pm_constant_operator_write_node_t *constant_operator_write_node = (pm_constant_operator_write_node_t*) node;
|
||||
// Foo += bar
|
||||
// ^^^^^^^^^^
|
||||
const pm_constant_operator_write_node_t *cast = (const pm_constant_operator_write_node_t *) node;
|
||||
VALUE name = ID2SYM(pm_constant_id_lookup(scope_node, cast->name));
|
||||
ID method_id = pm_constant_id_lookup(scope_node, cast->operator);
|
||||
|
||||
ID constant_name = pm_constant_id_lookup(scope_node, constant_operator_write_node->name);
|
||||
PM_PUTNIL;
|
||||
ADD_INSN1(ret, &dummy_line_node, putobject, Qtrue);
|
||||
ADD_INSN1(ret, &dummy_line_node, getconstant, ID2SYM(constant_name));
|
||||
|
||||
PM_COMPILE_NOT_POPPED(constant_operator_write_node->value);
|
||||
ID method_id = pm_constant_id_lookup(scope_node, constant_operator_write_node->operator);
|
||||
|
||||
int flags = VM_CALL_ARGS_SIMPLE;
|
||||
ADD_SEND_WITH_FLAG(ret, &dummy_line_node, method_id, INT2NUM(1), INT2FIX(flags));
|
||||
pm_compile_constant_read(iseq, name, &cast->name_loc, ret, scope_node);
|
||||
|
||||
PM_COMPILE_NOT_POPPED(cast->value);
|
||||
ADD_SEND_WITH_FLAG(ret, &dummy_line_node, method_id, INT2NUM(1), INT2FIX(VM_CALL_ARGS_SIMPLE));
|
||||
PM_DUP_UNLESS_POPPED;
|
||||
|
||||
ADD_INSN1(ret, &dummy_line_node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_CONST_BASE));
|
||||
ADD_INSN1(ret, &dummy_line_node, setconstant, ID2SYM(constant_name));
|
||||
ADD_INSN1(ret, &dummy_line_node, setconstant, name);
|
||||
|
||||
return;
|
||||
}
|
||||
case PM_CONSTANT_OR_WRITE_NODE: {
|
||||
pm_constant_or_write_node_t *constant_or_write_node = (pm_constant_or_write_node_t*) node;
|
||||
|
||||
LABEL *set_label= NEW_LABEL(lineno);
|
||||
// Foo ||= bar
|
||||
// ^^^^^^^^^^^
|
||||
const pm_constant_or_write_node_t *cast = (const pm_constant_or_write_node_t *) node;
|
||||
VALUE name = ID2SYM(pm_constant_id_lookup(scope_node, cast->name));
|
||||
LABEL *set_label = NEW_LABEL(lineno);
|
||||
LABEL *end_label = NEW_LABEL(lineno);
|
||||
|
||||
PM_PUTNIL;
|
||||
VALUE constant_name = ID2SYM(pm_constant_id_lookup(scope_node, constant_or_write_node->name));
|
||||
|
||||
ADD_INSN3(ret, &dummy_line_node, defined, INT2FIX(DEFINED_CONST), constant_name, Qtrue);
|
||||
|
||||
ADD_INSN3(ret, &dummy_line_node, defined, INT2FIX(DEFINED_CONST), name, Qtrue);
|
||||
ADD_INSNL(ret, &dummy_line_node, branchunless, set_label);
|
||||
|
||||
PM_PUTNIL;
|
||||
ADD_INSN1(ret, &dummy_line_node, putobject, Qtrue);
|
||||
ADD_INSN1(ret, &dummy_line_node, getconstant, constant_name);
|
||||
pm_compile_constant_read(iseq, name, &cast->name_loc, ret, scope_node);
|
||||
|
||||
PM_DUP_UNLESS_POPPED;
|
||||
|
||||
ADD_INSNL(ret, &dummy_line_node, branchif, end_label);
|
||||
|
||||
PM_POP_UNLESS_POPPED;
|
||||
|
||||
ADD_LABEL(ret, set_label);
|
||||
PM_COMPILE_NOT_POPPED(constant_or_write_node->value);
|
||||
PM_COMPILE_NOT_POPPED(cast->value);
|
||||
|
||||
PM_DUP_UNLESS_POPPED;
|
||||
|
||||
ADD_INSN1(ret, &dummy_line_node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_CONST_BASE));
|
||||
ADD_INSN1(ret, &dummy_line_node, setconstant, constant_name);
|
||||
ADD_INSN1(ret, &dummy_line_node, setconstant, name);
|
||||
ADD_LABEL(ret, end_label);
|
||||
|
||||
return;
|
||||
|
|
|
@ -21,7 +21,7 @@ typedef struct pm_scope_node {
|
|||
pm_node_t *parameters;
|
||||
pm_node_t *body;
|
||||
pm_constant_id_list_t locals;
|
||||
pm_parser_t *parser;
|
||||
const pm_parser_t *parser;
|
||||
|
||||
// The size of the local table
|
||||
// on the iseq which includes
|
||||
|
@ -32,7 +32,7 @@ typedef struct pm_scope_node {
|
|||
st_table *index_lookup_table;
|
||||
} pm_scope_node_t;
|
||||
|
||||
void pm_scope_node_init(const pm_node_t *node, pm_scope_node_t *scope, pm_scope_node_t *previous, pm_parser_t *parser);
|
||||
void pm_scope_node_init(const pm_node_t *node, pm_scope_node_t *scope, pm_scope_node_t *previous, const pm_parser_t *parser);
|
||||
void pm_scope_node_destroy(pm_scope_node_t *scope_node);
|
||||
bool *rb_ruby_prism_ptr(void);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче