ruby-changes:39198
From: nobu <ko1@a...>
Date: Fri, 17 Jul 2015 16:28:39 +0900 (JST)
Subject: [ruby-changes:39198] nobu:r51279 (trunk): EXEC_EVENT_HOOK_ORIG: eval the arguments only once
nobu 2015-07-17 16:28:22 +0900 (Fri, 17 Jul 2015) New Revision: 51279 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=51279 Log: EXEC_EVENT_HOOK_ORIG: eval the arguments only once * vm_core.h (EXEC_EVENT_HOOK_ORIG): evaluate each arguments only once to get rid of inadvertent side effects. fix use of `th` variable in the second `if` statement. Modified files: trunk/vm_core.h Index: vm_core.h =================================================================== --- vm_core.h (revision 51278) +++ vm_core.h (revision 51279) @@ -1128,24 +1128,33 @@ void rb_threadptr_exec_event_hooks(struc https://github.com/ruby/ruby/blob/trunk/vm_core.h#L1128 void rb_threadptr_exec_event_hooks_and_pop_frame(struct rb_trace_arg_struct *trace_arg); #define EXEC_EVENT_HOOK_ORIG(th_, flag_, self_, id_, klass_, data_, pop_p_) do { \ - if (UNLIKELY(ruby_vm_event_flags & (flag_))) { \ - if (((th)->event_hooks.events | (th)->vm->event_hooks.events) & (flag_)) { \ - struct rb_trace_arg_struct trace_arg; \ - trace_arg.event = (flag_); \ - trace_arg.th = (th_); \ - trace_arg.cfp = (trace_arg.th)->cfp; \ - trace_arg.self = (self_); \ - trace_arg.id = (id_); \ - trace_arg.klass = (klass_); \ - trace_arg.data = (data_); \ - trace_arg.path = Qundef; \ - trace_arg.klass_solved = 0; \ - if (pop_p_) rb_threadptr_exec_event_hooks_and_pop_frame(&trace_arg); \ - else rb_threadptr_exec_event_hooks(&trace_arg); \ - } \ + const rb_event_flag_t flag_arg_ = (flag_); \ + if (UNLIKELY(ruby_vm_event_flags & (flag_arg_))) { \ + /* defer evaluating the other arguments */ \ + ruby_exec_event_hook_orig(th_, flag_arg_, self_, id_, klass_, data_, pop_p_); \ } \ } while (0) +static inline void +ruby_exec_event_hook_orig(rb_thread_t *const th, const rb_event_flag_t flag, + VALUE self, ID id, VALUE klass, VALUE data, int pop_p) +{ + if ((th->event_hooks.events | th->vm->event_hooks.events) & flag) { + struct rb_trace_arg_struct trace_arg; + trace_arg.event = flag; + trace_arg.th = th; + trace_arg.cfp = th->cfp; + trace_arg.self = self; + trace_arg.id = id; + trace_arg.klass = klass; + trace_arg.data = data; + trace_arg.path = Qundef; + trace_arg.klass_solved = 0; + if (pop_p) rb_threadptr_exec_event_hooks_and_pop_frame(&trace_arg); + else rb_threadptr_exec_event_hooks(&trace_arg); + } +} + #define EXEC_EVENT_HOOK(th_, flag_, self_, id_, klass_, data_) \ EXEC_EVENT_HOOK_ORIG(th_, flag_, self_, id_, klass_, data_, 0) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/