From 4b352758c111d89901a8d6cd930279988dabd5a6 Mon Sep 17 00:00:00 2001 From: Szilagyi Adam Date: Fri, 25 Oct 2019 15:58:47 +0200 Subject: [PATCH] Refactor ecma_op_to_string (#3171) Similar to the ecma_op_to_object rework, in this new method we return directly with the pointer to the ecma string, and we don't wrap the result into an ecma_value_t JerryScript-DCO-1.0-Signed-off-by: Adam Szilagyi aszilagy@inf.u-szeged.hu --- jerry-core/api/jerry-snapshot.c | 5 +- jerry-core/api/jerry.c | 8 +- jerry-core/debugger/debugger.c | 22 +-- .../ecma-builtin-array-prototype.c | 64 ++++---- .../ecma/builtin-objects/ecma-builtin-date.c | 12 +- .../ecma-builtin-error-prototype.c | 55 +++---- .../builtin-objects/ecma-builtin-function.c | 36 ++--- .../builtin-objects/ecma-builtin-global.c | 8 +- .../ecma-builtin-helpers-error.c | 16 +- .../builtin-objects/ecma-builtin-helpers.c | 111 ++++++++------ .../ecma/builtin-objects/ecma-builtin-json.c | 38 +++-- .../ecma-builtin-regexp-prototype.c | 30 ++-- .../builtin-objects/ecma-builtin-regexp.c | 21 ++- .../ecma-builtin-string-prototype.c | 137 +++++++++--------- .../builtin-objects/ecma-builtin-string.c | 8 +- .../builtin-objects/ecma-builtin-symbol.c | 10 +- .../ecma-builtin-typedarray-prototype.c | 135 +++++++++-------- jerry-core/ecma/operations/ecma-conversion.c | 37 +---- jerry-core/ecma/operations/ecma-conversion.h | 2 +- jerry-core/ecma/operations/ecma-exceptions.c | 4 +- .../ecma/operations/ecma-regexp-object.c | 25 +--- .../ecma/operations/ecma-regexp-object.h | 2 +- .../ecma/operations/ecma-string-object.c | 8 +- .../ecma/operations/ecma-symbol-object.c | 8 +- jerry-core/vm/opcodes-ecma-arithmetics.c | 16 +- 25 files changed, 391 insertions(+), 427 deletions(-) diff --git a/jerry-core/api/jerry-snapshot.c b/jerry-core/api/jerry-snapshot.c index ce12cb2f5..f16f3b0e7 100644 --- a/jerry-core/api/jerry-snapshot.c +++ b/jerry-core/api/jerry-snapshot.c @@ -292,10 +292,11 @@ static_snapshot_error_unsupported_literal (snapshot_globals_t *globals_p, /**< s ecma_string_t *error_message_p = ecma_new_ecma_string_from_utf8 (error_prefix, sizeof (error_prefix) - 1); - literal = ecma_op_to_string (literal); JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (literal)); - ecma_string_t *literal_string_p = ecma_get_string_from_value (literal); + ecma_string_t *literal_string_p = ecma_op_to_string (literal); + JERRY_ASSERT (literal_string_p != NULL); + error_message_p = ecma_concat_ecma_strings (error_message_p, literal_string_p); ecma_deref_ecma_string (literal_string_p); diff --git a/jerry-core/api/jerry.c b/jerry-core/api/jerry.c index e691fc342..5257edb64 100644 --- a/jerry-core/api/jerry.c +++ b/jerry-core/api/jerry.c @@ -1288,7 +1288,13 @@ jerry_value_to_string (const jerry_value_t value) /**< input value */ return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (error_value_msg_p))); } - return jerry_return (ecma_op_to_string (value)); + ecma_string_t *str_p = ecma_op_to_string (value); + if (JERRY_UNLIKELY (str_p == NULL)) + { + return ecma_create_error_reference_from_context (); + } + + return jerry_return (ecma_make_string_value (str_p)); } /* jerry_value_to_string */ /** diff --git a/jerry-core/debugger/debugger.c b/jerry-core/debugger/debugger.c index 02ea6875d..7fe458baf 100644 --- a/jerry-core/debugger/debugger.c +++ b/jerry-core/debugger/debugger.c @@ -508,22 +508,22 @@ jerry_debugger_send_scope_variables (const uint8_t *recv_buffer_p) /**< pointer ecma_deref_ecma_string (prop_name); ecma_property_value_t prop_value_p = prop_pair_p->values[i]; - ecma_value_t property_value; uint8_t variable_type = jerry_debugger_get_variable_type (prop_value_p.value); - property_value = ecma_op_to_string (prop_value_p.value); + ecma_string_t *str_p = ecma_op_to_string (prop_value_p.value); + JERRY_ASSERT (str_p != NULL); if (!jerry_debugger_copy_variables_to_string_message (variable_type, - ecma_get_string_from_value (property_value), + str_p, message_string_p, &buffer_pos)) { - ecma_free_value (property_value); + ecma_deref_ecma_string (str_p); return; } - ecma_free_value (property_value); + ecma_deref_ecma_string (str_p); } } @@ -581,7 +581,8 @@ jerry_debugger_send_eval (const lit_utf8_byte_t *eval_string_p, /**< evaluated s if (!ecma_is_value_string (result)) { - ecma_value_t to_string_value = ecma_op_to_string (result); + ecma_string_t *str_p = ecma_op_to_string (result); + ecma_value_t to_string_value = ecma_make_string_value (str_p); ecma_free_value (result); result = to_string_value; } @@ -618,8 +619,10 @@ jerry_debugger_send_eval (const lit_utf8_byte_t *eval_string_p, /**< evaluated s else { /* Primitive type. */ - message = ecma_op_to_string (result); - JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (message)); + ecma_string_t *str_p = ecma_op_to_string (result); + JERRY_ASSERT (str_p != NULL); + + message = ecma_make_string_value (str_p); } ecma_free_value (result); @@ -1543,8 +1546,7 @@ jerry_debugger_send_exception_string (void) } else { - exception_value = ecma_op_to_string (exception_value); - string_p = ecma_get_string_from_value (exception_value); + string_p = ecma_op_to_string (exception_value); } ECMA_STRING_TO_UTF8_STRING (string_p, string_data_p, string_size); diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c index 6f5bcaf34..8799e0093 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c @@ -282,16 +282,16 @@ ecma_builtin_array_prototype_object_concat (const ecma_value_t args[], /**< argu * See also: * ECMA-262 v5.1, 15.4.4.2 4th step * - * @return ecma value - * Returned value must be freed with ecma_free_value. + * @return NULL - if the conversion fails + * ecma_string_t * - otherwise */ -static ecma_value_t +static ecma_string_t * ecma_op_array_get_separator_string (ecma_value_t separator) /**< possible separator */ { if (ecma_is_value_undefined (separator)) { - return ecma_make_magic_string_value (LIT_MAGIC_STRING_COMMA_CHAR); + return ecma_get_magic_string (LIT_MAGIC_STRING_COMMA_CHAR); } return ecma_op_to_string (separator); @@ -303,10 +303,10 @@ ecma_op_array_get_separator_string (ecma_value_t separator) /**< possible separa * See also: * ECMA-262 v5.1, 15.4.4.2 * - * @return ecma_value_t value - * Returned value must be freed with ecma_free_value. + * @return NULL - if the conversion fails + * ecma_string_t * - otherwise */ -static ecma_value_t +static ecma_string_t * ecma_op_array_get_to_string_at_index (ecma_object_t *obj_p, /**< this object */ uint32_t index) /**< array index */ { @@ -318,20 +318,20 @@ ecma_op_array_get_to_string_at_index (ecma_object_t *obj_p, /**< this object */ if (ECMA_IS_VALUE_ERROR (index_value)) { - return index_value; + return NULL; } if (ecma_is_value_undefined (index_value) || ecma_is_value_null (index_value)) { - return ecma_make_magic_string_value (LIT_MAGIC_STRING__EMPTY); + return ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY); } - ecma_value_t ret_value = ecma_op_to_string (index_value); + ecma_string_t *ret_str_p = ecma_op_to_string (index_value); ecma_free_value (index_value); - return ret_value; + return ret_str_p; } /* ecma_op_array_get_to_string_at_index */ /** @@ -349,15 +349,13 @@ ecma_builtin_array_prototype_join (ecma_value_t separator_arg, /**< separator ar uint32_t length) /**< array object's length */ { /* 4-5. */ - ecma_value_t separator_value = ecma_op_array_get_separator_string (separator_arg); + ecma_string_t *separator_string_p = ecma_op_array_get_separator_string (separator_arg); - if (ECMA_IS_VALUE_ERROR (separator_value)) + if (JERRY_UNLIKELY (separator_string_p == NULL)) { - return separator_value; + return ECMA_VALUE_ERROR; } - ecma_string_t *separator_string_p = ecma_get_string_from_value (separator_value); - if (length == 0) { /* 6. */ @@ -366,15 +364,14 @@ ecma_builtin_array_prototype_join (ecma_value_t separator_arg, /**< separator ar } /* 7-8. */ - ecma_value_t first_value = ecma_op_array_get_to_string_at_index (obj_p, 0); + ecma_string_t *first_string_p = ecma_op_array_get_to_string_at_index (obj_p, 0); - if (ECMA_IS_VALUE_ERROR (first_value)) + if (JERRY_UNLIKELY (first_string_p == NULL)) { ecma_deref_ecma_string (separator_string_p); - return first_value; + return ECMA_VALUE_ERROR; } - ecma_string_t *first_string_p = ecma_get_string_from_value (first_value); ecma_stringbuilder_t builder = ecma_stringbuilder_create_from (first_string_p); ecma_deref_ecma_string (first_string_p); @@ -384,18 +381,16 @@ ecma_builtin_array_prototype_join (ecma_value_t separator_arg, /**< separator ar /* 10.a */ ecma_stringbuilder_append (&builder, separator_string_p); - /* 10.b, 10.c */ - ecma_value_t next_string_value = ecma_op_array_get_to_string_at_index (obj_p, k); + /* 10.d */ + ecma_string_t *next_string_p = ecma_op_array_get_to_string_at_index (obj_p, k); - if (ECMA_IS_VALUE_ERROR (next_string_value)) + if (JERRY_UNLIKELY (next_string_p == NULL)) { ecma_deref_ecma_string (separator_string_p); ecma_stringbuilder_destroy (&builder); - return next_string_value; + return ECMA_VALUE_ERROR; } - /* 10.d */ - ecma_string_t *next_string_p = ecma_get_string_from_value (next_string_value); ecma_stringbuilder_append (&builder, next_string_p); ecma_deref_ecma_string (next_string_p); } @@ -882,24 +877,19 @@ ecma_builtin_array_prototype_object_sort_compare_helper (ecma_value_t lhs, /**< if (ecma_is_value_undefined (compare_func)) { /* Default comparison when no compare_func is passed. */ - ecma_value_t lhs_value = ecma_op_to_string (lhs); - - if (ECMA_IS_VALUE_ERROR (lhs_value)) + ecma_string_t *lhs_str_p = ecma_op_to_string (lhs); + if (JERRY_UNLIKELY (lhs_str_p == NULL)) { - return lhs_value; + return ECMA_VALUE_ERROR; } - ecma_string_t *lhs_str_p = ecma_get_string_from_value (lhs_value); - ecma_value_t rhs_value = ecma_op_to_string (rhs); - - if (ECMA_IS_VALUE_ERROR (rhs_value)) + ecma_string_t *rhs_str_p = ecma_op_to_string (rhs); + if (JERRY_UNLIKELY (rhs_str_p == NULL)) { ecma_deref_ecma_string (lhs_str_p); - return rhs_value; + return ECMA_VALUE_ERROR; } - ecma_string_t *rhs_str_p = ecma_get_string_from_value (rhs_value); - if (ecma_compare_ecma_strings_relational (lhs_str_p, rhs_str_p)) { result = ECMA_NUMBER_MINUS_ONE; diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-date.c b/jerry-core/ecma/builtin-objects/ecma-builtin-date.c index 615737a33..b3bb3a31e 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-date.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-date.c @@ -187,11 +187,11 @@ ecma_builtin_date_parse (ecma_value_t this_arg, /**< this argument */ ecma_number_t date_num = ecma_number_make_nan (); /* Date Time String fromat (ECMA-262 v5, 15.9.1.15) */ - ECMA_TRY_CATCH (date_str_value, - ecma_op_to_string (arg), - ret_value); - - ecma_string_t *date_str_p = ecma_get_string_from_value (date_str_value); + ecma_string_t *date_str_p = ecma_op_to_string (arg); + if (JERRY_UNLIKELY (date_str_p == NULL)) + { + return ECMA_VALUE_ERROR; + } ECMA_STRING_TO_UTF8_STRING (date_str_p, date_start_p, date_start_size); @@ -403,7 +403,7 @@ ecma_builtin_date_parse (ecma_value_t this_arg, /**< this argument */ ret_value = ecma_make_number_value (date_num); ECMA_FINALIZE_UTF8_STRING (date_start_p, date_start_size); - ECMA_FINALIZE (date_str_value); + ecma_deref_ecma_string (date_str_p); return ret_value; } /* ecma_builtin_date_parse */ diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-error-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-error-prototype.c index 69312ed34..d4e4eeb50 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-error-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-error-prototype.c @@ -60,57 +60,64 @@ ecma_builtin_error_prototype_object_to_string (ecma_value_t this_arg) /**< this /* 2. */ if (!ecma_is_value_object (this_arg)) { - ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Argument 'this' is not an object.")); + return ecma_raise_type_error (ECMA_ERR_MSG ("Argument 'this' is not an object.")); } else { ecma_object_t *obj_p = ecma_get_object_from_value (this_arg); - ECMA_TRY_CATCH (name_get_ret_value, - ecma_op_object_get_by_magic_id (obj_p, LIT_MAGIC_STRING_NAME), - ret_value); + ecma_value_t name_get_ret_value = ecma_op_object_get_by_magic_id (obj_p, LIT_MAGIC_STRING_NAME); + if (ECMA_IS_VALUE_ERROR (name_get_ret_value)) + { + return name_get_ret_value; + } - ecma_value_t name_to_str_completion; + ecma_string_t *name_string_p; if (ecma_is_value_undefined (name_get_ret_value)) { - name_to_str_completion = ecma_make_magic_string_value (LIT_MAGIC_STRING_ERROR_UL); + name_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_ERROR_UL); } else { - name_to_str_completion = ecma_op_to_string (name_get_ret_value); + name_string_p = ecma_op_to_string (name_get_ret_value); } - if (JERRY_UNLIKELY (ECMA_IS_VALUE_ERROR (name_to_str_completion))) + ecma_free_value (name_get_ret_value); + + if (JERRY_UNLIKELY (name_string_p == NULL)) { - ret_value = ecma_copy_value (name_to_str_completion); + return ECMA_VALUE_ERROR; } else { - ECMA_TRY_CATCH (msg_get_ret_value, - ecma_op_object_get_by_magic_id (obj_p, LIT_MAGIC_STRING_MESSAGE), - ret_value); + ecma_value_t msg_get_ret_value = ecma_op_object_get_by_magic_id (obj_p, LIT_MAGIC_STRING_MESSAGE); + if (ECMA_IS_VALUE_ERROR (msg_get_ret_value)) + { + ecma_deref_ecma_string (name_string_p); + return msg_get_ret_value; + } - ecma_value_t msg_to_str_completion; + ecma_string_t *msg_string_p; if (ecma_is_value_undefined (msg_get_ret_value)) { - msg_to_str_completion = ecma_make_magic_string_value (LIT_MAGIC_STRING__EMPTY); + msg_string_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY); } else { - msg_to_str_completion = ecma_op_to_string (msg_get_ret_value); + msg_string_p = ecma_op_to_string (msg_get_ret_value); } - if (JERRY_UNLIKELY (ECMA_IS_VALUE_ERROR (msg_to_str_completion))) + ecma_free_value (msg_get_ret_value); + + if (JERRY_UNLIKELY (msg_string_p == NULL)) { - ret_value = ecma_copy_value (msg_to_str_completion); + ecma_deref_ecma_string (name_string_p); + return ECMA_VALUE_ERROR; } else { - ecma_string_t *name_string_p = ecma_get_string_from_value (name_to_str_completion); - ecma_string_t *msg_string_p = ecma_get_string_from_value (msg_to_str_completion); - ecma_string_t *ret_str_p; if (ecma_string_is_empty (name_string_p)) @@ -163,14 +170,10 @@ ecma_builtin_error_prototype_object_to_string (ecma_value_t this_arg) /**< this ret_value = ecma_make_string_value (ret_str_p); } - ecma_free_value (msg_to_str_completion); - - ECMA_FINALIZE (msg_get_ret_value); + ecma_deref_ecma_string (msg_string_p); } - ecma_free_value (name_to_str_completion); - - ECMA_FINALIZE (name_get_ret_value); + ecma_deref_ecma_string (name_string_p); } return ret_value; diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-function.c b/jerry-core/ecma/builtin-objects/ecma-builtin-function.c index 1553aa65f..52468255e 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-function.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-function.c @@ -79,38 +79,39 @@ ecma_builtin_function_helper_get_function_arguments (const ecma_value_t *argumen return ecma_make_magic_string_value (LIT_MAGIC_STRING__EMPTY); } - ecma_value_t final_str = ecma_op_to_string (arguments_list_p[0]); + ecma_string_t *final_str_p = ecma_op_to_string (arguments_list_p[0]); - if (arguments_list_len == 2 || ECMA_IS_VALUE_ERROR (final_str)) + if (JERRY_UNLIKELY (final_str_p == NULL)) { - return final_str; + return ECMA_VALUE_ERROR; + } + + if (arguments_list_len == 2) + { + return ecma_make_string_value (final_str_p); } for (ecma_length_t idx = 1; idx < arguments_list_len - 1; idx++) { - ecma_value_t new_str = ecma_op_to_string (arguments_list_p[idx]); + ecma_string_t *new_str_p = ecma_op_to_string (arguments_list_p[idx]); - if (ECMA_IS_VALUE_ERROR (new_str)) + if (JERRY_UNLIKELY (new_str_p == NULL)) { - ecma_free_value (final_str); + ecma_deref_ecma_string (final_str_p); /* Return with the error. */ - final_str = new_str; + final_str_p = new_str_p; break; } - ecma_string_t *final_str_p = ecma_get_string_from_value (final_str); final_str_p = ecma_append_magic_string_to_string (final_str_p, LIT_MAGIC_STRING_COMMA_CHAR); - ecma_string_t *new_str_p = ecma_get_string_from_value (new_str); final_str_p = ecma_concat_ecma_strings (final_str_p, new_str_p); ecma_deref_ecma_string (new_str_p); - - final_str = ecma_make_string_value (final_str_p); } - return final_str; + return ecma_make_string_value (final_str_p); } /* ecma_builtin_function_helper_get_function_arguments */ /** @@ -135,26 +136,25 @@ ecma_builtin_function_dispatch_construct (const ecma_value_t *arguments_list_p, return arguments_value; } - ecma_value_t function_body_value; + ecma_string_t *function_body_str_p; if (arguments_list_len > 0) { - function_body_value = ecma_op_to_string (arguments_list_p[arguments_list_len - 1]); + function_body_str_p = ecma_op_to_string (arguments_list_p[arguments_list_len - 1]); - if (ECMA_IS_VALUE_ERROR (function_body_value)) + if (JERRY_UNLIKELY (function_body_str_p == NULL)) { ecma_free_value (arguments_value); - return function_body_value; + return ECMA_VALUE_ERROR; } } else { /* Very unlikely code path, not optimized. */ - function_body_value = ecma_make_magic_string_value (LIT_MAGIC_STRING__EMPTY); + function_body_str_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY); } ecma_string_t *arguments_str_p = ecma_get_string_from_value (arguments_value); - ecma_string_t *function_body_str_p = ecma_get_string_from_value (function_body_value); ECMA_STRING_TO_UTF8_STRING (arguments_str_p, arguments_buffer_p, arguments_buffer_size); ECMA_STRING_TO_UTF8_STRING (function_body_str_p, function_body_buffer_p, function_body_buffer_size); diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-global.c b/jerry-core/ecma/builtin-objects/ecma-builtin-global.c index 027dd2073..f4aad0c98 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-global.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-global.c @@ -1185,15 +1185,13 @@ ecma_builtin_global_dispatch_routine (uint16_t builtin_routine_id, /**< built-in return ecma_builtin_global_object_is_finite (arg_num); } - ecma_value_t string_value = ecma_op_to_string (routine_arg_1); + ecma_string_t *str_p = ecma_op_to_string (routine_arg_1); - if (ECMA_IS_VALUE_ERROR (string_value)) + if (JERRY_UNLIKELY (str_p == NULL)) { - return string_value; + return ECMA_VALUE_ERROR; } - ecma_string_t *str_p = ecma_get_string_from_value (string_value); - ecma_value_t ret_value; if (builtin_routine_id <= ECMA_GLOBAL_PARSE_FLOAT) diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-error.c b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-error.c index c97af8c37..9e2ce6214 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-error.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-error.c @@ -47,20 +47,18 @@ ecma_builtin_helper_error_dispatch_call (ecma_standard_error_t error_type, /**< if (arguments_list_len != 0 && !ecma_is_value_undefined (arguments_list_p[0])) { - ecma_value_t ret_value = ECMA_VALUE_EMPTY; + ecma_string_t *message_string_p = ecma_op_to_string (arguments_list_p[0]); - ECMA_TRY_CATCH (msg_str_value, - ecma_op_to_string (arguments_list_p[0]), - ret_value); + if (JERRY_UNLIKELY (message_string_p == NULL)) + { + return ECMA_VALUE_ERROR; + } - ecma_string_t *message_string_p = ecma_get_string_from_value (msg_str_value); ecma_object_t *new_error_object_p = ecma_new_standard_error_with_message (error_type, message_string_p); - ret_value = ecma_make_object_value (new_error_object_p); - ECMA_FINALIZE (msg_str_value); - - return ret_value; + ecma_deref_ecma_string (message_string_p); + return ecma_make_object_value (new_error_object_p); } else { diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.c b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.c index b544971f9..a1d18b6ce 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.c @@ -207,53 +207,73 @@ ecma_builtin_helper_get_to_locale_string_at_index (ecma_object_t *obj_p, /**< th { ecma_value_t ret_value = ECMA_VALUE_EMPTY; ecma_string_t *index_string_p = ecma_new_ecma_string_from_uint32 (index); + ecma_value_t index_value = ecma_op_object_get (obj_p, index_string_p); + ecma_deref_ecma_string (index_string_p); - ECMA_TRY_CATCH (index_value, - ecma_op_object_get (obj_p, index_string_p), - ret_value); + if (ECMA_IS_VALUE_ERROR (index_value)) + { + return index_value; + } if (ecma_is_value_undefined (index_value) || ecma_is_value_null (index_value)) { - ret_value = ecma_make_magic_string_value (LIT_MAGIC_STRING__EMPTY); + ecma_free_value (index_value); + return ecma_make_magic_string_value (LIT_MAGIC_STRING__EMPTY); + } + + ecma_value_t index_obj_value = ecma_op_to_object (index_value); + + ecma_free_value (index_value); + + if (ECMA_IS_VALUE_ERROR (index_obj_value)) + { + return index_obj_value; + } + + ecma_object_t *index_obj_p = ecma_get_object_from_value (index_obj_value); + ecma_value_t to_locale_value = ecma_op_object_get_by_magic_id (index_obj_p, LIT_MAGIC_STRING_TO_LOCALE_STRING_UL); + + if (ECMA_IS_VALUE_ERROR (to_locale_value)) + { + ecma_deref_object (index_obj_p); + return to_locale_value; + } + + if (ecma_op_is_callable (to_locale_value)) + { + ecma_object_t *locale_func_obj_p = ecma_get_object_from_value (to_locale_value); + + ecma_value_t call_value = ecma_op_function_call (locale_func_obj_p, + ecma_make_object_value (index_obj_p), + NULL, + 0); + + ecma_deref_object (locale_func_obj_p); + ecma_deref_object (index_obj_p); + + if (ECMA_IS_VALUE_ERROR (call_value)) + { + return call_value; + } + + ecma_string_t *call_str_p = ecma_op_to_string (call_value); + + ecma_free_value (call_value); + + if (JERRY_UNLIKELY (call_str_p == NULL)) + { + return ECMA_VALUE_ERROR; + } + + ret_value = ecma_make_string_value (call_str_p); } else { - ECMA_TRY_CATCH (index_obj_value, - ecma_op_to_object (index_value), - ret_value); - - ecma_object_t *index_obj_p = ecma_get_object_from_value (index_obj_value); - - ECMA_TRY_CATCH (to_locale_value, - ecma_op_object_get_by_magic_id (index_obj_p, LIT_MAGIC_STRING_TO_LOCALE_STRING_UL), - ret_value); - - if (ecma_op_is_callable (to_locale_value)) - { - ecma_object_t *locale_func_obj_p = ecma_get_object_from_value (to_locale_value); - ECMA_TRY_CATCH (call_value, - ecma_op_function_call (locale_func_obj_p, - ecma_make_object_value (index_obj_p), - NULL, - 0), - ret_value); - ret_value = ecma_op_to_string (call_value); - ECMA_FINALIZE (call_value); - - } - else - { - ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("'toLocaleString' is missing or not a function.")); - } - - ECMA_FINALIZE (to_locale_value); - ECMA_FINALIZE (index_obj_value); + ecma_free_value (to_locale_value); + ecma_deref_object (index_obj_p); + ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("'toLocaleString' is missing or not a function.")); } - ECMA_FINALIZE (index_value); - - ecma_deref_ecma_string (index_string_p); - return ret_value; } /* ecma_builtin_helper_get_to_locale_string_at_index */ @@ -570,16 +590,13 @@ ecma_builtin_helper_string_prototype_object_index_of (ecma_string_t *original_st } #endif /* ENABLED (JERRY_ES2015_BUILTIN) */ - /* 3 */ - ecma_value_t search_str_val = ecma_op_to_string (arg1); - - if (ECMA_IS_VALUE_ERROR (search_str_val)) - { - return search_str_val; - } - /* 7, 8 */ - ecma_string_t *search_str_p = ecma_get_string_from_value (search_str_val); + ecma_string_t *search_str_p = ecma_op_to_string (arg1); + + if (JERRY_UNLIKELY (search_str_p == NULL)) + { + return ECMA_VALUE_ERROR; + } /* 4 (indexOf, lastIndexOf), 9 (startsWith, includes), 10 (endsWith) */ ecma_number_t pos_num; diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-json.c b/jerry-core/ecma/builtin-objects/ecma-builtin-json.c index 494a61612..6b47b9757 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-json.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-json.c @@ -738,15 +738,13 @@ ecma_builtin_json_parse (ecma_value_t this_arg, /**< 'this' argument */ { JERRY_UNUSED (this_arg); - ecma_value_t text_value = ecma_op_to_string (arg1); + ecma_string_t *text_string_p = ecma_op_to_string (arg1); - if (ECMA_IS_VALUE_ERROR (text_value)) + if (JERRY_UNLIKELY (text_string_p == NULL)) { - return text_value; + return ECMA_VALUE_ERROR; } - ecma_string_t *text_string_p = ecma_get_string_from_value (text_value); - ECMA_STRING_TO_UTF8_STRING (text_string_p, str_start_p, string_size); ecma_value_t result = ecma_builtin_json_parse_buffer (str_start_p, string_size); ECMA_FINALIZE_UTF8_STRING (str_start_p, string_size); @@ -1176,7 +1174,8 @@ ecma_builtin_json_serialize_property (ecma_json_stringify_context_t *context_p, /* 5.b */ else if (class_name == LIT_MAGIC_STRING_STRING_UL) { - result = ecma_op_to_string (value); + ecma_string_t *str_p = ecma_op_to_string (value); + result = ecma_make_string_value (str_p); } /* 5.c */ else if (class_name == LIT_MAGIC_STRING_BOOLEAN_UL) @@ -1236,9 +1235,8 @@ ecma_builtin_json_serialize_property (ecma_json_stringify_context_t *context_p, /* 10.a */ if (!ecma_number_is_nan (num_value) && !ecma_number_is_infinity (num_value)) { - ecma_value_t result_value = ecma_op_to_string (value); - JERRY_ASSERT (ecma_is_value_string (result_value)); - ecma_string_t *result_string_p = ecma_get_string_from_value (result_value); + ecma_string_t *result_string_p = ecma_op_to_string (value); + JERRY_ASSERT (result_string_p != NULL); ecma_stringbuilder_append (&context_p->result_builder, result_string_p); ecma_deref_ecma_string (result_string_p); @@ -1406,25 +1404,25 @@ ecma_builtin_json_stringify (ecma_value_t this_arg, /**< 'this' argument */ /* 4.b.iii.5.e */ else if (ecma_is_value_number (value)) { - ecma_value_t number_str_value = ecma_op_to_string (value); - JERRY_ASSERT (ecma_is_value_string (number_str_value)); - item = number_str_value; + ecma_string_t *number_str_p = ecma_op_to_string (value); + JERRY_ASSERT (number_str_p != NULL); + item = ecma_make_string_value (number_str_p); } /* 4.b.iii.5.f */ else if (ecma_is_value_object (value) && (ecma_object_get_class_name (ecma_get_object_from_value (value)) == LIT_MAGIC_STRING_NUMBER_UL || ecma_object_get_class_name (ecma_get_object_from_value (value)) == LIT_MAGIC_STRING_STRING_UL)) { - ecma_value_t str_val = ecma_op_to_string (value); + ecma_string_t *str_p = ecma_op_to_string (value); - if (ECMA_IS_VALUE_ERROR (str_val)) + if (JERRY_UNLIKELY (str_p == NULL)) { ecma_collection_free (context.property_list_p); ecma_free_value (value); - return str_val; + return ECMA_VALUE_ERROR; } - item = str_val; + item = ecma_make_string_value (str_p); } ecma_free_value (value); @@ -1474,15 +1472,15 @@ ecma_builtin_json_stringify (ecma_value_t this_arg, /**< 'this' argument */ /* 5.b */ else if (class_name == LIT_MAGIC_STRING_STRING_UL) { - ecma_value_t value = ecma_op_to_string (arg3); + ecma_string_t *value_str_p = ecma_op_to_string (arg3); - if (ECMA_IS_VALUE_ERROR (value)) + if (JERRY_UNLIKELY (value_str_p == NULL)) { ecma_collection_free (context.property_list_p); - return value; + return ECMA_VALUE_ERROR; } - space = value; + space = ecma_make_string_value (value_str_p); } else { diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-regexp-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-regexp-prototype.c index 74de58d72..d5ca38fdb 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-regexp-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-regexp-prototype.c @@ -284,29 +284,27 @@ ecma_builtin_regexp_prototype_compile (ecma_value_t this_arg, /**< this argument return ecma_copy_value (this_arg); } - ecma_string_t *pattern_string_p = NULL; + ecma_string_t *pattern_string_p = ecma_regexp_read_pattern_str_helper (pattern_arg); /* Get source string. */ - ecma_value_t ret_value = ecma_regexp_read_pattern_str_helper (pattern_arg, &pattern_string_p); - if (ECMA_IS_VALUE_ERROR (ret_value)) + if (pattern_string_p == NULL) { - JERRY_ASSERT (pattern_string_p == NULL); - return ret_value; + return ECMA_VALUE_ERROR; } - JERRY_ASSERT (ecma_is_value_empty (ret_value)); /* Parse flags. */ if (!ecma_is_value_undefined (flags_arg)) { - ecma_value_t flags_str_value = ecma_op_to_string (flags_arg); - if (ECMA_IS_VALUE_ERROR (flags_str_value)) + ecma_string_t *flags_str_p = ecma_op_to_string (flags_arg); + if (JERRY_UNLIKELY (flags_str_p == NULL)) { ecma_deref_ecma_string (pattern_string_p); - return flags_str_value; + return ECMA_VALUE_ERROR; } - ecma_value_t parsed_flags_val = ecma_regexp_parse_flags (ecma_get_string_from_value (flags_str_value), &flags); - ecma_free_value (flags_str_value); + ecma_value_t parsed_flags_val = ecma_regexp_parse_flags (flags_str_p, &flags); + ecma_deref_ecma_string (flags_str_p); + if (ECMA_IS_VALUE_ERROR (parsed_flags_val)) { ecma_deref_ecma_string (pattern_string_p); @@ -367,17 +365,17 @@ ecma_builtin_regexp_prototype_exec (ecma_value_t this_arg, /**< this argument */ return obj_this; } - ecma_value_t input_str_value = ecma_op_to_string (arg); - if (ECMA_IS_VALUE_ERROR (input_str_value)) + ecma_string_t *input_str_p = ecma_op_to_string (arg); + if (JERRY_UNLIKELY (input_str_p == NULL)) { ecma_free_value (obj_this); - return input_str_value; + return ECMA_VALUE_ERROR; } - ecma_value_t ret_value = ecma_regexp_exec_helper (obj_this, input_str_value, false); + ecma_value_t ret_value = ecma_regexp_exec_helper (obj_this, ecma_make_string_value (input_str_p), false); ecma_free_value (obj_this); - ecma_free_value (input_str_value); + ecma_deref_ecma_string (input_str_p); return ret_value; } /* ecma_builtin_regexp_prototype_exec */ diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-regexp.c b/jerry-core/ecma/builtin-objects/ecma-builtin-regexp.c index 592aec18b..1acaa59a2 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-regexp.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-regexp.c @@ -89,29 +89,28 @@ ecma_builtin_regexp_dispatch_construct (const ecma_value_t *arguments_list_p, /* return ecma_raise_type_error (ECMA_ERR_MSG ("Invalid argument of RegExp call.")); } - ecma_string_t *pattern_string_p = NULL; - ecma_value_t ret_value = ecma_regexp_read_pattern_str_helper (pattern_value, &pattern_string_p); - if (ECMA_IS_VALUE_ERROR (ret_value)) + ecma_string_t *pattern_string_p = ecma_regexp_read_pattern_str_helper (pattern_value); + + if (pattern_string_p == NULL) { - return ret_value; + return ECMA_VALUE_ERROR; } - JERRY_ASSERT (ecma_is_value_empty (ret_value)); uint16_t flags = 0; + ecma_value_t ret_value = ECMA_VALUE_EMPTY; + if (!ecma_is_value_undefined (flags_value)) { - ecma_value_t flags_str_value = ecma_op_to_string (flags_value); + ecma_string_t *flags_string_p = ecma_op_to_string (flags_value); - if (ECMA_IS_VALUE_ERROR (flags_str_value)) + if (JERRY_UNLIKELY (flags_string_p == NULL)) { ecma_deref_ecma_string (pattern_string_p); - return flags_str_value; + return ECMA_VALUE_ERROR; } - ecma_string_t *flags_string_p = ecma_get_string_from_value (flags_str_value); - JERRY_ASSERT (flags_string_p != NULL); ret_value = ecma_regexp_parse_flags (flags_string_p, &flags); - ecma_free_value (flags_str_value); // implicit frees flags_string_p + ecma_deref_ecma_string (flags_string_p); if (ECMA_IS_VALUE_ERROR (ret_value)) { diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.c index f227662db..94b49a7ec 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.c @@ -156,24 +156,22 @@ ecma_builtin_string_prototype_char_at_helper (ecma_value_t this_arg, /**< this a { return to_num_result; } - ecma_free_value (to_num_result); /* 2 */ - ecma_value_t to_string_val = ecma_op_to_string (this_arg); - if (ECMA_IS_VALUE_ERROR (to_string_val)) + ecma_string_t *original_string_p = ecma_op_to_string (this_arg); + if (JERRY_UNLIKELY (original_string_p == NULL)) { - return to_string_val; + return ECMA_VALUE_ERROR; } /* 4 */ - ecma_string_t *original_string_p = ecma_get_string_from_value (to_string_val); const ecma_length_t len = ecma_string_get_length (original_string_p); /* 5 */ // When index_num is NaN, then the first two comparisons are false if (index_num < 0 || index_num >= len || (ecma_number_is_nan (index_num) && len == 0)) { - ecma_free_value (to_string_val); + ecma_deref_ecma_string (original_string_p); return (charcode_mode ? ecma_make_nan_value () : ecma_make_magic_string_value (LIT_MAGIC_STRING__EMPTY)); } @@ -188,7 +186,7 @@ ecma_builtin_string_prototype_char_at_helper (ecma_value_t this_arg, /**< this a JERRY_ASSERT (ecma_number_is_nan (index_num) || ecma_number_to_uint32 (index_num) == ecma_number_trunc (index_num)); ecma_char_t new_ecma_char = ecma_string_get_char_at_pos (original_string_p, ecma_number_to_uint32 (index_num)); - ecma_free_value (to_string_val); + ecma_deref_ecma_string (original_string_p); return (charcode_mode ? ecma_make_uint32_value (new_ecma_char) : ecma_make_string_value (ecma_new_ecma_string_from_code_unit (new_ecma_char))); @@ -215,15 +213,14 @@ ecma_builtin_string_prototype_object_concat (ecma_string_t *this_string_p, /**< for (uint32_t arg_index = 0; arg_index < arguments_number; ++arg_index) { /* 5a, b */ - ecma_value_t get_arg_string = ecma_op_to_string (argument_list_p[arg_index]); + ecma_string_t *get_arg_string_p = ecma_op_to_string (argument_list_p[arg_index]); - if (ECMA_IS_VALUE_ERROR (get_arg_string)) + if (JERRY_UNLIKELY (get_arg_string_p == NULL)) { ecma_deref_ecma_string (string_to_return); - return get_arg_string; + return ECMA_VALUE_ERROR; } - ecma_string_t *get_arg_string_p = ecma_get_string_from_value (get_arg_string); string_to_return = ecma_concat_ecma_strings (string_to_return, get_arg_string_p); ecma_deref_ecma_string (get_arg_string_p); @@ -247,15 +244,13 @@ ecma_builtin_string_prototype_object_locale_compare (ecma_string_t *this_string_ ecma_value_t arg) /**< routine's argument */ { /* 3. */ - ecma_value_t arg_to_string_val = ecma_op_to_string (arg); + ecma_string_t *arg_string_p = ecma_op_to_string (arg); - if (ECMA_IS_VALUE_ERROR (arg_to_string_val)) + if (JERRY_UNLIKELY (arg_string_p == NULL)) { - return arg_to_string_val; + return ECMA_VALUE_ERROR; } - ecma_string_t *arg_string_p = ecma_get_string_from_value (arg_to_string_val); - ecma_number_t result = ECMA_NUMBER_ZERO; if (ecma_compare_ecma_strings_relational (this_string_p, arg_string_p)) @@ -273,7 +268,6 @@ ecma_builtin_string_prototype_object_locale_compare (ecma_string_t *this_string_ ecma_deref_ecma_string (arg_string_p); - return ecma_make_number_value (result); } /* ecma_builtin_string_prototype_object_locale_compare */ @@ -659,7 +653,7 @@ ecma_builtin_string_prototype_object_replace_get_string (ecma_builtin_replace_se ecma_value_t ret_value = ECMA_VALUE_EMPTY; ecma_object_t *match_object_p = ecma_get_object_from_value (match_value); - ecma_value_t match_length_value = ecma_op_object_get_by_magic_id (match_object_p, LIT_MAGIC_STRING_LENGTH); + ecma_value_t match_length_value = ecma_op_object_get_by_magic_id (match_object_p, LIT_MAGIC_STRING_LENGTH); if (ECMA_IS_VALUE_ERROR (match_length_value)) { @@ -670,12 +664,15 @@ ecma_builtin_string_prototype_object_replace_get_string (ecma_builtin_replace_se ecma_number_t match_length_number = ecma_get_number_from_value (match_length_value); ecma_length_t match_length = (ecma_length_t) (match_length_number); + ecma_free_number (match_length_value); JERRY_ASSERT ((ecma_length_t) ecma_number_to_uint32 (match_length_number) == match_length); JERRY_ASSERT (match_length >= 1); if (context_p->is_replace_callable) { + ret_value = ECMA_VALUE_ERROR; + JMEM_DEFINE_LOCAL_ARRAY (arguments_list, match_length + 2, ecma_value_t); @@ -684,46 +681,46 @@ ecma_builtin_string_prototype_object_replace_get_string (ecma_builtin_replace_se * uninitalized elements must not be freed. */ ecma_length_t values_copied = 0; - for (ecma_length_t i = 0; - (i < match_length) && ecma_is_value_empty (ret_value); - i++) + for (ecma_length_t i = 0; i < match_length; i++) { ecma_string_t *index_p = ecma_new_ecma_string_from_uint32 (i); - ECMA_TRY_CATCH (current_value, - ecma_op_object_get (match_object_p, index_p), - ret_value); - - arguments_list[i] = ecma_copy_value (current_value); - values_copied++; - - ECMA_FINALIZE (current_value); + ecma_value_t current_value = ecma_op_object_get (match_object_p, index_p); ecma_deref_ecma_string (index_p); + + if (ECMA_IS_VALUE_ERROR (current_value)) + { + goto cleanup; + } + + arguments_list[i] = current_value; + values_copied++; } - if (ecma_is_value_empty (ret_value)) + arguments_list[match_length] = ecma_make_uint32_value (context_p->match_start); + arguments_list[match_length + 1] = ecma_copy_value (context_p->input_string); + + ecma_value_t result_value = ecma_op_function_call (context_p->replace_function_p, + ECMA_VALUE_UNDEFINED, + arguments_list, + match_length + 2); + + ecma_free_value (arguments_list[match_length]); + ecma_free_value (arguments_list[match_length + 1]); + + if (ECMA_IS_VALUE_ERROR (result_value)) { - arguments_list[match_length] = ecma_make_uint32_value (context_p->match_start); - arguments_list[match_length + 1] = ecma_copy_value (context_p->input_string); - - ECMA_TRY_CATCH (result_value, - ecma_op_function_call (context_p->replace_function_p, - ECMA_VALUE_UNDEFINED, - arguments_list, - match_length + 2), - ret_value); - - ECMA_TRY_CATCH (to_string_value, - ecma_op_to_string (result_value), - ret_value); - - ret_value = ecma_copy_value (to_string_value); - - ECMA_FINALIZE (to_string_value); - ECMA_FINALIZE (result_value); - - ecma_free_value (arguments_list[match_length + 1]); + goto cleanup; } + ecma_string_t *to_string_p = ecma_op_to_string (result_value); + ecma_free_value (result_value); + + if (JERRY_UNLIKELY (to_string_p != NULL)) + { + ret_value = ecma_make_string_value (to_string_p); + } + +cleanup: for (ecma_length_t i = 0; i < values_copied; i++) { ecma_free_value (arguments_list[i]); @@ -926,8 +923,6 @@ ecma_builtin_string_prototype_object_replace_get_string (ecma_builtin_replace_se } } - ecma_free_number (match_length_value); - return ret_value; } /* ecma_builtin_string_prototype_object_replace_get_string */ @@ -1057,15 +1052,14 @@ ecma_builtin_string_prototype_object_replace_main (ecma_builtin_replace_search_c context_p->is_replace_callable = false; - ecma_value_t to_string_replace_val = ecma_op_to_string (replace_value); + ecma_string_t *replace_string_p = ecma_op_to_string (replace_value); - if (ECMA_IS_VALUE_ERROR (to_string_replace_val)) + if (JERRY_UNLIKELY (replace_string_p == NULL)) { - return to_string_replace_val; + return ECMA_VALUE_ERROR; } ecma_value_t ret_value; - ecma_string_t *replace_string_p = ecma_get_string_from_value (to_string_replace_val); ECMA_STRING_TO_UTF8_STRING (replace_string_p, replace_start_p, replace_start_size); @@ -1159,22 +1153,22 @@ ecma_builtin_string_prototype_object_replace (ecma_value_t to_string_value, /**< return ecma_builtin_string_prototype_object_replace_main (&context, replace_value); } - ecma_value_t to_string_search_val = ecma_op_to_string (search_value); + ecma_string_t *to_string_search_p = ecma_op_to_string (search_value); - if (ECMA_IS_VALUE_ERROR (to_string_search_val)) + if (JERRY_UNLIKELY (to_string_search_p == NULL)) { - return to_string_search_val; + return ECMA_VALUE_ERROR; } context.is_regexp = false; context.is_global = false; context.input_string = to_string_value; context.input_length = ecma_string_get_length (ecma_get_string_from_value (to_string_value)); - context.regexp_or_search_string = to_string_search_val; + context.regexp_or_search_string = ecma_make_string_value (to_string_search_p); ecma_value_t ret_value = ecma_builtin_string_prototype_object_replace_main (&context, replace_value); - ecma_deref_ecma_string (ecma_get_string_from_value (to_string_search_val)); + ecma_deref_ecma_string (to_string_search_p); return ret_value; } /* ecma_builtin_string_prototype_object_replace */ @@ -1378,13 +1372,15 @@ ecma_builtin_string_prototype_object_split (ecma_value_t this_to_string_val, /** } else { - ECMA_TRY_CATCH (separator_to_string_val, - ecma_op_to_string (arg1), - ret_value); + ecma_string_t *separator_to_string_p = ecma_op_to_string (arg1); - separator = ecma_copy_value (separator_to_string_val); + if (JERRY_UNLIKELY (separator_to_string_p == NULL)) + { + ecma_deref_object (new_array_p); + return ECMA_VALUE_ERROR; + } - ECMA_FINALIZE (separator_to_string_val); + separator = ecma_make_string_value (separator_to_string_p); } const ecma_string_t *this_to_string_p = ecma_get_string_from_value (this_to_string_val); @@ -2057,15 +2053,14 @@ ecma_builtin_string_prototype_dispatch_routine (uint16_t builtin_routine_id, /** builtin_routine_id == ECMA_STRING_PROTOTYPE_CHAR_CODE_AT); } - ecma_value_t to_string_val = ecma_op_to_string (this_arg); + ecma_string_t *string_p = ecma_op_to_string (this_arg); - if (ECMA_IS_VALUE_ERROR (to_string_val)) + if (JERRY_UNLIKELY (string_p == NULL)) { - return to_string_val; + return ECMA_VALUE_ERROR; } - ecma_string_t *string_p = ecma_get_string_from_value (to_string_val); - + ecma_value_t to_string_val = ecma_make_string_value (string_p); ecma_value_t ret_value = ECMA_VALUE_EMPTY; switch (builtin_routine_id) diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-string.c b/jerry-core/ecma/builtin-objects/ecma-builtin-string.c index 901b0a119..1c4faf42c 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-string.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-string.c @@ -140,7 +140,13 @@ ecma_builtin_string_dispatch_call (const ecma_value_t *arguments_list_p, /**< ar /* 2.b */ else { - ret_value = ecma_op_to_string (arguments_list_p[0]); + ecma_string_t *str_p = ecma_op_to_string (arguments_list_p[0]); + if (JERRY_UNLIKELY (str_p == NULL)) + { + return ECMA_VALUE_ERROR; + } + + ret_value = ecma_make_string_value (str_p); } return ret_value; diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-symbol.c b/jerry-core/ecma/builtin-objects/ecma-builtin-symbol.c index 446a184cd..6c5681193 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-symbol.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-symbol.c @@ -198,18 +198,16 @@ ecma_builtin_symbol_for (ecma_value_t this_arg, /**< this argument */ ecma_value_t key) /**< key string */ { JERRY_UNUSED (this_arg); - ecma_value_t string_desc = ecma_op_to_string (key); + ecma_string_t *string_desc_p = ecma_op_to_string (key); /* 1. */ - if (ECMA_IS_VALUE_ERROR (string_desc)) + if (JERRY_UNLIKELY (string_desc_p == NULL)) { /* 2. */ - return string_desc; + return ECMA_VALUE_ERROR; } - /* 4-7. */ - JERRY_ASSERT (ecma_is_value_string (string_desc)); - return ecma_builtin_symbol_for_helper (string_desc); + return ecma_builtin_symbol_for_helper (ecma_make_string_value (string_desc_p)); } /* ecma_builtin_symbol_for */ /** diff --git a/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-prototype.c b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-prototype.c index 74fea2da6..b49f4cbeb 100644 --- a/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-prototype.c +++ b/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-prototype.c @@ -1022,35 +1022,34 @@ ecma_builtin_typedarray_prototype_set (ecma_value_t this_arg, /**< this argument * See also: * ECMA-262 v5.1, 15.4.4.2 * - * @return ecma_value_t value - * Returned value must be freed with ecma_free_value. + * @return NULL - if the converison fails + * ecma_string_t * - otherwise */ -static ecma_value_t +static ecma_string_t * ecma_op_typedarray_get_to_string_at_index (ecma_object_t *obj_p, /**< this object */ uint32_t index) /**< array index */ { - ecma_value_t ret_value = ECMA_VALUE_EMPTY; ecma_string_t *index_string_p = ecma_new_ecma_string_from_uint32 (index); ecma_value_t index_value = ecma_op_object_get (obj_p, index_string_p); ecma_deref_ecma_string (index_string_p); if (ECMA_IS_VALUE_ERROR (index_value)) { - return index_value; + return NULL; } if (ecma_is_value_undefined (index_value) || ecma_is_value_null (index_value)) { - ret_value = ecma_make_magic_string_value (LIT_MAGIC_STRING__EMPTY); - } - else - { - ret_value = ecma_op_to_string (index_value); + ecma_free_value (index_value); + return ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY); } + ecma_string_t *ret_str_p = ecma_op_to_string (index_value); + ecma_free_value (index_value); - return ret_value; + + return ret_str_p; } /* ecma_op_typedarray_get_to_string_at_index */ /** @@ -1060,15 +1059,15 @@ ecma_op_typedarray_get_to_string_at_index (ecma_object_t *obj_p, /**< this objec * See also: * ECMA-262 v5.1, 15.4.4.2 4th step * - * @return ecma value - * Returned value must be freed with ecma_free_value. + * @return NULL - if the conversion fails + * ecma_string_t * - otherwise */ -static ecma_value_t +static ecma_string_t * ecma_op_typedarray_get_separator_string (ecma_value_t separator) /**< possible separator */ { if (ecma_is_value_undefined (separator)) { - return ecma_make_magic_string_value (LIT_MAGIC_STRING_COMMA_CHAR); + return ecma_get_magic_string (LIT_MAGIC_STRING_COMMA_CHAR); } return ecma_op_to_string (separator); @@ -1106,84 +1105,73 @@ ecma_builtin_typedarray_prototype_join (ecma_value_t this_arg, /**< this argumen return length_value; } - ecma_value_t ret_value = ECMA_VALUE_EMPTY; + ecma_number_t length_number; - ECMA_OP_TO_NUMBER_TRY_CATCH (length_number, - length_value, - ret_value); - - /* 3. */ - uint32_t length = ecma_number_to_uint32 (length_number); - /* 4-5. */ - ecma_value_t separator_value = ecma_op_typedarray_get_separator_string (separator_arg); - if (ECMA_IS_VALUE_ERROR (separator_value)) + if (ECMA_IS_VALUE_ERROR (ecma_get_number (length_value, &length_number))) { ecma_free_value (length_value); ecma_free_value (obj_value); - return separator_value; + return ECMA_VALUE_ERROR; } + ecma_value_t ret_value = ECMA_VALUE_ERROR; + + /* 3. */ + uint32_t length = ecma_number_to_uint32 (length_number); + if (length == 0) { /* 6. */ - ret_value = ecma_make_magic_string_value (LIT_MAGIC_STRING__EMPTY); + ecma_free_value (length_value); + ecma_free_value (obj_value); + return ecma_make_magic_string_value (LIT_MAGIC_STRING__EMPTY); } else { - ecma_string_t *separator_string_p = ecma_get_string_from_value (separator_value); + ecma_string_t *separator_string_p = ecma_op_typedarray_get_separator_string (separator_arg); + + if (JERRY_UNLIKELY (separator_string_p == NULL)) + { + goto cleanup; + } /* 7-8. */ - ecma_value_t first_value = ecma_op_typedarray_get_to_string_at_index (obj_p, 0); - if (ECMA_IS_VALUE_ERROR (first_value)) + ecma_string_t *return_string_p = ecma_op_typedarray_get_to_string_at_index (obj_p, 0); + + if (JERRY_UNLIKELY (return_string_p == NULL)) { - ecma_free_value (separator_value); - ecma_free_value (length_value); - ecma_free_value (obj_value); - return first_value; + ecma_deref_ecma_string (separator_string_p); + goto cleanup; } - ecma_string_t *return_string_p = ecma_get_string_from_value (first_value); - ecma_ref_ecma_string (return_string_p); - if (ecma_is_value_empty (ret_value)) + /* 9-10. */ + for (uint32_t k = 1; k < length; k++) { - /* 9-10. */ - for (uint32_t k = 1; k < length; k++) + /* 10.a */ + return_string_p = ecma_concat_ecma_strings (return_string_p, separator_string_p); + + /* 10.d */ + ecma_string_t *next_string_p = ecma_op_typedarray_get_to_string_at_index (obj_p, k); + + if (JERRY_UNLIKELY (next_string_p == NULL)) { - /* 10.a */ - return_string_p = ecma_concat_ecma_strings (return_string_p, separator_string_p); - - /* 10.b, 10.c */ - ecma_value_t next_string_value = ecma_op_typedarray_get_to_string_at_index (obj_p, k); - if (ECMA_IS_VALUE_ERROR (next_string_value)) - { - ecma_deref_ecma_string (return_string_p); - ecma_free_value (first_value); - ecma_free_value (separator_value); - ecma_free_value (length_value); - ecma_free_value (obj_value); - return next_string_value; - } - - /* 10.d */ - ecma_string_t *next_string_p = ecma_get_string_from_value (next_string_value); - return_string_p = ecma_concat_ecma_strings (return_string_p, next_string_p); - - ecma_free_value (next_string_value); + ecma_deref_ecma_string (separator_string_p); + ecma_deref_ecma_string (return_string_p); + goto cleanup; } - ret_value = ecma_make_string_value (return_string_p); - } - else - { - ecma_deref_ecma_string (return_string_p); + + return_string_p = ecma_concat_ecma_strings (return_string_p, next_string_p); + ecma_deref_ecma_string (next_string_p); } - ecma_free_value (first_value); + ecma_deref_ecma_string (separator_string_p); + ret_value = ecma_make_string_value (return_string_p); } - ecma_free_value (separator_value); - ECMA_OP_TO_NUMBER_FINALIZE (length_number); +cleanup: ecma_free_value (length_value); ecma_free_value (obj_value); + return ret_value; } /* ecma_builtin_typedarray_prototype_join */ @@ -2063,8 +2051,17 @@ ecma_builtin_typedarray_prototype_to_locale_string_helper (ecma_object_t *this_o return call_value; } - ret_value = ecma_op_to_string (call_value); - ecma_free_value (call_value); + ecma_string_t *str_p = ecma_op_to_string (call_value); + + if (JERRY_UNLIKELY (str_p == NULL)) + { + ecma_free_value (element_value); + ecma_deref_object (element_obj_p); + return ECMA_VALUE_ERROR; + } + + ret_value = ecma_make_string_value (str_p); + ecma_deref_ecma_string (str_p); } else { diff --git a/jerry-core/ecma/operations/ecma-conversion.c b/jerry-core/ecma/operations/ecma-conversion.c index 345d45362..1e56a7edb 100644 --- a/jerry-core/ecma/operations/ecma-conversion.c +++ b/jerry-core/ecma/operations/ecma-conversion.c @@ -430,16 +430,16 @@ ecma_get_number (ecma_value_t value, /**< ecma value*/ } /* ecma_get_number */ /** - * ToString operation helper function. + * ToString operation. * * See also: * ECMA-262 v5, 9.8 * * @return NULL - if the conversion fails - * ecma-string - otherwise + * pointer to the string descriptor - otherwise */ -static ecma_string_t * -ecma_to_op_string_helper (ecma_value_t value) /**< ecma value */ +ecma_string_t * +ecma_op_to_string (ecma_value_t value) /**< ecma value */ { ecma_check_value_type_is_spec_defined (value); @@ -452,7 +452,7 @@ ecma_to_op_string_helper (ecma_value_t value) /**< ecma value */ return NULL; } - ecma_string_t *ret_string_p = ecma_to_op_string_helper (prim_value); + ecma_string_t *ret_string_p = ecma_op_to_string (prim_value); ecma_free_value (prim_value); @@ -506,31 +506,6 @@ ecma_to_op_string_helper (ecma_value_t value) /**< ecma value */ } return ecma_get_magic_string (LIT_MAGIC_STRING_FALSE); -} /* ecma_to_op_string_helper */ - -/** - * ToString operation. - * - * See also: - * ECMA-262 v5, 9.8 - * - * @return ecma value - * Returned value must be freed with ecma_free_value - */ -ecma_value_t -ecma_op_to_string (ecma_value_t value) /**< ecma value */ -{ - ecma_check_value_type_is_spec_defined (value); - - ecma_string_t *string_p = ecma_to_op_string_helper (value); - - if (JERRY_UNLIKELY (string_p == NULL)) - { - /* Note: At this point the error has already been thrown. */ - return ECMA_VALUE_ERROR; - } - - return ecma_make_string_value (string_p); } /* ecma_op_to_string */ /** @@ -553,7 +528,7 @@ ecma_op_to_prop_name (ecma_value_t value) /**< ecma value */ } #endif /* ENABLED (JERRY_ES2015) */ - return ecma_to_op_string_helper (value); + return ecma_op_to_string (value); } /* ecma_op_to_prop_name */ /** diff --git a/jerry-core/ecma/operations/ecma-conversion.h b/jerry-core/ecma/operations/ecma-conversion.h index 61e511774..6967718c9 100644 --- a/jerry-core/ecma/operations/ecma-conversion.h +++ b/jerry-core/ecma/operations/ecma-conversion.h @@ -46,7 +46,7 @@ ecma_value_t ecma_op_to_primitive (ecma_value_t value, ecma_preferred_type_hint_ bool ecma_op_to_boolean (ecma_value_t value); ecma_value_t ecma_op_to_number (ecma_value_t value); ecma_value_t ecma_get_number (ecma_value_t value, ecma_number_t *number_p); -ecma_value_t ecma_op_to_string (ecma_value_t value); +ecma_string_t *ecma_op_to_string (ecma_value_t value); ecma_string_t *ecma_op_to_prop_name (ecma_value_t value); ecma_value_t ecma_op_to_object (ecma_value_t value); ecma_value_t ecma_op_to_integer (ecma_value_t value, ecma_number_t *number_p); diff --git a/jerry-core/ecma/operations/ecma-exceptions.c b/jerry-core/ecma/operations/ecma-exceptions.c index cfd45c208..54ed8b575 100644 --- a/jerry-core/ecma/operations/ecma-exceptions.c +++ b/jerry-core/ecma/operations/ecma-exceptions.c @@ -302,8 +302,8 @@ ecma_raise_standard_error_with_format (ecma_standard_error_t error_type, /**< er #endif /* ENABLED (JERRY_ES2015) */ else { - ecma_value_t str_val = ecma_op_to_string (arg_val); - arg_string_p = ecma_get_string_from_value (str_val); + arg_string_p = ecma_op_to_string (arg_val); + JERRY_ASSERT (arg_string_p != NULL); } /* Concat argument. */ diff --git a/jerry-core/ecma/operations/ecma-regexp-object.c b/jerry-core/ecma/operations/ecma-regexp-object.c index f3bcb432f..d2debe616 100644 --- a/jerry-core/ecma/operations/ecma-regexp-object.c +++ b/jerry-core/ecma/operations/ecma-regexp-object.c @@ -1324,32 +1324,19 @@ cleanup_string: * @return empty value if success, error value otherwise * Returned value must be freed with ecma_free_value. */ -ecma_value_t -ecma_regexp_read_pattern_str_helper (ecma_value_t pattern_arg, /**< the RegExp pattern */ - ecma_string_t **pattern_string_p) /**< [out] ptr to the pattern string ptr */ +ecma_string_t * +ecma_regexp_read_pattern_str_helper (ecma_value_t pattern_arg) /**< the RegExp pattern */ { if (!ecma_is_value_undefined (pattern_arg)) { - ecma_value_t regexp_str_value = ecma_op_to_string (pattern_arg); - if (ECMA_IS_VALUE_ERROR (regexp_str_value)) + ecma_string_t *pattern_string_p = ecma_op_to_string (pattern_arg); + if (JERRY_UNLIKELY (pattern_string_p == NULL) || !ecma_string_is_empty (pattern_string_p)) { - return regexp_str_value; + return pattern_string_p; } - - *pattern_string_p = ecma_get_string_from_value (regexp_str_value); - if (!ecma_string_is_empty (*pattern_string_p)) - { - ecma_ref_ecma_string (*pattern_string_p); - } - - ecma_free_value (regexp_str_value); // must be freed *after* ecma_ref_ecma_string } - if (!*pattern_string_p || ecma_string_is_empty (*pattern_string_p)) - { - *pattern_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_EMPTY_NON_CAPTURE_GROUP); - } - return ECMA_VALUE_EMPTY; + return ecma_get_magic_string (LIT_MAGIC_STRING_EMPTY_NON_CAPTURE_GROUP); } /* ecma_regexp_read_pattern_str_helper */ /** diff --git a/jerry-core/ecma/operations/ecma-regexp-object.h b/jerry-core/ecma/operations/ecma-regexp-object.h index 1b1c6e547..a32d26ec4 100644 --- a/jerry-core/ecma/operations/ecma-regexp-object.h +++ b/jerry-core/ecma/operations/ecma-regexp-object.h @@ -90,7 +90,7 @@ typedef struct ecma_value_t ecma_op_create_regexp_object_from_bytecode (re_compiled_code_t *bytecode_p); ecma_value_t ecma_op_create_regexp_object (ecma_string_t *pattern_p, uint16_t flags); ecma_value_t ecma_regexp_exec_helper (ecma_value_t regexp_value, ecma_value_t input_string, bool ignore_global); -ecma_value_t ecma_regexp_read_pattern_str_helper (ecma_value_t pattern_arg, ecma_string_t **pattern_string_p); +ecma_string_t *ecma_regexp_read_pattern_str_helper (ecma_value_t pattern_arg); ecma_char_t ecma_regexp_canonicalize (ecma_char_t ch, bool is_ignorecase); ecma_char_t ecma_regexp_canonicalize_char (ecma_char_t ch); ecma_value_t ecma_regexp_parse_flags (ecma_string_t *flags_str_p, uint16_t *flags_p); diff --git a/jerry-core/ecma/operations/ecma-string-object.c b/jerry-core/ecma/operations/ecma-string-object.c index 2f3a11ecd..271225bef 100644 --- a/jerry-core/ecma/operations/ecma-string-object.c +++ b/jerry-core/ecma/operations/ecma-string-object.c @@ -50,14 +50,14 @@ ecma_op_create_string_object (const ecma_value_t *arguments_list_p, /**< list of if (arguments_list_len > 0) { - prim_value = ecma_op_to_string (arguments_list_p[0]); + ecma_string_t *str_p = ecma_op_to_string (arguments_list_p[0]); - if (ECMA_IS_VALUE_ERROR (prim_value)) + if (JERRY_UNLIKELY (str_p == NULL)) { - return prim_value; + return ECMA_VALUE_ERROR; } - JERRY_ASSERT (ecma_is_value_string (prim_value)); + prim_value = ecma_make_string_value (str_p); } #if ENABLED (JERRY_BUILTIN_STRING) diff --git a/jerry-core/ecma/operations/ecma-symbol-object.c b/jerry-core/ecma/operations/ecma-symbol-object.c index 1e881c19b..16294ec95 100644 --- a/jerry-core/ecma/operations/ecma-symbol-object.c +++ b/jerry-core/ecma/operations/ecma-symbol-object.c @@ -55,15 +55,15 @@ ecma_op_create_symbol (const ecma_value_t *arguments_list_p, /**< list of argume } else { - string_desc = ecma_op_to_string (arguments_list_p[0]); + ecma_string_t *str_p = ecma_op_to_string (arguments_list_p[0]); /* 4. */ - if (ECMA_IS_VALUE_ERROR (string_desc)) + if (JERRY_UNLIKELY (str_p == NULL)) { - return string_desc; + return ECMA_VALUE_ERROR; } - JERRY_ASSERT (ecma_is_value_string (string_desc)); + string_desc = ecma_make_string_value (str_p); } /* 5. */ diff --git a/jerry-core/vm/opcodes-ecma-arithmetics.c b/jerry-core/vm/opcodes-ecma-arithmetics.c index 68892768d..42ee5d779 100644 --- a/jerry-core/vm/opcodes-ecma-arithmetics.c +++ b/jerry-core/vm/opcodes-ecma-arithmetics.c @@ -132,9 +132,9 @@ opfunc_addition (ecma_value_t left_value, /**< left value */ if (ecma_is_value_string (left_value) || ecma_is_value_string (right_value)) { - ecma_value_t str_left_value = ecma_op_to_string (left_value); + ecma_string_t *string1_p = ecma_op_to_string (left_value); - if (ECMA_IS_VALUE_ERROR (str_left_value)) + if (JERRY_UNLIKELY (string1_p == NULL)) { if (free_left_value) { @@ -144,14 +144,12 @@ opfunc_addition (ecma_value_t left_value, /**< left value */ { ecma_free_value (right_value); } - return str_left_value; + return ECMA_VALUE_ERROR; } - ecma_string_t *string1_p = ecma_get_string_from_value (str_left_value); + ecma_string_t *string2_p = ecma_op_to_string (right_value); - ecma_value_t str_right_value = ecma_op_to_string (right_value); - - if (ECMA_IS_VALUE_ERROR (str_right_value)) + if (JERRY_UNLIKELY (string2_p == NULL)) { if (free_right_value) { @@ -162,11 +160,9 @@ opfunc_addition (ecma_value_t left_value, /**< left value */ ecma_free_value (left_value); } ecma_deref_ecma_string (string1_p); - return str_right_value; + return ECMA_VALUE_ERROR; } - ecma_string_t *string2_p = ecma_get_string_from_value (str_right_value); - string1_p = ecma_concat_ecma_strings (string1_p, string2_p); ret_value = ecma_make_string_value (string1_p);