summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--namespace.c2
-rw-r--r--vm.c59
2 files changed, 34 insertions, 27 deletions
diff --git a/namespace.c b/namespace.c
index e30d426d68..82bacd4108 100644
--- a/namespace.c
+++ b/namespace.c
@@ -460,7 +460,7 @@ rb_namespace_s_current(VALUE recv)
if (!rb_namespace_available())
return Qnil;
- ns = rb_vm_caller_namespace(GET_EC());
+ ns = rb_vm_current_namespace(GET_EC());
VM_ASSERT(ns && ns->ns_object);
return ns->ns_object;
}
diff --git a/vm.c b/vm.c
index 790a5af4f0..1a328fb63c 100644
--- a/vm.c
+++ b/vm.c
@@ -95,6 +95,29 @@ rb_vm_search_cf_from_ep(const rb_execution_context_t *ec, const rb_control_frame
}
}
+static const VALUE *
+VM_EP_RUBY_LEP(const rb_execution_context_t *ec, const rb_control_frame_t *current_cfp)
+{
+ const VALUE *ep = current_cfp->ep;
+ const rb_control_frame_t *cfp, *checkpoint_cfp = current_cfp;
+
+ while (!VM_ENV_LOCAL_P(ep) || VM_ENV_FRAME_TYPE_P(ep, VM_FRAME_MAGIC_CFUNC)) {
+ while (!VM_ENV_LOCAL_P(ep)) {
+ ep = VM_ENV_PREV_EP(ep);
+ }
+ while (VM_ENV_FRAME_TYPE_P(ep, VM_FRAME_MAGIC_CFUNC)) {
+ if (!cfp) {
+ cfp = rb_vm_search_cf_from_ep(ec, checkpoint_cfp, ep);
+ }
+ cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
+ ep = cfp->ep;
+ }
+ checkpoint_cfp = cfp;
+ cfp = NULL;
+ }
+ return ep;
+}
+
const VALUE *
rb_vm_ep_local_ep(const VALUE *ep)
{
@@ -1001,11 +1024,8 @@ vm_make_env_each(const rb_execution_context_t * const ec, rb_control_frame_t *co
VM_FORCE_WRITE_SPECIAL_CONST(&ep[VM_ENV_DATA_INDEX_SPECVAL], VM_GUARDED_PREV_EP(prev_cfp->ep));
}
}
- else if (VM_ENV_FRAME_TYPE_P(ep, VM_FRAME_MAGIC_TOP)) {
- // block_handler is always VM_BLOCK_HANDLER_NONE in this case
- }
else {
- VM_ASSERT(VM_ENV_LOCAL_P(ep) && !VM_ENV_FRAME_TYPE_P(ep, VM_FRAME_MAGIC_TOP));
+ VM_ASSERT(VM_ENV_LOCAL_P(ep));
VALUE block_handler = VM_ENV_BLOCK_HANDLER(ep);
if (block_handler != VM_BLOCK_HANDLER_NONE) {
@@ -3017,15 +3037,15 @@ rb_vm_frame_flag_set_ns_require(const rb_execution_context_t *ec)
}
static const rb_namespace_t *
-current_namespace_on_env(const VALUE *ep)
+current_namespace_on_cfp(const rb_execution_context_t *ec, const rb_control_frame_t *cfp)
{
rb_callable_method_entry_t *cme;
const rb_namespace_t *ns;
- const VALUE *lep = VM_EP_LEP(ep);
+ const VALUE *lep = VM_EP_RUBY_LEP(ec, cfp);
VM_ASSERT(lep);
VM_ASSERT(rb_namespace_available());
- if (VM_ENV_FRAME_TYPE_P(lep, VM_FRAME_MAGIC_METHOD) || VM_ENV_FRAME_TYPE_P(lep, VM_FRAME_MAGIC_CFUNC)) {
+ if (VM_ENV_FRAME_TYPE_P(lep, VM_FRAME_MAGIC_METHOD)) {
cme = check_method_entry(lep[VM_ENV_DATA_INDEX_ME_CREF], TRUE);
VM_ASSERT(cme);
VM_ASSERT(cme->def);
@@ -3053,29 +3073,16 @@ const rb_namespace_t *
rb_vm_current_namespace(const rb_execution_context_t *ec)
{
VM_ASSERT(rb_namespace_available());
- return current_namespace_on_env(ec->cfp->ep);
-}
-
-const rb_namespace_t *
-rb_vm_caller_namespace(const rb_execution_context_t *ec)
-{
- const rb_control_frame_t *caller_cfp;
-
- VM_ASSERT(rb_namespace_available());
-
- // The current control frame is MAGIC_CFUNC to call Namespace.current, but
- // we want to get the current namespace of its caller.
- caller_cfp = vm_get_ruby_level_caller_cfp(ec, ec->cfp);
- return current_namespace_on_env(caller_cfp->ep);
+ return current_namespace_on_cfp(ec, ec->cfp);
}
static const rb_control_frame_t *
-find_loader_control_frame(const rb_control_frame_t *cfp, const rb_control_frame_t *end_cfp)
+find_loader_control_frame(const rb_execution_context_t *ec, const rb_control_frame_t *cfp, const rb_control_frame_t *end_cfp)
{
while (RUBY_VM_VALID_CONTROL_FRAME_P(cfp, end_cfp)) {
if (!VM_ENV_FRAME_TYPE_P(cfp->ep, VM_FRAME_MAGIC_CFUNC))
break;
- if (!NAMESPACE_ROOT_P(current_namespace_on_env(cfp->ep)))
+ if (!NAMESPACE_ROOT_P(current_namespace_on_cfp(ec, cfp)))
break;
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
}
@@ -3102,13 +3109,13 @@ rb_vm_loading_namespace(const rb_execution_context_t *ec)
return rb_get_namespace_t(cfp->self);
}
// Kernel#require, #require_relative, #load
- cfp = find_loader_control_frame(cfp, end_cfp);
- return current_namespace_on_env(cfp->ep);
+ cfp = find_loader_control_frame(ec, cfp, end_cfp);
+ return current_namespace_on_cfp(ec, cfp);
}
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
}
// no require/load with explicit namespaces.
- return current_namespace_on_env(current_cfp->ep);
+ return current_namespace_on_cfp(ec, current_cfp);
}
/* vm */