From b51416e21f7c0df7d29a7ccd7660f794b6055620 Mon Sep 17 00:00:00 2001 From: matz Date: Wed, 6 Aug 2003 21:50:06 +0000 Subject: * eval.c (rb_call0): update ruby_class as well as ruby_cref. (ruby-bugs-ja PR#540) * eval.c (rb_yield_0): remove ruby_frame->cbase and unify to ruby_cref. [ruby-talk:78141] * eval.c: initialize /* OK */ variables by Qnil to stop warnings. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4346 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 50 ++++++++++++++++++++++++++++++++++++++++++ array.c | 5 ++--- class.c | 35 ++++++++++++++--------------- env.h | 1 - eval.c | 75 ++++++++++++++++++++++++++++++++------------------------------- gc.c | 2 -- intern.h | 4 ++-- marshal.c | 43 ++++++++++++++++++------------------ object.c | 55 ++++++++++++++++++++++++++-------------------- parse.y | 2 +- 10 files changed, 161 insertions(+), 111 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1e2ba50c12..6692b41fd1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +Thu Aug 7 06:46:06 2003 Yukihiro Matsumoto + + * eval.c (rb_call0): update ruby_class as well as ruby_cref. + (ruby-bugs-ja PR#540) + +Thu Aug 7 04:52:50 2003 Yukihiro Matsumoto + + * eval.c (rb_yield_0): remove ruby_frame->cbase and unify to + ruby_cref. [ruby-talk:78141] + Thu Aug 7 04:19:15 2003 Akinori MUSHA * gc.c: FreeBSD/ia64's mcontext_t is a bit different from that of @@ -39,10 +49,45 @@ Wed Aug 6 17:28:10 2003 Nobuyoshi Nakada * ext/digest/sha1/extconf.rb: have_library already appends library name. +Wed Aug 6 17:23:57 2003 Yukihiro Matsumoto + + * eval.c: initialize /* OK */ variables by Qnil to stop warnings. + Wed Aug 6 04:58:32 2003 NAKAMURA Usaku * ext/Setup*: add io/wait and openssl. +Wed Aug 6 01:13:38 2003 Yukihiro Matsumoto + + * eval.c (rb_f_autoload): use ruby_cbase instead of ruby_class. + + * eval.c (rb_f_autoload_p): ditto. + + * class.c (rb_mod_init_copy): no longer implements independent + clone and dup methods. override "initialize_copy" instead. + [ruby-core:01352] + + * object.c (rb_class_s_alloc): define Class allocation function. + this makes Classes to follow clone framework that uses + initialize_copy. + + * object.c (rb_class_initialize): separate instantiation and + initialization. + + * object.c (rb_obj_alloc): prohibit instantiation from + uninitialized class. + + * object.c (rb_class_superclass): check uninitialized class. + + * array.c (rb_ary_fill): wrong index processing with block. this + fix was done by Koji Arai [ruby-list:38029] + + * marshal.c (w_object): should preserve generic ivar for nil, + true, false, symbols, and fixnums. + + * marshal.c (w_uclass): base_klass check should be done after + rb_class_real(). + Wed Aug 6 01:18:50 2003 Minero Aoki * lib/net/http.rb: update document. @@ -51,6 +96,11 @@ Wed Aug 6 01:18:50 2003 Minero Aoki * lib/net/protocol.rb: ditto. +Wed Aug 6 00:48:37 2003 Koji Arai + + * marshal.c (w_object): should recommend marshal_dump rather than + _dump_data. + Tue Aug 5 17:58:57 2003 WATANABE Hirofumi * lib/fileutils.rb (install): should preserve timestamp only. diff --git a/array.c b/array.c index 887ba4db3e..46b0889911 100644 --- a/array.c +++ b/array.c @@ -1570,9 +1570,8 @@ rb_ary_fill(argc, argv, ary) VALUE v; long i; - for (i=0; ilen; i++) { - beg++; - v = rb_yield(LONG2NUM(beg++)); + for (i=beg; ilen; i++) { + v = rb_yield(LONG2NUM(i)); if (i>=RARRAY(ary)->len) break; RARRAY(ary)->ptr[i] = v; } diff --git a/class.c b/class.c index 796fd26a73..f137e698b6 100644 --- a/class.c +++ b/class.c @@ -60,39 +60,37 @@ clone_method(mid, body, tbl) } VALUE -rb_mod_clone(module) - VALUE module; +rb_mod_init_copy(clone, orig) + VALUE clone, orig; { - NEWOBJ(clone, struct RClass); - CLONESETUP(clone, module); - - RCLASS(clone)->super = RCLASS(module)->super; - if (RCLASS(module)->iv_tbl) { + rb_obj_init_copy(clone, orig); + RCLASS(clone)->super = RCLASS(orig)->super; + if (RCLASS(orig)->iv_tbl) { ID id; - RCLASS(clone)->iv_tbl = st_copy(RCLASS(module)->iv_tbl); + RCLASS(clone)->iv_tbl = st_copy(RCLASS(orig)->iv_tbl); id = rb_intern("__classpath__"); st_delete(RCLASS(clone)->iv_tbl, (st_data_t*)&id, 0); id = rb_intern("__classid__"); st_delete(RCLASS(clone)->iv_tbl, (st_data_t*)&id, 0); } - if (RCLASS(module)->m_tbl) { + if (RCLASS(orig)->m_tbl) { RCLASS(clone)->m_tbl = st_init_numtable(); - st_foreach(RCLASS(module)->m_tbl, clone_method, + st_foreach(RCLASS(orig)->m_tbl, clone_method, (st_data_t)RCLASS(clone)->m_tbl); } - return (VALUE)clone; + return clone; } VALUE -rb_mod_dup(mod) - VALUE mod; +rb_class_init_copy(clone, orig) + VALUE clone, orig; { - VALUE dup = rb_mod_clone(mod); - - RBASIC(dup)->flags = RBASIC(mod)->flags & (T_MASK|FL_TAINT|FL_SINGLETON); - return dup; + if (RCLASS(clone)->super != 0) { + rb_raise(rb_eTypeError, "already initialized class"); + } + return rb_mod_init_copy(clone, orig); } VALUE @@ -434,8 +432,7 @@ VALUE rb_mod_ancestors(mod) VALUE mod; { - VALUE ary = rb_ary_new(); - VALUE p; + VALUE p, ary = rb_ary_new(); for (p = mod; p; p = RCLASS(p)->super) { if (FL_TEST(p, FL_SINGLETON)) diff --git a/env.h b/env.h index a4802ed448..388c946933 100644 --- a/env.h +++ b/env.h @@ -20,7 +20,6 @@ extern struct FRAME { ID last_func; ID orig_func; VALUE last_class; - VALUE cbase; struct FRAME *prev; struct FRAME *tmp; struct RNode *node; diff --git a/eval.c b/eval.c index acfb22068f..33ccff6247 100644 --- a/eval.c +++ b/eval.c @@ -217,6 +217,7 @@ rb_clear_cache() static void rb_clear_cache_for_undef(klass, id) + VALUE klass; ID id; { struct cache_entry *ent, *end; @@ -591,7 +592,6 @@ static struct SCOPE *top_scope; _frame.tmp = 0; \ _frame.node = ruby_current_node; \ _frame.iter = ruby_iter->iter; \ - _frame.cbase = ruby_frame->cbase; \ _frame.argc = 0; \ _frame.argv = 0; \ _frame.flags = FRAME_ALLOCA; \ @@ -616,6 +616,7 @@ struct BLOCK { struct SCOPE *scope; struct BLOCKTAG *tag; VALUE klass; + NODE *cref; int iter; int vmode; int flags; @@ -652,6 +653,7 @@ new_blktag() _block.self = self; \ _block.frame = *ruby_frame; \ _block.klass = ruby_class; \ + _block.cref = ruby_cref; \ _block.frame.node = ruby_current_node;\ _block.scope = ruby_scope; \ _block.prev = ruby_block; \ @@ -1185,7 +1187,6 @@ ruby_init() ruby_frame->self = ruby_top_self; top_cref = rb_node_newnode(NODE_CREF,rb_cObject,0,0); ruby_cref = top_cref; - ruby_frame->cbase = (VALUE)ruby_cref; rb_define_global_const("TOPLEVEL_BINDING", rb_f_binding(ruby_top_self)); #ifdef __MACOS__ _macruby_init(); @@ -1446,7 +1447,7 @@ rb_eval_string_protect(str, state) const char *str; int *state; { - VALUE result; /* OK */ + VALUE result = Qnil; /* OK */ int status; PUSH_TAG(PROT_NONE); @@ -1483,7 +1484,7 @@ rb_eval_string_wrap(str, state) ruby_frame->orig_func = 0; ruby_frame->last_class = 0; ruby_frame->self = self; - ruby_frame->cbase = (VALUE)rb_node_newnode(NODE_CREF,ruby_wrapper,0,0); + PUSH_CREF(ruby_wrapper); PUSH_SCOPE(); val = rb_eval_string_protect(str, &status); @@ -1582,7 +1583,7 @@ rb_eval_cmd(cmd, arg, tcheck) int tcheck; { int state; - VALUE val; /* OK */ + VALUE val = Qnil; /* OK */ struct SCOPE *saved_scope; volatile int safe = ruby_safe_level; @@ -1600,8 +1601,7 @@ rb_eval_cmd(cmd, arg, tcheck) ruby_frame->orig_func = 0; ruby_frame->last_class = 0; ruby_frame->self = ruby_top_self; - ruby_frame->cbase = (VALUE)rb_node_newnode(NODE_CREF,0,0,0); - RNODE(ruby_frame->cbase)->nd_clss = ruby_wrapper ? ruby_wrapper : rb_cObject; + PUSH_CREF(ruby_wrapper ? ruby_wrapper : rb_cObject); if (tcheck && OBJ_TAINTED(cmd)) { ruby_safe_level = 4; @@ -1627,7 +1627,7 @@ superclass(self, node) VALUE self; NODE *node; { - VALUE val; /* OK */ + VALUE val = Qnil; /* OK */ int state; PUSH_TAG(PROT_NONE); @@ -1659,7 +1659,7 @@ superclass(self, node) return val; } -#define ruby_cbase (RNODE(ruby_frame->cbase)->nd_clss) +#define ruby_cbase (ruby_cref->nd_clss) static VALUE ev_const_defined(cref, id, self) @@ -1713,7 +1713,7 @@ ev_const_get(cref, id, self) static VALUE cvar_cbase() { - NODE *cref = RNODE(ruby_frame->cbase); + NODE *cref = ruby_cref; while (cref && cref->nd_next && FL_TEST(cref->nd_clss, FL_SINGLETON)) { cref = cref->nd_next; @@ -1727,7 +1727,7 @@ cvar_cbase() static VALUE rb_mod_nesting() { - NODE *cbase = RNODE(ruby_frame->cbase); + NODE *cbase = ruby_cref; VALUE ary = rb_ary_new(); while (cbase && cbase->nd_next) { @@ -1743,7 +1743,7 @@ rb_mod_nesting() static VALUE rb_mod_s_constants() { - NODE *cbase = RNODE(ruby_frame->cbase); + NODE *cbase = ruby_cref; void *data = 0; while (cbase) { @@ -1789,7 +1789,7 @@ rb_undef(klass, id) VALUE origin; NODE *body; - if (ruby_class == rb_cObject && klass == ruby_class) { + if (ruby_cbase == rb_cObject && klass == rb_cObject) { rb_secure(4); } if (ruby_safe_level >= 4 && !OBJ_TAINTED(klass)) { @@ -2123,7 +2123,7 @@ is_defined(self, node, buf) break; case NODE_CONST: - if (ev_const_defined(RNODE(ruby_frame->cbase), node->nd_vid, self)) { + if (ev_const_defined(ruby_cref, node->nd_vid, self)) { return "constant"; } break; @@ -3057,7 +3057,6 @@ rb_eval(self, n) if (node->nd_rval) { saved_cref = ruby_cref; ruby_cref = (NODE*)node->nd_rval; - ruby_frame->cbase = node->nd_rval; } if (node->nd_tbl) { VALUE *vars = ALLOCA_N(VALUE, node->nd_tbl[0]+1); @@ -3229,7 +3228,7 @@ rb_eval(self, n) break; case NODE_CONST: - result = ev_const_get(RNODE(ruby_frame->cbase), node->nd_vid, self); + result = ev_const_get(ruby_cref, node->nd_vid, self); break; case NODE_CVAR: @@ -3658,7 +3657,7 @@ module_setup(module, n) NODE * volatile node = n->nd_body; int state; struct FRAME frame; - VALUE result; /* OK */ + VALUE result = Qnil; /* OK */ TMP_PROTECT; frame = *ruby_frame; @@ -3683,7 +3682,6 @@ module_setup(module, n) } PUSH_CREF(module); - ruby_frame->cbase = (VALUE)ruby_cref; PUSH_TAG(PROT_NONE); if ((state = EXEC_TAG()) == 0) { if (trace_func) { @@ -4055,7 +4053,7 @@ rb_yield_0(val, self, klass, flags, avalue) frame.prev = ruby_frame; ruby_frame = &(frame); old_cref = (VALUE)ruby_cref; - ruby_cref = (NODE*)ruby_frame->cbase; + ruby_cref = block->cref; old_wrapper = ruby_wrapper; ruby_wrapper = block->wrapper; old_scope = ruby_scope; @@ -4071,8 +4069,14 @@ rb_yield_0(val, self, klass, flags, avalue) /* FOR does not introduce new scope */ ruby_dyna_vars = block->dyna_vars; } - ruby_class = klass ? klass : block->klass; - if (!klass) self = block->self; + if (klass) { + ruby_class = klass; + PUSH_CREF(klass); + } + else { + ruby_class = block->klass; + self = block->self; + } node = block->body; if (block->var) { @@ -4552,7 +4556,7 @@ rb_protect(proc, data, state) VALUE data; int *state; { - VALUE result; /* OK */ + VALUE result = Qnil; /* OK */ int status; PUSH_TAG(PROT_NONE); @@ -4599,7 +4603,7 @@ rb_with_disable_interrupt(proc, data) VALUE (*proc)(); VALUE data; { - VALUE result; /* OK */ + VALUE result = Qnil; /* OK */ int status; DEFER_INTS; @@ -4941,7 +4945,7 @@ rb_call0(klass, recv, id, oid, argc, argv, body, nosuper) if (body->nd_rval) { saved_cref = ruby_cref; ruby_cref = (NODE*)body->nd_rval; - ruby_frame->cbase = body->nd_rval; + ruby_class = ruby_cbase; } if (body->nd_tbl) { local_vars = TMP_ALLOC(body->nd_tbl[0]+1); @@ -5401,7 +5405,7 @@ eval(self, src, scope, file, line) old_vmode = scope_vmode; scope_vmode = data->vmode; old_cref = (VALUE)ruby_cref; - ruby_cref = (NODE*)ruby_frame->cbase; + ruby_cref = data->cref; old_wrapper = ruby_wrapper; ruby_wrapper = data->wrapper; if ((file == 0 || (line == 1 && strcmp(file, "(eval)") == 0)) && data->body) { @@ -5557,7 +5561,7 @@ exec_under(func, under, cbase, args) VALUE under, cbase; void *args; { - VALUE val; /* OK */ + VALUE val = Qnil; /* OK */ int state; int mode; @@ -5570,9 +5574,6 @@ exec_under(func, under, cbase, args) ruby_frame->argc = _frame.prev->argc; ruby_frame->argv = _frame.prev->argv; if (cbase) { - if (ruby_cbase != cbase) { - ruby_frame->cbase = (VALUE)rb_node_newnode(NODE_CREF,under,0,ruby_frame->cbase); - } PUSH_CREF(cbase); } @@ -5753,7 +5754,7 @@ rb_load(fname, wrap) ruby_frame->last_func = 0; ruby_frame->last_class = 0; ruby_frame->self = self; - ruby_frame->cbase = (VALUE)rb_node_newnode(NODE_CREF,ruby_class,0,0); + PUSH_CREF(ruby_class); PUSH_SCOPE(); /* default visibility is private at loading toplevel */ SCOPE_SET(SCOPE_PRIVATE); @@ -6626,7 +6627,7 @@ rb_f_autoload(obj, sym, file) VALUE sym; VALUE file; { - return rb_mod_autoload(ruby_class, sym, file); + return rb_mod_autoload(ruby_cbase, sym, file); } static VALUE @@ -6634,8 +6635,8 @@ rb_f_autoload_p(obj, sym) VALUE obj; VALUE sym; { - /* use ruby_class as same as rb_f_autoload. */ - return rb_mod_autoload_p(ruby_class, sym); + /* use ruby_cbase as same as rb_f_autoload. */ + return rb_mod_autoload_p(ruby_cbase, sym); } void @@ -6692,7 +6693,7 @@ blk_mark(data) rb_gc_mark((VALUE)data->body); rb_gc_mark((VALUE)data->self); rb_gc_mark((VALUE)data->dyna_vars); - rb_gc_mark((VALUE)data->klass); + rb_gc_mark((VALUE)data->cref); rb_gc_mark((VALUE)data->tag); rb_gc_mark(data->wrapper); rb_gc_mark(data->block_obj); @@ -7424,7 +7425,7 @@ method_call(argc, argv, method) VALUE *argv; VALUE method; { - VALUE result; /* OK */ + VALUE result = Qnil; /* OK */ struct METHOD *data; int state; volatile int safe = ruby_safe_level; @@ -7968,7 +7969,7 @@ rb_trap_eval(cmd, sig) int sig; { int state; - VALUE val; /* OK */ + VALUE val = Qnil; /* OK */ volatile struct thread_status_t save; THREAD_COPY_STATUS(curr_thread, &save); @@ -10070,7 +10071,7 @@ rb_f_catch(dmy, tag) { int state; ID t; - VALUE val; /* OK */ + VALUE val = Qnil; /* OK */ t = rb_to_id(tag); PUSH_TAG(t); diff --git a/gc.c b/gc.c index fe0801c47a..1f8970eed7 100644 --- a/gc.c +++ b/gc.c @@ -1157,7 +1157,6 @@ rb_gc_mark_frame(frame) struct FRAME *frame; { mark_locations_array(frame->argv, frame->argc); - rb_gc_mark(frame->cbase); rb_gc_mark((VALUE)frame->node); } @@ -1229,7 +1228,6 @@ rb_gc() } } } - rb_gc_mark((VALUE)ruby_class); rb_gc_mark((VALUE)ruby_scope); rb_gc_mark((VALUE)ruby_dyna_vars); if (finalizer_table) { diff --git a/intern.h b/intern.h index e94077e70a..1850f7b187 100644 --- a/intern.h +++ b/intern.h @@ -97,8 +97,8 @@ VALUE rb_big_rand _((VALUE, double*)); /* class.c */ VALUE rb_class_boot _((VALUE)); VALUE rb_class_new _((VALUE)); -VALUE rb_mod_clone _((VALUE)); -VALUE rb_mod_dup _((VALUE)); +VALUE rb_mod_init_copy _((VALUE, VALUE)); +VALUE rb_class_init_copy _((VALUE, VALUE)); VALUE rb_singleton_class_clone _((VALUE)); void rb_singleton_class_attached _((VALUE,VALUE)); VALUE rb_make_metaclass _((VALUE, VALUE)); diff --git a/marshal.c b/marshal.c index 835783958d..03992f6bdd 100644 --- a/marshal.c +++ b/marshal.c @@ -84,7 +84,7 @@ static ID s_getc, s_read, s_write, s_binmode; struct dump_arg { VALUE obj; VALUE str, dest; - st_table *symbol; + st_table *symbols; st_table *data; int taint; }; @@ -310,14 +310,14 @@ w_symbol(id, arg) char *sym = rb_id2name(id); long num; - if (st_lookup(arg->symbol, id, &num)) { + if (st_lookup(arg->symbols, id, &num)) { w_byte(TYPE_SYMLINK, arg); w_long(num, arg); } else { w_byte(TYPE_SYMBOL, arg); w_bytes(sym, strlen(sym), arg); - st_add_direct(arg->symbol, id, arg->symbol->num_entries); + st_add_direct(arg->symbols, id, arg->symbols->num_entries); } } @@ -400,9 +400,10 @@ w_uclass(obj, base_klass, arg) VALUE klass = CLASS_OF(obj); w_extended(klass, arg); + klass = rb_class_real(klass); if (klass != base_klass) { w_byte(TYPE_UCLASS, arg); - w_unique(rb_obj_classname(obj), arg); + w_unique(rb_class2name(klass), arg); } } @@ -432,6 +433,10 @@ w_object(obj, arg, limit) if (limit == 0) { rb_raise(rb_eArgError, "exceed depth limit"); } + + if (ivtbl = rb_generic_ivar_table(obj)) { + w_byte(TYPE_IVAR, arg); + } if (obj == Qnil) { w_byte(TYPE_NIL, arg); } @@ -452,13 +457,11 @@ w_object(obj, arg, limit) } else { w_object(rb_int2big(FIX2LONG(obj)), arg, limit); - return; } #endif } else if (SYMBOL_P(obj)) { w_symbol(SYM2ID(obj), arg); - return; } else { long num; @@ -475,10 +478,6 @@ w_object(obj, arg, limit) if (OBJ_TAINTED(obj)) arg->taint = Qtrue; - if (ivtbl = rb_generic_ivar_table(obj)) { - w_byte(TYPE_IVAR, arg); - } - st_add_direct(arg->data, obj, arg->data->num_entries); if (rb_respond_to(obj, s_mdump)) { VALUE v; @@ -641,7 +640,7 @@ w_object(obj, arg, limit) w_class(TYPE_DATA, obj, arg); if (!rb_respond_to(obj, s_dump_data)) { rb_raise(rb_eTypeError, - "class %s needs to have instance method `_dump_data'", + "class %s needs to have instance method `marshal_dump'", rb_obj_classname(obj)); } v = rb_funcall(obj, s_dump_data, 0); @@ -676,7 +675,7 @@ static VALUE dump_ensure(arg) struct dump_arg *arg; { - st_free_table(arg->symbol); + st_free_table(arg->symbols); st_free_table(arg->data); if (arg->taint) { OBJ_TAINT(arg->str); @@ -723,11 +722,11 @@ marshal_dump(argc, argv) arg.str = port; } - arg.symbol = st_init_numtable(); - arg.data = st_init_numtable(); - arg.taint = Qfalse; - c_arg.obj = obj; - c_arg.arg = &arg; + arg.symbols = st_init_numtable(); + arg.data = st_init_numtable(); + arg.taint = Qfalse; + c_arg.obj = obj; + c_arg.arg = &arg; c_arg.limit = limit; w_byte(MARSHAL_MAJOR, &arg); @@ -740,7 +739,7 @@ marshal_dump(argc, argv) struct load_arg { char *ptr, *end; - st_table *symbol; + st_table *symbols; VALUE data; VALUE proc; int taint; @@ -855,7 +854,7 @@ r_symlink(arg) ID id; long num = r_long(arg); - if (st_lookup(arg->symbol, num, &id)) { + if (st_lookup(arg->symbols, num, &id)) { return id; } rb_raise(rb_eArgError, "bad symbol"); @@ -868,7 +867,7 @@ r_symreal(arg) ID id; id = rb_intern(RSTRING(r_bytes(arg))->ptr); - st_insert(arg->symbol, arg->symbol->num_entries, id); + st_insert(arg->symbols, arg->symbols->num_entries, id); return id; } @@ -1295,7 +1294,7 @@ static VALUE load_ensure(arg) struct load_arg *arg; { - st_free_table(arg->symbol); + st_free_table(arg->symbols); return 0; } @@ -1341,7 +1340,7 @@ marshal_load(argc, argv) MARSHAL_MAJOR, MARSHAL_MINOR, major, minor); } - arg.symbol = st_init_numtable(); + arg.symbols = st_init_numtable(); arg.data = rb_hash_new(); if (NIL_P(proc)) arg.proc = 0; else arg.proc = proc; diff --git a/object.c b/object.c index 712c8b7581..67528fb925 100644 --- a/object.c +++ b/object.c @@ -675,49 +675,52 @@ rb_mod_cmp(mod, arg) return INT2FIX(1); } +static VALUE rb_module_s_alloc _((VALUE)); static VALUE -rb_mod_initialize(module) - VALUE module; +rb_module_s_alloc(klass) + VALUE klass; { - if (rb_block_given_p()) { - rb_mod_module_eval(0, 0, module); - } - return Qnil; + VALUE mod = rb_module_new(); + + RBASIC(mod)->klass = klass; + return mod; } static VALUE -rb_class_initialize(argc, argv, klass) +rb_class_s_alloc(argc, argv) int argc; VALUE *argv; - VALUE klass; { - return rb_mod_initialize(klass); + return rb_class_boot(0); } -static VALUE rb_module_s_alloc _((VALUE)); static VALUE -rb_module_s_alloc(klass) - VALUE klass; +rb_mod_initialize(module) + VALUE module; { - VALUE mod = rb_module_new(); - - RBASIC(mod)->klass = klass; - return mod; + if (rb_block_given_p()) { + rb_mod_module_eval(0, 0, module); + } + return Qnil; } static VALUE -rb_class_s_new(argc, argv) +rb_class_initialize(argc, argv, klass) int argc; VALUE *argv; + VALUE klass; { - VALUE super, klass; + VALUE super; + if (RCLASS(klass)->super != 0) { + rb_raise(rb_eTypeError, "already initialized class"); + } if (rb_scan_args(argc, argv, "01", &super) == 0) { super = rb_cObject; } - klass = rb_class_new(super); + RCLASS(klass)->super = super; rb_make_metaclass(klass, RBASIC(super)->klass); - rb_obj_call_init(klass, argc, argv); + rb_mod_initialize(klass); rb_class_inherited(super, klass); return klass; @@ -729,6 +732,9 @@ rb_obj_alloc(klass) { VALUE obj; + if (RCLASS(klass)->super == 0) { + rb_raise(rb_eTypeError, "can't instantiate uninitialized class"); + } if (FL_TEST(klass, FL_SINGLETON)) { rb_raise(rb_eTypeError, "can't create instance of virtual class"); } @@ -769,6 +775,9 @@ rb_class_superclass(klass) { VALUE super = RCLASS(klass)->super; + if (!super) { + rb_raise(rb_eTypeError, "uninitialized class"); + } while (TYPE(super) == T_ICLASS) { super = RCLASS(super)->super; } @@ -1491,8 +1500,7 @@ Init_Object() rb_define_method(rb_cModule, "<=", rb_mod_le, 1); rb_define_method(rb_cModule, ">", rb_mod_gt, 1); rb_define_method(rb_cModule, ">=", rb_mod_ge, 1); - rb_define_method(rb_cModule, "clone", rb_mod_clone, 0); - rb_define_method(rb_cModule, "dup", rb_mod_dup, 0); + rb_define_method(rb_cModule, "initialize_copy", rb_mod_init_copy, 1); rb_define_method(rb_cModule, "to_s", rb_mod_to_s, 0); rb_define_method(rb_cModule, "included_modules", rb_mod_included_modules, 0); rb_define_method(rb_cModule, "include?", rb_mod_include_p, 1); @@ -1524,8 +1532,7 @@ Init_Object() rb_define_method(rb_cClass, "new", rb_class_new_instance, -1); rb_define_method(rb_cClass, "initialize", rb_class_initialize, -1); rb_define_method(rb_cClass, "superclass", rb_class_superclass, 0); - rb_undef_alloc_func(rb_cClass); - rb_define_singleton_method(rb_cClass, "new", rb_class_s_new, -1); + rb_define_alloc_func(rb_cClass, rb_class_s_alloc); rb_undef_method(rb_cClass, "extend_object"); rb_undef_method(rb_cClass, "append_features"); diff --git a/parse.y b/parse.y index fd107555d7..c037fcb772 100644 --- a/parse.y +++ b/parse.y @@ -327,7 +327,7 @@ static void top_local_setup(); program : { lex_state = EXPR_BEG; top_local_init(); - if ((VALUE)ruby_class == rb_cObject) class_nest = 0; + if (ruby_class == rb_cObject) class_nest = 0; else class_nest = 1; } compstmt -- cgit v1.2.3