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
904b7eee
Commit
904b7eee
authored
Dec 02, 2020
by
Xavier Thompson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refactor acthon implementation
parent
a4bc6221
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
97 additions
and
75 deletions
+97
-75
Cython/Compiler/ModuleNode.py
Cython/Compiler/ModuleNode.py
+25
-24
Cython/Compiler/Naming.py
Cython/Compiler/Naming.py
+4
-0
Cython/Compiler/PyrexTypes.py
Cython/Compiler/PyrexTypes.py
+9
-8
Cython/Compiler/Symtab.py
Cython/Compiler/Symtab.py
+58
-43
Cython/Utility/CyObjects.cpp
Cython/Utility/CyObjects.cpp
+1
-0
No files found.
Cython/Compiler/ModuleNode.py
View file @
904b7eee
...
...
@@ -968,8 +968,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
"""
Generate activate function for activable cypclass entries.
"""
active_self_entry
=
entry
.
type
.
scope
.
lookup_here
(
"<active_self>"
)
activate_class_decl
=
"%s::Activated"
%
entry
.
type
.
empty_declaration_code
()
dunder_activate_entry
=
entry
.
type
.
scope
.
lookup_here
(
"__activate__"
)
# Here we generate the function header like Nodes.CFuncDefNode would do,
# but we streamline the process because we know the exact prototype.
...
...
@@ -985,30 +984,30 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code
.
putln
(
"if (%s->%sn <= %s) {"
%
(
Naming
.
optional_args_cname
,
Naming
.
pyrex_prefix
,
i
))
code
.
putln
(
"activated_instance = new %s
::Activated
(%s);"
%
(
entry
.
type
.
empty_declaration_code
()
,
code
.
putln
(
"activated_instance = new %s(%s);"
%
(
activate_class_decl
,
", "
.
join
(
activated_class_constructor_optargs_list
+
activated_class_constructor_defaultargs_list
[
i
:])))
code
.
putln
(
"} else {"
)
activated_class_constructor_optargs_list
.
append
(
"%s->%s"
%
(
Naming
.
optional_args_cname
,
dunder_activate_entry
.
type
.
opt_arg_cname
(
arg
.
name
)))
# We're in the final else clause, corresponding to all optional arguments specified)
code
.
putln
(
"activated_instance = new %s
::Activated
(%s);"
%
(
entry
.
type
.
empty_declaration_code
()
,
code
.
putln
(
"activated_instance = new %s(%s);"
%
(
activate_class_decl
,
", "
.
join
(
activated_class_constructor_optargs_list
)))
for
_
in
dunder_activate_entry
.
type
.
args
:
code
.
putln
(
"}"
)
code
.
putln
(
"}"
)
code
.
putln
(
"else {"
)
code
.
putln
(
"if (this->%s == NULL) {"
%
active_self_entry
.
cname
)
code
.
putln
(
"this->%s = new %s
::Activated
(this, %s);"
%
(
active_self_entry
.
cname
,
entry
.
type
.
empty_declaration_code
()
,
code
.
putln
(
"if (this->%s == NULL) {"
%
Naming
.
cypclass_active_self_
cname
)
code
.
putln
(
"this->%s = new %s(this, %s);"
%
(
Naming
.
cypclass_active_self_
cname
,
activate_class_decl
,
", "
.
join
(
activated_class_constructor_defaultargs_list
))
)
code
.
putln
(
"}"
)
code
.
putln
(
"Cy_INCREF(
this->%s);"
%
active_self_entry
.
cname
)
code
.
putln
(
"activated_instance =
this->%s;"
%
active_self_entry
.
cname
)
code
.
putln
(
"Cy_INCREF(
(%s *)(this->%s));"
%
(
activate_class_decl
,
Naming
.
cypclass_active_self_cname
)
)
code
.
putln
(
"activated_instance =
(%s *)(this->%s);"
%
(
activate_class_decl
,
Naming
.
cypclass_active_self_cname
)
)
code
.
putln
(
"}"
)
code
.
putln
(
"return activated_instance;"
)
code
.
putln
(
"}"
)
...
...
@@ -1051,8 +1050,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
passive_self_attr_cname
)
))
for
reifying_class_entry
in
entry
.
type
.
scope
.
reifying_entries
:
reified_function_entry
=
reifying_class_entry
.
reified_entry
for
reified_function_entry
in
entry
.
type
.
scope
.
reified_entries
:
reifying_class_name
=
"%s%s"
%
(
Naming
.
cypclass_reified_prefix
,
reified_function_entry
.
name
)
reifying_class_full_name
=
"%s::%s"
%
(
PyrexTypes
.
namespace_declaration_code
(
entry
.
type
),
reifying_class_name
)
code
.
putln
(
"// generating reified of %s"
%
reified_function_entry
.
name
)
reified_arg_cname_list
=
[]
reified_arg_decl_list
=
[]
...
...
@@ -1075,9 +1076,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
message_constructor_args_list
=
[
"this->%s"
%
passive_self_attr_cname
,
"sync_object"
,
"result_object"
]
+
reified_arg_cname_list
message_constructor_args_code
=
", "
.
join
(
message_constructor_args_list
)
code
.
putln
(
"%s = new %s(%s);"
%
(
reifying_class_
entry
.
type
.
declaration_code
(
"message"
)
,
reifying_class_
entry
.
type
.
empty_declaration_code
()
,
code
.
putln
(
"%s
* message
= new %s(%s);"
%
(
reifying_class_
full_name
,
reifying_class_
full_name
,
message_constructor_args_code
))
...
...
@@ -1147,9 +1148,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
else
:
code
.
decrease_indent
()
for
reif
ying_class_entry
in
entry
.
type
.
scope
.
reifying
_entries
:
reif
ied_function_entry
=
reifying_class_entry
.
reified_entry
reifying_class_full_name
=
reifying_class_entry
.
type
.
empty_declaration_code
(
)
for
reif
ied_function_entry
in
entry
.
type
.
scope
.
reified
_entries
:
reif
ying_class_name
=
"%s%s"
%
(
Naming
.
cypclass_reified_prefix
,
reified_function_entry
.
name
)
reifying_class_full_name
=
"%s::%s"
%
(
PyrexTypes
.
namespace_declaration_code
(
entry
.
type
),
reifying_class_name
)
class_name
=
reifying_class_full_name
.
split
(
'::'
)[
-
1
]
code
.
putln
(
"struct %s : public %s {"
%
(
reifying_class_full_name
,
message_base_type
.
empty_declaration_code
()))
# Declaring target object & reified method arguments
...
...
@@ -1622,8 +1623,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
constructor
=
None
destructor
=
None
if
entry
.
type
.
is_cyp_class
and
entry
.
type
.
activable
:
activated_class_entry
=
scope
.
lookup_here
(
"Activated"
)
code
.
putln
(
"struct %s;"
%
activated_class_entry
.
cname
)
code
.
putln
(
"struct Activated;"
)
dunder_activate_entry
=
scope
.
lookup_here
(
"__activate__"
)
code
.
putln
(
"%s;"
%
dunder_activate_entry
.
type
.
declaration_code
(
dunder_activate_entry
.
cname
))
for
attr
in
scope
.
var_entries
:
...
...
@@ -1651,8 +1651,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
is_implementing
=
'init_module'
in
code
.
globalstate
.
parts
for
reified
in
scope
.
reifying_entries
:
code
.
putln
(
"struct %s;"
%
reified
.
cname
)
for
reified
in
scope
.
reified_entries
:
reifying_class_name
=
"%s%s"
%
(
Naming
.
cypclass_reified_prefix
,
reified
.
name
)
code
.
putln
(
"struct %s;"
%
reifying_class_name
)
def
generate_cpp_constructor_code
(
arg_decls
,
arg_names
,
is_implementing
,
py_attrs
,
constructor
):
if
is_implementing
:
...
...
Cython/Compiler/Naming.py
View file @
904b7eee
...
...
@@ -170,6 +170,10 @@ api_name = pyrex_prefix + "capi__"
# cname for the type that defines the essential memory layout of a cypclass wrapper.
cypclass_wrapper_layout_type
=
"CyPyObject"
# active cypclass
cypclass_reified_prefix
=
builtin_prefix
+
'active_'
cypclass_active_self_cname
=
"_active_self"
# the h and api guards get changed to:
# __PYX_HAVE__FILENAME (for ascii filenames)
# __PYX_HAVE_U_PUNYCODEFILENAME (for non-ascii filenames)
...
...
Cython/Compiler/PyrexTypes.py
View file @
904b7eee
...
...
@@ -4785,13 +4785,12 @@ class QualifiedCypclassType(BaseType):
self
.
qualifier
=
qualifier
if
qualifier
==
'active'
:
# TODO: raise a proper compilation error.
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
QualifiedCypclassS
cope
self
.
scope
=
QualifiedCypclassS
cope
(
base_type
.
scope
,
qualifier
)
if
base_type
.
scope
is
not
None
:
from
.Symtab
import
qualified_cypclass_s
cope
self
.
scope
=
qualified_cypclass_s
cope
(
base_type
.
scope
,
qualifier
)
def
__repr__
(
self
):
return
"<QualifiedCypclassType %s%r>"
%
self
.
qual_base_type
...
...
@@ -4804,10 +4803,12 @@ class QualifiedCypclassType(BaseType):
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
if
not
deref
:
entity_code
=
"*%s"
%
entity_code
namespace_decl
=
namespace_declaration_code
(
self
.
qual_base_type
)
return
"%s::Activated %s"
%
(
namespace_decl
,
entity_code
)
else
:
decl_type
=
self
.
qual_base_type
return
decl_type
.
declaration_code
(
entity_code
,
for_display
,
dll_linkage
,
pyrex
,
template_params
,
deref
)
return
self
.
qual_base_type
.
declaration_code
(
entity_code
,
for_display
,
dll_linkage
,
pyrex
,
template_params
,
deref
)
def
empty_declaration_code
(
self
):
if
self
.
_empty_declaration
is
None
:
...
...
Cython/Compiler/Symtab.py
View file @
904b7eee
...
...
@@ -177,6 +177,8 @@ class Entry(object):
# static_cname string The cname of a static method in a cypclass
#
# original_name string The original name of a cpp or cypclass method
#
# is_asyncable boolean Is a cypclass method that can be called asynchronously
# TODO: utility_code and utility_code_definition serves the same purpose...
...
...
@@ -254,6 +256,7 @@ class Entry(object):
from_type
=
None
static_cname
=
None
original_name
=
None
is_asyncable
=
False
def
__init__
(
self
,
name
,
cname
,
type
,
pos
=
None
,
init
=
None
):
self
.
name
=
name
...
...
@@ -869,18 +872,13 @@ class Scope(object):
if
entry
.
type
.
activable
:
# === Acthon ===
# Declare activated class
act_scope
=
CppClassScope
(
"Activated"
,
scope
)
act_type
=
PyrexTypes
.
CypClassType
(
EncodedString
(
"Activated"
),
act_scope
,
"Activated"
,
None
,
templates
=
templates
,
lock_mode
=
entry
.
type
.
lock_mode
)
act_type
.
set_scope
(
act_scope
)
act_type
.
namespace
=
entry
.
type
#scope.declare_cpp_class("Activated", act_scope, pos)
act_entry
=
scope
.
declare
(
EncodedString
(
"Activated"
),
"Activated"
,
act_type
,
pos
,
visibility
)
act_entry
.
is_type
=
1
# Declaring active_self member and activate function (its definition is generated automatically)
act_attr_name
=
EncodedString
(
Naming
.
builtin_prefix
+
"_active_self"
)
scope
.
declare_var
(
EncodedString
(
"<active_self>"
),
act_type
,
pos
,
cname
=
act_attr_name
)
# Declare dunder activate method (its definition is generated automatically)
from
.
import
Builtin
queue_type
=
Builtin
.
acthon_queue_type
result_type
=
Builtin
.
acthon_result_type
...
...
@@ -919,6 +917,7 @@ class Scope(object):
activate_entry
.
is_variable
=
activate_entry
.
is_cfunction
=
1
activate_entry
.
func_cname
=
"%s::%s"
%
(
entry
.
type
.
empty_declaration_code
(),
"__activate__"
)
# Declare 'activate' function for this class
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
)
...
...
@@ -2806,7 +2805,7 @@ class CppClassScope(Scope):
self
.
directives
=
outer_scope
.
directives
self
.
inherited_var_entries
=
[]
self
.
inherited_type_entries
=
[]
self
.
reif
ying
_entries
=
[]
self
.
reif
ied
_entries
=
[]
if
templates
is
not
None
:
for
T
in
templates
:
template_entry
=
self
.
declare
(
...
...
@@ -2865,38 +2864,8 @@ class CppClassScope(Scope):
def
reify_method
(
self
,
entry
):
if
entry
.
type
.
has_varargs
:
error
(
entry
.
pos
,
"Could not reify method with ellipsis (you can use optional arguments)"
)
# Create the reifying class
reified_name
=
EncodedString
(
"reified_"
+
entry
.
name
)
reified_cname
=
Naming
.
builtin_prefix
+
reified_name
scope
=
CppClassScope
(
reified_name
,
self
)
reified_type
=
PyrexTypes
.
CypClassType
(
reified_name
,
scope
,
reified_cname
,
None
,
templates
=
None
,
lock_mode
=
"nolock"
)
reified_type
.
namespace
=
self
.
type
#reify_base_classes = ()
reifying_entry
=
self
.
declare
(
reified_name
,
reified_cname
,
reified_type
,
entry
.
pos
,
'extern'
)
# FIXME: visibility
#reified_entry.is_cpp_class = 1
reifying_entry
.
reified_entry
=
entry
self
.
reifying_entries
.
append
(
reifying_entry
)
# Add the base method to the Activated member class
from
.
import
Builtin
activated_class_entry
=
self
.
lookup_here
(
"Activated"
)
result_type
=
Builtin
.
acthon_result_type
sync_type
=
Builtin
.
acthon_sync_type
activated_method_sync_attr_type
=
PyrexTypes
.
CFuncTypeArg
(
"sync_method"
,
PyrexTypes
.
CConstOrVolatileType
(
sync_type
,
is_const
=
1
),
entry
.
pos
,
"sync_method"
)
activated_method_type
=
PyrexTypes
.
CFuncType
(
result_type
,
[
activated_method_sync_attr_type
]
+
entry
.
type
.
args
,
nogil
=
entry
.
type
.
nogil
,
has_varargs
=
entry
.
type
.
has_varargs
,
optional_arg_count
=
entry
.
type
.
optional_arg_count
)
if
hasattr
(
entry
.
type
,
'op_arg_struct'
):
activated_method_type
.
op_arg_struct
=
entry
.
type
.
op_arg_struct
activated_method_entry
=
activated_class_entry
.
type
.
scope
.
declare
(
entry
.
name
,
entry
.
cname
,
activated_method_type
,
entry
.
pos
,
'extern'
)
activated_method_entry
.
is_cfunction
=
1
activated_method_entry
.
is_variable
=
1
self
.
reified_entries
.
append
(
entry
)
entry
.
is_asyncable
=
True
# Return the type declaration string if stripped_name corresponds to a known type, None otherwise.
# The returned string is intended to be used to build an operator of the form "operator <type name>".
...
...
@@ -3298,7 +3267,7 @@ class QualifiedCypclassScope(Scope):
def
__init__
(
self
,
base_type_scope
,
qualifier
):
Scope
.
__init__
(
self
,
'
cyp_qual_'
+
base_type_scope
.
name
,
'
%s_'
%
qualifier
+
base_type_scope
.
name
,
base_type_scope
.
outer_scope
,
base_type_scope
.
parent_scope
)
self
.
base_type_scope
=
base_type_scope
...
...
@@ -3309,8 +3278,54 @@ class QualifiedCypclassScope(Scope):
try
:
return
self
.
cached_qualified_entries
[
name
]
except
KeyError
:
# TODO
pass
entry
=
self
.
resolve
(
name
)
self
.
cached_qualified_entries
[
name
]
=
entry
return
entry
def
resolve
(
self
,
name
):
return
None
def
qualified_cypclass_scope
(
base_type_scope
,
qualifier
):
if
qualifier
==
'active'
:
return
ActiveCypclassScope
(
base_type_scope
)
else
:
return
QualifiedCypclassScope
(
base_type_scope
,
qualifier
)
class
ActiveCypclassScope
(
QualifiedCypclassScope
):
def
__init__
(
self
,
base_type_scope
):
QualifiedCypclassScope
.
__init__
(
self
,
base_type_scope
,
'active'
)
def
resolve
(
self
,
name
):
base_entry
=
self
.
base_type_scope
.
lookup_here
(
name
)
if
base_entry
is
None
or
not
base_entry
.
is_asyncable
:
return
None
from
.
import
Builtin
result_type
=
Builtin
.
acthon_result_type
sync_type
=
Builtin
.
acthon_sync_type
activated_method_sync_attr_type
=
PyrexTypes
.
CFuncTypeArg
(
EncodedString
(
"sync_method"
),
PyrexTypes
.
CConstOrVolatileType
(
sync_type
,
is_const
=
1
),
base_entry
.
pos
,
"sync_method"
,
)
activated_method_type
=
PyrexTypes
.
CFuncType
(
result_type
,
[
activated_method_sync_attr_type
]
+
base_entry
.
type
.
args
,
nogil
=
base_entry
.
type
.
nogil
,
has_varargs
=
base_entry
.
type
.
has_varargs
,
optional_arg_count
=
base_entry
.
type
.
optional_arg_count
,
)
if
hasattr
(
base_entry
.
type
,
'op_arg_struct'
):
activated_method_type
.
op_arg_struct
=
base_entry
.
type
.
op_arg_struct
activated_method_entry
=
Entry
(
base_entry
.
name
,
base_entry
.
cname
,
activated_method_type
,
base_entry
.
pos
)
activated_method_entry
.
visibility
=
'extern'
activated_method_entry
.
scope
=
self
activated_method_entry
.
is_cfunction
=
1
activated_method_entry
.
is_variable
=
1
return
activated_method_entry
class
TemplateScope
(
Scope
):
def
__init__
(
self
,
name
,
outer_scope
):
...
...
Cython/Utility/CyObjects.cpp
View file @
904b7eee
...
...
@@ -362,6 +362,7 @@
struct
ActhonActivableClass
:
public
CyObject
{
ActhonQueueInterface
*
_active_queue_class
=
NULL
;
void
*
_active_self
=
NULL
;
ActhonResultInterface
*
(
*
_active_result_class
)(
void
);
ActhonActivableClass
(){}
// Used in Activated classes inheritance chain (base Activated calls this, derived calls the 2 args version below)
ActhonActivableClass
(
ActhonQueueInterface
*
queue_object
,
ActhonResultInterface
*
(
*
result_constructor
)(
void
));
...
...
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