summaryrefslogtreecommitdiff
path: root/insns.def
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2007-08-06 11:36:30 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2007-08-06 11:36:30 +0000
commitae421c43dfda6e9a1e9af1edaa649a3de17ff07a (patch)
tree7f12a2d3d92ec0e7744f7104ed545b5f6fbb3a7e /insns.def
parent7e2b837a3939b0c7473728c12579dd8930c3cfaf (diff)
* insnhelper.ci, insns.def: move some statements to functions.
* vm.c, vm.h, vm_evalbody.ci: fix include/typedef places. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12887 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'insns.def')
-rw-r--r--insns.def310
1 files changed, 16 insertions, 294 deletions
diff --git a/insns.def b/insns.def
index 21c7368bfb..c235426748 100644
--- a/insns.def
+++ b/insns.def
@@ -84,35 +84,7 @@ getspecial
()
(VALUE val)
{
- if (type == 0) {
- if (FIXNUM_P(key)) key = FIX2INT(key);
- val = lfp_svar_get(th, GET_LFP(), key);
- }
- else {
- VALUE backref = lfp_svar_get(th, GET_LFP(), 1);
-
- if (type & 0x01) {
- switch (type >> 1) {
- case '&':
- val = rb_reg_last_match(backref);
- break;
- case '`':
- val = rb_reg_match_pre(backref);
- break;
- case '\'':
- val = rb_reg_match_post(backref);
- break;
- case '+':
- val = rb_reg_match_last(backref);
- break;
- default:
- rb_bug("unexpected back-ref");
- }
- }
- else {
- val = rb_reg_nth_match(type >> 1, backref);
- }
- }
+ val = vm_getspecial(th, GET_LFP(), key, type);
}
/**
@@ -930,7 +902,7 @@ defined
ip = ip->parent_iseq;
}
if (ip) {
- VALUE klass = vm_search_super_klass(ip->klass, GET_SELF());
+ VALUE klass = vm_search_normal_super_klass(ip->klass, GET_SELF());
if (rb_method_boundp(klass, ip->defined_method_id, 0)) {
expr_type = "super";
}
@@ -1124,49 +1096,18 @@ send
NODE *mn;
VALUE recv, klass;
rb_block_t *blockptr = 0;
- rb_num_t num = caller_setup_args(th, GET_CFP(), op_flag, op_argc, blockiseq, &blockptr);
+ rb_num_t num = caller_setup_args(th, GET_CFP(), op_flag, op_argc, (rb_iseq_t *)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);
- }
-
+ recv = (flag & VM_CALL_FCALL_BIT) ? GET_SELF() : TOPN(num);
klass = CLASS_OF(recv);
-
mn = vm_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;
- }
+ if (flag & VM_CALL_SEND_BIT) {
+ vm_send_optimize(GET_CFP(), &mn, &flag, &num, &id, klass);
}
CALL_METHOD(num, blockptr, flag, id, mn, recv, klass);
@@ -1183,58 +1124,15 @@ invokesuper
(...)
(VALUE val) // inc += - op_argc;
{
- 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;
+ rb_block_t *blockptr = !(op_flag & VM_CALL_ARGS_BLOCKARG_BIT) ? GET_BLOCK_PTR() : 0;
+ int num = caller_setup_args(th, GET_CFP(), op_flag, op_argc, blockiseq, &blockptr);
VALUE recv, klass;
- ID id;
NODE *mn;
-
- if (!blockptr && !(flag & VM_CALL_ARGS_BLOCKARG_BIT)) {
- blockptr = GET_BLOCK_PTR();
- }
+ ID id;
+ const VALUE flag = VM_CALL_SUPER_BIT | 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 = vm_search_super_klass(lcfp->method_klass, recv);
-
- if (TOPN(num) == Qfalse) {
- /* zsuper */
- rb_raise(rb_eRuntimeError, "implicit argument passing of super from method defined by define_method() is not supported. Specify all arguments explicitly.");
- }
- }
- else {
- klass = vm_search_super_klass(ip->klass, recv);
- }
-
- flag = VM_CALL_SUPER_BIT | VM_CALL_FCALL_BIT;
+ vm_search_super_klass(GET_CFP(), GET_ISEQ(), recv, TOPN(num), &id, &klass);
mn = rb_method_node(klass, id);
CALL_METHOD(num, blockptr, flag, id, mn, recv, klass);
@@ -1251,42 +1149,10 @@ invokeblock
(...)
(VALUE val) // inc += 1 - num;
{
- rb_block_t *block = GET_BLOCK_PTR();
- rb_iseq_t *iseq;
- int argc = num;
-
- if (GET_ISEQ()->local_iseq->type != ISEQ_TYPE_METHOD || block == 0) {
- vm_localjump_error("no block given (yield)", Qnil, 0);
- }
- iseq = block->iseq;
-
- if (BUILTIN_TYPE(iseq) != T_NODE) {
- int opt_pc;
-
- argc = caller_setup_args(th, GET_CFP(), flag, argc, 0, 0);
-
- CHECK_STACK_OVERFLOW(GET_CFP(), iseq->stack_max);
-
- DEC_SP(argc);
- opt_pc = vm_yield_setup_args(th, iseq, argc, GET_SP(), 0,
- block_proc_is_lambda(block->proc));
- argc = iseq->arg_size;
- INC_SP(argc);
-
- vm_push_frame(th, iseq,
- FRAME_MAGIC_BLOCK, block->self, (VALUE) block->dfp,
- iseq->iseq_encoded + opt_pc, GET_SP(), block->lfp,
- iseq->local_size - argc);
-
- reg_cfp->sp -= argc;
+ val = vm_invoke_block(th, GET_CFP(), num, flag);
+ if (val == Qundef) {
RESTORE_REGS();
NEXT_INSN();
- /* unreachable */
- }
- else {
- val = vm_yield_with_cfunc(th, block, block->self,
- num, STACK_ADDR_FROM_TOP(num));
- POPN(num);
}
}
@@ -1347,147 +1213,8 @@ throw
(VALUE throwobj)
(VALUE val)
{
- rb_num_t state = throw_state & 0xff;
- rb_num_t flag = throw_state & 0x8000;
- rb_num_t level = throw_state >> 16;
- val = Qnil; /* dummy */
-
- if (state != 0) {
- VALUE *pt;
- int i;
- if (flag != 0) {
- if (throw_state & 0x4000) {
- pt = (void *)1;
- }
- else {
- pt = 0;
- }
- }
- else {
- if (state == TAG_BREAK) {
- rb_control_frame_t *cfp = GET_CFP();
- VALUE *dfp = GET_DFP();
- int is_orphan = 1;
- rb_iseq_t *base_iseq = GET_ISEQ();
-
- INSN_LABEL(search_parent):
- if (cfp->iseq->type != ISEQ_TYPE_BLOCK) {
- dfp = GC_GUARDED_PTR_REF((VALUE *) *dfp);
- base_iseq = base_iseq->parent_iseq;
-
- while ((VALUE *) cfp < th->stack + th->stack_size) {
- if (cfp->dfp == dfp) {
- goto INSN_LABEL(search_parent);
- }
- cfp++;
- }
- rb_bug("VM (throw): can't find break base.");
- }
-
- if (VM_FRAME_TYPE(cfp) == FRAME_MAGIC_LAMBDA) {
- /* lambda{... break ...} */
- is_orphan = 0;
- pt = dfp;
- }
- else {
- dfp = GC_GUARDED_PTR_REF((VALUE *) *dfp);
-
- while ((VALUE *)cfp < th->stack + th->stack_size) {
- if (cfp->dfp == dfp) {
- VALUE epc = epc = cfp->pc - cfp->iseq->iseq_encoded;
- rb_iseq_t *iseq = cfp->iseq;
- int i;
-
- for (i=0; i<iseq->catch_table_size; i++) {
- struct iseq_catch_table_entry *entry = &iseq->catch_table[i];
-
- if (entry->type == CATCH_TYPE_BREAK &&
- entry->start < epc && entry->end >= epc) {
- if (entry->cont == epc) {
- goto INSN_LABEL(found);
- }
- else {
- break;
- }
- }
- }
- break;
-
- INSN_LABEL(found):
-
- pt = dfp;
- is_orphan = 0;
- break;
- }
- cfp++;
- }
- }
-
- if (is_orphan) {
- vm_localjump_error("break from proc-closure", throwobj, TAG_BREAK);
- }
- }
- else if (state == TAG_RETRY) {
- pt = GC_GUARDED_PTR_REF((VALUE *) * GET_DFP());
- for (i = 0; i < level; i++) {
- pt = GC_GUARDED_PTR_REF((VALUE *) * pt);
- }
- }
- else if (state == TAG_RETURN) {
- rb_control_frame_t *cfp = GET_CFP();
- VALUE *dfp = GET_DFP();
- int is_orphan = 1;
-
- /**
- * check orphan:
- */
- while ((VALUE *) cfp < th->stack + th->stack_size) {
- if (GET_DFP() == dfp) {
- if (VM_FRAME_TYPE(cfp) == FRAME_MAGIC_LAMBDA) {
- /* in lambda */
- is_orphan = 0;
- break;
- }
- }
- cfp++;
- if (GET_LFP() == cfp->lfp &&
- cfp->iseq->type == ISEQ_TYPE_METHOD) {
- is_orphan = 0;
- break;
- }
- }
-
- if (is_orphan) {
- vm_localjump_error("unexpected return", throwobj, TAG_RETURN);
- }
-
- pt = GET_LFP();
- }
- else {
- rb_bug("isns(throw): unsupport throw type");
- }
- }
- th->state = state;
- THROW_EXCEPTION(NEW_THROW_OBJECT(throwobj, (VALUE) pt, state));
- }
- else {
- /* continue throw */
- VALUE err = throwobj;
-
- if (FIXNUM_P(err)) {
- th->state = FIX2INT(err);
- }
- else if (SYMBOL_P(err)) {
- th->state = TAG_THROW;
- }
- else if (BUILTIN_TYPE(err) == T_NODE) {
- th->state = GET_THROWOBJ_STATE(err);
- }
- else {
- th->state = FIX2INT(rb_ivar_get(err, idThrowState));
- }
- THROW_EXCEPTION(err);
- }
+ val = vm_throw(th, GET_CFP(), throw_state, throwobj);
+ THROW_EXCEPTION(val);
/* unreachable */
}
@@ -1936,18 +1663,13 @@ opt_mod
double y = RFLOAT(obj)->value;
double div, mod;
- /* copied from numeric.c#flodivmod */
-#if 0 && defined(HAVE_FMOD) && !__x86_64__ /* temporary */
- mod = fmod(x, y);
- printf("-- %f %% %f = %f\n", x, y, mod);
-#else
{
double z;
modf(x / y, &z);
mod = x - z * y;
}
-#endif
+
div = (x - mod) / y;
if (y * mod < 0) {
mod += y;