aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Fancsik <frobert@inf.u-szeged.hu>2019-08-26 17:20:00 +0200
committerDániel Bátyai <dbatyai@inf.u-szeged.hu>2019-08-26 17:20:00 +0200
commitb47c36ad18225190da807f158c17f5101391b6b1 (patch)
treeb9aa44a20c19b7315785eed2001ddf1118747e53
parent3af0079a0eb4bf149d7e7c5acd3c95dfd049f622 (diff)
Eliminate ECMA_TRY_CATCH macros part I. (#3006)
Also this patch introduces several helper function to find/put/delete properties by indexed property names to reduce code duplications. JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik frobert@inf.u-szeged.hu
-rw-r--r--jerry-core/ecma/base/ecma-globals.h8
-rw-r--r--jerry-core/ecma/base/ecma-helpers-string.c25
-rw-r--r--jerry-core/ecma/base/ecma-helpers.h1
-rw-r--r--jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c1242
-rw-r--r--jerry-core/ecma/builtin-objects/ecma-builtin-helpers.c40
-rw-r--r--jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h3
-rw-r--r--jerry-core/ecma/operations/ecma-objects.c142
-rw-r--r--jerry-core/ecma/operations/ecma-objects.h8
-rwxr-xr-xtools/run-tests.py2
9 files changed, 840 insertions, 631 deletions
diff --git a/jerry-core/ecma/base/ecma-globals.h b/jerry-core/ecma/base/ecma-globals.h
index 3356c651..27720904 100644
--- a/jerry-core/ecma/base/ecma-globals.h
+++ b/jerry-core/ecma/base/ecma-globals.h
@@ -1251,6 +1251,14 @@ typedef enum
((uintptr_t) (ECMA_TYPE_DIRECT_STRING | ((type) << ECMA_VALUE_SHIFT) | (value) << ECMA_DIRECT_STRING_SHIFT))
/**
+ * Create an ecma direct string from the given number.
+ *
+ * Note: the given number must be less or equal than ECMA_DIRECT_STRING_MAX_IMM
+ */
+#define ECMA_CREATE_DIRECT_UINT32_STRING(uint32_number) \
+ ((ecma_string_t *) ECMA_CREATE_DIRECT_STRING (ECMA_DIRECT_STRING_UINT, (uintptr_t) uint32_number))
+
+/**
* Checks whether the string is direct.
*/
#define ECMA_IS_DIRECT_STRING(string_p) \
diff --git a/jerry-core/ecma/base/ecma-helpers-string.c b/jerry-core/ecma/base/ecma-helpers-string.c
index af536c3c..3d490d28 100644
--- a/jerry-core/ecma/base/ecma-helpers-string.c
+++ b/jerry-core/ecma/base/ecma-helpers-string.c
@@ -520,15 +520,14 @@ ecma_new_ecma_string_from_code_units (ecma_char_t first_code_unit, /**< code uni
/**
* Allocate new ecma-string and fill it with ecma-number
*
+ * Note: the number cannot be represented as direct string
+ *
* @return pointer to ecma-string descriptor
*/
ecma_string_t *
-ecma_new_ecma_string_from_uint32 (uint32_t uint32_number) /**< uint32 value of the string */
+ecma_new_non_direct_string_from_uint32 (uint32_t uint32_number) /**< uint32 value of the string */
{
- if (JERRY_LIKELY (uint32_number <= ECMA_DIRECT_STRING_MAX_IMM))
- {
- return (ecma_string_t *) ECMA_CREATE_DIRECT_STRING (ECMA_DIRECT_STRING_UINT, (uintptr_t) uint32_number);
- }
+ JERRY_ASSERT (uint32_number > ECMA_DIRECT_STRING_MAX_IMM);
ecma_string_t *string_p = ecma_alloc_string ();
@@ -537,6 +536,22 @@ ecma_new_ecma_string_from_uint32 (uint32_t uint32_number) /**< uint32 value of t
string_p->u.uint32_number = uint32_number;
return string_p;
+} /* ecma_new_non_direct_string_from_uint32 */
+
+/**
+ * Allocate new ecma-string and fill it with ecma-number
+ *
+ * @return pointer to ecma-string descriptor
+ */
+ecma_string_t *
+ecma_new_ecma_string_from_uint32 (uint32_t uint32_number) /**< uint32 value of the string */
+{
+ if (JERRY_LIKELY (uint32_number <= ECMA_DIRECT_STRING_MAX_IMM))
+ {
+ return (ecma_string_t *) ECMA_CREATE_DIRECT_STRING (ECMA_DIRECT_STRING_UINT, (uintptr_t) uint32_number);
+ }
+
+ return ecma_new_non_direct_string_from_uint32 (uint32_number);
} /* ecma_new_ecma_string_from_uint32 */
/**
diff --git a/jerry-core/ecma/base/ecma-helpers.h b/jerry-core/ecma/base/ecma-helpers.h
index cc54ede1..38dd65ae 100644
--- a/jerry-core/ecma/base/ecma-helpers.h
+++ b/jerry-core/ecma/base/ecma-helpers.h
@@ -234,6 +234,7 @@ ecma_string_t *ecma_new_ecma_string_from_code_unit (ecma_char_t code_unit);
ecma_string_t *ecma_new_ecma_string_from_code_units (ecma_char_t first_code_unit, ecma_char_t second_code_unit);
#endif /* ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) */
ecma_string_t *ecma_new_ecma_string_from_uint32 (uint32_t uint32_number);
+ecma_string_t *ecma_new_non_direct_string_from_uint32 (uint32_t uint32_number);
ecma_string_t *ecma_get_ecma_string_from_uint32 (uint32_t uint32_number);
ecma_string_t *ecma_new_ecma_string_from_number (ecma_number_t num);
ecma_string_t *ecma_get_magic_string (lit_magic_string_id_t id);
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 17ec8c81..cd455ccf 100644
--- a/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c
+++ b/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c
@@ -27,7 +27,6 @@
#include "ecma-iterator-object.h"
#include "ecma-objects.h"
#include "ecma-string-object.h"
-#include "ecma-try-catch-macro.h"
#include "jrt.h"
#if ENABLED (JERRY_BUILTIN_ARRAY)
@@ -96,21 +95,23 @@ enum
* Helper function to set an object's length property
*
* @return ecma value (return value of the [[Put]] method)
- * Returned value must be freed with ecma_free_value.
+ * Calling ecma_free_value on the returned value is optional if it is not abrupt completion.
*/
static ecma_value_t
ecma_builtin_array_prototype_helper_set_length (ecma_object_t *object, /**< object*/
ecma_number_t length) /**< new length */
{
- ecma_value_t ret_value;
-
ecma_value_t length_value = ecma_make_number_value (length);
- ret_value = ecma_op_object_put (object,
- ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH),
- length_value,
- true);
+ ecma_value_t ret_value = ecma_op_object_put (object,
+ ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH),
+ length_value,
+ true);
ecma_free_value (length_value);
+
+ JERRY_ASSERT (ecma_is_value_boolean (ret_value)
+ || ecma_is_value_empty (ret_value)
+ || ECMA_IS_VALUE_ERROR (ret_value));
return ret_value;
} /* ecma_builtin_array_prototype_helper_set_length */
@@ -180,37 +181,37 @@ ecma_builtin_array_prototype_object_to_locale_string (ecma_object_t *obj_p, /**<
return first_value;
}
- ecma_value_t ret_value = ECMA_VALUE_EMPTY;
- ecma_string_t *return_string_p = ecma_get_string_from_value (first_value);
+ ecma_string_t *first_string_p = ecma_get_string_from_value (first_value);
+ ecma_string_t *return_string_p = first_string_p;
ecma_ref_ecma_string (return_string_p);
+ ecma_value_t ret_value = ECMA_VALUE_ERROR;
+
/* 9-10. */
- for (uint32_t k = 1; ecma_is_value_empty (ret_value) && (k < length); k++)
+ for (uint32_t k = 1; k < length; k++)
{
/* 4. Implementation-defined: set the separator to a single comma character. */
return_string_p = ecma_append_magic_string_to_string (return_string_p,
LIT_MAGIC_STRING_COMMA_CHAR);
- ECMA_TRY_CATCH (next_string_value,
- ecma_builtin_helper_get_to_locale_string_at_index (obj_p, k),
- ret_value);
+ ecma_value_t next_string_value = ecma_builtin_helper_get_to_locale_string_at_index (obj_p, k);
+
+ if (ECMA_IS_VALUE_ERROR (next_string_value))
+ {
+ ecma_deref_ecma_string (return_string_p);
+ goto clean_up;
+ }
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_FINALIZE (next_string_value);
+ ecma_deref_ecma_string (next_string_p);
}
- if (ecma_is_value_empty (ret_value))
- {
- ret_value = ecma_make_string_value (return_string_p);
- }
- else
- {
- ecma_deref_ecma_string (return_string_p);
- }
+ ret_value = ecma_make_string_value (return_string_p);
- ecma_free_value (first_value);
+clean_up:
+ ecma_deref_ecma_string (first_string_p);
return ret_value;
} /* ecma_builtin_array_prototype_object_to_locale_string */
@@ -245,40 +246,41 @@ ecma_builtin_array_prototype_object_concat (const ecma_value_t args[], /**< argu
ecma_object_t *new_array_p = ecma_get_object_from_value (new_array);
uint32_t new_length = 0;
- ecma_value_t ret_value = ECMA_VALUE_EMPTY;
-
/* 5.b - 5.c for this_arg */
- ECMA_TRY_CATCH (concat_this_value,
- ecma_builtin_helper_array_concat_value (new_array_p, &new_length, ecma_make_object_value (obj_p)),
- ret_value);
-
- /* 5. */
- for (uint32_t arg_index = 0;
- arg_index < args_number && ecma_is_value_empty (ret_value);
- arg_index++)
+ ecma_value_t concat_this_value = ecma_builtin_helper_array_concat_value (new_array_p,
+ &new_length,
+ ecma_make_object_value (obj_p));
+ if (ECMA_IS_VALUE_ERROR (concat_this_value))
{
- ECMA_TRY_CATCH (concat_value,
- ecma_builtin_helper_array_concat_value (new_array_p, &new_length, args[arg_index]),
- ret_value);
- ECMA_FINALIZE (concat_value);
+ ecma_deref_object (new_array_p);
+ return concat_this_value;
}
- ECMA_FINALIZE (concat_this_value);
+ JERRY_ASSERT (ecma_is_value_empty (concat_this_value));
- if (ecma_is_value_empty (ret_value))
+ /* 5. */
+ for (uint32_t arg_index = 0; arg_index < args_number; arg_index++)
{
- ECMA_TRY_CATCH (set_length_value,
- ecma_builtin_array_prototype_helper_set_length (new_array_p, ((ecma_number_t) new_length)),
- ret_value);
- ret_value = new_array;
- ECMA_FINALIZE (set_length_value);
+ ecma_value_t concat_value = ecma_builtin_helper_array_concat_value (new_array_p, &new_length, args[arg_index]);
+
+ if (ECMA_IS_VALUE_ERROR (concat_value))
+ {
+ ecma_deref_object (new_array_p);
+ return concat_value;
+ }
+
+ JERRY_ASSERT (ecma_is_value_empty (concat_value));
}
- else
+
+ ecma_value_t set_length_value = ecma_builtin_array_prototype_helper_set_length (new_array_p,
+ ((ecma_number_t) new_length));
+ if (ECMA_IS_VALUE_ERROR (set_length_value))
{
- ecma_free_value (new_array);
+ ecma_deref_object (new_array_p);
+ return set_length_value;
}
- return ret_value;
+ return new_array;
} /* ecma_builtin_array_prototype_object_concat */
/**
@@ -315,26 +317,26 @@ static ecma_value_t
ecma_op_array_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_TRY_CATCH (index_value,
- ecma_op_object_get (obj_p, index_string_p),
- ret_value);
+ ecma_value_t index_value = ecma_op_object_get (obj_p, index_string_p);
- if (ecma_is_value_undefined (index_value)
- || ecma_is_value_null (index_value))
+ ecma_deref_ecma_string (index_string_p);
+
+ if (ECMA_IS_VALUE_ERROR (index_value))
{
- ret_value = ecma_make_magic_string_value (LIT_MAGIC_STRING__EMPTY);
+ return index_value;
}
- else
+
+ if (ecma_is_value_undefined (index_value)
+ || ecma_is_value_null (index_value))
{
- ret_value = ecma_op_to_string (index_value);
+ return ecma_make_magic_string_value (LIT_MAGIC_STRING__EMPTY);
}
- ECMA_FINALIZE (index_value);
+ ecma_value_t ret_value = ecma_op_to_string (index_value);
- ecma_deref_ecma_string (index_string_p);
+ ecma_free_value (index_value);
return ret_value;
} /* ecma_op_array_get_to_string_at_index */
@@ -353,8 +355,6 @@ ecma_builtin_array_prototype_join (ecma_value_t separator_arg, /**< separator ar
ecma_object_t *obj_p, /**< array object */
uint32_t length) /**< array object's length */
{
- ecma_value_t ret_value = ECMA_VALUE_EMPTY;
-
/* 4-5. */
ecma_value_t separator_value = ecma_op_array_get_separator_string (separator_arg);
@@ -373,43 +373,47 @@ ecma_builtin_array_prototype_join (ecma_value_t separator_arg, /**< separator ar
}
/* 7-8. */
- ECMA_TRY_CATCH (first_value,
- ecma_op_array_get_to_string_at_index (obj_p, 0),
- ret_value);
+ ecma_value_t first_value = ecma_op_array_get_to_string_at_index (obj_p, 0);
- ecma_string_t *return_string_p = ecma_get_string_from_value (first_value);
+ if (ECMA_IS_VALUE_ERROR (first_value))
+ {
+ ecma_deref_ecma_string (separator_string_p);
+ return first_value;
+ }
+
+ ecma_string_t *first_string_p = ecma_get_string_from_value (first_value);
+ ecma_string_t *return_string_p = first_string_p;
ecma_ref_ecma_string (return_string_p);
+ ecma_value_t ret_value = ECMA_VALUE_ERROR;
/* 9-10. */
- for (uint32_t k = 1; ecma_is_value_empty (ret_value) && (k < length); k++)
+ for (uint32_t k = 1; k < length; k++)
{
/* 10.a */
return_string_p = ecma_concat_ecma_strings (return_string_p, separator_string_p);
/* 10.b, 10.c */
- ECMA_TRY_CATCH (next_string_value,
- ecma_op_array_get_to_string_at_index (obj_p, k),
- ret_value);
+ ecma_value_t next_string_value = ecma_op_array_get_to_string_at_index (obj_p, k);
+
+ if (ECMA_IS_VALUE_ERROR (next_string_value))
+ {
+ ecma_deref_ecma_string (return_string_p);
+ goto clean_up;
+ }
/* 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_FINALIZE (next_string_value);
+ ecma_deref_ecma_string (next_string_p);
}
- if (ecma_is_value_empty (ret_value))
- {
- ret_value = ecma_make_string_value (return_string_p);
- }
- else
- {
- ecma_deref_ecma_string (return_string_p);
- }
+ ret_value = ecma_make_string_value (return_string_p);
- ECMA_FINALIZE (first_value);
+clean_up:
+ ecma_deref_ecma_string (first_string_p);
- ecma_free_value (separator_value);
+ ecma_deref_ecma_string (separator_string_p);
return ret_value;
} /* ecma_builtin_array_prototype_join */
@@ -433,15 +437,8 @@ ecma_builtin_array_prototype_object_pop (ecma_object_t *obj_p, /**< array object
/* 4.a */
ecma_value_t set_length_value = ecma_builtin_array_prototype_helper_set_length (obj_p, ECMA_NUMBER_ZERO);
- if (ECMA_IS_VALUE_ERROR (set_length_value))
- {
- return set_length_value;
- }
-
- ecma_free_value (set_length_value);
-
/* 4.b */
- return ECMA_VALUE_UNDEFINED;
+ return ECMA_IS_VALUE_ERROR (set_length_value) ? set_length_value : ECMA_VALUE_UNDEFINED;
}
/* 5.a */
@@ -452,29 +449,33 @@ ecma_builtin_array_prototype_object_pop (ecma_object_t *obj_p, /**< array object
if (ECMA_IS_VALUE_ERROR (get_value))
{
+ ecma_deref_ecma_string (index_str_p);
return get_value;
}
- ecma_value_t ret_value = ECMA_VALUE_EMPTY;
-
/* 5.c */
- ECMA_TRY_CATCH (del_value, ecma_op_object_delete (obj_p, index_str_p, true), ret_value);
+ ecma_value_t del_value = ecma_op_object_delete (obj_p, index_str_p, true);
- /* 5.d */
- ECMA_TRY_CATCH (set_length_value,
- ecma_builtin_array_prototype_helper_set_length (obj_p, ((ecma_number_t) len)),
- ret_value);
+ ecma_deref_ecma_string (index_str_p);
- ret_value = ecma_copy_value (get_value);
+ if (ECMA_IS_VALUE_ERROR (del_value))
+ {
+ ecma_free_value (get_value);
+ return del_value;
+ }
- ECMA_FINALIZE (set_length_value);
- ECMA_FINALIZE (del_value);
+ ecma_free_value (del_value);
- ecma_free_value (get_value);
- ecma_deref_ecma_string (index_str_p);
+ /* 5.d */
+ ecma_value_t set_length_value = ecma_builtin_array_prototype_helper_set_length (obj_p, ((ecma_number_t) len));
+ if (ECMA_IS_VALUE_ERROR (set_length_value))
+ {
+ ecma_free_value (get_value);
+ return set_length_value;
+ }
- return ret_value;
+ return get_value;
} /* ecma_builtin_array_prototype_object_pop */
/**
@@ -492,40 +493,29 @@ ecma_builtin_array_prototype_object_push (const ecma_value_t *argument_list_p, /
ecma_object_t *obj_p, /**< array object */
uint32_t length) /**< array object's length */
{
- ecma_value_t ret_value = ECMA_VALUE_EMPTY;
-
ecma_number_t n = (ecma_number_t) length;
/* 5. */
- for (uint32_t index = 0;
- index < arguments_number && ecma_is_value_empty (ret_value);
- index++, n++)
+ for (uint32_t index = 0; index < arguments_number; index++, n++)
{
- /* 5.a */
- ecma_value_t e_value = argument_list_p[index];
-
/* 5.b */
- ecma_string_t *n_str_p = ecma_new_ecma_string_from_number (n);
-
- ECMA_TRY_CATCH (put_value, ecma_op_object_put (obj_p, n_str_p, e_value, true), ret_value);
- ECMA_FINALIZE (put_value);
+ ecma_value_t put_value = ecma_op_object_put_by_number_index (obj_p, n, argument_list_p[index], true);
- ecma_deref_ecma_string (n_str_p);
+ if (ECMA_IS_VALUE_ERROR (put_value))
+ {
+ return put_value;
+ }
}
/* 6. */
- if (ecma_is_value_empty (ret_value))
- {
- ECMA_TRY_CATCH (set_length_value,
- ecma_builtin_array_prototype_helper_set_length (obj_p, n),
- ret_value);
+ ecma_value_t set_length_value = ecma_builtin_array_prototype_helper_set_length (obj_p, n);
- ret_value = ecma_make_number_value (n);
-
- ECMA_FINALIZE (set_length_value)
+ if (ECMA_IS_VALUE_ERROR (set_length_value))
+ {
+ return set_length_value;
}
- return ret_value;
+ return ecma_make_number_value (n);
} /* ecma_builtin_array_prototype_object_push */
/**
@@ -544,20 +534,34 @@ ecma_builtin_array_prototype_object_reverse (ecma_value_t this_arg, /**< this ar
{
/* 4. */
uint32_t middle = len / 2;
- ecma_value_t ret_value = ECMA_VALUE_EMPTY;
/* 5-6. */
- for (uint32_t lower = 0; lower < middle && ecma_is_value_empty (ret_value); lower++)
+ for (uint32_t lower = 0; lower < middle; lower++)
{
+ ecma_value_t ret_value = ECMA_VALUE_ERROR;
+ ecma_string_t *lower_str_p = ecma_new_ecma_string_from_uint32 (lower);
+
+ /* 6.d and 6.e */
+ ecma_value_t lower_value = ecma_op_object_get (obj_p, lower_str_p);
+
+ if (ECMA_IS_VALUE_ERROR (lower_value))
+ {
+ ecma_deref_ecma_string (lower_str_p);
+ return lower_value;
+ }
+
/* 6.a */
uint32_t upper = len - lower - 1;
/* 6.b and 6.c */
ecma_string_t *upper_str_p = ecma_new_ecma_string_from_uint32 (upper);
- ecma_string_t *lower_str_p = ecma_new_ecma_string_from_uint32 (lower);
- /* 6.d and 6.e */
- ECMA_TRY_CATCH (lower_value, ecma_op_object_get (obj_p, lower_str_p), ret_value);
- ECMA_TRY_CATCH (upper_value, ecma_op_object_get (obj_p, upper_str_p), ret_value);
+ ecma_value_t upper_value = ecma_op_object_get (obj_p, upper_str_p);
+
+ if (ECMA_IS_VALUE_ERROR (upper_value))
+ {
+ upper_value = ECMA_VALUE_EMPTY;
+ goto clean_up;
+ }
/* 6.f and 6.g */
bool lower_exist = ecma_op_object_has_property (obj_p, lower_str_p);
@@ -566,41 +570,73 @@ ecma_builtin_array_prototype_object_reverse (ecma_value_t this_arg, /**< this ar
/* 6.h */
if (lower_exist && upper_exist)
{
- ECMA_TRY_CATCH (outer_put_value, ecma_op_object_put (obj_p, lower_str_p, upper_value, true), ret_value);
- ECMA_TRY_CATCH (inner_put_value, ecma_op_object_put (obj_p, upper_str_p, lower_value, true), ret_value);
- ECMA_FINALIZE (inner_put_value);
- ECMA_FINALIZE (outer_put_value);
+ ecma_value_t outer_put_value = ecma_op_object_put (obj_p, lower_str_p, upper_value, true);
+
+ if (ECMA_IS_VALUE_ERROR (outer_put_value))
+ {
+ goto clean_up;
+ }
+
+ ecma_value_t inner_put_value = ecma_op_object_put (obj_p, upper_str_p, lower_value, true);
+
+ if (ECMA_IS_VALUE_ERROR (inner_put_value))
+ {
+ goto clean_up;
+ }
}
/* 6.i */
else if (!lower_exist && upper_exist)
{
- ECMA_TRY_CATCH (put_value, ecma_op_object_put (obj_p, lower_str_p, upper_value, true), ret_value);
- ECMA_TRY_CATCH (del_value, ecma_op_object_delete (obj_p, upper_str_p, true), ret_value);
- ECMA_FINALIZE (del_value);
- ECMA_FINALIZE (put_value);
+ ecma_value_t put_value = ecma_op_object_put (obj_p, lower_str_p, upper_value, true);
+
+ if (ECMA_IS_VALUE_ERROR (put_value))
+ {
+ goto clean_up;
+ }
+
+ ecma_value_t del_value = ecma_op_object_delete (obj_p, upper_str_p, true);
+
+ JERRY_ASSERT (ECMA_IS_VALUE_ERROR (del_value) || ecma_is_value_boolean (del_value));
+
+ if (ECMA_IS_VALUE_ERROR (del_value))
+ {
+ goto clean_up;
+ }
}
/* 6.j */
else if (lower_exist)
{
- ECMA_TRY_CATCH (del_value, ecma_op_object_delete (obj_p, lower_str_p, true), ret_value);
- ECMA_TRY_CATCH (put_value, ecma_op_object_put (obj_p, upper_str_p, lower_value, true), ret_value);
- ECMA_FINALIZE (put_value);
- ECMA_FINALIZE (del_value);
+ ecma_value_t del_value = ecma_op_object_delete (obj_p, lower_str_p, true);
+
+ if (ECMA_IS_VALUE_ERROR (del_value))
+ {
+ goto clean_up;
+ }
+
+ ecma_value_t put_value = ecma_op_object_put (obj_p, upper_str_p, lower_value, true);
+
+ if (ECMA_IS_VALUE_ERROR (put_value))
+ {
+ goto clean_up;
+ }
}
- ECMA_FINALIZE (upper_value);
- ECMA_FINALIZE (lower_value);
+ ret_value = ECMA_VALUE_EMPTY;
+
+clean_up:
+ ecma_free_value (upper_value);
+ ecma_free_value (lower_value);
ecma_deref_ecma_string (lower_str_p);
ecma_deref_ecma_string (upper_str_p);
- }
- if (ecma_is_value_empty (ret_value))
- {
- /* 7. */
- return ecma_copy_value (this_arg);
+ if (ECMA_IS_VALUE_ERROR (ret_value))
+ {
+ return ret_value;
+ }
}
- return ret_value;
+ /* 7. */
+ return ecma_copy_value (this_arg);
} /* ecma_builtin_array_prototype_object_reverse */
/**
@@ -621,18 +657,9 @@ ecma_builtin_array_prototype_object_shift (ecma_object_t *obj_p, /**< array obje
{
ecma_value_t set_length_value = ecma_builtin_array_prototype_helper_set_length (obj_p, ECMA_NUMBER_ZERO);
- if (ECMA_IS_VALUE_ERROR (set_length_value))
- {
- return set_length_value;
- }
-
- ecma_free_value (set_length_value);
-
- return ECMA_VALUE_UNDEFINED;
+ return ECMA_IS_VALUE_ERROR (set_length_value) ? set_length_value : ECMA_VALUE_UNDEFINED;
}
- ecma_value_t ret_value = ECMA_VALUE_EMPTY;
-
/* 5. */
ecma_value_t first_value = ecma_op_object_get (obj_p, ecma_get_ecma_string_from_uint32 (0));
@@ -642,59 +669,60 @@ ecma_builtin_array_prototype_object_shift (ecma_object_t *obj_p, /**< array obje
}
/* 6. and 7. */
- for (uint32_t k = 1; k < len && ecma_is_value_empty (ret_value); k++)
+ for (uint32_t k = 1; k < len; k++)
{
- /* 7.a */
- ecma_string_t *from_str_p = ecma_new_ecma_string_from_uint32 (k);
- /* 7.b */
- ecma_string_t *to_str_p = ecma_new_ecma_string_from_uint32 (k - 1);
+ /* 7.a - 7.c */
+ ecma_value_t curr_value = ecma_op_object_find_by_uint32_index (obj_p, k);
+
+ if (ECMA_IS_VALUE_ERROR (curr_value))
+ {
+ ecma_free_value (first_value);
+ return curr_value;
+ }
- /* 7.c */
- ECMA_TRY_CATCH (curr_value, ecma_op_object_find (obj_p, from_str_p), ret_value);
+ /* 7.b */
+ uint32_t to = k - 1;
+ ecma_value_t operation_value;
if (ecma_is_value_found (curr_value))
{
/* 7.d.i, 7.d.ii */
- ECMA_TRY_CATCH (put_value, ecma_op_object_put (obj_p, to_str_p, curr_value, true), ret_value);
-
- ECMA_FINALIZE (put_value);
+ operation_value = ecma_op_object_put_by_uint32_index (obj_p, to, curr_value, true);
+ ecma_free_value (curr_value);
}
else
{
/* 7.e.i */
- ECMA_TRY_CATCH (del_value, ecma_op_object_delete (obj_p, to_str_p, true), ret_value);
- ECMA_FINALIZE (del_value);
+ operation_value = ecma_op_object_delete_by_uint32_index (obj_p, to, true);
}
- ECMA_FINALIZE (curr_value);
-
- ecma_deref_ecma_string (to_str_p);
- ecma_deref_ecma_string (from_str_p);
+ if (ECMA_IS_VALUE_ERROR (operation_value))
+ {
+ ecma_free_value (first_value);
+ return operation_value;
+ }
}
- if (ecma_is_value_empty (ret_value))
- {
- len--;
- ecma_string_t *len_str_p = ecma_new_ecma_string_from_uint32 (len);
+ /* 8. */
+ ecma_value_t del_value = ecma_op_object_delete_by_uint32_index (obj_p, --len, true);
- /* 8. */
- ECMA_TRY_CATCH (del_value, ecma_op_object_delete (obj_p, len_str_p, true), ret_value);
+ if (ECMA_IS_VALUE_ERROR (del_value))
+ {
+ ecma_free_value (first_value);
+ return del_value;
+ }
- /* 9. */
- ECMA_TRY_CATCH (set_length_value,
- ecma_builtin_array_prototype_helper_set_length (obj_p, ((ecma_number_t) len)),
- ret_value);
- /* 10. */
- ret_value = ecma_copy_value (first_value);
+ /* 9. */
+ ecma_value_t set_length_value = ecma_builtin_array_prototype_helper_set_length (obj_p, ((ecma_number_t) len));
- ECMA_FINALIZE (set_length_value);
- ECMA_FINALIZE (del_value);
- ecma_deref_ecma_string (len_str_p);
+ if (ECMA_IS_VALUE_ERROR (set_length_value))
+ {
+ ecma_free_value (first_value);
+ return set_length_value;
}
- ecma_free_value (first_value);
-
- return ret_value;
+ /* 10. */
+ return first_value;
} /* ecma_builtin_array_prototype_object_shift */
/**
@@ -712,12 +740,15 @@ ecma_builtin_array_prototype_object_slice (ecma_value_t arg1, /**< start */
ecma_object_t *obj_p, /**< array object */
uint32_t len) /**< array object's length */
{
- ecma_value_t ret_value = ECMA_VALUE_EMPTY;
-
uint32_t start = 0, end = len;
/* 5. */
- ECMA_OP_TO_NUMBER_TRY_CATCH (start_num, arg1, ret_value);
+ ecma_number_t start_num;
+
+ if (ECMA_IS_VALUE_ERROR (ecma_get_number (arg1, &start_num)))
+ {
+ return ECMA_VALUE_ERROR;
+ }
start = ecma_builtin_helper_array_index_normalize (start_num, len);
@@ -729,15 +760,16 @@ ecma_builtin_array_prototype_object_slice (ecma_value_t arg1, /**< start */
else
{
/* 7. part 2 */
- ECMA_OP_TO_NUMBER_TRY_CATCH (end_num, arg2, ret_value);
+ ecma_number_t end_num;
- end = ecma_builtin_helper_array_index_normalize (end_num, len);
+ if (ECMA_IS_VALUE_ERROR (ecma_get_number (arg2, &end_num)))
+ {
+ return ECMA_VALUE_ERROR;
+ }
- ECMA_OP_TO_NUMBER_FINALIZE (end_num);
+ end = ecma_builtin_helper_array_index_normalize (end_num, len);
}
- ECMA_OP_TO_NUMBER_FINALIZE (start_num);
-
JERRY_ASSERT (start <= len && end <= len);
#if ENABLED (JERRY_ES2015_CLASS)
@@ -758,46 +790,32 @@ ecma_builtin_array_prototype_object_slice (ecma_value_t arg1, /**< start */
uint32_t n = 0;
/* 10. */
- for (uint32_t k = start; k < end && ecma_is_value_empty (ret_value); k++, n++)
+ for (uint32_t k = start; k < end; k++, n++)
{
- /* 10.a */
- ecma_string_t *curr_idx_str_p = ecma_new_ecma_string_from_uint32 (k);
-
/* 10.c */
- ECMA_TRY_CATCH (get_value, ecma_op_object_find (obj_p, curr_idx_str_p), ret_value);
+ ecma_value_t get_value = ecma_op_object_find_by_uint32_index (obj_p, k);
- if (ecma_is_value_found (get_value))
+ if (ECMA_IS_VALUE_ERROR (get_value))
{
- /* 10.c.i */
- ecma_string_t *to_idx_str_p = ecma_new_ecma_string_from_uint32 (n);
+ ecma_deref_object (new_array_p);
+ return get_value;
+ }
+ if (ecma_is_value_found (get_value))
+ {
/* 10.c.ii */
/* This will always be a simple value since 'is_throw' is false, so no need to free. */
- ecma_value_t put_comp = ecma_builtin_helper_def_prop (new_array_p,
- to_idx_str_p,
- get_value,
- ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
- false); /* Failure handling */
+ ecma_value_t put_comp = ecma_builtin_helper_def_prop_by_index (new_array_p,
+ n,
+ get_value,
+ ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
+ false); /* Failure handling */
JERRY_ASSERT (ecma_is_value_true (put_comp));
-
- ecma_deref_ecma_string (to_idx_str_p);
+ ecma_free_value (get_value);
}
-
- ECMA_FINALIZE (get_value);
-
- ecma_deref_ecma_string (curr_idx_str_p);
}
- if (ecma_is_value_empty (ret_value))
- {
- ret_value = new_array;
- }
- else
- {
- ecma_free_value (new_array);
- }
-
- return ret_value;
+ return new_array;
} /* ecma_builtin_array_prototype_object_slice */
/**
@@ -833,15 +851,27 @@ ecma_builtin_array_prototype_object_sort_compare_helper (ecma_value_t lhs, /**<
return ecma_make_number_value (ECMA_NUMBER_MINUS_ONE);
}
- ecma_value_t ret_value = ECMA_VALUE_EMPTY;
ecma_number_t result = ECMA_NUMBER_ZERO;
if (ecma_is_value_undefined (compare_func))
{
/* Default comparison when no compare_func is passed. */
- ECMA_TRY_CATCH (lhs_value, ecma_op_to_string (lhs), ret_value);
- ECMA_TRY_CATCH (rhs_value, ecma_op_to_string (rhs), ret_value);
+ ecma_value_t lhs_value = ecma_op_to_string (lhs);
+
+ if (ECMA_IS_VALUE_ERROR (lhs_value))
+ {
+ return lhs_value;
+ }
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_deref_ecma_string (lhs_str_p);
+ return rhs_value;
+ }
+
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))
@@ -857,8 +887,8 @@ ecma_builtin_array_prototype_object_sort_compare_helper (ecma_value_t lhs, /**<
result = ECMA_NUMBER_ZERO;
}
- ECMA_FINALIZE (rhs_value);
- ECMA_FINALIZE (lhs_value);
+ ecma_deref_ecma_string (rhs_str_p);
+ ecma_deref_ecma_string (lhs_str_p);
}
else
{
@@ -871,33 +901,36 @@ ecma_builtin_array_prototype_object_sort_compare_helper (ecma_value_t lhs, /**<
ecma_value_t compare_args[] = { lhs, rhs };
- ECMA_TRY_CATCH (call_value,
- ecma_op_function_call (comparefn_obj_p,
- ECMA_VALUE_UNDEFINED,
- compare_args,
- 2),
- ret_value);
+ ecma_value_t call_value = ecma_op_function_call (comparefn_obj_p,
+ ECMA_VALUE_UNDEFINED,
+ compare_args,
+ 2);
+ if (ECMA_IS_VALUE_ERROR (call_value))
+ {
+ return call_value;
+ }
if (!ecma_is_value_number (call_value))
{
- ECMA_OP_TO_NUMBER_TRY_CATCH (ret_num, call_value, ret_value);
+ ecma_number_t ret_num;
+
+ if (ECMA_IS_VALUE_ERROR (ecma_get_number (call_value, &ret_num)))
+ {
+ ecma_free_value (call_value);
+ return ECMA_VALUE_ERROR;
+ }
+
result = ret_num;
- ECMA_OP_TO_NUMBER_FINALIZE (ret_num);
}
else
{
result = ecma_get_number_from_value (call_value);
}
- ECMA_FINALIZE (call_value);
- }
-
- if (ecma_is_value_empty (ret_value))
- {
- ret_value = ecma_make_number_value (result);
+ ecma_free_value (call_value);
}
- return ret_value;
+ return ecma_make_number_value (result);
} /* ecma_builtin_array_prototype_object_sort_compare_helper */
/**
@@ -942,14 +975,14 @@ ecma_builtin_array_prototype_object_sort (ecma_value_t this_arg, /**< this argum
}
}
- ecma_value_t ret_value = ECMA_VALUE_EMPTY;
+ ecma_value_t ret_value = ECMA_VALUE_ERROR;
uint32_t copied_num = 0;
JMEM_DEFINE_LOCAL_ARRAY (values_buffer, defined_prop_count, ecma_value_t);
ecma_value_p = ecma_collection_iterator_init (array_index_props_p);
/* Copy unsorted array into a native c array. */
- while (ecma_value_p != NULL && ecma_is_value_empty (ret_value))
+ while (ecma_value_p != NULL)
{
ecma_string_t *property_name_p = ecma_get_string_from_value (*ecma_value_p);
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
@@ -962,42 +995,48 @@ ecma_builtin_array_prototype_object_sort (ecma_value_t this_arg, /**< this argum
break;
}
- ECMA_TRY_CATCH (index_value, ecma_op_object_get (obj_p, property_name_p), ret_value);
+ ecma_value_t index_value = ecma_op_object_get (obj_p, property_name_p);
- values_buffer[copied_num++] = ecma_copy_value (index_value);
+ if (ECMA_IS_VALUE_ERROR (index_value))
+ {
+ goto clean_up;
+ }
- ECMA_FINALIZE (index_value);
+ values_buffer[copied_num++] = index_value;
}
- JERRY_ASSERT (copied_num == defined_prop_count
- || !ecma_is_value_empty (ret_value));
+ JERRY_ASSERT (copied_num == defined_prop_count);
/* Sorting. */
- if (copied_num > 1 && ecma_is_value_empty (ret_value))
+ if (copied_num > 1)
{
const ecma_builtin_helper_sort_compare_fn_t sort_cb = &ecma_builtin_array_prototype_object_sort_compare_helper;
- ECMA_TRY_CATCH (sort_value,
- ecma_builtin_helper_array_heap_sort_helper (values_buffer,
- (uint32_t) (copied_num - 1),
- arg1,
- sort_cb),
- ret_value);
- ECMA_FINALIZE (sort_value);
+ ecma_value_t sort_value = ecma_builtin_helper_array_heap_sort_helper (values_buffer,
+ (uint32_t) (copied_num - 1),
+ arg1,
+ sort_cb);
+ if (ECMA_IS_VALUE_ERROR (sort_value))
+ {
+ goto clean_up;
+ }
+
+ ecma_free_value (sort_value);
}
/* Put sorted values to the front of the array. */
- for (uint32_t index = 0;
- index < copied_num && ecma_is_value_empty (ret_value);
- index++)
+ for (uint32_t index = 0; index < copied_num; index++)
{
- ecma_string_t *index_string_p = ecma_new_ecma_string_from_uint32 (index);
- ECMA_TRY_CATCH (put_value,
- ecma_op_object_put (obj_p, index_string_p, values_buffer[index], true),
- ret_value);
- ECMA_FINALIZE (put_value);
- ecma_deref_ecma_string (index_string_p);
+ ecma_value_t put_value = ecma_op_object_put_by_uint32_index (obj_p, index, values_buffer[index], true);
+
+ if (ECMA_IS_VALUE_ERROR (put_value))
+ {
+ goto clean_up;
+ }
}
+ ret_value = ECMA_VALUE_EMPTY;
+
+clean_up:
/* Free values that were copied to the local array. */
for (uint32_t index = 0; index < copied_num; index++)
{
@@ -1006,11 +1045,19 @@ ecma_builtin_array_prototype_object_sort (ecma_value_t this_arg, /**< this argum
JMEM_FINALIZE_LOCAL_ARRAY (values_buffer);
+ if (ECMA_IS_VALUE_ERROR (ret_value))
+ {
+ ecma_free_values_collection (array_index_props_p, 0);
+ return ret_value;
+ }
+
+ JERRY_ASSERT (ecma_is_value_empty (ret_value));
+
/* Undefined properties should be in the back of the array. */
ecma_value_p = ecma_collection_iterator_init (array_index_props_p);
- while (ecma_value_p != NULL && ecma_is_value_empty (ret_value))
+ while (ecma_value_p != NULL)
{
ecma_string_t *property_name_p = ecma_get_string_from_value (*ecma_value_p);
ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
@@ -1020,19 +1067,19 @@ ecma_builtin_array_prototype_object_sort (ecma_value_t this_arg, /**< this argum
if (index >= copied_num && index < len)
{
- ECMA_TRY_CATCH (del_value, ecma_op_object_delete (obj_p, property_name_p, true), ret_value);
- ECMA_FINALIZE (del_value);
+ ecma_value_t del_value = ecma_op_object_delete (obj_p, property_name_p, true);
+
+ if (ECMA_IS_VALUE_ERROR (del_value))
+ {
+ ecma_free_values_collection (array_index_props_p, 0);
+ return del_value;
+ }
}
}
ecma_free_values_collection (array_index_props_p, 0);
- if (ecma_is_value_empty (ret_value))
- {
- return ecma_copy_value (this_arg);
- }
-
- return ret_value;
+ return ecma_copy_value (this_arg);
} /* ecma_builtin_array_prototype_object_sort */
/**
@@ -1066,14 +1113,16 @@ ecma_builtin_array_prototype_object_splice (const ecma_value_t args[], /**< argu
uint32_t start = 0;
uint32_t delete_count = 0;
- ecma_value_t ret_value = ECMA_VALUE_EMPTY;
if (args_number > 0)
{
/* 5. */
- ECMA_OP_TO_NUMBER_TRY_CATCH (start_num,
- args[0],
- ret_value);
+ ecma_number_t start_num;
+ if (ECMA_IS_VALUE_ERROR (ecma_get_number (args[0], &start_num)))
+ {
+ ecma_deref_object (new_array_p);
+ return ECMA_VALUE_ERROR;
+ }
start = ecma_builtin_helper_array_index_normalize (start_num, len);
@@ -1088,9 +1137,12 @@ ecma_builtin_array_prototype_object_splice (const ecma_value_t args[], /**< argu
else
{
/* 7. */
- ECMA_OP_TO_NUMBER_TRY_CATCH (delete_num,
- args[1],
- ret_value);
+ ecma_number_t delete_num;
+ if (ECMA_IS_VALUE_ERROR (ecma_get_number (args[1], &delete_num)))
+ {
+ ecma_deref_object (new_array_p);
+ return ECMA_VALUE_ERROR;
+ }
if (!ecma_number_is_nan (delete_num))
{
@@ -1112,46 +1164,39 @@ ecma_builtin_array_prototype_object_splice (const ecma_value_t args[], /**< argu
{
delete_count = 0;
}
-
- ECMA_OP_TO_NUMBER_FINALIZE (delete_num);
}
-
- ECMA_OP_TO_NUMBER_FINALIZE (start_num);
}
/* 8-9. */
uint32_t k = 0;
- for (uint32_t del_item_idx; k < delete_count && ecma_is_value_empty (ret_value); k++)
+ for (uint32_t del_item_idx; k < delete_count; k++)
{
- /* 9.a */
+ /* 9.a - 9.b */
del_item_idx = k + start;
- ecma_string_t *idx_str_p = ecma_new_ecma_string_from_uint32 (del_item_idx);
- /* 9.b */
- ECMA_TRY_CATCH (get_value, ecma_op_object_find (obj_p, idx_str_p), ret_value);
+ ecma_value_t get_value = ecma_op_object_find_by_uint32_index (obj_p, del_item_idx);
- if (ecma_is_value_found (get_value))
+ if (ECMA_IS_VALUE_ERROR (get_value))
{
- /* 9.c.i */
+ ecma_deref_object (new_array_p);
+ return get_value;
+ }
- ecma_string_t *idx_str_new_p = ecma_new_ecma_string_from_uint32 (k);
+ if (ecma_is_value_found (get_value))
+ {
/* 9.c.ii */
/* This will always be a simple value since 'is_throw' is false, so no need to free. */
- ecma_value_t put_comp = ecma_builtin_helper_def_prop (new_array_p,
- idx_str_new_p,
- get_value,
- ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
- false); /* Failure handling */
+ ecma_value_t put_comp = ecma_builtin_helper_def_prop_by_index (new_array_p,
+ k,
+ get_value,
+ ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
+ false); /* Failure handling */
JERRY_ASSERT (ecma_is_value_true (put_comp));
- ecma_deref_ecma_string (idx_str_new_p);
+ ecma_free_value (get_value);
}
-
- ECMA_FINALIZE (get_value);
-
- ecma_deref_ecma_string (idx_str_p);
}
/* 11. */
@@ -1176,52 +1221,50 @@ ecma_builtin_array_prototype_object_splice (const ecma_value_t args[], /**< argu
if (item_count < delete_count)
{
/* 12.b */
- for (k = start; k < (len - delete_count) && ecma_is_value_empty (ret_value); k++)
+ for (k = start; k < (len - delete_count); k++)
{
from = k + delete_count;
- ecma_string_t *from_str_p = ecma_new_ecma_string_from_uint32 (from);
-
to = k + item_count;
- ecma_string_t *to_str_p = ecma_new_ecma_string_from_uint32 (to);
- /* 12.b.iii */
- ECMA_TRY_CATCH (get_value, ecma_op_object_find (obj_p, from_str_p), ret_value);
+ ecma_value_t get_value = ecma_op_object_find_by_uint32_index (obj_p, from);
+
+ if (ECMA_IS_VALUE_ERROR (get_value))
+ {
+ ecma_deref_object (new_array_p);
+ return get_value;
+ }
+ /* 12.b.iii */
+ ecma_value_t operation_value;
if (ecma_is_value_found (get_value))
{
/* 12.b.iv */
- ECMA_TRY_CATCH (put_value,
- ecma_op_object_put (obj_p, to_str_p, get_value, true),
- ret_value);
-
- ECMA_FINALIZE (put_value);
+ operation_value = ecma_op_object_put_by_uint32_index (obj_p, to, get_value, true);
+ ecma_free_value (get_value);
}
else
{
/* 12.b.v */
- ECMA_TRY_CATCH (del_value,
- ecma_op_object_delete (obj_p, to_str_p, true),
- ret_value);
-
- ECMA_FINALIZE (del_value);
+ operation_value = ecma_op_object_delete_by_uint32_index (obj_p, to, true);
}
- ECMA_FINALIZE (get_value);
-
- ecma_deref_ecma_string (to_str_p);
- ecma_deref_ecma_string (from_str_p);
+ if (ECMA_IS_VALUE_ERROR (operation_value))
+ {
+ ecma_deref_object (new_array_p);
+ return operation_value;
+ }
}
/* 12.d */
- for (k = len; k > new_len && ecma_is_value_empty (ret_value); k--)
+ for (k = len; k > new_len; k--)
{
- ecma_string_t *str_idx_p = ecma_new_ecma_string_from_uint32 (k - 1);
- ECMA_TRY_CATCH (del_value,
- ecma_op_object_delete (obj_p, str_idx_p, true),
- ret_value);
+ ecma_value_t del_value = ecma_op_object_delete_by_uint32_index (obj_p, k - 1, true);
- ECMA_FINALIZE (del_value);
- ecma_deref_ecma_string (str_idx_p);
+ if (ECMA_IS_VALUE_ERROR (del_value))
+ {
+ ecma_deref_object (new_array_p);
+ return del_value;
+ }
}
}
/* 13. */
@@ -1229,79 +1272,68 @@ ecma_builtin_array_prototype_object_splice (const ecma_value_t args[], /**< argu
{
JERRY_ASSERT (item_count > delete_count);
/* 13.b */
- for (k = len - delete_count; k > start && ecma_is_value_empty (ret_value); k--)
+ for (k = len - delete_count; k > start; k--)
{
from = k + delete_count - 1;
- ecma_string_t *from_str_p = ecma_new_ecma_string_from_uint32 (from);
-
to = k + item_count - 1;
- ecma_string_t *to_str_p = ecma_new_ecma_string_from_uint32 (to);
-
/* 13.b.iii */
- ECMA_TRY_CATCH (get_value, ecma_op_object_find (obj_p, from_str_p), ret_value);
+ ecma_value_t get_value = ecma_op_object_find_by_uint32_index (obj_p, from);
+
+ if (ECMA_IS_VALUE_ERROR (get_value))
+ {
+ ecma_deref_object (new_array_p);
+ return get_value;
+ }
+
+ ecma_value_t operation_value;
if (ecma_is_value_found (get_value))
{
/* 13.b.iv */
- ECMA_TRY_CATCH (put_value,
- ecma_op_object_put (obj_p, to_str_p, get_value, true),
- ret_value);
-
- ECMA_FINALIZE (put_value);
+ operation_value = ecma_op_object_put_by_uint32_index (obj_p, to, get_value, true);
+ ecma_free_value (get_value);
}
else
{
/* 13.b.v */
- ECMA_TRY_CATCH (del_value,
- ecma_op_object_delete (obj_p, to_str_p, true),
- ret_value);
-
- ECMA_FINALIZE (del_value);
+ operation_value = ecma_op_object_delete_by_uint32_index (obj_p, to, true);
}
- ECMA_FINALIZE (get_value);
-
- ecma_deref_ecma_string (to_str_p);
- ecma_deref_ecma_string (from_str_p);
+ if (ECMA_IS_VALUE_ERROR (operation_value))
+ {
+ ecma_deref_object (new_array_p);
+ return operation_value;
+ }
}
}
}
/* 15. */
ecma_length_t idx = 0;
- for (ecma_length_t arg_index = 2;
- arg_index < args_number && ecma_is_value_empty (ret_value);
- arg_index++, idx++)
+ for (ecma_length_t arg_index = 2; arg_index < args_number; arg_index++, idx++)
{
- ecma_string_t *str_idx_p = ecma_new_ecma_string_from_uint32 ((uint32_t) (start + idx));
- ECMA_TRY_CATCH (put_value,
- ecma_op_object_put (obj_p, str_idx_p, args[arg_index], true),
- ret_value);
+ ecma_value_t put_value = ecma_op_object_put_by_uint32_index (obj_p,
+ (uint32_t) (start + idx),
+ args[arg_index],
+ true);
- ECMA_FINALIZE (put_value);
- ecma_deref_ecma_string (str_idx_p);
+ if (ECMA_IS_VALUE_ERROR (put_value))
+ {
+ ecma_deref_object (new_array_p);
+ return put_value;
+ }
}
/* 16. */
- if (ecma_is_value_empty (ret_value))
- {
- ECMA_TRY_CATCH (set_length_value,
- ecma_builtin_array_prototype_helper_set_length (obj_p, ((ecma_number_t) new_len)),
- ret_value);
+ ecma_value_t set_length_value = ecma_builtin_array_prototype_helper_set_length (obj_p, ((ecma_number_t) new_len));
- ECMA_FINALIZE (set_length_value);
- }
-
- if (ecma_is_value_empty (ret_value))
+ if (ECMA_IS_VALUE_ERROR (set_length_value))
{
- ret_value = new_array;
- }
- else
- {
- ecma_free_value (new_array);
+ ecma_deref_object (new_array_p);
+ return set_length_value;
}
- return ret_value;
+ return new_array;
} /* ecma_builtin_array_prototype_object_splice */
/**
@@ -1319,64 +1351,60 @@ ecma_builtin_array_prototype_object_unshift (const ecma_value_t args[], /**< arg
ecma_object_t *obj_p, /**< array object */
uint32_t len) /**< array object's length */
{
- ecma_value_t ret_value = ECMA_VALUE_EMPTY;
-
/* 5. and 6. */
- for (uint32_t k = len; k > 0 && ecma_is_value_empty (ret_value); k--)
+ for (uint32_t k = len; k > 0; k--)
{
- /* 6.a */
- ecma_string_t *from_str_p = ecma_new_ecma_string_from_uint32 (k - 1);
+ /* 6.a, 6.c*/
+ ecma_value_t get_value = ecma_op_object_find_by_uint32_index (obj_p, k - 1);
+
+ if (ECMA_IS_VALUE_ERROR (get_value))
+ {
+ return get_value;
+ }
+
/* 6.b */
ecma_number_t new_idx = ((ecma_number_t) k) + ((ecma_number_t) args_number) - 1;
- ecma_string_t *to_str_p = ecma_new_ecma_string_from_number (new_idx);
-
- /* 6.c */
- ECMA_TRY_CATCH (get_value, ecma_op_object_find (obj_p, from_str_p), ret_value);
+ ecma_value_t operation_value;
if (ecma_is_value_found (get_value))
{
/* 6.d.i, 6.d.ii */
- ECMA_TRY_CATCH (put_value, ecma_op_object_put (obj_p, to_str_p, get_value, true), ret_value);
-
- ECMA_FINALIZE (put_value);
+ operation_value = ecma_op_object_put_by_number_index (obj_p, new_idx, get_value, true);
+ ecma_free_value (get_value);
}
else
{
/* 6.e.i */
- ECMA_TRY_CATCH (del_value, ecma_op_object_delete (obj_p, to_str_p, true), ret_value);
- ECMA_FINALIZE (del_value);
+ operation_value = ecma_op_object_delete_by_number_index (obj_p, new_idx, true);
}
- ECMA_FINALIZE (get_value);
-
- ecma_deref_ecma_string (to_str_p);
- ecma_deref_ecma_string (from_str_p);
+ if (ECMA_IS_VALUE_ERROR (operation_value))
+ {
+ return operation_value;
+ }
}
- for (uint32_t arg_index = 0;
- arg_index < args_number && ecma_is_value_empty (ret_value);
- arg_index++)
+ for (uint32_t arg_index = 0; arg_index < args_number; arg_index++)
{
- ecma_string_t *to_str_p = ecma_new_ecma_string_from_uint32 (arg_index);
/* 9.b */
- ECMA_TRY_CATCH (put_value, ecma_op_object_put (obj_p, to_str_p, args[arg_index], true), ret_value);
- ECMA_FINALIZE (put_value);
- ecma_deref_ecma_string (to_str_p);
+ ecma_value_t put_value = ecma_op_object_put_by_uint32_index (obj_p, arg_index, args[arg_index], true);
+
+ if (ECMA_IS_VALUE_ERROR (put_value))
+ {
+ return put_value;
+ }
}
- if (ecma_is_value_empty (ret_value))
- {
- ecma_number_t new_len = ((ecma_number_t) len) + ((ecma_number_t) args_number);
- /* 10. */
- ECMA_TRY_CATCH (set_length_value,
- ecma_builtin_array_prototype_helper_set_length (obj_p, new_len),
- ret_value);
- ret_value = ecma_make_number_value (new_len);
+ /* 10. */
+ ecma_number_t new_len = ((ecma_number_t) len) + ((ecma_number_t) args_number);
+ ecma_value_t set_length_value = ecma_builtin_array_prototype_helper_set_length (obj_p, new_len);
- ECMA_FINALIZE (set_length_value);
+ if (ECMA_IS_VALUE_ERROR (set_length_value))
+ {
+ return set_length_value;
}
- return ret_value;
+ return ecma_make_number_value (new_len);
} /* ecma_builtin_array_prototype_object_unshift */
/**
@@ -1400,48 +1428,40 @@ ecma_builtin_array_prototype_object_index_of (ecma_value_t arg1, /**< searchElem
return ecma_make_integer_value (-1);
}
- ecma_value_t ret_value = ECMA_VALUE_EMPTY;
-
/* 5. */
- ECMA_OP_TO_NUMBER_TRY_CATCH (arg_from_idx, arg2, ret_value);
+ ecma_number_t arg_from_idx;
+
+ if (ECMA_IS_VALUE_ERROR (ecma_get_number (arg2, &arg_from_idx)))
+ {
+ return ECMA_VALUE_ERROR;
+ }
ecma_number_t found_index = ECMA_NUMBER_MINUS_ONE;
uint32_t from_idx = ecma_builtin_helper_array_index_normalize (arg_from_idx, len);
/* 6. */
- if (from_idx < len)
+ for (; from_idx < len && found_index < 0; from_idx++)
{
- JERRY_ASSERT (from_idx < len);
+ /* 9.a */
+ ecma_value_t get_value = ecma_op_object_find_by_uint32_index (obj_p, from_idx);
- for (; from_idx < len && found_index < 0 && ecma_is_value_empty (ret_value); from_idx++)
+ if (ECMA_IS_VALUE_ERROR (get_value))
{
- ecma_string_t *idx_str_p = ecma_new_ecma_string_from_uint32 (from_idx);
-
- /* 9.a */
- ECMA_TRY_CATCH (get_value, ecma_op_object_find (obj_p, idx_str_p), ret_value);
-
- /* 9.b.i, 9.b.ii */
- if (ecma_is_value_found (get_value)
- && ecma_op_strict_equality_compare (arg1, get_value))
- {
- found_index = ((ecma_number_t) from_idx);
- }
-
- ECMA_FINALIZE (get_value);
+ return get_value;
+ }
- ecma_deref_ecma_string (idx_str_p);
+ /* 9.b.i, 9.b.ii */
+ if (ecma_is_value_found (get_value)
+ && ecma_op_strict_equality_compare (arg1, get_value))
+ {
+ found_index = ((ecma_number_t) from_idx);
}
- }
- if (ecma_is_value_empty (ret_value))
- {
- ret_value = ecma_make_number_value (found_index);
+ ecma_free_value (get_value);
}
- ECMA_OP_TO_NUMBER_FINALIZE (arg_from_idx);
-
- return ret_value;
+ return ecma_make_number_value (found_index);
} /* ecma_builtin_array_prototype_object_index_of */
/**
@@ -1465,17 +1485,19 @@ ecma_builtin_array_prototype_object_last_index_of (const ecma_value_t args[], /*
return ecma_make_integer_value (-1);
}
- ecma_value_t ret_value = ECMA_VALUE_EMPTY;
uint32_t from_idx = len - 1;
/* 5. */
if (args_number > 1)
{
- ECMA_OP_TO_NUMBER_TRY_CATCH (arg_from_idx, args[1], ret_value);
+ ecma_number_t arg_from_idx;
+ if (ECMA_IS_VALUE_ERROR (ecma_get_number (args[1], &arg_from_idx)))
+ {
+ return ECMA_VALUE_ERROR;
+ }
if (!ecma_number_is_nan (arg_from_idx))
{
-
if (ecma_number_is_infinity (arg_from_idx))
{
from_idx = ecma_number_is_negative (arg_from_idx) ? (uint32_t) -1 : len - 1;
@@ -1522,8 +1544,6 @@ ecma_builtin_array_prototype_object_last_index_of (const ecma_value_t args[], /*
{
from_idx = 0;
}
-
- ECMA_OP_TO_NUMBER_FINALIZE (arg_from_idx);
}
ecma_number_t num = ECMA_NUMBER_MINUS_ONE;
@@ -1534,13 +1554,15 @@ ecma_builtin_array_prototype_object_last_index_of (const ecma_value_t args[], /*
* for an underflow instead. This is safe, because from_idx will always start in [0, len - 1],
* and len is in [0, UINT_MAX], so from_idx >= len means we've had an underflow, and should stop.
*/
- for (; from_idx < len && num < 0 && ecma_is_value_empty (ret_value); from_idx--)
+ for (; from_idx < len && num < 0; from_idx--)
{
/* 8.a */
- ecma_string_t *idx_str_p = ecma_new_ecma_string_from_uint32 (from_idx);
+ ecma_value_t get_value = ecma_op_object_find_by_uint32_index (obj_p, from_idx);
- /* 8.a */
- ECMA_TRY_CATCH (get_value, ecma_op_object_find (obj_p, idx_str_p), ret_value);
+ if (ECMA_IS_VALUE_ERROR (get_value))
+ {
+ return get_value;
+ }
/* 8.b.i, 8.b.ii */
if (ecma_is_value_found (get_value)
@@ -1549,17 +1571,10 @@ ecma_builtin_array_prototype_object_last_index_of (const ecma_value_t args[], /*
num = ((ecma_number_t) from_idx);
}
- ECMA_FINALIZE (get_value);
-
- ecma_deref_ecma_string (idx_str_p);
- }
-
- if (ecma_is_value_empty (ret_value))
- {
- ret_value = ecma_make_number_value (num);
+ ecma_free_value (get_value);
}
- return ret_value;
+ return ecma_make_number_value (num);
} /* ecma_builtin_array_prototype_object_last_index_of */
/**
@@ -1602,22 +1617,20 @@ ecma_builtin_array_apply (ecma_value_t arg1, /**< callbackfn */
return ecma_raise_type_error (ECMA_ERR_MSG ("Callback function is not callable."));
}
- /* We already checked that arg1 is callable, so it will always coerce to an object. */
- ecma_value_t to_object_comp = ecma_op_to_object (arg1);
- JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (to_object_comp));
-
- ecma_object_t *func_object_p = ecma_get_object_from_value (to_object_comp);
- ecma_value_t ret_value = ECMA_VALUE_EMPTY;
+ /* We already checked that arg1 is callable */
+ ecma_object_t *func_object_p = ecma_get_object_from_value (arg1);
ecma_value_t current_index;
/* 7. */
- for (uint32_t index = 0; index < len && ecma_is_value_empty (ret_value); index++)
+ for (uint32_t index = 0; index < len; index++)
{
- /* 7.a */
- ecma_string_t *index_str_p = ecma_new_ecma_string_from_uint32 (index);
+ /* 7.a - 7.c */
+ ecma_value_t get_value = ecma_op_object_find_by_uint32_index (obj_p, index);
- /* 7.c */
- ECMA_TRY_CATCH (get_value, ecma_op_object_find (obj_p, index_str_p), ret_value);
+ if (ECMA_IS_VALUE_ERROR (get_value))
+ {
+ return get_value;
+ }
if (ecma_is_value_found (get_value))
{
@@ -1626,46 +1639,44 @@ ecma_builtin_array_apply (ecma_value_t arg1, /**< callbackfn */
ecma_value_t call_args[] = { get_value, current_index, ecma_make_object_value (obj_p) };
/* 7.c.ii */
- ECMA_TRY_CATCH (call_value, ecma_op_function_call (func_object_p, arg2, call_args, 3), ret_value);
+ ecma_value_t call_value = ecma_op_function_call (func_object_p, arg2, call_args, 3);
+
+ if (ECMA_IS_VALUE_ERROR (call_value))
+ {
+ ecma_free_value (get_value);
+ return call_value;
+ }
+
+ bool to_boolean = ecma_op_to_boolean (call_value);
+
+ ecma_free_value (call_value);
+ ecma_free_value (get_value);
/* 7.c.iii */
- if (mode == ARRAY_ROUTINE_EVERY && !ecma_op_to_boolean (call_value))
+ if (mode == ARRAY_ROUTINE_EVERY && !to_boolean)
{
- ret_value = ECMA_VALUE_FALSE;
+ return ECMA_VALUE_FALSE;
}
- else if (mode == ARRAY_ROUTINE_SOME && ecma_op_to_boolean (call_value))
+ else if (mode == ARRAY_ROUTINE_SOME && to_boolean)
{
- ret_value = ECMA_VALUE_TRUE;
+ return ECMA_VALUE_TRUE;
}
-
- ECMA_FINALIZE (call_value);
}
-
- ECMA_FINALIZE (get_value);
-
- ecma_deref_ecma_string (index_str_p);
}
- ecma_free_value (to_object_comp);
-
/* 8. */
- if (ecma_is_value_empty (ret_value))
+
+ if (mode == ARRAY_ROUTINE_EVERY)
{
- if (mode == ARRAY_ROUTINE_EVERY)
- {
- ret_value = ECMA_VALUE_TRUE;
- }
- else if (mode == ARRAY_ROUTINE_SOME)
- {
- ret_value = ECMA_VALUE_FALSE;
- }
- else
- {
- ret_value = ECMA_VALUE_UNDEFINED;
- }
+ return ECMA_VALUE_TRUE;
+ }
+ else if (mode == ARRAY_ROUTINE_SOME)
+ {
+ return ECMA_VALUE_FALSE;
}
- return ret_value;
+ JERRY_ASSERT (mode == ARRAY_ROUTINE_FOREACH);
+ return ECMA_VALUE_UNDEFINED;
} /* ecma_builtin_array_apply */
/**
@@ -1709,15 +1720,17 @@ ecma_builtin_array_prototype_object_map (ecma_value_t arg1, /**< callbackfn */
/* 7-8. */
ecma_value_t current_index;
- ecma_value_t ret_value = ECMA_VALUE_EMPTY;
- for (uint32_t index = 0; index < len && ecma_is_value_empty (ret_value); index++)
+ for (uint32_t index = 0; index < len; index++)
{
- /* 8.a */
- ecma_string_t *index_str_p = ecma_new_ecma_string_from_uint32 (index);
+ /* 8.a - 8.b */
+ ecma_value_t current_value = ecma_op_object_find_by_uint32_index (obj_p, index);
- /* 8.b */
- ECMA_TRY_CATCH (current_value, ecma_op_object_find (obj_p, index_str_p), ret_value);
+ if (ECMA_IS_VALUE_ERROR (current_value))
+ {
+ ecma_deref_object (new_array_p);
+ return current_value;
+ }
if (ecma_is_value_found (current_value))
{
@@ -1725,39 +1738,39 @@ ecma_builtin_array_prototype_object_map (ecma_value_t arg1, /**< callbackfn */
current_index = ecma_make_uint32_value (index);
ecma_value_t call_args[] = { current_value, current_index, ecma_make_object_value (obj_p) };
- ECMA_TRY_CATCH (mapped_value, ecma_op_function_call (func_object_p, arg2, call_args, 3), ret_value);
+ ecma_value_t mapped_value = ecma_op_function_call (func_object_p, arg2, call_args, 3);
+
+ if (ECMA_IS_VALUE_ERROR (mapped_value))
+ {
+ ecma_free_value (current_value);
+ ecma_deref_object (new_array_p);
+ return mapped_value;
+ }
/* 8.c.iii */
/* This will always be a simple value since 'is_throw' is false, so no need to free. */
- ecma_value_t put_comp = ecma_builtin_helper_def_prop (new_array_p,
- index_str_p,
- mapped_value,
- ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
- false); /* Failure handling */
+ ecma_value_t put_comp = ecma_builtin_helper_def_prop_by_index (new_array_p,
+ index,
+ mapped_value,
+ ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
+ false); /* Failure handling */
JERRY_ASSERT (ecma_is_value_true (put_comp));
- ECMA_FINALIZE (mapped_value);
+ ecma_free_value (mapped_value);
+ ecma_free_value (current_value);
}
+ }
- ECMA_FINALIZE (current_value);
- ecma_deref_ecma_string (index_str_p);
- }
+ ecma_value_t set_length_value = ecma_builtin_array_prototype_helper_set_length (new_array_p, ((ecma_number_t) len));
- if (ecma_is_value_empty (ret_value))
+ if (ECMA_IS_VALUE_ERROR (set_length_value))
{
- ECMA_TRY_CATCH (set_length_value,
- ecma_builtin_array_prototype_helper_set_length (new_array_p, ((ecma_number_t) len)),
- ret_value);
- ret_value = new_array;
- ECMA_FINALIZE (set_length_value);
- }
- else
- {
- ecma_free_value (new_array);
+ ecma_deref_object (new_array_p);
+ return set_length_value;
}
- return ret_value;
+ return new_array;
} /* ecma_builtin_array_prototype_object_map */
/**
@@ -1803,16 +1816,18 @@ ecma_builtin_array_prototype_object_filter (ecma_value_t arg1, /**< callbackfn *
/* 8. */
uint32_t new_array_index = 0;
ecma_value_t current_index;
- ecma_value_t ret_value = ECMA_VALUE_EMPTY;
/* 9. */
- for (uint32_t index = 0; index < len && ecma_is_value_empty (ret_value); index++)
+ for (uint32_t index = 0; index < len; index++)
{
- /* 9.a */
- ecma_string_t *index_str_p = ecma_new_ecma_string_from_uint32 (index);
+ /* 9.a - 9.c */
+ ecma_value_t get_value = ecma_op_object_find_by_uint32_index (obj_p, index);
- /* 9.c */
- ECMA_TRY_CATCH (get_value, ecma_op_object_find (obj_p, index_str_p), ret_value);
+ if (ECMA_IS_VALUE_ERROR (get_value))
+ {
+ ecma_deref_object (new_array_p);
+ return get_value;
+ }
if (ecma_is_value_found (get_value))
{
@@ -1821,44 +1836,34 @@ ecma_builtin_array_prototype_object_filter (ecma_value_t arg1, /**< callbackfn *
ecma_value_t call_args[] = { get_value, current_index, ecma_make_object_value (obj_p) };
/* 9.c.ii */
- ECMA_TRY_CATCH (call_value, ecma_op_function_call (func_object_p, arg2, call_args, 3), ret_value);
+ ecma_value_t call_value = ecma_op_function_call (func_object_p, arg2, call_args, 3);
+
+ if (ECMA_IS_VALUE_ERROR (call_value))
+ {
+ ecma_free_value (get_value);
+ ecma_deref_object (new_array_p);
+ return call_value;
+ }
/* 9.c.iii */
if (ecma_op_to_boolean (call_value))
{
- ecma_string_t *to_index_string_p = ecma_new_ecma_string_from_uint32 (new_array_index);
-
/* This will always be a simple value since 'is_throw' is false, so no need to free. */
- ecma_value_t put_comp = ecma_builtin_helper_def_prop (new_array_p,
- to_index_string_p,
- get_value,
- ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
- false); /* Failure handling */
+ ecma_value_t put_comp = ecma_builtin_helper_def_prop_by_index (new_array_p,
+ new_array_index,
+ get_value,
+ ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
+ false); /* Failure handling */
JERRY_ASSERT (ecma_is_value_true (put_comp));
-
- ecma_deref_ecma_string (to_index_string_p);
new_array_index++;
}
- ECMA_FINALIZE (call_value);
+ ecma_free_value (call_value);
+ ecma_free_value (get_value);
}
-
- ECMA_FINALIZE (get_value);
-
- ecma_deref_ecma_string (index_str_p);
- }
-
- if (ecma_is_value_empty (ret_value))
- {
- /* 10. */
- ret_value = new_array;
- }
- else
- {
- ecma_free_value (new_array);
}
- return ret_value;
+ return new_array;
} /* ecma_builtin_array_prototype_object_filter */
/**
@@ -1894,7 +1899,6 @@ ecma_builtin_array_reduce_from (ecma_value_t callbackfn, /**< routine's 1st argu
JERRY_ASSERT (ecma_is_value_object (callbackfn));
ecma_object_t *func_object_p = ecma_get_object_from_value (callbackfn);
- ecma_value_t ret_value = ECMA_VALUE_EMPTY;
ecma_value_t accumulator = ECMA_VALUE_UNDEFINED;
/* 6. */
@@ -1912,51 +1916,54 @@ ecma_builtin_array_reduce_from (ecma_value_t callbackfn, /**< routine's 1st argu
bool k_present = false;
/* 8.b */
- while (!k_present && index < len && ecma_is_value_empty (ret_value))
+ while (!k_present && index < len)
{
/* 8.b.i */
- ecma_string_t *index_str_p = ecma_new_ecma_string_from_uint32 (start_from_left ? index
- : last_index - index);
k_present = true;
/* 8.b.ii-iii */
- ECMA_TRY_CATCH (current_value, ecma_op_object_find (obj_p, index_str_p), ret_value);
+ ecma_value_t current_value = ecma_op_object_find_by_uint32_index (obj_p, start_from_left ? index :
+ last_index - index);
+
+ if (ECMA_IS_VALUE_ERROR (current_value))
+ {
+ return current_value;
+ }
if (ecma_is_value_found (current_value))
{
- accumulator = ecma_copy_value (current_value);
+ accumulator = current_value;
}
else
{
k_present = false;
}
- ECMA_FINALIZE (current_value);
-
/* 8.b.iv */
index++;
-
- ecma_deref_ecma_string (index_str_p);
}
/* 8.c */
if (!k_present)
{
- ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Missing array element."));
+ return ecma_raise_type_error (ECMA_ERR_MSG ("Missing array element."));
}
}
/* 9. */
ecma_value_t current_index;
- for (; index < len && ecma_is_value_empty (ret_value); index++)
+ for (; index < len; index++)
{
const uint32_t corrected_index = start_from_left ? index : last_index - index;
- /* 9.a */
- ecma_string_t *index_str_p = ecma_new_ecma_string_from_uint32 (corrected_index);
+ /* 9.a - 9.b */
+ ecma_value_t current_value = ecma_op_object_find_by_uint32_index (obj_p, corrected_index);
- /* 9.b */
- ECMA_TRY_CATCH (current_value, ecma_op_object_find (obj_p, index_str_p), ret_value);
+ if (ECMA_IS_VALUE_ERROR (current_value))
+ {
+ ecma_free_value (accumulator);
+ return current_value;
+ }
if (ecma_is_value_found (current_value))
{
@@ -1964,34 +1971,24 @@ ecma_builtin_array_reduce_from (ecma_value_t callbackfn, /**< routine's 1st argu
current_index = ecma_make_uint32_value (corrected_index);
ecma_value_t call_args[] = {accumulator, current_value, current_index, ecma_make_object_value (obj_p)};
- ECMA_TRY_CATCH (call_value,
- ecma_op_function_call (func_object_p,
- ECMA_VALUE_UNDEFINED,
- call_args,
- 4),
- ret_value);
-
+ ecma_value_t call_value = ecma_op_function_call (func_object_p,
+ ECMA_VALUE_UNDEFINED,
+ call_args,
+ 4);
+ ecma_free_value (current_index);
ecma_free_value (accumulator);
- accumulator = ecma_copy_value (call_value);
+ ecma_free_value (current_value);
- ECMA_FINALIZE (call_value);
- }
-
- ECMA_FINALIZE (current_value);
-
- ecma_deref_ecma_string (index_str_p);
-
- /* 9.d in for loop */
- }
+ if (ECMA_IS_VALUE_ERROR (call_value))
+ {
+ return call_value;
+ }
- if (ecma_is_value_empty (ret_value))
- {
- ret_value = ecma_copy_value (accumulator);
+ accumulator = call_value;
+ }
}
- ecma_free_value (accumulator);
-
- return ret_value;
+ return accumulator;
} /* ecma_builtin_array_reduce_from */
#if ENABLED (JERRY_ES2015_BUILTIN)
@@ -2024,16 +2021,16 @@ ecma_builtin_array_prototype_object_find (ecma_value_t predicate, /**< callback
JERRY_ASSERT (ecma_is_value_object (predicate));
ecma_object_t *func_object_p = ecma_get_object_from_value (predicate);
- ecma_value_t ret_value = ECMA_VALUE_EMPTY;
-
/* 7 - 8. */
- for (uint32_t index = 0; index < len && ecma_is_value_empty (ret_value); index++)
+ for (uint32_t index = 0; index < len; index++)
{
- /* 8.a */
- ecma_string_t *index_str_p = ecma_new_ecma_string_from_uint32 (index);
+ /* 8.a - 8.c */
+ ecma_value_t get_value = ecma_op_object_find_by_uint32_index (obj_p, index);
- /* 8.b - 8.c */
- ECMA_TRY_CATCH (get_value, ecma_op_object_find (obj_p, index_str_p), ret_value);
+ if (ECMA_IS_VALUE_ERROR (get_value))
+ {
+ return get_value;
+ }
if (ecma_is_value_found (get_value))
{
@@ -2042,29 +2039,34 @@ ecma_builtin_array_prototype_object_find (ecma_value_t predicate, /**< callback
ecma_value_t call_args[] = { get_value, current_index, ecma_make_object_value (obj_p) };
- ECMA_TRY_CATCH (call_value, ecma_op_function_call (func_object_p, predicate_this_arg, call_args, 3), ret_value);
+ ecma_value_t call_value = ecma_op_function_call (func_object_p, predicate_this_arg, call_args, 3);
+
+ if (ECMA_IS_VALUE_ERROR (call_value))
+ {
+ ecma_free_value (get_value);
+ return call_value;
+ }
if (ecma_op_to_boolean (call_value))
{
/* 8.f */
- ret_value = is_find ? ecma_copy_value (get_value) : current_index;
+ if (is_find)
+ {
+ return get_value;
+ }
+
+ ecma_free_value (get_value);
+ return current_index;
}
- ECMA_FINALIZE (call_value);
+ ecma_free_value (call_value);
+ ecma_free_value (get_value);
+ ecma_free_value (current_index);
}
-
- ECMA_FINALIZE (get_value);
-
- ecma_deref_ecma_string (index_str_p);
- }
-
- if (ecma_is_value_empty (ret_value))
- {
- /* 9. */
- ret_value = is_find ? ECMA_VALUE_UNDEFINED : ecma_make_integer_value (-1);
}
- return ret_value;
+ /* 9. */
+ return is_find ? ECMA_VALUE_UNDEFINED : ecma_make_integer_value (-1);
} /* ecma_builtin_array_prototype_object_find */
#endif /* ENABLED (JERRY_ES2015_BUILTIN) */
diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.c b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.c
index 3276c2e3..7537b062 100644
--- a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.c
+++ b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.c
@@ -472,11 +472,6 @@ ecma_builtin_helper_array_concat_value (ecma_object_t *obj_p, /**< array */
ecma_deref_ecma_string (new_array_index_string_p);
}
- if (ecma_is_value_empty (ret_value))
- {
- ret_value = ECMA_VALUE_TRUE;
- }
-
return ret_value;
} /* ecma_builtin_helper_array_concat_value */
@@ -796,6 +791,41 @@ ecma_builtin_helper_string_find_index (ecma_string_t *original_str_p, /**< index
} /* ecma_builtin_helper_string_find_index */
/**
+ * Helper function for using [[DefineOwnProperty]] specialized for indexed property names
+ *
+ * Note: this method falls back to the general ecma_builtin_helper_def_prop
+ *
+ * @return ecma value
+ * Returned value must be freed with ecma_free_value.
+ */
+ecma_value_t
+ecma_builtin_helper_def_prop_by_index (ecma_object_t *obj_p, /**< object */
+ uint32_t index, /**< property index */
+ ecma_value_t value, /**< value */
+ uint32_t opts, /**< any combination of ecma_property_flag_t bits */
+ bool is_throw) /**< is_throw */
+{
+ if (JERRY_LIKELY (index <= ECMA_DIRECT_STRING_MAX_IMM))
+ {
+ return ecma_builtin_helper_def_prop (obj_p,
+ ECMA_CREATE_DIRECT_UINT32_STRING (index),
+ value,
+ opts,
+ is_throw);
+ }
+
+ ecma_string_t *index_str_p = ecma_new_non_direct_string_from_uint32 (index);
+ ecma_value_t ret_value = ecma_builtin_helper_def_prop (obj_p,
+ index_str_p,
+ value,
+ opts,
+ is_throw);
+ ecma_deref_ecma_string (index_str_p);
+
+ return ret_value;
+} /* ecma_builtin_helper_def_prop_by_index */
+
+/**
* Helper function for using [[DefineOwnProperty]].
*
* See also:
diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h
index 3bd44d79..2cb1d45d 100644
--- a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h
+++ b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h
@@ -60,6 +60,9 @@ ecma_builtin_helper_string_find_index (ecma_string_t *original_str_p, ecma_strin
ecma_value_t
ecma_builtin_helper_def_prop (ecma_object_t *obj_p, ecma_string_t *index_p, ecma_value_t value,
uint32_t opts, bool is_throw);
+ecma_value_t
+ecma_builtin_helper_def_prop_by_index (ecma_object_t *obj_p, uint32_t index, ecma_value_t value,
+ uint32_t opts, bool is_throw);
#if ENABLED (JERRY_BUILTIN_DATE)
diff --git a/jerry-core/ecma/operations/ecma-objects.c b/jerry-core/ecma/operations/ecma-objects.c
index 95305312..626905da 100644
--- a/jerry-core/ecma/operations/ecma-objects.c
+++ b/jerry-core/ecma/operations/ecma-objects.c
@@ -603,6 +603,51 @@ ecma_op_object_find_own (ecma_value_t base_value, /**< base value */
} /* ecma_op_object_find_own */
/**
+ * Search the value corresponding to an uint32_t property index
+ *
+ * Note: this method falls back to the general ecma_op_object_find
+ *
+ * @return ecma value if property is found
+ * ECMA_VALUE_NOT_FOUND if property is not found
+ * Returned value must be freed with ecma_free_value
+ */
+ecma_value_t
+ecma_op_object_find_by_uint32_index (ecma_object_t *object_p, /**< the object */
+ uint32_t index) /**< property index */
+{
+ if (JERRY_LIKELY (index <= ECMA_DIRECT_STRING_MAX_IMM))
+ {
+ return ecma_op_object_find (object_p, ECMA_CREATE_DIRECT_UINT32_STRING (index));
+ }
+
+ ecma_string_t *index_str_p = ecma_new_non_direct_string_from_uint32 (index);
+ ecma_value_t ret_value = ecma_op_object_find (object_p, index_str_p);
+ ecma_deref_ecma_string (index_str_p);
+
+ return ret_value;
+} /* ecma_op_object_find_by_uint32_index */
+
+/**
+ * Search the value corresponding to an ecma_number_t property index
+ *
+ * Note: this method falls back to the general ecma_op_object_find
+ *
+ * @return ecma value if property is found
+ * ECMA_VALUE_NOT_FOUND if property is not found
+ * Returned value must be freed with ecma_free_value
+ */
+ecma_value_t
+ecma_op_object_find_by_number_index (ecma_object_t *object_p, /**< the object */
+ ecma_number_t index) /**< property index */
+{
+ ecma_string_t *index_str_p = ecma_new_ecma_string_from_number (index);
+ ecma_value_t ret_value = ecma_op_object_find (object_p, index_str_p);
+ ecma_deref_ecma_string (index_str_p);
+
+ return ret_value;
+} /* ecma_op_object_find_by_number_index */
+
+/**
* Search the value corresponding to a property name
*
* Note: search includes prototypes
@@ -809,6 +854,56 @@ ecma_op_get_method_by_symbol_id (ecma_value_t value, /**< ecma value */
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
/**
+ * [[Put]] ecma general object's operation specialized for uint32_ property index
+ *
+ * Note: This function falls back to the general ecma_op_object_put
+ *
+ * @return ecma value
+ * The returned value must be freed with ecma_free_value.
+ */
+ecma_value_t
+ecma_op_object_put_by_uint32_index (ecma_object_t *object_p, /**< the object */
+ uint32_t index, /**< property index */
+ ecma_value_t value, /**< ecma value */
+ bool is_throw) /**< flag that controls failure handling */
+{
+ if (JERRY_LIKELY (index <= ECMA_DIRECT_STRING_MAX_IMM))
+ {
+ return ecma_op_object_put (object_p,
+ ECMA_CREATE_DIRECT_UINT32_STRING (index),
+ value,
+ is_throw);
+ }
+
+ ecma_string_t *index_str_p = ecma_new_non_direct_string_from_uint32 (index);
+ ecma_value_t ret_value = ecma_op_object_put (object_p, index_str_p, value, is_throw);
+ ecma_deref_ecma_string (index_str_p);
+
+ return ret_value;
+} /* ecma_op_object_put_by_uint32_index */
+
+/**
+ * [[Put]] ecma general object's operation specialized for ecma_number_ property index
+ *
+ * Note: This function falls back to the general ecma_op_object_put
+ *
+ * @return ecma value
+ * The returned value must be freed with ecma_free_value.
+ */
+ecma_value_t
+ecma_op_object_put_by_number_index (ecma_object_t *object_p, /**< the object */
+ ecma_number_t index, /**< property index */
+ ecma_value_t value, /**< ecma value */
+ bool is_throw) /**< flag that controls failure handling */
+{
+ ecma_string_t *index_str_p = ecma_new_ecma_string_from_number (index);
+ ecma_value_t ret_value = ecma_op_object_put (object_p, index_str_p, value, is_throw);
+ ecma_deref_ecma_string (index_str_p);
+
+ return ret_value;
+} /* ecma_op_object_put_by_number_index */
+
+/**
* [[Put]] ecma general object's operation
*
* See also:
@@ -1098,6 +1193,53 @@ ecma_op_object_put (ecma_object_t *object_p, /**< the object */
} /* ecma_op_object_put */
/**
+ * [[Delete]] ecma object's operation specialized for uint32_t property index
+ *
+ * Note:
+ * This method falls back to the general ecma_op_object_delete
+ *
+ * @return true - if deleted successfully
+ * false - or type error otherwise (based in 'is_throw')
+ */
+ecma_value_t
+ecma_op_object_delete_by_uint32_index (ecma_object_t *obj_p, /**< the object */
+ uint32_t index, /**< property index */
+ bool is_throw) /**< flag that controls failure handling */
+{
+ if (JERRY_LIKELY (index <= ECMA_DIRECT_STRING_MAX_IMM))
+ {
+ return ecma_op_object_delete (obj_p, ECMA_CREATE_DIRECT_UINT32_STRING (index), is_throw);
+ }
+
+ ecma_string_t *index_str_p = ecma_new_non_direct_string_from_uint32 (index);
+ ecma_value_t ret_value = ecma_op_object_delete (obj_p, index_str_p, is_throw);
+ ecma_deref_ecma_string (index_str_p);
+
+ return ret_value;
+} /* ecma_op_object_delete_by_uint32_index */
+
+/**
+ * [[Delete]] ecma object's operation specialized for ecma_number_t property index
+ *
+ * Note:
+ * This method falls back to the general ecma_op_object_delete
+ *
+ * @return true - if deleted successfully
+ * false - or type error otherwise (based in 'is_throw')
+ */
+ecma_value_t
+ecma_op_object_delete_by_number_index (ecma_object_t *obj_p, /**< the object */
+ ecma_number_t index, /**< property index */
+ bool is_throw) /**< flag that controls failure handling */
+{
+ ecma_string_t *index_str_p = ecma_new_ecma_string_from_number (index);
+ ecma_value_t ret_value = ecma_op_object_delete (obj_p, index_str_p, is_throw);
+ ecma_deref_ecma_string (index_str_p);
+
+ return ret_value;
+} /* ecma_op_object_delete_by_number_index */
+
+/**
* [[Delete]] ecma object's operation
*
* See also:
diff --git a/jerry-core/ecma/operations/ecma-objects.h b/jerry-core/ecma/operations/ecma-objects.h
index d0c9ef72..436a90b1 100644
--- a/jerry-core/ecma/operations/ecma-objects.h
+++ b/jerry-core/ecma/operations/ecma-objects.h
@@ -32,6 +32,8 @@ bool ecma_op_object_has_own_property (ecma_object_t *object_p, ecma_string_t *pr
bool ecma_op_object_has_property (ecma_object_t *object_p, ecma_string_t *property_name_p);
ecma_value_t ecma_op_object_find_own (ecma_value_t base_value, ecma_object_t *object_p, ecma_string_t *property_name_p);
ecma_value_t ecma_op_object_find (ecma_object_t *object_p, ecma_string_t *property_name_p);
+ecma_value_t ecma_op_object_find_by_uint32_index (ecma_object_t *object_p, uint32_t index);
+ecma_value_t ecma_op_object_find_by_number_index (ecma_object_t *object_p, ecma_number_t index);
ecma_value_t ecma_op_object_get_own_data_prop (ecma_object_t *object_p, ecma_string_t *property_name_p);
ecma_value_t ecma_op_object_get (ecma_object_t *object_p, ecma_string_t *property_name_p);
ecma_value_t ecma_op_object_get_by_magic_id (ecma_object_t *object_p, lit_magic_string_id_t property_id);
@@ -41,7 +43,13 @@ ecma_value_t ecma_op_get_method_by_symbol_id (ecma_value_t value, lit_magic_stri
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
ecma_value_t ecma_op_object_put (ecma_object_t *object_p, ecma_string_t *property_name_p, ecma_value_t value,
bool is_throw);
+ecma_value_t ecma_op_object_put_by_uint32_index (ecma_object_t *object_p, uint32_t index,
+ ecma_value_t value, bool is_throw);
+ecma_value_t ecma_op_object_put_by_number_index (ecma_object_t *object_p, ecma_number_t index,
+ ecma_value_t value, bool is_throw);
ecma_value_t ecma_op_object_delete (ecma_object_t *obj_p, ecma_string_t *property_name_p, bool is_throw);
+ecma_value_t ecma_op_object_delete_by_uint32_index (ecma_object_t *obj_p, uint32_t index, bool is_throw);
+ecma_value_t ecma_op_object_delete_by_number_index (ecma_object_t *obj_p, ecma_number_t index, bool is_throw);
ecma_value_t ecma_op_object_default_value (ecma_object_t *obj_p, ecma_preferred_type_hint_t hint);
ecma_value_t ecma_op_object_define_own_property (ecma_object_t *obj_p, ecma_string_t *property_name_p,
const ecma_property_descriptor_t *property_desc_p, bool is_throw);
diff --git a/tools/run-tests.py b/tools/run-tests.py
index 4cde0269..af805432 100755
--- a/tools/run-tests.py
+++ b/tools/run-tests.py
@@ -37,7 +37,7 @@ OPTIONS_COMMON = ['--lto=off']
OPTIONS_PROFILE_MIN = ['--profile=minimal']
OPTIONS_PROFILE_ES51 = [] # NOTE: same as ['--profile=es5.1']
OPTIONS_PROFILE_ES2015 = ['--profile=es2015-subset']
-OPTIONS_STACK_LIMIT = ['--stack-limit=128']
+OPTIONS_STACK_LIMIT = ['--stack-limit=96']
OPTIONS_DEBUG = ['--debug']
OPTIONS_SNAPSHOT = ['--snapshot-save=on', '--snapshot-exec=on', '--jerry-cmdline-snapshot=on']
OPTIONS_UNITTESTS = ['--unittests=on', '--jerry-cmdline=off', '--error-messages=on',