Rb_rescue2 with vm

e$B$O$8$a$^$7$F!"%o%J%Y$H?=$7$^$9!#e(B

1.9 e$B$Ne(B rb_rescue2 e$B$rFI$s$G$$$Fe(B xxx_TAG
e$B7OE}$NO"B3$GFI$$K$/$+$C$?$N$Ge(B
e$B<B83E*$Ke(B VM e$B$r;H$C$?7A$K$7$F$
$^$7$?!#e(B

e$B$"$/$^$G<B83$J$N$G%P%C%/%H%l!<%9Ey$O9MN8$7$F$$$^$;$s!#e(B

e$B$b$H$b$H$NF05!$N!“e(Bmoriq e$B$5$s$NF|5-$K$”$C$?e(B Zlib::GzipReader
e$B$NF0:nITNI$Oe(B
e$B!Je(B http://moriq.tdiary.net/20070309.html e$B!Ke(B
e$B<j85$G3NG’$7$?8B$j$G$O2r>C$5$l$F$$$^$9!#e(B

1.9 e$B$NJ}8~@-$H$7$F$O$3$&$$$&$N$O$"$j$J$s$G$7$g$&$+!#e(B
e$BB.EY!&%a%b%j$N%3%9%H$r9M$($k$H8=>u$N$[$&$,$h$5$=$&$G$9$,!"e(B
e$BJ]<i$NLL$+$i$Oe(B VM
e$B$rB?MQ$7$?$[$&$,=hM}$bJ,;6$;$:!"8D?ME*$K$O9%$-$G$9!#e(B

Index: compile.c

— compile.c (revision 12030)
+++ compile.c (working copy)
@@ -3679,6 +3679,7 @@
VALUE argc;
VALUE flag = 0;
VALUE parent_block = iseq->compile_data->current_block;

  • int is_cfcall = (node->nd_tval == 0);
    iseq->compile_data->current_block = Qfalse;

#if SUPPORT_JOKE
@@ -3736,7 +3737,7 @@
if (type == NODE_CALL) {
COMPILE(recv, “recv”, node->nd_recv);
}

  • else if (type == NODE_FCALL || type == NODE_VCALL) {
  • else if (!is_cfcall && (type == NODE_FCALL || type == NODE_VCALL))
    {
    ADD_CALL_RECEIVER(recv, nd_line(node));
    }

@@ -3748,10 +3749,17 @@
argc = INT2FIX(0);
}

  • debugp_param(“call args argc”, argc);
  • if (is_cfcall) {
  •    debugp_param("call cfunc", node->nd_cfnc);
    
  •    ADD_SEQ(ret, args);
    
  •    ADD_INSN1(ret, nd_line(node), cfcall, node->nd_cfnc);
    
  •    break;
    
  • }
    ADD_SEQ(ret, recv);
    ADD_SEQ(ret, args);
  • debugp_param(“call args argc”, argc);
    debugp_param(“call method”, ID2SYM(mid));

    switch (nd_type(node)) {
    Index: eval.c
    ===================================================================
    — eval.c (revision 12030)
    +++ eval.c (working copy)
    @@ -1326,56 +1326,29 @@
    rb_rescue2(VALUE (*b_proc) (ANYARGS), VALUE data1, VALUE (*r_proc)
    (ANYARGS),
    VALUE data2, …)
    {

  • int state;

  • volatile VALUE result;

  • volatile VALUE e_info = GET_THREAD()->errinfo;
    va_list args;

  • PUSH_TAG(PROT_NONE);

  • if ((state = EXEC_TAG()) == 0) {

  •  retry_entry:
    
  • result = (*b_proc) (data1);

  • int len = 0;
  • VALUE eclass;
  • NODE *r_node = 0;
  • NODE *rb_node = 0;
  • NODE *e_node = 0;
  • NODE *b_node = NEW_CFCALL(INT2NUM(b_proc),
    NEW_ARRAY(NEW_LIT(data1)));
  • if(r_proc != 0) {
  • r_node = NEW_CFCALL(INT2NUM(r_proc), NEW_ARRAY(NEW_LIT(data2)));
    }
  • else if (state == TAG_RAISE) {
  • int handle = Qfalse;
  • VALUE eclass;
  • va_init_list(args, data2);
  • while (eclass = va_arg(args, VALUE)) {
  •  if (rb_obj_is_kind_of(GET_THREAD()->errinfo, eclass)) {
    
  • handle = Qtrue;
  • break;
  •  }
    
  • }
  • va_end(args);
  • if (handle) {
  •  if (r_proc) {
    
  • PUSH_TAG(PROT_NONE);
  • if ((state = EXEC_TAG()) == 0) {
  •    result = (*r_proc) (data2, GET_THREAD()->errinfo);
    
  • }
  • POP_TAG();
  • if (state == TAG_RETRY) {
  •    state = 0;
    
  •    GET_THREAD()->errinfo = Qnil;
    
  •    goto retry_entry;
    
  • }
  •  }
    
  •  else {
    
  • result = Qnil;
  • state = 0;
  •  }
    
  •  if (state == 0) {
    
  • GET_THREAD()->errinfo = e_info;
  •  }
    
  • }
  • rb_node = NEW_RESBODY(0, r_node, 0);
  • va_init_list(args, data2);
  • while (eclass = va_arg(args, VALUE)) {
  • NODE *n = NEW_ARRAY(NEW_LIT(eclass));
  • n->nd_next = e_node;
  • n->nd_alen = ++len;
  • e_node = n;
    }
  • POP_TAG();
  • if (state)
  • JUMP_TAG(state);
  • va_end(args);
  • return result;
  • rb_node->nd_args = e_node;
  • return yarvcore_eval_parsed(NEW_RESCUE(b_node, rb_node, 0),
    rb_str_new2(“in rb_rescue”));
    }

VALUE
Index: insns.def

— insns.def (revision 12030)
+++ insns.def (working copy)
@@ -2425,3 +2425,18 @@
ret = INT2FIX(42);
}

+/**

  • @c call
  • @e call the function using function pointer
  • @j e$B4X?t%]%$%s%?$,<($94X?t$r%3!<%k$9$ke(B
  • */
    +DEFINE_INSN
    +cfcall
    +(VALUE ptr)
    +(VALUE arg)
    +(VALUE ret)
    +{
  • VALUE (*func)(ANYARGS) = NUM2INT(ptr);
  • ret = func(arg);
    +}

Index: node.h

— node.h (revision 12030)
+++ node.h (working copy)
@@ -316,6 +316,7 @@
#define NEW_EVSTR(n) NEW_NODE(NODE_EVSTR,0,(n),0)
#define NEW_CALL(r,m,a) NEW_NODE(NODE_CALL,r,m,a)
#define NEW_FCALL(m,a) NEW_NODE(NODE_FCALL,0,m,a)
+#define NEW_CFCALL(p,a) NEW_NODE(NODE_FCALL,p,0,a)
#define NEW_VCALL(m) NEW_NODE(NODE_VCALL,0,m,0)
#define NEW_SUPER(a) NEW_NODE(NODE_SUPER,0,0,a)
#define NEW_ZSUPER() NEW_NODE(NODE_ZSUPER,0,0,0)

e$B%o%J%Y$G$9!#e(B

VM e$B$KMj$i$:$H$be(B Zlib::GzipReader
e$B$NF0:nITNI$r2r7h$G$-$?$N$G%Q%C%A$rAw$j$^$9!#e(B

Index: eval.c

— eval.c (revision 12066)
+++ eval.c (working copy)
@@ -1340,6 +1340,7 @@
int handle = Qfalse;
VALUE eclass;

  • GET_THREAD()->cfp++;
    va_init_list(args, data2);
    while (eclass = va_arg(args, VALUE)) {
    if (rb_obj_is_kind_of(GET_THREAD()->errinfo, eclass)) {
    @@ -2732,7 +2733,7 @@
    VALUE
    rb_errinfo(void)
    {
  • return get_errinfo();
  • return GET_THREAD()->errinfo;
    }

static void

e$B!!$5$5$@$G$9!%e(B

e$B!!$3$A$i$bCY$/$J$C$F$7$^$C$F$9$_$^$;$s!%e(B

wanabe wrote:

e$B%o%J%Y$G$9!#e(B

VM e$B$KMj$i$:$H$be(B Zlib::GzipReader e$B$NF0:nITNI$r2r7h$G$-$?$N$G%Q%C%A$rAw$je(B
e$B$^$9!#e(B

e$B!!$3$A$i$b!$$5$C$-$H:,$,F1$8!Je(Bcfp
e$B$rLa$7$F$$$J$$$N$,LdBj!K$@$H;W$$$^$7e(B
e$B$?!%$=$N$h$&$K=$@5$7$^$9!%$4;XE&$"$j$,$H$&$4$6$$$^$7$?!%e(Berrinfo
e$B$N$[$&e(B
e$B$O!$$A$g$C$H$o$+$i$J$+$C$?$s$G$9$,!$$3$l$O$^$:$$$G$7$g$&$+!%e(B

e$B!!$H$3$m$G!$85$N%a!<%k$K$"$C$?e(BCe$B4X?t$r8F$S=P$9$b$N$G$9$,!$e(BJIT/AOTe$B%3%s%Q%$e(B
e$B%i$N%$%s%?!<%U%’!<%9$H$7$FMQ0U$7$h$&$H;W$C$F$$$^$9!%e(B