feat: indie status page MVP -- FastAPI + SQLite
- 8 DB models (services, incidents, monitors, subscribers, etc.) - Full CRUD API for services, incidents, monitors - Public status page with live data - Incident detail page with timeline - API key authentication - Uptime monitoring scheduler - 13 tests passing - TECHNICAL_DESIGN.md with full spec
This commit is contained in:
commit
902133edd3
4655 changed files with 1342691 additions and 0 deletions
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,44 @@
|
|||
"""Primitive bytearray ops.
|
||||
|
||||
NOTE: Most of these should be added to bytearray_extra_ops.c, which requires the
|
||||
BYTEARRAY_EXTRA_OPS primitive dependency, since these are used relatively rarely and we
|
||||
don't want to compile them unless needed.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from mypyc.ir.deps import BYTEARRAY_EXTRA_OPS
|
||||
from mypyc.ir.ops import ERR_MAGIC, ERR_NEVER
|
||||
from mypyc.ir.rtypes import bit_rprimitive, bytearray_rprimitive, object_rprimitive
|
||||
from mypyc.primitives.registry import custom_primitive_op, function_op, load_address_op
|
||||
|
||||
# Get the 'bytearray' type object.
|
||||
load_address_op(name="builtins.bytearray", type=object_rprimitive, src="PyByteArray_Type")
|
||||
|
||||
# bytearray(obj)
|
||||
function_op(
|
||||
name="builtins.bytearray",
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=bytearray_rprimitive,
|
||||
c_function_name="PyByteArray_FromObject",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# bytearray() -- construct empty bytearray
|
||||
function_op(
|
||||
name="builtins.bytearray",
|
||||
arg_types=[],
|
||||
return_type=bytearray_rprimitive,
|
||||
c_function_name="CPyByteArray_New",
|
||||
error_kind=ERR_MAGIC,
|
||||
dependencies=[BYTEARRAY_EXTRA_OPS],
|
||||
)
|
||||
|
||||
# isinstance(obj, bytearray)
|
||||
isinstance_bytearray = custom_primitive_op(
|
||||
name="builtins.isinstance",
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=bit_rprimitive,
|
||||
c_function_name="PyByteArray_Check",
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
Binary file not shown.
194
venv/lib/python3.11/site-packages/mypyc/primitives/bytes_ops.py
Normal file
194
venv/lib/python3.11/site-packages/mypyc/primitives/bytes_ops.py
Normal file
|
|
@ -0,0 +1,194 @@
|
|||
"""Primitive bytes ops."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from mypyc.ir.deps import BYTES_EXTRA_OPS
|
||||
from mypyc.ir.ops import ERR_MAGIC, ERR_NEVER
|
||||
from mypyc.ir.rtypes import (
|
||||
RUnion,
|
||||
bit_rprimitive,
|
||||
bool_rprimitive,
|
||||
bytes_rprimitive,
|
||||
c_int_rprimitive,
|
||||
c_pyssize_t_rprimitive,
|
||||
dict_rprimitive,
|
||||
int64_rprimitive,
|
||||
int_rprimitive,
|
||||
list_rprimitive,
|
||||
object_rprimitive,
|
||||
str_rprimitive,
|
||||
)
|
||||
from mypyc.primitives.registry import (
|
||||
ERR_NEG_INT,
|
||||
binary_op,
|
||||
custom_op,
|
||||
custom_primitive_op,
|
||||
function_op,
|
||||
load_address_op,
|
||||
method_op,
|
||||
)
|
||||
|
||||
# Get the 'bytes' type object.
|
||||
load_address_op(name="builtins.bytes", type=object_rprimitive, src="PyBytes_Type")
|
||||
|
||||
# bytes(obj)
|
||||
function_op(
|
||||
name="builtins.bytes",
|
||||
arg_types=[RUnion([list_rprimitive, dict_rprimitive, str_rprimitive])],
|
||||
return_type=bytes_rprimitive,
|
||||
c_function_name="PyBytes_FromObject",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# translate isinstance(obj, bytes)
|
||||
isinstance_bytes = function_op(
|
||||
name="builtins.isinstance",
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=bit_rprimitive,
|
||||
c_function_name="PyBytes_Check",
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
# bytes ==/!= (return -1/0/1)
|
||||
bytes_compare = custom_op(
|
||||
arg_types=[bytes_rprimitive, bytes_rprimitive],
|
||||
return_type=c_int_rprimitive,
|
||||
c_function_name="CPyBytes_Compare",
|
||||
error_kind=ERR_NEG_INT,
|
||||
)
|
||||
|
||||
# bytes + bytes
|
||||
binary_op(
|
||||
name="+",
|
||||
arg_types=[bytes_rprimitive, bytes_rprimitive],
|
||||
return_type=bytes_rprimitive,
|
||||
c_function_name="CPyBytes_Concat",
|
||||
error_kind=ERR_MAGIC,
|
||||
steals=[True, False],
|
||||
)
|
||||
|
||||
# bytes * int
|
||||
binary_op(
|
||||
name="*",
|
||||
arg_types=[bytes_rprimitive, int_rprimitive],
|
||||
return_type=bytes_rprimitive,
|
||||
c_function_name="CPyBytes_Multiply",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# int * bytes
|
||||
binary_op(
|
||||
name="*",
|
||||
arg_types=[int_rprimitive, bytes_rprimitive],
|
||||
return_type=bytes_rprimitive,
|
||||
c_function_name="CPyBytes_Multiply",
|
||||
error_kind=ERR_MAGIC,
|
||||
ordering=[1, 0],
|
||||
)
|
||||
|
||||
# bytes[begin:end]
|
||||
bytes_slice_op = custom_op(
|
||||
arg_types=[bytes_rprimitive, int_rprimitive, int_rprimitive],
|
||||
return_type=bytes_rprimitive,
|
||||
c_function_name="CPyBytes_GetSlice",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# bytes[index]
|
||||
# bytearray[index]
|
||||
method_op(
|
||||
name="__getitem__",
|
||||
arg_types=[bytes_rprimitive, int_rprimitive],
|
||||
return_type=int_rprimitive,
|
||||
c_function_name="CPyBytes_GetItem",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# bytes.join(obj)
|
||||
method_op(
|
||||
name="join",
|
||||
arg_types=[bytes_rprimitive, object_rprimitive],
|
||||
return_type=bytes_rprimitive,
|
||||
c_function_name="CPyBytes_Join",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# bytes.translate(table)
|
||||
method_op(
|
||||
name="translate",
|
||||
arg_types=[bytes_rprimitive, object_rprimitive],
|
||||
return_type=bytes_rprimitive,
|
||||
c_function_name="CPyBytes_Translate",
|
||||
error_kind=ERR_MAGIC,
|
||||
dependencies=[BYTES_EXTRA_OPS],
|
||||
)
|
||||
|
||||
# bytes.startswith(bytes)
|
||||
method_op(
|
||||
name="startswith",
|
||||
arg_types=[bytes_rprimitive, bytes_rprimitive],
|
||||
return_type=c_int_rprimitive,
|
||||
c_function_name="CPyBytes_Startswith",
|
||||
truncated_type=bool_rprimitive,
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# bytes.endswith(bytes)
|
||||
method_op(
|
||||
name="endswith",
|
||||
arg_types=[bytes_rprimitive, bytes_rprimitive],
|
||||
return_type=c_int_rprimitive,
|
||||
c_function_name="CPyBytes_Endswith",
|
||||
truncated_type=bool_rprimitive,
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# Join bytes objects and return a new bytes.
|
||||
# The first argument is the total number of the following bytes.
|
||||
bytes_build_op = custom_op(
|
||||
arg_types=[c_pyssize_t_rprimitive],
|
||||
return_type=bytes_rprimitive,
|
||||
c_function_name="CPyBytes_Build",
|
||||
error_kind=ERR_MAGIC,
|
||||
var_arg_type=bytes_rprimitive,
|
||||
)
|
||||
|
||||
function_op(
|
||||
name="builtins.ord",
|
||||
arg_types=[bytes_rprimitive],
|
||||
return_type=int_rprimitive,
|
||||
c_function_name="CPyBytes_Ord",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# Optimized bytes.__getitem__ operations
|
||||
|
||||
# bytes index adjustment - convert negative index to positive
|
||||
bytes_adjust_index_op = custom_primitive_op(
|
||||
name="bytes_adjust_index",
|
||||
arg_types=[bytes_rprimitive, int64_rprimitive],
|
||||
return_type=int64_rprimitive,
|
||||
c_function_name="CPyBytes_AdjustIndex",
|
||||
error_kind=ERR_NEVER,
|
||||
dependencies=[BYTES_EXTRA_OPS],
|
||||
)
|
||||
|
||||
# bytes range check - check if index is in valid range
|
||||
bytes_range_check_op = custom_primitive_op(
|
||||
name="bytes_range_check",
|
||||
arg_types=[bytes_rprimitive, int64_rprimitive],
|
||||
return_type=bool_rprimitive,
|
||||
c_function_name="CPyBytes_RangeCheck",
|
||||
error_kind=ERR_NEVER,
|
||||
dependencies=[BYTES_EXTRA_OPS],
|
||||
)
|
||||
|
||||
# bytes.__getitem__() - get byte at index (no bounds checking)
|
||||
bytes_get_item_unsafe_op = custom_primitive_op(
|
||||
name="bytes_get_item_unsafe",
|
||||
arg_types=[bytes_rprimitive, int64_rprimitive],
|
||||
return_type=int_rprimitive,
|
||||
c_function_name="CPyBytes_GetItemUnsafe",
|
||||
error_kind=ERR_NEVER,
|
||||
dependencies=[BYTES_EXTRA_OPS],
|
||||
)
|
||||
Binary file not shown.
343
venv/lib/python3.11/site-packages/mypyc/primitives/dict_ops.py
Normal file
343
venv/lib/python3.11/site-packages/mypyc/primitives/dict_ops.py
Normal file
|
|
@ -0,0 +1,343 @@
|
|||
"""Primitive dict ops."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from mypyc.ir.ops import ERR_FALSE, ERR_MAGIC, ERR_NEVER
|
||||
from mypyc.ir.rtypes import (
|
||||
bit_rprimitive,
|
||||
bool_rprimitive,
|
||||
c_int_rprimitive,
|
||||
c_pyssize_t_rprimitive,
|
||||
dict_next_rtuple_pair,
|
||||
dict_next_rtuple_single,
|
||||
dict_rprimitive,
|
||||
int_rprimitive,
|
||||
list_rprimitive,
|
||||
object_rprimitive,
|
||||
)
|
||||
from mypyc.primitives.registry import (
|
||||
ERR_NEG_INT,
|
||||
binary_op,
|
||||
custom_op,
|
||||
function_op,
|
||||
load_address_op,
|
||||
method_op,
|
||||
)
|
||||
|
||||
# Get the 'dict' type object.
|
||||
load_address_op(name="builtins.dict", type=object_rprimitive, src="PyDict_Type")
|
||||
|
||||
# Construct an empty dictionary via dict().
|
||||
function_op(
|
||||
name="builtins.dict",
|
||||
arg_types=[],
|
||||
return_type=dict_rprimitive,
|
||||
c_function_name="PyDict_New",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# Construct an empty dictionary.
|
||||
dict_new_op = custom_op(
|
||||
arg_types=[], return_type=dict_rprimitive, c_function_name="PyDict_New", error_kind=ERR_MAGIC
|
||||
)
|
||||
|
||||
# Construct a dictionary from keys and values.
|
||||
# Positional argument is the number of key-value pairs
|
||||
# Variable arguments are (key1, value1, ..., keyN, valueN).
|
||||
dict_build_op = custom_op(
|
||||
arg_types=[c_pyssize_t_rprimitive],
|
||||
return_type=dict_rprimitive,
|
||||
c_function_name="CPyDict_Build",
|
||||
error_kind=ERR_MAGIC,
|
||||
var_arg_type=object_rprimitive,
|
||||
)
|
||||
|
||||
# Construct a dictionary from another dictionary.
|
||||
dict_copy_op = function_op(
|
||||
name="builtins.dict",
|
||||
arg_types=[dict_rprimitive],
|
||||
return_type=dict_rprimitive,
|
||||
c_function_name="PyDict_Copy",
|
||||
error_kind=ERR_MAGIC,
|
||||
priority=2,
|
||||
)
|
||||
|
||||
# Generic one-argument dict constructor: dict(obj)
|
||||
dict_copy = function_op(
|
||||
name="builtins.dict",
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=dict_rprimitive,
|
||||
c_function_name="CPyDict_FromAny",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# translate isinstance(obj, dict)
|
||||
isinstance_dict = function_op(
|
||||
name="builtins.isinstance",
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=bit_rprimitive,
|
||||
c_function_name="PyDict_Check",
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
# dict[key]
|
||||
dict_get_item_op = method_op(
|
||||
name="__getitem__",
|
||||
arg_types=[dict_rprimitive, object_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPyDict_GetItem",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# dict[key] = value
|
||||
dict_set_item_op = method_op(
|
||||
name="__setitem__",
|
||||
arg_types=[dict_rprimitive, object_rprimitive, object_rprimitive],
|
||||
return_type=c_int_rprimitive,
|
||||
c_function_name="CPyDict_SetItem",
|
||||
error_kind=ERR_NEG_INT,
|
||||
)
|
||||
|
||||
# dict[key] = value (exact dict only, no subclasses)
|
||||
# NOTE: this is currently for internal use only, and not used for CallExpr specialization
|
||||
exact_dict_set_item_op = custom_op(
|
||||
arg_types=[dict_rprimitive, object_rprimitive, object_rprimitive],
|
||||
return_type=c_int_rprimitive,
|
||||
c_function_name="PyDict_SetItem",
|
||||
error_kind=ERR_NEG_INT,
|
||||
)
|
||||
|
||||
# key in dict
|
||||
binary_op(
|
||||
name="in",
|
||||
arg_types=[object_rprimitive, dict_rprimitive],
|
||||
return_type=c_int_rprimitive,
|
||||
c_function_name="PyDict_Contains",
|
||||
error_kind=ERR_NEG_INT,
|
||||
truncated_type=bool_rprimitive,
|
||||
ordering=[1, 0],
|
||||
)
|
||||
|
||||
# dict1.update(dict2)
|
||||
dict_update_op = method_op(
|
||||
name="update",
|
||||
arg_types=[dict_rprimitive, dict_rprimitive],
|
||||
return_type=c_int_rprimitive,
|
||||
c_function_name="CPyDict_Update",
|
||||
error_kind=ERR_NEG_INT,
|
||||
priority=2,
|
||||
)
|
||||
|
||||
# Operation used for **value in dict displays.
|
||||
# This is mostly like dict.update(obj), but has customized error handling.
|
||||
dict_update_in_display_op = custom_op(
|
||||
arg_types=[dict_rprimitive, object_rprimitive],
|
||||
return_type=c_int_rprimitive,
|
||||
c_function_name="CPyDict_UpdateInDisplay",
|
||||
error_kind=ERR_NEG_INT,
|
||||
)
|
||||
|
||||
# dict.update(obj)
|
||||
method_op(
|
||||
name="update",
|
||||
arg_types=[dict_rprimitive, object_rprimitive],
|
||||
return_type=c_int_rprimitive,
|
||||
c_function_name="CPyDict_UpdateFromAny",
|
||||
error_kind=ERR_NEG_INT,
|
||||
)
|
||||
|
||||
# dict.get(key, default)
|
||||
method_op(
|
||||
name="get",
|
||||
arg_types=[dict_rprimitive, object_rprimitive, object_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPyDict_Get",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# dict.get(key)
|
||||
dict_get_method_with_none = method_op(
|
||||
name="get",
|
||||
arg_types=[dict_rprimitive, object_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPyDict_GetWithNone",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# dict.setdefault(key, default)
|
||||
dict_setdefault_op = method_op(
|
||||
name="setdefault",
|
||||
arg_types=[dict_rprimitive, object_rprimitive, object_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPyDict_SetDefault",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# dict.setdefault(key)
|
||||
method_op(
|
||||
name="setdefault",
|
||||
arg_types=[dict_rprimitive, object_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPyDict_SetDefaultWithNone",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# dict.setdefault(key, empty tuple/list/set)
|
||||
# The third argument marks the data type of the second argument.
|
||||
# 1: list 2: dict 3: set
|
||||
# Other number would lead to an error.
|
||||
dict_setdefault_spec_init_op = custom_op(
|
||||
arg_types=[dict_rprimitive, object_rprimitive, c_int_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPyDict_SetDefaultWithEmptyDatatype",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# dict.keys()
|
||||
method_op(
|
||||
name="keys",
|
||||
arg_types=[dict_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPyDict_KeysView",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# dict.values()
|
||||
method_op(
|
||||
name="values",
|
||||
arg_types=[dict_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPyDict_ValuesView",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# dict.items()
|
||||
method_op(
|
||||
name="items",
|
||||
arg_types=[dict_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPyDict_ItemsView",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# dict.clear()
|
||||
method_op(
|
||||
name="clear",
|
||||
arg_types=[dict_rprimitive],
|
||||
return_type=bit_rprimitive,
|
||||
c_function_name="CPyDict_Clear",
|
||||
error_kind=ERR_FALSE,
|
||||
)
|
||||
|
||||
# dict.copy()
|
||||
method_op(
|
||||
name="copy",
|
||||
arg_types=[dict_rprimitive],
|
||||
return_type=dict_rprimitive,
|
||||
c_function_name="CPyDict_Copy",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# list(dict.keys())
|
||||
dict_keys_op = custom_op(
|
||||
arg_types=[dict_rprimitive],
|
||||
return_type=list_rprimitive,
|
||||
c_function_name="CPyDict_Keys",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# list(dict.values())
|
||||
dict_values_op = custom_op(
|
||||
arg_types=[dict_rprimitive],
|
||||
return_type=list_rprimitive,
|
||||
c_function_name="CPyDict_Values",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# list(dict.items())
|
||||
dict_items_op = custom_op(
|
||||
arg_types=[dict_rprimitive],
|
||||
return_type=list_rprimitive,
|
||||
c_function_name="CPyDict_Items",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# PyDict_Next() fast iteration
|
||||
dict_key_iter_op = custom_op(
|
||||
arg_types=[dict_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPyDict_GetKeysIter",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
dict_value_iter_op = custom_op(
|
||||
arg_types=[dict_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPyDict_GetValuesIter",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
dict_item_iter_op = custom_op(
|
||||
arg_types=[dict_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPyDict_GetItemsIter",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
dict_next_key_op = custom_op(
|
||||
arg_types=[object_rprimitive, int_rprimitive],
|
||||
return_type=dict_next_rtuple_single,
|
||||
c_function_name="CPyDict_NextKey",
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
dict_next_value_op = custom_op(
|
||||
arg_types=[object_rprimitive, int_rprimitive],
|
||||
return_type=dict_next_rtuple_single,
|
||||
c_function_name="CPyDict_NextValue",
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
dict_next_item_op = custom_op(
|
||||
arg_types=[object_rprimitive, int_rprimitive],
|
||||
return_type=dict_next_rtuple_pair,
|
||||
c_function_name="CPyDict_NextItem",
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
# check that len(dict) == const during iteration
|
||||
dict_check_size_op = custom_op(
|
||||
arg_types=[dict_rprimitive, c_pyssize_t_rprimitive],
|
||||
return_type=bit_rprimitive,
|
||||
c_function_name="CPyDict_CheckSize",
|
||||
error_kind=ERR_FALSE,
|
||||
)
|
||||
|
||||
dict_ssize_t_size_op = custom_op(
|
||||
arg_types=[dict_rprimitive],
|
||||
return_type=c_pyssize_t_rprimitive,
|
||||
c_function_name="PyDict_Size",
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
# Delete an item from a dict
|
||||
dict_del_item = custom_op(
|
||||
arg_types=[object_rprimitive, object_rprimitive],
|
||||
return_type=c_int_rprimitive,
|
||||
c_function_name="PyDict_DelItem",
|
||||
error_kind=ERR_NEG_INT,
|
||||
)
|
||||
|
||||
supports_mapping_protocol = custom_op(
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=c_int_rprimitive,
|
||||
c_function_name="CPyMapping_Check",
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
mapping_has_key = custom_op(
|
||||
arg_types=[object_rprimitive, object_rprimitive],
|
||||
return_type=c_int_rprimitive,
|
||||
c_function_name="PyMapping_HasKey",
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
Binary file not shown.
111
venv/lib/python3.11/site-packages/mypyc/primitives/exc_ops.py
Normal file
111
venv/lib/python3.11/site-packages/mypyc/primitives/exc_ops.py
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
"""Exception-related primitive ops."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from mypyc.ir.ops import ERR_ALWAYS, ERR_FALSE, ERR_NEVER
|
||||
from mypyc.ir.rtypes import bit_rprimitive, exc_rtuple, object_rprimitive, void_rtype
|
||||
from mypyc.primitives.registry import custom_op, custom_primitive_op
|
||||
|
||||
# If the argument is a class, raise an instance of the class. Otherwise, assume
|
||||
# that the argument is an exception object, and raise it.
|
||||
raise_exception_op = custom_op(
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=void_rtype,
|
||||
c_function_name="CPy_Raise",
|
||||
error_kind=ERR_ALWAYS,
|
||||
)
|
||||
|
||||
# Raise StopIteration exception with the specified value (which can be NULL).
|
||||
set_stop_iteration_value = custom_op(
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=void_rtype,
|
||||
c_function_name="CPyGen_SetStopIterationValue",
|
||||
error_kind=ERR_ALWAYS,
|
||||
)
|
||||
|
||||
# Raise exception with traceback.
|
||||
# Arguments are (exception type, exception value, traceback).
|
||||
raise_exception_with_tb_op = custom_op(
|
||||
arg_types=[object_rprimitive, object_rprimitive, object_rprimitive],
|
||||
return_type=void_rtype,
|
||||
c_function_name="CPyErr_SetObjectAndTraceback",
|
||||
error_kind=ERR_ALWAYS,
|
||||
)
|
||||
|
||||
# Reraise the currently raised exception.
|
||||
reraise_exception_op = custom_op(
|
||||
arg_types=[], return_type=void_rtype, c_function_name="CPy_Reraise", error_kind=ERR_ALWAYS
|
||||
)
|
||||
|
||||
# Propagate exception if the CPython error indicator is set (an exception was raised).
|
||||
no_err_occurred_op = custom_op(
|
||||
arg_types=[],
|
||||
return_type=bit_rprimitive,
|
||||
c_function_name="CPy_NoErrOccurred",
|
||||
error_kind=ERR_FALSE,
|
||||
)
|
||||
|
||||
err_occurred_op = custom_op(
|
||||
arg_types=[],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="PyErr_Occurred",
|
||||
error_kind=ERR_NEVER,
|
||||
is_borrowed=True,
|
||||
)
|
||||
|
||||
# Keep propagating a raised exception by unconditionally giving an error value.
|
||||
# This doesn't actually raise an exception.
|
||||
keep_propagating_op = custom_op(
|
||||
arg_types=[],
|
||||
return_type=bit_rprimitive,
|
||||
c_function_name="CPy_KeepPropagating",
|
||||
error_kind=ERR_FALSE,
|
||||
)
|
||||
|
||||
# If argument is NULL, propagate currently raised exception (in this case
|
||||
# an exception must have been raised). If this can be used, it's faster
|
||||
# than using PyErr_Occurred().
|
||||
propagate_if_error_op = custom_primitive_op(
|
||||
"propagate_if_error",
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=bit_rprimitive,
|
||||
error_kind=ERR_FALSE,
|
||||
)
|
||||
|
||||
# Catches a propagating exception and makes it the "currently
|
||||
# handled exception" (by sticking it into sys.exc_info()). Returns the
|
||||
# exception that was previously being handled, which must be restored
|
||||
# later.
|
||||
error_catch_op = custom_op(
|
||||
arg_types=[], return_type=exc_rtuple, c_function_name="CPy_CatchError", error_kind=ERR_NEVER
|
||||
)
|
||||
|
||||
# Restore an old "currently handled exception" returned from.
|
||||
# error_catch (by sticking it into sys.exc_info())
|
||||
restore_exc_info_op = custom_op(
|
||||
arg_types=[exc_rtuple],
|
||||
return_type=void_rtype,
|
||||
c_function_name="CPy_RestoreExcInfo",
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
# Checks whether the exception currently being handled matches a particular type.
|
||||
exc_matches_op = custom_op(
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=bit_rprimitive,
|
||||
c_function_name="CPy_ExceptionMatches",
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
# Get the value of the exception currently being handled.
|
||||
get_exc_value_op = custom_op(
|
||||
arg_types=[],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPy_GetExcValue",
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
# Get exception info (exception type, exception instance, traceback object).
|
||||
get_exc_info_op = custom_op(
|
||||
arg_types=[], return_type=exc_rtuple, c_function_name="CPy_GetExcInfo", error_kind=ERR_NEVER
|
||||
)
|
||||
Binary file not shown.
178
venv/lib/python3.11/site-packages/mypyc/primitives/float_ops.py
Normal file
178
venv/lib/python3.11/site-packages/mypyc/primitives/float_ops.py
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
"""Primitive float ops."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from mypyc.ir.ops import ERR_MAGIC, ERR_MAGIC_OVERLAPPING, ERR_NEVER
|
||||
from mypyc.ir.rtypes import (
|
||||
bit_rprimitive,
|
||||
bool_rprimitive,
|
||||
float_rprimitive,
|
||||
int_rprimitive,
|
||||
object_rprimitive,
|
||||
str_rprimitive,
|
||||
)
|
||||
from mypyc.primitives.registry import binary_op, function_op, load_address_op
|
||||
|
||||
# Get the 'builtins.float' type object.
|
||||
load_address_op(name="builtins.float", type=object_rprimitive, src="PyFloat_Type")
|
||||
|
||||
binary_op(
|
||||
name="//",
|
||||
arg_types=[float_rprimitive, float_rprimitive],
|
||||
return_type=float_rprimitive,
|
||||
c_function_name="CPyFloat_FloorDivide",
|
||||
error_kind=ERR_MAGIC_OVERLAPPING,
|
||||
)
|
||||
|
||||
# float(int)
|
||||
int_to_float_op = function_op(
|
||||
name="builtins.float",
|
||||
arg_types=[int_rprimitive],
|
||||
return_type=float_rprimitive,
|
||||
c_function_name="CPyFloat_FromTagged",
|
||||
error_kind=ERR_MAGIC_OVERLAPPING,
|
||||
)
|
||||
|
||||
# float(str)
|
||||
function_op(
|
||||
name="builtins.float",
|
||||
arg_types=[str_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="PyFloat_FromString",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# abs(float)
|
||||
function_op(
|
||||
name="builtins.abs",
|
||||
arg_types=[float_rprimitive],
|
||||
return_type=float_rprimitive,
|
||||
c_function_name="fabs",
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
# math.sin(float)
|
||||
function_op(
|
||||
name="math.sin",
|
||||
arg_types=[float_rprimitive],
|
||||
return_type=float_rprimitive,
|
||||
c_function_name="CPyFloat_Sin",
|
||||
error_kind=ERR_MAGIC_OVERLAPPING,
|
||||
)
|
||||
|
||||
# math.cos(float)
|
||||
function_op(
|
||||
name="math.cos",
|
||||
arg_types=[float_rprimitive],
|
||||
return_type=float_rprimitive,
|
||||
c_function_name="CPyFloat_Cos",
|
||||
error_kind=ERR_MAGIC_OVERLAPPING,
|
||||
)
|
||||
|
||||
# math.tan(float)
|
||||
function_op(
|
||||
name="math.tan",
|
||||
arg_types=[float_rprimitive],
|
||||
return_type=float_rprimitive,
|
||||
c_function_name="CPyFloat_Tan",
|
||||
error_kind=ERR_MAGIC_OVERLAPPING,
|
||||
)
|
||||
|
||||
# math.sqrt(float)
|
||||
function_op(
|
||||
name="math.sqrt",
|
||||
arg_types=[float_rprimitive],
|
||||
return_type=float_rprimitive,
|
||||
c_function_name="CPyFloat_Sqrt",
|
||||
error_kind=ERR_MAGIC_OVERLAPPING,
|
||||
)
|
||||
|
||||
# math.exp(float)
|
||||
function_op(
|
||||
name="math.exp",
|
||||
arg_types=[float_rprimitive],
|
||||
return_type=float_rprimitive,
|
||||
c_function_name="CPyFloat_Exp",
|
||||
error_kind=ERR_MAGIC_OVERLAPPING,
|
||||
)
|
||||
|
||||
# math.log(float)
|
||||
function_op(
|
||||
name="math.log",
|
||||
arg_types=[float_rprimitive],
|
||||
return_type=float_rprimitive,
|
||||
c_function_name="CPyFloat_Log",
|
||||
error_kind=ERR_MAGIC_OVERLAPPING,
|
||||
)
|
||||
|
||||
# math.floor(float)
|
||||
function_op(
|
||||
name="math.floor",
|
||||
arg_types=[float_rprimitive],
|
||||
return_type=int_rprimitive,
|
||||
c_function_name="CPyFloat_Floor",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# math.ceil(float)
|
||||
function_op(
|
||||
name="math.ceil",
|
||||
arg_types=[float_rprimitive],
|
||||
return_type=int_rprimitive,
|
||||
c_function_name="CPyFloat_Ceil",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# math.fabs(float)
|
||||
function_op(
|
||||
name="math.fabs",
|
||||
arg_types=[float_rprimitive],
|
||||
return_type=float_rprimitive,
|
||||
c_function_name="fabs",
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
# math.pow(float, float)
|
||||
pow_op = function_op(
|
||||
name="math.pow",
|
||||
arg_types=[float_rprimitive, float_rprimitive],
|
||||
return_type=float_rprimitive,
|
||||
c_function_name="CPyFloat_Pow",
|
||||
error_kind=ERR_MAGIC_OVERLAPPING,
|
||||
)
|
||||
|
||||
# math.copysign(float, float)
|
||||
copysign_op = function_op(
|
||||
name="math.copysign",
|
||||
arg_types=[float_rprimitive, float_rprimitive],
|
||||
return_type=float_rprimitive,
|
||||
c_function_name="copysign",
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
# math.isinf(float)
|
||||
function_op(
|
||||
name="math.isinf",
|
||||
arg_types=[float_rprimitive],
|
||||
return_type=bool_rprimitive,
|
||||
c_function_name="CPyFloat_IsInf",
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
# math.isnan(float)
|
||||
function_op(
|
||||
name="math.isnan",
|
||||
arg_types=[float_rprimitive],
|
||||
return_type=bool_rprimitive,
|
||||
c_function_name="CPyFloat_IsNaN",
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
# translate isinstance(obj, float)
|
||||
isinstance_float = function_op(
|
||||
name="builtins.isinstance",
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=bit_rprimitive,
|
||||
c_function_name="PyFloat_Check",
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
Binary file not shown.
|
|
@ -0,0 +1,426 @@
|
|||
"""Fallback primitive operations that operate on 'object' operands.
|
||||
|
||||
These just call the relevant Python C API function or a thin wrapper
|
||||
around an API function. Most of these also have faster, specialized
|
||||
ops that operate on some more specific types.
|
||||
|
||||
Many of these ops are given a low priority (0) so that specialized ops
|
||||
will take precedence. If your specialized op doesn't seem to be used,
|
||||
check that the priorities are configured properly.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from mypyc.ir.ops import ERR_MAGIC, ERR_NEVER
|
||||
from mypyc.ir.rtypes import (
|
||||
bool_rprimitive,
|
||||
c_int_rprimitive,
|
||||
c_pyssize_t_rprimitive,
|
||||
c_size_t_rprimitive,
|
||||
int_rprimitive,
|
||||
object_pointer_rprimitive,
|
||||
object_rprimitive,
|
||||
pointer_rprimitive,
|
||||
)
|
||||
from mypyc.primitives.registry import (
|
||||
ERR_NEG_INT,
|
||||
binary_op,
|
||||
custom_op,
|
||||
custom_primitive_op,
|
||||
function_op,
|
||||
method_op,
|
||||
unary_op,
|
||||
)
|
||||
|
||||
# Binary operations
|
||||
|
||||
for op, opid in [
|
||||
("==", 2), # PY_EQ
|
||||
("!=", 3), # PY_NE
|
||||
("<", 0), # PY_LT
|
||||
("<=", 1), # PY_LE
|
||||
(">", 4), # PY_GT
|
||||
(">=", 5),
|
||||
]: # PY_GE
|
||||
# The result type is 'object' since that's what PyObject_RichCompare returns.
|
||||
binary_op(
|
||||
name=op,
|
||||
arg_types=[object_rprimitive, object_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="PyObject_RichCompare",
|
||||
error_kind=ERR_MAGIC,
|
||||
extra_int_constants=[(opid, c_int_rprimitive)],
|
||||
priority=0,
|
||||
)
|
||||
|
||||
for op, funcname in [
|
||||
("+", "PyNumber_Add"),
|
||||
("-", "PyNumber_Subtract"),
|
||||
("*", "PyNumber_Multiply"),
|
||||
("//", "PyNumber_FloorDivide"),
|
||||
("/", "PyNumber_TrueDivide"),
|
||||
("%", "PyNumber_Remainder"),
|
||||
("<<", "PyNumber_Lshift"),
|
||||
(">>", "PyNumber_Rshift"),
|
||||
("&", "PyNumber_And"),
|
||||
("^", "PyNumber_Xor"),
|
||||
("|", "PyNumber_Or"),
|
||||
("@", "PyNumber_MatrixMultiply"),
|
||||
]:
|
||||
binary_op(
|
||||
name=op,
|
||||
arg_types=[object_rprimitive, object_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name=funcname,
|
||||
error_kind=ERR_MAGIC,
|
||||
priority=0,
|
||||
)
|
||||
|
||||
|
||||
function_op(
|
||||
name="builtins.divmod",
|
||||
arg_types=[object_rprimitive, object_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="PyNumber_Divmod",
|
||||
error_kind=ERR_MAGIC,
|
||||
priority=0,
|
||||
)
|
||||
|
||||
|
||||
for op, funcname in [
|
||||
("+=", "PyNumber_InPlaceAdd"),
|
||||
("-=", "PyNumber_InPlaceSubtract"),
|
||||
("*=", "PyNumber_InPlaceMultiply"),
|
||||
("@=", "PyNumber_InPlaceMatrixMultiply"),
|
||||
("//=", "PyNumber_InPlaceFloorDivide"),
|
||||
("/=", "PyNumber_InPlaceTrueDivide"),
|
||||
("%=", "PyNumber_InPlaceRemainder"),
|
||||
("<<=", "PyNumber_InPlaceLshift"),
|
||||
(">>=", "PyNumber_InPlaceRshift"),
|
||||
("&=", "PyNumber_InPlaceAnd"),
|
||||
("^=", "PyNumber_InPlaceXor"),
|
||||
("|=", "PyNumber_InPlaceOr"),
|
||||
]:
|
||||
binary_op(
|
||||
name=op,
|
||||
arg_types=[object_rprimitive, object_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name=funcname,
|
||||
error_kind=ERR_MAGIC,
|
||||
priority=0,
|
||||
)
|
||||
|
||||
for op, c_function in (("**", "CPyNumber_Power"), ("**=", "CPyNumber_InPlacePower")):
|
||||
binary_op(
|
||||
name=op,
|
||||
arg_types=[object_rprimitive, object_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
error_kind=ERR_MAGIC,
|
||||
c_function_name=c_function,
|
||||
priority=0,
|
||||
)
|
||||
|
||||
for arg_count, c_function in ((2, "CPyNumber_Power"), (3, "PyNumber_Power")):
|
||||
function_op(
|
||||
name="builtins.pow",
|
||||
arg_types=[object_rprimitive] * arg_count,
|
||||
return_type=object_rprimitive,
|
||||
error_kind=ERR_MAGIC,
|
||||
c_function_name=c_function,
|
||||
priority=0,
|
||||
)
|
||||
|
||||
binary_op(
|
||||
name="in",
|
||||
arg_types=[object_rprimitive, object_rprimitive],
|
||||
return_type=c_int_rprimitive,
|
||||
c_function_name="PySequence_Contains",
|
||||
error_kind=ERR_NEG_INT,
|
||||
truncated_type=bool_rprimitive,
|
||||
ordering=[1, 0],
|
||||
priority=0,
|
||||
)
|
||||
|
||||
|
||||
# Unary operations
|
||||
|
||||
for op, funcname in [
|
||||
("-", "PyNumber_Negative"),
|
||||
("+", "PyNumber_Positive"),
|
||||
("~", "PyNumber_Invert"),
|
||||
]:
|
||||
unary_op(
|
||||
name=op,
|
||||
arg_type=object_rprimitive,
|
||||
return_type=object_rprimitive,
|
||||
c_function_name=funcname,
|
||||
error_kind=ERR_MAGIC,
|
||||
priority=0,
|
||||
)
|
||||
|
||||
unary_op(
|
||||
name="not",
|
||||
arg_type=object_rprimitive,
|
||||
return_type=c_int_rprimitive,
|
||||
c_function_name="PyObject_Not",
|
||||
error_kind=ERR_NEG_INT,
|
||||
truncated_type=bool_rprimitive,
|
||||
priority=0,
|
||||
)
|
||||
|
||||
# abs(obj)
|
||||
function_op(
|
||||
name="builtins.abs",
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="PyNumber_Absolute",
|
||||
error_kind=ERR_MAGIC,
|
||||
priority=0,
|
||||
)
|
||||
|
||||
# obj1[obj2]
|
||||
py_get_item_op = method_op(
|
||||
name="__getitem__",
|
||||
arg_types=[object_rprimitive, object_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="PyObject_GetItem",
|
||||
error_kind=ERR_MAGIC,
|
||||
priority=0,
|
||||
)
|
||||
|
||||
# obj1[obj2] = obj3
|
||||
method_op(
|
||||
name="__setitem__",
|
||||
arg_types=[object_rprimitive, object_rprimitive, object_rprimitive],
|
||||
return_type=c_int_rprimitive,
|
||||
c_function_name="PyObject_SetItem",
|
||||
error_kind=ERR_NEG_INT,
|
||||
priority=0,
|
||||
)
|
||||
|
||||
# del obj1[obj2]
|
||||
method_op(
|
||||
name="__delitem__",
|
||||
arg_types=[object_rprimitive, object_rprimitive],
|
||||
return_type=c_int_rprimitive,
|
||||
c_function_name="PyObject_DelItem",
|
||||
error_kind=ERR_NEG_INT,
|
||||
priority=0,
|
||||
)
|
||||
|
||||
# hash(obj)
|
||||
function_op(
|
||||
name="builtins.hash",
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=int_rprimitive,
|
||||
c_function_name="CPyObject_Hash",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# getattr(obj, attr)
|
||||
py_getattr_op = function_op(
|
||||
name="builtins.getattr",
|
||||
arg_types=[object_rprimitive, object_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPyObject_GetAttr",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# getattr(obj, attr, default)
|
||||
function_op(
|
||||
name="builtins.getattr",
|
||||
arg_types=[object_rprimitive, object_rprimitive, object_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPyObject_GetAttr3",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# setattr(obj, attr, value)
|
||||
py_setattr_op = function_op(
|
||||
name="builtins.setattr",
|
||||
arg_types=[object_rprimitive, object_rprimitive, object_rprimitive],
|
||||
return_type=c_int_rprimitive,
|
||||
c_function_name="PyObject_SetAttr",
|
||||
error_kind=ERR_NEG_INT,
|
||||
)
|
||||
|
||||
# hasattr(obj, attr)
|
||||
py_hasattr_op = function_op(
|
||||
name="builtins.hasattr",
|
||||
arg_types=[object_rprimitive, object_rprimitive],
|
||||
return_type=bool_rprimitive,
|
||||
c_function_name="PyObject_HasAttr",
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
# del obj.attr
|
||||
py_delattr_op = function_op(
|
||||
name="builtins.delattr",
|
||||
arg_types=[object_rprimitive, object_rprimitive],
|
||||
return_type=c_int_rprimitive,
|
||||
c_function_name="PyObject_DelAttr",
|
||||
error_kind=ERR_NEG_INT,
|
||||
)
|
||||
|
||||
# Call callable object with N positional arguments: func(arg1, ..., argN)
|
||||
# Arguments are (func, arg1, ..., argN).
|
||||
py_call_op = custom_op(
|
||||
arg_types=[],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="PyObject_CallFunctionObjArgs",
|
||||
error_kind=ERR_MAGIC,
|
||||
var_arg_type=object_rprimitive,
|
||||
extra_int_constants=[(0, pointer_rprimitive)],
|
||||
)
|
||||
|
||||
# Call callable object using positional and/or keyword arguments (Python 3.8+)
|
||||
py_vectorcall_op = custom_op(
|
||||
arg_types=[
|
||||
object_rprimitive, # Callable
|
||||
object_pointer_rprimitive, # Args (PyObject **)
|
||||
c_size_t_rprimitive, # Number of positional args
|
||||
object_rprimitive,
|
||||
], # Keyword arg names tuple (or NULL)
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="PyObject_Vectorcall",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# Call method using positional and/or keyword arguments (Python 3.9+)
|
||||
py_vectorcall_method_op = custom_op(
|
||||
arg_types=[
|
||||
object_rprimitive, # Method name
|
||||
object_pointer_rprimitive, # Args, including self (PyObject **)
|
||||
c_size_t_rprimitive, # Number of positional args, including self
|
||||
object_rprimitive,
|
||||
], # Keyword arg names tuple (or NULL)
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="PyObject_VectorcallMethod",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# Call callable object with positional + keyword args: func(*args, **kwargs)
|
||||
# Arguments are (func, *args tuple, **kwargs dict).
|
||||
py_call_with_kwargs_op = custom_op(
|
||||
arg_types=[object_rprimitive, object_rprimitive, object_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="PyObject_Call",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# Call callable object with positional args only: func(*args)
|
||||
# Arguments are (func, *args tuple).
|
||||
py_call_with_posargs_op = custom_op(
|
||||
arg_types=[object_rprimitive, object_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="PyObject_CallObject",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# Call method with positional arguments: obj.method(arg1, ...)
|
||||
# Arguments are (object, attribute name, arg1, ...).
|
||||
py_method_call_op = custom_op(
|
||||
arg_types=[],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPyObject_CallMethodObjArgs",
|
||||
error_kind=ERR_MAGIC,
|
||||
var_arg_type=object_rprimitive,
|
||||
extra_int_constants=[(0, pointer_rprimitive)],
|
||||
)
|
||||
|
||||
# len(obj)
|
||||
generic_len_op = custom_op(
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=int_rprimitive,
|
||||
c_function_name="CPyObject_Size",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# len(obj)
|
||||
# same as generic_len_op, however return py_ssize_t
|
||||
generic_ssize_t_len_op = custom_op(
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=c_pyssize_t_rprimitive,
|
||||
c_function_name="PyObject_Size",
|
||||
error_kind=ERR_NEG_INT,
|
||||
)
|
||||
|
||||
# iter(obj)
|
||||
iter_op = function_op(
|
||||
name="builtins.iter",
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="PyObject_GetIter",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
# next(iterator)
|
||||
#
|
||||
# Although the error_kind is set to be ERR_NEVER, this can actually
|
||||
# return NULL, and thus it must be checked using Branch.IS_ERROR.
|
||||
next_op = custom_op(
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="PyIter_Next",
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
# next(iterator)
|
||||
#
|
||||
# Do a next, don't swallow StopIteration, but also don't propagate an
|
||||
# error. (N.B: This can still return NULL without an error to
|
||||
# represent an implicit StopIteration, but if StopIteration is
|
||||
# *explicitly* raised this will not swallow it.)
|
||||
# Can return NULL: see next_op.
|
||||
next_raw_op = custom_op(
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPyIter_Next",
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
# this would be aiter(obj) if it existed
|
||||
aiter_op = custom_op(
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPy_GetAIter",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# this would be anext(obj) if it existed
|
||||
anext_op = custom_op(
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPy_GetANext",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# x.__name__ (requires Python 3.11+)
|
||||
name_op = custom_primitive_op(
|
||||
name="__name__",
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPy_GetName",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# look-up name in tp_dict but don't raise AttributeError on failure
|
||||
generic_getattr = custom_op(
|
||||
arg_types=[object_rprimitive, object_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPyObject_GenericGetAttr",
|
||||
error_kind=ERR_NEVER,
|
||||
returns_null=True,
|
||||
)
|
||||
|
||||
generic_setattr = custom_op(
|
||||
arg_types=[object_rprimitive, object_rprimitive, object_rprimitive],
|
||||
return_type=c_int_rprimitive,
|
||||
c_function_name="CPyObject_GenericSetAttr",
|
||||
error_kind=ERR_NEG_INT,
|
||||
)
|
||||
|
||||
setup_object = custom_op(
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPy_SetupObject",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
Binary file not shown.
359
venv/lib/python3.11/site-packages/mypyc/primitives/int_ops.py
Normal file
359
venv/lib/python3.11/site-packages/mypyc/primitives/int_ops.py
Normal file
|
|
@ -0,0 +1,359 @@
|
|||
"""Arbitrary-precision integer primitive ops.
|
||||
|
||||
These mostly operate on (usually) unboxed integers that use a tagged pointer
|
||||
representation (CPyTagged) and correspond to the Python 'int' type.
|
||||
|
||||
See also the documentation for mypyc.rtypes.int_rprimitive.
|
||||
|
||||
Use mypyc.ir.ops.IntOp for operations on fixed-width/C integers.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from mypyc.ir.ops import (
|
||||
ERR_ALWAYS,
|
||||
ERR_MAGIC,
|
||||
ERR_MAGIC_OVERLAPPING,
|
||||
ERR_NEVER,
|
||||
PrimitiveDescription,
|
||||
)
|
||||
from mypyc.ir.rtypes import (
|
||||
RType,
|
||||
bit_rprimitive,
|
||||
bool_rprimitive,
|
||||
bytes_rprimitive,
|
||||
c_pyssize_t_rprimitive,
|
||||
float_rprimitive,
|
||||
int16_rprimitive,
|
||||
int32_rprimitive,
|
||||
int64_rprimitive,
|
||||
int_rprimitive,
|
||||
object_rprimitive,
|
||||
str_rprimitive,
|
||||
void_rtype,
|
||||
)
|
||||
from mypyc.primitives.registry import (
|
||||
binary_op,
|
||||
custom_op,
|
||||
function_op,
|
||||
load_address_op,
|
||||
method_op,
|
||||
unary_op,
|
||||
)
|
||||
|
||||
# Constructors for builtins.int and native int types have the same behavior. In
|
||||
# interpreted mode, native int types are just aliases to 'int'.
|
||||
for int_name in (
|
||||
"builtins.int",
|
||||
"mypy_extensions.i64",
|
||||
"mypy_extensions.i32",
|
||||
"mypy_extensions.i16",
|
||||
"mypy_extensions.u8",
|
||||
):
|
||||
# These int constructors produce object_rprimitives that then need to be unboxed
|
||||
# I guess unboxing ourselves would save a check and branch though?
|
||||
|
||||
# Get the type object for 'builtins.int' or a native int type.
|
||||
# For ordinary calls to int() we use a load_address to the type.
|
||||
# Native ints don't have a separate type object -- we just use 'builtins.int'.
|
||||
load_address_op(name=int_name, type=object_rprimitive, src="PyLong_Type")
|
||||
|
||||
# int(float). We could do a bit better directly.
|
||||
function_op(
|
||||
name=int_name,
|
||||
arg_types=[float_rprimitive],
|
||||
return_type=int_rprimitive,
|
||||
c_function_name="CPyTagged_FromFloat",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# int(string)
|
||||
function_op(
|
||||
name=int_name,
|
||||
arg_types=[str_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPyLong_FromStr",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# int(string, base)
|
||||
function_op(
|
||||
name=int_name,
|
||||
arg_types=[str_rprimitive, int_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPyLong_FromStrWithBase",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
for name in ("builtins.str", "builtins.repr"):
|
||||
# str(int) and repr(int)
|
||||
int_to_str_op = function_op(
|
||||
name=name,
|
||||
arg_types=[int_rprimitive],
|
||||
return_type=str_rprimitive,
|
||||
c_function_name="CPyTagged_Str",
|
||||
error_kind=ERR_MAGIC,
|
||||
priority=2,
|
||||
)
|
||||
# We need a specialization for str on bools also since the int one is wrong...
|
||||
function_op(
|
||||
name=name,
|
||||
arg_types=[bool_rprimitive],
|
||||
return_type=str_rprimitive,
|
||||
c_function_name="CPyBool_Str",
|
||||
error_kind=ERR_MAGIC,
|
||||
priority=3,
|
||||
)
|
||||
|
||||
int_to_ascii_op = custom_op(
|
||||
arg_types=[int_rprimitive],
|
||||
return_type=bytes_rprimitive,
|
||||
c_function_name="CPyTagged_AsciiBytes",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
|
||||
def int_binary_primitive(
|
||||
op: str, primitive_name: str, return_type: RType = int_rprimitive, error_kind: int = ERR_NEVER
|
||||
) -> PrimitiveDescription:
|
||||
return binary_op(
|
||||
name=op,
|
||||
arg_types=[int_rprimitive, int_rprimitive],
|
||||
return_type=return_type,
|
||||
primitive_name=primitive_name,
|
||||
error_kind=error_kind,
|
||||
)
|
||||
|
||||
|
||||
int_eq = int_binary_primitive(op="==", primitive_name="int_eq", return_type=bit_rprimitive)
|
||||
int_ne = int_binary_primitive(op="!=", primitive_name="int_ne", return_type=bit_rprimitive)
|
||||
int_lt = int_binary_primitive(op="<", primitive_name="int_lt", return_type=bit_rprimitive)
|
||||
int_le = int_binary_primitive(op="<=", primitive_name="int_le", return_type=bit_rprimitive)
|
||||
int_gt = int_binary_primitive(op=">", primitive_name="int_gt", return_type=bit_rprimitive)
|
||||
int_ge = int_binary_primitive(op=">=", primitive_name="int_ge", return_type=bit_rprimitive)
|
||||
|
||||
|
||||
def int_binary_op(
|
||||
name: str,
|
||||
c_function_name: str,
|
||||
return_type: RType = int_rprimitive,
|
||||
error_kind: int = ERR_NEVER,
|
||||
) -> None:
|
||||
binary_op(
|
||||
name=name,
|
||||
arg_types=[int_rprimitive, int_rprimitive],
|
||||
return_type=return_type,
|
||||
c_function_name=c_function_name,
|
||||
error_kind=error_kind,
|
||||
)
|
||||
|
||||
|
||||
# Binary, unary and augmented assignment operations that operate on CPyTagged ints
|
||||
# are implemented as C functions.
|
||||
|
||||
int_binary_op("+", "CPyTagged_Add")
|
||||
int_binary_op("-", "CPyTagged_Subtract")
|
||||
int_binary_op("*", "CPyTagged_Multiply")
|
||||
int_binary_op("&", "CPyTagged_And")
|
||||
int_binary_op("|", "CPyTagged_Or")
|
||||
int_binary_op("^", "CPyTagged_Xor")
|
||||
# Divide and remainder we honestly propagate errors from because they
|
||||
# can raise ZeroDivisionError
|
||||
int_binary_op("//", "CPyTagged_FloorDivide", error_kind=ERR_MAGIC)
|
||||
int_binary_op("%", "CPyTagged_Remainder", error_kind=ERR_MAGIC)
|
||||
# Negative shift counts raise an exception
|
||||
int_binary_op(">>", "CPyTagged_Rshift", error_kind=ERR_MAGIC)
|
||||
int_binary_op("<<", "CPyTagged_Lshift", error_kind=ERR_MAGIC)
|
||||
|
||||
int_binary_op(
|
||||
"/", "CPyTagged_TrueDivide", return_type=float_rprimitive, error_kind=ERR_MAGIC_OVERLAPPING
|
||||
)
|
||||
|
||||
# This should work because assignment operators are parsed differently
|
||||
# and the code in irbuild that handles it does the assignment
|
||||
# regardless of whether or not the operator works in place anyway.
|
||||
int_binary_op("+=", "CPyTagged_Add")
|
||||
int_binary_op("-=", "CPyTagged_Subtract")
|
||||
int_binary_op("*=", "CPyTagged_Multiply")
|
||||
int_binary_op("&=", "CPyTagged_And")
|
||||
int_binary_op("|=", "CPyTagged_Or")
|
||||
int_binary_op("^=", "CPyTagged_Xor")
|
||||
int_binary_op("//=", "CPyTagged_FloorDivide", error_kind=ERR_MAGIC)
|
||||
int_binary_op("%=", "CPyTagged_Remainder", error_kind=ERR_MAGIC)
|
||||
int_binary_op(">>=", "CPyTagged_Rshift", error_kind=ERR_MAGIC)
|
||||
int_binary_op("<<=", "CPyTagged_Lshift", error_kind=ERR_MAGIC)
|
||||
|
||||
|
||||
def int_unary_op(name: str, c_function_name: str) -> PrimitiveDescription:
|
||||
return unary_op(
|
||||
name=name,
|
||||
arg_type=int_rprimitive,
|
||||
return_type=int_rprimitive,
|
||||
c_function_name=c_function_name,
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
|
||||
int_neg_op = int_unary_op("-", "CPyTagged_Negate")
|
||||
int_invert_op = int_unary_op("~", "CPyTagged_Invert")
|
||||
|
||||
|
||||
# Primitives related to integer comparison operations:
|
||||
|
||||
|
||||
# Equals operation on two boxed tagged integers
|
||||
int_equal_ = custom_op(
|
||||
arg_types=[int_rprimitive, int_rprimitive],
|
||||
return_type=bit_rprimitive,
|
||||
c_function_name="CPyTagged_IsEq_",
|
||||
error_kind=ERR_NEVER,
|
||||
is_pure=True,
|
||||
)
|
||||
|
||||
# Less than operation on two boxed tagged integers
|
||||
int_less_than_ = custom_op(
|
||||
arg_types=[int_rprimitive, int_rprimitive],
|
||||
return_type=bit_rprimitive,
|
||||
c_function_name="CPyTagged_IsLt_",
|
||||
error_kind=ERR_NEVER,
|
||||
is_pure=True,
|
||||
)
|
||||
|
||||
int64_divide_op = custom_op(
|
||||
arg_types=[int64_rprimitive, int64_rprimitive],
|
||||
return_type=int64_rprimitive,
|
||||
c_function_name="CPyInt64_Divide",
|
||||
error_kind=ERR_MAGIC_OVERLAPPING,
|
||||
)
|
||||
|
||||
int64_mod_op = custom_op(
|
||||
arg_types=[int64_rprimitive, int64_rprimitive],
|
||||
return_type=int64_rprimitive,
|
||||
c_function_name="CPyInt64_Remainder",
|
||||
error_kind=ERR_MAGIC_OVERLAPPING,
|
||||
)
|
||||
|
||||
int32_divide_op = custom_op(
|
||||
arg_types=[int32_rprimitive, int32_rprimitive],
|
||||
return_type=int32_rprimitive,
|
||||
c_function_name="CPyInt32_Divide",
|
||||
error_kind=ERR_MAGIC_OVERLAPPING,
|
||||
)
|
||||
|
||||
int32_mod_op = custom_op(
|
||||
arg_types=[int32_rprimitive, int32_rprimitive],
|
||||
return_type=int32_rprimitive,
|
||||
c_function_name="CPyInt32_Remainder",
|
||||
error_kind=ERR_MAGIC_OVERLAPPING,
|
||||
)
|
||||
|
||||
int16_divide_op = custom_op(
|
||||
arg_types=[int16_rprimitive, int16_rprimitive],
|
||||
return_type=int16_rprimitive,
|
||||
c_function_name="CPyInt16_Divide",
|
||||
error_kind=ERR_MAGIC_OVERLAPPING,
|
||||
)
|
||||
|
||||
int16_mod_op = custom_op(
|
||||
arg_types=[int16_rprimitive, int16_rprimitive],
|
||||
return_type=int16_rprimitive,
|
||||
c_function_name="CPyInt16_Remainder",
|
||||
error_kind=ERR_MAGIC_OVERLAPPING,
|
||||
)
|
||||
|
||||
# Convert tagged int (as PyObject *) to i64
|
||||
int_to_int64_op = custom_op(
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=int64_rprimitive,
|
||||
c_function_name="CPyLong_AsInt64",
|
||||
error_kind=ERR_MAGIC_OVERLAPPING,
|
||||
)
|
||||
|
||||
ssize_t_to_int_op = custom_op(
|
||||
arg_types=[c_pyssize_t_rprimitive],
|
||||
return_type=int_rprimitive,
|
||||
c_function_name="CPyTagged_FromSsize_t",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
int64_to_int_op = custom_op(
|
||||
arg_types=[int64_rprimitive],
|
||||
return_type=int_rprimitive,
|
||||
c_function_name="CPyTagged_FromInt64",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# Convert tagged int (as PyObject *) to i32
|
||||
int_to_int32_op = custom_op(
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=int32_rprimitive,
|
||||
c_function_name="CPyLong_AsInt32",
|
||||
error_kind=ERR_MAGIC_OVERLAPPING,
|
||||
)
|
||||
|
||||
int32_overflow = custom_op(
|
||||
arg_types=[],
|
||||
return_type=void_rtype,
|
||||
c_function_name="CPyInt32_Overflow",
|
||||
error_kind=ERR_ALWAYS,
|
||||
)
|
||||
|
||||
int16_overflow = custom_op(
|
||||
arg_types=[],
|
||||
return_type=void_rtype,
|
||||
c_function_name="CPyInt16_Overflow",
|
||||
error_kind=ERR_ALWAYS,
|
||||
)
|
||||
|
||||
uint8_overflow = custom_op(
|
||||
arg_types=[],
|
||||
return_type=void_rtype,
|
||||
c_function_name="CPyUInt8_Overflow",
|
||||
error_kind=ERR_ALWAYS,
|
||||
)
|
||||
|
||||
# translate isinstance(obj, int)
|
||||
isinstance_int = function_op(
|
||||
name="builtints.isinstance",
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=bit_rprimitive,
|
||||
c_function_name="PyLong_Check",
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
# specialized custom_op cases for int.to_bytes
|
||||
|
||||
# int.to_bytes(length, "big")
|
||||
# int.to_bytes(length, "big", signed=...)
|
||||
int_to_big_endian_op = custom_op(
|
||||
arg_types=[int_rprimitive, c_pyssize_t_rprimitive, bool_rprimitive],
|
||||
return_type=bytes_rprimitive,
|
||||
c_function_name="CPyTagged_ToBigEndianBytes",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# int.to_bytes(length, "little")
|
||||
# int.to_bytes(length, "little", signed=...)
|
||||
int_to_little_endian_op = custom_op(
|
||||
arg_types=[int_rprimitive, c_pyssize_t_rprimitive, bool_rprimitive],
|
||||
return_type=bytes_rprimitive,
|
||||
c_function_name="CPyTagged_ToLittleEndianBytes",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# int.to_bytes(length, byteorder, signed=...)
|
||||
int_to_bytes_op = custom_op(
|
||||
arg_types=[int_rprimitive, c_pyssize_t_rprimitive, str_rprimitive, bool_rprimitive],
|
||||
return_type=bytes_rprimitive,
|
||||
c_function_name="CPyTagged_ToBytes",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# int.bit_length()
|
||||
method_op(
|
||||
name="bit_length",
|
||||
arg_types=[int_rprimitive],
|
||||
return_type=int_rprimitive,
|
||||
c_function_name="CPyTagged_BitLength",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
Binary file not shown.
|
|
@ -0,0 +1,428 @@
|
|||
from mypyc.ir.deps import BYTES_WRITER_EXTRA_OPS, LIBRT_STRINGS, STRING_WRITER_EXTRA_OPS
|
||||
from mypyc.ir.ops import ERR_MAGIC, ERR_MAGIC_OVERLAPPING, ERR_NEVER
|
||||
from mypyc.ir.rtypes import (
|
||||
bool_rprimitive,
|
||||
bytearray_rprimitive,
|
||||
bytes_rprimitive,
|
||||
bytes_writer_rprimitive,
|
||||
float_rprimitive,
|
||||
int16_rprimitive,
|
||||
int32_rprimitive,
|
||||
int64_rprimitive,
|
||||
none_rprimitive,
|
||||
short_int_rprimitive,
|
||||
str_rprimitive,
|
||||
string_writer_rprimitive,
|
||||
uint8_rprimitive,
|
||||
void_rtype,
|
||||
)
|
||||
from mypyc.primitives.registry import custom_primitive_op, function_op, method_op
|
||||
|
||||
function_op(
|
||||
name="librt.strings.BytesWriter",
|
||||
arg_types=[],
|
||||
return_type=bytes_writer_rprimitive,
|
||||
c_function_name="LibRTStrings_BytesWriter_internal",
|
||||
error_kind=ERR_MAGIC,
|
||||
experimental=True,
|
||||
dependencies=[LIBRT_STRINGS],
|
||||
)
|
||||
|
||||
method_op(
|
||||
name="getvalue",
|
||||
arg_types=[bytes_writer_rprimitive],
|
||||
return_type=bytes_rprimitive,
|
||||
c_function_name="LibRTStrings_BytesWriter_getvalue_internal",
|
||||
error_kind=ERR_MAGIC,
|
||||
experimental=True,
|
||||
dependencies=[LIBRT_STRINGS],
|
||||
)
|
||||
|
||||
method_op(
|
||||
name="write",
|
||||
arg_types=[bytes_writer_rprimitive, bytes_rprimitive],
|
||||
return_type=none_rprimitive,
|
||||
c_function_name="CPyBytesWriter_Write",
|
||||
error_kind=ERR_MAGIC,
|
||||
experimental=True,
|
||||
dependencies=[LIBRT_STRINGS, BYTES_WRITER_EXTRA_OPS],
|
||||
)
|
||||
|
||||
method_op(
|
||||
name="write",
|
||||
arg_types=[bytes_writer_rprimitive, bytearray_rprimitive],
|
||||
return_type=none_rprimitive,
|
||||
c_function_name="CPyBytesWriter_Write",
|
||||
error_kind=ERR_MAGIC,
|
||||
experimental=True,
|
||||
dependencies=[LIBRT_STRINGS, BYTES_WRITER_EXTRA_OPS],
|
||||
)
|
||||
|
||||
method_op(
|
||||
name="append",
|
||||
arg_types=[bytes_writer_rprimitive, uint8_rprimitive],
|
||||
return_type=none_rprimitive,
|
||||
c_function_name="CPyBytesWriter_Append",
|
||||
error_kind=ERR_MAGIC,
|
||||
experimental=True,
|
||||
dependencies=[LIBRT_STRINGS, BYTES_WRITER_EXTRA_OPS],
|
||||
)
|
||||
|
||||
method_op(
|
||||
name="truncate",
|
||||
arg_types=[bytes_writer_rprimitive, int64_rprimitive],
|
||||
return_type=none_rprimitive,
|
||||
c_function_name="LibRTStrings_BytesWriter_truncate_internal",
|
||||
error_kind=ERR_MAGIC,
|
||||
experimental=True,
|
||||
dependencies=[LIBRT_STRINGS],
|
||||
)
|
||||
|
||||
function_op(
|
||||
name="builtins.len",
|
||||
arg_types=[bytes_writer_rprimitive],
|
||||
return_type=short_int_rprimitive,
|
||||
c_function_name="CPyBytesWriter_Len",
|
||||
error_kind=ERR_NEVER,
|
||||
experimental=True,
|
||||
dependencies=[LIBRT_STRINGS, BYTES_WRITER_EXTRA_OPS],
|
||||
)
|
||||
|
||||
# BytesWriter index adjustment - convert negative index to positive
|
||||
bytes_writer_adjust_index_op = custom_primitive_op(
|
||||
name="bytes_writer_adjust_index",
|
||||
arg_types=[bytes_writer_rprimitive, int64_rprimitive],
|
||||
return_type=int64_rprimitive,
|
||||
c_function_name="CPyBytesWriter_AdjustIndex",
|
||||
error_kind=ERR_NEVER,
|
||||
experimental=True,
|
||||
dependencies=[LIBRT_STRINGS, BYTES_WRITER_EXTRA_OPS],
|
||||
)
|
||||
|
||||
# BytesWriter range check - check if index is in valid range
|
||||
bytes_writer_range_check_op = custom_primitive_op(
|
||||
name="bytes_writer_range_check",
|
||||
arg_types=[bytes_writer_rprimitive, int64_rprimitive],
|
||||
return_type=bool_rprimitive,
|
||||
c_function_name="CPyBytesWriter_RangeCheck",
|
||||
error_kind=ERR_NEVER,
|
||||
experimental=True,
|
||||
dependencies=[LIBRT_STRINGS, BYTES_WRITER_EXTRA_OPS],
|
||||
)
|
||||
|
||||
# BytesWriter.__getitem__() - get byte at index (no bounds checking)
|
||||
bytes_writer_get_item_unsafe_op = custom_primitive_op(
|
||||
name="bytes_writer_get_item",
|
||||
arg_types=[bytes_writer_rprimitive, int64_rprimitive],
|
||||
return_type=uint8_rprimitive,
|
||||
c_function_name="CPyBytesWriter_GetItem",
|
||||
error_kind=ERR_NEVER,
|
||||
experimental=True,
|
||||
dependencies=[LIBRT_STRINGS, BYTES_WRITER_EXTRA_OPS],
|
||||
)
|
||||
|
||||
# BytesWriter.__setitem__() - set byte at index (no bounds checking)
|
||||
bytes_writer_set_item_unsafe_op = custom_primitive_op(
|
||||
name="bytes_writer_set_item",
|
||||
arg_types=[bytes_writer_rprimitive, int64_rprimitive, uint8_rprimitive],
|
||||
return_type=void_rtype,
|
||||
c_function_name="CPyBytesWriter_SetItem",
|
||||
error_kind=ERR_NEVER,
|
||||
experimental=True,
|
||||
dependencies=[LIBRT_STRINGS, BYTES_WRITER_EXTRA_OPS],
|
||||
)
|
||||
|
||||
# i16 write/read functions
|
||||
|
||||
function_op(
|
||||
name="librt.strings.write_i16_le",
|
||||
arg_types=[bytes_writer_rprimitive, int16_rprimitive],
|
||||
return_type=none_rprimitive,
|
||||
c_function_name="CPyBytesWriter_WriteI16LE",
|
||||
error_kind=ERR_MAGIC,
|
||||
experimental=True,
|
||||
dependencies=[LIBRT_STRINGS, BYTES_WRITER_EXTRA_OPS],
|
||||
)
|
||||
|
||||
function_op(
|
||||
name="librt.strings.write_i16_be",
|
||||
arg_types=[bytes_writer_rprimitive, int16_rprimitive],
|
||||
return_type=none_rprimitive,
|
||||
c_function_name="CPyBytesWriter_WriteI16BE",
|
||||
error_kind=ERR_MAGIC,
|
||||
experimental=True,
|
||||
dependencies=[LIBRT_STRINGS, BYTES_WRITER_EXTRA_OPS],
|
||||
)
|
||||
|
||||
function_op(
|
||||
name="librt.strings.read_i16_le",
|
||||
arg_types=[bytes_rprimitive, int64_rprimitive],
|
||||
return_type=int16_rprimitive,
|
||||
c_function_name="CPyBytes_ReadI16LE",
|
||||
error_kind=ERR_MAGIC_OVERLAPPING,
|
||||
experimental=True,
|
||||
dependencies=[LIBRT_STRINGS, BYTES_WRITER_EXTRA_OPS],
|
||||
)
|
||||
|
||||
function_op(
|
||||
name="librt.strings.read_i16_be",
|
||||
arg_types=[bytes_rprimitive, int64_rprimitive],
|
||||
return_type=int16_rprimitive,
|
||||
c_function_name="CPyBytes_ReadI16BE",
|
||||
error_kind=ERR_MAGIC_OVERLAPPING,
|
||||
experimental=True,
|
||||
dependencies=[LIBRT_STRINGS, BYTES_WRITER_EXTRA_OPS],
|
||||
)
|
||||
|
||||
# i32 write/read functions
|
||||
|
||||
function_op(
|
||||
name="librt.strings.write_i32_le",
|
||||
arg_types=[bytes_writer_rprimitive, int32_rprimitive],
|
||||
return_type=none_rprimitive,
|
||||
c_function_name="CPyBytesWriter_WriteI32LE",
|
||||
error_kind=ERR_MAGIC,
|
||||
experimental=True,
|
||||
dependencies=[LIBRT_STRINGS, BYTES_WRITER_EXTRA_OPS],
|
||||
)
|
||||
|
||||
function_op(
|
||||
name="librt.strings.write_i32_be",
|
||||
arg_types=[bytes_writer_rprimitive, int32_rprimitive],
|
||||
return_type=none_rprimitive,
|
||||
c_function_name="CPyBytesWriter_WriteI32BE",
|
||||
error_kind=ERR_MAGIC,
|
||||
experimental=True,
|
||||
dependencies=[LIBRT_STRINGS, BYTES_WRITER_EXTRA_OPS],
|
||||
)
|
||||
|
||||
function_op(
|
||||
name="librt.strings.read_i32_le",
|
||||
arg_types=[bytes_rprimitive, int64_rprimitive],
|
||||
return_type=int32_rprimitive,
|
||||
c_function_name="CPyBytes_ReadI32LE",
|
||||
error_kind=ERR_MAGIC_OVERLAPPING,
|
||||
experimental=True,
|
||||
dependencies=[LIBRT_STRINGS, BYTES_WRITER_EXTRA_OPS],
|
||||
)
|
||||
|
||||
function_op(
|
||||
name="librt.strings.read_i32_be",
|
||||
arg_types=[bytes_rprimitive, int64_rprimitive],
|
||||
return_type=int32_rprimitive,
|
||||
c_function_name="CPyBytes_ReadI32BE",
|
||||
error_kind=ERR_MAGIC_OVERLAPPING,
|
||||
experimental=True,
|
||||
dependencies=[LIBRT_STRINGS, BYTES_WRITER_EXTRA_OPS],
|
||||
)
|
||||
|
||||
# i64 write/read functions
|
||||
|
||||
function_op(
|
||||
name="librt.strings.write_i64_le",
|
||||
arg_types=[bytes_writer_rprimitive, int64_rprimitive],
|
||||
return_type=none_rprimitive,
|
||||
c_function_name="CPyBytesWriter_WriteI64LE",
|
||||
error_kind=ERR_MAGIC,
|
||||
experimental=True,
|
||||
dependencies=[LIBRT_STRINGS, BYTES_WRITER_EXTRA_OPS],
|
||||
)
|
||||
|
||||
function_op(
|
||||
name="librt.strings.write_i64_be",
|
||||
arg_types=[bytes_writer_rprimitive, int64_rprimitive],
|
||||
return_type=none_rprimitive,
|
||||
c_function_name="CPyBytesWriter_WriteI64BE",
|
||||
error_kind=ERR_MAGIC,
|
||||
experimental=True,
|
||||
dependencies=[LIBRT_STRINGS, BYTES_WRITER_EXTRA_OPS],
|
||||
)
|
||||
|
||||
function_op(
|
||||
name="librt.strings.read_i64_le",
|
||||
arg_types=[bytes_rprimitive, int64_rprimitive],
|
||||
return_type=int64_rprimitive,
|
||||
c_function_name="CPyBytes_ReadI64LE",
|
||||
error_kind=ERR_MAGIC_OVERLAPPING,
|
||||
experimental=True,
|
||||
dependencies=[LIBRT_STRINGS, BYTES_WRITER_EXTRA_OPS],
|
||||
)
|
||||
|
||||
function_op(
|
||||
name="librt.strings.read_i64_be",
|
||||
arg_types=[bytes_rprimitive, int64_rprimitive],
|
||||
return_type=int64_rprimitive,
|
||||
c_function_name="CPyBytes_ReadI64BE",
|
||||
error_kind=ERR_MAGIC_OVERLAPPING,
|
||||
experimental=True,
|
||||
dependencies=[LIBRT_STRINGS, BYTES_WRITER_EXTRA_OPS],
|
||||
)
|
||||
|
||||
# f32 write/read functions
|
||||
|
||||
function_op(
|
||||
name="librt.strings.write_f32_le",
|
||||
arg_types=[bytes_writer_rprimitive, float_rprimitive],
|
||||
return_type=none_rprimitive,
|
||||
c_function_name="CPyBytesWriter_WriteF32LE",
|
||||
error_kind=ERR_MAGIC,
|
||||
experimental=True,
|
||||
dependencies=[LIBRT_STRINGS, BYTES_WRITER_EXTRA_OPS],
|
||||
)
|
||||
|
||||
function_op(
|
||||
name="librt.strings.write_f32_be",
|
||||
arg_types=[bytes_writer_rprimitive, float_rprimitive],
|
||||
return_type=none_rprimitive,
|
||||
c_function_name="CPyBytesWriter_WriteF32BE",
|
||||
error_kind=ERR_MAGIC,
|
||||
experimental=True,
|
||||
dependencies=[LIBRT_STRINGS, BYTES_WRITER_EXTRA_OPS],
|
||||
)
|
||||
|
||||
function_op(
|
||||
name="librt.strings.read_f32_le",
|
||||
arg_types=[bytes_rprimitive, int64_rprimitive],
|
||||
return_type=float_rprimitive,
|
||||
c_function_name="CPyBytes_ReadF32LE",
|
||||
error_kind=ERR_MAGIC_OVERLAPPING,
|
||||
experimental=True,
|
||||
dependencies=[LIBRT_STRINGS, BYTES_WRITER_EXTRA_OPS],
|
||||
)
|
||||
|
||||
function_op(
|
||||
name="librt.strings.read_f32_be",
|
||||
arg_types=[bytes_rprimitive, int64_rprimitive],
|
||||
return_type=float_rprimitive,
|
||||
c_function_name="CPyBytes_ReadF32BE",
|
||||
error_kind=ERR_MAGIC_OVERLAPPING,
|
||||
experimental=True,
|
||||
dependencies=[LIBRT_STRINGS, BYTES_WRITER_EXTRA_OPS],
|
||||
)
|
||||
|
||||
# f64 write/read functions
|
||||
|
||||
function_op(
|
||||
name="librt.strings.write_f64_le",
|
||||
arg_types=[bytes_writer_rprimitive, float_rprimitive],
|
||||
return_type=none_rprimitive,
|
||||
c_function_name="CPyBytesWriter_WriteF64LE",
|
||||
error_kind=ERR_MAGIC,
|
||||
experimental=True,
|
||||
dependencies=[LIBRT_STRINGS, BYTES_WRITER_EXTRA_OPS],
|
||||
)
|
||||
|
||||
function_op(
|
||||
name="librt.strings.write_f64_be",
|
||||
arg_types=[bytes_writer_rprimitive, float_rprimitive],
|
||||
return_type=none_rprimitive,
|
||||
c_function_name="CPyBytesWriter_WriteF64BE",
|
||||
error_kind=ERR_MAGIC,
|
||||
experimental=True,
|
||||
dependencies=[LIBRT_STRINGS, BYTES_WRITER_EXTRA_OPS],
|
||||
)
|
||||
|
||||
function_op(
|
||||
name="librt.strings.read_f64_le",
|
||||
arg_types=[bytes_rprimitive, int64_rprimitive],
|
||||
return_type=float_rprimitive,
|
||||
c_function_name="CPyBytes_ReadF64LE",
|
||||
error_kind=ERR_MAGIC_OVERLAPPING,
|
||||
experimental=True,
|
||||
dependencies=[LIBRT_STRINGS, BYTES_WRITER_EXTRA_OPS],
|
||||
)
|
||||
|
||||
function_op(
|
||||
name="librt.strings.read_f64_be",
|
||||
arg_types=[bytes_rprimitive, int64_rprimitive],
|
||||
return_type=float_rprimitive,
|
||||
c_function_name="CPyBytes_ReadF64BE",
|
||||
error_kind=ERR_MAGIC_OVERLAPPING,
|
||||
experimental=True,
|
||||
dependencies=[LIBRT_STRINGS, BYTES_WRITER_EXTRA_OPS],
|
||||
)
|
||||
|
||||
# StringWriter operations
|
||||
|
||||
function_op(
|
||||
name="librt.strings.StringWriter",
|
||||
arg_types=[],
|
||||
return_type=string_writer_rprimitive,
|
||||
c_function_name="LibRTStrings_StringWriter_internal",
|
||||
error_kind=ERR_MAGIC,
|
||||
experimental=True,
|
||||
dependencies=[LIBRT_STRINGS],
|
||||
)
|
||||
|
||||
method_op(
|
||||
name="getvalue",
|
||||
arg_types=[string_writer_rprimitive],
|
||||
return_type=str_rprimitive,
|
||||
c_function_name="LibRTStrings_StringWriter_getvalue_internal",
|
||||
error_kind=ERR_MAGIC,
|
||||
experimental=True,
|
||||
dependencies=[LIBRT_STRINGS],
|
||||
)
|
||||
|
||||
method_op(
|
||||
name="write",
|
||||
arg_types=[string_writer_rprimitive, str_rprimitive],
|
||||
return_type=none_rprimitive,
|
||||
c_function_name="LibRTStrings_StringWriter_write_internal",
|
||||
error_kind=ERR_MAGIC,
|
||||
experimental=True,
|
||||
dependencies=[LIBRT_STRINGS],
|
||||
)
|
||||
|
||||
method_op(
|
||||
name="append",
|
||||
arg_types=[string_writer_rprimitive, int32_rprimitive],
|
||||
return_type=none_rprimitive,
|
||||
c_function_name="CPyStringWriter_Append",
|
||||
error_kind=ERR_MAGIC,
|
||||
experimental=True,
|
||||
dependencies=[LIBRT_STRINGS, STRING_WRITER_EXTRA_OPS],
|
||||
)
|
||||
|
||||
function_op(
|
||||
name="builtins.len",
|
||||
arg_types=[string_writer_rprimitive],
|
||||
return_type=short_int_rprimitive,
|
||||
c_function_name="CPyStringWriter_Len",
|
||||
error_kind=ERR_NEVER,
|
||||
experimental=True,
|
||||
dependencies=[LIBRT_STRINGS, STRING_WRITER_EXTRA_OPS],
|
||||
)
|
||||
|
||||
# StringWriter index adjustment - convert negative index to positive
|
||||
string_writer_adjust_index_op = custom_primitive_op(
|
||||
name="string_writer_adjust_index",
|
||||
arg_types=[string_writer_rprimitive, int64_rprimitive],
|
||||
return_type=int64_rprimitive,
|
||||
c_function_name="CPyStringWriter_AdjustIndex",
|
||||
error_kind=ERR_NEVER,
|
||||
experimental=True,
|
||||
dependencies=[LIBRT_STRINGS, STRING_WRITER_EXTRA_OPS],
|
||||
)
|
||||
|
||||
# StringWriter range check - check if index is in valid range
|
||||
string_writer_range_check_op = custom_primitive_op(
|
||||
name="string_writer_range_check",
|
||||
arg_types=[string_writer_rprimitive, int64_rprimitive],
|
||||
return_type=bool_rprimitive,
|
||||
c_function_name="CPyStringWriter_RangeCheck",
|
||||
error_kind=ERR_NEVER,
|
||||
experimental=True,
|
||||
dependencies=[LIBRT_STRINGS, STRING_WRITER_EXTRA_OPS],
|
||||
)
|
||||
|
||||
# StringWriter.__getitem__() - get character at index (no bounds checking)
|
||||
string_writer_get_item_unsafe_op = custom_primitive_op(
|
||||
name="string_writer_get_item",
|
||||
arg_types=[string_writer_rprimitive, int64_rprimitive],
|
||||
return_type=int32_rprimitive,
|
||||
c_function_name="CPyStringWriter_GetItem",
|
||||
error_kind=ERR_NEVER,
|
||||
experimental=True,
|
||||
dependencies=[LIBRT_STRINGS, STRING_WRITER_EXTRA_OPS],
|
||||
)
|
||||
Binary file not shown.
|
|
@ -0,0 +1,14 @@
|
|||
from mypyc.ir.deps import LIBRT_TIME
|
||||
from mypyc.ir.ops import ERR_MAGIC_OVERLAPPING
|
||||
from mypyc.ir.rtypes import float_rprimitive
|
||||
from mypyc.primitives.registry import function_op
|
||||
|
||||
function_op(
|
||||
name="librt.time.time",
|
||||
arg_types=[],
|
||||
return_type=float_rprimitive,
|
||||
c_function_name="LibRTTime_time",
|
||||
error_kind=ERR_MAGIC_OVERLAPPING,
|
||||
experimental=True,
|
||||
dependencies=[LIBRT_TIME],
|
||||
)
|
||||
Binary file not shown.
|
|
@ -0,0 +1,15 @@
|
|||
from mypyc.ir.deps import LIBRT_VECS, VECS_EXTRA_OPS
|
||||
from mypyc.ir.ops import ERR_NEVER
|
||||
from mypyc.ir.rtypes import bit_rprimitive, object_rprimitive
|
||||
from mypyc.primitives.registry import function_op
|
||||
|
||||
# isinstance(obj, vec)
|
||||
isinstance_vec = function_op(
|
||||
name="builtins.isinstance",
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=bit_rprimitive,
|
||||
c_function_name="CPyVec_Check",
|
||||
error_kind=ERR_NEVER,
|
||||
experimental=True,
|
||||
dependencies=[LIBRT_VECS, VECS_EXTRA_OPS],
|
||||
)
|
||||
Binary file not shown.
374
venv/lib/python3.11/site-packages/mypyc/primitives/list_ops.py
Normal file
374
venv/lib/python3.11/site-packages/mypyc/primitives/list_ops.py
Normal file
|
|
@ -0,0 +1,374 @@
|
|||
"""List primitive ops."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from mypyc.ir.ops import ERR_FALSE, ERR_MAGIC, ERR_NEVER
|
||||
from mypyc.ir.rtypes import (
|
||||
bit_rprimitive,
|
||||
c_int_rprimitive,
|
||||
c_pyssize_t_rprimitive,
|
||||
int64_rprimitive,
|
||||
int_rprimitive,
|
||||
list_rprimitive,
|
||||
object_rprimitive,
|
||||
pointer_rprimitive,
|
||||
short_int_rprimitive,
|
||||
void_rtype,
|
||||
)
|
||||
from mypyc.primitives.registry import (
|
||||
ERR_NEG_INT,
|
||||
binary_op,
|
||||
custom_op,
|
||||
custom_primitive_op,
|
||||
function_op,
|
||||
load_address_op,
|
||||
method_op,
|
||||
)
|
||||
|
||||
# Get the 'builtins.list' type object.
|
||||
load_address_op(name="builtins.list", type=object_rprimitive, src="PyList_Type")
|
||||
|
||||
# sorted(obj)
|
||||
function_op(
|
||||
name="builtins.sorted",
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=list_rprimitive,
|
||||
c_function_name="CPySequence_Sort",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# list(obj)
|
||||
to_list = function_op(
|
||||
name="builtins.list",
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=list_rprimitive,
|
||||
c_function_name="PySequence_List",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# Construct an empty list via list().
|
||||
function_op(
|
||||
name="builtins.list",
|
||||
arg_types=[],
|
||||
return_type=list_rprimitive,
|
||||
c_function_name="PyList_New",
|
||||
error_kind=ERR_MAGIC,
|
||||
extra_int_constants=[(0, int_rprimitive)],
|
||||
)
|
||||
|
||||
# translate isinstance(obj, list)
|
||||
isinstance_list = function_op(
|
||||
name="builtins.isinstance",
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=bit_rprimitive,
|
||||
c_function_name="PyList_Check",
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
new_list_op = custom_op(
|
||||
arg_types=[c_pyssize_t_rprimitive],
|
||||
return_type=list_rprimitive,
|
||||
c_function_name="PyList_New",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
list_build_op = custom_op(
|
||||
arg_types=[c_pyssize_t_rprimitive],
|
||||
return_type=list_rprimitive,
|
||||
c_function_name="CPyList_Build",
|
||||
error_kind=ERR_MAGIC,
|
||||
var_arg_type=object_rprimitive,
|
||||
steals=True,
|
||||
)
|
||||
|
||||
# Get pointer to list items (ob_item PyListObject field)
|
||||
list_items = custom_primitive_op(
|
||||
name="list_items",
|
||||
arg_types=[list_rprimitive],
|
||||
return_type=pointer_rprimitive,
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
# list[index] (for an integer index)
|
||||
list_get_item_op = method_op(
|
||||
name="__getitem__",
|
||||
arg_types=[list_rprimitive, int_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPyList_GetItem",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# list[index] version with no int tag check for when it is known to be short
|
||||
method_op(
|
||||
name="__getitem__",
|
||||
arg_types=[list_rprimitive, short_int_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPyList_GetItemShort",
|
||||
error_kind=ERR_MAGIC,
|
||||
priority=2,
|
||||
)
|
||||
|
||||
# list[index] that produces a borrowed result
|
||||
method_op(
|
||||
name="__getitem__",
|
||||
arg_types=[list_rprimitive, int_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPyList_GetItemBorrow",
|
||||
error_kind=ERR_MAGIC,
|
||||
is_borrowed=True,
|
||||
priority=3,
|
||||
)
|
||||
|
||||
# list[index] that produces a borrowed result and index is known to be short
|
||||
method_op(
|
||||
name="__getitem__",
|
||||
arg_types=[list_rprimitive, short_int_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPyList_GetItemShortBorrow",
|
||||
error_kind=ERR_MAGIC,
|
||||
is_borrowed=True,
|
||||
priority=4,
|
||||
)
|
||||
|
||||
# Version with native int index
|
||||
method_op(
|
||||
name="__getitem__",
|
||||
arg_types=[list_rprimitive, int64_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPyList_GetItemInt64",
|
||||
error_kind=ERR_MAGIC,
|
||||
priority=5,
|
||||
)
|
||||
|
||||
# Version with native int index
|
||||
method_op(
|
||||
name="__getitem__",
|
||||
arg_types=[list_rprimitive, int64_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPyList_GetItemInt64Borrow",
|
||||
is_borrowed=True,
|
||||
error_kind=ERR_MAGIC,
|
||||
priority=6,
|
||||
)
|
||||
|
||||
# This is unsafe because it assumes that the index is a non-negative integer
|
||||
# that is in-bounds for the list.
|
||||
list_get_item_unsafe_op = custom_primitive_op(
|
||||
name="list_get_item_unsafe",
|
||||
arg_types=[list_rprimitive, c_pyssize_t_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
# list[index] = obj
|
||||
list_set_item_op = method_op(
|
||||
name="__setitem__",
|
||||
arg_types=[list_rprimitive, int_rprimitive, object_rprimitive],
|
||||
return_type=bit_rprimitive,
|
||||
c_function_name="CPyList_SetItem",
|
||||
error_kind=ERR_FALSE,
|
||||
steals=[False, False, True],
|
||||
)
|
||||
|
||||
# list[index_i64] = obj
|
||||
method_op(
|
||||
name="__setitem__",
|
||||
arg_types=[list_rprimitive, int64_rprimitive, object_rprimitive],
|
||||
return_type=bit_rprimitive,
|
||||
c_function_name="CPyList_SetItemInt64",
|
||||
error_kind=ERR_FALSE,
|
||||
steals=[False, False, True],
|
||||
priority=2,
|
||||
)
|
||||
|
||||
# PyList_SET_ITEM does no error checking,
|
||||
# and should only be used to fill in brand new lists.
|
||||
new_list_set_item_op = custom_op(
|
||||
arg_types=[list_rprimitive, c_pyssize_t_rprimitive, object_rprimitive],
|
||||
return_type=void_rtype,
|
||||
c_function_name="CPyList_SetItemUnsafe",
|
||||
error_kind=ERR_NEVER,
|
||||
steals=[False, False, True],
|
||||
)
|
||||
|
||||
# list.append(obj)
|
||||
list_append_op = method_op(
|
||||
name="append",
|
||||
arg_types=[list_rprimitive, object_rprimitive],
|
||||
return_type=c_int_rprimitive,
|
||||
c_function_name="PyList_Append",
|
||||
error_kind=ERR_NEG_INT,
|
||||
)
|
||||
|
||||
# list.extend(obj)
|
||||
list_extend_op = method_op(
|
||||
name="extend",
|
||||
arg_types=[list_rprimitive, object_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPyList_Extend",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# list.pop()
|
||||
list_pop_last = method_op(
|
||||
name="pop",
|
||||
arg_types=[list_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPyList_PopLast",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# list.pop(index)
|
||||
method_op(
|
||||
name="pop",
|
||||
arg_types=[list_rprimitive, int_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPyList_Pop",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# list.count(obj)
|
||||
method_op(
|
||||
name="count",
|
||||
arg_types=[list_rprimitive, object_rprimitive],
|
||||
return_type=short_int_rprimitive,
|
||||
c_function_name="CPyList_Count",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# list.insert(index, obj)
|
||||
method_op(
|
||||
name="insert",
|
||||
arg_types=[list_rprimitive, int_rprimitive, object_rprimitive],
|
||||
return_type=c_int_rprimitive,
|
||||
c_function_name="CPyList_Insert",
|
||||
error_kind=ERR_NEG_INT,
|
||||
)
|
||||
|
||||
# list.sort()
|
||||
method_op(
|
||||
name="sort",
|
||||
arg_types=[list_rprimitive],
|
||||
return_type=c_int_rprimitive,
|
||||
c_function_name="PyList_Sort",
|
||||
error_kind=ERR_NEG_INT,
|
||||
)
|
||||
|
||||
# list.reverse()
|
||||
method_op(
|
||||
name="reverse",
|
||||
arg_types=[list_rprimitive],
|
||||
return_type=c_int_rprimitive,
|
||||
c_function_name="PyList_Reverse",
|
||||
error_kind=ERR_NEG_INT,
|
||||
)
|
||||
|
||||
# list.remove(obj)
|
||||
method_op(
|
||||
name="remove",
|
||||
arg_types=[list_rprimitive, object_rprimitive],
|
||||
return_type=c_int_rprimitive,
|
||||
c_function_name="CPyList_Remove",
|
||||
error_kind=ERR_NEG_INT,
|
||||
)
|
||||
|
||||
# list.index(obj)
|
||||
method_op(
|
||||
name="index",
|
||||
arg_types=[list_rprimitive, object_rprimitive],
|
||||
return_type=int_rprimitive,
|
||||
c_function_name="CPyList_Index",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# list.clear()
|
||||
method_op(
|
||||
name="clear",
|
||||
arg_types=[list_rprimitive],
|
||||
return_type=bit_rprimitive,
|
||||
c_function_name="CPyList_Clear",
|
||||
error_kind=ERR_FALSE,
|
||||
)
|
||||
|
||||
# list.copy()
|
||||
method_op(
|
||||
name="copy",
|
||||
arg_types=[list_rprimitive],
|
||||
return_type=list_rprimitive,
|
||||
c_function_name="CPyList_Copy",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# list + list
|
||||
binary_op(
|
||||
name="+",
|
||||
arg_types=[list_rprimitive, list_rprimitive],
|
||||
return_type=list_rprimitive,
|
||||
c_function_name="PySequence_Concat",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# list += list
|
||||
binary_op(
|
||||
name="+=",
|
||||
arg_types=[list_rprimitive, object_rprimitive],
|
||||
return_type=list_rprimitive,
|
||||
c_function_name="PySequence_InPlaceConcat",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# list * int
|
||||
binary_op(
|
||||
name="*",
|
||||
arg_types=[list_rprimitive, int_rprimitive],
|
||||
return_type=list_rprimitive,
|
||||
c_function_name="CPySequence_Multiply",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# int * list
|
||||
binary_op(
|
||||
name="*",
|
||||
arg_types=[int_rprimitive, list_rprimitive],
|
||||
return_type=list_rprimitive,
|
||||
c_function_name="CPySequence_RMultiply",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# list *= int
|
||||
binary_op(
|
||||
name="*=",
|
||||
arg_types=[list_rprimitive, int_rprimitive],
|
||||
return_type=list_rprimitive,
|
||||
c_function_name="CPySequence_InPlaceMultiply",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# list[begin:end]
|
||||
list_slice_op = custom_op(
|
||||
arg_types=[list_rprimitive, int_rprimitive, int_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPyList_GetSlice",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
supports_sequence_protocol = custom_op(
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=c_int_rprimitive,
|
||||
c_function_name="CPySequence_Check",
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
sequence_get_item = custom_op(
|
||||
arg_types=[object_rprimitive, c_pyssize_t_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="PySequence_GetItem",
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
sequence_get_slice = custom_op(
|
||||
arg_types=[object_rprimitive, c_pyssize_t_rprimitive, c_pyssize_t_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="PySequence_GetSlice",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
Binary file not shown.
604
venv/lib/python3.11/site-packages/mypyc/primitives/misc_ops.py
Normal file
604
venv/lib/python3.11/site-packages/mypyc/primitives/misc_ops.py
Normal file
|
|
@ -0,0 +1,604 @@
|
|||
"""Miscellaneous primitive ops."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from mypyc.ir.deps import LIBRT_BASE64
|
||||
from mypyc.ir.ops import ERR_FALSE, ERR_MAGIC, ERR_MAGIC_OVERLAPPING, ERR_NEVER
|
||||
from mypyc.ir.rtypes import (
|
||||
KNOWN_NATIVE_TYPES,
|
||||
RUnion,
|
||||
bit_rprimitive,
|
||||
bool_rprimitive,
|
||||
bytes_rprimitive,
|
||||
c_int_rprimitive,
|
||||
c_pointer_rprimitive,
|
||||
c_pyssize_t_rprimitive,
|
||||
cstring_rprimitive,
|
||||
dict_rprimitive,
|
||||
float_rprimitive,
|
||||
int_rprimitive,
|
||||
none_rprimitive,
|
||||
object_pointer_rprimitive,
|
||||
object_rprimitive,
|
||||
pointer_rprimitive,
|
||||
str_rprimitive,
|
||||
uint8_rprimitive,
|
||||
void_rtype,
|
||||
)
|
||||
from mypyc.primitives.registry import (
|
||||
ERR_NEG_INT,
|
||||
custom_op,
|
||||
custom_primitive_op,
|
||||
function_op,
|
||||
load_address_op,
|
||||
method_op,
|
||||
)
|
||||
|
||||
# Get the 'bool' type object.
|
||||
load_address_op(name="builtins.bool", type=object_rprimitive, src="PyBool_Type")
|
||||
|
||||
# Get the 'range' type object.
|
||||
load_address_op(name="builtins.range", type=object_rprimitive, src="PyRange_Type")
|
||||
|
||||
# Get the boxed Python 'None' object
|
||||
none_object_op = load_address_op(name="Py_None", type=object_rprimitive, src="_Py_NoneStruct")
|
||||
|
||||
# Get the boxed object '...'
|
||||
ellipsis_op = load_address_op(name="...", type=object_rprimitive, src="_Py_EllipsisObject")
|
||||
|
||||
# Get the boxed NotImplemented object
|
||||
not_implemented_op = load_address_op(
|
||||
name="builtins.NotImplemented", type=object_rprimitive, src="_Py_NotImplementedStruct"
|
||||
)
|
||||
|
||||
# Get the boxed StopAsyncIteration object
|
||||
stop_async_iteration_op = load_address_op(
|
||||
name="builtins.StopAsyncIteration", type=object_rprimitive, src="PyExc_StopAsyncIteration"
|
||||
)
|
||||
|
||||
# id(obj)
|
||||
function_op(
|
||||
name="builtins.id",
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=int_rprimitive,
|
||||
c_function_name="CPyTagged_Id",
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
# Return the result of obj.__await()__ or obj.__iter__() (if no __await__ exists)
|
||||
coro_op = custom_op(
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPy_GetCoro",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# Do obj.send(value), or a next(obj) if second arg is None.
|
||||
# (This behavior is to match the PEP 380 spec for yield from.)
|
||||
# Like next_raw_op, don't swallow StopIteration,
|
||||
# but also don't propagate an error.
|
||||
# Can return NULL: see next_op.
|
||||
send_op = custom_op(
|
||||
arg_types=[object_rprimitive, object_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPyIter_Send",
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
# This is sort of unfortunate but oh well: yield_from_except performs most of the
|
||||
# error handling logic in `yield from` operations. It returns a bool and passes
|
||||
# a value by address.
|
||||
# If the bool is true, then a StopIteration was received and we should return.
|
||||
# If the bool is false, then the value should be yielded.
|
||||
# The normal case is probably that it signals an exception, which gets
|
||||
# propagated.
|
||||
# Op used for "yield from" error handling.
|
||||
# See comment in CPy_YieldFromErrorHandle for more information.
|
||||
yield_from_except_op = custom_op(
|
||||
arg_types=[object_rprimitive, object_pointer_rprimitive],
|
||||
return_type=bool_rprimitive,
|
||||
c_function_name="CPy_YieldFromErrorHandle",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# Create method object from a callable object and self.
|
||||
method_new_op = custom_op(
|
||||
arg_types=[object_rprimitive, object_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="PyMethod_New",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# Check if the current exception is a StopIteration and return its value if so.
|
||||
# Treats "no exception" as StopIteration with a None value.
|
||||
# If it is a different exception, re-reraise it.
|
||||
check_stop_op = custom_op(
|
||||
arg_types=[],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPy_FetchStopIterationValue",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# Determine the most derived metaclass and check for metaclass conflicts.
|
||||
# Arguments are (metaclass, bases).
|
||||
py_calc_meta_op = custom_op(
|
||||
arg_types=[object_rprimitive, object_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPy_CalculateMetaclass",
|
||||
error_kind=ERR_MAGIC,
|
||||
is_borrowed=True,
|
||||
)
|
||||
|
||||
# Import a module using the Python import system.
|
||||
import_op = custom_op(
|
||||
arg_types=[str_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="PyImport_Import",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# Import a native same-group module directly via C-level init/exec functions.
|
||||
native_import_op = custom_op(
|
||||
# (module name, init-only function, exec function, module static,
|
||||
# shared lib __file__, ext suffix, is_package)
|
||||
arg_types=[
|
||||
str_rprimitive,
|
||||
c_pointer_rprimitive,
|
||||
c_pointer_rprimitive,
|
||||
object_pointer_rprimitive,
|
||||
object_rprimitive,
|
||||
str_rprimitive,
|
||||
c_pyssize_t_rprimitive,
|
||||
],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPyImport_ImportNative",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# Table-driven import op.
|
||||
import_many_op = custom_op(
|
||||
arg_types=[
|
||||
object_rprimitive,
|
||||
c_pointer_rprimitive,
|
||||
object_rprimitive,
|
||||
object_rprimitive,
|
||||
object_rprimitive,
|
||||
c_pointer_rprimitive,
|
||||
],
|
||||
return_type=bit_rprimitive,
|
||||
c_function_name="CPyImport_ImportMany",
|
||||
error_kind=ERR_FALSE,
|
||||
)
|
||||
|
||||
# From import helper op
|
||||
import_from_many_op = custom_op(
|
||||
arg_types=[object_rprimitive, object_rprimitive, object_rprimitive, object_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPyImport_ImportFromMany",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# Get attributes from an already-imported native module and store them in globals.
|
||||
get_native_attrs_op = custom_op(
|
||||
arg_types=[object_rprimitive, object_rprimitive, object_rprimitive, object_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPyImport_GetNativeAttrs",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# Get the sys.modules dictionary
|
||||
get_module_dict_op = custom_op(
|
||||
arg_types=[],
|
||||
return_type=dict_rprimitive,
|
||||
c_function_name="PyImport_GetModuleDict",
|
||||
error_kind=ERR_NEVER,
|
||||
is_borrowed=True,
|
||||
)
|
||||
|
||||
# isinstance(obj, cls)
|
||||
slow_isinstance_op = function_op(
|
||||
name="builtins.isinstance",
|
||||
arg_types=[object_rprimitive, object_rprimitive],
|
||||
return_type=c_int_rprimitive,
|
||||
c_function_name="PyObject_IsInstance",
|
||||
error_kind=ERR_NEG_INT,
|
||||
truncated_type=bool_rprimitive,
|
||||
)
|
||||
|
||||
# Faster isinstance(obj, cls) that only works with native classes and doesn't perform
|
||||
# type checking of the type argument.
|
||||
fast_isinstance_op = function_op(
|
||||
"builtins.isinstance",
|
||||
arg_types=[object_rprimitive, object_rprimitive],
|
||||
return_type=bool_rprimitive,
|
||||
c_function_name="CPy_TypeCheck",
|
||||
error_kind=ERR_NEVER,
|
||||
priority=0,
|
||||
)
|
||||
|
||||
# bool(obj) with unboxed result
|
||||
bool_op = function_op(
|
||||
name="builtins.bool",
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=c_int_rprimitive,
|
||||
c_function_name="PyObject_IsTrue",
|
||||
error_kind=ERR_NEG_INT,
|
||||
truncated_type=bool_rprimitive,
|
||||
)
|
||||
|
||||
# isinstance(obj, bool)
|
||||
isinstance_bool = function_op(
|
||||
name="builtins.isinstance",
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=bit_rprimitive,
|
||||
c_function_name="PyBool_Check",
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
# slice(start, stop, step)
|
||||
new_slice_op = function_op(
|
||||
name="builtins.slice",
|
||||
arg_types=[object_rprimitive, object_rprimitive, object_rprimitive],
|
||||
c_function_name="PySlice_New",
|
||||
return_type=object_rprimitive,
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# type(obj)
|
||||
type_op = function_op(
|
||||
name="builtins.type",
|
||||
arg_types=[object_rprimitive],
|
||||
c_function_name="CPy_TYPE",
|
||||
return_type=object_rprimitive,
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
# Get 'builtins.type' (base class of all classes)
|
||||
type_object_op = load_address_op(name="builtins.type", type=object_rprimitive, src="PyType_Type")
|
||||
|
||||
# Create a heap type based on a template non-heap type.
|
||||
# See CPyType_FromTemplate for more docs.
|
||||
pytype_from_template_op = custom_op(
|
||||
arg_types=[object_rprimitive, object_rprimitive, str_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPyType_FromTemplate",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# Call __init_subclass__ on a type. Separated from CPyType_FromTemplate
|
||||
# so that class attributes can be set before __init_subclass__ is called.
|
||||
py_init_subclass_op = custom_op(
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=bool_rprimitive,
|
||||
c_function_name="CPy_InitSubclass",
|
||||
error_kind=ERR_FALSE,
|
||||
)
|
||||
|
||||
# Create a dataclass from an extension class. See
|
||||
# CPyDataclass_SleightOfHand for more docs.
|
||||
dataclass_sleight_of_hand = custom_op(
|
||||
arg_types=[
|
||||
object_rprimitive,
|
||||
object_rprimitive,
|
||||
dict_rprimitive,
|
||||
dict_rprimitive,
|
||||
str_rprimitive,
|
||||
],
|
||||
return_type=bit_rprimitive,
|
||||
c_function_name="CPyDataclass_SleightOfHand",
|
||||
error_kind=ERR_FALSE,
|
||||
)
|
||||
|
||||
# Raise ValueError if length of first argument is not equal to the second argument.
|
||||
# The first argument must be a list or a variable-length tuple.
|
||||
check_unpack_count_op = custom_op(
|
||||
arg_types=[object_rprimitive, c_pyssize_t_rprimitive],
|
||||
return_type=c_int_rprimitive,
|
||||
c_function_name="CPySequence_CheckUnpackCount",
|
||||
error_kind=ERR_NEG_INT,
|
||||
)
|
||||
|
||||
|
||||
# Register an implementation for a singledispatch function
|
||||
register_function = custom_op(
|
||||
arg_types=[object_rprimitive, object_rprimitive, object_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPySingledispatch_RegisterFunction",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
|
||||
# Initialize a PyObject * item in a memory buffer (steal the value)
|
||||
buf_init_item = custom_primitive_op(
|
||||
name="buf_init_item",
|
||||
arg_types=[pointer_rprimitive, c_pyssize_t_rprimitive, object_rprimitive],
|
||||
return_type=void_rtype,
|
||||
error_kind=ERR_NEVER,
|
||||
steals=[False, False, True],
|
||||
)
|
||||
|
||||
# Get length of PyVarObject instance (e.g. list or tuple)
|
||||
var_object_size = custom_primitive_op(
|
||||
name="var_object_size",
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=c_pyssize_t_rprimitive,
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
# Set the lazy value compute function of an TypeAliasType instance (Python 3.12+).
|
||||
# This must only be used as part of initializing the object. Any existing value
|
||||
# will be cleared.
|
||||
set_type_alias_compute_function_op = custom_primitive_op(
|
||||
name="set_type_alias_compute_function",
|
||||
c_function_name="CPy_SetTypeAliasTypeComputeFunction",
|
||||
# (alias object, value compute function)
|
||||
arg_types=[object_rprimitive, object_rprimitive],
|
||||
return_type=void_rtype,
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
debug_print_op = custom_primitive_op(
|
||||
name="debug_print",
|
||||
c_function_name="CPyDebug_PrintObject",
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=void_rtype,
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
# Log an event to a trace log, which is written to a file during execution.
|
||||
log_trace_event = custom_primitive_op(
|
||||
name="log_trace_event",
|
||||
c_function_name="CPyTrace_LogEvent",
|
||||
# (fullname of function/location, line number, operation name, operation details)
|
||||
arg_types=[cstring_rprimitive, cstring_rprimitive, cstring_rprimitive, cstring_rprimitive],
|
||||
return_type=void_rtype,
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
# Mark object as immortal -- it won't be freed via reference counting, as
|
||||
# the reference count won't be updated any longer. Immortal objects support
|
||||
# fast concurrent read-only access from multiple threads when using free
|
||||
# threading, since this eliminates contention from concurrent reference count
|
||||
# updates.
|
||||
#
|
||||
# Needs at least Python 3.14.
|
||||
set_immortal_op = custom_primitive_op(
|
||||
name="set_immmortal",
|
||||
c_function_name="CPy_SetImmortal",
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=void_rtype,
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
write_buffer_rprimitive = KNOWN_NATIVE_TYPES["librt.internal.WriteBuffer"]
|
||||
read_buffer_rprimitive = KNOWN_NATIVE_TYPES["librt.internal.ReadBuffer"]
|
||||
|
||||
# ReadBuffer(source)
|
||||
function_op(
|
||||
name="librt.internal.ReadBuffer",
|
||||
arg_types=[bytes_rprimitive],
|
||||
return_type=read_buffer_rprimitive,
|
||||
c_function_name="ReadBuffer_internal",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# WriteBuffer()
|
||||
function_op(
|
||||
name="librt.internal.WriteBuffer",
|
||||
arg_types=[],
|
||||
return_type=write_buffer_rprimitive,
|
||||
c_function_name="WriteBuffer_internal",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
method_op(
|
||||
name="getvalue",
|
||||
arg_types=[write_buffer_rprimitive],
|
||||
return_type=bytes_rprimitive,
|
||||
c_function_name="WriteBuffer_getvalue_internal",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
function_op(
|
||||
name="librt.internal.write_bool",
|
||||
arg_types=[object_rprimitive, bool_rprimitive],
|
||||
return_type=none_rprimitive,
|
||||
c_function_name="write_bool_internal",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
function_op(
|
||||
name="librt.internal.read_bool",
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=bool_rprimitive,
|
||||
c_function_name="read_bool_internal",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
function_op(
|
||||
name="librt.internal.write_str",
|
||||
arg_types=[object_rprimitive, str_rprimitive],
|
||||
return_type=none_rprimitive,
|
||||
c_function_name="write_str_internal",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
function_op(
|
||||
name="librt.internal.read_str",
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=str_rprimitive,
|
||||
c_function_name="read_str_internal",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
function_op(
|
||||
name="librt.internal.write_bytes",
|
||||
arg_types=[object_rprimitive, bytes_rprimitive],
|
||||
return_type=none_rprimitive,
|
||||
c_function_name="write_bytes_internal",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
function_op(
|
||||
name="librt.internal.read_bytes",
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=bytes_rprimitive,
|
||||
c_function_name="read_bytes_internal",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
function_op(
|
||||
name="librt.internal.write_float",
|
||||
arg_types=[object_rprimitive, float_rprimitive],
|
||||
return_type=none_rprimitive,
|
||||
c_function_name="write_float_internal",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
function_op(
|
||||
name="librt.internal.read_float",
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=float_rprimitive,
|
||||
c_function_name="read_float_internal",
|
||||
error_kind=ERR_MAGIC_OVERLAPPING,
|
||||
)
|
||||
|
||||
function_op(
|
||||
name="librt.internal.write_int",
|
||||
arg_types=[object_rprimitive, int_rprimitive],
|
||||
return_type=none_rprimitive,
|
||||
c_function_name="write_int_internal",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
function_op(
|
||||
name="librt.internal.read_int",
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=int_rprimitive,
|
||||
c_function_name="read_int_internal",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
function_op(
|
||||
name="librt.internal.write_tag",
|
||||
arg_types=[object_rprimitive, uint8_rprimitive],
|
||||
return_type=none_rprimitive,
|
||||
c_function_name="write_tag_internal",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
function_op(
|
||||
name="librt.internal.read_tag",
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=uint8_rprimitive,
|
||||
c_function_name="read_tag_internal",
|
||||
error_kind=ERR_MAGIC_OVERLAPPING,
|
||||
)
|
||||
|
||||
function_op(
|
||||
name="librt.internal.cache_version",
|
||||
arg_types=[],
|
||||
return_type=uint8_rprimitive,
|
||||
c_function_name="cache_version_internal",
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
function_op(
|
||||
name="librt.base64.b64encode",
|
||||
arg_types=[bytes_rprimitive],
|
||||
return_type=bytes_rprimitive,
|
||||
c_function_name="LibRTBase64_b64encode_internal",
|
||||
error_kind=ERR_MAGIC,
|
||||
extra_int_constants=[(0, bool_rprimitive)],
|
||||
experimental=True,
|
||||
dependencies=[LIBRT_BASE64],
|
||||
)
|
||||
|
||||
function_op(
|
||||
name="librt.base64.urlsafe_b64encode",
|
||||
arg_types=[bytes_rprimitive],
|
||||
return_type=bytes_rprimitive,
|
||||
c_function_name="LibRTBase64_b64encode_internal",
|
||||
error_kind=ERR_MAGIC,
|
||||
extra_int_constants=[(1, bool_rprimitive)],
|
||||
experimental=True,
|
||||
dependencies=[LIBRT_BASE64],
|
||||
)
|
||||
|
||||
function_op(
|
||||
name="librt.base64.b64decode",
|
||||
arg_types=[RUnion([bytes_rprimitive, str_rprimitive])],
|
||||
return_type=bytes_rprimitive,
|
||||
c_function_name="LibRTBase64_b64decode_internal",
|
||||
error_kind=ERR_MAGIC,
|
||||
extra_int_constants=[(0, bool_rprimitive)],
|
||||
experimental=True,
|
||||
dependencies=[LIBRT_BASE64],
|
||||
)
|
||||
|
||||
function_op(
|
||||
name="librt.base64.urlsafe_b64decode",
|
||||
arg_types=[RUnion([bytes_rprimitive, str_rprimitive])],
|
||||
return_type=bytes_rprimitive,
|
||||
c_function_name="LibRTBase64_b64decode_internal",
|
||||
error_kind=ERR_MAGIC,
|
||||
extra_int_constants=[(1, bool_rprimitive)],
|
||||
experimental=True,
|
||||
dependencies=[LIBRT_BASE64],
|
||||
)
|
||||
|
||||
cpyfunction_get_name = function_op(
|
||||
name="CPyFunction_get_name",
|
||||
arg_types=[object_rprimitive, c_pointer_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPyFunction_get_name",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
cpyfunction_set_name = function_op(
|
||||
name="CPyFunction_set_name",
|
||||
arg_types=[object_rprimitive, object_rprimitive, c_pointer_rprimitive],
|
||||
return_type=c_int_rprimitive,
|
||||
c_function_name="CPyFunction_set_name",
|
||||
error_kind=ERR_NEG_INT,
|
||||
)
|
||||
|
||||
cpyfunction_get_code = function_op(
|
||||
name="CPyFunction_get_code",
|
||||
arg_types=[object_rprimitive, c_pointer_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPyFunction_get_code",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
cpyfunction_get_defaults = function_op(
|
||||
name="CPyFunction_get_defaults",
|
||||
arg_types=[object_rprimitive, c_pointer_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPyFunction_get_defaults",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
cpyfunction_get_kwdefaults = function_op(
|
||||
name="CPyFunction_get_kwdefaults",
|
||||
arg_types=[object_rprimitive, c_pointer_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPyFunction_get_kwdefaults",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
cpyfunction_get_annotations = function_op(
|
||||
name="CPyFunction_get_annotations",
|
||||
arg_types=[object_rprimitive, c_pointer_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPyFunction_get_annotations",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
cpyfunction_set_annotations = function_op(
|
||||
name="CPyFunction_set_annotations",
|
||||
arg_types=[object_rprimitive, object_rprimitive, c_pointer_rprimitive],
|
||||
return_type=c_int_rprimitive,
|
||||
c_function_name="CPyFunction_set_annotations",
|
||||
error_kind=ERR_NEG_INT,
|
||||
)
|
||||
Binary file not shown.
402
venv/lib/python3.11/site-packages/mypyc/primitives/registry.py
Normal file
402
venv/lib/python3.11/site-packages/mypyc/primitives/registry.py
Normal file
|
|
@ -0,0 +1,402 @@
|
|||
"""Utilities for defining primitive ops.
|
||||
|
||||
Most of the ops can be automatically generated by matching against AST
|
||||
nodes and types. For example, a func_op is automatically generated when
|
||||
a specific function is called with the specific positional argument
|
||||
count and argument types.
|
||||
|
||||
Example op definition:
|
||||
|
||||
list_len_op = function_op(name='builtins.len',
|
||||
arg_types=[list_rprimitive],
|
||||
result_type=short_int_rprimitive,
|
||||
error_kind=ERR_NEVER,
|
||||
c_function_name="...")
|
||||
|
||||
This op is automatically generated for calls to len() with a single
|
||||
list argument. The result type is short_int_rprimitive, and this
|
||||
never raises an exception (ERR_NEVER). The function c_function_name is
|
||||
called when generating C for this op. The op can also be manually generated
|
||||
using "list_len_op". Ops that are only generated automatically don't need to
|
||||
be assigned to a module attribute.
|
||||
|
||||
Ops defined with custom[_primitive]_op are only explicitly generated in
|
||||
mypyc.irbuild and won't be generated automatically. They are always
|
||||
assigned to a module attribute, as otherwise they won't be accessible.
|
||||
|
||||
The actual ops are defined in other submodules of this package, grouped
|
||||
by category.
|
||||
|
||||
Most operations have fallback implementations that apply to all possible
|
||||
arguments and types. For example, there are generic implementations of
|
||||
arbitrary function and method calls, and binary operators. These generic
|
||||
implementations are typically slower than specialized ones, but we tend
|
||||
to rely on them for infrequently used ops. It's impractical to have
|
||||
optimized implementations of all ops.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Final, NamedTuple
|
||||
|
||||
from mypyc.ir.deps import Dependency
|
||||
from mypyc.ir.ops import PrimitiveDescription, StealsDescription
|
||||
from mypyc.ir.rtypes import RType
|
||||
|
||||
# Error kind for functions that return negative integer on exception. This
|
||||
# is only used for primitives. We translate it away during IR building.
|
||||
ERR_NEG_INT: Final = 10
|
||||
|
||||
|
||||
class CFunctionDescription(NamedTuple):
|
||||
name: str
|
||||
arg_types: list[RType]
|
||||
return_type: RType
|
||||
var_arg_type: RType | None
|
||||
truncated_type: RType | None
|
||||
c_function_name: str
|
||||
error_kind: int
|
||||
steals: StealsDescription
|
||||
is_borrowed: bool
|
||||
ordering: list[int] | None
|
||||
extra_int_constants: list[tuple[int, RType]]
|
||||
priority: int
|
||||
is_pure: bool
|
||||
returns_null: bool
|
||||
dependencies: list[Dependency] | None
|
||||
|
||||
|
||||
# A description for C load operations including LoadGlobal and LoadAddress
|
||||
class LoadAddressDescription(NamedTuple):
|
||||
name: str
|
||||
type: RType
|
||||
src: str # name of the target to load
|
||||
|
||||
|
||||
# Primitive ops for method call (such as 'str.join')
|
||||
method_call_ops: dict[str, list[PrimitiveDescription]] = {}
|
||||
|
||||
# Primitive ops for top level function call (such as 'builtins.list')
|
||||
function_ops: dict[str, list[PrimitiveDescription]] = {}
|
||||
|
||||
# Primitive ops for binary operations
|
||||
binary_ops: dict[str, list[PrimitiveDescription]] = {}
|
||||
|
||||
# Primitive ops for unary ops
|
||||
unary_ops: dict[str, list[PrimitiveDescription]] = {}
|
||||
|
||||
builtin_names: dict[str, tuple[RType, str]] = {}
|
||||
|
||||
|
||||
def method_op(
|
||||
name: str,
|
||||
arg_types: list[RType],
|
||||
return_type: RType,
|
||||
c_function_name: str,
|
||||
error_kind: int,
|
||||
var_arg_type: RType | None = None,
|
||||
truncated_type: RType | None = None,
|
||||
ordering: list[int] | None = None,
|
||||
extra_int_constants: list[tuple[int, RType]] | None = None,
|
||||
steals: StealsDescription = False,
|
||||
is_borrowed: bool = False,
|
||||
priority: int = 1,
|
||||
is_pure: bool = False,
|
||||
experimental: bool = False,
|
||||
dependencies: list[Dependency] | None = None,
|
||||
) -> PrimitiveDescription:
|
||||
"""Define a c function call op that replaces a method call.
|
||||
|
||||
This will be automatically generated by matching against the AST.
|
||||
|
||||
Args:
|
||||
name: short name of the method (for example, 'append')
|
||||
arg_types: argument types; the receiver is always the first argument
|
||||
return_type: type of the return value. Use void_rtype to represent void.
|
||||
c_function_name: name of the C function to call
|
||||
error_kind: how errors are represented in the result (one of ERR_*)
|
||||
var_arg_type: type of all variable arguments
|
||||
truncated_type: type to truncated to(See Truncate for info)
|
||||
if it's defined both return_type and it should be non-referenced
|
||||
integer types or bool type
|
||||
ordering: optional ordering of the arguments, if defined,
|
||||
reorders the arguments accordingly.
|
||||
should never be used together with var_arg_type.
|
||||
all the other arguments(such as arg_types) are in the order
|
||||
accepted by the python syntax(before reordering)
|
||||
extra_int_constants: optional extra integer constants as the last arguments to a C call
|
||||
steals: description of arguments that this steals (ref count wise)
|
||||
is_borrowed: if True, returned value is borrowed (no need to decrease refcount)
|
||||
priority: if multiple ops match, the one with the highest priority is picked
|
||||
is_pure: if True, declare that the C function has no side effects, takes immutable
|
||||
arguments, and never raises an exception
|
||||
"""
|
||||
if extra_int_constants is None:
|
||||
extra_int_constants = []
|
||||
ops = method_call_ops.setdefault(name, [])
|
||||
desc = PrimitiveDescription(
|
||||
name,
|
||||
arg_types,
|
||||
return_type,
|
||||
var_arg_type,
|
||||
truncated_type,
|
||||
c_function_name,
|
||||
error_kind,
|
||||
steals,
|
||||
is_borrowed,
|
||||
ordering,
|
||||
extra_int_constants,
|
||||
priority,
|
||||
is_pure=is_pure,
|
||||
experimental=experimental,
|
||||
dependencies=dependencies,
|
||||
)
|
||||
ops.append(desc)
|
||||
return desc
|
||||
|
||||
|
||||
def function_op(
|
||||
name: str,
|
||||
arg_types: list[RType],
|
||||
return_type: RType,
|
||||
c_function_name: str,
|
||||
error_kind: int,
|
||||
var_arg_type: RType | None = None,
|
||||
truncated_type: RType | None = None,
|
||||
ordering: list[int] | None = None,
|
||||
extra_int_constants: list[tuple[int, RType]] | None = None,
|
||||
steals: StealsDescription = False,
|
||||
is_borrowed: bool = False,
|
||||
priority: int = 1,
|
||||
experimental: bool = False,
|
||||
dependencies: list[Dependency] | None = None,
|
||||
) -> PrimitiveDescription:
|
||||
"""Define a C function call op that replaces a function call.
|
||||
|
||||
This will be automatically generated by matching against the AST.
|
||||
|
||||
Most arguments are similar to method_op().
|
||||
|
||||
Args:
|
||||
name: full name of the function
|
||||
arg_types: positional argument types for which this applies
|
||||
"""
|
||||
if extra_int_constants is None:
|
||||
extra_int_constants = []
|
||||
ops = function_ops.setdefault(name, [])
|
||||
desc = PrimitiveDescription(
|
||||
name,
|
||||
arg_types,
|
||||
return_type,
|
||||
var_arg_type=var_arg_type,
|
||||
truncated_type=truncated_type,
|
||||
c_function_name=c_function_name,
|
||||
error_kind=error_kind,
|
||||
steals=steals,
|
||||
is_borrowed=is_borrowed,
|
||||
ordering=ordering,
|
||||
extra_int_constants=extra_int_constants,
|
||||
priority=priority,
|
||||
is_pure=False,
|
||||
experimental=experimental,
|
||||
dependencies=dependencies,
|
||||
)
|
||||
ops.append(desc)
|
||||
return desc
|
||||
|
||||
|
||||
def binary_op(
|
||||
name: str,
|
||||
arg_types: list[RType],
|
||||
return_type: RType,
|
||||
error_kind: int,
|
||||
c_function_name: str | None = None,
|
||||
primitive_name: str | None = None,
|
||||
var_arg_type: RType | None = None,
|
||||
truncated_type: RType | None = None,
|
||||
ordering: list[int] | None = None,
|
||||
extra_int_constants: list[tuple[int, RType]] | None = None,
|
||||
steals: StealsDescription = False,
|
||||
is_borrowed: bool = False,
|
||||
priority: int = 1,
|
||||
dependencies: list[Dependency] | None = None,
|
||||
) -> PrimitiveDescription:
|
||||
"""Define a c function call op for a binary operation.
|
||||
|
||||
This will be automatically generated by matching against the AST.
|
||||
|
||||
Most arguments are similar to method_op(), but exactly two argument types
|
||||
are expected.
|
||||
"""
|
||||
assert c_function_name is not None or primitive_name is not None
|
||||
assert not (c_function_name is not None and primitive_name is not None)
|
||||
if extra_int_constants is None:
|
||||
extra_int_constants = []
|
||||
ops = binary_ops.setdefault(name, [])
|
||||
desc = PrimitiveDescription(
|
||||
name=primitive_name or name,
|
||||
arg_types=arg_types,
|
||||
return_type=return_type,
|
||||
var_arg_type=var_arg_type,
|
||||
truncated_type=truncated_type,
|
||||
c_function_name=c_function_name,
|
||||
error_kind=error_kind,
|
||||
steals=steals,
|
||||
is_borrowed=is_borrowed,
|
||||
ordering=ordering,
|
||||
extra_int_constants=extra_int_constants,
|
||||
priority=priority,
|
||||
is_pure=False,
|
||||
experimental=False,
|
||||
dependencies=dependencies,
|
||||
)
|
||||
ops.append(desc)
|
||||
return desc
|
||||
|
||||
|
||||
def custom_op(
|
||||
arg_types: list[RType],
|
||||
return_type: RType,
|
||||
c_function_name: str,
|
||||
error_kind: int,
|
||||
var_arg_type: RType | None = None,
|
||||
truncated_type: RType | None = None,
|
||||
ordering: list[int] | None = None,
|
||||
extra_int_constants: list[tuple[int, RType]] | None = None,
|
||||
steals: StealsDescription = False,
|
||||
is_borrowed: bool = False,
|
||||
*,
|
||||
is_pure: bool = False,
|
||||
returns_null: bool = False,
|
||||
) -> CFunctionDescription:
|
||||
"""Create a one-off CallC op that can't be automatically generated from the AST.
|
||||
|
||||
Most arguments are similar to method_op().
|
||||
"""
|
||||
if extra_int_constants is None:
|
||||
extra_int_constants = []
|
||||
return CFunctionDescription(
|
||||
"<custom>",
|
||||
arg_types,
|
||||
return_type,
|
||||
var_arg_type,
|
||||
truncated_type,
|
||||
c_function_name,
|
||||
error_kind,
|
||||
steals,
|
||||
is_borrowed,
|
||||
ordering,
|
||||
extra_int_constants,
|
||||
0,
|
||||
is_pure=is_pure,
|
||||
returns_null=returns_null,
|
||||
dependencies=None,
|
||||
)
|
||||
|
||||
|
||||
def custom_primitive_op(
|
||||
name: str,
|
||||
arg_types: list[RType],
|
||||
return_type: RType,
|
||||
error_kind: int,
|
||||
c_function_name: str | None = None,
|
||||
var_arg_type: RType | None = None,
|
||||
truncated_type: RType | None = None,
|
||||
ordering: list[int] | None = None,
|
||||
extra_int_constants: list[tuple[int, RType]] | None = None,
|
||||
steals: StealsDescription = False,
|
||||
is_borrowed: bool = False,
|
||||
is_pure: bool = False,
|
||||
experimental: bool = False,
|
||||
dependencies: list[Dependency] | None = None,
|
||||
) -> PrimitiveDescription:
|
||||
"""Define a primitive op that can't be automatically generated based on the AST.
|
||||
|
||||
Most arguments are similar to method_op().
|
||||
"""
|
||||
if extra_int_constants is None:
|
||||
extra_int_constants = []
|
||||
return PrimitiveDescription(
|
||||
name=name,
|
||||
arg_types=arg_types,
|
||||
return_type=return_type,
|
||||
var_arg_type=var_arg_type,
|
||||
truncated_type=truncated_type,
|
||||
c_function_name=c_function_name,
|
||||
error_kind=error_kind,
|
||||
steals=steals,
|
||||
is_borrowed=is_borrowed,
|
||||
ordering=ordering,
|
||||
extra_int_constants=extra_int_constants,
|
||||
priority=0,
|
||||
is_pure=is_pure,
|
||||
experimental=experimental,
|
||||
dependencies=dependencies,
|
||||
)
|
||||
|
||||
|
||||
def unary_op(
|
||||
name: str,
|
||||
arg_type: RType,
|
||||
return_type: RType,
|
||||
c_function_name: str,
|
||||
error_kind: int,
|
||||
truncated_type: RType | None = None,
|
||||
ordering: list[int] | None = None,
|
||||
extra_int_constants: list[tuple[int, RType]] | None = None,
|
||||
steals: StealsDescription = False,
|
||||
is_borrowed: bool = False,
|
||||
priority: int = 1,
|
||||
is_pure: bool = False,
|
||||
dependencies: list[Dependency] | None = None,
|
||||
) -> PrimitiveDescription:
|
||||
"""Define a primitive op for an unary operation.
|
||||
|
||||
This will be automatically generated by matching against the AST.
|
||||
|
||||
Most arguments are similar to method_op(), but exactly one argument type
|
||||
is expected.
|
||||
"""
|
||||
if extra_int_constants is None:
|
||||
extra_int_constants = []
|
||||
ops = unary_ops.setdefault(name, [])
|
||||
desc = PrimitiveDescription(
|
||||
name,
|
||||
[arg_type],
|
||||
return_type,
|
||||
var_arg_type=None,
|
||||
truncated_type=truncated_type,
|
||||
c_function_name=c_function_name,
|
||||
error_kind=error_kind,
|
||||
steals=steals,
|
||||
is_borrowed=is_borrowed,
|
||||
ordering=ordering,
|
||||
extra_int_constants=extra_int_constants,
|
||||
priority=priority,
|
||||
is_pure=is_pure,
|
||||
experimental=False,
|
||||
dependencies=dependencies,
|
||||
)
|
||||
ops.append(desc)
|
||||
return desc
|
||||
|
||||
|
||||
def load_address_op(name: str, type: RType, src: str) -> LoadAddressDescription:
|
||||
assert name not in builtin_names, "already defined: %s" % name
|
||||
builtin_names[name] = (type, src)
|
||||
return LoadAddressDescription(name, type, src)
|
||||
|
||||
|
||||
# Import various modules that set up global state.
|
||||
import mypyc.primitives.bytearray_ops
|
||||
import mypyc.primitives.bytes_ops
|
||||
import mypyc.primitives.dict_ops
|
||||
import mypyc.primitives.float_ops
|
||||
import mypyc.primitives.int_ops
|
||||
import mypyc.primitives.librt_strings_ops
|
||||
import mypyc.primitives.librt_time_ops
|
||||
import mypyc.primitives.list_ops
|
||||
import mypyc.primitives.misc_ops
|
||||
import mypyc.primitives.str_ops
|
||||
import mypyc.primitives.tuple_ops
|
||||
import mypyc.primitives.weakref_ops # noqa: F401
|
||||
Binary file not shown.
161
venv/lib/python3.11/site-packages/mypyc/primitives/set_ops.py
Normal file
161
venv/lib/python3.11/site-packages/mypyc/primitives/set_ops.py
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
"""Primitive set and frozenset ops."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from mypyc.ir.ops import ERR_FALSE, ERR_MAGIC, ERR_NEVER
|
||||
from mypyc.ir.rtypes import (
|
||||
bit_rprimitive,
|
||||
bool_rprimitive,
|
||||
c_int_rprimitive,
|
||||
frozenset_rprimitive,
|
||||
object_rprimitive,
|
||||
pointer_rprimitive,
|
||||
set_rprimitive,
|
||||
)
|
||||
from mypyc.primitives.registry import (
|
||||
ERR_NEG_INT,
|
||||
binary_op,
|
||||
function_op,
|
||||
load_address_op,
|
||||
method_op,
|
||||
)
|
||||
|
||||
# Get the 'builtins.set' type object.
|
||||
load_address_op(name="builtins.set", type=object_rprimitive, src="PySet_Type")
|
||||
|
||||
# Get the 'builtins.frozenset' type object.
|
||||
load_address_op(name="builtins.frozenset", type=object_rprimitive, src="PyFrozenSet_Type")
|
||||
|
||||
# Construct an empty set.
|
||||
new_set_op = function_op(
|
||||
name="builtins.set",
|
||||
arg_types=[],
|
||||
return_type=set_rprimitive,
|
||||
c_function_name="PySet_New",
|
||||
error_kind=ERR_MAGIC,
|
||||
extra_int_constants=[(0, pointer_rprimitive)],
|
||||
)
|
||||
|
||||
# set(obj)
|
||||
function_op(
|
||||
name="builtins.set",
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=set_rprimitive,
|
||||
c_function_name="PySet_New",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# Construct an empty frozenset
|
||||
function_op(
|
||||
name="builtins.frozenset",
|
||||
arg_types=[],
|
||||
return_type=frozenset_rprimitive,
|
||||
c_function_name="PyFrozenSet_New",
|
||||
error_kind=ERR_MAGIC,
|
||||
extra_int_constants=[(0, pointer_rprimitive)],
|
||||
)
|
||||
|
||||
# frozenset(obj)
|
||||
function_op(
|
||||
name="builtins.frozenset",
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=frozenset_rprimitive,
|
||||
c_function_name="PyFrozenSet_New",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# translate isinstance(obj, set)
|
||||
isinstance_set = function_op(
|
||||
name="builtins.isinstance",
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=bit_rprimitive,
|
||||
c_function_name="PySet_Check",
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
# translate isinstance(obj, frozenset)
|
||||
isinstance_frozenset = function_op(
|
||||
name="builtins.isinstance",
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=bit_rprimitive,
|
||||
c_function_name="PyFrozenSet_Check",
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
# item in set
|
||||
set_in_op = binary_op(
|
||||
name="in",
|
||||
arg_types=[object_rprimitive, set_rprimitive],
|
||||
return_type=c_int_rprimitive,
|
||||
c_function_name="PySet_Contains",
|
||||
error_kind=ERR_NEG_INT,
|
||||
truncated_type=bool_rprimitive,
|
||||
ordering=[1, 0],
|
||||
)
|
||||
|
||||
# item in frozenset
|
||||
binary_op(
|
||||
name="in",
|
||||
arg_types=[object_rprimitive, frozenset_rprimitive],
|
||||
return_type=c_int_rprimitive,
|
||||
c_function_name="PySet_Contains",
|
||||
error_kind=ERR_NEG_INT,
|
||||
truncated_type=bool_rprimitive,
|
||||
ordering=[1, 0],
|
||||
)
|
||||
|
||||
# set.remove(obj)
|
||||
method_op(
|
||||
name="remove",
|
||||
arg_types=[set_rprimitive, object_rprimitive],
|
||||
return_type=bit_rprimitive,
|
||||
c_function_name="CPySet_Remove",
|
||||
error_kind=ERR_FALSE,
|
||||
)
|
||||
|
||||
# set.discard(obj)
|
||||
method_op(
|
||||
name="discard",
|
||||
arg_types=[set_rprimitive, object_rprimitive],
|
||||
return_type=c_int_rprimitive,
|
||||
c_function_name="PySet_Discard",
|
||||
error_kind=ERR_NEG_INT,
|
||||
)
|
||||
|
||||
# set.add(obj)
|
||||
set_add_op = method_op(
|
||||
name="add",
|
||||
arg_types=[set_rprimitive, object_rprimitive],
|
||||
return_type=c_int_rprimitive,
|
||||
c_function_name="PySet_Add",
|
||||
error_kind=ERR_NEG_INT,
|
||||
)
|
||||
|
||||
# set.update(obj)
|
||||
#
|
||||
# This is not a public API but looks like it should be fine.
|
||||
set_update_op = method_op(
|
||||
name="update",
|
||||
arg_types=[set_rprimitive, object_rprimitive],
|
||||
return_type=c_int_rprimitive,
|
||||
c_function_name="_PySet_Update",
|
||||
error_kind=ERR_NEG_INT,
|
||||
)
|
||||
|
||||
# set.clear()
|
||||
method_op(
|
||||
name="clear",
|
||||
arg_types=[set_rprimitive],
|
||||
return_type=c_int_rprimitive,
|
||||
c_function_name="PySet_Clear",
|
||||
error_kind=ERR_NEG_INT,
|
||||
)
|
||||
|
||||
# set.pop()
|
||||
method_op(
|
||||
name="pop",
|
||||
arg_types=[set_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="PySet_Pop",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
Binary file not shown.
587
venv/lib/python3.11/site-packages/mypyc/primitives/str_ops.py
Normal file
587
venv/lib/python3.11/site-packages/mypyc/primitives/str_ops.py
Normal file
|
|
@ -0,0 +1,587 @@
|
|||
"""Primitive str ops."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from mypyc.ir.deps import STR_EXTRA_OPS
|
||||
from mypyc.ir.ops import ERR_MAGIC, ERR_NEVER
|
||||
from mypyc.ir.rtypes import (
|
||||
RType,
|
||||
bit_rprimitive,
|
||||
bool_rprimitive,
|
||||
bytes_rprimitive,
|
||||
c_int_rprimitive,
|
||||
c_pyssize_t_rprimitive,
|
||||
int64_rprimitive,
|
||||
int_rprimitive,
|
||||
list_rprimitive,
|
||||
object_rprimitive,
|
||||
pointer_rprimitive,
|
||||
short_int_rprimitive,
|
||||
str_rprimitive,
|
||||
tuple_rprimitive,
|
||||
)
|
||||
from mypyc.primitives.registry import (
|
||||
ERR_NEG_INT,
|
||||
binary_op,
|
||||
custom_op,
|
||||
custom_primitive_op,
|
||||
function_op,
|
||||
load_address_op,
|
||||
method_op,
|
||||
)
|
||||
|
||||
# Get the 'str' type object.
|
||||
load_address_op(name="builtins.str", type=object_rprimitive, src="PyUnicode_Type")
|
||||
|
||||
# str(obj)
|
||||
str_op = function_op(
|
||||
name="builtins.str",
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=str_rprimitive,
|
||||
c_function_name="PyObject_Str",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# repr(obj)
|
||||
function_op(
|
||||
name="builtins.repr",
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=str_rprimitive,
|
||||
c_function_name="PyObject_Repr",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# translate isinstance(obj, str)
|
||||
isinstance_str = function_op(
|
||||
name="builtins.isinstance",
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=bit_rprimitive,
|
||||
c_function_name="PyUnicode_Check",
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
# str1 + str2
|
||||
binary_op(
|
||||
name="+",
|
||||
arg_types=[str_rprimitive, str_rprimitive],
|
||||
return_type=str_rprimitive,
|
||||
c_function_name="PyUnicode_Concat",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# str1 += str2
|
||||
#
|
||||
# PyUnicode_Append makes an effort to reuse the LHS when the refcount
|
||||
# is 1. This is super dodgy but oh well, the interpreter does it.
|
||||
binary_op(
|
||||
name="+=",
|
||||
arg_types=[str_rprimitive, str_rprimitive],
|
||||
return_type=str_rprimitive,
|
||||
c_function_name="CPyStr_Append",
|
||||
error_kind=ERR_MAGIC,
|
||||
steals=[True, False],
|
||||
)
|
||||
|
||||
# str * int
|
||||
binary_op(
|
||||
name="*",
|
||||
arg_types=[str_rprimitive, int_rprimitive],
|
||||
return_type=str_rprimitive,
|
||||
c_function_name="CPyStr_Multiply",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# int * str
|
||||
binary_op(
|
||||
name="*",
|
||||
arg_types=[int_rprimitive, str_rprimitive],
|
||||
return_type=str_rprimitive,
|
||||
c_function_name="CPyStr_Multiply",
|
||||
error_kind=ERR_MAGIC,
|
||||
ordering=[1, 0],
|
||||
)
|
||||
|
||||
# str1 == str2 (very common operation, so we provide our own)
|
||||
str_eq = custom_primitive_op(
|
||||
name="str_eq",
|
||||
c_function_name="CPyStr_Equal",
|
||||
arg_types=[str_rprimitive, str_rprimitive],
|
||||
return_type=bool_rprimitive,
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
str_eq_literal = custom_primitive_op(
|
||||
name="str_eq_literal",
|
||||
c_function_name="CPyStr_EqualLiteral",
|
||||
arg_types=[str_rprimitive, str_rprimitive, c_pyssize_t_rprimitive],
|
||||
return_type=bool_rprimitive,
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
unicode_compare = custom_op(
|
||||
arg_types=[str_rprimitive, str_rprimitive],
|
||||
return_type=c_int_rprimitive,
|
||||
c_function_name="PyUnicode_Compare",
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
# str[index] (for an int index)
|
||||
method_op(
|
||||
name="__getitem__",
|
||||
arg_types=[str_rprimitive, int_rprimitive],
|
||||
return_type=str_rprimitive,
|
||||
c_function_name="CPyStr_GetItem",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# This is unsafe since it assumes that the index is within reasonable bounds.
|
||||
# In the future this might do no bounds checking at all.
|
||||
str_get_item_unsafe_op = custom_op(
|
||||
arg_types=[str_rprimitive, c_pyssize_t_rprimitive],
|
||||
return_type=str_rprimitive,
|
||||
c_function_name="CPyStr_GetItemUnsafe",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# str[begin:end]
|
||||
str_slice_op = custom_op(
|
||||
arg_types=[str_rprimitive, int_rprimitive, int_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPyStr_GetSlice",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# item in str
|
||||
binary_op(
|
||||
name="in",
|
||||
arg_types=[str_rprimitive, str_rprimitive],
|
||||
return_type=c_int_rprimitive,
|
||||
c_function_name="PyUnicode_Contains",
|
||||
error_kind=ERR_NEG_INT,
|
||||
truncated_type=bool_rprimitive,
|
||||
ordering=[1, 0],
|
||||
)
|
||||
|
||||
# str.find(...) and str.rfind(...)
|
||||
str_find_types: list[RType] = [str_rprimitive, str_rprimitive, int_rprimitive, int_rprimitive]
|
||||
str_find_functions = ["CPyStr_Find", "CPyStr_Find", "CPyStr_FindWithEnd"]
|
||||
str_find_constants: list[list[tuple[int, RType]]] = [[(0, c_int_rprimitive)], [], []]
|
||||
str_rfind_constants: list[list[tuple[int, RType]]] = [[(0, c_int_rprimitive)], [], []]
|
||||
for i in range(len(str_find_types) - 1):
|
||||
method_op(
|
||||
name="find",
|
||||
arg_types=str_find_types[0 : i + 2],
|
||||
return_type=int_rprimitive,
|
||||
c_function_name=str_find_functions[i],
|
||||
extra_int_constants=str_find_constants[i] + [(1, c_int_rprimitive)],
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
method_op(
|
||||
name="rfind",
|
||||
arg_types=str_find_types[0 : i + 2],
|
||||
return_type=int_rprimitive,
|
||||
c_function_name=str_find_functions[i],
|
||||
extra_int_constants=str_rfind_constants[i] + [(-1, c_int_rprimitive)],
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# str.join(obj)
|
||||
method_op(
|
||||
name="join",
|
||||
arg_types=[str_rprimitive, object_rprimitive],
|
||||
return_type=str_rprimitive,
|
||||
c_function_name="PyUnicode_Join",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
str_build_op = custom_op(
|
||||
arg_types=[c_pyssize_t_rprimitive],
|
||||
return_type=str_rprimitive,
|
||||
c_function_name="CPyStr_Build",
|
||||
error_kind=ERR_MAGIC,
|
||||
var_arg_type=str_rprimitive,
|
||||
)
|
||||
|
||||
# str.strip, str.lstrip, str.rstrip
|
||||
for strip_prefix in ["l", "r", ""]:
|
||||
method_op(
|
||||
name=f"{strip_prefix}strip",
|
||||
arg_types=[str_rprimitive, str_rprimitive],
|
||||
return_type=str_rprimitive,
|
||||
c_function_name=f"CPyStr_{strip_prefix.upper()}Strip",
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
method_op(
|
||||
name=f"{strip_prefix}strip",
|
||||
arg_types=[str_rprimitive],
|
||||
return_type=str_rprimitive,
|
||||
c_function_name=f"CPyStr_{strip_prefix.upper()}Strip",
|
||||
# This 0 below is implicitly treated as NULL in C.
|
||||
extra_int_constants=[(0, c_int_rprimitive)],
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
# str.startswith(str)
|
||||
method_op(
|
||||
name="startswith",
|
||||
arg_types=[str_rprimitive, str_rprimitive],
|
||||
return_type=c_int_rprimitive,
|
||||
c_function_name="CPyStr_Startswith",
|
||||
truncated_type=bool_rprimitive,
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
# str.startswith(tuple)
|
||||
method_op(
|
||||
name="startswith",
|
||||
arg_types=[str_rprimitive, tuple_rprimitive],
|
||||
return_type=bool_rprimitive,
|
||||
c_function_name="CPyStr_Startswith",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# str.endswith(str)
|
||||
method_op(
|
||||
name="endswith",
|
||||
arg_types=[str_rprimitive, str_rprimitive],
|
||||
return_type=c_int_rprimitive,
|
||||
c_function_name="CPyStr_Endswith",
|
||||
truncated_type=bool_rprimitive,
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
# str.endswith(tuple)
|
||||
method_op(
|
||||
name="endswith",
|
||||
arg_types=[str_rprimitive, tuple_rprimitive],
|
||||
return_type=bool_rprimitive,
|
||||
c_function_name="CPyStr_Endswith",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# str.removeprefix(str)
|
||||
method_op(
|
||||
name="removeprefix",
|
||||
arg_types=[str_rprimitive, str_rprimitive],
|
||||
return_type=str_rprimitive,
|
||||
c_function_name="CPyStr_Removeprefix",
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
# str.removesuffix(str)
|
||||
method_op(
|
||||
name="removesuffix",
|
||||
arg_types=[str_rprimitive, str_rprimitive],
|
||||
return_type=str_rprimitive,
|
||||
c_function_name="CPyStr_Removesuffix",
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
# str.split(...) and str.rsplit(...)
|
||||
str_split_types: list[RType] = [str_rprimitive, str_rprimitive, int_rprimitive]
|
||||
str_split_functions = ["PyUnicode_Split", "PyUnicode_Split", "CPyStr_Split"]
|
||||
str_rsplit_functions = ["PyUnicode_RSplit", "PyUnicode_RSplit", "CPyStr_RSplit"]
|
||||
str_split_constants: list[list[tuple[int, RType]]] = [
|
||||
[(0, pointer_rprimitive), (-1, c_int_rprimitive)],
|
||||
[(-1, c_int_rprimitive)],
|
||||
[],
|
||||
]
|
||||
for i in range(len(str_split_types)):
|
||||
method_op(
|
||||
name="split",
|
||||
arg_types=str_split_types[0 : i + 1],
|
||||
return_type=list_rprimitive,
|
||||
c_function_name=str_split_functions[i],
|
||||
extra_int_constants=str_split_constants[i],
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
method_op(
|
||||
name="rsplit",
|
||||
arg_types=str_split_types[0 : i + 1],
|
||||
return_type=list_rprimitive,
|
||||
c_function_name=str_rsplit_functions[i],
|
||||
extra_int_constants=str_split_constants[i],
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# str.splitlines(...)
|
||||
str_splitlines_types: list[RType] = [str_rprimitive, bool_rprimitive]
|
||||
str_splitlines_constants: list[list[tuple[int, RType]]] = [[(0, c_int_rprimitive)], []]
|
||||
for i in range(2):
|
||||
method_op(
|
||||
name="splitlines",
|
||||
arg_types=str_splitlines_types[0 : i + 1],
|
||||
return_type=list_rprimitive,
|
||||
c_function_name="PyUnicode_Splitlines",
|
||||
extra_int_constants=str_splitlines_constants[i],
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
# str.partition(str)
|
||||
method_op(
|
||||
name="partition",
|
||||
arg_types=[str_rprimitive, str_rprimitive],
|
||||
return_type=tuple_rprimitive,
|
||||
c_function_name="PyUnicode_Partition",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# str.rpartition(str)
|
||||
method_op(
|
||||
name="rpartition",
|
||||
arg_types=[str_rprimitive, str_rprimitive],
|
||||
return_type=tuple_rprimitive,
|
||||
c_function_name="PyUnicode_RPartition",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# str.count(substring)
|
||||
method_op(
|
||||
name="count",
|
||||
arg_types=[str_rprimitive, str_rprimitive],
|
||||
return_type=c_pyssize_t_rprimitive,
|
||||
c_function_name="CPyStr_Count",
|
||||
error_kind=ERR_NEG_INT,
|
||||
extra_int_constants=[(0, c_pyssize_t_rprimitive)],
|
||||
)
|
||||
|
||||
# str.count(substring, start)
|
||||
method_op(
|
||||
name="count",
|
||||
arg_types=[str_rprimitive, str_rprimitive, int_rprimitive],
|
||||
return_type=c_pyssize_t_rprimitive,
|
||||
c_function_name="CPyStr_Count",
|
||||
error_kind=ERR_NEG_INT,
|
||||
)
|
||||
|
||||
# str.count(substring, start, end)
|
||||
method_op(
|
||||
name="count",
|
||||
arg_types=[str_rprimitive, str_rprimitive, int_rprimitive, int_rprimitive],
|
||||
return_type=c_pyssize_t_rprimitive,
|
||||
c_function_name="CPyStr_CountFull",
|
||||
error_kind=ERR_NEG_INT,
|
||||
)
|
||||
|
||||
# str.replace(old, new)
|
||||
method_op(
|
||||
name="replace",
|
||||
arg_types=[str_rprimitive, str_rprimitive, str_rprimitive],
|
||||
return_type=str_rprimitive,
|
||||
c_function_name="PyUnicode_Replace",
|
||||
error_kind=ERR_MAGIC,
|
||||
extra_int_constants=[(-1, c_int_rprimitive)],
|
||||
)
|
||||
|
||||
# str.replace(old, new, count)
|
||||
method_op(
|
||||
name="replace",
|
||||
arg_types=[str_rprimitive, str_rprimitive, str_rprimitive, int_rprimitive],
|
||||
return_type=str_rprimitive,
|
||||
c_function_name="CPyStr_Replace",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# check if a string is true (isn't an empty string)
|
||||
str_check_if_true = custom_op(
|
||||
arg_types=[str_rprimitive],
|
||||
return_type=bit_rprimitive,
|
||||
c_function_name="CPyStr_IsTrue",
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
str_ssize_t_size_op = custom_op(
|
||||
arg_types=[str_rprimitive],
|
||||
return_type=c_pyssize_t_rprimitive,
|
||||
c_function_name="CPyStr_Size_size_t",
|
||||
error_kind=ERR_NEG_INT,
|
||||
)
|
||||
|
||||
# str.lower()
|
||||
method_op(
|
||||
name="lower",
|
||||
arg_types=[str_rprimitive],
|
||||
return_type=str_rprimitive,
|
||||
c_function_name="CPyStr_Lower",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# str.upper()
|
||||
method_op(
|
||||
name="upper",
|
||||
arg_types=[str_rprimitive],
|
||||
return_type=str_rprimitive,
|
||||
c_function_name="CPyStr_Upper",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
method_op(
|
||||
name="isspace",
|
||||
arg_types=[str_rprimitive],
|
||||
return_type=bool_rprimitive,
|
||||
c_function_name="CPyStr_IsSpace",
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
method_op(
|
||||
name="isalnum",
|
||||
arg_types=[str_rprimitive],
|
||||
return_type=bool_rprimitive,
|
||||
c_function_name="CPyStr_IsAlnum",
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
method_op(
|
||||
name="isdigit",
|
||||
arg_types=[str_rprimitive],
|
||||
return_type=bool_rprimitive,
|
||||
c_function_name="CPyStr_IsDigit",
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
|
||||
# obj.decode()
|
||||
method_op(
|
||||
name="decode",
|
||||
arg_types=[bytes_rprimitive],
|
||||
return_type=str_rprimitive,
|
||||
c_function_name="CPy_Decode",
|
||||
error_kind=ERR_MAGIC,
|
||||
extra_int_constants=[(0, pointer_rprimitive), (0, pointer_rprimitive)],
|
||||
)
|
||||
|
||||
# obj.decode(encoding)
|
||||
method_op(
|
||||
name="decode",
|
||||
arg_types=[bytes_rprimitive, str_rprimitive],
|
||||
return_type=str_rprimitive,
|
||||
c_function_name="CPy_Decode",
|
||||
error_kind=ERR_MAGIC,
|
||||
extra_int_constants=[(0, pointer_rprimitive)],
|
||||
)
|
||||
|
||||
# bytes.decode(encoding, errors)
|
||||
method_op(
|
||||
name="decode",
|
||||
arg_types=[bytes_rprimitive, str_rprimitive, str_rprimitive],
|
||||
return_type=str_rprimitive,
|
||||
c_function_name="CPy_Decode",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# bytes.decode(encoding) - utf8 strict specialization
|
||||
bytes_decode_utf8_strict = custom_op(
|
||||
arg_types=[bytes_rprimitive],
|
||||
return_type=str_rprimitive,
|
||||
c_function_name="CPy_DecodeUTF8",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# bytes.decode(encoding) - ascii strict specialization
|
||||
bytes_decode_ascii_strict = custom_op(
|
||||
arg_types=[bytes_rprimitive],
|
||||
return_type=str_rprimitive,
|
||||
c_function_name="CPy_DecodeASCII",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# bytes.decode(encoding) - latin1 strict specialization
|
||||
bytes_decode_latin1_strict = custom_op(
|
||||
arg_types=[bytes_rprimitive],
|
||||
return_type=str_rprimitive,
|
||||
c_function_name="CPy_DecodeLatin1",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# str.encode()
|
||||
method_op(
|
||||
name="encode",
|
||||
arg_types=[str_rprimitive],
|
||||
return_type=bytes_rprimitive,
|
||||
c_function_name="CPy_Encode",
|
||||
error_kind=ERR_MAGIC,
|
||||
extra_int_constants=[(0, pointer_rprimitive), (0, pointer_rprimitive)],
|
||||
)
|
||||
|
||||
# str.encode(encoding)
|
||||
method_op(
|
||||
name="encode",
|
||||
arg_types=[str_rprimitive, str_rprimitive],
|
||||
return_type=bytes_rprimitive,
|
||||
c_function_name="CPy_Encode",
|
||||
error_kind=ERR_MAGIC,
|
||||
extra_int_constants=[(0, pointer_rprimitive)],
|
||||
)
|
||||
|
||||
# str.encode(encoding) - utf8 strict specialization
|
||||
str_encode_utf8_strict = custom_op(
|
||||
arg_types=[str_rprimitive],
|
||||
return_type=bytes_rprimitive,
|
||||
c_function_name="PyUnicode_AsUTF8String",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# str.encode(encoding) - ascii strict specialization
|
||||
str_encode_ascii_strict = custom_op(
|
||||
arg_types=[str_rprimitive],
|
||||
return_type=bytes_rprimitive,
|
||||
c_function_name="PyUnicode_AsASCIIString",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# str.encode(encoding) - latin1 strict specialization
|
||||
str_encode_latin1_strict = custom_op(
|
||||
arg_types=[str_rprimitive],
|
||||
return_type=bytes_rprimitive,
|
||||
c_function_name="PyUnicode_AsLatin1String",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# str.encode(encoding, errors)
|
||||
method_op(
|
||||
name="encode",
|
||||
arg_types=[str_rprimitive, str_rprimitive, str_rprimitive],
|
||||
return_type=bytes_rprimitive,
|
||||
c_function_name="CPy_Encode",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
function_op(
|
||||
name="builtins.ord",
|
||||
arg_types=[str_rprimitive],
|
||||
return_type=int_rprimitive,
|
||||
c_function_name="CPyStr_Ord",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# Optimized str indexing for ord(s[i])
|
||||
|
||||
# str index adjustment - convert negative index to positive
|
||||
str_adjust_index_op = custom_primitive_op(
|
||||
name="str_adjust_index",
|
||||
arg_types=[str_rprimitive, int64_rprimitive],
|
||||
return_type=int64_rprimitive,
|
||||
c_function_name="CPyStr_AdjustIndex",
|
||||
error_kind=ERR_NEVER,
|
||||
dependencies=[STR_EXTRA_OPS],
|
||||
)
|
||||
|
||||
# str range check - check if index is in valid range
|
||||
str_range_check_op = custom_primitive_op(
|
||||
name="str_range_check",
|
||||
arg_types=[str_rprimitive, int64_rprimitive],
|
||||
return_type=bool_rprimitive,
|
||||
c_function_name="CPyStr_RangeCheck",
|
||||
error_kind=ERR_NEVER,
|
||||
dependencies=[STR_EXTRA_OPS],
|
||||
)
|
||||
|
||||
# str.__getitem__() as int - get character at index as int (ord value) - no bounds checking
|
||||
str_get_item_unsafe_as_int_op = custom_primitive_op(
|
||||
name="str_get_item_unsafe_as_int",
|
||||
arg_types=[str_rprimitive, int64_rprimitive],
|
||||
return_type=short_int_rprimitive,
|
||||
c_function_name="CPyStr_GetItemUnsafeAsInt",
|
||||
error_kind=ERR_NEVER,
|
||||
dependencies=[STR_EXTRA_OPS],
|
||||
)
|
||||
Binary file not shown.
136
venv/lib/python3.11/site-packages/mypyc/primitives/tuple_ops.py
Normal file
136
venv/lib/python3.11/site-packages/mypyc/primitives/tuple_ops.py
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
"""Primitive tuple ops for *variable-length* tuples.
|
||||
|
||||
Note: Varying-length tuples are represented as boxed Python tuple
|
||||
objects, i.e. tuple_rprimitive (RPrimitive), not RTuple.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from mypyc.ir.ops import ERR_MAGIC, ERR_NEVER
|
||||
from mypyc.ir.rtypes import (
|
||||
bit_rprimitive,
|
||||
c_pyssize_t_rprimitive,
|
||||
int_rprimitive,
|
||||
list_rprimitive,
|
||||
object_rprimitive,
|
||||
tuple_rprimitive,
|
||||
void_rtype,
|
||||
)
|
||||
from mypyc.primitives.registry import binary_op, custom_op, function_op, load_address_op, method_op
|
||||
|
||||
# Get the 'builtins.tuple' type object.
|
||||
load_address_op(name="builtins.tuple", type=object_rprimitive, src="PyTuple_Type")
|
||||
|
||||
# tuple[index] (for an int index)
|
||||
tuple_get_item_op = method_op(
|
||||
name="__getitem__",
|
||||
arg_types=[tuple_rprimitive, int_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPySequenceTuple_GetItem",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# This is unsafe because it assumes that the index is a non-negative integer
|
||||
# that is in-bounds for the tuple.
|
||||
tuple_get_item_unsafe_op = custom_op(
|
||||
arg_types=[tuple_rprimitive, c_pyssize_t_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPySequenceTuple_GetItemUnsafe",
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
# Construct a boxed tuple from items: (item1, item2, ...)
|
||||
new_tuple_op = custom_op(
|
||||
arg_types=[c_pyssize_t_rprimitive],
|
||||
return_type=tuple_rprimitive,
|
||||
c_function_name="PyTuple_Pack",
|
||||
error_kind=ERR_MAGIC,
|
||||
var_arg_type=object_rprimitive,
|
||||
)
|
||||
|
||||
new_tuple_with_length_op = custom_op(
|
||||
arg_types=[c_pyssize_t_rprimitive],
|
||||
return_type=tuple_rprimitive,
|
||||
c_function_name="PyTuple_New",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
load_empty_tuple_constant_op = custom_op(
|
||||
arg_types=[],
|
||||
return_type=tuple_rprimitive,
|
||||
c_function_name="CPyTuple_LoadEmptyTupleConstant",
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
# PyTuple_SET_ITEM does no error checking,
|
||||
# and should only be used to fill in brand new tuples.
|
||||
new_tuple_set_item_op = custom_op(
|
||||
arg_types=[tuple_rprimitive, c_pyssize_t_rprimitive, object_rprimitive],
|
||||
return_type=void_rtype,
|
||||
c_function_name="CPySequenceTuple_SetItemUnsafe",
|
||||
error_kind=ERR_NEVER,
|
||||
steals=[False, False, True],
|
||||
)
|
||||
|
||||
# Construct tuple from a list.
|
||||
list_tuple_op = function_op(
|
||||
name="builtins.tuple",
|
||||
arg_types=[list_rprimitive],
|
||||
return_type=tuple_rprimitive,
|
||||
c_function_name="PyList_AsTuple",
|
||||
error_kind=ERR_MAGIC,
|
||||
priority=2,
|
||||
)
|
||||
|
||||
# Construct tuple from an arbitrary (iterable) object.
|
||||
sequence_tuple_op = function_op(
|
||||
name="builtins.tuple",
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=tuple_rprimitive,
|
||||
c_function_name="PySequence_Tuple",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# translate isinstance(obj, tuple)
|
||||
isinstance_tuple = function_op(
|
||||
name="builtins.isinstance",
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=bit_rprimitive,
|
||||
c_function_name="PyTuple_Check",
|
||||
error_kind=ERR_NEVER,
|
||||
)
|
||||
|
||||
# tuple + tuple
|
||||
binary_op(
|
||||
name="+",
|
||||
arg_types=[tuple_rprimitive, tuple_rprimitive],
|
||||
return_type=tuple_rprimitive,
|
||||
c_function_name="PySequence_Concat",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# tuple * int
|
||||
binary_op(
|
||||
name="*",
|
||||
arg_types=[tuple_rprimitive, int_rprimitive],
|
||||
return_type=tuple_rprimitive,
|
||||
c_function_name="CPySequence_Multiply",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# int * tuple
|
||||
binary_op(
|
||||
name="*",
|
||||
arg_types=[int_rprimitive, tuple_rprimitive],
|
||||
return_type=tuple_rprimitive,
|
||||
c_function_name="CPySequence_RMultiply",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
# tuple[begin:end]
|
||||
tuple_slice_op = custom_op(
|
||||
arg_types=[tuple_rprimitive, int_rprimitive, int_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="CPySequenceTuple_GetSlice",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
Binary file not shown.
|
|
@ -0,0 +1,40 @@
|
|||
from mypyc.ir.ops import ERR_MAGIC
|
||||
from mypyc.ir.rtypes import object_rprimitive, pointer_rprimitive
|
||||
from mypyc.primitives.registry import function_op
|
||||
|
||||
# Weakref operations
|
||||
|
||||
new_ref_op = function_op(
|
||||
name="weakref.ReferenceType",
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="PyWeakref_NewRef",
|
||||
extra_int_constants=[(0, pointer_rprimitive)],
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
new_ref__with_callback_op = function_op(
|
||||
name="weakref.ReferenceType",
|
||||
arg_types=[object_rprimitive, object_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="PyWeakref_NewRef",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
new_proxy_op = function_op(
|
||||
name="_weakref.proxy",
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="PyWeakref_NewProxy",
|
||||
extra_int_constants=[(0, pointer_rprimitive)],
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
|
||||
new_proxy_with_callback_op = function_op(
|
||||
name="_weakref.proxy",
|
||||
arg_types=[object_rprimitive, object_rprimitive],
|
||||
# steals=[True, False],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name="PyWeakref_NewProxy",
|
||||
error_kind=ERR_MAGIC,
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue