2222#include " Format.hpp"
2323#include " SpecialModuleNames.hpp"
2424#include " PyInstance.hpp"
25+ #include " PyVersionCompat.hpp"
2526
2627class Function ;
2728
@@ -1082,7 +1083,12 @@ class Function : public Type {
10821083 static PyObject* moduleHashName = PyUnicode_FromString (" __module_hash__" );
10831084 outSequences.push_back (std::vector<PyObject*>({moduleHashName}));
10841085
1085- PyBytes_AsStringAndSize (((PyCodeObject*)code)->co_code , (char **)&bytes, &bytecount);
1086+ PyObject* codeBytes = PyCompat::codeGetCode (code);
1087+ PyCompat::NewRefIf311 codeBytesGuard (codeBytes);
1088+ PyBytes_AsStringAndSize (codeBytes, (char **)&bytes, &bytecount);
1089+
1090+ PyObject* names = PyCompat::codeGetNames (code);
1091+ PyCompat::NewRefIf311 namesGuard (names);
10861092
10871093 long opcodeCount = bytecount / 2 ;
10881094
@@ -1103,7 +1109,7 @@ class Function : public Type {
11031109 for (long ix = 0 ; ix < opcodeCount; ix++) {
11041110 // if we're loading an attr on an existing sequence, just make it bigger
11051111 if ((opcodeFor (ix) == LOAD_ATTR || opcodeFor (ix) == LOAD_METHOD) && curDotSequence.size ()) {
1106- curDotSequence.push_back (PyTuple_GetItem (code-> co_names , opcodeTargetFor (ix)));
1112+ curDotSequence.push_back (PyTuple_GetItem (names , opcodeTargetFor (ix)));
11071113 } else if (curDotSequence.size ()) {
11081114 // any other operation should flush the buffer
11091115 outSequences.push_back (curDotSequence);
@@ -1112,12 +1118,12 @@ class Function : public Type {
11121118
11131119 // if we're loading a global, we start a new sequence
11141120 if (opcodeFor (ix) == LOAD_GLOBAL) {
1115- curDotSequence.push_back (PyTuple_GetItem (code-> co_names , opcodeTargetFor (ix)));
1121+ curDotSequence.push_back (PyTuple_GetItem (names , opcodeTargetFor (ix)));
11161122 } else if (
11171123 opcodeFor (ix) == STORE_GLOBAL
11181124 || opcodeFor (ix) == DELETE_GLOBAL
11191125 ) {
1120- outSequences.push_back ({PyTuple_GetItem (code-> co_names , opcodeTargetFor (ix))});
1126+ outSequences.push_back ({PyTuple_GetItem (names , opcodeTargetFor (ix))});
11211127 }
11221128 }
11231129
@@ -1127,7 +1133,9 @@ class Function : public Type {
11271133 }
11281134
11291135 // recurse into sub code objects
1130- iterate(code->co_consts , [&](PyObject* o) {
1136+ PyObject* consts = PyCompat::codeGetConsts (code);
1137+ PyCompat::NewRefIf311 constsGuard (consts);
1138+ iterate(consts, [&](PyObject* o) {
11311139 if (PyCode_Check (o)) {
11321140 extractDottedGlobalAccessesFromCode ((PyCodeObject*)o, outSequences);
11331141 }
@@ -1138,7 +1146,12 @@ class Function : public Type {
11381146 uint8_t * bytes;
11391147 Py_ssize_t bytecount;
11401148
1141- PyBytes_AsStringAndSize (((PyCodeObject*)code)->co_code , (char **)&bytes, &bytecount);
1149+ PyObject* codeBytes = PyCompat::codeGetCode (code);
1150+ PyCompat::NewRefIf311 codeBytesGuard (codeBytes);
1151+ PyBytes_AsStringAndSize (codeBytes, (char **)&bytes, &bytecount);
1152+
1153+ PyObject* names = PyCompat::codeGetNames (code);
1154+ PyCompat::NewRefIf311 namesGuard (names);
11421155
11431156 long opcodeCount = bytecount / 2 ;
11441157
@@ -1155,7 +1168,7 @@ class Function : public Type {
11551168 for (long ix = 0 ; ix < opcodeCount; ix++) {
11561169 // if we're loading a global, we start a new sequence
11571170 if (opcodeFor (ix) == LOAD_GLOBAL) {
1158- PyObject* name = PyTuple_GetItem (code-> co_names , opcodeTargetFor (ix));
1171+ PyObject* name = PyTuple_GetItem (names , opcodeTargetFor (ix));
11591172 if (!PyUnicode_Check (name)) {
11601173 throw std::runtime_error (" Function had a non-string object in co_names" );
11611174 }
@@ -1164,7 +1177,7 @@ class Function : public Type {
11641177 opcodeFor (ix) == STORE_GLOBAL
11651178 || opcodeFor (ix) == DELETE_GLOBAL
11661179 ) {
1167- PyObject* name = PyTuple_GetItem (code-> co_names , opcodeTargetFor (ix));
1180+ PyObject* name = PyTuple_GetItem (names , opcodeTargetFor (ix));
11681181 if (!PyUnicode_Check (name)) {
11691182 throw std::runtime_error (" Function had a non-string object in co_names" );
11701183 }
@@ -1173,7 +1186,9 @@ class Function : public Type {
11731186 }
11741187
11751188 // recurse into sub code objects
1176- iterate(code->co_consts , [&](PyObject* o) {
1189+ PyObject* consts = PyCompat::codeGetConsts (code);
1190+ PyCompat::NewRefIf311 constsGuard (consts);
1191+ iterate(consts, [&](PyObject* o) {
11771192 if (PyCode_Check (o)) {
11781193 extractGlobalAccessesFromCode ((PyCodeObject*)o, outAccesses);
11791194 }
@@ -1183,14 +1198,25 @@ class Function : public Type {
11831198 }
11841199
11851200 static void extractNamesFromCode (PyCodeObject* code, std::set<PyObject*>& outNames) {
1186- iterate(code->co_names , [&](PyObject* o) { outNames.insert (o); });
1187- iterate(code->co_freevars , [&](PyObject* o) { outNames.insert (o); });
1188-
1189- iterate(code->co_consts , [&](PyObject* o) {
1190- if (PyCode_Check (o)) {
1191- extractNamesFromCode ((PyCodeObject*)o, outNames);
1192- }
1193- });
1201+ {
1202+ PyObject* names = PyCompat::codeGetNames (code);
1203+ PyCompat::NewRefIf311 guard (names);
1204+ iterate(names, [&](PyObject* o) { outNames.insert (o); });
1205+ }
1206+ {
1207+ PyObject* freevars = PyCompat::codeGetFreevars (code);
1208+ PyCompat::NewRefIf311 guard (freevars);
1209+ iterate(freevars, [&](PyObject* o) { outNames.insert (o); });
1210+ }
1211+ {
1212+ PyObject* consts = PyCompat::codeGetConsts (code);
1213+ PyCompat::NewRefIf311 guard (consts);
1214+ iterate(consts, [&](PyObject* o) {
1215+ if (PyCode_Check (o)) {
1216+ extractNamesFromCode ((PyCodeObject*)o, outNames);
1217+ }
1218+ });
1219+ }
11941220
11951221 static PyObject* moduleHashName = PyUnicode_FromString (" __module_hash__" );
11961222 outNames.insert (moduleHashName);
0 commit comments