@@ -55,6 +55,86 @@ ecma_builtin_function_dispatch_call (const ecma_value_t *arguments_list_p, /**<
5555 return ecma_builtin_function_dispatch_construct (arguments_list_p, arguments_list_len);
5656} /* ecma_builtin_function_dispatch_call */
5757
58+ /* *
59+ * Helper method to count and convert the arguments for the Function constructor call.
60+ *
61+ * Performs the operation described in ECMA 262 v5.1 15.3.2.1 steps 5.a-d
62+ *
63+ *
64+ * @return completion value - concatenated arguments as a string.
65+ * Returned value must be freed with ecma_free_completion_value.
66+ */
67+ static ecma_completion_value_t
68+ ecma_builtin_function_helper_get_arguments (const ecma_value_t *arguments_list_p, /* * < arguments list */
69+ ecma_length_t arguments_list_len, /* * < number of arguments */
70+ ecma_length_t *out_total_number_of_args_p) /* * < out: number of
71+ * arguments found */
72+ {
73+ JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL );
74+ JERRY_ASSERT (out_total_number_of_args_p != NULL );
75+
76+ ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
77+
78+ /* We are only processing the function arguments skipping the function body */
79+ ecma_length_t number_of_function_args = (arguments_list_len == 0 ? 0 : arguments_list_len - 1 );
80+ ecma_string_t *arguments_str_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY);
81+
82+ ecma_string_t *separator_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_COMMA_CHAR);
83+
84+ for (ecma_length_t idx = 0 ;
85+ idx < number_of_function_args && ecma_is_completion_value_empty (ret_value);
86+ idx++)
87+ {
88+ ECMA_TRY_CATCH (str_arg_value,
89+ ecma_op_to_string (arguments_list_p[idx]),
90+ ret_value);
91+
92+ ecma_string_t *str_p = ecma_get_string_from_value (str_arg_value);
93+
94+ lit_utf8_size_t str_size = ecma_string_get_size (str_p);
95+ MEM_DEFINE_LOCAL_ARRAY (start_p, str_size, lit_utf8_byte_t );
96+
97+ ecma_string_to_utf8_string (str_p, start_p, (ssize_t ) str_size);
98+ lit_utf8_iterator_t iter = lit_utf8_iterator_create (start_p, str_size);
99+
100+ while (!lit_utf8_iterator_is_eos (&iter))
101+ {
102+ ecma_char_t current_char = lit_utf8_iterator_read_next (&iter);
103+
104+ if (current_char == ' ,' )
105+ {
106+ (*out_total_number_of_args_p)++;
107+ }
108+ }
109+
110+ MEM_FINALIZE_LOCAL_ARRAY (start_p);
111+
112+ ecma_string_t *concated_str_p = ecma_concat_ecma_strings (arguments_str_p, str_p);
113+ ecma_deref_ecma_string (arguments_str_p);
114+ arguments_str_p = concated_str_p;
115+
116+ if (idx < number_of_function_args - 1 )
117+ {
118+ ecma_string_t *concated_str_p = ecma_concat_ecma_strings (arguments_str_p, separator_string_p);
119+ ecma_deref_ecma_string (arguments_str_p);
120+ arguments_str_p = concated_str_p;
121+ }
122+
123+ (*out_total_number_of_args_p)++;
124+
125+ ECMA_FINALIZE (str_arg_value);
126+ }
127+
128+ ecma_deref_ecma_string (separator_string_p);
129+
130+ if (ecma_is_completion_value_empty (ret_value))
131+ {
132+ ret_value = ecma_make_normal_completion_value (ecma_make_string_value (arguments_str_p));
133+ }
134+
135+ return ret_value;
136+ } /* ecma_builtin_function_helper_get_arguments */
137+
58138/* *
59139 * Handle calling [[Construct]] of built-in Function object
60140 *
@@ -71,9 +151,19 @@ ecma_builtin_function_dispatch_construct (const ecma_value_t *arguments_list_p,
71151
72152 ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
73153
154+ ecma_length_t total_number_of_function_args = 0 ;
155+
156+ ECMA_TRY_CATCH (arguments_value,
157+ ecma_builtin_function_helper_get_arguments (arguments_list_p,
158+ arguments_list_len,
159+ &total_number_of_function_args),
160+ ret_value);
161+
162+ ecma_string_t *arguments_str_p = ecma_get_string_from_value (arguments_value);
163+
74164 /* Last string, if any, is the function's body, and the rest, if any - are the function's parameter names */
75165 MEM_DEFINE_LOCAL_ARRAY (string_params_p,
76- arguments_list_len == 0 ? 1 : arguments_list_len ,
166+ arguments_list_len == 0 ? 1 : total_number_of_function_args + 1 ,
77167 ecma_string_t *);
78168 uint32_t params_count;
79169
@@ -89,22 +179,52 @@ ecma_builtin_function_dispatch_construct (const ecma_value_t *arguments_list_p,
89179 else
90180 {
91181 /* 4., 5., 6. */
92- strings_buffer_size = 0 ;
93-
94182 params_count = 0 ;
95- while (params_count < arguments_list_len
96- && ecma_is_completion_value_empty (ret_value))
183+
184+ lit_utf8_size_t str_size = ecma_string_get_size (arguments_str_p);
185+ strings_buffer_size = str_size;
186+
187+ MEM_DEFINE_LOCAL_ARRAY (start_p, str_size, lit_utf8_byte_t );
188+
189+ ecma_string_to_utf8_string (arguments_str_p, start_p, (ssize_t ) str_size);
190+ lit_utf8_iterator_t iter = lit_utf8_iterator_create (start_p, str_size);
191+ ecma_length_t last_separator = lit_utf8_iterator_get_index (&iter);
192+ ecma_length_t end_position;
193+
194+ while (!lit_utf8_iterator_is_eos (&iter))
97195 {
98- ECMA_TRY_CATCH (str_arg_value,
99- ecma_op_to_string (arguments_list_p[params_count]),
100- ret_value);
196+ ecma_char_t current_char = lit_utf8_iterator_read_next (&iter);
197+
198+ if (current_char == ' ,' )
199+ {
200+ lit_utf8_iterator_decr (&iter);
201+ end_position = lit_utf8_iterator_get_index (&iter);
202+
203+ string_params_p[params_count] = ecma_string_substr (arguments_str_p, last_separator, end_position);
101204
102- string_params_p[params_count] = ecma_copy_or_ref_ecma_string (ecma_get_string_from_value (str_arg_value));
103- strings_buffer_size += ecma_string_get_size (string_params_p[params_count]);
104- params_count++;
205+ lit_utf8_iterator_incr (&iter);
206+ last_separator = lit_utf8_iterator_get_index (&iter);
105207
106- ECMA_FINALIZE (str_arg_value);
208+ params_count++;
209+ }
107210 }
211+
212+ end_position = lit_utf8_string_length (start_p, str_size);
213+ string_params_p[params_count] = ecma_string_substr (arguments_str_p, last_separator, end_position);
214+ params_count++;
215+
216+ MEM_FINALIZE_LOCAL_ARRAY (start_p);
217+
218+ ECMA_TRY_CATCH (str_arg_value,
219+ ecma_op_to_string (arguments_list_p[arguments_list_len - 1 ]),
220+ ret_value);
221+
222+ ecma_string_t *str_p = ecma_get_string_from_value (str_arg_value);
223+ string_params_p[params_count] = ecma_copy_or_ref_ecma_string (str_p);
224+ strings_buffer_size += ecma_string_get_size (str_p);
225+ params_count++;
226+
227+ ECMA_FINALIZE (str_arg_value);
108228 }
109229
110230 if (ecma_is_completion_value_empty (ret_value))
@@ -197,6 +317,8 @@ ecma_builtin_function_dispatch_construct (const ecma_value_t *arguments_list_p,
197317
198318 MEM_FINALIZE_LOCAL_ARRAY (string_params_p);
199319
320+ ECMA_FINALIZE (arguments_value);
321+
200322 return ret_value;
201323} /* ecma_builtin_function_dispatch_construct */
202324
0 commit comments