diff --git a/jerry-core/ecma/operations/ecma-function-object.cpp b/jerry-core/ecma/operations/ecma-function-object.cpp index 5f491672f..be807c991 100644 --- a/jerry-core/ecma/operations/ecma-function-object.cpp +++ b/jerry-core/ecma/operations/ecma-function-object.cpp @@ -190,6 +190,16 @@ ecma_op_create_function_object (ecma_string_t* formal_parameter_list_p[], /**< f ECMA_INTERNAL_PROPERTY_FORMAL_PARAMETERS); if (formal_parameters_number != 0) { + /* + * Reverse formal parameter list + */ + for (ecma_length_t i = 0; i < formal_parameters_number / 2; i++) + { + ecma_string_t *tmp_p = formal_parameter_list_p[i]; + formal_parameter_list_p[i] = formal_parameter_list_p[formal_parameters_number - 1u - i]; + formal_parameter_list_p[formal_parameters_number - 1u - i] = tmp_p; + } + ecma_collection_header_t *formal_parameters_collection_p = ecma_new_strings_collection (formal_parameter_list_p, formal_parameters_number); ECMA_SET_POINTER (formal_parameters_prop_p->u.internal_property.value, formal_parameters_collection_p); @@ -395,12 +405,20 @@ ecma_function_call_setup_args_variables (ecma_object_t *func_obj_p, /**< Functio ecma_collection_iterator_t formal_params_iterator; ecma_collection_iterator_init (&formal_params_iterator, formal_parameters_p); - for (size_t n = 0; - n < formal_parameters_count; - n++) + /* + * Formal parameter list is stored in reversed order + * + * Although, specification defines ascending order of formal parameters list enumeration, + * implementation enumerates the parameters in descending order. + * + * In the case, redundant SetMutableBinding invocation could be avoided. + */ + for (ssize_t n = (ssize_t) formal_parameters_count - 1; + n >= 0; + n--) { ecma_value_t v; - if (n >= arguments_list_len) + if (n >= (ssize_t) arguments_list_len) { v = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED); } diff --git a/jerry-core/ecma/operations/ecma-objects-arguments.cpp b/jerry-core/ecma/operations/ecma-objects-arguments.cpp index 5886499f9..f7a8a5a53 100644 --- a/jerry-core/ecma/operations/ecma-objects-arguments.cpp +++ b/jerry-core/ecma/operations/ecma-objects-arguments.cpp @@ -147,7 +147,12 @@ ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function JERRY_ASSERT (param_index < formal_params_number); JERRY_ASSERT (ecma_is_value_string (*formal_params_iterator.current_value_p)); - formal_params[param_index] = ecma_get_string_from_value (*formal_params_iterator.current_value_p); + ecma_string_t *param_name_p = ecma_get_string_from_value (*formal_params_iterator.current_value_p); + + /* + * Formal parameter list is stored in reversed order + */ + formal_params[formal_params_number - 1u - param_index] = param_name_p; } JERRY_ASSERT (param_index == formal_params_number); diff --git a/tests/jerry/function-args.js b/tests/jerry/function-args.js index e69bcb060..8bd72e453 100644 --- a/tests/jerry/function-args.js +++ b/tests/jerry/function-args.js @@ -45,6 +45,13 @@ for(i = 11; i <= 20; i++) f1(i); } +function g (p, p) { + assert (p === arguments[1]); + assert (p === 'second'); +} + +g ('first', 'second'); + try { f1 ({}); f1 (undefined_variable);