Namespace management using control frame#13454
Conversation
9cb95e9 to
b0193f3
Compare
fd04acf to
88e1fad
Compare
This comment has been minimized.
This comment has been minimized.
139ed12 to
a5bbd18
Compare
a5bbd18 to
0ac3835
Compare
0ac3835 to
1e43ad1
Compare
35514e5 to
b47a40b
Compare
| /* Never set black_handler for VM_FRAME_MAGIC_TOP or VM_FRAME_MAGIC_CLASS | ||
| * and the specval is used for namespace (rb_namespace_t) in these case | ||
| */ | ||
| return VM_BLOCK_HANDLER_NONE; |
There was a problem hiding this comment.
For the anchor in the discussion: how to handle SPECVAL
| { | ||
| const VALUE *ep = VM_CF_LEP(cfp); | ||
| const VALUE *ep; | ||
| if (VM_ENV_NAMESPACED_P(cfp->ep)) { |
There was a problem hiding this comment.
I'm confused by the fact that VM_CF_BLOCK_HANDLER()'s implementation is different from GET_BLOCK_HANDLER()'s. GET_BLOCK_HANDLER() checks VM_ENV_NAMESPACED_P on GET_LEP() while VM_CF_BLOCK_HANDLER() checks cfp->ep instead of using VM_CF_LEP(cfp), which is the one actually queried later.
What allows them to be different? How is it safe for VM_CF_BLOCK_HANDLER() to not check the EP that has the specval to be queried?
There was a problem hiding this comment.
This if-clause is a kind of early returrn because if VM_ENV_NAMESPACED_P(ep) is true, then VM_ENV_LOCAL_P(ep) is also true and ep == VM_CF_LEP(ep) (at least for now). VM_ENV_BLOCK_HANDLER(ep) also checks VM_ENV_NAMESPACED_P(ep), so GET_BLOCK_HANDLER() returns the same result anyway.
I agree that it's confusing. So, I'll try to update GET_BLOCK_HANDLER definition to VM_CF_BLOCK_HANDLER(GET_CFP()) and check if it will work correctly.
68dd065 to
77d15c5
Compare
811a4b2 to
dfd940d
Compare
…al contexts to fix inconsistent and wrong current namespace detections. This includes: * Moving load_path and related things from rb_vm_t to rb_namespace_t to simplify accessing those values via namespace (instead of accessing either vm or ns) * Initializing root_namespace earlier and consolidate builtin_namespace into root_namespace * Adding VM_FRAME_FLAG_NS_REQUIRE for checkpoints to detect a namespace to load/require files * Removing implicit refinements in the root namespace which was used to determine the namespace to be loaded (replaced by VM_FRAME_FLAG_NS_REQUIRE) * Removing namespaces from rb_proc_t because its namespace can be identified by lexical context * Starting to use ep[VM_ENV_DATA_INDEX_SPECVAL] to store the current namespace when the frame type is MAGIC_TOP or MAGIC_CLASS (block handlers don't exist in this case)
Calling rb_current_namespace() in rb_namespace_current() means to show the definition namespace of Namespace.current itself (it's the root always) but the users' expectation is to show the namespace of the place where the Namespace.current is called.
* checking all control frames (instead of filtering by VM_FRAME_RUBYFRAME_P) because VM_FRAME_FLAG_NS_REQUIRE is set on non-rubyframe * skip frames of CFUNC in the root namespace for Kernel#require (etc) to avoid detecting the root namespace of those frames wrongly
* The current namespace should be based on the Ruby-level location (file, line no in .rb) and we can get it by LEP(ep) basically (VM_ENV_FLAG_LOCAL flag is set) * But the control frame with VM_FRAME_MAGIC_CFUNC is also a LOCAL frame because it's a visible Ruby-level frame without block handlers * So, for the namespace detection, LEP(ep) is not enough and we need to skip CFUNC frames to fetch the caller of such frames
…/pop With this change, the argument code of Namespace#eval cannot refer local variables around the calling line, but it should not be able to refer these values. The code is evaluated in the receiver namespace, independently from the local context.
* Originally, k0kubun added a change to respect namespace in gen_block_given ruby@d129669 * Just after the change, XrXr proposes a change on master and he says it can fix the problem around block_given?, and it has been merged into the master ruby#14208 * tagomoris respect the commit on master then will see if it works
* rb_vm_current_namespace() returns main_namespace if it's ready, root_namespace otherwise on the top of main_stack.
dfd940d to
97a1920
Compare
This change is to update the namespace management. The main purpose is to fix bugs in corner cases to determine the current namespaces. I expect that this fix can solve bugs/problems to run RubyGems/Bundler with namespaces.
Core changes are:
VM_CF_LEPorVM_EP_RUBY_LEP) basicallycfp->ep[VM_ENV_DATA_INDEX_SPECVAL]) to store the namespace of the frameVM_FRAME_MAGIC_TOPorVM_FRAME_MAGIC_CLASSvm->load_pathand other values, then start referring the root namespace (and itsload_pathand other fields) for simplicityVM_FRAME_FLAG_NS_REQUIRETODO:
top_selfunder namespaces (#to_sand#inspect)rb_namespace_t(especiallyloading_table_entry)namespace_entry_memsizevm_set_main_stack(ec, iseq); // TODO: not need to set the namespace?→ nothing to doAdd tests about: