8000 merge revision(s) r48000: [Backport #10368] · github/ruby@06ce3b7 · GitHub
[go: up one dir, main page]

Skip to content

Commit 06ce3b7

Browse files
committed
merge revision(s) r48000: [Backport ruby#10368]
* vm_core.h, vm.c, proc.c: fix GC mark miss on bindings. [ruby-dev:48616] [Bug ruby#10368] * test/ruby/test_eval.rb: add a test code. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_1@48004 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
1 parent 3ec2fe7 commit 06ce3b7

File tree

6 files changed

+70
-30
lines changed

6 files changed

+70
-30
lines changed

ChangeLog

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
Sun Oct 19 03:22:53 2014 Kazuki Tsujimoto <kazuki@callcc.net>
2+
3+
* vm_core.h, vm.c, proc.c: fix GC mark miss on bindings.
4+
[ruby-dev:48616] [Bug #10368]
5+
6+
* test/ruby/test_eval.rb: add a test code.
7+
18
Sun Oct 19 03:13:38 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
29

310
* parse.y (parser_here_document): do not append already appended

proc.c

Lines changed: 8 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,7 @@ binding_mark(void *ptr)
262262
bind = ptr;
263263
RUBY_MARK_UNLESS_NULL(bind->env);
264264
RUBY_MARK_UNLESS_NULL(bind->path);
265+
RUBY_MARK_UNLESS_NULL(bind->blockprocval);
265266
}
266267
RUBY_MARK_LEAVE("binding");
267268
}
@@ -282,8 +283,8 @@ const rb_data_type_t ruby_binding_data_type = {
282283
NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
283284
};
284285

285-
static VALUE
286-
binding_alloc(VALUE klass)
286+
VALUE
287+
rb_binding_alloc(VALUE klass)
287288
{
288289
VALUE obj;
289290
rb_binding_t *bind;
@@ -295,12 +296,13 @@ binding_alloc(VALUE klass)
295296
static VALUE
296297
binding_dup(VALUE self)
297298
{
298-
VALUE bindval = binding_alloc(rb_cBinding);
299+
VALUE bindval = rb_binding_alloc(rb_cBinding);
299300
rb_binding_t *src, *dst;
300301
GetBindingPtr(self, src);
301302
GetBindingPtr(bindval, dst);
302303
dst->env = src->env;
303304
dst->path = src->path;
305+
dst->blockprocval = src->blockprocval;
304306
dst->first_lineno = src->first_lineno;
305307
return bindval;
306308
}
@@ -317,30 +319,7 @@ binding_clone(VALUE self)
317319
VALUE
318320
rb_binding_new_with_cfp(rb_thread_t *th, const rb_control_frame_t *src_cfp)
319321
{
320-
rb_control_frame_t *cfp = rb_vm_get_binding_creatable_next_cfp(th, src_cfp);
321-
rb_control_frame_t *ruby_level_cfp = rb_vm_get_ruby_level_next_cfp(th, src_cfp);
322-
VALUE bindval, envval;
323-
rb_binding_t *bind;
324-
325-
if (cfp == 0 || ruby_level_cfp == 0) {
326-
rb_raise(rb_eRuntimeError, "Can't create Binding Object on top of Fiber.");
327-
}
328-
329-
while (1) {
330-
envval = rb_vm_make_env_object(th, cfp);
331-
if (cfp == ruby_level_cfp) {
332-
break;
333-
}
334-
cfp = rb_vm_get_binding_creatable_next_cfp(th, RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp));
335-
}
336-
337-
bindval = binding_alloc(rb_cBinding);
338-
GetBindingPtr(bindval, bind);
339-
bind->env = envval;
340-
bind->path = ruby_level_cfp->iseq->location.path;
341-
bind->first_lineno = rb_vm_get_sourceline(ruby_level_cfp);
342-
343-
return bindval;
322+
return rb_vm_make_binding(th, src_cfp);
344323
}
345324

346325
VALUE
@@ -2409,9 +2388,10 @@ proc_binding(VALUE self)
24092388
}
24102389
}
24112390

2412-
bindval = binding_alloc(rb_cBinding);
2391+
bindval = rb_binding_alloc(rb_cBinding);
24132392
GetBindingPtr(bindval, bind);
24142393
bind->env = proc->envval;
2394+
bind->blockprocval = proc->blockprocval;
24152395
if (RUBY_VM_NORMAL_ISEQ_P(proc->block.iseq)) {
24162396
bind->path = proc->block.iseq->location.path;
24172397
bind->first_lineno = FIX2INT(rb_iseq_first_lineno(proc->block.iseq->self));

test/ruby/test_eval.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,4 +484,19 @@ def test_eval_location_fstring
484484

485485
assert_same a, b
486486
end
487+
488+
def test_gced_binding_block
489+
assert_normal_exit %q{
490+
def m
491+
binding
492+
end
493+
GC.stress = true
494+
b = nil
495+
tap do
496+
b = m {}
497+
end
498+
0.times.to_a
499+
b.eval('yield')
500+
}, '[Bug #10368]'
501+
end
487502
end

version.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#define RUBY_VERSION "2.1.4"
22
#define RUBY_RELEASE_DATE "2014-10-19"
3-
#define RUBY_PATCHLEVEL 260
3+
#define RUBY_PATCHLEVEL 261
44

55
#define RUBY_RELEASE_YEAR 2014
66
#define RUBY_RELEASE_MONTH 10

vm.c

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -688,6 +688,39 @@ rb_vm_make_proc(rb_thread_t *th, const rb_block_t *block, VALUE klass)
688688
return procval;
689689
}
690690

691+
/* Binding */
692+
693+
VALUE
694+
rb_vm_make_binding(rb_thread_t *th, const rb_control_frame_t *src_cfp)
695+
{
696+
rb_control_frame_t *cfp = rb_vm_get_binding_creatable_next_cfp(th, src_cfp);
697+
rb_control_frame_t *ruby_level_cfp = rb_vm_get_ruby_level_next_cfp(th, src_cfp);
698+
VALUE bindval, envval;
699+
rb_binding_t *bind;
700+
VALUE blockprocval = 0;
701+
702+
if (cfp == 0 || ruby_level_cfp == 0) {
703+
rb_raise(rb_eRuntimeError, "Can't create Binding Object on top of Fiber.");
704+
}
705+
706+
while (1) {
707+
envval = vm_make_env_object(th, cfp, &blockprocval);
708+
if (cfp == ruby_level_cfp) {
709+
break;
710+
}
711+
cfp = rb_vm_get_binding_creatable_next_cfp(th, RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp));
712+
}
713+
714+
bindval = rb_binding_alloc(rb_cBinding);
715+
GetBindingPtr(bindval, bind);
716+
bind->env = envval;
717+
bind->path = ruby_level_cfp->iseq->location.path;
718+
bind->blockprocval = blockprocval;
719+
bind->first_lineno = rb_vm_get_sourceline(ruby_level_cfp);
720+
721+
return bindval;
722+
}
723+
691724
VALUE *
692725
rb_binding_add_dynavars(rb_binding_t *bind, int dyncount, const ID *dynvars)
693726
{
@@ -699,6 +732,7 @@ rb_binding_add_dynavars(rb_binding_t *bind, int dyncount, const ID *dynvars)
699732
NODE *node = 0;
700733
ID minibuf[4], *dyns = minibuf;
701734
VALUE idtmp = 0;
735+
VALUE blockprocval = 0;
702736

703737
if (dyncount < 0) return 0;
704738

@@ -719,7 +753,8 @@ rb_binding_add_dynavars(rb_binding_t *bind, int dyncount, const ID *dynvars)
719753
ALLOCV_END(idtmp);
720754

721755
vm_set_eval_stack(th, iseqval, 0, base_block);
722-
bind->env = rb_vm_make_env_object(th, th->cfp);
756+
bind->env = vm_make_env_object(th, th->cfp, &blockprocval);
757+
bind->blockprocval = blockprocval;
723758
vm_pop_frame(th);
724759
GetEnvPtr(bind->env, env);
725760

vm_core.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -726,6 +726,7 @@ extern const rb_data_type_t ruby_binding_data_type;
726726
typedef struct {
727727
VALUE env;
728728
VALUE path;
729+
VALUE blockprocval; /* for GC mark */
729730
unsigned short first_lineno;
730731
} rb_binding_t;
731732

@@ -842,6 +843,7 @@ rb_block_t *rb_vm_control_frame_block_ptr(rb_control_frame_t *cfp);
842843
/* VM related object allocate functions */
843844
VALUE rb_thread_alloc(VALUE klass);
844845
VALUE rb_proc_alloc(VALUE klass);
846+
VALUE rb_binding_alloc(VALUE klass);
845847

846848
/* for debug */
847849
extern void rb_vmdebug_stack_dump_raw(rb_thread_t *, rb_control_frame_t *);
@@ -862,6 +864,7 @@ int rb_thread_method_id_and_class(rb_thread_t *th, ID *idp, VALUE *klassp);
862864
VALUE rb_vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc,
863865
int argc, const VALUE *argv, const rb_block_t *blockptr);
864866
VALUE rb_vm_make_proc(rb_thread_t *th, const rb_block_t *block, VALUE klass);
867+
VALUE rb_vm_make_binding(rb_thread_t *th, const rb_control_frame_t *src_cfp);
865868
VALUE rb_vm_make_env_object(rb_thread_t *th, rb_control_frame_t *cfp);
866869
VALUE rb_binding_new_with_cfp(rb_thread_t *th, const rb_control_frame_t *src_cfp);
867870
VALUE *rb_binding_add_dynavars(rb_binding_t *bind, int dyncount, const ID *dynvars);

0 commit comments

Comments
 (0)
0