init
This commit is contained in:
commit
38355d2442
9083 changed files with 1225834 additions and 0 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,84 @@
|
|||
"""Primitive bytes ops."""
|
||||
|
||||
from mypyc.ir.ops import ERR_MAGIC
|
||||
from mypyc.ir.rtypes import (
|
||||
object_rprimitive, bytes_rprimitive, list_rprimitive, dict_rprimitive,
|
||||
str_rprimitive, c_int_rprimitive, RUnion, c_pyssize_t_rprimitive,
|
||||
int_rprimitive,
|
||||
)
|
||||
from mypyc.primitives.registry import (
|
||||
load_address_op, function_op, method_op, binary_op, custom_op, ERR_NEG_INT
|
||||
)
|
||||
|
||||
# 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)
|
||||
|
||||
# bytearray(obj)
|
||||
function_op(
|
||||
name='builtins.bytearray',
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=bytes_rprimitive,
|
||||
c_function_name='PyByteArray_FromObject',
|
||||
error_kind=ERR_MAGIC)
|
||||
|
||||
# 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
|
||||
# bytearray + bytearray
|
||||
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[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)
|
||||
|
||||
# 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
|
||||
)
|
||||
Binary file not shown.
265
.venv/lib/python3.8/site-packages/mypyc/primitives/dict_ops.py
Normal file
265
.venv/lib/python3.8/site-packages/mypyc/primitives/dict_ops.py
Normal file
|
|
@ -0,0 +1,265 @@
|
|||
"""Primitive dict ops."""
|
||||
|
||||
from mypyc.ir.ops import ERR_FALSE, ERR_MAGIC, ERR_NEVER
|
||||
from mypyc.ir.rtypes import (
|
||||
dict_rprimitive, object_rprimitive, bool_rprimitive, int_rprimitive,
|
||||
list_rprimitive, dict_next_rtuple_single, dict_next_rtuple_pair, c_pyssize_t_rprimitive,
|
||||
c_int_rprimitive, bit_rprimitive
|
||||
)
|
||||
|
||||
from mypyc.primitives.registry import (
|
||||
custom_op, method_op, function_op, binary_op, load_address_op, ERR_NEG_INT
|
||||
)
|
||||
|
||||
# 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.
|
||||
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)
|
||||
function_op(
|
||||
name='builtins.dict',
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=dict_rprimitive,
|
||||
c_function_name='CPyDict_FromAny',
|
||||
error_kind=ERR_MAGIC)
|
||||
|
||||
# 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)
|
||||
|
||||
# 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, dict_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',
|
||||
is_borrowed=True,
|
||||
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, int_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)
|
||||
Binary file not shown.
|
|
@ -0,0 +1,96 @@
|
|||
"""Exception-related primitive ops."""
|
||||
|
||||
from mypyc.ir.ops import ERR_NEVER, ERR_FALSE, ERR_ALWAYS
|
||||
from mypyc.ir.rtypes import object_rprimitive, void_rtype, exc_rtuple, bit_rprimitive
|
||||
from mypyc.primitives.registry import custom_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_NoErrOccured',
|
||||
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)
|
||||
|
||||
# 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.
|
|
@ -0,0 +1,25 @@
|
|||
"""Primitive float ops."""
|
||||
|
||||
from mypyc.ir.ops import ERR_MAGIC
|
||||
from mypyc.ir.rtypes import (
|
||||
str_rprimitive, float_rprimitive
|
||||
)
|
||||
from mypyc.primitives.registry import (
|
||||
function_op
|
||||
)
|
||||
|
||||
# float(str)
|
||||
function_op(
|
||||
name='builtins.float',
|
||||
arg_types=[str_rprimitive],
|
||||
return_type=float_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='PyNumber_Absolute',
|
||||
error_kind=ERR_MAGIC)
|
||||
Binary file not shown.
|
|
@ -0,0 +1,277 @@
|
|||
"""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 mypyc.ir.ops import ERR_NEVER, ERR_MAGIC
|
||||
from mypyc.ir.rtypes import (
|
||||
object_rprimitive, int_rprimitive, bool_rprimitive, c_int_rprimitive, pointer_rprimitive,
|
||||
object_pointer_rprimitive, c_size_t_rprimitive, c_pyssize_t_rprimitive
|
||||
)
|
||||
from mypyc.primitives.registry import (
|
||||
binary_op, unary_op, method_op, function_op, custom_op, ERR_NEG_INT
|
||||
)
|
||||
|
||||
|
||||
# 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)
|
||||
|
||||
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)
|
||||
|
||||
binary_op(name='**',
|
||||
arg_types=[object_rprimitive, object_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
error_kind=ERR_MAGIC,
|
||||
c_function_name='CPyNumber_Power',
|
||||
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)
|
||||
|
||||
# obj1[obj2]
|
||||
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 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)
|
||||
Binary file not shown.
165
.venv/lib/python3.8/site-packages/mypyc/primitives/int_ops.py
Normal file
165
.venv/lib/python3.8/site-packages/mypyc/primitives/int_ops.py
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
"""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 typing import Dict, NamedTuple
|
||||
from mypyc.ir.ops import ERR_NEVER, ERR_MAGIC, ComparisonOp
|
||||
from mypyc.ir.rtypes import (
|
||||
int_rprimitive, bool_rprimitive, float_rprimitive, object_rprimitive,
|
||||
str_rprimitive, bit_rprimitive, RType
|
||||
)
|
||||
from mypyc.primitives.registry import (
|
||||
load_address_op, unary_op, CFunctionDescription, function_op, binary_op, custom_op
|
||||
)
|
||||
|
||||
# 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'.
|
||||
# For ordinary calls to int() we use a load_address to the type
|
||||
load_address_op(
|
||||
name='builtins.int',
|
||||
type=object_rprimitive,
|
||||
src='PyLong_Type')
|
||||
|
||||
# int(float). We could do a bit better directly.
|
||||
function_op(
|
||||
name='builtins.int',
|
||||
arg_types=[float_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name='CPyLong_FromFloat',
|
||||
error_kind=ERR_MAGIC)
|
||||
|
||||
# int(string)
|
||||
function_op(
|
||||
name='builtins.int',
|
||||
arg_types=[str_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name='CPyLong_FromStr',
|
||||
error_kind=ERR_MAGIC)
|
||||
|
||||
# int(string, base)
|
||||
function_op(
|
||||
name='builtins.int',
|
||||
arg_types=[str_rprimitive, int_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name='CPyLong_FromStrWithBase',
|
||||
error_kind=ERR_MAGIC)
|
||||
|
||||
# str(int)
|
||||
int_to_str_op = function_op(
|
||||
name='builtins.str',
|
||||
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='builtins.str',
|
||||
arg_types=[bool_rprimitive],
|
||||
return_type=str_rprimitive,
|
||||
c_function_name='CPyBool_Str',
|
||||
error_kind=ERR_MAGIC,
|
||||
priority=3)
|
||||
|
||||
|
||||
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)
|
||||
|
||||
# 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) -> CFunctionDescription:
|
||||
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:
|
||||
|
||||
# Description for building int comparison ops
|
||||
#
|
||||
# Fields:
|
||||
# binary_op_variant: identify which IntOp to use when operands are short integers
|
||||
# c_func_description: the C function to call when operands are tagged integers
|
||||
# c_func_negated: whether to negate the C function call's result
|
||||
# c_func_swap_operands: whether to swap lhs and rhs when call the function
|
||||
IntComparisonOpDescription = NamedTuple(
|
||||
'IntComparisonOpDescription', [('binary_op_variant', int),
|
||||
('c_func_description', CFunctionDescription),
|
||||
('c_func_negated', bool),
|
||||
('c_func_swap_operands', bool)])
|
||||
|
||||
# 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)
|
||||
|
||||
# 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)
|
||||
|
||||
# Provide mapping from textual op to short int's op variant and boxed int's description.
|
||||
# Note that these are not complete implementations and require extra IR.
|
||||
int_comparison_op_mapping: Dict[str, IntComparisonOpDescription] = {
|
||||
'==': IntComparisonOpDescription(ComparisonOp.EQ, int_equal_, False, False),
|
||||
'!=': IntComparisonOpDescription(ComparisonOp.NEQ, int_equal_, True, False),
|
||||
'<': IntComparisonOpDescription(ComparisonOp.SLT, int_less_than_, False, False),
|
||||
'<=': IntComparisonOpDescription(ComparisonOp.SLE, int_less_than_, True, True),
|
||||
'>': IntComparisonOpDescription(ComparisonOp.SGT, int_less_than_, False, True),
|
||||
'>=': IntComparisonOpDescription(ComparisonOp.SGE, int_less_than_, True, False),
|
||||
}
|
||||
Binary file not shown.
194
.venv/lib/python3.8/site-packages/mypyc/primitives/list_ops.py
Normal file
194
.venv/lib/python3.8/site-packages/mypyc/primitives/list_ops.py
Normal file
|
|
@ -0,0 +1,194 @@
|
|||
"""List primitive ops."""
|
||||
|
||||
from mypyc.ir.ops import ERR_MAGIC, ERR_NEVER, ERR_FALSE
|
||||
from mypyc.ir.rtypes import (
|
||||
int_rprimitive, short_int_rprimitive, list_rprimitive, object_rprimitive, c_int_rprimitive,
|
||||
c_pyssize_t_rprimitive, bit_rprimitive
|
||||
)
|
||||
from mypyc.primitives.registry import (
|
||||
load_address_op, function_op, binary_op, method_op, custom_op, ERR_NEG_INT
|
||||
)
|
||||
|
||||
|
||||
# Get the 'builtins.list' type object.
|
||||
load_address_op(
|
||||
name='builtins.list',
|
||||
type=object_rprimitive,
|
||||
src='PyList_Type')
|
||||
|
||||
# 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)])
|
||||
|
||||
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)
|
||||
|
||||
# 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)
|
||||
|
||||
# Version with no int bounds 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)
|
||||
|
||||
# This is unsafe because it assumes that the index is a non-negative short integer
|
||||
# that is in-bounds for the list.
|
||||
list_get_item_unsafe_op = custom_op(
|
||||
arg_types=[list_rprimitive, short_int_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name='CPyList_GetItemUnsafe',
|
||||
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])
|
||||
|
||||
# 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, int_rprimitive, object_rprimitive],
|
||||
return_type=bit_rprimitive,
|
||||
c_function_name='CPyList_SetItemUnsafe',
|
||||
error_kind=ERR_FALSE,
|
||||
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)
|
||||
list_pop = 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 * 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[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,)
|
||||
Binary file not shown.
225
.venv/lib/python3.8/site-packages/mypyc/primitives/misc_ops.py
Normal file
225
.venv/lib/python3.8/site-packages/mypyc/primitives/misc_ops.py
Normal file
|
|
@ -0,0 +1,225 @@
|
|||
"""Miscellaneous primitive ops."""
|
||||
|
||||
from mypyc.ir.ops import ERR_NEVER, ERR_MAGIC, ERR_FALSE
|
||||
from mypyc.ir.rtypes import (
|
||||
bool_rprimitive, object_rprimitive, str_rprimitive, object_pointer_rprimitive,
|
||||
int_rprimitive, dict_rprimitive, c_int_rprimitive, bit_rprimitive, c_pyssize_t_rprimitive,
|
||||
list_rprimitive,
|
||||
)
|
||||
from mypyc.primitives.registry import (
|
||||
function_op, custom_op, load_address_op, ERR_NEG_INT
|
||||
)
|
||||
|
||||
# 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')
|
||||
|
||||
# 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
|
||||
import_op = custom_op(
|
||||
arg_types=[str_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name='PyImport_Import',
|
||||
error_kind=ERR_MAGIC)
|
||||
|
||||
# Import with extra arguments (used in from import handling)
|
||||
import_extra_args_op = custom_op(
|
||||
arg_types=[str_rprimitive, dict_rprimitive, dict_rprimitive,
|
||||
list_rprimitive, c_int_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name='PyImport_ImportModuleLevelObject',
|
||||
error_kind=ERR_MAGIC
|
||||
)
|
||||
|
||||
# Import-from helper op
|
||||
import_from_op = custom_op(
|
||||
arg_types=[object_rprimitive, str_rprimitive,
|
||||
str_rprimitive, str_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name='CPyImport_ImportFrom',
|
||||
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)
|
||||
|
||||
# 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='PyObject_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)
|
||||
|
||||
# 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],
|
||||
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,
|
||||
)
|
||||
Binary file not shown.
247
.venv/lib/python3.8/site-packages/mypyc/primitives/registry.py
Normal file
247
.venv/lib/python3.8/site-packages/mypyc/primitives/registry.py
Normal file
|
|
@ -0,0 +1,247 @@
|
|||
"""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 = func_op(name='builtins.len',
|
||||
arg_types=[list_rprimitive],
|
||||
result_type=short_int_rprimitive,
|
||||
error_kind=ERR_NEVER,
|
||||
emit=emit_len)
|
||||
|
||||
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 emit_len is used
|
||||
to generate 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_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 typing import Dict, List, Optional, NamedTuple, Tuple
|
||||
from typing_extensions import Final
|
||||
|
||||
from mypyc.ir.ops import 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
|
||||
|
||||
|
||||
CFunctionDescription = NamedTuple(
|
||||
'CFunctionDescription', [('name', str),
|
||||
('arg_types', List[RType]),
|
||||
('return_type', RType),
|
||||
('var_arg_type', Optional[RType]),
|
||||
('truncated_type', Optional[RType]),
|
||||
('c_function_name', str),
|
||||
('error_kind', int),
|
||||
('steals', StealsDescription),
|
||||
('is_borrowed', bool),
|
||||
('ordering', Optional[List[int]]),
|
||||
('extra_int_constants', List[Tuple[int, RType]]),
|
||||
('priority', int)])
|
||||
|
||||
# A description for C load operations including LoadGlobal and LoadAddress
|
||||
LoadAddressDescription = NamedTuple(
|
||||
'LoadAddressDescription', [('name', str),
|
||||
('type', RType),
|
||||
('src', str)]) # name of the target to load
|
||||
|
||||
|
||||
# CallC op for method call(such as 'str.join')
|
||||
method_call_ops: Dict[str, List[CFunctionDescription]] = {}
|
||||
|
||||
# CallC op for top level function call(such as 'builtins.list')
|
||||
function_ops: Dict[str, List[CFunctionDescription]] = {}
|
||||
|
||||
# CallC op for binary ops
|
||||
binary_ops: Dict[str, List[CFunctionDescription]] = {}
|
||||
|
||||
# CallC op for unary ops
|
||||
unary_ops: Dict[str, List[CFunctionDescription]] = {}
|
||||
|
||||
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: Optional[RType] = None,
|
||||
truncated_type: Optional[RType] = None,
|
||||
ordering: Optional[List[int]] = None,
|
||||
extra_int_constants: List[Tuple[int, RType]] = [],
|
||||
steals: StealsDescription = False,
|
||||
is_borrowed: bool = False,
|
||||
priority: int = 1) -> CFunctionDescription:
|
||||
"""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
|
||||
"""
|
||||
ops = method_call_ops.setdefault(name, [])
|
||||
desc = CFunctionDescription(name, arg_types, return_type, var_arg_type, truncated_type,
|
||||
c_function_name, error_kind, steals, is_borrowed, ordering,
|
||||
extra_int_constants, priority)
|
||||
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: Optional[RType] = None,
|
||||
truncated_type: Optional[RType] = None,
|
||||
ordering: Optional[List[int]] = None,
|
||||
extra_int_constants: List[Tuple[int, RType]] = [],
|
||||
steals: StealsDescription = False,
|
||||
is_borrowed: bool = False,
|
||||
priority: int = 1) -> CFunctionDescription:
|
||||
"""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
|
||||
"""
|
||||
ops = function_ops.setdefault(name, [])
|
||||
desc = CFunctionDescription(name, arg_types, return_type, var_arg_type, truncated_type,
|
||||
c_function_name, error_kind, steals, is_borrowed, ordering,
|
||||
extra_int_constants, priority)
|
||||
ops.append(desc)
|
||||
return desc
|
||||
|
||||
|
||||
def binary_op(name: str,
|
||||
arg_types: List[RType],
|
||||
return_type: RType,
|
||||
c_function_name: str,
|
||||
error_kind: int,
|
||||
var_arg_type: Optional[RType] = None,
|
||||
truncated_type: Optional[RType] = None,
|
||||
ordering: Optional[List[int]] = None,
|
||||
extra_int_constants: List[Tuple[int, RType]] = [],
|
||||
steals: StealsDescription = False,
|
||||
is_borrowed: bool = False,
|
||||
priority: int = 1) -> CFunctionDescription:
|
||||
"""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.
|
||||
"""
|
||||
ops = binary_ops.setdefault(name, [])
|
||||
desc = CFunctionDescription(name, arg_types, return_type, var_arg_type, truncated_type,
|
||||
c_function_name, error_kind, steals, is_borrowed, ordering,
|
||||
extra_int_constants, priority)
|
||||
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: Optional[RType] = None,
|
||||
truncated_type: Optional[RType] = None,
|
||||
ordering: Optional[List[int]] = None,
|
||||
extra_int_constants: List[Tuple[int, RType]] = [],
|
||||
steals: StealsDescription = False,
|
||||
is_borrowed: 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().
|
||||
"""
|
||||
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)
|
||||
|
||||
|
||||
def unary_op(name: str,
|
||||
arg_type: RType,
|
||||
return_type: RType,
|
||||
c_function_name: str,
|
||||
error_kind: int,
|
||||
truncated_type: Optional[RType] = None,
|
||||
ordering: Optional[List[int]] = None,
|
||||
extra_int_constants: List[Tuple[int, RType]] = [],
|
||||
steals: StealsDescription = False,
|
||||
is_borrowed: bool = False,
|
||||
priority: int = 1) -> CFunctionDescription:
|
||||
"""Define a c function call 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.
|
||||
"""
|
||||
ops = unary_ops.setdefault(name, [])
|
||||
desc = CFunctionDescription(name, [arg_type], return_type, None, truncated_type,
|
||||
c_function_name, error_kind, steals, is_borrowed, ordering,
|
||||
extra_int_constants, priority)
|
||||
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.int_ops # noqa
|
||||
import mypyc.primitives.str_ops # noqa
|
||||
import mypyc.primitives.bytes_ops # noqa
|
||||
import mypyc.primitives.list_ops # noqa
|
||||
import mypyc.primitives.dict_ops # noqa
|
||||
import mypyc.primitives.tuple_ops # noqa
|
||||
import mypyc.primitives.misc_ops # noqa
|
||||
import mypyc.primitives.float_ops # noqa
|
||||
Binary file not shown.
|
|
@ -0,0 +1,94 @@
|
|||
"""Primitive set (and frozenset) ops."""
|
||||
|
||||
from mypyc.primitives.registry import function_op, method_op, binary_op, ERR_NEG_INT
|
||||
from mypyc.ir.ops import ERR_MAGIC, ERR_FALSE
|
||||
from mypyc.ir.rtypes import (
|
||||
object_rprimitive, bool_rprimitive, set_rprimitive, c_int_rprimitive, pointer_rprimitive,
|
||||
bit_rprimitive
|
||||
)
|
||||
|
||||
|
||||
# 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)
|
||||
|
||||
# frozenset(obj)
|
||||
function_op(
|
||||
name='builtins.frozenset',
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=object_rprimitive,
|
||||
c_function_name='PyFrozenSet_New',
|
||||
error_kind=ERR_MAGIC)
|
||||
|
||||
# item in set
|
||||
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])
|
||||
|
||||
# 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.
205
.venv/lib/python3.8/site-packages/mypyc/primitives/str_ops.py
Normal file
205
.venv/lib/python3.8/site-packages/mypyc/primitives/str_ops.py
Normal file
|
|
@ -0,0 +1,205 @@
|
|||
"""Primitive str ops."""
|
||||
|
||||
from typing import List, Tuple
|
||||
|
||||
from mypyc.ir.ops import ERR_MAGIC, ERR_NEVER
|
||||
from mypyc.ir.rtypes import (
|
||||
RType, object_rprimitive, str_rprimitive, int_rprimitive, list_rprimitive,
|
||||
c_int_rprimitive, pointer_rprimitive, bool_rprimitive, bit_rprimitive,
|
||||
c_pyssize_t_rprimitive, bytes_rprimitive
|
||||
)
|
||||
from mypyc.primitives.registry import (
|
||||
method_op, binary_op, function_op,
|
||||
load_address_op, custom_op, ERR_NEG_INT
|
||||
)
|
||||
|
||||
|
||||
# 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)
|
||||
|
||||
# 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])
|
||||
|
||||
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
|
||||
)
|
||||
|
||||
# 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)
|
||||
|
||||
# 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.startswith(str)
|
||||
method_op(
|
||||
name='startswith',
|
||||
arg_types=[str_rprimitive, str_rprimitive],
|
||||
return_type=bool_rprimitive,
|
||||
c_function_name='CPyStr_Startswith',
|
||||
error_kind=ERR_NEVER
|
||||
)
|
||||
|
||||
# str.endswith(str)
|
||||
method_op(
|
||||
name='endswith',
|
||||
arg_types=[str_rprimitive, str_rprimitive],
|
||||
return_type=bool_rprimitive,
|
||||
c_function_name='CPyStr_Endswith',
|
||||
error_kind=ERR_NEVER
|
||||
)
|
||||
|
||||
# str.split(...)
|
||||
str_split_types: List[RType] = [str_rprimitive, str_rprimitive, int_rprimitive]
|
||||
str_split_functions = ["PyUnicode_Split", "PyUnicode_Split", "CPyStr_Split"]
|
||||
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)
|
||||
|
||||
# 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)
|
||||
|
||||
# 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)])
|
||||
|
||||
# obj.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)
|
||||
|
||||
# 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, 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)
|
||||
Binary file not shown.
|
|
@ -0,0 +1,68 @@
|
|||
"""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 mypyc.ir.ops import ERR_MAGIC, ERR_FALSE
|
||||
from mypyc.ir.rtypes import (
|
||||
tuple_rprimitive, int_rprimitive, list_rprimitive, object_rprimitive,
|
||||
c_pyssize_t_rprimitive, bit_rprimitive
|
||||
)
|
||||
from mypyc.primitives.registry import method_op, function_op, custom_op
|
||||
|
||||
|
||||
# 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)
|
||||
|
||||
# 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)
|
||||
|
||||
# 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, int_rprimitive, object_rprimitive],
|
||||
return_type=bit_rprimitive,
|
||||
c_function_name='CPySequenceTuple_SetItemUnsafe',
|
||||
error_kind=ERR_FALSE,
|
||||
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.
|
||||
function_op(
|
||||
name='builtins.tuple',
|
||||
arg_types=[object_rprimitive],
|
||||
return_type=tuple_rprimitive,
|
||||
c_function_name='PySequence_Tuple',
|
||||
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)
|
||||
Loading…
Add table
Add a link
Reference in a new issue