@@ -76,6 +76,149 @@ ecma_builtin_array_prototype_helper_set_length (ecma_object_t *object, /**< obje
7676 return ret_value;
7777} /* ecma_builtin_array_prototype_helper_set_length */
7878
79+ /* *
80+ * The Array.prototype object's 'concat' routine
81+ *
82+ * See also:
83+ * ECMA-262 v5, 15.4.4.4
84+ *
85+ * @return completion value
86+ * Returned value must be freed with ecma_free_completion_value.
87+ */
88+ static ecma_completion_value_t
89+ ecma_builtin_array_prototype_object_concat (ecma_value_t this_arg, /* *< this argument */
90+ const ecma_value_t args[], /* *< arguments list */
91+ ecma_length_t args_number) /* *< number of arguments */
92+ {
93+ ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
94+ /* 1. */
95+ ECMA_TRY_CATCH (obj_this,
96+ ecma_op_to_object (this_arg),
97+ ret_value);
98+
99+ ecma_object_t *obj_p = ecma_get_object_from_value (obj_this);
100+ ecma_string_t *magic_string_length_p = ecma_get_magic_string (ECMA_MAGIC_STRING_LENGTH);
101+
102+ ECMA_TRY_CATCH (len_value,
103+ ecma_op_object_get (obj_p, magic_string_length_p),
104+ ret_value);
105+
106+ ECMA_OP_TO_NUMBER_TRY_CATCH (len_number, len_value, ret_value);
107+
108+ uint32_t len = ecma_number_to_uint32 (len_number);
109+
110+ uint32_t new_array_index = 0 ;
111+
112+ /* 2. */
113+ ecma_completion_value_t new_array = ecma_op_create_array_object (0 , 0 , false );
114+ ecma_object_t *new_array_p = ecma_get_object_from_completion_value (new_array);
115+
116+
117+ for (uint32_t index = 0 ;
118+ index < len && ecma_is_completion_value_empty (ret_value);
119+ index++, new_array_index++)
120+ {
121+ ecma_string_t *index_string_p = ecma_new_ecma_string_from_uint32 (index);
122+ ECMA_TRY_CATCH (get_value, ecma_op_object_get (obj_p, index_string_p), ret_value);
123+
124+ /* Using [[Put]] is equvalent to [[DefineOwnProperty]] in this case, so we use it for simplicity. */
125+ ecma_completion_value_t put_comp = ecma_op_object_put (new_array_p,
126+ index_string_p,
127+ get_value,
128+ false );
129+ JERRY_ASSERT (ecma_is_completion_value_normal (put_comp));
130+ ecma_free_completion_value (put_comp);
131+
132+ ECMA_FINALIZE (get_value);
133+ ecma_deref_ecma_string (index_string_p);
134+ }
135+
136+ for (uint32_t arg_index = 0 ;
137+ arg_index < args_number && ecma_is_completion_value_empty (ret_value);
138+ arg_index++)
139+ {
140+ /* 5.b */
141+ if (ecma_is_value_object (args[arg_index]) &&
142+ (ecma_get_object_type (ecma_get_object_from_value (args[arg_index])) == ECMA_OBJECT_TYPE_ARRAY))
143+ {
144+ /* 5.b.ii */
145+ ECMA_TRY_CATCH (arg_len_value,
146+ ecma_op_object_get (ecma_get_object_from_value (args[arg_index]),
147+ magic_string_length_p),
148+ ret_value);
149+ ECMA_OP_TO_NUMBER_TRY_CATCH (arg_len_number, len_value, ret_value);
150+
151+ uint32_t arg_len = ecma_number_to_uint32 (arg_len_number);
152+
153+ for (uint32_t array_index = 0 ;
154+ array_index < arg_len && ecma_is_completion_value_empty (ret_value);
155+ array_index++, new_array_index++)
156+ {
157+ ecma_string_t *array_index_string_p = ecma_new_ecma_string_from_uint32 (array_index);
158+
159+ /* 5.b.iii.2 */
160+ if (ecma_op_object_get_property (ecma_get_object_from_value (args[arg_index]),
161+ array_index_string_p) != NULL )
162+ {
163+ ecma_string_t *new_array_index_string_p = ecma_new_ecma_string_from_uint32 (new_array_index);
164+
165+ ECMA_TRY_CATCH (get_value,
166+ ecma_op_object_get (ecma_get_object_from_value (args[arg_index]),
167+ array_index_string_p),
168+ ret_value);
169+
170+ /* Using [[Put]] is equvalent to [[DefineOwnProperty]] in this case, so we use it for simplicity. */
171+ ecma_completion_value_t put_comp = ecma_op_object_put (new_array_p,
172+ new_array_index_string_p,
173+ get_value,
174+ false );
175+ JERRY_ASSERT (ecma_is_completion_value_normal (put_comp));
176+ ecma_free_completion_value (put_comp);
177+
178+ ECMA_FINALIZE (get_value);
179+ ecma_deref_ecma_string (new_array_index_string_p);
180+ }
181+
182+ ecma_deref_ecma_string (array_index_string_p);
183+ }
184+
185+ ECMA_OP_TO_NUMBER_FINALIZE (len_number);
186+ ECMA_FINALIZE (arg_len_value);
187+ }
188+ else
189+ {
190+ ecma_string_t *new_array_index_string_p = ecma_new_ecma_string_from_uint32 (new_array_index);
191+
192+ /* Using [[Put]] is equvalent to [[DefineOwnProperty]] in this case, so we use it for simplicity. */
193+ ecma_completion_value_t put_comp = ecma_op_object_put (new_array_p,
194+ new_array_index_string_p,
195+ args[arg_index],
196+ false );
197+ JERRY_ASSERT (ecma_is_completion_value_normal (put_comp));
198+ ecma_free_completion_value (put_comp);
199+
200+ ecma_deref_ecma_string (new_array_index_string_p);
201+ new_array_index++;
202+ }
203+ }
204+
205+ if (ecma_is_completion_value_empty (ret_value))
206+ {
207+ ret_value = new_array;
208+ }
209+ else
210+ {
211+ ecma_free_completion_value (new_array);
212+ }
213+
214+ ECMA_OP_TO_NUMBER_FINALIZE (len_number);
215+ ECMA_FINALIZE (len_value);
216+ ecma_deref_ecma_string (magic_string_length_p);
217+ ECMA_FINALIZE (obj_this);
218+
219+ return ret_value;
220+ }
221+
79222/* *
80223 * The Array.prototype object's 'forEach' routine
81224 *
0 commit comments