[前][次][番号順一覧][スレッド一覧][生データ]

yarv-diff:139

From: ko1 atdot.net
Date: 28 Nov 2005 00:10:31 -0000
Subject: [yarv-diff:139] r298 - in trunk: . benchmark lib yarvtest

Author: ko1
Date: 2005-11-28 09:10:29 +0900 (Mon, 28 Nov 2005)
New Revision: 298

Added:
   trunk/lib/tempfile.rb
   trunk/lib/tmpdir.rb
Modified:
   trunk/ChangeLog
   trunk/benchmark/bmx_temp.rb
   trunk/compile.c
   trunk/eval_intern.h
   trunk/eval_method.h
   trunk/eval_thread.c
   trunk/insns.def
   trunk/string.c
   trunk/test.rb
   trunk/time.c
   trunk/vm.c
   trunk/vm_evalbody.h
   trunk/vm_macro.def
   trunk/yarvcore.c
   trunk/yarvcore.h
   trunk/yarvtest/test_class.rb
Log:
	* compile.c, insns.def, vm_evalbody.h : support super
	with splat argument and block (and zsuper with block)

	* yarvtest/test_class.rb : add tests for above

	* compile.c, yarvcore.h, yarvcore.c, insns.def, time.c, string.c :
	add opt_succ insn

	* eval_method.h : fix indent

	* eval_thread.c : apply cast to vanish a warning

	* lib/tempfile.rb, lib/tmpdir.rb : added

	* vm.c : eval_method_missing added

	* vm_macro.def : refactoring



Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2005-11-21 12:22:32 UTC (rev 297)
+++ trunk/ChangeLog	2005-11-28 00:10:29 UTC (rev 298)
@@ -4,7 +4,27 @@
 #  from Mon, 03 May 2004 01:24:19 +0900
 #
 
+2005-11-28(Mon) 09:02:57 +0900  Koichi Sasada  <ko1 atdot.net>
 
+	* compile.c, insns.def, vm_evalbody.h : support super
+	with splat argument and block (and zsuper with block)
+
+	* yarvtest/test_class.rb : add tests for above
+
+	* compile.c, yarvcore.h, yarvcore.c, insns.def, time.c, string.c :
+	add opt_succ insn
+
+	* eval_method.h : fix indent
+
+	* eval_thread.c : apply cast to vanish a warning
+
+	* lib/tempfile.rb, lib/tmpdir.rb : added
+
+	* vm.c : eval_method_missing added
+
+	* vm_macro.def : refactoring
+
+
 2005-11-21(Mon) 21:21:33 +0900  Koichi Sasada  <ko1 atdot.net>
 
 	* compile.c, compile.h, yarvcore.c : remove "iseqobj"

Modified: trunk/benchmark/bmx_temp.rb
===================================================================
--- trunk/benchmark/bmx_temp.rb	2005-11-21 12:22:32 UTC (rev 297)
+++ trunk/benchmark/bmx_temp.rb	2005-11-28 00:10:29 UTC (rev 298)
@@ -1 +1,17 @@
-0
+
+
+
+__END__
+class Integer
+  def times_
+    i=0
+    while i<self
+      yield(i)
+      i = i.succ
+    end
+  end
+end
+
+10000000.times{}
+
+

Modified: trunk/compile.c
===================================================================
--- trunk/compile.c	2005-11-21 12:22:32 UTC (rev 297)
+++ trunk/compile.c	2005-11-28 00:10:29 UTC (rev 298)
@@ -654,6 +654,9 @@
       if(mid == idLength){
         iobj = new_insn_body(iseq, line_no, BIN(opt_length), 0);
       }
+      else if(mid == idSucc){
+        iobj = new_insn_body(iseq, line_no, BIN(opt_succ), 0);
+      }
     }
     else if(argc == I2F(2)){
       if(mid == idASET){
@@ -789,7 +792,7 @@
   static ID id_dollar_bang;
 
   if(!id_dollar_bang){
-    id_dollar_bang = rb_intern("$!");
+    id_dollar_bang = rb_intern("__$!");
   }
   iseq->local_tbl = (ID*)ALLOC_N(ID*, 1);
   iseq->local_size = 1;
@@ -3125,20 +3128,20 @@
      */
     DECL_ANCHOR(recv);
     DECL_ANCHOR(args);
+    ID mid = node->nd_mid;
     VALUE argc;
     VALUE flag  = 0;
     VALUE block = 0;
     VALUE parent_block = iseq->compile_data->current_block;
     iseq->compile_data->current_block = Qfalse;
-
     
 #if SUPPORT_JOKE
     if(nd_type(node) == NODE_VCALL){
-      if(node->nd_mid ==idBitblt){
+      if(mid ==idBitblt){
         ADD_INSN(ret, nd_line(node), bitblt);
         break;
       }
-      else if(node->nd_mid == idAnswer){
+      else if(mid == idAnswer){
         ADD_INSN(ret, nd_line(node), answer);
         break;
       }
@@ -3156,7 +3159,7 @@
       }
       
       if(nd_type(node) == NODE_FCALL &&
-         (node->nd_mid == goto_id || node->nd_mid == label_id)){
+         (mid == goto_id || mid == label_id)){
         if(nd_type(node->nd_args->nd_head) == NODE_LIT &&
            SYMBOL_P(node->nd_args->nd_head->nd_lit)){
 
@@ -3171,7 +3174,7 @@
         }
         
         
-        if(node->nd_mid == goto_id){
+        if(mid == goto_id){
           ADD_INSNL(ret, nd_line(node), jump, label);
         }
         else{
@@ -3181,7 +3184,6 @@
       }
     }
 #endif
-
     /* reciever */
     if(type == NODE_CALL){
       COMPILE(recv, "recv", node->nd_recv);
@@ -3237,7 +3239,7 @@
     }
 
     debugp_param("call args argc", argc);
-    debugp_param("call method",    ID2SYM(node->nd_mid));
+    debugp_param("call method",    ID2SYM(mid));
 
     switch(nd_type(node)){
     NODE_VCALL:
@@ -3247,7 +3249,7 @@
       flag |= VM_CALL_FCALL_BIT;
     }
     
-    ADD_SEND_R(ret, nd_line(node), ID2SYM(node->nd_mid), argc,
+    ADD_SEND_R(ret, nd_line(node), ID2SYM(mid), argc,
                block, I2F(flag));
     
     if(poped){
@@ -3259,6 +3261,9 @@
     DECL_ANCHOR(args);
     VALUE argc;
     VALUE flag = 0;
+    VALUE block = 0;
+    VALUE parent_block = iseq->compile_data->current_block;
+    iseq->compile_data->current_block = Qfalse;
     
     /* args */
     if(type != NODE_VCALL && node->nd_args){
@@ -3284,19 +3289,45 @@
     else{
       argc = I2F(0);
     }
-
+    
     ADD_INSN(ret, nd_line(node), putnil); /* dummy reciever */
     ADD_SEQ(ret, args);
-    ADD_INSN2(ret, nd_line(node), super, argc, I2F(flag));
 
+    /* block */
+    if(parent_block){
+      if(parent_block & 1){
+        flag |= VM_CALL_ARGS_BLOCKARG_BIT;
+        //dump_disasm_list((LINK_ANCHOR *)(parent_block & (~1)));
+        ADD_SEQ(ret, (LINK_ANCHOR *)(parent_block & (~1)));
+      }
+      else{
+        block = parent_block;
+      }
+    }
+    
+    ADD_INSN3(ret, nd_line(node), super, argc, block, I2F(flag));
+
     if(poped){
       ADD_INSN(ret, nd_line(node), pop);
     }
     break;
   }
   case NODE_ZSUPER:{
-    ADD_INSN(ret, nd_line(node), zsuper);
+    VALUE block = 0;
+    VALUE parent_block = iseq->compile_data->current_block;
+    
+    /* block */
+    if(parent_block){
+      if(parent_block & 1){
+        rb_bug("zsuper with blockval");
+      }
+      else{
+        block = parent_block;
+      }
+    }
 
+    ADD_INSN1(ret, nd_line(node), zsuper, block);
+
     if(poped){
       ADD_INSN(ret, nd_line(node), pop);
     }

Modified: trunk/eval_intern.h
===================================================================
--- trunk/eval_intern.h	2005-11-21 12:22:32 UTC (rev 297)
+++ trunk/eval_intern.h	2005-11-28 00:10:29 UTC (rev 298)
@@ -248,8 +248,8 @@
 #define SCOPE_PROTECTED 2
 #define SCOPE_MODFUNC   5
 #define SCOPE_MASK      7
-#define SCOPE_SET(f)  (scope_vmode=(f))
-#define SCOPE_TEST(f) (scope_vmode&(f))
+#define SCOPE_SET(f)  (f)
+#define SCOPE_TEST(f) (0&(f))
 
 struct ruby_env {
     struct ruby_env *prev;

Modified: trunk/eval_method.h
===================================================================
--- trunk/eval_method.h	2005-11-21 12:22:32 UTC (rev 297)
+++ trunk/eval_method.h	2005-11-28 00:10:29 UTC (rev 298)
@@ -21,244 +21,228 @@
 void
 rb_clear_cache()
 {
-   struct cache_entry *ent, *end;
+  struct cache_entry *ent, *end;
 
-    if (!ruby_running) return;
-    ent = cache; end = ent + CACHE_SIZE;
-    while (ent < end) {
-	ent->mid = 0;
-	ent++;
-    }
+  if (!ruby_running) return;
+  ent = cache; end = ent + CACHE_SIZE;
+  while (ent < end) {
+    ent->mid = 0;
+    ent++;
+  }
 }
 
 static void
-rb_clear_cache_for_undef(klass, id)
-    VALUE klass;
-    ID id;
+rb_clear_cache_for_undef(VALUE klass, ID id)
 {
-    struct cache_entry *ent, *end;
+  struct cache_entry *ent, *end;
 
-    if (!ruby_running) return;
-    ent = cache; end = ent + CACHE_SIZE;
-    while (ent < end) {
-	if (ent->origin == klass && ent->mid == id) {
-	    ent->mid = 0;
-	}
-	ent++;
+  if (!ruby_running) return;
+  ent = cache; end = ent + CACHE_SIZE;
+  while (ent < end) {
+    if (ent->origin == klass && ent->mid == id) {
+      ent->mid = 0;
     }
+    ent++;
+  }
 }
 
 static void
-rb_clear_cache_by_id(id)
-    ID id;
+rb_clear_cache_by_id(ID id)
 {
-    struct cache_entry *ent, *end;
+  struct cache_entry *ent, *end;
 
-    if (!ruby_running) return;
-    ent = cache; end = ent + CACHE_SIZE;
-    while (ent < end) {
-	if (ent->mid == id) {
-	    ent->mid = 0;
-	}
-	ent++;
+  if (!ruby_running) return;
+  ent = cache; end = ent + CACHE_SIZE;
+  while (ent < end) {
+    if (ent->mid == id) {
+      ent->mid = 0;
     }
+    ent++;
+  }
 }
 
 void
-rb_clear_cache_by_class(klass)
-    VALUE klass;
+rb_clear_cache_by_class(VALUE klass)
 {
-    struct cache_entry *ent, *end;
+  struct cache_entry *ent, *end;
 
-    if (!ruby_running) return;
-    ent = cache; end = ent + CACHE_SIZE;
-    while (ent < end) {
-	if (ent->klass == klass || ent->origin == klass) {
-	    ent->mid = 0;
-	}
-	ent++;
+  if (!ruby_running) return;
+  ent = cache; end = ent + CACHE_SIZE;
+  while (ent < end) {
+    if (ent->klass == klass || ent->origin == klass) {
+      ent->mid = 0;
     }
+    ent++;
+  }
 }
 
 
 void
-rb_add_method(klass, mid, node, noex)
-    VALUE klass;
-    ID mid;
-    NODE *node;
-    int noex;
+rb_add_method(VALUE klass, ID mid, NODE* node, int noex)
 {
-    NODE *body;
+  NODE *body;
 
-    if (NIL_P(klass)) klass = rb_cObject;
-    if (ruby_safe_level >= 4 && (klass == rb_cObject || !OBJ_TAINTED(klass))) {
-	rb_raise(rb_eSecurityError, "Insecure: can't define method");
+  if (NIL_P(klass)){
+    klass = rb_cObject;
+  }
+  if (ruby_safe_level >= 4 && (klass == rb_cObject || !OBJ_TAINTED(klass))) {
+    rb_raise(rb_eSecurityError, "Insecure: can't define method");
+  }
+  if (!FL_TEST(klass, FL_SINGLETON) &&
+      node && nd_type(node) != NODE_ZSUPER &&
+      (mid == rb_intern("initialize" )|| mid == rb_intern("initialize_copy"))) {
+    noex = NOEX_PRIVATE | noex;
+  }
+  else if (FL_TEST(klass, FL_SINGLETON) && node && nd_type(node) == NODE_CFUNC &&
+           mid == rb_intern("allocate")) {
+    rb_warn("defining %s.allocate is deprecated; use rb_define_alloc_func()",
+            rb_class2name(rb_iv_get(klass, "__attached__")));
+    mid = ID_ALLOCATOR;
+  }
+  if (OBJ_FROZEN(klass)){
+    rb_error_frozen("class/module");
+  }
+  rb_clear_cache_by_id(mid);
+  body = NEW_METHOD(node, noex);
+  st_insert(RCLASS(klass)->m_tbl, mid, (st_data_t)body);
+  if (node && mid != ID_ALLOCATOR && ruby_running) {
+    if (FL_TEST(klass, FL_SINGLETON)) {
+      rb_funcall(rb_iv_get(klass, "__attached__"), singleton_added, 1, ID2SYM(mid));
     }
-    if (!FL_TEST(klass, FL_SINGLETON) &&
-	node && nd_type(node) != NODE_ZSUPER &&
-	(mid == rb_intern("initialize" )|| mid == rb_intern("initialize_copy"))) {
-	noex = NOEX_PRIVATE | noex;
+    else {
+      rb_funcall(klass, added, 1, ID2SYM(mid));
     }
-    else if (FL_TEST(klass, FL_SINGLETON) && node && nd_type(node) == NODE_CFUNC &&
-	     mid == rb_intern("allocate")) {
-	rb_warn("defining %s.allocate is deprecated; use rb_define_alloc_func()",
-		rb_class2name(rb_iv_get(klass, "__attached__")));
-	mid = ID_ALLOCATOR;
-    }
-    if (OBJ_FROZEN(klass)) rb_error_frozen("class/module");
-    rb_clear_cache_by_id(mid);
-    body = NEW_METHOD(node, noex);
-    st_insert(RCLASS(klass)->m_tbl, mid, (st_data_t)body);
-    if (node && mid != ID_ALLOCATOR && ruby_running) {
-	if (FL_TEST(klass, FL_SINGLETON)) {
-	    rb_funcall(rb_iv_get(klass, "__attached__"), singleton_added, 1, ID2SYM(mid));
-	}
-	else {
-	    rb_funcall(klass, added, 1, ID2SYM(mid));
-	}
-    }
+  }
 }
 
 void
-rb_define_alloc_func(klass, func)
-    VALUE klass;
-    VALUE (*func) _((VALUE));
+rb_define_alloc_func(VALUE klass, VALUE (*func) _((VALUE)))
 {
-    Check_Type(klass, T_CLASS);
-    rb_add_method(CLASS_OF(klass), ID_ALLOCATOR, NEW_CFUNC(func, 0), NOEX_PRIVATE);
+  Check_Type(klass, T_CLASS);
+  rb_add_method(CLASS_OF(klass), ID_ALLOCATOR, NEW_CFUNC(func, 0), NOEX_PRIVATE);
 }
 
 void
-rb_undef_alloc_func(klass)
-    VALUE klass;
+rb_undef_alloc_func(VALUE klass)
 {
-    Check_Type(klass, T_CLASS);
-    rb_add_method(CLASS_OF(klass), ID_ALLOCATOR, 0, NOEX_UNDEF);
+  Check_Type(klass, T_CLASS);
+  rb_add_method(CLASS_OF(klass), ID_ALLOCATOR, 0, NOEX_UNDEF);
 }
 
 static NODE*
-search_method(klass, id, origin)
-    VALUE klass, *origin;
-    ID id;
+search_method(VALUE klass, ID id, VALUE *origin)
 {
-    NODE *body;
+  NODE *body;
 
+  if (!klass) return 0;
+  while (!st_lookup(RCLASS(klass)->m_tbl, id, (st_data_t *)&body)) {
+    klass = RCLASS(klass)->super;
     if (!klass) return 0;
-    while (!st_lookup(RCLASS(klass)->m_tbl, id, (st_data_t *)&body)) {
-	klass = RCLASS(klass)->super;
-	if (!klass) return 0;
-    }
+  }
 
-    if (origin) *origin = klass;
-    return body;
+  if (origin) *origin = klass;
+  return body;
 }
 
 NODE*
-rb_get_method_body(klassp, idp, noexp)
-    VALUE *klassp;
-    ID *idp;
-    int *noexp;
+rb_get_method_body(VALUE *klassp, ID *idp, int *noexp)
 {
-    ID id = *idp;
-    VALUE klass = *klassp;
-    VALUE origin;
-    NODE * volatile body;
-    struct cache_entry *ent;
+  ID id = *idp;
+  VALUE klass = *klassp;
+  VALUE origin;
+  NODE * volatile body;
+  struct cache_entry *ent;
 
-    if ((body = search_method(klass, id, &origin)) == 0 || !body->nd_body) {
-	/* store empty info in cache */
-	ent = cache + EXPR1(klass, id);
-	ent->klass  = klass;
-	ent->origin = klass;
-	ent->mid = ent->mid0 = id;
-	ent->noex   = 0;
-	ent->method = 0;
+  if ((body = search_method(klass, id, &origin)) == 0 || !body->nd_body) {
+    /* store empty info in cache */
+    ent = cache + EXPR1(klass, id);
+    ent->klass  = klass;
+    ent->origin = klass;
+    ent->mid = ent->mid0 = id;
+    ent->noex   = 0;
+    ent->method = 0;
 
-	return 0;
-    }
+    return 0;
+  }
 
-    if (ruby_running) {
-	/* store in cache */
-	ent = cache + EXPR1(klass, id);
-	ent->klass  = klass;
-	ent->noex   = body->nd_noex;
-	if (noexp) *noexp = body->nd_noex;
-	body = body->nd_body;
-	if (nd_type(body) == NODE_FBODY) {
-	    ent->mid = id;
-	    *klassp = body->nd_orig;
-	    ent->origin = body->nd_orig;
-	    *idp = ent->mid0 = body->nd_mid;
-	    body = ent->method = body->nd_head;
-	}
-	else {
-	    *klassp = origin;
-	    ent->origin = origin;
-	    ent->mid = ent->mid0 = id;
-	    ent->method = body;
-	}
+  if (ruby_running) {
+    /* store in cache */
+    ent = cache + EXPR1(klass, id);
+    ent->klass  = klass;
+    ent->noex   = body->nd_noex;
+    if (noexp) *noexp = body->nd_noex;
+    body = body->nd_body;
+    if (nd_type(body) == NODE_FBODY) {
+      ent->mid = id;
+      *klassp = body->nd_orig;
+      ent->origin = body->nd_orig;
+      *idp = ent->mid0 = body->nd_mid;
+      body = ent->method = body->nd_head;
     }
     else {
-	if (noexp) *noexp = body->nd_noex;
-	body = body->nd_body;
-	if (nd_type(body) == NODE_FBODY) {
-	    *klassp = body->nd_orig;
-	    *idp = body->nd_mid;
-	    body = body->nd_head;
-	}
-	else {
-	    *klassp = origin;
-	}
+      *klassp = origin;
+      ent->origin = origin;
+      ent->mid = ent->mid0 = id;
+      ent->method = body;
     }
+  }
+  else {
+    if (noexp) *noexp = body->nd_noex;
+    body = body->nd_body;
+    if (nd_type(body) == NODE_FBODY) {
+      *klassp = body->nd_orig;
+      *idp = body->nd_mid;
+      body = body->nd_head;
+    }
+    else {
+      *klassp = origin;
+    }
+  }
 
-    return body;
+  return body;
 }
 
 NODE*
-rb_method_node(klass, id)
-    VALUE klass;
-    ID id;
+rb_method_node(VALUE klass, ID id)
 {
-    int noex;
-    struct cache_entry *ent;
+  int noex;
+  struct cache_entry *ent;
 
-    ent = cache + EXPR1(klass, id);
-    if (ent->mid == id && ent->klass == klass && ent->method){
-	return ent->method;
-    }
+  ent = cache + EXPR1(klass, id);
+  if (ent->mid == id && ent->klass == klass && ent->method){
+    return ent->method;
+  }
 
-    return rb_get_method_body(&klass, &id, &noex);
+  return rb_get_method_body(&klass, &id, &noex);
 }
 
 static void
-remove_method(klass, mid)
-    VALUE klass;
-    ID mid;
+remove_method(VALUE klass, ID mid)
 {
-    NODE *body;
+  NODE *body;
 
-    if (klass == rb_cObject) {
-	rb_secure(4);
-    }
-    if (ruby_safe_level >= 4 && !OBJ_TAINTED(klass)) {
-	rb_raise(rb_eSecurityError, "Insecure: can't remove method");
-    }
-    if (OBJ_FROZEN(klass)) rb_error_frozen("class/module");
-    if (mid == __id__ || mid == __send__ || mid == init) {
-	rb_warn("removing `%s' may cause serious problem", rb_id2name(mid));
-    }
-    if (!st_delete(RCLASS(klass)->m_tbl, &mid, (st_data_t *)&body) ||
-	!body->nd_body) {
-	rb_name_error(mid, "method `%s' not defined in %s",
-		      rb_id2name(mid), rb_class2name(klass));
-    }
-    rb_clear_cache_for_undef(klass, mid);
-    if (FL_TEST(klass, FL_SINGLETON)) {
-	rb_funcall(rb_iv_get(klass, "__attached__"), singleton_removed, 1, ID2SYM(mid));
-    }
-    else {
-	rb_funcall(klass, removed, 1, ID2SYM(mid));
-    }
+  if (klass == rb_cObject) {
+    rb_secure(4);
+  }
+  if (ruby_safe_level >= 4 && !OBJ_TAINTED(klass)) {
+    rb_raise(rb_eSecurityError, "Insecure: can't remove method");
+  }
+  if (OBJ_FROZEN(klass)) rb_error_frozen("class/module");
+  if (mid == __id__ || mid == __send__ || mid == init) {
+    rb_warn("removing `%s' may cause serious problem", rb_id2name(mid));
+  }
+  if (!st_delete(RCLASS(klass)->m_tbl, &mid, (st_data_t *)&body) ||
+      !body->nd_body) {
+    rb_name_error(mid, "method `%s' not defined in %s",
+                  rb_id2name(mid), rb_class2name(klass));
+  }
+  rb_clear_cache_for_undef(klass, mid);
+  if (FL_TEST(klass, FL_SINGLETON)) {
+    rb_funcall(rb_iv_get(klass, "__attached__"), singleton_removed, 1, ID2SYM(mid));
+  }
+  else {
+    rb_funcall(klass, removed, 1, ID2SYM(mid));
+  }
 }
 
 void
@@ -278,36 +262,29 @@
  */
 
 static VALUE
-rb_mod_remove_method(argc, argv, mod)
-    int argc;
-    VALUE *argv;
-    VALUE mod;
+rb_mod_remove_method(int argc, VALUE *argv, VALUE mod)
 {
-    int i;
+  int i;
 
-    for (i=0; i<argc; i++) {
-	remove_method(mod, rb_to_id(argv[i]));
-    }
-    return mod;
+  for (i=0; i<argc; i++) {
+    remove_method(mod, rb_to_id(argv[i]));
+  }
+  return mod;
 }
 
 #undef rb_disable_super
 #undef rb_enable_super
 
 void
-rb_disable_super(klass, name)
-    VALUE klass;
-    const char *name;
+rb_disable_super(VALUE klass, const char *name)
 {
-    /* obsolete - no use */
+  /* obsolete - no use */
 }
 
 void
-rb_enable_super(klass, name)
-    VALUE klass;
-    const char *name;
+rb_enable_super(VALUE klass, const char *name)
 {
-    rb_warning("rb_enable_super() is obsolete");
+  rb_warning("rb_enable_super() is obsolete");
 }
 
 static void
@@ -365,50 +342,49 @@
 }
 
 void
-rb_attr(klass, id, read, write, ex)
-    VALUE klass;
-    ID id;
-    int read, write, ex;
+rb_attr(VALUE klass, ID id, int read, int write, int ex)
 {
-    const char *name;
-    char *buf;
-    ID attriv;
-    int noex;
-    size_t len;
+  const char *name;
+  char *buf;
+  ID attriv;
+  int noex;
+  size_t len;
 
-    if (!ex) noex = NOEX_PUBLIC;
-    else {
-	if (SCOPE_TEST(SCOPE_PRIVATE)) {
-	    noex = NOEX_PRIVATE;
-	    rb_warning((scope_vmode == SCOPE_MODFUNC) ?
-		       "attribute accessor as module_function" :
-		       "private attribute?");
-	}
-	else if (SCOPE_TEST(SCOPE_PROTECTED)) {
-	    noex = NOEX_PROTECTED;
-	}
-	else {
-	    noex = NOEX_PUBLIC;
-	}
+  if (!ex) {
+    noex = NOEX_PUBLIC;
+  }
+  else {
+    if (SCOPE_TEST(SCOPE_PRIVATE)) {
+      noex = NOEX_PRIVATE;
+      rb_warning((scope_vmode == SCOPE_MODFUNC) ?
+                 "attribute accessor as module_function" :
+                 "private attribute?");
     }
-
-    if (!rb_is_local_id(id) && !rb_is_const_id(id)) {
-	rb_name_error(id, "invalid attribute name `%s'", rb_id2name(id));
+    else if (SCOPE_TEST(SCOPE_PROTECTED)) {
+      noex = NOEX_PROTECTED;
     }
-    name = rb_id2name(id);
-    if (!name) {
-	rb_raise(rb_eArgError, "argument needs to be symbol or string");
+    else {
+      noex = NOEX_PUBLIC;
     }
-    len = strlen(name)+2;
-    buf = ALLOCA_N(char,len);
-    snprintf(buf, len, "@%s", name);
-    attriv = rb_intern(buf);
-    if (read) {
-	rb_add_method(klass, id, NEW_IVAR(attriv), noex);
-    }
-    if (write) {
-	rb_add_method(klass, rb_id_attrset(id), NEW_ATTRSET(attriv), noex);
-    }
+  }
+
+  if (!rb_is_local_id(id) && !rb_is_const_id(id)) {
+    rb_name_error(id, "invalid attribute name `%s'", rb_id2name(id));
+  }
+  name = rb_id2name(id);
+  if (!name) {
+    rb_raise(rb_eArgError, "argument needs to be symbol or string");
+  }
+  len = strlen(name)+2;
+  buf = ALLOCA_N(char,len);
+  snprintf(buf, len, "@%s", name);
+  attriv = rb_intern(buf);
+  if (read) {
+    rb_add_method(klass, id, NEW_IVAR(attriv), noex);
+  }
+  if (write) {
+    rb_add_method(klass, rb_id_attrset(id), NEW_ATTRSET(attriv), noex);
+  }
 }
 
 static VALUE
@@ -542,53 +518,51 @@
 }
 
 void
-rb_alias(klass, name, def)
-    VALUE klass;
-    ID name, def;
+rb_alias(VALUE klass, ID name, ID def)
 {
-    VALUE origin;
-    NODE *orig, *body, *node;
-    VALUE singleton = 0;
+  VALUE origin;
+  NODE *orig, *body, *node;
+  VALUE singleton = 0;
 
-    rb_frozen_class_p(klass);
-    if (name == def) return;
-    if (klass == rb_cObject) {
-	rb_secure(4);
+  rb_frozen_class_p(klass);
+  if (name == def) return;
+  if (klass == rb_cObject) {
+    rb_secure(4);
+  }
+  orig = search_method(klass, def, &origin);
+  if (!orig || !orig->nd_body) {
+    if (TYPE(klass) == T_MODULE) {
+      orig = search_method(rb_cObject, def, &origin);
     }
-    orig = search_method(klass, def, &origin);
-    if (!orig || !orig->nd_body) {
-	if (TYPE(klass) == T_MODULE) {
-	    orig = search_method(rb_cObject, def, &origin);
-	}
-    }
-    if (!orig || !orig->nd_body) {
-	print_undef(klass, def);
-    }
-    if (FL_TEST(klass, FL_SINGLETON)) {
-	singleton = rb_iv_get(klass, "__attached__");
-    }
-    body = orig->nd_body;
-    orig->nd_cnt++;
-    if (nd_type(body) == NODE_FBODY) { /* was alias */
-	def = body->nd_mid;
-	origin = body->nd_orig;
-	body = body->nd_head;
-    }
+  }
+  if (!orig || !orig->nd_body) {
+    print_undef(klass, def);
+  }
+  if (FL_TEST(klass, FL_SINGLETON)) {
+    singleton = rb_iv_get(klass, "__attached__");
+  }
+  body = orig->nd_body;
+  orig->nd_cnt++;
+  if (nd_type(body) == NODE_FBODY) { /* was alias */
+    def = body->nd_mid;
+    origin = body->nd_orig;
+    body = body->nd_head;
+  }
 
-    rb_clear_cache_by_id(name);
-    if (RTEST(ruby_verbose) && st_lookup(RCLASS(klass)->m_tbl, name, (st_data_t *)&node)) {
-	if (node->nd_cnt == 0 && node->nd_body) {
-	    rb_warning("discarding old %s", rb_id2name(name));
-	}
+  rb_clear_cache_by_id(name);
+  if (RTEST(ruby_verbose) && st_lookup(RCLASS(klass)->m_tbl, name, (st_data_t *)&node)) {
+    if (node->nd_cnt == 0 && node->nd_body) {
+      rb_warning("discarding old %s", rb_id2name(name));
     }
-    st_insert(RCLASS(klass)->m_tbl, name,
-      (st_data_t)NEW_METHOD(NEW_FBODY(body, def, origin), orig->nd_noex));
-    if (singleton) {
-	rb_funcall(singleton, singleton_added, 1, ID2SYM(name));
-    }
-    else {
-	rb_funcall(klass, added, 1, ID2SYM(name));
-    }
+  }
+  st_insert(RCLASS(klass)->m_tbl, name,
+            (st_data_t)NEW_METHOD(NEW_FBODY(body, def, origin), orig->nd_noex));
+  if (singleton) {
+    rb_funcall(singleton, singleton_added, 1, ID2SYM(name));
+  }
+  else {
+    rb_funcall(klass, added, 1, ID2SYM(name));
+  }
 }
 
 /*

Modified: trunk/eval_thread.c
===================================================================
--- trunk/eval_thread.c	2005-11-21 12:22:32 UTC (rev 297)
+++ trunk/eval_thread.c	2005-11-28 00:10:29 UTC (rev 298)
@@ -1850,7 +1850,7 @@
 	    return;
 	}
     }
-    th_signm = sig;
+    th_signm = (char *)sig;
     curr_thread = main_thread;
     rb_thread_restore_context(curr_thread, RESTORE_SIGNAL);
 }

Modified: trunk/insns.def
===================================================================
--- trunk/insns.def	2005-11-21 12:22:32 UTC (rev 297)
+++ trunk/insns.def	2005-11-28 00:10:29 UTC (rev 298)
@@ -1215,11 +1215,15 @@
   VALUE klass;
   yarv_block_t *blockptr = 0;
   ulong num = op_argc;
-  macro_eval_setup_send_arguments(num, recv, blockptr, flag, blockval);
+  int noex;
 
+  macro_eval_setup_send_arguments(num, blockptr, flag, blockval);
+  recv  = TOPN(num);
+  klass = CLASS_OF(recv);
+
+
 //  dpi(id);
-  
-  mn = eval_method_search(id, klass, ic);
+  mn = eval_method_search(id, klass, ic, &noex);
 
 #if CURRENT_INSN_send || CURRENT_INSN_send_SC_xx_ax
 #if !YARV_AOT_COMPILED
@@ -1243,6 +1247,7 @@
     klass    = CLASS_OF(recv);
     blockptr = 0;
     mn       = rb_method_node(klass, id);
+    noex     = 0; // TODO
   }
   if(0){
     LABEL_IS_SC(start_init_in_super):
@@ -1257,12 +1262,13 @@
       }
 
       id    = rb_to_id(ip->name);
-      num   = (ulong)tmp_id;
+      num   = tmp_num;
       recv  = GET_SELF();
       klass = eval_search_super_klass(ip->klass, recv);
 
-      blockptr  = GET_BLOCK_PTR();
-      mn        = rb_method_node(klass, id);
+      blockptr = tmp_blockptr;
+      mn       = rb_method_node(klass, id);
+      noex     = 0;
     }
   }
   if(0){
@@ -1280,11 +1286,11 @@
       id = rb_to_id(ip->name);
       num   = ip->argc;
       recv  = GET_SELF();
-
       klass = eval_search_super_klass(ip->klass, recv);
 
-      blockptr = GET_BLOCK_PTR();
+      blockptr = tmp_blockptr;
       mn       = rb_method_node(klass, id);
+      noex     = 0;
 
       /* copy locals */
       sp = GET_SP();
@@ -1298,7 +1304,7 @@
   }
 #endif
 #endif
-  macro_eval_invoke_method(recv, klass, id, num, mn, blockptr);
+  macro_eval_invoke_method(recv, klass, id, num, mn, noex, blockptr);
 }
 
 /**
@@ -1308,7 +1314,7 @@
  */
 DEFINE_INSN
 super
-(ulong num, ulong flag)
+(ulong op_argc, VALUE blockval, ulong flag)
 (...)
 (VALUE val)
 {
@@ -1316,8 +1322,13 @@
 #if YARV_AOT_COMPILED
   rb_bug("...");
 #else
-  /* expand flag */
-  tmp_id = (ID)num;
+  tmp_num = op_argc;
+  tmp_blockptr = 0;
+  macro_eval_setup_send_arguments(tmp_num, tmp_blockptr,
+                                  flag, blockval);
+  if(!tmp_blockptr){
+    tmp_blockptr = GET_BLOCK_PTR();
+  }
   goto LABEL_IS_SC(start_init_in_super);
 #endif
 }
@@ -1329,13 +1340,23 @@
  */
 DEFINE_INSN
 zsuper
-()
+(VALUE blockval)
 (...)
 (VALUE val)
 {
 #if YARV_AOT_COMPILED
 #else
-  // TODO
+  tmp_blockptr = 0;
+  if(blockval){
+    yarv_iseq_t *blockiseq;
+    GetISeqVal(blockval, blockiseq);
+    tmp_blockptr = GET_BLOCK_PTR_IN_CFP(GET_CFP());
+    tmp_blockptr->iseq = blockiseq;
+    tmp_blockptr->proc = 0;
+  }
+  else{
+    tmp_blockptr = GET_BLOCK_PTR();
+  }
   goto LABEL_IS_SC(start_init_in_zsuper);
 #endif
 }
@@ -2298,6 +2319,53 @@
 
 /**
   @c optimize
+  @e optimized succ
+  @j optimized succ
+ */
+DEFINE_INSN
+opt_succ
+()
+(VALUE recv)
+(VALUE val)
+{
+  if(SPECIAL_CONST_P(recv)){
+    if(FIXNUM_P(recv) && BASIC_OP_UNREDEFINED(FIXNUM_SUCC)){
+      const VALUE obj = INT2FIX(1);
+      /* fixnum + INT2FIX(1) */
+      val = (recv + (obj & (~1)));
+      if((~(recv^obj)&(recv^val))&0x80000000){
+        val = rb_big_plus(rb_int2big(INT2FIX(recv)),
+                          rb_int2big(INT2FIX(obj)));
+      }
+    }
+    else{
+      goto INSN_LABEL(normal_dispatch);
+    }
+  }
+  else{
+    if(HEAP_CLASS_OF(recv) == rb_cString){
+      val = rb_str_succ(recv);
+    }
+    else if(HEAP_CLASS_OF(recv) == rb_cTime){
+      val = rb_time_succ(recv);
+    }
+    else{
+      goto INSN_LABEL(normal_dispatch);
+    }
+  }
+  if(0){
+    INSN_LABEL(normal_dispatch):
+    /* other */
+#ifdef YARV_AOT_COMPILED
+    val = rb_funcall(recv, idSucc, 0);
+#else
+    val = rb_funcall(recv, idSucc, 0);
+#endif
+  }
+}
+
+/**
+  @c optimize
   @e optimized regexp match
   @j KK\}b`
  */

Added: trunk/lib/tempfile.rb
===================================================================
--- trunk/lib/tempfile.rb	2005-11-21 12:22:32 UTC (rev 297)
+++ trunk/lib/tempfile.rb	2005-11-28 00:10:29 UTC (rev 298)
@@ -0,0 +1,195 @@
+#
+# tempfile - manipulates temporary files
+#
+# $Id: tempfile.rb,v 1.28 2005/05/11 01:46:00 ocean Exp $
+#
+
+require 'delegate'
+require 'tmpdir'
+
+# A class for managing temporary files.  This library is written to be
+# thread safe.
+class Tempfile < DelegateClass(File)
+  MAX_TRY = 10
+  @@cleanlist = []
+
+  # Creates a temporary file of mode 0600 in the temporary directory
+  # whose name is basename.pid.n and opens with mode "w+".  A Tempfile
+  # object works just like a File object.
+  #
+  # If tmpdir is omitted, the temporary directory is determined by
+  # Dir::tmpdir provided by 'tmpdir.rb'.
+  # When $SAFE > 0 and the given tmpdir is tainted, it uses
+  # /tmp. (Note that ENV values are tainted by default)
+  def initialize(basename, tmpdir=Dir::tmpdir)
+    if $SAFE > 0 and tmpdir.tainted?
+      tmpdir = '/tmp'
+    end
+
+    lock = nil
+    n = failure = 0
+    
+    begin
+      Thread.critical = true
+
+      begin
+	tmpname = File.join(tmpdir, make_tmpname(basename, n))
+	lock = tmpname + '.lock'
+	n += 1
+      end while   cleanlist.include?(tmpname) or
+	File.exist?(lock) or File.exist?(tmpname)
+
+      Dir.mkdir(lock)
+    rescue
+      failure += 1
+      retry if failure < MAX_TRY
+      raise "cannot generate tempfile `%s'" % tmpname
+    ensure
+      Thread.critical = false
+    end
+
+    @data = [tmpname]
+    @clean_proc = Tempfile.callback(@data)
+    ObjectSpace.define_finalizer(self, @clean_proc)
+
+    @tmpfile = File.open(tmpname, File::RDWR|File::CREAT|File::EXCL, 0600)
+    @tmpname = tmpname
+    @@cleanlist << @tmpname
+    @data[1] = @tmpfile
+    @data[2] = @@cleanlist
+
+    super(@tmpfile)
+
+    # Now we have all the File/IO methods defined, you must not
+    # carelessly put bare puts(), etc. after this.
+
+    Dir.rmdir(lock)
+  end
+
+  def make_tmpname(basename, n)
+    sprintf('%s%d.%d', basename, $$, n)
+  end
+  private :make_tmpname
+
+  # Opens or reopens the file with mode "r+".
+  def open
+    @tmpfile.close if @tmpfile
+    @tmpfile = File.open(@tmpname, 'r+')
+    @data[1] = @tmpfile
+    __setobj__(@tmpfile)
+  end
+
+  def _close	# :nodoc:
+    @tmpfile.close if @tmpfile
+    @tmpfile = nil
+    @data[1] = nil if @data
+  end
+  protected :_close
+
+  #Closes the file.  If the optional flag is true, unlinks the file
+  # after closing.
+  #
+  # If you don't explicitly unlink the temporary file, the removal
+  # will be delayed until the object is finalized.
+  def close(unlink_now=false)
+    if unlink_now
+      close!
+    else
+      _close
+    end
+  end
+
+  # Closes and unlinks the file.
+  def close!
+    _close
+    @clean_proc.call
+    ObjectSpace.undefine_finalizer(self)
+    @data = @tmpname = nil
+  end
+
+  # Unlinks the file.  On UNIX-like systems, it is often a good idea
+  # to unlink a temporary file immediately after creating and opening
+  # it, because it leaves other programs zero chance to access the
+  # file.
+  def unlink
+    # keep this order for thread safeness
+    begin
+      File.unlink(@tmpname) if File.exist?(@tmpname)
+        cleanlist.delete( tmpname)
+      @data = @tmpname = nil
+      ObjectSpace.undefine_finalizer(self)
+    rescue Errno::EACCES
+      # may not be able to unlink on Windows; just ignore
+    end
+  end
+  alias delete unlink
+
+  # Returns the full path name of the temporary file.
+  def path
+    @tmpname
+  end
+
+  # Returns the size of the temporary file.  As a side effect, the IO
+  # buffer is flushed before determining the size.
+  def size
+    if @tmpfile
+      @tmpfile.flush
+      @tmpfile.stat.size
+    else
+      0
+    end
+  end
+  alias length size
+
+  class << self
+    def callback(data)	# :nodoc:
+      pid = $$
+      Proc.new {
+	if pid == $$ 
+	  path, tmpfile, cleanlist = *data
+
+	  print "removing ", path, "..." if $DEBUG
+
+	  tmpfile.close if tmpfile
+
+	  # keep this order for thread safeness
+	  File.unlink(path) if File.exist?(path)
+	  cleanlist.delete(path) if cleanlist
+
+	  print "done\n" if $DEBUG
+	end
+      }
+    end
+
+    # If no block is given, this is a synonym for new().
+    #
+    # If a block is given, it will be passed tempfile as an argument,
+    # and the tempfile will automatically be closed when the block
+    # terminates.  In this case, open() returns nil.
+    def open(*args)
+      tempfile = new(*args)
+
+      if block_given?
+	begin
+	  yield(tempfile)
+	ensure
+	  tempfile.close
+	end
+
+	nil
+      else
+	tempfile
+      end
+    end
+  end
+end
+
+if __FILE__ == $0
+#  $DEBUG = true
+  f = Tempfile.new("foo")
+  f.print("foo\n")
+  f.close
+  f.open
+  p f.gets # => "foo\n"
+  f.close!
+end

Added: trunk/lib/tmpdir.rb
===================================================================
--- trunk/lib/tmpdir.rb	2005-11-21 12:22:32 UTC (rev 297)
+++ trunk/lib/tmpdir.rb	2005-11-28 00:10:29 UTC (rev 298)
@@ -0,0 +1,42 @@
+#
+# tmpdir - retrieve temporary directory path
+#
+# $Id: tmpdir.rb,v 1.5 2003/07/26 15:38:58 eban Exp $
+#
+
+class Dir
+
+  @@systmpdir = '/tmp'
+
+  begin
+    require 'Win32API'
+    max_pathlen = 260
+    windir = ' '*(max_pathlen+1)
+    begin
+      getdir = Win32API.new('kernel32', 'GetSystemWindowsDirectory', 'PL', 'L')
+    rescue RuntimeError
+      getdir = Win32API.new('kernel32', 'GetWindowsDirectory', 'PL', 'L')
+    end
+    getdir.call(windir, windir.size)
+    windir = File.expand_path(windir.rstrip.untaint)
+    temp = File.join(windir, 'temp')
+    @@systmpdir = temp if File.directory?(temp) and File.writable?(temp)
+  rescue LoadError
+  end
+
+  def Dir::tmpdir
+    tmp = '.'
+    if $SAFE > 0
+      tmp = @@systmpdir
+    else
+      for dir in [ENV['TMPDIR'], ENV['TMP'], ENV['TEMP'],
+	          ENV['USERPROFILE'], @@systmpdir, '/tmp']
+	if dir and File.directory?(dir) and File.writable?(dir)
+	  tmp = dir
+	  break
+	end
+      end
+    end
+    File.expand_path(tmp)
+  end
+end

Modified: trunk/string.c
===================================================================
--- trunk/string.c	2005-11-21 12:22:32 UTC (rev 297)
+++ trunk/string.c	2005-11-28 00:10:29 UTC (rev 298)
@@ -1283,7 +1283,7 @@
  *     "***".succ         #=> "**+"
  */
 
-static VALUE
+VALUE
 rb_str_succ(VALUE orig)
 {
     VALUE str;

Modified: trunk/test.rb
===================================================================
--- trunk/test.rb	2005-11-21 12:22:32 UTC (rev 297)
+++ trunk/test.rb	2005-11-28 00:10:29 UTC (rev 298)
@@ -1,6 +1,21 @@
+prs = []
+3.times{|i|
+  a = i+1
+  b = i*2
+  prs << lambda{p [a, b]}
+}
+prs.each{|pr|
+  pr.call
+}
 
-p [1, 2, 3].map{|e|
-  p e
-  e = e * 2
-  e
+__END__
+prs = []
+1.times{|e|
+3.times{|e|
+  prs << lambda{p e}
 }
+}
+prs.each{|pr|
+  pr.call
+}
+

Modified: trunk/time.c
===================================================================
--- trunk/time.c	2005-11-21 12:22:32 UTC (rev 297)
+++ trunk/time.c	2005-11-28 00:10:29 UTC (rev 298)
@@ -1325,6 +1325,12 @@
     return rb_time_new(tobj->tv.tv_sec + 1, tobj->tv.tv_usec);
 }
 
+VALUE
+rb_time_succ(VALUE time)
+{
+  return time_succ(time);
+}
+
 /*
  *  call-seq:
  *     time.sec => fixnum

Modified: trunk/vm.c
===================================================================
--- trunk/vm.c	2005-11-21 12:22:32 UTC (rev 297)
+++ trunk/vm.c	2005-11-28 00:10:29 UTC (rev 298)
@@ -911,8 +911,19 @@
   return klass;
 }
 
+EVALBODY_HELPER_FUNCTION VALUE
+eval_method_missing(yarv_thread_t *th, ID id, VALUE recv, int num, int opt){
+  yarv_control_frame_t *reg_cfp = th->cfp;
+  VALUE *argv = STACK_ADDR_FROM_TOP(num+1);
+  VALUE val;
+  argv[0] = ID2SYM(id);
+  val = rb_funcall2(recv, idMethodMissing, num+1, argv);
+  POPN(num+1);
+  return val;
+}
+
 EVALBODY_HELPER_FUNCTION NODE*
-eval_method_search(VALUE id, VALUE klass, IC ic)
+eval_method_search(VALUE id, VALUE klass, IC ic, int *noex)
 {
   NODE *mn;
 

Modified: trunk/vm_evalbody.h
===================================================================
--- trunk/vm_evalbody.h	2005-11-21 12:22:32 UTC (rev 297)
+++ trunk/vm_evalbody.h	2005-11-28 00:10:29 UTC (rev 298)
@@ -66,6 +66,8 @@
 #endif
 
   ID tmp_id;
+  yarv_block_t *tmp_blockptr;
+  ulong tmp_num;
 
 #if OPT_TOKEN_THREADED_CODE || OPT_DIRECT_THREADED_CODE
 #include "vmtc.inc"

Modified: trunk/vm_macro.def
===================================================================
--- trunk/vm_macro.def	2005-11-21 12:22:32 UTC (rev 297)
+++ trunk/vm_macro.def	2005-11-28 00:10:29 UTC (rev 298)
@@ -3,7 +3,7 @@
 /*                              */
 
 
-MACRO macro_eval_setup_send_arguments(num, recv, blockptr, flag, blockval)
+MACRO macro_eval_setup_send_arguments(num, blockptr, flag, blockval)
 {
   if(flag & VM_CALL_ARGS_BLOCKARG_BIT){
     yarv_proc_t *po;
@@ -34,9 +34,6 @@
     blockptr->proc = 0;
   }
 
-  recv  = TOPN(num);
-  klass = CLASS_OF(recv);
-
   /* expand top of stack? */
   if(flag & VM_CALL_ARGS_SPLAT_BIT){
     VALUE ary = TOPN(0);
@@ -213,7 +210,7 @@
   }
 }
 
-MACRO macro_eval_invoke_method(recv, klass, id, num, mn, blockptr)
+MACRO macro_eval_invoke_method(recv, klass, id, num, mn, noex, blockptr)
 {
   /* method missing */
   if(mn == 0){
@@ -222,12 +219,19 @@
       rb_bug("method missing");
     }
     else{
-      VALUE *argv = STACK_ADDR_FROM_TOP(num+1);
-      argv[0] = ID2SYM(id);
-      val = rb_funcall2(recv, idMethodMissing, num+1, argv);
+      val = eval_method_missing(th, id, recv, num, 0);
     }
-    POPN(num+1);
   }
+  else if(0 && noex & (NOEX_PRIVATE | NOEX_PROTECTED)){
+    /* TODO: resarch call statistics */
+    if((noex & NOEX_PRIVATE) && !(flag & VM_CALL_FCALL_BIT)){
+      printf("call noex: %d\n", mn->nd_noex);
+      val = eval_method_missing(th, id, recv, num, NOEX_PRIVATE);
+    }
+    if(0 /* TODO */ && (noex & NOEX_PUBLIC)){
+      rb_bug("unsupport protected");
+    }
+  }
   else{
     switch(nd_type(mn)){
     case YARV_METHOD_NODE:{

Modified: trunk/yarvcore.c
===================================================================
--- trunk/yarvcore.c	2005-11-21 12:22:32 UTC (rev 297)
+++ trunk/yarvcore.c	2005-11-28 00:10:29 UTC (rev 298)
@@ -47,6 +47,7 @@
 ID idEach;
 ID idLength;
 ID idGets;
+ID idSucc;
 ID idBitblt;
 ID idAnswer;
 
@@ -1002,6 +1003,8 @@
   idLength = rb_intern("length");
   idIntern = rb_intern("intern");
   idGets   = rb_intern("gets");
+  idSucc   = rb_intern("succ");
+
   idMethodMissing = rb_intern("method_missing");
 
   idThrowState     = rb_intern("#__ThrowState__");

Modified: trunk/yarvcore.h
===================================================================
--- trunk/yarvcore.h	2005-11-21 12:22:32 UTC (rev 297)
+++ trunk/yarvcore.h	2005-11-28 00:10:29 UTC (rev 298)
@@ -114,6 +114,7 @@
 extern ID idEach;
 extern ID idLength;
 extern ID idGets;
+extern ID idSucc;
 extern ID idBitblt;
 extern ID idAnswer;
 

Modified: trunk/yarvtest/test_class.rb
===================================================================
--- trunk/yarvtest/test_class.rb	2005-11-21 12:22:32 UTC (rev 297)
+++ trunk/yarvtest/test_class.rb	2005-11-28 00:10:29 UTC (rev 298)
@@ -178,6 +178,44 @@
     end
   end
 
+  def test_super2
+    ae %q{
+      class C
+        def m(a, b)
+          a+b
+        end
+      end
+
+      class D < C
+        def m arg
+          super(*arg)
+        end
+      end
+
+      D.new.m([1, 2])
+    }
+
+    ae %q{
+      class C
+        def m
+          yield
+        end
+      end
+      
+      class D < C
+        def m
+          super(){
+            :D
+          }
+        end
+      end
+
+      D.new.m{
+        :top
+      }
+    }
+  end
+  
   def test_zsuper
     ae %q{
       class C
@@ -243,6 +281,26 @@
       remove_const(:C2)
       remove_const(:C3)
     end
+
+    ae %q{
+      class C
+        def m
+          yield
+        end
+      end
+      
+      class D < C
+        def m
+          super{
+            :D
+          }
+        end
+      end
+
+      D.new.m{
+        :top
+      }
+    }
   end
 
   def test_const_in_other_scope


-- 
ML: yarv-diff quickml.atdot.net
Info: http://www.atdot.net/~ko1/quickml

[前][次][番号順一覧][スレッド一覧][生データ]