From cd78df63e881342a9617028530bd1c8378b857fa Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Fri, 8 Jul 2022 10:42:27 -0700 Subject: [PATCH] Restore time_t and other core types to 64bit This brings us back in line with upstream musl. The change to 32-bit was only recently made in #16966. The reason we made this change was made was because we had certain C library calls that were implemented in JS that returned `time_t`. Since returning 64-bit values from JS functions is not always easy (we don't always have WASM_BIGINT available) that simplest solution was to define `time_t` to 32-bit which doesn't have issues at the JS boundary. However, in the intervening time many of the `time_t`-returning function have been moved into native code (See #16606 and #16439) with only two remaining: _mktime_js and _timegm_js. So this change redefines just those two functions to return `int` while keeping `time_t` itself as 64-bit. Fixes: #17393 --- ChangeLog.md | 2 ++ system/lib/libc/emscripten_time.c | 8 ++++++-- .../libc/musl/arch/emscripten/bits/alltypes.h | 16 ++++++++-------- system/lib/libc/musl/include/inttypes.h | 8 ++++---- tests/core/test_statvfs.c | 11 ++++++----- tests/utime/test_utime.c | 7 ++++--- 6 files changed, 30 insertions(+), 22 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index 0c346f8ff4088..8be4b342b5bac 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -39,6 +39,8 @@ See docs/process.md for more on how version tagging works. - The getWasmTableEntry/setWasmTableEntry library function are no longer included by default. Add them to `DEFAULT_LIBRARY_FUNCS_TO_INCLUDE` or `EXPORTED_RUNTIME_METHODS` if you want to use them outside of JS library code. +- The type of `time_t` was restored 64-bit after being converted to 32-bit in + 3.1.11. (#17401) 3.1.15 - 07/01/2022 ------------------- diff --git a/system/lib/libc/emscripten_time.c b/system/lib/libc/emscripten_time.c index 6f150c1229dfd..84205e3521ddf 100644 --- a/system/lib/libc/emscripten_time.c +++ b/system/lib/libc/emscripten_time.c @@ -19,8 +19,12 @@ __attribute__((__weak__)) int daylight = 0; __attribute__((__weak__)) char *tzname[2] = { 0, 0 }; void _tzset_js(long* timezone, int* daylight, char** tzname); -time_t _timegm_js(struct tm *tm); -time_t _mktime_js(struct tm *tm); +// Declare these functions `int` rather than time_t to avoid int64 at the wasm +// bounday (avoids 64-bit complexity at the boundary when WASM_BIGINT is +// missing). +// TODO(sbc): Covert back to `time_t` before 2038 ... +int _timegm_js(struct tm *tm); +int _mktime_js(struct tm *tm); void _localtime_js(const time_t *restrict t, struct tm *restrict tm); void _gmtime_js(const time_t *restrict t, struct tm *restrict tm); double _emscripten_date_now(); diff --git a/system/lib/libc/musl/arch/emscripten/bits/alltypes.h b/system/lib/libc/musl/arch/emscripten/bits/alltypes.h index e90252190f63c..f239859acacb6 100644 --- a/system/lib/libc/musl/arch/emscripten/bits/alltypes.h +++ b/system/lib/libc/musl/arch/emscripten/bits/alltypes.h @@ -78,12 +78,12 @@ typedef long double double_t; #endif #if defined(__NEED_time_t) && !defined(__DEFINED_time_t) -typedef int time_t; /* XXX EMSCRIPTEN: ensure it's always 32-bits even in wasm64 */ +typedef _Int64 time_t; #define __DEFINED_time_t #endif #if defined(__NEED_suseconds_t) && !defined(__DEFINED_suseconds_t) -typedef int suseconds_t; /* XXX EMSCRIPTEN: ensure it's always 32-bits even in wasm64 */ +typedef _Int64 suseconds_t; #define __DEFINED_suseconds_t #endif @@ -248,27 +248,27 @@ typedef unsigned _Int64 ino_t; #endif #if defined(__NEED_dev_t) && !defined(__DEFINED_dev_t) -typedef unsigned int dev_t; +typedef unsigned _Int64 dev_t; #define __DEFINED_dev_t #endif #if defined(__NEED_blksize_t) && !defined(__DEFINED_blksize_t) -typedef int blksize_t; /* XXX EMSCRIPTEN: ensure it's always 32-bits even in wasm64 */ -#define __DEFINED_blksize_t +typedef long blksize_t; +#define __DEF_Int64 #endif #if defined(__NEED_blkcnt_t) && !defined(__DEFINED_blkcnt_t) -typedef int blkcnt_t; +typedef _Int64 blkcnt_t; #define __DEFINED_blkcnt_t #endif #if defined(__NEED_fsblkcnt_t) && !defined(__DEFINED_fsblkcnt_t) -typedef unsigned int fsblkcnt_t; +typedef unsigned _Int64 fsblkcnt_t; #define __DEFINED_fsblkcnt_t #endif #if defined(__NEED_fsfilcnt_t) && !defined(__DEFINED_fsfilcnt_t) -typedef unsigned int fsfilcnt_t; +typedef unsigned _Int64 fsfilcnt_t; #define __DEFINED_fsfilcnt_t #endif diff --git a/system/lib/libc/musl/include/inttypes.h b/system/lib/libc/musl/include/inttypes.h index fd012b0f33964..90c35c8664ae8 100644 --- a/system/lib/libc/musl/include/inttypes.h +++ b/system/lib/libc/musl/include/inttypes.h @@ -22,14 +22,14 @@ uintmax_t strtoumax(const char *__restrict, char **__restrict, int); intmax_t wcstoimax(const wchar_t *__restrict, wchar_t **__restrict, int); uintmax_t wcstoumax(const wchar_t *__restrict, wchar_t **__restrict, int); -#if UINTPTR_MAX == UINT64_MAX -#define __PRI64 "l" -#define __PRIPTR "l" -#elif defined(__EMSCRIPTEN__) +#if defined(__EMSCRIPTEN__) // Under emscripten __PTRDIFF_TYPE__ and therefor intptr_t are defined to // be `long int` even on wasm32. #define __PRI64 "ll" #define __PRIPTR "l" +#elif UINTPTR_MAX == UINT64_MAX +#define __PRI64 "l" +#define __PRIPTR "l" #else #define __PRI64 "ll" #define __PRIPTR "" diff --git a/tests/core/test_statvfs.c b/tests/core/test_statvfs.c index 2de11485b03ff..f1cc925d4974a 100644 --- a/tests/core/test_statvfs.c +++ b/tests/core/test_statvfs.c @@ -7,6 +7,7 @@ #include #include +#include #include int main() { @@ -17,12 +18,12 @@ int main() { printf("f_bsize: %lu\n", s.f_bsize); printf("f_frsize: %lu\n", s.f_frsize); - printf("f_blocks: %u\n", s.f_blocks); - printf("f_bfree: %u\n", s.f_bfree); - printf("f_bavail: %u\n", s.f_bavail); + printf("f_blocks: %" PRId64 "\n", s.f_blocks); + printf("f_bfree: %" PRId64 "\n", s.f_bfree); + printf("f_bavail: %" PRId64 "\n", s.f_bavail); printf("f_files: %d\n", s.f_files > 5); - printf("f_ffree: %u\n", s.f_ffree); - printf("f_favail: %u\n", s.f_favail); + printf("f_ffree: %" PRId64 "\n", s.f_ffree); + printf("f_favail: %" PRId64 "\n", s.f_favail); printf("f_fsid: %lu\n", s.f_fsid); printf("f_flag: %lu\n", s.f_flag); printf("f_namemax: %lu\n", s.f_namemax); diff --git a/tests/utime/test_utime.c b/tests/utime/test_utime.c index ebc78c5dc6656..76c37e56953e1 100644 --- a/tests/utime/test_utime.c +++ b/tests/utime/test_utime.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -51,9 +52,9 @@ void test() { stat("writeable", &s); assert(s.st_atime == s.st_mtime); time_t diff = s.st_atime - now; - if (abs(diff) > 5) { - fprintf(stderr, "st_atime: %i, now: %i, diff: %i\n ", s.st_atime, now, diff); - assert(abs(diff) <= 5); + if (llabs(diff) > 5) { + fprintf(stderr, "st_atime: %" PRId64 ", now: %" PRId64 ", diff: %" PRId64 "\n ", s.st_atime, now, diff); + assert(llabs(diff) <= 5); } // write permissions aren't checked when setting node