diff --git a/jerry-core/ecma/base/ecma-helpers-values-collection.cpp b/jerry-core/ecma/base/ecma-helpers-values-collection.cpp index c1a56a851..58573e448 100644 --- a/jerry-core/ecma/base/ecma-helpers-values-collection.cpp +++ b/jerry-core/ecma/base/ecma-helpers-values-collection.cpp @@ -284,7 +284,7 @@ ecma_collection_iterator_init (ecma_collection_iterator_t *iterator_p, /**< cont ecma_collection_header_t *collection_p) /**< header of collection */ { iterator_p->header_p = collection_p; - iterator_p->next_chunk_cp = collection_p->first_chunk_cp; + iterator_p->next_chunk_cp = (collection_p != NULL ? collection_p->first_chunk_cp : MEM_CP_NULL); iterator_p->current_index = 0; iterator_p->current_value_p = NULL; iterator_p->current_chunk_end_p = NULL; @@ -299,7 +299,8 @@ ecma_collection_iterator_init (ecma_collection_iterator_t *iterator_p, /**< cont bool ecma_collection_iterator_next (ecma_collection_iterator_t *iterator_p) /**< context of iterator */ { - if (unlikely (iterator_p->header_p->unit_number == 0)) + if (iterator_p->header_p == NULL + || unlikely (iterator_p->header_p->unit_number == 0)) { return false; } diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.cpp b/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.cpp index 74bf38db9..381eb0d40 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.cpp +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.cpp @@ -113,7 +113,7 @@ ecma_builtin_array_prototype_object_to_string (ecma_value_t this_arg) /**< this /* 4. */ ecma_object_t *join_func_obj_p = ecma_get_object_from_value (join_value); - return_value = ecma_op_function_call (join_func_obj_p, this_arg, NULL, 0); + return_value = ecma_op_function_call (join_func_obj_p, this_arg, NULL); } ECMA_FINALIZE (join_value); @@ -1013,10 +1013,10 @@ ecma_builtin_array_prototype_object_sort_compare_helper (ecma_value_t j, /**< le ecma_value_t compare_args[] = {j, k}; ECMA_TRY_CATCH (call_value, - ecma_op_function_call (comparefn_obj_p, - ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED), - compare_args, - 2), + ecma_op_function_call_array_args (comparefn_obj_p, + ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED), + compare_args, + 2), ret_value); if (!ecma_is_value_number (call_value)) @@ -2069,7 +2069,7 @@ ecma_builtin_array_prototype_object_every (ecma_value_t this_arg, /**< this argu ecma_value_t call_args[] = { get_value, current_index, obj_this }; /* 7.c.ii */ - ECMA_TRY_CATCH (call_value, ecma_op_function_call (func_object_p, arg2, call_args, 3), ret_value); + ECMA_TRY_CATCH (call_value, ecma_op_function_call_array_args (func_object_p, arg2, call_args, 3), ret_value); /* 7.c.iii, ecma_op_to_boolean always returns a simple value, so no need to free. */ if (ecma_is_completion_value_normal_false (ecma_op_to_boolean (call_value))) @@ -2170,7 +2170,7 @@ ecma_builtin_array_prototype_object_some (ecma_value_t this_arg, /**< this argum ecma_value_t call_args[] = { get_value, current_index, obj_this }; /* 7.c.ii */ - ECMA_TRY_CATCH (call_value, ecma_op_function_call (func_object_p, arg2, call_args, 3), ret_value); + ECMA_TRY_CATCH (call_value, ecma_op_function_call_array_args (func_object_p, arg2, call_args, 3), ret_value); /* 7.c.iii, ecma_op_to_boolean always returns a simple value, so no need to free. */ if (ecma_is_completion_value_normal_true (ecma_op_to_boolean (call_value))) @@ -2270,7 +2270,7 @@ ecma_builtin_array_prototype_object_for_each (ecma_value_t this_arg, /**< this a /* 7.c.ii */ ecma_value_t call_args[] = {current_value, current_index, obj_this}; - ECMA_TRY_CATCH (call_value, ecma_op_function_call (func_object_p, arg2, call_args, 3), ret_value); + ECMA_TRY_CATCH (call_value, ecma_op_function_call_array_args (func_object_p, arg2, call_args, 3), ret_value); ECMA_FINALIZE (call_value); ECMA_FINALIZE (current_value); @@ -2367,7 +2367,7 @@ ecma_builtin_array_prototype_object_map (ecma_value_t this_arg, /**< this argume current_index = ecma_make_number_value (num_p); ecma_value_t call_args[] = {current_value, current_index, obj_this}; - ECMA_TRY_CATCH (mapped_value, ecma_op_function_call (func_object_p, arg2, call_args, 3), ret_value); + ECMA_TRY_CATCH (mapped_value, ecma_op_function_call_array_args (func_object_p, arg2, call_args, 3), ret_value); /* 8.c.iii */ /* This will always be a simple value since 'is_throw' is false, so no need to free. */ @@ -2485,7 +2485,7 @@ ecma_builtin_array_prototype_object_filter (ecma_value_t this_arg, /**< this arg ecma_value_t call_args[] = { get_value, current_index, obj_this }; /* 9.c.ii */ - ECMA_TRY_CATCH (call_value, ecma_op_function_call (func_object_p, arg2, call_args, 3), ret_value); + ECMA_TRY_CATCH (call_value, ecma_op_function_call_array_args (func_object_p, arg2, call_args, 3), ret_value); /* 9.c.iii, ecma_op_to_boolean always returns a simple value, so no need to free. */ if (ecma_is_completion_value_normal_true (ecma_op_to_boolean (call_value))) @@ -2643,10 +2643,10 @@ ecma_builtin_array_prototype_object_reduce (ecma_value_t this_arg, /**< this arg ecma_value_t call_args[] = {accumulator, current_value, current_index, obj_this}; ECMA_TRY_CATCH (call_value, - ecma_op_function_call (func_object_p, - ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED), - call_args, - 4), + ecma_op_function_call_array_args (func_object_p, + ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED), + call_args, + 4), ret_value); ecma_free_value (accumulator, true); @@ -2787,10 +2787,10 @@ ecma_builtin_array_prototype_object_reduce_right (ecma_value_t this_arg, /**< th ecma_value_t call_args[] = {accumulator, current_value, current_index, obj_this}; ECMA_TRY_CATCH (call_value, - ecma_op_function_call (func_object_p, - ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED), - call_args, - 4), + ecma_op_function_call_array_args (func_object_p, + ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED), + call_args, + 4), ret_value); ecma_free_value (accumulator, true); diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-date-prototype.cpp b/jerry-core/ecma/builtin-objects/ecma-builtin-date-prototype.cpp index ef21d1ee1..48080f0c1 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-date-prototype.cpp +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-date-prototype.cpp @@ -1233,7 +1233,7 @@ ecma_builtin_date_prototype_to_json (ecma_value_t this_arg, /**< this argument * else { ecma_object_t *to_iso_obj_p = ecma_get_object_from_value (to_iso); - ret_value = ecma_op_function_call (to_iso_obj_p, this_arg, NULL, 0); + ret_value = ecma_op_function_call (to_iso_obj_p, this_arg, NULL); } ECMA_FINALIZE (to_iso); diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-function-prototype.cpp b/jerry-core/ecma/builtin-objects/ecma-builtin-function-prototype.cpp index 428a67fac..5791a2122 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-function-prototype.cpp +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-function-prototype.cpp @@ -97,10 +97,7 @@ ecma_builtin_function_prototype_object_apply (ecma_value_t this_arg, /**< this a /* 2. */ if (ecma_is_value_null (arg2) || ecma_is_value_undefined (arg2)) { - ret_value = ecma_op_function_call (func_obj_p, - arg1, - NULL, - 0); + ret_value = ecma_op_function_call (func_obj_p, arg1, NULL); } else { @@ -127,10 +124,9 @@ ecma_builtin_function_prototype_object_apply (ecma_value_t this_arg, /**< this a const uint32_t length = ecma_number_to_uint32 (length_number); /* 6. */ - MEM_DEFINE_LOCAL_ARRAY (arg_list, length, ecma_value_t); + ecma_collection_header_t *arg_collection_p = ecma_new_values_collection (NULL, 0, true); /* 7. */ - uint32_t appended_num = 0; for (uint32_t index = 0; index < length && ecma_is_completion_value_empty (ret_value); index++) { ecma_string_t *curr_idx_str_p = ecma_new_ecma_string_from_uint32 (index); @@ -139,29 +135,22 @@ ecma_builtin_function_prototype_object_apply (ecma_value_t this_arg, /**< this a ecma_op_object_get (obj_p, curr_idx_str_p), ret_value); - arg_list[index] = ecma_copy_value (get_value, true); - appended_num++; + ecma_append_to_values_collection (arg_collection_p, get_value, true); ECMA_FINALIZE (get_value); ecma_deref_ecma_string (curr_idx_str_p); } - JERRY_ASSERT (appended_num == length || !ecma_is_completion_value_empty (ret_value)); + JERRY_ASSERT (arg_collection_p->unit_number == length || !ecma_is_completion_value_empty (ret_value)); if (ecma_is_completion_value_empty (ret_value)) { ret_value = ecma_op_function_call (func_obj_p, arg1, - arg_list, - (ecma_length_t) appended_num); + arg_collection_p); } - for (uint32_t index = 0; index < appended_num; index++) - { - ecma_free_value (arg_list[index], true); - } - - MEM_FINALIZE_LOCAL_ARRAY (arg_list); + ecma_free_values_collection (arg_collection_p, true); ECMA_OP_TO_NUMBER_FINALIZE (length_number); ECMA_FINALIZE (length_value); @@ -199,15 +188,14 @@ ecma_builtin_function_prototype_object_call (ecma_value_t this_arg, /**< this ar { return ecma_op_function_call (func_obj_p, ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED), - NULL, - 0); + NULL); } else { - return ecma_op_function_call (func_obj_p, - arguments_list_p[0], - (arguments_number == 1u) ? NULL : (arguments_list_p + 1), - (ecma_length_t) (arguments_number - 1u)); + return ecma_op_function_call_array_args (func_obj_p, + arguments_list_p[0], + (arguments_number == 1u) ? NULL : (arguments_list_p + 1), + (ecma_length_t) (arguments_number - 1u)); } } } /* ecma_builtin_function_prototype_object_call */ diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.cpp b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.cpp index 861febf24..ff88c9e51 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.cpp +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.cpp @@ -158,8 +158,7 @@ ecma_builtin_helper_get_to_locale_string_at_index (ecma_object_t *obj_p, /** < t ECMA_TRY_CATCH (call_value, ecma_op_function_call (locale_func_obj_p, ecma_make_object_value (index_obj_p), - NULL, - 0), + NULL), ret_value); ret_value = ecma_op_to_string (call_value); ECMA_FINALIZE (call_value); diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-json.cpp b/jerry-core/ecma/builtin-objects/ecma-builtin-json.cpp index 6f139b80f..017dce325 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-json.cpp +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-json.cpp @@ -793,10 +793,10 @@ ecma_builtin_json_walk (ecma_object_t *reviver_p, /**< reviver function */ /* * The completion value can be anything including exceptions. */ - ret_value = ecma_op_function_call (reviver_p, - ecma_make_object_value (holder_p), - arguments_list, - 2); + ret_value = ecma_op_function_call_array_args (reviver_p, + ecma_make_object_value (holder_p), + arguments_list, + 2); } else { @@ -1353,7 +1353,7 @@ ecma_builtin_json_str (ecma_string_t *key_p, /**< property key*/ ecma_object_t *toJSON_obj_p = ecma_get_object_from_value (toJSON); ECMA_TRY_CATCH (func_ret_val, - ecma_op_function_call (toJSON_obj_p, my_val, call_args, 1), + ecma_op_function_call_array_args (toJSON_obj_p, my_val, call_args, 1), ret_value); ecma_free_value (my_val, true); @@ -1375,7 +1375,7 @@ ecma_builtin_json_str (ecma_string_t *key_p, /**< property key*/ ecma_value_t call_args[] = { key_value, my_val }; ECMA_TRY_CATCH (func_ret_val, - ecma_op_function_call (context_p->replacer_function_p, holder_value, call_args, 2), + ecma_op_function_call_array_args (context_p->replacer_function_p, holder_value, call_args, 2), ret_value); ecma_free_value (my_val, true); diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-object-prototype.cpp b/jerry-core/ecma/builtin-objects/ecma-builtin-object-prototype.cpp index b9e9f7560..cffaef2f3 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-object-prototype.cpp +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-object-prototype.cpp @@ -110,7 +110,7 @@ ecma_builtin_object_prototype_object_to_locale_string (ecma_value_t this_arg) /* { /* 4. */ ecma_object_t *to_string_func_obj_p = ecma_get_object_from_value (to_string_val); - return_value = ecma_op_function_call (to_string_func_obj_p, this_arg, NULL, 0); + return_value = ecma_op_function_call (to_string_func_obj_p, this_arg, NULL); } ECMA_FINALIZE (to_string_val); diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.cpp b/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.cpp index c2caf0100..d4fa0ade1 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.cpp +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.cpp @@ -1045,10 +1045,10 @@ ecma_builtin_string_prototype_object_replace_get_string (ecma_builtin_replace_se arguments_list[length + 1] = ecma_copy_value (context_p->input_string, true); ECMA_TRY_CATCH (result_value, - ecma_op_function_call (context_p->replace_function_p, - context_p->regexp_or_search_string, - arguments_list, - length + 2), + ecma_op_function_call_array_args (context_p->replace_function_p, + context_p->regexp_or_search_string, + arguments_list, + length + 2), ret_value); ECMA_TRY_CATCH (to_string_value, diff --git a/jerry-core/ecma/builtin-objects/ecma-builtins.cpp b/jerry-core/ecma/builtin-objects/ecma-builtins.cpp index 711e177bf..7a7db84bd 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtins.cpp +++ b/jerry-core/ecma/builtin-objects/ecma-builtins.cpp @@ -392,11 +392,25 @@ ecma_builtin_make_function_object_for_routine (ecma_builtin_id_t builtin_id, /** ecma_completion_value_t ecma_builtin_dispatch_call (ecma_object_t *obj_p, /**< built-in object */ ecma_value_t this_arg_value, /**< 'this' argument value */ - const ecma_value_t *arguments_list_p, /**< arguments list */ - ecma_length_t arguments_list_len) /**< length of the arguments list */ + ecma_collection_header_t* arg_collection_p) /**< arguments collection */ { JERRY_ASSERT (ecma_get_object_is_builtin (obj_p)); - JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL); + + ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); + + const ecma_length_t arguments_list_len = arg_collection_p != NULL ? arg_collection_p->unit_number : 0; + MEM_DEFINE_LOCAL_ARRAY (arguments_list_p, arguments_list_len, ecma_value_t); + + ecma_collection_iterator_t arg_collection_iter; + ecma_collection_iterator_init (&arg_collection_iter, + arg_collection_p); + + for (ecma_length_t arg_index = 0; + ecma_collection_iterator_next (&arg_collection_iter); + arg_index++) + { + arguments_list_p[arg_index] = *arg_collection_iter.current_value_p; + } if (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION) { @@ -417,11 +431,11 @@ ecma_builtin_dispatch_call (ecma_object_t *obj_p, /**< built-in object */ ecma_builtin_id_t built_in_id = (ecma_builtin_id_t) built_in_id_field; uint16_t routine_id = (uint16_t) routine_id_field; - return ecma_builtin_dispatch_routine (built_in_id, - routine_id, - this_arg_value, - arguments_list_p, - arguments_list_len); + ret_value = ecma_builtin_dispatch_routine (built_in_id, + routine_id, + this_arg_value, + arguments_list_p, + arguments_list_len); } else { @@ -445,13 +459,10 @@ ecma_builtin_dispatch_call (ecma_object_t *obj_p, /**< built-in object */ { \ if (object_type == ECMA_OBJECT_TYPE_FUNCTION) \ { \ - return ecma_builtin_ ## lowercase_name ## _dispatch_call (arguments_list_p, \ - arguments_list_len); \ - } \ - else \ - { \ - JERRY_UNREACHABLE (); \ + ret_value = ecma_builtin_ ## lowercase_name ## _dispatch_call (arguments_list_p, \ + arguments_list_len); \ } \ + break; \ } #include "ecma-builtins.inc.h" @@ -471,7 +482,11 @@ ecma_builtin_dispatch_call (ecma_object_t *obj_p, /**< built-in object */ } } - JERRY_UNREACHABLE (); + MEM_FINALIZE_LOCAL_ARRAY (arguments_list_p); + + JERRY_ASSERT (!ecma_is_completion_value_empty (ret_value)); + + return ret_value; } /* ecma_builtin_dispatch_call */ /** @@ -481,13 +496,26 @@ ecma_builtin_dispatch_call (ecma_object_t *obj_p, /**< built-in object */ */ ecma_completion_value_t ecma_builtin_dispatch_construct (ecma_object_t *obj_p, /**< built-in object */ - const ecma_value_t *arguments_list_p, /**< arguments list */ - ecma_length_t arguments_list_len) /**< length of the arguments list */ + ecma_collection_header_t* arg_collection_p) /**< arguments collection */ { JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_FUNCTION); - JERRY_ASSERT (ecma_get_object_is_builtin (obj_p)); - JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL); + + ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); + + const ecma_length_t arguments_list_len = arg_collection_p != NULL ? arg_collection_p->unit_number : 0; + MEM_DEFINE_LOCAL_ARRAY (arguments_list_p, arguments_list_len, ecma_value_t); + + ecma_collection_iterator_t arg_collection_iter; + ecma_collection_iterator_init (&arg_collection_iter, + arg_collection_p); + + for (ecma_length_t arg_index = 0; + ecma_collection_iterator_next (&arg_collection_iter); + arg_index++) + { + arguments_list_p[arg_index] = *arg_collection_iter.current_value_p; + } ecma_property_t *built_in_id_prop_p = ecma_get_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_BUILT_IN_ID); @@ -495,6 +523,7 @@ ecma_builtin_dispatch_construct (ecma_object_t *obj_p, /**< built-in object */ JERRY_ASSERT (ecma_builtin_is (obj_p, builtin_id)); + JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_FUNCTION); switch (builtin_id) { #define BUILTIN(builtin_id, \ @@ -507,13 +536,10 @@ ecma_builtin_dispatch_construct (ecma_object_t *obj_p, /**< built-in object */ { \ if (object_type == ECMA_OBJECT_TYPE_FUNCTION) \ { \ - return ecma_builtin_ ## lowercase_name ## _dispatch_construct (arguments_list_p, \ - arguments_list_len); \ - } \ - else \ - { \ - JERRY_UNREACHABLE (); \ + ret_value = ecma_builtin_ ## lowercase_name ## _dispatch_construct (arguments_list_p, \ + arguments_list_len); \ } \ + break; \ } #include "ecma-builtins.inc.h" @@ -532,7 +558,11 @@ ecma_builtin_dispatch_construct (ecma_object_t *obj_p, /**< built-in object */ } } - JERRY_UNREACHABLE (); + MEM_FINALIZE_LOCAL_ARRAY (arguments_list_p); + + JERRY_ASSERT (!ecma_is_completion_value_empty (ret_value)); + + return ret_value; } /* ecma_builtin_dispatch_construct */ /** diff --git a/jerry-core/ecma/builtin-objects/ecma-builtins.h b/jerry-core/ecma/builtin-objects/ecma-builtins.h index e0904c264..f60425ade 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtins.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtins.h @@ -41,12 +41,10 @@ extern void ecma_finalize_builtins (void); extern ecma_completion_value_t ecma_builtin_dispatch_call (ecma_object_t *obj_p, ecma_value_t this_arg, - const ecma_value_t *arguments_list_p, - ecma_length_t arguments_list_len); + ecma_collection_header_t *arg_collection_p); extern ecma_completion_value_t ecma_builtin_dispatch_construct (ecma_object_t *obj_p, - const ecma_value_t *arguments_list_p, - ecma_length_t arguments_list_len); + ecma_collection_header_t *arg_collection_p); extern ecma_property_t* ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, ecma_string_t *string_p); diff --git a/jerry-core/ecma/operations/ecma-function-object.cpp b/jerry-core/ecma/operations/ecma-function-object.cpp index 6dbc2ad93..3ddfb6119 100644 --- a/jerry-core/ecma/operations/ecma-function-object.cpp +++ b/jerry-core/ecma/operations/ecma-function-object.cpp @@ -154,16 +154,16 @@ ecma_is_constructor (ecma_value_t value) /**< ecma-value */ * - [[Call]] implementation for Function objects. * - [[Construct]] implementation for Function objects. * - * @return ecma_value_t* - pointer to the merged argument list. + * @return collection of arguments that should be freed + * using ecma_free_values_collection with do_ref_if_object flag set */ -static ecma_value_t* +static ecma_collection_header_t * ecma_function_bind_merge_arg_lists (ecma_object_t *func_obj_p, /**< Function object */ - const ecma_value_t *arguments_list_p, /**< arguments list */ - ecma_length_t arguments_list_len, /**< length of arguments list */ - ecma_length_t *total_args_count) /**< length of the merged argument list */ + ecma_collection_header_t* passed_arg_collection_p) /**< passed arguments list */ { - ecma_value_t *arg_list_p; - ecma_length_t bound_args_count = 0; + ecma_length_t passed_args_number = passed_arg_collection_p != NULL ? passed_arg_collection_p->unit_number : 0; + + ecma_collection_header_t *merged_arg_collection_p = ecma_new_values_collection (NULL, 0, true); ecma_property_t *bound_args_prop_p; bound_args_prop_p = ecma_find_internal_property (func_obj_p, ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_BOUND_ARGS); @@ -176,35 +176,26 @@ ecma_function_bind_merge_arg_lists (ecma_object_t *func_obj_p, /**< Function obj ecma_collection_iterator_t bound_args_iterator; ecma_collection_iterator_init (&bound_args_iterator, bound_arg_list_p); - bound_args_count = bound_arg_list_p->unit_number; - - *total_args_count = bound_args_count + arguments_list_len; - - const size_t arg_list_size = (size_t) *total_args_count * sizeof (ecma_value_t); - arg_list_p = static_cast (mem_heap_alloc_block (arg_list_size, MEM_HEAP_ALLOC_SHORT_TERM)); - - for (ecma_length_t i = 0; i < bound_args_count; i++) + for (ecma_length_t i = 0; i < bound_arg_list_p->unit_number; i++) { bool is_moved = ecma_collection_iterator_next (&bound_args_iterator); JERRY_ASSERT (is_moved); - arg_list_p[i] = *bound_args_iterator.current_value_p; + ecma_append_to_values_collection (merged_arg_collection_p, *bound_args_iterator.current_value_p, true); } } - else - { - *total_args_count = arguments_list_len; - const size_t arg_list_size = (size_t) *total_args_count * sizeof (ecma_value_t); - arg_list_p = static_cast (mem_heap_alloc_block (arg_list_size, MEM_HEAP_ALLOC_SHORT_TERM)); + ecma_collection_iterator_t passed_args_iterator; + ecma_collection_iterator_init (&passed_args_iterator, passed_arg_collection_p); + for (ecma_length_t i = 0; i < passed_args_number; i++) + { + bool is_moved = ecma_collection_iterator_next (&passed_args_iterator); + JERRY_ASSERT (is_moved); + + ecma_append_to_values_collection (merged_arg_collection_p, *passed_args_iterator.current_value_p, true); } - for (ecma_length_t i = 0; i < arguments_list_len; i++) - { - arg_list_p[i + bound_args_count] = arguments_list_p[i]; - } - - return arg_list_p; + return merged_arg_collection_p; } /* ecma_function_bind_merge_arg_lists */ /** @@ -435,8 +426,7 @@ ecma_op_create_external_function_object (ecma_external_pointer_t code_p) /**< po static ecma_completion_value_t ecma_function_call_setup_args_variables (ecma_object_t *func_obj_p, /**< Function object */ ecma_object_t *env_p, /**< lexical environment */ - const ecma_value_t *arguments_list_p, /**< arguments list */ - ecma_length_t arguments_list_len, /**< length of argument list */ + ecma_collection_header_t *arg_collection_p, /**< arguments collection */ bool is_strict, /**< flag indicating strict mode */ bool do_instantiate_arguments_object) /**< flag indicating whether * Arguments object should be @@ -452,7 +442,9 @@ ecma_function_call_setup_args_variables (ecma_object_t *func_obj_p, /**< Functio { ecma_length_t formal_parameters_count = formal_parameters_p->unit_number; - ecma_collection_iterator_t formal_params_iterator; + ecma_collection_iterator_t arguments_iterator, formal_params_iterator; + + ecma_collection_iterator_init (&arguments_iterator, arg_collection_p); ecma_collection_iterator_init (&formal_params_iterator, formal_parameters_p); /* @@ -467,14 +459,14 @@ ecma_function_call_setup_args_variables (ecma_object_t *func_obj_p, /**< Functio n < formal_parameters_count; n++) { - ecma_value_t v; - if (n >= arguments_list_len) + ecma_value_t arg_value; + if (ecma_collection_iterator_next (&arguments_iterator)) { - v = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED); + arg_value = *arguments_iterator.current_value_p; } else { - v = arguments_list_p[n]; + arg_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED); } bool is_moved = ecma_collection_iterator_next (&formal_params_iterator); @@ -499,7 +491,7 @@ ecma_function_call_setup_args_variables (ecma_object_t *func_obj_p, /**< Functio ecma_completion_value_t completion = ecma_op_set_mutable_binding (env_p, formal_parameter_name_string_p, - v, + arg_value, is_strict); if (ecma_is_completion_value_throw (completion)) @@ -536,8 +528,7 @@ ecma_function_call_setup_args_variables (ecma_object_t *func_obj_p, /**< Functio ecma_object_t *args_obj_p = ecma_op_create_arguments_object (func_obj_p, env_p, formal_parameters_p, - arguments_list_p, - arguments_list_len, + arg_collection_p, is_strict); if (is_strict) @@ -657,6 +648,41 @@ ecma_op_function_has_instance (ecma_object_t *func_obj_p, /**< Function object * return ret_value; } /* ecma_op_function_has_instance */ +/** + * Function call helper with arguments list specified in array instead of collection + * + * See also: + * ecma_op_function_call + * + * @return completion value + * Returned value must be freed with ecma_free_completion_value + */ +ecma_completion_value_t +ecma_op_function_call_array_args (ecma_object_t *func_obj_p, /**< Function object */ + ecma_value_t this_arg_value, /**< 'this' argument's value */ + const ecma_value_t* arguments_list_p, /**< arguments list */ + ecma_length_t arguments_list_len) /**< length of arguments list */ +{ + if (arguments_list_len == 0) + { + return ecma_op_function_call (func_obj_p, this_arg_value, NULL); + } + else + { + ecma_collection_header_t *arg_collection_p = ecma_new_values_collection (arguments_list_p, + arguments_list_len, + true); + + ecma_completion_value_t ret_value = ecma_op_function_call (func_obj_p, + this_arg_value, + arg_collection_p); + + ecma_free_values_collection (arg_collection_p, true); + + return ret_value; + } +} /* ecma_op_function_call_array_args */ + /** * [[Call]] implementation for Function objects, * created through 13.2 (ECMA_OBJECT_TYPE_FUNCTION) @@ -670,13 +696,11 @@ ecma_op_function_has_instance (ecma_object_t *func_obj_p, /**< Function object * ecma_completion_value_t ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */ ecma_value_t this_arg_value, /**< 'this' argument's value */ - const ecma_value_t* arguments_list_p, /**< arguments list */ - ecma_length_t arguments_list_len) /**< length of arguments list */ + ecma_collection_header_t* arg_collection_p) /**< arguments list */ { JERRY_ASSERT (func_obj_p != NULL && !ecma_is_lexical_environment (func_obj_p)); JERRY_ASSERT (ecma_op_is_callable (ecma_make_object_value (func_obj_p))); - JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL); ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); @@ -686,8 +710,7 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */ { ret_value = ecma_builtin_dispatch_call (func_obj_p, this_arg_value, - arguments_list_p, - arguments_list_len); + arg_collection_p); } else { @@ -737,8 +760,7 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */ ECMA_TRY_CATCH (args_var_declaration_ret, ecma_function_call_setup_args_variables (func_obj_p, local_env_p, - arguments_list_p, - arguments_list_len, + arg_collection_p, is_strict, do_instantiate_args_obj), ret_value); @@ -769,8 +791,7 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */ { ret_value = ecma_builtin_dispatch_call (func_obj_p, this_arg_value, - arguments_list_p, - arguments_list_len); + arg_collection_p); } else if (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION) { @@ -783,8 +804,7 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */ ret_value = jerry_dispatch_external_function (func_obj_p, handler_p, this_arg_value, - arguments_list_p, - arguments_list_len); + arg_collection_p); } else { @@ -801,29 +821,22 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */ ecma_object_t *target_func_obj_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, target_function_prop_p->u.internal_property.value); - ecma_length_t total_args_count; - /* 4. */ - ecma_value_t *arg_list_p = ecma_function_bind_merge_arg_lists (func_obj_p, - arguments_list_p, - arguments_list_len, - &total_args_count); + ecma_collection_header_t *merged_arg_collection_p = ecma_function_bind_merge_arg_lists (func_obj_p, + arg_collection_p); ecma_value_t bound_this_value = bound_this_prop_p->u.internal_property.value; /* 5. */ ret_value = ecma_op_function_call (target_func_obj_p, bound_this_value, - arg_list_p, - total_args_count); + merged_arg_collection_p); - if (arg_list_p != NULL) - { - mem_heap_free_block (arg_list_p); - } + ecma_free_values_collection (merged_arg_collection_p, true); } JERRY_ASSERT (!ecma_is_completion_value_empty (ret_value)); + return ret_value; } /* ecma_op_function_call */ @@ -837,8 +850,8 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */ */ static ecma_completion_value_t ecma_op_function_construct_simple_or_external (ecma_object_t *func_obj_p, /**< Function object */ - const ecma_value_t* arguments_list_p, /**< arguments list */ - ecma_length_t arguments_list_len) /**< length of arguments list */ + ecma_collection_header_t* arg_collection_p) /**< arguments + * collection */ { JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_FUNCTION || ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION); @@ -885,8 +898,7 @@ ecma_op_function_construct_simple_or_external (ecma_object_t *func_obj_p, /**< F ECMA_TRY_CATCH (call_completion, ecma_op_function_call (func_obj_p, ecma_make_object_value (obj_p), - arguments_list_p, - arguments_list_len), + arg_collection_p), ret_value); ecma_value_t obj_value; @@ -927,13 +939,11 @@ ecma_op_function_construct_simple_or_external (ecma_object_t *func_obj_p, /**< F */ ecma_completion_value_t ecma_op_function_construct (ecma_object_t *func_obj_p, /**< Function object */ - const ecma_value_t* arguments_list_p, /**< arguments list */ - ecma_length_t arguments_list_len) /**< length of arguments list */ + ecma_collection_header_t *arg_collection_p) /**< arguments collection */ { JERRY_ASSERT (func_obj_p != NULL && !ecma_is_lexical_environment (func_obj_p)); JERRY_ASSERT (ecma_is_constructor (ecma_make_object_value (func_obj_p))); - JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL); ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); @@ -942,16 +952,16 @@ ecma_op_function_construct (ecma_object_t *func_obj_p, /**< Function object */ if (unlikely (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_FUNCTION && ecma_get_object_is_builtin (func_obj_p))) { - ret_value = ecma_builtin_dispatch_construct (func_obj_p, arguments_list_p, arguments_list_len); + ret_value = ecma_builtin_dispatch_construct (func_obj_p, arg_collection_p); } else { - ret_value = ecma_op_function_construct_simple_or_external (func_obj_p, arguments_list_p, arguments_list_len); + ret_value = ecma_op_function_construct_simple_or_external (func_obj_p, arg_collection_p); } } else if (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION) { - ret_value = ecma_op_function_construct_simple_or_external (func_obj_p, arguments_list_p, arguments_list_len); + ret_value = ecma_op_function_construct_simple_or_external (func_obj_p, arg_collection_p); } else { @@ -972,22 +982,15 @@ ecma_op_function_construct (ecma_object_t *func_obj_p, /**< Function object */ } else { - ecma_length_t total_args_count; - /* 4. */ - ecma_value_t *arg_list_p = ecma_function_bind_merge_arg_lists (func_obj_p, - arguments_list_p, - arguments_list_len, - &total_args_count); + ecma_collection_header_t *merged_arg_collection_p = ecma_function_bind_merge_arg_lists (func_obj_p, + arg_collection_p); /* 5. */ ret_value = ecma_op_function_construct (target_func_obj_p, - arg_list_p, - total_args_count); - if (arg_list_p != NULL) - { - mem_heap_free_block (arg_list_p); - } + merged_arg_collection_p); + + ecma_free_values_collection (merged_arg_collection_p, true); } } diff --git a/jerry-core/ecma/operations/ecma-function-object.h b/jerry-core/ecma/operations/ecma-function-object.h index a2a7779b5..bad581d1a 100644 --- a/jerry-core/ecma/operations/ecma-function-object.h +++ b/jerry-core/ecma/operations/ecma-function-object.h @@ -42,13 +42,18 @@ ecma_op_create_external_function_object (ecma_external_pointer_t code_p); extern ecma_completion_value_t ecma_op_function_call (ecma_object_t *func_obj_p, ecma_value_t this_arg_value, - const ecma_value_t* arguments_list_p, - ecma_length_t arguments_list_len); + ecma_collection_header_t *arg_collection_p); + +extern ecma_completion_value_t +ecma_op_function_call_array_args (ecma_object_t *func_obj_p, + ecma_value_t this_arg_value, + const ecma_value_t* arguments_list_p, + ecma_length_t arguments_list_len); + extern ecma_completion_value_t ecma_op_function_construct (ecma_object_t *func_obj_p, - const ecma_value_t* arguments_list_p, - ecma_length_t arguments_list_len); + ecma_collection_header_t *arg_collection_p); extern ecma_completion_value_t ecma_op_function_has_instance (ecma_object_t *func_obj_p, diff --git a/jerry-core/ecma/operations/ecma-get-put-value.cpp b/jerry-core/ecma/operations/ecma-get-put-value.cpp index 1e2ff1a2e..b0f8f9ea0 100644 --- a/jerry-core/ecma/operations/ecma-get-put-value.cpp +++ b/jerry-core/ecma/operations/ecma-get-put-value.cpp @@ -146,8 +146,7 @@ ecma_op_get_value_object_base (ecma_reference_t ref) /**< ECMA-reference */ // 7. ret_value = ecma_op_function_call (obj_p, base, - NULL, - 0); + NULL); } } @@ -324,7 +323,7 @@ ecma_op_put_value_object_base (ecma_reference_t ref, /**< ECMA-reference */ JERRY_ASSERT (setter_p != NULL); ECMA_TRY_CATCH (call_ret, - ecma_op_function_call (setter_p, base, &value, 1), + ecma_op_function_call_array_args (setter_p, base, &value, 1), ret_value); ret_value = ecma_make_empty_completion_value (); diff --git a/jerry-core/ecma/operations/ecma-objects-arguments.cpp b/jerry-core/ecma/operations/ecma-objects-arguments.cpp index 915bb3457..62ba6bbb4 100644 --- a/jerry-core/ecma/operations/ecma-objects-arguments.cpp +++ b/jerry-core/ecma/operations/ecma-objects-arguments.cpp @@ -45,13 +45,14 @@ ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function ecma_object_t *lex_env_p, /**< lexical environment the Arguments object is created for */ ecma_collection_header_t *formal_params_p, /**< formal parameters collection */ - const ecma_value_t *arguments_list_p, /**< list of arguments */ - ecma_length_t arguments_list_length, /**< length of arguments' list */ + ecma_collection_header_t *arg_collection_p, /**< arguments collection */ bool is_strict) /**< flag indicating whether strict mode is enabled */ { + const ecma_length_t arguments_number = arg_collection_p != NULL ? arg_collection_p->unit_number : 0; + // 1. ecma_number_t *len_p = ecma_alloc_number (); - *len_p = ecma_uint32_to_number (arguments_list_length); + *len_p = ecma_uint32_to_number (arguments_number); // 2., 3., 6. ecma_object_t *prototype_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE); @@ -90,14 +91,20 @@ ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function ecma_dealloc_number (len_p); // 11.a, 11.b + ecma_collection_iterator_t args_iterator; + ecma_collection_iterator_init (&args_iterator, arg_collection_p); + for (ecma_length_t indx = 0; - indx < arguments_list_length; + indx < arguments_number; indx++) { + bool is_moved = ecma_collection_iterator_next (&args_iterator); + JERRY_ASSERT (is_moved); + prop_desc = ecma_make_empty_property_descriptor (); { prop_desc.is_value_defined = true; - prop_desc.value = arguments_list_p[indx]; + prop_desc.value = *args_iterator.current_value_p; prop_desc.is_writable_defined = true; prop_desc.is_writable = true; @@ -128,7 +135,7 @@ ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function ecma_collection_iterator_init (&formal_params_iterator, formal_params_p); if (!is_strict - && arguments_list_length > 0 + && arguments_number > 0 && formal_params_number > 0) { // 8. diff --git a/jerry-core/ecma/operations/ecma-objects-arguments.h b/jerry-core/ecma/operations/ecma-objects-arguments.h index 5c3c2314a..d1e743bb9 100644 --- a/jerry-core/ecma/operations/ecma-objects-arguments.h +++ b/jerry-core/ecma/operations/ecma-objects-arguments.h @@ -23,8 +23,7 @@ extern ecma_object_t* ecma_op_create_arguments_object (ecma_object_t *func_obj_p, ecma_object_t *lex_env_p, ecma_collection_header_t *formal_params_p, - const ecma_value_t *arguments_list_p, - ecma_length_t arguments_list_length, + ecma_collection_header_t *arg_collection_p, bool is_strict); extern ecma_completion_value_t ecma_op_arguments_object_get (ecma_object_t *obj_p, diff --git a/jerry-core/ecma/operations/ecma-objects-general.cpp b/jerry-core/ecma/operations/ecma-objects-general.cpp index 64a2a613e..468057aa6 100644 --- a/jerry-core/ecma/operations/ecma-objects-general.cpp +++ b/jerry-core/ecma/operations/ecma-objects-general.cpp @@ -174,8 +174,7 @@ ecma_op_general_object_get (ecma_object_t *obj_p, /**< the object */ { return ecma_op_function_call (getter_p, ecma_make_object_value (obj_p), - NULL, - 0); + NULL); } } @@ -314,10 +313,10 @@ ecma_op_general_object_put (ecma_object_t *obj_p, /**< the object */ ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); ECMA_TRY_CATCH (call_ret, - ecma_op_function_call (setter_p, - ecma_make_object_value (obj_p), - &value, - 1), + ecma_op_function_call_array_args (setter_p, + ecma_make_object_value (obj_p), + &value, + 1), ret_value); ret_value = ecma_make_simple_completion_value (ECMA_SIMPLE_VALUE_TRUE); @@ -569,7 +568,7 @@ ecma_op_general_object_default_value (ecma_object_t *obj_p, /**< the object */ call_completion = ecma_op_function_call (func_obj_p, ecma_make_object_value (obj_p), - NULL, 0); + NULL); } ecma_free_completion_value (function_value_get_completion); diff --git a/jerry-core/jerry-internal.h b/jerry-core/jerry-internal.h index 18146bc20..12203e2d6 100644 --- a/jerry-core/jerry-internal.h +++ b/jerry-core/jerry-internal.h @@ -27,8 +27,7 @@ extern ecma_completion_value_t jerry_dispatch_external_function (ecma_object_t *function_object_p, ecma_external_pointer_t handler_p, ecma_value_t this_arg_value, - const ecma_value_t args_p[], - ecma_length_t args_count); + ecma_collection_header_t *arg_collection_p); extern void jerry_dispatch_object_free_callback (ecma_external_pointer_t freecb_p, diff --git a/jerry-core/jerry.cpp b/jerry-core/jerry.cpp index b6636f7e5..f484e6c75 100644 --- a/jerry-core/jerry.cpp +++ b/jerry-core/jerry.cpp @@ -556,20 +556,25 @@ ecma_completion_value_t jerry_dispatch_external_function (ecma_object_t *function_object_p, /**< external function object */ ecma_external_pointer_t handler_p, /**< pointer to the function's native handler */ ecma_value_t this_arg_value, /**< 'this' argument */ - const ecma_value_t args_p[], /**< arguments list */ - ecma_length_t args_count) /**< number of arguments */ + ecma_collection_header_t *arg_collection_p) /**< arguments collection */ { jerry_assert_api_available (); - JERRY_STATIC_ASSERT (sizeof (args_count) == sizeof (uint32_t)); + const ecma_length_t args_count = (arg_collection_p != NULL ? arg_collection_p->unit_number : 0); ecma_completion_value_t completion_value; MEM_DEFINE_LOCAL_ARRAY (api_arg_values, args_count, jerry_api_value_t); + ecma_collection_iterator_t args_iterator; + ecma_collection_iterator_init (&args_iterator, arg_collection_p); + for (uint32_t i = 0; i < args_count; ++i) { - jerry_api_convert_ecma_value_to_api_value (&api_arg_values[i], args_p[i]); + bool is_moved = ecma_collection_iterator_next (&args_iterator); + JERRY_ASSERT (is_moved); + + jerry_api_convert_ecma_value_to_api_value (&api_arg_values[i], *args_iterator.current_value_p); } jerry_api_value_t api_this_arg_value, api_ret_value; @@ -982,11 +987,16 @@ jerry_api_invoke_function (bool is_invoke_as_constructor, /**< true - invoke fun bool is_successful = true; - MEM_DEFINE_LOCAL_ARRAY (arg_values, args_count, ecma_value_t); + ecma_collection_header_t *arg_collection_p = ecma_new_values_collection (NULL, 0, true); for (uint32_t i = 0; i < args_count; ++i) { - jerry_api_convert_api_value_to_ecma_value (&arg_values[i], &args_p[i]); + ecma_value_t arg_value; + jerry_api_convert_api_value_to_ecma_value (&arg_value, &args_p[i]); + + ecma_append_to_values_collection (arg_collection_p, arg_value, true); + + ecma_free_value (arg_value, true); } ecma_completion_value_t call_completion; @@ -996,9 +1006,7 @@ jerry_api_invoke_function (bool is_invoke_as_constructor, /**< true - invoke fun JERRY_ASSERT (this_arg_p == NULL); JERRY_ASSERT (jerry_api_is_constructor (function_object_p)); - call_completion = ecma_op_function_construct (function_object_p, - arg_values, - args_count); + call_completion = ecma_op_function_construct (function_object_p, arg_collection_p); } else { @@ -1017,10 +1025,11 @@ jerry_api_invoke_function (bool is_invoke_as_constructor, /**< true - invoke fun call_completion = ecma_op_function_call (function_object_p, this_arg_val, - arg_values, - args_count); + arg_collection_p); } + ecma_free_values_collection (arg_collection_p, true); + if (!ecma_is_completion_value_normal (call_completion)) { /* unhandled exception during the function call */ @@ -1037,13 +1046,6 @@ jerry_api_invoke_function (bool is_invoke_as_constructor, /**< true - invoke fun ecma_free_completion_value (call_completion); - for (uint32_t i = 0; i < args_count; i++) - { - ecma_free_value (arg_values[i], true); - } - - MEM_FINALIZE_LOCAL_ARRAY (arg_values); - return is_successful; } /* jerry_api_invoke_function */ diff --git a/jerry-core/vm/opcodes.cpp b/jerry-core/vm/opcodes.cpp index ac982b8f0..dd6d877aa 100644 --- a/jerry-core/vm/opcodes.cpp +++ b/jerry-core/vm/opcodes.cpp @@ -541,7 +541,7 @@ opfunc_func_decl_n (vm_instr_t instr, /**< instruction */ ecma_completion_value_t ret_value; - ecma_collection_header_t *formal_params_collection_p = ecma_new_values_collection (NULL, 0, false); + ecma_collection_header_t *formal_params_collection_p = ecma_new_strings_collection (NULL, 0); vm_fill_params_list (frame_ctx_p, params_number, formal_params_collection_p); @@ -575,7 +575,7 @@ opfunc_func_expr_n (vm_instr_t instr, /**< instruction */ vm_instr_counter_t function_code_end_oc; - ecma_collection_header_t *formal_params_collection_p = ecma_new_values_collection (NULL, 0, false); + ecma_collection_header_t *formal_params_collection_p = ecma_new_strings_collection (NULL, 0); vm_fill_params_list (frame_ctx_p, params_number, formal_params_collection_p); @@ -816,24 +816,10 @@ opfunc_call_n (vm_instr_t instr, /**< instruction */ ecma_object_t *func_obj_p = ecma_get_object_from_value (func_value); - MEM_DEFINE_LOCAL_ARRAY (arg_values, args_read, ecma_value_t); - - ecma_collection_iterator_t arg_collection_iter; - ecma_collection_iterator_init (&arg_collection_iter, - arg_collection_p); - - for (ecma_length_t arg_index = 0; - ecma_collection_iterator_next (&arg_collection_iter); - arg_index++) - { - arg_values[arg_index] = *arg_collection_iter.current_value_p; - } - ECMA_TRY_CATCH (call_ret_value, ecma_op_function_call (func_obj_p, this_value, - arg_values, - args_read), + arg_collection_p), ret_value); ret_value = set_variable_value (frame_ctx_p, lit_oc, @@ -842,8 +828,6 @@ opfunc_call_n (vm_instr_t instr, /**< instruction */ ECMA_FINALIZE (call_ret_value); - MEM_FINALIZE_LOCAL_ARRAY (arg_values); - if (call_flags & OPCODE_CALL_FLAGS_DIRECT_CALL_TO_EVAL_FORM) { JERRY_ASSERT (frame_ctx_p->is_call_in_direct_eval_form); @@ -888,6 +872,7 @@ opfunc_construct_n (vm_instr_t instr, /**< instruction */ const vm_instr_counter_t lit_oc = frame_ctx_p->pos; ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); + ECMA_TRY_CATCH (constructor_value, get_variable_value (frame_ctx_p, constructor_name_lit_idx, false), ret_value); @@ -913,31 +898,15 @@ opfunc_construct_n (vm_instr_t instr, /**< instruction */ { ecma_object_t *constructor_obj_p = ecma_get_object_from_value (constructor_value); - MEM_DEFINE_LOCAL_ARRAY (arg_values, args_read, ecma_value_t); - - ecma_collection_iterator_t arg_collection_iter; - ecma_collection_iterator_init (&arg_collection_iter, - arg_collection_p); - - for (ecma_length_t arg_index = 0; - ecma_collection_iterator_next (&arg_collection_iter); - arg_index++) - { - arg_values[arg_index] = *arg_collection_iter.current_value_p; - } - ECMA_TRY_CATCH (construction_ret_value, ecma_op_function_construct (constructor_obj_p, - arg_values, - args_number), + arg_collection_p), ret_value); ret_value = set_variable_value (frame_ctx_p, lit_oc, lhs_var_idx, construction_ret_value); ECMA_FINALIZE (construction_ret_value); - - MEM_FINALIZE_LOCAL_ARRAY (arg_values); } } else