Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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
Changes from all commits
645f2c0
File filter
Filter by extension
Conversations
Jump to
There are no files selected for viewing
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
orjerry_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.
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__USE_MISC
if_DEFAULT_SOURCE
is defined: https://sourceware.org/git/?p=glibc.git;a=blob;f=include/features.h;h=5bed0a499605a3a26d55443f3c8b7e67de152f74;hb=HEAD#l368So, 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 seetm_gmtoff
. Perhaps settingCMAKE_REQUIRED_DEFINITIONS
to_DEFAULT_SOURCE
beforeCHECK_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:(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 indefault-date.c
before each return statement. The one we hit is the one immediately beforereturn 0;
, so it's not even attempting to use thetm.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.
Hmm... looking at
CMakeCache.txt
after a clean build, maybe I'm wrong, and for some reason, when run as part of the larger project,tm.tm_gmtoff
isn't found.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 .
injerry-port/default
, myCMakeCache.txt
is generated withHAVE_TM_GMTOFF:INTERNAL=1
, but when run as part oftools/build.py
, the generatedCMakeCache.txt
(inbuild/tests/test262_tests/CMakeCache.txt
) hasHAVE_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.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 :).
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 thetm.tm_gmtoff
GNU extension implies the POSIX extension as well.Another approach could be to use
timegm(&tm) - t
instead oftm.tm_gmtoff
buttimegm
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 withtm.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 haslocaltime_s
[4], which seems to be the same aslocaltime_r
, but with a different name. However, it doesn't havetm_gmtoff
, so we couldn't support it this way anyway. Windows also doesn't supporttimegm
, and themkgmtime
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
ortm.tm_gmtoff
. And the ARM Compiler (version 6) does have a_localtime_r
but no info onstruct 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 haslocaltime_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 usingGetTimeZoneInformationForYear
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...)