@@ -92,6 +92,7 @@ def generate_class(cl: ClassIR, module: str, emitter: Emitter) -> None:
9292
9393 setup_name = '{}_setup' .format (name_prefix )
9494 new_name = '{}_new' .format (name_prefix )
95+ members_name = '{}_members' .format (name_prefix )
9596 getseters_name = '{}_getseters' .format (name_prefix )
9697 vtable_name = '{}_vtable' .format (name_prefix )
9798 traverse_name = '{}_traverse' .format (name_prefix )
@@ -153,10 +154,23 @@ def emit_line() -> None:
153154 # populate these fields ourselves if we want them to have correct
154155 # values. PyType_Ready will inherit the offsets from tp_base but
155156 # that isn't what we want.
156- if any (x .inherits_python for x in cl .mro ):
157+
158+ has_dict = any (x .inherits_python for x in cl .mro )
159+ # XXX: there is no reason for the __weakref__ stuff to be mixed up with __dict__
160+ if has_dict :
161+ weak_offset = '{} + sizeof(PyObject *)' .format (base_size )
162+ emitter .emit_lines (
163+ 'PyMemberDef {}[] = {{' .format (members_name ),
164+ '{{"__dict__", T_OBJECT_EX, {}, 0, NULL}},' .format (base_size ),
165+ '{{"__weakref__", T_OBJECT_EX, {}, 0, NULL}},' .format (weak_offset ),
166+ '{0}' ,
167+ '};' ,
168+ )
169+
170+ fields ['tp_members' ] = members_name
157171 fields ['tp_basicsize' ] = '{} + 2*sizeof(PyObject *)' .format (base_size )
158172 fields ['tp_dictoffset' ] = base_size
159- fields ['tp_weaklistoffset' ] = '{} + sizeof(PyObject *)' . format ( base_size )
173+ fields ['tp_weaklistoffset' ] = weak_offset
160174 else :
161175 fields ['tp_basicsize' ] = base_size
162176
0 commit comments