Skip to content

Commit

Permalink
Implemented StableApiDefinition::[bignum_positive_p|bignum_negative_p…
Browse files Browse the repository at this point in the history
…]. (#461)

* Implemented StableApiDefinition::[bignum_positive_p|bignum_negative_p].

* Avoiding function calls to be on par with macros.

* Review suggestion: Lets implement bignum_negative_p by default using bignum_positive_p.

* Fixing copy/pasta errors.
  • Loading branch information
goyox86 authored Dec 5, 2024
1 parent de0ab79 commit 3f54d0b
Show file tree
Hide file tree
Showing 12 changed files with 149 additions and 3 deletions.
4 changes: 1 addition & 3 deletions crates/rb-sys-build/src/bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,7 @@ pub fn generate(
let bindings = if cfg!(feature = "bindgen-deprecated-types") {
bindings
} else {
bindings
.blocklist_item("^ruby_fl_type.*")
.blocklist_item("^_bindgen_ty_9.*")
bindings.blocklist_item("^_bindgen_ty_9.*")
};

let bindings = opaqueify_bindings(rbconfig, bindings, &mut wrapper_h);
Expand Down
54 changes: 54 additions & 0 deletions crates/rb-sys-tests/src/stable_api_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,60 @@ parity_test!(
}
);

parity_test!(
name: test_bignum_positive_p_evaled,
func: bignum_positive_p,
data_factory: {
ruby_eval!("2 ** 64")
},
expected: true
);

parity_test!(
name: test_bignum_negative_p_evaled,
func: bignum_negative_p,
data_factory: {
ruby_eval!("-(2 ** 64)")
},
expected: true
);

parity_test!(
name: test_bignum_positive_p_for_zero,
func: bignum_positive_p,
data_factory: {
unsafe { rb_sys::rb_int2big(0) }
},
expected: true
);

parity_test!(
name: test_bignum_negative_p_for_zero,
func: bignum_negative_p,
data_factory: {
unsafe { rb_sys::rb_int2big(0) }
},
expected: false
);

parity_test!(
name: test_bignum_positive_p,
func: bignum_positive_p,
data_factory: {
unsafe { rb_sys::rb_int2big(64) }
},
expected: true
);

parity_test!(
name: test_bignum_negative_p,
func: bignum_negative_p,
data_factory: {
unsafe { rb_sys::rb_int2big(-1) }
},
expected: true
);

parity_test!(
name: test_builtin_type_for_string,
func: builtin_type,
Expand Down
18 changes: 18 additions & 0 deletions crates/rb-sys/src/stable_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,24 @@ pub trait StableApiDefinition {
/// is valid.
unsafe fn rarray_const_ptr(&self, obj: VALUE) -> *const VALUE;

/// Tests if a bignum is positive.
///
/// # Safety
/// This function is unsafe because it dereferences a raw pointer to get
/// access to underlying RBasic struct. The caller must ensure that the
/// `VALUE` is a valid pointer to a bignum.
unsafe fn bignum_positive_p(&self, obj: VALUE) -> bool;

/// Tests if a bignum is negative.
///
/// # Safety
/// This function is unsafe because it dereferences a raw pointer to get
/// access to underlying RBasic struct. The caller must ensure that the
/// `VALUE` is a valid pointer to a bignum.
unsafe fn bignum_negative_p(&self, obj: VALUE) -> bool {
!self.bignum_positive_p(obj)
}

/// Tests if the given value is a special constant.
fn special_const_p(&self, value: VALUE) -> bool;

Expand Down
11 changes: 11 additions & 0 deletions crates/rb-sys/src/stable_api/compiled.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,17 @@ impl_special_const_p(VALUE obj) {
return SPECIAL_CONST_P(obj);
}

int
impl_bignum_positive_p(VALUE obj) {
return RBIGNUM_POSITIVE_P(obj);
}

int
impl_bignum_negative_p(VALUE obj) {
return RBIGNUM_NEGATIVE_P(obj);
}


enum ruby_value_type
impl_builtin_type(VALUE obj) {
return RB_BUILTIN_TYPE(obj);
Expand Down
16 changes: 16 additions & 0 deletions crates/rb-sys/src/stable_api/compiled.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ extern "C" {
#[link_name = "impl_special_const_p"]
fn impl_special_const_p(value: VALUE) -> bool;

#[link_name = "impl_bignum_positive_p"]
fn impl_bignum_positive_p(obj: VALUE) -> bool;

#[link_name = "impl_bignum_negative_p"]
fn impl_bignum_negative_p(obj: VALUE) -> bool;

#[link_name = "impl_builtin_type"]
fn impl_builtin_type(obj: VALUE) -> ruby_value_type;

Expand Down Expand Up @@ -93,6 +99,16 @@ impl StableApiDefinition for Definition {
unsafe { impl_special_const_p(value) }
}

#[inline]
unsafe fn bignum_positive_p(&self, obj: VALUE) -> bool {
impl_bignum_positive_p(obj)
}

#[inline]
unsafe fn bignum_negative_p(&self, obj: VALUE) -> bool {
impl_bignum_negative_p(obj)
}

#[inline]
unsafe fn builtin_type(&self, obj: VALUE) -> ruby_value_type {
impl_builtin_type(obj)
Expand Down
7 changes: 7 additions & 0 deletions crates/rb-sys/src/stable_api/ruby_2_6.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,13 @@ impl StableApiDefinition for Definition {
ptr
}

#[inline]
unsafe fn bignum_positive_p(&self, obj: VALUE) -> bool {
let rbasic = obj as *const crate::RBasic;

((*rbasic).flags & crate::ruby_fl_type::RUBY_FL_USER1 as VALUE) != 0
}

#[inline]
fn special_const_p(&self, value: VALUE) -> bool {
let is_immediate = value & (crate::special_consts::IMMEDIATE_MASK as VALUE) != 0;
Expand Down
7 changes: 7 additions & 0 deletions crates/rb-sys/src/stable_api/ruby_2_7.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,13 @@ impl StableApiDefinition for Definition {
ptr
}

#[inline]
unsafe fn bignum_positive_p(&self, obj: VALUE) -> bool {
let rbasic = obj as *const crate::RBasic;

((*rbasic).flags & crate::ruby_fl_type::RUBY_FL_USER1 as VALUE) != 0
}

#[inline]
fn special_const_p(&self, value: VALUE) -> bool {
let is_immediate = value & (crate::special_consts::IMMEDIATE_MASK as VALUE) != 0;
Expand Down
7 changes: 7 additions & 0 deletions crates/rb-sys/src/stable_api/ruby_3_0.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,13 @@ impl StableApiDefinition for Definition {
}
}

#[inline]
unsafe fn bignum_positive_p(&self, obj: VALUE) -> bool {
let rbasic = obj as *const crate::RBasic;

((*rbasic).flags & crate::ruby_fl_type::RUBY_FL_USER1 as VALUE) != 0
}

#[inline]
fn special_const_p(&self, value: VALUE) -> bool {
let is_immediate = value & (crate::special_consts::IMMEDIATE_MASK as VALUE) != 0;
Expand Down
7 changes: 7 additions & 0 deletions crates/rb-sys/src/stable_api/ruby_3_1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,13 @@ impl StableApiDefinition for Definition {
ret
}

#[inline]
unsafe fn bignum_positive_p(&self, obj: VALUE) -> bool {
let rbasic = obj as *const crate::RBasic;

((*rbasic).flags & crate::ruby_fl_type::RUBY_FL_USER1 as VALUE) != 0
}

#[inline]
fn special_const_p(&self, value: VALUE) -> bool {
let is_immediate = value & (crate::special_consts::IMMEDIATE_MASK as VALUE) != 0;
Expand Down
7 changes: 7 additions & 0 deletions crates/rb-sys/src/stable_api/ruby_3_2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,13 @@ impl StableApiDefinition for Definition {
ptr
}

#[inline]
unsafe fn bignum_positive_p(&self, obj: VALUE) -> bool {
let rbasic = obj as *const crate::RBasic;

((*rbasic).flags & crate::ruby_fl_type::RUBY_FL_USER1 as VALUE) != 0
}

#[inline]
fn special_const_p(&self, value: VALUE) -> bool {
let is_immediate = (value) & (crate::special_consts::IMMEDIATE_MASK as VALUE) != 0;
Expand Down
7 changes: 7 additions & 0 deletions crates/rb-sys/src/stable_api/ruby_3_3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,13 @@ impl StableApiDefinition for Definition {
ptr
}

#[inline]
unsafe fn bignum_positive_p(&self, obj: VALUE) -> bool {
let rbasic = obj as *const crate::RBasic;

((*rbasic).flags & crate::ruby_fl_type::RUBY_FL_USER1 as VALUE) != 0
}

#[inline]
fn special_const_p(&self, value: VALUE) -> bool {
let is_immediate = (value) & (crate::special_consts::IMMEDIATE_MASK as VALUE) != 0;
Expand Down
7 changes: 7 additions & 0 deletions crates/rb-sys/src/stable_api/ruby_3_4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,13 @@ impl StableApiDefinition for Definition {
is_immediate || !test
}

#[inline]
unsafe fn bignum_positive_p(&self, obj: VALUE) -> bool {
let rbasic = obj as *const crate::RBasic;

((*rbasic).flags & crate::ruby_fl_type::RUBY_FL_USER1 as VALUE) != 0
}

#[inline]
unsafe fn builtin_type(&self, obj: VALUE) -> crate::ruby_value_type {
let rbasic = obj as *const crate::RBasic;
Expand Down

0 comments on commit 3f54d0b

Please sign in to comment.