mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* proc.c (rb_binding_new_with_cfp): permit to create binding object
of IFUNC frame. When `rb_binding_new_with_cfp()' is called, VM finds out the first normal (has iseq) frame and create a binding object of this frame and create Env objects. `ep's of related frames are updated (`ep's point Env object managed spaces). However, `ep' of skipped IFUNC frame was not updated and old invalid `ep' was remained. It causes serious problems. To solve this issue, permit IFUNC to create binding. (Maybe there is no problem on it) [ruby-dev:46908] [ruby-trunk - Bug #7774] * test/ruby/test_settracefunc.rb: add a test. * vm.c (rb_vm_get_binding_creatable_next_cfp), vm_core.h: added. * vm_trace.c: fix to use `rb_vm_get_binding_creatable_next_cfp()'. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@39067 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
757bbe8737
commit
88101695ab
6 changed files with 59 additions and 5 deletions
20
ChangeLog
20
ChangeLog
|
@ -1,3 +1,23 @@
|
||||||
|
Tue Feb 05 15:04:34 2013 Koichi Sasada <ko1@atdot.net>
|
||||||
|
|
||||||
|
* proc.c (rb_binding_new_with_cfp): permit to create binding object
|
||||||
|
of IFUNC frame.
|
||||||
|
When `rb_binding_new_with_cfp()' is called, VM finds out the first
|
||||||
|
normal (has iseq) frame and create a binding object of this frame
|
||||||
|
and create Env objects. `ep's of related frames are updated
|
||||||
|
(`ep's point Env object managed spaces).
|
||||||
|
However, `ep' of skipped IFUNC frame was not updated and
|
||||||
|
old invalid `ep' was remained. It causes serious problems.
|
||||||
|
To solve this issue, permit IFUNC to create binding.
|
||||||
|
(Maybe there is no problem on it)
|
||||||
|
[ruby-dev:46908] [ruby-trunk - Bug #7774]
|
||||||
|
|
||||||
|
* test/ruby/test_settracefunc.rb: add a test.
|
||||||
|
|
||||||
|
* vm.c (rb_vm_get_binding_creatable_next_cfp), vm_core.h: added.
|
||||||
|
|
||||||
|
* vm_trace.c: fix to use `rb_vm_get_binding_creatable_next_cfp()'.
|
||||||
|
|
||||||
Tue Feb 5 14:43:15 2013 Marc-Andre Lafortune <ruby-core@marc-andre.ca>
|
Tue Feb 5 14:43:15 2013 Marc-Andre Lafortune <ruby-core@marc-andre.ca>
|
||||||
|
|
||||||
* lib/matrix.rb: Fix error message, patch by pypypy [Bug #7777]
|
* lib/matrix.rb: Fix error message, patch by pypypy [Bug #7777]
|
||||||
|
|
10
proc.c
10
proc.c
|
@ -313,19 +313,21 @@ binding_clone(VALUE self)
|
||||||
VALUE
|
VALUE
|
||||||
rb_binding_new_with_cfp(rb_thread_t *th, const rb_control_frame_t *src_cfp)
|
rb_binding_new_with_cfp(rb_thread_t *th, const rb_control_frame_t *src_cfp)
|
||||||
{
|
{
|
||||||
rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, src_cfp);
|
rb_control_frame_t *cfp = rb_vm_get_binding_creatable_next_cfp(th, src_cfp);
|
||||||
|
rb_control_frame_t *ruby_level_cfp = rb_vm_get_ruby_level_next_cfp(th, src_cfp);
|
||||||
VALUE bindval;
|
VALUE bindval;
|
||||||
rb_binding_t *bind;
|
rb_binding_t *bind;
|
||||||
|
|
||||||
if (cfp == 0) {
|
if (cfp == 0 || ruby_level_cfp == 0) {
|
||||||
rb_raise(rb_eRuntimeError, "Can't create Binding Object on top of Fiber.");
|
rb_raise(rb_eRuntimeError, "Can't create Binding Object on top of Fiber.");
|
||||||
}
|
}
|
||||||
|
|
||||||
bindval = binding_alloc(rb_cBinding);
|
bindval = binding_alloc(rb_cBinding);
|
||||||
GetBindingPtr(bindval, bind);
|
GetBindingPtr(bindval, bind);
|
||||||
bind->env = rb_vm_make_env_object(th, cfp);
|
bind->env = rb_vm_make_env_object(th, cfp);
|
||||||
bind->path = cfp->iseq->location.path;
|
bind->path = ruby_level_cfp->iseq->location.path;
|
||||||
bind->first_lineno = rb_vm_get_sourceline(cfp);
|
bind->first_lineno = rb_vm_get_sourceline(ruby_level_cfp);
|
||||||
|
|
||||||
return bindval;
|
return bindval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -941,4 +941,22 @@ class TestSetTraceFunc < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
assert_security_error_safe4(func)
|
assert_security_error_safe4(func)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_trace_point_binding_in_ifunc
|
||||||
|
assert_normal_exit %q{
|
||||||
|
tp = TracePoint.new(:raise) do |tp|
|
||||||
|
tp.binding
|
||||||
|
end
|
||||||
|
tp.enable do
|
||||||
|
obj = Object.new
|
||||||
|
class << obj
|
||||||
|
include Enumerable
|
||||||
|
def each
|
||||||
|
yield 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
obj.zip({}) {}
|
||||||
|
end
|
||||||
|
}, '[ruby-dev:46908] [ruby-trunk - Bug #7774]'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
12
vm.c
12
vm.c
|
@ -185,6 +185,18 @@ vm_set_main_stack(rb_thread_t *th, VALUE iseqval)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rb_control_frame_t *
|
||||||
|
rb_vm_get_binding_creatable_next_cfp(rb_thread_t *th, const rb_control_frame_t *cfp)
|
||||||
|
{
|
||||||
|
while (!RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, cfp)) {
|
||||||
|
if (cfp->iseq) {
|
||||||
|
return (rb_control_frame_t *)cfp;
|
||||||
|
}
|
||||||
|
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
rb_control_frame_t *
|
rb_control_frame_t *
|
||||||
rb_vm_get_ruby_level_next_cfp(rb_thread_t *th, const rb_control_frame_t *cfp)
|
rb_vm_get_ruby_level_next_cfp(rb_thread_t *th, const rb_control_frame_t *cfp)
|
||||||
{
|
{
|
||||||
|
|
|
@ -843,6 +843,7 @@ void rb_thread_wakeup_timer_thread(void);
|
||||||
int ruby_thread_has_gvl_p(void);
|
int ruby_thread_has_gvl_p(void);
|
||||||
typedef int rb_backtrace_iter_func(void *, VALUE, int, VALUE);
|
typedef int rb_backtrace_iter_func(void *, VALUE, int, VALUE);
|
||||||
rb_control_frame_t *rb_vm_get_ruby_level_next_cfp(rb_thread_t *th, const rb_control_frame_t *cfp);
|
rb_control_frame_t *rb_vm_get_ruby_level_next_cfp(rb_thread_t *th, const rb_control_frame_t *cfp);
|
||||||
|
rb_control_frame_t *rb_vm_get_binding_creatable_next_cfp(rb_thread_t *th, const rb_control_frame_t *cfp);
|
||||||
int rb_vm_get_sourceline(const rb_control_frame_t *);
|
int rb_vm_get_sourceline(const rb_control_frame_t *);
|
||||||
VALUE rb_name_err_mesg_new(VALUE obj, VALUE mesg, VALUE recv, VALUE method);
|
VALUE rb_name_err_mesg_new(VALUE obj, VALUE mesg, VALUE recv, VALUE method);
|
||||||
void rb_vm_stack_to_heap(rb_thread_t *th);
|
void rb_vm_stack_to_heap(rb_thread_t *th);
|
||||||
|
|
|
@ -763,7 +763,8 @@ VALUE
|
||||||
rb_tracearg_binding(rb_trace_arg_t *trace_arg)
|
rb_tracearg_binding(rb_trace_arg_t *trace_arg)
|
||||||
{
|
{
|
||||||
rb_control_frame_t *cfp;
|
rb_control_frame_t *cfp;
|
||||||
cfp = rb_vm_get_ruby_level_next_cfp(trace_arg->th, trace_arg->cfp);
|
cfp = rb_vm_get_binding_creatable_next_cfp(trace_arg->th, trace_arg->cfp);
|
||||||
|
|
||||||
if (cfp) {
|
if (cfp) {
|
||||||
return rb_binding_new_with_cfp(trace_arg->th, cfp);
|
return rb_binding_new_with_cfp(trace_arg->th, cfp);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue