diff --git a/jerry-core/api/jerry.c b/jerry-core/api/jerry.c index c4a4bde9a..6ae534df0 100644 --- a/jerry-core/api/jerry.c +++ b/jerry-core/api/jerry.c @@ -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 */ /** diff --git a/jerry-core/ecma/base/ecma-helpers-value.c b/jerry-core/ecma/base/ecma-helpers-value.c index 1eedc2975..baeabf912 100644 --- a/jerry-core/ecma/base/ecma-helpers-value.c +++ b/jerry-core/ecma/base/ecma-helpers-value.c @@ -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 */ diff --git a/jerry-core/ecma/base/ecma-helpers.h b/jerry-core/ecma/base/ecma-helpers.h index 24e37874e..e5cde489a 100644 --- a/jerry-core/ecma/base/ecma-helpers.h +++ b/jerry-core/ecma/base/ecma-helpers.h @@ -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); 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 773e29c80..98f1ff0ee 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c @@ -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) */ diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-array.c b/jerry-core/ecma/builtin-objects/ecma-builtin-array.c index d743f5bf5..82d79274d 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-array.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-array.c @@ -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); diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-json.c b/jerry-core/ecma/builtin-objects/ecma-builtin-json.c index c55732f20..05f0317cf 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-json.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-json.c @@ -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); diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-object.c b/jerry-core/ecma/builtin-objects/ecma-builtin-object.c index 7e2d60451..5198a89ea 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-object.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-object.c @@ -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: diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-promise.c b/jerry-core/ecma/builtin-objects/ecma-builtin-promise.c index 92c6d2027..b0b274611 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-promise.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-promise.c @@ -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)); diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-reflect.c b/jerry-core/ecma/builtin-objects/ecma-builtin-reflect.c index 88ea0e6c2..1cdcf4f19 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-reflect.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-reflect.c @@ -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) diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.c index 94030d05d..78d080f8a 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.c @@ -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. */ diff --git a/jerry-core/ecma/operations/ecma-array-object.c b/jerry-core/ecma/operations/ecma-array-object.c index ff96c2faa..45d9acdbd 100644 --- a/jerry-core/ecma/operations/ecma-array-object.c +++ b/jerry-core/ecma/operations/ecma-array-object.c @@ -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 */ /** diff --git a/jerry-core/ecma/operations/ecma-array-object.h b/jerry-core/ecma/operations/ecma-array-object.h index a3c52b694..ddf905b1e 100644 --- a/jerry-core/ecma/operations/ecma-array-object.h +++ b/jerry-core/ecma/operations/ecma-array-object.h @@ -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); diff --git a/jerry-core/ecma/operations/ecma-iterator-object.c b/jerry-core/ecma/operations/ecma-iterator-object.c index 412cd7ca9..398b78913 100644 --- a/jerry-core/ecma/operations/ecma-iterator-object.c +++ b/jerry-core/ecma/operations/ecma-iterator-object.c @@ -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 */ /** diff --git a/jerry-core/ecma/operations/ecma-objects.c b/jerry-core/ecma/operations/ecma-objects.c index 69d97abda..d44d69087 100644 --- a/jerry-core/ecma/operations/ecma-objects.c +++ b/jerry-core/ecma/operations/ecma-objects.c @@ -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 */ diff --git a/jerry-core/ecma/operations/ecma-proxy-object.c b/jerry-core/ecma/operations/ecma-proxy-object.c index 1272d3969..f9ee4083e 100644 --- a/jerry-core/ecma/operations/ecma-proxy-object.c +++ b/jerry-core/ecma/operations/ecma-proxy-object.c @@ -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 .*/ diff --git a/jerry-core/ecma/operations/ecma-regexp-object.c b/jerry-core/ecma/operations/ecma-regexp-object.c index 9d8459366..637a72871 100644 --- a/jerry-core/ecma/operations/ecma-regexp-object.c +++ b/jerry-core/ecma/operations/ecma-regexp-object.c @@ -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); diff --git a/jerry-core/vm/vm-utils.c b/jerry-core/vm/vm-utils.c index c93aecfab..31a407910 100644 --- a/jerry-core/vm/vm-utils.c +++ b/jerry-core/vm/vm-utils.c @@ -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 */ diff --git a/jerry-core/vm/vm.c b/jerry-core/vm/vm.c index 859722a06..02d36729e 100644 --- a/jerry-core/vm/vm.c +++ b/jerry-core/vm/vm.c @@ -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;