mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* vm_insnhelper.h: define struct THROW_DATA to represent
throwing data. Also define accessor functions. * eval_intern.h: move related changes into vm_insnhelper.h. Now these MACROs (functions) are only used in vm*.c. There is only THROW_DATA_P(err) to check this data type or not. * vm.c: catch up these changes. * vm_eval.c: ditto. * vm_insnhelper.c: ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49921 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
9d937bb086
commit
46cdb8f187
7 changed files with 90 additions and 39 deletions
16
ChangeLog
16
ChangeLog
|
@ -1,3 +1,19 @@
|
||||||
|
Wed Mar 11 03:21:37 2015 Koichi Sasada <ko1@atdot.net>
|
||||||
|
|
||||||
|
* vm_insnhelper.h: define struct THROW_DATA to represent
|
||||||
|
throwing data. Also define accessor functions.
|
||||||
|
|
||||||
|
* eval_intern.h: move related changes into vm_insnhelper.h.
|
||||||
|
Now these MACROs (functions) are only used in vm*.c.
|
||||||
|
|
||||||
|
There is only THROW_DATA_P(err) to check this data type or not.
|
||||||
|
|
||||||
|
* vm.c: catch up these changes.
|
||||||
|
|
||||||
|
* vm_eval.c: ditto.
|
||||||
|
|
||||||
|
* vm_insnhelper.c: ditto.
|
||||||
|
|
||||||
Wed Mar 11 00:57:00 2015 Rei Odaira <Rei.Odaira@gmail.com>
|
Wed Mar 11 00:57:00 2015 Rei Odaira <Rei.Odaira@gmail.com>
|
||||||
|
|
||||||
* test/rubygems/test_gem_security_trust_dir.rb: The return value of
|
* test/rubygems/test_gem_security_trust_dir.rb: The return value of
|
||||||
|
|
4
eval.c
4
eval.c
|
@ -215,7 +215,7 @@ ruby_cleanup(volatile int ex)
|
||||||
if (!RTEST(err)) continue;
|
if (!RTEST(err)) continue;
|
||||||
|
|
||||||
/* th->errinfo contains a NODE while break'ing */
|
/* th->errinfo contains a NODE while break'ing */
|
||||||
if (RB_TYPE_P(err, T_NODE)) continue;
|
if (THROW_DATA_P(err)) continue;
|
||||||
|
|
||||||
if (rb_obj_is_kind_of(err, rb_eSystemExit)) {
|
if (rb_obj_is_kind_of(err, rb_eSystemExit)) {
|
||||||
ex = sysexit_status(err);
|
ex = sysexit_status(err);
|
||||||
|
@ -1508,7 +1508,7 @@ errinfo_place(rb_thread_t *th)
|
||||||
return &cfp->ep[-2];
|
return &cfp->ep[-2];
|
||||||
}
|
}
|
||||||
else if (cfp->iseq->type == ISEQ_TYPE_ENSURE &&
|
else if (cfp->iseq->type == ISEQ_TYPE_ENSURE &&
|
||||||
!RB_TYPE_P(cfp->ep[-2], T_NODE) &&
|
!THROW_DATA_P(cfp->ep[-2]) &&
|
||||||
!FIXNUM_P(cfp->ep[-2])) {
|
!FIXNUM_P(cfp->ep[-2])) {
|
||||||
return &cfp->ep[-2];
|
return &cfp->ep[-2];
|
||||||
}
|
}
|
||||||
|
|
|
@ -199,16 +199,7 @@ enum ruby_tag_type {
|
||||||
#define TAG_FATAL RUBY_TAG_FATAL
|
#define TAG_FATAL RUBY_TAG_FATAL
|
||||||
#define TAG_MASK RUBY_TAG_MASK
|
#define TAG_MASK RUBY_TAG_MASK
|
||||||
|
|
||||||
#define NEW_THROW_OBJECT(val, pt, st) \
|
#define THROW_DATA_P(err) (BUILTIN_TYPE(err) == T_NODE)
|
||||||
((VALUE)rb_node_newnode(NODE_LIT, (VALUE)(val), (VALUE)(pt), (VALUE)(st)))
|
|
||||||
#define SET_THROWOBJ_CATCH_POINT(obj, val) \
|
|
||||||
(RNODE((obj))->u2.value = (val))
|
|
||||||
#define SET_THROWOBJ_STATE(obj, val) \
|
|
||||||
(RNODE((obj))->u3.value = (val))
|
|
||||||
|
|
||||||
#define GET_THROWOBJ_VAL(obj) ((VALUE)RNODE((obj))->u1.value)
|
|
||||||
#define GET_THROWOBJ_CATCH_POINT(obj) ((rb_control_frame_t*)RNODE((obj))->u2.value)
|
|
||||||
#define GET_THROWOBJ_STATE(obj) ((int)RNODE((obj))->u3.value)
|
|
||||||
|
|
||||||
#define SCOPE_TEST(f) (CREF_VISI(rb_vm_cref()) & (f))
|
#define SCOPE_TEST(f) (CREF_VISI(rb_vm_cref()) & (f))
|
||||||
#define SCOPE_CHECK(f) (CREF_VISI(rb_vm_cref()) == (f))
|
#define SCOPE_CHECK(f) (CREF_VISI(rb_vm_cref()) == (f))
|
||||||
|
|
35
vm.c
35
vm.c
|
@ -1179,7 +1179,7 @@ vm_iter_break(rb_thread_t *th, VALUE val)
|
||||||
rb_control_frame_t *target_cfp = rb_vm_search_cf_from_ep(th, cfp, ep);
|
rb_control_frame_t *target_cfp = rb_vm_search_cf_from_ep(th, cfp, ep);
|
||||||
|
|
||||||
th->state = TAG_BREAK;
|
th->state = TAG_BREAK;
|
||||||
th->errinfo = (VALUE)NEW_THROW_OBJECT(val, (VALUE)target_cfp, TAG_BREAK);
|
th->errinfo = (VALUE)NEW_THROW_DATA(val, target_cfp, TAG_BREAK);
|
||||||
TH_JUMP_TAG(th, TAG_BREAK);
|
TH_JUMP_TAG(th, TAG_BREAK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1422,8 +1422,9 @@ static VALUE
|
||||||
vm_exec(rb_thread_t *th)
|
vm_exec(rb_thread_t *th)
|
||||||
{
|
{
|
||||||
int state;
|
int state;
|
||||||
VALUE result, err;
|
VALUE result;
|
||||||
VALUE initial = 0;
|
VALUE initial = 0;
|
||||||
|
struct THROW_DATA *err;
|
||||||
|
|
||||||
TH_PUSH_TAG(th);
|
TH_PUSH_TAG(th);
|
||||||
_tag.retval = Qnil;
|
_tag.retval = Qnil;
|
||||||
|
@ -1431,7 +1432,7 @@ vm_exec(rb_thread_t *th)
|
||||||
vm_loop_start:
|
vm_loop_start:
|
||||||
result = vm_exec_core(th, initial);
|
result = vm_exec_core(th, initial);
|
||||||
if ((state = th->state) != 0) {
|
if ((state = th->state) != 0) {
|
||||||
err = result;
|
err = (struct THROW_DATA *)result;
|
||||||
th->state = 0;
|
th->state = 0;
|
||||||
goto exception_handler;
|
goto exception_handler;
|
||||||
}
|
}
|
||||||
|
@ -1444,9 +1445,9 @@ vm_exec(rb_thread_t *th)
|
||||||
VALUE catch_iseqval;
|
VALUE catch_iseqval;
|
||||||
rb_control_frame_t *cfp;
|
rb_control_frame_t *cfp;
|
||||||
VALUE type;
|
VALUE type;
|
||||||
rb_control_frame_t *escape_cfp;
|
const rb_control_frame_t *escape_cfp;
|
||||||
|
|
||||||
err = th->errinfo;
|
err = (struct THROW_DATA *)th->errinfo;
|
||||||
|
|
||||||
exception_handler:
|
exception_handler:
|
||||||
cont_pc = cont_sp = catch_iseqval = 0;
|
cont_pc = cont_sp = catch_iseqval = 0;
|
||||||
|
@ -1465,13 +1466,13 @@ vm_exec(rb_thread_t *th)
|
||||||
|
|
||||||
escape_cfp = NULL;
|
escape_cfp = NULL;
|
||||||
if (state == TAG_BREAK || state == TAG_RETURN) {
|
if (state == TAG_BREAK || state == TAG_RETURN) {
|
||||||
escape_cfp = GET_THROWOBJ_CATCH_POINT(err);
|
escape_cfp = THROW_DATA_CATCH_FRAME(err);
|
||||||
|
|
||||||
if (cfp == escape_cfp) {
|
if (cfp == escape_cfp) {
|
||||||
if (state == TAG_RETURN) {
|
if (state == TAG_RETURN) {
|
||||||
if (!VM_FRAME_TYPE_FINISH_P(cfp)) {
|
if (!VM_FRAME_TYPE_FINISH_P(cfp)) {
|
||||||
SET_THROWOBJ_CATCH_POINT(err, (VALUE)(cfp + 1));
|
THROW_DATA_CATCH_FRAME_SET(err, cfp + 1);
|
||||||
SET_THROWOBJ_STATE(err, state = TAG_BREAK);
|
THROW_DATA_STATE_SET(err, state = TAG_BREAK);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ct = cfp->iseq->catch_table;
|
ct = cfp->iseq->catch_table;
|
||||||
|
@ -1487,7 +1488,7 @@ vm_exec(rb_thread_t *th)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!catch_iseqval) {
|
if (!catch_iseqval) {
|
||||||
result = GET_THROWOBJ_VAL(err);
|
result = THROW_DATA_VAL(err);
|
||||||
th->errinfo = Qnil;
|
th->errinfo = Qnil;
|
||||||
|
|
||||||
switch (VM_FRAME_TYPE(cfp)) {
|
switch (VM_FRAME_TYPE(cfp)) {
|
||||||
|
@ -1505,9 +1506,9 @@ vm_exec(rb_thread_t *th)
|
||||||
else {
|
else {
|
||||||
/* TAG_BREAK */
|
/* TAG_BREAK */
|
||||||
#if OPT_STACK_CACHING
|
#if OPT_STACK_CACHING
|
||||||
initial = (GET_THROWOBJ_VAL(err));
|
initial = THROW_DATA_VAL(err);
|
||||||
#else
|
#else
|
||||||
*th->cfp->sp++ = (GET_THROWOBJ_VAL(err));
|
*th->cfp->sp++ = THROW_DATA_VAL(err);
|
||||||
#endif
|
#endif
|
||||||
th->errinfo = Qnil;
|
th->errinfo = Qnil;
|
||||||
goto vm_loop_start;
|
goto vm_loop_start;
|
||||||
|
@ -1544,8 +1545,8 @@ vm_exec(rb_thread_t *th)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (entry->type == CATCH_TYPE_RETRY) {
|
else if (entry->type == CATCH_TYPE_RETRY) {
|
||||||
rb_control_frame_t *escape_cfp;
|
const rb_control_frame_t *escape_cfp;
|
||||||
escape_cfp = GET_THROWOBJ_CATCH_POINT(err);
|
escape_cfp = THROW_DATA_CATCH_FRAME(err);
|
||||||
if (cfp == escape_cfp) {
|
if (cfp == escape_cfp) {
|
||||||
cfp->pc = cfp->iseq->iseq_encoded + entry->cont;
|
cfp->pc = cfp->iseq->iseq_encoded + entry->cont;
|
||||||
th->errinfo = Qnil;
|
th->errinfo = Qnil;
|
||||||
|
@ -1576,9 +1577,9 @@ vm_exec(rb_thread_t *th)
|
||||||
|
|
||||||
if (state != TAG_REDO) {
|
if (state != TAG_REDO) {
|
||||||
#if OPT_STACK_CACHING
|
#if OPT_STACK_CACHING
|
||||||
initial = (GET_THROWOBJ_VAL(err));
|
initial = THROW_DATA_VAL(err);
|
||||||
#else
|
#else
|
||||||
*th->cfp->sp++ = (GET_THROWOBJ_VAL(err));
|
*th->cfp->sp++ = THROW_DATA_VAL(err);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
th->errinfo = Qnil;
|
th->errinfo = Qnil;
|
||||||
|
@ -1622,7 +1623,7 @@ vm_exec(rb_thread_t *th)
|
||||||
cfp->pc = cfp->iseq->iseq_encoded + cont_pc;
|
cfp->pc = cfp->iseq->iseq_encoded + cont_pc;
|
||||||
|
|
||||||
/* push block frame */
|
/* push block frame */
|
||||||
cfp->sp[0] = err;
|
cfp->sp[0] = (VALUE)err;
|
||||||
vm_push_frame(th, catch_iseq, VM_FRAME_MAGIC_RESCUE,
|
vm_push_frame(th, catch_iseq, VM_FRAME_MAGIC_RESCUE,
|
||||||
cfp->self, cfp->klass,
|
cfp->self, cfp->klass,
|
||||||
VM_ENVVAL_PREV_EP_PTR(cfp->ep),
|
VM_ENVVAL_PREV_EP_PTR(cfp->ep),
|
||||||
|
@ -1662,7 +1663,7 @@ vm_exec(rb_thread_t *th)
|
||||||
|
|
||||||
if (VM_FRAME_TYPE_FINISH_P(th->cfp)) {
|
if (VM_FRAME_TYPE_FINISH_P(th->cfp)) {
|
||||||
vm_pop_frame(th);
|
vm_pop_frame(th);
|
||||||
th->errinfo = err;
|
th->errinfo = (VALUE)err;
|
||||||
TH_TMPPOP_TAG();
|
TH_TMPPOP_TAG();
|
||||||
JUMP_TAG(state);
|
JUMP_TAG(state);
|
||||||
}
|
}
|
||||||
|
|
10
vm_eval.c
10
vm_eval.c
|
@ -1130,15 +1130,15 @@ rb_iterate(VALUE (* it_proc) (VALUE), VALUE data1,
|
||||||
retval = (*it_proc) (data1);
|
retval = (*it_proc) (data1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
VALUE err = th->errinfo;
|
const struct THROW_DATA *err = (struct THROW_DATA *)th->errinfo;
|
||||||
if (state == TAG_BREAK) {
|
if (state == TAG_BREAK) {
|
||||||
rb_control_frame_t *escape_cfp = GET_THROWOBJ_CATCH_POINT(err);
|
const rb_control_frame_t *escape_cfp = THROW_DATA_CATCH_FRAME(err);
|
||||||
|
|
||||||
if (cfp == escape_cfp) {
|
if (cfp == escape_cfp) {
|
||||||
state = 0;
|
state = 0;
|
||||||
th->state = 0;
|
th->state = 0;
|
||||||
th->errinfo = Qnil;
|
th->errinfo = Qnil;
|
||||||
retval = GET_THROWOBJ_VAL(err);
|
retval = THROW_DATA_VAL(err);
|
||||||
|
|
||||||
rb_vm_rewind_cfp(th, cfp);
|
rb_vm_rewind_cfp(th, cfp);
|
||||||
}
|
}
|
||||||
|
@ -1147,7 +1147,7 @@ rb_iterate(VALUE (* it_proc) (VALUE), VALUE data1,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (state == TAG_RETRY) {
|
else if (state == TAG_RETRY) {
|
||||||
rb_control_frame_t *escape_cfp = GET_THROWOBJ_CATCH_POINT(err);
|
const rb_control_frame_t *escape_cfp = THROW_DATA_CATCH_FRAME(err);
|
||||||
|
|
||||||
if (cfp == escape_cfp) {
|
if (cfp == escape_cfp) {
|
||||||
rb_vm_rewind_cfp(th, cfp);
|
rb_vm_rewind_cfp(th, cfp);
|
||||||
|
@ -1878,8 +1878,8 @@ rb_throw_obj(VALUE tag, VALUE value)
|
||||||
desc[2] = rb_str_new_cstr("uncaught throw %p");
|
desc[2] = rb_str_new_cstr("uncaught throw %p");
|
||||||
rb_exc_raise(rb_class_new_instance(numberof(desc), desc, rb_eUncaughtThrow));
|
rb_exc_raise(rb_class_new_instance(numberof(desc), desc, rb_eUncaughtThrow));
|
||||||
}
|
}
|
||||||
th->errinfo = NEW_THROW_OBJECT(tag, 0, TAG_THROW);
|
|
||||||
|
|
||||||
|
th->errinfo = (VALUE)NEW_THROW_DATA(tag, NULL, TAG_THROW);
|
||||||
JUMP_TAG(TAG_THROW);
|
JUMP_TAG(TAG_THROW);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -627,10 +627,9 @@ vm_setinstancevariable(VALUE obj, ID id, VALUE val, IC ic)
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
vm_throw_continue(rb_thread_t *th, VALUE throwobj)
|
vm_throw_continue(rb_thread_t *th, VALUE err)
|
||||||
{
|
{
|
||||||
/* continue throw */
|
/* continue throw */
|
||||||
VALUE err = throwobj;
|
|
||||||
|
|
||||||
if (FIXNUM_P(err)) {
|
if (FIXNUM_P(err)) {
|
||||||
th->state = FIX2INT(err);
|
th->state = FIX2INT(err);
|
||||||
|
@ -638,8 +637,8 @@ vm_throw_continue(rb_thread_t *th, VALUE throwobj)
|
||||||
else if (SYMBOL_P(err)) {
|
else if (SYMBOL_P(err)) {
|
||||||
th->state = TAG_THROW;
|
th->state = TAG_THROW;
|
||||||
}
|
}
|
||||||
else if (BUILTIN_TYPE(err) == T_NODE) {
|
else if (THROW_DATA_P(err)) {
|
||||||
th->state = GET_THROWOBJ_STATE(err);
|
th->state = THROW_DATA_STATE((struct THROW_DATA *)err);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
th->state = TAG_RAISE;
|
th->state = TAG_RAISE;
|
||||||
|
@ -778,7 +777,7 @@ vm_throw_start(rb_thread_t * const th, rb_control_frame_t * const reg_cfp, int s
|
||||||
}
|
}
|
||||||
|
|
||||||
th->state = state;
|
th->state = state;
|
||||||
return (VALUE)NEW_THROW_OBJECT(throwobj, (VALUE)escape_cfp, state);
|
return (VALUE)NEW_THROW_DATA(throwobj, escape_cfp, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
|
|
|
@ -239,4 +239,48 @@ struct SVAR {
|
||||||
VALUE others;
|
VALUE others;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct THROW_DATA {
|
||||||
|
VALUE flags;
|
||||||
|
VALUE reserved;
|
||||||
|
VALUE throw_obj;
|
||||||
|
const rb_control_frame_t *catch_frame;
|
||||||
|
VALUE throw_state;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline struct THROW_DATA *
|
||||||
|
NEW_THROW_DATA(VALUE val, rb_control_frame_t *cf, VALUE st)
|
||||||
|
{
|
||||||
|
return (struct THROW_DATA *)rb_node_newnode(NODE_LIT, val, (VALUE)cf, st);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
THROW_DATA_CATCH_FRAME_SET(struct THROW_DATA *obj, const rb_control_frame_t *cfp)
|
||||||
|
{
|
||||||
|
obj->catch_frame = cfp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
THROW_DATA_STATE_SET(struct THROW_DATA *obj, VALUE st)
|
||||||
|
{
|
||||||
|
obj->throw_state = st;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline VALUE
|
||||||
|
THROW_DATA_VAL(const struct THROW_DATA *obj)
|
||||||
|
{
|
||||||
|
return obj->throw_obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline const rb_control_frame_t *
|
||||||
|
THROW_DATA_CATCH_FRAME(const struct THROW_DATA *obj)
|
||||||
|
{
|
||||||
|
return obj->catch_frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
THROW_DATA_STATE(const struct THROW_DATA *obj)
|
||||||
|
{
|
||||||
|
return obj->throw_state;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* RUBY_INSNHELPER_H */
|
#endif /* RUBY_INSNHELPER_H */
|
||||||
|
|
Loading…
Reference in a new issue