[#30549] [ANN] Ruby 1.8.6 has been released — "Akinori MUSHA" <knu@...>

 Ruby 1.8.6 をリリースしました。

14 messages 2007/03/12

[#30553] help: lib/shell for ruby 1.9 — keiju@... (Keiju ISHITSUKA)

けいじゅ@いしつかです.

13 messages 2007/03/13
[#30585] Re: help: lib/shell for ruby 1.9 — Yukihiro Matsumoto <matz@...> 2007/03/15

まつもと ゆきひろです

[#30587] Re: help: lib/shell for ruby 1.9 — keiju@... (石塚圭樹) 2007/03/15

けいじゅ@いしつかです.

[#30588] Re: help: lib/shell for ruby 1.9 — Yukihiro Matsumoto <matz@...> 2007/03/15

まつもと ゆきひろです

[ruby-dev:30551] rb_rescue2 with vm

From: wanabe <s.wanabe@...>
Date: 2007-03-13 05:36:16 UTC
List: ruby-dev #30551
はじめまして、ワナベと申します。

1.9 の rb_rescue2 を読んでいて xxx_TAG 系統の連続で読みにくかったので
実験的に VM を使った形にしてみました。
# あくまで実験なのでバックトレース等は考慮していません。

もともとの動機の、moriq さんの日記にあった Zlib::GzipReader の動作不良は
( http://moriq.tdiary.net/20070309.html )
手元で確認した限りでは解消されています。

1.9 の方向性としてはこういうのはありなんでしょうか。
速度・メモリのコストを考えると現状のほうがよさそうですが、
保守の面からは VM を多用したほうが処理も分散せず、個人的には好きです。



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 関数ポインタが示す関数をコールする
+ */
+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)

-- 
ワナベ

In This Thread

Prev Next