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

yarv-diff:162

From: ko1 atdot.net
Date: 24 Dec 2005 00:52:40 -0000
Subject: [yarv-diff:162] r321 - trunk

Author: ko1
Date: 2005-12-24 09:52:40 +0900 (Sat, 24 Dec 2005)
New Revision: 321

Modified:
   trunk/ChangeLog
   trunk/class.c
   trunk/compile.c
   trunk/eval.c
   trunk/eval_intern.h
   trunk/eval_method.h
   trunk/eval_proc.c
   trunk/gc.c
   trunk/insns.def
   trunk/node.h
   trunk/test.rb
   trunk/thread.c
   trunk/thread_pthread.h
   trunk/thread_win32.h
   trunk/vm.c
   trunk/vm_macro.def
   trunk/yarvcore.h
Log:
	* eval_method.h : change data structure for RClass#m_tbl

	* class.c, eval.c, eval_proc.c : fix for above changes

	* node.h, gc.c : change NODE_FBODY, NODE_METHOD members
	for above changes

	* insns.def : support private/protected visibility

	* vm_macro.def : ditto

	* vm.c : ditto

	* thread.c : fix typo

	* thread_pthread.h : fix typo

	* thread_win32.h : fix typo

	* eval.c, yarvcore.h : add yarv_thread_t#method_missing_reason
	to pass method_missing reason and use it to build error message

	* compile.c : use ADD_CALL instead of ADD_SEND for
	NODE_X(D)STR, NODE_CONST (func)



Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2005-12-21 17:49:44 UTC (rev 320)
+++ trunk/ChangeLog	2005-12-24 00:52:40 UTC (rev 321)
@@ -4,6 +4,34 @@
 #  from Mon, 03 May 2004 01:24:19 +0900
 #
 
+2005-12-24(Sat) 09:05:23 +0900  Koichi Sasada  <ko1 atdot.net>
+
+	* eval_method.h : change data structure for RClass#m_tbl
+
+	* class.c, eval.c, eval_proc.c : fix for above changes
+
+	* node.h, gc.c : change NODE_FBODY, NODE_METHOD members
+	for above changes
+
+	* insns.def : support private/protected visibility
+
+	* vm_macro.def : ditto
+
+	* vm.c : ditto
+
+	* thread.c : fix typo
+
+	* thread_pthread.h : fix typo
+
+	* thread_win32.h : fix typo
+
+	* eval.c, yarvcore.h : add yarv_thread_t#method_missing_reason
+	to pass method_missing reason and use it to build error message
+
+	* compile.c : use ADD_CALL instead of ADD_SEND for
+	NODE_X(D)STR, NODE_CONST (func)
+
+
 2005-12-22(Thu) 02:45:27 +0900  Koichi Sasada  <ko1 atdot.net>
 
 	* yarv_version.h, Changes : 0.3.3

Modified: trunk/class.c
===================================================================
--- trunk/class.c	2005-12-21 17:49:44 UTC (rev 320)
+++ trunk/class.c	2005-12-24 00:52:40 UTC (rev 321)
@@ -59,8 +59,9 @@
 static int
 clone_method(ID mid, NODE *body, st_table *tbl)
 {
-    st_insert(tbl, mid, (st_data_t)NEW_METHOD(body->nd_body, body->nd_noex));
-    return ST_CONTINUE;
+  rb_bug("unsupported: class.c#clone_method");
+  //st_insert(tbl, mid, (st_data_t)NEW_METHOD(body->nd_body, body->nd_noex));
+  return ST_CONTINUE;
 }
 
 /* :nodoc: */
@@ -540,6 +541,7 @@
 method_entry(ID key, NODE *body, st_table *list)
 {
     long type;
+    body = body->nd_body;
 
     if (key == ID_ALLOCATOR) return ST_CONTINUE;
     if (!st_lookup(list, key, 0)) {

Modified: trunk/compile.c
===================================================================
--- trunk/compile.c	2005-12-21 17:49:44 UTC (rev 320)
+++ trunk/compile.c	2005-12-24 00:52:40 UTC (rev 321)
@@ -3739,7 +3739,7 @@
   case NODE_XSTR:{
     ADD_INSN (ret, nd_line(node), putself);
     ADD_INSN1(ret, nd_line(node), putobject, node->nd_lit);
-    ADD_SEND (ret, nd_line(node), ID2SYM(idBackquote), INT2FIX(1));
+    ADD_CALL (ret, nd_line(node), ID2SYM(idBackquote), INT2FIX(1));
     
     if(poped){
       ADD_INSN(ret, nd_line(node), pop);
@@ -3749,7 +3749,7 @@
   case NODE_DXSTR:{
     ADD_INSN(ret, nd_line(node), putself);
     compile_dstr(self, iseq, ret, node);
-    ADD_SEND(ret, nd_line(node), ID2SYM(idBackquote), INT2FIX(1));
+    ADD_CALL(ret, nd_line(node), ID2SYM(idBackquote), INT2FIX(1));
 
     if(poped){
       ADD_INSN(ret, nd_line(node), pop);
@@ -3980,7 +3980,7 @@
       /* function call */
       ADD_INSN(ret, nd_line(node), putself);
       COMPILE (ret, "colon2#nd_head", node->nd_head);
-      ADD_SEND(ret, nd_line(node), ID2SYM(node->nd_mid), INT2FIX(1));
+      ADD_CALL(ret, nd_line(node), ID2SYM(node->nd_mid), INT2FIX(1));
     }
     if(poped){
       ADD_INSN(ret, nd_line(node), pop);

Modified: trunk/eval.c
===================================================================
--- trunk/eval.c	2005-12-21 17:49:44 UTC (rev 320)
+++ trunk/eval.c	2005-12-24 00:52:40 UTC (rev 321)
@@ -50,7 +50,7 @@
 static NODE *compile _((VALUE, char*, int));
 
 static VALUE rb_yield_0 _((VALUE, VALUE, VALUE, int, int));
-static VALUE rb_call _((VALUE,VALUE,ID,int,const VALUE*,int));
+static VALUE rb_call(VALUE,VALUE,ID,int,const VALUE*,int);
 
 typedef struct event_hook {
     rb_event_hook_func_t func;
@@ -800,17 +800,17 @@
  */
 
 static VALUE
-rb_mod_public_method_defined(mod, mid)
-    VALUE mod, mid;
+rb_mod_public_method_defined(VALUE mod, VALUE mid)
 {
-    ID id = rb_to_id(mid);
-    int noex;
+  ID id = rb_to_id(mid);
+  NODE *method;
 
-    if (rb_get_method_body(&mod, &id, &noex)) {
-	if (VISI_CHECK(noex, NOEX_PUBLIC))
-	    return Qtrue;
-    }
-    return Qfalse;
+  method = rb_method_node(mod, id);
+  if (method) {
+    if (VISI_CHECK(method->nd_noex, NOEX_PUBLIC))
+      return Qtrue;
+  }
+  return Qfalse;
 }
 
 /*
@@ -840,17 +840,17 @@
  */
 
 static VALUE
-rb_mod_private_method_defined(mod, mid)
-    VALUE mod, mid;
+rb_mod_private_method_defined(VALUE mod, VALUE mid)
 {
-    ID id = rb_to_id(mid);
-    int noex;
+  ID id = rb_to_id(mid);
+  NODE *method;
 
-    if (rb_get_method_body(&mod, &id, &noex)) {
-	if (VISI_CHECK(noex, NOEX_PRIVATE))
-	    return Qtrue;
-    }
-    return Qfalse;
+  method = rb_method_node(mod, id);
+  if (method) {
+    if (VISI_CHECK(method->nd_noex, NOEX_PRIVATE))
+      return Qtrue;
+  }
+  return Qfalse;
 }
 
 /*
@@ -880,17 +880,17 @@
  */
 
 static VALUE
-rb_mod_protected_method_defined(mod, mid)
-    VALUE mod, mid;
+rb_mod_protected_method_defined(VALUE mod, VALUE mid)
 {
-    ID id = rb_to_id(mid);
-    int noex;
+  ID id = rb_to_id(mid);
+  NODE *method;
 
-    if (rb_get_method_body(&mod, &id, &noex)) {
-	if (VISI_CHECK(noex, NOEX_PROTECTED))
-	    return Qtrue;
-    }
-    return Qfalse;
+  method = rb_method_node(mod, id);
+  if (method) {
+    if (VISI_CHECK(method->nd_noex, NOEX_PROTECTED))
+      return Qtrue;
+  }
+  return Qfalse;
 }
 
 NORETURN(void th_iter_break _((yarv_thread_t *)));
@@ -1476,13 +1476,6 @@
     }
 }
 
-static int last_call_status;
-
-#define CSTAT_PRIV  1
-#define CSTAT_PROT  2
-#define CSTAT_VCALL 4
-#define CSTAT_SUPER 8
-
 /*
  *  call-seq:
  *     obj.method_missing(symbol [, *args] )   => result
@@ -1514,136 +1507,128 @@
  */
 
 static VALUE
-rb_method_missing(argc, argv, obj)
-    int argc;
-    VALUE *argv;
-    VALUE obj;
+rb_method_missing(int argc, const VALUE *argv, VALUE obj)
 {
-    ID id;
-    VALUE exc = rb_eNoMethodError;
-    char *format = 0;
-    NODE *cnode = ruby_current_node;
+  ID id;
+  VALUE exc = rb_eNoMethodError;
+  char *format = 0;
+  NODE *cnode = ruby_current_node;
+  yarv_thread_t *th = GET_THREAD();
+  int last_call_status = th->method_missing_reason;
+  if (argc == 0 || !SYMBOL_P(argv[0])) {
+    rb_raise(rb_eArgError, "no id given");
+  }
 
-    if (argc == 0 || !SYMBOL_P(argv[0])) {
-	rb_raise(rb_eArgError, "no id given");
-    }
+  stack_check();
 
-    stack_check();
+  id = SYM2ID(argv[0]);
 
-    id = SYM2ID(argv[0]);
+  if (last_call_status & NOEX_PRIVATE) {
+    format = "private method `%s' called for %s";
+  }
+  else if (last_call_status & NOEX_PROTECTED) {
+    format = "protected method `%s' called for %s";
+  }
+  else if (last_call_status & NOEX_VCALL) {
+    format = "undefined local variable or method `%s' for %s";
+    exc = rb_eNameError;
+  }
+  else if (last_call_status & NOEX_SUPER) {
+    format = "super: no superclass method `%s'";
+  }
+  if (!format) {
+    format = "undefined method `%s' for %s";
+  }
 
-    if (last_call_status & CSTAT_PRIV) {
-	format = "private method `%s' called for %s";
-    }
-    else if (last_call_status & CSTAT_PROT) {
-	format = "protected method `%s' called for %s";
-    }
-    else if (last_call_status & CSTAT_VCALL) {
-	format = "undefined local variable or method `%s' for %s";
-	exc = rb_eNameError;
-    }
-    else if (last_call_status & CSTAT_SUPER) {
-	format = "super: no superclass method `%s'";
-    }
-    if (!format) {
-	format = "undefined method `%s' for %s";
-    }
+  ruby_current_node = cnode;
+  {
+    int n = 0;
+    VALUE args[3];
 
-    ruby_current_node = cnode;
-    {
-	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];
-	if (exc == rb_eNoMethodError) {
-	    args[n++] = rb_ary_new4(argc-1, argv+1);
-	}
-	exc = rb_class_new_instance(n, args, exc);
-	rb_exc_raise(exc);
+    args[n++] = rb_funcall(rb_const_get(exc, rb_intern("message")), '!',
+                           3, rb_str_new2(format), obj, argv[0]);
+    args[n++] = argv[0];
+    if (exc == rb_eNoMethodError) {
+      args[n++] = rb_ary_new4(argc-1, argv+1);
     }
+    exc = rb_class_new_instance(n, args, exc);
+    rb_exc_raise(exc);
+  }
 
-    return Qnil;		/* not reached */
+  return Qnil;		/* not reached */
 }
 
 static VALUE
-method_missing(obj, id, argc, argv, call_status)
-    VALUE obj;
-    ID    id;
-    int   argc;
-    const VALUE *argv;
-    int   call_status;
+method_missing(VALUE obj, ID id, int argc, const VALUE *argv, int call_status)
 {
-    VALUE *nargv;
+  VALUE *nargv;
+  GET_THREAD()->method_missing_reason = call_status;
+  
+  if (id == missing) {
+    rb_method_missing(argc, argv, obj);
+  }
+  else if (id == ID_ALLOCATOR) {
+    rb_raise(rb_eTypeError, "allocator undefined for %s", rb_class2name(obj));
+  }
 
-    last_call_status = call_status;
+  nargv = ALLOCA_N(VALUE, argc+1);
+  nargv[0] = ID2SYM(id);
+  MEMCPY(nargv+1, argv, VALUE, argc);
 
-    if (id == missing) {
-	rb_method_missing(argc, argv, obj);
-    }
-    else if (id == ID_ALLOCATOR) {
-	rb_raise(rb_eTypeError, "allocator undefined for %s", rb_class2name(obj));
-    }
-
-    nargv = ALLOCA_N(VALUE, argc+1);
-    nargv[0] = ID2SYM(id);
-    MEMCPY(nargv+1, argv, VALUE, argc);
-
-    return rb_funcall2(obj, missing, argc+1, nargv);
+  return rb_funcall2(obj, missing, argc+1, nargv);
 }
 
 
 static VALUE
-rb_call(klass, recv, mid, argc, argv, scope)
-    VALUE klass, recv;
-    ID    mid;
-    int argc;			/* OK */
-    const VALUE *argv;		/* OK */
-    int scope;
+rb_call(VALUE klass, VALUE recv, ID mid, int argc, const VALUE *argv, int scope)
 {
-    NODE  *body;		/* OK */
-    int    noex;
-    ID     id = mid;
-    struct cache_entry *ent;
+  NODE  *body, *method;
+  int    noex;
+  ID     id = mid;
+  struct cache_entry *ent;
 
-    if (!klass) {
-	rb_raise(rb_eNotImpError, "method `%s' called on terminated object (%p)",
-		 rb_id2name(mid), (void*)recv);
+  if (!klass) {
+    rb_raise(rb_eNotImpError, "method `%s' called on terminated object (%p)",
+             rb_id2name(mid), (void*)recv);
+  }
+  /* is it in the method cache? */
+  ent = cache + EXPR1(klass, mid);
+  if (ent->mid == mid && ent->klass == klass) {
+    if (!ent->method)
+      return method_missing(recv, mid, argc, argv, scope==2 ? NOEX_VCALL : 0);
+    id    = ent->mid0;
+    noex  = ent->method->nd_noex;
+    klass = ent->method->nd_clss;
+    body  = ent->method->nd_body;
+  }
+  else if ((method = rb_get_method_body(klass, id, &id)) != 0) {
+    noex  = method->nd_noex;
+    klass = method->nd_clss;
+    body  = method->nd_body;
+  }
+  else {
+    if (scope == 3) {
+      return method_missing(recv, mid, argc, argv, NOEX_SUPER);
     }
-    /* is it in the method cache? */
-    ent = cache + EXPR1(klass, mid);
-    if (ent->mid == mid && ent->klass == klass) {
-	if (!ent->method)
-	    return method_missing(recv, mid, argc, argv, scope==2?CSTAT_VCALL:0);
-	klass = ent->origin;
-	id    = ent->mid0;
-	noex  = ent->noex;
-	body  = ent->method;
-    }
-    else if ((body = rb_get_method_body(&klass, &id, &noex)) == 0) {
-	if (scope == 3) {
-	    return method_missing(recv, mid, argc, argv, CSTAT_SUPER);
-	}
-	return method_missing(recv, mid, argc, argv, scope==2?CSTAT_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)
-	    return method_missing(recv, mid, argc, argv, CSTAT_PRIV);
+  if (mid != missing) {
+    /* receiver specified form for private method */
+    if ((noex & 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)) {
-	    VALUE defined_class = klass;
+    /* self must be kind of a specified form for protected method */
+    if ((noex & NOEX_PROTECTED)) {
+      VALUE defined_class = klass;
 
-	    if (TYPE(defined_class) == T_ICLASS) {
-		defined_class = RBASIC(defined_class)->klass;
-	    }
-	    if (!rb_obj_is_kind_of(rb_frame_self(), rb_class_real(defined_class)))
-		return method_missing(recv, mid, argc, argv, CSTAT_PROT);
-	}
+      if (TYPE(defined_class) == T_ICLASS) {
+        defined_class = RBASIC(defined_class)->klass;
+      }
+      if (!rb_obj_is_kind_of(rb_frame_self(), rb_class_real(defined_class)))
+        return method_missing(recv, mid, argc, argv, NOEX_PROTECTED);
     }
+  }
 
   {
     VALUE val;
@@ -2193,28 +2178,23 @@
 }
 
 static void
-secure_visibility(self)
-    VALUE self;
+secure_visibility(VALUE self)
 {
-    if (ruby_safe_level >= 4 && !OBJ_TAINTED(self)) {
-	rb_raise(rb_eSecurityError, "Insecure: can't change method visibility");
-    }
+  if (ruby_safe_level >= 4 && !OBJ_TAINTED(self)) {
+    rb_raise(rb_eSecurityError, "Insecure: can't change method visibility");
+  }
 }
 
 static void
-set_method_visibility(self, argc, argv, ex)
-    VALUE self;
-    int argc;
-    VALUE *argv;
-    ID ex;
+set_method_visibility(VALUE self, int argc, VALUE *argv, ID ex)
 {
-    int i;
+  int i;
 
-    secure_visibility(self);
-    for (i=0; i<argc; i++) {
-	rb_export_method(self, rb_to_id(argv[i]), ex);
-    }
-    rb_clear_cache_by_class(self);
+  secure_visibility(self);
+  for (i=0; i<argc; i++) {
+    rb_export_method(self, rb_to_id(argv[i]), ex);
+  }
+  rb_clear_cache_by_class(self);
 }
 
 /*
@@ -2410,47 +2390,45 @@
  */
 
 static VALUE
-rb_mod_modfunc(argc, argv, module)
-    int argc;
-    VALUE *argv;
-    VALUE module;
+rb_mod_modfunc(int argc, VALUE *argv, VALUE module)
 {
-    int i;
-    ID id;
-    NODE *body;
+  int i;
+  ID id;
+  NODE *fbody;
 
-    if (TYPE(module) != T_MODULE) {
-	rb_raise(rb_eTypeError, "module_function must be called for modules");
-    }
+  if (TYPE(module) != T_MODULE) {
+    rb_raise(rb_eTypeError, "module_function must be called for modules");
+  }
 
-    secure_visibility(module);
-    if (argc == 0) {
-	SCOPE_SET(SCOPE_MODFUNC);
-	return module;
-    }
+  secure_visibility(module);
+  if (argc == 0) {
+    SCOPE_SET(SCOPE_MODFUNC);
+    return module;
+  }
+  
+  set_method_visibility(module, argc, argv, NOEX_PRIVATE);
+  
+  for (i=0; i<argc; i++) {
+    VALUE m = module;
 
-    set_method_visibility(module, argc, argv, NOEX_PRIVATE);
-    for (i=0; i<argc; i++) {
-	VALUE m = module;
-
-	id = rb_to_id(argv[i]);
-	for (;;) {
-	    body = search_method(m, id, &m);
-	    if (body == 0) {
-		body = search_method(rb_cObject, id, &m);
-	    }
-	    if (body == 0 || body->nd_body == 0) {
-		rb_bug("undefined method `%s'; can't happen", rb_id2name(id));
-	    }
-	    if (nd_type(body->nd_body) != NODE_ZSUPER) {
-		break;		/* normal case: need not to follow 'super' link */
-	    }
-	    m = RCLASS(m)->super;
-	    if (!m) break;
-	}
-	rb_add_method(rb_singleton_class(module), id, body->nd_body, NOEX_PUBLIC);
+    id = rb_to_id(argv[i]);
+    for (;;) {
+      fbody = search_method(m, id, &m);
+      if (fbody == 0) {
+        fbody = search_method(rb_cObject, id, &m);
+      }
+      if (fbody == 0 || fbody->nd_body == 0) {
+        rb_bug("undefined method `%s'; can't happen", rb_id2name(id));
+      }
+      if (nd_type(fbody->nd_body->nd_body) != NODE_ZSUPER) {
+        break;		/* normal case: need not to follow 'super' link */
+      }
+      m = RCLASS(m)->super;
+      if (!m) break;
     }
-    return module;
+    rb_add_method(rb_singleton_class(module), id, fbody->nd_body->nd_body, NOEX_PUBLIC);
+  }
+  return module;
 }
 
 /*

Modified: trunk/eval_intern.h
===================================================================
--- trunk/eval_intern.h	2005-12-21 17:49:44 UTC (rev 320)
+++ trunk/eval_intern.h	2005-12-24 00:52:40 UTC (rev 321)
@@ -277,8 +277,6 @@
 int thread_set_raised();
 int thread_reset_raised();
 
-NODE* rb_get_method_body(VALUE *klassp, ID *idp, int *noexp);
-
 VALUE rb_f_eval(int argc, VALUE *argv, VALUE self);
 VALUE rb_make_exception _((int argc, VALUE *argv));
 

Modified: trunk/eval_method.h
===================================================================
--- trunk/eval_method.h	2005-12-21 17:49:44 UTC (rev 320)
+++ trunk/eval_method.h	2005-12-24 00:52:40 UTC (rev 321)
@@ -10,9 +10,7 @@
     ID mid;			/* method's id */
     ID mid0;			/* method's original id */
     VALUE klass;		/* receiver's class */
-    VALUE origin;		/* where method defined  */
     NODE *method;
-    int noex;
 };
 
 static struct cache_entry cache[CACHE_SIZE];
@@ -39,7 +37,7 @@
   if (!ruby_running) return;
   ent = cache; end = ent + CACHE_SIZE;
   while (ent < end) {
-    if (ent->origin == klass && ent->mid == id) {
+    if (ent->method && ent->method->nd_clss == klass && ent->mid == id) {
       ent->mid = 0;
     }
     ent++;
@@ -69,14 +67,14 @@
   if (!ruby_running) return;
   ent = cache; end = ent + CACHE_SIZE;
   while (ent < end) {
-    if (ent->klass == klass || ent->origin == klass) {
+    if ((ent->klass == klass) ||
+        (ent->method && ent->method->nd_clss == klass)) {
       ent->mid = 0;
     }
     ent++;
   }
 }
 
-
 void
 rb_add_method(VALUE klass, ID mid, NODE* node, int noex)
 {
@@ -103,8 +101,21 @@
     rb_error_frozen("class/module");
   }
   rb_clear_cache_by_id(mid);
-  body = NEW_METHOD(node, noex);
+
+  /*
+   * NODE_METHOD (NEW_METHOD(body, klass, vis)):
+   *   nd_body : method body   // (2) // mark
+   *   nd_clss : klass         // (1) // mark
+   *   nd_noex : visibility    // (3)
+   *
+   * NODE_FBODY (NEW_FBODY(method, alias)):
+   *   nd_body : method (NODE_METHOD)  // (2) // mark
+   *   nd_oid  : original id           // (1)
+   *   nd_cnt  : alias count           // (3)
+   */
+  body = NEW_FBODY(NEW_METHOD(node, klass, noex), 0);
   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));
@@ -130,75 +141,71 @@
 }
 
 static NODE*
-search_method(VALUE klass, ID id, VALUE *origin)
+search_method(VALUE klass, ID id, VALUE *klassp)
 {
   NODE *body;
 
-  if (!klass) return 0;
+  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;
+  if(klassp){
+    *klassp = klass;
+  }
+  
   return body;
 }
 
+/*
+ * search method body (NODE_METHOD)
+ *   with    : klass and id
+ *   without : method cache
+ *
+ * if you need method node with method cache, use
+ * rb_method_node()
+ */
 NODE*
-rb_get_method_body(VALUE *klassp, ID *idp, int *noexp)
+rb_get_method_body(VALUE klass, ID id, ID *idp)
 {
-  ID id = *idp;
-  VALUE klass = *klassp;
   VALUE origin;
-  NODE * volatile body;
-  struct cache_entry *ent;
+  NODE * volatile fbody, *body;
+  NODE * method;
 
-  if ((body = search_method(klass, id, &origin)) == 0 || !body->nd_body) {
+  if ((fbody = search_method(klass, id, 0)) == 0 ||
+      !fbody->nd_body) {
     /* store empty info in cache */
+    struct cache_entry *ent;
     ent = cache + EXPR1(klass, id);
     ent->klass  = klass;
-    ent->origin = klass;
     ent->mid = ent->mid0 = id;
-    ent->noex   = 0;
     ent->method = 0;
-
     return 0;
   }
 
+  method = fbody->nd_body;
+
   if (ruby_running) {
     /* store in cache */
+    struct cache_entry *ent;
     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;
-    }
+    ent->mid    = id;
+    ent->mid0   = fbody->nd_oid;
+    ent->method = body    = method;
   }
   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;
-    }
+    body    = method;
   }
 
+  if(idp){
+    *idp = fbody->nd_oid;
+  }
+  
   return body;
 }
 
@@ -213,7 +220,7 @@
     return ent->method;
   }
 
-  return rb_get_method_body(&klass, &id, &noex);
+  return rb_get_method_body(klass, id, 0);
 }
 
 static void
@@ -290,22 +297,22 @@
 static void
 rb_export_method(VALUE klass, ID name, ID noex)
 {
-  NODE *body;
+  NODE *fbody;
   VALUE origin;
 
   if (klass == rb_cObject) {
     rb_secure(4);
   }
-  body = search_method(klass, name, &origin);
-  if (!body && TYPE(klass) == T_MODULE) {
-    body = search_method(rb_cObject, name, &origin);
+  fbody = search_method(klass, name, &origin);
+  if (!fbody && TYPE(klass) == T_MODULE) {
+    fbody = search_method(rb_cObject, name, &origin);
   }
-  if (!body || !body->nd_body) {
+  if (!fbody || !fbody->nd_body) {
     print_undef(klass, name);
   }
-  if (body->nd_noex != noex) {
+  if (fbody->nd_body->nd_noex != noex) {
     if (klass == origin) {
-      body->nd_noex = noex;
+      fbody->nd_body->nd_noex = noex;
     }
     else {
       rb_add_method(klass, name, NEW_ZSUPER(), noex);
@@ -318,20 +325,14 @@
 {
   struct cache_entry *ent;
   int noex;
+  NODE *method;
 
-  /* is it in the method cache? */
-  ent = cache + EXPR1(klass, id);
-  if (ent->mid == id && ent->klass == klass) {
-    if (ex && (ent->noex & NOEX_PRIVATE))
+  if ((method = rb_method_node(klass, id)) != 0) {
+    if (ex && (method->nd_noex & NOEX_PRIVATE)) {
       return Qfalse;
-    if (!ent->method) return Qfalse;
+    }
     return Qtrue;
   }
-  if (rb_get_method_body(&klass, &id, &noex)) {
-    if (ex && (noex & NOEX_PRIVATE))
-      return Qfalse;
-    return Qtrue;
-  }
   return Qfalse;
 }
 
@@ -514,8 +515,7 @@
 void
 rb_alias(VALUE klass, ID name, ID def)
 {
-  VALUE origin;
-  NODE *orig, *body, *node;
+  NODE *orig_fbody, *node;
   VALUE singleton = 0;
 
   rb_frozen_class_p(klass);
@@ -523,34 +523,32 @@
   if (klass == rb_cObject) {
     rb_secure(4);
   }
-  orig = search_method(klass, def, &origin);
-  if (!orig || !orig->nd_body) {
+  orig_fbody = search_method(klass, def, 0);
+  if (!orig_fbody || !orig_fbody->nd_body) {
     if (TYPE(klass) == T_MODULE) {
-      orig = search_method(rb_cObject, def, &origin);
+      orig_fbody = search_method(rb_cObject, def, 0);
     }
   }
-  if (!orig || !orig->nd_body) {
+  if (!orig_fbody || !orig_fbody->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;
-  }
-
+  
+  orig_fbody->nd_cnt++;
   rb_clear_cache_by_id(name);
-  if (RTEST(ruby_verbose) && st_lookup(RCLASS(klass)->m_tbl, name, (st_data_t *)&node)) {
+  
+  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));
+            (st_data_t)NEW_FBODY(orig_fbody->nd_body, def));
+
   if (singleton) {
     rb_funcall(singleton, singleton_added, 1, ID2SYM(name));
   }

Modified: trunk/eval_proc.c
===================================================================
--- trunk/eval_proc.c	2005-12-21 17:49:44 UTC (rev 320)
+++ trunk/eval_proc.c	2005-12-24 00:52:40 UTC (rev 321)
@@ -441,21 +441,25 @@
   rb_gc_mark((VALUE)data->body);
 }
 
+NODE* rb_get_method_body(VALUE klass, ID id, ID *idp);
+
 static VALUE
 mnew(VALUE klass, VALUE obj, ID id, VALUE mklass)
 {
   VALUE method;
   NODE *body;
-  int noex;
   struct METHOD *data;
   VALUE rklass = klass;
   ID oid = id;
 
 again:
-  if ((body = rb_get_method_body(&klass, &id, &noex)) == 0) {
+  if ((body = rb_get_method_body(klass, id, &id)) == 0) {
     print_undef(rklass, oid);
   }
 
+  klass = body->nd_clss;
+  body  = body->nd_body;
+  
   if (nd_type(body) == NODE_ZSUPER) {
     klass = RCLASS(klass)->super;
     goto again;

Modified: trunk/gc.c
===================================================================
--- trunk/gc.c	2005-12-21 17:49:44 UTC (rev 320)
+++ trunk/gc.c	2005-12-24 00:52:40 UTC (rev 321)
@@ -762,7 +762,6 @@
 	  case NODE_DXSTR:
 	  case NODE_DREGX:
 	  case NODE_DREGX_ONCE:
-	  case NODE_FBODY:
 	  case NODE_ENSURE:
 	  case NODE_CALL:
 	  case NODE_DEFS:
@@ -775,7 +774,8 @@
 	    ptr = (VALUE)obj->as.node.u3.node;
 	    goto again;
 
-	  case NODE_WHILE:	/* 1,2 */
+	  case NODE_METHOD:	/* 1,2 */
+	  case NODE_WHILE:
 	  case NODE_UNTIL:
 	  case NODE_AND:
 	  case NODE_OR:
@@ -794,7 +794,7 @@
 	  case NODE_VALIAS:
 	    gc_mark((VALUE)obj->as.node.u1.node, lev);
 	    /* fall through */
-	  case NODE_METHOD:	/* 2 */
+	  case NODE_FBODY:	/* 2 */
 	  case NODE_NOT:
 	  case NODE_GASGN:
 	  case NODE_LASGN:

Modified: trunk/insns.def
===================================================================
--- trunk/insns.def	2005-12-21 17:49:44 UTC (rev 320)
+++ trunk/insns.def	2005-12-24 00:52:40 UTC (rev 321)
@@ -1244,13 +1244,12 @@
   VALUE klass;
   yarv_block_t *blockptr = 0;
   ulong num = op_argc;
-  int noex;
 
   macro_eval_setup_send_arguments(num, blockptr, flag, blockiseq);
   recv  = TOPN(num);
   klass = CLASS_OF(recv);
 
-  mn = eval_method_search(id, klass, ic, &noex);
+  mn = eval_method_search(id, klass, ic);
 
 #if CURRENT_INSN_send || CURRENT_INSN_send_SC_xx_ax
 #if !YARV_AOT_COMPILED
@@ -1274,7 +1273,6 @@
     klass    = CLASS_OF(recv);
     blockptr = 0;
     mn       = rb_method_node(klass, id);
-    noex     = 0; // TODO
   }
   if(0){
     LABEL_IS_SC(start_init_in_super):
@@ -1291,15 +1289,15 @@
       id    = rb_to_id(ip->name);
       num   = tmp_num;
       recv  = GET_SELF();
+      flag  = VM_CALL_FCALL_BIT;
       klass = eval_search_super_klass(ip->klass, recv);
       blockptr = tmp_blockptr;
       mn       = rb_method_node(klass, id);
-      noex     = 0;
     }
   }
 #endif
 #endif
-  macro_eval_invoke_method(recv, klass, id, num, mn, noex, blockptr);
+  macro_eval_invoke_method(recv, klass, id, num, mn, blockptr);
 }
 
 /**

Modified: trunk/node.h
===================================================================
--- trunk/node.h	2005-12-21 17:49:44 UTC (rev 320)
+++ trunk/node.h	2005-12-24 00:52:40 UTC (rev 321)
@@ -195,6 +195,7 @@
 #define nd_cflag u2.id
 #define nd_cval  u3.value
 
+#define nd_oid   u1.id
 #define nd_cnt   u3.cnt
 #define nd_tbl   u1.tbl
 
@@ -215,7 +216,7 @@
 #define nd_mid   u2.id
 #define nd_args  u3.node
 
-#define nd_noex  u1.id
+#define nd_noex  u3.id
 #define nd_defn  u3.node
 
 #define nd_cfnc  u1.cfunc
@@ -239,8 +240,8 @@
 
 #define NEW_NODE(t,a0,a1,a2) rb_node_newnode((t),(VALUE)(a0),(VALUE)(a1),(VALUE)(a2))
 
-#define NEW_METHOD(n,x) NEW_NODE(NODE_METHOD,x,n,0)
-#define NEW_FBODY(n,i,o) NEW_NODE(NODE_FBODY,n,i,o)
+#define NEW_METHOD(n,x,v) NEW_NODE(NODE_METHOD,x,n,v)
+#define NEW_FBODY(n,i) NEW_NODE(NODE_FBODY,i,n,0)
 #define NEW_DEFN(i,a,d,p) NEW_NODE(NODE_DEFN,p,i,NEW_RFUNC(a,d))
 #define NEW_DEFS(r,i,a,d) NEW_NODE(NODE_DEFS,r,i,NEW_RFUNC(a,d))
 #define NEW_CFUNC(f,c) NEW_NODE(NODE_CFUNC,f,c,0)
@@ -352,6 +353,9 @@
 #define NOEX_UNDEF     NOEX_NOSUPER
 #define NOEX_RECV      8
 
+#define NOEX_SUPER     16
+#define NOEX_VCALL     32
+
 VALUE rb_parser_new(void);
 VALUE rb_parser_end_seen_p(VALUE);
 

Modified: trunk/test.rb
===================================================================
--- trunk/test.rb	2005-12-21 17:49:44 UTC (rev 320)
+++ trunk/test.rb	2005-12-24 00:52:40 UTC (rev 321)
@@ -1,7 +1,51 @@
 
+
+require 'test/unit'
 __END__
+module M
+  def m
+    p "M#m"
+  end
 
+  module_function :m
+end
 
+M::m
+
+
+__END__
+require 'shellwords'
+
+for arg in Shellwords::shellwords('...')
+end
+
+__END__
+  require 'mkmf'
+
+__END__
+require 'test/unit'
+
+
+__END__
+p Object.methods
+__END__
+class C
+  def m
+    p "C#m"
+  end
+
+  protected :m
+
+  def test
+    m
+  end
+end
+
+C.new.test
+
+__END__
+
+
 ary = [1, 2].partition {|n| n == 1 }
 a, b = ary
 p a

Modified: trunk/thread.c
===================================================================
--- trunk/thread.c	2005-12-21 17:49:44 UTC (rev 320)
+++ trunk/thread.c	2005-12-24 00:52:40 UTC (rev 321)
@@ -131,7 +131,7 @@
   th->first_proc = rb_block_proc();
 
   /* kick thread */
-  native_thread_crteate(th);
+  native_thread_create(th);
   return thval;
 }
 

Modified: trunk/thread_pthread.h
===================================================================
--- trunk/thread_pthread.h	2005-12-21 17:49:44 UTC (rev 320)
+++ trunk/thread_pthread.h	2005-12-24 00:52:40 UTC (rev 321)
@@ -59,7 +59,7 @@
 static void make_timer_thread();
 
 static int
-native_thread_crteate(yarv_thread_t *th)
+native_thread_create(yarv_thread_t *th)
 {
   pthread_attr_t attr;
   size_t stack_size = 4 * 1024 - sizeof(int); /* 4KB */

Modified: trunk/thread_win32.h
===================================================================
--- trunk/thread_win32.h	2005-12-21 17:49:44 UTC (rev 320)
+++ trunk/thread_win32.h	2005-12-24 00:52:40 UTC (rev 321)
@@ -179,7 +179,7 @@
 static void make_timer_thread();
 
 static int
-native_thread_crteate(yarv_thread_t *th)
+native_thread_create(yarv_thread_t *th)
 {
   size_t stack_size = 4 * 1024 - sizeof(int); /* 4KB */
   static int init = 0;

Modified: trunk/vm.c
===================================================================
--- trunk/vm.c	2005-12-21 17:49:44 UTC (rev 320)
+++ trunk/vm.c	2005-12-24 00:52:40 UTC (rev 321)
@@ -59,8 +59,6 @@
 #define CACHE_MASK 0x7ff
 #define EXPR1(c,m) ((((c)>>3)^(m))&CACHE_MASK)
 
-NODE* rb_get_method_body(VALUE *klassp, ID *idp, int *noexp);
-
 #include "call_cfunc.h"
 
 /*
@@ -485,7 +483,13 @@
     }
   }
   
-  body = rb_method_node(klass, id);
+  body = rb_method_node(klass, id); /* this returns NODE_METHOD */
+  if(body){
+    body = body->nd_body;
+  }
+  else{
+    rb_bug("th_call_super: not found");
+  }
   return th_call0(th, klass, recv, id, id, argc, argv, body, nosuper);
 }
 
@@ -871,13 +875,14 @@
   VALUE *argv = STACK_ADDR_FROM_TOP(num+1);
   VALUE val;
   argv[0] = ID2SYM(id);
+  th->method_missing_reason = opt;
   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, int *noex)
+eval_method_search(VALUE id, VALUE klass, IC ic)
 {
   NODE *mn;
 

Modified: trunk/vm_macro.def
===================================================================
--- trunk/vm_macro.def	2005-12-21 17:49:44 UTC (rev 320)
+++ trunk/vm_macro.def	2005-12-24 00:52:40 UTC (rev 321)
@@ -240,7 +240,7 @@
   }
 }
 
-MACRO macro_eval_invoke_method(recv, klass, id, num, mn, noex, blockptr)
+MACRO macro_eval_invoke_method(recv, klass, id, num, mn, blockptr)
 {
   /* method missing */
   if(mn == 0){
@@ -249,20 +249,38 @@
       rb_bug("method missing");
     }
     else{
-      val = eval_method_missing(th, id, recv, num, 0);
+      int stat = 0;
+      if(flag & VM_CALL_VCALL_BIT){
+        stat |= NOEX_VCALL;
+      }
+      val = eval_method_missing(th, id, recv, num, stat);
     }
   }
-  else if(0 && noex & (NOEX_PRIVATE | NOEX_PROTECTED)){
-    /* TODO: resarch call statistics */
-    if((noex & NOEX_PRIVATE) && !(flag & VM_CALL_FCALL_BIT)){
-      printf("call noex: %ld\n", mn->nd_noex);
-      val = eval_method_missing(th, id, recv, num, NOEX_PRIVATE);
+  else if(!(flag & VM_CALL_FCALL_BIT) &&
+          mn->nd_noex & NOEX_PRIVATE){
+    int stat = NOEX_PRIVATE;
+    if(flag & VM_CALL_VCALL_BIT){
+      stat |= NOEX_VCALL;
     }
-    if(0 /* TODO */ && (noex & NOEX_PUBLIC)){
-      rb_bug("unsupport protected");
+    val = eval_method_missing(th, id, recv, num, stat);
+  }
+  else if(mn->nd_noex & NOEX_PROTECTED){
+    VALUE defined_class = mn->nd_clss;
+    
+    if (TYPE(defined_class) == T_ICLASS) {
+      defined_class = RBASIC(defined_class)->klass;
     }
+    if (!rb_obj_is_kind_of(GET_SELF(), rb_class_real(defined_class))){
+      val = eval_method_missing(th, id, recv, num, NOEX_PROTECTED);
+    }
+    else{
+      goto INSN_LABEL(normal_method_dispatch);
+    }
   }
   else{
+    INSN_LABEL(normal_method_dispatch):
+    
+    mn = mn->nd_body;
     switch(nd_type(mn)){
     case YARV_METHOD_NODE:{
       macro_eval_invoke_func(mn->nd_body, recv, klass,

Modified: trunk/yarvcore.h
===================================================================
--- trunk/yarvcore.h	2005-12-21 17:49:44 UTC (rev 320)
+++ trunk/yarvcore.h	2005-12-24 00:52:40 UTC (rev 321)
@@ -381,9 +381,13 @@
   VALUE  *machine_stack_end;
   jmp_buf machine_regs;
   
-  /* other information */
+  /* statistics data for profiler */
   st_table *local_storage; /* thread local storage */
   VALUE stat_insn_usage;
+
+  /* misc */
+  int method_missing_reason;
+  
 } yarv_thread_t;
 
 /** node -> yarv instruction sequence object */


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

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