summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog16
-rw-r--r--array.c10
-rw-r--r--dir.c2
-rw-r--r--eval.c55
-rw-r--r--file.c2
-rw-r--r--hash.c10
-rw-r--r--intern.h4
-rw-r--r--io.c42
-rw-r--r--lib/profile.rb46
-rw-r--r--numeric.c4
-rw-r--r--object.c26
-rw-r--r--parse.y78
-rw-r--r--re.c4
-rw-r--r--string.c16
-rw-r--r--struct.c4
-rw-r--r--time.c2
16 files changed, 194 insertions, 127 deletions
diff --git a/ChangeLog b/ChangeLog
index 4848da0..8c7f1ab 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+Fri Dec 20 16:20:04 2002 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * 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 <knu@iDaemons.org>
* lib/README, lib/cgi/ftplib.rb, lib/telnet.rb: Delete ftplib.rb
diff --git a/array.c b/array.c
index 927d4dc..9c880e0 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 7794071..e04fac6 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 bc4dc46..5630d34 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 4905de9..add70d2 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 245ba53..16b89bf 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; i<argc; i+=2) {
rb_hash_aset(hash, argv[i], argv[i + 1]);
}
@@ -1595,7 +1595,7 @@ Init_Hash()
rb_include_module(rb_cHash, rb_mEnumerable);
- rb_define_singleton_method(rb_cHash, "allocate", rb_hash_s_alloc, 0);
+ rb_define_alloc_func(rb_cHash, hash_alloc);
rb_define_singleton_method(rb_cHash, "[]", rb_hash_s_create, -1);
rb_define_method(rb_cHash,"initialize", rb_hash_initialize, -1);
diff --git a/intern.h b/intern.h
index eca1fd1..46ceb7d 100644
--- a/intern.h
+++ b/intern.h
@@ -17,6 +17,8 @@
* the kernel.
*/
+#define ID_ALLOCATOR 1
+
/* array.c */
void rb_mem_clear _((register VALUE*, register long));
VALUE rb_assoc_new _((VALUE, VALUE));
@@ -144,6 +146,8 @@ VALUE rb_f_abort _((int,VALUE*));
void rb_remove_method _((VALUE, const char*));
void rb_disable_super _((VALUE, const char*));
void rb_enable_super _((VALUE, const char*));
+void rb_define_alloc_func _((VALUE, VALUE (*)(VALUE)));
+void rb_undef_alloc_func _((VALUE));
void rb_clear_cache _((void));
void rb_alias _((VALUE, ID, ID));
void rb_attr _((VALUE,ID,int,int,int));
diff --git a/io.c b/io.c
index 6c83798..8987fd3 100644
--- a/io.c
+++ b/io.c
@@ -275,6 +275,18 @@ ruby_dup(orig)
return fd;
}
+static VALUE
+io_alloc(klass)
+ VALUE klass;
+{
+ NEWOBJ(io, struct RFile);
+ OBJSETUP(io, klass, T_FILE);
+
+ io->fptr = 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;
@@ -2780,18 +2788,6 @@ prep_path(io, 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;
VALUE *argv;
@@ -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 23840c4..e295f6e 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 0e21164..73fa329 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 7363482..6b59de3 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 b1d2bfe..5db815e 100644
--- a/parse.y
+++ b/parse.y
@@ -248,7 +248,7 @@ static void top_local_setup();
%type <node> mrhs mrhs_basic superclass block_call block_command
%type <node> f_arglist f_args f_optarg f_opt f_block_arg opt_f_block_arg
%type <node> assoc_list assocs assoc undef_list backref string_dvar
-%type <node> block_var opt_block_var brace_block do_block lhs none
+%type <node> block_var opt_block_var brace_block cmd_brace_block do_block lhs none
%type <node> mlhs mlhs_head mlhs_basic mlhs_entry mlhs_item mlhs_node
%type <id> fitem variable sym symbol operation operation2 operation3
%type <id> 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
+ {
+ $<vars>$ = dyna_push();
+ $<num>1 = ruby_sourceline;
+ }
+ opt_block_var
+ compstmt
+ '}'
+ {
+ $$ = NEW_ITER($3, 0, $4);
+ nd_set_line($$, $<num>1);
+ dyna_pop($<vars>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($$, $<num>1);
dyna_pop($<vars>2);
}
- | tLBRACE_ARG
- {
- $<vars>$ = dyna_push();
- $<num>1 = ruby_sourceline;
- }
- opt_block_var
- compstmt
- '}'
- {
- $$ = NEW_ITER($3, 0, $4);
- nd_set_line($$, $<num>1);
- dyna_pop($<vars>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 354bab2..1757e96 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 23a804a..d9de50b 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 e8ae73a..5081174 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 cb3b3d7..2d533d1 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);