summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--variable.c3
-rw-r--r--yjit/bindgen/src/main.rs1
-rw-r--r--yjit/src/codegen.rs28
-rw-r--r--yjit/src/cruby_bindings.inc.rs1
4 files changed, 33 insertions, 0 deletions
diff --git a/variable.c b/variable.c
index 4e55427ff5..bcdf2fb070 100644
--- a/variable.c
+++ b/variable.c
@@ -97,6 +97,8 @@ rb_namespace_p(VALUE obj)
* to not be anonymous. <code>*permanent</code> is set to 1
* if +classpath+ has no anonymous components. There is no builtin
* Ruby level APIs that can change a permanent +classpath+.
+ *
+ * YJIT needs this function to not allocate.
*/
static VALUE
classname(VALUE klass, bool *permanent)
@@ -127,6 +129,7 @@ rb_mod_name0(VALUE klass, bool *permanent)
VALUE
rb_mod_name(VALUE mod)
{
+ // YJIT needs this function to not allocate.
bool permanent;
return classname(mod, &permanent);
}
diff --git a/yjit/bindgen/src/main.rs b/yjit/bindgen/src/main.rs
index ea60dd23b9..28e7ac3e9c 100644
--- a/yjit/bindgen/src/main.rs
+++ b/yjit/bindgen/src/main.rs
@@ -378,6 +378,7 @@ fn main() {
.allowlist_function("rb_attr_get")
.allowlist_function("rb_ivar_defined")
.allowlist_function("rb_ivar_get")
+ .allowlist_function("rb_mod_name")
// From internal/vm.h
.allowlist_var("rb_vm_insns_count")
diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs
index 746a46903c..7e69ba32fa 100644
--- a/yjit/src/codegen.rs
+++ b/yjit/src/codegen.rs
@@ -5135,6 +5135,33 @@ fn jit_rb_mod_eqq(
return true;
}
+// Substitution for rb_mod_name(). Returns the name of a module/class.
+fn jit_rb_mod_name(
+ _jit: &mut JITState,
+ asm: &mut Assembler,
+ _ci: *const rb_callinfo,
+ _cme: *const rb_callable_method_entry_t,
+ _block: Option<BlockHandler>,
+ argc: i32,
+ _known_recv_class: Option<VALUE>,
+) -> bool {
+ if argc != 0 {
+ return false;
+ }
+
+ asm_comment!(asm, "Module#name");
+
+ // rb_mod_name() never allocates, so no preparation needed.
+ let name = asm.ccall(rb_mod_name as _, vec![asm.stack_opnd(0)]);
+
+ let _ = asm.stack_pop(1); // pop self
+ // call-seq: mod.name -> string or nil
+ let ret = asm.stack_push(Type::Unknown);
+ asm.mov(ret, name);
+
+ true
+}
+
// Codegen for rb_obj_equal()
// object identity comparison
fn jit_rb_obj_equal(
@@ -10373,6 +10400,7 @@ pub fn yjit_reg_method_codegen_fns() {
yjit_reg_method(rb_mKernel, "eql?", jit_rb_obj_equal);
yjit_reg_method(rb_cModule, "==", jit_rb_obj_equal);
yjit_reg_method(rb_cModule, "===", jit_rb_mod_eqq);
+ yjit_reg_method(rb_cModule, "name", jit_rb_mod_name);
yjit_reg_method(rb_cSymbol, "==", jit_rb_obj_equal);
yjit_reg_method(rb_cSymbol, "===", jit_rb_obj_equal);
yjit_reg_method(rb_cInteger, "==", jit_rb_int_equal);
diff --git a/yjit/src/cruby_bindings.inc.rs b/yjit/src/cruby_bindings.inc.rs
index ea4c14e512..147d30e202 100644
--- a/yjit/src/cruby_bindings.inc.rs
+++ b/yjit/src/cruby_bindings.inc.rs
@@ -1036,6 +1036,7 @@ extern "C" {
pub fn rb_str_buf_append(dst: VALUE, src: VALUE) -> VALUE;
pub fn rb_str_dup(str_: VALUE) -> VALUE;
pub fn rb_str_intern(str_: VALUE) -> VALUE;
+ pub fn rb_mod_name(mod_: VALUE) -> VALUE;
pub fn rb_ivar_get(obj: VALUE, name: ID) -> VALUE;
pub fn rb_ivar_defined(obj: VALUE, name: ID) -> VALUE;
pub fn rb_attr_get(obj: VALUE, name: ID) -> VALUE;