Skip to content

Commit 6974424

Browse files
committed
Cleanup jerry's assert-like routines and macros
Until now, jerry had 3 different assert-like routines: `jerry_assert_fail`, `jerry_unreachable`, and `jerry_unimplemented`, and 3 corresponding macros (`JERRY_ASSERT`, `JERRY_UNREACHABLE`, and `JERRY_UNIMPLEMENTED`). They had some irregularities, namely: * All of them had a string parameter, although `jerry_unreachable` never got anything there but NULL. * Both `jerry_unreachable` and `jerry_unimplemented` checked its string parameter for NULL, although it was always NULL for the first one and never NULL for the second. * `jerry_unreachable` is just a regular assert with a fixed error message (i.e., control should not have got here), however, the expansion of its corresponding macro in debug and release modes differs from the behaviour of `JERRY_ASSERT`: `JERRY_ASSERT` is a no-op in release, however, `JERRY_UNREACHABLE` was triggering a crash even there. * Moreover, `JERRY_UNIMPLEMENTED` was almost never used anymore but in a few places (where often an `#ifdef` selected between `JERRY_UNIMPLEMENTED` and `JERRY_UNREACHABLE`). Because of the above, this patch makes the following changes: * Drops `JERRY_UNIMPLEMENTED` completely and whereever it was still used, replaces it with `JERRY_UNREACHABLE`. As a consequence, the `jerry_unimplemented` function and the `ERR_UNIMPLEMENTED_CASE` fatal error code are also removed. * Makes `JERRY_UNREACHABLE` expand to no-op in release builds. (Actually, to `__builtin_unreachable ()` to avoid warnings.) As a consequence, makes both `jerry_assert_fail` and `jerry_unreachable` be guarded by `#ifndef JERRY_NDEBUG`. Also, changes `jerry_unreachable` not to expect a string parameter. * Rewrites `TEST_ASSERT` not to rely on `jerry_assert_fail` as `TEST_ASSERT` has to work in release builds as well. This also allows changing the error message not to mention "ICE", which would misleadingly suggest an assert within the engine, but "TEST" instead. As a side-effect of the cleanup, some refactorings happened in jrt.h: * Removed the definition of the unnecessary `__extension__` macro. * Re-used `JERRY_UNUSED` and `unlikely` where possible. * Moved some parts of the file around. * Fixed some comments (`/**` should only be used for the docstring of a single entity, for groups header comments, the regular `/*` should be used). JerryScript-DCO-1.0-Signed-off-by: Akos Kiss akiss@inf.u-szeged.hu
1 parent f15e7be commit 6974424

7 files changed

Lines changed: 75 additions & 157 deletions

File tree

jerry-core/ecma/builtin-objects/ecma-builtins.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ ecma_instantiate_builtin (ecma_builtin_id_t id) /**< built-in id */
253253
{
254254
JERRY_ASSERT (id < ECMA_BUILTIN_ID__COUNT);
255255

256-
JERRY_UNIMPLEMENTED ("The built-in is not implemented.");
256+
JERRY_UNREACHABLE (); /* The built-in is not implemented. */
257257
}
258258
}
259259
} /* ecma_instantiate_builtin */
@@ -683,7 +683,7 @@ ecma_builtin_dispatch_routine (ecma_builtin_id_t builtin_object_id, /**< built-i
683683

684684
default:
685685
{
686-
JERRY_UNIMPLEMENTED ("The built-in is not implemented.");
686+
JERRY_UNREACHABLE (); /* The built-in is not implemented. */
687687
}
688688
}
689689

@@ -744,7 +744,7 @@ ecma_builtin_dispatch_call (ecma_object_t *obj_p, /**< built-in object */
744744

745745
default:
746746
{
747-
JERRY_UNIMPLEMENTED ("The built-in is not implemented.");
747+
JERRY_UNREACHABLE (); /* The built-in is not implemented. */
748748
}
749749
}
750750
}
@@ -799,7 +799,7 @@ ecma_builtin_dispatch_construct (ecma_object_t *obj_p, /**< built-in object */
799799

800800
default:
801801
{
802-
JERRY_UNIMPLEMENTED ("The built-in is not implemented.");
802+
JERRY_UNREACHABLE (); /* The built-in is not implemented. */
803803
}
804804
}
805805

jerry-core/jerry-port.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ typedef enum
4848
ERR_OUT_OF_MEMORY = 10,
4949
ERR_SYSCALL = 11,
5050
ERR_REF_COUNT_LIMIT = 12,
51-
ERR_UNIMPLEMENTED_CASE = 118,
5251
ERR_FAILED_INTERNAL_ASSERTION = 120
5352
} jerry_fatal_code_t;
5453

jerry-core/jerry.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1821,7 +1821,7 @@ snapshot_add_compiled_code (ecma_compiled_code_t *compiled_code_p, /**< compiled
18211821
copied_code_p->status_flags = compiled_code_p->status_flags;
18221822

18231823
#else /* CONFIG_DISABLE_REGEXP_BUILTIN */
1824-
JERRY_UNIMPLEMENTED ("RegExp is not supported in the selected profile.");
1824+
JERRY_UNREACHABLE (); /* RegExp is not supported in the selected profile. */
18251825
#endif /* !CONFIG_DISABLE_REGEXP_BUILTIN */
18261826
return start_offset;
18271827
}
@@ -2117,7 +2117,7 @@ snapshot_load_compiled_code (const uint8_t *snapshot_data_p, /**< snapshot data
21172117

21182118
return (ecma_compiled_code_t *) re_bytecode_p;
21192119
#else /* CONFIG_DISABLE_REGEXP_BUILTIN */
2120-
JERRY_UNIMPLEMENTED ("RegExp is not supported in the selected profile.");
2120+
JERRY_UNREACHABLE (); /* RegExp is not supported in the selected profile. */
21212121
#endif /* !CONFIG_DISABLE_REGEXP_BUILTIN */
21222122
}
21232123

jerry-core/jrt/jrt-fatals.c

Lines changed: 3 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,6 @@ jerry_fatal (jerry_fatal_code_t code) /**< status code */
5151
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: ERR_REF_COUNT_LIMIT\n");
5252
break;
5353
}
54-
case ERR_UNIMPLEMENTED_CASE:
55-
{
56-
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: ERR_UNIMPLEMENTED_CASE\n");
57-
break;
58-
}
5954
case ERR_FAILED_INTERNAL_ASSERTION:
6055
{
6156
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: ERR_FAILED_INTERNAL_ASSERTION\n");
@@ -72,6 +67,7 @@ jerry_fatal (jerry_fatal_code_t code) /**< status code */
7267
}
7368
} /* jerry_fatal */
7469

70+
#ifndef JERRY_NDEBUG
7571
/**
7672
* Handle failed assertion
7773
*/
@@ -81,19 +77,12 @@ jerry_assert_fail (const char *assertion, /**< assertion condition string */
8177
const char *function, /**< function name */
8278
const uint32_t line) /**< line */
8379
{
84-
#ifndef JERRY_NDEBUG
8580
jerry_port_log (JERRY_LOG_LEVEL_ERROR,
8681
"ICE: Assertion '%s' failed at %s(%s):%lu.\n",
8782
assertion,
8883
file,
8984
function,
9085
(unsigned long) line);
91-
#else /* JERRY_NDEBUG */
92-
(void) assertion;
93-
(void) file;
94-
(void) function;
95-
(void) line;
96-
#endif /* !JERRY_NDEBUG */
9786

9887
jerry_fatal (ERR_FAILED_INTERNAL_ASSERTION);
9988
} /* jerry_assert_fail */
@@ -102,62 +91,16 @@ jerry_assert_fail (const char *assertion, /**< assertion condition string */
10291
* Handle execution of control path that should be unreachable
10392
*/
10493
void __noreturn
105-
jerry_unreachable (const char *comment, /**< comment to unreachable mark if exists,
106-
NULL - otherwise */
107-
const char *file, /**< file name */
94+
jerry_unreachable (const char *file, /**< file name */
10895
const char *function, /**< function name */
10996
const uint32_t line) /**< line */
11097
{
111-
#ifndef JERRY_NDEBUG
11298
jerry_port_log (JERRY_LOG_LEVEL_ERROR,
113-
"ICE: Unreachable control path at %s(%s):%lu was executed",
99+
"ICE: Unreachable control path at %s(%s):%lu was executed.\n",
114100
file,
115101
function,
116102
(unsigned long) line);
117-
#else /* JERRY_NDEBUG */
118-
(void) file;
119-
(void) function;
120-
(void) line;
121-
#endif /* !JERRY_NDEBUG */
122-
123-
if (comment != NULL)
124-
{
125-
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "(%s)", comment);
126-
}
127-
128-
jerry_port_log (JERRY_LOG_LEVEL_ERROR, ".\n");
129103

130104
jerry_fatal (ERR_FAILED_INTERNAL_ASSERTION);
131105
} /* jerry_unreachable */
132-
133-
/**
134-
* Handle unimplemented case execution
135-
*/
136-
void __noreturn
137-
jerry_unimplemented (const char *comment, /**< comment to unimplemented mark if exists,
138-
NULL - otherwise */
139-
const char *file, /**< file name */
140-
const char *function, /**< function name */
141-
const uint32_t line) /**< line */
142-
{
143-
#ifndef JERRY_NDEBUG
144-
jerry_port_log (JERRY_LOG_LEVEL_ERROR,
145-
"SORRY: Unimplemented case at %s(%s):%lu was executed",
146-
file,
147-
function,
148-
(unsigned long) line);
149-
#else /* JERRY_NDEBUG */
150-
(void) file;
151-
(void) function;
152-
(void) line;
153106
#endif /* !JERRY_NDEBUG */
154-
155-
if (comment != NULL)
156-
{
157-
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "(%s)", comment);
158-
}
159-
160-
jerry_port_log (JERRY_LOG_LEVEL_ERROR, ".\n");
161-
162-
jerry_fatal (ERR_UNIMPLEMENTED_CASE);
163-
} /* jerry_unimplemented */

jerry-core/jrt/jrt.h

Lines changed: 50 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
#include "jerry-port.h"
2525
#include "jrt-types.h"
2626

27-
/**
27+
/*
2828
* Attributes
2929
*/
3030
#define __noreturn __attribute__((noreturn))
@@ -40,7 +40,13 @@
4040
# define __attr_pure___ __attribute__((pure))
4141
#endif /* !__attr_pure___ */
4242

43-
/**
43+
/*
44+
* Conditions' likeliness, unlikeliness.
45+
*/
46+
#define likely(x) __builtin_expect (!!(x), 1)
47+
#define unlikely(x) __builtin_expect (!!(x) , 0)
48+
49+
/*
4450
* Normally compilers store const(ant)s in ROM. Thus saving RAM.
4551
* But if your compiler does not support it then the directive below can force it.
4652
*
@@ -51,16 +57,17 @@
5157
# define JERRY_CONST_DATA
5258
#endif /* JERRY_CONST_DATA */
5359

54-
#ifndef __GNUC__
55-
#define __extension__
56-
#endif /* !__GNUC__ */
57-
58-
/**
60+
/*
5961
* Constants
6062
*/
6163
#define JERRY_BITSINBYTE 8
6264

63-
/**
65+
/*
66+
* Make sure unused parameters, variables, or expressions trigger no compiler warning.
67+
*/
68+
#define JERRY_UNUSED(x) ((void) (x))
69+
70+
/*
6471
* Asserts
6572
*
6673
* Warning:
@@ -73,131 +80,87 @@
7380
#define JERRY_STATIC_ASSERT(x, msg) \
7481
enum { JERRY_STATIC_ASSERT_GLUE (static_assertion_failed_, __LINE__, msg) = 1 / (!!(x)) }
7582

76-
/**
77-
* Variable that must not be referenced.
78-
*
79-
* May be used for static assertion checks.
80-
*/
81-
extern uint32_t jerry_unreferenced_expression;
82-
83-
extern void __noreturn jerry_assert_fail (const char *, const char *, const char *, const uint32_t);
84-
extern void __noreturn jerry_unreachable (const char *, const char *, const char *, const uint32_t);
85-
extern void __noreturn jerry_unimplemented (const char *, const char *, const char *, const uint32_t);
86-
8783
#ifndef JERRY_NDEBUG
88-
#define JERRY_ASSERT(x) do { if (__builtin_expect (!(x), 0)) { \
89-
jerry_assert_fail (#x, __FILE__, __func__, __LINE__); } } while (0)
90-
#else /* JERRY_NDEBUG */
91-
#define JERRY_ASSERT(x) do { if (false) { (void)(x); } } while (0)
92-
#endif /* !JERRY_NDEBUG */
93-
94-
#define JERRY_UNUSED(x) ((void) (x))
84+
extern void __noreturn jerry_assert_fail (const char *, const char *, const char *, const uint32_t);
85+
extern void __noreturn jerry_unreachable (const char *, const char *, const uint32_t);
9586

96-
#ifdef JERRY_ENABLE_LOG
97-
#define JERRY_DLOG(...) jerry_port_log (JERRY_LOG_LEVEL_DEBUG, __VA_ARGS__)
98-
#define JERRY_DDLOG(...) jerry_port_log (JERRY_LOG_LEVEL_TRACE, __VA_ARGS__)
99-
#else /* !JERRY_ENABLE_LOG */
100-
#define JERRY_DLOG(...) \
87+
#define JERRY_ASSERT(x) \
10188
do \
10289
{ \
103-
if (false) \
90+
if (unlikely (!(x))) \
10491
{ \
105-
jerry_ref_unused_variables (0, __VA_ARGS__); \
92+
jerry_assert_fail (#x, __FILE__, __func__, __LINE__); \
10693
} \
10794
} while (0)
108-
#define JERRY_DDLOG(...) JERRY_DLOG (__VA_ARGS__)
109-
#endif /* JERRY_ENABLE_LOG */
110-
111-
#define JERRY_ERROR_MSG(...) jerry_port_log (JERRY_LOG_LEVEL_ERROR, __VA_ARGS__)
112-
#define JERRY_WARNING_MSG(...) jerry_port_log (JERRY_LOG_LEVEL_WARNING, __VA_ARGS__)
11395

114-
/**
115-
* Mark for unreachable points and unimplemented cases
116-
*/
117-
extern void jerry_ref_unused_variables (void *, ...);
118-
119-
#ifndef JERRY_NDEBUG
12096
#define JERRY_UNREACHABLE() \
12197
do \
12298
{ \
123-
jerry_unreachable (NULL, __FILE__, __func__, __LINE__); \
99+
jerry_unreachable (__FILE__, __func__, __LINE__); \
124100
} while (0)
125-
126-
#define JERRY_UNIMPLEMENTED(comment) \
127-
do \
128-
{ \
129-
jerry_unimplemented (comment, __FILE__, __func__, __LINE__); \
130-
} while (0)
131-
132-
#define JERRY_UNIMPLEMENTED_REF_UNUSED_VARS(comment, ...) \
101+
#else /* JERRY_NDEBUG */
102+
#define JERRY_ASSERT(x) \
133103
do \
134104
{ \
135105
if (false) \
136106
{ \
137-
jerry_ref_unused_variables (0, __VA_ARGS__); \
107+
JERRY_UNUSED (x); \
138108
} \
139-
jerry_unimplemented (comment, __FILE__, __func__, __LINE__); \
140-
} while (0)
141-
#else /* JERRY_NDEBUG */
142-
#define JERRY_UNREACHABLE() \
143-
do \
144-
{ \
145-
jerry_unreachable (NULL, NULL, NULL, 0); \
146109
} while (0)
147110

148-
#define JERRY_UNIMPLEMENTED(comment) \
149-
do \
150-
{ \
151-
jerry_unimplemented (comment, NULL, NULL, 0); \
152-
} while (0)
111+
#define JERRY_UNREACHABLE() __builtin_unreachable ()
112+
#endif /* !JERRY_NDEBUG */
113+
114+
/**
115+
* Exit on fatal error
116+
*/
117+
extern void __noreturn jerry_fatal (jerry_fatal_code_t);
118+
119+
/*
120+
* Logging
121+
*/
122+
#ifdef JERRY_ENABLE_LOG
123+
#define JERRY_DLOG(...) jerry_port_log (JERRY_LOG_LEVEL_DEBUG, __VA_ARGS__)
124+
#define JERRY_DDLOG(...) jerry_port_log (JERRY_LOG_LEVEL_TRACE, __VA_ARGS__)
125+
#else /* !JERRY_ENABLE_LOG */
126+
/**
127+
* Mark for unreachable points and unimplemented cases
128+
*/
129+
extern void jerry_ref_unused_variables (void *, ...);
153130

154-
#define JERRY_UNIMPLEMENTED_REF_UNUSED_VARS(comment, ...) \
131+
#define JERRY_DLOG(...) \
155132
do \
156133
{ \
157134
if (false) \
158135
{ \
159136
jerry_ref_unused_variables (0, __VA_ARGS__); \
160137
} \
161-
jerry_unimplemented (comment, NULL, NULL, 0); \
162138
} while (0)
163-
#endif /* !JERRY_NDEBUG */
164-
165-
/**
166-
* Conditions' likeliness, unlikeliness.
167-
*/
168-
#define likely(x) __builtin_expect (!!(x), 1)
169-
#define unlikely(x) __builtin_expect (!!(x) , 0)
139+
#define JERRY_DDLOG(...) JERRY_DLOG (__VA_ARGS__)
140+
#endif /* JERRY_ENABLE_LOG */
170141

171-
/**
172-
* Exit
173-
*/
174-
extern void __noreturn jerry_fatal (jerry_fatal_code_t);
142+
#define JERRY_ERROR_MSG(...) jerry_port_log (JERRY_LOG_LEVEL_ERROR, __VA_ARGS__)
143+
#define JERRY_WARNING_MSG(...) jerry_port_log (JERRY_LOG_LEVEL_WARNING, __VA_ARGS__)
175144

176145
/**
177-
* sizeof, offsetof, ...
146+
* Size of struct member
178147
*/
179148
#define JERRY_SIZE_OF_STRUCT_MEMBER(struct_name, member_name) sizeof (((struct_name *) NULL)->member_name)
180149

181-
/**
182-
* Alignment
183-
*/
184-
185150
/**
186151
* Aligns @a value to @a alignment. @a must be the power of 2.
187152
*
188153
* Returns minimum positive value, that divides @a alignment and is more than or equal to @a value
189154
*/
190155
#define JERRY_ALIGNUP(value, alignment) (((value) + ((alignment) - 1)) & ~((alignment) - 1))
191156

192-
/**
157+
/*
193158
* min, max
194159
*/
195160
#define JERRY_MIN(v1, v2) (((v1) < (v2)) ? (v1) : (v2))
196161
#define JERRY_MAX(v1, v2) (((v1) < (v2)) ? (v2) : (v1))
197162

198-
199163
extern bool jrt_read_from_buffer_by_offset (const uint8_t *, size_t, size_t *, void *, size_t);
200-
201164
extern bool jrt_write_to_buffer_by_offset (uint8_t *, size_t, size_t *, const void *, size_t);
202165

203166
#endif /* !JRT_H */

jerry-core/vm/vm.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ vm_construct_literal_object (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
301301

302302
return ret_value;
303303
#else /* CONFIG_DISABLE_REGEXP_BUILTIN */
304-
JERRY_UNIMPLEMENTED ("Regular Expressions are not supported in the selected profile!");
304+
JERRY_UNREACHABLE (); /* Regular Expressions are not supported in the selected profile! */
305305
#endif /* !CONFIG_DISABLE_REGEXP_BUILTIN */
306306
}
307307
} /* vm_construct_literal_object */

0 commit comments

Comments
 (0)