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

yarv-diff:173

From: ko1 atdot.net
Date: 26 Dec 2005 17:08:24 -0000
Subject: [yarv-diff:173] r332 - in trunk: . yarvtest

Author: ko1
Date: 2005-12-27 02:08:23 +0900 (Tue, 27 Dec 2005)
New Revision: 332

Modified:
   trunk/ChangeLog
   trunk/array.c
   trunk/eval.c
   trunk/eval_intern.h
   trunk/eval_load.c
   trunk/eval_method.h
   trunk/eval_proc.c
   trunk/insnhelper.h
   trunk/insns.def
   trunk/intern.h
   trunk/node.h
   trunk/test.rb
   trunk/variable.c
   trunk/vm.c
   trunk/vm.h
   trunk/vm_macro.def
   trunk/yarv.h
   trunk/yarvcore.c
   trunk/yarvcore.h
   trunk/yarvtest/test_class.rb
Log:
	* array.c, intern.h, insns.def : expose rb_ary_replace and use it
	in insns.def

	* eval.c : fix to use SCOPE_* to NOEX_*

	* eval_intern.h : remove SCOPE_*
	and fix SCOPE_TEST() and SCOPE_SET(f)

	* eval_load.c : save and store klass and visibility
	at require and load

	* eval_method.h : fix undefed method node ([yarv-dev-en:8])

	* eval_proc.c : fix define_method ([yarv-dev:704])

	* insnhelper.h, vm.h : remove GET_VM_STATE_VERSION(),
	INC_VM_STATE_VERSION() and move these to vm.h

	* insns.def : supportintg visibility

	* node.h : remove NOEX_RECV

	* variable.c, vm.c : add rb_vm_change_state() and use it in
	remove_const

	* vm.c, insns.def, yarvcore.h, yarvcore.c : add eval_push_cref(),
	eval_pop_cref() and th_cref_init to manage current visibility

	* yarv.h : add a prototype of rb_vm_change_state()

	* yarvcore.h, insns.def : add defined_method_id and support
	super in define_method scope

	* yarvtest/test_class.rb : add tests for above



Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2005-12-26 11:45:39 UTC (rev 331)
+++ trunk/ChangeLog	2005-12-26 17:08:23 UTC (rev 332)
@@ -4,6 +4,44 @@
 #  from Mon, 03 May 2004 01:24:19 +0900
 #
 
+2005-12-27(Tue) 01:52:07 +0900  Koichi Sasada  <ko1 atdot.net>
+
+	* array.c, intern.h, insns.def : expose rb_ary_replace and use it
+	in insns.def
+
+	* eval.c : fix to use SCOPE_* to NOEX_*
+
+	* eval_intern.h : remove SCOPE_*
+	and fix SCOPE_TEST() and SCOPE_SET(f)
+
+	* eval_load.c : save and store klass and visibility
+	at require and load
+
+	* eval_method.h : fix undefed method node ([yarv-dev-en:8])
+
+	* eval_proc.c : fix define_method ([yarv-dev:704])
+
+	* insnhelper.h, vm.h : remove GET_VM_STATE_VERSION(),
+	INC_VM_STATE_VERSION() and move these to vm.h
+
+	* insns.def : supportintg visibility
+
+	* node.h : remove NOEX_RECV
+
+	* variable.c, vm.c : add rb_vm_change_state() and use it in
+	remove_const
+
+	* vm.c, insns.def, yarvcore.h, yarvcore.c : add eval_push_cref(),
+	eval_pop_cref() and th_cref_init to manage current visibility
+
+	* yarv.h : add a prototype of rb_vm_change_state()
+
+	* yarvcore.h, insns.def : add defined_method_id and support
+	super in define_method scope
+
+	* yarvtest/test_class.rb : add tests for above
+
+
 2005-12-26(Mon) 20:44:38 +0900  Minero Aoki  <aamine loveruby.net>
 
 	* test/ruby/test_basicinstructions.rb: new file.

Modified: trunk/array.c
===================================================================
--- trunk/array.c	2005-12-26 11:45:39 UTC (rev 331)
+++ trunk/array.c	2005-12-26 17:08:23 UTC (rev 332)
@@ -270,8 +270,6 @@
     return rb_check_convert_type(ary, T_ARRAY, "Array", "to_ary");
 }
 
-static VALUE rb_ary_replace(VALUE, VALUE);
-
 /*
  *  call-seq:
  *     Array.new(size=0, obj=nil)
@@ -2039,7 +2037,7 @@
  *     a                              #=> ["x", "y", "z"]
  */
 
-static VALUE
+VALUE
 rb_ary_replace(VALUE copy, VALUE orig)
 {
     VALUE shared;

Modified: trunk/eval.c
===================================================================
--- trunk/eval.c	2005-12-26 11:45:39 UTC (rev 331)
+++ trunk/eval.c	2005-12-26 17:08:23 UTC (rev 332)
@@ -144,7 +144,7 @@
   Init_heap();
 
   /* default visibility is private at toplevel */
-  SCOPE_SET(SCOPE_PRIVATE);
+  // SCOPE_SET(SCOPE_PRIVATE);
 
   PUSH_TAG(PROT_NONE);
   if ((state = EXEC_TAG()) == 0) {
@@ -1193,8 +1193,7 @@
 
 
 VALUE
-rb_yield(val)
-    VALUE val;
+rb_yield(VALUE val)
 {
   return rb_yield_0(val, 0, 0, 0, Qfalse);
 }
@@ -1289,7 +1288,6 @@
     retval = (*it_proc)(data1);
   }
   else if (state == TAG_BREAK /* TODO: more check */ ) {
-    // TODO: Fix me
     state = 0;
     th->state = 0;
     th->errinfo = Qnil;
@@ -1546,7 +1544,6 @@
   {
     int n = 0;
     VALUE args[3];
-
     args[n++] = rb_funcall(rb_const_get(exc, rb_intern("message")), '!',
                            3, rb_str_new2(format), obj, argv[0]);
     args[n++] = argv[0];
@@ -1580,7 +1577,6 @@
   return rb_funcall2(obj, missing, argc+1, nargv);
 }
 
-
 static VALUE
 rb_call(VALUE klass, VALUE recv, ID mid, int argc, const VALUE *argv, int scope)
 {
@@ -1612,16 +1608,16 @@
     if (scope == 3) {
       return method_missing(recv, mid, argc, argv, NOEX_SUPER);
     }
-    return method_missing(recv, mid, argc, argv, scope==2 ? NOEX_VCALL:0);
+    return method_missing(recv, mid, argc, argv, scope==2 ? NOEX_VCALL : 0);
   }
-
   if (mid != missing) {
     /* receiver specified form for private method */
-    if ((noex & NOEX_PRIVATE) && scope == 0)
+    if (((noex & NOEX_MASK) & NOEX_PRIVATE) && scope == 0){
       return method_missing(recv, mid, argc, argv, NOEX_PRIVATE);
+    }
 
     /* self must be kind of a specified form for protected method */
-    if ((noex & NOEX_PROTECTED)) {
+    if (((noex & NOEX_MASK) & NOEX_PROTECTED)) {
       VALUE defined_class = klass;
 
       if (TYPE(defined_class) == T_ICLASS) {
@@ -1634,8 +1630,8 @@
 
   {
     VALUE val;
-    static int level;
-    int i;
+    //static int level;
+    //int i;
     //for(i=0; i<level; i++){printf("  ");}
     //printf("invoke %s (%s)\n", rb_id2name(mid), node_name(nd_type(body)));
     //level++;
@@ -1660,7 +1656,7 @@
     argc = RARRAY(args)->len; /* Assigns LONG, but argc is INT */
     argv = ALLOCA_N(VALUE, argc);
     MEMCPY(argv, RARRAY(args)->ptr, VALUE, argc);
-    return rb_call(CLASS_OF(recv), recv, mid, argc, argv, 1);
+    return rb_call(CLASS_OF(recv), recv, mid, argc, argv, NOEX_NOSUPER);
 }
 
 /*
@@ -1690,7 +1686,7 @@
 
   vid = *argv++; argc--;
   PASS_PASSED_BLOCK();
-  return rb_call(CLASS_OF(recv), recv, rb_to_id(vid), argc, argv, 1);
+  return rb_call(CLASS_OF(recv), recv, rb_to_id(vid), argc, argv, NOEX_NOSUPER);
 }
 
 VALUE
@@ -1722,19 +1718,19 @@
 	argv = 0;
     }
 
-    return rb_call(CLASS_OF(recv), recv, mid, n, argv, 1);
+    return rb_call(CLASS_OF(recv), recv, mid, n, argv, NOEX_NOSUPER);
 }
 
 VALUE
 rb_funcall2(VALUE recv, ID mid, int argc, const VALUE *argv)
 {
-  return rb_call(CLASS_OF(recv), recv, mid, argc, argv, 1);
+  return rb_call(CLASS_OF(recv), recv, mid, argc, argv, NOEX_NOSUPER);
 }
 
 VALUE
 rb_funcall3(VALUE recv, ID mid, int argc, const VALUE *argv)
 {
-  return rb_call(CLASS_OF(recv), recv, mid, argc, argv, 0);
+  return rb_call(CLASS_OF(recv), recv, mid, argc, argv, NOEX_PUBLIC);
 }
 
 VALUE
@@ -2217,7 +2213,7 @@
 {
     secure_visibility(module);
     if (argc == 0) {
-	SCOPE_SET(SCOPE_PUBLIC);
+	SCOPE_SET(NOEX_PUBLIC);
     }
     else {
 	set_method_visibility(module, argc, argv, NOEX_PUBLIC);
@@ -2243,7 +2239,7 @@
 {
     secure_visibility(module);
     if (argc == 0) {
-	SCOPE_SET(SCOPE_PROTECTED);
+	SCOPE_SET(NOEX_PROTECTED);
     }
     else {
 	set_method_visibility(module, argc, argv, NOEX_PROTECTED);
@@ -2271,14 +2267,11 @@
  */
 
 static VALUE
-rb_mod_private(argc, argv, module)
-    int argc;
-    VALUE *argv;
-    VALUE module;
+rb_mod_private(int argc, VALUE *argv, VALUE module)
 {
     secure_visibility(module);
     if (argc == 0) {
-	SCOPE_SET(SCOPE_PRIVATE);
+	SCOPE_SET(NOEX_PRIVATE);
     }
     else {
 	set_method_visibility(module, argc, argv, NOEX_PRIVATE);
@@ -2404,7 +2397,7 @@
 
   secure_visibility(module);
   if (argc == 0) {
-    SCOPE_SET(SCOPE_MODFUNC);
+    SCOPE_SET(NOEX_MODFUNC);
     return module;
   }
   

Modified: trunk/eval_intern.h
===================================================================
--- trunk/eval_intern.h	2005-12-26 11:45:39 UTC (rev 331)
+++ trunk/eval_intern.h	2005-12-26 17:08:23 UTC (rev 332)
@@ -243,14 +243,16 @@
 #define TAG_MASK	0xf
 
 static int scope_vmode;
-#define SCOPE_PUBLIC    0
-#define SCOPE_PRIVATE   1
-#define SCOPE_PROTECTED 2
-#define SCOPE_MODFUNC   5
-#define SCOPE_MASK      7
-#define SCOPE_SET(f)  (f)
-#define SCOPE_TEST(f) (0&(f))
 
+#define SCOPE_TEST(f)   \
+  (FIX2INT(rb_ary_entry(GET_THREAD()->visibility_nest_stack, -1)) == f)
+
+#define SCOPE_SET(f)  \
+{ \
+  yarv_thread_t *th = GET_THREAD(); \
+  rb_ary_store(th->visibility_nest_stack, -1, INT2FIX(f)); \
+}
+
 struct ruby_env {
     struct ruby_env *prev;
     struct FRAME *frame;

Modified: trunk/eval_load.c
===================================================================
--- trunk/eval_load.c	2005-12-26 11:45:39 UTC (rev 331)
+++ trunk/eval_load.c	2005-12-26 17:08:23 UTC (rev 332)
@@ -114,8 +114,16 @@
   int state;
   volatile ID callee, this_func;
   volatile VALUE self = ruby_top_self;
-  NODE * volatile last_node;
-  
+  volatile VALUE stored_klass_nest_stack;
+  volatile VALUE stored_visibility_nest_stack;
+  yarv_thread_t *th = GET_THREAD();
+
+  stored_klass_nest_stack = th->klass_nest_stack;
+  stored_visibility_nest_stack = th->visibility_nest_stack;
+
+  /* default visibility is private at loading toplevel */
+  th_cref_init(th);
+
   FilePathValue(fname);
   fname = rb_str_new4(fname);
   tmp = rb_find_file(fname);
@@ -132,8 +140,6 @@
     /* load in anonymous module as toplevel */
     self = rb_obj_clone(ruby_top_self);
   }
-  /* default visibility is private at loading toplevel */
-  SCOPE_SET(SCOPE_PRIVATE);
 
   PUSH_TAG(PROT_NONE);
   state = EXEC_TAG();
@@ -141,7 +147,10 @@
     yarv_load(RSTRING(fname)->ptr);
   }
   POP_TAG();
-  
+
+  th->klass_nest_stack = stored_klass_nest_stack;
+  th->visibility_nest_stack = stored_visibility_nest_stack;
+
   if (ruby_nerrs > 0) {
     ruby_nerrs = 0;
     rb_exc_raise(GET_THREAD()->errinfo);
@@ -352,8 +361,7 @@
 
   /* store */
   stored_klass_nest_stack = th->klass_nest_stack;
-  th->klass_nest_stack = rb_ary_new();
-  rb_ary_push(th->klass_nest_stack, rb_cObject);
+  th->klass_nest_stack = rb_ary_push(rb_ary_new(), rb_cObject);
   
   saved.vmode = scope_vmode;
   saved.node = ruby_current_node;
@@ -391,7 +399,7 @@
           ruby_current_node = 0;
           ruby_sourcefile = rb_source_filename(RSTRING(path)->ptr);
           ruby_sourceline = 0;
-          SCOPE_SET(SCOPE_PUBLIC);
+          SCOPE_SET(NOEX_PUBLIC);
           handle = (long)dln_load(RSTRING(path)->ptr);
           rb_ary_push(ruby_dln_librefs, LONG2NUM(handle));
           break;

Modified: trunk/eval_method.h
===================================================================
--- trunk/eval_method.h	2005-12-26 11:45:39 UTC (rev 331)
+++ trunk/eval_method.h	2005-12-26 17:08:23 UTC (rev 332)
@@ -113,7 +113,12 @@
    *   nd_oid  : original id           // (1)
    *   nd_cnt  : alias count           // (3)
    */
-  body = NEW_FBODY(NEW_METHOD(node, klass, noex), 0);
+  if(node){
+    body = NEW_FBODY(NEW_METHOD(node, klass, noex), 0);
+  }
+  else{
+    body = 0;
+  }
   st_insert(RCLASS(klass)->m_tbl, mid, (st_data_t)body);
   
   if (node && mid != ID_ALLOCATOR && ruby_running) {
@@ -349,13 +354,13 @@
     noex = NOEX_PUBLIC;
   }
   else {
-    if (SCOPE_TEST(SCOPE_PRIVATE)) {
+    if (SCOPE_TEST(NOEX_PRIVATE)) {
       noex = NOEX_PRIVATE;
-      rb_warning((scope_vmode == SCOPE_MODFUNC) ?
+      rb_warning((scope_vmode == NOEX_MODFUNC) ?
                  "attribute accessor as module_function" :
                  "private attribute?");
     }
-    else if (SCOPE_TEST(SCOPE_PROTECTED)) {
+    else if (SCOPE_TEST(NOEX_PROTECTED)) {
       noex = NOEX_PROTECTED;
     }
     else {
@@ -449,7 +454,9 @@
     rb_name_error(id, "undefined method `%s' for%s `%s'",
                   rb_id2name(id),s0,rb_class2name(c));
   }
+  
   rb_add_method(klass, id, 0, NOEX_PUBLIC);
+  
   if (FL_TEST(klass, FL_SINGLETON)) {
     rb_funcall(rb_iv_get(klass, "__attached__"),
                singleton_undefined, 1, ID2SYM(id));

Modified: trunk/eval_proc.c
===================================================================
--- trunk/eval_proc.c	2005-12-26 11:45:39 UTC (rev 331)
+++ trunk/eval_proc.c	2005-12-26 17:08:23 UTC (rev 332)
@@ -741,8 +741,14 @@
     node = method->body;
   }
   else if(yarv_obj_is_proc(body)){
-    struct BLOCK *block;
-    // TODO: body = proc_clone(body); why?
+    // struct BLOCK *block;
+    // TODO: body = proc_clone(body);
+    yarv_proc_t *proc;
+    GetProcVal(body, proc);
+    if(BUILTIN_TYPE(proc->block.iseq) != T_NODE){
+      proc->block.iseq->defined_method_id = id;
+      proc->block.iseq->klass = mod;
+    }
     node = NEW_BMETHOD(body);
   }
   else{

Modified: trunk/insnhelper.h
===================================================================
--- trunk/insnhelper.h	2005-12-26 11:45:39 UTC (rev 331)
+++ trunk/insnhelper.h	2005-12-26 17:08:23 UTC (rev 332)
@@ -178,11 +178,6 @@
 /* others                                                 */
 /**********************************************************/
 
-#define GET_VM_STATE_VERSION() (yarvGlobalStateVersion)
-#define INC_VM_STATE_VERSION() \
-  (yarvGlobalStateVersion = (yarvGlobalStateVersion+1) & 0x8fffffff)
-
-
 /* optimize insn */
 #define FIXNUM_2_P(a, b) ((a) & (b) & 1)
 #define BASIC_OP_UNREDEFINED(op) (yarv_unredefined_flag)

Modified: trunk/insns.def
===================================================================
--- trunk/insns.def	2005-12-26 11:45:39 UTC (rev 331)
+++ trunk/insns.def	2005-12-26 17:08:23 UTC (rev 332)
@@ -850,11 +850,12 @@
   NODE *newbody;
   VALUE klass;
   yarv_iseq_t *miseq;
+  int noex = FIX2INT(rb_ary_entry(th->visibility_nest_stack, -1));
 
   /* dup */
   GetISeqVal(body, miseq);
-  rb_funcall2(miseq->klass_nest_stack, rb_intern("replace"),
-              1, &th->klass_nest_stack);
+  rb_ary_replace(miseq->klass_nest_stack, th->klass_nest_stack);
+  
   miseq->klass = rb_ary_entry(th->klass_nest_stack, -1);
 
   /* make new node */
@@ -871,8 +872,14 @@
   else{
     GET_EV_KLASS(klass);
   }
-  rb_add_method(klass, id, newbody, NOEX_PUBLIC);
 
+  rb_add_method(klass, id, newbody, noex);
+
+  if(noex == NOEX_MODFUNC){
+    rb_add_method(rb_singleton_class(klass),
+                  id, newbody, NOEX_PUBLIC);
+  }
+  
   if(0){
     NODE *mn = rb_method_node(klass, id);
     dp(klass);
@@ -896,6 +903,7 @@
   VALUE klass;
   NODE *newbody;
   yarv_iseq_t *iseq;
+  int noex = NOEX_PUBLIC; /* TODO: really? */
 
   if(FIXNUM_P(obj) || SYMBOL_P(obj)){
     rb_raise(rb_eTypeError,
@@ -919,13 +927,13 @@
   }
   
   GetISeqVal(body, iseq);
-  rb_funcall2(iseq->klass_nest_stack, rb_intern("replace"),
-              1, &th->klass_nest_stack);
+  rb_ary_replace(iseq->klass_nest_stack, th->klass_nest_stack);
+  
   iseq->klass = CLASS_OF(obj);
   
   newbody = NEW_NODE(YARV_METHOD_NODE, NOEX_PUBLIC, body, 0);
 
-  rb_add_method(klass, id, newbody, NOEX_PUBLIC); /* TODO: visibility */
+  rb_add_method(klass, id, newbody, noex);
   
   INC_VM_STATE_VERSION();
 }
@@ -1136,7 +1144,8 @@
              klass_iseq->local_size, 0, 0);
   RESTORE_REGS();
   /* others */
-  rb_ary_push(th->klass_nest_stack, klass);
+  eval_push_cref(th, klass, NOEX_PUBLIC);
+  
   INC_VM_STATE_VERSION();
   NEXT_INSN();
 }
@@ -1167,7 +1176,8 @@
              klass_iseq->local_size, 0, 0);
   RESTORE_REGS();
   /* others */
-  rb_ary_push(th->klass_nest_stack, klass);
+  eval_push_cref(th, klass, NOEX_PUBLIC);
+
   INC_VM_STATE_VERSION();
   NEXT_INSN();
 }
@@ -1215,7 +1225,8 @@
   RESTORE_REGS();
   
   /* others */
-  rb_ary_push(th->klass_nest_stack, module);
+  eval_push_cref(th, module, NOEX_PUBLIC);
+  
   INC_VM_STATE_VERSION();
   NEXT_INSN();
 }
@@ -1231,7 +1242,7 @@
 ()
 ()
 {
-  rb_ary_pop(th->klass_nest_stack);
+  eval_pop_cref(th);
 }
 
 
@@ -1293,19 +1304,26 @@
     LABEL_IS_SC(start_init_in_super):
     {
       yarv_iseq_t *iseq = GET_ISEQ();
-      yarv_iseq_t *ip   = iseq;
+      yarv_iseq_t *ip   = iseq->local_iseq;
       VALUE *sp;
-      
-      /* really? */
-      while(ip->parent_iseq){
-        ip = ip->parent_iseq;
-      }
 
-      id    = rb_to_id(ip->name);
       num   = tmp_num;
+      flag  = VM_CALL_FCALL_BIT;
       recv  = GET_SELF();
-      flag  = VM_CALL_FCALL_BIT;
-      klass = eval_search_super_klass(ip->klass, recv);
+      
+      if(ip->klass == 0){
+        ip = iseq;
+        while(!ip->defined_method_id){
+          ip = ip->parent_iseq;
+        }
+        id    = ip->defined_method_id;
+        klass = eval_search_super_klass(ip->klass, recv);
+      }
+      else{
+        id    = rb_to_id(ip->name);
+        klass = eval_search_super_klass(ip->klass, recv);
+      }
+      
       blockptr = tmp_blockptr;
       mn       = rb_method_node(klass, id);
     }

Modified: trunk/intern.h
===================================================================
--- trunk/intern.h	2005-12-26 11:45:39 UTC (rev 331)
+++ trunk/intern.h	2005-12-26 17:08:23 UTC (rev 332)
@@ -66,6 +66,7 @@
 VALUE rb_ary_rassoc(VALUE, VALUE);
 VALUE rb_ary_includes(VALUE, VALUE);
 VALUE rb_ary_cmp(VALUE, VALUE);
+VALUE rb_ary_replace(VALUE copy, VALUE orig);
 VALUE rb_check_array_value(VALUE);
 VALUE rb_get_values_at(VALUE, long, int, VALUE*, VALUE(*)(VALUE,long));
 /* bignum.c */

Modified: trunk/node.h
===================================================================
--- trunk/node.h	2005-12-26 11:45:39 UTC (rev 331)
+++ trunk/node.h	2005-12-26 17:08:23 UTC (rev 332)
@@ -344,17 +344,18 @@
 #define NEW_PRELUDE(p,b) NEW_NODE(NODE_PRELUDE,p,b,0)
 #define NEW_OPTBLOCK(a) NEW_NODE(NODE_OPTBLOCK,a,0,0)
 
-#define NOEX_PUBLIC    0
-#define NOEX_NOSUPER   1
-#define NOEX_PRIVATE   2
-#define NOEX_PROTECTED 4 
-#define NOEX_MASK      6 
+#define NOEX_PUBLIC    0x00
+#define NOEX_NOSUPER   0x01
+#define NOEX_PRIVATE   0x02
+#define NOEX_PROTECTED 0x04
+#define NOEX_MASK      0x06
 
+#define NOEX_MODFUNC   0x08
+
 #define NOEX_UNDEF     NOEX_NOSUPER
-#define NOEX_RECV      8
 
-#define NOEX_SUPER     16
-#define NOEX_VCALL     32
+#define NOEX_SUPER     0x10
+#define NOEX_VCALL     0x20
 
 VALUE rb_parser_new(void);
 VALUE rb_parser_end_seen_p(VALUE);

Modified: trunk/test.rb
===================================================================
--- trunk/test.rb	2005-12-26 11:45:39 UTC (rev 331)
+++ trunk/test.rb	2005-12-26 17:08:23 UTC (rev 332)
@@ -1,33 +1,68 @@
+class Module
+  public :remove_const
+end
+
+class A
+  C = "OK"
+  class B
+    C = "BAD"
+    def self.c
+      C
+    end
+  end
+end
+
+A::B.c
+A::B.remove_const :C
+p A::B.c
+
+__END__
+
 Const = :top
+class A
+  Const = :A
+end
+
 class C
   Const = :C
   def m
-    p 1.instance_eval("Const")
+    p A.class_eval('Const')
   end
 end
 
 C.new.m
 
 __END__
-class C
-  define_method(:m){
-    return 1
-  }
-end
 
-C.new.m
+p 1.times{
+  break :boo
+}
 
 __END__
 
-def m() 2 ensure return 3; end;  p m()
-__END__
-def m()
-  p(begin
-      2
-    ensure
-      return 3
-    end)
-  4
+class Range
+  def each
+    i = first
+    while i<last
+      yield(i)
+      i = i.succ
+    end
+  end
 end
 
-m()
+module Enumerable
+  def map
+    each{|e|
+      yield(e)
+    }
+  end
+end
+
+p((1..3).map{|e|
+  break :ok
+  # break I
+})
+__END__
+["a"].inject("ng"){|x,y|
+  break "ok"
+}

Modified: trunk/variable.c
===================================================================
--- trunk/variable.c	2005-12-26 11:45:39 UTC (rev 331)
+++ trunk/variable.c	2005-12-26 17:08:23 UTC (rev 332)
@@ -1336,6 +1336,8 @@
     ID id = rb_to_id(name);
     VALUE val;
 
+    rb_vm_change_state();
+
     if (!rb_is_const_id(id)) {
 	rb_name_error(id, "`%s' is not allowed as a constant name", rb_id2name(id));
     }

Modified: trunk/vm.c
===================================================================
--- trunk/vm.c	2005-12-26 11:45:39 UTC (rev 331)
+++ trunk/vm.c	2005-12-26 17:08:23 UTC (rev 332)
@@ -61,6 +61,11 @@
 
 #include "call_cfunc.h"
 
+void
+rb_vm_change_state(){
+  INC_VM_STATE_VERSION();
+}
+
 /*
  * prepare stack frame
  */
@@ -391,7 +396,6 @@
     blockptr = th->passed_block;
     th->passed_block = 0;
   }
-  
   switch(nd_type(body)){
   case YARV_METHOD_NODE:{
     yarv_control_frame_t *reg_cfp;
@@ -502,7 +506,6 @@
   return th_call_super(th, argc, argv);
 }
 
-
 static inline VALUE
 th_invoke_yield_cfunc(yarv_thread_t *th,
                       yarv_block_t *block, int argc, VALUE *argv)
@@ -957,6 +960,20 @@
   return mn;
 }
 
+EVALBODY_HELPER_FUNCTION VALUE
+eval_push_cref(yarv_thread_t *th, VALUE klass, int noex)
+{
+  rb_ary_push(th->klass_nest_stack, klass);
+  rb_ary_push(th->visibility_nest_stack, INT2FIX(noex));
+}
+
+EVALBODY_HELPER_FUNCTION VALUE
+eval_pop_cref(yarv_thread_t *th)
+{
+  rb_ary_pop(th->klass_nest_stack);
+  rb_ary_pop(th->visibility_nest_stack);
+}
+
 static void
 call_yarv_end_proc(VALUE data)
 {
@@ -1319,7 +1336,7 @@
     else{
       /* pop cref */
       if(cfp->iseq->type == ISEQ_TYPE_CLASS){
-        rb_ary_pop(th->klass_nest_stack);
+        eval_pop_cref(th);
       }
       
       th->cfp++;

Modified: trunk/vm.h
===================================================================
--- trunk/vm.h	2005-12-26 11:45:39 UTC (rev 331)
+++ trunk/vm.h	2005-12-26 17:08:23 UTC (rev 332)
@@ -259,6 +259,12 @@
 
 #define SCREG(r) (reg_##r)
 
+/* VM state version */
+
+#define GET_VM_STATE_VERSION() (yarvGlobalStateVersion)
+#define INC_VM_STATE_VERSION() \
+  (yarvGlobalStateVersion = (yarvGlobalStateVersion+1) & 0x8fffffff)
+
 #endif	// _VM_H_INCLUDED_
 
 

Modified: trunk/vm_macro.def
===================================================================
--- trunk/vm_macro.def	2005-12-26 11:45:39 UTC (rev 331)
+++ trunk/vm_macro.def	2005-12-26 17:08:23 UTC (rev 332)
@@ -257,14 +257,14 @@
     }
   }
   else if(!(flag & VM_CALL_FCALL_BIT) &&
-          mn->nd_noex & NOEX_PRIVATE){
+          (mn->nd_noex & NOEX_MASK) & NOEX_PRIVATE){
     int stat = NOEX_PRIVATE;
     if(flag & VM_CALL_VCALL_BIT){
       stat |= NOEX_VCALL;
     }
     val = eval_method_missing(th, id, recv, num, stat);
   }
-  else if(mn->nd_noex & NOEX_PROTECTED){
+  else if((mn->nd_noex & NOEX_MASK) & NOEX_PROTECTED){
     VALUE defined_class = mn->nd_clss;
     
     if (TYPE(defined_class) == T_ICLASS) {

Modified: trunk/yarv.h
===================================================================
--- trunk/yarv.h	2005-12-26 11:45:39 UTC (rev 331)
+++ trunk/yarv.h	2005-12-26 17:08:23 UTC (rev 332)
@@ -63,6 +63,8 @@
 #define GET_THREAD() yarv_get_current_running_thread()
 #define GET_VM()     yarv_get_current_running_vm()
 
+void rb_vm_change_state();
+
 struct yarv_yield_data{
   yarv_thread_t *th;
   yarv_block_t *block;

Modified: trunk/yarvcore.c
===================================================================
--- trunk/yarvcore.c	2005-12-26 11:45:39 UTC (rev 331)
+++ trunk/yarvcore.c	2005-12-26 17:08:23 UTC (rev 332)
@@ -46,6 +46,7 @@
 ID idIntern;
 ID idMethodMissing;
 ID idLength;
+ID idLambda;
 ID idGets;
 ID idSucc;
 ID idEach;
@@ -595,7 +596,9 @@
 /* Thread */
 /**********/
 
-static void thread_free(void *ptr){
+static void
+thread_free(void *ptr)
+{
   yarv_thread_t *th;
 
   FREE_REPORT("-> thread");
@@ -613,7 +616,9 @@
 
 void yarv_machine_stack_mark(yarv_thread_t *th);
 
-static void thread_mark(void *ptr){
+static void
+thread_mark(void *ptr)
+{
   yarv_thread_t *th;
   MARK_REPORT("-> thread", 1);
   if(ptr){
@@ -630,9 +635,10 @@
         }
       }
     }
-    
+
     /* mark ruby objects */
     MARK_UNLESS_NULL(th->klass_nest_stack);
+    MARK_UNLESS_NULL(th->visibility_nest_stack);
 
     MARK_UNLESS_NULL(th->first_proc);
     MARK_UNLESS_NULL(th->first_args);
@@ -640,7 +646,7 @@
     MARK_UNLESS_NULL(th->wait_thread_value);
     MARK_UNLESS_NULL(th->value);
     MARK_UNLESS_NULL(th->errinfo);
-    
+
     rb_mark_tbl(th->local_storage);
 
     if(GET_THREAD() != th &&
@@ -649,12 +655,14 @@
       yarv_machine_stack_mark(th);
     }
   }
-  
+
   MARK_UNLESS_NULL(th->stat_insn_usage);
   MARK_REPORT("<- thread", 0);
 }
 
-static VALUE thread_alloc(VALUE klass){
+static VALUE
+thread_alloc(VALUE klass)
+{
   VALUE volatile obj;
   yarv_thread_t *th;
 
@@ -664,7 +672,8 @@
 }
 
 static void
-th_init2(yarv_thread_t *th){
+th_init2(yarv_thread_t *th)
+{
   MEMZERO(th, yarv_thread_t, 1);
 
   /* allocate thread stack */
@@ -684,11 +693,19 @@
   th->status = THREAD_RUNNABLE;
   th->errinfo = Qnil;
 }
+
+void
+th_cref_init(yarv_thread_t *th)
+{
+  th->klass_nest_stack = rb_ary_push(rb_ary_new(), rb_cObject);
+  th->visibility_nest_stack = rb_ary_push(rb_ary_new(), INT2FIX(NOEX_PRIVATE));
+}
+
 static void
 th_init(yarv_thread_t *th)
 {
   th_init2(th);
-  th->klass_nest_stack = rb_ary_push(rb_ary_new(), rb_cObject);
+  th_cref_init(th);
 }
 
 static VALUE
@@ -1046,6 +1063,7 @@
   idEach   = rb_intern("each");
   idTimes  = rb_intern("times");
   idLength = rb_intern("length");
+  idLambda = rb_intern("lambda");
   idIntern = rb_intern("intern");
   idGets   = rb_intern("gets");
   idSucc   = rb_intern("succ");

Modified: trunk/yarvcore.h
===================================================================
--- trunk/yarvcore.h	2005-12-26 11:45:39 UTC (rev 331)
+++ trunk/yarvcore.h	2005-12-26 17:08:23 UTC (rev 332)
@@ -116,6 +116,7 @@
 extern ID idGets;
 extern ID idSucc;
 extern ID idEach;
+extern ID idLambda;
 extern ID idRangeEachLT;
 extern ID idRangeEachLE;
 extern ID idArrayEach;
@@ -268,6 +269,9 @@
   void *special_block_builder;
   void *cached_special_block_builder;
   VALUE cached_special_block;
+
+  /* misc */
+  ID defined_method_id; /* for define_method */
   
   struct iseq_compile_data *compile_data;
 };
@@ -354,6 +358,7 @@
 
   /* klass/module nest information stack */
   VALUE klass_nest_stack; /* Array */
+  VALUE visibility_nest_stack; /* Array */
 
   /* passed via parse.y, eval.c (rb_scope_setup_local_tbl) */
   ID *top_local_tbl;

Modified: trunk/yarvtest/test_class.rb
===================================================================
--- trunk/yarvtest/test_class.rb	2005-12-26 11:45:39 UTC (rev 331)
+++ trunk/yarvtest/test_class.rb	2005-12-26 17:08:23 UTC (rev 332)
@@ -215,6 +215,50 @@
       }
     }
   end
+
+  def test_super_from_define_method
+    ae %q{
+      class C
+        def a
+          "C#a"
+        end
+        def m
+          "C#m"
+        end
+      end
+      class D < C
+        define_method(:m){
+          super
+        }
+        define_method(:a){
+          r = nil
+          1.times{
+            r = super
+          }
+          r
+        }
+      end
+      D.new.m + D.new.a
+    }
+    ae %q{
+      class X
+        def a
+          "X#a"
+        end
+        def b
+          class << self
+            define_method(:a) {
+              super
+            }
+          end
+        end
+      end
+      
+      x = X.new
+      x.b
+      x.a
+    }
+  end
   
   def test_zsuper
     ae %q{


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

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