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
a4bc6221
Commit
a4bc6221
authored
Dec 02, 2020
by
Xavier Thompson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Introduce 'active' qualifier for cypclass references
parent
03d7c50c
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
173 additions
and
1 deletion
+173
-1
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+13
-0
Cython/Compiler/Parsing.py
Cython/Compiler/Parsing.py
+7
-0
Cython/Compiler/PyrexTypes.py
Cython/Compiler/PyrexTypes.py
+110
-0
Cython/Compiler/Symtab.py
Cython/Compiler/Symtab.py
+33
-0
Cython/Utility/CyObjects.cpp
Cython/Utility/CyObjects.cpp
+9
-0
tests/run/cypclass_acthon.pyx
tests/run/cypclass_acthon.pyx
+1
-1
No files found.
Cython/Compiler/Nodes.py
View file @
a4bc6221
...
...
@@ -1348,6 +1348,19 @@ class CConstOrVolatileTypeNode(CBaseTypeNode):
return
PyrexTypes
.
c_const_or_volatile_type
(
base
,
self
.
is_const
,
self
.
is_volatile
)
class
QualifiedCypclassNode
(
CBaseTypeNode
):
# base_type CBaseTypeNode
# qualifier string
child_attrs
=
[
"base_type"
]
def
analyse
(
self
,
env
,
could_be_name
=
False
):
base
=
self
.
base_type
.
analyse
(
env
,
could_be_name
)
if
not
base
.
is_cyp_class
:
error
(
self
.
pos
,
"Qualifier '%s' can only apply to cypclass types"
%
self
.
qualifier
)
return
base
return
PyrexTypes
.
cyp_class_qualified_type
(
base
,
self
.
qualifier
)
class
CVarDefNode
(
StatNode
):
# C variable definition or forward/extern function declaration.
#
...
...
Cython/Compiler/Parsing.py
View file @
a4bc6221
...
...
@@ -2534,6 +2534,13 @@ def p_c_simple_base_type(s, self_flag, nonempty, templates = None):
return
Nodes
.
CConstOrVolatileTypeNode
(
pos
,
base_type
=
base_type
,
is_const
=
is_const
,
is_volatile
=
is_volatile
)
# Handle cypclass qualifiers
if
s
.
sy
==
'IDENT'
and
s
.
systring
in
(
'active'
,):
qualifier
=
s
.
systring
s
.
next
()
base_type
=
p_c_base_type
(
s
,
self_flag
=
self_flag
,
nonempty
=
nonempty
,
templates
=
templates
)
return
Nodes
.
QualifiedCypclassNode
(
pos
,
base_type
=
base_type
,
qualifier
=
qualifier
)
if
s
.
sy
!=
'IDENT'
:
error
(
pos
,
"Expected an identifier, found '%s'"
%
s
.
sy
)
if
looking_at_base_type
(
s
):
...
...
Cython/Compiler/PyrexTypes.py
View file @
a4bc6221
...
...
@@ -256,6 +256,7 @@ class PyrexType(BaseType):
is_cpp_class
=
0
is_cyp_class
=
0
is_const_cyp_class
=
0
is_qualified_cyp_class
=
0
is_cpp_string
=
0
is_struct
=
0
is_enum
=
0
...
...
@@ -4768,6 +4769,108 @@ class ConstCypclassType(BaseType):
return
getattr
(
self
.
const_base_type
,
name
)
class
QualifiedCypclassType
(
BaseType
):
"A qualified cypclass reference"
# qualifier string the qualifier keyword
subtypes
=
[
'qual_base_type'
]
is_cyp_class
=
1
is_qualified_cyp_class
=
1
def
__init__
(
self
,
base_type
,
qualifier
):
assert
base_type
.
is_cyp_class
self
.
qual_base_type
=
base_type
self
.
qualifier
=
qualifier
if
qualifier
==
'active'
:
assert
base_type
.
activable
# For now just redirect to the nested "Activated" cypclass scope
self
.
scope
=
self
.
qual_base_type
.
scope
.
lookup_here
(
"Activated"
).
type
.
scope
elif
base_type
.
has_attributes
and
base_type
.
scope
is
not
None
:
from
.Symtab
import
QualifiedCypclassScope
self
.
scope
=
QualifiedCypclassScope
(
base_type
.
scope
,
qualifier
)
def
__repr__
(
self
):
return
"<QualifiedCypclassType %s%r>"
%
self
.
qual_base_type
def
__str__
(
self
):
return
self
.
declaration_code
(
""
,
for_display
=
1
)
def
declaration_code
(
self
,
entity_code
,
for_display
=
0
,
dll_linkage
=
None
,
pyrex
=
0
,
template_params
=
None
,
deref
=
0
):
if
for_display
:
decl
=
self
.
qual_base_type
.
declaration_code
(
entity_code
,
for_display
,
dll_linkage
,
pyrex
,
template_params
,
deref
)
return
"%s %s"
%
(
self
.
qualifier
,
decl
)
if
self
.
qualifier
==
'active'
:
decl_type
=
self
.
qual_base_type
.
scope
.
lookup_here
(
"Activated"
).
type
else
:
decl_type
=
self
.
qual_base_type
return
decl_type
.
declaration_code
(
entity_code
,
for_display
,
dll_linkage
,
pyrex
,
template_params
,
deref
)
def
empty_declaration_code
(
self
):
if
self
.
_empty_declaration
is
None
:
self
.
_empty_declaration
=
self
.
qual_base_type
.
empty_declaration_code
()
return
self
.
_empty_declaration
def
cast_code
(
self
,
expr_code
):
return
"((%s)%s)"
%
(
self
.
declaration_code
(
''
),
expr_code
)
def
dynamic_cast_code
(
self
,
expr_code
):
return
"dynamic_cast<%s>(%s)"
%
(
self
.
declaration_code
(
''
),
expr_code
)
def
resolve
(
self
):
base_type
=
self
.
qual_base_type
.
resolve
()
if
base_type
==
self
.
qual_base_type
:
return
self
return
QualifiedCypclassType
(
base_type
,
self
.
qualifier
)
def
specialize
(
self
,
values
):
base_type
=
self
.
qual_base_type
.
specialize
(
values
)
if
base_type
==
self
.
qual_base_type
:
return
self
return
QualifiedCypclassType
(
base_type
,
self
.
qualifier
)
def
as_argument_type
(
self
):
return
self
def
deduce_template_params
(
self
,
actual
):
return
self
.
qual_base_type
.
deduce_template_params
(
actual
)
def
can_coerce_to_pyobject
(
self
,
env
):
return
self
.
qual_base_type
.
can_coerce_to_pyobject
(
env
)
def
can_coerce_from_pyobject
(
self
,
env
):
return
self
.
qual_base_type
.
can_coerce_from_pyobject
(
env
)
def
create_to_py_utility_code
(
self
,
env
):
if
self
.
qual_base_type
.
create_to_py_utility_code
(
env
):
self
.
to_py_function
=
self
.
qual_base_type
.
to_py_function
return
True
def
assignable_from
(
self
,
src_type
):
return
self
.
assignable_from_resolved_type
(
src_type
.
resolve
())
def
assignable_from_resolved_type
(
self
,
src_type
):
if
src_type
.
is_qualified_cyp_class
and
self
.
qualifier
==
src_type
.
qualifier
:
return
self
.
qual_base_type
.
assignable_from_resolved_type
(
src_type
.
qual_base_type
)
return
0
def
same_as
(
self
,
other_type
):
if
not
other_type
.
is_qualified_cyp_class
:
return
0
return
self
.
same_as_resolved_type
(
other_type
.
resolve
())
def
same_as_resolved_type
(
self
,
other_type
):
if
other_type
.
is_qualified_cyp_class
and
self
.
qualifier
==
other_type
.
qualifier
:
return
self
.
qual_base_type
.
same_as_resolved_type
(
other_type
.
qual_base_type
)
return
0
def
__getattr__
(
self
,
name
):
return
getattr
(
self
.
qual_base_type
,
name
)
class
TemplatePlaceholderType
(
CType
):
is_template_typename
=
1
...
...
@@ -5669,6 +5772,13 @@ def cyp_class_const_type(base_type):
else
:
return
ConstCypclassType
(
base_type
)
def
cyp_class_qualified_type
(
base_type
,
qualifier
):
# Construct a qualified cypclass type.
if
base_type
is
error_type
:
return
error_type
else
:
return
QualifiedCypclassType
(
base_type
,
qualifier
)
def
qualified_method_type
(
base_type
,
const
,
volatile
):
# Construct a proxy type for methods looked-up from qualified objects.
if
base_type
is
error_type
:
...
...
Cython/Compiler/Symtab.py
View file @
a4bc6221
...
...
@@ -919,6 +919,20 @@ class Scope(object):
activate_entry
.
is_variable
=
activate_entry
.
is_cfunction
=
1
activate_entry
.
func_cname
=
"%s::%s"
%
(
entry
.
type
.
empty_declaration_code
(),
"__activate__"
)
activate_func_arg
=
PyrexTypes
.
CFuncTypeArg
(
EncodedString
(
"o"
),
entry
.
type
,
pos
)
activate_func_return
=
PyrexTypes
.
cyp_class_qualified_type
(
entry
.
type
,
'active'
)
activate_func_type
=
PyrexTypes
.
CFuncType
(
activate_func_return
,
[
activate_func_arg
],
nogil
=
1
)
builtin_scope
=
scope
.
builtin_scope
()
if
'activate'
in
builtin_scope
.
entries
:
activate_func_entry
=
Entry
(
EncodedString
(
'activate'
),
'activate'
,
activate_func_type
,
pos
=
None
)
activate_func_entry
.
visibility
=
'extern'
activate_func_entry
.
scope
=
builtin_scope
activate_func_entry
.
overloaded_alternatives
=
builtin_scope
.
entries
[
'activate'
].
overloaded_alternatives
activate_func_entry
.
overloaded_alternatives
.
append
(
activate_func_entry
)
else
:
activate_func_entry
=
builtin_scope
.
declare
(
EncodedString
(
'activate'
),
'activate'
,
activate_func_type
,
None
,
'extern'
)
activate_func_entry
.
is_variable
=
activate_func_entry
.
is_cfunction
=
1
if
self
.
is_cpp_class_scope
:
entry
.
type
.
namespace
=
self
.
outer_scope
.
lookup
(
self
.
name
).
type
return
entry
...
...
@@ -3279,6 +3293,25 @@ class CConstOrVolatileScope(Scope):
return
entry
class
QualifiedCypclassScope
(
Scope
):
def
__init__
(
self
,
base_type_scope
,
qualifier
):
Scope
.
__init__
(
self
,
'cyp_qual_'
+
base_type_scope
.
name
,
base_type_scope
.
outer_scope
,
base_type_scope
.
parent_scope
)
self
.
base_type_scope
=
base_type_scope
self
.
qualifier
=
qualifier
self
.
cached_qualified_entries
=
{}
def
lookup_here
(
self
,
name
):
try
:
return
self
.
cached_qualified_entries
[
name
]
except
KeyError
:
# TODO
pass
class
TemplateScope
(
Scope
):
def
__init__
(
self
,
name
,
outer_scope
):
Scope
.
__init__
(
self
,
name
,
outer_scope
,
None
)
...
...
Cython/Utility/CyObjects.cpp
View file @
a4bc6221
...
...
@@ -449,6 +449,15 @@
return
dynamic_cast
<
const
typename
std
::
remove_pointer
<
T
>::
type
*>
(
ob
)
!=
NULL
;
}
/*
* Activate a passive Cyobject.
*/
template
<
typename
T
>
static
inline
typename
T
::
Activated
*
activate
(
T
*
ob
)
{
static_assert
(
std
::
is_convertible
<
T
*
,
ActhonActivableClass
*>::
value
,
"wrong type for activate"
);
return
ob
->
__activate__
(
NULL
);
}
/*
* Cast from CyObject to PyObject:
* - borrow an atomic reference
...
...
tests/run/cypclass_acthon.pyx
View file @
a4bc6221
...
...
@@ -152,7 +152,7 @@ def test_acthon_chain(n):
after_sync1
=
ActivityCounterSync
(
sync1
)
obj
=
A
()
with
wlocked
obj
:
obj_actor
=
obj
.
__activate__
(
)
obj_actor
=
activate
(
obj
)
with
wlocked
obj_actor
,
wlocked
sync1
,
wlocked
after_sync1
:
# Pushing things in the queue
obj_actor
.
setter
(
sync1
,
n
)
...
...
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