cython-devel

changeset 912:fe3d5f426ff2

Fix optional cdef arguments for c++, possible optimization when not all args are used.
author Robert Bradshaw <robertwb@math.washington.edu>
date Sun Aug 03 04:02:45 2008 -0700 (3 years ago)
parents 464b7f41f688
children f69dab8c46d8
files Cython/Compiler/ExprNodes.py Demos/Setup.py tests/run/cdefoptargs.pyx
line diff
1.1 --- a/Cython/Compiler/ExprNodes.py Sun Aug 03 09:47:55 2008 +0200 1.2 +++ b/Cython/Compiler/ExprNodes.py Sun Aug 03 04:02:45 2008 -0700 1.3 @@ -1680,6 +1680,7 @@ 1.4 # self ExprNode or None used internally 1.5 # coerced_self ExprNode or None used internally 1.6 # wrapper_call bool used internally 1.7 + # has_optional_args bool used internally 1.8 1.9 subexprs = ['self', 'coerced_self', 'function', 'args', 'arg_tuple'] 1.10 1.11 @@ -1687,6 +1688,7 @@ 1.12 coerced_self = None 1.13 arg_tuple = None 1.14 wrapper_call = False 1.15 + has_optional_args = False 1.16 1.17 def compile_time_value(self, denv): 1.18 function = self.function.compile_time_value(denv) 1.19 @@ -1773,6 +1775,11 @@ 1.20 self.type = PyrexTypes.error_type 1.21 self.result_code = "<error>" 1.22 return 1.23 + if func_type.optional_arg_count and expected_nargs != actual_nargs: 1.24 + self.has_optional_args = 1 1.25 + self.is_temp = 1 1.26 + self.opt_arg_struct = env.allocate_temp(func_type.op_arg_struct.base_type) 1.27 + env.release_temp(self.opt_arg_struct) 1.28 # Coerce arguments 1.29 for i in range(min(max_nargs, actual_nargs)): 1.30 formal_type = func_type.args[i].type 1.31 @@ -1818,15 +1825,7 @@ 1.32 if expected_nargs == actual_nargs: 1.33 optional_args = 'NULL' 1.34 else: 1.35 - optional_arg_code = [str(actual_nargs - expected_nargs)] 1.36 - for formal_arg, actual_arg in args[expected_nargs:actual_nargs]: 1.37 - arg_code = actual_arg.result_as(formal_arg.type) 1.38 - optional_arg_code.append(arg_code) 1.39 -# for formal_arg in formal_args[actual_nargs:max_nargs]: 1.40 -# optional_arg_code.append(formal_arg.type.cast_code('0')) 1.41 - optional_arg_struct = '{%s}' % ','.join(optional_arg_code) 1.42 - optional_args = PyrexTypes.c_void_ptr_type.cast_code( 1.43 - '&' + func_type.op_arg_struct.base_type.cast_code(optional_arg_struct)) 1.44 + optional_args = "&%s" % self.opt_arg_struct 1.45 arg_list_code.append(optional_args) 1.46 1.47 for actual_arg in self.args[len(formal_args):]: 1.48 @@ -1849,6 +1848,19 @@ 1.49 arg_code, 1.50 code.error_goto_if_null(self.result_code, self.pos))) 1.51 elif func_type.is_cfunction: 1.52 + if self.has_optional_args: 1.53 + actual_nargs = len(self.args) 1.54 + expected_nargs = len(func_type.args) - func_type.optional_arg_count 1.55 + code.putln("%s.%s = %s;" % ( 1.56 + self.opt_arg_struct, 1.57 + Naming.pyrex_prefix + "n", 1.58 + len(self.args) - expected_nargs)) 1.59 + args = zip(func_type.args, self.args) 1.60 + for formal_arg, actual_arg in args[expected_nargs:actual_nargs]: 1.61 + code.putln("%s.%s = %s;" % ( 1.62 + self.opt_arg_struct, 1.63 + formal_arg.name, 1.64 + actual_arg.result_as(formal_arg.type))) 1.65 exc_checks = [] 1.66 if self.type.is_pyobject: 1.67 exc_checks.append("!%s" % self.result_code) 1.68 @@ -1883,12 +1895,12 @@ 1.69 rhs, 1.70 raise_py_exception, 1.71 code.error_goto(self.pos))) 1.72 - return 1.73 - code.putln( 1.74 - "%s%s; %s" % ( 1.75 - lhs, 1.76 - rhs, 1.77 - code.error_goto_if(" && ".join(exc_checks), self.pos))) 1.78 + else: 1.79 + if exc_checks: 1.80 + goto_error = code.error_goto_if(" && ".join(exc_checks), self.pos) 1.81 + else: 1.82 + goto_error = "" 1.83 + code.putln("%s%s; %s" % (lhs, rhs, goto_error)) 1.84 1.85 class GeneralCallNode(CallNode): 1.86 # General Python function call, including keyword,
2.1 --- a/Demos/Setup.py Sun Aug 03 09:47:55 2008 +0200 2.2 +++ b/Demos/Setup.py Sun Aug 03 04:02:45 2008 -0700 2.3 @@ -7,7 +7,6 @@ 2.4 ext_modules=[ 2.5 Extension("primes", ["primes.pyx"]), 2.6 Extension("spam", ["spam.pyx"]), 2.7 -# Extension("optargs", ["optargs.pyx"], language = "c++"), 2.8 ] 2.9 2.10 for file in glob.glob("*.pyx"):
3.1 --- a/tests/run/cdefoptargs.pyx Sun Aug 03 09:47:55 2008 +0200 3.2 +++ b/tests/run/cdefoptargs.pyx Sun Aug 03 04:02:45 2008 -0700 3.3 @@ -2,6 +2,11 @@ 3.4 >>> call2() 3.5 >>> call3() 3.6 >>> call4() 3.7 + >>> test_foo() 3.8 + 2 3.9 + 3 3.10 + 7 3.11 + 26 3.12 """ 3.13 3.14 # the calls: 3.15 @@ -19,3 +24,13 @@ 3.16 3.17 cdef b(a, b, c=1, d=2): 3.18 pass 3.19 + 3.20 + 3.21 +cdef int foo(int a, int b=1, int c=1): 3.22 + return a+b*c 3.23 + 3.24 +def test_foo(): 3.25 + print foo(1) 3.26 + print foo(1, 2) 3.27 + print foo(1, 2, 3) 3.28 + print foo(1, foo(2, 3), foo(4))