summaryrefslogtreecommitdiff
path: root/load.c
diff options
context:
space:
mode:
authorJeremy Evans <code@jeremyevans.net>2021-10-18 08:50:10 -0700
committerJeremy Evans <code@jeremyevans.net>2021-11-17 22:43:40 -0800
commitb35b7a1ef25347735a6bb7c28ab7e77afea1d856 (patch)
tree0e9ca22419d4798df525c3d81d9d7ded1291cffb /load.c
parent05a3dc1a654c5e92200d994d0a51a2e159c88162 (diff)
downloadruby-b35b7a1ef25347735a6bb7c28ab7e77afea1d856.tar.gz
Allow Kernel#load to load code into a specified module
Instead of always using a new anonymous module for Kernel#load if the wrap argument is not false/nil, use the given module if a module is provided. Implements [Feature #6210]
Diffstat (limited to 'load.c')
-rw-r--r--load.c26
1 files changed, 15 insertions, 11 deletions
diff --git a/load.c b/load.c
index 58f71b9d22..a2b9da48fb 100644
--- a/load.c
+++ b/load.c
@@ -657,7 +657,7 @@ load_iseq_eval(rb_execution_context_t *ec, VALUE fname)
}
static inline enum ruby_tag_type
-load_wrapping(rb_execution_context_t *ec, VALUE fname)
+load_wrapping(rb_execution_context_t *ec, VALUE fname, VALUE load_wrapper)
{
enum ruby_tag_type state;
rb_thread_t *th = rb_ec_thread_ptr(ec);
@@ -669,9 +669,9 @@ load_wrapping(rb_execution_context_t *ec, VALUE fname)
ec->errinfo = Qnil; /* ensure */
- /* load in anonymous module as toplevel */
+ /* load in module as toplevel */
th->top_self = rb_obj_clone(rb_vm_top_self());
- th->top_wrapper = rb_module_new();
+ th->top_wrapper = load_wrapper;
rb_extend_object(th->top_self, th->top_wrapper);
EC_PUSH_TAG(ec);
@@ -703,12 +703,15 @@ raise_load_if_failed(rb_execution_context_t *ec, enum ruby_tag_type state)
}
static void
-rb_load_internal(VALUE fname, int wrap)
+rb_load_internal(VALUE fname, VALUE wrap)
{
rb_execution_context_t *ec = GET_EC();
enum ruby_tag_type state = TAG_NONE;
- if (wrap) {
- state = load_wrapping(ec, fname);
+ if (RTEST(wrap)) {
+ if (!RB_TYPE_P(wrap, T_MODULE)) {
+ wrap = rb_module_new();
+ }
+ state = load_wrapping(ec, fname, wrap);
}
else {
load_iseq_eval(ec, fname);
@@ -721,7 +724,7 @@ rb_load(VALUE fname, int wrap)
{
VALUE tmp = rb_find_file(FilePathValue(fname));
if (!tmp) load_failed(fname);
- rb_load_internal(tmp, wrap);
+ rb_load_internal(tmp, RBOOL(wrap));
}
void
@@ -763,9 +766,10 @@ rb_load_protect(VALUE fname, int wrap, int *pstate)
*
* If the optional _wrap_ parameter is +true+, the loaded script will
* be executed under an anonymous module, protecting the calling
- * program's global namespace. In no circumstance will any local
- * variables in the loaded file be propagated to the loading
- * environment.
+ * program's global namespace. If the optional _wrap_ parameter is a
+ * module, the loaded script will be executed under the given module.
+ * In no circumstance will any local variables in the loaded file be
+ * propagated to the loading environment.
*/
static VALUE
@@ -785,7 +789,7 @@ rb_f_load(int argc, VALUE *argv, VALUE _)
load_failed(orig_fname);
path = fname;
}
- rb_load_internal(path, RTEST(wrap));
+ rb_load_internal(path, wrap);
RUBY_DTRACE_HOOK(LOAD_RETURN, RSTRING_PTR(orig_fname));