summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog13
-rw-r--r--compile.c17
-rw-r--r--compile.h6
-rw-r--r--eval.c10
-rw-r--r--insns.def13
-rw-r--r--vm.h7
6 files changed, 49 insertions, 17 deletions
diff --git a/ChangeLog b/ChangeLog
index b57527af67..ee7d76eafe 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+Fri Jan 5 20:52:56 2007 Koichi Sasada <ko1@atdot.net>
+
+ * compile.c, compile.h : add ADD_CALL_RECEIVER() macro.
+
+ * insns.def (send) : use GET_SELF() direct if FCALL.
+
+ * eval.c (rb_f_send) : check method dispatch type to permit
+ invoking private method when dispatch type is FCALL/VCALL
+
+ * insns.def (opt_ltlt) : remove useless statement.
+
+ * vm.h : remove unused macros.
+
Fri Jan 5 20:50:31 2007 Koichi Sasada <ko1@atdot.net>
* benchmark/run_rite.rb : fix to use readlines instead of
diff --git a/compile.c b/compile.c
index 131eb7f8e6..198a4c21d2 100644
--- a/compile.c
+++ b/compile.c
@@ -2901,7 +2901,7 @@ iseq_compile_each(yarv_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
end_label, redo_label);
}
else {
- ADD_INSN(ret, nd_line(node), putself);
+ ADD_CALL_RECEIVER(ret, nd_line(node));
ADD_CALL(ret, nd_line(node), ID2SYM(idGets), INT2FIX(0));
ADD_INSNL(ret, nd_line(node), branchif, redo_label) ;
/* opt_n */
@@ -3626,7 +3626,7 @@ iseq_compile_each(yarv_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
COMPILE(recv, "recv", node->nd_recv);
}
else if (type == NODE_FCALL || type == NODE_VCALL) {
- ADD_INSN(recv, nd_line(node), putself);
+ ADD_CALL_RECEIVER(recv, nd_line(node));
}
/* args */
@@ -4013,7 +4013,7 @@ iseq_compile_each(yarv_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
break;
}
case NODE_XSTR:{
- ADD_INSN(ret, nd_line(node), putself);
+ ADD_CALL_RECEIVER(ret, nd_line(node));
ADD_INSN1(ret, nd_line(node), putobject, node->nd_lit);
ADD_CALL(ret, nd_line(node), ID2SYM(idBackquote), INT2FIX(1));
@@ -4023,7 +4023,7 @@ iseq_compile_each(yarv_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
break;
}
case NODE_DXSTR:{
- ADD_INSN(ret, nd_line(node), putself);
+ ADD_CALL_RECEIVER(ret, nd_line(node));
compile_dstr(iseq, ret, node);
ADD_CALL(ret, nd_line(node), ID2SYM(idBackquote), INT2FIX(1));
@@ -4258,7 +4258,7 @@ iseq_compile_each(yarv_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
}
else {
/* function call */
- ADD_INSN(ret, nd_line(node), putself);
+ ADD_CALL_RECEIVER(ret, nd_line(node));
COMPILE(ret, "colon2#nd_head", node->nd_head);
ADD_CALL(ret, nd_line(node), ID2SYM(node->nd_mid),
INT2FIX(1));
@@ -4507,11 +4507,12 @@ iseq_compile_each(yarv_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
break;
}
case NODE_LAMBDA:{
+ /* compile same as lambda{...} */
VALUE block = NEW_CHILD_ISEQVAL(node, make_name_for_block(iseq), ISEQ_TYPE_BLOCK);
VALUE argc = INT2FIX(0);
- ADD_INSN (ret, nd_line(node), putself);
- ADD_SEND_R(ret, nd_line(node), ID2SYM(idLambda), argc,
- block, INT2FIX(VM_CALL_FCALL_BIT));
+ ADD_CALL_RECEIVER(ret, nd_line(node));
+ ADD_CALL_WITH_BLOCK(ret, nd_line(node), ID2SYM(idLambda), argc, block);
+
if (poped) {
ADD_INSN(ret, nd_line(node), pop);
}
diff --git a/compile.h b/compile.h
index 2955977688..9c8dccbae3 100644
--- a/compile.h
+++ b/compile.h
@@ -144,9 +144,15 @@ r_value(VALUE value)
#define ADD_SEND(seq, line, id, argc) \
ADD_SEND_R(seq, line, id, argc, (VALUE)Qfalse, (VALUE)INT2FIX(0))
+#define ADD_CALL_RECEIVER(seq, line) \
+ ADD_INSN(seq, line, putnil)
+
#define ADD_CALL(seq, line, id, argc) \
ADD_SEND_R(seq, line, id, argc, (VALUE)Qfalse, (VALUE)INT2FIX(VM_CALL_FCALL_BIT))
+#define ADD_CALL_WITH_BLOCK(seq, line, id, argc, block) \
+ ADD_SEND_R(seq, line, id, argc, block, (VALUE)INT2FIX(VM_CALL_FCALL_BIT))
+
#define ADD_SEND_R(seq, line, id, argc, block, flag) \
ADD_ELEM(seq, (LINK_ELEMENT *) \
new_insn_send(iseq, line, \
diff --git a/eval.c b/eval.c
index 56fa3ae81e..07034794ae 100644
--- a/eval.c
+++ b/eval.c
@@ -1712,7 +1712,15 @@ send_funcall(int argc, VALUE *argv, VALUE recv, int scope)
static VALUE
rb_f_send(int argc, VALUE *argv, VALUE recv)
{
- return send_funcall(argc, argv, recv, NOEX_PUBLIC);
+ int scope = NOEX_PUBLIC;
+ yarv_thread_t *th = GET_THREAD();
+ yarv_control_frame_t *cfp = YARV_PREVIOUS_CONTROL_FRAME(th->cfp);
+
+ if (SPECIAL_CONST_P(cfp->sp[0])) {
+ scope = NOEX_NOSUPER | NOEX_PRIVATE;
+ }
+
+ return send_funcall(argc, argv, recv, scope);
}
/*
diff --git a/insns.def b/insns.def
index 99e35a7190..201e0db937 100644
--- a/insns.def
+++ b/insns.def
@@ -1158,7 +1158,16 @@ send
num_t flag = op_flag;
macro_eval_setup_send_arguments(num, blockptr, flag, blockiseq);
- recv = TOPN(num);
+
+ if (flag & VM_CALL_FCALL_BIT) {
+ /* method(...) */
+ recv = GET_SELF();
+ }
+ else {
+ /* recv.method(...) */
+ recv = TOPN(num);
+ }
+
klass = CLASS_OF(recv);
mn = eval_method_search(id, klass, ic);
@@ -2110,8 +2119,6 @@ opt_ltlt
(VALUE recv, VALUE obj)
(VALUE val)
{
- if (0) {
- }
if (!SPECIAL_CONST_P(recv)) {
if (0) {
}
diff --git a/vm.h b/vm.h
index d4b0a54431..942a1c4cb5 100644
--- a/vm.h
+++ b/vm.h
@@ -229,12 +229,9 @@ default: \
};
*/
-#define ENV_VAL(env) ((env)[3])
-#define ENV_IN_HEAP_P(env) ((env)[2] == Qundef)
#define ORPHAN_ENV_P(env) ((env)[1] == Qundef)
-
-#define ENV_IN_HEAP(env) ((env)[2] = Qundef)
-#define ORPHAN_ENV(env) ((env)[1] = Qundef)
+#define ENV_IN_HEAP_P(env) ((env)[2] == Qundef)
+#define ENV_VAL(env) ((env)[3])
#define FRAME_MAGIC_METHOD 0xfaffff11
#define FRAME_MAGIC_BLOCK 0xfaffff21