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
This commit is contained in:
Akos Kiss
2016-04-13 21:24:53 +02:00
parent ecfd478df0
commit ff185dc57e
7 changed files with 92 additions and 116 deletions
+2 -2
View File
@@ -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
+45
View File
@@ -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 <stdio.h>
#include <stdlib.h>
#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 */
+1 -27
View File
@@ -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 */
-45
View File
@@ -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 <stdio.h>
#include <stdlib.h>
#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 */
+28 -26
View File
@@ -18,6 +18,7 @@
* Jerry printf implementation
*/
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
@@ -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");
}
}
}
+6 -6
View File
@@ -18,6 +18,7 @@
* Jerry libc platform-specific functions darwin implementation
*/
#include <assert.h>
#include <fcntl.h>
#include <signal.h>
#include <stdarg.h>
@@ -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;
}
+10 -10
View File
@@ -18,6 +18,7 @@
* Jerry libc platform-specific functions linux implementation
*/
#include <assert.h>
#include <fcntl.h>
#include <signal.h>
#include <stdarg.h>
@@ -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 */