mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* compile.c (defined_expr): false short-circuit destination label may
be needed. [ruby-talk:295296] * compile.c (iseq_compile_each): put nil if false short-circuit is created. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@15836 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
f2025c33ff
commit
708e5ddde6
2 changed files with 50 additions and 52 deletions
|
@ -1,4 +1,10 @@
|
||||||
Tue Mar 25 15:09:36 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
Tue Mar 25 15:26:30 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* compile.c (defined_expr): false short-circuit destination label may
|
||||||
|
be needed. [ruby-talk:295296]
|
||||||
|
|
||||||
|
* compile.c (iseq_compile_each): put nil if false short-circuit is
|
||||||
|
created.
|
||||||
|
|
||||||
* compile.c (compile_massign_opt): no need to use alloca.
|
* compile.c (compile_massign_opt): no need to use alloca.
|
||||||
|
|
||||||
|
|
94
compile.c
94
compile.c
|
@ -2258,7 +2258,7 @@ compile_cpath(LINK_ANCHOR *ret, rb_iseq_t *iseq, NODE *cpath)
|
||||||
|
|
||||||
static int
|
static int
|
||||||
defined_expr(rb_iseq_t *iseq, LINK_ANCHOR *ret,
|
defined_expr(rb_iseq_t *iseq, LINK_ANCHOR *ret,
|
||||||
NODE * node, LABEL *lfinish, VALUE needstr)
|
NODE *node, LABEL **lfinish, VALUE needstr)
|
||||||
{
|
{
|
||||||
char *estr = 0;
|
char *estr = 0;
|
||||||
enum node_type type;
|
enum node_type type;
|
||||||
|
@ -2280,22 +2280,21 @@ defined_expr(rb_iseq_t *iseq, LINK_ANCHOR *ret,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NODE_ARRAY:{
|
case NODE_ARRAY:{
|
||||||
LABEL *lfalse = NULL;
|
|
||||||
NODE *vals = node;
|
NODE *vals = node;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
defined_expr(iseq, ret, vals->nd_head, lfinish, Qfalse);
|
defined_expr(iseq, ret, vals->nd_head, lfinish, Qfalse);
|
||||||
|
|
||||||
if (lfalse) {
|
if (lfinish[1]) {
|
||||||
ADD_INSNL(ret, nd_line(node), branchunless, lfalse);
|
ADD_INSNL(ret, nd_line(node), branchunless, lfinish[1]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LABEL *lcont = NEW_LABEL(nd_line(node));
|
LABEL *lcont = NEW_LABEL(nd_line(node));
|
||||||
lfalse = NEW_LABEL(nd_line(node));
|
lfinish[1] = NEW_LABEL(nd_line(node));
|
||||||
ADD_INSNL(ret, nd_line(node), branchif, lcont);
|
ADD_INSNL(ret, nd_line(node), branchif, lcont);
|
||||||
ADD_LABEL(ret, lfalse);
|
ADD_LABEL(ret, lfinish[1]);
|
||||||
ADD_INSN(ret, nd_line(node), putnil);
|
ADD_INSN(ret, nd_line(node), putnil);
|
||||||
ADD_INSNL(ret, nd_line(node), jump, lfinish);
|
ADD_INSNL(ret, nd_line(node), jump, lfinish[0]);
|
||||||
ADD_LABEL(ret, lcont);
|
ADD_LABEL(ret, lcont);
|
||||||
}
|
}
|
||||||
} while ((vals = vals->nd_next) != NULL);
|
} while ((vals = vals->nd_next) != NULL);
|
||||||
|
@ -2336,28 +2335,18 @@ defined_expr(rb_iseq_t *iseq, LINK_ANCHOR *ret,
|
||||||
ID2SYM(node->nd_vid), needstr);
|
ID2SYM(node->nd_vid), needstr);
|
||||||
return 1;
|
return 1;
|
||||||
case NODE_COLON2:
|
case NODE_COLON2:
|
||||||
|
if (!lfinish[1]) {
|
||||||
|
lfinish[1] = NEW_LABEL(nd_line(node));
|
||||||
|
}
|
||||||
|
defined_expr(iseq, ret, node->nd_head, lfinish, Qfalse);
|
||||||
|
ADD_INSNL(ret, nd_line(node), branchunless, lfinish[1]);
|
||||||
|
|
||||||
if (rb_is_const_id(node->nd_mid)) {
|
if (rb_is_const_id(node->nd_mid)) {
|
||||||
LABEL *lcont = NEW_LABEL(nd_line(node));
|
|
||||||
defined_expr(iseq, ret, node->nd_head, lfinish, Qfalse);
|
|
||||||
|
|
||||||
ADD_INSNL(ret, nd_line(node), branchif, lcont);
|
|
||||||
ADD_INSN(ret, nd_line(node), putnil);
|
|
||||||
ADD_INSNL(ret, nd_line(node), jump, lfinish);
|
|
||||||
|
|
||||||
ADD_LABEL(ret, lcont);
|
|
||||||
COMPILE(ret, "defined/colon2#nd_head", node->nd_head);
|
COMPILE(ret, "defined/colon2#nd_head", node->nd_head);
|
||||||
ADD_INSN3(ret, nd_line(node), defined, INT2FIX(DEFINED_CONST),
|
ADD_INSN3(ret, nd_line(node), defined, INT2FIX(DEFINED_CONST),
|
||||||
ID2SYM(node->nd_mid), needstr);
|
ID2SYM(node->nd_mid), needstr);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LABEL *lcont = NEW_LABEL(nd_line(node));
|
|
||||||
defined_expr(iseq, ret, node->nd_head, lfinish, Qfalse);
|
|
||||||
|
|
||||||
ADD_INSNL(ret, nd_line(node), branchif, lcont);
|
|
||||||
ADD_INSN(ret, nd_line(node), putnil);
|
|
||||||
ADD_INSNL(ret, nd_line(node), jump, lfinish);
|
|
||||||
|
|
||||||
ADD_LABEL(ret, lcont);
|
|
||||||
COMPILE(ret, "defined/colon2#nd_head", node->nd_head);
|
COMPILE(ret, "defined/colon2#nd_head", node->nd_head);
|
||||||
ADD_INSN3(ret, nd_line(node), defined, INT2FIX(DEFINED_METHOD),
|
ADD_INSN3(ret, nd_line(node), defined, INT2FIX(DEFINED_METHOD),
|
||||||
ID2SYM(node->nd_mid), needstr);
|
ID2SYM(node->nd_mid), needstr);
|
||||||
|
@ -2374,7 +2363,6 @@ defined_expr(rb_iseq_t *iseq, LINK_ANCHOR *ret,
|
||||||
case NODE_VCALL:
|
case NODE_VCALL:
|
||||||
case NODE_FCALL:
|
case NODE_FCALL:
|
||||||
case NODE_ATTRASGN:{
|
case NODE_ATTRASGN:{
|
||||||
LABEL *lfalse = NULL;
|
|
||||||
int self = Qtrue;
|
int self = Qtrue;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
@ -2386,23 +2374,17 @@ defined_expr(rb_iseq_t *iseq, LINK_ANCHOR *ret,
|
||||||
default:
|
default:
|
||||||
/* through */;
|
/* through */;
|
||||||
}
|
}
|
||||||
|
if (!lfinish[1]) {
|
||||||
|
lfinish[1] = NEW_LABEL(nd_line(node));
|
||||||
|
}
|
||||||
if (node->nd_args) {
|
if (node->nd_args) {
|
||||||
lfalse = NEW_LABEL(nd_line(node));
|
|
||||||
defined_expr(iseq, ret, node->nd_args, lfinish, Qfalse);
|
defined_expr(iseq, ret, node->nd_args, lfinish, Qfalse);
|
||||||
ADD_INSNL(ret, nd_line(node), branchunless, lfalse);
|
ADD_INSNL(ret, nd_line(node), branchunless, lfinish[1]);
|
||||||
}
|
}
|
||||||
if (!self) {
|
if (!self) {
|
||||||
LABEL *lcont = NEW_LABEL(nd_line(node));
|
|
||||||
|
|
||||||
defined_expr(iseq, ret, node->nd_recv, lfinish, Qfalse);
|
defined_expr(iseq, ret, node->nd_recv, lfinish, Qfalse);
|
||||||
ADD_INSNL(ret, nd_line(node), branchif, lcont);
|
ADD_INSNL(ret, nd_line(node), branchunless, lfinish[1]);
|
||||||
if (lfalse) {
|
|
||||||
ADD_LABEL(ret, lfalse);
|
|
||||||
}
|
|
||||||
ADD_INSN(ret, nd_line(node), putnil);
|
|
||||||
ADD_INSNL(ret, nd_line(node), jump, lfinish);
|
|
||||||
|
|
||||||
ADD_LABEL(ret, lcont);
|
|
||||||
COMPILE(ret, "defined/recv", node->nd_recv);
|
COMPILE(ret, "defined/recv", node->nd_recv);
|
||||||
ADD_INSN3(ret, nd_line(node), defined, INT2FIX(DEFINED_METHOD),
|
ADD_INSN3(ret, nd_line(node), defined, INT2FIX(DEFINED_METHOD),
|
||||||
ID2SYM(node->nd_mid), needstr);
|
ID2SYM(node->nd_mid), needstr);
|
||||||
|
@ -2411,12 +2393,6 @@ defined_expr(rb_iseq_t *iseq, LINK_ANCHOR *ret,
|
||||||
ADD_INSN(ret, nd_line(node), putself);
|
ADD_INSN(ret, nd_line(node), putself);
|
||||||
ADD_INSN3(ret, nd_line(node), defined, INT2FIX(DEFINED_FUNC),
|
ADD_INSN3(ret, nd_line(node), defined, INT2FIX(DEFINED_FUNC),
|
||||||
ID2SYM(node->nd_mid), needstr);
|
ID2SYM(node->nd_mid), needstr);
|
||||||
ADD_INSNL(ret, nd_line(node), jump, lfinish);
|
|
||||||
if (lfalse) {
|
|
||||||
ADD_LABEL(ret, lfalse);
|
|
||||||
ADD_INSN(ret, nd_line(node), putnil);
|
|
||||||
ADD_INSNL(ret, nd_line(node), jump, lfinish);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -2458,7 +2434,6 @@ defined_expr(rb_iseq_t *iseq, LINK_ANCHOR *ret,
|
||||||
default:{
|
default:{
|
||||||
LABEL *lstart = NEW_LABEL(nd_line(node));
|
LABEL *lstart = NEW_LABEL(nd_line(node));
|
||||||
LABEL *lend = NEW_LABEL(nd_line(node));
|
LABEL *lend = NEW_LABEL(nd_line(node));
|
||||||
LABEL *ldefed = NEW_LABEL(nd_line(node));
|
|
||||||
VALUE ensure = NEW_CHILD_ISEQVAL(NEW_NIL(),
|
VALUE ensure = NEW_CHILD_ISEQVAL(NEW_NIL(),
|
||||||
rb_str_concat(rb_str_new2
|
rb_str_concat(rb_str_new2
|
||||||
("defined guard in "),
|
("defined guard in "),
|
||||||
|
@ -2467,10 +2442,10 @@ defined_expr(rb_iseq_t *iseq, LINK_ANCHOR *ret,
|
||||||
|
|
||||||
ADD_LABEL(ret, lstart);
|
ADD_LABEL(ret, lstart);
|
||||||
COMPILE(ret, "defined expr (others)", node);
|
COMPILE(ret, "defined expr (others)", node);
|
||||||
ADD_INSNL(ret, nd_line(node), branchif, ldefed);
|
if (!lfinish[1]) {
|
||||||
ADD_INSN(ret, nd_line(node), putnil);
|
lfinish[1] = NEW_LABEL(nd_line(node));
|
||||||
ADD_INSNL(ret, nd_line(node), jump, lend);
|
}
|
||||||
ADD_LABEL(ret, ldefed);
|
ADD_INSNL(ret, nd_line(node), branchunless, lfinish[1]);
|
||||||
if (needstr) {
|
if (needstr) {
|
||||||
ADD_INSN1(ret, nd_line(node), putstring, rb_str_new2("expression"));
|
ADD_INSN1(ret, nd_line(node), putstring, rb_str_new2("expression"));
|
||||||
}
|
}
|
||||||
|
@ -2479,7 +2454,7 @@ defined_expr(rb_iseq_t *iseq, LINK_ANCHOR *ret,
|
||||||
}
|
}
|
||||||
ADD_LABEL(ret, lend);
|
ADD_LABEL(ret, lend);
|
||||||
|
|
||||||
ADD_CATCH_ENTRY(CATCH_TYPE_ENSURE, lstart, lend, ensure, lfinish);
|
ADD_CATCH_ENTRY(CATCH_TYPE_ENSURE, lstart, lend, ensure, lfinish[1]);
|
||||||
return 1;
|
return 1;
|
||||||
} /* end of default */
|
} /* end of default */
|
||||||
}
|
}
|
||||||
|
@ -3609,12 +3584,22 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
|
||||||
case NODE_OP_ASGN_AND:
|
case NODE_OP_ASGN_AND:
|
||||||
case NODE_OP_ASGN_OR:{
|
case NODE_OP_ASGN_OR:{
|
||||||
LABEL *lfin = NEW_LABEL(nd_line(node));
|
LABEL *lfin = NEW_LABEL(nd_line(node));
|
||||||
LABEL *lassign = NEW_LABEL(nd_line(node));
|
LABEL *lassign;
|
||||||
|
|
||||||
if (nd_type(node) == NODE_OP_ASGN_OR) {
|
if (nd_type(node) == NODE_OP_ASGN_OR) {
|
||||||
defined_expr(iseq, ret, node->nd_head, lassign, Qfalse);
|
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(nd_line(node));
|
||||||
|
}
|
||||||
ADD_INSNL(ret, nd_line(node), branchunless, lassign);
|
ADD_INSNL(ret, nd_line(node), branchunless, lassign);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
lassign = NEW_LABEL(nd_line(node));
|
||||||
|
}
|
||||||
|
|
||||||
COMPILE(ret, "NODE_OP_ASGN_AND/OR#nd_head", node->nd_head);
|
COMPILE(ret, "NODE_OP_ASGN_AND/OR#nd_head", node->nd_head);
|
||||||
ADD_INSN(ret, nd_line(node), dup);
|
ADD_INSN(ret, nd_line(node), dup);
|
||||||
|
@ -4459,9 +4444,16 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
|
||||||
}
|
}
|
||||||
case NODE_DEFINED:{
|
case NODE_DEFINED:{
|
||||||
if (!poped) {
|
if (!poped) {
|
||||||
LABEL *lfinish = NEW_LABEL(nd_line(node));
|
LABEL *lfinish[2];
|
||||||
|
lfinish[0] = NEW_LABEL(nd_line(node));
|
||||||
|
lfinish[1] = 0;
|
||||||
defined_expr(iseq, ret, node->nd_head, lfinish, Qtrue);
|
defined_expr(iseq, ret, node->nd_head, lfinish, Qtrue);
|
||||||
ADD_LABEL(ret, lfinish);
|
if (lfinish[1]) {
|
||||||
|
ADD_INSNL(ret, nd_line(node), jump, lfinish[0]);
|
||||||
|
ADD_LABEL(ret, lfinish[1]);
|
||||||
|
ADD_INSN(ret, nd_line(node), putnil);
|
||||||
|
}
|
||||||
|
ADD_LABEL(ret, lfinish[0]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue