diff options
author | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-06-24 13:05:51 +0000 |
---|---|---|
committer | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-06-24 13:05:51 +0000 |
commit | 62deb7dbbda5104c352abd723053bd1b18e50dbf (patch) | |
tree | 4680058ffc0d96cf05e0209aba88ef6cbf767fd4 /insns.def | |
parent | 904b9e5d547f4f9a9f3236d2633f0cb6d7aae14c (diff) | |
download | ruby-62deb7dbbda5104c352abd723053bd1b18e50dbf.tar.gz |
* insn_send.ci: removed.
* common.mk: ditto.
* vm.c (vm_call_bmethod), isnsn.def: added. fix to use this
function instead of using goto.
* vm.c (vm_call_bmethod): renamed from th_invoke_bmethod().
* vm.c (vm_method_missing): renamed from eval_methdo_missing().
* vm_evalbody.ci: remove tmp_* variables.
* insnhelper.h: add some macros.
* insns.def: forbid zsuper from method defined by define_method().
* test/ruby/test_super.rb: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12601 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'insns.def')
-rw-r--r-- | insns.def | 236 |
1 files changed, 121 insertions, 115 deletions
@@ -1152,7 +1152,55 @@ send (...) (VALUE val) // inc += - (op_argc + ((op_flag & VM_CALL_ARGS_BLOCKARG_BIT) ? 1 : 0)); { -#include "insn_send.ci" + NODE *mn; + VALUE recv, klass, v; + rb_block_t *blockptr = 0; + rb_num_t num = caller_setup_args(th, GET_CFP(), op_flag, op_argc, blockiseq, &blockptr); + rb_num_t flag = op_flag; + ID id = op_id; + + /* get receiver */ + 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); + + /* send/funcall optimization */ + 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; + VALUE sym = TOPN(num - 1); + id = SYMBOL_P(sym) ? SYM2ID(sym) : rb_to_id(sym); + + /* shift arguments */ + for (i=num-1; i>0; i--) { + TOPN(i) = TOPN(i-1); + } + + mn = rb_method_node(klass, id); + + num -= 1; + DEC_SP(1); + } + + if (node->nd_cfnc == rb_f_funcall) { + flag |= VM_CALL_FCALL_BIT; + } + } + + CALL_METHOD(num, blockptr, flag, id, mn, recv, klass); } /** @@ -1162,21 +1210,65 @@ send */ DEFINE_INSN invokesuper -(rb_num_t op_argc, ISEQ blockiseq, rb_num_t flag) +(rb_num_t op_argc, ISEQ blockiseq, rb_num_t op_flag) (...) (VALUE val) // inc += - op_argc; { -#if YARV_AOT_COMPILED - /* TODO: */ - rb_bug("..."); -#else - tmp_blockptr = 0; - tmp_num = caller_setup_args(th, GET_CFP(), flag, op_argc, blockiseq, &tmp_blockptr); - if (!tmp_blockptr && !(flag & VM_CALL_ARGS_BLOCKARG_BIT)) { - tmp_blockptr = GET_BLOCK_PTR(); + rb_block_t *blockptr = 0; + VALUE flag = op_flag; + int num = caller_setup_args(th, GET_CFP(), flag, op_argc, blockiseq, &blockptr); + rb_iseq_t *iseq = GET_ISEQ(); + rb_iseq_t *ip = iseq; + VALUE recv, klass; + ID id; + NODE *mn; + + if (!blockptr && !(flag & VM_CALL_ARGS_BLOCKARG_BIT)) { + blockptr = GET_BLOCK_PTR(); } - goto LABEL_IS_SC(start_init_in_super); -#endif + + recv = GET_SELF(); + + while (ip && !ip->klass) { + ip = ip->parent_iseq; + } + + if (ip == 0) { + rb_raise(rb_eNoMethodError, "super called outside of method"); + } + + id = ip->defined_method_id; + + if (ip != ip->local_iseq) { + /* defined by Module#define_method() */ + rb_control_frame_t *lcfp = GET_CFP(); + + while (lcfp->iseq != ip) { + VALUE *tdfp = GET_PREV_DFP(lcfp->dfp); + while (1) { + lcfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(lcfp); + if (lcfp->dfp == tdfp) { + break; + } + } + } + + id = lcfp->method_id; + klass = search_super_klass(lcfp->method_klass, recv); + + if (TOPN(num) == Qfalse) { + /* zsuper */ + rb_raise(rb_eRuntimeError, "zsuper from method defined by define_method() is not supported. Specify all arguments."); + } + } + else { + klass = search_super_klass(ip->klass, recv); + } + + flag = VM_CALL_SUPER_BIT | VM_CALL_FCALL_BIT; + mn = rb_method_node(klass, id); + + CALL_METHOD(num, blockptr, flag, id, mn, recv, klass); } /** @@ -1581,15 +1673,9 @@ opt_plus } else { INSN_LABEL(normal_dispatch): - -#ifdef YARV_AOT_COMPILED - val = rb_funcall(recv, idPLUS, 1, obj); -#else PUSH(recv); PUSH(obj); - tmp_id = idPLUS; - goto LABEL_IS_SC(start_init_in_send_for_opt_1); -#endif + CALL_SIMPLE_METHOD(1, idPLUS, recv); } } @@ -1619,14 +1705,9 @@ opt_minus } else { /* other */ -#ifdef YARV_AOT_COMPILED - val = rb_funcall(recv, idMINUS, 1, obj); -#else PUSH(recv); PUSH(obj); - tmp_id = idMINUS; - goto LABEL_IS_SC(start_init_in_send_for_opt_1); -#endif + CALL_SIMPLE_METHOD(1, idMINUS, recv); } } @@ -1675,16 +1756,9 @@ opt_mult } else { INSN_LABEL(normal_dispatch): - - /* other */ -#ifdef YARV_AOT_COMPILED - val = rb_funcall(recv, idMULT, 1, obj); -#else PUSH(recv); PUSH(obj); - tmp_id = idMULT; - goto LABEL_IS_SC(start_init_in_send_for_opt_1); -#endif + CALL_SIMPLE_METHOD(1, idMULT, recv); } } @@ -1746,16 +1820,9 @@ opt_div } else { INSN_LABEL(normal_dispatch): - - /* other */ -#ifdef YARV_AOT_COMPILED - val = rb_funcall(recv, idDIV, 1, obj); -#else PUSH(recv); PUSH(obj); - tmp_id = idDIV; - goto LABEL_IS_SC(start_init_in_send_for_opt_1); -#endif + CALL_SIMPLE_METHOD(1, idDIV, recv); } } @@ -1837,16 +1904,9 @@ opt_mod } else { INSN_LABEL(normal_dispatch): - - /* other */ -#ifdef YARV_AOT_COMPILED - val = rb_funcall(recv, idMOD, 1, obj); -#else PUSH(recv); PUSH(obj); - tmp_id = idMOD; - goto LABEL_IS_SC(start_init_in_send_for_opt_1); -#endif + CALL_SIMPLE_METHOD(1, idMOD, recv); } } @@ -1916,14 +1976,9 @@ opt_eq else { INSN_LABEL(normal_dispatch): /* other */ -#ifdef YARV_AOT_COMPILED - val = rb_funcall(recv, idEq, 1, obj); -#else PUSH(recv); PUSH(obj); - tmp_id = idEq; - goto LABEL_IS_SC(start_init_in_send_for_opt_1); -#endif + CALL_SIMPLE_METHOD(1, idEq, recv); } } @@ -1951,15 +2006,9 @@ opt_lt } } else { - /* other */ -#ifdef YARV_AOT_COMPILED - val = rb_funcall(recv, idLT, 1, obj); -#else PUSH(recv); PUSH(obj); - tmp_id = idLT; - goto LABEL_IS_SC(start_init_in_send_for_opt_1); -#endif + CALL_SIMPLE_METHOD(1, idLT, recv); } } @@ -1987,14 +2036,9 @@ opt_le } else { /* other */ -#ifdef YARV_AOT_COMPILED - val = rb_funcall(recv, idLE, 1, obj); -#else PUSH(recv); PUSH(obj); - tmp_id = idLE; - goto LABEL_IS_SC(start_init_in_send_for_opt_1); -#endif + CALL_SIMPLE_METHOD(1, idLE, recv); } } @@ -2021,15 +2065,9 @@ opt_gt } } else { - /* other */ -#ifdef YARV_AOT_COMPILED - val = rb_funcall(recv, idGT, 1, obj); -#else PUSH(recv); PUSH(obj); - tmp_id = idGT; - goto LABEL_IS_SC(start_init_in_send_for_opt_1); -#endif + CALL_SIMPLE_METHOD(1, idGT, recv); } } @@ -2056,15 +2094,9 @@ opt_ge } } else { - /* other */ -#ifdef YARV_AOT_COMPILED - val = rb_funcall(recv, idGE, 1, obj); -#else PUSH(recv); PUSH(obj); - tmp_id = idGE; - goto LABEL_IS_SC(start_init_in_send_for_opt_1); -#endif + CALL_SIMPLE_METHOD(1, idGE, recv); } } @@ -2096,15 +2128,9 @@ opt_ltlt } else { INSN_LABEL(normal_dispatch): - /* other */ -#ifdef YARV_AOT_COMPILED - val = rb_funcall(recv, idLTLT, 1, obj); -#else PUSH(recv); PUSH(obj); - tmp_id = idLTLT; - goto LABEL_IS_SC(start_init_in_send_for_opt_1); -#endif + CALL_SIMPLE_METHOD(1, idLTLT, recv); } } @@ -2132,15 +2158,9 @@ opt_aref } else { INSN_LABEL(normal_dispatch): - /* other */ -#ifdef YARV_AOT_COMPILED - val = rb_funcall(recv, idAREF, 1, obj); -#else PUSH(recv); PUSH(obj); - tmp_id = idAREF; - goto LABEL_IS_SC(start_init_in_send_for_opt_1); -#endif + CALL_SIMPLE_METHOD(1, idAREF, recv); } } @@ -2171,16 +2191,10 @@ opt_aset } else { INSN_LABEL(normal_dispatch): - /* other */ -#ifdef YARV_AOT_COMPILED - val = rb_funcall(recv, idASET, 2, obj, set); -#else PUSH(recv); PUSH(obj); PUSH(set); - tmp_id = idASET; - goto LABEL_IS_SC(start_init_in_send_for_opt_2); -#endif + CALL_SIMPLE_METHOD(2, idASET, recv); } } @@ -2212,12 +2226,8 @@ opt_length } else { INSN_LABEL(normal_dispatch): - /* other */ -#ifdef YARV_AOT_COMPILED - val = rb_funcall(recv, idLength, 0); -#else - val = rb_funcall(recv, idLength, 0); -#endif + PUSH(recv); + CALL_SIMPLE_METHOD(0, idLength, recv); } } @@ -2262,12 +2272,8 @@ opt_succ } if (0) { INSN_LABEL(normal_dispatch): - /* other */ -#ifdef YARV_AOT_COMPILED - val = rb_funcall(recv, idSucc, 0); -#else - val = rb_funcall(recv, idSucc, 0); -#endif + PUSH(recv); + CALL_SIMPLE_METHOD(0, idSucc, recv); } } |