-
-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Expand file tree
/
Copy pathlist_ops.py
More file actions
71 lines (60 loc) · 2.46 KB
/
list_ops.py
File metadata and controls
71 lines (60 loc) · 2.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
from __future__ import annotations
from mypyc.common import PLATFORM_SIZE
from mypyc.ir.ops import GetElementPtr, Integer, IntOp, SetMem, Value
from mypyc.ir.rtypes import (
PyListObject,
c_pyssize_t_rprimitive,
object_rprimitive,
pointer_rprimitive,
)
from mypyc.irbuild.ll_builder import LowLevelIRBuilder
from mypyc.lower.registry import lower_primitive_op
@lower_primitive_op("buf_init_item")
def buf_init_item(builder: LowLevelIRBuilder, args: list[Value], line: int) -> Value:
"""Initialize an item in a buffer of "PyObject *" values at given index.
This can be used to initialize the data buffer of a freshly allocated list
object.
"""
base = args[0]
index_value = args[1]
value = args[2]
assert isinstance(index_value, Integer), index_value
index = index_value.numeric_value()
if index == 0:
ptr = base
else:
ptr = builder.add(
IntOp(
pointer_rprimitive,
base,
Integer(index * PLATFORM_SIZE, c_pyssize_t_rprimitive),
IntOp.ADD,
line,
)
)
return builder.add(SetMem(object_rprimitive, ptr, value, line))
@lower_primitive_op("list_items")
def list_items(builder: LowLevelIRBuilder, args: list[Value], line: int) -> Value:
ob_item_ptr = builder.add(GetElementPtr(args[0], PyListObject, "ob_item", line))
return builder.load_mem(ob_item_ptr, pointer_rprimitive)
def list_item_ptr(builder: LowLevelIRBuilder, obj: Value, index: Value, line: int) -> Value:
"""Get a pointer to a list item (index must be valid and non-negative).
Type of index must be c_pyssize_t_rprimitive, and obj must refer to a list object.
"""
# List items are represented as an array of pointers. Pointer to the item obj[index] is
# <pointer to first item> + index * <pointer size>.
items = list_items(builder, [obj], line)
delta = builder.add(
IntOp(
c_pyssize_t_rprimitive,
index,
Integer(PLATFORM_SIZE, c_pyssize_t_rprimitive),
IntOp.MUL,
)
)
return builder.add(IntOp(pointer_rprimitive, items, delta, IntOp.ADD))
@lower_primitive_op("list_get_item_unsafe")
def list_get_item_unsafe(builder: LowLevelIRBuilder, args: list[Value], line: int) -> Value:
index = builder.coerce(args[1], c_pyssize_t_rprimitive, line)
item_ptr = list_item_ptr(builder, args[0], index, line)
return builder.load_mem(item_ptr, object_rprimitive)