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