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
Show 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,6 +782,9 @@ class ExprNode(Node):
...
@@ -782,6 +782,9 @@ 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
():
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
())
code
.
put_incref
(
self
.
result
(),
self
.
ctype
())
def
make_owned_memoryviewslice
(
self
,
code
):
def
make_owned_memoryviewslice
(
self
,
code
):
...
@@ -824,6 +827,9 @@ class ExprNode(Node):
...
@@ -824,6 +827,9 @@ 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
():
if
self
.
type
.
is_cyp_class
:
code
.
put_cyxdecref
(
self
.
result
())
else
:
code
.
put_decref_clear
(
self
.
result
(),
self
.
ctype
(),
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
:
...
@@ -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,6 +1845,9 @@ class ImagNode(AtomicExprNode):
...
@@ -1837,6 +1845,9 @@ 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
)))
if
self
.
type
.
is_cyp_class
:
code
.
put_cygotref
(
self
.
result
())
else
:
self
.
generate_gotref
(
code
)
self
.
generate_gotref
(
code
)
...
@@ -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,9 +7249,6 @@ class AttributeNode(ExprNode):
...
@@ -7223,9 +7249,6 @@ class AttributeNode(ExprNode):
# (AnalyseExpressionsTransform)
# (AnalyseExpressionsTransform)
self
.
member
=
self
.
entry
.
cname
self
.
member
=
self
.
entry
.
cname
if
obj
.
type
.
nogil
:
return
"%s"
%
self
.
entry
.
func_cname
else
:
return
"((struct %s *)%s%s%s)->%s"
%
(
return
"((struct %s *)%s%s%s)->%s"
%
(
obj
.
type
.
vtabstruct_cname
,
obj_code
,
self
.
op
,
obj
.
type
.
vtabstruct_cname
,
obj_code
,
self
.
op
,
obj
.
type
.
vtabslot_cname
,
self
.
member
)
obj
.
type
.
vtabslot_cname
,
self
.
member
)
...
@@ -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,6 +13540,9 @@ class CoerceToTempNode(CoercionNode):
...
@@ -13519,6 +13540,9 @@ 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
:
if
self
.
type
.
is_cyp_class
:
code
.
put_cyincref
(
self
.
result
())
else
:
code
.
put_incref
(
self
.
result
(),
self
.
ctype
())
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
,
...
...
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
...
@@ -7,7 +7,7 @@ from __future__ import absolute_import
...
@@ -7,7 +7,7 @@ from __future__ import absolute_import
import
cython
import
cython
cython
.
declare
(
sys
=
object
,
os
=
object
,
copy
=
object
,
cython
.
declare
(
sys
=
object
,
os
=
object
,
copy
=
object
,
Builtin
=
object
,
error
=
object
,
warning
=
object
,
Naming
=
object
,
PyrexTypes
=
object
,
Builtin
=
object
,
error
=
object
,
warning
=
object
,
Naming
=
object
,
PyrexTypes
=
object
,
py_object_type
=
object
,
ModuleScope
=
object
,
LocalScope
=
object
,
ClosureScope
=
object
,
py_object_type
=
object
,
cy_object_type
=
object
,
ModuleScope
=
object
,
LocalScope
=
object
,
ClosureScope
=
object
,
StructOrUnionScope
=
object
,
PyClassScope
=
object
,
StructOrUnionScope
=
object
,
PyClassScope
=
object
,
CppClassScope
=
object
,
UtilityCode
=
object
,
EncodedString
=
object
,
CppClassScope
=
object
,
UtilityCode
=
object
,
EncodedString
=
object
,
error_type
=
object
,
_py_int_types
=
object
)
error_type
=
object
,
_py_int_types
=
object
)
...
@@ -20,7 +20,7 @@ from .Errors import error, warning, InternalError, CompileError
...
@@ -20,7 +20,7 @@ from .Errors import error, warning, InternalError, CompileError
from
.
import
Naming
from
.
import
Naming
from
.
import
PyrexTypes
from
.
import
PyrexTypes
from
.
import
TypeSlots
from
.
import
TypeSlots
from
.PyrexTypes
import
py_object_type
,
error_type
from
.PyrexTypes
import
py_object_type
,
cy_object_type
,
error_type
from
.Symtab
import
(
ModuleScope
,
LocalScope
,
ClosureScope
,
PropertyScope
,
from
.Symtab
import
(
ModuleScope
,
LocalScope
,
ClosureScope
,
PropertyScope
,
StructOrUnionScope
,
PyClassScope
,
CppClassScope
,
TemplateScope
,
StructOrUnionScope
,
PyClassScope
,
CppClassScope
,
TemplateScope
,
punycodify_name
)
punycodify_name
)
...
@@ -956,6 +956,9 @@ class CArgDeclNode(Node):
...
@@ -956,6 +956,9 @@ class CArgDeclNode(Node):
default
.
make_owned_reference
(
code
)
default
.
make_owned_reference
(
code
)
result
=
default
.
result
()
if
overloaded_assignment
else
default
.
result_as
(
self
.
type
)
result
=
default
.
result
()
if
overloaded_assignment
else
default
.
result_as
(
self
.
type
)
code
.
putln
(
"%s = %s;"
%
(
target
,
result
))
code
.
putln
(
"%s = %s;"
%
(
target
,
result
))
if
self
.
type
.
is_cyp_class
:
code
.
put_cygiveref
(
default
.
result
())
else
:
code
.
put_giveref
(
default
.
result
(),
self
.
type
)
code
.
put_giveref
(
default
.
result
(),
self
.
type
)
default
.
generate_post_assignment_code
(
code
)
default
.
generate_post_assignment_code
(
code
)
default
.
free_temps
(
code
)
default
.
free_temps
(
code
)
...
@@ -1008,6 +1011,9 @@ class CSimpleBaseTypeNode(CBaseTypeNode):
...
@@ -1008,6 +1011,9 @@ class CSimpleBaseTypeNode(CBaseTypeNode):
error
(
self
.
pos
,
"Unrecognised type modifier combination"
)
error
(
self
.
pos
,
"Unrecognised type modifier combination"
)
elif
self
.
name
==
"object"
and
not
self
.
module_path
:
elif
self
.
name
==
"object"
and
not
self
.
module_path
:
type
=
py_object_type
type
=
py_object_type
elif
self
.
name
==
"cyobject"
:
type
=
cy_object_type
self
.
arg_name
=
EncodedString
(
self
.
name
)
elif
self
.
name
is
None
:
elif
self
.
name
is
None
:
if
self
.
is_self_arg
and
env
.
is_c_class_scope
:
if
self
.
is_self_arg
and
env
.
is_c_class_scope
:
#print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
#print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
...
@@ -1474,7 +1480,7 @@ class CppClassNode(CStructOrUnionDefNode, BlockNode):
...
@@ -1474,7 +1480,7 @@ class CppClassNode(CStructOrUnionDefNode, BlockNode):
error
(
self
.
pos
,
"Required template parameters must precede optional template parameters."
)
error
(
self
.
pos
,
"Required template parameters must precede optional template parameters."
)
self
.
entry
=
env
.
declare_cpp_class
(
self
.
entry
=
env
.
declare_cpp_class
(
self
.
name
,
None
,
self
.
pos
,
self
.
cname
,
self
.
name
,
None
,
self
.
pos
,
self
.
cname
,
base_classes
=
[],
visibility
=
self
.
visibility
,
templates
=
template_types
)
base_classes
=
[],
visibility
=
self
.
visibility
,
templates
=
template_types
,
cypclass
=
self
.
cypclass
)
def
analyse_declarations
(
self
,
env
):
def
analyse_declarations
(
self
,
env
):
if
self
.
templates
is
None
:
if
self
.
templates
is
None
:
...
@@ -1491,10 +1497,24 @@ class CppClassNode(CStructOrUnionDefNode, BlockNode):
...
@@ -1491,10 +1497,24 @@ class CppClassNode(CStructOrUnionDefNode, BlockNode):
return
True
return
True
else
:
else
:
error
(
self
.
pos
,
"Base class '%s' not a struct or class."
%
base_class
)
error
(
self
.
pos
,
"Base class '%s' not a struct or class."
%
base_class
)
base_class_types
=
filter
(
base_ok
,
[
b
.
analyse
(
scope
or
env
)
for
b
in
self
.
base_classes
])
base_types_list
=
[
b
.
analyse
(
scope
or
env
)
for
b
in
self
.
base_classes
]
if
self
.
cypclass
:
cyobject_base
=
False
for
base_type
in
base_types_list
:
cyobject_base
=
cyobject_base
or
base_type
is
cy_object_type
or
base_type
.
is_cyp_class
if
not
cyobject_base
:
cyobject_class
=
CSimpleBaseTypeNode
(
self
.
pos
,
name
=
"cyobject"
,
module_path
=
[],
is_basic_c_type
=
0
,
signed
=
0
,
complex
=
0
,
longness
=
0
,
is_self_arg
=
0
,
templates
=
None
)
self
.
base_classes
.
append
(
cyobject_class
)
base_types_list
.
append
(
cyobject_class
.
analyse
(
scope
or
env
))
base_class_types
=
filter
(
base_ok
,
base_types_list
)
self
.
entry
=
env
.
declare_cpp_class
(
self
.
entry
=
env
.
declare_cpp_class
(
self
.
name
,
scope
,
self
.
pos
,
self
.
name
,
scope
,
self
.
pos
,
self
.
cname
,
base_class_types
,
visibility
=
self
.
visibility
,
templates
=
template_types
)
self
.
cname
,
base_class_types
,
visibility
=
self
.
visibility
,
templates
=
template_types
,
cypclass
=
self
.
cypclass
)
if
self
.
entry
is
None
:
if
self
.
entry
is
None
:
return
return
self
.
entry
.
is_cpp_class
=
1
self
.
entry
.
is_cpp_class
=
1
...
@@ -1832,7 +1852,7 @@ class FuncDefNode(StatNode, BlockNode):
...
@@ -1832,7 +1852,7 @@ class FuncDefNode(StatNode, BlockNode):
init
=
""
init
=
""
return_type
=
self
.
return_type
return_type
=
self
.
return_type
if
not
return_type
.
is_void
:
if
not
return_type
.
is_void
:
if
return_type
.
is_pyobject
:
if
return_type
.
is_pyobject
or
return_type
.
is_cyp_class
:
init
=
" = NULL"
init
=
" = NULL"
elif
return_type
.
is_memoryviewslice
:
elif
return_type
.
is_memoryviewslice
:
init
=
' = '
+
return_type
.
literal_code
(
return_type
.
default_value
)
init
=
' = '
+
return_type
.
literal_code
(
return_type
.
default_value
)
...
@@ -1966,6 +1986,9 @@ class FuncDefNode(StatNode, BlockNode):
...
@@ -1966,6 +1986,9 @@ class FuncDefNode(StatNode, BlockNode):
elif
is_cdef
and
entry
.
cf_is_reassigned
:
elif
is_cdef
and
entry
.
cf_is_reassigned
:
code
.
put_var_incref_memoryviewslice
(
entry
,
code
.
put_var_incref_memoryviewslice
(
entry
,
have_gil
=
code
.
funcstate
.
gil_owned
)
have_gil
=
code
.
funcstate
.
gil_owned
)
# We have to Cy_INCREF the nogil classes (ccdef'ed ones)
elif
entry
.
type
.
is_cyp_class
and
len
(
entry
.
cf_assignments
)
>
1
:
code
.
put_cyincref
(
entry
.
cname
)
for
entry
in
lenv
.
var_entries
:
for
entry
in
lenv
.
var_entries
:
if
entry
.
is_arg
and
entry
.
cf_is_reassigned
and
not
entry
.
in_closure
:
if
entry
.
is_arg
and
entry
.
cf_is_reassigned
and
not
entry
.
in_closure
:
if
entry
.
xdecref_cleanup
:
if
entry
.
xdecref_cleanup
:
...
@@ -2148,11 +2171,14 @@ class FuncDefNode(StatNode, BlockNode):
...
@@ -2148,11 +2171,14 @@ class FuncDefNode(StatNode, BlockNode):
if
not
entry
.
used
or
entry
.
in_closure
:
if
not
entry
.
used
or
entry
.
in_closure
:
continue
continue
if
entry
.
type
.
is_pyobject
:
if
entry
.
type
.
is_pyobject
or
entry
.
type
.
is_cyp_class
:
if
entry
.
is_arg
and
not
entry
.
cf_is_reassigned
:
if
entry
.
is_arg
and
not
entry
.
cf_is_reassigned
:
continue
continue
if
entry
.
type
.
needs_refcounting
:
if
entry
.
type
.
needs_refcounting
:
assure_gil
(
'success'
)
assure_gil
(
'success'
)
if
entry
.
type
.
is_cyp_class
:
code
.
put_cyxdecref
(
entry
.
cname
)
else
:
# FIXME ideally use entry.xdecref_cleanup but this currently isn't reliable
# FIXME ideally use entry.xdecref_cleanup but this currently isn't reliable
code
.
put_var_xdecref
(
entry
,
have_gil
=
gil_owned
[
'success'
])
code
.
put_var_xdecref
(
entry
,
have_gil
=
gil_owned
[
'success'
])
...
@@ -2170,7 +2196,11 @@ class FuncDefNode(StatNode, BlockNode):
...
@@ -2170,7 +2196,11 @@ class FuncDefNode(StatNode, BlockNode):
continue
continue
if
entry
.
type
.
needs_refcounting
:
if
entry
.
type
.
needs_refcounting
:
assure_gil
(
'success'
)
assure_gil
(
'success'
)
if
entry
.
type
.
is_cyp_class
:
# We must check for NULL because it is possible to have
# NULL as a valid cypclass (with a typecast)
code
.
put_cyxdecref
(
entry
.
cname
)
else
:
# FIXME use entry.xdecref_cleanup - del arg seems to be the problem
# FIXME use entry.xdecref_cleanup - del arg seems to be the problem
code
.
put_var_xdecref
(
entry
,
have_gil
=
gil_owned
[
'success'
])
code
.
put_var_xdecref
(
entry
,
have_gil
=
gil_owned
[
'success'
])
if
self
.
needs_closure
:
if
self
.
needs_closure
:
...
@@ -2185,6 +2215,9 @@ class FuncDefNode(StatNode, BlockNode):
...
@@ -2185,6 +2215,9 @@ class FuncDefNode(StatNode, BlockNode):
if
err_val
is
None
and
default_retval
:
if
err_val
is
None
and
default_retval
:
err_val
=
default_retval
# FIXME: why is err_val not used?
err_val
=
default_retval
# FIXME: why is err_val not used?
code
.
put_xgiveref
(
Naming
.
retval_cname
,
return_type
)
code
.
put_xgiveref
(
Naming
.
retval_cname
,
return_type
)
# We can always return a CythonExtensionType as it is nogil-compliant
if
self
.
return_type
.
is_cyp_class
:
code
.
put_cyxgiveref
(
Naming
.
retval_cname
)
if
self
.
entry
.
is_special
and
self
.
entry
.
name
==
"__hash__"
:
if
self
.
entry
.
is_special
and
self
.
entry
.
name
==
"__hash__"
:
# Returning -1 for __hash__ is supposed to signal an error
# Returning -1 for __hash__ is supposed to signal an error
...
@@ -3376,8 +3409,6 @@ class DefNodeWrapper(FuncDefNode):
...
@@ -3376,8 +3409,6 @@ 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
:
...
@@ -4908,7 +4939,6 @@ class CClassDefNode(ClassDefNode):
...
@@ -4908,7 +4939,6 @@ 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
...
@@ -4918,7 +4948,6 @@ class CClassDefNode(ClassDefNode):
...
@@ -4918,7 +4948,6 @@ 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
...
@@ -4963,7 +4992,6 @@ class CClassDefNode(ClassDefNode):
...
@@ -4963,7 +4992,6 @@ 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
)
...
@@ -5052,7 +5080,6 @@ class CClassDefNode(ClassDefNode):
...
@@ -5052,7 +5080,6 @@ 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
)
...
@@ -6192,8 +6219,6 @@ class DelStatNode(StatNode):
...
@@ -6192,8 +6219,6 @@ class DelStatNode(StatNode):
error
(
arg
.
pos
,
"Deletion of global C variable"
)
error
(
arg
.
pos
,
"Deletion of global C variable"
)
elif
arg
.
type
.
is_ptr
and
arg
.
type
.
base_type
.
is_cpp_class
:
elif
arg
.
type
.
is_ptr
and
arg
.
type
.
base_type
.
is_cpp_class
:
self
.
cpp_check
(
env
)
self
.
cpp_check
(
env
)
elif
arg
.
type
.
is_struct_or_union
and
arg
.
type
.
nogil
:
pass
# del nogil extension
elif
arg
.
type
.
is_cpp_class
:
elif
arg
.
type
.
is_cpp_class
:
error
(
arg
.
pos
,
"Deletion of non-heap C++ object"
)
error
(
arg
.
pos
,
"Deletion of non-heap C++ object"
)
elif
arg
.
is_subscript
and
arg
.
base
.
type
is
Builtin
.
bytearray_type
:
elif
arg
.
is_subscript
and
arg
.
base
.
type
is
Builtin
.
bytearray_type
:
...
@@ -6222,8 +6247,6 @@ class DelStatNode(StatNode):
...
@@ -6222,8 +6247,6 @@ class DelStatNode(StatNode):
arg
.
generate_evaluation_code
(
code
)
arg
.
generate_evaluation_code
(
code
)
code
.
putln
(
"delete %s;"
%
arg
.
result
())
code
.
putln
(
"delete %s;"
%
arg
.
result
())
arg
.
generate_disposal_code
(
code
)
arg
.
generate_disposal_code
(
code
)
elif
arg
.
type
.
is_struct_or_union
and
hasattr
(
arg
.
type
,
"nogil"
)
and
arg
.
type
.
nogil
:
code
.
putln
(
"free(&%s);"
%
arg
.
result
())
# else error reported earlier
# else error reported earlier
def
annotate
(
self
,
code
):
def
annotate
(
self
,
code
):
...
@@ -6341,6 +6364,9 @@ class ReturnStatNode(StatNode):
...
@@ -6341,6 +6364,9 @@ class ReturnStatNode(StatNode):
# Use specialised default handling for "return None".
# Use specialised default handling for "return None".
value
=
None
value
=
None
if
self
.
return_type
.
is_cyp_class
:
code
.
put_cyxdecref
(
Naming
.
retval_cname
)
if
value
:
if
value
:
value
.
generate_evaluation_code
(
code
)
value
.
generate_evaluation_code
(
code
)
if
self
.
return_type
.
is_memoryviewslice
:
if
self
.
return_type
.
is_memoryviewslice
:
...
...
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,6 +637,10 @@ class Scope(object):
...
@@ -637,6 +637,10 @@ 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
:
if
cypclass
:
type
=
PyrexTypes
.
CypClassType
(
name
,
scope
,
cname
,
base_classes
,
templates
=
templates
)
else
:
type
=
PyrexTypes
.
CppClassType
(
type
=
PyrexTypes
.
CppClassType
(
name
,
scope
,
cname
,
base_classes
,
templates
=
templates
)
name
,
scope
,
cname
,
base_classes
,
templates
=
templates
)
entry
=
self
.
declare_type
(
name
,
type
,
pos
,
cname
,
entry
=
self
.
declare_type
(
name
,
type
,
pos
,
cname
,
...
@@ -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
:
pass
if
nogil
:
type
=
PyrexTypes
.
CythonExtensionType
(
name
,
typedef_flag
,
base_type
,
visibility
==
'extern'
,
check_size
=
check_size
)
else
:
type
=
PyrexTypes
.
PyExtensionType
(
type
=
PyrexTypes
.
PyExtensionType
(
name
,
typedef_flag
,
base_type
,
visibility
==
'extern'
,
check_size
=
check_size
)
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,7 +2331,6 @@ class CClassScope(ClassScope):
...
@@ -2334,7 +2331,6 @@ 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
:
...
@@ -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
:
if
self
.
type
.
is_pyobject
:
code
.
put_decref
(
self
.
result
(),
self
.
ctype
())
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