summaryrefslogtreecommitdiff
path: root/insns.def
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2007-01-06 00:24:59 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2007-01-06 00:24:59 +0000
commitce55b4c0e0062cd59eb3d5e05ffc5d75bdcde85a (patch)
treef4252badb58ec3ab74af8c2f2a99db6ccbf4d4ab /insns.def
parenta782fa12681c106fe6516955f72ec048bb27bbc9 (diff)
* insns.def : support direct method dispatch with "send" or "funcall".
This means that "obj.send :m" skips "BasicObject#send" invocation (method frame creation, etc) and "obj.m" invokes directly. If you make backtrace, there are no enties of "send" method. * compile.c (iseq_specialized_instruction) : fix to support above * eval.c : ditto (remove "static" from rb_f_send and rb_f_funcall * yarvcore.c : ditto (add a external IDs for compiler) * yarvcore.h : ditto (add a VM_CALL_SEND_BIT macro) * yarvtest/test_method.rb : add tests for above changes * eval.c : remove unused "Kernel#send" declaration git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11488 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'insns.def')
-rw-r--r--insns.def28
1 files changed, 27 insertions, 1 deletions
diff --git a/insns.def b/insns.def
index 201e0db937..0e5ec71185 100644
--- a/insns.def
+++ b/insns.def
@@ -1146,7 +1146,7 @@ defineclass
*/
DEFINE_INSN
send
-(ID id, num_t op_argc, ISEQ blockiseq, num_t op_flag, IC ic)
+(ID op_id, num_t op_argc, ISEQ blockiseq, num_t op_flag, IC ic)
(...)
(VALUE val) // inc += - (op_argc + ((op_flag & VM_CALL_ARGS_BLOCKARG_BIT) ? 1 : 0));
{
@@ -1156,6 +1156,7 @@ send
yarv_block_t *blockptr = 0;
num_t num = op_argc;
num_t flag = op_flag;
+ ID id = op_id;
macro_eval_setup_send_arguments(num, blockptr, flag, blockiseq);
@@ -1172,6 +1173,31 @@ send
mn = eval_method_search(id, klass, ic);
+ if ((flag & VM_CALL_SEND_BIT) && mn && nd_type(mn->nd_body) == NODE_CFUNC) {
+ NODE *node = mn->nd_body;
+ extern VALUE rb_f_funcall(int argc, VALUE *argv, VALUE recv);
+ extern VALUE rb_f_send(int argc, VALUE *argv, VALUE recv);
+
+ if (node->nd_cfnc == rb_f_funcall || node->nd_cfnc == rb_f_send) {
+ int i;
+ id = rb_to_id(TOPN(num - 1));
+
+ /* shift arguments */
+ for (i=1; i<num; i++) {
+ GET_SP()[-num+i-1] = GET_SP()[(-num+i-1)+1];
+ }
+
+ mn = rb_method_node(klass, id);
+
+ num -= 1;
+ INC_SP(-1);
+ }
+
+ if (node->nd_cfnc == rb_f_funcall) {
+ flag |= VM_CALL_FCALL_BIT;
+ }
+ }
+
#if CURRENT_INSN_send || CURRENT_INSN_send_SC_xx_ax
#if !YARV_AOT_COMPILED
if (0) {