Skip to content

Commit 5f69e35

Browse files
tekknolagik0kubun
authored andcommitted
Add return_type to FnProperties and CCall
1 parent 3e57c4d commit 5f69e35

File tree

3 files changed

+39
-16
lines changed

3 files changed

+39
-16
lines changed

zjit/src/codegen.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ fn gen_insn(jit: &mut JITState, asm: &mut Assembler, function: &Function, insn_i
203203
Insn::GuardType { val, guard_type, state } => gen_guard_type(asm, opnd!(val), *guard_type, &function.frame_state(*state))?,
204204
Insn::GuardBitEquals { val, expected, state } => gen_guard_bit_equals(asm, opnd!(val), *expected, &function.frame_state(*state))?,
205205
Insn::PatchPoint(_) => return Some(()), // For now, rb_zjit_bop_redefined() panics. TODO: leave a patch point and fix rb_zjit_bop_redefined()
206-
Insn::CCall { cfun, args, name: _ } => gen_ccall(jit, asm, *cfun, args)?,
206+
Insn::CCall { cfun, args, name: _, return_type: _ } => gen_ccall(jit, asm, *cfun, args)?,
207207
_ => {
208208
debug!("ZJIT: gen_function: unexpected insn {:?}", insn);
209209
return None;

zjit/src/cruby_methods.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,21 @@
1111
use crate::cruby::*;
1212
use std::collections::HashMap;
1313
use std::ffi::c_void;
14+
use crate::hir_type::{types, Type};
1415

1516
pub struct Annotations {
1617
cfuncs: HashMap<*mut c_void, FnProperties>,
1718
}
1819

1920
/// Runtime behaviors of C functions that implement a Ruby method
20-
#[derive(Clone, Copy, Default)]
21+
#[derive(Clone, Copy)]
2122
pub struct FnProperties {
2223
/// Whether it's possible for the function to yield to the GC
2324
pub no_gc: bool,
2425
/// Whether it's possible for the function to make a ruby call
2526
pub leaf: bool,
27+
/// What Type the C function returns
28+
pub return_type: Type,
2629
}
2730

2831
impl Annotations {
@@ -60,19 +63,19 @@ pub fn init() -> Annotations {
6063
let cfuncs = &mut HashMap::new();
6164

6265
macro_rules! annotate {
63-
($module:ident, $method_name:literal, $($properties:ident),+) => {
64-
let mut props = FnProperties::default();
66+
($module:ident, $method_name:literal, $return_type:expr, $($properties:ident),+) => {
67+
let mut props = FnProperties { no_gc: false, leaf: false, return_type: $return_type };
6568
$(
6669
props.$properties = true;
6770
)+
6871
annotate_c_method(cfuncs, unsafe { $module }, $method_name, props);
6972
}
7073
}
7174

72-
annotate!(rb_mKernel, "itself", no_gc, leaf);
73-
annotate!(rb_cString, "bytesize", no_gc, leaf);
74-
annotate!(rb_cModule, "name", no_gc, leaf);
75-
annotate!(rb_cModule, "===", no_gc, leaf);
75+
annotate!(rb_mKernel, "itself", types::BasicObject, no_gc, leaf);
76+
annotate!(rb_cString, "bytesize", types::Fixnum, no_gc, leaf);
77+
annotate!(rb_cModule, "name", types::StringExact.union(types::NilClassExact), no_gc, leaf);
78+
annotate!(rb_cModule, "===", types::BoolExact, no_gc, leaf);
7679

7780
Annotations {
7881
cfuncs: std::mem::take(cfuncs)

zjit/src/hir.rs

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ pub enum Insn {
326326

327327
// Call a C function
328328
// `name` is for printing purposes only
329-
CCall { cfun: *const u8, args: Vec<InsnId>, name: ID },
329+
CCall { cfun: *const u8, args: Vec<InsnId>, name: ID, return_type: Type },
330330

331331
// Send without block with dynamic dispatch
332332
// Ignoring keyword arguments etc for now
@@ -475,11 +475,11 @@ impl<'a> std::fmt::Display for InsnPrinter<'a> {
475475
Insn::FixnumLe { left, right, .. } => { write!(f, "FixnumLe {left}, {right}") },
476476
Insn::FixnumGt { left, right, .. } => { write!(f, "FixnumGt {left}, {right}") },
477477
Insn::FixnumGe { left, right, .. } => { write!(f, "FixnumGe {left}, {right}") },
478-
Insn::GuardType { val, guard_type, .. } => { write!(f, "GuardType {val}, {guard_type}") },
478+
Insn::GuardType { val, guard_type, .. } => { write!(f, "GuardType {val}, {}", guard_type.print(self.ptr_map)) },
479479
Insn::GuardBitEquals { val, expected, .. } => { write!(f, "GuardBitEquals {val}, {}", expected.print(self.ptr_map)) },
480480
Insn::PatchPoint(invariant) => { write!(f, "PatchPoint {}", invariant.print(self.ptr_map)) },
481481
Insn::GetConstantPath { ic } => { write!(f, "GetConstantPath {:p}", self.ptr_map.map_ptr(ic)) },
482-
Insn::CCall { cfun, args, name } => {
482+
Insn::CCall { cfun, args, name, return_type: _ } => {
483483
write!(f, "CCall {}@{:p}", name.contents_lossy(), self.ptr_map.map_ptr(cfun))?;
484484
for arg in args {
485485
write!(f, ", {arg}")?;
@@ -790,7 +790,7 @@ impl Function {
790790
},
791791
ArraySet { array, idx, val } => ArraySet { array: find!(*array), idx: *idx, val: find!(*val) },
792792
ArrayDup { val } => ArrayDup { val: find!(*val) },
793-
CCall { cfun, args, name } => CCall { cfun: *cfun, args: args.iter().map(|arg| find!(*arg)).collect(), name: *name },
793+
CCall { cfun, args, name, return_type } => CCall { cfun: *cfun, args: args.iter().map(|arg| find!(*arg)).collect(), name: *name, return_type: *return_type },
794794
Defined { .. } => todo!("find(Defined)"),
795795
}
796796
}
@@ -838,7 +838,7 @@ impl Function {
838838
Insn::StringIntern { .. } => types::StringExact,
839839
Insn::NewArray { .. } => types::ArrayExact,
840840
Insn::ArrayDup { .. } => types::ArrayExact,
841-
Insn::CCall { .. } => types::Any,
841+
Insn::CCall { return_type, .. } => *return_type,
842842
Insn::GuardType { val, guard_type, .. } => self.type_of(*val).intersection(*guard_type),
843843
Insn::GuardBitEquals { val, expected, .. } => self.type_of(*val).intersection(Type::from_value(*expected)),
844844
Insn::FixnumAdd { .. } => types::Fixnum,
@@ -1024,7 +1024,7 @@ impl Function {
10241024

10251025
// Filter for a leaf and GC free function
10261026
use crate::cruby_methods::FnProperties;
1027-
let Some(FnProperties { leaf: true, no_gc: true }) =
1027+
let Some(FnProperties { leaf: true, no_gc: true, return_type }) =
10281028
ZJITState::get_method_annotations().get_cfunc_properties(method)
10291029
else {
10301030
return Err(());
@@ -1040,7 +1040,7 @@ impl Function {
10401040
let cfun = unsafe { get_mct_func(cfunc) }.cast();
10411041
let mut cfunc_args = vec![self_val];
10421042
cfunc_args.append(&mut args);
1043-
let ccall = fun.push_insn(block, Insn::CCall { cfun, args: cfunc_args, name: method_id });
1043+
let ccall = fun.push_insn(block, Insn::CCall { cfun, args: cfunc_args, name: method_id, return_type });
10441044
fun.make_equal_to(send_insn_id, ccall);
10451045
return Ok(());
10461046
}
@@ -3306,7 +3306,7 @@ mod opt_tests {
33063306
bb0():
33073307
v1:Fixnum[1] = Const Value(1)
33083308
PatchPoint MethodRedefined(Integer@0x1000, itself@0x1008)
3309-
v8:Any = CCall itself@0x1010, v1
3309+
v8:BasicObject = CCall itself@0x1010, v1
33103310
PatchPoint CalleeModifiedLocals(v8)
33113311
Return v8
33123312
"#]]);
@@ -3330,4 +3330,24 @@ mod opt_tests {
33303330
Return v4
33313331
"#]]);
33323332
}
3333+
3334+
#[test]
3335+
fn string_bytesize_simple() {
3336+
eval("
3337+
def test = 'abc'.bytesize
3338+
test
3339+
test
3340+
");
3341+
assert_optimized_method_hir("test", expect![[r#"
3342+
fn test:
3343+
bb0():
3344+
v1:StringExact[VALUE(0x1000)] = Const Value(VALUE(0x1000))
3345+
v2:StringExact = StringCopy v1
3346+
PatchPoint MethodRedefined(String@0x1008, bytesize@0x1010)
3347+
v8:StringExact[VALUE(0x1018)] = GuardType v2, StringExact[VALUE(0x1018)]
3348+
v9:Fixnum = CCall bytesize@0x1020, v2
3349+
PatchPoint CalleeModifiedLocals(v9)
3350+
Return v9
3351+
"#]]);
3352+
}
33333353
}

0 commit comments

Comments
 (0)