Revise internal array creation operations (#4291)
JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik frobert@inf.u-szeged.hu
This commit is contained in:
+3
-14
@@ -1771,15 +1771,8 @@ jerry_create_array (uint32_t size) /**< size of array */
|
||||
{
|
||||
jerry_assert_api_available ();
|
||||
|
||||
ecma_value_t array_length = ecma_make_uint32_value (size);
|
||||
|
||||
const jerry_length_t argument_size = 1;
|
||||
ecma_value_t array_value = ecma_op_create_array_object (&array_length, argument_size, true);
|
||||
ecma_free_value (array_length);
|
||||
|
||||
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (array_value));
|
||||
|
||||
return array_value;
|
||||
ecma_object_t *array_p = ecma_op_new_array_object (size);
|
||||
return ecma_make_object_value (array_p);
|
||||
} /* jerry_create_array */
|
||||
|
||||
/**
|
||||
@@ -3329,11 +3322,7 @@ jerry_get_object_keys (const jerry_value_t obj_val) /**< object value */
|
||||
}
|
||||
#endif /* ENABLED (JERRY_BUILTIN_PROXY) */
|
||||
|
||||
ecma_value_t result_array = ecma_op_create_array_object (prop_names->buffer_p, prop_names->item_count, false);
|
||||
|
||||
ecma_collection_free (prop_names);
|
||||
|
||||
return result_array;
|
||||
return ecma_op_new_array_object_from_collection (prop_names, false);
|
||||
} /* jerry_get_object_keys */
|
||||
|
||||
/**
|
||||
|
||||
@@ -1191,6 +1191,15 @@ ecma_free_value_if_not_object (ecma_value_t value) /**< value description */
|
||||
}
|
||||
} /* ecma_free_value_if_not_object */
|
||||
|
||||
/**
|
||||
* Free an ecma-value object
|
||||
*/
|
||||
inline void JERRY_ATTR_ALWAYS_INLINE
|
||||
ecma_free_object (ecma_value_t value) /**< value description */
|
||||
{
|
||||
ecma_deref_object (ecma_get_object_from_value (value));
|
||||
} /* ecma_free_object */
|
||||
|
||||
/**
|
||||
* Free an ecma-value number
|
||||
*/
|
||||
|
||||
@@ -284,6 +284,7 @@ void ecma_value_assign_number (ecma_value_t *value_p, ecma_number_t ecma_number)
|
||||
void ecma_free_value (ecma_value_t value);
|
||||
void ecma_fast_free_value (ecma_value_t value);
|
||||
void ecma_free_value_if_not_object (ecma_value_t value);
|
||||
void ecma_free_object (ecma_value_t value);
|
||||
void ecma_free_number (ecma_value_t value);
|
||||
lit_magic_string_id_t ecma_get_typeof_lit_id (ecma_value_t value);
|
||||
|
||||
|
||||
@@ -188,18 +188,16 @@ ecma_builtin_array_prototype_object_concat (const ecma_value_t args[], /**< argu
|
||||
{
|
||||
/* 2. */
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
ecma_value_t new_array = ecma_op_array_species_create (obj_p, 0);
|
||||
ecma_object_t *new_array_p = ecma_op_array_species_create (obj_p, 0);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (new_array))
|
||||
if (JERRY_UNLIKELY (new_array_p == NULL))
|
||||
{
|
||||
return new_array;
|
||||
return ECMA_VALUE_ERROR;
|
||||
}
|
||||
#else /* !ENABLED (JERRY_ESNEXT) */
|
||||
ecma_value_t new_array = ecma_op_create_array_object (NULL, 0, false);
|
||||
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (new_array));
|
||||
ecma_object_t *new_array_p = ecma_op_new_array_object (0);
|
||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||
|
||||
ecma_object_t *new_array_p = ecma_get_object_from_value (new_array);
|
||||
ecma_length_t new_length = 0;
|
||||
|
||||
/* 5.b - 5.c for this_arg */
|
||||
@@ -236,7 +234,7 @@ ecma_builtin_array_prototype_object_concat (const ecma_value_t args[], /**< argu
|
||||
return set_length_value;
|
||||
}
|
||||
|
||||
return new_array;
|
||||
return ecma_make_object_value (new_array_p);
|
||||
} /* ecma_builtin_array_prototype_object_concat */
|
||||
|
||||
/**
|
||||
@@ -859,19 +857,17 @@ ecma_builtin_array_prototype_object_slice (ecma_value_t arg1, /**< start */
|
||||
bool use_fast_path = ecma_op_object_is_fast_array (obj_p);
|
||||
ecma_length_t copied_length = (end > start) ? end - start : 0;
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
ecma_value_t new_array = ecma_op_array_species_create (obj_p, copied_length);
|
||||
ecma_object_t *new_array_p = ecma_op_array_species_create (obj_p, copied_length);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (new_array))
|
||||
if (JERRY_UNLIKELY (new_array_p == NULL))
|
||||
{
|
||||
return new_array;
|
||||
return ECMA_VALUE_ERROR;
|
||||
}
|
||||
use_fast_path &= ecma_op_object_is_fast_array (ecma_get_object_from_value (new_array));
|
||||
#else /* !ENABLED (JERRY_ESNEXT) */
|
||||
ecma_value_t new_array = ecma_op_create_array_object (NULL, 0, false);
|
||||
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (new_array));
|
||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||
|
||||
ecma_object_t *new_array_p = ecma_get_object_from_value (new_array);
|
||||
use_fast_path &= ecma_op_object_is_fast_array (new_array_p);
|
||||
#else /* !ENABLED (JERRY_ESNEXT) */
|
||||
ecma_object_t *new_array_p = ecma_op_new_array_object (0);
|
||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||
|
||||
if (use_fast_path && copied_length > 0)
|
||||
{
|
||||
@@ -885,7 +881,7 @@ ecma_builtin_array_prototype_object_slice (ecma_value_t arg1, /**< start */
|
||||
* Very unlikely case: the buffer copied from is a fast buffer and the property list was deleted.
|
||||
* There is no need to do any copy.
|
||||
*/
|
||||
return new_array;
|
||||
return ecma_make_object_value (new_array_p);
|
||||
}
|
||||
|
||||
ecma_extended_object_t *ext_to_obj_p = (ecma_extended_object_t *) new_array_p;
|
||||
@@ -927,7 +923,7 @@ ecma_builtin_array_prototype_object_slice (ecma_value_t arg1, /**< start */
|
||||
|
||||
ext_to_obj_p->u.array.u.hole_count &= ECMA_FAST_ARRAY_HOLE_ONE - 1;
|
||||
|
||||
return new_array;
|
||||
return ecma_make_object_value (new_array_p);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -983,7 +979,7 @@ ecma_builtin_array_prototype_object_slice (ecma_value_t arg1, /**< start */
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||
|
||||
return new_array;
|
||||
return ecma_make_object_value (new_array_p);
|
||||
} /* ecma_builtin_array_prototype_object_slice */
|
||||
|
||||
/**
|
||||
@@ -1316,22 +1312,17 @@ ecma_builtin_array_prototype_object_splice (const ecma_value_t args[], /**< argu
|
||||
}
|
||||
|
||||
/* ES11: 9. */
|
||||
ecma_value_t new_array = ecma_op_array_species_create (obj_p, actual_delete_count);
|
||||
ecma_object_t *new_array_p = ecma_op_array_species_create (obj_p, actual_delete_count);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (new_array))
|
||||
if (JERRY_UNLIKELY (new_array_p == NULL))
|
||||
{
|
||||
return new_array;
|
||||
return ECMA_VALUE_ERROR;
|
||||
}
|
||||
#else /* !ENABLED (JERRY_ESNEXT) */
|
||||
/* ES5.1: 2. */
|
||||
ecma_value_t length = ecma_make_length_value (actual_delete_count);
|
||||
ecma_value_t new_array = ecma_op_create_array_object (&length, 1, true);
|
||||
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (new_array));
|
||||
ecma_free_value (length);
|
||||
ecma_object_t *new_array_p = ecma_op_new_array_object (actual_delete_count);
|
||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||
|
||||
ecma_object_t *new_array_p = ecma_get_object_from_value (new_array);
|
||||
|
||||
/* ES5.1: 8, ES11: 10. */
|
||||
ecma_length_t k = 0;
|
||||
|
||||
@@ -1498,7 +1489,7 @@ ecma_builtin_array_prototype_object_splice (const ecma_value_t args[], /**< argu
|
||||
}
|
||||
|
||||
/* ES5.1: 17, ES11: 20. */
|
||||
return new_array;
|
||||
return ecma_make_object_value (new_array_p);
|
||||
} /* ecma_builtin_array_prototype_object_splice */
|
||||
|
||||
/**
|
||||
@@ -1960,21 +1951,16 @@ ecma_builtin_array_prototype_object_map (ecma_value_t arg1, /**< callbackfn */
|
||||
|
||||
/* 6. */
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
ecma_value_t new_array = ecma_op_array_species_create (obj_p, len);
|
||||
ecma_object_t *new_array_p = ecma_op_array_species_create (obj_p, len);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (new_array))
|
||||
if (JERRY_UNLIKELY (new_array_p == NULL))
|
||||
{
|
||||
return new_array;
|
||||
return ECMA_VALUE_ERROR;
|
||||
}
|
||||
#else /* !ENABLED (JERRY_ESNEXT) */
|
||||
ecma_value_t length_value = ecma_make_uint32_value (len);
|
||||
ecma_value_t new_array = ecma_op_create_array_object (&length_value, 1, true);
|
||||
ecma_free_value (length_value);
|
||||
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (new_array));
|
||||
ecma_object_t *new_array_p = ecma_op_new_array_object (len);
|
||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||
|
||||
ecma_object_t *new_array_p = ecma_get_object_from_value (new_array);
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_object (arg1));
|
||||
ecma_object_t *func_object_p = ecma_get_object_from_value (arg1);
|
||||
|
||||
@@ -2059,25 +2045,22 @@ ecma_builtin_array_prototype_object_filter (ecma_value_t arg1, /**< callbackfn *
|
||||
|
||||
/* 6. */
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
ecma_value_t new_array = ecma_op_array_species_create (obj_p, 0);
|
||||
ecma_object_t *new_array_p = ecma_op_array_species_create (obj_p, 0);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (new_array))
|
||||
if (JERRY_UNLIKELY (new_array_p == NULL))
|
||||
{
|
||||
return new_array;
|
||||
return ECMA_VALUE_ERROR;
|
||||
}
|
||||
|
||||
/* ES11: 22.1.3.7. 7.c.iii.1 */
|
||||
const uint32_t prop_flags = ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE | ECMA_IS_THROW;
|
||||
#else /* !ENABLED (JERRY_ESNEXT) */
|
||||
ecma_value_t new_array = ecma_op_create_array_object (NULL, 0, false);
|
||||
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (new_array));
|
||||
ecma_object_t *new_array_p = ecma_op_new_array_object (0);
|
||||
|
||||
/* ES5.1: 15.4.4.20. 9.c.iii.1 */
|
||||
const uint32_t prop_flags = ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE;
|
||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||
|
||||
ecma_object_t *new_array_p = ecma_get_object_from_value (new_array);
|
||||
|
||||
/* We already checked that arg1 is callable, so it will always be an object. */
|
||||
JERRY_ASSERT (ecma_is_value_object (arg1));
|
||||
ecma_object_t *func_object_p = ecma_get_object_from_value (arg1);
|
||||
@@ -2142,7 +2125,7 @@ ecma_builtin_array_prototype_object_filter (ecma_value_t arg1, /**< callbackfn *
|
||||
}
|
||||
}
|
||||
|
||||
return new_array;
|
||||
return ecma_make_object_value (new_array_p);
|
||||
} /* ecma_builtin_array_prototype_object_filter */
|
||||
|
||||
/**
|
||||
@@ -2825,15 +2808,15 @@ ecma_builtin_array_prototype_object_flat (const ecma_value_t args[], /**< argume
|
||||
}
|
||||
|
||||
/* 5. */
|
||||
ecma_value_t new_array = ecma_op_array_species_create (obj_p, 0);
|
||||
ecma_object_t *new_array_p = ecma_op_array_species_create (obj_p, 0);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (new_array))
|
||||
if (JERRY_UNLIKELY (new_array_p == NULL))
|
||||
{
|
||||
return new_array;
|
||||
return ECMA_VALUE_ERROR;
|
||||
}
|
||||
|
||||
/* 6. */
|
||||
ecma_value_t flatten_val = ecma_builtin_array_flatten_into_array (new_array,
|
||||
ecma_value_t flatten_val = ecma_builtin_array_flatten_into_array (ecma_make_object_value (new_array_p),
|
||||
obj_p,
|
||||
len,
|
||||
0,
|
||||
@@ -2843,12 +2826,12 @@ ecma_builtin_array_prototype_object_flat (const ecma_value_t args[], /**< argume
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (flatten_val))
|
||||
{
|
||||
ecma_free_value (new_array);
|
||||
ecma_deref_object (new_array_p);
|
||||
return flatten_val;
|
||||
}
|
||||
|
||||
/* 7. */
|
||||
return new_array;
|
||||
return ecma_make_object_value (new_array_p);
|
||||
} /* ecma_builtin_array_prototype_object_flat */
|
||||
|
||||
/**
|
||||
@@ -2872,15 +2855,15 @@ ecma_builtin_array_prototype_object_flat_map (ecma_value_t callback, /**< callba
|
||||
}
|
||||
|
||||
/* 4. */
|
||||
ecma_value_t new_array = ecma_op_array_species_create (obj_p, 0);
|
||||
ecma_object_t *new_array_p = ecma_op_array_species_create (obj_p, 0);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (new_array))
|
||||
if (JERRY_UNLIKELY (new_array_p == NULL))
|
||||
{
|
||||
return new_array;
|
||||
return ECMA_VALUE_ERROR;
|
||||
}
|
||||
|
||||
/* 5. */
|
||||
ecma_value_t flatten_val = ecma_builtin_array_flatten_into_array (new_array,
|
||||
ecma_value_t flatten_val = ecma_builtin_array_flatten_into_array (ecma_make_object_value (new_array_p),
|
||||
obj_p,
|
||||
len,
|
||||
0,
|
||||
@@ -2889,12 +2872,12 @@ ecma_builtin_array_prototype_object_flat_map (ecma_value_t callback, /**< callba
|
||||
this_arg);
|
||||
if (ECMA_IS_VALUE_ERROR (flatten_val))
|
||||
{
|
||||
ecma_free_value (new_array);
|
||||
ecma_deref_object (new_array_p);
|
||||
return flatten_val;
|
||||
}
|
||||
|
||||
/* 6. */
|
||||
return new_array;
|
||||
return ecma_make_object_value (new_array_p);
|
||||
} /* ecma_builtin_array_prototype_object_flat_map */
|
||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||
|
||||
|
||||
@@ -122,36 +122,36 @@ ecma_builtin_array_object_from (ecma_value_t this_arg, /**< 'this' argument */
|
||||
/* 6. */
|
||||
if (!ecma_is_value_undefined (using_iterator))
|
||||
{
|
||||
ecma_value_t array;
|
||||
ecma_object_t *array_obj_p;
|
||||
|
||||
/* 6.a */
|
||||
if (ecma_is_constructor (constructor))
|
||||
{
|
||||
ecma_object_t *constructor_obj_p = ecma_get_object_from_value (constructor);
|
||||
|
||||
array = ecma_op_function_construct (constructor_obj_p, constructor_obj_p, NULL, 0);
|
||||
ecma_value_t array = ecma_op_function_construct (constructor_obj_p, constructor_obj_p, NULL, 0);
|
||||
|
||||
if (ecma_is_value_undefined (array) || ecma_is_value_null (array))
|
||||
{
|
||||
ecma_free_value (using_iterator);
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Cannot convert undefined or null to object"));
|
||||
}
|
||||
|
||||
/* 6.c */
|
||||
if (ECMA_IS_VALUE_ERROR (array))
|
||||
{
|
||||
ecma_free_value (using_iterator);
|
||||
return array;
|
||||
}
|
||||
|
||||
array_obj_p = ecma_get_object_from_value (array);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 6.b */
|
||||
array = ecma_op_create_array_object (NULL, 0, false);
|
||||
array_obj_p = ecma_op_new_array_object (0);
|
||||
}
|
||||
|
||||
/* 6.c */
|
||||
if (ECMA_IS_VALUE_ERROR (array))
|
||||
{
|
||||
ecma_free_value (using_iterator);
|
||||
return array;
|
||||
}
|
||||
|
||||
ecma_object_t *array_obj_p = ecma_get_object_from_value (array);
|
||||
|
||||
/* 6.d */
|
||||
ecma_value_t next_method;
|
||||
ecma_value_t iterator = ecma_op_get_iterator (items, using_iterator, &next_method);
|
||||
@@ -160,7 +160,7 @@ ecma_builtin_array_object_from (ecma_value_t this_arg, /**< 'this' argument */
|
||||
/* 6.e */
|
||||
if (ECMA_IS_VALUE_ERROR (iterator))
|
||||
{
|
||||
ecma_free_value (array);
|
||||
ecma_deref_object (array_obj_p);
|
||||
return iterator;
|
||||
}
|
||||
|
||||
@@ -199,7 +199,7 @@ ecma_builtin_array_object_from (ecma_value_t this_arg, /**< 'this' argument */
|
||||
ecma_free_value (iterator);
|
||||
ecma_free_value (next_method);
|
||||
/* 6.g.iv.3 */
|
||||
return array;
|
||||
return ecma_make_object_value (array_obj_p);
|
||||
}
|
||||
|
||||
/* 6.g.v */
|
||||
@@ -257,7 +257,7 @@ ecma_builtin_array_object_from (ecma_value_t this_arg, /**< 'this' argument */
|
||||
iterator_cleanup:
|
||||
ecma_free_value (iterator);
|
||||
ecma_free_value (next_method);
|
||||
ecma_free_value (array);
|
||||
ecma_deref_object (array_obj_p);
|
||||
|
||||
return ret_value;
|
||||
}
|
||||
@@ -283,41 +283,43 @@ iterator_cleanup:
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
len_value = ecma_make_length_value (len);
|
||||
|
||||
/* 12. */
|
||||
ecma_value_t array;
|
||||
ecma_object_t *array_obj_p;
|
||||
|
||||
/* 12.a */
|
||||
if (ecma_is_constructor (constructor))
|
||||
{
|
||||
ecma_object_t *constructor_obj_p = ecma_get_object_from_value (constructor);
|
||||
|
||||
array = ecma_op_function_construct (constructor_obj_p, constructor_obj_p, &len_value, 1);
|
||||
len_value = ecma_make_length_value (len);
|
||||
ecma_value_t array = ecma_op_function_construct (constructor_obj_p, constructor_obj_p, &len_value, 1);
|
||||
ecma_free_value (len_value);
|
||||
|
||||
if (ecma_is_value_undefined (array) || ecma_is_value_null (array))
|
||||
{
|
||||
ecma_free_value (len_value);
|
||||
ecma_raise_type_error (ECMA_ERR_MSG ("Cannot convert undefined or null to object"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* 14. */
|
||||
if (ECMA_IS_VALUE_ERROR (array))
|
||||
{
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
array_obj_p = ecma_get_object_from_value (array);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 13.a */
|
||||
array = ecma_op_create_array_object (&len_value, 1, true);
|
||||
array_obj_p = ecma_op_new_array_object_from_length (len);
|
||||
|
||||
if (JERRY_UNLIKELY (array_obj_p == NULL))
|
||||
{
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
ecma_free_value (len_value);
|
||||
|
||||
/* 14. */
|
||||
if (ECMA_IS_VALUE_ERROR (array))
|
||||
{
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ecma_object_t *array_obj_p = ecma_get_object_from_value (array);
|
||||
|
||||
/* 15. */
|
||||
ecma_length_t k = 0;
|
||||
|
||||
@@ -412,7 +414,7 @@ ecma_builtin_array_object_of (ecma_value_t this_arg, /**< 'this' argument */
|
||||
{
|
||||
if (!ecma_is_constructor (this_arg))
|
||||
{
|
||||
return ecma_op_create_array_object (arguments_list_p, arguments_list_len, false);
|
||||
return ecma_op_new_array_object_from_buffer (arguments_list_p, arguments_list_len);
|
||||
}
|
||||
|
||||
ecma_value_t len = ecma_make_uint32_value (arguments_list_len);
|
||||
@@ -481,7 +483,8 @@ ecma_builtin_array_species_get (ecma_value_t this_value) /**< This Value */
|
||||
/**
|
||||
* Handle calling [[Call]] of built-in Array object
|
||||
*
|
||||
* @return ecma value
|
||||
* @return ECMA_VALUE_ERROR - if the array construction fails
|
||||
* constructed array object - otherwise
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_builtin_array_dispatch_call (const ecma_value_t *arguments_list_p, /**< arguments list */
|
||||
@@ -489,13 +492,28 @@ ecma_builtin_array_dispatch_call (const ecma_value_t *arguments_list_p, /**< arg
|
||||
{
|
||||
JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
|
||||
|
||||
return ecma_op_create_array_object (arguments_list_p, arguments_list_len, true);
|
||||
if (arguments_list_len != 1
|
||||
|| !ecma_is_value_number (arguments_list_p[0]))
|
||||
{
|
||||
return ecma_op_new_array_object_from_buffer (arguments_list_p, arguments_list_len);
|
||||
}
|
||||
|
||||
ecma_number_t num = ecma_get_number_from_value (arguments_list_p[0]);
|
||||
uint32_t num_uint32 = ecma_number_to_uint32 (num);
|
||||
|
||||
if (num != ((ecma_number_t) num_uint32))
|
||||
{
|
||||
return ecma_raise_range_error (ECMA_ERR_MSG ("Invalid array length."));
|
||||
}
|
||||
|
||||
return ecma_make_object_value (ecma_op_new_array_object (num_uint32));
|
||||
} /* ecma_builtin_array_dispatch_call */
|
||||
|
||||
/**
|
||||
* Handle calling [[Construct]] of built-in Array object
|
||||
*
|
||||
* @return ecma value
|
||||
* @return ECMA_VALUE_ERROR - if the array construction fails
|
||||
* constructed array object - otherwise
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_builtin_array_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */
|
||||
@@ -504,7 +522,7 @@ ecma_builtin_array_dispatch_construct (const ecma_value_t *arguments_list_p, /**
|
||||
JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
|
||||
|
||||
#if !ENABLED (JERRY_ESNEXT)
|
||||
return ecma_op_create_array_object (arguments_list_p, arguments_list_len, true);
|
||||
return ecma_builtin_array_dispatch_call (arguments_list_p, arguments_list_len);
|
||||
#else /* ENABLED (JERRY_ESNEXT) */
|
||||
ecma_object_t *proto_p = ecma_op_get_prototype_from_constructor (JERRY_CONTEXT (current_new_target),
|
||||
ECMA_BUILTIN_ID_ARRAY_PROTOTYPE);
|
||||
@@ -514,12 +532,12 @@ ecma_builtin_array_dispatch_construct (const ecma_value_t *arguments_list_p, /**
|
||||
return ECMA_VALUE_ERROR;
|
||||
}
|
||||
|
||||
ecma_value_t result = ecma_op_create_array_object (arguments_list_p, arguments_list_len, true);
|
||||
ecma_value_t result = ecma_builtin_array_dispatch_call (arguments_list_p, arguments_list_len);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (result))
|
||||
{
|
||||
ecma_deref_object (proto_p);
|
||||
return ECMA_VALUE_ERROR;
|
||||
return result;
|
||||
}
|
||||
|
||||
ecma_object_t *object_p = ecma_get_object_from_value (result);
|
||||
|
||||
@@ -543,11 +543,7 @@ ecma_builtin_json_parse_value (ecma_json_token_t *token_p) /**< token argument *
|
||||
case TOKEN_LEFT_SQUARE:
|
||||
{
|
||||
uint32_t length = 0;
|
||||
|
||||
ecma_value_t array_construction = ecma_op_create_array_object (NULL, 0, false);
|
||||
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (array_construction));
|
||||
|
||||
ecma_object_t *array_p = ecma_get_object_from_value (array_construction);
|
||||
ecma_object_t *array_p = ecma_op_new_array_object (0);
|
||||
|
||||
ecma_builtin_json_parse_next_token (token_p, true);
|
||||
|
||||
|
||||
@@ -694,12 +694,8 @@ ecma_builtin_object_object_keys_values_helper (ecma_object_t *obj_p, /**< routin
|
||||
return ECMA_VALUE_ERROR;
|
||||
}
|
||||
|
||||
ecma_value_t *names_buffer_p = props_p->buffer_p;
|
||||
/* 3. */
|
||||
ecma_value_t array_value = ecma_op_create_array_object (names_buffer_p, props_p->item_count, false);
|
||||
ecma_collection_free (props_p);
|
||||
|
||||
return array_value;
|
||||
return ecma_op_new_array_object_from_collection (props_p, option != ECMA_ENUMERABLE_PROPERTY_KEYS);
|
||||
} /* ecma_builtin_object_object_keys_values_helper */
|
||||
|
||||
/**
|
||||
@@ -1342,7 +1338,7 @@ ecma_op_object_get_own_property_keys (ecma_value_t this_arg, /**< this argument
|
||||
}
|
||||
|
||||
/* 3. */
|
||||
ecma_collection_t *name_list = ecma_new_collection ();
|
||||
ecma_collection_t *name_list_p = ecma_new_collection ();
|
||||
|
||||
/* 4. */
|
||||
for (uint32_t i = 0; i < props_p->item_count; i++)
|
||||
@@ -1354,23 +1350,22 @@ ecma_op_object_get_own_property_keys (ecma_value_t this_arg, /**< this argument
|
||||
|| (ecma_is_value_string (prop_name) && type == ECMA_OBJECT_ROUTINE_GET_OWN_PROPERTY_NAMES))
|
||||
{
|
||||
ecma_ref_ecma_string (name_p);
|
||||
ecma_collection_push_back (name_list, prop_name);
|
||||
ecma_collection_push_back (name_list_p, prop_name);
|
||||
}
|
||||
}
|
||||
|
||||
ecma_value_t result_array = ecma_op_create_array_object (name_list->buffer_p, name_list->item_count, false);
|
||||
ecma_value_t result_array = ecma_op_new_array_object_from_collection (name_list_p, false);
|
||||
|
||||
ecma_deref_object (obj_p);
|
||||
ecma_collection_free (name_list);
|
||||
ecma_collection_free (props_p);
|
||||
|
||||
return result_array;
|
||||
#else /* !ENABLED (JERRY_ESNEXT) */
|
||||
JERRY_UNUSED (type);
|
||||
ecma_object_t *obj_p = ecma_get_object_from_value (this_arg);
|
||||
ecma_object_t *obj_p = ecma_get_object_from_value (this_arg);
|
||||
ecma_collection_t *props_p = ecma_op_object_own_property_keys (obj_p);
|
||||
ecma_value_t result_array = ecma_op_create_array_object (props_p->buffer_p, props_p->item_count, false);
|
||||
return ecma_op_new_array_object_from_collection (props_p, false);
|
||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||
|
||||
ecma_collection_free (props_p);
|
||||
return result_array;
|
||||
} /* ecma_op_object_get_own_property_keys */
|
||||
|
||||
/**
|
||||
@@ -1491,7 +1486,7 @@ ecma_builtin_object_dispatch_routine (uint16_t builtin_routine_id, /**< built-in
|
||||
|
||||
const int option = builtin_routine_id - ECMA_OBJECT_ROUTINE_KEYS;
|
||||
result = ecma_builtin_object_object_keys_values_helper (obj_p,
|
||||
(ecma_enumerable_property_names_options_t) option);
|
||||
(ecma_enumerable_property_names_options_t) option);
|
||||
break;
|
||||
}
|
||||
case ECMA_OBJECT_ROUTINE_GET_OWN_PROPERTY_DESCRIPTOR:
|
||||
|
||||
@@ -253,7 +253,7 @@ ecma_builtin_promise_perform_all (ecma_value_t iterator, /**< iteratorRecord */
|
||||
ecma_object_t *resolve_func_p = ecma_get_object_from_value (resolve);
|
||||
|
||||
/* 3. */
|
||||
ecma_object_t *values_array_obj_p = ecma_op_new_fast_array_object (0);
|
||||
ecma_object_t *values_array_obj_p = ecma_op_new_array_object (0);
|
||||
ecma_value_t values_array = ecma_make_object_value (values_array_obj_p);
|
||||
/* 4. */
|
||||
ecma_value_t remaining = ecma_op_create_number_object (ecma_make_integer_value (1));
|
||||
|
||||
@@ -176,10 +176,7 @@ ecma_builtin_reflect_dispatch_routine (uint16_t builtin_routine_id, /**< built-i
|
||||
#endif /* ENABLED (JERRY_BUILTIN_PROXY) */
|
||||
|
||||
/* 3. */
|
||||
ecma_value_t new_array = ecma_op_create_array_object (prop_names->buffer_p, prop_names->item_count, false);
|
||||
ecma_collection_free (prop_names);
|
||||
|
||||
return new_array;
|
||||
return ecma_op_new_array_object_from_collection (prop_names, false);
|
||||
}
|
||||
|
||||
if (builtin_routine_id == ECMA_REFLECT_OBJECT_CONSTRUCT)
|
||||
|
||||
@@ -909,7 +909,8 @@ ecma_builtin_string_prototype_object_split (ecma_value_t this_value, /**< this a
|
||||
}
|
||||
|
||||
/* 6. */
|
||||
result = ecma_op_create_array_object (NULL, 0, false);
|
||||
ecma_object_t *array_p = ecma_op_new_array_object (0);
|
||||
result = ecma_make_object_value (array_p);
|
||||
|
||||
/* 14. */
|
||||
if (limit == 0)
|
||||
@@ -917,7 +918,7 @@ ecma_builtin_string_prototype_object_split (ecma_value_t this_value, /**< this a
|
||||
goto cleanup_separator;
|
||||
}
|
||||
|
||||
ecma_object_t *array_p = ecma_get_object_from_value (result);
|
||||
/* 6. */
|
||||
lit_utf8_size_t array_length = 0;
|
||||
|
||||
/* 15. */
|
||||
|
||||
@@ -66,8 +66,8 @@
|
||||
*
|
||||
* @return pointer to the constructed array object
|
||||
*/
|
||||
ecma_object_t *
|
||||
ecma_op_new_array_object (uint32_t length) /**< length of the new array */
|
||||
static ecma_object_t *
|
||||
ecma_op_alloc_array_object (uint32_t length) /**< length of the new array */
|
||||
{
|
||||
#if ENABLED (JERRY_BUILTIN_ARRAY)
|
||||
ecma_object_t *array_prototype_object_p = ecma_builtin_get (ECMA_BUILTIN_ID_ARRAY_PROTOTYPE);
|
||||
@@ -91,7 +91,7 @@ ecma_op_new_array_object (uint32_t length) /**< length of the new array */
|
||||
ext_obj_p->u.array.u.length_prop = ECMA_PROPERTY_FLAG_WRITABLE | ECMA_PROPERTY_TYPE_VIRTUAL;
|
||||
|
||||
return object_p;
|
||||
} /* ecma_op_new_array_object */
|
||||
} /* ecma_op_alloc_array_object */
|
||||
|
||||
/**
|
||||
* Check whether the given object is fast-access mode array
|
||||
@@ -121,43 +121,184 @@ ecma_op_array_is_fast_array (ecma_extended_object_t *array_p) /**< ecma-array-ob
|
||||
} /* ecma_op_array_is_fast_array */
|
||||
|
||||
/**
|
||||
* Allocate a new fast access mode array object with the given length
|
||||
* Allocate a new array object with the given length
|
||||
*
|
||||
* @return NULL - if the allocation of the underlying buffer failed
|
||||
* pointer to the constructed fast access mode array object otherwise
|
||||
* Note: The returned array can be normal of fast access mode
|
||||
*
|
||||
* @return pointer to the constructed array object
|
||||
*/
|
||||
ecma_object_t *
|
||||
ecma_op_new_fast_array_object (uint32_t length) /**< length of the new fast access mode array */
|
||||
ecma_op_new_array_object (uint32_t length) /**< length of the new array */
|
||||
{
|
||||
ecma_object_t *object_p = ecma_op_alloc_array_object (length);
|
||||
|
||||
const uint32_t aligned_length = ECMA_FAST_ARRAY_ALIGN_LENGTH (length);
|
||||
ecma_value_t *values_p = NULL;
|
||||
|
||||
if (length != 0)
|
||||
if (length > 0)
|
||||
{
|
||||
if (length >= ECMA_FAST_ARRAY_MAX_INITIAL_LENGTH)
|
||||
{
|
||||
return object_p;
|
||||
}
|
||||
|
||||
values_p = (ecma_value_t *) jmem_heap_alloc_block_null_on_error (aligned_length * sizeof (ecma_value_t));
|
||||
|
||||
if (JERRY_UNLIKELY (values_p == NULL))
|
||||
{
|
||||
return NULL;
|
||||
return object_p;
|
||||
}
|
||||
}
|
||||
|
||||
ecma_object_t *object_p = ecma_op_new_array_object (length);
|
||||
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) object_p;
|
||||
|
||||
ext_obj_p->u.array.u.length_prop = (uint8_t) (ext_obj_p->u.array.u.length_prop | ECMA_FAST_ARRAY_FLAG);
|
||||
ext_obj_p->u.array.u.hole_count += length * ECMA_FAST_ARRAY_HOLE_ONE;
|
||||
|
||||
JERRY_ASSERT (object_p->u1.property_list_cp == JMEM_CP_NULL);
|
||||
|
||||
for (uint32_t i = 0; i < aligned_length; i++)
|
||||
{
|
||||
values_p[i] = ECMA_VALUE_ARRAY_HOLE;
|
||||
}
|
||||
|
||||
JERRY_ASSERT (object_p->u1.property_list_cp == JMEM_CP_NULL);
|
||||
ECMA_SET_POINTER (object_p->u1.property_list_cp, values_p);
|
||||
return object_p;
|
||||
} /* ecma_op_new_fast_array_object */
|
||||
} /* ecma_op_new_array_object */
|
||||
|
||||
/**
|
||||
* Allocate a new array object from the given length
|
||||
*
|
||||
* Note: The returned array can be normal of fast access mode
|
||||
*
|
||||
* @return NULL - if the given length is invalid
|
||||
* pointer to the constructed array object - otherwise
|
||||
*/
|
||||
ecma_object_t *
|
||||
ecma_op_new_array_object_from_length (ecma_length_t length) /**< length of the new array */
|
||||
{
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
if (length > UINT32_MAX)
|
||||
{
|
||||
ecma_raise_range_error (ECMA_ERR_MSG ("Invalid array length"));
|
||||
return NULL;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||
|
||||
return ecma_op_new_array_object ((uint32_t) length);
|
||||
} /* ecma_op_new_array_object_from_length */
|
||||
|
||||
/**
|
||||
* Allocate a new array object from the given buffer
|
||||
*
|
||||
* Note: The returned array can be normal of fast access mode
|
||||
*
|
||||
* @return ecma_value - constructed array object
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_op_new_array_object_from_buffer (const ecma_value_t *args_p, /**< array element list */
|
||||
uint32_t length) /**< number of array elements */
|
||||
{
|
||||
if (length == 0)
|
||||
{
|
||||
return ecma_make_object_value (ecma_op_new_array_object (0));
|
||||
}
|
||||
|
||||
ecma_object_t *object_p = ecma_op_alloc_array_object (length);
|
||||
const uint32_t aligned_length = ECMA_FAST_ARRAY_ALIGN_LENGTH (length);
|
||||
ecma_value_t *values_p;
|
||||
values_p = (ecma_value_t *) jmem_heap_alloc_block_null_on_error (aligned_length * sizeof (ecma_value_t));
|
||||
|
||||
if (values_p != NULL)
|
||||
{
|
||||
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) object_p;
|
||||
ext_obj_p->u.array.u.length_prop = (uint8_t) (ext_obj_p->u.array.u.length_prop | ECMA_FAST_ARRAY_FLAG);
|
||||
JERRY_ASSERT (object_p->u1.property_list_cp == JMEM_CP_NULL);
|
||||
|
||||
for (uint32_t i = 0; i < length; i++)
|
||||
{
|
||||
JERRY_ASSERT (!ecma_is_value_array_hole (args_p[i]));
|
||||
values_p[i] = ecma_copy_value_if_not_object (args_p[i]);
|
||||
}
|
||||
|
||||
for (uint32_t i = length; i < aligned_length; i++)
|
||||
{
|
||||
values_p[i] = ECMA_VALUE_ARRAY_HOLE;
|
||||
}
|
||||
|
||||
ECMA_SET_POINTER (object_p->u1.property_list_cp, values_p);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (uint32_t i = 0; i < length; i++)
|
||||
{
|
||||
JERRY_ASSERT (!ecma_is_value_array_hole (args_p[i]));
|
||||
|
||||
ecma_string_t *prop_name_p = ecma_new_ecma_string_from_uint32 (i);
|
||||
ecma_property_value_t *prop_value_p;
|
||||
prop_value_p = ecma_create_named_data_property (object_p,
|
||||
prop_name_p,
|
||||
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
|
||||
NULL);
|
||||
ecma_deref_ecma_string (prop_name_p);
|
||||
prop_value_p->value = ecma_copy_value_if_not_object (args_p[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return ecma_make_object_value (object_p);
|
||||
} /* ecma_op_new_array_object_from_buffer */
|
||||
|
||||
/**
|
||||
* Allocate a new fast acces mode array object from the given collection
|
||||
*
|
||||
* Note: The given collection will be unavailable after and it's underlying buffer is reused
|
||||
*
|
||||
* @return ecma_value - constructed fast access mode array object
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_op_new_array_object_from_collection (ecma_collection_t *collection_p, /**< collection to create array from */
|
||||
bool unref_objects) /**< true - if the collection potentially
|
||||
containts objects
|
||||
false - otherwise */
|
||||
{
|
||||
const uint32_t item_count = collection_p->item_count;
|
||||
|
||||
if (item_count == 0)
|
||||
{
|
||||
ecma_collection_destroy (collection_p);
|
||||
return ecma_make_object_value (ecma_op_new_array_object (0));
|
||||
}
|
||||
|
||||
ecma_object_t *object_p;
|
||||
ecma_value_t *buffer_p = collection_p->buffer_p;
|
||||
const uint32_t old_size = ECMA_COLLECTION_ALLOCATED_SIZE (collection_p->capacity);
|
||||
const uint32_t aligned_length = ECMA_FAST_ARRAY_ALIGN_LENGTH (collection_p->item_count);
|
||||
|
||||
jmem_heap_free_block (collection_p, sizeof (ecma_collection_t));
|
||||
buffer_p = jmem_heap_realloc_block (buffer_p, old_size, aligned_length * sizeof (ecma_value_t));
|
||||
object_p = ecma_op_alloc_array_object (item_count);
|
||||
|
||||
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) object_p;
|
||||
ext_obj_p->u.array.u.length_prop = (uint8_t) (ext_obj_p->u.array.u.length_prop | ECMA_FAST_ARRAY_FLAG);
|
||||
JERRY_ASSERT (object_p->u1.property_list_cp == JMEM_CP_NULL);
|
||||
JERRY_ASSERT (ext_obj_p->u.array.u.hole_count < ECMA_FAST_ARRAY_HOLE_ONE);
|
||||
ECMA_SET_POINTER (object_p->u1.property_list_cp, buffer_p);
|
||||
|
||||
if (JERRY_UNLIKELY (unref_objects))
|
||||
{
|
||||
for (uint32_t i = 0; i < item_count; i++)
|
||||
{
|
||||
/* Strong references from the collection are no longer needed
|
||||
since GC will mark these object as a fast access mode array properties */
|
||||
ecma_deref_if_object (buffer_p[i]);
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t i = item_count; i < aligned_length; i++)
|
||||
{
|
||||
buffer_p[i] = ECMA_VALUE_ARRAY_HOLE;
|
||||
}
|
||||
|
||||
return ecma_make_object_value (object_p);
|
||||
} /* ecma_op_new_array_object_from_collection */
|
||||
|
||||
/**
|
||||
* Converts a fast access mode array back to a normal property list based array
|
||||
@@ -541,105 +682,6 @@ ecma_fast_array_object_own_property_keys (ecma_object_t *object_p) /**< fast acc
|
||||
return ret_p;
|
||||
} /* ecma_fast_array_object_own_property_keys */
|
||||
|
||||
/**
|
||||
* Array object creation operation.
|
||||
*
|
||||
* See also: ECMA-262 v5, 15.4.2.1
|
||||
* ECMA-262 v5, 15.4.2.2
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_op_create_array_object (const ecma_value_t *arguments_list_p, /**< list of arguments that
|
||||
* are passed to Array constructor */
|
||||
uint32_t arguments_list_len, /**< length of the arguments' list */
|
||||
bool is_treat_single_arg_as_length) /**< if the value is true,
|
||||
* arguments_list_len is 1
|
||||
* and single argument is Number,
|
||||
* then treat the single argument
|
||||
* as new Array's length rather
|
||||
* than as single item of the Array */
|
||||
{
|
||||
JERRY_ASSERT (arguments_list_len == 0
|
||||
|| arguments_list_p != NULL);
|
||||
|
||||
uint32_t length;
|
||||
const ecma_value_t *array_items_p;
|
||||
uint32_t array_items_count;
|
||||
|
||||
if (is_treat_single_arg_as_length
|
||||
&& arguments_list_len == 1
|
||||
&& ecma_is_value_number (arguments_list_p[0]))
|
||||
{
|
||||
ecma_number_t num = ecma_get_number_from_value (arguments_list_p[0]);
|
||||
uint32_t num_uint32 = ecma_number_to_uint32 (num);
|
||||
|
||||
if (num != ((ecma_number_t) num_uint32))
|
||||
{
|
||||
return ecma_raise_range_error (ECMA_ERR_MSG ("Invalid array length."));
|
||||
}
|
||||
else
|
||||
{
|
||||
length = num_uint32;
|
||||
array_items_p = NULL;
|
||||
array_items_count = 0;
|
||||
}
|
||||
|
||||
if (length > ECMA_FAST_ARRAY_MAX_INITIAL_LENGTH)
|
||||
{
|
||||
return ecma_make_object_value (ecma_op_new_array_object (length));
|
||||
}
|
||||
|
||||
ecma_object_t *object_p = ecma_op_new_fast_array_object (length);
|
||||
|
||||
if (object_p == NULL)
|
||||
{
|
||||
return ecma_make_object_value (ecma_op_new_array_object (length));
|
||||
}
|
||||
|
||||
JERRY_ASSERT (ecma_op_object_is_fast_array (object_p));
|
||||
|
||||
return ecma_make_object_value (object_p);
|
||||
}
|
||||
else
|
||||
{
|
||||
length = arguments_list_len;
|
||||
array_items_p = arguments_list_p;
|
||||
array_items_count = arguments_list_len;
|
||||
}
|
||||
|
||||
ecma_object_t *object_p = ecma_op_new_fast_array_object (length);
|
||||
|
||||
/* At this point we were not able to allocate a length * sizeof (ecma_value_t) amount of memory,
|
||||
so we can terminate the engine since converting it into normal property list based array
|
||||
would consume more memory. */
|
||||
if (object_p == NULL)
|
||||
{
|
||||
jerry_fatal (ERR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
if (length == 0)
|
||||
{
|
||||
return ecma_make_object_value (object_p);
|
||||
}
|
||||
|
||||
ecma_value_t *values_p = ECMA_GET_NON_NULL_POINTER (ecma_value_t, object_p->u1.property_list_cp);
|
||||
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) object_p;
|
||||
|
||||
for (uint32_t index = 0;
|
||||
index < array_items_count;
|
||||
index++)
|
||||
{
|
||||
JERRY_ASSERT (!ecma_is_value_array_hole (array_items_p[index]));
|
||||
values_p[index] = ecma_copy_value_if_not_object (array_items_p[index]);
|
||||
}
|
||||
|
||||
ext_obj_p->u.array.u.hole_count -= ECMA_FAST_ARRAY_HOLE_ONE * array_items_count;
|
||||
|
||||
return ecma_make_object_value (object_p);
|
||||
} /* ecma_op_create_array_object */
|
||||
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
/**
|
||||
* Array object creation with custom prototype.
|
||||
@@ -649,7 +691,7 @@ ecma_op_create_array_object (const ecma_value_t *arguments_list_p, /**< list of
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_object_t *
|
||||
ecma_op_array_species_create (ecma_object_t *original_array_p, /**< The object from whom the new array object
|
||||
* is being created */
|
||||
ecma_length_t length) /**< length of the array */
|
||||
@@ -661,7 +703,7 @@ ecma_op_array_species_create (ecma_object_t *original_array_p, /**< The object f
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (is_array))
|
||||
{
|
||||
return is_array;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ecma_is_value_true (is_array))
|
||||
@@ -669,7 +711,7 @@ ecma_op_array_species_create (ecma_object_t *original_array_p, /**< The object f
|
||||
constructor = ecma_op_object_get_by_magic_id (original_array_p, LIT_MAGIC_STRING_CONSTRUCTOR);
|
||||
if (ECMA_IS_VALUE_ERROR (constructor))
|
||||
{
|
||||
return constructor;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ecma_is_constructor (constructor)
|
||||
@@ -686,7 +728,7 @@ ecma_op_array_species_create (ecma_object_t *original_array_p, /**< The object f
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (constructor))
|
||||
{
|
||||
return constructor;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ecma_is_value_null (constructor))
|
||||
@@ -698,17 +740,14 @@ ecma_op_array_species_create (ecma_object_t *original_array_p, /**< The object f
|
||||
|
||||
if (ecma_is_value_undefined (constructor))
|
||||
{
|
||||
ecma_value_t length_val = ecma_make_length_value (length);
|
||||
ecma_value_t new_array = ecma_op_create_array_object (&length_val, 1, true);
|
||||
ecma_free_value (length_val);
|
||||
|
||||
return new_array;
|
||||
return ecma_op_new_array_object_from_length (length);
|
||||
}
|
||||
|
||||
if (!ecma_is_constructor (constructor))
|
||||
{
|
||||
ecma_free_value (constructor);
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Invalid species constructor"));
|
||||
ecma_raise_type_error (ECMA_ERR_MSG ("Invalid species constructor"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ecma_value_t len_val = ecma_make_length_value (length);
|
||||
@@ -720,7 +759,13 @@ ecma_op_array_species_create (ecma_object_t *original_array_p, /**< The object f
|
||||
|
||||
ecma_deref_object (ctor_object_p);
|
||||
ecma_free_value (len_val);
|
||||
return ret_val;
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (ret_val))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ecma_get_object_from_value (ret_val);
|
||||
} /* ecma_op_array_species_create */
|
||||
|
||||
/**
|
||||
|
||||
@@ -65,7 +65,13 @@ ecma_object_t *
|
||||
ecma_op_new_array_object (uint32_t length);
|
||||
|
||||
ecma_object_t *
|
||||
ecma_op_new_fast_array_object (uint32_t length);
|
||||
ecma_op_new_array_object_from_length (ecma_length_t length);
|
||||
|
||||
ecma_value_t
|
||||
ecma_op_new_array_object_from_buffer (const ecma_value_t *args_p, uint32_t length);
|
||||
|
||||
ecma_value_t
|
||||
ecma_op_new_array_object_from_collection (ecma_collection_t *collection_p, bool unref_objects);
|
||||
|
||||
bool
|
||||
ecma_op_object_is_fast_array (ecma_object_t *object_p);
|
||||
@@ -95,12 +101,8 @@ ecma_fast_array_object_own_property_keys (ecma_object_t *object_p);
|
||||
void
|
||||
ecma_fast_array_convert_to_normal (ecma_object_t *object_p);
|
||||
|
||||
ecma_value_t
|
||||
ecma_op_create_array_object (const ecma_value_t *arguments_list_p, uint32_t arguments_list_len,
|
||||
bool is_treat_single_arg_as_length);
|
||||
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
ecma_value_t
|
||||
ecma_object_t *
|
||||
ecma_op_array_species_create (ecma_object_t *original_array_p,
|
||||
ecma_length_t length);
|
||||
|
||||
|
||||
@@ -53,29 +53,26 @@ ecma_create_array_from_iter_element (ecma_value_t value, /**< value */
|
||||
ecma_value_t index_value) /**< iterator index */
|
||||
{
|
||||
/* 2. */
|
||||
ecma_value_t new_array = ecma_op_create_array_object (NULL, 0, false);
|
||||
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (new_array));
|
||||
ecma_object_t *new_array_p = ecma_get_object_from_value (new_array);
|
||||
ecma_object_t *new_array_p = ecma_op_new_array_object (0);
|
||||
|
||||
/* 3 - 4. */
|
||||
for (uint32_t index = 0; index < 2; index++)
|
||||
{
|
||||
ecma_string_t *index_string_p = ecma_new_ecma_string_from_uint32 (index);
|
||||
/* 3-4. */
|
||||
ecma_value_t completion;
|
||||
completion = ecma_builtin_helper_def_prop_by_index (new_array_p,
|
||||
0,
|
||||
index_value,
|
||||
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
|
||||
|
||||
/* 4.a */
|
||||
ecma_value_t completion = ecma_builtin_helper_def_prop (new_array_p,
|
||||
index_string_p,
|
||||
(index == 0) ? index_value : value,
|
||||
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
|
||||
/* 4.b */
|
||||
JERRY_ASSERT (ecma_is_value_true (completion));
|
||||
|
||||
/* 4.b */
|
||||
JERRY_ASSERT (ecma_is_value_true (completion));
|
||||
|
||||
ecma_deref_ecma_string (index_string_p);
|
||||
}
|
||||
completion = ecma_builtin_helper_def_prop_by_index (new_array_p,
|
||||
1,
|
||||
value,
|
||||
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
|
||||
JERRY_ASSERT (ecma_is_value_true (completion));
|
||||
|
||||
/* 5. */
|
||||
return new_array;
|
||||
return ecma_make_object_value (new_array_p);
|
||||
} /* ecma_create_array_from_iter_element */
|
||||
|
||||
/**
|
||||
|
||||
@@ -2052,9 +2052,16 @@ ecma_op_object_get_enumerable_property_names (ecma_object_t *obj_p, /**< routine
|
||||
JERRY_ASSERT (option == ECMA_ENUMERABLE_PROPERTY_ENTRIES);
|
||||
|
||||
/* 4.a.ii.2.c.ii */
|
||||
ecma_object_t *entry_p = ecma_op_new_fast_array_object (2);
|
||||
ecma_fast_array_set_property (entry_p, 0, names_buffer_p[i]);
|
||||
ecma_fast_array_set_property (entry_p, 1, value);
|
||||
ecma_object_t *entry_p = ecma_op_new_array_object (2);
|
||||
|
||||
ecma_builtin_helper_def_prop_by_index (entry_p,
|
||||
0,
|
||||
names_buffer_p[i],
|
||||
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
|
||||
ecma_builtin_helper_def_prop_by_index (entry_p,
|
||||
1,
|
||||
value,
|
||||
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
|
||||
ecma_free_value (value);
|
||||
|
||||
/* 4.a.ii.2.c.iii */
|
||||
|
||||
@@ -1720,13 +1720,13 @@ ecma_proxy_object_call (ecma_object_t *obj_p, /**< proxy object */
|
||||
}
|
||||
|
||||
/* 8. */
|
||||
ecma_value_t args_array = ecma_op_create_array_object (args_p, argc, false);
|
||||
ecma_value_t args_array = ecma_op_new_array_object_from_buffer (args_p, argc);
|
||||
ecma_value_t value_array[] = {target, this_argument, args_array};
|
||||
ecma_object_t *func_obj_p = ecma_get_object_from_value (trap);
|
||||
/* 9. */
|
||||
ecma_value_t ret_value = ecma_op_function_call (func_obj_p, handler, value_array, 3);
|
||||
ecma_deref_object (func_obj_p);
|
||||
ecma_deref_object (ecma_get_object_from_value (args_array));
|
||||
ecma_free_object (args_array);
|
||||
|
||||
return ret_value;
|
||||
} /* ecma_proxy_object_call */
|
||||
@@ -1776,16 +1776,16 @@ ecma_proxy_object_construct (ecma_object_t *obj_p, /**< proxy object */
|
||||
}
|
||||
|
||||
/* 8. */
|
||||
ecma_value_t arg_array = ecma_op_create_array_object (args_p, argc, false);
|
||||
ecma_value_t args_array = ecma_op_new_array_object_from_buffer (args_p, argc);
|
||||
|
||||
ecma_object_t *func_obj_p = ecma_get_object_from_value (trap);
|
||||
ecma_value_t new_target_value = ecma_make_object_value (new_target_p);
|
||||
ecma_value_t function_call_args[] = {target, arg_array, new_target_value};
|
||||
ecma_value_t function_call_args[] = {target, args_array, new_target_value};
|
||||
|
||||
/* 9. */
|
||||
ecma_value_t new_obj = ecma_op_function_call (func_obj_p, handler, function_call_args, 3);
|
||||
|
||||
ecma_free_value (arg_array);
|
||||
ecma_free_object (args_array);
|
||||
ecma_deref_object (func_obj_p);
|
||||
|
||||
/* 10 .*/
|
||||
|
||||
@@ -1641,8 +1641,7 @@ ecma_regexp_create_result_object (ecma_regexp_ctx_t *re_ctx_p, /**< regexp conte
|
||||
ecma_string_t *input_string_p, /**< input ecma string */
|
||||
uint32_t index) /**< match index */
|
||||
{
|
||||
ecma_value_t result_array = ecma_op_create_array_object (0, 0, false);
|
||||
ecma_object_t *result_p = ecma_get_object_from_value (result_array);
|
||||
ecma_object_t *result_p = ecma_op_new_array_object (0);
|
||||
|
||||
for (uint32_t i = 0; i < re_ctx_p->captures_count; i++)
|
||||
{
|
||||
@@ -1664,7 +1663,7 @@ ecma_regexp_create_result_object (ecma_regexp_ctx_t *re_ctx_p, /**< regexp conte
|
||||
ecma_make_string_value (input_string_p),
|
||||
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
|
||||
|
||||
return result_array;
|
||||
return ecma_make_object_value (result_p);
|
||||
} /* ecma_regexp_create_result_object */
|
||||
|
||||
/**
|
||||
@@ -2214,7 +2213,8 @@ ecma_regexp_split_helper (ecma_value_t this_arg, /**< this value */
|
||||
}
|
||||
|
||||
/* 15. */
|
||||
ecma_value_t array = ecma_op_create_array_object (NULL, 0, false);
|
||||
ecma_object_t *const array_p = ecma_op_new_array_object (0);
|
||||
ecma_value_t array = ecma_make_object_value (array_p);
|
||||
|
||||
/* 21. */
|
||||
if (limit == 0)
|
||||
@@ -2225,7 +2225,6 @@ ecma_regexp_split_helper (ecma_value_t this_arg, /**< this value */
|
||||
|
||||
const lit_utf8_size_t string_length = ecma_string_get_length (string_p);
|
||||
|
||||
ecma_object_t *const array_p = ecma_get_object_from_value (array);
|
||||
uint32_t array_length = 0;
|
||||
|
||||
/* 22. */
|
||||
@@ -2440,7 +2439,8 @@ cleanup_string:
|
||||
}
|
||||
|
||||
/* 15. */
|
||||
ecma_value_t array = ecma_op_create_array_object (NULL, 0, false);
|
||||
ecma_object_t *const array_p = ecma_op_new_array_object (0);
|
||||
ecma_value_t array = ecma_make_object_value (array_p);
|
||||
|
||||
/* 21. */
|
||||
if (limit == 0)
|
||||
@@ -2449,7 +2449,6 @@ cleanup_string:
|
||||
goto cleanup_string;
|
||||
}
|
||||
|
||||
ecma_object_t *const array_p = ecma_get_object_from_value (array);
|
||||
uint32_t array_length = 0;
|
||||
|
||||
ecma_object_t *const regexp_p = ecma_get_object_from_value (this_arg);
|
||||
@@ -3425,8 +3424,7 @@ ecma_regexp_match_helper (ecma_value_t this_arg, /**< this argument */
|
||||
}
|
||||
|
||||
ecma_value_t ret_value = ECMA_VALUE_ERROR;
|
||||
ecma_value_t result_array = ecma_op_create_array_object (0, 0, false);
|
||||
ecma_object_t *result_array_p = ecma_get_object_from_value (result_array);
|
||||
ecma_object_t *result_array_p = ecma_op_new_array_object (0);
|
||||
uint32_t n = 0;
|
||||
|
||||
while (true)
|
||||
@@ -3447,7 +3445,7 @@ ecma_regexp_match_helper (ecma_value_t this_arg, /**< this argument */
|
||||
}
|
||||
|
||||
ecma_deref_ecma_string (str_p);
|
||||
return result_array;
|
||||
return ecma_make_object_value (result_array_p);
|
||||
}
|
||||
|
||||
ecma_object_t *result_value_p = ecma_get_object_from_value (result_value);
|
||||
|
||||
@@ -62,15 +62,13 @@ ecma_value_t
|
||||
vm_get_backtrace (uint32_t max_depth) /**< maximum backtrace depth, 0 = unlimited */
|
||||
{
|
||||
#if ENABLED (JERRY_LINE_INFO)
|
||||
ecma_value_t result_array = ecma_op_create_array_object (NULL, 0, false);
|
||||
|
||||
if (max_depth == 0)
|
||||
{
|
||||
max_depth = UINT32_MAX;
|
||||
}
|
||||
|
||||
vm_frame_ctx_t *context_p = JERRY_CONTEXT (vm_top_context_p);
|
||||
ecma_object_t *array_p = ecma_get_object_from_value (result_array);
|
||||
ecma_object_t *array_p = ecma_op_new_array_object (0);
|
||||
JERRY_ASSERT (ecma_op_object_is_fast_array (array_p));
|
||||
uint32_t index = 0;
|
||||
|
||||
@@ -107,10 +105,10 @@ vm_get_backtrace (uint32_t max_depth) /**< maximum backtrace depth, 0 = unlimite
|
||||
}
|
||||
}
|
||||
|
||||
return result_array;
|
||||
return ecma_make_object_value (array_p);
|
||||
#else /* !ENABLED (JERRY_LINE_INFO) */
|
||||
JERRY_UNUSED (max_depth);
|
||||
|
||||
return ecma_op_create_array_object (NULL, 0, false);
|
||||
return ecma_make_object_value (ecma_op_new_array_object (0));
|
||||
#endif /* ENABLED (JERRY_LINE_INFO) */
|
||||
} /* vm_get_backtrace */
|
||||
|
||||
+6
-6
@@ -2024,8 +2024,8 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
}
|
||||
case VM_OC_PUSH_ARRAY:
|
||||
{
|
||||
// Note: this operation cannot throw an exception
|
||||
*stack_top_p++ = ecma_make_object_value (ecma_op_new_fast_array_object (0));
|
||||
/* Note: this operation cannot throw an exception */
|
||||
*stack_top_p++ = ecma_make_object_value (ecma_op_new_array_object (0));
|
||||
continue;
|
||||
}
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
@@ -2329,9 +2329,8 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
arg_list_len = argument_end;
|
||||
}
|
||||
|
||||
result = ecma_op_create_array_object (arg_list_p + argument_end,
|
||||
arg_list_len - argument_end,
|
||||
false);
|
||||
result = ecma_op_new_array_object_from_buffer (arg_list_p + argument_end,
|
||||
arg_list_len - argument_end);
|
||||
|
||||
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (result));
|
||||
*stack_top_p++ = result;
|
||||
@@ -2401,7 +2400,8 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
}
|
||||
case VM_OC_REST_INITIALIZER:
|
||||
{
|
||||
ecma_object_t *array_p = ecma_op_new_fast_array_object (0);
|
||||
ecma_object_t *array_p = ecma_op_new_array_object (0);
|
||||
JERRY_ASSERT (ecma_op_object_is_fast_array (array_p));
|
||||
ecma_value_t iterator = stack_top_p[-1];
|
||||
uint32_t index = 0;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user