Skip to content

Commit

Permalink
Restore time_t and other core types to 64bit
Browse files Browse the repository at this point in the history
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
  • Loading branch information
sbc100 committed Jul 8, 2022
1 parent 338aaf9 commit cd78df6
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 22 deletions.
2 changes: 2 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
-------------------
Expand Down
8 changes: 6 additions & 2 deletions system/lib/libc/emscripten_time.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
16 changes: 8 additions & 8 deletions system/lib/libc/musl/arch/emscripten/bits/alltypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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

Expand Down
8 changes: 4 additions & 4 deletions system/lib/libc/musl/include/inttypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 ""
Expand Down
11 changes: 6 additions & 5 deletions tests/core/test_statvfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include <stdio.h>
#include <errno.h>
#include <inttypes.h>
#include <sys/statvfs.h>

int main() {
Expand All @@ -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);
Expand Down
7 changes: 4 additions & 3 deletions tests/utime/test_utime.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include <assert.h>
#include <errno.h>
#include <inttypes.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit cd78df6

Please sign in to comment.