|
1 | 1 | from __future__ import annotations |
2 | 2 |
|
3 | 3 | from mypyc.common import PLATFORM_SIZE |
4 | | -from mypyc.ir.ops import GetElementPtr, Integer, IntOp, LoadMem, SetMem, Value |
| 4 | +from mypyc.ir.ops import GetElementPtr, IncRef, Integer, IntOp, LoadMem, SetMem, Value |
5 | 5 | from mypyc.ir.rtypes import ( |
6 | 6 | PyListObject, |
7 | 7 | c_pyssize_t_rprimitive, |
@@ -43,3 +43,31 @@ def buf_init_item(builder: LowLevelIRBuilder, args: list[Value], line: int) -> V |
43 | 43 | def list_items(builder: LowLevelIRBuilder, args: list[Value], line: int) -> Value: |
44 | 44 | ob_item_ptr = builder.add(GetElementPtr(args[0], PyListObject, "ob_item", line)) |
45 | 45 | return builder.add(LoadMem(pointer_rprimitive, ob_item_ptr, line)) |
| 46 | + |
| 47 | + |
| 48 | +def list_item_ptr(builder: LowLevelIRBuilder, obj: Value, index: Value, line: int) -> Value: |
| 49 | + """Get a pointer to a list item (index must be valid and non-negative). |
| 50 | +
|
| 51 | + Type of index must be c_pyssize_t_rprimitive, and obj must refer to a list object. |
| 52 | + """ |
| 53 | + # List items are represented as an array of pointers. Pointer to the item obj[index] is |
| 54 | + # <pointer to first item> + index * <pointer size>. |
| 55 | + items = list_items(builder, [obj], line) |
| 56 | + delta = builder.add( |
| 57 | + IntOp( |
| 58 | + c_pyssize_t_rprimitive, |
| 59 | + index, |
| 60 | + Integer(PLATFORM_SIZE, c_pyssize_t_rprimitive), |
| 61 | + IntOp.MUL, |
| 62 | + ) |
| 63 | + ) |
| 64 | + return builder.add(IntOp(pointer_rprimitive, items, delta, IntOp.ADD)) |
| 65 | + |
| 66 | + |
| 67 | +@lower_primitive_op("list_get_item_unsafe") |
| 68 | +def list_get_item_unsafe(builder: LowLevelIRBuilder, args: list[Value], line: int) -> Value: |
| 69 | + index = builder.coerce(args[1], c_pyssize_t_rprimitive, line) |
| 70 | + item_ptr = list_item_ptr(builder, args[0], index, line) |
| 71 | + value = builder.add(LoadMem(object_rprimitive, item_ptr, line)) |
| 72 | + builder.add(IncRef(value)) |
| 73 | + return value |
0 commit comments