Пример #1
0
)

# 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,
                  error_kind: int = ERR_NEVER) -> None:
    binary_op(op=op,
              arg_types=[int_rprimitive, int_rprimitive],
              result_type=result_type,
              error_kind=error_kind,
              format_str='{dest} = {args[0]} %s {args[1]} :: int' % op,
              emit=call_emit(c_func_name))
Пример #2
0
"""Primitive set (and frozenset) ops."""

from mypyc.primitives.registry import (func_op, method_op, binary_op,
                                       simple_emit, negative_int_emit,
                                       call_negative_bool_emit, c_function_op,
                                       c_method_op)
from mypyc.ir.ops import ERR_MAGIC, ERR_FALSE, ERR_NEVER, ERR_NEG_INT, EmitterInterface
from mypyc.ir.rtypes import (object_rprimitive, bool_rprimitive,
                             set_rprimitive, int_rprimitive, c_int_rprimitive)
from typing import List

# Construct an empty set.
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);'))

# set(obj)
c_function_op(name='builtins.set',
              arg_types=[object_rprimitive],
              return_type=set_rprimitive,
              c_function_name='PySet_New',
              error_kind=ERR_MAGIC)

# frozenset(obj)
c_function_op(name='builtins.frozenset',
              arg_types=[object_rprimitive],
              return_type=object_rprimitive,
              c_function_name='PyFrozenSet_New',
              error_kind=ERR_MAGIC)
Пример #3
0
# Construct a dictionary from keys and values.
# Arguments are (key1, value1, ..., keyN, valueN).
new_dict_op = custom_op(
    name='builtins.dict',
    arg_types=[object_rprimitive],
    is_var_arg=True,
    result_type=dict_rprimitive,
    format_str='{dest} = {{{colon_args}}}',
    error_kind=ERR_MAGIC,
    emit=emit_new_dict)

# Construct a dictionary from another dictionary.
func_op(
    name='builtins.dict',
    arg_types=[dict_rprimitive],
    result_type=dict_rprimitive,
    error_kind=ERR_MAGIC,
    emit=call_emit('PyDict_Copy'),
    priority=2)

# Generic one-argument dict constructor: dict(obj)
func_op(
    name='builtins.dict',
    arg_types=[object_rprimitive],
    result_type=dict_rprimitive,
    error_kind=ERR_MAGIC,
    emit=call_emit('CPyDict_FromAny'))


def emit_len(emitter: EmitterInterface, args: List[str], dest: str) -> None:
    temp = emitter.temp_name()
Пример #4
0
                             bool_rprimitive, int_rprimitive, list_rprimitive)
from mypyc.primitives.registry import (func_op, binary_op, simple_emit,
                                       name_ref_op, method_op, call_emit,
                                       name_emit, c_method_op)

# Get the 'str' type object.
name_ref_op('builtins.str',
            result_type=object_rprimitive,
            error_kind=ERR_NEVER,
            emit=name_emit('&PyUnicode_Type', target_type='PyObject *'),
            is_borrowed=True)

# str(obj)
func_op(name='builtins.str',
        arg_types=[object_rprimitive],
        result_type=str_rprimitive,
        error_kind=ERR_MAGIC,
        emit=call_emit('PyObject_Str'))

# str1 + str2
binary_op(op='+',
          arg_types=[str_rprimitive, str_rprimitive],
          result_type=str_rprimitive,
          error_kind=ERR_MAGIC,
          emit=call_emit('PyUnicode_Concat'))

# str.join(obj)
c_method_op(name='join',
            arg_types=[str_rprimitive, object_rprimitive],
            return_type=str_rprimitive,
            c_function_name='PyUnicode_Join',
Пример #5
0
                               is_borrowed=True)

# isinstance(obj, cls)
c_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 = func_op(
    'builtins.isinstance',
    arg_types=[object_rprimitive, object_rprimitive],
    result_type=bool_rprimitive,
    error_kind=ERR_NEVER,
    emit=simple_emit(
        '{dest} = PyObject_TypeCheck({args[0]}, (PyTypeObject *){args[1]});'),
    priority=0)

# Exact type check that doesn't consider subclasses: type(obj) is cls
type_is_op = custom_op(
    name='type_is',
    arg_types=[object_rprimitive, object_rprimitive],
    result_type=bool_rprimitive,
    error_kind=ERR_NEVER,
    emit=simple_emit(
        '{dest} = Py_TYPE({args[0]}) == (PyTypeObject *){args[1]};'))

# bool(obj) with unboxed result
bool_op = func_op('builtins.bool',
Пример #6
0
from typing import List, Callable

from mypyc.ops import ERR_MAGIC, ERR_NEVER, EmitterInterface, EmitCallback
from mypyc.rtypes import (RType, object_rprimitive, str_rprimitive,
                          bool_rprimitive, int_rprimitive, list_rprimitive)
from mypyc.primitives.registry 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]});'))
Пример #7
0
# 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 name_ref to the type
name_ref_op('builtins.int',
            result_type=object_rprimitive,
            error_kind=ERR_NEVER,
            emit=name_emit('&PyLong_Type', target_type='PyObject *'),
            is_borrowed=True)

# Convert from a float to int. 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)

# int(string)
func_op(
    name='builtins.int',
    arg_types=[str_rprimitive],
    result_type=object_rprimitive,
    error_kind=ERR_MAGIC,
    emit=call_emit('CPyLong_FromStr'),
    priority=1)

# int(string, base)
func_op(
Пример #8
0
                                 is_borrowed=True)

# isinstance(obj, cls)
c_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 = func_op(
    'builtins.isinstance',
    arg_types=[object_rprimitive, object_rprimitive],
    result_type=bool_rprimitive,
    error_kind=ERR_NEVER,
    emit=simple_emit(
        '{dest} = PyObject_TypeCheck({args[0]}, (PyTypeObject *){args[1]});'),
    priority=0)

# Exact type check that doesn't consider subclasses: type(obj) is cls
type_is_op = custom_op(
    name='type_is',
    arg_types=[object_rprimitive, object_rprimitive],
    result_type=bool_rprimitive,
    error_kind=ERR_NEVER,
    emit=simple_emit(
        '{dest} = Py_TYPE({args[0]}) == (PyTypeObject *){args[1]};'))

# bool(obj) with unboxed result
bool_op = c_function_op(name='builtins.bool',
Пример #9
0
                          result_type=list_rprimitive,
                          error_kind=ERR_MAGIC,
                          emit=call_emit('CPyDict_Items'))


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 = PyDict_Size(%s);' % (temp, args[0]))
    emitter.emit_line('%s = CPyTagged_ShortFromSsize_t(%s);' % (dest, temp))


# len(dict)
func_op(name='builtins.len',
        arg_types=[dict_rprimitive],
        result_type=int_rprimitive,
        error_kind=ERR_NEVER,
        emit=emit_len)

# PyDict_Next() fast iteration
dict_key_iter_op = custom_op(
    name='key_iter',
    arg_types=[dict_rprimitive],
    result_type=object_rprimitive,
    error_kind=ERR_MAGIC,
    emit=call_emit('CPyDict_GetKeysIter'),
)

dict_value_iter_op = custom_op(
    name='value_iter',
    arg_types=[dict_rprimitive],
Пример #10
0
            error_kind=ERR_MAGIC)

# list * int
c_binary_op(name='*',
            arg_types=[list_rprimitive, int_rprimitive],
            return_type=list_rprimitive,
            c_function_name='CPySequence_Multiply',
            error_kind=ERR_MAGIC)

# int * list
c_binary_op(name='*',
            arg_types=[int_rprimitive, list_rprimitive],
            return_type=list_rprimitive,
            c_function_name='CPySequence_RMultiply',
            error_kind=ERR_MAGIC)


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 = PyList_GET_SIZE(%s);' % (temp, args[0]))
    emitter.emit_line('%s = CPyTagged_ShortFromSsize_t(%s);' % (dest, temp))


# len(list)
list_len_op = func_op(name='builtins.len',
                      arg_types=[list_rprimitive],
                      result_type=short_int_rprimitive,
                      error_kind=ERR_NEVER,
                      emit=emit_len)
Пример #11
0
          error_kind=ERR_FALSE,
          emit=call_negative_bool_emit('PyObject_SetItem'),
          priority=0)

# del obj1[obj2]
method_op('__delitem__',
          arg_types=[object_rprimitive, object_rprimitive],
          result_type=bool_rprimitive,
          error_kind=ERR_FALSE,
          emit=call_negative_bool_emit('PyObject_DelItem'),
          priority=0)

# hash(obj)
func_op(
    name='builtins.hash',
    arg_types=[object_rprimitive],
    result_type=int_rprimitive,
    error_kind=ERR_MAGIC,
    emit=call_emit('CPyObject_Hash'))

# getattr(obj, attr)
py_getattr_op = func_op(
    name='builtins.getattr',
    arg_types=[object_rprimitive, object_rprimitive],
    result_type=object_rprimitive,
    error_kind=ERR_MAGIC,
    emit=call_emit('CPyObject_GetAttr')
)

# getattr(obj, attr, default)
func_op(
    name='builtins.getattr',
Пример #12
0
ellipsis_op = custom_op(name='...',
                        arg_types=[],
                        result_type=object_rprimitive,
                        error_kind=ERR_NEVER,
                        emit=name_emit('Py_Ellipsis'),
                        is_borrowed=True)

not_implemented_op = name_ref_op(name='builtins.NotImplemented',
                                 result_type=object_rprimitive,
                                 error_kind=ERR_NEVER,
                                 emit=name_emit('Py_NotImplemented'),
                                 is_borrowed=True)

func_op(name='builtins.id',
        arg_types=[object_rprimitive],
        result_type=int_rprimitive,
        error_kind=ERR_NEVER,
        emit=call_emit('CPyTagged_Id'))

iter_op = func_op(name='builtins.iter',
                  arg_types=[object_rprimitive],
                  result_type=object_rprimitive,
                  error_kind=ERR_MAGIC,
                  emit=call_emit('PyObject_GetIter'))

coro_op = custom_op(name='get_coroutine_obj',
                    arg_types=[object_rprimitive],
                    result_type=object_rprimitive,
                    error_kind=ERR_MAGIC,
                    emit=call_emit('CPy_GetCoro'))
Пример #13
0
    name_emit,
    call_emit,
    call_negative_bool_emit,
)

# Get the 'builtins.list' type object.
name_ref_op('builtins.list',
            result_type=object_rprimitive,
            error_kind=ERR_NEVER,
            emit=name_emit('&PyList_Type', target_type='PyObject *'),
            is_borrowed=True)

# list(obj)
to_list = 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))
    emitter.emit_line('}')


# Construct a list from values: [item1, item2, ....]
new_list_op = custom_op(arg_types=[object_rprimitive],
Пример #14
0
    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)


list_tuple_op = func_op(
    name='builtins.tuple',
    arg_types=[list_rprimitive],
    result_type=tuple_rprimitive,
    error_kind=ERR_MAGIC,
    emit=call_emit('PyList_AsTuple'),
    priority=2)

func_op(
    name='builtins.tuple',
    arg_types=[object_rprimitive],