[PRISM] Remove dummy_line_node usage from index nodes
This commit is contained in:
parent
6bec2a5333
commit
bc5a520eca
408
prism_compile.c
408
prism_compile.c
@ -1223,8 +1223,11 @@ pm_compile_hash_elements(const pm_node_list_t *elements, int lineno, rb_iseq_t *
|
|||||||
|
|
||||||
// This is details. Users should call pm_setup_args() instead.
|
// This is details. Users should call pm_setup_args() instead.
|
||||||
static int
|
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_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, const pm_line_column_t *node_location)
|
||||||
{
|
{
|
||||||
|
const pm_line_column_t location = *node_location;
|
||||||
|
NODE dummy_line_node = generate_dummy_line_node(location.line, location.column);
|
||||||
|
|
||||||
int orig_argc = 0;
|
int orig_argc = 0;
|
||||||
bool has_splat = false;
|
bool has_splat = false;
|
||||||
bool has_keyword_splat = false;
|
bool has_keyword_splat = false;
|
||||||
@ -1235,17 +1238,15 @@ pm_setup_args_core(const pm_arguments_node_t *arguments_node, const pm_node_t *b
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pm_node_list_t arguments_node_list = arguments_node->arguments;
|
const pm_node_list_t *arguments = &arguments_node->arguments;
|
||||||
|
has_keyword_splat = PM_NODE_FLAG_P(arguments_node, PM_ARGUMENTS_NODE_FLAGS_CONTAINS_KEYWORD_SPLAT);
|
||||||
has_keyword_splat = (arguments_node->base.flags & PM_ARGUMENTS_NODE_FLAGS_CONTAINS_KEYWORD_SPLAT);
|
|
||||||
|
|
||||||
// We count the number of elements post the splat node that are not keyword elements to
|
// We count the number of elements post the splat node that are not keyword elements to
|
||||||
// eventually pass as an argument to newarray
|
// eventually pass as an argument to newarray
|
||||||
int post_splat_counter = 0;
|
int post_splat_counter = 0;
|
||||||
|
const pm_node_t *argument;
|
||||||
|
|
||||||
for (size_t index = 0; index < arguments_node_list.size; index++) {
|
PM_NODE_LIST_FOREACH(arguments, index, argument) {
|
||||||
const pm_node_t *argument = arguments_node_list.nodes[index];
|
|
||||||
|
|
||||||
switch (PM_NODE_TYPE(argument)) {
|
switch (PM_NODE_TYPE(argument)) {
|
||||||
// A keyword hash node contains all keyword arguments as AssocNodes and AssocSplatNodes
|
// A keyword hash node contains all keyword arguments as AssocNodes and AssocSplatNodes
|
||||||
case PM_KEYWORD_HASH_NODE: {
|
case PM_KEYWORD_HASH_NODE: {
|
||||||
@ -1255,7 +1256,7 @@ pm_setup_args_core(const pm_arguments_node_t *arguments_node, const pm_node_t *b
|
|||||||
if (has_keyword_splat || has_splat) {
|
if (has_keyword_splat || has_splat) {
|
||||||
*flags |= VM_CALL_KW_SPLAT;
|
*flags |= VM_CALL_KW_SPLAT;
|
||||||
has_keyword_splat = true;
|
has_keyword_splat = true;
|
||||||
pm_compile_hash_elements(elements, nd_line(&dummy_line_node), iseq, ret, scope_node);
|
pm_compile_hash_elements(elements, location.line, iseq, ret, scope_node);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// We need to first figure out if all elements of the
|
// We need to first figure out if all elements of the
|
||||||
@ -1335,7 +1336,7 @@ pm_setup_args_core(const pm_arguments_node_t *arguments_node, const pm_node_t *b
|
|||||||
PM_COMPILE_NOT_POPPED(assoc->value);
|
PM_COMPILE_NOT_POPPED(assoc->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
ADD_INSN1(ret, &dummy_line_node, newhash, INT2FIX(size * 2));
|
PUSH_INSN1(ret, location, newhash, INT2FIX(size * 2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1360,8 +1361,8 @@ pm_setup_args_core(const pm_arguments_node_t *arguments_node, const pm_node_t *b
|
|||||||
//
|
//
|
||||||
// foo(a, *b, c)
|
// foo(a, *b, c)
|
||||||
// ^^
|
// ^^
|
||||||
if (index + 1 < arguments_node_list.size || has_regular_blockarg) {
|
if (index + 1 < arguments->size || has_regular_blockarg) {
|
||||||
ADD_INSN1(ret, &dummy_line_node, splatarray, Qtrue);
|
PUSH_INSN1(ret, location, splatarray, Qtrue);
|
||||||
*flags |= VM_CALL_ARGS_SPLAT_MUT;
|
*flags |= VM_CALL_ARGS_SPLAT_MUT;
|
||||||
}
|
}
|
||||||
// If this is the first spalt array seen and it's the last
|
// If this is the first spalt array seen and it's the last
|
||||||
@ -1370,7 +1371,7 @@ pm_setup_args_core(const pm_arguments_node_t *arguments_node, const pm_node_t *b
|
|||||||
// foo(a, *b)
|
// foo(a, *b)
|
||||||
// ^^
|
// ^^
|
||||||
else {
|
else {
|
||||||
ADD_INSN1(ret, &dummy_line_node, splatarray, Qfalse);
|
PUSH_INSN1(ret, location, splatarray, Qfalse);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1380,8 +1381,8 @@ pm_setup_args_core(const pm_arguments_node_t *arguments_node, const pm_node_t *b
|
|||||||
//
|
//
|
||||||
// foo(a, *b, *c)
|
// foo(a, *b, *c)
|
||||||
// ^^
|
// ^^
|
||||||
ADD_INSN1(ret, &dummy_line_node, splatarray, Qfalse);
|
PUSH_INSN1(ret, location, splatarray, Qfalse);
|
||||||
ADD_INSN(ret, &dummy_line_node, concatarray);
|
PUSH_INSN(ret, location, concatarray);
|
||||||
}
|
}
|
||||||
|
|
||||||
has_splat = true;
|
has_splat = true;
|
||||||
@ -1400,7 +1401,7 @@ pm_setup_args_core(const pm_arguments_node_t *arguments_node, const pm_node_t *b
|
|||||||
// Push the *
|
// Push the *
|
||||||
pm_local_index_t mult_local = pm_lookup_local_index(iseq, scope_node, PM_CONSTANT_MULT, 0);
|
pm_local_index_t mult_local = pm_lookup_local_index(iseq, scope_node, PM_CONSTANT_MULT, 0);
|
||||||
ADD_GETLOCAL(ret, &dummy_line_node, mult_local.index, mult_local.level);
|
ADD_GETLOCAL(ret, &dummy_line_node, mult_local.index, mult_local.level);
|
||||||
ADD_INSN1(ret, &dummy_line_node, splatarray, Qtrue);
|
PUSH_INSN1(ret, location, splatarray, Qtrue);
|
||||||
|
|
||||||
// Push the **
|
// Push the **
|
||||||
pm_local_index_t pow_local = pm_lookup_local_index(iseq, scope_node, PM_CONSTANT_POW, 0);
|
pm_local_index_t pow_local = pm_lookup_local_index(iseq, scope_node, PM_CONSTANT_POW, 0);
|
||||||
@ -1408,8 +1409,8 @@ pm_setup_args_core(const pm_arguments_node_t *arguments_node, const pm_node_t *b
|
|||||||
|
|
||||||
// Push the &
|
// Push the &
|
||||||
pm_local_index_t and_local = pm_lookup_local_index(iseq, scope_node, PM_CONSTANT_AND, 0);
|
pm_local_index_t and_local = pm_lookup_local_index(iseq, scope_node, PM_CONSTANT_AND, 0);
|
||||||
ADD_INSN2(ret, &dummy_line_node, getblockparamproxy, INT2FIX(and_local.index + VM_ENV_DATA_SIZE - 1), INT2FIX(and_local.level));
|
PUSH_INSN2(ret, location, getblockparamproxy, INT2FIX(and_local.index + VM_ENV_DATA_SIZE - 1), INT2FIX(and_local.level));
|
||||||
ADD_INSN(ret, &dummy_line_node, splatkw);
|
PUSH_INSN(ret, location, splatkw);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1435,23 +1436,23 @@ pm_setup_args_core(const pm_arguments_node_t *arguments_node, const pm_node_t *b
|
|||||||
// If the next node is NULL (we have hit the end):
|
// If the next node is NULL (we have hit the end):
|
||||||
//
|
//
|
||||||
// foo(*a, b)
|
// foo(*a, b)
|
||||||
if (index == arguments_node_list.size - 1) {
|
if (index == arguments->size - 1) {
|
||||||
RUBY_ASSERT(post_splat_counter > 0);
|
RUBY_ASSERT(post_splat_counter > 0);
|
||||||
ADD_INSN1(ret, &dummy_line_node, pushtoarray, INT2FIX(post_splat_counter));
|
PUSH_INSN1(ret, location, pushtoarray, INT2FIX(post_splat_counter));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pm_node_t *next_arg = arguments_node_list.nodes[index + 1];
|
pm_node_t *next_arg = arguments->nodes[index + 1];
|
||||||
|
|
||||||
switch (PM_NODE_TYPE(next_arg)) {
|
switch (PM_NODE_TYPE(next_arg)) {
|
||||||
// A keyword hash node contains all keyword arguments as AssocNodes and AssocSplatNodes
|
// A keyword hash node contains all keyword arguments as AssocNodes and AssocSplatNodes
|
||||||
case PM_KEYWORD_HASH_NODE: {
|
case PM_KEYWORD_HASH_NODE: {
|
||||||
ADD_INSN1(ret, &dummy_line_node, newarray, INT2FIX(post_splat_counter));
|
PUSH_INSN1(ret, location, newarray, INT2FIX(post_splat_counter));
|
||||||
ADD_INSN(ret, &dummy_line_node, concatarray);
|
PUSH_INSN(ret, location, concatarray);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PM_SPLAT_NODE: {
|
case PM_SPLAT_NODE: {
|
||||||
ADD_INSN1(ret, &dummy_line_node, newarray, INT2FIX(post_splat_counter));
|
PUSH_INSN1(ret, location, newarray, INT2FIX(post_splat_counter));
|
||||||
ADD_INSN(ret, &dummy_line_node, concatarray);
|
PUSH_INSN(ret, location, concatarray);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -1467,20 +1468,14 @@ pm_setup_args_core(const pm_arguments_node_t *arguments_node, const pm_node_t *b
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (has_splat) {
|
if (has_splat) orig_argc++;
|
||||||
orig_argc++;
|
if (has_keyword_splat) orig_argc++;
|
||||||
}
|
|
||||||
|
|
||||||
if (has_keyword_splat) {
|
|
||||||
orig_argc++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return orig_argc;
|
return orig_argc;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compile the argument parts of a call
|
// Compile the argument parts of a call
|
||||||
static int
|
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_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, const pm_line_column_t *node_location)
|
||||||
{
|
{
|
||||||
if (block && PM_NODE_TYPE_P(block, PM_BLOCK_ARGUMENT_NODE)) {
|
if (block && PM_NODE_TYPE_P(block, PM_BLOCK_ARGUMENT_NODE)) {
|
||||||
// We compile the `&block_arg` expression first and stitch it later
|
// We compile the `&block_arg` expression first and stitch it later
|
||||||
@ -1507,11 +1502,12 @@ pm_setup_args(const pm_arguments_node_t *arguments_node, const pm_node_t *block,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int argc = pm_setup_args_core(arguments_node, block, flags, regular_block_arg, kw_arg, iseq, ret, scope_node, dummy_line_node);
|
int argc = pm_setup_args_core(arguments_node, block, flags, regular_block_arg, kw_arg, iseq, ret, scope_node, node_location);
|
||||||
ADD_SEQ(ret, block_arg);
|
ADD_SEQ(ret, block_arg);
|
||||||
return argc;
|
return argc;
|
||||||
}
|
}
|
||||||
return pm_setup_args_core(arguments_node, block, flags, false, kw_arg, iseq, ret, scope_node, dummy_line_node);
|
|
||||||
|
return pm_setup_args_core(arguments_node, block, flags, false, kw_arg, iseq, ret, scope_node, node_location);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1525,30 +1521,26 @@ pm_setup_args(const pm_arguments_node_t *arguments_node, const pm_node_t *block,
|
|||||||
* and then calling the []= method with the result of the operator method.
|
* and then calling the []= method with the result of the operator method.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
pm_compile_index_operator_write_node(pm_scope_node_t *scope_node, const pm_index_operator_write_node_t *node, rb_iseq_t *iseq, LINK_ANCHOR *const ret, bool popped)
|
pm_compile_index_operator_write_node(rb_iseq_t *iseq, const pm_index_operator_write_node_t *node, const pm_line_column_t *node_location, LINK_ANCHOR *const ret, bool popped, pm_scope_node_t *scope_node)
|
||||||
{
|
{
|
||||||
int lineno = pm_node_line_number(scope_node->parser, (const pm_node_t *) node);
|
const pm_line_column_t location = *node_location;
|
||||||
const NODE dummy_line_node = generate_dummy_line_node(lineno, lineno);
|
if (!popped) PUSH_INSN(ret, location, putnil);
|
||||||
|
|
||||||
if (!popped) {
|
|
||||||
PM_PUTNIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
PM_COMPILE_NOT_POPPED(node->receiver);
|
PM_COMPILE_NOT_POPPED(node->receiver);
|
||||||
|
|
||||||
int boff = (node->block == NULL ? 0 : 1);
|
int boff = (node->block == NULL ? 0 : 1);
|
||||||
int flag = PM_NODE_TYPE_P(node->receiver, PM_SELF_NODE) ? VM_CALL_FCALL : 0;
|
int flag = PM_NODE_TYPE_P(node->receiver, PM_SELF_NODE) ? VM_CALL_FCALL : 0;
|
||||||
struct rb_callinfo_kwarg *keywords = NULL;
|
struct rb_callinfo_kwarg *keywords = NULL;
|
||||||
int argc = pm_setup_args(node->arguments, node->block, &flag, &keywords, iseq, ret, scope_node, dummy_line_node);
|
int argc = pm_setup_args(node->arguments, node->block, &flag, &keywords, iseq, ret, scope_node, node_location);
|
||||||
|
|
||||||
if ((argc > 0 || boff) && (flag & VM_CALL_KW_SPLAT)) {
|
if ((argc > 0 || boff) && (flag & VM_CALL_KW_SPLAT)) {
|
||||||
if (boff) {
|
if (boff) {
|
||||||
ADD_INSN(ret, &dummy_line_node, splatkw);
|
PUSH_INSN(ret, location, splatkw);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ADD_INSN(ret, &dummy_line_node, dup);
|
PUSH_INSN(ret, location, dup);
|
||||||
ADD_INSN(ret, &dummy_line_node, splatkw);
|
PUSH_INSN(ret, location, splatkw);
|
||||||
ADD_INSN(ret, &dummy_line_node, pop);
|
PUSH_INSN(ret, location, pop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1560,76 +1552,77 @@ pm_compile_index_operator_write_node(pm_scope_node_t *scope_node, const pm_index
|
|||||||
dup_argn += keyword_len;
|
dup_argn += keyword_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
ADD_INSN1(ret, &dummy_line_node, dupn, INT2FIX(dup_argn));
|
PUSH_INSN1(ret, location, dupn, INT2FIX(dup_argn));
|
||||||
ADD_SEND_R(ret, &dummy_line_node, idAREF, INT2FIX(argc), NULL, INT2FIX(flag & ~(VM_CALL_ARGS_SPLAT_MUT | VM_CALL_KW_SPLAT_MUT)), keywords);
|
PUSH_SEND_R(ret, location, idAREF, INT2FIX(argc), NULL, INT2FIX(flag & ~(VM_CALL_ARGS_SPLAT_MUT | VM_CALL_KW_SPLAT_MUT)), keywords);
|
||||||
|
|
||||||
PM_COMPILE_NOT_POPPED(node->value);
|
PM_COMPILE_NOT_POPPED(node->value);
|
||||||
|
|
||||||
ID id_operator = pm_constant_id_lookup(scope_node, node->operator);
|
ID id_operator = pm_constant_id_lookup(scope_node, node->operator);
|
||||||
ADD_SEND(ret, &dummy_line_node, id_operator, INT2FIX(1));
|
PUSH_SEND(ret, location, id_operator, INT2FIX(1));
|
||||||
|
|
||||||
if (!popped) {
|
if (!popped) {
|
||||||
ADD_INSN1(ret, &dummy_line_node, setn, INT2FIX(dup_argn + 1));
|
PUSH_INSN1(ret, location, setn, INT2FIX(dup_argn + 1));
|
||||||
}
|
}
|
||||||
if (flag & VM_CALL_ARGS_SPLAT) {
|
if (flag & VM_CALL_ARGS_SPLAT) {
|
||||||
if (flag & VM_CALL_KW_SPLAT) {
|
if (flag & VM_CALL_KW_SPLAT) {
|
||||||
ADD_INSN1(ret, &dummy_line_node, topn, INT2FIX(2 + boff));
|
PUSH_INSN1(ret, location, topn, INT2FIX(2 + boff));
|
||||||
|
|
||||||
if (!(flag & VM_CALL_ARGS_SPLAT_MUT)) {
|
if (!(flag & VM_CALL_ARGS_SPLAT_MUT)) {
|
||||||
ADD_INSN1(ret, &dummy_line_node, splatarray, Qtrue);
|
PUSH_INSN1(ret, location, splatarray, Qtrue);
|
||||||
flag |= VM_CALL_ARGS_SPLAT_MUT;
|
flag |= VM_CALL_ARGS_SPLAT_MUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
ADD_INSN(ret, &dummy_line_node, swap);
|
PUSH_INSN(ret, location, swap);
|
||||||
ADD_INSN1(ret, &dummy_line_node, pushtoarray, INT2FIX(1));
|
PUSH_INSN1(ret, location, pushtoarray, INT2FIX(1));
|
||||||
ADD_INSN1(ret, &dummy_line_node, setn, INT2FIX(2 + boff));
|
PUSH_INSN1(ret, location, setn, INT2FIX(2 + boff));
|
||||||
ADD_INSN(ret, &dummy_line_node, pop);
|
PUSH_INSN(ret, location, pop);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (boff > 0) {
|
if (boff > 0) {
|
||||||
ADD_INSN1(ret, &dummy_line_node, dupn, INT2FIX(3));
|
PUSH_INSN1(ret, location, dupn, INT2FIX(3));
|
||||||
ADD_INSN(ret, &dummy_line_node, swap);
|
PUSH_INSN(ret, location, swap);
|
||||||
ADD_INSN(ret, &dummy_line_node, pop);
|
PUSH_INSN(ret, location, pop);
|
||||||
}
|
}
|
||||||
if (!(flag & VM_CALL_ARGS_SPLAT_MUT)) {
|
if (!(flag & VM_CALL_ARGS_SPLAT_MUT)) {
|
||||||
ADD_INSN(ret, &dummy_line_node, swap);
|
PUSH_INSN(ret, location, swap);
|
||||||
ADD_INSN1(ret, &dummy_line_node, splatarray, Qtrue);
|
PUSH_INSN1(ret, location, splatarray, Qtrue);
|
||||||
ADD_INSN(ret, &dummy_line_node, swap);
|
PUSH_INSN(ret, location, swap);
|
||||||
flag |= VM_CALL_ARGS_SPLAT_MUT;
|
flag |= VM_CALL_ARGS_SPLAT_MUT;
|
||||||
}
|
}
|
||||||
ADD_INSN1(ret, &dummy_line_node, pushtoarray, INT2FIX(1));
|
PUSH_INSN1(ret, location, pushtoarray, INT2FIX(1));
|
||||||
if (boff > 0) {
|
if (boff > 0) {
|
||||||
ADD_INSN1(ret, &dummy_line_node, setn, INT2FIX(3));
|
PUSH_INSN1(ret, location, setn, INT2FIX(3));
|
||||||
PM_POP;
|
PUSH_INSN(ret, location, pop);
|
||||||
PM_POP;
|
PUSH_INSN(ret, location, pop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ADD_SEND_R(ret, &dummy_line_node, idASET, INT2FIX(argc), NULL, INT2FIX(flag), keywords);
|
|
||||||
|
PUSH_SEND_R(ret, location, idASET, INT2FIX(argc), NULL, INT2FIX(flag), keywords);
|
||||||
}
|
}
|
||||||
else if (flag & VM_CALL_KW_SPLAT) {
|
else if (flag & VM_CALL_KW_SPLAT) {
|
||||||
if (boff > 0) {
|
if (boff > 0) {
|
||||||
ADD_INSN1(ret, &dummy_line_node, topn, INT2FIX(2));
|
PUSH_INSN1(ret, location, topn, INT2FIX(2));
|
||||||
ADD_INSN(ret, &dummy_line_node, swap);
|
PUSH_INSN(ret, location, swap);
|
||||||
ADD_INSN1(ret, &dummy_line_node, setn, INT2FIX(3));
|
PUSH_INSN1(ret, location, setn, INT2FIX(3));
|
||||||
PM_POP;
|
PUSH_INSN(ret, location, pop);
|
||||||
}
|
}
|
||||||
ADD_INSN(ret, &dummy_line_node, swap);
|
PUSH_INSN(ret, location, swap);
|
||||||
ADD_SEND_R(ret, &dummy_line_node, idASET, INT2FIX(argc + 1), NULL, INT2FIX(flag), keywords);
|
PUSH_SEND_R(ret, location, idASET, INT2FIX(argc + 1), NULL, INT2FIX(flag), keywords);
|
||||||
}
|
}
|
||||||
else if (keyword_len) {
|
else if (keyword_len) {
|
||||||
ADD_INSN(ret, &dummy_line_node, dup);
|
PUSH_INSN(ret, location, dup);
|
||||||
ADD_INSN1(ret, &dummy_line_node, opt_reverse, INT2FIX(keyword_len + boff + 2));
|
PUSH_INSN1(ret, location, opt_reverse, INT2FIX(keyword_len + boff + 2));
|
||||||
ADD_INSN1(ret, &dummy_line_node, opt_reverse, INT2FIX(keyword_len + boff + 1));
|
PUSH_INSN1(ret, location, opt_reverse, INT2FIX(keyword_len + boff + 1));
|
||||||
ADD_INSN(ret, &dummy_line_node, pop);
|
PUSH_INSN(ret, location, pop);
|
||||||
ADD_SEND_R(ret, &dummy_line_node, idASET, INT2FIX(argc + 1), NULL, INT2FIX(flag), keywords);
|
PUSH_SEND_R(ret, location, idASET, INT2FIX(argc + 1), NULL, INT2FIX(flag), keywords);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (boff > 0) {
|
if (boff > 0) {
|
||||||
PM_SWAP;
|
PUSH_INSN(ret, location, swap);
|
||||||
}
|
}
|
||||||
ADD_SEND_R(ret, &dummy_line_node, idASET, INT2FIX(argc + 1), NULL, INT2FIX(flag), keywords);
|
PUSH_SEND_R(ret, location, idASET, INT2FIX(argc + 1), NULL, INT2FIX(flag), keywords);
|
||||||
}
|
}
|
||||||
PM_POP;
|
|
||||||
|
PUSH_INSN(ret, location, pop);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1645,30 +1638,25 @@ pm_compile_index_operator_write_node(pm_scope_node_t *scope_node, const pm_index
|
|||||||
* []= method.
|
* []= method.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
pm_compile_index_control_flow_write_node(pm_scope_node_t *scope_node, const pm_node_t *node, const pm_node_t *receiver, const pm_arguments_node_t *arguments, const pm_node_t *block, const pm_node_t *value, rb_iseq_t *iseq, LINK_ANCHOR *const ret, bool popped)
|
pm_compile_index_control_flow_write_node(rb_iseq_t *iseq, const pm_node_t *node, const pm_node_t *receiver, const pm_arguments_node_t *arguments, const pm_node_t *block, const pm_node_t *value, const pm_line_column_t *node_location, LINK_ANCHOR *const ret, bool popped, pm_scope_node_t *scope_node)
|
||||||
{
|
{
|
||||||
int lineno = pm_node_line_number(scope_node->parser, node);
|
const pm_line_column_t location = *node_location;
|
||||||
const NODE dummy_line_node = generate_dummy_line_node(lineno, lineno);
|
if (!popped) PUSH_INSN(ret, location, putnil);
|
||||||
|
|
||||||
if (!popped) {
|
|
||||||
PM_PUTNIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
PM_COMPILE_NOT_POPPED(receiver);
|
PM_COMPILE_NOT_POPPED(receiver);
|
||||||
|
|
||||||
int boff = (block == NULL ? 0 : 1);
|
int boff = (block == NULL ? 0 : 1);
|
||||||
int flag = PM_NODE_TYPE_P(receiver, PM_SELF_NODE) ? VM_CALL_FCALL : 0;
|
int flag = PM_NODE_TYPE_P(receiver, PM_SELF_NODE) ? VM_CALL_FCALL : 0;
|
||||||
struct rb_callinfo_kwarg *keywords = NULL;
|
struct rb_callinfo_kwarg *keywords = NULL;
|
||||||
int argc = pm_setup_args(arguments, block, &flag, &keywords, iseq, ret, scope_node, dummy_line_node);
|
int argc = pm_setup_args(arguments, block, &flag, &keywords, iseq, ret, scope_node, node_location);
|
||||||
|
|
||||||
if ((argc > 0 || boff) && (flag & VM_CALL_KW_SPLAT)) {
|
if ((argc > 0 || boff) && (flag & VM_CALL_KW_SPLAT)) {
|
||||||
if (boff) {
|
if (boff) {
|
||||||
ADD_INSN(ret, &dummy_line_node, splatkw);
|
PUSH_INSN(ret, location, splatkw);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ADD_INSN(ret, &dummy_line_node, dup);
|
PUSH_INSN(ret, location, dup);
|
||||||
ADD_INSN(ret, &dummy_line_node, splatkw);
|
PUSH_INSN(ret, location, splatkw);
|
||||||
ADD_INSN(ret, &dummy_line_node, pop);
|
PUSH_INSN(ret, location, pop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1680,91 +1668,93 @@ pm_compile_index_control_flow_write_node(pm_scope_node_t *scope_node, const pm_n
|
|||||||
dup_argn += keyword_len;
|
dup_argn += keyword_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
ADD_INSN1(ret, &dummy_line_node, dupn, INT2FIX(dup_argn));
|
PUSH_INSN1(ret, location, dupn, INT2FIX(dup_argn));
|
||||||
ADD_SEND_R(ret, &dummy_line_node, idAREF, INT2FIX(argc), NULL, INT2FIX(flag & ~(VM_CALL_ARGS_SPLAT_MUT | VM_CALL_KW_SPLAT_MUT)), keywords);
|
PUSH_SEND_R(ret, location, idAREF, INT2FIX(argc), NULL, INT2FIX(flag & ~(VM_CALL_ARGS_SPLAT_MUT | VM_CALL_KW_SPLAT_MUT)), keywords);
|
||||||
|
|
||||||
LABEL *label = NEW_LABEL(lineno);
|
LABEL *label = NEW_LABEL(location.line);
|
||||||
LABEL *lfin = NEW_LABEL(lineno);
|
LABEL *lfin = NEW_LABEL(location.line);
|
||||||
|
|
||||||
ADD_INSN(ret, &dummy_line_node, dup);
|
PUSH_INSN(ret, location, dup);
|
||||||
if (PM_NODE_TYPE_P(node, PM_INDEX_AND_WRITE_NODE)) {
|
if (PM_NODE_TYPE_P(node, PM_INDEX_AND_WRITE_NODE)) {
|
||||||
ADD_INSNL(ret, &dummy_line_node, branchunless, label);
|
PUSH_INSNL(ret, location, branchunless, label);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ADD_INSNL(ret, &dummy_line_node, branchif, label);
|
PUSH_INSNL(ret, location, branchif, label);
|
||||||
}
|
}
|
||||||
|
|
||||||
PM_POP;
|
PUSH_INSN(ret, location, pop);
|
||||||
PM_COMPILE_NOT_POPPED(value);
|
PM_COMPILE_NOT_POPPED(value);
|
||||||
|
|
||||||
if (!popped) {
|
if (!popped) {
|
||||||
ADD_INSN1(ret, &dummy_line_node, setn, INT2FIX(dup_argn + 1));
|
PUSH_INSN1(ret, location, setn, INT2FIX(dup_argn + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flag & VM_CALL_ARGS_SPLAT) {
|
if (flag & VM_CALL_ARGS_SPLAT) {
|
||||||
if (flag & VM_CALL_KW_SPLAT) {
|
if (flag & VM_CALL_KW_SPLAT) {
|
||||||
ADD_INSN1(ret, &dummy_line_node, topn, INT2FIX(2 + boff));
|
PUSH_INSN1(ret, location, topn, INT2FIX(2 + boff));
|
||||||
if (!(flag & VM_CALL_ARGS_SPLAT_MUT)) {
|
if (!(flag & VM_CALL_ARGS_SPLAT_MUT)) {
|
||||||
ADD_INSN1(ret, &dummy_line_node, splatarray, Qtrue);
|
PUSH_INSN1(ret, location, splatarray, Qtrue);
|
||||||
flag |= VM_CALL_ARGS_SPLAT_MUT;
|
flag |= VM_CALL_ARGS_SPLAT_MUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
ADD_INSN(ret, &dummy_line_node, swap);
|
PUSH_INSN(ret, location, swap);
|
||||||
ADD_INSN1(ret, &dummy_line_node, pushtoarray, INT2FIX(1));
|
PUSH_INSN1(ret, location, pushtoarray, INT2FIX(1));
|
||||||
ADD_INSN1(ret, &dummy_line_node, setn, INT2FIX(2 + boff));
|
PUSH_INSN1(ret, location, setn, INT2FIX(2 + boff));
|
||||||
ADD_INSN(ret, &dummy_line_node, pop);
|
PUSH_INSN(ret, location, pop);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (boff > 0) {
|
if (boff > 0) {
|
||||||
ADD_INSN1(ret, &dummy_line_node, dupn, INT2FIX(3));
|
PUSH_INSN1(ret, location, dupn, INT2FIX(3));
|
||||||
ADD_INSN(ret, &dummy_line_node, swap);
|
PUSH_INSN(ret, location, swap);
|
||||||
ADD_INSN(ret, &dummy_line_node, pop);
|
PUSH_INSN(ret, location, pop);
|
||||||
}
|
}
|
||||||
if (!(flag & VM_CALL_ARGS_SPLAT_MUT)) {
|
if (!(flag & VM_CALL_ARGS_SPLAT_MUT)) {
|
||||||
ADD_INSN(ret, &dummy_line_node, swap);
|
PUSH_INSN(ret, location, swap);
|
||||||
ADD_INSN1(ret, &dummy_line_node, splatarray, Qtrue);
|
PUSH_INSN1(ret, location, splatarray, Qtrue);
|
||||||
ADD_INSN(ret, &dummy_line_node, swap);
|
PUSH_INSN(ret, location, swap);
|
||||||
flag |= VM_CALL_ARGS_SPLAT_MUT;
|
flag |= VM_CALL_ARGS_SPLAT_MUT;
|
||||||
}
|
}
|
||||||
ADD_INSN1(ret, &dummy_line_node, pushtoarray, INT2FIX(1));
|
PUSH_INSN1(ret, location, pushtoarray, INT2FIX(1));
|
||||||
if (boff > 0) {
|
if (boff > 0) {
|
||||||
ADD_INSN1(ret, &dummy_line_node, setn, INT2FIX(3));
|
PUSH_INSN1(ret, location, setn, INT2FIX(3));
|
||||||
PM_POP;
|
PUSH_INSN(ret, location, pop);
|
||||||
PM_POP;
|
PUSH_INSN(ret, location, pop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ADD_SEND_R(ret, &dummy_line_node, idASET, INT2FIX(argc), NULL, INT2FIX(flag), keywords);
|
|
||||||
|
PUSH_SEND_R(ret, location, idASET, INT2FIX(argc), NULL, INT2FIX(flag), keywords);
|
||||||
}
|
}
|
||||||
else if (flag & VM_CALL_KW_SPLAT) {
|
else if (flag & VM_CALL_KW_SPLAT) {
|
||||||
if (boff > 0) {
|
if (boff > 0) {
|
||||||
ADD_INSN1(ret, &dummy_line_node, topn, INT2FIX(2));
|
PUSH_INSN1(ret, location, topn, INT2FIX(2));
|
||||||
ADD_INSN(ret, &dummy_line_node, swap);
|
PUSH_INSN(ret, location, swap);
|
||||||
ADD_INSN1(ret, &dummy_line_node, setn, INT2FIX(3));
|
PUSH_INSN1(ret, location, setn, INT2FIX(3));
|
||||||
PM_POP;
|
PUSH_INSN(ret, location, pop);
|
||||||
}
|
}
|
||||||
|
|
||||||
ADD_INSN(ret, &dummy_line_node, swap);
|
PUSH_INSN(ret, location, swap);
|
||||||
ADD_SEND_R(ret, &dummy_line_node, idASET, INT2FIX(argc + 1), NULL, INT2FIX(flag), keywords);
|
PUSH_SEND_R(ret, location, idASET, INT2FIX(argc + 1), NULL, INT2FIX(flag), keywords);
|
||||||
}
|
}
|
||||||
else if (keyword_len) {
|
else if (keyword_len) {
|
||||||
ADD_INSN1(ret, &dummy_line_node, opt_reverse, INT2FIX(keyword_len + boff + 1));
|
PUSH_INSN1(ret, location, opt_reverse, INT2FIX(keyword_len + boff + 1));
|
||||||
ADD_INSN1(ret, &dummy_line_node, opt_reverse, INT2FIX(keyword_len + boff + 0));
|
PUSH_INSN1(ret, location, opt_reverse, INT2FIX(keyword_len + boff + 0));
|
||||||
ADD_SEND_R(ret, &dummy_line_node, idASET, INT2FIX(argc + 1), NULL, INT2FIX(flag), keywords);
|
PUSH_SEND_R(ret, location, idASET, INT2FIX(argc + 1), NULL, INT2FIX(flag), keywords);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (boff > 0) {
|
if (boff > 0) {
|
||||||
PM_SWAP;
|
PUSH_INSN(ret, location, swap);
|
||||||
}
|
}
|
||||||
ADD_SEND_R(ret, &dummy_line_node, idASET, INT2FIX(argc + 1), NULL, INT2FIX(flag), keywords);
|
PUSH_SEND_R(ret, location, idASET, INT2FIX(argc + 1), NULL, INT2FIX(flag), keywords);
|
||||||
}
|
}
|
||||||
PM_POP;
|
|
||||||
ADD_INSNL(ret, &dummy_line_node, jump, lfin);
|
PUSH_INSN(ret, location, pop);
|
||||||
ADD_LABEL(ret, label);
|
PUSH_INSNL(ret, location, jump, lfin);
|
||||||
|
PUSH_LABEL(ret, label);
|
||||||
if (!popped) {
|
if (!popped) {
|
||||||
ADD_INSN1(ret, &dummy_line_node, setn, INT2FIX(dup_argn + 1));
|
PUSH_INSN1(ret, location, setn, INT2FIX(dup_argn + 1));
|
||||||
}
|
}
|
||||||
ADD_INSN1(ret, &dummy_line_node, adjuststack, INT2FIX(dup_argn + 1));
|
PUSH_INSN1(ret, location, adjuststack, INT2FIX(dup_argn + 1));
|
||||||
ADD_LABEL(ret, lfin);
|
PUSH_LABEL(ret, lfin);
|
||||||
}
|
}
|
||||||
|
|
||||||
// When we compile a pattern matching expression, we use the stack as a scratch
|
// When we compile a pattern matching expression, we use the stack as a scratch
|
||||||
@ -3165,21 +3155,19 @@ pm_compile_call(rb_iseq_t *iseq, const pm_call_node_t *call_node, LINK_ANCHOR *c
|
|||||||
const pm_location_t *message_loc = &call_node->message_loc;
|
const pm_location_t *message_loc = &call_node->message_loc;
|
||||||
if (message_loc->start == NULL) message_loc = &call_node->base.location;
|
if (message_loc->start == NULL) message_loc = &call_node->base.location;
|
||||||
|
|
||||||
int lineno = pm_location_line_number(scope_node->parser, message_loc);
|
const pm_line_column_t location = pm_newline_list_line_column(&scope_node->parser->newline_list, message_loc->start, scope_node->parser->start_line);
|
||||||
NODE dummy_line_node = generate_dummy_line_node(lineno, lineno);
|
LABEL *else_label = NEW_LABEL(location.line);
|
||||||
|
LABEL *end_label = NEW_LABEL(location.line);
|
||||||
LABEL *else_label = NEW_LABEL(lineno);
|
|
||||||
LABEL *end_label = NEW_LABEL(lineno);
|
|
||||||
|
|
||||||
if (PM_NODE_FLAG_P(call_node, PM_CALL_NODE_FLAGS_SAFE_NAVIGATION)) {
|
if (PM_NODE_FLAG_P(call_node, PM_CALL_NODE_FLAGS_SAFE_NAVIGATION)) {
|
||||||
PM_DUP;
|
PUSH_INSN(ret, location, dup);
|
||||||
ADD_INSNL(ret, &dummy_line_node, branchnil, else_label);
|
PUSH_INSNL(ret, location, branchnil, else_label);
|
||||||
}
|
}
|
||||||
|
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
struct rb_callinfo_kwarg *kw_arg = NULL;
|
struct rb_callinfo_kwarg *kw_arg = NULL;
|
||||||
|
|
||||||
int orig_argc = pm_setup_args(call_node->arguments, call_node->block, &flags, &kw_arg, iseq, ret, scope_node, dummy_line_node);
|
int orig_argc = pm_setup_args(call_node->arguments, call_node->block, &flags, &kw_arg, iseq, ret, scope_node, &location);
|
||||||
const rb_iseq_t *block_iseq = NULL;
|
const rb_iseq_t *block_iseq = NULL;
|
||||||
|
|
||||||
if (call_node->block != NULL && PM_NODE_TYPE_P(call_node->block, PM_BLOCK_NODE)) {
|
if (call_node->block != NULL && PM_NODE_TYPE_P(call_node->block, PM_BLOCK_NODE)) {
|
||||||
@ -3211,46 +3199,46 @@ pm_compile_call(rb_iseq_t *iseq, const pm_call_node_t *call_node, LINK_ANCHOR *c
|
|||||||
|
|
||||||
if (!popped && PM_NODE_FLAG_P(call_node, PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE)) {
|
if (!popped && PM_NODE_FLAG_P(call_node, PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE)) {
|
||||||
if (flags & VM_CALL_ARGS_BLOCKARG) {
|
if (flags & VM_CALL_ARGS_BLOCKARG) {
|
||||||
ADD_INSN1(ret, &dummy_line_node, topn, INT2FIX(1));
|
PUSH_INSN1(ret, location, topn, INT2FIX(1));
|
||||||
if (flags & VM_CALL_ARGS_SPLAT) {
|
if (flags & VM_CALL_ARGS_SPLAT) {
|
||||||
ADD_INSN1(ret, &dummy_line_node, putobject, INT2FIX(-1));
|
PUSH_INSN1(ret, location, putobject, INT2FIX(-1));
|
||||||
ADD_SEND_WITH_FLAG(ret, &dummy_line_node, idAREF, INT2FIX(1), INT2FIX(0));
|
PUSH_SEND_WITH_FLAG(ret, location, idAREF, INT2FIX(1), INT2FIX(0));
|
||||||
}
|
}
|
||||||
ADD_INSN1(ret, &dummy_line_node, setn, INT2FIX(orig_argc + 3));
|
PUSH_INSN1(ret, location, setn, INT2FIX(orig_argc + 3));
|
||||||
PM_POP;
|
PUSH_INSN(ret, location, pop);
|
||||||
}
|
}
|
||||||
else if (flags & VM_CALL_ARGS_SPLAT) {
|
else if (flags & VM_CALL_ARGS_SPLAT) {
|
||||||
ADD_INSN(ret, &dummy_line_node, dup);
|
PUSH_INSN(ret, location, dup);
|
||||||
ADD_INSN1(ret, &dummy_line_node, putobject, INT2FIX(-1));
|
PUSH_INSN1(ret, location, putobject, INT2FIX(-1));
|
||||||
ADD_SEND_WITH_FLAG(ret, &dummy_line_node, idAREF, INT2FIX(1), INT2FIX(0));
|
PUSH_SEND_WITH_FLAG(ret, location, idAREF, INT2FIX(1), INT2FIX(0));
|
||||||
ADD_INSN1(ret, &dummy_line_node, setn, INT2FIX(orig_argc + 2));
|
PUSH_INSN1(ret, location, setn, INT2FIX(orig_argc + 2));
|
||||||
PM_POP;
|
PUSH_INSN(ret, location, pop);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ADD_INSN1(ret, &dummy_line_node, setn, INT2FIX(orig_argc + 1));
|
PUSH_INSN1(ret, location, setn, INT2FIX(orig_argc + 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((flags & VM_CALL_KW_SPLAT) && (flags & VM_CALL_ARGS_BLOCKARG) && !(flags & VM_CALL_KW_SPLAT_MUT)) {
|
if ((flags & VM_CALL_KW_SPLAT) && (flags & VM_CALL_ARGS_BLOCKARG) && !(flags & VM_CALL_KW_SPLAT_MUT)) {
|
||||||
ADD_INSN(ret, &dummy_line_node, splatkw);
|
PUSH_INSN(ret, location, splatkw);
|
||||||
}
|
}
|
||||||
|
|
||||||
ADD_SEND_R(ret, &dummy_line_node, method_id, INT2FIX(orig_argc), block_iseq, INT2FIX(flags), kw_arg);
|
PUSH_SEND_R(ret, location, method_id, INT2FIX(orig_argc), block_iseq, INT2FIX(flags), kw_arg);
|
||||||
|
|
||||||
if (PM_NODE_FLAG_P(call_node, PM_CALL_NODE_FLAGS_SAFE_NAVIGATION)) {
|
if (PM_NODE_FLAG_P(call_node, PM_CALL_NODE_FLAGS_SAFE_NAVIGATION)) {
|
||||||
ADD_INSNL(ret, &dummy_line_node, jump, end_label);
|
PUSH_INSNL(ret, location, jump, end_label);
|
||||||
ADD_LABEL(ret, else_label);
|
PUSH_LABEL(ret, else_label);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PM_NODE_FLAG_P(call_node, PM_CALL_NODE_FLAGS_SAFE_NAVIGATION) || (block_iseq && ISEQ_BODY(block_iseq)->catch_table)) {
|
if (PM_NODE_FLAG_P(call_node, PM_CALL_NODE_FLAGS_SAFE_NAVIGATION) || (block_iseq && ISEQ_BODY(block_iseq)->catch_table)) {
|
||||||
ADD_LABEL(ret, end_label);
|
PUSH_LABEL(ret, end_label);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PM_NODE_FLAG_P(call_node, PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE)) {
|
if (PM_NODE_FLAG_P(call_node, PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE) && !popped) {
|
||||||
PM_POP_UNLESS_POPPED;
|
PUSH_INSN(ret, location, pop);
|
||||||
}
|
}
|
||||||
|
|
||||||
PM_POP_IF_POPPED;
|
if (popped) PUSH_INSN(ret, location, pop);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is exactly the same as add_ensure_iseq, except it compiled
|
// This is exactly the same as add_ensure_iseq, except it compiled
|
||||||
@ -3621,8 +3609,8 @@ pm_compile_multi_target_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR
|
|||||||
static void
|
static void
|
||||||
pm_compile_target_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const parents, LINK_ANCHOR *const writes, LINK_ANCHOR *const cleanup, pm_scope_node_t *scope_node, pm_multi_target_state_t *state)
|
pm_compile_target_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const parents, LINK_ANCHOR *const writes, LINK_ANCHOR *const cleanup, pm_scope_node_t *scope_node, pm_multi_target_state_t *state)
|
||||||
{
|
{
|
||||||
int lineno = pm_node_line_number(scope_node->parser, node);
|
const pm_line_column_t location = pm_newline_list_line_column(&scope_node->parser->newline_list, node->location.start, scope_node->parser->start_line);
|
||||||
NODE dummy_line_node = generate_dummy_line_node(lineno, lineno);
|
NODE dummy_line_node = generate_dummy_line_node(location.line, location.column);
|
||||||
|
|
||||||
switch (PM_NODE_TYPE(node)) {
|
switch (PM_NODE_TYPE(node)) {
|
||||||
case PM_LOCAL_VARIABLE_TARGET_NODE: {
|
case PM_LOCAL_VARIABLE_TARGET_NODE: {
|
||||||
@ -3631,7 +3619,7 @@ pm_compile_target_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *cons
|
|||||||
//
|
//
|
||||||
// for i in []; end
|
// for i in []; end
|
||||||
//
|
//
|
||||||
pm_local_variable_target_node_t *cast = (pm_local_variable_target_node_t *) node;
|
const pm_local_variable_target_node_t *cast = (const pm_local_variable_target_node_t *) node;
|
||||||
pm_local_index_t index = pm_lookup_local_index(iseq, scope_node, cast->name, cast->depth);
|
pm_local_index_t index = pm_lookup_local_index(iseq, scope_node, cast->name, cast->depth);
|
||||||
|
|
||||||
ADD_SETLOCAL(writes, &dummy_line_node, index.index, index.level);
|
ADD_SETLOCAL(writes, &dummy_line_node, index.index, index.level);
|
||||||
@ -3643,10 +3631,10 @@ pm_compile_target_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *cons
|
|||||||
//
|
//
|
||||||
// for @@i in []; end
|
// for @@i in []; end
|
||||||
//
|
//
|
||||||
pm_class_variable_target_node_t *cast = (pm_class_variable_target_node_t *) node;
|
const pm_class_variable_target_node_t *cast = (const pm_class_variable_target_node_t *) node;
|
||||||
ID name = pm_constant_id_lookup(scope_node, cast->name);
|
ID name = pm_constant_id_lookup(scope_node, cast->name);
|
||||||
|
|
||||||
ADD_INSN2(writes, &dummy_line_node, setclassvariable, ID2SYM(name), get_cvar_ic_value(iseq, name));
|
PUSH_INSN2(writes, location, setclassvariable, ID2SYM(name), get_cvar_ic_value(iseq, name));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PM_CONSTANT_TARGET_NODE: {
|
case PM_CONSTANT_TARGET_NODE: {
|
||||||
@ -3655,11 +3643,11 @@ pm_compile_target_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *cons
|
|||||||
//
|
//
|
||||||
// for I in []; end
|
// for I in []; end
|
||||||
//
|
//
|
||||||
pm_constant_target_node_t *cast = (pm_constant_target_node_t *) node;
|
const pm_constant_target_node_t *cast = (const pm_constant_target_node_t *) node;
|
||||||
ID name = pm_constant_id_lookup(scope_node, cast->name);
|
ID name = pm_constant_id_lookup(scope_node, cast->name);
|
||||||
|
|
||||||
ADD_INSN1(writes, &dummy_line_node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_CONST_BASE));
|
PUSH_INSN1(writes, location, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_CONST_BASE));
|
||||||
ADD_INSN1(writes, &dummy_line_node, setconstant, ID2SYM(name));
|
PUSH_INSN1(writes, location, setconstant, ID2SYM(name));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PM_GLOBAL_VARIABLE_TARGET_NODE: {
|
case PM_GLOBAL_VARIABLE_TARGET_NODE: {
|
||||||
@ -3668,10 +3656,10 @@ pm_compile_target_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *cons
|
|||||||
//
|
//
|
||||||
// for $i in []; end
|
// for $i in []; end
|
||||||
//
|
//
|
||||||
pm_global_variable_target_node_t *cast = (pm_global_variable_target_node_t *) node;
|
const pm_global_variable_target_node_t *cast = (const pm_global_variable_target_node_t *) node;
|
||||||
ID name = pm_constant_id_lookup(scope_node, cast->name);
|
ID name = pm_constant_id_lookup(scope_node, cast->name);
|
||||||
|
|
||||||
ADD_INSN1(writes, &dummy_line_node, setglobal, ID2SYM(name));
|
PUSH_INSN1(writes, location, setglobal, ID2SYM(name));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PM_INSTANCE_VARIABLE_TARGET_NODE: {
|
case PM_INSTANCE_VARIABLE_TARGET_NODE: {
|
||||||
@ -3680,10 +3668,10 @@ pm_compile_target_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *cons
|
|||||||
//
|
//
|
||||||
// for @i in []; end
|
// for @i in []; end
|
||||||
//
|
//
|
||||||
pm_instance_variable_target_node_t *cast = (pm_instance_variable_target_node_t *) node;
|
const pm_instance_variable_target_node_t *cast = (const pm_instance_variable_target_node_t *) node;
|
||||||
ID name = pm_constant_id_lookup(scope_node, cast->name);
|
ID name = pm_constant_id_lookup(scope_node, cast->name);
|
||||||
|
|
||||||
ADD_INSN2(writes, &dummy_line_node, setinstancevariable, ID2SYM(name), get_ivar_ic_value(iseq, name));
|
PUSH_INSN2(writes, location, setinstancevariable, ID2SYM(name), get_ivar_ic_value(iseq, name));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PM_CONSTANT_PATH_TARGET_NODE: {
|
case PM_CONSTANT_PATH_TARGET_NODE: {
|
||||||
@ -3702,21 +3690,21 @@ pm_compile_target_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *cons
|
|||||||
pm_compile_node(iseq, cast->parent, parents, false, scope_node);
|
pm_compile_node(iseq, cast->parent, parents, false, scope_node);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ADD_INSN1(parents, &dummy_line_node, putobject, rb_cObject);
|
PUSH_INSN1(parents, location, putobject, rb_cObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state == NULL) {
|
if (state == NULL) {
|
||||||
ADD_INSN(writes, &dummy_line_node, swap);
|
PUSH_INSN(writes, location, swap);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ADD_INSN1(writes, &dummy_line_node, topn, INT2FIX(1));
|
PUSH_INSN1(writes, location, topn, INT2FIX(1));
|
||||||
pm_multi_target_state_push(state, (INSN *) LAST_ELEMENT(writes), 1);
|
pm_multi_target_state_push(state, (INSN *) LAST_ELEMENT(writes), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ADD_INSN1(writes, &dummy_line_node, setconstant, ID2SYM(name));
|
PUSH_INSN1(writes, location, setconstant, ID2SYM(name));
|
||||||
|
|
||||||
if (state != NULL) {
|
if (state != NULL) {
|
||||||
ADD_INSN(cleanup, &dummy_line_node, pop);
|
PUSH_INSN(cleanup, location, pop);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -3736,19 +3724,19 @@ pm_compile_target_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *cons
|
|||||||
pm_compile_node(iseq, cast->receiver, parents, false, scope_node);
|
pm_compile_node(iseq, cast->receiver, parents, false, scope_node);
|
||||||
|
|
||||||
if (state != NULL) {
|
if (state != NULL) {
|
||||||
ADD_INSN1(writes, &dummy_line_node, topn, INT2FIX(1));
|
PUSH_INSN1(writes, location, topn, INT2FIX(1));
|
||||||
pm_multi_target_state_push(state, (INSN *) LAST_ELEMENT(writes), 1);
|
pm_multi_target_state_push(state, (INSN *) LAST_ELEMENT(writes), 1);
|
||||||
ADD_INSN(writes, &dummy_line_node, swap);
|
PUSH_INSN(writes, location, swap);
|
||||||
}
|
}
|
||||||
|
|
||||||
int flags = VM_CALL_ARGS_SIMPLE;
|
int flags = VM_CALL_ARGS_SIMPLE;
|
||||||
if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY)) flags |= VM_CALL_FCALL;
|
if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY)) flags |= VM_CALL_FCALL;
|
||||||
|
|
||||||
ADD_SEND_WITH_FLAG(writes, &dummy_line_node, method_id, INT2FIX(1), INT2FIX(flags));
|
PUSH_SEND_WITH_FLAG(writes, location, method_id, INT2FIX(1), INT2FIX(flags));
|
||||||
ADD_INSN(writes, &dummy_line_node, pop);
|
PUSH_INSN(writes, location, pop);
|
||||||
|
|
||||||
if (state != NULL) {
|
if (state != NULL) {
|
||||||
ADD_INSN(cleanup, &dummy_line_node, pop);
|
PUSH_INSN(cleanup, location, pop);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -3769,20 +3757,20 @@ pm_compile_target_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *cons
|
|||||||
|
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
struct rb_callinfo_kwarg *kwargs = NULL;
|
struct rb_callinfo_kwarg *kwargs = NULL;
|
||||||
int argc = pm_setup_args(cast->arguments, cast->block, &flags, &kwargs, iseq, parents, scope_node, dummy_line_node);
|
int argc = pm_setup_args(cast->arguments, cast->block, &flags, &kwargs, iseq, parents, scope_node, &location);
|
||||||
|
|
||||||
if (state != NULL) {
|
if (state != NULL) {
|
||||||
ADD_INSN1(writes, &dummy_line_node, topn, INT2FIX(argc + 1));
|
PUSH_INSN1(writes, location, topn, INT2FIX(argc + 1));
|
||||||
pm_multi_target_state_push(state, (INSN *) LAST_ELEMENT(writes), argc + 1);
|
pm_multi_target_state_push(state, (INSN *) LAST_ELEMENT(writes), argc + 1);
|
||||||
|
|
||||||
if (argc == 0) {
|
if (argc == 0) {
|
||||||
ADD_INSN(writes, &dummy_line_node, swap);
|
PUSH_INSN(writes, location, swap);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for (int index = 0; index < argc; index++) {
|
for (int index = 0; index < argc; index++) {
|
||||||
ADD_INSN1(writes, &dummy_line_node, topn, INT2FIX(argc + 1));
|
PUSH_INSN1(writes, location, topn, INT2FIX(argc + 1));
|
||||||
}
|
}
|
||||||
ADD_INSN1(writes, &dummy_line_node, topn, INT2FIX(argc + 1));
|
PUSH_INSN1(writes, location, topn, INT2FIX(argc + 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3793,20 +3781,20 @@ pm_compile_target_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *cons
|
|||||||
int ci_argc = argc + 1;
|
int ci_argc = argc + 1;
|
||||||
if (flags & VM_CALL_ARGS_SPLAT) {
|
if (flags & VM_CALL_ARGS_SPLAT) {
|
||||||
ci_argc--;
|
ci_argc--;
|
||||||
ADD_INSN1(writes, &dummy_line_node, newarray, INT2FIX(1));
|
PUSH_INSN1(writes, location, newarray, INT2FIX(1));
|
||||||
ADD_INSN(writes, &dummy_line_node, concatarray);
|
PUSH_INSN(writes, location, concatarray);
|
||||||
}
|
}
|
||||||
|
|
||||||
ADD_SEND_R(writes, &dummy_line_node, idASET, INT2NUM(ci_argc), NULL, INT2FIX(flags), kwargs);
|
PUSH_SEND_R(writes, location, idASET, INT2NUM(ci_argc), NULL, INT2FIX(flags), kwargs);
|
||||||
ADD_INSN(writes, &dummy_line_node, pop);
|
PUSH_INSN(writes, location, pop);
|
||||||
|
|
||||||
if (state != NULL) {
|
if (state != NULL) {
|
||||||
if (argc != 0) {
|
if (argc != 0) {
|
||||||
ADD_INSN(writes, &dummy_line_node, pop);
|
PUSH_INSN(writes, location, pop);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int index = 0; index < argc + 1; index++) {
|
for (int index = 0; index < argc + 1; index++) {
|
||||||
ADD_INSN(cleanup, &dummy_line_node, pop);
|
PUSH_INSN(cleanup, location, pop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6059,7 +6047,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
|
|||||||
// In this case a method call/local variable read is implied by virtue
|
// In this case a method call/local variable read is implied by virtue
|
||||||
// of the missing value. To compile these nodes, we simply compile the
|
// of the missing value. To compile these nodes, we simply compile the
|
||||||
// value that is implied, which is helpfully supplied by the parser.
|
// value that is implied, which is helpfully supplied by the parser.
|
||||||
pm_implicit_node_t *cast = (pm_implicit_node_t *)node;
|
const pm_implicit_node_t *cast = (const pm_implicit_node_t *)node;
|
||||||
PM_COMPILE(cast->value);
|
PM_COMPILE(cast->value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -6069,17 +6057,25 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
|
|||||||
rb_bug("Should not ever enter an in node directly");
|
rb_bug("Should not ever enter an in node directly");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case PM_INDEX_OPERATOR_WRITE_NODE:
|
case PM_INDEX_OPERATOR_WRITE_NODE: {
|
||||||
pm_compile_index_operator_write_node(scope_node, (const pm_index_operator_write_node_t *) node, iseq, ret, popped);
|
// foo[bar] += baz
|
||||||
|
// ^^^^^^^^^^^^^^^
|
||||||
|
const pm_index_operator_write_node_t *cast = (const pm_index_operator_write_node_t *) node;
|
||||||
|
pm_compile_index_operator_write_node(iseq, cast, &location, ret, popped, scope_node);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
case PM_INDEX_AND_WRITE_NODE: {
|
case PM_INDEX_AND_WRITE_NODE: {
|
||||||
|
// foo[bar] &&= baz
|
||||||
|
// ^^^^^^^^^^^^^^^^
|
||||||
const pm_index_and_write_node_t *cast = (const pm_index_and_write_node_t *) node;
|
const pm_index_and_write_node_t *cast = (const pm_index_and_write_node_t *) node;
|
||||||
pm_compile_index_control_flow_write_node(scope_node, node, cast->receiver, cast->arguments, cast->block, cast->value, iseq, ret, popped);
|
pm_compile_index_control_flow_write_node(iseq, node, cast->receiver, cast->arguments, cast->block, cast->value, &location, ret, popped, scope_node);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case PM_INDEX_OR_WRITE_NODE: {
|
case PM_INDEX_OR_WRITE_NODE: {
|
||||||
|
// foo[bar] ||= baz
|
||||||
|
// ^^^^^^^^^^^^^^^^
|
||||||
const pm_index_or_write_node_t *cast = (const pm_index_or_write_node_t *) node;
|
const pm_index_or_write_node_t *cast = (const pm_index_or_write_node_t *) node;
|
||||||
pm_compile_index_control_flow_write_node(scope_node, node, cast->receiver, cast->arguments, cast->block, cast->value, iseq, ret, popped);
|
pm_compile_index_control_flow_write_node(iseq, node, cast->receiver, cast->arguments, cast->block, cast->value, &location, ret, popped, scope_node);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case PM_INSTANCE_VARIABLE_AND_WRITE_NODE: {
|
case PM_INSTANCE_VARIABLE_AND_WRITE_NODE: {
|
||||||
@ -8254,7 +8250,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
|
|||||||
|
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
struct rb_callinfo_kwarg *keywords = NULL;
|
struct rb_callinfo_kwarg *keywords = NULL;
|
||||||
int argc = pm_setup_args(cast->arguments, cast->block, &flags, &keywords, iseq, ret, scope_node, dummy_line_node);
|
int argc = pm_setup_args(cast->arguments, cast->block, &flags, &keywords, iseq, ret, scope_node, &location);
|
||||||
flags |= VM_CALL_SUPER | VM_CALL_FCALL;
|
flags |= VM_CALL_SUPER | VM_CALL_FCALL;
|
||||||
|
|
||||||
const rb_iseq_t *parent_block = ISEQ_COMPILE_DATA(iseq)->current_block;
|
const rb_iseq_t *parent_block = ISEQ_COMPILE_DATA(iseq)->current_block;
|
||||||
@ -8383,7 +8379,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
|
|||||||
struct rb_callinfo_kwarg *keywords = NULL;
|
struct rb_callinfo_kwarg *keywords = NULL;
|
||||||
|
|
||||||
if (cast->arguments) {
|
if (cast->arguments) {
|
||||||
argc = pm_setup_args(cast->arguments, NULL, &flags, &keywords, iseq, ret, scope_node, dummy_line_node);
|
argc = pm_setup_args(cast->arguments, NULL, &flags, &keywords, iseq, ret, scope_node, &location);
|
||||||
}
|
}
|
||||||
|
|
||||||
PUSH_INSN1(ret, location, invokeblock, new_callinfo(iseq, 0, argc, flags, keywords, FALSE));
|
PUSH_INSN1(ret, location, invokeblock, new_callinfo(iseq, 0, argc, flags, keywords, FALSE));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user