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
83047799
Commit
83047799
authored
Feb 05, 2019
by
gsamain
Committed by
Xavier Thompson
Jun 18, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Gwenael: Remove nogil extension and introduce refcounted cypclass
parent
6521ad76
Changes
12
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
324 additions
and
383 deletions
+324
-383
Cython/Compiler/Code.py
Cython/Compiler/Code.py
+26
-3
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+55
-31
Cython/Compiler/ModuleNode.py
Cython/Compiler/ModuleNode.py
+15
-16
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+50
-24
Cython/Compiler/Parsing.py
Cython/Compiler/Parsing.py
+18
-27
Cython/Compiler/PyrexTypes.py
Cython/Compiler/PyrexTypes.py
+57
-213
Cython/Compiler/Symtab.py
Cython/Compiler/Symtab.py
+15
-17
Cython/Compiler/UtilNodes.py
Cython/Compiler/UtilNodes.py
+8
-2
Cython/Utility/CyObjects.cpp
Cython/Utility/CyObjects.cpp
+75
-0
Cython/Utility/ObjectHandling.c
Cython/Utility/ObjectHandling.c
+0
-45
nogil_test/nogil_extension.pyx
nogil_test/nogil_extension.pyx
+4
-4
test.pyx
test.pyx
+1
-1
No files found.
Cython/Compiler/Code.py
View file @
83047799
...
@@ -2039,7 +2039,7 @@ class CCodeWriter(object):
...
@@ -2039,7 +2039,7 @@ class CCodeWriter(object):
entry
.
cname
,
dll_linkage
=
dll_linkage
))
entry
.
cname
,
dll_linkage
=
dll_linkage
))
if
entry
.
init
is
not
None
:
if
entry
.
init
is
not
None
:
self
.
put_safe
(
" = %s"
%
entry
.
type
.
literal_code
(
entry
.
init
))
self
.
put_safe
(
" = %s"
%
entry
.
type
.
literal_code
(
entry
.
init
))
elif
entry
.
type
.
is_pyobject
:
elif
entry
.
type
.
is_pyobject
or
entry
.
type
.
is_cyp_class
:
self
.
put
(
" = NULL"
)
self
.
put
(
" = NULL"
)
self
.
putln
(
";"
)
self
.
putln
(
";"
)
...
@@ -2050,8 +2050,8 @@ class CCodeWriter(object):
...
@@ -2050,8 +2050,8 @@ class CCodeWriter(object):
self
.
putln
(
"%s = NULL;"
%
decl
)
self
.
putln
(
"%s = NULL;"
%
decl
)
elif
type
.
is_memoryviewslice
:
elif
type
.
is_memoryviewslice
:
self
.
putln
(
"%s = %s;"
%
(
decl
,
type
.
literal_code
(
type
.
default_value
)))
self
.
putln
(
"%s = %s;"
%
(
decl
,
type
.
literal_code
(
type
.
default_value
)))
elif
type
.
is_
struct
and
type
.
is_extension_type
and
type
.
nogil
:
elif
type
.
is_
cyp_class
:
self
.
putln
(
"%s;"
%
decl
)
self
.
putln
(
"%s
= NULL
;"
%
decl
)
else
:
else
:
self
.
putln
(
"%s%s;"
%
(
static
and
"static "
or
""
,
decl
))
self
.
putln
(
"%s%s;"
%
(
static
and
"static "
or
""
,
decl
))
...
@@ -2084,6 +2084,29 @@ class CCodeWriter(object):
...
@@ -2084,6 +2084,29 @@ class CCodeWriter(object):
return
''
return
''
return
'%s '
%
' '
.
join
([
mapper
(
m
,
m
)
for
m
in
modifiers
])
return
'%s '
%
' '
.
join
([
mapper
(
m
,
m
)
for
m
in
modifiers
])
# CyObjects reference counting
def
put_cygotref
(
self
,
cname
):
self
.
putln
(
"Cy_GOTREF(%s);"
%
cname
)
def
put_cygiveref
(
self
,
cname
):
self
.
putln
(
"Cy_GIVEREF(%s);"
%
cname
)
def
put_cyxgiveref
(
self
,
cname
):
self
.
putln
(
"Cy_XGIVEREF(%s);"
%
cname
)
def
put_cyxgotref
(
self
,
cname
):
self
.
putln
(
"Cy_XGOTREF(%s);"
%
cname
)
def
put_cyincref
(
self
,
cname
):
self
.
putln
(
"Cy_INCREF(%s);"
%
cname
)
def
put_cydecref
(
self
,
cname
):
self
.
putln
(
"Cy_DECREF(%s);"
%
cname
)
def
put_cyxdecref
(
self
,
cname
):
self
.
putln
(
"Cy_XDECREF(%s);"
%
cname
)
# Python objects and reference counting
# Python objects and reference counting
def
entry_as_pyobject
(
self
,
entry
):
def
entry_as_pyobject
(
self
,
entry
):
...
...
Cython/Compiler/ExprNodes.py
View file @
83047799
...
@@ -782,7 +782,10 @@ class ExprNode(Node):
...
@@ -782,7 +782,10 @@ class ExprNode(Node):
If the result is in a temp, it is already a new reference.
If the result is in a temp, it is already a new reference.
"""
"""
if
not
self
.
result_in_temp
():
if
not
self
.
result_in_temp
():
code
.
put_incref
(
self
.
result
(),
self
.
ctype
())
if
self
.
type
.
is_cyp_class
and
"NULL"
not
in
self
.
result
():
code
.
put_cyincref
(
self
.
result
())
else
:
code
.
put_incref
(
self
.
result
(),
self
.
ctype
())
def
make_owned_memoryviewslice
(
self
,
code
):
def
make_owned_memoryviewslice
(
self
,
code
):
"""
"""
...
@@ -824,7 +827,10 @@ class ExprNode(Node):
...
@@ -824,7 +827,10 @@ class ExprNode(Node):
self
.
generate_subexpr_disposal_code
(
code
)
self
.
generate_subexpr_disposal_code
(
code
)
self
.
free_subexpr_temps
(
code
)
self
.
free_subexpr_temps
(
code
)
if
self
.
result
():
if
self
.
result
():
code
.
put_decref_clear
(
self
.
result
(),
self
.
ctype
(),
if
self
.
type
.
is_cyp_class
:
code
.
put_cyxdecref
(
self
.
result
())
else
:
code
.
put_decref_clear
(
self
.
result
(),
self
.
ctype
(),
have_gil
=
not
self
.
in_nogil_context
)
have_gil
=
not
self
.
in_nogil_context
)
if
self
.
has_temp_moved
:
if
self
.
has_temp_moved
:
code
.
globalstate
.
use_utility_code
(
code
.
globalstate
.
use_utility_code
(
...
@@ -847,6 +853,8 @@ class ExprNode(Node):
...
@@ -847,6 +853,8 @@ class ExprNode(Node):
self
.
free_subexpr_temps
(
code
)
self
.
free_subexpr_temps
(
code
)
elif
self
.
type
.
is_pyobject
:
elif
self
.
type
.
is_pyobject
:
code
.
putln
(
"%s = 0;"
%
self
.
result
())
code
.
putln
(
"%s = 0;"
%
self
.
result
())
elif
self
.
type
.
is_cyp_class
:
code
.
putln
(
"%s = 0;"
%
self
.
result
())
elif
self
.
type
.
is_memoryviewslice
:
elif
self
.
type
.
is_memoryviewslice
:
code
.
putln
(
"%s.memview = NULL;"
%
self
.
result
())
code
.
putln
(
"%s.memview = NULL;"
%
self
.
result
())
code
.
putln
(
"%s.data = NULL;"
%
self
.
result
())
code
.
putln
(
"%s.data = NULL;"
%
self
.
result
())
...
@@ -1837,7 +1845,10 @@ class ImagNode(AtomicExprNode):
...
@@ -1837,7 +1845,10 @@ class ImagNode(AtomicExprNode):
self
.
result
(),
self
.
result
(),
float
(
self
.
value
),
float
(
self
.
value
),
code
.
error_goto_if_null
(
self
.
result
(),
self
.
pos
)))
code
.
error_goto_if_null
(
self
.
result
(),
self
.
pos
)))
self
.
generate_gotref
(
code
)
if
self
.
type
.
is_cyp_class
:
code
.
put_cygotref
(
self
.
result
())
else
:
self
.
generate_gotref
(
code
)
class
NewExprNode
(
AtomicExprNode
):
class
NewExprNode
(
AtomicExprNode
):
...
@@ -2319,8 +2330,9 @@ class NameNode(AtomicExprNode):
...
@@ -2319,8 +2330,9 @@ class NameNode(AtomicExprNode):
code
.
error_goto_if_null
(
self
.
result
(),
self
.
pos
)))
code
.
error_goto_if_null
(
self
.
result
(),
self
.
pos
)))
self
.
generate_gotref
(
code
)
self
.
generate_gotref
(
code
)
elif
entry
.
is_local
and
isinstance
(
entry
.
type
,
PyrexTypes
.
CythonExtensionType
):
elif
entry
.
is_local
and
entry
.
type
.
is_cyp_class
:
pass
code
.
put_cygotref
(
self
.
result
())
#pass
# code.putln(entry.cname)
# 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
...
@@ -2426,6 +2438,10 @@ class NameNode(AtomicExprNode):
...
@@ -2426,6 +2438,10 @@ class NameNode(AtomicExprNode):
assigned
=
False
assigned
=
False
if
is_external_ref
:
if
is_external_ref
:
rhs
.
generate_giveref
(
code
)
rhs
.
generate_giveref
(
code
)
elif
self
.
type
.
is_cyp_class
:
code
.
put_cyxdecref
(
self
.
result
())
if
isinstance
(
rhs
,
NameNode
):
rhs
.
make_owned_reference
(
code
)
if
not
self
.
type
.
is_memoryviewslice
:
if
not
self
.
type
.
is_memoryviewslice
:
if
not
assigned
:
if
not
assigned
:
if
overloaded_assignment
:
if
overloaded_assignment
:
...
@@ -2537,6 +2553,22 @@ class NameNode(AtomicExprNode):
...
@@ -2537,6 +2553,22 @@ class NameNode(AtomicExprNode):
else
:
else
:
code
.
put_decref_clear
(
self
.
result
(),
self
.
ctype
(),
code
.
put_decref_clear
(
self
.
result
(),
self
.
ctype
(),
have_gil
=
not
self
.
nogil
)
have_gil
=
not
self
.
nogil
)
elif
self
.
entry
.
type
.
is_cyp_class
:
if
not
self
.
cf_is_null
:
if
self
.
cf_maybe_null
and
not
ignore_nonexisting
:
code
.
put_error_if_unbound
(
self
.
pos
,
self
.
entry
)
if
self
.
entry
.
in_closure
:
# generator
if
ignore_nonexisting
and
self
.
cf_maybe_null
:
code
.
put_cyxgotref
(
self
.
result
())
else
:
code
.
put_cygotref
(
self
.
result
())
if
ignore_nonexisting
and
self
.
cf_maybe_null
:
code
.
put_cyxdecref
(
self
.
result
())
else
:
code
.
put_cydecref
(
self
.
result
())
code
.
putln
(
'%s = NULL;'
%
self
.
result
())
else
:
else
:
error
(
self
.
pos
,
"Deletion of C names not supported"
)
error
(
self
.
pos
,
"Deletion of C names not supported"
)
...
@@ -4135,6 +4167,8 @@ class IndexNode(_IndexingBaseNode):
...
@@ -4135,6 +4167,8 @@ class IndexNode(_IndexingBaseNode):
code
.
error_goto_if
(
error_check
%
self
.
result
(),
self
.
pos
)))
code
.
error_goto_if
(
error_check
%
self
.
result
(),
self
.
pos
)))
if
self
.
type
.
is_pyobject
:
if
self
.
type
.
is_pyobject
:
self
.
generate_gotref
(
code
)
self
.
generate_gotref
(
code
)
elif
self
.
type
.
is_cyp_class
:
code
.
put_cygotref
(
self
.
result
())
def
generate_setitem_code
(
self
,
value_code
,
code
):
def
generate_setitem_code
(
self
,
value_code
,
code
):
if
self
.
index
.
type
.
is_int
:
if
self
.
index
.
type
.
is_int
:
...
@@ -5555,18 +5589,6 @@ class CallNode(ExprNode):
...
@@ -5555,18 +5589,6 @@ 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
...
@@ -6069,6 +6091,8 @@ class SimpleCallNode(CallNode):
...
@@ -6069,6 +6091,8 @@ class SimpleCallNode(CallNode):
code
.
putln
(
"%s%s; %s"
%
(
lhs
,
rhs
,
goto_error
))
code
.
putln
(
"%s%s; %s"
%
(
lhs
,
rhs
,
goto_error
))
if
self
.
type
.
is_pyobject
and
self
.
result
():
if
self
.
type
.
is_pyobject
and
self
.
result
():
self
.
generate_gotref
(
code
)
self
.
generate_gotref
(
code
)
elif
self
.
type
.
is_cyp_class
and
self
.
result
():
code
.
put_cygotref
(
self
.
result
())
if
self
.
has_optional_args
:
if
self
.
has_optional_args
:
code
.
funcstate
.
release_temp
(
self
.
opt_arg_struct
)
code
.
funcstate
.
release_temp
(
self
.
opt_arg_struct
)
...
@@ -7073,6 +7097,8 @@ class AttributeNode(ExprNode):
...
@@ -7073,6 +7097,8 @@ class AttributeNode(ExprNode):
self
.
op
=
"->"
self
.
op
=
"->"
elif
obj_type
.
is_reference
and
obj_type
.
is_fake_reference
:
elif
obj_type
.
is_reference
and
obj_type
.
is_fake_reference
:
self
.
op
=
"->"
self
.
op
=
"->"
elif
obj_type
.
is_cyp_class
:
self
.
op
=
"->"
else
:
else
:
self
.
op
=
"."
self
.
op
=
"."
if
obj_type
.
has_attributes
:
if
obj_type
.
has_attributes
:
...
@@ -7223,12 +7249,9 @@ class AttributeNode(ExprNode):
...
@@ -7223,12 +7249,9 @@ class AttributeNode(ExprNode):
# (AnalyseExpressionsTransform)
# (AnalyseExpressionsTransform)
self
.
member
=
self
.
entry
.
cname
self
.
member
=
self
.
entry
.
cname
if
obj
.
type
.
nogil
:
return
"((struct %s *)%s%s%s)->%s"
%
(
return
"%s"
%
self
.
entry
.
func_cname
obj
.
type
.
vtabstruct_cname
,
obj_code
,
self
.
op
,
else
:
obj
.
type
.
vtabslot_cname
,
self
.
member
)
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
...
@@ -7329,6 +7352,11 @@ class AttributeNode(ExprNode):
...
@@ -7329,6 +7352,11 @@ class AttributeNode(ExprNode):
from
.
import
MemoryView
from
.
import
MemoryView
MemoryView
.
put_assign_to_memviewslice
(
MemoryView
.
put_assign_to_memviewslice
(
select_code
,
rhs
,
rhs
.
result
(),
self
.
type
,
code
)
select_code
,
rhs
,
rhs
.
result
(),
self
.
type
,
code
)
elif
self
.
type
.
is_cyp_class
:
rhs
.
make_owned_reference
(
code
)
code
.
put_cygiveref
(
rhs
.
result
())
code
.
put_cygotref
(
select_code
)
code
.
put_cyxdecref
(
select_code
)
if
not
self
.
type
.
is_memoryviewslice
:
if
not
self
.
type
.
is_memoryviewslice
:
code
.
putln
(
code
.
putln
(
...
@@ -8827,8 +8855,6 @@ class DictNode(ExprNode):
...
@@ -8827,8 +8855,6 @@ class DictNode(ExprNode):
# pairs are evaluated and used one at a time.
# pairs are evaluated and used one at a time.
code
.
mark_pos
(
self
.
pos
)
code
.
mark_pos
(
self
.
pos
)
self
.
allocate_temp_result
(
code
)
self
.
allocate_temp_result
(
code
)
if
hasattr
(
self
.
type
,
'nogil'
)
and
self
.
type
.
nogil
:
code
.
putln
(
"%s = (struct %s *)malloc(sizeof(struct %s));"
%
(
self
.
result
(),
self
.
type
.
objstruct_cname
,
self
.
type
.
objstruct_cname
))
is_dict
=
self
.
type
.
is_pyobject
is_dict
=
self
.
type
.
is_pyobject
if
is_dict
:
if
is_dict
:
...
@@ -8886,11 +8912,6 @@ class DictNode(ExprNode):
...
@@ -8886,11 +8912,6 @@ 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
(),
...
@@ -13519,7 +13540,10 @@ class CoerceToTempNode(CoercionNode):
...
@@ -13519,7 +13540,10 @@ class CoerceToTempNode(CoercionNode):
self
.
result
(),
self
.
arg
.
result_as
(
self
.
ctype
())))
self
.
result
(),
self
.
arg
.
result_as
(
self
.
ctype
())))
if
self
.
use_managed_ref
:
if
self
.
use_managed_ref
:
if
not
self
.
type
.
is_memoryviewslice
:
if
not
self
.
type
.
is_memoryviewslice
:
code
.
put_incref
(
self
.
result
(),
self
.
ctype
())
if
self
.
type
.
is_cyp_class
:
code
.
put_cyincref
(
self
.
result
())
else
:
code
.
put_incref
(
self
.
result
(),
self
.
ctype
())
else
:
else
:
code
.
put_incref_memoryviewslice
(
self
.
result
(),
self
.
type
,
code
.
put_incref_memoryviewslice
(
self
.
result
(),
self
.
type
,
have_gil
=
not
self
.
in_nogil_context
)
have_gil
=
not
self
.
in_nogil_context
)
...
...
Cython/Compiler/ModuleNode.py
View file @
83047799
...
@@ -6,7 +6,7 @@ from __future__ import absolute_import
...
@@ -6,7 +6,7 @@ from __future__ import absolute_import
import
cython
import
cython
cython
.
declare
(
Naming
=
object
,
Options
=
object
,
PyrexTypes
=
object
,
TypeSlots
=
object
,
cython
.
declare
(
Naming
=
object
,
Options
=
object
,
PyrexTypes
=
object
,
TypeSlots
=
object
,
error
=
object
,
warning
=
object
,
py_object_type
=
object
,
UtilityCode
=
object
,
error
=
object
,
warning
=
object
,
py_object_type
=
object
,
cy_object_type
=
object
,
UtilityCode
=
object
,
EncodedString
=
object
,
re
=
object
)
EncodedString
=
object
,
re
=
object
)
from
collections
import
defaultdict
from
collections
import
defaultdict
...
@@ -28,7 +28,7 @@ from . import PyrexTypes
...
@@ -28,7 +28,7 @@ from . import PyrexTypes
from
.
import
Pythran
from
.
import
Pythran
from
.Errors
import
error
,
warning
from
.Errors
import
error
,
warning
from
.PyrexTypes
import
py_object_type
from
.PyrexTypes
import
py_object_type
,
cy_object_type
from
..Utils
import
open_new_file
,
replace_suffix
,
decode_filename
,
build_hex_version
from
..Utils
import
open_new_file
,
replace_suffix
,
decode_filename
,
build_hex_version
from
.Code
import
UtilityCode
,
IncludeCode
from
.Code
import
UtilityCode
,
IncludeCode
from
.StringEncoding
import
EncodedString
,
encoded_string_or_bytes_literal
from
.StringEncoding
import
EncodedString
,
encoded_string_or_bytes_literal
...
@@ -980,17 +980,21 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -980,17 +980,21 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
# Just let everything be public.
# Just let everything be public.
code
.
put
(
"struct %s"
%
type
.
cname
)
code
.
put
(
"struct %s"
%
type
.
cname
)
if
type
.
base_classes
:
if
type
.
base_classes
:
base_class_decl
=
", public "
.
join
(
base_class_list
=
[
base_class
.
empty_declaration_code
()
for
base_class
in
type
.
base_classes
]
[
base_class
.
empty_declaration_code
()
for
base_class
in
type
.
base_classes
])
if
type
.
is_cyp_class
and
type
.
base_classes
[
-
1
]
is
cy_object_type
:
base_class_list
[
-
1
]
=
"virtual "
+
base_class_list
[
-
1
]
base_class_decl
=
", public "
.
join
(
base_class_list
)
code
.
put
(
" : public %s"
%
base_class_decl
)
code
.
put
(
" : public %s"
%
base_class_decl
)
code
.
putln
(
" {"
)
code
.
putln
(
" {"
)
self
.
generate_type_header_code
(
scope
.
type_entries
,
code
)
self
.
generate_type_header_code
(
scope
.
type_entries
,
code
)
self
.
generate_cyp_class_wrapper_definitions
(
scope
.
sue_entries
,
code
)
py_attrs
=
[
e
for
e
in
scope
.
entries
.
values
()
py_attrs
=
[
e
for
e
in
scope
.
entries
.
values
()
if
e
.
type
.
is_pyobject
and
not
e
.
is_inherited
]
if
e
.
type
.
is_pyobject
and
not
e
.
is_inherited
]
has_virtual_methods
=
False
has_virtual_methods
=
False
constructor
=
None
constructor
=
None
destructor
=
None
destructor
=
None
for
attr
in
scope
.
var_entries
:
for
attr
in
scope
.
var_entries
:
cname
=
attr
.
cname
if
attr
.
type
.
is_cfunction
and
attr
.
type
.
is_static_method
:
if
attr
.
type
.
is_cfunction
and
attr
.
type
.
is_static_method
:
code
.
put
(
"static "
)
code
.
put
(
"static "
)
elif
attr
.
name
==
"<init>"
:
elif
attr
.
name
==
"<init>"
:
...
@@ -1001,7 +1005,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -1001,7 +1005,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
elif
attr
.
type
.
is_cfunction
:
elif
attr
.
type
.
is_cfunction
:
code
.
put
(
"virtual "
)
code
.
put
(
"virtual "
)
has_virtual_methods
=
True
has_virtual_methods
=
True
code
.
putln
(
"%s;"
%
attr
.
type
.
declaration_code
(
attr
.
cname
))
elif
attr
.
type
.
is_cyp_class
:
cname
=
"%s = NULL"
%
cname
code
.
putln
(
"%s;"
%
attr
.
type
.
declaration_code
(
cname
))
is_implementing
=
'init_module'
in
code
.
globalstate
.
parts
is_implementing
=
'init_module'
in
code
.
globalstate
.
parts
def
generate_cpp_constructor_code
(
arg_decls
,
arg_names
,
is_implementing
,
py_attrs
,
constructor
):
def
generate_cpp_constructor_code
(
arg_decls
,
arg_names
,
is_implementing
,
py_attrs
,
constructor
):
...
@@ -1084,6 +1090,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -1084,6 +1090,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code
.
putln
(
"%s& operator=(const %s& __Pyx_other);"
%
(
type
.
cname
,
type
.
cname
))
code
.
putln
(
"%s& operator=(const %s& __Pyx_other);"
%
(
type
.
cname
,
type
.
cname
))
code
.
putln
(
"};"
)
code
.
putln
(
"};"
)
if
type
.
is_cyp_class
:
code
.
globalstate
.
use_utility_code
(
UtilityCode
.
load
(
"CyObjects"
,
"CyObjects.cpp"
,
proto_block
=
"utility_code_proto_before_types"
))
def
generate_enum_definition
(
self
,
entry
,
code
):
def
generate_enum_definition
(
self
,
entry
,
code
):
code
.
mark_pos
(
entry
.
pos
)
code
.
mark_pos
(
entry
.
pos
)
type
=
entry
.
type
type
=
entry
.
type
...
@@ -1197,7 +1207,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -1197,7 +1207,6 @@ 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"
:
...
@@ -1208,16 +1217,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -1208,16 +1217,6 @@ 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
.
globalstate
.
use_utility_code
(
UtilityCode
.
load_cached
(
"CythonReferenceCounting"
,
"ObjectHandling.c"
))
code
.
putln
(
"// nogil"
)
code
.
putln
(
"int ob_refcnt;"
# "CyObject_HEAD;" Sometimes the CythonReferenceCounting was put after the nogil extension declaration, WTF!!!
)
else
:
else
:
code
.
putln
(
code
.
putln
(
"PyObject_HEAD"
)
"PyObject_HEAD"
)
...
...
Cython/Compiler/Nodes.py
View file @
83047799
This diff is collapsed.
Click to expand it.
Cython/Compiler/Parsing.py
View file @
83047799
...
@@ -2235,7 +2235,7 @@ def p_statement(s, ctx, first_statement = 0):
...
@@ -2235,7 +2235,7 @@ def p_statement(s, ctx, first_statement = 0):
elif
s
.
sy
==
'IF'
:
elif
s
.
sy
==
'IF'
:
return
p_IF_statement
(
s
,
ctx
)
return
p_IF_statement
(
s
,
ctx
)
elif
s
.
sy
==
'@'
:
elif
s
.
sy
==
'@'
:
if
ctx
.
level
not
in
(
'module'
,
'class'
,
'c_class'
,
'
class_nogil'
,
'
function'
,
'property'
,
'module_pxd'
,
'c_class_pxd'
,
'other'
):
if
ctx
.
level
not
in
(
'module'
,
'class'
,
'c_class'
,
'function'
,
'property'
,
'module_pxd'
,
'c_class_pxd'
,
'other'
):
s
.
error
(
'decorator not allowed here'
)
s
.
error
(
'decorator not allowed here'
)
s
.
level
=
ctx
.
level
s
.
level
=
ctx
.
level
decorators
=
p_decorators
(
s
)
decorators
=
p_decorators
(
s
)
...
@@ -2249,21 +2249,20 @@ def p_statement(s, ctx, first_statement = 0):
...
@@ -2249,21 +2249,20 @@ def p_statement(s, ctx, first_statement = 0):
return
p_pass_statement
(
s
,
with_newline
=
1
)
return
p_pass_statement
(
s
,
with_newline
=
1
)
overridable
=
0
overridable
=
0
nogil_flag
=
ctx
.
nogil
if
s
.
sy
==
'cdef'
:
if
s
.
sy
==
'cdef'
:
cdef_flag
=
1
cdef_flag
=
1
s
.
next
()
s
.
next
()
elif
s
.
sy
==
'cpdef'
:
elif
s
.
sy
==
'cpdef'
:
if
ctx
.
level
==
'c_class_nogil'
:
s
.
error
(
'cpdef statement not allowed in nogil extension type'
)
s
.
level
=
ctx
.
level
s
.
level
=
ctx
.
level
cdef_flag
=
1
cdef_flag
=
1
overridable
=
1
overridable
=
1
s
.
next
()
s
.
next
()
if
cdef_flag
:
if
cdef_flag
:
if
ctx
.
level
not
in
(
'module'
,
'module_pxd'
,
'function'
,
'c_class'
,
'c_class_
nogil'
,
'c_class_
pxd'
):
if
ctx
.
level
not
in
(
'module'
,
'module_pxd'
,
'function'
,
'c_class'
,
'c_class_pxd'
):
s
.
error
(
'cdef statement not allowed here'
)
s
.
error
(
'cdef statement not allowed here'
)
s
.
level
=
ctx
.
level
s
.
level
=
ctx
.
level
node
=
p_cdef_statement
(
s
,
ctx
(
overridable
=
overridable
))
node
=
p_cdef_statement
(
s
,
ctx
(
overridable
=
overridable
,
nogil
=
nogil_flag
))
if
decorators
is
not
None
:
if
decorators
is
not
None
:
tup
=
(
Nodes
.
CFuncDefNode
,
Nodes
.
CVarDefNode
,
Nodes
.
CClassDefNode
)
tup
=
(
Nodes
.
CFuncDefNode
,
Nodes
.
CVarDefNode
,
Nodes
.
CClassDefNode
)
if
ctx
.
allow_struct_enum_decorator
:
if
ctx
.
allow_struct_enum_decorator
:
...
@@ -2280,8 +2279,6 @@ def p_statement(s, ctx, first_statement = 0):
...
@@ -2280,8 +2279,6 @@ def p_statement(s, ctx, first_statement = 0):
# as part of a cdef class
# as part of a cdef class
if
(
'pxd'
in
ctx
.
level
)
and
(
ctx
.
level
!=
'c_class_pxd'
):
if
(
'pxd'
in
ctx
.
level
)
and
(
ctx
.
level
!=
'c_class_pxd'
):
s
.
error
(
'def statement not allowed here'
)
s
.
error
(
'def statement not allowed here'
)
if
ctx
.
level
==
'c_class_nogil'
:
s
.
error
(
'def statement not allowed in nogil extension type, only cdef with nogil is allowed'
)
s
.
level
=
ctx
.
level
s
.
level
=
ctx
.
level
return
p_def_statement
(
s
,
decorators
)
return
p_def_statement
(
s
,
decorators
)
elif
s
.
sy
==
'class'
:
elif
s
.
sy
==
'class'
:
...
@@ -2292,7 +2289,7 @@ def p_statement(s, ctx, first_statement = 0):
...
@@ -2292,7 +2289,7 @@ def p_statement(s, ctx, first_statement = 0):
if
ctx
.
level
not
in
(
'module'
,
'module_pxd'
):
if
ctx
.
level
not
in
(
'module'
,
'module_pxd'
):
s
.
error
(
"include statement not allowed here"
)
s
.
error
(
"include statement not allowed here"
)
return
p_include_statement
(
s
,
ctx
)
return
p_include_statement
(
s
,
ctx
)
elif
ctx
.
level
in
(
'c_class'
,
'c_class_nogil'
)
and
s
.
sy
==
'IDENT'
and
s
.
systring
==
'property'
:
elif
ctx
.
level
==
'c_class'
and
s
.
sy
==
'IDENT'
and
s
.
systring
==
'property'
:
return
p_property_decl
(
s
)
return
p_property_decl
(
s
)
elif
s
.
sy
==
'pass'
and
ctx
.
level
!=
'property'
:
elif
s
.
sy
==
'pass'
and
ctx
.
level
!=
'property'
:
return
p_pass_statement
(
s
,
with_newline
=
True
)
return
p_pass_statement
(
s
,
with_newline
=
True
)
...
@@ -3068,9 +3065,11 @@ def p_cdef_statement(s, ctx):
...
@@ -3068,9 +3065,11 @@ def p_cdef_statement(s, ctx):
return
p_cdef_extern_block
(
s
,
pos
,
ctx
)
return
p_cdef_extern_block
(
s
,
pos
,
ctx
)
elif
p_nogil
(
s
):
elif
p_nogil
(
s
):
ctx
.
nogil
=
1
ctx
.
nogil
=
1
if
ctx
.
overridable
:
#
if ctx.overridable:
error
(
pos
,
"cdef blocks cannot be declared cpdef"
)
#
error(pos, "cdef blocks cannot be declared cpdef")
return
p_cdef_block
(
s
,
ctx
)
return
p_cdef_block
(
s
,
ctx
)
elif
ctx
.
overridable
and
ctx
.
nogil
:
error
(
pos
,
"nogil blocks cannot be declared cpdef"
)
elif
s
.
sy
==
':'
:
elif
s
.
sy
==
':'
:
if
ctx
.
overridable
:
if
ctx
.
overridable
:
error
(
pos
,
"cdef blocks cannot be declared cpdef"
)
error
(
pos
,
"cdef blocks cannot be declared cpdef"
)
...
@@ -3081,7 +3080,7 @@ def p_cdef_statement(s, ctx):
...
@@ -3081,7 +3080,7 @@ def p_cdef_statement(s, ctx):
if
ctx
.
overridable
:
if
ctx
.
overridable
:
error
(
pos
,
"Extension types cannot be declared cpdef"
)
error
(
pos
,
"Extension types cannot be declared cpdef"
)
return
p_c_class_definition
(
s
,
pos
,
ctx
)
return
p_c_class_definition
(
s
,
pos
,
ctx
)
elif
s
.
sy
==
'IDENT'
and
s
.
systring
==
'cppclass'
:
elif
s
.
sy
==
'IDENT'
and
s
.
systring
in
(
'cppclass'
,
'cypclass'
)
:
return
p_cpp_class_definition
(
s
,
pos
,
ctx
)
return
p_cpp_class_definition
(
s
,
pos
,
ctx
)
elif
s
.
sy
==
'IDENT'
and
s
.
systring
in
struct_enum_union
:
elif
s
.
sy
==
'IDENT'
and
s
.
systring
in
struct_enum_union
:
if
ctx
.
level
not
in
(
'module'
,
'module_pxd'
):
if
ctx
.
level
not
in
(
'module'
,
'module_pxd'
):
...
@@ -3276,7 +3275,7 @@ def p_c_modifiers(s):
...
@@ -3276,7 +3275,7 @@ def p_c_modifiers(s):
return
[]
return
[]
def
p_c_func_or_var_declaration
(
s
,
pos
,
ctx
):
def
p_c_func_or_var_declaration
(
s
,
pos
,
ctx
):
cmethod_flag
=
ctx
.
level
in
(
'c_class'
,
'c_class_pxd'
,
'c_class_nogil'
)
cmethod_flag
=
ctx
.
level
in
(
'c_class'
,
'c_class_pxd'
)
modifiers
=
p_c_modifiers
(
s
)
modifiers
=
p_c_modifiers
(
s
)
base_type
=
p_c_base_type
(
s
,
nonempty
=
1
,
templates
=
ctx
.
templates
)
base_type
=
p_c_base_type
(
s
,
nonempty
=
1
,
templates
=
ctx
.
templates
)
declarator
=
p_c_declarator
(
s
,
ctx
(
modifiers
=
modifiers
),
cmethod_flag
=
cmethod_flag
,
declarator
=
p_c_declarator
(
s
,
ctx
(
modifiers
=
modifiers
),
cmethod_flag
=
cmethod_flag
,
...
@@ -3295,13 +3294,8 @@ def p_c_func_or_var_declaration(s, pos, ctx):
...
@@ -3295,13 +3294,8 @@ def p_c_func_or_var_declaration(s, pos, ctx):
fatal
=
False
)
fatal
=
False
)
s
.
next
()
s
.
next
()
p_test
(
s
)
# Keep going, but ignore result.
p_test
(
s
)
# Keep going, but ignore result.
if
s
.
sy
==
'nogil'
:
nogil
=
p_nogil
(
s
)
s
.
next
()
if
ctx
.
level
==
'c_class_nogil'
and
not
nogil
:
s
.
error
(
"Only C function with nogil allowed in nogil extension"
)
if
s
.
sy
==
':'
:
if
s
.
sy
==
':'
:
if
ctx
.
level
not
in
(
'module'
,
'c_class'
,
'module_pxd'
,
'c_class_pxd'
,
'cpp_class'
,
'c_class_nogil'
)
and
not
ctx
.
templates
:
if
ctx
.
level
not
in
(
'module'
,
'c_class'
,
'module_pxd'
,
'c_class_pxd'
,
'cpp_class'
)
and
not
ctx
.
templates
:
s
.
error
(
"C function definition not allowed here"
)
s
.
error
(
"C function definition not allowed here"
)
doc
,
suite
=
p_suite_with_docstring
(
s
,
Ctx
(
level
=
'function'
))
doc
,
suite
=
p_suite_with_docstring
(
s
,
Ctx
(
level
=
'function'
))
result
=
Nodes
.
CFuncDefNode
(
pos
,
result
=
Nodes
.
CFuncDefNode
(
pos
,
...
@@ -3329,7 +3323,7 @@ def p_c_func_or_var_declaration(s, pos, ctx):
...
@@ -3329,7 +3323,7 @@ def p_c_func_or_var_declaration(s, pos, ctx):
declarators
.
append
(
declarator
)
declarators
.
append
(
declarator
)
doc_line
=
s
.
start_line
+
1
doc_line
=
s
.
start_line
+
1
s
.
expect_newline
(
"Syntax error in C variable declaration"
,
ignore_semicolon
=
True
)
s
.
expect_newline
(
"Syntax error in C variable declaration"
,
ignore_semicolon
=
True
)
if
ctx
.
level
in
(
'c_class'
,
'c_class_pxd'
,
'c_class_nogil'
)
and
s
.
start_line
==
doc_line
:
if
ctx
.
level
in
(
'c_class'
,
'c_class_pxd'
)
and
s
.
start_line
==
doc_line
:
doc
=
p_doc_string
(
s
)
doc
=
p_doc_string
(
s
)
else
:
else
:
doc
=
None
doc
=
None
...
@@ -3530,12 +3524,9 @@ def p_c_class_definition(s, pos, ctx):
...
@@ -3530,12 +3524,9 @@ def p_c_class_definition(s, pos, ctx):
if
ctx
.
visibility
not
in
(
'public'
,
'extern'
)
and
not
ctx
.
api
:
if
ctx
.
visibility
not
in
(
'public'
,
'extern'
)
and
not
ctx
.
api
:
error
(
s
.
position
(),
"Name options only allowed for 'public', 'api', or 'extern' C class"
)
error
(
s
.
position
(),
"Name options only allowed for 'public', 'api', or 'extern' C class"
)
objstruct_name
,
typeobj_name
,
check_size
=
p_c_class_options
(
s
)
objstruct_name
,
typeobj_name
,
check_size
=
p_c_class_options
(
s
)
nogil
=
p_nogil
(
s
)
if
s
.
sy
==
':'
:
if
s
.
sy
==
':'
:
if
ctx
.
level
==
'module_pxd'
:
if
ctx
.
level
==
'module_pxd'
:
body_level
=
'c_class_pxd'
body_level
=
'c_class_pxd'
elif
nogil
:
body_level
=
'c_class_nogil'
else
:
else
:
body_level
=
'c_class'
body_level
=
'c_class'
doc
,
body
=
p_suite_with_docstring
(
s
,
Ctx
(
level
=
body_level
))
doc
,
body
=
p_suite_with_docstring
(
s
,
Ctx
(
level
=
body_level
))
...
@@ -3574,8 +3565,7 @@ def p_c_class_definition(s, pos, ctx):
...
@@ -3574,8 +3565,7 @@ def p_c_class_definition(s, pos, ctx):
check_size
=
check_size
,
check_size
=
check_size
,
in_pxd
=
ctx
.
level
==
'module_pxd'
,
in_pxd
=
ctx
.
level
==
'module_pxd'
,
doc
=
doc
,
doc
=
doc
,
body
=
body
,
body
=
body
)
nogil
=
nogil
or
ctx
.
nogil
)
def
p_c_class_options
(
s
):
def
p_c_class_options
(
s
):
...
@@ -3756,7 +3746,8 @@ def p_template_definition(s):
...
@@ -3756,7 +3746,8 @@ def p_template_definition(s):
return
name
,
required
return
name
,
required
def
p_cpp_class_definition
(
s
,
pos
,
ctx
):
def
p_cpp_class_definition
(
s
,
pos
,
ctx
):
# s.sy == 'cppclass'
# s.sy in ('cppclass', 'cypclass')
cypclass
=
s
.
systring
==
'cypclass'
s
.
next
()
s
.
next
()
module_path
=
[]
module_path
=
[]
class_name
=
p_ident
(
s
)
class_name
=
p_ident
(
s
)
...
@@ -3787,7 +3778,7 @@ def p_cpp_class_definition(s, pos, ctx):
...
@@ -3787,7 +3778,7 @@ def p_cpp_class_definition(s, pos, ctx):
base_classes
=
[]
base_classes
=
[]
if
s
.
sy
==
'['
:
if
s
.
sy
==
'['
:
error
(
s
.
position
(),
"Name options not allowed for C++ class"
)
error
(
s
.
position
(),
"Name options not allowed for C++ class"
)
nogil
=
p_nogil
(
s
)
nogil
=
p_nogil
(
s
)
or
cypclass
if
s
.
sy
==
':'
:
if
s
.
sy
==
':'
:
s
.
next
()
s
.
next
()
s
.
expect
(
'NEWLINE'
)
s
.
expect
(
'NEWLINE'
)
...
@@ -3816,7 +3807,7 @@ def p_cpp_class_definition(s, pos, ctx):
...
@@ -3816,7 +3807,7 @@ def p_cpp_class_definition(s, pos, ctx):
visibility
=
ctx
.
visibility
,
visibility
=
ctx
.
visibility
,
in_pxd
=
ctx
.
level
==
'module_pxd'
,
in_pxd
=
ctx
.
level
==
'module_pxd'
,
attributes
=
attributes
,
attributes
=
attributes
,
templates
=
templates
)
templates
=
templates
,
cypclass
=
cypclass
)
def
p_cpp_class_attribute
(
s
,
ctx
):
def
p_cpp_class_attribute
(
s
,
ctx
):
decorators
=
None
decorators
=
None
...
...
Cython/Compiler/PyrexTypes.py
View file @
83047799
This diff is collapsed.
Click to expand it.
Cython/Compiler/Symtab.py
View file @
83047799
...
@@ -17,7 +17,7 @@ from .Errors import warning, error, InternalError
...
@@ -17,7 +17,7 @@ from .Errors import warning, error, InternalError
from
.StringEncoding
import
EncodedString
from
.StringEncoding
import
EncodedString
from
.
import
Options
,
Naming
from
.
import
Options
,
Naming
from
.
import
PyrexTypes
from
.
import
PyrexTypes
from
.PyrexTypes
import
py_object_type
,
unspecified_type
from
.PyrexTypes
import
py_object_type
,
cy_object_type
,
unspecified_type
from
.TypeSlots
import
(
from
.TypeSlots
import
(
pyfunction_signature
,
pymethod_signature
,
richcmp_special_methods
,
pyfunction_signature
,
pymethod_signature
,
richcmp_special_methods
,
get_special_method_signature
,
get_property_accessor_signature
)
get_special_method_signature
,
get_property_accessor_signature
)
...
@@ -628,7 +628,7 @@ class Scope(object):
...
@@ -628,7 +628,7 @@ class Scope(object):
def
declare_cpp_class
(
self
,
name
,
scope
,
def
declare_cpp_class
(
self
,
name
,
scope
,
pos
,
cname
=
None
,
base_classes
=
(),
pos
,
cname
=
None
,
base_classes
=
(),
visibility
=
'extern'
,
templates
=
None
):
visibility
=
'extern'
,
templates
=
None
,
cypclass
=
0
):
if
cname
is
None
:
if
cname
is
None
:
if
self
.
in_cinclude
or
(
visibility
!=
'private'
):
if
self
.
in_cinclude
or
(
visibility
!=
'private'
):
cname
=
name
cname
=
name
...
@@ -637,8 +637,12 @@ class Scope(object):
...
@@ -637,8 +637,12 @@ class Scope(object):
base_classes
=
list
(
base_classes
)
base_classes
=
list
(
base_classes
)
entry
=
self
.
lookup_here
(
name
)
entry
=
self
.
lookup_here
(
name
)
if
not
entry
:
if
not
entry
:
type
=
PyrexTypes
.
CppClassType
(
if
cypclass
:
name
,
scope
,
cname
,
base_classes
,
templates
=
templates
)
type
=
PyrexTypes
.
CypClassType
(
name
,
scope
,
cname
,
base_classes
,
templates
=
templates
)
else
:
type
=
PyrexTypes
.
CppClassType
(
name
,
scope
,
cname
,
base_classes
,
templates
=
templates
)
entry
=
self
.
declare_type
(
name
,
type
,
pos
,
cname
,
entry
=
self
.
declare_type
(
name
,
type
,
pos
,
cname
,
visibility
=
visibility
,
defining
=
scope
is
not
None
)
visibility
=
visibility
,
defining
=
scope
is
not
None
)
self
.
sue_entries
.
append
(
entry
)
self
.
sue_entries
.
append
(
entry
)
...
@@ -666,7 +670,7 @@ class Scope(object):
...
@@ -666,7 +670,7 @@ class Scope(object):
def
declare_inherited_attributes
(
entry
,
base_classes
):
def
declare_inherited_attributes
(
entry
,
base_classes
):
for
base_class
in
base_classes
:
for
base_class
in
base_classes
:
if
base_class
is
PyrexTypes
.
error_type
:
if
base_class
is
PyrexTypes
.
error_type
or
base_class
is
PyrexTypes
.
cy_object_type
:
continue
continue
if
base_class
.
scope
is
None
:
if
base_class
.
scope
is
None
:
error
(
pos
,
"Cannot inherit from incomplete type"
)
error
(
pos
,
"Cannot inherit from incomplete type"
)
...
@@ -1573,7 +1577,7 @@ class ModuleScope(Scope):
...
@@ -1573,7 +1577,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
,
nogil
=
0
,
check_size
=
None
,
typedef_flag
=
0
,
api
=
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
...
@@ -1606,15 +1610,8 @@ class ModuleScope(Scope):
...
@@ -1606,15 +1610,8 @@ 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
:
if
nogil
:
type
=
PyrexTypes
.
PyExtensionType
(
pass
name
,
typedef_flag
,
base_type
,
visibility
==
'extern'
,
check_size
=
check_size
)
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
:
...
@@ -2334,8 +2331,7 @@ class CClassScope(ClassScope):
...
@@ -2334,8 +2331,7 @@ class CClassScope(ClassScope):
defining
=
0
,
modifiers
=
(),
utility_code
=
None
,
overridable
=
False
):
defining
=
0
,
modifiers
=
(),
utility_code
=
None
,
overridable
=
False
):
name
=
self
.
mangle_class_private_name
(
name
)
name
=
self
.
mangle_class_private_name
(
name
)
if
get_special_method_signature
(
name
)
and
not
self
.
parent_type
.
is_builtin_type
:
if
get_special_method_signature
(
name
)
and
not
self
.
parent_type
.
is_builtin_type
:
if
not
(
hasattr
(
self
.
parent_type
,
"nogil"
)
and
self
.
parent_type
.
nogil
and
self
.
parent_type
.
is_struct_or_union
):
error
(
pos
,
"Special methods must be declared with 'def', not 'cdef'"
)
error
(
pos
,
"Special methods must be declared with 'def', not 'cdef'"
)
args
=
type
.
args
args
=
type
.
args
if
not
type
.
is_static_method
:
if
not
type
.
is_static_method
:
if
not
args
:
if
not
args
:
...
@@ -2571,6 +2567,8 @@ class CppClassScope(Scope):
...
@@ -2571,6 +2567,8 @@ class CppClassScope(Scope):
type
.
return_type
=
PyrexTypes
.
c_void_type
type
.
return_type
=
PyrexTypes
.
c_void_type
if
name
in
(
'<init>'
,
'<del>'
)
and
type
.
nogil
:
if
name
in
(
'<init>'
,
'<del>'
)
and
type
.
nogil
:
for
base
in
self
.
type
.
base_classes
:
for
base
in
self
.
type
.
base_classes
:
if
base
is
cy_object_type
:
continue
base_entry
=
base
.
scope
.
lookup
(
name
)
base_entry
=
base
.
scope
.
lookup
(
name
)
if
base_entry
and
not
base_entry
.
type
.
nogil
:
if
base_entry
and
not
base_entry
.
type
.
nogil
:
error
(
pos
,
"Constructor cannot be called without GIL unless all base constructors can also be called without GIL"
)
error
(
pos
,
"Constructor cannot be called without GIL unless all base constructors can also be called without GIL"
)
...
...
Cython/Compiler/UtilNodes.py
View file @
83047799
...
@@ -198,10 +198,13 @@ class ResultRefNode(AtomicExprNode):
...
@@ -198,10 +198,13 @@ class ResultRefNode(AtomicExprNode):
pass
pass
def
generate_assignment_code
(
self
,
rhs
,
code
,
overloaded_assignment
=
False
):
def
generate_assignment_code
(
self
,
rhs
,
code
,
overloaded_assignment
=
False
):
if
self
.
type
.
is_pyobject
:
if
self
.
type
.
is_pyobject
or
self
.
type
.
is_cyp_class
:
rhs
.
make_owned_reference
(
code
)
rhs
.
make_owned_reference
(
code
)
if
not
self
.
lhs_of_first_assignment
:
if
not
self
.
lhs_of_first_assignment
:
code
.
put_decref
(
self
.
result
(),
self
.
ctype
())
if
self
.
type
.
is_pyobject
:
code
.
put_decref
(
self
.
result
(),
self
.
ctype
())
elif
self
.
type
.
is_cyp_class
:
code
.
put_cydecref
(
self
.
result
())
code
.
putln
(
'%s = %s;'
%
(
code
.
putln
(
'%s = %s;'
%
(
self
.
result
(),
self
.
result
(),
rhs
.
result
()
if
overloaded_assignment
else
rhs
.
result_as
(
self
.
ctype
()),
rhs
.
result
()
if
overloaded_assignment
else
rhs
.
result_as
(
self
.
ctype
()),
...
@@ -248,6 +251,9 @@ class LetNodeMixin:
...
@@ -248,6 +251,9 @@ class LetNodeMixin:
else
:
else
:
if
self
.
temp_type
.
is_pyobject
:
if
self
.
temp_type
.
is_pyobject
:
code
.
put_decref_clear
(
self
.
temp
,
self
.
temp_type
)
code
.
put_decref_clear
(
self
.
temp
,
self
.
temp_type
)
elif
self
.
temp_type
.
is_cyp_class
:
pass
#code.put_decref_clear(self.temp, self.temp_type)
code
.
funcstate
.
release_temp
(
self
.
temp
)
code
.
funcstate
.
release_temp
(
self
.
temp
)
...
...
Cython/Utility/CyObjects.cpp
0 → 100644
View file @
83047799
/////////////// CyObjects.proto ///////////////
#if !defined(__GNUC__)
#define GCC_VERSION (__GNUC__ * 10000 \
+ __GNUC_MINOR__ * 100 \
+ __GNUC_PATCHLEVEL__)
/* Test for GCC > 4.9.0 */
#if GCC_VERSION < 40900
#error atomic.h works only with GCC newer than version 4.9
#endif
/* GNUC >= 4.9 */
#endif
/* Has GCC */
#ifdef __cplusplus
#if __cplusplus >= 201103L
#include <atomic>
using
namespace
std
;
#define CyObject_ATOMIC_REFCOUNT_TYPE atomic_int
class
CyObject
{
private:
CyObject_ATOMIC_REFCOUNT_TYPE
ob_refcnt
;
public:
CyObject
()
:
ob_refcnt
(
1
)
{}
virtual
~
CyObject
()
{}
void
CyObject_INCREF
();
int
CyObject_DECREF
();
};
static
inline
int
_Cy_DECREF
(
CyObject
*
op
)
{
return
op
->
CyObject_DECREF
();
}
static
inline
void
_Cy_INCREF
(
CyObject
*
op
)
{
op
->
CyObject_INCREF
();
}
/* Cast argument to CyObject* type. */
#define _CyObject_CAST(op) op
#define Cy_INCREF(op) do {if (op != NULL) {_Cy_INCREF(_CyObject_CAST(op));}} while(0)
#define Cy_DECREF(op) do {if (_Cy_DECREF(_CyObject_CAST(op))) {op = NULL;}} while(0)
#define Cy_XDECREF(op) do {if (op != NULL) {Cy_DECREF(op);}} while(0)
#define Cy_GOTREF(op)
#define Cy_XGOTREF(op)
#define Cy_GIVEREF(op)
#define Cy_XGIVEREF(op)
#endif
#endif
/////////////// CyObjects ///////////////
#ifdef __cplusplus
#include <cstdlib>
#include <cstddef>
// atomic is already included in ModuleSetupCode
// #include <atomic>
#else
#error C++ needed for cython+ nogil classes
#endif
/* __cplusplus */
void
CyObject
::
CyObject_INCREF
()
{
atomic_fetch_add
(
&
(
this
->
ob_refcnt
),
1
);
}
int
CyObject
::
CyObject_DECREF
()
{
if
(
atomic_fetch_sub
(
&
(
this
->
ob_refcnt
),
1
)
==
1
)
{
delete
this
;
return
1
;
}
return
0
;
}
Cython/Utility/ObjectHandling.c
View file @
83047799
...
@@ -1851,51 +1851,6 @@ try_unpack:
...
@@ -1851,51 +1851,6 @@ try_unpack:
return
0
;
return
0
;
}
}
/////////////// CythonReferenceCounting.proto ///////////////
#include <stdlib.h>
#include <stddef.h>
#if !defined(__GNUC__)
#define GCC_VERSION (__GNUC__ * 10000 \
+ __GNUC_MINOR__ * 100 \
+ __GNUC_PATCHLEVEL__)
/* Test for GCC > 4.9.0 */
#if GCC_VERSION < 40900
#error atomic.h works only with GCC newer than version 4.9
#endif
/* GNUC >= 4.9 */
#endif
/* Has GCC */
// #include <stdatomic.h>
/* CyObject_HEAD defines the initial segment of every CyObject. */
#define CyObject_HEAD \
int ob_refcnt; \
void (*cdealloc)();
struct
CyObject
{
CyObject_HEAD
};
/* Cast argument to PyObject* type. */
#define _CyObject_CAST(op) ((struct CyObject*)(op))
// XXX: Without scope analysis this is useless...
/*
static inline void _Cy_DECREF(struct CyObject *op) {
if (atomic_fetch_sub(&(op->ob_refcnt), 1) == 1) {
op->cdealloc(op);
}
}
static inline void _Cy_INCREF(struct CyObject *op) {
atomic_fetch_add(&(op->ob_refcnt), 1);
}
#define Cy_INCREF(op) _Cy_INCREF(_CyObject_CAST(op))
#define Cy_DECREF(op) _Cy_DECREF(_CyObject_CAST(op))
*/
/////////////// UnpackUnboundCMethod.proto ///////////////
/////////////// UnpackUnboundCMethod.proto ///////////////
...
...
nogil_test/nogil_extension.pyx
View file @
83047799
...
@@ -32,7 +32,7 @@ from libc.stdio cimport printf
...
@@ -32,7 +32,7 @@ from libc.stdio cimport printf
# cdef class SomeMemory:
# cdef class SomeMemory:
c
def
class
SomeMemory
nogil
:
c
cdef
class
SomeMemory
:
"""
"""
This is a cdef class which is also called
This is a cdef class which is also called
a extensino type. It is a kind of C struct
a extensino type. It is a kind of C struct
...
@@ -41,7 +41,7 @@ cdef class SomeMemory nogil:
...
@@ -41,7 +41,7 @@ cdef class SomeMemory nogil:
We would like to be able to define "nogil"
We would like to be able to define "nogil"
extension types:
extension types:
c
def class SomeMemory nogil
:
c
cdef class SomeMemory
:
where all methods are "nogil" and memory
where all methods are "nogil" and memory
allocation does not depend on python runtime
allocation does not depend on python runtime
...
@@ -54,10 +54,10 @@ cdef class SomeMemory nogil:
...
@@ -54,10 +54,10 @@ cdef class SomeMemory nogil:
# self.b = b
# self.b = b
pass
pass
cdef
void
cdealloc
(
self
)
nogil
:
cdef
void
cdealloc
(
self
):
pass
pass
cdef
void
foo1
(
self
)
nogil
:
cdef
void
foo1
(
self
):
"""
"""
It is possible to define native C/Cython methods
It is possible to define native C/Cython methods
that release the GIL (cool...)
that release the GIL (cool...)
...
...
test.pyx
View file @
83047799
...
@@ -31,7 +31,7 @@ from libc.stdio cimport printf
...
@@ -31,7 +31,7 @@ from libc.stdio cimport printf
# cdef class SomeMemory:
# cdef class SomeMemory:
c
def
class
SomeMemory
nogil
:
c
cdef
class
SomeMemory
:
"""
"""
This is a cdef class which is also called
This is a cdef class which is also called
a extensino type. It is a kind of C struct
a extensino type. It is a kind of C struct
...
...
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