-
Notifications
You must be signed in to change notification settings - Fork 673
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
Change jerry_port interface to allow for a correct implementation of timezones. #2540
Change jerry_port interface to allow for a correct implementation of timezones. #2540
Conversation
b0821b5
to
76236da
Compare
Can one of the maintainers take a look? Maybe @zherczeg? |
I don't know much about times but the patch looks reasonable. Does somebody knows more about time zones here? |
@crazy2be Sorry for the late response. I'll take a look on this patch later this week. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Those tests do pass for me, but it took some doing. Initially, they did not pass, and after investigating a bit, they always appeared to be off by 3 hours. After quite some digging, I discovered this is because the author lives in California, and the version of the tests we run assumes the California timezone. This was fixed in [1], but the
Given this caveat, do we still want these tests enabled by default? Or should I just change the TODO? Ideally, it seems like [1] should be cherry-picked onto the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First, mostly stylistic observations. More to follow.
jerry-port/default/default-date.c
Outdated
@@ -21,33 +24,32 @@ | |||
#include "jerryscript-port-default.h" | |||
|
|||
/** | |||
* Default implementation of jerry_port_get_time_zone. Uses 'gettimeofday' if | |||
* available on the system, does nothing otherwise. | |||
* Default implementation of jerry_port_get_local_tza. Uses the `tm_gmtoff` field |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Current documentation style doesn't use backticks (i.e., markdownish syntax) in doc comments but single quotes. It's not necessarily the best approach but at least it's consistent. (At least, I hope.) Please follow the style found throughout the code base.
jerry-port/default/default-date.c
Outdated
* @return true - if 'gettimeofday' is available and executed successfully, | ||
* false - otherwise. | ||
* @return offset between utc and localtime at the given unix timestamp, if | ||
* available. 0 otherwise. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd suggest "UTC", "local time", and "available, 0 otherwise."
jerry-port/default/default-date.c
Outdated
if (gettimeofday (&tv, &tz) == 0) | ||
#ifdef HAVE_TM_GMTOFF | ||
struct tm tm; | ||
time_t now = (time_t)(unix_ms / 1000); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure why our code style checker did not catch this but there should be a space after the type cast (i.e., (time_t) (unix_ms ...
)
* @param[out] tz_p time zone structure to fill. | ||
* @return true - if success | ||
* false - otherwise | ||
* @return milliseconds between local time and utc for the given timestamp. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The documentation in a public header, like this one, should be complete, i.e., the params must be documented.
Suggestion: "UTC".
* Get local timezone adjustment, in milliseconds. This value, added to a timestamp in UTC | ||
* time, should yield local time. Ideally, this function should satisfy the stipulations | ||
* applied to LocalTZA in section 20.3.1.7 of ecmascript version 9.0 [1]. | ||
* [1] https://www.ecma-international.org/ecma-262/9.0/#sec-local-time-zone-adjustment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIRC, the code base doesn't use url references to external documents, it just mentions the standard name, the version, and the section. Like:
* See also:
* ECMA-262 v5, 15.9.1.9
(Taken from another code block, needs to be adapted.)
36b71f4
to
b81a97f
Compare
re: the time zone issue during test262#es5-tests testing |
I've tried to address the test262 time zone issue in #2551 . |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some more comments.
#ifdef HAVE_TM_GMTOFF | ||
struct tm tm; | ||
time_t now = (time_t) (js_time_ms / 1000); | ||
localtime_r (&now, &tm); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A little bit of thinking aloud: localtime_r
is not C99 but an extension defined by the POSIX standard. Which means that this code will not necessarily compile on all targets. Unless the existence of the tm.tm_gmtoff
GNU extension implies the POSIX extension as well.
Another approach could be to use timegm(&tm) - t
instead of tm.tm_gmtoff
but timegm
is also a GNU/BSD extension. (Which could be emulated if not present on the system, but I'm not sure it would be worth the effort.)
So, it seems to me that we need to rely on at least two extensions to get this work. I'm not sure yet which way to go. (That's why I was thinking aloud. I'm open to inputs.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
localtime_r
seems ubiquitous, even on embedded systems. I find it hard to imagine a system without it but with tm.tm_gmtoff
. tm.tm_gmtoff
is not specified in any standard, but appears to exist as a GNU extension on linux (as you said) [0], and also in FreeBSD [1], OpenBSD [2], and OSX [3]. Windows has localtime_s
[4], which seems to be the same as localtime_r
, but with a different name. However, it doesn't have tm_gmtoff
, so we couldn't support it this way anyway. Windows also doesn't support timegm
, and the mkgmtime
it supports doesn't support dates prior to 1970 [5], so you are likely going to need some non-standard solution there anyway (v8 resorts to calling WIN32API functions on windows).
[0] https://linux.die.net/man/3/localtime_r
[1] https://www.freebsd.org/cgi/man.cgi?query=localtime_r
[2] https://man.openbsd.org/ctime.3
[3] https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/localtime_r.3.html
[4] https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/localtime-s-localtime32-s-localtime64-s?view=vs-2017
[5] https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/mkgmtime-mkgmtime32-mkgmtime64?view=vs-2017
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please note that we are targeting embedded systems way below the embedded-Linux world as well. And there, it is easy to find missing bits and pieces. E.g., it's a bit hard to dig for info, but it's probable that neither TI's MSP430 C compiler nor the IAR Embedded Workbench have support for localtime_r
or tm.tm_gmtoff
. And the ARM Compiler (version 6) does have a _localtime_r
but no info on struct tm
.
That being said, the platforms these compilers compile for will most probably have their own implementation for all/most jerry port functions instead of these default implementations.
Still, it's good to keep those ideals (i.e., C99 conformance) in mind that drive the project. For the core engine library, we must be strict, I think. For libraries around it, we might be less strict, provided that the extensions are properly guarded. Here that seems to be the case.
Anyway, I'd like to hear the opinion of other reviewers. I summon @zherczeg @LaszloLango
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My point was mainly that if a given platform has tm.tm_gmtoff
then it most probably has localtime_r
as well. But maybe there is a better way that has support on more platforms, I'm open to suggestions. We can always change / improve this later, however.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I understand correctly this is the default implementation. Low-end targets must have their own implementation (or return 0 if not supported).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Btw what about windows? Does gcc on windows support this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct, this is the default implementation. Most embedded targets won't even use this, or they will just use the return 0;
default implementation, which should have the same "assume UTC" behaviour that they always had.
Windows does not support tm.tm_gmtoff
. It's also not supported by mingw. However, it's fairly straightforward to shim it by using GetTimeZoneInformationForYear
if someone wants to do this at some point. I'd rather not do it in this PR, as it's already gotten quite big (and it's a PITA for me to test on windows...)
jerry-port/default/default-date.c
Outdated
*/ | ||
bool jerry_port_get_time_zone (jerry_time_zone_t *tz_p) /**< [out] time zone structure to fill */ | ||
double jerry_port_get_local_tza (double js_time_ms, /**< ms since unix epoch */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure about the js_
prefix for this param. It's time in millisecs, which is quite well expressed by time_ms
. There is not much JS-specific in that concept.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd only done this because it was a double
, but I agree, I think unix_ms
is probably a better name. (or do you prefer time_ms
? Both seem better than js_time_ms
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unix_ms
is fine by me
* Get timezone and daylight saving data | ||
* Get local timezone adjustment, in milliseconds. This value, added to a timestamp in UTC | ||
* time, should yield local time. Ideally, this function should satisfy the stipulations | ||
* applied to LocalTZA in section 20.3.1.7 of ecmascript version 9.0. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Timezone might better be time zone, but I'm not completely sure, even the spec uses timezone at least once (although it uses time zone more often). About ECMAScript instead of ecmascript, I'm positive.
And I also think that the documentation of all other port functions are kept in sync in the docs/05.PORT-API.md and in jerry-core/include/jerryscript-port.h. This should also happen here. Perhaps the two texts should be merged into a single description and used at both places. (Especially as the current text here is a little bit vague about the case when is_utc == false
.)
* CONFIG_DISABLE_DATE_BUILTIN is _not_ defined. Otherwise this function is | ||
* not used. | ||
* CONFIG_DISABLE_DATE_BUILTIN is _not_ defined. Otherwise this function | ||
* is not used. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpicking: moving the "is" back to the end of the previous line would give a bit less churn.
*/ | ||
return tz->daylight_saving_time * ECMA_DATE_MS_PER_HOUR; | ||
} /* ecma_date_daylight_saving_ta */ | ||
|
||
/** | ||
* Helper function to get local time from UTC. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment of this function (ecma_date_local_time_zone
) became (was?) misleading. Especially when considered together with the other changed function, ecma_date_utc
. That latter one is documented as "get utc from local time" which is aligned to the code, but this current one has an inverse doc ("get local time from UTC") although it does not implement the inverse operation. Could be updated in this patch.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I noticed that, but I wasn't sure if you guys would want it fixed. I renamed it to ecma_date_local_time_zone_adjustment
and updated the docs as well.
96fa494
to
69726da
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test262 runner has been changed too much.
done | ||
(>&2 echo) | ||
(>&2 echo) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now, this is something that I'd like to see in a different PR. This is a feature/improvement that has nothing to do with the goals of this current PR. This change could work no matter what port API is in place.
|
||
echo "Starting test262 testing for ${ENGINE}. Running test262 may take a several minutes." | ||
function progress_monitor() { | ||
NUM_LINES_EXPECTED=11558 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is too hard-wired. How did you get this number? Why can't it be computed here by this script? (BTW, summary prints me 11552 executed tests.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is number of lines, not number of tests, so it is slightly more than the number of tests. Previously it just ran for several minutes without giving any feedback, slightly wrong feedback (like if the test suite changes) seems a lot better than no feedback to me. I think the right place to put this is probably down a level in test262.py
, but that is a considerably more involved change that I'm not about to attempt.
I suppose you could always just print number of tests executed, and not the percentage... at least then you can see that it's progressing. It still seems worse than giving the percentage, even if it's slightly off, but maybe it's an approach that will age better.
(>&2 echo) | ||
while read line; do | ||
FRAC=$((NUM_LINES_GOTTEN * 100 / NUM_LINES_EXPECTED)) | ||
(>&2 echo -ne "\rEstimated ${FRAC}% complete (${NUM_LINES_GOTTEN}/${NUM_LINES_EXPECTED})...") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will print 10k lines. On a live console, that's no problem as lines end in CR only without LF. However, it still blows up logs if output is redirected (see Travis CI raw logs). Printing progress (the same way, with CRs) only when the percentage increases, that would be the proper solution.
|
||
/** | ||
* Helper function to get utc from local time. | ||
* Helper function to get utc time from local time. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion: UTC
*/ | ||
bool jerry_port_get_time_zone (jerry_time_zone_t *tz_p); | ||
double jerry_port_get_local_time_zone_adjustment (double unix_ms, bool is_utc); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question to other reviewers (again, ping @zherczeg @LaszloLango ): do we want this long identifiers / port API identifiers? jerry_port_get_local_time_zone_adjustment
or jerry_port_get_local_tza
or ...?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer full words, so I like the current one.
docs/05.PORT-API.md
Outdated
*/ | ||
bool jerry_port_get_time_zone (jerry_time_zone_t *tz_p) | ||
double jerry_port_get_local_time_zone_adjustment (double unix_ms, /**< ms since unix epoch */ | ||
bool is_utc) /**< is the time above in utc? */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion: UTC
Now that #2551 has landed, it might be worth rebasing this PR onto latest master. |
2c97ff7
to
a90db7b
Compare
I think I addressed all the outstanding concerns, can you guys take another look? |
Just looked into the build failures - they seem to be due to my CMake changes not having the desired effect (on Ubuntu, the target is getting built as though there is no |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The change makes sense but I have some questions.
docs/05.PORT-API.md
Outdated
* The timestamp can be specified in either UTC or local time, depending on | ||
* the value of is_utc. Adding the value returned from this function to | ||
* a timestamp in UTC time should result in local time for the current time | ||
* zone. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about the reverse? Subtracting from local gives an utc?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct, assuming you specify the timestamp in local time (is_utc
is false). Should I make this explicit in the docs?
docs/05.PORT-API.md
Outdated
* false - otherwise | ||
* @param unix_ms The unix timestamp we want an offset for, given in | ||
* millisecond precision (could be now, in the future, | ||
* or in the past) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the base? 1970.01.01? How leap seconds are handled? Do they need to be handled?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct, the base is 1970.01.01. The given unix_ms
is assumed to be unix time - i.e. every day is exactly 86400 seconds, leap seconds cause the same second to occur twice. This seems to be the same set of assumptions made by the date object according to MDN [1]
The JavaScript date is based on a time value that is milliseconds since midnight January 1, 1970, UTC. A day holds 86,400,000 milliseconds. The JavaScript Date object range is -100,000,000 days to 100,000,000 days relative to January 1, 1970 UTC.
This API only cares about handling them correctly to the extent that it allows it to most correctly determine if dst is in effect, other than that, they should not affect the returned local_time_zone_adjustment
, since leap seconds occur at the same time around the world, regardless of local timezone.
[1] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
*/ | ||
bool jerry_port_get_time_zone (jerry_time_zone_t *tz_p); | ||
double jerry_port_get_local_time_zone_adjustment (double unix_ms, bool is_utc); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer full words, so I like the current one.
CHECK_STRUCT_HAS_MEMBER ("struct tm" tm_gmtoff time.h HAVE_TM_GMTOFF) | ||
if(HAVE_TM_GMTOFF) | ||
set(DEFINES_PORT_DEFAULT ${DEFINES_PORT_DEFAULT} HAVE_TM_GMTOFF) | ||
endif() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this only affects the default implementation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct. It also doesn't seem to work, and I haven't been able to figure out why yet. My cmake-fu is not great.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't investigated all the details of the problem but my guess is that the root of the problem is that tm_gmtoff
is non-standard. See, for example, in glibc:
tm_gmtoff
is only declared if__USE_MISC
is defined: https://sourceware.org/git/?p=glibc.git;a=blob;f=time/bits/types/struct_tm.h;h=b13b631228d0ec36691b25db2e1f9b1d66b54bb0;hb=HEAD#l19- and it only defines
__USE_MISC
if_DEFAULT_SOURCE
is defined: https://sourceware.org/git/?p=glibc.git;a=blob;f=include/features.h;h=5bed0a499605a3a26d55443f3c8b7e67de152f74;hb=HEAD#l368 - but when a compiler is instructed to compile in strict C99 mode then it will not pass extra macros to the preprocessor and thus will not "enable" such non-standard libc parts.
So, if CHECK_STRUCT_HAS_MEMBER
calls the compiler with default settings, i.e., with no extra defines, then the compilation during the check will not see tm_gmtoff
. Perhaps setting CMAKE_REQUIRED_DEFINITIONS
to _DEFAULT_SOURCE
before CHECK_STRUCT_HAS_MEMBER
may solve the problem (see: https://cmake.org/cmake/help/v3.0/module/CheckStructHasMember.html). But even if this works, it may be glibc-specific.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is something to do with my defines not getting passed. If I put a message() inside the if, it gets printed (at least, if I run (cd jerry-port/default && cmake .)
). And compiling outside of cmake or any build system compiles fine without errors:
#include <stdio.h>
#include <time.h>
#include <stdbool.h>
double jerry_port_get_local_time_zone_adjustment (double unix_ms, /**< ms since unix epoch */
bool is_utc) /**< is the time above in UTC? */
{
struct tm tm;
time_t now = (time_t) (unix_ms / 1000);
localtime_r (&now, &tm);
if (!is_utc)
{
now -= tm.tm_gmtoff;
localtime_r (&now, &tm);
}
return ((double) tm.tm_gmtoff) * 1000;
} /* jerry_port_get_local_time_zone_adjustment */
int main() {
double adj = jerry_port_get_local_time_zone_adjustment(0, 0);
printf("%lf\n", adj);
}
(the above compiles without any warnings or errors with just gcc test_gmtoff.c
)
I verified that it isn't trying to use tm.tm_gmtoff
(and getting, say, bogus values) by putting a printf in default-date.c
before each return statement. The one we hit is the one immediately before return 0;
, so it's not even attempting to use the tm.tm_gmtoff
path.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Confirmed that when running cmake .
in jerry-port/default
, my CMakeCache.txt
is generated with HAVE_TM_GMTOFF:INTERNAL=1
, but when run as part of tools/build.py
, the generated CMakeCache.txt
(in build/tests/test262_tests/CMakeCache.txt
) has HAVE_TM_GMTOFF:INTERNAL=
, as above.
Looking at the two different CMakeCache.txt
files, no glaring differences in build configuration stick out at me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I see now what you were saying. I didn't realize jerryscript compiled in strict c99 mode (which, as you said, makes tm.tm_gmtoff
invisible). gcc -std=c99 test_gmtoff.c
does indeed fail as you predicted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Huh, so the default source code that check_struct_has_member
uses to check if the given struct has the given member actually fails to compile with the default jerryscript compiler options... Ugh.
Performing C SOURCE FILE Test HAVE_TM_GMTOFF failed with the following output:
Change Dir: /home/fbuser/src/jerryscript/build/tests/test262_tests/CMakeFiles/CMakeTmp
Run Build Command:"/usr/bin/make" "cmTC_a80df/fast"
/usr/bin/make -f CMakeFiles/cmTC_a80df.dir/build.make CMakeFiles/cmTC_a80df.dir/build
make[1]: Entering directory '/home/fbuser/src/jerryscript/build/tests/test262_tests/CMakeFiles/CMakeTmp'
Building C object CMakeFiles/cmTC_a80df.dir/src.c.o
/usr/bin/cc -D_DEFAULT_SOURCE -flto -fno-fat-lto-objects -std=c99 -pedantic -fno-builtin -fno-stack-protector -Wall -Werror=all -Wextra -Werror=extra -Wformat-nonliteral -Werror=format-nonliteral -Winit-self -Werror=init-self -Wconversion -Werror=conversion -Wsign-conversion -Werror=sign-conversion -Wformat-security -Werror=format-security -Wmissing-declarations -Werror=missing-declarations -Wshadow -Werror=shadow -Wstrict-prototypes -Werror=strict-prototypes -Wundef -Werror=undef -Wold-style-definition -Werror=old-style-definition -Wno-stack-protector -Wno-attributes -Werror -Wlogical-op -Werror=logical-op -DHAVE_TM_GMTOFF -o CMakeFiles/cmTC_a80df.dir/src.c.o -c /home/fbuser/src/jerryscript/build/tests/test262_tests/CMakeFiles/CMakeTmp/src.c
/home/fbuser/src/jerryscript/build/tests/test262_tests/CMakeFiles/CMakeTmp/src.c:4:5: error: function declaration isn’t a prototype [-Werror=strict-prototypes]
int main()
^
/home/fbuser/src/jerryscript/build/tests/test262_tests/CMakeFiles/CMakeTmp/src.c: In function ‘main’:
/home/fbuser/src/jerryscript/build/tests/test262_tests/CMakeFiles/CMakeTmp/src.c:4:5: error: old-style function definition [-Werror=old-style-definition]
cc1: all warnings being treated as errors
CMakeFiles/cmTC_a80df.dir/build.make:65: recipe for target 'CMakeFiles/cmTC_a80df.dir/src.c.o' failed
make[1]: *** [CMakeFiles/cmTC_a80df.dir/src.c.o] Error 1
make[1]: Leaving directory '/home/fbuser/src/jerryscript/build/tests/test262_tests/CMakeFiles/CMakeTmp'
Makefile:126: recipe for target 'cmTC_a80df/fast' failed
make: *** [cmTC_a80df/fast] Error 2
Source file was:
#include <time.h>
int main()
{
(void)sizeof(((struct tm *)0)->tm_gmtoff);
return 0;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Finally got it all to build. On the plus side, I'm a lot more familiar with cmake now :).
#ifdef HAVE_TM_GMTOFF | ||
struct tm tm; | ||
time_t now = (time_t) (js_time_ms / 1000); | ||
localtime_r (&now, &tm); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I understand correctly this is the default implementation. Low-end targets must have their own implementation (or return 0 if not supported).
a90db7b
to
09d6e76
Compare
I think I addressed all the outstanding concerns, and the build passes now. Can you take another look? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm almost OK with the PR
01da250
to
49defba
Compare
@rerobika: Those tests have been enabled, and pass. The travis-ci build seems to have hung on the signed-off-by check, I re-triggered it which should make the build go green. Everything else is passing. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Getting close, just a few minor things.
jerry-port/default/default-date.c
Outdated
@@ -13,6 +13,9 @@ | |||
* limitations under the License. | |||
*/ | |||
|
|||
#ifdef HAVE_TM_GMTOFF | |||
#include <time.h> | |||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a closing comment for #endif
.
#endif /* HAVE_TM_GMTOFF */
jerry-port/default/default-date.c
Outdated
@@ -13,6 +13,9 @@ | |||
* limitations under the License. | |||
*/ | |||
|
|||
#ifdef HAVE_TM_GMTOFF | |||
#include <time.h> | |||
#endif | |||
#ifdef __GNUC__ | |||
#include <sys/time.h> | |||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This patch does not affect this code path, but I would be great to unify the closing #endif
comments as well.
jerry-port/default/default-date.c
Outdated
return false; | ||
} /* jerry_port_get_time_zone */ | ||
return ((double) tm.tm_gmtoff) * 1000; | ||
#else |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a comment here as well.
#else /* !HAVE_TM_GMTOFF */
//assert (d.getMinutes() == 1); | ||
//assert (d.getSeconds() == 1); | ||
//assert (d.getMilliseconds() == 1); | ||
d.setTime(0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are several FIXME:
s in date-getters.js as well due to the timezone adjustment. Could you check them please?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, and they pass (with some changes, the original tests were slightly incorrect).
…timezones. The previous jerry_port interface did not allow timezones to be handled correctly, even if the host system was up to the task. This PR changes the jerry_port interface to allow a completely correct implementation to exist, and provides one (for Linux/BSD systems) in default-date.c. Fixes jerryscript-project#1661 JerryScript-DCO-1.0-Signed-off-by: crazy2be [email protected]
49defba
to
645f2c0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM (informal)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. thanks for seeing it through.
The previous jerry_port interface did not allow timezones to be handled correctly,
even if the host system was up to the task. This PR changes the jerry_port interface
to allow a completely correct implementation to exist, and provides one (for Linux/BSD
systems) in default-date.c.
There is some additional background in my comment on the original issue #1661 (comment), but essentially, this solution resolves the original ticket by allowing the jerry_port interface to from the time-invariant
to the time-dependent
As dst state and timezone rules in general change over time, it's necessary to give the time as an argument to correctly determine the local time offset at that time.
This interface also allows the platform to figure out the local time adjustment for a given date in whichever way it pleases. On most Linux / BSD systems, the
tm_gmtoff
field ofstruct tm
can be used. On windows,GetTimeZoneInformationForYear
can be used. On most embedded platforms, UTC can always be assumed, or some other local timezone.The alternative is to have jerryscript link in some external timezone library, with all of the logic for handling timezones. However, I can't see any big advantage to this approach, and the libraries are often quite large. Most systems that run JerryScript simply don't need the complexity (they can just run UTC), and the ones that do need the complexity probably already have some other system which will be fairly easy to just link into the provided jerry_port interface (Linux and Windows are both quite easy, about 10 lines, to hook into this interface).
Fixes #1661
JerryScript-DCO-1.0-Signed-off-by: crazy2be [email protected]