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 | #include "jerryscript-ext/handler.h" |
17 | #include "jerryscript-port.h" |
18 | |
19 | #include <inttypes.h> |
20 | |
21 | /** |
22 | * Hard assert for scripts. The routine calls jerry_port_fatal on assertion failure. |
23 | * |
24 | * Notes: |
25 | * * If the `JERRY_FEATURE_LINE_INFO` runtime feature is enabled (build option: `JERRY_LINE_INFO`) |
26 | * a backtrace is also printed out. |
27 | * |
28 | * @return true - if only one argument was passed and that argument was a boolean true. |
29 | * Note that the function does not return otherwise. |
30 | */ |
31 | jerry_value_t |
32 | jerryx_handler_assert_fatal (const jerry_value_t func_obj_val, /**< function object */ |
33 | const jerry_value_t this_p, /**< this arg */ |
34 | const jerry_value_t args_p[], /**< function arguments */ |
35 | const jerry_length_t args_cnt) /**< number of function arguments */ |
36 | { |
37 | (void) func_obj_val; /* unused */ |
38 | (void) this_p; /* unused */ |
39 | |
40 | if (args_cnt == 1 |
41 | && jerry_value_is_boolean (args_p[0]) |
42 | && jerry_get_boolean_value (args_p[0])) |
43 | { |
44 | return jerry_create_boolean (true); |
45 | } |
46 | |
47 | /* Assert failed, print a bit of JS backtrace */ |
48 | jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Script Error: assertion failed\n" ); |
49 | |
50 | if (jerry_is_feature_enabled (JERRY_FEATURE_LINE_INFO)) |
51 | { |
52 | jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Script backtrace (top 5):\n" ); |
53 | |
54 | /* If the line info feature is disabled an empty array will be returned. */ |
55 | jerry_value_t backtrace_array = jerry_get_backtrace (5); |
56 | uint32_t array_length = jerry_get_array_length (backtrace_array); |
57 | |
58 | for (uint32_t idx = 0; idx < array_length; idx++) |
59 | { |
60 | jerry_value_t property = jerry_get_property_by_index (backtrace_array, idx); |
61 | |
62 | jerry_length_t total_size = jerry_get_utf8_string_size (property); |
63 | jerry_length_t current_size = 0; |
64 | jerry_char_t string_buffer[64]; |
65 | const jerry_length_t copy_size = (jerry_length_t) (sizeof (string_buffer) - 1); |
66 | |
67 | /* On some systems the uint32_t values can't be printed with "%u" and |
68 | * on some systems it can be printed. To avoid differences in the uint32_t typdef |
69 | * The "PRIu32" macro is used to correctly add the formatter. |
70 | */ |
71 | jerry_port_log (JERRY_LOG_LEVEL_ERROR, " %" PRIu32": " , idx); |
72 | do |
73 | { |
74 | jerry_size_t copied_bytes = jerry_substring_to_utf8_char_buffer (property, |
75 | current_size, |
76 | current_size + copy_size, |
77 | string_buffer, |
78 | copy_size); |
79 | string_buffer[copied_bytes] = '\0'; |
80 | jerry_port_log (JERRY_LOG_LEVEL_ERROR, "%s" , string_buffer); |
81 | |
82 | current_size += copied_bytes; |
83 | } |
84 | while (total_size != current_size); |
85 | jerry_port_log (JERRY_LOG_LEVEL_ERROR, "\n" ); |
86 | |
87 | jerry_release_value (property); |
88 | } |
89 | |
90 | jerry_release_value (backtrace_array); |
91 | } |
92 | |
93 | jerry_port_fatal (ERR_FAILED_INTERNAL_ASSERTION); |
94 | } /* jerryx_handler_assert_fatal */ |
95 | |
96 | /** |
97 | * Soft assert for scripts. The routine throws an error on assertion failure. |
98 | * |
99 | * @return true - if only one argument was passed and that argument was a boolean true. |
100 | * error - otherwise. |
101 | */ |
102 | jerry_value_t |
103 | jerryx_handler_assert_throw (const jerry_value_t func_obj_val, /**< function object */ |
104 | const jerry_value_t this_p, /**< this arg */ |
105 | const jerry_value_t args_p[], /**< function arguments */ |
106 | const jerry_length_t args_cnt) /**< number of function arguments */ |
107 | { |
108 | (void) func_obj_val; /* unused */ |
109 | (void) this_p; /* unused */ |
110 | |
111 | if (args_cnt == 1 |
112 | && jerry_value_is_boolean (args_p[0]) |
113 | && jerry_get_boolean_value (args_p[0])) |
114 | { |
115 | return jerry_create_boolean (true); |
116 | } |
117 | |
118 | return jerry_create_error (JERRY_ERROR_COMMON, (jerry_char_t *) "assertion failed" ); |
119 | } /* jerryx_handler_assert_throw */ |
120 | |
121 | /** |
122 | * An alias to `jerryx_handler_assert_fatal`. |
123 | * |
124 | * @return true - if only one argument was passed and that argument was a boolean true. |
125 | * Note that the function does not return otherwise. |
126 | */ |
127 | jerry_value_t |
128 | jerryx_handler_assert (const jerry_value_t func_obj_val, /**< function object */ |
129 | const jerry_value_t this_p, /**< this arg */ |
130 | const jerry_value_t args_p[], /**< function arguments */ |
131 | const jerry_length_t args_cnt) /**< number of function arguments */ |
132 | { |
133 | return jerryx_handler_assert_fatal (func_obj_val, this_p, args_p, args_cnt); |
134 | } /* jerryx_handler_assert */ |
135 | |