Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
nexedi
cython
Commits
519a19a9
Commit
519a19a9
authored
Jan 08, 2012
by
Vitja Makarov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
DefNode: split into function and python wrapper
parent
262bc9fb
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
286 additions
and
106 deletions
+286
-106
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+3
-2
Cython/Compiler/Naming.py
Cython/Compiler/Naming.py
+1
-0
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+281
-104
Cython/Compiler/Symtab.py
Cython/Compiler/Symtab.py
+1
-0
No files found.
Cython/Compiler/ExprNodes.py
View file @
519a19a9
...
@@ -6252,15 +6252,16 @@ class GeneratorExpressionNode(LambdaNode):
...
@@ -6252,15 +6252,16 @@ class GeneratorExpressionNode(LambdaNode):
super
(
GeneratorExpressionNode
,
self
).
analyse_declarations
(
env
)
super
(
GeneratorExpressionNode
,
self
).
analyse_declarations
(
env
)
# No pymethdef required
# No pymethdef required
self
.
def_node
.
pymethdef_required
=
False
self
.
def_node
.
pymethdef_required
=
False
self
.
def_node
.
py_wrapper_required
=
False
self
.
def_node
.
is_cyfunction
=
False
self
.
def_node
.
is_cyfunction
=
False
# Force genexpr signature
# Force genexpr signature
self
.
def_node
.
entry
.
signature
=
TypeSlots
.
pyfunction_noargs
self
.
def_node
.
entry
.
signature
=
TypeSlots
.
pyfunction_noargs
def
generate_result_code
(
self
,
code
):
def
generate_result_code
(
self
,
code
):
code
.
putln
(
code
.
putln
(
'%s = %s(%s
, NULL
); %s'
%
(
'%s = %s(%s); %s'
%
(
self
.
result
(),
self
.
result
(),
self
.
def_node
.
entry
.
func_cname
,
self
.
def_node
.
entry
.
py
func_cname
,
self
.
self_result_code
(),
self
.
self_result_code
(),
code
.
error_goto_if_null
(
self
.
result
(),
self
.
pos
)))
code
.
error_goto_if_null
(
self
.
result
(),
self
.
pos
)))
code
.
put_gotref
(
self
.
py_result
())
code
.
put_gotref
(
self
.
py_result
())
...
...
Cython/Compiler/Naming.py
View file @
519a19a9
...
@@ -19,6 +19,7 @@ funcdoc_prefix = pyrex_prefix + "doc_"
...
@@ -19,6 +19,7 @@ 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_"
pyfunc_prefix
=
pyrex_prefix
+
"pf_"
pywrap_prefix
=
pyrex_prefix
+
"pw_"
genbody_prefix
=
pyrex_prefix
+
"gb_"
genbody_prefix
=
pyrex_prefix
+
"gb_"
gstab_prefix
=
pyrex_prefix
+
"getsets_"
gstab_prefix
=
pyrex_prefix
+
"getsets_"
prop_get_prefix
=
pyrex_prefix
+
"getprop_"
prop_get_prefix
=
pyrex_prefix
+
"getprop_"
...
...
Cython/Compiler/Nodes.py
View file @
519a19a9
...
@@ -1405,14 +1405,7 @@ class FuncDefNode(StatNode, BlockNode):
...
@@ -1405,14 +1405,7 @@ class FuncDefNode(StatNode, BlockNode):
if
'cython_unused'
not
in
self
.
modifiers
:
if
'cython_unused'
not
in
self
.
modifiers
:
self
.
modifiers
=
self
.
modifiers
+
[
'cython_unused'
]
self
.
modifiers
=
self
.
modifiers
+
[
'cython_unused'
]
preprocessor_guard
=
None
preprocessor_guard
=
self
.
get_preprocessor_guard
()
if
self
.
entry
.
is_special
and
not
is_buffer_slot
:
slot
=
TypeSlots
.
method_name_to_slot
.
get
(
self
.
entry
.
name
)
if
slot
:
preprocessor_guard
=
slot
.
preprocessor_guard_code
()
if
(
self
.
entry
.
name
==
'__long__'
and
not
self
.
entry
.
scope
.
lookup_here
(
'__int__'
)):
preprocessor_guard
=
None
profile
=
code
.
globalstate
.
directives
[
'profile'
]
profile
=
code
.
globalstate
.
directives
[
'profile'
]
if
profile
and
lenv
.
nogil
:
if
profile
and
lenv
.
nogil
:
...
@@ -1459,7 +1452,7 @@ class FuncDefNode(StatNode, BlockNode):
...
@@ -1459,7 +1452,7 @@ class FuncDefNode(StatNode, BlockNode):
self
.
generate_argument_declarations
(
lenv
,
code
)
self
.
generate_argument_declarations
(
lenv
,
code
)
for
entry
in
lenv
.
var_entries
:
for
entry
in
lenv
.
var_entries
:
if
not
entry
.
in_closure
:
if
not
(
entry
.
in_closure
or
entry
.
is_arg
)
:
code
.
put_var_declaration
(
entry
)
code
.
put_var_declaration
(
entry
)
# Initialize the return variable __pyx_r
# Initialize the return variable __pyx_r
...
@@ -1555,7 +1548,8 @@ class FuncDefNode(StatNode, BlockNode):
...
@@ -1555,7 +1548,8 @@ class FuncDefNode(StatNode, BlockNode):
is_cdef
=
isinstance
(
self
,
CFuncDefNode
)
is_cdef
=
isinstance
(
self
,
CFuncDefNode
)
for
entry
in
lenv
.
arg_entries
:
for
entry
in
lenv
.
arg_entries
:
if
entry
.
type
.
is_pyobject
:
if
entry
.
type
.
is_pyobject
:
if
(
acquire_gil
or
entry
.
assignments
)
and
not
entry
.
in_closure
:
if
((
acquire_gil
or
len
(
entry
.
cf_assignments
)
>
1
)
and
not
entry
.
in_closure
):
code
.
put_var_incref
(
entry
)
code
.
put_var_incref
(
entry
)
# Note: defaults are always increffed. For def functions, we
# Note: defaults are always increffed. For def functions, we
...
@@ -1565,6 +1559,9 @@ class FuncDefNode(StatNode, BlockNode):
...
@@ -1565,6 +1559,9 @@ class FuncDefNode(StatNode, BlockNode):
if
is_cdef
and
entry
.
type
.
is_memoryviewslice
:
if
is_cdef
and
entry
.
type
.
is_memoryviewslice
:
code
.
put_incref_memoryviewslice
(
entry
.
cname
,
code
.
put_incref_memoryviewslice
(
entry
.
cname
,
have_gil
=
not
lenv
.
nogil
)
have_gil
=
not
lenv
.
nogil
)
for
entry
in
lenv
.
var_entries
:
if
entry
.
is_arg
and
len
(
entry
.
cf_assignments
)
>
1
:
code
.
put_var_incref
(
entry
)
# ----- Initialise local buffer auxiliary variables
# ----- Initialise local buffer auxiliary variables
for
entry
in
lenv
.
var_entries
+
lenv
.
arg_entries
:
for
entry
in
lenv
.
var_entries
+
lenv
.
arg_entries
:
...
@@ -1709,14 +1706,15 @@ class FuncDefNode(StatNode, BlockNode):
...
@@ -1709,14 +1706,15 @@ class FuncDefNode(StatNode, BlockNode):
if
entry
.
type
.
is_memoryviewslice
:
if
entry
.
type
.
is_memoryviewslice
:
code
.
put_xdecref_memoryviewslice
(
entry
.
cname
,
code
.
put_xdecref_memoryviewslice
(
entry
.
cname
,
have_gil
=
not
lenv
.
nogil
)
have_gil
=
not
lenv
.
nogil
)
elif
entry
.
type
.
is_pyobject
:
elif
entry
.
type
.
is_pyobject
:
code
.
put_var_decref
(
entry
)
if
not
entry
.
is_arg
or
len
(
entry
.
cf_assignments
)
>
1
:
code
.
put_var_decref
(
entry
)
# Decref any increfed args
# Decref any increfed args
for
entry
in
lenv
.
arg_entries
:
for
entry
in
lenv
.
arg_entries
:
if
entry
.
type
.
is_pyobject
:
if
entry
.
type
.
is_pyobject
:
if
(
acquire_gil
or
entry
.
assignments
)
and
not
entry
.
in_closure
:
if
((
acquire_gil
or
len
(
entry
.
cf_assignments
)
>
1
)
and
not
entry
.
in_closure
):
code
.
put_var_decref
(
entry
)
code
.
put_var_decref
(
entry
)
if
entry
.
type
.
is_memoryviewslice
:
if
entry
.
type
.
is_memoryviewslice
:
code
.
put_xdecref_memoryviewslice
(
entry
.
cname
,
code
.
put_xdecref_memoryviewslice
(
entry
.
cname
,
...
@@ -1853,6 +1851,21 @@ class FuncDefNode(StatNode, BlockNode):
...
@@ -1853,6 +1851,21 @@ class FuncDefNode(StatNode, BlockNode):
code
.
putln
(
"__Pyx_DECREF(Py_None); %s->obj = NULL;"
%
info
)
code
.
putln
(
"__Pyx_DECREF(Py_None); %s->obj = NULL;"
%
info
)
code
.
putln
(
"}"
)
code
.
putln
(
"}"
)
def
get_preprocessor_guard
(
self
):
is_buffer_slot
=
((
self
.
entry
.
name
==
"__getbuffer__"
and
self
.
entry
.
scope
.
is_c_class_scope
)
or
(
self
.
entry
.
name
==
"__releasebuffer__"
and
self
.
entry
.
scope
.
is_c_class_scope
))
if
self
.
entry
.
is_special
and
not
is_buffer_slot
:
slot
=
TypeSlots
.
method_name_to_slot
.
get
(
self
.
entry
.
name
)
if
slot
:
preprocessor_guard
=
slot
.
preprocessor_guard_code
()
if
(
self
.
entry
.
name
==
'__long__'
and
not
self
.
entry
.
scope
.
lookup_here
(
'__int__'
)):
preprocessor_guard
=
None
return
preprocessor_guard
class
CFuncDefNode
(
FuncDefNode
):
class
CFuncDefNode
(
FuncDefNode
):
# C function definition.
# C function definition.
#
#
...
@@ -2607,6 +2620,8 @@ class PyArgDeclNode(Node):
...
@@ -2607,6 +2620,8 @@ class PyArgDeclNode(Node):
# entry Symtab.Entry
# entry Symtab.Entry
# annotation ExprNode or None Py3 argument annotation
# annotation ExprNode or None Py3 argument annotation
child_attrs
=
[]
child_attrs
=
[]
is_self_arg
=
False
is_type_arg
=
False
def
generate_function_definitions
(
self
,
env
,
code
):
def
generate_function_definitions
(
self
,
env
,
code
):
self
.
entry
.
generate_function_definitions
(
env
,
code
)
self
.
entry
.
generate_function_definitions
(
env
,
code
)
...
@@ -2646,8 +2661,6 @@ class DefNode(FuncDefNode):
...
@@ -2646,8 +2661,6 @@ class DefNode(FuncDefNode):
lambda_name
=
None
lambda_name
=
None
assmt
=
None
assmt
=
None
num_kwonly_args
=
0
num_required_kw_args
=
0
reqd_kw_flags_cname
=
"0"
reqd_kw_flags_cname
=
"0"
is_wrapper
=
0
is_wrapper
=
0
no_assignment_synthesis
=
0
no_assignment_synthesis
=
0
...
@@ -2663,6 +2676,9 @@ class DefNode(FuncDefNode):
...
@@ -2663,6 +2676,9 @@ class DefNode(FuncDefNode):
fused_py_func
=
False
fused_py_func
=
False
specialized_cpdefs
=
None
specialized_cpdefs
=
None
py_wrapper
=
None
py_wrapper_required
=
True
func_cname
=
None
def
__init__
(
self
,
pos
,
**
kwds
):
def
__init__
(
self
,
pos
,
**
kwds
):
FuncDefNode
.
__init__
(
self
,
pos
,
**
kwds
)
FuncDefNode
.
__init__
(
self
,
pos
,
**
kwds
)
...
@@ -2781,6 +2797,16 @@ class DefNode(FuncDefNode):
...
@@ -2781,6 +2797,16 @@ class DefNode(FuncDefNode):
self
.
return_type
=
self
.
entry
.
signature
.
return_type
()
self
.
return_type
=
self
.
entry
.
signature
.
return_type
()
self
.
create_local_scope
(
env
)
self
.
create_local_scope
(
env
)
self
.
py_wrapper
=
DefNodeWrapper
(
self
.
pos
,
target
=
self
,
name
=
self
.
entry
.
name
,
args
=
self
.
args
,
star_arg
=
self
.
star_arg
,
starstar_arg
=
self
.
starstar_arg
,
return_type
=
self
.
return_type
)
self
.
py_wrapper
.
analyse_declarations
(
env
)
def
analyse_argument_types
(
self
,
env
):
def
analyse_argument_types
(
self
,
env
):
directive_locals
=
self
.
directive_locals
=
env
.
directives
[
'locals'
]
directive_locals
=
self
.
directive_locals
=
env
.
directives
[
'locals'
]
allow_none_for_extension_args
=
env
.
directives
[
'allow_none_for_extension_args'
]
allow_none_for_extension_args
=
env
.
directives
[
'allow_none_for_extension_args'
]
...
@@ -2926,17 +2952,6 @@ class DefNode(FuncDefNode):
...
@@ -2926,17 +2952,6 @@ class DefNode(FuncDefNode):
"(%d declared, %s expected)"
%
(
"(%d declared, %s expected)"
%
(
desc
,
self
.
name
,
len
(
self
.
args
),
expected_str
))
desc
,
self
.
name
,
len
(
self
.
args
),
expected_str
))
def
signature_has_nongeneric_args
(
self
):
argcount
=
len
(
self
.
args
)
if
argcount
==
0
or
(
argcount
==
1
and
(
self
.
args
[
0
].
is_self_arg
or
self
.
args
[
0
].
is_type_arg
)):
return
0
return
1
def
signature_has_generic_args
(
self
):
return
self
.
entry
.
signature
.
has_generic_args
def
declare_pyfunction
(
self
,
env
):
def
declare_pyfunction
(
self
,
env
):
#print "DefNode.declare_pyfunction:", self.name, "in", env ###
#print "DefNode.declare_pyfunction:", self.name, "in", env ###
name
=
self
.
name
name
=
self
.
name
...
@@ -2950,8 +2965,7 @@ class DefNode(FuncDefNode):
...
@@ -2950,8 +2965,7 @@ class DefNode(FuncDefNode):
entry
=
env
.
declare_pyfunction
(
name
,
self
.
pos
,
allow_redefine
=
not
self
.
is_wrapper
)
entry
=
env
.
declare_pyfunction
(
name
,
self
.
pos
,
allow_redefine
=
not
self
.
is_wrapper
)
self
.
entry
=
entry
self
.
entry
=
entry
prefix
=
env
.
next_id
(
env
.
scope_prefix
)
prefix
=
env
.
next_id
(
env
.
scope_prefix
)
entry
.
func_cname
=
Naming
.
pyfunc_prefix
+
prefix
+
name
self
.
entry
.
pyfunc_cname
=
Naming
.
pyfunc_prefix
+
prefix
+
name
entry
.
pymethdef_cname
=
Naming
.
pymethdef_prefix
+
prefix
+
name
if
Options
.
docstrings
:
if
Options
.
docstrings
:
entry
.
doc
=
embed_position
(
self
.
pos
,
self
.
doc
)
entry
.
doc
=
embed_position
(
self
.
pos
,
self
.
doc
)
entry
.
doc_cname
=
Naming
.
funcdoc_prefix
+
prefix
+
name
entry
.
doc_cname
=
Naming
.
funcdoc_prefix
+
prefix
+
name
...
@@ -2967,6 +2981,7 @@ class DefNode(FuncDefNode):
...
@@ -2967,6 +2981,7 @@ class DefNode(FuncDefNode):
entry
=
env
.
declare_lambda_function
(
self
.
lambda_name
,
self
.
pos
)
entry
=
env
.
declare_lambda_function
(
self
.
lambda_name
,
self
.
pos
)
entry
.
doc
=
None
entry
.
doc
=
None
self
.
entry
=
entry
self
.
entry
=
entry
self
.
entry
.
pyfunc_cname
=
entry
.
cname
def
declare_arguments
(
self
,
env
):
def
declare_arguments
(
self
,
env
):
for
arg
in
self
.
args
:
for
arg
in
self
.
args
:
...
@@ -3069,80 +3084,272 @@ class DefNode(FuncDefNode):
...
@@ -3069,80 +3084,272 @@ class DefNode(FuncDefNode):
self
.
assmt
.
analyse_declarations
(
env
)
self
.
assmt
.
analyse_declarations
(
env
)
self
.
assmt
.
analyse_expressions
(
env
)
self
.
assmt
.
analyse_expressions
(
env
)
def
error_value
(
self
):
return
self
.
entry
.
signature
.
error_value
def
caller_will_check_exceptions
(
self
):
return
1
def
generate_function_definitions
(
self
,
env
,
code
):
# Before closure cnames are mangled
if
self
.
py_wrapper_required
:
# func_cname might be modified by @cname
self
.
py_wrapper
.
func_cname
=
self
.
entry
.
func_cname
self
.
py_wrapper
.
generate_function_definitions
(
env
,
code
)
FuncDefNode
.
generate_function_definitions
(
self
,
env
,
code
)
def
generate_function_header
(
self
,
code
,
with_pymethdef
,
proto_only
=
0
):
def
generate_function_header
(
self
,
code
,
with_pymethdef
,
proto_only
=
0
):
if
proto_only
:
if
self
.
py_wrapper_required
:
self
.
py_wrapper
.
generate_function_header
(
code
,
with_pymethdef
,
True
)
return
arg_code_list
=
[]
arg_code_list
=
[]
sig
=
self
.
entry
.
signature
if
self
.
entry
.
signature
.
has_dummy_arg
:
if
self
.
needs_outer_scope
or
self
.
defaults_struct
:
self_arg
=
'PyObject *%s'
%
Naming
.
self_cname
else
:
self_arg
=
'CYTHON_UNUSED PyObject *%s'
%
Naming
.
self_cname
arg_code_list
.
append
(
self_arg
)
def
arg_decl_code
(
arg
):
entry
=
arg
.
entry
if
entry
.
in_closure
:
cname
=
entry
.
original_cname
else
:
cname
=
entry
.
cname
if
arg
.
is_self_arg
or
arg
.
is_type_arg
or
entry
.
is_declared_generic
:
decl
=
"PyObject *%s"
%
cname
else
:
decl
=
entry
.
type
.
declaration_code
(
cname
)
if
entry
.
cf_used
:
return
decl
return
'CYTHON_UNUSED '
+
decl
for
arg
in
self
.
args
:
arg_code_list
.
append
(
arg_decl_code
(
arg
))
if
self
.
star_arg
:
arg_code_list
.
append
(
arg_decl_code
(
self
.
star_arg
))
if
self
.
starstar_arg
:
arg_code_list
.
append
(
arg_decl_code
(
self
.
starstar_arg
))
arg_code
=
', '
.
join
(
arg_code_list
)
dc
=
self
.
return_type
.
declaration_code
(
self
.
entry
.
pyfunc_cname
)
decls_code
=
code
.
globalstate
[
'decls'
]
preprocessor_guard
=
self
.
get_preprocessor_guard
()
if
preprocessor_guard
:
decls_code
.
putln
(
preprocessor_guard
)
decls_code
.
putln
(
"static %s(%s); /* proto */"
%
(
dc
,
arg_code
))
if
preprocessor_guard
:
decls_code
.
putln
(
"#endif"
)
code
.
putln
(
"static %s(%s) {"
%
(
dc
,
arg_code
))
def
generate_argument_declarations
(
self
,
env
,
code
):
pass
def
generate_keyword_list
(
self
,
code
):
pass
def
generate_argument_parsing_code
(
self
,
env
,
code
):
# Move arguments into closure if required
def
put_into_closure
(
entry
):
if
entry
.
in_closure
:
code
.
putln
(
'%s = %s;'
%
(
entry
.
cname
,
entry
.
original_cname
))
code
.
put_var_incref
(
entry
)
code
.
put_var_giveref
(
entry
)
for
arg
in
self
.
args
:
put_into_closure
(
arg
.
entry
)
for
arg
in
self
.
star_arg
,
self
.
starstar_arg
:
if
arg
:
put_into_closure
(
arg
.
entry
)
def
generate_argument_type_tests
(
self
,
code
):
pass
class
DefNodeWrapper
(
FuncDefNode
):
# DefNode python wrapper code generator
defnode
=
None
target
=
None
# Target DefNode
def
__init__
(
self
,
*
args
,
**
kwargs
):
FuncDefNode
.
__init__
(
self
,
*
args
,
**
kwargs
)
self
.
num_kwonly_args
=
self
.
target
.
num_kwonly_args
self
.
num_required_kw_args
=
self
.
target
.
num_required_kw_args
self
.
num_required_args
=
self
.
target
.
num_required_args
self
.
self_in_stararg
=
self
.
target
.
self_in_stararg
self
.
signature
=
None
def
analyse_declarations
(
self
,
env
):
target_entry
=
self
.
target
.
entry
name
=
self
.
name
prefix
=
env
.
next_id
(
env
.
scope_prefix
)
target_entry
.
func_cname
=
Naming
.
pywrap_prefix
+
prefix
+
name
target_entry
.
pymethdef_cname
=
Naming
.
pymethdef_prefix
+
prefix
+
name
self
.
signature
=
target_entry
.
signature
def
signature_has_nongeneric_args
(
self
):
argcount
=
len
(
self
.
args
)
if
argcount
==
0
or
(
argcount
==
1
and
(
self
.
args
[
0
].
is_self_arg
or
self
.
args
[
0
].
is_type_arg
)):
return
0
return
1
def
signature_has_generic_args
(
self
):
return
self
.
signature
.
has_generic_args
def
generate_function_body
(
self
,
code
):
args
=
[]
if
self
.
signature
.
has_dummy_arg
:
args
.
append
(
Naming
.
self_cname
)
for
arg
in
self
.
args
:
args
.
append
(
arg
.
entry
.
cname
)
if
self
.
star_arg
:
args
.
append
(
self
.
star_arg
.
entry
.
cname
)
if
self
.
starstar_arg
:
args
.
append
(
self
.
starstar_arg
.
entry
.
cname
)
args
=
', '
.
join
(
args
)
if
not
self
.
return_type
.
is_void
:
code
.
put
(
'%s = '
%
Naming
.
retval_cname
)
code
.
putln
(
'%s(%s);'
%
(
self
.
target
.
entry
.
pyfunc_cname
,
args
))
def
generate_function_definitions
(
self
,
env
,
code
):
lenv
=
self
.
target
.
local_scope
# Generate C code for header and body of function
code
.
putln
(
""
)
code
.
putln
(
"/* Python wrapper */"
)
preprocessor_guard
=
self
.
target
.
get_preprocessor_guard
()
if
preprocessor_guard
:
code
.
putln
(
preprocessor_guard
)
code
.
enter_cfunc_scope
()
code
.
return_from_error_cleanup_label
=
code
.
new_label
()
with_pymethdef
=
(
self
.
target
.
needs_assignment_synthesis
(
lenv
,
code
)
or
self
.
target
.
pymethdef_required
)
self
.
generate_function_header
(
code
,
with_pymethdef
)
self
.
generate_argument_declarations
(
lenv
,
code
)
self
.
generate_keyword_list
(
code
)
tempvardecl_code
=
code
.
insertion_point
()
if
self
.
return_type
.
is_pyobject
:
retval_init
=
' = 0'
else
:
retval_init
=
''
if
not
self
.
return_type
.
is_void
:
code
.
putln
(
'%s%s;'
%
(
self
.
return_type
.
declaration_code
(
Naming
.
retval_cname
),
retval_init
))
code
.
put_declare_refcount_context
()
code
.
put_setup_refcount_context
(
'%s (wrapper)'
%
self
.
name
)
self
.
generate_argument_parsing_code
(
lenv
,
code
)
self
.
generate_argument_type_tests
(
code
)
self
.
generate_function_body
(
code
)
# ----- Go back and insert temp variable declarations
tempvardecl_code
.
put_temp_declarations
(
code
.
funcstate
)
# ----- Error cleanup
if
code
.
error_label
in
code
.
labels_used
:
code
.
put_goto
(
code
.
return_label
)
code
.
put_label
(
code
.
error_label
)
for
cname
,
type
in
code
.
funcstate
.
all_managed_temps
():
code
.
put_xdecref
(
cname
,
type
)
# ----- Non-error return cleanup
code
.
put_label
(
code
.
return_label
)
for
entry
in
lenv
.
var_entries
:
if
entry
.
is_arg
and
entry
.
type
.
is_pyobject
:
code
.
put_var_decref
(
entry
)
code
.
put_finish_refcount_context
()
if
not
self
.
return_type
.
is_void
:
code
.
putln
(
"return %s;"
%
Naming
.
retval_cname
)
code
.
putln
(
'}'
)
code
.
exit_cfunc_scope
()
if
preprocessor_guard
:
code
.
putln
(
"#endif /*!(%s)*/"
%
preprocessor_guard
)
def
generate_function_header
(
self
,
code
,
with_pymethdef
,
proto_only
=
0
):
arg_code_list
=
[]
sig
=
self
.
signature
if
sig
.
has_dummy_arg
or
self
.
self_in_stararg
:
if
sig
.
has_dummy_arg
or
self
.
self_in_stararg
:
arg_code_list
.
append
(
arg_code_list
.
append
(
"PyObject *%s"
%
Naming
.
self_cname
)
"PyObject *%s"
%
Naming
.
self_cname
)
for
arg
in
self
.
args
:
for
arg
in
self
.
args
:
if
not
arg
.
is_generic
:
if
not
arg
.
is_generic
:
if
arg
.
is_self_arg
or
arg
.
is_type_arg
:
if
arg
.
is_self_arg
or
arg
.
is_type_arg
:
arg_code_list
.
append
(
"PyObject *%s"
%
arg
.
hdr_cname
)
arg_code_list
.
append
(
"PyObject *%s"
%
arg
.
hdr_cname
)
else
:
else
:
decl
=
arg
.
hdr_type
.
declaration_code
(
arg
.
hdr_cname
)
arg_code_list
.
append
(
entry
=
self
.
local_scope
.
lookup
(
arg
.
name
)
arg
.
hdr_type
.
declaration_code
(
arg
.
hdr_cname
))
if
not
entry
.
cf_used
:
entry
=
self
.
target
.
entry
arg_code_list
.
append
(
'CYTHON_UNUSED '
+
decl
)
if
not
entry
.
is_special
and
sig
.
method_flags
()
==
[
TypeSlots
.
method_noargs
]:
else
:
arg_code_list
.
append
(
decl
)
if
not
self
.
entry
.
is_special
and
sig
.
method_flags
()
==
[
TypeSlots
.
method_noargs
]:
arg_code_list
.
append
(
"CYTHON_UNUSED PyObject *unused"
)
arg_code_list
.
append
(
"CYTHON_UNUSED PyObject *unused"
)
if
(
self
.
entry
.
scope
.
is_c_class_scope
and
self
.
entry
.
name
==
"__ipow__"
)
:
if
entry
.
scope
.
is_c_class_scope
and
entry
.
name
==
"__ipow__"
:
arg_code_list
.
append
(
"CYTHON_UNUSED PyObject *unused"
)
arg_code_list
.
append
(
"CYTHON_UNUSED 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"
%
(
Naming
.
args_cname
,
Naming
.
kwds_cname
))
%
(
Naming
.
args_cname
,
Naming
.
kwds_cname
))
arg_code
=
", "
.
join
(
arg_code_list
)
arg_code
=
", "
.
join
(
arg_code_list
)
dc
=
self
.
return_type
.
declaration_code
(
self
.
entry
.
func_cname
)
dc
=
self
.
return_type
.
declaration_code
(
entry
.
func_cname
)
mf
=
" "
.
join
(
self
.
modifiers
).
upper
()
header
=
"static %s(%s)"
%
(
dc
,
arg_code
)
if
mf
:
mf
+=
" "
header
=
"static %s%s(%s)"
%
(
mf
,
dc
,
arg_code
)
code
.
putln
(
"%s; /*proto*/"
%
header
)
code
.
putln
(
"%s; /*proto*/"
%
header
)
if
proto_only
:
if
proto_only
:
if
self
.
fused_py_func
:
if
self
.
target
.
fused_py_func
:
# If we are the specialized version of the cpdef, we still
# If we are the specialized version of the cpdef, we still
# want the prototype for the "fused cpdef", in case we're
# want the prototype for the "fused cpdef", in case we're
# checking to see if our method was overridden in Python
# checking to see if our method was overridden in Python
self
.
fused_py_func
.
generate_function_header
(
self
.
target
.
fused_py_func
.
generate_function_header
(
code
,
with_pymethdef
,
proto_only
=
True
)
code
,
with_pymethdef
,
proto_only
=
True
)
return
return
if
(
Options
.
docstrings
and
self
.
entry
.
doc
and
if
(
Options
.
docstrings
and
entry
.
doc
and
not
self
.
fused_py_func
and
not
self
.
target
.
fused_py_func
and
not
self
.
entry
.
scope
.
is_property_scope
and
not
entry
.
scope
.
is_property_scope
and
(
not
self
.
entry
.
is_special
or
self
.
entry
.
wrapperbase_cname
)):
(
not
entry
.
is_special
or
entry
.
wrapperbase_cname
)):
# h_code = code.globalstate['h_code']
# h_code = code.globalstate['h_code']
docstr
=
self
.
entry
.
doc
docstr
=
entry
.
doc
if
docstr
.
is_unicode
:
if
docstr
.
is_unicode
:
docstr
=
docstr
.
utf8encode
()
docstr
=
docstr
.
utf8encode
()
code
.
putln
(
code
.
putln
(
'static char %s[] = "%s";'
%
(
'static char %s[] = "%s";'
%
(
self
.
entry
.
doc_cname
,
entry
.
doc_cname
,
split_string_literal
(
escape_byte_string
(
docstr
))))
split_string_literal
(
escape_byte_string
(
docstr
))))
if
self
.
entry
.
is_special
:
if
entry
.
is_special
:
code
.
putln
(
code
.
putln
(
"struct wrapperbase %s;"
%
self
.
entry
.
wrapperbase_cname
)
"struct wrapperbase %s;"
%
entry
.
wrapperbase_cname
)
if
with_pymethdef
or
self
.
fused_py_func
:
if
with_pymethdef
or
self
.
target
.
fused_py_func
:
code
.
put
(
code
.
put
(
"static PyMethodDef %s = "
%
"static PyMethodDef %s = "
%
self
.
entry
.
pymethdef_cname
)
entry
.
pymethdef_cname
)
code
.
put_pymethoddef
(
self
.
entry
,
";"
,
allow_skip
=
False
)
code
.
put_pymethoddef
(
self
.
target
.
entry
,
";"
,
allow_skip
=
False
)
code
.
putln
(
"%s {"
%
header
)
code
.
putln
(
"%s {"
%
header
)
def
generate_argument_declarations
(
self
,
env
,
code
):
def
generate_argument_declarations
(
self
,
env
,
code
):
for
arg
in
self
.
args
:
for
arg
in
self
.
args
:
if
arg
.
is_generic
:
# or arg.needs_conversion:
if
arg
.
is_generic
:
if
arg
.
needs_conversion
:
if
arg
.
needs_conversion
:
code
.
putln
(
"PyObject *%s = 0;"
%
arg
.
hdr_cname
)
code
.
putln
(
"PyObject *%s = 0;"
%
arg
.
hdr_cname
)
el
if
not
arg
.
entry
.
in_closur
e
:
el
s
e
:
code
.
put_var_declaration
(
arg
.
entry
)
code
.
put_var_declaration
(
arg
.
entry
)
for
entry
in
env
.
var_entries
:
if
entry
.
is_arg
:
code
.
put_var_declaration
(
entry
)
def
generate_keyword_list
(
self
,
code
):
def
generate_keyword_list
(
self
,
code
):
if
self
.
signature_has_generic_args
()
and
\
if
self
.
signature_has_generic_args
()
and
\
...
@@ -3159,7 +3366,7 @@ class DefNode(FuncDefNode):
...
@@ -3159,7 +3366,7 @@ class DefNode(FuncDefNode):
def
generate_argument_parsing_code
(
self
,
env
,
code
):
def
generate_argument_parsing_code
(
self
,
env
,
code
):
# Generate fast equivalent of PyArg_ParseTuple call for
# Generate fast equivalent of PyArg_ParseTuple call for
# generic arguments, if any, including args/kwargs
# generic arguments, if any, including args/kwargs
if
self
.
entry
.
signature
.
has_dummy_arg
and
not
self
.
self_in_stararg
:
if
self
.
signature
.
has_dummy_arg
and
not
self
.
self_in_stararg
:
# get rid of unused argument warning
# get rid of unused argument warning
code
.
putln
(
"%s = %s;"
%
(
Naming
.
self_cname
,
Naming
.
self_cname
))
code
.
putln
(
"%s = %s;"
%
(
Naming
.
self_cname
,
Naming
.
self_cname
))
...
@@ -3175,9 +3382,6 @@ class DefNode(FuncDefNode):
...
@@ -3175,9 +3382,6 @@ class DefNode(FuncDefNode):
if
not
arg
.
type
.
is_pyobject
:
if
not
arg
.
type
.
is_pyobject
:
if
not
arg
.
type
.
create_from_py_utility_code
(
env
):
if
not
arg
.
type
.
create_from_py_utility_code
(
env
):
pass
# will fail later
pass
# will fail later
elif
arg
.
is_self_arg
and
arg
.
entry
.
in_closure
:
# must store 'self' in the closure explicitly for extension types
self
.
generate_arg_assignment
(
arg
,
arg
.
hdr_cname
,
code
)
if
not
self
.
signature_has_generic_args
():
if
not
self
.
signature_has_generic_args
():
if
has_star_or_kw_args
:
if
has_star_or_kw_args
:
...
@@ -3220,41 +3424,17 @@ class DefNode(FuncDefNode):
...
@@ -3220,41 +3424,17 @@ class DefNode(FuncDefNode):
code
.
put_var_xdecref_clear
(
self
.
starstar_arg
.
entry
)
code
.
put_var_xdecref_clear
(
self
.
starstar_arg
.
entry
)
else
:
else
:
code
.
put_var_decref_clear
(
self
.
starstar_arg
.
entry
)
code
.
put_var_decref_clear
(
self
.
starstar_arg
.
entry
)
code
.
put_add_traceback
(
self
.
entry
.
qualified_name
)
code
.
put_add_traceback
(
self
.
target
.
entry
.
qualified_name
)
# The arguments are put into the closure one after the
# other, so when type errors are found, all references in
# the closure instance must be properly ref-counted to
# facilitate generic closure instance deallocation. In
# the case of an argument type error, it's best to just
# DECREF+clear the already handled references, as this
# frees their references as early as possible.
for
arg
in
self
.
args
:
if
arg
.
type
.
is_pyobject
and
arg
.
entry
.
in_closure
:
code
.
put_var_xdecref_clear
(
arg
.
entry
)
if
self
.
needs_closure
:
code
.
put_decref
(
Naming
.
cur_scope_cname
,
self
.
local_scope
.
scope_class
.
type
)
code
.
put_finish_refcount_context
()
code
.
put_finish_refcount_context
()
code
.
putln
(
"return %s;"
%
self
.
error_value
())
code
.
putln
(
"return %s;"
%
self
.
error_value
())
if
code
.
label_used
(
end_label
):
if
code
.
label_used
(
end_label
):
code
.
put_label
(
end_label
)
code
.
put_label
(
end_label
)
# fix refnanny view on closure variables here, instead of
# doing it separately for each arg parsing special case
if
self
.
star_arg
and
self
.
star_arg
.
entry
.
in_closure
:
code
.
put_var_giveref
(
self
.
star_arg
.
entry
)
if
self
.
starstar_arg
and
self
.
starstar_arg
.
entry
.
in_closure
:
code
.
put_var_giveref
(
self
.
starstar_arg
.
entry
)
for
arg
in
self
.
args
:
if
arg
.
type
.
is_pyobject
and
arg
.
entry
.
in_closure
:
code
.
put_var_giveref
(
arg
.
entry
)
def
generate_arg_assignment
(
self
,
arg
,
item
,
code
,
incref_closure
=
True
):
def
generate_arg_assignment
(
self
,
arg
,
item
,
code
,
incref_closure
=
True
):
if
arg
.
type
.
is_pyobject
:
if
arg
.
type
.
is_pyobject
:
if
arg
.
is_generic
:
if
arg
.
is_generic
:
item
=
PyrexTypes
.
typecast
(
arg
.
type
,
PyrexTypes
.
py_object_type
,
item
)
item
=
PyrexTypes
.
typecast
(
arg
.
type
,
PyrexTypes
.
py_object_type
,
item
)
entry
=
arg
.
entry
entry
=
arg
.
entry
if
incref_closure
and
entry
.
in_closure
:
code
.
put_incref
(
item
,
PyrexTypes
.
py_object_type
)
code
.
putln
(
"%s = %s;"
%
(
entry
.
cname
,
item
))
code
.
putln
(
"%s = %s;"
%
(
entry
.
cname
,
item
))
else
:
else
:
func
=
arg
.
type
.
from_py_function
func
=
arg
.
type
.
from_py_function
...
@@ -3509,8 +3689,6 @@ class DefNode(FuncDefNode):
...
@@ -3509,8 +3689,6 @@ class DefNode(FuncDefNode):
code
.
putln
(
"if (unlikely(!%s)) {"
%
self
.
star_arg
.
entry
.
cname
)
code
.
putln
(
"if (unlikely(!%s)) {"
%
self
.
star_arg
.
entry
.
cname
)
if
self
.
starstar_arg
:
if
self
.
starstar_arg
:
code
.
put_decref_clear
(
self
.
starstar_arg
.
entry
.
cname
,
py_object_type
)
code
.
put_decref_clear
(
self
.
starstar_arg
.
entry
.
cname
,
py_object_type
)
if
self
.
needs_closure
:
code
.
put_decref
(
Naming
.
cur_scope_cname
,
self
.
local_scope
.
scope_class
.
type
)
code
.
put_finish_refcount_context
()
code
.
put_finish_refcount_context
()
code
.
putln
(
'return %s;'
%
self
.
error_value
())
code
.
putln
(
'return %s;'
%
self
.
error_value
())
code
.
putln
(
'}'
)
code
.
putln
(
'}'
)
...
@@ -3527,10 +3705,10 @@ class DefNode(FuncDefNode):
...
@@ -3527,10 +3705,10 @@ class DefNode(FuncDefNode):
code
.
putln
(
"PyObject* values[%d] = {%s};"
%
(
code
.
putln
(
"PyObject* values[%d] = {%s};"
%
(
max_args
,
','
.
join
(
'0'
*
max_args
)))
max_args
,
','
.
join
(
'0'
*
max_args
)))
if
self
.
defaults_struct
:
if
self
.
target
.
defaults_struct
:
code
.
putln
(
'%s *%s = __Pyx_CyFunction_Defaults(%s, %s);'
%
(
code
.
putln
(
'%s *%s = __Pyx_CyFunction_Defaults(%s, %s);'
%
(
self
.
defaults_struct
,
Naming
.
dynamic_args_cname
,
self
.
target
.
defaults_struct
,
Naming
.
dynamic_args_cname
,
self
.
defaults_struct
,
Naming
.
self_cname
))
self
.
target
.
defaults_struct
,
Naming
.
self_cname
))
# assign borrowed Python default values to the values array,
# assign borrowed Python default values to the values array,
# so that they can be overwritten by received arguments below
# so that they can be overwritten by received arguments below
...
@@ -3697,10 +3875,6 @@ class DefNode(FuncDefNode):
...
@@ -3697,10 +3875,6 @@ class DefNode(FuncDefNode):
for
arg
in
self
.
args
:
for
arg
in
self
.
args
:
if
arg
.
needs_conversion
:
if
arg
.
needs_conversion
:
self
.
generate_arg_conversion
(
arg
,
code
)
self
.
generate_arg_conversion
(
arg
,
code
)
elif
not
arg
.
is_self_arg
and
arg
.
entry
.
in_closure
:
if
arg
.
type
.
is_pyobject
:
code
.
put_incref
(
arg
.
hdr_cname
,
py_object_type
)
code
.
putln
(
'%s = %s;'
%
(
arg
.
entry
.
cname
,
arg
.
hdr_cname
))
def
generate_arg_conversion
(
self
,
arg
,
code
):
def
generate_arg_conversion
(
self
,
arg
,
code
):
# Generate conversion code for one argument.
# Generate conversion code for one argument.
...
@@ -3768,10 +3942,7 @@ class DefNode(FuncDefNode):
...
@@ -3768,10 +3942,7 @@ class DefNode(FuncDefNode):
self
.
generate_arg_none_check
(
arg
,
code
)
self
.
generate_arg_none_check
(
arg
,
code
)
def
error_value
(
self
):
def
error_value
(
self
):
return
self
.
entry
.
signature
.
error_value
return
self
.
signature
.
error_value
def
caller_will_check_exceptions
(
self
):
return
1
class
GeneratorDefNode
(
DefNode
):
class
GeneratorDefNode
(
DefNode
):
...
@@ -7837,6 +8008,8 @@ class CnameDecoratorNode(StatNode):
...
@@ -7837,6 +8008,8 @@ class CnameDecoratorNode(StatNode):
e
.
cname
=
self
.
cname
e
.
cname
=
self
.
cname
e
.
func_cname
=
self
.
cname
e
.
func_cname
=
self
.
cname
e
.
used
=
True
e
.
used
=
True
if
e
.
pyfunc_cname
and
'.'
in
e
.
pyfunc_cname
:
e
.
pyfunc_cname
=
self
.
mangle
(
e
.
pyfunc_cname
)
elif
is_struct_or_enum
:
elif
is_struct_or_enum
:
e
.
cname
=
e
.
type
.
cname
=
self
.
cname
e
.
cname
=
e
.
type
.
cname
=
self
.
cname
else
:
else
:
...
@@ -7853,12 +8026,16 @@ class CnameDecoratorNode(StatNode):
...
@@ -7853,12 +8026,16 @@ class CnameDecoratorNode(StatNode):
for
name
,
entry
in
scope
.
entries
.
iteritems
():
for
name
,
entry
in
scope
.
entries
.
iteritems
():
if
entry
.
func_cname
:
if
entry
.
func_cname
:
cname
=
entry
.
cname
entry
.
func_cname
=
self
.
mangle
(
entry
.
cname
)
if
'.'
in
cname
:
if
entry
.
pyfunc_cname
:
# remove __pyx_base from func_cname
old
=
entry
.
pyfunc_cname
cname
=
cname
.
split
(
'.'
)[
-
1
]
entry
.
pyfunc_cname
=
self
.
mangle
(
entry
.
pyfunc_cname
)
entry
.
func_cname
=
'%s_%s'
%
(
self
.
cname
,
cname
)
def
mangle
(
self
,
cname
):
if
'.'
in
cname
:
# remove __pyx_base from func_cname
cname
=
cname
.
split
(
'.'
)[
-
1
]
return
'%s_%s'
%
(
self
.
cname
,
cname
)
def
analyse_expressions
(
self
,
env
):
def
analyse_expressions
(
self
,
env
):
self
.
node
.
analyse_expressions
(
env
)
self
.
node
.
analyse_expressions
(
env
)
...
...
Cython/Compiler/Symtab.py
View file @
519a19a9
...
@@ -156,6 +156,7 @@ class Entry(object):
...
@@ -156,6 +156,7 @@ class Entry(object):
from_closure = 0
from_closure = 0
is_declared_generic = 0
is_declared_generic = 0
is_readonly = 0
is_readonly = 0
pyfunc_cname = None
func_cname = None
func_cname = None
func_modifiers = []
func_modifiers = []
final_func_cname = None
final_func_cname = None
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment