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
Boxiang Sun
cython
Commits
5a11a252
Commit
5a11a252
authored
Nov 28, 2018
by
Boxiang Sun
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Initial support for nogil extension C code generation
parent
f4290b82
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
57 additions
and
6 deletions
+57
-6
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+31
-3
Cython/Compiler/ModuleNode.py
Cython/Compiler/ModuleNode.py
+9
-0
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+6
-0
Cython/Compiler/ParseTreeTransforms.py
Cython/Compiler/ParseTreeTransforms.py
+1
-0
Cython/Compiler/Symtab.py
Cython/Compiler/Symtab.py
+10
-3
No files found.
Cython/Compiler/ExprNodes.py
View file @
5a11a252
...
@@ -671,6 +671,8 @@ class ExprNode(Node):
...
@@ -671,6 +671,8 @@ class ExprNode(Node):
self
.
gil_error
()
self
.
gil_error
()
def
gil_assignment_check
(
self
,
env
):
def
gil_assignment_check
(
self
,
env
):
if
self
.
type
==
PyrexTypes
.
PyExtensionType
and
env
.
nogil
and
self
.
type
.
nogil
:
error
(
"No gil type in no gil function"
)
if
env
.
nogil
and
self
.
type
.
is_pyobject
:
if
env
.
nogil
and
self
.
type
.
is_pyobject
:
error
(
self
.
pos
,
"Assignment of Python object not allowed without gil"
)
error
(
self
.
pos
,
"Assignment of Python object not allowed without gil"
)
...
@@ -1656,6 +1658,9 @@ class StringNode(PyConstNode):
...
@@ -1656,6 +1658,9 @@ class StringNode(PyConstNode):
is_identifier
=
None
is_identifier
=
None
unicode_value
=
None
unicode_value
=
None
# XXX: Let the StringNode can be used in nogil extension initializing
nogil_check
=
None
def
calculate_constant_result
(
self
):
def
calculate_constant_result
(
self
):
if
self
.
unicode_value
is
not
None
:
if
self
.
unicode_value
is
not
None
:
# only the Unicode value is portable across Py2/3
# only the Unicode value is portable across Py2/3
...
@@ -2249,6 +2254,9 @@ class NameNode(AtomicExprNode):
...
@@ -2249,6 +2254,9 @@ class NameNode(AtomicExprNode):
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
())
elif
entry
.
is_local
and
isinstance
(
entry
.
type
,
PyrexTypes
.
CythonExtensionType
):
pass
# code.putln(entry.cname)
elif
entry
.
is_local
or
entry
.
in_closure
or
entry
.
from_closure
or
entry
.
type
.
is_memoryviewslice
:
elif
entry
.
is_local
or
entry
.
in_closure
or
entry
.
from_closure
or
entry
.
type
.
is_memoryviewslice
:
# Raise UnboundLocalError for objects and memoryviewslices
# Raise UnboundLocalError for objects and memoryviewslices
raise_unbound
=
(
raise_unbound
=
(
...
@@ -5442,6 +5450,18 @@ class CallNode(ExprNode):
...
@@ -5442,6 +5450,18 @@ class CallNode(ExprNode):
self
.
analyse_c_function_call
(
env
)
self
.
analyse_c_function_call
(
env
)
self
.
type
=
type
self
.
type
=
type
return
True
return
True
elif
type
and
type
.
is_struct
and
type
.
nogil
:
args
,
kwds
=
self
.
explicit_args_kwds
()
items
=
[]
for
arg
,
member
in
zip
(
args
,
type
.
scope
.
var_entries
):
items
.
append
(
DictItemNode
(
pos
=
arg
.
pos
,
key
=
StringNode
(
pos
=
arg
.
pos
,
value
=
member
.
name
),
value
=
arg
))
if
kwds
:
items
+=
kwds
.
key_value_pairs
self
.
key_value_pairs
=
items
self
.
__class__
=
DictNode
self
.
analyse_types
(
env
)
# FIXME
self
.
coerce_to
(
type
,
env
)
return
True
def
is_lvalue
(
self
):
def
is_lvalue
(
self
):
return
self
.
type
.
is_reference
return
self
.
type
.
is_reference
...
@@ -7157,9 +7177,12 @@ class AttributeNode(ExprNode):
...
@@ -7157,9 +7177,12 @@ class AttributeNode(ExprNode):
# (AnalyseExpressionsTransform)
# (AnalyseExpressionsTransform)
self
.
member
=
self
.
entry
.
cname
self
.
member
=
self
.
entry
.
cname
return
"((struct %s *)%s%s%s)->%s"
%
(
if
obj
.
type
.
nogil
:
obj
.
type
.
vtabstruct_cname
,
obj_code
,
self
.
op
,
return
"%s"
%
self
.
entry
.
func_cname
obj
.
type
.
vtabslot_cname
,
self
.
member
)
else
:
return
"((struct %s *)%s%s%s)->%s"
%
(
obj
.
type
.
vtabstruct_cname
,
obj_code
,
self
.
op
,
obj
.
type
.
vtabslot_cname
,
self
.
member
)
elif
self
.
result_is_used
:
elif
self
.
result_is_used
:
return
self
.
member
return
self
.
member
# Generating no code at all for unused access to optimised builtin
# Generating no code at all for unused access to optimised builtin
...
@@ -8810,6 +8833,11 @@ class DictNode(ExprNode):
...
@@ -8810,6 +8833,11 @@ class DictNode(ExprNode):
code
.
putln
(
'}'
)
code
.
putln
(
'}'
)
if
self
.
exclude_null_values
:
if
self
.
exclude_null_values
:
code
.
putln
(
'}'
)
code
.
putln
(
'}'
)
elif
self
.
type
.
nogil
:
code
.
putln
(
"%s->%s = %s;"
%
(
self
.
result
(),
item
.
key
.
value
,
item
.
value
.
result
()))
else
:
else
:
code
.
putln
(
"%s.%s = %s;"
%
(
code
.
putln
(
"%s.%s = %s;"
%
(
self
.
result
(),
self
.
result
(),
...
...
Cython/Compiler/ModuleNode.py
View file @
5a11a252
...
@@ -1104,6 +1104,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -1104,6 +1104,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
self
.
sue_header_footer
(
type
,
"struct"
,
type
.
objstruct_cname
)
self
.
sue_header_footer
(
type
,
"struct"
,
type
.
objstruct_cname
)
code
.
putln
(
header
)
code
.
putln
(
header
)
base_type
=
type
.
base_type
base_type
=
type
.
base_type
nogil
=
type
.
nogil
if
base_type
:
if
base_type
:
basestruct_cname
=
base_type
.
objstruct_cname
basestruct_cname
=
base_type
.
objstruct_cname
if
basestruct_cname
==
"PyTypeObject"
:
if
basestruct_cname
==
"PyTypeObject"
:
...
@@ -1114,6 +1115,14 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -1114,6 +1115,14 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
(
"struct "
,
""
)[
base_type
.
typedef_flag
],
(
"struct "
,
""
)[
base_type
.
typedef_flag
],
basestruct_cname
,
basestruct_cname
,
Naming
.
obj_base_cname
))
Naming
.
obj_base_cname
))
elif
nogil
:
# Extension type with nogil keyword indicate it is a CPython-free struct
code
.
putln
(
"// nogil"
)
code
.
putln
(
"size_t ob_refcnt;"
)
else
:
else
:
code
.
putln
(
code
.
putln
(
"PyObject_HEAD"
)
"PyObject_HEAD"
)
...
...
Cython/Compiler/Nodes.py
View file @
5a11a252
...
@@ -3273,6 +3273,8 @@ class DefNodeWrapper(FuncDefNode):
...
@@ -3273,6 +3273,8 @@ class DefNodeWrapper(FuncDefNode):
# different code types.
# different code types.
for
arg
in
self
.
args
:
for
arg
in
self
.
args
:
if
not
arg
.
type
.
is_pyobject
:
if
not
arg
.
type
.
is_pyobject
:
if
arg
.
type
is
PyrexTypes
.
PyExtensionType
and
arg
.
type
.
nogil
:
continue
# XXX maybe here is not the correct place to put it...
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
.
hdr_type
and
not
arg
.
hdr_type
.
is_pyobject
:
elif
arg
.
hdr_type
and
not
arg
.
hdr_type
.
is_pyobject
:
...
@@ -4636,6 +4638,7 @@ class CClassDefNode(ClassDefNode):
...
@@ -4636,6 +4638,7 @@ class CClassDefNode(ClassDefNode):
# doc string or None
# doc string or None
# body StatNode or None
# body StatNode or None
# entry Symtab.Entry
# entry Symtab.Entry
# nogil boolean
# base_type PyExtensionType or None
# base_type PyExtensionType or None
# buffer_defaults_node DictNode or None Declares defaults for a buffer
# buffer_defaults_node DictNode or None Declares defaults for a buffer
# buffer_defaults_pos
# buffer_defaults_pos
...
@@ -4645,6 +4648,7 @@ class CClassDefNode(ClassDefNode):
...
@@ -4645,6 +4648,7 @@ class CClassDefNode(ClassDefNode):
buffer_defaults_pos
=
None
buffer_defaults_pos
=
None
typedef_flag
=
False
typedef_flag
=
False
api
=
False
api
=
False
nogil
=
False
objstruct_name
=
None
objstruct_name
=
None
typeobj_name
=
None
typeobj_name
=
None
check_size
=
None
check_size
=
None
...
@@ -4685,6 +4689,7 @@ class CClassDefNode(ClassDefNode):
...
@@ -4685,6 +4689,7 @@ class CClassDefNode(ClassDefNode):
typedef_flag
=
self
.
typedef_flag
,
typedef_flag
=
self
.
typedef_flag
,
check_size
=
self
.
check_size
,
check_size
=
self
.
check_size
,
api
=
self
.
api
,
api
=
self
.
api
,
nogil
=
self
.
nogil
,
buffer_defaults
=
self
.
buffer_defaults
(
env
),
buffer_defaults
=
self
.
buffer_defaults
(
env
),
shadow
=
self
.
shadow
)
shadow
=
self
.
shadow
)
...
@@ -4773,6 +4778,7 @@ class CClassDefNode(ClassDefNode):
...
@@ -4773,6 +4778,7 @@ class CClassDefNode(ClassDefNode):
visibility
=
self
.
visibility
,
visibility
=
self
.
visibility
,
typedef_flag
=
self
.
typedef_flag
,
typedef_flag
=
self
.
typedef_flag
,
api
=
self
.
api
,
api
=
self
.
api
,
nogil
=
self
.
nogil
,
buffer_defaults
=
self
.
buffer_defaults
(
env
),
buffer_defaults
=
self
.
buffer_defaults
(
env
),
shadow
=
self
.
shadow
)
shadow
=
self
.
shadow
)
...
...
Cython/Compiler/ParseTreeTransforms.py
View file @
5a11a252
...
@@ -1630,6 +1630,7 @@ if VALUE is not None:
...
@@ -1630,6 +1630,7 @@ if VALUE is not None:
if
stats
:
if
stats
:
node
.
body
.
stats
+=
stats
node
.
body
.
stats
+=
stats
if
(
node
.
visibility
!=
'extern'
if
(
node
.
visibility
!=
'extern'
and
not
node
.
nogil
and
not
node
.
scope
.
lookup
(
'__reduce__'
)
and
not
node
.
scope
.
lookup
(
'__reduce__'
)
and
not
node
.
scope
.
lookup
(
'__reduce_ex__'
)):
and
not
node
.
scope
.
lookup
(
'__reduce_ex__'
)):
self
.
_inject_pickle_methods
(
node
)
self
.
_inject_pickle_methods
(
node
)
...
...
Cython/Compiler/Symtab.py
View file @
5a11a252
...
@@ -1482,7 +1482,7 @@ class ModuleScope(Scope):
...
@@ -1482,7 +1482,7 @@ class ModuleScope(Scope):
def
declare_c_class
(
self
,
name
,
pos
,
defining
=
0
,
implementing
=
0
,
def
declare_c_class
(
self
,
name
,
pos
,
defining
=
0
,
implementing
=
0
,
module_name
=
None
,
base_type
=
None
,
objstruct_cname
=
None
,
module_name
=
None
,
base_type
=
None
,
objstruct_cname
=
None
,
typeobj_cname
=
None
,
typeptr_cname
=
None
,
visibility
=
'private'
,
typeobj_cname
=
None
,
typeptr_cname
=
None
,
visibility
=
'private'
,
typedef_flag
=
0
,
api
=
0
,
check_size
=
None
,
typedef_flag
=
0
,
api
=
0
,
nogil
=
0
,
check_size
=
None
,
buffer_defaults
=
None
,
shadow
=
0
):
buffer_defaults
=
None
,
shadow
=
0
):
# If this is a non-extern typedef class, expose the typedef, but use
# If this is a non-extern typedef class, expose the typedef, but use
# the non-typedef struct internally to avoid needing forward
# the non-typedef struct internally to avoid needing forward
...
@@ -1515,8 +1515,15 @@ class ModuleScope(Scope):
...
@@ -1515,8 +1515,15 @@ class ModuleScope(Scope):
# Make a new entry if needed
# Make a new entry if needed
#
#
if
not
entry
or
shadow
:
if
not
entry
or
shadow
:
type
=
PyrexTypes
.
PyExtensionType
(
if
nogil
:
name
,
typedef_flag
,
base_type
,
visibility
==
'extern'
,
check_size
=
check_size
)
pass
if
nogil
:
type
=
PyrexTypes
.
CythonExtensionType
(
name
,
typedef_flag
,
base_type
,
visibility
==
'extern'
,
check_size
=
check_size
)
else
:
type
=
PyrexTypes
.
PyExtensionType
(
name
,
typedef_flag
,
base_type
,
visibility
==
'extern'
,
check_size
=
check_size
)
type
.
nogil
=
nogil
type
.
pos
=
pos
type
.
pos
=
pos
type
.
buffer_defaults
=
buffer_defaults
type
.
buffer_defaults
=
buffer_defaults
if
objtypedef_cname
is
not
None
:
if
objtypedef_cname
is
not
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