@@ -143,5 +143,299 @@ inline PyTypeObject* make_default_metaclass() {
143143 return type;
144144}
145145
146+ extern " C" inline PyObject *pybind11_new (PyTypeObject *type, PyObject *, PyObject *) {
147+ PyObject *self = type->tp_alloc (type, 0 );
148+ auto instance = (instance_essentials<void > *) self;
149+ auto tinfo = get_type_info (type);
150+ instance->value = ::operator new (tinfo->type_size );
151+ instance->owned = true ;
152+ instance->holder_constructed = false ;
153+ get_internals ().registered_instances .emplace (instance->value , self);
154+ return self;
155+ }
156+
157+ extern " C" inline int pybind11_init (PyObject *self, PyObject *, PyObject *) {
158+ PyTypeObject *type = Py_TYPE (self);
159+ std::string msg;
160+ #if defined(PYPY_VERSION)
161+ msg += handle ((PyObject *) type).attr (" __module__" ).cast <std::string>() + " ." ;
162+ #endif
163+ msg += type->tp_name ;
164+ msg += " : No constructor defined!" ;
165+ PyErr_SetString (PyExc_TypeError, msg.c_str ());
166+ return -1 ;
167+ }
168+
169+ extern " C" inline void pybind11_dealloc (PyObject *self) {
170+ auto instance = (instance_essentials<void > *) self;
171+ if (instance->value ) {
172+ auto type = Py_TYPE (self);
173+ get_type_info (type)->dealloc (self);
174+
175+ auto ®istered_instances = get_internals ().registered_instances ;
176+ auto range = registered_instances.equal_range (instance->value );
177+ bool found = false ;
178+ for (auto it = range.first ; it != range.second ; ++it) {
179+ if (type == Py_TYPE (it->second )) {
180+ registered_instances.erase (it);
181+ found = true ;
182+ break ;
183+ }
184+ }
185+ if (!found)
186+ pybind11_fail (" pybind11_dealloc(): Tried to deallocate unregistered instance!" );
187+
188+ if (instance->weakrefs )
189+ PyObject_ClearWeakRefs (self);
190+
191+ PyObject **dict_ptr = _PyObject_GetDictPtr (self);
192+ if (dict_ptr)
193+ Py_CLEAR (*dict_ptr);
194+ }
195+ Py_TYPE (self)->tp_free (self);
196+ }
197+
198+ /* * Create a type which can be used as a common base for all classes with the same
199+ instance size, i.e. all classes with the same `sizeof(holder_type)`. This is
200+ needed in order to satisfy Python's requirements for multiple inheritance.
201+ Return value: New reference. */
202+ inline PyObject *make_object_base_type (size_t instance_size) {
203+ auto name = " pybind11_object_" + std::to_string (instance_size);
204+ auto name_obj = reinterpret_steal<object>(PYBIND11_FROM_STRING (name.c_str ()));
205+
206+ /* Danger zone: from now (and until PyType_Ready), make sure to
207+ issue no Python C API calls which could potentially invoke the
208+ garbage collector (the GC will call type_traverse(), which will in
209+ turn find the newly constructed type in an invalid state) */
210+ auto metaclass = get_internals ().default_metaclass ;
211+ auto heap_type = (PyHeapTypeObject *) metaclass->tp_alloc (metaclass, 0 );
212+ if (!heap_type)
213+ pybind11_fail (" make_object_base_type(): error allocating type!" );
214+
215+ heap_type->ht_name = name_obj.inc_ref ().ptr ();
216+ #if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3
217+ heap_type->ht_qualname = name_obj.inc_ref ().ptr ();
218+ #endif
219+
220+ auto type = &heap_type->ht_type ;
221+ type->tp_name = strdup (name.c_str ());
222+ type->tp_base = &PyBaseObject_Type;
223+ type->tp_basicsize = static_cast <ssize_t >(instance_size);
224+ type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE;
225+
226+ type->tp_new = pybind11_new;
227+ type->tp_init = pybind11_init;
228+ type->tp_dealloc = pybind11_dealloc;
229+
230+ /* Support weak references (needed for the keep_alive feature) */
231+ type->tp_weaklistoffset = offsetof (instance_essentials<void >, weakrefs);
232+
233+ if (PyType_Ready (type) < 0 )
234+ pybind11_fail (" PyType_Ready failed in make_object_base_type():" + error_string ());
235+
236+ assert (!PyType_HasFeature (type, Py_TPFLAGS_HAVE_GC));
237+ return (PyObject *) heap_type;
238+ }
239+
240+ /* * Return the appropriate base type for the given instance size. The results are cached
241+ in `internals.bases` so that only a single base is ever created for any size value.
242+ Return value: Borrowed reference. */
243+ inline PyObject *internals::get_base (size_t instance_size) {
244+ auto it = bases.find (instance_size);
245+ if (it != bases.end ()) {
246+ return it->second ;
247+ } else {
248+ auto base = make_object_base_type (instance_size);
249+ bases[instance_size] = base;
250+ return base;
251+ }
252+ }
253+
254+ extern " C" inline PyObject *pybind11_get_dict (PyObject *self, void *) {
255+ PyObject *&dict = *_PyObject_GetDictPtr (self);
256+ if (!dict)
257+ dict = PyDict_New ();
258+ Py_XINCREF (dict);
259+ return dict;
260+ }
261+
262+ extern " C" inline int pybind11_set_dict (PyObject *self, PyObject *new_dict, void *) {
263+ if (!PyDict_Check (new_dict)) {
264+ PyErr_Format (PyExc_TypeError, " __dict__ must be set to a dictionary, not a '%.200s'" ,
265+ Py_TYPE (new_dict)->tp_name );
266+ return -1 ;
267+ }
268+ PyObject *&dict = *_PyObject_GetDictPtr (self);
269+ Py_INCREF (new_dict);
270+ Py_CLEAR (dict);
271+ dict = new_dict;
272+ return 0 ;
273+ }
274+
275+ static PyGetSetDef pybind11_getset[] = {
276+ {const_cast <char *>(" __dict__" ), pybind11_get_dict, pybind11_set_dict, nullptr , nullptr },
277+ {nullptr , nullptr , nullptr , nullptr , nullptr }
278+ };
279+
280+ extern " C" inline int pybind11_traverse (PyObject *self, visitproc visit, void *arg) {
281+ PyObject *&dict = *_PyObject_GetDictPtr (self);
282+ Py_VISIT (dict);
283+ return 0 ;
284+ }
285+
286+ extern " C" inline int pybind11_clear (PyObject *self) {
287+ PyObject *&dict = *_PyObject_GetDictPtr (self);
288+ Py_CLEAR (dict);
289+ return 0 ;
290+ }
291+
292+ extern " C" inline int pybind11_getbuffer (PyObject *obj, Py_buffer *view, int flags) {
293+ auto tinfo = get_type_info (Py_TYPE (obj));
294+ if (view == nullptr || obj == nullptr || !tinfo || !tinfo->get_buffer ) {
295+ if (view)
296+ view->obj = nullptr ;
297+ PyErr_SetString (PyExc_BufferError, " generic_type::getbuffer(): Internal error" );
298+ return -1 ;
299+ }
300+ memset (view, 0 , sizeof (Py_buffer));
301+ buffer_info *info = tinfo->get_buffer (obj, tinfo->get_buffer_data );
302+ view->obj = obj;
303+ view->ndim = 1 ;
304+ view->internal = info;
305+ view->buf = info->ptr ;
306+ view->itemsize = (ssize_t ) info->itemsize ;
307+ view->len = view->itemsize ;
308+ for (auto s : info->shape )
309+ view->len *= s;
310+ if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT)
311+ view->format = const_cast <char *>(info->format .c_str ());
312+ if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) {
313+ view->ndim = (int ) info->ndim ;
314+ view->strides = (ssize_t *) &info->strides [0 ];
315+ view->shape = (ssize_t *) &info->shape [0 ];
316+ }
317+ Py_INCREF (view->obj );
318+ return 0 ;
319+ }
320+
321+ extern " C" inline void pybind11_releasebuffer (PyObject *, Py_buffer *view) {
322+ delete (buffer_info *) view->internal ;
323+ }
324+
325+ /* * Create a brand new Python type according to the `type_record` specification.
326+ Return value: New reference. */
327+ inline PyObject* make_new_python_type (const type_record &rec) {
328+ auto name = reinterpret_steal<object>(PYBIND11_FROM_STRING (rec.name ));
329+
330+ #if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3
331+ auto ht_qualname = name;
332+ if (rec.scope && hasattr (rec.scope , " __qualname__" )) {
333+ ht_qualname = reinterpret_steal<object>(
334+ PyUnicode_FromFormat (" %U.%U" , rec.scope .attr (" __qualname__" ).ptr (), name.ptr ()));
335+ }
336+ #endif
337+
338+ object module ;
339+ if (rec.scope ) {
340+ if (hasattr (rec.scope , " __module__" ))
341+ module = rec.scope .attr (" __module__" );
342+ else if (hasattr (rec.scope , " __name__" ))
343+ module = rec.scope .attr (" __name__" );
344+ }
345+
346+ #if !defined(PYPY_VERSION)
347+ const auto full_name = module ? str (module ).cast <std::string>() + " ." + rec.name
348+ : std::string (rec.name );
349+ #else
350+ const auto full_name = std::string (rec.name );
351+ #endif
352+
353+ char *tp_doc = nullptr ;
354+ if (rec.doc && options::show_user_defined_docstrings ()) {
355+ /* Allocate memory for docstring (using PyObject_MALLOC, since
356+ Python will free this later on) */
357+ size_t size = strlen (rec.doc ) + 1 ;
358+ tp_doc = (char *) PyObject_MALLOC (size);
359+ memcpy ((void *) tp_doc, rec.doc , size);
360+ }
361+
362+ auto &internals = get_internals ();
363+ auto bases = tuple (rec.bases );
364+ auto base = (bases.size () == 0 ) ? internals.get_base (rec.instance_size )
365+ : bases[0 ].ptr ();
366+
367+ /* Danger zone: from now (and until PyType_Ready), make sure to
368+ issue no Python C API calls which could potentially invoke the
369+ garbage collector (the GC will call type_traverse(), which will in
370+ turn find the newly constructed type in an invalid state) */
371+ auto metaclass = internals.default_metaclass ;
372+ auto heap_type = (PyHeapTypeObject *) metaclass->tp_alloc (metaclass, 0 );
373+ if (!heap_type)
374+ pybind11_fail (std::string (rec.name ) + " : Unable to create type object!" );
375+
376+ heap_type->ht_name = name.release ().ptr ();
377+ #if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3
378+ heap_type->ht_qualname = ht_qualname.release ().ptr ();
379+ #endif
380+
381+ auto type = &heap_type->ht_type ;
382+ type->tp_name = strdup (full_name.c_str ());
383+ type->tp_doc = tp_doc;
384+ type->tp_base = (PyTypeObject *) handle (base).inc_ref ().ptr ();
385+ type->tp_basicsize = static_cast <ssize_t >(rec.instance_size );
386+ if (bases.size () > 0 )
387+ type->tp_bases = bases.release ().ptr ();
388+
389+ /* Supported protocols */
390+ type->tp_as_number = &heap_type->as_number ;
391+ type->tp_as_sequence = &heap_type->as_sequence ;
392+ type->tp_as_mapping = &heap_type->as_mapping ;
393+
394+ /* Flags */
395+ type->tp_flags |= Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE;
396+ #if PY_MAJOR_VERSION < 3
397+ type->tp_flags |= Py_TPFLAGS_CHECKTYPES;
398+ #endif
399+
400+ /* Support dynamic attributes */
401+ if (rec.dynamic_attr ) {
402+ #if defined(PYPY_VERSION)
403+ pybind11_fail (std::string (rec.name ) + " : dynamic attributes are "
404+ " currently not supported in "
405+ " conjunction with PyPy!" );
406+ #endif
407+ type->tp_dictoffset = type->tp_basicsize ; // place dict at the end
408+ type->tp_basicsize += sizeof (PyObject *); // and allocate enough space for it
409+ type->tp_getset = pybind11_getset;
410+ type->tp_traverse = pybind11_traverse;
411+ type->tp_clear = pybind11_clear;
412+ type->tp_flags |= Py_TPFLAGS_HAVE_GC;
413+ }
414+
415+ if (rec.buffer_protocol ) {
416+ type->tp_as_buffer = &heap_type->as_buffer ;
417+ #if PY_MAJOR_VERSION < 3
418+ type->tp_flags |= Py_TPFLAGS_HAVE_NEWBUFFER;
419+ #endif
420+ heap_type->as_buffer .bf_getbuffer = pybind11_getbuffer;
421+ heap_type->as_buffer .bf_releasebuffer = pybind11_releasebuffer;
422+ }
423+
424+ if (PyType_Ready (type) < 0 )
425+ pybind11_fail (std::string (rec.name ) + " : PyType_Ready failed (" + error_string () + " )!" );
426+
427+ assert (rec.dynamic_attr ? PyType_HasFeature (type, Py_TPFLAGS_HAVE_GC)
428+ : !PyType_HasFeature (type, Py_TPFLAGS_HAVE_GC));
429+
430+ /* Register type with the parent scope */
431+ if (rec.scope )
432+ setattr (rec.scope , rec.name , (PyObject *) type);
433+
434+ if (module ) // Needed by pydoc
435+ setattr ((PyObject *) type, " __module__" , module );
436+
437+ return (PyObject *) type;
438+ }
439+
146440NAMESPACE_END (detail)
147441NAMESPACE_END(pybind11)
0 commit comments