# 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)
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):
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
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"
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"
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:
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,
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):
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:
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:
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 = \