diff --git a/ChangeLog b/ChangeLog index 61cbafa0be..5c2a187d24 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +Wed Jun 27 17:08:42 2007 Koichi Sasada + + * vm_evalbody.ci: support OPT_CALL_THREADED_CODE. + + * insns.def, vm.c, vm.h: ditto. + + * vm.h: add VM_CFP_CNT() and VM_SP_CNT(). + Wed Jun 27 04:23:47 2007 Koichi Sasada * compile.c (iseq_compile_each): fix type error. diff --git a/insns.def b/insns.def index 8bd52fa496..a8bec163e1 100644 --- a/insns.def +++ b/insns.def @@ -1325,8 +1325,8 @@ leave { if (OPT_CHECKED_RUN) { if (reg_cfp->sp != reg_cfp->bp) { - rb_bug("Stack consistency error (sp: %p, bp: %p)", - reg_cfp->sp, reg_cfp->bp); + rb_bug("Stack consistency error (sp: %d, bp: %d)", + VM_SP_CNT(th, reg_cfp->sp), VM_SP_CNT(th, reg_cfp->bp)); } } @@ -1346,8 +1346,12 @@ finish (VALUE val) (VALUE val) { +#if OPT_CALL_THREADED_CODE + rb_bug("unused instruction on OPT_CALL_THREADED_CODE"); +#else th->cfp++; return val; +#endif } /**********************************************************/ @@ -1422,7 +1426,7 @@ throw } } th->state = state; - return (VALUE) NEW_THROW_OBJECT(throwobj, (VALUE) pt, state); + THROW_EXCEPTION(NEW_THROW_OBJECT(throwobj, (VALUE) pt, state)); } else { /* continue throw */ @@ -1440,7 +1444,7 @@ throw else { th->state = FIX2INT(rb_ivar_get(err, idThrowState)); } - return err; + THROW_EXCEPTION(err); } /* unreachable */ } diff --git a/vm.c b/vm.c index 378f3ad8b5..7dc292e112 100644 --- a/vm.c +++ b/vm.c @@ -409,7 +409,6 @@ vm_call0(rb_thread_t *th, VALUE klass, VALUE recv, if (0) printf("id: %s, nd: %s, argc: %d, passed: %p\n", rb_id2name(id), ruby_node_name(nd_type(body)), argc, th->passed_block); - //SDR2(th->cfp); if (th->passed_block) { blockptr = th->passed_block; @@ -418,18 +417,20 @@ vm_call0(rb_thread_t *th, VALUE klass, VALUE recv, switch (nd_type(body)) { case RUBY_VM_METHOD_NODE:{ rb_control_frame_t *reg_cfp; + VALUE iseqval = (VALUE)body->nd_body; int i; rb_vm_set_finish_env(th); reg_cfp = th->cfp; - CHECK_STACK_OVERFLOW(reg_cfp, argc); + CHECK_STACK_OVERFLOW(reg_cfp, argc + 1); + *reg_cfp->sp++ = recv; for (i = 0; i < argc; i++) { *reg_cfp->sp++ = argv[i]; } - vm_setup_method(th, reg_cfp, argc, blockptr, 0, (VALUE)body->nd_body, recv, klass); + vm_setup_method(th, reg_cfp, argc, blockptr, 0, iseqval, recv, klass); val = vm_eval_body(th); break; } diff --git a/vm.h b/vm.h index b3e311cb0f..364eaa11d9 100644 --- a/vm.h +++ b/vm.h @@ -112,7 +112,7 @@ typedef rb_control_frame_t * (*insn_func_type) (rb_thread_t *, rb_control_frame_t *)FASTCALL; #define INSN_ENTRY(insn) \ - rb_control_frame_t * \ + static rb_control_frame_t * \ LABEL(insn)(rb_thread_t *th, rb_control_frame_t *reg_cfp) FASTCALL { #define END_INSN(insn) return reg_cfp;} @@ -219,6 +219,10 @@ default: \ /************************************************/ /************************************************/ +#define VM_CFP_CNT(th, cfp) \ + ((rb_control_frame_t *)(th->stack + th->stack_size) - (rb_control_frame_t *)(cfp)) +#define VM_SP_CNT(th, sp) ((sp) - (th)->stack) + /* env{ env[0] // special (block or prev env) @@ -266,6 +270,15 @@ default: \ #define SET_THROWOBJ_STATE(obj, val) \ (RNODE((obj))->u3.value = (val)) +#if OPT_CALL_THREADED_CODE +#define THROW_EXCEPTION(exc) do { \ + th->errinfo = (VALUE)(exc); \ + return 0; \ +} while (0) +#else +#define THROW_EXCEPTION(exc) return (exc) +#endif + #define SCREG(r) (reg_##r) /* VM state version */ diff --git a/vm_evalbody.ci b/vm_evalbody.ci index a7c0f83262..53683865d5 100644 --- a/vm_evalbody.ci +++ b/vm_evalbody.ci @@ -122,15 +122,24 @@ VALUE vm_eval(rb_thread_t *th, VALUE initial) { register rb_control_frame_t *reg_cfp = th->cfp; - SET_PC(reg_cfp->iseq->iseq_encoded); + VALUE ret; while (*GET_PC()) { reg_cfp = ((insn_func_type) (*GET_PC()))(th, reg_cfp); + + if (reg_cfp == 0) { + VALUE err = th->errinfo; + th->errinfo = Qnil; + return err; + } } - { - VALUE ret = *--reg_cfp->sp; - th->cfp--; - return ret; + + if (th->cfp->magic != FRAME_MAGIC_FINISH) { + rb_bug("cfp consistency error"); } + + ret = *(th->cfp->sp-1); /* pop */ + th->cfp++; /* pop cf */ + return ret; } #endif