@@ -76,6 +76,149 @@ ecma_builtin_array_prototype_helper_set_length (ecma_object_t *object, /**< obje
76
76
return ret_value;
77
77
} /* ecma_builtin_array_prototype_helper_set_length */
78
78
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
+
79
222
/* *
80
223
* The Array.prototype object's 'forEach' routine
81
224
*
0 commit comments