From: ts Date: 2004-12-03T20:41:04+09:00 Subject: Re: [1.9, 1.8] super >>>>> "Y" == Yukihiro Matsumoto writes: Y> Interesting! I have never thought of that. Let me work on it (or you Y> can, if you want ;-). I'm not really sure because it's easier to write for 1.8 :-( uln% diff -pu eval.c.old eval.c --- eval.c.old 2004-12-03 12:24:05.000000000 +0100 +++ eval.c 2004-12-03 12:32:43.000000000 +0100 @@ -3237,11 +3237,19 @@ rb_eval(self, n) } } if (nd_type(node) == NODE_ZSUPER) { - if (ruby_frame->prev && (ruby_frame->prev->flags & FRAME_DMETH)) { - rb_raise(rb_eRuntimeError, "super: specify arguments explicitly"); - } argc = ruby_frame->argc; - argv = ruby_scope->local_vars + 2; + if (argc && ruby_frame->prev && + (ruby_frame->prev->flags & FRAME_DMETH)) { + if (TYPE(RBASIC(ruby_scope)->klass) != T_ARRAY || + RARRAY(RBASIC(ruby_scope)->klass)->len != argc) { + rb_raise(rb_eRuntimeError, + "super: specify arguments explicitly"); + } + argv = RARRAY(RBASIC(ruby_scope)->klass)->ptr; + } + else { + argv = ruby_scope->local_vars + 2; + } } else { BEGIN_CALLARGS; @@ -8188,7 +8196,7 @@ proc_invoke(proc, args, self, klass) volatile int safe = ruby_safe_level; volatile VALUE old_wrapper = ruby_wrapper; volatile int pcall, avalue = Qtrue; - VALUE bvar = Qnil; + VALUE bvar = Qnil, tmp = args; Data_Get_Struct(proc, struct BLOCK, data); pcall = (data->flags & BLOCK_LAMBDA) ? YIELD_LAMBDA_CALL : 0; @@ -8213,6 +8221,14 @@ proc_invoke(proc, args, self, klass) _block.block_obj = bvar; if (self != Qundef) _block.frame.self = self; if (klass) _block.frame.last_class = klass; + _block.frame.argc = RARRAY(tmp)->len; + if (_block.frame.argc) { + NEWOBJ(scope, struct SCOPE); + OBJSETUP(scope, tmp, T_SCOPE); + scope->local_tbl = _block.scope->local_tbl; + scope->local_vars = _block.scope->local_vars; + _block.scope = scope; + } ruby_block = &_block; PUSH_ITER(ITER_CUR); @@ -8229,6 +8245,9 @@ proc_invoke(proc, args, self, klass) } POP_TAG(); POP_ITER(); + if (_block.frame.argc) { + rb_gc_force_recycle((VALUE)ruby_block->scope); + } ruby_block = old_block; ruby_wrapper = old_wrapper; POP_VARS(); uln% Guy Decoux