Commit dfe95b09 authored by Xavier Thompson's avatar Xavier Thompson

Synthesize the underlying cyobject for each wrapper cclass

parent 9569a1e7
......@@ -578,7 +578,7 @@ def generate_cyp_class_wrapper_definition(type, wrapper_entry, constructor_entry
is_new_return_type = not new_entry or new_entry.type.return_type == type
# initialise PyObject fields
if (is_new_return_type):
if is_new_return_type and type.wrapper_type:
code.putln("if(self) {")
code.putln("self->ob_cypyobject = new CyPyObject(); // for now")
code.putln("self->ob_cypyobject->ob_refcnt = 0;")
......
......@@ -1502,7 +1502,7 @@ class CppClassNode(CStructOrUnionDefNode, BlockNode):
# cname string or None
# visibility "extern"
# in_pxd boolean
# attributes [CVarDefNode] or None
# attributes [StatNode] or None
# entry Entry
# base_classes [CBaseTypeNode]
# templates [(string, bool)] or None
......@@ -1607,8 +1607,7 @@ class CppClassNode(CStructOrUnionDefNode, BlockNode):
if self.in_pxd and not env.in_cinclude:
self.entry.defined_in_pxd = 1
for attr in self.attributes:
declare = getattr(attr, 'declare', None)
if declare:
if hasattr(attr, 'declare'):
attr.declare(scope)
attr.analyse_declarations(scope)
for func in func_attributes(self.attributes):
......@@ -1637,9 +1636,15 @@ class CppClassNode(CStructOrUnionDefNode, BlockNode):
from .ExprNodes import TupleNode
cclass_bases = TupleNode(self.pos, args=[])
if self.templates:
print("Quick warning: Python wrappers for templated cypclasses are not supported yet")
return
if self.attributes is not None:
# for now
cclass_body = StatListNode(pos=self.pos, stats=[])
# the underlying cyobject must come first thing after PyObject_HEAD in the memory layout
# long term, only the base class will declare the underlying attribute
underlying_cyobject = self.synthesise_underlying_cyobject_attribute(env)
cclass_body = StatListNode(pos=self.pos, stats=[underlying_cyobject])
else:
cclass_body = None
......@@ -1655,7 +1660,7 @@ class CppClassNode(CStructOrUnionDefNode, BlockNode):
objstruct_name = None,
typeobj_name = None,
check_size = None,
in_pxd = 0,
in_pxd = self.in_pxd,
doc = EncodedString("Python Object wrapper for underlying cypclass %s" % self.name),
body = cclass_body,
is_cyp_wrapper = 1
......@@ -1667,7 +1672,37 @@ class CppClassNode(CStructOrUnionDefNode, BlockNode):
self.entry.type.wrapper_type = wrapper.entry.type
wrapper.entry.type.is_cyp_wrapper = 1
self.cyp_wrapper = wrapper
def synthesise_underlying_cyobject_attribute(self, env):
nested_path = [] if env.is_module_scope else env.qualified_name.split(".")
underlying_base_type = CSimpleBaseTypeNode(
self.pos,
name = self.name,
module_path = nested_path,
is_basic_c_type = 0,
signed = 1,
complex = 0,
longness = 0,
is_self_arg = 0,
templates = None
)
underlying_name_declarator = CNameDeclaratorNode(self.pos, name = "nogil_cyobject", cname = None)
underlying_cyobject = CVarDefNode(
pos = self.pos,
visibility = 'private',
base_type = underlying_base_type,
declarators = [underlying_name_declarator],
in_pxd = self.in_pxd,
doc = None,
api = 0,
modifiers = [],
overridable = 0
)
return underlying_cyobject
def analyse_expressions(self, env):
self.body = self.body.analyse_expressions(self.entry.type.scope)
......
......@@ -3959,9 +3959,8 @@ def compute_mro_generic(cls):
class CypClassType(CppClassType):
# lock_mode string (tri-state: "nolock"/"checklock"/"autolock")
# _mro [CppClassType] or None The Method Resolution Order of this cypclass according to Python
# wrapper_type PyExtensionType the type of the cclass wrapper
# _mro [CppClassType] or None the Method Resolution Order of this cypclass according to Python
# wrapper_type PyExtensionType or None the type of the cclass wrapper
is_cyp_class = 1
to_py_function = "__Pyx_PyObject_FromCyObject"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment