diff options
author | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-01-06 00:24:59 +0000 |
---|---|---|
committer | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-01-06 00:24:59 +0000 |
commit | ce55b4c0e0062cd59eb3d5e05ffc5d75bdcde85a (patch) | |
tree | f4252badb58ec3ab74af8c2f2a99db6ccbf4d4ab /insns.def | |
parent | a782fa12681c106fe6516955f72ec048bb27bbc9 (diff) | |
download | ruby-ce55b4c0e0062cd59eb3d5e05ffc5d75bdcde85a.tar.gz |
* 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.def | 28 |
1 files changed, 27 insertions, 1 deletions
@@ -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) {
|