Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Xavier Thompson
cython
Commits
a66de9b6
Commit
a66de9b6
authored
Jun 08, 2020
by
Xavier Thompson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Cast underlying cyobject to base type and back safely instead of void *
parent
e01817ce
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
44 additions
and
16 deletions
+44
-16
Cython/Compiler/CypclassWrapper.py
Cython/Compiler/CypclassWrapper.py
+17
-7
Cython/Compiler/ModuleNode.py
Cython/Compiler/ModuleNode.py
+2
-2
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+11
-7
Cython/Compiler/PyrexTypes.py
Cython/Compiler/PyrexTypes.py
+14
-0
No files found.
Cython/Compiler/CypclassWrapper.py
View file @
a66de9b6
...
...
@@ -237,12 +237,20 @@ class CypclassWrapperInjection(CythonTransform):
return
wrapper
def
synthesize_underlying_cyobject_attribute
(
self
,
node
):
base_type
=
node
.
entry
.
type
.
wrapped_base_type
void_type_node
=
Nodes
.
CSimpleBaseTypeNode
(
nesting_path
=
[]
outer_scope
=
base_type
.
scope
.
outer_scope
while
outer_scope
and
not
outer_scope
.
is_module_scope
:
nesting_path
.
append
(
outer_scope
.
name
)
outer_scope
=
outer_scope
.
outer_scope
nesting_path
.
reverse
()
base_type_node
=
Nodes
.
CSimpleBaseTypeNode
(
node
.
pos
,
name
=
"void"
,
module_path
=
[]
,
is_basic_c_type
=
1
,
name
=
base_type
.
name
,
module_path
=
nesting_path
,
is_basic_c_type
=
0
,
signed
=
1
,
complex
=
0
,
longness
=
0
,
...
...
@@ -251,12 +259,11 @@ class CypclassWrapperInjection(CythonTransform):
)
underlying_name_declarator
=
Nodes
.
CNameDeclaratorNode
(
node
.
pos
,
name
=
underlying_name
,
cname
=
None
)
underlying_name_declarator
=
Nodes
.
CPtrDeclaratorNode
(
node
.
pos
,
base
=
underlying_name_declarator
)
underlying_cyobject
=
Nodes
.
CVarDefNode
(
pos
=
node
.
pos
,
visibility
=
'private'
,
base_type
=
void
_type_node
,
base_type
=
base
_type_node
,
declarators
=
[
underlying_name_declarator
],
in_pxd
=
node
.
in_pxd
,
doc
=
None
,
...
...
@@ -765,11 +772,14 @@ def generate_cyp_class_wrapper_definition(type, wrapper_entry, constructor_entry
# initialise PyObject fields
if
is_new_return_type
and
type
.
wrapper_type
:
chain_casted_self
=
"self"
for
first_base
in
type
.
first_base_iter
():
chain_casted_self
=
"static_cast<%s *>(%s)"
%
(
first_base
.
empty_declaration_code
(),
chain_casted_self
)
objstruct_cname
=
type
.
wrapper_type
.
objstruct_cname
cclass_wrapper_base
=
type
.
wrapped_base_type
.
wrapper_type
code
.
putln
(
"if(self) {"
)
code
.
putln
(
"%s * wrapper = new %s();"
%
(
objstruct_cname
,
objstruct_cname
))
code
.
putln
(
"((%s *)wrapper)->nogil_cyobject =
self;"
%
cclass_wrapper_base
.
objstruct_cname
)
code
.
putln
(
"((%s *)wrapper)->nogil_cyobject =
%s;"
%
(
cclass_wrapper_base
.
objstruct_cname
,
chain_casted_self
)
)
code
.
putln
(
"PyObject * wrapper_as_py = (PyObject *) wrapper;"
)
code
.
putln
(
"wrapper_as_py->ob_refcnt = 0;"
)
code
.
putln
(
"wrapper_as_py->ob_type = %s;"
%
type
.
wrapper_type
.
typeptr_cname
)
...
...
Cython/Compiler/ModuleNode.py
View file @
a66de9b6
...
...
@@ -1354,7 +1354,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
# internal classes (should) never need None inits, normal zeroing will do
py_attrs
=
[]
#
cyp_class attributes should not be treated as normal cpp_class attribute
s
#
unlike normal cpp_class attributes, cyp_class attributes are always held as pointer
s
cpp_class_attrs
=
[
entry
for
entry
in
scope
.
var_entries
if
entry
.
type
.
is_cpp_class
and
not
entry
.
type
.
is_cyp_class
]
...
...
@@ -1534,7 +1534,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
_
,
(
py_attrs
,
_
,
memoryview_slices
)
=
scope
.
get_refcounted_entries
()
#
cyp_class attributes should not be treated as normal cpp_class attribute
s
#
unlike normal cpp_class attributes, cyp_class attributes are always held as pointer
s
cpp_class_attrs
=
[
entry
for
entry
in
scope
.
var_entries
if
entry
.
type
.
is_cpp_class
and
not
entry
.
type
.
is_cyp_class
]
...
...
Cython/Compiler/Nodes.py
View file @
a66de9b6
...
...
@@ -5432,13 +5432,17 @@ class CypclassWrapperDefNode(CClassDefNode):
# > access the underlying cyobject from the self argument of the wrapper method
underlying_obj
=
ExprNodes
.
AttributeNode
(
cfunc_method
.
pos
,
obj
=
self_obj
,
attribute
=
underlying_name
)
empty_declarator
=
CNameDeclaratorNode
(
cfunc_method
.
pos
,
name
=
""
,
cname
=
None
)
cast_operation
=
ExprNodes
.
TypecastNode
(
cfunc_method
.
pos
,
type
=
self
.
wrapped_cypclass
.
entry
.
type
,
operand
=
underlying_obj
,
typecheck
=
False
)
# > cast the underlying object back to this type
underlying_type
=
self
.
wrapped_cypclass
.
entry
.
type
cast_operation
=
underlying_obj
for
derived_type
in
underlying_type
.
first_base_rev_iter
():
cast_operation
=
ExprNodes
.
TypecastNode
(
cfunc_method
.
pos
,
type
=
derived_type
,
operand
=
cast_operation
,
typecheck
=
False
)
cast_underlying_obj
=
ExprNodes
.
NameNode
(
self_pos
,
name
=
EncodedString
(
"cast_cyobject"
))
cast_assignment
=
SingleAssignmentNode
(
self_pos
,
lhs
=
cast_underlying_obj
,
rhs
=
cast_operation
)
...
...
Cython/Compiler/PyrexTypes.py
View file @
a66de9b6
...
...
@@ -3934,6 +3934,20 @@ class CypClassType(CppClassType):
self
.
wrapped_base_type
=
base_type
.
wrapped_base_type
break
# iterate over the chain of first wrapped bases until the oldest wrapped base is reached
def
first_base_iter
(
self
):
type_item
=
self
while
type_item
is
not
self
.
wrapped_base_type
:
type_item
=
type_item
.
first_wrapped_base
yield
type_item
# iterate down the chain of first wrapped bases until this type is reached
def
first_base_rev_iter
(
self
):
if
self
is
not
self
.
wrapped_base_type
:
for
t
in
self
.
first_wrapped_base
.
first_base_rev_iter
():
yield
t
yield
self
# allow conversion to Python only when there is a wrapper type
def
can_coerce_to_pyobject
(
self
,
env
):
return
self
.
wrapper_type
is
not
None
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment