From d6cf6342394783d32530a8a026e26ebce709aec5 Mon Sep 17 00:00:00 2001 From: Akos Kiss Date: Wed, 9 May 2018 11:15:45 +0200 Subject: [PATCH] Refactor/fix/document the default port implementation (#2317) - Various constructs could be expressed with simpler and/or more readable code. - The jerry_port_log implementation for the debugger case was prone to buffer overflow error. - Some documentation was still missing (even from jerryscript-port.h). JerryScript-DCO-1.0-Signed-off-by: Akos Kiss akiss@inf.u-szeged.hu --- docs/05.PORT-API.md | 3 +++ jerry-core/include/jerryscript-port.h | 3 +++ jerry-port/default/default-date.c | 26 +++++++++++--------------- jerry-port/default/default-debugger.c | 27 +++++++++++++++------------ jerry-port/default/default-fatal.c | 12 ++++-------- jerry-port/default/default-io.c | 26 +++++++++++++++----------- 6 files changed, 51 insertions(+), 46 deletions(-) diff --git a/docs/05.PORT-API.md b/docs/05.PORT-API.md index 9a7cd82b4..ce07cd1d6 100644 --- a/docs/05.PORT-API.md +++ b/docs/05.PORT-API.md @@ -87,6 +87,7 @@ typedef struct * CONFIG_DISABLE_DATE_BUILTIN is _not_ defined. Otherwise this function is * not used. * + * @param[out] tz_p time zone structure to fill. * @return true - if success * false - otherwise */ @@ -134,6 +135,8 @@ struct jerry_instance_t *jerry_port_get_current_instance (void); * Note: * This port function is called by jerry-core when JERRY_DEBUGGER is * defined. Otherwise this function is not used. + * + * @param sleep_time milliseconds to sleep. */ void jerry_port_sleep (uint32_t sleep_time); ``` diff --git a/jerry-core/include/jerryscript-port.h b/jerry-core/include/jerryscript-port.h index 8fc8ba882..b90b71828 100644 --- a/jerry-core/include/jerryscript-port.h +++ b/jerry-core/include/jerryscript-port.h @@ -119,6 +119,7 @@ typedef struct * CONFIG_DISABLE_DATE_BUILTIN is _not_ defined. Otherwise this function is * not used. * + * @param[out] tz_p time zone structure to fill. * @return true - if success * false - otherwise */ @@ -156,6 +157,8 @@ struct jerry_instance_t *jerry_port_get_current_instance (void); * Note: * This port function is called by jerry-core when JERRY_DEBUGGER is * defined. Otherwise this function is not used. + * + * @param sleep_time milliseconds to sleep. */ void jerry_port_sleep (uint32_t sleep_time); diff --git a/jerry-port/default/default-date.c b/jerry-port/default/default-date.c index 0d5ebed59..837ef7d80 100644 --- a/jerry-port/default/default-date.c +++ b/jerry-port/default/default-date.c @@ -37,18 +37,16 @@ bool jerry_port_get_time_zone (jerry_time_zone_t *tz_p) /**< [out] time zone str tz.tz_minuteswest = 0; tz.tz_dsttime = 0; - if (gettimeofday (&tv, &tz) != 0) + if (gettimeofday (&tv, &tz) == 0) { - return false; + tz_p->offset = tz.tz_minuteswest; + tz_p->daylight_saving_time = tz.tz_dsttime > 0 ? 1 : 0; + + return true; } - - tz_p->offset = tz.tz_minuteswest; - tz_p->daylight_saving_time = tz.tz_dsttime > 0 ? 1 : 0; - - return true; -#else /* !__GNUC__ */ - return false; #endif /* __GNUC__ */ + + return false; } /* jerry_port_get_time_zone */ /** @@ -64,13 +62,11 @@ double jerry_port_get_current_time (void) #ifdef __GNUC__ struct timeval tv; - if (gettimeofday (&tv, NULL) != 0) + if (gettimeofday (&tv, NULL) == 0) { - return 0.0; + return ((double) tv.tv_sec) * 1000.0 + ((double) tv.tv_usec) / 1000.0; } - - return ((double) tv.tv_sec) * 1000.0 + ((double) tv.tv_usec) / 1000.0; -#else /* __!GNUC__ */ - return 0.0; #endif /* __GNUC__ */ + + return 0.0; } /* jerry_port_get_current_time */ diff --git a/jerry-port/default/default-debugger.c b/jerry-port/default/default-debugger.c index 9127a8c0a..e847469c4 100644 --- a/jerry-port/default/default-debugger.c +++ b/jerry-port/default/default-debugger.c @@ -13,27 +13,30 @@ * limitations under the License. */ -#include "jerryscript-port.h" -#include "jerryscript-port-default.h" - #ifdef HAVE_TIME_H #include #elif defined (HAVE_UNISTD_H) #include #endif /* HAVE_TIME_H */ -#ifdef JERRY_DEBUGGER -void jerry_port_sleep (uint32_t sleep_time) +#include "jerryscript-port.h" +#include "jerryscript-port-default.h" + +/** + * Default implementation of jerry_port_sleep. Uses 'nanosleep' or 'usleep' if + * available on the system, does nothing otherwise. + */ +void jerry_port_sleep (uint32_t sleep_time) /**< milliseconds to sleep */ { #ifdef HAVE_TIME_H - nanosleep (&(const struct timespec) - { - (time_t) sleep_time / 1000, ((long int) sleep_time % 1000) * 1000000L /* Seconds, nanoseconds */ - } - , NULL); + struct timespec sleep_timespec; + sleep_timespec.tv_sec = (time_t) sleep_time / 1000; + sleep_timespec.tv_nsec = ((long int) sleep_time % 1000) * 1000000L; + + nanosleep (&sleep_timespec, NULL); #elif defined (HAVE_UNISTD_H) usleep ((useconds_t) sleep_time * 1000); -#endif /* HAVE_TIME_H */ +#else (void) sleep_time; +#endif /* HAVE_TIME_H */ } /* jerry_port_sleep */ -#endif /* JERRY_DEBUGGER */ diff --git a/jerry-port/default/default-fatal.c b/jerry-port/default/default-fatal.c index 3577c3876..8fab74110 100644 --- a/jerry-port/default/default-fatal.c +++ b/jerry-port/default/default-fatal.c @@ -61,20 +61,16 @@ bool jerry_port_default_is_abort_on_fail (void) * The "abort-on-fail" behaviour is only available if the port * implementation library is compiled without the DISABLE_EXTRA_API macro. */ -void jerry_port_fatal (jerry_fatal_code_t code) +void jerry_port_fatal (jerry_fatal_code_t code) /**< cause of error */ { #ifndef DISABLE_EXTRA_API if (code != 0 && code != ERR_OUT_OF_MEMORY - && jerry_port_default_is_abort_on_fail ()) + && abort_on_fail) { abort (); } - else - { -#endif /* !DISABLE_EXTRA_API */ - exit (code); -#ifndef DISABLE_EXTRA_API - } #endif /* !DISABLE_EXTRA_API */ + + exit (code); } /* jerry_port_fatal */ diff --git a/jerry-port/default/default-io.c b/jerry-port/default/default-io.c index 1e2f03225..6ded52c41 100644 --- a/jerry-port/default/default-io.c +++ b/jerry-port/default/default-io.c @@ -61,10 +61,12 @@ jerry_port_default_set_log_level (jerry_log_level_t level) /**< log level */ #endif /* !DISABLE_EXTRA_API */ /** - * Default implementation of jerry_port_log. Prints log message to a buffer - * then prints the buffer to the standard error with 'fprintf' if message - * level is less than or equal to the set log level. - * Additionally, sends the message to the debugger client. + * Default implementation of jerry_port_log. Prints log message to the standard + * error with 'vfprintf' if message log level is less than or equal to the + * current log level. + * + * If debugger support is enabled, printing happens first to an in-memory buffer, + * which is then sent both to the standard error and to the debugger client. * * Note: * Changing the log level from JERRY_LOG_LEVEL_ERROR is only possible if @@ -72,7 +74,7 @@ jerry_port_default_set_log_level (jerry_log_level_t level) /**< log level */ * DISABLE_EXTRA_API macro. */ void -jerry_port_log (jerry_log_level_t level, /**< log level */ +jerry_port_log (jerry_log_level_t level, /**< message log level */ const char *format, /**< format string */ ...) /**< parameters */ { @@ -81,13 +83,15 @@ jerry_port_log (jerry_log_level_t level, /**< log level */ va_list args; va_start (args, format); #ifdef JERRY_DEBUGGER - char buffer[256]; - int length = 0; - length = vsnprintf (buffer, 255, format, args); - buffer[length] = '\0'; + int length = vsnprintf (NULL, 0, format, args); + va_end (args); + va_start (args, format); + + char buffer[length + 1]; + vsnprintf (buffer, (size_t) length + 1, format, args); + fprintf (stderr, "%s", buffer); - jerry_char_t *jbuffer = (jerry_char_t *) buffer; - jerry_debugger_send_output (jbuffer, (jerry_size_t) length, (uint8_t) (level + 2)); + jerry_debugger_send_output ((jerry_char_t *) buffer, (jerry_size_t) length, (uint8_t) (level + 2)); #else /* If jerry-debugger isn't defined, libc is turned on */ vfprintf (stderr, format, args); #endif /* JERRY_DEBUGGER */