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