aboutsummaryrefslogtreecommitdiffstats
path: root/vm_core.h
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-07-17 07:28:22 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-07-17 07:28:22 +0000
commit01962439e9450b3d9468030b6e2858767c8c43c0 (patch)
tree90e8fb659043dfc25d811f568ea819973eac1828 /vm_core.h
parent137d08de4b0bb809e13158911587e08605fe576e (diff)
downloadruby-01962439e9450b3d9468030b6e2858767c8c43c0.tar.gz
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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51279 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'vm_core.h')
-rw-r--r--vm_core.h39
1 files changed, 24 insertions, 15 deletions
diff --git a/vm_core.h b/vm_core.h
index f98ba80876..5686ec7e08 100644
--- a/vm_core.h
+++ b/vm_core.h
@@ -1128,24 +1128,33 @@ void rb_threadptr_exec_event_hooks(struct rb_trace_arg_struct *trace_arg);
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)