1 /****************************************************************************
2 **
3 ** Copyright (C) 2018 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of Qt for Python.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #ifndef PEP384IMPL_H
41 #define PEP384IMPL_H
42 
43 extern "C"
44 {
45 
46 /*****************************************************************************
47  *
48  * RESOLVED: memoryobject.h
49  *
50  */
51 
52 // Extracted into bufferprocs27.h
53 #ifdef Py_LIMITED_API
54 #include "bufferprocs_py37.h"
55 #endif
56 
57 /*****************************************************************************
58  *
59  * RESOLVED: object.h
60  *
61  */
62 #ifdef Py_LIMITED_API
63 // Why the hell is this useful debugging function not allowed?
64 // BTW: When used, it breaks on Windows, intentionally!
65 LIBSHIBOKEN_API void _PyObject_Dump(PyObject *);
66 #endif
67 
68 /*
69  * There are a few structures that are needed, but cannot be used without
70  * breaking the API. We use some heuristics to get those fields anyway
71  * and validate that we really found them, see pep384impl.cpp .
72  */
73 
74 #ifdef Py_LIMITED_API
75 
76 /*
77  * These are the type object fields that we use.
78  * We will verify that they never change.
79  * The unused fields are intentionally named as "void *Xnn" because
80  * the chance is smaller to forget to validate a field.
81  * When we need more fields, we replace it back and add it to the
82  * validation.
83  */
84 typedef struct _typeobject {
85     PyVarObject ob_base;
86     const char *tp_name;
87     Py_ssize_t tp_basicsize;
88     void *X03; // Py_ssize_t tp_itemsize;
89     destructor tp_dealloc;
90     void *X05; // Py_ssize_t tp_vectorcall_offset;
91     void *X06; // getattrfunc tp_getattr;
92     void *X07; // setattrfunc tp_setattr;
93     void *X08; // PyAsyncMethods *tp_as_async;
94     reprfunc tp_repr;
95     void *X10; // PyNumberMethods *tp_as_number;
96     void *X11; // PySequenceMethods *tp_as_sequence;
97     void *X12; // PyMappingMethods *tp_as_mapping;
98     void *X13; // hashfunc tp_hash;
99     ternaryfunc tp_call;
100     reprfunc tp_str;
101     getattrofunc tp_getattro;
102     setattrofunc tp_setattro;
103     void *X18; // PyBufferProcs *tp_as_buffer;
104     unsigned long tp_flags;
105     void *X20; // const char *tp_doc;
106     traverseproc tp_traverse;
107     inquiry tp_clear;
108     void *X23; // richcmpfunc tp_richcompare;
109     Py_ssize_t tp_weaklistoffset;
110     void *X25; // getiterfunc tp_iter;
111     iternextfunc tp_iternext;
112     struct PyMethodDef *tp_methods;
113     struct PyMemberDef *tp_members;
114     struct PyGetSetDef *tp_getset;
115     struct _typeobject *tp_base;
116     PyObject *tp_dict;
117     descrgetfunc tp_descr_get;
118     descrsetfunc tp_descr_set;
119     Py_ssize_t tp_dictoffset;
120     initproc tp_init;
121     allocfunc tp_alloc;
122     newfunc tp_new;
123     freefunc tp_free;
124     inquiry tp_is_gc; /* For PyObject_IS_GC */
125     PyObject *tp_bases;
126     PyObject *tp_mro; /* method resolution order */
127 
128 } PyTypeObject;
129 
130 #ifndef PyObject_IS_GC
131 /* Test if an object has a GC head */
132 #define PyObject_IS_GC(o) \
133     (PyType_IS_GC(Py_TYPE(o)) \
134      && (Py_TYPE(o)->tp_is_gc == NULL || Py_TYPE(o)->tp_is_gc(o)))
135 #endif
136 
137 // This was a macro error in the limited API from the beginning.
138 // It was fixed in Python master, but did make it only in Python 3.8 .
139 #define PY_ISSUE33738_SOLVED 0x03080000
140 #if PY_VERSION_HEX < PY_ISSUE33738_SOLVED
141 #undef PyIndex_Check
142 LIBSHIBOKEN_API int PyIndex_Check(PyObject *obj);
143 #endif
144 
145 #endif // Py_LIMITED_API
146 
147 struct SbkObjectTypePrivate;
148 struct PySideQFlagsTypePrivate;
149 struct _SbkGenericTypePrivate;
150 
151 #define PepHeapType_SIZE \
152     (reinterpret_cast<PyTypeObject *>(&PyType_Type)->tp_basicsize)
153 
154 #define _genericTypeExtender(etype) \
155     (reinterpret_cast<char *>(etype) + PepHeapType_SIZE)
156 
157 #define PepType_SOTP(etype) \
158     (*reinterpret_cast<SbkObjectTypePrivate **>(_genericTypeExtender(etype)))
159 
160 #define PepType_SETP(etype) \
161     (reinterpret_cast<SbkEnumTypePrivate *>(_genericTypeExtender(etype)))
162 
163 #define PepType_PFTP(etype) \
164     (reinterpret_cast<PySideQFlagsTypePrivate *>(_genericTypeExtender(etype)))
165 
166 #define PepType_SGTP(etype) \
167     (reinterpret_cast<_SbkGenericTypePrivate *>(_genericTypeExtender(etype)))
168 
169 // functions used everywhere
170 LIBSHIBOKEN_API const char *PepType_GetNameStr(PyTypeObject *type);
171 
172 /*****************************************************************************
173  *
174  * RESOLVED: longobject.h
175  *
176  */
177 #ifdef Py_LIMITED_API
178 LIBSHIBOKEN_API int _PepLong_AsInt(PyObject *);
179 #else
180 #define _PepLong_AsInt _PyLong_AsInt
181 #endif
182 
183 /*****************************************************************************
184  *
185  * RESOLVED: pydebug.h
186  *
187  */
188 #ifdef Py_LIMITED_API
189 /*
190  * We have no direct access to Py_VerboseFlag because debugging is not
191  * supported. The python developers are partially a bit too rigorous.
192  * Instead, we compute the value and use a function call macro.
193  * Was before: extern LIBSHIBOKEN_API int Py_VerboseFlag;
194  */
195 LIBSHIBOKEN_API int Pep_GetFlag(const char *name);
196 LIBSHIBOKEN_API int Pep_GetVerboseFlag(void);
197 #define Py_VerboseFlag              Pep_GetVerboseFlag()
198 #endif
199 
200 /*****************************************************************************
201  *
202  * RESOLVED: unicodeobject.h
203  *
204  */
205 
206 ///////////////////////////////////////////////////////////////////////
207 //
208 // PYSIDE-813: About The Length Of Unicode Objects
209 // -----------------------------------------------
210 //
211 // In Python 2 and before Python 3.3, the macro PyUnicode_GET_SIZE
212 // worked fine and really like a macro.
213 //
214 // Meanwhile, the unicode objects have changed their layout very much,
215 // and the former cheap macro call has become a real function call
216 // that converts objects and needs PyMemory.
217 //
218 // That is not only inefficient, but also requires the GIL!
219 // This problem was visible by debug Python and qdatastream_test.py .
220 // It was found while fixing the refcount problem of PYSIDE-813 which
221 // needed a debug Python.
222 //
223 
224 // PyUnicode_GetSize is deprecated in favor of PyUnicode_GetLength.
225 #if PY_VERSION_HEX < 0x03000000
226 #define PepUnicode_GetLength(op)    PyUnicode_GetSize((PyObject *)(op))
227 #else
228 #define PepUnicode_GetLength(op)    PyUnicode_GetLength((PyObject *)(op))
229 #endif
230 
231 #ifdef Py_LIMITED_API
232 
233 LIBSHIBOKEN_API char *_PepUnicode_AsString(PyObject *);
234 
235 #else
236 #define _PepUnicode_AsString     PyUnicode_AsUTF8
237 #endif
238 
239 /*****************************************************************************
240  *
241  * RESOLVED: bytesobject.h
242  *
243  */
244 #ifdef Py_LIMITED_API
245 #define PyBytes_AS_STRING(op)       PyBytes_AsString(op)
246 #define PyBytes_GET_SIZE(op)        PyBytes_Size(op)
247 #endif
248 
249 /*****************************************************************************
250  *
251  * RESOLVED: floatobject.h
252  *
253  */
254 #ifdef Py_LIMITED_API
255 #define PyFloat_AS_DOUBLE(op)       PyFloat_AsDouble(op)
256 #endif
257 
258 /*****************************************************************************
259  *
260  * RESOLVED: tupleobject.h
261  *
262  */
263 #ifdef Py_LIMITED_API
264 #define PyTuple_GET_ITEM(op, i)     PyTuple_GetItem((PyObject *)op, i)
265 #define PyTuple_SET_ITEM(op, i, v)  PyTuple_SetItem(op, i, v)
266 #define PyTuple_GET_SIZE(op)        PyTuple_Size((PyObject *)op)
267 #endif
268 
269 /*****************************************************************************
270  *
271  * RESOLVED: listobject.h
272  *
273  */
274 #ifdef Py_LIMITED_API
275 #define PyList_GET_ITEM(op, i)      PyList_GetItem(op, i)
276 #define PyList_SET_ITEM(op, i, v)   PyList_SetItem(op, i, v)
277 #define PyList_GET_SIZE(op)         PyList_Size(op)
278 #endif
279 
280 /*****************************************************************************
281  *
282  * RESOLVED: dictobject.h
283  *
284  * PYSIDE-803, PYSIDE-813: We need PyDict_GetItemWithError in order to
285  *                         avoid the GIL.
286  */
287 #if PY_VERSION_HEX < 0x03000000
288 LIBSHIBOKEN_API PyObject *PyDict_GetItemWithError(PyObject *mp, PyObject *key);
289 #endif
290 
291 /*****************************************************************************
292  *
293  * RESOLVED: methodobject.h
294  *
295  */
296 
297 #ifdef Py_LIMITED_API
298 
299 typedef struct _pycfunc PyCFunctionObject;
300 #define PyCFunction_GET_FUNCTION(func)  PyCFunction_GetFunction((PyObject *)func)
301 #define PyCFunction_GET_SELF(func)      PyCFunction_GetSelf((PyObject *)func)
302 #define PyCFunction_GET_FLAGS(func)     PyCFunction_GetFlags((PyObject *)func)
303 #define PepCFunction_GET_NAMESTR(func) \
304     _PepUnicode_AsString(PyObject_GetAttrString((PyObject *)func, "__name__"))
305 #else
306 #define PepCFunction_GET_NAMESTR(func)        ((func)->m_ml->ml_name)
307 #endif
308 
309 /*****************************************************************************
310  *
311  * RESOLVED: pythonrun.h
312  *
313  */
314 #ifdef Py_LIMITED_API
315 LIBSHIBOKEN_API PyObject *PyRun_String(const char *, int, PyObject *, PyObject *);
316 #endif
317 
318 /*****************************************************************************
319  *
320  * RESOLVED: abstract.h
321  *
322  */
323 #ifdef Py_LIMITED_API
324 
325 // This definition breaks the limited API a little, because it re-enables the
326 // buffer functions.
327 // But this is no problem as we check it's validity for every version.
328 
329 #define PYTHON_BUFFER_VERSION_COMPATIBLE    (PY_VERSION_HEX >= 0x03030000 && \
330                                              PY_VERSION_HEX <  0x0309FFFF)
331 #if !PYTHON_BUFFER_VERSION_COMPATIBLE
332 # error Please check the buffer compatibility for this python version!
333 #endif
334 
335 typedef struct {
336      getbufferproc bf_getbuffer;
337      releasebufferproc bf_releasebuffer;
338 } PyBufferProcs;
339 
340 typedef struct _Pepbuffertype {
341     PyVarObject ob_base;
342     void *skip[17];
343     PyBufferProcs *tp_as_buffer;
344 } PepBufferType;
345 
346 #define PepType_AS_BUFFER(type)   \
347     reinterpret_cast<PepBufferType *>(type)->tp_as_buffer
348 
349 #define PyObject_CheckBuffer(obj) \
350     ((PepType_AS_BUFFER(Py_TYPE(obj)) != NULL) &&  \
351      (PepType_AS_BUFFER(Py_TYPE(obj))->bf_getbuffer != NULL))
352 
353 LIBSHIBOKEN_API int PyObject_GetBuffer(PyObject *ob, Pep_buffer *view, int flags);
354 LIBSHIBOKEN_API void PyBuffer_Release(Pep_buffer *view);
355 
356 #else
357 
358 #define Pep_buffer                          Py_buffer
359 #define PepType_AS_BUFFER(type)             ((type)->tp_as_buffer)
360 
361 #endif /* Py_LIMITED_API */
362 
363 /*****************************************************************************
364  *
365  * RESOLVED: funcobject.h
366  *
367  */
368 #ifdef Py_LIMITED_API
369 typedef struct _func PyFunctionObject;
370 
371 extern LIBSHIBOKEN_API PyTypeObject *PepFunction_TypePtr;
372 LIBSHIBOKEN_API PyObject *PepFunction_Get(PyObject *, const char *);
373 
374 #define PyFunction_Check(op)        (Py_TYPE(op) == PepFunction_TypePtr)
375 #define PyFunction_GET_CODE(func)   PyFunction_GetCode(func)
376 
377 #define PyFunction_GetCode(func)    PepFunction_Get((PyObject *)func, "__code__")
378 #define PepFunction_GetName(func)   PepFunction_Get((PyObject *)func, "__name__")
379 #else
380 #define PepFunction_TypePtr         (&PyFunction_Type)
381 #define PepFunction_GetName(func)   (((PyFunctionObject *)func)->func_name)
382 #endif
383 
384 /*****************************************************************************
385  *
386  * RESOLVED: classobject.h
387  *
388  */
389 #ifdef Py_LIMITED_API
390 
391 typedef struct _meth PyMethodObject;
392 
393 extern LIBSHIBOKEN_API PyTypeObject *PepMethod_TypePtr;
394 
395 LIBSHIBOKEN_API PyObject *PyMethod_New(PyObject *, PyObject *);
396 LIBSHIBOKEN_API PyObject *PyMethod_Function(PyObject *);
397 LIBSHIBOKEN_API PyObject *PyMethod_Self(PyObject *);
398 
399 #define PyMethod_Check(op) ((op)->ob_type == PepMethod_TypePtr)
400 
401 #define PyMethod_GET_SELF(op)       PyMethod_Self(op)
402 #define PyMethod_GET_FUNCTION(op)   PyMethod_Function(op)
403 #endif
404 
405 /*****************************************************************************
406  *
407  * RESOLVED: code.h
408  *
409  */
410 #ifdef Py_LIMITED_API
411 /* Bytecode object */
412 
413 // we have to grab the code object from python
414 typedef struct _code PepCodeObject;
415 
416 LIBSHIBOKEN_API int PepCode_Get(PepCodeObject *co, const char *name);
417 
418 #  define PepCode_GET_FLAGS(o)         PepCode_Get(o, "co_flags")
419 #  define PepCode_GET_ARGCOUNT(o)      PepCode_Get(o, "co_argcount")
420 
421 /* Masks for co_flags above */
422 #  define CO_OPTIMIZED    0x0001
423 #  define CO_NEWLOCALS    0x0002
424 #  define CO_VARARGS      0x0004
425 #  define CO_VARKEYWORDS  0x0008
426 #  define CO_NESTED       0x0010
427 #  define CO_GENERATOR    0x0020
428 
429 #else
430 
431 #  define PepCodeObject                PyCodeObject
432 #  define PepCode_GET_FLAGS(o)         ((o)->co_flags)
433 #  define PepCode_GET_ARGCOUNT(o)      ((o)->co_argcount)
434 
435 #endif
436 
437 /*****************************************************************************
438  *
439  * RESOLVED: datetime.h
440  *
441  */
442 #ifdef Py_LIMITED_API
443 
444 LIBSHIBOKEN_API int PyDateTime_Get(PyObject *ob, const char *name);
445 
446 #define PyDateTime_GetYear(o)         PyDateTime_Get(o, "year")
447 #define PyDateTime_GetMonth(o)        PyDateTime_Get(o, "month")
448 #define PyDateTime_GetDay(o)          PyDateTime_Get(o, "day")
449 #define PyDateTime_GetHour(o)         PyDateTime_Get(o, "hour")
450 #define PyDateTime_GetMinute(o)       PyDateTime_Get(o, "minute")
451 #define PyDateTime_GetSecond(o)       PyDateTime_Get(o, "second")
452 #define PyDateTime_GetMicrosecond(o)  PyDateTime_Get(o, "microsecond")
453 #define PyDateTime_GetFold(o)         PyDateTime_Get(o, "fold")
454 
455 #define PyDateTime_GET_YEAR(o)              PyDateTime_GetYear(o)
456 #define PyDateTime_GET_MONTH(o)             PyDateTime_GetMonth(o)
457 #define PyDateTime_GET_DAY(o)               PyDateTime_GetDay(o)
458 
459 #define PyDateTime_DATE_GET_HOUR(o)         PyDateTime_GetHour(o)
460 #define PyDateTime_DATE_GET_MINUTE(o)       PyDateTime_GetMinute(o)
461 #define PyDateTime_DATE_GET_SECOND(o)       PyDateTime_GetSecond(o)
462 #define PyDateTime_DATE_GET_MICROSECOND(o)  PyDateTime_GetMicrosecond(o)
463 #define PyDateTime_DATE_GET_FOLD(o)         PyDateTime_GetFold(o)
464 
465 #define PyDateTime_TIME_GET_HOUR(o)         PyDateTime_GetHour(o)
466 #define PyDateTime_TIME_GET_MINUTE(o)       PyDateTime_GetMinute(o)
467 #define PyDateTime_TIME_GET_SECOND(o)       PyDateTime_GetSecond(o)
468 #define PyDateTime_TIME_GET_MICROSECOND(o)  PyDateTime_GetMicrosecond(o)
469 #define PyDateTime_TIME_GET_FOLD(o)         PyDateTime_GetFold(o)
470 
471 /* Define structure slightly similar to C API. */
472 typedef struct {
473     PyObject *module;
474     /* type objects */
475     PyTypeObject *DateType;
476     PyTypeObject *DateTimeType;
477     PyTypeObject *TimeType;
478     PyTypeObject *DeltaType;
479     PyTypeObject *TZInfoType;
480 } datetime_struc;
481 
482 LIBSHIBOKEN_API datetime_struc *init_DateTime(void);
483 
484 #define PyDateTime_IMPORT     PyDateTimeAPI = init_DateTime()
485 
486 extern LIBSHIBOKEN_API datetime_struc *PyDateTimeAPI;
487 
488 #define PyDate_Check(op)      PyObject_TypeCheck(op, PyDateTimeAPI->DateType)
489 #define PyDateTime_Check(op)  PyObject_TypeCheck(op, PyDateTimeAPI->DateTimeType)
490 #define PyTime_Check(op)      PyObject_TypeCheck(op, PyDateTimeAPI->TimeType)
491 
492 LIBSHIBOKEN_API PyObject *PyDate_FromDate(int year, int month, int day);
493 LIBSHIBOKEN_API PyObject *PyDateTime_FromDateAndTime(
494     int year, int month, int day, int hour, int min, int sec, int usec);
495 LIBSHIBOKEN_API PyObject *PyTime_FromTime(
496     int hour, int minute, int second, int usecond);
497 
498 #endif /* Py_LIMITED_API */
499 
500 /*****************************************************************************
501  *
502  * Extra support for name mangling
503  *
504  */
505 
506 // PYSIDE-772: This function supports the fix, but is not meant as public.
507 LIBSHIBOKEN_API PyObject *_Pep_PrivateMangle(PyObject *self, PyObject *name);
508 
509 /*****************************************************************************
510  *
511  * Extra support for signature.cpp
512  *
513  */
514 
515 #ifdef Py_LIMITED_API
516 extern LIBSHIBOKEN_API PyTypeObject *PepStaticMethod_TypePtr;
517 LIBSHIBOKEN_API PyObject *PyStaticMethod_New(PyObject *callable);
518 #else
519 #define PepStaticMethod_TypePtr &PyStaticMethod_Type
520 #endif
521 // Although not PEP specific, we resolve this similar issue, here:
522 #if PY_VERSION_HEX < 0x03000000
523 extern LIBSHIBOKEN_API PyTypeObject *PepMethodDescr_TypePtr;
524 #else
525 #define PepMethodDescr_TypePtr &PyMethodDescr_Type
526 #endif
527 
528 /*****************************************************************************
529  *
530  * Newly introduced convenience functions
531  *
532  * This is not defined if Py_LIMITED_API is defined.
533  */
534 #if PY_VERSION_HEX < 0x03070000 || defined(Py_LIMITED_API)
535 LIBSHIBOKEN_API PyObject *PyImport_GetModule(PyObject *name);
536 #endif // PY_VERSION_HEX < 0x03070000 || defined(Py_LIMITED_API)
537 
538 // Evaluate a script and return the variable `result`
539 LIBSHIBOKEN_API PyObject *PepRun_GetResult(const char *command);
540 
541 /*****************************************************************************
542  *
543  * Python 2 incompatibilities
544  *
545  * This is incompatibly implemented as macro in Python 2.
546  */
547 #if PY_VERSION_HEX < 0x03000000
548 extern LIBSHIBOKEN_API PyObject *PepMapping_Items(PyObject *o);
549 #else
550 #define PepMapping_Items PyMapping_Items
551 #endif
552 
553 /*****************************************************************************
554  *
555  * Runtime support for Python 3.8 incompatibilities
556  *
557  */
558 
559 #ifndef Py_TPFLAGS_METHOD_DESCRIPTOR
560 /* Objects behave like an unbound method */
561 #define Py_TPFLAGS_METHOD_DESCRIPTOR (1UL << 17)
562 #endif
563 
564 extern LIBSHIBOKEN_API int PepRuntime_38_flag;
565 
566 /*****************************************************************************
567  *
568  * Module Initialization
569  *
570  */
571 
572 LIBSHIBOKEN_API void Pep384_Init(void);
573 
574 } // extern "C"
575 
576 #endif // PEP384IMPL_H
577