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
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Gwenaël Samain
cython
Commits
7bbd22bd
Commit
7bbd22bd
authored
Feb 06, 2013
by
Stefan Behnel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
move major part of SimplifyCalls transform into type analysis in GeneralCallNode
parent
d86ee399
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
73 additions
and
55 deletions
+73
-55
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+60
-5
Cython/Compiler/Optimize.py
Cython/Compiler/Optimize.py
+12
-49
Cython/Compiler/Pipeline.py
Cython/Compiler/Pipeline.py
+1
-1
No files found.
Cython/Compiler/ExprNodes.py
View file @
7bbd22bd
...
...
@@ -4299,6 +4299,7 @@ class GeneralCallNode(CallNode):
# keyword_args ExprNode or None Dict of keyword arguments
type
=
py_object_type
is_simple_call
=
False
subexprs
=
[
'function'
,
'positional_args'
,
'keyword_args'
]
...
...
@@ -4324,17 +4325,23 @@ class GeneralCallNode(CallNode):
if
self
.
analyse_as_type_constructor
(
env
):
return
self
.
function
.
analyse_types
(
env
)
self
.
positional_args
.
analyse_types
(
env
)
if
self
.
keyword_args
:
self
.
keyword_args
.
analyse_types
(
env
)
if
not
self
.
function
.
type
.
is_pyobject
:
if
self
.
function
.
type
.
is_error
:
self
.
type
=
error_type
return
if
hasattr
(
self
.
function
,
'entry'
)
and
not
self
.
function
.
entry
.
as_variable
:
error
(
self
.
pos
,
"Keyword and starred arguments not allowed in cdef functions."
)
if
hasattr
(
self
.
function
,
'entry'
):
self
.
map_keywords_to_posargs
()
if
not
self
.
is_simple_call
:
if
self
.
function
.
entry
.
as_variable
:
self
.
function
=
self
.
function
.
coerce_to_pyobject
(
env
)
else
:
error
(
self
.
pos
,
"Keyword and starred arguments "
"not allowed in cdef functions."
)
else
:
self
.
function
=
self
.
function
.
coerce_to_pyobject
(
env
)
if
self
.
keyword_args
:
self
.
keyword_args
.
analyse_types
(
env
)
self
.
positional_args
.
analyse_types
(
env
)
self
.
positional_args
=
\
self
.
positional_args
.
coerce_to_pyobject
(
env
)
function
=
self
.
function
...
...
@@ -4348,6 +4355,54 @@ class GeneralCallNode(CallNode):
self
.
type
=
py_object_type
self
.
is_temp
=
1
def
map_keywords_to_posargs
(
self
):
if
not
isinstance
(
self
.
positional_args
,
TupleNode
):
# has starred argument
return
if
not
isinstance
(
self
.
keyword_args
,
DictNode
):
# nothing to do here
return
function
=
self
.
function
entry
=
getattr
(
function
,
'entry'
,
None
)
if
not
entry
or
not
entry
.
is_cfunction
:
return
args
=
self
.
positional_args
.
args
kwargs
=
self
.
keyword_args
declared_args
=
entry
.
type
.
args
if
len
(
declared_args
)
<
len
(
args
):
# will lead to an error elsewhere
error
(
self
.
pos
,
"function call got too many positional arguments, "
"expected %d, got %s"
%
(
len
(
declared_args
),
len
(
args
)))
return
matched_pos_args
=
set
([
arg
.
name
for
arg
in
declared_args
[:
len
(
args
)]])
unmatched_args
=
declared_args
[
len
(
args
):]
matched_kwargs
=
set
()
args
=
list
(
args
)
# TODO: match keywords out-of-order and move values
# into ordered temps if necessary
for
decl_arg
,
arg
in
zip
(
unmatched_args
,
kwargs
.
key_value_pairs
):
name
=
arg
.
key
.
value
if
name
in
matched_pos_args
:
error
(
arg
.
pos
,
"keyword argument '%s' passed twice"
%
name
)
return
if
decl_arg
.
name
==
name
:
matched_kwargs
.
add
(
name
)
args
.
append
(
arg
.
value
)
else
:
break
if
not
matched_kwargs
:
return
self
.
positional_args
.
args
=
args
if
len
(
kwargs
.
key_value_pairs
)
==
len
(
matched_kwargs
):
self
.
keyword_args
=
None
self
.
is_simple_call
=
True
else
:
kwargs
.
key_value_pairs
=
[
item
for
item
in
kwargs
.
key_value_pairs
if
item
.
key
.
value
not
in
matched_kwargs
]
def
generate_result_code
(
self
,
code
):
if
self
.
type
.
is_error
:
return
if
self
.
keyword_args
:
...
...
Cython/Compiler/Optimize.py
View file @
7bbd22bd
...
...
@@ -1175,59 +1175,22 @@ class DropRefcountingTransform(Visitor.VisitorTransform):
class
SimplifyCalls
(
Visitor
.
EnvTransform
):
"""
Statically map keyword arguments in C calls to positional arguments
.
Replace GeneralCallNode by SimpleCallNode if possible
.
"""
def
visit_GeneralCallNode
(
self
,
node
):
self
.
visitchildren
(
node
)
arg_tuple
=
node
.
positional_args
if
not
isinstance
(
arg_tuple
,
ExprNodes
.
TupleNode
):
return
node
args
=
arg_tuple
.
args
kwargs
=
node
.
keyword_args
function
=
node
.
function
if
not
function
.
is_name
:
# TODO: optimise methods as well
if
not
node
.
is_simple_call
:
return
node
entry
=
function
.
entry
if
not
entry
:
entry
=
self
.
current_env
().
lookup
(
function
.
name
)
if
not
entry
:
return
node
if
not
entry
.
is_cfunction
or
not
entry
.
type
:
return
node
declared_args
=
entry
.
type
.
args
if
len
(
declared_args
)
<
len
(
args
):
# will lead to an error elsewhere
return
node
matched_pos_args
=
set
([
arg
.
name
for
arg
in
declared_args
[:
len
(
args
)]])
unmatched_args
=
declared_args
[
len
(
args
):]
matched_kwargs
=
set
()
args
=
list
(
args
)
# TODO: match keywords out-of-order and move values
# into ordered temps if necessary
for
decl_arg
,
arg
in
zip
(
unmatched_args
,
kwargs
.
key_value_pairs
):
name
=
arg
.
key
.
value
if
name
in
matched_pos_args
:
# keyword argument passed twice => should fail elsewhere
return
node
if
decl_arg
.
name
==
name
:
matched_kwargs
.
add
(
name
)
args
.
append
(
arg
.
value
)
else
:
break
if
not
matched_kwargs
:
return
node
if
len
(
kwargs
.
key_value_pairs
)
==
len
(
matched_kwargs
):
return
ExprNodes
.
SimpleCallNode
(
node
.
pos
,
function
=
function
,
args
=
args
)
arg_tuple
.
args
=
args
kwargs
.
key_value_pairs
=
[
item
for
item
in
kwargs
.
key_value_pairs
if
item
.
key
.
value
not
in
matched_kwargs
]
return
node
args
=
[
unwrap_coerced_node
(
arg
)
for
arg
in
node
.
positional_args
.
args
]
call_node
=
ExprNodes
.
SimpleCallNode
(
node
.
pos
,
function
=
node
.
function
,
args
=
args
)
call_node
.
analyse_types
(
self
.
current_env
())
if
node
.
type
!=
call_node
.
type
:
call_node
=
call_node
.
coerce_to
(
node
.
type
)
return
call_node
class
EarlyReplaceBuiltinCalls
(
Visitor
.
EnvTransform
):
...
...
Cython/Compiler/Pipeline.py
View file @
7bbd22bd
...
...
@@ -182,7 +182,6 @@ def create_pipeline(context, mode, exclude_classes=()):
AnalyseDeclarationsTransform
(
context
),
AutoTestDictTransform
(
context
),
EmbedSignature
(
context
),
SimplifyCalls
(
context
),
EarlyReplaceBuiltinCalls
(
context
),
## Necessary?
TransformBuiltinMethods
(
context
),
## Necessary?
MarkParallelAssignments
(
context
),
...
...
@@ -194,6 +193,7 @@ def create_pipeline(context, mode, exclude_classes=()):
_check_c_declarations
,
InlineDefNodeCalls
(
context
),
AnalyseExpressionsTransform
(
context
),
SimplifyCalls
(
context
),
FindInvalidUseOfFusedTypes
(
context
),
CreateClosureClasses
(
context
),
## After all lookups and type inference
ExpandInplaceOperators
(
context
),
...
...
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