8000 Fix for 32bit Linux by nobu · Pull Request #13607 · ruby/ruby · GitHub
[go: up one dir, main page]

Skip to content

Fix for 32bit Linux #13607

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions file.c
Original file line number Diff line number Diff line change
Expand Up @@ -662,7 +662,7 @@ rb_stat_dev(VALUE self)
#if RUBY_USE_STATX
unsigned int m = get_stat(self)->stx_dev_major;
unsigned int n = get_stat(self)->stx_dev_minor;
return DEVT2NUM(makedev(m, n));
return ULL2NUM(makedev(m, n));
#elif SIZEOF_STRUCT_STAT_ST_DEV <= SIZEOF_DEV_T
return DEVT2NUM(get_stat(self)->st_dev);
#elif SIZEOF_STRUCT_STAT_ST_DEV <= SIZEOF_LONG
Expand Down Expand Up @@ -833,7 +833,7 @@ rb_stat_rdev(VALUE self)
#if RUBY_USE_STATX
unsigned int m = get_stat(self)->stx_rdev_major;
unsigned int n = get_stat(self)->stx_rdev_minor;
return DEVT2NUM(makedev(m, n));
return ULL2NUM(makedev(m, n));
#elif !defined(HAVE_STRUCT_STAT_ST_RDEV)
return Qnil;
#elif SIZEOF_STRUCT_STAT_ST_RDEV <= SIZEOF_DEV_T
Expand Down
50 changes: 27 additions & 23 deletions time.c
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ divmodv(VALUE n, VALUE d, VALUE *q, VALUE *r)
# define FIXWV2WINT(w) FIX2LONG(WIDEVAL_GET(w))
#endif

#define SIZEOF_WIDEINT SIZEOF_INT64_T
#define POSFIXWVABLE(wi) ((wi) < FIXWV_MAX+1)
#define NEGFIXWVABLE(wi) ((wi) >= FIXWV_MIN)
#define FIXWV_P(w) FIXWINT_P(WIDEVAL_GET(w))
Expand Down Expand Up @@ -1891,7 +1892,7 @@ time_mark(void *ptr)
{
struct time_object *tobj = ptr;
if (!FIXWV_P(tobj->timew)) {
rb_gc_mark_movable(WIDEVAL_GET(tobj->timew));
rb_gc_mark_movable(w2v(tobj->timew));
}
rb_gc_mark_movable(tobj->vtm.year);
rb_gc_mark_movable(tobj->vtm.subsecx);
Expand All @@ -1904,7 +1905,7 @@ time_compact(void *ptr)
{
struct time_object *tobj = ptr;
if (!FIXWV_P(tobj->timew)) {
WIDEVAL_GET(tobj->timew) = rb_gc_location(WIDEVAL_GET(tobj->timew));
WIDEVAL_GET(tobj->timew) = WIDEVAL_WRAP(rb_gc_location(w2v(tobj->timew)));
}

tobj->vtm.year = rb_gc_location(tobj->vtm.year);
Expand Down Expand Up @@ -1968,11 +1969,11 @@ time_modify(VALUE time)
}

static wideval_t
timenano2timew(time_t sec, long nsec)
timenano2timew(wideint_t sec, long nsec)
{
wideval_t timew;

timew = rb_time_magnify(TIMET2WV(sec));
timew = rb_time_magnify(WINT2WV(sec));
if (nsec)
timew = wadd(timew, wmulquoll(WINT2WV(nsec), TIME_SCALE, 1000000000));
return timew;
Expand Down Expand Up @@ -2747,46 +2748,35 @@ time_init_parse(rb_execution_context_t *ec, VALUE time, VALUE str, VALUE zone, V
}

static void
subsec_normalize(time_t *secp, long *subsecp, const long maxsubsec)
subsec_normalize(wideint_t *secp, long *subsecp, const long maxsubsec)
{
time_t sec = *secp;
wideint_t sec = *secp;
long subsec = *subsecp;
long sec2;

if (UNLIKELY(subsec >= maxsubsec)) { /* subsec positive overflow */
sec2 = subsec / maxsubsec;
if (TIMET_MAX - sec2 < sec) {
if (WIDEINT_MAX - sec2 < sec) {
rb_raise(rb_eRangeError, "out of Time range");
}
subsec -= sec2 * maxsubsec;
sec += sec2;
}
else if (UNLIKELY(subsec < 0)) { /* subsec negative overflow */
sec2 = NDIV(subsec, maxsubsec); /* negative div */
if (sec < TIMET_MIN - sec2) {
if (sec < WIDEINT_MIN - sec2) {
rb_raise(rb_eRangeError, "out of Time range");
}
subsec -= sec2 * maxsubsec;
sec += sec2;
}
#ifndef NEGATIVE_TIME_T
if (sec < 0)
rb_raise(rb_eArgError, "time must be positive");
#endif
*secp = sec;
*subsecp = subsec;
}

#define time_usec_normalize(secp, usecp) subsec_normalize(secp, usecp, 1000000)
#define time_nsec_normalize(secp, nsecp) subsec_normalize(secp, nsecp, 1000000000)

static wideval_t
nsec2timew(time_t sec, long nsec)
{
time_nsec_normalize(&sec, &nsec);
return timenano2timew(sec, nsec);
}

static VALUE
time_new_timew(VALUE klass, wideval_t timew)
{
Expand All @@ -2800,25 +2790,39 @@ time_new_timew(VALUE klass, wideval_t timew)
return time;
}

static wideint_t
TIMETtoWIDEINT(time_t t)
{
#if SIZEOF_TIME_T * CHAR_BIT - (SIGNEDNESS_OF_TIME_T < 0) > \
SIZEOF_WIDEINT * CHAR_BIT - 1
/* compare in bit size without sign bit */
if (t > WIDEINT_MAX) rb_raise(rb_eArgError, "out of Time range");
#endif
return (wideint_t)t;
}

VALUE
rb_time_new(time_t sec, long usec)
{
time_usec_normalize(&sec, &usec);
return time_new_timew(rb_cTime, timenano2timew(sec, usec * 1000));
wideint_t isec = TIMETtoWIDEINT(sec);
time_usec_normalize(&isec, &usec);
return time_new_timew(rb_cTime, timenano2timew(isec, usec * 1000));
}

/* returns localtime time object */
VALUE
rb_time_nano_new(time_t sec, long nsec)
{
return time_new_timew(rb_cTime, nsec2timew(sec, nsec));
wideint_t isec = TIMETtoWIDEINT(sec);
time_nsec_normalize(&isec, &nsec);
return time_new_timew(rb_cTime, timenano2timew(isec, nsec));
}

VALUE
rb_time_timespec_new(const struct timespec *ts, int offset)
{
struct time_object *tobj;
VALUE time = time_new_timew(rb_cTime, nsec2timew(ts->tv_sec, ts->tv_nsec));
VALUE time = rb_time_nano_new(ts->tv_sec, ts->tv_nsec);

if (-86400 < offset && offset < 86400) { /* fixoff */
GetTimeval(time, tobj);
Expand Down
Loading
0