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

Avoid call to PyArg_ParseTupleAndKeywords for zero- and single-argument functions.

parent 57edf105
...@@ -294,7 +294,7 @@ class CCodeWriter: ...@@ -294,7 +294,7 @@ class CCodeWriter:
'{"%s", (PyCFunction)%s, %s, %s}%s' % ( '{"%s", (PyCFunction)%s, %s, %s}%s' % (
entry.name, entry.name,
entry.func_cname, entry.func_cname,
entry.meth_flags, "|".join(entry.meth_flags),
doc_code, doc_code,
term)) term))
......
...@@ -8,6 +8,7 @@ import Code ...@@ -8,6 +8,7 @@ import Code
from Errors import error, warning, InternalError from Errors import error, warning, InternalError
import Naming import Naming
import PyrexTypes import PyrexTypes
import TypeSlots
from PyrexTypes import py_object_type, error_type, CTypedefType from PyrexTypes import py_object_type, error_type, CTypedefType
from Symtab import ModuleScope, LocalScope, \ from Symtab import ModuleScope, LocalScope, \
StructOrUnionScope, PyClassScope, CClassScope StructOrUnionScope, PyClassScope, CClassScope
...@@ -819,6 +820,13 @@ class DefNode(FuncDefNode): ...@@ -819,6 +820,13 @@ class DefNode(FuncDefNode):
def analyse_signature(self, env): def analyse_signature(self, env):
any_type_tests_needed = 0 any_type_tests_needed = 0
if self.entry.signature is TypeSlots.pymethod_signature:
if len(self.args) == 1:
self.entry.signature = TypeSlots.unaryfunc
self.entry.meth_flags = [TypeSlots.method_noargs]
elif len(self.args) == 2 and self.args[1].type.is_pyobject and self.args[1].default is None:
self.entry.signature = TypeSlots.ibinaryfunc
self.entry.meth_flags = [TypeSlots.method_onearg]
sig = self.entry.signature sig = self.entry.signature
nfixed = sig.num_fixed_args() nfixed = sig.num_fixed_args()
for i in range(nfixed): for i in range(nfixed):
...@@ -963,6 +971,8 @@ class DefNode(FuncDefNode): ...@@ -963,6 +971,8 @@ class DefNode(FuncDefNode):
else: else:
arg_code_list.append( arg_code_list.append(
arg.hdr_type.declaration_code(arg.hdr_cname)) arg.hdr_type.declaration_code(arg.hdr_cname))
if self.entry.meth_flags == [TypeSlots.method_noargs]:
arg_code_list.append("PyObject *unused")
if sig.has_generic_args: if sig.has_generic_args:
arg_code_list.append( arg_code_list.append(
"PyObject *%s, PyObject *%s" "PyObject *%s, PyObject *%s"
......
...@@ -303,7 +303,7 @@ class Scope: ...@@ -303,7 +303,7 @@ class Scope:
# Add an entry for a Python function. # Add an entry for a Python function.
entry = self.declare_var(name, py_object_type, pos) entry = self.declare_var(name, py_object_type, pos)
entry.signature = pyfunction_signature entry.signature = pyfunction_signature
entry.meth_flags = "METH_VARARGS|METH_KEYWORDS" entry.meth_flags = [TypeSlots.method_varargs, TypeSlots.method_keywords]
self.pyfunc_entries.append(entry) self.pyfunc_entries.append(entry)
return entry return entry
...@@ -1091,13 +1091,13 @@ class CClassScope(ClassScope): ...@@ -1091,13 +1091,13 @@ class CClassScope(ClassScope):
# signature declared in advance. # signature declared in advance.
entry.signature = special_sig entry.signature = special_sig
if special_sig == TypeSlots.unaryfunc: if special_sig == TypeSlots.unaryfunc:
entry.meth_flags = "METH_NOARGS|METH_COEXIST" entry.meth_flags = [TypeSlots.method_noargs, TypeSlots.method_coexist]
elif special_sig == TypeSlots.binaryfunc or special_sig == TypeSlots.ibinaryfunc: elif special_sig == TypeSlots.binaryfunc or special_sig == TypeSlots.ibinaryfunc:
entry.meth_flags = "METH_O|METH_COEXIST" entry.meth_flags = [TypeSlots.method_onearg, TypeSlots.method_coexist]
else: else:
entry.meth_flags = None # should it generate a wrapper function? entry.meth_flags = None # should it generate a wrapper function?
else: else:
entry.meth_flags = "METH_VARARGS|METH_KEYWORDS" entry.meth_flags = [TypeSlots.method_varargs, TypeSlots.method_keywords]
entry.signature = pymethod_signature entry.signature = pymethod_signature
self.pyfunc_entries.append(entry) self.pyfunc_entries.append(entry)
......
...@@ -590,3 +590,12 @@ MethodSlot(delattrofunc, "", "__delattr__") ...@@ -590,3 +590,12 @@ MethodSlot(delattrofunc, "", "__delattr__")
MethodSlot(descrgetfunc, "", "__get__") MethodSlot(descrgetfunc, "", "__get__")
MethodSlot(descrsetfunc, "", "__set__") MethodSlot(descrsetfunc, "", "__set__")
MethodSlot(descrdelfunc, "", "__delete__") MethodSlot(descrdelfunc, "", "__delete__")
# Method flags for python-exposed methods.
method_noargs = "METH_NOARGS"
method_onearg = "METH_O"
method_varargs = "METH_VARARGS"
method_keywords = "METH_KEYWORDS"
method_coexist = "METH_COEXIST"
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