@@ -1448,44 +1448,65 @@ ecma_builtin_array_prototype_object_sort (ecma_value_t this_arg, /**< this argum
14481448
14491449 uint32_t len = ecma_number_to_uint32 (len_number);
14501450
1451- MEM_DEFINE_LOCAL_ARRAY (values_buffer, len, ecma_value_t );
1451+ uint32_t defined_prop_count = 0 ;
1452+ /* Count number of defined properties. */
1453+ for (ecma_property_t *property_p = ecma_get_property_list (obj_p);
1454+ property_p != NULL ;
1455+ property_p = ECMA_GET_POINTER (ecma_property_t , property_p->next_property_p ))
1456+ {
1457+ defined_prop_count++;
1458+ }
1459+
1460+ MEM_DEFINE_LOCAL_ARRAY (values_buffer, defined_prop_count, ecma_value_t );
14521461 uint32_t copied_num = 0 ;
14531462
14541463 /* Copy unsorted array into a native c array. */
14551464 for (uint32_t index = 0 ; index < len && ecma_is_completion_value_empty (ret_value); index++)
14561465 {
14571466 ecma_string_t *index_string_p = ecma_new_ecma_string_from_uint32 (index);
1458- ECMA_TRY_CATCH (index_value, ecma_op_object_get (obj_p, index_string_p), ret_value);
1467+ if (ecma_op_object_get_property (obj_p, index_string_p) != NULL )
1468+ {
1469+ ECMA_TRY_CATCH (index_value, ecma_op_object_get (obj_p, index_string_p), ret_value);
14591470
1460- values_buffer[index] = ecma_copy_value (index_value, true );
1461- copied_num++;
1471+ values_buffer[copied_num++] = ecma_copy_value (index_value, true );
14621472
1463- ECMA_FINALIZE (index_value);
1473+ ECMA_FINALIZE (index_value);
1474+ }
14641475 ecma_deref_ecma_string (index_string_p);
14651476 }
14661477
1467- JERRY_ASSERT (copied_num == len || ! ecma_is_completion_value_empty (ret_value) );
1478+ JERRY_ASSERT (copied_num <= defined_prop_count );
14681479
14691480 /* Sorting. */
14701481 if (len > 1 && ecma_is_completion_value_empty (ret_value))
14711482 {
14721483 ECMA_TRY_CATCH (sort_value,
14731484 ecma_builtin_array_prototype_object_array_heap_sort_helper (values_buffer,
1474- (int )(len - 1 ),
1485+ (int )(copied_num - 1 ),
14751486 arg1),
14761487 ret_value);
14771488 ECMA_FINALIZE (sort_value);
14781489 }
14791490
1480- if (ecma_is_completion_value_empty (ret_value))
1491+ /* Put sorted values to the front of the array. */
1492+ uint32_t index;
1493+ for (index = 0 ; index < copied_num && ecma_is_completion_value_empty (ret_value); index++)
14811494 {
1482- /*
1483- * FIXME: Casting len to ecma_length_t may overflow, but since ecma_length_t is still at least
1484- * 16 bits long, with an array of that size, we would run out of memory way before this happens.
1485- */
1486- JERRY_ASSERT ((ecma_length_t ) len == len);
1487- /* Copy the sorted array into a new array. */
1488- ret_value = ecma_op_create_array_object (values_buffer, (ecma_length_t ) len, false );
1495+ ecma_string_t *index_string_p = ecma_new_ecma_string_from_uint32 (index);
1496+ ECMA_TRY_CATCH (put_value,
1497+ ecma_op_object_put (obj_p, index_string_p, values_buffer[index], true ),
1498+ ret_value);
1499+ ECMA_FINALIZE (put_value);
1500+ ecma_deref_ecma_string (index_string_p);
1501+ }
1502+
1503+ /* Undefined properties should be in the back of the array. */
1504+ for (;index < len && ecma_is_completion_value_empty (ret_value); index++)
1505+ {
1506+ ecma_string_t *index_string_p = ecma_new_ecma_string_from_uint32 (index);
1507+ ECMA_TRY_CATCH (del_value, ecma_op_object_delete (obj_p, index_string_p, true ), ret_value);
1508+ ECMA_FINALIZE (del_value);
1509+ ecma_deref_ecma_string (index_string_p);
14891510 }
14901511
14911512 /* Free values that were copied to the local array. */
@@ -1494,6 +1515,11 @@ ecma_builtin_array_prototype_object_sort (ecma_value_t this_arg, /**< this argum
14941515 ecma_free_value (values_buffer[index], true );
14951516 }
14961517
1518+ if (ecma_is_completion_value_empty (ret_value))
1519+ {
1520+ ret_value = ecma_make_normal_completion_value (ecma_copy_value (this_arg, true ));
1521+ }
1522+
14971523 MEM_FINALIZE_LOCAL_ARRAY (values_buffer);
14981524
14991525 ECMA_OP_TO_NUMBER_FINALIZE (len_number);
0 commit comments