From cadc81d583ff0d40aac571b968e864b1e8fdf52d Mon Sep 17 00:00:00 2001 From: Zoltan Herczeg Date: Wed, 10 Feb 2016 02:58:27 -0800 Subject: [PATCH] ECMAScript Parameters cannot be passed in collections anymore, only as arrays. JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com --- .../ecma-builtin-array-prototype.cpp | 38 +-- .../ecma-builtin-date-prototype.cpp | 2 +- .../ecma-builtin-function-prototype.cpp | 37 ++- .../builtin-objects/ecma-builtin-helpers.cpp | 3 +- .../builtin-objects/ecma-builtin-json.cpp | 12 +- .../ecma-builtin-object-prototype.cpp | 2 +- .../ecma-builtin-string-prototype.cpp | 8 +- .../ecma/builtin-objects/ecma-builtins.cpp | 38 +-- .../ecma/builtin-objects/ecma-builtins.h | 6 +- .../ecma/operations/ecma-function-object.cpp | 309 +++++++----------- .../ecma/operations/ecma-function-object.h | 10 +- .../ecma/operations/ecma-get-put-value.cpp | 6 +- .../operations/ecma-objects-arguments.cpp | 148 ++------- .../ecma/operations/ecma-objects-arguments.h | 8 +- .../ecma/operations/ecma-objects-general.cpp | 14 +- jerry-core/jerry.cpp | 25 +- jerry-core/vm/opcodes.cpp | 23 +- jerry-core/vm/opcodes.h | 9 +- jerry-core/vm/vm.cpp | 83 +---- jerry-core/vm/vm.h | 11 +- 20 files changed, 270 insertions(+), 522 deletions(-) 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 f376f1864..e42291d4f 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); + return_value = ecma_op_function_call (join_func_obj_p, this_arg, NULL, 0); } ECMA_FINALIZE (join_value); @@ -545,8 +545,6 @@ ecma_builtin_array_prototype_object_push (ecma_value_t this_arg, /**< this argum const ecma_value_t *argument_list_p, /**< arguments list */ ecma_length_t arguments_number) /**< number of arguments */ { - JERRY_ASSERT (argument_list_p == NULL || arguments_number > 0); - ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); /* 1. */ @@ -1013,10 +1011,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_array_args (comparefn_obj_p, - ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED), - compare_args, - 2), + ecma_op_function_call (comparefn_obj_p, + ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED), + compare_args, + 2), ret_value); if (!ecma_is_value_number (call_value)) @@ -2047,7 +2045,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_array_args (func_object_p, arg2, call_args, 3), ret_value); + ECMA_TRY_CATCH (call_value, ecma_op_function_call (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))) @@ -2148,7 +2146,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_array_args (func_object_p, arg2, call_args, 3), ret_value); + ECMA_TRY_CATCH (call_value, ecma_op_function_call (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))) @@ -2248,7 +2246,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_array_args (func_object_p, arg2, call_args, 3), ret_value); + ECMA_TRY_CATCH (call_value, ecma_op_function_call (func_object_p, arg2, call_args, 3), ret_value); ECMA_FINALIZE (call_value); ECMA_FINALIZE (current_value); @@ -2345,7 +2343,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_array_args (func_object_p, arg2, call_args, 3), ret_value); + ECMA_TRY_CATCH (mapped_value, ecma_op_function_call (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. */ @@ -2463,7 +2461,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_array_args (func_object_p, arg2, call_args, 3), ret_value); + ECMA_TRY_CATCH (call_value, ecma_op_function_call (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))) @@ -2623,10 +2621,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_array_args (func_object_p, - ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED), - call_args, - 4), + ecma_op_function_call (func_object_p, + ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED), + call_args, + 4), ret_value); ecma_free_value (accumulator, true); @@ -2769,10 +2767,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_array_args (func_object_p, - ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED), - call_args, - 4), + ecma_op_function_call (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 9bde7135f..fc14731e5 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-date-prototype.cpp +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-date-prototype.cpp @@ -1213,7 +1213,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); + ret_value = ecma_op_function_call (to_iso_obj_p, this_arg, NULL, 0); } 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 c39133ccd..9dcfc416a 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-function-prototype.cpp +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-function-prototype.cpp @@ -98,7 +98,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); + ret_value = ecma_op_function_call (func_obj_p, arg1, NULL, 0); } else { @@ -125,10 +125,13 @@ ecma_builtin_function_prototype_object_apply (ecma_value_t this_arg, /**< this a const uint32_t length = ecma_number_to_uint32 (length_number); /* 6. */ - ecma_collection_header_t *arg_collection_p = ecma_new_values_collection (NULL, 0, true); + MEM_DEFINE_LOCAL_ARRAY (arguments_list_p, length, ecma_value_t); + uint32_t last_index = 0; /* 7. */ - for (uint32_t index = 0; index < length && ecma_is_completion_value_empty (ret_value); index++) + 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); @@ -136,22 +139,28 @@ 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); - ecma_append_to_values_collection (arg_collection_p, get_value, true); + arguments_list_p[index] = ecma_copy_value (get_value, true); + last_index = index + 1; ECMA_FINALIZE (get_value); ecma_deref_ecma_string (curr_idx_str_p); } - JERRY_ASSERT (arg_collection_p->unit_number == length || !ecma_is_completion_value_empty (ret_value)); - if (ecma_is_completion_value_empty (ret_value)) { + JERRY_ASSERT (last_index == length); ret_value = ecma_op_function_call (func_obj_p, arg1, - arg_collection_p); + arguments_list_p, + length); } - ecma_free_values_collection (arg_collection_p, true); + for (uint32_t index = 0; index < last_index; index++) + { + ecma_free_value (arguments_list_p[index], true); + } + + MEM_FINALIZE_LOCAL_ARRAY (arguments_list_p); ECMA_OP_TO_NUMBER_FINALIZE (length_number); ECMA_FINALIZE (length_value); @@ -187,16 +196,18 @@ ecma_builtin_function_prototype_object_call (ecma_value_t this_arg, /**< this ar if (arguments_number == 0) { + /* Even a 'this' argument is missing. */ return ecma_op_function_call (func_obj_p, ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED), - NULL); + NULL, + 0); } else { - 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)); + return ecma_op_function_call (func_obj_p, + arguments_list_p[0], + 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 ca1f011cf..cb5169c73 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.cpp +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.cpp @@ -158,7 +158,8 @@ 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), + NULL, + 0), 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 fed66c7f1..8e6e49975 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-json.cpp +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-json.cpp @@ -675,10 +675,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_array_args (reviver_p, - ecma_make_object_value (holder_p), - arguments_list, - 2); + ret_value = ecma_op_function_call (reviver_p, + ecma_make_object_value (holder_p), + arguments_list, + 2); } else { @@ -1252,7 +1252,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_array_args (toJSON_obj_p, my_val, call_args, 1), + ecma_op_function_call (toJSON_obj_p, my_val, call_args, 1), ret_value); ecma_free_value (my_val, true); @@ -1274,7 +1274,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_array_args (context_p->replacer_function_p, holder_value, call_args, 2), + ecma_op_function_call (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 cffaef2f3..b9e9f7560 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); + return_value = ecma_op_function_call (to_string_func_obj_p, this_arg, NULL, 0); } 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 3854ee901..b92c13289 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.cpp +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.cpp @@ -844,10 +844,10 @@ ecma_builtin_string_prototype_object_replace_get_string (ecma_builtin_replace_se arguments_list[match_length + 1] = ecma_copy_value (context_p->input_string, true); ECMA_TRY_CATCH (result_value, - ecma_op_function_call_array_args (context_p->replace_function_p, - ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED), - arguments_list, - match_length + 2), + ecma_op_function_call (context_p->replace_function_p, + ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED), + arguments_list, + match_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 f58509e91..994d14d03 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtins.cpp +++ b/jerry-core/ecma/builtin-objects/ecma-builtins.cpp @@ -508,26 +508,13 @@ 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 */ - ecma_collection_header_t *arg_collection_p) /**< arguments collection */ + const ecma_value_t *arguments_list_p, /**< arguments list */ + ecma_length_t arguments_list_len) /**< arguments list length */ { JERRY_ASSERT (ecma_get_object_is_builtin (obj_p)); 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) { ecma_property_t *desc_prop_p = ecma_get_internal_property (obj_p, @@ -598,8 +585,6 @@ ecma_builtin_dispatch_call (ecma_object_t *obj_p, /**< built-in object */ } } - MEM_FINALIZE_LOCAL_ARRAY (arguments_list_p); - JERRY_ASSERT (!ecma_is_completion_value_empty (ret_value)); return ret_value; @@ -612,27 +597,14 @@ 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 */ - ecma_collection_header_t *arg_collection_p) /**< arguments collection */ + const ecma_value_t *arguments_list_p, /**< arguments list */ + ecma_length_t arguments_list_len) /**< arguments list length */ { JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_FUNCTION); JERRY_ASSERT (ecma_get_object_is_builtin (obj_p)); 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); ecma_builtin_id_t builtin_id = (ecma_builtin_id_t) built_in_id_prop_p->u.internal_property.value; @@ -674,8 +646,6 @@ ecma_builtin_dispatch_construct (ecma_object_t *obj_p, /**< built-in object */ } } - MEM_FINALIZE_LOCAL_ARRAY (arguments_list_p); - JERRY_ASSERT (!ecma_is_completion_value_empty (ret_value)); return ret_value; diff --git a/jerry-core/ecma/builtin-objects/ecma-builtins.h b/jerry-core/ecma/builtin-objects/ecma-builtins.h index 989f7a518..b9d827a7b 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtins.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtins.h @@ -39,9 +39,11 @@ extern void ecma_init_builtins (void); extern void ecma_finalize_builtins (void); extern ecma_completion_value_t -ecma_builtin_dispatch_call (ecma_object_t *, ecma_value_t, ecma_collection_header_t *); +ecma_builtin_dispatch_call (ecma_object_t *, ecma_value_t, + const ecma_value_t *, ecma_length_t); extern ecma_completion_value_t -ecma_builtin_dispatch_construct (ecma_object_t *, ecma_collection_header_t *); +ecma_builtin_dispatch_construct (ecma_object_t *, + const ecma_value_t *, ecma_length_t); extern ecma_property_t * ecma_builtin_try_to_instantiate_property (ecma_object_t *, ecma_string_t *); extern void diff --git a/jerry-core/ecma/operations/ecma-function-object.cpp b/jerry-core/ecma/operations/ecma-function-object.cpp index e697553b9..c0a777b7d 100644 --- a/jerry-core/ecma/operations/ecma-function-object.cpp +++ b/jerry-core/ecma/operations/ecma-function-object.cpp @@ -98,49 +98,32 @@ ecma_is_constructor (ecma_value_t value) /**< ecma-value */ * Used by: * - [[Call]] implementation for Function objects. * - [[Construct]] implementation for Function objects. - * - * @return collection of arguments that should be freed - * using ecma_free_values_collection with do_ref_if_object flag set */ -static ecma_collection_header_t * -ecma_function_bind_merge_arg_lists (ecma_object_t *func_obj_p, /**< Function object */ - ecma_collection_header_t *passed_arg_collection_p) /**< passed arguments list */ +static void +ecma_function_bind_merge_arg_lists (ecma_value_t *merged_args_list_p, /**< destination argument list */ + ecma_collection_header_t *bound_arg_list_p, /**< bound argument list */ + const ecma_value_t *arguments_list_p, /**< source arguments list */ + ecma_length_t arguments_list_len) /**< length of source arguments list */ { - ecma_length_t passed_args_number = passed_arg_collection_p != NULL ? passed_arg_collection_p->unit_number : 0; + /* Performance optimization: only the values are copied. This is + * enough, since the original references keep these objects alive. */ - ecma_collection_header_t *merged_arg_collection_p = ecma_new_values_collection (NULL, 0, true); + ecma_collection_iterator_t bound_args_iterator; + ecma_collection_iterator_init (&bound_args_iterator, bound_arg_list_p); - 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); - - if (bound_args_prop_p != NULL) + for (ecma_length_t i = bound_arg_list_p->unit_number; i > 0; i--) { - ecma_collection_header_t *bound_arg_list_p = ECMA_GET_POINTER (ecma_collection_header_t, - bound_args_prop_p->u.internal_property.value); - - ecma_collection_iterator_t bound_args_iterator; - ecma_collection_iterator_init (&bound_args_iterator, bound_arg_list_p); - - 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); - - ecma_append_to_values_collection (merged_arg_collection_p, *bound_args_iterator.current_value_p, true); - } - } - - 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); + bool is_moved = ecma_collection_iterator_next (&bound_args_iterator); JERRY_ASSERT (is_moved); - ecma_append_to_values_collection (merged_arg_collection_p, *passed_args_iterator.current_value_p, true); + *merged_args_list_p++ = *bound_args_iterator.current_value_p; } - return merged_arg_collection_p; + while (arguments_list_len > 0) + { + *merged_args_list_p++ = *arguments_list_p++; + arguments_list_len--; + } } /* ecma_function_bind_merge_arg_lists */ /** @@ -187,18 +170,12 @@ ecma_op_create_function_object (ecma_object_t *scope_p, /**< function's scope */ ecma_property_t *scope_prop_p = ecma_create_internal_property (f, ECMA_INTERNAL_PROPERTY_SCOPE); ECMA_SET_POINTER (scope_prop_p->u.internal_property.value, scope_p); - // 10. - // 11. - // 12. + // 10., 11., 12. ecma_property_t *bytecode_prop_p = ecma_create_internal_property (f, ECMA_INTERNAL_PROPERTY_CODE_BYTECODE); MEM_CP_SET_NON_NULL_POINTER (bytecode_prop_p->u.internal_property.value, bytecode_data_p); ecma_bytecode_ref ((ecma_compiled_code_t *) bytecode_data_p); - // 14. - // 15. - // 16. - // 17. - // 18. + // 14., 15., 16., 17., 18. /* * 'length' and 'prototype' properties are instantiated lazily * @@ -560,130 +537,6 @@ 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); - } - - if (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_FUNCTION - && !ecma_get_object_is_builtin (func_obj_p)) - { - /* Fast call. */ - ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); - - /* Entering Function Code (ECMA-262 v5, 10.4.3) */ - ecma_property_t *scope_prop_p = ecma_get_internal_property (func_obj_p, ECMA_INTERNAL_PROPERTY_SCOPE); - ecma_property_t *bytecode_prop_p = ecma_get_internal_property (func_obj_p, ECMA_INTERNAL_PROPERTY_CODE_BYTECODE); - - ecma_object_t *scope_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, - scope_prop_p->u.internal_property.value); - - // 8. - ecma_value_t this_binding; - bool is_strict; - bool is_no_lex_env; - - const ecma_compiled_code_t *bytecode_data_p; - bytecode_data_p = MEM_CP_GET_POINTER (const ecma_compiled_code_t, - bytecode_prop_p->u.internal_property.value); - - is_strict = (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE) ? true : false; - is_no_lex_env = (bytecode_data_p->status_flags & CBC_CODE_FLAGS_LEXICAL_ENV_NOT_NEEDED) ? true : false; - - // 1. - if (is_strict) - { - this_binding = ecma_copy_value (this_arg_value, true); - } - else if (ecma_is_value_undefined (this_arg_value) - || ecma_is_value_null (this_arg_value)) - { - // 2. - this_binding = ecma_make_object_value (ecma_builtin_get (ECMA_BUILTIN_ID_GLOBAL)); - } - else - { - // 3., 4. - ecma_completion_value_t completion = ecma_op_to_object (this_arg_value); - JERRY_ASSERT (ecma_is_completion_value_normal (completion)); - - this_binding = ecma_get_completion_value_value (completion); - } - - // 5. - ecma_object_t *local_env_p; - if (is_no_lex_env) - { - local_env_p = scope_p; - } - else - { - local_env_p = ecma_create_decl_lex_env (scope_p); - - if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_ARGUMENTS_NEEDED) - { - ecma_op_create_arguments_object_array_args (func_obj_p, - local_env_p, - arguments_list_p, - arguments_list_len, - bytecode_data_p); - } - } - - ecma_completion_value_t completion = vm_run_array_args (bytecode_data_p, - this_binding, - local_env_p, - false, - arguments_list_p, - arguments_list_len); - - if (ecma_is_completion_value_return (completion)) - { - ret_value = ecma_make_normal_completion_value (ecma_get_completion_value_value (completion)); - } - else - { - ret_value = completion; - } - - if (!is_no_lex_env) - { - ecma_deref_object (local_env_p); - } - - ecma_free_value (this_binding, true); - return ret_value; - } - - /* Slow call. */ - - 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) @@ -697,7 +550,8 @@ ecma_op_function_call_array_args (ecma_object_t *func_obj_p, /**< Function objec 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 */ - ecma_collection_header_t *arg_collection_p) /**< arguments list */ + const ecma_value_t *arguments_list_p, /**< arguments list */ + ecma_length_t arguments_list_len) /**< length of arguments list */ { JERRY_ASSERT (func_obj_p != NULL && !ecma_is_lexical_environment (func_obj_p)); @@ -711,7 +565,8 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */ { ret_value = ecma_builtin_dispatch_call (func_obj_p, this_arg_value, - arg_collection_p); + arguments_list_p, + arguments_list_len); } else { @@ -767,7 +622,8 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */ { ecma_op_create_arguments_object (func_obj_p, local_env_p, - arg_collection_p, + arguments_list_p, + arguments_list_len, bytecode_data_p); } } @@ -776,7 +632,8 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */ this_binding, local_env_p, false, - arg_collection_p); + arguments_list_p, + arguments_list_len); if (ecma_is_completion_value_return (completion)) { @@ -799,7 +656,8 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */ { ret_value = ecma_builtin_dispatch_call (func_obj_p, this_arg_value, - arg_collection_p); + arguments_list_p, + arguments_list_len); } else if (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION) { @@ -809,10 +667,16 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */ &handler_p); JERRY_ASSERT (is_retrieved); + ecma_collection_header_t *arg_collection_p = ecma_new_values_collection (arguments_list_p, + arguments_list_len, + true); + ret_value = jerry_dispatch_external_function (func_obj_p, handler_p, this_arg_value, arg_collection_p); + + ecma_free_values_collection (arg_collection_p, true); } else { @@ -830,17 +694,43 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */ target_function_prop_p->u.internal_property.value); /* 4. */ - ecma_collection_header_t *merged_arg_collection_p = ecma_function_bind_merge_arg_lists (func_obj_p, - arg_collection_p); - + ecma_property_t *bound_args_prop_p; ecma_value_t bound_this_value = bound_this_prop_p->u.internal_property.value; + bound_args_prop_p = ecma_find_internal_property (func_obj_p, ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_BOUND_ARGS); - /* 5. */ - ret_value = ecma_op_function_call (target_func_obj_p, - bound_this_value, - merged_arg_collection_p); + if (bound_args_prop_p != NULL) + { + ecma_collection_header_t *bound_arg_list_p; + bound_arg_list_p = ECMA_GET_NON_NULL_POINTER (ecma_collection_header_t, + bound_args_prop_p->u.internal_property.value); - ecma_free_values_collection (merged_arg_collection_p, true); + JERRY_ASSERT (bound_arg_list_p->unit_number > 0); + + ecma_length_t merged_args_list_len = bound_arg_list_p->unit_number + arguments_list_len; + + MEM_DEFINE_LOCAL_ARRAY (merged_args_list_p, merged_args_list_len, ecma_value_t); + + ecma_function_bind_merge_arg_lists (merged_args_list_p, + bound_arg_list_p, + arguments_list_p, + arguments_list_len); + + /* 5. */ + ret_value = ecma_op_function_call (target_func_obj_p, + bound_this_value, + merged_args_list_p, + merged_args_list_len); + + MEM_FINALIZE_LOCAL_ARRAY (merged_args_list_p); + } + else + { + /* 5. */ + ret_value = ecma_op_function_call (target_func_obj_p, + bound_this_value, + arguments_list_p, + arguments_list_len); + } } JERRY_ASSERT (!ecma_is_completion_value_empty (ret_value)); @@ -858,8 +748,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 */ - ecma_collection_header_t *arg_collection_p) /**< arguments - * collection */ + const ecma_value_t *arguments_list_p, /**< arguments list */ + ecma_length_t arguments_list_len) /**< length of arguments list */ { 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); @@ -906,7 +796,8 @@ 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), - arg_collection_p), + arguments_list_p, + arguments_list_len), ret_value); ecma_value_t obj_value; @@ -947,7 +838,8 @@ 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 */ - ecma_collection_header_t *arg_collection_p) /**< arguments collection */ + const ecma_value_t *arguments_list_p, /**< arguments list */ + ecma_length_t arguments_list_len) /**< length of arguments list */ { JERRY_ASSERT (func_obj_p != NULL && !ecma_is_lexical_environment (func_obj_p)); @@ -960,16 +852,22 @@ 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, arg_collection_p); + ret_value = ecma_builtin_dispatch_construct (func_obj_p, + arguments_list_p, + arguments_list_len); } else { - ret_value = ecma_op_function_construct_simple_or_external (func_obj_p, arg_collection_p); + ret_value = ecma_op_function_construct_simple_or_external (func_obj_p, + arguments_list_p, + arguments_list_len); } } 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, arg_collection_p); + ret_value = ecma_op_function_construct_simple_or_external (func_obj_p, + arguments_list_p, + arguments_list_len); } else { @@ -991,14 +889,41 @@ ecma_op_function_construct (ecma_object_t *func_obj_p, /**< Function object */ else { /* 4. */ - ecma_collection_header_t *merged_arg_collection_p = ecma_function_bind_merge_arg_lists (func_obj_p, - arg_collection_p); + 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); - /* 5. */ - ret_value = ecma_op_function_construct (target_func_obj_p, - merged_arg_collection_p); + if (bound_args_prop_p != NULL) + { + ecma_collection_header_t *bound_arg_list_p; + bound_arg_list_p = ECMA_GET_NON_NULL_POINTER (ecma_collection_header_t, + bound_args_prop_p->u.internal_property.value); - ecma_free_values_collection (merged_arg_collection_p, true); + + JERRY_ASSERT (bound_arg_list_p->unit_number > 0); + + ecma_length_t merged_args_list_len = bound_arg_list_p->unit_number + arguments_list_len; + + MEM_DEFINE_LOCAL_ARRAY (merged_args_list_p, merged_args_list_len, ecma_value_t); + + ecma_function_bind_merge_arg_lists (merged_args_list_p, + bound_arg_list_p, + arguments_list_p, + arguments_list_len); + + /* 5. */ + ret_value = ecma_op_function_construct (target_func_obj_p, + merged_args_list_p, + merged_args_list_len); + + MEM_FINALIZE_LOCAL_ARRAY (merged_args_list_p); + } + else + { + /* 5. */ + ret_value = ecma_op_function_construct (target_func_obj_p, + arguments_list_p, + arguments_list_len); + } } } diff --git a/jerry-core/ecma/operations/ecma-function-object.h b/jerry-core/ecma/operations/ecma-function-object.h index 3e84142c5..3fb2e6c19 100644 --- a/jerry-core/ecma/operations/ecma-function-object.h +++ b/jerry-core/ecma/operations/ecma-function-object.h @@ -41,18 +41,14 @@ extern ecma_object_t * ecma_op_create_external_function_object (ecma_external_pointer_t); extern ecma_completion_value_t -ecma_op_function_call (ecma_object_t *, ecma_value_t, ecma_collection_header_t *); - +ecma_op_function_call (ecma_object_t *, ecma_value_t, + const ecma_value_t *, ecma_length_t); extern ecma_property_t * ecma_op_function_object_get_own_property (ecma_object_t *, ecma_string_t *); extern ecma_completion_value_t -ecma_op_function_call_array_args (ecma_object_t *, ecma_value_t, const ecma_value_t *, ecma_length_t); - - -extern ecma_completion_value_t -ecma_op_function_construct (ecma_object_t *, ecma_collection_header_t *); +ecma_op_function_construct (ecma_object_t *, const ecma_value_t *, ecma_length_t); extern ecma_completion_value_t ecma_op_function_has_instance (ecma_object_t *, ecma_value_t); diff --git a/jerry-core/ecma/operations/ecma-get-put-value.cpp b/jerry-core/ecma/operations/ecma-get-put-value.cpp index b0f8f9ea0..8d4a5afa1 100644 --- a/jerry-core/ecma/operations/ecma-get-put-value.cpp +++ b/jerry-core/ecma/operations/ecma-get-put-value.cpp @@ -144,9 +144,7 @@ ecma_op_get_value_object_base (ecma_reference_t ref) /**< ECMA-reference */ else { // 7. - ret_value = ecma_op_function_call (obj_p, - base, - NULL); + ret_value = ecma_op_function_call (obj_p, base, NULL, 0); } } @@ -323,7 +321,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_array_args (setter_p, base, &value, 1), + ecma_op_function_call (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 c0a3db5fe..a0a3198fc 100644 --- a/jerry-core/ecma/operations/ecma-objects-arguments.cpp +++ b/jerry-core/ecma/operations/ecma-objects-arguments.cpp @@ -36,18 +36,46 @@ #include "jrt.h" /** - * Arguments object creation common part. + * Arguments object creation operation. * * See also: ECMA-262 v5, 10.6 */ -static void -ecma_op_create_arguments_object_common (ecma_object_t *obj_p, /**< 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_length_t arguments_number, /**< length of arguments list */ - const ecma_compiled_code_t *bytecode_data_p) /**< bytecode data */ +void +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 */ + const ecma_value_t *arguments_list_p, /**< arguments list */ + ecma_length_t arguments_number, /**< length of arguments list */ + const ecma_compiled_code_t *bytecode_data_p) /**< byte code */ { + // 2., 3., 6. + ecma_object_t *prototype_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE); + + ecma_object_t *obj_p = ecma_create_object (prototype_p, true, ECMA_OBJECT_TYPE_GENERAL); + + ecma_deref_object (prototype_p); + + // 11.a, 11.b + for (ecma_length_t indx = 0; + indx < arguments_number; + indx++) + { + ecma_completion_value_t completion; + ecma_string_t *indx_string_p = ecma_new_ecma_string_from_uint32 (indx); + + completion = ecma_builtin_helper_def_prop (obj_p, + indx_string_p, + arguments_list_p[indx], + true, /* Writable */ + true, /* Enumerable */ + true, /* Configurable */ + false); /* Failure handling */ + + JERRY_ASSERT (ecma_is_completion_value_normal_true (completion)); + + ecma_deref_ecma_string (indx_string_p); + } + bool is_strict = (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE) != 0; // 1. @@ -239,112 +267,8 @@ ecma_op_create_arguments_object_common (ecma_object_t *obj_p, /**< arguments obj ecma_deref_ecma_string (arguments_string_p); ecma_deref_object (obj_p); -} /* ecma_op_create_arguments_object_common */ - -/** - * Arguments object creation operation. - * - * See also: ECMA-262 v5, 10.6 - * - * @return pointer to newly created Arguments object - */ -void -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 *arg_collection_p, /**< arguments collection */ - const ecma_compiled_code_t *bytecode_data_p) /**< byte code */ -{ - const ecma_length_t arguments_number = arg_collection_p != NULL ? arg_collection_p->unit_number : 0; - - // 2., 3., 6. - ecma_object_t *prototype_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE); - - ecma_object_t *obj_p = ecma_create_object (prototype_p, true, ECMA_OBJECT_TYPE_GENERAL); - - ecma_deref_object (prototype_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_number; - indx++) - { - ecma_completion_value_t completion; - bool is_moved = ecma_collection_iterator_next (&args_iterator); - JERRY_ASSERT (is_moved); - - ecma_string_t *indx_string_p = ecma_new_ecma_string_from_uint32 (indx); - completion = ecma_builtin_helper_def_prop (obj_p, - indx_string_p, - *args_iterator.current_value_p, - true, /* Writable */ - true, /* Enumerable */ - true, /* Configurable */ - false); /* Failure handling */ - - JERRY_ASSERT (ecma_is_completion_value_normal_true (completion)); - - ecma_deref_ecma_string (indx_string_p); - } - - ecma_op_create_arguments_object_common (obj_p, - func_obj_p, - lex_env_p, - arguments_number, - bytecode_data_p); } /* ecma_op_create_arguments_object */ -/** - * Arguments object creation operation. - * - * See also: ECMA-262 v5, 10.6 - */ -void -ecma_op_create_arguments_object_array_args (ecma_object_t *func_obj_p, /**< callee function */ - ecma_object_t *lex_env_p, /**< lexical environment the Arguments - object is created for */ - const ecma_value_t *arguments_list_p, /**< arguments list */ - ecma_length_t arguments_number, /**< length of arguments list */ - const ecma_compiled_code_t *bytecode_data_p) /**< byte code */ -{ - // 2., 3., 6. - ecma_object_t *prototype_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE); - - ecma_object_t *obj_p = ecma_create_object (prototype_p, true, ECMA_OBJECT_TYPE_GENERAL); - - ecma_deref_object (prototype_p); - - // 11.a, 11.b - for (ecma_length_t indx = 0; - indx < arguments_number; - indx++) - { - ecma_completion_value_t completion; - ecma_string_t *indx_string_p = ecma_new_ecma_string_from_uint32 (indx); - - completion = ecma_builtin_helper_def_prop (obj_p, - indx_string_p, - arguments_list_p[indx], - true, /* Writable */ - true, /* Enumerable */ - true, /* Configurable */ - false); /* Failure handling */ - - JERRY_ASSERT (ecma_is_completion_value_normal_true (completion)); - - ecma_deref_ecma_string (indx_string_p); - } - - ecma_op_create_arguments_object_common (obj_p, - func_obj_p, - lex_env_p, - arguments_number, - bytecode_data_p); -} /* ecma_op_create_arguments_object_array_args */ - /** * Get value of function's argument mapped to index of Arguments object. * diff --git a/jerry-core/ecma/operations/ecma-objects-arguments.h b/jerry-core/ecma/operations/ecma-objects-arguments.h index e9cf08e51..74d626428 100644 --- a/jerry-core/ecma/operations/ecma-objects-arguments.h +++ b/jerry-core/ecma/operations/ecma-objects-arguments.h @@ -20,12 +20,8 @@ #include "ecma-helpers.h" extern void -ecma_op_create_arguments_object (ecma_object_t *, ecma_object_t *, - ecma_collection_header_t *, const ecma_compiled_code_t *); - -extern void -ecma_op_create_arguments_object_array_args (ecma_object_t *, ecma_object_t *, const ecma_value_t *, - ecma_length_t, const ecma_compiled_code_t *); +ecma_op_create_arguments_object (ecma_object_t *, ecma_object_t *, const ecma_value_t *, + ecma_length_t, const ecma_compiled_code_t *); extern ecma_completion_value_t ecma_op_arguments_object_get (ecma_object_t *, ecma_string_t *); diff --git a/jerry-core/ecma/operations/ecma-objects-general.cpp b/jerry-core/ecma/operations/ecma-objects-general.cpp index 8b9c20a7f..5f5d4f3db 100644 --- a/jerry-core/ecma/operations/ecma-objects-general.cpp +++ b/jerry-core/ecma/operations/ecma-objects-general.cpp @@ -175,7 +175,8 @@ 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); + NULL, + 0); } } @@ -314,10 +315,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_array_args (setter_p, - ecma_make_object_value (obj_p), - &value, - 1), + ecma_op_function_call (setter_p, + ecma_make_object_value (obj_p), + &value, + 1), ret_value); ret_value = ecma_make_simple_completion_value (ECMA_SIMPLE_VALUE_TRUE); @@ -554,7 +555,8 @@ 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); + NULL, + 0); } ecma_free_completion_value (function_value_get_completion); diff --git a/jerry-core/jerry.cpp b/jerry-core/jerry.cpp index 55c7fc6c0..f3192d29e 100644 --- a/jerry-core/jerry.cpp +++ b/jerry-core/jerry.cpp @@ -1406,16 +1406,11 @@ jerry_api_invoke_function (bool is_invoke_as_constructor, /**< true - invoke fun bool is_successful = true; - ecma_collection_header_t *arg_collection_p = ecma_new_values_collection (NULL, 0, true); + MEM_DEFINE_LOCAL_ARRAY (arguments_list_p, args_count, ecma_value_t); for (uint32_t i = 0; i < args_count; ++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); + jerry_api_convert_api_value_to_ecma_value (arguments_list_p + i, args_p + i); } ecma_completion_value_t call_completion; @@ -1425,7 +1420,9 @@ 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_collection_p); + call_completion = ecma_op_function_construct (function_object_p, + arguments_list_p, + args_count); } else { @@ -1444,11 +1441,10 @@ 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_collection_p); + arguments_list_p, + args_count); } - ecma_free_values_collection (arg_collection_p, true); - if (!ecma_is_completion_value_normal (call_completion)) { /* unhandled exception during the function call */ @@ -1465,6 +1461,13 @@ 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 (arguments_list_p[i], true); + } + + MEM_FINALIZE_LOCAL_ARRAY (arguments_list_p); + return is_successful; } /* jerry_api_invoke_function */ diff --git a/jerry-core/vm/opcodes.cpp b/jerry-core/vm/opcodes.cpp index 46de24088..96308f52b 100644 --- a/jerry-core/vm/opcodes.cpp +++ b/jerry-core/vm/opcodes.cpp @@ -58,10 +58,10 @@ opfunc_call_n (ecma_value_t this_value, /**< this object value */ ecma_object_t *func_obj_p = ecma_get_object_from_value (func_value); - ret_value = ecma_op_function_call_array_args (func_obj_p, - this_value, - arguments_list_p, - arguments_list_len); + ret_value = ecma_op_function_call (func_obj_p, + this_value, + arguments_list_p, + arguments_list_len); return ret_value; } /* opfunc_call_n */ @@ -76,16 +76,10 @@ opfunc_call_n (ecma_value_t this_value, /**< this object value */ */ ecma_completion_value_t opfunc_construct_n (ecma_value_t constructor_value, /**< constructor object value */ - uint8_t args_num, /**< number of arguments */ - ecma_value_t *stack_p) /**< stack pointer */ + const ecma_value_t *arguments_list_p, /**< stack pointer */ + ecma_length_t arguments_list_len) /**< number of arguments */ { ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); - ecma_collection_header_t *arg_collection_p = ecma_new_values_collection (NULL, 0, true); - - for (int i = 0; i < args_num; i++) - { - ecma_append_to_values_collection (arg_collection_p, stack_p[i], true); - } if (!ecma_is_constructor (constructor_value)) { @@ -97,7 +91,8 @@ opfunc_construct_n (ecma_value_t constructor_value, /**< constructor object valu ECMA_TRY_CATCH (construction_ret_value, ecma_op_function_construct (constructor_obj_p, - arg_collection_p), + arguments_list_p, + arguments_list_len), ret_value); ret_value = ecma_make_normal_completion_value (ecma_copy_value (construction_ret_value, true)); @@ -105,8 +100,6 @@ opfunc_construct_n (ecma_value_t constructor_value, /**< constructor object valu ECMA_FINALIZE (construction_ret_value); } - ecma_free_values_collection (arg_collection_p, true); - return ret_value; } /* opfunc_construct_n */ diff --git a/jerry-core/vm/opcodes.h b/jerry-core/vm/opcodes.h index cc7707a9c..648789ba1 100644 --- a/jerry-core/vm/opcodes.h +++ b/jerry-core/vm/opcodes.h @@ -57,13 +57,12 @@ ecma_completion_value_t vm_var_decl (vm_frame_ctx_t *, ecma_string_t *); ecma_completion_value_t -opfunc_call_n (ecma_value_t, - ecma_value_t, - const ecma_value_t *, - ecma_length_t); +opfunc_call_n (ecma_value_t, ecma_value_t, + const ecma_value_t *, ecma_length_t); ecma_completion_value_t -opfunc_construct_n (ecma_value_t, uint8_t, ecma_value_t *); +opfunc_construct_n (ecma_value_t, + const ecma_value_t *, ecma_length_t); ecma_completion_value_t opfunc_equal_value (ecma_value_t, ecma_value_t); diff --git a/jerry-core/vm/vm.cpp b/jerry-core/vm/vm.cpp index 2420aea63..3ac64c4e2 100644 --- a/jerry-core/vm/vm.cpp +++ b/jerry-core/vm/vm.cpp @@ -191,7 +191,8 @@ vm_run_global (void) ecma_make_object_value (glob_obj_p), lex_env_p, false, - NULL); + NULL, + 0); if (ecma_is_completion_value_return (completion)) { @@ -251,7 +252,8 @@ vm_run_eval (ecma_compiled_code_t *bytecode_data_p, /**< byte-code data */ this_binding, lex_env_p, true, - NULL); + NULL, + 0); if (ecma_is_completion_value_return (completion)) { @@ -1302,8 +1304,8 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ stack_top_p -= right_value; last_completion_value = opfunc_construct_n (stack_top_p[-1], - (uint8_t) right_value, - stack_top_p); + stack_top_p, + right_value); /* Free registers. */ for (uint32_t i = 0; i < right_value; i++) @@ -2407,75 +2409,8 @@ vm_run (const ecma_compiled_code_t *bytecode_header_p, /**< byte-code data heade ecma_value_t this_binding_value, /**< value of 'ThisBinding' */ ecma_object_t *lex_env_p, /**< lexical environment to use */ bool is_eval_code, /**< is the code is eval code (ECMA-262 v5, 10.1) */ - ecma_collection_header_t *arg_collection_p) /**< arguments list */ -{ - lit_cpointer_t *literal_p; - vm_frame_ctx_t frame_ctx; - uint32_t call_stack_size; - - if (bytecode_header_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS) - { - cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) bytecode_header_p; - uint8_t *byte_p = ((uint8_t *) bytecode_header_p + sizeof (cbc_uint16_arguments_t)); - - literal_p = (lit_cpointer_t *) byte_p; - frame_ctx.literal_start_p = literal_p; - literal_p += args_p->literal_end; - call_stack_size = (uint32_t) (args_p->register_end + args_p->stack_limit); - } - else - { - cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) bytecode_header_p; - uint8_t *byte_p = ((uint8_t *) bytecode_header_p + sizeof (cbc_uint8_arguments_t)); - - literal_p = (lit_cpointer_t *) byte_p; - frame_ctx.literal_start_p = literal_p; - literal_p += args_p->literal_end; - call_stack_size = (uint32_t) (args_p->register_end + args_p->stack_limit); - } - - frame_ctx.bytecode_header_p = bytecode_header_p; - frame_ctx.byte_code_p = (uint8_t *) literal_p; - frame_ctx.byte_code_start_p = (uint8_t *) literal_p; - frame_ctx.lex_env_p = lex_env_p; - frame_ctx.this_binding = this_binding_value; - frame_ctx.context_depth = 0; - frame_ctx.is_eval_code = is_eval_code; - - ecma_length_t arg_list_len = 0; - - if (arg_collection_p == NULL) - { - arg_list_len = 1; - } - - if (call_stack_size <= INLINE_STACK_SIZE) - { - return vm_run_with_inline_stack (&frame_ctx, - arg_collection_p, - arg_list_len); - } - else - { - return vm_run_with_alloca (&frame_ctx, - arg_collection_p, - arg_list_len, - call_stack_size); - } -} /* vm_run */ - -/** - * Run the code. - * - * @return completion value - */ -ecma_completion_value_t -vm_run_array_args (const ecma_compiled_code_t *bytecode_header_p, /**< byte-code data header */ - ecma_value_t this_binding_value, /**< value of 'ThisBinding' */ - ecma_object_t *lex_env_p, /**< lexical environment to use */ - bool is_eval_code, /**< is the code is eval code (ECMA-262 v5, 10.1) */ - const ecma_value_t *arg_list_p, /**< arguments list */ - ecma_length_t arg_list_len) /**< length of arguments list */ + const ecma_value_t *arg_list_p, /**< arguments list */ + ecma_length_t arg_list_len) /**< length of arguments list */ { lit_cpointer_t *literal_p; vm_frame_ctx_t frame_ctx; @@ -2525,7 +2460,7 @@ vm_run_array_args (const ecma_compiled_code_t *bytecode_header_p, /**< byte-code arg_list_len, call_stack_size); } -} /* vm_run_array_args */ +} /* vm_run */ /** * Check whether currently executed code is strict mode code diff --git a/jerry-core/vm/vm.h b/jerry-core/vm/vm.h index dcaa4237e..6541a9d6a 100644 --- a/jerry-core/vm/vm.h +++ b/jerry-core/vm/vm.h @@ -190,18 +190,13 @@ extern jerry_completion_code_t vm_run_global (void); extern ecma_completion_value_t vm_run_eval (ecma_compiled_code_t *, bool); extern ecma_completion_value_t vm_loop (vm_frame_ctx_t *); + extern ecma_completion_value_t vm_run (const ecma_compiled_code_t *, ecma_value_t, ecma_object_t *, bool, - ecma_collection_header_t *); - -extern ecma_completion_value_t vm_run_array_args (const ecma_compiled_code_t *, - ecma_value_t, - ecma_object_t *, - bool, - const ecma_value_t *, - ecma_length_t); + const ecma_value_t *, + ecma_length_t); extern bool vm_is_strict_mode (void); extern bool vm_is_direct_eval_form_call (void);