Skip to content

Commit 0786a77

Browse files
authored
Fix gmtime etc in STANDALONE_WASM mode (#22316)
This was broken in #21379. Replaces: #22276
1 parent 9b80ef1 commit 0786a77

File tree

6 files changed

+32
-21
lines changed

6 files changed

+32
-21
lines changed

src/library.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -446,15 +446,14 @@ addToLibrary({
446446

447447
#endif
448448

449+
#if !STANDALONE_WASM
449450
// ==========================================================================
450451
// assert.h
451452
// ==========================================================================
452453

453-
#if !STANDALONE_WASM
454454
__assert_fail: (condition, filename, line, func) => {
455455
abort(`Assertion failed: ${UTF8ToString(condition)}, at: ` + [filename ? UTF8ToString(filename) : 'unknown filename', line, func ? UTF8ToString(func) : 'unknown function']);
456456
},
457-
#endif
458457

459458
// ==========================================================================
460459
// time.h
@@ -595,6 +594,7 @@ addToLibrary({
595594
stringToUTF8(s, buf, 26);
596595
return buf;
597596
},
597+
#endif
598598

599599
#if STACK_OVERFLOW_CHECK >= 2
600600
// Set stack limits used by binaryen's `StackCheck` pass.
@@ -626,6 +626,7 @@ addToLibrary({
626626
return ret;
627627
},
628628

629+
#if !STANDALONE_WASM
629630
_tzset_js__deps: ['$stringToUTF8',
630631
#if ASSERTIONS
631632
'$lengthBytesUTF8',
@@ -686,6 +687,7 @@ addToLibrary({
686687
stringToUTF8(summerName, std_name, {{{ cDefs.TZNAME_MAX + 1 }}});
687688
}
688689
},
690+
#endif
689691

690692
$MONTH_DAYS_REGULAR: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
691693
$MONTH_DAYS_LEAP: [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],

system/lib/libc/musl/src/time/__tz.c

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,37 +15,45 @@
1515
#include "emscripten_internal.h"
1616
#endif
1717

18+
#if defined(__EMSCRIPTEN__) && !defined(EMSCRIPTEN_STANDALONE_WASM)
19+
#define USE_EXTERNAL_ZONEINFO
20+
#endif
21+
1822
#define malloc __libc_malloc
1923
#define calloc undef
2024
#define realloc undef
2125
#define free undef
2226

23-
long __timezone = 0;
24-
int __daylight = 0;
25-
char *__tzname[2] = { 0, 0 };
27+
weak long __timezone = 0;
28+
weak int __daylight = 0;
29+
weak char *__tzname[2] = { 0, 0 };
2630

2731
weak_alias(__timezone, timezone);
2832
weak_alias(__daylight, daylight);
2933
weak_alias(__tzname, tzname);
3034

3135
static char std_name[TZNAME_MAX+1];
3236
static char dst_name[TZNAME_MAX+1];
33-
const char __utc[] = "UTC";
37+
weak const char __utc[] = "UTC";
3438

3539
static int dst_off;
3640
static int r0[5], r1[5];
3741

42+
#ifndef USE_EXTERNAL_ZONEINFO
3843
static const unsigned char *zi, *trans, *index, *types, *abbrevs, *abbrevs_end;
3944
static size_t map_size;
45+
#endif
4046

4147
static char old_tz_buf[32];
4248
static char *old_tz = old_tz_buf;
4349
static size_t old_tz_size = sizeof old_tz_buf;
4450

4551
static volatile int lock[1];
52+
#ifndef __EMSCRIPTEN__
4653
volatile int *const __timezone_lockptr = lock;
54+
#endif
4755

48-
#ifndef __EMSCRIPTEN__
56+
#ifndef USE_EXTERNAL_ZONEINFO
4957
static int getint(const char **p)
5058
{
5159
unsigned x;
@@ -133,7 +141,7 @@ static size_t zi_dotprod(const unsigned char *z, const unsigned char *v, size_t
133141

134142
static void do_tzset()
135143
{
136-
#ifdef __EMSCRIPTEN__
144+
#ifdef USE_EXTERNAL_ZONEINFO
137145
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
138146
static _Atomic bool done_init = false;
139147
if (!done_init) {
@@ -280,7 +288,7 @@ static void do_tzset()
280288
#endif
281289
}
282290

283-
#ifndef __EMSCRIPTEN__
291+
#ifndef USE_EXTERNAL_ZONEINFO
284292
/* Search zoneinfo rules to find the one that applies to the given time,
285293
* and determine alternate opposite-DST-status rule that may be needed. */
286294

@@ -451,14 +459,16 @@ static void __tzset()
451459

452460
weak_alias(__tzset, tzset);
453461

454-
const char *__tm_to_tzname(const struct tm *tm)
462+
weak const char *__tm_to_tzname(const struct tm *tm)
455463
{
456464
const void *p = tm->__tm_zone;
457465
LOCK(lock);
458466
do_tzset();
467+
#ifndef USE_EXTERNAL_ZONEINFO
459468
if (p != __utc && p != __tzname[0] && p != __tzname[1] &&
460469
(!zi || (uintptr_t)p-(uintptr_t)abbrevs >= abbrevs_end - abbrevs))
461470
p = "";
471+
#endif
462472
UNLOCK(lock);
463473
return p;
464474
}

test/core/test_time.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,10 @@ void check_gmtime_localtime(time_t time) {
2626

2727
// gmtime and localtime are only equal when timezone is UTC
2828
if ((timezone == 0) && (strcmp(gmbuf, locbuf) != 0)) {
29-
printf("time: %lld, gmtime: %s != localtime: %s\n", time, gmbuf, locbuf);
29+
printf("time: %lld, gmtime: %s != localtime: %s\n", (long long)time, gmbuf, locbuf);
3030
puts("failed");
3131
} else {
32-
printf("time: %lld, gmtime: %s\n", time, gmbuf);
32+
printf("time: %lld, gmtime: %s\n", (long long)time, gmbuf);
3333
}
3434
}
3535

@@ -38,13 +38,14 @@ int main() {
3838
time_t summer2002 = 1025528525ll;
3939
struct tm* tm_ptr;
4040

41+
#ifdef __EMSCRIPTEN__
4142
// Make sure stime() always fails.
4243
printf("stime: %d\n", stime(&xmas2002));
44+
#endif
4345

4446
// Verify that tzname sets *something*.
4547
tzset();
4648
printf("tzname[0] set: %d\n", strlen(tzname[0]) >= 3);
47-
printf("tzname[1] set: %d\n", strlen(tzname[1]) >= 3);
4849

4950
// Verify gmtime() creates correct struct.
5051
tm_ptr = gmtime(&xmas2002);
@@ -58,7 +59,8 @@ int main() {
5859
printf("yday: %d\n", tm_ptr->tm_yday);
5960
printf("dst: %d\n", tm_ptr->tm_isdst);
6061
printf("off: %ld\n", (long)tm_ptr->tm_gmtoff);
61-
printf("zone: %s\n", tm_ptr->tm_zone);
62+
// glibc used "GMT" there whereas musl uses "UTC"
63+
assert(strcmp(tm_ptr->tm_zone, "GMT") || strcmp(tm_ptr->tm_zone, "UTC"));
6264

6365
// Verify timegm() reverses gmtime; run through an entire year in half hours.
6466
int timegmOk = 1;
@@ -89,7 +91,7 @@ int main() {
8991
printf("localtime found DST data (summer): %s\n", tm_summer.tm_isdst < 0 ? "no" : "yes");
9092
printf("localtime found DST data (winter): %s\n", tm_winter.tm_isdst < 0 ? "no" : "yes");
9193
int localeHasDst = tm_winter.tm_isdst == 1 || tm_summer.tm_isdst == 1; // DST is in December in south
92-
printf("localtime matches daylight: %s\n", localeHasDst == _daylight ? "yes" : "no");
94+
printf("localtime matches daylight: %s\n", localeHasDst == daylight ? "yes" : "no");
9395
int goodGmtOff = (tm_winter.tm_gmtoff != tm_summer.tm_gmtoff) == localeHasDst;
9496
printf("localtime gmtoff matches DST: %s\n", goodGmtOff ? "yes" : "no");
9597
printf("localtime tm_zone matches tzname (winter): %s\n",
@@ -169,9 +171,7 @@ int main() {
169171
struct tm tm_big = {0};
170172
tm_big.tm_year = 292278994;
171173
time_t tbig = mktime(&tm_big);
172-
printf("tbig: %lld\n", tbig);
173-
assert(tbig == -1);
174-
assert(errno == EOVERFLOW);
174+
assert((tbig == -1 && errno == EOVERFLOW) || tbig == 9223431975273600);
175175

176176
// Verify localtime_r() doesn't clobber static data.
177177
time_t t3 = 60*60*24*5; // Jan 5 1970

test/core/test_time.out

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
stime: -1
22
tzname[0] set: 1
3-
tzname[1] set: 1
43
sec: 43
54
min: 22
65
hour: 3
@@ -11,7 +10,6 @@ wday: 3
1110
yday: 358
1211
dst: 0
1312
off: 0
14-
zone: GMT
1513
timegm <-> gmtime: 1
1614
old year still: 102
1715
new year: 70
@@ -27,7 +25,6 @@ mktime updates parameter to be in range: 1
2725
mktime parameter is equivalent to localtime return: 1
2826
mktime guesses DST (winter): 1
2927
mktime guesses DST (summer): 1
30-
tbig: -1
3128
old year still: 102
3229
new year: 70
3330
time: 1

test/test_core.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2668,6 +2668,7 @@ def test_pthread_run_on_main_thread(self):
26682668
def test_tcgetattr(self):
26692669
self.do_runf('termios/test_tcgetattr.c', 'success')
26702670

2671+
@also_with_standalone_wasm()
26712672
def test_time(self):
26722673
self.do_core_test('test_time.c')
26732674
for tz in ['EST+05EDT', 'UTC+0', 'CET']:

tools/system_libs.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2197,6 +2197,7 @@ def get_files(self):
21972197
files += files_in_path(
21982198
path='system/lib/libc/musl/src/time',
21992199
filenames=['__secs_to_tm.c',
2200+
'__tz.c',
22002201
'clock.c',
22012202
'clock_gettime.c',
22022203
'gettimeofday.c',

0 commit comments

Comments
 (0)