-
-
Notifications
You must be signed in to change notification settings - Fork 56
Open
Labels
enhancementNew feature or requestNew feature or request
Description
Summary
Add stable API methods for converting between Ruby numeric values and C's long, equivalent to NUM2LONG, RB_NUM2LONG, LONG2NUM, and RB_LONG2NUM.
Motivation
Integer conversion is one of the most common operations in Ruby C extensions:
- Extracting array indices
- Loop counters
- Size/length values
- Any numeric parameter handling
The inline versions handle Fixnum fast-path without function call overhead.
Ruby Source Reference
// include/ruby/internal/arithmetic/long.h
static inline long
rb_num2long_inline(VALUE x)
{
if (RB_FIXNUM_P(x))
return RB_FIX2LONG(x);
else
return rb_num2long(x); // handles Bignum, Float, etc.
}
static inline VALUE
rb_long2num_inline(long v)
{
if (RB_FIXABLE(v))
return RB_LONG2FIX(v);
else
return rb_int2big(v);
}Proposed API
/// Convert a Ruby numeric to C long (akin to `NUM2LONG`).
///
/// Handles Fixnum (fast path), Bignum, Float, and any object responding to to_int.
///
/// # Safety
/// This function is unsafe because it may call Ruby methods (to_int)
/// which could raise exceptions or trigger GC.
unsafe fn num2long(&self, obj: VALUE) -> c_long;
/// Convert C long to Ruby Integer (akin to `LONG2NUM`).
///
/// Returns a Fixnum if the value fits, otherwise creates a Bignum.
fn long2num(&self, val: c_long) -> VALUE;
/// Convert a Ruby Fixnum to C long (akin to `FIX2LONG`).
///
/// # Safety
/// Caller must ensure the VALUE is actually a Fixnum.
fn fix2long(&self, obj: VALUE) -> c_long;
/// Convert C long to Ruby Fixnum (akin to `LONG2FIX`).
///
/// # Panics
/// Debug builds will panic if the value doesn't fit in a Fixnum.
fn long2fix(&self, val: c_long) -> VALUE;
/// Check if a long value fits in a Fixnum (akin to `FIXABLE`).
fn fixable(&self, val: c_long) -> bool;Implementation Notes
FIX2LONG: Right-shift by 1 (arithmetic shift)LONG2FIX: Left-shift by 1, OR withRUBY_FIXNUM_FLAGFIXABLE: Check againstRUBY_FIXNUM_MINandRUBY_FIXNUM_MAX- These are simple bit operations, should be very fast
- Reference:
include/ruby/internal/arithmetic/long.h
Checklist
- Add methods to
StableApiDefinitiontrait - Implement for each Ruby version
- Add C fallback in
compiled.c - Add public macro wrappers in
macros.rs - Add comprehensive tests including edge cases
- Add to
show-asmscript for performance verification
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request