summaryrefslogtreecommitdiff
path: root/compile.c
diff options
context:
space:
mode:
authorNobuyoshi Nakada <nobu@ruby-lang.org>2017-03-12 12:55:43 +0900
committerNobuyoshi Nakada <nobu@ruby-lang.org>2021-09-01 15:19:08 +0900
commit6cf9f1719168dd4c07b423f419412bed5a2bbd56 (patch)
tree9e01a658d5ef0db6e582026c472960af38128dd1 /compile.c
parentd045d5f860192802b521af96309fd314156d8320 (diff)
Extract compile_op_log from iseq_compile_each0
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/4795
Diffstat (limited to 'compile.c')
-rw-r--r--compile.c85
1 files changed, 46 insertions, 39 deletions
diff --git a/compile.c b/compile.c
index 1b24c04ae0..3ca1fa3804 100644
--- a/compile.c
+++ b/compile.c
@@ -8435,6 +8435,50 @@ compile_op_cdecl(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node
return COMPILE_OK;
}
+static int
+compile_op_log(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int popped, const enum node_type type)
+{
+ const int line = nd_line(node);
+ LABEL *lfin = NEW_LABEL(line);
+ LABEL *lassign;
+
+ if (type == NODE_OP_ASGN_OR && nd_type(node->nd_head) != NODE_IVAR) {
+ LABEL *lfinish[2];
+ lfinish[0] = lfin;
+ lfinish[1] = 0;
+ defined_expr(iseq, ret, node->nd_head, lfinish, Qfalse);
+ lassign = lfinish[1];
+ if (!lassign) {
+ lassign = NEW_LABEL(line);
+ }
+ ADD_INSNL(ret, node, branchunless, lassign);
+ }
+ else {
+ lassign = NEW_LABEL(line);
+ }
+
+ CHECK(COMPILE(ret, "NODE_OP_ASGN_AND/OR#nd_head", node->nd_head));
+ ADD_INSN(ret, node, dup);
+
+ if (type == NODE_OP_ASGN_AND) {
+ ADD_INSNL(ret, node, branchunless, lfin);
+ }
+ else {
+ ADD_INSNL(ret, node, branchif, lfin);
+ }
+
+ ADD_INSN(ret, node, pop);
+ ADD_LABEL(ret, lassign);
+ CHECK(COMPILE(ret, "NODE_OP_ASGN_AND/OR#nd_value", node->nd_value));
+ ADD_LABEL(ret, lfin);
+
+ if (popped) {
+ /* we can apply more optimize */
+ ADD_INSN(ret, node, pop);
+ }
+ return COMPILE_OK;
+}
+
static int iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int popped);
/**
compile each node
@@ -8668,46 +8712,9 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no
CHECK(compile_op_cdecl(iseq, ret, node, popped));
break;
case NODE_OP_ASGN_AND:
- case NODE_OP_ASGN_OR:{
- LABEL *lfin = NEW_LABEL(line);
- LABEL *lassign;
-
- if (nd_type(node) == NODE_OP_ASGN_OR && nd_type(node->nd_head) != NODE_IVAR) {
- LABEL *lfinish[2];
- lfinish[0] = lfin;
- lfinish[1] = 0;
- defined_expr(iseq, ret, node->nd_head, lfinish, Qfalse);
- lassign = lfinish[1];
- if (!lassign) {
- lassign = NEW_LABEL(line);
- }
- ADD_INSNL(ret, node, branchunless, lassign);
- }
- else {
- lassign = NEW_LABEL(line);
- }
-
- CHECK(COMPILE(ret, "NODE_OP_ASGN_AND/OR#nd_head", node->nd_head));
- ADD_INSN(ret, node, dup);
-
- if (nd_type(node) == NODE_OP_ASGN_AND) {
- ADD_INSNL(ret, node, branchunless, lfin);
- }
- else {
- ADD_INSNL(ret, node, branchif, lfin);
- }
-
- ADD_INSN(ret, node, pop);
- ADD_LABEL(ret, lassign);
- CHECK(COMPILE(ret, "NODE_OP_ASGN_AND/OR#nd_value", node->nd_value));
- ADD_LABEL(ret, lfin);
-
- if (popped) {
- /* we can apply more optimize */
- ADD_INSN(ret, node, pop);
- }
+ case NODE_OP_ASGN_OR:
+ CHECK(compile_op_log(iseq, ret, node, popped, type));
break;
- }
case NODE_CALL: /* obj.foo */
case NODE_OPCALL: /* foo[] */
if (compile_call_precheck_freeze(iseq, ret, node, node, popped) == TRUE) {