def int_unary_op(op: str, c_func_name: str) -> OpDescription: return unary_op(op=op, arg_type=int_rprimitive, result_type=int_rprimitive, error_kind=ERR_NEVER, format_str='{dest} = %s{args[0]} :: int' % op, emit=simple_emit('{dest} = %s({args[0]});' % c_func_name))
def int_binary_op(op: str, c_func_name: str, result_type: RType = int_rprimitive) -> None: binary_op(op=op, arg_types=[int_rprimitive, int_rprimitive], result_type=result_type, error_kind=ERR_NEVER, format_str='{dest} = {args[0]} %s {args[1]} :: int' % op, emit=simple_emit('{dest} = %s({args[0]}, {args[1]});' % c_func_name))
def int_compare_op(op: str, c_func_name: str) -> None: int_binary_op(op, c_func_name, bool_rprimitive) # Generate a straight compare if we know both sides are short binary_op( op=op, arg_types=[short_int_rprimitive, short_int_rprimitive], result_type=bool_rprimitive, error_kind=ERR_NEVER, format_str='{dest} = {args[0]} %s {args[1]} :: short_int' % op, emit=simple_emit( '{dest} = (Py_ssize_t){args[0]} %s (Py_ssize_t){args[1]};' % op), priority=2)
) tuple_get_item_op = method_op(name='__getitem__', arg_types=[tuple_rprimitive, int_rprimitive], result_type=object_rprimitive, error_kind=ERR_MAGIC, emit=call_emit('CPySequenceTuple_GetItem')) new_tuple_op = custom_op( arg_types=[object_rprimitive], result_type=tuple_rprimitive, is_var_arg=True, error_kind=ERR_MAGIC, steals=False, format_str='{dest} = ({comma_args}) :: tuple', emit=simple_emit('{dest} = PyTuple_Pack({num_args}{pre_comma_args});')) def emit_len(emitter: EmitterInterface, args: List[str], dest: str) -> None: temp = emitter.temp_name() emitter.emit_declaration('Py_ssize_t %s;' % temp) emitter.emit_line('%s = PyTuple_GET_SIZE(%s);' % (temp, args[0])) emitter.emit_line('%s = CPyTagged_ShortFromSsize_t(%s);' % (dest, temp)) tuple_len_op = func_op(name='builtins.len', arg_types=[tuple_rprimitive], result_type=int_rprimitive, error_kind=ERR_NEVER, emit=emit_len)
from typing import List, Callable from mypyc.ops import (object_rprimitive, str_rprimitive, bool_rprimitive, ERR_MAGIC, ERR_NEVER, EmitterInterface) from mypyc.ops_primitive import func_op, binary_op, simple_emit, name_ref_op, method_op name_ref_op('builtins.str', result_type=object_rprimitive, error_kind=ERR_NEVER, emit=simple_emit('{dest} = (PyObject *)&PyUnicode_Type;'), is_borrowed=True) func_op(name='builtins.str', arg_types=[object_rprimitive], result_type=str_rprimitive, error_kind=ERR_MAGIC, emit=simple_emit('{dest} = PyObject_Str({args[0]});')) binary_op(op='+', arg_types=[str_rprimitive, str_rprimitive], result_type=str_rprimitive, error_kind=ERR_MAGIC, emit=simple_emit('{dest} = PyUnicode_Concat({args[0]}, {args[1]});')) method_op(name='join', arg_types=[str_rprimitive, object_rprimitive], result_type=str_rprimitive, error_kind=ERR_MAGIC, emit=simple_emit('{dest} = PyUnicode_Join({args[0]}, {args[1]});')) # PyUnicodeAppend makes an effort to reuse the LHS when the refcount
from mypyc.ops import ( bool_rprimitive, object_rprimitive, void_rtype, exc_rtuple, ERR_NEVER, ERR_FALSE ) from mypyc.ops_primitive import ( simple_emit, custom_op, ) # TODO: Making this raise conditionally is kind of hokey. raise_exception_op = custom_op( arg_types=[object_rprimitive], result_type=bool_rprimitive, error_kind=ERR_FALSE, format_str='raise_exception({args[0]}); {dest} = 0', emit=simple_emit('CPy_Raise({args[0]}); {dest} = 0;')) set_stop_iteration_value = custom_op( arg_types=[object_rprimitive], result_type=bool_rprimitive, error_kind=ERR_FALSE, format_str='set_stop_iteration_value({args[0]}); {dest} = 0', emit=simple_emit('CPyGen_SetStopIterationValue({args[0]}); {dest} = 0;')) raise_exception_with_tb_op = custom_op( arg_types=[object_rprimitive, object_rprimitive, object_rprimitive], result_type=bool_rprimitive, error_kind=ERR_FALSE, format_str='raise_exception_with_tb({args[0]}, {args[1]}, {args[2]}); {dest} = 0', emit=simple_emit('CPyErr_SetObjectAndTraceback({args[0]}, {args[1]}, {args[2]}); {dest} = 0;'))
from mypyc.ops import (int_rprimitive, list_rprimitive, object_rprimitive, bool_rprimitive, ERR_MAGIC, ERR_NEVER, ERR_FALSE, EmitterInterface, PrimitiveOp, Value) from mypyc.ops_primitive import ( name_ref_op, binary_op, func_op, method_op, custom_op, simple_emit, ) name_ref_op('builtins.list', result_type=object_rprimitive, error_kind=ERR_NEVER, emit=simple_emit('{dest} = (PyObject *)&PyList_Type;'), is_borrowed=True) def emit_new(emitter: EmitterInterface, args: List[str], dest: str) -> None: # TODO: This would be better split into multiple smaller ops. emitter.emit_line('%s = PyList_New(%d); ' % (dest, len(args))) emitter.emit_line('if (%s != NULL) {' % dest) for i, arg in enumerate(args): emitter.emit_line('PyList_SET_ITEM(%s, %s, %s);' % (dest, i, arg)) emitter.emit_line('}') new_list_op = custom_op(arg_types=[object_rprimitive], result_type=list_rprimitive, is_var_arg=True,
' PyErr_SetObject(PyExc_KeyError, %s);' % args[1], 'else', ' Py_INCREF(%s);' % dest) dict_get_item_op = method_op(name='__getitem__', arg_types=[dict_rprimitive, object_rprimitive], result_type=object_rprimitive, error_kind=ERR_MAGIC, emit=emit_get_item) dict_set_item_op = method_op( name='__setitem__', arg_types=[dict_rprimitive, object_rprimitive, object_rprimitive], result_type=bool_rprimitive, error_kind=ERR_FALSE, emit=simple_emit( '{dest} = PyDict_SetItem({args[0]}, {args[1]}, {args[2]}) >= 0;')) binary_op( op='in', arg_types=[object_rprimitive, dict_rprimitive], result_type=bool_rprimitive, error_kind=ERR_MAGIC, format_str='{dest} = {args[0]} in {args[1]} :: dict', emit=negative_int_emit('{dest} = PyDict_Contains({args[1]}, {args[0]});')) # NOTE: PyDict_Update is technically not equivalent to update, but the cases where it # differs (when the second argument has no keys) should never typecheck for us, so the # difference is irrelevant. dict_update_op = method_op( name='update', arg_types=[dict_rprimitive, object_rprimitive],
binary_op, unary_op, func_op, custom_op, simple_emit, call_emit, ) # These int constructors produce object_rprimitives that then need to be unboxed # I guess unboxing ourselves would save a check and branch though? # For ordinary calls to int() we use a name_ref to the type name_ref_op('builtins.int', result_type=object_rprimitive, error_kind=ERR_NEVER, emit=simple_emit('{dest} = (PyObject *)&PyLong_Type;'), is_borrowed=True) # Convert from a float. We could do a bit better directly. func_op(name='builtins.int', arg_types=[float_rprimitive], result_type=object_rprimitive, error_kind=ERR_MAGIC, emit=call_emit('CPyLong_FromFloat'), priority=1) def int_binary_op(op: str, c_func_name: str, result_type: RType = int_rprimitive) -> None: binary_op(op=op,
Value) from mypyc.ops_primitive import ( name_ref_op, binary_op, func_op, method_op, custom_op, simple_emit, call_emit, call_negative_bool_emit, ) name_ref_op('builtins.list', result_type=object_rprimitive, error_kind=ERR_NEVER, emit=simple_emit('{dest} = (PyObject *)&PyList_Type;'), is_borrowed=True) func_op(name='builtins.list', arg_types=[object_rprimitive], result_type=list_rprimitive, error_kind=ERR_MAGIC, emit=call_emit('PySequence_List')) def emit_new(emitter: EmitterInterface, args: List[str], dest: str) -> None: # TODO: This would be better split into multiple smaller ops. emitter.emit_line('%s = PyList_New(%d); ' % (dest, len(args))) emitter.emit_line('if (likely(%s != NULL)) {' % dest) for i, arg in enumerate(args): emitter.emit_line('PyList_SET_ITEM(%s, %s, %s);' % (dest, i, arg))
binary_op, simple_emit, negative_int_emit, call_emit, call_negative_bool_emit, ) from mypyc.ops import (object_rprimitive, bool_rprimitive, set_rprimitive, int_rprimitive, ERR_MAGIC, ERR_FALSE, ERR_NEVER, EmitterInterface) from typing import List new_set_op = func_op(name='builtins.set', arg_types=[], result_type=set_rprimitive, error_kind=ERR_MAGIC, emit=simple_emit('{dest} = PySet_New(NULL);')) func_op(name='builtins.set', arg_types=[object_rprimitive], result_type=set_rprimitive, error_kind=ERR_MAGIC, emit=call_emit('PySet_New')) func_op(name='builtins.frozenset', arg_types=[object_rprimitive], result_type=object_rprimitive, error_kind=ERR_MAGIC, emit=call_emit('PyFrozenSet_New')) def emit_len(emitter: EmitterInterface, args: List[str], dest: str) -> None:
void_rtype, exc_rtuple, ERR_NEVER, ERR_MAGIC, ERR_FALSE ) from mypyc.ops_primitive import ( simple_emit, func_op, method_op, custom_op, negative_int_emit, ) # TODO: Making this raise conditionally is kind of hokey. raise_exception_op = custom_op( arg_types=[object_rprimitive, object_rprimitive], result_type=bool_rprimitive, error_kind=ERR_FALSE, format_str = 'raise_exception({args[0]}, {args[1]}); {dest} = 0', emit=simple_emit('PyErr_SetObject({args[0]}, {args[1]}); {dest} = 0;')) reraise_exception_op = custom_op( arg_types=[], result_type=bool_rprimitive, error_kind=ERR_FALSE, format_str = 'reraise_exc; {dest} = 0', emit=simple_emit('CPy_Reraise(); {dest} = 0;')) no_err_occurred_op = custom_op( arg_types=[], result_type=bool_rprimitive, error_kind=ERR_FALSE, format_str = '{dest} = no_err_occurred', emit=simple_emit('{dest} = (PyErr_Occurred() == NULL);'))
ERR_MAGIC, ERR_NEVER, ) from mypyc.ops_primitive import ( name_ref_op, method_op, binary_op, func_op, simple_emit, negative_int_emit, ) name_ref_op('builtins.dict', result_type=object_rprimitive, error_kind=ERR_NEVER, emit=simple_emit('{dest} = (PyObject *)&PyDict_Type;'), is_borrowed=True) dict_get_item_op = method_op( name='__getitem__', arg_types=[dict_rprimitive, object_rprimitive], result_type=object_rprimitive, error_kind=ERR_MAGIC, emit=simple_emit('{dest} = CPyDict_GetItem({args[0]}, {args[1]});')) dict_set_item_op = method_op( name='__setitem__', arg_types=[dict_rprimitive, object_rprimitive, object_rprimitive], result_type=bool_rprimitive, error_kind=ERR_FALSE, emit=simple_emit(
(RPrimitive, not RTuple). """ from typing import List from mypyc.ops import (EmitterInterface, PrimitiveOp, tuple_rprimitive, int_rprimitive, list_rprimitive, object_rprimitive, ERR_NEVER, ERR_MAGIC) from mypyc.ops_primitive import method_op, func_op, simple_emit tuple_get_item_op = method_op( name='__getitem__', arg_types=[tuple_rprimitive, int_rprimitive], result_type=object_rprimitive, error_kind=ERR_MAGIC, emit=simple_emit( '{dest} = CPySequenceTuple_GetItem({args[0]}, {args[1]});')) def emit_len(emitter: EmitterInterface, args: List[str], dest: str) -> None: temp = emitter.temp_name() emitter.emit_declaration('long long %s;' % temp) emitter.emit_line('%s = PyTuple_GET_SIZE(%s);' % (temp, args[0])) emitter.emit_line('%s = CPyTagged_ShortFromLongLong(%s);' % (dest, temp)) tuple_len_op = func_op(name='builtins.len', arg_types=[tuple_rprimitive], result_type=int_rprimitive, error_kind=ERR_NEVER, emit=emit_len)
RType, EmitterInterface, OpDescription, ERR_NEVER, ERR_MAGIC, ) from mypyc.ops_primitive import name_ref_op, binary_op, unary_op, func_op, simple_emit # These int constructors produce object_rprimitives that then need to be unboxed # I guess unboxing ourselves would save a check and branch though? # For ordinary calls to int() we use a name_ref to the type name_ref_op('builtins.int', result_type=object_rprimitive, error_kind=ERR_NEVER, emit=simple_emit('{dest} = (PyObject *)&PyLong_Type;'), is_borrowed=True) # Convert from a float. We could do a bit better directly. func_op(name='builtins.int', arg_types=[float_rprimitive], result_type=object_rprimitive, error_kind=ERR_MAGIC, emit=simple_emit('{dest} = CPyLong_FromFloat({args[0]});'), priority=1) def int_binary_op(op: str, c_func_name: str, result_type: RType = int_rprimitive) -> None: binary_op(op=op,
"""Primitive set ops.""" from mypyc.ops_primitive import func_op, custom_op, simple_emit from mypyc.ops import object_rprimitive, bool_rprimitive, ERR_MAGIC, ERR_FALSE new_set_op = func_op(name='builtins.set', arg_types=[], result_type=object_rprimitive, error_kind=ERR_MAGIC, format_str='{dest} = set()', emit=simple_emit('{dest} = PySet_New(NULL);')) # This operation is only used during set literal generation. The first argument must be a set. # If sets get added as special types, this will become a method_op on set rprimitives. set_add_op = custom_op( arg_types=[object_rprimitive, object_rprimitive], result_type=bool_rprimitive, error_kind=ERR_FALSE, format_str='{dest} = {args[0]}.add({args[1]})', emit=simple_emit('{dest} = PySet_Add({args[0]}, {args[1]}) == 0;'))
from typing import List, Callable from mypyc.ops import (object_rprimitive, str_rprimitive, bool_rprimitive, ERR_MAGIC, EmitterInterface) from mypyc.ops_primitive import func_op, binary_op, simple_emit func_op(name='builtins.str', arg_types=[object_rprimitive], result_type=str_rprimitive, error_kind=ERR_MAGIC, emit=simple_emit('{dest} = PyObject_Str({args[0]});')) binary_op(op='+', arg_types=[str_rprimitive, str_rprimitive], result_type=str_rprimitive, error_kind=ERR_MAGIC, emit=simple_emit('{dest} = PyUnicode_Concat({args[0]}, {args[1]});')) def emit_str_compare( comparison: str) -> Callable[[EmitterInterface, List[str], str], None]: def emit(emitter: EmitterInterface, args: List[str], dest: str) -> None: temp = emitter.temp_name() emitter.emit_declaration('int %s;' % temp) emitter.emit_lines( '%s = PyUnicode_Compare(%s, %s);' % (temp, args[0], args[1]), 'if (%s == -1 && PyErr_Occurred())' % temp, ' %s = 2;' % dest, 'else', ' %s = (%s %s);' % (dest, temp, comparison)) return emit
"""Primitive set ops.""" from mypyc.ops_primitive import func_op, method_op, binary_op, simple_emit, negative_int_emit from mypyc.ops import ( object_rprimitive, bool_rprimitive, set_rprimitive, int_rprimitive, ERR_MAGIC, ERR_FALSE, ERR_NEVER, EmitterInterface ) from typing import List new_set_op = func_op( name='builtins.set', arg_types=[], result_type=set_rprimitive, error_kind=ERR_MAGIC, emit=simple_emit('{dest} = PySet_New(NULL);') ) func_op( name='builtins.set', arg_types=[object_rprimitive], result_type=set_rprimitive, error_kind=ERR_MAGIC, emit=simple_emit('{dest} = PySet_New({args[0]});') ) def emit_len(emitter: EmitterInterface, args: List[str], dest: str) -> None: temp = emitter.temp_name() emitter.emit_declaration('long long %s;' % temp) emitter.emit_line('%s = PySet_GET_SIZE(%s);' % (temp, args[0])) emitter.emit_line('%s = CPyTagged_ShortFromLongLong(%s);' % (dest, temp))
from mypyc.ops_primitive import ( name_ref_op, method_op, binary_op, func_op, simple_emit, negative_int_emit, call_emit, call_negative_bool_emit, call_negative_magic_emit, ) name_ref_op('builtins.dict', result_type=object_rprimitive, error_kind=ERR_NEVER, emit=simple_emit('{dest} = (PyObject *)&PyDict_Type;'), is_borrowed=True) dict_get_item_op = method_op(name='__getitem__', arg_types=[dict_rprimitive, object_rprimitive], result_type=object_rprimitive, error_kind=ERR_MAGIC, emit=call_emit('CPyDict_GetItem')) dict_set_item_op = method_op( name='__setitem__', arg_types=[dict_rprimitive, object_rprimitive, object_rprimitive], result_type=bool_rprimitive, error_kind=ERR_FALSE, emit=call_negative_bool_emit('CPyDict_SetItem'))
from typing import List, Callable from mypyc.ops import (object_rprimitive, str_rprimitive, bool_rprimitive, ERR_MAGIC, ERR_NEVER, EmitterInterface, RType, int_rprimitive, list_rprimitive, EmitCallback) from mypyc.ops_primitive import func_op, binary_op, simple_emit, name_ref_op, method_op name_ref_op('builtins.str', result_type=object_rprimitive, error_kind=ERR_NEVER, emit=simple_emit('{dest} = (PyObject *)&PyUnicode_Type;'), is_borrowed=True) func_op(name='builtins.str', arg_types=[object_rprimitive], result_type=str_rprimitive, error_kind=ERR_MAGIC, emit=simple_emit('{dest} = PyObject_Str({args[0]});')) binary_op(op='+', arg_types=[str_rprimitive, str_rprimitive], result_type=str_rprimitive, error_kind=ERR_MAGIC, emit=simple_emit('{dest} = PyUnicode_Concat({args[0]}, {args[1]});')) method_op(name='join', arg_types=[str_rprimitive, object_rprimitive], result_type=str_rprimitive, error_kind=ERR_MAGIC, emit=simple_emit('{dest} = PyUnicode_Join({args[0]}, {args[1]});'))
emitter.emit_line('}') new_list_op = custom_op(arg_types=[object_rprimitive], result_type=list_rprimitive, is_var_arg=True, error_kind=ERR_MAGIC, format_str='{dest} = [{comma_args}]', emit=emit_new) list_get_item_op = method_op( name='__getitem__', arg_types=[list_rprimitive, int_rprimitive], result_type=object_rprimitive, error_kind=ERR_MAGIC, emit=simple_emit('{dest} = CPyList_GetItem({args[0]}, {args[1]});')) list_set_item_op = method_op( name='__setitem__', arg_types=[list_rprimitive, int_rprimitive, object_rprimitive], result_type=bool_rprimitive, error_kind=ERR_FALSE, emit=simple_emit( '{dest} = CPyList_SetItem({args[0]}, {args[1]}, {args[2]}) != 0;')) list_append_op = method_op( name='append', arg_types=[list_rprimitive, object_rprimitive], result_type=bool_rprimitive, error_kind=ERR_FALSE, emit=simple_emit('{dest} = PyList_Append({args[0]}, {args[1]}) != -1;'))
ERR_FALSE) from mypyc.ops_primitive import ( name_ref_op, simple_emit, binary_op, unary_op, func_op, method_op, custom_op, negative_int_emit, ) none_op = name_ref_op('builtins.None', result_type=none_rprimitive, error_kind=ERR_NEVER, emit=simple_emit('{dest} = Py_None;'), is_borrowed=True) true_op = name_ref_op('builtins.True', result_type=bool_rprimitive, error_kind=ERR_NEVER, emit=simple_emit('{dest} = 1;')) false_op = name_ref_op('builtins.False', result_type=bool_rprimitive, error_kind=ERR_NEVER, emit=simple_emit('{dest} = 0;')) ellipsis_op = custom_op( name='...', arg_types=[],
name_emit, call_negative_bool_emit, call_negative_magic_emit, ) none_object_op = custom_op(result_type=object_rprimitive, arg_types=[], error_kind=ERR_NEVER, format_str='{dest} = builtins.None :: object', emit=name_emit('Py_None'), is_borrowed=True) none_op = name_ref_op('builtins.None', result_type=none_rprimitive, error_kind=ERR_NEVER, emit=simple_emit('{dest} = 1; /* None */')) true_op = name_ref_op('builtins.True', result_type=bool_rprimitive, error_kind=ERR_NEVER, emit=simple_emit('{dest} = 1;')) false_op = name_ref_op('builtins.False', result_type=bool_rprimitive, error_kind=ERR_NEVER, emit=simple_emit('{dest} = 0;')) ellipsis_op = custom_op(name='...', arg_types=[], result_type=object_rprimitive, error_kind=ERR_NEVER,
def emit_none(emitter: EmitterInterface, args: List[str], dest: str) -> None: emitter.emit_lines('{} = Py_None;'.format(dest), 'Py_INCREF({});'.format(dest)) none_op = name_ref_op('builtins.None', result_type=none_rprimitive, error_kind=ERR_NEVER, emit=emit_none) true_op = name_ref_op('builtins.True', result_type=bool_rprimitive, error_kind=ERR_NEVER, emit=simple_emit('{dest} = 1;')) false_op = name_ref_op('builtins.False', result_type=bool_rprimitive, error_kind=ERR_NEVER, emit=simple_emit('{dest} = 0;')) iter_op = func_op(name='builtins.iter', arg_types=[object_rprimitive], result_type=object_rprimitive, error_kind=ERR_MAGIC, emit=simple_emit('{dest} = PyObject_GetIter({args[0]});')) # 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 = func_op(name='builtins.next',