@@ -1456,6 +1456,83 @@ pub(crate) fn declarations(policy: &Policy, list_type: TypeId) -> Vec<Decl> {
14561456 ) ) ,
14571457 ] ,
14581458 ) ) ;
1459+ // Positional indexing already has an unboxed integer in the Python
1460+ // frontend (notably while unpacking nested tuples). Keep that integer
1461+ // through the dispatch instead of allocating a box only to read it
1462+ // back in every list branch. Dicts still need a boxed key.
1463+ let position = local ( "position" , i64 ( ) ) ;
1464+ d. push ( define (
1465+ "zb_any_getitem_i64" ,
1466+ & [ & x, & position] ,
1467+ any ( ) ,
1468+ vec ! [
1469+ cat. decl( category( x. e( ) ) ) ,
1470+ when(
1471+ is( & cat, STR ) ,
1472+ vec![ ret( box_str( call(
1473+ "zb_str_get" ,
1474+ vec![ get_str( x. e( ) ) , position. e( ) ] ,
1475+ string( ) ,
1476+ ) ) ) ] ,
1477+ ) ,
1478+ when(
1479+ ne( cat. e( ) , int( CUSTOM ) ) ,
1480+ vec![ type_error( add(
1481+ quoted( type_name( x. e( ) ) ) ,
1482+ text( " object is not subscriptable" ) ,
1483+ ) ) ] ,
1484+ ) ,
1485+ when(
1486+ is_dict( x. e( ) ) ,
1487+ vec![ ret( call(
1488+ "zb_dict_get" ,
1489+ vec![ raw_any( x. e( ) ) , box_i64( position. e( ) ) ] ,
1490+ any( ) ,
1491+ ) ) ] ,
1492+ ) ,
1493+ when(
1494+ kind_is( Kind :: Int , x. e( ) ) ,
1495+ vec![ ret( box_i64( call(
1496+ "zb_list_get_i64" ,
1497+ vec![ unbox( Kind :: Int , x. e( ) ) , position. e( ) ] ,
1498+ i64 ( ) ,
1499+ ) ) ) ] ,
1500+ ) ,
1501+ when(
1502+ kind_is( Kind :: Float , x. e( ) ) ,
1503+ vec![ ret( box_f64( call(
1504+ "zb_list_get_f64" ,
1505+ vec![ unbox( Kind :: Float , x. e( ) ) , position. e( ) ] ,
1506+ f64 ( ) ,
1507+ ) ) ) ] ,
1508+ ) ,
1509+ when(
1510+ kind_is( Kind :: Str , x. e( ) ) ,
1511+ vec![ ret( box_str( call(
1512+ "zb_list_get_str" ,
1513+ vec![ unbox( Kind :: Str , x. e( ) ) , position. e( ) ] ,
1514+ string( ) ,
1515+ ) ) ) ] ,
1516+ ) ,
1517+ when(
1518+ kind_is( Kind :: Ptr , x. e( ) ) ,
1519+ vec![ ret( call(
1520+ "zb_hook_box_instance" ,
1521+ vec![ call(
1522+ "zb_list_get_ptr" ,
1523+ vec![ unbox( Kind :: Ptr , x. e( ) ) , position. e( ) ] ,
1524+ Kind :: Ptr . ty( ) ,
1525+ ) ] ,
1526+ any( ) ,
1527+ ) ) ] ,
1528+ ) ,
1529+ ret( call(
1530+ "zb_list_get_any" ,
1531+ vec![ iter( x. e( ) ) , position. e( ) ] ,
1532+ any( ) ,
1533+ ) ) ,
1534+ ] ,
1535+ ) ) ;
14591536 let mutable_list = |x : Expr | {
14601537 and (
14611538 eq ( category ( x. clone ( ) ) , int ( CUSTOM ) ) ,
@@ -1567,6 +1644,99 @@ pub(crate) fn declarations(policy: &Policy, list_type: TypeId) -> Vec<Decl> {
15671644 ret_void( ) ,
15681645 ] ,
15691646 ) ) ;
1647+ let list_set_i64 = |k : Kind , x : Expr , i : Expr , v : Expr | {
1648+ expr ( call (
1649+ & format ! ( "zb_list_set_{}" , k. suffix( ) ) ,
1650+ vec ! [ unbox( k, x) , i, v] ,
1651+ unit ( ) ,
1652+ ) )
1653+ } ;
1654+ d. push ( define (
1655+ "zb_any_setitem_i64" ,
1656+ & [ & x, & position, & v] ,
1657+ unit ( ) ,
1658+ vec ! [
1659+ when(
1660+ boxed_dict( x. e( ) ) ,
1661+ vec![
1662+ expr( call(
1663+ "zb_dict_set" ,
1664+ vec![ raw_any( x. e( ) ) , box_i64( position. e( ) ) , v. e( ) ] ,
1665+ unit( ) ,
1666+ ) ) ,
1667+ ret_void( ) ,
1668+ ] ,
1669+ ) ,
1670+ when(
1671+ not( mutable_list( x. e( ) ) ) ,
1672+ vec![ type_error( add(
1673+ quoted( type_name( x. e( ) ) ) ,
1674+ text( " object does not support item assignment" ) ,
1675+ ) ) ] ,
1676+ ) ,
1677+ when(
1678+ kind_is( Kind :: Int , x. e( ) ) ,
1679+ vec![
1680+ list_set_i64(
1681+ Kind :: Int ,
1682+ x. e( ) ,
1683+ position. e( ) ,
1684+ call( "zb_any_as_i64" , vec![ v. e( ) ] , i64 ( ) ) ,
1685+ ) ,
1686+ ret_void( ) ,
1687+ ] ,
1688+ ) ,
1689+ when(
1690+ kind_is( Kind :: Float , x. e( ) ) ,
1691+ vec![
1692+ list_set_i64(
1693+ Kind :: Float ,
1694+ x. e( ) ,
1695+ position. e( ) ,
1696+ call( "zb_any_as_f64" , vec![ v. e( ) ] , f64 ( ) ) ,
1697+ ) ,
1698+ ret_void( ) ,
1699+ ] ,
1700+ ) ,
1701+ when(
1702+ kind_is( Kind :: Str , x. e( ) ) ,
1703+ vec![
1704+ list_set_i64(
1705+ Kind :: Str ,
1706+ x. e( ) ,
1707+ position. e( ) ,
1708+ call( "zb_any_as_str" , vec![ v. e( ) ] , string( ) ) ,
1709+ ) ,
1710+ ret_void( ) ,
1711+ ] ,
1712+ ) ,
1713+ when(
1714+ kind_is( Kind :: Ptr , x. e( ) ) ,
1715+ vec![
1716+ when(
1717+ not( is_instance( v. e( ) ) ) ,
1718+ vec![ type_error( add(
1719+ text( "expected an instance, got " ) ,
1720+ quoted( type_name( v. e( ) ) ) ,
1721+ ) ) ] ,
1722+ ) ,
1723+ list_set_i64(
1724+ Kind :: Ptr ,
1725+ x. e( ) ,
1726+ position. e( ) ,
1727+ cast( call( "zb_unbox_instance_raw" , vec![ v. e( ) ] , i64 ( ) ) , usize ( ) ) ,
1728+ ) ,
1729+ ret_void( ) ,
1730+ ] ,
1731+ ) ,
1732+ expr( call(
1733+ "zb_list_set_any" ,
1734+ vec![ unbox( Kind :: Any , x. e( ) ) , position. e( ) , v. e( ) ] ,
1735+ unit( ) ,
1736+ ) ) ,
1737+ ret_void( ) ,
1738+ ] ,
1739+ ) ) ;
15701740 d. push ( define (
15711741 "zb_any_delitem" ,
15721742 & [ & x, & i] ,
0 commit comments