@@ -1435,6 +1435,311 @@ ecma_builtin_array_prototype_object_slice (ecma_value_t this_arg, /**< 'this' ar
1435
1435
return ret_value;
1436
1436
} /* ecma_builtin_array_prototype_object_slice */
1437
1437
1438
+ /* *
1439
+ * The Array.prototype object's 'splice' routine
1440
+ *
1441
+ * See also:
1442
+ * ECMA-262 v5, 15.4.4.12
1443
+ *
1444
+ * @return completion value
1445
+ * Returned value must be freed with ecma_free_completion_value.
1446
+ */
1447
+ static ecma_completion_value_t
1448
+ ecma_builtin_array_prototype_object_splice (ecma_value_t this_arg, /* *< this argument */
1449
+ const ecma_value_t args[], /* *< arguments list */
1450
+ ecma_length_t args_number) /* *< number of arguments */
1451
+ {
1452
+ ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
1453
+
1454
+ /* 1. */
1455
+ ECMA_TRY_CATCH (obj_this,
1456
+ ecma_op_to_object (this_arg),
1457
+ ret_value);
1458
+
1459
+ ecma_object_t *obj_p = ecma_get_object_from_value (obj_this);
1460
+
1461
+ /* 3. */
1462
+ ecma_string_t *length_magic_string_p = ecma_get_magic_string (ECMA_MAGIC_STRING_LENGTH);
1463
+
1464
+ ECMA_TRY_CATCH (len_value,
1465
+ ecma_op_object_get (obj_p, length_magic_string_p),
1466
+ ret_value);
1467
+
1468
+ /* 4. */
1469
+ ECMA_OP_TO_NUMBER_TRY_CATCH (len_number,
1470
+ len_value,
1471
+ ret_value);
1472
+
1473
+ const uint32_t len = ecma_number_to_uint32 (len_number);
1474
+
1475
+ ecma_completion_value_t new_array = ecma_op_create_array_object (0 , 0 , false );
1476
+ ecma_object_t *new_array_p = ecma_get_object_from_completion_value (new_array);
1477
+
1478
+ uint32_t start = 0 ;
1479
+ uint32_t delete_count = 0 ;
1480
+
1481
+ if (args_number > 0 )
1482
+ {
1483
+ /* 5. */
1484
+ ECMA_OP_TO_NUMBER_TRY_CATCH (start_num,
1485
+ args[0 ],
1486
+ ret_value);
1487
+
1488
+ int32_t relative_start = ecma_number_to_int32 (start_num);
1489
+
1490
+ /* 6. */
1491
+ if (relative_start < 0 )
1492
+ {
1493
+ uint32_t start_abs = (uint32_t ) - relative_start;
1494
+ if (start_abs > len)
1495
+ {
1496
+ start = 0 ;
1497
+ }
1498
+ else
1499
+ {
1500
+ start = len - start_abs;
1501
+ }
1502
+ }
1503
+ else
1504
+ {
1505
+ start = (uint32_t ) relative_start;
1506
+ if (start > len)
1507
+ {
1508
+ start = len;
1509
+ }
1510
+ }
1511
+
1512
+ /*
1513
+ * If there is only one argument, that will be the start argument,
1514
+ * and we must delete the additional elements.
1515
+ */
1516
+ if (args_number == 1 )
1517
+ {
1518
+ delete_count = len - start;
1519
+ }
1520
+ else
1521
+ {
1522
+ /* 7. */
1523
+ ECMA_OP_TO_NUMBER_TRY_CATCH (delete_num,
1524
+ args[1 ],
1525
+ ret_value);
1526
+
1527
+ int32_t delete_count_int = ecma_number_to_int32 (delete_num);
1528
+
1529
+ if (delete_count_int > 0 )
1530
+ {
1531
+ delete_count = (uint32_t ) delete_count_int;
1532
+ }
1533
+ else
1534
+ {
1535
+ delete_count = 0 ;
1536
+ }
1537
+
1538
+ if (len - start < delete_count)
1539
+ {
1540
+ delete_count = len - start;
1541
+ }
1542
+
1543
+ ECMA_OP_TO_NUMBER_FINALIZE (delete_num);
1544
+ }
1545
+
1546
+ ECMA_OP_TO_NUMBER_FINALIZE (start_num);
1547
+ }
1548
+
1549
+ /* 8-9. */
1550
+ uint32_t k;
1551
+
1552
+ for (uint32_t del_item_idx, k = 0 ;
1553
+ k < delete_count && ecma_is_completion_value_empty (ret_value);
1554
+ k++)
1555
+ {
1556
+ /* 9.a */
1557
+ del_item_idx = k + start;
1558
+ ecma_string_t *idx_str_p = ecma_new_ecma_string_from_uint32 (del_item_idx);
1559
+
1560
+ /* 9.b */
1561
+ if (ecma_op_object_get_property (obj_p, idx_str_p) != NULL )
1562
+ {
1563
+ /* 9.c.i */
1564
+ ECMA_TRY_CATCH (get_value,
1565
+ ecma_op_object_get (obj_p, idx_str_p),
1566
+ ret_value);
1567
+
1568
+ ecma_string_t *idx_str_new_p = ecma_new_ecma_string_from_uint32 (k);
1569
+
1570
+ /* 9.c.ii
1571
+ * Using [[Put]] is equivalent to using [[DefineOwnProperty]] as specified the standard,
1572
+ * so we use [[Put]] instead for simplicity. No need for a try-catch block since it is called
1573
+ * with is_throw = false.
1574
+ */
1575
+ ECMA_TRY_CATCH (put_value,
1576
+ ecma_op_object_put (new_array_p, idx_str_new_p, get_value, false ),
1577
+ ret_value);
1578
+
1579
+ ECMA_FINALIZE (put_value);
1580
+ ecma_deref_ecma_string (idx_str_new_p);
1581
+ ECMA_FINALIZE (get_value);
1582
+ }
1583
+
1584
+ ecma_deref_ecma_string (idx_str_p);
1585
+ }
1586
+
1587
+ /* 11. */
1588
+ ecma_length_t item_count;
1589
+
1590
+ if (args_number > 2 )
1591
+ {
1592
+ item_count = (ecma_length_t ) (args_number - 2 );
1593
+ }
1594
+ else
1595
+ {
1596
+ item_count = 0 ;
1597
+ }
1598
+
1599
+ const uint32_t new_len = len - delete_count + item_count;
1600
+
1601
+ if (item_count != delete_count)
1602
+ {
1603
+ uint32_t from, to;
1604
+
1605
+ /* 12. */
1606
+ if (item_count < delete_count)
1607
+ {
1608
+ /* 12.b */
1609
+ for (k = start; k < (len - delete_count) && ecma_is_completion_value_empty (ret_value); k++)
1610
+ {
1611
+ from = k + delete_count;
1612
+ ecma_string_t *from_str_p = ecma_new_ecma_string_from_uint32 (from);
1613
+
1614
+ to = k + item_count;
1615
+ ecma_string_t *to_str_p = ecma_new_ecma_string_from_uint32 (to);
1616
+
1617
+ /* 12.b.iii */
1618
+ if (ecma_op_object_get_property (obj_p, from_str_p) != NULL )
1619
+ {
1620
+ /* 12.b.iv */
1621
+ ECMA_TRY_CATCH (get_value,
1622
+ ecma_op_object_get (obj_p, from_str_p),
1623
+ ret_value);
1624
+
1625
+ ECMA_TRY_CATCH (put_value,
1626
+ ecma_op_object_put (obj_p, to_str_p, get_value, true ),
1627
+ ret_value);
1628
+
1629
+ ECMA_FINALIZE (put_value);
1630
+ ECMA_FINALIZE (get_value);
1631
+ }
1632
+ else
1633
+ {
1634
+ /* 12.b.v */
1635
+ ECMA_TRY_CATCH (del_value,
1636
+ ecma_op_object_delete (obj_p, to_str_p, true ),
1637
+ ret_value);
1638
+
1639
+ ECMA_FINALIZE (del_value);
1640
+ }
1641
+
1642
+ ecma_deref_ecma_string (to_str_p);
1643
+ ecma_deref_ecma_string (from_str_p);
1644
+ }
1645
+
1646
+ /* 12.d */
1647
+ for (k = len; k > new_len && ecma_is_completion_value_empty (ret_value); k--)
1648
+ {
1649
+ ecma_string_t *str_idx_p = ecma_new_ecma_string_from_uint32 (k - 1 );
1650
+ ECMA_TRY_CATCH (del_value,
1651
+ ecma_op_object_delete (obj_p, str_idx_p, true ),
1652
+ ret_value);
1653
+
1654
+ ECMA_FINALIZE (del_value);
1655
+ ecma_deref_ecma_string (str_idx_p);
1656
+ }
1657
+ }
1658
+ /* 13. */
1659
+ else if (item_count > delete_count)
1660
+ {
1661
+ /* 13.b */
1662
+ for (k = len - delete_count; k > start && ecma_is_completion_value_empty (ret_value); k--)
1663
+ {
1664
+ from = k + delete_count - 1 ;
1665
+ ecma_string_t *from_str_p = ecma_new_ecma_string_from_uint32 (from);
1666
+
1667
+ to = k + item_count - 1 ;
1668
+ ecma_string_t *to_str_p = ecma_new_ecma_string_from_uint32 (to);
1669
+
1670
+ /* 13.b.iii */
1671
+ if (ecma_op_object_get_property (obj_p, from_str_p) != NULL )
1672
+ {
1673
+ /* 13.b.iv */
1674
+ ECMA_TRY_CATCH (get_value,
1675
+ ecma_op_object_get (obj_p, from_str_p),
1676
+ ret_value);
1677
+
1678
+ ECMA_TRY_CATCH (put_value,
1679
+ ecma_op_object_put (obj_p, to_str_p, get_value, true ),
1680
+ ret_value);
1681
+
1682
+ ECMA_FINALIZE (put_value);
1683
+ ECMA_FINALIZE (get_value);
1684
+ }
1685
+ else
1686
+ {
1687
+ /* 13.b.v */
1688
+ ECMA_TRY_CATCH (del_value,
1689
+ ecma_op_object_delete (obj_p, to_str_p, true ),
1690
+ ret_value);
1691
+
1692
+ ECMA_FINALIZE (del_value);
1693
+ }
1694
+
1695
+ ecma_deref_ecma_string (to_str_p);
1696
+ ecma_deref_ecma_string (from_str_p);
1697
+ }
1698
+ }
1699
+ }
1700
+
1701
+ /* 15. */
1702
+ ecma_length_t idx = 0 ;
1703
+ for (ecma_length_t arg_index = 2 ;
1704
+ arg_index < args_number && ecma_is_completion_value_empty (ret_value);
1705
+ arg_index++, idx++)
1706
+ {
1707
+ ecma_string_t *str_idx_p = ecma_new_ecma_string_from_uint32 ((uint32_t ) (start + idx));
1708
+ ECMA_TRY_CATCH (put_value,
1709
+ ecma_op_object_put (obj_p, str_idx_p, args[arg_index], true ),
1710
+ ret_value);
1711
+
1712
+ ECMA_FINALIZE (put_value);
1713
+ ecma_deref_ecma_string (str_idx_p);
1714
+ }
1715
+
1716
+ /* 16. */
1717
+ if (ecma_is_completion_value_empty (ret_value))
1718
+ {
1719
+ ECMA_TRY_CATCH (set_length_value,
1720
+ ecma_builtin_array_prototype_helper_set_length (obj_p, new_len),
1721
+ ret_value);
1722
+
1723
+ ECMA_FINALIZE (set_length_value);
1724
+ }
1725
+
1726
+ if (ecma_is_completion_value_empty (ret_value))
1727
+ {
1728
+ ret_value = new_array;
1729
+ }
1730
+ else
1731
+ {
1732
+ ecma_free_completion_value (new_array);
1733
+ }
1734
+
1735
+ ECMA_OP_TO_NUMBER_FINALIZE (len_number);
1736
+ ECMA_FINALIZE (len_value);
1737
+ ecma_deref_ecma_string (length_magic_string_p);
1738
+ ECMA_FINALIZE (obj_this);
1739
+
1740
+ return ret_value;
1741
+ } /* ecma_builtin_array_prototype_object_splice */
1742
+
1438
1743
/* *
1439
1744
* @}
1440
1745
* @}
0 commit comments