Commit 8f854eae authored by Robert Bradshaw's avatar Robert Bradshaw

Fix cpdef after merge, change so one can still call super methods

parent 24a2be7c
......@@ -1434,12 +1434,14 @@ class SimpleCallNode(ExprNode):
# arg_tuple ExprNode or None used internally
# self ExprNode or None used internally
# coerced_self ExprNode or None used internally
# wrapper_call bool used internally
subexprs = ['self', 'coerced_self', 'function', 'args', 'arg_tuple']
self = None
coerced_self = None
arg_tuple = None
wrapper_call = False
def compile_time_value(self, denv):
function = self.function.compile_time_value(denv)
......@@ -1547,6 +1549,9 @@ class SimpleCallNode(ExprNode):
arg_list_code.append(actual_arg.result_code)
result = "%s(%s)" % (self.function.result_code,
join(arg_list_code, ","))
if self.wrapper_call or \
self.function.entry.is_unbound_cmethod and self.function.entry.is_overridable:
result = "(%s = 1, %s)" % (Naming.skip_dispatch_cname, result)
return result
def generate_result_code(self, code):
......@@ -1764,6 +1769,8 @@ class AttributeNode(ExprNode):
entry.type)
ubcm_entry.is_cfunction = 1
ubcm_entry.func_cname = entry.func_cname
ubcm_entry.is_unbound_cmethod = 1
ubcm_entry.is_overridable = entry.is_overridable
self.mutate_into_name_node(env, ubcm_entry, None)
return 1
return 0
......
......@@ -13,6 +13,7 @@ arg_prefix = pyrex_prefix + "arg_"
funcdoc_prefix = pyrex_prefix + "doc_"
enum_prefix = pyrex_prefix + "e_"
func_prefix = pyrex_prefix + "f_"
pyfunc_prefix = pyrex_prefix + "pf_"
gstab_prefix = pyrex_prefix + "getsets_"
prop_get_prefix = pyrex_prefix + "getprop_"
const_prefix = pyrex_prefix + "k"
......@@ -56,6 +57,7 @@ stringtab_cname = pyrex_prefix + "string_tab"
vtabslot_cname = pyrex_prefix + "vtab"
c_api_tab_cname = pyrex_prefix + "c_api_tab"
gilstate_cname = pyrex_prefix + "state"
skip_dispatch_cname = pyrex_prefix + "skip_dispatch"
extern_c_macro = pyrex_prefix.upper() + "EXTERN_C"
......
......@@ -768,6 +768,7 @@ class CFuncDefNode(FuncDefNode):
cname = cname, visibility = self.visibility,
defining = self.body is not None,
api = self.api)
self.entry.is_overridable = self.overridable
self.return_type = type.return_type
if self.overridable:
......@@ -775,7 +776,7 @@ class CFuncDefNode(FuncDefNode):
arg_names = [arg.name for arg in self.type.args]
self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.declarator.base.name)
c_call = ExprNodes.SimpleCallNode(self.pos, function=cfunc, args=[ExprNodes.NameNode(self.pos, name=n) for n in arg_names[1:]])
c_call = ExprNodes.SimpleCallNode(self.pos, function=cfunc, args=[ExprNodes.NameNode(self.pos, name=n) for n in arg_names[1:]], wrapper_call=True)
py_func_body = ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
self.py_func = DefNode(pos = self.pos,
name = self.declarator.base.name,
......@@ -790,7 +791,7 @@ class CFuncDefNode(FuncDefNode):
if Options.intern_names:
self.py_func.interned_attr_cname = env.intern(self.py_func.entry.name)
self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
self.body.stats.insert(0, self.override)
self.body = StatListNode(self.pos, stats=[self.override, self.body])
def declare_arguments(self, env):
......@@ -1020,7 +1021,7 @@ class DefNode(FuncDefNode):
self.entry = entry
prefix = env.scope_prefix
entry.func_cname = \
Naming.func_prefix + prefix + name
Naming.pyfunc_prefix + prefix + name
entry.pymethdef_cname = \
Naming.pymethdef_prefix + prefix + name
if not entry.is_special:
......@@ -1389,8 +1390,10 @@ class OverrideCheckNode(StatNode):
def generate_execution_code(self, code):
# Check to see if we are an extension type
self_arg = "((PyObject *)%s)" % self.args[0].cname
code.putln("/* Check if called by wrapper */")
code.putln("if (unlikely(%s)) %s = 0;" % (Naming.skip_dispatch_cname, Naming.skip_dispatch_cname))
code.putln("/* Check if overriden in Python */")
code.putln("if (unlikely(%s->ob_type->tp_dictoffset != 0)) {" % self_arg)
code.putln("else if (unlikely(%s->ob_type->tp_dictoffset != 0)) {" % self_arg)
err = code.error_goto_if_null(self_arg, self.pos)
# need to get attribute manually--scope would return cdef method
if Options.intern_names:
......@@ -2950,7 +2953,11 @@ static INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
else return PyObject_IsTrue(x);
}
"""
""" + """
static int %(skip_dispatch_cname)s = 0;
""" % { 'skip_dispatch_cname': Naming.skip_dispatch_cname }
if Options.gcc_branch_hints:
branch_prediction_macros = \
......
......@@ -34,6 +34,7 @@ class Entry:
# is_variable boolean Is a variable
# is_cfunction boolean Is a C function
# is_cmethod boolean Is a C method of an extension type
# is_unbound_cmethod boolean Is an unbound C method of an extension type
# is_type boolean Is a type definition
# is_const boolean Is a constant
# is_property boolean Is a property of an extension type:
......@@ -81,6 +82,7 @@ class Entry:
is_variable = 0
is_cfunction = 0
is_cmethod = 0
is_unbound_cmethod = 0
is_type = 0
is_const = 0
is_property = 0
......
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