| 1171 | } |
| 1172 | |
| 1173 | static tsn_value tsn_copy_properties_impl(tsn_vm* ctx, |
| 1174 | tsn_value_const dest_obj, |
| 1175 | tsn_value_const src_obj, |
| 1176 | int atoms_to_ignore_size, |
| 1177 | tsn_atom* atoms_to_ignore) { |
| 1178 | if (JS_IsArray(ctx, dest_obj) != 0) { |
| 1179 | auto index_start = JS_GetArrayLength_tsn(ctx, dest_obj); |
| 1180 | // Source object is array |
| 1181 | if (JS_IsArray(ctx, src_obj) != 0) { |
| 1182 | auto array_length = JS_GetArrayLength_tsn(ctx, src_obj); |
| 1183 | |
| 1184 | for (int i = 0; i < array_length; i++) { |
| 1185 | auto item = tsn_get_property_index(ctx, src_obj, static_cast<uint32_t>(i)); |
| 1186 | if (tsn_is_exception(ctx, item)) { |
| 1187 | return JS_EXCEPTION; |
| 1188 | } |
| 1189 | |
| 1190 | if (tsn_set_property_index(ctx, dest_obj, static_cast<uint32_t>(index_start + i), item) < 0) { |
| 1191 | tsn_release(ctx, item); |
| 1192 | return JS_EXCEPTION; |
| 1193 | } |
| 1194 | tsn_release(ctx, item); |
| 1195 | } |
| 1196 | |
| 1197 | return tsn_int32(ctx, array_length); |
| 1198 | } |
| 1199 | // Source object is iterable |
| 1200 | tsn_iterator iterator = tsn_new_iterator(ctx, src_obj); |
| 1201 | if (!tsn_iterator_is_exception(ctx, &iterator)) { |
| 1202 | int32_t i = 0; |
| 1203 | for (auto item = tsn_iterator_next(ctx, &iterator); tsn_iterator_has_value(ctx, &iterator); |
| 1204 | item = tsn_iterator_next(ctx, &iterator)) { |
| 1205 | if (tsn_is_exception(ctx, item)) { |
| 1206 | tsn_release_iterator(ctx, &iterator); |
| 1207 | return JS_EXCEPTION; |
| 1208 | } |
| 1209 | if (tsn_set_property_index(ctx, dest_obj, static_cast<uint32_t>(index_start + (i++)), item) < 0) { |
| 1210 | tsn_release(ctx, item); |
| 1211 | tsn_release_iterator(ctx, &iterator); |
| 1212 | return JS_EXCEPTION; |
| 1213 | } |
| 1214 | tsn_release(ctx, item); |
| 1215 | } |
| 1216 | tsn_release_iterator(ctx, &iterator); |
| 1217 | return tsn_int32(ctx, i); |
| 1218 | } else { |
| 1219 | // Not iterable |
| 1220 | return JS_EXCEPTION; |
| 1221 | } |
| 1222 | } else { |
| 1223 | if (tsn_is_undefined_or_null(ctx, src_obj)) { |
| 1224 | // spread undefined or null copies nothing |
| 1225 | return tsn_int32(ctx, 0); |
| 1226 | } |
| 1227 | JSPropertyEnum* properties = nullptr; |
| 1228 | uint32_t properties_length; |
| 1229 | if (JS_GetOwnPropertyNames( |
| 1230 | ctx, &properties, &properties_length, src_obj, JS_GPN_STRING_MASK | JS_GPN_ENUM_ONLY) != 0) { |
no test coverage detected