diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2006-07-10 01:08:15 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2006-07-10 01:08:15 +0000 |
commit | 672549bb47cdf3ccbd6d91697941dadf7328617e (patch) | |
tree | 8edb1a59d129300539245135b80194271cf63870 | |
parent | 021336c36f9154b71bcd4a3cd9f18dcf73e1e6c9 (diff) |
* eval.c (proc_invoke): should not overwrite block information in
current frame. [ruby-dev:28957]
* eval.c (rb_yield_0): retrieve proper block object from the frame
record.
* eval.c (proc_alloc): return preserved block object if it's
available.
* st.h (st_data_t): use pointer sized integer for st_data_t.
[ruby-dev:28988]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@10497 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 26 | ||||
-rw-r--r-- | eval.c | 95 | ||||
-rw-r--r-- | hash.c | 1 | ||||
-rw-r--r-- | parse.y | 31 | ||||
-rw-r--r-- | ruby.h | 2 | ||||
-rw-r--r-- | st.h | 7 | ||||
-rw-r--r-- | time.c | 2 |
7 files changed, 124 insertions, 40 deletions
@@ -3,6 +3,22 @@ Mon Jul 10 09:29:12 2006 Nobuyoshi Nakada <[email protected]> * eval.c (rb_clear_cache_for_remove): clear entries for included module. fixed: [ruby-core:08180] +Mon Jul 10 02:22:58 2006 Yukihiro Matsumoto <[email protected]> + + * eval.c (proc_invoke): should not overwrite block information in + current frame. [ruby-dev:28957] + + * eval.c (rb_yield_0): retrieve proper block object from the frame + record. + + * eval.c (proc_alloc): return preserved block object if it's + available. + +Mon Jul 10 01:48:38 2006 Yukihiro Matsumoto <[email protected]> + + * st.h (st_data_t): use pointer sized integer for st_data_t. + [ruby-dev:28988] + Sun Jul 9 18:06:47 2006 Nobuyoshi Nakada <[email protected]> * lib/mkmf.rb (try_constant): fix for value 1 at cross compiling. @@ -46,6 +62,11 @@ Fri Jul 7 14:05:03 2006 NAKAMURA Usaku <[email protected]> * win32/Makefile.sub (config.h): define FUNC_STDCALL/FUNC_CDECL. from [ruby-dev:28970]. +Fri Jul 7 00:38:49 2006 Yukihiro Matsumoto <[email protected]> + + * hash.c (rb_hash_default): should not call default procedure if + no key is given. [ruby-list:42541] + Thu Jul 6 23:30:04 2006 Nobuyoshi Nakada <[email protected]> * process.c (rb_proc_times): use sysconf(_SC_CLK_TCK) value prior to @@ -61,6 +82,11 @@ Thu Jul 6 21:50:06 2006 Minero Aoki <[email protected]> * lib/racc/parser.rb: update coding style. +Wed Jul 5 05:28:45 2006 Yukihiro Matsumoto <[email protected]> + + * parse.y (block_param): should allow block argument after splat + and post splat args. + Wed Jul 5 01:12:19 2006 Yukihiro Matsumoto <[email protected]> * test/ruby/test_lambda.rb (TestLambdaParameters::test_lambda_as_iterator): @@ -236,11 +236,14 @@ typedef jmp_buf rb_jmpbuf_t; VALUE rb_cProc; static VALUE rb_cBinding; +static VALUE proc_alloc(VALUE,struct BLOCK*,int); static VALUE proc_invoke(VALUE,VALUE,VALUE,VALUE,int); static VALUE proc_lambda(void); static VALUE rb_f_binding(VALUE); static void rb_f_END(void); static struct BLOCK *passing_block(VALUE,struct BLOCK*); +static int block_orphan(struct BLOCK *data); + static VALUE rb_cMethod; static VALUE rb_cUnboundMethod; static VALUE umethod_bind(VALUE, VALUE); @@ -1054,6 +1057,7 @@ static NODE *compile(VALUE, const char*, int); static VALUE rb_yield_0(VALUE, VALUE, VALUE, int); #define YIELD_ARY_ARGS 1 +#define YIELD_PROC_INVOKE 2 #define YIELD_PUBLIC_DEF 4 #define YIELD_FUNC_AVALUE 1 #define YIELD_FUNC_SVALUE 2 @@ -4800,11 +4804,15 @@ rb_yield_0(VALUE val, VALUE self, VALUE klass /* OK */, int flags) assign(self, var, val, lambda); } if (bvar) { + struct BLOCK *b = ruby_frame->prev->prev->block; VALUE blk; - if (lambda) - blk = rb_block_proc(); - else - blk = block->block_obj; + + if ((flags & YIELD_PROC_INVOKE) && b) { + blk = proc_alloc(rb_cProc, b, lambda); + } + else { + blk = Qnil; + } assign(self, bvar, blk, 0); } } @@ -5941,20 +5949,21 @@ rb_call(VALUE klass, VALUE recv, ID mid, if (scope > CALLING_NORMAL) { /* pass receiver info */ noex |= NOEX_RECV; } - if (block && !iter) { + if (block && !iter && !block_orphan(block)) { VALUE result; int state; PUSH_TAG(PROT_LOOP); -// prot_tag->blkid = block->uniq; + prot_tag->blkid = block->uniq; state = EXEC_TAG(); if (state == 0) { + retry: result = rb_call0(klass, recv, mid, id, argc, argv, block, body, noex); } -// else if (state == TAG_BREAK && TAG_DST()) { -// result = prot_tag->retval; -// state = 0; -// } + else if (state == TAG_BREAK && TAG_DST()) { + result = prot_tag->retval; + state = 0; + } POP_TAG(); if (state) JUMP_TAG(state); return result; @@ -8284,7 +8293,34 @@ proc_set_safe_level(VALUE data) } static VALUE -proc_alloc(VALUE klass, int lambda) +proc_alloc(VALUE klass, struct BLOCK *blk, int lambda) +{ + volatile VALUE block; + struct BLOCK *data; + + block = Data_Make_Struct(klass, struct BLOCK, blk_mark, blk_free, data); + *data = *blk; + + if (!lambda && data->block_obj) { + return data->block_obj; + } + data->orig_thread = rb_thread_current(); + data->wrapper = ruby_wrapper; + frame_dup(&data->frame); + blk_nail_down(data); + scope_dup(data->scope); + proc_save_safe_level(block); + if (lambda) { + data->flags |= BLOCK_LAMBDA; + } + else { + data->block_obj = block; + } + return block; +} + +static VALUE +proc_new(VALUE klass, int lambda) { volatile VALUE block; struct FRAME *frame = ruby_frame; @@ -8304,23 +8340,10 @@ proc_alloc(VALUE klass, int lambda) } return obj; } - block = Data_Make_Struct(klass, struct BLOCK, blk_mark, blk_free, data); - *data = *frame->block; - - data->orig_thread = rb_thread_current(); - data->wrapper = ruby_wrapper; - data->block_obj = block; - frame_dup(&data->frame); - blk_nail_down(data); - scope_dup(data->scope); - proc_save_safe_level(block); - if (lambda) { - data->flags |= BLOCK_LAMBDA; - } - else { + block = proc_alloc(klass, frame->block, lambda); + if (!lambda) { frame->block->block_obj = block; } - return block; } @@ -8344,7 +8367,7 @@ proc_alloc(VALUE klass, int lambda) static VALUE proc_s_new(int argc, VALUE *argv, VALUE klass) { - VALUE block = proc_alloc(klass, Qfalse); + VALUE block = proc_new(klass, Qfalse); rb_obj_call_init(block, argc, argv); return block; @@ -8360,14 +8383,14 @@ proc_s_new(int argc, VALUE *argv, VALUE klass) VALUE rb_block_proc(void) { - return proc_alloc(rb_cProc, Qfalse); + return proc_new(rb_cProc, Qfalse); } VALUE rb_f_lambda(void) { rb_warn("rb_f_lambda() is deprecated; use rb_block_proc() instead"); - return proc_alloc(rb_cProc, Qtrue); + return proc_new(rb_cProc, Qtrue); } /* @@ -8381,7 +8404,7 @@ rb_f_lambda(void) static VALUE proc_lambda(void) { - return proc_alloc(rb_cProc, Qtrue); + return proc_new(rb_cProc, Qtrue); } static int @@ -8403,21 +8426,22 @@ static VALUE proc_invoke(VALUE proc, VALUE args /* OK */, VALUE self, VALUE klass, int call) { struct BLOCK _block; - struct BLOCK *data, *volatile old_block; + struct BLOCK *data; volatile VALUE result = Qundef; int state; volatile int safe = ruby_safe_level; volatile VALUE old_wrapper = ruby_wrapper; volatile int pcall, lambda; - VALUE bvar = Qnil; + VALUE bvar = 0; Data_Get_Struct(proc, struct BLOCK, data); pcall = call ? YIELD_ARY_ARGS : 0; + pcall |= YIELD_PROC_INVOKE; lambda = data->flags & BLOCK_LAMBDA; if (rb_block_given_p() && ruby_frame->callee) { if (klass != ruby_frame->this_class) klass = rb_obj_class(proc); - bvar = rb_block_proc(); +// bvar = rb_block_proc(); } PUSH_VARS(); @@ -8437,8 +8461,7 @@ proc_invoke(VALUE proc, VALUE args /* OK */, VALUE self, VALUE klass, int call) scope->local_vars = _block.scope->local_vars; _block.scope = scope; } - /* modify current frame */ - old_block = ruby_frame->block; + PUSH_FRAME(Qfalse); ruby_frame->block = &_block; PUSH_TAG(lambda ? PROT_LAMBDA : PROT_NONE); state = EXEC_TAG(); @@ -8450,7 +8473,7 @@ proc_invoke(VALUE proc, VALUE args /* OK */, VALUE self, VALUE klass, int call) result = prot_tag->retval; } POP_TAG(); - ruby_frame->block = old_block; + POP_FRAME(); ruby_wrapper = old_wrapper; POP_VARS(); if (proc_safe_level_p(proc)) @@ -474,6 +474,7 @@ rb_hash_default(int argc, VALUE *argv, VALUE hash) rb_scan_args(argc, argv, "01", &key); if (FL_TEST(hash, HASH_PROC_DEFAULT)) { + if (argc == 0) return Qnil; return rb_funcall(RHASH(hash)->ifnone, id_yield, 2, hash, key); } return RHASH(hash)->ifnone; @@ -2921,7 +2921,16 @@ block_param : block_param0 $$ = NEW_BLOCK_PARAM($9, NEW_MASGN($1, NEW_POSTARG($4,$6))); /*% $$ = blockvar_add_star(blockvar_new($1), $4); - $$ = blockvar_add_block($$, $6); + $$ = blockvar_add_block($$, $9); + %*/ + } + | block_param0 ',' tSTAR lhs ',' tAMPER lhs + { + /*%%%*/ + $$ = NEW_BLOCK_PARAM($7, NEW_MASGN($1, $4)); + /*% + $$ = blockvar_add_star(blockvar_new($1), $4); + $$ = blockvar_add_block($$, $7); %*/ } | block_param0 ',' tSTAR ',' tAMPER lhs @@ -2939,7 +2948,7 @@ block_param : block_param0 $$ = NEW_BLOCK_PARAM($8, NEW_MASGN($1, NEW_POSTARG(-1,$5))); /*% $$ = blockvar_add_star(blockvar_new($1), Qnil); - $$ = blockvar_add_block($$, $5); + $$ = blockvar_add_block($$, $8); %*/ } | block_param0 ',' tSTAR lhs @@ -3008,6 +3017,15 @@ block_param : block_param0 $$ = blockvar_add_star(blockvar_new(Qnil), $2); %*/ } + | tSTAR lhs ',' mlhs_post ',' tAMPER lhs + { + /*%%%*/ + $$ = NEW_BLOCK_PARAM($7, NEW_MASGN(0, NEW_POSTARG($2,$4))); + /*% + $$ = blockvar_add_star(blockvar_new(Qnil), Qnil); + $$ = blockvar_add_block($$, $7); + %*/ + } | tSTAR { /*%%%*/ @@ -3024,6 +3042,15 @@ block_param : block_param0 $$ = blockvar_add_star(blockvar_new(Qnil), Qnil); %*/ } + | tSTAR ',' mlhs_post ',' tAMPER lhs + { + /*%%%*/ + $$ = NEW_BLOCK_PARAM($6, NEW_MASGN(0, NEW_POSTARG(-1,$3))); + /*% + $$ = blockvar_add_star(blockvar_new(Qnil), Qnil); + $$ = blockvar_add_block($$, $6); + %*/ + } | tAMPER lhs { /*%%%*/ @@ -606,7 +606,7 @@ VALUE rb_require(const char*); #ifdef __ia64 void ruby_init_stack(VALUE*, void*); -#define RUBY_INIT_STACK \ +#define RUBY_INTT_STACK \ VALUE variable_in_this_stack_frame; \ ruby_init_stack(&variable_in_this_stack_frame, rb_ia64_bsp()); #else @@ -6,7 +6,14 @@ #define ST_INCLUDED +#if SIZEOF_LONG == SIZEOF_VOIDP typedef unsigned long st_data_t; +#elif SIZEOF_LONG_LONG == SIZEOF_VOIDP +typedef unsigned LONG_LONG st_data_t; +#else +# error ---->> st.c requires sizeof(void*) == sizeof(long) to be compiled. <<--- +- +#endif #define ST_DATA_T_DEFINED typedef struct st_table st_table; @@ -1924,7 +1924,7 @@ time_mdump(VALUE time) if ((tm->tm_year & 0xffff) != tm->tm_year) rb_raise(rb_eArgError, "year too big to marshal"); - p = 0x1UL << 31 | /* 1 */ + p = 0x1UL << 31 | /* 1 */ tobj->gmt << 30 | /* 1 */ tm->tm_year << 14 | /* 16 */ tm->tm_mon << 10 | /* 4 */ |