diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst
index 385c7f94c672f2..0600f361000525 100644
--- a/Doc/c-api/typeobj.rst
+++ b/Doc/c-api/typeobj.rst
@@ -147,6 +147,10 @@ Quick Reference
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
| :c:member:`~PyTypeObject.tp_vectorcall` | :c:type:`vectorcallfunc` | | | | | |
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
+ | :c:member:`~PyTypeObject.tp_obj_offset` | const Py_ssize_t | | | X | ~ | |
+ +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
+ | :c:member:`~PyTypeObject.tp_obj_size` | const Py_ssize_t | | | X | ~ | |
+ +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
.. [#slots]
A slot name in parentheses indicates it is (effectively) deprecated.
@@ -1015,6 +1019,12 @@ and :c:type:`PyType_Type` effectively act as defaults.)
:c:func:`PyType_HasFeature` takes a type and a flags value, *tp* and *f*, and
checks whether ``tp->tp_flags & f`` is non-zero.
+ .. data:: Py_TPFLAGS_USES_OPAQUE_OBJECT
+
+ This bit is set when the type object's :c:member:`PyTypeObject.tp_basicsize` is configured
+ for an opaque :c:type:`PyObject` structure. The value of :c:member:`PyTypeObject.tp_basicsize` is the size of the type's
+ internal object structure EXCLUDING the base type's structure size.
+
.. data:: Py_TPFLAGS_HEAPTYPE
This bit is set when the type object itself is allocated on the heap, for
diff --git a/Include/cpython/object.h b/Include/cpython/object.h
index ae3920d4508e14..e9182e8ee4b924 100644
--- a/Include/cpython/object.h
+++ b/Include/cpython/object.h
@@ -263,6 +263,10 @@ struct _typeobject {
destructor tp_finalize;
vectorcallfunc tp_vectorcall;
+
+ /* INTERNAL USE ONLY! MODIFYING THIS CAN CRASH PYTHON! */
+ const Py_ssize_t tp_obj_offset; /* Offset from "PyObject *" pointer */
+ const Py_ssize_t tp_obj_size; /* Total memory allocation size */
};
/* The *real* layout of a type object when allocated on the heap */
diff --git a/Include/cpython/objimpl.h b/Include/cpython/objimpl.h
index 15999a239f7a9a..645f0f35248c54 100644
--- a/Include/cpython/objimpl.h
+++ b/Include/cpython/objimpl.h
@@ -18,10 +18,11 @@
# error "_PyObject_VAR_SIZE requires SIZEOF_VOID_P be a power of 2"
#endif
-#define _PyObject_VAR_SIZE(typeobj, nitems) \
- _Py_SIZE_ROUND_UP((typeobj)->tp_basicsize + \
- (nitems)*(typeobj)->tp_itemsize, \
- SIZEOF_VOID_P)
+static inline Py_ssize_t _PyObject_VAR_SIZE(PyTypeObject *typeobj, Py_ssize_t nitems)
+{
+ Py_ssize_t size = (PyType_HasFeature(typeobj, Py_TPFLAGS_OMIT_PYOBJECT_SIZE) ? typeobj->tp_obj_size : typeobj->tp_basicsize);
+ return _Py_SIZE_ROUND_UP((size + (nitems * (typeobj->tp_itemsize))), SIZEOF_VOID_P);
+}
/* This example code implements an object constructor with a custom
diff --git a/Include/object.h b/Include/object.h
index 537567040f9871..16a69dc88378b7 100644
--- a/Include/object.h
+++ b/Include/object.h
@@ -102,26 +102,62 @@ typedef struct _typeobject PyTypeObject;
* by hand. Similarly every pointer to a variable-size Python object can,
* in addition, be cast to PyVarObject*.
*/
-typedef struct _object {
+
+typedef struct _object PyObject;
+typedef struct _varobject PyVarObject;
+
+// TODO: Send "_object" and "_varobject" to CPython internal only.
+struct _object {
_PyObject_HEAD_EXTRA
Py_ssize_t ob_refcnt;
PyTypeObject *ob_type;
-} PyObject;
+};
+
+struct _varobject {
+ PyObject ob_base;
+ Py_ssize_t ob_size; /* Number of items in variable part */
+};
/* Cast argument to PyObject* type. */
#define _PyObject_CAST(op) ((PyObject*)(op))
#define _PyObject_CAST_CONST(op) ((const PyObject*)(op))
-typedef struct {
- PyObject ob_base;
- Py_ssize_t ob_size; /* Number of items in variable part */
-} PyVarObject;
-
/* Cast argument to PyVarObject* type. */
#define _PyVarObject_CAST(op) ((PyVarObject*)(op))
#define _PyVarObject_CAST_CONST(op) ((const PyVarObject*)(op))
+Py_SLIB_LOCAL(Py_ssize_t) PyObject_GetRefCount(const PyObject *ob);
+Py_SLIB_LOCAL(PyTypeObject *) PyObject_GetType(const PyObject *ob);
+
+Py_SLIB_LOCAL(void) PyObject_SetRefCount(PyObject *ob, const Py_ssize_t refcnt);
+Py_SLIB_LOCAL(void) PyObject_SetType(PyObject *ob, const PyTypeObject *type);
+
+
+Py_SLIB_LOCAL(Py_ssize_t) PyVarObject_GetSize(const PyVarObject *ob);
+
+Py_SLIB_LOCAL(void) PyVarObject_SetSize(PyVarObject *ob, const Py_ssize_t size);
+
+
+Py_SLIB_LOCAL(int) PyObject_IsType(const PyObject *ob, const PyTypeObject *type);
+
+
+Py_SLIB_LOCAL(void *) PyObject_GetStructure(const PyObject *ob, const PyTypeObject *type);
+#define Py_GET_STRUCTURE(ob, type) PyObject_GetStructure(_PyObject_CAST_CONST(ob), (const PyTypeObject *)type)
+
+#ifdef Py_USE_SLIB
+#define Py_REFCNT(ob) PyObject_GetRefCount(_PyObject_CAST_CONST(ob))
+#define Py_TYPE(ob) PyObject_GetType(_PyObject_CAST_CONST(ob))
+
+#define Py_SET_REFCNT(ob, refcnt) PyObject_SetRefCount(_PyObject_CAST(ob), refcnt)
+#define Py_SET_TYPE(ob, type) PyObject_SetType(_PyObject_CAST(ob), type)
+
+#define Py_SIZE(ob) PyVarObject_GetSize(_PyVarObject_CAST_CONST(ob))
+
+#define Py_SET_SIZE(ob, size) PyVarObject_SetSize(_PyVarObject_CAST(ob), size)
+
+#define Py_IS_TYPE(ob, type) PyObject_IsType(_PyObject_CAST_CONST(ob), type)
+#else
static inline Py_ssize_t _Py_REFCNT(const PyObject *ob) {
return ob->ob_refcnt;
}
@@ -162,7 +198,7 @@ static inline void _Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size) {
ob->ob_size = size;
}
#define Py_SET_SIZE(ob, size) _Py_SET_SIZE(_PyVarObject_CAST(ob), size)
-
+#endif
/*
Type objects contain a string containing the type name (to help somewhat
@@ -317,6 +353,9 @@ Code can use PyType_HasFeature(type_ob, flag_value) to test whether the
given type object has a specified feature.
*/
+/* Set if the type object's tp_basicsize is set for opague object */
+#define Py_TPFLAGS_OMIT_PYOBJECT_SIZE (1UL << 8)
+
/* Set if the type object is dynamically allocated */
#define Py_TPFLAGS_HEAPTYPE (1UL << 9)
@@ -419,6 +458,23 @@ PyAPI_FUNC(void) _Py_NegativeRefcount(const char *filename, int lineno,
PyAPI_FUNC(void) _Py_Dealloc(PyObject *);
+Py_SLIB_LOCAL(void) PyObject_IncRef(PyObject *op);
+
+Py_SLIB_LOCAL(void) PyObject_DecRef(
+#ifdef Py_REF_DEBUG
+ const char *filename, int lineno,
+#endif
+ PyObject *op);
+
+#ifdef Py_USE_SLIB
+# define Py_INCREF(op) PyObject_IncRef(_PyObject_CAST(op))
+
+# ifdef Py_REF_DEBUG
+# define Py_DECREF(op) PyObject_DecRef(__FILE__, __LINE__, _PyObject_CAST(op))
+# else
+# define Py_DECREF(op) PyObject_DecRef(_PyObject_CAST(op))
+# endif
+#else
static inline void _Py_INCREF(PyObject *op)
{
#ifdef Py_REF_DEBUG
@@ -426,7 +482,6 @@ static inline void _Py_INCREF(PyObject *op)
#endif
op->ob_refcnt++;
}
-
#define Py_INCREF(op) _Py_INCREF(_PyObject_CAST(op))
static inline void _Py_DECREF(
@@ -449,13 +504,12 @@ static inline void _Py_DECREF(
_Py_Dealloc(op);
}
}
-
#ifdef Py_REF_DEBUG
# define Py_DECREF(op) _Py_DECREF(__FILE__, __LINE__, _PyObject_CAST(op))
#else
# define Py_DECREF(op) _Py_DECREF(_PyObject_CAST(op))
#endif
-
+#endif
/* Safely decref `op` and set `op` to NULL, especially useful in tp_clear
* and tp_dealloc implementations.
diff --git a/Include/pyport.h b/Include/pyport.h
index 7137006870bf01..e93cdc2cf79e34 100644
--- a/Include/pyport.h
+++ b/Include/pyport.h
@@ -187,9 +187,11 @@ typedef int Py_ssize_clean_t;
/* ignore warnings if the compiler decides not to inline a function */
# pragma warning(disable: 4710)
/* fastest possible local call under MSVC */
+# define Py_SLIB_LOCAL(type) type __fastcall
# define Py_LOCAL(type) static type __fastcall
# define Py_LOCAL_INLINE(type) static __inline type __fastcall
#else
+# define Py_SLIB_LOCAL(type) type
# define Py_LOCAL(type) static type
# define Py_LOCAL_INLINE(type) static inline type
#endif
diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py
index aaba6630ff4396..9020e0d33b2968 100644
--- a/Lib/test/test_sys.py
+++ b/Lib/test/test_sys.py
@@ -1334,7 +1334,7 @@ def delx(self): del self.__x
check((1,2,3), vsize('') + 3*self.P)
# type
# static type: PyTypeObject
- fmt = 'P2nPI13Pl4Pn9Pn11PIPP'
+ fmt = 'P2nPI13Pl4Pn9Pn11PIPPll'
s = vsize(fmt)
check(int, s)
# class
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index f0e349ecd2bb92..ec521e6d993b2f 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -2086,11 +2086,19 @@ best_base(PyObject *bases)
return base;
}
+static inline const Py_ssize_t get_type_totalsize(PyTypeObject *type)
+{
+ if (type->tp_obj_size < sizeof(PyObject)) // PyType_Type->tp_new manages to trigger this.
+ return type->tp_basicsize;
+
+ return type->tp_obj_size;
+}
+
static int
extra_ivars(PyTypeObject *type, PyTypeObject *base)
{
- size_t t_size = type->tp_basicsize;
- size_t b_size = base->tp_basicsize;
+ size_t t_size = get_type_totalsize(type);
+ size_t b_size = get_type_totalsize(base);
assert(t_size >= b_size); /* Else type smaller than base! */
if (type->tp_itemsize || base->tp_itemsize) {
@@ -4846,7 +4854,7 @@ object___sizeof___impl(PyObject *self)
isize = Py_TYPE(self)->tp_itemsize;
if (isize > 0)
res = Py_SIZE(self) * isize;
- res += Py_TYPE(self)->tp_basicsize;
+ res += get_type_totalsize(Py_TYPE(self));
return PyLong_FromSsize_t(res);
}
@@ -4945,7 +4953,8 @@ PyTypeObject PyBaseObject_Type = {
PyObject_GenericGetAttr, /* tp_getattro */
PyObject_GenericSetAttr, /* tp_setattro */
0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | /* tp_flags */
+ Py_TPFLAGS_OMIT_PYOBJECT_SIZE,
object_doc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
@@ -5364,6 +5373,30 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base)
static int add_operators(PyTypeObject *);
+void set_type_memory_data(PyTypeObject *type, PyTypeObject *base)
+{
+ // Obtain the true size of the base type.
+ Py_ssize_t base_size = 0, base_offset = 0;
+ if (base != NULL) { // Only possible if we're not dealing with PyBaseObject_Type
+ if (_PyType_HasFeature(base, Py_TPFLAGS_OMIT_PYOBJECT_SIZE)) {
+ base_size = base->tp_obj_size;
+ base_offset = base->tp_obj_offset;
+ } else {
+ base_size = base->tp_basicsize;
+ base_offset = 0; // PyObject ALWAYS occupies the start of the memory block.
+ }
+ }
+
+ Py_ssize_t *size_ptr = (Py_ssize_t *)&type->tp_obj_size, *offset_ptr = (Py_ssize_t *)&type->tp_obj_offset;
+ if (_PyType_HasFeature(type, Py_TPFLAGS_OMIT_PYOBJECT_SIZE)) {
+ *size_ptr = base_size + type->tp_basicsize;
+ *offset_ptr = base_offset + base_size; // The type's internal structure occupies the next block of memory.
+ } else {
+ *size_ptr = type->tp_basicsize; // tp_basicsize already includes base_size.
+ *offset_ptr = 0; // The type's internal structure already includes "PyObject".
+ }
+}
+
int
PyType_Ready(PyTypeObject *type)
{
@@ -5426,6 +5459,8 @@ PyType_Ready(PyTypeObject *type)
goto error;
}
+ set_type_memory_data(type, base);
+
/* Initialize ob_type if NULL. This means extensions that want to be
compilable separately on Windows can call PyType_Ready() instead of
initializing the ob_type field of their type objects. */
diff --git a/PC/pyconfig.h b/PC/pyconfig.h
index b29f63c35bccb1..2353ead1e7f74a 100644
--- a/PC/pyconfig.h
+++ b/PC/pyconfig.h
@@ -260,6 +260,10 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */
/* All windows compilers that use this header support __declspec */
#define HAVE_DECLSPEC_DLL
+#if !defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_BUILTIN)
+# define Py_USE_SLIB
+#endif
+
/* For an MSVC DLL, we can nominate the .lib files used by extensions */
#ifdef MS_COREDLL
# if !defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_BUILTIN)
@@ -269,10 +273,13 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */
file in their Makefile (other compilers are
generally taken care of by distutils.) */
# if defined(_DEBUG)
+# pragma comment(lib, "slib_python310_d.lib")
# pragma comment(lib,"python310_d.lib")
# elif defined(Py_LIMITED_API)
+# pragma comment(lib, "slib_python310.lib")
# pragma comment(lib,"python3.lib")
# else
+# pragma comment(lib, "slib_python310.lib")
# pragma comment(lib,"python310.lib")
# endif /* _DEBUG */
# endif /* _MSC_VER */
diff --git a/PCbuild/pcbuild.sln b/PCbuild/pcbuild.sln
index 4b6dc1e6771dc3..2cf9e3638b0eb0 100644
--- a/PCbuild/pcbuild.sln
+++ b/PCbuild/pcbuild.sln
@@ -107,6 +107,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythonw_uwp", "pythonw_uwp.
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_uuid", "_uuid.vcxproj", "{CB435430-EBB1-478B-8F4E-C256F6838F55}"
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "slib_pythoncore", "slib_pythoncore.vcxproj", "{983BBA6B-A34B-40F8-927C-A57C714F1887}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM = Debug|ARM
@@ -1508,6 +1510,34 @@ Global
{CB435430-EBB1-478B-8F4E-C256F6838F55}.Release|Win32.Build.0 = Release|Win32
{CB435430-EBB1-478B-8F4E-C256F6838F55}.Release|x64.ActiveCfg = Release|x64
{CB435430-EBB1-478B-8F4E-C256F6838F55}.Release|x64.Build.0 = Release|x64
+ {983BBA6B-A34B-40F8-927C-A57C714F1887}.Debug|ARM.ActiveCfg = Debug|Win32
+ {983BBA6B-A34B-40F8-927C-A57C714F1887}.Debug|ARM64.ActiveCfg = Debug|Win32
+ {983BBA6B-A34B-40F8-927C-A57C714F1887}.Debug|Win32.ActiveCfg = Debug|Win32
+ {983BBA6B-A34B-40F8-927C-A57C714F1887}.Debug|Win32.Build.0 = Debug|Win32
+ {983BBA6B-A34B-40F8-927C-A57C714F1887}.Debug|x64.ActiveCfg = Debug|x64
+ {983BBA6B-A34B-40F8-927C-A57C714F1887}.Debug|x64.Build.0 = Debug|x64
+ {983BBA6B-A34B-40F8-927C-A57C714F1887}.PGInstrument|ARM.ActiveCfg = Release|x64
+ {983BBA6B-A34B-40F8-927C-A57C714F1887}.PGInstrument|ARM.Build.0 = Release|x64
+ {983BBA6B-A34B-40F8-927C-A57C714F1887}.PGInstrument|ARM64.ActiveCfg = Release|x64
+ {983BBA6B-A34B-40F8-927C-A57C714F1887}.PGInstrument|ARM64.Build.0 = Release|x64
+ {983BBA6B-A34B-40F8-927C-A57C714F1887}.PGInstrument|Win32.ActiveCfg = Release|Win32
+ {983BBA6B-A34B-40F8-927C-A57C714F1887}.PGInstrument|Win32.Build.0 = Release|Win32
+ {983BBA6B-A34B-40F8-927C-A57C714F1887}.PGInstrument|x64.ActiveCfg = Release|x64
+ {983BBA6B-A34B-40F8-927C-A57C714F1887}.PGInstrument|x64.Build.0 = Release|x64
+ {983BBA6B-A34B-40F8-927C-A57C714F1887}.PGUpdate|ARM.ActiveCfg = Release|x64
+ {983BBA6B-A34B-40F8-927C-A57C714F1887}.PGUpdate|ARM.Build.0 = Release|x64
+ {983BBA6B-A34B-40F8-927C-A57C714F1887}.PGUpdate|ARM64.ActiveCfg = Release|x64
+ {983BBA6B-A34B-40F8-927C-A57C714F1887}.PGUpdate|ARM64.Build.0 = Release|x64
+ {983BBA6B-A34B-40F8-927C-A57C714F1887}.PGUpdate|Win32.ActiveCfg = Release|Win32
+ {983BBA6B-A34B-40F8-927C-A57C714F1887}.PGUpdate|Win32.Build.0 = Release|Win32
+ {983BBA6B-A34B-40F8-927C-A57C714F1887}.PGUpdate|x64.ActiveCfg = Release|x64
+ {983BBA6B-A34B-40F8-927C-A57C714F1887}.PGUpdate|x64.Build.0 = Release|x64
+ {983BBA6B-A34B-40F8-927C-A57C714F1887}.Release|ARM.ActiveCfg = Release|Win32
+ {983BBA6B-A34B-40F8-927C-A57C714F1887}.Release|ARM64.ActiveCfg = Release|Win32
+ {983BBA6B-A34B-40F8-927C-A57C714F1887}.Release|Win32.ActiveCfg = Release|Win32
+ {983BBA6B-A34B-40F8-927C-A57C714F1887}.Release|Win32.Build.0 = Release|Win32
+ {983BBA6B-A34B-40F8-927C-A57C714F1887}.Release|x64.ActiveCfg = Release|x64
+ {983BBA6B-A34B-40F8-927C-A57C714F1887}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/PCbuild/python3dll.vcxproj b/PCbuild/python3dll.vcxproj
index ec22e6fc76e584..f7a740f0b9aedf 100644
--- a/PCbuild/python3dll.vcxproj
+++ b/PCbuild/python3dll.vcxproj
@@ -104,6 +104,11 @@
+
+
+ {983bba6b-a34b-40f8-927c-a57c714f1887}
+
+
diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj
index db26e38911bc05..5665f5815e1052 100644
--- a/PCbuild/pythoncore.vcxproj
+++ b/PCbuild/pythoncore.vcxproj
@@ -501,6 +501,11 @@
+
+
+ {983bba6b-a34b-40f8-927c-a57c714f1887}
+
+
@@ -533,7 +538,6 @@
-
@@ -542,4 +546,4 @@
-
+
\ No newline at end of file
diff --git a/PCbuild/slib_pythoncore.vcxproj b/PCbuild/slib_pythoncore.vcxproj
new file mode 100644
index 00000000000000..95bab6533dd415
--- /dev/null
+++ b/PCbuild/slib_pythoncore.vcxproj
@@ -0,0 +1,113 @@
+
+
+
+
+ Debug
+ ARM
+
+
+ Debug
+ ARM64
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ PGInstrument
+ ARM
+
+
+ PGInstrument
+ ARM64
+
+
+ PGInstrument
+ Win32
+
+
+ PGInstrument
+ x64
+
+
+ PGUpdate
+ ARM
+
+
+ PGUpdate
+ ARM64
+
+
+ PGUpdate
+ Win32
+
+
+ PGUpdate
+ x64
+
+
+ Release
+ ARM
+
+
+ Release
+ ARM64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ {983bba6b-a34b-40f8-927c-a57c714f1887}
+ slib_pythoncore
+
+
+
+
+ StaticLibrary
+ false
+
+
+
+
+
+ false
+
+
+
+
+
+
+
+ <_ProjectFileVersion>10.0.30319.1
+ slib_$(PyDllName)
+
+
+ Link
+
+
+
+ /Zm200 %(AdditionalOptions)
+ $(PySourcePath)Python;%(AdditionalIncludeDirectories)
+ $(zlibDir);%(AdditionalIncludeDirectories)
+ _USRDLL;Py_BUILD_SLIB;MS_DLL_ID="$(SysWinVer)";%(PreprocessorDefinitions)
+
+
+
+
+ AssemblyAndSourceCode
+
+
+
+
+
+
\ No newline at end of file
diff --git a/PCbuild/slib_pythoncore.vcxproj.filters b/PCbuild/slib_pythoncore.vcxproj.filters
new file mode 100644
index 00000000000000..46f286dafd724a
--- /dev/null
+++ b/PCbuild/slib_pythoncore.vcxproj.filters
@@ -0,0 +1,25 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;c++;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+ {87f89d00-deec-4816-998c-fc76b8c42c23}
+
+
+
+
+ Source Files\Objects
+
+
+
\ No newline at end of file
diff --git a/SLib/object.c b/SLib/object.c
new file mode 100644
index 00000000000000..01117def36c4aa
--- /dev/null
+++ b/SLib/object.c
@@ -0,0 +1,71 @@
+#include // TODO: Replace with appropriate INTERNAL ONLY header.
+
+Py_SLIB_LOCAL(Py_ssize_t) PyObject_GetRefCount(const PyObject *ob) {
+ return ob->ob_refcnt;
+}
+
+Py_SLIB_LOCAL(PyTypeObject *) PyObject_GetType(const PyObject *ob) {
+ return ob->ob_type;
+}
+
+Py_SLIB_LOCAL(void) PyObject_SetRefCount(PyObject *ob, const Py_ssize_t refcnt) {
+ ob->ob_refcnt = (Py_ssize_t)refcnt;
+}
+
+Py_SLIB_LOCAL(void) PyObject_SetType(PyObject *ob, const PyTypeObject *type) {
+ ob->ob_type = (PyTypeObject *)type;
+}
+
+
+Py_SLIB_LOCAL(Py_ssize_t) PyVarObject_GetSize(const PyVarObject *ob) {
+ return ob->ob_size;
+}
+
+Py_SLIB_LOCAL(void) PyVarObject_SetSize(PyVarObject *ob, const Py_ssize_t size) {
+ ob->ob_size = (Py_ssize_t)size;
+}
+
+
+Py_SLIB_LOCAL(int) PyObject_IsType(const PyObject *ob, const PyTypeObject *type) {
+ return Py_TYPE(ob) == type;
+}
+
+
+Py_SLIB_LOCAL(void *) PyObject_GetStructure(const PyObject *ob, const PyTypeObject *type)
+{
+ if (!PyType_HasFeature((PyTypeObject *)type, Py_TPFLAGS_OMIT_PYOBJECT_SIZE) ||
+ type->tp_obj_offset == type->tp_obj_size) // This checks to see if tp_basicsize was 0 (IE: It has no internal structure)
+ return (void *)ob;
+
+ return (void *)(((unsigned char *)ob) + type->tp_obj_offset);
+}
+
+
+Py_SLIB_LOCAL(void) PyObject_IncRef(PyObject *ob)
+{
+#ifdef Py_REF_DEBUG
+ ++_Py_RefTotal;
+#endif
+ ++ob->ob_refcnt;
+}
+
+Py_SLIB_LOCAL(void) PyObject_DecRef(
+#ifdef Py_REF_DEBUG
+ const char *filename, int lineno,
+#endif
+ PyObject *ob)
+{
+#ifdef Py_REF_DEBUG
+ --_Py_RefTotal;
+#endif
+ if (--ob->ob_refcnt != 0) {
+#ifdef Py_REF_DEBUG
+ if (ob->ob_refcnt < 0) {
+ _Py_NegativeRefcount(filename, lineno, ob);
+ }
+#endif
+ }
+ else {
+ _Py_Dealloc(ob);
+ }
+}