mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* 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
This commit is contained in:
parent
021336c36f
commit
672549bb47
7 changed files with 124 additions and 40 deletions
26
ChangeLog
26
ChangeLog
|
@ -3,6 +3,22 @@ Mon Jul 10 09:29:12 2006 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
|||
* 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 <matz@ruby-lang.org>
|
||||
|
||||
* 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 <matz@ruby-lang.org>
|
||||
|
||||
* 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 <nobu@ruby-lang.org>
|
||||
|
||||
* 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 <usa@ruby-lang.org>
|
|||
* win32/Makefile.sub (config.h): define FUNC_STDCALL/FUNC_CDECL.
|
||||
from [ruby-dev:28970].
|
||||
|
||||
Fri Jul 7 00:38:49 2006 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* 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 <nobu@ruby-lang.org>
|
||||
|
||||
* 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 <aamine@loveruby.net>
|
|||
|
||||
* lib/racc/parser.rb: update coding style.
|
||||
|
||||
Wed Jul 5 05:28:45 2006 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* parse.y (block_param): should allow block argument after splat
|
||||
and post splat args.
|
||||
|
||||
Wed Jul 5 01:12:19 2006 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* test/ruby/test_lambda.rb (TestLambdaParameters::test_lambda_as_iterator):
|
||||
|
|
95
eval.c
95
eval.c
|
@ -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))
|
||||
|
|
1
hash.c
1
hash.c
|
@ -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;
|
||||
|
|
31
parse.y
31
parse.y
|
@ -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
|
||||
{
|
||||
/*%%%*/
|
||||
|
|
2
ruby.h
2
ruby.h
|
@ -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
|
||||
|
|
7
st.h
7
st.h
|
@ -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;
|
||||
|
|
2
time.c
2
time.c
|
@ -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 */
|
||||
|
|
Loading…
Add table
Reference in a new issue