1 /* Copyright JS Foundation and other contributors, http://js.foundation
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 /**
17 * Implementation of exit with specified status code.
18 */
19
20 #include "jmem.h"
21 #include "jrt.h"
22 #include "jrt-libc-includes.h"
23
24 #ifdef _WIN32
25 # ifdef _WIN64
26 # define PRI_SIZET "lu"
27 # define MSG_SIZE_TYPE unsigned long
28 # else
29 # define PRI_SIZET "zu"
30 # define MSG_SIZE_TYPE size_t
31 # endif
32 #else
33 # define PRI_SIZET "zu"
34 # define MSG_SIZE_TYPE size_t
35 #endif
36
37 #if defined (_WIN32) || defined (_WIN64) || !defined (JERRY_NDEBUG) || defined (__APPLE__)
38 #if ENABLED (JERRY_MEM_STATS)
39 static void
jerry_dump_memstats_on_error(void)40 jerry_dump_memstats_on_error (void)
41 {
42 /* Dump memory stats */
43 jmem_heap_stats_t jmem_heap_stats;
44 jmem_heap_get_stats (&jmem_heap_stats);
45
46 JERRY_ERROR_MSG ("\tMemory info:\n");
47 JERRY_ERROR_MSG ("\theap total size: %"PRI_SIZET"\n", (MSG_SIZE_TYPE)(jmem_heap_stats.size));
48
49 JERRY_ERROR_MSG ("\tcurrently allocated bytes: %"PRI_SIZET"\n", (MSG_SIZE_TYPE)(jmem_heap_stats.allocated_bytes));
50 JERRY_ERROR_MSG ("\tpeak allocated bytes: %"PRI_SIZET"\n", (MSG_SIZE_TYPE)(jmem_heap_stats.peak_allocated_bytes));
51
52 JERRY_ERROR_MSG ("\tbytes waste due to blocks filled partially: %"PRI_SIZET"\n", (MSG_SIZE_TYPE)(jmem_heap_stats.waste_bytes));
53 JERRY_ERROR_MSG ("\tpeak wasted bytes: %"PRI_SIZET"\n", (MSG_SIZE_TYPE)(jmem_heap_stats.peak_waste_bytes));
54
55 JERRY_ERROR_MSG ("\tallocated memory for byte code: %"PRI_SIZET"\n", (MSG_SIZE_TYPE)(jmem_heap_stats.byte_code_bytes));
56 JERRY_ERROR_MSG ("\tpeak allocated memory for byte code: %"PRI_SIZET"\n", (MSG_SIZE_TYPE)(jmem_heap_stats.peak_byte_code_bytes));
57
58 JERRY_ERROR_MSG ("\tallocated memory for strings: %"PRI_SIZET"\n", (MSG_SIZE_TYPE)(jmem_heap_stats.string_bytes));
59 JERRY_ERROR_MSG ("\tpeak allocated memory for strings: %"PRI_SIZET"\n", (MSG_SIZE_TYPE)(jmem_heap_stats.peak_string_bytes));
60
61 JERRY_ERROR_MSG ("\tallocated memory for objects: %"PRI_SIZET"\n", (MSG_SIZE_TYPE)(jmem_heap_stats.object_bytes));
62 JERRY_ERROR_MSG ("\tpeak allocated memory for objects: %"PRI_SIZET"\n", (MSG_SIZE_TYPE)(jmem_heap_stats.peak_object_bytes));
63
64 JERRY_ERROR_MSG ("\tallocated memory for properties: %"PRI_SIZET"\n", (MSG_SIZE_TYPE)(jmem_heap_stats.property_bytes));
65 JERRY_ERROR_MSG ("\tpeak allocated memory for properties: %"PRI_SIZET"\n", (MSG_SIZE_TYPE)(jmem_heap_stats.peak_property_bytes));
66 }
67 #endif
68 #endif /* Windows/Mac Or !defined (JERRY_NDEBUG) */
69
70 /*
71 * Exit with specified status code.
72 *
73 * If !JERRY_NDEBUG and code != 0, print status code with description
74 * and call assertion fail handler.
75 */
76 void JERRY_ATTR_NORETURN
jerry_fatal(jerry_fatal_code_t code)77 jerry_fatal (jerry_fatal_code_t code) /**< status code */
78 {
79 #if defined (_WIN32) || defined (_WIN64) || !defined (JERRY_NDEBUG) || defined (__APPLE__)
80 switch (code)
81 {
82 case ERR_OUT_OF_MEMORY:
83 {
84 JERRY_ERROR_MSG ("Error: ERR_OUT_OF_MEMORY\n");
85 break;
86 }
87 case ERR_REF_COUNT_LIMIT:
88 {
89 JERRY_ERROR_MSG ("Error: ERR_REF_COUNT_LIMIT\n");
90 break;
91 }
92 case ERR_UNTERMINATED_GC_LOOPS:
93 {
94 JERRY_ERROR_MSG ("Error: ERR_UNTERMINATED_GC_LOOPS\n");
95 break;
96 }
97 case ERR_DISABLED_BYTE_CODE:
98 {
99 JERRY_ERROR_MSG ("Error: ERR_DISABLED_BYTE_CODE\n");
100 break;
101 }
102 case ERR_FAILED_INTERNAL_ASSERTION:
103 {
104 JERRY_ERROR_MSG ("Error: ERR_FAILED_INTERNAL_ASSERTION\n");
105 break;
106 }
107 default:
108 {
109 JERRY_ERROR_MSG ("Error: ERR_UNKNOWN_FATAL\n");
110 break;
111 }
112 }
113
114 #if ENABLED (JERRY_MEM_STATS)
115 jerry_dump_memstats_on_error ();
116 #endif
117 #endif /* Windows/Mac Or !defined (JERRY_NDEBUG) */
118
119 jerry_port_fatal (code);
120
121 /* to make compiler happy for some RTOS: 'control reaches end of non-void function' */
122 while (true)
123 {
124 }
125 } /* jerry_fatal */
126
127 #ifndef JERRY_NDEBUG
128 /**
129 * Handle failed assertion
130 */
131 void JERRY_ATTR_NORETURN
jerry_assert_fail(const char * assertion,const char * file,const char * function,const uint32_t line)132 jerry_assert_fail (const char *assertion, /**< assertion condition string */
133 const char *file, /**< file name */
134 const char *function, /**< function name */
135 const uint32_t line) /**< line */
136 {
137 JERRY_ERROR_MSG ("ICE: Assertion '%s' failed at %s(%s):%lu.\n",
138 assertion,
139 file,
140 function,
141 (unsigned long) line);
142
143 jerry_fatal (ERR_FAILED_INTERNAL_ASSERTION);
144 } /* jerry_assert_fail */
145
146 /**
147 * Handle execution of control path that should be unreachable
148 */
149 void JERRY_ATTR_NORETURN
jerry_unreachable(const char * file,const char * function,const uint32_t line)150 jerry_unreachable (const char *file, /**< file name */
151 const char *function, /**< function name */
152 const uint32_t line) /**< line */
153 {
154 JERRY_ERROR_MSG ("ICE: Unreachable control path at %s(%s):%lu was executed.\n",
155 file,
156 function,
157 (unsigned long) line);
158
159 jerry_fatal (ERR_FAILED_INTERNAL_ASSERTION);
160 } /* jerry_unreachable */
161 #endif /* !JERRY_NDEBUG */
162