Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
43392af
ripper: Fix dependency for generated ripper sources
nobu Sep 23, 2025
4f47327
Update current namespace management by using control frames and lexic…
tagomoris Jun 15, 2025
76c4663
Fix Namespace.current to show its caller's namespace
tagomoris Jun 22, 2025
545cee0
There is no longer needs to evict ivars thanks to fields
tagomoris Jun 22, 2025
2100826
Fix wrong way to check an object is an instance of rb_cNamespace
tagomoris Jun 22, 2025
c755f35
Stop using ns->top_self here because it's set to th->top_self beforeh…
tagomoris Jun 24, 2025
48523da
Follow the usual naming rule for singleton methods
tagomoris Jun 29, 2025
bb21b61
Detect the correct loading namespace from control frames
tagomoris Jun 29, 2025
a5df24f
Define a debug method Kernel#dump_classext only when RUBY_DEBUG is set
tagomoris Jul 27, 2025
20c73b1
Skip CFUNC frames in the current namespace detection
tagomoris Jul 27, 2025
32f5862
Update Namespace#eval to use control frames instead of namespace_push…
tagomoris Aug 10, 2025
53a1ff7
Add and fix dependencies
tagomoris Aug 11, 2025
f3f7032
Skip loading gem_prelude in wasm environment
tagomoris Aug 11, 2025
228d2c3
Stop using C23 spec: initialization with an empty struct
tagomoris Aug 11, 2025
bff625d
add VM_ENV_NAMESPACED_P to unify/simplify/correct when SPECVAL has a …
tagomoris Aug 12, 2025
2622d79
fix the wrong patch: 6cea12a4de44e0c072e33eca51b57965068b474a
tagomoris Aug 12, 2025
140bf4d
localize rb_vm_t and minimize times of GET_VM() calls
tagomoris Aug 12, 2025
f9ea85d
delete unused code
tagomoris Aug 12, 2025
5803088
YJIT: respect the code in master branch
k0kubun Aug 12, 2025
81f3591
Unify all block_handler getter to check namespace consistently
tagomoris Sep 20, 2025
f58f7f2
Fix bug of uninitialized variable, missed EoCFP, return values
tagomoris Sep 20, 2025
4644d14
Fix the missed vm_ns during rebase to follow the change b227a942b205c…
tagomoris Sep 20, 2025
9361af6
Update dependency after rebase
tagomoris Sep 20, 2025
88b5287
re-implement free/memsize for rb_namespace_t correctly
tagomoris Sep 20, 2025
ccbf066
No need to set namespace to the frame start evaluating main
tagomoris Sep 20, 2025
88d7ef4
calling free() here causes free for un-malloced memory
tagomoris Sep 28, 2025
6e9a341
zeroing on the table to suppress unintentional call of classext_foreach
tagomoris Sep 28, 2025
9d9390a
Add methods for debugging only when RUBY_DEBUG
tagomoris Sep 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 7 additions & 10 deletions builtin.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,17 +50,8 @@ load_with_builtin_functions(const char *feature_name, const struct rb_builtin_fu
ASSUME(iseq); // otherwise an exception should have raised
vm->builtin_function_table = NULL;

rb_namespace_enable_builtin();

// exec
if (rb_namespace_available() && rb_mNamespaceRefiner) {
rb_iseq_eval_with_refinement(rb_iseq_check(iseq), rb_mNamespaceRefiner);
}
else {
rb_iseq_eval(rb_iseq_check(iseq));
}

rb_namespace_disable_builtin();
rb_iseq_eval(rb_iseq_check(iseq), rb_root_namespace()); // builtin functions are loaded in the root namespace
}

void
Expand All @@ -86,5 +77,11 @@ Init_builtin(void)
void
Init_builtin_features(void)
{

#ifdef BUILTIN_BINARY_SIZE

load_with_builtin_functions("gem_prelude", NULL);

#endif

}
6 changes: 5 additions & 1 deletion class.c
Original file line number Diff line number Diff line change
Expand Up @@ -650,7 +650,7 @@ class_alloc0(enum ruby_value_type type, VALUE klass, bool namespaceable)
{
rb_ns_subclasses_t *ns_subclasses;
rb_subclass_anchor_t *anchor;
const rb_namespace_t *ns = rb_definition_namespace();
const rb_namespace_t *ns = rb_current_namespace();

if (!ruby_namespace_init_done) {
namespaceable = true;
Expand Down Expand Up @@ -693,6 +693,10 @@ class_alloc0(enum ruby_value_type type, VALUE klass, bool namespaceable)
RCLASS_SET_SUPER((VALUE)obj, 0);
*/

if (namespaceable) {
((struct RClass_namespaceable *)obj)->ns_classext_tbl = NULL;
}

RCLASS_PRIME_NS((VALUE)obj) = ns;
// Classes/Modules defined in user namespaces are
// writable directly because it exists only in a namespace.
Expand Down
1 change: 1 addition & 0 deletions common.mk
Original file line number Diff line number Diff line change
Expand Up @@ -1316,6 +1316,7 @@ $(common_mk__artifact_): $(srcdir)/common.mk $(common_mk_includes)
ripper_srcs: $(RIPPER_SRCS)

$(RIPPER_SRCS): $(srcdir)/parse.y $(srcdir)/defs/id.def
$(RIPPER_SRCS): $(srcdir)/ext/ripper/depend $(srcdir)/ext/ripper/extconf.rb
$(RIPPER_SRCS): $(srcdir)/ext/ripper/tools/preproc.rb $(srcdir)/ext/ripper/tools/dsl.rb
$(RIPPER_SRCS): $(srcdir)/ext/ripper/ripper_init.c.tmpl $(srcdir)/ext/ripper/eventids2.c
$(ECHO) generating $@
Expand Down
29 changes: 29 additions & 0 deletions depend
Original file line number Diff line number Diff line change
Expand Up @@ -9263,6 +9263,29 @@ namespace.$(OBJEXT): $(top_srcdir)/internal/string.h
namespace.$(OBJEXT): $(top_srcdir)/internal/variable.h
namespace.$(OBJEXT): $(top_srcdir)/internal/vm.h
namespace.$(OBJEXT): $(top_srcdir)/internal/warnings.h
namespace.$(OBJEXT): $(top_srcdir)/prism/ast.h
namespace.$(OBJEXT): $(top_srcdir)/prism/defines.h
namespace.$(OBJEXT): $(top_srcdir)/prism/diagnostic.h
namespace.$(OBJEXT): $(top_srcdir)/prism/encoding.h
namespace.$(OBJEXT): $(top_srcdir)/prism/node.h
namespace.$(OBJEXT): $(top_srcdir)/prism/options.h
namespace.$(OBJEXT): $(top_srcdir)/prism/pack.h
namespace.$(OBJEXT): $(top_srcdir)/prism/parser.h
namespace.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h
namespace.$(OBJEXT): $(top_srcdir)/prism/prism.h
namespace.$(OBJEXT): $(top_srcdir)/prism/regexp.h
namespace.$(OBJEXT): $(top_srcdir)/prism/static_literals.h
namespace.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h
namespace.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h
namespace.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h
namespace.$(OBJEXT): $(top_srcdir)/prism/util/pm_integer.h
namespace.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h
namespace.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h
namespace.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h
namespace.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h
namespace.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h
namespace.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h
namespace.$(OBJEXT): $(top_srcdir)/prism/version.h
namespace.$(OBJEXT): {$(VPATH)}assert.h
namespace.$(OBJEXT): {$(VPATH)}atomic.h
namespace.$(OBJEXT): {$(VPATH)}backward/2/assume.h
Expand All @@ -9279,6 +9302,7 @@ namespace.$(OBJEXT): {$(VPATH)}constant.h
namespace.$(OBJEXT): {$(VPATH)}debug_counter.h
namespace.$(OBJEXT): {$(VPATH)}defines.h
namespace.$(OBJEXT): {$(VPATH)}encoding.h
namespace.$(OBJEXT): {$(VPATH)}eval_intern.h
namespace.$(OBJEXT): {$(VPATH)}id.h
namespace.$(OBJEXT): {$(VPATH)}id_table.h
namespace.$(OBJEXT): {$(VPATH)}intern.h
Expand Down Expand Up @@ -9433,12 +9457,17 @@ namespace.$(OBJEXT): {$(VPATH)}internal/value_type.h
namespace.$(OBJEXT): {$(VPATH)}internal/variable.h
namespace.$(OBJEXT): {$(VPATH)}internal/warning_push.h
namespace.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
namespace.$(OBJEXT): {$(VPATH)}iseq.h
namespace.$(OBJEXT): {$(VPATH)}method.h
namespace.$(OBJEXT): {$(VPATH)}missing.h
namespace.$(OBJEXT): {$(VPATH)}namespace.c
namespace.$(OBJEXT): {$(VPATH)}node.h
namespace.$(OBJEXT): {$(VPATH)}onigmo.h
namespace.$(OBJEXT): {$(VPATH)}oniguruma.h
namespace.$(OBJEXT): {$(VPATH)}prism/ast.h
namespace.$(OBJEXT): {$(VPATH)}prism/diagnostic.h
namespace.$(OBJEXT): {$(VPATH)}prism/version.h
namespace.$(OBJEXT): {$(VPATH)}prism_compile.h
namespace.$(OBJEXT): {$(VPATH)}ruby_assert.h
namespace.$(OBJEXT): {$(VPATH)}ruby_atomic.h
namespace.$(OBJEXT): {$(VPATH)}rubyparser.h
Expand Down
1 change: 1 addition & 0 deletions eval.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ ruby_setup(void)
rb_vm_encoded_insn_data_table_init();
Init_enable_namespace();
Init_vm_objects();
Init_root_namespace();
Init_fstring_table();

EC_PUSH_TAG(GET_EC());
Expand Down
6 changes: 5 additions & 1 deletion eval_intern.h
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,11 @@ VALUE rb_vm_make_jump_tag_but_local_jump(enum ruby_tag_type state, VALUE val);
rb_cref_t *rb_vm_cref(void);
rb_cref_t *rb_vm_cref_replace_with_duplicated_cref(void);
VALUE rb_vm_call_cfunc(VALUE recv, VALUE (*func)(VALUE), VALUE arg, VALUE block_handler, VALUE filename);
VALUE rb_vm_call_cfunc2(VALUE recv, VALUE (*func)(VALUE, VALUE), VALUE arg1, VALUE arg2, VALUE block_handler, VALUE filename);
VALUE rb_vm_call_cfunc_in_namespace(VALUE recv, VALUE (*func)(VALUE, VALUE), VALUE arg1, VALUE arg2, VALUE filename, const rb_namespace_t *ns);
void rb_vm_frame_flag_set_ns_require(const rb_execution_context_t *ec);
const rb_namespace_t *rb_vm_current_namespace(const rb_execution_context_t *ec);
const rb_namespace_t *rb_vm_caller_namespace(const rb_execution_context_t *ec);
const rb_namespace_t *rb_vm_loading_namespace(const rb_execution_context_t *ec);
void rb_vm_set_progname(VALUE filename);
VALUE rb_vm_cbase(void);

Expand Down
2 changes: 1 addition & 1 deletion inits.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ rb_call_inits(void)
CALL(Time);
CALL(Random);
CALL(load);
CALL(Namespace);
CALL(Proc);
CALL(Binding);
CALL(Math);
Expand All @@ -78,7 +79,6 @@ rb_call_inits(void)
CALL(Prism);
CALL(unicode_version);
CALL(Set);
CALL(Namespace);

// enable builtin loading
CALL(builtin);
Expand Down
3 changes: 2 additions & 1 deletion insns.def
Original file line number Diff line number Diff line change
Expand Up @@ -803,12 +803,13 @@ defineclass
(VALUE val)
{
VALUE klass = vm_find_or_create_class_by_id(id, flags, cbase, super);
const rb_namespace_t *ns = rb_current_namespace();

rb_iseq_check(class_iseq);

/* enter scope */
vm_push_frame(ec, class_iseq, VM_FRAME_MAGIC_CLASS | VM_ENV_FLAG_LOCAL, klass,
GET_BLOCK_HANDLER(),
GC_GUARDED_PTR(ns),
(VALUE)vm_cref_push(ec, klass, NULL, FALSE, FALSE),
ISEQ_BODY(class_iseq)->iseq_encoded, GET_SP(),
ISEQ_BODY(class_iseq)->local_table_size,
Expand Down
16 changes: 6 additions & 10 deletions internal/class.h
Original file line number Diff line number Diff line change
Expand Up @@ -390,8 +390,7 @@ RCLASS_EXT_READABLE_LOOKUP(VALUE obj, const rb_namespace_t *ns)
static inline rb_classext_t *
RCLASS_EXT_READABLE_IN_NS(VALUE obj, const rb_namespace_t *ns)
{
if (!ns
|| NAMESPACE_BUILTIN_P(ns)
if (NAMESPACE_ROOT_P(ns)
|| RCLASS_PRIME_CLASSEXT_READABLE_P(obj)) {
return RCLASS_EXT_PRIME(obj);
}
Expand All @@ -405,9 +404,9 @@ RCLASS_EXT_READABLE(VALUE obj)
if (RCLASS_PRIME_CLASSEXT_READABLE_P(obj)) {
return RCLASS_EXT_PRIME(obj);
}
// delay namespace loading to optimize for unmodified classes
// delay determining the current namespace to optimize for unmodified classes
ns = rb_current_namespace();
if (!ns || NAMESPACE_BUILTIN_P(ns)) {
if (NAMESPACE_ROOT_P(ns)) {
return RCLASS_EXT_PRIME(obj);
}
return RCLASS_EXT_READABLE_LOOKUP(obj, ns);
Expand Down Expand Up @@ -440,8 +439,7 @@ RCLASS_EXT_WRITABLE_LOOKUP(VALUE obj, const rb_namespace_t *ns)
static inline rb_classext_t *
RCLASS_EXT_WRITABLE_IN_NS(VALUE obj, const rb_namespace_t *ns)
{
if (!ns
|| NAMESPACE_BUILTIN_P(ns)
if (NAMESPACE_ROOT_P(ns)
|| RCLASS_PRIME_CLASSEXT_WRITABLE_P(obj)) {
return RCLASS_EXT_PRIME(obj);
}
Expand All @@ -455,11 +453,9 @@ RCLASS_EXT_WRITABLE(VALUE obj)
if (LIKELY(RCLASS_PRIME_CLASSEXT_WRITABLE_P(obj))) {
return RCLASS_EXT_PRIME(obj);
}
// delay namespace loading to optimize for unmodified classes
// delay determining the current namespace to optimize for unmodified classes
ns = rb_current_namespace();
if (!ns || NAMESPACE_BUILTIN_P(ns)) {
// If no namespace is specified, Ruby VM is in bootstrap
// and the clean class definition is under construction.
if (NAMESPACE_ROOT_P(ns)) {
return RCLASS_EXT_PRIME(obj);
}
return RCLASS_EXT_WRITABLE_LOOKUP(obj, ns);
Expand Down
3 changes: 3 additions & 0 deletions internal/inits.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ void Init_enable_namespace(void);
void Init_BareVM(void);
void Init_vm_objects(void);

/* namespace.c */
void Init_root_namespace(void);

/* vm_backtrace.c */
void Init_vm_backtrace(void);

Expand Down
21 changes: 7 additions & 14 deletions internal/namespace.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,14 @@ struct rb_namespace_struct {

VALUE gvar_tbl;

bool is_builtin;
bool is_user;
bool is_optional;
};
typedef struct rb_namespace_struct rb_namespace_t;

#define NAMESPACE_BUILTIN_P(ns) (ns && ns->is_builtin)
#define NAMESPACE_OBJ_P(obj) (rb_obj_class(obj) == rb_cNamespace)

#define NAMESPACE_ROOT_P(ns) (ns && !ns->is_user)
#define NAMESPACE_USER_P(ns) (ns && ns->is_user)
#define NAMESPACE_OPTIONAL_P(ns) (ns && ns->is_optional)
#define NAMESPACE_MAIN_P(ns) (ns && ns->is_user && !ns->is_optional)
Expand All @@ -60,24 +61,16 @@ rb_namespace_available(void)
return ruby_namespace_enabled;
}

void rb_namespace_enable_builtin(void);
void rb_namespace_disable_builtin(void);
void rb_namespace_push_loading_namespace(const rb_namespace_t *);
void rb_namespace_pop_loading_namespace(const rb_namespace_t *);
rb_namespace_t * rb_root_namespace(void);
const rb_namespace_t *rb_builtin_namespace(void);
rb_namespace_t * rb_main_namespace(void);
const rb_namespace_t * rb_definition_namespace(void);
const rb_namespace_t * rb_loading_namespace(void);
const rb_namespace_t * rb_root_namespace(void);
const rb_namespace_t * rb_main_namespace(void);
const rb_namespace_t * rb_current_namespace(void);
VALUE rb_current_namespace_details(VALUE);
const rb_namespace_t * rb_loading_namespace(void);

void rb_namespace_entry_mark(void *);
void rb_namespace_gc_update_references(void *ptr);

rb_namespace_t * rb_get_namespace_t(VALUE ns);
VALUE rb_get_namespace_object(rb_namespace_t *ns);
typedef VALUE namespace_exec_func(VALUE arg);
VALUE rb_namespace_exec(const rb_namespace_t *ns, namespace_exec_func *func, VALUE arg);

VALUE rb_namespace_local_extension(VALUE namespace, VALUE fname, VALUE path);

Expand Down
17 changes: 16 additions & 1 deletion iseq.c
Original file line number Diff line number Diff line change
Expand Up @@ -1161,6 +1161,21 @@ rb_iseq_load_iseq(VALUE fname)
return NULL;
}

const rb_iseq_t *
rb_iseq_compile_iseq(VALUE str, VALUE fname)
{
VALUE args[] = {
str, fname
};
VALUE iseqv = rb_check_funcall(rb_cISeq, rb_intern("compile"), 2, args);

if (!SPECIAL_CONST_P(iseqv) && RBASIC_CLASS(iseqv) == rb_cISeq) {
return iseqw_check(iseqv);
}

return NULL;
}

#define CHECK_ARRAY(v) rb_to_array_type(v)
#define CHECK_HASH(v) rb_to_hash_type(v)
#define CHECK_STRING(v) rb_str_to_str(v)
Expand Down Expand Up @@ -1966,7 +1981,7 @@ iseqw_eval(VALUE self)
if (0 == ISEQ_BODY(iseq)->iseq_size) {
rb_raise(rb_eTypeError, "attempt to evaluate dummy InstructionSequence");
}
return rb_iseq_eval(iseq);
return rb_iseq_eval(iseq, rb_current_namespace());
}

/*
Expand Down
1 change: 1 addition & 0 deletions iseq.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ void rb_iseq_init_trace(rb_iseq_t *iseq);
int rb_iseq_add_local_tracepoint_recursively(const rb_iseq_t *iseq, rb_event_flag_t turnon_events, VALUE tpval, unsigned int target_line, bool target_bmethod);
int rb_iseq_remove_local_tracepoint_recursively(const rb_iseq_t *iseq, VALUE tpval);
const rb_iseq_t *rb_iseq_load_iseq(VALUE fname);
const rb_iseq_t *rb_iseq_compile_iseq(VALUE str, VALUE fname);
int rb_iseq_opt_frozen_string_literal(void);

#if VM_INSN_INFO_TABLE_IMPL == 2
Expand Down
Loading