Commit fb6c602d authored by Stefan Behnel's avatar Stefan Behnel

Merge branch '0.29.x'

parents 6644799d 02bb311d
...@@ -2035,35 +2035,43 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -2035,35 +2035,43 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
def generate_binop_function(self, scope, slot, code): def generate_binop_function(self, scope, slot, code):
func_name = scope.mangle_internal(slot.slot_name) func_name = scope.mangle_internal(slot.slot_name)
if scope.directives['c_api_binop_methods']:
code.putln('#define %s %s' % (func_name, slot.left_slot.slot_code(scope)))
return
code.putln() code.putln()
preprocessor_guard = slot.preprocessor_guard_code() preprocessor_guard = slot.preprocessor_guard_code()
if preprocessor_guard: if preprocessor_guard:
code.putln(preprocessor_guard) code.putln(preprocessor_guard)
if scope.directives['c_api_binop_methods']:
code.putln('#define %s %s' % (func_name, slot.left_slot.slot_code(scope)))
else:
if slot.left_slot.signature == TypeSlots.binaryfunc: if slot.left_slot.signature == TypeSlots.binaryfunc:
slot_type = 'binaryfunc'
extra_arg = extra_arg_decl = '' extra_arg = extra_arg_decl = ''
elif slot.left_slot.signature == TypeSlots.ternaryfunc: elif slot.left_slot.signature == TypeSlots.ternaryfunc:
slot_type = 'ternaryfunc'
extra_arg = ', extra_arg' extra_arg = ', extra_arg'
extra_arg_decl = ', PyObject* extra_arg' extra_arg_decl = ', PyObject* extra_arg'
else: else:
error(entry.pos, "Unexpected type lost signature: %s" % slot) error(entry.pos, "Unexpected type lost signature: %s" % slot)
def has_slot_method(method_name): def has_slot_method(method_name):
entry = scope.lookup(method_name) entry = scope.lookup(method_name)
return bool(entry and entry.is_special and entry.func_cname) return bool(entry and entry.is_special and entry.func_cname)
def call_slot_method(method_name, reverse): def call_slot_method(method_name, reverse):
entry = scope.lookup(method_name) entry = scope.lookup(method_name)
if entry and entry.is_special and entry.func_cname: if entry and entry.is_special and entry.func_cname:
return "%s(%s%s)" % (entry.func_cname, "right, left" if reverse else "left, right", extra_arg) return "%s(%s%s)" % (
entry.func_cname,
"right, left" if reverse else "left, right",
extra_arg)
else: else:
super = 'Py_TYPE(right)->tp_base' if reverse else 'Py_TYPE(left)->tp_base' return '%s_maybe_call_slot(%s, left, right %s)' % (
return ('(%s->tp_as_number && %s->tp_as_number->%s)' func_name,
' ? %s->tp_as_number->%s(left, right %s)' 'Py_TYPE(right)->tp_base' if reverse else 'Py_TYPE(left)->tp_base',
' : (Py_INCREF(Py_NotImplemented), Py_NotImplemented)') % ( extra_arg)
super, super, slot.slot_name, super, slot.slot_name, extra_arg)
code.putln( code.putln(
TempitaUtilityCode.load_cached( TempitaUtilityCode.load_as_string(
"BinopSlot", "ExtensionTypes.c", "BinopSlot", "ExtensionTypes.c",
context={ context={
"func_name": func_name, "func_name": func_name,
...@@ -2072,10 +2080,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -2072,10 +2080,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
"call_left": call_slot_method(slot.left_slot.method_name, reverse=False), "call_left": call_slot_method(slot.left_slot.method_name, reverse=False),
"call_right": call_slot_method(slot.right_slot.method_name, reverse=True), "call_right": call_slot_method(slot.right_slot.method_name, reverse=True),
"type_cname": scope.parent_type.typeptr_cname, "type_cname": scope.parent_type.typeptr_cname,
"slot_type": slot_type,
"extra_arg": extra_arg, "extra_arg": extra_arg,
"extra_arg_decl": extra_arg_decl, "extra_arg_decl": extra_arg_decl,
}).impl.strip()) })[1])
code.putln()
if preprocessor_guard: if preprocessor_guard:
code.putln("#endif") code.putln("#endif")
......
...@@ -329,24 +329,39 @@ __PYX_GOOD: ...@@ -329,24 +329,39 @@ __PYX_GOOD:
/////////////// BinopSlot /////////////// /////////////// BinopSlot ///////////////
static CYTHON_INLINE PyObject *{{func_name}}_maybe_call_slot(PyTypeObject* type, PyObject *left, PyObject *right {{extra_arg_decl}}) {
{{slot_type}} slot;
#if CYTHON_USE_TYPE_SLOTS
slot = type->tp_as_number ? type->tp_as_number->{{slot_name}} : NULL;
#else
slot = ({{slot_type}}) PyType_GetSlot(type, Py_{{slot_name}});
#endif
return slot ? slot(left, right {{extra_arg}}) : __Pyx_NewRef(Py_NotImplemented);
}
static PyObject *{{func_name}}(PyObject *left, PyObject *right {{extra_arg_decl}}) { static PyObject *{{func_name}}(PyObject *left, PyObject *right {{extra_arg_decl}}) {
PyObject *res; PyObject *res;
int maybe_self_is_left, maybe_self_is_right = 0; int maybe_self_is_left, maybe_self_is_right = 0;
maybe_self_is_left = Py_TYPE(left) == Py_TYPE(right) maybe_self_is_left = Py_TYPE(left) == Py_TYPE(right)
#if CYTHON_USE_TYPE_SLOTS
|| (Py_TYPE(left)->tp_as_number && Py_TYPE(left)->tp_as_number->{{slot_name}} == &{{func_name}}) || (Py_TYPE(left)->tp_as_number && Py_TYPE(left)->tp_as_number->{{slot_name}} == &{{func_name}})
|| PyType_IsSubtype(Py_TYPE(left), {{type_cname}}); #endif
|| __Pyx_TypeCheck(left, {{type_cname}});
// Optimize for the common case where the left operation is defined (and successful). // Optimize for the common case where the left operation is defined (and successful).
if (!{{overloads_left}}) { if (!{{overloads_left}}) {
maybe_self_is_right = Py_TYPE(left) == Py_TYPE(right) maybe_self_is_right = Py_TYPE(left) == Py_TYPE(right)
#if CYTHON_USE_TYPE_SLOTS
|| (Py_TYPE(right)->tp_as_number && Py_TYPE(right)->tp_as_number->{{slot_name}} == &{{func_name}}) || (Py_TYPE(right)->tp_as_number && Py_TYPE(right)->tp_as_number->{{slot_name}} == &{{func_name}})
|| PyType_IsSubtype(Py_TYPE(right), {{type_cname}}); #endif
|| __Pyx_TypeCheck(right, {{type_cname}});
} }
if (maybe_self_is_left) { if (maybe_self_is_left) {
if (maybe_self_is_right && !{{overloads_left}}) { if (maybe_self_is_right && !{{overloads_left}}) {
res = {{call_right}}; res = {{call_right}};
if (res != Py_NotImplemented) return res; if (res != Py_NotImplemented) return res;
Py_DECREF(res); Py_DECREF(res);
maybe_self_is_right = 0; // Don't bother calling it again. // Don't bother calling it again.
maybe_self_is_right = 0;
} }
res = {{call_left}}; res = {{call_left}};
if (res != Py_NotImplemented) return res; if (res != Py_NotImplemented) return res;
...@@ -354,11 +369,13 @@ static PyObject *{{func_name}}(PyObject *left, PyObject *right {{extra_arg_decl} ...@@ -354,11 +369,13 @@ static PyObject *{{func_name}}(PyObject *left, PyObject *right {{extra_arg_decl}
} }
if ({{overloads_left}}) { if ({{overloads_left}}) {
maybe_self_is_right = Py_TYPE(left) == Py_TYPE(right) maybe_self_is_right = Py_TYPE(left) == Py_TYPE(right)
#if CYTHON_USE_TYPE_SLOTS
|| (Py_TYPE(right)->tp_as_number && Py_TYPE(right)->tp_as_number->{{slot_name}} == &{{func_name}}) || (Py_TYPE(right)->tp_as_number && Py_TYPE(right)->tp_as_number->{{slot_name}} == &{{func_name}})
#endif
|| PyType_IsSubtype(Py_TYPE(right), {{type_cname}}); || PyType_IsSubtype(Py_TYPE(right), {{type_cname}});
} }
if (maybe_self_is_right) { if (maybe_self_is_right) {
return {{call_right}}; return {{call_right}};
} }
return Py_INCREF(Py_NotImplemented), Py_NotImplemented; return __Pyx_NewRef(Py_NotImplemented);
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment