From: nobu.nakada@... Date: 2001-10-03T20:27:30+09:00 Subject: [ruby-dev:14872] Re: allocation framework(Re: custom marshal) なかだです。 At Wed, 3 Oct 2001 15:43:43 +0900, matz@ruby-lang.org (Yukihiro Matsumoto) wrote: > もうちょっとイロイロやりました。と、口で説明するよりコミット > した方が早いでしょうね。  若干まずいです。 * Regexp.new(str)が無限に再帰してスタックオーバーフロー * メソッド内のProc.newがwithout blockでArgumentError  こんなかなぁ。Regexp.newはまぁ見ての通りなんですが、Procの方 はProc.allocateの中からブロックにうまくアクセスできなかったんで、 Proc#initializeとに分けてみました。あとは初期化されてないProcの ためにいくらか修正。 Index: eval.c =================================================================== RCS file: /cvs/ruby/src/ruby/eval.c,v retrieving revision 1.208 diff -u -2 -p -r1.208 eval.c --- eval.c 2001/10/03 07:19:10 1.208 +++ eval.c 2001/10/03 11:17:54 @@ -6147,4 +6147,5 @@ blk_free(data) void *tmp; + if (!data) return; frame = data->frame.prev; while (frame) { @@ -6326,8 +6327,14 @@ proc_set_safe_level(data) static VALUE -proc_new(klass) +proc_s_alloc(klass) VALUE klass; { - volatile VALUE proc; + return Data_Wrap_Struct(klass, blk_mark, blk_free, 0); +} + +static VALUE +proc_new(proc) + VALUE proc; +{ struct BLOCK *data, *p; struct RVarmap *vars; @@ -6337,5 +6344,11 @@ proc_new(klass) } - proc = Data_Make_Struct(klass, struct BLOCK, blk_mark, blk_free, data); + data = DATA_PTR(proc); + if (data) { + DATA_PTR(proc) = 0; + blk_free(data); + } + data = ALLOC(struct BLOCK); + DATA_PTR(proc) = data; *data = *ruby_block; @@ -6365,8 +6378,16 @@ proc_new(klass) } +static VALUE +proc_initialize(proc) + VALUE proc; +{ + ruby_frame = ruby_frame->prev; + return proc_new(proc); +} + VALUE rb_f_lambda() { - return proc_new(rb_cProc); + return proc_new(proc_s_alloc(rb_cProc)); } @@ -6375,4 +6396,7 @@ blk_orphan(data) struct BLOCK *data; { + if (!data) { + rb_raise(rb_eTypeError, "uninitialized Proc"); + } if (!(data->scope->flags & SCOPE_NOSTACK)) { return 0; @@ -6484,4 +6508,7 @@ proc_arity(proc) Data_Get_Struct(proc, struct BLOCK, data); + if (!data) { + rb_raise(rb_eTypeError, "uninitialized Proc"); + } if (data->var == 0) return INT2FIX(-1); if (data->var == (NODE*)1) return INT2FIX(0); @@ -6514,4 +6541,6 @@ proc_eq(self, other) Data_Get_Struct(self, struct BLOCK, data); Data_Get_Struct(other, struct BLOCK, data2); + if (data == data2) return Qtrue; + if (!data || !data2) return Qfalse; if (data->tag == data2->tag) return Qtrue; return Qfalse; @@ -6528,5 +6557,5 @@ proc_to_s(self, other) Data_Get_Struct(self, struct BLOCK, data); str = rb_str_new(0, strlen(cname)+6+16+1); /* 6:tags 16:addr 1:nul */ - sprintf(RSTRING(str)->ptr, "#<%s:0x%lx>", cname, data->tag); + sprintf(RSTRING(str)->ptr, "#<%s:0x%lx>", cname, data ? data->tag : 0); RSTRING(str)->len = strlen(RSTRING(str)->ptr); if (OBJ_TAINTED(self)) OBJ_TAINT(str); @@ -6970,5 +6999,6 @@ Init_Proc() rb_cProc = rb_define_class("Proc", rb_cObject); - rb_define_singleton_method(rb_cProc, "allocate", proc_new, 0); + rb_define_singleton_method(rb_cProc, "allocate", proc_s_alloc, 0); + rb_define_method(rb_cProc, "initialize", proc_initialize, 0); rb_define_method(rb_cProc, "call", proc_call, -2); Index: re.c =================================================================== RCS file: /src/ruby/re.c,v retrieving revision 1.48 diff -u -2 -p -u -r1.48 re.c --- re.c 2001/10/03 07:19:10 1.48 +++ re.c 2001/10/03 11:11:06 @@ -1046,11 +1046,12 @@ rb_reg_s_alloc(klass) VALUE klass; { - VALUE re = rb_obj_alloc(klass); + NEWOBJ(re, struct RRegexp); + OBJSETUP(re, klass, T_REGEXP); - RREGEXP(re)->ptr = 0; - RREGEXP(re)->len = 0; - RREGEXP(re)->str = 0; + re->ptr = 0; + re->len = 0; + re->str = 0; - return re; + return (VALUE)re; } -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦