@@ -660,14 +660,86 @@ PyMarshal_WriteObjectToFile(PyObject *x, FILE *fp, int version)
660
660
w_flush (& wf );
661
661
}
662
662
663
-
664
- struct context {
663
+ typedef struct hydration_context {
664
+ PyObject_HEAD
665
665
PyObject * obj ; // Python bytes(-like) object containing the data
666
666
const char * buf ; // Pointer to first byte
667
667
Py_ssize_t len ; // Number of bytes
668
668
PyObject * refs ; // List of shared values
669
669
PyCodeObject * code ; // If not NULL, code object to be updated
670
670
// TODO: the latter is neither re-entrant nor thread-safe :-(
671
+ } _PyHydrationContext ;
672
+
673
+ static void
674
+ hydration_ctx_dealloc (_PyHydrationContext * self )
675
+ {
676
+ Py_XDECREF (self -> obj );
677
+ Py_XDECREF (self -> refs );
678
+ Py_XDECREF (self -> code );
679
+ PyObject_Free (self );
680
+ }
681
+
682
+ PyTypeObject _PyHydrationContext_Type ;
683
+
684
+ _PyHydrationContext *
685
+ _PyHydrationContext_new (
686
+ PyObject * obj , char * s , Py_ssize_t n , PyObject * refs )
687
+ {
688
+ _PyHydrationContext * ctx = PyObject_New (
689
+ _PyHydrationContext , & _PyHydrationContext_Type );
690
+ if (ctx == NULL ) {
691
+ PyErr_NoMemory ();
692
+ return NULL ;
693
+ }
694
+ Py_INCREF (obj );
695
+ ctx -> obj = obj ;
696
+ ctx -> buf = s ;
697
+ ctx -> len = n ;
698
+ ctx -> code = NULL ;
699
+ Py_INCREF (refs );
700
+ ctx -> refs = refs ;
701
+ return ctx ;
702
+ }
703
+
704
+ PyTypeObject _PyHydrationContext_Type = {
705
+ PyVarObject_HEAD_INIT (& PyType_Type , 0 )
706
+ "HydrationContext" ,
707
+ sizeof (_PyHydrationContext ),
708
+ 0 ,
709
+ (destructor )hydration_ctx_dealloc , /* tp_dealloc */
710
+ 0 , /* tp_vectorcall_offset */
711
+ 0 , /* tp_getattr */
712
+ 0 , /* tp_setattr */
713
+ 0 , /* tp_as_async */
714
+ 0 , /* tp_repr */
715
+ 0 , /* tp_as_number */
716
+ 0 , /* tp_as_sequence */
717
+ 0 , /* tp_as_mapping */
718
+ 0 , /* tp_hash */
719
+ 0 , /* tp_call */
720
+ 0 , /* tp_str */
721
+ 0 , /* tp_getattro */
722
+ 0 , /* tp_setattro */
723
+ 0 , /* tp_as_buffer */
724
+ Py_TPFLAGS_DEFAULT , /* tp_flags */
725
+ 0 , /* tp_doc */
726
+ 0 , /* tp_traverse */
727
+ 0 , /* tp_clear */
728
+ 0 , /* tp_richcompare */
729
+ 0 , /* tp_weaklistoffset */
730
+ 0 , /* tp_iter */
731
+ 0 , /* tp_iternext */
732
+ 0 , /* tp_methods */
733
+ 0 , /* tp_members */
734
+ 0 , /* tp_getset */
735
+ 0 , /* tp_base */
736
+ 0 , /* tp_dict */
737
+ 0 , /* tp_descr_get */
738
+ 0 , /* tp_descr_set */
739
+ 0 , /* tp_dictoffset */
740
+ 0 , /* tp_init */
741
+ 0 , /* tp_alloc */
742
+ 0 , /* tp_new */
671
743
};
672
744
673
745
typedef struct {
@@ -680,7 +752,7 @@ typedef struct {
680
752
Py_ssize_t buf_size ;
681
753
PyObject * refs ; /* a list */
682
754
Py_ssize_t refs_pos ; /* Where in refs to insert/append */
683
- struct context * ctx ;
755
+ _PyHydrationContext * ctx ;
684
756
} RFILE ;
685
757
686
758
static const char *
@@ -1954,28 +2026,23 @@ marshal_loads_impl(PyObject *module, Py_buffer *bytes, int lazy)
1954
2026
if (lazy < 0 )
1955
2027
lazy = getenv ("LAZY" ) && * getenv ("LAZY" ); // TODO: Rename?
1956
2028
if (lazy ) {
1957
- rf .ctx = PyMem_Malloc (sizeof (struct context ));
2029
+ rf .ctx = _PyHydrationContext_new (
2030
+ bytes -> obj , s , n , rf .refs );
1958
2031
if (rf .ctx == NULL ) {
1959
2032
PyErr_NoMemory ();
1960
2033
return NULL ;
1961
2034
}
1962
- Py_INCREF (bytes -> obj );
1963
- rf .ctx -> obj = bytes -> obj ;
1964
- rf .ctx -> buf = s ;
1965
- rf .ctx -> len = n ;
1966
- rf .ctx -> code = NULL ;
1967
- Py_INCREF (rf .refs );
1968
- rf .ctx -> refs = rf .refs ;
1969
2035
}
1970
2036
result = read_object (& rf );
1971
- Py_DECREF (rf .refs );
2037
+ Py_XDECREF (rf .ctx );
2038
+ Py_XDECREF (rf .refs );
1972
2039
return result ;
1973
2040
}
1974
2041
1975
2042
PyCodeObject *
1976
2043
_PyCode_Hydrate (PyCodeObject * code )
1977
2044
{
1978
- struct context * ctx = code -> co_hydra_context ;
2045
+ _PyHydrationContext * ctx = code -> co_hydra_context ;
1979
2046
if (ctx == NULL ) {
1980
2047
// Not dehydrated
1981
2048
assert (_PyCode_IsHydrated (code ));
@@ -1998,12 +2065,17 @@ _PyCode_Hydrate(PyCodeObject *code)
1998
2065
rf .end = s + n ;
1999
2066
rf .depth = 0 ;
2000
2067
rf .refs = ctx -> refs ;
2068
+ Py_XINCREF (rf .refs );
2001
2069
rf .refs_pos = code -> co_hydra_refs_pos ;
2002
2070
rf .ctx = ctx ;
2071
+ Py_INCREF (code );
2003
2072
ctx -> code = code ;
2004
2073
2005
2074
PyObject * result = read_object (& rf );
2006
-
2075
+ Py_XDECREF (rf .refs );
2076
+ Py_XDECREF (code -> co_hydra_context );
2077
+ code -> co_hydra_context = NULL ;
2078
+ Py_XDECREF (ctx -> code );
2007
2079
ctx -> code = NULL ;
2008
2080
assert (result == NULL || PyCode_Check (result ));
2009
2081
return (PyCodeObject * )result ;
0 commit comments