* vm_macro.def: removed.
* insn_send.ci: added. this file includes send instruction body. * common.mk: ditto. * insns.def: ditto. * tool/insns2vm.rb: ditto. * vm.c: ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12600 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
59202b7ab8
commit
904b9e5d54
14
ChangeLog
14
ChangeLog
@ -1,3 +1,17 @@
|
|||||||
|
Sun Jun 24 20:01:08 2007 Koichi Sasada <ko1@atdot.net>
|
||||||
|
|
||||||
|
* vm_macro.def: removed.
|
||||||
|
|
||||||
|
* insn_send.ci: added. this file includes send instruction body.
|
||||||
|
|
||||||
|
* common.mk: ditto.
|
||||||
|
|
||||||
|
* insns.def: ditto.
|
||||||
|
|
||||||
|
* tool/insns2vm.rb: ditto.
|
||||||
|
|
||||||
|
* vm.c: ditto.
|
||||||
|
|
||||||
Sun Jun 24 19:30:37 2007 Koichi Sasada <ko1@atdot.net>
|
Sun Jun 24 19:30:37 2007 Koichi Sasada <ko1@atdot.net>
|
||||||
|
|
||||||
* insnhelper.h (RESTORE_REGS): add do/while(0) around macro.
|
* insnhelper.h (RESTORE_REGS): add do/while(0) around macro.
|
||||||
|
@ -566,7 +566,7 @@ vm.$(OBJEXT): {$(VPATH)}vm.c {$(VPATH)}vm.h {$(VPATH)}insnhelper.h \
|
|||||||
{$(VPATH)}node.h {$(VPATH)}util.h {$(VPATH)}signal.h {$(VPATH)}dln.h \
|
{$(VPATH)}node.h {$(VPATH)}util.h {$(VPATH)}signal.h {$(VPATH)}dln.h \
|
||||||
{$(VPATH)}vm_evalbody.ci {$(VPATH)}call_cfunc.ci \
|
{$(VPATH)}vm_evalbody.ci {$(VPATH)}call_cfunc.ci \
|
||||||
{$(VPATH)}insns.inc {$(VPATH)}vm.inc {$(VPATH)}vmtc.inc \
|
{$(VPATH)}insns.inc {$(VPATH)}vm.inc {$(VPATH)}vmtc.inc \
|
||||||
{$(VPATH)}vm_macro.inc {$(VPATH)}vm_opts.h {$(VPATH)}eval_intern.h \
|
{$(VPATH)}insn_send.ci {$(VPATH)}vm_opts.h {$(VPATH)}eval_intern.h \
|
||||||
{$(VPATH)}defines.h {$(VPATH)}missing.h {$(VPATH)}intern.h \
|
{$(VPATH)}defines.h {$(VPATH)}missing.h {$(VPATH)}intern.h \
|
||||||
{$(VPATH)}gc.h {$(VPATH)}thread_$(THREAD_MODEL).h
|
{$(VPATH)}gc.h {$(VPATH)}thread_$(THREAD_MODEL).h
|
||||||
vm_dump.$(OBJEXT): {$(VPATH)}vm_dump.c {$(VPATH)}yarvcore.h {$(VPATH)}vm.h \
|
vm_dump.$(OBJEXT): {$(VPATH)}vm_dump.c {$(VPATH)}yarvcore.h {$(VPATH)}vm.h \
|
||||||
@ -616,10 +616,6 @@ $(INSNS): $(srcdir)/insns.def {$(VPATH)}vm_opts.h
|
|||||||
$(RM) $(PROGRAM)
|
$(RM) $(PROGRAM)
|
||||||
$(BASERUBY) $(srcdir)/tool/insns2vm.rb $(INSNS2VMOPT)
|
$(BASERUBY) $(srcdir)/tool/insns2vm.rb $(INSNS2VMOPT)
|
||||||
|
|
||||||
vm_macro.inc: $(srcdir)/vm_macro.def
|
|
||||||
$(RM) $(PROGRAM)
|
|
||||||
$(BASERUBY) $(srcdir)/tool/insns2vm.rb $(INSNS2VMOPT) vm_macro.inc
|
|
||||||
|
|
||||||
incs: $(INSNS)
|
incs: $(INSNS)
|
||||||
|
|
||||||
docs:
|
docs:
|
||||||
|
226
insn_send.ci
Normal file
226
insn_send.ci
Normal file
@ -0,0 +1,226 @@
|
|||||||
|
/* -*-c-*- */
|
||||||
|
/* send instruction body */
|
||||||
|
|
||||||
|
{
|
||||||
|
NODE *mn;
|
||||||
|
VALUE recv;
|
||||||
|
VALUE klass;
|
||||||
|
rb_block_t *blockptr = 0;
|
||||||
|
rb_num_t num;
|
||||||
|
rb_num_t flag = op_flag;
|
||||||
|
ID id = op_id;
|
||||||
|
|
||||||
|
num = caller_setup_args(th, GET_CFP(), flag, op_argc, blockiseq, &blockptr);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CURRENT_INSN_send || CURRENT_INSN_send_SC_xx_ax
|
||||||
|
#if !YARV_AOT_COMPILED
|
||||||
|
if (0) {
|
||||||
|
if (0) {
|
||||||
|
LABEL_IS_SC(start_init_in_send_for_opt_1):
|
||||||
|
num = 1;
|
||||||
|
recv = TOPN(1);
|
||||||
|
}
|
||||||
|
else if (0) {
|
||||||
|
LABEL_IS_SC(start_init_in_send_for_opt_2):
|
||||||
|
num = 2;
|
||||||
|
recv = TOPN(2);
|
||||||
|
}
|
||||||
|
flag = 0;
|
||||||
|
id = tmp_id;
|
||||||
|
klass = CLASS_OF(recv);
|
||||||
|
blockptr = 0;
|
||||||
|
mn = rb_method_node(klass, id);
|
||||||
|
}
|
||||||
|
if (0) {
|
||||||
|
LABEL_IS_SC(start_init_in_super):
|
||||||
|
{
|
||||||
|
rb_iseq_t *iseq = GET_ISEQ();
|
||||||
|
rb_iseq_t *ip = iseq;
|
||||||
|
|
||||||
|
num = tmp_num;
|
||||||
|
flag = VM_CALL_FCALL_BIT;
|
||||||
|
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) {
|
||||||
|
/* for ZSUPER */
|
||||||
|
int i;
|
||||||
|
POPN(num);
|
||||||
|
num = ip->argc;
|
||||||
|
for (i = 0; i < ip->argc; i++) {
|
||||||
|
PUSH(lcfp->dfp[i - ip->local_size]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
klass = search_super_klass(ip->klass, recv);
|
||||||
|
}
|
||||||
|
|
||||||
|
flag = VM_CALL_SUPER_BIT | VM_CALL_FCALL_BIT;
|
||||||
|
blockptr = tmp_blockptr;
|
||||||
|
mn = rb_method_node(klass, id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LABEL_IS_SC(start_method_dispatch):
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
/* method missing */
|
||||||
|
if (mn == 0) {
|
||||||
|
/* temporarily */
|
||||||
|
if (id == idMethodMissing) {
|
||||||
|
rb_bug("method missing");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int stat = 0;
|
||||||
|
if (flag & VM_CALL_VCALL_BIT) {
|
||||||
|
stat |= NOEX_VCALL;
|
||||||
|
}
|
||||||
|
if (flag & VM_CALL_SUPER_BIT) {
|
||||||
|
stat |= NOEX_SUPER;
|
||||||
|
}
|
||||||
|
val = eval_method_missing(th, id, recv, num, blockptr, stat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!(flag & VM_CALL_FCALL_BIT) &&
|
||||||
|
(mn->nd_noex & NOEX_MASK) & NOEX_PRIVATE) {
|
||||||
|
int stat = NOEX_PRIVATE;
|
||||||
|
if (flag & VM_CALL_VCALL_BIT) {
|
||||||
|
stat |= NOEX_VCALL;
|
||||||
|
}
|
||||||
|
val = eval_method_missing(th, id, recv, num, blockptr, stat);
|
||||||
|
}
|
||||||
|
else if ((mn->nd_noex & NOEX_MASK) & NOEX_PROTECTED) {
|
||||||
|
VALUE defined_class = mn->nd_clss;
|
||||||
|
|
||||||
|
if (TYPE(defined_class) == T_ICLASS) {
|
||||||
|
defined_class = RBASIC(defined_class)->klass;
|
||||||
|
}
|
||||||
|
if (!rb_obj_is_kind_of(GET_SELF(), rb_class_real(defined_class))) {
|
||||||
|
val =
|
||||||
|
eval_method_missing(th, id, recv, num, blockptr,
|
||||||
|
NOEX_PROTECTED);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
goto INSN_LABEL(normal_method_dispatch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
NODE *node;
|
||||||
|
INSN_LABEL(normal_method_dispatch):
|
||||||
|
|
||||||
|
node = mn->nd_body;
|
||||||
|
switch (nd_type(node)) {
|
||||||
|
case RUBY_VM_METHOD_NODE:{
|
||||||
|
vm_setup_method(th, GET_CFP(), num, blockptr, flag, (VALUE)node->nd_body, recv, klass);
|
||||||
|
RESTORE_REGS();
|
||||||
|
NEXT_INSN();
|
||||||
|
}
|
||||||
|
case NODE_CFUNC:{
|
||||||
|
val = vm_call_cfunc(th, GET_CFP(), num, id, recv, klass, node, blockptr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NODE_ATTRSET:{
|
||||||
|
val = rb_ivar_set(recv, node->nd_vid, TOPN(0));
|
||||||
|
POPN(2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NODE_IVAR:{
|
||||||
|
val = rb_ivar_get(recv, node->nd_vid);
|
||||||
|
POP();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NODE_BMETHOD:{
|
||||||
|
VALUE *argv = GET_SP() - num;
|
||||||
|
val = th_invoke_bmethod(th, id, node->nd_cval,
|
||||||
|
recv, klass, num, argv);
|
||||||
|
INC_SP(-num-1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NODE_ZSUPER:{
|
||||||
|
klass = RCLASS(mn->nd_clss)->super;
|
||||||
|
mn = rb_method_node(klass, id);
|
||||||
|
|
||||||
|
if (mn != 0) {
|
||||||
|
goto INSN_LABEL(normal_method_dispatch);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
goto LABEL_IS_SC(start_method_dispatch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:{
|
||||||
|
printf("node: %s\n", ruby_node_name(nd_type(node)));
|
||||||
|
rb_bug("eval_invoke_method: unreachable");
|
||||||
|
/* unreachable */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RUBY_VM_CHECK_INTS();
|
||||||
|
}
|
||||||
|
|
130
insns.def
130
insns.def
@ -1152,135 +1152,7 @@ send
|
|||||||
(...)
|
(...)
|
||||||
(VALUE val) // inc += - (op_argc + ((op_flag & VM_CALL_ARGS_BLOCKARG_BIT) ? 1 : 0));
|
(VALUE val) // inc += - (op_argc + ((op_flag & VM_CALL_ARGS_BLOCKARG_BIT) ? 1 : 0));
|
||||||
{
|
{
|
||||||
NODE *mn;
|
#include "insn_send.ci"
|
||||||
VALUE recv;
|
|
||||||
VALUE klass;
|
|
||||||
rb_block_t *blockptr = 0;
|
|
||||||
rb_num_t num;
|
|
||||||
rb_num_t flag = op_flag;
|
|
||||||
ID id = op_id;
|
|
||||||
|
|
||||||
num = caller_setup_args(th, GET_CFP(), flag, op_argc, blockiseq, &blockptr);
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if CURRENT_INSN_send || CURRENT_INSN_send_SC_xx_ax
|
|
||||||
#if !YARV_AOT_COMPILED
|
|
||||||
if (0) {
|
|
||||||
if (0) {
|
|
||||||
LABEL_IS_SC(start_init_in_send_for_opt_1):
|
|
||||||
num = 1;
|
|
||||||
recv = TOPN(1);
|
|
||||||
}
|
|
||||||
else if (0) {
|
|
||||||
LABEL_IS_SC(start_init_in_send_for_opt_2):
|
|
||||||
num = 2;
|
|
||||||
recv = TOPN(2);
|
|
||||||
}
|
|
||||||
flag = 0;
|
|
||||||
id = tmp_id;
|
|
||||||
klass = CLASS_OF(recv);
|
|
||||||
blockptr = 0;
|
|
||||||
mn = rb_method_node(klass, id);
|
|
||||||
}
|
|
||||||
if (0) {
|
|
||||||
LABEL_IS_SC(start_init_in_super):
|
|
||||||
{
|
|
||||||
rb_iseq_t *iseq = GET_ISEQ();
|
|
||||||
rb_iseq_t *ip = iseq;
|
|
||||||
|
|
||||||
num = tmp_num;
|
|
||||||
flag = VM_CALL_FCALL_BIT;
|
|
||||||
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) {
|
|
||||||
/* for ZSUPER */
|
|
||||||
int i;
|
|
||||||
POPN(num);
|
|
||||||
num = ip->argc;
|
|
||||||
for (i = 0; i < ip->argc; i++) {
|
|
||||||
PUSH(lcfp->dfp[i - ip->local_size]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
klass = search_super_klass(ip->klass, recv);
|
|
||||||
}
|
|
||||||
|
|
||||||
flag = VM_CALL_SUPER_BIT | VM_CALL_FCALL_BIT;
|
|
||||||
blockptr = tmp_blockptr;
|
|
||||||
mn = rb_method_node(klass, id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LABEL_IS_SC(start_method_dispatch):
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
macro_eval_invoke_method(recv, klass, id, num, mn, blockptr);
|
|
||||||
RUBY_VM_CHECK_INTS();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1208,23 +1208,6 @@ class InsnsDef
|
|||||||
ERB.new(vpath.read('template/yarvarch.en')).result(binding)
|
ERB.new(vpath.read('template/yarvarch.en')).result(binding)
|
||||||
end
|
end
|
||||||
|
|
||||||
def vm_macro_inc
|
|
||||||
ret = ''
|
|
||||||
flag = false
|
|
||||||
vpath.foreach('vm_macro.def') {|line|
|
|
||||||
line.rstrip!
|
|
||||||
if /^MACRO\s/ =~ line
|
|
||||||
line.sub!(/^MACRO/, '#define')
|
|
||||||
flag = true
|
|
||||||
elsif /^\}/ =~ line
|
|
||||||
flag = false
|
|
||||||
end
|
|
||||||
|
|
||||||
ret << line + (flag ? " \\" : '') + "\n"
|
|
||||||
}
|
|
||||||
ret
|
|
||||||
end
|
|
||||||
|
|
||||||
Files = { # codes
|
Files = { # codes
|
||||||
'vm.inc' => :vm_inc,
|
'vm.inc' => :vm_inc,
|
||||||
'vmtc.inc' => :vmtc_inc,
|
'vmtc.inc' => :vmtc_inc,
|
||||||
@ -1235,7 +1218,6 @@ class InsnsDef
|
|||||||
'optunifs.inc' => :optunifs_unc,
|
'optunifs.inc' => :optunifs_unc,
|
||||||
'opt_sc.inc' => :opt_sc_inc,
|
'opt_sc.inc' => :opt_sc_inc,
|
||||||
'yasmdata.rb' => :yasmdata_rb,
|
'yasmdata.rb' => :yasmdata_rb,
|
||||||
'vm_macro.inc' => :vm_macro_inc,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def make_sources args = []
|
def make_sources args = []
|
||||||
|
1
vm.c
1
vm.c
@ -18,7 +18,6 @@
|
|||||||
#include "yarvcore.h"
|
#include "yarvcore.h"
|
||||||
#include "vm.h"
|
#include "vm.h"
|
||||||
#include "insnhelper.h"
|
#include "insnhelper.h"
|
||||||
#include "vm_macro.inc"
|
|
||||||
#include "insns.inc"
|
#include "insns.inc"
|
||||||
#include "eval_intern.h"
|
#include "eval_intern.h"
|
||||||
|
|
||||||
|
99
vm_macro.def
99
vm_macro.def
@ -1,99 +0,0 @@
|
|||||||
/* -*- c -*- */
|
|
||||||
/* do not use C++ style comment */
|
|
||||||
/* */
|
|
||||||
|
|
||||||
MACRO macro_eval_invoke_method(recv, klass, id, num, mn, blockptr)
|
|
||||||
{
|
|
||||||
/* method missing */
|
|
||||||
if (mn == 0) {
|
|
||||||
/* temporarily */
|
|
||||||
if (id == idMethodMissing) {
|
|
||||||
rb_bug("method missing");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
int stat = 0;
|
|
||||||
if (flag & VM_CALL_VCALL_BIT) {
|
|
||||||
stat |= NOEX_VCALL;
|
|
||||||
}
|
|
||||||
if (flag & VM_CALL_SUPER_BIT) {
|
|
||||||
stat |= NOEX_SUPER;
|
|
||||||
}
|
|
||||||
val = eval_method_missing(th, id, recv, num, blockptr, stat);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!(flag & VM_CALL_FCALL_BIT) &&
|
|
||||||
(mn->nd_noex & NOEX_MASK) & NOEX_PRIVATE) {
|
|
||||||
int stat = NOEX_PRIVATE;
|
|
||||||
if (flag & VM_CALL_VCALL_BIT) {
|
|
||||||
stat |= NOEX_VCALL;
|
|
||||||
}
|
|
||||||
val = eval_method_missing(th, id, recv, num, blockptr, stat);
|
|
||||||
}
|
|
||||||
else if ((mn->nd_noex & NOEX_MASK) & NOEX_PROTECTED) {
|
|
||||||
VALUE defined_class = mn->nd_clss;
|
|
||||||
|
|
||||||
if (TYPE(defined_class) == T_ICLASS) {
|
|
||||||
defined_class = RBASIC(defined_class)->klass;
|
|
||||||
}
|
|
||||||
if (!rb_obj_is_kind_of(GET_SELF(), rb_class_real(defined_class))) {
|
|
||||||
val =
|
|
||||||
eval_method_missing(th, id, recv, num, blockptr,
|
|
||||||
NOEX_PROTECTED);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
goto INSN_LABEL(normal_method_dispatch);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
NODE *node;
|
|
||||||
INSN_LABEL(normal_method_dispatch):
|
|
||||||
|
|
||||||
node = mn->nd_body;
|
|
||||||
switch (nd_type(node)) {
|
|
||||||
case RUBY_VM_METHOD_NODE:{
|
|
||||||
vm_setup_method(th, GET_CFP(), num, blockptr, flag, (VALUE)node->nd_body, recv, klass);
|
|
||||||
RESTORE_REGS();
|
|
||||||
NEXT_INSN();
|
|
||||||
}
|
|
||||||
case NODE_CFUNC:{
|
|
||||||
val = vm_call_cfunc(th, GET_CFP(), num, id, recv, klass, node, blockptr);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case NODE_ATTRSET:{
|
|
||||||
val = rb_ivar_set(recv, node->nd_vid, TOPN(0));
|
|
||||||
POPN(2);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case NODE_IVAR:{
|
|
||||||
val = rb_ivar_get(recv, node->nd_vid);
|
|
||||||
POP();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case NODE_BMETHOD:{
|
|
||||||
VALUE *argv = GET_SP() - num;
|
|
||||||
val = th_invoke_bmethod(th, id, node->nd_cval,
|
|
||||||
recv, klass, num, argv);
|
|
||||||
INC_SP(-num-1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case NODE_ZSUPER:{
|
|
||||||
klass = RCLASS(mn->nd_clss)->super;
|
|
||||||
mn = rb_method_node(klass, id);
|
|
||||||
|
|
||||||
if (mn != 0) {
|
|
||||||
goto INSN_LABEL(normal_method_dispatch);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
goto LABEL_IS_SC(start_method_dispatch);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default:{
|
|
||||||
printf("node: %s\n", ruby_node_name(nd_type(node)));
|
|
||||||
rb_bug("eval_invoke_method: unreachable");
|
|
||||||
/* unreachable */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user