Correctly casting node for accessing nd_recv, nd_mid and nd_args in compile.c
This commit is contained in:
parent
fdc329ea6f
commit
b1131851e0
125
compile.c
125
compile.c
@ -721,6 +721,73 @@ validate_labels(rb_iseq_t *iseq, st_table *labels_table)
|
|||||||
st_free_table(labels_table);
|
st_free_table(labels_table);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NODE *
|
||||||
|
get_nd_recv(const NODE *node)
|
||||||
|
{
|
||||||
|
switch (nd_type(node)) {
|
||||||
|
case NODE_CALL:
|
||||||
|
return RNODE_CALL(node)->nd_recv;
|
||||||
|
case NODE_OPCALL:
|
||||||
|
return RNODE_OPCALL(node)->nd_recv;
|
||||||
|
case NODE_FCALL:
|
||||||
|
return 0;
|
||||||
|
case NODE_QCALL:
|
||||||
|
return RNODE_QCALL(node)->nd_recv;
|
||||||
|
case NODE_VCALL:
|
||||||
|
return 0;
|
||||||
|
case NODE_ATTRASGN:
|
||||||
|
return RNODE_ATTRASGN(node)->nd_recv;
|
||||||
|
case NODE_OP_ASGN1:
|
||||||
|
return RNODE_OP_ASGN1(node)->nd_recv;
|
||||||
|
case NODE_OP_ASGN2:
|
||||||
|
return RNODE_OP_ASGN2(node)->nd_recv;
|
||||||
|
default:
|
||||||
|
rb_bug("unexpected node: %s", ruby_node_name(nd_type(node)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static ID
|
||||||
|
get_nd_mid(const NODE *node)
|
||||||
|
{
|
||||||
|
switch (nd_type(node)) {
|
||||||
|
case NODE_CALL:
|
||||||
|
return RNODE_CALL(node)->nd_mid;
|
||||||
|
case NODE_OPCALL:
|
||||||
|
return RNODE_OPCALL(node)->nd_mid;
|
||||||
|
case NODE_FCALL:
|
||||||
|
return RNODE_FCALL(node)->nd_mid;
|
||||||
|
case NODE_QCALL:
|
||||||
|
return RNODE_QCALL(node)->nd_mid;
|
||||||
|
case NODE_VCALL:
|
||||||
|
return RNODE_VCALL(node)->nd_mid;
|
||||||
|
case NODE_ATTRASGN:
|
||||||
|
return RNODE_ATTRASGN(node)->nd_mid;
|
||||||
|
default:
|
||||||
|
rb_bug("unexpected node: %s", ruby_node_name(nd_type(node)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static NODE *
|
||||||
|
get_nd_args(const NODE *node)
|
||||||
|
{
|
||||||
|
switch (nd_type(node)) {
|
||||||
|
case NODE_CALL:
|
||||||
|
return RNODE_CALL(node)->nd_args;
|
||||||
|
case NODE_OPCALL:
|
||||||
|
return RNODE_OPCALL(node)->nd_args;
|
||||||
|
case NODE_FCALL:
|
||||||
|
return RNODE_FCALL(node)->nd_args;
|
||||||
|
case NODE_QCALL:
|
||||||
|
return RNODE_QCALL(node)->nd_args;
|
||||||
|
case NODE_VCALL:
|
||||||
|
return 0;
|
||||||
|
case NODE_ATTRASGN:
|
||||||
|
return RNODE_ATTRASGN(node)->nd_args;
|
||||||
|
default:
|
||||||
|
rb_bug("unexpected node: %s", ruby_node_name(nd_type(node)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
rb_iseq_compile_callback(rb_iseq_t *iseq, const struct rb_iseq_new_with_callback_callback_func * ifunc)
|
rb_iseq_compile_callback(rb_iseq_t *iseq, const struct rb_iseq_new_with_callback_callback_func * ifunc)
|
||||||
{
|
{
|
||||||
@ -5353,8 +5420,8 @@ compile_cpath(LINK_ANCHOR *const ret, rb_iseq_t *iseq, const NODE *cpath)
|
|||||||
static inline int
|
static inline int
|
||||||
private_recv_p(const NODE *node)
|
private_recv_p(const NODE *node)
|
||||||
{
|
{
|
||||||
if (nd_type_p(RNODE_CALL(node)->nd_recv, NODE_SELF)) {
|
if (nd_type_p(get_nd_recv(node), NODE_SELF)) {
|
||||||
NODE *self = RNODE_CALL(node)->nd_recv;
|
NODE *self = get_nd_recv(node);
|
||||||
return RNODE_SELF(self)->nd_state != 0;
|
return RNODE_SELF(self)->nd_state != 0;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -5477,7 +5544,7 @@ defined_expr0(rb_iseq_t *iseq, LINK_ANCHOR *const ret,
|
|||||||
(type == NODE_CALL || type == NODE_OPCALL ||
|
(type == NODE_CALL || type == NODE_OPCALL ||
|
||||||
(type == NODE_ATTRASGN && !private_recv_p(node)));
|
(type == NODE_ATTRASGN && !private_recv_p(node)));
|
||||||
|
|
||||||
if (RNODE_CALL(node)->nd_args || explicit_receiver) {
|
if (get_nd_args(node) || explicit_receiver) {
|
||||||
if (!lfinish[1]) {
|
if (!lfinish[1]) {
|
||||||
lfinish[1] = NEW_LABEL(line);
|
lfinish[1] = NEW_LABEL(line);
|
||||||
}
|
}
|
||||||
@ -5485,31 +5552,31 @@ defined_expr0(rb_iseq_t *iseq, LINK_ANCHOR *const ret,
|
|||||||
lfinish[2] = NEW_LABEL(line);
|
lfinish[2] = NEW_LABEL(line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (RNODE_CALL(node)->nd_args) {
|
if (get_nd_args(node)) {
|
||||||
defined_expr0(iseq, ret, RNODE_CALL(node)->nd_args, lfinish, Qfalse, false);
|
defined_expr0(iseq, ret, get_nd_args(node), lfinish, Qfalse, false);
|
||||||
ADD_INSNL(ret, line_node, branchunless, lfinish[1]);
|
ADD_INSNL(ret, line_node, branchunless, lfinish[1]);
|
||||||
}
|
}
|
||||||
if (explicit_receiver) {
|
if (explicit_receiver) {
|
||||||
defined_expr0(iseq, ret, RNODE_CALL(node)->nd_recv, lfinish, Qfalse, true);
|
defined_expr0(iseq, ret, get_nd_recv(node), lfinish, Qfalse, true);
|
||||||
switch (nd_type(RNODE_CALL(node)->nd_recv)) {
|
switch (nd_type(get_nd_recv(node))) {
|
||||||
case NODE_CALL:
|
case NODE_CALL:
|
||||||
case NODE_OPCALL:
|
case NODE_OPCALL:
|
||||||
case NODE_VCALL:
|
case NODE_VCALL:
|
||||||
case NODE_FCALL:
|
case NODE_FCALL:
|
||||||
case NODE_ATTRASGN:
|
case NODE_ATTRASGN:
|
||||||
ADD_INSNL(ret, line_node, branchunless, lfinish[2]);
|
ADD_INSNL(ret, line_node, branchunless, lfinish[2]);
|
||||||
compile_call(iseq, ret, RNODE_CALL(node)->nd_recv, nd_type(RNODE_CALL(node)->nd_recv), line_node, 0, true);
|
compile_call(iseq, ret, get_nd_recv(node), nd_type(get_nd_recv(node)), line_node, 0, true);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ADD_INSNL(ret, line_node, branchunless, lfinish[1]);
|
ADD_INSNL(ret, line_node, branchunless, lfinish[1]);
|
||||||
NO_CHECK(COMPILE(ret, "defined/recv", RNODE_CALL(node)->nd_recv));
|
NO_CHECK(COMPILE(ret, "defined/recv", get_nd_recv(node)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (keep_result) {
|
if (keep_result) {
|
||||||
ADD_INSN(ret, line_node, dup);
|
ADD_INSN(ret, line_node, dup);
|
||||||
}
|
}
|
||||||
ADD_INSN3(ret, line_node, defined, INT2FIX(DEFINED_METHOD),
|
ADD_INSN3(ret, line_node, defined, INT2FIX(DEFINED_METHOD),
|
||||||
ID2SYM(RNODE_CALL(node)->nd_mid), PUSH_VAL(DEFINED_METHOD));
|
ID2SYM(get_nd_mid(node)), PUSH_VAL(DEFINED_METHOD));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ADD_INSN(ret, line_node, putself);
|
ADD_INSN(ret, line_node, putself);
|
||||||
@ -5517,7 +5584,7 @@ defined_expr0(rb_iseq_t *iseq, LINK_ANCHOR *const ret,
|
|||||||
ADD_INSN(ret, line_node, dup);
|
ADD_INSN(ret, line_node, dup);
|
||||||
}
|
}
|
||||||
ADD_INSN3(ret, line_node, defined, INT2FIX(DEFINED_FUNC),
|
ADD_INSN3(ret, line_node, defined, INT2FIX(DEFINED_FUNC),
|
||||||
ID2SYM(RNODE_CALL(node)->nd_mid), PUSH_VAL(DEFINED_METHOD));
|
ID2SYM(get_nd_mid(node)), PUSH_VAL(DEFINED_METHOD));
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -8018,13 +8085,13 @@ compile_call_precheck_freeze(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE
|
|||||||
/* optimization shortcut
|
/* optimization shortcut
|
||||||
* "literal".freeze -> opt_str_freeze("literal")
|
* "literal".freeze -> opt_str_freeze("literal")
|
||||||
*/
|
*/
|
||||||
if (RNODE_CALL(node)->nd_recv && nd_type_p(RNODE_CALL(node)->nd_recv, NODE_STR) &&
|
if (get_nd_recv(node) && nd_type_p(get_nd_recv(node), NODE_STR) &&
|
||||||
(RNODE_CALL(node)->nd_mid == idFreeze || RNODE_CALL(node)->nd_mid == idUMinus) &&
|
(get_nd_mid(node) == idFreeze || get_nd_mid(node) == idUMinus) &&
|
||||||
RNODE_CALL(node)->nd_args == NULL &&
|
get_nd_args(node) == NULL &&
|
||||||
ISEQ_COMPILE_DATA(iseq)->current_block == NULL &&
|
ISEQ_COMPILE_DATA(iseq)->current_block == NULL &&
|
||||||
ISEQ_COMPILE_DATA(iseq)->option->specialized_instruction) {
|
ISEQ_COMPILE_DATA(iseq)->option->specialized_instruction) {
|
||||||
VALUE str = rb_fstring(RNODE_STR(RNODE_CALL(node)->nd_recv)->nd_lit);
|
VALUE str = rb_fstring(RNODE_STR(get_nd_recv(node))->nd_lit);
|
||||||
if (RNODE_CALL(node)->nd_mid == idUMinus) {
|
if (get_nd_mid(node) == idUMinus) {
|
||||||
ADD_INSN2(ret, line_node, opt_str_uminus, str,
|
ADD_INSN2(ret, line_node, opt_str_uminus, str,
|
||||||
new_callinfo(iseq, idUMinus, 0, 0, NULL, FALSE));
|
new_callinfo(iseq, idUMinus, 0, 0, NULL, FALSE));
|
||||||
}
|
}
|
||||||
@ -8041,14 +8108,14 @@ compile_call_precheck_freeze(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE
|
|||||||
/* optimization shortcut
|
/* optimization shortcut
|
||||||
* obj["literal"] -> opt_aref_with(obj, "literal")
|
* obj["literal"] -> opt_aref_with(obj, "literal")
|
||||||
*/
|
*/
|
||||||
if (RNODE_CALL(node)->nd_mid == idAREF && !private_recv_p(node) && RNODE_CALL(node)->nd_args &&
|
if (get_nd_mid(node) == idAREF && !private_recv_p(node) && get_nd_args(node) &&
|
||||||
nd_type_p(RNODE_CALL(node)->nd_args, NODE_LIST) && RNODE_LIST(RNODE_CALL(node)->nd_args)->as.nd_alen == 1 &&
|
nd_type_p(get_nd_args(node), NODE_LIST) && RNODE_LIST(get_nd_args(node))->as.nd_alen == 1 &&
|
||||||
nd_type_p(RNODE_LIST(RNODE_CALL(node)->nd_args)->nd_head, NODE_STR) &&
|
nd_type_p(RNODE_LIST(get_nd_args(node))->nd_head, NODE_STR) &&
|
||||||
ISEQ_COMPILE_DATA(iseq)->current_block == NULL &&
|
ISEQ_COMPILE_DATA(iseq)->current_block == NULL &&
|
||||||
!ISEQ_COMPILE_DATA(iseq)->option->frozen_string_literal &&
|
!ISEQ_COMPILE_DATA(iseq)->option->frozen_string_literal &&
|
||||||
ISEQ_COMPILE_DATA(iseq)->option->specialized_instruction) {
|
ISEQ_COMPILE_DATA(iseq)->option->specialized_instruction) {
|
||||||
VALUE str = rb_fstring(RNODE_STR(RNODE_LIST(RNODE_CALL(node)->nd_args)->nd_head)->nd_lit);
|
VALUE str = rb_fstring(RNODE_STR(RNODE_LIST(get_nd_args(node))->nd_head)->nd_lit);
|
||||||
CHECK(COMPILE(ret, "recv", RNODE_CALL(node)->nd_recv));
|
CHECK(COMPILE(ret, "recv", get_nd_recv(node)));
|
||||||
ADD_INSN2(ret, line_node, opt_aref_with, str,
|
ADD_INSN2(ret, line_node, opt_aref_with, str,
|
||||||
new_callinfo(iseq, idAREF, 1, 0, NULL, FALSE));
|
new_callinfo(iseq, idAREF, 1, 0, NULL, FALSE));
|
||||||
RB_OBJ_WRITTEN(iseq, Qundef, str);
|
RB_OBJ_WRITTEN(iseq, Qundef, str);
|
||||||
@ -8319,7 +8386,7 @@ static int
|
|||||||
compile_builtin_function_call(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, const NODE *line_node, int popped,
|
compile_builtin_function_call(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, const NODE *line_node, int popped,
|
||||||
const rb_iseq_t *parent_block, LINK_ANCHOR *args, const char *builtin_func)
|
const rb_iseq_t *parent_block, LINK_ANCHOR *args, const char *builtin_func)
|
||||||
{
|
{
|
||||||
NODE *args_node = RNODE_QCALL(node)->nd_args;
|
NODE *args_node = get_nd_args(node);
|
||||||
|
|
||||||
if (parent_block != NULL) {
|
if (parent_block != NULL) {
|
||||||
COMPILE_ERROR(ERROR_ARGS_AT(line_node) "should not call builtins here.");
|
COMPILE_ERROR(ERROR_ARGS_AT(line_node) "should not call builtins here.");
|
||||||
@ -8422,7 +8489,7 @@ compile_call(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, co
|
|||||||
*/
|
*/
|
||||||
DECL_ANCHOR(recv);
|
DECL_ANCHOR(recv);
|
||||||
DECL_ANCHOR(args);
|
DECL_ANCHOR(args);
|
||||||
ID mid = RNODE_CALL(node)->nd_mid;
|
ID mid = get_nd_mid(node);
|
||||||
VALUE argc;
|
VALUE argc;
|
||||||
unsigned int flag = 0;
|
unsigned int flag = 0;
|
||||||
struct rb_callinfo_kwarg *keywords = NULL;
|
struct rb_callinfo_kwarg *keywords = NULL;
|
||||||
@ -8501,7 +8568,7 @@ compile_call(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, co
|
|||||||
|
|
||||||
const char *builtin_func;
|
const char *builtin_func;
|
||||||
if (UNLIKELY(iseq_has_builtin_function_table(iseq)) &&
|
if (UNLIKELY(iseq_has_builtin_function_table(iseq)) &&
|
||||||
(builtin_func = iseq_builtin_function_name(type, RNODE_CALL(node)->nd_recv, mid)) != NULL) {
|
(builtin_func = iseq_builtin_function_name(type, get_nd_recv(node), mid)) != NULL) {
|
||||||
return compile_builtin_function_call(iseq, ret, node, line_node, popped, parent_block, args, builtin_func);
|
return compile_builtin_function_call(iseq, ret, node, line_node, popped, parent_block, args, builtin_func);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8511,16 +8578,16 @@ compile_call(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, co
|
|||||||
int idx, level;
|
int idx, level;
|
||||||
|
|
||||||
if (mid == idCall &&
|
if (mid == idCall &&
|
||||||
nd_type_p(RNODE_CALL(node)->nd_recv, NODE_LVAR) &&
|
nd_type_p(get_nd_recv(node), NODE_LVAR) &&
|
||||||
iseq_block_param_id_p(iseq, RNODE_LVAR(RNODE_CALL(node)->nd_recv)->nd_vid, &idx, &level)) {
|
iseq_block_param_id_p(iseq, RNODE_LVAR(get_nd_recv(node))->nd_vid, &idx, &level)) {
|
||||||
ADD_INSN2(recv, RNODE_CALL(node)->nd_recv, getblockparamproxy, INT2FIX(idx + VM_ENV_DATA_SIZE - 1), INT2FIX(level));
|
ADD_INSN2(recv, get_nd_recv(node), getblockparamproxy, INT2FIX(idx + VM_ENV_DATA_SIZE - 1), INT2FIX(level));
|
||||||
}
|
}
|
||||||
else if (private_recv_p(node)) {
|
else if (private_recv_p(node)) {
|
||||||
ADD_INSN(recv, node, putself);
|
ADD_INSN(recv, node, putself);
|
||||||
flag |= VM_CALL_FCALL;
|
flag |= VM_CALL_FCALL;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
CHECK(COMPILE(recv, "recv", RNODE_CALL(node)->nd_recv));
|
CHECK(COMPILE(recv, "recv", get_nd_recv(node)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == NODE_QCALL) {
|
if (type == NODE_QCALL) {
|
||||||
@ -8534,7 +8601,7 @@ compile_call(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, co
|
|||||||
|
|
||||||
/* args */
|
/* args */
|
||||||
if (type != NODE_VCALL) {
|
if (type != NODE_VCALL) {
|
||||||
argc = setup_args(iseq, args, RNODE_CALL(node)->nd_args, &flag, &keywords);
|
argc = setup_args(iseq, args, get_nd_args(node), &flag, &keywords);
|
||||||
CHECK(!NIL_P(argc));
|
CHECK(!NIL_P(argc));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user