aboutsummaryrefslogtreecommitdiffstats
path: root/compile.c
diff options
context:
space:
mode:
authoryui-knk <spiketeika@gmail.com>2023-10-01 12:51:25 +0900
committerYuichiro Kaneko <spiketeika@gmail.com>2023-10-02 09:41:45 +0900
commitb1131851e085a4d1e5b56599adea1b851be97563 (patch)
treede5584e75370d1a4da9552c6c7f927d5f5077580 /compile.c
parentfdc329ea6f5bce922e95645a0c2118cfd3e1cdea (diff)
downloadruby-b1131851e085a4d1e5b56599adea1b851be97563.tar.gz
Correctly casting node for accessing nd_recv, nd_mid and nd_args in compile.c
Diffstat (limited to 'compile.c')
-rw-r--r--compile.c125
1 files changed, 96 insertions, 29 deletions
diff --git a/compile.c b/compile.c
index a411e8d6f7..40aedde788 100644
--- a/compile.c
+++ b/compile.c
@@ -721,6 +721,73 @@ validate_labels(rb_iseq_t *iseq, st_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
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
private_recv_p(const NODE *node)
{
- if (nd_type_p(RNODE_CALL(node)->nd_recv, NODE_SELF)) {
- NODE *self = RNODE_CALL(node)->nd_recv;
+ if (nd_type_p(get_nd_recv(node), NODE_SELF)) {
+ NODE *self = get_nd_recv(node);
return RNODE_SELF(self)->nd_state != 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_ATTRASGN && !private_recv_p(node)));
- if (RNODE_CALL(node)->nd_args || explicit_receiver) {
+ if (get_nd_args(node) || explicit_receiver) {
if (!lfinish[1]) {
lfinish[1] = NEW_LABEL(line);
}
@@ -5485,31 +5552,31 @@ defined_expr0(rb_iseq_t *iseq, LINK_ANCHOR *const ret,
lfinish[2] = NEW_LABEL(line);
}
}
- if (RNODE_CALL(node)->nd_args) {
- defined_expr0(iseq, ret, RNODE_CALL(node)->nd_args, lfinish, Qfalse, false);
+ if (get_nd_args(node)) {
+ defined_expr0(iseq, ret, get_nd_args(node), lfinish, Qfalse, false);
ADD_INSNL(ret, line_node, branchunless, lfinish[1]);
}
if (explicit_receiver) {
- defined_expr0(iseq, ret, RNODE_CALL(node)->nd_recv, lfinish, Qfalse, true);
- switch (nd_type(RNODE_CALL(node)->nd_recv)) {
+ defined_expr0(iseq, ret, get_nd_recv(node), lfinish, Qfalse, true);
+ switch (nd_type(get_nd_recv(node))) {
case NODE_CALL:
case NODE_OPCALL:
case NODE_VCALL:
case NODE_FCALL:
case NODE_ATTRASGN:
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;
default:
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;
}
if (keep_result) {
ADD_INSN(ret, line_node, dup);
}
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 {
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_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;
}
@@ -8018,13 +8085,13 @@ compile_call_precheck_freeze(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE
/* optimization shortcut
* "literal".freeze -> opt_str_freeze("literal")
*/
- if (RNODE_CALL(node)->nd_recv && nd_type_p(RNODE_CALL(node)->nd_recv, NODE_STR) &&
- (RNODE_CALL(node)->nd_mid == idFreeze || RNODE_CALL(node)->nd_mid == idUMinus) &&
- RNODE_CALL(node)->nd_args == NULL &&
+ if (get_nd_recv(node) && nd_type_p(get_nd_recv(node), NODE_STR) &&
+ (get_nd_mid(node) == idFreeze || get_nd_mid(node) == idUMinus) &&
+ get_nd_args(node) == NULL &&
ISEQ_COMPILE_DATA(iseq)->current_block == NULL &&
ISEQ_COMPILE_DATA(iseq)->option->specialized_instruction) {
- VALUE str = rb_fstring(RNODE_STR(RNODE_CALL(node)->nd_recv)->nd_lit);
- if (RNODE_CALL(node)->nd_mid == idUMinus) {
+ VALUE str = rb_fstring(RNODE_STR(get_nd_recv(node))->nd_lit);
+ if (get_nd_mid(node) == idUMinus) {
ADD_INSN2(ret, line_node, opt_str_uminus, str,
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
* obj["literal"] -> opt_aref_with(obj, "literal")
*/
- if (RNODE_CALL(node)->nd_mid == idAREF && !private_recv_p(node) && RNODE_CALL(node)->nd_args &&
- nd_type_p(RNODE_CALL(node)->nd_args, NODE_LIST) && RNODE_LIST(RNODE_CALL(node)->nd_args)->as.nd_alen == 1 &&
- nd_type_p(RNODE_LIST(RNODE_CALL(node)->nd_args)->nd_head, NODE_STR) &&
+ if (get_nd_mid(node) == idAREF && !private_recv_p(node) && get_nd_args(node) &&
+ nd_type_p(get_nd_args(node), NODE_LIST) && RNODE_LIST(get_nd_args(node))->as.nd_alen == 1 &&
+ nd_type_p(RNODE_LIST(get_nd_args(node))->nd_head, NODE_STR) &&
ISEQ_COMPILE_DATA(iseq)->current_block == NULL &&
!ISEQ_COMPILE_DATA(iseq)->option->frozen_string_literal &&
ISEQ_COMPILE_DATA(iseq)->option->specialized_instruction) {
- VALUE str = rb_fstring(RNODE_STR(RNODE_LIST(RNODE_CALL(node)->nd_args)->nd_head)->nd_lit);
- CHECK(COMPILE(ret, "recv", RNODE_CALL(node)->nd_recv));
+ VALUE str = rb_fstring(RNODE_STR(RNODE_LIST(get_nd_args(node))->nd_head)->nd_lit);
+ CHECK(COMPILE(ret, "recv", get_nd_recv(node)));
ADD_INSN2(ret, line_node, opt_aref_with, str,
new_callinfo(iseq, idAREF, 1, 0, NULL, FALSE));
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,
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) {
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(args);
- ID mid = RNODE_CALL(node)->nd_mid;
+ ID mid = get_nd_mid(node);
VALUE argc;
unsigned int flag = 0;
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;
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);
}
@@ -8511,16 +8578,16 @@ compile_call(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, co
int idx, level;
if (mid == idCall &&
- nd_type_p(RNODE_CALL(node)->nd_recv, NODE_LVAR) &&
- iseq_block_param_id_p(iseq, RNODE_LVAR(RNODE_CALL(node)->nd_recv)->nd_vid, &idx, &level)) {
- ADD_INSN2(recv, RNODE_CALL(node)->nd_recv, getblockparamproxy, INT2FIX(idx + VM_ENV_DATA_SIZE - 1), INT2FIX(level));
+ nd_type_p(get_nd_recv(node), NODE_LVAR) &&
+ iseq_block_param_id_p(iseq, RNODE_LVAR(get_nd_recv(node))->nd_vid, &idx, &level)) {
+ ADD_INSN2(recv, get_nd_recv(node), getblockparamproxy, INT2FIX(idx + VM_ENV_DATA_SIZE - 1), INT2FIX(level));
}
else if (private_recv_p(node)) {
ADD_INSN(recv, node, putself);
flag |= VM_CALL_FCALL;
}
else {
- CHECK(COMPILE(recv, "recv", RNODE_CALL(node)->nd_recv));
+ CHECK(COMPILE(recv, "recv", get_nd_recv(node)));
}
if (type == NODE_QCALL) {
@@ -8534,7 +8601,7 @@ compile_call(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, co
/* args */
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));
}
else {