Skip to content

Commit 0e3791a

Browse files
committed
Improve error message
JerryScript-DCO-1.0-Signed-off-by: Yanhui Shen [email protected]
1 parent c6a7765 commit 0e3791a

File tree

6 files changed

+153
-66
lines changed

6 files changed

+153
-66
lines changed

jerry-core/ecma/base/ecma-helpers-string.c

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
* limitations under the License.
1414
*/
1515

16+
#include <stdarg.h>
1617
#include "ecma-alloc.h"
1718
#include "ecma-gc.h"
1819
#include "ecma-globals.h"
@@ -708,6 +709,69 @@ ecma_concat_ecma_strings (ecma_string_t *string1_p, /**< first ecma-string */
708709
return string_desc_p;
709710
} /* ecma_concat_ecma_strings */
710711

712+
#ifdef JERRY_ENABLE_ERROR_MESSAGES
713+
714+
/**
715+
* Format ecma-strings.
716+
*
717+
* @return a newly created ecma-string
718+
*/
719+
ecma_string_t *
720+
ecma_format_ecma_strings (const char *format, /**< format string */
721+
...) /**< ecma-strings */
722+
{
723+
JERRY_ASSERT (format != NULL);
724+
725+
va_list args;
726+
727+
va_start (args, format);
728+
729+
ecma_string_t *string_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY);
730+
ecma_string_t *string1_p;
731+
ecma_string_t *string2_p;
732+
733+
const char *start_p = format;
734+
const char *end_p = format;
735+
736+
while (*end_p)
737+
{
738+
if (*end_p == '%')
739+
{
740+
string1_p = string_p;
741+
string2_p = ecma_new_ecma_string_from_utf8 ((const lit_utf8_byte_t *) start_p,
742+
(lit_utf8_size_t) (end_p - start_p));
743+
string_p = ecma_concat_ecma_strings (string1_p, string2_p);
744+
ecma_deref_ecma_string (string1_p);
745+
ecma_deref_ecma_string (string2_p);
746+
747+
string1_p = string_p;
748+
string2_p = va_arg (args, ecma_string_t *);
749+
string_p = ecma_concat_ecma_strings (string1_p, string2_p);
750+
ecma_deref_ecma_string (string1_p);
751+
752+
start_p = end_p + 1;
753+
}
754+
755+
end_p++;
756+
}
757+
758+
if (start_p < end_p)
759+
{
760+
string1_p = string_p;
761+
string2_p = ecma_new_ecma_string_from_utf8 ((const lit_utf8_byte_t *) start_p,
762+
(lit_utf8_size_t) (end_p - start_p));
763+
string_p = ecma_concat_ecma_strings (string1_p, string2_p);
764+
ecma_deref_ecma_string (string1_p);
765+
ecma_deref_ecma_string (string2_p);
766+
}
767+
768+
va_end (args);
769+
770+
return string_p;
771+
} /* ecma_format_ecma_strings */
772+
773+
#endif /* JERRY_ENABLE_ERROR_MESSAGES */
774+
711775
/**
712776
* Increase reference counter of ecma-string.
713777
*/

jerry-core/ecma/base/ecma-helpers.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ ecma_string_t *ecma_new_ecma_string_from_magic_string_id (lit_magic_string_id_t
172172
ecma_string_t *ecma_new_ecma_string_from_magic_string_ex_id (lit_magic_string_ex_id_t id);
173173
ecma_string_t *ecma_new_ecma_length_string (void);
174174
ecma_string_t *ecma_concat_ecma_strings (ecma_string_t *string1_p, ecma_string_t *string2_p);
175+
ecma_string_t *ecma_format_ecma_strings (const char *format, ...);
175176
void ecma_ref_ecma_string (ecma_string_t *string_p);
176177
void ecma_deref_ecma_string (ecma_string_t *string_p);
177178
ecma_number_t ecma_string_to_number (const ecma_string_t *str_p);

jerry-core/ecma/operations/ecma-get-put-value.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,15 @@ ecma_op_get_value_lex_env_base (ecma_object_t *ref_base_lex_env_p, /**< referenc
5252
/* 3. */
5353
if (unlikely (is_unresolvable_reference))
5454
{
55-
return ecma_raise_reference_error (ECMA_ERR_MSG ("Cannot resolve reference."));
55+
#ifdef JERRY_ENABLE_ERROR_MESSAGES
56+
ecma_string_t *error_msg_p = ecma_format_ecma_strings ("% is not defined", var_name_string_p);
57+
ecma_object_t *error_obj_p = ecma_new_standard_error_with_message (ECMA_ERROR_REFERENCE, error_msg_p);
58+
ecma_value_t error_value = ecma_make_error_obj_value (error_obj_p);
59+
ecma_deref_ecma_string (error_msg_p);
60+
#else /* !JERRY_ENABLE_ERROR_MESSAGES */
61+
ecma_value_t error_value = ecma_raise_reference_error (NULL);
62+
#endif /* JERRY_ENABLE_ERROR_MESSAGES */
63+
return error_value;
5664
}
5765

5866
/* 5. */
@@ -149,7 +157,15 @@ ecma_op_put_value_lex_env_base (ecma_object_t *ref_base_lex_env_p, /**< referenc
149157
/* 3.a. */
150158
if (is_strict)
151159
{
152-
return ecma_raise_reference_error (ECMA_ERR_MSG ("Cannot resolve reference."));
160+
#ifdef JERRY_ENABLE_ERROR_MESSAGES
161+
ecma_string_t *error_msg_p = ecma_format_ecma_strings ("% is not defined", var_name_string_p);
162+
ecma_object_t *error_obj_p = ecma_new_standard_error_with_message (ECMA_ERROR_REFERENCE, error_msg_p);
163+
ecma_value_t error_value = ecma_make_error_obj_value (error_obj_p);
164+
ecma_deref_ecma_string (error_msg_p);
165+
#else /* !JERRY_ENABLE_ERROR_MESSAGES */
166+
ecma_value_t error_value = ecma_raise_reference_error (NULL);
167+
#endif /* JERRY_ENABLE_ERROR_MESSAGES */
168+
return error_value;
153169
}
154170
else
155171
{

jerry-core/ecma/operations/ecma-reference.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,15 @@ ecma_op_resolve_reference_value (ecma_object_t *lex_env_p, /**< starting lexical
123123
lex_env_p = ecma_get_lex_env_outer_reference (lex_env_p);
124124
}
125125

126-
return ecma_raise_reference_error (ECMA_ERR_MSG ("Cannot resolve reference."));
126+
#ifdef JERRY_ENABLE_ERROR_MESSAGES
127+
ecma_string_t *error_msg_p = ecma_format_ecma_strings ("% is not defined", name_p);
128+
ecma_object_t *error_obj_p = ecma_new_standard_error_with_message (ECMA_ERROR_REFERENCE, error_msg_p);
129+
ecma_value_t error_value = ecma_make_error_obj_value (error_obj_p);
130+
ecma_deref_ecma_string (error_msg_p);
131+
#else /* !JERRY_ENABLE_ERROR_MESSAGES */
132+
ecma_value_t error_value = ecma_raise_reference_error (NULL);
133+
#endif /* JERRY_ENABLE_ERROR_MESSAGES */
134+
return error_value;
127135
} /* ecma_op_resolve_reference_value */
128136

129137
/**

jerry-core/parser/js/js-parser.c

Lines changed: 18 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -2345,13 +2345,6 @@ parser_send_breakpoints (parser_context_t *context_p, /**< context */
23452345

23462346
#endif /* JERRY_DEBUGGER */
23472347

2348-
#define PARSE_ERR_POS_START " [line: "
2349-
#define PARSE_ERR_POS_START_SIZE ((uint32_t) sizeof (PARSE_ERR_POS_START) - 1)
2350-
#define PARSE_ERR_POS_MIDDLE ", column: "
2351-
#define PARSE_ERR_POS_MIDDLE_SIZE ((uint32_t) sizeof (PARSE_ERR_POS_MIDDLE) - 1)
2352-
#define PARSE_ERR_POS_END "]"
2353-
#define PARSE_ERR_POS_END_SIZE ((uint32_t) sizeof (PARSE_ERR_POS_END))
2354-
23552348
#endif /* JERRY_JS_PARSER */
23562349

23572350
/**
@@ -2389,50 +2382,24 @@ parser_parse_script (const uint8_t *source_p, /**< source code */
23892382
return ecma_make_error_value (ecma_make_simple_value (ECMA_SIMPLE_VALUE_NULL));
23902383
}
23912384
#ifdef JERRY_ENABLE_ERROR_MESSAGES
2392-
const char *err_str_p = parser_error_to_string (parser_error.error);
2393-
uint32_t err_str_size = lit_zt_utf8_string_size ((const lit_utf8_byte_t *) err_str_p);
2394-
2395-
char line_str_p[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32];
2396-
uint32_t line_len = ecma_uint32_to_utf8_string (parser_error.line,
2397-
(lit_utf8_byte_t *) line_str_p,
2398-
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);
2399-
2400-
char col_str_p[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32];
2401-
uint32_t col_len = ecma_uint32_to_utf8_string (parser_error.column,
2402-
(lit_utf8_byte_t *) col_str_p,
2403-
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);
2404-
2405-
uint32_t msg_size = (err_str_size
2406-
+ line_len
2407-
+ col_len
2408-
+ PARSE_ERR_POS_START_SIZE
2409-
+ PARSE_ERR_POS_MIDDLE_SIZE
2410-
+ PARSE_ERR_POS_END_SIZE);
2411-
2412-
ecma_value_t error_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
2413-
2414-
JMEM_DEFINE_LOCAL_ARRAY (error_msg_p, msg_size, char);
2415-
char *err_msg_pos_p = error_msg_p;
2416-
2417-
strncpy (err_msg_pos_p, err_str_p, err_str_size);
2418-
err_msg_pos_p += err_str_size;
2419-
2420-
strncpy (err_msg_pos_p, PARSE_ERR_POS_START, PARSE_ERR_POS_START_SIZE);
2421-
err_msg_pos_p += PARSE_ERR_POS_START_SIZE;
2422-
2423-
strncpy (err_msg_pos_p, line_str_p, line_len);
2424-
err_msg_pos_p += line_len;
2425-
2426-
strncpy (err_msg_pos_p, PARSE_ERR_POS_MIDDLE, PARSE_ERR_POS_MIDDLE_SIZE);
2427-
err_msg_pos_p += PARSE_ERR_POS_MIDDLE_SIZE;
2428-
2429-
strncpy (err_msg_pos_p, col_str_p, col_len);
2430-
err_msg_pos_p += col_len;
2431-
2432-
strncpy (err_msg_pos_p, PARSE_ERR_POS_END, PARSE_ERR_POS_END_SIZE);
2433-
2434-
error_value = ecma_raise_syntax_error (error_msg_p);
2435-
JMEM_FINALIZE_LOCAL_ARRAY (error_msg_p);
2385+
const lit_utf8_byte_t *err_bytes_p = (const lit_utf8_byte_t *) parser_error_to_string (parser_error.error);
2386+
lit_utf8_size_t err_bytes_size = lit_zt_utf8_string_size (err_bytes_p);
2387+
2388+
ecma_string_t *err_str_p = ecma_new_ecma_string_from_utf8 (err_bytes_p, err_bytes_size);
2389+
ecma_string_t *line_str_p = ecma_new_ecma_string_from_uint32 (parser_error.line);
2390+
ecma_string_t *col_str_p = ecma_new_ecma_string_from_uint32 (parser_error.column);
2391+
ecma_string_t *error_msg_p = ecma_format_ecma_strings ("% [line: %, column: %]",
2392+
err_str_p,
2393+
line_str_p,
2394+
col_str_p);
2395+
2396+
ecma_object_t *error_obj_p = ecma_new_standard_error_with_message (ECMA_ERROR_SYNTAX, error_msg_p);
2397+
ecma_value_t error_value = ecma_make_error_obj_value (error_obj_p);
2398+
2399+
ecma_deref_ecma_string (error_msg_p);
2400+
ecma_deref_ecma_string (col_str_p);
2401+
ecma_deref_ecma_string (line_str_p);
2402+
ecma_deref_ecma_string (err_str_p);
24362403

24372404
return error_value;
24382405
#else /* !JERRY_ENABLE_ERROR_MESSAGES */

jerry-core/vm/vm.c

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,24 @@ vm_op_get_value (ecma_value_t object, /**< base object */
9696

9797
if (unlikely (ecma_is_value_undefined (object) || ecma_is_value_null (object)))
9898
{
99-
return ecma_raise_type_error (ECMA_ERR_MSG ("Base object cannot be null or undefined."));
99+
#ifdef JERRY_ENABLE_ERROR_MESSAGES
100+
ecma_value_t obj_to_string_result = ecma_op_to_string (object);
101+
ecma_string_t *obj_name_p = ecma_get_string_from_value (obj_to_string_result);
102+
103+
ecma_value_t prop_to_string_result = ecma_op_to_string (property);
104+
ecma_string_t *prop_name_p = ecma_get_string_from_value (prop_to_string_result);
105+
106+
ecma_string_t *error_msg_p = ecma_format_ecma_strings ("Cannot read property '%' of %", prop_name_p, obj_name_p);
107+
ecma_object_t *error_obj_p = ecma_new_standard_error_with_message (ECMA_ERROR_TYPE, error_msg_p);
108+
ecma_value_t error_value = ecma_make_error_obj_value (error_obj_p);
109+
110+
ecma_deref_ecma_string (error_msg_p);
111+
ecma_deref_ecma_string (prop_name_p);
112+
ecma_deref_ecma_string (obj_name_p);
113+
#else /* !JERRY_ENABLE_ERROR_MESSAGES */
114+
ecma_value_t error_value = ecma_raise_type_error (NULL);
115+
#endif /* JERRY_ENABLE_ERROR_MESSAGES */
116+
return error_value;
100117
}
101118

102119
ecma_value_t prop_to_string_result = ecma_op_to_string (property);
@@ -136,8 +153,29 @@ vm_op_set_value (ecma_value_t object, /**< base object */
136153

137154
if (ECMA_IS_VALUE_ERROR (to_object))
138155
{
156+
ecma_free_value (to_object);
157+
158+
#ifdef JERRY_ENABLE_ERROR_MESSAGES
159+
ecma_value_t obj_to_string_result = ecma_op_to_string (object);
160+
ecma_string_t *obj_name_p = ecma_get_string_from_value (obj_to_string_result);
161+
162+
ecma_value_t prop_to_string_result = ecma_op_to_string (property);
163+
ecma_string_t *prop_name_p = ecma_get_string_from_value (prop_to_string_result);
164+
165+
ecma_string_t *error_msg_p = ecma_format_ecma_strings ("Cannot set property '%' of %", prop_name_p, obj_name_p);
166+
ecma_object_t *error_obj_p = ecma_new_standard_error_with_message (ECMA_ERROR_TYPE, error_msg_p);
167+
ecma_value_t error_value = ecma_make_error_obj_value (error_obj_p);
168+
169+
ecma_deref_ecma_string (error_msg_p);
170+
ecma_deref_ecma_string (prop_name_p);
171+
ecma_deref_ecma_string (obj_name_p);
172+
#else /* !JERRY_ENABLE_ERROR_MESSAGES */
173+
ecma_value_t error_value = ecma_raise_type_error (NULL);
174+
#endif /* JERRY_ENABLE_ERROR_MESSAGES */
175+
139176
ecma_free_value (property);
140-
return to_object;
177+
178+
return error_value;
141179
}
142180

143181
object = to_object;
@@ -1076,16 +1114,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
10761114
ref_base_lex_env_p = ecma_op_resolve_reference_base (frame_ctx_p->lex_env_p,
10771115
name_p);
10781116

1079-
if (ref_base_lex_env_p != NULL)
1080-
{
1081-
result = ecma_op_get_value_lex_env_base (ref_base_lex_env_p,
1082-
name_p,
1083-
is_strict);
1084-
}
1085-
else
1086-
{
1087-
result = ecma_raise_reference_error (ECMA_ERR_MSG ("Cannot resolve reference."));
1088-
}
1117+
result = ecma_op_get_value_lex_env_base (ref_base_lex_env_p,
1118+
name_p,
1119+
is_strict);
10891120

10901121
if (ECMA_IS_VALUE_ERROR (result))
10911122
{

0 commit comments

Comments
 (0)