From bc49bc7c6b6a16d725cd1279e9021465b1307f3d Mon Sep 17 00:00:00 2001 From: matz Date: Fri, 20 Dec 2002 08:33:17 +0000 Subject: * parse.y (do_block): split "do" block and tLBRACE_ARG block. * parse.y (cmd_brace_block): new tLBRACE_ARG block rule * parse.y (command): can take optional cmd_brace_block; use %prec to resolve shift/reduce conflict. (ruby-bugs-ja PR#372) * eval.c (ruby_finalize): trace_func should be cleared here (after executing exit procs and finalizers). * eval.c (rb_define_alloc_func): new allocation framework, based on Nobu's work [ruby-dev:19116]. "allocate" method is no longer used for object allocation. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@3188 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 16 ++++++++++++ array.c | 10 ++++---- dir.c | 2 +- eval.c | 55 ++++++++++++++++++++++++----------------- file.c | 2 +- hash.c | 10 ++++---- intern.h | 4 +++ io.c | 42 ++++++++++++++----------------- lib/profile.rb | 46 +++++++++++++++++++--------------- numeric.c | 4 +-- object.c | 26 ++++++++------------ parse.y | 78 ++++++++++++++++++++++++++++++++++++++++++++-------------- re.c | 4 +-- string.c | 16 ++++++------ struct.c | 4 +-- time.c | 2 +- 16 files changed, 194 insertions(+), 127 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4848da0e9e..8c7f1ab48b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +Fri Dec 20 16:20:04 2002 Yukihiro Matsumoto + + * parse.y (do_block): split "do" block and tLBRACE_ARG block. + + * parse.y (cmd_brace_block): new tLBRACE_ARG block rule + + * parse.y (command): can take optional cmd_brace_block; use %prec + to resolve shift/reduce conflict. (ruby-bugs-ja PR#372) + + * eval.c (ruby_finalize): trace_func should be cleared here (after + executing exit procs and finalizers). + + * eval.c (rb_define_alloc_func): new allocation framework, based + on Nobu's work [ruby-dev:19116]. "allocate" method is no longer + used for object allocation. + Fri Dec 20 05:06:49 2002 Akinori MUSHA * lib/README, lib/cgi/ftplib.rb, lib/telnet.rb: Delete ftplib.rb diff --git a/array.c b/array.c index 927d4dcbde..9c880e04bc 100644 --- a/array.c +++ b/array.c @@ -87,7 +87,7 @@ rb_ary_frozen_p(ary) } static VALUE -rb_ary_s_alloc(klass) +ary_alloc(klass) VALUE klass; { NEWOBJ(ary, struct RArray); @@ -105,7 +105,7 @@ ary_new(klass, len) VALUE klass; long len; { - VALUE ary = rb_obj_alloc(klass); + VALUE ary = ary_alloc(klass); if (len < 0) { rb_raise(rb_eArgError, "negative array size (or size too big)"); @@ -275,7 +275,7 @@ rb_ary_s_create(argc, argv, klass) VALUE *argv; VALUE klass; { - VALUE ary = rb_obj_alloc(klass); + VALUE ary = ary_alloc(klass); if (argc < 0) { rb_raise(rb_eArgError, "negative number of arguments"); @@ -480,7 +480,7 @@ rb_ary_subseq(ary, beg, len) if (len == 0) return ary_new(klass, 0); ary_make_shared(ary); - ary2 = rb_obj_alloc(klass); + ary2 = ary_alloc(klass); RARRAY(ary2)->ptr = RARRAY(ary)->ptr + beg; RARRAY(ary2)->len = len; RARRAY(ary2)->aux.shared = RARRAY(ary)->aux.shared; @@ -1872,7 +1872,7 @@ Init_Array() rb_cArray = rb_define_class("Array", rb_cObject); rb_include_module(rb_cArray, rb_mEnumerable); - rb_define_singleton_method(rb_cArray, "allocate", rb_ary_s_alloc, 0); + rb_define_alloc_func(rb_cArray, ary_alloc); rb_define_singleton_method(rb_cArray, "[]", rb_ary_s_create, -1); rb_define_method(rb_cArray, "initialize", rb_ary_initialize, -1); rb_define_method(rb_cArray, "to_s", rb_ary_to_s, 0); diff --git a/dir.c b/dir.c index 779407131e..e04fac67d6 100644 --- a/dir.c +++ b/dir.c @@ -1074,7 +1074,7 @@ Init_Dir() rb_include_module(rb_cDir, rb_mEnumerable); - rb_define_singleton_method(rb_cDir, "allocate", dir_s_alloc, 0); + rb_define_alloc_func(rb_cDir, dir_s_alloc); rb_define_singleton_method(rb_cDir, "open", dir_s_open, 1); rb_define_singleton_method(rb_cDir, "foreach", dir_foreach, 1); rb_define_singleton_method(rb_cDir, "entries", dir_entries, 1); diff --git a/eval.c b/eval.c index bc4dc46c24..5630d34314 100644 --- a/eval.c +++ b/eval.c @@ -250,12 +250,35 @@ rb_add_method(klass, mid, node, noex) if (mid == init && !FL_TEST(klass, FL_SINGLETON) && node && nd_type(node) != NODE_ZSUPER) { noex = NOEX_PRIVATE | (noex & NOEX_NOSUPER); } + else if (mid == alloc && FL_TEST(klass, FL_SINGLETON) && node && nd_type(node) == NODE_CFUNC) { + rb_warn("defining %s.allocate is deprecated; use rb_define_alloc_func()", + rb_class2name(rb_iv_get(klass, "__attached__"))); + mid = ID_ALLOCATOR; + } if (OBJ_FROZEN(klass)) rb_error_frozen("class/module"); rb_clear_cache_by_id(mid); body = NEW_METHOD(node, noex); st_insert(RCLASS(klass)->m_tbl, mid, body); } +void +rb_define_alloc_func(klass, func) + VALUE klass; + VALUE (*func) _((VALUE)); +{ + Check_Type(klass, T_CLASS); + rb_add_method(CLASS_OF(klass), ID_ALLOCATOR, NEW_CFUNC(func, 0), + NOEX_PRIVATE|NOEX_CFUNC); +} + +void +rb_undef_alloc_func(klass) + VALUE klass; +{ + Check_Type(klass, T_CLASS); + rb_add_method(CLASS_OF(klass), ID_ALLOCATOR, 0, NOEX_UNDEF); +} + static NODE* search_method(klass, id, origin) VALUE klass, *origin; @@ -337,13 +360,6 @@ remove_method(klass, mid) if (mid == __id__ || mid == __send__ || mid == init) { rb_warn("removing `%s' may cause serious problem", rb_id2name(mid)); } - if (mid == alloc) { - if (klass == rb_cClass || - (FL_TEST(klass, FL_SINGLETON) && - rb_obj_is_kind_of(rb_iv_get(klass, "__attached__"), rb_cClass))) { - rb_name_error(mid, "removing `%s'", rb_id2name(mid)); - } - } if (!st_delete(RCLASS(klass)->m_tbl, &mid, &body) || !body->nd_body) { rb_name_error(mid, "method `%s' not defined in %s", rb_id2name(mid), rb_class2name(klass)); @@ -1229,6 +1245,8 @@ ruby_finalize() rb_gc_call_finalizer_at_exit(); } POP_TAG(); + trace_func = 0; + tracing = 0; } int @@ -1248,8 +1266,6 @@ ruby_cleanup(ex) } POP_ITER(); - trace_func = 0; - tracing = 0; ex = error_handle(ex); POP_TAG(); ruby_finalize(); @@ -1649,7 +1665,7 @@ rb_undef(klass, id) rb_raise(rb_eSecurityError, "Insecure: can't undef `%s'", rb_id2name(id)); } rb_frozen_class_p(klass); - if (id == __id__ || id == __send__ || id == init || id == alloc) { + if (id == __id__ || id == __send__ || id == init) { rb_warn("undefining `%s' may cause serious problem", rb_id2name(id)); } body = search_method(klass, id, &origin); @@ -1716,9 +1732,6 @@ rb_alias(klass, name, def) } if (FL_TEST(klass, FL_SINGLETON)) { singleton = rb_iv_get(klass, "__attached__"); - if (name == alloc && TYPE(singleton) == T_CLASS) { - rb_raise(rb_eNameError, "cannot make alias named `allocate'"); - } } body = orig->nd_body; orig->nd_cnt++; @@ -3196,9 +3209,6 @@ rb_eval(self, n) if (NIL_P(ruby_class)) { rb_raise(rb_eTypeError, "no class/module to add method"); } - if (ruby_class == rb_cClass && node->nd_mid == alloc) { - rb_raise(rb_eNameError, "redefining Class#allocate will cause infinite loop"); - } if (ruby_class == rb_cObject && node->nd_mid == init) { rb_warn("redefining Object#initialize may cause infinite loop"); } @@ -4598,6 +4608,7 @@ rb_call0(klass, recv, id, oid, argc, argv, body, nosuper) if (trace_func) { int state; + if (id == ID_ALLOCATOR) id = alloc; call_trace_func("c-call", ruby_current_node, recv, id, klass); PUSH_TAG(PROT_FUNC); if ((state = EXEC_TAG()) == 0) { @@ -7260,7 +7271,7 @@ Init_Proc() rb_eSysStackError = rb_define_class("SystemStackError", rb_eStandardError); rb_cProc = rb_define_class("Proc", rb_cObject); - rb_undef_method(CLASS_OF(rb_cProc), "allocate"); + rb_undef_alloc_func(rb_cProc); rb_define_singleton_method(rb_cProc, "new", proc_s_new, -1); rb_define_method(rb_cProc, "call", proc_call, -2); @@ -7275,12 +7286,12 @@ Init_Proc() rb_define_global_function("lambda", rb_f_lambda, 0); rb_define_global_function("binding", rb_f_binding, 0); rb_cBinding = rb_define_class("Binding", rb_cObject); - rb_undef_method(CLASS_OF(rb_cBinding), "allocate"); + rb_undef_alloc_func(rb_cBinding); rb_undef_method(CLASS_OF(rb_cBinding), "new"); rb_define_method(rb_cBinding, "clone", bind_clone, 0); rb_cMethod = rb_define_class("Method", rb_cObject); - rb_undef_method(CLASS_OF(rb_cMethod), "allocate"); + rb_undef_alloc_func(rb_cMethod); rb_undef_method(CLASS_OF(rb_cMethod), "new"); rb_define_method(rb_cMethod, "==", method_eq, 1); rb_define_method(rb_cMethod, "clone", method_clone, 0); @@ -9454,7 +9465,7 @@ Init_Thread() rb_eThreadError = rb_define_class("ThreadError", rb_eStandardError); rb_cThread = rb_define_class("Thread", rb_cObject); - rb_undef_method(CLASS_OF(rb_cThread), "allocate"); + rb_undef_alloc_func(rb_cThread); rb_define_singleton_method(rb_cThread, "new", rb_thread_s_new, -1); rb_define_method(rb_cThread, "initialize", rb_thread_initialize, -2); @@ -9506,13 +9517,13 @@ Init_Thread() curr_thread = main_thread->prev = main_thread->next = main_thread; rb_cCont = rb_define_class("Continuation", rb_cObject); - rb_undef_method(CLASS_OF(rb_cCont), "allocate"); + rb_undef_alloc_func(rb_cCont); rb_undef_method(CLASS_OF(rb_cCont), "new"); rb_define_method(rb_cCont, "call", rb_cont_call, -1); rb_define_global_function("callcc", rb_callcc, 0); cThGroup = rb_define_class("ThreadGroup", rb_cObject); - rb_define_singleton_method(cThGroup, "allocate", thgroup_s_alloc, 0); + rb_define_alloc_func(cThGroup, thgroup_s_alloc); rb_define_method(cThGroup, "list", thgroup_list, 0); rb_define_method(cThGroup, "add", thgroup_add, 1); rb_define_const(cThGroup, "Default", rb_obj_alloc(cThGroup)); diff --git a/file.c b/file.c index 4905de9f0b..add70d2697 100644 --- a/file.c +++ b/file.c @@ -2653,7 +2653,7 @@ Init_File() rb_define_global_function("test", rb_f_test, -1); rb_cStat = rb_define_class_under(rb_cFile, "Stat", rb_cObject); - rb_define_singleton_method(rb_cStat, "allocate", rb_stat_s_alloc, 0); + rb_define_alloc_func(rb_cStat, rb_stat_s_alloc); rb_define_method(rb_cStat, "initialize", rb_stat_init, 1); rb_define_method(rb_cStat, "copy_object", rb_stat_copy_object, 1); diff --git a/hash.c b/hash.c index 245ba53e5a..16b89bfacd 100644 --- a/hash.c +++ b/hash.c @@ -179,7 +179,7 @@ rb_hash_foreach(hash, func, farg) } static VALUE -rb_hash_s_alloc(klass) +hash_alloc(klass) VALUE klass; { NEWOBJ(hash, struct RHash); @@ -194,7 +194,7 @@ rb_hash_s_alloc(klass) VALUE rb_hash_new() { - return rb_hash_s_alloc(rb_cHash); + return hash_alloc(rb_cHash); } static VALUE @@ -231,7 +231,7 @@ rb_hash_s_create(argc, argv, klass) int i; if (argc == 1 && TYPE(argv[0]) == T_HASH) { - hash = rb_obj_alloc(klass); + hash = hash_alloc(klass); RHASH(hash)->ifnone = Qnil; RHASH(hash)->tbl = st_copy(RHASH(argv[0])->tbl); @@ -243,7 +243,7 @@ rb_hash_s_create(argc, argv, klass) rb_raise(rb_eArgError, "odd number args for Hash"); } - hash = rb_obj_alloc(klass); + hash = hash_alloc(klass); for (i=0; ifptr = 0; + + return (VALUE)io; +} + static void io_fflush(f, fptr) FILE *f; @@ -1813,9 +1825,7 @@ VALUE rb_file_open(fname, mode) const char *fname, *mode; { - VALUE io = rb_obj_alloc(rb_cFile); - - return rb_file_open_internal(io, fname, mode); + return rb_file_open_internal(io_alloc(rb_cFile), fname, mode); } static VALUE @@ -1845,9 +1855,7 @@ rb_file_sysopen(fname, flags, mode) const char *fname; int flags, mode; { - VALUE io = rb_obj_alloc(rb_cFile); - - return rb_file_sysopen_internal(io, fname, flags, mode); + return rb_file_sysopen_internal(io_alloc(rb_cFile)); } #if defined (_WIN32) || defined(DJGPP) || defined(__CYGWIN__) || defined(__human68k__) || defined(__VMS) @@ -1960,7 +1968,7 @@ pipe_open(pname, mode) if (!f) rb_sys_fail(pname); else { - VALUE port = rb_obj_alloc(rb_cIO); + VALUE port = io_alloc(rb_cIO); MakeOpenFile(port, fptr); fptr->finalize = pipe_finalize; @@ -1990,7 +1998,7 @@ retry: rb_sys_fail(pname); } else { - VALUE port = rb_obj_alloc(rb_cIO); + VALUE port = io_alloc(rb_cIO); MakeOpenFile(port, fptr); fptr->mode = modef; @@ -2067,7 +2075,7 @@ retry: default: /* parent */ if (pid < 0) rb_sys_fail(pname); else { - VALUE port = rb_obj_alloc(rb_cIO); + VALUE port = io_alloc(rb_cIO); MakeOpenFile(port, fptr); fptr->mode = modef; @@ -2758,7 +2766,7 @@ prep_stdio(f, mode, klass) VALUE klass; { OpenFile *fp; - VALUE io = rb_obj_alloc(klass); + VALUE io = io_alloc(klass); MakeOpenFile(io, fp); fp->f = f; @@ -2779,18 +2787,6 @@ prep_path(io, path) fptr->path = strdup(path); } -static VALUE -rb_io_s_alloc(klass) - VALUE klass; -{ - NEWOBJ(io, struct RFile); - OBJSETUP(io, klass, T_FILE); - - io->fptr = 0; - - return (VALUE)io; -} - static VALUE rb_io_initialize(argc, argv, io) int argc; @@ -3903,7 +3899,7 @@ Init_IO() rb_cIO = rb_define_class("IO", rb_cObject); rb_include_module(rb_cIO, rb_mEnumerable); - rb_define_singleton_method(rb_cIO, "allocate", rb_io_s_alloc, 0); + rb_define_alloc_func(rb_cIO, io_alloc); rb_define_singleton_method(rb_cIO, "new", rb_io_s_new, -1); rb_define_singleton_method(rb_cIO, "open", rb_io_s_open, -1); rb_define_singleton_method(rb_cIO, "sysopen", rb_io_s_sysopen, -1); diff --git a/lib/profile.rb b/lib/profile.rb index 23840c4e19..e295f6e069 100644 --- a/lib/profile.rb +++ b/lib/profile.rb @@ -1,19 +1,15 @@ - module Profiler__ Times = if defined? Process.times then Process else Time end - Start = Float(Times::times[0]) - top = "toplevel".intern - Stack = [[0, 0, top]] - MAP = {"#toplevel" => [1, 0, 0, "#toplevel"]} - - p = proc{|event, file, line, id, binding, klass| + # internal values + @@start = @@stack = @@map = nil + PROFILE_PROC = proc{|event, file, line, id, binding, klass| case event when "call", "c-call" now = Float(Times::times[0]) - Stack.push [now, 0.0, id] + @@stack.push [now, 0.0, id] when "return", "c-return" now = Float(Times::times[0]) - tick = Stack.pop + tick = @@stack.pop name = klass.to_s if name.nil? then name = '' end if klass.kind_of? Class @@ -22,26 +18,34 @@ module Profiler__ name += "." end name += id.id2name - data = MAP[name] + data = @@map[name] unless data data = [0.0, 0.0, 0.0, name] - MAP[name] = data + @@map[name] = data end data[0] += 1 cost = now - tick[0] data[1] += cost data[2] += cost - tick[1] - Stack[-1][1] += cost + @@stack[-1][1] += cost end } - END { +module_function + def start_profile + @@start = Float(Times::times[0]) + @@stack = [[0, 0, :toplevel], [0, 0, :dummy]] + @@map = {"#toplevel" => [1, 0, 0, "#toplevel"]} + set_trace_func PROFILE_PROC + end + def stop_profile set_trace_func nil - total = Float(Times::times[0]) - Start + end + def print_profile(f) + stop_profile + total = Float(Times::times[0]) - @@start if total == 0 then total = 0.01 end - MAP["#toplevel"][1] = total -# f = open("./rmon.out", "w") - f = STDERR - data = MAP.values + @@map["#toplevel"][1] = total + data = @@map.values data.sort!{|a,b| b[2] <=> a[2]} sum = 0 f.printf " %% cumulative self self total\n" @@ -51,7 +55,9 @@ module Profiler__ f.printf "%6.2f %8.2f %8.2f %8d ", d[2]/total*100, sum, d[2], d[0] f.printf "%8.2f %8.2f %s\n", d[2]*1000/d[0], d[1]*1000/d[0], d[3] end - f.close + end + END { + print_profile(STDERR) } - set_trace_func p + start_profile end diff --git a/numeric.c b/numeric.c index 0e2116460e..73fa329479 100644 --- a/numeric.c +++ b/numeric.c @@ -1698,7 +1698,7 @@ Init_Numeric() rb_define_method(rb_cNumeric, "step", num_step, -1); rb_cInteger = rb_define_class("Integer", rb_cNumeric); - rb_undef_method(CLASS_OF(rb_cInteger), "allocate"); + rb_undef_alloc_func(rb_cInteger); rb_undef_method(CLASS_OF(rb_cInteger), "new"); rb_define_method(rb_cInteger, "integer?", int_int_p, 0); @@ -1761,7 +1761,7 @@ Init_Numeric() rb_cFloat = rb_define_class("Float", rb_cNumeric); - rb_undef_method(CLASS_OF(rb_cFloat), "allocate"); + rb_undef_alloc_func(rb_cFloat); rb_undef_method(CLASS_OF(rb_cFloat), "new"); rb_define_singleton_method(rb_cFloat, "induced_from", rb_flo_induced_from, 1); diff --git a/object.c b/object.c index 736348279d..6b59de3469 100644 --- a/object.c +++ b/object.c @@ -34,7 +34,6 @@ VALUE rb_cSymbol; static ID eq, eql; static ID inspect; static ID copy_obj; -static ID alloc; VALUE rb_equal(obj1, obj2) @@ -717,7 +716,7 @@ VALUE rb_obj_alloc(klass) VALUE klass; { - VALUE obj = rb_funcall(klass, alloc, 0, 0); + VALUE obj = rb_funcall(klass, ID_ALLOCATOR, 0, 0); if (rb_obj_class(obj) != rb_class_real(klass)) { rb_raise(rb_eTypeError, "wrong instance allocation"); @@ -732,10 +731,7 @@ rb_class_allocate_instance(klass) if (FL_TEST(klass, FL_SINGLETON)) { rb_raise(rb_eTypeError, "can't create instance of virtual class"); } - if (rb_frame_last_func() != alloc) { - return rb_obj_alloc(klass); - } - else { + { NEWOBJ(obj, struct RObject); OBJSETUP(obj, klass, T_OBJECT); return (VALUE)obj; @@ -1271,8 +1267,6 @@ Init_Object() { VALUE metaclass; - alloc = rb_intern("allocate"); - rb_cObject = boot_defclass("Object", 0); rb_cModule = boot_defclass("Module", rb_cObject); rb_cClass = boot_defclass("Class", rb_cModule); @@ -1283,6 +1277,7 @@ Init_Object() rb_mKernel = rb_define_module("Kernel"); rb_include_module(rb_cObject, rb_mKernel); + rb_define_alloc_func(rb_cObject, rb_class_allocate_instance); rb_define_private_method(rb_cObject, "initialize", rb_obj_dummy, 0); rb_define_private_method(rb_cClass, "inherited", rb_obj_dummy, 1); rb_define_private_method(rb_cModule, "included", rb_obj_dummy, 1); @@ -1380,13 +1375,13 @@ Init_Object() rb_define_method(rb_cNilClass, "^", false_xor, 1); rb_define_method(rb_cNilClass, "nil?", rb_true, 0); - rb_undef_method(CLASS_OF(rb_cNilClass), "allocate"); + rb_undef_alloc_func(rb_cNilClass); rb_undef_method(CLASS_OF(rb_cNilClass), "new"); rb_define_global_const("NIL", Qnil); rb_cSymbol = rb_define_class("Symbol", rb_cObject); rb_define_singleton_method(rb_cSymbol, "all_symbols", rb_sym_all_symbols, 0); - rb_undef_method(CLASS_OF(rb_cSymbol), "allocate"); + rb_undef_alloc_func(rb_cSymbol); rb_undef_method(CLASS_OF(rb_cSymbol), "new"); rb_define_method(rb_cSymbol, "to_i", sym_to_i, 0); @@ -1416,7 +1411,7 @@ Init_Object() rb_define_private_method(rb_cModule, "attr_writer", rb_mod_attr_writer, -1); rb_define_private_method(rb_cModule, "attr_accessor", rb_mod_attr_accessor, -1); - rb_define_singleton_method(rb_cModule, "allocate", rb_module_s_alloc, 0); + rb_define_alloc_func(rb_cModule, rb_module_s_alloc); rb_define_method(rb_cModule, "initialize", rb_mod_initialize, 0); rb_define_method(rb_cModule, "instance_methods", rb_class_instance_methods, -1); rb_define_method(rb_cModule, "public_instance_methods", rb_class_public_instance_methods, -1); @@ -1431,17 +1426,16 @@ Init_Object() rb_define_method(rb_cModule, "class_variables", rb_mod_class_variables, 0); rb_define_private_method(rb_cModule, "remove_class_variable", rb_mod_remove_cvar, 1); - rb_define_method(rb_cClass, "allocate", rb_class_allocate_instance, 0); 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_method(CLASS_OF(rb_cClass), "allocate"); + rb_undef_alloc_func(rb_cClass); rb_define_singleton_method(rb_cClass, "new", rb_class_s_new, -1); rb_undef_method(rb_cClass, "extend_object"); rb_undef_method(rb_cClass, "append_features"); rb_cData = rb_define_class("Data", rb_cObject); - rb_undef_method(CLASS_OF(rb_cData), "allocate"); + rb_undef_alloc_func(rb_cData); ruby_top_self = rb_obj_alloc(rb_cObject); rb_global_variable(&ruby_top_self); @@ -1452,7 +1446,7 @@ Init_Object() rb_define_method(rb_cTrueClass, "&", true_and, 1); rb_define_method(rb_cTrueClass, "|", true_or, 1); rb_define_method(rb_cTrueClass, "^", true_xor, 1); - rb_undef_method(CLASS_OF(rb_cTrueClass), "allocate"); + rb_undef_alloc_func(rb_cTrueClass); rb_undef_method(CLASS_OF(rb_cTrueClass), "new"); rb_define_global_const("TRUE", Qtrue); @@ -1461,7 +1455,7 @@ Init_Object() rb_define_method(rb_cFalseClass, "&", false_and, 1); rb_define_method(rb_cFalseClass, "|", false_or, 1); rb_define_method(rb_cFalseClass, "^", false_xor, 1); - rb_undef_method(CLASS_OF(rb_cFalseClass), "allocate"); + rb_undef_alloc_func(rb_cFalseClass); rb_undef_method(CLASS_OF(rb_cFalseClass), "new"); rb_define_global_const("FALSE", Qfalse); diff --git a/parse.y b/parse.y index b1d2bfe8f8..5db815e122 100644 --- a/parse.y +++ b/parse.y @@ -248,7 +248,7 @@ static void top_local_setup(); %type mrhs mrhs_basic superclass block_call block_command %type f_arglist f_args f_optarg f_opt f_block_arg opt_f_block_arg %type assoc_list assocs assoc undef_list backref string_dvar -%type block_var opt_block_var brace_block do_block lhs none +%type block_var opt_block_var brace_block cmd_brace_block do_block lhs none %type mlhs mlhs_head mlhs_basic mlhs_entry mlhs_item mlhs_node %type fitem variable sym symbol operation operation2 operation3 %type cname fname op f_rest_arg @@ -286,6 +286,9 @@ static void top_local_setup(); * precedence table */ +%nonassoc LOWEST +%nonassoc tLBRACE_ARG + %left kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD %left kOR kAND %right kNOT @@ -613,21 +616,72 @@ block_command : block_call } ; -command : operation command_args +cmd_brace_block : tLBRACE_ARG + { + $$ = dyna_push(); + $1 = ruby_sourceline; + } + opt_block_var + compstmt + '}' + { + $$ = NEW_ITER($3, 0, $4); + nd_set_line($$, $1); + dyna_pop($2); + } + ; + +command : operation command_args %prec LOWEST + { + $$ = new_fcall($1, $2); + fixpos($$, $2); + } + | operation command_args cmd_brace_block { $$ = new_fcall($1, $2); + if ($3) { + if (nd_type($$) == NODE_BLOCK_PASS) { + rb_compile_error("both block arg and actual block given"); + } + $3->nd_iter = $$; + $$ = $3; + } fixpos($$, $2); } - | primary_value '.' operation2 command_args + | primary_value '.' operation2 command_args %prec LOWEST { $$ = new_call($1, $3, $4); fixpos($$, $1); } - | primary_value tCOLON2 operation2 command_args + | primary_value '.' operation2 command_args cmd_brace_block + { + $$ = new_call($1, $3, $4); + if ($5) { + if (nd_type($$) == NODE_BLOCK_PASS) { + rb_compile_error("both block arg and actual block given"); + } + $5->nd_iter = $$; + $$ = $5; + } + fixpos($$, $1); + } + | primary_value tCOLON2 operation2 command_args %prec LOWEST { $$ = new_call($1, $3, $4); fixpos($$, $1); } + | primary_value tCOLON2 operation2 command_args cmd_brace_block + { + $$ = new_call($1, $3, $4); + if ($5) { + if (nd_type($$) == NODE_BLOCK_PASS) { + rb_compile_error("both block arg and actual block given"); + } + $5->nd_iter = $$; + $$ = $5; + } + fixpos($$, $1); + } | kSUPER command_args { $$ = new_super($2); @@ -1606,20 +1660,6 @@ do_block : kDO_BLOCK nd_set_line($$, $1); dyna_pop($2); } - | tLBRACE_ARG - { - $$ = dyna_push(); - $1 = ruby_sourceline; - } - opt_block_var - compstmt - '}' - { - $$ = NEW_ITER($3, 0, $4); - nd_set_line($$, $1); - dyna_pop($2); - } - ; block_call : command do_block @@ -1629,7 +1669,7 @@ block_call : command do_block } $2->nd_iter = $1; $$ = $2; - fixpos($$, $2); + fixpos($$, $1); } | block_call '.' operation2 opt_paren_args { diff --git a/re.c b/re.c index 354bab28e1..1757e968c7 100644 --- a/re.c +++ b/re.c @@ -1594,7 +1594,7 @@ Init_Regexp() rb_define_virtual_variable("$-K", kcode_getter, kcode_setter); rb_cRegexp = rb_define_class("Regexp", rb_cObject); - rb_define_singleton_method(rb_cRegexp, "allocate", rb_reg_s_alloc, 0); + rb_define_alloc_func(rb_cRegexp, rb_reg_s_alloc); rb_define_singleton_method(rb_cRegexp, "compile", rb_class_new_instance, -1); rb_define_singleton_method(rb_cRegexp, "quote", rb_reg_s_quote, -1); rb_define_singleton_method(rb_cRegexp, "escape", rb_reg_s_quote, -1); @@ -1624,7 +1624,7 @@ Init_Regexp() rb_cMatch = rb_define_class("MatchData", rb_cObject); rb_define_global_const("MatchingData", rb_cMatch); - rb_define_singleton_method(rb_cMatch, "allocate", match_alloc, 0); + rb_define_alloc_func(rb_cMatch, match_alloc); rb_undef_method(CLASS_OF(rb_cMatch), "new"); rb_define_method(rb_cMatch, "copy_object", match_copy_object, 1); diff --git a/string.c b/string.c index 23a804a829..d9de50bf6c 100644 --- a/string.c +++ b/string.c @@ -37,7 +37,7 @@ VALUE rb_cString; VALUE rb_fs; static VALUE -rb_str_s_alloc(klass) +str_alloc(klass) VALUE klass; { NEWOBJ(str, struct RString); @@ -62,7 +62,7 @@ str_new(klass, ptr, len) rb_raise(rb_eArgError, "negative string size (or size too big)"); } - str = rb_obj_alloc(klass); + str = str_alloc(klass); RSTRING(str)->len = len; RSTRING(str)->aux.capa = len; RSTRING(str)->ptr = ALLOC_N(char,len+1); @@ -119,7 +119,7 @@ static VALUE str_new3(klass, str) VALUE klass, str; { - VALUE str2 = rb_obj_alloc(klass); + VALUE str2 = str_alloc(klass); RSTRING(str2)->len = RSTRING(str)->len; RSTRING(str2)->ptr = RSTRING(str)->ptr; @@ -141,7 +141,7 @@ static VALUE str_new4(klass, str) VALUE klass, str; { - VALUE str2 = rb_obj_alloc(klass); + VALUE str2 = str_alloc(klass); RSTRING(str2)->len = RSTRING(str)->len; RSTRING(str2)->ptr = RSTRING(str)->ptr; @@ -193,7 +193,7 @@ VALUE rb_str_buf_new(capa) long capa; { - VALUE str = rb_obj_alloc(rb_cString); + VALUE str = str_alloc(rb_cString); if (capa < STR_BUF_MIN_SIZE) { capa = STR_BUF_MIN_SIZE; @@ -281,7 +281,7 @@ VALUE rb_str_dup(str) VALUE str; { - VALUE dup = rb_str_s_alloc(rb_cString); + VALUE dup = str_alloc(rb_cString); rb_str_replace(dup, str); return dup; } @@ -1629,7 +1629,7 @@ str_gsub(argc, argv, str, bang) FL_UNSET(str, ELTS_SHARED|STR_ASSOC); } else { - VALUE dup = rb_obj_alloc(rb_obj_class(str)); + VALUE dup = str_alloc(rb_obj_class(str)); OBJ_INFECT(dup, str); str = dup; @@ -3190,7 +3190,7 @@ Init_String() rb_cString = rb_define_class("String", rb_cObject); rb_include_module(rb_cString, rb_mComparable); rb_include_module(rb_cString, rb_mEnumerable); - rb_define_singleton_method(rb_cString, "allocate", rb_str_s_alloc, 0); + rb_define_alloc_func(rb_cString, str_alloc); rb_define_method(rb_cString, "initialize", rb_str_init, -1); rb_define_method(rb_cString, "copy_object", rb_str_replace, 1); rb_define_method(rb_cString, "<=>", rb_str_cmp_m, 1); diff --git a/struct.c b/struct.c index e8ae73a5e7..5081174ce0 100644 --- a/struct.c +++ b/struct.c @@ -169,7 +169,7 @@ make_struct(name, member, klass) rb_iv_set(nstr, "__size__", LONG2NUM(RARRAY(member)->len)); rb_iv_set(nstr, "__member__", member); - rb_define_singleton_method(nstr, "allocate", struct_alloc, 0); + rb_define_alloc_func(nstr, struct_alloc); rb_define_singleton_method(nstr, "new", rb_class_new_instance, -1); rb_define_singleton_method(nstr, "[]", rb_class_new_instance, -1); rb_define_singleton_method(nstr, "members", rb_struct_s_members, 0); @@ -588,7 +588,7 @@ Init_Struct() rb_cStruct = rb_define_class("Struct", rb_cObject); rb_include_module(rb_cStruct, rb_mEnumerable); - rb_undef_method(CLASS_OF(rb_cStruct), "allocate"); + rb_undef_alloc_func(rb_cStruct); rb_define_singleton_method(rb_cStruct, "new", rb_struct_s_def, -1); rb_define_method(rb_cStruct, "initialize", rb_struct_initialize, -2); diff --git a/time.c b/time.c index cb3b3d79f3..2d533d156c 100644 --- a/time.c +++ b/time.c @@ -1397,7 +1397,7 @@ Init_Time() rb_include_module(rb_cTime, rb_mComparable); rb_define_singleton_method(rb_cTime, "now", time_s_now, 0); - rb_define_singleton_method(rb_cTime, "allocate", time_s_alloc, 0); + rb_define_alloc_func(rb_cTime, time_s_alloc); rb_define_singleton_method(rb_cTime, "at", time_s_at, -1); rb_define_singleton_method(rb_cTime, "utc", time_s_mkutc, -1); rb_define_singleton_method(rb_cTime, "gm", time_s_mkutc, -1); -- cgit v1.2.3