From ff185dc57e5c217cb83b1231049c37000e5f90c6 Mon Sep 17 00:00:00 2001 From: Akos Kiss Date: Wed, 13 Apr 2016 21:24:53 +0200 Subject: [PATCH] Turn assert functionality standard-conforming in jerry-libc Introducing the `assert.h` public header with the `assert(x)` macro and already making use of it in jerry-libc sources. These newly introduced ISO C-conforming features replace the non-conforming `LIBC_ASSERT` and `LIBC_NDEBUG` at no cost, and they also have the benefit that we can expose `assert` in a public header and make it useful to jerry-libc users. JerryScript-DCO-1.0-Signed-off-by: Akos Kiss akiss@inf.u-szeged.hu --- jerry-libc/CMakeLists.txt | 4 +- jerry-libc/include/assert.h | 45 ++++++++++++++++ jerry-libc/jerry-libc-defs.h | 28 +--------- jerry-libc/jerry-libc-fatals.c | 45 ---------------- jerry-libc/jerry-libc-printf.c | 54 ++++++++++---------- jerry-libc/target/darwin/jerry-libc-target.c | 12 ++--- jerry-libc/target/linux/jerry-libc-target.c | 20 ++++---- 7 files changed, 92 insertions(+), 116 deletions(-) create mode 100644 jerry-libc/include/assert.h delete mode 100644 jerry-libc/jerry-libc-fatals.c diff --git a/jerry-libc/CMakeLists.txt b/jerry-libc/CMakeLists.txt index 5caac1aeb..535b3499b 100644 --- a/jerry-libc/CMakeLists.txt +++ b/jerry-libc/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright 2015 Samsung Electronics Co., Ltd. +# Copyright 2015-2016 Samsung Electronics Co., Ltd. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -25,7 +25,7 @@ set(COMPILE_FLAGS_LIBC "${COMPILE_FLAGS_JERRY} ${C_FLAGS_JERRY}") set(DEFINES_LIBC_DEBUG ) # Release - set(DEFINES_LIBC_RELEASE LIBC_NDEBUG) + set(DEFINES_LIBC_RELEASE NDEBUG) # Architecture-specific # x86_64 diff --git a/jerry-libc/include/assert.h b/jerry-libc/include/assert.h new file mode 100644 index 000000000..382029ecf --- /dev/null +++ b/jerry-libc/include/assert.h @@ -0,0 +1,45 @@ +/* Copyright 2016 Samsung Electronics Co., Ltd. + * Copyright 2016 University of Szeged. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef JERRY_LIBC_ASSERT_H +#define JERRY_LIBC_ASSERT_H + +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif /* !__cplusplus */ + +#ifndef NDEBUG +#define assert(x) \ + do \ + { \ + if (__builtin_expect (!(x), 0)) \ + { \ + fprintf (stderr, "%s:%d: %s: Assertion `%s' failed.", __FILE__, __LINE__, __func__, #x); \ + abort (); \ + } \ + } while (0) +#else +#define assert(x) ((void) 0) +#endif /* !NDEBUG */ + +#ifdef __cplusplus +} +#endif /* !__cplusplus */ +#endif /* !JERRY_LIBC_ASSERT_H */ diff --git a/jerry-libc/jerry-libc-defs.h b/jerry-libc/jerry-libc-defs.h index 084f915e6..8177d61e2 100644 --- a/jerry-libc/jerry-libc-defs.h +++ b/jerry-libc/jerry-libc-defs.h @@ -1,4 +1,4 @@ -/* Copyright 2015 Samsung Electronics Co., Ltd. +/* Copyright 2015-2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,30 +28,4 @@ #define __attr_noreturn___ __attribute__((noreturn)) #define __attr_noinline___ __attribute__((noinline)) -/** - * Assertions - */ -extern void __attr_noreturn___ -libc_fatal (const char *msg, - const char *file_name, - const char *function_name, - const unsigned int line_number); - -#ifndef LIBC_NDEBUG -# define LIBC_ASSERT(x) do { if (__builtin_expect (!(x), 0)) { \ - libc_fatal (#x, __FILE__, __func__, __LINE__); } } while (0) -# define LIBC_UNREACHABLE() \ - do \ - { \ - libc_fatal ("Code is unreachable", __FILE__, __func__, __LINE__); \ - } while (0) -#else /* !LIBC_NDEBUG */ -# define LIBC_ASSERT(x) do { if (false) { (void) (x); } } while (0) -# define LIBC_UNREACHABLE() \ - do \ - { \ - libc_fatal (NULL, NULL, NULL, 0); \ - } while (0) -#endif /* !LIBC_NDEBUG */ - #endif /* !DEFS_H */ diff --git a/jerry-libc/jerry-libc-fatals.c b/jerry-libc/jerry-libc-fatals.c deleted file mode 100644 index e741e4165..000000000 --- a/jerry-libc/jerry-libc-fatals.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright 2015 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Jerry libc's fatal errors handlers - */ - -#include -#include - -#include "jerry-libc-defs.h" - -/** - * Fatal error handler - * - * Arguments may be NULL. If so, they are ignored. - */ -void __attr_noreturn___ -libc_fatal (const char *msg, /**< fatal error description */ - const char *file_name, /**< file name */ - const char *function_name, /**< function name */ - const unsigned int line_number) /**< line number */ -{ - if (msg != NULL - && file_name != NULL - && function_name != NULL) - { - printf ("Assertion '%s' failed at %s (%s:%u).\n", - msg, function_name, file_name, line_number); - } - - abort (); -} /* libc_fatal */ diff --git a/jerry-libc/jerry-libc-printf.c b/jerry-libc/jerry-libc-printf.c index dc053690a..843ec8457 100644 --- a/jerry-libc/jerry-libc-printf.c +++ b/jerry-libc/jerry-libc-printf.c @@ -18,6 +18,7 @@ * Jerry printf implementation */ +#include #include #include #include @@ -132,20 +133,20 @@ libc_printf_uint_to_string (uintmax_t value, /**< integer value */ char *str_p = str_buffer_end; *--str_p = '\0'; - LIBC_ASSERT (radix >= 2); + assert (radix >= 2); if ((radix & (radix - 1)) != 0) { /* * Radix is not power of 2. Only 32-bit numbers are supported in this mode. */ - LIBC_ASSERT ((value >> 32) == 0); + assert ((value >> 32) == 0); uint32_t value_lo = (uint32_t) value; while (value_lo != 0) { - LIBC_ASSERT (str_p != buffer_p); + assert (str_p != buffer_p); *--str_p = alphabet[ value_lo % radix ]; value_lo /= radix; @@ -158,7 +159,7 @@ libc_printf_uint_to_string (uintmax_t value, /**< integer value */ { shift++; - LIBC_ASSERT (shift <= 32); + assert (shift <= 32); } uint32_t value_lo = (uint32_t) value; @@ -167,7 +168,7 @@ libc_printf_uint_to_string (uintmax_t value, /**< integer value */ while (value_lo != 0 || value_hi != 0) { - LIBC_ASSERT (str_p != buffer_p); + assert (str_p != buffer_p); *--str_p = alphabet[ value_lo & (radix - 1) ]; value_lo >>= shift; @@ -181,7 +182,7 @@ libc_printf_uint_to_string (uintmax_t value, /**< integer value */ *--str_p = '0'; } - LIBC_ASSERT (str_p >= buffer_p && str_p < str_buffer_end); + assert (str_p >= buffer_p && str_p < str_buffer_end); return str_p; } /* libc_printf_uint_to_string */ @@ -198,7 +199,7 @@ libc_printf_write_d_i (FILE *stream, /**< stream pointer */ libc_printf_arg_length_type_t length, /**< field's length type */ uint32_t width) /**< minimum field width to output */ { - LIBC_ASSERT ((flags & LIBC_PRINTF_ARG_FLAG_SHARP) == 0); + assert ((flags & LIBC_PRINTF_ARG_FLAG_SHARP) == 0); bool is_signed = true; uintmax_t value = 0; @@ -252,7 +253,7 @@ libc_printf_write_d_i (FILE *stream, /**< stream pointer */ case LIBC_PRINTF_ARG_LENGTH_TYPE_HIGHL: { - LIBC_UNREACHABLE (); + assert (!"unsupported length field L"); } } @@ -276,7 +277,7 @@ libc_printf_write_d_i (FILE *stream, /**< stream pointer */ if (!sign || (flags & LIBC_PRINTF_ARG_FLAG_PRINT_SIGN)) { - LIBC_ASSERT (string_p > str_buffer); + assert (string_p > str_buffer); *--string_p = (sign ? '+' : '-'); } else if (flags & LIBC_PRINTF_ARG_FLAG_SPACE) @@ -310,7 +311,7 @@ libc_printf_write_u_o_x_X (FILE *stream, /**< stream pointer */ libc_printf_arg_length_type_t length, /**< field's length type */ uint32_t width) /**< minimum field width to output */ { - uintmax_t value = 0; + uintmax_t value; switch (length) { @@ -354,7 +355,14 @@ libc_printf_write_u_o_x_X (FILE *stream, /**< stream pointer */ case LIBC_PRINTF_ARG_LENGTH_TYPE_HIGHL: { - LIBC_UNREACHABLE (); + assert (!"unsupported length field L"); + return; + } + + default: + { + assert (!"unexpected length field"); + return; } } @@ -374,7 +382,7 @@ libc_printf_write_u_o_x_X (FILE *stream, /**< stream pointer */ } else { - LIBC_ASSERT (specifier == 'o'); + assert (specifier == 'o'); } } } @@ -414,7 +422,8 @@ libc_printf_write_u_o_x_X (FILE *stream, /**< stream pointer */ default: { - LIBC_UNREACHABLE (); + assert (!"unexpected type field"); + return; } } @@ -513,8 +522,7 @@ vfprintf (FILE *stream, /**< stream pointer */ if (*format_iter_p == '*') { - /* Not supported */ - LIBC_UNREACHABLE (); + assert (!"unsupported width field *"); } // If there is a number, recognize it as field width @@ -527,8 +535,7 @@ vfprintf (FILE *stream, /**< stream pointer */ if (*format_iter_p == '.') { - /* Not supported */ - LIBC_UNREACHABLE (); + assert (!"unsupported precision field"); } switch (*format_iter_p) @@ -621,8 +628,7 @@ vfprintf (FILE *stream, /**< stream pointer */ case 'a': case 'A': { - /* Not supported */ - LIBC_UNREACHABLE (); + assert (!"unsupported double type field"); break; } @@ -630,8 +636,7 @@ vfprintf (FILE *stream, /**< stream pointer */ { if (length & LIBC_PRINTF_ARG_LENGTH_TYPE_L) { - /* Not supported */ - LIBC_UNREACHABLE (); + assert (!"unsupported length field L"); } else { @@ -654,8 +659,7 @@ vfprintf (FILE *stream, /**< stream pointer */ { if (length & LIBC_PRINTF_ARG_LENGTH_TYPE_L) { - /* Not supported */ - LIBC_UNREACHABLE (); + assert (!"unsupported length field L"); } else { @@ -695,9 +699,7 @@ vfprintf (FILE *stream, /**< stream pointer */ case 'n': { - /* Not supported */ - LIBC_UNREACHABLE (); - break; + assert (!"unsupported type field n"); } } } diff --git a/jerry-libc/target/darwin/jerry-libc-target.c b/jerry-libc/target/darwin/jerry-libc-target.c index 6e1d2aab5..0b6aaeaa5 100644 --- a/jerry-libc/target/darwin/jerry-libc-target.c +++ b/jerry-libc/target/darwin/jerry-libc-target.c @@ -18,6 +18,7 @@ * Jerry libc platform-specific functions darwin implementation */ +#include #include #include #include @@ -123,8 +124,8 @@ fopen (const char *path, /**< file path */ bool create_if_not_exist = false; bool position_at_end = false; - LIBC_ASSERT (path != NULL && mode != NULL); - LIBC_ASSERT (mode[1] == '+' || mode[1] == '\0'); + assert (path != NULL && mode != NULL); + assert (mode[1] == '+' || mode[1] == '\0'); switch (mode[0]) { @@ -149,14 +150,13 @@ fopen (const char *path, /**< file path */ create_if_not_exist = true; if (mode[1] == '+') { - /* Not supported */ - LIBC_UNREACHABLE (); + assert (!"unsupported mode a+"); } break; } default: { - LIBC_UNREACHABLE (); + assert (!"unsupported mode"); } } @@ -172,7 +172,7 @@ fopen (const char *path, /**< file path */ } else { - LIBC_ASSERT (may_read && may_write); + assert (may_read && may_write); flags = O_RDWR; } diff --git a/jerry-libc/target/linux/jerry-libc-target.c b/jerry-libc/target/linux/jerry-libc-target.c index e86f5147b..fb3179dc9 100644 --- a/jerry-libc/target/linux/jerry-libc-target.c +++ b/jerry-libc/target/linux/jerry-libc-target.c @@ -18,6 +18,7 @@ * Jerry libc platform-specific functions linux implementation */ +#include #include #include #include @@ -123,8 +124,8 @@ fopen (const char *path, /**< file path */ bool create_if_not_exist = false; bool position_at_end = false; - LIBC_ASSERT (path != NULL && mode != NULL); - LIBC_ASSERT (mode[1] == '+' || mode[1] == '\0'); + assert (path != NULL && mode != NULL); + assert (mode[1] == '+' || mode[1] == '\0'); switch (mode[0]) { @@ -149,14 +150,13 @@ fopen (const char *path, /**< file path */ create_if_not_exist = true; if (mode[1] == '+') { - /* Not supported */ - LIBC_UNREACHABLE (); + assert (!"unsupported mode a+"); } break; } default: { - LIBC_UNREACHABLE (); + assert (!"unsupported mode"); } } @@ -172,7 +172,7 @@ fopen (const char *path, /**< file path */ } else { - LIBC_ASSERT (may_read && may_write); + assert (may_read && may_write); flags = O_RDWR; } @@ -348,16 +348,16 @@ jrt_set_mem_limits (size_t data_size, /**< limit for data + bss + brk heap */ #ifdef __TARGET_HOST_x64 ret = syscall_2 (__NR_setrlimit, RLIMIT_DATA, (intptr_t) &data_limit); - LIBC_ASSERT (ret == 0); + assert (ret == 0); ret = syscall_2 (__NR_setrlimit, RLIMIT_STACK, (intptr_t) &stack_limit); - LIBC_ASSERT (ret == 0); + assert (ret == 0); #elif defined (__TARGET_HOST_ARMv7) ret = syscall_3 (__NR_prlimit64, 0, RLIMIT_DATA, (intptr_t) &data_limit); - LIBC_ASSERT (ret == 0); + assert (ret == 0); ret = syscall_3 (__NR_prlimit64, 0, RLIMIT_STACK, (intptr_t) &stack_limit); - LIBC_ASSERT (ret == 0); + assert (ret == 0); #elif defined (__TARGET_HOST_x86) # error "__TARGET_HOST_x86 case is not implemented" #else /* !__TARGET_HOST_x64 && !__TARGET_HOST_ARMv7 && !__TARGET_HOST_x86 */