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